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

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

Powered by Google App Engine
This is Rietveld 408576698