-
Notifications
You must be signed in to change notification settings - Fork 71
Expand file tree
/
Copy pathCheckBox.h
More file actions
1151 lines (1025 loc) · 43.1 KB
/
CheckBox.h
File metadata and controls
1151 lines (1025 loc) · 43.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#ifndef UI_CONTROL_CHECKBOX_H_
#define UI_CONTROL_CHECKBOX_H_
#include "duilib/Control/Button.h"
#include "duilib/Core/StateColorMap2.h"
#include "duilib/Utils/AttributeUtil.h"
#include "duilib/Core/StateColorMap.h"
#include "duilib/Animation/AnimationManager.h"
#include "duilib/Animation/AnimationPlayer.h"
namespace ui {
/** CheckBox功能的实现,功能要点如下:
* 1. CheckBox有两种状态:m_bSelected(选择状态) 和 m_bChecked(勾选状态)
* 2. 选择状态:鼠标点击CheckBox任何区域,都会触发m_bSelected(选择状态)的变化
* 3. 勾选状态:只有鼠标点击在CheckBox图标上时,才会触发m_bChecked(勾选状态)的变化,点击其他区域,勾选状态不变
* 4. 选择状态(m_bSelected)的变化,当 IsAutoCheckSelect() 函数返回true时,会导致勾选状态(m_bChecked)的变化,保持状态一致(Select -> Check)
* 5. 勾选状态(m_bChecked)的变化,当 IsAutoSelectCheck() 函数返回true时,会导致选择状态(m_bSelected)的变化,保持状态一致(Check - Select)
* 6. 默认情况下,勾选状态关闭,当 SupportCheckMode() 函数返回true时,开启勾选状态
* 7. m_bSelected(选择状态) 和 m_bChecked(勾选状态)共享图片资源和字体相关资源
* 8. m_bSelected(选择状态)支持三态:选择/部分选择/未选择
* 9. m_bChecked(勾选状态)支持三态:勾选/部分勾选/未勾选
* 10. CheckBox继承自Button类,不会触发按钮的kEventClick事件,但会执行Activate这个虚函数
*/
template<typename InheritType = Control>
class UILIB_API CheckBoxTemplate : public ButtonTemplate<InheritType>
{
typedef ButtonTemplate<InheritType> BaseClass;
public:
explicit CheckBoxTemplate(Window* pWindow);
CheckBoxTemplate(const CheckBoxTemplate& r) = delete;
CheckBoxTemplate& operator=(const CheckBoxTemplate& r) = delete;
virtual ~CheckBoxTemplate() override;
/// 重写父类方法,提供个性化功能,请参考父类声明
virtual DString GetType() const override;
virtual void Activate(const EventArgs* pMsg) override;
virtual void SetAttribute(const DString& strName, const DString& strValue) override;
virtual void PaintStateColors(IRender* pRender) override;
virtual void PaintStateImages(IRender* pRender) override;
virtual void PaintText(IRender* pRender) override;
virtual bool HasHotState() override;
virtual DString GetBorderColor(ControlStateType stateType) const override;
/** DPI发生变化,更新控件大小和布局
* @param [in] nOldDpiScale 旧的DPI缩放百分比
* @param [in] nNewDpiScale 新的DPI缩放百分比,与Dpi().GetScale()的值一致
*/
virtual void ChangeDpiScale(uint32_t nOldDpiScale, uint32_t nNewDpiScale) override;
public:
/** 获取被选择时的图片
* @param [in] stateType 要获取何种状态下的图片,参考 ControlStateType 枚举
* @return 返回图片路径和属性
*/
DString GetSelectedStateImage(ControlStateType stateType) const;
/** 设置被选择时的图片
* @param [in] stateType 要设置哪中状态下的图片
* @param [in] strImage 图片路径和属性
*/
void SetSelectedStateImage(ControlStateType stateType, const DString& strImage);
/** 获取被选择时的前景图片
* @param[in] stateType 要获取何种状态下的前景图片
*/
DString GetSelectedForeStateImage(ControlStateType stateType) const;
/** 设置被选择时的前景图片
* @param[in] stateType 要设置何种状态下的前景图片
* @param[in] strImage 图片位置
*/
void SetSelectedForeStateImage(ControlStateType stateType, const DString& strImage);
/** 获取被选择时的文本颜色
*/
DString GetSelectedTextColor() const;
/** 设置被选择时的文本颜色
* @param[in] dwTextColor 要设置的颜色字符串,该颜色必须在 global.xml 中存在
*/
void SetSelectedTextColor(const DString& dwTextColor);
/** 获取被选择时指定状态下的文本颜色
* @param[in] stateType 要获取何种状态下的颜色
* @return 返回颜色字符串,该值在 global.xml 中定义
*/
DString GetSelectedStateTextColor(ControlStateType stateType) const;
/** 设置被选择时指定状态下的文本颜色
* @param[in] stateType 要设置何种状态下的颜色
* @param[in] stateColor 要设置的颜色
*/
void SetSelectedStateTextColor(ControlStateType stateType, const DString& dwTextColor);
/** 获取被选择时的控件颜色
* @param [in] stateType 要获取何种状态下的颜色
* @return 返回颜色字符串,该值在 global.xml 中定义
*/
DString GetSelectStateColor(ControlStateType stateType) const;
/** 获取被选择时的控件颜色矩形外边距
* @param [in] stateType 要获取何种状态下的颜色值,参考 ControlStateType 枚举
* @return 指定状态下设定的颜色矩形外边距(已经做过DPI缩放)
*/
UiMargin GetSelectStateColorMargin(ControlStateType stateType) const;
/** 获取被选择时的控件颜色矩形圆角大小
* @param [in] stateType 要获取何种状态下的颜色值,参考 ControlStateType 枚举
* @return 指定状态下设定的颜色矩形圆角大小(已经做过DPI缩放)
*/
UiSize GetSelectStateColorRound(ControlStateType stateType) const;
/** 设置被选择时的控件颜色
* @param [in] stateType 要设置何种状态下的颜色
* @param [in] stateColor 要设置的颜色
* @param [in] colorMargin 要设置的颜色矩形外边距,如果不设置,则颜色矩形与控件矩形重合
* @param [in] colorRound 要设置的颜色矩形圆角大小,如果不设置,则颜色矩形跟随控件矩形的形状
* @param [in] bNeedDpiScale 是否需要做DPI自适应
*/
void SetSelectedStateColor(ControlStateType stateType, const DString& stateColor);
void SetSelectedStateColorMargin(ControlStateType stateType, UiMargin colorMargin, bool bNeedDpiScale);
void SetSelectedStateColorRound(ControlStateType stateType, UiSize colorRound, bool bNeedDpiScale);
public:
/** 获取部分选择时的图片
* @param [in] stateType 要获取何种状态下的图片,参考 ControlStateType 枚举
* @return 返回图片路径和属性
*/
DString GetPartSelectedStateImage(ControlStateType stateType);
/** 设置部分选择时的图片
* @param [in] stateType 要设置哪中状态下的图片
* @param [in] strImage 图片路径和属性
*/
void SetPartSelectedStateImage(ControlStateType stateType, const DString& strImage);
/** 获取部分选择时的前景图片
* @param[in] stateType 要获取何种状态下的前景图片
*/
DString GetPartSelectedForeStateImage(ControlStateType stateType);
/** 设置部分选择时的前景图片
* @param[in] stateType 要设置何种状态下的前景图片
* @param[in] strImage 图片位置
*/
void SetPartSelectedForeStateImage(ControlStateType stateType, const DString& strImage);
public:
/** 判断当前是否是选择状态
* @return 返回 true 为选择状态,否则为 false
*/
bool IsSelected() const { return m_bSelected; }
/** 设置选择状态,但不触发事件,不更新界面
* @param [in] bSelected true为选择状态,false为非选择状态
*/
virtual void SetSelected(bool bSelected);
/** 设置控件是否选择状态
* @param [in] bSelected 为 true 时为选择状态,false 时为取消选择状态
* @param [in] bTriggerEvent 是否发送状态改变事件,true 为发送,否则为 false。默认为 false
* @param [in] vkFlag 按键标志, 取值范围参见 enum VKFlag 的定义
*/
virtual void Selected(bool bSelected, bool bTriggerEvent = false, uint64_t vkFlag = 0);
/** 设置部分选择标志(支持三态选择标志:全部选择/部分选择/未选择)
* @return 如果状态变化返回true,否则返回false
*/
bool SetPartSelected(bool bPartSelected);
/** 当前是否为部分选择
*/
bool IsPartSelected() const { return m_bPartSelected; }
/** 设置当选择状态变化时,是否自动同步到勾选状态,保持勾选状态与选择状态一致(Select -> Check)
* @param [in] bAutoCheckSelect 如果为true,表示Check状态与Select状态保持同步
*/
void SetAutoCheckSelect(bool bAutoCheckSelect) { m_bAutoCheckSelected = bAutoCheckSelect; }
/** 获取当选择状态变化时,是否自动同步到勾选状态 (Select -> Check)
*/
bool IsAutoCheckSelect() const { return m_bAutoCheckSelected; }
/** 监听被选择时的事件
* @param [in] callback 被选择时触发的回调函数
* @param [in] callbackID 该回调函数对应的ID(用于删除回调函数)
*/
void AttachSelect(const EventCallback& callback, EventCallbackID callbackID = 0) { this->AttachEvent(kEventSelect, callback, callbackID); }
/** 监听取消选择时的事件
* @param [in] callback 取消选择时触发的回调函数
* @param [in] callbackID 该回调函数对应的ID(用于删除回调函数)
*/
void AttachUnSelect(const EventCallback& callback, EventCallbackID callbackID = 0) { this->AttachEvent(kEventUnSelect, callback, callbackID); }
public:
///(三态选择[全部选择、部分选择、未选择]/勾选模式两种功能的函数)
/** 是否处于勾选状态, 仅当 SupportCheckMode() 函数为true的时候,有意义
*/
bool IsChecked() const { return m_bChecked; }
/** 设置Check状态
* @param [in] bChecked 是否设置为Check状态
* @param [in] bTriggerEvent 是否发送状态改变事件,true 为发送,否则为 false。默认为 false
*/
void SetChecked(bool bChecked, bool bTriggerEvent = false);
/** 设置部分勾选标志(支持三态勾选标志:全部勾选/部分勾选/未勾选)
* @return 如果状态变化返回true,否则返回false
*/
bool SetPartChecked(bool bPartChecked);
/** 当前是否为部分选择
*/
bool IsPartChecked() const { return m_bPartChecked; }
/** 设置当勾选状态变化时,是否自动同步到选择状态,保持选择状态与勾选状态一致(Check -> Select)
* @param [in] bAutoSelectCheck 如果为true,表示Select状态与Check状态保持同步
*/
void SetAutoSelectCheck(bool bAutoSelectCheck) { m_bAutoSelectChecked = bAutoSelectCheck; }
/** 获取当勾选状态变化时,是否自动同步到选择状态 (Check -> Select)
*/
bool IsAutoSelectCheck() const { return m_bAutoSelectChecked; }
/** 监听被勾选时的事件(仅当 SupportCheckMode() 函数为true的时候,会有这个事件)
* @param [in] callback 被选择时触发的回调函数
* @param [in] callbackID 该回调函数对应的ID(用于删除回调函数)
*/
void AttachCheck(const EventCallback& callback, EventCallbackID callbackID = 0) { this->AttachEvent(kEventCheck, callback, callbackID); }
/** 监听取消勾选时的事件(仅当 SupportCheckMode() 函数为true的时候,会有这个事件)
* @param [in] callback 取消选择时触发的回调函数
* @param [in] callbackID 该回调函数对应的ID(用于删除回调函数)
*/
void AttachUnCheck(const EventCallback& callback, EventCallbackID callbackID = 0) { this->AttachEvent(kEventUnCheck, callback, callbackID); }
/** 当前点击是否点击在CheckBox图标上(Check模式使用,用于在Activate函数中判断鼠标的点击位置)
*/
bool IsCheckBoxImageClicked() const;
/** 设置是否支持勾选模式
*/
void SetSupportCheckMode(bool bSupport) { m_bSupportCheckMode = bSupport; }
/** 是否支持勾选模式(目前是TreeView/ListCtrl在使用这个模式)
勾选模式是指:
(1)只有点击在CheckBox图片上的时候,勾选框图片才是选择状态(非勾选模式下,是点击在控件矩形内就选择)
(2)勾选状态和选择状态分离,是两个不同的状态
*/
virtual bool SupportCheckMode() const { return m_bSupportCheckMode; }
/** 是否绘制选择状态下的背景色,提供虚函数作为可选项
* (比如ListBox/TreeView节点在多选时,由于有勾选项,并不需要绘制选择状态的背景色)
*/
virtual bool CanPaintSelectedColors() const { return true; }
public:
/** 关闭CheckBox功能,清除CheckBox的所有图片属性(比如树节点,CheckBox功能是可用通过开关开启或者关闭的)
*/
void ClearStateImages();
/** 选择状态下,没有设置背景色或背景图时,是否用非选择状态的对应属性来绘制
* @return 返回 true 为选择状态,否则为 false
*/
bool IsPaintNormalFirst() const { return m_bPaintNormalFirst; }
/** 设置控件选择状态下,没有设置背景色或背景图时,用非选择状态的对应属性来绘制
* @param[in] bFirst 为 true 绘制非选择状态属性,false 不绘制
* @return 无
*/
void SetPaintNormalFirst(bool bFirst) { m_bPaintNormalFirst = bFirst; }
protected:
/** 鼠标按键弹起事件,用于判断是否点击在CheckBox图片上(实现勾选功能)
*/
virtual bool ButtonUp(const EventArgs& msg) override;
protected:
/** 获取被选择时指定状态下的实际被渲染文本颜色
* @param [in] buttonStateType 要获取何种状态下的颜色
* @param [out] stateType 实际被渲染的状态
* @return 返回颜色字符串,该值在 global.xml 中定义
*/
DString GetPaintSelectedStateTextColor(ControlStateType buttonStateType, ControlStateType& stateType) const;
/** 内部设置选择状态
* @return 返回true表示内部状态有变化,否则表示无变化
*/
bool PrivateSetSelected(bool bSelected);
/** 内部设置勾选状态
* @return 返回true表示内部状态有变化,否则表示无变化
*/
bool PrivateSetChecked(bool bChecked);
/** 选择状态变化事件(m_bSelected变量发生变化)
*/
virtual void OnPrivateSetSelected() {}
/** 勾选状态变化事件(m_bChecked变量发生变化)
*/
virtual void OnPrivateSetChecked() {}
private:
//选择状态的文本颜色
UiString m_dwSelectedTextColor;
//选择状态的文本颜色
StateColorMap* m_pSelectedTextColorMap;
//选择状态的背景颜色
StateColorMap2* m_pSelectedColorMap;
//选择状态
bool m_bSelected;
//是否为部分选择(只影响选择状态下绘制哪个图片,对业务无影响)
bool m_bPartSelected;
/** 当选择的时候,是否自动勾选,就是当m_bSelected变化的时候,同步修改m_bChecked,保持值相同
*/
bool m_bAutoCheckSelected;
//是否优先绘制Normal状态
bool m_bPaintNormalFirst;
private:
///(三态选择[全部选择、部分选择、未选择]/勾选模式两种功能的变量)
//是否支持勾选功能
bool m_bSupportCheckMode;
//是否已经处于Check状态(仅当 SupportCheckMode() 函数为true的时候,有意义)
bool m_bChecked;
//是否为部分勾选(只影响勾选状态下绘制哪个图片,对业务无影响)
bool m_bPartChecked;
/** 当勾选的时候,是否自动选择,就是当m_bChecked变化的时候,同步修改m_bSelected,保持值相同
*/
bool m_bAutoSelectChecked;
//当前点击是否点击在CheckBox图标上
bool m_bCheckBoxImageClicked;
//CheckBox图标所在的矩形(仅当 SupportCheckMode() 函数为true的时候,有意义)
UiRect* m_pCheckBoxImageRect;
};
template<typename InheritType>
CheckBoxTemplate<InheritType>::CheckBoxTemplate(Window* pWindow) :
ButtonTemplate<InheritType>(pWindow),
m_bSelected(false),
m_bPaintNormalFirst(false),
m_dwSelectedTextColor(),
m_pSelectedTextColorMap(nullptr),
m_pSelectedColorMap(nullptr),
m_bPartSelected(false),
m_bSupportCheckMode(false),
m_bChecked(false),
m_bPartChecked(false),
m_pCheckBoxImageRect(nullptr),
m_bAutoCheckSelected(false),
m_bAutoSelectChecked(false),
m_bCheckBoxImageClicked(false)
{
}
template<typename InheritType>
CheckBoxTemplate<InheritType>::~CheckBoxTemplate()
{
if (m_pSelectedTextColorMap != nullptr) {
delete m_pSelectedTextColorMap;
m_pSelectedTextColorMap = nullptr;
}
if (m_pSelectedColorMap != nullptr) {
delete m_pSelectedColorMap;
m_pSelectedColorMap = nullptr;
}
if (m_pCheckBoxImageRect != nullptr) {
delete m_pCheckBoxImageRect;
m_pCheckBoxImageRect = nullptr;
}
}
template<typename InheritType>
inline DString CheckBoxTemplate<InheritType>::GetType() const { return DUI_CTR_CHECKBOX; }
template<>
inline DString CheckBoxTemplate<Box>::GetType() const { return DUI_CTR_CHECKBOXBOX; }
template<>
inline DString CheckBoxTemplate<HBox>::GetType() const { return DUI_CTR_CHECKBOXHBOX; }
template<>
inline DString CheckBoxTemplate<VBox>::GetType() const { return DUI_CTR_CHECKBOXVBOX; }
template<typename InheritType>
void CheckBoxTemplate<InheritType>::SetAttribute(const DString& strName, const DString& strValue)
{
if (strName == _T("selected")) {
Selected(strValue == _T("true"), true);
}
else if ((strName == _T("switch_select")) || (strName == _T("switchselect"))) {
Selected(!IsSelected());
}
else if (strName == _T("support_check_Mode")) {
SetSupportCheckMode(strValue == _T("true"));
}
else if (strName == _T("auto_check_select")) {
//设置当选择状态变化时,是否自动同步到勾选状态,保持勾选状态与选择状态一致(Select->Check)
SetAutoCheckSelect(strValue == _T("true"));
}
else if (strName == _T("auto_select_check")) {
//设置当勾选状态变化时,是否自动同步到选择状态,保持选择状态与勾选状态一致(Check -> Select)
SetAutoSelectCheck(strValue == _T("true"));
}
else if ((strName == _T("normal_first")) || (strName == _T("normalfirst"))) {
SetPaintNormalFirst(strValue == _T("true"));
}
else if ((strName == _T("selected_normal_image")) || (strName == _T("selectednormalimage"))) {
SetSelectedStateImage(kControlStateNormal, strValue);
}
else if ((strName == _T("selected_hot_image")) || (strName == _T("selectedhotimage"))) {
SetSelectedStateImage(kControlStateHot, strValue);
}
else if ((strName == _T("selected_pushed_image")) || (strName == _T("selectedpushedimage"))) {
SetSelectedStateImage(kControlStatePushed, strValue);
}
else if ((strName == _T("selected_disabled_image")) || (strName == _T("selecteddisabledimage"))) {
SetSelectedStateImage(kControlStateDisabled, strValue);
}
else if ((strName == _T("selected_fore_normal_image")) || (strName == _T("selectedforenormalimage"))) {
SetSelectedForeStateImage(kControlStateNormal, strValue);
}
else if ((strName == _T("selected_fore_hot_image")) || (strName == _T("selectedforehotimage"))) {
SetSelectedForeStateImage(kControlStateHot, strValue);
}
else if ((strName == _T("selected_fore_pushed_image")) || (strName == _T("selectedforepushedimage"))) {
SetSelectedForeStateImage(kControlStatePushed, strValue);
}
else if ((strName == _T("selected_fore_disabled_image")) || (strName == _T("selectedforedisabledimage"))) {
SetSelectedForeStateImage(kControlStateDisabled, strValue);
}
else if (strName == _T("part_selected_normal_image")) {
SetPartSelectedStateImage(kControlStateNormal, strValue);
}
else if (strName == _T("part_selected_hot_image")) {
SetPartSelectedStateImage(kControlStateHot, strValue);
}
else if (strName == _T("part_selected_pushed_image")) {
SetPartSelectedStateImage(kControlStatePushed, strValue);
}
else if (strName == _T("part_selected_disabled_image")) {
SetPartSelectedStateImage(kControlStateDisabled, strValue);
}
else if (strName == _T("part_selected_fore_normal_image")) {
SetPartSelectedForeStateImage(kControlStateNormal, strValue);
}
else if (strName == _T("part_selected_fore_hot_image")) {
SetPartSelectedForeStateImage(kControlStateHot, strValue);
}
else if (strName == _T("part_selected_fore_pushed_image")) {
SetPartSelectedForeStateImage(kControlStatePushed, strValue);
}
else if (strName == _T("part_selected_fore_disabled_image")) {
SetPartSelectedForeStateImage(kControlStateDisabled, strValue);
}
else if ((strName == _T("selected_text_color")) || (strName == _T("selectedtextcolor"))) {
SetSelectedTextColor(strValue);
}
else if ((strName == _T("selected_normal_text_color")) || (strName == _T("selectednormaltextcolor"))) {
SetSelectedStateTextColor(kControlStateNormal, strValue);
}
else if ((strName == _T("selected_hot_text_color")) || (strName == _T("selectedhottextcolor"))) {
SetSelectedStateTextColor(kControlStateHot, strValue);
}
else if ((strName == _T("selected_pushed_text_color")) || (strName == _T("selectedpushedtextcolor"))) {
SetSelectedStateTextColor(kControlStatePushed, strValue);
}
else if ((strName == _T("selected_disabled_text_color")) || (strName == _T("selecteddisabledtextcolor"))) {
SetSelectedStateTextColor(kControlStateDisabled, strValue);
}
else if ((strName == _T("selected_normal_color")) || (strName == _T("selectednormalcolor"))) {
SetSelectedStateColor(kControlStateNormal, strValue);
}
else if ((strName == _T("selected_hot_color")) || (strName == _T("selectedhotcolor"))) {
SetSelectedStateColor(kControlStateHot, strValue);
}
else if ((strName == _T("selected_pushed_color")) || (strName == _T("selectedpushedcolor"))) {
SetSelectedStateColor(kControlStatePushed, strValue);
}
else if ((strName == _T("selected_disabled_color")) || (strName == _T("selecteddisabledcolor"))) {
SetSelectedStateColor(kControlStateDisabled, strValue);
}
else if (strName == _T("selected_normal_color_margin")) {
UiMargin rcMargin;
AttributeUtil::ParseMarginValue(strValue.c_str(), rcMargin);
SetSelectedStateColorMargin(kControlStateNormal, rcMargin, true);
}
else if (strName == _T("selected_hot_color_margin")) {
UiMargin rcMargin;
AttributeUtil::ParseMarginValue(strValue.c_str(), rcMargin);
SetSelectedStateColorMargin(kControlStateHot, rcMargin, true);
}
else if (strName == _T("selected_pushed_color_margin")) {
UiMargin rcMargin;
AttributeUtil::ParseMarginValue(strValue.c_str(), rcMargin);
SetSelectedStateColorMargin(kControlStatePushed, rcMargin, true);
}
else if (strName == _T("selected_disabled_color_margin")) {
UiMargin rcMargin;
AttributeUtil::ParseMarginValue(strValue.c_str(), rcMargin);
SetSelectedStateColorMargin(kControlStateDisabled, rcMargin, true);
}
else if (strName == _T("selected_normal_color_round")) {
UiSize szRound;
AttributeUtil::ParseSizeValue(strValue.c_str(), szRound);
SetSelectedStateColorRound(kControlStateNormal, szRound, true);
}
else if (strName == _T("selected_hot_color_round")) {
UiSize szRound;
AttributeUtil::ParseSizeValue(strValue.c_str(), szRound);
SetSelectedStateColorRound(kControlStateHot, szRound, true);
}
else if (strName == _T("selected_pushed_color_round")) {
UiSize szRound;
AttributeUtil::ParseSizeValue(strValue.c_str(), szRound);
SetSelectedStateColorRound(kControlStatePushed, szRound, true);
}
else if (strName == _T("selected_disabled_color_round")) {
UiSize szRound;
AttributeUtil::ParseSizeValue(strValue.c_str(), szRound);
SetSelectedStateColorRound(kControlStateDisabled, szRound, true);
}
else {
BaseClass::SetAttribute(strName, strValue);
}
}
template<typename InheritType>
void CheckBoxTemplate<InheritType>::ChangeDpiScale(uint32_t nOldDpiScale, uint32_t nNewDpiScale)
{
if (!this->Dpi().CheckDisplayScaleFactor(nNewDpiScale)) {
return;
}
BaseClass::ChangeDpiScale(nOldDpiScale, nNewDpiScale);
if (m_pSelectedColorMap != nullptr) {
for (int32_t nStateType = 0; nStateType < kControlStateCount; ++nStateType) {
ControlStateType stateType = (ControlStateType)nStateType;
UiMargin colorMargin = m_pSelectedColorMap->GetStateColorMargin(stateType);
UiMargin newColorMargin = this->Dpi().GetScaleMargin(colorMargin, nOldDpiScale);
if (!newColorMargin.Equals(colorMargin)) {
m_pSelectedColorMap->SetStateColorMargin(stateType, newColorMargin);
}
UiSize colorRound = m_pSelectedColorMap->GetStateColorRound(stateType);
UiSize newColorRound = this->Dpi().GetScaleSize(colorRound, nOldDpiScale);
if (!newColorRound.Equals(colorRound)) {
m_pSelectedColorMap->SetStateColorRound(stateType, newColorRound);
}
}
}
}
template<typename InheritType>
bool CheckBoxTemplate<InheritType>::ButtonUp(const EventArgs& msg)
{
std::weak_ptr<WeakFlag> weakFlag = this->GetWeakFlag();
bool bSetChecked = false;
bool bCheckedMode = SupportCheckMode();
if (bCheckedMode && (m_pCheckBoxImageRect != nullptr)) {
if (this->IsEnabled()) {
UiRect pos = this->GetPos();
UiPoint pt(msg.ptMouse);
pt.Offset(this->GetScrollOffsetInScrollBox());
if (pos.ContainsPt(pt) && m_pCheckBoxImageRect->ContainsPt(pt)) {
//确认点击在CheckBox图标上面,改变勾选状态(开关属性)
SetChecked(!IsChecked(), true);
bSetChecked = true;
if (weakFlag.expired()) {
return true;
}
}
}
}
if (bSetChecked) {
//标记为点击在CheckBox图标上
m_bCheckBoxImageClicked = true;
}
bool bRet = BaseClass::ButtonUp(msg);
if (bSetChecked && !weakFlag.expired()) {
//取消标记为点击在CheckBox图标上
m_bCheckBoxImageClicked = false;
}
return bRet;
}
template<typename InheritType>
bool CheckBoxTemplate<InheritType>::IsCheckBoxImageClicked() const
{
return m_bCheckBoxImageClicked;
}
template<typename InheritType>
void CheckBoxTemplate<InheritType>::Activate(const EventArgs* /*pMsg*/)
{
if (!this->IsActivatable()) {
return;
}
Selected(!m_bSelected, true);
}
template<typename InheritType>
void CheckBoxTemplate<InheritType>::SetSelected(bool bSelected)
{
//只修改变量值,不触发事件,不更新界面
PrivateSetSelected(bSelected);
}
template<typename InheritType>
void CheckBoxTemplate<InheritType>::Selected(bool bSelected, bool bTriggerEvent, uint64_t /*vkFlag*/)
{
bool bSelectChanged = m_bSelected != bSelected;
bool bChanged = PrivateSetSelected(bSelected);
if (bTriggerEvent && bSelectChanged) {
auto flag = this->GetWeakFlag();
if (m_bSelected) {
this->SendEvent(kEventSelect);
}
else {
this->SendEvent(kEventUnSelect);
}
if (flag.expired()) {
return;
}
if (IsAutoCheckSelect()) {
//同步触发Check事件
if (m_bChecked) {
this->SendEvent(kEventCheck);
}
else {
this->SendEvent(kEventUnCheck);
}
if (flag.expired()) {
return;
}
}
}
if (bChanged) {
this->Invalidate();
}
}
template<typename InheritType>
bool CheckBoxTemplate<InheritType>::PrivateSetSelected(bool bSelected)
{
bool bChanged = false;
bool bSelectChanged = false;
if (m_bSelected != bSelected) {
m_bSelected = bSelected;
bSelectChanged = true;
bChanged = true;
}
if (!bSelected && m_bPartSelected) {
//非选择状态时,对部分选择标记复位
m_bPartSelected = false;
bChanged = true;
}
if (IsAutoCheckSelect()) {
//自动同步给Check变量
bChanged = PrivateSetChecked(m_bSelected);
}
if (bSelectChanged) {
OnPrivateSetSelected();
}
return bChanged;
}
template<typename InheritType>
bool CheckBoxTemplate<InheritType>::SetPartSelected(bool bPartSelected)
{
bool bChanged = false;
if (m_bPartSelected != bPartSelected) {
m_bPartSelected = bPartSelected;
bChanged = true;
}
if (IsAutoCheckSelect()) {
//自动同步给PartChecked变量
if (m_bPartChecked != bPartSelected) {
m_bPartChecked = bPartSelected;
bChanged = true;
}
}
if (bChanged) {
this->Invalidate();
}
return bChanged;
}
template<typename InheritType>
void CheckBoxTemplate<InheritType>::SetChecked(bool bChecked, bool bTriggerEvent)
{
bool bCheckChanged = m_bChecked != bChecked;
bool bChanged = PrivateSetChecked(bChecked);
if (bTriggerEvent && bCheckChanged) {
auto flag = this->GetWeakFlag();
if (m_bChecked) {
this->SendEvent(kEventCheck);
}
else {
this->SendEvent(kEventUnCheck);
}
if (flag.expired()) {
return;
}
if (IsAutoSelectCheck()) {
if (m_bSelected) {
this->SendEvent(kEventSelect);
}
else {
this->SendEvent(kEventUnSelect);
}
if (flag.expired()) {
return;
}
}
}
if (bChanged) {
this->Invalidate();
}
}
template<typename InheritType>
bool CheckBoxTemplate<InheritType>::SetPartChecked(bool bPartChecked)
{
bool bChanged = false;
if (m_bPartChecked != bPartChecked) {
m_bPartChecked = bPartChecked;
bChanged = true;
}
if (IsAutoSelectCheck()) {
//自动同步给PartSelected变量
if (m_bPartSelected != bPartChecked) {
m_bPartSelected = bPartChecked;
bChanged = true;
}
}
if (bChanged) {
this->Invalidate();
}
return bChanged;
}
template<typename InheritType>
bool CheckBoxTemplate<InheritType>::PrivateSetChecked(bool bChecked)
{
bool bChanged = false;
bool bCheckChanged = false;
if (m_bChecked != bChecked) {
m_bChecked = bChecked;
bChanged = true;
bCheckChanged = true;
}
if (!bChecked && m_bPartChecked) {
//非选择状态时,对部分选择标记复位
m_bPartChecked = false;
bChanged = true;
}
if (IsAutoSelectCheck()) {
//自动同步给Select变量
bChanged = PrivateSetSelected(m_bChecked);
}
if (bCheckChanged) {
OnPrivateSetChecked();
}
return bChanged;
}
template<typename InheritType>
bool CheckBoxTemplate<InheritType>::HasHotState()
{
if (BaseClass::HasHotState()) {
return true;
}
if ((m_pSelectedColorMap != nullptr) && m_pSelectedColorMap->HasHotColor()) {
return true;
}
if ((m_pSelectedTextColorMap != nullptr) && m_pSelectedTextColorMap->HasHotColor()) {
return true;
}
return false;
}
template<typename InheritType>
DString CheckBoxTemplate<InheritType>::GetBorderColor(ControlStateType stateType) const
{
if (this->IsSelected()) {
DString borderColor = BaseClass::GetBorderColor(kControlStatePushed);
if (!borderColor.empty()) {
return borderColor;
}
}
return BaseClass::GetBorderColor(stateType);
}
template<typename InheritType>
void CheckBoxTemplate<InheritType>::ClearStateImages()
{
if (m_pCheckBoxImageRect != nullptr) {
delete m_pCheckBoxImageRect;
m_pCheckBoxImageRect = nullptr;
}
BaseClass::ClearStateImages();
}
template<typename InheritType>
void CheckBoxTemplate<InheritType>::PaintStateColors(IRender* pRender)
{
if (!IsSelected() || !CanPaintSelectedColors()) {
BaseClass::PaintStateColors(pRender);
return;
}
if (m_pSelectedColorMap == nullptr) {
if (IsPaintNormalFirst()) {
this->PaintStateColor(pRender, this->GetState());
}
}
else {
if (IsPaintNormalFirst() && !m_pSelectedColorMap->HasStateColors()) {
this->PaintStateColor(pRender, this->GetState());
}
else {
m_pSelectedColorMap->PaintStateColor(pRender, this->GetRect(), this->GetState());
}
}
}
template<typename InheritType>
void CheckBoxTemplate<InheritType>::PaintStateImages(IRender* pRender)
{
bool bCheckMode = SupportCheckMode();
if (bCheckMode && (m_pCheckBoxImageRect == nullptr)) {
m_pCheckBoxImageRect = new UiRect;
}
bool isSelectNone = false;
if (bCheckMode) {
//如果SupportCheckMode()为true,则按IsChecked()判断是否显示选择状态的图片
if (!IsChecked()) {
isSelectNone = true;
}
}
else {
//如果SupportCheckMode()为false,则按IsSelected()判断是否显示选择状态的图片
if (!IsSelected()) {
isSelectNone = true;
}
}
if (isSelectNone) {
//未选择状态
this->PaintStateImage(pRender, kStateImageBk, this->GetState(), _T(""), m_pCheckBoxImageRect);
this->PaintStateImage(pRender, kStateImageFore, this->GetState(), _T(""), m_pCheckBoxImageRect);
return;
}
bool bPartSelected = bCheckMode ? this->IsPartChecked() : this->IsPartSelected();
if (bPartSelected) {
//部分选择状态
bool bPainted = false;
if (this->HasStateImage(kStateImagePartSelectedBk)) {
this->PaintStateImage(pRender, kStateImagePartSelectedBk, this->GetState(), _T(""), m_pCheckBoxImageRect);
bPainted = true;
}
if (this->HasStateImage(kStateImagePartSelectedFore)) {
this->PaintStateImage(pRender, kStateImagePartSelectedFore, this->GetState(), _T(""), m_pCheckBoxImageRect);
bPainted = true;
}
if (bPainted) {
//如果已经绘制了部分选择状态,返回
return;
}
}
//全部选择状态
if (IsPaintNormalFirst() && !this->HasStateImage(kStateImageSelectedBk)) {
this->PaintStateImage(pRender, kStateImageBk, this->GetState(), _T(""), m_pCheckBoxImageRect);
}
else {
this->PaintStateImage(pRender, kStateImageSelectedBk, this->GetState(), _T(""), m_pCheckBoxImageRect);
}
if (IsPaintNormalFirst() && !this->HasStateImage(kStateImageSelectedFore)) {
this->PaintStateImage(pRender, kStateImageFore, this->GetState(), _T(""), m_pCheckBoxImageRect);
}
else {
this->PaintStateImage(pRender, kStateImageSelectedFore, this->GetState(), _T(""), m_pCheckBoxImageRect);
}
}
template<typename InheritType>
void CheckBoxTemplate<InheritType>::PaintText(IRender* pRender)
{
if (!IsSelected()) {
BaseClass::PaintText(pRender);
return;
}
DString textValue = this->GetText();
if (textValue.empty() || (pRender == nullptr)) {
return;
}
UiRect rc = this->GetRect();
UiPadding rcPadding = this->GetControlPadding();
rc.Deflate(rcPadding);
rc.Deflate(this->GetTextPadding());
auto stateType = this->GetState();
DString clrColor = GetPaintSelectedStateTextColor(this->GetState(), stateType);
if (clrColor.empty()) {
clrColor = m_dwSelectedTextColor.empty() ? this->GetPaintStateTextColor(this->GetState(), stateType) : m_dwSelectedTextColor.c_str();
}
UiColor dwClrColor = this->GetUiColor(clrColor);
uint32_t uTextStyle = this->GetTextStyle();
if (this->IsSingleLine()) {
uTextStyle |= TEXT_SINGLELINE;
}
else {
uTextStyle &= ~TEXT_SINGLELINE;
}
this->SetTextStyle(uTextStyle, false);
DrawStringParam drawParam = this->GetDrawParam();//绘制参数
drawParam.textRect = rc;
if (this->IsAnimationPlayerPlaying(AnimationType::kAnimationHot)) {
if ((stateType == kControlStateNormal || stateType == kControlStateHot) &&
!GetSelectedStateTextColor(kControlStateHot).empty()) {
//先绘制默认的文本
const uint8_t nHotAlpha = this->GetHotAlpha();
bool bPainted = false;
DString clrStateColor = GetSelectedStateTextColor(kControlStateNormal);
if (!clrStateColor.empty()) {
drawParam.dwTextColor = this->GetUiColor(clrStateColor);
drawParam.uFade = 255 - nHotAlpha;
pRender->DrawString(textValue, drawParam);
bPainted = true;
}
//绘制Hot状态的文本(半透明)
DString textColor = GetSelectedStateTextColor(kControlStateHot);
if (!textColor.empty()) {
drawParam.dwTextColor = this->GetUiColor(textColor);
drawParam.uFade = nHotAlpha;
pRender->DrawString(textValue, drawParam);
bPainted = true;
}
if (bPainted) {
return;
}
}
}
drawParam.dwTextColor = dwClrColor;
drawParam.uFade = 255;
pRender->DrawString(textValue, drawParam);
}
template<typename InheritType>
DString CheckBoxTemplate<InheritType>::GetSelectedStateImage(ControlStateType stateType) const
{
return this->GetStateImage(kStateImageSelectedBk, stateType);
}
template<typename InheritType>
void CheckBoxTemplate<InheritType>::SetSelectedStateImage(ControlStateType stateType, const DString& strImage)
{
this->SetStateImage(kStateImageSelectedBk, stateType, strImage);
this->RelayoutOrRedraw();
}
template<typename InheritType>
DString CheckBoxTemplate<InheritType>::GetSelectedForeStateImage(ControlStateType stateType) const
{
return this->GetStateImage(kStateImageSelectedFore, stateType);
}
template<typename InheritType>
void CheckBoxTemplate<InheritType>::SetSelectedForeStateImage(ControlStateType stateType, const DString& strImage)
{
this->SetStateImage(kStateImageSelectedFore, stateType, strImage);
this->RelayoutOrRedraw();
}
template<typename InheritType>