Converted the text to use the formula system as well.
Buttons now can draw their label from the definition. Various minor cleanups.
This commit is contained in:
parent
109acec398
commit
73abe36486
6 changed files with 184 additions and 47 deletions
|
@ -60,6 +60,19 @@ void tbutton::set_height(const unsigned height)
|
|||
tcontrol::set_height(height);
|
||||
}
|
||||
|
||||
void tbutton::set_label(const t_string& label)
|
||||
{
|
||||
|
||||
// set label in canvases
|
||||
canvas_enabled_.set_variable("text", variant(label.str()));
|
||||
canvas_disabled_.set_variable("text", variant(label.str()));
|
||||
canvas_pressed_.set_variable("text", variant(label.str()));
|
||||
canvas_focussed_.set_variable("text", variant(label.str()));
|
||||
|
||||
// inherited
|
||||
tcontrol::set_label(label);
|
||||
}
|
||||
|
||||
void tbutton::mouse_down(const tevent_info& /*event*/, bool& /*handled*/)
|
||||
{
|
||||
DBG_G_E << "Button: left mouse button down.\n";
|
||||
|
@ -167,6 +180,14 @@ void tbutton::resolve_definition()
|
|||
canvas_disabled_ = definition_->disabled.canvas;
|
||||
canvas_pressed_ = definition_->pressed.canvas;
|
||||
canvas_focussed_ = definition_->focussed.canvas;
|
||||
|
||||
// FIXME we need some extra routines since a lot of code will
|
||||
// be duplicated here otherwise.
|
||||
canvas_enabled_.set_variable("text", variant(label()));
|
||||
canvas_disabled_.set_variable("text", variant(label()));
|
||||
canvas_pressed_.set_variable("text", variant(label()));
|
||||
canvas_focussed_.set_variable("text", variant(label()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "gui/widgets/settings.hpp"
|
||||
#include "log.hpp"
|
||||
#include "tstring.hpp"
|
||||
|
||||
namespace gui2 {
|
||||
|
||||
|
@ -42,6 +43,8 @@ public:
|
|||
|
||||
void set_height(const unsigned height);
|
||||
|
||||
void set_label(const t_string& label);
|
||||
|
||||
void mouse_down(const tevent_info& /*event*/, bool& /*handled*/);
|
||||
void mouse_up(const tevent_info& /*event*/, bool& /*handled*/);
|
||||
void mouse_click(const tevent_info& /*event*/, bool& /*handled*/);
|
||||
|
|
|
@ -70,10 +70,22 @@ static Uint32 decode_colour(const std::string& colour)
|
|||
return result;
|
||||
}
|
||||
|
||||
//! A value can be either a number of a formula, if between brackets it is a formula
|
||||
//! else it will be read as an unsigned.
|
||||
//! If empty neither is modified otherwise only the type it is is modified.
|
||||
static void read_possible_formula(const std::string str, unsigned& value, std::string& formula)
|
||||
//! Reads a value as formula or value depending on the contents.
|
||||
//!
|
||||
//! A value can either be formula or a text containing a value, this function
|
||||
//! determines the type and sets either the formula or the value part.
|
||||
//! Formulas always start with a opening bracket '('.
|
||||
//!
|
||||
//! @param str The text with the value or formula. (Since there
|
||||
//! are some problems with tempories when a value is
|
||||
//! taken from a (v)config it uses a copy instead of
|
||||
//! a reference.)
|
||||
//! @param value The value part, if the text is a value this will
|
||||
//! be modified otherwise left untouched.
|
||||
//! @param formula The value part, if the text is a formula this will
|
||||
//! be modified otherwise left untouched.
|
||||
template <class T>
|
||||
static void read_possible_formula(const std::string str, T& value, std::string& formula)
|
||||
{
|
||||
if(str.empty()) {
|
||||
return;
|
||||
|
@ -82,14 +94,38 @@ static void read_possible_formula(const std::string str, unsigned& value, std::s
|
|||
if(str[0] == '(') {
|
||||
formula = str;
|
||||
} else {
|
||||
value = lexical_cast_default<unsigned>(str);
|
||||
value = lexical_cast_default<T>(str);
|
||||
}
|
||||
}
|
||||
|
||||
static void read_possible_formula(const std::string str, t_string& value, std::string& formula)
|
||||
{
|
||||
if(str.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(str[0] == '(') {
|
||||
formula = str;
|
||||
} else {
|
||||
value = t_string(str);
|
||||
}
|
||||
}
|
||||
|
||||
static void read_possible_formula(const std::string str, std::string& value, std::string& formula)
|
||||
{
|
||||
if(str.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(str[0] == '(') {
|
||||
formula = str;
|
||||
} else {
|
||||
value = str;
|
||||
}
|
||||
}
|
||||
|
||||
namespace gui2{
|
||||
|
||||
|
||||
|
||||
tcanvas::tcanvas() :
|
||||
shapes_(),
|
||||
dirty_(true),
|
||||
|
@ -289,6 +325,7 @@ tcanvas::tline::tline(const vconfig& cfg) :
|
|||
* Variables:
|
||||
* width unsigned The width of the canvas.
|
||||
* height unsigned The height of the canvas.
|
||||
* text tstring The text to render on the widget.
|
||||
*
|
||||
* Note when drawing the valid coordinates are:
|
||||
* 0 -> width - 1
|
||||
|
@ -327,6 +364,7 @@ tcanvas::tline::tline(const vconfig& cfg) :
|
|||
* signed number.
|
||||
* string A text.
|
||||
* tstring A translatable string.
|
||||
* f_tstring Formula returning a translatable string.
|
||||
*
|
||||
* colour A string which constains the colour, this
|
||||
* a group of 4 numbers between 0 and 255
|
||||
|
@ -365,22 +403,22 @@ void tcanvas::tline::draw(surface& canvas,
|
|||
// bit silly unless there has been a resize. So to optimize we should
|
||||
// use an extra flag or do the calculation in a separate routine.
|
||||
if(!x1_formula_.empty()) {
|
||||
DBG_G_D << "Line execute x1 formula '" << x1_formula_ << "'.\n";
|
||||
DBG_G_D << "Line: execute x1 formula '" << x1_formula_ << "'.\n";
|
||||
x1_ = game_logic::formula(x1_formula_).execute(variables).as_int();
|
||||
}
|
||||
|
||||
if(!y1_formula_.empty()) {
|
||||
DBG_G_D << "Line execute y1 formula '" << y1_formula_ << "'.\n";
|
||||
DBG_G_D << "Line: execute y1 formula '" << y1_formula_ << "'.\n";
|
||||
y1_ = game_logic::formula(y1_formula_).execute(variables).as_int();
|
||||
}
|
||||
|
||||
if(!x2_formula_.empty()) {
|
||||
DBG_G_D << "Line execute x2 formula '" << x2_formula_ << "'.\n";
|
||||
DBG_G_D << "Line: execute x2 formula '" << x2_formula_ << "'.\n";
|
||||
x2_ = game_logic::formula(x2_formula_).execute(variables).as_int();
|
||||
}
|
||||
|
||||
if(!y2_formula_.empty()) {
|
||||
DBG_G_D << "Line execute y2 formula '" << y2_formula_ << "'.\n";
|
||||
DBG_G_D << "Line: execute y2 formula '" << y2_formula_ << "'.\n";
|
||||
y2_ = game_logic::formula(y2_formula_).execute(variables).as_int();
|
||||
}
|
||||
|
||||
|
@ -422,7 +460,7 @@ tcanvas::trectangle::trectangle(const vconfig& cfg) :
|
|||
{
|
||||
/*WIKI
|
||||
* [rectangle]
|
||||
* Definition of a line.
|
||||
* Definition of a rectangle.
|
||||
* Keys:
|
||||
* x (f_unsigned = 0) The x coordinate of the top left corner.
|
||||
* y (f_unsigned = 0) The y coordinate of the top left corner.
|
||||
|
@ -439,6 +477,8 @@ tcanvas::trectangle::trectangle(const vconfig& cfg) :
|
|||
*
|
||||
* Variables:
|
||||
* See [line].
|
||||
*
|
||||
* [/rectangle]
|
||||
*/
|
||||
read_possible_formula(cfg["x"], x_, x_formula_);
|
||||
read_possible_formula(cfg["y"], y_, y_formula_);
|
||||
|
@ -463,22 +503,22 @@ void tcanvas::trectangle::draw(surface& canvas,
|
|||
// bit silly unless there has been a resize. So to optimize we should
|
||||
// use an extra flag or do the calculation in a separate routine.
|
||||
if(!x_formula_.empty()) {
|
||||
DBG_G_D << "Rectangle execute x formula '" << x_formula_ << "'.\n";
|
||||
DBG_G_D << "Rectangle: execute x formula '" << x_formula_ << "'.\n";
|
||||
x_ = game_logic::formula(x_formula_).execute(variables).as_int();
|
||||
}
|
||||
|
||||
if(!y_formula_.empty()) {
|
||||
DBG_G_D << "Rectangle execute y formula '" << y_formula_ << "'.\n";
|
||||
DBG_G_D << "Rectangle: execute y formula '" << y_formula_ << "'.\n";
|
||||
y_ = game_logic::formula(y_formula_).execute(variables).as_int();
|
||||
}
|
||||
|
||||
if(!w_formula_.empty()) {
|
||||
DBG_G_D << "Rectangle execute width formula '" << w_formula_ << "'.\n";
|
||||
DBG_G_D << "Rectangle: execute width formula '" << w_formula_ << "'.\n";
|
||||
w_ = game_logic::formula(w_formula_).execute(variables).as_int();
|
||||
}
|
||||
|
||||
if(!h_formula_.empty()) {
|
||||
DBG_G_D << "Rectangle execute height formula '" << h_formula_ << "'.\n";
|
||||
DBG_G_D << "Rectangle: execute height formula '" << h_formula_ << "'.\n";
|
||||
h_ = game_logic::formula(h_formula_).execute(variables).as_int();
|
||||
}
|
||||
|
||||
|
@ -579,35 +619,51 @@ void tcanvas::timage::draw(surface& canvas,
|
|||
}
|
||||
|
||||
tcanvas::ttext::ttext(const vconfig& cfg) :
|
||||
x_(lexical_cast_default<unsigned>(cfg["x"])),
|
||||
y_(lexical_cast_default<unsigned>(cfg["y"])),
|
||||
w_(lexical_cast_default<unsigned>(cfg["w"])),
|
||||
h_(lexical_cast_default<unsigned>(cfg["h"])),
|
||||
x_(0),
|
||||
y_(0),
|
||||
w_(0),
|
||||
h_(0),
|
||||
x_formula_(""),
|
||||
y_formula_(""),
|
||||
w_formula_(""),
|
||||
h_formula_(""),
|
||||
font_size_(lexical_cast_default<unsigned>(cfg["font_size"])),
|
||||
colour_(decode_colour(cfg["colour"])),
|
||||
text_(cfg["text"])
|
||||
text_(""),
|
||||
text_formula_("")
|
||||
{
|
||||
|
||||
//FIXME enhance the options and write the wiki block in the new style.
|
||||
|
||||
//FIXME make sure text is rendered properly.
|
||||
|
||||
/*WIKI
|
||||
* [text]
|
||||
* x, y = (unsigned = 0), (unsigned = 0)
|
||||
* The top left corner of the bounding
|
||||
* rectangle.
|
||||
* w = (unsigned = 0) The width of the bounding rectangle.
|
||||
* h = (unsigned = 0) The height of the bounding rectangle.
|
||||
* font_size = (unsigned = 0) The size of the font.
|
||||
* colour = (widget.colour = "") The colour of the text.
|
||||
* text = (t_string = "") The text to print, for now always printed
|
||||
* centered in the area.
|
||||
* debug = (string = "") Debug message to show upon creation
|
||||
* this message is not stored.
|
||||
* [/rectangle]
|
||||
* Definition of text.
|
||||
* Keys:
|
||||
* x (f_unsigned = 0) The x coordinate of the top left corner.
|
||||
* y (f_unsigned = 0) The y coordinate of the top left corner.
|
||||
* w (f_unsigned = 0) The width of the rectangle.
|
||||
* h (f_unsigned = 0) The height of the rectangle.
|
||||
* font_size (unsigned = 0) The size of the font to draw in.
|
||||
* colour (colour = "") The colour of the text.
|
||||
* text (tstring = "") The text to draw (translatable).
|
||||
* debug = (string = "") Debug message to show upon creation
|
||||
* this message is not stored.
|
||||
*
|
||||
* NOTE there's no option of font style yet, alignment can be done with the
|
||||
* forumulas.
|
||||
*
|
||||
* Variables:
|
||||
* text_width unsigned The width of the rendered text.
|
||||
* text_height unsigned The height of the renedered text.
|
||||
* And also the ones defined in [line].
|
||||
*
|
||||
* [/text]
|
||||
*/
|
||||
|
||||
read_possible_formula(cfg["x"], x_, x_formula_);
|
||||
read_possible_formula(cfg["y"], y_, y_formula_);
|
||||
read_possible_formula(cfg["w"], w_, w_formula_);
|
||||
read_possible_formula(cfg["h"], h_, h_formula_);
|
||||
read_possible_formula(cfg["text"], text_, text_formula_);
|
||||
|
||||
const std::string& debug = (cfg["debug"]);
|
||||
if(!debug.empty()) {
|
||||
DBG_G_P << "Text: found debug message '" << debug << "'.\n";
|
||||
|
@ -617,12 +673,56 @@ tcanvas::ttext::ttext(const vconfig& cfg) :
|
|||
void tcanvas::ttext::draw(surface& canvas,
|
||||
const game_logic::map_formula_callable& variables)
|
||||
{
|
||||
DBG_G_D << "Text: draw at " << x_ << ',' << y_ << " text '"
|
||||
<< text_ << "'.\n";
|
||||
|
||||
assert(variables.has_key("text"));
|
||||
|
||||
// We first need to determine the size of the text which need the rendered
|
||||
// text. So resolve and render the text first and then start to resolve
|
||||
// the other formulas.
|
||||
if(!text_formula_.empty()) {
|
||||
DBG_G_D << "Text: execute text formula '" << text_formula_ << "'.\n";
|
||||
text_ = t_string(game_logic::formula(text_formula_).execute(variables).as_string());
|
||||
}
|
||||
|
||||
SDL_Color col = { (colour_ >> 24), (colour_ >> 16), (colour_ >> 8), colour_ };
|
||||
surface surf(font::get_rendered_text(text_, font_size_, col, TTF_STYLE_NORMAL));
|
||||
|
||||
game_logic::map_formula_callable local_variables(variables);
|
||||
local_variables.add("text_width", variant(surf->w));
|
||||
local_variables.add("text_height", variant(surf->h));
|
||||
|
||||
|
||||
//@todo formulas are now recalculated every draw cycle which is a
|
||||
// bit silly unless there has been a resize. So to optimize we should
|
||||
// use an extra flag or do the calculation in a separate routine.
|
||||
if(!x_formula_.empty()) {
|
||||
DBG_G_D << "Text: execute x formula '" << x_formula_ << "'.\n";
|
||||
x_ = game_logic::formula(x_formula_).execute(local_variables).as_int();
|
||||
}
|
||||
|
||||
if(!y_formula_.empty()) {
|
||||
DBG_G_D << "Text: execute y formula '" << y_formula_ << "'.\n";
|
||||
y_ = game_logic::formula(y_formula_).execute(local_variables).as_int();
|
||||
}
|
||||
|
||||
if(!w_formula_.empty()) {
|
||||
DBG_G_D << "Text: execute width formula '" << w_formula_ << "'.\n";
|
||||
w_ = game_logic::formula(w_formula_).execute(local_variables).as_int();
|
||||
}
|
||||
|
||||
if(!h_formula_.empty()) {
|
||||
DBG_G_D << "Text: execute height formula '" << h_formula_ << "'.\n";
|
||||
h_ = game_logic::formula(h_formula_).execute(local_variables).as_int();
|
||||
}
|
||||
|
||||
DBG_G_D << "Text: drawint text '" << text_
|
||||
<< "' drawn from " << x_ << ',' << y_
|
||||
<< " width " << w_ << " height " << h_
|
||||
<< " canvas size " << canvas->w << ',' << canvas->h << ".\n";
|
||||
|
||||
VALIDATE(x_ < canvas->w && y_ < canvas->h, _("Text doesn't start on canvas."));
|
||||
|
||||
// A text might be to long and will be clipped.
|
||||
if(surf->w > w_) {
|
||||
WRN_G_D << "Text: text is too wide for the canvas and will be clipped.\n";
|
||||
}
|
||||
|
@ -630,18 +730,15 @@ void tcanvas::ttext::draw(surface& canvas,
|
|||
if(surf->h > h_) {
|
||||
WRN_G_D << "Text: text is too high for the canvas and will be clipped.\n";
|
||||
}
|
||||
|
||||
unsigned x_off = (surf->w >= w_) ? 0 : ((w_ - surf->w) / 2);
|
||||
unsigned y_off = (surf->h >= h_) ? 0 : ((h_ - surf->h) / 2);
|
||||
unsigned w_max = w_ - x_ - x_off;
|
||||
unsigned h_max = h_ - y_ - y_off;
|
||||
|
||||
SDL_Rect dst = { x_ + x_off, y_ + y_off, w_max, h_max };
|
||||
|
||||
//FIXME make sure text is rendered properly.
|
||||
//
|
||||
// A hack to make the letters show up a bit readable it does however
|
||||
// clear the back ground. This needs to be fixed but don't want to stall
|
||||
// development too long on it.
|
||||
SDL_SetAlpha(surf, 0, 0);
|
||||
|
||||
SDL_Rect dst = { x_, y_, canvas->w, canvas->h };
|
||||
SDL_BlitSurface(surf, 0, canvas, &dst);
|
||||
}
|
||||
|
||||
|
|
|
@ -154,9 +154,17 @@ public:
|
|||
private:
|
||||
unsigned x_, y_;
|
||||
unsigned w_, h_;
|
||||
|
||||
std::string
|
||||
x_formula_,
|
||||
y_formula_,
|
||||
w_formula_,
|
||||
h_formula_;
|
||||
|
||||
unsigned font_size_;
|
||||
Uint32 colour_;
|
||||
t_string text_;
|
||||
std::string text_formula_;
|
||||
};
|
||||
|
||||
tcanvas();
|
||||
|
@ -175,6 +183,9 @@ public:
|
|||
|
||||
void set_cfg(const config& cfg) { parse_cfg(cfg); }
|
||||
|
||||
void set_variable(const std::string& key, const variant& value)
|
||||
{ variables_.add(key, value); }
|
||||
|
||||
private:
|
||||
void set_dirty(const bool dirty = true) { dirty_ = dirty; }
|
||||
|
||||
|
|
|
@ -67,8 +67,10 @@ twindow build(CVideo& video, const std::string& type)
|
|||
|
||||
const std::string id = definition->grid.widgets[x * cols + y].id;
|
||||
const std::string def = definition->grid.widgets[x * cols + y].definition;
|
||||
const t_string label = definition->grid.widgets[x * cols + y].label;
|
||||
button->set_definition(id);
|
||||
button->set_definition(def);
|
||||
button->set_label(label);
|
||||
window.add_child(button, x, y);
|
||||
|
||||
DBG_G << "Window builder: placed button '" << id << "' with defintion '"
|
||||
|
@ -194,7 +196,8 @@ twindow_builder::tresolution::tgrid::tgrid(const config* cfg) :
|
|||
|
||||
twindow_builder::tresolution::tgrid::twidget::twidget(const config& cfg) :
|
||||
id(cfg["id"]),
|
||||
definition(cfg["button_definition"])
|
||||
definition(cfg["button_definition"]),
|
||||
label(cfg["label"])
|
||||
{
|
||||
|
||||
if(definition.empty()) {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef __GUI_WIDGETS_WINDOW_BUILDER_HPP_INCLUDED__
|
||||
#define __GUI_WIDGETS_WINDOW_BUILDER_HPP_INCLUDED__
|
||||
|
||||
#include "tstring.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -73,6 +74,7 @@ public:
|
|||
|
||||
std::string id;
|
||||
std::string definition;
|
||||
t_string label;
|
||||
};
|
||||
|
||||
std::vector<twidget> widgets;
|
||||
|
|
Loading…
Add table
Reference in a new issue