summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/graphics/gui/theme.xml14
-rw-r--r--src/graphics.cpp124
-rw-r--r--src/graphics.h15
-rw-r--r--src/resources/theme.cpp11
4 files changed, 120 insertions, 44 deletions
diff --git a/data/graphics/gui/theme.xml b/data/graphics/gui/theme.xml
index 047ef01c..6656f770 100644
--- a/data/graphics/gui/theme.xml
+++ b/data/graphics/gui/theme.xml
@@ -51,7 +51,7 @@
<skin type="Window" frameSize="0" padding="3" titleBarHeight="20">
<state>
- <img src="window.png" left="4" right="4" top="4" bottom="4" />
+ <img src="window.png" left="4" right="4" top="4" bottom="4" fill="repeat" />
</state>
</skin>
<skin type="ResizeGrip" padding="2">
@@ -61,7 +61,7 @@
</skin>
<skin type="Popup" padding="6">
<state>
- <img src="window.png" left="4" right="4" top="4" bottom="4" />
+ <img src="window.png" left="4" right="4" top="4" bottom="4" fill="repeat" />
</state>
</skin>
<skin type="SpeechBubble">
@@ -169,23 +169,23 @@
</skin>
<skin type="ScrollAreaHMarker">
<state hovered="true">
- <img src="vscroll_highlight.png" left="4" right="4" top="4" bottom="4" />
+ <img src="vscroll_highlight.png" left="4" right="4" top="4" bottom="4" fill="repeat" />
</state>
<state>
- <img src="vscroll_grey.png" left="4" right="4" top="4" bottom="4" />
+ <img src="vscroll_grey.png" left="4" right="4" top="4" bottom="4" fill="repeat" />
</state>
</skin>
<skin type="ScrollAreaVMarker">
<state hovered="true">
- <img src="vscroll_highlight.png" left="4" right="4" top="4" bottom="4" />
+ <img src="vscroll_highlight.png" left="4" right="4" top="4" bottom="4" fill="repeat" />
</state>
<state>
- <img src="vscroll_grey.png" left="4" right="4" top="4" bottom="4" />
+ <img src="vscroll_grey.png" left="4" right="4" top="4" bottom="4" fill="repeat" />
</state>
</skin>
<skin type="ProgressBar">
<state>
- <img src="vscroll_grey.png" left="4" right="4" top="4" bottom="4" />
+ <img src="vscroll_grey.png" left="4" right="4" top="4" bottom="4" fill="repeat" />
</state>
</skin>
<skin type="Slider">
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;