X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flayout.cpp;h=495d6261c6483b55f3f76bee50b7980eb0fd33a1;hb=394e5c9969a30b604bfaf78fc05a8c2d5c98ab5b;hp=b6248e6ad8511bb8dbaa9bc0d1ba5b1eaeaa18ba;hpb=9f38197854e699a6093a906ab43f4238f3cd2388;p=libs%2Fgltk.git diff --git a/source/layout.cpp b/source/layout.cpp index b6248e6..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 = 1; - unsigned n_rows = 1; + size_t n_columns = 1; + size_t n_rows = 1; std::vector columns; 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,12 +85,6 @@ Layout::Pointers Layout::pointers[2] = } }; -Layout::~Layout() -{ - for(Slot *s: slots) - delete s; -} - void Layout::set_container(Container &c) { if(container) @@ -136,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(); } @@ -163,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); @@ -173,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(); @@ -199,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) { @@ -214,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"); @@ -253,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)); @@ -324,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); } @@ -351,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; @@ -366,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); } { @@ -388,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; @@ -423,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); @@ -433,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) @@ -449,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); @@ -458,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); @@ -470,7 +463,7 @@ void Layout::solve_constraints(int dir, SolveMode mode) Layout::Constraint::Constraint(ConstraintType t, Slot &s): type(t), - target(s) + target(&s) { } @@ -624,7 +617,7 @@ void operator>>(const LexicalConverter &conv, Layout::ConstraintType &ctype) } -Layout::LinearProgram::LinearProgram(unsigned s): +Layout::LinearProgram::LinearProgram(size_t s): n_columns(s), columns(n_columns) { } @@ -634,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[]"); @@ -647,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; @@ -707,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]; @@ -826,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; @@ -869,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[]");