From dca3785f848cbc2ff0f1f7cd500acd68fa3770c9 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Thu, 6 Jul 2023 01:20:44 +0300 Subject: [PATCH 01/16] Initial version of radial wheel for army management --- Mods/vcmi/Data/radialMenu/stackInfo.png | Bin 0 -> 1047 bytes Mods/vcmi/Data/radialMenu/stackMerge.png | Bin 0 -> 1032 bytes Mods/vcmi/Data/radialMenu/stackMove.png | Bin 0 -> 824 bytes .../vcmi/Data/radialMenu/stackSplitDialog.png | Bin 0 -> 831 bytes Mods/vcmi/Data/radialMenu/stackSplitEqual.png | Bin 0 -> 962 bytes Mods/vcmi/Data/radialMenu/stackSplitOne.png | Bin 0 -> 942 bytes Mods/vcmi/Data/radialMenu/stackSwap.png | Bin 0 -> 832 bytes client/widgets/CGarrisonInt.cpp | 159 +++++++++++++++--- client/widgets/CGarrisonInt.h | 55 +++++- 9 files changed, 185 insertions(+), 29 deletions(-) create mode 100644 Mods/vcmi/Data/radialMenu/stackInfo.png create mode 100644 Mods/vcmi/Data/radialMenu/stackMerge.png create mode 100644 Mods/vcmi/Data/radialMenu/stackMove.png create mode 100644 Mods/vcmi/Data/radialMenu/stackSplitDialog.png create mode 100644 Mods/vcmi/Data/radialMenu/stackSplitEqual.png create mode 100644 Mods/vcmi/Data/radialMenu/stackSplitOne.png create mode 100644 Mods/vcmi/Data/radialMenu/stackSwap.png diff --git a/Mods/vcmi/Data/radialMenu/stackInfo.png b/Mods/vcmi/Data/radialMenu/stackInfo.png new file mode 100644 index 0000000000000000000000000000000000000000..a19929fa2b6f4d1abb13677152d71158ed476798 GIT binary patch literal 1047 zcmeAS@N?(olHy`uVBq!ia0vp^u0ZV1!3-q3PW-54U|`G$@CgA4Lcss~*)S%ZXe~v7 z1wD?}_e6cTl=Ay_=AXM+U$3Pvrab zSsusN2JKzqD<;PF?_Tz`-4Sc1xh?8(I=I6B=go{zPlYKB*57ZWPj0aKcQ0#3i*0V4 z#>z=96KXA=pGw#=$LrJ8)H?^FuI-9EyxKp)N8!xo&_gTz^wnfI-(O5w zI>G7n*`!k&gMQr1a4;3Ryd&J&MD)te@L6rP_YTFJ+Y)oI~G4Op?pSO+j5y^KHa)1_mZmPZ!6K z3dXlLT7y1&F}Q!^W&dY!aPFf5-tzMH?D@NQ|9-qU@zvcEJjs7;53E#Kee9U#f(wR% zqKyk~xCAm;F)vlqS%X1z=7pTfSGo$;8KyV4MoNEM{%)J{{}&xId8`~A9l~z~zh`4*wN(q$ z*Wg*v^Ix%6L+97t<#r5Q{A{wxNeeO_m^Uv{jz1axY3l0LfBqexU(d_i-_zIYzQV`n zk>spTu`}n*30!p3^3k)up<)aPfzzj{H9nnsb?aB&gpA8^H!rcx%dISHxNAH2mOK;R znyH?AN0%zc{`fur?ZW!fclHnJvsrhDo!2;9`k-y?CWeB~V)Jf$6+YK1I3Fg-=CJ%7 zGmqv`<_8azqg`*Y$#w5O^kp;|V(`ib+q7>=A44AP$8u-*U3_M#>08(8j7d0@RkE+K6P_X1YI zs=9-pAFD}4^+f#CnBX?$f%*rNfTz>9IR>?y+VF)>Da6M4c~hv;iEy2%_Z==eoRLU3 z2x4bDv-4A(h*)jjEkPTN7p9$6P9+O&FDcl~RJP!9iok1!e;41)IqJx7 zb=8)CN=tE`oSY-&xYObA)H{_GcdW9e3Yw}lWCd6i^tOIo>HIYG{=}nG)$d-nR9h3I pXBCjNNQ2FBV&@6XB?o>b`!R%N&7Q7)F6*2UngGj_pw0jQ literal 0 HcmV?d00001 diff --git a/Mods/vcmi/Data/radialMenu/stackMerge.png b/Mods/vcmi/Data/radialMenu/stackMerge.png new file mode 100644 index 0000000000000000000000000000000000000000..a0c611a0ba1a596f6b573b05c1747a4ddec81fb7 GIT binary patch literal 1032 zcmeAS@N?(olHy`uVBq!ia0vp^u0ZV1!3-q3PW-3^Qhx$`LO_BL@c(``j7dYHoQ#_4;hm z@7tM|cZ9#cm~!t>%(*S0501osy_Wv*a;lOHM{|*}t%*o`sp-ozi3@ui-EAe>N=*A} zE%z+(O^#B(wmb6w^Zai&GYmBOZtsu&|El1~>VUP=-5UP$iURF3ED7=pW?(e^Z!G#> znuXh$S%p`aiOt}jkpwHBgR7FNKwvnBzKNJ5m(BnG|J@Y+|5pdnf*0zA4lpn?z=S@y%Z2^KazR($b8KJ6`_ZpX#_U>Qt6SW~KjuhWMDxb0>wK-1pcg z&De^&$#V8ln-}UE5-y(-3q0^>l5eWy7w(8{CE5$_H-&mnZnm*V=RCJ~1$WGuwadI0 zC>5N1wSz~CIed**nP}+4sH5qBtyW0g*^p$eEq!(V*FR#b`fr!(Jkrx(y;D5@>+c02 z9}d*LRm_mukmUGJ!$i)$a#c{?vCSvb|5|3eVNKQ#J#_X#Xj)nNrHZxYK6^qpp5VDB zDOG)_TCiq9xS4WDL%$M`=AJ6fFyGGjqiftrosfM(x9&4sdouNmlWP_Cnr`0Kh0oL1 zDdj3TL?76e^yf_Ijfq?MZn1t7d7A#OnB`%<#;NmvZZmbfl|7|Z_e@KE3%^If0;f7L zt%Gb0aU4f?&RlI!_=9up-YMZm#Z#3Vw6rZG0ahXIgOI z_TFyxt?Q;Tyo)+A_x6jpS#X1+sg2Z^UQ6XXAT9|(x%LP f*lsBJg@?g2WWv&CEepQ_lQe^;tDnm{r-UW|q)F5VQ~TGBkvu{`8Da}{sZ;#ne39u$XsU`_pXYP*ToFTN`Nntr3Y zhEERhA4`7+3bJvnv*XZWbGGb#_{i^A)bO%sd79(bgE2xEnM|2KH_m#TzBDE^vCy-!=E>C5cWX}k)Y!dgmFbS{de0ZH zIi)21=;E>`HBUqnURNqUS6;8fob&#`-dIcd$kg{M_wg4fJXc=r@%q3*i=cD>M@v=o)EObwpiz!DA=IW{x znTg>$j(;_?ikNs(vht~$!rYTjde#)JE}d{vGBVYF7sG_j6T|1p-kJD$Vz|_=$VU5R zOiQ&yes}NlX8f@|?pJ!M+!dZJN|ScF$k14{0m Lu6{1-oD!M%XOq z`cEY-RGz2PbgFr&$|Am1Y}1%S-S?e3f9lk$S^H9z*RT1U;;feXWU6oO$E4_G4^L>X ze$x@Yd(!8L;SGDgx6bL`vx#p*{ef<0OZmvBFV@!a6evAcUhQ%Fz)FkDx3By>VgIt2 zlY9nHs*mfu+32?$fEs#tdt@ zO`j;Q{_vz2CeOKVLkbxFm=5 zio}z3DSws~ho1O0-FEt$?@#al@O+(~DjC9iMS0RvFWHD5by@BeI?uApIO9al9ChEU zYGsgoz4|h%wSnlvSCcjD)v_)|m}|&O^p_+r$T5(*|4PC!Qo>K^bilF8jR);N&TC)! z_44wz7rjhX4t!aGJ@v0He4Tz**;sb|yX&ffVbU+kFGz)MX;@&XmdKI;Vst07?==Bme*a literal 0 HcmV?d00001 diff --git a/Mods/vcmi/Data/radialMenu/stackSplitEqual.png b/Mods/vcmi/Data/radialMenu/stackSplitEqual.png new file mode 100644 index 0000000000000000000000000000000000000000..d0d376bce088abdbafb8223caf2ebf012a572a89 GIT binary patch literal 962 zcmeAS@N?(olHy`uVBq!ia0vp^u0ZV1!3-q3PW-3^Qda|fLO_BL@c(``j7cZjNQ?jN z`Q)p+B95;O+PlPeN`v*!n;GA4q)(`|e10k+!bc%KNIB3=wkk{i&)uxoXOn*4&b+)M z{Qbq0dxv7qZ3%sFB=+mI^pBTQm1H=Yi;QheMA}PDU!F-^*yFf;%}fiRCp1ff{DK)6 zP5&E#h=ab)X%*XcVojf<;i-v8grwx}Xwu5^F0@Ac;|wr@{)8}M@V&sJk! z$(xZ3=X#CKIXf|Vb4#B!IvL^_5f{l5*;?Yov^upS+jw!XP=tKOmI->7SjF2E#68!j zOy6x`gdIXd?nwhYU+WtmdA3X!>Z<0RkxRT z2Hu%_WkU4?Mz06^=KW%p4trwrr~TuJwy72o+OcnwAFa9a=;WJ~_N_W=Smv27^-1}n zRWwh0Qe#(g%cn)e&w?H-uFd0SMqeL+0u9i8InosR1deO>mYl=qod!Pojf z=bg7s-x(6VBZ94jaSh8Yqcx@f^^e~2|K0Di_Rr)0yO!zP67mtXh(A`s*RVM?<*a0# dw6NoO28Qa0*<1c8eeVHfJWp3Ymvv4FO#nFBf%pIb literal 0 HcmV?d00001 diff --git a/Mods/vcmi/Data/radialMenu/stackSplitOne.png b/Mods/vcmi/Data/radialMenu/stackSplitOne.png new file mode 100644 index 0000000000000000000000000000000000000000..28e15c7472540c4f60b6b24ab2b0f84f74dfbb7c GIT binary patch literal 942 zcmeAS@N?(olHy`uVBq!ia0vp^u0ZV1!3-q3PW-3^Qda|fLO_BL@c(``j7bmLNQ?jN z`Q)p+B7l}1UmLV{iSLvK>z_9>zTZfnP;2@8R6>N0LVS>Npqp$}mj0i+S+CC~{l1-f zc}MvBiz)XG#hlv``rt_H*K6q?FQ+QWa5NVg+nR{9mzusjlenYzF^~Bv|0>e4!MrVE6MY# zB_@e8?CD9YU=M~`NYLl{X8ij6hE)1XGzs<@;97uULjRyr~BTotSgU9 zdXTOE>jQ7dVWl7UxE`~6NOm*ZKUUm7NjbkT;nBH^zj{M53V#@jb!rAAcPH%Xda*M( ztxPZ3Fv0FkzLVOmhr-gNfr(be2t5jiS?A5F1`DfWIy-mW-L!18 zN<;Bxo>jMXJ8KzqIqpteyZiNb??*|@Z|}uFuDSbHXFAi%8@kP}-=*)o#Px#lCs2#- z+@?sQ(%GsTXB&90dv_rE)7qw8%=ss`bG_o*qk3O!h4qJNHLDlEBr3i4alhhwqWe=1 zB=I3Op!~wuX*J?kWKTqY0&*SzC2H;hMW#mrHK&T@pDdqw6eyGS5kn~BMqH^rtg&T+7Ppf5JpWhh&al-t7+f4R{GHTnS#D0j?zNlT=)~dhu#d#Hx zs0YP7&xA!H9wh&nx{*Icch7pI&oKg*E-cqgzG!V@1ZSHC^ ztiC7BD$1xVxX!HSQ?f?yuPDc#2NF!o7*4VMy?Euk-IUgQDx1DE%xZjR|9)<}xAn__ z*e&jixeDx=B9Ft{r|o|wJM;I?ceSxXskQ8PoAU#Yh6~hmc1=28 callback) + : callback(callback) +{ + OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; + + image = IImage::createFromFile("radialMenu/" + imageName); + picture = std::make_shared(image, Point(0,0)); + pos = picture->pos; +} + +bool RadialMenuItem::isInside(const Point & position) +{ + Point localPosition = position - pos.topLeft(); + + return !image->isTransparent(localPosition); +} + +void RadialMenuItem::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) +{ + +} + +void RadialMenuItem::gesture(bool on, const Point & initialPosition, const Point & finalPosition) +{ + +} + +RadialMenu::RadialMenu(CGarrisonInt * army, CGarrisonSlot * slot) +{ + OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; + + bool isExchange = army->armedObjs[0] && army->armedObjs[1]; // two armies exist + + addItem(ITEM_NW, "stackMerge", [=](){army->bulkMergeStacks(slot);}); + addItem(ITEM_NE, "stackInfo", [=](){slot->viewInfo();}); + + addItem(ITEM_WW, "stackSplitOne", [=](){slot->splitIntoParts(slot->upg, 1); }); + addItem(ITEM_EE, "stackSplitEqual", [=](){army->bulkSmartSplitStack(slot);}); + + if (isExchange) + { + addItem(ITEM_SW, "stackMove", [=](){army->moveStackToAnotherArmy(slot);}); + //FIXME: addItem(ITEM_SE, "stackSplitDialog", [=](){slot->split();}); + } + + for(const auto & item : items) + pos = pos.include(item->pos); + +} + +void RadialMenu::addItem(const Point & offset, const std::string & path, std::function callback ) +{ + auto item = std::make_shared(path, callback); + + item->moveBy(offset); + + items.push_back(item); +} + +void RadialMenu::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) +{ + +} + +void RadialMenu::show(Canvas & to) +{ + showAll(to); +} + +void RadialMenu::gesture(bool on, const Point & initialPosition, const Point & finalPosition) +{ + if (!on) + { + for(const auto & item : items) + { + if (item->isInside(finalPosition)) + { + item->callback(); + return; + } + } + } +} + void CGarrisonSlot::setHighlight(bool on) { if (on) @@ -227,8 +312,6 @@ bool CGarrisonSlot::highlightOrDropArtifact() bool CGarrisonSlot::split() { const CGarrisonSlot * selection = owner->getSelection(); - owner->p2 = ID; // store the second stack pos - owner->pb = upg; // store the second stack owner (up or down army) owner->setSplittingMode(false); int minLeft=0, minRight=0; @@ -252,8 +335,12 @@ bool CGarrisonSlot::split() int countLeft = selection->myStack ? selection->myStack->count : 0; int countRight = myStack ? myStack->count : 0; - GH.windows().createAndPushWindow(selection->creature, std::bind(&CGarrisonInt::splitStacks, owner, _1, _2), - minLeft, minRight, countLeft, countRight); + auto splitFunctor = [this, selection](int amountLeft, int amountRight) + { + owner->splitStacks(selection, owner->armedObjs[upg], ID, amountRight); + }; + + GH.windows().createAndPushWindow(selection->creature, splitFunctor, minLeft, minRight, countLeft, countRight); return true; } @@ -349,17 +436,50 @@ 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(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(); +} + void CGarrisonSlot::update() { if(getObj() != nullptr) { - addUsedEvents(LCLICK | SHOW_POPUP | HOVER); + addUsedEvents(LCLICK | SHOW_POPUP | GESTURE | HOVER); myStack = getObj()->getStackPtr(ID); creature = myStack ? myStack->type : nullptr; } else { - removeUsedEvents(LCLICK | SHOW_POPUP | HOVER); + removeUsedEvents(LCLICK | SHOW_POPUP | GESTURE | HOVER); myStack = nullptr; creature = nullptr; } @@ -434,9 +554,7 @@ void CGarrisonSlot::splitIntoParts(CGarrisonSlot::EGarrisonType type, int amount if(empty == SlotID()) return; - owner->pb = type; - owner->p2 = empty; - owner->splitStacks(1, amount); + owner->splitStacks(this, owner->armedObjs[type], empty, amount); } bool CGarrisonSlot::handleSplittingShortcuts() @@ -555,9 +673,9 @@ void CGarrisonInt::splitClick() setSplittingMode(!getSplittingMode()); redraw(); } -void CGarrisonInt::splitStacks(int, int amountRight) +void CGarrisonInt::splitStacks(const CGarrisonSlot * from, const CArmedInstance * armyDest, SlotID slotDest, int amount ) { - LOCPLINT->cb->splitStack(armedObjs[getSelection()->upg], armedObjs[pb], getSelection()->ID, p2, amountRight); + LOCPLINT->cb->splitStack(armedObjs[from->upg], armyDest, from->ID, slotDest, amount); } bool CGarrisonInt::checkSelected(const CGarrisonSlot * selected, TQuantity min) const @@ -669,17 +787,14 @@ void CGarrisonInt::bulkSmartSplitStack(const CGarrisonSlot * selected) LOCPLINT->cb->bulkSmartSplitStack(armedObjs[type]->id, selected->ID); } -CGarrisonInt::CGarrisonInt(int x, int y, int inx, const Point & garsOffset, - const CArmedInstance * s1, const CArmedInstance * s2, - bool _removableUnits, bool smallImgs, ESlotsLayout _layout) - : highlighted(nullptr), - inSplittingMode(false), - interx(inx), - garOffset(garsOffset), - pb(false), - smallIcons(smallImgs), - removableUnits(_removableUnits), - layout(_layout) +CGarrisonInt::CGarrisonInt(int x, int y, int inx, const Point & garsOffset, const CArmedInstance * s1, const CArmedInstance * s2, bool _removableUnits, bool smallImgs, ESlotsLayout _layout) + : highlighted(nullptr) + , inSplittingMode(false) + , interx(inx) + , garOffset(garsOffset) + , smallIcons(smallImgs) + , removableUnits(_removableUnits) + , layout(_layout) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); diff --git a/client/widgets/CGarrisonInt.h b/client/widgets/CGarrisonInt.h index baa1360ca..626f9ce19 100644 --- a/client/widgets/CGarrisonInt.h +++ b/client/widgets/CGarrisonInt.h @@ -24,10 +24,47 @@ class CButton; class CAnimImage; class CGarrisonSlot; class CLabel; +class IImage; + +class RadialMenuItem : public CIntObject +{ + std::shared_ptr image; + std::shared_ptr picture; +public: + std::function callback; + + RadialMenuItem(std::string imageName, std::function callback); + + bool isInside(const Point & position); + + void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override; + void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override; +}; + +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); + + std::vector> items; + + void addItem(const Point & offset, const std::string & path, std::function callback ); +public: + RadialMenu(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; + void show(Canvas & to) override; +}; /// A single garrison slot which holds one creature of a specific amount class CGarrisonSlot : public CIntObject { +public: SlotID ID; //for identification CGarrisonInt *owner; const CStackInstance * myStack; //nullptr if slot is empty @@ -43,7 +80,9 @@ class CGarrisonSlot : public CIntObject std::shared_ptr creatureImage; std::shared_ptr selectionImage; // image for selection, not always visible std::shared_ptr stackCount; + std::shared_ptr radialMenu; +public: bool viewInfo(); bool highlightOrDropArtifact(); bool split(); @@ -52,7 +91,6 @@ class CGarrisonSlot : public CIntObject void setHighlight(bool on); std::function getDismiss() const; -public: virtual void hover (bool on) override; //call-in const CArmedInstance * getObj() const; bool our() const; @@ -60,6 +98,10 @@ public: bool ally() const; void showPopupWindow(const Point & cursorPosition) override; void clickPressed(const Point & cursorPosition) override; + + 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(); CGarrisonSlot(CGarrisonInt *Owner, int x, int y, SlotID IID, EGarrisonType Upg=EGarrisonType::UP, const CStackInstance * creature_ = nullptr); @@ -92,11 +134,10 @@ public: Point garOffset; ///< Offset between garrisons (not used if only one hero) std::vector> splitButtons; ///< May be empty if no buttons - SlotID p2; ///< TODO: comment me - bool pb, - smallIcons, ///< true - 32x32 imgs, false - 58x64 - removableUnits, ///< player Can remove units from up - owned[2]; ///< player Owns up or down army ([0] upper, [1] lower) + bool smallIcons; ///< true - 32x32 imgs, false - 58x64 + bool removableUnits; ///< player Can remove units from up + bool twoRows; ///< slots Will be placed in 2 rows + bool owned[2]; ///< player Owns up or down army ([0] upper, [1] lower) ESlotsLayout layout; @@ -117,7 +158,7 @@ public: void recreateSlots(); void splitClick(); ///< handles click on split button - void splitStacks(int amountLeft, int amountRight); ///< TODO: comment me + void splitStacks(const CGarrisonSlot * from, const CArmedInstance * armyDest, SlotID slotDest, int amount); ///< TODO: comment me void moveStackToAnotherArmy(const CGarrisonSlot * selected); void bulkMoveArmy(const CGarrisonSlot * selected); void bulkMergeStacks(const CGarrisonSlot * selected); // Gather all creatures of selected type to the selected slot from other hero/garrison slots From a494dc4870cff0c7bf653e9e4d9b0217e62e89a3 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Fri, 7 Jul 2023 01:08:29 +0300 Subject: [PATCH 02/16] Refactoring of CGarrisonInt --- client/CMakeLists.txt | 2 + client/CPlayerInterface.cpp | 7 +- client/gui/CIntObject.h | 6 + client/widgets/CGarrisonInt.cpp | 207 +++++++++--------------- client/widgets/CGarrisonInt.h | 100 ++++-------- client/widgets/MiscWidgets.cpp | 4 +- client/widgets/RadialMenu.cpp | 101 ++++++++++++ client/widgets/RadialMenu.h | 52 ++++++ client/windows/CCastleInterface.cpp | 3 +- client/windows/CCastleInterface.h | 4 +- client/windows/CHeroWindow.cpp | 3 +- client/windows/CHeroWindow.h | 13 +- client/windows/CKingdomInterface.cpp | 15 +- client/windows/CKingdomInterface.h | 13 +- client/windows/GUIClasses.cpp | 7 +- client/windows/GUIClasses.h | 11 +- client/windows/QuickRecruitmentWindow.h | 2 +- 17 files changed, 315 insertions(+), 235 deletions(-) create mode 100644 client/widgets/RadialMenu.cpp create mode 100644 client/widgets/RadialMenu.h diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 3eeae7018..e67d803e1 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -107,6 +107,7 @@ set(client_SRCS widgets/CArtifactsOfHeroMarket.cpp widgets/CArtifactsOfHeroBackpack.cpp widgets/CWindowWithArtifacts.cpp + widgets/RadialMenu.cpp windows/CCastleInterface.cpp windows/CCreatureWindow.cpp @@ -262,6 +263,7 @@ set(client_HEADERS widgets/CArtifactsOfHeroMarket.h widgets/CArtifactsOfHeroBackpack.h widgets/CWindowWithArtifacts.h + widgets/RadialMenu.h windows/CCastleInterface.h windows/CCreatureWindow.h diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index d1300e540..445359148 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -34,6 +34,7 @@ #include "windows/CQuestLog.h" #include "windows/CPuzzleWindow.h" #include "widgets/CComponent.h" +#include "widgets/CGarrisonInt.h" #include "widgets/Buttons.h" #include "windows/CTradeWindow.h" #include "windows/CSpellWindow.h" @@ -536,8 +537,8 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town) if(castleInt) { castleInt->garr->selectSlot(nullptr); - castleInt->garr->setArmy(town->getUpperArmy(), 0); - castleInt->garr->setArmy(town->visitingHero, 1); + castleInt->garr->setArmy(town->getUpperArmy(), EGarrisonType::UPPER); + castleInt->garr->setArmy(town->visitingHero, EGarrisonType::LOWER); castleInt->garr->recreateSlots(); castleInt->heroes->update(); @@ -601,7 +602,7 @@ void CPlayerInterface::garrisonsChanged(std::vector ob adventureInt->onTownChanged(town); } - for (auto cgh : GH.windows().findWindows()) + for (auto cgh : GH.windows().findWindows()) cgh->updateGarrisons(); for (auto cmw : GH.windows().findWindows()) diff --git a/client/gui/CIntObject.h b/client/gui/CIntObject.h index a6306e052..4b4dbfd87 100644 --- a/client/gui/CIntObject.h +++ b/client/gui/CIntObject.h @@ -143,6 +143,12 @@ protected: void close(); }; +class IGarrisonHolder +{ +public: + virtual void updateGarrisons() = 0; +}; + class IStatusBar { public: diff --git a/client/widgets/CGarrisonInt.cpp b/client/widgets/CGarrisonInt.cpp index 839e172ef..f2e464173 100644 --- a/client/widgets/CGarrisonInt.cpp +++ b/client/widgets/CGarrisonInt.cpp @@ -12,6 +12,7 @@ #include "Buttons.h" #include "TextControls.h" +#include "RadialMenu.h" #include "../gui/CGuiHandler.h" #include "../gui/WindowHandler.h" @@ -30,90 +31,6 @@ #include "../../lib/TextOperations.h" #include "../../lib/gameState/CGameState.h" -RadialMenuItem::RadialMenuItem(std::string imageName, std::function callback) - : callback(callback) -{ - OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - - image = IImage::createFromFile("radialMenu/" + imageName); - picture = std::make_shared(image, Point(0,0)); - pos = picture->pos; -} - -bool RadialMenuItem::isInside(const Point & position) -{ - Point localPosition = position - pos.topLeft(); - - return !image->isTransparent(localPosition); -} - -void RadialMenuItem::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) -{ - -} - -void RadialMenuItem::gesture(bool on, const Point & initialPosition, const Point & finalPosition) -{ - -} - -RadialMenu::RadialMenu(CGarrisonInt * army, CGarrisonSlot * slot) -{ - OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - - bool isExchange = army->armedObjs[0] && army->armedObjs[1]; // two armies exist - - addItem(ITEM_NW, "stackMerge", [=](){army->bulkMergeStacks(slot);}); - addItem(ITEM_NE, "stackInfo", [=](){slot->viewInfo();}); - - addItem(ITEM_WW, "stackSplitOne", [=](){slot->splitIntoParts(slot->upg, 1); }); - addItem(ITEM_EE, "stackSplitEqual", [=](){army->bulkSmartSplitStack(slot);}); - - if (isExchange) - { - addItem(ITEM_SW, "stackMove", [=](){army->moveStackToAnotherArmy(slot);}); - //FIXME: addItem(ITEM_SE, "stackSplitDialog", [=](){slot->split();}); - } - - for(const auto & item : items) - pos = pos.include(item->pos); - -} - -void RadialMenu::addItem(const Point & offset, const std::string & path, std::function callback ) -{ - auto item = std::make_shared(path, callback); - - item->moveBy(offset); - - items.push_back(item); -} - -void RadialMenu::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) -{ - -} - -void RadialMenu::show(Canvas & to) -{ - showAll(to); -} - -void RadialMenu::gesture(bool on, const Point & initialPosition, const Point & finalPosition) -{ - if (!on) - { - for(const auto & item : items) - { - if (item->isInside(finalPosition)) - { - item->callback(); - return; - } - } - } -} - void CGarrisonSlot::setHighlight(bool on) { if (on) @@ -157,16 +74,16 @@ void CGarrisonSlot::hover (bool on) } else { - const bool isHeroOnMap = owner->armedObjs[0] // Hero is not a visitor and not a garrison defender - && owner->armedObjs[0]->ID == Obj::HERO - && (!owner->armedObjs[1] || owner->armedObjs[1]->ID == Obj::HERO) // one hero or we are in the Heroes exchange window - && !(static_cast(owner->armedObjs[0]))->inTownGarrison; + const bool isHeroOnMap = owner->upperArmy() // Hero is not a visitor and not a garrison defender + && owner->upperArmy()->ID == Obj::HERO + && (!owner->lowerArmy() || owner->lowerArmy()->ID == Obj::HERO) // one hero or we are in the Heroes exchange window + && !(static_cast(owner->upperArmy()))->inTownGarrison; if(isHeroOnMap) { temp = CGI->generaltexth->allTexts[481]; //Select %s } - else if(upg == EGarrisonType::UP) + else if(upg == EGarrisonType::UPPER) { temp = CGI->generaltexth->tcommands[12]; //Select %s (in garrison) } @@ -210,16 +127,14 @@ void CGarrisonSlot::hover (bool on) const CArmedInstance * CGarrisonSlot::getObj() const { - return owner->armedObjs[upg]; + return owner->army(upg); } -/// @return Whether the unit in the slot belongs to the current player. bool CGarrisonSlot::our() const { - return owner->owned[upg]; + return owner->isArmyOwned(upg); } -/// @return Whether the unit in the slot belongs to an ally but not to the current player. bool CGarrisonSlot::ally() const { if(!getObj()) @@ -337,19 +252,13 @@ bool CGarrisonSlot::split() auto splitFunctor = [this, selection](int amountLeft, int amountRight) { - owner->splitStacks(selection, owner->armedObjs[upg], ID, amountRight); + owner->splitStacks(selection, owner->army(upg), ID, amountRight); }; GH.windows().createAndPushWindow(selection->creature, splitFunctor, minLeft, minRight, countLeft, countRight); return true; } -/// If certain creates cannot be moved, the selection should change -/// Force reselection in these cases -/// * When attempting to take creatures from ally -/// * When attempting to swap creatures with an ally -/// * When attempting to take unremovable units -/// @return Whether reselection must be done bool CGarrisonSlot::mustForceReselection() const { const CGarrisonSlot * selection = owner->getSelection(); @@ -364,10 +273,10 @@ bool CGarrisonSlot::mustForceReselection() const return true; if (!owner->removableUnits) { - if (selection->upg == EGarrisonType::UP) + if (selection->upg == EGarrisonType::UPPER) return true; else - return creature || upg == EGarrisonType::UP; + return creature || upg == EGarrisonType::UPPER; } return false; } @@ -405,7 +314,7 @@ void CGarrisonSlot::clickPressed(const Point & cursorPosition) } else { - const CArmedInstance * selectedObj = owner->armedObjs[selection->upg]; + const CArmedInstance * selectedObj = owner->army(selection->upg); bool lastHeroStackSelected = false; if(selectedObj->stacksCount() == 1 && owner->getSelection()->upg != upg @@ -420,13 +329,13 @@ void CGarrisonSlot::clickPressed(const Point & cursorPosition) refr = split(); } else if(!creature && lastHeroStackSelected) // split all except last creature - LOCPLINT->cb->splitStack(selectedObj, owner->armedObjs[upg], selection->ID, ID, selection->myStack->count - 1); + LOCPLINT->cb->splitStack(selectedObj, owner->army(upg), selection->ID, ID, selection->myStack->count - 1); else if(creature != selection->creature) // swap - LOCPLINT->cb->swapCreatures(owner->armedObjs[upg], selectedObj, ID, selection->ID); + LOCPLINT->cb->swapCreatures(owner->army(upg), selectedObj, ID, selection->ID); else if(lastHeroStackSelected) // merge last stack to other hero stack refr = split(); else // merge - LOCPLINT->cb->mergeStacks(selectedObj, owner->armedObjs[upg], selection->ID, ID); + LOCPLINT->cb->mergeStacks(selectedObj, owner->army(upg), selection->ID, ID); } if(refr) { @@ -499,7 +408,7 @@ void CGarrisonSlot::update() } } -CGarrisonSlot::CGarrisonSlot(CGarrisonInt * Owner, int x, int y, SlotID IID, CGarrisonSlot::EGarrisonType Upg, const CStackInstance * creature_) +CGarrisonSlot::CGarrisonSlot(CGarrisonInt * Owner, int x, int y, SlotID IID, EGarrisonType Upg, const CStackInstance * creature_) : ID(IID), owner(Owner), myStack(creature_), @@ -547,14 +456,14 @@ CGarrisonSlot::CGarrisonSlot(CGarrisonInt * Owner, int x, int y, SlotID IID, CGa update(); } -void CGarrisonSlot::splitIntoParts(CGarrisonSlot::EGarrisonType type, int amount) +void CGarrisonSlot::splitIntoParts(EGarrisonType type, int amount) { auto empty = owner->getEmptySlot(type); if(empty == SlotID()) return; - owner->splitStacks(this, owner->armedObjs[type], empty, amount); + owner->splitStacks(this, owner->army(type), empty, amount); } bool CGarrisonSlot::handleSplittingShortcuts() @@ -618,21 +527,23 @@ void CGarrisonInt::addSplitBtn(std::shared_ptr button) void CGarrisonInt::createSlots() { int distance = interx + (smallIcons ? 32 : 58); - for(int i = 0; i < 2; i++) + for(auto i : { EGarrisonType::UPPER, EGarrisonType::LOWER }) { + Point offset = garOffset * static_cast(i); + std::vector> garrisonSlots; garrisonSlots.resize(7); - if(armedObjs[i]) + if(army(i)) { - for(auto & elem : armedObjs[i]->Slots()) + for(auto & elem : army(i)->Slots()) { - garrisonSlots[elem.first.getNum()] = std::make_shared(this, i*garOffset.x + (elem.first.getNum()*distance), i*garOffset.y, elem.first, static_cast(i), elem.second); + garrisonSlots[elem.first.getNum()] = std::make_shared(this, offset.x + (elem.first.getNum()*distance), offset.y, elem.first, i, elem.second); } } for(int j = 0; j < 7; j++) { if(!garrisonSlots[j]) - garrisonSlots[j] = std::make_shared(this, i*garOffset.x + (j*distance), i*garOffset.y, SlotID(j), static_cast(i), nullptr); + garrisonSlots[j] = std::make_shared(this, offset.x + (j*distance), offset.x, SlotID(j), i, nullptr); if(layout == ESlotsLayout::TWO_ROWS && j >= 4) { @@ -673,6 +584,7 @@ void CGarrisonInt::splitClick() setSplittingMode(!getSplittingMode()); redraw(); } + void CGarrisonInt::splitStacks(const CGarrisonSlot * from, const CArmedInstance * armyDest, SlotID slotDest, int amount ) { LOCPLINT->cb->splitStack(armedObjs[from->upg], armyDest, from->ID, slotDest, amount); @@ -689,9 +601,9 @@ void CGarrisonInt::moveStackToAnotherArmy(const CGarrisonSlot * selected) return; const auto srcArmyType = selected->upg; - const auto destArmyType = srcArmyType == CGarrisonSlot::UP - ? CGarrisonSlot::DOWN - : CGarrisonSlot::UP; + const auto destArmyType = srcArmyType == EGarrisonType::UPPER + ? EGarrisonType::LOWER + : EGarrisonType::UPPER; auto srcArmy = armedObjs[srcArmyType]; auto destArmy = armedObjs[destArmyType]; @@ -733,9 +645,9 @@ void CGarrisonInt::bulkMoveArmy(const CGarrisonSlot * selected) return; const auto srcArmyType = selected->upg; - const auto destArmyType = (srcArmyType == CGarrisonSlot::UP) - ? CGarrisonSlot::DOWN - : CGarrisonSlot::UP; + const auto destArmyType = (srcArmyType == EGarrisonType::UPPER) + ? EGarrisonType::LOWER + : EGarrisonType::UPPER; auto srcArmy = armedObjs[srcArmyType]; auto destArmy = armedObjs[destArmyType]; @@ -787,7 +699,7 @@ void CGarrisonInt::bulkSmartSplitStack(const CGarrisonSlot * selected) LOCPLINT->cb->bulkSmartSplitStack(armedObjs[type]->id, selected->ID); } -CGarrisonInt::CGarrisonInt(int x, int y, int inx, const Point & garsOffset, const CArmedInstance * s1, const CArmedInstance * s2, bool _removableUnits, bool smallImgs, ESlotsLayout _layout) +CGarrisonInt::CGarrisonInt(const Point & position, int inx, const Point & garsOffset, const CArmedInstance * s1, const CArmedInstance * s2, bool _removableUnits, bool smallImgs, ESlotsLayout _layout) : highlighted(nullptr) , inSplittingMode(false) , interx(inx) @@ -798,10 +710,9 @@ CGarrisonInt::CGarrisonInt(int x, int y, int inx, const Point & garsOffset, cons { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - setArmy(s1, false); - setArmy(s2, true); - pos.x += x; - pos.y += y; + setArmy(s1, EGarrisonType::UPPER); + setArmy(s2, EGarrisonType::LOWER); + pos += position; createSlots(); } @@ -846,19 +757,51 @@ bool CGarrisonInt::getSplittingMode() return inSplittingMode; } -SlotID CGarrisonInt::getEmptySlot(CGarrisonSlot::EGarrisonType type) const +SlotID CGarrisonInt::getEmptySlot(EGarrisonType type) const { - assert(armedObjs[type]); - return armedObjs[type] ? armedObjs[type]->getFreeSlot() : SlotID(); + assert(army(type)); + return army(type) ? army(type)->getFreeSlot() : SlotID(); } -bool CGarrisonInt::hasEmptySlot(CGarrisonSlot::EGarrisonType type) const +bool CGarrisonInt::hasEmptySlot(EGarrisonType type) const { return getEmptySlot(type) != SlotID(); } -void CGarrisonInt::setArmy(const CArmedInstance * army, bool bottomGarrison) +const CArmedInstance * CGarrisonInt::upperArmy() const { - owned[bottomGarrison] = army ? (army->tempOwner == LOCPLINT->playerID || army->tempOwner == PlayerColor::UNFLAGGABLE) : false; - armedObjs[bottomGarrison] = army; + return army(EGarrisonType::UPPER); +} + +const CArmedInstance * CGarrisonInt::lowerArmy() const +{ + return army(EGarrisonType::LOWER); +} + +const CArmedInstance * CGarrisonInt::army(EGarrisonType which) const +{ + if(armedObjs.count(which)) + return armedObjs.at(which); + return nullptr; +} + +bool CGarrisonInt::isArmyOwned(EGarrisonType which) const +{ + const auto * object = army(which); + + if (!object) + return false; + + if (object->tempOwner == LOCPLINT->playerID) + return true; + + if (object->tempOwner == PlayerColor::UNFLAGGABLE) + return true; + + return false; +} + +void CGarrisonInt::setArmy(const CArmedInstance * army, EGarrisonType type) +{ + armedObjs[type] = army; } diff --git a/client/widgets/CGarrisonInt.h b/client/widgets/CGarrisonInt.h index 626f9ce19..fde35e7a3 100644 --- a/client/widgets/CGarrisonInt.h +++ b/client/widgets/CGarrisonInt.h @@ -9,12 +9,11 @@ */ #pragma once -#include "../windows/CWindowObject.h" +#include "../gui/CIntObject.h" VCMI_LIB_NAMESPACE_BEGIN class CArmedInstance; -class CCreatureSet; class CStackInstance; VCMI_LIB_NAMESPACE_END @@ -22,60 +21,23 @@ VCMI_LIB_NAMESPACE_END class CGarrisonInt; class CButton; class CAnimImage; -class CGarrisonSlot; class CLabel; -class IImage; +class RadialMenu; -class RadialMenuItem : public CIntObject +enum class EGarrisonType { - std::shared_ptr image; - std::shared_ptr picture; -public: - std::function callback; - - RadialMenuItem(std::string imageName, std::function callback); - - bool isInside(const Point & position); - - void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override; - void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override; -}; - -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); - - std::vector> items; - - void addItem(const Point & offset, const std::string & path, std::function callback ); -public: - RadialMenu(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; - void show(Canvas & to) override; + UPPER, /// up garrison (Garrisoned) + LOWER, /// down garrison (Visiting) }; /// A single garrison slot which holds one creature of a specific amount class CGarrisonSlot : public CIntObject { -public: SlotID ID; //for identification CGarrisonInt *owner; const CStackInstance * myStack; //nullptr if slot is empty const CCreature * creature; - - /// Type of Garrison for slot (up or down) - enum EGarrisonType - { - UP=0, ///< 0 - up garrison (Garrisoned) - DOWN, ///< 1 - down garrison (Visiting) - } upg; ///< Flag indicating if it is the up or down garrison + EGarrisonType upg; std::shared_ptr creatureImage; std::shared_ptr selectionImage; // image for selection, not always visible @@ -86,24 +48,33 @@ public: bool viewInfo(); bool highlightOrDropArtifact(); bool split(); + + /// If certain creates cannot be moved, the selection should change + /// Force reselection in these cases + /// * When attempting to take creatures from ally + /// * When attempting to swap creatures with an ally + /// * When attempting to take unremovable units + /// @return Whether reselection must be done bool mustForceReselection() const; void setHighlight(bool on); std::function getDismiss() const; - virtual void hover (bool on) override; //call-in const CArmedInstance * getObj() const; bool our() const; SlotID getSlot() const { return ID; } + EGarrisonType getGarrison() const { return upg; } bool ally() const; + + // CIntObject overrides 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(); - CGarrisonSlot(CGarrisonInt *Owner, int x, int y, SlotID IID, EGarrisonType Upg=EGarrisonType::UP, const CStackInstance * creature_ = nullptr); + CGarrisonSlot(CGarrisonInt *Owner, int x, int y, SlotID IID, EGarrisonType Upg, const CStackInstance * creature_); void splitIntoParts(EGarrisonType type, int amount); bool handleSplittingShortcuts(); /// Returns true when some shortcut is pressed, false otherwise @@ -122,6 +93,8 @@ class CGarrisonInt :public CIntObject void createSlots(); bool checkSelected(const CGarrisonSlot * selected, TQuantity min = 0) const; + std::map armedObjs; + public: enum class ESlotsLayout { @@ -137,7 +110,6 @@ public: bool smallIcons; ///< true - 32x32 imgs, false - 58x64 bool removableUnits; ///< player Can remove units from up bool twoRows; ///< slots Will be placed in 2 rows - bool owned[2]; ///< player Owns up or down army ([0] upper, [1] lower) ESlotsLayout layout; @@ -147,16 +119,19 @@ public: void setSplittingMode(bool on); bool getSplittingMode(); - bool hasEmptySlot(CGarrisonSlot::EGarrisonType type) const; - SlotID getEmptySlot(CGarrisonSlot::EGarrisonType type) const; + bool hasEmptySlot(EGarrisonType type) const; + SlotID getEmptySlot(EGarrisonType type) const; - const CArmedInstance * armedObjs[2]; ///< [0] is upper, [1] is down - - void setArmy(const CArmedInstance * army, bool bottomGarrison); + void setArmy(const CArmedInstance * army, EGarrisonType type); void addSplitBtn(std::shared_ptr button); void recreateSlots(); + const CArmedInstance* upperArmy() const; + const CArmedInstance* lowerArmy() const; + const CArmedInstance* army(EGarrisonType which) const; + bool isArmyOwned(EGarrisonType which) const; + void splitClick(); ///< handles click on split button void splitStacks(const CGarrisonSlot * from, const CArmedInstance * armyDest, SlotID slotDest, int amount); ///< TODO: comment me void moveStackToAnotherArmy(const CGarrisonSlot * selected); @@ -166,24 +141,17 @@ public: void bulkSmartSplitStack(const CGarrisonSlot * selected); /// Constructor - /// @param x, y Position - /// @param inx Distance between slots; - /// @param garsOffset + /// @param position Relative position to parent element + /// @param slotInterval Distance between slots; + /// @param secondGarrisonOffset /// @param s1, s2 Top and bottom armies /// @param _removableUnits You can take units from top /// @param smallImgs Units images size 64x58 or 32x32 /// @param _layout - when TWO_ROWS - Display slots in 2 rows (1st row = 4 slots, 2nd = 3 slots), REVERSED_TWO_ROWS = 3 slots in 1st row - CGarrisonInt(int x, int y, int inx, - const Point & garsOffset, - const CArmedInstance * s1, const CArmedInstance * s2 = nullptr, + CGarrisonInt(const Point & position, int slotInterval, + const Point & secondGarrisonOffset, + const CArmedInstance * upperArmy, const CArmedInstance * lowerArmy = nullptr, bool _removableUnits = true, bool smallImgs = false, ESlotsLayout _layout = ESlotsLayout::ONE_ROW); }; - -class CGarrisonHolder -{ -public: - virtual void updateGarrisons() = 0; -}; - diff --git a/client/widgets/MiscWidgets.cpp b/client/widgets/MiscWidgets.cpp index 9ef040193..0fdc7f18e 100644 --- a/client/widgets/MiscWidgets.cpp +++ b/client/widgets/MiscWidgets.cpp @@ -304,7 +304,7 @@ CHeroTooltip::CHeroTooltip(Point pos, const CGHeroInstance * hero): } CInteractableHeroTooltip::CInteractableHeroTooltip(Point pos, const CGHeroInstance * hero): - CGarrisonInt(pos.x, pos.y+73, 4, Point(0, 0), hero, nullptr, true, true, CGarrisonInt::ESlotsLayout::REVERSED_TWO_ROWS) + CGarrisonInt(pos + Point(0, 73), 4, Point(0, 0), hero, nullptr, true, true, CGarrisonInt::ESlotsLayout::REVERSED_TWO_ROWS) { init(InfoAboutHero(hero, InfoAboutHero::EInfoLevel::DETAILED)); } @@ -383,7 +383,7 @@ CTownTooltip::CTownTooltip(Point pos, const CGTownInstance * town) } CInteractableTownTooltip::CInteractableTownTooltip(Point pos, const CGTownInstance * town) - : CGarrisonInt(pos.x, pos.y+73, 4, Point(0, 0), town->getUpperArmy(), nullptr, true, true, CGarrisonInt::ESlotsLayout::REVERSED_TWO_ROWS) + : CGarrisonInt(pos + Point(0, 73), 4, Point(0, 0), town->getUpperArmy(), nullptr, true, true, CGarrisonInt::ESlotsLayout::REVERSED_TWO_ROWS) { init(InfoAboutTown(town, true)); } diff --git a/client/widgets/RadialMenu.cpp b/client/widgets/RadialMenu.cpp new file mode 100644 index 000000000..89d0c47c2 --- /dev/null +++ b/client/widgets/RadialMenu.cpp @@ -0,0 +1,101 @@ +/* + * RadialMenu.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 "RadialMenu.h" + +#include "Images.h" + +#include "../gui/CGuiHandler.h" +#include "../render/IImage.h" +#include "CGarrisonInt.h" + +RadialMenuItem::RadialMenuItem(std::string imageName, std::function callback) + : callback(callback) +{ + OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; + + image = IImage::createFromFile("radialMenu/" + imageName); + picture = std::make_shared(image, Point(0,0)); + pos = picture->pos; +} + +bool RadialMenuItem::isInside(const Point & position) +{ + Point localPosition = position - pos.topLeft(); + + return !image->isTransparent(localPosition); +} + +void RadialMenuItem::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) +{ + +} + +void RadialMenuItem::gesture(bool on, const Point & initialPosition, const Point & finalPosition) +{ + +} + +RadialMenu::RadialMenu(CGarrisonInt * army, CGarrisonSlot * slot) +{ + OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; + + bool isExchange = army->upperArmy() && army->lowerArmy(); // two armies exist + + addItem(ITEM_NW, "stackMerge", [=](){army->bulkMergeStacks(slot);}); + addItem(ITEM_NE, "stackInfo", [=](){slot->viewInfo();}); + + addItem(ITEM_WW, "stackSplitOne", [=](){slot->splitIntoParts(slot->getGarrison(), 1); }); + addItem(ITEM_EE, "stackSplitEqual", [=](){army->bulkSmartSplitStack(slot);}); + + if (isExchange) + { + addItem(ITEM_SW, "stackMove", [=](){army->moveStackToAnotherArmy(slot);}); + //FIXME: addItem(ITEM_SE, "stackSplitDialog", [=](){slot->split();}); + } + + for(const auto & item : items) + pos = pos.include(item->pos); + +} + +void RadialMenu::addItem(const Point & offset, const std::string & path, std::function callback ) +{ + auto item = std::make_shared(path, callback); + + item->moveBy(offset); + + items.push_back(item); +} + +void RadialMenu::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) +{ + +} + +void RadialMenu::show(Canvas & to) +{ + showAll(to); +} + +void RadialMenu::gesture(bool on, const Point & initialPosition, const Point & finalPosition) +{ + if (!on) + { + for(const auto & item : items) + { + if (item->isInside(finalPosition)) + { + item->callback(); + return; + } + } + } +} diff --git a/client/widgets/RadialMenu.h b/client/widgets/RadialMenu.h new file mode 100644 index 000000000..e69b2df7c --- /dev/null +++ b/client/widgets/RadialMenu.h @@ -0,0 +1,52 @@ +/* + * RadialMenu.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 IImage; + +class CGarrisonInt; +class CGarrisonSlot; + +class RadialMenuItem : public CIntObject +{ + std::shared_ptr image; + std::shared_ptr picture; +public: + std::function callback; + + RadialMenuItem(std::string imageName, std::function callback); + + bool isInside(const Point & position); + + void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override; + void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override; +}; + +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); + + std::vector> items; + + void addItem(const Point & offset, const std::string & path, std::function callback ); +public: + RadialMenu(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; + void show(Canvas & to) override; +}; diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index a9f94b6c1..e3f743aec 100644 --- a/client/windows/CCastleInterface.cpp +++ b/client/windows/CCastleInterface.cpp @@ -25,6 +25,7 @@ #include "../gui/WindowHandler.h" #include "../widgets/MiscWidgets.h" #include "../widgets/CComponent.h" +#include "../widgets/CGarrisonInt.h" #include "../widgets/Buttons.h" #include "../widgets/TextControls.h" #include "../render/Canvas.h" @@ -1154,7 +1155,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst center(); updateShadow(); - garr = std::make_shared(305, 387, 4, Point(0,96), town->getUpperArmy(), town->visitingHero); + garr = std::make_shared(Point(305, 387), 4, Point(0,96), town->getUpperArmy(), town->visitingHero); garr->setRedrawParent(true); heroes = std::make_shared(town, Point(241, 387), Point(241, 483), garr, true); diff --git a/client/windows/CCastleInterface.h b/client/windows/CCastleInterface.h index 5450a0096..05ea80fe1 100644 --- a/client/windows/CCastleInterface.h +++ b/client/windows/CCastleInterface.h @@ -9,7 +9,7 @@ */ #pragma once -#include "../widgets/CGarrisonInt.h" +#include "../windows/CWindowObject.h" #include "../widgets/Images.h" VCMI_LIB_NAMESPACE_BEGIN @@ -212,7 +212,7 @@ public: }; /// Class which manages the castle window -class CCastleInterface : public CStatusbarWindow, public CGarrisonHolder +class CCastleInterface : public CStatusbarWindow, public IGarrisonHolder { std::shared_ptr title; std::shared_ptr income; diff --git a/client/windows/CHeroWindow.cpp b/client/windows/CHeroWindow.cpp index 63f83fe9c..771d4a521 100644 --- a/client/windows/CHeroWindow.cpp +++ b/client/windows/CHeroWindow.cpp @@ -24,6 +24,7 @@ #include "../gui/WindowHandler.h" #include "../widgets/MiscWidgets.h" #include "../widgets/CComponent.h" +#include "../widgets/CGarrisonInt.h" #include "../widgets/TextControls.h" #include "../widgets/Buttons.h" #include "../render/CAnimation.h" @@ -200,7 +201,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded) std::string helpBox = heroscrn[32]; boost::algorithm::replace_first(helpBox, "%s", CGI->generaltexth->allTexts[43]); - garr = std::make_shared(15, 485, 8, Point(), curHero); + garr = std::make_shared(Point(15, 485), 8, Point(), curHero); auto split = std::make_shared(Point(539, 519), "hsbtns9.def", CButton::tooltip(CGI->generaltexth->allTexts[256], helpBox), [&](){ garr->splitClick(); }); garr->addSplitBtn(split); } diff --git a/client/windows/CHeroWindow.h b/client/windows/CHeroWindow.h index 608b31a93..8f87ac7e9 100644 --- a/client/windows/CHeroWindow.h +++ b/client/windows/CHeroWindow.h @@ -9,12 +9,12 @@ */ #pragma once -#include - -#include "../../lib/bonuses/Bonus.h" -#include "../../lib/bonuses/IBonusBearer.h" #include "../widgets/CWindowWithArtifacts.h" -#include "../widgets/CGarrisonInt.h" +#include "CWindowObject.h" + +#include "../../lib/bonuses/IBonusBearer.h" + +#include VCMI_LIB_NAMESPACE_BEGIN @@ -33,6 +33,7 @@ class CToggleButton; class CToggleGroup; class CGStatusBar; class CTextBox; +class CGarrisonInt; /// Button which switches hero selection class CHeroSwitcher : public CIntObject @@ -46,7 +47,7 @@ public: CHeroSwitcher(CHeroWindow * owner_, Point pos_, const CGHeroInstance * hero_); }; -class CHeroWindow : public CStatusbarWindow, public CGarrisonHolder, public CWindowWithArtifacts +class CHeroWindow : public CStatusbarWindow, public IGarrisonHolder, public CWindowWithArtifacts { std::shared_ptr name; std::shared_ptr title; diff --git a/client/windows/CKingdomInterface.cpp b/client/windows/CKingdomInterface.cpp index 9e1a07dde..300092027 100644 --- a/client/windows/CKingdomInterface.cpp +++ b/client/windows/CKingdomInterface.cpp @@ -20,6 +20,7 @@ #include "../gui/CGuiHandler.h" #include "../gui/Shortcut.h" #include "../widgets/CComponent.h" +#include "../widgets/CGarrisonInt.h" #include "../widgets/TextControls.h" #include "../widgets/MiscWidgets.h" #include "../widgets/Buttons.h" @@ -646,7 +647,7 @@ void CKingdomInterface::heroRemoved() void CKingdomInterface::updateGarrisons() { - if(auto garrison = std::dynamic_pointer_cast(tabArea->getItem())) + if(auto garrison = std::dynamic_pointer_cast(tabArea->getItem())) garrison->updateGarrisons(); } @@ -692,7 +693,7 @@ void CKingdHeroList::updateGarrisons() { for(std::shared_ptr object : heroes->getItems()) { - if(CGarrisonHolder * garrison = dynamic_cast(object.get())) + if(IGarrisonHolder * garrison = dynamic_cast(object.get())) garrison->updateGarrisons(); } } @@ -744,7 +745,7 @@ void CKingdTownList::updateGarrisons() { for(std::shared_ptr object : towns->getItems()) { - if(CGarrisonHolder * garrison = dynamic_cast(object.get())) + if(IGarrisonHolder * garrison = dynamic_cast(object.get())) garrison->updateGarrisons(); } } @@ -772,7 +773,7 @@ CTownItem::CTownItem(const CGTownInstance * Town) hall = std::make_shared( 69, 31, town, true); fort = std::make_shared(111, 31, town, false); - garr = std::make_shared(313, 3, 4, Point(232,0), town->getUpperArmy(), town->visitingHero, true, true, CGarrisonInt::ESlotsLayout::TWO_ROWS); + garr = std::make_shared(Point(313, 3), 4, Point(232,0), town->getUpperArmy(), town->visitingHero, true, true, CGarrisonInt::ESlotsLayout::TWO_ROWS); heroes = std::make_shared(town, Point(244,6), Point(475,6), garr, false); size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->settings()->getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)]; @@ -790,8 +791,8 @@ CTownItem::CTownItem(const CGTownInstance * Town) void CTownItem::updateGarrisons() { garr->selectSlot(nullptr); - garr->setArmy(town->getUpperArmy(), 0); - garr->setArmy(town->visitingHero, 1); + garr->setArmy(town->getUpperArmy(), EGarrisonType::UPPER); + garr->setArmy(town->visitingHero, EGarrisonType::LOWER); garr->recreateSlots(); } @@ -913,7 +914,7 @@ CHeroItem::CHeroItem(const CGHeroInstance * Hero) artButtons->addCallback(std::bind(&CHeroItem::onArtChange, this, _1)); artButtons->setSelected(0); - garr = std::make_shared(6, 78, 4, Point(), hero, nullptr, true, true); + garr = std::make_shared(Point(6, 78), 4, Point(), hero, nullptr, true, true); portrait = std::make_shared("PortraitsLarge", hero->portrait, 0, 5, 6); heroArea = std::make_shared(5, 6, hero); diff --git a/client/windows/CKingdomInterface.h b/client/windows/CKingdomInterface.h index e305f2e16..6a6b51301 100644 --- a/client/windows/CKingdomInterface.h +++ b/client/windows/CKingdomInterface.h @@ -10,7 +10,7 @@ #pragma once #include "../widgets/CWindowWithArtifacts.h" -#include "../widgets/CGarrisonInt.h" +#include "CWindowObject.h" class CButton; class CAnimImage; @@ -27,6 +27,7 @@ class MoraleLuckBox; class CListBox; class CTabbedInt; class CGStatusBar; +class CGarrisonInt; class CKingdHeroList; class CKingdTownList; @@ -195,7 +196,7 @@ public: }; /// Class which holds all parts of kingdom overview window -class CKingdomInterface : public CWindowObject, public CGarrisonHolder, public CArtifactHolder +class CKingdomInterface : public CWindowObject, public IGarrisonHolder, public CArtifactHolder { private: struct OwnedObjectInfo @@ -255,7 +256,7 @@ public: }; /// List item with town -class CTownItem : public CIntObject, public CGarrisonHolder +class CTownItem : public CIntObject, public IGarrisonHolder { std::shared_ptr background; std::shared_ptr picture; @@ -282,7 +283,7 @@ public: }; /// List item with hero -class CHeroItem : public CIntObject, public CGarrisonHolder +class CHeroItem : public CIntObject, public IGarrisonHolder { const CGHeroInstance * hero; @@ -315,7 +316,7 @@ public: }; /// Tab with all hero-specific data -class CKingdHeroList : public CIntObject, public CGarrisonHolder, public CWindowWithArtifacts +class CKingdHeroList : public CIntObject, public IGarrisonHolder, public CWindowWithArtifacts { private: std::shared_ptr heroes; @@ -331,7 +332,7 @@ public: }; /// Tab with all town-specific data -class CKingdTownList : public CIntObject, public CGarrisonHolder +class CKingdTownList : public CIntObject, public IGarrisonHolder { private: std::shared_ptr towns; diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 643fb62d9..e921cdf88 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -31,6 +31,7 @@ #include "../gui/WindowHandler.h" #include "../widgets/CComponent.h" +#include "../widgets/CGarrisonInt.h" #include "../widgets/MiscWidgets.h" #include "../widgets/CreatureCostBox.h" #include "../widgets/Buttons.h" @@ -968,7 +969,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, //garrison interface - garr = std::make_shared(69, qeLayout ? 122 : 131, 4, Point(418,0), heroInst[0], heroInst[1], true, true); + garr = std::make_shared(Point(69, qeLayout ? 122 : 131), 4, Point(418,0), heroInst[0], heroInst[1], true, true); auto splitButtonCallback = [&](){ garr->splitClick(); }; garr->addSplitBtn(std::make_shared( Point( 10, qeLayout ? 122 : 132), "TSBTNS.DEF", CButton::tooltip(CGI->generaltexth->tcommands[3]), splitButtonCallback)); garr->addSplitBtn(std::make_shared( Point(744, qeLayout ? 122 : 132), "TSBTNS.DEF", CButton::tooltip(CGI->generaltexth->tcommands[3]), splitButtonCallback)); @@ -1351,7 +1352,7 @@ CGarrisonWindow::CGarrisonWindow(const CArmedInstance * up, const CGHeroInstance { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - garr = std::make_shared(92, 127, 4, Point(0,96), up, down, removableUnits); + garr = std::make_shared(Point(92, 127), 4, Point(0,96), up, down, removableUnits); { auto split = std::make_shared(Point(88, 314), "IDV6432.DEF", CButton::tooltip(CGI->generaltexth->tcommands[3], ""), [&](){ garr->splitClick(); } ); garr->addSplitBtn(split); @@ -1424,7 +1425,7 @@ CHillFortWindow::CHillFortWindow(const CGHeroInstance * visitor, const CGObjectI quit = std::make_shared(Point(294, 275), "IOKAY.DEF", CButton::tooltip(), std::bind(&CHillFortWindow::close, this), EShortcut::GLOBAL_ACCEPT); statusbar = CGStatusBar::create(std::make_shared(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); - garr = std::make_shared(108, 60, 18, Point(), hero, nullptr); + garr = std::make_shared(Point(108, 60), 18, Point(), hero, nullptr); updateGarrisons(); } diff --git a/client/windows/GUIClasses.h b/client/windows/GUIClasses.h index 72adfab04..157377aeb 100644 --- a/client/windows/GUIClasses.h +++ b/client/windows/GUIClasses.h @@ -14,7 +14,6 @@ #include "../lib/ResourceSet.h" #include "../lib/int3.h" #include "../widgets/CWindowWithArtifacts.h" -#include "../widgets/CGarrisonInt.h" #include "../widgets/Images.h" VCMI_LIB_NAMESPACE_BEGIN @@ -38,6 +37,8 @@ class CToggleButton; class CGStatusBar; class CTextBox; class CResDataBar; +class CGarrisonInt; +class CGarrisonSlot; enum class EUserEvent; @@ -273,7 +274,7 @@ private: void moveStack(const CGHeroInstance * source, const CGHeroInstance * target, SlotID sourceSlot); }; -class CExchangeWindow : public CStatusbarWindow, public CGarrisonHolder, public CWindowWithArtifacts +class CExchangeWindow : public CStatusbarWindow, public IGarrisonHolder, public CWindowWithArtifacts { std::array, 2> titles; std::vector> primSkillImages;//shared for both heroes @@ -348,7 +349,7 @@ public: }; /// Creature transformer window -class CTransformerWindow : public CStatusbarWindow, public CGarrisonHolder +class CTransformerWindow : public CStatusbarWindow, public IGarrisonHolder { class CItem : public CIntObject { @@ -449,7 +450,7 @@ public: }; /// Garrison window where you can take creatures out of the hero to place it on the garrison -class CGarrisonWindow : public CWindowObject, public CGarrisonHolder +class CGarrisonWindow : public CWindowObject, public IGarrisonHolder { std::shared_ptr title; std::shared_ptr banner; @@ -466,7 +467,7 @@ public: }; /// Hill fort is the building where you can upgrade units -class CHillFortWindow : public CStatusbarWindow, public CGarrisonHolder +class CHillFortWindow : public CStatusbarWindow, public IGarrisonHolder { private: static const int slotsCount = 7; diff --git a/client/windows/QuickRecruitmentWindow.h b/client/windows/QuickRecruitmentWindow.h index 16f47cd61..cdb36e819 100644 --- a/client/windows/QuickRecruitmentWindow.h +++ b/client/windows/QuickRecruitmentWindow.h @@ -9,7 +9,7 @@ */ #pragma once -#include "../widgets/CGarrisonInt.h" +#include "../windows/CWindowObject.h" class CButton; class CreatureCostBox; From d26595cef7fc7c7cacf4ab9c05dcc9234a1702dc Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 16 Jul 2023 14:49:48 +0300 Subject: [PATCH 03/16] Radial menu is now a proper window. Minor fixes to positioning. --- Mods/vcmi/Data/radialMenu/stackEmpty.png | Bin 0 -> 517 bytes client/gui/EventDispatcher.cpp | 6 +++++ client/widgets/CGarrisonInt.cpp | 29 +---------------------- client/widgets/CGarrisonInt.h | 3 --- client/widgets/RadialMenu.cpp | 27 +++++++++++++++++---- client/widgets/RadialMenu.h | 24 ++++++++++++------- lib/Point.h | 5 ++++ 7 files changed, 49 insertions(+), 45 deletions(-) create mode 100644 Mods/vcmi/Data/radialMenu/stackEmpty.png diff --git a/Mods/vcmi/Data/radialMenu/stackEmpty.png b/Mods/vcmi/Data/radialMenu/stackEmpty.png new file mode 100644 index 0000000000000000000000000000000000000000..0b6e00094558ff9b8e7bfbbb079c93356b18418f GIT binary patch literal 517 zcmeAS@N?(olHy`uVBq!ia0vp^u0ZV1!3HGvigEZeFfg9+ba4!+U`&!=X%Ou2{eS=b zKmH}X2mc82xiG%H!+2aPP~h0d|L?-WG*!)2J-iw&y=77iVqp38FMi3o=|`(F*Oac> z{M?4$S>fl*+=TQx1Fi|_FF()WxU7{t<+Zq9KgT47=SFRTtUT!o$`{tGd8cve)htoQ zrTGb04oY5ru!OCRdk!D(>2r*2q5Y43e|PA5J~QkU-}hMKqldT1ChRyM`NJs5fBta; z_a9GZE7!c-VtuFl>@5DY7mRJ@$~LTd_mXb(Uy(ggI45`MyAS)b`Sjd=EIBE`cCJV2 zWm`+)gD#@yZ*Oe1G7i#Bs zcAM^WR+ya_Eu+rIP3b#ES@?LXDmw)FEeZ);87F2h52^&?(ag)canb+6L9Lt$^1IAgTSjGx`N oC)Rh^aDLc+;K%dBi$BTV;@rG=qn^xOVDvJ0y85}Sb4q9e0NI=5u>b%7 literal 0 HcmV?d00001 diff --git a/client/gui/EventDispatcher.cpp b/client/gui/EventDispatcher.cpp index c09d95826..19ed96b6f 100644 --- a/client/gui/EventDispatcher.cpp +++ b/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); } diff --git a/client/widgets/CGarrisonInt.cpp b/client/widgets/CGarrisonInt.cpp index f2e464173..3d52d9a0c 100644 --- a/client/widgets/CGarrisonInt.cpp +++ b/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(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(pos.center(), owner, this); } void CGarrisonSlot::update() diff --git a/client/widgets/CGarrisonInt.h b/client/widgets/CGarrisonInt.h index fde35e7a3..b991d4f31 100644 --- a/client/widgets/CGarrisonInt.h +++ b/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 creatureImage; std::shared_ptr selectionImage; // image for selection, not always visible std::shared_ptr stackCount; - std::shared_ptr 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(); diff --git a/client/widgets/RadialMenu.cpp b/client/widgets/RadialMenu.cpp index 89d0c47c2..88aa5b376 100644 --- a/client/widgets/RadialMenu.cpp +++ b/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 callback) +RadialMenuItem::RadialMenuItem(const std::string & imageName, const std::function & callback) : callback(callback) { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; image = IImage::createFromFile("radialMenu/" + imageName); - picture = std::make_shared(image, Point(0,0)); + picture = std::make_shared(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("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 callback ) +void RadialMenu::addItem(const Point & offset, const std::string & path, const std::function& callback ) { auto item = std::make_shared(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; } } } diff --git a/client/widgets/RadialMenu.h b/client/widgets/RadialMenu.h index e69b2df7c..10ac3229d 100644 --- a/client/widgets/RadialMenu.h +++ b/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 callback; - RadialMenuItem(std::string imageName, std::function callback); + RadialMenuItem(const std::string& imageName, const std::function& 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> items; - void addItem(const Point & offset, const std::string & path, std::function callback ); + std::shared_ptr statusBarBackground; + std::shared_ptr statusBar; + + void addItem(const Point & offset, const std::string & path, const std::function& 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; diff --git a/lib/Point.h b/lib/Point.h index b80be2703..0d8827562 100644 --- a/lib/Point.h +++ b/lib/Point.h @@ -67,6 +67,11 @@ public: return *this; } + constexpr Point operator-() const + { + return Point(-x, -y); + } + template constexpr Point operator-(const T &b) const { From e3f5ab57f2697398042700f1c84fa7a3a964e598 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 16 Jul 2023 17:56:47 +0300 Subject: [PATCH 04/16] Fixed input event ordering. Fixes radial menu show/hide logic --- .../{stackMove.png => heroMove.png} | Bin .../{stackSwap.png => heroSwap.png} | Bin .../{stackEmpty.png => itemEmpty.png} | Bin Mods/vcmi/Data/radialMenu/statusBar.png | Bin 0 -> 97 bytes client/eventsSDL/InputSourceMouse.cpp | 4 +- client/gui/EventDispatcher.cpp | 22 +++++---- client/gui/EventsReceiver.cpp | 15 ++++-- client/gui/EventsReceiver.h | 3 -- client/widgets/CGarrisonInt.cpp | 14 +++++- client/widgets/RadialMenu.cpp | 45 ++++-------------- client/widgets/RadialMenu.h | 39 ++++++++------- 11 files changed, 67 insertions(+), 75 deletions(-) rename Mods/vcmi/Data/radialMenu/{stackMove.png => heroMove.png} (100%) rename Mods/vcmi/Data/radialMenu/{stackSwap.png => heroSwap.png} (100%) rename Mods/vcmi/Data/radialMenu/{stackEmpty.png => itemEmpty.png} (100%) create mode 100644 Mods/vcmi/Data/radialMenu/statusBar.png diff --git a/Mods/vcmi/Data/radialMenu/stackMove.png b/Mods/vcmi/Data/radialMenu/heroMove.png similarity index 100% rename from Mods/vcmi/Data/radialMenu/stackMove.png rename to Mods/vcmi/Data/radialMenu/heroMove.png diff --git a/Mods/vcmi/Data/radialMenu/stackSwap.png b/Mods/vcmi/Data/radialMenu/heroSwap.png similarity index 100% rename from Mods/vcmi/Data/radialMenu/stackSwap.png rename to Mods/vcmi/Data/radialMenu/heroSwap.png diff --git a/Mods/vcmi/Data/radialMenu/stackEmpty.png b/Mods/vcmi/Data/radialMenu/itemEmpty.png similarity index 100% rename from Mods/vcmi/Data/radialMenu/stackEmpty.png rename to Mods/vcmi/Data/radialMenu/itemEmpty.png diff --git a/Mods/vcmi/Data/radialMenu/statusBar.png b/Mods/vcmi/Data/radialMenu/statusBar.png new file mode 100644 index 0000000000000000000000000000000000000000..1234e754305961f81903680bd97546e18c0a8811 GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^&wyBjkr_xX{&)EmkYWq)332^@KO4wgrr6a9q{KX3 t978G?lMnE}`u~{C-fhd96*_SY43Dn=>qy^tw+N_$!PC{xWt~$(69Cz>9y|a5 literal 0 HcmV?d00001 diff --git a/client/eventsSDL/InputSourceMouse.cpp b/client/eventsSDL/InputSourceMouse.cpp index 7d35b6797..cf2b80785 100644 --- a/client/eventsSDL/InputSourceMouse.cpp +++ b/client/eventsSDL/InputSourceMouse.cpp @@ -30,14 +30,14 @@ void InputSourceMouse::handleEventMouseMotion(const SDL_MouseMotionEvent & motio Point newPosition(motion.x, motion.y); Point distance(-motion.xrel, -motion.yrel); + mouseButtonsMask = motion.state; + if (mouseButtonsMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) GH.events().dispatchGesturePanning(middleClickPosition, newPosition, distance); else if (mouseButtonsMask & SDL_BUTTON(SDL_BUTTON_LEFT)) GH.events().dispatchMouseDragged(newPosition, distance); else GH.input().setCursorPosition(newPosition); - - mouseButtonsMask = motion.state; } void InputSourceMouse::handleEventMouseButtonDown(const SDL_MouseButtonEvent & button) diff --git a/client/gui/EventDispatcher.cpp b/client/gui/EventDispatcher.cpp index 19ed96b6f..068cbb8b3 100644 --- a/client/gui/EventDispatcher.cpp +++ b/client/gui/EventDispatcher.cpp @@ -243,39 +243,41 @@ void EventDispatcher::dispatchGesturePanningStarted(const Point & initialPositio for(auto it : copied) { - if (it->receiveEvent(initialPosition, AEventsReceiver::GESTURE)) + if (!vstd::contains(panningInterested, it)) + continue; + + if (!it->isGesturing() && it->receiveEvent(initialPosition, AEventsReceiver::GESTURE)) { - it->gesture(true, initialPosition, initialPosition); it->panningState = true; + it->gesture(true, initialPosition, initialPosition); } } } void EventDispatcher::dispatchGesturePanningEnded(const Point & initialPosition, const Point & finalPosition) { + dispatchGesturePanningStarted(initialPosition); auto copied = panningInterested; for(auto it : copied) { if (it->isGesturing()) { - it->gesture(false, initialPosition, finalPosition); it->panningState = false; + it->gesture(false, initialPosition, finalPosition); } } } void EventDispatcher::dispatchGesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) { + dispatchGesturePanningStarted(initialPosition); auto copied = panningInterested; for(auto it : copied) { - if (!it->isGesturing() && it->receiveEvent(initialPosition, AEventsReceiver::GESTURE)) - { - it->gesture(true, initialPosition, initialPosition); - it->panningState = true; - } + if (!vstd::contains(panningInterested, it)) + continue; if (it->isGesturing()) it->gesturePanning(initialPosition, currentPosition, lastUpdateDistance); @@ -309,16 +311,16 @@ void EventDispatcher::dispatchMouseMoved(const Point & distance, const Point & p { if (elem->isHovered()) { - elem->hover(false); elem->hoveredState = false; + elem->hover(false); } } } for(auto & elem : newlyHovered) { - elem->hover(true); elem->hoveredState = true; + elem->hover(true); } //sending active, MotionInterested objects mouseMoved() call diff --git a/client/gui/EventsReceiver.cpp b/client/gui/EventsReceiver.cpp index aa44124b3..2dbed3a33 100644 --- a/client/gui/EventsReceiver.cpp +++ b/client/gui/EventsReceiver.cpp @@ -37,11 +37,6 @@ bool AEventsReceiver::isActive() const return activeState; } -bool AEventsReceiver::isMouseLeftButtonPressed() const -{ - return mouseClickedState; -} - void AEventsReceiver::activateEvents(ui16 what) { assert((what & GENERAL) || (activeState & GENERAL)); @@ -62,4 +57,14 @@ void AEventsReceiver::deactivateEvents(ui16 what) what = activeState; } GH.events().deactivateElement(this, what & activeState); + + if (!(activeState & GESTURE) && panningState) + panningState = false; + + if (!(activeState & LCLICK) && mouseClickedState) + mouseClickedState = false; + +// FIXME: might lead to regressions, recheck before enabling +// if (!(activeState & HOVER)) +// hoveredState = false; } diff --git a/client/gui/EventsReceiver.h b/client/gui/EventsReceiver.h index af94c9290..37aeb5fa4 100644 --- a/client/gui/EventsReceiver.h +++ b/client/gui/EventsReceiver.h @@ -99,7 +99,4 @@ public: /// Returns true if element is currently active and may receive events bool isActive() const; - - /// Returns true if left mouse button was pressed when inside this element - bool isMouseLeftButtonPressed() const; }; diff --git a/client/widgets/CGarrisonInt.cpp b/client/widgets/CGarrisonInt.cpp index 3d52d9a0c..bbb57dda6 100644 --- a/client/widgets/CGarrisonInt.cpp +++ b/client/widgets/CGarrisonInt.cpp @@ -347,8 +347,18 @@ void CGarrisonSlot::clickPressed(const Point & cursorPosition) void CGarrisonSlot::gesture(bool on, const Point & initialPosition, const Point & finalPosition) { - if (on) - GH.windows().createAndPushWindow(pos.center(), owner, this); + if (!on) + return; + + std::vector menuElements = { + { RadialMenuConfig::ITEM_NW, "stackMerge", "", [this](){owner->bulkMergeStacks(this);} }, + { RadialMenuConfig::ITEM_NE, "stackInfo", "", [this](){viewInfo();} }, + { RadialMenuConfig::ITEM_WW, "stackSplitOne", "", [this](){splitIntoParts(this->getGarrison(), 1); } }, + { RadialMenuConfig::ITEM_EE, "stackSplitEqual", "", [this](){owner->bulkSmartSplitStack(this);} }, + { RadialMenuConfig::ITEM_SW, "heroMove", "", [this](){owner->moveStackToAnotherArmy(this);} }, + }; + + GH.windows().createAndPushWindow(pos.center(), menuElements); } void CGarrisonSlot::update() diff --git a/client/widgets/RadialMenu.cpp b/client/widgets/RadialMenu.cpp index 88aa5b376..d13fd1931 100644 --- a/client/widgets/RadialMenu.cpp +++ b/client/widgets/RadialMenu.cpp @@ -16,10 +16,10 @@ #include "../gui/CGuiHandler.h" #include "../gui/WindowHandler.h" #include "../render/IImage.h" -#include "CGarrisonInt.h" -RadialMenuItem::RadialMenuItem(const std::string & imageName, const std::function & callback) +RadialMenuItem::RadialMenuItem(const std::string & imageName, const std::string & hoverText, const std::function & callback) : callback(callback) + , hoverText(hoverText) { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; @@ -35,42 +35,20 @@ bool RadialMenuItem::isInside(const Point & position) return !image->isTransparent(localPosition); } -void RadialMenuItem::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) -{ - -} - -void RadialMenuItem::gesture(bool on, const Point & initialPosition, const Point & finalPosition) -{ - -} - -RadialMenu::RadialMenu(const Point & positionToCenter, CGarrisonInt * army, CGarrisonSlot * slot) +RadialMenu::RadialMenu(const Point & positionToCenter, const std::vector & menuConfig) { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; pos += positionToCenter; - bool isExchange = army->upperArmy() && army->lowerArmy(); // two armies exist - - addItem(Point(0,0), "stackEmpty", [](){}); + addItem(Point(0,0), "itemEmpty", "", [](){}); Point itemSize = items.back()->pos.dimensions(); moveBy(-itemSize / 2); - addItem(ITEM_NW, "stackMerge", [=](){army->bulkMergeStacks(slot);}); - addItem(ITEM_NE, "stackInfo", [=](){slot->viewInfo();}); + for (auto const & item : menuConfig) + addItem(item.itemPosition, item.imageName, item.hoverText, item.callback); - addItem(ITEM_WW, "stackSplitOne", [=](){slot->splitIntoParts(slot->getGarrison(), 1); }); - addItem(ITEM_EE, "stackSplitEqual", [=](){army->bulkSmartSplitStack(slot);}); - - if (isExchange) - { - addItem(ITEM_SW, "stackMove", [=](){army->moveStackToAnotherArmy(slot);}); - //FIXME: addItem(ITEM_SE, "stackSplitDialog", [=](){slot->split();}); - } - - //statusBarBackground = std::make_shared("DiBoxBck", Rect(-itemSize.x * 2, -100, itemSize.x * 4, 20)); - //statusBar = CGStatusBar::create(statusBarBackground); + statusBar = CGStatusBar::create(-80, -100, "radialMenu/statusBar"); for(const auto & item : items) pos = pos.include(item->pos); @@ -80,9 +58,9 @@ RadialMenu::RadialMenu(const Point & positionToCenter, CGarrisonInt * army, CGar addUsedEvents(GESTURE); } -void RadialMenu::addItem(const Point & offset, const std::string & path, const std::function& callback ) +void RadialMenu::addItem(const Point & offset, const std::string & path, const std::string & hoverText, const std::function& callback ) { - auto item = std::make_shared(path, callback); + auto item = std::make_shared(path, hoverText, callback); item->moveBy(offset); @@ -94,11 +72,6 @@ void RadialMenu::gesturePanning(const Point & initialPosition, const Point & cur } -void RadialMenu::show(Canvas & to) -{ - showAll(to); -} - void RadialMenu::gesture(bool on, const Point & initialPosition, const Point & finalPosition) { if (!on) diff --git a/client/widgets/RadialMenu.h b/client/widgets/RadialMenu.h index 10ac3229d..e9df78d06 100644 --- a/client/widgets/RadialMenu.h +++ b/client/widgets/RadialMenu.h @@ -15,44 +15,49 @@ class IImage; class CGarrisonInt; class CGarrisonSlot; -class CFilledTexture; class CGStatusBar; +struct RadialMenuConfig +{ + 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); + + Point itemPosition; + std::string imageName; + std::string hoverText; + std::function callback; +}; class RadialMenuItem : public CIntObject { + friend class RadialMenu; + std::shared_ptr image; std::shared_ptr picture; -public: std::function callback; + std::string hoverText; - RadialMenuItem(const std::string& imageName, const std::function& callback); +public: + RadialMenuItem(const std::string & imageName, const std::string & hoverText, const std::function & callback); bool isInside(const Point & position); - - void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override; - void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override; }; class RadialMenu : public CIntObject { - 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> items; - std::shared_ptr statusBarBackground; std::shared_ptr statusBar; - void addItem(const Point & offset, const std::string & path, const std::function& callback ); + void addItem(const Point & offset, const std::string & path, const std::string & hoverText, const std::function & callback); + public: - RadialMenu(const Point & positionToCenter, CGarrisonInt * army, CGarrisonSlot * slot); + RadialMenu(const Point & positionToCenter, const std::vector & menuConfig); void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override; void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override; - void show(Canvas & to) override; }; From 8c4faa24f4f5092ba7cd4739dd533fcc8f8bf181 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 17 Jul 2023 15:28:45 +0300 Subject: [PATCH 05/16] Add alpha channel to radial menu items --- Mods/vcmi/Data/radialMenu/heroMove.png | Bin 824 -> 11230 bytes Mods/vcmi/Data/radialMenu/heroSwap.png | Bin 832 -> 11759 bytes Mods/vcmi/Data/radialMenu/itemEmpty.png | Bin 517 -> 6702 bytes Mods/vcmi/Data/radialMenu/stackInfo.png | Bin 1047 -> 10450 bytes Mods/vcmi/Data/radialMenu/stackMerge.png | Bin 1032 -> 15130 bytes .../vcmi/Data/radialMenu/stackSplitDialog.png | Bin 831 -> 11596 bytes Mods/vcmi/Data/radialMenu/stackSplitEqual.png | Bin 962 -> 15275 bytes Mods/vcmi/Data/radialMenu/stackSplitOne.png | Bin 942 -> 15373 bytes Mods/vcmi/Data/radialMenu/statusBar.png | Bin 97 -> 1975 bytes client/widgets/RadialMenu.cpp | 2 +- 10 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Mods/vcmi/Data/radialMenu/heroMove.png b/Mods/vcmi/Data/radialMenu/heroMove.png index f9921a93d1cb24153bb2285cd1081e7d27b8fcd3..30fa00ce06aac0c751e3de3ca08f35f457a0ada7 100644 GIT binary patch literal 11230 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 IM6N<$f{*bO+W-In literal 824 zcmeAS@N?(olHy`uVBq!ia0vp^u0ZV1!3-q3PW-3^Qda|fLO_BL@c(``j7cZjNQ?jN z`Q)p+B95;O+PlPeN`v*!n;GA4q)(`|e10k+!bc%KNIB3=wkk{i&)uxoXOn*4&b+)M z{Qbq0dxv7qZ3%sFB=+mI^pBTQm1H=Yi;QheMA}PDU!F-^*yFf;%}fiRCp1ff{DK)6 zP5&E<{+DLqc4k)L6=q^H_-7=+%IDy!q$&^?&Y^E2Cdp;vrl2mU`8MJ?0|VnrPZ!6K z3dXlLu0}oO5OH}pH|}ohq)F5VQ~TGBkvu{`8Da}{sZ;#ne39u$XsU`_pXYP*ToFTN`Nntr3Y zhEERhA4`7+3bJvnv*XZWbGGb#_{i^A)bO%sd79(bgE2xEnM|2KH_m#TzBDE^vCy-!=E>C5cWX}k)Y!dgmFbS{de0ZH zIi)21=;E>`HBUqnURNqUS6;8fob&#`-dIcd$kg{M_wg4fJXc=r@%q3*i=cD>M@v=o)EObwpiz!DA=IW{x znTg>$j(;_?ikNs(vht~$!rYTjde#)JE}d{vGBVYF7sG_j6T|1p-kJD$Vz|_=$VU5R zOiQ&yes}NlX8f@|?pJ!M+!dZJN|ScF$k14{0m Lu6{1-oD!Mh001bkdQ@0+Qek%> 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 R@A3cu002ovPDHLkV1ncl5{Uo+ literal 832 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 Ef+&)?Y5)KL delta 492 zcmZ2y(#kSHxt{Tir;B4q1!Ix~OM_sC@BjPf|M4&BJ@`kE&xP^r9meBYfda=q{(l!1 zrm1SK>fzOJ=`E9D5ChAvfALG!O+Q+dxu$g0=I1v2&I&(g<|d@q8E{QVfBAV1$7QYL zDX+!-`Z*>sJU40!WaUX$P`<& zt?Ob2fqk8KvauAI=hP&>b~+jOV1!tBIo8Flt|ymuA%?5)0B zduK!LWkvZjw?6NEqM91-#TH|8JHh^E(e=y+C)YNc$+?9a_6Y9NuY2?OZ2zggwxyq+ zd0T7pb{QVJs~_>YDty7otb3K-9SVE9#2KSqX8i2FJ+Z#ShV#Sr13#W0Ui?Y^7U$;0 T8}(%NG5~?6tDnm{r-UW|UuEP7 diff --git a/Mods/vcmi/Data/radialMenu/stackInfo.png b/Mods/vcmi/Data/radialMenu/stackInfo.png index a19929fa2b6f4d1abb13677152d71158ed476798..32396d314b16b1a3cca0cfa8ddddb85a24d75931 100644 GIT binary patch literal 10450 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 IM6N<$f=r|Dwg3PC literal 1047 zcmeAS@N?(olHy`uVBq!ia0vp^u0ZV1!3-q3PW-54U|`G$@CgA4Lcss~*)S%ZXe~v7 z1wD?}_e6cTl=Ay_=AXM+U$3Pvrab zSsusN2JKzqD<;PF?_Tz`-4Sc1xh?8(I=I6B=go{zPlYKB*57ZWPj0aKcQ0#3i*0V4 z#>z=96KXA=pGw#=$LrJ8)H?^FuI-9EyxKp)N8!xo&_gTz^wnfI-(O5w zI>G7n*`!k&gMQr1a4;3Ryd&J&MD)te@L6rP_YTFJ+Y)oI~G4Op?pSO+j5y^KHa)1_mZmPZ!6K z3dXlLT7y1&F}Q!^W&dY!aPFf5-tzMH?D@NQ|9-qU@zvcEJjs7;53E#Kee9U#f(wR% zqKyk~xCAm;F)vlqS%X1z=7pTfSGo$;8KyV4MoNEM{%)J{{}&xId8`~A9l~z~zh`4*wN(q$ z*Wg*v^Ix%6L+97t<#r5Q{A{wxNeeO_m^Uv{jz1axY3l0LfBqexU(d_i-_zIYzQV`n zk>spTu`}n*30!p3^3k)up<)aPfzzj{H9nnsb?aB&gpA8^H!rcx%dISHxNAH2mOK;R znyH?AN0%zc{`fur?ZW!fclHnJvsrhDo!2;9`k-y?CWeB~V)Jf$6+YK1I3Fg-=CJ%7 zGmqv`<_8azqg`*Y$#w5O^kp;|V(`ib+q7>=A44AP$8u-*U3_M#>08(8j7d0@RkE+K6P_X1YI zs=9-pAFD}4^+f#CnBX?$f%*rNfTz>9IR>?y+VF)>Da6M4c~hv;iEy2%_Z==eoRLU3 z2x4bDv-4A(h*)jjEkPTN7p9$6P9+O&FDcl~RJP!9iok1!e;41)IqJx7 zb=8)CN=tE`oSY-&xYObA)H{_GcdW9e3Yw}lWCd6i^tOIo>HIYG{=}nG)$d-nR9h3I pXBCjNNQ2FBV&@6XB?o>b`!R%N&7Q7)F6*2UngGj_pw0jQ diff --git a/Mods/vcmi/Data/radialMenu/stackMerge.png b/Mods/vcmi/Data/radialMenu/stackMerge.png index a0c611a0ba1a596f6b573b05c1747a4ddec81fb7..795e73e659ef99495ec17d7dd0a5d84ec953479d 100644 GIT binary patch literal 15130 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 KMNUMnLSTX=UyR5A literal 831 zcmeAS@N?(olHy`uVBq!ia0vp^u0ZV1!3-q3PW-3^Qda|fLO_BL@c(``j7cZjNQ?jN z`Q)p+B95;O+PlPeN`v*!n;GA4q)(`|e10k+!bc%KNIB3=wkk{i&)uxoXOn*4&b+)M z{Qbq0dxv7qZ3%sFB=+mI^pBTQm1H=Yi;QheMA}PDU!F-^*yFf;%}fiRCp1ff{DK)6 zP5&E<{+DLqc4k)L6=q^H_-7=+%IDy!q$&^?&Y^E2Cdp;vrl2mU`8MJ?0|Vm+PZ!6K z3dXlLQlqpvC0rh^f8ThB^BqfhdHK!%eQpISOmZI=-@pHLPDPZG_owD%Dq2}=j@}^` zxqiuRagFq}u5zt*pK^(_ihXWijQ9)V7kx=t3hcIl4*FRu`u{~eF=6mxW}bLl;f1w< zNaUo%DXkNG{A)#~@E%jTTal*xJ9xeCf%XOq z`cEY-RGz2PbgFr&$|Am1Y}1%S-S?e3f9lk$S^H9z*RT1U;;feXWU6oO$E4_G4^L>X ze$x@Yd(!8L;SGDgx6bL`vx#p*{ef<0OZmvBFV@!a6evAcUhQ%Fz)FkDx3By>VgIt2 zlY9nHs*mfu+32?$fEs#tdt@ zO`j;Q{_vz2CeOKVLkbxFm=5 zio}z3DSws~ho1O0-FEt$?@#al@O+(~DjC9iMS0RvFWHD5by@BeI?uApIO9al9ChEU zYGsgoz4|h%wSnlvSCcjD)v_)|m}|&O^p_+r$T5(*|4PC!Qo>K^bilF8jR);N&TC)! z_44wz7rjhX4t!aGJ@v0He4Tz**;sb|yX&ffVbU+kFGz)MX;@&XmdKI;Vst07?==Bme*a diff --git a/Mods/vcmi/Data/radialMenu/stackSplitEqual.png b/Mods/vcmi/Data/radialMenu/stackSplitEqual.png index d0d376bce088abdbafb8223caf2ebf012a572a89..7cde04a1198119a3d79a17fa37bcc5b61fa1a0e3 100644 GIT binary patch literal 15275 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 literal 962 zcmeAS@N?(olHy`uVBq!ia0vp^u0ZV1!3-q3PW-3^Qda|fLO_BL@c(``j7cZjNQ?jN z`Q)p+B95;O+PlPeN`v*!n;GA4q)(`|e10k+!bc%KNIB3=wkk{i&)uxoXOn*4&b+)M z{Qbq0dxv7qZ3%sFB=+mI^pBTQm1H=Yi;QheMA}PDU!F-^*yFf;%}fiRCp1ff{DK)6 zP5&E#h=ab)X%*XcVojf<;i-v8grwx}Xwu5^F0@Ac;|wr@{)8}M@V&sJk! z$(xZ3=X#CKIXf|Vb4#B!IvL^_5f{l5*;?Yov^upS+jw!XP=tKOmI->7SjF2E#68!j zOy6x`gdIXd?nwhYU+WtmdA3X!>Z<0RkxRT z2Hu%_WkU4?Mz06^=KW%p4trwrr~TuJwy72o+OcnwAFa9a=;WJ~_N_W=Smv27^-1}n zRWwh0Qe#(g%cn)e&w?H-uFd0SMqeL+0u9i8InosR1deO>mYl=qod!Pojf z=bg7s-x(6VBZ94jaSh8Yqcx@f^^e~2|K0Di_Rr)0yO!zP67mtXh(A`s*RVM?<*a0# dw6NoO28Qa0*<1c8eeVHfJWp3Ymvv4FO#nFBf%pIb diff --git a/Mods/vcmi/Data/radialMenu/stackSplitOne.png b/Mods/vcmi/Data/radialMenu/stackSplitOne.png index 28e15c7472540c4f60b6b24ab2b0f84f74dfbb7c..dbcfe1390cfef21eed3f91a8cf2a61f2397002d7 100644 GIT binary patch literal 15373 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 literal 942 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, Point(0, 0)); pos = picture->pos; } From f3508bdfdac089dd286317153cc92b395de1ef59 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 19 Jul 2023 17:08:15 +0300 Subject: [PATCH 06/16] Show option description on hovering --- client/widgets/CGarrisonInt.cpp | 10 +++++----- client/widgets/CGarrisonInt.h | 1 - client/widgets/RadialMenu.cpp | 9 +++++++++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/client/widgets/CGarrisonInt.cpp b/client/widgets/CGarrisonInt.cpp index bbb57dda6..e4414c515 100644 --- a/client/widgets/CGarrisonInt.cpp +++ b/client/widgets/CGarrisonInt.cpp @@ -351,11 +351,11 @@ void CGarrisonSlot::gesture(bool on, const Point & initialPosition, const Point return; std::vector menuElements = { - { RadialMenuConfig::ITEM_NW, "stackMerge", "", [this](){owner->bulkMergeStacks(this);} }, - { RadialMenuConfig::ITEM_NE, "stackInfo", "", [this](){viewInfo();} }, - { RadialMenuConfig::ITEM_WW, "stackSplitOne", "", [this](){splitIntoParts(this->getGarrison(), 1); } }, - { RadialMenuConfig::ITEM_EE, "stackSplitEqual", "", [this](){owner->bulkSmartSplitStack(this);} }, - { RadialMenuConfig::ITEM_SW, "heroMove", "", [this](){owner->moveStackToAnotherArmy(this);} }, + { RadialMenuConfig::ITEM_NW, "stackMerge", "Merge same units", [this](){owner->bulkMergeStacks(this);} }, + { RadialMenuConfig::ITEM_NE, "stackInfo", "Show unit information", [this](){viewInfo();} }, + { RadialMenuConfig::ITEM_WW, "stackSplitOne", "Split off single unit", [this](){splitIntoParts(this->getGarrison(), 1); } }, + { RadialMenuConfig::ITEM_EE, "stackSplitEqual", "Split unit equally", [this](){owner->bulkSmartSplitStack(this);} }, + { RadialMenuConfig::ITEM_SW, "heroMove", "Move unit to another army", [this](){owner->moveStackToAnotherArmy(this);} }, }; GH.windows().createAndPushWindow(pos.center(), menuElements); diff --git a/client/widgets/CGarrisonInt.h b/client/widgets/CGarrisonInt.h index b991d4f31..b77d6300b 100644 --- a/client/widgets/CGarrisonInt.h +++ b/client/widgets/CGarrisonInt.h @@ -106,7 +106,6 @@ public: bool smallIcons; ///< true - 32x32 imgs, false - 58x64 bool removableUnits; ///< player Can remove units from up - bool twoRows; ///< slots Will be placed in 2 rows ESlotsLayout layout; diff --git a/client/widgets/RadialMenu.cpp b/client/widgets/RadialMenu.cpp index 84e8aeb9e..23db1a3fa 100644 --- a/client/widgets/RadialMenu.cpp +++ b/client/widgets/RadialMenu.cpp @@ -69,7 +69,16 @@ void RadialMenu::addItem(const Point & offset, const std::string & path, const s void RadialMenu::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) { + GH.statusbar()->clear(); + for(const auto & item : items) + { + if (item->isInside(currentPosition)) + { + GH.statusbar()->write(item->hoverText); + break; + } + } } void RadialMenu::gesture(bool on, const Point & initialPosition, const Point & finalPosition) From 5b2ac27e9048f362231bae95042af32838c03e46 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 19 Jul 2023 17:27:17 +0300 Subject: [PATCH 07/16] Fix slot positioning --- client/widgets/CGarrisonInt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/widgets/CGarrisonInt.cpp b/client/widgets/CGarrisonInt.cpp index e4414c515..95e103563 100644 --- a/client/widgets/CGarrisonInt.cpp +++ b/client/widgets/CGarrisonInt.cpp @@ -526,7 +526,7 @@ void CGarrisonInt::createSlots() for(int j = 0; j < 7; j++) { if(!garrisonSlots[j]) - garrisonSlots[j] = std::make_shared(this, offset.x + (j*distance), offset.x, SlotID(j), i, nullptr); + garrisonSlots[j] = std::make_shared(this, offset.x + (j*distance), offset.y, SlotID(j), i, nullptr); if(layout == ESlotsLayout::TWO_ROWS && j >= 4) { From a45a0d1c403d9851663de49f8a6ff6f734ae4c89 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 19 Jul 2023 17:36:05 +0300 Subject: [PATCH 08/16] Activate nearest radial menu item, even if not hovered --- client/widgets/RadialMenu.cpp | 49 +++++++++++++++++------------------ client/widgets/RadialMenu.h | 3 +-- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/client/widgets/RadialMenu.cpp b/client/widgets/RadialMenu.cpp index 23db1a3fa..f0f056790 100644 --- a/client/widgets/RadialMenu.cpp +++ b/client/widgets/RadialMenu.cpp @@ -28,13 +28,6 @@ RadialMenuItem::RadialMenuItem(const std::string & imageName, const std::string pos = picture->pos; } -bool RadialMenuItem::isInside(const Point & position) -{ - Point localPosition = position - pos.topLeft(); - - return !image->isTransparent(localPosition); -} - RadialMenu::RadialMenu(const Point & positionToCenter, const std::vector & menuConfig) { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; @@ -67,34 +60,40 @@ void RadialMenu::addItem(const Point & offset, const std::string & path, const s items.push_back(item); } -void RadialMenu::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) +std::shared_ptr RadialMenu::findNearestItem(const Point & cursorPosition) const { - GH.statusbar()->clear(); + int bestDistance = std::numeric_limits::max(); + std::shared_ptr bestItem; for(const auto & item : items) { - if (item->isInside(currentPosition)) + Point vector = item->pos.center() - cursorPosition; + + if (vector.length() < bestDistance) { - GH.statusbar()->write(item->hoverText); - break; + bestDistance = vector.length(); + bestItem = item; } } + + assert(bestItem); + return bestItem; +} + +void RadialMenu::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) +{ + auto item = findNearestItem(currentPosition); + GH.statusbar()->write(item->hoverText); } void RadialMenu::gesture(bool on, const Point & initialPosition, const Point & finalPosition) { - 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); + if (on) + return; - for(const auto & item : items) - { - if (item->isInside(finalPosition)) - { - item->callback(); - break; - } - } - } + auto item = findNearestItem(finalPosition); + + // we need to close this window first so if action spawns a new window it won't be closed instead + GH.windows().popWindows(1); + item->callback(); } diff --git a/client/widgets/RadialMenu.h b/client/widgets/RadialMenu.h index e9df78d06..a0e4c0977 100644 --- a/client/widgets/RadialMenu.h +++ b/client/widgets/RadialMenu.h @@ -43,8 +43,6 @@ class RadialMenuItem : public CIntObject public: RadialMenuItem(const std::string & imageName, const std::string & hoverText, const std::function & callback); - - bool isInside(const Point & position); }; class RadialMenu : public CIntObject @@ -55,6 +53,7 @@ class RadialMenu : public CIntObject void addItem(const Point & offset, const std::string & path, const std::string & hoverText, const std::function & callback); + std::shared_ptr findNearestItem(const Point & cursorPosition) const; public: RadialMenu(const Point & positionToCenter, const std::vector & menuConfig); From cb28a90a3b51eca8b77793afdc163e8bda68dd2b Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 19 Jul 2023 18:08:58 +0300 Subject: [PATCH 09/16] Create items only if action is possible --- client/widgets/CGarrisonInt.cpp | 23 ++++++++++++++++++----- client/widgets/RadialMenu.cpp | 9 ++++++--- client/widgets/RadialMenu.h | 3 ++- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/client/widgets/CGarrisonInt.cpp b/client/widgets/CGarrisonInt.cpp index 95e103563..57042cb81 100644 --- a/client/widgets/CGarrisonInt.cpp +++ b/client/widgets/CGarrisonInt.cpp @@ -350,14 +350,27 @@ void CGarrisonSlot::gesture(bool on, const Point & initialPosition, const Point if (!on) return; + if (!myStack) + return; + + bool stackExists = myStack != nullptr; + bool hasSameUnit = stackExists && !owner->army(upg)->getCreatureSlots(myStack->type, ID).empty(); + bool hasEmptySlots = stackExists && owner->army(upg)->getFreeSlot() != SlotID(); + bool exchangeMode = stackExists && owner->upperArmy() && owner->lowerArmy(); + std::vector menuElements = { - { RadialMenuConfig::ITEM_NW, "stackMerge", "Merge same units", [this](){owner->bulkMergeStacks(this);} }, - { RadialMenuConfig::ITEM_NE, "stackInfo", "Show unit information", [this](){viewInfo();} }, - { RadialMenuConfig::ITEM_WW, "stackSplitOne", "Split off single unit", [this](){splitIntoParts(this->getGarrison(), 1); } }, - { RadialMenuConfig::ITEM_EE, "stackSplitEqual", "Split unit equally", [this](){owner->bulkSmartSplitStack(this);} }, - { RadialMenuConfig::ITEM_SW, "heroMove", "Move unit to another army", [this](){owner->moveStackToAnotherArmy(this);} }, + { RadialMenuConfig::ITEM_NW, hasSameUnit, "stackMerge", "Merge same units", [this](){owner->bulkMergeStacks(this);} }, + { RadialMenuConfig::ITEM_NE, stackExists, "stackInfo", "Show unit information", [this](){viewInfo();} }, + { RadialMenuConfig::ITEM_WW, hasEmptySlots, "stackSplitOne", "Split off single unit", [this](){splitIntoParts(this->getGarrison(), 1); } }, + { RadialMenuConfig::ITEM_EE, hasEmptySlots, "stackSplitEqual", "Split unit equally", [this](){owner->bulkSmartSplitStack(this);} }, + { RadialMenuConfig::ITEM_SW, exchangeMode, "heroMove", "Move unit to another army", [this](){owner->moveStackToAnotherArmy(this);} }, }; + // additional options to consider: + // - Ctrl + Shift + Click - splits from current stack, stacks of 1 in all free slots + // - Alt + Shift + Click - dismiss stack with confirmation window + // Split unit (same as button) + GH.windows().createAndPushWindow(pos.center(), menuElements); } diff --git a/client/widgets/RadialMenu.cpp b/client/widgets/RadialMenu.cpp index f0f056790..217e523ea 100644 --- a/client/widgets/RadialMenu.cpp +++ b/client/widgets/RadialMenu.cpp @@ -33,13 +33,13 @@ RadialMenu::RadialMenu(const Point & positionToCenter, const std::vectorpos.dimensions(); moveBy(-itemSize / 2); for (auto const & item : menuConfig) - addItem(item.itemPosition, item.imageName, item.hoverText, item.callback); + addItem(item.itemPosition, item.enabled, item.imageName, item.hoverText, item.callback); statusBar = CGStatusBar::create(-80, -100, "radialMenu/statusBar"); @@ -51,8 +51,11 @@ RadialMenu::RadialMenu(const Point & positionToCenter, const std::vector& callback ) +void RadialMenu::addItem(const Point & offset, bool enabled, const std::string & path, const std::string & hoverText, const std::function& callback ) { + if (!enabled) + return; + auto item = std::make_shared(path, hoverText, callback); item->moveBy(offset); diff --git a/client/widgets/RadialMenu.h b/client/widgets/RadialMenu.h index a0e4c0977..f7ce5ad07 100644 --- a/client/widgets/RadialMenu.h +++ b/client/widgets/RadialMenu.h @@ -27,6 +27,7 @@ struct RadialMenuConfig static constexpr Point ITEM_SE = Point(+40, +70); Point itemPosition; + bool enabled; std::string imageName; std::string hoverText; std::function callback; @@ -51,7 +52,7 @@ class RadialMenu : public CIntObject std::shared_ptr statusBar; - void addItem(const Point & offset, const std::string & path, const std::string & hoverText, const std::function & callback); + void addItem(const Point & offset, bool enabled, const std::string & path, const std::string & hoverText, const std::function & callback); std::shared_ptr findNearestItem(const Point & cursorPosition) const; public: From 816adecca0bc47813aa6720921ce324cac5ead1c Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 19 Jul 2023 18:31:24 +0300 Subject: [PATCH 10/16] Added "split stack" action to wheel --- client/widgets/CGarrisonInt.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/client/widgets/CGarrisonInt.cpp b/client/widgets/CGarrisonInt.cpp index 57042cb81..63efd8650 100644 --- a/client/widgets/CGarrisonInt.cpp +++ b/client/widgets/CGarrisonInt.cpp @@ -347,30 +347,30 @@ void CGarrisonSlot::clickPressed(const Point & cursorPosition) void CGarrisonSlot::gesture(bool on, const Point & initialPosition, const Point & finalPosition) { - if (!on) + if(!on) return; - if (!myStack) + if(!myStack) return; + const auto * otherArmy = upg == EGarrisonType::UPPER ? owner->lowerArmy() : owner->upperArmy(); + bool stackExists = myStack != nullptr; bool hasSameUnit = stackExists && !owner->army(upg)->getCreatureSlots(myStack->type, ID).empty(); - bool hasEmptySlots = stackExists && owner->army(upg)->getFreeSlot() != SlotID(); + bool hasOwnEmptySlots = stackExists && owner->army(upg)->getFreeSlot() != SlotID(); bool exchangeMode = stackExists && owner->upperArmy() && owner->lowerArmy(); + bool hasOtherEmptySlots = exchangeMode && otherArmy->getFreeSlot() != SlotID(); + bool hasAnyEmptySlots = hasOtherEmptySlots || hasOwnEmptySlots; std::vector menuElements = { { RadialMenuConfig::ITEM_NW, hasSameUnit, "stackMerge", "Merge same units", [this](){owner->bulkMergeStacks(this);} }, { RadialMenuConfig::ITEM_NE, stackExists, "stackInfo", "Show unit information", [this](){viewInfo();} }, - { RadialMenuConfig::ITEM_WW, hasEmptySlots, "stackSplitOne", "Split off single unit", [this](){splitIntoParts(this->getGarrison(), 1); } }, - { RadialMenuConfig::ITEM_EE, hasEmptySlots, "stackSplitEqual", "Split unit equally", [this](){owner->bulkSmartSplitStack(this);} }, - { RadialMenuConfig::ITEM_SW, exchangeMode, "heroMove", "Move unit to another army", [this](){owner->moveStackToAnotherArmy(this);} }, + { RadialMenuConfig::ITEM_WW, hasOwnEmptySlots, "stackSplitOne", "Split off single unit", [this](){splitIntoParts(this->getGarrison(), 1); } }, + { RadialMenuConfig::ITEM_EE, hasOwnEmptySlots, "stackSplitEqual", "Split unit equally", [this](){owner->bulkSmartSplitStack(this);} }, + { RadialMenuConfig::ITEM_SW, hasOtherEmptySlots, "heroMove", "Move unit to another army", [this](){owner->moveStackToAnotherArmy(this);} }, + { RadialMenuConfig::ITEM_SE, hasAnyEmptySlots, "heroSwap", "Split unit to another slot", [this](){ owner->selectSlot(this); owner->splitClick();} }, }; - // additional options to consider: - // - Ctrl + Shift + Click - splits from current stack, stacks of 1 in all free slots - // - Alt + Shift + Click - dismiss stack with confirmation window - // Split unit (same as button) - GH.windows().createAndPushWindow(pos.center(), menuElements); } From e2ad8bbf583f4d82d95111ec9388ed013b5ec3d8 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 19 Jul 2023 19:19:21 +0300 Subject: [PATCH 11/16] Added initial version of selection highlight --- Mods/vcmi/Data/radialMenu/heroMove.png | Bin 11230 -> 483 bytes Mods/vcmi/Data/radialMenu/heroSwap.png | Bin 11759 -> 493 bytes Mods/vcmi/Data/radialMenu/itemEmpty.png | Bin 6702 -> 1355 bytes Mods/vcmi/Data/radialMenu/itemInactive.png | Bin 0 -> 676 bytes Mods/vcmi/Data/radialMenu/stackInfo.png | Bin 10450 -> 628 bytes Mods/vcmi/Data/radialMenu/stackMerge.png | Bin 15130 -> 678 bytes .../vcmi/Data/radialMenu/stackSplitDialog.png | Bin 11596 -> 490 bytes Mods/vcmi/Data/radialMenu/stackSplitEqual.png | Bin 15275 -> 934 bytes Mods/vcmi/Data/radialMenu/stackSplitOne.png | Bin 15373 -> 914 bytes client/widgets/RadialMenu.cpp | 33 ++++++++++++++---- client/widgets/RadialMenu.h | 9 +++-- 11 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 Mods/vcmi/Data/radialMenu/itemInactive.png diff --git a/Mods/vcmi/Data/radialMenu/heroMove.png b/Mods/vcmi/Data/radialMenu/heroMove.png index 30fa00ce06aac0c751e3de3ca08f35f457a0ada7..eca9a22e802ebda54e1cacf42877623756988008 100644 GIT binary patch delta 468 zcmcZ?{+M}!WIZzj14Gw|AGJWrDZnSh6-fWTpZ))u4~V><`Tt(#|GOFg@235~2jph` zznl91PVE0XasTf`|G$^?|3UWuds+W4+5Eqk{QqXi|GO#w@1;xUSgZw_B2p6M7tFx$ z=06I!{{Q#8?f0x07#M9lT^vIy>KWfof9Q4CL4a+4sg&=QsMWvzt=IDSIKh8gW2~3% z%>A-$w(GXrC4;;-WuL;*E!JGJYSto70vPo{D*ynDLiOZihrV|6jfnI>9I?vC~I z3Qua=@H+Q-$IWE;c79I9#K)6D`Ru=jH$?V%hfNeq5Yn)or^qTR7{`fvG7Bq`a+hrC!&5eZ!YG%H=Md>6NgHQ z%A`=ctqnacn@%}eIfWHwhOm7$FN)dZHFYhMudQfA=tG;en?dNk;O!3S8v?-&mdlW21i&!N^lb}s2Mz6{an^LB{Ts5h~Mf= literal 11230 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 IM6N<$f{*bO+W-In diff --git a/Mods/vcmi/Data/radialMenu/heroSwap.png b/Mods/vcmi/Data/radialMenu/heroSwap.png index 5536b94ab40a3b9a2bcda7488c41dd8809b08ce3..e1fc20bf04ed99587c48ef9efca90ab28eaf4f62 100644 GIT binary patch delta 478 zcmV<40U`eHTkQjo8Gi!+004@}_|JF?Z-)sNhY5(47|J`W+ z-DdyZYyaPB|J`N(++F|NUjN)%|K4K%;A{WhYX8za|K4N&*;N1CWdGi08*DhO0000K zbW%=J008R$|NsC0|NsC0|NsC0|J48ZdxVW#0003-Nkl&5&(P}U)Gc(1IhJZOg@E?H$#XAj4v<;o*wooR4f zTB=A-(6x+9R)5j+#en0ISNhu?UUcRaj!RZK{?y+jX@=vHRe&aGf`rj4xn!Ge{ULV4 zE&Z0P($kZ=q!S#MymA?Fv?G&z771#@O}pfkhWGwV`hYQz2>QSigk?;!iq3o!5BzZIRdBAf?TpnXYRmp$to%LidR%qkycf7ozhu?%8hPX$}3V@ z2{xV20xoto{@qNL-T}9NxwGVQ$7Yv%Dh0;ImpdyqK>VM}oh6q${>J5=HP*k(H&%=Y U<1Z{h001bkdQ@0+Qek%> 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 R@A3cu002ovPDHLkV1ncl5{Uo+ diff --git a/Mods/vcmi/Data/radialMenu/itemEmpty.png b/Mods/vcmi/Data/radialMenu/itemEmpty.png index 9d3ee0870fb72c5dc7e8e662e44aeafbfa8d928b..731660f73ab7e2f82c08ec13c328fcb4aaeb3edc 100644 GIT binary patch literal 1355 zcmXX_3pCSv9G{Kkl}A)wiEc!=aUvAueVZbi&2uyF=6D=&%MG_txyg+aS68~0x~kK> zCfP3Idd|j}78W-1c0HyR%{JWJpStJ#{@?%ie9!mu`F}pY&-v$F_Vrd%)>DQ+AZizW z@IZjKCwTn!!a%*plx9I7a>C0O19pckm6zCWPz$}dEk3^gb-+YN*v9*~C00cHOTRuc zl1mE~y^CHSjtRMB43>j@j(~k|-crzutO&_y+;CG+X2QvvNj6|pGI|9tOm$-b!#p#* zEZ5o0SlP-{^>MDt93vdCjkSiX4aJB!(bNhbe@{bScYO*G4*2QS{_m)P%L9=B2pCc# zPh5?%1ggN9?ZHY%uS|DiiV047Itm4u4wGFNW*uU@E%ft9tdJd9^U%xP>0oWC_v&C2 zm;*ha5p!c1HHc{RvAAF}Kn^wszj_3Md2OM2*X=b_VYxrr@!LbcSr&8Sp51q~v(j+1 z(W)$T18{%>j@n-OhWVMaKL6kE&|iT+C)$iO2LaS9BYYIt8ID;Qh#Y7LNXA*P8&Kl+ zal4us;ouUAZaNto>@Cc49RE9{=65gQU=+~Cs71sCnS#%4@$jJHL(MjMcrXW-1B4AU z?D}QaA~;kupar+lOGZw0VSsE71r0*s(t@-dC zfz#2!S=BB1_<5|mdrYi^7f5HA%vleHR5;kqUNL^MzQ*n1uJ21E(fPgw$JJtyV1_v(_3B+2>|hhQYZ+5Lk}WA?>nD>x-RX+> zDVctg1Ur6b*`m(>t!kR|yYBdDyJiK<7+HL%IJE@=fyQ6(a1BV86OP_`IET}gpE{GY z6UC#fQZf>Flti9-vtZx|`|v**1Se93^=0yFN_}HJ1?npl8p^w6-)c1^n`!w}y6Ij` zD}r~M;22}{k%0-=zjI6TtIIR0mQv}aOi}*XWKNE|L1q@=)myUYF7x>9yn;M6brl8E znVJ1s#YG%%^H+IFpHj|;hTQOqMcZ#$o-sRp)LCt@m-YQ|OAD{`dp>ZLwRJ*Ba8uaR z0ArK*`)DlI3xz5d;7&c#v}t(W8CrMLDm4bxSn=Y(gQ}{7rvgyW2R){FZ<-YRQxi(y zWqO~g#|L@;SwsWYAwwBv#JrmHtB&8G_QiR*{yv>li*7+ntgDMkzE{3( zN`$@cLE{vS6uZ*BKCHV{^T%B7_)Q}nrjSzYubuR_o%L{Pr_5+5GAtWautOs`-pSO# zC6=?=uKP!HZ0c>lsmJ4}Fw-7}>SKKogS)}D&c9^qK&CacDwH}W^bP6g=xQFOC>qIx zMkmMOvpc>hZn-$nK8cv;Gfv+~J5;c*T&{3YdRvg2h<`{l$R{wD9>K)K+8RxVKgyv> zRqHCG#AI7NYjzERKVPz4Hpi|&U|Dt6+2d+SkLpPRh_gO*4}Z%C{bKqW>xRqu4=T~naR2}S literal 6702 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 Ef+&)?Y5)KL diff --git a/Mods/vcmi/Data/radialMenu/itemInactive.png b/Mods/vcmi/Data/radialMenu/itemInactive.png new file mode 100644 index 0000000000000000000000000000000000000000..90dbde5692500818dc17500d4d5fc971fdc41387 GIT binary patch literal 676 zcmeAS@N?(olHy`uVBq!ia0vp^u0ZV1!3HGvigEZeFfe6%x;TbZFuuLR=&lnlar|T1 zwoRI5Y9Rp|Tt#mv{ACsmaM00U)p8J8;h?+ZfP=J$Mo`zZEvDAzy?@s;Uf;Q+`u&@d zXJ>5e?eZUR%VnSc5)sFE+2W|WpJ6Xkk){0YipD>WSZ{xrID6`bE;c0&A3>=ISI(Jp z+as@BY${pMYL)g-F|Hf z?w7;lp5Y{P<%po#gj-WLcCw$~uR5T1%H!;>jV%m{N16l}r(MYZEw%OmkNgCY9|t70 z%+@^;%z4N;$;to5Ar7JY4A%;}IVL3u=51_iT(a(>5%2^tZxBEUYNdJG<{>_u4S%RT4iY+Mt9oiv*F2|*f;^*%^SHWs8^4*%Xx}w?Q z4R5uCbNI7Fxza5%H4OpBZEQ+vRo5(dcq02UTUdb8qt6?g(>=IsliBU+N?3g!s-)`Q z@Hc2>TCq_y?>vq^TlU0x4${NqbvX42iF7AkEPBY vt$Fk4<{r0=-10kP7)2jzFBZLh{l)*47C*y6r@ZI~ralHwS3j3^P6VqrjwS#e2gox)GZ&|T$#C0A?41J0x_xP z1Py75nSxVdS>}>POZG@BCOYQsV~!G*k3UpOEIeHa&p+RH4x9%ZSNpg5D8VZOvJ$8Y zAWDEx09gT~3Vcj^75EfD6aygz>N>nn0lE@qFTtV|yd^leQh>S!v>ZrgnFy#d@JN7U zMk}%*>keZyhn3f~EVx+Kgmy>$|Aj%s&2PZeBo>S{Gk6E6nq#p>ht&remp zarGI=9bU|VrZ~7A+lUUj^-dz@)@-?p^ zW#CMuvsW6cJVGIjHf z+Ws>^zWa6CqdifVFNRPPiG;`>3w54~r72k*ttn2wds&A}e&rB6W1pFie_5&)o~tJx&5(-kVH+WlrjP-4$G|4@Gb9q`W{q5w-TMcxBvwxV literal 10450 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 IM6N<$f=r|Dwg3PC diff --git a/Mods/vcmi/Data/radialMenu/stackMerge.png b/Mods/vcmi/Data/radialMenu/stackMerge.png index 795e73e659ef99495ec17d7dd0a5d84ec953479d..b14628f4fb7a5dc85a4f7186b0ba7b681e9d9357 100644 GIT binary patch delta 665 zcmV;K0%rZ1cBTc88Gi!+004@}_|JF?Z-)sNhY5(47|J`W+ z-DdyZYyaPB|J`N(++F|NUjN)%|K4K%;A{WhYX8za|K4N&*;N1CWdGi0|Jzpo-)8^b zX#ePB|L1T2;cWlfO8@F`|KDc~lh>#K0013yQchC<0PO$&|9}7g|NsC0|NsC0|JVQf z|NsC0|NsC0>gVa%#Q*>S+et)0RCod0mW8t0FcbxkdO~t39P|JGWzo|+u&LZp>Af9z zkj>7OQ7V&EPfAL)oh4A$N%33VAn`|aqtGcdDm%~gR5?ibBN8h+AypXZZ%rFw{TZko zg!S4hv;HojMSs5WMrA^aZ$@$JZ|w9lLZc_pUI#B^A*d~ZWe&TM%Nf>ERQxtR7eHE6 zVy*Aqd*Oo+)}r$9NBd~o2O+FQMas6fvc*dhYf%Y7wzVmoCD5W`e_yw3`y__7sKkK0 zAfX1c*mAbHBG9msb+#?p7l~mlDlzU>7JwQa7u(l&)_;NSN7lHKWebNvjVm{0TL@`X z`6!*9pCHzv5*)rEhP9|v^SUedM!!OH$4cY%nXse6nPP-1CwdMGxnG7;(2U4t@4RYbwh2k#{RP+F7eAZEsI4?pE5#?%P$B zZa7Y!aeucmdpZu?s)|Onvm4m0G@e_H;tJofuv>X{*MDxt4lDo&Vkn53{+qr6j(xF+ zZQw)TP5vv^idLYN+ZCe5D|6Iz#Jf@Ba-X3lm%C9Do5ZMb+ZZ+FVWB3MyHS(c3tE}C z@EJ9=(Dqy9Ud#WN*UP<@{&oHxZvQdwuloV^=n@feu1)5E00000NkvXXu0mjfGSXs& literal 15130 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 KMNUMnLSTX=UyR5A diff --git a/Mods/vcmi/Data/radialMenu/stackSplitEqual.png b/Mods/vcmi/Data/radialMenu/stackSplitEqual.png index 7cde04a1198119a3d79a17fa37bcc5b61fa1a0e3..b9582f5497c4d14a224b99d5b1c5a77a503c1ea8 100644 GIT binary patch delta 913 zcmV;C18)4QccurBBYy*JNkl*zQnj{i+qP}nw$in>&06$s zkLt`0zMOsAGdU+tUcG#|g?AeXQZCk01rl;D0gOM_qQCERUARF z_ELxAy{hT|PRL;-={_~nA0vz~+@Gxv#1s!CgP+$;;u&AQI)B{VCrY&?A4d9>(u!|e zc2`MszKNLSNS3W!xMz-(b3MJOerko+u@>76H z7m%&dpMP;ECW!)m4Cuk@>3{-Mx`1qrwuBYo{vFD?u4zF*DqTRfp8+cZ^Jsxe7m%${ z?=UL@fPz%IfNWo4Rs;YAsdRy4o?=!60EMV@fn@Z3%!&Y@AeAn#f66V$ieR7sl`a7# z##j*)6rj=ty3ZBJieR7sl`i4lou{k_1`1H=0)I+5MOhIH6rj=t#+0Lg6@ftkDqTb= z2MH^Jf&x^!2$bD~6~RFPDqUcp-A-5$7!;t=C7^5qtOyJWV$c8s?Ha;Cqo4o=4FY93 z;Gl(VpEtD#aL~dAMb8uR=Lp)5)~J~&Udq|Y*cv@W6bupj=6iblzW~A$WD^`EKpom4iKZQfIOs~>p-;x+YSdD z>#61;fWb=H8r2w&AA&RO)B|FM3y$?fos&rb93M&*Sug~QH`b`~g2oL2s_~zflBEs- naI8_qq`?pXM;A;Ga`_JVAHL`|Vb_QN015yANkvXXu0mjfrS6#+ literal 15275 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 diff --git a/Mods/vcmi/Data/radialMenu/stackSplitOne.png b/Mods/vcmi/Data/radialMenu/stackSplitOne.png index dbcfe1390cfef21eed3f91a8cf2a61f2397002d7..a1945631a20dabd61219b08724ae06cbee750920 100644 GIT binary patch delta 892 zcmV-?1B3jHc#;Q@BYy)~Nkl*@Cu`fbZQHhOYm&8X-gRoK zYmj+oah|HibG!4tIye0dGTB)E#HhS9gCT(N`&8)HWflx~+v*bG$1)v|826QpabKoO zNBFTy{xumKMpXM$L${IcVZ?ZD9ekVoKvI0ZZisI`{ih?`K7RqQFKQS-y>0>Sn-2)Q z4XfJX<4~OG0JhbUU`$*)7NffnjFBs%Vs&qV@p6$Ds|FB^ohyc7)DVKU=bEs@=uy;j zA_4a*0)pj zc0mpIHiHWav>qK`-^y!MGum^D79grnNvr_eb#{_z!~ZV;IDpN0}h ztfQ0vM62%-nDrlo5@{@9u}j0d`Hx7<8h~P>((uhgQi^KqZ9nHQYjC1<^G1wQ8lb%4 zFlz?|mwzI(UabB|Vb%@`E=6#?SS=K0?V#XN1lNmEA4$yGLBXX6tQV`^aG14&f=dxp z?~XnMW*rR$l_I#_sK+E`?V!L?1lJpVm%^;0q2N-4)r-|PD9kzx1(71OUaXFgn6-lf zOA%TxMqeT^YX=3CBD`L#I?MPTEg(gBy%>Fh5q}CGMR>hfP5Evkn3Lr&z zy%@cd5egthc)eK8&yoQt!t2GV4UA9#DZ=Z;>Q#(T04c)j#p7ZNhGnfko0UR;99{~)qHH1d> zB6S!q-D=aW1Y@LIm)xFfOau`XqgpeJgCsSszBx-e2;jK7CIm3JT1u>HK-Ve+zqC`E zD;)%I#IXG)69F7Cx*``0g84?QD#J2w5TwT4F3yz>0ytt-VKx{9aCAPFv3v#Vb-w8J S5sSb80000h001@hdQ@0+Qek%> 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 diff --git a/client/widgets/RadialMenu.cpp b/client/widgets/RadialMenu.cpp index 217e523ea..04f798a56 100644 --- a/client/widgets/RadialMenu.cpp +++ b/client/widgets/RadialMenu.cpp @@ -23,9 +23,19 @@ RadialMenuItem::RadialMenuItem(const std::string & imageName, const std::string { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - image = IImage::createFromFile("radialMenu/" + imageName, EImageBlitMode::COLORKEY); - picture = std::make_shared(image, Point(0, 0)); - pos = picture->pos; + inactiveImage = std::make_shared("radialMenu/itemInactive", Point(0, 0)); + selectedImage = std::make_shared("radialMenu/itemEmpty", Point(0, 0)); + + iconImage = std::make_shared("radialMenu/" + imageName, Point(0, 0)); + + pos = selectedImage->pos; + selectedImage->setEnabled(false); +} + +void RadialMenuItem::setSelected(bool selected) +{ + selectedImage->setEnabled(selected); + inactiveImage->setEnabled(!selected); } RadialMenu::RadialMenu(const Point & positionToCenter, const std::vector & menuConfig) @@ -33,10 +43,10 @@ RadialMenu::RadialMenu(const Point & positionToCenter, const std::vectorpos.dimensions(); + Point itemSize = Point(70, 80); moveBy(-itemSize / 2); + pos.w = itemSize.x; + pos.h = itemSize.y; for (auto const & item : menuConfig) addItem(item.itemPosition, item.enabled, item.imageName, item.hoverText, item.callback); @@ -87,6 +97,17 @@ void RadialMenu::gesturePanning(const Point & initialPosition, const Point & cur { auto item = findNearestItem(currentPosition); GH.statusbar()->write(item->hoverText); + + if (item != selectedItem) + { + if (selectedItem) + selectedItem->setSelected(false); + + item->setSelected(true); + selectedItem = item; + + GH.windows().totalRedraw(); + } } void RadialMenu::gesture(bool on, const Point & initialPosition, const Point & finalPosition) diff --git a/client/widgets/RadialMenu.h b/client/widgets/RadialMenu.h index f7ce5ad07..a3c648367 100644 --- a/client/widgets/RadialMenu.h +++ b/client/widgets/RadialMenu.h @@ -37,13 +37,16 @@ class RadialMenuItem : public CIntObject { friend class RadialMenu; - std::shared_ptr image; - std::shared_ptr picture; + std::shared_ptr iconImage; + std::shared_ptr selectedImage; + std::shared_ptr inactiveImage; std::function callback; std::string hoverText; public: RadialMenuItem(const std::string & imageName, const std::string & hoverText, const std::function & callback); + + void setSelected(bool selected); }; class RadialMenu : public CIntObject @@ -52,6 +55,8 @@ class RadialMenu : public CIntObject std::shared_ptr statusBar; + std::shared_ptr selectedItem; + void addItem(const Point & offset, bool enabled, const std::string & path, const std::string & hoverText, const std::function & callback); std::shared_ptr findNearestItem(const Point & cursorPosition) const; From 3a3306863a859c4c607dd5228fe8c3173a91ab7f Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Fri, 21 Jul 2023 15:46:49 +0300 Subject: [PATCH 12/16] Moved new texts to config --- Mods/vcmi/config/vcmi/english.json | 7 +++++++ client/widgets/CGarrisonInt.cpp | 12 ++++++------ client/widgets/RadialMenu.cpp | 5 ++++- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Mods/vcmi/config/vcmi/english.json b/Mods/vcmi/config/vcmi/english.json index 890101689..8b0d07ea3 100644 --- a/Mods/vcmi/config/vcmi/english.json +++ b/Mods/vcmi/config/vcmi/english.json @@ -29,6 +29,13 @@ "vcmi.capitalColors.5" : "Purple", "vcmi.capitalColors.6" : "Teal", "vcmi.capitalColors.7" : "Pink", + + "vcmi.radialWheel.mergeSameUnit" : "Merge same creatures", + "vcmi.radialWheel.showUnitInformation" : "Show creature information", + "vcmi.radialWheel.splitSingleUnit" : "Split off single creature", + "vcmi.radialWheel.splitUnitEqually" : "Split creaturess equally", + "vcmi.radialWheel.moveUnit" : "Move creatures to another army", + "vcmi.radialWheel.splitUnit" : "Split creature to another slot", "vcmi.mainMenu.tutorialNotImplemented" : "Sorry, tutorial is not implemented yet\n", "vcmi.mainMenu.highscoresNotImplemented" : "Sorry, high scores menu is not implemented yet\n", diff --git a/client/widgets/CGarrisonInt.cpp b/client/widgets/CGarrisonInt.cpp index 63efd8650..21c2450fc 100644 --- a/client/widgets/CGarrisonInt.cpp +++ b/client/widgets/CGarrisonInt.cpp @@ -363,12 +363,12 @@ void CGarrisonSlot::gesture(bool on, const Point & initialPosition, const Point bool hasAnyEmptySlots = hasOtherEmptySlots || hasOwnEmptySlots; std::vector menuElements = { - { RadialMenuConfig::ITEM_NW, hasSameUnit, "stackMerge", "Merge same units", [this](){owner->bulkMergeStacks(this);} }, - { RadialMenuConfig::ITEM_NE, stackExists, "stackInfo", "Show unit information", [this](){viewInfo();} }, - { RadialMenuConfig::ITEM_WW, hasOwnEmptySlots, "stackSplitOne", "Split off single unit", [this](){splitIntoParts(this->getGarrison(), 1); } }, - { RadialMenuConfig::ITEM_EE, hasOwnEmptySlots, "stackSplitEqual", "Split unit equally", [this](){owner->bulkSmartSplitStack(this);} }, - { RadialMenuConfig::ITEM_SW, hasOtherEmptySlots, "heroMove", "Move unit to another army", [this](){owner->moveStackToAnotherArmy(this);} }, - { RadialMenuConfig::ITEM_SE, hasAnyEmptySlots, "heroSwap", "Split unit to another slot", [this](){ owner->selectSlot(this); owner->splitClick();} }, + { RadialMenuConfig::ITEM_NW, hasSameUnit, "stackMerge", "vcmi.radialWheel.mergeSameUnit", [this](){owner->bulkMergeStacks(this);} }, + { RadialMenuConfig::ITEM_NE, stackExists, "stackInfo", "vcmi.radialWheel.showUnitInformation", [this](){viewInfo();} }, + { RadialMenuConfig::ITEM_WW, hasOwnEmptySlots, "stackSplitOne", "vcmi.radialWheel.splitSingleUnit", [this](){splitIntoParts(this->getGarrison(), 1); } }, + { RadialMenuConfig::ITEM_EE, hasOwnEmptySlots, "stackSplitEqual", "vcmi.radialWheel.splitUnitEqually", [this](){owner->bulkSmartSplitStack(this);} }, + { RadialMenuConfig::ITEM_SW, hasOtherEmptySlots, "heroMove", "vcmi.radialWheel.moveUnit", [this](){owner->moveStackToAnotherArmy(this);} }, + { RadialMenuConfig::ITEM_SE, hasAnyEmptySlots, "heroSwap", "vcmi.radialWheel.splitUnit", [this](){ owner->selectSlot(this); owner->splitClick();} }, }; GH.windows().createAndPushWindow(pos.center(), menuElements); diff --git a/client/widgets/RadialMenu.cpp b/client/widgets/RadialMenu.cpp index 04f798a56..b68da5555 100644 --- a/client/widgets/RadialMenu.cpp +++ b/client/widgets/RadialMenu.cpp @@ -16,6 +16,9 @@ #include "../gui/CGuiHandler.h" #include "../gui/WindowHandler.h" #include "../render/IImage.h" +#include "../CGameInfo.h" + +#include "../../lib/CGeneralTextHandler.h" RadialMenuItem::RadialMenuItem(const std::string & imageName, const std::string & hoverText, const std::function & callback) : callback(callback) @@ -66,7 +69,7 @@ void RadialMenu::addItem(const Point & offset, bool enabled, const std::string & if (!enabled) return; - auto item = std::make_shared(path, hoverText, callback); + auto item = std::make_shared(path, CGI->generaltexth->translate(hoverText), callback); item->moveBy(offset); From 6cd219738be8ab3a85e36ced40e06fcca6ed08f2 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Fri, 21 Jul 2023 15:47:20 +0300 Subject: [PATCH 13/16] Added option to disable radial wheel in config (no UI) --- client/widgets/CGarrisonInt.cpp | 4 ++++ config/schemas/settings.json | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/client/widgets/CGarrisonInt.cpp b/client/widgets/CGarrisonInt.cpp index 21c2450fc..08bed6bbc 100644 --- a/client/widgets/CGarrisonInt.cpp +++ b/client/widgets/CGarrisonInt.cpp @@ -27,6 +27,7 @@ #include "../../lib/ArtifactUtils.h" #include "../../lib/CGeneralTextHandler.h" #include "../../lib/CCreatureHandler.h" +#include "../../lib/CConfigHandler.h" #include "../../lib/mapObjects/CGHeroInstance.h" #include "../../lib/TextOperations.h" #include "../../lib/gameState/CGameState.h" @@ -353,6 +354,9 @@ void CGarrisonSlot::gesture(bool on, const Point & initialPosition, const Point if(!myStack) return; + if (!settings["input"]["radialWheelGarrisonSwipe"].Bool()) + return; + const auto * otherArmy = upg == EGarrisonType::UPPER ? owner->lowerArmy() : owner->upperArmy(); bool stackExists = myStack != nullptr; diff --git a/config/schemas/settings.json b/config/schemas/settings.json index 4276ed1b0..ef234a135 100644 --- a/config/schemas/settings.json +++ b/config/schemas/settings.json @@ -3,7 +3,7 @@ { "type" : "object", "$schema" : "http://json-schema.org/draft-04/schema", - "required" : [ "general", "video", "adventure", "battle", "server", "logging", "launcher", "gameTweaks" ], + "required" : [ "general", "video", "adventure", "battle", "input", "server", "logging", "launcher", "gameTweaks" ], "definitions" : { "logLevelEnum" : { "type" : "string", @@ -207,6 +207,18 @@ } } }, + "input" : { + "type" : "object", + "additionalProperties" : false, + "default" : {}, + "required" : [ "radialWheelGarrisonSwipe" ], + "properties" : { + "radialWheelGarrisonSwipe" : { + "type" : "boolean", + "default" : true + } + } + }, "adventure" : { "type" : "object", "additionalProperties" : false, From da20665fab22d32c2eab802cd948967c6343cd7b Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Fri, 21 Jul 2023 15:47:36 +0300 Subject: [PATCH 14/16] Slightly better icon --- Mods/vcmi/Data/radialMenu/heroSwap.png | Bin 493 -> 511 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Mods/vcmi/Data/radialMenu/heroSwap.png b/Mods/vcmi/Data/radialMenu/heroSwap.png index e1fc20bf04ed99587c48ef9efca90ab28eaf4f62..4c94ba0ae66ddba2bc822be8415c437c91cb0224 100644 GIT binary patch delta 374 zcmV-+0g3+Y1OEe%l7Co9L_t(|0qvM!OT$1AL}#3)=CoR?`v3o`a0ClZ*bCkBz|i;g z9*>P1B`4Ytc}S4?27qLTxySMe$b6&Si5r;?J8YfYeiVzz4tp3JHEly=k1cZi8{PyJ1jW;iZc1t^jxNC+OuCEs+Zhd4xA`XyPVrYBWN7dS3?_v2`b^HUGhr7dp(mrU<49DA9#YWj!9P0!skhtk1ztsD+LmKm{79H7m5TUkgReB zF42NqvPxyH_;1fLl&s=-#qo*}N5)nl+*pyk;s-&c{X4y>qBf&usRWgO`sG39D`dXH zHh(n>xY`-~-OMgGckJip&Mr5147<5!rMxlf=FT1)Aog=}CrACiZoti*L>{8aH#>_6 U-%tHZ8vp({(4`U#Cr9pxZGnB0Ig(krmNLD!l zr_q93vPx&}z+G|4Dk=AhR8x^wRdk)wS%S)qZd%GKQd$W%ozDU;b~gUqOqSjOw|}{_ zSUBD>gv Date: Fri, 21 Jul 2023 16:47:49 +0300 Subject: [PATCH 15/16] Updated localization --- Mods/vcmi/config/vcmi/english.json | 4 +-- Mods/vcmi/config/vcmi/ukrainian.json | 45 ++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/Mods/vcmi/config/vcmi/english.json b/Mods/vcmi/config/vcmi/english.json index 8b0d07ea3..223891897 100644 --- a/Mods/vcmi/config/vcmi/english.json +++ b/Mods/vcmi/config/vcmi/english.json @@ -33,7 +33,7 @@ "vcmi.radialWheel.mergeSameUnit" : "Merge same creatures", "vcmi.radialWheel.showUnitInformation" : "Show creature information", "vcmi.radialWheel.splitSingleUnit" : "Split off single creature", - "vcmi.radialWheel.splitUnitEqually" : "Split creaturess equally", + "vcmi.radialWheel.splitUnitEqually" : "Split creatures equally", "vcmi.radialWheel.moveUnit" : "Move creatures to another army", "vcmi.radialWheel.splitUnit" : "Split creature to another slot", @@ -131,8 +131,8 @@ "vcmi.battleOptions.showStickyHeroInfoWindows.help": "{Show heroes statistics windows}\n\nPermanently toggle on heroes statistics windows that show primary stats and spell points.", "vcmi.battleOptions.skipBattleIntroMusic.hover": "Skip Intro Music", "vcmi.battleOptions.skipBattleIntroMusic.help": "{Skip Intro Music}\n\nAllow actions during the intro music that plays at the beginning of each battle", - "vcmi.battleWindow.pressKeyToSkipIntro" : "Press any key to start battle immediately", + "vcmi.battleWindow.pressKeyToSkipIntro" : "Press any key to start battle immediately", "vcmi.battleWindow.damageEstimation.melee" : "Attack %CREATURE (%DAMAGE).", "vcmi.battleWindow.damageEstimation.meleeKills" : "Attack %CREATURE (%DAMAGE, %KILLS).", "vcmi.battleWindow.damageEstimation.ranged" : "Shoot %CREATURE (%SHOTS, %DAMAGE).", diff --git a/Mods/vcmi/config/vcmi/ukrainian.json b/Mods/vcmi/config/vcmi/ukrainian.json index 31915f101..1507ace26 100644 --- a/Mods/vcmi/config/vcmi/ukrainian.json +++ b/Mods/vcmi/config/vcmi/ukrainian.json @@ -13,14 +13,41 @@ "vcmi.adventureMap.monsterThreat.levels.10" : "Смертельна", "vcmi.adventureMap.monsterThreat.levels.11" : "Неможлива", - "vcmi.adventureMap.moveCostDetails" : "Очки руху - Вартість: %TURNS ходів + %POINTS очок. Залишок очок: %REMAINING", - "vcmi.adventureMap.moveCostDetailsNoTurns" : "Очки руху - Вартість: %POINTS очок, Залишок очок: %REMAINING", - "vcmi.adventureMap.confirmRestartGame" : "Ви впевнені, що хочете перезапустити гру?", "vcmi.adventureMap.noTownWithMarket" : "Немає доступних ринків!", "vcmi.adventureMap.noTownWithTavern" : "Немає доступного міста з таверною!", "vcmi.adventureMap.spellUnknownProblem" : "Невідома проблема з цим заклинанням, більше інформації немає.", "vcmi.adventureMap.playerAttacked" : "Гравця атаковано: %s", + "vcmi.adventureMap.moveCostDetails" : "Очки руху - Вартість: %TURNS ходів + %POINTS очок. Залишок очок: %REMAINING", + "vcmi.adventureMap.moveCostDetailsNoTurns" : "Очки руху - Вартість: %POINTS очок, Залишок очок: %REMAINING", + + "vcmi.capitalColors.0" : "Червоний", + "vcmi.capitalColors.1" : "Синій", + "vcmi.capitalColors.2" : "Сірий", + "vcmi.capitalColors.3" : "Зелений", + "vcmi.capitalColors.4" : "Оранжевий", + "vcmi.capitalColors.5" : "Бордовий", + "vcmi.capitalColors.6" : "Сизий", + "vcmi.capitalColors.7" : "Рожевий", + + "vcmi.radialWheel.mergeSameUnit" : "Об'єднати однакових істот", + "vcmi.radialWheel.showUnitInformation" : "Показати відомості про істоту", + "vcmi.radialWheel.splitSingleUnit" : "Відділити одну істоту", + "vcmi.radialWheel.splitUnitEqually" : "Розділити істот порівну", + "vcmi.radialWheel.moveUnit" : "Перемістити істоту до іншої армії", + "vcmi.radialWheel.splitUnit" : "Розділити істоту в інший слот", + + "vcmi.mainMenu.tutorialNotImplemented" : "Вибачте, навчання ще не реалізовано\n", + "vcmi.mainMenu.highscoresNotImplemented" : "Вибачте, таблицю рекордів ще не реалізовано\n", + "vcmi.mainMenu.serverConnecting" : "Підключення...", + "vcmi.mainMenu.serverAddressEnter" : "Вкажіть адресу:", + "vcmi.mainMenu.serverClosing" : "Завершення...", + "vcmi.mainMenu.hostTCP" : "Створити TCP/IP гру", + "vcmi.mainMenu.joinTCP" : "Приєднатися до TCP/IP гри", + "vcmi.mainMenu.playerName" : "Гравець", + + "vcmi.lobby.filename" : "Назва файлу", + "vcmi.lobby.creationDate" : "Дата створення", "vcmi.server.errors.existingProcess" : "Працює інший процес vcmiserver, будь ласка, спочатку завершіть його", "vcmi.server.errors.modsIncompatibility" : "Потрібні модифікації для завантаження гри:", @@ -57,6 +84,8 @@ "vcmi.systemOptions.longTouchMenu.entry" : "%d мілісекунд", "vcmi.systemOptions.framerateButton.hover" : "Лічильник кадрів", "vcmi.systemOptions.framerateButton.help" : "{Лічильник кадрів}\n\n Перемикає видимість лічильника кадрів на секунду у кутку ігрового вікна", + "vcmi.systemOptions.hapticFeedbackButton.hover" : "Тактильний відгук", + "vcmi.systemOptions.hapticFeedbackButton.help" : "{Тактильний відгук}\n\Використовувати вібрацію при використанні сенсорного екрану", "vcmi.adventureOptions.infoBarPick.help" : "{Повідомлення у панелі статусу}\n\nЗа можливості, повідомлення про відвідування об'єктів карти пригод будуть відображені у панелі статусу замість окремого вікна", "vcmi.adventureOptions.infoBarPick.hover" : "Повідомлення у панелі статусу", @@ -68,6 +97,8 @@ "vcmi.adventureOptions.showGrid.help" : "{Показувати сітку}\n\n Відображає сітку, що показує межі між клітинками на мапі пригод.", "vcmi.adventureOptions.borderScroll.hover" : "Прокрутка по краю", "vcmi.adventureOptions.borderScroll.help" : "{{Прокрутка по краю}\n\nПрокручувати мапу пригод, коли курсор знаходиться біля краю вікна. Цю функцію можна вимкнути, утримуючи клавішу CTRL.", + "vcmi.adventureOptions.infoBarCreatureManagement.hover" : "Керування істотами у вікні статусу", + "vcmi.adventureOptions.infoBarCreatureManagement.help" : "{Керування істотами у вікні статусу}\n\nДозволяє впорядковувати істот у вікні статусу замість циклічного перемикання між типовими компонентами", "vcmi.adventureOptions.leftButtonDrag.hover" : "Переміщення мапи лівою кнопкою", "vcmi.adventureOptions.leftButtonDrag.help" : "{Переміщення мапи лівою кнопкою}\n\nЯкщо увімкнено, переміщення миші з натиснутою лівою кнопкою буде перетягувати мапу пригод", "vcmi.adventureOptions.mapScrollSpeed1.hover": "", @@ -96,11 +127,12 @@ "vcmi.battleOptions.movementHighlightOnHover.help": "{Підсвічувати зону руху істоти}\n\nПідсвічувати можливу зону руху істоти при наведенні курсора миші на неї", "vcmi.battleOptions.rangeLimitHighlightOnHover.hover": "Межа повного шкоди пострілом", "vcmi.battleOptions.rangeLimitHighlightOnHover.help": "{Межа повного шкоди пострілом}\n\nПідсвічувати зону у якій створіння може завдавати максимальної шкоди пострілом при наведенні на неї курсору миші.", + "vcmi.battleOptions.showStickyHeroInfoWindows.hover": "Показувати вікно інформації героя", + "vcmi.battleOptions.showStickyHeroInfoWindows.help": "{Показувати вікно інформації героя}\n\nЗавжди показувати вікно статистики героїв, що відображає первинні параметри та очки заклинань.", "vcmi.battleOptions.skipBattleIntroMusic.hover": "Пропускати вступну музику", "vcmi.battleOptions.skipBattleIntroMusic.help": "{Пропускати вступну музику}\n\n Пропускати коротку музику, яка грає на початку кожної битви перед початком дії. Також можна пропустити, натиснувши клавішу ESC.", - + "vcmi.battleWindow.pressKeyToSkipIntro" : "Натисніть будь-яку клавішу, щоб розпочати бій", - "vcmi.battleWindow.damageEstimation.melee" : "Атакувати %CREATURE (%DAMAGE).", "vcmi.battleWindow.damageEstimation.meleeKills" : "Атакувати %CREATURE (%DAMAGE, %KILLS).", "vcmi.battleWindow.damageEstimation.ranged" : "Стріляти в %CREATURE (%SHOTS, %DAMAGE).", @@ -112,11 +144,12 @@ "vcmi.battleWindow.damageEstimation.kills" : "%d загинуть", "vcmi.battleWindow.damageEstimation.kills.1" : "%d загине", + "vcmi.battleResultsWindow.applyResultsLabel" : "Прийняти результат бою", + "vcmi.otherOptions.availableCreaturesAsDwellingLabel.hover" : "Показувати доступних істот", "vcmi.otherOptions.availableCreaturesAsDwellingLabel.help" : "{Показувати доступних істот}\n\n Показує істот, яких можна придбати, замість їхнього приросту у зведенні по місту (нижній лівий кут).", "vcmi.otherOptions.creatureGrowthAsDwellingLabel.hover" : "Показувати приріст істот", "vcmi.otherOptions.creatureGrowthAsDwellingLabel.help" : "{Показувати приріст істот}\n\n Показує щотижневий приріст істот, замість кількості яку можна придбати у зведенні по місту (нижній лівий кут).", - "vcmi.otherOptions.compactTownCreatureInfo.hover": "Компактне відображення істот у місті", "vcmi.otherOptions.compactTownCreatureInfo.help": "{Компактне відображення істот у місті}\n\n Показує інформацію про істот у місті у зведенні по місту у більш компактному вигляді.", From 1acc936e5103ea6ec57410863bff6078a7c0bae6 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Fri, 21 Jul 2023 17:01:53 +0300 Subject: [PATCH 16/16] Do not activate radial wheel if cursor stays in the center --- client/widgets/RadialMenu.cpp | 29 ++++++++++++++++++++++------- client/widgets/RadialMenu.h | 4 ++-- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/client/widgets/RadialMenu.cpp b/client/widgets/RadialMenu.cpp index b68da5555..82a6a1983 100644 --- a/client/widgets/RadialMenu.cpp +++ b/client/widgets/RadialMenu.cpp @@ -41,7 +41,8 @@ void RadialMenuItem::setSelected(bool selected) inactiveImage->setEnabled(!selected); } -RadialMenu::RadialMenu(const Point & positionToCenter, const std::vector & menuConfig) +RadialMenu::RadialMenu(const Point & positionToCenter, const std::vector & menuConfig): + centerPosition(positionToCenter) { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; pos += positionToCenter; @@ -78,6 +79,12 @@ void RadialMenu::addItem(const Point & offset, bool enabled, const std::string & std::shared_ptr RadialMenu::findNearestItem(const Point & cursorPosition) const { + static const int requiredDistanceFromCenter = 45; + + // cursor is inside centeral area -> no selection + if ((centerPosition - cursorPosition).length() < requiredDistanceFromCenter) + return nullptr; + int bestDistance = std::numeric_limits::max(); std::shared_ptr bestItem; @@ -98,16 +105,23 @@ std::shared_ptr RadialMenu::findNearestItem(const Point & cursor void RadialMenu::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) { - auto item = findNearestItem(currentPosition); - GH.statusbar()->write(item->hoverText); + auto newSelection = findNearestItem(currentPosition); - if (item != selectedItem) + + if (newSelection != selectedItem) { if (selectedItem) selectedItem->setSelected(false); - item->setSelected(true); - selectedItem = item; + if (newSelection) + { + GH.statusbar()->write(newSelection->hoverText); + newSelection->setSelected(true); + } + else + GH.statusbar()->clear(); + + selectedItem = newSelection; GH.windows().totalRedraw(); } @@ -122,5 +136,6 @@ void RadialMenu::gesture(bool on, const Point & initialPosition, const Point & f // we need to close this window first so if action spawns a new window it won't be closed instead GH.windows().popWindows(1); - item->callback(); + if (item) + item->callback(); } diff --git a/client/widgets/RadialMenu.h b/client/widgets/RadialMenu.h index a3c648367..854999280 100644 --- a/client/widgets/RadialMenu.h +++ b/client/widgets/RadialMenu.h @@ -52,11 +52,11 @@ public: class RadialMenu : public CIntObject { std::vector> items; - std::shared_ptr statusBar; - std::shared_ptr selectedItem; + Point centerPosition; + void addItem(const Point & offset, bool enabled, const std::string & path, const std::string & hoverText, const std::function & callback); std::shared_ptr findNearestItem(const Point & cursorPosition) const;