Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: xfa/fwl/core/ifwl_checkbox.cpp

Issue 2524173002: Merge IFWL and CFWL classes. (Closed)
Patch Set: make chrome build happy Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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_checkbox.h"
8
9 #include <algorithm>
10 #include <memory>
11 #include <utility>
12
13 #include "third_party/base/ptr_util.h"
14 #include "xfa/fde/tto/fde_textout.h"
15 #include "xfa/fwl/core/cfwl_app.h"
16 #include "xfa/fwl/core/cfwl_evtcheckstatechanged.h"
17 #include "xfa/fwl/core/cfwl_msgkey.h"
18 #include "xfa/fwl/core/cfwl_msgmouse.h"
19 #include "xfa/fwl/core/cfwl_notedriver.h"
20 #include "xfa/fwl/core/cfwl_themebackground.h"
21 #include "xfa/fwl/core/cfwl_themetext.h"
22 #include "xfa/fwl/core/cfwl_widgetmgr.h"
23 #include "xfa/fwl/core/ifwl_themeprovider.h"
24
25 namespace {
26
27 const int kCaptionMargin = 5;
28
29 } // namespace
30
31 IFWL_CheckBox::IFWL_CheckBox(const CFWL_App* app,
32 std::unique_ptr<CFWL_WidgetProperties> properties)
33 : IFWL_Widget(app, std::move(properties), nullptr),
34 m_dwTTOStyles(FDE_TTOSTYLE_SingleLine),
35 m_iTTOAlign(FDE_TTOALIGNMENT_Center),
36 m_bBtnDown(false) {
37 m_rtClient.Reset();
38 m_rtBox.Reset();
39 m_rtCaption.Reset();
40 m_rtFocus.Reset();
41 }
42
43 IFWL_CheckBox::~IFWL_CheckBox() {}
44
45 FWL_Type IFWL_CheckBox::GetClassID() const {
46 return FWL_Type::CheckBox;
47 }
48
49 void IFWL_CheckBox::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) {
50 if (!bAutoSize) {
51 rect = m_pProperties->m_rtWidget;
52 return;
53 }
54
55 rect.Set(0, 0, 0, 0);
56 if (!m_pProperties->m_pThemeProvider)
57 m_pProperties->m_pThemeProvider = GetAvailableTheme();
58 if (!m_pProperties->m_pThemeProvider)
59 return;
60
61 CFX_SizeF sz = CalcTextSize(
62 L"Check box", m_pProperties->m_pThemeProvider,
63 !!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_MultiLine));
64 rect.Set(0, 0, sz.x, sz.y);
65 rect.Inflate(kCaptionMargin, kCaptionMargin);
66
67 FX_FLOAT fCheckBox = m_pDataProvider->GetBoxSize(this);
68 rect.width += fCheckBox;
69 rect.height = std::max(rect.height, fCheckBox);
70 IFWL_Widget::GetWidgetRect(rect, true);
71 }
72
73 void IFWL_CheckBox::Update() {
74 if (IsLocked())
75 return;
76 if (!m_pProperties->m_pThemeProvider)
77 m_pProperties->m_pThemeProvider = GetAvailableTheme();
78
79 UpdateTextOutStyles();
80 Layout();
81 }
82
83 void IFWL_CheckBox::DrawWidget(CFX_Graphics* pGraphics,
84 const CFX_Matrix* pMatrix) {
85 if (!pGraphics)
86 return;
87 if (!m_pProperties->m_pThemeProvider)
88 return;
89
90 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
91 if (HasBorder()) {
92 DrawBorder(pGraphics, CFWL_Part::Border, m_pProperties->m_pThemeProvider,
93 pMatrix);
94 }
95 if (HasEdge())
96 DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix);
97
98 int32_t dwStates = GetPartStates();
99
100 CFWL_ThemeBackground param;
101 param.m_pWidget = this;
102 param.m_iPart = CFWL_Part::Background;
103 param.m_dwStates = dwStates;
104 param.m_pGraphics = pGraphics;
105 if (pMatrix)
106 param.m_matrix.Concat(*pMatrix);
107 param.m_rtPart = m_rtClient;
108 if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused)
109 param.m_pData = &m_rtFocus;
110 pTheme->DrawBackground(&param);
111
112 param.m_iPart = CFWL_Part::CheckBox;
113 param.m_rtPart = m_rtBox;
114 pTheme->DrawBackground(&param);
115
116 CFWL_ThemeText textParam;
117 textParam.m_pWidget = this;
118 textParam.m_iPart = CFWL_Part::Caption;
119 textParam.m_dwStates = dwStates;
120 textParam.m_pGraphics = pGraphics;
121 if (pMatrix)
122 textParam.m_matrix.Concat(*pMatrix);
123 textParam.m_rtPart = m_rtCaption;
124 textParam.m_wsText = L"Check box";
125 textParam.m_dwTTOStyles = m_dwTTOStyles;
126 textParam.m_iTTOAlign = m_iTTOAlign;
127 pTheme->DrawText(&textParam);
128 }
129
130 void IFWL_CheckBox::SetCheckState(int32_t iCheck) {
131 m_pProperties->m_dwStates &= ~FWL_STATE_CKB_CheckMask;
132 switch (iCheck) {
133 case 1:
134 m_pProperties->m_dwStates |= FWL_STATE_CKB_Checked;
135 break;
136 case 2:
137 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_3State)
138 m_pProperties->m_dwStates |= FWL_STATE_CKB_Neutral;
139 break;
140 default:
141 break;
142 }
143 Repaint(&m_rtClient);
144 }
145
146 void IFWL_CheckBox::Layout() {
147 m_pProperties->m_rtWidget.width =
148 FXSYS_round(m_pProperties->m_rtWidget.width);
149 m_pProperties->m_rtWidget.height =
150 FXSYS_round(m_pProperties->m_rtWidget.height);
151 GetClientRect(m_rtClient);
152
153 FX_FLOAT fBoxTop = m_rtClient.top;
154 FX_FLOAT fClientBottom = m_rtClient.bottom();
155
156 FX_FLOAT fCheckBox = m_pDataProvider->GetBoxSize(this);
157 switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_VLayoutMask) {
158 case FWL_STYLEEXT_CKB_Top:
159 break;
160 case FWL_STYLEEXT_CKB_Bottom: {
161 fBoxTop = fClientBottom - fCheckBox;
162 break;
163 }
164 case FWL_STYLEEXT_CKB_VCenter:
165 default: {
166 fBoxTop = m_rtClient.top + (m_rtClient.height - fCheckBox) / 2;
167 fBoxTop = FXSYS_floor(fBoxTop);
168 break;
169 }
170 }
171
172 FX_FLOAT fBoxLeft = m_rtClient.left;
173 FX_FLOAT fTextLeft = 0.0;
174 FX_FLOAT fTextRight = 0.0;
175 FX_FLOAT fClientRight = m_rtClient.right();
176 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_LeftText) {
177 fBoxLeft = fClientRight - fCheckBox;
178 fTextLeft = m_rtClient.left;
179 fTextRight = fBoxLeft;
180 } else {
181 fTextLeft = fBoxLeft + fCheckBox;
182 fTextRight = fClientRight;
183 }
184 m_rtBox.Set(fBoxLeft, fBoxTop, fCheckBox, fCheckBox);
185 m_rtCaption.Set(fTextLeft, m_rtClient.top, fTextRight - fTextLeft,
186 m_rtClient.height);
187 m_rtCaption.Inflate(-kCaptionMargin, -kCaptionMargin);
188
189 CFX_RectF rtFocus;
190 rtFocus.Set(m_rtCaption.left, m_rtCaption.top, m_rtCaption.width,
191 m_rtCaption.height);
192
193 CalcTextRect(L"Check box", m_pProperties->m_pThemeProvider, m_dwTTOStyles,
194 m_iTTOAlign, rtFocus);
195 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_MultiLine) == 0) {
196 FX_FLOAT fWidth = std::max(m_rtCaption.width, rtFocus.width);
197 FX_FLOAT fHeight = std::min(m_rtCaption.height, rtFocus.height);
198 FX_FLOAT fLeft = m_rtCaption.left;
199 FX_FLOAT fTop = m_rtCaption.top;
200 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_HLayoutMask) ==
201 FWL_STYLEEXT_CKB_Center) {
202 fLeft = m_rtCaption.left + (m_rtCaption.width - fWidth) / 2;
203 } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_HLayoutMask) ==
204 FWL_STYLEEXT_CKB_Right) {
205 fLeft = m_rtCaption.right() - fWidth;
206 }
207 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_VLayoutMask) ==
208 FWL_STYLEEXT_CKB_VCenter) {
209 fTop = m_rtCaption.top + (m_rtCaption.height - fHeight) / 2;
210 } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_VLayoutMask) ==
211 FWL_STYLEEXT_CKB_Bottom) {
212 fTop = m_rtCaption.bottom() - fHeight;
213 }
214 m_rtFocus.Set(fLeft, fTop, fWidth, fHeight);
215 } else {
216 m_rtFocus.Set(rtFocus.left, rtFocus.top, rtFocus.width, rtFocus.height);
217 }
218 m_rtFocus.Inflate(1, 1);
219 }
220
221 uint32_t IFWL_CheckBox::GetPartStates() const {
222 int32_t dwStates = CFWL_PartState_Normal;
223 if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) ==
224 FWL_STATE_CKB_Neutral) {
225 dwStates = CFWL_PartState_Neutral;
226 } else if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) ==
227 FWL_STATE_CKB_Checked) {
228 dwStates = CFWL_PartState_Checked;
229 }
230 if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)
231 dwStates |= CFWL_PartState_Disabled;
232 else if (m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered)
233 dwStates |= CFWL_PartState_Hovered;
234 else if (m_pProperties->m_dwStates & FWL_STATE_CKB_Pressed)
235 dwStates |= CFWL_PartState_Pressed;
236 else
237 dwStates |= CFWL_PartState_Normal;
238 if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused)
239 dwStates |= CFWL_PartState_Focused;
240 return dwStates;
241 }
242
243 void IFWL_CheckBox::UpdateTextOutStyles() {
244 switch (m_pProperties->m_dwStyleExes &
245 (FWL_STYLEEXT_CKB_HLayoutMask | FWL_STYLEEXT_CKB_VLayoutMask)) {
246 case FWL_STYLEEXT_CKB_Left | FWL_STYLEEXT_CKB_Top: {
247 m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft;
248 break;
249 }
250 case FWL_STYLEEXT_CKB_Center | FWL_STYLEEXT_CKB_Top: {
251 m_iTTOAlign = FDE_TTOALIGNMENT_TopCenter;
252 break;
253 }
254 case FWL_STYLEEXT_CKB_Right | FWL_STYLEEXT_CKB_Top: {
255 m_iTTOAlign = FDE_TTOALIGNMENT_TopRight;
256 break;
257 }
258 case FWL_STYLEEXT_CKB_Left | FWL_STYLEEXT_CKB_VCenter: {
259 m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft;
260 break;
261 }
262 case FWL_STYLEEXT_CKB_Right | FWL_STYLEEXT_CKB_VCenter: {
263 m_iTTOAlign = FDE_TTOALIGNMENT_CenterRight;
264 break;
265 }
266 case FWL_STYLEEXT_CKB_Left | FWL_STYLEEXT_CKB_Bottom: {
267 m_iTTOAlign = FDE_TTOALIGNMENT_BottomLeft;
268 break;
269 }
270 case FWL_STYLEEXT_CKB_Center | FWL_STYLEEXT_CKB_Bottom: {
271 m_iTTOAlign = FDE_TTOALIGNMENT_BottomCenter;
272 break;
273 }
274 case FWL_STYLEEXT_CKB_Right | FWL_STYLEEXT_CKB_Bottom: {
275 m_iTTOAlign = FDE_TTOALIGNMENT_BottomRight;
276 break;
277 }
278 case FWL_STYLEEXT_CKB_Center | FWL_STYLEEXT_CKB_VCenter:
279 default: {
280 m_iTTOAlign = FDE_TTOALIGNMENT_Center;
281 break;
282 }
283 }
284 m_dwTTOStyles = 0;
285 if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading)
286 m_dwTTOStyles |= FDE_TTOSTYLE_RTL;
287 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_MultiLine)
288 m_dwTTOStyles |= FDE_TTOSTYLE_LineWrap;
289 else
290 m_dwTTOStyles |= FDE_TTOSTYLE_SingleLine;
291 }
292
293 void IFWL_CheckBox::NextStates() {
294 uint32_t dwFirststate = m_pProperties->m_dwStates;
295 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_RadioButton) {
296 if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) ==
297 FWL_STATE_CKB_Unchecked) {
298 CFWL_WidgetMgr* pWidgetMgr = GetOwnerApp()->GetWidgetMgr();
299 if (!pWidgetMgr->IsFormDisabled()) {
300 CFX_ArrayTemplate<IFWL_Widget*> radioarr;
301 pWidgetMgr->GetSameGroupRadioButton(this, radioarr);
302 IFWL_CheckBox* pCheckBox = nullptr;
303 int32_t iCount = radioarr.GetSize();
304 for (int32_t i = 0; i < iCount; i++) {
305 pCheckBox = static_cast<IFWL_CheckBox*>(radioarr[i]);
306 if (pCheckBox != this &&
307 pCheckBox->GetStates() & FWL_STATE_CKB_Checked) {
308 pCheckBox->SetCheckState(0);
309 CFX_RectF rt;
310 pCheckBox->GetWidgetRect(rt);
311 rt.left = rt.top = 0;
312 m_pWidgetMgr->RepaintWidget(pCheckBox, &rt);
313 break;
314 }
315 }
316 }
317 m_pProperties->m_dwStates |= FWL_STATE_CKB_Checked;
318 }
319 } else {
320 if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) ==
321 FWL_STATE_CKB_Neutral) {
322 m_pProperties->m_dwStates &= ~FWL_STATE_CKB_CheckMask;
323 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_3State)
324 m_pProperties->m_dwStates |= FWL_STATE_CKB_Checked;
325 } else if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) ==
326 FWL_STATE_CKB_Checked) {
327 m_pProperties->m_dwStates &= ~FWL_STATE_CKB_CheckMask;
328 } else {
329 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_3State)
330 m_pProperties->m_dwStates |= FWL_STATE_CKB_Neutral;
331 else
332 m_pProperties->m_dwStates |= FWL_STATE_CKB_Checked;
333 }
334 }
335
336 Repaint(&m_rtClient);
337 if (dwFirststate == m_pProperties->m_dwStates)
338 return;
339
340 CFWL_EvtCheckStateChanged wmCheckBoxState;
341 wmCheckBoxState.m_pSrcTarget = this;
342 DispatchEvent(&wmCheckBoxState);
343 }
344
345 void IFWL_CheckBox::OnProcessMessage(CFWL_Message* pMessage) {
346 if (!pMessage)
347 return;
348
349 switch (pMessage->GetClassID()) {
350 case CFWL_MessageType::SetFocus:
351 OnFocusChanged(true);
352 break;
353 case CFWL_MessageType::KillFocus:
354 OnFocusChanged(false);
355 break;
356 case CFWL_MessageType::Mouse: {
357 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
358 switch (pMsg->m_dwCmd) {
359 case FWL_MouseCommand::LeftButtonDown:
360 OnLButtonDown();
361 break;
362 case FWL_MouseCommand::LeftButtonUp:
363 OnLButtonUp(pMsg);
364 break;
365 case FWL_MouseCommand::Move:
366 OnMouseMove(pMsg);
367 break;
368 case FWL_MouseCommand::Leave:
369 OnMouseLeave();
370 break;
371 default:
372 break;
373 }
374 break;
375 }
376 case CFWL_MessageType::Key: {
377 CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage);
378 if (pKey->m_dwCmd == FWL_KeyCommand::KeyDown)
379 OnKeyDown(pKey);
380 break;
381 }
382 default:
383 break;
384 }
385
386 IFWL_Widget::OnProcessMessage(pMessage);
387 }
388
389 void IFWL_CheckBox::OnDrawWidget(CFX_Graphics* pGraphics,
390 const CFX_Matrix* pMatrix) {
391 DrawWidget(pGraphics, pMatrix);
392 }
393
394 void IFWL_CheckBox::OnFocusChanged(bool bSet) {
395 if (bSet)
396 m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
397 else
398 m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
399
400 Repaint(&m_rtClient);
401 }
402
403 void IFWL_CheckBox::OnLButtonDown() {
404 if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)
405 return;
406 if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0)
407 SetFocus(true);
408
409 m_bBtnDown = true;
410 m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Hovered;
411 m_pProperties->m_dwStates |= FWL_STATE_CKB_Pressed;
412 Repaint(&m_rtClient);
413 }
414
415 void IFWL_CheckBox::OnLButtonUp(CFWL_MsgMouse* pMsg) {
416 if (!m_bBtnDown)
417 return;
418
419 m_bBtnDown = false;
420 if (!m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy))
421 return;
422
423 m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered;
424 m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Pressed;
425 NextStates();
426 }
427
428 void IFWL_CheckBox::OnMouseMove(CFWL_MsgMouse* pMsg) {
429 if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)
430 return;
431
432 bool bRepaint = false;
433 if (m_bBtnDown) {
434 if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
435 if ((m_pProperties->m_dwStates & FWL_STATE_CKB_Pressed) == 0) {
436 bRepaint = true;
437 m_pProperties->m_dwStates |= FWL_STATE_CKB_Pressed;
438 }
439 if ((m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered)) {
440 bRepaint = true;
441 m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Hovered;
442 }
443 } else {
444 if (m_pProperties->m_dwStates & FWL_STATE_CKB_Pressed) {
445 bRepaint = true;
446 m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Pressed;
447 }
448 if ((m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered) == 0) {
449 bRepaint = true;
450 m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered;
451 }
452 }
453 } else {
454 if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
455 if ((m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered) == 0) {
456 bRepaint = true;
457 m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered;
458 }
459 }
460 }
461 if (bRepaint)
462 Repaint(&m_rtBox);
463 }
464
465 void IFWL_CheckBox::OnMouseLeave() {
466 if (m_bBtnDown)
467 m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered;
468 else
469 m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Hovered;
470
471 Repaint(&m_rtBox);
472 }
473
474 void IFWL_CheckBox::OnKeyDown(CFWL_MsgKey* pMsg) {
475 if (pMsg->m_dwKeyCode == FWL_VKEY_Tab) {
476 DispatchKeyEvent(pMsg);
477 return;
478 }
479 if (pMsg->m_dwKeyCode == FWL_VKEY_Return ||
480 pMsg->m_dwKeyCode == FWL_VKEY_Space) {
481 NextStates();
482 }
483 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698