summaryrefslogtreecommitdiff
path: root/src/gui/window.cpp
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2007-04-15 01:22:17 +0000
committerBjørn Lindeijer <bjorn@lindeijer.nl>2007-04-15 01:22:17 +0000
commit59c80255ddd1de9698a75c49ec7a6a1b7c4c1069 (patch)
tree53236090da5c6c6fc92e948e94d4c2859ae163f8 /src/gui/window.cpp
parenta3770925c652e0d2bab15f5bd46fa740345a28d0 (diff)
downloadmana-59c80255ddd1de9698a75c49ec7a6a1b7c4c1069.tar.gz
mana-59c80255ddd1de9698a75c49ec7a6a1b7c4c1069.tar.bz2
mana-59c80255ddd1de9698a75c49ec7a6a1b7c4c1069.tar.xz
mana-59c80255ddd1de9698a75c49ec7a6a1b7c4c1069.zip
Reimplemented window resizing. It is now once again possible to resize windows
using their borders (except for the top one, since that's the title bar for Guichan) and the resize grip in the bottom right is much easier to grab. Needs some testing.
Diffstat (limited to 'src/gui/window.cpp')
-rw-r--r--src/gui/window.cpp191
1 files changed, 124 insertions, 67 deletions
diff --git a/src/gui/window.cpp b/src/gui/window.cpp
index 4f26af79..bd3e7eb5 100644
--- a/src/gui/window.cpp
+++ b/src/gui/window.cpp
@@ -24,10 +24,13 @@
#include "window.h"
#include <guichan/exception.hpp>
+#include <guichan/widgets/icon.hpp>
#include "gccontainer.h"
#include "windowcontainer.h"
+#include "widgets/resizegrip.h"
+
#include "../configlistener.h"
#include "../configuration.h"
#include "../graphics.h"
@@ -36,11 +39,10 @@
#include "../resources/image.h"
#include "../resources/resourcemanager.h"
-ConfigListener *Window::windowConfigListener = NULL;
-WindowContainer *Window::windowContainer = NULL;
+ConfigListener *Window::windowConfigListener = 0;
+WindowContainer *Window::windowContainer = 0;
int Window::instances = 0;
ImageRect Window::border;
-Image *Window::resizeGrip;
class WindowConfigListener : public ConfigListener
{
@@ -54,13 +56,13 @@ class WindowConfigListener : public ConfigListener
Window::Window(const std::string& caption, bool modal, Window *parent):
gcn::Window(caption),
+ mGrip(0),
mParent(parent),
mWindowName("window"),
- mSnapSize(8),
mShowTitle(true),
mModal(modal),
mResizable(false),
- mMouseResize(false),
+ mMouseResize(0),
mSticky(false),
mMinWinWidth(100),
mMinWinHeight(28),
@@ -87,7 +89,6 @@ Window::Window(const std::string& caption, bool modal, Window *parent):
border.grid[6] = dBorders->getSubImage(0, 15, 4, 4);
border.grid[7] = dBorders->getSubImage(4, 15, 3, 4);
border.grid[8] = dBorders->getSubImage(7, 15, 4, 4);
- resizeGrip = resman->getImage("graphics/gui/resize.png");
dBorders->decRef();
windowConfigListener = new WindowConfigListener();
// Send GUI alpha changed for initialization
@@ -151,10 +152,10 @@ Window::~Window()
delete border.grid[6];
delete border.grid[7];
delete border.grid[8];
- resizeGrip->decRef();
}
delete mChrome;
+ delete mGrip;
}
void Window::setWindowContainer(WindowContainer *wc)
@@ -162,22 +163,15 @@ void Window::setWindowContainer(WindowContainer *wc)
windowContainer = wc;
}
-void Window::draw(gcn::Graphics* graphics)
+void Window::draw(gcn::Graphics *graphics)
{
- Graphics *g = (Graphics*)graphics;
+ Graphics *g = static_cast<Graphics*>(graphics);
g->drawImageRect(0, 0, getWidth(), getHeight(), border);
- // Draw grip
- if (mResizable)
- {
- g->drawImage(Window::resizeGrip,
- getWidth() - resizeGrip->getWidth(),
- getHeight() - resizeGrip->getHeight());
- }
-
// Draw title
- if (mShowTitle) {
+ if (mShowTitle)
+ {
graphics->setFont(getFont());
graphics->drawText(getCaption(), 7, 5, gcn::Graphics::LEFT);
}
@@ -203,6 +197,37 @@ void Window::setContentSize(int width, int height)
setContentHeight(height);
}
+void Window::setWidth(int width)
+{
+ gcn::Window::setWidth(width);
+
+ if (mGrip)
+ {
+ mGrip->setX(getWidth() - mGrip->getWidth() - getChildrenArea().x);
+ }
+}
+
+void Window::setHeight(int height)
+{
+ gcn::Window::setHeight(height);
+
+ if (mGrip)
+ {
+ mGrip->setY(getHeight() - mGrip->getHeight() - getChildrenArea().y);
+ }
+}
+
+void Window::setDimension(const gcn::Rectangle &dimension)
+{
+ gcn::Window::setDimension(dimension);
+
+ if (mGrip)
+ {
+ mGrip->setX(getWidth() - mGrip->getWidth() - getChildrenArea().x);
+ mGrip->setY(getHeight() - mGrip->getHeight() - getChildrenArea().y);
+ }
+}
+
void Window::setLocationRelativeTo(gcn::Widget* widget)
{
int wx, wy;
@@ -238,6 +263,19 @@ void Window::setMaxHeight(unsigned int height)
void Window::setResizable(bool r)
{
mResizable = r;
+
+ if (mResizable)
+ {
+ mGrip = new ResizeGrip();
+ mGrip->setX(getWidth() - mGrip->getWidth() - getChildrenArea().x);
+ mGrip->setY(getHeight() - mGrip->getHeight() - getChildrenArea().y);
+ gcn::Window::add(mGrip);
+ }
+ else
+ {
+ delete mGrip;
+ mGrip = 0;
+ }
}
bool Window::isResizable()
@@ -250,16 +288,18 @@ void Window::setSticky(bool sticky)
mSticky = sticky;
}
-bool Window::isSticky() {
+bool Window::isSticky()
+{
return mSticky;
}
-void Window::setVisible(bool visible) {
- if(isSticky())
+void Window::setVisible(bool visible)
+{
+ if (isSticky())
{
gcn::Window::setVisible(true);
- }
- else
+ }
+ else
{
gcn::Window::setVisible(visible);
}
@@ -285,15 +325,27 @@ void Window::mousePressed(gcn::MouseEvent &event)
// Let Guichan move window to top and figure out title bar drag
gcn::Window::mousePressed(event);
- int x = event.getX();
- int y = event.getY();
+ const int x = event.getX();
+ const int y = event.getY();
+ mMouseResize = 0;
- // Activate resizing if the left mouse button was pressed on the grip
- mMouseResize =
- isResizable() &&
- event.getButton() == gcn::MouseEvent::LEFT &&
- getGripDimension().isPointInRect(x, y) &&
- !getChildrenArea().isPointInRect(x, y);
+ // Activate resizing handles as appropriate
+ if (event.getSource() == this && isResizable() &&
+ event.getButton() == gcn::MouseEvent::LEFT &&
+ !getChildrenArea().isPointInRect(x, y))
+ {
+ mMouseResize |= (x > getWidth() - resizeBorderWidth) ? RIGHT :
+ (x < resizeBorderWidth) ? LEFT : 0;
+ mMouseResize |= (y > getHeight() - resizeBorderWidth) ? BOTTOM :
+ (y < resizeBorderWidth) ? TOP : 0;
+ }
+ else if (event.getSource() == mGrip)
+ {
+ mDragOffsetX = x + mGrip->getX();
+ mDragOffsetY = y + mGrip->getY();
+ mMouseResize |= BOTTOM | RIGHT;
+ mIsMoving = false;
+ }
}
void Window::mouseDragged(gcn::MouseEvent &event)
@@ -301,20 +353,47 @@ void Window::mouseDragged(gcn::MouseEvent &event)
// Let Guichan handle title bar drag
gcn::Window::mouseDragged(event);
- // Keep guichan window inside screen
- int newX = std::max(0, getX());
- int newY = std::max(0, getY());
- newX = std::min(windowContainer->getWidth() - getWidth(), newX);
- newY = std::min(windowContainer->getHeight() - getHeight(), newY);
- setPosition(newX, newY);
+ // Keep guichan window inside screen when it may be moved
+ if (isMovable() && mIsMoving)
+ {
+ int newX = std::max(0, getX());
+ int newY = std::max(0, getY());
+ newX = std::min(windowContainer->getWidth() - getWidth(), newX);
+ newY = std::min(windowContainer->getHeight() - getHeight(), newY);
+ setPosition(newX, newY);
+ }
if (mMouseResize && !mIsMoving)
{
+ const int dx = event.getX() - mDragOffsetX +
+ ((event.getSource() == mGrip) ? mGrip->getX() : 0);
+ const int dy = event.getY() - mDragOffsetY +
+ ((event.getSource() == mGrip) ? mGrip->getY() : 0);
gcn::Rectangle newDim = getDimension();
- // We're dragging bottom right
- newDim.width += event.getX() - mDragOffsetX;
- newDim.height += event.getY() - mDragOffsetY;
+ if (mMouseResize & (TOP | BOTTOM))
+ {
+ int newHeight = newDim.height + ((mMouseResize & TOP) ? -dy : dy);
+ newDim.height = std::min(mMaxWinHeight,
+ std::max(mMinWinHeight, newHeight));
+
+ if (mMouseResize & TOP)
+ {
+ newDim.y -= newDim.height - getHeight();
+ }
+ }
+
+ if (mMouseResize & (LEFT | RIGHT))
+ {
+ int newWidth = newDim.width + ((mMouseResize & LEFT) ? -dx : dx);
+ newDim.width = std::min(mMaxWinWidth,
+ std::max(mMinWinWidth, newWidth));
+
+ if (mMouseResize & LEFT)
+ {
+ newDim.x -= newDim.width - getWidth();
+ }
+ }
// Keep guichan window inside screen (supports resizing any side)
if (newDim.x < 0)
@@ -336,29 +415,16 @@ void Window::mouseDragged(gcn::MouseEvent &event)
newDim.height = windowContainer->getHeight() - newDim.y;
}
- // Keep the window at least its minimum size
- if (newDim.width < mMinWinWidth)
- {
- newDim.width = mMinWinWidth;
- }
- else if (newDim.width > mMaxWinWidth)
- {
- newDim.width = mMaxWinWidth;
- }
-
- if (newDim.height < mMinWinHeight)
+ // Update mouse offset when dragging bottom or right border
+ if (mMouseResize & BOTTOM)
{
- newDim.height = mMinWinHeight;
+ mDragOffsetY += newDim.height - getHeight();
}
- else if (newDim.height > mMaxWinHeight)
+ if (mMouseResize & RIGHT)
{
- newDim.height = mMaxWinHeight;
+ mDragOffsetX += newDim.width - getWidth();
}
- // Update mouse offset when dragging bottom or right border
- mDragOffsetX += newDim.width - getWidth();
- mDragOffsetY += newDim.height - getHeight();
-
// Set the new window and content dimensions
setDimension(newDim);
const gcn::Rectangle area = getChildrenArea();
@@ -366,15 +432,6 @@ void Window::mouseDragged(gcn::MouseEvent &event)
}
}
-gcn::Rectangle
-Window::getGripDimension()
-{
- return gcn::Rectangle(getWidth() - resizeGrip->getWidth(),
- getHeight() - resizeGrip->getHeight(),
- getWidth(),
- getHeight());
-}
-
void
Window::loadWindowState()
{