v0.2
This commit is contained in:
parent
c4d0959cf3
commit
f5a9ddf8df
13 changed files with 162 additions and 91 deletions
20
README.md
20
README.md
|
@ -34,7 +34,7 @@ Install JRE/JDK 8 or higher (openJDK is good. Oracle's one is also good). JavaFX
|
|||
|
||||
See 'Linux' section.
|
||||
|
||||
Set 'Security & Privacy' if needed.
|
||||
Set 'Security & Privacy' settings if needed.
|
||||
|
||||
### Windows:
|
||||
|
||||
|
@ -63,10 +63,18 @@ Table 'Status' = 'Uploaded' does not means that file installed. It means that it
|
|||
Handling successful/failed installation is a purpose of the other side application (TinFoil/GoldLeaf). (And they don't provide any feedback interfaces so I can't detect success/failure.)
|
||||
|
||||
## TODO:
|
||||
- [x] macOS QA by [Konstanin Kelemen](https://github.com/konstantin-kelemen). Appreciate assistance of [Vitaliy Natarov](https://github.com/SebastianUA).
|
||||
- [x] macOS QA
|
||||
-[x] v0.1
|
||||
-[ ] v0.2 (partly)
|
||||
- [x] Windows support
|
||||
- [ ] code refactoring
|
||||
- [ ] GoldLeaf support
|
||||
- [ ] code refactoring (almost. todo: printLog() )
|
||||
- [x] GoldLeaf support
|
||||
- [ ] XCI support
|
||||
- [ ] Settings
|
||||
- [ ] File order sort (non-critical)
|
||||
- [ ] File order sort (non-critical)
|
||||
|
||||
## Thanks
|
||||
Appreciate assistance and support of both Vitaliy and Konstantin. Without you all this magic would not have happened.
|
||||
|
||||
[Konstanin Kelemen](https://github.com/konstantin-kelemen)
|
||||
|
||||
[Vitaliy Natarov](https://github.com/SebastianUA)
|
23
src/main/java/nsusbloader/AppPreferences.java
Normal file
23
src/main/java/nsusbloader/AppPreferences.java
Normal file
|
@ -0,0 +1,23 @@
|
|||
package nsusbloader;
|
||||
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
public class AppPreferences {
|
||||
private static final AppPreferences INSTANCE = new AppPreferences();
|
||||
public static AppPreferences getInstance() { return INSTANCE; }
|
||||
|
||||
private Preferences preferences;
|
||||
|
||||
private AppPreferences(){ preferences = Preferences.userRoot().node("NS-USBloader"); }
|
||||
|
||||
public String getTheme(){
|
||||
String theme = preferences.get("THEME", "/res/app_dark.css"); // Don't let user to change settings manually
|
||||
if (!theme.matches("(^/res/app_dark.css$)|(^/res/app_light.css$)"))
|
||||
theme = "/res/app_dark.css";
|
||||
return theme;
|
||||
}
|
||||
public void setTheme(String theme){ preferences.put("THEME", theme); }
|
||||
|
||||
public String getRecent(){ return preferences.get("RECENT", System.getProperty("user.home")); }
|
||||
public void setRecent(String path){ preferences.put("RECENT", path); }
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package nsusbloader;
|
||||
package nsusbloader.Controllers;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
@ -8,7 +8,10 @@ import javafx.scene.control.*;
|
|||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.stage.FileChooser;
|
||||
import nsusbloader.Controllers.NSTableViewController;
|
||||
import nsusbloader.AppPreferences;
|
||||
import nsusbloader.MediatorControl;
|
||||
import nsusbloader.NSLMain;
|
||||
import nsusbloader.UsbCommunications;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
|
@ -46,7 +49,7 @@ public class NSLMainController implements Initializable {
|
|||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
this.resourceBundle = rb;
|
||||
logArea.setText(rb.getString("logsGreetingsMessage")+" "+NSLMain.appVersion+"!\n");
|
||||
logArea.setText(rb.getString("logsGreetingsMessage")+" "+ NSLMain.appVersion+"!\n");
|
||||
if (System.getProperty("os.name").toLowerCase().startsWith("lin"))
|
||||
if (!System.getProperty("user.name").equals("root"))
|
||||
logArea.appendText(rb.getString("logsEnteredAsMsg1")+System.getProperty("user.name")+"\n"+rb.getString("logsEnteredAsMsg2") + "\n");
|
||||
|
@ -81,18 +84,20 @@ public class NSLMainController implements Initializable {
|
|||
btnSwitchImage.getStyleClass().add("regionLamp");
|
||||
switchThemeBtn.setGraphic(btnSwitchImage);
|
||||
this.switchThemeBtn.setOnAction(e->switchTheme());
|
||||
|
||||
previouslyOpenedPath = AppPreferences.getInstance().getRecent();
|
||||
}
|
||||
/**
|
||||
* Changes UI theme on the go
|
||||
* */
|
||||
private void switchTheme(){
|
||||
if (switchThemeBtn.getScene().getStylesheets().get(0).equals("/res/app.css")) {
|
||||
switchThemeBtn.getScene().getStylesheets().remove("/res/app.css");
|
||||
if (switchThemeBtn.getScene().getStylesheets().get(0).equals("/res/app_dark.css")) {
|
||||
switchThemeBtn.getScene().getStylesheets().remove("/res/app_dark.css");
|
||||
switchThemeBtn.getScene().getStylesheets().add("/res/app_light.css");
|
||||
}
|
||||
else {
|
||||
switchThemeBtn.getScene().getStylesheets().add("/res/app.css");
|
||||
switchThemeBtn.getScene().getStylesheets().remove("/res/app_light.css");
|
||||
switchThemeBtn.getScene().getStylesheets().add("/res/app_dark.css");
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
@ -103,16 +108,14 @@ public class NSLMainController implements Initializable {
|
|||
List<File> filesList;
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.setTitle(resourceBundle.getString("btnFileOpen"));
|
||||
if (previouslyOpenedPath == null)
|
||||
|
||||
File validator = new File(previouslyOpenedPath);
|
||||
if (validator.exists())
|
||||
fileChooser.setInitialDirectory(validator); // TODO: read from prefs
|
||||
else
|
||||
fileChooser.setInitialDirectory(new File(System.getProperty("user.home"))); // TODO: read from prefs
|
||||
else {
|
||||
File validator = new File(previouslyOpenedPath);
|
||||
if (validator.exists())
|
||||
fileChooser.setInitialDirectory(validator); // TODO: read from prefs
|
||||
else
|
||||
fileChooser.setInitialDirectory(new File(System.getProperty("user.home"))); // TODO: read from prefs
|
||||
}
|
||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NS ROM", "*.nsp"));
|
||||
|
||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NSP ROM", "*.nsp"));
|
||||
|
||||
filesList = fileChooser.showOpenMultipleDialog(logArea.getScene().getWindow());
|
||||
if (filesList != null && !filesList.isEmpty()) {
|
||||
|
@ -156,7 +159,7 @@ public class NSLMainController implements Initializable {
|
|||
* This thing modify UI for reusing 'Upload to NS' button and make functionality set for "Stop transmission"
|
||||
* Called from mediator
|
||||
* */
|
||||
void notifyTransmissionStarted(boolean isTransmissionStarted){
|
||||
public void notifyTransmissionStarted(boolean isTransmissionStarted){
|
||||
if (isTransmissionStarted) {
|
||||
selectNspBtn.setDisable(true);
|
||||
uploadStopBtn.setOnAction(e->{ stopBtnAction(); });
|
||||
|
@ -182,4 +185,11 @@ public class NSLMainController implements Initializable {
|
|||
uploadStopBtn.getStyleClass().add("buttonUp");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Save preferences before exit
|
||||
* */
|
||||
public void exit(){
|
||||
AppPreferences.getInstance().setTheme(switchThemeBtn.getScene().getStylesheets().get(0));
|
||||
AppPreferences.getInstance().setRecent(previouslyOpenedPath);
|
||||
}
|
||||
}
|
|
@ -39,14 +39,14 @@ public class NSLRowModel {
|
|||
public void setStatus(EFileStatus status){ // TODO: Localization
|
||||
switch (status){
|
||||
case UPLOADED:
|
||||
this.status = "Uploaded";
|
||||
this.status = "Success";
|
||||
markForUpload = false;
|
||||
break;
|
||||
case FAILED:
|
||||
this.status = "Upload failed";
|
||||
this.status = "Failed";
|
||||
break;
|
||||
case INCORRECT_FILE_FAILED:
|
||||
this.status = "File incorrect";
|
||||
this.status = "Failed: Incorrect file";
|
||||
markForUpload = false;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -33,15 +33,29 @@ public class NSTableViewController implements Initializable {
|
|||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
rowsObsLst = FXCollections.observableArrayList();
|
||||
table.setPlaceholder(new Label());
|
||||
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||
|
||||
TableColumn<NSLRowModel, String> statusColumn = new TableColumn<>(resourceBundle.getString("tableStatusLbl"));
|
||||
TableColumn<NSLRowModel, String> fileNameColumn = new TableColumn<>(resourceBundle.getString("tableFileNameLbl"));
|
||||
TableColumn<NSLRowModel, String> fileSizeColumn = new TableColumn<>(resourceBundle.getString("tableSizeLbl"));
|
||||
TableColumn<NSLRowModel, Boolean> uploadColumn = new TableColumn<>(resourceBundle.getString("tableUploadLbl"));
|
||||
statusColumn.setMinWidth(70.0);
|
||||
fileNameColumn.setMinWidth(250.0);
|
||||
fileSizeColumn.setMinWidth(70.0);
|
||||
uploadColumn.setMinWidth(70.0);
|
||||
// See https://bugs.openjdk.java.net/browse/JDK-8157687
|
||||
statusColumn.setMinWidth(100.0);
|
||||
statusColumn.setPrefWidth(100.0);
|
||||
statusColumn.setMaxWidth(100.0);
|
||||
statusColumn.setResizable(false);
|
||||
|
||||
fileNameColumn.setMinWidth(25.0);
|
||||
|
||||
fileSizeColumn.setMinWidth(120.0);
|
||||
fileSizeColumn.setPrefWidth(120.0);
|
||||
fileSizeColumn.setMaxWidth(120.0);
|
||||
fileSizeColumn.setResizable(false);
|
||||
|
||||
uploadColumn.setMinWidth(100.0);
|
||||
uploadColumn.setPrefWidth(100.0);
|
||||
uploadColumn.setMaxWidth(100.0);
|
||||
uploadColumn.setResizable(false);
|
||||
|
||||
statusColumn.setCellValueFactory(new PropertyValueFactory<>("status"));
|
||||
fileNameColumn.setCellValueFactory(new PropertyValueFactory<>("nspFileName"));
|
||||
|
@ -76,12 +90,6 @@ public class NSTableViewController implements Initializable {
|
|||
|
||||
table.setItems(rowsObsLst);
|
||||
table.getColumns().addAll(statusColumn, fileNameColumn, fileSizeColumn, uploadColumn);
|
||||
/* debug content
|
||||
rowsObsLst.add(new NSLRowModel(new File("/home/loper/стихи_2"), true));
|
||||
rowsObsLst.add(new NSLRowModel(new File("/home/loper/стихи_2"), false));
|
||||
rowsObsLst.add(new NSLRowModel(new File("/home/loper/стихи_2"), false));
|
||||
rowsObsLst.add(new NSLRowModel(new File("/home/loper/стихи_2"), true));
|
||||
*/
|
||||
}
|
||||
/**
|
||||
* See uploadColumn callback. In case of GoldLeaf we have to restrict selection
|
||||
|
@ -145,6 +153,7 @@ public class NSTableViewController implements Initializable {
|
|||
model.setStatus(status);
|
||||
}
|
||||
}
|
||||
table.refresh();
|
||||
}
|
||||
/**
|
||||
* Called if selected different USB protocol
|
||||
|
|
|
@ -1,26 +1,28 @@
|
|||
package nsusbloader;
|
||||
|
||||
import nsusbloader.Controllers.NSLMainController;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
class MediatorControl {
|
||||
public class MediatorControl {
|
||||
private AtomicBoolean isTransferActive = new AtomicBoolean(false); // Overcoded just for sure
|
||||
private NSLMainController applicationController;
|
||||
|
||||
static MediatorControl getInstance(){
|
||||
public static MediatorControl getInstance(){
|
||||
return MediatorControlHold.INSTANCE;
|
||||
}
|
||||
|
||||
private static class MediatorControlHold {
|
||||
private static final MediatorControl INSTANCE = new MediatorControl();
|
||||
}
|
||||
void setController(NSLMainController controller){
|
||||
public void setController(NSLMainController controller){
|
||||
this.applicationController = controller;
|
||||
}
|
||||
NSLMainController getContoller(){ return this.applicationController; }
|
||||
|
||||
synchronized void setTransferActive(boolean state) {
|
||||
public synchronized void setTransferActive(boolean state) {
|
||||
isTransferActive.set(state);
|
||||
applicationController.notifyTransmissionStarted(state);
|
||||
}
|
||||
synchronized boolean getTransferActive() { return this.isTransferActive.get(); }
|
||||
public synchronized boolean getTransferActive() { return this.isTransferActive.get(); }
|
||||
}
|
||||
|
|
|
@ -49,19 +49,18 @@ public class MessagesConsumer extends AnimationTimer {
|
|||
if (progressRecieved > 0)
|
||||
progress.forEach(prg -> progressBar.setProgress(prg));
|
||||
|
||||
if (isInterrupted) {
|
||||
if (isInterrupted) { // It's safe 'cuz it's could't be interrupted while HashMap populating
|
||||
MediatorControl.getInstance().setTransferActive(false);
|
||||
progressBar.setProgress(0.0);
|
||||
|
||||
if (statusMap.size() > 0) // It's safe 'cuz it's could't be interrupted while HashMap populating
|
||||
if (statusMap.size() > 0)
|
||||
for (String key : statusMap.keySet())
|
||||
tableViewController.setFileStatus(key, statusMap.get(key));
|
||||
this.stop();
|
||||
}
|
||||
//TODO
|
||||
}
|
||||
|
||||
void interrupt(){
|
||||
this.isInterrupted = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,22 +6,24 @@ import javafx.scene.Parent;
|
|||
import javafx.scene.Scene;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.stage.Stage;
|
||||
import nsusbloader.Controllers.NSLMainController;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class NSLMain extends Application {
|
||||
static final String appVersion = "v0.2-DEVELOPMENT";
|
||||
public static final String appVersion = "v0.2";
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception{
|
||||
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/NSLMain.fxml"));
|
||||
|
||||
ResourceBundle rb;
|
||||
if (Locale.getDefault().getISO3Language().equals("rus"))
|
||||
rb = ResourceBundle.getBundle("locale", new Locale("ru"));
|
||||
else
|
||||
rb = ResourceBundle.getBundle("locale", new Locale("en"));
|
||||
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/NSLMain.fxml"));
|
||||
|
||||
loader.setResources(rb);
|
||||
Parent root = loader.load();
|
||||
|
||||
|
@ -36,7 +38,9 @@ public class NSLMain extends Application {
|
|||
primaryStage.setMinWidth(600);
|
||||
primaryStage.setMinHeight(375);
|
||||
Scene mainScene = new Scene(root, 800, 400);
|
||||
mainScene.getStylesheets().add("/res/app.css");
|
||||
|
||||
mainScene.getStylesheets().add(AppPreferences.getInstance().getTheme());
|
||||
|
||||
primaryStage.setScene(mainScene);
|
||||
primaryStage.show();
|
||||
|
||||
|
@ -45,6 +49,9 @@ public class NSLMain extends Application {
|
|||
if(! ServiceWindow.getConfirmationWindow(rb.getString("windowTitleConfirmExit"), rb.getString("windowBodyConfirmExit")))
|
||||
e.consume();
|
||||
});
|
||||
|
||||
NSLMainController controller = loader.getController();
|
||||
primaryStage.setOnHidden(e-> controller.exit());
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
|
|
@ -35,12 +35,9 @@ public class ServiceWindow {
|
|||
alertBox.getDialogPane().setMinWidth(Region.USE_PREF_SIZE);
|
||||
alertBox.getDialogPane().setMinHeight(Region.USE_PREF_SIZE);
|
||||
alertBox.setResizable(true); // Java bug workaround for JDR11/OpenJFX. TODO: nothing. really.
|
||||
alertBox.getDialogPane().getStylesheets().add("/res/app.css");
|
||||
alertBox.getDialogPane().getStylesheets().add(AppPreferences.getInstance().getTheme());
|
||||
Optional<ButtonType> result = alertBox.showAndWait();
|
||||
if (result.get() == ButtonType.OK)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
return (result.isPresent() && result.get() == ButtonType.OK);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,13 @@ import java.util.List;
|
|||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
class UsbCommunications extends Task<Void> {
|
||||
public class UsbCommunications extends Task<Void> {
|
||||
private final int DEFAULT_INTERFACE = 0;
|
||||
|
||||
private BlockingQueue<String> msgQueue;
|
||||
private BlockingQueue<Double> progressQueue;
|
||||
private HashMap<String, EFileStatus> statusMap; // BlockingQueue for literally one object. TODO: read more books ; replace to hashMap
|
||||
private EFileStatus status = EFileStatus.FAILED;
|
||||
|
||||
private MessagesConsumer msgConsumer;
|
||||
|
||||
|
@ -44,7 +45,7 @@ class UsbCommunications extends Task<Void> {
|
|||
Since this application let user an ability (theoretically) to choose same files in different folders, the latest selected file will be added to the list and handled correctly.
|
||||
I have no idea why he/she will make a decision to do that. Just in case, we're good in this point.
|
||||
*/
|
||||
UsbCommunications(List<File> nspList, String protocol){
|
||||
public UsbCommunications(List<File> nspList, String protocol){
|
||||
this.protocol = protocol;
|
||||
this.nspMap = new HashMap<>();
|
||||
for (File f: nspList)
|
||||
|
@ -275,28 +276,17 @@ class UsbCommunications extends Task<Void> {
|
|||
printLog("\tEnd chain", EMsgType.INFO);
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Report transfer status
|
||||
* */
|
||||
private void reportTransferStatus(EFileStatus status){
|
||||
for (String fileName: nspMap.keySet())
|
||||
statusMap.put(fileName, status);
|
||||
}
|
||||
/**
|
||||
* Tinfoil processing
|
||||
* */
|
||||
private class TinFoil{
|
||||
TinFoil(){
|
||||
|
||||
if (!sendListOfNSP()) {
|
||||
reportTransferStatus(EFileStatus.FAILED);
|
||||
if (!sendListOfNSP())
|
||||
return;
|
||||
}
|
||||
|
||||
if (proceedCommands()) // REPORT SUCCESS
|
||||
reportTransferStatus(EFileStatus.UPLOADED);
|
||||
else // REPORT FAILURE
|
||||
reportTransferStatus(EFileStatus.FAILED);
|
||||
status = EFileStatus.UPLOADED; // Don't change status that is already set to FAILED
|
||||
}
|
||||
/**
|
||||
* Send what NSP will be transferred
|
||||
|
@ -547,15 +537,14 @@ class UsbCommunications extends Task<Void> {
|
|||
PFSProvider pfsElement = new PFSProvider(nspMap.get(nspMap.keySet().toArray()[0]), msgQueue);
|
||||
if (!pfsElement.init()) {
|
||||
printLog("GL File provided have incorrect structure and won't be uploaded", EMsgType.FAIL);
|
||||
reportTransferStatus(EFileStatus.INCORRECT_FILE_FAILED);
|
||||
status = EFileStatus.INCORRECT_FILE_FAILED;
|
||||
return;
|
||||
}
|
||||
printLog("GL File structure validated and it will be uploaded", EMsgType.PASS);
|
||||
|
||||
if (initGoldLeafProtocol(pfsElement))
|
||||
reportTransferStatus(EFileStatus.UPLOADED);
|
||||
else
|
||||
reportTransferStatus(EFileStatus.FAILED);
|
||||
status = EFileStatus.UPLOADED;
|
||||
// else - no change status that is already set to FAILED
|
||||
}
|
||||
private boolean initGoldLeafProtocol(PFSProvider pfsElement){
|
||||
// Go parse commands
|
||||
|
@ -774,6 +763,11 @@ class UsbCommunications extends Task<Void> {
|
|||
LibUsb.exit(contextNS);
|
||||
printLog("Requested context close", EMsgType.INFO);
|
||||
}
|
||||
|
||||
// Report status
|
||||
for (String fileName: nspMap.keySet())
|
||||
statusMap.put(fileName, status);
|
||||
|
||||
msgConsumer.interrupt();
|
||||
}
|
||||
/**
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.shape.SVGPath?>
|
||||
|
||||
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.NSLMainController">
|
||||
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.NSLMainController">
|
||||
<children>
|
||||
<VBox AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
|
|
|
@ -98,7 +98,7 @@
|
|||
-fx-background-color: #f7fafa;
|
||||
-fx-min-height: 1;
|
||||
}
|
||||
|
||||
// -======================== Choice box =========================-
|
||||
.choice-box {
|
||||
-fx-background-color: #4f4f4f;
|
||||
-fx-border-color: #4f4f4f;
|
||||
|
@ -120,13 +120,19 @@
|
|||
}
|
||||
|
||||
// Background color of the whole context menu
|
||||
.choice-box .context-menu { -fx-background-color: #2d2d2d; }
|
||||
.choice-box .context-menu {
|
||||
-fx-background-color: #2d2d2d;
|
||||
}
|
||||
|
||||
// Focused item background color in the list
|
||||
.choice-box .menu-item:focused { -fx-background-color: #eea11e; }
|
||||
// Text color of non-focused items in the list
|
||||
.choice-box .menu-item > .label { -fx-text-fill: #f7fafa; }
|
||||
// Text color of focused item in the list
|
||||
.choice-box .menu-item:focused > .label { -fx-text-fill: #2d2d2d; }
|
||||
.choice-box .context-menu .menu-item:focused {
|
||||
-fx-background-color: #eea11e;
|
||||
|
||||
}
|
||||
.choice-box .context-menu .menu-item:focused .label {
|
||||
-fx-text-fill: #2c2c2c;
|
||||
}
|
||||
|
||||
|
||||
// -======================== TAB PANE =========================-
|
||||
.tab-pane .tab SVGPath{
|
||||
|
@ -176,12 +182,18 @@
|
|||
-fx-border-radius: 3;
|
||||
-fx-border-width: 2;
|
||||
}
|
||||
.table-view .arrow {
|
||||
-fx-mark-color: #08f3ff ;
|
||||
}
|
||||
.table-view .column-header {
|
||||
-fx-background-color: transparent;
|
||||
-fx-border-width: 0 1 2 0;
|
||||
-fx-border-color: #6d8484;
|
||||
}
|
||||
.table-view .column-header-background .label{
|
||||
-fx-background-color: transparent;
|
||||
-fx-text-fill: #08f3ff;
|
||||
|
||||
}
|
||||
.table-view .column-header-background, .table-view .filler{
|
||||
-fx-background-color: #4f4f4f;
|
||||
|
@ -194,14 +206,14 @@
|
|||
-fx-background-color: -fx-table-cell-border-color, #424242;
|
||||
-fx-background-insets: 0, 0 0 1 0;
|
||||
-fx-padding: 0.0em; /* 0 */
|
||||
-fx-table-cell-border-color: #f7fafa;
|
||||
-fx-table-cell-border-color: #6d8484;
|
||||
}
|
||||
|
||||
.table-row-cell:odd, .table-row-cell:odd:filled:selected, .table-row-cell:odd:selected{
|
||||
-fx-background-color: -fx-table-cell-border-color, #4f4f4f;
|
||||
-fx-background-insets: 0, 0 0 1 0;
|
||||
-fx-padding: 0.0em; /* 0 */
|
||||
-fx-table-cell-border-color: #f7fafa;
|
||||
-fx-table-cell-border-color: #6d8484;
|
||||
}
|
||||
// -========================== Context menu =====================-
|
||||
.context-menu {
|
|
@ -99,7 +99,7 @@
|
|||
-fx-background-color: #2c2c2c;
|
||||
-fx-min-height: 1;
|
||||
}
|
||||
|
||||
// -======================== Choice box =========================-
|
||||
.choice-box {
|
||||
-fx-background-color: #fefefe;
|
||||
-fx-border-color: #fefefe;
|
||||
|
@ -121,13 +121,18 @@
|
|||
}
|
||||
|
||||
// Background color of the whole context menu
|
||||
.choice-box .context-menu { -fx-background-color: #fefefe; }
|
||||
.choice-box .context-menu {
|
||||
-fx-background-color: #fefefe;
|
||||
}
|
||||
|
||||
// Focused item background color in the list
|
||||
.choice-box .menu-item:focused { -fx-background-color: #eea11e; }
|
||||
// Text color of non-focused items in the list
|
||||
.choice-box .menu-item > .label { -fx-text-fill: #2c2c2c; }
|
||||
// Text color of focused item in the list
|
||||
.choice-box .menu-item:focused > .label { -fx-text-fill: #2d2d2d; }
|
||||
.choice-box .context-menu .menu-item:focused {
|
||||
-fx-background-color: #eea11e;
|
||||
|
||||
}
|
||||
.choice-box .context-menu .menu-item:focused .label {
|
||||
-fx-text-fill: #2c2c2c;
|
||||
}
|
||||
|
||||
// -======================== TAB PANE =========================-
|
||||
.tab-pane .tab SVGPath{
|
||||
|
@ -177,8 +182,13 @@
|
|||
-fx-border-radius: 3;
|
||||
-fx-border-width: 2;
|
||||
}
|
||||
.table-view .arrow {
|
||||
-fx-mark-color: #2c2c2c ;
|
||||
}
|
||||
.table-view .column-header {
|
||||
-fx-background-color: transparent;
|
||||
-fx-border-width: 0 1 2 0;
|
||||
-fx-border-color: #b0b0b0;
|
||||
}
|
||||
.table-view .column-header-background .label{
|
||||
-fx-background-color: transparent;
|
||||
|
@ -195,14 +205,14 @@
|
|||
-fx-background-color: -fx-table-cell-border-color, #d3fffd;
|
||||
-fx-background-insets: 0, 0 0 1 0;
|
||||
-fx-padding: 0.0em; /* 0 */
|
||||
-fx-table-cell-border-color: #2c2c2c;
|
||||
-fx-table-cell-border-color: #b0b0b0;
|
||||
}
|
||||
|
||||
.table-row-cell:odd, .table-row-cell:odd:filled:selected, .table-row-cell:odd:selected{
|
||||
-fx-background-color: -fx-table-cell-border-color, #fefefe;
|
||||
-fx-background-insets: 0, 0 0 1 0;
|
||||
-fx-padding: 0.0em; /* 0 */
|
||||
-fx-table-cell-border-color: #2c2c2c;
|
||||
-fx-table-cell-border-color: #b0b0b0;
|
||||
}
|
||||
// -========================== Context menu =====================-
|
||||
.context-menu {
|
||||
|
|
Loading…
Reference in a new issue