You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GroupWidget is the dashboard's nested-layout container (panel / collapsible / tabbed — the project's named "tabs, collapsible groups" core value). In tabbed mode it already navigates by name — switchTab(tabName) (GroupWidget.m:382) and addChild(widget, tabName) (:80) both key off the tab name via the private findTab.
But there is no public read side:
No way to enumerate tabs. To list tab names a caller must reach into the internal Tabs cell-of-struct and know its struct('name',…,'widgets',{{…}}) shape (:41, :84). grep -rnE "getTabNames|getActiveTab|listTabs" libs/ examples/ returns nothing.
No way to validate a tab before switching.switchTab silently no-ops on an unknown tab (:386–389), unlike its siblings removeTab(tabName) and removeChild(idx, tabName) which throw GroupWidget:unknownTab. A caller has no non-throwing pre-check.
Add three small read-only introspection methods to GroupWidget, mirroring the page-introspection API from #279:
getTabNames() → cellstr of the tabbed group's tab names ({} when not tabbed / no tabs).
hasTab(name) → logical; true if a tab with that name exists.
getActiveTab() → returns the active tab name (ActiveTab).
Rough sketch
Single file — libs/Dashboard/GroupWidget.m, three methods over the existing private findTab:
functionnames= getTabNames(obj)
%GETTABNAMES Cellstr of tab names (tabbed mode); {} otherwise.if ~strcmp(obj.Mode, 'tabbed') || isempty(obj.Tabs)
names = {};
return;
end
names = cellfun(@(t) t.name, obj.Tabs, 'UniformOutput', false);
endfunctiontf= hasTab(obj, name)
%HASTAB True if a tab with NAME exists.
tf =obj.findTab(name) ~=0;
endfunctionname= getActiveTab(obj)
%GETACTIVETAB Name of the active tab ('' when none).
name =obj.ActiveTab;
end
Lets a "jump to tab" menu, a FastSenseCompanion control, or a structural test assert/enumerate tabs without touching Tabs internals — e.g. for n = g.getTabNames(); ...; end then if g.hasTab(n), g.switchTab(n); end.
Value
Medium. Tabbed groups are an explicitly named core value ("organize … into navigable sections … tabs, collapsible groups"). Enumeration is the primitive that name-based navigation needs on the read side; #279 established the same value for the page analog one cycle ago, so the shape and worth are concrete and consistent.
Constraints check
Toolbox-free: yes — plain cellfun / strcmp via existing findTab.
Backward-compatible: yes — strictly additive. No existing method changes; switchTab keeps its current silent-no-op behavior (deliberately not touched here). No serialization change (Tabs already round-trips).
Pure MATLAB/Octave: yes.
Widget contract: yes — read-only methods on the existing GroupWidget (a DashboardWidget); no contract change.
Effort estimate
S — one file, three small read-only methods.
Related note (NOT part of this additive change)
switchTab(tabName) silently no-ops on an unknown tab while its removeTab / removeChild siblings throw GroupWidget:unknownTab. Tightening that to throw would be a behavior change (callers may rely on the silent path), so it is intentionally excluded here — hasTab() gives callers a non-throwing pre-check instead. Route the switchTab consistency question separately as a small bug/decision if desired.
AI-proposed via /feature-scout — needs a human product decision before implementation.
Problem / motivation
GroupWidgetis the dashboard's nested-layout container (panel / collapsible / tabbed — the project's named "tabs, collapsible groups" core value). In tabbed mode it already navigates by name —switchTab(tabName)(GroupWidget.m:382) andaddChild(widget, tabName)(:80) both key off the tab name via the privatefindTab.But there is no public read side:
Tabscell-of-struct and know itsstruct('name',…,'widgets',{{…}})shape (:41,:84).grep -rnE "getTabNames|getActiveTab|listTabs" libs/ examples/returns nothing.switchTabsilently no-ops on an unknown tab (:386–389), unlike its siblingsremoveTab(tabName)andremoveChild(idx, tabName)which throwGroupWidget:unknownTab. A caller has no non-throwing pre-check.DashboardEnginepages just receivedgetPageNames()/getActivePageName()introspection (DashboardEngine: name-based page navigation (switchPage by name) + page-name introspection #279). TabbedGroupWidgetis the directly-analogous nested-layout primitive with the same gap — the read side of name-based navigation is missing.Proposed feature
Add three small read-only introspection methods to
GroupWidget, mirroring the page-introspection API from #279:getTabNames()→ cellstr of the tabbed group's tab names ({}when not tabbed / no tabs).hasTab(name)→ logical; true if a tab with that name exists.getActiveTab()→ returns the active tab name (ActiveTab).Rough sketch
Single file —
libs/Dashboard/GroupWidget.m, three methods over the existing privatefindTab:Lets a "jump to tab" menu, a
FastSenseCompanioncontrol, or a structural test assert/enumerate tabs without touchingTabsinternals — e.g.for n = g.getTabNames(); ...; endthenif g.hasTab(n), g.switchTab(n); end.Value
Medium. Tabbed groups are an explicitly named core value ("organize … into navigable sections … tabs, collapsible groups"). Enumeration is the primitive that name-based navigation needs on the read side; #279 established the same value for the page analog one cycle ago, so the shape and worth are concrete and consistent.
Constraints check
cellfun/strcmpvia existingfindTab.switchTabkeeps its current silent-no-op behavior (deliberately not touched here). No serialization change (Tabsalready round-trips).GroupWidget(aDashboardWidget); no contract change.Effort estimate
S — one file, three small read-only methods.
Related note (NOT part of this additive change)
switchTab(tabName)silently no-ops on an unknown tab while itsremoveTab/removeChildsiblings throwGroupWidget:unknownTab. Tightening that to throw would be a behavior change (callers may rely on the silent path), so it is intentionally excluded here —hasTab()gives callers a non-throwing pre-check instead. Route theswitchTabconsistency question separately as a small bug/decision if desired.AI-proposed via
/feature-scout— needs a human product decision before implementation.