summaryrefslogtreecommitdiff
path: root/src/gui/widgets/window.cpp
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2014-03-01 19:13:11 +0300
committerAndrei Karas <akaras@inbox.ru>2014-03-01 19:13:11 +0300
commita260aeab234704ace8ba672b1d1ce57e18425e07 (patch)
treee215c6eeeae7e6c2ca4f4453718cef6ca9a8af6a /src/gui/widgets/window.cpp
parent382067b05c4fe97bcf0da0143405375ec295f7c6 (diff)
parent2c62286a7ecf246e8a445dd7d00f618efae2a96a (diff)
downloadplus-a260aeab234704ace8ba672b1d1ce57e18425e07.tar.gz
plus-a260aeab234704ace8ba672b1d1ce57e18425e07.tar.bz2
plus-a260aeab234704ace8ba672b1d1ce57e18425e07.tar.xz
plus-a260aeab234704ace8ba672b1d1ce57e18425e07.zip
Merge branch 'master' into stable
Diffstat (limited to 'src/gui/widgets/window.cpp')
-rw-r--r--src/gui/widgets/window.cpp254
1 files changed, 175 insertions, 79 deletions
diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp
index 36372dcaa..ec83af9a8 100644
--- a/src/gui/widgets/window.cpp
+++ b/src/gui/widgets/window.cpp
@@ -20,6 +20,49 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
#include "gui/widgets/window.h"
#include "client.h"
@@ -29,6 +72,8 @@
#include "soundconsts.h"
#include "soundmanager.h"
+#include "gui/focushandler.h"
+#include "gui/font.h"
#include "gui/gui.h"
#include "gui/viewport.h"
@@ -37,10 +82,6 @@
#include "resources/cursor.h"
#include "resources/image.h"
-#include <guichan/exception.hpp>
-#include <guichan/focushandler.hpp>
-#include <guichan/font.hpp>
-
#include "debug.h"
const int resizeMask = 8 + 4 + 2 + 1;
@@ -50,9 +91,17 @@ int Window::mouseResize = 0;
Window::Window(const std::string &caption, const bool modal,
Window *const parent, std::string skin) :
- gcn::Window(caption),
- Widget2(),
- gcn::WidgetListener(),
+ gcn::Container(nullptr),
+ MouseListener(),
+ WidgetListener(),
+ mCaption(caption),
+ mAlignment(Graphics::CENTER),
+ mPadding(2),
+ mTitleBarHeight(16),
+ mMovable(true),
+ mDragOffsetX(0),
+ mDragOffsetY(0),
+ mMoved(false),
mSkin(nullptr),
mDefaultX(0),
mDefaultY(0),
@@ -74,7 +123,7 @@ Window::Window(const std::string &caption, const bool modal,
mVertexes(new ImageCollection),
mCaptionOffsetX(7),
mCaptionOffsetY(5),
- mCaptionAlign(gcn::Graphics::LEFT),
+ mCaptionAlign(Graphics::LEFT),
mTitlePadding(4),
mGripPadding(2),
mResizeHandles(-1),
@@ -92,16 +141,11 @@ Window::Window(const std::string &caption, const bool modal,
{
logger->log("Window::Window(\"%s\")", caption.c_str());
-#ifndef USE_INTERNALGUICHAN
- mDragOffsetX = 0;
- mDragOffsetY = 0;
-#endif
-
- if (!windowContainer)
- throw GCN_EXCEPTION("Window::Window(): no windowContainer set");
-
windowInstances++;
+// mFrameSize = 1;
+ addMouseListener(this);
+
setFrameSize(0);
setPadding(3);
setTitleBarHeight(20);
@@ -119,7 +163,7 @@ Window::Window(const std::string &caption, const bool modal,
{
setPadding(mSkin->getPadding());
if (getOptionBool("titlebarBold"))
- mCaptionFont = reinterpret_cast<gcn::Font*>(boldFont);
+ mCaptionFont = boldFont;
mTitlePadding = mSkin->getTitlePadding();
mGripPadding = getOption("resizePadding");
mCaptionOffsetX = getOption("captionoffsetx");
@@ -128,12 +172,12 @@ Window::Window(const std::string &caption, const bool modal,
mCaptionOffsetY = getOption("captionoffsety");
if (!mCaptionOffsetY)
mCaptionOffsetY = 5;
- mCaptionAlign = static_cast<gcn::Graphics::Alignment>(
+ mCaptionAlign = static_cast<Graphics::Alignment>(
getOption("captionalign"));
- if (mCaptionAlign < gcn::Graphics::LEFT
- || mCaptionAlign > gcn::Graphics::RIGHT)
+ if (mCaptionAlign < Graphics::LEFT
+ || mCaptionAlign > Graphics::RIGHT)
{
- mCaptionAlign = gcn::Graphics::LEFT;
+ mCaptionAlign = Graphics::LEFT;
}
setTitleBarHeight(getOption("titlebarHeight"));
if (!mTitleBarHeight)
@@ -147,7 +191,8 @@ Window::Window(const std::string &caption, const bool modal,
}
// Add this window to the window container
- windowContainer->add(this);
+ if (windowContainer)
+ windowContainer->add(this);
if (mModal)
{
@@ -208,13 +253,12 @@ void Window::setWindowContainer(WindowContainer *const wc)
windowContainer = wc;
}
-void Window::draw(gcn::Graphics *graphics)
+void Window::draw(Graphics *graphics)
{
if (!mSkin)
return;
BLOCK_START("Window::draw")
- Graphics *const g = static_cast<Graphics*>(graphics);
bool update = false;
if (isBatchDrawRenders(openGLMode))
@@ -230,8 +274,11 @@ void Window::draw(gcn::Graphics *graphics)
mRedraw = false;
update = true;
mVertexes->clear();
- g->calcWindow(mVertexes, 0, 0, mDimension.width,
- mDimension.height, mSkin->getBorder());
+ graphics->calcWindow(mVertexes,
+ 0, 0,
+ mDimension.width,
+ mDimension.height,
+ mSkin->getBorder());
// Draw Close Button
if (mCloseWindowButton)
@@ -240,8 +287,10 @@ void Window::draw(gcn::Graphics *graphics)
mResizeHandles == CLOSE);
if (button)
{
- g->calcTileCollection(mVertexes, button,
- mCloseRect.x, mCloseRect.y);
+ graphics->calcTileCollection(mVertexes,
+ button,
+ mCloseRect.x,
+ mCloseRect.y);
}
}
// Draw Sticky Button
@@ -250,27 +299,33 @@ void Window::draw(gcn::Graphics *graphics)
const Image *const button = mSkin->getStickyImage(mSticky);
if (button)
{
- g->calcTileCollection(mVertexes, button,
- mStickyRect.x, mStickyRect.y);
+ graphics->calcTileCollection(mVertexes,
+ button,
+ mStickyRect.x,
+ mStickyRect.y);
}
}
if (mGrip)
{
- g->calcTileCollection(mVertexes, mGrip,
- mGripRect.x, mGripRect.y);
+ graphics->calcTileCollection(mVertexes,
+ mGrip,
+ mGripRect.x,
+ mGripRect.y);
}
}
else
{
mLastRedraw = false;
}
- g->drawTileCollection(mVertexes);
+ graphics->drawTileCollection(mVertexes);
}
else
{
- g->drawImageRect(0, 0, mDimension.width,
- mDimension.height, mSkin->getBorder());
+ graphics->drawImageRect(0, 0,
+ mDimension.width,
+ mDimension.height,
+ mSkin->getBorder());
// Draw Close Button
if (mCloseWindowButton)
@@ -278,24 +333,24 @@ void Window::draw(gcn::Graphics *graphics)
const Image *const button = mSkin->getCloseImage(
mResizeHandles == CLOSE);
if (button)
- g->drawImage2(button, mCloseRect.x, mCloseRect.y);
+ graphics->drawImage(button, mCloseRect.x, mCloseRect.y);
}
// Draw Sticky Button
if (mStickyButton)
{
const Image *const button = mSkin->getStickyImage(mSticky);
if (button)
- g->drawImage2(button, mStickyRect.x, mStickyRect.y);
+ graphics->drawImage(button, mStickyRect.x, mStickyRect.y);
}
if (mGrip)
- g->drawImage2(mGrip, mGripRect.x, mGripRect.y);
+ graphics->drawImage(mGrip, mGripRect.x, mGripRect.y);
}
// Draw title
if (mShowTitle)
{
- g->setColorAll(mForegroundColor, mForegroundColor2);
+ graphics->setColorAll(mForegroundColor, mForegroundColor2);
int x;
switch (mCaptionAlign)
{
@@ -310,14 +365,14 @@ void Window::draw(gcn::Graphics *graphics)
x = mCaptionOffsetX - mCaptionFont->getWidth(mCaption);
break;
}
- mCaptionFont->drawString(g, mCaption, x, mCaptionOffsetY);
+ mCaptionFont->drawString(graphics, mCaption, x, mCaptionOffsetY);
}
if (update)
{
- g->setRedraw(update);
+ graphics->setRedraw(update);
drawChildren(graphics);
- g->setRedraw(false);
+ graphics->setRedraw(false);
}
else
{
@@ -343,7 +398,7 @@ void Window::setContentSize(int width, int height)
setSize(width, height);
}
-void Window::setLocationRelativeTo(const gcn::Widget *const widget)
+void Window::setLocationRelativeTo(const Widget *const widget)
{
if (!widget)
return;
@@ -360,7 +415,7 @@ void Window::setLocationRelativeTo(const gcn::Widget *const widget)
- mDimension.height) / 2 - y));
}
-void Window::setLocationHorisontallyRelativeTo(const gcn::Widget *const widget)
+void Window::setLocationHorisontallyRelativeTo(const Widget *const widget)
{
if (!widget)
return;
@@ -485,9 +540,9 @@ void Window::setResizable(const bool r)
}
}
-void Window::widgetResized(const gcn::Event &event A_UNUSED)
+void Window::widgetResized(const Event &event A_UNUSED)
{
- const gcn::Rectangle area = getChildrenArea();
+ const Rect area = getChildrenArea();
if (mGrip)
{
@@ -549,12 +604,12 @@ void Window::widgetResized(const gcn::Event &event A_UNUSED)
mRedraw = true;
}
-void Window::widgetMoved(const gcn::Event& event A_UNUSED)
+void Window::widgetMoved(const Event& event A_UNUSED)
{
mRedraw = true;
}
-void Window::widgetHidden(const gcn::Event &event A_UNUSED)
+void Window::widgetHidden(const Event &event A_UNUSED)
{
if (gui)
gui->setCursorType(Cursor::CURSOR_POINTER);
@@ -608,25 +663,21 @@ void Window::setVisible(const bool visible, const bool forceSticky)
// Check if the window is off screen...
if (visible)
- {
ensureOnScreen();
- }
else
- {
mResizeHandles = 0;
- }
if (mStickyButtonLock)
- gcn::Window::setVisible(visible);
+ gcn::Container::setVisible(visible);
else
- gcn::Window::setVisible((!forceSticky && mSticky) || visible);
+ gcn::Container::setVisible((!forceSticky && mSticky) || visible);
if (visible)
{
if (mPlayVisibleSound)
soundManager.playGuiSound(SOUND_SHOW_WINDOW);
if (gui)
{
- gcn::MouseEvent *const event = reinterpret_cast<gcn::MouseEvent*>(
+ MouseEvent *const event = reinterpret_cast<MouseEvent*>(
gui->createMouseEvent(this));
if (event)
{
@@ -653,12 +704,19 @@ void Window::scheduleDelete()
windowContainer->scheduleDelete(this);
}
-void Window::mousePressed(gcn::MouseEvent &event)
+void Window::mousePressed(MouseEvent &event)
{
- // Let Guichan move window to top and figure out title bar drag
- gcn::Window::mousePressed(event);
+ if (event.getSource() == this)
+ {
+ if (getParent())
+ getParent()->moveToTop(this);
- if (event.getButton() == gcn::MouseEvent::LEFT)
+ mDragOffsetX = event.getX();
+ mDragOffsetY = event.getY();
+ mMoved = event.getY() <= static_cast<int>(mTitleBarHeight);
+ }
+
+ if (event.getButton() == MouseEvent::LEFT)
{
const int x = event.getX();
const int y = event.getY();
@@ -696,7 +754,7 @@ void Window::close()
setVisible(false);
}
-void Window::mouseReleased(gcn::MouseEvent &event A_UNUSED)
+void Window::mouseReleased(MouseEvent &event A_UNUSED)
{
if (mGrip && mouseResize)
{
@@ -705,22 +763,21 @@ void Window::mouseReleased(gcn::MouseEvent &event A_UNUSED)
gui->setCursorType(Cursor::CURSOR_POINTER);
}
- // This should be the responsibility of Guichan (and is from 0.8.0 on)
mMoved = false;
}
-void Window::mouseEntered(gcn::MouseEvent &event)
+void Window::mouseEntered(MouseEvent &event)
{
updateResizeHandler(event);
}
-void Window::mouseExited(gcn::MouseEvent &event A_UNUSED)
+void Window::mouseExited(MouseEvent &event A_UNUSED)
{
if (mGrip && !mouseResize && gui)
gui->setCursorType(Cursor::CURSOR_POINTER);
}
-void Window::updateResizeHandler(gcn::MouseEvent &event)
+void Window::updateResizeHandler(MouseEvent &event)
{
if (!gui)
return;
@@ -755,7 +812,7 @@ void Window::updateResizeHandler(gcn::MouseEvent &event)
}
}
-void Window::mouseMoved(gcn::MouseEvent &event)
+void Window::mouseMoved(MouseEvent &event)
{
updateResizeHandler(event);
if (viewport)
@@ -767,12 +824,20 @@ bool Window::canMove() const
return !mStickyButtonLock || !mSticky;
}
-void Window::mouseDragged(gcn::MouseEvent &event)
+void Window::mouseDragged(MouseEvent &event)
{
if (canMove())
{
- // Let Guichan handle title bar drag
- gcn::Window::mouseDragged(event);
+ if (!event.isConsumed() && event.getSource() == this)
+ {
+ if (isMovable() && mMoved)
+ {
+ setPosition(event.getX() - mDragOffsetX + getX(),
+ event.getY() - mDragOffsetY + getY());
+ }
+
+ event.consume();
+ }
}
else
{
@@ -794,7 +859,7 @@ void Window::mouseDragged(gcn::MouseEvent &event)
{
const int dx = event.getX() - mDragOffsetX;
const int dy = event.getY() - mDragOffsetY;
- gcn::Rectangle newDim = getDimension();
+ Rect newDim = getDimension();
if (mouseResize & (TOP | BOTTOM))
{
@@ -1080,10 +1145,10 @@ void Window::adjustSizeToScreen()
if (mDimension.height > screenHeight)
mDimension.height = screenHeight;
if (oldWidth != mDimension.width || oldHeight != mDimension.height)
- widgetResized(gcn::Event(this));
+ widgetResized(Event(this));
}
-int Window::getResizeHandles(const gcn::MouseEvent &event)
+int Window::getResizeHandles(const MouseEvent &event)
{
if (event.getX() < 0 || event.getY() < 0)
return 0;
@@ -1120,7 +1185,7 @@ int Window::getResizeHandles(const gcn::MouseEvent &event)
return resizeHandles;
}
-bool Window::isResizeAllowed(const gcn::MouseEvent &event) const
+bool Window::isResizeAllowed(const MouseEvent &event) const
{
const int y = event.getY();
@@ -1165,7 +1230,7 @@ void Window::clearLayout()
}
}
-LayoutCell &Window::place(const int x, const int y, gcn::Widget *const wg,
+LayoutCell &Window::place(const int x, const int y, Widget *const wg,
const int w, const int h)
{
add(wg);
@@ -1192,7 +1257,7 @@ void Window::redraw()
{
if (mLayout)
{
- const gcn::Rectangle area = getChildrenArea();
+ const Rect area = getChildrenArea();
int w = area.width;
int h = area.height;
mLayout->reflow(w, h);
@@ -1228,12 +1293,12 @@ void Window::ensureOnScreen()
mDimension.y = 0;
}
-gcn::Rectangle Window::getWindowArea() const
+Rect Window::getWindowArea() const
{
- return gcn::Rectangle(mPadding,
- mPadding,
- mDimension.width - mPadding * 2,
- mDimension.height - mPadding * 2);
+ return Rect(mPadding,
+ mPadding,
+ mDimension.width - mPadding * 2,
+ mDimension.height - mPadding * 2);
}
int Window::getOption(const std::string &name, const int def) const
@@ -1255,6 +1320,37 @@ bool Window::getOptionBool(const std::string &name, const bool def) const
return def;
}
+Rect Window::getChildrenArea()
+{
+ return Rect(mPadding,
+ mTitleBarHeight,
+ mDimension.width - mPadding * 2,
+ mDimension.height - mPadding - mTitleBarHeight);
+}
+
+void Window::resizeToContent()
+{
+ int w = 0;
+ int h = 0;
+ for (WidgetListConstIterator it = mWidgets.begin();
+ it != mWidgets.end(); ++ it)
+ {
+ const Widget *const widget = *it;
+ const int x = widget->getX();
+ const int y = widget->getY();
+ const int width = widget->getWidth();
+ const int height = widget->getHeight();
+ if (x + width > w)
+ w = x + width;
+
+ if (y + height > h)
+ h = y + height;
+ }
+
+ setSize(w + 2 * mPadding,
+ h + mPadding + mTitleBarHeight);
+}
+
#ifdef USE_PROFILER
void Window::logic()
{