diff options
author | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-03-17 10:39:38 +0100 |
---|---|---|
committer | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-03-24 13:47:11 +0100 |
commit | 5274cc92c1055a3209dfae7e5346bfe52c35e4a8 (patch) | |
tree | 8bb9ceab97fb752a07294a52dcf2d390e79616fe /src/gui | |
parent | d5f49e4bef99e2ae4b39bdf1b7c644c28a85c5a2 (diff) | |
download | mana-5274cc92c1055a3209dfae7e5346bfe52c35e4a8.tar.gz mana-5274cc92c1055a3209dfae7e5346bfe52c35e4a8.tar.bz2 mana-5274cc92c1055a3209dfae7e5346bfe52c35e4a8.tar.xz mana-5274cc92c1055a3209dfae7e5346bfe52c35e4a8.zip |
Define the GUI theme in XML
Now all images used by the various UI widgets are defined in a
`theme.xml`, removing hardcoded requirements on the size of images,
borders and sub-images and their locations. The `colors.xml` file was
merged into this new file as well.
The `<img>` element defines either a plain image, or a 9-scale that is
automatically rendered at the size of the widget when any of the `left`,
`right`, `top` or `bottom` attributes are given.
The `x`, `y`, `width` and `height` attributes determine the
sub-rectangle within the image referenced by `src`. `x` and `y` default
to 0 and `width` and `height` default to the imge size.
The `<state>` element defines in which state its images are used by
setting its `selected`, `disabled`, `hovered` or `focused` attributes to
either `true` or `false`. Only the first matching state is rendered.
The `Text` and `SpeechBubble` classes now use the same skin to draw the
bubble, as well as using a newly introduced `BUBBLE_TEXT` color from the
theme palette.
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/minimap.cpp | 3 | ||||
-rw-r--r-- | src/gui/speechbubble.cpp | 13 | ||||
-rw-r--r-- | src/gui/widgets/button.cpp | 20 | ||||
-rw-r--r-- | src/gui/widgets/checkbox.cpp | 11 | ||||
-rw-r--r-- | src/gui/widgets/dropdown.cpp | 32 | ||||
-rw-r--r-- | src/gui/widgets/popup.cpp | 25 | ||||
-rw-r--r-- | src/gui/widgets/popup.h | 23 | ||||
-rw-r--r-- | src/gui/widgets/radiobutton.cpp | 11 | ||||
-rw-r--r-- | src/gui/widgets/resizegrip.cpp | 13 | ||||
-rw-r--r-- | src/gui/widgets/scrollarea.cpp | 76 | ||||
-rw-r--r-- | src/gui/widgets/scrollarea.h | 8 | ||||
-rw-r--r-- | src/gui/widgets/slider.cpp | 16 | ||||
-rw-r--r-- | src/gui/widgets/tab.cpp | 16 | ||||
-rw-r--r-- | src/gui/widgets/textfield.cpp | 8 | ||||
-rw-r--r-- | src/gui/widgets/window.cpp | 81 | ||||
-rw-r--r-- | src/gui/widgets/window.h | 5 |
16 files changed, 186 insertions, 175 deletions
diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp index 14e2a257..fc7fddd0 100644 --- a/src/gui/minimap.cpp +++ b/src/gui/minimap.cpp @@ -59,8 +59,7 @@ Minimap::Minimap(): setVisible(config.showMinimap, isSticky()); } -Minimap::~Minimap() -{} +Minimap::~Minimap() = default; void Minimap::setMap(Map *map) { diff --git a/src/gui/speechbubble.cpp b/src/gui/speechbubble.cpp index 58747d57..72ec8bd2 100644 --- a/src/gui/speechbubble.cpp +++ b/src/gui/speechbubble.cpp @@ -27,14 +27,11 @@ #include "gui/widgets/label.h" #include "gui/widgets/textbox.h" -#include "resources/theme.h" - #include <guichan/font.hpp> - #include <guichan/widgets/label.hpp> -SpeechBubble::SpeechBubble(): - Popup("Speech", "speechbubble.xml") +SpeechBubble::SpeechBubble() + : Popup("Speech", SkinType::SpeechBubble) { setMinWidth(0); setMinHeight(0); @@ -45,7 +42,7 @@ SpeechBubble::SpeechBubble(): mSpeechBox = new TextBox; mSpeechBox->setEditable(false); mSpeechBox->setOpaque(false); - mSpeechBox->setTextColor(&Theme::getThemeColor(Theme::CHAT)); + mSpeechBox->setTextColor(&Theme::getThemeColor(Theme::BUBBLE_TEXT)); add(mCaption); add(mSpeechBox); @@ -60,11 +57,9 @@ void SpeechBubble::setCaption(const std::string &name, const gcn::Color *color) void SpeechBubble::setText(const std::string &text, bool showName) { - if (text == mText && (mCaption->getWidth() <= mSpeechBox->getMinWidth())) + if (text == mText && mCaption->getWidth() <= mSpeechBox->getMinWidth()) return; - mSpeechBox->setTextColor(&Theme::getThemeColor(Theme::TEXT)); - int width = mCaption->getWidth(); mSpeechBox->setTextWrapped(text, 130 > width ? 130 : width); const int speechWidth = mSpeechBox->getMinWidth(); diff --git a/src/gui/widgets/button.cpp b/src/gui/widgets/button.cpp index eb2722e5..215cb5a0 100644 --- a/src/gui/widgets/button.cpp +++ b/src/gui/widgets/button.cpp @@ -123,23 +123,21 @@ void Button::init() void Button::draw(gcn::Graphics *graphics) { - Theme::WidgetState state; - state.width = getWidth(); - state.height = getHeight(); - state.enabled = isEnabled(); - state.hovered = mHasMouse; - state.selected = isPressed(); - state.focused = isFocused(); + WidgetState state(this); + if (mHasMouse) + state.flags |= STATE_HOVERED; + if (isPressed()) + state.flags |= STATE_SELECTED; - gui->getTheme()->drawButton(static_cast<Graphics*>(graphics), state); + gui->getTheme()->drawSkin(static_cast<Graphics *>(graphics), SkinType::Button, state); int mode; - if (!state.enabled) + if (state.flags & STATE_DISABLED) mode = BUTTON_DISABLED; - else if (state.selected) + else if (state.flags & STATE_SELECTED) mode = BUTTON_PRESSED; - else if (state.hovered || state.focused) + else if (state.flags & (STATE_HOVERED | STATE_FOCUSED)) mode = BUTTON_HIGHLIGHTED; else mode = BUTTON_STANDARD; diff --git a/src/gui/widgets/checkbox.cpp b/src/gui/widgets/checkbox.cpp index e2d13ab2..bea5f1d9 100644 --- a/src/gui/widgets/checkbox.cpp +++ b/src/gui/widgets/checkbox.cpp @@ -43,12 +43,13 @@ void CheckBox::draw(gcn::Graphics* graphics) void CheckBox::drawBox(gcn::Graphics* graphics) { - Theme::WidgetState state; - state.enabled = isEnabled(); - state.hovered = mHasMouse; - state.selected = isSelected(); + WidgetState state(this); + if (mHasMouse) + state.flags |= STATE_HOVERED; + if (isSelected()) + state.flags |= STATE_SELECTED; - gui->getTheme()->drawCheckBox(graphics, state); + gui->getTheme()->drawSkin(static_cast<Graphics *>(graphics), SkinType::CheckBox, state); } void CheckBox::mouseEntered(gcn::MouseEvent& event) diff --git a/src/gui/widgets/dropdown.cpp b/src/gui/widgets/dropdown.cpp index 7202827b..1d54efd7 100644 --- a/src/gui/widgets/dropdown.cpp +++ b/src/gui/widgets/dropdown.cpp @@ -87,23 +87,31 @@ void DropDown::drawFrame(gcn::Graphics *graphics) { const int bs = getFrameSize(); - Theme::WidgetState state; - state.width = getWidth() + bs * 2; - state.height = getHeight() + bs * 2; + WidgetState state(this); + state.width += bs * 2; + state.height += bs * 2; - gui->getTheme()->drawDropDownFrame(static_cast<Graphics*>(graphics), state); + gui->getTheme()->drawSkin(static_cast<Graphics *>(graphics), SkinType::DropDownFrame, state); } void DropDown::drawButton(gcn::Graphics *graphics) { - Theme::WidgetState state; - state.width = getWidth(); - state.height = mDroppedDown ? mFoldedUpHeight : getHeight(); - state.enabled = isEnabled(); - state.selected = mDroppedDown; - state.hovered = mPushed; - - gui->getTheme()->drawDropDownButton(static_cast<Graphics*>(graphics), state); + WidgetState state(this); + if (mDroppedDown) + { + state.height = mFoldedUpHeight; + state.flags |= STATE_SELECTED; + } + if (mPushed) + state.flags |= STATE_HOVERED; + + const auto theme = gui->getTheme(); + const int buttonWidth = theme->getMinWidth(SkinType::DropDownButton); + + // FIXME: Needs support for setting alignment in the theme. + state.x = state.width - buttonWidth; + + theme->drawSkin(static_cast<Graphics *>(graphics), SkinType::DropDownButton, state); } // -- KeyListener notifications diff --git a/src/gui/widgets/popup.cpp b/src/gui/widgets/popup.cpp index b12acf31..8bbab948 100644 --- a/src/gui/widgets/popup.cpp +++ b/src/gui/widgets/popup.cpp @@ -29,14 +29,13 @@ #include "gui/viewport.h" #include "gui/widgets/windowcontainer.h" -#include "resources/theme.h" - #include <guichan/exception.hpp> -Popup::Popup(const std::string &name, const std::string &skin): - mPopupName(name), - mMaxWidth(graphics->getWidth()), - mMaxHeight(graphics->getHeight()) +Popup::Popup(const std::string &name, SkinType skinType) + : mPopupName(name) + , mMaxWidth(graphics->getWidth()) + , mMaxHeight(graphics->getHeight()) + , mSkinType(skinType) { logger->log("Popup::Popup(\"%s\")", name.c_str()); @@ -45,9 +44,6 @@ Popup::Popup(const std::string &name, const std::string &skin): setPadding(6); - // Loads the skin - mSkin = gui->getTheme()->load(skin); - // Add this window to the window container windowContainer->add(this); @@ -58,8 +54,6 @@ Popup::Popup(const std::string &name, const std::string &skin): Popup::~Popup() { logger->log("Popup::~Popup(\"%s\")", mPopupName.c_str()); - - mSkin->instances--; } void Popup::setWindowContainer(WindowContainer *wc) @@ -69,10 +63,7 @@ void Popup::setWindowContainer(WindowContainer *wc) void Popup::draw(gcn::Graphics *graphics) { - auto *g = static_cast<Graphics*>(graphics); - - g->drawImageRect(0, 0, getWidth(), getHeight(), mSkin->getBorder()); - + gui->getTheme()->drawSkin(static_cast<Graphics *>(graphics), mSkinType, WidgetState(this)); drawChildren(graphics); } @@ -116,12 +107,12 @@ void Popup::setLocationRelativeTo(gcn::Widget *widget) void Popup::setMinWidth(int width) { - mMinWidth = std::max(width, mSkin->getMinWidth()); + mMinWidth = std::max(gui->getTheme()->getMinWidth(mSkinType), width); } void Popup::setMinHeight(int height) { - mMinHeight = std::max(height, mSkin->getMinHeight()); + mMinHeight = std::max(gui->getTheme()->getMinHeight(mSkinType), height); } void Popup::setMaxWidth(int width) diff --git a/src/gui/widgets/popup.h b/src/gui/widgets/popup.h index 41914984..6a206672 100644 --- a/src/gui/widgets/popup.h +++ b/src/gui/widgets/popup.h @@ -25,6 +25,7 @@ #include "guichanfwd.h" #include "gui/widgets/container.h" +#include "resources/theme.h" #include <guichan/mouselistener.hpp> @@ -52,10 +53,10 @@ class Popup : public Container, public gcn::MouseListener * * @param name A human readable name for the popup. Only useful for * debugging purposes. - * @param skin The location where the Popup's skin XML can be found. + * @param skinType The skin type used when drawing the popup. */ - Popup(const std::string &name = std::string(), - const std::string &skin = "window.xml"); + explicit Popup(const std::string &name = std::string(), + SkinType skinType = SkinType::Popup); /** * Destructor. Deletes all the added widgets. @@ -151,12 +152,12 @@ class Popup : public Container, public gcn::MouseListener void position(int x, int y); private: - std::string mPopupName; /**< Name of the popup */ - int mMinWidth = 100; /**< Minimum popup width */ - int mMinHeight = 40; /**< Minimum popup height */ - int mMaxWidth; /**< Maximum popup width */ - int mMaxHeight; /**< Maximum popup height */ - int mPadding; /**< Holds the padding of the popup. */ - - Skin *mSkin; /**< Skin in use by this popup */ + std::string mPopupName; /**< Name of the popup */ + int mMinWidth = 100; /**< Minimum popup width */ + int mMinHeight = 40; /**< Minimum popup height */ + int mMaxWidth; /**< Maximum popup width */ + int mMaxHeight; /**< Maximum popup height */ + int mPadding; /**< Holds the padding of the popup. */ + + SkinType mSkinType; /**< The skin type used when drawing the popup widget. */ }; diff --git a/src/gui/widgets/radiobutton.cpp b/src/gui/widgets/radiobutton.cpp index ee2f4983..93ceee07 100644 --- a/src/gui/widgets/radiobutton.cpp +++ b/src/gui/widgets/radiobutton.cpp @@ -33,12 +33,13 @@ RadioButton::RadioButton(const std::string &caption, void RadioButton::drawBox(gcn::Graphics* graphics) { - Theme::WidgetState state; - state.enabled = isEnabled(); - state.hovered = mHasMouse; - state.selected = isSelected(); + WidgetState state(this); + if (mHasMouse) + state.flags |= STATE_HOVERED; + if (isSelected()) + state.flags |= STATE_SELECTED; - gui->getTheme()->drawRadioButton(graphics, state); + gui->getTheme()->drawSkin(static_cast<Graphics *>(graphics), SkinType::RadioButton, state); } void RadioButton::draw(gcn::Graphics* graphics) diff --git a/src/gui/widgets/resizegrip.cpp b/src/gui/widgets/resizegrip.cpp index bda0b386..69803d07 100644 --- a/src/gui/widgets/resizegrip.cpp +++ b/src/gui/widgets/resizegrip.cpp @@ -24,20 +24,21 @@ #include "graphics.h" #include "gui/gui.h" -#include "resources/image.h" #include "resources/theme.h" #include <guichan/graphics.hpp> ResizeGrip::ResizeGrip() { - const auto gripImage = gui->getTheme()->getResizeGripImage(); - setSize(gripImage->getWidth() + 2, - gripImage->getHeight() + 2); + const auto theme = gui->getTheme(); + const auto minWidth = theme->getMinWidth(SkinType::ResizeGrip); + const auto minHeight = theme->getMinHeight(SkinType::ResizeGrip); + setSize(minWidth + 2, minHeight + 2); } void ResizeGrip::draw(gcn::Graphics *graphics) { - const auto gripImage = gui->getTheme()->getResizeGripImage(); - static_cast<Graphics*>(graphics)->drawImage(gripImage, 0, 0); + gui->getTheme()->drawSkin(static_cast<Graphics *>(graphics), + SkinType::ResizeGrip, + WidgetState(this)); } diff --git a/src/gui/widgets/scrollarea.cpp b/src/gui/widgets/scrollarea.cpp index 6a2cb7e4..62c37c64 100644 --- a/src/gui/widgets/scrollarea.cpp +++ b/src/gui/widgets/scrollarea.cpp @@ -24,7 +24,6 @@ #include "graphics.h" #include "gui/gui.h" -#include "resources/theme.h" ScrollArea::ScrollArea() { @@ -107,11 +106,11 @@ void ScrollArea::drawFrame(gcn::Graphics *graphics) const int bs = getFrameSize(); - Theme::WidgetState state; - state.width = getWidth() + bs * 2; - state.height = getHeight() + bs * 2; + WidgetState state(this); + state.width += bs * 2; + state.height += + bs * 2; - gui->getTheme()->drawScrollAreaFrame(static_cast<Graphics *>(graphics), state); + gui->getTheme()->drawSkin(static_cast<Graphics *>(graphics), SkinType::ScrollArea, state); } void ScrollArea::setOpaque(bool opaque) @@ -127,38 +126,22 @@ void ScrollArea::drawBackground(gcn::Graphics *graphics) void ScrollArea::drawUpButton(gcn::Graphics *graphics) { - auto theme = gui->getTheme(); - theme->drawScrollAreaButton(static_cast<Graphics *>(graphics), - Theme::ARROW_UP, - mUpButtonPressed, - getUpButtonDimension()); + drawButton(graphics, SkinType::ButtonUp, mUpButtonPressed, getUpButtonDimension()); } void ScrollArea::drawDownButton(gcn::Graphics *graphics) { - auto theme = gui->getTheme(); - theme->drawScrollAreaButton(static_cast<Graphics *>(graphics), - Theme::ARROW_DOWN, - mDownButtonPressed, - getDownButtonDimension()); + drawButton(graphics, SkinType::ButtonDown, mDownButtonPressed, getDownButtonDimension()); } void ScrollArea::drawLeftButton(gcn::Graphics *graphics) { - auto theme = gui->getTheme(); - theme->drawScrollAreaButton(static_cast<Graphics *>(graphics), - Theme::ARROW_LEFT, - mLeftButtonPressed, - getLeftButtonDimension()); + drawButton(graphics, SkinType::ButtonLeft, mLeftButtonPressed, getLeftButtonDimension()); } void ScrollArea::drawRightButton(gcn::Graphics *graphics) { - auto theme = gui->getTheme(); - theme->drawScrollAreaButton(static_cast<Graphics *>(graphics), - Theme::ARROW_RIGHT, - mRightButtonPressed, - getRightButtonDimension()); + drawButton(graphics, SkinType::ButtonRight, mRightButtonPressed, getRightButtonDimension()); } void ScrollArea::drawVBar(gcn::Graphics *graphics) @@ -177,18 +160,45 @@ void ScrollArea::drawHBar(gcn::Graphics *graphics) void ScrollArea::drawVMarker(gcn::Graphics *graphics) { - auto theme = gui->getTheme(); - theme->drawScrollAreaMarker(static_cast<Graphics *>(graphics), - mHasMouse && (mX > (getWidth() - getScrollbarWidth())), - getVerticalMarkerDimension()); + drawMarker(static_cast<Graphics *>(graphics), + mHasMouse && (mX > (getWidth() - getScrollbarWidth())), + getVerticalMarkerDimension()); } void ScrollArea::drawHMarker(gcn::Graphics *graphics) { - auto theme = gui->getTheme(); - theme->drawScrollAreaMarker(static_cast<Graphics *>(graphics), - mHasMouse && (mY > (getHeight() - getScrollbarWidth())), - getHorizontalMarkerDimension()); + drawMarker(static_cast<Graphics *>(graphics), + mHasMouse && (mY > (getHeight() - getScrollbarWidth())), + getHorizontalMarkerDimension()); +} + +void ScrollArea::drawButton(gcn::Graphics *graphics, + SkinType skinType, + bool pressed, + const gcn::Rectangle &dim) +{ + WidgetState state; + state.x = dim.x; + state.y = dim.y; + state.width = dim.width; + state.height = dim.height; + if (pressed) + state.flags |= STATE_SELECTED; + + gui->getTheme()->drawSkin(static_cast<Graphics *>(graphics), skinType, state); +} + +void ScrollArea::drawMarker(gcn::Graphics *graphics, bool hovered, const gcn::Rectangle &dim) +{ + WidgetState state; + state.x = dim.x; + state.y = dim.y; + state.width = dim.width; + state.height = dim.height; + if (hovered) + state.flags |= STATE_HOVERED; + + gui->getTheme()->drawSkin(static_cast<Graphics *>(graphics), SkinType::ScrollBar, state); } void ScrollArea::mouseMoved(gcn::MouseEvent& event) diff --git a/src/gui/widgets/scrollarea.h b/src/gui/widgets/scrollarea.h index ab0eb026..17f69548 100644 --- a/src/gui/widgets/scrollarea.h +++ b/src/gui/widgets/scrollarea.h @@ -21,6 +21,8 @@ #pragma once +#include "resources/theme.h" + #include <guichan/widgetlistener.hpp> #include <guichan/widgets/scrollarea.hpp> @@ -108,6 +110,12 @@ class ScrollArea : public gcn::ScrollArea, public gcn::WidgetListener void drawVMarker(gcn::Graphics *graphics) override; void drawHMarker(gcn::Graphics *graphics) override; + static void drawButton(gcn::Graphics *graphics, + SkinType skinType, + bool pressed, + const gcn::Rectangle &dim); + static void drawMarker(gcn::Graphics *graphics, bool hovered, const gcn::Rectangle &dim); + int mX = 0; int mY = 0; bool mHasMouse = false; diff --git a/src/gui/widgets/slider.cpp b/src/gui/widgets/slider.cpp index 20a843f3..7ad5aa60 100644 --- a/src/gui/widgets/slider.cpp +++ b/src/gui/widgets/slider.cpp @@ -41,19 +41,21 @@ Slider::Slider(double scaleStart, double scaleEnd): void Slider::init() { setFrameSize(0); - setMarkerLength(gui->getTheme()->getSliderMarkerLength()); + setMarkerLength(gui->getTheme()->getMinWidth(SkinType::SliderHandle)); } void Slider::draw(gcn::Graphics *graphics) { - Theme::WidgetState state; - state.width = getWidth(); - state.height = getHeight(); - state.enabled = isEnabled(); - state.hovered = mHasMouse; + WidgetState state(this); + if (mHasMouse) + state.flags |= STATE_HOVERED; auto theme = gui->getTheme(); - theme->drawSlider(static_cast<Graphics*>(graphics), state, getMarkerPosition()); + theme->drawSkin(static_cast<Graphics*>(graphics), SkinType::Slider, state); + + WidgetState handleState(state); + handleState.x += getMarkerPosition(); + theme->drawSkin(static_cast<Graphics*>(graphics), SkinType::SliderHandle, handleState); } void Slider::drawMarker(gcn::Graphics *graphics) diff --git a/src/gui/widgets/tab.cpp b/src/gui/widgets/tab.cpp index 1a857e55..5779b561 100644 --- a/src/gui/widgets/tab.cpp +++ b/src/gui/widgets/tab.cpp @@ -44,18 +44,16 @@ void Tab::init() void Tab::draw(gcn::Graphics *graphics) { - Theme::WidgetState state; - state.width = getWidth(); - state.height = getHeight(); - state.enabled = isEnabled(); - state.hovered = mHasMouse; - state.selected = mTabbedArea && mTabbedArea->isTabSelected(this); - state.focused = isFocused(); + WidgetState state(this); + if (mHasMouse) + state.flags |= STATE_HOVERED; + if (mTabbedArea && mTabbedArea->isTabSelected(this)) + state.flags |= STATE_SELECTED; - gui->getTheme()->drawTab(static_cast<Graphics*>(graphics), state); + gui->getTheme()->drawSkin(static_cast<Graphics *>(graphics), SkinType::Tab, state); // if tab is selected, it doesnt need to highlight activity - if (state.selected) + if (state.flags & STATE_SELECTED) mFlash = false; if (mFlash) diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp index a1a20e90..46fa18ae 100644 --- a/src/gui/widgets/textfield.cpp +++ b/src/gui/widgets/textfield.cpp @@ -60,11 +60,11 @@ void TextField::drawFrame(gcn::Graphics *graphics) { const int bs = getFrameSize(); - Theme::WidgetState state; - state.width = getWidth() + bs * 2; - state.height = getHeight() + bs * 2; + WidgetState state(this); + state.width += bs * 2; + state.height += bs * 2; - gui->getTheme()->drawTextFieldFrame(static_cast<Graphics*>(graphics), state); + gui->getTheme()->drawSkin(static_cast<Graphics *>(graphics), SkinType::TextField, state); } void TextField::setNumeric(bool numeric) diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp index 52ee917e..d47e1a29 100644 --- a/src/gui/widgets/window.cpp +++ b/src/gui/widgets/window.cpp @@ -31,7 +31,6 @@ #include "gui/widgets/resizegrip.h" #include "gui/widgets/windowcontainer.h" -#include "resources/image.h" #include "resources/theme.h" #include <guichan/exception.hpp> @@ -43,13 +42,12 @@ int Window::instances = 0; int Window::mouseResize = 0; -Window::Window(const std::string &caption, bool modal, Window *parent, - const std::string &skin): - gcn::Window(caption), - mParent(parent), - mModal(modal), - mMaxWinWidth(graphics->getWidth()), - mMaxWinHeight(graphics->getHeight()) +Window::Window(const std::string &caption, bool modal, Window *parent) + : gcn::Window(caption) + , mParent(parent) + , mModal(modal) + , mMaxWinWidth(graphics->getWidth()) + , mMaxWinHeight(graphics->getHeight()) { logger->log("Window::Window(\"%s\")", caption.c_str()); @@ -62,9 +60,6 @@ Window::Window(const std::string &caption, bool modal, Window *parent, setPadding(3); setTitleBarHeight(20); - // Loads the skin - mSkin = gui->getTheme()->load(skin); - // Add this window to the window container windowContainer->add(this); @@ -94,8 +89,6 @@ Window::~Window() removeWidgetListener(this); instances--; - - mSkin->instances--; } void Window::setWindowContainer(WindowContainer *wc) @@ -105,9 +98,11 @@ void Window::setWindowContainer(WindowContainer *wc) void Window::draw(gcn::Graphics *graphics) { - auto *g = static_cast<Graphics*>(graphics); + auto g = static_cast<Graphics*>(graphics); + auto theme = gui->getTheme(); - g->drawImageRect(0, 0, getWidth(), getHeight(), mSkin->getBorder()); + WidgetState state(this); + theme->drawSkin(g, SkinType::Window, state); // Draw title if (mShowTitle) @@ -117,23 +112,26 @@ void Window::draw(gcn::Graphics *graphics) g->drawText(getCaption(), 7, 5, gcn::Graphics::LEFT); } + const int closeButtonWidth = theme->getMinWidth(SkinType::ButtonClose); + const int stickyButtonWidth = theme->getMinWidth(SkinType::ButtonSticky); + // Draw Close Button if (mCloseButton) { - g->drawImage(mSkin->getCloseImage(), - getWidth() - mSkin->getCloseImage()->getWidth() - getPadding(), - getPadding()); + state.x = state.width - closeButtonWidth - getPadding(); + state.y = getPadding(); + theme->drawSkin(g, SkinType::ButtonClose, state); } // Draw Sticky Button if (mStickyButton) { - Image *button = mSkin->getStickyImage(mSticky); - int x = getWidth() - button->getWidth() - getPadding(); + state.flags = mSticky ? STATE_SELECTED : 0; + state.x = state.width - stickyButtonWidth - getPadding(); + state.y = getPadding(); if (mCloseButton) - x -= mSkin->getCloseImage()->getWidth(); - - g->drawImage(button, x, getPadding()); + state.x -= closeButtonWidth; + theme->drawSkin(g, SkinType::ButtonSticky, state); } drawChildren(graphics); @@ -218,13 +216,12 @@ void Window::setLocationRelativeTo(ImageRect::ImagePosition position, void Window::setMinWidth(int width) { - mMinWinWidth = width > mSkin->getMinWidth() ? width : mSkin->getMinWidth(); + mMinWinWidth = std::max(gui->getTheme()->getMinWidth(SkinType::Window), width); } void Window::setMinHeight(int height) { - mMinWinHeight = height > mSkin->getMinHeight() ? - height : mSkin->getMinHeight(); + mMinWinHeight = std::max(gui->getTheme()->getMinHeight(SkinType::Window), height); } void Window::setMaxWidth(int width) @@ -338,38 +335,42 @@ void Window::mousePressed(gcn::MouseEvent &event) if (event.getButton() == gcn::MouseEvent::LEFT) { + auto theme = gui->getTheme(); + const int x = event.getX(); const int y = event.getY(); + const int closeButtonWidth = theme->getMinWidth(SkinType::ButtonClose); + const int closeButtonHeight = theme->getMinHeight(SkinType::ButtonClose); + const int stickyButtonWidth = theme->getMinWidth(SkinType::ButtonSticky); + const int stickyButtonHeight = theme->getMinHeight(SkinType::ButtonSticky); + // Handle close button if (mCloseButton) { - gcn::Rectangle closeButtonRect( - getWidth() - mSkin->getCloseImage()->getWidth() - getPadding(), - getPadding(), - mSkin->getCloseImage()->getWidth(), - mSkin->getCloseImage()->getHeight()); + gcn::Rectangle closeButtonRect(getWidth() - closeButtonWidth - getPadding(), + getPadding(), + closeButtonWidth, + closeButtonHeight); if (closeButtonRect.isPointInRect(x, y)) - { close(); - } } // Handle sticky button if (mStickyButton) { - Image *button = mSkin->getStickyImage(mSticky); - int rx = getWidth() - button->getWidth() - getPadding(); + int stickyButtonX = getWidth() - stickyButtonWidth - getPadding(); if (mCloseButton) - rx -= mSkin->getCloseImage()->getWidth(); - gcn::Rectangle stickyButtonRect(rx, getPadding(), - button->getWidth(), button->getHeight()); + stickyButtonX -= closeButtonWidth; + + gcn::Rectangle stickyButtonRect(stickyButtonX, + getPadding(), + stickyButtonWidth, + stickyButtonHeight); if (stickyButtonRect.isPointInRect(x, y)) - { setSticky(!isSticky()); - } } // Handle window resizing diff --git a/src/gui/widgets/window.h b/src/gui/widgets/window.h index 686e5f43..916d767b 100644 --- a/src/gui/widgets/window.h +++ b/src/gui/widgets/window.h @@ -53,10 +53,9 @@ class Window : public gcn::Window, gcn::WidgetListener * @param parent The parent window. This is the window standing above * this one in the window hiearchy. When reordering, * a window will never go below its parent window. - * @param skin The location where the window's skin XML can be found. */ Window(const std::string &caption = "Window", bool modal = false, - Window *parent = nullptr, const std::string &skin = "window.xml"); + Window *parent = nullptr); /** * Destructor. Deletes all the added widgets. @@ -398,8 +397,6 @@ class Window : public gcn::Window, gcn::WidgetListener static int instances; /**< Number of Window instances */ - Skin *mSkin; /**< Skin in use by this window */ - /** * The width of the resize border. Is independent of the actual window * border width, and determines mostly the size of the corner area |