summaryrefslogtreecommitdiff
path: root/src/gui/window.cpp
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2005-06-16 01:29:37 +0000
committerBjørn Lindeijer <bjorn@lindeijer.nl>2005-06-16 01:29:37 +0000
commit06afc063b8538b90b8dd8eb662a9ae0e11812963 (patch)
treefbae681cc37ebac36a1ededa7a292d5ec8505842 /src/gui/window.cpp
parentcf0b73ed23fa2213521c23fcd927aab37151a484 (diff)
downloadmana-06afc063b8538b90b8dd8eb662a9ae0e11812963.tar.gz
mana-06afc063b8538b90b8dd8eb662a9ae0e11812963.tar.bz2
mana-06afc063b8538b90b8dd8eb662a9ae0e11812963.tar.xz
mana-06afc063b8538b90b8dd8eb662a9ae0e11812963.zip
Fixed window resizing to work properly, and on all edges and corners.
Diffstat (limited to 'src/gui/window.cpp')
-rw-r--r--src/gui/window.cpp222
1 files changed, 143 insertions, 79 deletions
diff --git a/src/gui/window.cpp b/src/gui/window.cpp
index c5ef7a54..aa8569f2 100644
--- a/src/gui/window.cpp
+++ b/src/gui/window.cpp
@@ -35,11 +35,12 @@ Window::Window(const std::string& caption, bool modal, Window *parent):
parent(parent),
snapSize(8),
modal(modal),
- resizeable(false),
- minWinWidth(256),
- minWinHeight(128),
- maxWinWidth(512),
- maxWinHeight(512)
+ resizable(false),
+ mMouseResize(false),
+ minWinWidth(6),
+ minWinHeight(23),
+ maxWinWidth(INT_MAX),
+ maxWinHeight(INT_MAX)
{
logger->log("Window::Window(\"%s\")", caption.c_str());
@@ -192,14 +193,14 @@ void Window::setMaxHeight(unsigned int height)
maxWinHeight = height;
}
-void Window::setResizeable(bool r)
+void Window::setResizable(bool r)
{
- resizeable = r;
+ resizable = r;
}
-bool Window::getResizeable()
+bool Window::getResizable()
{
- return resizeable;
+ return resizable;
}
Window *Window::getParentWindow()
@@ -224,94 +225,158 @@ void Window::add(gcn::Widget *w, int x, int y)
void Window::mousePress(int x, int y, int button)
{
- if (getParent() != NULL)
+ // Let Guichan move window to top and figure out title bar drag
+ gcn::Window::mousePress(x, y, button);
+
+ // If the mouse is not inside the content, the press must have been on the
+ // border, and is a candidate for a resize.
+ if (getResizable() && button == 1 &&
+ !getContentDimension().isPointInRect(x, y) &&
+ !(mMouseDrag && y > (int)getPadding()))
{
- getParent()->moveToTop(this);
+ mMouseResize = true;
+ mMouseXOffset = x;
+ mMouseYOffset = y;
+
+ // Determine which borders are being dragged
+ mLeftBorderDrag = (x < 10);
+ mTopBorderDrag = (y < 10);
+ mRightBorderDrag = (x >= getWidth() - 10);
+ mBottomBorderDrag = (y >= getHeight() - 10);
}
+}
- if (hasMouse() && button == 1)
+void Window::mouseMotion(int x, int y)
+{
+ if (mMouseDrag || mMouseResize)
{
- mMouseXOffset = x;
- mMouseYOffset = y;
-
- if (isMovable() && y < (int)(getTitleBarHeight() + getPadding()))
+ int dx = x - mMouseXOffset;
+ int dy = y - mMouseYOffset;
+ gcn::Rectangle newDim = getDimension();
+
+ // Change the dimension according to dragging and moving
+ if (mMouseResize && getResizable())
{
- mMouseDrag = true;
+ if (mLeftBorderDrag)
+ {
+ newDim.x += dx;
+ newDim.width -= dx;
+ }
+
+ if (mTopBorderDrag)
+ {
+ newDim.y += dy;
+ newDim.height -= dy;
+ }
+
+ if (mBottomBorderDrag)
+ {
+ newDim.height += dy;
+ }
+
+ if (mRightBorderDrag)
+ {
+ newDim.width += dx;
+ }
+ }
+ else if (mMouseDrag && isMovable())
+ {
+ newDim.x += dx;
+ newDim.y += dy;
}
- if (getResizeable())
+ // Keep guichan window inside screen
+ if (newDim.x < 0)
{
- if (x > (getWidth() - 2 * getPadding()))
- {
- winXResizing = true;
- mMouseDrag = true;
- }
-
- if (y > (getHeight() - 2 * getPadding()))
- {
- winYResizing = true;
- mMouseDrag = true;
- }
+ if (mMouseResize)
+ {
+ newDim.width += newDim.x;
+ }
+
+ newDim.x = 0;
}
- }
-}
+ if (newDim.y < 0)
+ {
+ if (mMouseResize)
+ {
+ newDim.height += newDim.y;
+ }
-void Window::mouseMotion(int mx, int my)
-{
- if (mMouseDrag && isMovable())
- {
- int x = mx - mMouseXOffset + getX();
- int y = my - mMouseYOffset + getY();
+ newDim.y = 0;
+ }
+ if (newDim.x + newDim.width > screen->w)
+ {
+ if (mMouseResize)
+ {
+ newDim.width = screen->w - newDim.x;
+ }
+ else
+ {
+ newDim.x = screen->w - newDim.width;
+ }
+ }
+ if (newDim.y + newDim.height > screen->h)
+ {
+ if (mMouseResize)
+ {
+ newDim.height = screen->h - newDim.y;
+ }
+ else
+ {
+ newDim.y = screen->h - newDim.height;
+ }
+ }
+
+ // Keep the window at least its minimum size
+ int Xcorrection = 0;
+ int Ycorrection = 0;
+
+ if (newDim.width < minWinWidth)
+ {
+ Xcorrection = minWinWidth - newDim.width;
+ }
+ else if (newDim.width > maxWinWidth)
+ {
+ Xcorrection = maxWinWidth - newDim.width;
+ }
+
+ if (newDim.height < minWinHeight)
+ {
+ Ycorrection = minWinHeight - newDim.height;
+ }
+ else if (newDim.height > maxWinHeight)
+ {
+ Ycorrection = maxWinHeight - newDim.height;
+ }
- // Keep guichan window inside window
- if (x < 0) x = 0;
- if (y < 0) y = 0;
- if (x + getWidth() > screen->w) x = screen->w - getWidth();
- if (y + getHeight() > screen->h) y = screen->h - getHeight();
+ if (mLeftBorderDrag) newDim.x -= Xcorrection;
+ newDim.width += Xcorrection;
+
+ if (mTopBorderDrag) newDim.y -= Ycorrection;
+ newDim.height += Ycorrection;
// Snap window to edges
//if (x < snapSize) x = 0;
//if (y < snapSize) y = 0;
//if (x + winWidth + snapSize > screen->w) x = screen->w - winWidth;
//if (y + winHeight + snapSize > screen->h) y = screen->h - winHeight;
-
- if (getResizeable() &&
- ((mx > (getWidth() - 16)) || (my > (getHeight() - 16))))
+
+ // Update mouse offset when dragging bottom or right border
+ if (mBottomBorderDrag)
{
- // Resize in X direction
- if (winXResizing)
- {
- if (mx < minWinWidth)
- {
- mx = minWinWidth;
- }
- else if (mx >= maxWinWidth)
- {
- mx = maxWinWidth - 1;
- }
-
- setWidth(mx);
- }
-
- // Resize in Y direction
- if (winYResizing)
- {
- if (my < minWinHeight)
- {
- my = minWinHeight;
- }
- else if (my >= maxWinHeight)
- {
- my = maxWinHeight - 1;
- }
-
- setHeight(my);
- }
+ mMouseYOffset += newDim.height - getHeight();
}
- else
+ if (mRightBorderDrag)
+ {
+ mMouseXOffset += newDim.width - getWidth();
+ }
+
+ // Set the new window and content dimensions
+ setDimension(newDim);
+
+ if (mContent != NULL && mMouseResize)
{
- // Move
- setPosition(x, y);
+ mContent->setDimension(getContentDimension());
}
}
}
@@ -320,9 +385,8 @@ void Window::mouseRelease(int x, int y, int button)
{
if (button == 1)
{
+ mMouseResize = false;
mMouseDrag = false;
- winXResizing = false;
- winYResizing = false;
}
}