Skip to content

Commit f3f0fb2

Browse files
committed
node moving
1 parent 1f08426 commit f3f0fb2

File tree

6 files changed

+88
-11
lines changed

6 files changed

+88
-11
lines changed

src/DevTools.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ struct matjson::Serialize<Settings> {
3535
assign(value["button_y"], s.buttonPos.y);
3636
assign(value["button_editor"], s.buttonInEditor);
3737
assign(value["button_game"], s.buttonInGame);
38+
assign(value["enable_moving"], s.enableMoving);
3839

3940
return Ok(s);
4041
}
@@ -56,6 +57,7 @@ struct matjson::Serialize<Settings> {
5657
{ "button_y", settings.buttonPos.y },
5758
{ "button_editor", settings.buttonInEditor },
5859
{ "button_game", settings.buttonInGame },
60+
{ "enable_moving", settings.enableMoving }
5961
});
6062
}
6163
};
@@ -102,6 +104,14 @@ void DevTools::highlightNode(CCNode* node, HighlightMode mode) {
102104
m_toHighlight.push_back({ node, mode });
103105
}
104106

107+
CCNode* DevTools::getDraggedNode() const {
108+
return m_draggedNode;
109+
}
110+
111+
void DevTools::setDraggedNode(CCNode* node) {
112+
m_draggedNode = node;
113+
}
114+
105115
void DevTools::addCustomCallback(std::function<void(CCNode*)> callback) {
106116
m_customCallbacks.push_back(std::move(callback));
107117
}

src/DevTools.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct Settings {
3232
CCPoint buttonPos = {50, 50};
3333
bool buttonInEditor = false;
3434
bool buttonInGame = false;
35+
bool enableMoving = false;
3536
};
3637

3738
class DevTools {
@@ -50,6 +51,7 @@ class DevTools {
5051
ImFont* m_boxFont = nullptr;
5152
CCTexture2D* m_fontTexture = nullptr;
5253
Ref<CCNode> m_selectedNode;
54+
Ref<CCNode> m_draggedNode;
5355
std::vector<std::pair<CCNode*, HighlightMode>> m_toHighlight;
5456
std::vector<std::function<void(CCNode*)>> m_customCallbacks;
5557
std::string m_searchQuery;
@@ -60,7 +62,7 @@ class DevTools {
6062
void setupPlatform();
6163

6264
void drawTree();
63-
void drawTreeBranch(CCNode* node, size_t index);
65+
void drawTreeBranch(CCNode* node, size_t index, bool drag);
6466
void drawSettings();
6567
void drawAdvancedSettings();
6668
void drawNodeAttributes(CCNode* node);
@@ -111,6 +113,8 @@ class DevTools {
111113
CCNode* getSelectedNode() const;
112114
void selectNode(CCNode* node);
113115
void highlightNode(CCNode* node, HighlightMode mode);
116+
CCNode* getDraggedNode() const;
117+
void setDraggedNode(CCNode* node);
114118

115119
void addCustomCallback(std::function<void(CCNode*)> callback);
116120

src/nodes/DragButton.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "DragButton.hpp"
22
#include "../DevTools.hpp"
33

4+
#include <Geode/Geode.hpp>
5+
46
using namespace geode::prelude;
57

68
bool DragButton::init(CCNode* node, std::function<void()> onPress) {

src/nodes/DragButton.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include "Geode/cocos/base_nodes/CCNode.h"
4+
#include "Geode/cocos/layers_scenes_transitions_nodes/CCLayer.h"
45
#include "Geode/cocos/touch_dispatcher/CCTouchDelegateProtocol.h"
56

67
class DragButton : public cocos2d::CCLayer {

src/pages/Settings.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ void DevTools::drawSettings() {
5858
"As a side effect to disabling this, things may render incorrectly."
5959
);
6060
}
61+
ImGui::Checkbox("Enable Node Moving", &m_settings.enableMoving);
62+
if (ImGui::IsItemHovered()) {
63+
ImGui::SetTooltip(
64+
"Adds a button to allow moving a node to a different parent via drag/drop"
65+
);
66+
}
6167
ImGui::Checkbox("Advanced Settings", &m_settings.advancedSettings);
6268
if (ImGui::IsItemHovered()) {
6369
ImGui::SetTooltip(

src/pages/Tree.cpp

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
#include "../DevTools.hpp"
44
#include "../platform/utils.hpp"
55
#include <misc/cpp/imgui_stdlib.h>
6+
#include <Geode/utils/string.hpp>
7+
68
#ifndef GEODE_IS_WINDOWS
79
#include <cxxabi.h>
810
#endif
911

1012
using namespace geode::prelude;
1113

12-
void DevTools::drawTreeBranch(CCNode* node, size_t index) {
14+
void DevTools::drawTreeBranch(CCNode* node, size_t index, bool drag) {
1315
if (!searchBranch(node)) {
1416
return;
1517
}
@@ -20,15 +22,37 @@ void DevTools::drawTreeBranch(CCNode* node, size_t index) {
2022
if (selected) {
2123
flags |= ImGuiTreeNodeFlags_Selected;
2224
}
23-
if (!node->getChildrenCount())
24-
{
25+
if (!node->getChildrenCount()) {
2526
flags |= ImGuiTreeNodeFlags_Leaf;
2627
}
27-
if (m_settings.arrowExpand)
28-
{
28+
if (m_settings.arrowExpand) {
2929
flags |= ImGuiTreeNodeFlags_OpenOnArrow;
3030
}
3131

32+
if (auto dragged = DevTools::get()->getDraggedNode(); dragged && dragged != node && !drag) {
33+
float mouse = ImGui::GetMousePos().y;
34+
float cursor = ImGui::GetCursorPosY() + ImGui::GetWindowPos().y - ImGui::GetScrollY();
35+
36+
if (mouse <= cursor + 18 && mouse > cursor) {
37+
flags |= ImGuiTreeNodeFlags_Selected;
38+
39+
if (!ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
40+
for(CCNode* n = node;; n = n->getParent()) {
41+
if (n == dragged) { // can't drag a parent into its own child
42+
break;
43+
} else if (n == nullptr) {
44+
auto parent = dragged->getParent();
45+
dragged->removeFromParentAndCleanup(false);
46+
parent->updateLayout();
47+
node->addChild(dragged);
48+
node->updateLayout();
49+
break;
50+
}
51+
}
52+
}
53+
}
54+
}
55+
3256
if (m_searchQuery.empty()) {
3357
ImGui::SetNextItemOpen(m_nodeOpen.contains(node) && m_nodeOpen[node]);
3458
}
@@ -49,6 +73,9 @@ void DevTools::drawTreeBranch(CCNode* node, size_t index) {
4973
}
5074
// The order here is unusual due to imgui weirdness; see the second-to-last paragraph in https://kahwei.dev/2022/06/20/imgui-tree-node/
5175
bool expanded = ImGui::TreeNodeEx(node, flags, "%s", name.str().c_str());
76+
float height = ImGui::GetItemRectSize().y;
77+
78+
5279
if (ImGui::IsItemClicked()) {
5380
DevTools::get()->selectNode(node);
5481
selected = true;
@@ -61,9 +88,6 @@ void DevTools::drawTreeBranch(CCNode* node, size_t index) {
6188
}
6289
}
6390
}
64-
if (ImGui::IsItemHovered() && (m_settings.alwaysHighlight || ImGui::IsKeyDown(ImGuiMod_Shift))) {
65-
DevTools::get()->highlightNode(node, HighlightMode::Hovered);
66-
}
6791
if (ImGui::IsItemToggledOpen() && (m_searchQuery.empty() || m_searchQuery == m_prevQuery)) {
6892
if (!m_searchQuery.empty() && expanded) {
6993
CCNode* parent = node->getParent();
@@ -74,13 +98,39 @@ void DevTools::drawTreeBranch(CCNode* node, size_t index) {
7498
}
7599
m_nodeOpen[node] = expanded;
76100
}
101+
102+
if (ImGui::IsItemHovered() && (m_settings.alwaysHighlight || ImGui::IsKeyDown(ImGuiMod_Shift))) {
103+
DevTools::get()->highlightNode(node, HighlightMode::Hovered);
104+
}
105+
106+
bool isDrag = false;
107+
108+
if (m_settings.enableMoving) {
109+
ImGui::SameLine();
110+
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
111+
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0, 0, 0, 0));
112+
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0, 0, 0, 0));
113+
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0.75f));
114+
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 4);
115+
116+
std::string btnText = (U8STR(FEATHER_MENU"##menu_")) + std::to_string((long)node);
117+
ImGui::Button(btnText.c_str(), {0, height});
118+
119+
isDrag = ImGui::IsItemActive();
120+
if (isDrag) {
121+
DevTools::get()->setDraggedNode(node);
122+
}
123+
ImGui::PopStyleColor(3);
124+
ImGui::PopStyleVar();
125+
}
126+
77127
if (expanded) {
78128
if (m_settings.attributesInTree) {
79129
this->drawNodeAttributes(node);
80130
}
81131
size_t i = 0;
82132
for (auto& child : CCArrayExt<CCNode*>(node->getChildren())) {
83-
this->drawTreeBranch(child, i++);
133+
this->drawTreeBranch(child, i++, drag || isDrag);
84134
}
85135
ImGui::TreePop();
86136
}
@@ -101,7 +151,11 @@ void DevTools::drawTree() {
101151
m_searchQuery.clear();
102152
}
103153

104-
this->drawTreeBranch(CCDirector::get()->getRunningScene(), 0);
154+
this->drawTreeBranch(CCDirector::get()->getRunningScene(), 0, false);
155+
156+
if (!ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
157+
DevTools::get()->setDraggedNode(nullptr);
158+
}
105159
}
106160

107161
bool DevTools::searchBranch(CCNode* node) {

0 commit comments

Comments
 (0)