]> git.tdb.fi Git - libs/gltk.git/commitdiff
Add constraint types that allow flexible spacing between widgets
authorMikko Rasa <tdb@tdb.fi>
Wed, 12 Jun 2013 12:49:45 +0000 (15:49 +0300)
committerMikko Rasa <tdb@tdb.fi>
Wed, 12 Jun 2013 12:49:45 +0000 (15:49 +0300)
source/layout.cpp
source/layout.h
source/mixedrows.cpp

index 66eb66b8b98c3a1e817a5dcbca9a11116aea3829..993c82f42c7ce0d8f683065d9cf4d01f127cd895 100644 (file)
@@ -88,7 +88,10 @@ Layout::Layout():
        margin(8),
        row_spacing(5),
        col_spacing(4)
-{ }
+{
+       n_slack_constraints[0] = 0;
+       n_slack_constraints[1] = 0;
+}
 
 Layout::~Layout()
 {
@@ -167,10 +170,7 @@ void Layout::remove_widget(Widget &wdg)
                        delete *i;
                        slots.erase(i);
 
-                       unsigned n = 0;
-                       for(i=slots.begin(); i!=slots.end(); ++i, ++n)
-                               (*i)->index = n;
-
+                       update_slot_indices();
                        update();
                        return;
                }
@@ -191,6 +191,16 @@ void Layout::update_slot_indices()
                else
                        (*i)->index = -1;
        }
+
+       n_slack_constraints[0] = 0;
+       n_slack_constraints[1] = 0;
+       for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
+               if((*i)->index>=0)
+               {
+                       for(list<Constraint>::iterator j=(*i)->constraints.begin(); j!=(*i)->constraints.end(); ++j)
+                               if(j->target.index>(*i)->index && (j->type&SLACK))
+                                       ++n_slack_constraints[j->type&1];
+               }
 }
 
 Layout::Slot &Layout::get_slot_for_widget(Widget &wdg)
@@ -224,6 +234,7 @@ void Layout::create_constraint(Widget &src, ConstraintType type, Widget &tgt, in
        tgt_slot.constraints.push_back(Constraint(complement(type), src_slot));
        tgt_slot.constraints.back().spacing = sp;
 
+       update_slot_indices();
        update();
 }
 
@@ -286,7 +297,7 @@ void Layout::solve_constraints(int dir, SolveMode mode)
        five columns for each widget, and one constant column.  The first and second
        columns of a widget are its position and dimension, respectively.  The
        remaining three are slack columns; see below for their purposes. */
-       LinearProgram linprog(n_active_slots*5+1);
+       LinearProgram linprog(n_active_slots*5+n_slack_constraints[dir]+1);
        float weight = slots.size();
        for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
        {
@@ -344,6 +355,7 @@ void Layout::solve_constraints(int dir, SolveMode mode)
 
                /* Add rows for user-defined constraints.  Constraints are always added
                in pairs, so it's only necessary to create a row for one half. */
+               unsigned k = n_active_slots*5;
                for(list<Constraint>::iterator j=(*i)->constraints.begin(); j!=(*i)->constraints.end(); ++j)
                        if(j->target.index>(*i)->index && (j->type&1)==dir)
                        {
@@ -359,6 +371,8 @@ void Layout::solve_constraints(int dir, SolveMode mode)
                                        row[j->target.index*5+1] = -polarity;
                                if(j->type&SPACING)
                                        row.back() = (j->spacing>=0 ? j->spacing : this->*(ptrs.spacing));
+                               if(j->type&SLACK)
+                                       row[k++] = -1;
                        }
        }
 
index 43d1ca875c2d01d9e9a60e9e22e554808b43d673..2bddb77cfa30bef43632036b8e2564e41e59a06e 100644 (file)
@@ -61,7 +61,8 @@ private:
                TARGET_POS = 8,
                TARGET_DIM = 16,
                TARGET_MASK = 24,
-               SPACING = 32
+               SPACING = 32,
+               SLACK = 64
        };
 
 public:
@@ -71,6 +72,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,
+               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,
@@ -129,6 +134,7 @@ protected:
        Container *container;
        std::list<Slot *> slots;
        unsigned n_active_slots;
+       unsigned n_slack_constraints[2];
        Sides margin;
        unsigned row_spacing;
        unsigned col_spacing;
index bfcf6219c0b75660c12d5d564c4290d6dd8b78b9..763702057c65429e8114ff6643520622923612d3 100644 (file)
@@ -43,8 +43,7 @@ Layout::Slot *MixedRows::create_slot(Widget &wdg)
        if(!first)
        {
                Slot *prev = slots.back();
-               if(!hsplit)
-                       slot->constraints.push_back(Constraint(RIGHT_OF, *prev));
+               slot->constraints.push_back(Constraint((hsplit ? FAR_RIGHT_OF : RIGHT_OF), *prev));
                slot->constraints.push_back(Constraint(ALIGN_TOP, *prev));
                slot->constraints.push_back(Constraint(ALIGN_BOTTOM, *prev));
                if(uniform_cols)
@@ -53,8 +52,7 @@ Layout::Slot *MixedRows::create_slot(Widget &wdg)
        else if(!slots.empty())
        {
                Slot *prev = slots.back();
-               if(!vsplit)
-                       slot->constraints.push_back(Constraint(BELOW, *prev));
+               slot->constraints.push_back(Constraint((vsplit ? FAR_BELOW : BELOW), *prev));
                if(uniform_rows)
                        slot->constraints.push_back(Constraint(COPY_HEIGHT, *prev));
        }