margin(8),
row_spacing(5),
col_spacing(4)
-{ }
+{
+ n_slack_constraints[0] = 0;
+ n_slack_constraints[1] = 0;
+}
Layout::~Layout()
{
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;
}
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)
tgt_slot.constraints.push_back(Constraint(complement(type), src_slot));
tgt_slot.constraints.back().spacing = sp;
+ 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+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)
{
/* 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)
{
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;
}
}
TARGET_POS = 8,
TARGET_DIM = 16,
TARGET_MASK = 24,
- SPACING = 32
+ SPACING = 32,
+ SLACK = 64
};
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,
Container *container;
std::list<Slot *> slots;
unsigned n_active_slots;
+ unsigned n_slack_constraints[2];
Sides margin;
unsigned row_spacing;
unsigned col_spacing;
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)
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));
}