summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-03-29 20:34:14 +0100
committerThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-03-31 12:49:57 +0200
commit80f76c3aae438f7b9a7c1359c3f37aac460f934b (patch)
treec5786337049f701db3a22c432d773eaac4525012 /src/gui
parent2739d3cface75a5477918ce03bd2f85b3244fe1a (diff)
downloadmana-80f76c3aae438f7b9a7c1359c3f37aac460f934b.tar.gz
mana-80f76c3aae438f7b9a7c1359c3f37aac460f934b.tar.bz2
mana-80f76c3aae438f7b9a7c1359c3f37aac460f934b.tar.xz
mana-80f76c3aae438f7b9a7c1359c3f37aac460f934b.zip
GUI: Apply clipping only where necessary
Clipping has been disabled globally by taking it out of Graphics::pushClipArea. Now its name is a little confusing, but it can't just be changed since it is part of Guichan. Widgets that do need to clip their children use the new Graphics::pushClipRect, which pushes a clipping rectangle without affecting the local coordinates. These are: * ScrollArea * TextField * TabbedArea (scrolling tabs) * MiniMap While it might count as a small optimization, I'm actually disabling clipping because it is not always desired. For example it gets in the way of rendering the complete ResizeGrip in the Jewelry theme because that's a child widget.
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/itempopup.cpp3
-rw-r--r--src/gui/minimap.cpp51
-rw-r--r--src/gui/widgets/scrollarea.cpp10
-rw-r--r--src/gui/widgets/scrollarea.h5
-rw-r--r--src/gui/widgets/tabbedarea.cpp49
-rw-r--r--src/gui/widgets/tabbedarea.h2
-rw-r--r--src/gui/widgets/textfield.cpp5
7 files changed, 65 insertions, 60 deletions
diff --git a/src/gui/itempopup.cpp b/src/gui/itempopup.cpp
index c21f4003..35951331 100644
--- a/src/gui/itempopup.cpp
+++ b/src/gui/itempopup.cpp
@@ -23,7 +23,6 @@
#include "gui/itempopup.h"
#include "configuration.h"
-#include "graphics.h"
#include "units.h"
#include "gui/gui.h"
@@ -35,7 +34,6 @@
#include "utils/gettext.h"
#include "utils/stringutils.h"
-#include "resources/image.h"
#include "resources/resourcemanager.h"
#include "resources/theme.h"
@@ -139,6 +137,7 @@ void ItemPopup::setNoItem()
mItemDesc->setText(std::string());
mItemEffect->setText(std::string());
+ mItemWeight->setText(std::string());
setContentSize(mItemName->getWidth(), mItemName->getHeight());
}
diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp
index fc7fddd0..8924bc26 100644
--- a/src/gui/minimap.cpp
+++ b/src/gui/minimap.cpp
@@ -37,6 +37,7 @@
#include "utils/filesystem.h"
#include "utils/gettext.h"
+#include <algorithm>
#include <guichan/font.hpp>
Minimap::Minimap():
@@ -136,40 +137,38 @@ void Minimap::draw(gcn::Graphics *graphics)
{
Window::draw(graphics);
+ if (!mMap)
+ return;
+
+ auto g = static_cast<Graphics*>(graphics);
const gcn::Rectangle a = getChildrenArea();
- graphics->pushClipArea(a);
+ g->pushClipRect(a); // does actual clipping
+ g->pushClipArea(a); // only applies an offset
+
+ const int tileWidth = mMap->getTileWidth();
+ const int tileHeight = mMap->getTileHeight();
int mapOriginX = 0;
int mapOriginY = 0;
- if (mMapImage && mMap)
+ if (mMapImage)
{
if (mMapImage->getWidth() > a.width ||
mMapImage->getHeight() > a.height)
{
const Vector &p = local_player->getPosition();
- mapOriginX = (int) (((a.width) / 2) - (int) (p.x * mWidthProportion)
- / mMap->getTileWidth());
- mapOriginY = (int) (((a.height) / 2)
- - (int) (p.y * mHeightProportion)
- / mMap->getTileHeight());
+ mapOriginX = (a.width / 2) - (int) (p.x * mWidthProportion) / tileWidth;
+ mapOriginY = (a.height / 2) - (int) (p.y * mHeightProportion) / tileHeight;
const int minOriginX = a.width - mMapImage->getWidth();
const int minOriginY = a.height - mMapImage->getHeight();
- if (mapOriginX < minOriginX)
- mapOriginX = minOriginX;
- if (mapOriginY < minOriginY)
- mapOriginY = minOriginY;
- if (mapOriginX > 0)
- mapOriginX = 0;
- if (mapOriginY > 0)
- mapOriginY = 0;
+ mapOriginX = std::clamp(mapOriginX, minOriginX, 0);
+ mapOriginY = std::clamp(mapOriginY, minOriginY, 0);
}
- static_cast<Graphics*>(graphics)->
- drawImage(mMapImage, mapOriginX, mapOriginY);
+ g->drawImage(mMapImage, mapOriginX, mapOriginY);
}
for (auto actor : actorSpriteManager->getAll())
@@ -218,16 +217,14 @@ void Minimap::draw(gcn::Graphics *graphics)
const int offsetWidth = (int) ((dotSize - 1) * mWidthProportion);
const Vector &pos = being->getPosition();
- if (mMap)
- {
- graphics->fillRectangle(gcn::Rectangle(
- (int) (pos.x * mWidthProportion) / mMap->getTileWidth()
- + mapOriginX - offsetWidth,
- (int) (pos.y * mHeightProportion) / mMap->getTileHeight()
- + mapOriginY - offsetHeight,
- dotSize, dotSize));
- }
+ g->fillRectangle(
+ gcn::Rectangle((int) (pos.x * mWidthProportion) / tileWidth + mapOriginX - offsetWidth,
+ (int) (pos.y * mHeightProportion) / tileHeight + mapOriginY
+ - offsetHeight,
+ dotSize,
+ dotSize));
}
- graphics->popClipArea();
+ g->popClipArea();
+ g->popClipRect();
}
diff --git a/src/gui/widgets/scrollarea.cpp b/src/gui/widgets/scrollarea.cpp
index 8ee6692f..c4d55072 100644
--- a/src/gui/widgets/scrollarea.cpp
+++ b/src/gui/widgets/scrollarea.cpp
@@ -134,6 +134,16 @@ void ScrollArea::drawFrame(gcn::Graphics *graphics)
gui->getTheme()->drawSkin(static_cast<Graphics *>(graphics), SkinType::ScrollArea, state);
}
+void ScrollArea::drawChildren(gcn::Graphics *graphics)
+{
+ auto g = static_cast<Graphics*>(graphics);
+ g->pushClipRect(getChildrenArea());
+
+ gcn::ScrollArea::drawChildren(graphics);
+
+ g->popClipRect();
+}
+
void ScrollArea::setOpaque(bool opaque)
{
mOpaque = opaque;
diff --git a/src/gui/widgets/scrollarea.h b/src/gui/widgets/scrollarea.h
index 314711bf..40f1adc1 100644
--- a/src/gui/widgets/scrollarea.h
+++ b/src/gui/widgets/scrollarea.h
@@ -72,6 +72,11 @@ class ScrollArea : public gcn::ScrollArea
void drawFrame(gcn::Graphics *graphics) override;
/**
+ * Applies clipping to the contents.
+ */
+ void drawChildren(gcn::Graphics* graphics) override;
+
+ /**
* Sets whether the widget should draw its background or not.
*/
void setOpaque(bool opaque);
diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp
index d9ff9566..fb5436e0 100644
--- a/src/gui/widgets/tabbedarea.cpp
+++ b/src/gui/widgets/tabbedarea.cpp
@@ -21,6 +21,8 @@
#include "gui/widgets/tabbedarea.h"
+#include "graphics.h"
+
#include "gui/widgets/tab.h"
#include <guichan/widgets/container.hpp>
@@ -61,7 +63,12 @@ void TabbedArea::draw(gcn::Graphics *graphics)
if (mTabs.empty())
return;
+ auto g = static_cast<Graphics*>(graphics);
+ g->pushClipRect(getChildrenArea());
+
drawChildren(graphics);
+
+ g->popClipRect();
}
gcn::Widget *TabbedArea::getWidget(const std::string &name) const
@@ -206,9 +213,8 @@ void TabbedArea::updateTabsWidth()
{
mTabsWidth = 0;
for (const auto &[tab, _] : mTabs)
- {
mTabsWidth += tab->getWidth();
- }
+
updateVisibleTabsWidth();
}
@@ -216,9 +222,7 @@ void TabbedArea::updateVisibleTabsWidth()
{
mVisibleTabsWidth = 0;
for (unsigned int i = mTabScrollIndex; i < mTabs.size(); ++i)
- {
mVisibleTabsWidth += mTabs[i].first->getWidth();
- }
}
void TabbedArea::adjustTabPositions()
@@ -265,7 +269,7 @@ void TabbedArea::action(const gcn::ActionEvent& actionEvent)
{
if (actionEvent.getId() == "shift_left")
{
- if (mTabScrollIndex)
+ if (mTabScrollIndex > 0)
--mTabScrollIndex;
}
else if (actionEvent.getId() == "shift_right")
@@ -282,33 +286,18 @@ void TabbedArea::action(const gcn::ActionEvent& actionEvent)
void TabbedArea::updateArrowEnableState()
{
updateTabsWidth();
- if (mTabsWidth > getWidth() - 2)
- {
- mArrowButton[0]->setVisible(true);
- mArrowButton[1]->setVisible(true);
- }
- else
- {
- mArrowButton[0]->setVisible(false);
- mArrowButton[1]->setVisible(false);
+
+ const bool arrowButtonsVisible = mTabsWidth > getWidth() - 2;
+ mArrowButton[0]->setVisible(arrowButtonsVisible);
+ mArrowButton[1]->setVisible(arrowButtonsVisible);
+
+ if (!arrowButtonsVisible)
mTabScrollIndex = 0;
- }
- // Left arrow consistency check
- if (!mTabScrollIndex)
- mArrowButton[0]->setEnabled(false);
- else
- mArrowButton[0]->setEnabled(true);
+ mArrowButton[0]->setEnabled(mTabScrollIndex > 0);
// Right arrow consistency check
- if (mVisibleTabsWidth < getWidth() - 2
- - mArrowButton[0]->getWidth()
- - mArrowButton[1]->getWidth())
- {
- mArrowButton[1]->setEnabled(false);
- }
- else
- {
- mArrowButton[1]->setEnabled(true);
- }
+ const int availableWidth = getWidth() - 2 - mArrowButton[0]->getWidth()
+ - mArrowButton[1]->getWidth();
+ mArrowButton[1]->setEnabled(mVisibleTabsWidth >= availableWidth);
}
diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h
index c0566faa..558b2696 100644
--- a/src/gui/widgets/tabbedarea.h
+++ b/src/gui/widgets/tabbedarea.h
@@ -36,7 +36,7 @@ class Tab;
/**
* A tabbed area, the same as the guichan tabbed area in 0.8, but extended
*/
-class TabbedArea : public gcn::TabbedArea, public gcn::WidgetListener
+class TabbedArea final : public gcn::TabbedArea, public gcn::WidgetListener
{
public:
TabbedArea();
diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp
index 04955ec8..9f35a5dd 100644
--- a/src/gui/widgets/textfield.cpp
+++ b/src/gui/widgets/textfield.cpp
@@ -53,6 +53,9 @@ void TextField::draw(gcn::Graphics *graphics)
if (getFrameSize() == 0)
drawFrame(graphics);
+ auto g = static_cast<Graphics *>(graphics);
+ g->pushClipRect(gcn::Rectangle(0, 0, getWidth(), getHeight()));
+
if (isFocused())
{
drawCaret(graphics,
@@ -62,6 +65,8 @@ void TextField::draw(gcn::Graphics *graphics)
graphics->setColor(Theme::getThemeColor(Theme::TEXT));
graphics->setFont(getFont());
graphics->drawText(mText, mPadding - mXScroll, mPadding);
+
+ g->popClipRect();
}
void TextField::drawFrame(gcn::Graphics *graphics)