Add a very crude proof-of-concept multi page widget.

The widget is used in the campaign selection dialog, which doesn't work
properly (but is only used with --new-widgets). The code still needs a lot of
polishing and testing, which will be done later.
This commit is contained in:
Mark de Wever 2009-05-23 09:17:44 +00:00
parent 0bf5e72e90
commit c071bd16e8
9 changed files with 425 additions and 41 deletions

View file

@ -0,0 +1,126 @@
#textdomain wesnoth-lib
###
### Definition of a multi page
###
#define _GUI_RESOLUTION RESOLUTION FONT_SIZE FONT_STYLE FONT_COLOUR_ENABLED FONT_COLOUR_DISABLED
[resolution]
{RESOLUTION}
min_width = 0
min_height = 0
default_width = 0
default_height = 0
max_width = 0
max_height = 0
text_font_size = {FONT_SIZE}
text_font_style = {FONT_STYLE}
[state_enabled]
[draw]
[/draw]
[/state_enabled]
[state_disabled]
[draw]
[/draw]
[/state_disabled]
[grid]
[row]
grow_factor = 1
[column]
grow_factor = 1
horizontal_grow = "true" # needed ?
vertical_grow = "true" # needed ?
[grid]
id = "_content_grid"
[row]
[column]
horizontal_grow = "true"
vertical_grow = "true"
[grid]
id = "_list_grid"
[/grid]
[/column]
[/row]
[/grid]
[/column]
[column]
grow_factor = 0
{GUI__VERTICAL_SCROLLBAR_GRID}
[/column]
[/row]
[row]
grow_factor = 0
[column]
{GUI__HORIZONTAL_SCROLLBAR_GRID}
[/column]
[column]
[spacer]
[/spacer]
[/column]
[/row]
[/grid]
[/resolution]
#enddef
[multi_page_definition]
id = "default"
description = "Testing version."
{_GUI_RESOLUTION
({GUI_TINY__RESOLUTION})
({GUI_TINY__FONT_SIZE__DEFAULT})
()
({GUI__FONT_COLOUR_ENABLED__DEFAULT})
({GUI__FONT_COLOUR_DISABLED__DEFAULT})
}
{_GUI_RESOLUTION
({GUI_NORMAL__RESOLUTION})
({GUI_NORMAL__FONT_SIZE__DEFAULT})
()
({GUI__FONT_COLOUR_ENABLED__DEFAULT})
({GUI__FONT_COLOUR_DISABLED__DEFAULT})
}
[/multi_page_definition]
#undef _GUI_RESOLUTION

View file

@ -97,44 +97,55 @@
border_size = 5
vertical_alignment = "top"
# FIXME show the addon pane.
[panel]
[multi_page]
definition = "default"
[grid]
[list_definition]
[row]
grow_factor = 0
[column]
[scroll_label]
id = "description"
definition = "default"
[/scroll_label]
[grid]
[row]
grow_factor = 0
[column]
[label]
id = "description"
definition = "default"
wrap = "true"
[/label]
[/column]
[/row]
[row]
grow_factor = 1
[column]
horizontal_alignment = "center"
vertical_alignment = "top"
[image]
id = "image"
definition = "default"
[/image]
[/column]
[/row]
[/grid]
[/column]
[/row]
[/list_definition]
[row]
grow_factor = 1
[column]
horizontal_alignment = "center"
vertical_alignment = "top"
[image]
id = "image"
definition = "default"
[/image]
[/column]
[/row]
[/grid]
[/panel]
[/multi_page]
[/column]

View file

@ -182,6 +182,7 @@ tbuilder_widget_ptr create_builder_widget(const config& cfg)
TRY(listbox);
TRY(menubar);
TRY(minimap);
TRY(multi_page);
TRY(panel);
TRY(scroll_label);
TRY(slider);
@ -927,6 +928,107 @@ twidget* tbuilder_minimap::build() const
return minimap;
}
tbuilder_multi_page::tbuilder_multi_page(const config& cfg) :
tbuilder_control(cfg),
vertical_scrollbar_mode(
get_scrollbar_mode(cfg["vertical_scrollbar_mode"])),
horizontal_scrollbar_mode(
get_scrollbar_mode(cfg["horizontal_scrollbar_mode"])),
builder(0),
data()
{
/*WIKI
* @page = GUIWidgetInstanceWML
* @order = 2_multi_page
*
* == Multi page ==
*
* Instance of a multi page.
*
* List with the multi page specific variables:
* @start_table = config
* vertical_scrollbar_mode (scrollbar_mode = auto | initial_auto)
* Determines whether or not to show the
* scrollbar. The default of initial_auto
* is used when --new-widgets is used.
* In the future the default will be
* auto.
* horizontal_scrollbar_mode (scrollbar_mode = auto | initial_auto)
* Determines whether or not to show the
* scrollbar. The default of initial_auto
* is used when --new-widgets is used.
* In the future the default will be
* initial_auto.
*
* list_definition (section) This defines how a listbox item
* looks. It must contain the grid
* definition for 1 row of the list.
*
* list_data(section = []) A grid alike section which stores the
* initial data for the listbox. Every row
* must have the same number of columns as
* the 'list_definition'.
* @end_table
*/
const config &l = cfg.child("list_definition");
VALIDATE(l, _("No list defined."));
builder = new tbuilder_grid(l);
assert(builder);
VALIDATE(builder->rows == 1,
_("A 'list_definition' should contain one row."));
const config &data_cfg = cfg.child("list_data");
if (!data_cfg) return;
foreach (const config &row, data_cfg.child_range("row"))
{
unsigned col = 0;
foreach (const config &c, row.child_range("column"))
{
data.push_back(string_map());
foreach (const config::attribute &i, c.attribute_range()) {
data.back()[i.first] = i.second;
}
++col;
}
VALIDATE(col == builder->cols, _("'list_data' must have "
"the same number of columns as the 'list_definition'."));
}
}
twidget* tbuilder_multi_page::build() const
{
tlistbox *listbox = new tlistbox(
true, true, tgenerator_::independant, false);
init_control(listbox);
listbox->set_list_builder(builder); // FIXME in finalize???
listbox->set_vertical_scrollbar_mode(vertical_scrollbar_mode);
listbox->set_horizontal_scrollbar_mode(horizontal_scrollbar_mode);
DBG_GUI_G << "Window builder: placed listbox '"
<< id << "' with defintion '"
<< definition << "'.\n";
boost::intrusive_ptr<const tlistbox_definition::tresolution> conf =
boost::dynamic_pointer_cast
<const tlistbox_definition::tresolution>(listbox->config());
assert(conf);
conf->grid->build(&listbox->grid());
listbox->finalize(NULL, NULL, data);
return listbox;
}
tbuilder_panel::tbuilder_panel(const config& cfg) :
tbuilder_control(cfg),
grid(0)

View file

@ -167,6 +167,7 @@ public:
std::vector<string_map>list_data;
};
struct tbuilder_menubar : public tbuilder_control
{
tbuilder_menubar(const config& cfg);
@ -202,6 +203,32 @@ struct tbuilder_minimap : public tbuilder_control
twidget* build () const;
};
struct tbuilder_multi_page
: public tbuilder_control
{
private:
tbuilder_multi_page();
public:
tbuilder_multi_page(const config& cfg);
twidget* build () const;
tscrollbar_container::tscrollbar_mode
vertical_scrollbar_mode,
horizontal_scrollbar_mode;
tbuilder_grid_ptr builder;
/**
* Multi page data.
*
* Contains a vector with the data to set in every cell, it's used to
* serialize the data in the config, so the config is no longer required.
*/
std::vector<string_map> data;
};
struct tbuilder_panel : public tbuilder_control
{

View file

@ -243,6 +243,51 @@ void tvertical_list::handle_key_down_arrow(SDLMod /*modifier*/, bool& handled)
}
}
tpoint tindependant::calculate_best_size() const
{
/*
* The best size is the combination of the greatest width and greatest
* height.
*/
tpoint result(0, 0);
for(size_t i = 0; i < get_item_count(); ++i) {
const tgrid& grid = get_item(i);
const tpoint best_size = grid.get_best_size();
if(best_size.x > result.x) {
result.x = best_size.x;
}
if(best_size.y > result.y) {
result.y = best_size.y;
}
}
return result;
}
void tindependant::set_size(const tpoint& origin, const tpoint& size)
{
/*
* Set every item to it's best size, need to evaluate whether
* this is the best idea or that the size works better.
*/
for(size_t i = 0; i < get_item_count(); ++i) {
tgrid& grid = get_item(i);
tpoint best_size = grid.get_best_size();
assert(best_size.x <= size.x);
assert(best_size.y <= size.y);
grid.set_size(origin, best_size);
}
}
} // namespace placement
/***** ***** ***** ***** Select action ***** ***** ***** *****/

View file

@ -350,48 +350,70 @@ struct tindependant
: public virtual tgenerator_
{
/** See thorizontal_list::create_item(). */
void create_item(const unsigned /*index*/) { ERROR_LOG(false); }
void create_item(const unsigned /*index*/)
{
/* DO NOTHING */
}
/** See thorizontal_list::calculate_best_size(). */
tpoint calculate_best_size() const
{ ERROR_LOG(false); }
tpoint calculate_best_size() const;
/** See thorizontal_list::set_size(). */
void set_size(const tpoint& /*origin*/, const tpoint& /*size*/)
{ ERROR_LOG(false); }
void set_size(const tpoint& origin, const tpoint& size);
/** See thorizontal_list::set_origin(). */
void set_origin(const tpoint& /*origin*/)
{ ERROR_LOG(false); }
{
/* DO NOTHING */
/** @todo Evaluate what we need to do here. */
}
/** See thorizontal_list::set_visible_area(). */
void set_visible_area(const SDL_Rect& /*area*/)
{ ERROR_LOG(false); }
{
/* DO NOTHING */
/** @todo Evaluate what we need to do here. */
}
/** See thorizontal_list::find_widget(). */
twidget* find_widget(const tpoint&, const bool) { ERROR_LOG(false); }
twidget* find_widget(const tpoint&, const bool)
{
/** @todo implement. */
return NULL;
}
/** See thorizontal_list::find_widget(). */
const twidget* find_widget(const tpoint&, const bool) const
{ ERROR_LOG(false); }
{
/** @todo implement. */
return NULL;
}
/***** ***** ***** ***** keyboard functions ***** ***** ***** *****/
/** Inherited from tgenerator_. */
void handle_key_up_arrow(SDLMod, bool&)
{ ERROR_LOG(false); }
{
/* DO NOTHING */
}
/** Inherited from tgenerator_. */
void handle_key_down_arrow(SDLMod, bool&)
{ ERROR_LOG(false); }
{
/* DO NOTHING */
}
/** Inherited from tgenerator_. */
void handle_key_left_arrow(SDLMod, bool&)
{ ERROR_LOG(false); }
{
/* DO NOTHING */
}
/** Inherited from tgenerator_. */
void handle_key_right_arrow(SDLMod, bool&)
{ ERROR_LOG(false); }
{
/* DO NOTHING */
}
};
} // namespace placement

View file

@ -26,6 +26,7 @@ class tlistbox
: public tscrollbar_container
{
friend struct tbuilder_listbox;
friend struct tbuilder_multi_page;
friend class tdebug_layout_graph;
/** @todo Remove this item, part of the markup hack. */

View file

@ -196,6 +196,10 @@ const std::string& tgui_definition::read(const config& cfg)
* options. This version is used for map
* previews, there will be a another version
* which allows interaction.
* Multi_page A multi page is a control that contains
* serveral 'pages' of which only one is
* visible. The pages can contain the same
* of different info.
* Panel A panel is a container with can have it's
* own visual attributes.
* Scroll_label A label which can have scrollbars.
@ -264,6 +268,7 @@ const std::string& tgui_definition::read(const config& cfg)
load_definitions<tlistbox_definition>("listbox", cfg);
load_definitions<tmenubar_definition>("menubar", cfg);
load_definitions<tminimap_definition>("minimap", cfg);
load_definitions<tmulti_page_definition>("multi_page", cfg);
load_definitions<tpanel_definition>("panel", cfg);
load_definitions<tscroll_label_definition>("scroll_label", cfg);
load_definitions<tslider_definition>("slider", cfg);
@ -828,6 +833,37 @@ tpanel_definition::tpanel_definition(const config& cfg) :
load_resolutions<tresolution>(cfg);
}
tmulti_page_definition::tmulti_page_definition(const config& cfg) :
tcontrol_definition(cfg)
{
DBG_GUI_P << "Parsing multipage " << id << '\n';
load_resolutions<tresolution>(cfg);
}
tmulti_page_definition::tresolution::tresolution(const config& cfg) :
tresolution_definition_(cfg),
grid(NULL)
{
/*WIKI
* @page = GUIWidgetDefinitionWML
* @order = 1_multi_page
*
* == Multi page ==
*
* The documentation is not written yet.
*/
// Note the order should be the same as the enum tstate is listbox.hpp.
state.push_back(tstate_definition(cfg.child("state_enabled")));
state.push_back(tstate_definition(cfg.child("state_disabled")));
const config &child = cfg.child("grid");
VALIDATE(child, _("No grid defined."));
grid = new tbuilder_grid(child);
}
tpanel_definition::tresolution::tresolution(const config& cfg) :
tresolution_definition_(cfg),
top_border(lexical_cast_default<unsigned>(cfg["top_border"])),

View file

@ -240,6 +240,20 @@ struct tminimap_definition : public tcontrol_definition
};
};
struct tmulti_page_definition
: public tcontrol_definition
{
tmulti_page_definition(const config& cfg);
struct tresolution : public tresolution_definition_
{
tresolution(const config& cfg);
tbuilder_grid_ptr grid;
};
};
struct tpanel_definition : public tcontrol_definition
{