diff options
Diffstat (limited to 'src/ScreenPlacement.cc')
-rw-r--r-- | src/ScreenPlacement.cc | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/src/ScreenPlacement.cc b/src/ScreenPlacement.cc new file mode 100644 index 0000000..b455fc7 --- /dev/null +++ b/src/ScreenPlacement.cc | |||
@@ -0,0 +1,207 @@ | |||
1 | // ScreenPlacement.cc | ||
2 | // Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | // $Id$ | ||
23 | |||
24 | #include "ScreenPlacement.hh" | ||
25 | |||
26 | |||
27 | #include "RowSmartPlacement.hh" | ||
28 | #include "UnderMousePlacement.hh" | ||
29 | #include "ColSmartPlacement.hh" | ||
30 | #include "CascadePlacement.hh" | ||
31 | |||
32 | #include "Screen.hh" | ||
33 | #include "Window.hh" | ||
34 | |||
35 | #include <iostream> | ||
36 | #include <exception> | ||
37 | using std::cerr; | ||
38 | using std::endl; | ||
39 | |||
40 | ScreenPlacement::ScreenPlacement(BScreen &screen): | ||
41 | m_row_direction(screen.resourceManager(), LEFTRIGHT, | ||
42 | screen.name()+".rowPlacementDirection", | ||
43 | screen.altName()+".RowPlacementDirection"), | ||
44 | m_col_direction(screen.resourceManager(), TOPBOTTOM, | ||
45 | screen.name()+".colPlacementDirection", | ||
46 | screen.altName()+".ColPlacementDirection"), | ||
47 | m_placement_policy(screen.resourceManager(), ROWSMARTPLACEMENT, | ||
48 | screen.name()+".windowPlacement", | ||
49 | screen.altName()+".WindowPlacement"), | ||
50 | m_old_policy(*m_placement_policy), | ||
51 | m_strategy(new RowSmartPlacement()) | ||
52 | { | ||
53 | } | ||
54 | |||
55 | bool ScreenPlacement::placeWindow(const std::vector<FluxboxWindow *> &windowlist, | ||
56 | const FluxboxWindow &win, | ||
57 | int &place_x, int &place_y) { | ||
58 | |||
59 | // check the resource placement and see if has changed | ||
60 | // and if so update the strategy | ||
61 | if (m_old_policy != *m_placement_policy) { | ||
62 | m_old_policy = *m_placement_policy; | ||
63 | switch (*m_placement_policy) { | ||
64 | case ROWSMARTPLACEMENT: | ||
65 | m_strategy.reset(new RowSmartPlacement()); | ||
66 | break; | ||
67 | case COLSMARTPLACEMENT: | ||
68 | m_strategy.reset(new ColSmartPlacement()); | ||
69 | break; | ||
70 | case CASCADEPLACEMENT: | ||
71 | m_strategy.reset(new CascadePlacement(win.screen())); | ||
72 | break; | ||
73 | case UNDERMOUSEPLACEMENT: | ||
74 | m_strategy.reset(new UnderMousePlacement()); | ||
75 | break; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | // view (screen + head) constraints | ||
80 | int head = (signed) win.screen().getCurrHead(); | ||
81 | int head_left = (signed) win.screen().maxLeft(head); | ||
82 | int head_right = (signed) win.screen().maxRight(head); | ||
83 | int head_top = (signed) win.screen().maxTop(head); | ||
84 | int head_bot = (signed) win.screen().maxBottom(head); | ||
85 | |||
86 | // start placement, top left corner | ||
87 | place_x = head_left; | ||
88 | place_y = head_top; | ||
89 | |||
90 | bool placed = false; | ||
91 | try { | ||
92 | placed = m_strategy->placeWindow(windowlist, | ||
93 | win, | ||
94 | place_x, place_y); | ||
95 | } catch (std::bad_cast cast) { | ||
96 | // This should not happen. | ||
97 | // If for some reason we change the PlacementStrategy in Screen | ||
98 | // from ScreenPlacement to something else then we might get | ||
99 | // bad_cast from some placement strategies. | ||
100 | cerr<<"Failed to place window: "<<cast.what()<<endl; | ||
101 | } | ||
102 | |||
103 | if (!placed) { | ||
104 | // Create fallback strategy, when we need it the first time | ||
105 | // This strategy must succeed! | ||
106 | if (m_fallback_strategy.get() == 0) | ||
107 | m_fallback_strategy.reset(new CascadePlacement(win.screen())); | ||
108 | |||
109 | m_fallback_strategy->placeWindow(windowlist, | ||
110 | win, | ||
111 | place_x, place_y); | ||
112 | } | ||
113 | |||
114 | |||
115 | |||
116 | int win_w = win.width() + win.fbWindow().borderWidth()*2, | ||
117 | win_h = win.height() + win.fbWindow().borderWidth()*2; | ||
118 | |||
119 | |||
120 | // make sure the window is inside our screen(head) area | ||
121 | if (place_x + win_w > head_right) | ||
122 | place_x = (head_right - win_w) / 2; | ||
123 | if (place_y + win_h > head_bot) | ||
124 | place_y = (head_bot - win_h) / 2; | ||
125 | |||
126 | return true; | ||
127 | } | ||
128 | |||
129 | |||
130 | |||
131 | ////////////////////// Placement Resources | ||
132 | template <> | ||
133 | void FbTk::Resource<ScreenPlacement::PlacementPolicy>::setFromString(const char *str) { | ||
134 | if (strcasecmp("RowSmartPlacement", str) == 0) | ||
135 | *(*this) = ScreenPlacement::ROWSMARTPLACEMENT; | ||
136 | else if (strcasecmp("ColSmartPlacement", str) == 0) | ||
137 | *(*this) = ScreenPlacement::COLSMARTPLACEMENT; | ||
138 | else if (strcasecmp("UnderMousePlacement", str) == 0) | ||
139 | *(*this) = ScreenPlacement::UNDERMOUSEPLACEMENT; | ||
140 | else if (strcasecmp("CascadePlacement", str) == 0) | ||
141 | *(*this) = ScreenPlacement::CASCADEPLACEMENT; | ||
142 | else | ||
143 | setDefaultValue(); | ||
144 | } | ||
145 | |||
146 | template <> | ||
147 | std::string FbTk::Resource<ScreenPlacement::PlacementPolicy>::getString() const { | ||
148 | switch (*(*this)) { | ||
149 | case ScreenPlacement::ROWSMARTPLACEMENT: | ||
150 | return "RowSmartPlacement"; | ||
151 | case ScreenPlacement::COLSMARTPLACEMENT: | ||
152 | return "ColSmartPlacement"; | ||
153 | case ScreenPlacement::UNDERMOUSEPLACEMENT: | ||
154 | return "UnderMousePlacement"; | ||
155 | case ScreenPlacement::CASCADEPLACEMENT: | ||
156 | return "CascadePlacement"; | ||
157 | } | ||
158 | |||
159 | return "RowSmartPlacement"; | ||
160 | } | ||
161 | |||
162 | template <> | ||
163 | void FbTk::Resource<ScreenPlacement::RowDirection>::setFromString(const char *str) { | ||
164 | if (strcasecmp("LeftToRight", str) == 0) | ||
165 | *(*this) = ScreenPlacement::LEFTRIGHT; | ||
166 | else if (strcasecmp("RightToLeft", str) == 0) | ||
167 | *(*this) = ScreenPlacement::RIGHTLEFT; | ||
168 | else | ||
169 | setDefaultValue(); | ||
170 | |||
171 | } | ||
172 | |||
173 | template <> | ||
174 | std::string FbTk::Resource<ScreenPlacement::RowDirection>::getString() const { | ||
175 | switch (*(*this)) { | ||
176 | case ScreenPlacement::LEFTRIGHT: | ||
177 | return "LeftToRight"; | ||
178 | case ScreenPlacement::RIGHTLEFT: | ||
179 | return "RightToLeft"; | ||
180 | } | ||
181 | |||
182 | return "LeftToRight"; | ||
183 | } | ||
184 | |||
185 | |||
186 | template <> | ||
187 | void FbTk::Resource<ScreenPlacement::ColumnDirection>::setFromString(const char *str) { | ||
188 | if (strcasecmp("TopToBottom", str) == 0) | ||
189 | *(*this) = ScreenPlacement::TOPBOTTOM; | ||
190 | else if (strcasecmp("BottomToTop", str) == 0) | ||
191 | *(*this) = ScreenPlacement::BOTTOMTOP; | ||
192 | else | ||
193 | setDefaultValue(); | ||
194 | |||
195 | } | ||
196 | |||
197 | template <> | ||
198 | std::string FbTk::Resource<ScreenPlacement::ColumnDirection>::getString() const { | ||
199 | switch (*(*this)) { | ||
200 | case ScreenPlacement::TOPBOTTOM: | ||
201 | return "TopToBottom"; | ||
202 | case ScreenPlacement::BOTTOMTOP: | ||
203 | return "BottomToTop"; | ||
204 | } | ||
205 | |||
206 | return "TopToBottom"; | ||
207 | } | ||