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_form.h" | |
8 | |
9 #include <utility> | |
10 | |
11 #include "third_party/base/ptr_util.h" | |
12 #include "xfa/fde/tto/fde_textout.h" | |
13 #include "xfa/fwl/core/cfwl_app.h" | |
14 #include "xfa/fwl/core/cfwl_evtclose.h" | |
15 #include "xfa/fwl/core/cfwl_msgmouse.h" | |
16 #include "xfa/fwl/core/cfwl_notedriver.h" | |
17 #include "xfa/fwl/core/cfwl_noteloop.h" | |
18 #include "xfa/fwl/core/cfwl_sysbtn.h" | |
19 #include "xfa/fwl/core/cfwl_themebackground.h" | |
20 #include "xfa/fwl/core/cfwl_themepart.h" | |
21 #include "xfa/fwl/core/cfwl_themetext.h" | |
22 #include "xfa/fwl/core/cfwl_widgetmgr.h" | |
23 #include "xfa/fwl/core/ifwl_formproxy.h" | |
24 #include "xfa/fwl/core/ifwl_themeprovider.h" | |
25 #include "xfa/fwl/theme/cfwl_widgettp.h" | |
26 | |
27 namespace { | |
28 | |
29 const int kSystemButtonSize = 21; | |
30 const int kSystemButtonMargin = 5; | |
31 const int kSystemButtonSpan = 2; | |
32 | |
33 } // namespace | |
34 | |
35 namespace { | |
36 | |
37 const uint8_t kCornerEnlarge = 10; | |
38 | |
39 } // namespace | |
40 | |
41 IFWL_Form::IFWL_Form(const CFWL_App* app, | |
42 std::unique_ptr<CFWL_WidgetProperties> properties, | |
43 IFWL_Widget* pOuter) | |
44 : IFWL_Widget(app, std::move(properties), pOuter), | |
45 #if (_FX_OS_ == _FX_MACOSX_) | |
46 m_bMouseIn(false), | |
47 #endif | |
48 m_pCloseBox(nullptr), | |
49 m_pMinBox(nullptr), | |
50 m_pMaxBox(nullptr), | |
51 m_pSubFocus(nullptr), | |
52 m_fCXBorder(0), | |
53 m_fCYBorder(0), | |
54 m_iCaptureBtn(-1), | |
55 m_iSysBox(0), | |
56 m_bLButtonDown(false), | |
57 m_bMaximized(false), | |
58 m_bSetMaximize(false), | |
59 m_bDoModalFlag(false) { | |
60 m_rtRelative.Reset(); | |
61 m_rtRestore.Reset(); | |
62 | |
63 RegisterForm(); | |
64 RegisterEventTarget(nullptr); | |
65 } | |
66 | |
67 IFWL_Form::~IFWL_Form() { | |
68 UnregisterEventTarget(); | |
69 UnRegisterForm(); | |
70 RemoveSysButtons(); | |
71 } | |
72 | |
73 FWL_Type IFWL_Form::GetClassID() const { | |
74 return FWL_Type::Form; | |
75 } | |
76 | |
77 bool IFWL_Form::IsInstance(const CFX_WideStringC& wsClass) const { | |
78 if (wsClass == CFX_WideStringC(FWL_CLASS_Form)) | |
79 return true; | |
80 return IFWL_Widget::IsInstance(wsClass); | |
81 } | |
82 | |
83 void IFWL_Form::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { | |
84 if (!bAutoSize) { | |
85 rect = m_pProperties->m_rtWidget; | |
86 return; | |
87 } | |
88 | |
89 rect.Reset(); | |
90 FX_FLOAT fCXBorder = GetBorderSize(true); | |
91 FX_FLOAT fCYBorder = GetBorderSize(false); | |
92 FX_FLOAT fEdge = GetEdgeWidth(); | |
93 rect.height += fCYBorder + fEdge + fEdge; | |
94 rect.width += fCXBorder + fCXBorder + fEdge + fEdge; | |
95 } | |
96 | |
97 void IFWL_Form::GetClientRect(CFX_RectF& rect) { | |
98 rect = m_pProperties->m_rtWidget; | |
99 rect.Offset(-rect.left, -rect.top); | |
100 } | |
101 | |
102 void IFWL_Form::Update() { | |
103 if (m_iLock > 0) | |
104 return; | |
105 if (!m_pProperties->m_pThemeProvider) | |
106 m_pProperties->m_pThemeProvider = GetAvailableTheme(); | |
107 | |
108 Layout(); | |
109 } | |
110 | |
111 FWL_WidgetHit IFWL_Form::HitTest(FX_FLOAT fx, FX_FLOAT fy) { | |
112 GetAvailableTheme(); | |
113 | |
114 if (m_pCloseBox && m_pCloseBox->m_rtBtn.Contains(fx, fy)) | |
115 return FWL_WidgetHit::CloseBox; | |
116 if (m_pMaxBox && m_pMaxBox->m_rtBtn.Contains(fx, fy)) | |
117 return FWL_WidgetHit::MaxBox; | |
118 if (m_pMinBox && m_pMinBox->m_rtBtn.Contains(fx, fy)) | |
119 return FWL_WidgetHit::MinBox; | |
120 | |
121 CFX_RectF rtCap; | |
122 rtCap.Set(m_fCYBorder, m_fCXBorder, | |
123 0 - kSystemButtonSize * m_iSysBox - 2 * m_fCYBorder, | |
124 0 - m_fCXBorder); | |
125 if (rtCap.Contains(fx, fy)) | |
126 return FWL_WidgetHit::Titlebar; | |
127 if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) && | |
128 (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_FRM_Resize)) { | |
129 FX_FLOAT fWidth = m_rtRelative.width - 2 * (m_fCYBorder + kCornerEnlarge); | |
130 FX_FLOAT fHeight = m_rtRelative.height - 2 * (m_fCXBorder + kCornerEnlarge); | |
131 | |
132 CFX_RectF rt; | |
133 rt.Set(0, m_fCXBorder + kCornerEnlarge, m_fCYBorder, fHeight); | |
134 if (rt.Contains(fx, fy)) | |
135 return FWL_WidgetHit::Left; | |
136 | |
137 rt.Set(m_rtRelative.width - m_fCYBorder, m_fCXBorder + kCornerEnlarge, | |
138 m_fCYBorder, fHeight); | |
139 if (rt.Contains(fx, fy)) | |
140 return FWL_WidgetHit::Right; | |
141 | |
142 rt.Set(m_fCYBorder + kCornerEnlarge, 0, fWidth, m_fCXBorder); | |
143 if (rt.Contains(fx, fy)) | |
144 return FWL_WidgetHit::Top; | |
145 | |
146 rt.Set(m_fCYBorder + kCornerEnlarge, m_rtRelative.height - m_fCXBorder, | |
147 fWidth, m_fCXBorder); | |
148 if (rt.Contains(fx, fy)) | |
149 return FWL_WidgetHit::Bottom; | |
150 | |
151 rt.Set(0, 0, m_fCYBorder + kCornerEnlarge, m_fCXBorder + kCornerEnlarge); | |
152 if (rt.Contains(fx, fy)) | |
153 return FWL_WidgetHit::LeftTop; | |
154 | |
155 rt.Set(0, m_rtRelative.height - m_fCXBorder - kCornerEnlarge, | |
156 m_fCYBorder + kCornerEnlarge, m_fCXBorder + kCornerEnlarge); | |
157 if (rt.Contains(fx, fy)) | |
158 return FWL_WidgetHit::LeftBottom; | |
159 | |
160 rt.Set(m_rtRelative.width - m_fCYBorder - kCornerEnlarge, 0, | |
161 m_fCYBorder + kCornerEnlarge, m_fCXBorder + kCornerEnlarge); | |
162 if (rt.Contains(fx, fy)) | |
163 return FWL_WidgetHit::RightTop; | |
164 | |
165 rt.Set(m_rtRelative.width - m_fCYBorder - kCornerEnlarge, | |
166 m_rtRelative.height - m_fCXBorder - kCornerEnlarge, | |
167 m_fCYBorder + kCornerEnlarge, m_fCXBorder + kCornerEnlarge); | |
168 if (rt.Contains(fx, fy)) | |
169 return FWL_WidgetHit::RightBottom; | |
170 } | |
171 return FWL_WidgetHit::Client; | |
172 } | |
173 | |
174 void IFWL_Form::DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) { | |
175 if (!pGraphics) | |
176 return; | |
177 if (!m_pProperties->m_pThemeProvider) | |
178 return; | |
179 | |
180 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; | |
181 bool bInactive = !IsActive(); | |
182 int32_t iState = bInactive ? CFWL_PartState_Inactive : CFWL_PartState_Normal; | |
183 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_FRM_NoDrawClient) == 0) | |
184 DrawBackground(pGraphics, pTheme); | |
185 | |
186 #ifdef FWL_UseMacSystemBorder | |
187 return; | |
188 #endif | |
189 CFWL_ThemeBackground param; | |
190 param.m_pWidget = this; | |
191 param.m_dwStates = iState; | |
192 param.m_pGraphics = pGraphics; | |
193 param.m_rtPart = m_rtRelative; | |
194 if (pMatrix) | |
195 param.m_matrix.Concat(*pMatrix); | |
196 if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) { | |
197 param.m_iPart = CFWL_Part::Border; | |
198 pTheme->DrawBackground(¶m); | |
199 } | |
200 if ((m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_EdgeMask) != | |
201 FWL_WGTSTYLE_EdgeNone) { | |
202 CFX_RectF rtEdge; | |
203 GetEdgeRect(rtEdge); | |
204 param.m_iPart = CFWL_Part::Edge; | |
205 param.m_rtPart = rtEdge; | |
206 param.m_dwStates = iState; | |
207 pTheme->DrawBackground(¶m); | |
208 } | |
209 | |
210 #if (_FX_OS_ == _FX_MACOSX_) | |
211 { | |
212 if (m_pCloseBox) { | |
213 param.m_iPart = CFWL_Part::CloseBox; | |
214 param.m_dwStates = m_pCloseBox->GetPartState(); | |
215 if (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) | |
216 param.m_dwStates = CFWL_PartState_Disabled; | |
217 else if (CFWL_PartState_Normal == param.m_dwStates && m_bMouseIn) | |
218 param.m_dwStates = CFWL_PartState_Hovered; | |
219 param.m_rtPart = m_pCloseBox->m_rtBtn; | |
220 pTheme->DrawBackground(¶m); | |
221 } | |
222 if (m_pMaxBox) { | |
223 param.m_iPart = CFWL_Part::MaximizeBox; | |
224 param.m_dwStates = m_pMaxBox->GetPartState(); | |
225 if (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) | |
226 param.m_dwStates = CFWL_PartState_Disabled; | |
227 else if (CFWL_PartState_Normal == param.m_dwStates && m_bMouseIn) | |
228 param.m_dwStates = CFWL_PartState_Hovered; | |
229 param.m_rtPart = m_pMaxBox->m_rtBtn; | |
230 param.m_bMaximize = m_bMaximized; | |
231 pTheme->DrawBackground(¶m); | |
232 } | |
233 if (m_pMinBox) { | |
234 param.m_iPart = CFWL_Part::MinimizeBox; | |
235 param.m_dwStates = m_pMinBox->GetPartState(); | |
236 if (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) | |
237 param.m_dwStates = CFWL_PartState_Disabled; | |
238 else if (CFWL_PartState_Normal == param.m_dwStates && m_bMouseIn) | |
239 param.m_dwStates = CFWL_PartState_Hovered; | |
240 param.m_rtPart = m_pMinBox->m_rtBtn; | |
241 pTheme->DrawBackground(¶m); | |
242 } | |
243 m_bMouseIn = false; | |
244 } | |
245 #else | |
246 { | |
247 if (m_pCloseBox) { | |
248 param.m_iPart = CFWL_Part::CloseBox; | |
249 param.m_dwStates = m_pCloseBox->GetPartState(); | |
250 param.m_rtPart = m_pCloseBox->m_rtBtn; | |
251 pTheme->DrawBackground(¶m); | |
252 } | |
253 if (m_pMaxBox) { | |
254 param.m_iPart = CFWL_Part::MaximizeBox; | |
255 param.m_dwStates = m_pMaxBox->GetPartState(); | |
256 param.m_rtPart = m_pMaxBox->m_rtBtn; | |
257 param.m_bMaximize = m_bMaximized; | |
258 pTheme->DrawBackground(¶m); | |
259 } | |
260 if (m_pMinBox) { | |
261 param.m_iPart = CFWL_Part::MinimizeBox; | |
262 param.m_dwStates = m_pMinBox->GetPartState(); | |
263 param.m_rtPart = m_pMinBox->m_rtBtn; | |
264 pTheme->DrawBackground(¶m); | |
265 } | |
266 } | |
267 #endif | |
268 } | |
269 | |
270 IFWL_Widget* IFWL_Form::DoModal() { | |
271 const CFWL_App* pApp = GetOwnerApp(); | |
272 if (!pApp) | |
273 return nullptr; | |
274 | |
275 CFWL_NoteDriver* pDriver = pApp->GetNoteDriver(); | |
276 if (!pDriver) | |
277 return nullptr; | |
278 | |
279 m_pNoteLoop = pdfium::MakeUnique<CFWL_NoteLoop>(); | |
280 m_pNoteLoop->SetMainForm(this); | |
281 | |
282 pDriver->PushNoteLoop(m_pNoteLoop.get()); | |
283 m_bDoModalFlag = true; | |
284 SetStates(FWL_WGTSTATE_Invisible, false); | |
285 pDriver->Run(); | |
286 | |
287 #if _FX_OS_ != _FX_MACOSX_ | |
288 pDriver->PopNoteLoop(); | |
289 #endif | |
290 | |
291 m_pNoteLoop.reset(); | |
292 return nullptr; | |
293 } | |
294 | |
295 void IFWL_Form::EndDoModal() { | |
296 if (!m_pNoteLoop) | |
297 return; | |
298 | |
299 m_bDoModalFlag = false; | |
300 | |
301 #if (_FX_OS_ == _FX_MACOSX_) | |
302 m_pNoteLoop->EndModalLoop(); | |
303 const CFWL_App* pApp = GetOwnerApp(); | |
304 if (!pApp) | |
305 return; | |
306 | |
307 CFWL_NoteDriver* pDriver = | |
308 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); | |
309 if (!pDriver) | |
310 return; | |
311 | |
312 pDriver->PopNoteLoop(); | |
313 SetStates(FWL_WGTSTATE_Invisible, true); | |
314 #else | |
315 SetStates(FWL_WGTSTATE_Invisible, true); | |
316 m_pNoteLoop->EndModalLoop(); | |
317 #endif | |
318 } | |
319 | |
320 void IFWL_Form::DrawBackground(CFX_Graphics* pGraphics, | |
321 IFWL_ThemeProvider* pTheme) { | |
322 CFWL_ThemeBackground param; | |
323 param.m_pWidget = this; | |
324 param.m_iPart = CFWL_Part::Background; | |
325 param.m_pGraphics = pGraphics; | |
326 param.m_rtPart = m_rtRelative; | |
327 param.m_rtPart.Deflate(m_fCYBorder, m_fCXBorder, m_fCYBorder, m_fCXBorder); | |
328 pTheme->DrawBackground(¶m); | |
329 } | |
330 | |
331 void IFWL_Form::RemoveSysButtons() { | |
332 delete m_pCloseBox; | |
333 m_pCloseBox = nullptr; | |
334 delete m_pMinBox; | |
335 m_pMinBox = nullptr; | |
336 delete m_pMaxBox; | |
337 m_pMaxBox = nullptr; | |
338 } | |
339 | |
340 CFWL_SysBtn* IFWL_Form::GetSysBtnAtPoint(FX_FLOAT fx, FX_FLOAT fy) { | |
341 if (m_pCloseBox && m_pCloseBox->m_rtBtn.Contains(fx, fy)) | |
342 return m_pCloseBox; | |
343 if (m_pMaxBox && m_pMaxBox->m_rtBtn.Contains(fx, fy)) | |
344 return m_pMaxBox; | |
345 if (m_pMinBox && m_pMinBox->m_rtBtn.Contains(fx, fy)) | |
346 return m_pMinBox; | |
347 return nullptr; | |
348 } | |
349 | |
350 CFWL_SysBtn* IFWL_Form::GetSysBtnByState(uint32_t dwState) { | |
351 if (m_pCloseBox && (m_pCloseBox->m_dwState & dwState)) | |
352 return m_pCloseBox; | |
353 if (m_pMaxBox && (m_pMaxBox->m_dwState & dwState)) | |
354 return m_pMaxBox; | |
355 if (m_pMinBox && (m_pMinBox->m_dwState & dwState)) | |
356 return m_pMinBox; | |
357 return nullptr; | |
358 } | |
359 | |
360 CFWL_SysBtn* IFWL_Form::GetSysBtnByIndex(int32_t nIndex) { | |
361 if (nIndex < 0) | |
362 return nullptr; | |
363 | |
364 CFX_ArrayTemplate<CFWL_SysBtn*> arrBtn; | |
365 if (m_pMinBox) | |
366 arrBtn.Add(m_pMinBox); | |
367 if (m_pMaxBox) | |
368 arrBtn.Add(m_pMaxBox); | |
369 if (m_pCloseBox) | |
370 arrBtn.Add(m_pCloseBox); | |
371 return arrBtn[nIndex]; | |
372 } | |
373 | |
374 int32_t IFWL_Form::GetSysBtnIndex(CFWL_SysBtn* pBtn) { | |
375 CFX_ArrayTemplate<CFWL_SysBtn*> arrBtn; | |
376 if (m_pMinBox) | |
377 arrBtn.Add(m_pMinBox); | |
378 if (m_pMaxBox) | |
379 arrBtn.Add(m_pMaxBox); | |
380 if (m_pCloseBox) | |
381 arrBtn.Add(m_pCloseBox); | |
382 return arrBtn.Find(pBtn); | |
383 } | |
384 | |
385 void IFWL_Form::GetEdgeRect(CFX_RectF& rtEdge) { | |
386 rtEdge = m_rtRelative; | |
387 if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) { | |
388 FX_FLOAT fCX = GetBorderSize(); | |
389 FX_FLOAT fCY = GetBorderSize(false); | |
390 rtEdge.Deflate(fCX, fCY, fCX, fCY); | |
391 } | |
392 } | |
393 | |
394 void IFWL_Form::SetWorkAreaRect() { | |
395 m_rtRestore = m_pProperties->m_rtWidget; | |
396 CFWL_WidgetMgr* pWidgetMgr = GetOwnerApp()->GetWidgetMgr(); | |
397 if (!pWidgetMgr) | |
398 return; | |
399 | |
400 m_bSetMaximize = true; | |
401 Repaint(&m_rtRelative); | |
402 } | |
403 | |
404 void IFWL_Form::Layout() { | |
405 GetRelativeRect(m_rtRelative); | |
406 | |
407 #ifndef FWL_UseMacSystemBorder | |
408 ResetSysBtn(); | |
409 #endif | |
410 } | |
411 | |
412 void IFWL_Form::ResetSysBtn() { | |
413 m_fCXBorder = | |
414 *static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::CXBorder)); | |
415 m_fCYBorder = | |
416 *static_cast<FX_FLOAT*>(GetThemeCapacity(CFWL_WidgetCapacity::CYBorder)); | |
417 RemoveSysButtons(); | |
418 | |
419 m_iSysBox = 0; | |
420 if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_CloseBox) { | |
421 m_pCloseBox = new CFWL_SysBtn; | |
422 m_pCloseBox->m_rtBtn.Set( | |
423 m_rtRelative.right() - kSystemButtonMargin - kSystemButtonSize, | |
424 kSystemButtonMargin, kSystemButtonSize, kSystemButtonSize); | |
425 m_iSysBox++; | |
426 } | |
427 if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_MaximizeBox) { | |
428 m_pMaxBox = new CFWL_SysBtn; | |
429 if (m_pCloseBox) { | |
430 m_pMaxBox->m_rtBtn.Set( | |
431 m_pCloseBox->m_rtBtn.left - kSystemButtonSpan - kSystemButtonSize, | |
432 m_pCloseBox->m_rtBtn.top, kSystemButtonSize, kSystemButtonSize); | |
433 } else { | |
434 m_pMaxBox->m_rtBtn.Set( | |
435 m_rtRelative.right() - kSystemButtonMargin - kSystemButtonSize, | |
436 kSystemButtonMargin, kSystemButtonSize, kSystemButtonSize); | |
437 } | |
438 m_iSysBox++; | |
439 } | |
440 if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_MinimizeBox) { | |
441 m_pMinBox = new CFWL_SysBtn; | |
442 if (m_pMaxBox) { | |
443 m_pMinBox->m_rtBtn.Set( | |
444 m_pMaxBox->m_rtBtn.left - kSystemButtonSpan - kSystemButtonSize, | |
445 m_pMaxBox->m_rtBtn.top, kSystemButtonSize, kSystemButtonSize); | |
446 } else if (m_pCloseBox) { | |
447 m_pMinBox->m_rtBtn.Set( | |
448 m_pCloseBox->m_rtBtn.left - kSystemButtonSpan - kSystemButtonSize, | |
449 m_pCloseBox->m_rtBtn.top, kSystemButtonSize, kSystemButtonSize); | |
450 } else { | |
451 m_pMinBox->m_rtBtn.Set( | |
452 m_rtRelative.right() - kSystemButtonMargin - kSystemButtonSize, | |
453 kSystemButtonMargin, kSystemButtonSize, kSystemButtonSize); | |
454 } | |
455 m_iSysBox++; | |
456 } | |
457 } | |
458 | |
459 void IFWL_Form::RegisterForm() { | |
460 const CFWL_App* pApp = GetOwnerApp(); | |
461 if (!pApp) | |
462 return; | |
463 | |
464 CFWL_NoteDriver* pDriver = | |
465 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); | |
466 if (!pDriver) | |
467 return; | |
468 | |
469 pDriver->RegisterForm(this); | |
470 } | |
471 | |
472 void IFWL_Form::UnRegisterForm() { | |
473 const CFWL_App* pApp = GetOwnerApp(); | |
474 if (!pApp) | |
475 return; | |
476 | |
477 CFWL_NoteDriver* pDriver = | |
478 static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); | |
479 if (!pDriver) | |
480 return; | |
481 | |
482 pDriver->UnRegisterForm(this); | |
483 } | |
484 | |
485 void IFWL_Form::OnProcessMessage(CFWL_Message* pMessage) { | |
486 #ifndef FWL_UseMacSystemBorder | |
487 if (!pMessage) | |
488 return; | |
489 | |
490 switch (pMessage->GetClassID()) { | |
491 case CFWL_MessageType::Mouse: { | |
492 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); | |
493 switch (pMsg->m_dwCmd) { | |
494 case FWL_MouseCommand::LeftButtonDown: | |
495 OnLButtonDown(pMsg); | |
496 break; | |
497 case FWL_MouseCommand::LeftButtonUp: | |
498 OnLButtonUp(pMsg); | |
499 break; | |
500 case FWL_MouseCommand::Move: | |
501 OnMouseMove(pMsg); | |
502 break; | |
503 case FWL_MouseCommand::Leave: | |
504 OnMouseLeave(pMsg); | |
505 break; | |
506 case FWL_MouseCommand::LeftButtonDblClk: | |
507 OnLButtonDblClk(pMsg); | |
508 break; | |
509 default: | |
510 break; | |
511 } | |
512 break; | |
513 } | |
514 default: | |
515 break; | |
516 } | |
517 #endif // FWL_UseMacSystemBorder | |
518 } | |
519 | |
520 void IFWL_Form::OnDrawWidget(CFX_Graphics* pGraphics, | |
521 const CFX_Matrix* pMatrix) { | |
522 DrawWidget(pGraphics, pMatrix); | |
523 } | |
524 | |
525 void IFWL_Form::OnLButtonDown(CFWL_MsgMouse* pMsg) { | |
526 SetGrab(true); | |
527 m_bLButtonDown = true; | |
528 | |
529 CFWL_SysBtn* pPressBtn = GetSysBtnAtPoint(pMsg->m_fx, pMsg->m_fy); | |
530 m_iCaptureBtn = GetSysBtnIndex(pPressBtn); | |
531 | |
532 if (!pPressBtn) | |
533 return; | |
534 | |
535 pPressBtn->SetPressed(); | |
536 Repaint(&pPressBtn->m_rtBtn); | |
537 } | |
538 | |
539 void IFWL_Form::OnLButtonUp(CFWL_MsgMouse* pMsg) { | |
540 SetGrab(false); | |
541 m_bLButtonDown = false; | |
542 CFWL_SysBtn* pPointBtn = GetSysBtnAtPoint(pMsg->m_fx, pMsg->m_fy); | |
543 CFWL_SysBtn* pPressedBtn = GetSysBtnByIndex(m_iCaptureBtn); | |
544 if (!pPressedBtn || pPointBtn != pPressedBtn) | |
545 return; | |
546 if (pPressedBtn == GetSysBtnByState(FWL_SYSBUTTONSTATE_Pressed)) | |
547 pPressedBtn->SetNormal(); | |
548 if (pPressedBtn == m_pMaxBox) { | |
549 if (m_bMaximized) { | |
550 SetWidgetRect(m_rtRestore); | |
551 Update(); | |
552 Repaint(); | |
553 } else { | |
554 SetWorkAreaRect(); | |
555 Update(); | |
556 } | |
557 m_bMaximized = !m_bMaximized; | |
558 } else if (pPressedBtn != m_pMinBox) { | |
559 CFWL_EvtClose eClose; | |
560 eClose.m_pSrcTarget = this; | |
561 DispatchEvent(&eClose); | |
562 } | |
563 } | |
564 | |
565 void IFWL_Form::OnMouseMove(CFWL_MsgMouse* pMsg) { | |
566 if (m_bLButtonDown) | |
567 return; | |
568 | |
569 CFX_RectF rtInvalidate; | |
570 rtInvalidate.Reset(); | |
571 CFWL_SysBtn* pPointBtn = GetSysBtnAtPoint(pMsg->m_fx, pMsg->m_fy); | |
572 CFWL_SysBtn* pOldHover = GetSysBtnByState(FWL_SYSBUTTONSTATE_Hover); | |
573 | |
574 #if _FX_OS_ == _FX_MACOSX_ | |
575 { | |
576 if (pOldHover && pPointBtn != pOldHover) | |
577 pOldHover->SetNormal(); | |
578 if (pPointBtn && pPointBtn != pOldHover) | |
579 pPointBtn->SetHover(); | |
580 if (m_pCloseBox) | |
581 rtInvalidate = m_pCloseBox->m_rtBtn; | |
582 if (m_pMaxBox) { | |
583 if (rtInvalidate.IsEmpty()) | |
584 rtInvalidate = m_pMaxBox->m_rtBtn; | |
585 else | |
586 rtInvalidate.Union(m_pMaxBox->m_rtBtn); | |
587 } | |
588 if (m_pMinBox) { | |
589 if (rtInvalidate.IsEmpty()) | |
590 rtInvalidate = m_pMinBox->m_rtBtn; | |
591 else | |
592 rtInvalidate.Union(m_pMinBox->m_rtBtn); | |
593 } | |
594 if (!rtInvalidate.IsEmpty() && | |
595 rtInvalidate.Contains(pMsg->m_fx, pMsg->m_fy)) { | |
596 m_bMouseIn = true; | |
597 } | |
598 } | |
599 #else | |
600 { | |
601 if (pOldHover && pPointBtn != pOldHover) { | |
602 pOldHover->SetNormal(); | |
603 rtInvalidate = pOldHover->m_rtBtn; | |
604 } | |
605 if (pPointBtn && pPointBtn != pOldHover) { | |
606 pPointBtn->SetHover(); | |
607 if (rtInvalidate.IsEmpty()) | |
608 rtInvalidate = pPointBtn->m_rtBtn; | |
609 else | |
610 rtInvalidate.Union(pPointBtn->m_rtBtn); | |
611 } | |
612 } | |
613 #endif | |
614 | |
615 if (!rtInvalidate.IsEmpty()) | |
616 Repaint(&rtInvalidate); | |
617 } | |
618 | |
619 void IFWL_Form::OnMouseLeave(CFWL_MsgMouse* pMsg) { | |
620 CFWL_SysBtn* pHover = GetSysBtnByState(FWL_SYSBUTTONSTATE_Hover); | |
621 if (!pHover) | |
622 return; | |
623 | |
624 pHover->SetNormal(); | |
625 Repaint(&pHover->m_rtBtn); | |
626 } | |
627 | |
628 void IFWL_Form::OnLButtonDblClk(CFWL_MsgMouse* pMsg) { | |
629 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_FRM_Resize) && | |
630 HitTest(pMsg->m_fx, pMsg->m_fy) == FWL_WidgetHit::Titlebar) { | |
631 if (m_bMaximized) | |
632 SetWidgetRect(m_rtRestore); | |
633 else | |
634 SetWorkAreaRect(); | |
635 | |
636 Update(); | |
637 m_bMaximized = !m_bMaximized; | |
638 } | |
639 } | |
OLD | NEW |