]> git.tdb.fi Git - libs/gltk.git/blobdiff - source/layout.cpp
Add constraint types that allow flexible spacing between widgets
[libs/gltk.git] / source / layout.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;
                        }
        }