diff options
author | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-03-29 20:34:14 +0100 |
---|---|---|
committer | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-03-31 12:49:57 +0200 |
commit | 80f76c3aae438f7b9a7c1359c3f37aac460f934b (patch) | |
tree | c5786337049f701db3a22c432d773eaac4525012 /src/gui | |
parent | 2739d3cface75a5477918ce03bd2f85b3244fe1a (diff) | |
download | mana-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.cpp | 3 | ||||
-rw-r--r-- | src/gui/minimap.cpp | 51 | ||||
-rw-r--r-- | src/gui/widgets/scrollarea.cpp | 10 | ||||
-rw-r--r-- | src/gui/widgets/scrollarea.h | 5 | ||||
-rw-r--r-- | src/gui/widgets/tabbedarea.cpp | 49 | ||||
-rw-r--r-- | src/gui/widgets/tabbedarea.h | 2 | ||||
-rw-r--r-- | src/gui/widgets/textfield.cpp | 5 |
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) |