]> git.tdb.fi Git - libs/gltk.git/blobdiff - source/layout.h
Add getters for layout margin and spacings
[libs/gltk.git] / source / layout.h
index 379b468bf3f46efe30b37de4165081f8731e8d83..9c4e2a07e6525b73e15783c0df17d397f739ad1d 100644 (file)
@@ -4,11 +4,13 @@
 #include <list>
 #include <set>
 #include <sigc++/trackable.h>
 #include <list>
 #include <set>
 #include <sigc++/trackable.h>
+#include <msp/strings/lexicalcast.h>
 #include "geometry.h"
 
 namespace Msp {
 namespace GLtk {
 
 #include "geometry.h"
 
 namespace Msp {
 namespace GLtk {
 
+class Arrangement;
 class Container;
 class Widget;
 
 class Container;
 class Widget;
 
@@ -20,11 +22,11 @@ is then solved to obtain positions and dimensions that fulfill the constraints.
 There are three kinds of constraints available: ordering, alignment and
 dimension matching.
 
 There are three kinds of constraints available: ordering, alignment and
 dimension matching.
 
-Ordering constraints specify that the widgets should be placed next to other
-along X or Y axis.  These operate on one axis at a time, so a widget could be
-"right of" another even if they are separated by hundreds of pixels vertically.
-The widgets will be separated by a spacing value, which is settable on a per-
-layout basis.
+Ordering constraints specify that the widgets should be placed next to each
+other along X or Y axis.  These operate on one axis at a time, so a widget
+could be "right of" another even if they are separated by hundreds of pixels
+vertically.  The widgets will be separated by a spacing value, which is
+settable on a per-layout basis.
 
 Alignment constraints make the corresponding edges of two widgets be on the
 same line.  These are incompatible with ordering constraints, so only one or
 
 Alignment constraints make the corresponding edges of two widgets be on the
 same line.  These are incompatible with ordering constraints, so only one or
@@ -44,9 +46,9 @@ flag for a widget causes it to use as much space as possible.  If multiple co-
 dependent widgets have the expand flag set, the results are currently
 undefined.
 
 dependent widgets have the expand flag set, the results are currently
 undefined.
 
-Since specifiyng constraints manually can be quite tedious, there are some
-derived Layout classes that implement common positioning patterns.  See
-MixedRows and Grid.
+Since specifiyng constraints manually can be quite tedious, an Arrangement
+interface is provided to automatically arrange widgets.  See classes Row,
+Column and Grid for some commonly used arrangements.
 */
 class Layout
 {
 */
 class Layout
 {
@@ -57,9 +59,12 @@ private:
                VERTICAL = 1,
                SELF_POS = 2,
                SELF_DIM = 4,
                VERTICAL = 1,
                SELF_POS = 2,
                SELF_DIM = 4,
+               SELF_MASK = 6,
                TARGET_POS = 8,
                TARGET_DIM = 16,
                TARGET_POS = 8,
                TARGET_DIM = 16,
-               SPACING = 32
+               TARGET_MASK = 24,
+               SPACING = 32,
+               SLACK = 64
        };
 
 public:
        };
 
 public:
@@ -69,6 +74,10 @@ public:
                BELOW = VERTICAL|SELF_POS|SELF_DIM|TARGET_POS|SPACING,
                RIGHT_OF = HORIZONTAL|SELF_POS|TARGET_POS|TARGET_DIM|SPACING,
                LEFT_OF = HORIZONTAL|SELF_POS|SELF_DIM|TARGET_POS|SPACING,
                BELOW = VERTICAL|SELF_POS|SELF_DIM|TARGET_POS|SPACING,
                RIGHT_OF = HORIZONTAL|SELF_POS|TARGET_POS|TARGET_DIM|SPACING,
                LEFT_OF = HORIZONTAL|SELF_POS|SELF_DIM|TARGET_POS|SPACING,
+               FAR_ABOVE = VERTICAL|SELF_POS|TARGET_POS|TARGET_DIM|SPACING|SLACK,
+               FAR_BELOW = VERTICAL|SELF_POS|SELF_DIM|TARGET_POS|SPACING|SLACK,
+               FAR_RIGHT_OF = HORIZONTAL|SELF_POS|TARGET_POS|TARGET_DIM|SPACING|SLACK,
+               FAR_LEFT_OF = HORIZONTAL|SELF_POS|SELF_DIM|TARGET_POS|SPACING|SLACK,
                ALIGN_TOP = VERTICAL|SELF_POS|SELF_DIM|TARGET_POS|TARGET_DIM,
                ALIGN_BOTTOM = VERTICAL|SELF_POS|TARGET_POS,
                ALIGN_RIGHT = HORIZONTAL|SELF_POS|SELF_DIM|TARGET_POS|TARGET_DIM,
                ALIGN_TOP = VERTICAL|SELF_POS|SELF_DIM|TARGET_POS|TARGET_DIM,
                ALIGN_BOTTOM = VERTICAL|SELF_POS|TARGET_POS,
                ALIGN_RIGHT = HORIZONTAL|SELF_POS|SELF_DIM|TARGET_POS|TARGET_DIM,
@@ -77,13 +86,50 @@ public:
                COPY_HEIGHT = VERTICAL|SELF_DIM|TARGET_DIM
        };
 
                COPY_HEIGHT = VERTICAL|SELF_DIM|TARGET_DIM
        };
 
-protected:
+       class Loader: public DataFile::ObjectLoader<Layout>
+       {
+       public:
+               typedef std::map<std::string, Widget *> WidgetMap;
+
+       private:
+               const WidgetMap &wdg_map;
+
+       public:
+               Loader(Layout &, const WidgetMap &);
+
+       private:
+               void column_spacing(unsigned);
+               void margin();
+               void row_spacing(unsigned);
+               void spacing(unsigned);
+               void widget(const std::string &);
+       };
+
+private:
+       class WidgetLoader: public DataFile::Loader
+       {
+       private:
+               Layout &layout;
+               Widget &widget;
+               const Layout::Loader::WidgetMap &wdg_map;
+
+       public:
+               WidgetLoader(Layout &, Widget &, const Layout::Loader::WidgetMap &);
+
+       private:
+               void constraint(ConstraintType, const std::string &);
+               void expand(bool, bool);
+               void ghost(bool);
+               void gravity(int, int);
+       };
+
        struct Slot;
 
        struct Constraint
        {
                ConstraintType type;
                Slot &target;
        struct Slot;
 
        struct Constraint
        {
                ConstraintType type;
                Slot &target;
+               int spacing;
 
                Constraint(ConstraintType, Slot &);
        };
 
                Constraint(ConstraintType, Slot &);
        };
@@ -99,17 +145,25 @@ protected:
        struct Slot: public sigc::trackable
        {
                Layout &layout;
        struct Slot: public sigc::trackable
        {
                Layout &layout;
-               unsigned index;
+               int index;
                Widget &widget;
                Widget &widget;
+               Geometry autosize_geom;
                Geometry geom;
                std::list<Constraint> constraints;
                Packing horiz_pack;
                Packing vert_pack;
                Geometry geom;
                std::list<Constraint> constraints;
                Packing horiz_pack;
                Packing vert_pack;
+               bool ghost;
 
                Slot(Layout &, Widget &);
 
                Slot(Layout &, Widget &);
-               virtual ~Slot() { }
 
                void autosize_changed();
 
                void autosize_changed();
+               void visibility_changed(bool);
+       };
+
+       enum SolveMode
+       {
+               UPDATE,
+               AUTOSIZE
        };
 
        class LinearProgram;
        };
 
        class LinearProgram;
@@ -117,41 +171,73 @@ protected:
 
        Container *container;
        std::list<Slot *> slots;
 
        Container *container;
        std::list<Slot *> slots;
+       unsigned n_active_slots;
+       unsigned n_slack_constraints[2];
        Sides margin;
        unsigned row_spacing;
        unsigned col_spacing;
        Sides margin;
        unsigned row_spacing;
        unsigned col_spacing;
+       Geometry autosize_geom;
+       std::list<Arrangement *> arrangement_stack;
 
        static Pointers pointers[2];
 
 public:
        Layout();
 
        static Pointers pointers[2];
 
 public:
        Layout();
-       virtual ~Layout();
+       ~Layout();
 
        void set_container(Container &);
        void set_margin(const Sides &);
 
        void set_container(Container &);
        void set_margin(const Sides &);
+       const Sides &get_margin() const { return margin; }
+
+       /** Sets the default spacing between widgets in both directions. */
        void set_spacing(unsigned);
        void set_spacing(unsigned);
+
+       /** Sets the default vertical spacing between widgets.  Affects the ABOVE
+       and BELOW constraints. */
        void set_row_spacing(unsigned);
        void set_row_spacing(unsigned);
+
+       /** Sets the default horizontal spacing between widgets.  Affects the
+       LEFT_OF and RIGHT_OF constraints. */
        void set_column_spacing(unsigned);
 
        void set_column_spacing(unsigned);
 
+       unsigned get_row_spacing() const { return row_spacing; }
+       unsigned get_column_spacing() const { return col_spacing; }
+
+       void push_arrangement(Arrangement &);
+       Arrangement *get_arrangement() const;
+       void pop_arrangement(Arrangement &);
+
        void add_widget(Widget &);
        void remove_widget(Widget &);
        void add_widget(Widget &);
        void remove_widget(Widget &);
-protected:
-       virtual Slot *create_slot(Widget &);
+private:
+       void update_slot_indices();
        Slot &get_slot_for_widget(Widget &);
        static ConstraintType complement(ConstraintType);
        Slot &get_slot_for_widget(Widget &);
        static ConstraintType complement(ConstraintType);
+       void create_constraint(Widget &, ConstraintType, Widget &, int);
+
 public:
 public:
-       void add_constraint(Widget &, ConstraintType, Widget &);
+       /** Adds a constraint between two widgets. */
+       void add_constraint(Widget &src, ConstraintType type, Widget &tgt);
+
+       /** Adds a constraint between two widgets, overriding the default spacing.
+       Not all constraint types use a spacing. */
+       void add_constraint(Widget &src, ConstraintType type, Widget &tgt, unsigned);
+
        void set_gravity(Widget &, int, int);
        void set_expand(Widget &, bool, bool);
 
        void set_gravity(Widget &, int, int);
        void set_expand(Widget &, bool, bool);
 
+       /// Sets a widget as a ghost, taking up space even if it is hidden.
+       void set_ghost(Widget &, bool);
+
        void update();
        void update();
+       void autosize(Geometry &);
 
 
-protected:
-       void find_constraint_group(Slot &, ConstraintType, std::set<Slot *> &);
-       void sort_slots(std::list<Slot *> &, ConstraintType);
-       void solve_constraints(int);
+private:
+       void solve_constraints(int, SolveMode);
 };
 
 };
 
+void operator>>(const LexicalConverter &, Layout::ConstraintType &);
+
 } // namespace GLtk
 } // namespace Msp
 
 } // namespace GLtk
 } // namespace Msp