diff --git a/src/gui/widgets/canvas.cpp b/src/gui/widgets/canvas.cpp index 3530fb1b1af..a97ce6784ee 100644 --- a/src/gui/widgets/canvas.cpp +++ b/src/gui/widgets/canvas.cpp @@ -251,15 +251,26 @@ tline::tline(const config& cfg) : * * scrollbar_mode How to show the scrollbar of a widget. * Possible values: - * @* always The scrollbar is always shown, - * regardless whether it's required or not. - * @* never The scrollbar is never shown, - * even not when needed. (Note when setting - * this mode dialogs might not properly fit - * anymore). - * @* auto Shows the scrollbar when + * @* always The scrollbar is always + * shown, regardless whether it's required + * or not. + * @* never The scrollbar is never + * shown, even not when needed. (Note when + * setting this mode dialogs might + * not properly fit anymore). + * @* auto Shows the scrollbar when * needed. The widget will reserve space for * the scrollbar, but only show when needed. + * @* initial_auto Like auto, but when the + * scrollbar is not needed the space is not + * reserved. + * @-Use auto when the list can be changed + * dynamically eg the game list in the + * lobby. For optimization you can also + * use auto when you really expect a + * scrollbar, but don't want it to be shown + * when not needed eg the language list + * will need a scrollbar on most screens. * @end_table * * == Section types == diff --git a/src/gui/widgets/scrollbar_container.cpp b/src/gui/widgets/scrollbar_container.cpp index 36a07c54ccd..0116fba0385 100644 --- a/src/gui/widgets/scrollbar_container.cpp +++ b/src/gui/widgets/scrollbar_container.cpp @@ -84,10 +84,10 @@ void callback_horizontal_scrollbar(twidget* caller) tscrollbar_container::tscrollbar_container(const unsigned canvas_count) : tcontainer_(canvas_count) , state_(ENABLED) - , vertical_scrollbar_mode_(SHOW_WHEN_NEEDED) - , horizontal_scrollbar_mode_(SHOW_WHEN_NEEDED) - , initial_vertical_scrollbar_mode_(SHOW_WHEN_NEEDED) - , initial_horizontal_scrollbar_mode_(SHOW_WHEN_NEEDED) + , vertical_scrollbar_mode_(auto_visible) + , horizontal_scrollbar_mode_(auto_visible) + , initial_vertical_scrollbar_mode_(auto_visible) + , initial_horizontal_scrollbar_mode_(auto_visible) , vertical_scrollbar_grid_(NULL) , horizontal_scrollbar_grid_(NULL) , vertical_scrollbar_(NULL) @@ -123,15 +123,15 @@ void tscrollbar_container::layout_init2(const bool full_initialization) * When the scrollbars should be shown when needed, assume they're not * needed and unhide them when needed. */ - if(initial_vertical_scrollbar_mode_ == SHOW_WHEN_NEEDED) { - vertical_scrollbar_mode_ = HIDE; + if(initial_vertical_scrollbar_mode_ == auto_visible) { + vertical_scrollbar_mode_ = always_invisible; } else { vertical_scrollbar_mode_ = initial_vertical_scrollbar_mode_; } show_vertical_scrollbar(); - if(initial_vertical_scrollbar_mode_ == SHOW_WHEN_NEEDED) { - horizontal_scrollbar_mode_ = HIDE; + if(initial_vertical_scrollbar_mode_ == auto_visible) { + horizontal_scrollbar_mode_ = always_invisible; } else { horizontal_scrollbar_mode_ = initial_horizontal_scrollbar_mode_; } @@ -150,17 +150,21 @@ void tscrollbar_container::NEW_layout_init(const bool full_initialization) if(full_initialization) { - if(initial_vertical_scrollbar_mode_ == HIDE) { - vertical_scrollbar_mode_ = HIDE; + + if(initial_vertical_scrollbar_mode_ == always_visible + || initial_vertical_scrollbar_mode_ == auto_visible) { + + vertical_scrollbar_mode_ = always_visible; } else { - vertical_scrollbar_mode_ = SHOW; + vertical_scrollbar_mode_ = always_invisible; } show_vertical_scrollbar(); - if(initial_vertical_scrollbar_mode_ == HIDE) { - horizontal_scrollbar_mode_ = HIDE; + if(initial_vertical_scrollbar_mode_ == always_visible + || initial_vertical_scrollbar_mode_ == auto_visible) { + horizontal_scrollbar_mode_ = always_visible; } else { - horizontal_scrollbar_mode_ = SHOW; + horizontal_scrollbar_mode_ = always_invisible; } show_horizontal_scrollbar(); } @@ -172,7 +176,7 @@ void tscrollbar_container::NEW_layout_init(const bool full_initialization) void tscrollbar_container::NEW_request_reduce_height( const unsigned maximum_height) { - if(initial_horizontal_scrollbar_mode_ == HIDE) { + if(initial_horizontal_scrollbar_mode_ == always_invisible) { return; } @@ -183,6 +187,15 @@ void tscrollbar_container::NEW_request_reduce_height( return; } + const bool unhide = + initial_horizontal_scrollbar_mode_ == auto_visible_first_run + && vertical_scrollbar_mode_ == always_invisible; + + if(unhide) { + horizontal_scrollbar_mode_ = always_visible; + show_horizontal_scrollbar(); + } + const tpoint scrollbar_size = vertical_scrollbar_grid_->get_best_size(); if(maximum_height > static_cast(scrollbar_size.y)) { size.y = maximum_height; @@ -193,6 +206,10 @@ void tscrollbar_container::NEW_request_reduce_height( // FIXME adjust for the step size of the scrollbar set_layout_size(size); + + if(unhide) { + /** @todo Throw a width change exception. */ + } } void tscrollbar_container::layout_wrap(const unsigned maximum_width) @@ -201,7 +218,7 @@ void tscrollbar_container::layout_wrap(const unsigned maximum_width) twidget::layout_wrap(maximum_width); assert(content_grid_ && vertical_scrollbar_grid_); - const unsigned offset = vertical_scrollbar_mode_ == HIDE + const unsigned offset = vertical_scrollbar_mode_ == always_invisible ? 0 : vertical_scrollbar_grid_->get_best_size().x; @@ -214,12 +231,12 @@ bool tscrollbar_container::has_vertical_scrollbar() const * @todo look at cleaning the has_X_scrollbar and can_wrap to do the * visibility test in a more generic way, preferably in the grid. */ - return is_visible() && vertical_scrollbar_mode_ != HIDE; + return is_visible() && vertical_scrollbar_mode_ != always_invisible; } bool tscrollbar_container::has_horizontal_scrollbar() const { - return is_visible() && horizontal_scrollbar_mode_ != HIDE; + return is_visible() && horizontal_scrollbar_mode_ != always_invisible; } void tscrollbar_container:: @@ -313,13 +330,13 @@ tpoint tscrollbar_container::calculate_best_size() const /***** get vertical scrollbar size *****/ const tpoint vertical_scrollbar = - vertical_scrollbar_mode_ == HIDE + vertical_scrollbar_mode_ == always_invisible ? tpoint(0, 0) : vertical_scrollbar_grid_->get_best_size(); /***** get horizontal scrollbar size *****/ const tpoint horizontal_scrollbar = - horizontal_scrollbar_mode_ == HIDE + horizontal_scrollbar_mode_ == always_invisible ? tpoint(0, 0) : horizontal_scrollbar_grid_->get_best_size(); @@ -349,7 +366,7 @@ static void set_scrollbar_mode(tgrid* scrollbar_grid, tscrollbar_* scrollbar, { assert(scrollbar_grid && scrollbar); - if(scrollbar_mode != tscrollbar_container::HIDE) { + if(scrollbar_mode != tscrollbar_container::always_invisible) { scrollbar->set_item_count(items); scrollbar->set_visible_items(visible_items); @@ -360,9 +377,9 @@ static void set_scrollbar_mode(tgrid* scrollbar_grid, tscrollbar_* scrollbar, if(!scrollbar_needed) { // Hide the scrollbar - if(scrollbar_mode == tscrollbar_container::SHOW_WHEN_NEEDED) { + if(scrollbar_mode == tscrollbar_container::auto_visible) { if(true) { // extra setting - scrollbar_mode = tscrollbar_container::HIDE; + scrollbar_mode = tscrollbar_container::always_invisible; } else { scrollbar_grid->set_visible(twidget::HIDDEN); } @@ -370,7 +387,7 @@ static void set_scrollbar_mode(tgrid* scrollbar_grid, tscrollbar_* scrollbar, } } - if(scrollbar_mode == tscrollbar_container::HIDE) { + if(scrollbar_mode == tscrollbar_container::always_invisible) { scrollbar_grid->set_visible(twidget::INVISIBLE); } } @@ -683,7 +700,7 @@ void tscrollbar_container::show_vertical_scrollbar() return; } - if(vertical_scrollbar_mode_ == HIDE) { + if(vertical_scrollbar_mode_ == always_invisible) { vertical_scrollbar_grid_->set_visible(twidget::INVISIBLE); } else { vertical_scrollbar_grid_->set_visible(twidget::VISIBLE); @@ -696,7 +713,7 @@ void tscrollbar_container::show_horizontal_scrollbar() return; } - if(horizontal_scrollbar_mode_ == HIDE) { + if(horizontal_scrollbar_mode_ == always_invisible) { horizontal_scrollbar_grid_->set_visible(twidget::INVISIBLE); } else { horizontal_scrollbar_grid_->set_visible(twidget::VISIBLE); @@ -951,12 +968,12 @@ void tscrollbar_container::scrollbar_moved() assert(vertical_scrollbar_ && horizontal_scrollbar_); /*** Update the content location. ***/ - const int x_offset = horizontal_scrollbar_mode_ == HIDE + const int x_offset = horizontal_scrollbar_mode_ == always_invisible ? 0 : horizontal_scrollbar_->get_item_position() * horizontal_scrollbar_->get_step_size(); - const int y_offset = vertical_scrollbar_mode_ == HIDE + const int y_offset = vertical_scrollbar_mode_ == always_invisible ? 0 : vertical_scrollbar_->get_item_position() * vertical_scrollbar_->get_step_size(); diff --git a/src/gui/widgets/scrollbar_container.hpp b/src/gui/widgets/scrollbar_container.hpp index e425f8194a3..7d2495c143d 100644 --- a/src/gui/widgets/scrollbar_container.hpp +++ b/src/gui/widgets/scrollbar_container.hpp @@ -46,22 +46,29 @@ public: /** The way to handle the showing or hiding of the scrollbar. */ enum tscrollbar_mode { - SHOW, /**< - * The scrollbar is always shown, whether - * needed or not. - */ - HIDE, /**< - * The scrollbar is never shown even not when - * needed. There's also no space reserved for - * the scrollbar. - */ - SHOW_WHEN_NEEDED /**< - * The scrollbar is shown when the number of - * items is larger as the visible items. The - * space for the scrollbar is always - * reserved, just in case it's needed after - * the initial sizing (due to adding items). - */ + always_visible, /**< + * The scrollbar is always shown, whether + * needed or not. + */ + always_invisible, /**< + * The scrollbar is never shown even not + * when needed. There's also no space + * reserved for the scrollbar. + */ + auto_visible, /**< + * The scrollbar is shown when the number of + * items is larger as the visible items. The + * space for the scrollbar is always + * reserved, just in case it's needed after + * the initial sizing (due to adding items). + */ + auto_visible_first_run /**< + * Like auto_visible, but when not needed + * upon the initial layout phase, the bars + * are not shown and no space is reserved + * for them. (The algorithm hides them by + * default. + */ }; /***** ***** ***** ***** layout functions ***** ***** ***** *****/ diff --git a/src/gui/widgets/widget.hpp b/src/gui/widgets/widget.hpp index 15063fa446f..6e1bf0156aa 100644 --- a/src/gui/widgets/widget.hpp +++ b/src/gui/widgets/widget.hpp @@ -173,8 +173,9 @@ public: * @see @ref layout_algorihm for more information. * * @param full_initialization For widgets with scrollbars it hides them - * unless the mode is tscrollbar_mode::SHOW. - * For other widgets this flag is a NOP. + * unless the mode is + * tscrollbar_mode::always_visible. For other + * widgets this flag is a NOP. */ virtual void NEW_layout_init(const bool full_initialization); diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp index a76c38bf146..6784ef786ed 100644 --- a/src/gui/widgets/window.cpp +++ b/src/gui/widgets/window.cpp @@ -1060,7 +1060,7 @@ void twindow::generate_dot_file(const std::string& generator, * - Clear the internal best size cache for all widgets. * - For widgets with scrollbars hide them unless the * @ref gui2::tscrollbar_container::tscrollbar_mode "scrollbar_mode" is - * SHOW. + * always_visible or auto_visible. * - Handle shared sizes: * - Height and width: * - Get the best size for all widgets that share height and width. diff --git a/src/gui/widgets/window_builder.cpp b/src/gui/widgets/window_builder.cpp index 5f3512eef54..4301f91b512 100644 --- a/src/gui/widgets/window_builder.cpp +++ b/src/gui/widgets/window_builder.cpp @@ -144,15 +144,17 @@ tscrollbar_container::tscrollbar_mode get_scrollbar_mode(const std::string& scrollbar_mode) { if(scrollbar_mode == "always") { - return tscrollbar_container::SHOW; + return tscrollbar_container::always_visible; } else if(scrollbar_mode == "never") { - return tscrollbar_container::HIDE; + return tscrollbar_container::always_invisible; + } else if(scrollbar_mode == "initial_auto") { + return tscrollbar_container::auto_visible_first_run; } else { if(!scrollbar_mode.empty() && scrollbar_mode != "auto") { ERR_GUI_E << "Invalid scrollbar mode '" << scrollbar_mode << "' falling back to 'auto'.\n"; } - return tscrollbar_container::SHOW_WHEN_NEEDED; + return tscrollbar_container::auto_visible; } }