Skip to content

Commit eea71d5

Browse files
committed
v2.66 First implementation of synchronised scrolling of REDUCEPanels in a split pane. Correct names of some menu items from *CheckBox to *CheckMenuItem.
1 parent baf791d commit eea71d5

4 files changed

Lines changed: 67 additions & 36 deletions

File tree

src/fjwright/runreduce/REDUCEPanel.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,11 @@ public class REDUCEPanel extends BorderPane {
6060
private double[] dividerPositions;
6161

6262
final WebEngine webEngine;
63-
private HTMLDocument doc;
63+
HTMLDocument doc;
6464
private HTMLElement html, head, inputPre;
6565
HTMLElement body;
6666
private JSObject katex, katexMacros;
67+
JSObject window;
6768

6869
/*
6970
* The <body> content should look like repeats of this structure:
@@ -142,7 +143,7 @@ public void log(String message) {
142143
(ov, oldState, newState) -> {
143144
if (newState == State.SUCCEEDED) {
144145
// Begin debugging support
145-
JSObject window = (JSObject) webEngine.executeScript("window");
146+
window = (JSObject) webEngine.executeScript("window");
146147
window.setMember("bridge", bridge);
147148
webEngine.executeScript(
148149
"console.error=function(message){bridge.log('JS ERROR: '+message)};" +
@@ -1034,9 +1035,9 @@ void updateMenus() {
10341035
FRAME.restartREDUCEMenuItem.setDisable(restartREDUCEMenuItemDisabled);
10351036
FRAME.killREDUCEMenuItem.setDisable(killREDUCEMenuItemDisabled);
10361037
// View menu items:
1037-
FRAME.boldPromptsCheckBox.setSelected(boldPromptsState);
1038-
FRAME.colouredIOCheckBox.setSelected(colouredIOState);
1039-
FRAME.typesetMathsCheckBox.setSelected(typesetMathsState);
1038+
FRAME.boldPromptsCheckMenuItem.setSelected(boldPromptsState);
1039+
FRAME.colouredIOCheckMenuItem.setSelected(colouredIOState);
1040+
FRAME.typesetMathsCheckMenuItem.setSelected(typesetMathsState);
10401041
// Templates and Functions menus:
10411042
FRAME.templatesMenu.setDisable(templatesMenuDisabled);
10421043
FRAME.functionsMenu.setDisable(functionsMenuDisabled);

src/fjwright/runreduce/RunREDUCE.java

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import javafx.scene.text.Font;
3030
import javafx.stage.Screen;
3131
import javafx.stage.Stage;
32+
import org.w3c.dom.events.EventListener;
33+
import org.w3c.dom.events.EventTarget;
3234

3335
import java.util.ArrayList;
3436
import java.util.Arrays;
@@ -45,6 +47,7 @@ public class RunREDUCE extends Application {
4547
static int tabLabelNumber = 1;
4648
public static REDUCEPanel reducePanel; // the REDUCEPanel with current focus
4749
static List<REDUCEPanel> reducePanelList = new ArrayList<>();
50+
private static REDUCEPanel reducePanel2; // the split pane REDUCEPanel without current focus
4851

4952
// Set the main window to 2/3 the linear dimension of the screen initially:
5053
static final Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
@@ -73,12 +76,12 @@ public void start(Stage primaryStage) throws Exception {
7376
primaryStage.setMinHeight(375);
7477
primaryStage.getIcons().addAll(RRicon128Image);
7578

76-
// REDUCE I/O requires a monospaced font:
77-
// Only "system" fonts (in C:\Windows\Fonts) are found, not
78-
// "user" fonts (in C:\Users\franc\AppData\Local\Microsoft\Windows\Fonts).
79-
// ("DejaVu Sans Mono" is my only "user" font.)
80-
// ToDo Consider bundling a font as a resource.
81-
reduceFontFamilyName = REDUCEConfiguration.windowsOS ? "Consolas" : "DejaVu Sans Mono";
79+
// REDUCE I/O requires a monospaced font:
80+
// Only "system" fonts (in C:\Windows\Fonts) are found, not
81+
// "user" fonts (in C:\Users\franc\AppData\Local\Microsoft\Windows\Fonts).
82+
// ("DejaVu Sans Mono" is my only "user" font.)
83+
// ToDo Consider bundling a font as a resource.
84+
reduceFontFamilyName = REDUCEConfiguration.windowsOS ? "Consolas" : "DejaVu Sans Mono";
8285
Font reduceFont = Font.font(reduceFontFamilyName, RRPreferences.fontSize);
8386
if (!reduceFont.getFamily().equals(reduceFontFamilyName))
8487
alert(Alert.AlertType.WARNING, "REDUCE I/O Font",
@@ -107,7 +110,7 @@ public void start(Stage primaryStage) throws Exception {
107110

108111
static void useSplitPane(boolean enable, boolean startup) {
109112
if (enable) {
110-
REDUCEPanel reducePanel2 = new REDUCEPanel();
113+
reducePanel2 = new REDUCEPanel();
111114
reducePanelList.add(reducePanel2);
112115
splitPane = new SplitPane(reducePanel, reducePanel2);
113116
splitPane.setDividerPositions(0.5);
@@ -118,26 +121,32 @@ static void useSplitPane(boolean enable, boolean startup) {
118121
if (startup)
119122
reducePanel.setSelected(true);
120123
else {
121-
reducePanel.setSelected(false); // old panel
124+
REDUCEPanel tmp = reducePanel; // swap panels
122125
reducePanel = reducePanel2; // new panel
126+
reducePanel2 = tmp;
123127
reducePanel.setSelected(true);
124128
reducePanel.updateMenus();
125129
reducePanel.inputTextArea.requestFocus();
126130
}
127131
} else { // Revert to single pane.
128-
reducePanelList.removeIf(x -> x != reducePanel);
132+
reducePanelList.remove(reducePanel2);
133+
reducePanel2 = null; // release resources
129134
splitPane = null; // release resources
130135
reducePanel.removeEventFilter(MouseEvent.MOUSE_CLICKED, RunREDUCE::splitPaneMouseClicked);
131-
// Retain the reducePanel from the selected tab:
136+
((EventTarget) reducePanel.doc).removeEventListener("scroll", scrollListener, false);
137+
RunREDUCE.runREDUCEFrame.syncScrollCheckMenuItem.setSelected(false);
138+
// Retain the selected reducePanel:
132139
runREDUCEFrame.frame.setCenter(reducePanel);
133140
reducePanel.activeLabel.setVisible(false);
134141
}
142+
RunREDUCE.runREDUCEFrame.syncScrollCheckMenuItem.setDisable(!enable);
135143
}
136144

137145
private static void splitPaneMouseClicked(MouseEvent event) {
138146
Node node = (Node) event.getSource();
139147
if (node == reducePanel) return;
140148
reducePanel.setSelected(false); // other panel
149+
reducePanel2 = reducePanel;
141150
reducePanel = (REDUCEPanel) node; // this panel
142151
reducePanel.setSelected(true);
143152
reducePanel.updateMenus();
@@ -150,17 +159,32 @@ private static void splitPaneKeyPressed(KeyEvent event) {
150159
event.getCode() == KeyCode.PAGE_UP ||
151160
event.getCode() == KeyCode.PAGE_DOWN)) {
152161
reducePanel.setSelected(false); // current panel
153-
for (var rp : reducePanelList)
154-
if (rp != reducePanel) {
155-
reducePanel = rp;
156-
break;
157-
}
162+
REDUCEPanel tmp = reducePanel; // swap panels
163+
reducePanel = reducePanel2;
164+
reducePanel2 = tmp;
158165
reducePanel.setSelected(true); // new panel
159166
reducePanel.updateMenus();
160167
reducePanel.inputTextArea.requestFocus();
161168
}
162169
}
163170

171+
static final EventListener scrollListener = new EventListener() {
172+
public void handleEvent(org.w3c.dom.events.Event ev) {
173+
int scrollY = (int) reducePanel.window.getMember("scrollY");
174+
reducePanel2.window.call("scrollTo", 0, scrollY);
175+
}
176+
};
177+
178+
static void setUseSplitPaneSyncScroll(boolean enable) {
179+
if (enable) {
180+
((EventTarget) reducePanel.doc).addEventListener("scroll", scrollListener, false);
181+
((EventTarget) reducePanel2.doc).addEventListener("scroll", scrollListener, false);
182+
} else {
183+
((EventTarget) reducePanel.doc).removeEventListener("scroll", scrollListener, false);
184+
((EventTarget) reducePanel2.doc).removeEventListener("scroll", scrollListener, false);
185+
}
186+
}
187+
164188
static void useTabPane(boolean enable) {
165189
if (enable) {
166190
tabPane = new TabPane();

src/fjwright/runreduce/RunREDUCEFrame.fxml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@
5353
<MenuItem mnemonicParsing="false" onAction="#fontSizeMenuItemAction" text="Font Size..."/>
5454
<MenuItem mnemonicParsing="false" onAction="#fontColorsMenuItemAction" text="Font Colours..."/>
5555
<SeparatorMenuItem mnemonicParsing="false"/>
56-
<CheckMenuItem fx:id="boldPromptsCheckBox" mnemonicParsing="false" onAction="#boldPromptsCheckBoxAction"
57-
text="Bold Prompts"/>
58-
<CheckMenuItem fx:id="colouredIOCheckBox" mnemonicParsing="false" onAction="#colouredIOCheckBoxAction"
59-
text="I/O Colouring"/>
60-
<CheckMenuItem fx:id="typesetMathsCheckBox" mnemonicParsing="false"
56+
<CheckMenuItem fx:id="boldPromptsCheckMenuItem" mnemonicParsing="false"
57+
onAction="#boldPromptsCheckBoxAction" text="Bold Prompts"/>
58+
<CheckMenuItem fx:id="colouredIOCheckMenuItem" mnemonicParsing="false"
59+
onAction="#colouredIOCheckBoxAction" text="I/O Colouring"/>
60+
<CheckMenuItem fx:id="typesetMathsCheckMenuItem" mnemonicParsing="false"
6161
onAction="#typesetMathsCheckBoxAction" text="Typeset Maths"/>
6262
<SeparatorMenuItem mnemonicParsing="false"/>
6363
<RadioMenuItem fx:id="singlePaneRadioButton" mnemonicParsing="false"
@@ -72,6 +72,9 @@
7272
<RadioMenuItem fx:id="tabbedPaneRadioButton" mnemonicParsing="false"
7373
onAction="#tabbedPaneRadioButtonAction" text="Tabbed Pane Display"
7474
toggleGroup="$displayPaneButtonGroup"/>
75+
<SeparatorMenuItem mnemonicParsing="false"/>
76+
<CheckMenuItem fx:id="syncScrollCheckMenuItem" disable="true" mnemonicParsing="false"
77+
onAction="#syncScrollCheckMenuItemAction" text="Synchronize Scrolling"/>
7578
<MenuItem fx:id="addTabMenuItem" disable="true" mnemonicParsing="false" onAction="#addTabMenuItemAction"
7679
text="Add Another Tab"/>
7780
</Menu>

src/fjwright/runreduce/RunREDUCEFrame.java

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public class RunREDUCEFrame {
5454
private Menu autoRunREDUCESubmenu;
5555
// View menu:
5656
@FXML
57-
CheckMenuItem boldPromptsCheckBox, colouredIOCheckBox, typesetMathsCheckBox;
57+
CheckMenuItem boldPromptsCheckMenuItem, colouredIOCheckMenuItem, typesetMathsCheckMenuItem, syncScrollCheckMenuItem;
5858
@FXML
5959
RadioMenuItem singlePaneRadioButton;
6060
@FXML
@@ -116,15 +116,13 @@ private void initialize() {
116116
* View menu *
117117
* ********* */
118118

119-
boldPromptsCheckBox.setSelected(RRPreferences.boldPromptsState);
120-
121-
colouredIOCheckBox.setSelected(RRPreferences.colouredIOState);
122-
123-
typesetMathsCheckBox.setSelected(RRPreferences.typesetMathsState);
124-
119+
boldPromptsCheckMenuItem.setSelected(RRPreferences.boldPromptsState);
120+
colouredIOCheckMenuItem.setSelected(RRPreferences.colouredIOState);
121+
typesetMathsCheckMenuItem.setSelected(RRPreferences.typesetMathsState);
125122
singlePaneRadioButton.setSelected(RRPreferences.displayPane == RRPreferences.DisplayPane.SINGLE);
126123
splitPaneRadioButton.setSelected(RRPreferences.displayPane == RRPreferences.DisplayPane.SPLIT);
127124
tabbedPaneRadioButton.setSelected(RRPreferences.displayPane == RRPreferences.DisplayPane.TABBED);
125+
syncScrollCheckMenuItem.setDisable(RRPreferences.displayPane != RRPreferences.DisplayPane.SPLIT);
128126
addTabMenuItem.setDisable(RRPreferences.displayPane != RRPreferences.DisplayPane.TABBED);
129127

130128
/* ********* *
@@ -487,12 +485,12 @@ private void fontSizeMenuItemAction() {
487485

488486
@FXML
489487
private void boldPromptsCheckBoxAction() {
490-
RRPreferences.save(RRPreferences.BOLDPROMPTS, boldPromptsCheckBox.isSelected());
488+
RRPreferences.save(RRPreferences.BOLDPROMPTS, boldPromptsCheckMenuItem.isSelected());
491489
}
492490

493491
@FXML
494492
private void colouredIOCheckBoxAction() {
495-
RRPreferences.save(RRPreferences.COLOUREDIO, colouredIOCheckBox.isSelected());
493+
RRPreferences.save(RRPreferences.COLOUREDIO, colouredIOCheckMenuItem.isSelected());
496494
}
497495

498496
@FXML
@@ -502,7 +500,7 @@ private void fontColorsMenuItemAction() {
502500

503501
@FXML
504502
private void typesetMathsCheckBoxAction() {
505-
RRPreferences.save(RRPreferences.TYPESET_MATHS, typesetMathsCheckBox.isSelected());
503+
RRPreferences.save(RRPreferences.TYPESET_MATHS, typesetMathsCheckMenuItem.isSelected());
506504
}
507505

508506
@FXML
@@ -535,6 +533,11 @@ private void tabbedPaneRadioButtonAction() {
535533
addTabMenuItem.setDisable(false);
536534
}
537535

536+
@FXML
537+
private void syncScrollCheckMenuItemAction() {
538+
RunREDUCE.setUseSplitPaneSyncScroll(syncScrollCheckMenuItem.isSelected());
539+
}
540+
538541
@FXML
539542
private void addTabMenuItemAction() {
540543
RunREDUCE.addTab();
@@ -662,7 +665,7 @@ private void sourceForgeMenuItemAction() {
662665
RunREDUCE.hostServices.showDocument("https://sourceforge.net/projects/reduce-algebra/");
663666
}
664667

665-
static final String VERSION = "2.65";
668+
static final String VERSION = "2.66";
666669

667670
@FXML
668671
private void aboutMenuItemAction() {

0 commit comments

Comments
 (0)