summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-03-17 10:39:38 +0100
committerThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-03-24 13:47:11 +0100
commit5274cc92c1055a3209dfae7e5346bfe52c35e4a8 (patch)
tree8bb9ceab97fb752a07294a52dcf2d390e79616fe /src/gui
parentd5f49e4bef99e2ae4b39bdf1b7c644c28a85c5a2 (diff)
downloadmana-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.cpp3
-rw-r--r--src/gui/speechbubble.cpp13
-rw-r--r--src/gui/widgets/button.cpp20
-rw-r--r--src/gui/widgets/checkbox.cpp11
-rw-r--r--src/gui/widgets/dropdown.cpp32
-rw-r--r--src/gui/widgets/popup.cpp25
-rw-r--r--src/gui/widgets/popup.h23
-rw-r--r--src/gui/widgets/radiobutton.cpp11
-rw-r--r--src/gui/widgets/resizegrip.cpp13
-rw-r--r--src/gui/widgets/scrollarea.cpp76
-rw-r--r--src/gui/widgets/scrollarea.h8
-rw-r--r--src/gui/widgets/slider.cpp16
-rw-r--r--src/gui/widgets/tab.cpp16
-rw-r--r--src/gui/widgets/textfield.cpp8
-rw-r--r--src/gui/widgets/window.cpp81
-rw-r--r--src/gui/widgets/window.h5
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