Skip to content

Commit f53c758

Browse files
committed
CheckButton checked/unchecked icon can be on both sides
If `inverted` is set to true on `CheckButton` the checked/unchecked icon will be drawn in the right for for right-to-left layouts or in the left for left-to-right layouts.
1 parent 2303ce8 commit f53c758

File tree

3 files changed

+54
-13
lines changed

3 files changed

+54
-13
lines changed

doc/classes/CheckButton.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,27 @@
99
</description>
1010
<tutorials>
1111
</tutorials>
12+
<methods>
13+
<method name="set_invert">
14+
<return type="bool" />
15+
<param index="0" name="invert" type="bool" />
16+
<description>
17+
If [code]true[/code] [theme_item checked]/[theme_item unchecked] will be drawn in the right for for right-to-left layouts or in the left for left-to-right layouts.
18+
</description>
19+
</method>
20+
<method name="is_invert" qualifiers="const">
21+
<return type="bool" />
22+
<description>
23+
Returns [code]true[/code] when [theme_item checked]/[theme_item unchecked] is drawn in the right for for right-to-left layouts or in the left for left-to-right layouts.
24+
</description>
25+
</method>
26+
</methods>
1227
<members>
1328
<member name="alignment" type="int" setter="set_text_alignment" getter="get_text_alignment" overrides="Button" enum="HorizontalAlignment" default="0" />
1429
<member name="toggle_mode" type="bool" setter="set_toggle_mode" getter="is_toggle_mode" overrides="BaseButton" default="true" />
30+
<member name="invert" type="bool" setter="set_invert" getter="is_invert" default="false">
31+
If [code]true[/code] [theme_item checked]/[theme_item unchecked] will be drawn in the right for for right-to-left layouts or in the left for left-to-right layouts.
32+
</member>
1533
</members>
1634
<theme_items>
1735
<theme_item name="button_checked_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">

scene/gui/check_button.cpp

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,20 @@ Size2 CheckButton::get_minimum_size() const {
8383
return minsize;
8484
}
8585

86+
void CheckButton::_set_left_and_right_internal_margins() {
87+
bool rtl = is_layout_rtl();
88+
Side icon_side = (rtl ^ invert) ? SIDE_LEFT : SIDE_RIGHT;
89+
Side text_side = (rtl ^ invert) ? SIDE_RIGHT : SIDE_LEFT;
90+
_set_internal_margin(icon_side, get_icon_size().width);
91+
_set_internal_margin(text_side, 0.f);
92+
}
93+
8694
void CheckButton::_notification(int p_what) {
8795
switch (p_what) {
8896
case NOTIFICATION_THEME_CHANGED:
8997
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
9098
case NOTIFICATION_TRANSLATION_CHANGED: {
91-
if (is_layout_rtl()) {
92-
_set_internal_margin(SIDE_LEFT, get_icon_size().width);
93-
_set_internal_margin(SIDE_RIGHT, 0.f);
94-
} else {
95-
_set_internal_margin(SIDE_LEFT, 0.f);
96-
_set_internal_margin(SIDE_RIGHT, get_icon_size().width);
97-
}
99+
_set_left_and_right_internal_margins();
98100
} break;
99101

100102
case NOTIFICATION_DRAW: {
@@ -125,7 +127,7 @@ void CheckButton::_notification(int p_what) {
125127
Vector2 ofs;
126128
Size2 tex_size = get_icon_size();
127129

128-
if (rtl) {
130+
if (rtl ^ invert) {
129131
ofs.x = theme_cache.normal_style->get_margin(SIDE_LEFT);
130132
} else {
131133
ofs.x = get_size().width - (tex_size.width + theme_cache.normal_style->get_margin(SIDE_RIGHT));
@@ -142,6 +144,10 @@ void CheckButton::_notification(int p_what) {
142144
}
143145

144146
void CheckButton::_bind_methods() {
147+
ClassDB::bind_method(D_METHOD("set_invert", "invert"), &CheckButton::set_invert);
148+
ClassDB::bind_method(D_METHOD("is_invert"), &CheckButton::is_invert);
149+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "invert"), "set_invert", "is_invert");
150+
145151
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, CheckButton, h_separation);
146152
BIND_THEME_ITEM(Theme::DATA_TYPE_CONSTANT, CheckButton, check_v_offset);
147153
BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_STYLEBOX, CheckButton, normal_style, "normal");
@@ -159,17 +165,27 @@ void CheckButton::_bind_methods() {
159165
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, CheckButton, button_unchecked_color);
160166
}
161167

168+
void CheckButton::set_invert(bool p_invert) {
169+
if (p_invert == invert) {
170+
return;
171+
}
172+
invert = p_invert;
173+
_set_left_and_right_internal_margins();
174+
queue_redraw();
175+
}
176+
177+
bool CheckButton::is_invert() const {
178+
return invert;
179+
}
180+
162181
CheckButton::CheckButton(const String &p_text) :
163182
Button(p_text) {
164183
set_toggle_mode(true);
165184

166185
set_text_alignment(HORIZONTAL_ALIGNMENT_LEFT);
167186

168-
if (is_layout_rtl()) {
169-
_set_internal_margin(SIDE_LEFT, get_icon_size().width);
170-
} else {
171-
_set_internal_margin(SIDE_RIGHT, get_icon_size().width);
172-
}
187+
Side icon_side = (is_layout_rtl() ^ invert) ? SIDE_LEFT : SIDE_RIGHT;
188+
_set_internal_margin(icon_side, get_icon_size().width);
173189
}
174190

175191
CheckButton::~CheckButton() {

scene/gui/check_button.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ class CheckButton : public Button {
5353
Color button_unchecked_color;
5454
} theme_cache;
5555

56+
bool invert = false;
57+
58+
void _set_left_and_right_internal_margins();
59+
5660
protected:
5761
Size2 get_icon_size() const;
5862
virtual Size2 get_minimum_size() const override;
@@ -61,6 +65,9 @@ class CheckButton : public Button {
6165
static void _bind_methods();
6266

6367
public:
68+
void set_invert(bool p_invert);
69+
bool is_invert() const;
70+
6471
CheckButton(const String &p_text = String());
6572
~CheckButton();
6673
};

0 commit comments

Comments
 (0)