1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2021 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker
7*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/pwl/cpwl_sbbutton.h"
8*3ac0a46fSAndroid Build Coastguard Worker
9*3ac0a46fSAndroid Build Coastguard Worker #include <utility>
10*3ac0a46fSAndroid Build Coastguard Worker #include <vector>
11*3ac0a46fSAndroid Build Coastguard Worker
12*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/cfx_renderdevice.h"
13*3ac0a46fSAndroid Build Coastguard Worker
CPWL_SBButton(const CreateParams & cp,std::unique_ptr<IPWL_FillerNotify::PerWindowData> pAttachedData,Type eButtonType)14*3ac0a46fSAndroid Build Coastguard Worker CPWL_SBButton::CPWL_SBButton(
15*3ac0a46fSAndroid Build Coastguard Worker const CreateParams& cp,
16*3ac0a46fSAndroid Build Coastguard Worker std::unique_ptr<IPWL_FillerNotify::PerWindowData> pAttachedData,
17*3ac0a46fSAndroid Build Coastguard Worker Type eButtonType)
18*3ac0a46fSAndroid Build Coastguard Worker : CPWL_Wnd(cp, std::move(pAttachedData)), m_eSBButtonType(eButtonType) {
19*3ac0a46fSAndroid Build Coastguard Worker GetCreationParams()->eCursorType = IPWL_FillerNotify::CursorStyle::kArrow;
20*3ac0a46fSAndroid Build Coastguard Worker }
21*3ac0a46fSAndroid Build Coastguard Worker
22*3ac0a46fSAndroid Build Coastguard Worker CPWL_SBButton::~CPWL_SBButton() = default;
23*3ac0a46fSAndroid Build Coastguard Worker
DrawThisAppearance(CFX_RenderDevice * pDevice,const CFX_Matrix & mtUser2Device)24*3ac0a46fSAndroid Build Coastguard Worker void CPWL_SBButton::DrawThisAppearance(CFX_RenderDevice* pDevice,
25*3ac0a46fSAndroid Build Coastguard Worker const CFX_Matrix& mtUser2Device) {
26*3ac0a46fSAndroid Build Coastguard Worker if (!IsVisible())
27*3ac0a46fSAndroid Build Coastguard Worker return;
28*3ac0a46fSAndroid Build Coastguard Worker
29*3ac0a46fSAndroid Build Coastguard Worker CFX_FloatRect rectWnd = GetWindowRect();
30*3ac0a46fSAndroid Build Coastguard Worker if (rectWnd.IsEmpty())
31*3ac0a46fSAndroid Build Coastguard Worker return;
32*3ac0a46fSAndroid Build Coastguard Worker
33*3ac0a46fSAndroid Build Coastguard Worker CFX_PointF ptCenter = GetCenterPoint();
34*3ac0a46fSAndroid Build Coastguard Worker int32_t nTransparency = GetTransparency();
35*3ac0a46fSAndroid Build Coastguard Worker
36*3ac0a46fSAndroid Build Coastguard Worker // draw border
37*3ac0a46fSAndroid Build Coastguard Worker pDevice->DrawStrokeRect(mtUser2Device, rectWnd,
38*3ac0a46fSAndroid Build Coastguard Worker ArgbEncode(nTransparency, 100, 100, 100), 0.0f);
39*3ac0a46fSAndroid Build Coastguard Worker pDevice->DrawStrokeRect(mtUser2Device, rectWnd.GetDeflated(0.5f, 0.5f),
40*3ac0a46fSAndroid Build Coastguard Worker ArgbEncode(nTransparency, 255, 255, 255), 1.0f);
41*3ac0a46fSAndroid Build Coastguard Worker
42*3ac0a46fSAndroid Build Coastguard Worker if (m_eSBButtonType != Type::kPosButton) {
43*3ac0a46fSAndroid Build Coastguard Worker // draw background
44*3ac0a46fSAndroid Build Coastguard Worker pDevice->DrawShadow(mtUser2Device, rectWnd.GetDeflated(1.0f, 1.0f),
45*3ac0a46fSAndroid Build Coastguard Worker nTransparency, 80, 220);
46*3ac0a46fSAndroid Build Coastguard Worker // draw arrow
47*3ac0a46fSAndroid Build Coastguard Worker if (rectWnd.top - rectWnd.bottom > 6.0f) {
48*3ac0a46fSAndroid Build Coastguard Worker std::vector<CFX_PointF> pts;
49*3ac0a46fSAndroid Build Coastguard Worker CFX_PointF origin(rectWnd.left + 1.5f, rectWnd.bottom);
50*3ac0a46fSAndroid Build Coastguard Worker if (m_eSBButtonType == Type::kMinButton) {
51*3ac0a46fSAndroid Build Coastguard Worker static constexpr CFX_PointF kOffsetsMin[] = {
52*3ac0a46fSAndroid Build Coastguard Worker {2.5f, 4.0f}, {2.5f, 3.0f}, {4.5f, 5.0f}, {6.5f, 3.0f},
53*3ac0a46fSAndroid Build Coastguard Worker {6.5f, 4.0f}, {4.5f, 6.0f}, {2.5f, 4.0f}};
54*3ac0a46fSAndroid Build Coastguard Worker for (const auto& offset : kOffsetsMin) {
55*3ac0a46fSAndroid Build Coastguard Worker pts.push_back(origin + offset);
56*3ac0a46fSAndroid Build Coastguard Worker }
57*3ac0a46fSAndroid Build Coastguard Worker } else {
58*3ac0a46fSAndroid Build Coastguard Worker static constexpr CFX_PointF kOffsets[] = {
59*3ac0a46fSAndroid Build Coastguard Worker {2.5f, 5.0f}, {2.5f, 6.0f}, {4.5f, 4.0f}, {6.5f, 6.0f},
60*3ac0a46fSAndroid Build Coastguard Worker {6.5f, 5.0f}, {4.5f, 3.0f}, {2.5f, 5.0f}};
61*3ac0a46fSAndroid Build Coastguard Worker for (const auto& offset : kOffsets) {
62*3ac0a46fSAndroid Build Coastguard Worker pts.push_back(origin + offset);
63*3ac0a46fSAndroid Build Coastguard Worker }
64*3ac0a46fSAndroid Build Coastguard Worker }
65*3ac0a46fSAndroid Build Coastguard Worker pDevice->DrawFillArea(mtUser2Device, pts,
66*3ac0a46fSAndroid Build Coastguard Worker ArgbEncode(nTransparency, 255, 255, 255));
67*3ac0a46fSAndroid Build Coastguard Worker }
68*3ac0a46fSAndroid Build Coastguard Worker return;
69*3ac0a46fSAndroid Build Coastguard Worker }
70*3ac0a46fSAndroid Build Coastguard Worker
71*3ac0a46fSAndroid Build Coastguard Worker // draw shadow effect
72*3ac0a46fSAndroid Build Coastguard Worker CFX_PointF ptTop = CFX_PointF(rectWnd.left, rectWnd.top - 1.0f);
73*3ac0a46fSAndroid Build Coastguard Worker CFX_PointF ptBottom = CFX_PointF(rectWnd.left, rectWnd.bottom + 1.0f);
74*3ac0a46fSAndroid Build Coastguard Worker
75*3ac0a46fSAndroid Build Coastguard Worker ptTop.x += 1.5f;
76*3ac0a46fSAndroid Build Coastguard Worker ptBottom.x += 1.5f;
77*3ac0a46fSAndroid Build Coastguard Worker
78*3ac0a46fSAndroid Build Coastguard Worker const FX_COLORREF refs[] = {ArgbEncode(nTransparency, 210, 210, 210),
79*3ac0a46fSAndroid Build Coastguard Worker ArgbEncode(nTransparency, 220, 220, 220),
80*3ac0a46fSAndroid Build Coastguard Worker ArgbEncode(nTransparency, 240, 240, 240),
81*3ac0a46fSAndroid Build Coastguard Worker ArgbEncode(nTransparency, 240, 240, 240),
82*3ac0a46fSAndroid Build Coastguard Worker ArgbEncode(nTransparency, 210, 210, 210),
83*3ac0a46fSAndroid Build Coastguard Worker ArgbEncode(nTransparency, 180, 180, 180),
84*3ac0a46fSAndroid Build Coastguard Worker ArgbEncode(nTransparency, 150, 150, 150),
85*3ac0a46fSAndroid Build Coastguard Worker ArgbEncode(nTransparency, 150, 150, 150),
86*3ac0a46fSAndroid Build Coastguard Worker ArgbEncode(nTransparency, 180, 180, 180),
87*3ac0a46fSAndroid Build Coastguard Worker ArgbEncode(nTransparency, 210, 210, 210)};
88*3ac0a46fSAndroid Build Coastguard Worker for (FX_COLORREF ref : refs) {
89*3ac0a46fSAndroid Build Coastguard Worker pDevice->DrawStrokeLine(&mtUser2Device, ptTop, ptBottom, ref, 1.0f);
90*3ac0a46fSAndroid Build Coastguard Worker
91*3ac0a46fSAndroid Build Coastguard Worker ptTop.x += 1.0f;
92*3ac0a46fSAndroid Build Coastguard Worker ptBottom.x += 1.0f;
93*3ac0a46fSAndroid Build Coastguard Worker }
94*3ac0a46fSAndroid Build Coastguard Worker
95*3ac0a46fSAndroid Build Coastguard Worker // draw friction
96*3ac0a46fSAndroid Build Coastguard Worker if (rectWnd.Height() <= 8.0f)
97*3ac0a46fSAndroid Build Coastguard Worker return;
98*3ac0a46fSAndroid Build Coastguard Worker
99*3ac0a46fSAndroid Build Coastguard Worker FX_COLORREF crStroke = ArgbEncode(nTransparency, 120, 120, 120);
100*3ac0a46fSAndroid Build Coastguard Worker float nFrictionWidth = 5.0f;
101*3ac0a46fSAndroid Build Coastguard Worker float nFrictionHeight = 5.5f;
102*3ac0a46fSAndroid Build Coastguard Worker CFX_PointF ptLeft = CFX_PointF(ptCenter.x - nFrictionWidth / 2.0f,
103*3ac0a46fSAndroid Build Coastguard Worker ptCenter.y - nFrictionHeight / 2.0f + 0.5f);
104*3ac0a46fSAndroid Build Coastguard Worker CFX_PointF ptRight = CFX_PointF(ptCenter.x + nFrictionWidth / 2.0f,
105*3ac0a46fSAndroid Build Coastguard Worker ptCenter.y - nFrictionHeight / 2.0f + 0.5f);
106*3ac0a46fSAndroid Build Coastguard Worker
107*3ac0a46fSAndroid Build Coastguard Worker for (size_t i = 0; i < 3; ++i) {
108*3ac0a46fSAndroid Build Coastguard Worker pDevice->DrawStrokeLine(&mtUser2Device, ptLeft, ptRight, crStroke, 1.0f);
109*3ac0a46fSAndroid Build Coastguard Worker ptLeft.y += 2.0f;
110*3ac0a46fSAndroid Build Coastguard Worker ptRight.y += 2.0f;
111*3ac0a46fSAndroid Build Coastguard Worker }
112*3ac0a46fSAndroid Build Coastguard Worker }
113*3ac0a46fSAndroid Build Coastguard Worker
OnLButtonDown(Mask<FWL_EVENTFLAG> nFlag,const CFX_PointF & point)114*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_SBButton::OnLButtonDown(Mask<FWL_EVENTFLAG> nFlag,
115*3ac0a46fSAndroid Build Coastguard Worker const CFX_PointF& point) {
116*3ac0a46fSAndroid Build Coastguard Worker CPWL_Wnd::OnLButtonDown(nFlag, point);
117*3ac0a46fSAndroid Build Coastguard Worker
118*3ac0a46fSAndroid Build Coastguard Worker if (CPWL_Wnd* pParent = GetParentWindow())
119*3ac0a46fSAndroid Build Coastguard Worker pParent->NotifyLButtonDown(this, point);
120*3ac0a46fSAndroid Build Coastguard Worker
121*3ac0a46fSAndroid Build Coastguard Worker m_bMouseDown = true;
122*3ac0a46fSAndroid Build Coastguard Worker SetCapture();
123*3ac0a46fSAndroid Build Coastguard Worker
124*3ac0a46fSAndroid Build Coastguard Worker return true;
125*3ac0a46fSAndroid Build Coastguard Worker }
126*3ac0a46fSAndroid Build Coastguard Worker
OnLButtonUp(Mask<FWL_EVENTFLAG> nFlag,const CFX_PointF & point)127*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_SBButton::OnLButtonUp(Mask<FWL_EVENTFLAG> nFlag,
128*3ac0a46fSAndroid Build Coastguard Worker const CFX_PointF& point) {
129*3ac0a46fSAndroid Build Coastguard Worker CPWL_Wnd::OnLButtonUp(nFlag, point);
130*3ac0a46fSAndroid Build Coastguard Worker
131*3ac0a46fSAndroid Build Coastguard Worker if (CPWL_Wnd* pParent = GetParentWindow())
132*3ac0a46fSAndroid Build Coastguard Worker pParent->NotifyLButtonUp(this, point);
133*3ac0a46fSAndroid Build Coastguard Worker
134*3ac0a46fSAndroid Build Coastguard Worker m_bMouseDown = false;
135*3ac0a46fSAndroid Build Coastguard Worker ReleaseCapture();
136*3ac0a46fSAndroid Build Coastguard Worker
137*3ac0a46fSAndroid Build Coastguard Worker return true;
138*3ac0a46fSAndroid Build Coastguard Worker }
139*3ac0a46fSAndroid Build Coastguard Worker
OnMouseMove(Mask<FWL_EVENTFLAG> nFlag,const CFX_PointF & point)140*3ac0a46fSAndroid Build Coastguard Worker bool CPWL_SBButton::OnMouseMove(Mask<FWL_EVENTFLAG> nFlag,
141*3ac0a46fSAndroid Build Coastguard Worker const CFX_PointF& point) {
142*3ac0a46fSAndroid Build Coastguard Worker CPWL_Wnd::OnMouseMove(nFlag, point);
143*3ac0a46fSAndroid Build Coastguard Worker
144*3ac0a46fSAndroid Build Coastguard Worker if (CPWL_Wnd* pParent = GetParentWindow())
145*3ac0a46fSAndroid Build Coastguard Worker pParent->NotifyMouseMove(this, point);
146*3ac0a46fSAndroid Build Coastguard Worker
147*3ac0a46fSAndroid Build Coastguard Worker return true;
148*3ac0a46fSAndroid Build Coastguard Worker }
149