OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "xfa/fwl/core/cfwl_widget.h" | 7 #include "xfa/fwl/core/cfwl_widget.h" |
8 | 8 |
| 9 #include <algorithm> |
| 10 #include <utility> |
| 11 |
9 #include "xfa/fde/tto/fde_textout.h" | 12 #include "xfa/fde/tto/fde_textout.h" |
10 #include "xfa/fwl/core/cfwl_app.h" | 13 #include "xfa/fwl/core/cfwl_app.h" |
| 14 #include "xfa/fwl/core/cfwl_combobox.h" |
| 15 #include "xfa/fwl/core/cfwl_evtkey.h" |
| 16 #include "xfa/fwl/core/cfwl_evtkillfocus.h" |
| 17 #include "xfa/fwl/core/cfwl_evtmouse.h" |
| 18 #include "xfa/fwl/core/cfwl_evtmousewheel.h" |
| 19 #include "xfa/fwl/core/cfwl_evtsetfocus.h" |
| 20 #include "xfa/fwl/core/cfwl_evtsizechanged.h" |
| 21 #include "xfa/fwl/core/cfwl_form.h" |
| 22 #include "xfa/fwl/core/cfwl_msgkey.h" |
| 23 #include "xfa/fwl/core/cfwl_msgkillfocus.h" |
| 24 #include "xfa/fwl/core/cfwl_msgmouse.h" |
| 25 #include "xfa/fwl/core/cfwl_msgmousewheel.h" |
| 26 #include "xfa/fwl/core/cfwl_msgsetfocus.h" |
11 #include "xfa/fwl/core/cfwl_notedriver.h" | 27 #include "xfa/fwl/core/cfwl_notedriver.h" |
| 28 #include "xfa/fwl/core/cfwl_themebackground.h" |
| 29 #include "xfa/fwl/core/cfwl_themepart.h" |
12 #include "xfa/fwl/core/cfwl_themetext.h" | 30 #include "xfa/fwl/core/cfwl_themetext.h" |
13 #include "xfa/fwl/core/cfwl_widgetmgr.h" | 31 #include "xfa/fwl/core/cfwl_widgetmgr.h" |
14 #include "xfa/fwl/core/ifwl_themeprovider.h" | 32 #include "xfa/fwl/core/ifwl_themeprovider.h" |
15 | 33 #include "xfa/fxfa/xfa_ffapp.h" |
| 34 |
| 35 #define FWL_STYLEEXT_MNU_Vert (1L << 0) |
16 #define FWL_WGT_CalcHeight 2048 | 36 #define FWL_WGT_CalcHeight 2048 |
17 #define FWL_WGT_CalcWidth 2048 | 37 #define FWL_WGT_CalcWidth 2048 |
18 #define FWL_WGT_CalcMultiLineDefWidth 120.0f | 38 #define FWL_WGT_CalcMultiLineDefWidth 120.0f |
19 | 39 |
20 CFWL_Widget::CFWL_Widget(const CFWL_App* app) : m_pApp(app) {} | 40 CFWL_Widget::CFWL_Widget(const CFWL_App* app, |
21 | 41 std::unique_ptr<CFWL_WidgetProperties> properties, |
22 CFWL_Widget::~CFWL_Widget() {} | 42 CFWL_Widget* pOuter) |
23 | 43 : m_pOwnerApp(app), |
24 void CFWL_Widget::Initialize() { | 44 m_pWidgetMgr(app->GetWidgetMgr()), |
25 ASSERT(m_pIface); | 45 m_pProperties(std::move(properties)), |
26 m_pIface->SetAssociateWidget(this); | 46 m_pOuter(pOuter), |
| 47 m_iLock(0), |
| 48 m_pLayoutItem(nullptr), |
| 49 m_nEventKey(0), |
| 50 m_pDelegate(nullptr) { |
| 51 ASSERT(m_pWidgetMgr); |
| 52 |
| 53 CFWL_Widget* pParent = m_pProperties->m_pParent; |
| 54 m_pWidgetMgr->InsertWidget(pParent, this); |
| 55 if (IsChild()) |
| 56 return; |
| 57 |
| 58 CFWL_Widget* pOwner = m_pProperties->m_pOwner; |
| 59 if (pOwner) |
| 60 m_pWidgetMgr->SetOwner(pOwner, this); |
| 61 } |
| 62 |
| 63 CFWL_Widget::~CFWL_Widget() { |
| 64 NotifyDriver(); |
| 65 m_pWidgetMgr->RemoveWidget(this); |
| 66 } |
| 67 |
| 68 bool CFWL_Widget::IsInstance(const CFX_WideStringC& wsClass) const { |
| 69 return false; |
27 } | 70 } |
28 | 71 |
29 void CFWL_Widget::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { | 72 void CFWL_Widget::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { |
30 if (m_pIface) | 73 if (!bAutoSize) { |
31 m_pIface->GetWidgetRect(rect, bAutoSize); | 74 rect = m_pProperties->m_rtWidget; |
| 75 return; |
| 76 } |
| 77 |
| 78 if (HasEdge()) { |
| 79 FX_FLOAT fEdge = GetEdgeWidth(); |
| 80 rect.Inflate(fEdge, fEdge); |
| 81 } |
| 82 if (HasBorder()) { |
| 83 FX_FLOAT fBorder = GetBorderSize(); |
| 84 rect.Inflate(fBorder, fBorder); |
| 85 } |
32 } | 86 } |
33 | 87 |
34 void CFWL_Widget::SetWidgetRect(const CFX_RectF& rect) { | 88 void CFWL_Widget::SetWidgetRect(const CFX_RectF& rect) { |
35 if (m_pIface) | 89 CFX_RectF rtOld = m_pProperties->m_rtWidget; |
36 m_pIface->SetWidgetRect(rect); | 90 m_pProperties->m_rtWidget = rect; |
| 91 if (IsChild()) { |
| 92 if (FXSYS_fabs(rtOld.width - rect.width) > 0.5f || |
| 93 FXSYS_fabs(rtOld.height - rect.height) > 0.5f) { |
| 94 CFWL_EvtSizeChanged ev; |
| 95 ev.m_pSrcTarget = this; |
| 96 ev.m_rtOld = rtOld; |
| 97 ev.m_rtNew = rect; |
| 98 |
| 99 if (IFWL_WidgetDelegate* pDelegate = GetDelegate()) |
| 100 pDelegate->OnProcessEvent(&ev); |
| 101 } |
| 102 return; |
| 103 } |
| 104 m_pWidgetMgr->SetWidgetRect_Native(this, rect); |
| 105 } |
| 106 |
| 107 void CFWL_Widget::GetClientRect(CFX_RectF& rect) { |
| 108 GetEdgeRect(rect); |
| 109 if (HasEdge()) { |
| 110 FX_FLOAT fEdge = GetEdgeWidth(); |
| 111 rect.Deflate(fEdge, fEdge); |
| 112 } |
| 113 } |
| 114 |
| 115 void CFWL_Widget::SetParent(CFWL_Widget* pParent) { |
| 116 m_pProperties->m_pParent = pParent; |
| 117 m_pWidgetMgr->SetParent(pParent, this); |
| 118 } |
| 119 |
| 120 uint32_t CFWL_Widget::GetStyles() const { |
| 121 return m_pProperties->m_dwStyles; |
37 } | 122 } |
38 | 123 |
39 void CFWL_Widget::ModifyStyles(uint32_t dwStylesAdded, | 124 void CFWL_Widget::ModifyStyles(uint32_t dwStylesAdded, |
40 uint32_t dwStylesRemoved) { | 125 uint32_t dwStylesRemoved) { |
41 if (m_pIface) | 126 m_pProperties->m_dwStyles = |
42 m_pIface->ModifyStyles(dwStylesAdded, dwStylesRemoved); | 127 (m_pProperties->m_dwStyles & ~dwStylesRemoved) | dwStylesAdded; |
43 } | 128 } |
44 | 129 |
45 uint32_t CFWL_Widget::GetStylesEx() { | 130 uint32_t CFWL_Widget::GetStylesEx() const { |
46 return m_pIface ? m_pIface->GetStylesEx() : 0; | 131 return m_pProperties->m_dwStyleExes; |
| 132 } |
| 133 uint32_t CFWL_Widget::GetStates() const { |
| 134 return m_pProperties->m_dwStates; |
47 } | 135 } |
48 | 136 |
49 void CFWL_Widget::ModifyStylesEx(uint32_t dwStylesExAdded, | 137 void CFWL_Widget::ModifyStylesEx(uint32_t dwStylesExAdded, |
50 uint32_t dwStylesExRemoved) { | 138 uint32_t dwStylesExRemoved) { |
51 m_pIface->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); | 139 m_pProperties->m_dwStyleExes = |
52 } | 140 (m_pProperties->m_dwStyleExes & ~dwStylesExRemoved) | dwStylesExAdded; |
53 | 141 } |
54 uint32_t CFWL_Widget::GetStates() { | 142 |
55 return m_pIface ? m_pIface->GetStates() : 0; | 143 static void NotifyHideChildWidget(CFWL_WidgetMgr* widgetMgr, |
| 144 CFWL_Widget* widget, |
| 145 CFWL_NoteDriver* noteDriver) { |
| 146 CFWL_Widget* child = widgetMgr->GetFirstChildWidget(widget); |
| 147 while (child) { |
| 148 noteDriver->NotifyTargetHide(child); |
| 149 NotifyHideChildWidget(widgetMgr, child, noteDriver); |
| 150 child = widgetMgr->GetNextSiblingWidget(child); |
| 151 } |
56 } | 152 } |
57 | 153 |
58 void CFWL_Widget::SetStates(uint32_t dwStates, bool bSet) { | 154 void CFWL_Widget::SetStates(uint32_t dwStates, bool bSet) { |
59 if (m_pIface) | 155 bSet ? (m_pProperties->m_dwStates |= dwStates) |
60 m_pIface->SetStates(dwStates, bSet); | 156 : (m_pProperties->m_dwStates &= ~dwStates); |
61 } | 157 if (!(dwStates & FWL_WGTSTATE_Invisible) || !bSet) |
62 | 158 return; |
63 void CFWL_Widget::SetLayoutItem(void* pItem) { | 159 |
64 if (m_pIface) | 160 CFWL_NoteDriver* noteDriver = |
65 m_pIface->SetLayoutItem(pItem); | 161 static_cast<CFWL_NoteDriver*>(GetOwnerApp()->GetNoteDriver()); |
66 } | 162 CFWL_WidgetMgr* widgetMgr = GetOwnerApp()->GetWidgetMgr(); |
67 | 163 noteDriver->NotifyTargetHide(this); |
68 void CFWL_Widget::Update() { | 164 CFWL_Widget* child = widgetMgr->GetFirstChildWidget(this); |
69 if (m_pIface) | 165 while (child) { |
70 m_pIface->Update(); | 166 noteDriver->NotifyTargetHide(child); |
71 } | 167 NotifyHideChildWidget(widgetMgr, child, noteDriver); |
72 | 168 child = widgetMgr->GetNextSiblingWidget(child); |
73 void CFWL_Widget::LockUpdate() { | 169 } |
74 if (m_pIface) | 170 return; |
75 m_pIface->LockUpdate(); | |
76 } | |
77 | |
78 void CFWL_Widget::UnlockUpdate() { | |
79 if (m_pIface) | |
80 m_pIface->UnlockUpdate(); | |
81 } | 171 } |
82 | 172 |
83 FWL_WidgetHit CFWL_Widget::HitTest(FX_FLOAT fx, FX_FLOAT fy) { | 173 FWL_WidgetHit CFWL_Widget::HitTest(FX_FLOAT fx, FX_FLOAT fy) { |
84 if (!m_pIface) | 174 CFX_RectF rtClient; |
85 return FWL_WidgetHit::Unknown; | 175 GetClientRect(rtClient); |
86 return m_pIface->HitTest(fx, fy); | 176 if (rtClient.Contains(fx, fy)) |
87 } | 177 return FWL_WidgetHit::Client; |
88 | 178 if (HasEdge()) { |
89 void CFWL_Widget::DrawWidget(CFX_Graphics* pGraphics, | 179 CFX_RectF rtEdge; |
| 180 GetEdgeRect(rtEdge); |
| 181 if (rtEdge.Contains(fx, fy)) |
| 182 return FWL_WidgetHit::Edge; |
| 183 } |
| 184 if (HasBorder()) { |
| 185 CFX_RectF rtRelative; |
| 186 GetRelativeRect(rtRelative); |
| 187 if (rtRelative.Contains(fx, fy)) |
| 188 return FWL_WidgetHit::Border; |
| 189 } |
| 190 return FWL_WidgetHit::Unknown; |
| 191 } |
| 192 |
| 193 void CFWL_Widget::TransformTo(CFWL_Widget* pWidget, |
| 194 FX_FLOAT& fx, |
| 195 FX_FLOAT& fy) { |
| 196 if (m_pWidgetMgr->IsFormDisabled()) { |
| 197 CFX_SizeF szOffset; |
| 198 if (IsParent(pWidget)) { |
| 199 szOffset = GetOffsetFromParent(pWidget); |
| 200 } else { |
| 201 szOffset = pWidget->GetOffsetFromParent(this); |
| 202 szOffset.x = -szOffset.x; |
| 203 szOffset.y = -szOffset.y; |
| 204 } |
| 205 fx += szOffset.x; |
| 206 fy += szOffset.y; |
| 207 return; |
| 208 } |
| 209 CFX_RectF r; |
| 210 CFX_Matrix m; |
| 211 CFWL_Widget* parent = GetParent(); |
| 212 if (parent) { |
| 213 GetWidgetRect(r); |
| 214 fx += r.left; |
| 215 fy += r.top; |
| 216 GetMatrix(m, true); |
| 217 m.TransformPoint(fx, fy); |
| 218 } |
| 219 CFWL_Widget* form1 = m_pWidgetMgr->GetSystemFormWidget(this); |
| 220 if (!form1) |
| 221 return; |
| 222 if (!pWidget) { |
| 223 form1->GetWidgetRect(r); |
| 224 fx += r.left; |
| 225 fy += r.top; |
| 226 return; |
| 227 } |
| 228 CFWL_Widget* form2 = m_pWidgetMgr->GetSystemFormWidget(pWidget); |
| 229 if (!form2) |
| 230 return; |
| 231 if (form1 != form2) { |
| 232 form1->GetWidgetRect(r); |
| 233 fx += r.left; |
| 234 fy += r.top; |
| 235 form2->GetWidgetRect(r); |
| 236 fx -= r.left; |
| 237 fy -= r.top; |
| 238 } |
| 239 parent = pWidget->GetParent(); |
| 240 if (parent) { |
| 241 pWidget->GetMatrix(m, true); |
| 242 CFX_Matrix m1; |
| 243 m1.SetIdentity(); |
| 244 m1.SetReverse(m); |
| 245 m1.TransformPoint(fx, fy); |
| 246 pWidget->GetWidgetRect(r); |
| 247 fx -= r.left; |
| 248 fy -= r.top; |
| 249 } |
| 250 } |
| 251 |
| 252 void CFWL_Widget::GetMatrix(CFX_Matrix& matrix, bool bGlobal) { |
| 253 if (!m_pProperties) |
| 254 return; |
| 255 if (!bGlobal) { |
| 256 matrix.SetIdentity(); |
| 257 return; |
| 258 } |
| 259 |
| 260 CFWL_Widget* parent = GetParent(); |
| 261 CFX_ArrayTemplate<CFWL_Widget*> parents; |
| 262 while (parent) { |
| 263 parents.Add(parent); |
| 264 parent = parent->GetParent(); |
| 265 } |
| 266 matrix.SetIdentity(); |
| 267 CFX_Matrix ctmOnParent; |
| 268 CFX_RectF rect; |
| 269 int32_t count = parents.GetSize(); |
| 270 for (int32_t i = count - 2; i >= 0; i--) { |
| 271 parent = parents.GetAt(i); |
| 272 parent->GetMatrix(ctmOnParent, false); |
| 273 parent->GetWidgetRect(rect); |
| 274 matrix.Concat(ctmOnParent, true); |
| 275 matrix.Translate(rect.left, rect.top, true); |
| 276 } |
| 277 CFX_Matrix m; |
| 278 m.SetIdentity(); |
| 279 matrix.Concat(m, true); |
| 280 parents.RemoveAll(); |
| 281 } |
| 282 |
| 283 IFWL_ThemeProvider* CFWL_Widget::GetThemeProvider() const { |
| 284 return m_pProperties->m_pThemeProvider; |
| 285 } |
| 286 |
| 287 void CFWL_Widget::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) { |
| 288 m_pProperties->m_pThemeProvider = pThemeProvider; |
| 289 } |
| 290 |
| 291 bool CFWL_Widget::IsEnabled() const { |
| 292 return (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) == 0; |
| 293 } |
| 294 |
| 295 bool CFWL_Widget::IsActive() const { |
| 296 return (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) == 0; |
| 297 } |
| 298 |
| 299 bool CFWL_Widget::HasBorder() const { |
| 300 return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border); |
| 301 } |
| 302 |
| 303 bool CFWL_Widget::HasEdge() const { |
| 304 return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_EdgeMask); |
| 305 } |
| 306 |
| 307 bool CFWL_Widget::IsVisible() const { |
| 308 return (m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) == 0; |
| 309 } |
| 310 |
| 311 bool CFWL_Widget::IsOverLapper() const { |
| 312 return (m_pProperties->m_dwStyles & FWL_WGTSTYLE_WindowTypeMask) == |
| 313 FWL_WGTSTYLE_OverLapper; |
| 314 } |
| 315 |
| 316 bool CFWL_Widget::IsPopup() const { |
| 317 return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Popup); |
| 318 } |
| 319 |
| 320 bool CFWL_Widget::IsChild() const { |
| 321 return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Child); |
| 322 } |
| 323 |
| 324 bool CFWL_Widget::IsOffscreen() const { |
| 325 return !!(m_pProperties->m_dwStyles & FWL_WGTSTYLE_Offscreen); |
| 326 } |
| 327 |
| 328 void CFWL_Widget::GetEdgeRect(CFX_RectF& rtEdge) { |
| 329 rtEdge = m_pProperties->m_rtWidget; |
| 330 rtEdge.left = rtEdge.top = 0; |
| 331 if (HasBorder()) { |
| 332 FX_FLOAT fCX = GetBorderSize(); |
| 333 FX_FLOAT fCY = GetBorderSize(false); |
| 334 rtEdge.Deflate(fCX, fCY); |
| 335 } |
| 336 } |
| 337 |
| 338 FX_FLOAT CFWL_Widget::GetBorderSize(bool bCX) { |
| 339 FX_FLOAT* pfBorder = static_cast<FX_FLOAT*>(GetThemeCapacity( |
| 340 bCX ? CFWL_WidgetCapacity::CXBorder : CFWL_WidgetCapacity::CYBorder)); |
| 341 if (!pfBorder) |
| 342 return 0; |
| 343 return *pfBorder; |
| 344 } |
| 345 |
| 346 FX_FLOAT CFWL_Widget::GetEdgeWidth() { |
| 347 CFWL_WidgetCapacity dwCapacity = CFWL_WidgetCapacity::None; |
| 348 switch (m_pProperties->m_dwStyles & FWL_WGTSTYLE_EdgeMask) { |
| 349 case FWL_WGTSTYLE_EdgeFlat: { |
| 350 dwCapacity = CFWL_WidgetCapacity::EdgeFlat; |
| 351 break; |
| 352 } |
| 353 case FWL_WGTSTYLE_EdgeRaised: { |
| 354 dwCapacity = CFWL_WidgetCapacity::EdgeRaised; |
| 355 break; |
| 356 } |
| 357 case FWL_WGTSTYLE_EdgeSunken: { |
| 358 dwCapacity = CFWL_WidgetCapacity::EdgeSunken; |
| 359 break; |
| 360 } |
| 361 } |
| 362 if (dwCapacity != CFWL_WidgetCapacity::None) { |
| 363 FX_FLOAT* fRet = static_cast<FX_FLOAT*>(GetThemeCapacity(dwCapacity)); |
| 364 return fRet ? *fRet : 0; |
| 365 } |
| 366 return 0; |
| 367 } |
| 368 |
| 369 void CFWL_Widget::GetRelativeRect(CFX_RectF& rect) { |
| 370 rect = m_pProperties->m_rtWidget; |
| 371 rect.left = rect.top = 0; |
| 372 } |
| 373 |
| 374 void* CFWL_Widget::GetThemeCapacity(CFWL_WidgetCapacity dwCapacity) { |
| 375 IFWL_ThemeProvider* pTheme = GetAvailableTheme(); |
| 376 if (!pTheme) |
| 377 return nullptr; |
| 378 |
| 379 CFWL_ThemePart part; |
| 380 part.m_pWidget = this; |
| 381 return pTheme->GetCapacity(&part, dwCapacity); |
| 382 } |
| 383 |
| 384 IFWL_ThemeProvider* CFWL_Widget::GetAvailableTheme() { |
| 385 if (m_pProperties->m_pThemeProvider) |
| 386 return m_pProperties->m_pThemeProvider; |
| 387 |
| 388 CFWL_Widget* pUp = this; |
| 389 do { |
| 390 pUp = (pUp->GetStyles() & FWL_WGTSTYLE_Popup) |
| 391 ? m_pWidgetMgr->GetOwnerWidget(pUp) |
| 392 : m_pWidgetMgr->GetParentWidget(pUp); |
| 393 if (pUp) { |
| 394 IFWL_ThemeProvider* pRet = pUp->GetThemeProvider(); |
| 395 if (pRet) |
| 396 return pRet; |
| 397 } |
| 398 } while (pUp); |
| 399 return nullptr; |
| 400 } |
| 401 |
| 402 CFWL_Widget* CFWL_Widget::GetRootOuter() { |
| 403 CFWL_Widget* pRet = m_pOuter; |
| 404 if (!pRet) |
| 405 return nullptr; |
| 406 |
| 407 while (CFWL_Widget* pOuter = pRet->GetOuter()) |
| 408 pRet = pOuter; |
| 409 return pRet; |
| 410 } |
| 411 |
| 412 CFX_SizeF CFWL_Widget::CalcTextSize(const CFX_WideString& wsText, |
| 413 IFWL_ThemeProvider* pTheme, |
| 414 bool bMultiLine, |
| 415 int32_t iLineWidth) { |
| 416 if (!pTheme) |
| 417 return CFX_SizeF(); |
| 418 |
| 419 CFWL_ThemeText calPart; |
| 420 calPart.m_pWidget = this; |
| 421 calPart.m_wsText = wsText; |
| 422 calPart.m_dwTTOStyles = |
| 423 bMultiLine ? FDE_TTOSTYLE_LineWrap : FDE_TTOSTYLE_SingleLine; |
| 424 calPart.m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft; |
| 425 CFX_RectF rect; |
| 426 FX_FLOAT fWidth = bMultiLine |
| 427 ? (iLineWidth > 0 ? (FX_FLOAT)iLineWidth |
| 428 : FWL_WGT_CalcMultiLineDefWidth) |
| 429 : FWL_WGT_CalcWidth; |
| 430 rect.Set(0, 0, fWidth, FWL_WGT_CalcHeight); |
| 431 pTheme->CalcTextRect(&calPart, rect); |
| 432 return CFX_SizeF(rect.width, rect.height); |
| 433 } |
| 434 |
| 435 void CFWL_Widget::CalcTextRect(const CFX_WideString& wsText, |
| 436 IFWL_ThemeProvider* pTheme, |
| 437 uint32_t dwTTOStyles, |
| 438 int32_t iTTOAlign, |
| 439 CFX_RectF& rect) { |
| 440 CFWL_ThemeText calPart; |
| 441 calPart.m_pWidget = this; |
| 442 calPart.m_wsText = wsText; |
| 443 calPart.m_dwTTOStyles = dwTTOStyles; |
| 444 calPart.m_iTTOAlign = iTTOAlign; |
| 445 pTheme->CalcTextRect(&calPart, rect); |
| 446 } |
| 447 |
| 448 void CFWL_Widget::SetFocus(bool bFocus) { |
| 449 if (m_pWidgetMgr->IsFormDisabled()) |
| 450 return; |
| 451 |
| 452 const CFWL_App* pApp = GetOwnerApp(); |
| 453 if (!pApp) |
| 454 return; |
| 455 |
| 456 CFWL_NoteDriver* pDriver = |
| 457 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); |
| 458 if (!pDriver) |
| 459 return; |
| 460 |
| 461 CFWL_Widget* curFocus = pDriver->GetFocus(); |
| 462 if (bFocus && curFocus != this) |
| 463 pDriver->SetFocus(this); |
| 464 else if (!bFocus && curFocus == this) |
| 465 pDriver->SetFocus(nullptr); |
| 466 } |
| 467 |
| 468 void CFWL_Widget::SetGrab(bool bSet) { |
| 469 const CFWL_App* pApp = GetOwnerApp(); |
| 470 if (!pApp) |
| 471 return; |
| 472 |
| 473 CFWL_NoteDriver* pDriver = |
| 474 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); |
| 475 pDriver->SetGrab(this, bSet); |
| 476 } |
| 477 |
| 478 void CFWL_Widget::GetPopupPos(FX_FLOAT fMinHeight, |
| 479 FX_FLOAT fMaxHeight, |
| 480 const CFX_RectF& rtAnchor, |
| 481 CFX_RectF& rtPopup) { |
| 482 if (GetClassID() == FWL_Type::ComboBox) { |
| 483 if (m_pWidgetMgr->IsFormDisabled()) { |
| 484 m_pWidgetMgr->GetAdapterPopupPos(this, fMinHeight, fMaxHeight, rtAnchor, |
| 485 rtPopup); |
| 486 return; |
| 487 } |
| 488 GetPopupPosComboBox(fMinHeight, fMaxHeight, rtAnchor, rtPopup); |
| 489 return; |
| 490 } |
| 491 if (GetClassID() == FWL_Type::DateTimePicker && |
| 492 m_pWidgetMgr->IsFormDisabled()) { |
| 493 m_pWidgetMgr->GetAdapterPopupPos(this, fMinHeight, fMaxHeight, rtAnchor, |
| 494 rtPopup); |
| 495 return; |
| 496 } |
| 497 GetPopupPosGeneral(fMinHeight, fMaxHeight, rtAnchor, rtPopup); |
| 498 } |
| 499 |
| 500 bool CFWL_Widget::GetPopupPosMenu(FX_FLOAT fMinHeight, |
| 501 FX_FLOAT fMaxHeight, |
| 502 const CFX_RectF& rtAnchor, |
| 503 CFX_RectF& rtPopup) { |
| 504 FX_FLOAT fx = 0; |
| 505 FX_FLOAT fy = 0; |
| 506 |
| 507 if (GetStylesEx() & FWL_STYLEEXT_MNU_Vert) { |
| 508 bool bLeft = m_pProperties->m_rtWidget.left < 0; |
| 509 FX_FLOAT fRight = rtAnchor.right() + rtPopup.width; |
| 510 TransformTo(nullptr, fx, fy); |
| 511 if (fRight + fx > 0.0f || bLeft) { |
| 512 rtPopup.Set(rtAnchor.left - rtPopup.width, rtAnchor.top, rtPopup.width, |
| 513 rtPopup.height); |
| 514 } else { |
| 515 rtPopup.Set(rtAnchor.right(), rtAnchor.top, rtPopup.width, |
| 516 rtPopup.height); |
| 517 } |
| 518 } else { |
| 519 FX_FLOAT fBottom = rtAnchor.bottom() + rtPopup.height; |
| 520 TransformTo(nullptr, fx, fy); |
| 521 if (fBottom + fy > 0.0f) { |
| 522 rtPopup.Set(rtAnchor.left, rtAnchor.top - rtPopup.height, rtPopup.width, |
| 523 rtPopup.height); |
| 524 } else { |
| 525 rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), rtPopup.width, |
| 526 rtPopup.height); |
| 527 } |
| 528 } |
| 529 rtPopup.Offset(fx, fy); |
| 530 return true; |
| 531 } |
| 532 |
| 533 bool CFWL_Widget::GetPopupPosComboBox(FX_FLOAT fMinHeight, |
| 534 FX_FLOAT fMaxHeight, |
| 535 const CFX_RectF& rtAnchor, |
| 536 CFX_RectF& rtPopup) { |
| 537 FX_FLOAT fx = 0; |
| 538 FX_FLOAT fy = 0; |
| 539 |
| 540 FX_FLOAT fPopHeight = rtPopup.height; |
| 541 if (rtPopup.height > fMaxHeight) |
| 542 fPopHeight = fMaxHeight; |
| 543 else if (rtPopup.height < fMinHeight) |
| 544 fPopHeight = fMinHeight; |
| 545 |
| 546 FX_FLOAT fWidth = std::max(rtAnchor.width, rtPopup.width); |
| 547 FX_FLOAT fBottom = rtAnchor.bottom() + fPopHeight; |
| 548 TransformTo(nullptr, fx, fy); |
| 549 if (fBottom + fy > 0.0f) |
| 550 rtPopup.Set(rtAnchor.left, rtAnchor.top - fPopHeight, fWidth, fPopHeight); |
| 551 else |
| 552 rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), fWidth, fPopHeight); |
| 553 |
| 554 rtPopup.Offset(fx, fy); |
| 555 return true; |
| 556 } |
| 557 |
| 558 bool CFWL_Widget::GetPopupPosGeneral(FX_FLOAT fMinHeight, |
| 559 FX_FLOAT fMaxHeight, |
| 560 const CFX_RectF& rtAnchor, |
| 561 CFX_RectF& rtPopup) { |
| 562 FX_FLOAT fx = 0; |
| 563 FX_FLOAT fy = 0; |
| 564 |
| 565 TransformTo(nullptr, fx, fy); |
| 566 if (rtAnchor.bottom() + fy > 0.0f) { |
| 567 rtPopup.Set(rtAnchor.left, rtAnchor.top - rtPopup.height, rtPopup.width, |
| 568 rtPopup.height); |
| 569 } else { |
| 570 rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), rtPopup.width, |
| 571 rtPopup.height); |
| 572 } |
| 573 rtPopup.Offset(fx, fy); |
| 574 return true; |
| 575 } |
| 576 |
| 577 void CFWL_Widget::RegisterEventTarget(CFWL_Widget* pEventSource) { |
| 578 const CFWL_App* pApp = GetOwnerApp(); |
| 579 if (!pApp) |
| 580 return; |
| 581 |
| 582 CFWL_NoteDriver* pNoteDriver = pApp->GetNoteDriver(); |
| 583 if (!pNoteDriver) |
| 584 return; |
| 585 |
| 586 pNoteDriver->RegisterEventTarget(this, pEventSource); |
| 587 } |
| 588 |
| 589 void CFWL_Widget::UnregisterEventTarget() { |
| 590 const CFWL_App* pApp = GetOwnerApp(); |
| 591 if (!pApp) |
| 592 return; |
| 593 |
| 594 CFWL_NoteDriver* pNoteDriver = pApp->GetNoteDriver(); |
| 595 if (!pNoteDriver) |
| 596 return; |
| 597 |
| 598 pNoteDriver->UnregisterEventTarget(this); |
| 599 } |
| 600 |
| 601 void CFWL_Widget::DispatchKeyEvent(CFWL_MsgKey* pNote) { |
| 602 if (!pNote) |
| 603 return; |
| 604 |
| 605 auto pEvent = pdfium::MakeUnique<CFWL_EvtKey>(); |
| 606 pEvent->m_pSrcTarget = this; |
| 607 pEvent->m_dwCmd = pNote->m_dwCmd; |
| 608 pEvent->m_dwKeyCode = pNote->m_dwKeyCode; |
| 609 pEvent->m_dwFlags = pNote->m_dwFlags; |
| 610 DispatchEvent(pEvent.get()); |
| 611 } |
| 612 |
| 613 void CFWL_Widget::DispatchEvent(CFWL_Event* pEvent) { |
| 614 if (m_pOuter) { |
| 615 m_pOuter->GetDelegate()->OnProcessEvent(pEvent); |
| 616 return; |
| 617 } |
| 618 const CFWL_App* pApp = GetOwnerApp(); |
| 619 if (!pApp) |
| 620 return; |
| 621 |
| 622 CFWL_NoteDriver* pNoteDriver = pApp->GetNoteDriver(); |
| 623 if (!pNoteDriver) |
| 624 return; |
| 625 pNoteDriver->SendEvent(pEvent); |
| 626 } |
| 627 |
| 628 void CFWL_Widget::Repaint(const CFX_RectF* pRect) { |
| 629 if (pRect) { |
| 630 m_pWidgetMgr->RepaintWidget(this, pRect); |
| 631 return; |
| 632 } |
| 633 CFX_RectF rect; |
| 634 rect = m_pProperties->m_rtWidget; |
| 635 rect.left = rect.top = 0; |
| 636 m_pWidgetMgr->RepaintWidget(this, &rect); |
| 637 } |
| 638 |
| 639 void CFWL_Widget::DrawBackground(CFX_Graphics* pGraphics, |
| 640 CFWL_Part iPartBk, |
| 641 IFWL_ThemeProvider* pTheme, |
| 642 const CFX_Matrix* pMatrix) { |
| 643 CFX_RectF rtRelative; |
| 644 GetRelativeRect(rtRelative); |
| 645 CFWL_ThemeBackground param; |
| 646 param.m_pWidget = this; |
| 647 param.m_iPart = iPartBk; |
| 648 param.m_pGraphics = pGraphics; |
| 649 if (pMatrix) |
| 650 param.m_matrix.Concat(*pMatrix, true); |
| 651 param.m_rtPart = rtRelative; |
| 652 pTheme->DrawBackground(¶m); |
| 653 } |
| 654 |
| 655 void CFWL_Widget::DrawBorder(CFX_Graphics* pGraphics, |
| 656 CFWL_Part iPartBorder, |
| 657 IFWL_ThemeProvider* pTheme, |
90 const CFX_Matrix* pMatrix) { | 658 const CFX_Matrix* pMatrix) { |
91 if (m_pIface) | 659 CFX_RectF rtRelative; |
92 m_pIface->DrawWidget(pGraphics, pMatrix); | 660 GetRelativeRect(rtRelative); |
93 } | 661 CFWL_ThemeBackground param; |
94 | 662 param.m_pWidget = this; |
95 IFWL_WidgetDelegate* CFWL_Widget::GetDelegate() const { | 663 param.m_iPart = iPartBorder; |
96 return m_pIface ? m_pIface->GetDelegate() : nullptr; | 664 param.m_pGraphics = pGraphics; |
97 } | 665 if (pMatrix) |
98 | 666 param.m_matrix.Concat(*pMatrix, true); |
99 void CFWL_Widget::SetDelegate(IFWL_WidgetDelegate* pDelegate) { | 667 param.m_rtPart = rtRelative; |
100 if (m_pIface) | 668 pTheme->DrawBackground(¶m); |
101 m_pIface->SetDelegate(pDelegate); | 669 } |
102 } | 670 |
| 671 void CFWL_Widget::DrawEdge(CFX_Graphics* pGraphics, |
| 672 CFWL_Part iPartEdge, |
| 673 IFWL_ThemeProvider* pTheme, |
| 674 const CFX_Matrix* pMatrix) { |
| 675 CFX_RectF rtEdge; |
| 676 GetEdgeRect(rtEdge); |
| 677 CFWL_ThemeBackground param; |
| 678 param.m_pWidget = this; |
| 679 param.m_iPart = iPartEdge; |
| 680 param.m_pGraphics = pGraphics; |
| 681 if (pMatrix) |
| 682 param.m_matrix.Concat(*pMatrix, true); |
| 683 param.m_rtPart = rtEdge; |
| 684 pTheme->DrawBackground(¶m); |
| 685 } |
| 686 |
| 687 void CFWL_Widget::NotifyDriver() { |
| 688 const CFWL_App* pApp = GetOwnerApp(); |
| 689 if (!pApp) |
| 690 return; |
| 691 |
| 692 CFWL_NoteDriver* pDriver = |
| 693 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); |
| 694 if (!pDriver) |
| 695 return; |
| 696 |
| 697 pDriver->NotifyTargetDestroy(this); |
| 698 } |
| 699 |
| 700 CFX_SizeF CFWL_Widget::GetOffsetFromParent(CFWL_Widget* pParent) { |
| 701 if (pParent == this) |
| 702 return CFX_SizeF(); |
| 703 |
| 704 CFWL_WidgetMgr* pWidgetMgr = GetOwnerApp()->GetWidgetMgr(); |
| 705 if (!pWidgetMgr) |
| 706 return CFX_SizeF(); |
| 707 |
| 708 CFX_SizeF szRet(m_pProperties->m_rtWidget.left, |
| 709 m_pProperties->m_rtWidget.top); |
| 710 |
| 711 CFWL_Widget* pDstWidget = GetParent(); |
| 712 while (pDstWidget && pDstWidget != pParent) { |
| 713 CFX_RectF rtDst; |
| 714 pDstWidget->GetWidgetRect(rtDst); |
| 715 szRet += CFX_SizeF(rtDst.left, rtDst.top); |
| 716 pDstWidget = pWidgetMgr->GetParentWidget(pDstWidget); |
| 717 } |
| 718 return szRet; |
| 719 } |
| 720 |
| 721 bool CFWL_Widget::IsParent(CFWL_Widget* pParent) { |
| 722 CFWL_Widget* pUpWidget = GetParent(); |
| 723 while (pUpWidget) { |
| 724 if (pUpWidget == pParent) |
| 725 return true; |
| 726 pUpWidget = pUpWidget->GetParent(); |
| 727 } |
| 728 return false; |
| 729 } |
| 730 |
| 731 void CFWL_Widget::OnProcessMessage(CFWL_Message* pMessage) { |
| 732 if (!pMessage->m_pDstTarget) |
| 733 return; |
| 734 |
| 735 CFWL_Widget* pWidget = pMessage->m_pDstTarget; |
| 736 CFWL_MessageType dwMsgCode = pMessage->GetClassID(); |
| 737 switch (dwMsgCode) { |
| 738 case CFWL_MessageType::Mouse: { |
| 739 CFWL_MsgMouse* pMsgMouse = static_cast<CFWL_MsgMouse*>(pMessage); |
| 740 CFWL_EvtMouse evt; |
| 741 evt.m_pSrcTarget = pWidget; |
| 742 evt.m_pDstTarget = pWidget; |
| 743 evt.m_dwCmd = pMsgMouse->m_dwCmd; |
| 744 evt.m_dwFlags = pMsgMouse->m_dwFlags; |
| 745 evt.m_fx = pMsgMouse->m_fx; |
| 746 evt.m_fy = pMsgMouse->m_fy; |
| 747 pWidget->DispatchEvent(&evt); |
| 748 break; |
| 749 } |
| 750 case CFWL_MessageType::MouseWheel: { |
| 751 CFWL_MsgMouseWheel* pMsgMouseWheel = |
| 752 static_cast<CFWL_MsgMouseWheel*>(pMessage); |
| 753 CFWL_EvtMouseWheel evt; |
| 754 evt.m_pSrcTarget = pWidget; |
| 755 evt.m_pDstTarget = pWidget; |
| 756 evt.m_dwFlags = pMsgMouseWheel->m_dwFlags; |
| 757 evt.m_fDeltaX = pMsgMouseWheel->m_fDeltaX; |
| 758 evt.m_fDeltaY = pMsgMouseWheel->m_fDeltaY; |
| 759 evt.m_fx = pMsgMouseWheel->m_fx; |
| 760 evt.m_fy = pMsgMouseWheel->m_fy; |
| 761 pWidget->DispatchEvent(&evt); |
| 762 break; |
| 763 } |
| 764 case CFWL_MessageType::Key: { |
| 765 CFWL_MsgKey* pMsgKey = static_cast<CFWL_MsgKey*>(pMessage); |
| 766 CFWL_EvtKey evt; |
| 767 evt.m_pSrcTarget = pWidget; |
| 768 evt.m_pDstTarget = pWidget; |
| 769 evt.m_dwKeyCode = pMsgKey->m_dwKeyCode; |
| 770 evt.m_dwFlags = pMsgKey->m_dwFlags; |
| 771 evt.m_dwCmd = pMsgKey->m_dwCmd; |
| 772 pWidget->DispatchEvent(&evt); |
| 773 break; |
| 774 } |
| 775 case CFWL_MessageType::SetFocus: { |
| 776 CFWL_MsgSetFocus* pMsgSetFocus = static_cast<CFWL_MsgSetFocus*>(pMessage); |
| 777 CFWL_EvtSetFocus evt; |
| 778 evt.m_pSrcTarget = pMsgSetFocus->m_pDstTarget; |
| 779 evt.m_pDstTarget = pMsgSetFocus->m_pDstTarget; |
| 780 evt.m_pSetFocus = pWidget; |
| 781 pWidget->DispatchEvent(&evt); |
| 782 break; |
| 783 } |
| 784 case CFWL_MessageType::KillFocus: { |
| 785 CFWL_MsgKillFocus* pMsgKillFocus = |
| 786 static_cast<CFWL_MsgKillFocus*>(pMessage); |
| 787 CFWL_EvtKillFocus evt; |
| 788 evt.m_pSrcTarget = pMsgKillFocus->m_pDstTarget; |
| 789 evt.m_pDstTarget = pMsgKillFocus->m_pDstTarget; |
| 790 evt.m_pKillFocus = pWidget; |
| 791 pWidget->DispatchEvent(&evt); |
| 792 break; |
| 793 } |
| 794 default: |
| 795 break; |
| 796 } |
| 797 } |
| 798 |
| 799 void CFWL_Widget::OnProcessEvent(CFWL_Event* pEvent) {} |
| 800 |
| 801 void CFWL_Widget::OnDrawWidget(CFX_Graphics* pGraphics, |
| 802 const CFX_Matrix* pMatrix) {} |
OLD | NEW |