| OLD | NEW |
| (Empty) |
| 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/core/ifwl_tooltip.h" | |
| 8 | |
| 9 #include <memory> | |
| 10 #include <utility> | |
| 11 | |
| 12 #include "third_party/base/ptr_util.h" | |
| 13 #include "xfa/fde/tto/fde_textout.h" | |
| 14 #include "xfa/fwl/core/cfwl_notedriver.h" | |
| 15 #include "xfa/fwl/core/cfwl_themebackground.h" | |
| 16 #include "xfa/fwl/core/cfwl_themepart.h" | |
| 17 #include "xfa/fwl/core/cfwl_themetext.h" | |
| 18 #include "xfa/fwl/core/ifwl_themeprovider.h" | |
| 19 #include "xfa/fwl/core/ifwl_timerinfo.h" | |
| 20 #include "xfa/fwl/theme/cfwl_widgettp.h" | |
| 21 | |
| 22 IFWL_ToolTip::IFWL_ToolTip(const IFWL_App* app, | |
| 23 std::unique_ptr<CFWL_WidgetProperties> properties, | |
| 24 IFWL_Widget* pOuter) | |
| 25 : IFWL_Form(app, std::move(properties), pOuter), | |
| 26 m_dwTTOStyles(FDE_TTOSTYLE_SingleLine), | |
| 27 m_iTTOAlign(FDE_TTOALIGNMENT_Center), | |
| 28 m_pTimerInfoShow(nullptr), | |
| 29 m_pTimerInfoHide(nullptr), | |
| 30 m_TimerShow(this), | |
| 31 m_TimerHide(this) { | |
| 32 m_rtClient.Set(0, 0, 0, 0); | |
| 33 m_rtCaption.Set(0, 0, 0, 0); | |
| 34 m_rtAnchor.Set(0, 0, 0, 0); | |
| 35 m_pProperties->m_dwStyles &= ~FWL_WGTSTYLE_Child; | |
| 36 m_pProperties->m_dwStyles |= FWL_WGTSTYLE_Popup; | |
| 37 } | |
| 38 | |
| 39 IFWL_ToolTip::~IFWL_ToolTip() {} | |
| 40 | |
| 41 FWL_Type IFWL_ToolTip::GetClassID() const { | |
| 42 return FWL_Type::ToolTip; | |
| 43 } | |
| 44 | |
| 45 void IFWL_ToolTip::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { | |
| 46 if (!bAutoSize) { | |
| 47 rect = m_pProperties->m_rtWidget; | |
| 48 return; | |
| 49 } | |
| 50 | |
| 51 rect.Set(0, 0, 0, 0); | |
| 52 if (!m_pProperties->m_pThemeProvider) | |
| 53 m_pProperties->m_pThemeProvider = GetAvailableTheme(); | |
| 54 | |
| 55 CFX_WideString wsCaption; | |
| 56 if (m_pProperties->m_pDataProvider) | |
| 57 m_pProperties->m_pDataProvider->GetCaption(this, wsCaption); | |
| 58 | |
| 59 int32_t iLen = wsCaption.GetLength(); | |
| 60 if (iLen > 0) { | |
| 61 CFX_SizeF sz = CalcTextSize(wsCaption, m_pProperties->m_pThemeProvider); | |
| 62 rect.Set(0, 0, sz.x, sz.y); | |
| 63 rect.width += 25; | |
| 64 rect.height += 16; | |
| 65 } | |
| 66 IFWL_Widget::GetWidgetRect(rect, true); | |
| 67 } | |
| 68 | |
| 69 void IFWL_ToolTip::Update() { | |
| 70 if (IsLocked()) | |
| 71 return; | |
| 72 if (!m_pProperties->m_pThemeProvider) | |
| 73 m_pProperties->m_pThemeProvider = GetAvailableTheme(); | |
| 74 | |
| 75 UpdateTextOutStyles(); | |
| 76 GetClientRect(m_rtClient); | |
| 77 m_rtCaption = m_rtClient; | |
| 78 } | |
| 79 | |
| 80 void IFWL_ToolTip::GetClientRect(CFX_RectF& rect) { | |
| 81 FX_FLOAT x = 0; | |
| 82 FX_FLOAT y = 0; | |
| 83 FX_FLOAT t = 0; | |
| 84 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; | |
| 85 if (pTheme) { | |
| 86 CFWL_ThemePart part; | |
| 87 part.m_pWidget = this; | |
| 88 x = *static_cast<FX_FLOAT*>( | |
| 89 pTheme->GetCapacity(&part, CFWL_WidgetCapacity::CXBorder)); | |
| 90 y = *static_cast<FX_FLOAT*>( | |
| 91 pTheme->GetCapacity(&part, CFWL_WidgetCapacity::CYBorder)); | |
| 92 } | |
| 93 rect = m_pProperties->m_rtWidget; | |
| 94 rect.Offset(-rect.left, -rect.top); | |
| 95 rect.Deflate(x, t, x, y); | |
| 96 } | |
| 97 | |
| 98 void IFWL_ToolTip::DrawWidget(CFX_Graphics* pGraphics, | |
| 99 const CFX_Matrix* pMatrix) { | |
| 100 if (!pGraphics || !m_pProperties->m_pThemeProvider) | |
| 101 return; | |
| 102 | |
| 103 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; | |
| 104 DrawBkground(pGraphics, pTheme, pMatrix); | |
| 105 DrawText(pGraphics, pTheme, pMatrix); | |
| 106 } | |
| 107 | |
| 108 void IFWL_ToolTip::DrawBkground(CFX_Graphics* pGraphics, | |
| 109 IFWL_ThemeProvider* pTheme, | |
| 110 const CFX_Matrix* pMatrix) { | |
| 111 CFWL_ThemeBackground param; | |
| 112 param.m_pWidget = this; | |
| 113 param.m_iPart = CFWL_Part::Background; | |
| 114 param.m_dwStates = m_pProperties->m_dwStates; | |
| 115 param.m_pGraphics = pGraphics; | |
| 116 if (pMatrix) | |
| 117 param.m_matrix.Concat(*pMatrix); | |
| 118 param.m_rtPart = m_rtClient; | |
| 119 if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) | |
| 120 param.m_pData = &m_rtCaption; | |
| 121 pTheme->DrawBackground(¶m); | |
| 122 } | |
| 123 | |
| 124 void IFWL_ToolTip::DrawText(CFX_Graphics* pGraphics, | |
| 125 IFWL_ThemeProvider* pTheme, | |
| 126 const CFX_Matrix* pMatrix) { | |
| 127 if (!m_pProperties->m_pDataProvider) | |
| 128 return; | |
| 129 | |
| 130 CFX_WideString wsCaption; | |
| 131 m_pProperties->m_pDataProvider->GetCaption(this, wsCaption); | |
| 132 if (wsCaption.IsEmpty()) | |
| 133 return; | |
| 134 | |
| 135 CFWL_ThemeText param; | |
| 136 param.m_pWidget = this; | |
| 137 param.m_iPart = CFWL_Part::Caption; | |
| 138 param.m_dwStates = m_pProperties->m_dwStates; | |
| 139 param.m_pGraphics = pGraphics; | |
| 140 if (pMatrix) | |
| 141 param.m_matrix.Concat(*pMatrix); | |
| 142 param.m_rtPart = m_rtCaption; | |
| 143 param.m_wsText = wsCaption; | |
| 144 param.m_dwTTOStyles = m_dwTTOStyles; | |
| 145 param.m_iTTOAlign = m_iTTOAlign; | |
| 146 pTheme->DrawText(¶m); | |
| 147 } | |
| 148 | |
| 149 void IFWL_ToolTip::UpdateTextOutStyles() { | |
| 150 m_iTTOAlign = FDE_TTOALIGNMENT_Center; | |
| 151 m_dwTTOStyles = FDE_TTOSTYLE_SingleLine; | |
| 152 if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading) | |
| 153 m_dwTTOStyles |= FDE_TTOSTYLE_RTL; | |
| 154 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_TTP_Multiline) | |
| 155 m_dwTTOStyles &= ~FDE_TTOSTYLE_SingleLine; | |
| 156 } | |
| 157 | |
| 158 void IFWL_ToolTip::RefreshToolTipPos() { | |
| 159 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_TTP_NoAnchor) == 0) { | |
| 160 CFX_RectF rtPopup; | |
| 161 CFX_RectF rtWidget(m_pProperties->m_rtWidget); | |
| 162 CFX_RectF rtAnchor(m_rtAnchor); | |
| 163 rtPopup.Set(0, 0, 0, 0); | |
| 164 FX_FLOAT fx = rtAnchor.Center().x + 20; | |
| 165 FX_FLOAT fy = rtAnchor.Center().y + 20; | |
| 166 rtPopup.Set(fx, fy, rtWidget.Width(), rtWidget.Height()); | |
| 167 | |
| 168 if (rtPopup.bottom() > 0.0f) | |
| 169 rtPopup.Offset(0, 0.0f - rtPopup.bottom()); | |
| 170 if (rtPopup.right() > 0.0f) | |
| 171 rtPopup.Offset(0.0f - rtPopup.right(), 0); | |
| 172 if (rtPopup.left < 0) | |
| 173 rtPopup.Offset(0 - rtPopup.left, 0); | |
| 174 if (rtPopup.top < 0) | |
| 175 rtPopup.Offset(0, 0 - rtPopup.top); | |
| 176 | |
| 177 SetWidgetRect(rtPopup); | |
| 178 Update(); | |
| 179 } | |
| 180 } | |
| 181 | |
| 182 void IFWL_ToolTip::OnDrawWidget(CFX_Graphics* pGraphics, | |
| 183 const CFX_Matrix* pMatrix) { | |
| 184 DrawWidget(pGraphics, pMatrix); | |
| 185 } | |
| 186 | |
| 187 IFWL_ToolTip::Timer::Timer(IFWL_ToolTip* pToolTip) : IFWL_Timer(pToolTip) {} | |
| 188 | |
| 189 void IFWL_ToolTip::Timer::Run(IFWL_TimerInfo* pTimerInfo) { | |
| 190 IFWL_ToolTip* pToolTip = static_cast<IFWL_ToolTip*>(m_pWidget); | |
| 191 | |
| 192 if (pToolTip->m_pTimerInfoShow == pTimerInfo && pToolTip->m_pTimerInfoShow) { | |
| 193 if (pToolTip->GetStates() & FWL_WGTSTATE_Invisible) { | |
| 194 pToolTip->SetStates(FWL_WGTSTATE_Invisible, false); | |
| 195 pToolTip->RefreshToolTipPos(); | |
| 196 pToolTip->m_pTimerInfoShow->StopTimer(); | |
| 197 pToolTip->m_pTimerInfoShow = nullptr; | |
| 198 return; | |
| 199 } | |
| 200 } | |
| 201 if (pToolTip->m_pTimerInfoHide == pTimerInfo && pToolTip->m_pTimerInfoHide) { | |
| 202 pToolTip->SetStates(FWL_WGTSTATE_Invisible, true); | |
| 203 pToolTip->m_pTimerInfoHide->StopTimer(); | |
| 204 pToolTip->m_pTimerInfoHide = nullptr; | |
| 205 } | |
| 206 } | |
| OLD | NEW |