]> git.tdb.fi Git - libs/gltk.git/blob - source/arrangement.cpp
Allow overriding the spacing between two widgets in LinearArrangement
[libs/gltk.git] / source / arrangement.cpp
1 #include "arrangement.h"
2
3 using namespace std;
4
5 namespace Msp {
6 namespace GLtk {
7
8 Arrangement::Arrangement(Layout &l):
9         layout(l),
10         parent(layout.get_arrangement())
11 {
12         layout.push_arrangement(*this);
13 }
14
15 Arrangement::~Arrangement()
16 {
17         layout.pop_arrangement(*this);
18 }
19
20 void Arrangement::arrange(Widget &wdg)
21 {
22         for(unsigned i=0; i<4; ++i)
23                 process_widget(wdg, static_cast<Side>(i), true);
24         finish_widget(wdg);
25         finish_slot();
26 }
27
28 void Arrangement::arrange(Arrangement &arr)
29 {
30         for(unsigned i=0; i<4; ++i)
31         {
32                 Side side = static_cast<Side>(i);
33                 const Edge &edge = arr.get_edge(side);
34                 for(list<Widget *>::const_iterator j=edge.widgets.begin(); j!=edge.widgets.end(); ++j)
35                         process_widget(**j, side, edge.aligned);
36         }
37         finish_slot();
38 }
39
40 void Arrangement::add_constraint(Widget &wdg, Layout::ConstraintType type, Side side, int spacing)
41 {
42         add_constraint(wdg, type, edges[side], spacing);
43 }
44
45 void Arrangement::add_constraint(Widget &wdg, Layout::ConstraintType type, const Edge &edge, int spacing)
46 {
47         for(list<Widget *>::const_iterator i=edge.widgets.begin(); i!=edge.widgets.end(); ++i)
48                 if(*i!=&wdg)
49                 {
50                         if(spacing<0)
51                                 layout.add_constraint(wdg, type, **i);
52                         else
53                                 layout.add_constraint(wdg, type, **i, spacing);
54                 }
55 }
56
57 Layout::ConstraintType Arrangement::get_order_constraint(Side s, bool slack)
58 {
59         switch(s)
60         {
61         case TOP:    return (slack ? Layout::FAR_ABOVE : Layout::ABOVE);
62         case RIGHT:  return (slack ? Layout::FAR_RIGHT_OF : Layout::RIGHT_OF);
63         case BOTTOM: return (slack ? Layout::FAR_BELOW : Layout::BELOW);
64         case LEFT:   return (slack ? Layout::FAR_LEFT_OF : Layout::LEFT_OF);
65         default: throw invalid_argument("Arrangement::get_align_constraint");
66         }
67 }
68
69 Layout::ConstraintType Arrangement::get_align_constraint(Side s)
70 {
71         switch(s)
72         {
73         case TOP:    return Layout::ALIGN_TOP;
74         case RIGHT:  return Layout::ALIGN_RIGHT;
75         case BOTTOM: return Layout::ALIGN_BOTTOM;
76         case LEFT:   return Layout::ALIGN_LEFT;
77         default: throw invalid_argument("Arrangement::get_align_constraint");
78         }
79 }
80
81
82 Arrangement::Edge::Edge():
83         aligned(false)
84 { }
85
86 void Arrangement::Edge::clear()
87 {
88         widgets.clear();
89         aligned = false;
90 }
91
92 void Arrangement::Edge::add(Widget &wdg, bool algn)
93 {
94         if(aligned)
95                 return;
96
97         if(algn)
98                 widgets.clear();
99
100         widgets.push_back(&wdg);
101         aligned = algn;
102 }
103
104 void Arrangement::Edge::align()
105 {
106         if(aligned || widgets.empty())
107                 return;
108
109         list<Widget *>::iterator second = widgets.begin();
110         ++second;
111
112         widgets.erase(second, widgets.end());
113         aligned = true;
114 }
115
116 } // namespace GLtk
117 } // namespace Msp