Skip to content

Commit 38ac76d

Browse files
committed
Use macOS menu bar
1 parent 7387d0c commit 38ac76d

File tree

7 files changed

+144
-50
lines changed

7 files changed

+144
-50
lines changed

.idea/modules/blobsaver_main.iml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules/blobsaver_test.iml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ If you have an antivirus or firewall, you may need to disable some other setting
2323
Please send feedback via [Github Issue](https://github.com/airsquared/blobsaver/issues/new/choose) or [Reddit PM](https://www.reddit.com//message/compose?to=01110101_00101111&subject=Blobsaver+Feedback) if you encounter any bugs/problems or have a feature request.
2424

2525
## TODO:
26-
- Use macOS menu bar
2726
- Auto-upload to Dropbox/Google Drive
2827
- Package into .app/.exe [maybe this](https://github.com/Jorl17/jar2app)
2928
- Better notifications

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ dependencies {
1818
compile group: 'org.json', name: 'json', version: '20180130'
1919
compile fileTree(dir: 'libs', include: ['*.jar'])
2020
compile group: 'it.sauronsoftware', name: 'junique', version: '1.0.4'
21+
compile "de.codecentric.centerdevice:centerdevice-nsmenufx:2.1.6"
2122
}
2223

2324
compileJava {

src/main/java/blobsaver/Controller.java

Lines changed: 135 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020

2121
import com.sun.javafx.PlatformUtil;
2222
import com.sun.javafx.scene.control.skin.LabeledText;
23+
import de.codecentric.centerdevice.MenuToolkit;
2324
import javafx.application.Platform;
2425
import javafx.beans.value.ObservableValue;
2526
import javafx.collections.FXCollections;
2627
import javafx.collections.ObservableList;
2728
import javafx.event.ActionEvent;
29+
import javafx.event.EventHandler;
2830
import javafx.fxml.FXML;
2931
import javafx.scene.control.*;
3032
import javafx.scene.effect.DropShadow;
@@ -33,6 +35,7 @@
3335
import javafx.scene.layout.VBox;
3436
import javafx.scene.paint.Color;
3537
import javafx.stage.DirectoryChooser;
38+
import javafx.stage.WindowEvent;
3639
import org.json.JSONArray;
3740

3841
import java.awt.Desktop;
@@ -54,6 +57,7 @@
5457
import java.util.zip.ZipInputStream;
5558

5659
import static blobsaver.Main.appPrefs;
60+
import static blobsaver.Main.primaryStage;
5761
import static blobsaver.Shared.githubIssue;
5862
import static blobsaver.Shared.newReportableError;
5963
import static blobsaver.Shared.newUnreportableError;
@@ -64,6 +68,8 @@
6468
public class Controller {
6569

6670

71+
@FXML private MenuBar menuBar;
72+
6773
@FXML private ChoiceBox deviceTypeChoiceBox;
6874
@FXML private ChoiceBox deviceModelChoiceBox;
6975

@@ -261,6 +267,17 @@ public void initialize() {
261267
path = path.replaceAll("%20", " ");
262268
pathField.setText(path);
263269

270+
if (PlatformUtil.isMac()) {
271+
EventHandler<WindowEvent> onShowing = new EventHandler<WindowEvent>() {
272+
@Override
273+
public void handle(WindowEvent event) {
274+
log("using macos menu bar");
275+
useMacOSMenuBar();
276+
primaryStage.removeEventHandler(event.getEventType(), this);
277+
}
278+
};
279+
primaryStage.setOnShowing(onShowing);
280+
}
264281
}
265282

266283
public void checkForUpdatesHandler() {
@@ -768,61 +785,132 @@ public void aboutMenuHandler() {
768785
"This program is licensed under GNU GPL v3.0-only");
769786
resizeAlertButtons(alert);
770787
alert.showAndWait();
771-
if (githubRepo.equals(alert.getResult())) {
772-
try {
773-
Desktop.getDesktop().browse(new URI("https://github.com/airsquared/blobsaver"));
774-
} catch (IOException | URISyntaxException e) {
775-
e.printStackTrace();
776-
}
777-
} else if (viewLicense.equals(alert.getResult())) {
778-
try {
779-
InputStream input;
780-
if (PlatformUtil.isWindows()) {
781-
input = Main.class.getResourceAsStream("gpl-3.0_windows.txt");
782-
} else {
783-
input = Main.class.getResourceAsStream("gpl-3.0.txt");
788+
switch (alert.getResult().getText()) {
789+
case "Github Repo":
790+
try {
791+
Desktop.getDesktop().browse(new URI("https://github.com/airsquared/blobsaver"));
792+
} catch (IOException | URISyntaxException e) {
793+
e.printStackTrace();
784794
}
785-
File licenseFile = File.createTempFile("gpl-3.0_", ".txt");
786-
OutputStream out = new FileOutputStream(licenseFile);
787-
int read;
788-
byte[] bytes = new byte[1024];
795+
break;
796+
case "View License":
797+
try {
798+
InputStream input;
799+
if (PlatformUtil.isWindows()) {
800+
input = Main.class.getResourceAsStream("gpl-3.0_windows.txt");
801+
} else {
802+
input = Main.class.getResourceAsStream("gpl-3.0.txt");
803+
}
804+
File licenseFile = File.createTempFile("gpl-3.0_", ".txt");
805+
OutputStream out = new FileOutputStream(licenseFile);
806+
int read;
807+
byte[] bytes = new byte[1024];
789808

790-
while ((read = input.read(bytes)) != -1) {
791-
out.write(bytes, 0, read);
792-
}
793-
out.close();
794-
licenseFile.deleteOnExit();
795-
licenseFile.setReadOnly();
796-
java.awt.Desktop.getDesktop().edit(licenseFile);
797-
} catch (IOException e) {
798-
e.printStackTrace();
799-
}
800-
} else if (librariesUsed.equals(alert.getResult())) {
801-
try {
802-
InputStream input;
803-
if (PlatformUtil.isWindows()) {
804-
input = getClass().getResourceAsStream("libraries_used_windows.txt");
805-
} else {
806-
input = getClass().getResourceAsStream("libraries_used.txt");
809+
while ((read = input.read(bytes)) != -1) {
810+
out.write(bytes, 0, read);
811+
}
812+
out.close();
813+
licenseFile.deleteOnExit();
814+
licenseFile.setReadOnly();
815+
java.awt.Desktop.getDesktop().edit(licenseFile);
816+
} catch (IOException e) {
817+
e.printStackTrace();
807818
}
808-
File libsUsedFile = File.createTempFile("blobsaver-libraries_used_", ".txt");
809-
OutputStream out = new FileOutputStream(libsUsedFile);
810-
int read;
811-
byte[] bytes = new byte[1024];
819+
break;
820+
case "Libraries Used":
821+
try {
822+
InputStream input;
823+
if (PlatformUtil.isWindows()) {
824+
input = Main.class.getResourceAsStream("libraries_used_windows.txt");
825+
} else {
826+
input = Main.class.getResourceAsStream("libraries_used.txt");
827+
}
828+
File libsUsedFile = File.createTempFile("blobsaver-libraries_used_", ".txt");
829+
OutputStream out = new FileOutputStream(libsUsedFile);
830+
int read;
831+
byte[] bytes = new byte[1024];
812832

813-
while ((read = input.read(bytes)) != -1) {
814-
out.write(bytes, 0, read);
833+
while ((read = input.read(bytes)) != -1) {
834+
out.write(bytes, 0, read);
835+
}
836+
out.close();
837+
libsUsedFile.deleteOnExit();
838+
libsUsedFile.setReadOnly();
839+
java.awt.Desktop.getDesktop().edit(libsUsedFile);
840+
} catch (IOException e) {
841+
e.printStackTrace();
815842
}
816-
out.close();
817-
libsUsedFile.deleteOnExit();
818-
libsUsedFile.setReadOnly();
819-
java.awt.Desktop.getDesktop().edit(libsUsedFile);
820-
} catch (IOException e) {
821-
e.printStackTrace();
822-
}
843+
break;
823844
}
824845
}
825846

847+
private void useMacOSMenuBar() {
848+
849+
((VBox) menuBar.getParent()).setMinHeight(560.0);
850+
((VBox) menuBar.getParent()).setPrefHeight(560.0);
851+
presetVBox.setMinHeight(560.0);
852+
presetVBox.setPrefHeight(560.0);
853+
854+
menuBar.setUseSystemMenuBar(true);
855+
MenuBar macOSMenuBar = new MenuBar();
856+
MenuToolkit tk = MenuToolkit.toolkit();
857+
858+
Menu applicationMenu = tk.createDefaultApplicationMenu("blobsaver");
859+
860+
MenuItem aboutMenuItem = new MenuItem("About blobsaver");
861+
aboutMenuItem.setOnAction(event2 -> aboutMenuHandler());
862+
applicationMenu.getItems().set(0, aboutMenuItem);
863+
864+
MenuItem checkForUpdatesMenuItem = new MenuItem("Check for Updates...");
865+
checkForUpdatesMenuItem.setOnAction(event1 -> checkForUpdatesHandler());
866+
applicationMenu.getItems().add(1, new SeparatorMenuItem());
867+
applicationMenu.getItems().add(2, checkForUpdatesMenuItem);
868+
869+
MenuItem clearAllDataMenuItem = new MenuItem("Clear all data...");
870+
clearAllDataMenuItem.setOnAction(event1 -> resetAppHandler());
871+
applicationMenu.getItems().add(3, new SeparatorMenuItem());
872+
applicationMenu.getItems().add(4, clearAllDataMenuItem);
873+
874+
macOSMenuBar.getMenus().add(0, applicationMenu);
875+
876+
877+
Menu windowMenu = new Menu("Window");
878+
879+
windowMenu.getItems().add(new SeparatorMenuItem());
880+
windowMenu.getItems().add(tk.createMinimizeMenuItem());
881+
windowMenu.getItems().add(tk.createCycleWindowsItem());
882+
883+
MenuItem debugLogMenuItem = new MenuItem("Open/Close Debug log");
884+
debugLogMenuItem.setOnAction(event -> {
885+
debugLogHandler();
886+
tk.setMenuBar(DebugWindow.getDebugStage(), macOSMenuBar);
887+
});
888+
windowMenu.getItems().add(new SeparatorMenuItem());
889+
windowMenu.getItems().add(debugLogMenuItem);
890+
891+
windowMenu.getItems().add(new SeparatorMenuItem());
892+
windowMenu.getItems().add(tk.createBringAllToFrontItem());
893+
windowMenu.getItems().add(new SeparatorMenuItem());
894+
tk.autoAddWindowMenuItems(windowMenu);
895+
896+
macOSMenuBar.getMenus().add(windowMenu);
897+
898+
899+
Menu helpMenu = menuBar.getMenus().get(1);
900+
901+
helpMenu.getItems().add(1, new SeparatorMenuItem());
902+
helpMenu.getItems().add(4, new SeparatorMenuItem());
903+
904+
MenuItem checkForValidBlobsMenuItem = new MenuItem("Check for Valid Blobs...");
905+
checkForValidBlobsMenuItem.setOnAction(event -> checkBlobs());
906+
helpMenu.getItems().set(5, checkForValidBlobsMenuItem);
907+
908+
macOSMenuBar.getMenus().add(helpMenu);
909+
910+
911+
tk.setMenuBar(primaryStage, macOSMenuBar);
912+
}
913+
826914
public void backgroundSettingsHandler() {
827915
choosingRunInBackground = !choosingRunInBackground;
828916
if (choosingRunInBackground) {

src/main/java/blobsaver/DebugWindow.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ static void hide() {
7979
System.setErr(sysOut);
8080
}
8181

82+
static Stage getDebugStage() {
83+
return debugStage;
84+
}
85+
8286
static boolean isShowing() {
8387
return debugStage.isShowing();
8488
}

src/main/resources/blobsaver/blobsaver.fxml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<?import javafx.scene.layout.*?>
2323
<HBox xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="blobsaver.Controller">
2424
<VBox maxHeight="Infinity" maxWidth="-Infinity" minHeight="580.0" prefWidth="500.0">
25-
<MenuBar>
25+
<MenuBar fx:id="menuBar">
2626
<Menu mnemonicParsing="false" text="Options">
2727
<MenuItem mnemonicParsing="false" onAction="#debugLogHandler"
2828
text="Debug log"/>
@@ -33,7 +33,7 @@
3333
<MenuItem mnemonicParsing="false" onAction="#resetAppHandler" text="Clear all data"/>
3434
</Menu>
3535
<Menu mnemonicParsing="false" text="Help">
36-
<Menu mnemonicParsing="false" text="Wiki">
36+
<Menu mnemonicParsing="false" text="blobsaver Help/Wiki">
3737
<MenuItem mnemonicParsing="false" onAction="#showWiki"
3838
text="Wiki Home"/>
3939
<MenuItem mnemonicParsing="false" onAction="#showWiki"

0 commit comments

Comments
 (0)