Skip to content

Commit 3d269fc

Browse files
author
kasemir
committed
NavTabs SelectedNavigationTabs cleanup
Custom record/class to get more meaningful names than 'left' and 'right'. More comments on what's going on
1 parent 85cfa2c commit 3d269fc

File tree

1 file changed

+43
-35
lines changed

1 file changed

+43
-35
lines changed

app/display/representation-javafx/src/main/java/org/csstudio/display/builder/representation/javafx/widgets/NavigationTabsRepresentation.java

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
import java.util.concurrent.atomic.AtomicReference;
1919
import java.util.logging.Level;
2020

21-
import javafx.util.Pair;
22-
import org.apache.commons.lang3.tuple.MutablePair;
2321
import org.csstudio.display.builder.model.DirtyFlag;
2422
import org.csstudio.display.builder.model.DisplayModel;
2523
import org.csstudio.display.builder.model.UntypedWidgetPropertyListener;
@@ -61,10 +59,22 @@ public class NavigationTabsRepresentation extends RegionBaseRepresentation<Navig
6159
// Track the "active tab" of navigation tabs _inside_ this one.
6260
// As user toggles between tabs, this will allow restoring the active tab
6361
// of nested instances, which would otherwise start over at their default tab
64-
private class SelectedNavigationTabs extends MutablePair<Integer, HashMap<Pair<Integer, String>, HashMap<String, SelectedNavigationTabs>>> {
65-
public SelectedNavigationTabs(int activeTab) {
66-
left = activeTab;
67-
right = new HashMap<>(); // 'right' is a mapping of the form: Tab Number & Tab Name (Integer, String) -> Name of Navigator Tab Widget (String) -> Opened Tab and Sub-Tabs (SelectedNavigationTabs)
62+
63+
// Tab index and name as unique identifier for a tab
64+
private static record UniqueTabID(int index, String name) {}
65+
66+
private static class SelectedNavigationTabs
67+
{
68+
// Index of active tab in this nav tabs widget
69+
int active_tab;
70+
71+
// Map from UniqueTabID -> ( Map from Name of child Navigator Tab Widget -> Opened Tab and Sub-Tabs )
72+
final HashMap<UniqueTabID,
73+
HashMap<String, SelectedNavigationTabs>> child_navtab_selections = new HashMap<>();
74+
75+
SelectedNavigationTabs(int activeTab)
76+
{
77+
active_tab = activeTab;
6878
}
6979
};
7080
protected SelectedNavigationTabs selectedNavigationTabs = new SelectedNavigationTabs(0);
@@ -190,7 +200,7 @@ private void activeTabChanged(final WidgetProperty<Integer> property, final Inte
190200
dirty_active_tab.mark();
191201
toolkit.scheduleUpdate(this);
192202
tab_display_listener.propertyChanged(null, null, null);
193-
selectedNavigationTabs.left = tab_index;
203+
selectedNavigationTabs.active_tab = tab_index;
194204
}
195205

196206
/** Update to the next pending display
@@ -250,35 +260,33 @@ private synchronized void updatePendingDisplay(final JobMonitor monitor)
250260
final List<TabProperty> tabs = model_widget.propTabs().getValue();
251261
final int tabNumber = Math.min(model_widget.propActiveTab().getValue(), tabs.size()-1);
252262
final String tabName = tabs.get(tabNumber).name().getValue();
253-
final Pair<Integer, String> tabNumberAndTabName = new Pair<>(tabNumber, tabName);
263+
final UniqueTabID tab_id = new UniqueTabID(tabNumber, tabName);
254264

255-
if (!selectedNavigationTabs.right.containsKey(tabNumberAndTabName)) {
256-
selectedNavigationTabs.right.put(tabNumberAndTabName, new HashMap<>());
257-
}
258-
HashMap<String, SelectedNavigationTabs> selectedNavigationTabsHashMapForCurrentTab = selectedNavigationTabs.right.get(tabNumberAndTabName);
259-
260-
new_model.getChildren()
261-
.stream()
262-
.filter(widget -> widget instanceof NavigationTabsWidget)
263-
.forEach(widget -> {
264-
NavigationTabsWidget nestedNavigationTabsWidget = (NavigationTabsWidget) widget;
265-
NavigationTabsRepresentation nestedNavigationTabsRepresentation = (NavigationTabsRepresentation) nestedNavigationTabsWidget.getUserData(Widget.USER_DATA_REPRESENTATION);
266-
if (nestedNavigationTabsRepresentation != null) {
267-
SelectedNavigationTabs nestedNavigationTabsRepresentation_selectedNavigationTabs;
268-
269-
if (!selectedNavigationTabsHashMapForCurrentTab.containsKey(nestedNavigationTabsWidget.getName())) {
270-
nestedNavigationTabsRepresentation_selectedNavigationTabs = new SelectedNavigationTabs(nestedNavigationTabsWidget.propActiveTab().getValue());
271-
selectedNavigationTabsHashMapForCurrentTab.put(nestedNavigationTabsWidget.getName(), nestedNavigationTabsRepresentation_selectedNavigationTabs);
272-
}
273-
else {
274-
nestedNavigationTabsRepresentation_selectedNavigationTabs = selectedNavigationTabsHashMapForCurrentTab.get(nestedNavigationTabsWidget.getName());
275-
if (nestedNavigationTabsWidget.propTabs().size() > nestedNavigationTabsRepresentation_selectedNavigationTabs.left) {
276-
nestedNavigationTabsWidget.propActiveTab().setValue(nestedNavigationTabsRepresentation_selectedNavigationTabs.left);
277-
}
278-
}
279-
nestedNavigationTabsRepresentation.selectedNavigationTabs = nestedNavigationTabsRepresentation_selectedNavigationTabs;
280-
}
281-
});
265+
// For this tab_id, create or update map of NavTabs children to their selected tab index and sub-navtabs
266+
final HashMap<String, SelectedNavigationTabs> selectedNavTabsMapForCurrentTab = selectedNavigationTabs.child_navtab_selections.computeIfAbsent(tab_id, tid -> new HashMap<>());
267+
268+
for (Widget w : new_model.getChildren())
269+
if (w instanceof NavigationTabsWidget childNavTab)
270+
{
271+
final NavigationTabsRepresentation childRepr = childNavTab.getUserData(Widget.USER_DATA_REPRESENTATION);
272+
if (childRepr != null)
273+
{
274+
SelectedNavigationTabs childRepr_selectedNavigationTabs = selectedNavTabsMapForCurrentTab.get(childNavTab.getName());
275+
if (childRepr_selectedNavigationTabs == null)
276+
{ // See childNavTab for the first time? Create its SelectedNavigationTabs with its propActiveTab as start value
277+
childRepr_selectedNavigationTabs = new SelectedNavigationTabs(childNavTab.propActiveTab().getValue());
278+
selectedNavTabsMapForCurrentTab.put(childNavTab.getName(), childRepr_selectedNavigationTabs);
279+
}
280+
// Known childNavTab? Re-select its last active tab (if valid index)
281+
else if (childRepr_selectedNavigationTabs.active_tab < childNavTab.propTabs().size())
282+
childNavTab.propActiveTab().setValue(childRepr_selectedNavigationTabs.active_tab);
283+
284+
// childRepr.selectedNavigationTabs was set when the childNavTabRepr got constructed,
285+
// but it's empty and its reference will be lost when we switch tabs.
286+
// Replace it with the one that's tracked by the parent navtab (this one)
287+
childRepr.selectedNavigationTabs = childRepr_selectedNavigationTabs;
288+
}
289+
}
282290

283291
model_widget.runtimePropEmbeddedModel().setValue(new_model);
284292
}

0 commit comments

Comments
 (0)