Parcourir la source

quickspell draft

Laserlicht il y a 1 an
Parent
commit
1f6e0fae7d

+ 49 - 0
client/battle/BattleInterfaceClasses.cpp

@@ -417,6 +417,55 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her
 	addUsedEvents(TIME);
 }
 
+QuickSpellPanel::QuickSpellPanel()
+	: CIntObject(LCLICK | SHOW_POPUP)
+{
+	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
+
+	setEnabled(false);
+
+	pos = Rect(0, 0, 52, 372);
+	background = std::make_shared<CFilledTexture>(ImagePath::builtin("DIBOXBCK"), pos);
+	rect = std::make_shared<TransparentFilledRectangle>(Rect(0, 0, pos.w + 1, pos.h + 1), ColorRGBA(0, 0, 0, 0), ColorRGBA(241, 216, 120, 255));
+
+	for(int i = 0; i < 10; i++) {
+		SpellID id = 14;
+		auto button = std::make_shared<CButton>(Point(2, 1 + 37 * i), AnimationPath::builtin("spellint"), CButton::tooltip(), [&](){ std::cout << "test"; }, EShortcut::HERO_COSTUME_0);
+		button->setOverlay(std::make_shared<CAnimImage>(AnimationPath::builtin("spellint"), i > 0 ? id.num : 0));
+
+		if(i > 3)
+		{
+			button->block(true);
+			buttonsDisabled.push_back(std::make_shared<TransparentFilledRectangle>(Rect(2, 1 + 37 * i, 48, 36), ColorRGBA(0, 0, 0, 128)));
+		}
+
+		buttons.push_back(button);
+	}
+}
+
+void QuickSpellPanel::show(Canvas & to)
+{
+	showAll(to);
+	CIntObject::show(to);
+}
+
+void QuickSpellPanel::clickReleased(const Point & cursorPosition)
+{
+	if(!pos.isInside(cursorPosition))
+		setEnabled(false);
+}
+
+void QuickSpellPanel::showPopupWindow(const Point & cursorPosition)
+{
+	if(!pos.isInside(cursorPosition))
+		setEnabled(false);
+}
+
+bool QuickSpellPanel::receiveEvent(const Point & position, int eventType) const
+{
+	return true;  // capture click also outside of window
+}
+
 HeroInfoBasicPanel::HeroInfoBasicPanel(const InfoAboutHero & hero, Point * position, bool initializeBackground)
 	: CIntObject(0)
 {

+ 17 - 0
client/battle/BattleInterfaceClasses.h

@@ -147,6 +147,23 @@ public:
 	BattleHero(const BattleInterface & owner, const CGHeroInstance * hero, bool defender);
 };
 
+class QuickSpellPanel : public CIntObject
+{
+private:
+	std::shared_ptr<CFilledTexture> background;
+	std::shared_ptr<TransparentFilledRectangle> rect;
+	std::vector<std::shared_ptr<CButton>> buttons;
+	std::vector<std::shared_ptr<TransparentFilledRectangle>> buttonsDisabled;
+
+	bool receiveEvent(const Point & position, int eventType) const override;
+	void clickReleased(const Point & cursorPosition) override;
+	void showPopupWindow(const Point & cursorPosition) override;
+public:
+	QuickSpellPanel();
+
+	void show(Canvas & to) override;
+};
+
 class HeroInfoBasicPanel : public CIntObject //extracted from InfoWindow to fit better as non-popup embed element
 {
 private:

+ 24 - 0
client/battle/BattleWindow.cpp

@@ -98,6 +98,30 @@ BattleWindow::BattleWindow(BattleInterface & owner):
 	createStickyHeroInfoWindows();
 	createTimerInfoWindows();
 
+	auto w = widget<CButton>("cast");
+	if(w)
+	{
+		auto hero = owner.getBattle()->battleGetMyHero();
+		if(GH.screenDimensions().x >= 1000 && hero && owner.getBattle()->battleCanCastSpell(hero, spells::Mode::HERO) != ESpellCastProblem::NO_SPELLBOOK && settings["general"]["enableUiEnhancements"].Bool())
+		{
+			quickSpellPanelWindow = std::make_shared<QuickSpellPanel>();
+			quickSpellPanelWindow->moveTo(Point(w->pos.x - 2, w->pos.y - 378));
+			w->addHoverCallback([this, w](bool on)
+			{
+				if(on)
+					quickSpellPanelWindow->setEnabled(true);
+				else
+					if(GH.getCursorPosition().x <= w->pos.x || GH.getCursorPosition().x >= w->pos.x + w->pos.w || GH.getCursorPosition().y >= w->pos.y + w->pos.h)
+						quickSpellPanelWindow->setEnabled(false);
+			});
+			w->addPanningCallback([this](const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance)
+			{
+				if((currentPosition - initialPosition).y < -20)
+					quickSpellPanelWindow->setEnabled(true);
+			});
+		}
+	}
+
 	if ( owner.tacticsMode )
 		tacticPhaseStarted();
 	else

+ 2 - 0
client/battle/BattleWindow.h

@@ -27,6 +27,7 @@ class StackQueue;
 class TurnTimerWidget;
 class HeroInfoBasicPanel;
 class StackInfoBasicPanel;
+class QuickSpellPanel;
 
 /// GUI object that handles functionality of panel at the bottom of combat screen
 class BattleWindow : public InterfaceObjectConfigurable
@@ -39,6 +40,7 @@ class BattleWindow : public InterfaceObjectConfigurable
 	std::shared_ptr<HeroInfoBasicPanel> defenderHeroWindow;
 	std::shared_ptr<StackInfoBasicPanel> attackerStackWindow;
 	std::shared_ptr<StackInfoBasicPanel> defenderStackWindow;
+	std::shared_ptr<QuickSpellPanel> quickSpellPanelWindow;
 
 	std::shared_ptr<TurnTimerWidget> attackerTimerWidget;
 	std::shared_ptr<TurnTimerWidget> defenderTimerWidget;

+ 18 - 1
client/widgets/Buttons.cpp

@@ -67,6 +67,16 @@ void CButton::addCallback(const std::function<void()> & callback)
 	this->callback += callback;
 }
 
+void CButton::addHoverCallback(const std::function<void(bool)> & callback)
+{
+	this->hoverCallback += callback;
+}
+
+void CButton::addPanningCallback(const std::function<void(const Point &, const Point &, const Point &)> & callback)
+{
+	this->panningCallback += callback;
+}
+
 void ButtonBase::setTextOverlay(const std::string & Text, EFonts font, ColorRGBA color)
 {
 	OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
@@ -295,6 +305,8 @@ void CButton::showPopupWindow(const Point & cursorPosition)
 
 void CButton::hover (bool on)
 {
+	hoverCallback(on);
+
 	if(hoverable && !isBlocked())
 	{
 		if(on)
@@ -319,6 +331,11 @@ void CButton::hover (bool on)
 	}
 }
 
+void CButton::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance)
+{
+	panningCallback(initialPosition, currentPosition, lastUpdateDistance);
+}
+
 ButtonBase::ButtonBase(Point position, const AnimationPath & defName, EShortcut key, bool playerColoredButton)
 	: CKeyShortcut(key)
 	, stateToIndex({0, 1, 2, 3})
@@ -351,7 +368,7 @@ CButton::CButton(Point position, const AnimationPath &defName, const std::pair<s
 	soundDisabled(false)
 {
 	defActions = 255-DISPOSE;
-	addUsedEvents(LCLICK | SHOW_POPUP | HOVER | KEYBOARD);
+	addUsedEvents(LCLICK | SHOW_POPUP | HOVER | KEYBOARD | GESTURE);
 	hoverTexts[0] = help.first;
 }
 

+ 5 - 0
client/widgets/Buttons.h

@@ -69,6 +69,8 @@ public:
 class CButton : public ButtonBase
 {
 	CFunctionList<void()> callback;
+	CFunctionList<void(bool)> hoverCallback;
+	CFunctionList<void(const Point &, const Point &, const Point &)> panningCallback;
 
 	std::array<std::string, 4> hoverTexts; //texts for statusbar, if empty - first entry will be used
 	std::optional<ColorRGBA> borderColor; // mapping of button state to border color
@@ -90,6 +92,8 @@ public:
 
 	/// adds one more callback to on-click actions
 	void addCallback(const std::function<void()> & callback);
+	void addHoverCallback(const std::function<void(bool)> & callback);
+	void addPanningCallback(const std::function<void(const Point &, const Point &, const Point &)> & callback);
 
 	void addHoverText(EButtonState state, const std::string & text);
 
@@ -114,6 +118,7 @@ public:
 	void clickReleased(const Point & cursorPosition) override;
 	void clickCancel(const Point & cursorPosition) override;
 	void hover (bool on) override;
+	void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override;
 	void showAll(Canvas & to) override;
 
 	/// generates tooltip that can be passed into constructor