mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-02 20:01:21 +00:00
Add a new scrollbar mode.
This way the user can select whether or not to show the scrollbar if the contents fit at the first run. The code will only be used for the new layout algorithm and does nothing at the moment.
This commit is contained in:
parent
cf8639b980
commit
4eff96aaa0
@ -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 ==
|
||||
|
@ -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<unsigned>(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();
|
||||
|
@ -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 ***** ***** ***** *****/
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user