summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-04-01 11:36:06 +0200
committerThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-04-01 11:36:10 +0200
commit1d41d71eff082bb3232962ac6c4c68051f771da0 (patch)
tree591bb844e20f0b68f89f8ec503406c79603aa6a0
parentc3ebaad314653009b2c985156fac2e022a2acb74 (diff)
downloadmana-1d41d71eff082bb3232962ac6c4c68051f771da0.tar.gz
mana-1d41d71eff082bb3232962ac6c4c68051f771da0.tar.bz2
mana-1d41d71eff082bb3232962ac6c4c68051f771da0.tar.xz
mana-1d41d71eff082bb3232962ac6c4c68051f771da0.zip
GUI: Made CheckBox, RadioButton and Slider more customizable
Added handling of padding and text format and added new "spacing" skin variable which is used for the space between the label and the control in case of CheckBox and RadioButton. Small tweaks to UI layout in various places.
-rw-r--r--data/graphics/gui/resize.pngbin443 -> 4466 bytes
-rw-r--r--data/graphics/gui/theme.xml28
-rw-r--r--src/gui/charcreatedialog.cpp2
-rw-r--r--src/gui/customserverdialog.cpp10
-rw-r--r--src/gui/logindialog.cpp4
-rw-r--r--src/gui/setup_audio.cpp7
-rw-r--r--src/gui/setup_colors.cpp10
-rw-r--r--src/gui/setup_players.cpp8
-rw-r--r--src/gui/setup_video.cpp6
-rw-r--r--src/gui/widgets/checkbox.cpp44
-rw-r--r--src/gui/widgets/checkbox.h4
-rw-r--r--src/gui/widgets/radiobutton.cpp42
-rw-r--r--src/gui/widgets/radiobutton.h13
-rw-r--r--src/gui/widgets/slider.cpp9
-rw-r--r--src/resources/theme.cpp1
-rw-r--r--src/resources/theme.h1
16 files changed, 103 insertions, 86 deletions
diff --git a/data/graphics/gui/resize.png b/data/graphics/gui/resize.png
index 6b31ac64..61cb2cc2 100644
--- a/data/graphics/gui/resize.png
+++ b/data/graphics/gui/resize.png
Binary files differ
diff --git a/data/graphics/gui/theme.xml b/data/graphics/gui/theme.xml
index 97480dad..2dfb5a5f 100644
--- a/data/graphics/gui/theme.xml
+++ b/data/graphics/gui/theme.xml
@@ -50,7 +50,7 @@
<img src="window.png" left="4" right="4" top="4" bottom="4" fill="repeat" />
</state>
</skin>
- <skin type="ResizeGrip" padding="2">
+ <skin type="ResizeGrip" padding="3">
<state>
<img src="resize.png" />
</state>
@@ -91,38 +91,38 @@
<img src="tab.png" left="10" right="10" top="14" bottom="2" />
</state>
</skin>
- <skin type="CheckBox">
+ <skin type="CheckBox" padding="3" spacing="4">
<state disabled="true" selected="true">
- <img src="checkbox.png" x="27" y="0" width="9" height="10" offsetX="2" offsetY="2" />
+ <img src="checkbox.png" x="27" y="0" width="9" height="10" offsetX="2" offsetY="5" />
</state>
<state disabled="true">
- <img src="checkbox.png" x="18" y="0" width="9" height="10" offsetX="2" offsetY="2" />
+ <img src="checkbox.png" x="18" y="0" width="9" height="10" offsetX="2" offsetY="5" />
</state>
<state selected="true" hovered="true">
- <img src="checkbox.png" x="45" y="0" width="9" height="10" offsetX="2" offsetY="2" />
+ <img src="checkbox.png" x="45" y="0" width="9" height="10" offsetX="2" offsetY="5" />
</state>
<state hovered="true">
- <img src="checkbox.png" x="36" y="0" width="9" height="10" offsetX="2" offsetY="2" />
+ <img src="checkbox.png" x="36" y="0" width="9" height="10" offsetX="2" offsetY="5" />
</state>
<state selected="true">
- <img src="checkbox.png" x="9" y="0" width="9" height="10" offsetX="2" offsetY="2" />
+ <img src="checkbox.png" x="9" y="0" width="9" height="10" offsetX="2" offsetY="5" />
</state>
<state>
- <img src="checkbox.png" x="0" y="0" width="9" height="10" offsetX="2" offsetY="2" />
+ <img src="checkbox.png" x="0" y="0" width="9" height="10" offsetX="2" offsetY="5" />
</state>
</skin>
- <skin type="RadioButton">
+ <skin type="RadioButton" padding="3" spacing="4">
<state hovered="true" selected="true">
- <img src="radioin_highlight.png" offsetX="2" offsetY="2" />
+ <img src="radioin_highlight.png" offsetX="2" offsetY="5" />
</state>
<state hovered="true">
- <img src="radioout_highlight.png" offsetX="2" offsetY="2" />
+ <img src="radioout_highlight.png" offsetX="2" offsetY="5" />
</state>
<state selected="true">
- <img src="radioin.png" offsetX="2" offsetY="2" />
+ <img src="radioin.png" offsetX="2" offsetY="5" />
</state>
<state>
- <img src="radioout.png" offsetX="2" offsetY="2" />
+ <img src="radioout.png" offsetX="2" offsetY="5" />
</state>
</skin>
<skin type="TextField" frameSize="2" padding="2">
@@ -186,7 +186,7 @@
<img src="vscroll_grey.png" left="4" right="4" top="4" bottom="4" fill="repeat" />
</state>
</skin>
- <skin type="Slider">
+ <skin type="Slider" padding="4">
<state hovered="true">
<img src="slider_hilight.png" height="6" left="4" right="4" top="6" offsetY="4" />
</state>
diff --git a/src/gui/charcreatedialog.cpp b/src/gui/charcreatedialog.cpp
index 46ebd18b..fb834933 100644
--- a/src/gui/charcreatedialog.cpp
+++ b/src/gui/charcreatedialog.cpp
@@ -343,7 +343,7 @@ void CharCreateDialog::setAttributes(const std::vector<std::string> &labels,
add(attributeLabel);
auto *attributeSlider = new Slider(min, max);
- attributeSlider->setDimension(gcn::Rectangle(75, y, 100, 10));
+ attributeSlider->setDimension(gcn::Rectangle(75, y, 100, attributeSlider->getHeight()));
attributeSlider->setActionEventId("statslider");
attributeSlider->addActionListener(this);
add(attributeSlider);
diff --git a/src/gui/customserverdialog.cpp b/src/gui/customserverdialog.cpp
index c7c03b1a..f58e51ad 100644
--- a/src/gui/customserverdialog.cpp
+++ b/src/gui/customserverdialog.cpp
@@ -77,17 +77,17 @@ CustomServerDialog::CustomServerDialog(ServerDialog *parent, int index):
mPortField->addActionListener(this);
place(0, 0, nameLabel);
- place(1, 0, mNameField, 4).setPadding(3);
+ place(1, 0, mNameField, 4).setPadding(2);
place(0, 1, serverAdressLabel);
- place(1, 1, mServerAddressField, 4).setPadding(3);
+ place(1, 1, mServerAddressField, 4).setPadding(2);
place(0, 2, portLabel);
- place(1, 2, mPortField, 4).setPadding(3);
+ place(1, 2, mPortField, 4).setPadding(2);
#ifdef MANASERV_SUPPORT
place(0, 3, typeLabel);
- place(1, 3, mTypeField).setPadding(3);
+ place(1, 3, mTypeField).setPadding(2);
#endif
place(0, 4, descriptionLabel);
- place(1, 4, mDescriptionField, 4).setPadding(3);
+ place(1, 4, mDescriptionField, 4).setPadding(2);
place(4, 5, mOkButton);
place(3, 5, mCancelButton);
diff --git a/src/gui/logindialog.cpp b/src/gui/logindialog.cpp
index 1f96e02d..42ec0842 100644
--- a/src/gui/logindialog.cpp
+++ b/src/gui/logindialog.cpp
@@ -64,8 +64,8 @@ LoginDialog::LoginDialog(LoginData *loginData):
place(0, 0, userLabel);
place(0, 1, passLabel);
- place(1, 0, mUserField, 3).setPadding(1);
- place(1, 1, mPassField, 3).setPadding(1);
+ place(1, 0, mUserField, 3).setPadding(2);
+ place(1, 1, mPassField, 3).setPadding(2);
place(0, 5, mKeepCheck, 4);
place(0, 6, mRegisterButton).setHAlign(LayoutCell::LEFT);
place(2, 6, mServerButton);
diff --git a/src/gui/setup_audio.cpp b/src/gui/setup_audio.cpp
index f51bfcb6..43b132d8 100644
--- a/src/gui/setup_audio.cpp
+++ b/src/gui/setup_audio.cpp
@@ -29,6 +29,7 @@
#include "gui/widgets/checkbox.h"
#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
#include "gui/widgets/slider.h"
#include "utils/gettext.h"
@@ -71,11 +72,11 @@ Setup_Audio::Setup_Audio():
// Do the layout
place(0, 0, mSoundCheckBox);
- place(0, 1, mSfxSlider);
+ place(0, 1, mSfxSlider).setVAlign(LayoutCell::CENTER);
place(1, 1, sfxLabel);
- place(0, 2, mNotificationsSlider);
+ place(0, 2, mNotificationsSlider).setVAlign(LayoutCell::CENTER);
place(1, 2, notificationsLabel);
- place(0, 3, mMusicSlider);
+ place(0, 3, mMusicSlider).setVAlign(LayoutCell::CENTER);
place(1, 3, musicLabel);
place(0, 4, mDownloadMusicCheckBox);
}
diff --git a/src/gui/setup_colors.cpp b/src/gui/setup_colors.cpp
index 880f6f8a..c3d6a8c8 100644
--- a/src/gui/setup_colors.cpp
+++ b/src/gui/setup_colors.cpp
@@ -150,19 +150,19 @@ Setup_Colors::Setup_Colors() :
place(0, 0, mScroll, 6, 6).setPadding(2);
place(0, 6, mPreviewBox, 6).setPadding(2);
place(0, 7, mGradTypeLabel, 3);
- place(3, 7, mGradTypeSlider);
+ place(3, 7, mGradTypeSlider).setVAlign(Layout::CENTER);
place(4, 7, mGradTypeText, 2).setPadding(1);
place(0, 8, mRedLabel, 3);
- place(3, 8, mRedSlider);
+ place(3, 8, mRedSlider).setVAlign(Layout::CENTER);
place(5, 8, mRedText).setPadding(1);
place(0, 9, mGreenLabel, 3);
- place(3, 9, mGreenSlider);
+ place(3, 9, mGreenSlider).setVAlign(Layout::CENTER);
place(5, 9, mGreenText).setPadding(1);
place(0, 10, mBlueLabel, 3);
- place(3, 10, mBlueSlider);
+ place(3, 10, mBlueSlider).setVAlign(Layout::CENTER);
place(5, 10, mBlueText).setPadding(1);
place(0, 11, mGradDelayLabel, 3);
- place(3, 11, mGradDelaySlider);
+ place(3, 11, mGradDelaySlider).setVAlign(Layout::CENTER);
place(5, 11, mGradDelayText).setPadding(1);
mGradTypeText->setCaption(std::string());
diff --git a/src/gui/setup_players.cpp b/src/gui/setup_players.cpp
index 67fe79da..7cfa572a 100644
--- a/src/gui/setup_players.cpp
+++ b/src/gui/setup_players.cpp
@@ -267,13 +267,13 @@ Setup_Players::Setup_Players():
place(0, 0, mPlayerTitleTable, 4);
place(0, 1, mPlayerScrollArea, 4, 4).setPadding(2);
place(0, 5, mDeleteButton);
- place(0, 6, mShowGenderCheckBox, 2).setPadding(2);
- place(0, 7, mEnableChatLogCheckBox, 2).setPadding(2);
+ place(0, 6, mShowGenderCheckBox, 2);
+ place(0, 7, mEnableChatLogCheckBox, 2);
place(2, 5, ignore_action_label);
- place(2, 6, mIgnoreActionChoicesBox, 2).setPadding(2);
+ place(2, 6, mIgnoreActionChoicesBox, 2);
place(0, 8, mDefaultTrading);
place(0, 9, mDefaultWhisper);
- place(0, 10, mWhisperTabCheckBox, 4).setPadding(4);
+ place(0, 10, mWhisperTabCheckBox, 4);
player_relations.addListener(this);
}
diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp
index 68fb6767..b5322525 100644
--- a/src/gui/setup_video.cpp
+++ b/src/gui/setup_video.cpp
@@ -325,17 +325,17 @@ Setup_Video::Setup_Video():
place(0, 2, mDisableSDLTransparencyCheckBox, 4);
place(0, 3, mFpsCheckBox);
- place(1, 3, mFpsSlider, 2);
+ place(1, 3, mFpsSlider, 2).setVAlign(LayoutCell::CENTER);
place(3, 3, mFpsLabel);
place(0, 4, mParticleEffectsCheckBox, 4);
place(0, 5, particleDetailLabel);
- place(1, 5, mParticleDetailSlider, 2);
+ place(1, 5, mParticleDetailSlider, 2).setVAlign(LayoutCell::CENTER);
place(3, 5, mParticleDetailField);
place(0, 6, overlayDetailLabel);
- place(1, 6, mOverlayDetailSlider, 2);
+ place(1, 6, mOverlayDetailSlider, 2).setVAlign(LayoutCell::CENTER);
place(3, 6, mOverlayDetailField);
}
diff --git a/src/gui/widgets/checkbox.cpp b/src/gui/widgets/checkbox.cpp
index bea5f1d9..e6079f2f 100644
--- a/src/gui/widgets/checkbox.cpp
+++ b/src/gui/widgets/checkbox.cpp
@@ -21,35 +21,43 @@
#include "gui/widgets/checkbox.h"
+#include "textrenderer.h"
+
#include "gui/gui.h"
#include "resources/theme.h"
-CheckBox::CheckBox(const std::string &caption, bool selected):
- gcn::CheckBox(caption, selected)
-{
-}
+#include <guichan/font.hpp>
-void CheckBox::draw(gcn::Graphics* graphics)
+CheckBox::CheckBox(const std::string &caption, bool selected)
+ : gcn::CheckBox(caption, selected)
{
- drawBox(graphics);
-
- graphics->setFont(getFont());
- graphics->setColor(Theme::getThemeColor(Theme::TEXT));
-
- const int h = getHeight() + getHeight() / 2;
-
- graphics->drawText(getCaption(), h - 2, 0);
+ auto &skin = gui->getTheme()->getSkin(SkinType::CheckBox);
+ setWidth(skin.getMinWidth() + 2 * skin.padding + skin.spacing + getFont()->getWidth(caption));
+ setHeight(skin.getMinHeight() + 2 * skin.padding);
}
-void CheckBox::drawBox(gcn::Graphics* graphics)
+void CheckBox::draw(gcn::Graphics* graphics)
{
- WidgetState state(this);
+ WidgetState widgetState(this);
if (mHasMouse)
- state.flags |= STATE_HOVERED;
+ widgetState.flags |= STATE_HOVERED;
if (isSelected())
- state.flags |= STATE_SELECTED;
+ widgetState.flags |= STATE_SELECTED;
+
+ auto &skin = gui->getTheme()->getSkin(SkinType::CheckBox);
+ skin.draw(static_cast<Graphics *>(graphics), widgetState);
- gui->getTheme()->drawSkin(static_cast<Graphics *>(graphics), SkinType::CheckBox, state);
+ if (auto skinState = skin.getState(widgetState.flags))
+ {
+ auto &textFormat = skinState->textFormat;
+ TextRenderer::renderText(static_cast<Graphics *>(graphics),
+ getCaption(),
+ skin.getMinWidth() + skin.padding + skin.spacing,
+ skin.padding,
+ Graphics::LEFT,
+ textFormat.bold ? boldFont : getFont(),
+ textFormat);
+ }
}
void CheckBox::mouseEntered(gcn::MouseEvent& event)
diff --git a/src/gui/widgets/checkbox.h b/src/gui/widgets/checkbox.h
index b72213a9..ea1a20e7 100644
--- a/src/gui/widgets/checkbox.h
+++ b/src/gui/widgets/checkbox.h
@@ -39,9 +39,9 @@ class CheckBox : public gcn::CheckBox
void draw(gcn::Graphics *graphics) override;
/**
- * Draws the check box, not the caption.
+ * Overridden because box is drawn in CheckBox::draw.
*/
- void drawBox(gcn::Graphics *graphics) override;
+ void drawBox(gcn::Graphics *graphics) override {}
/**
* Called when the mouse enteres the widget area.
diff --git a/src/gui/widgets/radiobutton.cpp b/src/gui/widgets/radiobutton.cpp
index 93ceee07..ceba78eb 100644
--- a/src/gui/widgets/radiobutton.cpp
+++ b/src/gui/widgets/radiobutton.cpp
@@ -21,6 +21,8 @@
#include "gui/widgets/radiobutton.h"
+#include "textrenderer.h"
+
#include "gui/gui.h"
#include "resources/theme.h"
@@ -29,33 +31,33 @@ RadioButton::RadioButton(const std::string &caption,
bool marked)
: gcn::RadioButton(caption, group, marked)
{
+ auto &skin = gui->getTheme()->getSkin(SkinType::RadioButton);
+ setWidth(skin.getMinWidth() + 2 * skin.padding + skin.spacing + getFont()->getWidth(caption));
+ setHeight(skin.getMinHeight() + 2 * skin.padding);
}
-void RadioButton::drawBox(gcn::Graphics* graphics)
+void RadioButton::draw(gcn::Graphics* graphics)
{
- WidgetState state(this);
+ WidgetState widgetState(this);
if (mHasMouse)
- state.flags |= STATE_HOVERED;
+ widgetState.flags |= STATE_HOVERED;
if (isSelected())
- state.flags |= STATE_SELECTED;
-
- gui->getTheme()->drawSkin(static_cast<Graphics *>(graphics), SkinType::RadioButton, state);
-}
-
-void RadioButton::draw(gcn::Graphics* graphics)
-{
- graphics->pushClipArea(gcn::Rectangle(1, 1, getWidth() - 1,
- getHeight() - 1));
-
- drawBox(graphics);
-
- graphics->popClipArea();
+ widgetState.flags |= STATE_SELECTED;
- graphics->setFont(getFont());
- graphics->setColor(getForegroundColor());
+ auto &skin = gui->getTheme()->getSkin(SkinType::RadioButton);
+ skin.draw(static_cast<Graphics *>(graphics), widgetState);
- int h = getHeight() + getHeight() / 2;
- graphics->drawText(getCaption(), h - 2, 0);
+ if (auto skinState = skin.getState(widgetState.flags))
+ {
+ auto &textFormat = skinState->textFormat;
+ TextRenderer::renderText(static_cast<Graphics *>(graphics),
+ getCaption(),
+ skin.getMinWidth() + skin.padding + skin.spacing,
+ skin.padding,
+ Graphics::LEFT,
+ textFormat.bold ? boldFont : getFont(),
+ textFormat);
+ }
}
void RadioButton::mouseEntered(gcn::MouseEvent& event)
diff --git a/src/gui/widgets/radiobutton.h b/src/gui/widgets/radiobutton.h
index 192e5d34..fda43d01 100644
--- a/src/gui/widgets/radiobutton.h
+++ b/src/gui/widgets/radiobutton.h
@@ -34,25 +34,24 @@ class RadioButton : public gcn::RadioButton
bool marked = false);
/**
- * Draws the radiobutton, not the caption.
+ * Implementation of the draw method.
*/
- void drawBox(gcn::Graphics* graphics) override;
+ void draw(gcn::Graphics *graphics) override;
/**
- * Implementation of the draw methods.
- * Thus, avoiding the rhomb around the radio button.
+ * Overridden because box is drawn in RadioButton::draw.
*/
- void draw(gcn::Graphics* graphics) override;
+ void drawBox(gcn::Graphics *graphics) override {}
/**
* Called when the mouse enteres the widget area.
*/
- void mouseEntered(gcn::MouseEvent& event) override;
+ void mouseEntered(gcn::MouseEvent &event) override;
/**
* Called when the mouse leaves the widget area.
*/
- void mouseExited(gcn::MouseEvent& event) override;
+ void mouseExited(gcn::MouseEvent &event) override;
private:
bool mHasMouse = false;
diff --git a/src/gui/widgets/slider.cpp b/src/gui/widgets/slider.cpp
index dd476eb9..bad10c15 100644
--- a/src/gui/widgets/slider.cpp
+++ b/src/gui/widgets/slider.cpp
@@ -41,8 +41,13 @@ Slider::Slider(double scaleStart, double scaleEnd):
void Slider::init()
{
auto theme = gui->getTheme();
- setFrameSize(theme->getSkin(SkinType::Slider).frameSize);
- setMarkerLength(theme->getMinWidth(SkinType::SliderHandle));
+ auto &sliderSkin = theme->getSkin(SkinType::Slider);
+ auto &sliderHandleSkin = theme->getSkin(SkinType::SliderHandle);
+ setFrameSize(sliderSkin.frameSize);
+ setMarkerLength(sliderHandleSkin.getMinWidth());
+
+ setWidth(100);
+ setHeight(sliderSkin.getMinHeight() + 2 * sliderSkin.padding);
}
void Slider::draw(gcn::Graphics *graphics)
diff --git a/src/resources/theme.cpp b/src/resources/theme.cpp
index 9dd602c7..694f2210 100644
--- a/src/resources/theme.cpp
+++ b/src/resources/theme.cpp
@@ -473,6 +473,7 @@ void Theme::readSkinNode(XML::Node node)
node.attribute("frameSize", skin.frameSize);
node.attribute("padding", skin.padding);
+ node.attribute("spacing", skin.spacing);
node.attribute("titleBarHeight", skin.titleBarHeight);
node.attribute("titleOffsetX", skin.titleOffsetX);
node.attribute("titleOffsetY", skin.titleOffsetY);
diff --git a/src/resources/theme.h b/src/resources/theme.h
index 4f3535b4..2f6d5aab 100644
--- a/src/resources/theme.h
+++ b/src/resources/theme.h
@@ -153,6 +153,7 @@ class Skin
int frameSize = 0;
int padding = 0;
+ int spacing = 0;
int titleBarHeight = 0;
int titleOffsetX = 0;
int titleOffsetY = 0;