Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
inspector_window.hpp
Go to the documentation of this file.
1// inspector_window.hpp — Tabbed inspector window with collapsable property panels
2#pragma once
3
4#include <pulp/view/view.hpp>
12
13#include <chrono>
14#include <functional>
15#include <map>
16#include <memory>
17#include <string>
18#include <vector>
19
20namespace pulp::view { class TextEditor; } // wiring-tab note field (pointer only)
21
22namespace pulp::inspect {
23
24using namespace pulp::view;
25using namespace pulp::canvas;
26
27// ── CollapsableSection ─────────────────────────────────────────────────────
29
30class CollapsableSection : public View {
31public:
32 CollapsableSection(std::string title, bool initially_expanded = true);
33
34 bool is_expanded() const { return expanded_; }
35 void set_expanded(bool e);
36
38 View* content() const { return content_; }
39
40 void paint(canvas::Canvas& canvas) override;
41 void on_mouse_event(const MouseEvent& event) override;
42
43private:
44 std::string title_;
45 bool expanded_;
46 View* header_ = nullptr; // owned as child
47 View* content_ = nullptr; // owned as child
48
49 static constexpr float kHeaderHeight = 24.0f;
50};
51
52// ── ConsoleEntry (visual row) ──────────────────────────────────────────────
53
55class ConsoleEntryView : public View {
56public:
57 void set_entry(const ConsoleCapture::Entry& entry);
58
59 void paint(canvas::Canvas& canvas) override;
60
61 float intrinsic_height() const override { return 22.0f; }
62
63private:
64 std::string level_;
65 std::string message_;
66 std::string timestamp_;
67};
68
69// ── InspectorWindow ────────────────────────────────────────────────────────
72
73class InspectorWindow : public View {
74public:
77
79 explicit InspectorWindow(View& root);
80
81 // ── Data sources ────────────────────────────────────────────────
84
86 void set_console_capture(ConsoleCapture* capture) { console_capture_ = capture; }
87
90
92 void set_state_inspector(StateInspector* si) { state_inspector_ = si; }
93
95 void refresh();
96
100 void select_tab(std::string_view title);
101
104 void set_figma_file_key(std::string key) { figma_file_key_ = std::move(key); }
105
110 bool export_wiring_annotations(const std::string& path) const;
111
125 std::function<void(View* view)> on_view_selected;
126
132
140
144 void set_selection_readonly(bool readonly) {
145 selection_readonly_ = readonly;
146 }
147 bool selection_readonly() const { return selection_readonly_; }
148
149 // ── Figma-style tool strip (Select / Text) ─────────────────────
150 //
151 // A compact horizontal strip in the window header showing the two
152 // tools (pointer = Select, "T" = Text) with the active one
153 // highlighted. The strip is wired BOTH WAYS to the overlay's tool
154 // mode via the host:
155 // * Click a tool button → on_tool_picked(0=Select, 1=Text) fires;
156 // the host calls InspectorOverlay::set_tool().
157 // * Keyboard V/T flips the overlay tool → the host calls
158 // set_active_tool() so the strip's highlight reflects it.
161 void set_active_tool(int tool_index);
162 int active_tool() const { return active_tool_; }
163
167 std::function<void(int tool_index)> on_tool_picked;
168
169private:
170 // ── Tab construction ────────────────────────────────────────────
171 std::unique_ptr<View> build_elements_tab();
172 std::unique_ptr<View> build_console_tab();
173 std::unique_ptr<View> build_performance_tab();
174 std::unique_ptr<View> build_state_tab();
175 std::unique_ptr<View> build_wiring_tab();
176
177 // ── Refresh helpers ─────────────────────────────────────────────
178 void refresh_elements();
179 void refresh_console();
180 void refresh_performance();
181 void refresh_state();
182 // Walks the inspected tree for DesignFrameView overlays that carry a Figma
183 // source_node_id, lists each with its node id + kind + wired/unwired badge.
184 void refresh_wiring();
185 // Select a wiring row by node id: loads its note into the editor + updates
186 // the detail line. Shared by row clicks and tests.
187 void select_wiring_node(const std::string& node);
188 // Figma editor URL for a node id (file_key + node-id), or "" if no file key.
189 std::string figma_reveal_url(const std::string& node) const;
190
191 void populate_tree_from_view(TreeNode& parent, View* view);
192 void show_properties_for(View* view);
193
194 // ── Data sources ────────────────────────────────────────────────
195 View* inspected_root_ = nullptr;
196 ConsoleCapture* console_capture_ = nullptr;
197 render::RenderPassManager* rpm_ = nullptr;
198 StateInspector* state_inspector_ = nullptr;
199
200 // ── Widgets (non-owning, owned as children) ─────────────────────
201 TabPanel* tabs_ = nullptr;
202
203 // ── Tool strip ─────────────────────────────────────────────────
204 // The strip View (custom paint + click handling) lives as the first
205 // child of the window, above the tab panel. active_tool_ is the index
206 // it highlights (0 = Select, 1 = Text). The strip reads active_tool_
207 // each paint and calls on_tool_picked on a button click.
208 class ToolStrip;
209 ToolStrip* tool_strip_ = nullptr;
210 int active_tool_ = 0;
211
212 // Elements tab
213 TreeView* tree_view_ = nullptr;
214 ScrollView* tree_scroll_ = nullptr; // viewport wrapping tree_view_
215 CollapsableSection* identity_section_ = nullptr;
216 CollapsableSection* layout_section_ = nullptr;
217 CollapsableSection* visual_section_ = nullptr;
218 CollapsableSection* widget_section_ = nullptr;
219 CollapsableSection* theme_section_ = nullptr;
220 View* elements_props_container_ = nullptr;
221
222 // Console tab
223 ScrollView* console_scroll_ = nullptr;
224 View* console_list_ = nullptr;
225
226 // Performance tab
227 Label* fps_label_ = nullptr;
228 Label* frame_time_label_ = nullptr;
229 Label* gpu_render_label_ = nullptr;
230 Label* budget_label_ = nullptr;
231 View* pass_list_ = nullptr;
232 Label* view_count_label_ = nullptr;
233
234 // State tab
235 ScrollView* state_scroll_ = nullptr;
236 View* state_list_ = nullptr;
237
238 ScrollView* wiring_scroll_ = nullptr;
239 View* wiring_list_ = nullptr;
240 TextEditor* wiring_note_editor_ = nullptr; // note for the selected control
241 Label* wiring_detail_ = nullptr; // selected node id + kind + state
242 Label* wiring_status_ = nullptr; // export / reveal status line
243 std::string figma_file_key_; // for Reveal-in-Figma URLs
244 std::string wiring_selected_; // selected control's node id
245 std::map<std::string, std::string> wiring_notes_; // node id → developer note
246 // Snapshot of the listed controls (rebuilt each refresh) so Export doesn't
247 // have to re-walk the tree.
248 struct WiringEntry { std::string node; std::string kind; bool wired = false; };
249 std::vector<WiringEntry> wiring_entries_;
250
251 // Currently selected view (Elements tab)
252 View* selected_view_ = nullptr;
253
254 // When true, tree-row clicks only display properties read-only and
255 // never drive the shared selection (opt-out). Default false for
256 // two-way selection. See set_selection_readonly().
257 bool selection_readonly_ = false;
258
259 // reflect_selection() (the canvas → window mirror) highlights the
260 // matching tree row and shows props, the same as a tree-row pick.
261 // Two-way selection is intentional; the only forbidden behavior is a
262 // stray selection box inside the inspector window, blocked in the
263 // paint hook.
264
265 // Tree-structure signature, to suppress the empty-content flicker.
266 // refresh_elements() runs on every idle tick (~30 Hz); rebuilding the
267 // whole TreeView each tick clears then repopulates it, which flashes
268 // empty. We hash the inspected tree's structure (type + id per node)
269 // and only rebuild when it actually changed; otherwise we just refresh
270 // the property labels for the current selection. Zero means "never built".
271 std::size_t tree_signature_ = 0;
272 // Compute the structural signature of the inspected tree.
273 std::size_t compute_tree_signature(const View* view) const;
274
275 // Property labels (Elements tab, Identity section)
276 Label* prop_type_label_ = nullptr;
277 Label* prop_id_label_ = nullptr;
278
279 // Layout section labels
280 Label* prop_bounds_label_ = nullptr;
281 Label* prop_direction_label_ = nullptr;
282 Label* prop_gap_label_ = nullptr;
283 Label* prop_padding_label_ = nullptr;
284 Label* prop_margin_label_ = nullptr;
285 Label* prop_grow_shrink_label_ = nullptr;
286
287 // Visual section labels
288 Label* prop_opacity_label_ = nullptr;
289 Label* prop_bgcolor_label_ = nullptr;
290 Label* prop_border_label_ = nullptr;
291 Label* prop_corner_label_ = nullptr;
292 Label* prop_visible_label_ = nullptr;
293 Label* prop_enabled_label_ = nullptr;
294
295 // Widget section labels
296 Label* prop_widget_value_label_ = nullptr;
297};
298
299} // namespace pulp::inspect
Definition canvas.hpp:240
A disclosure-triangle section: click header to expand/collapse content.
Definition inspector_window.hpp:30
CollapsableSection(std::string title, bool initially_expanded=true)
bool is_expanded() const
Definition inspector_window.hpp:34
void paint(canvas::Canvas &canvas) override
void on_mouse_event(const MouseEvent &event) override
Mouse down with full event context.
View * content() const
The content container — add children here.
Definition inspector_window.hpp:38
Captures JS console output (console.log/warn/error) for inspector display.
Definition console_capture.hpp:22
Displays a single console log entry with colored level badge and timestamp.
Definition inspector_window.hpp:55
void paint(canvas::Canvas &canvas) override
float intrinsic_height() const override
Definition inspector_window.hpp:61
void set_entry(const ConsoleCapture::Entry &entry)
void set_state_inspector(StateInspector *si)
Set the state inspector for the State tab.
Definition inspector_window.hpp:92
void set_console_capture(ConsoleCapture *capture)
Set the console capture for the Console tab.
Definition inspector_window.hpp:86
void set_selection_readonly(bool readonly)
When true, clicking a tree row only shows that node's properties (read-only display) and never change...
Definition inspector_window.hpp:144
bool export_wiring_annotations(const std::string &path) const
Write the Wiring-tab annotations (each design-sourced control's node id, kind, wired flag,...
std::function< void(View *view)> on_view_selected
Called when a view is selected in the tree.
Definition inspector_window.hpp:125
void set_render_pass_manager(render::RenderPassManager *rpm)
Set the render pass manager for the Performance tab.
Definition inspector_window.hpp:89
void set_figma_file_key(std::string key)
Figma file key used to build "Reveal in Figma" URLs for Wiring-tab rows (e.g.
Definition inspector_window.hpp:104
std::function< void(int tool_index)> on_tool_picked
Fired when the user clicks a tool button in the strip.
Definition inspector_window.hpp:167
InspectorWindow(View &root)
Convenience: construct and immediately set the inspected root.
void reflect_selection(View *view)
Reflect the canvas-driven selection into this window WITHOUT firing on_view_selected (no feedback loo...
void set_inspected_root(View *root)
Set the root view to inspect (Elements tab).
void set_active_tool(int tool_index)
Index of the active tool the strip highlights (0 = Select, 1 = Text).
int active_tool() const
Definition inspector_window.hpp:162
void refresh()
Refresh all tabs with latest data. Call once per frame.
void select_tab(std::string_view title)
Programmatically select a tab by title (e.g.
bool selection_readonly() const
Definition inspector_window.hpp:147
void select_view(View *view)
Select a view from external code (e.g., Cmd+click in plugin window).
Monitors StateStore parameters for the inspector.
Definition state_inspector.hpp:25
Frame-level render pass manager.
Definition render_pass.hpp:41
Definition widgets.hpp:56
Tabbed container that shows one child at a time.
Definition ui_components.hpp:356
Text editing widget with comprehensive keyboard/mouse interaction.
Definition text_editor.hpp:47
Hierarchical tree view widget.
Definition tree_view.hpp:57
Definition view.hpp:73
friend class ScrollView
Definition view.hpp:2792
View * parent() const
Definition view.hpp:163
Definition affine_transform.hpp:24
Definition agent_context.hpp:7
Hover-cursor tracking for platform window hosts.
Definition fwd.hpp:27
@ path
Definition anchor_strategy.hpp:42
@ e
Definition input_events.hpp:39
A captured log entry.
Definition console_capture.hpp:25
Rich mouse/pointer event with position, modifiers, button state, pointer ID, and stylus properties.
Definition input_events.hpp:104
A node in the tree hierarchy.
Definition tree_view.hpp:18
Hierarchical tree display widget for file browsers, plugin lists, etc.
Additional UI components: ComboBox, Tooltip, ProgressBar, CallOutBox, TabPanel, ListBox,...