浏览代码

Radial menu is now a proper window. Minor fixes to positioning.

Ivan Savenko 2 年之前
父节点
当前提交
d26595cef7

二进制
Mods/vcmi/Data/radialMenu/stackEmpty.png


+ 6 - 0
client/gui/EventDispatcher.cpp

@@ -271,6 +271,12 @@ void EventDispatcher::dispatchGesturePanning(const Point & initialPosition, cons
 
 	for(auto it : copied)
 	{
+		if (!it->isGesturing() && it->receiveEvent(initialPosition, AEventsReceiver::GESTURE))
+		{
+			it->gesture(true, initialPosition, initialPosition);
+			it->panningState = true;
+		}
+
 		if (it->isGesturing())
 			it->gesturePanning(initialPosition, currentPosition, lastUpdateDistance);
 	}

+ 1 - 28
client/widgets/CGarrisonInt.cpp

@@ -345,37 +345,10 @@ void CGarrisonSlot::clickPressed(const Point & cursorPosition)
 		}
 }
 
-void CGarrisonSlot::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance)
-{
-	assert(radialMenu);
-
-	if (radialMenu)
-		radialMenu->gesturePanning(initialPosition, currentPosition, lastUpdateDistance);
-}
-
 void CGarrisonSlot::gesture(bool on, const Point & initialPosition, const Point & finalPosition)
 {
 	if (on)
-	{
-		OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
-
-		radialMenu = std::make_shared<RadialMenu>(owner, this);
-		radialMenu->center(pos.center());
-
-		auto topParent = parent;
-		while (topParent->parent)
-			topParent = topParent->parent;
-
-		// Add radial menu to current window / topmost parent for proper rendering order
-		topParent->addChild(radialMenu.get(), false);
-	}
-	else
-	{
-		radialMenu->gesture(on, initialPosition, finalPosition);
-		radialMenu.reset();
-	}
-
-	GH.windows().totalRedraw();
+		GH.windows().createAndPushWindow<RadialMenu>(pos.center(), owner, this);
 }
 
 void CGarrisonSlot::update()

+ 0 - 3
client/widgets/CGarrisonInt.h

@@ -22,7 +22,6 @@ class CGarrisonInt;
 class CButton;
 class CAnimImage;
 class CLabel;
-class RadialMenu;
 
 enum class EGarrisonType
 {
@@ -42,7 +41,6 @@ class CGarrisonSlot : public CIntObject
 	std::shared_ptr<CAnimImage> creatureImage;
 	std::shared_ptr<CAnimImage> selectionImage; // image for selection, not always visible
 	std::shared_ptr<CLabel> stackCount;
-	std::shared_ptr<RadialMenu> radialMenu;
 
 public:
 	bool viewInfo();
@@ -70,7 +68,6 @@ public:
 	void showPopupWindow(const Point & cursorPosition) override;
 	void clickPressed(const Point & cursorPosition) override;
 	void hover (bool on) override; //call-in
-	void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override;
 	void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override;
 
 	void update();

+ 22 - 5
client/widgets/RadialMenu.cpp

@@ -11,18 +11,20 @@
 #include "RadialMenu.h"
 
 #include "Images.h"
+#include "TextControls.h"
 
 #include "../gui/CGuiHandler.h"
+#include "../gui/WindowHandler.h"
 #include "../render/IImage.h"
 #include "CGarrisonInt.h"
 
-RadialMenuItem::RadialMenuItem(std::string imageName, std::function<void()> callback)
+RadialMenuItem::RadialMenuItem(const std::string & imageName, const std::function<void()> & callback)
 	: callback(callback)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
 
 	image = IImage::createFromFile("radialMenu/" + imageName);
-	picture = std::make_shared<CPicture>(image, Point(0,0));
+	picture = std::make_shared<CPicture>(image, Point(0, 0));
 	pos = picture->pos;
 }
 
@@ -43,12 +45,18 @@ void RadialMenuItem::gesture(bool on, const Point & initialPosition, const Point
 
 }
 
-RadialMenu::RadialMenu(CGarrisonInt * army, CGarrisonSlot * slot)
+RadialMenu::RadialMenu(const Point & positionToCenter, CGarrisonInt * army, CGarrisonSlot * slot)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
+	pos += positionToCenter;
 
 	bool isExchange = army->upperArmy() && army->lowerArmy(); // two armies exist
 
+	addItem(Point(0,0), "stackEmpty", [](){});
+
+	Point itemSize = items.back()->pos.dimensions();
+	moveBy(-itemSize / 2);
+
 	addItem(ITEM_NW, "stackMerge", [=](){army->bulkMergeStacks(slot);});
 	addItem(ITEM_NE, "stackInfo", [=](){slot->viewInfo();});
 
@@ -61,12 +69,18 @@ RadialMenu::RadialMenu(CGarrisonInt * army, CGarrisonSlot * slot)
 		//FIXME: addItem(ITEM_SE, "stackSplitDialog", [=](){slot->split();});
 	}
 
+	//statusBarBackground = std::make_shared<CFilledTexture>("DiBoxBck", Rect(-itemSize.x * 2, -100, itemSize.x * 4, 20));
+	//statusBar = CGStatusBar::create(statusBarBackground);
+
 	for(const auto & item : items)
 		pos = pos.include(item->pos);
 
+	fitToScreen(10);
+
+	addUsedEvents(GESTURE);
 }
 
-void RadialMenu::addItem(const Point & offset, const std::string & path, std::function<void()> callback )
+void RadialMenu::addItem(const Point & offset, const std::string & path, const std::function<void()>& callback )
 {
 	auto item = std::make_shared<RadialMenuItem>(path, callback);
 
@@ -89,12 +103,15 @@ void RadialMenu::gesture(bool on, const Point & initialPosition, const Point & f
 {
 	if (!on)
 	{
+		// we need to close this window first so if action spawns a new window it won't be closed instead
+		GH.windows().popWindows(1);
+
 		for(const auto & item : items)
 		{
 			if (item->isInside(finalPosition))
 			{
 				item->callback();
-				return;
+				break;
 			}
 		}
 	}

+ 15 - 9
client/widgets/RadialMenu.h

@@ -15,6 +15,9 @@ class IImage;
 
 class CGarrisonInt;
 class CGarrisonSlot;
+class CFilledTexture;
+class CGStatusBar;
+
 
 class RadialMenuItem : public CIntObject
 {
@@ -23,7 +26,7 @@ class RadialMenuItem : public CIntObject
 public:
 	std::function<void()> callback;
 
-	RadialMenuItem(std::string imageName, std::function<void()> callback);
+	RadialMenuItem(const std::string& imageName, const std::function<void()>& callback);
 
 	bool isInside(const Point & position);
 
@@ -33,18 +36,21 @@ public:
 
 class RadialMenu : public CIntObject
 {
-	static constexpr Point ITEM_NW = Point( -35, -85);
-	static constexpr Point ITEM_NE = Point( +35, -85);
-	static constexpr Point ITEM_WW = Point( -85, 0);
-	static constexpr Point ITEM_EE = Point( +85, 0);
-	static constexpr Point ITEM_SW = Point( -35, +85);
-	static constexpr Point ITEM_SE = Point( +35, +85);
+	static constexpr Point ITEM_NW = Point( -40, -70);
+	static constexpr Point ITEM_NE = Point( +40, -70);
+	static constexpr Point ITEM_WW = Point( -80, 0);
+	static constexpr Point ITEM_EE = Point( +80, 0);
+	static constexpr Point ITEM_SW = Point( -40, +70);
+	static constexpr Point ITEM_SE = Point( +40, +70);
 
 	std::vector<std::shared_ptr<RadialMenuItem>> items;
 
-	void addItem(const Point & offset, const std::string & path, std::function<void()> callback );
+	std::shared_ptr<CFilledTexture> statusBarBackground;
+	std::shared_ptr<CGStatusBar> statusBar;
+
+	void addItem(const Point & offset, const std::string & path, const std::function<void()>& callback );
 public:
-	RadialMenu(CGarrisonInt * army, CGarrisonSlot * slot);
+	RadialMenu(const Point & positionToCenter, CGarrisonInt * army, CGarrisonSlot * slot);
 
 	void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override;
 	void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override;

+ 5 - 0
lib/Point.h

@@ -67,6 +67,11 @@ public:
 		return *this;
 	}
 
+	constexpr Point operator-() const
+	{
+		return Point(-x, -y);
+	}
+
 	template<typename T>
 	constexpr Point operator-(const T &b) const
 	{