]> git.tdb.fi Git - libs/gltk.git/blobdiff - source/layout.cpp
The entire row should be divided when initially making a column basic
[libs/gltk.git] / source / layout.cpp
index d5437f0b0a29ed04c1ce000534174fd0d9b9fa12..ba726f7ccbc5b88e29534625cc77b1de026fd1bb 100644 (file)
@@ -203,7 +203,7 @@ Layout::ConstraintType Layout::complement(ConstraintType type)
                return type;
 }
 
-void Layout::add_constraint(Widget &src, ConstraintType type, Widget &tgt)
+void Layout::create_constraint(Widget &src, ConstraintType type, Widget &tgt, int sp)
 {
        if(&src==&tgt)
                throw invalid_argument("&src==&tgt");
@@ -216,11 +216,23 @@ void Layout::add_constraint(Widget &src, ConstraintType type, Widget &tgt)
                        return;
 
        src_slot.constraints.push_back(Constraint(type, tgt_slot));
+       src_slot.constraints.back().spacing = sp;
        tgt_slot.constraints.push_back(Constraint(complement(type), src_slot));
+       tgt_slot.constraints.back().spacing = sp;
 
        update();
 }
 
+void Layout::add_constraint(Widget &src, ConstraintType type, Widget &tgt)
+{
+       create_constraint(src, type, tgt, -1);
+}
+
+void Layout::add_constraint(Widget &src, ConstraintType type, Widget &tgt, unsigned spacing)
+{
+       create_constraint(src, type, tgt, spacing);
+}
+
 void Layout::set_gravity(Widget &wdg, int h, int v)
 {
        Slot &slot = get_slot_for_widget(wdg);
@@ -304,6 +316,16 @@ void Layout::solve_constraints(int dir, SolveMode mode)
                        row.back() = geom.*(ptrs.dim)-margin.*(ptrs.high_margin);
                }
 
+               if(((*i)->*(ptrs.packing)).gravity==0)
+               {
+                       /* This forces the widget's distance from the left and right edge of
+                       the container to be equal.  It's a bit of a hack, but more time and
+                       thought is needed for a better solution. */
+                       LinearProgram::Row row = linprog.add_row();
+                       row[(*i)->index*5+2] = 1;
+                       row[(*i)->index*5+3] = -1;
+               }
+
                {
                        /* Only allow the widget's dimension to increase.  The geometry has
                        previously been set to the smallest allowable size. */
@@ -329,7 +351,7 @@ void Layout::solve_constraints(int dir, SolveMode mode)
                                if(j->type&TARGET_DIM)
                                        row[j->target.index*5+1] = -1;
                                if(j->type&SPACING)
-                                       row.back() = this->*(ptrs.spacing);
+                                       row.back() = (j->spacing>=0 ? j->spacing : this->*(ptrs.spacing));
                        }
        }
 
@@ -358,7 +380,8 @@ void Layout::solve_constraints(int dir, SolveMode mode)
 
 Layout::Constraint::Constraint(ConstraintType t, Slot &s):
        type(t),
-       target(s)
+       target(s),
+       spacing(-1)
 { }
 
 
@@ -474,11 +497,12 @@ void Layout::LinearProgram::prepare_columns()
        /* See if any variables are already basic.  A basic variable must only have
        a nonzero coefficient on one row, and its product with the constant column
        must not be negative.  Only one variable can be basic for any given row. */
-       vector<float> basic_coeff(n_rows, 0.0f);
+       vector<float> obj_coeff(n_rows, 0.0f);
+       vector<float> row_coeff(n_rows, 1.0f);
        const vector<float> &constants = columns.back().values;
        for(vector<Column>::iterator i=columns.begin(); i!=columns.end(); ++i)
        {
-               if(i->values.size()>=2 && i->values.back()!=0.0f && (constants.size()<i->values.size() || i->values.back()*constants[i->values.size()-1]>=0.0f) && basic_coeff[i->values.size()-1]==0.0f)
+               if(i->values.size()>=2 && i->values.back()!=0.0f && (constants.size()<i->values.size() || i->values.back()*constants[i->values.size()-1]>=0.0f) && obj_coeff[i->values.size()-1]==0.0f)
                {
                        bool basic = true;
                        for(unsigned j=1; (basic && j+1<i->values.size()); ++j)
@@ -486,7 +510,8 @@ void Layout::LinearProgram::prepare_columns()
                        if(basic)
                        {
                                i->basic = i->values.size()-1;
-                               basic_coeff[i->basic] = -i->values.front()/i->values.back();
+                               row_coeff[i->basic] = 1.0f/i->values.back();
+                               obj_coeff[i->basic] = -i->values.front();
                                i->values.clear();
                        }
                }
@@ -497,7 +522,10 @@ void Layout::LinearProgram::prepare_columns()
                if(!i->values.empty())
                {
                        for(unsigned j=0; j<i->values.size(); ++j)
-                               i->values.front() += basic_coeff[j]*i->values[j];
+                       {
+                               i->values[j] *= row_coeff[j];
+                               i->values.front() += obj_coeff[j]*i->values[j];
+                       }
                }
 }