Skip to content

Commit 4678c15

Browse files
committed
#537 improve custom panel support embed control
1 parent 7140e47 commit 4678c15

File tree

5 files changed

+183
-29
lines changed

5 files changed

+183
-29
lines changed

embedCONTROLCore/src/main/java/com/thecoderscorner/embedcontrol/core/controlmgr/MenuGridComponent.java

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
import java.util.Map;
1616
import java.util.Optional;
1717
import java.util.concurrent.ScheduledExecutorService;
18-
import java.util.concurrent.ScheduledFuture;
19-
import java.util.concurrent.TimeUnit;
2018
import java.util.function.Consumer;
2119

2220
import static com.thecoderscorner.embedcontrol.customization.FontInformation.SizeMeasurement.PERCENT;
@@ -29,7 +27,6 @@ public abstract class MenuGridComponent<T> {
2927
private final MenuTree tree;
3028
protected final Map<Integer, EditorComponent<T>> editorComponents = new HashMap<>();
3129
private final ScheduledExecutorService executor;
32-
private final ScheduledFuture<?> remoteTickTask;
3330
private ThreadMarshaller marshaller;
3431
private int row;
3532

@@ -40,12 +37,8 @@ public MenuGridComponent(MenuItemStore store, JfxNavigationManager navMgr, Sched
4037
this.navMgr = navMgr;
4138
this.executor = executor;
4239
this.marshaller = marshaller;
43-
44-
remoteTickTask = executor.scheduleAtFixedRate(this::timerTick, 100, 100, TimeUnit.MILLISECONDS);
4540
}
4641

47-
48-
4942
public void renderMenuRecursive(MenuEditorFactory<T> editorFactory, SubMenuItem sub, boolean recurse, int level) {
5043
Consumer<MenuItem> subRenderer = subMenuItem -> navMgr.pushMenuNavigation(asSubMenu(subMenuItem), menuItemStore);
5144
if (menuItemStore.hasSubConfiguration(sub.getId())) {
@@ -112,12 +105,6 @@ public void itemHasUpdated(MenuItem item) {
112105
}
113106
}
114107

115-
public void tickAll() {
116-
for(var component : editorComponents.values()) {
117-
component.tick();
118-
}
119-
}
120-
121108
private ComponentSettings getComponentForMenuItem(MenuItem item) {
122109
var position = defaultSpaceForItem(Optional.of(item));
123110

@@ -158,6 +145,12 @@ public void acknowledgementReceived(CorrelationId key, AckStatus status) {
158145
}
159146
}
160147

148+
public void tickAll() {
149+
for(var comp : editorComponents.values()) {
150+
comp.tick();
151+
}
152+
}
153+
161154
public record ScreenLayoutBasedConditionalColor(MenuItemStore store, ComponentPositioning where) implements ConditionalColoring {
162155
@Override
163156
public PortableColor foregroundFor(EditorComponent.RenderingStatus status, ColorComponentType compType) {
@@ -196,19 +189,6 @@ private ControlColor getControlColor(EditorComponent.RenderingStatus status, Col
196189
}
197190
}
198191

199-
/**
200-
* Called frequently by the executor to update the UI components.
201-
*/
202-
public void timerTick() {
203-
marshaller.runOnUiThread(this::tickAll);
204-
}
205-
206-
/**
207-
* Call this to stop the associated tasks.
208-
*/
209-
public void dispose() {
210-
remoteTickTask.cancel(false);
211-
}
212192

213193
public static ControlType defaultControlForType(MenuItem item) {
214194
if (item instanceof SubMenuItem || item instanceof BooleanMenuItem || item instanceof ActionMenuItem) {

embedCONTROLCore/src/main/java/com/thecoderscorner/embedcontrol/jfx/controlmgr/JfxMenuPresentable.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
import com.thecoderscorner.embedcontrol.core.service.GlobalSettings;
55
import com.thecoderscorner.embedcontrol.customization.FontInformation;
66
import com.thecoderscorner.embedcontrol.customization.MenuItemStore;
7+
import com.thecoderscorner.menu.domain.MenuItem;
78
import com.thecoderscorner.menu.domain.SubMenuItem;
89
import com.thecoderscorner.menu.domain.state.MenuTree;
910
import com.thecoderscorner.menu.domain.util.MenuItemFormatter;
10-
import javafx.application.Platform;
11+
import com.thecoderscorner.menu.remote.commands.AckStatus;
12+
import com.thecoderscorner.menu.remote.protocol.CorrelationId;
1113
import javafx.geometry.HPos;
1214
import javafx.geometry.VPos;
1315
import javafx.scene.Node;
@@ -23,7 +25,7 @@
2325
import static com.thecoderscorner.embedcontrol.core.controlmgr.color.ControlColor.asFxColor;
2426
import static com.thecoderscorner.embedcontrol.customization.FontInformation.SizeMeasurement;
2527

26-
public class JfxMenuPresentable implements PanelPresentable<Node> {
28+
public class JfxMenuPresentable implements PanelPresentable<Node>, UpdatablePanel {
2729
private final SubMenuItem subMenuItem;
2830
protected final MenuGridComponent<Node> gridComponent;
2931
private final MenuEditorFactory<Node> editorFactory;
@@ -89,8 +91,24 @@ public boolean canClose() {
8991
public void closePanel() {
9092
}
9193

94+
@Override
9295
public void connectionIsUp(boolean up) {
93-
Platform.runLater(()->gridPane.setDisable(!up));
96+
gridPane.setDisable(!up);
97+
}
98+
99+
@Override
100+
public void acknowledgedCorrelationId(CorrelationId correlationId, AckStatus status) {
101+
getGridComponent().acknowledgementReceived(correlationId, status);
102+
}
103+
104+
@Override
105+
public void tickAll() {
106+
getGridComponent().tickAll();
107+
}
108+
109+
@Override
110+
public void itemHasUpdated(MenuItem item) {
111+
getGridComponent().itemHasUpdated(item);
94112
}
95113

96114
class JfxGridComponent extends MenuGridComponent<Node> {

embedCONTROLCore/src/main/java/com/thecoderscorner/embedcontrol/jfx/controlmgr/JfxNavigationHeader.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.*;
2323
import java.util.concurrent.CopyOnWriteArrayList;
2424
import java.util.concurrent.ScheduledExecutorService;
25+
import java.util.concurrent.TimeUnit;
2526
import java.util.function.BiConsumer;
2627

2728
import static javafx.scene.control.Alert.AlertType;
@@ -158,6 +159,13 @@ public void pushMenuNavigation(SubMenuItem subMenuItem, MenuItemStore store, boo
158159
}
159160
runNavigation(presentable);
160161
navigationStack.push(presentable);
162+
executorService.scheduleAtFixedRate(() -> {
163+
Platform.runLater(() -> {
164+
if(currentNavigationPanel() instanceof UpdatablePanel updatablePanel) {
165+
updatablePanel.tickAll();
166+
}
167+
});
168+
}, 100L, 100L, TimeUnit.MILLISECONDS);
161169
});
162170
}
163171

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.thecoderscorner.embedcontrol.jfx.controlmgr;
2+
3+
import com.thecoderscorner.menu.domain.MenuItem;
4+
import com.thecoderscorner.menu.remote.commands.AckStatus;
5+
import com.thecoderscorner.menu.remote.protocol.CorrelationId;
6+
7+
/// Represents a `PanelPresentable` that can be updated when menu items change, it is also provided with a
8+
/// tick function so that the implementor can tick down updates that occur. When an item updates the update
9+
/// will be sent through the `itemHasUpdated` method, and you will be on the JavaFx thread when it occurs.
10+
public interface UpdatablePanel {
11+
/// called every 100 millis by the framework so that you can tick any animations that are in progress.
12+
void tickAll();
13+
14+
/// called whenever there is a menu item update so that the display can be updated.
15+
/// @param item the item that has updated
16+
void itemHasUpdated(MenuItem item);
17+
18+
/// called whenever the connection state changes.
19+
/// @param isUp true if connection up, otherwise false
20+
void connectionIsUp(boolean isUp);
21+
22+
/// called whenever an acknowledgement correlation ID is received
23+
/// @param correlationId the correlation id of the acknowledgement
24+
/// @param status the status of the acknowledgement
25+
void acknowledgedCorrelationId(CorrelationId correlationId, AckStatus status);
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package com.thecoderscorner.embedcontrol.jfx.controlmgr.panels;
2+
3+
import com.thecoderscorner.embedcontrol.core.controlmgr.*;
4+
import com.thecoderscorner.embedcontrol.core.controlmgr.color.ConditionalColoring;
5+
import com.thecoderscorner.embedcontrol.jfx.controlmgr.UpdatablePanel;
6+
import com.thecoderscorner.menu.domain.MenuItem;
7+
import com.thecoderscorner.menu.domain.state.MenuTree;
8+
import com.thecoderscorner.menu.remote.commands.AckStatus;
9+
import com.thecoderscorner.menu.remote.protocol.CorrelationId;
10+
import javafx.scene.Node;
11+
import javafx.scene.layout.Background;
12+
import javafx.scene.layout.BackgroundFill;
13+
import javafx.scene.layout.GridPane;
14+
15+
import java.util.HashMap;
16+
17+
import static com.thecoderscorner.embedcontrol.core.controlmgr.EditorComponent.RenderingStatus.NORMAL;
18+
import static com.thecoderscorner.embedcontrol.core.controlmgr.color.ConditionalColoring.ColorComponentType.TEXT_FIELD;
19+
import static com.thecoderscorner.embedcontrol.core.controlmgr.color.ControlColor.asFxColor;
20+
21+
public abstract class BaseCustomMenuPanel implements PanelPresentable<Node>, UpdatablePanel {
22+
protected final boolean panelCanBeClosed;
23+
protected final MenuEditorFactory<Node> editorFactory;
24+
protected final ConditionalColoring conditionalColoring;
25+
protected final MenuTree menuTree;
26+
protected final HashMap<Integer, EditorComponent<Node>> controlsBeingManaged = new HashMap<>();
27+
protected GridPane gridPane;
28+
protected double presentableWidth = 999;
29+
30+
public BaseCustomMenuPanel(MenuEditorFactory<Node> editorFactory,
31+
ConditionalColoring conditionalColoring,
32+
MenuTree menuTree,
33+
boolean canClose) {
34+
this.editorFactory = editorFactory;
35+
this.conditionalColoring = conditionalColoring;
36+
this.menuTree = menuTree;
37+
this.panelCanBeClosed = canClose;
38+
}
39+
40+
@Override
41+
public Node getPanelToPresent(double width) throws Exception {
42+
if (gridPane != null) {
43+
// empty it if it already exists to make GC easier
44+
gridPane.getChildren().clear();
45+
gridPane.getColumnConstraints().clear();
46+
gridPane.getRowConstraints().clear();
47+
}
48+
presentableWidth = width;
49+
makeBasicGridLayout();
50+
populateGrid();
51+
52+
return gridPane;
53+
}
54+
protected abstract void populateGrid();
55+
56+
protected void putIntoGrid(MenuItem item, ComponentSettings componentSettings) {
57+
ComponentPositioning pos = componentSettings.getPosition();
58+
var component = editorFactory.getComponentEditorItem(item, componentSettings, this::noAction);
59+
component.ifPresent(comp -> {
60+
controlsBeingManaged.put(item.getId(), comp);
61+
gridPane.add(comp.createComponent(), pos.getCol(), pos.getRow(), pos.getColSpan(), pos.getRowSpan());
62+
});
63+
}
64+
65+
protected void makeBasicGridLayout() {
66+
gridPane = new GridPane();
67+
gridPane.setHgap(5);
68+
gridPane.setVgap(5);
69+
gridPane.setMaxWidth(9999);
70+
gridPane.setPrefWidth(presentableWidth);
71+
gridPane.getChildren().clear();
72+
73+
// the grid will be 4 across by three down.
74+
gridPane.getColumnConstraints().clear();
75+
gridPane.getRowConstraints().clear();
76+
gridPane.setBackground(new Background(new BackgroundFill(
77+
asFxColor(conditionalColoring.colorFor(NORMAL, TEXT_FIELD).getBg()), null, null
78+
)));
79+
80+
}
81+
82+
protected void noAction(MenuItem menuItem) {
83+
}
84+
85+
86+
@Override
87+
public boolean canClose() {
88+
return panelCanBeClosed;
89+
}
90+
91+
92+
@Override
93+
public void closePanel() {
94+
controlsBeingManaged.clear();
95+
}
96+
97+
@Override
98+
public void itemHasUpdated(MenuItem item) {
99+
if(controlsBeingManaged.containsKey(item.getId())) {
100+
controlsBeingManaged.get(item.getId()).onItemUpdated(item, menuTree.getMenuState(item));
101+
}
102+
}
103+
104+
@Override
105+
public void connectionIsUp(boolean isUp) {
106+
gridPane.setDisable(!isUp);
107+
}
108+
109+
@Override
110+
public void acknowledgedCorrelationId(CorrelationId correlationId, AckStatus status) {
111+
for(var component : controlsBeingManaged.values()) {
112+
component.onCorrelation(correlationId, status);
113+
}
114+
}
115+
116+
@Override
117+
public void tickAll() {
118+
for(var component : controlsBeingManaged.values()) {
119+
component.tick();
120+
}
121+
}
122+
}

0 commit comments

Comments
 (0)