namespace Msp {
namespace GLtk {
-Button::Button(const Resources &r, const std::string &t):
- Widget(r),
+Button::Button(const std::string &t):
text(),
icon(0),
pressed(false)
{
- update_style();
set_text(t);
}
public:
sigc::signal<void> signal_clicked;
- Button(const Resources &, const std::string & =std::string());
+ Button(const std::string & = std::string());
+
void set_text(const std::string &);
void set_icon(const GL::Texture2D *);
virtual void button_press(int, int, unsigned);
namespace Msp {
namespace GLtk {
-Container::Container(const Resources &r):
- Widget(r),
+Container::Container():
click_focus(0),
click_button(0)
{ }
return new Child(*this, wdg);
}
+void Container::on_reparent()
+{
+ for(list<Child *>::iterator i=children.begin(); i!=children.end(); ++i)
+ {
+ if(Container *c = dynamic_cast<Container *>((*i)->widget))
+ c->on_reparent();
+ update_style(*(*i)->widget);
+ }
+}
+
Container::Child::Child(Container &c, Widget *w):
container(c),
Widget *click_focus;
unsigned click_button;
- Container(const Resources &);
+ Container();
public:
virtual ~Container();
virtual void pointer_leave();
protected:
virtual Child *create_child(Widget *);
+ virtual void on_reparent();
};
} // namespace GLtk
namespace Msp {
namespace GLtk {
-Dialog::Dialog(const Resources &r):
- Widget(r),
- Panel(r),
+Dialog::Dialog():
stale(false)
{ }
public:
sigc::signal<void, int> signal_response;
- Dialog(const Resources &);
+ Dialog();
/** Adds an action button to the dialog. Pressing the button will invoke
response handlers and delete the dialog. */
namespace Msp {
namespace GLtk {
-Dropdown::Dropdown(const Resources &r):
- Widget(r),
- Container(r),
- list(r),
+Dropdown::Dropdown():
dropped(false)
{
add(list);
list.signal_item_selected.connect(sigc::mem_fun(this, &Dropdown::list_item_selected));
-
- update_style();
}
void Dropdown::append(const string &item)
resize_list();
}
+void Dropdown::on_style_change()
+{
+ resize_list();
+}
+
void Dropdown::resize_list()
{
list.autosize();
public:
sigc::signal<void, int, const std::string &> signal_item_selected;
- Dropdown(const Resources &);
+ Dropdown();
void append(const std::string &);
void insert(unsigned, const std::string &);
virtual void render_special(const Part &) const;
virtual void on_geometry_change();
+ virtual void on_style_change();
void resize_list();
void list_item_selected(unsigned, const std::string &);
namespace Msp {
namespace GLtk {
-Entry::Entry(const Resources &r, const string &t):
- Widget(r),
- Container(r),
+Entry::Entry(const string &t):
text(),
multiline(false),
edit_pos(0),
text_part(0),
slider(0)
{
- update_style();
set_text(t);
}
{
if(!slider)
{
- slider = new VSlider(res);
+ slider = new VSlider;
add(*slider);
slider->set_step(1);
slider->signal_value_changed.connect(sigc::mem_fun(this, &Entry::slider_value_changed));
void Entry::on_style_change()
{
+ text.set_style(style);
+
+ if(!style)
+ {
+ text_part = 0;
+ return;
+ }
+
text_part = style->get_part("text");
- text.set_style(style);
reposition_slider();
if(multiline)
void Entry::reposition_slider()
{
- if(!slider)
+ if(!style || !slider)
return;
if(const Part *slider_part = style->get_part("slider"))
public:
sigc::signal<void> signal_enter;
- Entry(const Resources &, const std::string & =std::string());
+ Entry(const std::string & = std::string());
void set_text(const std::string &);
const std::string &get_text() const { return text.get(); }
namespace Msp {
namespace GLtk {
-HSlider::HSlider(const Resources &r):
- Slider(r)
-{
- update_style();
-}
+HSlider::HSlider():
+ slider_size(1)
+{ }
void HSlider::button_press(int x, int y, unsigned btn)
{
void HSlider::on_style_change()
{
+ if(!style)
+ return;
+
if(const Part *slider_part = style->get_part("slider"))
slider_size = slider_part->get_geometry().w;
unsigned slider_size;
public:
- HSlider(const Resources &);
+ HSlider();
virtual void button_press(int, int, unsigned);
virtual void button_release(int, int, unsigned);
virtual void pointer_motion(int, int);
namespace Msp {
namespace GLtk {
-Image::Image(const Resources &r, const GL::Texture2D *i):
- Widget(r),
+Image::Image(const GL::Texture2D *i):
image(i),
keep_aspect(true)
{
focusable = false;
- update_style();
}
void Image::set_image(const GL::Texture2D *i)
bool keep_aspect;
public:
- Image(const Resources &, const GL::Texture2D * = 0);
+ Image(const GL::Texture2D * = 0);
void set_image(const GL::Texture2D *);
void set_keep_aspect(bool);
namespace Msp {
namespace GLtk {
-Indicator::Indicator(const Resources &r):
- Widget(r)
+Indicator::Indicator()
{
focusable = false;
- update_style();
}
void Indicator::set_active(bool a)
class Indicator: public Widget
{
public:
- Indicator(const Resources &);
+ Indicator();
void set_active(bool);
private:
virtual const char *get_class() const { return "indicator"; }
namespace Msp {
namespace GLtk {
-Label::Label(const Resources &r, const string &t):
- Widget(r),
- text()
+Label::Label(const string &t)
{
focusable = false;
- update_style();
set_text(t);
}
void Label::autosize()
{
+ if(!style)
+ return;
+
geom.h = text.get_height();
geom.w = text.get_width();
if(const Part *text_part = style->get_part("text"))
Text text;
public:
- Label(const Resources &, const std::string & =std::string());
+ Label(const std::string & = std::string());
virtual void autosize();
void set_text(const std::string &);
namespace Msp {
namespace GLtk {
-List::List(const Resources &r):
- Widget(r),
- Container(r),
+List::List():
sel_index(-1),
first(0),
n_visible(1),
row_height(1),
- items_part(0),
- slider(res)
+ items_part(0)
{
add(slider);
slider.set_step(1);
slider.signal_value_changed.connect(sigc::mem_fun(this, &List::slider_value_changed));
-
- update_style();
}
void List::autosize()
{
+ if(!style)
+ return;
+
float font_size = style->get_font()->get_default_size();
geom.w = 0;
void List::on_style_change()
{
+ if(!style)
+ {
+ items_part = 0;
+ return;
+ }
+
reposition_slider();
items_part = style->get_part("items");
void List::reposition_slider()
{
+ if(!style)
+ return;
+
if(const Part *slider_part = style->get_part("slider"))
{
Geometry sgeom = slider_part->get_geometry();
public:
sigc::signal<void, unsigned, const std::string &> signal_item_selected;
- List(const Resources &);
+ List();
virtual void autosize();
namespace Msp {
namespace GLtk {
-Panel::Panel(const Resources &r):
- Widget(r),
- Container(r),
+Panel::Panel():
pointer_focus(0),
pointer_grabbed(false),
input_focus(0)
-{
- update_style();
-}
+{ }
void Panel::raise(Widget &wdg)
{
template<typename T>
void Panel::Loader::child(const string &n)
{
- RefPtr<T> chl = new T(pnl.res);
+ RefPtr<T> chl = new T();
load_sub(*chl);
pnl.add(*chl.get());
wdg_map[n] = chl.release();
void Panel::Loader::panel(const string &n)
{
- RefPtr<Panel> p = new Panel(pnl.res);
+ RefPtr<Panel> p = new Panel();
load_sub(*p, wdg_map);
pnl.add(*p.get());
wdg_map[n] = p.release();
Panel(const Panel &);
Panel &operator=(const Panel &);
public:
- Panel(const Resources &);
+ Panel();
void raise(Widget &);
Widget *get_input_focus() const { return input_focus; }
namespace GLtk {
Root::Root(const Resources &r, Graphics::Window &w):
- Widget(r),
- Panel(r),
+ resources(r),
window(w),
lbl_tooltip(0),
tooltip_target(0)
{
if(!lbl_tooltip)
{
- lbl_tooltip = new Label(res);
+ lbl_tooltip = new Label;
add(*lbl_tooltip);
lbl_tooltip->set_style("tooltip");
}
sigc::signal<std::string, int, int> signal_tooltip;
private:
+ const Resources &resources;
Graphics::Window &window;
Label *lbl_tooltip;
int pointer_x;
Root(const Resources &, Graphics::Window &);
void tick();
+ const Resources &get_resources() const { return resources; }
virtual unsigned get_width() const { return geom.w; }
virtual unsigned get_height() const { return geom.h; }
namespace Msp {
namespace GLtk {
-Slider::Slider(const Resources &r):
- Widget(r),
+Slider::Slider():
min(0),
max(1),
value(0),
sigc::signal<void, double> signal_value_changed;
protected:
- Slider(const Resources &);
+ Slider();
public:
void set_value(double);
void set_range(double, double);
namespace Msp {
namespace GLtk {
-Table::Table(const Resources &r):
- Widget(r),
+Table::Table():
rows(1),
columns(1),
data(1),
col_w(1)
{
focusable = false;
- update_style();
}
void Table::set_rows(unsigned r)
std::vector<unsigned> col_w;
public:
- Table(const Resources &);
+ Table();
void set_rows(unsigned);
void set_columns(unsigned);
{
style = s;
- float font_size = style->get_font()->get_default_size();
- for(vector<Line>::iterator i=lines.begin(); i!=lines.end(); ++i)
- i->width = static_cast<unsigned>(style->get_font()->get_string_width(text.substr(i->start, i->length))*font_size);
+ if(style)
+ {
+ float font_size = style->get_font()->get_default_size();
+ for(vector<Line>::iterator i=lines.begin(); i!=lines.end(); ++i)
+ i->width = static_cast<unsigned>(style->get_font()->get_string_width(text.substr(i->start, i->length))*font_size);
+ }
}
unsigned Text::get_width() const
unsigned Text::get_height() const
{
+ if(!style)
+ return lines.size();
+
const GL::Font *font = style->get_font();
float font_size = font->get_default_size();
unsigned line_height = static_cast<unsigned>((font->get_ascent()-font->get_descent())*font_size);
void Text::render(const Part &part, const Geometry &parent, unsigned first_row) const
{
- if(lines.empty())
+ if(!style || lines.empty())
return;
const GL::Color &color = style->get_font_color();
void Text::find_lines()
{
lines.clear();
- float font_size = style->get_font()->get_default_size();
+ float font_size = (style ? style->get_font()->get_default_size() : 1);
string::size_type start = 0;
while(1)
{
Line line;
line.start = start;
line.length = (newline==string::npos ? text.size() : newline)-start;
- line.width = static_cast<unsigned>(style->get_font()->get_string_width(text.substr(line.start, line.length))*font_size);
+ line.width = line.length;
+ if(style)
+ {
+ string str = text.substr(line.start, line.length);
+ line.width = static_cast<unsigned>(style->get_font()->get_string_width(str)*font_size);
+ }
lines.push_back(line);
if(newline==string::npos)
template<typename T, void (Text::*func)(unsigned, const Geometry &, T &) const>
void Text::process_lines(const Part &part, const Geometry &parent, unsigned first_row, T &data) const
{
+ if(!style)
+ return;
+
const GL::Font *font = style->get_font();
float font_size = font->get_default_size();
unsigned line_height = static_cast<unsigned>((font->get_ascent()-font->get_descent())*font_size);
int y_offset = static_cast<int>(-font->get_descent()*font_size);
const Sides &margin = part.get_margin();
- unsigned n_lines = max(min(lines.size(), (parent.h-margin.top-margin.bottom)/line_spacing), 1U);
+ unsigned n_lines = min(lines.size(), max((parent.h-margin.top-margin.bottom)/line_spacing, 1U));
first_row = min(first_row, lines.size()-n_lines);
for(unsigned i=0; i<n_lines; ++i)
namespace Msp {
namespace GLtk {
-Toggle::Toggle(const Resources &r, const string &t):
- Widget(r),
+Toggle::Toggle(const string &t):
text(),
pressed(false),
value(false),
exclusive(false)
{
- update_style();
set_text(t);
}
public:
sigc::signal<void, bool> signal_toggled;
- Toggle(const Resources &, const std::string & =std::string());
+ Toggle(const std::string & = std::string());
void set_text(const std::string &);
void set_exclusive(bool);
namespace Msp {
namespace GLtk {
-VSlider::VSlider(const Resources &r):
- Slider(r)
+VSlider::VSlider():
+ slider_size(1)
{
- update_style();
}
void VSlider::button_press(int x, int y, unsigned btn)
void VSlider::on_style_change()
{
+ if(!style)
+ return;
+
if(const Part *slider_part = style->get_part("slider"))
slider_size = slider_part->get_geometry().h;
unsigned slider_size;
public:
- VSlider(const Resources &);
+ VSlider();
virtual void button_press(int, int, unsigned);
virtual void button_release(int, int, unsigned);
virtual void pointer_motion(int, int);
#include <msp/gl/matrix.h>
#include <msp/gl/transform.h>
#include <msp/strings/formatter.h>
-#include "panel.h"
+#include "container.h"
#include "resources.h"
+#include "root.h"
#include "widget.h"
using namespace std;
namespace Msp {
namespace GLtk {
-Widget::Widget(const Resources &r):
- res(r),
+Widget::Widget():
style(0),
state(NORMAL),
visible(true),
void Widget::render() const
{
if(!style)
- throw InvalidState(format("Attempt to render a widget without a style (class=\"%s\")", get_class()));
+ throw InvalidState(format("Attempt to render a widget with null style (class=\"%s\", style_name=\"%s\")", get_class(), style_name));
GL::push_matrix();
GL::translate(geom.x, geom.y, 0);
void Widget::update_style()
{
- string sname = get_class();
- if(!style_name.empty())
+ Widget *top;
+ for(top=this; top->parent; top=top->parent) ;
+ Root *root = dynamic_cast<Root *>(top);
+ if(!root)
+ style = 0;
+ else
{
- sname += '-';
- sname += style_name;
+ string sname = get_class();
+ if(!style_name.empty())
+ {
+ sname += '-';
+ sname += style_name;
+ }
+
+ style = root->get_resources().get<Style>(sname);
}
- style = res.get<Style>(sname);
+
on_style_change();
}
+void Widget::update_style(Widget &w)
+{
+ w.update_style();
+}
+
void Widget::set_parent(Container *p)
{
if(parent && p)
parent = p;
on_reparent();
+ update_style();
}
void Widget::set_parent(Widget &w, Container *p)
sigc::signal<void> signal_ungrab_pointer;
protected:
- const Resources &res;
Geometry geom;
std::string style_name;
const Style *style;
Container *parent;
std::string tooltip;
- Widget(const Resources &);
+ Widget();
public:
virtual ~Widget();
*/
void update_style();
+ static void update_style(Widget &);
+
/**
Sets the widget's parent Panel. The widget must be unparented when calling
this function with a nonzero parameter.
/**
A helper function to set the parent of another widget.
*/
- void set_parent(Widget &, Container *);
+ static void set_parent(Widget &, Container *);
// More events
virtual void on_geometry_change() { }