1 // Copyright 2014 PDFium Authors. All rights reserved.
\r
2 // Use of this source code is governed by a BSD-style license that can be
\r
3 // found in the LICENSE file.
\r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
\r
7 #include "../../../foxitlib.h"
\r
8 #include "../core/include/fwl_targetimp.h"
\r
9 #include "../core/include/fwl_noteimp.h"
\r
10 #include "../core/include/fwl_widgetimp.h"
\r
11 #include "../core/include/fwl_panelimp.h"
\r
12 #include "../core/include/fwl_formimp.h"
\r
13 #include "include/fwl_tooltipctrlimp.h"
\r
14 IFWL_ToolTip *IFWL_ToolTip::Create()
\r
16 return new IFWL_ToolTip;
\r
18 FWL_ERR IFWL_ToolTip::Initialize(IFWL_Widget *pOuter)
\r
20 m_pData = FX_NEW CFWL_ToolTipImp(pOuter);
\r
21 ((CFWL_ToolTipImp*)m_pData)->SetInterface(this);
\r
22 return ((CFWL_ToolTipImp*)m_pData)->Initialize();
\r
24 FWL_ERR IFWL_ToolTip::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
\r
26 m_pData = FX_NEW CFWL_ToolTipImp(properties, pOuter);
\r
27 ((CFWL_ToolTipImp*)m_pData)->SetInterface(this);
\r
28 return ((CFWL_ToolTipImp*)m_pData)->Initialize();
\r
30 FWL_ERR IFWL_ToolTip::SetAnchor(const CFX_RectF &rtAnchor)
\r
32 return ((CFWL_ToolTipImp*)m_pData)->SetAnchor( rtAnchor);
\r
34 FWL_ERR IFWL_ToolTip::Show()
\r
36 return ((CFWL_ToolTipImp*)m_pData)->Show();
\r
38 FWL_ERR IFWL_ToolTip::Hide()
\r
40 return ((CFWL_ToolTipImp*)m_pData)->Hide();
\r
42 IFWL_ToolTip::IFWL_ToolTip()
\r
46 IFWL_ToolTip::~IFWL_ToolTip()
\r
49 delete (CFWL_ToolTipImp*)m_pData;
\r
53 CFWL_ToolTipImp::CFWL_ToolTipImp(IFWL_Widget *pOuter )
\r
54 : CFWL_FormImp(pOuter)
\r
56 , m_dwTTOStyles(FDE_TTOSTYLE_SingleLine)
\r
57 , m_iTTOAlign(FDE_TTOALIGNMENT_Center)
\r
58 , m_hTimerShow(NULL)
\r
59 , m_hTimerHide(NULL)
\r
62 m_rtClient.Set(0, 0, 0, 0);
\r
63 m_rtCaption.Set(0, 0, 0, 0);
\r
65 m_TimerShow.m_pToolTip = this;
\r
66 m_TimerHide.m_pToolTip = this;
\r
68 CFWL_ToolTipImp::CFWL_ToolTipImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
\r
69 : CFWL_FormImp(properties, pOuter)
\r
71 , m_dwTTOStyles(FDE_TTOSTYLE_SingleLine)
\r
72 , m_iTTOAlign(FDE_TTOALIGNMENT_Center)
\r
73 , m_hTimerShow(NULL)
\r
74 , m_hTimerHide(NULL)
\r
77 m_rtClient.Set(0, 0, 0, 0);
\r
78 m_rtCaption.Set(0, 0, 0, 0);
\r
79 m_rtAnchor.Set(0, 0, 0, 0);
\r
80 m_TimerShow.m_pToolTip = this;
\r
81 m_TimerHide.m_pToolTip = this;
\r
83 CFWL_ToolTipImp::~CFWL_ToolTipImp()
\r
90 FWL_ERR CFWL_ToolTipImp::GetClassName(CFX_WideString &wsClass) const
\r
92 wsClass = FWL_CLASS_ToolTip;
\r
93 return FWL_ERR_Succeeded;
\r
95 FX_DWORD CFWL_ToolTipImp::GetClassID() const
\r
97 return FWL_CLASSHASH_ToolTip;
\r
99 FWL_ERR CFWL_ToolTipImp::Initialize()
\r
101 m_pProperties->m_dwStyles |= FWL_WGTSTYLE_Popup;
\r
102 m_pProperties->m_dwStyles &= ~FWL_WGTSTYLE_Child;
\r
103 _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);
\r
104 m_pDelegate = (IFWL_WidgetDelegate*) FX_NEW CFWL_ToolTipImpDelegate(this);
\r
105 return FWL_ERR_Succeeded;
\r
107 FWL_ERR CFWL_ToolTipImp::Finalize()
\r
109 if ( m_pDelegate) {
\r
110 delete (CFWL_ToolTipImpDelegate*)m_pDelegate;
\r
111 m_pDelegate = NULL;
\r
113 return CFWL_WidgetImp::Finalize();
\r
115 FWL_ERR CFWL_ToolTipImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
\r
118 rect.Set(0, 0, 0, 0);
\r
119 if (m_pProperties->m_pThemeProvider == NULL) {
\r
120 m_pProperties->m_pThemeProvider = GetAvailableTheme();
\r
122 CFX_WideString wsCaption;
\r
123 IFWL_ToolTipDP *pData = (IFWL_ToolTipDP*)m_pProperties->m_pDataProvider;
\r
125 pData->GetCaption(m_pInterface, wsCaption);
\r
127 FX_INT32 iLen = wsCaption.GetLength();
\r
129 CFX_SizeF sz = CalcTextSize(wsCaption, m_pProperties->m_pThemeProvider);
\r
130 rect.Set(0, 0, sz.x, sz.y);
\r
131 rect.width += FWL_WGTCAPACITY_CXBorder * 25;
\r
132 rect.height += FWL_WGTCAPACITY_CYBorder * 8;
\r
134 CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
\r
136 rect = m_pProperties->m_rtWidget;
\r
138 return FWL_ERR_Succeeded;
\r
140 FWL_ERR CFWL_ToolTipImp::Update()
\r
143 return FWL_ERR_Indefinite;
\r
145 if (!m_pProperties->m_pThemeProvider) {
\r
146 m_pProperties->m_pThemeProvider = GetAvailableTheme();
\r
148 UpdateTextOutStyles();
\r
149 GetClientRect(m_rtClient);
\r
150 m_rtCaption = m_rtClient;
\r
151 return FWL_ERR_Succeeded;
\r
153 FWL_ERR CFWL_ToolTipImp::GetClientRect(CFX_RectF &rect)
\r
158 IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
\r
160 CFWL_ThemePart part;
\r
161 part.m_pWidget = m_pInterface;
\r
162 FX_FLOAT * value = NULL;
\r
163 value = (FX_FLOAT *) pTheme->GetCapacity(&part, FWL_WGTCAPACITY_CXBorder);
\r
165 value = (FX_FLOAT *) pTheme->GetCapacity(&part, FWL_WGTCAPACITY_CYBorder);
\r
168 rect = m_pProperties->m_rtWidget;
\r
169 rect.Offset(-rect.left, -rect.top);
\r
170 rect.Deflate(x, t, x, y);
\r
171 return FWL_ERR_Succeeded;
\r
173 FWL_ERR CFWL_ToolTipImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
\r
175 IFWL_ToolTipTarget * toolTipTarget = CFWL_ToolTipContainer::getInstance()->GetCurrentToolTipTarget();
\r
176 if (toolTipTarget && !toolTipTarget->UseDefaultTheme()) {
\r
177 return toolTipTarget->DrawToolTip(pGraphics, pMatrix, m_pInterface);
\r
179 _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
\r
180 _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, FWL_ERR_Indefinite);
\r
181 IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
\r
182 DrawBkground(pGraphics, pTheme, pMatrix);
\r
183 DrawText(pGraphics, pTheme, pMatrix);
\r
184 return FWL_ERR_Succeeded;
\r
186 void CFWL_ToolTipImp::DrawBkground(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
\r
188 CFWL_ThemeBackground param;
\r
189 param.m_pWidget = m_pInterface;
\r
190 param.m_iPart = FWL_PART_TTP_Background;
\r
191 param.m_dwStates = m_pProperties->m_dwStates;
\r
192 param.m_pGraphics = pGraphics;
\r
194 param.m_matrix.Concat(*pMatrix);
\r
196 param.m_rtPart = m_rtClient;
\r
197 if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
\r
198 param.m_pData = &m_rtCaption;
\r
200 pTheme->DrawBackground(¶m);
\r
202 void CFWL_ToolTipImp::DrawText(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
\r
204 _FWL_RETURN_IF_FAIL(m_pProperties->m_pDataProvider);
\r
205 CFX_WideString wsCaption;
\r
206 m_pProperties->m_pDataProvider->GetCaption(m_pInterface, wsCaption);
\r
207 if (wsCaption.IsEmpty()) {
\r
210 CFWL_ThemeText param;
\r
211 param.m_pWidget = m_pInterface;
\r
212 param.m_iPart = FWL_PART_TTP_Caption;
\r
213 param.m_dwStates = m_pProperties->m_dwStates;
\r
214 param.m_pGraphics = pGraphics;
\r
216 param.m_matrix.Concat(*pMatrix);
\r
218 param.m_rtPart = m_rtCaption;
\r
219 param.m_wsText = wsCaption;
\r
220 param.m_dwTTOStyles = m_dwTTOStyles;
\r
221 param.m_iTTOAlign = m_iTTOAlign;
\r
222 pTheme->DrawText(¶m);
\r
224 void CFWL_ToolTipImp::UpdateTextOutStyles()
\r
226 m_iTTOAlign = FDE_TTOALIGNMENT_Center;
\r
227 m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
\r
228 if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading) {
\r
229 m_dwTTOStyles |= FDE_TTOSTYLE_RTL;
\r
231 if ( m_pProperties->m_dwStyleExes & FWL_STYLEEXT_TTP_Multiline) {
\r
232 m_dwTTOStyles &= ~FDE_TTOSTYLE_SingleLine;
\r
235 FWL_ERR CFWL_ToolTipImp::SetAnchor(const CFX_RectF &rtAnchor)
\r
237 m_rtAnchor = rtAnchor;
\r
240 FWL_ERR CFWL_ToolTipImp::Show()
\r
242 IFWL_ToolTipDP *pData = (IFWL_ToolTipDP*)m_pProperties->m_pDataProvider;
\r
243 FX_INT32 nInitDelay = pData->GetInitialDelay(m_pInterface);
\r
244 if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible)) {
\r
245 m_hTimerShow = FWL_StartTimer( &m_TimerShow, nInitDelay, FALSE);
\r
249 FWL_ERR CFWL_ToolTipImp::Hide()
\r
251 SetStates( FWL_WGTSTATE_Invisible, TRUE);
\r
252 if ( m_hTimerHide) {
\r
253 FWL_StopTimer(m_hTimerHide);
\r
254 m_hTimerHide = NULL;
\r
256 if ( m_hTimerShow) {
\r
257 FWL_StopTimer(m_hTimerShow);
\r
258 m_hTimerShow = NULL;
\r
262 FWL_ERR CFWL_ToolTipImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet )
\r
264 if ( (dwStates & FWL_WGTSTATE_Invisible) && !bSet) {
\r
265 IFWL_ToolTipDP *pData = (IFWL_ToolTipDP*)m_pProperties->m_pDataProvider;
\r
266 FX_INT32 nAutoPopDelay = pData->GetAutoPopDelay(m_pInterface);
\r
267 m_hTimerHide = FWL_StartTimer( &m_TimerHide, nAutoPopDelay, FALSE);
\r
269 return CFWL_WidgetImp::SetStates(dwStates, bSet);
\r
271 void CFWL_ToolTipImp::RefreshToolTipPos()
\r
273 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_TTP_NoAnchor) == 0) {
\r
275 CFX_RectF rtWidget(m_pProperties->m_rtWidget);
\r
276 CFX_RectF rtAnchor(m_rtAnchor);
\r
277 rtPopup.Set( 0, 0, 0, 0);
\r
278 FX_FLOAT fx = rtAnchor.Center().x + 20;
\r
279 FX_FLOAT fy = rtAnchor.Center().y + 20;
\r
280 rtPopup.Set( fx, fy, rtWidget.Width(), rtWidget.Height());
\r
281 FX_FLOAT fScreenWidth = 0;
\r
282 FX_FLOAT fScreenHeight = 0;
\r
283 GetScreenSize(fScreenWidth, fScreenHeight);
\r
284 if (rtPopup.bottom() > fScreenHeight) {
\r
285 rtPopup.Offset( 0, fScreenHeight - rtPopup.bottom());
\r
287 if ( rtPopup.right() > fScreenWidth) {
\r
288 rtPopup.Offset( fScreenWidth - rtPopup.right(), 0);
\r
290 if ( rtPopup.left < 0) {
\r
291 rtPopup.Offset(0 - rtPopup.left, 0);
\r
293 if ( rtPopup.top < 0) {
\r
294 rtPopup.Offset( 0, 0 - rtPopup.top);
\r
296 SetWidgetRect(rtPopup);
\r
300 CFWL_ToolTipImp::CFWL_ToolTipTimer::CFWL_ToolTipTimer(CFWL_ToolTipImp * pToolTip)
\r
301 : m_pToolTip(pToolTip)
\r
304 FX_INT32 CFWL_ToolTipImp::CFWL_ToolTipTimer::Run(FWL_HTIMER hTimer)
\r
306 if (m_pToolTip->m_hTimerShow == hTimer && m_pToolTip->m_hTimerShow) {
\r
307 if (m_pToolTip->GetStates() & FWL_WGTSTATE_Invisible) {
\r
308 m_pToolTip->SetStates(FWL_WGTSTATE_Invisible, FALSE);
\r
309 m_pToolTip->RefreshToolTipPos();
\r
310 FWL_StopTimer(m_pToolTip->m_hTimerShow);
\r
311 m_pToolTip->m_hTimerShow = NULL;
\r
315 if (m_pToolTip->m_hTimerHide == hTimer && m_pToolTip->m_hTimerHide) {
\r
316 m_pToolTip->SetStates(FWL_WGTSTATE_Invisible, TRUE);
\r
317 FWL_StopTimer(m_pToolTip->m_hTimerHide);
\r
318 m_pToolTip->m_hTimerHide = NULL;
\r
323 CFWL_ToolTipImpDelegate::CFWL_ToolTipImpDelegate(CFWL_ToolTipImp *pOwner)
\r
327 FX_INT32 CFWL_ToolTipImpDelegate::OnProcessMessage(CFWL_Message *pMessage)
\r
329 return CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
\r
331 FWL_ERR CFWL_ToolTipImpDelegate::OnProcessEvent(CFWL_Event *pEvent)
\r
333 return FWL_ERR_Succeeded;
\r
335 FWL_ERR CFWL_ToolTipImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
\r
337 return m_pOwner->DrawWidget(pGraphics, pMatrix);
\r