#include <algorithm>
#include <limits>
+#include <msp/core/maputils.h>
#include <msp/strings/format.h>
#include "arrangement.h"
#include "container.h"
n_active_slots = 0;
for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
{
- if((*i)->widget.is_visible())
+ if((*i)->widget.is_visible() || (*i)->ghost)
(*i)->index = n_active_slots++;
else
(*i)->index = -1;
update();
}
+void Layout::set_ghost(Widget &wdg, bool g)
+{
+ Slot &slot = get_slot_for_widget(wdg);
+
+ slot.ghost = g;
+
+ if(!wdg.is_visible())
+ {
+ update_slot_indices();
+ update();
+ }
+}
+
void Layout::update()
{
solve_constraints(HORIZONTAL, UPDATE);
(*i)->widget.set_geometry((*i)->geom);
}
-void Layout::autosize()
+void Layout::autosize(Geometry &geom)
{
solve_constraints(HORIZONTAL, AUTOSIZE);
solve_constraints(VERTICAL, AUTOSIZE);
- container->set_size(autosize_geom.w, autosize_geom.h);
+ geom.w = max(geom.w, autosize_geom.w);
+ geom.h = max(geom.h, autosize_geom.h);
}
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_constraints[dir]+1);
float weight = slots.size();
+ unsigned k = n_active_slots*5;
for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
{
if((*i)->index<0)
/* 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)
{
Layout::Slot::Slot(Layout &l, Widget &w):
layout(l),
index(0),
- widget(w)
+ widget(w),
+ ghost(false)
{
vert_pack.gravity = 1;
widget.signal_autosize_changed.connect(sigc::mem_fun(this, &Slot::autosize_changed));
widget.autosize();
autosize_geom = widget.get_geometry();
- if(!widget.is_visible())
+ if(!widget.is_visible() && !ghost)
return;
// If the widget fits in the area it had, just leave it there.
void Layout::Slot::visibility_changed(bool v)
{
layout.update_slot_indices();
- if(v)
+ if(v || ghost)
{
layout.container->signal_autosize_changed.emit();
layout.update();
}
+Layout::Loader::Loader(Layout &l, const WidgetMap &wm):
+ DataFile::ObjectLoader<Layout>(l),
+ wdg_map(wm)
+{
+ add("column_spacing", &Loader::column_spacing);
+ add("margin", &Loader::margin);
+ add("row_spacing", &Loader::row_spacing);
+ add("spacing", &Loader::spacing);
+ add("widget", &Loader::widget);
+}
+
+void Layout::Loader::column_spacing(unsigned s)
+{
+ obj.set_column_spacing(s);
+}
+
+void Layout::Loader::margin()
+{
+ Sides sides;
+ load_sub(sides);
+ obj.set_margin(sides);
+}
+
+void Layout::Loader::spacing(unsigned s)
+{
+ obj.set_spacing(s);
+}
+
+void Layout::Loader::row_spacing(unsigned s)
+{
+ obj.set_row_spacing(s);
+}
+
+void Layout::Loader::widget(const string &n)
+{
+ Widget &wdg = *get_item(wdg_map, n);
+ WidgetLoader ldr(obj, wdg, wdg_map);
+ load_sub_with(ldr);
+}
+
+
+Layout::WidgetLoader::WidgetLoader(Layout &l, Widget &w, const Layout::Loader::WidgetMap &wm):
+ layout(l),
+ widget(w),
+ wdg_map(wm)
+{
+ add("constraint", &WidgetLoader::constraint);
+ add("expand", &WidgetLoader::expand);
+ add("ghost", &WidgetLoader::ghost);
+ add("gravity", &WidgetLoader::gravity);
+}
+
+void Layout::WidgetLoader::constraint(ConstraintType type, const string &n)
+{
+ Widget &target = *get_item(wdg_map, n);
+ layout.add_constraint(widget, type, target);
+}
+
+void Layout::WidgetLoader::expand(bool h, bool v)
+{
+ layout.set_expand(widget, h, v);
+}
+
+void Layout::WidgetLoader::ghost(bool g)
+{
+ layout.set_ghost(widget, g);
+}
+
+void Layout::WidgetLoader::gravity(int h, int v)
+{
+ layout.set_gravity(widget, h, v);
+}
+
+
void operator>>(const LexicalConverter &conv, Layout::ConstraintType &ctype)
{
const string &str = conv.get();