aboutsummaryrefslogtreecommitdiff
path: root/src/ScreenPlacement.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/ScreenPlacement.cc')
-rw-r--r--src/ScreenPlacement.cc207
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>
37using std::cerr;
38using std::endl;
39
40ScreenPlacement::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
55bool 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
132template <>
133void 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
146template <>
147std::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
162template <>
163void 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
173template <>
174std::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
186template <>
187void 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
197template <>
198std::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}