Ember
Loading...
Searching...
No Matches
TreeWidget.h
Go to the documentation of this file.
1#pragma once
2
3#include "Core/BehaviorTree.h"
5#include <memory>
6#include <unordered_map>
7#include <vector>
8#include <wx/scrolwin.h>
9#include <wx/wx.h>
10
11namespace EmberForge {
12
19class TreeWidget : public wxScrolledWindow {
20 public:
24 enum class LayoutAlgorithm {
25 Vertical, // Top-down tree layout
26 Horizontal, // Left-right tree layout
27 Radial, // Circular tree layout
28 Compact, // Space-efficient layout
29 Manual // User-controlled positions
30 };
31
35 enum class InteractionMode {
36 View, // Read-only viewing
37 Select, // Selection mode
38 Edit, // Editing mode (add/remove/move nodes)
39 Connect, // Connection editing mode
40 Debug // Debug/execution visualization
41 };
42
48 TreeWidget(wxWindow *parent, std::shared_ptr<EmberCore::BehaviorTree> tree = nullptr);
49
53 virtual ~TreeWidget();
54
55 // Tree management
56 void SetBehaviorTree(std::shared_ptr<EmberCore::BehaviorTree> tree);
57 std::shared_ptr<EmberCore::BehaviorTree> GetBehaviorTree() const { return behavior_tree_; }
58 bool HasTree() const { return behavior_tree_ != nullptr; }
59
60 // Layout management
62 void SetLayoutAlgorithm(LayoutAlgorithm algorithm);
63 void RefreshLayout();
64 void AutoFitLayout();
65
66 // Interaction mode
69
70 // EmberCore::Node management
72 std::vector<EmberForge::NodeWidget *> GetAllNodeWidgets() const;
73 std::vector<EmberForge::NodeWidget *> GetSelectedNodeWidgets() const;
74
75 // Selection
76 void SelectNode(EmberCore::Node *node, bool add_to_selection = false);
77 void DeselectNode(EmberCore::Node *node);
78 void ClearSelection();
79 void SelectAll();
80 EmberCore::Node *GetSelectedNode() const; // Returns first selected node
81 std::vector<EmberCore::Node *> GetSelectedNodes() const;
82
83 // Navigation
84 void ZoomIn();
85 void ZoomOut();
86 void ZoomToFit();
87 void ZoomToSelection();
88 void SetZoomLevel(double zoom);
89 double GetZoomLevel() const { return zoom_level_; }
90
91 void CenterOnNode(EmberCore::Node *node);
92 void CenterOnSelection();
93 void CenterView();
94
95 // Tree editing
96 bool CanAddNode(EmberCore::Node *parent) const;
97 bool AddNode(std::unique_ptr<EmberCore::Node> node, EmberCore::Node *parent);
100 bool CanMoveNode(EmberCore::Node *node, EmberCore::Node *new_parent) const;
101 bool MoveNode(EmberCore::Node *node, EmberCore::Node *new_parent);
102
103 // Visual properties
105 void SetConnectionStyle(int line_width, const wxColour &color);
106 void SetBackgroundColor(const wxColour &color);
107 void SetGridVisible(bool visible);
108 void SetConnectionsVisible(bool visible);
109
110 // Animation
111 void AnimateToNode(EmberCore::Node *node);
112 void HighlightExecutionPath(const std::vector<EmberCore::Node *> &path);
113 void ClearHighlights();
114
115 // Import/Export
116 bool SaveLayout(const wxString &filename) const;
117 bool LoadLayout(const wxString &filename);
118 wxBitmap ExportAsImage(const wxSize &size = wxDefaultSize) const;
119
120 // Preferences
121 void LoadPreferences();
122
123 // Event callbacks
124 using NodeSelectionCallback = std::function<void(const std::vector<EmberCore::Node *> &)>;
125 using NodeEditCallback = std::function<void(EmberCore::Node *, const wxString &property, const wxString &value)>;
126 using TreeChangeCallback = std::function<void(const wxString &change_type)>;
127
131
132 protected:
133 // Rendering
134 virtual void OnPaint(wxPaintEvent &event);
135 virtual void OnSize(wxSizeEvent &event);
136 virtual void OnEraseBackground(wxEraseEvent &event);
137
138 // Mouse events
139 virtual void OnMouseDown(wxMouseEvent &event);
140 virtual void OnMouseUp(wxMouseEvent &event);
141 virtual void OnMouseMove(wxMouseEvent &event);
142 virtual void OnMouseWheel(wxMouseEvent &event);
143 virtual void OnRightClick(wxContextMenuEvent &event);
144
145 // Keyboard events
146 virtual void OnKeyDown(wxKeyEvent &event);
147 virtual void OnChar(wxKeyEvent &event);
148
149 // Layout methods
154 void UpdateScrollbars();
155 void LayoutNodeVertical(EmberCore::Node *node, int x, int y, int level);
156
157 // Drawing methods
158 void DrawBackground(wxDC &dc);
159 void DrawGrid(wxDC &dc);
160 void DrawConnections(wxDC &dc);
161 void DrawConnection(wxDC &dc, EmberForge::NodeWidget *parent, EmberForge::NodeWidget *child);
162 void DrawSelectionRect(wxDC &dc);
163
164 // Node widget management
165 void CreateNodeWidgets();
166 void UpdateNodeWidgets();
167 void DestroyNodeWidgets();
168 std::unique_ptr<EmberForge::NodeWidget> CreateNodeWidget(EmberCore::Node *node);
169
170 // Hit testing
171 EmberForge::NodeWidget *HitTestNode(const wxPoint &point) const;
172 EmberCore::Node *HitTestConnection(const wxPoint &point) const;
173
174 // Selection helpers
177
178 // Layout helpers
179 wxSize CalculateTreeSize() const;
180 wxPoint CalculateNodePosition(EmberCore::Node *node) const;
181 void PositionNodeWidgets();
182
183 // Coordinate conversion
184 wxPoint TreeToScreen(const wxPoint &tree_point) const;
185 wxPoint ScreenToTree(const wxPoint &screen_point) const;
186 wxRect TreeToScreen(const wxRect &tree_rect) const;
187 wxRect ScreenToTree(const wxRect &screen_rect) const;
188
189 private:
190 // Core data
191 std::shared_ptr<EmberCore::BehaviorTree> behavior_tree_;
194
195 // Node widgets
196 std::unordered_map<EmberCore::Node *, std::unique_ptr<EmberForge::NodeWidget>> node_widgets_;
197 std::vector<EmberCore::Node *> selected_nodes_;
198
199 // Visual state
204
205 // Zoom/Pan preferences
210
211 // Appearance
213 wxColour grid_color_;
218
219 // Interaction state
225
226 // Layout parameters
231 std::unordered_map<EmberCore::Node *, wxPoint> node_positions_;
232
233 // Animation
235 std::vector<EmberCore::Node *> highlighted_path_;
236
237 // Event callbacks
241
242 // Helper methods
243 void InitializeWidget();
244 void SetupEventHandlers();
245 void UpdateViewSize();
246 void ShowContextMenu(const wxPoint &position);
247
248 // Node widget event handlers
251 void OnNodeDragged(EmberForge::NodeWidget *widget, const wxPoint &delta);
252 void OnNodeEdited(EmberForge::NodeWidget *widget, const wxString &new_name);
253
254 // Constants
255 static constexpr double MIN_ZOOM = 0.1;
256 static constexpr double MAX_ZOOM = 5.0;
257 static const int DEFAULT_NODE_SPACING_X = 120;
258 static const int DEFAULT_NODE_SPACING_Y = 80;
259 static const int DEFAULT_LEVEL_SPACING = 100;
260 static const int GRID_SIZE = 20;
261
262 DECLARE_EVENT_TABLE()
263};
264
265} // namespace EmberForge
Represents a node in a behavior tree structure.
Definition Node.h:20
Custom widget for rendering and interacting with behavior tree nodes.
Definition NodeWidget.h:16
RenderStyle
Node rendering styles.
Definition NodeWidget.h:21
std::function< void(const std::vector< EmberCore::Node * > &)> NodeSelectionCallback
Definition TreeWidget.h:124
void OnNodeDragged(EmberForge::NodeWidget *widget, const wxPoint &delta)
std::vector< EmberForge::NodeWidget * > GetSelectedNodeWidgets() const
std::unique_ptr< EmberForge::NodeWidget > CreateNodeWidget(EmberCore::Node *node)
std::vector< EmberForge::NodeWidget * > GetAllNodeWidgets() const
void SetNodeEditCallback(NodeEditCallback callback)
Definition TreeWidget.h:129
std::vector< EmberCore::Node * > selected_nodes_
Definition TreeWidget.h:197
void SetGridVisible(bool visible)
void HighlightExecutionPath(const std::vector< EmberCore::Node * > &path)
void SetBackgroundColor(const wxColour &color)
void DrawGrid(wxDC &dc)
TreeWidget(wxWindow *parent, std::shared_ptr< EmberCore::BehaviorTree > tree=nullptr)
Constructor.
virtual void OnMouseUp(wxMouseEvent &event)
NodeEditCallback edit_callback_
Definition TreeWidget.h:239
InteractionMode interaction_mode_
Definition TreeWidget.h:193
EmberCore::Node * GetSelectedNode() const
void SetLayoutAlgorithm(LayoutAlgorithm algorithm)
void DrawSelectionRect(wxDC &dc)
bool SaveLayout(const wxString &filename) const
virtual void OnRightClick(wxContextMenuEvent &event)
virtual void OnPaint(wxPaintEvent &event)
InteractionMode
Tree interaction modes.
Definition TreeWidget.h:35
void SetConnectionsVisible(bool visible)
void SetInteractionMode(InteractionMode mode)
virtual ~TreeWidget()
Destructor.
EmberForge::NodeWidget::RenderStyle node_render_style_
Definition TreeWidget.h:203
void SetZoomLevel(double zoom)
void SelectNode(EmberCore::Node *node, bool add_to_selection=false)
InteractionMode GetInteractionMode() const
Definition TreeWidget.h:67
void SetNodeRenderStyle(EmberForge::NodeWidget::RenderStyle style)
virtual void OnChar(wxKeyEvent &event)
virtual void OnEraseBackground(wxEraseEvent &event)
std::unordered_map< EmberCore::Node *, wxPoint > node_positions_
Definition TreeWidget.h:231
std::function< void(const wxString &change_type)> TreeChangeCallback
Definition TreeWidget.h:126
virtual void OnMouseMove(wxMouseEvent &event)
void ShowContextMenu(const wxPoint &position)
bool CanAddNode(EmberCore::Node *parent) const
void LayoutNodeVertical(EmberCore::Node *node, int x, int y, int level)
bool CanMoveNode(EmberCore::Node *node, EmberCore::Node *new_parent) const
virtual void OnMouseWheel(wxMouseEvent &event)
static constexpr double MAX_ZOOM
Definition TreeWidget.h:256
bool AddNode(std::unique_ptr< EmberCore::Node > node, EmberCore::Node *parent)
void OnNodeEdited(EmberForge::NodeWidget *widget, const wxString &new_name)
void OnNodeClicked(EmberForge::NodeWidget *widget, EmberCore::Node *node)
LayoutAlgorithm GetLayoutAlgorithm() const
Definition TreeWidget.h:61
wxPoint TreeToScreen(const wxPoint &tree_point) const
EmberForge::NodeWidget * GetNodeWidget(EmberCore::Node *node) const
static constexpr double MIN_ZOOM
Definition TreeWidget.h:255
void SetTreeChangeCallback(TreeChangeCallback callback)
Definition TreeWidget.h:130
void AnimateToNode(EmberCore::Node *node)
bool HasTree() const
Definition TreeWidget.h:58
bool LoadLayout(const wxString &filename)
static const int DEFAULT_NODE_SPACING_Y
Definition TreeWidget.h:258
virtual void OnSize(wxSizeEvent &event)
void DeselectNode(EmberCore::Node *node)
std::function< void(EmberCore::Node *, const wxString &property, const wxString &value)> NodeEditCallback
Definition TreeWidget.h:125
LayoutAlgorithm layout_algorithm_
Definition TreeWidget.h:192
bool MoveNode(EmberCore::Node *node, EmberCore::Node *new_parent)
void DrawConnection(wxDC &dc, EmberForge::NodeWidget *parent, EmberForge::NodeWidget *child)
EmberForge::NodeWidget * HitTestNode(const wxPoint &point) const
static const int DEFAULT_LEVEL_SPACING
Definition TreeWidget.h:259
virtual void OnMouseDown(wxMouseEvent &event)
wxPoint ScreenToTree(const wxPoint &screen_point) const
EmberCore::Node * HitTestConnection(const wxPoint &point) const
void SetBehaviorTree(std::shared_ptr< EmberCore::BehaviorTree > tree)
wxBitmap ExportAsImage(const wxSize &size=wxDefaultSize) const
void CenterOnNode(EmberCore::Node *node)
static const int DEFAULT_NODE_SPACING_X
Definition TreeWidget.h:257
static const int GRID_SIZE
Definition TreeWidget.h:260
void SetNodeSelectionCallback(NodeSelectionCallback callback)
Definition TreeWidget.h:128
NodeSelectionCallback selection_callback_
Definition TreeWidget.h:238
double GetZoomLevel() const
Definition TreeWidget.h:89
void DrawBackground(wxDC &dc)
wxPoint CalculateNodePosition(EmberCore::Node *node) const
LayoutAlgorithm
Tree layout algorithms.
Definition TreeWidget.h:24
void OnNodeDoubleClicked(EmberForge::NodeWidget *widget, EmberCore::Node *node)
std::shared_ptr< EmberCore::BehaviorTree > behavior_tree_
Definition TreeWidget.h:191
virtual void OnKeyDown(wxKeyEvent &event)
std::vector< EmberCore::Node * > highlighted_path_
Definition TreeWidget.h:235
void DrawConnections(wxDC &dc)
std::vector< EmberCore::Node * > GetSelectedNodes() const
TreeChangeCallback tree_change_callback_
Definition TreeWidget.h:240
void SetConnectionStyle(int line_width, const wxColour &color)
std::shared_ptr< EmberCore::BehaviorTree > GetBehaviorTree() const
Definition TreeWidget.h:57
std::unordered_map< EmberCore::Node *, std::unique_ptr< EmberForge::NodeWidget > > node_widgets_
Definition TreeWidget.h:196
wxSize CalculateTreeSize() const