first = false;
}
+
+Column::Loader::Loader(Column &c):
+ DataFile::ObjectLoader<Column>(c)
+{
+ add("split", &Loader::split);
+}
+
+void Column::Loader::split()
+{
+ obj.split();
+}
+
} // namespace GLtk
} // namespace Msp
#ifndef MSP_GLTK_COLUMN_H_
#define MSP_GLTK_COLUMN_H_
+#include <msp/datafile/objectloader.h>
#include "arrangement.h"
namespace Msp {
class Column: public Arrangement
{
+public:
+ class Loader: public DataFile::ObjectLoader<Column>
+ {
+ public:
+ Loader(Column &);
+ private:
+ void split();
+ };
+
private:
Edge next_bottom;
bool first;
RefPtr<Button> btn = new Button();
load_sub(*btn);
obj.add_button(*btn.get(), c);
- wdg_map[n] = btn.release();
+ last_widget = wdg_map[n] = btn.release();
}
} // namespace GLtk
column = 0;
}
+
+Grid::Loader::Loader(Grid &g):
+ DataFile::ObjectLoader<Grid>(g)
+{
+ add("next_row", &Loader::next_row);
+ add("skip", &Loader::skip);
+}
+
+void Grid::Loader::next_row()
+{
+ obj.next_row();
+}
+
+void Grid::Loader::skip()
+{
+ obj.skip();
+}
+
} // namespace GLtk
} // namespace Msp
#ifndef MSP_GLTK_GRID_H_
#define MSP_GLTK_GRID_H_
+#include <msp/datafile/objectloader.h>
#include "arrangement.h"
namespace Msp {
class Grid: public Arrangement
{
+public:
+ class Loader: public DataFile::ObjectLoader<Grid>
+ {
+ public:
+ Loader(Grid &);
+ private:
+ void next_row();
+ void skip();
+ };
+
private:
struct Column
{
#include <algorithm>
#include <limits>
+#include <msp/strings/format.h>
#include "arrangement.h"
#include "container.h"
#include "layout.h"
}
+void operator>>(const LexicalConverter &conv, Layout::ConstraintType &ctype)
+{
+ const string &str = conv.get();
+ if(str=="ABOVE")
+ ctype = Layout::ABOVE;
+ else if(str=="BELOW")
+ ctype = Layout::BELOW;
+ else if(str=="RIGHT_OF")
+ ctype = Layout::RIGHT_OF;
+ else if(str=="LEFT_OF")
+ ctype = Layout::LEFT_OF;
+ else if(str=="FAR_ABOVE")
+ ctype = Layout::FAR_ABOVE;
+ else if(str=="FAR_BELOW")
+ ctype = Layout::FAR_BELOW;
+ else if(str=="FAR_RIGHT_OF")
+ ctype = Layout::FAR_RIGHT_OF;
+ else if(str=="FAR_LEFT_OF")
+ ctype = Layout::FAR_LEFT_OF;
+ else if(str=="ALIGN_TOP")
+ ctype = Layout::ALIGN_TOP;
+ else if(str=="ALIGN_BOTTOM")
+ ctype = Layout::ALIGN_BOTTOM;
+ else if(str=="ALIGN_RIGHT")
+ ctype = Layout::ALIGN_RIGHT;
+ else if(str=="ALIGN_LEFT")
+ ctype = Layout::ALIGN_LEFT;
+ else if(str=="COPY_WIDTH")
+ ctype = Layout::COPY_WIDTH;
+ else if(str=="COPY_HEIGHT")
+ ctype = Layout::COPY_HEIGHT;
+ else
+ throw lexical_error(format("conversion of '%s' to ConstraintType", str));
+}
+
+
Layout::LinearProgram::LinearProgram(unsigned s):
n_columns(s),
n_rows(1),
#include <list>
#include <set>
#include <sigc++/trackable.h>
+#include <msp/strings/lexicalcast.h>
#include "geometry.h"
namespace Msp {
void solve_constraints(int, SolveMode);
};
+void operator>>(const LexicalConverter &, Layout::ConstraintType &);
+
} // namespace GLtk
} // namespace Msp
#include <algorithm>
+#include <msp/core/maputils.h>
#include <msp/core/refptr.h>
#include "button.h"
+#include "column.h"
#include "dropdown.h"
#include "entry.h"
+#include "grid.h"
#include "hslider.h"
#include "indicator.h"
#include "label.h"
-#include "layout.h"
#include "list.h"
#include "panel.h"
#include "part.h"
+#include "row.h"
#include "toggle.h"
#include "vslider.h"
Panel::Loader::Loader(Panel &p, map<string, Widget *> &m):
DataFile::DerivedObjectLoader<Panel, Widget::Loader>(p),
- wdg_map(m)
+ wdg_map(m),
+ last_widget(0)
{
add("button", &Loader::child<Button>);
+ add("column", &Loader::arrangement<Column>);
+ add("constraint",&Loader::constraint);
add("dropdown", &Loader::child<Dropdown>);
add("entry", &Loader::child<Entry>);
+ add("expand", &Loader::expand);
+ add("gravity", &Loader::gravity);
+ add("grid", &Loader::grid);
add("hslider", &Loader::child<HSlider>);
add("indicator", &Loader::child<Indicator>);
add("label", &Loader::child<Label>);
add("list", &Loader::child<List>);
add("panel", &Loader::panel);
+ add("row", &Loader::arrangement<Row>);
add("toggle", &Loader::child<Toggle>);
add("vslider", &Loader::child<VSlider>);
}
+Layout &Panel::Loader::get_layout()
+{
+ if(!obj.layout)
+ obj.set_layout(new Layout);
+
+ return *obj.layout;
+}
+
+Widget &Panel::Loader::get_last_widget()
+{
+ if(!last_widget)
+ throw logic_error("no widget loaded");
+
+ return *last_widget;
+}
+
+template<typename T>
+void Panel::Loader::arrangement()
+{
+ T arr(get_layout());
+ ArrangedLoader<T> ldr(*this, arr);
+ load_sub_with(ldr);
+}
+
template<typename T>
void Panel::Loader::child(const string &n)
{
RefPtr<T> chl = new T();
load_sub(*chl);
obj.add(*chl.get());
- wdg_map[n] = chl.release();
+ last_widget = wdg_map[n] = chl.release();
+}
+
+void Panel::Loader::constraint(Layout::ConstraintType type, const string &n)
+{
+ Widget &src = get_last_widget();
+ Widget &tgt = *get_item(wdg_map, n);
+ get_layout().add_constraint(src, type, tgt);
+}
+
+void Panel::Loader::expand(bool h, bool v)
+{
+ get_layout().set_expand(get_last_widget(), h, v);
+}
+
+void Panel::Loader::gravity(int h, int v)
+{
+ get_layout().set_gravity(get_last_widget(), h, v);
+}
+
+void Panel::Loader::grid(unsigned cols)
+{
+ Grid grd(get_layout(), cols);
+ ArrangedLoader<Grid> ldr(*this, grd);
+ load_sub_with(ldr);
}
void Panel::Loader::panel(const string &n)
RefPtr<Panel> p = new Panel();
load_sub(*p, wdg_map);
obj.add(*p.get());
- wdg_map[n] = p.release();
+ last_widget = wdg_map[n] = p.release();
+}
+
+
+template<typename T>
+Panel::ArrangedLoader<T>::ArrangedLoader(Loader &ldr, T &arr):
+ arr_loader(arr)
+{
+ add_auxiliary_loader(ldr);
+ add_auxiliary_loader(arr_loader);
}
} // namespace GLtk
#define MSP_GLTK_PANEL_H_
#include "container.h"
+#include "layout.h"
namespace Msp {
namespace GLtk {
-class Layout;
-
/**
Panels are containers for other widgets. Panel styles should have a special
part "children" to render the child widgets. All properties of this part are
protected:
WidgetMap &wdg_map;
+ Widget *last_widget;
public:
Loader(Panel &, WidgetMap &);
private:
+ Layout &get_layout();
+ Widget &get_last_widget();
+ template<typename T>
+ void arrangement();
template<typename T>
void child(const std::string &);
+ void constraint(Layout::ConstraintType, const std::string &);
+ void expand(bool, bool);
+ void gravity(int, int);
+ void grid(unsigned);
void panel(const std::string &);
};
+private:
+ template<typename T>
+ class ArrangedLoader: public DataFile::Loader
+ {
+ private:
+ typename T::Loader arr_loader;
+
+ public:
+ ArrangedLoader(Loader &, T &);
+ };
+
protected:
Layout *layout;
first = false;
}
+
+Row::Loader::Loader(Row &c):
+ DataFile::ObjectLoader<Row>(c)
+{
+ add("split", &Loader::split);
+}
+
+void Row::Loader::split()
+{
+ obj.split();
+}
+
} // namespace GLtk
} // namespace Msp
#ifndef MSP_GLTK_ROW_H_
#define MSP_GLTK_ROW_H_
+#include <msp/datafile/objectloader.h>
#include "arrangement.h"
namespace Msp {
class Row: public Arrangement
{
+public:
+ class Loader: public DataFile::ObjectLoader<Row>
+ {
+ public:
+ Loader(Row &);
+ private:
+ void split();
+ };
+
private:
Edge next_right;
bool first;