]> git.tdb.fi Git - libs/gltk.git/commitdiff
Support floating widgets in layouts
authorMikko Rasa <tdb@tdb.fi>
Thu, 7 Nov 2013 12:57:14 +0000 (14:57 +0200)
committerMikko Rasa <tdb@tdb.fi>
Thu, 7 Nov 2013 12:57:14 +0000 (14:57 +0200)
An arrangement class that automatically makes widgets floating is also
added.

source/floatingarrangement.cpp [new file with mode: 0644]
source/floatingarrangement.h [new file with mode: 0644]
source/layout.cpp
source/layout.h

diff --git a/source/floatingarrangement.cpp b/source/floatingarrangement.cpp
new file mode 100644 (file)
index 0000000..6e707e8
--- /dev/null
@@ -0,0 +1,16 @@
+#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
diff --git a/source/floatingarrangement.h b/source/floatingarrangement.h
new file mode 100644 (file)
index 0000000..a4ebdd7
--- /dev/null
@@ -0,0 +1,23 @@
+#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
index 5df7bc1f77d2a16f87a02f80e4eea6892a2d3564..02e1ec4479dd17643dbbc8056b8b578c8bac0adb 100644 (file)
@@ -211,22 +211,31 @@ void Layout::remove_widget(Widget &wdg)
 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)
+               {
                        (*i)->index = n_active_slots++;
+                       if((*i)->floating)
+                               ++n_floating;
+               }
                else
                        (*i)->index = -1;
        }
 
-       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(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];
@@ -312,6 +321,16 @@ void Layout::set_ghost(Widget &wdg, bool g)
        }
 }
 
+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);
@@ -358,7 +377,8 @@ void Layout::solve_constraints(int dir, SolveMode mode)
                }
                else
                {
-                       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);
                }
 
@@ -380,18 +400,24 @@ void Layout::solve_constraints(int dir, SolveMode mode)
                        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;
-                       row[(*i)->index*5+1] = 0.5;
+                       row[(*i)->index*5+1] = a;
                        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;
@@ -470,7 +496,8 @@ Layout::Slot::Slot(Layout &l, Widget &w):
        layout(l),
        index(0),
        widget(w),
-       ghost(false)
+       ghost(false),
+       floating(false)
 {
        vert_pack.gravity = 1;
        widget.signal_autosize_changed.connect(sigc::mem_fun(this, &Slot::autosize_changed));
index 043d92cc1554b738092ce3ad771fcf5bb3cc5049..141a15cdb317d7920fd394778312f28002228b24 100644 (file)
@@ -153,6 +153,7 @@ private:
                Packing horiz_pack;
                Packing vert_pack;
                bool ghost;
+               bool floating;
 
                Slot(Layout &, Widget &);
 
@@ -229,6 +230,8 @@ public:
        /// 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 &);