| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- //
- // Urho3D Engine
- // Copyright (c) 2008-2011 Lasse Öörni
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- //
- #include "Precompiled.h"
- #include "InputEvents.h"
- #include "Window.h"
- #include "DebugNew.h"
- static const int DEFAULT_RESIZE_BORDER = 4;
- Window::Window(const std::string& name) :
- BorderImage(name),
- mMovable(false),
- mResizable(false),
- mMinSize(0, 0),
- mMaxSize(M_MAX_INT, M_MAX_INT),
- mResizeBorder(DEFAULT_RESIZE_BORDER, DEFAULT_RESIZE_BORDER, DEFAULT_RESIZE_BORDER, DEFAULT_RESIZE_BORDER),
- mDragMode(DRAG_NONE)
- {
- mBringToFront = true;
- mEnabled = true;
-
- validateSize();
- }
- Window::~Window()
- {
- }
- void Window::setStyle(const XMLElement& element, ResourceCache* cache)
- {
- BorderImage::setStyle(element, cache);
-
- if (element.hasChildElement("minsize"))
- setMinSize(element.getChildElement("minsize").getIntVector2("value"));
- if (element.hasChildElement("maxsize"))
- setMaxSize(element.getChildElement("maxsize").getIntVector2("value"));
- if (element.hasChildElement("resizeborder"))
- setResizeBorder(element.getChildElement("resizeborder").getIntRect("value"));
- if (element.hasChildElement("movable"))
- setMovable(element.getChildElement("movable").getBool("enable"));
- if (element.hasChildElement("resizable"))
- setResizable(element.getChildElement("resizable").getBool("enable"));
- }
- void Window::onDragStart(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers)
- {
- if ((buttons != MOUSEB_LEFT) || (!checkAlignment()))
- {
- mDragMode = DRAG_NONE;
- return;
- }
-
- mDragStartPosition = screenPosition;
- mOriginalPosition = getPosition();
- mOriginalSize = getSize();
-
- // Identify drag type
- // Top row
- if (position.mY < mResizeBorder.mTop)
- {
- if (mMovable)
- mDragMode = DRAG_MOVE;
- if (mResizable)
- {
- mDragMode = DRAG_RESIZE_TOP;
- if (position.mX < mResizeBorder.mLeft)
- mDragMode = DRAG_RESIZE_TOPLEFT;
- if (position.mX >= mOriginalSize.mX - mResizeBorder.mRight)
- mDragMode = DRAG_RESIZE_TOPRIGHT;
- }
- }
- // Bottom row
- else if (position.mY >= mOriginalSize.mY - mResizeBorder.mBottom)
- {
- if (mMovable)
- mDragMode = DRAG_MOVE;
- if (mResizable)
- {
- mDragMode = DRAG_RESIZE_BOTTOM;
- if (position.mX < mResizeBorder.mLeft)
- mDragMode = DRAG_RESIZE_BOTTOMLEFT;
- if (position.mX >= mOriginalSize.mX - mResizeBorder.mRight)
- mDragMode = DRAG_RESIZE_BOTTOMRIGHT;
- }
- }
- // Middle
- else
- {
- if (mMovable)
- mDragMode = DRAG_MOVE;
- if (mResizable)
- {
- if (position.mX < mResizeBorder.mLeft)
- mDragMode = DRAG_RESIZE_LEFT;
- if (position.mX >= mOriginalSize.mX - mResizeBorder.mRight)
- mDragMode = DRAG_RESIZE_RIGHT;
- }
- }
- }
- void Window::onDragMove(const IntVector2& position, const IntVector2& screenPosition, int buttons, int qualifiers)
- {
- if (mDragMode == DRAG_NONE)
- return;
-
- IntVector2 delta = screenPosition - mDragStartPosition;
-
- switch (mDragMode)
- {
- case DRAG_MOVE:
- setPosition(mOriginalPosition + delta);
- break;
-
- case DRAG_RESIZE_TOPLEFT:
- setPosition(mOriginalPosition + delta);
- setSize(mOriginalSize - delta);
- break;
-
- case DRAG_RESIZE_TOP:
- setPosition(mOriginalPosition.mX, mOriginalPosition.mY + delta.mY);
- setSize(mOriginalSize.mX, mOriginalSize.mY - delta.mY);
- break;
-
- case DRAG_RESIZE_TOPRIGHT:
- setPosition(mOriginalPosition.mX, mOriginalPosition.mY + delta.mY);
- setSize(mOriginalSize.mX + delta.mX, mOriginalSize.mY - delta.mY);
- break;
-
- case DRAG_RESIZE_RIGHT:
- setSize(mOriginalSize.mX + delta.mX, mOriginalSize.mY);
- break;
-
- case DRAG_RESIZE_BOTTOMRIGHT:
- setSize(mOriginalSize + delta);
- break;
-
- case DRAG_RESIZE_BOTTOM:
- setSize(mOriginalSize.mX, mOriginalSize.mY + delta.mY);
- break;
-
- case DRAG_RESIZE_BOTTOMLEFT:
- setPosition(mOriginalPosition.mX + delta.mX, mOriginalPosition.mY);
- setSize(mOriginalSize.mX - delta.mX, mOriginalSize.mY + delta.mY);
- break;
-
- case DRAG_RESIZE_LEFT:
- setPosition(mOriginalPosition.mX + delta.mX, mOriginalPosition.mY);
- setSize(mOriginalSize.mX - delta.mX, mOriginalSize.mY);
- break;
- }
-
- validateSize();
- validatePosition();
- }
- void Window::onDragEnd(const IntVector2& position, const IntVector2& screenPosition)
- {
- mDragMode = DRAG_NONE;
- }
- void Window::setMovable(bool enable)
- {
- mMovable = enable;
- }
- void Window::setResizable(bool enable)
- {
- mResizable = enable;
- }
- void Window::setMinSize(const IntVector2& minSize)
- {
- mMinSize = minSize;
- validateSize();
- }
- void Window::setMinSize(int width, int height)
- {
- setMinSize(IntVector2(width, height));
- }
- void Window::setMaxSize(const IntVector2& maxSize)
- {
- mMaxSize = maxSize;
- validateSize();
- }
- void Window::setMaxSize(int width, int height)
- {
- setMaxSize(IntVector2(width, height));
- }
- void Window::setResizeBorder(const IntRect& rect)
- {
- mResizeBorder.mLeft = max(rect.mLeft, 0);
- mResizeBorder.mTop = max(rect.mTop, 0);
- mResizeBorder.mRight = max(rect.mRight, 0);
- mResizeBorder.mBottom = max(rect.mBottom, 0);
- }
- void Window::setResizeBorder(int left, int top, int right, int bottom)
- {
- setResizeBorder(IntRect(left, top, right, bottom));
- }
- void Window::validateSize()
- {
- mMinSize.mX = max(mMinSize.mX, 0);
- mMinSize.mY = max(mMinSize.mY, 0);
- mMaxSize.mX = max(mMaxSize.mX, mMinSize.mX);
- mMaxSize.mY = max(mMaxSize.mY, mMinSize.mX);
-
- IntVector2 size = getSize();
- size.mX = clamp(size.mX, mMinSize.mX, mMaxSize.mX);
- size.mY = clamp(size.mY, mMinSize.mY, mMaxSize.mY);
- setSize(size);
- }
- void Window::validatePosition()
- {
- // Check that window does not go more than halfway outside its parent in either dimension
- if (!mParent)
- return;
-
- const IntVector2& parentSize = mParent->getSize();
- IntVector2 position = getPosition();
- IntVector2 halfSize = getSize() / 2;
-
- position.mX = clamp(position.mX, -halfSize.mX, parentSize.mX - halfSize.mX);
- position.mY = clamp(position.mY, -halfSize.mY, parentSize.mY - halfSize.mY);
-
- setPosition(position);
- }
- bool Window::checkAlignment() const
- {
- // Only top left-alignment is supported for move and resize
- if ((getHorizontalAlignment() == HA_LEFT) && (getVerticalAlignment() == VA_TOP))
- return true;
- else
- return false;
- }
|