// Copyright 2021 The PDFium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "fpdfsdk/pwl/cpwl_sbbutton.h" #include #include #include "core/fxge/cfx_renderdevice.h" CPWL_SBButton::CPWL_SBButton( const CreateParams& cp, std::unique_ptr pAttachedData, Type eButtonType) : CPWL_Wnd(cp, std::move(pAttachedData)), m_eSBButtonType(eButtonType) { GetCreationParams()->eCursorType = IPWL_FillerNotify::CursorStyle::kArrow; } CPWL_SBButton::~CPWL_SBButton() = default; void CPWL_SBButton::DrawThisAppearance(CFX_RenderDevice* pDevice, const CFX_Matrix& mtUser2Device) { if (!IsVisible()) return; CFX_FloatRect rectWnd = GetWindowRect(); if (rectWnd.IsEmpty()) return; CFX_PointF ptCenter = GetCenterPoint(); int32_t nTransparency = GetTransparency(); // draw border pDevice->DrawStrokeRect(mtUser2Device, rectWnd, ArgbEncode(nTransparency, 100, 100, 100), 0.0f); pDevice->DrawStrokeRect(mtUser2Device, rectWnd.GetDeflated(0.5f, 0.5f), ArgbEncode(nTransparency, 255, 255, 255), 1.0f); if (m_eSBButtonType != Type::kPosButton) { // draw background pDevice->DrawShadow(mtUser2Device, rectWnd.GetDeflated(1.0f, 1.0f), nTransparency, 80, 220); // draw arrow if (rectWnd.top - rectWnd.bottom > 6.0f) { std::vector pts; CFX_PointF origin(rectWnd.left + 1.5f, rectWnd.bottom); if (m_eSBButtonType == Type::kMinButton) { static constexpr CFX_PointF kOffsetsMin[] = { {2.5f, 4.0f}, {2.5f, 3.0f}, {4.5f, 5.0f}, {6.5f, 3.0f}, {6.5f, 4.0f}, {4.5f, 6.0f}, {2.5f, 4.0f}}; for (const auto& offset : kOffsetsMin) { pts.push_back(origin + offset); } } else { static constexpr CFX_PointF kOffsets[] = { {2.5f, 5.0f}, {2.5f, 6.0f}, {4.5f, 4.0f}, {6.5f, 6.0f}, {6.5f, 5.0f}, {4.5f, 3.0f}, {2.5f, 5.0f}}; for (const auto& offset : kOffsets) { pts.push_back(origin + offset); } } pDevice->DrawFillArea(mtUser2Device, pts, ArgbEncode(nTransparency, 255, 255, 255)); } return; } // draw shadow effect CFX_PointF ptTop = CFX_PointF(rectWnd.left, rectWnd.top - 1.0f); CFX_PointF ptBottom = CFX_PointF(rectWnd.left, rectWnd.bottom + 1.0f); ptTop.x += 1.5f; ptBottom.x += 1.5f; const FX_COLORREF refs[] = {ArgbEncode(nTransparency, 210, 210, 210), ArgbEncode(nTransparency, 220, 220, 220), ArgbEncode(nTransparency, 240, 240, 240), ArgbEncode(nTransparency, 240, 240, 240), ArgbEncode(nTransparency, 210, 210, 210), ArgbEncode(nTransparency, 180, 180, 180), ArgbEncode(nTransparency, 150, 150, 150), ArgbEncode(nTransparency, 150, 150, 150), ArgbEncode(nTransparency, 180, 180, 180), ArgbEncode(nTransparency, 210, 210, 210)}; for (FX_COLORREF ref : refs) { pDevice->DrawStrokeLine(&mtUser2Device, ptTop, ptBottom, ref, 1.0f); ptTop.x += 1.0f; ptBottom.x += 1.0f; } // draw friction if (rectWnd.Height() <= 8.0f) return; FX_COLORREF crStroke = ArgbEncode(nTransparency, 120, 120, 120); float nFrictionWidth = 5.0f; float nFrictionHeight = 5.5f; CFX_PointF ptLeft = CFX_PointF(ptCenter.x - nFrictionWidth / 2.0f, ptCenter.y - nFrictionHeight / 2.0f + 0.5f); CFX_PointF ptRight = CFX_PointF(ptCenter.x + nFrictionWidth / 2.0f, ptCenter.y - nFrictionHeight / 2.0f + 0.5f); for (size_t i = 0; i < 3; ++i) { pDevice->DrawStrokeLine(&mtUser2Device, ptLeft, ptRight, crStroke, 1.0f); ptLeft.y += 2.0f; ptRight.y += 2.0f; } } bool CPWL_SBButton::OnLButtonDown(Mask nFlag, const CFX_PointF& point) { CPWL_Wnd::OnLButtonDown(nFlag, point); if (CPWL_Wnd* pParent = GetParentWindow()) pParent->NotifyLButtonDown(this, point); m_bMouseDown = true; SetCapture(); return true; } bool CPWL_SBButton::OnLButtonUp(Mask nFlag, const CFX_PointF& point) { CPWL_Wnd::OnLButtonUp(nFlag, point); if (CPWL_Wnd* pParent = GetParentWindow()) pParent->NotifyLButtonUp(this, point); m_bMouseDown = false; ReleaseCapture(); return true; } bool CPWL_SBButton::OnMouseMove(Mask nFlag, const CFX_PointF& point) { CPWL_Wnd::OnMouseMove(nFlag, point); if (CPWL_Wnd* pParent = GetParentWindow()) pParent->NotifyMouseMove(this, point); return true; }