diff options
Diffstat (limited to 'src/gui/widgets/window.cpp')
-rw-r--r-- | src/gui/widgets/window.cpp | 1499 |
1 files changed, 0 insertions, 1499 deletions
diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp deleted file mode 100644 index b192bad35..000000000 --- a/src/gui/widgets/window.cpp +++ /dev/null @@ -1,1499 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * 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" -#include "configuration.h" -#ifndef DYECMD -#include "dragdrop.h" -#else // DYECMD -#include "resources/image/image.h" -#endif // DYECMD -#include "soundmanager.h" - -#include "const/sound.h" - -#include "gui/focushandler.h" -#include "gui/gui.h" -#include "gui/popupmanager.h" -#include "gui/skin.h" -#include "gui/viewport.h" - -#include "gui/fonts/font.h" - -#include "gui/popups/popupmenu.h" - -#include "gui/windows/setupwindow.h" - -#include "gui/widgets/containerplacer.h" -#include "gui/widgets/layout.h" - -#include "render/renderers.h" - -#include "render/vertexes/imagecollection.h" - -#include "utils/checkutils.h" -#include "utils/delete2.h" - -#include "debug.h" - -const int resizeMask = 8 + 4 + 2 + 1; - -int Window::windowInstances = 0; -int Window::mouseResize = 0; - -Window::Window(const std::string &caption, - const Modal modal, - Window *const parent, - std::string skin) : - BasicContainer2(nullptr), - MouseListener(), - WidgetListener(), - mCaption(caption), - mAlignment(Graphics::CENTER), - mPadding(2), - mTitleBarHeight(16), - mMovable(Move_true), - mDragOffsetX(0), - mDragOffsetY(0), - mMoved(false), - mSkin(nullptr), - mDefaultX(0), - mDefaultY(0), - mDefaultWidth(0), - mDefaultHeight(0), - mCaptionOffsetX(7), - mCaptionOffsetY(5), - mShowTitle(true), - mLastRedraw(true), - mGrip(nullptr), - mParentWindow(parent), - mLayout(nullptr), - mCloseRect(), - mStickyRect(), - mGripRect(), - mTextChunk(), - mWindowName("window"), - mMinWinWidth(100), - mMinWinHeight(40), - mMaxWinWidth(mainGraphics->mWidth), - mMaxWinHeight(mainGraphics->mHeight), - mVertexes(new ImageCollection), - mCaptionAlign(Graphics::LEFT), - mTitlePadding(4), - mGripPadding(2), - mResizeHandles(-1), - mOldResizeHandles(-1), - mClosePadding(0), - mStickySpacing(0), - mStickyPadding(0), - mCaptionFont(getFont()), - mModal(modal), - mCloseWindowButton(false), - mDefaultVisible(false), - mSaveVisible(false), - mStickyButton(false), - mSticky(false), - mStickyButtonLock(false), - mPlayVisibleSound(false), - mInit(false), - mTextChanged(true), - mAllowClose(false) -{ - logger->log("Window::Window(\"%s\")", caption.c_str()); - - mWindow = this; - - windowInstances++; - -// mFrameSize = 1; - addMouseListener(this); - - setFrameSize(0); - setPadding(3); - setTitleBarHeight(20); - - if (skin.empty()) - skin = "window.xml"; - - int childPalette = 1; - // Loads the skin - if (theme != nullptr) - { - mSkin = theme->load(skin, "window.xml"); - if (mSkin != nullptr) - { - setPadding(mSkin->getPadding()); - if (getOptionBool("titlebarBold")) - mCaptionFont = boldFont; - mTitlePadding = mSkin->getTitlePadding(); - mGripPadding = getOption("resizePadding"); - mCaptionOffsetX = getOption("captionoffsetx"); - if (mCaptionOffsetX == 0) - mCaptionOffsetX = 7; - mCaptionOffsetY = getOption("captionoffsety"); - if (mCaptionOffsetY == 0) - mCaptionOffsetY = 5; - mCaptionAlign = static_cast<Graphics::Alignment>( - getOption("captionalign")); - if (mCaptionAlign < Graphics::LEFT - || mCaptionAlign > Graphics::RIGHT) - { - mCaptionAlign = Graphics::LEFT; - } - setTitleBarHeight(CAST_U32( - getOption("titlebarHeight"))); - if (mTitleBarHeight == 0u) - mTitleBarHeight = mCaptionFont->getHeight() + mPadding; - - mTitleBarHeight += getOption("titlebarHeightRelative"); - setPalette(getOption("palette")); - childPalette = getOption("childPalette"); - mShowTitle = getOptionBool("showTitle", true); - mClosePadding = getOption("closePadding"); - mStickySpacing = getOption("stickySpacing"); - mStickyPadding = getOption("stickyPadding"); - } - } - - // Add this window to the window container - if (windowContainer != nullptr) - windowContainer->add(this); - - if (mModal == Modal_true) - { - gui->setCursorType(Cursor::CURSOR_POINTER); - requestModalFocus(); - } - - // Windows are invisible by default - setVisible(Visible_false, false); - - addWidgetListener(this); - mForegroundColor = getThemeColor(ThemeColorId::WINDOW); - mForegroundColor2 = getThemeColor(ThemeColorId::WINDOW_OUTLINE); - setPalette(childPalette); -} - -void Window::postInit() -{ - if (mInit) - { - reportAlways("error: Window created with calling postInit() " - "more than once: %s", - mWindowName.c_str()); - } - mInit = true; -} - -Window::~Window() -{ - logger->log("Window::~Window(\"%s\")", getCaption().c_str()); - - if (gui != nullptr) - gui->removeDragged(this); - -#ifndef DYECMD - if (setupWindow != nullptr) - setupWindow->unregisterWindowForReset(this); -#endif // DYECMD - - client->windowRemoved(this); - - saveWindowState(); - - delete2(mLayout); - - while (!mWidgets.empty()) - delete mWidgets.front(); - - mWidgets.clear(); - - removeWidgetListener(this); - delete2(mVertexes); - - windowInstances--; - - if (mSkin != nullptr) - { - if (theme != nullptr) - theme->unload(mSkin); - mSkin = nullptr; - } - if (mGrip != nullptr) - { - mGrip->decRef(); - mGrip = nullptr; - } - if (!mInit) - { - reportAlways("error: Window created without calling postInit(): %s", - mWindowName.c_str()); - } -} - -void Window::setWindowContainer(WindowContainer *const wc) -{ - windowContainer = wc; -} - -void Window::draw(Graphics *const graphics) -{ - if (mSkin == nullptr) - return; - - BLOCK_START("Window::draw") - bool update = false; - - if (mResizeHandles != mOldResizeHandles) - { - mRedraw = true; - mOldResizeHandles = mResizeHandles; - } - if (mRedraw) - { - mLastRedraw = true; - mRedraw = false; - update = true; - mVertexes->clear(); - graphics->calcWindow(mVertexes, - 0, 0, - mDimension.width, - mDimension.height, - mSkin->getBorder()); - - // Draw Close Button - if (mCloseWindowButton) - { - const Image *const button = mSkin->getCloseImage( - mResizeHandles == CLOSE); - if (button != nullptr) - { - graphics->calcTileCollection(mVertexes, - button, - mCloseRect.x, - mCloseRect.y); - } - } - // Draw Sticky Button - if (mStickyButton) - { - const Image *const button = mSkin->getStickyImage(mSticky); - if (button != nullptr) - { - graphics->calcTileCollection(mVertexes, - button, - mStickyRect.x, - mStickyRect.y); - } - } - - if (mGrip != nullptr) - { - graphics->calcTileCollection(mVertexes, - mGrip, - mGripRect.x, - mGripRect.y); - } - graphics->finalize(mVertexes); - } - else - { - mLastRedraw = false; - } - graphics->drawTileCollection(mVertexes); - - // Draw title - if (mShowTitle) - { - int x; - switch (mCaptionAlign) - { - case Graphics::LEFT: - default: - x = mCaptionOffsetX; - break; - case Graphics::CENTER: - x = mCaptionOffsetX - mCaptionFont->getWidth(mCaption) / 2; - break; - case Graphics::RIGHT: - x = mCaptionOffsetX - mCaptionFont->getWidth(mCaption); - break; - } - if (mTextChanged) - { - mTextChunk.textFont = mCaptionFont; - mTextChunk.deleteImage(); - mTextChunk.text = mCaption; - mTextChunk.color = mForegroundColor; - mTextChunk.color2 = mForegroundColor2; - mCaptionFont->generate(mTextChunk); - mTextChanged = false; - } - - const Image *const image = mTextChunk.img; - if (image != nullptr) - graphics->drawImage(image, x, mCaptionOffsetY); - } - - if (update) - { - graphics->setRedraw(update); - drawChildren(graphics); - graphics->setRedraw(false); - } - else - { - drawChildren(graphics); - } - BLOCK_END("Window::draw") -} - -void Window::safeDraw(Graphics *const graphics) -{ - if (mSkin == nullptr) - return; - - BLOCK_START("Window::safeDraw") - - graphics->drawImageRect(0, 0, - mDimension.width, - mDimension.height, - mSkin->getBorder()); - - // Draw Close Button - if (mCloseWindowButton) - { - const Image *const button = mSkin->getCloseImage( - mResizeHandles == CLOSE); - if (button != nullptr) - graphics->drawImage(button, mCloseRect.x, mCloseRect.y); - } - // Draw Sticky Button - if (mStickyButton) - { - const Image *const button = mSkin->getStickyImage(mSticky); - if (button != nullptr) - graphics->drawImage(button, mStickyRect.x, mStickyRect.y); - } - - if (mGrip != nullptr) - graphics->drawImage(mGrip, mGripRect.x, mGripRect.y); - - // Draw title - if (mShowTitle) - { - int x; - switch (mCaptionAlign) - { - case Graphics::LEFT: - default: - x = mCaptionOffsetX; - break; - case Graphics::CENTER: - x = mCaptionOffsetX - mCaptionFont->getWidth(mCaption) / 2; - break; - case Graphics::RIGHT: - x = mCaptionOffsetX - mCaptionFont->getWidth(mCaption); - break; - } - if (mTextChanged) - { - mTextChunk.textFont = mCaptionFont; - mTextChunk.deleteImage(); - mTextChunk.text = mCaption; - mTextChunk.color = mForegroundColor; - mTextChunk.color2 = mForegroundColor2; - mCaptionFont->generate(mTextChunk); - mTextChanged = false; - } - - const Image *const image = mTextChunk.img; - if (image != nullptr) - graphics->drawImage(image, x, mCaptionOffsetY); - } - - safeDrawChildren(graphics); - - BLOCK_END("Window::safeDraw") -} - -void Window::setContentSize(int width, int height) -{ - width = width + 2 * mPadding; - height = height + mPadding + mTitleBarHeight; - - if (mMinWinWidth > width) - width = mMinWinWidth; - else if (mMaxWinWidth < width) - width = mMaxWinWidth; - if (mMinWinHeight > height) - height = mMinWinHeight; - else if (mMaxWinHeight < height) - height = mMaxWinHeight; - - setSize(width, height); -} - -void Window::setLocationRelativeTo(const Widget *const widget) -{ - if (widget == nullptr) - return; - - int wx, wy; - int x, y; - - widget->getAbsolutePosition(wx, wy); - getAbsolutePosition(x, y); - - setPosition(mDimension.x + (wx + (widget->getWidth() - - mDimension.width) / 2 - x), - mDimension.y + (wy + (widget->getHeight() - - mDimension.height) / 2 - y)); -} - -void Window::setLocationHorisontallyRelativeTo(const Widget *const widget) -{ - if (widget == nullptr) - return; - - int wx, wy; - int x, y; - - widget->getAbsolutePosition(wx, wy); - getAbsolutePosition(x, y); - - setPosition(mDimension.x + (wx + (widget->getWidth() - - mDimension.width) / 2 - x), 0); -} - -void Window::setLocationRelativeTo(const ImagePosition::Type &position, - int offsetX, int offsetY) -{ - if (position == ImagePosition::UPPER_LEFT) - { - } - else if (position == ImagePosition::UPPER_CENTER) - { - offsetX += (mainGraphics->mWidth - mDimension.width) / 2; - } - else if (position == ImagePosition::UPPER_RIGHT) - { - offsetX += mainGraphics->mWidth - mDimension.width; - } - else if (position == ImagePosition::LEFT) - { - offsetY += (mainGraphics->mHeight - mDimension.height) / 2; - } - else if (position == ImagePosition::CENTER) - { - offsetX += (mainGraphics->mWidth - mDimension.width) / 2; - offsetY += (mainGraphics->mHeight - mDimension.height) / 2; - } - else if (position == ImagePosition::RIGHT) - { - offsetX += mainGraphics->mWidth - mDimension.width; - offsetY += (mainGraphics->mHeight - mDimension.height) / 2; - } - else if (position == ImagePosition::LOWER_LEFT) - { - offsetY += mainGraphics->mHeight - mDimension.height; - } - else if (position == ImagePosition::LOWER_CENTER) - { - offsetX += (mainGraphics->mWidth - mDimension.width) / 2; - offsetY += mainGraphics->mHeight - mDimension.height; - } - else if (position == ImagePosition::LOWER_RIGHT) - { - offsetX += mainGraphics->mWidth - mDimension.width; - offsetY += mainGraphics->mHeight - mDimension.height; - } - - setPosition(offsetX, offsetY); -} - -void Window::setMinWidth(const int width) -{ - if (mSkin != nullptr) - { - mMinWinWidth = width > mSkin->getMinWidth() - ? width : mSkin->getMinWidth(); - } - else - { - mMinWinWidth = width; - } -} - -void Window::setMinHeight(const int height) -{ - if (mSkin != nullptr) - { - mMinWinHeight = height > mSkin->getMinHeight() - ? height : mSkin->getMinHeight(); - } - else - { - mMinWinHeight = height; - } -} - -void Window::setMaxWidth(const int width) -{ - mMaxWinWidth = width; -} - -void Window::setMaxHeight(const int height) -{ - mMaxWinHeight = height; -} - -void Window::setResizable(const bool r) -{ - if ((mGrip != nullptr) == r) - return; - - if (mGrip != nullptr) - mGrip->decRef(); - if (r) - { - mGrip = Theme::getImageFromThemeXml("resize.xml", ""); - if (mGrip != nullptr) - { - mGripRect.x = mDimension.width - mGrip->getWidth() - mGripPadding; - mGripRect.y = mDimension.height - mGrip->getHeight() - - mGripPadding; - } - else - { - mGripRect.x = 0; - mGripRect.y = 0; - } - } - else - { - mGrip = nullptr; - } -} - -void Window::widgetResized(const Event &event A_UNUSED) -{ - if (mGrip != nullptr) - { - mGripRect.x = mDimension.width - mGrip->getWidth() - mGripPadding; - mGripRect.y = mDimension.height - mGrip->getHeight() - mGripPadding; - } - - if (mLayout != nullptr) - { - const Rect area = getChildrenArea(); - int w = area.width; - int h = area.height; - mLayout->reflow(w, h); - } - if (mSkin != nullptr) - { - const bool showClose = mCloseWindowButton - && (mSkin->getCloseImage(false) != nullptr); - if (showClose) - { - const Image *const button = mSkin->getCloseImage(false); - if (button != nullptr) - { - const int buttonWidth = button->getWidth(); - mCloseRect.x = mDimension.width - buttonWidth - mClosePadding; - mCloseRect.y = mClosePadding; - mCloseRect.width = buttonWidth; - mCloseRect.height = button->getHeight(); - } - } - if (mStickyButton) - { - const Image *const button = mSkin->getStickyImage(mSticky); - if (button != nullptr) - { - const int buttonWidth = button->getWidth(); - int x = mDimension.width - buttonWidth - - mStickySpacing - mClosePadding; - - if (showClose) - x -= mSkin->getCloseImage(false)->getWidth(); - - mStickyRect.x = x; - mStickyRect.y = mStickyPadding; - mStickyRect.width = buttonWidth; - mStickyRect.height = button->getHeight(); - } - } - } - else - { - mCloseRect.x = 0; - mCloseRect.y = 0; - mCloseRect.width = 0; - mCloseRect.height = 0; - mStickyRect.x = 0; - mStickyRect.y = 0; - mStickyRect.width = 0; - mStickyRect.height = 0; - } - - mRedraw = true; -} - -void Window::widgetMoved(const Event& event A_UNUSED) -{ - mRedraw = true; -} - -void Window::widgetHidden(const Event &event A_UNUSED) -{ - if (isBatchDrawRenders(openGLMode)) - mVertexes->clear(); - - mTextChunk.deleteImage(); - - mTextChanged = true; - mRedraw = true; - - if (gui != nullptr) - gui->setCursorType(Cursor::CURSOR_POINTER); - - if (mFocusHandler == nullptr) - return; - - for (WidgetListConstIterator it = mWidgets.begin(); - it != mWidgets.end(); ++ it) - { - if (mFocusHandler->isFocused(*it)) - mFocusHandler->focusNone(); - } -} - -void Window::setCloseButton(const bool flag) -{ - mCloseWindowButton = flag; - if (flag) - mAllowClose = true; -} - -bool Window::isResizable() const -{ - return mGrip != nullptr; -} - -void Window::setStickyButton(const bool flag) -{ - mStickyButton = flag; -} - -void Window::setSticky(const bool sticky) -{ - mSticky = sticky; - mRedraw = true; -} - -void Window::setStickyButtonLock(const bool lock) -{ - mStickyButtonLock = lock; - mStickyButton = lock; -} - -void Window::setVisible(Visible visible) -{ - setVisible(visible, false); -} - -void Window::setVisible(const Visible visible, const bool forceSticky) -{ - if (visible == mVisible) - return; - - // Check if the window is off screen... - if (visible == Visible_true) - ensureOnScreen(); - else - mResizeHandles = 0; - - if (mStickyButtonLock) - { - BasicContainer2::setVisible(visible); - } - else - { - BasicContainer2::setVisible(fromBool((!forceSticky && mSticky) || - visible == Visible_true, Visible)); - } - if (visible == Visible_true) - { - if (mPlayVisibleSound) - soundManager.playGuiSound(SOUND_SHOW_WINDOW); - if (gui != nullptr) - { - MouseEvent *const event = reinterpret_cast<MouseEvent*>( - gui->createMouseEvent(this)); - if (event != nullptr) - { - const int x = event->getX(); - const int y = event->getY(); - if (x >= 0 && x <= mDimension.width - && y >= 0 && y <= mDimension.height) - { - mouseMoved(*event); - } - delete event; - } - } - } - else - { - if (mPlayVisibleSound) - soundManager.playGuiSound(SOUND_HIDE_WINDOW); - } -} - -void Window::scheduleDelete() -{ - windowContainer->scheduleDelete(this); -} - -void Window::mousePressed(MouseEvent &event) -{ - if (event.isConsumed()) - return; - - if (event.getSource() == this) - { - if (getParent() != nullptr) - getParent()->moveToTop(this); - - mDragOffsetX = event.getX(); - mDragOffsetY = event.getY(); - mMoved = event.getY() <= CAST_S32(mTitleBarHeight); - } - - const MouseButtonT button = event.getButton(); - if (button == MouseButton::LEFT) - { - const int x = event.getX(); - const int y = event.getY(); - - // Handle close button - if (mCloseWindowButton && - mSkin != nullptr && - mCloseRect.isPointInRect(x, y)) - { - mouseResize = 0; - mMoved = false; - event.consume(); - close(); - return; - } - - // Handle sticky button - if (mStickyButton && - mSkin != nullptr && - mStickyRect.isPointInRect(x, y)) - { - setSticky(!isSticky()); - mouseResize = 0; - mMoved = false; - event.consume(); - return; - } - - // Handle window resizing - mouseResize = getResizeHandles(event) & resizeMask; - if (mouseResize != 0) - event.consume(); - if (canMove()) - mMoved = (mouseResize == 0); - else - mMoved = false; - } -#ifndef DYECMD - else if (button == MouseButton::RIGHT) - { - if (popupMenu != nullptr) - { - event.consume(); - popupMenu->showWindowPopup(this); - } - } -#endif // DYECMD -} - -void Window::close() -{ - setVisible(Visible_false); -} - -void Window::mouseReleased(MouseEvent &event A_UNUSED) -{ - if ((mGrip != nullptr) && (mouseResize != 0)) - { - mouseResize = 0; - if (gui != nullptr) - gui->setCursorType(Cursor::CURSOR_POINTER); - } - - mMoved = false; -} - -void Window::mouseEntered(MouseEvent &event) -{ - updateResizeHandler(event); -} - -void Window::mouseExited(MouseEvent &event A_UNUSED) -{ - if ((mGrip != nullptr) && (mouseResize == 0) && (gui != nullptr)) - gui->setCursorType(Cursor::CURSOR_POINTER); -} - -void Window::updateResizeHandler(MouseEvent &event) -{ - if (gui == nullptr) - return; - -#ifndef DYECMD - if (!dragDrop.isEmpty()) - return; -#endif // DYECMD - - mResizeHandles = getResizeHandles(event); - - // Changes the custom mouse cursor based on it's current position. - switch (mResizeHandles & resizeMask) - { - case BOTTOM | RIGHT: - case TOP | LEFT: - gui->setCursorType(Cursor::CURSOR_RESIZE_DOWN_RIGHT); - break; - case TOP | RIGHT: - case BOTTOM | LEFT: - gui->setCursorType(Cursor::CURSOR_RESIZE_DOWN_LEFT); - break; - case BOTTOM: - case TOP: - gui->setCursorType(Cursor::CURSOR_RESIZE_DOWN); - break; - case RIGHT: - case LEFT: - gui->setCursorType(Cursor::CURSOR_RESIZE_ACROSS); - break; - default: - gui->setCursorType(Cursor::CURSOR_POINTER); - break; - } -} - -void Window::mouseMoved(MouseEvent &event) -{ - updateResizeHandler(event); - if ((popupManager != nullptr) && !event.isConsumed()) - { - PopupManager::hideBeingPopup(); - PopupManager::hideTextPopup(); - } -} - -bool Window::canMove() const -{ - return !mStickyButtonLock || !mSticky; -} - -void Window::mouseDragged(MouseEvent &event) -{ - if (canMove()) - { - if (!event.isConsumed() && event.getSource() == this) - { - if (isMovable() && mMoved) - { - setPosition(event.getX() - mDragOffsetX + getX(), - event.getY() - mDragOffsetY + getY()); - } - - event.consume(); - } - } - else - { - if (!event.isConsumed() && event.getSource() == this) - event.consume(); - return; - } - - // Keep guichan window inside screen when it may be moved - if (isMovable() && mMoved) - { - setPosition(std::min(mainGraphics->mWidth - mDimension.width, - std::max(0, mDimension.x)), - std::min(mainGraphics->mHeight - mDimension.height, - std::max(0, mDimension.y))); - } - - if ((mouseResize != 0) && !mMoved) - { - const int dx = event.getX() - mDragOffsetX; - const int dy = event.getY() - mDragOffsetY; - Rect newDim = getDimension(); - - if ((mouseResize & (TOP | BOTTOM)) != 0) - { - const int newHeight = newDim.height - + ((mouseResize & TOP) != 0 ? -dy : dy); - newDim.height = std::min(mMaxWinHeight, - std::max(mMinWinHeight, newHeight)); - - if ((mouseResize & TOP) != 0) - newDim.y -= newDim.height - getHeight(); - } - - if ((mouseResize & (LEFT | RIGHT)) != 0) - { - const int newWidth = newDim.width - + ((mouseResize & LEFT) != 0 ? -dx : dx); - newDim.width = std::min(mMaxWinWidth, - std::max(mMinWinWidth, newWidth)); - - if ((mouseResize & LEFT) != 0) - newDim.x -= newDim.width - mDimension.width; - } - - // Keep guichan window inside screen (supports resizing any side) - if (newDim.x < 0) - { - newDim.width += newDim.x; - newDim.x = 0; - } - if (newDim.y < 0) - { - newDim.height += newDim.y; - newDim.y = 0; - } - if (newDim.x + newDim.width > mainGraphics->mWidth) - newDim.width = mainGraphics->mWidth - newDim.x; - if (newDim.y + newDim.height > mainGraphics->mHeight) - newDim.height = mainGraphics->mHeight - newDim.y; - - // Update mouse offset when dragging bottom or right border - if ((mouseResize & BOTTOM) != 0) - mDragOffsetY += newDim.height - mDimension.height; - - if ((mouseResize & RIGHT) != 0) - mDragOffsetX += newDim.width - mDimension.width; - - // Set the new window and content dimensions - setDimension(newDim); - } -} - -void Window::setModal(const Modal modal) -{ - if (mModal != modal) - { - mModal = modal; - if (mModal == Modal_true) - { - if (gui != nullptr) - gui->setCursorType(Cursor::CURSOR_POINTER); - requestModalFocus(); - } - else - { - releaseModalFocus(); - } - } -} - -void Window::loadWindowState() -{ - const std::string &name = mWindowName; - if (name.empty()) - return; - - setPosition(config.getValueInt(name + "WinX", mDefaultX), - config.getValueInt(name + "WinY", mDefaultY)); - - if (mSaveVisible) - { - setVisible(fromBool(config.getValueBool(name - + "Visible", mDefaultVisible), Visible)); - } - - if (mStickyButton) - { - setSticky(config.getValueBool(name - + "Sticky", isSticky())); - } - - if (mGrip != nullptr) - { - int width = config.getValueInt(name + "WinWidth", mDefaultWidth); - int height = config.getValueInt(name + "WinHeight", mDefaultHeight); - - if (getMinWidth() > width) - width = getMinWidth(); - else if (getMaxWidth() < width) - width = getMaxWidth(); - if (getMinHeight() > height) - height = getMinHeight(); - else if (getMaxHeight() < height) - height = getMaxHeight(); - - setSize(width, height); - } - else - { - setSize(mDefaultWidth, mDefaultHeight); - } - - // Check if the window is off screen... - ensureOnScreen(); - - if (viewport != nullptr) - { - int width = mDimension.width; - int height = mDimension.height; - - if (mDimension.x + width > viewport->getWidth()) - width = viewport->getWidth() - mDimension.x; - if (mDimension.y + height > viewport->getHeight()) - height = viewport->getHeight() - mDimension.y; - if (width < 0) - width = 0; - if (height < 0) - height = 0; - setSize(width, height); - } -} - -void Window::saveWindowState() -{ - // Saving X, Y and Width and Height for resizables in the config - if (!mWindowName.empty() && mWindowName != "window") - { - config.setValue(mWindowName + "WinX", mDimension.x); - config.setValue(mWindowName + "WinY", mDimension.y); - - if (mSaveVisible) - config.setValue(mWindowName + "Visible", isWindowVisible()); - - if (mStickyButton) - config.setValue(mWindowName + "Sticky", isSticky()); - - if (mGrip != nullptr) - { - if (getMinWidth() > mDimension.width) - setWidth(getMinWidth()); - else if (getMaxWidth() < mDimension.width) - setWidth(getMaxWidth()); - if (getMinHeight() > mDimension.height) - setHeight(getMinHeight()); - else if (getMaxHeight() < mDimension.height) - setHeight(getMaxHeight()); - - config.setValue(mWindowName + "WinWidth", mDimension.width); - config.setValue(mWindowName + "WinHeight", mDimension.height); - } - } -} - -void Window::setDefaultSize(const int defaultX, const int defaultY, - int defaultWidth, int defaultHeight) -{ - if (mMinWinWidth > defaultWidth) - defaultWidth = mMinWinWidth; - else if (mMaxWinWidth < defaultWidth) - defaultWidth = mMaxWinWidth; - if (mMinWinHeight > defaultHeight) - defaultHeight = mMinWinHeight; - else if (mMaxWinHeight < defaultHeight) - defaultHeight = mMaxWinHeight; - - mDefaultX = defaultX; - mDefaultY = defaultY; - mDefaultWidth = defaultWidth; - mDefaultHeight = defaultHeight; -} - -void Window::setDefaultSize() -{ - mDefaultX = mDimension.x; - mDefaultY = mDimension.y; - mDefaultWidth = mDimension.width; - mDefaultHeight = mDimension.height; -} - -void Window::setDefaultSize(const int defaultWidth, const int defaultHeight, - const ImagePosition::Type &position, - const int offsetX, const int offsetY) -{ - int x = 0; - int y = 0; - - if (position == ImagePosition::UPPER_LEFT) - { - } - else if (position == ImagePosition::UPPER_CENTER) - { - x = (mainGraphics->mWidth - defaultWidth) / 2; - } - else if (position == ImagePosition::UPPER_RIGHT) - { - x = mainGraphics->mWidth - defaultWidth; - } - else if (position == ImagePosition::LEFT) - { - y = (mainGraphics->mHeight - defaultHeight) / 2; - } - else if (position == ImagePosition::CENTER) - { - x = (mainGraphics->mWidth - defaultWidth) / 2; - y = (mainGraphics->mHeight - defaultHeight) / 2; - } - else if (position == ImagePosition::RIGHT) - { - x = mainGraphics->mWidth - defaultWidth; - y = (mainGraphics->mHeight - defaultHeight) / 2; - } - else if (position == ImagePosition::LOWER_LEFT) - { - y = mainGraphics->mHeight - defaultHeight; - } - else if (position == ImagePosition::LOWER_CENTER) - { - x = (mainGraphics->mWidth - defaultWidth) / 2; - y = mainGraphics->mHeight - defaultHeight; - } - else if (position == ImagePosition::LOWER_RIGHT) - { - x = mainGraphics->mWidth - defaultWidth; - y = mainGraphics->mHeight - defaultHeight; - } - - mDefaultX = x - offsetX; - mDefaultY = y - offsetY; - mDefaultWidth = defaultWidth; - mDefaultHeight = defaultHeight; -} - -void Window::resetToDefaultSize() -{ - setPosition(mDefaultX, mDefaultY); - setSize(mDefaultWidth, mDefaultHeight); - saveWindowState(); -} - -void Window::adjustPositionAfterResize(const int oldScreenWidth, - const int oldScreenHeight) -{ - // If window was aligned to the right or bottom, keep it there - const int rightMargin = oldScreenWidth - (mDimension.x + mDimension.width); - const int bottomMargin = oldScreenHeight - - (mDimension.y + mDimension.height); - if (mDimension.x > 0 && mDimension.x > rightMargin) - mDimension.x = mainGraphics->mWidth - rightMargin - mDimension.width; - if (mDimension.y > 0 && mDimension.y > bottomMargin) - { - mDimension.y = mainGraphics->mHeight - - bottomMargin - mDimension.height; - } - - ensureOnScreen(); - adjustSizeToScreen(); -} - -void Window::adjustSizeToScreen() -{ - if (mGrip == nullptr) - return; - - const int screenWidth = mainGraphics->mWidth; - const int screenHeight = mainGraphics->mHeight; - const int oldWidth = mDimension.width; - const int oldHeight = mDimension.height; - if (oldWidth + mDimension.x > screenWidth) - mDimension.x = 0; - if (oldHeight + mDimension.y > screenHeight) - mDimension.x = 0; - if (mDimension.width > screenWidth) - mDimension.width = screenWidth; - if (mDimension.height > screenHeight) - mDimension.height = screenHeight; - if (oldWidth != mDimension.width || oldHeight != mDimension.height) - widgetResized(Event(this)); -} - -int Window::getResizeHandles(const MouseEvent &event) -{ - if (event.getX() < 0 || event.getY() < 0) - return 0; - - int resizeHandles = 0; - const unsigned y = event.getY(); - const unsigned x = event.getX(); - if (mCloseRect.isPointInRect(x, y)) - return CLOSE; - - if (!mStickyButtonLock || !mSticky) - { - if ((mGrip != nullptr) && - (y > mTitleBarHeight || - (CAST_S32(y) < mPadding && - CAST_S32(mTitleBarHeight) > mPadding))) - { - if (!getWindowArea().isPointInRect(x, y) - && event.getSource() == this) - { - resizeHandles |= (x > mDimension.width - resizeBorderWidth) - ? RIGHT : (x < resizeBorderWidth) ? LEFT : 0; - resizeHandles |= (y > mDimension.height - resizeBorderWidth) - ? BOTTOM : (y < resizeBorderWidth) ? TOP : 0; - } - if (x >= CAST_U32(mGripRect.x) - && y >= CAST_U32(mGripRect.y)) - { - mDragOffsetX = x; - mDragOffsetY = y; - resizeHandles |= BOTTOM | RIGHT; - } - } - } - - return resizeHandles; -} - -bool Window::isResizeAllowed(const MouseEvent &event) const -{ - const int y = event.getY(); - - if ((mGrip != nullptr) && - (y > CAST_S32(mTitleBarHeight) || - y < mPadding)) - { - const int x = event.getX(); - - if (!getWindowArea().isPointInRect(x, y) && event.getSource() == this) - return true; - - if (x >= mGripRect.x && y >= mGripRect.y) - return true; - } - - return false; -} - -Layout &Window::getLayout() -{ - if (mLayout == nullptr) - mLayout = new Layout; - return *mLayout; -} - -void Window::clearLayout() -{ - clear(); - - // Recreate layout instance when one is present - if (mLayout != nullptr) - { - delete mLayout; - mLayout = new Layout; - } -} - -LayoutCell &Window::place(const int x, const int y, Widget *const wg, - const int w, const int h) -{ - add(wg); - return getLayout().place(wg, x, y, w, h); -} - -ContainerPlacer Window::getPlacer(const int x, const int y) -{ - return ContainerPlacer(this, &getLayout().at(x, y)); -} - -void Window::reflowLayout(int w, int h) -{ - if (mLayout == nullptr) - return; - - mLayout->reflow(w, h); - delete2(mLayout); - setContentSize(w, h); -} - -void Window::redraw() -{ - if (mLayout != nullptr) - { - const Rect area = getChildrenArea(); - int w = area.width; - int h = area.height; - mLayout->reflow(w, h); - } -} - -void Window::center() -{ - setLocationRelativeTo(getParent()); -} - -void Window::centerHorisontally() -{ - setLocationHorisontallyRelativeTo(getParent()); -} - -void Window::ensureOnScreen() -{ - // Skip when a window hasn't got any size initialized yet - if (mDimension.width == 0 && mDimension.height == 0) - return; - - // Check the left and bottom screen boundaries - if (mDimension.x + mDimension.width > mainGraphics->mWidth) - mDimension.x = mainGraphics->mWidth - mDimension.width; - if (mDimension.y + mDimension.height > mainGraphics->mHeight) - mDimension.y = mainGraphics->mHeight - mDimension.height; - - // But never allow the windows to disappear in to the right and top - if (mDimension.x < 0) - mDimension.x = 0; - if (mDimension.y < 0) - mDimension.y = 0; -} - -Rect Window::getWindowArea() const -{ - return Rect(mPadding, - mPadding, - mDimension.width - mPadding * 2, - mDimension.height - mPadding * 2); -} - -int Window::getOption(const std::string &name, const int def) const -{ - if (mSkin != nullptr) - { - const int val = mSkin->getOption(name); - if (val != 0) - return val; - return def; - } - return def; -} - -bool Window::getOptionBool(const std::string &name, const bool def) const -{ - if (mSkin != nullptr) - return mSkin->getOption(name, static_cast<int>(def)) != 0; - 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() -{ - BLOCK_START("Window::logic") - logicChildren(); - BLOCK_END("Window::logic") -} -#endif // USE_PROFILER |