X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flayout.cpp;h=495d6261c6483b55f3f76bee50b7980eb0fd33a1;hb=394e5c9969a30b604bfaf78fc05a8c2d5c98ab5b;hp=200801f36285b7c3d9ed55402fd764a27f0a8813;hpb=b4a3d651f57c46507aaa99a71a14fea15f0e430d;p=libs%2Fgltk.git diff --git a/source/layout.cpp b/source/layout.cpp index 200801f..495d626 100644 --- a/source/layout.cpp +++ b/source/layout.cpp @@ -19,44 +19,44 @@ public: { private: LinearProgram &linprog; - unsigned index; + size_t index; public: - Row(LinearProgram &, unsigned); + Row(LinearProgram &, size_t); - float &operator[](unsigned); + float &operator[](size_t); float &back(); }; private: struct Column { - unsigned basic; + size_t basic; std::vector values; Column(); }; - unsigned n_columns; - unsigned n_rows; + size_t n_columns = 1; + size_t n_rows = 1; std::vector columns; - bool solved; - bool infeasible; + bool solved = false; + bool infeasible = false; public: - LinearProgram(unsigned); + LinearProgram(size_t); Row add_row(); - Row operator[](unsigned); + Row operator[](size_t); Row get_objective_row(); - float get_variable(unsigned); + float get_variable(size_t); bool solve(); private: void prepare_columns(); void add_artificial_variables(); void remove_artificial_variables(); - unsigned find_minimal_ratio(unsigned); - void make_basic_column(unsigned, unsigned); + size_t find_minimal_ratio(size_t); + void make_basic_column(size_t, size_t); bool pivot(); }; @@ -85,23 +85,6 @@ Layout::Pointers Layout::pointers[2] = } }; -Layout::Layout(): - container(0), - n_active_slots(0), - margin(8), - row_spacing(5), - col_spacing(4) -{ - n_slack_vars[0] = 0; - n_slack_vars[1] = 0; -} - -Layout::~Layout() -{ - for(Slot *s: slots) - delete s; -} - void Layout::set_container(Container &c) { if(container) @@ -147,7 +130,7 @@ void Layout::push_arrangement(Arrangement &arr) Arrangement *Layout::get_arrangement() const { if(arrangement_stack.empty()) - return 0; + return nullptr; else return arrangement_stack.back(); } @@ -174,7 +157,7 @@ void Layout::add_widget(Widget &wdg) if(!container) throw logic_error("!container"); - slots.push_back(new Slot(*this, wdg)); + slots.emplace_back(make_unique(*this, wdg)); update_slot_indices(); if(!arrangement_stack.empty()) arrangement_stack.back()->arrange(wdg); @@ -184,23 +167,22 @@ void Layout::add_widget(Widget &wdg) void Layout::remove_widget(Widget &wdg) { - auto i = find_if(slots, [&wdg](Slot *s){ return &s->widget==&wdg; }); + auto i = find_if(slots, [&wdg](const unique_ptr &s){ return &s->widget==&wdg; }); if(i==slots.end()) return; - for(Slot *s: slots) + for(const unique_ptr &s: slots) if(s!=*i) { for(auto k=s->constraints.begin(); k!=s->constraints.end(); ) { - if(&k->target==*i) - s->constraints.erase(k++); + if(k->target==i->get()) + k = s->constraints.erase(k); else ++k; } } - delete *i; slots.erase(i); update_slot_indices(); @@ -210,8 +192,8 @@ void Layout::remove_widget(Widget &wdg) void Layout::update_slot_indices() { n_active_slots = 0; - unsigned n_floating = 0; - for(Slot *s: slots) + size_t n_floating = 0; + for(const unique_ptr &s: slots) { if(s->widget.is_visible() || s->ghost) { @@ -225,25 +207,25 @@ void Layout::update_slot_indices() n_slack_vars[0] = n_floating*2; n_slack_vars[1] = n_floating*2; - for(const Slot *s: slots) + for(const unique_ptr &s: slots) if(s->index>=0) { if(!s->floating) { for(unsigned j=0; j<2; ++j) - if((s->*(pointers[j].packing)).gravity==0) + if((s.get()->*(pointers[j].packing)).gravity==0) n_slack_vars[j] += 2; } for(const Constraint &c: s->constraints) - if(c.target.index>s->index && (c.type&SLACK)) + if(c.target->index>s->index && (c.type&SLACK)) ++n_slack_vars[c.type&1]; } } Layout::Slot &Layout::get_slot_for_widget(Widget &wdg) { - auto i = find_if(slots, [&wdg](const Slot *s){ return &s->widget==&wdg; }); + auto i = find_if(slots, [&wdg](const unique_ptr &s){ return &s->widget==&wdg; }); if(i==slots.end()) throw hierarchy_error("widget not in layout"); @@ -264,7 +246,7 @@ void Layout::create_constraint(Widget &src, ConstraintType type, Widget &tgt, in Slot &tgt_slot = get_slot_for_widget(tgt); for(const Constraint &c: src_slot.constraints) - if(c.type==type && &c.target==&tgt_slot) + if(c.type==type && c.target==&tgt_slot) return; src_slot.constraints.push_back(Constraint(type, tgt_slot)); @@ -335,7 +317,7 @@ void Layout::update() solve_constraints(HORIZONTAL, UPDATE); solve_constraints(VERTICAL, UPDATE); - for(const Slot *s: slots) + for(const unique_ptr &s: slots) s->widget.set_geometry(s->geom); } @@ -362,8 +344,8 @@ void Layout::solve_constraints(int dir, SolveMode mode) remaining three are slack columns; see below for their purposes. */ LinearProgram linprog(n_active_slots*5+n_slack_vars[dir]+1); float weight = slots.size()+1; - unsigned k = n_active_slots*5; - for(const Slot *s: slots) + size_t k = n_active_slots*5; + for(const unique_ptr &s: slots) { if(s->index<0) continue; @@ -377,8 +359,8 @@ void Layout::solve_constraints(int dir, SolveMode mode) else { if(!s->floating) - objective[s->index*5] = (s->*(ptrs.packing)).gravity/weight; - objective[s->index*5+1] = ((s->*(ptrs.packing)).expand ? weight : -1); + objective[s->index*5] = (s.get()->*(ptrs.packing)).gravity/weight; + objective[s->index*5+1] = ((s.get()->*(ptrs.packing)).expand ? weight : -1); } { @@ -399,12 +381,12 @@ void Layout::solve_constraints(int dir, SolveMode mode) row.back() = geom.*(ptrs.dim)-margin.*(ptrs.high_margin); } - if(s->floating || (s->*(ptrs.packing)).gravity==0) + if(s->floating || (s.get()->*(ptrs.packing)).gravity==0) { /* Try to keep the widget as close to a target position as possible. Since linear programs can't express absolute values directly, use two opposing slack variables that are optimized for a low value. */ - float a = (s->*(ptrs.packing)).gravity*0.5+0.5; + float a = (s.get()->*(ptrs.packing)).gravity*0.5+0.5; LinearProgram::Row row = linprog.add_row(); row[s->index*5] = 1; row[s->index*5+1] = a; @@ -434,7 +416,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. */ for(const Constraint &c: s->constraints) - if(c.target.index>s->index && (c.type&1)==dir) + if(c.target->index>s->index && (c.type&1)==dir) { LinearProgram::Row row = linprog.add_row(); float polarity = ((c.type&SELF_DIM) ? -1 : 1); @@ -444,9 +426,9 @@ void Layout::solve_constraints(int dir, SolveMode mode) if(c.type&SELF_DIM) row[s->index*5+1] = polarity*dim_weight; if(c.type&TARGET_POS) - row[c.target.index*5] = -polarity; + row[c.target->index*5] = -polarity; if(c.type&TARGET_DIM) - row[c.target.index*5+1] = -polarity*dim_weight; + row[c.target->index*5+1] = -polarity*dim_weight; if(c.type&SPACING) row.back() = (c.spacing>=0 ? c.spacing : this->*(ptrs.spacing)); if(c.type&SLACK) @@ -460,7 +442,7 @@ void Layout::solve_constraints(int dir, SolveMode mode) if(mode==AUTOSIZE) { autosize_geom.*(ptrs.dim) = 0; - for(const Slot *s: slots) + for(const unique_ptr &s: slots) if(s->index>=0) { int high_edge = linprog.get_variable(s->index*5)+linprog.get_variable(s->index*5+1); @@ -469,7 +451,7 @@ void Layout::solve_constraints(int dir, SolveMode mode) } else { - for(Slot *s: slots) + for(const unique_ptr &s: slots) if(s->index>=0) { s->geom.*(ptrs.pos) = linprog.get_variable(s->index*5); @@ -481,23 +463,13 @@ void Layout::solve_constraints(int dir, SolveMode mode) Layout::Constraint::Constraint(ConstraintType t, Slot &s): type(t), - target(s), - spacing(-1) -{ } - - -Layout::Packing::Packing(): - gravity(-1), - expand(false) + target(&s) { } Layout::Slot::Slot(Layout &l, Widget &w): layout(l), - index(0), - widget(w), - ghost(false), - floating(false) + widget(w) { vert_pack.gravity = 1; widget.signal_autosize_changed.connect(sigc::mem_fun(this, &Slot::autosize_changed)); @@ -645,12 +617,9 @@ void operator>>(const LexicalConverter &conv, Layout::ConstraintType &ctype) } -Layout::LinearProgram::LinearProgram(unsigned s): +Layout::LinearProgram::LinearProgram(size_t s): n_columns(s), - n_rows(1), - columns(n_columns), - solved(false), - infeasible(false) + columns(n_columns) { } Layout::LinearProgram::Row Layout::LinearProgram::add_row() @@ -658,7 +627,7 @@ Layout::LinearProgram::Row Layout::LinearProgram::add_row() return Row(*this, n_rows++); } -Layout::LinearProgram::Row Layout::LinearProgram::operator[](unsigned r) +Layout::LinearProgram::Row Layout::LinearProgram::operator[](size_t r) { if(r>=n_rows) throw out_of_range("LinearProgram::operator[]"); @@ -671,14 +640,14 @@ Layout::LinearProgram::Row Layout::LinearProgram::get_objective_row() return Row(*this, 0); } -float Layout::LinearProgram::get_variable(unsigned i) +float Layout::LinearProgram::get_variable(size_t i) { if(!solved || infeasible) throw logic_error("not solved"); if(i+1>=n_columns) throw out_of_range("LinearProgram::get_variable"); - if(unsigned r = columns[i].basic) + if(size_t r = columns[i].basic) return columns.back().values[r]; else return 0; @@ -731,7 +700,7 @@ void Layout::LinearProgram::prepare_columns() if(c.values.size()>=2 && c.values.back()!=0.0f && (constants.size()=0.0f) && obj_coeff[c.values.size()-1]==0.0f) { bool basic = true; - for(unsigned j=1; (basic && j+1 artificial_rows(n_rows-1); - for(unsigned i=0; i artificial_rows(n_rows-1); + for(size_t i=0; i::infinity(); - unsigned row = 0; - for(unsigned i=1; i0) { float ratio = columns.back().values[i]/columns[c].values[i]; @@ -850,11 +819,11 @@ unsigned Layout::LinearProgram::find_minimal_ratio(unsigned c) return row; } -void Layout::LinearProgram::make_basic_column(unsigned c, unsigned r) +void Layout::LinearProgram::make_basic_column(size_t c, size_t r) { /* Perform row transfer operations to make the pivot column basic, containing a 1 on the pivot row. */ - for(unsigned i=0; i0) - if(unsigned row = find_minimal_ratio(i)) + if(size_t row = find_minimal_ratio(i)) { make_basic_column(i, row); return true; @@ -893,12 +862,12 @@ bool Layout::LinearProgram::pivot() } -Layout::LinearProgram::Row::Row(LinearProgram &lp, unsigned i): +Layout::LinearProgram::Row::Row(LinearProgram &lp, size_t i): linprog(lp), index(i) { } -float &Layout::LinearProgram::Row::operator[](unsigned c) +float &Layout::LinearProgram::Row::operator[](size_t c) { if(c>=linprog.n_columns) throw out_of_range("Row::operator[]");