mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-26 21:13:51 +00:00
Fix action bar click-to-cast and add spellbook drag-and-drop
Left-click on action bar slots now casts spells/uses items instead of starting a drag. Right-click-drag rearranges slots. Spells can be dragged from the spellbook directly onto the action bar, replacing the old "Assign to" button row.
This commit is contained in:
parent
7e172e30fe
commit
738b161e95
3 changed files with 73 additions and 63 deletions
|
|
@ -31,6 +31,11 @@ public:
|
||||||
void toggle() { open = !open; }
|
void toggle() { open = !open; }
|
||||||
void setOpen(bool o) { open = o; }
|
void setOpen(bool o) { open = o; }
|
||||||
|
|
||||||
|
// Drag-and-drop state for action bar assignment
|
||||||
|
bool isDraggingSpell() const { return draggingSpell_; }
|
||||||
|
uint32_t getDragSpellId() const { return dragSpellId_; }
|
||||||
|
void consumeDragSpell() { draggingSpell_ = false; dragSpellId_ = 0; dragSpellIconTex_ = 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool open = false;
|
bool open = false;
|
||||||
bool pKeyWasDown = false;
|
bool pKeyWasDown = false;
|
||||||
|
|
@ -54,8 +59,10 @@ private:
|
||||||
// Tab state
|
// Tab state
|
||||||
SpellTab currentTab = SpellTab::GENERAL;
|
SpellTab currentTab = SpellTab::GENERAL;
|
||||||
|
|
||||||
// Action bar assignment
|
// Drag-and-drop from spellbook to action bar
|
||||||
int assigningSlot = -1;
|
bool draggingSpell_ = false;
|
||||||
|
uint32_t dragSpellId_ = 0;
|
||||||
|
GLuint dragSpellIconTex_ = 0;
|
||||||
|
|
||||||
void loadSpellDBC(pipeline::AssetManager* assetManager);
|
void loadSpellDBC(pipeline::AssetManager* assetManager);
|
||||||
void loadSpellIconDBC(pipeline::AssetManager* assetManager);
|
void loadSpellIconDBC(pipeline::AssetManager* assetManager);
|
||||||
|
|
|
||||||
|
|
@ -1509,15 +1509,21 @@ void GameScreen::renderActionBar(game::GameHandler& gameHandler) {
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool rightClicked = ImGui::IsItemClicked(ImGuiMouseButton_Right);
|
||||||
|
|
||||||
// Drop held item from inventory onto action bar
|
// Drop held item from inventory onto action bar
|
||||||
if (clicked && inventoryScreen.isHoldingItem()) {
|
if (clicked && inventoryScreen.isHoldingItem()) {
|
||||||
const auto& held = inventoryScreen.getHeldItem();
|
const auto& held = inventoryScreen.getHeldItem();
|
||||||
gameHandler.setActionBarSlot(i, game::ActionBarSlot::ITEM, held.itemId);
|
gameHandler.setActionBarSlot(i, game::ActionBarSlot::ITEM, held.itemId);
|
||||||
inventoryScreen.returnHeldItem(gameHandler.getInventory());
|
inventoryScreen.returnHeldItem(gameHandler.getInventory());
|
||||||
|
} else if (clicked && spellbookScreen.isDraggingSpell()) {
|
||||||
|
// Drop dragged spell from spellbook onto this slot
|
||||||
|
gameHandler.setActionBarSlot(i, game::ActionBarSlot::SPELL,
|
||||||
|
spellbookScreen.getDragSpellId());
|
||||||
|
spellbookScreen.consumeDragSpell();
|
||||||
} else if (clicked && actionBarDragSlot_ >= 0) {
|
} else if (clicked && actionBarDragSlot_ >= 0) {
|
||||||
// Dropping a dragged action bar slot onto another slot - swap or place
|
// Dropping a dragged action bar slot onto another slot - swap or place
|
||||||
if (i != actionBarDragSlot_) {
|
if (i != actionBarDragSlot_) {
|
||||||
// Swap the two slots
|
|
||||||
const auto& dragSrc = bar[actionBarDragSlot_];
|
const auto& dragSrc = bar[actionBarDragSlot_];
|
||||||
auto srcType = dragSrc.type;
|
auto srcType = dragSrc.type;
|
||||||
auto srcId = dragSrc.id;
|
auto srcId = dragSrc.id;
|
||||||
|
|
@ -1527,16 +1533,17 @@ void GameScreen::renderActionBar(game::GameHandler& gameHandler) {
|
||||||
actionBarDragSlot_ = -1;
|
actionBarDragSlot_ = -1;
|
||||||
actionBarDragIcon_ = 0;
|
actionBarDragIcon_ = 0;
|
||||||
} else if (clicked && !slot.isEmpty()) {
|
} else if (clicked && !slot.isEmpty()) {
|
||||||
// Pick up this action bar slot for dragging
|
// Left-click on non-empty slot: cast spell or use item
|
||||||
actionBarDragSlot_ = i;
|
|
||||||
actionBarDragIcon_ = iconTex;
|
|
||||||
} else if (clicked) {
|
|
||||||
if (slot.type == game::ActionBarSlot::SPELL && slot.isReady()) {
|
if (slot.type == game::ActionBarSlot::SPELL && slot.isReady()) {
|
||||||
uint64_t target = gameHandler.hasTarget() ? gameHandler.getTargetGuid() : 0;
|
uint64_t target = gameHandler.hasTarget() ? gameHandler.getTargetGuid() : 0;
|
||||||
gameHandler.castSpell(slot.id, target);
|
gameHandler.castSpell(slot.id, target);
|
||||||
} else if (slot.type == game::ActionBarSlot::ITEM && slot.id != 0) {
|
} else if (slot.type == game::ActionBarSlot::ITEM && slot.id != 0) {
|
||||||
gameHandler.useItemById(slot.id);
|
gameHandler.useItemById(slot.id);
|
||||||
}
|
}
|
||||||
|
} else if (rightClicked && !slot.isEmpty()) {
|
||||||
|
// Right-click on non-empty slot: pick up for dragging
|
||||||
|
actionBarDragSlot_ = i;
|
||||||
|
actionBarDragIcon_ = iconTex;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tooltip
|
// Tooltip
|
||||||
|
|
@ -1604,8 +1611,8 @@ void GameScreen::renderActionBar(game::GameHandler& gameHandler) {
|
||||||
IM_COL32(80, 80, 120, 180));
|
IM_COL32(80, 80, 120, 180));
|
||||||
}
|
}
|
||||||
|
|
||||||
// On mouse release, check if outside the action bar area
|
// On right mouse release, check if outside the action bar area
|
||||||
if (ImGui::IsMouseReleased(ImGuiMouseButton_Left)) {
|
if (ImGui::IsMouseReleased(ImGuiMouseButton_Right)) {
|
||||||
bool insideBar = (mousePos.x >= barX && mousePos.x <= barX + barW &&
|
bool insideBar = (mousePos.x >= barX && mousePos.x <= barX + barW &&
|
||||||
mousePos.y >= barY && mousePos.y <= barY + barH);
|
mousePos.y >= barY && mousePos.y <= barY + barH);
|
||||||
if (!insideBar) {
|
if (!insideBar) {
|
||||||
|
|
|
||||||
|
|
@ -204,22 +204,12 @@ void SpellbookScreen::render(game::GameHandler& gameHandler, pipeline::AssetMana
|
||||||
if (ImGui::BeginTabItem(label)) {
|
if (ImGui::BeginTabItem(label)) {
|
||||||
currentTab = tab;
|
currentTab = tab;
|
||||||
|
|
||||||
// Action bar assignment mode indicator
|
|
||||||
if (assigningSlot >= 0) {
|
|
||||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.3f, 1.0f),
|
|
||||||
"Click a spell to assign to slot %d", assigningSlot + 1);
|
|
||||||
if (ImGui::SmallButton("Cancel")) {
|
|
||||||
assigningSlot = -1;
|
|
||||||
}
|
|
||||||
ImGui::Separator();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spellList.empty()) {
|
if (spellList.empty()) {
|
||||||
ImGui::TextDisabled("No spells in this category.");
|
ImGui::TextDisabled("No spells in this category.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spell list with icons
|
// Spell list with icons
|
||||||
ImGui::BeginChild("SpellList", ImVec2(0, -60), true);
|
ImGui::BeginChild("SpellList", ImVec2(0, 0), true);
|
||||||
|
|
||||||
float iconSize = 32.0f;
|
float iconSize = 32.0f;
|
||||||
bool isPassiveTab = (tab == SpellTab::PASSIVE);
|
bool isPassiveTab = (tab == SpellTab::PASSIVE);
|
||||||
|
|
@ -274,35 +264,40 @@ void SpellbookScreen::render(game::GameHandler& gameHandler, pipeline::AssetMana
|
||||||
ImGui::GetWindowDrawList()->AddRectFilled(
|
ImGui::GetWindowDrawList()->AddRectFilled(
|
||||||
rowMin, rowMax, IM_COL32(255, 255, 255, 20));
|
rowMin, rowMax, IM_COL32(255, 255, 255, 20));
|
||||||
|
|
||||||
if (ImGui::IsMouseClicked(0)) {
|
// Left-click-drag to pick up spell for action bar
|
||||||
if (assigningSlot >= 0 && !isPassiveTab) {
|
if (ImGui::IsMouseClicked(0) && !isPassiveTab) {
|
||||||
gameHandler.setActionBarSlot(assigningSlot,
|
draggingSpell_ = true;
|
||||||
game::ActionBarSlot::SPELL, info->spellId);
|
dragSpellId_ = info->spellId;
|
||||||
assigningSlot = -1;
|
dragSpellIconTex_ = iconTex;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::IsMouseDoubleClicked(0) && !isPassiveTab && !onCooldown) {
|
if (ImGui::IsMouseDoubleClicked(0) && !isPassiveTab && !onCooldown) {
|
||||||
|
// Double-click casts (cancel any drag)
|
||||||
|
draggingSpell_ = false;
|
||||||
|
dragSpellId_ = 0;
|
||||||
|
dragSpellIconTex_ = 0;
|
||||||
uint64_t target = gameHandler.hasTarget() ? gameHandler.getTargetGuid() : 0;
|
uint64_t target = gameHandler.hasTarget() ? gameHandler.getTargetGuid() : 0;
|
||||||
gameHandler.castSpell(info->spellId, target);
|
gameHandler.castSpell(info->spellId, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tooltip
|
// Tooltip (only when not dragging)
|
||||||
ImGui::BeginTooltip();
|
if (!draggingSpell_) {
|
||||||
ImGui::Text("%s", info->name.c_str());
|
ImGui::BeginTooltip();
|
||||||
if (!info->rank.empty()) {
|
ImGui::Text("%s", info->name.c_str());
|
||||||
ImGui::TextDisabled("%s", info->rank.c_str());
|
if (!info->rank.empty()) {
|
||||||
}
|
ImGui::TextDisabled("%s", info->rank.c_str());
|
||||||
ImGui::TextDisabled("Spell ID: %u", info->spellId);
|
|
||||||
if (isPassiveTab) {
|
|
||||||
ImGui::TextDisabled("Passive");
|
|
||||||
} else {
|
|
||||||
if (!onCooldown) {
|
|
||||||
ImGui::TextDisabled("Double-click to cast");
|
|
||||||
}
|
}
|
||||||
ImGui::TextDisabled("Use buttons below to assign to action bar");
|
ImGui::TextDisabled("Spell ID: %u", info->spellId);
|
||||||
|
if (isPassiveTab) {
|
||||||
|
ImGui::TextDisabled("Passive");
|
||||||
|
} else {
|
||||||
|
ImGui::TextDisabled("Drag to action bar to assign");
|
||||||
|
if (!onCooldown) {
|
||||||
|
ImGui::TextDisabled("Double-click to cast");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndTooltip();
|
||||||
}
|
}
|
||||||
ImGui::EndTooltip();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPassiveTab || onCooldown) {
|
if (isPassiveTab || onCooldown) {
|
||||||
|
|
@ -329,35 +324,36 @@ void SpellbookScreen::render(game::GameHandler& gameHandler, pipeline::AssetMana
|
||||||
|
|
||||||
ImGui::EndTabBar();
|
ImGui::EndTabBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Action bar quick-assign buttons (not for passive tab)
|
|
||||||
if (currentTab != SpellTab::PASSIVE) {
|
|
||||||
ImGui::Separator();
|
|
||||||
ImGui::Text("Assign to:");
|
|
||||||
ImGui::SameLine();
|
|
||||||
static const char* slotLabels[] = {"1","2","3","4","5","6","7","8","9","0","-","="};
|
|
||||||
for (int i = 0; i < 12; ++i) {
|
|
||||||
if (i > 0) ImGui::SameLine(0, 2);
|
|
||||||
ImGui::PushID(100 + i);
|
|
||||||
bool isAssigning = (assigningSlot == i);
|
|
||||||
if (isAssigning) {
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.8f, 0.6f, 0.2f, 1.0f));
|
|
||||||
}
|
|
||||||
if (ImGui::SmallButton(slotLabels[i])) {
|
|
||||||
assigningSlot = isAssigning ? -1 : i;
|
|
||||||
}
|
|
||||||
if (isAssigning) {
|
|
||||||
ImGui::PopStyleColor();
|
|
||||||
}
|
|
||||||
ImGui::PopID();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
if (!windowOpen) {
|
if (!windowOpen) {
|
||||||
open = false;
|
open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render dragged spell icon at cursor
|
||||||
|
if (draggingSpell_ && dragSpellId_ != 0) {
|
||||||
|
ImVec2 mousePos = ImGui::GetMousePos();
|
||||||
|
float dragSize = 32.0f;
|
||||||
|
if (dragSpellIconTex_) {
|
||||||
|
ImGui::GetForegroundDrawList()->AddImage(
|
||||||
|
(ImTextureID)(uintptr_t)dragSpellIconTex_,
|
||||||
|
ImVec2(mousePos.x - dragSize * 0.5f, mousePos.y - dragSize * 0.5f),
|
||||||
|
ImVec2(mousePos.x + dragSize * 0.5f, mousePos.y + dragSize * 0.5f));
|
||||||
|
} else {
|
||||||
|
ImGui::GetForegroundDrawList()->AddRectFilled(
|
||||||
|
ImVec2(mousePos.x - dragSize * 0.5f, mousePos.y - dragSize * 0.5f),
|
||||||
|
ImVec2(mousePos.x + dragSize * 0.5f, mousePos.y + dragSize * 0.5f),
|
||||||
|
IM_COL32(80, 80, 120, 180));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cancel drag on mouse release (action bar consumes it before this if dropped on a slot)
|
||||||
|
if (ImGui::IsMouseReleased(ImGuiMouseButton_Left)) {
|
||||||
|
draggingSpell_ = false;
|
||||||
|
dragSpellId_ = 0;
|
||||||
|
dragSpellIconTex_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}} // namespace wowee::ui
|
}} // namespace wowee::ui
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue