@ -50,6 +50,63 @@ void Button::_set_internal_margin(Side p_side, float p_value) {
void Button : : _queue_update_size_cache ( ) {
}
void Button : : _set_h_separation_is_valid_when_no_text ( bool p_h_separation_is_valid_when_no_text ) {
h_separation_is_valid_when_no_text = p_h_separation_is_valid_when_no_text ;
}
Ref < StyleBox > Button : : _get_current_stylebox ( ) const {
Ref < StyleBox > stylebox = theme_cache . normal ;
const bool rtl = is_layout_rtl ( ) ;
switch ( get_draw_mode ( ) ) {
case DRAW_NORMAL : {
if ( rtl & & has_theme_stylebox ( SNAME ( " normal_mirrored " ) ) ) {
stylebox = theme_cache . normal_mirrored ;
} else {
stylebox = theme_cache . normal ;
}
} break ;
case DRAW_HOVER_PRESSED : {
// Edge case for CheckButton and CheckBox.
if ( has_theme_stylebox ( " hover_pressed " ) ) {
if ( rtl & & has_theme_stylebox ( SNAME ( " hover_pressed_mirrored " ) ) ) {
stylebox = theme_cache . hover_pressed_mirrored ;
} else {
stylebox = theme_cache . hover_pressed ;
}
break ;
}
}
[[fallthrough]] ;
case DRAW_PRESSED : {
if ( rtl & & has_theme_stylebox ( SNAME ( " pressed_mirrored " ) ) ) {
stylebox = theme_cache . pressed_mirrored ;
} else {
stylebox = theme_cache . pressed ;
}
} break ;
case DRAW_HOVER : {
if ( rtl & & has_theme_stylebox ( SNAME ( " hover_mirrored " ) ) ) {
stylebox = theme_cache . hover_mirrored ;
} else {
stylebox = theme_cache . hover ;
}
} break ;
case DRAW_DISABLED : {
if ( rtl & & has_theme_stylebox ( SNAME ( " disabled_mirrored " ) ) ) {
stylebox = theme_cache . disabled_mirrored ;
} else {
stylebox = theme_cache . disabled ;
}
} break ;
}
return stylebox ;
}
void Button : : _notification ( int p_what ) {
switch ( p_what ) {
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED : {
@ -72,287 +129,265 @@ void Button::_notification(int p_what) {
} break ;
case NOTIFICATION_DRAW : {
RID ci = get_canvas_item ( ) ;
Size2 size = get_size ( ) ;
Color color ;
Color color_icon ( 1 , 1 , 1 , 1 ) ;
const RID ci = get_canvas_item ( ) ;
const Size2 size = get_size ( ) ;
Ref < StyleBox > style = theme_cache . normal ;
bool rtl = is_layout_rtl ( ) ;
const bool is_clipped = clip_text | | overrun_behavior ! = TextServer : : OVERRUN_NO_TRIMMING ;
const Ref < StyleBox > style = _get_current_stylebox ( ) ;
{ // Draws the stylebox in the current state.
if ( ! flat ) {
style - > draw ( ci , Rect2 ( Point2 ( ) , size ) ) ;
}
switch ( get_draw_mode ( ) ) {
case DRAW_NORMAL : {
if ( rtl & & has_theme_stylebox ( SNAME ( " normal_mirrored " ) ) ) {
style = theme_cache . normal_mirrored ;
} else {
style = theme_cache . normal ;
if ( has_focus ( ) ) {
Ref < StyleBox > style2 = theme_cache . focus ;
style2 - > draw ( ci , Rect2 ( Point2 ( ) , size ) ) ;
}
}
Ref < Texture2D > _icon = icon ;
if ( _icon . is_null ( ) & & has_theme_icon ( SNAME ( " icon " ) ) ) {
_icon = theme_cache . icon ;
}
if ( xl_text . is_empty ( ) & & _icon . is_null ( ) ) {
break ;
}
const float style_margin_left = style - > get_margin ( SIDE_LEFT ) ;
const float style_margin_right = style - > get_margin ( SIDE_RIGHT ) ;
const float style_margin_top = style - > get_margin ( SIDE_TOP ) ;
const float style_margin_bottom = style - > get_margin ( SIDE_BOTTOM ) ;
Size2 drawable_size_remained = size ;
{ // The size after the stelybox is stripped.
drawable_size_remained . width - = style_margin_left + style_margin_right ;
drawable_size_remained . height - = style_margin_top + style_margin_bottom ;
}
const int h_separation = MAX ( 0 , theme_cache . h_separation ) ;
{ // The width reserved for internal element in derived classes (and h_separation if need).
float internal_margin = _internal_margin [ SIDE_LEFT ] + _internal_margin [ SIDE_RIGHT ] ;
if ( ! xl_text . is_empty ( ) | | h_separation_is_valid_when_no_text ) {
if ( _internal_margin [ SIDE_LEFT ] > 0.0f ) {
internal_margin + = h_separation ;
}
if ( ! flat ) {
style - > draw ( ci , Rect2 ( Point2 ( 0 , 0 ) , size ) ) ;
if ( _internal_margin [ SIDE_RIGHT ] > 0.0f ) {
internal_margin + = h_separation ;
}
}
drawable_size_remained . width - = internal_margin ; // The size after the internal element is stripped.
}
HorizontalAlignment icon_align_rtl_checked = horizontal_icon_alignment ;
HorizontalAlignment align_rtl_checked = alignment ;
// Swap icon and text alignment sides if right-to-left layout is set.
if ( is_layout_rtl ( ) ) {
if ( horizontal_icon_alignment = = HORIZONTAL_ALIGNMENT_RIGHT ) {
icon_align_rtl_checked = HORIZONTAL_ALIGNMENT_LEFT ;
} else if ( horizontal_icon_alignment = = HORIZONTAL_ALIGNMENT_LEFT ) {
icon_align_rtl_checked = HORIZONTAL_ALIGNMENT_RIGHT ;
}
if ( alignment = = HORIZONTAL_ALIGNMENT_RIGHT ) {
align_rtl_checked = HORIZONTAL_ALIGNMENT_LEFT ;
} else if ( alignment = = HORIZONTAL_ALIGNMENT_LEFT ) {
align_rtl_checked = HORIZONTAL_ALIGNMENT_RIGHT ;
}
}
Color font_color ;
Color icon_modulate_color ( 1 , 1 , 1 , 1 ) ;
// Get the font color and icon modulate color in the current state.
switch ( get_draw_mode ( ) ) {
case DRAW_NORMAL : {
// Focus colors only take precedence over normal state.
if ( has_focus ( ) ) {
color = theme_cache . font_focus_color ;
font_ color = theme_cache . font_focus_color ;
if ( has_theme_color ( SNAME ( " icon_focus_color " ) ) ) {
color_icon = theme_cache . icon_focus_color ;
icon_modulate_color = theme_cache . icon_focus_color ;
}
} else {
color = theme_cache . font_color ;
font_ color = theme_cache . font_color ;
if ( has_theme_color ( SNAME ( " icon_normal_color " ) ) ) {
color_icon = theme_cache . icon_normal_color ;
icon_modulate_color = theme_cache . icon_normal_color ;
}
}
} break ;
case DRAW_HOVER_PRESSED : {
// Edge case for CheckButton and CheckBox.
if ( has_theme_stylebox ( " hover_pressed " ) ) {
if ( rtl & & has_theme_stylebox ( SNAME ( " hover_pressed_mirrored " ) ) ) {
style = theme_cache . hover_pressed_mirrored ;
} else {
style = theme_cache . hover_pressed ;
}
if ( ! flat ) {
style - > draw ( ci , Rect2 ( Point2 ( 0 , 0 ) , size ) ) ;
}
if ( has_theme_color ( SNAME ( " font_hover_pressed_color " ) ) ) {
color = theme_cache . font_hover_pressed_color ;
font_color = theme_cache . font_hover_pressed_color ;
}
if ( has_theme_color ( SNAME ( " icon_hover_pressed_color " ) ) ) {
color_icon = theme_cache . icon_hover_pressed_color ;
icon_modulate_color = theme_cache . icon_hover_pressed_color ;
}
break ;
}
[[fallthrough]] ;
}
[[fallthrough]] ;
case DRAW_PRESSED : {
if ( rtl & & has_theme_stylebox ( SNAME ( " pressed_mirrored " ) ) ) {
style = theme_cache . pressed_mirrored ;
} else {
style = theme_cache . pressed ;
}
if ( ! flat ) {
style - > draw ( ci , Rect2 ( Point2 ( 0 , 0 ) , size ) ) ;
}
if ( has_theme_color ( SNAME ( " font_pressed_color " ) ) ) {
color = theme_cache . font_pressed_color ;
font_color = theme_cache . font_pressed_color ;
} else {
color = theme_cache . font_color ;
font_color = theme_cache . font_color ;
}
if ( has_theme_color ( SNAME ( " icon_pressed_color " ) ) ) {
color_icon = theme_cache . icon_pressed_color ;
icon_modulate_color = theme_cache . icon_pressed_color ;
}
} break ;
case DRAW_HOVER : {
if ( rtl & & has_theme_stylebox ( SNAME ( " hover_mirrored " ) ) ) {
style = theme_cache . hover_mirrored ;
} else {
style = theme_cache . hover ;
}
if ( ! flat ) {
style - > draw ( ci , Rect2 ( Point2 ( 0 , 0 ) , size ) ) ;
}
color = theme_cache . font_hover_color ;
font_color = theme_cache . font_hover_color ;
if ( has_theme_color ( SNAME ( " icon_hover_color " ) ) ) {
color_icon = theme_cache . icon_hover_color ;
icon_modulate_color = theme_cache . icon_hover_color ;
}
} break ;
case DRAW_DISABLED : {
if ( rtl & & has_theme_stylebox ( SNAME ( " disabled_mirrored " ) ) ) {
style = theme_cache . disabled_mirrored ;
} else {
style = theme_cache . disabled ;
}
if ( ! flat ) {
style - > draw ( ci , Rect2 ( Point2 ( 0 , 0 ) , size ) ) ;
}
color = theme_cache . font_disabled_color ;
font_color = theme_cache . font_disabled_color ;
if ( has_theme_color ( SNAME ( " icon_disabled_color " ) ) ) {
color_icon = theme_cache . icon_disabled_color ;
icon_modulate_color = theme_cache . icon_disabled_color ;
} else {
color_icon . a = 0.4 ;
icon_modulate_color . a = 0.4 ;
}
} break ;
}
if ( has_focus ( ) ) {
Ref < StyleBox > style2 = theme_cache . focus ;
style2 - > draw ( ci , Rect2 ( Point2 ( ) , size ) ) ;
}
Ref < Texture2D > _icon ;
if ( icon . is_null ( ) & & has_theme_icon ( SNAME ( " icon " ) ) ) {
_icon = theme_cache . icon ;
} else {
_icon = icon ;
}
Rect2 icon_region ;
HorizontalAlignment icon_align_rtl_checked = horizontal_icon_alignment ;
HorizontalAlignment align_rtl_checked = alignment ;
// Swap icon and text alignment sides if right-to-left layout is set.
if ( rtl ) {
if ( horizontal_icon_alignment = = HORIZONTAL_ALIGNMENT_RIGHT ) {
icon_align_rtl_checked = HORIZONTAL_ALIGNMENT_LEFT ;
} else if ( horizontal_icon_alignment = = HORIZONTAL_ALIGNMENT_LEFT ) {
icon_align_rtl_checked = HORIZONTAL_ALIGNMENT_RIGHT ;
}
if ( alignment = = HORIZONTAL_ALIGNMENT_RIGHT ) {
align_rtl_checked = HORIZONTAL_ALIGNMENT_LEFT ;
} else if ( alignment = = HORIZONTAL_ALIGNMENT_LEFT ) {
align_rtl_checked = HORIZONTAL_ALIGNMENT_RIGHT ;
}
}
if ( ! _icon . is_null ( ) ) {
int valign = size . height - style - > get_minimum_size ( ) . y ;
const bool is_clipped = clip_text | | overrun_behavior ! = TextServer : : OVERRUN_NO_TRIMMING ;
const Size2 custom_element_size = drawable_size_remained ;
// Draw the icon.
if ( _icon . is_valid ( ) ) {
Size2 icon_size ;
{ // Calculate the drawing size of the icon.
icon_size = _icon - > get_size ( ) ;
if ( expand_icon ) {
const Size2 text_buf_size = text_buf - > get_size ( ) ;
Size2 _size = custom_element_size ;
if ( ! is_clipped & & icon_align_rtl_checked ! = HORIZONTAL_ALIGNMENT_CENTER & & text_buf_size . width > 0.0f ) {
// If there is not enough space for icon and h_separation, h_separation will occupy the space first,
// so the icon's width may be negative. Keep it negative to make it easier to calculate the space
// reserved for text later.
_size . width - = text_buf_size . width + h_separation ;
}
if ( vertical_icon_alignment ! = VERTICAL_ALIGNMENT_CENTER ) {
_size . height - = text_buf_size . height ;
}
int voffset = 0 ;
Size2 icon_size = _icon - > get_size ( ) ;
float icon_width = icon_size . width * _size . height / icon_size . height ;
float icon_height = _size . height ;
// Fix vertical size.
if ( vertical_icon_alignment ! = VERTICAL_ALIGNMENT_CENTER ) {
valign - = text_buf - > get_size ( ) . height ;
}
if ( icon_width > _size . width ) {
icon_width = _size . width ;
icon_height = icon_size . height * icon_width / icon_size . width ;
}
float icon_ofs_region = 0.0 ;
Point2 style_offset ;
if ( icon_align_rtl_checked = = HORIZONTAL_ALIGNMENT_LEFT ) {
style_offset . x = style - > get_margin ( SIDE_LEFT ) ;
if ( _internal_margin [ SIDE_LEFT ] > 0 ) {
icon_ofs_region = _internal_margin [ SIDE_LEFT ] + theme_cache . h_separation ;
}
} else if ( icon_align_rtl_checked = = HORIZONTAL_ALIGNMENT_CENTER ) {
style_offset . x = 0.0 ;
} else if ( icon_align_rtl_checked = = HORIZONTAL_ALIGNMENT_RIGHT ) {
style_offset . x = - style - > get_margin ( SIDE_RIGHT ) ;
if ( _internal_margin [ SIDE_RIGHT ] > 0 ) {
icon_ofs_region = - _internal_margin [ SIDE_RIGHT ] - theme_cache . h_separation ;
icon_size = Size2 ( icon_width , icon_height ) ;
}
icon_size = _fit_icon_size ( icon_size ) ;
}
style_offset . y = style - > get_margin ( SIDE_TOP ) ;
if ( expand_icon ) {
Size2 _size = get_size ( ) - style - > get_offset ( ) * 2 ;
int icon_text_separation = text . is_empty ( ) ? 0 : theme_cache . h_separation ;
_size . width - = icon_text_separation + icon_ofs_region ;
if ( ! is_clipped & & icon_align_rtl_checked ! = HORIZONTAL_ALIGNMENT_CENTER ) {
_size . width - = text_buf - > get_size ( ) . width ;
}
if ( vertical_icon_alignment ! = VERTICAL_ALIGNMENT_CENTER ) {
_size . height - = text_buf - > get_size ( ) . height ;
}
float icon_width = _icon - > get_width ( ) * _size . height / _icon - > get_height ( ) ;
float icon_height = _size . height ;
if ( icon_width > _size . width ) {
icon_width = _size . width ;
icon_height = _icon - > get_height ( ) * icon_width / _icon - > get_width ( ) ;
if ( icon_size . width > 0.0f ) {
// Calculate the drawing position of the icon.
Point2 icon_ofs ;
switch ( icon_align_rtl_checked ) {
case HORIZONTAL_ALIGNMENT_CENTER : {
icon_ofs . x = ( custom_element_size . width - icon_size . width ) / 2.0f ;
}
[[fallthrough]] ;
case HORIZONTAL_ALIGNMENT_FILL :
case HORIZONTAL_ALIGNMENT_LEFT : {
icon_ofs . x + = style_margin_left ;
icon_ofs . x + = _internal_margin [ SIDE_LEFT ] ;
} break ;
case HORIZONTAL_ALIGNMENT_RIGHT : {
icon_ofs . x = size . x - style_margin_right ;
icon_ofs . x - = _internal_margin [ SIDE_RIGHT ] ;
icon_ofs . x - = icon_size . width ;
} break ;
}
icon_size = Size2 ( icon_width , icon_height ) ;
}
icon_size = _fit_icon_size ( icon_size ) ;
switch ( vertical_icon_alignment ) {
case VERTICAL_ALIGNMENT_CENTER : {
icon_ofs . y = ( custom_element_size . height - icon_size . height ) / 2.0f ;
}
[[fallthrough]] ;
case VERTICAL_ALIGNMENT_FILL :
case VERTICAL_ALIGNMENT_TOP : {
icon_ofs . y + = style_margin_top ;
} break ;
case VERTICAL_ALIGNMENT_BOTTOM : {
icon_ofs . y = size . y - style_margin_bottom - icon_size . height ;
} break ;
}
if ( vertical_icon_alignment = = VERTICAL_ALIGNMENT_TOP ) {
voffset = - ( valign - icon_size . y ) / 2 ;
}
if ( vertical_icon_alignment = = VERTICAL_ALIGNMENT_BOTTOM ) {
voffset = ( valign - icon_size . y ) / 2 + text_buf - > get_size ( ) . y ;
Rect2 icon_region = Rect2 ( icon_ofs , icon_size ) ;
draw_texture_rect ( _icon , icon_region , false , icon_modulate_color ) ;
}
if ( icon_align_rtl_checked = = HORIZONTAL_ALIGNMENT_LEFT ) {
icon_region = Rect2 ( style_offset + Point2 ( icon_ofs_region , voffset + Math : : floor ( ( valign - icon_size . y ) * 0.5 ) ) , icon_size ) ;
} else if ( icon_align_rtl_checked = = HORIZONTAL_ALIGNMENT_CENTER ) {
icon_region = Rect2 ( style_offset + Point2 ( icon_ofs_region + Math : : floor ( ( size . x - icon_size . x ) * 0.5 ) , voffset + Math : : floor ( ( valign - icon_size . y ) * 0.5 ) ) , icon_size ) ;
} else {
icon_region = Rect2 ( style_offset + Point2 ( icon_ofs_region + size . x - icon_size . x , voffset + Math : : floor ( ( valign - icon_size . y ) * 0.5 ) ) , icon_size ) ;
}
if ( ! xl_text . is_empty ( ) ) {
// Update the size after the icon is stripped. Stripping only when the icon alignments are not center.
if ( icon_align_rtl_checked ! = HORIZONTAL_ALIGNMENT_CENTER ) {
// Subtract the space's width occupied by icon and h_separation together.
drawable_size_remained . width - = icon_size . width + h_separation ;
}
if ( icon_region . size . width > 0 ) {
Rect2 icon_region_rounded = Rect2 ( icon_region . position . round ( ) , icon_region . size . round ( ) ) ;
draw_texture_rect ( _icon , icon_region_rounded , false , color_icon ) ;
if ( vertical_icon_alignment ! = VERTICAL_ALIGNMENT_CENTER ) {
drawable_size_remained . height - = icon_size . height ;
}
}
}
Point2 icon_ofs = ! _icon . is_null ( ) ? Point2 ( icon_region . size . width + theme_cache . h_separation , 0 ) : Point2 ( ) ;
if ( align_rtl_checked = = HORIZONTAL_ALIGNMENT_CENTER & & icon_align_rtl_checked = = HORIZONTAL_ALIGNMENT_CENTER ) {
icon_ofs . x = 0.0 ;
}
int text_clip = size . width - style - > get_minimum_size ( ) . width - icon_ofs . width ;
if ( _internal_margin [ SIDE_LEFT ] > 0 ) {
text_clip - = _internal_margin [ SIDE_LEFT ] + theme_cache . h_separation ;
}
if ( _internal_margin [ SIDE_RIGHT ] > 0 ) {
text_clip - = _internal_margin [ SIDE_RIGHT ] + theme_cache . h_separation ;
}
text_buf - > set_width ( is_clipped ? text_clip : - 1 ) ;
// Draw the text.
if ( ! xl_text . is_empty ( ) ) {
text_buf - > set_alignment ( align_rtl_checked ) ;
int text_width = MAX ( 1 , is_clipped ? MIN ( text_clip , text_buf - > get_size ( ) . x ) : text_buf - > get_size ( ) . x ) ;
float text_buf_width = MAX ( 1.0f , drawable_size_remained . width ) ; // The space's width filled by the text_buf.
text_buf - > set_width ( text_buf_width ) ;
Point2 text_ofs = ( size - style - > get_minimum_size ( ) - icon_ofs - text_buf - > get_size ( ) - Point2 ( _internal_margin [ SIDE_RIGHT ] - _internal_margin [ SIDE_LEFT ] , 0 ) ) / 2.0 ;
if ( vertical_icon_alignment = = VERTICAL_ALIGNMENT_TOP ) {
text_ofs . y + = icon_region . size . height / 2 ;
}
if ( vertical_icon_alignment = = VERTICAL_ALIGNMENT_BOTTOM ) {
text_ofs . y - = icon_region . size . height / 2 ;
}
Point2 text_ofs ;
text_buf - > set_alignment ( align_rtl_checked ) ;
text_buf - > set_width ( text_width ) ;
switch ( align_rtl_checked ) {
case HORIZONTAL_ALIGNMENT_FILL :
case HORIZONTAL_ALIGNMENT_LEFT : {
if ( icon_align_rtl_checked ! = HORIZONTAL_ALIGNMENT_LEFT ) {
icon_ofs . x = 0.0 ;
}
if ( _internal_margin [ SIDE_LEFT ] > 0 ) {
text_ofs . x = style - > get_margin ( SIDE_LEFT ) + icon_ofs . x + _internal_margin [ SIDE_LEFT ] + theme_cache . h_separation ;
} else {
text_ofs . x = style - > get_margin ( SIDE_LEFT ) + icon_ofs . x ;
}
text_ofs . y + = style - > get_offset ( ) . y ;
} break ;
case HORIZONTAL_ALIGNMENT_CENTER : {
if ( text_ofs . x < 0 ) {
text_ofs . x = 0 ;
}
if ( icon_align_rtl_checked = = HORIZONTAL_ALIGNMENT_LEFT ) {
text_ofs + = icon_ofs ;
}
text_ofs + = style - > get_offset ( ) ;
} break ;
case HORIZONTAL_ALIGNMENT_RIGHT : {
if ( _internal_margin [ SIDE_RIGHT ] > 0 ) {
text_ofs . x = size . x - style - > get_margin ( SIDE_RIGHT ) - text_width - _internal_margin [ SIDE_RIGHT ] - theme_cache . h_separation ;
} else {
text_ofs . x = size . x - style - > get_margin ( SIDE_RIGHT ) - text_width ;
}
text_ofs . y + = style - > get_offset ( ) . y ;
if ( icon_align_rtl_checked = = HORIZONTAL_ALIGNMENT_RIGHT ) {
text_ofs . x - = icon_ofs . x ;
switch ( align_rtl_checked ) {
case HORIZONTAL_ALIGNMENT_CENTER : {
text_ofs . x = ( drawable_size_remained . width - text_buf_width ) / 2.0f ;
}
} break ;
}
[[fallthrough]] ;
case HORIZONTAL_ALIGNMENT_FILL :
case HORIZONTAL_ALIGNMENT_LEFT :
case HORIZONTAL_ALIGNMENT_RIGHT : {
text_ofs . x + = style_margin_left ;
text_ofs . x + = _internal_margin [ SIDE_LEFT ] ;
if ( icon_align_rtl_checked = = HORIZONTAL_ALIGNMENT_LEFT ) {
// Offset by the space's width that occupied by icon and h_separation together.
text_ofs . x + = custom_element_size . width - drawable_size_remained . width ;
}
} break ;
}
text_ofs . y = ( drawable_size_remained . height - text_buf - > get_size ( ) . height ) / 2.0f + style_margin_top ;
if ( vertical_icon_alignment = = VERTICAL_ALIGNMENT_TOP ) {
text_ofs . y + = custom_element_size . height - drawable_size_remained . height ; // Offset by the icon's height.
}
Color font_outline_color = theme_cache . font_outline_color ;
int outline_size = theme_cache . outline_size ;
if ( outline_size > 0 & & font_outline_color . a > 0 ) {
text_buf - > draw_outline ( ci , text_ofs , outline_size , font_outline_color ) ;
Color font_outline_color = theme_cache . font_outline_color ;
int outline_size = theme_cache . outline_size ;
if ( outline_size > 0 & & font_outline_color . a > 0.0f ) {
text_buf - > draw_outline ( ci , text_ofs , outline_size , font_outline_color ) ;
}
text_buf - > draw ( ci , text_ofs , font_color ) ;
}
text_buf - > draw ( ci , text_ofs , color ) ;
} break ;
}
}
@ -411,7 +446,7 @@ Size2 Button::get_minimum_size_for_text_and_icon(const String &p_text, Ref<Textu
}
}
return theme_cache . normal - > get_minimum_size ( ) + minsize ;
return _get_current_stylebox ( ) - > get_minimum_size ( ) + minsize ;
}
void Button : : _shape ( Ref < TextParagraph > p_paragraph , String p_text ) {
@ -443,9 +478,13 @@ void Button::_shape(Ref<TextParagraph> p_paragraph, String p_text) {
void Button : : set_text_overrun_behavior ( TextServer : : OverrunBehavior p_behavior ) {
if ( overrun_behavior ! = p_behavior ) {
bool need_update_cache = overrun_behavior = = TextServer : : OVERRUN_NO_TRIMMING | | p_behavior = = TextServer : : OVERRUN_NO_TRIMMING ;
overrun_behavior = p_behavior ;
_shape ( ) ;
if ( need_update_cache ) {
_queue_update_size_cache ( ) ;
}
queue_redraw ( ) ;
update_minimum_size ( ) ;
}
@ -550,6 +589,8 @@ bool Button::is_flat() const {
void Button : : set_clip_text ( bool p_enabled ) {
if ( clip_text ! = p_enabled ) {
clip_text = p_enabled ;
_queue_update_size_cache ( ) ;
queue_redraw ( ) ;
update_minimum_size ( ) ;
}
@ -571,13 +612,25 @@ HorizontalAlignment Button::get_text_alignment() const {
}
void Button : : set_icon_alignment ( HorizontalAlignment p_alignment ) {
if ( horizontal_icon_alignment = = p_alignment ) {
return ;
}
horizontal_icon_alignment = p_alignment ;
update_minimum_size ( ) ;
queue_redraw ( ) ;
}
void Button : : set_vertical_icon_alignment ( VerticalAlignment p_alignment ) {
if ( vertical_icon_alignment = = p_alignment ) {
return ;
}
bool need_update_cache = vertical_icon_alignment = = VERTICAL_ALIGNMENT_CENTER | | p_alignment = = VERTICAL_ALIGNMENT_CENTER ;
vertical_icon_alignment = p_alignment ;
if ( need_update_cache ) {
_queue_update_size_cache ( ) ;
}
update_minimum_size ( ) ;
queue_redraw ( ) ;
}