server

Clone or download

Modified Files

--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,35 @@
+name: Build
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+ branches:
+ - master
+
+jobs:
+ build:
+ name: Build
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Setup Java and Maven Central
+ uses: actions/setup-java@v1
+ with:
+ java-version: 11
+ server-id: ossrh
+ server-username: MAVEN_USERNAME
+ server-password: MAVEN_PASSWORD
+
+ - name: Verify project
+ run: mvn clean verify
+
+ - name: Deploy snapshots
+ env:
+ MAVEN_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
+ MAVEN_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
+ run: |
+ mvn deploy -DskipTests=true -Dgpg.skip
\ No newline at end of file
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,42 @@
+name: Release
+on:
+ push:
+ tags:
+ - '*'
+
+jobs:
+ build:
+ name: Build
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Setup Java 11
+ uses: actions/setup-java@v1
+ with:
+ java-version: 11
+
+ - name: Configure GIT
+ run: |
+ git config user.name "${{ github.event.head_commit.committer.name }}"
+ git config user.email "${{ github.event.head_commit.committer.email }}"
+
+ - name: Release artifacts
+ run: |
+ mvn deploy -DskipTests=true -B -U -Prelease
+ with:
+ server-id: ossrh
+ server-username: ${{ secrets.SONATYPE_USERNAME }}
+ server-password: ${{ secrets.SONATYPE_PASSWORD }}
+ gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
+ gpg-passphrase: ${{ secrets.GPG_PASSPHRASE }}
+
+ - name: Update new version
+ run: |
+ TAG=${GITHUB_REF/refs\/tags\//}
+ newVersion=${TAG%.*}.$((${TAG##*.} + 1))
+ mvn versions:set -DnewVersion=$newVersion-SNAPSHOT -DgenerateBackupPoms=false
+ git commit pom.xml -m "Prepare development of $newVersion"
+ git push https://${GITHUB_ACTOR}:${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY} HEAD:master
\ No newline at end of file
A README.md
+18 −0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,18 @@
+# Stream-Pi Server
+
+![version](https://img.shields.io/badge/Version-1.0.0-green)
+
+## Prerequisites
+
+- Java >= 11
+- Maven >= 3.6.3
+
+## Quick Start
+
+This project depends on the following Stream-Pi modules:
+
+- [Stream-Pi Action API](https://github.com/stream-pi/action-api)
+- [Stream-Pi Theme API](https://github.com/stream-pi/theme-api)
+- [Stream-Pi Utilities](https://github.com/stream-pi/util) - **This needs to be installed first**
+
+Build and run using `mvn clean javafx:run`
A jlink_command
+2 −0
--- /dev/null
+++ b/jlink_command
@@ -0,0 +1,2 @@
+jlink --no-header-files --no-man-pages --add-modules java.base,java.logging,java.net.http,java.scripting,jdk.jsobject,jdk.unsupported,jdk.unsupported.desktop,jdk.xml.dom,java.xml,java.management,jdk.localedata,java.sql,jdk.crypto.ec --output jre
+
M pom.xml
+138 −45
--- 'a/pom.xml'
+++ b/pom.xml
@@ -4,36 +4,32 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>com.stream_pi</groupId>
+ <groupId>com.stream-pi</groupId>
<artifactId>server</artifactId>
- <version>1.0.0</version>
+ <version>1.0.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
-
<client.plugin.version>0.1.36</client.plugin.version>
+ <javafx.version>16</javafx.version>
- <JavaFXVersion>16-ea+6</JavaFXVersion>
-
-
- <CommonsBeanUtilsVersion>1.9.4</CommonsBeanUtilsVersion>
- <CommonsConfigurationVersion>2.7</CommonsConfigurationVersion>
-
- <ActionAPIVersion>1.0.0</ActionAPIVersion>
- <ThemeAPIVersion>1.0.0</ThemeAPIVersion>
- <UtilVersion>1.0.0</UtilVersion>
- <!--CommAPIVersion>1.0.0</CommAPIVersion-->
-
- <Log4JVersion>2.14.0</Log4JVersion>
-
- <IkonliVersion>11.5.0</IkonliVersion>
- <IkonliFA5PackVersion>11.5.0</IkonliFA5PackVersion>
-
-
- <MainClassName>com.stream_pi.server.Main</MainClassName>
+ <action.api.version>1.0.0-SNAPSHOT</action.api.version>
+ <theme.api.version>1.0.0-SNAPSHOT</theme.api.version>
+ <util.version>1.0.0-SNAPSHOT</util.version>
+
+ <commons.bean.util.version>1.9.4</commons.bean.util.version>
+ <commons.configuration.version>2.7</commons.configuration.version>
+
+ <log4j.version>2.14.0</log4j.version>
+ <ikonli.version>11.5.0</ikonli.version>
+ <main.class.name>com.stream_pi.server.Main</main.class.name>
+
+ <source.plugin.version>2.2.1</source.plugin.version>
+ <javadoc.plugin.version>3.1.0</javadoc.plugin.version>
+ <gpg.plugin.version>1.6</gpg.plugin.version>
</properties>
@@ -41,61 +37,54 @@
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
- <version>${JavaFXVersion}</version>
+ <version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-media</artifactId>
- <version>${JavaFXVersion}</version>
+ <version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-fontawesome5-pack</artifactId>
- <version>${IkonliFA5PackVersion}</version>
+ <version>${ikonli.version}</version>
</dependency>
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-javafx</artifactId>
- <version>${IkonliVersion}</version>
- </dependency>
-
- <dependency>
- <groupId>org.openjfx</groupId>
- <artifactId>javafx-base</artifactId>
- <version>${JavaFXVersion}</version>
+ <version>${ikonli.version}</version>
</dependency>
<dependency>
- <groupId>com.stream_pi</groupId>
- <artifactId>actionapi</artifactId>
- <version>${ActionAPIVersion}</version>
+ <groupId>com.stream-pi</groupId>
+ <artifactId>action-api</artifactId>
+ <version>${action.api.version}</version>
</dependency>
<dependency>
- <groupId>com.stream_pi</groupId>
+ <groupId>com.stream-pi</groupId>
<artifactId>util</artifactId>
- <version>${UtilVersion}</version>
+ <version>${util.version}</version>
</dependency>
<dependency>
- <groupId>com.stream_pi</groupId>
- <artifactId>themeapi</artifactId>
- <version>${ThemeAPIVersion}</version>
+ <groupId>com.stream-pi</groupId>
+ <artifactId>theme-api</artifactId>
+ <version>${theme.api.version}</version>
</dependency>
- <dependency>
- <groupId>org.json</groupId>
- <artifactId>json</artifactId>
- <version>20201115</version>
- </dependency>
</dependencies>
<repositories>
<repository>
+ <id>sonatype-snapshots</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
+ </repository>
+ <repository>
<id>gluon-releases</id>
<url>http://nexus.gluonhq.com/nexus/content/repositories/releases/</url>
</repository>
@@ -122,12 +111,14 @@
<commandlineArgs>-DStreamPi.startupRunnerFileName=run_min -DStreamPi.startupMode=maximise</commandlineArgs>
<options>
<option>-Dglass.gtk.uiScale=1.0</option>
+ <option>-Dprism.verbose=true</option>
+ <option>-Djavafx.verbose=true</option>
+ <option>-Dprism.forceGPU=true</option>
</options>
- <mainClass>${MainClassName}</mainClass>
+ <mainClass>${main.class.name}</mainClass>
</configuration>
</plugin>
-
<plugin>
<groupId>com.gluonhq</groupId>
<artifactId>client-maven-plugin</artifactId>
@@ -143,7 +134,7 @@
<reflectionList>
<list>java.util.logging.FileHandler</list>
</reflectionList>
- <mainClass>${MainClassName}</mainClass>
+ <mainClass>${main.class.name}</mainClass>
</configuration>
</plugin>
@@ -158,7 +149,6 @@
</plugins>
</build>
-
<pluginRepositories>
<pluginRepository>
<id>gluon-releases</id>
@@ -170,4 +160,107 @@
</pluginRepository>
</pluginRepositories>
+ <profiles>
+ <profile>
+ <id>release</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.2.1</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>${javadoc.plugin.version}</version>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <source>8</source>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-gpg-plugin</artifactId>
+ <version>${gpg.plugin.version}</version>
+ <executions>
+ <execution>
+ <id>sign-artifacts</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>sign</goal>
+ </goals>
+ <configuration>
+ <gpgArguments>
+ <arg>--pinentry-mode</arg>
+ <arg>loopback</arg>
+ </gpgArguments>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+ <organization>
+ <name>Stream Pi</name>
+ <url>https://www.stream-pi.com</url>
+ </organization>
+
+ <issueManagement>
+ <system>GitHub</system>
+ <url>https://github.com/Stream-Pi/client/issues</url>
+ </issueManagement>
+
+ <licenses>
+ <license>
+ <name>GPL-3.0 License</name>
+ <url>https://www.gnu.org/licenses/gpl-3.0.en.html</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <developers>
+ <developer>
+ <name>Debayan Sutradhar</name>
+ <email>debayansutradhar3@gmail.com</email>
+ <organization>Stream-Pi</organization>
+ <organizationUrl>https://www.stream-pi.com</organizationUrl>
+ </developer>
+ </developers>
+
+ <scm>
+ <url>https://github.com/stream-pi/client</url>
+ <connection>scm:git:git://github.com/stream-pi/client.git</connection>
+ <developerConnection>scm:git:ssh://git@github.com:stream-pi/client.git</developerConnection>
+ </scm>
+
+ <distributionManagement>
+ <snapshotRepository>
+ <id>ossrh</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ </snapshotRepository>
+ <repository>
+ <id>ossrh</id>
+ <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
+ </repository>
+ </distributionManagement>
+
</project>
\ No newline at end of file
--- 'a/src/main/java/com/stream_pi/server/Main.java'
+++ b/src/main/java/com/stream_pi/server/Main.java
@@ -13,8 +13,6 @@ GNU General Public License for more deta
Written by : Debayan Sutradhar (rnayabed)
*/
-
-
package com.stream_pi.server;
import com.stream_pi.server.controller.Controller;
@@ -32,16 +30,20 @@ public class Main extends Application {
* Then a new instance of controller is created, and then initialised.
*/
public void start(Stage stage) {
-
for(String eachArg : getParameters().getRaw())
{
+ if(!eachArg.startsWith("-DStreamPi"))
+ continue;
+
String[] r = eachArg.split("=");
- if(r[0].equals("-DStreamPi.startupRunnerFileName"))
- ServerInfo.getInstance().setRunnerFileName(r[1]);
- else if(r[0].equals("-DStreamPi.startupMode"))
- ServerInfo.getInstance().setStartMinimised(r[1].equals("min"));
- }
+ String arg = r[0];
+ String val = r[1];
+ if(arg.equals("-DStreamPi.startupRunnerFileName"))
+ ServerInfo.getInstance().setRunnerFileName(val);
+ else if(arg.equals("-DStreamPi.startupMode"))
+ ServerInfo.getInstance().setStartMinimised(val.equals("min"));
+ }
Controller d = new Controller();
Scene s = new Scene(d);
@@ -56,7 +58,6 @@ public class Main extends Application {
*/
public static void main(String[] args)
{
-
launch(args);
}
}
--- /dev/null
+++ b/src/main/java/com/stream_pi/server/action/ExternalPlugins.java
@@ -0,0 +1,594 @@
+/*
+Stream-Pi - Free & Open-Source Modular Cross-Platform Programmable Macropad
+Copyright (C) 2019-2021 Debayan Sutradhar (rnayabed), Samuel Quiñones (SamuelQuinones)
+
+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.
+
+Written by : Debayan Sutradhar (rnayabed)
+*/
+
+package com.stream_pi.server.action;
+
+import com.stream_pi.action_api.action.Action;
+import com.stream_pi.action_api.action.ActionType;
+import com.stream_pi.action_api.action.PropertySaver;
+import com.stream_pi.action_api.action.ServerConnection;
+import com.stream_pi.action_api.actionproperty.ServerProperties;
+import com.stream_pi.action_api.actionproperty.property.Property;
+import com.stream_pi.action_api.actionproperty.property.Type;
+import com.stream_pi.action_api.externalplugin.ExternalPlugin;
+import com.stream_pi.action_api.externalplugin.ToggleAction;
+import com.stream_pi.action_api.externalplugin.ToggleExtras;
+import com.stream_pi.util.exception.MinorException;
+import com.stream_pi.util.exception.SevereException;
+import com.stream_pi.util.exception.StreamPiException;
+import com.stream_pi.util.version.Version;
+import com.stream_pi.util.xmlconfighelper.XMLConfigHelper;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.File;
+import java.lang.module.Configuration;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReference;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ServiceLoader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+public class ExternalPlugins
+{
+ private static ExternalPlugins instance = null;
+ private final Logger logger;
+
+ private File configFile;
+ private Document document;
+
+ private static String pluginsLocation = null;
+
+
+ /**
+ * Singleton class instance getter. Creates new one, when asked for the first time
+ *
+ * @return returns instance of NormalActionPlugins (one and only, always)
+ */
+ public static synchronized ExternalPlugins getInstance()
+ {
+ if(instance == null)
+ {
+ instance = new ExternalPlugins();
+ }
+
+ return instance;
+ }
+
+ /**
+ * Sets the folder location where the plugin JARs and their dependencies are stored
+ *
+ * @param location Folder location
+ */
+ public static void setPluginsLocation(String location)
+ {
+ pluginsLocation = location;
+ }
+
+ /**
+ * Private constructor
+ */
+ private ExternalPlugins()
+ {
+ logger = Logger.getLogger(ExternalPlugins.class.getName());
+ externalPluginsHashmap = new HashMap<>();
+ }
+
+ /**
+ * init Method
+ */
+ public void init() throws SevereException, MinorException
+ {
+ registerPlugins();
+ initPlugins();
+ }
+
+ /**
+ * Used to fetch list of all external Plugins
+ *
+ * @return List of plugins
+ */
+ public List<ExternalPlugin> getPlugins()
+ {
+ return externalPlugins;
+ }
+
+ /**
+ * Returns a plugin by its module name
+ *
+ * @param name Module Name
+ * @return The plugin. If not found, then null is returned
+ */
+ public ExternalPlugin getPluginByModuleName(String name)
+ {
+ logger.info("Plugin being requested : "+name);
+ Integer index = externalPluginsHashmap.getOrDefault(name, -1);
+ if(index != -1)
+ {
+ return externalPlugins.get(index);
+ }
+
+ return null;
+ }
+
+ private List<ExternalPlugin> externalPlugins = null;
+ HashMap<String, Integer> externalPluginsHashmap;
+
+ /**
+ * Used to register plugins from plugin location
+ */
+ public void registerPlugins() throws SevereException, MinorException
+ {
+ logger.info("Registering external plugins from "+pluginsLocation+" ...");
+
+ try
+ {
+ configFile = new File(pluginsLocation+"/config.xml");
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+ document = docBuilder.parse(configFile);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new SevereException("Plugins","Error reading plugins config.xml. Cannot continue.");
+ }
+
+ ArrayList<ExternalPlugin> errorModules = new ArrayList<>();
+ ArrayList<String> errorModuleError = new ArrayList<>();
+
+ ArrayList<Action> pluginsConfigs = new ArrayList<>();
+
+ NodeList actionsNode = document.getElementsByTagName("actions").item(0).getChildNodes();
+
+ for(int i=0; i<actionsNode.getLength(); i++)
+ {
+ Node eachActionNode = actionsNode.item(i);
+
+ if(eachActionNode.getNodeType() != Node.ELEMENT_NODE ||
+ !eachActionNode.getNodeName().equals("action"))
+ continue;
+
+ Element eachActionElement = (Element) eachActionNode;
+
+ String name;
+ Version version;
+ ActionType actionType;
+ try
+ {
+ name = XMLConfigHelper.getStringProperty(eachActionElement, "module-name");
+ actionType = ActionType.valueOf(XMLConfigHelper.getStringProperty(eachActionElement, "type"));
+ version = new Version(XMLConfigHelper.getStringProperty(eachActionElement, "version"));
+ }
+ catch (Exception e)
+ {
+ logger.log(Level.WARNING, "Skipping configuration because invalid ...");
+ e.printStackTrace();
+ continue;
+ }
+
+ ServerProperties serverProperties = new ServerProperties();
+
+ NodeList serverPropertiesNodeList = eachActionElement.getElementsByTagName("properties").item(0).getChildNodes();
+
+ for(int j = 0;j<serverPropertiesNodeList.getLength();j++)
+ {
+ Node eachPropertyNode = serverPropertiesNodeList.item(j);
+
+ if(eachPropertyNode.getNodeType() != Node.ELEMENT_NODE)
+ continue;
+
+ if(!eachPropertyNode.getNodeName().equals("property"))
+ continue;
+
+
+ Element eachPropertyElement = (Element) eachPropertyNode;
+
+ try
+ {
+ Property property = new Property(XMLConfigHelper.getStringProperty(eachPropertyElement, "name"), Type.STRING);
+ property.setRawValue(XMLConfigHelper.getStringProperty(eachPropertyElement, "value"));
+
+ serverProperties.addProperty(property);
+ }
+ catch (Exception e)
+ {
+ logger.log(Level.WARNING, "Skipping property because invalid ...");
+ e.printStackTrace();
+ }
+ }
+
+ Action action = new Action(actionType);
+
+ action.setModuleName(name);
+ action.setVersion(version);
+ action.getServerProperties().set(serverProperties);
+
+ pluginsConfigs.add(action);
+ }
+
+ logger.info("Size : "+pluginsConfigs.size());
+
+ Path pluginsDir = Paths.get(pluginsLocation); // Directory with plugins JARs
+ try
+ {
+ // Search for plugins in the plugins directory
+ ModuleFinder pluginsFinder = ModuleFinder.of(pluginsDir);
+
+ // Find all names of all found plugin modules
+ List<String> p = pluginsFinder
+ .findAll()
+ .stream()
+ .map(ModuleReference::descriptor)
+ .map(ModuleDescriptor::name)
+ .collect(Collectors.toList());
+
+ // Create configuration that will resolve plugin modules
+ // (verify that the graph of modules is correct)
+ Configuration pluginsConfiguration = ModuleLayer
+ .boot()
+ .configuration()
+ .resolve(pluginsFinder, ModuleFinder.of(), p);
+
+ // Create a module layer for plugins
+ ModuleLayer layer = ModuleLayer
+ .boot()
+ .defineModulesWithOneLoader(pluginsConfiguration, ClassLoader.getSystemClassLoader());
+
+ logger.info("Loading plugins from jar ...");
+ // Now you can use the new module layer to find service implementations in it
+ externalPlugins = ServiceLoader
+ .load(layer, ExternalPlugin.class).stream()
+ .map(ServiceLoader.Provider::get)
+ .collect(Collectors.toList());
+
+ logger.info("...Done!");
+
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new MinorException("Error", "Error loading modules\n"+e.getMessage()+"\nPlease fix the errors. Other plugins wont be loaded.");
+ }
+
+
+ sortedPlugins = new HashMap<>();
+
+ for (ExternalPlugin eachPlugin : externalPlugins)
+ {
+ try
+ {
+ eachPlugin.setPropertySaver(getPropertySaver());
+ eachPlugin.setServerConnection(serverConnection);
+
+ if(eachPlugin instanceof ToggleAction)
+ ((ToggleAction) eachPlugin).setToggleExtras(getToggleExtras());
+
+
+
+ eachPlugin.initProperties();
+
+ logger.info("MODULE : "+eachPlugin.getModuleName());
+
+
+ Action foundAction = null;
+ for (Action action : pluginsConfigs)
+ {
+ if (action.getModuleName().equals(eachPlugin.getModuleName())
+ && action.getVersion().isEqual(eachPlugin.getVersion()))
+ {
+
+ foundAction = action;
+
+ List<Property> eachPluginStoredProperties = action.getServerProperties().get();
+ List<Property> eachPluginCodeProperties = eachPlugin.getServerProperties().get();
+
+ for (int i =0;i< eachPluginCodeProperties.size(); i++)
+ {
+
+ Property eachPluginCodeProperty = eachPluginCodeProperties.get(i);
+
+ Property foundProp = null;
+ for (Property eachPluginStoredProperty : eachPluginStoredProperties) {
+ if (eachPluginCodeProperty.getName().equals(eachPluginStoredProperty.getName())) {
+ eachPluginCodeProperty.setRawValue(eachPluginStoredProperty.getRawValue());
+ foundProp = eachPluginStoredProperty;
+ }
+ }
+
+ eachPluginCodeProperties.set(i, eachPluginCodeProperty);
+
+ if (foundProp != null) {
+ eachPluginStoredProperties.remove(foundProp);
+ }
+ }
+
+ eachPlugin.getServerProperties().set(eachPluginCodeProperties);
+ break;
+ }
+ }
+
+ if (foundAction != null)
+ pluginsConfigs.remove(foundAction);
+ else
+ {
+ List<Property> eachPluginStoredProperties = eachPlugin.getServerProperties().get();
+ for(Property property :eachPluginStoredProperties)
+ {
+ if(property.getType() == Type.STRING || property.getType() == Type.INTEGER || property.getType() == Type.DOUBLE)
+ property.setRawValue(property.getDefaultRawValue());
+ }
+ }
+
+ if (!sortedPlugins.containsKey(eachPlugin.getCategory())) {
+ sortedPlugins.put(eachPlugin.getCategory(), new ArrayList<>());
+ }
+ sortedPlugins.get(eachPlugin.getCategory()).add(eachPlugin);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ errorModules.add(eachPlugin);
+ errorModuleError.add(e.getMessage());
+ }
+ }
+
+ try {
+ saveServerSettings();
+ } catch (MinorException e) {
+ e.printStackTrace();
+ }
+
+ logger.log(Level.INFO, "All plugins registered!");
+
+ if(errorModules.size() > 0)
+ {
+ StringBuilder errors = new StringBuilder("The following action modules could not be loaded:");
+ for(int i = 0; i<errorModules.size(); i++)
+ {
+ externalPlugins.remove(errorModules.get(i));
+ errors.append("\n * ").append(errorModules.get(i).getModuleName()).append("\n(")
+ .append(errorModuleError.get(i)).append(")");
+ }
+ throw new MinorException("Plugins", errors.toString());
+ }
+
+ for(int i=0; i<externalPlugins.size(); i++)
+ {
+ externalPluginsHashmap.put(externalPlugins.get(i).getModuleName(), i);
+ }
+ }
+
+ /**
+ * Used to init plugins
+ */
+ public void initPlugins() throws MinorException
+ {
+ StringBuilder errors = new StringBuilder("There were errors registering the following plugins. As a result, they have been omitted : ");
+ boolean isError = false;
+
+ for(ExternalPlugin eachPlugin : externalPlugins)
+ {
+ try
+ {
+ eachPlugin.initAction();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ isError = true;
+ errors.append("\n* ")
+ .append(eachPlugin.getName())
+ .append(" - ")
+ .append(eachPlugin.getModuleName())
+ .append("\n");
+
+ if(e instanceof StreamPiException)
+ errors.append(((MinorException) e).getShortMessage());
+
+ errors.append("\n");
+ }
+ }
+
+ if(isError)
+ {
+ throw new MinorException("Plugin init error", errors.toString());
+ }
+ }
+
+ HashMap<String, ArrayList<ExternalPlugin>> sortedPlugins;
+
+ /**
+ * Gets list of sorted plugins
+ *
+ * @return Hashmap with category key, and list of plugins of each category
+ */
+ public HashMap<String, ArrayList<ExternalPlugin>> getSortedPlugins()
+ {
+ return sortedPlugins;
+ }
+
+ /**
+ * @return Gets actions element from the config.xml in plugins folder
+ */
+ private Element getActionsElement()
+ {
+ return (Element) document.getElementsByTagName("actions").item(0);
+ }
+
+ /**
+ * Saves ServerProperties of every plugin in config.xml in plugins folder
+ *
+ * @throws MinorException Thrown when failed to save settings
+ */
+ public void saveServerSettings() throws MinorException
+ {
+ XMLConfigHelper.removeChilds(getActionsElement());
+
+ for(ExternalPlugin externalPlugin : externalPlugins)
+ {
+ Element actionElement = document.createElement("action");
+ getActionsElement().appendChild(actionElement);
+
+ Element moduleNameElement = document.createElement("module-name");
+ moduleNameElement.setTextContent(externalPlugin.getModuleName());
+ actionElement.appendChild(moduleNameElement);
+
+
+ Element versionElement = document.createElement("version");
+ versionElement.setTextContent(externalPlugin.getVersion().getText());
+ actionElement.appendChild(versionElement);
+
+ Element actionTypeElement = document.createElement("type");
+ actionTypeElement.setTextContent(externalPlugin.getActionType().toString());
+ actionElement.appendChild(actionTypeElement);
+
+ Element propertiesElement = document.createElement("properties");
+ actionElement.appendChild(propertiesElement);
+
+ for(String key : externalPlugin.getServerProperties().getNames())
+ {
+ for(Property eachProperty : externalPlugin.getServerProperties().getMultipleProperties(key))
+ {
+ Element propertyElement = document.createElement("property");
+ propertiesElement.appendChild(propertyElement);
+
+ Element nameElement = document.createElement("name");
+ nameElement.setTextContent(eachProperty.getName());
+ propertyElement.appendChild(nameElement);
+
+ Element valueElement = document.createElement("value");
+ valueElement.setTextContent(eachProperty.getRawValue());
+ propertyElement.appendChild(valueElement);
+ }
+ }
+ }
+
+ save();
+ }
+
+ private PropertySaver propertySaver = null;
+
+ /**
+ * Set PropertySaver class
+ * @param propertySaver instance of PropertySaver
+ */
+ public void setPropertySaver(PropertySaver propertySaver)
+ {
+ this.propertySaver = propertySaver;
+ }
+
+ public PropertySaver getPropertySaver()
+ {
+ return propertySaver;
+ }
+
+ private ToggleExtras toggleExtras = null;
+
+ /**
+ * Set PropertySaver class
+ * @param toggleExtras instance of PropertySaver
+ */
+ public void setToggleExtras(ToggleExtras toggleExtras)
+ {
+ this.toggleExtras = toggleExtras;
+ }
+
+ public ToggleExtras getToggleExtras() {
+ return toggleExtras;
+ }
+
+ private ServerConnection serverConnection = null;
+
+ /**
+ * Set setServerConnection class
+ * @param serverConnection instance of ServerConnection
+ */
+ public void setServerConnection(ServerConnection serverConnection)
+ {
+ this.serverConnection = serverConnection;
+ }
+
+ /**
+ * Get plugin from index from list
+ *
+ * @param index of plugin
+ * @return found plugin
+ */
+ public ExternalPlugin getActionFromIndex(int index)
+ {
+ return externalPlugins.get(index);
+ }
+
+ /**
+ * Calls onShutDown method in every plugin
+ */
+ public void shutDownActions()
+ {
+ if(externalPlugins != null)
+ {
+ for(ExternalPlugin eachPlugin : externalPlugins)
+ {
+ try
+ {
+ eachPlugin.onShutDown();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ externalPlugins.clear();
+ }
+ }
+
+ /**
+ * Saves all Server Properties of each Plugin in config.xml in Plugins folder
+ * @throws MinorException thrown when failed to save
+ */
+ public void save() throws MinorException
+ {
+ try
+ {
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ Result output = new StreamResult(configFile);
+ Source input = new DOMSource(document);
+
+ transformer.transform(input, output);
+ }
+ catch (Exception e)
+ {
+ throw new MinorException("Config", "unable to save server plugins settings");
+ }
+ }
+}
--- 'a/src/main/java/com/stream_pi/server/action/NormalActionPlugins.java'
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
-Stream-Pi - Free & Open-Source Modular Cross-Platform Programmable Macropad
-Copyright (C) 2019-2021 Debayan Sutradhar (rnayabed), Samuel Quiñones (SamuelQuinones)
-
-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.
-
-Written by : Debayan Sutradhar (rnayabed)
-*/
-
-package com.stream_pi.server.action;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.transform.Result;
-import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-import com.stream_pi.actionapi.action.Action;
-import com.stream_pi.actionapi.action.ActionType;
-import com.stream_pi.actionapi.action.PropertySaver;
-import com.stream_pi.actionapi.action.ServerConnection;
-import com.stream_pi.actionapi.actionproperty.ServerProperties;
-import com.stream_pi.actionapi.actionproperty.property.Property;
-import com.stream_pi.actionapi.actionproperty.property.Type;
-import com.stream_pi.actionapi.normalaction.NormalAction;
-import com.stream_pi.util.exception.MinorException;
-import com.stream_pi.util.exception.SevereException;
-import com.stream_pi.util.exception.StreamPiException;
-import com.stream_pi.util.version.Version;
-import com.stream_pi.util.xmlconfighelper.XMLConfigHelper;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-import java.io.File;
-import java.lang.module.*;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ServiceLoader;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.stream.Collectors;
-
-import org.w3c.dom.Element;
-
-public class NormalActionPlugins
-{
- private static NormalActionPlugins instance = null;
- private final Logger logger;
-
- private File configFile;
- private Document document;
-
- private static String pluginsLocation = null;
-
-
- /**
- * Singleton class instance getter. Creates new one, when asked for the first time
- *
- * @return returns instance of NormalActionPlugins (one and only, always)
- */
- public static synchronized NormalActionPlugins getInstance()
- {
- if(instance == null)
- {
- instance = new NormalActionPlugins();
- }
-
- return instance;
- }
-
- /**
- * Sets the folder location where the plugin JARs and their dependencies are stored
- *
- * @param location Folder location
- */
- public static void setPluginsLocation(String location)
- {
- pluginsLocation = location;
- }
-
- /**
- * Private constructor
- */
- private NormalActionPlugins()
- {
- logger = Logger.getLogger(NormalActionPlugins.class.getName());
- normalPluginsHashmap = new HashMap<>();
- }
-
- /**
- * init Method
- */
- public void init() throws SevereException, MinorException
- {
- registerPlugins();
- initPlugins();
- }
-
- /**
- * Used to fetch list of all external Plugins
- *
- * @return List of plugins
- */
- public List<NormalAction> getPlugins()
- {
- return normalPlugins;
- }
-
- /**
- * Returns a plugin by its module name
- *
- * @param name Module Name
- * @return The plugin. If not found, then null is returned
- */
- public NormalAction getPluginByModuleName(String name)
- {
- logger.info("Plugin being requested : "+name);
- Integer index = normalPluginsHashmap.getOrDefault(name, -1);
- if(index != -1)
- {
- return normalPlugins.get(index);
- }
-
- return null;
- }
-
- private List<NormalAction> normalPlugins = null;
- HashMap<String, Integer> normalPluginsHashmap;
-
- /**
- * Used to register plugins from plugin location
- */
- public void registerPlugins() throws SevereException, MinorException
- {
- logger.info("Registering external plugins from "+pluginsLocation+" ...");
-
- try
- {
- configFile = new File(pluginsLocation+"/config.xml");
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
- document = docBuilder.parse(configFile);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- throw new SevereException("Plugins","Error reading plugins config.xml. Cannot continue.");
- }
-
- ArrayList<NormalAction> errorModules = new ArrayList<>();
- ArrayList<String> errorModuleError = new ArrayList<>();
-
- ArrayList<Action> pluginsConfigs = new ArrayList<>();
-
- NodeList actionsNode = document.getElementsByTagName("actions").item(0).getChildNodes();
-
- for(int i =0;i<actionsNode.getLength();i++)
- {
- Node eachActionNode = actionsNode.item(i);
-
- if(eachActionNode.getNodeType() != Node.ELEMENT_NODE)
- continue;
-
- if(!eachActionNode.getNodeName().equals("action"))
- continue;
-
- Element eachActionElement = (Element) eachActionNode;
-
-
-
- String name;
- Version version;
- try
- {
- name = XMLConfigHelper.getStringProperty(eachActionElement, "module-name");
- version = new Version(XMLConfigHelper.getStringProperty(eachActionElement, "version"));
- }
- catch (Exception e)
- {
- logger.log(Level.WARNING, "Skipping configuration because invalid ...");
- e.printStackTrace();
- continue;
- }
-
- ServerProperties serverProperties = new ServerProperties();
-
- NodeList serverPropertiesNodeList = eachActionElement.getElementsByTagName("properties").item(0).getChildNodes();
-
- for(int j = 0;j<serverPropertiesNodeList.getLength();j++)
- {
- Node eachPropertyNode = serverPropertiesNodeList.item(j);
-
-
- if(eachPropertyNode.getNodeType() != Node.ELEMENT_NODE)
- continue;
-
- if(!eachPropertyNode.getNodeName().equals("property"))
- continue;
-
-
- Element eachPropertyElement = (Element) eachPropertyNode;
-
- try
- {
- Property property = new Property(XMLConfigHelper.getStringProperty(eachPropertyElement, "name"), Type.STRING);
- property.setRawValue(XMLConfigHelper.getStringProperty(eachPropertyElement, "value"));
-
- serverProperties.addProperty(property);
- }
- catch (Exception e)
- {
- logger.log(Level.WARNING, "Skipping property because invalid ...");
- e.printStackTrace();
- }
- }
-
- Action action = new Action(ActionType.NORMAL);
-
- action.setModuleName(name);
- action.setVersion(version);
- action.getServerProperties().set(serverProperties);
-
- pluginsConfigs.add(action);
- }
-
- logger.info("Size : "+pluginsConfigs.size());
-
- Path pluginsDir = Paths.get(pluginsLocation); // Directory with plugins JARs
- try
- {
- // Search for plugins in the plugins directory
- ModuleFinder pluginsFinder = ModuleFinder.of(pluginsDir);
-
- // Find all names of all found plugin modules
- List<String> p = pluginsFinder
- .findAll()
- .stream()
- .map(ModuleReference::descriptor)
- .map(ModuleDescriptor::name)
- .collect(Collectors.toList());
-
- // Create configuration that will resolve plugin modules
- // (verify that the graph of modules is correct)
- Configuration pluginsConfiguration = ModuleLayer
- .boot()
- .configuration()
- .resolve(pluginsFinder, ModuleFinder.of(), p);
-
- // Create a module layer for plugins
- ModuleLayer layer = ModuleLayer
- .boot()
- .defineModulesWithOneLoader(pluginsConfiguration, ClassLoader.getSystemClassLoader());
-
- logger.info("Loading plugins from jar ...");
- // Now you can use the new module layer to find service implementations in it
- normalPlugins = ServiceLoader
- .load(layer, NormalAction.class).stream()
- .map(ServiceLoader.Provider::get)
- .collect(Collectors.toList());
-
- logger.info("...Done!");
-
- }
- catch (Exception e)
- {
- e.printStackTrace();
-
- throw new MinorException("Error", "Error loading modules\n"+e.getMessage()+"\nPlease fix the errors. Other plugins wont be loaded.");
- }
-
-
- sortedPlugins = new HashMap<>();
-
- for (NormalAction eachPlugin : normalPlugins)
- {
- try
- {
- eachPlugin.setPropertySaver(propertySaver);
- eachPlugin.setServerConnection(serverConnection);
- eachPlugin.initProperties();
-
- Action foundAction = null;
- for (Action action : pluginsConfigs) {
- if (action.getModuleName().equals(eachPlugin.getModuleName())
- && action.getVersion().isEqual(eachPlugin.getVersion())) {
-
- foundAction = action;
-
- List<Property> eachPluginStoredProperties = action.getServerProperties().get();
- List<Property> eachPluginCodeProperties = eachPlugin.getServerProperties().get();
-
-
- for (int i =0;i< eachPluginCodeProperties.size(); i++) {
-
- Property eachPluginCodeProperty = eachPluginCodeProperties.get(i);
-
- Property foundProp = null;
- for (Property eachPluginStoredProperty : eachPluginStoredProperties) {
- if (eachPluginCodeProperty.getName().equals(eachPluginStoredProperty.getName())) {
- eachPluginCodeProperty.setRawValue(eachPluginStoredProperty.getRawValue());
- foundProp = eachPluginStoredProperty;
- }
- }
-
- eachPluginCodeProperties.set(i, eachPluginCodeProperty);
-
- if (foundProp != null) {
- eachPluginStoredProperties.remove(foundProp);
- }
- }
-
-
- eachPlugin.getServerProperties().set(eachPluginCodeProperties);
-
- break;
- }
- }
-
- if (foundAction != null)
- pluginsConfigs.remove(foundAction);
- else
- {
- List<Property> eachPluginStoredProperties = eachPlugin.getServerProperties().get();
- for(Property property :eachPluginStoredProperties)
- {
- if(property.getType() == Type.STRING || property.getType() == Type.INTEGER || property.getType() == Type.DOUBLE)
- property.setRawValue(property.getDefaultRawValue());
- }
- }
-
-
-
- if (!sortedPlugins.containsKey(eachPlugin.getCategory())) {
- ArrayList<NormalAction> actions = new ArrayList<>();
-
- sortedPlugins.put(eachPlugin.getCategory(), actions);
- }
-
- sortedPlugins.get(eachPlugin.getCategory()).add(eachPlugin);
-
- }
- catch (Exception e)
- {
- e.printStackTrace();
- errorModules.add(eachPlugin);
- errorModuleError.add(e.getMessage());
- }
- }
-
- try {
- saveServerSettings();
- } catch (MinorException e) {
- e.printStackTrace();
- }
-
- logger.log(Level.INFO, "All plugins registered!");
-
- if(errorModules.size() > 0)
- {
- StringBuilder errors = new StringBuilder("The following action modules could not be loaded:");
- for(int i = 0; i<errorModules.size(); i++)
- {
- normalPlugins.remove(errorModules.get(i));
- errors.append("\n * ").append(errorModules.get(i).getModuleName()).append("\n(")
- .append(errorModuleError.get(i)).append(")");
- }
-
- throw new MinorException("Plugins", errors.toString());
- }
-
-
- for(int i = 0;i<normalPlugins.size();i++)
- {
- normalPluginsHashmap.put(normalPlugins.get(i).getModuleName(), i);
- }
- }
-
- /**
- * Used to init plugins
- */
- public void initPlugins() throws MinorException
- {
- StringBuilder errors = new StringBuilder("There were errors registering the following plugins. As a result, they have been omitted : ");
- boolean isError = false;
-
- for(NormalAction eachPlugin : normalPlugins)
- {
- try
- {
- eachPlugin.initAction();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- isError = true;
- errors.append("\n* ")
- .append(eachPlugin.getName())
- .append(" - ")
- .append(eachPlugin.getModuleName())
- .append("\n");
-
- if(e instanceof StreamPiException)
- errors.append(((MinorException) e).getShortMessage());
-
- errors.append("\n");
- }
- }
-
- if(isError)
- {
- throw new MinorException("Plugin init error", errors.toString());
- }
- }
-
- HashMap<String, ArrayList<NormalAction>> sortedPlugins;
-
- /**
- * Gets list of sorted plugins
- *
- * @return Hashmap with category key, and list of plugins of each category
- */
- public HashMap<String, ArrayList<NormalAction>> getSortedPlugins()
- {
- return sortedPlugins;
- }
-
- /**
- * @return Gets actions element from the config.xml in plugins folder
- */
- private Element getActionsElement()
- {
- return (Element) document.getElementsByTagName("actions").item(0);
- }
-
- /**
- * Saves ServerProperties of every plugin in config.xml in plugins folder
- *
- * @throws MinorException Thrown when failed to save settings
- */
- public void saveServerSettings() throws MinorException
- {
- XMLConfigHelper.removeChilds(getActionsElement());
-
- for(NormalAction normalAction : normalPlugins)
- {
- Element actionElement = document.createElement("action");
- getActionsElement().appendChild(actionElement);
-
- Element moduleNameElement = document.createElement("module-name");
- moduleNameElement.setTextContent(normalAction.getModuleName());
- actionElement.appendChild(moduleNameElement);
-
-
- Element versionElement = document.createElement("version");
- versionElement.setTextContent(normalAction.getVersion().getText());
- actionElement.appendChild(versionElement);
-
- Element propertiesElement = document.createElement("properties");
- actionElement.appendChild(propertiesElement);
-
- for(String key : normalAction.getServerProperties().getNames())
- {
- for(Property eachProperty : normalAction.getServerProperties().getMultipleProperties(key))
- {
- Element propertyElement = document.createElement("property");
- propertiesElement.appendChild(propertyElement);
-
- Element nameElement = document.createElement("name");
- nameElement.setTextContent(eachProperty.getName());
- propertyElement.appendChild(nameElement);
-
- Element valueElement = document.createElement("value");
- valueElement.setTextContent(eachProperty.getRawValue());
- propertyElement.appendChild(valueElement);
- }
- }
- }
-
- save();
- }
-
- private PropertySaver propertySaver = null;
-
- /**
- * Set PropertySaver class
- * @param propertySaver instance of PropertySaver
- */
- public void setPropertySaver(PropertySaver propertySaver)
- {
- this.propertySaver = propertySaver;
- }
-
- private ServerConnection serverConnection = null;
-
- /**
- * Set setServerConnection class
- * @param serverConnection instance of ServerConnection
- */
- public void setServerConnection(ServerConnection serverConnection)
- {
- this.serverConnection = serverConnection;
- }
-
- /**
- * Get plugin from index from list
- *
- * @param index of plugin
- * @return found plugin
- */
- public NormalAction getActionFromIndex(int index)
- {
- return normalPlugins.get(index);
- }
-
- /**
- * Calls onShutDown method in every plugin
- */
- public void shutDownActions()
- {
- if(normalPlugins != null)
- {
- for(NormalAction eachPlugin : normalPlugins)
- {
- try
- {
- eachPlugin.onShutDown();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- normalPlugins.clear();
- }
- }
-
- /**
- * Saves all Server Properties of each Plugin in config.xml in Plugins folder
- * @throws MinorException thrown when failed to save
- */
- public void save() throws MinorException
- {
- try
- {
- Transformer transformer = TransformerFactory.newInstance().newTransformer();
- Result output = new StreamResult(configFile);
- Source input = new DOMSource(document);
-
- transformer.transform(input, output);
- }
- catch (Exception e)
- {
- throw new MinorException("Config", "unable to save server plugins settings");
- }
- }
-}
--- 'a/src/main/java/com/stream_pi/server/client/Client.java'
+++ b/src/main/java/com/stream_pi/server/client/Client.java
@@ -25,7 +25,8 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
-public class Client {
+public class Client
+{
private String nickName;
private final SocketAddress remoteSocketAddress;
private final Platform platform;
@@ -34,7 +35,7 @@ public class Client {
private final Version themeAPIVersion;
private final ReleaseStatus releaseStatus;
- private double startupDisplayHeight, startupDisplayWidth;
+ private double displayHeight, displayWidth;
private final HashMap<String,ClientProfile> profiles;
@@ -156,34 +157,34 @@ public class Client {
return themeAPIVersion;
}
- public double getStartupDisplayHeight()
+ public double getDisplayHeight()
{
- return startupDisplayHeight;
+ return displayHeight;
}
- public double getStartupDisplayWidth()
+ public double getDisplayWidth()
{
- return startupDisplayWidth;
+ return displayWidth;
}
- public void setStartupDisplayHeight(double height)
+ public void setDisplayHeight(double height)
{
- startupDisplayHeight = height;
+ displayHeight = height;
}
- public void setStartupDisplayWidth(double width)
+ public void setDisplayWidth(double width)
{
- startupDisplayWidth = width;
+ displayWidth = width;
}
private int getMaxRows(int eachActionSize)
{
- return (int) (startupDisplayHeight / eachActionSize);
+ return (int) (displayHeight / eachActionSize);
}
public int getMaxCols(int eachActionSize)
{
- return (int) (startupDisplayWidth / eachActionSize);
+ return (int) (displayWidth / eachActionSize);
}
}
--- 'a/src/main/java/com/stream_pi/server/client/ClientProfile.java'
+++ b/src/main/java/com/stream_pi/server/client/ClientProfile.java
@@ -16,7 +16,7 @@ Written by : Debayan Sutradhar (rnayabed
package com.stream_pi.server.client;
-import com.stream_pi.actionapi.action.Action;
+import com.stream_pi.action_api.action.Action;
import java.util.HashMap;
import java.util.Set;
--- 'a/src/main/java/com/stream_pi/server/connection/ClientConnection.java'
+++ b/src/main/java/com/stream_pi/server/connection/ClientConnection.java
@@ -1,21 +1,27 @@
package com.stream_pi.server.connection;
-import com.stream_pi.actionapi.action.Action;
-import com.stream_pi.actionapi.action.ActionType;
-import com.stream_pi.actionapi.action.DisplayTextAlignment;
-import com.stream_pi.actionapi.action.Location;
-import com.stream_pi.actionapi.actionproperty.ClientProperties;
-import com.stream_pi.actionapi.actionproperty.property.Property;
-import com.stream_pi.actionapi.actionproperty.property.Type;
-import com.stream_pi.actionapi.normalaction.NormalAction;
-import com.stream_pi.server.action.NormalActionPlugins;
+import com.stream_pi.action_api.action.Action;
+import com.stream_pi.action_api.action.ActionType;
+import com.stream_pi.action_api.action.DisplayTextAlignment;
+import com.stream_pi.action_api.action.Location;
+import com.stream_pi.action_api.actionproperty.ClientProperties;
+import com.stream_pi.action_api.actionproperty.property.Property;
+import com.stream_pi.action_api.actionproperty.property.Type;
+import com.stream_pi.action_api.externalplugin.ExternalPlugin;
+import com.stream_pi.action_api.externalplugin.NormalAction;
+import com.stream_pi.action_api.externalplugin.ToggleAction;
+import com.stream_pi.action_api.otheractions.CombineAction;
+import com.stream_pi.action_api.otheractions.FolderAction;
+import com.stream_pi.server.action.ExternalPlugins;
import com.stream_pi.server.client.Client;
import com.stream_pi.server.client.ClientProfile;
import com.stream_pi.server.client.ClientTheme;
import com.stream_pi.server.info.ServerInfo;
import com.stream_pi.server.window.ExceptionAndAlertHandler;
+import com.stream_pi.server.window.dashboard.actiongridpane.ActionBox;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlertType;
+import com.stream_pi.util.comms.Message;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.exception.StreamPiException;
@@ -23,22 +29,23 @@ import com.stream_pi.util.platform.Platf
import com.stream_pi.util.platform.ReleaseStatus;
import com.stream_pi.util.version.Version;
import javafx.concurrent.Task;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
+
+import java.io.*;
import java.net.Socket;
+import java.net.SocketAddress;
+import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
-public class ClientConnection extends Thread{
+public class ClientConnection extends Thread
+{
private Socket socket;
private ServerListener serverListener;
private AtomicBoolean stop = new AtomicBoolean(false);
- private DataInputStream dis;
- private DataOutputStream dos;
+ private ObjectOutputStream oos;
+ private ObjectInputStream ois;
private Logger logger;
@@ -49,7 +56,6 @@ public class ClientConnection extends Th
public ClientConnection(Socket socket, ServerListener serverListener, ExceptionAndAlertHandler exceptionAndAlertHandler)
{
this.exceptionAndAlertHandler = exceptionAndAlertHandler;
- //actionIconsToBeSent = new ArrayList__();
this.socket = socket;
this.serverListener = serverListener;
@@ -58,8 +64,8 @@ public class ClientConnection extends Th
try
{
- dis = new DataInputStream(socket.getInputStream());
- dos = new DataOutputStream(socket.getOutputStream());
+ oos = new ObjectOutputStream(socket.getOutputStream());
+ ois = new ObjectInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
@@ -80,7 +86,7 @@ public class ClientConnection extends Th
{
if(socket !=null)
{
- logger.info("Stopping connection "+socket.getRemoteSocketAddress());
+ logger.info("Stopping connection "+getRemoteSocketAddress());
disconnect();
}
}
@@ -91,102 +97,74 @@ public class ClientConnection extends Th
}
}
+ public SocketAddress getRemoteSocketAddress()
+ {
+ return socket.getRemoteSocketAddress();
+ }
+
public synchronized void exitAndRemove()
{
exit();
+ callOnClientDisconnectOnAllActions();
removeConnection();
serverListener.clearTemp();
}
- public void removeConnection()
+ public void callOnClientDisconnectOnAllActions()
{
- ClientConnections.getInstance().removeConnection(this);
- }
-
-
- public void writeToStream(String text) throws SevereException
- {
- /*try
- {
- logger.debug(text);
- dos.writeUTF(text);
- dos.flush();
- }
- catch (IOException e)
- {
- e.printStackTrace();
- throw new SevereException("Unable to write to io Stream!");
- }*/
-
- try
+ for(ClientProfile profile : getClient().getAllClientProfiles())
{
- byte[] txtBytes = text.getBytes();
+ for (String actionID : profile.getActionsKeySet())
+ {
+ Action action = profile.getActionByID(actionID);
+ if(action instanceof ExternalPlugin)
+ {
+ try
+ {
+ ((ExternalPlugin) action).onClientDisconnected();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
- Thread.sleep(50);
- dos.writeUTF("string:: ::");
- dos.flush();
- dos.writeInt(txtBytes.length);
- dos.flush();
- write(txtBytes);
- dos.flush();
- }
- catch (IOException | InterruptedException e)
- {
- e.printStackTrace();
- throw new SevereException("Unable to write to io Stream!");
+ exceptionAndAlertHandler.handleMinorException(
+ new MinorException(
+ "Unable to run onClientDisconnected for "+action.getModuleName(),
+ "Detailed message : "+e.getMessage()
+ )
+ );
+ }
+ }
+ }
}
-
}
- public void sendIcon(String profileID, String actionID, byte[] icon) throws SevereException
+ public void removeConnection()
{
- try
- {
- logger.info("Sending action Icon...");
- //Thread.sleep(50);
- System.out.println("1");
- dos.writeUTF("action_icon::"+profileID+"!!"+actionID+"!!::"+icon.length);
-
- System.out.println("2");
- dos.flush();
-
- System.out.println("3");
- dos.writeInt(icon.length);
-
- System.out.println("4");
- dos.flush();
-
- System.out.println("5");
- write(icon);
-
- System.out.println("6");
- dos.flush();
-
- System.out.println("7");
- }
- catch (IOException e)
- {
- e.printStackTrace();
- throw new SevereException("Unable to write to io Stream!");
- }
+ ClientConnections.getInstance().removeConnection(this);
}
- public void write(byte[] array) throws SevereException
+ public void sendIcon(String profileID, String actionID, String state, byte[] icon) throws SevereException
{
try
{
- dos.write(array);
+ Thread.sleep(50);
}
- catch (IOException e)
+ catch (InterruptedException e)
{
e.printStackTrace();
- throw new SevereException("Unable to write to io Stream!");
}
- }
+ Message message = new Message("action_icon");
+ message.setStringArrValue(profileID, actionID, state);
+ message.setByteArrValue(icon);
+ sendMessage(message);
+ }
- public void initAfterConnectionQueryReceive(String[] arr) throws StreamPiException
+ public void initAfterConnectionQueryReceive(Message message) throws StreamPiException
{
+ String[] ar = message.getStringArrValue();
+
logger.info("Setting up client object ...");
Version clientVersion;
@@ -197,10 +175,10 @@ public class ClientConnection extends Th
try
{
- clientVersion = new Version(arr[1]);
- releaseStatus = ReleaseStatus.valueOf(arr[2]);
- commsStandard = new Version(arr[3]);
- themesStandard = new Version(arr[4]);
+ clientVersion = new Version(ar[0]);
+ releaseStatus = ReleaseStatus.valueOf(ar[1]);
+ commsStandard = new Version(ar[2]);
+ themesStandard = new Version(ar[3]);
}
catch (MinorException e)
{
@@ -218,17 +196,32 @@ public class ClientConnection extends Th
throw new MinorException(errTxt);
}
- client = new Client(clientVersion, releaseStatus, commsStandard, themesStandard, arr[5], Platform.valueOf(arr[8]), socket.getRemoteSocketAddress());
+ client = new Client(clientVersion, releaseStatus, commsStandard, themesStandard, ar[4], Platform.valueOf(ar[7]), socket.getRemoteSocketAddress());
- client.setStartupDisplayWidth(Double.parseDouble(arr[6]));
- client.setStartupDisplayHeight(Double.parseDouble(arr[7]));
- client.setDefaultProfileID(arr[9]);
- client.setDefaultThemeFullName(arr[10]);
+ client.setDisplayWidth(Double.parseDouble(ar[5]));
+ client.setDisplayHeight(Double.parseDouble(ar[6]));
+ client.setDefaultProfileID(ar[8]);
+ client.setDefaultThemeFullName(ar[9]);
//call get profiles command.
serverListener.clearTemp();
}
+ public void updateClientDetails(Message message)
+ {
+ String[] ar = message.getStringArrValue();
+
+ logger.info("Setting up client object ...");
+
+ client.setNickName(ar[4]);
+ client.setDisplayWidth(Double.parseDouble(ar[5]));
+ client.setDisplayHeight(Double.parseDouble(ar[6]));
+ client.setDefaultProfileID(ar[8]);
+ client.setDefaultThemeFullName(ar[9]);
+
+ serverListener.getSettingsBase().getClientsSettings().loadData();
+ }
+
public synchronized Client getClient()
{
return client;
@@ -252,78 +245,53 @@ public class ClientConnection extends Th
{
while(!stop.get())
{
- String msg = "";
try
{
- String raw = dis.readUTF();
+ Message message = (Message) ois.readObject();
- int length = dis.readInt();
+ String header = message.getHeader();
- System.out.println("SIZE TO READ : "+length);
+ switch (header)
+ {
+ case "action_icon" : onActionIconReceived(message);
+ break;
- String[] precursor = raw.split("::");
+ case "disconnect" : clientDisconnected(message);
+ break;
- String inputType = precursor[0];
- String secondArg = precursor[1];
+ case "register_client_details" : initAfterConnectionQueryReceive(message);
+ getProfilesFromClient();
+ getThemesFromClient();
+ break;
+ case "update_client_details" : updateClientDetails(message);
+ break;
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ case "client_screen_details" : onClientScreenDetailsReceived(message);
+ break;
- /*int count;
- int chunkSize = 512;
- while (length>0)
- {
- if(chunkSize > length)
- chunkSize = length;
- else
- chunkSize = 512;
-
- byte[] buffer = new byte[chunkSize];
- count = dis.read(buffer);
-
- System.out.println(count);
-
- byteArrayOutputStream.write(buffer);
-
- length-=count;
- }*/
-
- /*byte[] buffer = new byte[8192];
- int read;
- while((read = dis.read(buffer)) != -1){
- System.out.println("READ : "+read);
- byteArrayOutputStream.write(buffer, 0, read);
- }
+ case "profiles" : registerProfilesFromClient(message);
+ break;
- System.out.println("READ : "+byteArrayOutputStream.size());
+ case "profile_details" : registerProfileDetailsFromClient(message);
+ break;
- byteArrayOutputStream.close();
+ case "action_details" : registerActionToProfile(message);
+ break;
- byte[] bArr = byteArrayOutputStream.toByteArray();*/
+ case "themes": registerThemes(message);
+ break;
- byte[] bArr = new byte[length];
+ case "action_clicked": onActionClicked(message);
+ break;
- dis.readFully(bArr);
+ default: logger.warning("Command '"+header+"' does not match records. Make sure client and server versions are equal.");
- if(inputType.equals("string"))
- {
- msg = new String(bArr);
- }
- else if(inputType.equals("action_icon"))
- {
- String[] secondArgSep = secondArg.split("!!");
-
- String profileID = secondArgSep[0];
- String actionID = secondArgSep[1];
- getClient().getProfileByID(profileID).getActionByID(actionID).setIcon(bArr);
-
- //serverListener.clearTemp();
- continue;
}
}
- catch (IOException e)
+ catch (IOException | ClassNotFoundException e)
{
logger.log(Level.SEVERE, e.getMessage());
e.printStackTrace();
@@ -340,42 +308,6 @@ public class ClientConnection extends Th
return;
}
-
- logger.info("Received text : '"+msg+"'");
-
- String[] sep = msg.split("::");
-
- String command = sep[0];
-
- switch (command)
- {
- case "disconnect" : clientDisconnected(msg);
- break;
-
- case "client_details" : initAfterConnectionQueryReceive(sep);
- getProfilesFromClient();
- getThemesFromClient();
- break;
-
- case "profiles" : registerProfilesFromClient(sep);
- break;
-
- case "profile_details" : registerProfileDetailsFromClient(sep);
- break;
-
- case "action_details" : registerActionToProfile(sep);
- break;
-
- case "themes": registerThemes(sep);
- break;
-
- case "action_clicked": actionClicked(sep[1], sep[2]);
- break;
-
- default: logger.warning("Command '"+command+"' does not match records. Make sure client and server versions are equal.");
-
-
- }
}
}
catch (StreamPiException e)
@@ -391,17 +323,26 @@ public class ClientConnection extends Th
}
}
+ // commands
+ private void onActionIconReceived(Message message) throws MinorException
+ {
+ String[] s = message.getStringArrValue();
-
-
-
- // commands
+ String profileID = s[0];
+ String actionID = s[1];
+ String iconState = s[2];
+
+ getClient()
+ .getProfileByID(profileID)
+ .getActionByID(actionID)
+ .addIcon(iconState,message.getByteArrValue());
+ }
public void initAfterConnectionQuerySend() throws SevereException
{
logger.info("Asking client details ...");
- writeToStream("get_client_details::");
+ sendMessage(new Message("get_client_details"));
}
public void disconnect() throws SevereException {
@@ -415,8 +356,10 @@ public class ClientConnection extends Th
stop.set(true);
logger.info("Sending client disconnect message ...");
- writeToStream("disconnect::"+message+"::");
+ Message m = new Message("disconnect");
+ m.setStringValue(message);
+ sendMessage(m);
try
{
@@ -430,13 +373,31 @@ public class ClientConnection extends Th
}
}
- public void clientDisconnected(String message)
+ public synchronized void sendMessage(Message message) throws SevereException
+ {
+ try
+ {
+ logger.info("Sending message with heading "+message.getHeader()+" ...");
+ oos.writeObject(message);
+ oos.flush();
+ logger.info("... Done!");
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ throw new SevereException("Unable to write to io Stream!");
+ }
+ }
+
+ public void clientDisconnected(Message message)
{
stop.set(true);
String txt = "Disconnected!";
- if(!message.equals("disconnect::::"))
- txt = "Message : "+message.split("::")[1];
+ String msg = message.getStringValue();
+
+ if(!msg.isBlank())
+ txt = "Message : "+msg;
new StreamPiAlert("Disconnected from "+getClient().getNickName()+".", txt, StreamPiAlertType.WARNING).show();;
exitAndRemove();
@@ -445,26 +406,26 @@ public class ClientConnection extends Th
public void getProfilesFromClient() throws StreamPiException
{
logger.info("Asking client to send profiles ...");
- writeToStream("get_profiles::");
+ sendMessage(new Message("get_profiles"));
}
public void getThemesFromClient() throws StreamPiException
{
logger.info("Asking clients to send themes ...");
- writeToStream("get_themes::");
+ sendMessage(new Message("get_themes"));
}
- public void registerThemes(String[] sep)
+ public void registerThemes(Message message)
{
- for(int i =1; i<sep.length;i++)
- {
- String[] internal = sep[i].split("__");
+ String[] r = message.getStringArrValue();
+ for(int i =0; i<(r.length);i+=4)
+ {
ClientTheme clientTheme = new ClientTheme(
- internal[0],
- internal[1],
- internal[2],
- internal[3]
+ r[i],
+ r[i+1],
+ r[i+2],
+ r[i+3]
);
try
@@ -479,15 +440,18 @@ public class ClientConnection extends Th
}
}
- public void registerProfilesFromClient(String[] sep) throws StreamPiException
+ int totalActions;
+ public void registerProfilesFromClient(Message message) throws StreamPiException
{
logger.info("Registering profiles ...");
- int noOfProfiles = Integer.parseInt(sep[1]);
+ String[] r = message.getStringArrValue();
+
+ totalActions = message.getIntValue();
+ System.out.println("TTOOOX : "+totalActions);
- for(int i = 2; i<(noOfProfiles + 2); i++)
+ for (String profileID : r)
{
- String profileID = sep[i];
getProfileDetailsFromClient(profileID);
}
}
@@ -495,20 +459,24 @@ public class ClientConnection extends Th
public void getProfileDetailsFromClient(String ID) throws StreamPiException
{
logger.info("Asking client to send details of profile : "+ID);
- writeToStream("get_profile_details::"+ID+"::");
+ Message message = new Message("get_profile_details");
+ message.setStringValue(ID);
+ sendMessage(message);
}
- public void registerProfileDetailsFromClient(String[] sep)
+ public void registerProfileDetailsFromClient(Message message)
{
- String ID = sep[1];
+ String[] r = message.getStringArrValue();
+
+ String ID = r[0];
logger.info("Registering details for profile : "+ID);
- String name = sep[2];
- int rows = Integer.parseInt(sep[3]);
- int cols = Integer.parseInt(sep[4]);
- int actionSize = Integer.parseInt(sep[5]);
- int actionGap = Integer.parseInt(sep[6]);
+ String name = r[1];
+ int rows = Integer.parseInt(r[2]);
+ int cols = Integer.parseInt(r[3]);
+ int actionSize = Integer.parseInt(r[4]);
+ int actionGap = Integer.parseInt(r[5]);
ClientProfile clientProfile = new ClientProfile(name, ID, rows, cols, actionSize, actionGap);
@@ -526,160 +494,210 @@ public class ClientConnection extends Th
serverListener.clearTemp();
}
- /*public void getActionIcon(String profileID, String actionID) throws StreamPiException
+ public synchronized void registerActionToProfile(Message message) throws StreamPiException
{
- System.out.println("getting action icon from "+profileID+", "+actionID);
- writeToStream("get_action_icon::"+profileID+"::"+actionID);
- }*/
+ totalActions--;
- public synchronized void registerActionToProfile(String[] sep) throws StreamPiException
- {
- String profileID = sep[1];
+ String[] r = message.getStringArrValue();
- String ID = sep[2];
- ActionType actionType = ActionType.valueOf(sep[3]);
+ String profileID = r[0];
- //4 - Version
- //5 - ModuleName
+ String ID = r[1];
+ ActionType actionType = ActionType.valueOf(r[2]);
+
+ //3 - Version
+ //4 - ModuleName
//display
- String bgColorHex = sep[6];
+ String bgColorHex = r[5];
//icon
- boolean isHasIcon = sep[7].equals("true");
- boolean isShowIcon = sep[8].equals("true");
+ String[] allIconStateNames = r[6].split("::");
+ String defaultIconState = r[7];
//text
- boolean isShowDisplayText = sep[9].equals("true");
- String displayFontColor = sep[10];
- String displayText = sep[11];
- DisplayTextAlignment displayTextAlignment = DisplayTextAlignment.valueOf(sep[12]);
+ boolean isShowDisplayText = r[8].equals("true");
+ String displayFontColor = r[9];
+ String displayText = r[10];
+ DisplayTextAlignment displayTextAlignment = DisplayTextAlignment.valueOf(r[11]);
//location
- String row = sep[13];
- String col = sep[14];
+ String row = r[12];
+ String col = r[13];
Location location = new Location(Integer.parseInt(row), Integer.parseInt(col));
+ String root = r[14];
-
- Action action = new Action(ID, actionType);
-
- action.setBgColourHex(bgColorHex);
- action.setShowIcon(isShowIcon);
- action.setHasIcon(isHasIcon);
-
- action.setShowDisplayText(isShowDisplayText);
- action.setDisplayTextFontColourHex(displayFontColor);
- action.setDisplayText(displayText);
- action.setDisplayTextAlignment(displayTextAlignment);
-
-
- action.setLocation(location);
+ int delayBeforeRunning = Integer.parseInt(r[15]);
//client properties
- int clientPropertiesSize = Integer.parseInt(sep[15]);
-
- String root = sep[17];
- action.setParent(root);
-
- String[] clientPropertiesRaw = sep[16].split("!!");
+ int clientPropertiesSize = Integer.parseInt(r[16]);
ClientProperties clientProperties = new ClientProperties();
if(actionType == ActionType.FOLDER)
clientProperties.setDuplicatePropertyAllowed(true);
- for(int i = 0;i<clientPropertiesSize; i++)
+ for(int i = 17;i<((clientPropertiesSize*2) + 17); i+=2)
{
- String[] clientPraw = clientPropertiesRaw[i].split("__");
-
- Property property = new Property(clientPraw[0], Type.STRING);
-
- if(clientPraw.length > 1)
- property.setRawValue(clientPraw[1]);
+ Property property = new Property(r[i], Type.STRING);
+ property.setRawValue(r[i+1]);
clientProperties.addProperty(property);
}
- action.setClientProperties(clientProperties);
- action.setModuleName(sep[5]);
-
//set up action
//action toBeAdded = null;
- if(actionType == ActionType.NORMAL)
+ boolean isInvalidAction = false;
+
+ if(actionType == ActionType.NORMAL || actionType == ActionType.TOGGLE)
{
- NormalAction actionCopy = NormalActionPlugins.getInstance().getPluginByModuleName(sep[5]);
+ String moduleName = r[4];
+ Version version = new Version(r[3]);
+
+ ExternalPlugin originalAction = ExternalPlugins.getInstance().getPluginByModuleName(moduleName);
- if(actionCopy == null)
+ if(originalAction == null)
{
- action.setInvalid(true);
+ isInvalidAction = true;
}
else
{
- action.setVersion(new Version(sep[4]));
-
- //action.setHelpLink(actionCopy.getHelpLink());
-
- if(actionCopy.getVersion().getMajor() != action.getVersion().getMajor())
+ if(originalAction.getVersion().getMajor() != version.getMajor())
{
- action.setInvalid(true);
+ isInvalidAction = true;
}
else
{
- action.setName(actionCopy.getName());
+ try
+ {
+ ExternalPlugin newPlugin = originalAction.clone();
- ClientProperties finalClientProperties = new ClientProperties();
+ newPlugin.setID(ID);
+ System.out.println("SAVVEEEEEEEEEEEEEEE@@@@@ : "+profileID);
+ newPlugin.setProfileID(profileID);
+ newPlugin.setSocketAddressForClient(socket.getRemoteSocketAddress());
+ newPlugin.setBgColourHex(bgColorHex);
+ newPlugin.setCurrentIconState(defaultIconState);
- for(Property property : actionCopy.getClientProperties().get())
- {
- for(int i = 0;i<action.getClientProperties().getSize();i++)
+ newPlugin.setShowDisplayText(isShowDisplayText);
+ newPlugin.setDisplayTextFontColourHex(displayFontColor);
+ newPlugin.setDisplayText(displayText);
+ newPlugin.setDisplayTextAlignment(displayTextAlignment);
+
+ newPlugin.setLocation(location);
+
+ newPlugin.setParent(root);
+
+ newPlugin.setDelayBeforeExecuting(delayBeforeRunning);
+
+
+ ClientProperties finalClientProperties = new ClientProperties();
+
+
+ for(Property property : originalAction.getClientProperties().get())
{
- Property property1 = action.getClientProperties().get().get(i);
- if (property.getName().equals(property1.getName()))
+ for(int i = 0;i<clientProperties.getSize();i++)
{
- property.setRawValue(property1.getRawValue());
+ Property property1 = clientProperties.get().get(i);
+ if (property.getName().equals(property1.getName()))
+ {
+ property.setRawValue(property1.getRawValue());
-
- finalClientProperties.addProperty(property);
+ finalClientProperties.addProperty(property);
+ }
}
}
- }
- action.setClientProperties(finalClientProperties);
+ newPlugin.setClientProperties(finalClientProperties);
+
+ getClient().getProfileByID(profileID).addAction(newPlugin);
+
+ new Thread(new Task<Void>() {
+ @Override
+ protected Void call()
+ {
+ try
+ {
+ newPlugin.onClientConnected();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ exceptionAndAlertHandler.handleMinorException(
+ new MinorException("Failed","Error "+moduleName+" at onClientConnected \nMessage"+e.getMessage())
+ );
+ }
+ return null;
+ }
+ }).start();
+
+ }
+ catch (CloneNotSupportedException e)
+ {
+ exceptionAndAlertHandler.handleMinorException(new MinorException("action", "Unable to clone"));
+ }
+
+ checkIfReady();
+ return;
}
}
}
- try
+ Action action = null;
+
+ if(isInvalidAction)
{
- for(Property prop : action.getClientProperties().get())
+ String moduleName = r[4];
+ Version version = new Version(r[3]);
+
+ action = new Action();
+ action.setInvalid(true);
+ action.setVersion(version);
+ action.setModuleName(moduleName);
+ }
+ else
+ {
+ if(actionType == ActionType.COMBINE)
+ {
+ action = new CombineAction();
+ }
+ else if(actionType == ActionType.FOLDER)
{
- logger.info("G@@@@@ : "+prop.getRawValue());
+ action = new FolderAction();
}
+ }
+ action.setID(ID);
+ action.setProfileID(profileID);
+ action.setSocketAddressForClient(socket.getRemoteSocketAddress());
- getClient().getProfileByID(profileID).addAction(action);
+ action.setBgColourHex(bgColorHex);
+ action.setCurrentIconState(defaultIconState);
+ action.setShowDisplayText(isShowDisplayText);
+ action.setDisplayTextFontColourHex(displayFontColor);
+ action.setDisplayText(displayText);
+ action.setDisplayTextAlignment(displayTextAlignment);
+ action.setLocation(location);
+
+ action.setParent(root);
- for(String action1x : getClient().getProfileByID(profileID).getActionsKeySet())
- {
- Action action1 = getClient().getProfileByID(profileID).getActionByID(action1x);
- logger.info("231cc : "+action1.getID());
- for(Property prop : action1.getClientProperties().get())
- {
- logger.info("G@VVVV@@@ : "+prop.getRawValue());
- }
- }
+ action.setClientProperties(clientProperties);
+
+ try
+ {
+ getClient().getProfileByID(profileID).addAction(action);
}
catch (CloneNotSupportedException e)
{
@@ -687,113 +705,139 @@ public class ClientConnection extends Th
exceptionAndAlertHandler.handleMinorException(new MinorException("action", "Unable to clone"));
}
+ checkIfReady();
}
- public void saveActionDetails(String profileID, Action action) throws SevereException
+ public void checkIfReady() throws SevereException
{
- StringBuilder finalQuery = new StringBuilder("save_action_details::");
-
-
- //failsafes
-
- if(action.getDisplayText().endsWith(":"))
- action.setDisplayText(action.getDisplayText()+" ");
+ if(totalActions == 0)
+ {
+ sendMessage(new Message("ready"));
+ }
+ }
+ public synchronized void saveActionDetails(String profileID, Action action) throws SevereException
+ {
+ ArrayList<String> a = new ArrayList<>();
- finalQuery.append(profileID)
- .append("::")
- .append(action.getID())
- .append("::")
- .append(action.getActionType())
- .append("::");
+ a.add(profileID);
+ a.add(action.getID());
+ a.add(action.getActionType()+"");
- if(action.getActionType() == ActionType.NORMAL)
+ if(action.getActionType() == ActionType.NORMAL || action.getActionType() == ActionType.TOGGLE)
{
- finalQuery.append(action.getVersion().getText());
+ a.add(action.getVersion().getText());
System.out.println("VERSION :sdd "+action.getVersion().getText());
}
+ else
+ {
+ a.add("no");
+ }
- finalQuery.append("::");
- if(action.getActionType() == ActionType.NORMAL)
- finalQuery.append(action.getModuleName());
+ if(action.getActionType() == ActionType.NORMAL || action.getActionType() == ActionType.TOGGLE)
+ {
+ a.add(action.getModuleName());
+ }
+ else
+ {
+ a.add("nut");
+ }
- finalQuery.append("::");
//display
- finalQuery.append(action.getBgColourHex())
- .append("::");
+ a.add(action.getBgColourHex());
//icon
- finalQuery.append(action.isHasIcon())
- .append("::")
- .append(action.isShowIcon())
- .append("::");
+
+ StringBuilder allIconStatesNames = new StringBuilder();
+ for(String eachState : action.getIcons().keySet())
+ {
+ allIconStatesNames.append(eachState).append("::");
+ }
+ a.add(allIconStatesNames.toString());
+
+
+ a.add(action.getCurrentIconState());
//text
- finalQuery.append(action.isShowDisplayText())
- .append("::")
- .append(action.getDisplayTextFontColourHex())
- .append("::")
- .append(action.getDisplayText())
- .append("::")
- .append(action.getDisplayTextAlignment())
- .append("::");
+ a.add(action.isShowDisplayText()+"");
+ a.add(action.getDisplayTextFontColourHex());
+ a.add(action.getDisplayText());
+ a.add(action.getDisplayTextAlignment()+"");
//location
if(action.getLocation() == null)
- finalQuery.append("-1::-1::");
+ {
+ a.add("-1");
+ a.add("-1");
+ }
else
- finalQuery.append(action.getLocation().getRow())
- .append("::")
- .append(action.getLocation().getCol())
- .append("::");
+ {
+ a.add(action.getLocation().getRow()+"");
+ a.add(action.getLocation().getCol()+"");
+ }
+
+ a.add(action.getParent());
+
+ a.add(action.getDelayBeforeExecuting()+"");
//client properties
ClientProperties clientProperties = action.getClientProperties();
- finalQuery.append(clientProperties.getSize())
- .append("::");
+
+ a.add(clientProperties.getSize()+"");
for(Property property : clientProperties.get())
{
- finalQuery.append(property.getName())
- .append("__")
- .append(property.getRawValue())
- .append("__");
-
- finalQuery.append("!!");
+ a.add(property.getName());
+ a.add(property.getRawValue());
}
- finalQuery.append("::")
- .append(action.getParent())
- .append("::");
- writeToStream(finalQuery.toString());
+ Message message = new Message("save_action_details");
+ String[] x = new String[a.size()];
+ x = a.toArray(x);
+ message.setStringArrValue(x);
+ sendMessage(message);
+ }
+
+ public void getClientScreenDetails() throws SevereException
+ {
+ Message message = new Message("get_client_screen_details");
+ sendMessage(message);
+ }
+
+ public void onClientScreenDetailsReceived(Message message)
+ {
+ getClient().setDisplayWidth(message.getDoubleArrValue()[0]);
+ getClient().setDisplayHeight(message.getDoubleArrValue()[1]);
}
public void deleteAction(String profileID, String actionID) throws SevereException
{
- writeToStream("delete_action::"+profileID+"::"+actionID);
+ Message message = new Message("delete_action");
+ message.setStringArrValue(profileID, actionID);
+ sendMessage(message);
}
- public void saveClientDetails(String clientNickname, String screenWidth, String screenHeight, String defaultProfileID,
+ public void saveClientDetails(String clientNickname, String defaultProfileID,
String defaultThemeFullName) throws SevereException
{
- writeToStream("save_client_details::"+
- clientNickname+"::"+
- screenWidth+"::"+
- screenHeight+"::"+
- defaultProfileID+"::"+
- defaultThemeFullName+"::");
+ Message message = new Message("save_client_details");
+ message.setStringArrValue(
+ clientNickname,
+ defaultProfileID,
+ defaultThemeFullName
+ );
+
+ sendMessage(message);
client.setNickName(clientNickname);
- client.setStartupDisplayWidth(Double.parseDouble(screenWidth));
- client.setStartupDisplayHeight(Double.parseDouble(screenHeight));
client.setDefaultProfileID(defaultProfileID);
client.setDefaultThemeFullName(defaultThemeFullName);
}
@@ -810,68 +854,102 @@ public class ClientConnection extends Th
else
client.addProfile(clientProfile);
- writeToStream("save_client_profile::"+
- clientProfile.getID()+"::"+
- clientProfile.getName()+"::"+
- clientProfile.getRows()+"::"+
- clientProfile.getCols()+"::"+
- clientProfile.getActionSize()+"::"+
- clientProfile.getActionGap()+"::");
+ Message message = new Message("save_client_profile");
+
+ message.setStringArrValue(
+ clientProfile.getID(),
+ clientProfile.getName(),
+ clientProfile.getRows()+"",
+ clientProfile.getCols()+"",
+ clientProfile.getActionSize()+"",
+ clientProfile.getActionGap()+""
+ );
+
+ sendMessage(message);
}
public void deleteProfile(String ID) throws SevereException
{
- writeToStream("delete_profile::"+ID+"::");
+ Message message = new Message("delete_profile");
+ message.setStringValue(ID);
+ sendMessage(message);
}
- public void actionClicked(String profileID, String actionID) {
-
+ public void onActionClicked(Message message)
+ {
try
{
+ String[] r = message.getStringArrValue();
+
+ String profileID = r[0];
+ String actionID = r[1];
+ boolean toggle = r[2].equals("true");
+
Action action = client.getProfileByID(profileID).getActionByID(actionID);
- if(action.getActionType() == ActionType.NORMAL)
+ if(action.getActionType() == ActionType.NORMAL || action.getActionType() == ActionType.TOGGLE)
{
- NormalAction original = NormalActionPlugins.getInstance().getPluginByModuleName(
- action.getModuleName()
- );
-
- if(original == null)
+ if(action.isInvalid())
{
throw new MinorException(
"The action isn't installed on the server."
);
}
-
- NormalAction normalAction = original.clone();
-
-
-
- normalAction.setLocation(action.getLocation());
- normalAction.setDisplayText(action.getDisplayText());
- normalAction.setID(actionID);
-
- normalAction.setClientProperties(action.getClientProperties());
-
- new Thread(new Task<Void>() {
- @Override
- protected Void call()
+ else
+ {
+ if(action instanceof ToggleAction)
{
- try
- {
- boolean result = serverListener.onNormalActionClicked(normalAction);
- if(!result)
+ new Thread(new Task<Void>() {
+ @Override
+ protected Void call()
{
- sendActionFailed(profileID, actionID);
+ try
+ {
+ boolean result = serverListener.onToggleActionClicked((ToggleAction) action, toggle, profileID);
+ if(!result)
+ {
+ sendActionFailed(profileID, actionID);
+ }
+ }
+ catch (SevereException e)
+ {
+ exceptionAndAlertHandler.handleSevereException(e);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ return null;
}
- }
- catch (SevereException e)
- {
- exceptionAndAlertHandler.handleSevereException(e);
- }
- return null;
+ }).start();
+ }
+ else if(action instanceof NormalAction)
+ {
+ new Thread(new Task<Void>() {
+ @Override
+ protected Void call()
+ {
+ try
+ {
+ boolean result = serverListener.onNormalActionClicked((NormalAction) action, profileID);
+ if(!result)
+ {
+ sendActionFailed(profileID, actionID);
+ }
+ }
+ catch (SevereException e)
+ {
+ exceptionAndAlertHandler.handleSevereException(e);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ }).start();
}
- }).start();
+ }
}
} catch (Exception e) {
e.printStackTrace();
@@ -879,10 +957,19 @@ public class ClientConnection extends Th
}
}
+ public void setToggleStatus(boolean status, String profileID, String actionID) throws SevereException
+ {
+ Message message = new Message("set_toggle_status");
+
+ message.setStringArrValue(profileID, actionID, status+"");
+
+ sendMessage(message);
+ }
+
public void sendActionFailed(String profileID, String actionID) throws SevereException {
logger.info("Sending failed status ...");
- writeToStream("action_failed::"+
- profileID+"::"+
- actionID+"::");
+ Message message = new Message("action_failed");
+ message.setStringArrValue(profileID, actionID);
+ sendMessage(message);
}
}
--- 'a/src/main/java/com/stream_pi/server/connection/ClientConnections.java'
+++ b/src/main/java/com/stream_pi/server/connection/ClientConnections.java
@@ -42,7 +42,7 @@ public class ClientConnections {
public void removeConnection(ClientConnection clientConnection)
{
- System.out.println(connections.remove(clientConnection)+" 22222222222222222222222222222222222222222");
+ connections.remove(clientConnection);
}
public void disconnectAll()
--- 'a/src/main/java/com/stream_pi/server/connection/ConnectionService.java'
+++ /dev/null
@@ -1,345 +0,0 @@
-/*package com.StreamPi.Server.connection;
-
-import com.StreamPi.ActionAPI.action.action;
-import com.StreamPi.ActionAPI.action.ActionType;
-import com.StreamPi.ActionAPI.action.Location;
-import com.StreamPi.ActionAPI.ActionProperty.ClientProperties;
-import com.StreamPi.ActionAPI.NormalAction.NormalAction;
-import com.StreamPi.CommAPI.ConnectionGrpc;
-import com.StreamPi.CommAPI.ServerGRPC;
-import NormalActionPlugins;
-import client;
-import ClientProfile;
-import ServerInfo;
-import com.StreamPi.Util.Exception.MinorException;
-import com.StreamPi.Util.Exception.SevereException;
-import com.StreamPi.Util.Exception.StreamPiException;
-import com.StreamPi.Util.Platform.Platform;
-import com.StreamPi.Util.Version.Version;
-import io.grpc.stub.StreamObserver;
-import javafx.concurrent.Task;
-import javafx.scene.control.Alert;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-public class ConnectionService extends ConnectionGrpc.ConnectionImplBase {
-
- private client client = null;
- private Logger logger;
-
- ServerListener serverListener;
-
- final HashMap<String, Boolean> actionStatuses;
-
- public ConnectionService(ServerListener serverListener)
- {
- super();
-
- isDisconnect = false;
- disconnectMessage = "";
-
- logger = LoggerFactory.getLogger(ConnectionService.class);
- actionStatuses = new HashMap<>();
-
- this.serverListener = serverListener;
- }
-
-
- boolean isDisconnect;
- String disconnectMessage;
-
- public void disconnect()
- {
- disconnect("");
- }
-
- public void disconnect(String message)
- {
- if(!isDisconnect)
- {
- this.isDisconnect = true;
- this.disconnectMessage = message;
- }
- }
-
- @Override
- public void sendClientDetails(ServerGRPC.ClientDetails request, StreamObserver<ServerGRPC.Status> responseObserver) {
-
- Version clientVersion;
- Version commsAPIVersion;
- Version themeAPIVersion;
-
- try
- {
- clientVersion = new Version(request.getClientVersion());
- commsAPIVersion = new Version(request.getCommAPIVersion());
- themeAPIVersion = new Version(request.getThemeAPIVersion());
- }
- catch (MinorException e)
- {
- e.printStackTrace();
- serverListener.onRPCError(new MinorException("versions invalid. Check stacktrace"));
- disconnect();
- return;
- }
-
-
- String nickName = request.getNickName();
- Platform platform = Platform.valueOf(request.getPlatform().toString());
-
- client = new client(clientVersion, commsAPIVersion, themeAPIVersion, nickName, platform, null);
-
- boolean sendActions = true;
-
- if(!commsAPIVersion.isEqual(ServerInfo.getInstance().getCommAPIVersion()))
- {
- sendActions = false;
- disconnect("client CommAPI and Server CommAPI do not match!");
- }
-
- responseObserver.onNext(ServerGRPC.Status.newBuilder().setSendActions(sendActions).build());
-
- responseObserver.onCompleted();
- }
-
- @Override
- public StreamObserver<ServerGRPC.ClientProfile> sendClientProfiles(StreamObserver<ServerGRPC.Empty> responseObserver) {
-
- client.getProfiles().clear();
-
- ArrayList<String> notFoundActions = new ArrayList<>();
-
- return new StreamObserver<ServerGRPC.ClientProfile>() {
- @Override
- public void onNext(ServerGRPC.ClientProfile clientProfile) {
-
- String name = clientProfile.getName();
- String id = clientProfile.getId();
-
- int rows = clientProfile.getRows();
- int cols = clientProfile.getCols();
-
- int actionSize = clientProfile.getActionSize();
- int actionGap = clientProfile.getActionGap();
-
- ClientProfile finalClientProfile = new ClientProfile(name, id, rows, cols, actionSize, actionGap);
-
- ArrayList<action> actions = new ArrayList<>();
-
- List<ServerGRPC.ClientAction> clientActions = clientProfile.getActionsList();
- for(ServerGRPC.ClientAction clientAction : clientActions)
- {
-
- String actionID = clientAction.getId();
- String actionName = clientAction.getActionName();
-
- boolean hasIcon = clientAction.getHasIcon();
-
- ActionType actionType = ActionType.valueOf(clientAction.getActionType().toString());
-
- action action = new action(actionID, actionType);
- action.setActionName(actionName);
-
- action.setHasIcon(hasIcon);
-
- int locationX = clientAction.getLocationX();
- int locationY = clientAction.getLocationY();
-
- action.setLocation(new Location(locationX, locationY));
-
- if(actionType == ActionType.NORMAL)
- {
- action.setModuleName(clientAction.getModuleName());
-
- ClientProperties properties = new ClientProperties();
-
- List<ServerGRPC.ClientProperty> clientProperties = clientAction.getClientPropertiesList();
-
- for(ServerGRPC.ClientProperty clientProperty : clientProperties)
- {
- String propertyName = clientProperty.getName();
- String propertyValue = clientProperty.getValue();
-
- properties.addProperty(propertyName, propertyValue);
- }
-
- action.setClientProperties(properties);
-
- boolean isFound = false;
- for(NormalAction normalAction : NormalActionPlugins.getInstance().getPlugins())
- {
- if(normalAction.getModuleName().equals(action.getModuleName()))
- {
- isFound = true;
-
- normalAction.setClientProperties(action.getClientProperties());
- normalAction.setActionName(action.getActionName());
- normalAction.setHasIcon(action.isHasIcon());
- normalAction.setID(action.getID());
- normalAction.setLocation(action.getLocation());
- normalAction.setInvalid(false);
-
- actions.add(normalAction);
-
- break;
- }
- }
-
- if(!isFound)
- {
- String aName = action.getModuleName();
-
- action.setInvalid(true);
-
- logger.warn("action "+aName+" not found!");
- if(!notFoundActions.contains(aName))
- notFoundActions.add(aName);
-
- actions.add(action);
- }
- }
- }
-
- finalClientProfile.setActions(actions);
- client.addProfile(finalClientProfile);
-
-
- }
-
- @Override
- public void onError(Throwable throwable) {
- serverListener.onRPCError(new SevereException(throwable.getMessage()));
- }
-
- @Override
- public void onCompleted() {
-
- if(!notFoundActions.isEmpty())
- {
- StringBuilder all = new StringBuilder("Some actions cannot be edited/used because they are not installed on the server : ");
-
- for(String each : notFoundActions)
- {
- all.append("\n * ").append(each);
- }
-
- serverListener.onAlert("Warning",all.toString(), Alert.AlertType.WARNING);
- }
-
- responseObserver.onNext(ServerGRPC.Empty.newBuilder().build());
- responseObserver.onCompleted();
- }
- };
- }
-
- @Override
- public void actionClicked(ServerGRPC.ClickedActionID request, StreamObserver<ServerGRPC.Empty> responseObserver) {
- try
- {
- action actionClicked = client.getProfileByID(request.getProfileID()).getActionByID(request.getId());
- new Thread(new Task<Void>() {
- @Override
- protected Void call()
- {
- try
- {
- synchronized (actionStatuses)
- {
- actionStatuses.put(request.getId(), serverListener.onActionClicked(actionClicked));
- }
- }
- catch (MinorException e)
- {
- serverListener.onRPCError(e);
- }
- return null;
- }
- }).start();
- }
- catch (MinorException e)
- {
- e.printStackTrace();
- }
- finally {
- responseObserver.onNext(ServerGRPC.Empty.newBuilder().build());
- responseObserver.onCompleted();
- }
- }
-
- @Override
- public StreamObserver<ServerGRPC.Empty> actionClickedStatus(StreamObserver<ServerGRPC.ActionStatus> responseObserver) {
- return new StreamObserver<ServerGRPC.Empty>() {
- @Override
- public void onNext(ServerGRPC.Empty empty) {
-
- }
-
- @Override
- public void onError(Throwable throwable) {
- serverListener.onRPCError(new StreamPiException(throwable.getMessage()));
- }
-
- @Override
- public void onCompleted() {
- String id = null;
- boolean success = false;
- synchronized (actionStatuses)
- {
- if(!actionStatuses.isEmpty())
- {
- for(String key : actionStatuses.keySet())
- {
- id = key;
- success = actionStatuses.get(id);
-
- System.out.println("SDSDSDASDASDXZXCZXCZXC");
- break;
- }
- }
- }
-
- if(id==null)
- {
- responseObserver.onNext(ServerGRPC.ActionStatus.newBuilder().build());
- }
- else
- responseObserver.onNext(ServerGRPC.ActionStatus.newBuilder()
- .setId(id)
- .setIsSuccess(success)
- .build());
-
- responseObserver.onCompleted();
- }
- };
- }
-
- @Override
- public StreamObserver<ServerGRPC.DisconnectMessage> disconnect(StreamObserver<ServerGRPC.DisconnectMessage> responseObserver) {
- return new StreamObserver<ServerGRPC.DisconnectMessage>() {
- @Override
- public void onNext(ServerGRPC.DisconnectMessage disconnectMessage) {
- if(disconnectMessage.getIsDisconnect())
- disconnect(disconnectMessage.getMessage());
- }
-
- @Override
- public void onError(Throwable throwable) {
- serverListener.onRPCError(new StreamPiException(throwable.getMessage()));
- }
-
- @Override
- public void onCompleted() {
- responseObserver.onNext(ServerGRPC.DisconnectMessage.newBuilder()
- .setIsDisconnect(isDisconnect)
- .setMessage(disconnectMessage)
- .build());
- responseObserver.onCompleted();
- }
- };
- }
-}
-*/
\ No newline at end of file
--- 'a/src/main/java/com/stream_pi/server/connection/MainServer.java'
+++ b/src/main/java/com/stream_pi/server/connection/MainServer.java
@@ -3,15 +3,15 @@ package com.stream_pi.server.connection;
import com.stream_pi.server.window.ExceptionAndAlertHandler;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.SevereException;
+import javafx.application.Platform;
import java.io.IOException;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketException;
+import java.net.*;
+import java.util.Enumeration;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger;
-public class MainServer extends Thread{
+public class MainServer extends Thread {
private ServerListener serverListener;
private Logger logger = Logger.getLogger(MainServer.class.getName());
@@ -19,14 +19,12 @@ public class MainServer extends Thread{
private ServerSocket serverSocket = null;
//private Server server;
-
private AtomicBoolean stop = new AtomicBoolean(false);
private ExceptionAndAlertHandler exceptionAndAlertHandler;
public MainServer(ServerListener serverListener, ExceptionAndAlertHandler exceptionAndAlertHandler)
{
this.exceptionAndAlertHandler = exceptionAndAlertHandler;
- this.port = port;
this.serverListener = serverListener;
}
@@ -55,14 +53,16 @@ public class MainServer extends Thread{
logger.info("Stopping listening for connections ...");
if(serverSocket!=null)
if(!serverSocket.isClosed())
+ {
+ stop.set(true);
serverSocket.close();
+ }
} catch (IOException e) {
e.printStackTrace();
}
finally {
logger.info("... Done!");
}
- stop.set(true);
}
@Override
@@ -70,17 +70,9 @@ public class MainServer extends Thread{
logger.warning("Starting main server on port "+port+" ...");
try {
-
logger.info("Starting server on port "+port+" ...");
- /*Server server = ServerBuilder.forPort(port)
- .addService(new ConnectionService(serverListener))
- .build();
-
- server.start();
- logger.info("... Done!");*/
-
serverSocket = new ServerSocket(port);
-
+ setupStageTitle(true);
while(!stop.get())
{
Socket s = serverSocket.accept();
@@ -92,13 +84,63 @@ public class MainServer extends Thread{
}
catch (SocketException e)
{
- logger.info("Main Server stopped accepting calls ...");
- e.printStackTrace(); //more likely stopped listening;
- } catch (IOException e) {
+ if(!e.getMessage().contains("Socket closed") && !e.getMessage().contains("Interrupted function call: accept failed"))
+ {
+ logger.info("Main Server stopped accepting calls ...");
+
+ setupStageTitle(false);
+
+ exceptionAndAlertHandler.handleMinorException(new MinorException("Sorry!","Server could not be started at "+port+".\n" +
+ "This could be due to another process or another instance of Stream-Pi Server using the same port. \n\n" +
+ "If another Server Instance probably running, close it. If not, try changing the port in settings and restart Stream-Pi Server." +
+ "If the problem still persists, consider contacting us. \n\nFull Message : "+e.getMessage()));
+ e.printStackTrace();
+ }
+ }
+ catch (IOException e)
+ {
exceptionAndAlertHandler.handleSevereException(new SevereException("MainServer io Exception occurred!"));
e.printStackTrace();
}
}
+ private void setupStageTitle(boolean isSuccess)
+ {
+ try
+ {
+ if(isSuccess)
+ {
+ StringBuilder ips = new StringBuilder();
+ Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
+ while(e.hasMoreElements())
+ {
+ NetworkInterface n = e.nextElement();
+ Enumeration<InetAddress> ee = n.getInetAddresses();
+ while (ee.hasMoreElements())
+ {
+ InetAddress i = ee.nextElement();
+ String hostAddress = i.getHostAddress();
+ if(i instanceof Inet4Address)
+ {
+ ips.append(hostAddress);
+ if(e.hasMoreElements())
+ ips.append(" / ");
+ }
+ }
+ }
+
+ Platform.runLater(()-> serverListener.getStage().setTitle("Stream-Pi Server - IP(s): "+ips+" | Port: "+ port));
+ }
+ else
+ {
+ Platform.runLater(()-> serverListener.getStage().setTitle("Stream-Pi Server - Offline"));
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ exceptionAndAlertHandler.handleMinorException(new MinorException("Error",e.getMessage()));
+ }
+ }
}
--- 'a/src/main/java/com/stream_pi/server/connection/ServerListener.java'
+++ b/src/main/java/com/stream_pi/server/connection/ServerListener.java
@@ -1,13 +1,28 @@
package com.stream_pi.server.connection;
-import com.stream_pi.actionapi.normalaction.NormalAction;
+import com.stream_pi.action_api.externalplugin.NormalAction;
+import com.stream_pi.action_api.externalplugin.ToggleAction;
+import com.stream_pi.server.window.dashboard.ClientAndProfileSelectorPane;
+import com.stream_pi.server.window.dashboard.DashboardBase;
+import com.stream_pi.server.window.settings.SettingsBase;
+import com.stream_pi.util.exception.SevereException;
+import javafx.stage.Stage;
-public interface ServerListener {
- boolean onNormalActionClicked(NormalAction action);
+public interface ServerListener
+{
+ boolean onNormalActionClicked(NormalAction action, String profileID);
+ boolean onToggleActionClicked(ToggleAction action, boolean toggle, String profileID);
void clearTemp();
void init();
void othInit();
+
+ Stage getStage();
+
+ DashboardBase getDashboardBase();
+ SettingsBase getSettingsBase();
+
+ void initLogger() throws SevereException;
}
--- /dev/null
+++ b/src/main/java/com/stream_pi/server/controller/ActionDataFormats.java
@@ -0,0 +1,18 @@
+package com.stream_pi.server.controller;
+
+import javafx.scene.input.DataFormat;
+
+public class ActionDataFormats
+{
+ public static final DataFormat IS_NEW = new DataFormat("Is New");
+ public static final DataFormat ACTION_TYPE = new DataFormat("Action Type");
+ public static final DataFormat MODULE_NAME = new DataFormat("Module Name");
+ public static final DataFormat CLIENT_PROPERTIES = new DataFormat("Client Properties");
+ public static final DataFormat ICONS = new DataFormat("Icons");
+ public static final DataFormat CURRENT_ICON_STATE = new DataFormat("Current Icon State");
+ public static final DataFormat BACKGROUND_COLOUR = new DataFormat("Background Colour");
+ public static final DataFormat DISPLAY_TEXT_FONT_COLOUR = new DataFormat("Display Text Font Colour");
+ public static final DataFormat DISPLAY_TEXT = new DataFormat("Display Text");
+ public static final DataFormat DISPLAY_TEXT_ALIGNMENT = new DataFormat("Display Text Alignment");
+ public static final DataFormat DISPLAY_TEXT_SHOW = new DataFormat("Display Text Show");
+}
--- 'a/src/main/java/com/stream_pi/server/controller/Controller.java'
+++ b/src/main/java/com/stream_pi/server/controller/Controller.java
@@ -1,24 +1,31 @@
package com.stream_pi.server.controller;
-import com.stream_pi.actionapi.action.ServerConnection;
-import com.stream_pi.actionapi.action.PropertySaver;
-import com.stream_pi.actionapi.normalaction.NormalAction;
+import com.stream_pi.action_api.action.Action;
+import com.stream_pi.action_api.action.PropertySaver;
+import com.stream_pi.action_api.action.ServerConnection;
+import com.stream_pi.action_api.externalplugin.NormalAction;
+import com.stream_pi.action_api.externalplugin.ToggleAction;
+import com.stream_pi.action_api.externalplugin.ToggleExtras;
import com.stream_pi.server.Main;
-import com.stream_pi.server.action.NormalActionPlugins;
+import com.stream_pi.server.action.ExternalPlugins;
+import com.stream_pi.server.client.Client;
+import com.stream_pi.server.client.ClientProfile;
+import com.stream_pi.server.connection.ClientConnection;
import com.stream_pi.server.connection.ClientConnections;
import com.stream_pi.server.connection.MainServer;
-import com.stream_pi.server.io.Config;
import com.stream_pi.server.info.ServerInfo;
+import com.stream_pi.server.io.Config;
import com.stream_pi.server.window.Base;
+import com.stream_pi.server.window.dashboard.DashboardBase;
import com.stream_pi.server.window.dashboard.DonatePopupContent;
+import com.stream_pi.server.window.dashboard.actiongridpane.ActionBox;
import com.stream_pi.server.window.firsttimeuse.FirstTimeUse;
+import com.stream_pi.server.window.settings.SettingsBase;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlertListener;
import com.stream_pi.util.alert.StreamPiAlertType;
-import com.stream_pi.util.exception.MinorException;
-import com.stream_pi.util.exception.SevereException;
-import com.stream_pi.util.iohelper.IOHelper;
-
+import com.stream_pi.util.exception.*;
+import javafx.animation.Animation;
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
@@ -27,53 +34,41 @@ import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.scene.Node;
import javafx.scene.Scene;
+import javafx.scene.image.Image;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
-import java.awt.SystemTray;
import javafx.util.Duration;
+
+import java.awt.MenuItem;
+import java.awt.PopupMenu;
+import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
-import java.awt.PopupMenu;
-import java.awt.MenuItem;
-
-import java.io.File;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
+import java.net.SocketAddress;
+import java.util.Objects;
import java.util.Random;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.logging.Level;
-public class Controller extends Base implements PropertySaver, ServerConnection
+public class Controller extends Base implements PropertySaver, ServerConnection, ToggleExtras
{
- MainServer mainServer;
+ private ExecutorService executor = Executors.newCachedThreadPool();
+ private MainServer mainServer;
+ private Animation openSettingsAnimation;
+ private Animation closeSettingsAnimation;
- final SystemTray systemTray;
+ public Controller(){
+ mainServer = null;
+ }
public void setupDashWindow() throws SevereException
{
try
{
- getStage().setTitle("Stream-Pi Server - "+InetAddress.getLocalHost().getCanonicalHostName()+":"+ Config.getInstance().getPort()); //Sets title
getStage().setOnCloseRequest(this::onCloseRequest);
}
- catch (UnknownHostException e)
- {
- e.printStackTrace();
- throw new SevereException(e.getMessage());
- }
- }
-
- private void checkPrePathDirectory() throws SevereException
- {
- try {
- File filex = new File(ServerInfo.getInstance().getPrePath());
-
- if(!filex.exists())
- {
- filex.mkdirs();
- IOHelper.unzip(Main.class.getResourceAsStream("Default.obj"), ServerInfo.getInstance().getPrePath());
- }
- }
catch (Exception e)
{
e.printStackTrace();
@@ -84,39 +79,39 @@ public class Controller extends Base imp
@Override
public void init()
{
- try {
- checkPrePathDirectory();
+ try
+ {
initBase();
setupDashWindow();
-
setupSettingsWindowsAnimations();
- NormalActionPlugins.getInstance().setPropertySaver(this);
- NormalActionPlugins.getInstance().setServerConnection(this);
+ ExternalPlugins.getInstance().setPropertySaver(this);
+ ExternalPlugins.getInstance().setToggleExtras(this);
+ ExternalPlugins.getInstance().setServerConnection(this);
- getDashboardPane().getPluginsPane().getSettingsButton().setOnAction(event -> {
- openSettingsTimeLine.play();
- });
- getSettingsPane().getCloseButton().setOnAction(event -> {
- closeSettingsTimeLine.play();
+ getDashboardBase().getPluginsPane().getSettingsButton().setOnAction(event -> {
+ openSettingsAnimation.play();
});
- getSettingsPane().getThemesSettings().setController(this);
+ getSettingsBase().getCloseButton().setOnAction(event -> {
+ closeSettingsAnimation.play();
+ });
+ getSettingsBase().getThemesSettings().setController(this);
mainServer = new MainServer(this, this);
-
if(getConfig().isFirstTimeUse())
{
Stage stage = new Stage();
- Scene s = new Scene(new FirstTimeUse(this, this), 512, 300);
- stage.setResizable(false);
- stage.setScene(s);
+ Scene s = new Scene(new FirstTimeUse(this, this),
+ getConfig().getStartupWindowWidth(), getConfig().getStartupWindowHeight());
+ stage.setScene(s);
+ stage.getIcons().add(new Image(Objects.requireNonNull(Main.class.getResourceAsStream("app_icon.png"))));
stage.setTitle("Stream-Pi Server Setup");
stage.initModality(Modality.APPLICATION_MODAL);
stage.setOnCloseRequest(event->Platform.exit());
@@ -132,7 +127,6 @@ public class Controller extends Base imp
othInit();
}
-
}
catch (SevereException e)
{
@@ -145,7 +139,7 @@ public class Controller extends Base imp
{
try
{
- if(ServerInfo.getInstance().isStartMinimised())
+ if(ServerInfo.getInstance().isStartMinimised() && SystemTray.isSupported())
minimiseApp();
else
getStage().show();
@@ -154,49 +148,47 @@ public class Controller extends Base imp
{
handleMinorException(e);
}
-
- new Thread(new Task<Void>() {
+
+ executor.execute(new Task<Void>() {
@Override
protected Void call()
{
try
{
- getSettingsPane().getGeneralSettings().loadDataFromConfig();
+ getSettingsBase().getGeneralSettings().loadDataFromConfig();
//themes
- getSettingsPane().getThemesSettings().setThemes(getThemes());
- getSettingsPane().getThemesSettings().setCurrentThemeFullName(getCurrentTheme().getFullName());
- getSettingsPane().getThemesSettings().loadThemes();
+ getSettingsBase().getThemesSettings().setThemes(getThemes());
+ getSettingsBase().getThemesSettings().setCurrentThemeFullName(getCurrentTheme().getFullName());
+ getSettingsBase().getThemesSettings().loadThemes();
//clients
- getSettingsPane().getClientsSettings().loadData();
+ getSettingsBase().getClientsSettings().loadData();
try
{
-
//Plugins
Platform.runLater(()->{
- getDashboardPane().getPluginsPane().clearData();
- getDashboardPane().getPluginsPane().loadOtherActions();
+ getDashboardBase().getPluginsPane().clearData();
+ getDashboardBase().getPluginsPane().loadOtherActions();
});
- NormalActionPlugins.setPluginsLocation(getConfig().getPluginsPath());
- NormalActionPlugins.getInstance().init();
+ ExternalPlugins.setPluginsLocation(getConfig().getPluginsPath());
+ ExternalPlugins.getInstance().init();
- Platform.runLater(()->getDashboardPane().getPluginsPane().loadData());
+ Platform.runLater(()->getDashboardBase().getPluginsPane().loadData());
- getSettingsPane().getPluginsSettings().loadPlugins();
+ getSettingsBase().getPluginsSettings().loadPlugins();
}
catch (MinorException e)
{
- getSettingsPane().getPluginsSettings().showPluginInitError();
+ getSettingsBase().getPluginsSettings().showPluginInitError();
handleMinorException(e);
}
//Server
mainServer.setPort(getConfig().getPort());
mainServer.start();
-
}
catch (SevereException e)
{
@@ -204,169 +196,35 @@ public class Controller extends Base imp
}
return null;
}
- }).start();
+ });
}
private void setupSettingsWindowsAnimations()
{
- Node settingsNode = getSettingsPane();
- Node dashboardNode = getDashboardPane();
-
- openSettingsTimeLine = new Timeline();
- openSettingsTimeLine.setCycleCount(1);
-
-
- openSettingsTimeLine.getKeyFrames().addAll(
- new KeyFrame(Duration.millis(0.0D),
- new KeyValue(settingsNode.opacityProperty(),
- 0.0D, Interpolator.EASE_IN),
- new KeyValue(settingsNode.scaleXProperty(),
- 1.1D, Interpolator.EASE_IN),
- new KeyValue(settingsNode.scaleYProperty(),
- 1.1D, Interpolator.EASE_IN),
- new KeyValue(settingsNode.scaleZProperty(),
- 1.1D, Interpolator.EASE_IN)),
- new KeyFrame(Duration.millis(90.0D),
- new KeyValue(settingsNode.opacityProperty(),
- 1.0D, Interpolator.LINEAR),
- new KeyValue(settingsNode.scaleXProperty(),
- 1.0D, Interpolator.LINEAR),
- new KeyValue(settingsNode.scaleYProperty(),
- 1.0D, Interpolator.LINEAR),
- new KeyValue(settingsNode.scaleZProperty(),
- 1.0D, Interpolator.LINEAR)),
-
-
- new KeyFrame(Duration.millis(0.0D),
- new KeyValue(dashboardNode.opacityProperty(),
- 1.0D, Interpolator.LINEAR),
- new KeyValue(dashboardNode.scaleXProperty(),
- 1.0D, Interpolator.LINEAR),
- new KeyValue(dashboardNode.scaleYProperty(),
- 1.0D, Interpolator.LINEAR),
- new KeyValue(dashboardNode.scaleZProperty(),
- 1.0D, Interpolator.LINEAR)),
- new KeyFrame(Duration.millis(90.0D),
- new KeyValue(dashboardNode.opacityProperty(),
- 0.0D, Interpolator.LINEAR),
- new KeyValue(dashboardNode.scaleXProperty(),
- 0.9D, Interpolator.LINEAR),
- new KeyValue(dashboardNode.scaleYProperty(),
- 0.9D, Interpolator.LINEAR),
- new KeyValue(dashboardNode.scaleZProperty(),
- 0.9D, Interpolator.LINEAR))
- );
-
- openSettingsTimeLine.setOnFinished(event1 -> {
- settingsNode.toFront();
- });
-
-
- closeSettingsTimeLine = new Timeline();
- closeSettingsTimeLine.setCycleCount(1);
-
- closeSettingsTimeLine.getKeyFrames().addAll(
-
- new KeyFrame(Duration.millis(0.0D),
- new KeyValue(settingsNode.opacityProperty(),
- 1.0D, Interpolator.LINEAR),
- new KeyValue(settingsNode.scaleXProperty(),
- 1.0D, Interpolator.LINEAR),
- new KeyValue(settingsNode.scaleYProperty(),
- 1.0D, Interpolator.LINEAR),
- new KeyValue(settingsNode.scaleZProperty(),
- 1.0D, Interpolator.LINEAR)),
- new KeyFrame(Duration.millis(90.0D),
- new KeyValue(settingsNode.opacityProperty(),
- 0.0D, Interpolator.LINEAR),
- new KeyValue(settingsNode.scaleXProperty(),
- 1.1D, Interpolator.LINEAR),
- new KeyValue(settingsNode.scaleYProperty(),
- 1.1D, Interpolator.LINEAR),
- new KeyValue(settingsNode.scaleZProperty(),
- 1.1D, Interpolator.LINEAR)),
-
- new KeyFrame(Duration.millis(0.0D),
- new KeyValue(dashboardNode.opacityProperty(),
- 0.0D, Interpolator.LINEAR),
- new KeyValue(dashboardNode.scaleXProperty(),
- 0.9D, Interpolator.LINEAR),
- new KeyValue(dashboardNode.scaleYProperty(),
- 0.9D, Interpolator.LINEAR),
- new KeyValue(dashboardNode.scaleZProperty(),
- 0.9D, Interpolator.LINEAR)),
- new KeyFrame(Duration.millis(90.0D),
- new KeyValue(dashboardNode.opacityProperty(),
- 1.0D, Interpolator.LINEAR),
- new KeyValue(dashboardNode.scaleXProperty(),
- 1.0D, Interpolator.LINEAR),
- new KeyValue(dashboardNode.scaleYProperty(),
- 1.0D, Interpolator.LINEAR),
- new KeyValue(dashboardNode.scaleZProperty(),
- 1.0D, Interpolator.LINEAR))
-
- );
-
- closeSettingsTimeLine.setOnFinished(event1 -> {
- dashboardNode.toFront();
- new Thread(new Task<Void>() {
- @Override
- protected Void call() {
- try {
- getSettingsPane().getClientsSettings().loadData();
-
- getSettingsPane().getGeneralSettings().loadDataFromConfig();
- getSettingsPane().getPluginsSettings().loadPlugins();
+ Node settingsNode = getSettingsBase();
+ Node dashboardNode = getDashboardBase();
- getSettingsPane().getThemesSettings().setThemes(getThemes());
- getSettingsPane().getThemesSettings().setCurrentThemeFullName(getCurrentTheme().getFullName());
- getSettingsPane().getThemesSettings().loadThemes();
-
- getSettingsPane().setDefaultTabToGeneral();
- }
- catch (SevereException e)
- {
- handleSevereException(e);
- }
- catch (MinorException e)
- {
- handleMinorException(e);
- }
- return null;
- }
- }).start();
- });
- }
-
- private Timeline openSettingsTimeLine;
- private Timeline closeSettingsTimeLine;
-
-
- public Controller(){
- systemTray = SystemTray.getSystemTray();
- mainServer = null;
+ openSettingsAnimation = createOpenSettingsAnimation(settingsNode, dashboardNode);
+ closeSettingsAnimation = createCloseSettingsAnimation(settingsNode, dashboardNode);
}
public void onCloseRequest(WindowEvent event)
{
try
{
- if(Config.getInstance().getCloseOnX())
- {
- getConfig().setStartupWindowSize(
- getWidth(),
- getHeight()
- );
- getConfig().save();
- onQuitApp();
- NormalActionPlugins.getInstance().shutDownActions();
- Platform.exit();
- }
- else
+ if(Config.getInstance().getMinimiseToSystemTrayOnClose() &&
+ SystemTray.isSupported())
{
minimiseApp();
event.consume();
+ return;
}
+
+ getConfig().setStartupWindowSize(getWidth(), getHeight());
+ getConfig().save();
+ onQuitApp();
+ ExternalPlugins.getInstance().shutDownActions();
+ Platform.exit();
}
catch (SevereException e)
{
@@ -378,6 +236,7 @@ public class Controller extends Base imp
}
finally
{
+ getLogger().info("Shut down");
closeLogger();
}
}
@@ -388,7 +247,7 @@ public class Controller extends Base imp
mainServer.stopListeningForConnections();
ClientConnections.getInstance().disconnectAll();
-
+ executor.shutdown();
getLogger().info("Shutting down ...");
}
@@ -396,20 +255,17 @@ public class Controller extends Base imp
{
try
{
+ SystemTray systemTray = SystemTray.getSystemTray();
- if(SystemTray.isSupported())
- {
- if(getTrayIcon() == null)
- initIconTray();
-
- systemTray.add(getTrayIcon());
- //getStage().setIconified(true);
- getStage().hide();
- }
- else
- {
- new StreamPiAlert("System Tray Error", "Your System does not support System Tray", StreamPiAlertType.ERROR).show();
- }
+ if(getTrayIcon() == null)
+ initIconTray(systemTray);
+
+ systemTray.add(getTrayIcon());
+ getStage().hide();
+
+ getStage().setOnShown(windowEvent -> {
+ systemTray.remove(getTrayIcon());
+ });
}
catch(Exception e)
{
@@ -417,21 +273,12 @@ public class Controller extends Base imp
}
}
- public void initIconTray()
+ public void initIconTray(SystemTray systemTray)
{
Platform.setImplicitExit(false);
PopupMenu popup = new PopupMenu();
-
- MenuItem showItem = new MenuItem("Show");
- showItem.addActionListener(l->{
- systemTray.remove(getTrayIcon());
- Platform.runLater(()->{
- //getStage().setIconified(false);
- getStage().show();
- });
- });
MenuItem exitItem = new MenuItem("Exit");
exitItem.addActionListener(l->{
@@ -440,8 +287,6 @@ public class Controller extends Base imp
Platform.exit();
});
- popup.add(showItem);
- popup.addSeparator();
popup.add(exitItem);
TrayIcon trayIcon = new TrayIcon(
@@ -450,6 +295,12 @@ public class Controller extends Base imp
popup
);
+ trayIcon.addActionListener(l-> Platform.runLater(()-> {
+ getStage().show();
+ getStage().setAlwaysOnTop(true);
+ getStage().setAlwaysOnTop(false);
+ }));
+
trayIcon.setImageAutoSize(true);
this.trayIcon = trayIcon;
@@ -463,16 +314,18 @@ public class Controller extends Base imp
}
@Override
- public void handleMinorException(MinorException e) {
- getLogger().log(Level.SEVERE, e.getMessage());
+ public void handleMinorException(MinorException e)
+ {
+ getLogger().log(Level.SEVERE, e.getMessage(), e);
e.printStackTrace();
+
Platform.runLater(()-> new StreamPiAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.WARNING).show());
}
@Override
public void handleSevereException(SevereException e) {
- getLogger().log(Level.SEVERE, e.getMessage());
+ getLogger().log(Level.SEVERE, e.getMessage(), e);
e.printStackTrace();
Platform.runLater(()->{
@@ -493,15 +346,69 @@ public class Controller extends Base imp
}
@Override
- public synchronized boolean onNormalActionClicked(NormalAction action) {
+ public synchronized boolean onNormalActionClicked(NormalAction action, String profileID)
+ {
try{
getLogger().info("action "+action.getID()+" clicked!");
-
action.onActionClicked();
return true;
}
catch (Exception e)
{
+ e.printStackTrace();
+ //check if its windows UAC related
+ if(e.getMessage().contains("operation requires elevation"))
+ {
+ handleMinorException(new MinorException(
+ "Action Execution Failed!",
+ "Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
+ "This action requires higher UAC privileges. Re-launch Stream-Pi Server with 'Administrator Privileges' in order to run this command.")
+ );
+ }
+ else
+ {
+ handleMinorException(new MinorException(
+ "Action Execution Failed!",
+ "Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
+ "Check stacktrace/log to know what exactly happened\n\nMessage : \n"+e.getMessage() )
+ );
+ }
+ return false;
+ }
+ }
+
+ @Override
+ public boolean onToggleActionClicked(ToggleAction action, boolean toggle, String profileID)
+ {
+ try{
+ getLogger().info("action "+action.getID()+" clicked!");
+
+
+
+ if(toggle)
+ {
+ action.onToggleOn();
+ }
+ else
+ {
+ action.onToggleOff();
+ }
+
+// ActionBox actionBox = getDashboardBase().getActionGridPane().getActionBoxByIDAndProfileID(
+// action.getID(),
+// profileID
+// );
+//
+// if(actionBox != null)
+// {
+// Platform.runLater(()->actionBox.init(toggle));
+// }
+
+ return true;
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
//check if its windows UAC related
if(e.getMessage().contains("operation requires elevation"))
{
@@ -526,26 +433,326 @@ public class Controller extends Base imp
@Override
public void clearTemp() {
Platform.runLater(() -> {
- getDashboardPane().getClientDetailsPane().refresh();
- getDashboardPane().getActionGridPane().clear();
- getDashboardPane().getActionDetailsPane().clear();
- getSettingsPane().getClientsSettings().loadData();
+ getDashboardBase().getClientAndProfileSelectorPane().refresh();
+ getDashboardBase().getActionGridPane().clear();
+ getDashboardBase().getActionGridPane().setFreshRender(true);
+ getDashboardBase().getActionDetailsPane().clear();
+ getSettingsBase().getClientsSettings().loadData();
});
}
@Override
- public void saveServerProperties() {
- try {
- NormalActionPlugins.getInstance().saveServerSettings();
- getSettingsPane().getPluginsSettings().loadPlugins();
+ public void saveServerProperties()
+ {
+ try
+ {
+ ExternalPlugins.getInstance().saveServerSettings();
+ getSettingsBase().getPluginsSettings().loadPlugins();
} catch (MinorException e) {
e.printStackTrace();
handleMinorException(e);
}
}
+ private void saveClientActionMain(String profileID, String actionID, SocketAddress socketAddress, boolean sendIcons)
+ {
+ try {
+ ClientConnection clientConnection = ClientConnections.getInstance().getClientConnectionBySocketAddress(socketAddress);
+
+ ClientProfile clientProfile = clientConnection.getClient().getProfileByID(profileID);
+
+ Action action = clientProfile.getActionByID(actionID);
+ clientConnection.saveActionDetails(profileID, action);
+
+ if(sendIcons && action.isHasIcon())
+ {
+ saveAllIcons(profileID, actionID, socketAddress, false);
+ }
+
+
+ Platform.runLater(()->{
+ try {
+
+ ActionBox actionBox = getDashboardBase().getActionGridPane().getActionBoxByIDAndProfileID(
+ action.getID(),
+ profileID
+ );
+
+ if(actionBox != null)
+ {
+ Platform.runLater(actionBox::init);
+ }
+
+ if(getDashboardBase().getActionDetailsPane().getAction() != null)
+ {
+ // This block is executed when no Action is selected.
+ if(getDashboardBase().getActionDetailsPane().getAction().getID().equals(actionID))
+ {
+ getDashboardBase().getActionDetailsPane().setAction(action);
+ getDashboardBase().getActionDetailsPane().refresh();
+ }
+ }
+
+
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ });
+ }
+ catch (SevereException e)
+ {
+ handleSevereException(e);
+ }
+ }
+
+ @Override
+ public void saveClientAction(String profileID, String actionID, SocketAddress socketAddress, boolean sendIcons, boolean runAsync)
+ {
+ if(runAsync)
+ {
+ executor.execute(new Task<Void>() {
+ @Override
+ protected Void call()
+ {
+ saveClientActionMain(profileID, actionID, socketAddress, sendIcons);
+ return null;
+ }
+ });
+ }
+ else
+ {
+ saveClientActionMain(profileID, actionID, socketAddress, sendIcons);
+ }
+ }
+
+ @Override
+ public void saveAllIcons(String profileID, String actionID, SocketAddress socketAddress)
+ {
+ saveAllIcons(profileID, actionID, socketAddress, true);
+ }
+
+
+ public void saveAllIcons(String profileID, String actionID, SocketAddress socketAddress, boolean async)
+ {
+ if(async)
+ {
+ executor.execute(new Task<Void>() {
+ @Override
+ protected Void call()
+ {
+ saveAllIconsMain(profileID, actionID, socketAddress);
+ return null;
+ }
+ });
+ }
+ else
+ {
+ saveAllIconsMain(profileID, actionID, socketAddress);
+ }
+ }
+
+ private void saveAllIconsMain(String profileID, String actionID, SocketAddress socketAddress)
+ {
+ try {
+ ClientConnection clientConnection = ClientConnections.getInstance().getClientConnectionBySocketAddress(socketAddress);
+
+ ClientProfile clientProfile = clientConnection.getClient().getProfileByID(profileID);
+ Action action = clientProfile.getActionByID(actionID);
+
+ for(String eachState : action.getIcons().keySet())
+ {
+ clientConnection.sendIcon(profileID, actionID, eachState,
+ action.getIcon(eachState));
+ }
+ }
+ catch (SevereException e)
+ {
+ handleSevereException(e);
+ }
+ }
+
+ @Override
+ public void saveIcon(String state, String profileID, String actionID, SocketAddress socketAddress) {
+ executor.execute(new Task<Void>() {
+ @Override
+ protected Void call()
+ {
+ try {
+ ClientConnection clientConnection = ClientConnections.getInstance().getClientConnectionBySocketAddress(socketAddress);
+
+ ClientProfile clientProfile = clientConnection.getClient().getProfileByID(profileID);
+ Action action = clientProfile.getActionByID(actionID);
+
+ clientConnection.sendIcon(profileID, actionID, state, action.getIcon(state));
+ }
+ catch (SevereException e)
+ {
+ handleSevereException(e);
+ }
+ return null;
+ }
+ });
+ }
+
@Override
public com.stream_pi.util.platform.Platform getPlatform() {
- return ServerInfo.getInstance().getPlatformType();
+ return ServerInfo.getInstance().getPlatform();
+ }
+
+ private Animation createOpenSettingsAnimation(Node settingsNode, Node dashboardNode) {
+ Timeline openSettingsTimeline = new Timeline();
+ openSettingsTimeline.setCycleCount(1);
+
+ openSettingsTimeline.getKeyFrames().addAll(
+ new KeyFrame(Duration.millis(0.0D),
+ new KeyValue(settingsNode.opacityProperty(),
+ 0.0D, Interpolator.EASE_IN),
+ new KeyValue(settingsNode.scaleXProperty(),
+ 1.1D, Interpolator.EASE_IN),
+ new KeyValue(settingsNode.scaleYProperty(),
+ 1.1D, Interpolator.EASE_IN),
+ new KeyValue(settingsNode.scaleZProperty(),
+ 1.1D, Interpolator.EASE_IN)),
+ new KeyFrame(Duration.millis(90.0D),
+ new KeyValue(settingsNode.opacityProperty(),
+ 1.0D, Interpolator.LINEAR),
+ new KeyValue(settingsNode.scaleXProperty(),
+ 1.0D, Interpolator.LINEAR),
+ new KeyValue(settingsNode.scaleYProperty(),
+ 1.0D, Interpolator.LINEAR),
+ new KeyValue(settingsNode.scaleZProperty(),
+ 1.0D, Interpolator.LINEAR)),
+
+ new KeyFrame(Duration.millis(0.0D),
+ new KeyValue(dashboardNode.opacityProperty(),
+ 1.0D, Interpolator.LINEAR),
+ new KeyValue(dashboardNode.scaleXProperty(),
+ 1.0D, Interpolator.LINEAR),
+ new KeyValue(dashboardNode.scaleYProperty(),
+ 1.0D, Interpolator.LINEAR),
+ new KeyValue(dashboardNode.scaleZProperty(),
+ 1.0D, Interpolator.LINEAR)),
+ new KeyFrame(Duration.millis(90.0D),
+ new KeyValue(dashboardNode.opacityProperty(),
+ 0.0D, Interpolator.LINEAR),
+ new KeyValue(dashboardNode.scaleXProperty(),
+ 0.9D, Interpolator.LINEAR),
+ new KeyValue(dashboardNode.scaleYProperty(),
+ 0.9D, Interpolator.LINEAR),
+ new KeyValue(dashboardNode.scaleZProperty(),
+ 0.9D, Interpolator.LINEAR))
+ );
+
+ openSettingsTimeline.setOnFinished(e -> settingsNode.toFront());
+ return openSettingsTimeline;
+ }
+
+ private Animation createCloseSettingsAnimation(Node settingsNode, Node dashboardNode) {
+ Timeline closeSettingsTimeline = new Timeline();
+ closeSettingsTimeline.setCycleCount(1);
+
+ closeSettingsTimeline.getKeyFrames().addAll(
+
+ new KeyFrame(Duration.millis(0.0D),
+ new KeyValue(settingsNode.opacityProperty(),
+ 1.0D, Interpolator.LINEAR),
+ new KeyValue(settingsNode.scaleXProperty(),
+ 1.0D, Interpolator.LINEAR),
+ new KeyValue(settingsNode.scaleYProperty(),
+ 1.0D, Interpolator.LINEAR),
+ new KeyValue(settingsNode.scaleZProperty(),
+ 1.0D, Interpolator.LINEAR)),
+ new KeyFrame(Duration.millis(90.0D),
+ new KeyValue(settingsNode.opacityProperty(),
+ 0.0D, Interpolator.LINEAR),
+ new KeyValue(settingsNode.scaleXProperty(),
+ 1.1D, Interpolator.LINEAR),
+ new KeyValue(settingsNode.scaleYProperty(),
+ 1.1D, Interpolator.LINEAR),
+ new KeyValue(settingsNode.scaleZProperty(),
+ 1.1D, Interpolator.LINEAR)),
+
+ new KeyFrame(Duration.millis(0.0D),
+ new KeyValue(dashboardNode.opacityProperty(),
+ 0.0D, Interpolator.LINEAR),
+ new KeyValue(dashboardNode.scaleXProperty(),
+ 0.9D, Interpolator.LINEAR),
+ new KeyValue(dashboardNode.scaleYProperty(),
+ 0.9D, Interpolator.LINEAR),
+ new KeyValue(dashboardNode.scaleZProperty(),
+ 0.9D, Interpolator.LINEAR)),
+ new KeyFrame(Duration.millis(90.0D),
+ new KeyValue(dashboardNode.opacityProperty(),
+ 1.0D, Interpolator.LINEAR),
+ new KeyValue(dashboardNode.scaleXProperty(),
+ 1.0D, Interpolator.LINEAR),
+ new KeyValue(dashboardNode.scaleYProperty(),
+ 1.0D, Interpolator.LINEAR),
+ new KeyValue(dashboardNode.scaleZProperty(),
+ 1.0D, Interpolator.LINEAR))
+
+ );
+
+ closeSettingsTimeline.setOnFinished(event1 -> {
+ dashboardNode.toFront();
+ executor.execute(new Task<Void>() {
+ @Override
+ protected Void call() {
+ try {
+ getSettingsBase().getClientsSettings().loadData();
+
+ getSettingsBase().getGeneralSettings().loadDataFromConfig();
+ getSettingsBase().getPluginsSettings().loadPlugins();
+
+ getSettingsBase().getThemesSettings().setThemes(getThemes());
+ getSettingsBase().getThemesSettings().setCurrentThemeFullName(getCurrentTheme().getFullName());
+ getSettingsBase().getThemesSettings().loadThemes();
+
+ getSettingsBase().setDefaultTabToGeneral();
+ }
+ catch (SevereException e)
+ {
+ handleSevereException(e);
+ }
+ catch (MinorException e)
+ {
+ handleMinorException(e);
+ }
+ return null;
+ }
+ });
+ });
+ return closeSettingsTimeline;
+ }
+
+ @Override
+ public void setToggleStatus(boolean currentStatus, String profileID, String actionID, SocketAddress clientSocketAddress)
+ throws MinorException
+ {
+ ClientConnection clientConnection = ClientConnections.getInstance().getClientConnectionBySocketAddress(
+ clientSocketAddress
+ );
+
+ if(clientConnection == null)
+ throw new ClientNotFoundException("setToggleStatus failed because no client found with given socket address");
+
+ new Thread(new Task<Void>() {
+ @Override
+ protected Void call()
+ {
+ try
+ {
+ clientConnection.setToggleStatus(currentStatus, profileID, actionID);
+ }
+ catch (SevereException e)
+ {
+ handleSevereException(e);
+ }
+ return null;
+ }
+ }).start();
+
}
}
--- 'a/src/main/java/com/stream_pi/server/info/ServerInfo.java'
+++ b/src/main/java/com/stream_pi/server/info/ServerInfo.java
@@ -15,7 +15,7 @@ import com.stream_pi.util.version.Versio
public class ServerInfo {
private Version version;
private final ReleaseStatus releaseStatus;
- private final Platform platformType;
+ private final Platform platform;
private String prePath;
@@ -28,26 +28,26 @@ public class ServerInfo {
private String runnerFileName = null;
private boolean startMinimised = false;
- private ServerInfo(){
+ private ServerInfo()
+ {
version = new Version(1,0,0);
minThemeSupportVersion = new Version(1,0,0);
minPluginSupportVersion = new Version(1,0,0);
commStandardVersion = new Version(1,0,0);
releaseStatus = ReleaseStatus.EA;
- prePath = "data/";
+ prePath = System.getProperty("user.home")+"/Stream-Pi/Server/";
String osName = System.getProperty("os.name").toLowerCase();
if(osName.contains("windows"))
- platformType = Platform.WINDOWS;
+ platform = Platform.WINDOWS;
else if (osName.contains("linux"))
- platformType = Platform.LINUX;
+ platform = Platform.LINUX;
else if (osName.contains("mac"))
- platformType = Platform.MAC;
+ platform = Platform.MAC;
else
- platformType = Platform.UNKNOWN;
-
+ platform = Platform.UNKNOWN;
}
@@ -76,7 +76,8 @@ public class ServerInfo {
return runnerFileName;
}
- public static synchronized ServerInfo getInstance(){
+ public static synchronized ServerInfo getInstance()
+ {
if(instance == null)
{
instance = new ServerInfo();
@@ -86,9 +87,9 @@ public class ServerInfo {
}
- public Platform getPlatformType()
+ public Platform getPlatform()
{
- return platformType;
+ return platform;
}
public Version getVersion() {
--- 'a/src/main/java/com/stream_pi/server/io/Config.java'
+++ b/src/main/java/com/stream_pi/server/io/Config.java
@@ -8,7 +8,9 @@ handler for config.xml
package com.stream_pi.server.io;
+import java.awt.*;
import java.io.File;
+import java.util.Objects;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
@@ -20,13 +22,16 @@ import javax.xml.transform.TransformerFa
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
+import com.stream_pi.server.Main;
import com.stream_pi.server.info.ServerInfo;
import com.stream_pi.util.exception.SevereException;
+import com.stream_pi.util.iohelper.IOHelper;
import com.stream_pi.util.xmlconfighelper.XMLConfigHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-public class Config {
+public class Config
+{
private static Config instance = null;
@@ -94,7 +99,7 @@ public class Config {
//default getters
public String getDefaultServerName()
{
- return "StreamPi Server";
+ return "Stream-Pi Server";
}
public int getDefaultPort()
@@ -149,17 +154,17 @@ public class Config {
//default getters
public String getDefaultCurrentThemeFullName()
{
- return "com.StreamPi.DefaultLight";
+ return "com.stream_pi.defaultlight";
}
public String getDefaultThemesPath()
{
- return "Themes/";
+ return ServerInfo.getInstance().getPrePath()+"Themes/";
}
public String getDefaultPluginsPath()
{
- return "Plugins/";
+ return ServerInfo.getInstance().getPrePath()+"Plugins/";
}
@@ -206,10 +211,10 @@ public class Config {
getDefaultStartOnBoot(), false, true, document, configFile);
}
- public boolean getCloseOnX()
+ public boolean getMinimiseToSystemTrayOnClose()
{
- return XMLConfigHelper.getBooleanProperty(getOthersElement(), "close-on-x",
- getDefaultCloseOnX(), false, true, document, configFile);
+ return XMLConfigHelper.getBooleanProperty(getOthersElement(), "minimize-to-tray-on-close",
+ getDefaultMinimiseToSystemTrayOnClose(), false, true, document, configFile);
}
public boolean isFirstTimeUse()
@@ -228,9 +233,9 @@ public class Config {
return false;
}
- public boolean getDefaultCloseOnX()
+ public boolean getDefaultMinimiseToSystemTrayOnClose()
{
- return false;
+ return true;
}
@@ -307,9 +312,9 @@ public class Config {
getOthersElement().getElementsByTagName("start-on-boot").item(0).setTextContent(value+"");
}
- public void setCloseOnX(boolean value)
+ public void setMinimiseToSystemTrayOnClose(boolean value)
{
- getOthersElement().getElementsByTagName("close-on-x").item(0).setTextContent(value+"");
+ getOthersElement().getElementsByTagName("minimize-to-tray-on-close").item(0).setTextContent(value+"");
}
public void setFirstTimeUse(boolean value)
@@ -321,4 +326,19 @@ public class Config {
{
getOthersElement().getElementsByTagName("allow-donate-popup").item(0).setTextContent(value+"");
}
+
+ public static void unzipToDefaultPrePath() throws Exception
+ {
+ IOHelper.unzip(Objects.requireNonNull(Main.class.getResourceAsStream("Default.zip")), ServerInfo.getInstance().getPrePath());
+
+ Config.getInstance().setThemesPath(ServerInfo.getInstance().getPrePath()+"Themes/");
+ Config.getInstance().setPluginsPath(ServerInfo.getInstance().getPrePath()+"Plugins/");
+
+ if(SystemTray.isSupported())
+ {
+ Config.getInstance().setMinimiseToSystemTrayOnClose(true);
+ }
+
+ Config.getInstance().save();
+ }
}
--- 'a/src/main/java/com/stream_pi/server/uipropertybox/UIPropertyBox.java'
+++ b/src/main/java/com/stream_pi/server/uipropertybox/UIPropertyBox.java
@@ -1,7 +1,8 @@
package com.stream_pi.server.uipropertybox;
-import com.stream_pi.actionapi.actionproperty.property.ControlType;
-import com.stream_pi.actionapi.actionproperty.property.Type;
+import com.stream_pi.action_api.actionproperty.property.ControlType;
+import com.stream_pi.action_api.actionproperty.property.Type;
+import java.util.List;
import javafx.scene.Node;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Slider;
@@ -60,7 +61,8 @@ public class UIPropertyBox
{
String rawValue = null;
- if (controlType == ControlType.TEXT_FIELD)
+ if (List.of(ControlType.TEXT_FIELD, ControlType.TEXT_FIELD_MASKED, ControlType.FILE_PATH)
+ .contains(controlType))
rawValue = ((TextField) controlNode).getText();
else if (controlType == ControlType.COMBO_BOX)
rawValue = ((ComboBox<String>) controlNode).getSelectionModel().getSelectedIndex() + "";
--- 'a/src/main/java/com/stream_pi/server/window/Base.java'
+++ b/src/main/java/com/stream_pi/server/window/Base.java
@@ -6,40 +6,46 @@ import com.stream_pi.server.info.ServerI
import com.stream_pi.server.Main;
import com.stream_pi.server.window.dashboard.DashboardBase;
import com.stream_pi.server.window.settings.SettingsBase;
-import com.stream_pi.themeapi.Theme;
-import com.stream_pi.themeapi.Themes;
+import com.stream_pi.theme_api.Theme;
+import com.stream_pi.theme_api.Themes;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.SevereException;
+import com.stream_pi.util.iohelper.IOHelper;
+import com.stream_pi.util.loggerhelper.StreamPiLogFallbackHandler;
import com.stream_pi.util.loggerhelper.StreamPiLogFileHandler;
+import com.stream_pi.util.platform.Platform;
import javafx.application.HostServices;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
import javafx.scene.image.Image;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Font;
import javafx.stage.Stage;
+import java.awt.*;
+import java.io.File;
+import java.util.Objects;
import java.util.logging.Logger;
public abstract class Base extends StackPane implements ExceptionAndAlertHandler, ServerListener {
private Config config;
-
private ServerInfo serverInfo;
-
private Stage stage;
-
private HostServices hostServices;
+ private SettingsBase settingsBase;
+ private DashboardBase dashboardBase;
+ private StackPane alertStackPane;
+ private StreamPiLogFileHandler logFileHandler = null;
+ private StreamPiLogFallbackHandler logFallbackHandler = null;
+ private Logger logger = null;
public Logger getLogger(){
return logger;
}
- private SettingsBase settingsBase;
- private DashboardBase dashboardBase;
-
- private StackPane alertStackPane;
-
public void setHostServices(HostServices hostServices)
{
this.hostServices = hostServices;
@@ -50,57 +56,63 @@ public abstract class Base extends Stack
return hostServices;
}
- private Logger logger = null;
- private StreamPiLogFileHandler logFileHandler = null;
-
- public void initLogger() throws SevereException
+ @Override
+ public void initLogger()
{
try
{
- if(logger != null)
+ if(logFileHandler != null)
return;
+ closeLogger();
logger = Logger.getLogger("");
- logFileHandler = new StreamPiLogFileHandler(ServerInfo.getInstance().getPrePath()+"../streampi.log");
- logger.addHandler(logFileHandler);
+
+ if(new File(ServerInfo.getInstance().getPrePath()).getAbsoluteFile().getParentFile().canWrite())
+ {
+ String path = ServerInfo.getInstance().getPrePath()+"../stream-pi-server.log";
+
+ if(ServerInfo.getInstance().getPlatform() == Platform.ANDROID)
+ path = ServerInfo.getInstance().getPrePath()+"stream-pi-server.log";
+
+ logFileHandler = new StreamPiLogFileHandler(path);
+ logger.addHandler(logFileHandler);
+ }
+ else
+ {
+ logFallbackHandler = new StreamPiLogFallbackHandler();
+ logger.addHandler(logFallbackHandler);
+ }
+
}
catch(Exception e)
{
e.printStackTrace();
- throw new SevereException("Cant get logger started!");
+
+ logFallbackHandler = new StreamPiLogFallbackHandler();
+ logger.addHandler(logFallbackHandler);
}
}
-
+
public void closeLogger()
{
if(logFileHandler != null)
logFileHandler.close();
+ else if(logFallbackHandler != null)
+ logFallbackHandler.close();
}
- public void initBase() throws SevereException {
- initLogger();
-
- getChildren().clear();
-
+ public void initBase() throws SevereException
+ {
stage = (Stage) getScene().getWindow();
- getStage().getIcons().add(new Image(Main.class.getResourceAsStream("app_icon.png")));
+ getStage().getIcons().add(new Image(Objects.requireNonNull(Main.class.getResourceAsStream("app_icon.png"))));
- getStage().setMinWidth(500);
- getStage().setMinHeight(500);
-
- config = Config.getInstance();
-
- stage.setWidth(config.getStartupWindowWidth());
- stage.setHeight(config.getStartupWindowHeight());
- stage.centerOnScreen();
-
+ getStage().setMinWidth(710);
+ getStage().setMinHeight(530);
serverInfo = ServerInfo.getInstance();
- initThemes();
-
settingsBase = new SettingsBase(getHostServices(), this, this);
settingsBase.prefWidthProperty().bind(widthProperty());
settingsBase.prefHeightProperty().bind(heightProperty());
@@ -114,20 +126,68 @@ public abstract class Base extends Stack
StreamPiAlert.setParent(alertStackPane);
- getChildren().addAll(settingsBase, dashboardBase, alertStackPane);
+ getChildren().clear();
+ getChildren().addAll(alertStackPane);
+
+ initLogger();
+
+ checkPrePathDirectory();
+
+ getChildren().addAll(settingsBase, dashboardBase);
+
+ config = Config.getInstance();
+
+ initThemes();
+
+ stage.setWidth(config.getStartupWindowWidth());
+ stage.setHeight(config.getStartupWindowHeight());
+ stage.centerOnScreen();
dashboardBase.toFront();
+ }
+ private void checkPrePathDirectory() throws SevereException
+ {
+ try
+ {
+ File filex = new File(ServerInfo.getInstance().getPrePath());
+ if(!filex.exists())
+ {
+ boolean result = filex.mkdirs();
+ if(result)
+ {
+ Config.unzipToDefaultPrePath();
+
+ initLogger();
+ }
+ else
+ {
+ setPrefSize(300,300);
+ clearStylesheets();
+ applyDefaultStylesheet();
+ applyDefaultIconsStylesheet();
+ getStage().show();
+ throw new SevereException("No storage permission. Give it!");
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new SevereException(e.getMessage());
+ }
}
public void initThemes() throws SevereException {
clearStylesheets();
registerThemes();
- applyDefaultTheme();
applyDefaultStylesheet();
+ applyDefaultTheme();
+ applyDefaultIconsStylesheet();
}
+ @Override
public Stage getStage()
{
return stage;
@@ -143,12 +203,18 @@ public abstract class Base extends Stack
logger.info("... Done!");
}
- public DashboardBase getDashboardPane()
+ public void applyDefaultIconsStylesheet()
+ {
+ Font.loadFont(Main.class.getResourceAsStream("Roboto.ttf"), 13);
+ getStylesheets().add(Main.class.getResource("default_icons.css").toExternalForm());
+ }
+
+ public DashboardBase getDashboardBase()
{
return dashboardBase;
}
- public SettingsBase getSettingsPane()
+ public SettingsBase getSettingsBase()
{
return settingsBase;
}
@@ -185,7 +251,7 @@ public abstract class Base extends Stack
currentTheme = t;
getStylesheets().addAll(t.getStylesheets());
- logger.info("... Done!");
+ logger.info("... Theme applied successfully!");
}
public void clearStylesheets()
@@ -199,7 +265,7 @@ public abstract class Base extends Stack
logger.info("Loading themes ...");
themes = new Themes(getConfig().getThemesPath(), getConfig().getCurrentThemeFullName(), serverInfo.getMinThemeSupportVersion());
- if(themes.getErrors().size()>0)
+ if(!themes.getErrors().isEmpty())
{
StringBuilder themeErrors = new StringBuilder();
@@ -218,9 +284,7 @@ public abstract class Base extends Stack
handleMinorException(new MinorException("Theme Loading issues", themeErrors.toString()));
}
-
-
- logger.info("... Done!");
+ logger.info("...Themes loaded successfully !");
}
public Themes getThemes()
@@ -232,8 +296,6 @@ public abstract class Base extends Stack
{
logger.info("Applying default theme ...");
-
-
boolean foundTheme = false;
for(Theme t: themes.getThemeList())
{
@@ -245,9 +307,7 @@ public abstract class Base extends Stack
}
}
- if(foundTheme)
- logger.info("... Done!");
- else
+ if(!foundTheme)
{
logger.info("Theme not found. reverting to light theme ...");
try {
@@ -261,9 +321,5 @@ public abstract class Base extends Stack
handleSevereException(e);
}
}
-
-
}
-
-
}
--- 'a/src/main/java/com/stream_pi/server/window/dashboard/ClientAndProfileSelectorPane.java'
+++ b/src/main/java/com/stream_pi/server/window/dashboard/ClientAndProfileSelectorPane.java
@@ -25,6 +25,7 @@ public class ClientAndProfileSelectorPan
getStyleClass().add("client_and_profile_selector_pane");
setPadding(new Insets(10));
setMinHeight(90);
+ setMaxHeight(90);
initUI();
loadData();
@@ -38,6 +39,20 @@ public class ClientAndProfileSelectorPan
private ComboBox<ClientProfile> clientProfilesComboBox;
+ private ClientProfile currentSelectedClientProfile = null;
+
+ public ClientProfile getCurrentSelectedClientProfile()
+ {
+ return currentSelectedClientProfile;
+ }
+
+ private ClientConnection currentSelectedClientConnection = null;
+
+ public ClientConnection getCurrentSelectedClientConnection()
+ {
+ return currentSelectedClientConnection;
+ }
+
public void initUI()
{
noClientsConnectedLabel = new Label("No Clients Connected");
@@ -51,6 +66,7 @@ public class ClientAndProfileSelectorPan
clientsComboBox.valueProperty().addListener((observableValue, oldVal, newVal) -> {
if(oldVal!=newVal && newVal!=null)
{
+ currentSelectedClientConnection = newVal;
dashboard.newSelectedClientConnection(newVal);
clientProfilesComboBox.setItems(FXCollections.observableArrayList(newVal.getClient().getAllClientProfiles()));
clientProfilesComboBox.setVisible(true);
@@ -93,6 +109,7 @@ public class ClientAndProfileSelectorPan
clientProfilesComboBox.valueProperty().addListener((observableValue, oldVal, newVal) -> {
if(oldVal!=newVal && newVal!=null)
{
+ currentSelectedClientProfile = newVal;
dashboard.newSelectedClientProfile(newVal);
}
});
--- 'a/src/main/java/com/stream_pi/server/window/dashboard/DashboardBase.java'
+++ b/src/main/java/com/stream_pi/server/window/dashboard/DashboardBase.java
@@ -9,13 +9,15 @@ import com.stream_pi.server.window.dashb
import com.stream_pi.server.window.ExceptionAndAlertHandler;
import com.stream_pi.util.exception.SevereException;
import javafx.application.HostServices;
+import javafx.geometry.Orientation;
+import javafx.scene.control.SplitPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
-public class DashboardBase extends HBox implements DashboardInterface {
+public class DashboardBase extends SplitPane implements DashboardInterface {
- private final VBox leftPane;
+ private final SplitPane leftSplitPane;
private Logger logger;
@@ -28,10 +30,14 @@ public class DashboardBase extends HBox
{
this.exceptionAndAlertHandler = exceptionAndAlertHandler;
logger = Logger.getLogger(DashboardBase.class.getName());
- leftPane = new VBox();
- HBox.setHgrow(leftPane, Priority.ALWAYS);
- getChildren().add(leftPane);
+ leftSplitPane = new SplitPane();
+ leftSplitPane.getStyleClass().add("dashboard_left_split_pane");
+ leftSplitPane.setOrientation(Orientation.VERTICAL);
+
+ getStyleClass().add("dashboard_right_split_pane");
+
+ getItems().add(leftSplitPane);
setPluginsPane(new PluginsPane(hostServices));
@@ -39,7 +45,7 @@ public class DashboardBase extends HBox
setActionGridPane(new ActionGridPane(exceptionAndAlertHandler));
- setActionDetailsPane(new ActionDetailsPane(exceptionAndAlertHandler, hostServices));
+ setActionDetailsPane(new ActionDetailsPane(exceptionAndAlertHandler, hostServices, getActionGridPane()));
getActionGridPane().setActionDetailsPaneListener(getActionDetailsPane());
}
@@ -50,7 +56,7 @@ public class DashboardBase extends HBox
private void setPluginsPane(PluginsPane pluginsPane)
{
this.pluginsPane = pluginsPane;
- getChildren().add(this.pluginsPane);
+ getItems().add(this.pluginsPane);
}
public PluginsPane getPluginsPane()
{
@@ -61,9 +67,10 @@ public class DashboardBase extends HBox
private void setClientDetailsPane(ClientAndProfileSelectorPane clientAndProfileSelectorPane)
{
this.clientAndProfileSelectorPane = clientAndProfileSelectorPane;
- leftPane.getChildren().add(this.clientAndProfileSelectorPane);
+ leftSplitPane.getItems().add(this.clientAndProfileSelectorPane);
}
- public ClientAndProfileSelectorPane getClientDetailsPane()
+
+ public ClientAndProfileSelectorPane getClientAndProfileSelectorPane()
{
return clientAndProfileSelectorPane;
}
@@ -72,7 +79,7 @@ public class DashboardBase extends HBox
private void setActionGridPane(ActionGridPane actionGridPane)
{
this.actionGridPane = actionGridPane;
- leftPane.getChildren().add(this.actionGridPane);
+ leftSplitPane.getItems().add(this.actionGridPane);
}
public ActionGridPane getActionGridPane()
{
@@ -83,7 +90,7 @@ public class DashboardBase extends HBox
private void setActionDetailsPane(ActionDetailsPane actionDetailsPane)
{
this.actionDetailsPane = actionDetailsPane;
- leftPane.getChildren().add(this.actionDetailsPane);
+ leftSplitPane.getItems().add(this.actionDetailsPane);
}
public ActionDetailsPane getActionDetailsPane()
{
@@ -98,8 +105,8 @@ public class DashboardBase extends HBox
}
else
{
- getActionDetailsPane().setClient(clientConnection.getClient());
- getActionGridPane().setClient(clientConnection.getClient());
+ getActionDetailsPane().setClientConnection(clientConnection);
+ getActionGridPane().setClientConnection(clientConnection);
}
}
--- 'a/src/main/java/com/stream_pi/server/window/dashboard/DonatePopupContent.java'
+++ b/src/main/java/com/stream_pi/server/window/dashboard/DonatePopupContent.java
@@ -17,9 +17,9 @@ public class DonatePopupContent{
public DonatePopupContent(HostServices hostServices, ExceptionAndAlertHandler exceptionAndAlertHandler)
{
Label label = new Label("We are a very small team working very hard on this project for best user experience.\n\n" +
- "Something like StreamPi takes time, effort and resources. But we will always keep this 100% opensource and free.\n\n" +
+ "Something like Stream-Pi takes time, effort and resources. But we will always keep this 100% opensource and free.\n\n" +
"If you find this project helpful, and would want to help us, please consider donating :)\n\n"+
- "If you are unable to do so even a small shoutout and share across social media would be very helpful.");
+ "If you are unable to do so even a small shout-out and share across social media would be very helpful.");
label.setWrapText(true);
label.getStyleClass().add("donate_request_popup_label");
--- 'a/src/main/java/com/stream_pi/server/window/dashboard/PluginsPane.java'
+++ b/src/main/java/com/stream_pi/server/window/dashboard/PluginsPane.java
@@ -1,14 +1,9 @@
package com.stream_pi.server.window.dashboard;
-import com.stream_pi.actionapi.action.Action;
-import com.stream_pi.actionapi.action.ActionType;
-import com.stream_pi.actionapi.action.DisplayTextAlignment;
-import com.stream_pi.actionapi.actionproperty.property.Property;
-import com.stream_pi.actionapi.actionproperty.property.Type;
-import com.stream_pi.actionapi.normalaction.NormalAction;
-import com.stream_pi.actionapi.otheractions.CombineAction;
-import com.stream_pi.actionapi.otheractions.FolderAction;
-import com.stream_pi.server.action.NormalActionPlugins;
+import com.stream_pi.action_api.action.ActionType;
+import com.stream_pi.action_api.externalplugin.ExternalPlugin;
+import com.stream_pi.server.action.ExternalPlugins;
+import com.stream_pi.server.controller.ActionDataFormats;
import com.stream_pi.util.uihelper.SpaceFiller;
import javafx.application.HostServices;
import javafx.geometry.Insets;
@@ -33,6 +28,7 @@ public class PluginsPane extends VBox {
public PluginsPane(HostServices hostServices)
{
setMinWidth(250);
+ setMaxWidth(350);
getStyleClass().add("plugins_pane");
setPadding(new Insets(10));
@@ -62,7 +58,7 @@ public class PluginsPane extends VBox {
Label pluginsLabel = new Label("Plugins");
pluginsLabel.getStyleClass().add("plugins_pane_top_label");
- getChildren().addAll(pluginsLabel, pluginsAccordion, new SpaceFiller(SpaceFiller.FillerType.VBox), settingsHBox);
+ getChildren().addAll(pluginsLabel, pluginsAccordion, SpaceFiller.vertical(), settingsHBox);
}
public Button getSettingsButton()
@@ -77,7 +73,7 @@ public class PluginsPane extends VBox {
public void loadData()
{
- HashMap<String, ArrayList<NormalAction>> sortedPlugins = NormalActionPlugins.getInstance().getSortedPlugins();
+ HashMap<String, ArrayList<ExternalPlugin>> sortedPlugins = ExternalPlugins.getInstance().getSortedPlugins();
for(String eachCategory : sortedPlugins.keySet())
{
@@ -86,7 +82,7 @@ public class PluginsPane extends VBox {
TitledPane pane = new TitledPane(eachCategory, vBox);
pane.getStyleClass().add("plugins_pane_each_plugin_category_titled_pane");
- for(NormalAction eachAction : sortedPlugins.get(eachCategory))
+ for(ExternalPlugin eachAction : sortedPlugins.get(eachCategory))
{
if(!eachAction.isVisibleInPluginsPane())
continue;
@@ -129,7 +125,9 @@ public class PluginsPane extends VBox {
ClipboardContent content = new ClipboardContent();
- content.put(Action.getDataFormat(), createFakeAction(eachAction, "Untitled action"));
+ content.put(ActionDataFormats.ACTION_TYPE, eachAction.getActionType());
+ content.put(ActionDataFormats.MODULE_NAME, eachAction.getModuleName());
+ content.put(ActionDataFormats.IS_NEW, true);
db.setContent(content);
@@ -167,44 +165,6 @@ public class PluginsPane extends VBox {
private HostServices hostServices;
- public Action createFakeAction(Action action, String displayText)
- {
- Action newAction = new Action(action.getActionType());
-
- if(action.getActionType() == ActionType.NORMAL)
- {
- newAction.setModuleName(action.getModuleName());
- newAction.setVersion(action.getVersion());
- newAction.setName(action.getName());
- }
-
- newAction.setClientProperties(action.getClientProperties());
-
- for(Property property : newAction.getClientProperties().get())
- {
- if(property.getType() == Type.STRING || property.getType() == Type.INTEGER || property.getType() == Type.DOUBLE)
- property.setRawValue(property.getDefaultRawValue());
- }
-
- // newAction.setLocation(location);
-
- newAction.setIDRandom();
-
-
- newAction.setShowDisplayText(true);
- newAction.setDisplayText(displayText);
- newAction.setDisplayTextAlignment(DisplayTextAlignment.CENTER);
- newAction.setShowIcon(false);
- newAction.setHasIcon(false);
-
- //action.setParent(root);
-
- newAction.setBgColourHex("");
- newAction.setDisplayTextFontColourHex("");
-
- return newAction;
- }
-
public void loadOtherActions()
{
VBox vBox = new VBox();
@@ -222,7 +182,7 @@ public class PluginsPane extends VBox {
ClipboardContent content = new ClipboardContent();
- content.put(Action.getDataFormat(), createFakeAction(new FolderAction(), "Untitled Folder"));
+ content.put(ActionDataFormats.ACTION_TYPE, ActionType.FOLDER);
db.setContent(content);
@@ -244,14 +204,13 @@ public class PluginsPane extends VBox {
ClipboardContent content = new ClipboardContent();
- content.put(Action.getDataFormat(), createFakeAction(new CombineAction(), "Untitled Combine"));
+ content.put(ActionDataFormats.ACTION_TYPE, ActionType.COMBINE);
db.setContent(content);
mouseEvent.consume();
});
-
HBox.setHgrow(folderActionButton, Priority.ALWAYS);
HBox h1 = new HBox(folderActionButton);
h1.getStyleClass().add("plugins_pane_each_plugin_box");
@@ -262,7 +221,7 @@ public class PluginsPane extends VBox {
vBox.getChildren().addAll(h1, h2);
- TitledPane pane = new TitledPane("StreamPi", vBox);
+ TitledPane pane = new TitledPane("Stream-Pi", vBox);
pane.getStyleClass().add("plugins_pane_each_plugin_category_titled_pane");
pluginsAccordion.getPanes().add(pane);
--- 'a/src/main/java/com/stream_pi/server/window/dashboard/actiondetailpane/ActionDetailsPane.java'
+++ b/src/main/java/com/stream_pi/server/window/dashboard/actiondetailpane/ActionDetailsPane.java
@@ -1,14 +1,17 @@
package com.stream_pi.server.window.dashboard.actiondetailpane;
-import com.stream_pi.actionapi.action.Action;
-import com.stream_pi.actionapi.action.ActionType;
-import com.stream_pi.actionapi.action.DisplayTextAlignment;
-import com.stream_pi.actionapi.action.Location;
-import com.stream_pi.actionapi.actionproperty.property.ControlType;
-import com.stream_pi.actionapi.actionproperty.property.Property;
-import com.stream_pi.actionapi.actionproperty.property.Type;
-import com.stream_pi.actionapi.otheractions.CombineAction;
-import com.stream_pi.actionapi.otheractions.FolderAction;
+import com.stream_pi.action_api.action.Action;
+import com.stream_pi.action_api.action.ActionType;
+import com.stream_pi.action_api.action.DisplayTextAlignment;
+import com.stream_pi.action_api.action.Location;
+import com.stream_pi.action_api.actionproperty.ClientProperties;
+import com.stream_pi.action_api.actionproperty.property.ControlType;
+import com.stream_pi.action_api.actionproperty.property.FileExtensionFilter;
+import com.stream_pi.action_api.actionproperty.property.Property;
+import com.stream_pi.action_api.actionproperty.property.Type;
+import com.stream_pi.action_api.externalplugin.ExternalPlugin;
+import com.stream_pi.action_api.otheractions.CombineAction;
+import com.stream_pi.action_api.otheractions.FolderAction;
import com.stream_pi.server.uipropertybox.UIPropertyBox;
import com.stream_pi.server.client.Client;
import com.stream_pi.server.client.ClientProfile;
@@ -16,6 +19,8 @@ import com.stream_pi.server.connection.C
import com.stream_pi.server.connection.ClientConnections;
import com.stream_pi.server.window.dashboard.actiongridpane.ActionBox;
import com.stream_pi.server.window.ExceptionAndAlertHandler;
+import com.stream_pi.server.controller.ActionDataFormats;
+import com.stream_pi.server.window.dashboard.actiongridpane.ActionGridPaneListener;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.uihelper.HBoxInputBox;
@@ -23,17 +28,17 @@ import com.stream_pi.util.uihelper.HBoxI
import com.stream_pi.util.uihelper.SpaceFiller;
import javafx.application.HostServices;
import javafx.collections.FXCollections;
+import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.*;
+import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
-import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
-import javafx.scene.paint.Paint;
import javafx.stage.FileChooser;
import javafx.stage.Window;
import javafx.util.Callback;
@@ -42,9 +47,11 @@ import org.kordamp.ikonli.javafx.FontIco
import java.io.File;
import java.nio.file.Files;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.logging.Logger;
-public class ActionDetailsPane extends VBox implements ActionDetailsPaneListener {
+public class ActionDetailsPane extends VBox implements ActionDetailsPaneListener
+{
private ScrollPane scrollPane;
@@ -54,9 +61,12 @@ public class ActionDetailsPane extends V
private Button saveButton;
private Button deleteButton;
private Button openFolderButton;
+ private Button resetToDefaultsFolderButton;
private HBox buttonBar;
+ private VBox pluginExtraButtonBar;
+
private Label actionHeadingLabel;
private Logger logger;
@@ -67,9 +77,14 @@ public class ActionDetailsPane extends V
private HostServices hostServices;
- public ActionDetailsPane(ExceptionAndAlertHandler exceptionAndAlertHandler, HostServices hostServices) {
+ private ActionGridPaneListener actionGridPaneListener;
+
+ public ActionDetailsPane(ExceptionAndAlertHandler exceptionAndAlertHandler, HostServices hostServices,
+ ActionGridPaneListener actionGridPaneListener)
+ {
this.hostServices = hostServices;
this.exceptionAndAlertHandler = exceptionAndAlertHandler;
+ this.actionGridPaneListener = actionGridPaneListener;
logger = Logger.getLogger(ActionDetailsPane.class.getName());
@@ -84,6 +99,10 @@ public class ActionDetailsPane extends V
vbox.setSpacing(10.0);
+ pluginExtraButtonBar = new VBox();
+ pluginExtraButtonBar.setSpacing(10.0);
+
+
getStyleClass().add("action_details_pane");
scrollPane = new ScrollPane();
@@ -91,7 +110,7 @@ public class ActionDetailsPane extends V
scrollPane.getStyleClass().add("action_details_pane_scroll_pane");
- setMinHeight(310);
+ setMinHeight(210);
scrollPane.setContent(vbox);
vbox.prefWidthProperty().bind(scrollPane.widthProperty());
@@ -102,12 +121,15 @@ public class ActionDetailsPane extends V
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
openFolderButton = new Button("Open Folder");
+ openFolderButton.managedProperty().bind(openFolderButton.visibleProperty());
FontIcon folderOpenIcon = new FontIcon("far-folder-open");
openFolderButton.setGraphic(folderOpenIcon);
openFolderButton.setOnAction(event -> onOpenFolderButtonClicked());
saveButton = new Button("Apply Changes");
- FontIcon syncIcon = new FontIcon("fas-sync-alt");
+ saveButton.getStyleClass().add("action_details_pane_save_button");
+ FontIcon syncIcon = new FontIcon("far-save");
+ syncIcon.getStyleClass().add("action_details_save_delete_button_icon");
saveButton.setGraphic(syncIcon);
saveButton.setOnAction(event -> onSaveButtonClicked());
@@ -116,22 +138,30 @@ public class ActionDetailsPane extends V
FontIcon deleteIcon = new FontIcon("fas-trash");
deleteIcon.getStyleClass().add("action_details_pane_delete_button_icon");
deleteButton.setGraphic(deleteIcon);
-
deleteButton.setOnAction(event -> onDeleteButtonClicked());
+
+ resetToDefaultsFolderButton = new Button("Reset");
+ resetToDefaultsFolderButton.managedProperty().bind(resetToDefaultsFolderButton.visibleProperty());
+ resetToDefaultsFolderButton.getStyleClass().add("action_details_pane_reset_button");
+ FontIcon resetToDefaultsIcon = new FontIcon("fas-sync-alt");
+ resetToDefaultsIcon.getStyleClass().add("action_details_pane_reset_button_icon");
+ resetToDefaultsFolderButton.setGraphic(resetToDefaultsIcon);
+ resetToDefaultsFolderButton.setOnAction(event -> onResetToDefaultsButtonClicked());
+
returnButtonForCombineActionChild = new Button("Return");
returnButtonForCombineActionChild.setGraphic(new FontIcon("fas-caret-left"));
returnButtonForCombineActionChild.managedProperty().bind(returnButtonForCombineActionChild.visibleProperty());
returnButtonForCombineActionChild.setOnAction(event -> {
try {
- logger.info("@@## : " + action.getParent());
- onActionClicked(getClientProfile().getActionByID(action.getParent()), getActionBox());
+ logger.info("@@## : " + getAction().getParent());
+ onActionClicked(getClientProfile().getActionByID(getAction().getParent()), getActionBox());
} catch (MinorException e) {
e.printStackTrace();
}
});
- buttonBar = new HBox(openFolderButton, returnButtonForCombineActionChild, saveButton, deleteButton);
+ buttonBar = new HBox(openFolderButton, resetToDefaultsFolderButton, returnButtonForCombineActionChild, saveButton, deleteButton);
buttonBar.getStyleClass().add("action_details_pane_button_bar");
buttonBar.setPadding(new Insets(10, 10, 10, 0));
buttonBar.setAlignment(Pos.CENTER_RIGHT);
@@ -175,23 +205,58 @@ public class ActionDetailsPane extends V
displayNameTextField = new TextField();
displayNameTextField.managedProperty().bind(displayNameTextField.visibleProperty());
- iconFileTextField = new TextField();
- iconFileTextField.managedProperty().bind(iconFileTextField.visibleProperty());
- iconFileTextField.textProperty().addListener((observableValue, s, t1) -> {
+ defaultIconFileTextField = new TextField();
+ defaultIconFileTextField.textProperty().addListener((observableValue, s, t1) -> {
try {
if (!s.equals(t1) && t1.length() > 0) {
byte[] iconFileByteArray = Files.readAllBytes(new File(t1).toPath());
- hideIconCheckBox.setDisable(false);
- hideIconCheckBox.setSelected(false);
+ hideDefaultIconCheckBox.setDisable(false);
+ hideDefaultIconCheckBox.setSelected(false);
clearIconButton.setDisable(false);
- System.out.println("ABABABABABBABABBABABABCCCCCCCCCCCCCCCCCC");
+ getAction().addIcon("default", iconFileByteArray);
+ getAction().setCurrentIconState("default");
+ setSendIcon(true);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ exceptionAndAlertHandler.handleMinorException(new MinorException(e.getMessage()));
+ }
+ });
- action.setIcon(iconFileByteArray);
+ toggleOffIconFileTextField = new TextField();
+ toggleOffIconFileTextField.textProperty().addListener((observableValue, s, t1) -> {
+ try {
+ if (!s.equals(t1) && t1.length() > 0) {
+ byte[] iconFileByteArray = Files.readAllBytes(new File(t1).toPath());
+
+ hideToggleOffIconCheckBox.setDisable(false);
+ hideToggleOffIconCheckBox.setSelected(false);
+ clearIconButton.setDisable(false);
+
+ getAction().addIcon("toggle_off", iconFileByteArray);
setSendIcon(true);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ exceptionAndAlertHandler.handleMinorException(new MinorException(e.getMessage()));
+ }
+ });
+
+
+ toggleOnIconFileTextField = new TextField();
+ toggleOnIconFileTextField.textProperty().addListener((observableValue, s, t1) -> {
+ try {
+ if (!s.equals(t1) && t1.length() > 0) {
+ byte[] iconFileByteArray = Files.readAllBytes(new File(t1).toPath());
+
+ hideToggleOnIconCheckBox.setDisable(false);
+ hideToggleOnIconCheckBox.setSelected(false);
+ clearIconButton.setDisable(false);
- System.out.println(action.getIconAsByteArray().length);
+ getAction().addIcon("toggle_on", iconFileByteArray);
+ setSendIcon(true);
}
} catch (Exception e) {
e.printStackTrace();
@@ -199,22 +264,37 @@ public class ActionDetailsPane extends V
}
});
+
clearIconButton = new Button("Clear Icon");
clearIconButton.managedProperty().bind(clearIconButton.visibleProperty());
clearIconButton.setOnAction(event -> {
- hideIconCheckBox.setDisable(true);
- hideIconCheckBox.setSelected(false);
+ hideDefaultIconCheckBox.setDisable(true);
+ hideDefaultIconCheckBox.setSelected(false);
+
+ hideToggleOffIconCheckBox.setDisable(true);
+ hideToggleOffIconCheckBox.setSelected(false);
+
+ hideToggleOnIconCheckBox.setDisable(true);
+ hideToggleOnIconCheckBox.setSelected(false);
clearIconButton.setDisable(true);
- iconFileTextField.clear();
+
+ setSendIcon(false);
+
+ defaultIconFileTextField.clear();
+ toggleOffIconFileTextField.clear();
+ toggleOnIconFileTextField.clear();
});
hideDisplayTextCheckBox = new CheckBox("Hide");
hideDisplayTextCheckBox.managedProperty().bind(hideDisplayTextCheckBox.visibleProperty());
- hideIconCheckBox = new CheckBox("Hide");
- hideIconCheckBox.managedProperty().bind(hideIconCheckBox.visibleProperty());
+ hideDefaultIconCheckBox = new CheckBox("Hide");
+
+ hideToggleOnIconCheckBox = new CheckBox("Hide");
+
+ hideToggleOffIconCheckBox = new CheckBox("Hide");
actionBackgroundColourPicker = new ColorPicker();
actionBackgroundColourPicker.managedProperty().bind(actionBackgroundColourPicker.visibleProperty());
@@ -226,8 +306,8 @@ public class ActionDetailsPane extends V
actionBackgroundColourPicker.disableProperty()
.bind(actionBackgroundColourTransparentCheckBox.selectedProperty());
- HBox.setMargin(actionBackgroundColourTransparentCheckBox, new Insets(0, 0, 0, 10));
-
+ HBox.setMargin(actionBackgroundColourTransparentCheckBox, new Insets(0, 0, 0, 10));
+
displayTextColourDefaultCheckBox = new CheckBox("Default");
displayTextColourPicker.disableProperty()
@@ -235,18 +315,12 @@ public class ActionDetailsPane extends V
HBox.setMargin(displayTextColourDefaultCheckBox, new Insets(0, 0, 0, 10));
- Region r = new Region();
- HBox.setHgrow(r, Priority.ALWAYS);
-
- Region r1 = new Region();
- HBox.setHgrow(r1, Priority.ALWAYS);
-
- HBox displayTextColourHBox = new HBox(new Label("Display Text Colour"), r1, displayTextColourPicker,
+ HBox displayTextColourHBox = new HBox(new Label("Display Text Colour"), SpaceFiller.horizontal(), displayTextColourPicker,
displayTextColourDefaultCheckBox);
displayTextColourHBox.setAlignment(Pos.CENTER);
displayTextColourHBox.setSpacing(5.0);
- HBox bgColourHBox = new HBox(new Label("Background Colour"), r, actionBackgroundColourPicker,
+ HBox bgColourHBox = new HBox(new Label("Background Colour"), SpaceFiller.horizontal(), actionBackgroundColourPicker,
actionBackgroundColourTransparentCheckBox);
bgColourHBox.setAlignment(Pos.CENTER);
bgColourHBox.setSpacing(5.0);
@@ -256,26 +330,50 @@ public class ActionDetailsPane extends V
displayTextFieldHBox = new HBoxInputBox("Display Name", displayNameTextField, hideDisplayTextCheckBox);
- normalActionsPropsVBox = new VBox(displayTextColourHBox,
- new HBox(new Label("Alignment"), new SpaceFiller(SpaceFiller.FillerType.HBox),
- displayTextAlignmentComboBox),
+ HBox alignmentHBox = new HBox(new Label("Alignment"), SpaceFiller.horizontal(),
+ displayTextAlignmentComboBox);
+
- new HBoxInputBoxWithFileChooser("Icon", iconFileTextField, hideIconCheckBox,
- new FileChooser.ExtensionFilter("Images", "*.jpeg", "*.jpg", "*.png", "*.gif")),
- clearIconHBox, bgColourHBox);
+ normalToggleActionCommonPropsVBox = new VBox(
+ displayTextColourHBox,
+ alignmentHBox,
+ bgColourHBox,
+ clearIconHBox
+ );
+
+ normalToggleActionCommonPropsVBox.managedProperty().bind(normalToggleActionCommonPropsVBox.visibleProperty());
+ normalToggleActionCommonPropsVBox.setSpacing(10.0);
+
+ normalActionsPropsVBox = new VBox(
+ new HBoxInputBoxWithFileChooser("Icon", defaultIconFileTextField, hideDefaultIconCheckBox,
+ new FileChooser.ExtensionFilter("Images", "*.jpeg", "*.jpg", "*.png", "*.gif"))
+ );
normalActionsPropsVBox.managedProperty().bind(normalActionsPropsVBox.visibleProperty());
normalActionsPropsVBox.setSpacing(10.0);
- vbox.getChildren().addAll(displayTextFieldHBox, normalActionsPropsVBox, clientPropertiesVBox);
+ toggleActionsPropsVBox = new VBox(
+ new HBoxInputBoxWithFileChooser("Toggle Off Icon", toggleOffIconFileTextField, hideToggleOffIconCheckBox,
+ new FileChooser.ExtensionFilter("Images", "*.jpeg", "*.jpg", "*.png", "*.gif")),
+
+ new HBoxInputBoxWithFileChooser("Toggle On Icon", toggleOnIconFileTextField, hideToggleOnIconCheckBox,
+ new FileChooser.ExtensionFilter("Images", "*.jpeg", "*.jpg", "*.png", "*.gif"))
+ );
+
+ toggleActionsPropsVBox.managedProperty().bind(toggleActionsPropsVBox.visibleProperty());
+ toggleActionsPropsVBox.setSpacing(10.0);
+
+ vbox.getChildren().addAll(displayTextFieldHBox,normalToggleActionCommonPropsVBox,
+ normalActionsPropsVBox, toggleActionsPropsVBox, clientPropertiesVBox,
+ pluginExtraButtonBar);
vbox.setVisible(false);
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
setOnDragOver(dragEvent -> {
- if (dragEvent.getDragboard().hasContent(Action.getDataFormat()) && action != null) {
- if (action.getActionType() == ActionType.COMBINE) {
+ if (dragEvent.getDragboard().hasContent(ActionDataFormats.ACTION_TYPE) && action != null) {
+ if (getAction().getActionType() == ActionType.COMBINE) {
dragEvent.acceptTransferModes(TransferMode.ANY);
dragEvent.consume();
@@ -285,12 +383,54 @@ public class ActionDetailsPane extends V
setOnDragDropped(dragEvent -> {
try {
- Action newAction = (Action) dragEvent.getDragboard().getContent(Action.getDataFormat());
- if (newAction.getActionType() == ActionType.NORMAL) {
+ Dragboard db = dragEvent.getDragboard();
+
+ ActionType actionType = (ActionType) db.getContent(ActionDataFormats.ACTION_TYPE);
+
+ if(actionType == ActionType.NORMAL || actionType == ActionType.TOGGLE)
+ {
+ ExternalPlugin newAction = actionGridPaneListener.createNewActionFromExternalPlugin(
+ (String) db.getContent(ActionDataFormats.MODULE_NAME)
+ );
+
+ boolean isNew = (boolean) db.getContent(ActionDataFormats.IS_NEW);
+
+ if(isNew)
+ {
+ newAction.setDisplayText("Untitled Action");
+ newAction.setShowDisplayText(true);
+ newAction.setDisplayTextAlignment(DisplayTextAlignment.CENTER);
+
+ if(actionType == ActionType.TOGGLE)
+ newAction.setCurrentIconState("false__false");
+ }
+ else
+ {
+ newAction.setClientProperties((ClientProperties) db.getContent(ActionDataFormats.CLIENT_PROPERTIES));
+ newAction.setIcons((HashMap<String, byte[]>) db.getContent(ActionDataFormats.ICONS));
+ newAction.setCurrentIconState((String) db.getContent(ActionDataFormats.CURRENT_ICON_STATE));
+ newAction.setBgColourHex((String) db.getContent(ActionDataFormats.BACKGROUND_COLOUR));
+ newAction.setDisplayTextFontColourHex((String) db.getContent(ActionDataFormats.DISPLAY_TEXT_FONT_COLOUR));
+ newAction.setDisplayText((String) db.getContent(ActionDataFormats.DISPLAY_TEXT));
+ newAction.setDisplayTextAlignment((DisplayTextAlignment) db.getContent(ActionDataFormats.DISPLAY_TEXT_ALIGNMENT));
+ newAction.setShowDisplayText((boolean) db.getContent(ActionDataFormats.DISPLAY_TEXT_SHOW));
+ }
+
newAction.setLocation(new Location(-1, -1));
- newAction.setParent(this.action.getID());
+ newAction.setParent(getAction().getID());
+ newAction.setProfileID(actionGridPaneListener.getCurrentProfile().getID());
+ newAction.setSocketAddressForClient(actionGridPaneListener.getClientConnection().getRemoteSocketAddress());
+
+ try
+ {
+ newAction.onActionCreate();
+ }
+ catch (Exception e)
+ {
+ exceptionAndAlertHandler.handleMinorException(new MinorException("Error","onCreate() failed for "+getAction().getModuleName()+"\n\n"+e.getMessage()));
+ }
combineActionPropertiesPane.getCombineAction().addChild(newAction.getID());
@@ -303,8 +443,12 @@ public class ActionDetailsPane extends V
combineActionPropertiesPane.renderProps();
- saveAction();
+ saveAction(true, false);
+
+
+
}
+
} catch (MinorException e) {
exceptionAndAlertHandler.handleMinorException(e);
e.printStackTrace();
@@ -313,23 +457,48 @@ public class ActionDetailsPane extends V
e.printStackTrace();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
+ } catch (Exception e)
+ {
+ e.printStackTrace();
}
});
}
+ private void onResetToDefaultsButtonClicked()
+ {
+ getAction().getClientProperties().resetToDefaults();
+
+ try
+ {
+ onActionClicked(getAction(), getActionBox());
+ saveAction(true, true);
+ }
+ catch (MinorException e)
+ {
+ exceptionAndAlertHandler.handleMinorException(e);
+ }
+ }
+
private VBox normalActionsPropsVBox;
+ private VBox normalToggleActionCommonPropsVBox;
+ private VBox toggleActionsPropsVBox;
private HBox displayTextFieldHBox;
- private Client client;
+ private ClientConnection clientConnection;
private ClientProfile clientProfile;
- public void setClient(Client client) {
- this.client = client;
+ public void setClientConnection(ClientConnection clientConnection) {
+ this.clientConnection = clientConnection;
}
- public Client getClient() {
- return client;
+ public ClientConnection getClientConnection() {
+ return clientConnection;
+ }
+
+ public Client getClient()
+ {
+ return getClientConnection().getClient();
}
public void setClientProfile(ClientProfile clientProfile) {
@@ -346,7 +515,7 @@ public class ActionDetailsPane extends V
private Action action;
- public Action getAction() {
+ public synchronized Action getAction() {
return action;
}
@@ -357,20 +526,43 @@ public class ActionDetailsPane extends V
}
@Override
- public void onActionClicked(Action action, ActionBox actionBox) throws MinorException {
- this.action = action;
- this.actionBox = actionBox;
-
- logger.info("action Display text : "+action.getDisplayText());
+ public void onActionClicked(Action action, ActionBox actionBox) throws MinorException
+ {
clear();
+ setAction(action);
+ this.actionBox = actionBox;
+
renderActionProperties();
}
+
+
+ public void refresh()
+ {
+ clear(false);
+ try
+ {
+ renderActionProperties();
+ }
+ catch (MinorException e)
+ {
+ exceptionAndAlertHandler.handleMinorException(e);
+ }
+ }
+
private TextField displayNameTextField;
private CheckBox hideDisplayTextCheckBox;
- private CheckBox hideIconCheckBox;
- private TextField iconFileTextField;
+
+ private CheckBox hideDefaultIconCheckBox;
+ private TextField defaultIconFileTextField;
+
+ private CheckBox hideToggleOnIconCheckBox;
+ private TextField toggleOnIconFileTextField;
+
+ private CheckBox hideToggleOffIconCheckBox;
+ private TextField toggleOffIconFileTextField;
+
private Button clearIconButton;
private ColorPicker actionBackgroundColourPicker;
private ColorPicker displayTextColourPicker;
@@ -378,20 +570,49 @@ public class ActionDetailsPane extends V
private CheckBox displayTextColourDefaultCheckBox;
private ComboBox<DisplayTextAlignment> displayTextAlignmentComboBox;
- public void clear()
+ public void clear(boolean actionNull)
{
sendIcon = false;
actionClientProperties.clear();
displayNameTextField.clear();
- iconFileTextField.clear();
+
+
+ defaultIconFileTextField.clear();
+ toggleOffIconFileTextField.clear();
+ toggleOnIconFileTextField.clear();
+
+
clientPropertiesVBox.getChildren().clear();
+ pluginExtraButtonBar.getChildren().clear();
vbox.setVisible(false);
+
+ normalActionsPropsVBox.setVisible(false);
+ toggleActionsPropsVBox.setVisible(false);
+ saveButton.setVisible(false);
+ openFolderButton.setVisible(false);
+ resetToDefaultsFolderButton.setVisible(false);
+ returnButtonForCombineActionChild.setVisible(false);
+ clearIconButton.setVisible(false);
+
+
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
buttonBar.setVisible(false);
setActionHeadingLabelText("");
actionBackgroundColourPicker.setValue(Color.WHITE);
displayTextColourPicker.setValue(Color.WHITE);
+
+ if(actionNull)
+ {
+ action = null;
+ actionBox = null;
+ }
+ }
+
+ @Override
+ public void clear()
+ {
+ clear(true);
}
boolean isCombineChild = false;
@@ -404,79 +625,148 @@ public class ActionDetailsPane extends V
{
//Combine Child action
- isCombineChild = action.getLocation().getCol() == -1;
+ isCombineChild = getAction().getLocation().getCol() == -1;
+
+ displayNameTextField.setText(getAction().getDisplayText());
+
+ vbox.setVisible(true);
+ scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
+
+ buttonBar.setVisible(true);
+
- displayNameTextField.setText(action.getDisplayText());
+ displayTextAlignmentComboBox.getSelectionModel().select(getAction().getDisplayTextAlignment());
+
+ if(!getAction().getBgColourHex().isEmpty())
+ actionBackgroundColourPicker.setValue(Color.valueOf(getAction().getBgColourHex()));
+ else
+ actionBackgroundColourTransparentCheckBox.setSelected(true);
+
+
+
+ if(!getAction().getDisplayTextFontColourHex().isEmpty())
+ displayTextColourPicker.setValue(Color.valueOf(getAction().getDisplayTextFontColourHex()));
+ else
+ displayTextColourDefaultCheckBox.setSelected(true);
+
+
+ hideDisplayTextCheckBox.setSelected(!getAction().isShowDisplayText());
+
+
+ if(getAction().isInvalid())
+ {
+ setActionHeadingLabelText("Invalid action ("+getAction().getModuleName()+")");
+ return;
+ }
+
+
+ saveButton.setVisible(!getAction().isInvalid());
if(isCombineChild)
{
setReturnButtonForCombineActionChildVisible(true);
normalActionsPropsVBox.setVisible(false);
+ normalToggleActionCommonPropsVBox.setVisible(false);
hideDisplayTextCheckBox.setSelected(false);
hideDisplayTextCheckBox.setVisible(false);
}
else
{
- normalActionsPropsVBox.setVisible(true);
- setReturnButtonForCombineActionChildVisible(false);
- hideDisplayTextCheckBox.setVisible(true);
- setFolderButtonVisible(action.getActionType().equals(ActionType.FOLDER));
+ normalToggleActionCommonPropsVBox.setVisible(true);
- displayTextAlignmentComboBox.getSelectionModel().select(action.getDisplayTextAlignment());
+ if(getAction().getActionType() == ActionType.TOGGLE)
+ {
+ normalActionsPropsVBox.setVisible(false);
+ toggleActionsPropsVBox.setVisible(true);
- if(!action.getBgColourHex().isEmpty())
- actionBackgroundColourPicker.setValue(Color.valueOf(action.getBgColourHex()));
- else
- actionBackgroundColourTransparentCheckBox.setSelected(true);
-
+
+ boolean doesToggleOnExist = getAction().getIcons().containsKey("toggle_on");
+ boolean isToggleOnHidden = getAction().getCurrentIconState().contains("toggle_on");
+
+
+ if(!doesToggleOnExist)
+ isToggleOnHidden = false;
+
+ hideToggleOnIconCheckBox.setDisable(!doesToggleOnExist);
+ hideToggleOnIconCheckBox.setSelected(isToggleOnHidden);
- if(!action.getDisplayTextFontColourHex().isEmpty())
- displayTextColourPicker.setValue(Color.valueOf(action.getDisplayTextFontColourHex()));
- else
- displayTextColourDefaultCheckBox.setSelected(true);
- hideDisplayTextCheckBox.setSelected(!action.isShowDisplayText());
+ boolean doesToggleOffExist = getAction().getIcons().containsKey("toggle_off");
+ boolean isToggleOffHidden = getAction().getCurrentIconState().contains("toggle_off");
- hideIconCheckBox.setDisable(!action.isHasIcon());
- hideIconCheckBox.setSelected(!action.isShowIcon());
+ if(!doesToggleOffExist)
+ isToggleOffHidden = false;
- if(!action.isHasIcon())
+ hideToggleOffIconCheckBox.setDisable(!doesToggleOffExist);
+ hideToggleOffIconCheckBox.setSelected(isToggleOffHidden);
+ }
+ else
{
- hideIconCheckBox.setSelected(false);
+ normalActionsPropsVBox.setVisible(true);
+ toggleActionsPropsVBox.setVisible(false);
+
+
+ boolean doesDefaultExist = getAction().getIcons().containsKey("default");
+ boolean isDefaultHidden = !getAction().getCurrentIconState().equals("default");
+
+ if(!doesDefaultExist)
+ isDefaultHidden = false;
+
+ hideDefaultIconCheckBox.setDisable(!doesDefaultExist);
+ hideDefaultIconCheckBox.setSelected(isDefaultHidden);
}
- clearIconButton.setDisable(!action.isHasIcon());
- }
+ setReturnButtonForCombineActionChildVisible(false);
+ hideDisplayTextCheckBox.setVisible(true);
+ setFolderButtonVisible(getAction().getActionType().equals(ActionType.FOLDER));
+ setResetToDefaultsFolderButtonVisible(!(getAction().getActionType().equals(ActionType.FOLDER) || getAction().getActionType().equals(ActionType.COMBINE)));
+
+ clearIconButton.setDisable(!getAction().isHasIcon());
+ }
- buttonBar.setVisible(true);
- vbox.setVisible(true);
- scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
- if(action.getActionType() == ActionType.NORMAL)
+ if(getAction().getActionType() == ActionType.NORMAL || getAction().getActionType() == ActionType.TOGGLE)
{
- if(action.isInvalid())
- setActionHeadingLabelText("Invalid action ("+action.getModuleName()+")");
- else
- setActionHeadingLabelText(action.getName());
+ setActionHeadingLabelText(getAction().getName());
}
- else if(action.getActionType() == ActionType.COMBINE)
+ else if(getAction().getActionType() == ActionType.COMBINE)
+ {
setActionHeadingLabelText("Combine action");
- else if(action.getActionType() == ActionType.FOLDER)
+ }
+ else if(getAction().getActionType() == ActionType.FOLDER)
+ {
setActionHeadingLabelText("Folder action");
+ }
+
- if(!action.isInvalid())
+
+ if(getAction().getActionType() == ActionType.NORMAL || getAction().getActionType() == ActionType.TOGGLE)
{
- if(action.getActionType() == ActionType.NORMAL)
- renderClientProperties();
- else if(action.getActionType() == ActionType.COMBINE)
- renderCombineActionProperties();
+ renderClientProperties();
+ renderPluginExtraButtonBar();
+ }
+ else if(getAction().getActionType() == ActionType.COMBINE)
+ renderCombineActionProperties();
+
+ }
+
+ private void renderPluginExtraButtonBar()
+ {
+ ExternalPlugin externalPlugin = (ExternalPlugin) getAction();
+
+ externalPlugin.initClientActionSettingsButtonBar();
+
+ if(externalPlugin.getClientActionSettingsButtonBar() != null)
+ {
+ HBox tba = new HBox(SpaceFiller.horizontal(), externalPlugin.getClientActionSettingsButtonBar());
+ pluginExtraButtonBar.getChildren().add(tba);
}
}
@@ -495,7 +785,7 @@ public class ActionDetailsPane extends V
{
try
{
- combineActionPropertiesPane = new CombineActionPropertiesPane(getActionAsCombineAction(action),
+ combineActionPropertiesPane = new CombineActionPropertiesPane((CombineAction) getAction(),
getClientProfile(),
this
);
@@ -509,58 +799,15 @@ public class ActionDetailsPane extends V
}
}
- public void setAction(Action action) {
+ @Override
+ public synchronized void setAction(Action action) {
this.action = action;
}
- public FolderAction getActionAsFolderAction(Action action)
- {
- FolderAction folderAction = new FolderAction();
- folderAction.setDisplayText(action.getDisplayText());
- folderAction.setName(action.getName());
- folderAction.setID(action.getID());
- folderAction.setLocation(action.getLocation());
- folderAction.setBgColourHex(action.getBgColourHex());
- folderAction.setParent(action.getParent());
- folderAction.getClientProperties().set(action.getClientProperties());
- folderAction.setDisplayTextAlignment(action.getDisplayTextAlignment());
- folderAction.setShowIcon(action.isShowIcon());
- folderAction.setHasIcon(action.isHasIcon());
- if(folderAction.isHasIcon())
- folderAction.setIcon(action.getIconAsByteArray());
- folderAction.setDisplayTextFontColourHex(action.getDisplayTextFontColourHex());
-
- return folderAction;
- }
-
- public CombineAction getActionAsCombineAction(Action action)
- {
- CombineAction combineAction = new CombineAction();
- combineAction.setDisplayText(action.getDisplayText());
- combineAction.setName(action.getName());
- combineAction.setID(action.getID());
- combineAction.setLocation(action.getLocation());
- combineAction.setBgColourHex(action.getBgColourHex());
- combineAction.setParent(action.getParent());
- combineAction.getClientProperties().set(action.getClientProperties());
- combineAction.setDisplayTextAlignment(action.getDisplayTextAlignment());
- combineAction.setShowIcon(action.isShowIcon());
- combineAction.setHasIcon(action.isHasIcon());
- if(combineAction.isHasIcon())
- combineAction.setIcon(action.getIconAsByteArray());
- combineAction.setDisplayTextFontColourHex(action.getDisplayTextFontColourHex());
-
- for(Property prop : combineAction.getClientProperties().get())
- {
- System.out.println("PROP : "+prop.getName()+","+prop.getRawValue());
- }
- return combineAction;
- }
-
+ @Override
public void onOpenFolderButtonClicked()
{
- FolderAction folderAction = getActionAsFolderAction(action);
- actionBox.getActionGridPaneListener().renderFolder(folderAction);
+ actionBox.getActionGridPaneListener().renderFolder((FolderAction) getAction());
clear();
}
@@ -571,11 +818,21 @@ public class ActionDetailsPane extends V
private ArrayList<UIPropertyBox> actionClientProperties;
+ private TextField delayBeforeRunningTextField;
+
public void renderClientProperties() throws MinorException
{
- for(int i =0;i< action.getClientProperties().getSize(); i++)
+
+ delayBeforeRunningTextField = new TextField();
+ delayBeforeRunningTextField.setText(getAction().getDelayBeforeExecuting()+"");
+
+ clientPropertiesVBox.getChildren().add(
+ new HBoxInputBox("Delay before running (milli-seconds)", delayBeforeRunningTextField, 100)
+ );
+
+ for(int i =0;i< getAction().getClientProperties().getSize(); i++)
{
- Property eachProperty = action.getClientProperties().get().get(i);
+ Property eachProperty = getAction().getClientProperties().get().get(i);
if(!eachProperty.isVisible())
continue;
@@ -599,9 +856,12 @@ public class ActionDetailsPane extends V
});
hBox.getChildren().add(helpButton);
+
+ hBox.getChildren().add(controlNode);
}
- hBox.getChildren().add(new SpaceFiller(SpaceFiller.FillerType.HBox));
+ hBox.getChildren().add(SpaceFiller.horizontal());
+
if(eachProperty.getControlType() == ControlType.COMBO_BOX)
{
@@ -611,12 +871,43 @@ public class ActionDetailsPane extends V
controlNode = comboBox;
+
+ hBox.getChildren().add(controlNode);
}
- else if(eachProperty.getControlType() == ControlType.TEXT_FIELD)
+ else if(eachProperty.getControlType() == ControlType.FILE_PATH)
{
TextField textField = new TextField(eachProperty.getRawValue());
+ FileExtensionFilter[] fileExtensionFilters = eachProperty.getExtensionFilters();
+ FileChooser.ExtensionFilter[] extensionFilters = new FileChooser.ExtensionFilter[fileExtensionFilters.length];
+
+ for(int x = 0;x<fileExtensionFilters.length;x++)
+ {
+ extensionFilters[x] = new FileChooser.ExtensionFilter(
+ fileExtensionFilters[x].getDescription(),
+ fileExtensionFilters[x].getExtensions()
+ );
+ }
+
+ hBox = new HBoxInputBoxWithFileChooser(eachProperty.getDisplayName(), textField, null,
+ extensionFilters);
+
+ controlNode = textField;
+ }
+ else if(eachProperty.getControlType() == ControlType.TEXT_FIELD)
+ {
+ controlNode= new TextField(eachProperty.getRawValue());
+
+ hBox.getChildren().add(controlNode);
+ }
+ else if(eachProperty.getControlType() == ControlType.TEXT_FIELD_MASKED)
+ {
+ PasswordField textField = new PasswordField();
+ textField.setText(eachProperty.getRawValue());
+
controlNode= textField;
+
+ hBox.getChildren().add(controlNode);
}
else if(eachProperty.getControlType() == ControlType.TOGGLE)
{
@@ -636,6 +927,8 @@ public class ActionDetailsPane extends V
});
controlNode = toggleButton;
+
+ hBox.getChildren().add(controlNode);
}
else if(eachProperty.getControlType() == ControlType.SLIDER_DOUBLE)
{
@@ -645,6 +938,8 @@ public class ActionDetailsPane extends V
slider.setMin(eachProperty.getMinDoubleValue());
controlNode = slider;
+
+ hBox.getChildren().add(controlNode);
}
else if(eachProperty.getControlType() == ControlType.SLIDER_INTEGER)
{
@@ -657,10 +952,11 @@ public class ActionDetailsPane extends V
slider.setSnapToTicks(true);
controlNode = slider;
+
+ hBox.getChildren().add(controlNode);
}
- hBox.getChildren().add(controlNode);
UIPropertyBox clientProperty = new UIPropertyBox(i, eachProperty.getDisplayName(), controlNode,
eachProperty.getControlType(), eachProperty.getType(), eachProperty.isCanBeBlank());
@@ -679,7 +975,7 @@ public class ActionDetailsPane extends V
validateForm();
- saveAction();
+ saveAction(true, true);
}
catch (MinorException e)
{
@@ -701,33 +997,39 @@ public class ActionDetailsPane extends V
}
@Override
- public void saveAction(Action action, boolean runAsync)
+ public synchronized void saveAction(Action action, boolean runAsync, boolean runOnActionSavedFromServer)
{
+ String delayBeforeRunning = "0";
+ if(action.getActionType() != ActionType.FOLDER && action.getActionType() !=ActionType.COMBINE)
+ delayBeforeRunning =delayBeforeRunningTextField.getText();
+
new OnSaveActionTask(
ClientConnections.getInstance().getClientConnectionBySocketAddress(
getClient().getRemoteSocketAddress()
),
- action,
+ action, delayBeforeRunning,
displayNameTextField.getText(),
isCombineChild(),
!hideDisplayTextCheckBox.isSelected(),
- displayTextColourDefaultCheckBox.isSelected(),
+ displayTextColourDefaultCheckBox.isSelected(),
"#" + displayTextColourPicker.getValue().toString().substring(2),
clearIconButton.isDisable(),
- !hideIconCheckBox.isSelected(),
+ hideDefaultIconCheckBox.isSelected(),
+ hideToggleOffIconCheckBox.isSelected(),
+ hideToggleOnIconCheckBox.isSelected(),
displayTextAlignmentComboBox.getSelectionModel().getSelectedItem(),
actionBackgroundColourTransparentCheckBox.isSelected(),
"#" + actionBackgroundColourPicker.getValue().toString().substring(2),
- getCombineActionPropertiesPane(),
+ getCombineActionPropertiesPane(),
clientProfile, sendIcon, actionBox, actionClientProperties, exceptionAndAlertHandler,
- saveButton, deleteButton, runAsync
+ saveButton, deleteButton, runOnActionSavedFromServer, runAsync, this
);
}
@Override
- public void saveAction()
+ public void saveAction(boolean runAsync, boolean runOnActionSavedFromServer)
{
- saveAction(action, true);
+ saveAction(getAction(), runAsync, runOnActionSavedFromServer);
}
public void setFolderButtonVisible(boolean visible)
@@ -735,6 +1037,11 @@ public class ActionDetailsPane extends V
openFolderButton.setVisible(visible);
}
+ public void setResetToDefaultsFolderButtonVisible(boolean visible)
+ {
+ resetToDefaultsFolderButton.setVisible(visible);
+ }
+
public void validateForm() throws MinorException
{
String displayNameStr = displayNameTextField.getText();
@@ -748,17 +1055,38 @@ public class ActionDetailsPane extends V
if(!isCombineChild())
{
- if(action.isHasIcon())
+ if(getAction().getActionType() == ActionType.NORMAL)
+ {
+ if(getAction().isHasIcon())
+ {
+ if(hideDisplayTextCheckBox.isSelected() && hideDefaultIconCheckBox.isSelected())
+ {
+ finalErrors.append(" * Both Icon and display text check box cannot be hidden.\n");
+ }
+ }
+ else
+ {
+ if(hideDisplayTextCheckBox.isSelected())
+ finalErrors.append(" * Display Text cannot be hidden, since there is also no icon.\n");
+ }
+ }
+ }
+
+ if(getAction().getActionType() == ActionType.NORMAL)
+ {
+ try
{
- if(hideDisplayTextCheckBox.isSelected() && hideIconCheckBox.isSelected())
- finalErrors.append(" * Both Icon and display text check box cannot be hidden.\n");
+ int n = Integer.parseInt(delayBeforeRunningTextField.getText());
+
+ if (n<0)
+ {
+ finalErrors.append(" * Sleep should be greater than 0.\n");
+ }
}
- else
+ catch (Exception e)
{
- if(hideDisplayTextCheckBox.isSelected())
- finalErrors.append(" * Display Text cannot be hidden, since there is also no icon.\n");
+ finalErrors.append(" * Sleep should be a number.\n");
}
-
}
@@ -767,7 +1095,8 @@ public class ActionDetailsPane extends V
Node controlNode = clientProperty.getControlNode();
- if (clientProperty.getControlType() == ControlType.TEXT_FIELD)
+ if (clientProperty.getControlType() == ControlType.TEXT_FIELD ||
+ clientProperty.getControlType() == ControlType.FILE_PATH)
{
String value = ((TextField) controlNode).getText();
if(clientProperty.getType() == Type.INTEGER)
@@ -805,7 +1134,7 @@ public class ActionDetailsPane extends V
),
action,
isCombineChild(),
- getCombineActionPropertiesPane(),
+ getCombineActionPropertiesPane(),
clientProfile, actionBox, this, exceptionAndAlertHandler,
!isCombineChild
);
--- 'a/src/main/java/com/stream_pi/server/window/dashboard/actiondetailpane/ActionDetailsPaneListener.java'
+++ b/src/main/java/com/stream_pi/server/window/dashboard/actiondetailpane/ActionDetailsPaneListener.java
@@ -1,23 +1,27 @@
package com.stream_pi.server.window.dashboard.actiondetailpane;
-import com.stream_pi.actionapi.action.Action;
+import com.stream_pi.action_api.action.Action;
import com.stream_pi.server.window.dashboard.actiongridpane.ActionBox;
+import com.stream_pi.server.window.dashboard.actiongridpane.ActionGridPaneListener;
import com.stream_pi.util.exception.MinorException;
import javafx.stage.Window;
public interface ActionDetailsPaneListener {
void onActionClicked(Action action, ActionBox actionBox) throws MinorException;
- void saveAction();
+ void saveAction(boolean runAsync, boolean runOnActionSavedFromServer);
- void saveAction(Action action, boolean runAsync);
+ void saveAction(Action action, boolean runAsync, boolean runOnActionSavedFromServer);
void clear();
void setSendIcon(boolean sendIcon);
+ void setAction(Action action);
+
void onOpenFolderButtonClicked();
Window getCurrentWindow();
+ void refresh();
}
--- 'a/src/main/java/com/stream_pi/server/window/dashboard/actiondetailpane/CombineActionPropertiesPane.java'
+++ b/src/main/java/com/stream_pi/server/window/dashboard/actiondetailpane/CombineActionPropertiesPane.java
@@ -1,8 +1,8 @@
package com.stream_pi.server.window.dashboard.actiondetailpane;
-import com.stream_pi.actionapi.action.Action;
-import com.stream_pi.actionapi.actionproperty.property.Property;
-import com.stream_pi.actionapi.otheractions.CombineAction;
+import com.stream_pi.action_api.action.Action;
+import com.stream_pi.action_api.actionproperty.property.Property;
+import com.stream_pi.action_api.otheractions.CombineAction;
import com.stream_pi.server.client.ClientProfile;
import com.stream_pi.util.exception.MinorException;
import javafx.event.ActionEvent;
@@ -52,7 +52,6 @@ public class CombineActionPropertiesPane
Action action = clientProfile.getActionByID(actionID);
System.out.println("232323xxxxxxxxxxxx : "+action.getID());
-
Button settingsButton = new Button();
FontIcon settingsFontIcon = new FontIcon("fas-cog");
@@ -93,7 +92,7 @@ public class CombineActionPropertiesPane
public void onSettingsButtonClicked(Action action)
{
- actionDetailsPane.clear();
+ actionDetailsPane.clear(false);
actionDetailsPane.setAction(action);
try {
actionDetailsPane.renderActionProperties();
@@ -117,7 +116,7 @@ public class CombineActionPropertiesPane
combineAction.addChild(current.getRawValue(), currentIndex-1);
combineAction.addChild(aboveOne.getRawValue(), currentIndex);
- actionDetailsPane.saveAction();
+ actionDetailsPane.saveAction(true, true);
renderProps();
}
}
@@ -143,7 +142,7 @@ public class CombineActionPropertiesPane
combineAction.addChild(current.getRawValue(), currentIndex+1);
combineAction.addChild(belowOne.getRawValue(), currentIndex);
- actionDetailsPane.saveAction();
+ actionDetailsPane.saveAction(true, true);
renderProps();
}
}
--- 'a/src/main/java/com/stream_pi/server/window/dashboard/actiondetailpane/OnDeleteActionTask.java'
+++ b/src/main/java/com/stream_pi/server/window/dashboard/actiondetailpane/OnDeleteActionTask.java
@@ -2,7 +2,8 @@ package com.stream_pi.server.window.dash
import java.util.logging.Logger;
-import com.stream_pi.actionapi.action.Action;
+import com.stream_pi.action_api.action.Action;
+import com.stream_pi.action_api.externalplugin.ExternalPlugin;
import com.stream_pi.server.client.ClientProfile;
import com.stream_pi.server.connection.ClientConnection;
import com.stream_pi.server.window.ExceptionAndAlertHandler;
@@ -53,6 +54,43 @@ public class OnDeleteActionTask extends
{
try {
+ if(action instanceof ExternalPlugin)
+ {
+ try
+ {
+ ((ExternalPlugin) action).onActionDeleted();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+
+ exceptionAndAlertHandler.handleMinorException(
+ new MinorException(
+ "Unable to run onActionDeleted for "+action.getModuleName(),
+ "Detailed message : "+e.getMessage()
+ )
+ );
+ }
+ }
+
+ Action a = clientProfile.getActionByID(action.getID());
+ if(a instanceof ExternalPlugin)
+ {
+ try
+ {
+ ((ExternalPlugin) a).onActionDeleted();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ exceptionAndAlertHandler.handleMinorException(
+ new MinorException("failed at onActionDeleted for "+a.getModuleName(),
+ "Detailed Message : "+e.getMessage())
+ );
+ }
+ }
+
+
connection.deleteAction(clientProfile.getID(), action.getID());
clientProfile.removeActionByID(action.getID());
@@ -67,10 +105,11 @@ public class OnDeleteActionTask extends
try {
-
- actionDetailsPane.saveAction(combineActionPropertiesPane.getCombineAction(), false);
-
- System.out.println(combineActionPropertiesPane.getCombineAction().getDisplayText()+"@#@#@#@#@#@#");
+
+ System.out.println(combineActionPropertiesPane.getCombineAction().getDisplayText());
+
+ connection.saveActionDetails(clientProfile.getID(), combineActionPropertiesPane.getCombineAction());
+
actionDetailsPane.onActionClicked(
combineActionPropertiesPane.getCombineAction(),
actionBox
--- 'a/src/main/java/com/stream_pi/server/window/dashboard/actiondetailpane/OnSaveActionTask.java'
+++ b/src/main/java/com/stream_pi/server/window/dashboard/actiondetailpane/OnSaveActionTask.java
@@ -4,18 +4,20 @@ import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
-import com.stream_pi.actionapi.action.Action;
-import com.stream_pi.actionapi.action.ActionType;
-import com.stream_pi.actionapi.action.DisplayTextAlignment;
-import com.stream_pi.actionapi.actionproperty.ClientProperties;
-import com.stream_pi.actionapi.actionproperty.property.Property;
-import com.stream_pi.actionapi.actionproperty.property.Type;
+import com.stream_pi.action_api.action.Action;
+import com.stream_pi.action_api.action.ActionType;
+import com.stream_pi.action_api.action.DisplayTextAlignment;
+import com.stream_pi.action_api.actionproperty.ClientProperties;
+import com.stream_pi.action_api.actionproperty.property.Property;
+import com.stream_pi.action_api.actionproperty.property.Type;
+import com.stream_pi.action_api.externalplugin.ExternalPlugin;
import com.stream_pi.server.client.ClientProfile;
import com.stream_pi.server.connection.ClientConnection;
import com.stream_pi.server.uipropertybox.UIPropertyBox;
import com.stream_pi.server.window.ExceptionAndAlertHandler;
import com.stream_pi.server.window.dashboard.actiongridpane.ActionBox;
+import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.SevereException;
import javafx.application.Platform;
import javafx.concurrent.Task;
@@ -27,15 +29,16 @@ public class OnSaveActionTask extends Ta
private Logger logger;
- public OnSaveActionTask(ClientConnection connection, Action action, String displayNameText, boolean isCombineChild,
+ public OnSaveActionTask(ClientConnection connection, Action action, String delayBeforeRunningString, String displayNameText, boolean isCombineChild,
boolean isShowDisplayText, boolean isDefaultDisplayTextColour, String displayTextFontColour, boolean isClearIcon,
- boolean isHideIcon, DisplayTextAlignment displayTextAlignment, boolean isTransparentBackground, String backgroundColour,
+ boolean isHideDefaultIcon, boolean isHideToggleOffIcon, boolean isHideToggleOnIcon, DisplayTextAlignment displayTextAlignment, boolean isTransparentBackground, String backgroundColour,
CombineActionPropertiesPane combineActionPropertiesPane, ClientProfile clientProfile, boolean sendIcon, ActionBox actionBox,
ArrayList<UIPropertyBox> actionClientProperties, ExceptionAndAlertHandler exceptionAndAlertHandler, Button saveButton, Button deleteButton,
- boolean runAsync)
+ boolean runOnActionSavedFromServer, boolean runAsync, ActionDetailsPaneListener actionDetailsPaneListener)
{
this.saveButton = saveButton;
this.deleteButton = deleteButton;
+ this.delayBeforeRunningString = delayBeforeRunningString;
this.connection = connection;
this.action = action;
@@ -45,7 +48,9 @@ public class OnSaveActionTask extends Ta
this.isDefaultDisplayTextColour = isDefaultDisplayTextColour;
this.displayTextFontColour = displayTextFontColour;
this.isClearIcon = isClearIcon;
- this.isHideIcon = isHideIcon;
+ this.isHideDefaultIcon = isHideDefaultIcon;
+ this.isHideToggleOffIcon = isHideToggleOffIcon;
+ this.isHideToggleOnIcon = isHideToggleOnIcon;
this.displayTextAlignment = displayTextAlignment;
this.isTransparentBackground = isTransparentBackground;
this.combineActionPropertiesPane = combineActionPropertiesPane;
@@ -55,7 +60,8 @@ public class OnSaveActionTask extends Ta
this.exceptionAndAlertHandler = exceptionAndAlertHandler;
this.backgroundColour = backgroundColour;
this.actionClientProperties = actionClientProperties;
-
+ this.runOnActionSavedFromServer = runOnActionSavedFromServer;
+ this.actionDetailsPaneListener = actionDetailsPaneListener;
logger = Logger.getLogger(getClass().getName());
@@ -66,8 +72,13 @@ public class OnSaveActionTask extends Ta
runTask();
}
+ private boolean runOnActionSavedFromServer;
+
+ private ActionDetailsPaneListener actionDetailsPaneListener;
+
private Button saveButton;
private Button deleteButton;
+ private String delayBeforeRunningString;
private boolean isShowDisplayText;
private boolean isCombineChild;
private String displayNameText;
@@ -75,7 +86,9 @@ public class OnSaveActionTask extends Ta
private ArrayList<UIPropertyBox> actionClientProperties;
private String displayTextFontColour;
private boolean isClearIcon;
- private boolean isHideIcon;
+ private boolean isHideDefaultIcon;
+ private boolean isHideToggleOffIcon;
+ private boolean isHideToggleOnIcon;
private DisplayTextAlignment displayTextAlignment;
private boolean isTransparentBackground;
private String backgroundColour;
@@ -118,24 +131,35 @@ public class OnSaveActionTask extends Ta
if(isClearIcon)
{
- action.setIcon(null);
- action.setHasIcon(false);
- action.setShowIcon(false);
+ action.setIcons(null);
+ action.setCurrentIconState("");
}
- if(action.isHasIcon())
- action.setShowIcon(isHideIcon);
+ if(action.getActionType() == ActionType.NORMAL)
+ {
+ if(isHideDefaultIcon)
+ {
+ if(action.getIcon("default") != null)
+ action.setCurrentIconState("default");
+ }
+ else
+ {
+ action.setCurrentIconState("");
+ }
+ }
+ else if (action.getActionType() == ActionType.TOGGLE)
+ {
+ action.setCurrentIconState(isHideToggleOffIcon+"__"+isHideToggleOnIcon);
+ }
action.setDisplayTextAlignment(displayTextAlignment);
- logger.info("BBBGGG : "+backgroundColour);
if(isTransparentBackground)
action.setBgColourHex("");
else
{
- //String bgColour = "#" + actionBackgroundColourPicker.getValue().toString().substring(2);
action.setBgColourHex(backgroundColour);
}
}
@@ -162,6 +186,9 @@ public class OnSaveActionTask extends Ta
}
else
{
+ if(action.getActionType() != ActionType.FOLDER)
+ action.setDelayBeforeExecuting(Integer.parseInt(delayBeforeRunningString));
+
//properties
for (UIPropertyBox clientProperty : actionClientProperties) {
action.getClientProperties().get().get(clientProperty.getIndex()).setRawValue(clientProperty.getRawValue());
@@ -173,27 +200,28 @@ public class OnSaveActionTask extends Ta
{
logger.info("Saving action ... "+action.isHasIcon()+"+"+sendIcon);
- /*if(action.isHasIcon())
+ if(runOnActionSavedFromServer)
{
- if(clientProfile.getActionByID(action.getID()).getIconAsByteArray() == null)
+ try
{
- sendIcon = true;
+ if(action instanceof ExternalPlugin)
+ {
+ System.out.println(action.getSocketAddressForClient());
+ ((ExternalPlugin) action).onActionSavedFromServer();
+ }
}
- else
+ catch (Exception e)
{
- if(!Arrays.equals(action.getIconAsByteArray(), clientProfile.getActionByID(action.getID()).getIconAsByteArray()))
- {
- logger.info("Sending ...");
- sendIcon = true;
- }
- }
- }*/
+ e.printStackTrace();
+ exceptionAndAlertHandler.handleMinorException(new MinorException("Error","onActionSavedFromServer() failed for "+action.getModuleName()+"\n\n"+e.getMessage()));
+ }
+ }
connection.saveActionDetails(clientProfile.getID(), action);
if(sendIcon)
- {
- connection.sendIcon(clientProfile.getID(), action.getID(), action.getIconAsByteArray());
+ {
+ sendAllIcons(clientProfile, action);
}
if(!isCombineChild)
@@ -201,7 +229,7 @@ public class OnSaveActionTask extends Ta
Platform.runLater(()->{
actionBox.clear();
actionBox.setAction(action);
- actionBox.baseInit();
+ //actionBox.baseInit();
actionBox.init();
});
@@ -211,19 +239,31 @@ public class OnSaveActionTask extends Ta
clientProfile.removeActionByID(action.getID());
clientProfile.addAction(action);
+ Platform.runLater(actionDetailsPaneListener::refresh);
+
+
}
catch (SevereException e)
{
e.printStackTrace();
exceptionAndAlertHandler.handleSevereException(e);
}
- catch (CloneNotSupportedException e)
+ catch (Exception e)
{
e.printStackTrace();
}
}
+ private void sendAllIcons(ClientProfile clientProfile, Action action) throws SevereException
+ {
+ for(String state : action.getIcons().keySet())
+ {
+ System.out.println("Sending icon " +state+" -> "+action.getID()+ "-> "+clientProfile.getID());
+ connection.sendIcon(clientProfile.getID(), action.getID(), state, action.getIcon(state));
+ }
+ }
+
@Override
protected Void call() throws Exception
{
--- 'a/src/main/java/com/stream_pi/server/window/dashboard/actiongridpane/ActionBox.java'
+++ b/src/main/java/com/stream_pi/server/window/dashboard/actiongridpane/ActionBox.java
@@ -1,16 +1,22 @@
package com.stream_pi.server.window.dashboard.actiongridpane;
-import com.stream_pi.actionapi.action.Action;
-import com.stream_pi.actionapi.action.ActionType;
-import com.stream_pi.actionapi.action.DisplayTextAlignment;
-import com.stream_pi.actionapi.action.Location;
+import com.stream_pi.action_api.action.Action;
+import com.stream_pi.action_api.action.ActionType;
+import com.stream_pi.action_api.action.DisplayTextAlignment;
+import com.stream_pi.action_api.action.Location;
+import com.stream_pi.action_api.actionproperty.ClientProperties;
+import com.stream_pi.action_api.externalplugin.ExternalPlugin;
+import com.stream_pi.server.controller.ActionDataFormats;
import com.stream_pi.server.window.ExceptionAndAlertHandler;
import com.stream_pi.server.window.dashboard.actiondetailpane.ActionDetailsPaneListener;
import com.stream_pi.util.exception.MinorException;
import javafx.application.Platform;
+import javafx.concurrent.Task;
import javafx.geometry.Pos;
import javafx.scene.CacheHint;
+import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
+import javafx.scene.control.MenuItem;
import javafx.scene.image.Image;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
@@ -23,10 +29,12 @@ import javafx.scene.layout.BackgroundRep
import javafx.scene.layout.BackgroundSize;
import javafx.scene.layout.StackPane;
import javafx.scene.text.TextAlignment;
+import org.kordamp.ikonli.javafx.FontIcon;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.nio.ByteBuffer;
+import java.util.HashMap;
public class ActionBox extends StackPane{
@@ -55,11 +63,13 @@ public class ActionBox extends StackPane
public void clear()
{
+ setStyle(null);
setAction(null);
- setInvalid(false);
+ getStyleClass().clear();
setBackground(Background.EMPTY);
- setStyle(null);
+ removeFontIcon();
getChildren().clear();
+ baseInit();
}
public void baseInit()
@@ -68,7 +78,6 @@ public class ActionBox extends StackPane
displayTextLabel.setWrapText(true);
displayTextLabel.setTextAlignment(TextAlignment.CENTER);
displayTextLabel.getStyleClass().add("action_box_display_text_label");
-
displayTextLabel.prefHeightProperty().bind(heightProperty());
displayTextLabel.prefWidthProperty().bind(widthProperty());
@@ -79,13 +88,13 @@ public class ActionBox extends StackPane
setMaxSize(size, size);
getStyleClass().add("action_box");
- getStyleClass().add("action_box_icon_not_present");
+ setIcon(null);
getStyleClass().add("action_box_valid");
setOnDragOver(dragEvent ->
{
- if(dragEvent.getDragboard().hasContent(Action.getDataFormat()))
+ if(dragEvent.getDragboard().hasContent(ActionDataFormats.ACTION_TYPE))
{
dragEvent.acceptTransferModes(TransferMode.ANY);
@@ -99,28 +108,104 @@ public class ActionBox extends StackPane
{
if(action == null)
{
- Action action = (Action) dragEvent.getDragboard().getContent(Action.getDataFormat());
+ Dragboard db = dragEvent.getDragboard();
- action.setLocation(new Location(getRow(),
- getCol()));
+ ActionType actionType = (ActionType) db.getContent(ActionDataFormats.ACTION_TYPE);
- action.setParent(getStreamPiParent());
+ if(actionType == ActionType.NORMAL || actionType == ActionType.TOGGLE)
+ {
+ String moduleName = (String) dragEvent.getDragboard().getContent(ActionDataFormats.MODULE_NAME);
- action.setIDRandom();
+ ExternalPlugin newAction = actionGridPaneListener.createNewActionFromExternalPlugin(moduleName);
- actionGridPaneListener.addActionToCurrentClientProfile(action);
+ boolean isNew = (boolean) db.getContent(ActionDataFormats.IS_NEW);
- setAction(action);
- init();
+ if(isNew)
+ {
+ newAction.setDisplayText("Untitled Action");
+ newAction.setShowDisplayText(true);
+ newAction.getClientProperties().resetToDefaults();
+ newAction.setDisplayTextAlignment(DisplayTextAlignment.CENTER);
+ if(actionType == ActionType.TOGGLE)
+ newAction.setCurrentIconState("false__false");
+ }
+ else
+ {
+ newAction.setClientProperties((ClientProperties) db.getContent(ActionDataFormats.CLIENT_PROPERTIES));
+ newAction.setIcons((HashMap<String, byte[]>) db.getContent(ActionDataFormats.ICONS));
+ newAction.setCurrentIconState((String) db.getContent(ActionDataFormats.CURRENT_ICON_STATE));
+ newAction.setBgColourHex((String) db.getContent(ActionDataFormats.BACKGROUND_COLOUR));
+ newAction.setDisplayTextFontColourHex((String) db.getContent(ActionDataFormats.DISPLAY_TEXT_FONT_COLOUR));
+ newAction.setDisplayText((String) db.getContent(ActionDataFormats.DISPLAY_TEXT));
+ newAction.setDisplayTextAlignment((DisplayTextAlignment) db.getContent(ActionDataFormats.DISPLAY_TEXT_ALIGNMENT));
+ newAction.setShowDisplayText((boolean) db.getContent(ActionDataFormats.DISPLAY_TEXT_SHOW));
+ }
- actionDetailsPaneListener.onActionClicked(action, this);
-
- if(action.isHasIcon())
- actionDetailsPaneListener.setSendIcon(true);
- actionDetailsPaneListener.saveAction();
+
+ newAction.setLocation(new Location(getRow(),
+ getCol()));
+
+
+ System.out.println("@@#$#$#$ :"+newAction.getProfileID());
+ newAction.setParent(actionGridPaneListener.getCurrentParent());
+ newAction.setSocketAddressForClient(actionGridPaneListener.getClientConnection().getRemoteSocketAddress());
+
+ try
+ {
+ newAction.onActionCreate();
+ }
+ catch (Exception e)
+ {
+ exceptionAndAlertHandler.handleMinorException(new MinorException("Error","onCreate() failed for "+action.getModuleName()+"\n\n"+e.getMessage()));
+ }
+
+
+
+ newAction.setProfileID(actionGridPaneListener.getCurrentProfile().getID());
+ newAction.setSocketAddressForClient(actionGridPaneListener.getClientConnection().getRemoteSocketAddress());
+
+ actionGridPaneListener.addActionToCurrentClientProfile(newAction);
+
+ setAction(newAction);
+ init();
+
+ actionDetailsPaneListener.onActionClicked(newAction, this);
+
+ if(newAction.isHasIcon())
+ actionDetailsPaneListener.setSendIcon(true);
+
+
+ actionDetailsPaneListener.saveAction(true, false);
+
+ }
+ else
+ {
+ Action newAction = actionGridPaneListener.createNewOtherAction(actionType);
+
+ newAction.setLocation(new Location(getRow(),
+ getCol()));
+
+ newAction.setParent(actionGridPaneListener.getCurrentParent());
+
+ newAction.setProfileID(actionGridPaneListener.getCurrentProfile().getID());
+ newAction.setSocketAddressForClient(actionGridPaneListener.getClientConnection().getRemoteSocketAddress());
+
+ actionGridPaneListener.addActionToCurrentClientProfile(newAction);
+
+ setAction(newAction);
+ init();
+
+
+ actionDetailsPaneListener.onActionClicked(newAction, this);
+
+ if(newAction.isHasIcon())
+ actionDetailsPaneListener.setSendIcon(true);
+
+ actionDetailsPaneListener.saveAction(true, false);
+ }
}
}
catch (MinorException e)
@@ -128,63 +213,92 @@ public class ActionBox extends StackPane
exceptionAndAlertHandler.handleMinorException(e);
e.printStackTrace();
}
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
});
setOnDragDetected(mouseEvent -> {
- try {
- if(action!=null)
+ if(getAction()!=null)
+ {
+ if(getAction().getActionType() == ActionType.NORMAL)
{
- if(action.getActionType() == ActionType.NORMAL)
- {
- Dragboard db = startDragAndDrop(TransferMode.ANY);
-
- ClipboardContent content = new ClipboardContent();
-
- Action newAction = (Action) action.clone();
+ Dragboard db = startDragAndDrop(TransferMode.ANY);
- newAction.setIDRandom();
- newAction.setParent(getStreamPiParent());
+ ClipboardContent content = new ClipboardContent();
- content.put(Action.getDataFormat(), newAction);
+ content.put(ActionDataFormats.CLIENT_PROPERTIES, getAction().getClientProperties());
+ content.put(ActionDataFormats.ICONS, getAction().getIcons());
+ content.put(ActionDataFormats.CURRENT_ICON_STATE, getAction().getCurrentIconState());
+ content.put(ActionDataFormats.BACKGROUND_COLOUR, getAction().getBgColourHex());
+ content.put(ActionDataFormats.DISPLAY_TEXT_FONT_COLOUR, getAction().getDisplayTextFontColourHex());
+ content.put(ActionDataFormats.DISPLAY_TEXT, getAction().getDisplayText());
+ content.put(ActionDataFormats.DISPLAY_TEXT_ALIGNMENT, getAction().getDisplayTextAlignment());
+ content.put(ActionDataFormats.DISPLAY_TEXT_SHOW, getAction().isShowDisplayText());
+
+ content.put(ActionDataFormats.IS_NEW, false);
+ content.put(ActionDataFormats.ACTION_TYPE, getAction().getActionType());
+ content.put(ActionDataFormats.MODULE_NAME, getAction().getModuleName());
- db.setContent(content);
+ db.setContent(content);
- mouseEvent.consume();
- }
+ mouseEvent.consume();
}
}
- catch (CloneNotSupportedException e)
- {
- e.printStackTrace();
- }
});
setOnMouseClicked(mouseEvent -> {
- if(action != null && mouseEvent.getButton().equals(MouseButton.PRIMARY))
+ if(action != null)
{
- if(mouseEvent.getClickCount() == 2 && action.getActionType() == ActionType.FOLDER)
+ if(mouseEvent.getButton().equals(MouseButton.PRIMARY))
{
- getActionDetailsPaneListener().onOpenFolderButtonClicked();
- }
- else
- {
- try
+ if(mouseEvent.getClickCount() == 2 && getAction().getActionType() == ActionType.FOLDER)
{
- actionDetailsPaneListener.onActionClicked(action, this);
+ getActionDetailsPaneListener().onOpenFolderButtonClicked();
}
- catch (MinorException e)
+ else
{
- exceptionAndAlertHandler.handleMinorException(e);
- e.printStackTrace();
+ try
+ {
+ actionDetailsPaneListener.onActionClicked(action, this);
+ }
+ catch (MinorException e)
+ {
+ exceptionAndAlertHandler.handleMinorException(e);
+ e.printStackTrace();
+ }
+ }
+ }
+ else if(mouseEvent.getButton().equals(MouseButton.SECONDARY))
+ {
+ if(getAction().getActionType() == ActionType.TOGGLE)
+ {
+ toggleStateContextMenu.show(this, mouseEvent.getScreenX(),
+ mouseEvent.getScreenY());
}
}
}
+
});
+ toggleStateContextMenu = new ContextMenu();
+
+ MenuItem showToggleOffMenuItem = new MenuItem("Show Toggle OFF");
+ showToggleOffMenuItem.setOnAction(event-> fakeToggle(false));
+
+ MenuItem showToggleOnMenuItem = new MenuItem("Show Toggle ON");
+ showToggleOnMenuItem.setOnAction(event-> fakeToggle(true));
+
+ toggleStateContextMenu.getItems().addAll(showToggleOffMenuItem, showToggleOnMenuItem);
+
+
setCache(true);
- setCacheHint(CacheHint.SPEED);
+ setCacheHint(CacheHint.QUALITY);
}
+ ContextMenu toggleStateContextMenu;
+
public void setInvalid(boolean invalid)
{
if(invalid)
@@ -211,11 +325,15 @@ public class ActionBox extends StackPane
private int size;
private ActionGridPaneListener actionGridPaneListener;
- public ActionBox(int size, ActionDetailsPaneListener actionDetailsPaneListener, ActionGridPaneListener actionGridPaneListener)
+ public ActionBox(int size, ActionDetailsPaneListener actionDetailsPaneListener, ActionGridPaneListener actionGridPaneListener,
+ int col, int row)
{
this.actionGridPaneListener = actionGridPaneListener;
this.actionDetailsPaneListener = actionDetailsPaneListener;
this.size = size;
+
+ this.col = col;
+ this.row = row;
baseInit();
}
@@ -233,45 +351,73 @@ public class ActionBox extends StackPane
public void setIcon(byte[] iconByteArray)
{
+ removeFontIcon();
+
if(iconByteArray == null)
{
getStyleClass().remove("action_box_icon_present");
getStyleClass().add("action_box_icon_not_present");
setBackground(null);
- return;
}
else
{
getStyleClass().add("action_box_icon_present");
getStyleClass().remove("action_box_icon_not_present");
-
setBackground(
- new Background(
- new BackgroundImage(new Image(
- new ByteArrayInputStream(iconByteArray), size, size, false, true
- ), BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER,
-
- new BackgroundSize(100, 100, true, true, true, false))
- )
+ new Background(
+ new BackgroundImage(new Image(
+ new ByteArrayInputStream(iconByteArray), size, size, false, true
+ ), BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER,
+
+ new BackgroundSize(100, 100, true, true, true, false))
+ )
);
}
}
- private Action action;
- private ExceptionAndAlertHandler exceptionAndAlertHandler;
+ public void setDefaultToggleIcon(boolean isToggleOn)
+ {
- private String parent;
+ String styleClass;
- public String getStreamPiParent() {
- return parent;
+ if(isToggleOn)
+ {
+ styleClass = "action_box_toggle_on";
+ }
+ else
+ {
+ styleClass = "action_box_toggle_off";
+ }
+
+ setBackground(null);
+ removeFontIcon();
+
+ fontIcon = new FontIcon();
+ fontIcon.getStyleClass().add(styleClass);
+ fontIcon.setIconSize((int) (size * 0.8));
+
+ getChildren().add(fontIcon);
+ fontIcon.toBack();
}
- public void setStreamPiParent(String parent) {
- this.parent = parent;
+ public void removeFontIcon()
+ {
+ if(fontIcon!=null)
+ {
+ getChildren().remove(fontIcon);
+ fontIcon = null;
+ }
}
- public ActionBox(int size, Action action, ActionDetailsPaneListener actionDetailsPaneListener, ExceptionAndAlertHandler exceptionAndAlertHandler, ActionGridPaneListener actionGridPaneListener)
+ FontIcon fontIcon = null;
+
+ private Action action = null;
+ private ExceptionAndAlertHandler exceptionAndAlertHandler;
+
+
+ public ActionBox(int size, Action action, ActionDetailsPaneListener actionDetailsPaneListener, ExceptionAndAlertHandler exceptionAndAlertHandler, ActionGridPaneListener actionGridPaneListener,
+ int col, int row)
{
this.actionGridPaneListener = actionGridPaneListener;
this.exceptionAndAlertHandler = exceptionAndAlertHandler;
@@ -279,6 +425,8 @@ public class ActionBox extends StackPane
this.actionDetailsPaneListener = actionDetailsPaneListener;
this.size = size;
+ this.col = col;
+ this.row = row;
baseInit();
@@ -287,6 +435,10 @@ public class ActionBox extends StackPane
}
+ public Action getAction() {
+ return action;
+ }
+
public void setAction(Action action)
{
this.action = action;
@@ -294,8 +446,13 @@ public class ActionBox extends StackPane
public void init()
{
- if(action.isShowDisplayText())
- setDisplayTextLabel(action.getDisplayText());
+ init(false);
+ }
+
+ public void init(boolean start)
+ {
+ if(getAction().isShowDisplayText())
+ setDisplayTextLabel(getAction().getDisplayText());
else
setDisplayTextLabel("");
@@ -306,15 +463,95 @@ public class ActionBox extends StackPane
setInvalid(action.isInvalid());
Platform.runLater(()->{
- if(action.isHasIcon() && action.isShowIcon())
+ try {
+ if(action.getActionType() == ActionType.TOGGLE)
+ {
+ fakeToggle(start);
+ }
+ else
+ {
+ if(action.isHasIcon())
+ {
+ if(!action.getCurrentIconState().isBlank())
+ {
+ setIcon(action.getCurrentIcon());
+ }
+ }
+ else
+ {
+ setIcon(null);
+ }
+ }
+ }
+ catch (Exception e)
{
- setIcon(action.getIconAsByteArray());
+ e.printStackTrace();
+ }
+ });
+ }
+
+ public void fakeToggle(boolean isON)
+ {
+ System.out.println("CURRENT ICONS : "+action.getCurrentIconState());
+ String[] toggleStatesHiddenStatus = action.getCurrentIconState().split("__");
+
+ boolean isToggleOffHidden = toggleStatesHiddenStatus[0].equals("true");
+ boolean isToggleOnHidden = toggleStatesHiddenStatus[1].equals("true");
+
+ if(isON) // ON
+ {
+ if(action.isHasIcon())
+ {
+ boolean isToggleOnPresent = action.getIcons().containsKey("toggle_on");
+
+ if(isToggleOnPresent)
+ {
+ if(isToggleOnHidden)
+ {
+ setDefaultToggleIcon(true);
+ }
+ else
+ {
+ setIcon(action.getIcons().get("toggle_on"));
+ }
+ }
+ else
+ {
+ setDefaultToggleIcon(true);
+ }
}
else
{
- setIcon(null);
+ setDefaultToggleIcon(true);
}
- });
+ }
+ else // OFF
+ {
+ if(action.isHasIcon())
+ {
+ boolean isToggleOffPresent = action.getIcons().containsKey("toggle_off");
+
+ if(isToggleOffPresent)
+ {
+ if(isToggleOffHidden)
+ {
+ setDefaultToggleIcon(false);
+ }
+ else
+ {
+ setIcon(action.getIcons().get("toggle_off"));
+ }
+ }
+ else
+ {
+ setDefaultToggleIcon(false);
+ }
+ }
+ else
+ {
+ setDefaultToggleIcon(false);
+ }
+ }
}
public void setDisplayTextLabel(String text)
@@ -342,7 +579,7 @@ public class ActionBox extends StackPane
public void setBackgroundColour(String colour)
{
System.out.println("COLOr : "+colour);
- if(!colour.isEmpty() && action.getIconAsByteArray() == null)
+ if(!colour.isEmpty())
setStyle("-fx-background-color : "+colour);
}
}
--- 'a/src/main/java/com/stream_pi/server/window/dashboard/actiongridpane/ActionGridPane.java'
+++ b/src/main/java/com/stream_pi/server/window/dashboard/actiongridpane/ActionGridPane.java
@@ -1,10 +1,18 @@
package com.stream_pi.server.window.dashboard.actiongridpane;
-import com.stream_pi.actionapi.action.Action;
-import com.stream_pi.actionapi.action.Location;
-import com.stream_pi.actionapi.otheractions.FolderAction;
+import com.stream_pi.action_api.action.Action;
+import com.stream_pi.action_api.action.ActionType;
+import com.stream_pi.action_api.action.DisplayTextAlignment;
+import com.stream_pi.action_api.action.Location;
+import com.stream_pi.action_api.actionproperty.property.Property;
+import com.stream_pi.action_api.actionproperty.property.Type;
+import com.stream_pi.action_api.externalplugin.ExternalPlugin;
+import com.stream_pi.action_api.otheractions.CombineAction;
+import com.stream_pi.action_api.otheractions.FolderAction;
+import com.stream_pi.server.action.ExternalPlugins;
import com.stream_pi.server.client.Client;
import com.stream_pi.server.client.ClientProfile;
+import com.stream_pi.server.connection.ClientConnection;
import com.stream_pi.server.io.Config;
import com.stream_pi.server.window.ExceptionAndAlertHandler;
import com.stream_pi.server.window.dashboard.actiondetailpane.ActionDetailsPaneListener;
@@ -12,11 +20,13 @@ import com.stream_pi.util.exception.Mino
import com.stream_pi.util.exception.SevereException;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
+import javafx.scene.CacheHint;
import javafx.scene.Node;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.*;
import org.kordamp.ikonli.javafx.FontIcon;
+import java.util.HashMap;
import java.util.logging.Logger;
public class ActionGridPane extends ScrollPane implements ActionGridPaneListener {
@@ -27,11 +37,12 @@ public class ActionGridPane extends Scro
public ActionGridPane(ExceptionAndAlertHandler exceptionAndAlertHandler)
{
logger = Logger.getLogger(ActionGridPane.class.getName());
+
+ actionBoxHashMap = new HashMap<>();
+
this.exceptionAndAlertHandler = exceptionAndAlertHandler;
getStyleClass().add("action_grid_pane_parent");
- VBox.setVgrow(this, Priority.ALWAYS);
-
actionsGridPane = new GridPane();
actionsGridPane.setPadding(new Insets(5.0));
actionsGridPane.getStyleClass().add("action_grid_pane");
@@ -39,30 +50,115 @@ public class ActionGridPane extends Scro
actionsGridPane.setPrefSize(USE_COMPUTED_SIZE, USE_COMPUTED_SIZE);
setContent(actionsGridPane);
+
+ setCache(true);
+ setCacheHint(CacheHint.SPEED);
+ }
+
+ private HashMap<String, ActionBox> actionBoxHashMap;
+
+ public ActionBox getActionBoxByIDAndProfileID(String actionID, String profileID)
+ {
+ // Returns null when there is no such action available
+
+ if(getClientProfile() == null)
+ {
+ return null;
+ }
+
+ if(!getClientProfile().getID().equals(profileID))
+ {
+ return null;
+ }
+
+ return actionBoxHashMap.getOrDefault(actionID, null);
}
public void setActionDetailsPaneListener(ActionDetailsPaneListener actionDetailsPaneListener) {
this.actionDetailsPaneListener = actionDetailsPaneListener;
}
- private String currentParent;
+ private String currentParent = null;
+
+ @Override
+ public ExternalPlugin createNewActionFromExternalPlugin(String moduleName) throws Exception
+ {
+ ExternalPlugin newAction = ExternalPlugins.getInstance().getPluginByModuleName(moduleName).clone();
+
+ if(newAction.getActionType() == ActionType.TOGGLE)
+ {
+ newAction.setCurrentIconState("false__false");
+ }
+
+ newAction.setIDRandom();
+
+ newAction.setShowDisplayText(true);
+ newAction.setDisplayText("Untitled Action");
+ newAction.setDisplayTextAlignment(DisplayTextAlignment.CENTER);
+
+ newAction.setBgColourHex("");
+ newAction.setDisplayTextFontColourHex("");
+
+ return newAction;
+ }
+
+ @Override
+ public Action createNewOtherAction(ActionType actionType) throws Exception
+ {
+ Action newAction;
+
+ String displayText;
+ if(actionType == ActionType.FOLDER)
+ {
+ displayText = "Untitled Folder";
+ newAction = new FolderAction();
+ }
+ else if(actionType == ActionType.COMBINE)
+ {
+ displayText = "Untitled Combine";
+ newAction = new CombineAction();
+ }
+ else
+ throw new IllegalArgumentException("External Plugins are not supported here!");
+
+ newAction.setIDRandom();
+
+
+ newAction.setShowDisplayText(true);
+ newAction.setDisplayText(displayText);
+ newAction.setDisplayTextAlignment(DisplayTextAlignment.CENTER);
+
+ newAction.setBgColourHex("");
+ newAction.setDisplayTextFontColourHex("");
+
+ return newAction;
+ }
+
+ @Override
public void setCurrentParent(String currentParent) {
this.currentParent = currentParent;
}
+ @Override
+ public ClientConnection getClientConnection() {
+ return clientConnection;
+ }
+
public ClientProfile getClientProfile() {
return clientProfile;
}
- private Client client;
+ private ClientConnection clientConnection;
+
- public void setClient(Client client) {
- this.client = client;
+ public void setClientConnection(ClientConnection clientConnection)
+ {
+ this.clientConnection = clientConnection;
}
public Client getClient() {
- return client;
+ return getClientConnection().getClient();
}
private int rows, cols;
@@ -81,10 +177,16 @@ public class ActionGridPane extends Scro
}
+ @Override
public String getCurrentParent() {
return currentParent;
}
+ @Override
+ public ClientProfile getCurrentProfile() {
+ return clientProfile;
+ }
+
public StackPane getFolderBackButton() throws SevereException
{
StackPane stackPane = new StackPane();
@@ -98,7 +200,7 @@ public class ActionGridPane extends Scro
FontIcon fontIcon = new FontIcon("fas-chevron-left");
fontIcon.getStyleClass().add("folder_action_back_button_icon");
- fontIcon.setIconSize(Config.getInstance().getActionGridActionSize() - 30);
+ fontIcon.setIconSize((int) (Config.getInstance().getActionGridActionSize() * 0.8));
stackPane.setAlignment(Pos.CENTER);
stackPane.getChildren().add(fontIcon);
@@ -108,19 +210,49 @@ public class ActionGridPane extends Scro
return stackPane;
}
- public void renderGrid() throws SevereException {
- clear();
+ private ActionBox[][] actionBoxes;
+ private boolean isFreshRender = true;
+ private Node folderBackButton = null;
+ public void renderGrid() throws SevereException
+ {
actionsGridPane.setHgap(Config.getInstance().getActionGridActionGap());
actionsGridPane.setVgap(Config.getInstance().getActionGridActionGap());
+ if(isFreshRender)
+ {
+ clear();
+ actionBoxes = new ActionBox[cols][rows];
+ }
+
boolean isFolder = false;
- if(!getCurrentParent().equals("root"))
+ if(getCurrentParent().equals("root"))
+ {
+ if(folderBackButton != null)
+ {
+ actionsGridPane.getChildren().remove(folderBackButton);
+ folderBackButton = null;
+
+ actionBoxes[0][0] = addBlankActionBox(0,0);
+ }
+ }
+ else
{
isFolder = true;
- actionsGridPane.add(getFolderBackButton(), 0,0);
+ if(folderBackButton != null)
+ {
+ actionsGridPane.getChildren().remove(folderBackButton);
+ folderBackButton = null;
+ }
+ else
+ {
+ actionsGridPane.getChildren().remove(actionBoxes[0][0]);
+ }
+
+ folderBackButton = getFolderBackButton();
+ actionsGridPane.add(folderBackButton, 0,0);
}
for(int row = 0; row<rows; row++)
@@ -130,16 +262,34 @@ public class ActionGridPane extends Scro
if(row == 0 && col == 0 && isFolder)
continue;
- ActionBox actionBox = new ActionBox(Config.getInstance().getActionGridActionSize(), actionDetailsPaneListener, this);
+ if(isFreshRender)
+ {
+ actionBoxes[col][row] = addBlankActionBox(col, row);
+ }
+ else
+ {
+ if(actionBoxes[col][row].getAction() != null)
+ {
+ actionBoxes[col][row].clear();
+ }
+ }
+ }
+ }
+
+ isFreshRender = false;
+ }
- actionBox.setStreamPiParent(currentParent);
- actionBox.setRow(row);
- actionBox.setCol(col);
+ public void setFreshRender(boolean freshRender)
+ {
+ isFreshRender = freshRender;
+ }
- actionsGridPane.add(actionBox, row, col);
+ public ActionBox addBlankActionBox(int col, int row) throws SevereException {
+ ActionBox actionBox = new ActionBox(Config.getInstance().getActionGridActionSize(), actionDetailsPaneListener, this,
+ col, row);
- }
- }
+ actionsGridPane.add(actionBox, col, row);
+ return actionBox;
}
public void renderActions()
@@ -172,6 +322,7 @@ public class ActionGridPane extends Scro
public void clear()
{
+ actionBoxHashMap.clear();
actionsGridPane.getChildren().clear();
}
@@ -198,7 +349,17 @@ public class ActionGridPane extends Scro
}
- ActionBox actionBox = new ActionBox(Config.getInstance().getActionGridActionSize(), action, actionDetailsPaneListener, exceptionAndAlertHandler, this);
+ Location location = action.getLocation();
+
+ ActionBox actionBox = actionBoxes[location.getCol()][location.getRow()];
+ actionBox.clear();
+ actionBox.setAction(action);
+
+ actionBox.init();
+
+ actionBoxHashMap.put(action.getID(), actionBox);
+
+ /*ActionBox actionBox = new ActionBox(Config.getInstance().getActionGridActionSize(), action, actionDetailsPaneListener, exceptionAndAlertHandler, this);
Location location = action.getLocation();
@@ -217,7 +378,7 @@ public class ActionGridPane extends Scro
}
System.out.println(location.getCol()+","+location.getRow());
- actionsGridPane.add(actionBox, location.getRow(), location.getCol());
+ actionsGridPane.add(actionBox, location.getRow(), location.getCol());*/
}
--- 'a/src/main/java/com/stream_pi/server/window/dashboard/actiongridpane/ActionGridPaneListener.java'
+++ b/src/main/java/com/stream_pi/server/window/dashboard/actiongridpane/ActionGridPaneListener.java
@@ -1,10 +1,28 @@
package com.stream_pi.server.window.dashboard.actiongridpane;
-import com.stream_pi.actionapi.action.Action;
-import com.stream_pi.actionapi.otheractions.FolderAction;
+import com.stream_pi.action_api.action.Action;
+import com.stream_pi.action_api.action.ActionType;
+import com.stream_pi.action_api.externalplugin.ExternalPlugin;
+import com.stream_pi.action_api.otheractions.FolderAction;
+import com.stream_pi.server.client.ClientProfile;
+import com.stream_pi.server.connection.ClientConnection;
-public interface ActionGridPaneListener {
+public interface ActionGridPaneListener
+{
void addActionToCurrentClientProfile(Action newAction);
+ ActionBox getActionBoxByIDAndProfileID(String actionID, String profileID);
+
void renderFolder(FolderAction action);
+
+ String getCurrentParent();
+
+ ClientProfile getCurrentProfile();
+
+ void setCurrentParent(String currentParent);
+
+ ClientConnection getClientConnection();
+
+ ExternalPlugin createNewActionFromExternalPlugin(String module) throws Exception;
+ Action createNewOtherAction(ActionType actionType) throws Exception;
}
--- 'a/src/main/java/com/stream_pi/server/window/firsttimeuse/FinalConfigPane.java'
+++ b/src/main/java/com/stream_pi/server/window/firsttimeuse/FinalConfigPane.java
@@ -6,7 +6,6 @@ import com.stream_pi.server.window.Excep
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.uihelper.HBoxInputBox;
import com.stream_pi.util.uihelper.SpaceFiller;
-import com.stream_pi.util.uihelper.SpaceFiller.FillerType;
import javafx.geometry.Pos;
import javafx.scene.control.Alert;
@@ -23,14 +22,17 @@ public class FinalConfigPane extends VBo
{
private TextField serverNicknameTextField;
private TextField serverPortTextField;
+ private Button nextButton;
private ExceptionAndAlertHandler exceptionAndAlertHandler;
private ServerListener serverListener;
- public FinalConfigPane(ExceptionAndAlertHandler exceptionAndAlertHandler, ServerListener serverListener)
+ public FinalConfigPane(ExceptionAndAlertHandler exceptionAndAlertHandler, ServerListener serverListener,
+ Button nextButton)
{
this.exceptionAndAlertHandler = exceptionAndAlertHandler;
this.serverListener = serverListener;
+ this.nextButton = nextButton;
getStyleClass().add("first_time_use_pane_final_config");
@@ -45,18 +47,19 @@ public class FinalConfigPane extends VBo
HBoxInputBox serverNickNameInputBox = new HBoxInputBox("Server Nickname", serverNicknameTextField, 200);
HBoxInputBox serverPortInputBox = new HBoxInputBox("Server Port", serverPortTextField);
- Button confirmButton = new Button("Confirm");
- confirmButton.setOnAction(event -> onConfirmButtonClicked());
- HBox bBar = new HBox(confirmButton);
- bBar.setAlignment(Pos.CENTER_RIGHT);
-
- getChildren().addAll(label, serverNickNameInputBox, serverPortInputBox, new SpaceFiller(FillerType.VBox), bBar);
+ getChildren().addAll(label, serverNickNameInputBox, serverPortInputBox);
setSpacing(10.0);
setVisible(false);
}
+ public void makeChangesToNextButton()
+ {
+ nextButton.setText("Confirm");
+ nextButton.setOnAction(event -> onConfirmButtonClicked());
+ }
+
private void onConfirmButtonClicked()
{
StringBuilder errors = new StringBuilder();
@@ -74,7 +77,9 @@ public class FinalConfigPane extends VBo
serverPort = Integer.parseInt(serverPortStr);
if (serverPort < 1024)
- errors.append("* Server Port must be more than 1024");
+ errors.append("* Server Port must be more than 1024\n");
+ else if(serverPort > 65535)
+ errors.append("* Server Port must be lesser than 65535\n");
}
catch (NumberFormatException e)
{
@@ -91,6 +96,7 @@ public class FinalConfigPane extends VBo
Config.getInstance().save();
serverListener.othInit();
+ serverListener.initLogger();
((Stage) getScene().getWindow()).close();
}
--- 'a/src/main/java/com/stream_pi/server/window/firsttimeuse/FirstTimeUse.java'
+++ b/src/main/java/com/stream_pi/server/window/firsttimeuse/FirstTimeUse.java
@@ -4,7 +4,6 @@ import com.stream_pi.server.Main;
import com.stream_pi.server.connection.ServerListener;
import com.stream_pi.server.window.ExceptionAndAlertHandler;
import com.stream_pi.util.uihelper.SpaceFiller;
-import com.stream_pi.util.uihelper.SpaceFiller.FillerType;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
@@ -36,17 +35,6 @@ public class FirstTimeUse extends VBox{
VBox.setVgrow(stackPane, Priority.ALWAYS);
- welcomePane = new WelcomePane();
- licensePane = new LicensePane();
- finalConfigPane = new FinalConfigPane(exceptionAndAlertHandler, serverListener);
-
- stackPane.getChildren().addAll(
- welcomePane,
- licensePane,
- finalConfigPane
- );
-
-
nextButton = new Button("Next");
nextButton.setOnAction(event-> onNextButtonClicked());
@@ -54,9 +42,19 @@ public class FirstTimeUse extends VBox{
previousButton.setOnAction(event-> onPreviousButtonClicked());
- HBox buttonBar = new HBox(previousButton, new SpaceFiller(FillerType.HBox), nextButton);
+ HBox buttonBar = new HBox(previousButton, SpaceFiller.horizontal(), nextButton);
buttonBar.setSpacing(10.0);
+ welcomePane = new WelcomePane();
+ licensePane = new LicensePane();
+ finalConfigPane = new FinalConfigPane(exceptionAndAlertHandler, serverListener, nextButton);
+
+ stackPane.getChildren().addAll(
+ welcomePane,
+ licensePane,
+ finalConfigPane
+ );
+
getChildren().addAll(headingLabel, stackPane, buttonBar);
setWindow(WindowName.WELCOME);
@@ -107,8 +105,9 @@ public class FirstTimeUse extends VBox{
headingLabel.setText("");
- nextButton.setDisable(false);
- previousButton.setDisable(true);
+ nextButton.setText("Next");
+ nextButton.setOnAction(event-> onNextButtonClicked());
+ previousButton.setVisible(false);
}
else if (windowName == WindowName.LICENSE)
{
@@ -120,8 +119,9 @@ public class FirstTimeUse extends VBox{
headingLabel.setText("License Agreement");
- nextButton.setDisable(false);
- previousButton.setDisable(false);
+ nextButton.setText("Agree and Continue");
+ nextButton.setOnAction(event-> onNextButtonClicked());
+ previousButton.setVisible(true);
}
else if (windowName == WindowName.FINAL)
{
@@ -133,8 +133,8 @@ public class FirstTimeUse extends VBox{
headingLabel.setText("Finishing up ...");
- nextButton.setDisable(true);
- previousButton.setDisable(false);
+ finalConfigPane.makeChangesToNextButton();
+ previousButton.setVisible(true);
}
}
--- 'a/src/main/java/com/stream_pi/server/window/firsttimeuse/LicensePane.java'
+++ b/src/main/java/com/stream_pi/server/window/firsttimeuse/LicensePane.java
@@ -2,20 +2,18 @@ package com.stream_pi.server.window.firs
import com.stream_pi.server.info.License;
+import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
-public class LicensePane extends VBox {
+public class LicensePane extends VBox
+{
public LicensePane()
{
getStyleClass().add("first_time_use_pane_license");
- Label label = new Label("By clicking on 'Next' you agree with the Stream-Pi license, and, the license('s) of the library('s) used/included with this software.");
- label.prefWidthProperty().bind(widthProperty());
- label.setWrapText(true);
-
TextArea licenseTextArea = new TextArea(License.getLicense());
licenseTextArea.setWrapText(false);
licenseTextArea.setEditable(false);
@@ -23,6 +21,6 @@ public class LicensePane extends VBox {
licenseTextArea.prefWidthProperty().bind(widthProperty());
VBox.setVgrow(licenseTextArea, Priority.ALWAYS);
- getChildren().addAll(label, licenseTextArea);
+ getChildren().addAll(licenseTextArea);
}
}
--- 'a/src/main/java/com/stream_pi/server/window/settings/About.java'
+++ /dev/null
@@ -1,99 +0,0 @@
-package com.stream_pi.server.window.settings;
-
-import com.stream_pi.actionapi.ActionAPI;
-import com.stream_pi.server.info.License;
-import com.stream_pi.server.info.ServerInfo;
-import com.stream_pi.server.Main;
-import javafx.application.HostServices;
-import javafx.geometry.Insets;
-import javafx.geometry.Pos;
-import javafx.scene.control.Hyperlink;
-import javafx.scene.control.Label;
-import javafx.scene.control.TextArea;
-import javafx.scene.image.Image;
-import javafx.scene.image.ImageView;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Priority;
-import javafx.scene.layout.VBox;
-
-public class About extends VBox{
-
- private HostServices hostServices;
-
- public About(HostServices hostServices)
- {
- getStyleClass().add("about");
- this.hostServices = hostServices;
-
- setAlignment(Pos.TOP_CENTER);
-
- Image appIcon = new Image(Main.class.getResourceAsStream("app_icon.png"));
- ImageView appIconImageView = new ImageView(appIcon);
- appIconImageView.setFitHeight(196);
- appIconImageView.setFitWidth(182);
-
- Label licenseLabel = new Label("License");
- licenseLabel.getStyleClass().add("about_license_label");
-
- VBox.setMargin(licenseLabel, new Insets(20, 0 , 10 ,0));
-
- TextArea licenseTextArea = new TextArea(License.getLicense());
- licenseTextArea.getStyleClass().add("about_license_text_area");
- licenseTextArea.setWrapText(false);
- licenseTextArea.setEditable(false);
- licenseTextArea.setMaxWidth(600);
-
- VBox.setVgrow(licenseTextArea, Priority.ALWAYS);
-
- HBox links = new HBox();
- links.getStyleClass().add("about_links_box");
-
- Hyperlink github = new Hyperlink("GitHub");
- github.setOnAction(event -> openWebpage("https://github.com/Stream-Pi"));
-
- Hyperlink discord = new Hyperlink("Discord");
- discord.setOnAction(event -> openWebpage("https://discord.gg/BExqGmk"));
-
- Hyperlink website = new Hyperlink("Website");
- website.setOnAction(event -> openWebpage("https://stream-pi.com"));
-
- Hyperlink twitter = new Hyperlink("Twitter");
- twitter.setOnAction(event -> openWebpage("https://twitter.com/Stream_Pi"));
-
- Hyperlink matrix = new Hyperlink("Matrix");
- matrix.setOnAction(event -> openWebpage("https://matrix.to/#/#stream-pi_general:matrix.org"));
-
- links.setAlignment(Pos.CENTER);
- links.getChildren().addAll(github, matrix, discord, website, twitter);
-
- Hyperlink donateButton = new Hyperlink("DONATE");
- donateButton.setOnAction(event -> {
- openWebpage("https://www.patreon.com/streampi");
- });
- donateButton.getStyleClass().add("about_donate_hyperlink");
-
-
- ServerInfo serverInfo = ServerInfo.getInstance();
-
- Label versionText = new Label(serverInfo.getVersion().getText() + " - "+ serverInfo.getPlatformType().getUIName() + " - "+ serverInfo.getReleaseStatus().getUIName());
- versionText.getStyleClass().add("about_version_label");
-
- Label commStandardLabel = new Label("Comm Standard "+serverInfo.getCommStandardVersion().getText());
- commStandardLabel.getStyleClass().add("about_comm_standard_label");
-
- Label minThemeAPILabel = new Label("Min ThemeAPI "+serverInfo.getMinThemeSupportVersion().getText());
- minThemeAPILabel.getStyleClass().add("about_min_theme_api_label");
-
- Label minActionAPILabel = new Label("Min ActionAPI "+serverInfo.getMinPluginSupportVersion().getText());
- minActionAPILabel.getStyleClass().add("about_min_action_api_label");
-
- Label currentActionAPILabel = new Label("ActionAPI "+ ActionAPI.API_VERSION.getText());
- currentActionAPILabel.getStyleClass().add("about_current_action_api_label");
-
- getChildren().addAll(appIconImageView, licenseLabel, licenseTextArea, links, donateButton, versionText, commStandardLabel, minThemeAPILabel, minActionAPILabel, currentActionAPILabel);
- }
-
- public void openWebpage(String url) {
- hostServices.showDocument(url);
- }
-}
--- /dev/null
+++ b/src/main/java/com/stream_pi/server/window/settings/About/About.java
@@ -0,0 +1,101 @@
+package com.stream_pi.server.window.settings.About;
+
+import com.stream_pi.action_api.ActionAPI;
+import com.stream_pi.server.info.ServerInfo;
+import com.stream_pi.server.Main;
+import javafx.application.HostServices;
+import javafx.event.Event;
+import javafx.geometry.Pos;
+import javafx.scene.CacheHint;
+import javafx.scene.control.*;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.SwipeEvent;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.VBox;
+
+import java.util.Objects;
+
+public class About extends VBox
+{
+
+ private HostServices hostServices;
+
+ public About(HostServices hostServices)
+ {
+ getStyleClass().add("about");
+ this.hostServices = hostServices;
+
+ setAlignment(Pos.TOP_CENTER);
+
+ Image appIcon = new Image(Objects.requireNonNull(Main.class.getResourceAsStream("app_icon.png")));
+ ImageView appIconImageView = new ImageView(appIcon);
+ appIconImageView.setFitHeight(196);
+ appIconImageView.setFitWidth(182);
+
+ TabPane tabPane = new TabPane();
+ tabPane.addEventFilter(SwipeEvent.ANY, Event::consume);
+ tabPane.getStyleClass().add("settings_about_tab_internal");
+ tabPane.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
+ tabPane.setMaxWidth(600);
+ VBox.setVgrow(tabPane, Priority.ALWAYS);
+
+ Tab licenseTab = new Tab("License");
+ licenseTab.setContent(new LicenseTab());
+
+
+ Tab contributorsTab = new Tab("Contributors");
+ contributorsTab.setContent(new ContributorsTab());
+
+ Tab contactTab = new Tab("Contact");
+ contactTab.setContent(new ContactTab(hostServices));
+
+ tabPane.getTabs().addAll(licenseTab, contributorsTab, contactTab);
+
+
+ Hyperlink donateButton = new Hyperlink("DONATE");
+ donateButton.setOnAction(event -> openWebpage("https://www.patreon.com/streampi"));
+ donateButton.getStyleClass().add("about_donate_hyperlink");
+
+ ServerInfo serverInfo = ServerInfo.getInstance();
+
+ Label versionText = new Label(serverInfo.getVersion().getText() + " - "+ serverInfo.getPlatform().getUIName() + " - "+ serverInfo.getReleaseStatus().getUIName());
+ versionText.getStyleClass().add("about_version_label");
+
+ Label commStandardLabel = new Label("Comm Standard "+serverInfo.getCommStandardVersion().getText());
+ commStandardLabel.getStyleClass().add("about_comm_standard_label");
+
+ Label minThemeAPILabel = new Label("Min ThemeAPI "+serverInfo.getMinThemeSupportVersion().getText());
+ minThemeAPILabel.getStyleClass().add("about_min_theme_api_label");
+
+ Label minActionAPILabel = new Label("Min ActionAPI "+serverInfo.getMinPluginSupportVersion().getText());
+ minActionAPILabel.getStyleClass().add("about_min_action_api_label");
+
+ Label currentActionAPILabel = new Label("ActionAPI "+ ActionAPI.API_VERSION.getText());
+ currentActionAPILabel.getStyleClass().add("about_current_action_api_label");
+
+ HBox hBox = new HBox(versionText, getSep(),
+ commStandardLabel, getSep(),
+ minThemeAPILabel, getSep(),
+ minActionAPILabel, getSep(),
+ currentActionAPILabel);
+
+ hBox.setAlignment(Pos.CENTER);
+ hBox.setSpacing(10);
+
+ getChildren().addAll(appIconImageView, tabPane, donateButton, hBox);
+ }
+
+ public void openWebpage(String url)
+ {
+ hostServices.showDocument(url);
+ }
+
+ private Label getSep()
+ {
+ Label label = new Label("|");
+ label.getStyleClass().add("separator_ui_label");
+ return label;
+ }
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/server/window/settings/About/ContactTab.java
@@ -0,0 +1,49 @@
+package com.stream_pi.server.window.settings.About;
+
+import javafx.application.HostServices;
+import javafx.geometry.Insets;
+import javafx.scene.control.Hyperlink;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.layout.VBox;
+
+
+public class ContactTab extends ScrollPane
+{
+ private final HostServices hostServices;
+
+
+ public ContactTab(HostServices hostServices)
+ {
+ this.hostServices = hostServices;
+
+ getStyleClass().add("about_contact_tab_scroll_pane");
+
+ Hyperlink github = new Hyperlink("GitHub");
+ github.setOnAction(event -> openWebpage("https://github.com/Stream-Pi"));
+
+ Hyperlink discord = new Hyperlink("Discord");
+ discord.setOnAction(event -> openWebpage("https://discord.gg/BExqGmk"));
+
+ Hyperlink website = new Hyperlink("Website");
+ website.setOnAction(event -> openWebpage("https://stream-pi.com"));
+
+ Hyperlink twitter = new Hyperlink("Twitter");
+ twitter.setOnAction(event -> openWebpage("https://twitter.com/Stream_Pi"));
+
+ Hyperlink matrix = new Hyperlink("Matrix");
+ matrix.setOnAction(event -> openWebpage("https://matrix.to/#/#stream-pi_general:matrix.org"));
+
+
+ VBox vBox = new VBox(github, discord, website, twitter, matrix);
+ vBox.setSpacing(10.0);
+
+ setContent(vBox);
+ }
+
+
+ public void openWebpage(String url)
+ {
+ hostServices.showDocument(url);
+ }
+
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/server/window/settings/About/Contributor.java
@@ -0,0 +1,49 @@
+package com.stream_pi.server.window.settings.About;
+
+public class Contributor
+{
+ private String name = null;
+ private String email = null;
+ private String description = null;
+ private String location = null;
+
+ public Contributor(String name, String email, String description, String location)
+ {
+ this.name = name;
+ this.email = email;
+ this.description = description;
+ this.location = location;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public void setLocation(String location) {
+ this.location = location;
+ }
+}
\ No newline at end of file
--- /dev/null
+++ b/src/main/java/com/stream_pi/server/window/settings/About/ContributorsTab.java
@@ -0,0 +1,78 @@
+package com.stream_pi.server.window.settings.About;
+
+import javafx.scene.control.Label;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.layout.VBox;
+
+public class ContributorsTab extends VBox
+{
+
+ public ContributorsTab()
+ {
+ getStyleClass().add("about_license_contributors_vbox");
+
+ TableView<Contributor> tableView = new TableView<>();
+ tableView.getStyleClass().add("about_license_contributors_table_view");
+
+ TableColumn<Contributor, String> descriptionColumn = new TableColumn<>("Description");
+ descriptionColumn.setReorderable(false);
+ descriptionColumn.setPrefWidth(250);
+ descriptionColumn.setResizable(false);
+ descriptionColumn.setCellValueFactory(new PropertyValueFactory<>("description"));
+
+ TableColumn<Contributor, String> nameColumn = new TableColumn<>("Name (GitHub)");
+ nameColumn.setReorderable(false);
+ nameColumn.setPrefWidth(220);
+ nameColumn.setResizable(false);
+ nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
+
+ TableColumn<Contributor, String> emailColumn = new TableColumn<>("Email");
+ emailColumn.setReorderable(false);
+ emailColumn.setPrefWidth(200);
+ emailColumn.setResizable(false);
+ emailColumn.setCellValueFactory(new PropertyValueFactory<>("email"));
+
+ TableColumn<Contributor, String> locationColumn = new TableColumn<>("Location");
+ locationColumn.setReorderable(false);
+ locationColumn.setPrefWidth(100);
+ locationColumn.setResizable(false);
+ locationColumn.setCellValueFactory(new PropertyValueFactory<>("location"));
+
+
+ tableView.getColumns().addAll(descriptionColumn, nameColumn, emailColumn, locationColumn);
+
+ tableView.setPrefWidth(descriptionColumn.getPrefWidth() + nameColumn.getPrefWidth() + emailColumn.getPrefWidth());
+
+
+ tableView.getItems().addAll(
+ new Contributor("Debayan Sutradhar (rnayabed)",
+ "debayansutradhar3@gmail.com",
+ "Founder, Original Author, Maintainer",
+ "India"),
+ new Contributor("Samuel Quiñones (SamuelQuinones)",
+ "sdquinones1@gmail.com",
+ "Founder",
+ "United States"),
+ new Contributor("Abhinay Agarwal (abhinayagarwal)",
+ "abhinay_agarwal@live.com",
+ "Refactoring, Fixes",
+ "India"),
+ new Contributor("Jordan Duabe (j4ckofalltrades)",
+ "jordan.duabe@gmail.com",
+ "Minor Fix (#0dafac9)",
+ "Australia")
+ );
+
+ Label disclaimerLabel = new Label("This contributor list shows only those who have contributed " +
+ "to the Server Source code.\nTo know about the contributors of Action API, Theme API, Util, " +
+ "visit the respective repositories.");
+
+ disclaimerLabel.getStyleClass().add("about_license_contributors_disclaimer_label");
+
+ disclaimerLabel.setWrapText(true);
+
+ getChildren().addAll(tableView, disclaimerLabel);
+ }
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/server/window/settings/About/LicenseTab.java
@@ -0,0 +1,16 @@
+package com.stream_pi.server.window.settings.About;
+
+
+import com.stream_pi.server.info.License;
+import javafx.scene.control.TextArea;
+
+public class LicenseTab extends TextArea
+{
+ public LicenseTab()
+ {
+ setText(License.getLicense());
+ getStyleClass().add("about_license_text_area");
+ setWrapText(false);
+ setEditable(false);
+ }
+}
--- 'a/src/main/java/com/stream_pi/server/window/settings/ClientsSettings.java'
+++ b/src/main/java/com/stream_pi/server/window/settings/ClientsSettings.java
@@ -11,7 +11,6 @@ import com.stream_pi.util.exception.Mino
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.uihelper.HBoxInputBox;
import com.stream_pi.util.uihelper.SpaceFiller;
-import com.stream_pi.util.platform.ReleaseStatus;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.concurrent.Task;
@@ -28,7 +27,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
-public class ClientsSettings extends VBox {
+public class ClientsSettings extends VBox
+{
private VBox clientsSettingsVBox;
private Button saveButton;
@@ -93,21 +93,6 @@ public class ClientsSettings extends VBo
if(clientSettingsVBox.getNickname().isBlank())
errors.append(" Cannot have blank nickname. \n");
- try {
- Double.parseDouble(clientSettingsVBox.getStartupWindowHeight());
- }
- catch (NumberFormatException e)
- {
- errors.append(" Must have integer display height. \n");
- }
-
- try {
- Double.parseDouble(clientSettingsVBox.getStartupWindowWidth());
- }
- catch (NumberFormatException e)
- {
- errors.append(" Must have integer display width. \n");
- }
for(ClientProfileVBox clientProfileVBox : clientSettingsVBox.getClientProfileVBoxes())
{
@@ -133,48 +118,12 @@ public class ClientsSettings extends VBo
errors2.append(" Must have integer action Gap. \n");
}
-
- try {
- int rows = Integer.parseInt(clientProfileVBox.getRows());
-
- int actionsSize = Integer.parseInt(clientProfileVBox.getActionSize());
- double startupWidth = Double.parseDouble(clientSettingsVBox.getStartupWindowWidth());
-
-
- if((rows*actionsSize) > (startupWidth - 25) && clientSettingsVBox.getPlatform()!= com.stream_pi.util.platform.Platform.ANDROID)
- {
- errors2.append(" Rows out of bounds of screen size. \n"+startupWidth);
- }
- }
- catch (NumberFormatException e)
- {
- errors2.append(" Must have integer Rows. \n");
- }
-
-
- try {
- int cols = Integer.parseInt(clientProfileVBox.getCols());
-
- int actionsSize = Integer.parseInt(clientProfileVBox.getActionSize());
- double startupHeight = Double.parseDouble(clientSettingsVBox.getStartupWindowHeight());
-
- if((cols*actionsSize) > (startupHeight - 25) && clientSettingsVBox.getPlatform()!= com.stream_pi.util.platform.Platform.ANDROID)
- {
- errors2.append(" Cols out of bounds of screen size. \n"+startupHeight);
- }
- }
- catch (NumberFormatException e)
- {
- errors2.append(" Must have integer Columns. \n");
- }
-
-
if(!errors2.toString().isEmpty())
{
errors.append(" ")
.append(clientProfileVBox.getRealName())
.append("\n")
- .append(errors2.toString())
+ .append(errors2)
.append("\n");
}
}
@@ -185,7 +134,7 @@ public class ClientsSettings extends VBo
finalErrors.append("* ")
.append(clientSettingsVBox.getRealNickName())
.append("\n")
- .append(errors.toString())
+ .append(errors)
.append("\n");
}
@@ -195,7 +144,7 @@ public class ClientsSettings extends VBo
if(!finalErrors.toString().isEmpty())
throw new MinorException("You made form mistakes",
- "Please fix the following issues : \n"+finalErrors.toString());
+ "Please fix the following issues : \n"+finalErrors);
@@ -272,16 +221,19 @@ public class ClientsSettings extends VBo
private ComboBox<ClientTheme> themesComboBox;
- private TextField startupWindowHeightTextField;
+ private Client client;
- public String getStartupWindowHeight() {
- return startupWindowHeightTextField.getText();
+ public void setClient(Client client)
+ {
+ this.client = client;
}
- private TextField startupWindowWidthTextField;
+ public double getDisplayHeight() {
+ return client.getDisplayHeight();
+ }
- public String getStartupWindowWidth() {
- return startupWindowWidthTextField.getText();
+ public double getDisplayWidth() {
+ return client.getDisplayWidth();
}
private TextField nicknameTextField;
@@ -315,8 +267,6 @@ public class ClientsSettings extends VBo
private Label platformLabel;
- private HBoxInputBox startupWindowHeightInputBox, startupWindowWidthInputBox;
-
public ArrayList<ClientProfileVBox> getClientProfileVBoxes() {
return clientProfileVBoxes;
}
@@ -340,21 +290,15 @@ public class ClientsSettings extends VBo
}
public void saveClientAndProfileDetails() throws SevereException, CloneNotSupportedException, MinorException {
- System.out.println("IIN");
+
getConnection().saveClientDetails(
nicknameTextField.getText(),
- startupWindowWidthTextField.getText(),
- startupWindowHeightTextField.getText(),
profilesComboBox.getSelectionModel().getSelectedItem().getID(),
themesComboBox.getSelectionModel().getSelectedItem().getThemeFullName()
);
- System.out.println("OUT");
-
- logger.info("Profiles : ");
for(ClientProfileVBox clientProfileVBox : clientProfileVBoxes)
{
- logger.info("Name : "+clientProfileVBox.getClientProfile().getName());
getConnection().saveProfileDetails(clientProfileVBox.getClientProfile());
}
@@ -434,9 +378,6 @@ public class ClientsSettings extends VBo
themesComboBox.setCellFactory(themesComboBoxFactory);
themesComboBox.setButtonCell(themesComboBoxFactory.call(null));
- startupWindowHeightTextField = new TextField();
- startupWindowWidthTextField = new TextField();
-
platformLabel = new Label();
platformLabel.getStyleClass().add("client_settings_each_client_platform_label");
@@ -464,12 +405,6 @@ public class ClientsSettings extends VBo
getStyleClass().add("settings_clients_each_client");
- startupWindowHeightInputBox = new HBoxInputBox("Startup window Height", startupWindowHeightTextField);
- startupWindowHeightInputBox.managedProperty().bind(startupWindowHeightInputBox.visibleProperty());
-
- startupWindowWidthInputBox = new HBoxInputBox("Startup window Width", startupWindowWidthTextField);
- startupWindowWidthInputBox.managedProperty().bind(startupWindowWidthInputBox.visibleProperty());
-
this.getChildren().addAll(
nickNameLabel,
@@ -479,16 +414,12 @@ public class ClientsSettings extends VBo
new HBoxInputBox("Nickname",nicknameTextField),
new HBox(
new Label("Theme"),
- new SpaceFiller(SpaceFiller.FillerType.HBox),
+ SpaceFiller.horizontal(),
themesComboBox
),
- startupWindowHeightInputBox,
-
- startupWindowWidthInputBox,
-
new HBox(new Label("Startup Profile"),
- new SpaceFiller(SpaceFiller.FillerType.HBox),
+ SpaceFiller.horizontal(),
profilesComboBox),
addNewProfileButton,
@@ -515,16 +446,9 @@ public class ClientsSettings extends VBo
nicknameTextField.setText(client.getNickName());
- if(client.getPlatform() == com.stream_pi.util.platform.Platform.ANDROID)
- {
- startupWindowHeightInputBox.setVisible(false);
- startupWindowWidthInputBox.setVisible(false);
- }
-
platformLabel.setText("Platform : "+client.getPlatform().getUIName());
- startupWindowWidthTextField.setText(client.getStartupDisplayWidth()+"");
- startupWindowHeightTextField.setText(client.getStartupDisplayHeight()+"");
+ setClient(client);
socketConnectionLabel.setText(client.getRemoteSocketAddress().toString().substring(1)); //substring removes the `/`
@@ -673,10 +597,10 @@ public class ClientsSettings extends VBo
getChildren().addAll(
new HBoxInputBox("Name ", nameTextField),
- new HBoxInputBox("Columns", rowsTextField),
- new HBoxInputBox("Rows", colsTextField),
- new HBoxInputBox("action Size", actionSizeTextField),
- new HBoxInputBox("action Gap", actionGapTextField),
+ new HBoxInputBox("Rows", rowsTextField),
+ new HBoxInputBox("Columns", colsTextField),
+ new HBoxInputBox("Action Size", actionSizeTextField),
+ new HBoxInputBox("Action Gap", actionGapTextField),
hBox
);
}
--- 'a/src/main/java/com/stream_pi/server/window/settings/GeneralSettings.java'
+++ b/src/main/java/com/stream_pi/server/window/settings/GeneralSettings.java
@@ -7,14 +7,17 @@ import com.stream_pi.server.info.ServerI
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlertType;
+import com.stream_pi.util.checkforupdates.CheckForUpdates;
+import com.stream_pi.util.checkforupdates.UpdateHyperlinkOnClick;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.SevereException;
-import com.stream_pi.util.startatboot.SoftwareType;
+import com.stream_pi.util.platform.PlatformType;
import com.stream_pi.util.startatboot.StartAtBoot;
import com.stream_pi.util.version.Version;
import javafx.application.HostServices;
import javafx.application.Platform;
import javafx.concurrent.Task;
+import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.*;
@@ -24,7 +27,6 @@ import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.*;
import javafx.stage.DirectoryChooser;
-import org.json.JSONObject;
import org.kordamp.ikonli.javafx.FontIcon;
import java.awt.SystemTray;
@@ -43,7 +45,7 @@ public class GeneralSettings extends VBo
private final TextField actionGridPaneActionBoxSize;
private final TextField actionGridPaneActionBoxGap;
private final ToggleButton startOnBootToggleButton;
- private final ToggleButton closeOnXToggleButton;
+ private final ToggleButton minimizeToSystemTrayOnCloseToggleButton;
private final Button saveButton;
private final Button checkForUpdatesButton;
@@ -78,7 +80,7 @@ public class GeneralSettings extends VBo
actionGridPaneActionBoxGap = new TextField();
startOnBootToggleButton = new ToggleButton("Start on Boot");
- closeOnXToggleButton = new ToggleButton("Quit On window Close");
+ minimizeToSystemTrayOnCloseToggleButton = new ToggleButton("Minimise To Tray On Close");
checkForUpdatesButton = new Button("Check for updates");
checkForUpdatesButton.setOnAction(event->checkForUpdates());
@@ -100,7 +102,7 @@ public class GeneralSettings extends VBo
serverNameTextField.setPrefWidth(200);
- HBox toggleButtons = new HBox(closeOnXToggleButton, startOnBootToggleButton);
+ HBox toggleButtons = new HBox(minimizeToSystemTrayOnCloseToggleButton, startOnBootToggleButton);
toggleButtons.setSpacing(10.0);
VBox.setMargin(toggleButtons, new Insets(30, 0 , 0,0));
toggleButtons.setAlignment(Pos.CENTER);
@@ -115,6 +117,17 @@ public class GeneralSettings extends VBo
}
+ private void checkForUpdates()
+ {
+ new CheckForUpdates(checkForUpdatesButton,
+ PlatformType.SERVER, ServerInfo.getInstance().getVersion(), new UpdateHyperlinkOnClick() {
+ @Override
+ public void handle(ActionEvent actionEvent) {
+ hostServices.showDocument(getURL());
+ }
+ });
+ }
+
private HBox getUIInputBoxWithDirectoryChooser(String labelText, TextField textField)
{
HBox hBox = getUIInputBox(labelText, textField);
@@ -176,7 +189,7 @@ public class GeneralSettings extends VBo
actionGridPaneActionBoxSize.setText(config.getActionGridActionSize()+"");
actionGridPaneActionBoxGap.setText(config.getActionGridActionGap()+"");
- closeOnXToggleButton.setSelected(config.getCloseOnX());
+ minimizeToSystemTrayOnCloseToggleButton.setSelected(config.getMinimiseToSystemTrayOnClose());
startOnBootToggleButton.setSelected(config.getStartOnBoot());
});
}
@@ -197,7 +210,7 @@ public class GeneralSettings extends VBo
serverNameTextField.setDisable(true);
portTextField.setDisable(true);
- closeOnXToggleButton.setDisable(true);
+ minimizeToSystemTrayOnCloseToggleButton.setDisable(true);
startOnBootToggleButton.setDisable(true);
});
@@ -209,7 +222,7 @@ public class GeneralSettings extends VBo
String actionGridActionBoxSize = actionGridPaneActionBoxSize.getText();
String actionGridActionBoxGap = actionGridPaneActionBoxGap.getText();
- boolean closeOnX = closeOnXToggleButton.isSelected();
+ boolean minimizeToSystemTrayOnClose = minimizeToSystemTrayOnCloseToggleButton.isSelected();
boolean startOnBoot = startOnBootToggleButton.isSelected();
Config config = Config.getInstance();
@@ -235,7 +248,9 @@ public class GeneralSettings extends VBo
serverPort = Integer.parseInt(serverPortStr);
if (serverPort < 1024)
- errors.append("* Server Port must be more than 1024");
+ errors.append("* Server Port must be more than 1024\n");
+ else if(serverPort > 65535)
+ errors.append("* Server Port must be lesser than 65535\n");
if(config.getPort()!=serverPort)
{
@@ -303,7 +318,7 @@ public class GeneralSettings extends VBo
if(!errors.toString().isEmpty())
{
- throw new MinorException("settings", "Please rectify the following errors and try again :\n"+errors.toString());
+ throw new MinorException("Uh Oh!", "Please rectify the following errors and try again :\n"+errors.toString());
}
if(config.getStartOnBoot() != startOnBoot)
@@ -315,7 +330,7 @@ public class GeneralSettings extends VBo
}
else
{
- StartAtBoot startAtBoot = new StartAtBoot(SoftwareType.SERVER, ServerInfo.getInstance().getPlatformType());
+ StartAtBoot startAtBoot = new StartAtBoot(PlatformType.SERVER, ServerInfo.getInstance().getPlatform());
if(startOnBoot)
{
startAtBoot.create(new File(ServerInfo.getInstance().getRunnerFileName()));
@@ -329,19 +344,14 @@ public class GeneralSettings extends VBo
}
}
- if(!closeOnX)
+ if(minimizeToSystemTrayOnClose)
{
- System.out.println("XYZ");
if(!SystemTray.isSupported())
{
StreamPiAlert alert = new StreamPiAlert("Not Supported", "Tray System not supported on this platform ", StreamPiAlertType.ERROR);
alert.show();
- closeOnX = true;
- }
- else
- {
- System.out.println("YES");
+ minimizeToSystemTrayOnClose = false;
}
}
@@ -352,7 +362,7 @@ public class GeneralSettings extends VBo
config.setPluginsPath(pluginsPathStr);
config.setThemesPath(themesPathStr);
- config.setCloseOnX(closeOnX);
+ config.setMinimiseToSystemTrayOnClose(minimizeToSystemTrayOnClose);
config.setStartupOnBoot(startOnBoot);
config.save();
@@ -385,7 +395,7 @@ public class GeneralSettings extends VBo
serverNameTextField.setDisable(false);
portTextField.setDisable(false);
- closeOnXToggleButton.setDisable(false);
+ minimizeToSystemTrayOnCloseToggleButton.setDisable(false);
startOnBootToggleButton.setDisable(false);
});
}
@@ -393,86 +403,4 @@ public class GeneralSettings extends VBo
}
}).start();
}
-
- public void checkForUpdates()
- {
- new Thread(new Task<Void>()
- {
- @Override
- protected Void call() throws Exception {
- try
- {
- Platform.runLater(()->checkForUpdatesButton.setDisable(true));
-
-
- String jsonRaw = readUrl("https://stream-pi.com/API/get_latest.php?TYPE=SERVER");
-
- System.out.println(jsonRaw);
-
- JSONObject jsonObject = new JSONObject(jsonRaw);
-
- String latestVersionRaw = jsonObject.getString("Version");
- String releasePage = jsonObject.getString("Release Page");
-
- Version latestVersion = new Version(latestVersionRaw);
- Version currentVersion = ServerInfo.getInstance().getVersion();
-
- if(latestVersion.isBiggerThan(currentVersion))
- {
- VBox vBox = new VBox();
-
- Hyperlink urlLabel = new Hyperlink(releasePage);
- urlLabel.setOnAction(event->hostServices.showDocument(releasePage));
-
- Label label = new Label(
- "New Version "+latestVersionRaw+" Available.\n" +
- "Current Version "+currentVersion.getText()+".\n"+
- "Changelog and install instructions are included in the release page.\n" +
- "It is recommended to update to ensure maximum stability and least bugs.");
- label.setWrapText(true);
-
- vBox.setSpacing(5);
- vBox.getChildren().addAll(
- urlLabel,
- label
- );
-
- new StreamPiAlert("New Update Available!", StreamPiAlertType.INFORMATION, vBox).show();;
- }
- else
- {
- new StreamPiAlert("Up to Date", "Server is upto date. ("+currentVersion.getText()+")", StreamPiAlertType.INFORMATION).show();;
- }
- }
- catch (Exception e)
- {
- e.printStackTrace();
- new StreamPiAlert("Uh Oh", "Update Check Failed. API Error/Network issue.", StreamPiAlertType.WARNING).show();;
- }
- finally
- {
- Platform.runLater(()->checkForUpdatesButton.setDisable(false));
- }
- return null;
- }
- }).start();;
- }
-
- private String readUrl(String urlString) throws Exception {
- BufferedReader reader = null;
- try {
- URL url = new URL(urlString);
- reader = new BufferedReader(new InputStreamReader(url.openStream()));
- StringBuffer buffer = new StringBuffer();
- int read;
- char[] chars = new char[1024];
- while ((read = reader.read(chars)) != -1)
- buffer.append(chars, 0, read);
-
- return buffer.toString();
- } finally {
- if (reader != null)
- reader.close();
- }
- }
}
--- 'a/src/main/java/com/stream_pi/server/window/settings/PluginsSettings.java'
+++ b/src/main/java/com/stream_pi/server/window/settings/PluginsSettings.java
@@ -1,22 +1,21 @@
package com.stream_pi.server.window.settings;
+import com.stream_pi.action_api.externalplugin.ExternalPlugin;
import com.stream_pi.server.uipropertybox.UIPropertyBox;
-import com.stream_pi.actionapi.actionproperty.property.ControlType;
-import com.stream_pi.actionapi.actionproperty.property.Property;
-import com.stream_pi.actionapi.actionproperty.property.Type;
-import com.stream_pi.actionapi.normalaction.NormalAction;
-import com.stream_pi.server.action.NormalActionPlugins;
+import com.stream_pi.action_api.actionproperty.property.ControlType;
+import com.stream_pi.action_api.actionproperty.property.Property;
+import com.stream_pi.action_api.actionproperty.property.Type;
+import com.stream_pi.action_api.externalplugin.NormalAction;
+import com.stream_pi.server.action.ExternalPlugins;
import com.stream_pi.server.connection.ServerListener;
import com.stream_pi.server.window.ExceptionAndAlertHandler;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.uihelper.SpaceFiller;
-import com.stream_pi.util.uihelper.SpaceFiller.FillerType;
import org.kordamp.ikonli.javafx.FontIcon;
import javafx.application.HostServices;
import javafx.application.Platform;
-import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.*;
@@ -115,6 +114,13 @@ public class PluginsSettings extends VBo
errors.append(" -> ").append(serverProperty.getDisplayName()).append(" cannot be blank.\n");
}
}
+ else if(serverProperty.getControlType() == ControlType.TEXT_FIELD_MASKED)
+ {
+ String value = ((TextField) controlNode).getText();
+
+ if(value.isBlank() && !serverProperty.isCanBeBlank())
+ errors.append(" -> ").append(serverProperty.getDisplayName()).append(" cannot be blank.\n");
+ }
}
if(!errors.toString().isBlank())
@@ -138,16 +144,16 @@ public class PluginsSettings extends VBo
String rawValue = serverProperty.getRawValue();
- NormalActionPlugins.getInstance().getActionFromIndex(pp.getIndex())
+ ExternalPlugins.getInstance().getActionFromIndex(pp.getIndex())
.getServerProperties().get()
.get(serverProperty.getIndex()).setRawValue(rawValue);
}
}
- NormalActionPlugins.getInstance().saveServerSettings();
+ ExternalPlugins.getInstance().saveServerSettings();
- NormalActionPlugins.getInstance().initPlugins();
+ ExternalPlugins.getInstance().initPlugins();
}
catch (MinorException e)
{
@@ -171,7 +177,7 @@ public class PluginsSettings extends VBo
pluginProperties.clear();
- List<NormalAction> actions = NormalActionPlugins.getInstance().getPlugins();
+ List<ExternalPlugin> actions = ExternalPlugins.getInstance().getPlugins();
Platform.runLater(()-> pluginsSettingsVBox.getChildren().clear());
@@ -193,7 +199,7 @@ public class PluginsSettings extends VBo
for(int i = 0; i<actions.size(); i++)
{
- NormalAction action = actions.get(i);
+ ExternalPlugin action = actions.get(i);
if(!action.isVisibleInServerSettingsPane())
continue;
@@ -215,7 +221,7 @@ public class PluginsSettings extends VBo
helpButton.setGraphic(questionIcon);
helpButton.setOnAction(event -> hostServices.showDocument(action.getHelpLink()));
- headerHBox.getChildren().addAll(new SpaceFiller(FillerType.HBox),helpButton);
+ headerHBox.getChildren().addAll(SpaceFiller.horizontal() ,helpButton);
}
@@ -251,7 +257,7 @@ public class PluginsSettings extends VBo
Region region = new Region();
HBox.setHgrow(region, Priority.ALWAYS);
- HBox hBox = new HBox(label, new SpaceFiller(SpaceFiller.FillerType.HBox));
+ HBox hBox = new HBox(label, SpaceFiller.horizontal());
//hBox.setId(j+"");
Node controlNode = null;
@@ -273,6 +279,15 @@ public class PluginsSettings extends VBo
controlNode = textField;
}
+ else if(eachProperty.getControlType() == ControlType.TEXT_FIELD_MASKED)
+ {
+ PasswordField textField = new PasswordField();
+ textField.setText(eachProperty.getRawValue());
+
+ controlNode= textField;
+
+ hBox.getChildren().add(controlNode);
+ }
else if(eachProperty.getControlType() == ControlType.TOGGLE)
{
ToggleButton toggleButton = new ToggleButton();
@@ -341,10 +356,11 @@ public class PluginsSettings extends VBo
vBox.setSpacing(5.0);
vBox.getChildren().addAll(headerHBox, authorLabel, moduleLabel, versionLabel, serverPropertiesVBox);
- if(action.getButtonBar()!=null)
+ if(action.getServerSettingsButtonBar()!=null)
{
- HBox buttonBarHBox = new HBox(new SpaceFiller(SpaceFiller.FillerType.HBox), action.getButtonBar());
- buttonBarHBox.getStyleClass().add("plugins_settings_each_plugin_button_bar");
+ action.getServerSettingsButtonBar().getStyleClass().add("plugins_settings_each_plugin_button_bar");
+ HBox buttonBarHBox = new HBox(SpaceFiller.horizontal(), action.getServerSettingsButtonBar());
+ buttonBarHBox.getStyleClass().add("plugins_settings_each_plugin_button_bar_hbox");
vBox.getChildren().add(buttonBarHBox);
}
--- 'a/src/main/java/com/stream_pi/server/window/settings/SettingsBase.java'
+++ b/src/main/java/com/stream_pi/server/window/settings/SettingsBase.java
@@ -2,15 +2,19 @@ package com.stream_pi.server.window.sett
import com.stream_pi.server.connection.ServerListener;
import com.stream_pi.server.window.ExceptionAndAlertHandler;
+import com.stream_pi.server.window.settings.About.About;
import javafx.application.HostServices;
+import javafx.event.Event;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.CacheHint;
import javafx.scene.control.*;
+import javafx.scene.input.SwipeEvent;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
-public class SettingsBase extends VBox {
+public class SettingsBase extends VBox
+{
private TabPane tabPane;
@@ -31,6 +35,7 @@ public class SettingsBase extends VBox {
this.hostServices = hostServices;
tabPane = new TabPane();
+ tabPane.addEventFilter(SwipeEvent.ANY, Event::consume);
tabPane.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
VBox.setVgrow(tabPane, Priority.ALWAYS);
@@ -50,7 +55,6 @@ public class SettingsBase extends VBox {
clientsSettings = new ClientsSettings(exceptionAndAlertHandler, serverListener);
clientsSettingsTab.setContent(clientsSettings);
-
Tab aboutTab = new Tab("About");
aboutTab.setContent(new About(hostServices));
@@ -64,7 +68,7 @@ public class SettingsBase extends VBox {
getChildren().addAll(tabPane, closeButton);
setCache(true);
- setCacheHint(CacheHint.QUALITY);
+ setCacheHint(CacheHint.SPEED);
}
public void setDefaultTabToGeneral()
--- 'a/src/main/java/com/stream_pi/server/window/settings/ThemesSettings.java'
+++ b/src/main/java/com/stream_pi/server/window/settings/ThemesSettings.java
@@ -2,8 +2,8 @@ package com.stream_pi.server.window.sett
import com.stream_pi.server.controller.Controller;
import com.stream_pi.server.io.Config;
-import com.stream_pi.themeapi.Theme;
-import com.stream_pi.themeapi.Themes;
+import com.stream_pi.theme_api.Theme;
+import com.stream_pi.theme_api.Themes;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.uihelper.SpaceFiller;
import javafx.application.HostServices;
@@ -112,7 +112,7 @@ public class ThemesSettings extends VBox
helpButton.setGraphic(questionIcon);
helpButton.setOnAction(event -> hostServices.showDocument(theme.getWebsite()));
- topRowHBox.getChildren().addAll(new SpaceFiller(SpaceFiller.FillerType.HBox), helpButton);
+ topRowHBox.getChildren().addAll(SpaceFiller.horizontal(), helpButton);
}
ToggleButton toggleButton = new ToggleButton();
--- 'a/src/main/java/module-info.java'
+++ b/src/main/java/module-info.java
@@ -1,10 +1,13 @@
-module com.stream_pi.server {
- uses com.stream_pi.actionapi.action.Action;
- uses com.stream_pi.actionapi.normalaction.NormalAction;
+module com.stream_pi.server
+{
- requires com.stream_pi.actionapi;
+ uses com.stream_pi.action_api.action.Action;
+ uses com.stream_pi.action_api.externalplugin.NormalAction;
+ uses com.stream_pi.action_api.externalplugin.ExternalPlugin;
+
+ requires com.stream_pi.action_api;
requires com.stream_pi.util;
- requires com.stream_pi.themeapi;
+ requires com.stream_pi.theme_api;
requires org.kordamp.ikonli.javafx;
@@ -19,7 +22,8 @@ module com.stream_pi.server {
requires java.sql;
- requires org.json;
+ opens com.stream_pi.server.window.settings;
exports com.stream_pi.server;
+ opens com.stream_pi.server.window.settings.About;
}
\ No newline at end of file
Binary files 'a/src/main/resources/com/stream_pi/server/Default.obj' and /dev/null differ
Binary files /dev/null and b/src/main/resources/com/stream_pi/server/Default.zip differ
--- /dev/null
+++ b/src/main/resources/com/stream_pi/server/default_icons.css
@@ -0,0 +1,34 @@
+.alert_error_icon
+{
+ -fx-icon-color: RED;
+}
+
+.alert_information_icon
+{
+ -fx-icon-color: BLUE;
+}
+
+.alert_warning_icon
+{
+ -fx-icon-color: #ffcc00;
+}
+
+.action_details_pane_delete_button_icon
+{
+ -fx-icon-color:red;
+}
+
+.action_box_toggle_on
+{
+ -fx-icon-code: fas-toggle-on;
+}
+
+.action_box_toggle_off
+{
+ -fx-icon-code: fas-toggle-off;
+}
+
+.action_details_pane_reset_button_icon
+{
+ -fx-icon-color:orange;
+}
\ No newline at end of file
--- 'a/src/main/resources/com/stream_pi/server/style.css'
+++ b/src/main/resources/com/stream_pi/server/style.css
@@ -8,6 +8,11 @@
-fx-font-weight : bold;
}
+.plugins_settings_each_plugin_button_bar
+{
+ -fx-alignment:center-right;
+}
+
.about_license_label
{
-fx-font-size : 16;
@@ -27,7 +32,7 @@
.action_box
{
-fx-border-width: 1px;
- -fx-shape: "M100,100 h200 a20,20 0 0 1 20,20 v200 a20,20 0 0 1 -20,20 h-200 a20,20 0 0 1 -20,-20 v-200 a20,20 0 0 1 20,-20 z";
+ -fx-border-color : grey;
}
.action_box_icon_present
@@ -91,21 +96,6 @@
-fx-icon-size : 30;
}
-.alert_error_icon
-{
- -fx-icon-color: RED;
-}
-
-.alert_information_icon
-{
- -fx-icon-color: BLUE;
-}
-
-.alert_warning_icon
-{
- -fx-icon-color: #ffcc00;
-}
-
.alert_content_pane
{
-fx-padding: 5;
@@ -235,9 +225,9 @@
-fx-text-fill : red;
}
-.action_details_pane_delete_button_icon
+.action_details_pane_reset_button
{
- -fx-icon-color:red;
+ -fx-text-fill : orange;
}
.client_and_profile_selector_pane_stack
@@ -248,4 +238,48 @@
.plugins_settings, .themes_settings, .clients_settings
{
-fx-padding: 0 10 0 0;
+}
+
+/*Alert Classes added to default stylesheet to show init error, if occurs */
+.action_box_display_text_label
+{
+ -fx-font-size : 16;
+ -fx-background-color : transparent;
+}
+
+.alert_pane
+{
+ -fx-background-color : white;
+ -fx-border-color : white;
+}
+
+.alert_content_pane
+{
+ -fx-background-color: white;
+ -fx-padding: 5;
+}
+
+.alert_scroll_pane
+{
+ -fx-background: white;
+ -fx-border-color:white;
+}
+
+.alert_button_bar
+{
+ -fx-background-color:white;
+}
+
+.split-pane-divider {
+ -fx-padding: 2;
+}
+
+.separator_ui_label
+{
+ -fx-text-fill: grey;
+}
+
+.about_license_contributors_disclaimer_label
+{
+ -fx-min-height : 50;
}
\ No newline at end of file
M style_classes.txt
+8 −3
--- 'a/style_classes.txt'
+++ b/style_classes.txt
@@ -101,9 +101,14 @@ settings
Each Titled Pane - client_settings_each_client_accordion_each_titled_pane
Content VBox - client_settings_each_client_accordion_each_profile_box
About - about
- License Label - about_license_label
- License Text Area - about_license_text_area
- Links HBox - about_links_box
+
+ Tab Pane - settings_about_tab_internal
+ License Tab (Text Area) - about_license_text_area
+ Contributors Tab (VBox) - about_license_contributors_vbox
+ Table View - about_license_contributors_table_view
+ Disclaimer Label - about_license_contributors_disclaimer_label
+ Contact Tab (Scroll Pane) - about_contact_tab_scroll_pane
+
DONATE Hyperlink - about_donate_hyperlink
Version Label - about_version_label