Skip to content

Commit 2c2c52d

Browse files
AustinShalitJLLeitschuh
authored andcommitted
Add About window (#588)
* Add About window * Use Application Modal instead of always on top * Add links to Github and ScreenSteps to the about dialog * Apply @JLLeitschuh patch * New button style * Fix open twice bug * Change Cursor to Hand while over links * Use CSS formating instead of Rectangle * Use utility style and autoclose * Fix Windows font bug * Fix tests so a mock network module is now injected * Updated to use Roboto fonts not loaded with CSS (#590) * Remove unused assert
1 parent fcb4cb9 commit 2c2c52d

File tree

10 files changed

+223
-5
lines changed

10 files changed

+223
-5
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package edu.wpi.grip.core.operations.network;
2+
3+
import com.google.inject.AbstractModule;
4+
import com.google.inject.name.Names;
5+
import edu.wpi.grip.core.operations.network.ros.MockROSManager;
6+
import edu.wpi.grip.core.operations.network.ros.ROSNetworkPublisherFactory;
7+
8+
/**
9+
* A mock of {@Link GRIPNetworkModule} for testing.
10+
*/
11+
public final class MockGRIPNetworkModule extends AbstractModule {
12+
@Override
13+
protected void configure() {
14+
bind(MapNetworkPublisherFactory.class)
15+
.annotatedWith(Names.named("ntManager"))
16+
.to(MockMapNetworkPublisher.class);
17+
bind(ROSNetworkPublisherFactory.class)
18+
.annotatedWith(Names.named("rosManager"))
19+
.to(MockROSManager.class);
20+
}
21+
}

core/src/test/java/edu/wpi/grip/core/operations/network/MockMapNetworkPublisher.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package edu.wpi.grip.core.operations.network;
22

3-
3+
import java.util.Collections;
44
import java.util.Map;
55
import java.util.Optional;
66
import java.util.Set;
77

88
@SuppressWarnings("PMD.UncommentedEmptyMethodBody")
9-
public class MockMapNetworkPublisher<T> extends MapNetworkPublisher<T> {
9+
public class MockMapNetworkPublisher<T> extends MapNetworkPublisher<T> implements MapNetworkPublisherFactory {
10+
11+
public MockMapNetworkPublisher() {
12+
this(Collections.emptySet());
13+
}
1014

1115
public MockMapNetworkPublisher(Set<String> keys) {
1216
super(keys);
@@ -36,4 +40,9 @@ protected void publishNameChanged(Optional<String> oldName, String newName) {
3640
public void close() {
3741

3842
}
43+
44+
@Override
45+
public <T> MapNetworkPublisher<T> create(Set<String> keys) {
46+
return new MockMapNetworkPublisher<>(keys);
47+
}
3948
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package edu.wpi.grip.core.operations.network.ros;
2+
3+
public class MockROSManager implements ROSNetworkPublisherFactory {
4+
5+
@Override
6+
public <C extends JavaToMessageConverter> ROSMessagePublisher create(C converter) {
7+
return null;
8+
}
9+
}

core/src/test/java/edu/wpi/grip/core/operations/network/ros/ROSPackageSanityTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
public class ROSPackageSanityTest extends AbstractPackageSanityTests {
77
public ROSPackageSanityTest() {
88
super();
9-
ignoreClasses(c -> c.equals(ROSLoader.class));
9+
ignoreClasses(c -> c.equals(ROSLoader.class) || c.equals(MockROSManager.class));
1010
setDefault(JavaToMessageConverter.class, JavaToMessageConverter.BLOBS);
1111
}
1212
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package edu.wpi.grip.ui;
2+
3+
import javafx.fxml.FXML;
4+
import javafx.scene.control.Label;
5+
import javafx.scene.input.MouseEvent;
6+
7+
import javax.inject.Inject;
8+
9+
public class AboutDialogController {
10+
11+
@Inject
12+
private Main main;
13+
14+
@FXML
15+
private Label versionNumberLabel;
16+
17+
@FXML
18+
void mousePressedDocumentationButton(MouseEvent event) {
19+
main.getHostServices().showDocument("http://wpilib.screenstepslive.com/s/4485/m/50711");
20+
}
21+
22+
@FXML
23+
void mousePressedGithubButton(MouseEvent event) {
24+
main.getHostServices().showDocument("https://github.com/WPIRoboticsProjects/GRIP");
25+
}
26+
27+
@FXML
28+
void initialize() {
29+
versionNumberLabel.setText("Version " + edu.wpi.grip.core.Main.class.getPackage().getImplementationVersion());
30+
}
31+
}

ui/src/main/java/edu/wpi/grip/ui/MainWindowController.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import javafx.application.Platform;
1818
import javafx.fxml.FXML;
1919
import javafx.scene.Parent;
20+
import javafx.scene.Scene;
2021
import javafx.scene.control.ButtonType;
2122
import javafx.scene.control.Dialog;
2223
import javafx.scene.control.SplitPane;
@@ -26,6 +27,8 @@
2627
import javafx.scene.layout.Region;
2728
import javafx.stage.FileChooser;
2829
import javafx.stage.FileChooser.ExtensionFilter;
30+
import javafx.stage.Stage;
31+
import javafx.stage.StageStyle;
2932
import org.controlsfx.control.StatusBar;
3033

3134
import javax.inject.Inject;
@@ -49,6 +52,8 @@ public class MainWindowController {
4952
@FXML
5053
private Pane deployPane;
5154
@FXML
55+
private Pane aboutPane;
56+
@FXML
5257
private StatusBar statusBar;
5358
@Inject
5459
private EventBus eventBus;
@@ -65,6 +70,8 @@ public class MainWindowController {
6570
@Inject
6671
private Project project;
6772

73+
private Stage aboutDialogStage;
74+
6875
public void initialize() {
6976
pipelineView.prefHeightProperty().bind(bottomPane.heightProperty());
7077
statusBar.getLeftItems().add(startStoppableButtonFactory.create(pipelineRunner));
@@ -209,6 +216,21 @@ public void showProjectSettingsEditor() {
209216
});
210217
}
211218

219+
@FXML
220+
public void showProjectAboutDialog() throws IOException {
221+
if (aboutDialogStage == null) {
222+
aboutDialogStage = new Stage();
223+
aboutDialogStage.setScene(new Scene(aboutPane));
224+
aboutDialogStage.initStyle(StageStyle.UTILITY);
225+
aboutDialogStage.focusedProperty().addListener((observable, oldvalue, newvalue) -> {
226+
if (oldvalue) {
227+
aboutDialogStage.hide();
228+
}
229+
});
230+
}
231+
aboutDialogStage.show();
232+
}
233+
212234
@FXML
213235
public void quit() {
214236
if (showConfirmationDialogAndWait()) {
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<?import java.net.URL?>
4+
<?import javafx.geometry.Insets?>
5+
<?import javafx.scene.control.Label?>
6+
<?import javafx.scene.image.Image?>
7+
<?import javafx.scene.image.ImageView?>
8+
<?import javafx.scene.layout.HBox?>
9+
<?import javafx.scene.layout.Pane?>
10+
<?import javafx.scene.layout.StackPane?>
11+
<?import javafx.scene.layout.VBox?>
12+
<?import javafx.scene.text.Font?>
13+
14+
<VBox fx:id="root" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="330.0" prefWidth="600.0" styleClass="about-window" stylesheets="@GRIP.css" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="edu.wpi.grip.ui.AboutDialogController">
15+
<children>
16+
<Pane VBox.vgrow="ALWAYS" />
17+
<HBox>
18+
<children>
19+
<Pane HBox.hgrow="ALWAYS" />
20+
<ImageView fitHeight="156.0" fitWidth="156.0" pickOnBounds="true" preserveRatio="true">
21+
<image>
22+
<Image url="@icons/grip.png" />
23+
</image>
24+
</ImageView>
25+
<Pane HBox.hgrow="ALWAYS" />
26+
<VBox HBox.hgrow="ALWAYS">
27+
<children>
28+
<Label style="-fx-font-size: 64; -fx-font-weight: BOLD;" text="GRIP" />
29+
<Label fx:id="versionNumberLabel" text="Version 0.0.0" />
30+
<Pane VBox.vgrow="ALWAYS" />
31+
<HBox>
32+
<children>
33+
<StackPane onMousePressed="#mousePressedGithubButton" styleClass="about-button">
34+
<children>
35+
<Label text="➔ Github">
36+
<font>
37+
<Font size="14.0" />
38+
</font></Label>
39+
</children>
40+
<opaqueInsets>
41+
<Insets />
42+
</opaqueInsets>
43+
<HBox.margin>
44+
<Insets left="-3.0" />
45+
</HBox.margin>
46+
<padding>
47+
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
48+
</padding>
49+
</StackPane>
50+
</children>
51+
</HBox>
52+
<Pane VBox.vgrow="ALWAYS" />
53+
<HBox>
54+
<children>
55+
<StackPane onMousePressed="#mousePressedDocumentationButton" styleClass="about-button">
56+
<children>
57+
<Label text="➔ ScreenSteps Documentation" />
58+
</children>
59+
<HBox.margin>
60+
<Insets left="-3.0" />
61+
</HBox.margin>
62+
<padding>
63+
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
64+
</padding>
65+
</StackPane>
66+
</children>
67+
</HBox>
68+
</children>
69+
</VBox>
70+
<Pane HBox.hgrow="ALWAYS" />
71+
</children>
72+
</HBox>
73+
<Pane VBox.vgrow="ALWAYS">
74+
<VBox.margin>
75+
<Insets />
76+
</VBox.margin>
77+
</Pane>
78+
<HBox>
79+
<children>
80+
<Pane HBox.hgrow="ALWAYS" />
81+
<Label style="-fx-font-size: 12;" text="GRIP is licensed under a 3 Clause BSD License" textFill="#818181" />
82+
<Pane HBox.hgrow="ALWAYS" />
83+
</children>
84+
<padding>
85+
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
86+
</padding>
87+
</HBox>
88+
</children>
89+
<stylesheets>
90+
<URL value="@GRIP.css" />
91+
</stylesheets>
92+
</VBox>

ui/src/main/resources/edu/wpi/grip/ui/GRIP.css

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,4 +233,18 @@ VBox.sockets {
233233

234234
.info-label {
235235
-fx-font-weight: bold;
236-
}
236+
}
237+
238+
.about-window Label {
239+
-fx-font-size: 14;
240+
}
241+
242+
.about-button:hover {
243+
-fx-background-color: gray;
244+
-fx-background-radius: 12;
245+
-fx-cursor: hand;
246+
}
247+
248+
.about-button:hover Label {
249+
-fx-text-fill: white;
250+
}

ui/src/main/resources/edu/wpi/grip/ui/MainWindow.fxml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,23 @@
132132
</graphic>
133133
</MenuItem>
134134
</Menu>
135+
<Menu text="Help">
136+
<MenuItem text="About" onAction="#showProjectAboutDialog">
137+
<graphic>
138+
<ImageView styleClass="menu-graphic">
139+
<fitWidth>
140+
<DPIUtility fx:constant="SMALL_ICON_SIZE"/>
141+
</fitWidth>
142+
<fitHeight>
143+
<DPIUtility fx:constant="SMALL_ICON_SIZE"/>
144+
</fitHeight>
145+
<image>
146+
<Image url="@icons/grip.png"/>
147+
</image>
148+
</ImageView>
149+
</graphic>
150+
</MenuItem>
151+
</Menu>
135152
</MenuBar>
136153
<SplitPane dividerPositions="0.6" orientation="VERTICAL" VBox.vgrow="ALWAYS">
137154
<items>
@@ -148,6 +165,7 @@
148165
</children>
149166
<fx:define>
150167
<fx:include source="Deploy.fxml" fx:id="deployPane"/>
168+
<fx:include source="AboutDialog.fxml" fx:id="aboutPane"/>
151169
</fx:define>
152170
<stylesheets>
153171
<URL value="@GRIP.css"/>

ui/src/test/java/edu/wpi/grip/ui/MainWindowTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.google.inject.util.Modules;
88
import edu.wpi.grip.core.*;
99
import edu.wpi.grip.core.events.OperationAddedEvent;
10+
import edu.wpi.grip.core.operations.network.MockGRIPNetworkModule;
1011
import edu.wpi.grip.core.sockets.InputSocket;
1112
import edu.wpi.grip.core.sockets.OutputSocket;
1213
import edu.wpi.grip.ui.util.DPIUtility;
@@ -39,7 +40,8 @@ public class MainWindowTest extends ApplicationTest {
3940
public void start(Stage stage) throws Exception {
4041
testModule.setUp();
4142

42-
Injector injector = Guice.createInjector(Modules.override(testModule).with(new GRIPUIModule()));
43+
Injector injector = Guice.createInjector(
44+
Modules.override(testModule, new MockGRIPNetworkModule()).with(new GRIPUIModule()));
4345

4446
final Parent root =
4547
FXMLLoader.load(Main.class.getResource("MainWindow.fxml"), null, null, injector::getInstance);

0 commit comments

Comments
 (0)