More refactoring, grids can now be nested properly...

...allowing better placement of widgets.
This commit is contained in:
Mark de Wever 2008-04-09 15:31:07 +00:00
parent 2563ef1135
commit b6b02b26e2
5 changed files with 317 additions and 170 deletions

View file

@ -12,10 +12,61 @@
left = "center" left = "center"
width = 600 width = 600
height = 150 height = 200
window_definition = "default" window_definition = "default"
[grid]
[row]
#fixme rename scale to grow_factor
scale = 0
[column]
scale = 1
border = "all"
border_size = 5
horizontal_alignment = "left"
horizontal_grow = "true" #FIXME should not be needed
[label]
label_definition = "default"
label = _ "Connect to Server"
[/label]
[/column]
[/row]
[row]
scale = 0
[column]
scale = 1
border = "all"
border_size = 5
horizontal_alignment = "left"
horizontal_grow = "true" #FIXME should not be needed
[label]
label_definition = "default"
label = _ "You will now connect to a server to download add-ons."
[/label]
[/column]
[/row]
[row]
scale = 1
[column]
scale = 1
horizontal_grow = "true"
[grid] [grid]
[row] [row]
@ -55,6 +106,21 @@
[/row] [/row]
[/grid]
[/column]
[/row]
[row]
scale = 0
[column]
scale = 1
horizontal_grow = "true"
[grid]
[row] [row]
scale = 0 scale = 0
@ -127,6 +193,12 @@
[/grid] [/grid]
[/column]
[/row]
[/grid]
[/resolution] [/resolution]
[/window] [/window]

View file

@ -214,6 +214,8 @@ tpoint tgrid::get_best_size() const
void tgrid::set_size(const SDL_Rect& rect) void tgrid::set_size(const SDL_Rect& rect)
{ {
log_scope2(gui, "Grid: set size");
twidget::set_size(rect); twidget::set_size(rect);
const tpoint orig(rect.x, rect.y); const tpoint orig(rect.x, rect.y);
@ -240,6 +242,7 @@ void tgrid::set_size(const SDL_Rect& rect)
col_width_ = best_col_width_; col_width_ = best_col_width_;
// expand it. // expand it.
if(size.x > best_size.x) {
const unsigned w = size.x - best_size.x; const unsigned w = size.x - best_size.x;
unsigned w_size = std::accumulate(col_scaling_.begin(), col_scaling_.end(), 0); unsigned w_size = std::accumulate(col_scaling_.begin(), col_scaling_.end(), 0);
DBG_G << "Grid: extra width " << w << " will be divided amount " << w_size << " units in " << cols_ << " columns.\n"; DBG_G << "Grid: extra width " << w << " will be divided amount " << w_size << " units in " << cols_ << " columns.\n";
@ -260,8 +263,9 @@ void tgrid::set_size(const SDL_Rect& rect)
<< col_scaling_[i] << " set width to " << col_width_[i] << ".\n"; << col_scaling_[i] << " set width to " << col_width_[i] << ".\n";
} }
}
if(size.y > best_size.y) {
const unsigned h = size.y - best_size.y; const unsigned h = size.y - best_size.y;
unsigned h_size = std::accumulate(row_scaling_.begin(), row_scaling_.end(), 0); unsigned h_size = std::accumulate(row_scaling_.begin(), row_scaling_.end(), 0);
DBG_G << "Grid: extra height " << h << " will be divided amount " << h_size << " units in " << rows_ << " rows.\n"; DBG_G << "Grid: extra height " << h << " will be divided amount " << h_size << " units in " << rows_ << " rows.\n";
@ -281,7 +285,7 @@ void tgrid::set_size(const SDL_Rect& rect)
DBG_G << "Grid: row " << i << " with scale factor " DBG_G << "Grid: row " << i << " with scale factor "
<< row_scaling_[i] << " set height to " << row_height_[i] << ".\n"; << row_scaling_[i] << " set height to " << row_height_[i] << ".\n";
} }
}
layout(orig); layout(orig);
return; return;
@ -344,6 +348,21 @@ twidget* tgrid::get_widget_by_id(const std::string& id)
return twidget::get_widget_by_id(id); return twidget::get_widget_by_id(id);
} }
void tgrid::draw(surface& surface)
{
for(iterator itor = begin(); itor != end(); ++itor) {
if(! *itor || !itor->dirty()) {
continue;
}
log_scope2(gui_draw, "Grid: draw child.");
itor->draw(surface);
}
set_dirty(false);
}
void tgrid::load_config() void tgrid::load_config()
{ {
for(std::vector<tchild>::iterator itor = children_.begin(); for(std::vector<tchild>::iterator itor = children_.begin();

View file

@ -102,7 +102,7 @@ public:
twidget* get_widget_by_id(const std::string& id); twidget* get_widget_by_id(const std::string& id);
//! Inherited from twidget. //! Inherited from twidget.
void draw(surface& surface) { /* FIXME IMPLEMENT */ } void draw(surface& surface);
//! Inherited from twidget. //! Inherited from twidget.
void load_config(); void load_config();
@ -298,6 +298,10 @@ public:
void set_col_scaling(const unsigned col, const unsigned scale) void set_col_scaling(const unsigned col, const unsigned scale)
{ grid_.set_col_scaling(col, scale); } { grid_.set_col_scaling(col, scale); }
//! Inherited from twidget.
//FIXME we also need to load our own config
void draw(surface& surface) { grid_.draw(surface); }
//! Inherited from twidget. //! Inherited from twidget.
//FIXME we also need to load our own config //FIXME we also need to load our own config
void load_config() { grid_.load_config(); } void load_config() { grid_.load_config(); }

View file

@ -49,54 +49,90 @@
namespace gui2 { namespace gui2 {
struct tbuilder_button : public tbuilder_widget struct tbuilder_control : public tbuilder_widget
{
private:
tbuilder_control();
public:
tbuilder_control(const config& cfg);
//! Parameters for the control.
std::string id;
std::string definition;
t_string label;
};
struct tbuilder_button : public tbuilder_control
{ {
private: private:
tbuilder_button(); tbuilder_button();
public: public:
tbuilder_button(const config& cfg) : tbuilder_button(const config& cfg);
tbuilder_widget(cfg),
retval_(0)
{ read_extra(cfg); }
twidget* build () const; twidget* build () const;
private: private:
int retval_; int retval_;
//! After reading the general part in the constructor read extra data.
void read_extra(const config& cfg);
}; };
struct tbuilder_label : public tbuilder_widget struct tbuilder_label : public tbuilder_control
{ {
private: private:
tbuilder_label(); tbuilder_label();
public: public:
tbuilder_label(const config& cfg) : tbuilder_label(const config& cfg) :
tbuilder_widget(cfg) tbuilder_control(cfg)
{} {}
twidget* build () const; twidget* build () const;
}; };
struct tbuilder_text_box : public tbuilder_widget struct tbuilder_text_box : public tbuilder_control
{ {
private: private:
tbuilder_text_box(); tbuilder_text_box();
public: public:
tbuilder_text_box(const config& cfg) : tbuilder_text_box(const config& cfg) :
tbuilder_widget(cfg) tbuilder_control(cfg)
{} {}
twidget* build () const; twidget* build () const;
}; };
struct tbuilder_grid : public tbuilder_widget
{
private:
tbuilder_grid();
public:
tbuilder_grid(const config& cfg);
unsigned rows;
unsigned cols;
//! The scale factor for the rows / columns.
std::vector<unsigned> row_scale;
std::vector<unsigned> col_scale;
//! The flags per grid cell.
std::vector<unsigned> flags;
//! The border size per grid cell.
std::vector<unsigned> border_size;
//! The widgets per grid cell.
std::vector<tbuilder_widget_ptr> widgets;
twidget* build () const;
private:
//! After reading the general part in the constructor read extra data.
void read_extra(const config& cfg);
};
twindow build(CVideo& video, const std::string& type) twindow build(CVideo& video, const std::string& type)
{ {
@ -107,21 +143,23 @@ twindow build(CVideo& video, const std::string& type)
twindow window(video, 100, 100, definition->width, definition->height); // FIXME use proper origin twindow window(video, 100, 100, definition->width, definition->height); // FIXME use proper origin
// twindow window(video, 0, 0, definition->width, definition->height); // FIXME use proper origin // twindow window(video, 0, 0, definition->width, definition->height); // FIXME use proper origin
const unsigned rows = definition->grid.rows; log_scope2(gui, "Window builder: building grid for window");
const unsigned cols = definition->grid.cols;
const unsigned rows = definition->grid->rows;
const unsigned cols = definition->grid->cols;
window.set_rows_cols(rows, cols); window.set_rows_cols(rows, cols);
for(unsigned x = 0; x < rows; ++x) { for(unsigned x = 0; x < rows; ++x) {
window.set_row_scaling(x, definition->grid.row_scale[x]); window.set_row_scaling(x, definition->grid->row_scale[x]);
for(unsigned y = 0; y < cols; ++y) { for(unsigned y = 0; y < cols; ++y) {
if(x == 0) { if(x == 0) {
window.set_col_scaling(y, definition->grid.col_scale[y]); window.set_col_scaling(y, definition->grid->col_scale[y]);
} }
twidget* widget = definition->grid.widgets[x * cols + y]->build(); twidget* widget = definition->grid->widgets[x * cols + y]->build();
window.add_child(widget, x, y, definition->grid.flags[x * cols + y], definition->grid.border_size[x * cols + y]); window.add_child(widget, x, y, definition->grid->flags[x * cols + y], definition->grid->border_size[x * cols + y]);
} }
} }
@ -175,7 +213,7 @@ twindow_builder::tresolution::tresolution(const config& cfg) :
width(lexical_cast_default<unsigned>(cfg["width"])), width(lexical_cast_default<unsigned>(cfg["width"])),
height(lexical_cast_default<unsigned>(cfg["height"])), height(lexical_cast_default<unsigned>(cfg["height"])),
definition(cfg["window_definition"]), definition(cfg["window_definition"]),
grid(cfg.child("grid")) grid(0) //new tbuilder_grid(cfg.child("grid")))
{ {
/*WIKI /*WIKI
* [resolution] * [resolution]
@ -193,6 +231,10 @@ twindow_builder::tresolution::tresolution(const config& cfg) :
* [/resolution] * [/resolution]
*/ */
VALIDATE(cfg.child("grid"), _("No grid defined."));
grid = new tbuilder_grid(*(cfg.child("grid")));
DBG_G_P << "Window builder: parsing resolution " DBG_G_P << "Window builder: parsing resolution "
<< window_width << ',' << window_height << '\n'; << window_width << ',' << window_height << '\n';
@ -255,14 +297,19 @@ static unsigned read_flags(const config& cfg)
return flags; return flags;
} }
twindow_builder::tresolution::tgrid::tgrid(const config* cfg) : tbuilder_grid::tbuilder_grid(const config& cfg) :
tbuilder_widget(cfg),
rows(0), rows(0),
cols(0), cols(0),
row_scale(),
col_scale(),
flags(),
border_size(),
widgets() widgets()
{ {
VALIDATE(cfg, _("No grid defined.")); log_scope2(gui_parse, "Window builder: parsing a grid");
const config::child_list& row_cfgs = cfg->get_children("row"); const config::child_list& row_cfgs = cfg.get_children("row");
for(std::vector<config*>::const_iterator row_itor = row_cfgs.begin(); for(std::vector<config*>::const_iterator row_itor = row_cfgs.begin();
row_itor != row_cfgs.end(); ++row_itor) { row_itor != row_cfgs.end(); ++row_itor) {
@ -286,6 +333,8 @@ twindow_builder::tresolution::tgrid::tgrid(const config* cfg) :
widgets.push_back(new tbuilder_label(*((**col_itor).child("label")))); widgets.push_back(new tbuilder_label(*((**col_itor).child("label"))));
} else if((**col_itor).child("text_box")) { } else if((**col_itor).child("text_box")) {
widgets.push_back(new tbuilder_text_box(*((**col_itor).child("text_box")))); widgets.push_back(new tbuilder_text_box(*((**col_itor).child("text_box"))));
} else if((**col_itor).child("grid")) {
widgets.push_back(new tbuilder_grid(*((**col_itor).child("grid"))));
} else { } else {
assert(false); assert(false);
} }
@ -307,7 +356,8 @@ twindow_builder::tresolution::tgrid::tgrid(const config* cfg) :
<< rows << " rows and " << cols << " columns.\n"; << rows << " rows and " << cols << " columns.\n";
} }
tbuilder_widget::tbuilder_widget(const config& cfg) : tbuilder_control::tbuilder_control(const config& cfg) :
tbuilder_widget(cfg),
id(cfg["id"]), id(cfg["id"]),
definition(cfg["button_definition"]), definition(cfg["button_definition"]),
label(cfg["label"]) label(cfg["label"])
@ -318,7 +368,7 @@ tbuilder_widget::tbuilder_widget(const config& cfg) :
} }
DBG_G_P << "Window builder: found widget with id '" DBG_G_P << "Window builder: found control with id '"
<< id << "' and definition '" << definition << "'.\n"; << id << "' and definition '" << definition << "'.\n";
} }
@ -342,9 +392,10 @@ twidget* tbuilder_button::build() const
return button; return button;
} }
void tbuilder_button::read_extra(const config& cfg) tbuilder_button::tbuilder_button(const config& cfg) :
tbuilder_control(cfg),
retval_(lexical_cast_default<int>(cfg["return_value"]))
{ {
retval_ = lexical_cast_default<int>(cfg["return_value"]);
} }
twidget* tbuilder_label::build() const twidget* tbuilder_label::build() const
@ -376,5 +427,34 @@ twidget* tbuilder_text_box::build() const
return text_box; return text_box;
} }
twidget* tbuilder_grid::build() const
{
tgrid *grid = new tgrid(0, 0, 0, 0);
grid->set_rows_cols(rows, cols);
log_scope2(gui, "Window builder: building grid");
DBG_G << "Window builder: grid has " << rows << " rows and "
<< cols << " columns.\n";
for(unsigned x = 0; x < rows; ++x) {
grid->set_row_scaling(x, row_scale[x]);
for(unsigned y = 0; y < cols; ++y) {
if(x == 0) {
grid->set_col_scaling(y, col_scale[y]);
}
DBG_G << "Window builder: adding child at " << x << ',' << y << ".\n";
twidget* widget = widgets[x * cols + y]->build();
grid->add_child(widget, x, y, flags[x * cols + y], border_size[x * cols + y]);
}
}
return grid;
}
} // namespace gui2 } // namespace gui2

View file

@ -26,6 +26,7 @@ class CVideo;
namespace gui2 { namespace gui2 {
class tbuilder_grid;
class twidget; class twidget;
class twindow; class twindow;
@ -39,12 +40,8 @@ private:
tbuilder_widget(); tbuilder_widget();
public: public:
tbuilder_widget(const config& cfg); tbuilder_widget(const config& /*cfg*/) {}
//! Parameters for the widget.
std::string id;
std::string definition;
t_string label;
virtual twidget* build() const = 0; virtual twidget* build() const = 0;
virtual ~tbuilder_widget() {} virtual ~tbuilder_widget() {}
@ -79,33 +76,8 @@ public:
std::string definition; std::string definition;
struct tgrid
{
private:
tgrid();
public: tbuilder_grid* grid;
tgrid(const config* cfg);
unsigned rows;
unsigned cols;
//! The scale factor for the rows / columns.
std::vector<unsigned> row_scale;
std::vector<unsigned> col_scale;
//! The flags per grid cell.
std::vector<unsigned> flags;
//! The border size per grid cell.
std::vector<unsigned> border_size;
//! The widgets per grid cell.
std::vector<tbuilder_widget_ptr> widgets;
};
tgrid grid;
}; };
std::vector<tresolution> resolutions; std::vector<tresolution> resolutions;