2014-02-10 02:10:30 +01:00
/*************************************************************************/
/* progress_bar.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2014-02-10 02:10:30 +01:00
/*************************************************************************/
2022-01-03 21:27:34 +01:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2014-02-10 02:10:30 +01:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
2018-01-05 00:50:27 +01:00
2014-04-29 02:56:43 +02:00
# include "progress_bar.h"
2022-02-15 18:06:48 +01:00
2020-09-03 13:22:16 +02:00
# include "scene/resources/text_line.h"
2014-04-29 02:56:43 +02:00
Size2 ProgressBar : : get_minimum_size ( ) const {
2021-07-17 23:22:52 +02:00
Ref < StyleBox > bg = get_theme_stylebox ( SNAME ( " bg " ) ) ;
Ref < StyleBox > fg = get_theme_stylebox ( SNAME ( " fg " ) ) ;
Ref < Font > font = get_theme_font ( SNAME ( " font " ) ) ;
int font_size = get_theme_font_size ( SNAME ( " font_size " ) ) ;
2014-04-29 02:56:43 +02:00
2018-03-28 19:52:55 +02:00
Size2 minimum_size = bg - > get_minimum_size ( ) ;
minimum_size . height = MAX ( minimum_size . height , fg - > get_minimum_size ( ) . height ) ;
minimum_size . width = MAX ( minimum_size . width , fg - > get_minimum_size ( ) . width ) ;
2019-02-27 14:56:49 +01:00
if ( percent_visible ) {
2020-09-03 13:22:16 +02:00
String txt = " 100% " ;
TextLine tl = TextLine ( txt , font , font_size ) ;
minimum_size . height = MAX ( minimum_size . height , bg - > get_minimum_size ( ) . height + tl . get_size ( ) . y ) ;
2019-02-27 14:56:49 +01:00
} else { // this is needed, else the progressbar will collapse
minimum_size . width = MAX ( minimum_size . width , 1 ) ;
minimum_size . height = MAX ( minimum_size . height , 1 ) ;
}
2018-03-28 19:52:55 +02:00
return minimum_size ;
2014-04-29 02:56:43 +02:00
}
void ProgressBar : : _notification ( int p_what ) {
2022-02-15 18:06:48 +01:00
switch ( p_what ) {
case NOTIFICATION_DRAW : {
Ref < StyleBox > bg = get_theme_stylebox ( SNAME ( " bg " ) ) ;
Ref < StyleBox > fg = get_theme_stylebox ( SNAME ( " fg " ) ) ;
Ref < Font > font = get_theme_font ( SNAME ( " font " ) ) ;
int font_size = get_theme_font_size ( SNAME ( " font_size " ) ) ;
Color font_color = get_theme_color ( SNAME ( " font_color " ) ) ;
2014-04-29 02:56:43 +02:00
2022-02-15 18:06:48 +01:00
draw_style_box ( bg , Rect2 ( Point2 ( ) , get_size ( ) ) ) ;
2021-02-19 07:02:59 +01:00
2022-02-15 18:06:48 +01:00
float r = get_as_ratio ( ) ;
2021-02-19 07:02:59 +01:00
switch ( mode ) {
case FILL_BEGIN_TO_END :
case FILL_END_TO_BEGIN : {
int mp = fg - > get_minimum_size ( ) . width ;
int p = round ( r * ( get_size ( ) . width - mp ) ) ;
// We want FILL_BEGIN_TO_END to map to right to left when UI layout is RTL,
// and left to right otherwise. And likewise for FILL_END_TO_BEGIN.
bool right_to_left = is_layout_rtl ( ) ? ( mode = = FILL_BEGIN_TO_END ) : ( mode = = FILL_END_TO_BEGIN ) ;
if ( p > 0 ) {
if ( right_to_left ) {
int p_remaining = round ( ( 1.0 - r ) * ( get_size ( ) . width - mp ) ) ;
draw_style_box ( fg , Rect2 ( Point2 ( p_remaining , 0 ) , Size2 ( p + fg - > get_minimum_size ( ) . width , get_size ( ) . height ) ) ) ;
} else {
draw_style_box ( fg , Rect2 ( Point2 ( 0 , 0 ) , Size2 ( p + fg - > get_minimum_size ( ) . width , get_size ( ) . height ) ) ) ;
}
}
} break ;
case FILL_TOP_TO_BOTTOM :
case FILL_BOTTOM_TO_TOP : {
int mp = fg - > get_minimum_size ( ) . height ;
int p = round ( r * ( get_size ( ) . height - mp ) ) ;
if ( p > 0 ) {
if ( mode = = FILL_TOP_TO_BOTTOM ) {
draw_style_box ( fg , Rect2 ( Point2 ( 0 , 0 ) , Size2 ( get_size ( ) . width , p + fg - > get_minimum_size ( ) . height ) ) ) ;
} else {
int p_remaining = round ( ( 1.0 - r ) * ( get_size ( ) . height - mp ) ) ;
draw_style_box ( fg , Rect2 ( Point2 ( 0 , p_remaining ) , Size2 ( get_size ( ) . width , p + fg - > get_minimum_size ( ) . height ) ) ) ;
}
}
} break ;
case FILL_MODE_MAX :
break ;
2020-09-03 13:22:16 +02:00
}
2014-04-29 02:56:43 +02:00
2022-02-15 18:06:48 +01:00
if ( percent_visible ) {
String txt = TS - > format_number ( itos ( int ( get_as_ratio ( ) * 100 ) ) ) + TS - > percent_sign ( ) ;
TextLine tl = TextLine ( txt , font , font_size ) ;
Vector2 text_pos = ( Point2 ( get_size ( ) . width - tl . get_size ( ) . x , get_size ( ) . height - tl . get_size ( ) . y ) / 2 ) . round ( ) ;
Color font_outline_color = get_theme_color ( SNAME ( " font_outline_color " ) ) ;
int outline_size = get_theme_constant ( SNAME ( " outline_size " ) ) ;
if ( outline_size > 0 & & font_outline_color . a > 0 ) {
tl . draw_outline ( get_canvas_item ( ) , text_pos , outline_size , font_outline_color ) ;
}
tl . draw ( get_canvas_item ( ) , text_pos , font_color ) ;
2020-12-25 22:45:28 +01:00
}
2022-02-15 18:06:48 +01:00
} break ;
2014-04-29 02:56:43 +02:00
}
}
2021-02-19 07:02:59 +01:00
void ProgressBar : : set_fill_mode ( int p_fill ) {
ERR_FAIL_INDEX ( p_fill , FILL_MODE_MAX ) ;
mode = ( FillMode ) p_fill ;
update ( ) ;
}
int ProgressBar : : get_fill_mode ( ) {
return mode ;
}
2014-04-29 02:56:43 +02:00
void ProgressBar : : set_percent_visible ( bool p_visible ) {
2017-03-05 16:44:50 +01:00
percent_visible = p_visible ;
2014-04-29 02:56:43 +02:00
update ( ) ;
}
2017-03-05 16:44:50 +01:00
bool ProgressBar : : is_percent_visible ( ) const {
2014-04-29 02:56:43 +02:00
return percent_visible ;
}
void ProgressBar : : _bind_methods ( ) {
2021-02-19 07:02:59 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_fill_mode " , " mode " ) , & ProgressBar : : set_fill_mode ) ;
ClassDB : : bind_method ( D_METHOD ( " get_fill_mode " ) , & ProgressBar : : get_fill_mode ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_percent_visible " , " visible " ) , & ProgressBar : : set_percent_visible ) ;
ClassDB : : bind_method ( D_METHOD ( " is_percent_visible " ) , & ProgressBar : : is_percent_visible ) ;
2022-03-21 23:21:56 +01:00
2021-02-19 07:02:59 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " fill_mode " , PROPERTY_HINT_ENUM , " Begin to End,End to Begin,Top to Bottom,Bottom to Top " ) , " set_fill_mode " , " get_fill_mode " ) ;
2017-03-05 16:44:50 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " percent_visible " ) , " set_percent_visible " , " is_percent_visible " ) ;
2021-02-19 07:02:59 +01:00
BIND_ENUM_CONSTANT ( FILL_BEGIN_TO_END ) ;
BIND_ENUM_CONSTANT ( FILL_END_TO_BEGIN ) ;
BIND_ENUM_CONSTANT ( FILL_TOP_TO_BOTTOM ) ;
BIND_ENUM_CONSTANT ( FILL_BOTTOM_TO_TOP ) ;
2014-04-29 02:56:43 +02:00
}
ProgressBar : : ProgressBar ( ) {
set_v_size_flags ( 0 ) ;
2019-01-24 12:58:58 +01:00
set_step ( 0.01 ) ;
2014-04-29 02:56:43 +02:00
}