layout.add_constraint(wdg, type, **i);
}
+Layout::ConstraintType Arrangement::get_order_constraint(Side s, bool slack)
+{
+ switch(s)
+ {
+ case TOP: return (slack ? Layout::FAR_ABOVE : Layout::ABOVE);
+ case RIGHT: return (slack ? Layout::FAR_RIGHT_OF : Layout::RIGHT_OF);
+ case BOTTOM: return (slack ? Layout::FAR_BELOW : Layout::BELOW);
+ case LEFT: return (slack ? Layout::FAR_LEFT_OF : Layout::LEFT_OF);
+ default: throw invalid_argument("Arrangement::get_align_constraint");
+ }
+}
+
+Layout::ConstraintType Arrangement::get_align_constraint(Side s)
+{
+ switch(s)
+ {
+ case TOP: return Layout::ALIGN_TOP;
+ case RIGHT: return Layout::ALIGN_RIGHT;
+ case BOTTOM: return Layout::ALIGN_BOTTOM;
+ case LEFT: return Layout::ALIGN_LEFT;
+ default: throw invalid_argument("Arrangement::get_align_constraint");
+ }
+}
+
Arrangement::Edge::Edge():
aligned(false)
const Edge &get_edge(Side s) const { return edges[s]; }
void add_constraint(Widget &, Layout::ConstraintType, Side);
void add_constraint(Widget &, Layout::ConstraintType, const Edge &);
+
+ static Layout::ConstraintType get_order_constraint(Side, bool);
+ static Layout::ConstraintType get_align_constraint(Side);
};
} // namespace GLtk
namespace GLtk {
Column::Column(Layout &l):
- Arrangement(l),
- first(true),
- split_here(false),
- gravity(1)
+ LinearArrangement(l, BOTTOM)
{ }
-void Column::split()
-{
- if(gravity<0)
- throw arrangement_error("already split");
-
- split_here = true;
- gravity = -1;
-}
-
-void Column::process_widget(Widget &wdg, Side side, bool aligned)
-{
- if(side==TOP)
- {
- bool snug = (edges[BOTTOM].aligned && aligned && !split_here);
- add_constraint(wdg, (snug ? Layout::BELOW : Layout::FAR_BELOW), BOTTOM);
- if(first)
- edges[TOP].add(wdg, aligned);
- }
- else if(side==BOTTOM)
- next_bottom.add(wdg, (aligned && gravity<0));
- else
- {
- if(edges[side].aligned && aligned)
- add_constraint(wdg, (side==LEFT ? Layout::ALIGN_LEFT : Layout::ALIGN_RIGHT), side);
- edges[side].add(wdg, aligned);
- }
-}
-
void Column::finish_widget(Widget &wdg)
{
- layout.set_gravity(wdg, -1, gravity);
-}
-
-void Column::finish_slot()
-{
- edges[BOTTOM] = next_bottom;
- next_bottom.clear();
- split_here = false;
- first = false;
-}
-
-
-Column::Loader::Loader(Column &c):
- DataFile::ObjectLoader<Column>(c)
-{
- add("split", &Loader::split);
-}
-
-void Column::Loader::split()
-{
- obj.split();
+ layout.set_gravity(wdg, -1, (gravity==BOTTOM ? -1 : 1));
}
} // namespace GLtk
#ifndef MSP_GLTK_COLUMN_H_
#define MSP_GLTK_COLUMN_H_
-#include <msp/datafile/objectloader.h>
-#include "arrangement.h"
+#include "lineararrangement.h"
namespace Msp {
namespace GLtk {
-class Column: public Arrangement
+class Column: public LinearArrangement
{
-public:
- class Loader: public DataFile::ObjectLoader<Column>
- {
- public:
- Loader(Column &);
- private:
- void split();
- };
-
-private:
- Edge next_bottom;
- bool first;
- bool split_here;
- int gravity;
-
public:
Column(Layout &);
- void split();
-
private:
- virtual void process_widget(Widget &, Side, bool);
virtual void finish_widget(Widget &);
- virtual void finish_slot();
};
} // namespace GLtk
--- /dev/null
+#include "lineararrangement.h"
+
+namespace Msp {
+namespace GLtk {
+
+LinearArrangement::LinearArrangement(Layout &l, Side p):
+ Arrangement(l),
+ primary(p),
+ opposite(static_cast<Side>((primary+2)%4)),
+ first(true),
+ split_here(false),
+ gravity(opposite)
+{ }
+
+void LinearArrangement::split()
+{
+ if(gravity==primary)
+ throw arrangement_error("already split");
+
+ split_here = true;
+ gravity = primary;
+}
+
+void LinearArrangement::process_widget(Widget &wdg, Side side, bool aligned)
+{
+ if(side==opposite)
+ {
+ bool snug = (edges[primary].aligned && aligned && !split_here);
+ add_constraint(wdg, get_order_constraint(primary, !snug), primary);
+ if(first)
+ edges[side].add(wdg, aligned);
+ }
+ else if(side==primary)
+ next.add(wdg, (aligned && gravity==primary));
+ else
+ {
+ if(edges[side].aligned && aligned)
+ add_constraint(wdg, get_align_constraint(side), side);
+ edges[side].add(wdg, aligned);
+ }
+}
+
+void LinearArrangement::finish_slot()
+{
+ edges[primary] = next;
+ next.clear();
+ split_here = false;
+ first = false;
+}
+
+
+LinearArrangement::Loader::Loader(LinearArrangement &c):
+ DataFile::ObjectLoader<LinearArrangement>(c)
+{
+ add("split", &Loader::split);
+}
+
+void LinearArrangement::Loader::split()
+{
+ obj.split();
+}
+
+} // namespace GLtk
+} // namespace Msp
--- /dev/null
+#ifndef MSP_GLTK_LINEARARRANGEMENT_H_
+#define MSP_GLTK_LINEARARRANGEMENT_H_
+
+#include <msp/datafile/objectloader.h>
+#include "arrangement.h"
+
+namespace Msp {
+namespace GLtk {
+
+class LinearArrangement: public Arrangement
+{
+public:
+ class Loader: public DataFile::ObjectLoader<LinearArrangement>
+ {
+ public:
+ Loader(LinearArrangement &);
+ private:
+ void split();
+ };
+
+protected:
+ Side primary;
+ Side opposite;
+ Edge next;
+ bool first;
+ bool split_here;
+ Side gravity;
+
+ LinearArrangement(Layout &, Side);
+
+public:
+ void split();
+ void expand();
+
+protected:
+ virtual void process_widget(Widget &, Side, bool);
+ virtual void finish_slot();
+};
+
+} // namespace GLtk
+} // namespace Msp
+
+#endif
namespace GLtk {
Row::Row(Layout &l):
- Arrangement(l),
- first(true),
- split_here(false),
- gravity(-1)
+ LinearArrangement(l, RIGHT)
{ }
-void Row::split()
-{
- if(gravity>0)
- throw arrangement_error("already split");
-
- split_here = true;
- gravity = 1;
-}
-
-void Row::process_widget(Widget &wdg, Side side, bool aligned)
-{
- if(side==LEFT)
- {
- bool snug = (edges[RIGHT].aligned && aligned && !split_here);
- add_constraint(wdg, (snug ? Layout::RIGHT_OF : Layout::FAR_RIGHT_OF), RIGHT);
- if(first)
- edges[LEFT].add(wdg, aligned);
- }
- else if(side==RIGHT)
- next_right.add(wdg, (aligned && gravity>0));
- else
- {
- if(edges[side].aligned && aligned)
- add_constraint(wdg, (side==TOP ? Layout::ALIGN_TOP : Layout::ALIGN_BOTTOM), side);
- edges[side].add(wdg, aligned);
- }
-}
-
void Row::finish_widget(Widget &wdg)
{
- layout.set_gravity(wdg, gravity, 1);
-}
-
-void Row::finish_slot()
-{
- edges[RIGHT] = next_right;
- next_right.clear();
- split_here = false;
- first = false;
-}
-
-
-Row::Loader::Loader(Row &c):
- DataFile::ObjectLoader<Row>(c)
-{
- add("split", &Loader::split);
-}
-
-void Row::Loader::split()
-{
- obj.split();
+ layout.set_gravity(wdg, (gravity==LEFT ? -1 : 1), 1);
}
} // namespace GLtk
#ifndef MSP_GLTK_ROW_H_
#define MSP_GLTK_ROW_H_
-#include <msp/datafile/objectloader.h>
-#include "arrangement.h"
+#include "lineararrangement.h"
namespace Msp {
namespace GLtk {
-class Row: public Arrangement
+class Row: public LinearArrangement
{
-public:
- class Loader: public DataFile::ObjectLoader<Row>
- {
- public:
- Loader(Row &);
- private:
- void split();
- };
-
-private:
- Edge next_right;
- bool first;
- bool split_here;
- int gravity;
-
public:
Row(Layout &);
- void split();
-
private:
- virtual void process_widget(Widget &, Side, bool);
virtual void finish_widget(Widget &);
- virtual void finish_slot();
};
} // namespace GLtk