57 Commits
0.1.6 ... 055

Author SHA1 Message Date
6a2c5d050f update 0.2.1 (055) 2017-11-14 23:44:49 +01:00
b8f4f89ec6 renamed SmmdbAPIQuery to SMMDBAPIController 2017-11-14 12:02:39 +01:00
dafd0b84df maven buildsystem
* maven is now used to build cemu_UI
* cleaned up a lot of code for better overview
2017-11-13 16:44:39 +01:00
06429eaf87 added jfxokaycanceldialog class
* added jfxokaycanceldialog class
* code clean up
2017-11-11 22:27:19 +01:00
9e3b553851 added jfxinfodialog class
* added jfxinfodialog class
* code clean up
2017-11-10 17:11:19 +01:00
61e02f6ac1 added support for updating to different branches
* added support for updating to different branches
* smmdb api fixed bad response from http url, using https now
* code clean-up
2017-11-10 15:58:20 +01:00
40c6084412 Update LICENSE 2017-11-06 21:33:05 +01:00
6cc9790c5a added update support
* added a manuall update function
* added a auto update function
2017-11-06 10:42:31 +01:00
3bcbf902d5 added adialog to explain missing values if adding a game manually 2017-11-06 10:00:10 +01:00
3f85fdf07b fiyed typos 2017-11-04 17:04:21 +01:00
40dd2c48d3 Merge remote-tracking branch 'origin/master' 2017-10-31 14:11:40 +01:00
1a4027e687 added edit dialog
* added a dialog for editing existing games
* a few UI clean ups
* you need to have valid values in every text field if you're adding a new game manually
2017-10-31 14:11:17 +01:00
b76126add1 Create CONTRIBUTING.md 2017-10-30 18:55:00 +01:00
9c4934966c UI clean up
* added a dialog if cloud sync init fails
*  fixed sideMenuSlideOut() is call even if its already outside
* code clean up
2017-10-30 18:28:58 +01:00
74440e3d7e add new Game is now one dialog
* add new game will now show only one dialog
* code clean up
2017-10-30 17:52:45 +01:00
e4a316f62c added System.exit(0) in main 2017-10-29 23:57:39 +01:00
eb127282ad more lib updates and cloud sync fixes
* added a fallback if something went wrong with cloud sync init
* removed old libs
2017-10-29 23:27:36 +01:00
5b46a0b58c updated some libraries
* google api libraries 1.22 -> 1.23
* apache commons-io 2.3 -> 2.6
* apache commons-codec 1.10 -> 1.11
2017-10-29 22:04:40 +01:00
6169a5e7cd added support for cemu 1.11 save path change
see https://github.com/Seil0/cemu_UI/issues/6
2017-10-28 16:43:04 +02:00
f53055db7e buildnumber 043 -> 045 2017-10-26 23:40:09 +02:00
8d759a724b fixed PlayBtn Position on startup
* fixed playBtn has a wrong Position on startup
2017-10-26 21:13:56 +02:00
f6778a320f Merge remote-tracking branch 'origin/master' 2017-10-24 22:42:07 +02:00
607bcf8ace added a update section in the settings
* added "check now!" button (not working for now)
* added a toggle button for auto updates (not working for now)
* all labels used in the settings are now accessable from the mwc (preparation for supporting more languages)
2017-10-24 22:41:56 +02:00
c5d6a2f276 Update README.md 2017-10-24 21:33:29 +02:00
0f0f962d8c update to version 0.2.0 "Puzzle Plank Galaxy" 2017-10-24 21:07:49 +02:00
0d46e818e1 code clean up
* removed old addGame() methode
2017-10-24 21:06:25 +02:00
05f6f7e664 code clean up
* Code is under GNU GPL version 3 now
* reworked the addGame() Method
* text fixes
2017-10-15 13:37:45 +02:00
8d49ce902e updated libraries
* jfoenix 1.8.0 -> 1.9.1
* code clean up
2017-10-15 12:29:18 +02:00
6d5e9409a5 window resize workaround
* added a workaround for the resizing option (this could be a linux specific bug, windows was not tested)
* begun reworking of the addGames() Method, not activated yet
2017-10-14 15:42:13 +02:00
bda73cf627 code clean up 2017-10-13 21:15:51 +02:00
e13a187c71 Update README.md 2017-09-17 21:48:32 +02:00
e4dbbe0d55 Update README.md 2017-09-16 18:52:45 +02:00
f09258190a save windows size only if ther is 500ms no action
* if the window is resized, the new size is only saved if no resize
action is done for 5000ms
2017-09-16 17:08:50 +02:00
109bcf6e03 performance improvements
* call refreshUIData() only if there is enough space for another column
2017-09-15 19:23:44 +02:00
3853f70895 removed workaround for SmmdbApiQuery 2017-09-14 00:05:16 +02:00
9b4bc3ada9 Merge remote-tracking branch 'origin/master' 2017-09-13 23:58:58 +02:00
3bc571bacd window resize performance tuning
* only call refreshUI if space change is enough
* added FIXME for pane.setPrefWidth under windows, other parts that are affected see issue main.1
2017-09-13 23:57:29 +02:00
729a4ee10e fixed generating position
* ROM covers are placed now correctly on resize action
2017-09-13 00:14:54 +02:00
3f98dfa059 save window size 2017-09-12 20:13:26 +02:00
78791bb7e1 added a resize option
* if the window is resized and ther is enough space for a new column, the UI will be adapt to fit the new size
2017-09-12 19:45:39 +02:00
0124a5b1a4 Update README.md 2017-09-12 15:33:25 +02:00
959963f9bc more logger work and lib updates
* jfoenix 1.7.0 -> 1.8.0
* sqlite 3.19.1 -> 3.20.0
* replaced all remaining syso/syse with logger output
* fixed a bug in smmdb api integration by only requesting the first 70 courses (this is a temporary workaround)
* code clean up
* typo fixes
2017-09-12 15:04:21 +02:00
85fc66e8d6 logging to file
* the logger output is now written into a file in the cemu_UI directory called app.log
2017-09-02 17:38:40 +02:00
6c1663f386 reworked loadSettings
* loadSettings() should be 100% bulletproof
* replaced a few more syso with logger
2017-08-30 11:29:58 +02:00
71cf0316ec replace syso with logger
* replacing all debug/info syso and all syse with log4j 2 logger
2017-08-27 20:44:08 +02:00
dec767f553 Merge remote-tracking branch 'origin/master' 2017-08-27 18:23:36 +02:00
a24783f18c code clean up
* smmdb api query is not started anymore when closing the smmdb window
* general code clean up
2017-08-27 18:23:09 +02:00
9f0956a674 code clean up
* smmdb api query is not started anymore on closing the smmdb window
* general code clean up
2017-08-27 18:22:05 +02:00
dbd52cbe9c smmdb api integration rework
* fixed wrong placment of the downloaded courses
2017-08-27 17:25:41 +02:00
4c8a0a51e9 smmdb api integration rework part 2/2
* fixed all remaining parameters
* course is downloaded as .zip now
* junrar is replaced by zip4j
2017-08-26 00:13:09 +02:00
7a2112a759 smmd rework part 1
due to changes on the smmdb api i have to rework the smmdb integration
2017-08-25 14:57:15 +02:00
9930a4cb15 added a smmID
* added 44fc5929 to smmIDs
2017-08-24 22:04:06 +02:00
d36b869e80 updated build number 2017-08-11 20:04:36 +02:00
43a7e22254 fixed loading error
* fixed an issue with loading sttings when no cloudService is set
2017-08-11 20:01:43 +02:00
07d33df63a updated libraries
* jfoenix 1.4.0 -> 1.7.0
* sqlite-jdbc 3.18.0 -> 3.19.3
* flow 8.0.1
2017-08-01 20:20:37 +02:00
e394b1a573 Material styled dialogs
* added material styled dialogs
2017-08-01 20:11:17 +02:00
a30def1fd0 Update README.md 2017-07-26 18:08:26 +02:00
133 changed files with 3877 additions and 2623 deletions

View File

@ -1,26 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.fx.ide.jdt.core.JAVAFX_CONTAINER"/>
<classpathentry kind="lib" path="src/libraries/commons-io-2.5.jar"/>
<classpathentry kind="lib" path="src/libraries/google_apis/google-api-client-1.22.0.jar"/>
<classpathentry kind="lib" path="src/libraries/google_apis/google-api-services-drive-v3-rev68-1.22.0.jar"/>
<classpathentry kind="lib" path="src/libraries/google_apis/google-http-client-1.22.0.jar"/>
<classpathentry kind="lib" path="src/libraries/google_apis/google-http-client-jackson2-1.22.0.jar"/>
<classpathentry kind="lib" path="src/libraries/google_apis/google-oauth-client-1.22.0.jar"/>
<classpathentry kind="lib" path="src/libraries/google_apis/google-oauth-client-java6-1.22.0.jar"/>
<classpathentry kind="lib" path="src/libraries/google_apis/google-oauth-client-jetty-1.22.0.jar"/>
<classpathentry kind="lib" path="src/libraries/google_apis/javax.servlet-api-3.1.0.jar"/>
<classpathentry kind="lib" path="src/libraries/google_apis/jetty-6.1.25.jar"/>
<classpathentry kind="lib" path="src/libraries/google_apis/jetty-util-6.1.25.jar"/>
<classpathentry kind="lib" path="src/libraries/google_apis/jackson-core-2.8.8.jar"/>
<classpathentry kind="lib" path="src/libraries/commons-codec-1.10.jar"/>
<classpathentry kind="lib" path="src/libraries/jfoenix-1.4.0.jar"/>
<classpathentry kind="lib" path="src/libraries/sqlite-jdbc-3.18.0.jar"/>
<classpathentry kind="lib" path="src/libraries/minimal-json-0.9.4.jar"/>
<classpathentry kind="lib" path="src/libraries/junrar-0.7.jar"/>
<classpathentry kind="lib" path="src/libraries/commons-logging-api-1.1.jar"/>
<classpathentry kind="lib" path="src/libraries/commons-vfs2-2.1.1744488.2.jar"/>
<classpathentry kind="output" path="bin"/>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

3
.gitignore vendored
View File

@ -48,4 +48,5 @@ Temporary Items
config.xml
client_secret.json
.directory
target/
cemu_UI.jar

View File

@ -15,8 +15,14 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>

View File

@ -0,0 +1,5 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/test/java=UTF-8
encoding/<project>=UTF-8

View File

@ -9,4 +9,5 @@ org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.8

View File

@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

27
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,27 @@
# Contributing to cemu_UI
The following is a set of guidelines for contributing to cemu_UI.
## Java Sytleguide
If your willing to contribute to cemu_UI please us the following example as guide and rules to design your code.
* Use names for methods and variables that clarify their purpose. (This will help a lot to understand the code)
* Use as many spaces as necessary to make the code clear, but as little as possible.
* Sort all variables according to their type.
* For all (debugging) console outputs, use the log4j based logger. (syso/syse is okay for testing)
```java
// Use this as a sample Class:
public ClassName () {
void MethodName () {
double gameID; // Title-ID used on the Wii U
if (gameID == null) {
// Do something
}
// more code ...
}
}
```

17
LICENSE
View File

@ -1,13 +1,4 @@
"THE CHOCOLATE-WARE LICENSE" (Revision 1):
<@Seil0> wrote this file. As long as you retain
this notice this software is licensed under the
GNU GENERAL PUBLIC LICENSE Version 3 ,with the following additions:
* If we meet some day, and you think this stuff is worth it,
you can buy me a chocolate in return. - @Seil0
(license based in Beer-ware, see https://fedoraproject.org/wiki/Licensing/Beerware )
GNU GENERAL PUBLIC LICENSE
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
@ -640,8 +631,8 @@ to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {name of author}
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -661,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
{project} Copyright (C) {year} {fullname}
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.

View File

@ -1,18 +1,16 @@
# cemu_UI
![Total Downloads](https://img.shields.io/github/downloads/Seil0/cemu_UI/total.svg?style=flat-square)
[![Latest](https://img.shields.io/github/release/Seil0/cemu_UI/all.svg?style=flat-square)](https://github.com/Seil0/cemu_UI/releases)
[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg?style=flat-square)](https://www.gnu.org/licenses/gpl-3.0)
cemu_UI is a simple, material design graphical frontend for [cemu](http://cemu.info/), a Wii U emulator. Downloads can be found [here](https://github.com/Seil0/cemu_UI/releases).
## installation
Simply download the cemu_UI.jar from [releases](https://github.com/Seil0/cemu_UI/releases), make sure you have the latest version of java 8 oracle jre/jdk installed, open the file. cemu_UI creats a new directory "C:\Users\USERNAME\Documents\cemu_UI", where the database, settings and covers are stored. **first start can take while!**
## Installation
Simply download the cemu_UI.jar from [releases](https://github.com/Seil0/cemu_UI/releases), make sure you have the latest version of java 8 oracle jre/jdk installed and open the file. cemu_UI creats a new directory "C:\Users\USERNAME\Documents\cemu_UI", where the database, settings and covers are stored. **first start can take while!**
If you want to use the cloud sync function read the [wiki](https://github.com/Seil0/cemu_UI/wiki#cloud-savegame-syncronisation) carefully!
## building from source
1. read the [license](https://github.com/Seil0/cemu_UI/blob/master/LICENSE)
2. download/clone the git repository
3. make sure you have the latest versionj of java 8 oracle jdk installed
4. place the unzip repository into your workspace and start eclipse, project should now be there **or** import the project to your workspace
## Features
* launch Games
@ -22,26 +20,21 @@ If you want to use the cloud sync function read the [wiki](https://github.com/Se
* automatic rom detection (only .rpx files with a app.xml)
* customisable UI
* [sync savegames via google drive](https://github.com/Seil0/cemu_UI/wiki)
* [smmdb api](https://github.com/Tarnadas/smmdb) integration
## [planed Features](https://github.com/Seil0/cemu_UI/projects/1) (no ETA)
* Controller support
* more UI improvements
* support more rom file formats in automatic detection
* [smmdb api](http://smmdb.ddns.net/api) integration
### If you have another idea, make a "new issue" with the ![#f03c15](https://placehold.it/15/fbca04/000000?text=+)`idea` lable
## FAQ
## [FAQ](https://github.com/Seil0/cemu_UI/wiki#faq)
* My game is not detected automaticaly
* You need to add it to the [games.db](https://github.com/Seil0/cemu_UI/blob/master/downloadContent/games.db) database or you add it to the [games.csv](https://github.com/Seil0/cemu_UI/blob/master/downloadContent/games.csv) table so everyone can use it.
* How can I update the games.db?
* Delete the games.db file in "C:\Users\USERNAME\Documents\cemu_UI" it will be downloaded again at the next start of cemu_UI.
* I have another question
* make a new issue and let me know
### [building from source](https://github.com/Seil0/cemu_UI/wiki/Documantation)
## screenshots
## Screenshots
![Screenshot](/downloadContent/cemu_UI4.png)

1
bin/.gitignore vendored
View File

@ -1 +0,0 @@
/application/

Binary file not shown.

View File

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXColorPicker?>
<?import com.jfoenix.controls.JFXHamburger?>
<?import com.jfoenix.controls.JFXTextField?>
<?import com.jfoenix.controls.JFXToggleButton?>
<?import com.jfoenix.controls.JFXTreeTableView?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.TextFlow?>
<AnchorPane prefHeight="600.0" prefWidth="892.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainWindowController">
<children>
<ScrollPane fx:id="scrollPaneMain" fitToWidth="true" layoutY="38.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="38.0">
<content>
<AnchorPane fx:id="gamesAnchorPane">
<padding>
<Insets bottom="17.0" />
</padding></AnchorPane>
</content>
</ScrollPane>
<HBox fx:id="topHBox" prefHeight="38.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<JFXHamburger fx:id="menuHam" prefHeight="38.0" prefWidth="38.0" stylesheets="@MainWindows.css" />
</children>
</HBox>
<VBox fx:id="sideMenuVBox" layoutY="32.0" prefHeight="568.0" prefWidth="175.0" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="38.0">
<children>
<JFXButton fx:id="aboutBtn" alignment="TOP_LEFT" maxHeight="38.0" maxWidth="190.0" onAction="#aboutBtnAction" prefHeight="38.0" prefWidth="190.0" text="About" textAlignment="LEFT">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<JFXButton fx:id="settingsBtn" alignment="TOP_LEFT" maxHeight="38.0" maxWidth="213.0" onAction="#settingsBtnAction" prefHeight="38.0" prefWidth="213.0" text="Settings" textAlignment="LEFT">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<JFXButton fx:id="addBtn" alignment="TOP_LEFT" maxHeight="38.0" maxWidth="193.0" onAction="#addBtnAction" prefHeight="38.0" prefWidth="193.0" text="Add new Game" textAlignment="LEFT">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<JFXButton fx:id="reloadRomsBtn" alignment="TOP_LEFT" maxHeight="38.0" maxWidth="199.0" onAction="#reloadRomsBtnAction" prefHeight="38.0" prefWidth="199.0" text="reload roms" textAlignment="LEFT">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<JFXButton fx:id="smmdbBtn" alignment="TOP_LEFT" onAction="#smmdbBtnAction" prefHeight="38.0" prefWidth="216.0" text="smmdb">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
</children>
</VBox>
<!-- space between settings sections 35px, between sections elements (label + element) 20px, between label and element 3px(or more) -->
<AnchorPane fx:id="settingsAnchorPane" layoutX="38.0" layoutY="27.0" prefHeight="573.0" style="-fx-background-color: white;" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="175.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="38.0">
<children>
<Label layoutX="22.0" layoutY="59.0" text="Cemu Directory" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="59.0" />
<JFXTextField fx:id="cemuTextField" layoutX="18.0" layoutY="83.0" maxWidth="305.0" minWidth="305.0" onAction="#cemuTextFieldAction" prefHeight="32.0" prefWidth="305.0" promptText="cemu directory" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="79.0" />
<JFXTextField fx:id="romTextField" layoutX="18.0" layoutY="159.0" maxWidth="305.0" minWidth="305.0" onAction="#romTextFieldAction" prefHeight="32.0" prefWidth="305.0" promptText="rom directory" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="151.0" />
<JFXButton fx:id="romTFBtn" layoutX="337.0" layoutY="159.0" onAction="#romTFBtnAction" prefHeight="32.0" prefWidth="108.0" text="choose directory" AnchorPane.leftAnchor="333.0" AnchorPane.topAnchor="151.0" />
<JFXButton fx:id="cemuTFBtn" layoutX="333.0" layoutY="79.0" onAction="#cemuTFBtnAction" prefHeight="32.0" prefWidth="108.0" text="choose directory" AnchorPane.leftAnchor="333.0" AnchorPane.topAnchor="79.0" />
<JFXColorPicker fx:id="colorPicker" layoutX="22.0" layoutY="235.0" onAction="#colorPickerAction" AnchorPane.leftAnchor="16.0" AnchorPane.topAnchor="227.0" />
<JFXToggleButton fx:id="fullscreenToggleBtn" layoutX="14.0" layoutY="391.0" onAction="#fullscreenToggleBtnAction" text="start game in fullscreen" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="390.0" />
<Label layoutX="22.0" layoutY="135.0" text="Rom Directory" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="131.0" />
<Label layoutX="22.0" layoutY="211.0" text="main Color" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="203.0" />
<Label layoutX="14.0" layoutY="371.0" text="Cemu Settings" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="350.0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Label>
<Label layoutX="22.0" layoutY="14.0" text="cemu_UI Settings" AnchorPane.leftAnchor="18.0" AnchorPane.topAnchor="14.0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Label>
<JFXToggleButton fx:id="cloudSyncToggleBtn" layoutX="14.0" layoutY="264.0" onAction="#cloudSyncToggleBtnAction" text="cloud savegames (Google Drive)" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="267.0" />
</children>
</AnchorPane>
<AnchorPane fx:id="smmdbAnchorPane" style="-fx-background-color: white;" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="175.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="38.0">
<children>
<JFXTreeTableView fx:id="courseTreeTable" layoutX="14.0" layoutY="14.0" prefHeight="537.0" prefWidth="405.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="14.0" />
<ImageView fx:id="smmdbImageView" fitHeight="150.0" fitWidth="267.0" layoutX="436.0" layoutY="14.0" pickOnBounds="true" preserveRatio="true" AnchorPane.leftAnchor="436.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0" />
<ScrollPane fx:id="smmdbScrollPane" layoutX="436.0" layoutY="181.0" prefHeight="290.0" prefWidth="267.0" AnchorPane.bottomAnchor="91.0" AnchorPane.leftAnchor="436.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="181.0">
<content>
<TextFlow fx:id="smmdbTextFlow" maxWidth="265.0" prefWidth="265.0" />
</content>
</ScrollPane>
<JFXButton fx:id="smmdbDownloadBtn" buttonType="RAISED" layoutX="436.0" layoutY="479.0" onAction="#smmdbDownloadBtnAction" prefHeight="38.0" prefWidth="267.0" text="download" AnchorPane.bottomAnchor="45.0" AnchorPane.leftAnchor="436.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="479.0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<Label fx:id="helpLabel" layoutX="436.0" layoutY="538.0" prefHeight="17.0" prefWidth="267.0" text="please help me improving this! click me!">
<font>
<Font size="14.0" />
</font>
</Label>
</children></AnchorPane>
<JFXButton fx:id="playBtn" buttonType="RAISED" maxHeight="38.0" maxWidth="100.0" onAction="#playBtnAction" ripplerFill="#c92a2a" text="play" visible="false" AnchorPane.bottomAnchor="7.0" AnchorPane.leftAnchor="396.0" AnchorPane.rightAnchor="396.0" AnchorPane.topAnchor="555.0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<JFXButton fx:id="timePlayedBtn" buttonType="RAISED" maxHeight="32.0" minWidth="100.0" onAction="#timePlayedBtnAction" prefHeight="32.0" style="-fx-background-color: #ffffff; -fx-button-type: RAISED; -fx-text-fill: BLACK;" visible="false" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="516.5" AnchorPane.topAnchor="558.0">
</JFXButton>
<JFXButton fx:id="lastTimePlayedBtn" buttonType="RAISED" maxHeight="32.0" minWidth="100.0" onAction="#lastTimePlayedBtnAction" prefHeight="32.0" style="-fx-background-color: #ffffff; -fx-button-type: RAISED; -fx-text-fill: BLACK;" visible="false" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="516.5" AnchorPane.topAnchor="558.0" />
</children>
</AnchorPane>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="ASCII"?>
<anttasks:AntTask xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:anttasks="http://org.eclipse.fx.ide.jdt/1.0" buildDirectory="${project}/build">
<deploy>
<application name="cemu_UI"/>
<info/>
</deploy>
<signjar/>
</anttasks:AntTask>

222
pom.xml Normal file
View File

@ -0,0 +1,222 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com</groupId>
<artifactId>cemu_UI</artifactId>
<version>0.2.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>cemu_UI</name>
<url>http://www.kellerkinder.xyz</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jfoenix</groupId>
<artifactId>jfoenix</artifactId>
<version>1.9.0</version>
</dependency>
<dependency>
<groupId>com.eclipsesource.minimal-json</groupId>
<artifactId>minimal-json</artifactId>
<version>0.9.4</version>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-vfs2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-vfs2</artifactId>
<version>2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.datafx/flow -->
<dependency>
<groupId>io.datafx</groupId>
<artifactId>flow</artifactId>
<version>8.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.lingala.zip4j/zip4j -->
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>1.3.2</version>
</dependency>
<!-- Google Drive-API libraries-->
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.api-client/google-api-client -->
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.23.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.apis/google-api-services-drive -->
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-drive</artifactId>
<version>v3-rev87-1.23.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.http-client/google-http-client -->
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client</artifactId>
<version>1.23.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.http-client/google-http-client-jackson2 -->
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-jackson2</artifactId>
<version>1.23.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.oauth-client/google-oauth-client -->
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client</artifactId>
<version>1.23.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.oauth-client/google-oauth-client-java6 -->
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-java6</artifactId>
<version>1.23.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.oauth-client/google-oauth-client-jetty -->
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-jetty</artifactId>
<version>1.23.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0-b01</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mortbay.jetty/jetty -->
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.26</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mortbay.jetty/jetty-util -->
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>6.1.26</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libraries/</classpathPrefix>
<mainClass>com.cemu_UI.application.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/libraries</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,153 +0,0 @@
/**
* cemu_UI
*
* Copyright 2017 <@Seil0>
*
* "THE CHOCOLATE-WARE LICENSE" (Revision 1):
* As long as you retain this notice this software is licensed under the GNU GENERAL PUBLIC LICENSE Version 3,
* with the following additions:
* If we meet some day, and you think this stuff is worth it,
* you can buy me a chocolate in return. - @Seil0
* (license based in Beer-ware, see https://fedoraproject.org/wiki/Licensing/Beerware )
*
*/
package application;
import java.io.File;
import java.io.IOException;
import cloudControllerInstances.GoogleDriveController;
import javafx.application.Platform;
public class CloudController {
public CloudController(Main ma) {
main = ma;
}
private Main main;
private GoogleDriveController googleDriveController = new GoogleDriveController();
void initializeConnection(String cloudService, String cemuDirectory) {
System.out.println("sartting cloud initialisation... ");
if(cloudService.equals("GoogleDrive")) {
System.out.println("selected service is Google Drive");
try {
googleDriveController.main(cemuDirectory);
} catch (IOException e) {
e.printStackTrace();
}
}
if(cloudService.equals("Dropbox")) {
System.out.println("selected service is Dropbox");
}
System.out.println("cloud initialisation done!");
}
void stratupCheck(String cloudService, String cemuDirectory) {
if(cloudService.equals("GoogleDrive")) {
System.out.println("starting startup check google drive...");
try {
if (!googleDriveController.checkFolder()) {
googleDriveController.creatFolder();
main.mainWindowController.saveSettings();
Thread thread = new Thread(new Runnable() {
public void run() {
Platform.runLater(() -> {
main.mainWindowController.getPlayBtn().setText("syncing...");
});
googleDriveController.uploadAllFiles();
Platform.runLater(() -> {
main.mainWindowController.getPlayBtn().setText("play");
});
}
});
thread.start();
} else {
sync(cloudService, cemuDirectory);
}
} catch (IOException e) {
e.printStackTrace();
}
}
if(cloudService.equals("Dropbox")) {
}
}
void sync(String cloudService, String cemuDirectory) {
//running sync in a new thread, instead of blocking the main thread
Thread thread = new Thread(new Runnable() {
public void run() {
Platform.runLater(() -> {
main.mainWindowController.getPlayBtn().setText("syncing...");
});
System.out.println("starting sync in new thread...");
if(cloudService.equals("GoogleDrive")) {
try {
googleDriveController.sync(cemuDirectory);
} catch (IOException e) {
e.printStackTrace();
}
}
if(cloudService.equals("Dropbox")) {
}
Platform.runLater(() -> {
main.mainWindowController.getPlayBtn().setText("play");
});
main.mainWindowController.saveSettings();
System.out.println("sync finished!");
}
});
thread.start();
}
void uploadFile(String cloudService, File file) {
//running uploadFile in a new thread, instead of blocking the main thread
new Thread() {
public void run() {
System.out.println("starting uploadFile in new thread...");
if(cloudService.equals("GoogleDrive")) {
try {
googleDriveController.uploadFile(file);
} catch (IOException e) {
e.printStackTrace();
}
}
if(cloudService.equals("Dropbox")) {
}
}
}.start();
}
public String getFolderID(String cloudService) {
String folderID = "";
if(cloudService.equals("GoogleDrive")) {
folderID = googleDriveController.getFolderID();
}
if(cloudService.equals("Dropbox")) {
}
return folderID;
}
public void setFolderID(String folderID, String cloudService) {
if(cloudService.equals("GoogleDrive")) {
googleDriveController.setFolderID(folderID);
}
if(cloudService.equals("Dropbox")) {
}
}
}

View File

@ -1,176 +0,0 @@
/**
* cemu_UI
*
* Copyright 2017 <@Seil0>
*
* "THE CHOCOLATE-WARE LICENSE" (Revision 1):
* As long as you retain this notice this software is licensed under the GNU GENERAL PUBLIC LICENSE Version 3,
* with the following additions:
* If we meet some day, and you think this stuff is worth it,
* you can buy me a chocolate in return. - @Seil0
* (license based in Beer-ware, see https://fedoraproject.org/wiki/Licensing/Beerware )
*
*/
package application;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.Optional;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.AnchorPane;
public class Main extends Application {
Stage primaryStage;
public MainWindowController mainWindowController; //TODO find a better way
CloudController cloudController;
private String dirWin = System.getProperty("user.home") + "/Documents/cemu_UI"; //Windows: C:/Users/"User"/Documents/HomeFlix
private String dirLinux = System.getProperty("user.home") + "/cemu_UI"; //Linux: /home/"User"/HomeFlix
private String gamesDBdownloadURL = "https://github.com/Seil0/cemu_UI/raw/master/downloadContent/games.db";
private File directory;
private File configFile;
private File gamesDBFile;
@SuppressWarnings("unused")
private File localDB;
private File pictureCache;
@Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
cloudController = new CloudController(this);
mainWindow();
}
private void mainWindow(){
try {
FXMLLoader loader = new FXMLLoader(Main.class.getResource("MainWindow.fxml"));
AnchorPane pane = loader.load();
primaryStage.setResizable(false);
primaryStage.setTitle("cemu_UI");
// primaryStage.getIcons().add(new Image(Main.class.getResourceAsStream("/resources/Homeflix_Icon_64x64.png"))); //adds application icon
mainWindowController = loader.getController(); //Link of FXMLController and controller class
mainWindowController.setMain(this); //call setMain
//get os and the right paths
if(System.getProperty("os.name").equals("Linux")){
directory = new File(dirLinux);
configFile = new File(dirLinux + "/config.xml");
gamesDBFile = new File(dirLinux + "/games.db");
localDB = new File(dirLinux+"/localRoms.db");
pictureCache= new File(dirLinux+"/picture_cache");
}else{
directory = new File(dirWin);
configFile = new File(dirWin + "/config.xml");
gamesDBFile = new File(dirWin + "/games.db");
localDB = new File(dirWin+"/localRoms.db");
pictureCache= new File(dirWin+"/picture_cache");
}
//startup checks
System.out.println("Directory: " + directory.exists());
System.out.println("configfile: " + configFile.exists());
if(directory.exists() != true){
System.out.println("mkdir all");
directory.mkdir();
pictureCache.mkdir();
}
if(configFile.exists() != true){
System.out.println("firststart");
firstStart();
mainWindowController.setColor("00a8cc");
mainWindowController.setxPosHelper(0);
mainWindowController.saveSettings();
Runtime.getRuntime().exec("java -jar cemu_UI.jar"); //start again (preventing Bugs)
System.exit(0); //finishes itself
}
if(pictureCache.exists() != true){
pictureCache.mkdir();
}
if(gamesDBFile.exists() != true){
try {
System.out.print("downloading games.db... ");
URL website = new URL(gamesDBdownloadURL);
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(gamesDBFile);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
System.out.println("done!");
} catch (Exception e) {
e.printStackTrace();
}
}
//loading settings and initialize UI, dbController.main() loads all databases
mainWindowController.loadSettings();
mainWindowController.dbController.main();
if(mainWindowController.isCloudSync()) {
cloudController.initializeConnection(mainWindowController.getCloudService(), mainWindowController.getCemuPath());
cloudController.stratupCheck(mainWindowController.getCloudService(), mainWindowController.getCemuPath());
}
mainWindowController.addUIData();
mainWindowController.initActions();
mainWindowController.initUI();
Scene scene = new Scene(pane); //create new scene, append pane to scene
scene.getStylesheets().add(Main.class.getResource("MainWindows.css").toExternalForm());
primaryStage.setScene(scene); //append scene to stage
primaryStage.show(); //show stage
} catch (IOException e) {
e.printStackTrace();
}
}
private void firstStart(){
Alert alert = new Alert(AlertType.CONFIRMATION); //new alert with file-chooser
alert.setTitle("cemu_UI");
alert.setHeaderText("cemu installation");
alert.setContentText("please select your cemu installation");
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == ButtonType.OK){
DirectoryChooser directoryChooser = new DirectoryChooser();
File selectedDirectory = directoryChooser.showDialog(primaryStage);
mainWindowController.setCemuPath(selectedDirectory.getAbsolutePath());
} else {
mainWindowController.setCemuPath(null);
}
Alert alert2 = new Alert(AlertType.CONFIRMATION); //new alert with file-chooser
alert2.setTitle("cemu_UI");
alert2.setHeaderText("rom directory");
alert2.setContentText("please select your rom directory");
Optional<ButtonType> result2 = alert2.showAndWait();
if (result2.get() == ButtonType.OK){
DirectoryChooser directoryChooser = new DirectoryChooser();
File selectedDirectory = directoryChooser.showDialog(primaryStage);
mainWindowController.setRomPath(selectedDirectory.getAbsolutePath());
} else {
mainWindowController.setRomPath(null);
}
}
public static void main(String[] args) {
launch(args);
}
}

View File

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXColorPicker?>
<?import com.jfoenix.controls.JFXHamburger?>
<?import com.jfoenix.controls.JFXTextField?>
<?import com.jfoenix.controls.JFXToggleButton?>
<?import com.jfoenix.controls.JFXTreeTableView?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.TextFlow?>
<AnchorPane prefHeight="600.0" prefWidth="892.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainWindowController">
<children>
<ScrollPane fx:id="scrollPaneMain" fitToWidth="true" layoutY="38.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="38.0">
<content>
<AnchorPane fx:id="gamesAnchorPane">
<padding>
<Insets bottom="17.0" />
</padding></AnchorPane>
</content>
</ScrollPane>
<HBox fx:id="topHBox" prefHeight="38.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<JFXHamburger fx:id="menuHam" prefHeight="38.0" prefWidth="38.0" stylesheets="@MainWindows.css" />
</children>
</HBox>
<VBox fx:id="sideMenuVBox" layoutY="32.0" prefHeight="568.0" prefWidth="175.0" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="38.0">
<children>
<JFXButton fx:id="aboutBtn" alignment="TOP_LEFT" maxHeight="38.0" maxWidth="190.0" onAction="#aboutBtnAction" prefHeight="38.0" prefWidth="190.0" text="About" textAlignment="LEFT">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<JFXButton fx:id="settingsBtn" alignment="TOP_LEFT" maxHeight="38.0" maxWidth="213.0" onAction="#settingsBtnAction" prefHeight="38.0" prefWidth="213.0" text="Settings" textAlignment="LEFT">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<JFXButton fx:id="addBtn" alignment="TOP_LEFT" maxHeight="38.0" maxWidth="193.0" onAction="#addBtnAction" prefHeight="38.0" prefWidth="193.0" text="Add new Game" textAlignment="LEFT">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<JFXButton fx:id="reloadRomsBtn" alignment="TOP_LEFT" maxHeight="38.0" maxWidth="199.0" onAction="#reloadRomsBtnAction" prefHeight="38.0" prefWidth="199.0" text="reload roms" textAlignment="LEFT">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<JFXButton fx:id="smmdbBtn" alignment="TOP_LEFT" onAction="#smmdbBtnAction" prefHeight="38.0" prefWidth="216.0" text="smmdb">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
</children>
</VBox>
<!-- space between settings sections 35px, between sections elements (label + element) 20px, between label and element 3px(or more) -->
<AnchorPane fx:id="settingsAnchorPane" layoutX="38.0" layoutY="27.0" prefHeight="573.0" style="-fx-background-color: white;" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="175.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="38.0">
<children>
<Label layoutX="22.0" layoutY="59.0" text="Cemu Directory" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="59.0" />
<JFXTextField fx:id="cemuTextField" layoutX="18.0" layoutY="83.0" maxWidth="305.0" minWidth="305.0" onAction="#cemuTextFieldAction" prefHeight="32.0" prefWidth="305.0" promptText="cemu directory" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="79.0" />
<JFXTextField fx:id="romTextField" layoutX="18.0" layoutY="159.0" maxWidth="305.0" minWidth="305.0" onAction="#romTextFieldAction" prefHeight="32.0" prefWidth="305.0" promptText="rom directory" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="151.0" />
<JFXButton fx:id="romTFBtn" layoutX="337.0" layoutY="159.0" onAction="#romTFBtnAction" prefHeight="32.0" prefWidth="108.0" text="choose directory" AnchorPane.leftAnchor="333.0" AnchorPane.topAnchor="151.0" />
<JFXButton fx:id="cemuTFBtn" layoutX="333.0" layoutY="79.0" onAction="#cemuTFBtnAction" prefHeight="32.0" prefWidth="108.0" text="choose directory" AnchorPane.leftAnchor="333.0" AnchorPane.topAnchor="79.0" />
<JFXColorPicker fx:id="colorPicker" layoutX="22.0" layoutY="235.0" onAction="#colorPickerAction" AnchorPane.leftAnchor="16.0" AnchorPane.topAnchor="227.0" />
<JFXToggleButton fx:id="fullscreenToggleBtn" layoutX="14.0" layoutY="391.0" onAction="#fullscreenToggleBtnAction" text="start game in fullscreen" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="390.0" />
<Label layoutX="22.0" layoutY="135.0" text="Rom Directory" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="131.0" />
<Label layoutX="22.0" layoutY="211.0" text="main Color" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="203.0" />
<Label layoutX="14.0" layoutY="371.0" text="Cemu Settings" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="350.0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Label>
<Label layoutX="22.0" layoutY="14.0" text="cemu_UI Settings" AnchorPane.leftAnchor="18.0" AnchorPane.topAnchor="14.0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Label>
<JFXToggleButton fx:id="cloudSyncToggleBtn" layoutX="14.0" layoutY="264.0" onAction="#cloudSyncToggleBtnAction" text="cloud savegames (Google Drive)" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="267.0" />
</children>
</AnchorPane>
<AnchorPane fx:id="smmdbAnchorPane" style="-fx-background-color: white;" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="175.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="38.0">
<children>
<JFXTreeTableView fx:id="courseTreeTable" layoutX="14.0" layoutY="14.0" prefHeight="537.0" prefWidth="405.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="14.0" />
<ImageView fx:id="smmdbImageView" fitHeight="150.0" fitWidth="267.0" layoutX="436.0" layoutY="14.0" pickOnBounds="true" preserveRatio="true" AnchorPane.leftAnchor="436.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0" />
<ScrollPane fx:id="smmdbScrollPane" layoutX="436.0" layoutY="181.0" prefHeight="290.0" prefWidth="267.0" AnchorPane.bottomAnchor="91.0" AnchorPane.leftAnchor="436.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="181.0">
<content>
<TextFlow fx:id="smmdbTextFlow" maxWidth="265.0" prefWidth="265.0" />
</content>
</ScrollPane>
<JFXButton fx:id="smmdbDownloadBtn" buttonType="RAISED" layoutX="436.0" layoutY="479.0" onAction="#smmdbDownloadBtnAction" prefHeight="38.0" prefWidth="267.0" text="download" AnchorPane.bottomAnchor="45.0" AnchorPane.leftAnchor="436.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="479.0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<Label fx:id="helpLabel" layoutX="436.0" layoutY="538.0" prefHeight="17.0" prefWidth="267.0" text="please help me improving this! click me!">
<font>
<Font size="14.0" />
</font>
</Label>
</children></AnchorPane>
<JFXButton fx:id="playBtn" buttonType="RAISED" maxHeight="38.0" maxWidth="100.0" onAction="#playBtnAction" ripplerFill="#c92a2a" text="play" visible="false" AnchorPane.bottomAnchor="7.0" AnchorPane.leftAnchor="396.0" AnchorPane.rightAnchor="396.0" AnchorPane.topAnchor="555.0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<JFXButton fx:id="timePlayedBtn" buttonType="RAISED" maxHeight="32.0" minWidth="100.0" onAction="#timePlayedBtnAction" prefHeight="32.0" style="-fx-background-color: #ffffff; -fx-button-type: RAISED; -fx-text-fill: BLACK;" visible="false" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="516.5" AnchorPane.topAnchor="558.0">
</JFXButton>
<JFXButton fx:id="lastTimePlayedBtn" buttonType="RAISED" maxHeight="32.0" minWidth="100.0" onAction="#lastTimePlayedBtnAction" prefHeight="32.0" style="-fx-background-color: #ffffff; -fx-button-type: RAISED; -fx-text-fill: BLACK;" visible="false" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="516.5" AnchorPane.topAnchor="558.0" />
</children>
</AnchorPane>

File diff suppressed because it is too large Load Diff

View File

@ -1,86 +0,0 @@
/*
* HAMBURGER CSS
*/
.jfx-hamburgerW StackPane {
-fx-background-color: white;
-fx-background-radius: 5px;
}
.jfx-hamburgerB StackPane {
-fx-background-color: black;
-fx-background-radius: 5px;
}
/*
* TREE TABLE CSS
*/
.tree-table-view {
-fx-tree-table-color: rgba(0, 168, 204, 0.2);
-fx-tree-table-rippler-color: rgba(0, 168, 204, 0.4);
}
.tree-table-view:focused .tree-table-row-cell:selected {
-fx-background-color: -fx-tree-table-color;
-fx-table-cell-border-color: -fx-tree-table-color;
-fx-text-fill: BLACK;
}
.tree-table-view:focused .tree-table-row-cell:selected .tree-table-cell {
-fx-text-fill: BLACK;
}
.tree-table-view .jfx-rippler {
-jfx-rippler-fill: -fx-tree-table-rippler-color;
}
.tree-table-view .column-header,
.tree-table-view .column-header-background,
.tree-table-view .column-header-background .filler {
-fx-background-color: TRANSPARENT;
}
.tree-table-view .column-header {
-fx-border-width: 0 1 0 1;
-fx-border-color: #F3F3F3;
}
.tree-table-view .column-header .label {
-fx-text-fill: #949494;
-fx-padding: 16 0 16 0;
}
.tree-table-view .column-header .arrow, .tree-table-view .column-header .sort-order-dot {
-fx-background-color: #949494;
}
.tree-table-view .column-header:last-visible {
-fx-border-width: 0 2 0 1;
}
.tree-table-view .column-header-background {
-fx-border-width: 0 0.0 1 0;
-fx-border-color: #F3F3F3;
}
.tree-table-view .tree-table-cell {
-fx-border-width: 0 0 0 0;
-fx-padding: 16 0 16 0;
}
.tree-table-view .column-overlay {
-fx-background-color: -fx-tree-table-color;
}
.tree-table-view .column-resize-line, .tree-table-view .column-drag-header {
-fx-background-color: -fx-tree-table-rippler-color;
}
.tree-table-view:focused {
-fx-background-color: -fx-tree-table-color, -fx-box-border, -fx-control-inner-background;
-fx-background-insets: -1.4, 0, 1;
-fx-background-radius: 1.4, 0, 0;
/*....*/
-fx-padding: 1; /* 0.083333em; */
}

View File

@ -1,135 +0,0 @@
/**
* smmdbapi query
* api query, return all courses as ArrayList
*/
package application;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;
import datatypes.SmmdbApiDataType;
public class SmmdbApiQuery {
private String URL = "http://smmdb.ddns.net/api/getcourses?";
public SmmdbApiQuery() {
//Auto-generated constructor stub
}
//start api query
public ArrayList<SmmdbApiDataType> startQuery() {
ArrayList<Integer> courseIDs = new ArrayList<>();
ArrayList<SmmdbApiDataType> course = new ArrayList<>();
String output = "";
try {
URL apiUrl = new URL(URL);
BufferedReader ina = new BufferedReader(new InputStreamReader(apiUrl.openStream()));
output = ina.readLine();
ina.close();
} catch (IOException e) {
System.out.println("error while making api request or reading response");
e.printStackTrace();
}
JsonObject mainObject = Json.parse(output).asObject().get("courses").asObject();
JsonArray objectAssets = Json.parse(output).asObject().get("order").asArray();
for (JsonValue asset : objectAssets) {
courseIDs.add(asset.asInt());
}
//if value is 9 or "notset" the api returned NULL as value
for (int i = 0; i < courseIDs.size(); i++) {
int id, owner, coursetype, leveltype, difficulty, lastmodified, uploaded, downloads, stars, hasimage, ispackage, updatereq;
String nintendoid, title;
JsonObject singleObject = mainObject.get(courseIDs.get(i).toString()).asObject();
try {
id = singleObject.getInt("id", 0);
} catch (Exception e) {
id = 9;
}
try {
owner = singleObject.getInt("owner", 0);
} catch (Exception e) {
owner = 9;
}
try {
coursetype = singleObject.getInt("coursetype", 0);
} catch (Exception e) {
coursetype = 9;
}
try {
leveltype = singleObject.getInt("leveltype", 0);
} catch (Exception e) {
leveltype = 9;
}
try {
difficulty = singleObject.getInt("difficulty", 0);
} catch (Exception e) {
difficulty = 9;
}
try {
lastmodified = singleObject.getInt("lastmodified", 0);
} catch (Exception e) {
lastmodified = 9;
}
try {
uploaded = singleObject.getInt("uploaded", 0);
} catch (Exception e) {
uploaded = 9;
}
try {
downloads = singleObject.getInt("downloads", 0);
} catch (Exception e) {
downloads = 9;
}
try {
stars = singleObject.getInt("stars", 0);
} catch (Exception e) {
stars = 9;
}
try {
hasimage = singleObject.getInt("hasimage", 0);
} catch (Exception e) {
hasimage = 9;
}
try {
ispackage = singleObject.getInt("ispackage", 0);
} catch (Exception e) {
ispackage = 9;
}
try {
updatereq = singleObject.getInt("updatereq", 0);
} catch (Exception e) {
updatereq = 9;
}
try {
nintendoid = singleObject.getString("nintendoid", "");
} catch (Exception e) {
nintendoid = "notset";
}
try {
title = singleObject.getString("title", "");;
} catch (Exception e) {
title = "notset";
}
course.add(new SmmdbApiDataType(id, owner, coursetype, leveltype, difficulty, lastmodified, uploaded, downloads,
stars, hasimage, ispackage, updatereq, nintendoid, title));
}
return course;
}
}

View File

@ -1,26 +0,0 @@
/**
* Datatype used in the TreeTableview for
*/
package datatypes;
import com.jfoenix.controls.datamodels.treetable.RecursiveTreeObject;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class CourseTableDataType extends RecursiveTreeObject<CourseTableDataType> {
public final StringProperty title;
public final IntegerProperty downloads;
public final IntegerProperty stars;
public final IntegerProperty id;
public CourseTableDataType(String title, int downloads, int stars, int id) {
this.title = new SimpleStringProperty(title);
this.downloads = new SimpleIntegerProperty(downloads);
this.stars = new SimpleIntegerProperty(stars);
this.id = new SimpleIntegerProperty(id);
}
}

View File

@ -1,215 +0,0 @@
/**
* Datatype used for the smmdbapi query
*/
package datatypes;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class SmmdbApiDataType {
private final IntegerProperty id = new SimpleIntegerProperty();
private final IntegerProperty owner = new SimpleIntegerProperty();
private final IntegerProperty coursetype = new SimpleIntegerProperty();
private final IntegerProperty leveltype = new SimpleIntegerProperty();
private final IntegerProperty difficulty = new SimpleIntegerProperty();
private final IntegerProperty lastmodified = new SimpleIntegerProperty();
private final IntegerProperty uploaded = new SimpleIntegerProperty();
private final IntegerProperty downloads = new SimpleIntegerProperty();
private final IntegerProperty stars = new SimpleIntegerProperty();
private final IntegerProperty hasimage = new SimpleIntegerProperty();
private final IntegerProperty ispackage = new SimpleIntegerProperty();
private final IntegerProperty updatereq = new SimpleIntegerProperty();
private final StringProperty nintendoid = new SimpleStringProperty();
private final StringProperty title = new SimpleStringProperty();
public SmmdbApiDataType(final int id, final int owner, final int coursetype, final int leveltype, final int difficulty,
final int lastmodified, final int uploaded, final int downloads, final int stars, final int hasimage,
final int ispackage, final int updatereq, final String nintendoid, final String title) {
this.id.set(id);
this.owner.set(owner);
this.coursetype.set(coursetype);
this.leveltype.set(leveltype);
this.difficulty.set(difficulty);
this.lastmodified.set(lastmodified);
this.uploaded.set(uploaded);
this.downloads.set(downloads);
this.stars.set(stars);
this.hasimage.set(hasimage);
this.ispackage.set(ispackage);
this.updatereq.set(updatereq);
this.nintendoid.set(nintendoid);
this.title.set(title);
}
public IntegerProperty idProperty(){
return id;
}
public IntegerProperty ownerProperty(){
return owner;
}
public IntegerProperty coursetypeProperty(){
return coursetype;
}
public StringProperty nintendoidProperty(){
return nintendoid;
}
public IntegerProperty leveltypeProperty(){
return leveltype;
}
public IntegerProperty difficultyProperty(){
return difficulty;
}
public IntegerProperty lastmodifiedProperty(){
return lastmodified;
}
public IntegerProperty uploadedProperty(){
return uploaded;
}
public IntegerProperty downloadsProperty(){
return downloads;
}
public IntegerProperty starsProperty(){
return stars;
}
public IntegerProperty hasimageProperty(){
return hasimage;
}
public IntegerProperty ispackageProperty(){
return ispackage;
}
public IntegerProperty updatereqProperty(){
return updatereq;
}
public StringProperty titleProperty(){
return title;
}
public int getId() {
return idProperty().get();
}
public int getOwner() {
return ownerProperty().get();
}
public int getCoursetype() {
return coursetypeProperty().get();
}
public int getLeveltype() {
return leveltypeProperty().get();
}
public int getDifficulty() {
return difficultyProperty().get();
}
public int getLastmodified() {
return lastmodifiedProperty().get();
}
public int getUploaded() {
return uploadedProperty().get();
}
public int getDownloads() {
return downloadsProperty().get();
}
public int getStars() {
return starsProperty().get();
}
public int getHasimage() {
return hasimageProperty().get();
}
public int getIspackage() {
return ispackageProperty().get();
}
public int getUpdatereq() {
return updatereqProperty().get();
}
public String getNintendoid() {
return nintendoidProperty().get();
}
public String getTitle() {
return titleProperty().get();
}
public final void setId(int id) {
idProperty().set(id);
}
public final void setOwner(int owner) {
ownerProperty().set(owner);
}
public final void setCoursetype(int coursetype) {
coursetypeProperty().set(coursetype);
}
public final void setLeveltype(int leveltype) {
leveltypeProperty().set(leveltype);
}
public final void setDifficulty(int difficulty) {
difficultyProperty().set(difficulty);
}
public final void setLastmodified(int lastmodified) {
lastmodifiedProperty().set(lastmodified);
}
public final void setUploaded(int uploaded) {
uploadedProperty().set(uploaded);
}
public final void setDownloads(int downloads) {
downloadsProperty().set(downloads);
}
public final void setStars(int stars) {
starsProperty().set(stars);
}
public final void setHasimage(int hasimage) {
hasimageProperty().set(hasimage);
}
public final void setIspackage(int ispackage) {
ispackageProperty().set(ispackage);
}
public final void setUpdatereq(int updatereq) {
updatereqProperty().set(updatereq);
}
public final void setNintendoid(String nintendoid) {
nintendoidProperty().set(nintendoid);
}
public final void setTitle(String title) {
titleProperty().set(title);
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,306 @@
/**
* cemu_UI
*
* Copyright 2017 <@Seil0>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package com.cemu_UI.application;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.Optional;
import java.util.Timer;
import java.util.TimerTask;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.cemu_UI.controller.CloudController;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXMLLoader;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.AnchorPane;
public class Main extends Application {
Stage primaryStage;
public MainWindowController mainWindowController; //TODO find a better way
CloudController cloudController;
AnchorPane pane;
private Scene scene;
private String dirWin = System.getProperty("user.home") + "/Documents/cemu_UI"; //Windows: C:/Users/"User"/Documents/cemu_UI
private String dirLinux = System.getProperty("user.home") + "/cemu_UI"; //Linux: /home/"User"/cemu_UI
private String gamesDBdownloadURL = "https://github.com/Seil0/cemu_UI/raw/master/downloadContent/games.db";
private File directory;
private File configFile;
private File gamesDBFile;
@SuppressWarnings("unused")
private File localDB;
private File pictureCache;
private static Logger LOGGER;
@Override
public void start(Stage primaryStage) {
try {
this.primaryStage = primaryStage;
cloudController = new CloudController(mainWindowController);
mainWindow();
initActions();
} catch (Exception e) {
LOGGER.error("ooooops",e);
}
}
private void mainWindow(){
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(ClassLoader.getSystemResource("fxml/MainWindow.fxml"));
pane = (AnchorPane) loader.load();
// primaryStage.setResizable(false);
primaryStage.setTitle("cemu_UI");
// primaryStage.getIcons().add(new Image(Main.class.getResourceAsStream("/resources/Homeflix_Icon_64x64.png"))); //adds application icon
mainWindowController = loader.getController(); //Link of FXMLController and controller class
mainWindowController.setMain(this); //call setMain
//get os and the right paths
if (System.getProperty("os.name").equals("Linux")) {
directory = new File(dirLinux);
configFile = new File(dirLinux + "/config.xml");
gamesDBFile = new File(dirLinux + "/games.db");
localDB = new File(dirLinux+"/localRoms.db");
pictureCache= new File(dirLinux+"/picture_cache");
} else {
directory = new File(dirWin);
configFile = new File(dirWin + "/config.xml");
gamesDBFile = new File(dirWin + "/games.db");
localDB = new File(dirWin+"/localRoms.db");
pictureCache= new File(dirWin+"/picture_cache");
}
//startup checks
//check if client_secret.jason is present
if (Main.class.getResourceAsStream("/client_secret.json") == null) {
LOGGER.error("client_secret is missing!!!!!");
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("cemu_UI");
alert.setHeaderText("Error");
alert.setContentText("client_secret is missing! Please contact the maintainer. \nIf you compiled cemu_UI by yourself see: \nhttps://github.com/Seil0/cemu_UI/wiki/Documantation");
alert.showAndWait();
}
LOGGER.info("Directory: " + directory.exists());
LOGGER.info("Configfile: " + configFile.exists());
if (!directory.exists()) {
LOGGER.info("creating cemu_UI directory");
directory.mkdir();
pictureCache.mkdir();
}
if (!configFile.exists()) {
LOGGER.info("firststart, setting default values");
firstStart();
mainWindowController.setColor("00a8cc");
mainWindowController.setAutoUpdate(false);
mainWindowController.setxPosHelper(0);
mainWindowController.saveSettings();
Runtime.getRuntime().exec("java -jar cemu_UI.jar"); //start again (preventing Bugs)
System.exit(0); //finishes itself
}
if (pictureCache.exists() != true) {
pictureCache.mkdir();
}
if (gamesDBFile.exists() != true) {
try {
LOGGER.info("downloading games.db... ");
URL website = new URL(gamesDBdownloadURL);
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(gamesDBFile);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
LOGGER.info("finished downloading games.db");
} catch (Exception e) {
e.printStackTrace();
}
}
//loading settings and initialize UI, dbController.main() loads all databases
mainWindowController.loadSettings();
mainWindowController.checkAutoUpdate();
mainWindowController.initActions();
mainWindowController.initUI();
mainWindowController.dbController.main();
if(mainWindowController.isCloudSync()) {
cloudController.initializeConnection(mainWindowController.getCloudService(), mainWindowController.getCemuPath());
cloudController.stratupCheck(mainWindowController.getCloudService(), mainWindowController.getCemuPath());
}
mainWindowController.addUIData();
scene = new Scene(pane); //create new scene, append pane to scene
scene.getStylesheets().add(Main.class.getResource("/css/MainWindows.css").toExternalForm());
primaryStage.setScene(scene); //append scene to stage
primaryStage.show(); //show stage
} catch (IOException e) {
e.printStackTrace();
}
}
private void firstStart(){
Alert alert = new Alert(AlertType.CONFIRMATION); //new alert with file-chooser
alert.setTitle("cemu_UI");
alert.setHeaderText("cemu installation");
alert.setContentText("please select your cemu installation");
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == ButtonType.OK) {
DirectoryChooser directoryChooser = new DirectoryChooser();
File selectedDirectory = directoryChooser.showDialog(primaryStage);
mainWindowController.setCemuPath(selectedDirectory.getAbsolutePath());
} else {
mainWindowController.setCemuPath(null);
}
Alert alert2 = new Alert(AlertType.CONFIRMATION); //new alert with file-chooser
alert2.setTitle("cemu_UI");
alert2.setHeaderText("rom directory");
alert2.setContentText("please select your rom directory");
Optional<ButtonType> result2 = alert2.showAndWait();
if (result2.get() == ButtonType.OK) {
DirectoryChooser directoryChooser = new DirectoryChooser();
File selectedDirectory = directoryChooser.showDialog(primaryStage);
mainWindowController.setRomPath(selectedDirectory.getAbsolutePath());
} else {
mainWindowController.setRomPath(null);
}
}
private void initActions() {
final ChangeListener<Number> widthListener = new ChangeListener<Number>() {
final Timer timer = new Timer();
TimerTask saveTask = null; //task to execute save operation
final long delayTime = 500; //delay until the window size is saved, if the window is resized earlier it will be killed, default is 500ms
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, final Number newValue) {
int xPosHelperMax = (int) Math.floor((mainWindowController.getMainAnchorPane().getWidth() - 36) / 217);
mainWindowController.refreshplayBtnPosition();
//call only if there is enough space for a new row
if (mainWindowController.getOldXPosHelper() != xPosHelperMax) {
mainWindowController.refreshUIData();
}
//if saveTask is already running kill it
if (saveTask != null) saveTask.cancel();
saveTask = new TimerTask() {
@Override
public void run() {
mainWindowController.saveSettings();
}
};
timer.schedule(saveTask, delayTime);
}
};
final ChangeListener<Number> heightListener = new ChangeListener<Number>() {
final Timer timer = new Timer();
TimerTask saveTask = null; //task to execute save operation
final long delayTime = 500; //delay until the window size is saved, if the window is resized earlier it will be killed, default is 500ms
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, final Number newValue) {
if (saveTask != null) saveTask.cancel();
saveTask = new TimerTask() {
@Override
public void run() {
mainWindowController.saveSettings();
}
};
timer.schedule(saveTask, delayTime);
}
};
final ChangeListener<Boolean> maximizeListener = new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
primaryStage.setMaximized(false);
Alert alert = new Alert(AlertType.WARNING);
alert.setTitle("edit");
alert.setHeaderText("cemu_UI");
alert.setContentText("maximized Window is not supporte!");
alert.initOwner(primaryStage);
alert.showAndWait();
LOGGER.warn("maximized Window is not supported");
}
};
//add listener to primaryStage
primaryStage.widthProperty().addListener(widthListener);
primaryStage.heightProperty().addListener(heightListener);
primaryStage.maximizedProperty().addListener(maximizeListener);
}
public static void main(String[] args) {
//delete old log file and create new
if(System.getProperty("os.name").equals("Linux")){
System.setProperty("logFilename", System.getProperty("user.home") + "/cemu_UI/app.log");
File logFile = new File(System.getProperty("user.home") + "/cemu_UI/app.log");
logFile.delete();
}else{
System.setProperty("logFilename", System.getProperty("user.home") + "/Documents/cemu_UI/app.log");
File logFile = new File(System.getProperty("user.home") + "/Documents/cemu_UI/app.log");
logFile.delete();
}
LOGGER = LogManager.getLogger(Main.class.getName());
launch(args);
}
@Override
public void stop() {
System.exit(0);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -3,31 +3,45 @@
*
* Copyright 2017 <@Seil0>
*
* "THE CHOCOLATE-WARE LICENSE" (Revision 1):
* As long as you retain this notice this software is licensed under the GNU GENERAL PUBLIC LICENSE Version 3,
* with the following additions:
* If we meet some day, and you think this stuff is worth it,
* you can buy me a chocolate in return. - @Seil0
* (license based in Beer-ware, see https://fedoraproject.org/wiki/Licensing/Beerware )
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package application;
package com.cemu_UI.application;
import java.io.IOException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.cemu_UI.controller.dbController;
import javafx.application.Platform;
public class playGame extends Thread{
MainWindowController mainWindowController;
dbController dbController;
private static final Logger LOGGER = LogManager.getLogger(playGame.class.getName());
public playGame(MainWindowController m, dbController db){
public playGame(MainWindowController m, com.cemu_UI.controller.dbController db){
mainWindowController = m;
dbController = db;
}
@Override
public void run(){
String selectedGameTitleID = mainWindowController.getSelectedGameTitleID();
String executeComand;
@ -55,22 +69,22 @@ public class playGame extends Thread{
executeComand = mainWindowController.getCemuPath()+"\\Cemu.exe -g \""+mainWindowController.getGameExecutePath()+"\"";
}
}
System.out.println(executeComand);
LOGGER.info(executeComand);
p = Runtime.getRuntime().exec(executeComand);
p.waitFor();
endTime = System.currentTimeMillis();
timePlayedNow = (int) Math.floor(((endTime - startTime)/1000/60));
timePlayed = Integer.parseInt(dbController.getTimePlayed(selectedGameTitleID))+timePlayedNow;
timePlayed = Integer.parseInt(dbController.getTotalPlaytime(selectedGameTitleID))+timePlayedNow;
dbController.setTimePlayed(Integer.toString(timePlayed), selectedGameTitleID);
dbController.setTotalPlaytime(Integer.toString(timePlayed), selectedGameTitleID);
Platform.runLater(() -> {
if(Integer.parseInt(dbController.getTimePlayed(selectedGameTitleID)) > 60){
int hoursPlayed = (int) Math.floor(Integer.parseInt(dbController.getTimePlayed(selectedGameTitleID))/60);
int minutesPlayed = Integer.parseInt(dbController.getTimePlayed(selectedGameTitleID))-60*hoursPlayed;
mainWindowController.timePlayedBtn.setText(hoursPlayed+"h "+minutesPlayed+"min");
if(Integer.parseInt(dbController.getTotalPlaytime(selectedGameTitleID)) > 60){
int hoursPlayed = (int) Math.floor(Integer.parseInt(dbController.getTotalPlaytime(selectedGameTitleID))/60);
int minutesPlayed = Integer.parseInt(dbController.getTotalPlaytime(selectedGameTitleID))-60*hoursPlayed;
mainWindowController.totalPlaytimeBtn.setText(hoursPlayed+"h "+minutesPlayed+"min");
}else{
mainWindowController.timePlayedBtn.setText(dbController.getTimePlayed(selectedGameTitleID)+ " min");
mainWindowController.totalPlaytimeBtn.setText(dbController.getTotalPlaytime(selectedGameTitleID)+ " min");
}
mainWindowController.main.primaryStage.setIconified(false);
});

View File

@ -0,0 +1,180 @@
/**
* cemu_UI
*
* Copyright 2017 <@Seil0>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package com.cemu_UI.controller;
import java.io.File;
import java.io.IOException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.cemu_UI.application.MainWindowController;
import com.cemu_UI.vendorCloudController.GoogleDriveController;
import javafx.application.Platform;
public class CloudController {
public CloudController(MainWindowController mwc) {
this.mwc = mwc;
}
private MainWindowController mwc;
private GoogleDriveController googleDriveController = new GoogleDriveController();
private static final Logger LOGGER = LogManager.getLogger(CloudController.class.getName());
public boolean initializeConnection(String cloudService, String cemuDirectory) {
boolean success = false;
LOGGER.info("sartting cloud initialisation ...");
if(cloudService.equals("GoogleDrive")) {
LOGGER.info("selected service is Google Drive");
try {
googleDriveController.main(cemuDirectory);
} catch (IOException e) {
LOGGER.error("error while initialize connection", e);
return success;
}
success = true;
}
if(cloudService.equals("Dropbox")) {
LOGGER.info("selected service is Dropbox");
}
LOGGER.info("cloud initialisation done!");
return success;
}
public void stratupCheck(String cloudService, String cemuDirectory) {
if(cloudService.equals("GoogleDrive")) {
LOGGER.info("starting startup check google drive ...");
try {
if (!googleDriveController.checkFolder()) {
googleDriveController.creatFolder();
mwc.saveSettings();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Platform.runLater(() -> {
mwc.getPlayBtn().setText("syncing...");
});
googleDriveController.uploadAllFiles();
Platform.runLater(() -> {
mwc.getPlayBtn().setText("play");
});
}
});
thread.start();
} else {
sync(cloudService, cemuDirectory);
}
} catch (IOException e) {
LOGGER.error("google drive startup check failed", e);
}
}
if(cloudService.equals("Dropbox")) {
}
}
public void sync(String cloudService, String cemuDirectory) {
//running sync in a new thread, instead of blocking the main thread
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Platform.runLater(() -> {
mwc.getPlayBtn().setText("syncing...");
});
LOGGER.info("starting synchronization in new thread ...");
if(cloudService.equals("GoogleDrive")) {
try {
googleDriveController.sync(cemuDirectory);
} catch (IOException e) {
LOGGER.error("google drive synchronization failed", e);
}
}
if(cloudService.equals("Dropbox")) {
}
Platform.runLater(() -> {
mwc.getPlayBtn().setText("play");
});
mwc.saveSettings();
LOGGER.info("synchronization successful!");
}
});
thread.start();
}
void uploadFile(String cloudService, File file) {
//running uploadFile in a new thread, instead of blocking the main thread
new Thread() {
@Override
public void run() {
LOGGER.info("starting uploadFile in new thread ...");
if(cloudService.equals("GoogleDrive")) {
try {
googleDriveController.uploadFile(file);
} catch (IOException e) {
LOGGER.error("google drive uploadFile failed" ,e);
}
}
if(cloudService.equals("Dropbox")) {
}
}
}.start();
}
public String getFolderID(String cloudService) {
String folderID = "";
if (cloudService != null) {
if(cloudService.equals("GoogleDrive")) {
folderID = googleDriveController.getFolderID();
}
if(cloudService.equals("Dropbox")) {
}
}
return folderID;
}
public void setFolderID(String folderID, String cloudService) {
if (cloudService != null) {
if (cloudService.equals("GoogleDrive")) {
googleDriveController.setFolderID(folderID);
}
if (cloudService.equals("Dropbox")) {
}
}
}
}

View File

@ -0,0 +1,154 @@
/**
* cemu_UI
*
* Copyright 2017 <@Seil0>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package com.cemu_UI.controller;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.cemu_UI.datatypes.SmmdbApiDataType;
import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonValue;
public class SmmdbAPIController {
private String URL = "https://smmdb.ddns.net/api/getcourses?format=json";
private static final Logger LOGGER = LogManager.getLogger(SmmdbAPIController.class.getName());
public SmmdbAPIController() {
//Auto-generated constructor stub
}
/**
* start smmdb api query
* @return a ArryList with all courses found at smmdb
*/
public ArrayList<SmmdbApiDataType> startQuery() {
ArrayList<SmmdbApiDataType> course = new ArrayList<>();
String output = "";
try {
URL apiUrl = new URL(URL);
BufferedReader ina = new BufferedReader(new InputStreamReader(apiUrl.openStream()));
output = ina.readLine();
ina.close();
LOGGER.info("response from " + URL + " was valid");
LOGGER.info(output);
} catch (IOException e) {
LOGGER.error("error while making api request or reading response");
LOGGER.error("response from " + URL + " was: " + output, e);
}
String apiOutput = "{ \"courses\": " + output + "}";
JsonArray items = Json.parse(apiOutput).asObject().get("courses").asArray();
for (JsonValue item : items) {
int courseTheme, gameStyle, difficulty, lastmodified, uploaded, autoScroll, stars ,time;
String owner, id, nintendoid, title;
try {
courseTheme = item.asObject().getInt("courseTheme", 9);
} catch (Exception e) {
courseTheme = 9;
}
try {
gameStyle = item.asObject().getInt("gameStyle", 9);
} catch (Exception e) {
gameStyle = 9;
}
try {
difficulty = item.asObject().getInt("difficulty", 9);
} catch (Exception e) {
difficulty = 9;
}
try {
lastmodified = item.asObject().getInt("lastmodified", 9);
} catch (Exception e) {
lastmodified = 9;
}
try {
uploaded = item.asObject().getInt("uploaded", 9);
} catch (Exception e) {
uploaded = 9;
}
try {
autoScroll = item.asObject().getInt("autoScroll", 9);
} catch (Exception e) {
autoScroll = 9;
}
try {
stars = item.asObject().getInt("stars", 9);
} catch (Exception e) {
stars = 9;
}
try {
time = item.asObject().getInt("time", 9);
} catch (Exception e) {
time = 9;
}
try {
owner = item.asObject().getString("owner", "");
} catch (Exception e) {
owner = "notset";
}
try {
id = item.asObject().getString("id", "");
} catch (Exception e) {
id = "notset";
}
try {
nintendoid = item.asObject().getString("nintendoid", "");
} catch (Exception e) {
nintendoid = "notset";
}
try {
title = item.asObject().getString("title", "");;
} catch (Exception e) {
title = "notset";
}
course.add(new SmmdbApiDataType(courseTheme, gameStyle, difficulty, lastmodified, uploaded, autoScroll,
stars, time, owner, id, nintendoid, title));
}
return course;
}
}

View File

@ -0,0 +1,158 @@
/**
* cemu_UI
*
* Copyright 2017 <@Seil0>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package com.cemu_UI.controller;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.swing.ProgressMonitor;
import javax.swing.ProgressMonitorInputStream;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.cemu_UI.application.MainWindowController;
import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;
import javafx.application.Platform;
public class UpdateController implements Runnable{
private MainWindowController mainWindowController;
private String buildNumber;
private String apiOutput;
private String updateBuildNumber; //tag_name from Github
private String browserDownloadUrl; //update download link
private String githubApiRelease = "https://api.github.com/repos/Seil0/cemu_UI/releases/latest";
private String githubApiBeta = "https://api.github.com/repos/Seil0/cemu_UI/releases";
private URL githubApiUrl;
private boolean useBeta;
private static final Logger LOGGER = LogManager.getLogger(UpdateController.class.getName());
/**
* updater for cemu_UI based on Project HomeFlix
* checks for Updates and download it in case there is one
*/
public UpdateController(MainWindowController mwc, String buildNumber, boolean useBeta){
mainWindowController = mwc;
this.buildNumber = buildNumber;
this.useBeta = useBeta;
}
public void run(){
System.out.println("checking for updates ...");
Platform.runLater(() -> {
mainWindowController.getUpdateBtn().setText("checking for updates ...");
});
try {
if (useBeta) {
githubApiUrl = new URL(githubApiBeta);
} else {
githubApiUrl = new URL(githubApiRelease);
}
// URL githubApiUrl = new URL(githubApiRelease);
BufferedReader ina = new BufferedReader(new InputStreamReader(githubApiUrl.openStream()));
apiOutput = ina.readLine();
ina.close();
} catch (IOException e) {
Platform.runLater(() -> {
LOGGER.error("could not check update version", e);
});
}
if (useBeta) {
JsonArray objectArray = Json.parse("{\"items\": " + apiOutput + "}").asObject().get("items").asArray();
JsonValue object = objectArray.get(0);
JsonArray objectAssets = object.asObject().get("assets").asArray();
updateBuildNumber = object.asObject().getString("tag_name", "");
// updateName = object.asObject().getString("name", "");
// updateChanges = object.asObject().getString("body", "");
for (JsonValue asset : objectAssets) {
browserDownloadUrl = asset.asObject().getString("browser_download_url", "");
}
} else {
JsonObject object = Json.parse(apiOutput).asObject();
JsonArray objectAssets = Json.parse(apiOutput).asObject().get("assets").asArray();
updateBuildNumber = object.getString("tag_name", "");
// updateName = object.getString("name", "");
// updateChanges = object.getString("body", "");
for (JsonValue asset : objectAssets) {
browserDownloadUrl = asset.asObject().getString("browser_download_url", "");
}
}
LOGGER.info("Build: "+buildNumber+", Update: "+updateBuildNumber);
//Compares the program BuildNumber with the current BuildNumber if program BuildNumber < current BuildNumber then perform a update
int iversion = Integer.parseInt(buildNumber);
int iaktVersion = Integer.parseInt(updateBuildNumber.replace(".", ""));
if(iversion >= iaktVersion){
Platform.runLater(() -> {
mainWindowController.getUpdateBtn().setText("no update available");
});
LOGGER.info("no update available");
}else{
Platform.runLater(() -> {
mainWindowController.getUpdateBtn().setText("update available");
});
LOGGER.info("update available");
LOGGER.info("download link: " + browserDownloadUrl);
try {
//open new Http connection, ProgressMonitorInputStream for downloading the data
HttpURLConnection conn = (HttpURLConnection) new URL(browserDownloadUrl).openConnection();
ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(null, "Downloading...", conn.getInputStream());
ProgressMonitor pm = pmis.getProgressMonitor();
pm.setMillisToDecideToPopup(0);
pm.setMillisToPopup(0);
pm.setMinimum(0);// tell the progress bar that we start at the beginning of the stream
pm.setMaximum(conn.getContentLength());// tell the progress bar the total number of bytes we are going to read.
FileUtils.copyInputStreamToFile(pmis, new File("cemu_UI_update.jar")); //download update
org.apache.commons.io.FileUtils.copyFile(new File("cemu_UI_update.jar"), new File("cemu_UI.jar")); //TODO rename update to old name
org.apache.commons.io.FileUtils.deleteQuietly(new File("cemu_UI_update.jar")); //delete update
Runtime.getRuntime().exec("java -jar cemu_UI.jar"); //start again
System.exit(0); //finishes itself
} catch (IOException e) {
Platform.runLater(() -> {
LOGGER.info("could not download update files", e);
});
}
}
}
}

View File

@ -3,15 +3,23 @@
*
* Copyright 2017 <@Seil0>
*
* "THE CHOCOLATE-WARE LICENSE" (Revision 1):
* As long as you retain this notice this software is licensed under the GNU GENERAL PUBLIC LICENSE Version 3,
* with the following additions:
* If we meet some day, and you think this stuff is worth it,
* you can buy me a chocolate in return. - @Seil0
* (license based in Beer-ware, see https://fedoraproject.org/wiki/Licensing/Beerware )
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package application;
package com.cemu_UI.controller;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
@ -32,9 +40,13 @@ import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import com.cemu_UI.application.MainWindowController;
public class dbController {
public dbController(MainWindowController m) {
@ -47,15 +59,16 @@ public class dbController {
private String DB_PATH_games;
private Connection connection = null;
private Connection connectionGames = null;
private static final Logger LOGGER = LogManager.getLogger(dbController.class.getName());
public void main(){
System.out.println("<==========starting loading sql==========>");
LOGGER.info("<==========starting loading sql==========>");
loadRomDatabase();
loadGamesDatabase();
createRomDatabase();
loadAllRoms();
checkRemoveEntry();
System.out.println("<==========finished loading sql==========>");
LOGGER.info("<==========finished loading sql==========>");
}
private void loadRomDatabase(){
@ -70,9 +83,9 @@ public class dbController {
connection.setAutoCommit(false); //AutoCommit to false -> manual commit is active
} catch (SQLException e) {
// if the error message is "out of memory", it probably means no database file is found
System.err.println(e.getMessage());
LOGGER.error("error while loading the ROM database", e);
}
System.out.println("rom database loaded successfull");
LOGGER.info("ROM database loaded successfull");
}
/**
@ -91,9 +104,9 @@ public class dbController {
connectionGames.setAutoCommit(false); //AutoCommit to false -> manual commit is active
} catch (SQLException e) {
// if the error message is "out of memory", it probably means no database file is found
System.err.println(e.getMessage());
LOGGER.error("error while loading the games database", e);
}
System.out.println("games database loaded successfull");
LOGGER.info("games database loaded successfull");
}
//creating database, if database has 0 entries search for all .rpx files in the roms directory and add them
@ -103,8 +116,8 @@ public class dbController {
stmt.executeUpdate("create table if not exists local_roms (title, coverPath, romPath, titleID, productCode, region, lastPlayed, timePlayed)");
stmt.close();
connection.commit();
} catch (SQLException e1) {
e1.printStackTrace();
} catch (SQLException e) {
LOGGER.error("error while creating ROM database", e);
}
try {
@ -115,34 +128,34 @@ public class dbController {
}
stmt.close();
rs.close();
}catch (SQLException ea){
System.err.println("Ups! an error occured!");
ea.printStackTrace();
}catch (SQLException e){
LOGGER.error("error while loading ROMs from ROM database, local_roms table", e);
}
if(entries.size() == 0){
loadRomDirectory(mainWindowController.getRomPath());
}
}
void addRom(String title, String coverPath, String romPath, String titleID, String productCode, String region, String lastPlayed, String timePlayed) throws SQLException{
public void addRom(String title, String coverPath, String romPath, String titleID, String productCode, String region, String lastPlayed, String timePlayed) throws SQLException{
Statement stmt = connection.createStatement();
stmt.executeUpdate("insert into local_roms values ('"+title+"','"+coverPath+"','"+romPath+"','"+titleID+"','"+productCode+"','"+region+"','"+lastPlayed+"','"+timePlayed+"')");
stmt.executeUpdate("insert into local_roms values ('"+title+"','"+coverPath+"','"+romPath+"','"+titleID+"',"
+ "'"+productCode+"','"+region+"','"+lastPlayed+"','"+timePlayed+"')");
connection.commit();
stmt.close();
System.out.println("added \""+title+"\" to databsae");
LOGGER.info("added \""+title+"\" to ROM database");
}
void removeRom(String titleID) throws SQLException{
public void removeRom(String titleID) throws SQLException{
Statement stmt = connection.createStatement();
stmt.executeUpdate("delete from local_roms where titleID = '"+titleID+"'");
connection.commit();
stmt.close();
System.out.println("removed \""+titleID+"\" from databsae");
LOGGER.info("removed \""+titleID+"\" from ROM database");
}
//load all rom's on startup to the UI
//load all ROMs on startup to the mainWindowController
void loadAllRoms(){
System.out.println("loading all rom's on startup to mwc ...");
LOGGER.info("loading all rom's on startup into the mainWindowController ...");
try {
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM local_roms");
@ -152,13 +165,13 @@ public class dbController {
stmt.close();
rs.close();
}catch (Exception e){
e.printStackTrace();
LOGGER.error("error while loading all ROMs into the mainWindowController", e);
}
}
//load one single rom after manual adding one
void loadSingleRom(String titleID){
System.out.println("loading a single rom (ID: "+titleID+") to mwc ...");
//load one single ROM after manual adding into the mainWindowController
public void loadSingleRom(String titleID){
LOGGER.info("loading a single ROM (ID: "+titleID+") into the mainWindowController ...");
try {
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM local_roms where titleID = '"+titleID+"'");
@ -168,12 +181,12 @@ public class dbController {
stmt.close();
rs.close();
}catch (Exception e){
e.printStackTrace();
LOGGER.error("error while loading a single ROM into the mainWindowController", e);
}
}
//get all files with .rpx TODO add other formats
void loadRomDirectory(String directory){
public void loadRomDirectory(String directory){
File dir = new File(directory);
File appFile;
String[] extensions = new String[] { "rpx", "jsp" };
@ -181,15 +194,15 @@ public class dbController {
String coverPath;
if(System.getProperty("os.name").equals("Linux")){
pictureCache = mainWindowController.pictureCacheLinux;
pictureCache = mainWindowController.getPictureCacheLinux();
}else{
pictureCache = mainWindowController.pictureCacheWin;
pictureCache = mainWindowController.getPictureCacheWin();
}
try {
Statement stmt = connectionGames.createStatement();
System.out.println("Getting all .rpx files in " + dir.getCanonicalPath()+" including those in subdirectories \n");
Statement stmt = connectionGames.createStatement();
List<File> files = (List<File>) FileUtils.listFiles(dir, extensions, true);
LOGGER.info("Getting all .rpx files in " + dir.getCanonicalPath()+" including those in subdirectories");
for (File file : files) {
if(System.getProperty("os.name").equals("Linux")){
appFile = new File(file.getParent()+"/app.xml");
@ -201,16 +214,13 @@ public class dbController {
Document document = documentBuilder.parse(appFile);
String title_ID = document.getElementsByTagName("title_id").item(0).getTextContent();
title_ID = title_ID.substring(0, 8) + "-" + title_ID.substring(8, title_ID.length());
System.out.println("Name: "+file.getName()+"; Title ID: "+title_ID);
LOGGER.info("Name: "+file.getName()+"; Title ID: "+title_ID);
ResultSet rs = stmt.executeQuery("SELECT * FROM games WHERE TitleID = '"+title_ID+"';");
while (rs.next()) {
System.out.print(rs.getString(2));
if (checkEntry(rs.getString(2))) {
System.out.println(": game already in database");
LOGGER.info(rs.getString(2) + ": game already in database");
}else{
System.out.println(": add game");
System.out.println("adding cover to cache ...");
LOGGER.info("adding cover to cache ...");
BufferedImage originalImage = ImageIO.read(new URL(rs.getString(6)));//change path to where file is located
int type = originalImage.getType() == 0 ? BufferedImage.TYPE_INT_ARGB : originalImage.getType();
BufferedImage resizeImagePNG = resizeImage(originalImage, type, 400, 600);
@ -221,15 +231,14 @@ public class dbController {
ImageIO.write(resizeImagePNG, "png", new File(pictureCache+"\\"+rs.getString(3)+".png")); //change path where you want it saved
coverPath = pictureCache+"\\"+rs.getString(3)+".png";
}
LOGGER.info(rs.getString(2) + ": adding ROM");
addRom(rs.getString(2), coverPath, file.getCanonicalPath(), rs.getString(1), rs.getString(3), rs.getString(5),"","0");
}
}
System.out.println("");
}
} catch (IOException | SQLException | ParserConfigurationException | SAXException e) {
System.out.println("Ups something went wrong!");
e.printStackTrace();
LOGGER.error("error while loading ROMs from directory", e);
}
}
@ -244,8 +253,11 @@ public class dbController {
}
private void checkRemoveEntry() {
// TODO needs to be implemented!
System.out.println("check if entry removed not done yet!");
/**
* TODO needs to be implemented!
* don't show ROM on the UI, but keep all parameter in case it's showing up again ask if old data should be used
*/
//LOGGER.info("check if entry removed not done yet!");
}
private static BufferedImage resizeImage(BufferedImage originalImage, int type, int IMG_WIDTH, int IMG_HEIGHT) {
@ -257,18 +269,56 @@ public class dbController {
return resizedImage;
}
void setLastPlayed(String titleID){
/**
* getting info for a game with titleID
* @param titleID Title-ID of the Game
* @return title, coverPath, romPath, titleID (in this order)
*/
public String[] getGameInfo(String titleID){
String[] gameInfo = new String[4];
LOGGER.info("getting game info for titleID: "+titleID+" ...");
try {
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM local_roms where titleID = '"+titleID+"'");
while (rs.next()) {
gameInfo[0] = rs.getString(1);// title
gameInfo[1] = rs.getString(2);// coverPath
gameInfo[2] = rs.getString(3);// romPath
gameInfo[3] = rs.getString(4);// titleID
}
stmt.close();
rs.close();
}catch (Exception e){
LOGGER.error("error while getting game info", e);
}
return gameInfo;
}
public void setGameInfo(String title, String titleID, String romPath, String coverPath){
LOGGER.info("setting game info for titleID: "+titleID+" ...");
try {
Statement stmt = connection.createStatement();
stmt.executeUpdate("UPDATE local_roms SET title = '" + title + "', coverPath = '" + coverPath + "',"
+ " romPath = '" + romPath + "' WHERE titleID = '"+titleID+"';");
connection.commit();
stmt.close();
}catch (Exception e){
LOGGER.error("error while setting game info", e);
}
}
public void setLastPlayed(String titleID){
try{
Statement stmt = connection.createStatement();
stmt.executeUpdate("UPDATE local_roms SET lastPlayed=date('now') WHERE titleID = '"+titleID+"';");
connection.commit();
stmt.close();
}catch(SQLException e){
e.printStackTrace();
LOGGER.error("failed to set the last played", e);
}
}
String getLastPlayed(String titleID){
public String getLastPlayed(String titleID){
String lastPlayed = null;
try{
Statement stmt = connection.createStatement();
@ -277,23 +327,24 @@ public class dbController {
stmt.close();
rs.close();
}catch(SQLException e){
e.printStackTrace();
LOGGER.error("failed to get the last played", e);
}
return lastPlayed;
}
void setTimePlayed(String timePlayed, String titleID){
public void setTotalPlaytime(String timePlayed, String titleID){
try{
Statement stmt = connection.createStatement();
stmt.executeUpdate("UPDATE local_roms SET timePlayed='"+timePlayed+"' WHERE titleID = '"+titleID+"';");
connection.commit();
stmt.close();
}catch(SQLException e){
LOGGER.error("failed to set total play time", e);
e.printStackTrace();
}
}
String getTimePlayed(String titleID){
public String getTotalPlaytime(String titleID){
String timePlayed = null;
try{
Statement stmt = connection.createStatement();
@ -302,10 +353,10 @@ public class dbController {
stmt.close();
rs.close();
}catch(SQLException e){
e.printStackTrace();
LOGGER.error("failed to get total play time", e);
}
return timePlayed;
}
}

View File

@ -0,0 +1,47 @@
/**
* cemu_UI
*
* Copyright 2017 <@Seil0>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package com.cemu_UI.datatypes;
import com.jfoenix.controls.datamodels.treetable.RecursiveTreeObject;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class CourseTableDataType extends RecursiveTreeObject<CourseTableDataType> {
public final StringProperty title;
public final StringProperty id;
public final IntegerProperty time;
public final IntegerProperty stars;
/**
* Data type used in the TreeTableview for
*/
public CourseTableDataType(String title, String id, int time, int stars) {
this.title = new SimpleStringProperty(title);
this.id = new SimpleStringProperty(id);
this.time = new SimpleIntegerProperty(time);
this.stars = new SimpleIntegerProperty(stars);
}
}

View File

@ -0,0 +1,209 @@
/**
* cemu_UI
*
* Copyright 2017 <@Seil0>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package com.cemu_UI.datatypes;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class SmmdbApiDataType {
private final IntegerProperty courseTheme = new SimpleIntegerProperty();
private final IntegerProperty gameStyle = new SimpleIntegerProperty();
private final IntegerProperty difficulty = new SimpleIntegerProperty();
private final IntegerProperty lastmodified = new SimpleIntegerProperty();
private final IntegerProperty uploaded = new SimpleIntegerProperty();
private final IntegerProperty autoScroll = new SimpleIntegerProperty();
private final IntegerProperty stars = new SimpleIntegerProperty();
private final IntegerProperty time = new SimpleIntegerProperty();
private final StringProperty owner = new SimpleStringProperty();
private final StringProperty id = new SimpleStringProperty();
private final StringProperty nintendoid = new SimpleStringProperty();
private final StringProperty title = new SimpleStringProperty();
/**
* Data type used for the smmdbapi query
*/
public SmmdbApiDataType(final int courseTheme, final int gameStyle, final int difficulty, final int lastmodified,
final int uploaded, final int autoScroll, final int stars, final int time,
final String owner, final String id, final String nintendoid, final String title) {
this.id.set(id);
this.owner.set(owner);
this.courseTheme.set(courseTheme);
this.gameStyle.set(gameStyle);
this.difficulty.set(difficulty);
this.lastmodified.set(lastmodified);
this.uploaded.set(uploaded);
this.autoScroll.set(autoScroll);
this.stars.set(stars);
this.time.set(time);
this.nintendoid.set(nintendoid);
this.title.set(title);
}
public IntegerProperty courseThemeProperty(){
return courseTheme;
}
public IntegerProperty gameStyleProperty(){
return gameStyle;
}
public IntegerProperty difficultyProperty(){
return difficulty;
}
public IntegerProperty lastmodifiedProperty(){
return lastmodified;
}
public IntegerProperty uploadedProperty(){
return uploaded;
}
public IntegerProperty autoScrollProperty(){
return autoScroll;
}
public IntegerProperty starsProperty(){
return stars;
}
public IntegerProperty timeProperty(){
return time;
}
public StringProperty ownerProperty(){
return owner;
}
public StringProperty idProperty(){
return id;
}
public StringProperty nintendoidProperty(){
return nintendoid;
}
public StringProperty titleProperty(){
return title;
}
public int getCourseTheme() {
return courseThemeProperty().get();
}
public int getGameStyle() {
return gameStyleProperty().get();
}
public int getDifficulty() {
return difficultyProperty().get();
}
public int getLastmodified() {
return lastmodifiedProperty().get();
}
public int getUploaded() {
return uploadedProperty().get();
}
public int getAutoScroll() {
return autoScrollProperty().get();
}
public int getStars() {
return starsProperty().get();
}
public int getTime() {
return timeProperty().get();
}
public String getOwner() {
return ownerProperty().get();
}
public String getId() {
return idProperty().get();
}
public String getNintendoid() {
return nintendoidProperty().get();
}
public String getTitle() {
return titleProperty().get();
}
public final void setCourseTheme(int courseTheme) {
courseThemeProperty().set(courseTheme);
}
public final void setGameStyle(int gameStyle) {
gameStyleProperty().set(gameStyle);
}
public final void setDifficulty(int difficulty) {
difficultyProperty().set(difficulty);
}
public final void setLastmodified(int lastmodified) {
lastmodifiedProperty().set(lastmodified);
}
public final void setUploaded(int uploaded) {
uploadedProperty().set(uploaded);
}
public final void setAutoScroll(int autoScroll) {
autoScrollProperty().set(autoScroll);
}
public final void setStars(int stars) {
starsProperty().set(stars);
}
public final void setTime(int time) {
timeProperty().set(time);
}
public final void setOwner(String owner) {
ownerProperty().set(owner);
}
public final void setId(String id) {
idProperty().set(id);
}
public final void setNintendoid(String nintendoid) {
nintendoidProperty().set(nintendoid);
}
public final void setTitle(String title) {
titleProperty().set(title);
}
}

View File

@ -1,7 +1,25 @@
/**
* Datatype used for UI ROM elements
* cemu_UI
*
* Copyright 2017 <@Seil0>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package datatypes;
package com.cemu_UI.datatypes;
import com.jfoenix.controls.JFXButton;
@ -9,6 +27,7 @@ import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.control.Label;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
public class UIROMDataType {
@ -16,14 +35,20 @@ public class UIROMDataType {
private final SimpleObjectProperty<VBox> vBox = new SimpleObjectProperty<>();
private final SimpleObjectProperty<Label> label = new SimpleObjectProperty<>();
private final SimpleObjectProperty<JFXButton> button = new SimpleObjectProperty<>();
private final SimpleObjectProperty<ImageView> imageView = new SimpleObjectProperty<>();
private final StringProperty titleID = new SimpleStringProperty();
private final StringProperty romPath = new SimpleStringProperty();
public UIROMDataType (final VBox vBox, final Label label, final JFXButton button, final String titleID, final String romPath){
/**
* Data type used for UI ROM elements all uiROMElemts are of this data type
*/
public UIROMDataType (final VBox vBox, final Label label, final JFXButton button, final ImageView imageView, final String titleID, final String romPath){
this.vBox.set(vBox);
this.label.set(label);
this.button.set(button);
this.imageView.set(imageView);
this.titleID.set(titleID);
this.romPath.set(romPath);
}
public SimpleObjectProperty<VBox> vBoxProperty(){
@ -38,6 +63,10 @@ public class UIROMDataType {
return button;
}
public SimpleObjectProperty<ImageView> imageViewProperty(){
return imageView;
}
public StringProperty titleIDProperty(){
return titleID;
}
@ -59,6 +88,10 @@ public class UIROMDataType {
return buttonProperty().get();
}
public final ImageView getImageView() {
return imageViewProperty().get();
}
public final String getTitleID(){
return titleIDProperty().get();
}
@ -80,6 +113,10 @@ public class UIROMDataType {
buttonProperty().set(button);
}
public final void setImageView(ImageView imageView) {
imageViewProperty().set(imageView);
}
public final void setTitleID(String titleID){
titleIDProperty().set(titleID);
}

View File

@ -0,0 +1,86 @@
/**
* cemu_UI
*
* Copyright 2017 <@Seil0>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package com.cemu_UI.uiElements;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXDialog;
import com.jfoenix.controls.JFXDialogLayout;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
public class JFXInfoDialog {
private String headingText;
private String bodyText;
private String dialogBtnStyle;
private int dialogWidth;
private int dialogHeight;
private Pane pane;
/**
* Creates a new JFoenix Dialog to show some information
* @param headingText Heading Text, just the heading
* @param bodyText body Text, all other text belongs here
* @param dialogBtnStyle Style of the okay button
* @param dialogWidth dialog width
* @param dialogHeight dialog height
* @param pane pane to which the dialog belongs
*/
public JFXInfoDialog(String headingText, String bodyText, String dialogBtnStyle, int dialogWidth, int dialogHeight, Pane pane) {
this.headingText = headingText;
this.bodyText = bodyText;
this.dialogBtnStyle = dialogBtnStyle;
this.dialogWidth = dialogWidth;
this.dialogHeight = dialogHeight;
this.pane = pane;
}
public void show() {
JFXDialogLayout content = new JFXDialogLayout();
content.setHeading(new Text(headingText));
content.setBody(new Text(bodyText));
content.setPrefSize(dialogWidth, dialogHeight);
StackPane stackPane = new StackPane();
stackPane.autosize();
JFXDialog dialog = new JFXDialog(stackPane, content, JFXDialog.DialogTransition.LEFT, true);
JFXButton button = new JFXButton("Okay");
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
dialog.close();
}
});
button.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED);
button.setPrefHeight(32);
button.setStyle(dialogBtnStyle);
content.setActions(button);
pane.getChildren().add(stackPane);
AnchorPane.setTopAnchor(stackPane, (pane.getHeight() - content.getPrefHeight()) / 2);
AnchorPane.setLeftAnchor(stackPane, (pane.getWidth() - content.getPrefWidth()) / 2);
dialog.show();
}
}

View File

@ -0,0 +1,105 @@
/**
* cemu_UI
*
* Copyright 2017 <@Seil0>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package com.cemu_UI.uiElements;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXDialog;
import com.jfoenix.controls.JFXDialogLayout;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
public class JFXOkayCancelDialog {
private String headingText;
private String bodyText;
private String dialogBtnStyle;
private int dialogWidth;
private int dialogHeight;
private EventHandler<ActionEvent> okayAction;
private EventHandler<ActionEvent> cancelAction;
private Pane pane;
/**
* Creates a new JFoenix Dialog to show some information with okay and cancel option
* @param headingText Heading Text, just the heading
* @param bodyText body Text, all other text belongs here
* @param dialogBtnStyle Style of the okay button
* @param dialogWidth dialog width
* @param dialogHeight dialog height
* @param okayAction action which is performed if the okay button is clicked
* @param cancelAction action which is performed if the cancel button is clicked
* @param pane pane to which the dialog belongs
*/
public JFXOkayCancelDialog(String headingText, String bodyText, String dialogBtnStyle, int dialogWidth,
int dialogHeight, EventHandler<ActionEvent> okayAction, EventHandler<ActionEvent> cancelAction, Pane pane) {
this.headingText = headingText;
this.bodyText = bodyText;
this.dialogBtnStyle = dialogBtnStyle;
this.dialogWidth = dialogWidth;
this.dialogHeight = dialogHeight;
this.okayAction = okayAction;
this.cancelAction = cancelAction;
this.pane = pane;
}
public void show() {
JFXDialogLayout content= new JFXDialogLayout();
content.setHeading(new Text(headingText));
content.setBody(new Text(bodyText));
StackPane stackPane = new StackPane();
stackPane.autosize();
JFXDialog dialog = new JFXDialog(stackPane, content, JFXDialog.DialogTransition.LEFT, true);
JFXButton okayBtn = new JFXButton("Okay");
okayBtn.addEventHandler(ActionEvent.ACTION, okayAction);
okayBtn.addEventHandler(ActionEvent.ACTION, (e)-> {
dialog.close();
});
okayBtn.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED);
okayBtn.setPrefHeight(32);
okayBtn.setStyle(dialogBtnStyle);
JFXButton cancelBtn = new JFXButton("Cancel");
cancelBtn.addEventHandler(ActionEvent.ACTION, cancelAction);
cancelBtn.addEventHandler(ActionEvent.ACTION, (e)-> {
dialog.close();
});
cancelBtn.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED);
cancelBtn.setPrefHeight(32);
cancelBtn.setStyle(dialogBtnStyle);
Label placeholder = new Label();
placeholder.setPrefSize(15, 10);
content.setActions(cancelBtn, placeholder, okayBtn);
content.setPrefSize(dialogWidth, dialogHeight);
pane.getChildren().add(stackPane);
AnchorPane.setTopAnchor(stackPane, (pane.getHeight()-content.getPrefHeight())/2);
AnchorPane.setLeftAnchor(stackPane, (pane.getWidth()-content.getPrefWidth())/2);
dialog.show();
}
}

View File

@ -1,4 +1,25 @@
package cloudControllerInstances;
/**
* cemu_UI
*
* Copyright 2017 <@Seil0>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package com.cemu_UI.vendorCloudController;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@ -11,6 +32,8 @@ import java.util.Collections;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
@ -33,14 +56,15 @@ import com.google.api.services.drive.model.FileList;
public class GoogleDriveController {
Drive service;
private String cemuDirectory;
private String saveDirectory;
private String folderID;
private ArrayList<java.io.File> localSavegames = new ArrayList<>();
private ArrayList<File> cloudSavegames = new ArrayList<>();
private ArrayList<String> localSavegamesName = new ArrayList<>();
private ArrayList<String> cloudSavegamesName = new ArrayList<>();
private static final Logger LOGGER = LogManager.getLogger(GoogleDriveController.class.getName());
private final String APPLICATION_NAME ="cemu_Ui Drive API Controller";
private final String APPLICATION_NAME ="cemu_Ui Drive API Controller"; //TODO add Google
//Directory to store user credentials for this application
private final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"), ".credentials/cemu_UI_credential");
@ -65,7 +89,7 @@ public class GoogleDriveController {
DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
folderID = "";
} catch (Throwable t) {
t.printStackTrace();
LOGGER.error("error", t);
System.exit(1);
}
}
@ -77,17 +101,17 @@ public class GoogleDriveController {
*/
public Credential authorize() throws IOException {
// Load client secrets.
InputStream in = getClass().getClassLoader().getResourceAsStream("resources/client_secret.json");
InputStream in = getClass().getClassLoader().getResourceAsStream("client_secret.json");
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
//FIXME Linux fails to open a new browser window, application crashes, maybe a kde only bug
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(DATA_STORE_FACTORY)
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(DATA_STORE_FACTORY)
.setAccessType("offline")
.build();
Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
System.out.println("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
LOGGER.info("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
return credential;
}
@ -105,8 +129,18 @@ public class GoogleDriveController {
public void main(String cemuDirectory) throws IOException {
java.io.File dir = new java.io.File(cemuDirectory + "/mlc01/usr/save");
service = getDriveService();
this.cemuDirectory = cemuDirectory;
// cemu >= 1.11 uses /mlc01/usr/save/... instead of /mlc01/emulatorSave/...
if (dir.exists()) {
LOGGER.info("using new save path");
saveDirectory = cemuDirectory + "/mlc01/usr/save";
} else {
LOGGER.info("using old save path");
saveDirectory = cemuDirectory + "/mlc01/emulatorSave";
}
}
public void sync(String cemuDirectory) throws IOException {
@ -129,19 +163,19 @@ public class GoogleDriveController {
FileInputStream fis = new FileInputStream(localSavegames.get(localSavegamesNumber));
if (cloudSavegames.get(i).getMd5Checksum().equals(org.apache.commons.codec.digest.DigestUtils.md5Hex(fis))) {
System.out.println("both files are the same, nothing to do");
LOGGER.info("both files are the same, nothing to do");
} else {
if (localModified >= cloudModified) {
System.out.print("local is newer, ");
LOGGER.info("local is newer");
updateFile(cloudSavegames.get(i), localSavegames.get(localSavegamesNumber));
} else {
System.out.print("cloud is newer, ");
LOGGER.info("cloud is newer");
downloadFile(cloudSavegames.get(i));
}
}
} else {
System.out.print("file doesn't exist locally, ");
LOGGER.info("file doesn't exist locally");
downloadFile(cloudSavegames.get(i));
}
}
@ -149,7 +183,7 @@ public class GoogleDriveController {
// upload file to cloud which don't exist in the cloud
for (int j = 0; j < localSavegames.size(); j++) {
if (!cloudSavegamesName.contains(localSavegamesName.get(j))) {
System.out.print("file doesn't exist in the cloud, ");
LOGGER.info("file doesn't exist in the cloud");
uploadFile(localSavegames.get(j));
}
}
@ -157,13 +191,13 @@ public class GoogleDriveController {
//create a folder in google drive
public void creatFolder() throws IOException {
System.out.println("creating new folder");
LOGGER.info("creating new folder");
File fileMetadata = new File();
fileMetadata.setName("cemu_savegames");
fileMetadata.setMimeType("application/vnd.google-apps.folder");
File file = service.files().create(fileMetadata).setFields("id").execute();
System.out.println("Folder ID: " + file.getId());
LOGGER.info("Folder ID: " + file.getId());
folderID = file.getId();
}
@ -185,11 +219,11 @@ public class GoogleDriveController {
//reading all local savegames
private void getLocalSavegames() throws IOException {
java.io.File dir = new java.io.File(cemuDirectory+"/mlc01/emulatorSave");
java.io.File dir = new java.io.File(saveDirectory);
String[] extensions = new String[] { "dat","sav","bin" };
localSavegames.removeAll(localSavegames);
localSavegamesName.removeAll(localSavegamesName);
System.out.println("Getting all dat,sav,bin files in " + dir.getCanonicalPath()+" including those in subdirectories");
LOGGER.info("Getting all dat,sav,bin files in " + dir.getCanonicalPath()+" including those in subdirectories");
List<java.io.File> files = (List<java.io.File>) FileUtils.listFiles(dir, extensions, true);
for (java.io.File file : files) {
localSavegamesName.add(file.getParentFile().getName()+"_"+file.getName());
@ -199,7 +233,7 @@ public class GoogleDriveController {
//reading all cloud savegames
private void getCloudSavegames() throws IOException {
System.out.println("getting all cloud savegames");
LOGGER.info("getting all cloud savegames");
cloudSavegames.removeAll(cloudSavegames);
cloudSavegamesName.removeAll(cloudSavegamesName);
Files.List request = service.files().list().setQ("'"+folderID+"' in parents").setFields("nextPageToken, files(id, name, size, modifiedTime, createdTime, md5Checksum)");
@ -216,46 +250,45 @@ public class GoogleDriveController {
FileList files = request.execute();
try {
System.out.println("FolderID: " + files.getFiles().get(0).getId());
LOGGER.info("FolderID: " + files.getFiles().get(0).getId());
setFolderID(files.getFiles().get(0).getId());
} catch (Exception e) {
System.out.println("Oops, something went wrong! It seems that you have more than one folder called 'cemu_savegames'!");
e.printStackTrace();
LOGGER.error("Oops, something went wrong! It seems that you have more than one folder called 'cemu_savegames'!", e);
}
}
//upload a file to the cloud from the local savegames folder
public void uploadFile(java.io.File uploadFile) throws IOException{
System.out.println("uploading " + uploadFile.getName() + "...");
LOGGER.info("uploading " + uploadFile.getName() + " ...");
File fileMetadata = new File();
fileMetadata.setName(uploadFile.getParentFile().getName()+"_"+uploadFile.getName());
fileMetadata.setParents(Collections.singletonList(folderID));
fileMetadata.setModifiedTime(new DateTime(uploadFile.lastModified()));
FileContent mediaContent = new FileContent("", uploadFile);
File file = service.files().create(fileMetadata, mediaContent).setFields("id, parents").execute();
System.out.println("upload successfull, File ID: " + file.getId());
LOGGER.info("upload successfull, File ID: " + file.getId());
}
//download a file from the cloud to the local savegames folder
private void downloadFile(File downloadFile) throws IOException{
System.out.print("downloading "+downloadFile.getName()+"... ");
java.io.File directory = new java.io.File(cemuDirectory+"/mlc01/emulatorSave/"+ downloadFile.getName().substring(0,8));
String file = downloadFile.getName().substring(9,downloadFile.getName().length());
if(!directory.exists()) {
System.out.print("dir dosent exist... ");
directory.mkdir();
}
private void downloadFile(File downloadFile) throws IOException{
LOGGER.info("downloading "+downloadFile.getName()+" ...");
java.io.File directory = new java.io.File(saveDirectory + "/" + downloadFile.getName().substring(0,8));
String file = downloadFile.getName().substring(9,downloadFile.getName().length());
if(!directory.exists()) {
LOGGER.info("dir dosent exist");
directory.mkdir();
}
OutputStream outputStream = new FileOutputStream(directory +"/"+ file);
service.files().get(downloadFile.getId()).executeMediaAndDownloadTo(outputStream);
outputStream.close();
System.out.println("done");
OutputStream outputStream = new FileOutputStream(directory +"/"+ file);
service.files().get(downloadFile.getId()).executeMediaAndDownloadTo(outputStream);
outputStream.close();
LOGGER.info("download successfull, File ID: " + file); //TODO add FileID
}
//update a file in the cloud, by deleting the old one and uploading an new with the same id
private void updateFile(File oldFile, java.io.File newFile) throws IOException {
System.out.println("updating " +oldFile.getName()+"... ");
LOGGER.info("updating " +oldFile.getName()+" ...");
service.files().delete(oldFile.getId()).execute(); //deleting old file
//uploading new file
@ -266,21 +299,19 @@ public class GoogleDriveController {
FileContent mediaContent = new FileContent("", newFile);
File file = service.files().create(fileMetadata, mediaContent).setFields("id, parents").execute();
System.out.println("File ID: " + file.getId());
LOGGER.info("update successfull, File ID: " + file.getId());
}
public void uploadAllFiles() {
try {
getLocalSavegames();
System.out.println("uploading " + localSavegames.size() + " files...");
LOGGER.info("uploading " + localSavegames.size() + " files ...");
for (int i = 0; i < localSavegames.size(); i++) {
uploadFile(localSavegames.get(i));
}
System.out.println("finished uploading all files!");
LOGGER.info("finished uploading all files");
} catch (IOException e) {
//Auto-generated catch block
System.out.println("Oops, there went something wrong! Error during uploading all files.");
e.printStackTrace();
LOGGER.error("error while uploading all files", e);
}
}

View File

@ -17,7 +17,7 @@
*/
.tree-table-view {
-fx-tree-table-color: rgba(0, 168, 204, 0.2);
-fx-tree-table-color: rgba(0, 168, 204, 0.2);
-fx-tree-table-rippler-color: rgba(0, 168, 204, 0.4);
}
@ -32,7 +32,7 @@
}
.tree-table-view .jfx-rippler {
-jfx-rippler-fill: -fx-tree-table-rippler-color;
-jfx-rippler-fill: -fx-tree-table-rippler-color;
}
.tree-table-view .column-header,

View File

@ -0,0 +1,127 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXColorPicker?>
<?import com.jfoenix.controls.JFXHamburger?>
<?import com.jfoenix.controls.JFXTextField?>
<?import com.jfoenix.controls.JFXToggleButton?>
<?import com.jfoenix.controls.JFXTreeTableView?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.TextFlow?>
<AnchorPane fx:id="mainAnchorPane" prefHeight="600.0" prefWidth="904.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.cemu_UI.application.MainWindowController">
<children>
<ScrollPane fx:id="mainScrollPane" fitToWidth="true" layoutY="38.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="38.0">
<content>
<AnchorPane fx:id="gamesAnchorPane">
<padding>
<Insets bottom="17.0" />
</padding></AnchorPane>
</content>
</ScrollPane>
<HBox fx:id="topHBox" prefHeight="38.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<JFXHamburger fx:id="menuHam" prefHeight="38.0" prefWidth="38.0" stylesheets="@../css/MainWindows.css" />
</children>
</HBox>
<VBox fx:id="sideMenuVBox" layoutY="32.0" prefHeight="568.0" prefWidth="175.0" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="38.0">
<children>
<JFXButton fx:id="aboutBtn" alignment="TOP_LEFT" maxHeight="38.0" maxWidth="190.0" onAction="#aboutBtnAction" prefHeight="38.0" prefWidth="190.0" text="About" textAlignment="LEFT">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<JFXButton fx:id="settingsBtn" alignment="TOP_LEFT" maxHeight="38.0" maxWidth="213.0" onAction="#settingsBtnAction" prefHeight="38.0" prefWidth="213.0" text="Settings" textAlignment="LEFT">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<JFXButton fx:id="addBtn" alignment="TOP_LEFT" maxHeight="38.0" maxWidth="193.0" onAction="#addBtnAction" prefHeight="38.0" prefWidth="193.0" text="Add new Game" textAlignment="LEFT">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<JFXButton fx:id="reloadRomsBtn" alignment="TOP_LEFT" maxHeight="38.0" maxWidth="199.0" onAction="#reloadRomsBtnAction" prefHeight="38.0" prefWidth="199.0" text="reload roms" textAlignment="LEFT">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<JFXButton fx:id="smmdbBtn" alignment="TOP_LEFT" onAction="#smmdbBtnAction" prefHeight="38.0" prefWidth="216.0" text="smmdb">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
</children>
</VBox>
<ScrollPane fx:id="settingsScrollPane" style="-fx-background: white;" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="175.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="38.0">
<content>
<!-- space between settings sections 35px, between sections elements (label + element) 20px, between label and element 3px(or more) -->
<AnchorPane fx:id="settingsAnchorPane" prefHeight="562.0" prefWidth="511.0" style="-fx-background-color: white;">
<children>
<Label fx:id="cemuDirectoryLbl" layoutX="10.0" layoutY="39.0" text="Cemu Directory" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="39.0" />
<JFXTextField fx:id="cemuTextField" layoutX="10.0" layoutY="59.0" maxWidth="305.0" minWidth="305.0" onAction="#cemuTextFieldAction" prefHeight="32.0" prefWidth="305.0" promptText="cemu directory" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="59.0" />
<JFXTextField fx:id="romTextField" layoutX="10.0" layoutY="131.0" maxWidth="305.0" minWidth="305.0" onAction="#romTextFieldAction" prefHeight="32.0" prefWidth="305.0" promptText="rom directory" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="131.0" />
<JFXButton fx:id="romTFBtn" layoutX="329.0" layoutY="131.0" onAction="#romTFBtnAction" prefHeight="32.0" text="choose directory" AnchorPane.leftAnchor="329.0" AnchorPane.topAnchor="131.0" />
<JFXButton fx:id="cemuTFBtn" layoutX="329.0" layoutY="59.0" onAction="#cemuTFBtnAction" prefHeight="32.0" text="choose directory" AnchorPane.leftAnchor="329.0" AnchorPane.topAnchor="59.0" />
<JFXColorPicker fx:id="colorPicker" layoutX="12.0" layoutY="207.0" onAction="#colorPickerAction" AnchorPane.leftAnchor="12.0" AnchorPane.topAnchor="207.0" />
<JFXToggleButton fx:id="fullscreenToggleBtn" layoutX="16.0" layoutY="488.0" onAction="#fullscreenToggleBtnAction" text="start game in fullscreen" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="488.0" />
<Label fx:id="romDirectoryLbl" layoutX="10.0" layoutY="111.0" text="Rom Directory" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="111.0" />
<Label fx:id="mainColorLbl" layoutX="10.0" layoutY="183.0" text="main Color" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="183.0" />
<Label fx:id="cemuSettingsLbl" layoutX="16.0" layoutY="450.0" text="Cemu Settings" AnchorPane.leftAnchor="16.0" AnchorPane.topAnchor="465.0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Label>
<Label fx:id="cemu_UISettingsLbl" layoutX="22.0" layoutY="14.0" text="cemu_UI Settings" AnchorPane.leftAnchor="18.0" AnchorPane.topAnchor="14.0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Label>
<JFXToggleButton fx:id="cloudSyncToggleBtn" layoutX="10.0" layoutY="247.0" onAction="#cloudSyncToggleBtnAction" text="cloud savegames (Google Drive)" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="247.0" />
<Label fx:id="updateLbl" layoutX="10.0" layoutY="315.0" text="Updates" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="315.0" />
<JFXButton fx:id="updateBtn" layoutX="14.0" layoutY="335.0" onAction="#updateBtnAction" prefHeight="32.0" text="check now!" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="335.0" />
<JFXToggleButton fx:id="autoUpdateToggleBtn" layoutX="10.0" layoutY="372.0" onAction="#autoUpdateToggleBtnAction" text="check for updates on startup" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="372.0" />
<ChoiceBox fx:id="branchChoisBox" layoutX="270.0" layoutY="339.0" prefWidth="150.0" AnchorPane.leftAnchor="270.0" AnchorPane.topAnchor="339.0" />
<Label fx:id="branchLbl" layoutX="204.0" layoutY="337.0" prefHeight="32.0" text="Branch" AnchorPane.leftAnchor="204.0" AnchorPane.topAnchor="335.0" />
</children>
</AnchorPane>
</content>
</ScrollPane>
<AnchorPane fx:id="smmdbAnchorPane" style="-fx-background-color: white;" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="175.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="38.0">
<children>
<JFXTreeTableView fx:id="courseTreeTable" layoutX="14.0" layoutY="14.0" prefHeight="537.0" prefWidth="405.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="14.0" />
<ImageView fx:id="smmdbImageView" fitHeight="150.0" fitWidth="267.0" layoutX="436.0" layoutY="14.0" pickOnBounds="true" preserveRatio="true" AnchorPane.leftAnchor="436.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0" />
<ScrollPane fx:id="smmdbScrollPane" layoutX="436.0" layoutY="181.0" prefHeight="290.0" prefWidth="267.0" AnchorPane.bottomAnchor="91.0" AnchorPane.leftAnchor="436.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="181.0">
<content>
<TextFlow fx:id="smmdbTextFlow" maxWidth="265.0" prefWidth="265.0" />
</content>
</ScrollPane>
<JFXButton fx:id="smmdbDownloadBtn" buttonType="RAISED" layoutX="436.0" layoutY="479.0" onAction="#smmdbDownloadBtnAction" prefHeight="38.0" prefWidth="267.0" text="download" AnchorPane.bottomAnchor="45.0" AnchorPane.leftAnchor="436.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="479.0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<Label fx:id="helpLabel" layoutX="436.0" layoutY="538.0" prefHeight="17.0" prefWidth="267.0" text="please help me improving this! click me!">
<font>
<Font size="14.0" />
</font>
</Label>
</children></AnchorPane>
<JFXButton fx:id="playBtn" buttonType="RAISED" layoutX="396.0" maxHeight="28.0" minWidth="100.0" onAction="#playBtnAction" ripplerFill="#00aacc" text="play" textAlignment="CENTER" visible="false" AnchorPane.bottomAnchor="12.0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</JFXButton>
<JFXButton fx:id="totalPlaytimeBtn" buttonType="RAISED" layoutX="275.5" maxHeight="32.0" minWidth="100.0" onAction="#totalPlaytimeBtnAction" prefHeight="32.0" style="-fx-background-color: #ffffff; -fx-button-type: RAISED; -fx-text-fill: BLACK;" text="0 h 0 min" visible="false" AnchorPane.bottomAnchor="10.0">
</JFXButton>
<JFXButton fx:id="lastTimePlayedBtn" buttonType="RAISED" layoutX="516.5" maxHeight="32.0" minWidth="100.0" onAction="#lastTimePlayedBtnAction" prefHeight="32.0" style="-fx-background-color: #ffffff; -fx-button-type: RAISED; -fx-text-fill: BLACK;" text="Last played, never" visible="false" AnchorPane.bottomAnchor="10.0" />
</children>
</AnchorPane>

View File

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

Before

Width:  |  Height:  |  Size: 222 B

After

Width:  |  Height:  |  Size: 222 B

View File

Before

Width:  |  Height:  |  Size: 233 B

After

Width:  |  Height:  |  Size: 233 B

View File

Before

Width:  |  Height:  |  Size: 235 B

After

Width:  |  Height:  |  Size: 235 B

View File

Before

Width:  |  Height:  |  Size: 245 B

After

Width:  |  Height:  |  Size: 245 B

View File

Before

Width:  |  Height:  |  Size: 114 B

After

Width:  |  Height:  |  Size: 114 B

View File

Before

Width:  |  Height:  |  Size: 116 B

After

Width:  |  Height:  |  Size: 116 B

View File

Before

Width:  |  Height:  |  Size: 222 B

After

Width:  |  Height:  |  Size: 222 B

View File

Before

Width:  |  Height:  |  Size: 232 B

After

Width:  |  Height:  |  Size: 232 B

View File

Before

Width:  |  Height:  |  Size: 322 B

After

Width:  |  Height:  |  Size: 322 B

View File

Before

Width:  |  Height:  |  Size: 326 B

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More