1 // Copyright 2014 PDFium Authors. All rights reserved.
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 "xfa/fwl/cfwl_caret.h"
8 
9 #include <utility>
10 
11 #include "third_party/base/ptr_util.h"
12 #include "xfa/fwl/cfwl_notedriver.h"
13 #include "xfa/fwl/cfwl_themebackground.h"
14 #include "xfa/fwl/cfwl_timerinfo.h"
15 #include "xfa/fwl/cfwl_widgetproperties.h"
16 #include "xfa/fwl/ifwl_themeprovider.h"
17 
18 namespace {
19 
20 const uint32_t kFrequency = 400;
21 
22 constexpr int kStateHighlight = (1 << 0);
23 
24 }  // namespace
25 
CFWL_Caret(const CFWL_App * app,std::unique_ptr<CFWL_WidgetProperties> properties,CFWL_Widget * pOuter)26 CFWL_Caret::CFWL_Caret(const CFWL_App* app,
27                        std::unique_ptr<CFWL_WidgetProperties> properties,
28                        CFWL_Widget* pOuter)
29     : CFWL_Widget(app, std::move(properties), pOuter),
30       m_pTimer(pdfium::MakeUnique<CFWL_Caret::Timer>(this)),
31       m_pTimerInfo(nullptr) {
32   SetStates(kStateHighlight);
33 }
34 
~CFWL_Caret()35 CFWL_Caret::~CFWL_Caret() {
36   if (m_pTimerInfo) {
37     m_pTimerInfo->StopTimer();
38     m_pTimerInfo = nullptr;
39   }
40 }
41 
GetClassID() const42 FWL_Type CFWL_Caret::GetClassID() const {
43   return FWL_Type::Caret;
44 }
45 
Update()46 void CFWL_Caret::Update() {}
47 
DrawWidget(CXFA_Graphics * pGraphics,const CFX_Matrix & matrix)48 void CFWL_Caret::DrawWidget(CXFA_Graphics* pGraphics,
49                             const CFX_Matrix& matrix) {
50   if (!pGraphics)
51     return;
52   if (!m_pProperties->m_pThemeProvider)
53     m_pProperties->m_pThemeProvider = GetAvailableTheme();
54   if (!m_pProperties->m_pThemeProvider)
55     return;
56 
57   DrawCaretBK(pGraphics, m_pProperties->m_pThemeProvider, &matrix);
58 }
59 
ShowCaret()60 void CFWL_Caret::ShowCaret() {
61   if (m_pTimerInfo)
62     m_pTimerInfo->StopTimer();
63   m_pTimerInfo = m_pTimer->StartTimer(kFrequency, true);
64   RemoveStates(FWL_WGTSTATE_Invisible);
65 }
66 
HideCaret()67 void CFWL_Caret::HideCaret() {
68   if (m_pTimerInfo) {
69     m_pTimerInfo->StopTimer();
70     m_pTimerInfo = nullptr;
71   }
72   SetStates(FWL_WGTSTATE_Invisible);
73 }
74 
DrawCaretBK(CXFA_Graphics * pGraphics,IFWL_ThemeProvider * pTheme,const CFX_Matrix * pMatrix)75 void CFWL_Caret::DrawCaretBK(CXFA_Graphics* pGraphics,
76                              IFWL_ThemeProvider* pTheme,
77                              const CFX_Matrix* pMatrix) {
78   if (!(m_pProperties->m_dwStates & kStateHighlight))
79     return;
80 
81   CFWL_ThemeBackground param;
82   param.m_pWidget = this;
83   param.m_pGraphics = pGraphics;
84   param.m_rtPart = CFX_RectF(0, 0, GetWidgetRect().Size());
85   param.m_iPart = CFWL_Part::Background;
86   param.m_dwStates = CFWL_PartState_HightLight;
87   if (pMatrix)
88     param.m_matrix.Concat(*pMatrix);
89   pTheme->DrawBackground(&param);
90 }
91 
OnProcessMessage(CFWL_Message * pMessage)92 void CFWL_Caret::OnProcessMessage(CFWL_Message* pMessage) {}
93 
OnDrawWidget(CXFA_Graphics * pGraphics,const CFX_Matrix & matrix)94 void CFWL_Caret::OnDrawWidget(CXFA_Graphics* pGraphics,
95                               const CFX_Matrix& matrix) {
96   DrawWidget(pGraphics, matrix);
97 }
98 
Timer(CFWL_Caret * pCaret)99 CFWL_Caret::Timer::Timer(CFWL_Caret* pCaret) : CFWL_Timer(pCaret) {}
100 
Run(CFWL_TimerInfo * pTimerInfo)101 void CFWL_Caret::Timer::Run(CFWL_TimerInfo* pTimerInfo) {
102   CFWL_Caret* pCaret = static_cast<CFWL_Caret*>(m_pWidget.Get());
103   if (!(pCaret->GetStates() & kStateHighlight))
104     pCaret->SetStates(kStateHighlight);
105   else
106     pCaret->RemoveStates(kStateHighlight);
107 
108   CFX_RectF rt = pCaret->GetWidgetRect();
109   pCaret->RepaintRect(CFX_RectF(0, 0, rt.width + 1, rt.height));
110 }
111