row_spacing(5),
col_spacing(4)
{
- n_slack_constraints[0] = 0;
- n_slack_constraints[1] = 0;
+ n_slack_vars[0] = 0;
+ n_slack_vars[1] = 0;
}
Layout::~Layout()
(*i)->index = -1;
}
- n_slack_constraints[0] = 0;
- n_slack_constraints[1] = 0;
+ n_slack_vars[0] = 0;
+ n_slack_vars[1] = 0;
for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
if((*i)->index>=0)
{
+ for(unsigned j=0; j<2; ++j)
+ if(((*i)->*(pointers[j].packing)).gravity==0)
+ n_slack_vars[j] += 2;
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];
+ ++n_slack_vars[j->type&1];
}
}
slot.horiz_pack.gravity = h;
slot.vert_pack.gravity = v;
+ update_slot_indices();
update();
}
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+n_slack_constraints[dir]+1);
+ LinearProgram linprog(n_active_slots*5+n_slack_vars[dir]+1);
float weight = slots.size();
unsigned k = n_active_slots*5;
for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
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. */
+ /* Try to keep the widget as close to the center of the container
+ as possible. Since linear programs can't express absolute values
+ directly, use two opposing slack variables that are optimized for
+ a low value. */
LinearProgram::Row row = linprog.add_row();
- row[(*i)->index*5+2] = 1;
- row[(*i)->index*5+3] = -1;
+ row[(*i)->index*5] = 1;
+ row[(*i)->index*5+1] = 0.5;
+ row[k] = 1;
+ row[k+1] = -1;
+ row.back() = geom.*(ptrs.dim)/2;
+ objective[k] = -1;
+ objective[k+1] = -1;
+ k += 2;
}
{