FIFE  be64c707dea6b3250bd4355bf5c825d25920087d
resizablewindow.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2013 by the FIFE team *
3  * http://www.fifengine.net *
4  * This file is part of FIFE:: *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 // Standard C++ library includes
23 #include <cassert>
24 
25 // 3rd party library includes
26 
27 // FIFE includes
28 // These includes are split up in two parts, separated by one empty line
29 // First block: files included from the FIFE root src directory
30 // Second block: files included from the same folder
33 #include "util/base/exception.h"
34 
35 #include "resizablewindow.h"
36 
37 namespace fcn {
39  Window(),
40  m_cursor(FIFE::FifechanManager::instance()->getCursor()),
41  m_borderDistance(5),
42  m_resizable(true),
43  m_resizableTop(true),
44  m_resizableRight(true),
45  m_resizableBottom(true),
46  m_resizableLeft(true),
47  m_resizing(false),
48  m_resizeTop(false),
49  m_resizeRight(false),
50  m_resizeBottom(false),
51  m_resizeLeft(false),
52  m_shove(false) {
53 
54  addKeyListener(this);
55  addFocusListener(this);
56  initCursors();
57  }
58 
60  Window(),
61  m_cursor(FIFE::FifechanManager::instance()->getCursor()),
63  m_resizable(resizable),
64  m_resizableTop(true),
65  m_resizableRight(true),
66  m_resizableBottom(true),
67  m_resizableLeft(true),
68  m_resizing(false),
69  m_resizeTop(false),
70  m_resizeRight(false),
71  m_resizeBottom(false),
72  m_resizeLeft(false),
73  m_shove(false) {
74 
75  addKeyListener(this);
76  addFocusListener(this);
77  initCursors();
78  }
79 
80  ResizableWindow::ResizableWindow(const std::string& caption, bool resizable):
81  Window(),
82  m_cursor(FIFE::FifechanManager::instance()->getCursor()),
84  m_resizable(resizable),
85  m_resizableTop(true),
86  m_resizableRight(true),
87  m_resizableBottom(true),
88  m_resizableLeft(true),
89  m_resizing(false),
90  m_resizeTop(false),
91  m_resizeRight(false),
92  m_resizeBottom(false),
93  m_resizeLeft(false),
94  m_shove(false) {
95 
96  setCaption(caption);
97  addKeyListener(this);
98  addFocusListener(this);
99  initCursors();
100  }
101 
103  }
104 
106  // defines default cursors
107  // don't change the sequence!
108  CursorState state;
109  state.cursorId = FIFE::NC_ARROW;
111  m_saved = state;
113  // left
114  state.cursorId = FIFE::NC_RESIZEWE;
115  m_cursors.push_back(state);
116  // right
117  state.cursorId = FIFE::NC_RESIZEWE;
118  m_cursors.push_back(state);
119  // top
120  state.cursorId = FIFE::NC_RESIZENS;
121  m_cursors.push_back(state);
122  // left and top
124  m_cursors.push_back(state);
125  // right and top
127  m_cursors.push_back(state);
128  // bottom
129  state.cursorId = FIFE::NC_RESIZENS;
130  m_cursors.push_back(state);
131  // left and bottom
133  m_cursors.push_back(state);
134  // right and bottom
136  m_cursors.push_back(state);
137  }
138 
141  switch (type) {
142  case FIFE::CURSOR_NATIVE:
144  break;
145  case FIFE::CURSOR_IMAGE:
147  break;
150  break;
151  default:
152  return;
153  }
154  }
155 
158  switch (type) {
159  case FIFE::CURSOR_NATIVE:
160  m_saved.cursorType = type;
164  break;
165  case FIFE::CURSOR_IMAGE:
166  m_saved.cursorType = type;
170  break;
172  m_saved.cursorType = type;
176  break;
177  default:
179  }
180  }
181 
183  m_borderDistance = border;
184  }
185 
187  return m_borderDistance;
188  }
189 
190  void ResizableWindow::setResizable(bool resizable) {
191  m_resizable = resizable;
192  }
193 
195  return m_resizable;
196  }
197 
198  void ResizableWindow::setTopResizable(bool resizable) {
199  m_resizableTop = resizable;
200  }
201 
203  return m_resizableTop;
204  }
205 
206  void ResizableWindow::setRightResizable(bool resizable) {
207  m_resizableRight = resizable;
208  }
209 
211  return m_resizableRight;
212  }
213 
214  void ResizableWindow::setBottomResizable(bool resizable) {
215  m_resizableBottom = resizable;
216  }
217 
219  return m_resizableBottom;
220  }
221 
222  void ResizableWindow::setLeftResizable(bool resizable) {
223  m_resizableLeft = resizable;
224  }
225 
227  return m_resizableLeft;
228  }
229 
230  void ResizableWindow::setShove(bool shove) {
231  m_shove = shove;
232  }
233 
235  return m_shove;
236  }
237 
238  void ResizableWindow::set(CursorDirections direction, uint32_t cursor_id) {
239  CursorState& state = m_cursors[direction];
241  state.cursorId = cursor_id;
242  state.cursorImage.reset();
243  state.cursorAnimation.reset();
244  }
245 
247  CursorState& state = m_cursors[direction];
249  state.cursorId = FIFE::NC_ARROW;
250  state.cursorImage = image;
251  state.cursorAnimation.reset();
252  }
253 
255  CursorState& state = m_cursors[direction];
257  state.cursorId = FIFE::NC_ARROW;
258  state.cursorImage.reset();
259  state.cursorAnimation = anim;
260  }
261 
263  return m_cursors[direction].cursorType;
264  }
265 
267  return m_cursors[direction].cursorId;
268  }
269 
271  return m_cursors[direction].cursorImage;
272  }
273 
275  return m_cursors[direction].cursorAnimation;
276  }
277 
278  void ResizableWindow::resizeToContent(bool recursiv) {
279  // we keep the size in case we want it resizable
280  if (m_resizable) {
281  int w = getWidth();
282  int h = getHeight();
283  Window::resizeToContent(recursiv);
284  setSize(w, h);
285  } else {
286  Window::resizeToContent(recursiv);
287  }
288  }
289 
290  void ResizableWindow::mouseEntered(MouseEvent& mouseEvent) {
291  if (m_resizable && !m_resizing) {
292  saveCursor();
293  }
294  Window::mouseEntered(mouseEvent);
295  }
296 
297  void ResizableWindow::mouseExited(MouseEvent& mouseEvent) {
299  restoreCursor();
300  } else if (m_resizable && m_resizing) {
301  mouseEvent.consume();
302  }
303  Window::mouseExited(mouseEvent);
304  }
305 
306  void ResizableWindow::mousePressed(MouseEvent& mouseEvent) {
307  if (m_resizable && mouseEvent.getButton() == MouseEvent::Left) {
308  m_resizeLeft = m_resizableLeft && mouseEvent.getX() < m_borderDistance;
309  m_resizeRight = m_resizableRight && mouseEvent.getX() > getWidth() - m_borderDistance;
310  m_resizeTop = m_resizableTop && mouseEvent.getY() < m_borderDistance;
311  m_resizeBottom = m_resizableBottom && mouseEvent.getY() > getHeight() - m_borderDistance;
313  m_resizing = true;
314  mouseEvent.consume();
315  }
316  }
317  Window::mousePressed(mouseEvent);
318  }
319 
320  void ResizableWindow::mouseReleased(MouseEvent& mouseEvent) {
321  if (m_resizing) {
322  adaptLayout();
323  m_resizing = false;
324  if (mouseEvent.getX() <= 0 || mouseEvent.getX() >= getWidth() ||
325  mouseEvent.getY() <= 0 || mouseEvent.getY() >= getHeight()) {
326  mouseExited(mouseEvent);
327  }
328  mouseEvent.consume();
329  } else {
330  Window::mouseReleased(mouseEvent);
331  }
332  }
333 
334  void ResizableWindow::mouseMoved(MouseEvent& mouseEvent) {
336  // use the CursorDirections directly
337  uint32_t index = 0;
338  index += (m_resizableLeft && mouseEvent.getX() < m_borderDistance) ? 1 : 0;
339  index += (m_resizableRight && mouseEvent.getX() > getWidth() - m_borderDistance) ? 2 : 0;
340  index += (m_resizableTop && mouseEvent.getY() < m_borderDistance) ? 3 : 0;
341  index += (m_resizableBottom && mouseEvent.getY() > getHeight() - m_borderDistance) ? 6 : 0;
342 
343  if (index > 0) {
344  // to get the real index value
345  index -= 1;
346  CursorState state = m_cursors[index];
347  FIFE::MouseCursorType type = state.cursorType;
348  switch (type) {
349  case FIFE::CURSOR_NATIVE:
350  m_cursor->set(state.cursorId);
351  break;
352  case FIFE::CURSOR_IMAGE:
353  m_cursor->set(state.cursorImage);
354  break;
356  m_cursor->set(state.cursorAnimation);
357  break;
358  default:
359  break;
360  }
361  mouseEvent.consume();
362  } else {
363  restoreCursor();
364  }
365  }
366  Window::mouseMoved(mouseEvent);
367  }
368 
369  void ResizableWindow::mouseDragged(MouseEvent& mouseEvent) {
370  if (m_resizable && m_resizing) {
371  int x = mouseEvent.getX();
372  int y = mouseEvent.getY();
373  if (m_resizeLeft) {
374  int oldW = getWidth();
375  int newW = oldW - x;
376  if (newW < 0) {
377  newW = 0;
378  }
379  setWidth(newW);
380  if (m_shove) {
381  setX(getX() + x);
382  } else {
383  newW = getWidth();
384  int newX = oldW - newW;
385  setX(getX() + newX);
386  }
387  } else if (m_resizeRight) {
388  setWidth(x);
389  if (x != getWidth() && m_shove) {
390  setX(getX() + (x-getWidth()));
391  }
392  }
393 
394  if (m_resizeTop) {
395  int oldH = getHeight();
396  int newH = oldH - y;
397  if (newH < 0) {
398  newH = 0;
399  }
400  setHeight(newH);
401  if (m_shove) {
402  setY(getY() + y);
403  } else {
404  newH = getHeight();
405  int newY = oldH - newH;
406  setY(getY() + newY);
407  }
408  } else if (m_resizeBottom) {
409  setHeight(y);
410  if (y != getHeight() && m_shove) {
411  setY(getY() + (y-getHeight()));
412  }
413  }
414  mouseEvent.consume();
415  } else {
416  Window::mouseDragged(mouseEvent);
417  }
418  }
419 
420 
421  void ResizableWindow::focusLost(const Event& event) {
422  m_resizing = false;
423  restoreCursor();
424  }
425 }
void setShove(bool shove)
Sets if the widget should be pushed if the size reaches the minimum.
virtual void mousePressed(MouseEvent &mouseEvent)
virtual void mouseExited(MouseEvent &mouseEvent)
virtual void mouseReleased(MouseEvent &mouseEvent)
void set(CursorDirections direction, uint32_t cursor_id=0)
Sets the mouse cursor for the specified direction.
bool isTopResizable() const
Gets if the widget is resizable at top.
std::vector< CursorState > m_cursors
bool isResizable() const
Gets if the widget is resizable.
uint32_t getId(CursorDirections direction) const
Gets the mouse cursor handle for the specified direction.
void setResizableBorderDistance(int32_t border)
Sets the size of the area that is active for resize events.
virtual void mouseMoved(MouseEvent &mouseEvent)
void reset(T *ptr=0)
reset this pointer to a null shared pointer this can be used to lower the reference count of the shar...
Definition: sharedptr.h:164
void setBottomResizable(bool resizable)
Sets if the widget is resizable at bottom.
virtual void resizeToContent(bool recursiv=true)
void setResizable(bool resizable)
Sets if the widget is resizable.
ImagePtr getImage()
Gets the current mouse image.
Definition: cursor.h:134
virtual void focusLost(const Event &event)
bool isBottomResizable() const
Gets if the widget is resizable at bottom.
bool isLeftResizable() const
Gets if the widget is resizable at left.
MouseCursorType
Defines the type of shown cursor native -> default cursor image -> cursor from image pool animation -...
Definition: cursor.h:48
bool isRightResizable() const
Gets if the widget is resizable at right.
void setTopResizable(bool resizable)
Sets if the widget is resizable at top.
MouseCursorType getType() const
Gets the current mouse cursor type.
Definition: cursor.h:126
AnimationPtr getAnimation()
Gets the current mouse animation.
Definition: cursor.h:138
FIFE::ImagePtr getImage(CursorDirections direction)
Gets the mouse image for the specified direction.
void setLeftResizable(bool resizable)
Sets if the widget is resizable at left.
FIFE::MouseCursorType cursorType
int32_t getResizableBorderDistance() const
Gets the size of the area that is active for resize events.
void set(uint32_t cursor_id=0)
Sets the current mouse cursor.
Definition: cursor.cpp:66
FIFE::AnimationPtr getAnimation(CursorDirections direction)
Gets the mouse animation for the specified direction.
bool getShove() const
Gets if the widget should be pushed if the size reaches the minimum.
virtual void mouseDragged(MouseEvent &mouseEvent)
virtual void mouseEntered(MouseEvent &mouseEvent)
uint32_t getId() const
Gets the current mouse cursor handle.
Definition: cursor.h:130
unsigned int uint32_t
Definition: core.h:40
void setRightResizable(bool resizable)
Sets if the widget is resizable at right.
FIFE::Cursor * m_cursor
FIFE::MouseCursorType getType(CursorDirections direction) const
Gets the mouse cursor type for the specified direction.