summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
729cb06)
An arrangement class that automatically makes widgets floating is also
added.
--- /dev/null
+#include "floatingarrangement.h"
+
+namespace Msp {
+namespace GLtk {
+
+FloatingArrangement::FloatingArrangement(Layout &l):
+ Arrangement(l)
+{ }
+
+void FloatingArrangement::finish_widget(Widget &wdg)
+{
+ layout.set_floating(wdg, true);
+}
+
+} // namespace GLtk
+} // namespace Msp
--- /dev/null
+#ifndef FLOATINGARRANGEMENT_H_
+#define FLOATINGARRANGEMENT_H_
+
+#include "arrangement.h"
+
+namespace Msp {
+namespace GLtk {
+
+class FloatingArrangement: public Arrangement
+{
+public:
+ FloatingArrangement(Layout &);
+
+private:
+ virtual void process_widget(Widget &, Side, bool) { }
+ virtual void finish_widget(Widget &);
+ virtual void finish_slot() { }
+};
+
+} // namespace GLtk
+} // namespace Msp
+
+#endif
void Layout::update_slot_indices()
{
n_active_slots = 0;
void Layout::update_slot_indices()
{
n_active_slots = 0;
+ unsigned n_floating = 0;
for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
{
if((*i)->widget.is_visible() || (*i)->ghost)
for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
{
if((*i)->widget.is_visible() || (*i)->ghost)
(*i)->index = n_active_slots++;
(*i)->index = n_active_slots++;
+ if((*i)->floating)
+ ++n_floating;
+ }
- n_slack_vars[0] = 0;
- n_slack_vars[1] = 0;
+ n_slack_vars[0] = n_floating*2;
+ n_slack_vars[1] = n_floating*2;
for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
if((*i)->index>=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;
+ if(!(*i)->floating)
+ {
+ 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_vars[j->type&1];
for(list<Constraint>::iterator j=(*i)->constraints.begin(); j!=(*i)->constraints.end(); ++j)
if(j->target.index>(*i)->index && (j->type&SLACK))
++n_slack_vars[j->type&1];
+void Layout::set_floating(Widget &wdg, bool f)
+{
+ Slot &slot = get_slot_for_widget(wdg);
+
+ slot.floating = f;
+
+ update_slot_indices();
+ update();
+}
+
void Layout::update()
{
solve_constraints(HORIZONTAL, UPDATE);
void Layout::update()
{
solve_constraints(HORIZONTAL, UPDATE);
- objective[(*i)->index*5] = ((*i)->*(ptrs.packing)).gravity/weight;
+ if(!(*i)->floating)
+ objective[(*i)->index*5] = ((*i)->*(ptrs.packing)).gravity/weight;
objective[(*i)->index*5+1] = (((*i)->*(ptrs.packing)).expand ? weight : -1);
}
objective[(*i)->index*5+1] = (((*i)->*(ptrs.packing)).expand ? weight : -1);
}
row.back() = geom.*(ptrs.dim)-margin.*(ptrs.high_margin);
}
row.back() = geom.*(ptrs.dim)-margin.*(ptrs.high_margin);
}
- if(((*i)->*(ptrs.packing)).gravity==0)
+ if((*i)->floating || ((*i)->*(ptrs.packing)).gravity==0)
- /* 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. */
+ /* 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 = ((*i)->*(ptrs.packing)).gravity*0.5+0.5;
LinearProgram::Row row = linprog.add_row();
row[(*i)->index*5] = 1;
LinearProgram::Row row = linprog.add_row();
row[(*i)->index*5] = 1;
- row[(*i)->index*5+1] = 0.5;
+ row[(*i)->index*5+1] = a;
row[k] = 1;
row[k+1] = -1;
row[k] = 1;
row[k+1] = -1;
- row.back() = geom.*(ptrs.dim)/2;
+ if((*i)->floating)
+ {
+ const Geometry &cgeom = (*i)->widget.get_geometry();
+ row.back() = cgeom.*(ptrs.pos)+cgeom.*(ptrs.dim)*a;
+ }
+ else
+ row.back() = geom.*(ptrs.dim)/2;
objective[k] = -1;
objective[k+1] = -1;
k += 2;
objective[k] = -1;
objective[k+1] = -1;
k += 2;
layout(l),
index(0),
widget(w),
layout(l),
index(0),
widget(w),
+ ghost(false),
+ floating(false)
{
vert_pack.gravity = 1;
widget.signal_autosize_changed.connect(sigc::mem_fun(this, &Slot::autosize_changed));
{
vert_pack.gravity = 1;
widget.signal_autosize_changed.connect(sigc::mem_fun(this, &Slot::autosize_changed));
Packing horiz_pack;
Packing vert_pack;
bool ghost;
Packing horiz_pack;
Packing vert_pack;
bool ghost;
Slot(Layout &, Widget &);
Slot(Layout &, Widget &);
/// Sets a widget as a ghost, taking up space even if it is hidden.
void set_ghost(Widget &, bool);
/// Sets a widget as a ghost, taking up space even if it is hidden.
void set_ghost(Widget &, bool);
+ void set_floating(Widget &, bool);
+
void update();
void autosize(Geometry &);
void update();
void autosize(Geometry &);