Skip to content

Commit

Permalink
feat: Added Settings menu to Drifty GUI (#544)
Browse files Browse the repository at this point in the history
* added the Settings.java file - done with Auto-Paste box

* added the Settings.java file - done with Auto-Paste box

* ended the page , added heading , added dark theme CSS , added dark theme choiceBox

* added the btnSave/Start png , added the banner Dark png , added the splash dark png and make the dark theme apply on them

* testing the splash

* ended the select directory feat. , edited the labels styles

* Fromating code

* Fromating code

* Fromating code 2

* solved most of the AI bots errors

* Solved an About-stage bug

* Added the applyTheme() method in Settings.java

* modified the handelDirectory method , added messageBroker getter

* Done the bidirectionally bind between tow checbox (Settign , Main)

* modifing the autoPaste main , Settings Logic

* Fixed an Save/Start icons bug , improved the icons methods readablty

* removed the unsafe getClass().getResources()

* Refactoring the Settings code

* fix: Fixed duplicate code, linter issues, redundant method calls and removed spelling mistakes

* fix: Fixed a method spacing issue

* fix: Fixed a minor linter issue

* Add: Added the Theme.java Class , migrating the theme logic into it

* Removing unused imports and the Arralist declaration

* fix: Fixed linter issues and applied all CodeRabbitAI reviews

* fix: Fixed a minor linter issue

* Refactoring the code

* Solving some of linter errors

* fix: Implemented all of the reviews except one

* fix: Fixed linter issue

* fix: implemented all the reviews

* added the dark theme to info window

* fix: solved the lint error

* fix: sovlving the ai reveiws

* fix: linter error fixed

* fix: Fixed failure to initialise About scene in Drifty GUI native image

---------

Co-authored-by: Ziad Ashraf <[email protected]>
Co-authored-by: Saptarshi Sarkar <[email protected]>
  • Loading branch information
3 people authored Jun 26, 2024
1 parent a5c4b58 commit ebbbb0c
Show file tree
Hide file tree
Showing 32 changed files with 810 additions and 216 deletions.
1 change: 1 addition & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions GUI/src/main/java/gui/preferences/Clear.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ public void mainAutoPaste() {
preferences.remove(MAIN_AUTO_PASTE.toString());
}

public void mainTheme() {
preferences.remove(MAIN_THEME.toString());
}

public void jobs() {
preferences.remove(JOBS.toString());
}
Expand Down
5 changes: 5 additions & 0 deletions GUI/src/main/java/gui/preferences/Get.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ static Get getInstance() {
return INSTANCE;
}


public Folders folders() {
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = FxGson.addFxSupport(gsonBuilder).setPrettyPrinting().create();
Expand All @@ -41,6 +42,10 @@ public boolean mainAutoPaste() {
return preferences.getBoolean(MAIN_AUTO_PASTE.toString(), false);
}

public String mainTheme() {
return preferences.get(MAIN_THEME.toString(), "Light");
}

public Jobs jobs() {
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = FxGson.addFxSupport(gsonBuilder).setPrettyPrinting().create();
Expand Down
2 changes: 1 addition & 1 deletion GUI/src/main/java/gui/preferences/Labels.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package gui.preferences;

public enum Labels implements preferences.Labels {
FOLDERS, MAIN_AUTO_PASTE, JOBS, ALWAYS_AUTO_PASTE
FOLDERS, MAIN_AUTO_PASTE, JOBS, ALWAYS_AUTO_PASTE, MAIN_THEME
}
8 changes: 6 additions & 2 deletions GUI/src/main/java/gui/preferences/Set.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
import java.nio.file.Paths;
import java.util.prefs.Preferences;

import static gui.preferences.Labels.FOLDERS;
import static gui.preferences.Labels.MAIN_AUTO_PASTE;
import static gui.preferences.Labels.*;
import static properties.Program.JOB_FILE;

public final class Set extends preferences.Set {
Expand All @@ -42,6 +41,11 @@ public void mainAutoPaste(boolean isMainAutoPasteEnabled) {
preferences.putBoolean(MAIN_AUTO_PASTE.toString(), isMainAutoPasteEnabled);
}

public void mainTheme(String theme) {
AppSettings.CLEAR.mainTheme();
preferences.put(MAIN_THEME.toString(), theme);
}

public void jobs(Jobs jobs) {
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = FxGson.addFxSupport(gsonBuilder).setPrettyPrinting().create();
Expand Down
52 changes: 37 additions & 15 deletions GUI/src/main/java/gui/support/Constants.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package gui.support;

import gui.init.Environment;
import gui.preferences.AppSettings;
import gui.utils.UIComponentBuilder;
import javafx.geometry.Rectangle2D;
import javafx.scene.Parent;
import javafx.scene.Scene;
Expand All @@ -13,6 +15,17 @@
import java.util.Objects;

public class Constants extends support.Constants {
public static final UIComponentBuilder UI_COMPONENT_BUILDER_INSTANCE = UIComponentBuilder.getInstance();
public static final String BUTTON_RELEASED =
"-fx-text-fill: white;" +
"-fx-font-weight: Bold;" +
"-fx-background-color: linear-gradient(rgb(0, 53, 105) 20%, rgb(26, 21, 129) 65%, rgb(0, 0, 65) 100%);" +
"-fx-border-color: white;";
public static final String BUTTON_PRESSED =
"-fx-text-fill: white;" +
"-fx-font-weight: Bold;" +
" -fx-background-color: linear-gradient(rgb(11, 118, 220) 20%, rgb(33, 31, 131) 65%, rgb(2, 2, 168) 100%);\n" +
"-fx-border-color: white;";
public static final String GUI_APPLICATION_TERMINATED = "Drifty GUI (Graphical User Interface) Application Terminated!";
public static final String TRYING_TO_DOWNLOAD_F = "Trying to download \"%s\" ...";
public static final String WRITE_ACCESS_DENIED_F = "Write Access To \"%s\" DENIED!";
Expand All @@ -22,20 +35,25 @@ public class Constants extends support.Constants {
public static final double SCREEN_HEIGHT = SCREEN_SIZE.getHeight();

// Graphics Files
public static final URL DRIFTY_MAIN_PNG = Constants.class.getResource("/Backgrounds/DriftyMain.png");
public static final URL SAVE_UP_PNG = Constants.class.getResource("/Buttons/Save/SaveUp.png");
public static final URL SAVE_DOWN_PNG = Constants.class.getResource("/Buttons/Save/SaveDown.png");
public static final URL START_UP_PNG = Constants.class.getResource("/Buttons/Start/StartUp.png");
public static final URL START_DOWN_PNG = Constants.class.getResource("/Buttons/Start/StartDown.png");
public static final URL DRIFTY_MAIN_PNG = AppSettings.GET.mainTheme().equals("Dark") ? Constants.class.getResource("/Backgrounds/DriftyMainDark.png") : Constants.class.getResource("/Backgrounds/DriftyMainLight.png");
public static final URL SAVE_UP_LIGHT_PNG = Constants.class.getResource("/Buttons/Save/SaveUpLight.png");
public static final URL SAVE_UP_DARK_PNG = Constants.class.getResource("/Buttons/Save/SaveUpDark.png");
public static final URL SAVE_DOWN_LIGHT_PNG = Constants.class.getResource("/Buttons/Save/SaveDownLight.png");
public static final URL SAVE_DOWN_DARK_PNG = Constants.class.getResource("/Buttons/Save/SaveDownDark.png");
public static final URL START_UP_LIGHT_PNG = Constants.class.getResource("/Buttons/Start/StartUpLight.png");
public static final URL START_UP_DARK_PNG = Constants.class.getResource("/Buttons/Start/StartUpDark.png");
public static final URL START_DOWN_LIGHT_PNG = Constants.class.getResource("/Buttons/Start/StartDownLight.png");
public static final URL START_DOWN_DARK_PNG = Constants.class.getResource("/Buttons/Start/StartDownDark.png");
public static final URL LINK_PNG = Constants.class.getResource("/Labels/Link.png");
public static final URL AUTO_PASTE_PNG = Constants.class.getResource("/Labels/AutoPaste.png");
public static final URL DIRECTORY_PNG = Constants.class.getResource("/Labels/Directory.png");
public static final URL FILENAME_PNG = Constants.class.getResource("/Labels/Filename.png");
public static final URL DRIFTY_ICON = Constants.class.getResource("/Icons/AppIcon.png");
public static final URL SPLASH = Constants.class.getResource("/Splash.png");
public static final URL SPLASH = AppSettings.GET.mainTheme().equals("Dark") ? Constants.class.getResource("/SplashDark.png") : Constants.class.getResource("/SplashLight.png");

// Stylesheets
public static final URL SCENE_CSS = Constants.class.getResource("/CSS/Scene.css");
public static final URL LIGHT_THEME_CSS = Constants.class.getResource("/CSS/LightTheme.css");
public static final URL DARK_THEME_CSS = Constants.class.getResource("/CSS/DarkTheme.css");
public static final URL LIST_VIEW_CSS = Constants.class.getResource("/CSS/ListView.css");
public static final URL TEXT_FIELD_CSS = Constants.class.getResource("/CSS/TextField.css");
public static final URL CONTEXT_MENU_CSS = Constants.class.getResource("/CSS/ContextMenu.css");
Expand All @@ -51,18 +69,22 @@ public class Constants extends support.Constants {
public static final URL MONACO_TTF = Constants.class.getResource("/Fonts/Monaco.ttf");

// JavaFX Image Objects
public static final Image IMG_MAIN_GUI_BANNER = new Image(Objects.requireNonNull(DRIFTY_MAIN_PNG).toExternalForm());
public static final Image IMG_SPLASH = new Image(Objects.requireNonNull(SPLASH).toExternalForm());
public static Image imgMainGuiBanner = new Image(Objects.requireNonNull(DRIFTY_MAIN_PNG).toExternalForm());
public static Image imgSplash = new Image(Objects.requireNonNull(SPLASH).toExternalForm());
public static final Image IMG_LINK_LABEL = new Image(Objects.requireNonNull(LINK_PNG).toExternalForm());
public static final Image IMG_DIR_LABEL = new Image(Objects.requireNonNull(DIRECTORY_PNG).toExternalForm());
public static final Image IMG_FILENAME_LABEL = new Image(Objects.requireNonNull(FILENAME_PNG).toExternalForm());
public static final Image IMG_AUTO_PASTE_LABEL = new Image(Objects.requireNonNull(AUTO_PASTE_PNG).toExternalForm());
public static final Image IMG_START_UP = new Image(Objects.requireNonNull(START_UP_PNG).toExternalForm());
public static final Image IMG_START_DOWN = new Image(Objects.requireNonNull(START_DOWN_PNG).toExternalForm());
public static final Image IMG_SAVE_UP = new Image(Objects.requireNonNull(SAVE_UP_PNG).toExternalForm());
public static final Image IMG_SAVE_DOWN = new Image(Objects.requireNonNull(SAVE_DOWN_PNG).toExternalForm());
public static final Image IMG_START_UP_LIGHT = new Image(Objects.requireNonNull(START_UP_LIGHT_PNG).toExternalForm());
public static final Image IMG_START_UP_DARK = new Image(Objects.requireNonNull(START_UP_DARK_PNG).toExternalForm());
public static final Image IMG_START_DOWN_LIGHT = new Image(Objects.requireNonNull(START_DOWN_LIGHT_PNG).toExternalForm());
public static final Image IMG_START_DOWN_DARK = new Image(Objects.requireNonNull(START_DOWN_DARK_PNG).toExternalForm());
public static final Image IMG_SAVE_UP_LIGHT = new Image(Objects.requireNonNull(SAVE_UP_LIGHT_PNG).toExternalForm());
public static final Image IMG_SAVE_UP_DARK = new Image(Objects.requireNonNull(SAVE_UP_DARK_PNG).toExternalForm());
public static final Image IMG_SAVE_DOWN_LIGHT = new Image(Objects.requireNonNull(SAVE_DOWN_LIGHT_PNG).toExternalForm());
public static final Image IMG_SAVE_DOWN_DARK = new Image(Objects.requireNonNull(SAVE_DOWN_DARK_PNG).toExternalForm());

// Methods for obtaining consistent Stages and Scenes
// Methods for getting consistent Stages and Scenes
public static Stage getStage(String title, boolean isPrimaryStage) {
Stage stage = new Stage();
Image icon = new Image(Objects.requireNonNull(DRIFTY_ICON).toExternalForm());
Expand All @@ -82,7 +104,7 @@ public static Stage getStage(String title, boolean isPrimaryStage) {

public static Scene getScene(Parent root) {
Scene scene = new Scene(root);
addCSS(scene, CHECK_BOX_CSS, CONTEXT_MENU_CSS, LABEL_CSS, LIST_VIEW_CSS, MENU_CSS, PROGRESS_BAR_CSS, SCENE_CSS, SCROLL_PANE_CSS, TEXT_FIELD_CSS, V_BOX_CSS, BUTTON_CSS);
addCSS(scene, CHECK_BOX_CSS, CONTEXT_MENU_CSS, LABEL_CSS, LIST_VIEW_CSS, MENU_CSS, LIGHT_THEME_CSS, PROGRESS_BAR_CSS, SCROLL_PANE_CSS, TEXT_FIELD_CSS, V_BOX_CSS, BUTTON_CSS);
return scene;
}

Expand Down
72 changes: 72 additions & 0 deletions GUI/src/main/java/gui/utils/UIComponentBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package gui.utils;

import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Paint;
import javafx.scene.text.Font;
import main.Drifty_GUI;

import java.util.Objects;

import static gui.support.Constants.MONACO_TTF;

public class UIComponentBuilder {
private static UIComponentBuilder instance;

public static UIComponentBuilder getInstance() {
if (instance == null) {
instance = new UIComponentBuilder();
}
return instance;
}

public Label buildLabel() {
Label label = new Label("");
label.setFont(new Font(Objects.requireNonNull(MONACO_TTF).toExternalForm(), 20 * .75));
label.prefWidth(Double.MAX_VALUE);
label.setAlignment(Pos.CENTER);
return label;
}

public Label buildLabel(String text, Font font, Paint textFill) {
Label label = new Label(text);
label.setAlignment(Pos.TOP_CENTER);
label.setFont(font);
label.setTextFill(textFill);
return label;
}

public HBox buildHBox(Node node) {
HBox hbox = new HBox(node);
hbox.setAlignment(Pos.CENTER);
return hbox;
}

public ImageView buildImageView(Image image, double scale) {
ImageView imageView = new ImageView(image);
imageView.setPreserveRatio(true);
imageView.setFitWidth(image.getWidth() * scale);
return imageView;
}

public TextField buildTextField() {
TextField tf = new TextField("");
tf.setPrefWidth(Double.MAX_VALUE);
return tf;
}

public Hyperlink buildHyperlink(String text, Font font, LinearGradient fill, String url) {
Hyperlink link = new Hyperlink(text);
link.setFont(font);
link.setTextFill(fill);
link.setOnAction(e -> Drifty_GUI.INSTANCE.openWebsite(url));
return link;
}
}
76 changes: 23 additions & 53 deletions GUI/src/main/java/main/Drifty_GUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,14 @@
import gui.utils.MessageBroker;
import javafx.application.Application;
import javafx.application.Preloader;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.input.Clipboard;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.LinearGradient;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import properties.Mode;
import ui.*;
Expand All @@ -26,12 +22,14 @@
import static gui.support.Constants.GUI_APPLICATION_TERMINATED;
import static javafx.scene.layout.AnchorPane.*;
import static support.Constants.DRIFTY_WEBSITE_URL;
import static support.Constants.VERSION_NUMBER;

public class Drifty_GUI extends Application {
public static final Drifty_GUI INSTANCE = new Drifty_GUI();
private static MessageBroker msgBroker;
private static Scene scene;
private final Settings settingsInstance = new Settings();
private About aboutInstance;
private Stage primaryStage;
private Scene scene;

public static void main(String[] args) {
System.setProperty("javafx.preloader", Splash.class.getCanonicalName());
Expand Down Expand Up @@ -65,9 +63,13 @@ private void createScene() {
MenuBar menu = menuBar(getMenuItemsOfMenu(), getEditMenu(), getWindowMenu(), getHelpMenu());
ap.getChildren().add(gridPane);
ap.getChildren().add(menu);

placeControl(gridPane, 40, 40, 40, 40);
placeControl(menu, 0, 0, 0, -1);
scene = Constants.getScene(ap);
if (AppSettings.GET.mainTheme().equals("Dark")) {
Constants.addCSS(scene, Constants.DARK_THEME_CSS);
}
scene.setOnContextMenuRequested(e -> getRightClickContextMenu().show(scene.getWindow(), e.getScreenX(), e.getScreenY()));
menu.setUseSystemMenuBar(true);
UIController.initLogic(gridPane);
Expand Down Expand Up @@ -116,6 +118,10 @@ private MenuBar menuBar(Menu... menus) {
return new MenuBar(menus);
}

public static Scene getScene() {
return scene;
}

private Menu getWindowMenu() {
Menu menu = new Menu("Window");
MenuItem fullScreen = new MenuItem("Toggle Full Screen");
Expand All @@ -138,48 +144,10 @@ private Menu getHelpMenu() {
securityVulnerability.setOnAction(e -> openWebsite("https://github.com/SaptarshiSarkar12/Drifty/security/advisories/new"));
feature.setOnAction(e -> openWebsite("https://github.com/SaptarshiSarkar12/Drifty/issues/new?assignees=&labels=feature+%E2%9C%A8%2CApp+%F0%9F%92%BB&projects=&template=feature-request-application.yaml&title=%5BFEATURE%5D+"));
about.setOnAction(event -> {
Stage stage = Constants.getStage("About Drifty", false);
VBox root = new VBox(10);
root.setPadding(new Insets(10));
root.setAlignment(Pos.TOP_CENTER);
ImageView appIcon = new ImageView(Constants.IMG_SPLASH);
appIcon.setFitWidth(Constants.SCREEN_WIDTH * .2);
appIcon.setFitHeight(Constants.SCREEN_HEIGHT * .2);
appIcon.setPreserveRatio(true);
Label lblDescription = new Label("An Open-Source Interactive File Downloader System");
lblDescription.setFont(Font.font("Arial", FontWeight.BOLD, 24));
lblDescription.setTextFill(LinearGradient.valueOf("linear-gradient(to right, #8e2de2, #4a00e0)"));
Label lblDriftyVersion = new Label("Drifty " + VERSION_NUMBER);
Label lblYtDlpVersion = new Label("yt-dlp version: " + AppSettings.GET.ytDlpVersion());
lblDriftyVersion.setFont(Font.font("Arial", FontWeight.BOLD, 20));
lblDriftyVersion.setTextFill(LinearGradient.valueOf("linear-gradient(to right, #0f0c29, #302b63, #24243e)"));
lblYtDlpVersion.setFont(Font.font("Arial", FontWeight.BOLD, 14));
lblYtDlpVersion.setTextFill(LinearGradient.valueOf("linear-gradient(to right, #0f0c29, #302b63, #24243e)"));
Hyperlink websiteLink = new Hyperlink("Website");
websiteLink.setFont(Font.font("Arial", FontWeight.BOLD, 18));
websiteLink.setTextFill(LinearGradient.valueOf("linear-gradient(to right, #fc466b, #3f5efb)"));
websiteLink.setOnAction(e -> openWebsite("https://saptarshisarkar12.github.io/Drifty"));
Hyperlink discordLink = new Hyperlink("Join Discord");
discordLink.setFont(Font.font("Arial", FontWeight.BOLD, 18));
discordLink.setTextFill(LinearGradient.valueOf("linear-gradient(to right, #00d956, #0575e6)"));
discordLink.setOnAction(e -> openWebsite("https://discord.gg/DeT4jXPfkG"));
Hyperlink githubLink = new Hyperlink("Contribute to Drifty");
githubLink.setFont(Font.font("Arial", FontWeight.BOLD, 18));
githubLink.setTextFill(LinearGradient.valueOf("linear-gradient(to right, #009fff, #ec2f4b)"));
githubLink.setOnAction(e -> openWebsite("https://github.com/SaptarshiSarkar12/Drifty"));
root.getChildren().addAll(appIcon, lblDescription, lblDriftyVersion, lblYtDlpVersion);
if (AppSettings.GET.isFfmpegWorking() && AppSettings.GET.ffmpegVersion() != null && !AppSettings.GET.ffmpegVersion().isEmpty()) {
Label lblFfmpegVersion = new Label("FFMPEG version: " + AppSettings.GET.ffmpegVersion());
lblFfmpegVersion.setFont(Font.font("Arial", FontWeight.BOLD, 14));
lblFfmpegVersion.setTextFill(LinearGradient.valueOf("linear-gradient(to right, #0f0c29, #302b63, #24243e)"));
root.getChildren().add(lblFfmpegVersion);
if (aboutInstance == null) {
aboutInstance = new About();
}
root.getChildren().addAll(websiteLink, discordLink, githubLink);
Scene aboutScene = Constants.getScene(root);
stage.setMinHeight(Constants.SCREEN_HEIGHT * .55);
stage.setMinWidth(Constants.SCREEN_WIDTH * .5);
stage.setScene(aboutScene);
stage.show();
aboutInstance.show();
});
menu.getItems().setAll(contactUs, contribute, bug, securityVulnerability, feature, about);
return menu;
Expand All @@ -188,13 +156,15 @@ private Menu getHelpMenu() {
private Menu getEditMenu() {
Menu menu = new Menu("Edit");
MenuItem wipeHistory = new MenuItem("Clear Download History");
MenuItem settings = new MenuItem("Settings");
wipeHistory.setOnAction(e -> {
ConfirmationDialog ask = new ConfirmationDialog("Clear Download History", "Are you sure you wish to wipe out all of your download history?\n(This will NOT delete any downloaded files)", false);
if (ask.getResponse().isYes()) {
UIController.clearJobHistory();
}
});
menu.getItems().addAll(wipeHistory);
settings.setOnAction(e -> settingsInstance.show());
menu.getItems().addAll(wipeHistory, settings);
return menu;
}

Expand All @@ -212,7 +182,7 @@ private ContextMenu getRightClickContextMenu() {
return contextMenu;
}

protected void openWebsite(String websiteURL) {
public void openWebsite(String websiteURL) {
getHostServices().showDocument(websiteURL);
}

Expand Down
Loading

0 comments on commit ebbbb0c

Please sign in to comment.