From 7a0f255ecf23391f09488ac54fb9b1124827dfa7 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 12 Jun 2013 15:49:45 +0300 Subject: [PATCH] Add constraint types that allow flexible spacing between widgets --- source/layout.cpp | 26 ++++++++++++++++++++------ source/layout.h | 8 +++++++- source/mixedrows.cpp | 6 ++---- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/source/layout.cpp b/source/layout.cpp index 66eb66b..993c82f 100644 --- a/source/layout.cpp +++ b/source/layout.cpp @@ -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::iterator i=slots.begin(); i!=slots.end(); ++i) + if((*i)->index>=0) + { + for(list::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::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::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; } } diff --git a/source/layout.h b/source/layout.h index 43d1ca8..2bddb77 100644 --- a/source/layout.h +++ b/source/layout.h @@ -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 slots; unsigned n_active_slots; + unsigned n_slack_constraints[2]; Sides margin; unsigned row_spacing; unsigned col_spacing; diff --git a/source/mixedrows.cpp b/source/mixedrows.cpp index bfcf621..7637020 100644 --- a/source/mixedrows.cpp +++ b/source/mixedrows.cpp @@ -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)); } -- 2.43.0