diff options
author | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-03-24 21:24:19 +0100 |
---|---|---|
committer | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2025-03-24 21:24:19 +0100 |
commit | 2739d3cface75a5477918ce03bd2f85b3244fe1a (patch) | |
tree | e3972d9a6c5eb1d0ddfdb73038055547b9291233 /src | |
parent | c600e0fae271ed25d066b01149fbc148295edde8 (diff) | |
download | mana-2739d3cface75a5477918ce03bd2f85b3244fe1a.tar.gz mana-2739d3cface75a5477918ce03bd2f85b3244fe1a.tar.bz2 mana-2739d3cface75a5477918ce03bd2f85b3244fe1a.tar.xz mana-2739d3cface75a5477918ce03bd2f85b3244fe1a.zip |
Added fill mode parameter to ImageRect
ImageRect now stretches the sides and center images by default because
this is more efficient these days. FilMode::Repeat can be specified when
repetition is desired.
Added 'fill' attribute to allow the fill mode to be specified for the
GUI theme images.
Diffstat (limited to 'src')
-rw-r--r-- | src/graphics.cpp | 124 | ||||
-rw-r--r-- | src/graphics.h | 15 | ||||
-rw-r--r-- | src/resources/theme.cpp | 11 |
3 files changed, 113 insertions, 37 deletions
diff --git a/src/graphics.cpp b/src/graphics.cpp index e9ccfc49..72101069 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -81,6 +81,14 @@ bool Graphics::drawImageF(const Image *image, float x, float y) return drawImageF(image, 0, 0, x, y, image->getWidth(), image->getHeight()); } +bool Graphics::drawRescaledImage(const Image *image, int x, int y, int width, int height) +{ + if (!image) + return false; + + return drawRescaledImage(image, 0, 0, x, y, image->getWidth(), image->getHeight(), width, height); +} + bool Graphics::drawRescaledImageF(const Image *image, int srcX, int srcY, float dstX, float dstY, int width, int height, float desiredWidth, float desiredHeight, bool useColor) { return drawRescaledImage(image, @@ -129,51 +137,95 @@ void Graphics::drawImageRect(int x, int y, int w, int h, const Image *bottomLeft, const Image *bottomRight, const Image *top, const Image *right, const Image *bottom, const Image *left, - const Image *center) -{ - pushClipArea(gcn::Rectangle(x, y, w, h)); - - // Draw the center area - drawImagePattern(center, - topLeft->getWidth(), topLeft->getHeight(), - w - topLeft->getWidth() - topRight->getWidth(), - h - topLeft->getHeight() - bottomLeft->getHeight()); - - // Draw the sides - drawImagePattern(top, - left->getWidth(), 0, - w - left->getWidth() - right->getWidth(), top->getHeight()); - drawImagePattern(bottom, - left->getWidth(), h - bottom->getHeight(), - w - left->getWidth() - right->getWidth(), - bottom->getHeight()); - drawImagePattern(left, - 0, top->getHeight(), - left->getWidth(), - h - top->getHeight() - bottom->getHeight()); - drawImagePattern(right, - w - right->getWidth(), top->getHeight(), - right->getWidth(), - h - top->getHeight() - bottom->getHeight()); + const Image *center, + FillMode fillMode) +{ + switch (fillMode) { + case FillMode::Stretch: + // Draw the center area + drawRescaledImage(center, + x + topLeft->getWidth(), + y + topLeft->getHeight(), + w - topLeft->getWidth() - topRight->getWidth(), + h - topLeft->getHeight() - bottomLeft->getHeight()); + + // Draw the sides + drawRescaledImage(top, + x + left->getWidth(), + y, + w - left->getWidth() - right->getWidth(), + top->getHeight()); + + drawRescaledImage(bottom, + x + left->getWidth(), + y + h - bottom->getHeight(), + w - left->getWidth() - right->getWidth(), + bottom->getHeight()); + + drawRescaledImage(left, + x, + y + top->getHeight(), + left->getWidth(), + h - top->getHeight() - bottom->getHeight()); + + drawRescaledImage(right, + x + w - right->getWidth(), + y + top->getHeight(), + right->getWidth(), + h - top->getHeight() - bottom->getHeight()); + break; + case FillMode::Repeat: + // Draw the center area + drawImagePattern(center, + x + topLeft->getWidth(), + y + topLeft->getHeight(), + w - topLeft->getWidth() - topRight->getWidth(), + h - topLeft->getHeight() - bottomLeft->getHeight()); + + // Draw the sides + drawImagePattern(top, + x + left->getWidth(), + y, + w - left->getWidth() - right->getWidth(), + top->getHeight()); + + drawImagePattern(bottom, + x + left->getWidth(), + y + h - bottom->getHeight(), + w - left->getWidth() - right->getWidth(), + bottom->getHeight()); + + drawImagePattern(left, + x, + y + top->getHeight(), + left->getWidth(), + h - top->getHeight() - bottom->getHeight()); + + drawImagePattern(right, + x + w - right->getWidth(), + y + top->getHeight(), + right->getWidth(), + h - top->getHeight() - bottom->getHeight()); + break; + } // Draw the corners - drawImage(topLeft, 0, 0); - drawImage(topRight, w - topRight->getWidth(), 0); - drawImage(bottomLeft, 0, h - bottomLeft->getHeight()); + drawImage(topLeft, x, y); + drawImage(topRight, x + w - topRight->getWidth(), y); + drawImage(bottomLeft, x, y + h - bottomLeft->getHeight()); drawImage(bottomRight, - w - bottomRight->getWidth(), - h - bottomRight->getHeight()); - - popClipArea(); + x + w - bottomRight->getWidth(), + y + h - bottomRight->getHeight()); } void Graphics::drawImageRect(int x, int y, int w, int h, const ImageRect &imgRect) { drawImageRect(x, y, w, h, - imgRect.grid[0], imgRect.grid[2], imgRect.grid[6], imgRect.grid[8], - imgRect.grid[1], imgRect.grid[5], imgRect.grid[7], imgRect.grid[3], - imgRect.grid[4]); + imgRect.grid[0], imgRect.grid[2], imgRect.grid[6], imgRect.grid[8], + imgRect.grid[1], imgRect.grid[5], imgRect.grid[7], imgRect.grid[3], + imgRect.grid[4], + imgRect.fillMode); } void Graphics::_beginDraw() diff --git a/src/graphics.h b/src/graphics.h index 085ad5d4..4df63932 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -28,6 +28,12 @@ class Image; +enum class FillMode +{ + Stretch, + Repeat, +}; + /** * 9 images defining a rectangle. 4 corners, 4 sides and a middle area. The * topology is as follows: @@ -70,6 +76,7 @@ public: ImageRect &operator=(ImageRect &&r) = delete; Image *grid[9]; + FillMode fillMode = FillMode::Stretch; void setAlpha(float alpha); int minWidth() const; @@ -115,6 +122,11 @@ class Graphics : public gcn::Graphics /** * Draws a rescaled version of the image. */ + bool drawRescaledImage(const Image *image, int x, int y, int width, int height); + + /** + * Draws a rescaled version of the image. + */ virtual bool drawRescaledImage(const Image *image, int srcX, int srcY, int dstX, int dstY, int width, int height, @@ -176,7 +188,8 @@ class Graphics : public gcn::Graphics const Image *bottomLeft, const Image *bottomRight, const Image *top, const Image *right, const Image *bottom, const Image *left, - const Image *center); + const Image *center, + FillMode fillMode = FillMode::Stretch); /** * Draws a rectangle using images. 4 corner images, 4 side images and 1 diff --git a/src/resources/theme.cpp b/src/resources/theme.cpp index 995d347f..70aaff83 100644 --- a/src/resources/theme.cpp +++ b/src/resources/theme.cpp @@ -503,6 +503,15 @@ void Theme::readSkinStateNode(XML::Node node, Skin &skin) const skin.addState(std::move(state)); } +template<> +inline void fromString(const char *str, FillMode &value) +{ + if (strcmp(str, "repeat") == 0) + value = FillMode::Repeat; + else if (strcmp(str, "stretch") == 0) + value = FillMode::Stretch; +} + void Theme::readSkinStateImgNode(XML::Node node, SkinState &state) const { const std::string src = node.getProperty("src", std::string()); @@ -549,6 +558,8 @@ void Theme::readSkinStateImgNode(XML::Node node, SkinState &state) const { auto &border = part.data.emplace<ImageRect>(); + node.attribute("fill", border.fillMode); + const int gridx[4] = {x, x + left, x + width - right, x + width}; const int gridy[4] = {y, y + top, y + height - bottom, y + height}; unsigned a = 0; |