Browse Source

Merge pull request #3629 from IvanSavenko/ui_generation

Unify graphical primitives elements
Ivan Savenko 1 year ago
parent
commit
8647abb94b

BIN
Mods/vcmi/Data/settingsWindow/checkBoxEmpty.png


BIN
Mods/vcmi/Data/settingsWindow/lineHorizontal.png


BIN
Mods/vcmi/Data/settingsWindow/lineVertical.png


+ 2 - 0
client/CMakeLists.txt

@@ -108,6 +108,7 @@ set(client_SRCS
 	widgets/CGarrisonInt.cpp
 	widgets/CreatureCostBox.cpp
 	widgets/ComboBox.cpp
+	widgets/GraphicalPrimitiveCanvas.cpp
 	widgets/Images.cpp
 	widgets/MiscWidgets.cpp
 	widgets/ObjectLists.cpp
@@ -291,6 +292,7 @@ set(client_HEADERS
 	widgets/CGarrisonInt.h
 	widgets/CreatureCostBox.h
 	widgets/ComboBox.h
+	widgets/GraphicalPrimitiveCanvas.h
 	widgets/Images.h
 	widgets/MiscWidgets.h
 	widgets/ObjectLists.h

+ 1 - 1
client/adventureMap/TurnTimerWidget.cpp

@@ -18,7 +18,7 @@
 #include "../gui/CGuiHandler.h"
 #include "../render/Graphics.h"
 #include "../widgets/Images.h"
-#include "../widgets/MiscWidgets.h"
+#include "../widgets/GraphicalPrimitiveCanvas.h"
 #include "../widgets/TextControls.h"
 
 #include "../../CCallback.h"

+ 1 - 1
client/battle/BattleInterfaceClasses.cpp

@@ -34,7 +34,7 @@
 #include "../widgets/Buttons.h"
 #include "../widgets/Images.h"
 #include "../widgets/TextControls.h"
-#include "../widgets/MiscWidgets.h"
+#include "../widgets/GraphicalPrimitiveCanvas.h"
 #include "../windows/CMessage.h"
 #include "../windows/CCreatureWindow.h"
 #include "../windows/CSpellWindow.h"

+ 1 - 0
client/globalLobby/GlobalLobbyLoginWindow.cpp

@@ -20,6 +20,7 @@
 #include "../gui/WindowHandler.h"
 #include "../widgets/Buttons.h"
 #include "../widgets/Images.h"
+#include "../widgets/GraphicalPrimitiveCanvas.h"
 #include "../widgets/MiscWidgets.h"
 #include "../widgets/TextControls.h"
 

+ 1 - 0
client/globalLobby/GlobalLobbyWidget.cpp

@@ -18,6 +18,7 @@
 #include "../gui/CGuiHandler.h"
 #include "../gui/WindowHandler.h"
 #include "../widgets/Buttons.h"
+#include "../widgets/GraphicalPrimitiveCanvas.h"
 #include "../widgets/MiscWidgets.h"
 #include "../widgets/ObjectLists.h"
 #include "../widgets/TextControls.h"

+ 41 - 3
client/gui/InterfaceObjectConfigurable.cpp

@@ -22,7 +22,7 @@
 #include "../widgets/CComponent.h"
 #include "../widgets/ComboBox.h"
 #include "../widgets/Buttons.h"
-#include "../widgets/MiscWidgets.h"
+#include "../widgets/GraphicalPrimitiveCanvas.h"
 #include "../widgets/ObjectLists.h"
 #include "../widgets/Slider.h"
 #include "../widgets/TextControls.h"
@@ -57,6 +57,7 @@ InterfaceObjectConfigurable::InterfaceObjectConfigurable(int used, Point offset)
 	REGISTER_BUILDER("layout", &InterfaceObjectConfigurable::buildLayout);
 	REGISTER_BUILDER("comboBox", &InterfaceObjectConfigurable::buildComboBox);
 	REGISTER_BUILDER("textInput", &InterfaceObjectConfigurable::buildTextInput);
+	REGISTER_BUILDER("graphicalPrimitive", &InterfaceObjectConfigurable::buildGraphicalPrimitive);
 	REGISTER_BUILDER("transparentFilledRectangle", &InterfaceObjectConfigurable::buildTransparentFilledRectangle);
 	REGISTER_BUILDER("textBox", &InterfaceObjectConfigurable::buildTextBox);
 }
@@ -113,8 +114,20 @@ void InterfaceObjectConfigurable::build(const JsonNode &config)
 	{
 		if (!config["library"].isNull())
 		{
-			const JsonNode library(JsonPath::fromJson(config["library"]));
-			loadCustomBuilders(library);
+			if (config["library"].isString())
+			{
+				const JsonNode library(JsonPath::fromJson(config["library"]));
+				loadCustomBuilders(library);
+			}
+
+			if (config["library"].isVector())
+			{
+				for (auto const & entry : config["library"].Vector())
+				{
+					const JsonNode library(JsonPath::fromJson(entry));
+					loadCustomBuilders(library);
+				}
+			}
 		}
 
 		loadCustomBuilders(config["customTypes"]);
@@ -707,6 +720,31 @@ std::shared_ptr<CShowableAnim> InterfaceObjectConfigurable::buildAnimation(const
 	return anim;
 }
 
+std::shared_ptr<CIntObject> InterfaceObjectConfigurable::buildGraphicalPrimitive(const JsonNode & config) const
+{
+	logGlobal->debug("Building widget GraphicalPrimitiveCanvas");
+
+	auto rect = readRect(config["rect"]);
+	auto widget = std::make_shared<GraphicalPrimitiveCanvas>(rect);
+
+	for (auto const & entry : config["primitives"].Vector())
+	{
+		auto color = readColor(entry["color"]);
+		auto typeString = entry["type"].String();
+		auto pointA = readPosition(entry["a"]);
+		auto pointB = readPosition(entry["b"]);
+
+		if (typeString == "line")
+			widget->addLine(pointA, pointB, color);
+		if (typeString == "filledBox")
+			widget->addBox(pointA, pointB, color);
+		if (typeString == "rectangle")
+			widget->addRectangle(pointA, pointB, color);
+	}
+
+	return widget;
+}
+
 std::shared_ptr<TransparentFilledRectangle> InterfaceObjectConfigurable::buildTransparentFilledRectangle(const JsonNode & config) const
 {
 	logGlobal->debug("Building widget TransparentFilledRectangle");

+ 1 - 0
client/gui/InterfaceObjectConfigurable.h

@@ -108,6 +108,7 @@ protected:
 	std::shared_ptr<ComboBox> buildComboBox(const JsonNode &);
 	std::shared_ptr<CTextInput> buildTextInput(const JsonNode &) const;
 	std::shared_ptr<TransparentFilledRectangle> buildTransparentFilledRectangle(const JsonNode & config) const;
+	std::shared_ptr<CIntObject> buildGraphicalPrimitive(const JsonNode & config) const;
 	std::shared_ptr<CTextBox> buildTextBox(const JsonNode & config) const;
 		
 	//composite widgets

+ 1 - 1
client/lobby/CSelectionBase.cpp

@@ -29,7 +29,7 @@
 #include "../mainmenu/CMainMenu.h"
 #include "../widgets/Buttons.h"
 #include "../widgets/CComponent.h"
-#include "../widgets/MiscWidgets.h"
+#include "../widgets/GraphicalPrimitiveCanvas.h"
 #include "../widgets/ObjectLists.h"
 #include "../widgets/Slider.h"
 #include "../widgets/TextControls.h"

+ 1 - 1
client/mainmenu/CHighScoreScreen.cpp

@@ -17,7 +17,7 @@
 #include "../widgets/TextControls.h"
 #include "../widgets/Buttons.h"
 #include "../widgets/Images.h"
-#include "../widgets/MiscWidgets.h"
+#include "../widgets/GraphicalPrimitiveCanvas.h"
 #include "../windows/InfoWindows.h"
 #include "../render/Canvas.h"
 

+ 85 - 0
client/widgets/GraphicalPrimitiveCanvas.cpp

@@ -0,0 +1,85 @@
+/*
+ * GraphicalPrimitiveCanvas.cpp, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#include "StdInc.h"
+#include "GraphicalPrimitiveCanvas.h"
+
+#include "../render/Canvas.h"
+
+GraphicalPrimitiveCanvas::GraphicalPrimitiveCanvas(Rect dimensions)
+{
+	pos = dimensions + pos.topLeft();
+}
+
+void GraphicalPrimitiveCanvas::showAll(Canvas & to)
+{
+	auto const & translatePoint = [this](const Point & input){
+		int x = input.x < 0 ? pos.w + input.x : input.x;
+		int y = input.y < 0 ? pos.h + input.y : input.y;
+
+		return Point(x,y);
+	};
+
+	for (auto const & entry : primitives)
+	{
+		switch (entry.type)
+		{
+			case PrimitiveType::LINE:
+			{
+				to.drawLine(pos.topLeft() + translatePoint(entry.a), pos.topLeft() + translatePoint(entry.b), entry.color, entry.color);
+				break;
+			}
+			case PrimitiveType::FILLED_BOX:
+			{
+				to.drawColorBlended(Rect(pos.topLeft() + translatePoint(entry.a), translatePoint(entry.b)), entry.color);
+				break;
+			}
+			case PrimitiveType::RECTANGLE:
+			{
+				to.drawBorder(Rect(pos.topLeft() + translatePoint(entry.a), translatePoint(entry.b)), entry.color);
+				break;
+			}
+		}
+	}
+}
+
+void GraphicalPrimitiveCanvas::addLine(const Point & from, const Point & to, const ColorRGBA & color)
+{
+	primitives.push_back({color, from, to, PrimitiveType::LINE});
+}
+
+void GraphicalPrimitiveCanvas::addBox(const Point & topLeft, const Point & size, const ColorRGBA & color)
+{
+	primitives.push_back({color, topLeft, size, PrimitiveType::FILLED_BOX});
+}
+
+void GraphicalPrimitiveCanvas::addRectangle(const Point & topLeft, const Point & size, const ColorRGBA & color)
+{
+	primitives.push_back({color, topLeft, size, PrimitiveType::RECTANGLE});
+}
+
+TransparentFilledRectangle::TransparentFilledRectangle(Rect position, ColorRGBA color) :
+	GraphicalPrimitiveCanvas(position)
+{
+	addBox(Point(0,0), Point(-1, -1), color);
+}
+
+TransparentFilledRectangle::TransparentFilledRectangle(Rect position, ColorRGBA color, ColorRGBA colorLine, int width) :
+	GraphicalPrimitiveCanvas(position)
+{
+	addBox(Point(0,0), Point(-1, -1), color);
+	for (int i = 0; i < width; ++i)
+		addRectangle(Point(i,i), Point(-1-i*2, -1-i*2), colorLine);
+}
+
+SimpleLine::SimpleLine(Point pos1, Point pos2, ColorRGBA color) :
+	GraphicalPrimitiveCanvas(Rect(pos1, pos2 - pos1))
+{
+	addLine(Point(0,0), Point(-1, -1), color);
+}

+ 54 - 0
client/widgets/GraphicalPrimitiveCanvas.h

@@ -0,0 +1,54 @@
+/*
+ * GraphicalPrimitiveCanvas.h, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#pragma once
+
+#include "../gui/CIntObject.h"
+
+class GraphicalPrimitiveCanvas : public CIntObject
+{
+	enum class PrimitiveType
+	{
+		LINE,
+		RECTANGLE,
+		FILLED_BOX
+	};
+
+	struct PrimitiveEntry
+	{
+		ColorRGBA color;
+		Point a;
+		Point b;
+		PrimitiveType type;
+	};
+
+	std::vector<PrimitiveEntry> primitives;
+
+	void showAll(Canvas & to) override;
+
+public:
+	GraphicalPrimitiveCanvas(Rect position);
+
+	void addLine(const Point & from, const Point & to, const ColorRGBA & color);
+	void addBox(const Point & topLeft, const Point & size, const ColorRGBA & color);
+	void addRectangle(const Point & topLeft, const Point & size, const ColorRGBA & color);
+};
+
+class TransparentFilledRectangle : public GraphicalPrimitiveCanvas
+{
+public:
+	TransparentFilledRectangle(Rect position, ColorRGBA color);
+	TransparentFilledRectangle(Rect position, ColorRGBA color, ColorRGBA colorLine, int width = 1);
+};
+
+class SimpleLine : public GraphicalPrimitiveCanvas
+{
+public:
+	SimpleLine(Point pos1, Point pos2, ColorRGBA color);
+};

+ 12 - 49
client/widgets/MiscWidgets.cpp

@@ -21,8 +21,9 @@
 #include "../gui/WindowHandler.h"
 #include "../eventsSDL/InputHandler.h"
 #include "../windows/CTradeWindow.h"
-#include "../widgets/TextControls.h"
 #include "../widgets/CGarrisonInt.h"
+#include "../widgets/GraphicalPrimitiveCanvas.h"
+#include "../widgets/TextControls.h"
 #include "../windows/CCastleInterface.h"
 #include "../windows/InfoWindows.h"
 #include "../render/Canvas.h"
@@ -663,54 +664,13 @@ void CCreaturePic::setAmount(int newAmount)
 		amount->setText("");
 }
 
-TransparentFilledRectangle::TransparentFilledRectangle(Rect position, ColorRGBA color) :
-	color(color), colorLine(ColorRGBA()), drawLine(false), lineWidth(0)
-{
-	pos = position + pos.topLeft();
-}
-
-TransparentFilledRectangle::TransparentFilledRectangle(Rect position, ColorRGBA color, ColorRGBA colorLine, int width) :
-	color(color), colorLine(colorLine), drawLine(true), lineWidth(width)
-{
-	pos = position + pos.topLeft();
-}
-
-void TransparentFilledRectangle::setDrawBorder(bool on)
-{
-	drawLine = on;
-}
-
-bool TransparentFilledRectangle::getDrawBorder()
-{
-	return drawLine;
-}
-
-void TransparentFilledRectangle::setBorderWidth(int width)
-{
-	lineWidth = width;
-}
-
-void TransparentFilledRectangle::showAll(Canvas & to) 
-{
-	to.drawColorBlended(pos, color);
-	if(drawLine)
-		to.drawBorder(pos, colorLine, lineWidth);
-}
-
-SimpleLine::SimpleLine(Point pos1, Point pos2, ColorRGBA color) :
-	pos1(pos1), pos2(pos2), color(color)
-{}
-
-void SimpleLine::showAll(Canvas & to) 
-{
-	to.drawLine(pos1 + pos.topLeft(), pos2 + pos.topLeft(), color, color);
-}
-
 SelectableSlot::SelectableSlot(Rect area, Point oversize, const int width)
 	: LRClickableAreaWTextComp(area)
+	, selected(false)
 {
-	selection = std::make_unique<TransparentFilledRectangle>(
-		Rect(area.topLeft() - oversize, area.dimensions() + oversize * 2), Colors::TRANSPARENCY, Colors::YELLOW, width);
+	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
+
+	selection = std::make_shared<TransparentFilledRectangle>( Rect(-oversize, area.dimensions() + oversize * 2), Colors::TRANSPARENCY, Colors::YELLOW, width);
 	selectSlot(false);
 }
 
@@ -726,15 +686,18 @@ SelectableSlot::SelectableSlot(Rect area, const int width)
 
 void SelectableSlot::selectSlot(bool on)
 {
-	selection->setDrawBorder(on);
+	selection->setEnabled(on);
+	selected = on;
 }
 
 bool SelectableSlot::isSelected() const
 {
-	return selection->getDrawBorder();
+	return selected;
 }
 
 void SelectableSlot::setSelectionWidth(int width)
 {
-	selection->setBorderWidth(width);
+	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
+	selection = std::make_shared<TransparentFilledRectangle>( selection->pos - pos.topLeft(), Colors::TRANSPARENCY, Colors::YELLOW, width);
+	selectSlot(selected);
 }

+ 3 - 27
client/widgets/MiscWidgets.h

@@ -33,6 +33,7 @@ class CCreatureAnim;
 class CComponent;
 class CAnimImage;
 class LRClickableArea;
+class TransparentFilledRectangle;
 
 /// Shows a text by moving the mouse cursor over the object
 class CHoverableArea: public virtual CIntObject
@@ -248,35 +249,10 @@ public:
 	MoraleLuckBox(bool Morale, const Rect &r, bool Small=false);
 };
 
-class TransparentFilledRectangle : public CIntObject
-{
-	ColorRGBA color;
-	ColorRGBA colorLine;
-	bool drawLine;
-	int lineWidth;
-
-public:
-    TransparentFilledRectangle(Rect position, ColorRGBA color);
-    TransparentFilledRectangle(Rect position, ColorRGBA color, ColorRGBA colorLine, int width = 1);
-	void setDrawBorder(bool on);
-	bool getDrawBorder();
-	void setBorderWidth(int width);
-    void showAll(Canvas & to) override;
-};
-
-class SimpleLine : public CIntObject
-{
-	Point pos1;
-	Point pos2;
-	ColorRGBA color;
-public:
-    SimpleLine(Point pos1, Point pos2, ColorRGBA color);
-    void showAll(Canvas & to) override;
-};
-
 class SelectableSlot : public LRClickableAreaWTextComp
 {
-	std::unique_ptr<TransparentFilledRectangle> selection;
+	std::shared_ptr<TransparentFilledRectangle> selection;
+	bool selected;
 
 public:
 	SelectableSlot(Rect area, Point oversize, const int width);

+ 2 - 2
client/windows/CHeroOverview.cpp

@@ -20,7 +20,7 @@
 #include "../widgets/CComponent.h"
 #include "../widgets/Images.h"
 #include "../widgets/TextControls.h"
-#include "../widgets/MiscWidgets.h"
+#include "../widgets/GraphicalPrimitiveCanvas.h"
 
 #include "../../lib/GameSettings.h"
 #include "../../lib/CGeneralTextHandler.h"
@@ -234,4 +234,4 @@ void CHeroOverview::genControls()
         labelSpellsNames.push_back(std::make_shared<CLabel>(302 + (292 / 2) + 3 * borderOffset + 32 + borderOffset, 8 * borderOffset + yOffset + 186 + i * (32 + borderOffset) + 3, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, (*CGI->spellh)[spell]->getNameTranslated()));
         i++;
     }
-}
+}

+ 1 - 1
client/windows/CSpellWindow.cpp

@@ -25,7 +25,7 @@
 #include "../gui/CGuiHandler.h"
 #include "../gui/Shortcut.h"
 #include "../gui/WindowHandler.h"
-#include "../widgets/MiscWidgets.h"
+#include "../widgets/GraphicalPrimitiveCanvas.h"
 #include "../widgets/CComponent.h"
 #include "../widgets/TextControls.h"
 #include "../adventureMap/AdventureMapInterface.h"

+ 61 - 0
config/widgets/commonPrimitives.json

@@ -0,0 +1,61 @@
+{
+	"boxWithNoBackground" : {
+		"type": "graphicalPrimitive",
+		"primitives" : [
+			// Top line
+			{ "type" : "line", "a" : { "x" : 0, "y" : 0}, "b" : { "x" : -1, "y" : 0}, "color" : [ 255, 255, 255, 32 ] },
+			{ "type" : "line", "a" : { "x" : 0, "y" : 1}, "b" : { "x" : -1, "y" : 1}, "color" : [ 0, 0, 0, 48 ] },
+			
+			// Left line
+			{ "type" : "line", "a" : { "x" : 0, "y" : 1}, "b" : { "x" : 0, "y" : -2}, "color" : [ 255, 255, 255, 32 ] },
+			{ "type" : "line", "a" : { "x" : 1, "y" : 2}, "b" : { "x" : 1, "y" : -2}, "color" : [ 0, 0, 0, 48 ] },
+			
+			// Right line
+			{ "type" : "line", "a" : { "x" : -2, "y" : 2}, "b" : { "x" : -2, "y" : -3}, "color" : [ 255, 255, 255, 24 ] },
+			{ "type" : "line", "a" : { "x" : -1, "y" : 1}, "b" : { "x" : -1, "y" : -2}, "color" : [ 255, 255, 255, 48 ] },
+
+			// Bottom line
+			{ "type" : "line", "a" : { "x" : 1, "y" : -2}, "b" : { "x" : -1, "y" : -2}, "color" : [ 255, 255, 255, 24 ] },
+			{ "type" : "line", "a" : { "x" : 0, "y" : -1}, "b" : { "x" : -1, "y" : -1}, "color" : [ 255, 255, 255, 48 ] },
+		]
+	},
+	
+	"horizontalLine" : {
+		"type": "graphicalPrimitive",
+		"primitives" : [
+			{ "type" : "line", "a" : { "x" : 0, "y" : 0}, "b" : { "x" : -1, "y" : 0}, "color" : [ 255, 255, 255, 64 ] },
+			{ "type" : "line", "a" : { "x" : 0, "y" : 1}, "b" : { "x" : -1, "y" : 1}, "color" : [ 0, 0, 0, 64 ] }
+		]
+	},
+	
+	"verticalLine" : {
+		"type": "graphicalPrimitive",
+		"primitives" : [
+			{ "type" : "line", "a" : { "x" : 0, "y" : 0}, "b" : { "x" : 0, "y" : -1}, "color" : [ 255, 255, 255, 64 ] },
+			{ "type" : "line", "a" : { "x" : 1, "y" : 0}, "b" : { "x" : 1, "y" : -1}, "color" : [ 0, 0, 0, 64 ] }
+		]
+	},
+	
+	"boxWithBackground" : {
+		"type": "graphicalPrimitive",
+		"primitives" : [
+			{ "type" : "filledBox", "a" : { "x" : 1, "y" : 1}, "b" : { "x" : -2, "y" : -2}, "color" : [ 0, 0, 0, 75 ] },
+		
+			// Top line
+			{ "type" : "line", "a" : { "x" : 0, "y" : 0}, "b" : { "x" : -1, "y" : 0}, "color" : [ 255, 255, 255, 32 ] },
+			{ "type" : "line", "a" : { "x" : 0, "y" : 1}, "b" : { "x" : -1, "y" : 1}, "color" : [ 0, 0, 0, 48 ] },
+			
+			// Left line
+			{ "type" : "line", "a" : { "x" : 0, "y" : 1}, "b" : { "x" : 0, "y" : -2}, "color" : [ 255, 255, 255, 32 ] },
+			{ "type" : "line", "a" : { "x" : 1, "y" : 2}, "b" : { "x" : 1, "y" : -2}, "color" : [ 0, 0, 0, 48 ] },
+			
+			// Right line
+			{ "type" : "line", "a" : { "x" : -2, "y" : 2}, "b" : { "x" : -2, "y" : -3}, "color" : [ 255, 255, 255, 24 ] },
+			{ "type" : "line", "a" : { "x" : -1, "y" : 1}, "b" : { "x" : -1, "y" : -2}, "color" : [ 255, 255, 255, 48 ] },
+
+			// Bottom line
+			{ "type" : "line", "a" : { "x" : 1, "y" : -2}, "b" : { "x" : -1, "y" : -2}, "color" : [ 255, 255, 255, 24 ] },
+			{ "type" : "line", "a" : { "x" : 0, "y" : -1}, "b" : { "x" : -1, "y" : -1}, "color" : [ 255, 255, 255, 48 ] }
+		]
+	},
+}

+ 5 - 5
config/widgets/extraOptionsTab.json

@@ -37,27 +37,27 @@
 		},
 		{
 			"type": "transparentFilledRectangle",
-			"rect": {"x": 54, "y": 127, "w": 335, "h": 1},
+			"rect": {"x": 54, "y": 127, "w": 335, "h": 2},
 			"color": [24, 41, 90, 255]
 		},
 		{
 			"type": "transparentFilledRectangle",
-			"rect": {"x": 158, "y": 90, "w": 2, "h": 37},
+			"rect": {"x": 159, "y": 90, "w": 2, "h": 38},
 			"color": [24, 41, 90, 255]
 		},
 		{
 			"type": "transparentFilledRectangle",
-			"rect": {"x": 234, "y": 90, "w": 2, "h": 37},
+			"rect": {"x": 235, "y": 90, "w": 2, "h": 38},
 			"color": [24, 41, 90, 255]
 		},
 		{
 			"type": "transparentFilledRectangle",
-			"rect": {"x": 310, "y": 90, "w": 2, "h": 37},
+			"rect": {"x": 311, "y": 90, "w": 2, "h": 38},
 			"color": [24, 41, 90, 255]
 		},
 		{
 			"type": "transparentFilledRectangle",
-			"rect": {"x": 55, "y": 556, "w": 334, "h": 18},
+			"rect": {"x": 55, "y": 556, "w": 335, "h": 19},
 			"color": [24, 41, 90, 255]
 		},
 		{

+ 20 - 36
config/widgets/mapOverview.json

@@ -1,4 +1,6 @@
 {
+	"library" : "config/widgets/commonPrimitives.json",
+
 	"items":
 	[		
 		{
@@ -8,10 +10,8 @@
 			"rect": {"w": 428, "h": 379}
 		},
 		{
-			"type": "transparentFilledRectangle",
-			"rect": {"x": 5, "y": 5, "w": 418, "h": 20},
-			"color": [0, 0, 0, 75],
-			"colorLine": [128, 100, 75, 255]
+			"type": "boxWithBackground",
+			"rect": {"x": 5, "y": 5, "w": 418, "h": 20}
 		},
 		{
 			"type": "label",
@@ -22,10 +22,8 @@
 			"position": {"x": 214, "y": 15}
 		},
 		{
-			"type": "transparentFilledRectangle",
-			"rect": {"x": 5, "y": 30, "w": 418, "h": 20},
-			"color": [0, 0, 0, 75],
-			"colorLine": [128, 100, 75, 255]
+			"type": "boxWithBackground",
+			"rect": {"x": 5, "y": 30, "w": 418, "h": 20}
 		},
 		{
 			"type": "label",
@@ -37,10 +35,8 @@
 			"position": {"x": 214, "y": 40}
 		},
 		{
-			"type": "transparentFilledRectangle",
-			"rect": {"x": 5, "y": 55, "w": 418, "h": 20},
-			"color": [0, 0, 0, 75],
-			"colorLine": [128, 100, 75, 255]
+			"type": "boxWithBackground",
+			"rect": {"x": 5, "y": 55, "w": 418, "h": 20}
 		},
 		{
 			"type": "label",
@@ -51,10 +47,8 @@
 			"position": {"x": 214, "y": 65}
 		},
 		{
-			"type": "transparentFilledRectangle",
-			"rect": {"x": 29, "y": 79, "w": 171, "h": 171},
-			"color": [0, 0, 0, 255],
-			"colorLine": [128, 100, 75, 255]
+			"type": "boxWithBackground",
+			"rect": {"x": 29, "y": 79, "w": 171, "h": 171}
 		},
 		{
 			"type": "label",
@@ -70,10 +64,8 @@
 			"rect": {"x": 30, "y": 80, "w": 169, "h": 169}
 		},
 		{
-			"type": "transparentFilledRectangle",
-			"rect": {"x": 228, "y": 79, "w": 171, "h": 171},
-			"color": [0, 0, 0, 255],
-			"colorLine": [128, 100, 75, 255]
+			"type": "boxWithBackground",
+			"rect": {"x": 228, "y": 79, "w": 171, "h": 171}
 		},
 		{
 			"type": "label",
@@ -90,10 +82,8 @@
 			"rect": {"x": 229, "y": 80, "w": 169, "h": 169}
 		},
 		{
-			"type": "transparentFilledRectangle",
-			"rect": {"x": 5, "y": 254, "w": 418, "h": 20},
-			"color": [0, 0, 0, 75],
-			"colorLine": [128, 100, 75, 255]
+			"type": "boxWithBackground",
+			"rect": {"x": 5, "y": 254, "w": 418, "h": 20}
 		},
 		{
 			"type": "label",
@@ -104,10 +94,8 @@
 			"position": {"x": 214, "y": 264}
 		},
 		{
-			"type": "transparentFilledRectangle",
-			"rect": {"x": 5, "y": 279, "w": 418, "h": 20},
-			"color": [0, 0, 0, 75],
-			"colorLine": [128, 100, 75, 255]
+			"type": "boxWithBackground",
+			"rect": {"x": 5, "y": 279, "w": 418, "h": 20}
 		},
 		{
 			"type": "label",
@@ -119,10 +107,8 @@
 			"position": {"x": 214, "y": 289}
 		},
 		{
-			"type": "transparentFilledRectangle",
-			"rect": {"x": 5, "y": 304, "w": 418, "h": 20},
-			"color": [0, 0, 0, 75],
-			"colorLine": [128, 100, 75, 255]
+			"type": "boxWithBackground",
+			"rect": {"x": 5, "y": 304, "w": 418, "h": 20}
 		},
 		{
 			"type": "label",
@@ -133,10 +119,8 @@
 			"position": {"x": 214, "y": 314}
 		},
 		{
-			"type": "transparentFilledRectangle",
-			"rect": {"x": 5, "y": 329, "w": 418, "h": 45},
-			"color": [0, 0, 0, 75],
-			"colorLine": [128, 100, 75, 255]
+			"type": "boxWithBackground",
+			"rect": {"x": 5, "y": 329, "w": 418, "h": 45}
 		},
 		{
 			"type": "textBox",

+ 5 - 3
config/widgets/settings/adventureOptionsTab.json

@@ -1,12 +1,14 @@
 {
-	"library" : "config/widgets/settings/library.json",
+	"library" : [
+		"config/widgets/settings/library.json",
+		"config/widgets/commonPrimitives.json",
+	],
 
 	"items":
 	[
 		{
 			"name": "lineLabelsEnd",
-			"type": "texture",
-			"image": "settingsWindow/lineHorizontal",
+			"type": "horizontalLine",
 			"rect": { "x" : 5, "y" : 229, "w": 365, "h": 3}
 		},
 /////////////////////////////////////// Left section - Hero Speed and Map Scrolling

+ 6 - 5
config/widgets/settings/battleOptionsTab.json

@@ -1,18 +1,19 @@
 {
-	"library" : "config/widgets/settings/library.json",
+	"library" : [
+		"config/widgets/settings/library.json",
+		"config/widgets/commonPrimitives.json",
+	],
 
 	"items":
 	[
 		{
 			"name": "lineCreatureInfo",
-			"type": "texture",
-			"image": "settingsWindow/lineHorizontal",
+			"type": "horizontalLine",
 			"rect": { "x" : 5, "y" : 289, "w": 365, "h": 3}
 		},
 		{
 			"name": "lineAnimationSpeed",
-			"type": "texture",
-			"image": "settingsWindow/lineHorizontal",
+			"type": "horizontalLine",
 			"rect": { "x" : 5, "y" : 349, "w": 365, "h": 3}
 		},
 		{

+ 5 - 3
config/widgets/settings/generalOptionsTab.json

@@ -1,12 +1,14 @@
 {
-	"library" : "config/widgets/settings/library.json",
+	"library" : [
+		"config/widgets/settings/library.json",
+		"config/widgets/commonPrimitives.json",
+	],
 
 	"items":
 	[
 		{
 			"name": "lineLabelsEnd",
-			"type": "texture",
-			"image": "settingsWindow/lineHorizontal",
+			"type": "horizontalLine",
 			"rect": { "x" : 5, "y" : 349, "w": 365, "h": 3}
 		},
 		{

+ 3 - 2
config/widgets/settings/library.json

@@ -35,8 +35,9 @@
 		]
 	},
 	"checkboxFake" : {
-		"type": "picture",
-		"image": "settingsWindow/checkBoxEmpty"
+		"type": "boxWithBackground",
+		"rect": { "x" : 0, "y" : 0, "w": 32, "h": 24}
+		
 	},
 	"audioSlider" : {
 		"type": "slider",

+ 7 - 6
config/widgets/settings/settingsMainContainer.json

@@ -1,4 +1,8 @@
 {
+	"library" : [
+		"config/widgets/commonPrimitives.json"
+	],
+	
 	"items":
 	[
 		{
@@ -9,14 +13,12 @@
 		},
 		{
 			"name": "lineTabs",
-			"type": "texture",
-			"image": "settingsWindow/lineHorizontal",
+			"type": "horizontalLine",
 			"rect": { "x" : 10, "y" : 45, "w": 580, "h": 3}
 		},
 		{
 			"name": "lineColumns",
-			"type": "texture",
-			"image": "settingsWindow/lineVertical",
+			"type": "verticalLine",
 			"rect": { "x" : 370, "y" : 50, "w": 3, "h": 420}
 		},
 
@@ -91,8 +93,7 @@
 
 		{
 			"name": "lineButtons",
-			"type": "texture",
-			"image": "settingsWindow/lineHorizontal",
+			"type": "horizontalLine",
 			"rect": { "x" : 375, "y" : 289, "w": 220, "h": 3}
 		},
 		{

+ 15 - 38
config/widgets/turnOptionsTab.json

@@ -1,5 +1,8 @@
 {
-	"library" : "config/widgets/turnOptionsDropdownLibrary.json",
+	"library" : [
+		"config/widgets/turnOptionsDropdownLibrary.json",
+		"config/widgets/commonPrimitives.json",
+	],
 
 	"customTypes" : {
 		"verticalLayout66" : {
@@ -30,10 +33,8 @@
 			"offset": {"x": 0, "y": 0}
 		},
 		"timeInputBackground" : {
-			"type": "transparentFilledRectangle",
-			"rect": {"x": 0, "y": 0, "w": 86, "h": 23},
-			"color": [0, 0, 0, 128],
-			"colorLine": [64, 80, 128, 128]
+			"type": "boxWithBackground",
+			"rect": {"x": 0, "y": 0, "w": 86, "h": 23}
 		}
 	},
 	
@@ -66,15 +67,7 @@
 			"rect": {"x": 60, "y": 48, "w": 320, "h": 0},
 			"adoptHeight": true
 		},
-		
-//		{
-//			"type": "label",
-//			"font": "medium",
-//			"alignment": "center",
-//			"color": "yellow",
-//			"text": "vcmi.optionsTab.selectPreset",
-//			"position": {"x": 105, "y": 100}
-//		},
+	
 		{
 			"type" : "dropDownTimers",
 			"name": "timerPresetSelector",
@@ -94,36 +87,20 @@
 			"color" : "blue", 
 			"rect": {"x" : 64, "y" : 394, "w": 316, "h": 124}
 		},
+		
 		{
-			"type": "transparentFilledRectangle",
-			"rect": {"x" : 64, "y" : 394, "w": 316, "h": 124},
-			"color": [0, 0, 0, 0],
-			"colorLine": [64, 80, 128, 128]
-		},
-		{
-			"type": "transparentFilledRectangle",
-			"rect": {"x" : 65, "y" : 416, "w": 314, "h": 1},
-			"color": [0, 0, 0, 0],
-			"colorLine": [80, 96, 160, 128]
-		},
-		{
-			"type": "transparentFilledRectangle",
-			"rect": {"x" : 65, "y" : 417, "w": 314, "h": 1},
-			"color": [0, 0, 0, 0],
-			"colorLine": [32, 40, 128, 128]
+			"type": "boxWithNoBackground",
+			"rect": {"x" : 64, "y" : 394, "w": 316, "h": 124}
 		},
 		{
-			"type": "transparentFilledRectangle",
-			"rect": {"x" : 65, "y" : 466, "w": 314, "h": 1},
-			"color": [0, 0, 0, 0],
-			"colorLine": [80, 96, 160, 128]
+			"type": "horizontalLine",
+			"rect": {"x" : 65, "y" : 416, "w": 314, "h": 2}
 		},
 		{
-			"type": "transparentFilledRectangle",
-			"rect": {"x" : 65, "y" : 467, "w": 314, "h": 1},
-			"color": [0, 0, 0, 0],
-			"colorLine": [32, 40, 128, 128]
+			"type": "horizontalLine",
+			"rect": {"x" : 65, "y" : 466, "w": 314, "h": 2}
 		},
+
 		{
 			"type" : "verticalLayout66",
 			"customType" : "labelTitle",