Add a new real multi page widget and use it.

It's used in the campaign dialog, this change breaks the unit tests
for small gui and small gui since UtBS won't fit in the available
space. This will be fixed later.
This commit is contained in:
Mark de Wever 2009-05-31 18:52:42 +00:00
parent 84a358af57
commit ef8895a344
14 changed files with 294 additions and 188 deletions

View file

@ -10,6 +10,7 @@ Version 1.7.0+svn:
* Improved the layout algorithm not to show scrollbars when they make the
situation worse
* Add a new transient message dialog
* Add a new multi page widget
* WML Engine:
* Made new turn, turn X, side turn and turn refresh events synchronous.
(bug #10603)

View file

@ -3,10 +3,11 @@
### Definition of a multi page
###
#define _GUI_RESOLUTION RESOLUTION FONT_SIZE FONT_STYLE FONT_COLOUR_ENABLED FONT_COLOUR_DISABLED
[resolution]
[multi_page_definition]
id = "default"
description = "Default multi page widget."
{RESOLUTION}
[resolution]
min_width = 0
min_height = 0
@ -17,110 +18,25 @@
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
vertical_grow = "true"
[column]
grow_factor = 1
horizontal_grow = "true" # needed ?
vertical_grow = "true" # needed ?
horizontal_grow = "true"
[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

@ -102,58 +102,47 @@
horizontal_scrollbar_mode = "never"
[list_definition]
[page_definition]
[row]
grow_factor = 0
[column]
border = "all"
border_size = 5
horizontal_alignment = "center"
vertical_alignment = "top"
[grid]
[label]
id = "description"
definition = "default"
[row]
grow_factor = 1
[column]
border = "all"
border_size = 5
vertical_alignment = "top"
[label]
id = "description"
definition = "default"
wrap = "true"
[/label]
[/column]
[/row]
[row]
grow_factor = 1
[column]
border = "all"
border_size = 5
horizontal_alignment = "center"
vertical_alignment = "top"
[image]
id = "image"
definition = "default"
[/image]
[/column]
[/row]
[/grid]
wrap = "true"
[/label]
[/column]
[/row]
[/list_definition]
[row]
grow_factor = 1
[column]
border = "all"
border_size = 5
horizontal_alignment = "center"
vertical_alignment = "top"
[image]
id = "image"
definition = "default"
[/image]
[/column]
[/row]
[/page_definition]
[/multi_page]

View file

@ -35,6 +35,7 @@ src/gui/widgets/label.cpp
src/gui/widgets/listbox.cpp
src/gui/widgets/menubar.cpp
src/gui/widgets/minimap.cpp
src/gui/widgets/multi_page.cpp
src/gui/widgets/panel.cpp
src/gui/widgets/password_box.cpp
src/gui/widgets/scroll_label.cpp

View file

@ -282,6 +282,7 @@ SET(wesnoth-main_SRC
gui/widgets/listbox.cpp
gui/widgets/menubar.cpp
gui/widgets/minimap.cpp
gui/widgets/multi_page.cpp
gui/widgets/panel.cpp
gui/widgets/password_box.cpp
gui/widgets/settings.cpp

View file

@ -107,6 +107,7 @@ wesnoth_source = \
gui/widgets/listbox.cpp \
gui/widgets/menubar.cpp \
gui/widgets/minimap.cpp \
gui/widgets/multi_page.cpp \
gui/widgets/panel.cpp \
gui/widgets/password_box.cpp \
gui/widgets/settings.cpp \

View file

@ -261,6 +261,7 @@ wesnoth_sources = Split("""
gui/widgets/listbox.cpp
gui/widgets/menubar.cpp
gui/widgets/minimap.cpp
gui/widgets/multi_page.cpp
gui/widgets/panel.cpp
gui/widgets/password_box.cpp
gui/widgets/settings.cpp

View file

@ -27,6 +27,7 @@
#include "gui/widgets/listbox.hpp"
#include "gui/widgets/generator.hpp"
#include "gui/widgets/minimap.hpp"
#include "gui/widgets/multi_page.hpp"
#include "gui/widgets/password_box.hpp"
#include "gui/widgets/scroll_label.hpp"
#include "gui/widgets/slider.hpp"
@ -930,10 +931,6 @@ twidget* tbuilder_minimap::build() const
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()
{
@ -947,49 +944,37 @@ tbuilder_multi_page::tbuilder_multi_page(const config& cfg) :
*
* 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
* page_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
* page_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");
const config &page = cfg.child("page_definition");
VALIDATE(l, _("No list defined."));
builder = new tbuilder_grid(l);
VALIDATE(page, _("No page defined."));
builder = new tbuilder_grid(page);
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;
/** @todo This part is untested. */
const config &d = cfg.child("page_data");
if(!d){
return;
}
foreach (const config &row, data_cfg.child_range("row"))
foreach(const config &row, d.child_range("row"))
{
unsigned col = 0;
foreach (const config &c, row.child_range("column"))
foreach (const config &column, row.child_range("column"))
{
data.push_back(string_map());
foreach (const config::attribute &i, c.attribute_range()) {
foreach (const config::attribute &i, column.attribute_range()) {
data.back()[i.first] = i.second;
}
++col;
@ -1002,31 +987,26 @@ tbuilder_multi_page::tbuilder_multi_page(const config& cfg) :
twidget* tbuilder_multi_page::build() const
{
tlistbox *listbox = new tlistbox(
true, true, tgenerator_::independant, false);
tmulti_page *multi_page = new tmulti_page();
init_control(listbox);
init_control(multi_page);
listbox->set_list_builder(builder); // FIXME in finalize???
multi_page->set_page_builder(builder);
listbox->set_vertical_scrollbar_mode(vertical_scrollbar_mode);
listbox->set_horizontal_scrollbar_mode(horizontal_scrollbar_mode);
DBG_GUI_G << "Window builder: placed listbox '"
DBG_GUI_G << "Window builder: placed multi_page '"
<< id << "' with defintion '"
<< definition << "'.\n";
boost::intrusive_ptr<const tlistbox_definition::tresolution> conf =
boost::intrusive_ptr<const tmulti_page_definition::tresolution> conf =
boost::dynamic_pointer_cast
<const tlistbox_definition::tresolution>(listbox->config());
<const tmulti_page_definition::tresolution>(multi_page->config());
assert(conf);
conf->grid->build(&multi_page->grid());
conf->grid->build(&listbox->grid());
multi_page->finalize(data);
listbox->finalize(NULL, NULL, data);
return listbox;
return multi_page;
}
tbuilder_panel::tbuilder_panel(const config& cfg) :

View file

@ -214,10 +214,6 @@ public:
twidget* build () const;
tscrollbar_container::tscrollbar_mode
vertical_scrollbar_mode,
horizontal_scrollbar_mode;
tbuilder_grid_ptr builder;
/**

View file

@ -20,6 +20,7 @@
#include "gui/dialogs/helper.hpp"
#include "gui/widgets/image.hpp"
#include "gui/widgets/listbox.hpp"
#include "gui/widgets/multi_page.hpp"
#include "gui/widgets/scroll_label.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/widgets/window.hpp"
@ -43,11 +44,11 @@ void tcampaign_selection::campaign_selected(twindow& window)
VALIDATE(list, missing_widget("campaign_list"));
tlistbox* page = dynamic_cast<tlistbox*>(
tmulti_page* multi_page = dynamic_cast<tmulti_page*>(
window.find_widget("campaign_details", false));
VALIDATE(page, missing_widget("campaign_details"));
VALIDATE(multi_page, missing_widget("campaign_details"));
page->select_row(list->get_selected_row());
multi_page->select_page(list->get_selected_row());
}
twindow* tcampaign_selection::build_window(CVideo& video)
@ -68,9 +69,9 @@ void tcampaign_selection::pre_show(CVideo& /*video*/, twindow& window)
window.keyboard_capture(list);
/***** Setup campaign details. *****/
tlistbox* page = dynamic_cast<tlistbox*>(
tmulti_page* multi_page = dynamic_cast<tmulti_page*>(
window.find_widget("campaign_details", false));
VALIDATE(page, missing_widget("campaign_details"));
VALIDATE(multi_page, missing_widget("campaign_details"));
foreach (const config &c, campaigns_) {
@ -92,7 +93,7 @@ void tcampaign_selection::pre_show(CVideo& /*video*/, twindow& window)
detail_item["label"] = c["image"];
detail_page.insert(std::make_pair("image", detail_item));
page->add_row(detail_page);
multi_page->add_page(detail_page);
}
campaign_selected(window);

View file

@ -26,7 +26,6 @@ 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

@ -0,0 +1,100 @@
/* $Id$ */
/*
Copyright (C) 2008 - 2009 by Mark de Wever <koraq@xs4all.nl>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
or at your option any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#define GETTEXT_DOMAIN "wesnoth-lib"
#include "gui/widgets/multi_page.hpp"
#include "gui/widgets/generator.hpp"
namespace gui2 {
tmulti_page::tmulti_page()
: tcontainer_(1)
, generator_(NULL)
, page_builder_(NULL)
{
generator_ = tgenerator_::build(
true, true, tgenerator_::independant, false);
}
void tmulti_page::add_page(const string_map& item)
{
assert(generator_);
generator_->create_item(-1, page_builder_, item, NULL);
}
void tmulti_page::add_page(
const std::map<std::string /* widget id */, string_map>& data)
{
assert(generator_);
generator_->create_item(-1, page_builder_, data, NULL);
}
unsigned tmulti_page::get_page_count() const
{
assert(generator_);
return generator_->get_item_count();
}
void tmulti_page::select_page(const unsigned page, const bool select)
{
assert(generator_);
generator_->select_item(page, select);
}
namespace {
/**
* Swaps an item in a grid for another one.*/
void swap_grid(tgrid* grid,
tgrid* content_grid, twidget* widget, const std::string& id)
{
assert(content_grid);
assert(widget);
// Make sure the new child has same id.
widget->set_id(id);
// Get the container containing the wanted widget.
tgrid* parent_grid = NULL;
if(grid) {
parent_grid = grid->find_widget<tgrid>(id, false, false);
}
if(!parent_grid) {
parent_grid = content_grid->find_widget<tgrid>(id, true, false);
}
parent_grid = dynamic_cast<tgrid*>(parent_grid->parent());
assert(parent_grid);
// Replace the child.
widget = parent_grid->swap_child(id, widget, false);
assert(widget);
delete widget;
}
} // namespace
void tmulti_page::finalize(
const std::vector<string_map>& page_data)
{
assert(generator_);
generator_->create_items(-1, page_builder_, page_data, NULL);
swap_grid(NULL, &grid(), generator_, "_content_grid");
}
} // namespace gui2

View file

@ -0,0 +1,121 @@
/* $Id$ */
/*
Copyright (C) 2008 - 2009 by Mark de Wever <koraq@xs4all.nl>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
or at your option any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef GUI_WIDGETS_MULTI_PAGE_HPP_INCLUDED
#define GUI_WIDGETS_MULTI_PAGE_HPP_INCLUDED
#include "gui/widgets/container.hpp"
namespace gui2 {
class tgenerator_;
/** The multi page class. */
class tmulti_page
: public tcontainer_
{
friend struct tbuilder_multi_page;
friend class tdebug_layout_graph;
public:
tmulti_page();
/***** ***** ***** ***** Page handling. ***** ***** ****** *****/
/**
* Adds single page to the grid.
*
* This function expect a page to one multiple widget.
*
* @param item The data to send to the set_members of the
* widget.
*/
void add_page(const string_map& item);
/**
* Adds single page to the grid.
*
* This function expect a page to have multiple widgets (either multiple
* columns or one column with multiple widgets).
*
*
* @param data The data to send to the set_members of the
* widgets. If the member id is not an empty
* string it is only send to the widget that
* has the wanted id (if any). If the member
* id is an empty string, it is send to all
* members. Having both empty and non-empty
* id's gives undefined behaviour.
*/
void add_page(const std::map<std::string /* widget id */,
string_map>& data);
/** Returns the number of pages. */
unsigned get_page_count() const;
/**
* Selectes a page.
*
* @param page The page to select.
* @param select Select or deselect the page.
*/
void select_page(const unsigned page, const bool select = true);
/***** ***** ***** inherited ***** ****** *****/
/** Inherited from tcontrol. */
bool get_active() const { return true; }
/** Inherited from tcontrol. */
unsigned get_state() const { return 0; }
/***** ***** ***** setters / getters for members ***** ****** *****/
void set_page_builder(tbuilder_grid_ptr page_builder)
{ page_builder_ = page_builder; }
private:
/**
* Finishes the building initialization of the widget.
*
* @param page_data The initial data to fill the widget with.
*/
void finalize(const std::vector<string_map>& page_data);
/**
* Contains a pointer to the generator.
*
* The pointer is not owned by this variable.
*/
tgenerator_* generator_;
/** Contains the builder for the new items. */
tbuilder_grid_const_ptr page_builder_;
/** Inherited from tcontrol. */
const std::string& get_control_type() const
{ static const std::string type = "multi_page"; return type; }
/** Inherited from tcontainer_. */
void set_self_active(const bool /*active*/) {}
};
} // namespace gui2
#endif

View file

@ -854,9 +854,8 @@ tmulti_page_definition::tresolution::tresolution(const config& cfg) :
* 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")));
// Add a dummy state since every widget needs a state.
state.push_back(tstate_definition(config("draw")));
const config &child = cfg.child("grid");
VALIDATE(child, _("No grid defined."));