tpanel now has its own defintion and part of twindow moved to tpanel.

More refactoring still required.
This commit is contained in:
Mark de Wever 2008-04-30 09:43:54 +00:00
parent 99e7c9bbef
commit a8fb9e9d9a
7 changed files with 196 additions and 10 deletions

View File

@ -38,6 +38,46 @@
namespace gui2 {
void tpanel::draw(surface& surface)
{
// Need to preserve the state and inherited draw clear the flag.
const bool is_dirty = dirty();
// background.
if(is_dirty) {
tcontrol::draw(surface);
}
// children
grid_.draw(surface);
// foreground
if(is_dirty) {
SDL_Rect rect = get_rect();
canvas(1).draw(true);
blit_surface(canvas(1).surf(), 0, surface, &rect);
}
}
SDL_Rect tpanel::get_client_rect() const
{
const tpanel_definition::tresolution* conf = dynamic_cast<const tpanel_definition::tresolution*>(config());
assert(conf);
SDL_Rect result = get_rect();
result.x += conf->left_border;
result.y += conf->top_border;
result.w -= conf->left_border + conf->right_border;
result.h -= conf->top_border + conf->bottom_border;
return result;
}
void tpanel::set_size(const SDL_Rect& rect)
{
tcontrol::set_size(rect);
grid_.set_size(get_client_rect());
}
} // namespace gui2

View File

@ -24,11 +24,16 @@ class tpanel : public tcontrol
{
public:
tpanel() :
tcontrol(0),
//! Constructor.
//!
//! @param load_conf When a class inherits from a panel that
//! config should be loaded, so set this to false.
//! @param canvas_count The canvas count for tcontrol.
tpanel(const bool load_conf = true, const unsigned canvas_count = 2) :
tcontrol(canvas_count),
grid_(0, 0, 0, 0)
{
//load_config();
if(load_conf) load_config();
grid_.set_parent(this);
}
@ -41,11 +46,23 @@ public:
// Inherited from twidget.
bool dirty() const { return twidget::dirty() || grid_.dirty(); }
//! A panel is always active atm so ignore the request.
void set_active(const bool /*active*/) {}
bool get_active() const { return true; }
unsigned get_state() const { return 0; }
//! Inherited from tcontrol.
void draw(surface& surface);
//! Inherited from tcontrol.
void set_size(const SDL_Rect& rect);
//***** **** wrappers to the grid **** ****
tgrid::iterator begin() { return grid_.begin(); }
tgrid::iterator end() { return grid_.end(); }
SDL_Rect get_client_rect() const;
void set_client_size(const SDL_Rect& rect) { grid_.set_size(rect); }
void set_rows(const unsigned rows) { grid_.set_rows(rows); }
@ -74,13 +91,12 @@ public:
void set_col_scaling(const unsigned col, const unsigned 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); }
private:
tgrid grid_;
//! Inherited from tcontrol.
const std::string& get_control_type() const
{ static const std::string type = "panel"; return type; }
};
} // namespace gui2

View File

@ -22,6 +22,7 @@
#include "gui/widgets/button.hpp"
#include "gui/widgets/helper.hpp"
#include "gui/widgets/label.hpp"
#include "gui/widgets/panel.hpp"
#include "gui/widgets/spacer.hpp"
#include "gui/widgets/widget.hpp"
#include "gui/widgets/window_builder.hpp"
@ -161,6 +162,7 @@ const std::string& tgui_definition::read(const config& cfg)
* @start_table = widget_definition
* button_definition A push button.
* label_definition A label.
* panel_definition A panel.
* spacer_definition A spacer.
* text_box_definition A single line text box.
* tooltip_definition A small tooltip with help.
@ -185,6 +187,7 @@ const std::string& tgui_definition::read(const config& cfg)
/***** Control definitions *****/
load_definitions<tbutton_definition>("button", cfg.get_children("button_definition"));
load_definitions<tlabel_definition>("label", cfg.get_children("label_definition"));
load_definitions<tpanel_definition>("panel", cfg.get_children("panel_definition"));
load_definitions<tspacer_definition>("spacer", cfg.get_children("spacer_definition"));
load_definitions<ttext_box_definition>("text_box", cfg.get_children("text_box_definition"));
load_definitions<ttooltip_definition>("tooltip", cfg.get_children("tooltip_definition"));
@ -224,8 +227,14 @@ void tgui_definition::load_definitions(const std::string& definition_type, const
control_definition[definition_type].insert(std::make_pair(def->id, def));
}
// FIXME use proper control name
VALIDATE(control_definition[definition_type].find("default") != control_definition[definition_type].end(), _ ("No default button defined."));
utils::string_map symbols;
symbols["definition"] = definition_type;
symbols["id"] = "default";
t_string msg(vgettext(
"Widget defintion '$definition' doesn't contain the defintion for '$id'.",
symbols));
VALIDATE(control_definition[definition_type].find("default")
!= control_definition[definition_type].end(), msg);
}
tcontrol_definition::tcontrol_definition(const config& cfg) :
@ -446,6 +455,51 @@ tlabel_definition::tresolution::tresolution(const config& cfg) :
state.push_back(tstate_definition(cfg.child("state_disabled")));
}
tpanel_definition::tpanel_definition(const config& cfg) :
tcontrol_definition(cfg)
{
DBG_G_P << "Parsing panel " << id << '\n';
load_resolutions<tresolution>(cfg.get_children("resolution"));
}
tpanel_definition::tresolution::tresolution(const config& cfg) :
tresolution_definition_(cfg),
top_border(lexical_cast_default<unsigned>(cfg["top_border"])),
bottom_border(lexical_cast_default<unsigned>(cfg["bottom_border"])),
left_border(lexical_cast_default<unsigned>(cfg["left_border"])),
right_border(lexical_cast_default<unsigned>(cfg["right_border"]))
{
/*WIKI
* @page = GUIToolkitWML
* @order = 1_widget_panel
*
* == Panel ==
*
* The definition of a panel. A panel is a container hold other elements in it's
* grid. A panel is always enabled and can't be disabled. Instead it uses the
* states as layers to draw on.
*
* The resolution for a text box also contains the following keys:
* @start_table = config
* top_border (unsigned = 0) The size which isn't used for the client area.
* bottom_border (unsigned = 0) The size which isn't used for the client area.
* left_border (unsigned = 0) The size which isn't used for the client area.
* right_border (unsigned = 0) The size which isn't used for the client area.
* @end_table
*
*
* The following layers exist:
* * background, the background of the panel.
* * foreground, the foreground of the panel/
*/
// The panel needs to know the order.
state.push_back(tstate_definition(cfg.child("background")));
state.push_back(tstate_definition(cfg.child("foreground")));
}
tspacer_definition::tspacer_definition(const config& cfg) :
tcontrol_definition(cfg)
{

View File

@ -123,6 +123,23 @@ struct tlabel_definition : public tcontrol_definition
};
};
struct tpanel_definition : public tcontrol_definition
{
tpanel_definition(const config& cfg);
struct tresolution : public tresolution_definition_
{
tresolution(const config& cfg);
unsigned top_border;
unsigned bottom_border;
unsigned left_border;
unsigned right_border;
};
};
struct tspacer_definition : public tcontrol_definition
{

View File

@ -53,7 +53,7 @@ namespace gui2{
twindow::twindow(CVideo& video,
const int x, const int y, const int w, const int h) :
tpanel(),
tpanel(false, 0),
tevent_handler(),
video_(video),
status_(NEW),
@ -122,6 +122,7 @@ int twindow::show(const bool restore, void* /*flip_function*/)
if(need_layout_) {
DBG_G << "Window: layout client area.\n";
layout(get_client_rect());
need_layout_ = false;
screen = make_neutral_surface(restorer_);

View File

@ -102,6 +102,7 @@ public:
//! Gets the coordinates of the client area, for external use the height
//! and the width are the most interesting things.
//FIXME this can be removed it the panel defintion inherites from panel defintion
SDL_Rect get_client_rect() const;
protected:

View File

@ -96,6 +96,19 @@ public:
};
struct tbuilder_panel : public tbuilder_control
{
private:
tbuilder_panel();
public:
tbuilder_panel(const config& cfg);
twidget* build () const;
tbuilder_grid* grid;
};
struct tbuilder_spacer : public tbuilder_control
{
@ -361,6 +374,8 @@ tbuilder_grid::tbuilder_grid(const config& cfg) :
widgets.push_back(new tbuilder_button(*((**col_itor).child("button"))));
} else if((**col_itor).child("label")) {
widgets.push_back(new tbuilder_label(*((**col_itor).child("label"))));
} else if((**col_itor).child("panel")) {
widgets.push_back(new tbuilder_panel(*((**col_itor).child("panel"))));
} else if((**col_itor).child("spacer")) {
widgets.push_back(new tbuilder_spacer(*((**col_itor).child("spacer"))));
} else if((**col_itor).child("text_box")) {
@ -453,6 +468,48 @@ twidget* tbuilder_label::build() const
return tmp_label;
}
tbuilder_panel::tbuilder_panel(const config& cfg) :
tbuilder_control(cfg),
grid(0)
{
VALIDATE(cfg.child("grid"), _("No grid defined."));
grid = new tbuilder_grid(*(cfg.child("grid")));
}
twidget* tbuilder_panel::build() const
{
tpanel *panel = new tpanel();
init_control(panel);
DBG_G << "Window builder: placed panel '" << id << "' with defintion '"
<< definition << "'.\n";
log_scope2(gui, "Window builder: building grid for panel.");
const unsigned rows = grid->rows;
const unsigned cols = grid->cols;
panel->set_rows_cols(rows, cols);
for(unsigned x = 0; x < rows; ++x) {
panel->set_row_scaling(x, grid->row_scale[x]);
for(unsigned y = 0; y < cols; ++y) {
if(x == 0) {
panel->set_col_scaling(y, grid->col_scale[y]);
}
twidget* widget = grid->widgets[x * cols + y]->build();
panel->add_child(widget, x, y, grid->flags[x * cols + y], grid->border_size[x * cols + y]);
}
}
return panel;
}
twidget* tbuilder_spacer::build() const
{
tspacer *spacer = new tspacer();