This commit is contained in:
huangyuhui
2017-08-01 18:10:36 +08:00
parent 6dc2b36d14
commit 1410b3b5b1
236 changed files with 18466 additions and 0 deletions

11
.idea/codeStyleSettings.xml generated Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectCodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
<value>
<option name="LINE_SEPARATOR" value="&#10;" />
</value>
</option>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</component>
</project>

17
.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel>
<module name="HMCL_main" target="1.8" />
<module name="hmcl_main" target="1.8" />
<module name="hmcl_test" target="1.8" />
<module name="HMCL_test" target="1.8" />
<module name="HMCLCore_main" target="1.8" />
<module name="HMCLCore_test" target="1.8" />
<module name="HMCLKotlin_main" target="1.8" />
<module name="HMCLKotlin_test" target="1.8" />
<module name="tornadofx_main" target="1.8" />
<module name="tornadofx_test" target="1.8" />
</bytecodeTargetLevel>
</component>
</project>

View File

@@ -0,0 +1,17 @@
#parse("HMCL.java")
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "") package ${PACKAGE_NAME};#end
import javafx.application.Application;
import javafx.stage.Stage;
public class ${NAME} extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
}
}

12
.idea/fileTemplates/Singleton.java generated Normal file
View File

@@ -0,0 +1,12 @@
#parse("HMCL.java")
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
public class ${NAME}{
private static ${NAME} ourInstance = new ${NAME}();
public static ${NAME} getInstance() {
return ourInstance;
}
private ${NAME}() {
}
}

18
.idea/fileTemplates/includes/HMCL.java generated Normal file
View File

@@ -0,0 +1,18 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/

View File

@@ -0,0 +1,4 @@
#parse("HMCL.java")
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
public @interface ${NAME} {
}

4
.idea/fileTemplates/internal/Class.java generated Normal file
View File

@@ -0,0 +1,4 @@
#parse("HMCL.java")
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
public class ${NAME} {
}

4
.idea/fileTemplates/internal/Enum.java generated Normal file
View File

@@ -0,0 +1,4 @@
#parse("HMCL.java")
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
public enum ${NAME} {
}

View File

@@ -0,0 +1,4 @@
#parse("HMCL.java")
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
public interface ${NAME} {
}

View File

@@ -0,0 +1,5 @@
#parse("HMCL.java")
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}
#end
class ${NAME} {
}

View File

@@ -0,0 +1,5 @@
#parse("HMCL.java")
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}
#end
enum class ${NAME} {
}

View File

@@ -0,0 +1,3 @@
#parse("HMCL.java")
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}
#end

View File

@@ -0,0 +1,5 @@
#parse("HMCL.java")
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME}
#end
interface ${NAME} {
}

53
.idea/gradle.xml generated Normal file
View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="1.8" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/HMCL" />
<option value="$PROJECT_DIR$/HMCLCore" />
</set>
</option>
<option name="useAutoImport" value="true" />
</GradleProjectSettings>
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$/HMCL" />
<option name="gradleJvm" value="1.8" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$/HMCL" />
</set>
</option>
<option name="useAutoImport" value="true" />
</GradleProjectSettings>
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$/JFoenix" />
<option name="gradleJvm" value="1.8" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$/JFoenix" />
</set>
</option>
<option name="useAutoImport" value="true" />
</GradleProjectSettings>
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$/TornadoFx" />
<option name="gradleJvm" value="1.8" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$/TornadoFx" />
</set>
</option>
<option name="useAutoImport" value="true" />
</GradleProjectSettings>
</option>
</component>
</project>

6
.idea/kotlinc.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Kotlin2JvmCompilerArguments">
<option name="jvmTarget" value="1.8" />
</component>
</project>

View File

@@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="Gradle: com.google.code.gson:gson:2.8.1">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.8.1/2a8e0aa38a2e21cb39e2f5a7d6704cbdc941da0/gson-2.8.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.8.1/c10732c97eccba635e20596a02c3824fef0605bf/gson-2.8.1-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="Gradle: junit:junit:4.12">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/2973d150c0dc1fefe998f834810d68f278ea58ec/junit-4.12.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/a6c32b40bf3d76eca54e3c601e5d1470c86fcdfa/junit-4.12-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="Gradle: org.hamcrest:hamcrest-core:1.3">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/42a25dc3219429f0e5d060061f71acb49bf010a0/hamcrest-core-1.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/1dc37250fbc78e23a65a67fbbaf71d2e9cbc3c0b/hamcrest-core-1.3-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="Gradle: org.jetbrains:annotations:13.0">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/5991ca87ef1fb5544943d9abc5a9a37583fabe03/annotations-13.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.1.3-2">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.1.3-2/9b44c139a4ec57031e0c84ba0e49ba16df6d801c/kotlin-stdlib-1.1.3-2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.1.3-2/fd533d031dcdf086dfc75cfb9003c4349ed829aa/kotlin-stdlib-1.1.3-2-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.3-2">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre7/1.1.3-2/3fe54c7558c903868351ac79b792d152bca958f2/kotlin-stdlib-jre7-1.1.3-2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre7/1.1.3-2/39fdd46daad46e2d19fbcad7e639dd940df9d74f/kotlin-stdlib-jre7-1.1.3-2-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre8:1.1.3-2">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre8/1.1.3-2/c8da1d60b49926296fa95f2ccdb218b7912f9c17/kotlin-stdlib-jre8-1.1.3-2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre8/1.1.3-2/989f32e8eb68a3e1ee346410f95729b78cbfb800/kotlin-stdlib-jre8-1.1.3-2-sources.jar!/" />
</SOURCES>
</library>
</component>

6
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

16
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/modules/HMCL/HMCL.iml" filepath="$PROJECT_DIR$/.idea/modules/HMCL/HMCL.iml" group="HMCL" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/HMCLCore/HMCLCore.iml" filepath="$PROJECT_DIR$/.idea/modules/HMCLCore/HMCLCore.iml" group="HMCLCore" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/HMCLCore/HMCLCore_main.iml" filepath="$PROJECT_DIR$/.idea/modules/HMCLCore/HMCLCore_main.iml" group="HMCLCore" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/HMCLCore/HMCLCore_test.iml" filepath="$PROJECT_DIR$/.idea/modules/HMCLCore/HMCLCore_test.iml" group="HMCLCore" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/HMCLKotlin.iml" filepath="$PROJECT_DIR$/.idea/modules/HMCLKotlin.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/HMCLKotlin_main.iml" filepath="$PROJECT_DIR$/.idea/modules/HMCLKotlin_main.iml" group="HMCLKotlin" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/HMCLKotlin_test.iml" filepath="$PROJECT_DIR$/.idea/modules/HMCLKotlin_test.iml" group="HMCLKotlin" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/HMCL/HMCL_main.iml" filepath="$PROJECT_DIR$/.idea/modules/HMCL/HMCL_main.iml" group="HMCL" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/HMCL/HMCL_test.iml" filepath="$PROJECT_DIR$/.idea/modules/HMCL/HMCL_test.iml" group="HMCL" />
</modules>
</component>
</project>

13
.idea/modules/HMCL/HMCL.iml generated Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":HMCL" external.linked.project.path="$MODULE_DIR$/../../../HMCL" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="org.jackhuang" external.system.module.version="3.0" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$/../../../HMCL">
<excludeFolder url="file://$MODULE_DIR$/../../../HMCL/.gradle" />
<excludeFolder url="file://$MODULE_DIR$/../../../HMCL/build" />
<excludeFolder url="file://$MODULE_DIR$/../../../HMCL/out" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

54
.idea/modules/HMCL/HMCL_main.iml generated Normal file
View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":HMCL:main" external.linked.project.path="$MODULE_DIR$/../../../HMCL" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="org.jackhuang" external.system.module.type="sourceSet" external.system.module.version="3.0" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="JVM 1.8" useProjectSettings="false">
<compilerSettings />
<compilerArguments>
<option name="destination" value="$MODULE_DIR$/../../../HMCL/build/kotlin-classes/main" />
<option name="classpath" value="$MODULE_DIR$/../../../lib/JFoenix.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre8/1.1.3-2/c8da1d60b49926296fa95f2ccdb218b7912f9c17/kotlin-stdlib-jre8-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.8.1/2a8e0aa38a2e21cb39e2f5a7d6704cbdc941da0/gson-2.8.1.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre7/1.1.3-2/3fe54c7558c903868351ac79b792d152bca958f2/kotlin-stdlib-jre7-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.1.3-2/9b44c139a4ec57031e0c84ba0e49ba16df6d801c/kotlin-stdlib-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar" />
<option name="noStdlib" value="true" />
<option name="noReflect" value="true" />
<option name="moduleName" value="HMCL_main" />
<option name="jvmTarget" value="1.8" />
<option name="addCompilerBuiltIns" value="true" />
<option name="loadBuiltInsFromDependencies" value="true" />
<option name="languageVersion" value="1.1" />
<option name="apiVersion" value="1.1" />
<option name="pluginOptions">
<array />
</option>
<option name="pluginClasspaths">
<array />
</option>
</compilerArguments>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/../../../HMCL/out/production/classes" />
<exclude-output />
<content url="file://$MODULE_DIR$/../../../HMCL/src/main">
<sourceFolder url="file://$MODULE_DIR$/../../../HMCL/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../../HMCL/src/main/kotlin" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../../HMCL/src/main/resources" type="java-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../../lib/JFoenix.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module" module-name="HMCLCore_main" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre8:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: com.google.code.gson:gson:2.8.1" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains:annotations:13.0" level="project" />
</component>
</module>

58
.idea/modules/HMCL/HMCL_test.iml generated Normal file
View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":HMCL:test" external.linked.project.path="$MODULE_DIR$/../../../HMCL" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="org.jackhuang" external.system.module.type="sourceSet" external.system.module.version="3.0" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="JVM 1.8" useProjectSettings="false">
<compilerSettings />
<compilerArguments>
<option name="destination" value="$MODULE_DIR$/../../../HMCL/build/kotlin-classes/test" />
<option name="classpath" value="$MODULE_DIR$/../../../lib/JFoenix.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre8/1.1.3-2/c8da1d60b49926296fa95f2ccdb218b7912f9c17/kotlin-stdlib-jre8-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.8.1/2a8e0aa38a2e21cb39e2f5a7d6704cbdc941da0/gson-2.8.1.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/2973d150c0dc1fefe998f834810d68f278ea58ec/junit-4.12.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre7/1.1.3-2/3fe54c7558c903868351ac79b792d152bca958f2/kotlin-stdlib-jre7-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.1.3-2/9b44c139a4ec57031e0c84ba0e49ba16df6d801c/kotlin-stdlib-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/42a25dc3219429f0e5d060061f71acb49bf010a0/hamcrest-core-1.3.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar" />
<option name="noStdlib" value="true" />
<option name="noReflect" value="true" />
<option name="moduleName" value="HMCL_main" />
<option name="jvmTarget" value="1.8" />
<option name="addCompilerBuiltIns" value="true" />
<option name="loadBuiltInsFromDependencies" value="true" />
<option name="languageVersion" value="1.1" />
<option name="apiVersion" value="1.1" />
<option name="pluginOptions">
<array />
</option>
<option name="pluginClasspaths">
<array />
</option>
</compilerArguments>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output-test url="file://$MODULE_DIR$/../../../HMCL/out/test/classes" />
<exclude-output />
<content url="file://$MODULE_DIR$/../../../HMCL/src/test">
<sourceFolder url="file://$MODULE_DIR$/../../../HMCL/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../HMCL/src/test/kotlin" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../HMCL/src/test/resources" type="java-test-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="HMCL_main" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../../lib/JFoenix.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module" module-name="HMCLCore_main" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre8:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: com.google.code.gson:gson:2.8.1" level="project" />
<orderEntry type="library" name="Gradle: junit:junit:4.12" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains:annotations:13.0" level="project" />
</component>
<component name="TestModuleProperties" production-module="HMCL_main" />
</module>

13
.idea/modules/HMCLCore/HMCLCore.iml generated Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":HMCLCore" external.linked.project.path="$MODULE_DIR$/../../../HMCLCore" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="org.jackhuang" external.system.module.version="3.0" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$/../../../HMCLCore">
<excludeFolder url="file://$MODULE_DIR$/../../../HMCLCore/.gradle" />
<excludeFolder url="file://$MODULE_DIR$/../../../HMCLCore/build" />
<excludeFolder url="file://$MODULE_DIR$/../../../HMCLCore/out" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

44
.idea/modules/HMCLCore/HMCLCore_main.iml generated Normal file
View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":HMCLCore:main" external.linked.project.path="$MODULE_DIR$/../../../HMCLCore" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="org.jackhuang" external.system.module.type="sourceSet" external.system.module.version="3.0" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="JVM 1.8" useProjectSettings="false">
<compilerSettings />
<compilerArguments>
<option name="destination" value="$MODULE_DIR$/../../../HMCLCore/build/kotlin-classes/main" />
<option name="classpath" value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre8/1.1.3-2/c8da1d60b49926296fa95f2ccdb218b7912f9c17/kotlin-stdlib-jre8-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.8.1/2a8e0aa38a2e21cb39e2f5a7d6704cbdc941da0/gson-2.8.1.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre7/1.1.3-2/3fe54c7558c903868351ac79b792d152bca958f2/kotlin-stdlib-jre7-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.1.3-2/9b44c139a4ec57031e0c84ba0e49ba16df6d801c/kotlin-stdlib-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar" />
<option name="noStdlib" value="true" />
<option name="noReflect" value="true" />
<option name="moduleName" value="HMCLCore_main" />
<option name="jvmTarget" value="1.8" />
<option name="addCompilerBuiltIns" value="true" />
<option name="loadBuiltInsFromDependencies" value="true" />
<option name="languageVersion" value="1.1" />
<option name="apiVersion" value="1.1" />
<option name="pluginOptions">
<array />
</option>
<option name="pluginClasspaths">
<array />
</option>
</compilerArguments>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/../../../HMCLCore/out/production/classes" />
<exclude-output />
<content url="file://$MODULE_DIR$/../../../HMCLCore/src/main">
<sourceFolder url="file://$MODULE_DIR$/../../../HMCLCore/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../../HMCLCore/src/main/kotlin" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../../HMCLCore/src/main/resources" type="java-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre8:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: com.google.code.gson:gson:2.8.1" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains:annotations:13.0" level="project" />
</component>
</module>

48
.idea/modules/HMCLCore/HMCLCore_test.iml generated Normal file
View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":HMCLCore:test" external.linked.project.path="$MODULE_DIR$/../../../HMCLCore" external.root.project.path="$MODULE_DIR$/../../.." external.system.id="GRADLE" external.system.module.group="org.jackhuang" external.system.module.type="sourceSet" external.system.module.version="3.0" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="JVM 1.8" useProjectSettings="false">
<compilerSettings />
<compilerArguments>
<option name="destination" value="$MODULE_DIR$/../../../HMCLCore/build/kotlin-classes/test" />
<option name="classpath" value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre8/1.1.3-2/c8da1d60b49926296fa95f2ccdb218b7912f9c17/kotlin-stdlib-jre8-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.8.1/2a8e0aa38a2e21cb39e2f5a7d6704cbdc941da0/gson-2.8.1.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/2973d150c0dc1fefe998f834810d68f278ea58ec/junit-4.12.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre7/1.1.3-2/3fe54c7558c903868351ac79b792d152bca958f2/kotlin-stdlib-jre7-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.1.3-2/9b44c139a4ec57031e0c84ba0e49ba16df6d801c/kotlin-stdlib-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/42a25dc3219429f0e5d060061f71acb49bf010a0/hamcrest-core-1.3.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar" />
<option name="noStdlib" value="true" />
<option name="noReflect" value="true" />
<option name="moduleName" value="HMCLCore_main" />
<option name="jvmTarget" value="1.8" />
<option name="addCompilerBuiltIns" value="true" />
<option name="loadBuiltInsFromDependencies" value="true" />
<option name="languageVersion" value="1.1" />
<option name="apiVersion" value="1.1" />
<option name="pluginOptions">
<array />
</option>
<option name="pluginClasspaths">
<array />
</option>
</compilerArguments>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output-test url="file://$MODULE_DIR$/../../../HMCLCore/out/test/classes" />
<exclude-output />
<content url="file://$MODULE_DIR$/../../../HMCLCore/src/test">
<sourceFolder url="file://$MODULE_DIR$/../../../HMCLCore/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../HMCLCore/src/test/kotlin" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/../../../HMCLCore/src/test/resources" type="java-test-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="HMCLCore_main" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre8:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: com.google.code.gson:gson:2.8.1" level="project" />
<orderEntry type="library" name="Gradle: junit:junit:4.12" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains:annotations:13.0" level="project" />
</component>
<component name="TestModuleProperties" production-module="HMCLCore_main" />
</module>

12
.idea/modules/HMCLKotlin.iml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="HMCLKotlin" external.linked.project.path="$MODULE_DIR$/../.." external.root.project.path="$MODULE_DIR$/../.." external.system.id="GRADLE" external.system.module.group="org.jackhuang" external.system.module.version="3.0" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$/../..">
<excludeFolder url="file://$MODULE_DIR$/../../.gradle" />
<excludeFolder url="file://$MODULE_DIR$/../../build" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

44
.idea/modules/HMCLKotlin_main.iml generated Normal file
View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="HMCLKotlin:main" external.linked.project.path="$MODULE_DIR$/../.." external.root.project.path="$MODULE_DIR$/../.." external.system.id="GRADLE" external.system.module.group="org.jackhuang" external.system.module.type="sourceSet" external.system.module.version="3.0" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="JVM 1.8" useProjectSettings="false">
<compilerSettings />
<compilerArguments>
<option name="destination" value="$MODULE_DIR$/../../build/kotlin-classes/main" />
<option name="classpath" value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre8/1.1.3-2/c8da1d60b49926296fa95f2ccdb218b7912f9c17/kotlin-stdlib-jre8-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.8.1/2a8e0aa38a2e21cb39e2f5a7d6704cbdc941da0/gson-2.8.1.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre7/1.1.3-2/3fe54c7558c903868351ac79b792d152bca958f2/kotlin-stdlib-jre7-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.1.3-2/9b44c139a4ec57031e0c84ba0e49ba16df6d801c/kotlin-stdlib-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar" />
<option name="noStdlib" value="true" />
<option name="noReflect" value="true" />
<option name="moduleName" value="HMCLKotlin_main" />
<option name="jvmTarget" value="1.8" />
<option name="addCompilerBuiltIns" value="true" />
<option name="loadBuiltInsFromDependencies" value="true" />
<option name="languageVersion" value="1.1" />
<option name="apiVersion" value="1.1" />
<option name="pluginOptions">
<array />
</option>
<option name="pluginClasspaths">
<array />
</option>
</compilerArguments>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/../../out/production/classes" />
<exclude-output />
<content url="file://$MODULE_DIR$/../../src/main">
<sourceFolder url="file://$MODULE_DIR$/../../src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../src/main/kotlin" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../src/main/resources" type="java-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre8:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: com.google.code.gson:gson:2.8.1" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains:annotations:13.0" level="project" />
</component>
</module>

48
.idea/modules/HMCLKotlin_test.iml generated Normal file
View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="HMCLKotlin:test" external.linked.project.path="$MODULE_DIR$/../.." external.root.project.path="$MODULE_DIR$/../.." external.system.id="GRADLE" external.system.module.group="org.jackhuang" external.system.module.type="sourceSet" external.system.module.version="3.0" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="JVM 1.8" useProjectSettings="false">
<compilerSettings />
<compilerArguments>
<option name="destination" value="$MODULE_DIR$/../../build/kotlin-classes/test" />
<option name="classpath" value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre8/1.1.3-2/c8da1d60b49926296fa95f2ccdb218b7912f9c17/kotlin-stdlib-jre8-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.8.1/2a8e0aa38a2e21cb39e2f5a7d6704cbdc941da0/gson-2.8.1.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/2973d150c0dc1fefe998f834810d68f278ea58ec/junit-4.12.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre7/1.1.3-2/3fe54c7558c903868351ac79b792d152bca958f2/kotlin-stdlib-jre7-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.1.3-2/9b44c139a4ec57031e0c84ba0e49ba16df6d801c/kotlin-stdlib-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/42a25dc3219429f0e5d060061f71acb49bf010a0/hamcrest-core-1.3.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar" />
<option name="noStdlib" value="true" />
<option name="noReflect" value="true" />
<option name="moduleName" value="HMCLKotlin_main" />
<option name="jvmTarget" value="1.8" />
<option name="addCompilerBuiltIns" value="true" />
<option name="loadBuiltInsFromDependencies" value="true" />
<option name="languageVersion" value="1.1" />
<option name="apiVersion" value="1.1" />
<option name="pluginOptions">
<array />
</option>
<option name="pluginClasspaths">
<array />
</option>
</compilerArguments>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output-test url="file://$MODULE_DIR$/../../out/test/classes" />
<exclude-output />
<content url="file://$MODULE_DIR$/../../src/test">
<sourceFolder url="file://$MODULE_DIR$/../../src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/../../src/test/kotlin" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/../../src/test/resources" type="java-test-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="HMCLKotlin_main" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre8:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: com.google.code.gson:gson:2.8.1" level="project" />
<orderEntry type="library" name="Gradle: junit:junit:4.12" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains:annotations:13.0" level="project" />
</component>
<component name="TestModuleProperties" production-module="HMCLKotlin_main" />
</module>

14
.idea/modules/jfoenix.iml generated Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="jfoenix" external.linked.project.path="$MODULE_DIR$/../../JFoenix" external.root.project.path="$MODULE_DIR$/../../JFoenix" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$/../../JFoenix">
<sourceFolder url="file://$MODULE_DIR$/../../JFoenix/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../JFoenix/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/../../JFoenix/.gradle" />
<excludeFolder url="file://$MODULE_DIR$/../../JFoenix/build" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

15
.idea/modules/tornadofx.iml generated Normal file
View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="tornadofx" external.linked.project.path="$MODULE_DIR$/../../TornadoFx" external.root.project.path="$MODULE_DIR$/../../TornadoFx" external.system.id="GRADLE" external.system.module.group="org.jackhuang" external.system.module.version="3.0" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$/../../TornadoFx">
<sourceFolder url="file://$MODULE_DIR$/../../TornadoFx/src/main/kotlin" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../TornadoFx/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../TornadoFx/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../TornadoFx/src/test/kotlin" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
</component>
</module>

43
.idea/modules/tornadofx_main.iml generated Normal file
View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="tornadofx:main" external.linked.project.path="$MODULE_DIR$/../../TornadoFx" external.root.project.path="$MODULE_DIR$/../../TornadoFx" external.system.id="GRADLE" external.system.module.group="org.jackhuang" external.system.module.type="sourceSet" external.system.module.version="3.0" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="JVM 1.8" useProjectSettings="false">
<compilerSettings />
<compilerArguments>
<option name="destination" value="$MODULE_DIR$/../../TornadoFx/build/kotlin-classes/main" />
<option name="classpath" value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre8/1.1.3-2/c8da1d60b49926296fa95f2ccdb218b7912f9c17/kotlin-stdlib-jre8-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.1.3-2/9b44c139a4ec57031e0c84ba0e49ba16df6d801c/kotlin-stdlib-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre7/1.1.3-2/3fe54c7558c903868351ac79b792d152bca958f2/kotlin-stdlib-jre7-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar" />
<option name="noStdlib" value="true" />
<option name="noReflect" value="true" />
<option name="moduleName" value="tornadofx_main" />
<option name="jvmTarget" value="1.8" />
<option name="addCompilerBuiltIns" value="true" />
<option name="loadBuiltInsFromDependencies" value="true" />
<option name="languageVersion" value="1.1" />
<option name="apiVersion" value="1.1" />
<option name="pluginOptions">
<array />
</option>
<option name="pluginClasspaths">
<array />
</option>
</compilerArguments>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/../../TornadoFx/build/classes/main" />
<exclude-output />
<content url="file://$MODULE_DIR$/../../TornadoFx/src/main">
<sourceFolder url="file://$MODULE_DIR$/../../TornadoFx/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../TornadoFx/src/main/kotlin" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../TornadoFx/src/main/resources" type="java-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre8:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains:annotations:13.0" level="project" />
</component>
</module>

47
.idea/modules/tornadofx_test.iml generated Normal file
View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="tornadofx:test" external.linked.project.path="$MODULE_DIR$/../../TornadoFx" external.root.project.path="$MODULE_DIR$/../../TornadoFx" external.system.id="GRADLE" external.system.module.group="org.jackhuang" external.system.module.type="sourceSet" external.system.module.version="3.0" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="JVM 1.8" useProjectSettings="false">
<compilerSettings />
<compilerArguments>
<option name="destination" value="$MODULE_DIR$/../../TornadoFx/build/kotlin-classes/test" />
<option name="classpath" value="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre8/1.1.3-2/c8da1d60b49926296fa95f2ccdb218b7912f9c17/kotlin-stdlib-jre8-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/2973d150c0dc1fefe998f834810d68f278ea58ec/junit-4.12.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.1.3-2/9b44c139a4ec57031e0c84ba0e49ba16df6d801c/kotlin-stdlib-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre7/1.1.3-2/3fe54c7558c903868351ac79b792d152bca958f2/kotlin-stdlib-jre7-1.1.3-2.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/42a25dc3219429f0e5d060061f71acb49bf010a0/hamcrest-core-1.3.jar;C:/Users/huang/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar" />
<option name="noStdlib" value="true" />
<option name="noReflect" value="true" />
<option name="moduleName" value="tornadofx_main" />
<option name="jvmTarget" value="1.8" />
<option name="addCompilerBuiltIns" value="true" />
<option name="loadBuiltInsFromDependencies" value="true" />
<option name="languageVersion" value="1.1" />
<option name="apiVersion" value="1.1" />
<option name="pluginOptions">
<array />
</option>
<option name="pluginClasspaths">
<array />
</option>
</compilerArguments>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output-test url="file://$MODULE_DIR$/../../TornadoFx/build/classes/test" />
<exclude-output />
<content url="file://$MODULE_DIR$/../../TornadoFx/src/test">
<sourceFolder url="file://$MODULE_DIR$/../../TornadoFx/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/../../TornadoFx/src/test/kotlin" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/../../TornadoFx/src/test/resources" type="java-test-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="tornadofx_main" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre8:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: junit:junit:4.12" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.3-2" level="project" />
<orderEntry type="library" name="Gradle: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains:annotations:13.0" level="project" />
</component>
<component name="TestModuleProperties" production-module="tornadofx_main" />
</module>

124
.idea/uiDesigner.xml generated Normal file
View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

2536
.idea/workspace.xml generated Normal file

File diff suppressed because it is too large Load Diff

14
HMCL/.travis.yml Normal file
View File

@@ -0,0 +1,14 @@
language: java
jdk:
- oraclejdk8
branches:
only:
- master
before_install:
- chmod +x gradlew
script: "bash ./gradlew clean build --stacktrace"
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
cache:
directories:
- "$HOME/.gradle/caches/"

View File

@@ -0,0 +1,394 @@
.root {
-fx-font-family: Roboto;
src: "/resources/roboto/Roboto-Regular.ttf";
}
/* Burgers Demo */
.jfx-hamburger {
-fx-spacing: 5;
-fx-cursor: hand;
}
.jfx-hamburger StackPane {
-fx-pref-width: 40px;
-fx-pref-height: 7px;
-fx-background-color: #D63333;
-fx-background-radius: 5px;
}
/* Input Demo */
.text-field {
-fx-max-width: 300;
}
.jfx-text-field, .jfx-password-field {
-fx-background-color: WHITE;
-fx-font-weight: BOLD;
-fx-prompt-text-fill: #808080;
-fx-alignment: top-left;
-jfx-focus-color: #4059A9;
-jfx-unfocus-color: #4d4d4d;
-fx-max-width: 300;
}
.jfx-decorator {
-fx-decorator-color: RED;
}
.jfx-decorator .jfx-decorator-buttons-container {
-fx-background-color: -fx-decorator-color;
}
.jfx-decorator .resize-border {
-fx-border-color: -fx-decorator-color;
-fx-border-width: 0 4 4 4;
}
.jfx-text-area, .text-area {
-fx-font-weight: BOLD;
}
.jfx-text-field:error, .jfx-password-field:error, .jfx-text-area:error {
-jfx-focus-color: #D34336;
-jfx-unfocus-color: #D34336;
}
.jfx-text-field .error-label, .jfx-password-field .error-label, .jfx-text-area .error-label {
-fx-text-fill: #D34336;
-fx-font-size: 0.75em;
}
.jfx-text-field .error-icon, .jfx-password-field .error-icon, .jfx-text-area .error-icon {
-fx-text-fill: #D34336;
-fx-font-size: 1em;
}
/* Progress Bar Demo */
.progress-bar > .bar {
-fx-min-width: 500;
}
.jfx-progress-bar > .bar {
-fx-min-width: 500;
}
.jfx-progress-bar {
-fx-progress-color: #0F9D58;
-fx-stroke-width: 3;
}
/* Icons Demo */
.icon {
-fx-text-fill: #FE774D;
-fx-padding: 10;
-fx-cursor: hand;
}
.icons-rippler {
-jfx-rippler-fill: BLUE;
-jfx-mask-type: CIRCLE;
}
.icons-rippler:hover {
-fx-cursor: hand;
}
.jfx-check-box {
-fx-font-weight: BOLD;
}
.custom-jfx-check-box {
-jfx-checked-color: RED;
-jfx-unchecked-color: BLACK;
}
/* Button */
.button {
-fx-padding: 0.7em 0.57em;
-fx-font-size: 14px;
}
.button-raised {
-fx-padding: 0.7em 0.57em;
-fx-font-size: 14px;
-jfx-button-type: RAISED;
-fx-background-color: rgb(77, 102, 204);
-fx-pref-width: 200;
-fx-text-fill: WHITE;
}
/* The main scrollbar **track** CSS class */
.mylistview .scroll-bar:horizontal .track,
.mylistview .scroll-bar:vertical .track {
-fx-background-color: transparent;
-fx-border-color: transparent;
-fx-background-radius: 0em;
-fx-border-radius: 2em;
}
/* The increment and decrement button CSS class of scrollbar */
.mylistview .scroll-bar:horizontal .increment-button,
.mylistview .scroll-bar:horizontal .decrement-button {
-fx-background-color: transparent;
-fx-background-radius: 0em;
-fx-padding: 0 0 10 0;
}
/* The increment and decrement button CSS class of scrollbar */
.mylistview .scroll-bar:vertical .increment-button,
.mylistview .scroll-bar:vertical .decrement-button {
-fx-background-color: transparent;
-fx-background-radius: 0em;
-fx-padding: 0 10 0 0;
}
.mylistview .scroll-bar .increment-arrow,
.mylistview .scroll-bar .decrement-arrow {
-fx-shape: " ";
-fx-padding: 0;
}
/* The main scrollbar **thumb** CSS class which we drag every time (movable) */
.mylistview .scroll-bar:horizontal .thumb,
.mylistview .scroll-bar:vertical .thumb {
-fx-background-color: derive(black, 90%);
-fx-background-insets: 2, 0, 0;
-fx-background-radius: 2em;
}
.jfx-list-cell-container {
-fx-alignment: center-left;
}
.jfx-list-cell-container > .label {
-fx-text-fill: BLACK;
}
.jfx-list-cell:odd:selected > .jfx-rippler > StackPane, .jfx-list-cell:even:selected > .jfx-rippler > StackPane {
-fx-background-color: rgba(0, 0, 255, 0.2);
}
.jfx-list-cell {
-fx-background-insets: 0.0;
-fx-text-fill: BLACK;
}
.jfx-list-cell:odd, .jfx-list-cell:even {
-fx-background-color: WHITE;
}
.jfx-list-cell:filled:hover {
-fx-text-fill: black;
}
.jfx-list-cell .jfx-rippler {
-jfx-rippler-fill: BLUE;
}
.jfx-list-view {
-fx-background-insets: 0;
-jfx-cell-horizontal-margin: 0.0;
-jfx-cell-vertical-margin: 5.0;
-jfx-vertical-gap: 10;
-jfx-expanded: false;
-fx-pref-width: 200;
}
.jfx-toggle-button {
-jfx-toggle-color: RED;
}
.jfx-tool-bar {
-fx-font-size: 15;
-fx-background-color: #5264AE;
-fx-pref-width: 100%;
-fx-pref-height: 64px;
}
.jfx-tool-bar HBox {
-fx-alignment: center;
-fx-spacing: 25;
-fx-padding: 0 10;
}
.jfx-tool-bar Label {
-fx-text-fill: WHITE;
}
.jfx-popup-container {
-fx-background-color: WHITE;
}
.jfx-snackbar-content {
-fx-background-color: #323232;
-fx-padding: 5;
-fx-spacing: 5;
}
.jfx-snackbar-toast {
-fx-text-fill: WHITE;
}
.jfx-snackbar-action {
-fx-text-fill: #ff4081;
}
.jfx-list-cell-content-container {
-fx-alignment: center-left;
}
.jfx-list-cell-container .label {
-fx-text-fill: BLACK;
}
.combo-box-popup .list-view .jfx-list-cell:odd:selected .jfx-list-cell-container,
.combo-box-popup .list-view .jfx-list-cell:even:selected .jfx-list-cell-container {
-fx-background-color: rgba(0.0, 0.0, 255.0, 0.2);
}
.combo-box-popup .list-view .jfx-list-cell {
-fx-background-insets: 0.0;
-fx-text-fill: BLACK;
}
.combo-box-popup .list-view .jfx-list-cell:odd,
.combo-box-popup .list-view .jfx-list-cell:even {
-fx-background-color: WHITE;
}
.combo-box-popup .list-view .jfx-list-cell:filled:hover {
-fx-text-fill: black;
}
.combo-box-popup .list-view .jfx-list-cell .jfx-rippler {
-fx-rippler-fill: #5264AE;
}
/*.combo-box .combo-box-button-container{
-fx-border-color:BLACK;-fx-border-width: 0 0 1 0;
}
.combo-box .combo-box-selected-value-container{
-fx-border-color:BLACK;
} */
/*
* TREE TABLE CSS
*/
.tree-table-view {
-fx-tree-table-color: rgba(255, 0, 0, 0.2);
-fx-tree-table-rippler-color: rgba(255, 0, 0, 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; */
}
.tree-table-row-cell > .tree-disclosure-node > .arrow {
-fx-background-color: -fx-text-fill;
-fx-padding: 0.333333em 0.229em 0.333333em 0.229em; /* 4 */
-fx-shape: "M 0 -3.5 L 4 0 L 0 3.5 z";
}
.tree-table-row-cell .jfx-text-field {
-fx-focus-color: rgba(240, 40, 40);
}
.tree-table-row-group {
-fx-background-color: rgba(230, 230, 230);
}
.animated-option-button {
-fx-pref-width: 50px;
-fx-background-color: #44B449;
-fx-background-radius: 50px;
-fx-pref-height: 50px;
-fx-text-fill: white;
-fx-border-color: WHITE;
-fx-border-radius: 50px;
-fx-border-width: 4px;
}
.animated-option-sub-button {
-fx-background-color: #43609C;
}
.animated-option-sub-button2 {
-fx-background-color: rgb(203, 104, 96);
}
.tree-table-view .menu-item:focused {
-fx-background-color: -fx-tree-table-color;
}
.tree-table-view .menu-item .label {
-fx-padding: 5 0 5 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXListView?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.StackPane?>
<fx:root xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
type="StackPane"
prefHeight="400.0" prefWidth="600.0">
<JFXListView fx:id="list" styleClass="jfx-list-view" maxWidth="300" maxHeight="100">
<BorderPane mouseTransparent="true">
<left>
<Label>Install New Game</Label>
</left>
<right>
<fx:include source="/assets/svg/arrow-right.fxml"/>
</right>
</BorderPane>
<BorderPane mouseTransparent="true">
<left>
<Label>Install Modpack (CurseForge supported)</Label>
</left>
<right>
<fx:include source="/assets/svg/arrow-right.fxml"/>
</right>
</BorderPane>
</JFXListView>
</fx:root>

View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXListView?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<?import com.jfoenix.controls.JFXButton?>
<?import javafx.scene.layout.HBox?>
<fx:root xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
type="StackPane">
<BorderPane>
<top>
<HBox alignment="CENTER" style="-fx-padding: 40px;">
<Label fx:id="lblGameVersion" alignment="CENTER" />
</HBox>
</top>
<center>
<JFXListView fx:id="list" styleClass="jfx-list-view" maxHeight="150" maxWidth="300">
<BorderPane mouseTransparent="true">
<left>
<Label fx:id="lblForge">Install Forge</Label>
</left>
<right>
<fx:include source="/assets/svg/arrow-right.fxml"/>
</right>
</BorderPane>
<BorderPane mouseTransparent="true">
<left>
<Label fx:id="lblLiteLoader">Install LiteLoader</Label>
</left>
<right>
<fx:include source="/assets/svg/arrow-right.fxml"/>
</right>
</BorderPane>
<BorderPane mouseTransparent="true">
<left>
<Label fx:id="lblOptiFine">Install OptiFine</Label>
</left>
<right>
<fx:include source="/assets/svg/arrow-right.fxml"/>
</right>
</BorderPane>
</JFXListView>
</center>
<bottom>
<HBox alignment="CENTER">
<JFXButton fx:id="buttonLaunch" prefWidth="100" prefHeight="40" buttonType="RAISED" text="Install"
style="-fx-text-fill:WHITE;-fx-background-color:#5264AE;-fx-font-size:14px;"/>
</HBox>
</bottom>
</BorderPane>
</fx:root>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<fx:root xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
type="BorderPane" pickOnBounds="false">
<left>
<VBox alignment="CENTER_LEFT" mouseTransparent="true">
<Label fx:id="lblSelfVersion" style="-fx-font-size: 15;" />
</VBox>
</left>
<center>
<VBox alignment="CENTER" mouseTransparent="true">
<Label alignment="CENTER" fx:id="lblGameVersion" style="-fx-color: gray;" />
</VBox>
</center>
<right>
<fx:include source="/assets/svg/arrow-right.fxml" />
</right>
</fx:root>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXListView?>
<?import javafx.scene.layout.StackPane?>
<?import com.jfoenix.controls.JFXSpinner?>
<fx:root xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
type="StackPane"
prefHeight="400.0" prefWidth="600.0">
<JFXSpinner fx:id="spinner" style="-fx-radius:16" styleClass="materialDesign-purple, first-spinner" />
<JFXListView fx:id="list" styleClass="jfx-list-view">
</JFXListView>
</fx:root>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import com.jfoenix.controls.*?>
<BorderPane
maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
fx:controller="org.jackhuang.hmcl.ui.MainController"
style="-fx-background-color: white;"
xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1">
<center>
<StackPane fx:id="page" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
</center>
<left>
<BorderPane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<top>
<JFXComboBox fx:id="comboProfiles" prefWidth="150.0" BorderPane.alignment="CENTER" />
</top>
<center>
<StackPane>
<JFXListView fx:id="listVersions" styleClass="mylistview" style="-fx-background-color: #F1F1F1;" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
<AnchorPane pickOnBounds="false">
<JFXButton onMouseClicked="#installNewVersion" AnchorPane.bottomAnchor="16" AnchorPane.rightAnchor="16" buttonType="RAISED" prefWidth="40" prefHeight="40" style="-fx-text-fill:WHITE;-fx-background-color:#5264AE;-fx-font-size:14px;-fx-background-radius: 80px;">
<graphic>
<fx:include source="/assets/svg/plus.fxml" />
</graphic>
</JFXButton>
</AnchorPane>
</StackPane>
</center>
</BorderPane>
</left>
<bottom>
<BorderPane prefHeight="50.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<right>
<StackPane prefHeight="50.0" prefWidth="150.0" BorderPane.alignment="CENTER">
<JFXSpinner fx:id="spinner" style="-fx-radius:16" styleClass="materialDesign-purple, first-spinner" />
<JFXButton fx:id="buttonLaunch" prefWidth="100" prefHeight="40" buttonType="RAISED" text="Launch"
style="-fx-text-fill:WHITE;-fx-background-color:#5264AE;-fx-font-size:14px;"/>
</StackPane>
</right>
</BorderPane>
</bottom>
</BorderPane>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import com.jfoenix.controls.JFXButton?>
<fx:root xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
style="-fx-background-color: transparent; "
type="BorderPane" pickOnBounds="false">
<left>
<VBox alignment="CENTER_LEFT" mouseTransparent="true">
<Label fx:id="lblVersionName" style="-fx-font-size: 15;" />
<Label fx:id="lblGameVersion" />
</VBox>
</left>
<right>
<HBox>
<JFXButton onMouseClicked="#onSettings" styleClass="toggle-icon3">
<graphic>
<fx:include source="/assets/svg/gear.fxml"/>
</graphic>
</JFXButton>
<JFXButton onMouseClicked="#onLaunch" styleClass="toggle-icon3">
<graphic>
<fx:include source="/assets/svg/rocket.fxml"/>
</graphic>
</JFXButton>
</HBox>
</right>
</fx:root>

View File

@@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.*?>
<?import javafx.collections.FXCollections?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<StackPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.jackhuang.hmcl.ui.VersionController">
<VBox spacing="20" GridPane.rowIndex="0">
<JFXToolbar maxHeight="20" styleClass="jfx-tool-bar">
<leftItems>
<JFXButton fx:id="backButton" maxHeight="20" styleClass="toggle-icon3"
StackPane.alignment="CENTER_LEFT">
<graphic>
<fx:include source="/assets/svg/arrow-left.fxml" />
</graphic>
<StackPane.margin>
<Insets left="20" />
</StackPane.margin>
</JFXButton>
<Label fx:id="titleLabel" style="-fx-text-fill:WHITE; -fx-font-size: 20;"
StackPane.alignment="CENTER_LEFT"/>
</leftItems>
<rightItems>
</rightItems>
</JFXToolbar>
<ScrollPane fx:id="scroll"
style="-fx-margin: 10; -fx-background-color: white; -fx-font-size: 14; -fx-pref-width: 100%; "
fitToHeight="true" fitToWidth="true">
<VBox.margin>
<Insets left="10" right="10"/>
</VBox.margin>
<VBox>
<GridPane fx:id="settingsPane" style="-fx-margin-left: 10; -fx-background-color: white; " hgap="5" vgap="10">
<Label GridPane.rowIndex="0" GridPane.columnIndex="0">Java Directory</Label>
<Label GridPane.rowIndex="1" GridPane.columnIndex="0">Max Memory</Label>
<Label GridPane.rowIndex="2" GridPane.columnIndex="0">Launcher Visibility</Label>
<Label GridPane.rowIndex="3" GridPane.columnIndex="0">Run Directory</Label>
<Label GridPane.rowIndex="4" GridPane.columnIndex="0">Dimension</Label>
<Label GridPane.rowIndex="5" GridPane.columnIndex="0"> </Label>
<JFXTextField styleClass="fit-width" fx:id="txtGameDir" GridPane.rowIndex="0" GridPane.columnIndex="1"
maxWidth="Infinity"/>
<BorderPane GridPane.rowIndex="1" GridPane.columnIndex="1" GridPane.columnSpan="2">
<left>
<JFXTextField fx:id="txtMaxMemory" maxWidth="Infinity"/>
</left>
<right>
<Label>Physical Memory: 16000MB
<BorderPane.margin>
<Insets right="7"/>
</BorderPane.margin>
</Label>
</right>
</BorderPane>
<JFXComboBox fx:id="cboLauncherVisibility" GridPane.rowIndex="2" GridPane.columnIndex="1"
GridPane.columnSpan="2" maxWidth="Infinity">
<items>
<FXCollections fx:factory="observableArrayList">
<Label>Close</Label>
<Label>Hide</Label>
<Label>Keep</Label>
<Label>Hide and Reopen</Label>
</FXCollections>
</items>
</JFXComboBox>
<JFXComboBox fx:id="cboRunDirectory" GridPane.rowIndex="3" GridPane.columnIndex="1"
GridPane.columnSpan="2" maxWidth="Infinity">
<items>
<FXCollections fx:factory="observableArrayList">
<Label>Default(.minecraft/)</Label>
<Label>Divided(.minecraft/versions/&lt;versionName&gt;)</Label>
</FXCollections>
</items>
</JFXComboBox>
<BorderPane GridPane.rowIndex="4" GridPane.columnIndex="1" GridPane.columnSpan="2">
<left>
<HBox prefWidth="210">
<JFXTextField fx:id="txtWidth" promptText="800" prefWidth="100"/>
<Label>x</Label>
<JFXTextField fx:id="txtHeight" promptText="480" prefWidth="100"/>
</HBox>
</left>
<right>
<JFXCheckBox fx:id="chkFullscreen" text="Fullscreen" alignment="CENTER">
<BorderPane.margin>
<Insets right="7"/>
</BorderPane.margin>
</JFXCheckBox>
</right>
</BorderPane>
<JFXButton GridPane.rowIndex="0" GridPane.columnIndex="2" text="Explore" onMouseClicked="#onExploreJavaDir" />
</GridPane>
<VBox fx:id="advancedSettingsPane" style="-fx-padding-bottom: 10; -fx-background-color: white; " spacing="30">
<JFXTextField labelFloat="true" promptText="JVM Args" styleClass="fit-width" fx:id="txtJVMArgs" maxWidth="Infinity"/>
<JFXTextField labelFloat="true" promptText="Game Args" styleClass="fit-width" fx:id="txtGameArgs" maxWidth="Infinity"/>
<JFXTextField labelFloat="true" promptText="Metaspace" styleClass="fit-width" fx:id="txtMetaspace" maxWidth="Infinity"/>
<JFXTextField labelFloat="true" promptText="Wrapper Launcher(like optirun)" styleClass="fit-width" fx:id="txtWrapper" maxWidth="Infinity"/>
<JFXTextField labelFloat="true" promptText="Pre-calling command" styleClass="fit-width" fx:id="txtPrecallingCommand" maxWidth="Infinity"/>
<JFXTextField labelFloat="true" promptText="Server IP" styleClass="fit-width" fx:id="txtServerIP" maxWidth="Infinity"/>
</VBox>
</VBox>
</ScrollPane>
</VBox>
</StackPane>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXToolbar?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.*?>
<fx:root xmlns="http://javafx.com/javafx"
type="StackPane"
xmlns:fx="http://javafx.com/fxml">
<VBox>
<JFXToolbar fx:id="toolbar" maxHeight="20" styleClass="jfx-tool-bar">
<leftItems>
<JFXButton fx:id="closeButton" maxHeight="20" styleClass="toggle-icon3"
StackPane.alignment="CENTER_RIGHT" onMouseClicked="#close">
<graphic>
<fx:include source="/assets/svg/close.fxml"/>
</graphic>
<StackPane.margin>
<Insets left="20"/>
</StackPane.margin>
</JFXButton>
<JFXButton fx:id="backButton" maxHeight="20" styleClass="toggle-icon3"
StackPane.alignment="CENTER_LEFT" onMouseClicked="#back">
<graphic>
<fx:include source="/assets/svg/arrow-left.fxml"/>
</graphic>
</JFXButton>
<Label fx:id="titleLabel" style="-fx-text-fill:WHITE; -fx-font-size: 15;"
StackPane.alignment="CENTER_LEFT"/>
</leftItems>
<rightItems>
<JFXButton fx:id="refreshButton" maxHeight="20" styleClass="toggle-icon3" disable="true"
StackPane.alignment="CENTER_RIGHT">
<graphic>
<fx:include source="/assets/svg/refresh.fxml"/>
</graphic>
<StackPane.margin>
<Insets left="20"/>
</StackPane.margin>
</JFXButton>
</rightItems>
</JFXToolbar>
<StackPane fx:id="root"/>
</VBox>
</fx:root>

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<javafx.scene.shape.SVGPath fill="white" content="M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z" />

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<javafx.scene.shape.SVGPath content="M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z" />

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<javafx.scene.shape.SVGPath fill="white" content="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<javafx.scene.shape.SVGPath fill="white" content="M12,16A2,2 0 0,1 14,18A2,2 0 0,1 12,20A2,2 0 0,1 10,18A2,2 0 0,1 12,16M12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12A2,2 0 0,1 12,10M12,4A2,2 0 0,1 14,6A2,2 0 0,1 12,8A2,2 0 0,1 10,6A2,2 0 0,1 12,4Z" />

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<javafx.scene.shape.SVGPath content="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z" />

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<javafx.scene.shape.SVGPath fill="white" content="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" />

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<javafx.scene.shape.SVGPath fill="white" content="M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z" />

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<javafx.scene.shape.SVGPath content="M2.81,14.12L5.64,11.29L8.17,10.79C11.39,6.41 17.55,4.22 19.78,4.22C19.78,6.45 17.59,12.61 13.21,15.83L12.71,18.36L9.88,21.19L9.17,17.66C7.76,17.66 7.76,17.66 7.05,16.95C6.34,16.24 6.34,16.24 6.34,14.83L2.81,14.12M5.64,16.95L7.05,18.36L4.39,21.03H2.97V19.61L5.64,16.95M4.22,15.54L5.46,15.71L3,18.16V16.74L4.22,15.54M8.29,18.54L8.46,19.78L7.26,21H5.84L8.29,18.54M13,9.5A1.5,1.5 0 0,0 11.5,11A1.5,1.5 0 0,0 13,12.5A1.5,1.5 0 0,0 14.5,11A1.5,1.5 0 0,0 13,9.5Z" />

2
HMCL/settings.gradle Normal file
View File

@@ -0,0 +1,2 @@
rootProject.name = 'HMCL'

View File

@@ -0,0 +1,61 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl
import javafx.application.Application
import javafx.stage.Stage
import org.jackhuang.hmcl.ui.Controllers
import org.jackhuang.hmcl.util.DEFAULT_USER_AGENT
import org.jackhuang.hmcl.util.OS
import java.io.File
class MainApplication : Application() {
override fun start(stage: Stage) {
Controllers.initialize(stage)
stage.isResizable = false
stage.scene = Controllers.scene
stage.show()
}
companion object {
@JvmStatic
fun main(args: Array<String>) {
DEFAULT_USER_AGENT = "Hello Minecraft! Launcher"
launch(MainApplication::class.java, *args)
}
fun getWorkingDirectory(folder: String): File {
val userhome = System.getProperty("user.home", ".")
return when (OS.CURRENT_OS) {
OS.LINUX -> File(userhome, ".$folder/")
OS.WINDOWS -> {
val appdata: String? = System.getenv("APPDATA")
File(appdata ?: userhome, ".$folder/")
}
OS.OSX -> File(userhome, "Library/Application Support/" + folder)
else -> File(userhome, "$folder/")
}
}
fun getMinecraftDirectory(): File = getWorkingDirectory("minecraft")
}
}

View File

@@ -0,0 +1,43 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.game
import org.jackhuang.hmcl.util.LOG
import java.io.File
import java.io.IOException
import java.util.logging.Level
class HMCLGameRepository(baseDirectory: File)
: DefaultGameRepository(baseDirectory) {
val PROFILE = "{\"selectedProfile\": \"(Default)\",\"profiles\": {\"(Default)\": {\"name\": \"(Default)\"}},\"clientToken\": \"88888888-8888-8888-8888-888888888888\"}"
@Synchronized
override fun refreshVersions() {
super.refreshVersions()
try {
val file = baseDirectory.resolve("launcher_profiles.json")
if (!file.exists())
file.writeText(PROFILE)
} catch (ex: IOException) {
LOG.log(Level.WARNING, "Unable to create launcher_profiles.json, Forge/LiteLoader installer will not work.", ex)
}
}
}

View File

@@ -0,0 +1,23 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.setting
enum class EnumGameDirectory {
ROOT_FOLDER,
VERSION_FOLDER
}

View File

@@ -0,0 +1,47 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.setting
/**
* The visibility of launcher.
* @author huangyuhui
*/
enum class LauncherVisibility {
/**
* Close the launcher anyway when the game process created even if failed to
* launch game.
*/
CLOSE,
/**
* Hide the launcher when the game process created, if failed to launch
* game, will show the log window.
*/
HIDE,
/**
* Keep the launcher visible even if the game launched successfully.
*/
KEEP,
/**
* Hide the launcher and reopen it when game closes.
*/
HIDE_AND_REOPEN
}

View File

@@ -0,0 +1,232 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.setting
import com.google.gson.*
import javafx.beans.property.*
import org.jackhuang.hmcl.util.*
import java.lang.reflect.Type
class VersionSetting() {
/**
* The displayed name.
*/
val nameProperty = SimpleStringProperty(this, "name", "")
var name: String by nameProperty
/**
* HMCL Version Settings have been divided into 2 parts.
* 1. Global settings.
* 2. Version settings.
* If a version claims that it uses global settings, its version setting will be disabled.
*
* Defaults false because if one version uses global first, custom version file will not be generated.
*/
val usesGlobalProperty = SimpleBooleanProperty(this, "usesGlobal", false)
var usesGlobal: Boolean by usesGlobalProperty
// java
/**
* Java version or null if user customizes java directory.
*/
val javaProperty = SimpleStringProperty(this, "java", null)
var java: String? by javaProperty
/**
* User customized java directory or null if user uses system Java.
*/
val javaDirProperty = SimpleStringProperty(this, "javaDir", "")
var javaDir: String by javaDirProperty
/**
* The command to launch java, i.e. optirun.
*/
val wrapperProperty = SimpleStringProperty(this, "wrapper", "")
var wrapper: String by wrapperProperty
/**
* The permanent generation size of JVM garbage collection.
*/
val permSizeProperty = SimpleIntegerProperty(this, "permSize", 0)
var permSize: Int by permSizeProperty
/**
* The maximum memory that JVM can allocate.
* The size of JVM heap.
*/
val maxMemoryProperty = SimpleIntegerProperty(this, "maxMemory", 0)
var maxMemory: Int by maxMemoryProperty
/**
* The command that will be executed before launching the Minecraft.
* Operating system relevant.
*/
val precalledCommandProperty = SimpleStringProperty(this, "precalledCommand", "")
var precalledCommand: String by precalledCommandProperty
// options
/**
* The user customized arguments passed to JVM.
*/
val javaArgsProperty = SimpleStringProperty(this, "javaArgs", "")
var javaArgs: String by javaArgsProperty
/**
* The user customized arguments passed to Minecraft.
*/
val minecraftArgsProperty = SimpleStringProperty(this, "minecraftArgs", "")
var minecraftArgs: String by minecraftArgsProperty
/**
* True if disallow HMCL use default JVM arguments.
*/
val noJVMArgsProperty = SimpleBooleanProperty(this, "noJVMArgs", false)
var noJVMArgs: Boolean by noJVMArgsProperty
/**
* True if HMCL does not check game's completeness.
*/
val notCheckGameProperty = SimpleBooleanProperty(this, "notCheckGame", false)
var notCheckGame: Boolean by notCheckGameProperty
// Minecraft settings.
/**
* The server ip that will be entered after Minecraft successfully loaded immediately.
*
* Format: ip:port or without port.
*/
val serverIpProperty = SimpleStringProperty(this, "serverIp", "")
var serverIp: String by serverIpProperty
/**
* True if Minecraft started in fullscreen mode.
*/
val fullscreenProperty = SimpleBooleanProperty(this, "fullscreen", false)
var fullscreen: Boolean by fullscreenProperty
/**
* The width of Minecraft window, defaults 800.
*
* The field saves int value.
* String type prevents unexpected value from causing JsonSyntaxException.
* We can only reset this field instead of recreating the whole setting file.
*/
val widthProperty = SimpleIntegerProperty(this, "width", 0)
var width: Int by widthProperty
/**
* The height of Minecraft window, defaults 480.
*
* The field saves int value.
* String type prevents unexpected value from causing JsonSyntaxException.
* We can only reset this field instead of recreating the whole setting file.
*/
val heightProperty = SimpleIntegerProperty(this, "height", 0)
var height: Int by heightProperty
/**
* 0 - .minecraft<br/>
* 1 - .minecraft/versions/&lt;version&gt;/<br/>
*/
val gameDirTypeProperty = SimpleObjectProperty<EnumGameDirectory>(this, "gameDirTypeProperty", EnumGameDirectory.ROOT_FOLDER)
var gameDirType: EnumGameDirectory by gameDirTypeProperty
// launcher settings
/**
* 0 - Close the launcher when the game starts.<br/>
* 1 - Hide the launcher when the game starts.<br/>
* 2 - Keep the launcher open.<br/>
*/
val launcherVisibilityProperty = SimpleObjectProperty<LauncherVisibility>(this, "launcherVisibility", LauncherVisibility.HIDE)
var launcherVisibility: LauncherVisibility by launcherVisibilityProperty
val gameVersion: String
get() = "1.7.10"
companion object Serializer: JsonSerializer<VersionSetting>, JsonDeserializer<VersionSetting> {
override fun serialize(src: VersionSetting?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement {
if (src == null) return JsonNull.INSTANCE
val jsonObject = JsonObject()
with(jsonObject) {
addProperty("name", src.name)
addProperty("usesGlobal", src.usesGlobal)
addProperty("javaArgs", src.javaArgs)
addProperty("minecraftArgs", src.minecraftArgs)
addProperty("maxMemory", src.maxMemory)
addProperty("permSize", src.permSize)
addProperty("width", src.width)
addProperty("height", src.height)
addProperty("javaDir", src.javaDir)
addProperty("precalledCommand", src.precalledCommand)
addProperty("serverIp", src.serverIp)
addProperty("java", src.java)
addProperty("wrapper", src.wrapper)
addProperty("fullscreen", src.fullscreen)
addProperty("noJVMArgs", src.noJVMArgs)
addProperty("notCheckGame", src.notCheckGame)
addProperty("launcherVisibility", src.launcherVisibility.ordinal)
addProperty("gameDirType", src.gameDirType.ordinal)
}
return jsonObject
}
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): VersionSetting? {
if (json == null || json == JsonNull.INSTANCE || json !is JsonObject) return null
return VersionSetting().apply {
name = json["name"]?.asString ?: ""
usesGlobal = json["usesGlobal"]?.asBoolean ?: false
javaArgs = json["javaArgs"]?.asString ?: ""
minecraftArgs = json["minecraftArgs"]?.asString ?: ""
maxMemory = parseJsonPrimitive(json["maxMemory"]?.asJsonPrimitive)
permSize = parseJsonPrimitive(json["permSize"]?.asJsonPrimitive)
width = parseJsonPrimitive(json["width"]?.asJsonPrimitive)
height = parseJsonPrimitive(json["height"]?.asJsonPrimitive)
javaDir = json["javaDir"]?.asString ?: ""
precalledCommand = json["precalledCommand"]?.asString ?: ""
serverIp = json["serverIp"]?.asString ?: ""
java = json["java"]?.asString
wrapper = json["wrapper"]?.asString ?: ""
fullscreen = json["fullscreen"]?.asBoolean ?: false
noJVMArgs = json["noJVMArgs"]?.asBoolean ?: false
notCheckGame = json["notCheckGame"]?.asBoolean ?: false
launcherVisibility = LauncherVisibility.values()[json["launcherVisibility"]?.asInt ?: 1]
gameDirType = EnumGameDirectory.values()[json["gameDirType"]?.asInt ?: 0]
}
}
fun parseJsonPrimitive(primitive: JsonPrimitive?, defaultValue: Int = 0): Int {
if (primitive != null)
if (primitive.isNumber)
return primitive.asInt
else
return primitive.asString.toIntOrNull() ?: defaultValue
else
return defaultValue
}
}
}

View File

@@ -0,0 +1,63 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui
import javafx.fxml.FXMLLoader
import javafx.scene.Node
import javafx.scene.Scene
import javafx.scene.layout.Pane
import javafx.scene.layout.StackPane
import javafx.stage.Stage
object Controllers {
lateinit var scene: Scene private set
lateinit var stage: Stage private set
lateinit var mainController: MainController
private val mainPane: Pane = loadPane("main")
lateinit var versionController: VersionController
val versionPane: Pane = loadPane("version")
fun initialize(stage: Stage) {
this.stage = stage
val decorator = Decorator(stage, mainPane, max = false)
// Let root pane fix window size.
(mainPane.parent as StackPane).run {
mainPane.prefWidthProperty().bind(widthProperty())
mainPane.prefHeightProperty().bind(heightProperty())
}
decorator.isCustomMaximize = false
scene = Scene(decorator, 800.0, 480.0)
scene.stylesheets.addAll(Controllers::class.java.getResource("/css/jfoenix-design.css").toExternalForm(),
Controllers::class.java.getResource("/assets/css/jfoenix-components.css").toExternalForm(),
Controllers::class.java.getResource("/assets/css/jfoenix-main-demo.css").toExternalForm())
stage.minWidth = 800.0
stage.maxWidth = 800.0
stage.maxHeight = 480.0
stage.minHeight = 480.0
}
fun navigate(node: Node?) {
mainController.setContentPage(node)
}
private fun <T> loadPane(s: String): T = FXMLLoader(Controllers::class.java.getResource("/assets/fxml/$s.fxml")).load()
}

View File

@@ -0,0 +1,384 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui
import com.jfoenix.controls.JFXButton
import com.jfoenix.svg.SVGGlyph
import javafx.animation.*
import javafx.application.Platform
import javafx.beans.property.BooleanProperty
import javafx.beans.property.ObjectProperty
import javafx.beans.property.SimpleBooleanProperty
import javafx.beans.property.SimpleObjectProperty
import javafx.geometry.BoundingBox
import javafx.geometry.Bounds
import javafx.geometry.Insets
import javafx.geometry.Pos
import javafx.scene.Cursor
import javafx.scene.Node
import javafx.scene.control.Button
import javafx.scene.control.Label
import javafx.scene.control.Tooltip
import javafx.scene.input.MouseEvent
import javafx.scene.layout.*
import javafx.scene.paint.Color
import javafx.scene.shape.Rectangle
import javafx.stage.Screen
import javafx.stage.Stage
import javafx.stage.StageStyle
import java.util.ArrayList
class Decorator @JvmOverloads constructor(private val primaryStage: Stage, node: Node, max: Boolean = true, min: Boolean = true) : VBox() {
private var xOffset: Double = 0.toDouble()
private var yOffset: Double = 0.toDouble()
private var newX: Double = 0.toDouble()
private var newY: Double = 0.toDouble()
private var initX: Double = 0.toDouble()
private var initY: Double = 0.toDouble()
private var allowMove: Boolean = false
private var isDragging: Boolean = false
private var windowDecoratorAnimation: Timeline? = null
private val contentPlaceHolder: StackPane
private val titleContainer: BorderPane
private val onCloseButtonAction: ObjectProperty<Runnable>
private val customMaximize: BooleanProperty
private var maximized: Boolean = false
private var originalBox: BoundingBox? = null
private var maximizedBox: BoundingBox? = null
private val btnMax: JFXButton
init {
this.xOffset = 0.0
this.yOffset = 0.0
this.allowMove = false
this.isDragging = false
this.contentPlaceHolder = StackPane()
this.onCloseButtonAction = SimpleObjectProperty(Runnable { this.primaryStage.close() })
this.customMaximize = SimpleBooleanProperty(false)
this.maximized = false
this.primaryStage.initStyle(StageStyle.UNDECORATED)
this.isPickOnBounds = false
this.styleClass.add("jfx-decorator")
val minus = SVGGlyph(0, "MINUS", "M804.571 420.571v109.714q0 22.857-16 38.857t-38.857 16h-694.857q-22.857 0-38.857-16t-16-38.857v-109.714q0-22.857 16-38.857t38.857-16h694.857q22.857 0 38.857 16t16 38.857z", Color.WHITE)
minus.setSize(12.0, 2.0)
minus.translateY = 4.0
val resizeMax = SVGGlyph(0, "RESIZE_MAX", "M726 810v-596h-428v596h428zM726 44q34 0 59 25t25 59v768q0 34-25 60t-59 26h-428q-34 0-59-26t-25-60v-768q0-34 25-60t59-26z", Color.WHITE)
resizeMax.setSize(12.0, 12.0)
val resizeMin = SVGGlyph(0, "RESIZE_MIN", "M80.842 943.158v-377.264h565.894v377.264h-565.894zM0 404.21v619.79h727.578v-619.79h-727.578zM377.264 161.684h565.894v377.264h-134.736v80.842h215.578v-619.79h-727.578v323.37h80.842v-161.686z", Color.WHITE)
resizeMin.setSize(12.0, 12.0)
val close = SVGGlyph(0, "CLOSE", "M810 274l-238 238 238 238-60 60-238-238-238 238-60-60 238-238-238-238 60-60 238 238 238-238z", Color.WHITE)
close.setSize(12.0, 12.0)
val btnClose = JFXButton()
btnClose.styleClass.add("jfx-decorator-button")
btnClose.cursor = Cursor.HAND
btnClose.setOnAction { action -> (this.onCloseButtonAction.get() as Runnable).run() }
btnClose.graphic = close
btnClose.ripplerFill = Color.WHITE
val btnMin = JFXButton()
btnMin.styleClass.add("jfx-decorator-button")
btnMin.cursor = Cursor.HAND
btnMin.setOnAction { action -> this.primaryStage.isIconified = true }
btnMin.graphic = minus
btnMin.ripplerFill = Color.WHITE
this.btnMax = JFXButton()
this.btnMax.styleClass.add("jfx-decorator-button")
this.btnMax.cursor = Cursor.HAND
this.btnMax.ripplerFill = Color.WHITE
this.btnMax.setOnAction { action ->
if (!this.isCustomMaximize) {
this.primaryStage.isMaximized = !this.primaryStage.isMaximized
this.maximized = this.primaryStage.isMaximized
if (this.primaryStage.isMaximized) {
this.btnMax.graphic = resizeMin
this.btnMax.tooltip = Tooltip("Restore Down")
} else {
this.btnMax.graphic = resizeMax
this.btnMax.tooltip = Tooltip("Maximize")
}
} else {
if (!this.maximized) {
this.originalBox = BoundingBox(primaryStage.x, primaryStage.y, primaryStage.width, primaryStage.height)
val screen = Screen.getScreensForRectangle(primaryStage.x, primaryStage.y, primaryStage.width, primaryStage.height)[0] as Screen
val bounds = screen.visualBounds
this.maximizedBox = BoundingBox(bounds.minX, bounds.minY, bounds.width, bounds.height)
primaryStage.x = this.maximizedBox!!.minX
primaryStage.y = this.maximizedBox!!.minY
primaryStage.width = this.maximizedBox!!.width
primaryStage.height = this.maximizedBox!!.height
this.btnMax.graphic = resizeMin
this.btnMax.tooltip = Tooltip("Restore Down")
} else {
primaryStage.x = this.originalBox!!.minX
primaryStage.y = this.originalBox!!.minY
primaryStage.width = this.originalBox!!.width
primaryStage.height = this.originalBox!!.height
this.originalBox = null
this.btnMax.graphic = resizeMax
this.btnMax.tooltip = Tooltip("Maximize")
}
this.maximized = !this.maximized
}
}
this.btnMax.graphic = resizeMax
titleContainer = BorderPane()
titleContainer.styleClass += "jfx-decorator-buttons-container"
titleContainer.isPickOnBounds = false
val titleWrapper = HBox()
titleWrapper.style += "-fx-padding: 15;"
titleWrapper.alignment = Pos.CENTER_LEFT
val title = Label("Hello Minecraft! Launcher")
title.alignment = Pos.CENTER_LEFT
title.style += "--fx-background-color: transparent; -fx-text-fill: white; -fx-font-size: 15px;"
title.isMouseTransparent = false
titleWrapper.children.setAll(title)
titleContainer.left = titleWrapper
val buttonsContainer = HBox()
buttonsContainer.styleClass.add("jfx-decorator-buttons-container")
buttonsContainer.background = Background(*arrayOf(BackgroundFill(Color.BLACK, CornerRadii.EMPTY, Insets.EMPTY)))
buttonsContainer.padding = Insets(4.0)
buttonsContainer.alignment = Pos.CENTER_RIGHT
titleContainer.addEventHandler(MouseEvent.MOUSE_CLICKED) { mouseEvent ->
if (mouseEvent.clickCount == 2) {
this.btnMax.fire()
}
}
val btns = ArrayList<Button>()
if (min) {
btns.add(btnMin)
}
if (max) {
btns.add(this.btnMax)
}
btns.add(btnClose)
buttonsContainer.children.addAll(btns)
titleContainer.addEventHandler(MouseEvent.MOUSE_ENTERED) { enter -> this.allowMove = true }
titleContainer.addEventHandler(MouseEvent.MOUSE_EXITED) { enter ->
if (!this.isDragging) {
this.allowMove = false
}
}
buttonsContainer.minWidth = 180.0
titleContainer.right = buttonsContainer
this.contentPlaceHolder.styleClass.add("jfx-decorator-content-container")
this.contentPlaceHolder.setMinSize(0.0, 0.0)
this.contentPlaceHolder.children.add(node)
(node as Region).setMinSize(0.0, 0.0)
VBox.setVgrow(this.contentPlaceHolder, Priority.ALWAYS)
this.contentPlaceHolder.styleClass.add("resize-border")
this.contentPlaceHolder.border = Border(*arrayOf(BorderStroke(Color.BLACK, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, BorderWidths(0.0, 4.0, 4.0, 4.0))))
val clip = Rectangle()
clip.widthProperty().bind(node.widthProperty())
clip.heightProperty().bind(node.heightProperty())
node.setClip(clip)
this.children.addAll(*arrayOf<Node>(titleContainer, this.contentPlaceHolder))
this.setOnMouseMoved { mouseEvent ->
if (!this.primaryStage.isMaximized && !this.primaryStage.isFullScreen && !this.maximized) {
if (!this.primaryStage.isResizable) {
this.updateInitMouseValues(mouseEvent)
} else {
val x = mouseEvent.x
val y = mouseEvent.y
val boundsInParent = this.boundsInParent
if (this.contentPlaceHolder.border != null && this.contentPlaceHolder.border.strokes.size > 0) {
val borderWidth = this.contentPlaceHolder.snappedLeftInset()
if (this.isRightEdge(x, y, boundsInParent)) {
if (y < borderWidth) {
this.cursor = Cursor.NE_RESIZE
} else if (y > this.height - borderWidth) {
this.cursor = Cursor.SE_RESIZE
} else {
this.cursor = Cursor.E_RESIZE
}
} else if (this.isLeftEdge(x, y, boundsInParent)) {
if (y < borderWidth) {
this.cursor = Cursor.NW_RESIZE
} else if (y > this.height - borderWidth) {
this.cursor = Cursor.SW_RESIZE
} else {
this.cursor = Cursor.W_RESIZE
}
} else if (this.isTopEdge(x, y, boundsInParent)) {
this.cursor = Cursor.N_RESIZE
} else if (this.isBottomEdge(x, y, boundsInParent)) {
this.cursor = Cursor.S_RESIZE
} else {
this.cursor = Cursor.DEFAULT
}
this.updateInitMouseValues(mouseEvent)
}
}
} else {
this.cursor = Cursor.DEFAULT
}
}
this.setOnMouseReleased { mouseEvent -> this.isDragging = false }
this.setOnMouseDragged { mouseEvent ->
this.isDragging = true
if (mouseEvent.isPrimaryButtonDown && (this.xOffset != -1.0 || this.yOffset != -1.0)) {
if (!this.primaryStage.isFullScreen && !mouseEvent.isStillSincePress && !this.primaryStage.isMaximized && !this.maximized) {
this.newX = mouseEvent.screenX
this.newY = mouseEvent.screenY
val deltax = this.newX - this.initX
val deltay = this.newY - this.initY
val cursor = this.cursor
if (Cursor.E_RESIZE == cursor) {
this.setStageWidth(this.primaryStage.width + deltax)
mouseEvent.consume()
} else if (Cursor.NE_RESIZE == cursor) {
if (this.setStageHeight(this.primaryStage.height - deltay)) {
this.primaryStage.y = this.primaryStage.y + deltay
}
this.setStageWidth(this.primaryStage.width + deltax)
mouseEvent.consume()
} else if (Cursor.SE_RESIZE == cursor) {
this.setStageWidth(this.primaryStage.width + deltax)
this.setStageHeight(this.primaryStage.height + deltay)
mouseEvent.consume()
} else if (Cursor.S_RESIZE == cursor) {
this.setStageHeight(this.primaryStage.height + deltay)
mouseEvent.consume()
} else if (Cursor.W_RESIZE == cursor) {
if (this.setStageWidth(this.primaryStage.width - deltax)) {
this.primaryStage.x = this.primaryStage.x + deltax
}
mouseEvent.consume()
} else if (Cursor.SW_RESIZE == cursor) {
if (this.setStageWidth(this.primaryStage.width - deltax)) {
this.primaryStage.x = this.primaryStage.x + deltax
}
this.setStageHeight(this.primaryStage.height + deltay)
mouseEvent.consume()
} else if (Cursor.NW_RESIZE == cursor) {
if (this.setStageWidth(this.primaryStage.width - deltax)) {
this.primaryStage.x = this.primaryStage.x + deltax
}
if (this.setStageHeight(this.primaryStage.height - deltay)) {
this.primaryStage.y = this.primaryStage.y + deltay
}
mouseEvent.consume()
} else if (Cursor.N_RESIZE == cursor) {
if (this.setStageHeight(this.primaryStage.height - deltay)) {
this.primaryStage.y = this.primaryStage.y + deltay
}
mouseEvent.consume()
} else if (this.allowMove) {
this.primaryStage.x = mouseEvent.screenX - this.xOffset
this.primaryStage.y = mouseEvent.screenY - this.yOffset
mouseEvent.consume()
}
}
}
}
}
private fun updateInitMouseValues(mouseEvent: MouseEvent) {
this.initX = mouseEvent.screenX
this.initY = mouseEvent.screenY
this.xOffset = mouseEvent.sceneX
this.yOffset = mouseEvent.sceneY
}
private fun isRightEdge(x: Double, y: Double, boundsInParent: Bounds): Boolean {
return x < this.width && x > this.width - this.contentPlaceHolder.snappedLeftInset()
}
private fun isTopEdge(x: Double, y: Double, boundsInParent: Bounds): Boolean {
return y >= 0.0 && y < this.contentPlaceHolder.snappedLeftInset()
}
private fun isBottomEdge(x: Double, y: Double, boundsInParent: Bounds): Boolean {
return y < this.height && y > this.height - this.contentPlaceHolder.snappedLeftInset()
}
private fun isLeftEdge(x: Double, y: Double, boundsInParent: Bounds): Boolean {
return x >= 0.0 && x < this.contentPlaceHolder.snappedLeftInset()
}
internal fun setStageWidth(width: Double): Boolean {
var width = width
if (width >= this.primaryStage.minWidth && width >= this.titleContainer.minWidth) {
this.primaryStage.width = width
this.initX = this.newX
return true
} else {
if (width >= this.primaryStage.minWidth && width <= this.titleContainer.minWidth) {
width = this.titleContainer.minWidth
this.primaryStage.width = width
}
return false
}
}
internal fun setStageHeight(height: Double): Boolean {
var height = height
if (height >= this.primaryStage.minHeight && height >= this.titleContainer.height) {
this.primaryStage.height = height
this.initY = this.newY
return true
} else {
if (height >= this.primaryStage.minHeight && height <= this.titleContainer.height) {
height = this.titleContainer.height
this.primaryStage.height = height
}
return false
}
}
fun setOnCloseButtonAction(onCloseButtonAction: Runnable) {
this.onCloseButtonAction.set(onCloseButtonAction)
}
fun customMaximizeProperty(): BooleanProperty {
return this.customMaximize
}
var isCustomMaximize: Boolean
get() = this.customMaximizeProperty().get()
set(customMaximize) = this.customMaximizeProperty().set(customMaximize)
fun setMaximized(maximized: Boolean) {
if (this.maximized != maximized) {
Platform.runLater { this.btnMax.fire() }
}
}
fun setContent(content: Node) {
this.contentPlaceHolder.children.setAll(*arrayOf(content))
}
}

View File

@@ -0,0 +1,89 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui
import com.jfoenix.concurrency.JFXUtilities
import javafx.animation.Animation
import javafx.animation.KeyFrame
import javafx.animation.Timeline
import javafx.event.ActionEvent
import javafx.event.EventHandler
import javafx.fxml.FXMLLoader
import javafx.scene.Node
import javafx.scene.control.ListView
import javafx.scene.control.ScrollBar
import javafx.scene.input.MouseEvent
import javafx.scene.input.ScrollEvent
import javafx.util.Duration
fun Node.loadFXML(absolutePath: String) {
val fxmlLoader = FXMLLoader(this.javaClass.getResource(absolutePath))
fxmlLoader.setRoot(this)
fxmlLoader.setController(this)
fxmlLoader.load<Any>()
}
fun ListView<*>.smoothScrolling() {
skinProperty().addListener { _ ->
val bar = lookup(".scroll-bar") as ScrollBar
val virtualFlow = lookup(".virtual-flow")
val frictions = doubleArrayOf(0.99, 0.1, 0.05, 0.04, 0.03, 0.02, 0.01, 0.04, 0.01, 0.008, 0.008, 0.008, 0.008, 0.0006, 0.0005, 0.00003, 0.00001)
val pushes = doubleArrayOf(1.0)
val derivatives = DoubleArray(frictions.size)
val timeline = Timeline()
bar.addEventHandler(MouseEvent.DRAG_DETECTED) { timeline.stop() }
val scrollEventHandler = EventHandler<ScrollEvent> { event ->
if (event.eventType == ScrollEvent.SCROLL) {
val direction = if (event.deltaY > 0) -1 else 1
for (i in pushes.indices) {
derivatives[i] += direction * pushes[i]
}
if (timeline.status == Animation.Status.STOPPED) {
timeline.play()
}
event.consume()
}
}
bar.addEventHandler(ScrollEvent.ANY, scrollEventHandler)
virtualFlow.onScroll = scrollEventHandler
timeline.keyFrames.add(KeyFrame(Duration.millis(3.0), EventHandler<ActionEvent> {
for (i in derivatives.indices) {
derivatives[i] *= frictions[i]
}
for (i in 1..derivatives.size - 1) {
derivatives[i] += derivatives[i - 1]
}
val dy = derivatives[derivatives.size - 1]
val height = layoutBounds.height
bar.value = Math.min(Math.max(bar.value + dy / height, 0.0), 1.0)
if (Math.abs(dy) < 0.001) {
timeline.stop()
}
requestLayout()
}))
timeline.cycleCount = Animation.INDEFINITE
}
}
fun runOnUiThread(runnable: () -> Unit) = {
JFXUtilities.runInFX(runnable)
}

View File

@@ -0,0 +1,125 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui
import com.jfoenix.controls.JFXButton
import com.jfoenix.controls.JFXComboBox
import com.jfoenix.controls.JFXListCell
import com.jfoenix.controls.JFXListView
import javafx.fxml.FXML
import javafx.scene.Node
import javafx.scene.layout.Pane
import javafx.scene.layout.StackPane
import org.jackhuang.hmcl.setting.VersionSetting
import org.jackhuang.hmcl.ui.animation.ContainerAnimations
import org.jackhuang.hmcl.ui.download.DownloadWizardProvider
import org.jackhuang.hmcl.ui.animation.TransitionHandler
import org.jackhuang.hmcl.ui.wizard.Wizard
/**
* @see /assets/fxml/main.fxml
*/
class MainController {
/**
* A combo box that allows user to select Minecraft directory.
*/
@FXML lateinit var comboProfiles: JFXComboBox<String> // TODO: JFXComboBox<Profile>
/**
* The button that is to launch the selected game version.
*/
@FXML lateinit var buttonLaunch: JFXButton
/**
* A central pane that contains popups like (global) version settings, app settings, game installations and so on.
*/
@FXML lateinit var page: StackPane
@FXML lateinit var listVersions: JFXListView<VersionSetting> // TODO: JFXListView<Version> including icon, title, game version(if equals to title, hidden)
lateinit var animationHandler: TransitionHandler
// TODO: implementing functions.
fun initialize() {
Controllers.mainController = this
animationHandler = TransitionHandler(page)
listVersions.items.add(VersionSetting("1"))
listVersions.items.add(VersionSetting("2"))
listVersions.items.add(VersionSetting("3"))
listVersions.items.add(VersionSetting("4"))
listVersions.items.add(VersionSetting("5"))
listVersions.items.add(VersionSetting("6"))
listVersions.items.add(VersionSetting("7"))
listVersions.items.add(VersionSetting("8"))
listVersions.items.add(VersionSetting("9"))
listVersions.items.add(VersionSetting("10"))
listVersions.items.add(VersionSetting("11"))
listVersions.items.add(VersionSetting("12"))
listVersions.setCellFactory {
object : JFXListCell<VersionSetting>() {
override fun updateItem(item: VersionSetting?, empty: Boolean) {
super.updateItem(item, empty)
if (item == null || empty) return
val g = VersionListItem(item, item.gameVersion)
g.onSettingsButtonClicked {
setContentPage(Controllers.versionPane)
Controllers.versionController.loadVersionSetting(g.setting)
}
graphic = g
}
}
}
listVersions.setOnMouseClicked {
if (it.clickCount == 2) {
setContentPage(Controllers.versionPane)
Controllers.versionController.loadVersionSetting(listVersions.selectionModel.selectedItem)
} else
it.consume()
}
comboProfiles.items.add("SA")
comboProfiles.items.add("SB")
comboProfiles.items.add("SC")
comboProfiles.items.add("SD")
comboProfiles.items.add("SE")
comboProfiles.items.add("SF")
comboProfiles.items.add("SG")
comboProfiles.items.add("SH")
comboProfiles.items.add("SI")
comboProfiles.items.add("SJ")
comboProfiles.items.add("SK")
listVersions.smoothScrolling()
}
private val empty = Pane()
fun setContentPage(node: Node?) {
animationHandler.setContent(node ?: empty, ContainerAnimations.FADE.animationProducer)
}
fun installNewVersion() {
setContentPage(Wizard.createWizard("Install New Game", DownloadWizardProvider()))
}
}

View File

@@ -0,0 +1,57 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui
import javafx.fxml.FXMLLoader
import javafx.scene.Group
import javafx.scene.Node
import javafx.scene.shape.SVGPath
import kotlin.coroutines.experimental.EmptyCoroutineContext.plus
object SVG {
val svgNames = setOf("gear")
val svgs: Map<String, Group>
init {
val svgsImpl = HashMap<String, Group>()
for (svgName in svgNames) {
svgsImpl[svgName] = FXMLLoader(Controllers::class.java.getResource("/assets/svg/$svgName.fxml")).load()
}
svgs = svgsImpl
}
private fun createSVGPath(d: String, fill: String = "black", width: Double = 20.0, height: Double = 20.0): Node {
val path = SVGPath()
path.styleClass += "svg"
path.content = d
path.style = "-fx-fill: $fill;"
val svg = Group(path)
val scale = minOf(width / svg.boundsInParent.width, height / svg.boundsInParent.height)
svg.scaleX = scale
svg.scaleY = scale
svg.maxWidth(width)
return svg
}
fun gear(): Node = createSVGPath("M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z")
fun back(fill: String = "white"): Node = createSVGPath("M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z", fill)
fun close(fill: String = "white"): Node = createSVGPath("M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z", fill)
fun dotsVertical(fill: String = "white"): Node = createSVGPath("M12,16A2,2 0 0,1 14,18A2,2 0 0,1 12,20A2,2 0 0,1 10,18A2,2 0 0,1 12,16M12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12A2,2 0 0,1 12,10M12,4A2,2 0 0,1 14,6A2,2 0 0,1 12,8A2,2 0 0,1 10,6A2,2 0 0,1 12,4Z", fill)
}

View File

@@ -0,0 +1,73 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui
import com.jfoenix.controls.JFXButton
import com.jfoenix.controls.JFXScrollPane
import com.jfoenix.controls.JFXTextField
import javafx.fxml.FXML
import javafx.scene.control.Label
import javafx.scene.control.ScrollPane
import javafx.scene.layout.ColumnConstraints
import javafx.scene.layout.GridPane
import javafx.scene.layout.Priority
import javafx.scene.paint.Color
import javafx.stage.DirectoryChooser
import org.jackhuang.hmcl.setting.VersionSetting
class VersionController {
@FXML
lateinit var titleLabel: Label
@FXML
lateinit var backButton: JFXButton
@FXML
lateinit var scroll: ScrollPane
@FXML
lateinit var settingsPane: GridPane
@FXML
lateinit var txtGameDir: JFXTextField
fun initialize() {
Controllers.versionController = this
settingsPane.columnConstraints.addAll(
ColumnConstraints(),
ColumnConstraints().apply { hgrow = Priority.ALWAYS },
ColumnConstraints()
)
backButton.ripplerFill = Color.WHITE
backButton.setOnMouseClicked {
Controllers.navigate(null)
}
JFXScrollPane.smoothScrolling(scroll)
}
fun loadVersionSetting(version: VersionSetting) {
titleLabel.text = version.name
}
fun onExploreJavaDir() {
val chooser = DirectoryChooser()
chooser.title = "Selecting Java Directory"
val selectedDir = chooser.showDialog(Controllers.stage)
if (selectedDir != null)
txtGameDir.text = selectedDir.absolutePath
}
}

View File

@@ -0,0 +1,49 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui
import javafx.fxml.FXML
import javafx.scene.control.Label
import javafx.scene.layout.BorderPane
import org.jackhuang.hmcl.setting.VersionSetting
class VersionListItem(val setting: VersionSetting, val gameVersion: String) : BorderPane() {
@FXML lateinit var lblVersionName: Label
@FXML lateinit var lblGameVersion: Label
private var handler: () -> Unit = {}
init {
loadFXML("/assets/fxml/version-list-item.fxml")
lblVersionName.text = setting.name
lblGameVersion.text = gameVersion
}
fun onSettings() {
handler()
}
fun onLaunch() {
}
fun onSettingsButtonClicked(handler: () -> Unit) {
this.handler = handler
}
}

View File

@@ -0,0 +1,28 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.animation
import javafx.scene.Node
import javafx.scene.layout.Pane
import javafx.util.Duration
interface AnimationHandler {
val snapshot: Node
val duration: Duration
val view: Pane
}

View File

@@ -0,0 +1,99 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.animation
import javafx.animation.Interpolator
import javafx.animation.KeyFrame
import javafx.animation.KeyValue
import javafx.util.Duration
enum class ContainerAnimations(val animationProducer: (AnimationHandler) -> List<KeyFrame>) {
/**
* None
*/
NONE({
emptyList()
}),
/**
* A fade between the old and new view
*/
FADE({ c ->
listOf(
KeyFrame(Duration.ZERO,
KeyValue(c.snapshot.opacityProperty(), 1.0, Interpolator.EASE_BOTH)),
KeyFrame(c.duration,
KeyValue(c.snapshot.opacityProperty(), 0.0, Interpolator.EASE_BOTH))
)
}),
/**
* A zoom effect
*/
ZOOM_IN({ c ->
listOf(
KeyFrame(Duration.ZERO,
KeyValue(c.snapshot.scaleXProperty(), 1, Interpolator.EASE_BOTH),
KeyValue(c.snapshot.scaleYProperty(), 1, Interpolator.EASE_BOTH),
KeyValue(c.snapshot.opacityProperty(), 1.0, Interpolator.EASE_BOTH)),
KeyFrame(c.duration,
KeyValue(c.snapshot.scaleXProperty(), 4, Interpolator.EASE_BOTH),
KeyValue(c.snapshot.scaleYProperty(), 4, Interpolator.EASE_BOTH),
KeyValue(c.snapshot.opacityProperty(), 0, Interpolator.EASE_BOTH))
)
}),
/**
* A zoom effect
*/
ZOOM_OUT({ c ->
listOf(
KeyFrame(Duration.ZERO,
KeyValue(c.snapshot.scaleXProperty(), 1, Interpolator.EASE_BOTH),
KeyValue(c.snapshot.scaleYProperty(), 1, Interpolator.EASE_BOTH),
KeyValue(c.snapshot.opacityProperty(), 1.0, Interpolator.EASE_BOTH)),
KeyFrame(c.duration,
KeyValue(c.snapshot.scaleXProperty(), 0, Interpolator.EASE_BOTH),
KeyValue(c.snapshot.scaleYProperty(), 0, Interpolator.EASE_BOTH),
KeyValue(c.snapshot.opacityProperty(), 0, Interpolator.EASE_BOTH))
)
}),
/**
* A swipe effect
*/
SWIPE_LEFT({ c ->
listOf(
KeyFrame(Duration.ZERO,
KeyValue(c.view.translateXProperty(), c.view.getWidth(), Interpolator.EASE_BOTH),
KeyValue(c.snapshot.translateXProperty(), -c.view.getWidth(), Interpolator.EASE_BOTH)),
KeyFrame(c.duration,
KeyValue(c.view.translateXProperty(), 0, Interpolator.EASE_BOTH),
KeyValue(c.snapshot.translateXProperty(), -c.view.getWidth(), Interpolator.EASE_BOTH)
))
}),
/**
* A swipe effect
*/
SWIPE_RIGHT({ c ->
listOf(
KeyFrame(Duration.ZERO,
KeyValue(c.view.translateXProperty(), -c.view.getWidth(), Interpolator.EASE_BOTH),
KeyValue(c.snapshot.translateXProperty(), c.view.getWidth(), Interpolator.EASE_BOTH)),
KeyFrame(c.duration,
KeyValue(c.view.translateXProperty(), 0, Interpolator.EASE_BOTH),
KeyValue(c.snapshot.translateXProperty(), c.view.getWidth(), Interpolator.EASE_BOTH))
)
})
}

View File

@@ -0,0 +1,81 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.animation
import javafx.animation.KeyFrame
import javafx.animation.Timeline
import javafx.event.EventHandler
import javafx.scene.Node
import javafx.scene.SnapshotParameters
import javafx.scene.image.ImageView
import javafx.scene.image.WritableImage
import javafx.scene.layout.StackPane
import javafx.util.Duration
class TransitionHandler(override val view: StackPane): AnimationHandler {
private var animation: Timeline? = null
override val snapshot = ImageView().apply {
isPreserveRatio = true
isSmooth = true
}
override lateinit var duration: Duration
private set
fun setContent(newView: Node, transition: (TransitionHandler) -> List<KeyFrame>, duration: Duration = Duration.millis(320.0)) {
this.duration = duration
val prevAnimation = animation
if (prevAnimation != null)
prevAnimation.stop()
updateContent(newView)
val nowAnimation = Timeline().apply {
keyFrames.addAll(transition(this@TransitionHandler))
keyFrames.add(KeyFrame(duration, EventHandler {
snapshot.image = null
snapshot.x = 0.0
snapshot.y = 0.0
snapshot.isVisible = false
}))
}
nowAnimation.play()
animation = nowAnimation
}
private fun updateContent(newView: Node) {
if (view.width > 0 && view.height > 0) {
val image = view.snapshot(SnapshotParameters(), null)
val x = (image.width - view.width) / 2
val y = image.height - view.height
val newImage = WritableImage(image.pixelReader, x.toInt(), y.toInt(), view.width.toInt(), view.height.toInt())
snapshot.image = newImage
snapshot.fitWidth = newImage.width
snapshot.fitHeight = newImage.height
} else
snapshot.image = null
snapshot.isVisible = true
snapshot.opacity = 1.0
view.children.setAll(snapshot)
view.children.add(newView)
snapshot.toFront()
}
}

View File

@@ -0,0 +1,48 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.download
import javafx.scene.Node
import javafx.scene.layout.Pane
import org.jackhuang.hmcl.download.BMCLAPIDownloadProvider
import org.jackhuang.hmcl.ui.wizard.WizardController
import org.jackhuang.hmcl.ui.wizard.WizardProvider
class DownloadWizardProvider(): WizardProvider() {
override fun finish(settings: Map<String, Any>): Any? {
println(settings)
return null
}
override fun createPage(controller: WizardController, step: Int, settings: Map<String, Any>): Node {
return when (step) {
0 -> InstallTypePage(controller)
1 -> when (settings[InstallTypePage.INSTALL_TYPE]) {
0 -> VersionsPage(controller, "", BMCLAPIDownloadProvider, "game", { controller.onNext(InstallersPage(controller, BMCLAPIDownloadProvider)) })
else -> Pane()
}
else -> throw IllegalStateException()
}
}
override fun cancel(): Boolean {
return true
}
}

View File

@@ -0,0 +1,50 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.download
import com.jfoenix.controls.JFXListView
import javafx.fxml.FXML
import javafx.scene.layout.StackPane
import org.jackhuang.hmcl.ui.loadFXML
import org.jackhuang.hmcl.ui.wizard.WizardController
import org.jackhuang.hmcl.ui.wizard.WizardPage
class InstallTypePage(private val controller: WizardController): StackPane(), WizardPage {
@FXML lateinit var list: JFXListView<Any>
init {
loadFXML("/assets/fxml/download/dltype.fxml")
list.selectionModel.selectedIndexProperty().addListener { _, _, newValue ->
controller.settings[INSTALL_TYPE] = newValue
controller.onNext()
}
}
override fun cleanup(settings: MutableMap<String, Any>) {
settings.remove(INSTALL_TYPE)
}
override val title: String
get() = "Select an operation"
companion object {
const val INSTALL_TYPE: String = "INSTALL_TYPE"
}
}

View File

@@ -0,0 +1,78 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.download
import com.jfoenix.controls.JFXListView
import javafx.fxml.FXML
import javafx.scene.control.Label
import javafx.scene.layout.StackPane
import org.jackhuang.hmcl.download.DownloadProvider
import org.jackhuang.hmcl.ui.loadFXML
import org.jackhuang.hmcl.ui.wizard.WizardController
import org.jackhuang.hmcl.ui.wizard.WizardPage
class InstallersPage(private val controller: WizardController, private val downloadProvider: DownloadProvider): StackPane(), WizardPage {
@FXML lateinit var list: JFXListView<VersionsPageItem>
@FXML lateinit var lblGameVersion: Label
@FXML lateinit var lblForge: Label
@FXML lateinit var lblLiteLoader: Label
@FXML lateinit var lblOptiFine: Label
init {
loadFXML("/assets/fxml/download/installers.fxml")
list.selectionModel.selectedIndexProperty().addListener { _, _, newValue ->
controller.settings[INSTALLER_TYPE] = newValue
controller.onNext(when (newValue){
0 -> VersionsPage(controller, controller.settings["game"] as String, downloadProvider, "forge") { controller.onPrev(false) }
1 -> VersionsPage(controller, controller.settings["game"] as String, downloadProvider, "liteloader") { controller.onPrev(false) }
2 -> VersionsPage(controller, controller.settings["game"] as String, downloadProvider, "optifine") { controller.onPrev(false) }
else -> throw IllegalStateException()
})
}
}
override val title: String
get() = "Choose a game version"
override fun onNavigate(settings: MutableMap<String, Any>) {
lblGameVersion.text = "Current Game Version: ${controller.settings["game"]}"
if (controller.settings.containsKey("forge"))
lblForge.text = "Forge Versoin: ${controller.settings["forge"]}"
else
lblForge.text = "Forge not installed"
if (controller.settings.containsKey("liteloader"))
lblLiteLoader.text = "LiteLoader Versoin: ${controller.settings["liteloader"]}"
else
lblLiteLoader.text = "LiteLoader not installed"
if (controller.settings.containsKey("optifine"))
lblOptiFine.text = "OptiFine Versoin: ${controller.settings["optifine"]}"
else
lblOptiFine.text = "OptiFine not installed"
}
override fun cleanup(settings: MutableMap<String, Any>) {
settings.remove(INSTALLER_TYPE)
}
companion object {
val INSTALLER_TYPE = "INSTALLER_TYPE"
}
}

View File

@@ -0,0 +1,65 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.download
import com.jfoenix.controls.JFXListView
import com.jfoenix.controls.JFXSpinner
import javafx.fxml.FXML
import javafx.scene.layout.StackPane
import org.jackhuang.hmcl.download.RemoteVersion
import org.jackhuang.hmcl.download.DownloadProvider
import org.jackhuang.hmcl.task.Scheduler
import org.jackhuang.hmcl.ui.animation.ContainerAnimations
import org.jackhuang.hmcl.ui.animation.TransitionHandler
import org.jackhuang.hmcl.ui.loadFXML
import org.jackhuang.hmcl.ui.wizard.WizardController
import org.jackhuang.hmcl.ui.wizard.WizardPage
class VersionsPage(private val controller: WizardController, private val gameVersion: String, private val downloadProvider: DownloadProvider, private val libraryId: String, private val callback: () -> Unit): StackPane(), WizardPage {
@FXML lateinit var list: JFXListView<VersionsPageItem>
@FXML lateinit var spinner: JFXSpinner
val transitionHandler = TransitionHandler(this)
private val versionList = downloadProvider.getVersionListById(libraryId)
init {
loadFXML("/assets/fxml/download/versions.fxml")
children.setAll(spinner)
list.selectionModel.selectedItemProperty().addListener { _, _, newValue ->
controller.settings[libraryId] = newValue.remoteVersion.selfVersion
callback()
}
versionList.refreshAsync(downloadProvider).subscribe(Scheduler.JAVAFX) {
val versions = ArrayList(versionList.getVersions(gameVersion))
versions.sortWith(RemoteVersion)
for (version in versions) {
list.items.add(VersionsPageItem(version))
}
transitionHandler.setContent(list, ContainerAnimations.FADE.animationProducer)
}
}
override val title: String
get() = "Choose a game version"
override fun cleanup(settings: MutableMap<String, Any>) {
settings.remove(libraryId)
}
}

View File

@@ -0,0 +1,38 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.download
import javafx.fxml.FXML
import javafx.scene.control.Label
import javafx.scene.layout.BorderPane
import org.jackhuang.hmcl.download.RemoteVersion
import org.jackhuang.hmcl.ui.loadFXML
class VersionsPageItem(val remoteVersion: RemoteVersion<*>) : BorderPane() {
@FXML lateinit var lblSelfVersion: Label
@FXML lateinit var lblGameVersion: Label
private var handler: () -> Unit = {}
init {
loadFXML("/assets/fxml/download/versions-list-item.fxml")
lblSelfVersion.text = remoteVersion.selfVersion
lblGameVersion.text = remoteVersion.gameVersion
}
}

View File

@@ -0,0 +1,124 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.wizard
import com.jfoenix.concurrency.JFXUtilities
import com.jfoenix.controls.JFXButton
import com.jfoenix.controls.JFXProgressBar
import com.jfoenix.controls.JFXToolbar
import javafx.fxml.FXML
import javafx.scene.Node
import javafx.scene.control.Label
import javafx.scene.layout.StackPane
import javafx.scene.layout.VBox
import org.jackhuang.hmcl.ui.Controllers
import org.jackhuang.hmcl.ui.animation.TransitionHandler
import org.jackhuang.hmcl.ui.loadFXML
import kotlin.concurrent.thread
internal class DefaultWizardDisplayer(private val prefix: String, wizardProvider: WizardProvider) : StackPane(), WizardDisplayer {
val wizardController = WizardController(this, wizardProvider)
lateinit var transitionHandler: TransitionHandler
@FXML lateinit var root: StackPane
@FXML lateinit var closeButton: JFXButton
@FXML lateinit var backButton: JFXButton
@FXML lateinit var toolbar: JFXToolbar
/**
* Only shown if it is needed in now step.
*/
@FXML lateinit var refreshButton: JFXButton
@FXML lateinit var titleLabel: Label
init {
loadFXML("/assets/fxml/wizard.fxml")
toolbar.effect = null
}
fun initialize() {
transitionHandler = TransitionHandler(root)
wizardController.onStart()
}
fun back() {
wizardController.onPrev(true)
}
fun close() {
wizardController.onCancel()
Controllers.navigate(null)
}
override fun navigateTo(page: Node, nav: Navigation.NavigationDirection) {
backButton.isDisable = !wizardController.canPrev()
transitionHandler.setContent(page, nav.animation.animationProducer)
val title = if (prefix.isEmpty()) "" else "$prefix - "
if (page is WizardPage)
titleLabel.text = title + page.title
}
override fun handleDeferredWizardResult(settings: Map<String, Any>, deferredResult: DeferredWizardResult) {
val vbox = VBox()
val progressBar = JFXProgressBar()
val label = Label()
progressBar.maxHeight = 10.0
vbox.children += progressBar
vbox.children += label
root.children.setAll(progressBar)
thread {
deferredResult.start(settings, object : ResultProgressHandle {
private var running = true
override fun setProgress(currentStep: Int, totalSteps: Int) {
progressBar.progress = 1.0 * currentStep / totalSteps
}
override fun setProgress(description: String, currentStep: Int, totalSteps: Int) {
label.text = description
progressBar.progress = 1.0 * currentStep / totalSteps
}
override fun setBusy(description: String) {
progressBar.progress = JFXProgressBar.INDETERMINATE_PROGRESS
}
override fun finished(result: Any) {
running = false
}
override fun failed(message: String, canNavigateBack: Boolean) {
label.text = message
running = false
}
override val isRunning: Boolean
get() = running
})
JFXUtilities.runInFX {
navigateTo(Label("Successful"), Navigation.NavigationDirection.FINISH)
}
}
}
}

View File

@@ -0,0 +1,24 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.wizard
abstract class DeferredWizardResult(val canAbort: Boolean = false) {
abstract fun start(settings: Map<String, Any>, progressHandle: ResultProgressHandle)
open fun abort() { }
}

View File

@@ -0,0 +1,38 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.wizard
import org.jackhuang.hmcl.ui.animation.ContainerAnimations
interface Navigation {
fun onStart()
fun onNext()
fun onPrev(cleanUp: Boolean)
fun canPrev(): Boolean
fun onFinish()
fun onCancel()
enum class NavigationDirection(val animation: ContainerAnimations) {
START(ContainerAnimations.NONE),
PREVIOUS(ContainerAnimations.SWIPE_RIGHT),
NEXT(ContainerAnimations.SWIPE_LEFT),
FINISH(ContainerAnimations.SWIPE_LEFT),
IN(ContainerAnimations.ZOOM_IN),
OUT(ContainerAnimations.ZOOM_OUT)
}
}

View File

@@ -0,0 +1,104 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.wizard
/**
* A controller for the progress bar shown in the user interface. Used in
* conjunction then `DeferredWizardResult` for cases where at
* the conclusion of the wizard, the work to create the final wizard result
* will take a while and needs to happen on a background thread.
* @author Tim Boudreau
*/
interface ResultProgressHandle {
/**
* Set the current position and total number of steps. Note it is
* inadvisable to be holding any locks when calling this method, as it
* may immediately update the GUI using
* `EventQueue.invokeAndWait()`.
* @param currentStep the current step in the progress of computing the
* * result.
* *
* @param totalSteps the total number of steps. Must be greater than
* * or equal to currentStep.
*/
fun setProgress(currentStep: Int, totalSteps: Int)
/**
* Set the current position and total number of steps, and description
* of what the computation is doing. Note it is
* inadvisable to be holding any locks when calling this method, as it
* may immediately update the GUI using
* `EventQueue.invokeAndWait()`.
* @param description Text to describe what is being done, which can
* * be displayed in the UI.
* *
* @param currentStep the current step in the progress of computing the
* * result.
* *
* @param totalSteps the total number of steps. Must be greater than
* * or equal to currentStep.
*/
fun setProgress(description: String, currentStep: Int, totalSteps: Int)
/**
* Set the status as "busy" - a rotating icon will be displayed instead
* of a percent complete progress bar.
* Note it is inadvisable to be holding any locks when calling this method, as it
* may immediately update the GUI using
* `EventQueue.invokeAndWait()`.
* @param description Text to describe what is being done, which can
* * be displayed in the UI.
*/
fun setBusy(description: String)
/**
* Call this method when the computation is complete, and pass in the
* final result of the computation. The method doing the computation
* (`DeferredWizardResult.start()` or something it
* called) should exit immediately after calling this method. If the
* `failed()` method is called after this method has been
* called, a runtime exception may be thrown.
* @param result the Object which was computed, if any.
*/
fun finished(result: Any)
/**
* Call this method if computation fails. The message may be some text
* describing what went wrong, or null if no description.
* @param message The text to display to the user. The method
* * doing the computation (`DeferredWizardResult.start()` or something it
* * called). If the `finished()` method is called after this
* * method has been called, a runtime exception may be thrown.
* * should exit immediately after calling this method.
* * It is A description of what went wrong, or null.
* *
* @param canNavigateBack whether or not the Prev button should be
* * enabled.
*/
fun failed(message: String, canNavigateBack: Boolean)
/**
* Returns true if the computation is still running, i.e., if neither finished or failed have been called.
* @return true if there is no result yet.
*/
val isRunning: Boolean
}

View File

@@ -0,0 +1,41 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.wizard
import com.jfoenix.controls.JFXListView
import com.jfoenix.controls.JFXTextArea
import javafx.scene.Node
class Summary(
/**
* The component that will display the summary information
*/
val component: Node,
/**
* The object that represents the actual result of whatever that Wizard
* that created this Summary object computes, or null.
*/
val result: Any?) {
constructor(items: Array<String>, result: Any?)
: this(JFXListView<String>().apply { this.items.addAll(*items) }, result) {
}
constructor(text: String, result: Any?)
: this(JFXTextArea(text).apply { isEditable = false }, result) {
}
}

View File

@@ -0,0 +1,24 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.wizard
import javafx.scene.Node
object Wizard {
fun createWizard(namespace: String = "", provider: WizardProvider): Node = DefaultWizardDisplayer(namespace, provider)
}

View File

@@ -0,0 +1,76 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.wizard
import javafx.scene.Node
import java.util.*
class WizardController(protected val displayer: WizardDisplayer, protected val provider: WizardProvider) : Navigation {
val settings = mutableMapOf<String, Any>()
val pages = Stack<Node>()
override fun onStart() {
val page = navigatingTo(0)
pages.push(page)
displayer.navigateTo(page, Navigation.NavigationDirection.START)
}
override fun onNext() {
onNext(navigatingTo(pages.size))
}
fun onNext(page: Node) {
pages.push(page)
if (page is WizardPage)
page.onNavigate(settings)
displayer.navigateTo(page, Navigation.NavigationDirection.NEXT)
}
override fun onPrev(cleanUp: Boolean) {
val page = pages.pop()
if (cleanUp && page is WizardPage)
page.cleanup(settings)
val prevPage = pages.peek()
if (prevPage is WizardPage)
prevPage.onNavigate(settings)
displayer.navigateTo(prevPage, Navigation.NavigationDirection.PREVIOUS)
}
override fun canPrev() = pages.size > 1
override fun onFinish() {
val result = provider.finish(settings)
when (result) {
is DeferredWizardResult -> displayer.handleDeferredWizardResult(settings, result)
is Summary -> displayer.navigateTo(result.component, Navigation.NavigationDirection.NEXT)
}
}
override fun onCancel() {
}
fun navigatingTo(step: Int): Node {
return provider.createPage(this, step, settings)
}
}

View File

@@ -0,0 +1,26 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.wizard
import javafx.scene.Node
interface WizardDisplayer {
fun navigateTo(page: Node, nav: Navigation.NavigationDirection)
fun handleDeferredWizardResult(settings: Map<String, Any>, deferredResult: DeferredWizardResult)
}

View File

@@ -0,0 +1,29 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.wizard
enum class WizardNavigationResult {
PROCEED {
override val deferredComputation = false
},
DENY {
override val deferredComputation = false
};
abstract val deferredComputation: Boolean
}

View File

@@ -0,0 +1,23 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.wizard
interface WizardObserver {
fun stepsChanged(wizard: Wizard)
}

View File

@@ -0,0 +1,24 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.wizard
interface WizardPage {
fun onNavigate(settings: MutableMap<String, Any>) {}
fun cleanup(settings: MutableMap<String, Any>)
val title: String
}

View File

@@ -0,0 +1,27 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
*
* 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, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hmcl.ui.wizard
import javafx.scene.Node
abstract class WizardProvider {
abstract fun finish(settings: Map<String, Any>): Any?
abstract fun createPage(controller: WizardController, step: Int, settings: Map<String, Any>): Node
abstract fun cancel(): Boolean
}

View File

@@ -0,0 +1,394 @@
.root {
-fx-font-family: Roboto;
src: "/resources/roboto/Roboto-Regular.ttf";
}
/* Burgers Demo */
.jfx-hamburger {
-fx-spacing: 5;
-fx-cursor: hand;
}
.jfx-hamburger StackPane {
-fx-pref-width: 40px;
-fx-pref-height: 7px;
-fx-background-color: #D63333;
-fx-background-radius: 5px;
}
/* Input Demo */
.text-field {
-fx-max-width: 300;
}
.jfx-text-field, .jfx-password-field {
-fx-background-color: WHITE;
-fx-font-weight: BOLD;
-fx-prompt-text-fill: #808080;
-fx-alignment: top-left;
-jfx-focus-color: #4059A9;
-jfx-unfocus-color: #4d4d4d;
-fx-max-width: 300;
}
.jfx-decorator {
-fx-decorator-color: RED;
}
.jfx-decorator .jfx-decorator-buttons-container {
-fx-background-color: -fx-decorator-color;
}
.jfx-decorator .resize-border {
-fx-border-color: -fx-decorator-color;
-fx-border-width: 0 4 4 4;
}
.jfx-text-area, .text-area {
-fx-font-weight: BOLD;
}
.jfx-text-field:error, .jfx-password-field:error, .jfx-text-area:error {
-jfx-focus-color: #D34336;
-jfx-unfocus-color: #D34336;
}
.jfx-text-field .error-label, .jfx-password-field .error-label, .jfx-text-area .error-label {
-fx-text-fill: #D34336;
-fx-font-size: 0.75em;
}
.jfx-text-field .error-icon, .jfx-password-field .error-icon, .jfx-text-area .error-icon {
-fx-text-fill: #D34336;
-fx-font-size: 1em;
}
/* Progress Bar Demo */
.progress-bar > .bar {
-fx-min-width: 500;
}
.jfx-progress-bar > .bar {
-fx-min-width: 500;
}
.jfx-progress-bar {
-fx-progress-color: #0F9D58;
-fx-stroke-width: 3;
}
/* Icons Demo */
.icon {
-fx-text-fill: #FE774D;
-fx-padding: 10;
-fx-cursor: hand;
}
.icons-rippler {
-jfx-rippler-fill: BLUE;
-jfx-mask-type: CIRCLE;
}
.icons-rippler:hover {
-fx-cursor: hand;
}
.jfx-check-box {
-fx-font-weight: BOLD;
}
.custom-jfx-check-box {
-jfx-checked-color: RED;
-jfx-unchecked-color: BLACK;
}
/* Button */
.button {
-fx-padding: 0.7em 0.57em;
-fx-font-size: 14px;
}
.button-raised {
-fx-padding: 0.7em 0.57em;
-fx-font-size: 14px;
-jfx-button-type: RAISED;
-fx-background-color: rgb(77, 102, 204);
-fx-pref-width: 200;
-fx-text-fill: WHITE;
}
/* The main scrollbar **track** CSS class */
.mylistview .scroll-bar:horizontal .track,
.mylistview .scroll-bar:vertical .track {
-fx-background-color: transparent;
-fx-border-color: transparent;
-fx-background-radius: 0em;
-fx-border-radius: 2em;
}
/* The increment and decrement button CSS class of scrollbar */
.mylistview .scroll-bar:horizontal .increment-button,
.mylistview .scroll-bar:horizontal .decrement-button {
-fx-background-color: transparent;
-fx-background-radius: 0em;
-fx-padding: 0 0 10 0;
}
/* The increment and decrement button CSS class of scrollbar */
.mylistview .scroll-bar:vertical .increment-button,
.mylistview .scroll-bar:vertical .decrement-button {
-fx-background-color: transparent;
-fx-background-radius: 0em;
-fx-padding: 0 10 0 0;
}
.mylistview .scroll-bar .increment-arrow,
.mylistview .scroll-bar .decrement-arrow {
-fx-shape: " ";
-fx-padding: 0;
}
/* The main scrollbar **thumb** CSS class which we drag every time (movable) */
.mylistview .scroll-bar:horizontal .thumb,
.mylistview .scroll-bar:vertical .thumb {
-fx-background-color: derive(black, 90%);
-fx-background-insets: 2, 0, 0;
-fx-background-radius: 2em;
}
.jfx-list-cell-container {
-fx-alignment: center-left;
}
.jfx-list-cell-container > .label {
-fx-text-fill: BLACK;
}
.jfx-list-cell:odd:selected > .jfx-rippler > StackPane, .jfx-list-cell:even:selected > .jfx-rippler > StackPane {
-fx-background-color: rgba(0, 0, 255, 0.2);
}
.jfx-list-cell {
-fx-background-insets: 0.0;
-fx-text-fill: BLACK;
}
.jfx-list-cell:odd, .jfx-list-cell:even {
-fx-background-color: WHITE;
}
.jfx-list-cell:filled:hover {
-fx-text-fill: black;
}
.jfx-list-cell .jfx-rippler {
-jfx-rippler-fill: BLUE;
}
.jfx-list-view {
-fx-background-insets: 0;
-jfx-cell-horizontal-margin: 0.0;
-jfx-cell-vertical-margin: 5.0;
-jfx-vertical-gap: 10;
-jfx-expanded: false;
-fx-pref-width: 200;
}
.jfx-toggle-button {
-jfx-toggle-color: RED;
}
.jfx-tool-bar {
-fx-font-size: 15;
-fx-background-color: #5264AE;
-fx-pref-width: 100%;
-fx-pref-height: 64px;
}
.jfx-tool-bar HBox {
-fx-alignment: center;
-fx-spacing: 25;
-fx-padding: 0 10;
}
.jfx-tool-bar Label {
-fx-text-fill: WHITE;
}
.jfx-popup-container {
-fx-background-color: WHITE;
}
.jfx-snackbar-content {
-fx-background-color: #323232;
-fx-padding: 5;
-fx-spacing: 5;
}
.jfx-snackbar-toast {
-fx-text-fill: WHITE;
}
.jfx-snackbar-action {
-fx-text-fill: #ff4081;
}
.jfx-list-cell-content-container {
-fx-alignment: center-left;
}
.jfx-list-cell-container .label {
-fx-text-fill: BLACK;
}
.combo-box-popup .list-view .jfx-list-cell:odd:selected .jfx-list-cell-container,
.combo-box-popup .list-view .jfx-list-cell:even:selected .jfx-list-cell-container {
-fx-background-color: rgba(0.0, 0.0, 255.0, 0.2);
}
.combo-box-popup .list-view .jfx-list-cell {
-fx-background-insets: 0.0;
-fx-text-fill: BLACK;
}
.combo-box-popup .list-view .jfx-list-cell:odd,
.combo-box-popup .list-view .jfx-list-cell:even {
-fx-background-color: WHITE;
}
.combo-box-popup .list-view .jfx-list-cell:filled:hover {
-fx-text-fill: black;
}
.combo-box-popup .list-view .jfx-list-cell .jfx-rippler {
-fx-rippler-fill: #5264AE;
}
/*.combo-box .combo-box-button-container{
-fx-border-color:BLACK;-fx-border-width: 0 0 1 0;
}
.combo-box .combo-box-selected-value-container{
-fx-border-color:BLACK;
} */
/*
* TREE TABLE CSS
*/
.tree-table-view {
-fx-tree-table-color: rgba(255, 0, 0, 0.2);
-fx-tree-table-rippler-color: rgba(255, 0, 0, 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; */
}
.tree-table-row-cell > .tree-disclosure-node > .arrow {
-fx-background-color: -fx-text-fill;
-fx-padding: 0.333333em 0.229em 0.333333em 0.229em; /* 4 */
-fx-shape: "M 0 -3.5 L 4 0 L 0 3.5 z";
}
.tree-table-row-cell .jfx-text-field {
-fx-focus-color: rgba(240, 40, 40);
}
.tree-table-row-group {
-fx-background-color: rgba(230, 230, 230);
}
.animated-option-button {
-fx-pref-width: 50px;
-fx-background-color: #44B449;
-fx-background-radius: 50px;
-fx-pref-height: 50px;
-fx-text-fill: white;
-fx-border-color: WHITE;
-fx-border-radius: 50px;
-fx-border-width: 4px;
}
.animated-option-sub-button {
-fx-background-color: #43609C;
}
.animated-option-sub-button2 {
-fx-background-color: rgb(203, 104, 96);
}
.tree-table-view .menu-item:focused {
-fx-background-color: -fx-tree-table-color;
}
.tree-table-view .menu-item .label {
-fx-padding: 5 0 5 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXListView?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.StackPane?>
<fx:root xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
type="StackPane"
prefHeight="400.0" prefWidth="600.0">
<JFXListView fx:id="list" styleClass="jfx-list-view" maxWidth="300" maxHeight="100">
<BorderPane mouseTransparent="true">
<left>
<Label>Install New Game</Label>
</left>
<right>
<fx:include source="/assets/svg/arrow-right.fxml"/>
</right>
</BorderPane>
<BorderPane mouseTransparent="true">
<left>
<Label>Install Modpack (CurseForge supported)</Label>
</left>
<right>
<fx:include source="/assets/svg/arrow-right.fxml"/>
</right>
</BorderPane>
</JFXListView>
</fx:root>

View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXListView?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<?import com.jfoenix.controls.JFXButton?>
<?import javafx.scene.layout.HBox?>
<fx:root xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
type="StackPane">
<BorderPane>
<top>
<HBox alignment="CENTER" style="-fx-padding: 40px;">
<Label fx:id="lblGameVersion" alignment="CENTER" />
</HBox>
</top>
<center>
<JFXListView fx:id="list" styleClass="jfx-list-view" maxHeight="150" maxWidth="300">
<BorderPane mouseTransparent="true">
<left>
<Label fx:id="lblForge">Install Forge</Label>
</left>
<right>
<fx:include source="/assets/svg/arrow-right.fxml"/>
</right>
</BorderPane>
<BorderPane mouseTransparent="true">
<left>
<Label fx:id="lblLiteLoader">Install LiteLoader</Label>
</left>
<right>
<fx:include source="/assets/svg/arrow-right.fxml"/>
</right>
</BorderPane>
<BorderPane mouseTransparent="true">
<left>
<Label fx:id="lblOptiFine">Install OptiFine</Label>
</left>
<right>
<fx:include source="/assets/svg/arrow-right.fxml"/>
</right>
</BorderPane>
</JFXListView>
</center>
<bottom>
<HBox alignment="CENTER">
<JFXButton fx:id="buttonLaunch" prefWidth="100" prefHeight="40" buttonType="RAISED" text="Install"
style="-fx-text-fill:WHITE;-fx-background-color:#5264AE;-fx-font-size:14px;"/>
</HBox>
</bottom>
</BorderPane>
</fx:root>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<fx:root xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
type="BorderPane" pickOnBounds="false">
<left>
<VBox alignment="CENTER_LEFT" mouseTransparent="true">
<Label fx:id="lblSelfVersion" style="-fx-font-size: 15;" />
</VBox>
</left>
<center>
<VBox alignment="CENTER" mouseTransparent="true">
<Label alignment="CENTER" fx:id="lblGameVersion" style="-fx-color: gray;" />
</VBox>
</center>
<right>
<fx:include source="/assets/svg/arrow-right.fxml" />
</right>
</fx:root>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXListView?>
<?import javafx.scene.layout.StackPane?>
<?import com.jfoenix.controls.JFXSpinner?>
<fx:root xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
type="StackPane"
prefHeight="400.0" prefWidth="600.0">
<JFXSpinner fx:id="spinner" style="-fx-radius:16" styleClass="materialDesign-purple, first-spinner" />
<JFXListView fx:id="list" styleClass="jfx-list-view">
</JFXListView>
</fx:root>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import com.jfoenix.controls.*?>
<BorderPane
maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
fx:controller="org.jackhuang.hmcl.ui.MainController"
style="-fx-background-color: white;"
xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1">
<center>
<StackPane fx:id="page" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
</center>
<left>
<BorderPane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<top>
<JFXComboBox fx:id="comboProfiles" prefWidth="150.0" BorderPane.alignment="CENTER" />
</top>
<center>
<StackPane>
<JFXListView fx:id="listVersions" styleClass="mylistview" style="-fx-background-color: #F1F1F1;" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
<AnchorPane pickOnBounds="false">
<JFXButton onMouseClicked="#installNewVersion" AnchorPane.bottomAnchor="16" AnchorPane.rightAnchor="16" buttonType="RAISED" prefWidth="40" prefHeight="40" style="-fx-text-fill:WHITE;-fx-background-color:#5264AE;-fx-font-size:14px;-fx-background-radius: 80px;">
<graphic>
<fx:include source="/assets/svg/plus.fxml" />
</graphic>
</JFXButton>
</AnchorPane>
</StackPane>
</center>
</BorderPane>
</left>
<bottom>
<BorderPane prefHeight="50.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<right>
<StackPane prefHeight="50.0" prefWidth="150.0" BorderPane.alignment="CENTER">
<JFXSpinner fx:id="spinner" style="-fx-radius:16" styleClass="materialDesign-purple, first-spinner" />
<JFXButton fx:id="buttonLaunch" prefWidth="100" prefHeight="40" buttonType="RAISED" text="Launch"
style="-fx-text-fill:WHITE;-fx-background-color:#5264AE;-fx-font-size:14px;"/>
</StackPane>
</right>
</BorderPane>
</bottom>
</BorderPane>

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