From: Mikko Rasa Date: Sun, 16 Jun 2013 09:17:17 +0000 (+0300) Subject: Combine common parts of Column and Row into LinearArrangement X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=32539688068fad9614291159b069da10ead10f47;p=libs%2Fgltk.git Combine common parts of Column and Row into LinearArrangement --- diff --git a/source/arrangement.cpp b/source/arrangement.cpp index ec890ef..581e6b4 100644 --- a/source/arrangement.cpp +++ b/source/arrangement.cpp @@ -48,6 +48,30 @@ void Arrangement::add_constraint(Widget &wdg, Layout::ConstraintType type, const 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) diff --git a/source/arrangement.h b/source/arrangement.h index ed1798b..fc3ec82 100644 --- a/source/arrangement.h +++ b/source/arrangement.h @@ -58,6 +58,9 @@ protected: 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 diff --git a/source/column.cpp b/source/column.cpp index 811185d..e7f7095 100644 --- a/source/column.cpp +++ b/source/column.cpp @@ -4,63 +4,12 @@ namespace Msp { 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(c) -{ - add("split", &Loader::split); -} - -void Column::Loader::split() -{ - obj.split(); + layout.set_gravity(wdg, -1, (gravity==BOTTOM ? -1 : 1)); } } // namespace GLtk diff --git a/source/column.h b/source/column.h index b6092bb..75ee1d3 100644 --- a/source/column.h +++ b/source/column.h @@ -1,38 +1,18 @@ #ifndef MSP_GLTK_COLUMN_H_ #define MSP_GLTK_COLUMN_H_ -#include -#include "arrangement.h" +#include "lineararrangement.h" namespace Msp { namespace GLtk { -class Column: public Arrangement +class Column: public LinearArrangement { -public: - class Loader: public DataFile::ObjectLoader - { - 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 diff --git a/source/lineararrangement.cpp b/source/lineararrangement.cpp new file mode 100644 index 0000000..891b858 --- /dev/null +++ b/source/lineararrangement.cpp @@ -0,0 +1,64 @@ +#include "lineararrangement.h" + +namespace Msp { +namespace GLtk { + +LinearArrangement::LinearArrangement(Layout &l, Side p): + Arrangement(l), + primary(p), + opposite(static_cast((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(c) +{ + add("split", &Loader::split); +} + +void LinearArrangement::Loader::split() +{ + obj.split(); +} + +} // namespace GLtk +} // namespace Msp diff --git a/source/lineararrangement.h b/source/lineararrangement.h new file mode 100644 index 0000000..571e279 --- /dev/null +++ b/source/lineararrangement.h @@ -0,0 +1,43 @@ +#ifndef MSP_GLTK_LINEARARRANGEMENT_H_ +#define MSP_GLTK_LINEARARRANGEMENT_H_ + +#include +#include "arrangement.h" + +namespace Msp { +namespace GLtk { + +class LinearArrangement: public Arrangement +{ +public: + class Loader: public DataFile::ObjectLoader + { + 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 diff --git a/source/row.cpp b/source/row.cpp index 92f3fe6..0188f4a 100644 --- a/source/row.cpp +++ b/source/row.cpp @@ -4,63 +4,12 @@ namespace Msp { 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(c) -{ - add("split", &Loader::split); -} - -void Row::Loader::split() -{ - obj.split(); + layout.set_gravity(wdg, (gravity==LEFT ? -1 : 1), 1); } } // namespace GLtk diff --git a/source/row.h b/source/row.h index 58480db..4bf2d38 100644 --- a/source/row.h +++ b/source/row.h @@ -1,38 +1,18 @@ #ifndef MSP_GLTK_ROW_H_ #define MSP_GLTK_ROW_H_ -#include -#include "arrangement.h" +#include "lineararrangement.h" namespace Msp { namespace GLtk { -class Row: public Arrangement +class Row: public LinearArrangement { -public: - class Loader: public DataFile::ObjectLoader - { - 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