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