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