client

Clone or download

lots of minor bug fixes, Client Action Grid Pane now is present inside a Scroll Pane

Modified Files

M pom.xml
+13 −5
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
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>
<modelVersion>4.0.0</modelVersion>
<groupId>com.stream-pi</groupId>
<groupId>com.stream-pi</groupId>
<artifactId>client</artifactId>
<artifactId>client</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>1.0.0-SNAPSHOT</version>
<url>https://stream-pi.com/</url>
<url>https://stream-pi.com/</url>
<properties>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>11</maven.compiler.release>
<maven.compiler.release>11</maven.compiler.release>
<javafx.version>17-ea+7</javafx.version>
<javafx.version>17-ea+7</javafx.version>
<javafx.scope>compile</javafx.scope>
<javafx.scope>compile</javafx.scope>
<javafx.systemPath>/opt/javafx-17-sdk/lib</javafx.systemPath>
<javafx.systemPath>/opt/javafx-17-sdk/lib</javafx.systemPath>
<javafx.drm.egl.lib.path>/home/rnayabed/openjfx/javafx-sdk-17/lib/libgluon_drm-1.1.3.so</javafx.drm.egl.lib.path>
<javafx.drm.egl.lib.path>/home/rnayabed/openjfx/javafx-sdk-17/lib/libgluon_drm-1.1.3.so</javafx.drm.egl.lib.path>
<javafx.drm.display.card>/dev/dri/card0</javafx.drm.display.card>
<javafx.drm.display.card>/dev/dri/card0</javafx.drm.display.card>
<client.plugin.version>0.1.40-SNAPSHOT</client.plugin.version>
<client.plugin.version>0.1.40-SNAPSHOT</client.plugin.version>
<ikonli.version>11.5.0</ikonli.version>
<ikonli.version>11.5.0</ikonli.version>
<action.api.version>1.0.0-SNAPSHOT</action.api.version>
<action.api.version>1.0.0-SNAPSHOT</action.api.version>
<util.version>1.0.0-SNAPSHOT</util.version>
<util.version>1.0.0-SNAPSHOT</util.version>
<theme.api.version>1.0.0-SNAPSHOT</theme.api.version>
<theme.api.version>1.0.0-SNAPSHOT</theme.api.version>
<attach.version>4.0.11</attach.version>
<main.class.name>com.stream_pi.client.Main</main.class.name>
<main.class.name>com.stream_pi.client.Main</main.class.name>
<source.plugin.version>2.2.1</source.plugin.version>
<source.plugin.version>2.2.1</source.plugin.version>
<javadoc.plugin.version>3.1.0</javadoc.plugin.version>
<javadoc.plugin.version>3.1.0</javadoc.plugin.version>
<gpg.plugin.version>1.6</gpg.plugin.version>
<gpg.plugin.version>1.6</gpg.plugin.version>
</properties>
</properties>
<dependencies>
<dependencies>
<dependency>
<dependency>
<groupId>org.openjfx</groupId>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
<version>${javafx.version}</version>
<!--scope>${javafx.scope}</scope>
<!--scope>${javafx.scope}</scope>
<systemPath>${javafx.systemPath}/javafx.controls.jar</systemPath-->
<systemPath>${javafx.systemPath}/javafx.controls.jar</systemPath-->
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>org.openjfx</groupId>
<groupId>org.openjfx</groupId>
<artifactId>javafx-base</artifactId>
<artifactId>javafx-base</artifactId>
<version>${javafx.version}</version>
<version>${javafx.version}</version>
<!--scope>${javafx.scope}</scope>
<!--scope>${javafx.scope}</scope>
<systemPath>${javafx.systemPath}/javafx.base.jar</systemPath-->
<systemPath>${javafx.systemPath}/javafx.base.jar</systemPath-->
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>org.openjfx</groupId>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<artifactId>javafx-graphics</artifactId>
<version>${javafx.version}</version>
<version>${javafx.version}</version>
<!--scope>${javafx.scope}</scope>
<!--scope>${javafx.scope}</scope>
<systemPath>${javafx.systemPath}/javafx.graphics.jar</systemPath-->
<systemPath>${javafx.systemPath}/javafx.graphics.jar</systemPath-->
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-fontawesome5-pack</artifactId>
<artifactId>ikonli-fontawesome5-pack</artifactId>
<version>${ikonli.version}</version>
<version>${ikonli.version}</version>
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-javafx</artifactId>
<artifactId>ikonli-javafx</artifactId>
<version>${ikonli.version}</version>
<version>${ikonli.version}</version>
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>com.stream-pi</groupId>
<groupId>com.stream-pi</groupId>
<artifactId>action-api</artifactId>
<artifactId>action-api</artifactId>
<version>${action.api.version}</version>
<version>${action.api.version}</version>
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>com.stream-pi</groupId>
<groupId>com.stream-pi</groupId>
<artifactId>theme-api</artifactId>
<artifactId>theme-api</artifactId>
<version>${theme.api.version}</version>
<version>${theme.api.version}</version>
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>com.stream-pi</groupId>
<groupId>com.stream-pi</groupId>
<artifactId>util</artifactId>
<artifactId>util</artifactId>
<version>${util.version}</version>
<version>${util.version}</version>
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>com.gluonhq.attach</groupId>
<groupId>com.gluonhq.attach</groupId>
<artifactId>lifecycle</artifactId>
<artifactId>lifecycle</artifactId>
<version>4.0.10</version>
<version>${attach.version}</version>
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>com.gluonhq.attach</groupId>
<groupId>com.gluonhq.attach</groupId>
<artifactId>util</artifactId>
<artifactId>util</artifactId>
<version>4.0.10</version>
<version>${attach.version}</version>
</dependency>
<dependency>
<groupId>com.gluonhq.attach</groupId>
<artifactId>orientation</artifactId>
<version>${attach.version}</version>
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>com.gluonhq.attach</groupId>
<groupId>com.gluonhq.attach</groupId>
<artifactId>storage</artifactId>
<artifactId>storage</artifactId>
<version>4.0.10</version>
<version>${attach.version}</version>
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>com.gluonhq.attach</groupId>
<groupId>com.gluonhq.attach</groupId>
<artifactId>browser</artifactId>
<artifactId>browser</artifactId>
<version>4.0.10</version>
<version>${attach.version}</version>
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>com.gluonhq.attach</groupId>
<groupId>com.gluonhq.attach</groupId>
<artifactId>vibration</artifactId>
<artifactId>vibration</artifactId>
<version>4.0.10</version>
<version>${attach.version}</version>
</dependency>
</dependency>
</dependencies>
</dependencies>
<repositories>
<repositories>
<repository>
<repository>
<id>gluon-releases</id>
<id>gluon-releases</id>
<url>http://nexus.gluonhq.com/nexus/content/repositories/releases/</url>
<url>http://nexus.gluonhq.com/nexus/content/repositories/releases/</url>
</repository>
</repository>
<repository>
<repository>
<id>sonatype-snapshot</id>
<id>sonatype-snapshot</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
</repository>
</repositories>
</repositories>
<build>
<build>
<plugins>
<plugins>
<plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<version>3.8.1</version>
</plugin>
</plugin>
<plugin>
<plugin>
<groupId>org.openjfx</groupId>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.5</version>
<version>0.0.5</version>
<configuration>
<configuration>
<stripDebug>true</stripDebug>
<stripDebug>true</stripDebug>
<compress>2</compress>
<compress>2</compress>
<noHeaderFiles>true</noHeaderFiles>
<noHeaderFiles>true</noHeaderFiles>
<noManPages>true</noManPages>
<noManPages>true</noManPages>
<mainClass>${main.class.name}</mainClass>
<mainClass>${main.class.name}</mainClass>
<!--options>${additional.javafx.plugin.options}</options-->
<!--options>${additional.javafx.plugin.options}</options-->
</configuration>
</configuration>
</plugin>
</plugin>
<plugin>
<plugin>
<groupId>com.gluonhq</groupId>
<groupId>com.gluonhq</groupId>
<artifactId>client-maven-plugin</artifactId>
<artifactId>client-maven-plugin</artifactId>
<version>${client.plugin.version}</version>
<version>${client.plugin.version}</version>
<configuration>
<configuration>
<target>${client.target}</target>
<target>${client.target}</target>
<verbose>true</verbose>
<verbose>true</verbose>
<nativeImageArgs>
<nativeImageArgs>
<list>--initialize-at-build-time=com.sun.org.apache.xml.internal.serializer.ToXMLStream</list>
<list>--initialize-at-build-time=com.sun.org.apache.xml.internal.serializer.ToXMLStream</list>
<list>${additional.native.client.args}</list>
<list>${additional.native.client.args}</list>
</nativeImageArgs>
</nativeImageArgs>
<bundlesList>
<bundlesList>
<list>com.sun.org.apache.xerces.internal.impl.msg.XMLMessages</list>
<list>com.sun.org.apache.xerces.internal.impl.msg.XMLMessages</list>
</bundlesList>
</bundlesList>
<attachList>
<attachList>
<list>lifecycle</list>
<list>lifecycle</list>
<list>storage</list>
<list>storage</list>
<list>browser</list>
<list>browser</list>
<list>vibration</list>
<list>vibration</list>
<list>orientation</list>
</attachList>
</attachList>
<reflectionList>
<reflectionList>
<list>java.util.logging.FileHandler</list>
<list>java.util.logging.FileHandler</list>
</reflectionList>
</reflectionList>
<mainClass>${main.class.name}</mainClass>
<mainClass>${main.class.name}</mainClass>
</configuration>
</configuration>
</plugin>
</plugin>
<plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
<version>3.2.0</version>
<configuration>
<configuration>
<includeEmptyDirs>true</includeEmptyDirs>
<includeEmptyDirs>true</includeEmptyDirs>
</configuration>
</configuration>
</plugin>
</plugin>
</plugins>
</plugins>
</build>
</build>
<pluginRepositories>
<pluginRepositories>
<pluginRepository>
<pluginRepository>
<id>gluon-releases</id>
<id>gluon-releases</id>
<url>http://nexus.gluonhq.com/nexus/content/repositories/releases/</url>
<url>http://nexus.gluonhq.com/nexus/content/repositories/releases/</url>
</pluginRepository>
</pluginRepository>
<pluginRepository>
<pluginRepository>
<id>gluon-snapshots</id>
<id>gluon-snapshots</id>
<url>https://nexus.gluonhq.com/nexus/content/repositories/public-snapshots</url>
<url>https://nexus.gluonhq.com/nexus/content/repositories/public-snapshots</url>
</pluginRepository>
</pluginRepository>
<pluginRepository>
<pluginRepository>
<id>Sonatype</id>
<id>Sonatype</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</pluginRepository>
</pluginRepository>
</pluginRepositories>
</pluginRepositories>
<profiles>
<profiles>
<profile>
<profile>
<id>android</id>
<id>android</id>
<properties>
<properties>
<client.target>android</client.target>
<client.target>android</client.target>
<additional.native.client.args>-Dsvm.targetName=android</additional.native.client.args>
<additional.native.client.args>-Dsvm.targetName=android</additional.native.client.args>
</properties>
</properties>
</profile>
</profile>
<profile>
<profile>
<id>ios</id>
<id>ios</id>
<properties>
<properties>
<client.target>ios</client.target>
<client.target>ios</client.target>
<additional.native.client.args>-Dsvm.targetName=iOS</additional.native.client.args>
<additional.native.client.args>-Dsvm.targetName=iOS</additional.native.client.args>
</properties>
</properties>
</profile>
</profile>
<profile>
<profile>
<id>linux-aarch64</id>
<id>linux-aarch64</id>
<properties>
<properties>
<client.target>linux-aarch64</client.target>
<client.target>linux-aarch64</client.target>
<additional.native.client.args>-Dsvm.targetName=Linux</additional.native.client.args>
<additional.native.client.args>-Dsvm.targetName=Linux</additional.native.client.args>
</properties>
</properties>
</profile>
</profile>
<profile>
<profile>
<id>linux-x86_64</id>
<id>linux-x86_64</id>
<properties>
<properties>
<client.target>host</client.target>
<client.target>host</client.target>
<additional.native.client.args>-Dsvm.targetName=Linux</additional.native.client.args>
<additional.native.client.args>-Dsvm.targetName=Linux</additional.native.client.args>
</properties>
</properties>
</profile>
</profile>
<profile>
<profile>
<id>windows-x86_64</id>
<id>windows-x86_64</id>
<properties>
<properties>
<client.target>host</client.target>
<client.target>host</client.target>
<additional.native.client.args>-Dsvm.targetName=Linux</additional.native.client.args>
<additional.native.client.args>-Dsvm.targetName=Linux</additional.native.client.args>
</properties>
</properties>
</profile>
</profile>
<!--profile>
<!--profile>
<id>ARM-DRM</id>
<id>ARM-DRM</id>
<properties>
<properties>
<additional.javafx.plugin.options>
<additional.javafx.plugin.options>
<option>-Dmonocle.platform=EGL</option>
<option>-Dmonocle.platform=EGL</option>
<option>-Dembedded=monocle</option>
<option>-Dembedded=monocle</option>
<option>-Dglass.platform=Monocle</option>
<option>-Dglass.platform=Monocle</option>
<option>-Degl.displayid=${javafx.drm.display.card}</option>
<option>-Degl.displayid=${javafx.drm.display.card}</option>
<option>-Dmonocle.egl.lib=${javafx.drm.egl.lib.path}</option>
<option>-Dmonocle.egl.lib=${javafx.drm.egl.lib.path}</option>
<option>-Dprism.verbose=true</option>
<option>-Dprism.verbose=true</option>
</additional.javafx.plugin.options>
</additional.javafx.plugin.options>
</properties>
</properties>
</profile-->
</profile-->
<profile>
<profile>
<id>release</id>
<id>release</id>
<build>
<build>
<plugins>
<plugins>
<plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<version>2.2.1</version>
<executions>
<executions>
<execution>
<execution>
<id>attach-sources</id>
<id>attach-sources</id>
<goals>
<goals>
<goal>jar-no-fork</goal>
<goal>jar-no-fork</goal>
</goals>
</goals>
</execution>
</execution>
</executions>
</executions>
</plugin>
</plugin>
<plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${javadoc.plugin.version}</version>
<version>${javadoc.plugin.version}</version>
<executions>
<executions>
<execution>
<execution>
<id>attach-javadocs</id>
<id>attach-javadocs</id>
<goals>
<goals>
<goal>jar</goal>
<goal>jar</goal>
</goals>
</goals>
</execution>
</execution>
</executions>
</executions>
<configuration>
<configuration>
<source>8</source>
<source>8</source>
</configuration>
</configuration>
</plugin>
</plugin>
<plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<artifactId>maven-gpg-plugin</artifactId>
<version>${gpg.plugin.version}</version>
<version>${gpg.plugin.version}</version>
<executions>
<executions>
<execution>
<execution>
<id>sign-artifacts</id>
<id>sign-artifacts</id>
<phase>verify</phase>
<phase>verify</phase>
<goals>
<goals>
<goal>sign</goal>
<goal>sign</goal>
</goals>
</goals>
<configuration>
<configuration>
<gpgArguments>
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
<arg>loopback</arg>
</gpgArguments>
</gpgArguments>
</configuration>
</configuration>
</execution>
</execution>
</executions>
</executions>
</plugin>
</plugin>
</plugins>
</plugins>
</build>
</build>
</profile>
</profile>
</profiles>
</profiles>
<organization>
<organization>
<name>Stream Pi</name>
<name>Stream Pi</name>
<url>https://www.stream-pi.com</url>
<url>https://www.stream-pi.com</url>
</organization>
</organization>
<issueManagement>
<issueManagement>
<system>GitHub</system>
<system>GitHub</system>
<url>https://github.com/Stream-Pi/client/issues</url>
<url>https://github.com/Stream-Pi/client/issues</url>
</issueManagement>
</issueManagement>
<licenses>
<licenses>
<license>
<license>
<name>GPL-3.0 License</name>
<name>GPL-3.0 License</name>
<url>https://www.gnu.org/licenses/gpl-3.0.en.html</url>
<url>https://www.gnu.org/licenses/gpl-3.0.en.html</url>
<distribution>repo</distribution>
<distribution>repo</distribution>
</license>
</license>
</licenses>
</licenses>
<developers>
<developers>
<developer>
<developer>
<name>Debayan Sutradhar</name>
<name>Debayan Sutradhar</name>
<email>debayansutradhar3@gmail.com</email>
<email>debayansutradhar3@gmail.com</email>
<organization>Stream-Pi</organization>
<organization>Stream-Pi</organization>
<organizationUrl>https://www.stream-pi.com</organizationUrl>
<organizationUrl>https://www.stream-pi.com</organizationUrl>
</developer>
</developer>
<developer>
<developer>
<name>Abhinay Agarwal</name>
<name>Abhinay Agarwal</name>
<email>abhinay_agarwal@live.com</email>
<email>abhinay_agarwal@live.com</email>
<organization>Stream-Pi</organization>
<organization>Stream-Pi</organization>
<organizationUrl>https://www.stream-pi.com</organizationUrl>
<organizationUrl>https://www.stream-pi.com</organizationUrl>
</developer>
</developer>
</developers>
</developers>
<scm>
<scm>
<url>https://github.com/stream-pi/client</url>
<url>https://github.com/stream-pi/client</url>
<connection>scm:git:git://github.com/stream-pi/client.git</connection>
<connection>scm:git:git://github.com/stream-pi/client.git</connection>
<developerConnection>scm:git:ssh://git@github.com:stream-pi/client.git</developerConnection>
<developerConnection>scm:git:ssh://git@github.com:stream-pi/client.git</developerConnection>
</scm>
</scm>
<distributionManagement>
<distributionManagement>
<snapshotRepository>
<snapshotRepository>
<id>ossrh</id>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
</snapshotRepository>
<repository>
<repository>
<id>ossrh</id>
<id>ossrh</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</repository>
</distributionManagement>
</distributionManagement>
</project>
</project>
package com.stream_pi.client.controller;
package com.stream_pi.client.controller;
import com.gluonhq.attach.orientation.OrientationService;
import com.gluonhq.attach.vibration.VibrationService;
import com.gluonhq.attach.vibration.VibrationService;
import com.stream_pi.action_api.action.Action;
import com.stream_pi.action_api.action.Action;
import com.stream_pi.client.connection.Client;
import com.stream_pi.client.connection.Client;
import com.stream_pi.client.io.Config;
import com.stream_pi.client.io.Config;
import com.stream_pi.client.info.ClientInfo;
import com.stream_pi.client.info.ClientInfo;
import com.stream_pi.client.profile.ClientProfile;
import com.stream_pi.client.profile.ClientProfile;
import com.stream_pi.client.profile.ClientProfiles;
import com.stream_pi.client.profile.ClientProfiles;
import com.stream_pi.client.window.Base;
import com.stream_pi.client.window.Base;
import com.stream_pi.client.window.dashboard.actiongridpane.ActionBox;
import com.stream_pi.client.window.dashboard.actiongridpane.ActionBox;
import com.stream_pi.client.window.dashboard.actiongridpane.ActionGridPaneListener;
import com.stream_pi.client.window.dashboard.actiongridpane.ActionGridPaneListener;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlertListener;
import com.stream_pi.util.alert.StreamPiAlertListener;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.exception.SevereException;
import com.gluonhq.attach.lifecycle.LifecycleService;
import com.gluonhq.attach.lifecycle.LifecycleService;
import com.gluonhq.attach.util.Services;
import com.gluonhq.attach.util.Services;
import com.stream_pi.util.platform.PlatformType;
import com.stream_pi.util.platform.PlatformType;
import com.stream_pi.util.startatboot.StartAtBoot;
import com.stream_pi.util.startatboot.StartAtBoot;
import javafx.animation.Interpolator;
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Orientation;
import javafx.scene.Node;
import javafx.scene.Node;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyCombination;
import javafx.stage.Screen;
import javafx.util.Duration;
import javafx.util.Duration;
import java.io.*;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Level;
public class Controller extends Base
public class Controller extends Base
{
{
private Client client;
private Client client;
public Controller()
public Controller()
{
{
client = null;
client = null;
}
}
private boolean firstRun = true;
private boolean firstRun = true;
@Override
@Override
public void init()
public void init()
{
{
try
try
{
{
if(firstRun)
if(firstRun)
initBase();
initBase();
if(getClientInfo().getPlatform() != com.stream_pi.util.platform.Platform.ANDROID)
if(getClientInfo().getPlatform() != com.stream_pi.util.platform.Platform.ANDROID)
{
{
if(getConfig().isStartOnBoot())
if(getConfig().isStartOnBoot())
{
{
if(getClientInfo().isXMode() != getConfig().isStartupXMode())
if(getClientInfo().isXMode() != getConfig().isStartupXMode())
{
{
StartAtBoot startAtBoot = new StartAtBoot(PlatformType.CLIENT, ClientInfo.getInstance().getPlatform());
StartAtBoot startAtBoot = new StartAtBoot(PlatformType.CLIENT, ClientInfo.getInstance().getPlatform());
boolean result = startAtBoot.delete();
boolean result = startAtBoot.delete();
if(!result)
if(!result)
new StreamPiAlert("Uh Oh!", "Unable to delete the previous starter file.\n" +
new StreamPiAlert("Uh Oh!", "Unable to delete the previous starter file.\n" +
"This was probably because you ran Stream-Pi as root before. Restart stream pi as root, " +
"This was probably because you ran Stream-Pi as root before. Restart stream pi as root, " +
"delete the old starter file, then exit and restart Stream-Pi as normal user.", StreamPiAlertType.ERROR).show();
"delete the old starter file, then exit and restart Stream-Pi as normal user.", StreamPiAlertType.ERROR).show();
else
else
{
{
startAtBoot.create(new File(ClientInfo.getInstance().getRunnerFileName()),
startAtBoot.create(new File(ClientInfo.getInstance().getRunnerFileName()),
ClientInfo.getInstance().isXMode());
ClientInfo.getInstance().isXMode());
getConfig().setStartupIsXMode(ClientInfo.getInstance().isXMode());
getConfig().setStartupIsXMode(ClientInfo.getInstance().isXMode());
}
}
}
}
}
}
setupFlags();
setupFlags();
if(!getConfig().getIsFullScreenMode())
if(!getConfig().getIsFullScreenMode())
{
{
getStage().setWidth(getConfig().getStartupWindowWidth());
getStage().setWidth(getConfig().getStartupWindowWidth());
getStage().setHeight(getConfig().getStartupWindowHeight());
getStage().setHeight(getConfig().getStartupWindowHeight());
getStage().centerOnScreen();
getStage().centerOnScreen();
}
}
}
}
applyDefaultTheme();
applyDefaultTheme();
setupDashWindow();
setupDashWindow();
getStage().show();
getStage().show();
requestFocus();
requestFocus();
if(Config.getInstance().isFirstTimeUse())
if(Config.getInstance().isFirstTimeUse())
return;
return;
setupSettingsWindowsAnimations();
setupSettingsWindowsAnimations();
getDashboardPane().getSettingsButton().setOnAction(event -> {
getDashboardPane().getSettingsButton().setOnAction(event -> {
openSettingsTimeLine.play();
openSettingsTimeLine.play();
});
});
getSettingsPane().getCloseButton().setOnAction(event -> {
getSettingsPane().getCloseButton().setOnAction(event -> {
closeSettingsTimeLine.play();
closeSettingsTimeLine.play();
});
});
setClientProfiles(new ClientProfiles(new File(getConfig().getProfilesPath()), getConfig().getStartupProfileID()));
setClientProfiles(new ClientProfiles(new File(getConfig().getProfilesPath()), getConfig().getStartupProfileID()));
if(getClientProfiles().getLoadingErrors().size() > 0)
if(getClientProfiles().getLoadingErrors().size() > 0)
{
{
StringBuilder errors = new StringBuilder("Please rectify the following errors and try again");
StringBuilder errors = new StringBuilder("Please rectify the following errors and try again");
for(MinorException exception : getClientProfiles().getLoadingErrors())
for(MinorException exception : getClientProfiles().getLoadingErrors())
{
{
errors.append("\n * ")
errors.append("\n * ")
.append(exception.getMessage());
.append(exception.getMessage());
}
}
throw new MinorException("Profiles", errors.toString());
throw new MinorException("Profiles", errors.toString());
}
}
renderRootDefaultProfile();
renderRootDefaultProfile();
loadSettings();
loadSettings();
if(firstRun)
if(firstRun)
{
{
if(getConfig().isConnectOnStartup())
if(getConfig().isConnectOnStartup())
{
{
setupClientConnection();
setupClientConnection();
}
}
firstRun = false;
firstRun = false;
}
}
if(!getClientInfo().isPhone())
ChangeListener<Number> windowResizeListener = (observableValue, number, t1) -> {
{
if(isConnected())
getStage().widthProperty().addListener((observableValue, orientation, t1) -> syncClientSizeDetailsWithServer());
{
getStage().heightProperty().addListener((observableValue, orientation, t1) -> syncClientSizeDetailsWithServer());
try {
}
client.sendClientScreenDetails();
} catch (SevereException e) {
e.printStackTrace();
}
}
};
getStage().widthProperty().addListener(windowResizeListener);
getStage().heightProperty().addListener(windowResizeListener);
}
}
catch (SevereException e)
catch (SevereException e)
{
{
handleSevereException(e);
handleSevereException(e);
}
}
catch (MinorException e)
catch (MinorException e)
{
{
handleMinorException(e);
handleMinorException(e);
}
}
}
}
public void syncClientSizeDetailsWithServer()
{
if(isConnected())
{
try {
client.sendClientScreenDetails();
} catch (SevereException e) {
e.printStackTrace();
}
}
}
@Override
@Override
public void setupClientConnection()
public void setupClientConnection()
{
{
setupClientConnection(null);
setupClientConnection(null);
}
}
@Override
@Override
public void setupClientConnection(Runnable onConnect)
public void setupClientConnection(Runnable onConnect)
{
{
if(getSettingsPane().getConnectDisconnectButton().isDisabled()) //probably already connecting
if(getSettingsPane().getConnectDisconnectButton().isDisabled()) //probably already connecting
return;
return;
Platform.runLater(()->getSettingsPane().setDisableStatus(true));
Platform.runLater(()->getSettingsPane().setDisableStatus(true));
client = new Client(getConfig().getSavedServerHostNameOrIP(), getConfig().getSavedServerPort(), this, this, onConnect);
client = new Client(getConfig().getSavedServerHostNameOrIP(), getConfig().getSavedServerPort(), this, this, onConnect);
}
}
@Override
@Override
public void updateSettingsConnectDisconnectButton() {
public void updateSettingsConnectDisconnectButton() {
getSettingsPane().setConnectDisconnectButtonStatus();
getSettingsPane().setConnectDisconnectButtonStatus();
}
}
@Override
@Override
public void disconnect(String message) throws SevereException {
public void disconnect(String message) throws SevereException {
client.disconnect(message);
client.disconnect(message);
}
}
public void setupDashWindow()
public void setupDashWindow()
{
{
getStage().setTitle("Stream-Pi Client");
getStage().setTitle("Stream-Pi Client");
getStage().setOnCloseRequest(e->onCloseRequest());
getStage().setOnCloseRequest(e->onCloseRequest());
}
}
@Override
@Override
public void onCloseRequest()
public void onCloseRequest()
{
{
try
try
{
{
if(isConnected())
if(isConnected())
client.exit();
client.exit();
getConfig().setStartupWindowSize(getStageWidth(), getStageHeight());
getConfig().setStartupWindowSize(getStageWidth(), getStageHeight());
getConfig().save();
getConfig().save();
}
}
catch (SevereException e)
catch (SevereException e)
{
{
handleSevereException(e);
handleSevereException(e);
}
}
finally
finally
{
{
getLogger().info("Shut down");
getLogger().info("Shut down");
closeLogger();
closeLogger();
if (ClientInfo.getInstance().getPlatform() == com.stream_pi.util.platform.Platform.ANDROID)
if (ClientInfo.getInstance().getPlatform() == com.stream_pi.util.platform.Platform.ANDROID)
Services.get(LifecycleService.class).ifPresent(LifecycleService::shutdown);
Services.get(LifecycleService.class).ifPresent(LifecycleService::shutdown);
}
}
}
}
@Override
@Override
public void loadSettings() {
public void loadSettings() {
try {
try {
getSettingsPane().loadData();
getSettingsPane().loadData();
} catch (SevereException e) {
} catch (SevereException e) {
e.printStackTrace();
e.printStackTrace();
handleSevereException(e);
handleSevereException(e);
}
}
}
}
@Override
@Override
public Client getClient() {
public Client getClient() {
return client;
return client;
}
}
@Override
@Override
public void onDisconnect() {
public void onDisconnect() {
Platform.runLater(()->getDashboardPane().getActionGridPane().toggleOffAllToggleActions());
Platform.runLater(()->getDashboardPane().getActionGridPane().toggleOffAllToggleActions());
}
}
@Override
@Override
public boolean getToggleStatus(String profileID, String actionID)
public boolean getToggleStatus(String profileID, String actionID)
{
{
return getClientProfiles().getProfileFromID(profileID).getActionFromID(actionID).getCurrentToggleStatus();
return getClientProfiles().getProfileFromID(profileID).getActionFromID(actionID).getCurrentToggleStatus();
}
}
private Timeline openSettingsTimeLine;
private Timeline openSettingsTimeLine;
private Timeline closeSettingsTimeLine;
private Timeline closeSettingsTimeLine;
private void setupSettingsWindowsAnimations()
private void setupSettingsWindowsAnimations()
{
{
Node settingsNode = getSettingsPane();
Node settingsNode = getSettingsPane();
Node dashboardNode = getDashboardPane();
Node dashboardNode = getDashboardPane();
openSettingsTimeLine = new Timeline();
openSettingsTimeLine = new Timeline();
openSettingsTimeLine.setCycleCount(1);
openSettingsTimeLine.setCycleCount(1);
openSettingsTimeLine.getKeyFrames().addAll(
openSettingsTimeLine.getKeyFrames().addAll(
new KeyFrame(Duration.millis(0.0D),
new KeyFrame(Duration.millis(0.0D),
new KeyValue(settingsNode.opacityProperty(),
new KeyValue(settingsNode.opacityProperty(),
0.0D, Interpolator.EASE_IN)),
0.0D, Interpolator.EASE_IN)),
new KeyFrame(Duration.millis(90.0D),
new KeyFrame(Duration.millis(90.0D),
new KeyValue(settingsNode.opacityProperty(),
new KeyValue(settingsNode.opacityProperty(),
1.0D, Interpolator.LINEAR)),
1.0D, Interpolator.LINEAR)),
new KeyFrame(Duration.millis(0.0D),
new KeyFrame(Duration.millis(0.0D),
new KeyValue(dashboardNode.opacityProperty(),
new KeyValue(dashboardNode.opacityProperty(),
1.0D, Interpolator.LINEAR)),
1.0D, Interpolator.LINEAR)),
new KeyFrame(Duration.millis(90.0D),
new KeyFrame(Duration.millis(90.0D),
new KeyValue(dashboardNode.opacityProperty(),
new KeyValue(dashboardNode.opacityProperty(),
0.0D, Interpolator.LINEAR))
0.0D, Interpolator.LINEAR))
);
);
openSettingsTimeLine.setOnFinished(event1 -> settingsNode.toFront());
openSettingsTimeLine.setOnFinished(event1 -> settingsNode.toFront());
closeSettingsTimeLine = new Timeline();
closeSettingsTimeLine = new Timeline();
closeSettingsTimeLine.setCycleCount(1);
closeSettingsTimeLine.setCycleCount(1);
closeSettingsTimeLine.getKeyFrames().addAll(
closeSettingsTimeLine.getKeyFrames().addAll(
new KeyFrame(Duration.millis(0.0D),
new KeyFrame(Duration.millis(0.0D),
new KeyValue(settingsNode.opacityProperty(),
new KeyValue(settingsNode.opacityProperty(),
1.0D, Interpolator.LINEAR)),
1.0D, Interpolator.LINEAR)),
new KeyFrame(Duration.millis(90.0D),
new KeyFrame(Duration.millis(90.0D),
new KeyValue(settingsNode.opacityProperty(),
new KeyValue(settingsNode.opacityProperty(),
0.0D, Interpolator.LINEAR)),
0.0D, Interpolator.LINEAR)),
new KeyFrame(Duration.millis(0.0D),
new KeyFrame(Duration.millis(0.0D),
new KeyValue(dashboardNode.opacityProperty(),
new KeyValue(dashboardNode.opacityProperty(),
0.0D, Interpolator.LINEAR)),
0.0D, Interpolator.LINEAR)),
new KeyFrame(Duration.millis(90.0D),
new KeyFrame(Duration.millis(90.0D),
new KeyValue(dashboardNode.opacityProperty(),
new KeyValue(dashboardNode.opacityProperty(),
1.0D, Interpolator.LINEAR))
1.0D, Interpolator.LINEAR))
);
);
closeSettingsTimeLine.setOnFinished(event1 -> {
closeSettingsTimeLine.setOnFinished(event1 -> {
dashboardNode.toFront();
dashboardNode.toFront();
Platform.runLater(()-> {
Platform.runLater(()-> {
try {
try {
getSettingsPane().loadData();
getSettingsPane().loadData();
} catch (SevereException e) {
} catch (SevereException e) {
e.printStackTrace();
e.printStackTrace();
handleSevereException(e);
handleSevereException(e);
}
}
});
});
});
});
}
}
@Override
@Override
public void handleMinorException(MinorException e)
public void handleMinorException(MinorException e)
{
{
getLogger().log(Level.SEVERE, e.getMessage(), e);
getLogger().log(Level.SEVERE, e.getMessage(), e);
e.printStackTrace();
e.printStackTrace();
Platform.runLater(()-> genNewAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.WARNING).show());
Platform.runLater(()-> genNewAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.WARNING).show());
}
}
@Override
@Override
public void handleSevereException(SevereException e)
public void handleSevereException(SevereException e)
{
{
getLogger().log(Level.SEVERE, e.getMessage(), e);
getLogger().log(Level.SEVERE, e.getMessage(), e);
e.printStackTrace();
e.printStackTrace();
Platform.runLater(()->
Platform.runLater(()->
{
{
StreamPiAlert alert = genNewAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.ERROR);
StreamPiAlert alert = genNewAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.ERROR);
alert.setOnClicked(new StreamPiAlertListener()
alert.setOnClicked(new StreamPiAlertListener()
{
{
@Override
@Override
public void onClick(String txt)
public void onClick(String txt)
{
{
onCloseRequest();
onCloseRequest();
Platform.exit();
Platform.exit();
}
}
});
});
alert.show();
alert.show();
});
});
}
}
@Override
@Override
public void onAlert(String title, String body, StreamPiAlertType alertType) {
public void onAlert(String title, String body, StreamPiAlertType alertType) {
Platform.runLater(()-> genNewAlert(title, body, alertType).show());
Platform.runLater(()-> genNewAlert(title, body, alertType).show());
}
}
public StreamPiAlert genNewAlert(String title, String message, StreamPiAlertType alertType)
public StreamPiAlert genNewAlert(String title, String message, StreamPiAlertType alertType)
{
{
StreamPiAlert alert = new StreamPiAlert(title, message, alertType);
StreamPiAlert alert = new StreamPiAlert(title, message, alertType);
return alert;
return alert;
}
}
private boolean isConnected = false;
private boolean isConnected = false;
@Override
@Override
public void onActionFailed(String profileID, String actionID) {
public void onActionFailed(String profileID, String actionID) {
Platform.runLater(()-> getDashboardPane().getActionGridPane().actionFailed(profileID, actionID));
Platform.runLater(()-> getDashboardPane().getActionGridPane().actionFailed(profileID, actionID));
}
}
@Override
@Override
public void onActionClicked(String profileID, String actionID, boolean toggleState)
public void onActionClicked(String profileID, String actionID, boolean toggleState)
{
{
try {
try {
vibratePhone();
vibratePhone();
client.onActionClicked(profileID, actionID, toggleState);
client.onActionClicked(profileID, actionID, toggleState);
} catch (SevereException e) {
} catch (SevereException e) {
e.printStackTrace();
e.printStackTrace();
handleSevereException(e);
handleSevereException(e);
}
}
}
}
public void vibratePhone()
public void vibratePhone()
{
{
if(getConfig().isVibrateOnActionClicked())
if(getConfig().isVibrateOnActionClicked())
{
{
VibrationService.create().ifPresent(VibrationService::vibrate);
VibrationService.create().ifPresent(VibrationService::vibrate);
}
}
}
}
@Override
@Override
public void setConnected(boolean isConnected) {
public void setConnected(boolean isConnected) {
this.isConnected = isConnected;
this.isConnected = isConnected;
}
}
@Override
@Override
public ActionBox getActionBox(int col, int row)
public ActionBox getActionBox(int col, int row)
{
{
return getDashboardPane().getActionGridPane().getActionBox(col, row);
return getDashboardPane().getActionGridPane().getActionBox(col, row);
}
}
@Override
@Override
public boolean isConnected()
public boolean isConnected()
{
{
return isConnected;
return isConnected;
}
}
@Override
@Override
public void renderProfile(ClientProfile clientProfile, boolean freshRender)
public void renderProfile(ClientProfile clientProfile, boolean freshRender)
{
{
getDashboardPane().renderProfile(clientProfile, freshRender);
getDashboardPane().renderProfile(clientProfile, freshRender);
}
}
@Override
@Override
public void clearActionBox(int col, int row)
public void clearActionBox(int col, int row)
{
{
Platform.runLater(()->getDashboardPane().getActionGridPane().clearActionBox(col, row));
Platform.runLater(()->getDashboardPane().getActionGridPane().clearActionBox(col, row));
}
}
@Override
@Override
public void addBlankActionBox(int col, int row)
public void addBlankActionBox(int col, int row)
{
{
Platform.runLater(()->getDashboardPane().getActionGridPane().addBlankActionBox(col, row));
Platform.runLater(()->getDashboardPane().getActionGridPane().addBlankActionBox(col, row));
}
}
@Override
@Override
public void renderAction(String currentProfileID, Action action)
public void renderAction(String currentProfileID, Action action)
{
{
Platform.runLater(()->{
Platform.runLater(()->{
try {
try {
if(getDashboardPane().getActionGridPane().getCurrentParent().equals(action.getParent()) &&
if(getDashboardPane().getActionGridPane().getCurrentParent().equals(action.getParent()) &&
getCurrentProfile().getID().equals(currentProfileID))
getCurrentProfile().getID().equals(currentProfileID))
{
{
getDashboardPane().getActionGridPane().renderAction(action);
getDashboardPane().getActionGridPane().renderAction(action);
}
}
}
}
catch (Exception e)
catch (Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
}
}
});
});
}
}
@Override
@Override
public void refreshGridIfCurrentProfile(String profileID) {
public void refreshGridIfCurrentProfile(String profileID) {
if(getCurrentProfile().getID().equals(profileID))
if(getCurrentProfile().getID().equals(profileID))
{
{
Platform.runLater(()-> getDashboardPane().renderProfile(getClientProfiles().getProfileFromID(profileID), true));
Platform.runLater(()-> getDashboardPane().renderProfile(getClientProfiles().getProfileFromID(profileID), true));
}
}
}
}
@Override
@Override
public ClientProfile getCurrentProfile() {
public ClientProfile getCurrentProfile() {
return getDashboardPane().getActionGridPane().getClientProfile();
return getDashboardPane().getActionGridPane().getClientProfile();
}
}
@Override
@Override
public String getCurrentParent()
public String getCurrentParent()
{
{
return getDashboardPane().getActionGridPane().getCurrentParent();
return getDashboardPane().getActionGridPane().getCurrentParent();
}
}
@Override
@Override
public ActionBox getActionBoxByProfileAndID(String profileID, String actionID)
public ActionBox getActionBoxByProfileAndID(String profileID, String actionID)
{
{
Action action = getClientProfiles().getProfileFromID(profileID).getActionFromID(actionID);
Action action = getClientProfiles().getProfileFromID(profileID).getActionFromID(actionID);
if(!getCurrentProfile().getID().equals(profileID) && !getCurrentParent().equals(action.getParent()))
if(!getCurrentProfile().getID().equals(profileID) && !getCurrentParent().equals(action.getParent()))
return null;
return null;
return getDashboardPane().getActionGridPane().getActionBoxByLocation(action.getLocation());
return getDashboardPane().getActionGridPane().getActionBoxByLocation(action.getLocation());
}
}
}
}
package com.stream_pi.client.window;
package com.stream_pi.client.window;
import com.stream_pi.client.connection.ClientListener;
import com.stream_pi.client.connection.ClientListener;
import com.stream_pi.client.io.Config;
import com.stream_pi.client.io.Config;
import com.stream_pi.client.info.ClientInfo;
import com.stream_pi.client.info.ClientInfo;
import java.io.File;
import java.io.File;
import java.util.Objects;
import java.util.Objects;
import java.util.logging.Logger;
import java.util.logging.Logger;
import com.stream_pi.client.Main;
import com.stream_pi.client.Main;
import com.stream_pi.client.profile.ClientProfiles;
import com.stream_pi.client.profile.ClientProfiles;
import com.stream_pi.client.window.dashboard.DashboardBase;
import com.stream_pi.client.window.dashboard.DashboardBase;
import com.stream_pi.client.window.firsttimeuse.FirstTimeUse;
import com.stream_pi.client.window.firsttimeuse.FirstTimeUse;
import com.stream_pi.client.window.settings.SettingsBase;
import com.stream_pi.client.window.settings.SettingsBase;
import com.stream_pi.theme_api.Theme;
import com.stream_pi.theme_api.Theme;
import com.stream_pi.theme_api.Themes;
import com.stream_pi.theme_api.Themes;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.combobox.StreamPiComboBox;
import com.stream_pi.util.combobox.StreamPiComboBox;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.iohelper.IOHelper;
import com.stream_pi.util.iohelper.IOHelper;
import com.stream_pi.util.loggerhelper.StreamPiLogFallbackHandler;
import com.stream_pi.util.loggerhelper.StreamPiLogFallbackHandler;
import com.stream_pi.util.loggerhelper.StreamPiLogFileHandler;
import com.stream_pi.util.loggerhelper.StreamPiLogFileHandler;
import com.stream_pi.util.platform.Platform;
import com.stream_pi.util.platform.Platform;
import javafx.application.HostServices;
import javafx.application.HostServices;
import javafx.geometry.Insets;
import javafx.geometry.Insets;
import javafx.scene.CacheHint;
import javafx.scene.CacheHint;
import javafx.scene.Cursor;
import javafx.scene.Cursor;
import javafx.scene.image.Image;
import javafx.scene.image.Image;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Font;
import javafx.scene.text.Font;
import javafx.stage.Screen;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.Stage;
public abstract class Base extends StackPane implements ExceptionAndAlertHandler, ClientListener {
public abstract class Base extends StackPane implements ExceptionAndAlertHandler, ClientListener {
private Config config;
private Config config;
private ClientProfiles clientProfiles;
private ClientProfiles clientProfiles;
private ClientInfo clientInfo;
private ClientInfo clientInfo;
private Stage stage;
private Stage stage;
public Stage getStage()
public Stage getStage()
{
{
return stage;
return stage;
}
}
public Logger getLogger()
public Logger getLogger()
{
{
return logger;
return logger;
}
}
private DashboardBase dashboardBase;
private DashboardBase dashboardBase;
private SettingsBase settingsBase;
private SettingsBase settingsBase;
private FirstTimeUse firstTimeUse;
private FirstTimeUse firstTimeUse;
public FirstTimeUse getFirstTimeUse() {
public FirstTimeUse getFirstTimeUse() {
return firstTimeUse;
return firstTimeUse;
}
}
private StackPane alertStackPane;
private StackPane alertStackPane;
@Override
@Override
public ClientProfiles getClientProfiles() {
public ClientProfiles getClientProfiles() {
return clientProfiles;
return clientProfiles;
}
}
public void setClientProfiles(ClientProfiles clientProfiles) {
public void setClientProfiles(ClientProfiles clientProfiles) {
this.clientProfiles = clientProfiles;
this.clientProfiles = clientProfiles;
}
}
private Logger logger = null;
private Logger logger = null;
private StreamPiLogFileHandler logFileHandler = null;
private StreamPiLogFileHandler logFileHandler = null;
private StreamPiLogFallbackHandler logFallbackHandler = null;
private StreamPiLogFallbackHandler logFallbackHandler = null;
@Override
@Override
public void initLogger()
public void initLogger()
{
{
try
try
{
{
if(logFileHandler != null)
if(logFileHandler != null)
return;
return;
closeLogger();
closeLogger();
logger = Logger.getLogger("");
logger = Logger.getLogger("");
if(new File(ClientInfo.getInstance().getPrePath()).getAbsoluteFile().getParentFile().canWrite())
if(new File(ClientInfo.getInstance().getPrePath()).getAbsoluteFile().getParentFile().canWrite())
{
{
String path = ClientInfo.getInstance().getPrePath()+"../stream-pi-client.log";
String path = ClientInfo.getInstance().getPrePath()+"../stream-pi-client.log";
Platform platform = getClientInfo().getPlatform();
Platform platform = getClientInfo().getPlatform();
if(platform == Platform.ANDROID ||
if(platform == Platform.ANDROID ||
platform == Platform.IOS)
platform == Platform.IOS)
path = ClientInfo.getInstance().getPrePath()+"stream-pi-client.log";
path = ClientInfo.getInstance().getPrePath()+"stream-pi-client.log";
logFileHandler = new StreamPiLogFileHandler(path);
logFileHandler = new StreamPiLogFileHandler(path);
logger.addHandler(logFileHandler);
logger.addHandler(logFileHandler);
}
}
else
else
{
{
logFallbackHandler = new StreamPiLogFallbackHandler();
logFallbackHandler = new StreamPiLogFallbackHandler();
logger.addHandler(logFallbackHandler);
logger.addHandler(logFallbackHandler);
}
}
}
}
catch(Exception e)
catch(Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
logFallbackHandler = new StreamPiLogFallbackHandler();
logFallbackHandler = new StreamPiLogFallbackHandler();
logger.addHandler(logFallbackHandler);
logger.addHandler(logFallbackHandler);
}
}
}
}
public void closeLogger()
public void closeLogger()
{
{
if(logFileHandler != null)
if(logFileHandler != null)
logFileHandler.close();
logFileHandler.close();
else if(logFallbackHandler != null)
else if(logFallbackHandler != null)
logFallbackHandler.close();
logFallbackHandler.close();
}
}
private HostServices hostServices;
private HostServices hostServices;
public void setHostServices(HostServices hostServices)
public void setHostServices(HostServices hostServices)
{
{
this.hostServices = hostServices;
this.hostServices = hostServices;
}
}
public HostServices getHostServices()
public HostServices getHostServices()
{
{
return hostServices;
return hostServices;
}
}
public void initBase() throws SevereException
public void initBase() throws SevereException
{
{
stage = (Stage) getScene().getWindow();
stage = (Stage) getScene().getWindow();
getStage().getIcons().add(new Image(Main.class.getResourceAsStream("app_icon.png")));
getStage().getIcons().add(new Image(Main.class.getResourceAsStream("app_icon.png")));
clientInfo = ClientInfo.getInstance();
clientInfo = ClientInfo.getInstance();
dashboardBase = new DashboardBase(this, this);
dashboardBase = new DashboardBase(this, this);
dashboardBase.prefWidthProperty().bind(widthProperty());
dashboardBase.prefWidthProperty().bind(widthProperty());
dashboardBase.prefHeightProperty().bind(heightProperty());
dashboardBase.prefHeightProperty().bind(heightProperty());
settingsBase = new SettingsBase(this, this, getHostServices());
settingsBase = new SettingsBase(this, this, getHostServices());
alertStackPane = new StackPane();
alertStackPane = new StackPane();
alertStackPane.setPadding(new Insets(10));
alertStackPane.setPadding(new Insets(10));
alertStackPane.setVisible(false);
alertStackPane.setVisible(false);
StreamPiAlert.setParent(alertStackPane);
StreamPiAlert.setParent(alertStackPane);
StreamPiComboBox.setParent(alertStackPane);
StreamPiComboBox.setParent(alertStackPane);
firstTimeUse = new FirstTimeUse(this, this);
firstTimeUse = new FirstTimeUse(this, this);
getChildren().clear();
getChildren().clear();
getChildren().addAll(alertStackPane);
getChildren().addAll(alertStackPane);
if(getClientInfo().isPhone())
if(getClientInfo().isPhone())
{
{
dashboardBase.setPadding(new Insets(10));
dashboardBase.setPadding(new Insets(10));
settingsBase.setPadding(new Insets(10));
settingsBase.setPadding(new Insets(10));
}
}
initLogger();
initLogger();
checkPrePathDirectory();
checkPrePathDirectory();
getChildren().addAll(settingsBase, dashboardBase);
getChildren().addAll(settingsBase, dashboardBase);
setStyle(null);
setStyle(null);
config = Config.getInstance();
config = Config.getInstance();
if(config.isFirstTimeUse())
if(config.isFirstTimeUse())
{
{
clearStylesheets();
clearStylesheets();
applyDefaultStylesheet();
applyDefaultStylesheet();
applyDefaultIconsStylesheet();
applyDefaultIconsStylesheet();
getChildren().add(firstTimeUse);
getChildren().add(firstTimeUse);
if(getClientInfo().isPhone())
if(getClientInfo().isPhone())
{
{
System.out.println("FELLOW ANDROID ENJOYER :D");
firstTimeUse.setPadding(new Insets(10));
firstTimeUse.setPadding(new Insets(10));
}
}
firstTimeUse.toFront();
firstTimeUse.toFront();
//resolution check
//resolution check
resizeAccordingToResolution();
resizeAccordingToResolution();
}
}
else
else
{
{
dashboardBase.toFront();
dashboardBase.toFront();
}
}
initThemes();
initThemes();
}
}
private void resizeAccordingToResolution()
private void resizeAccordingToResolution()
{
{
if(!getClientInfo().isPhone())
if(!getClientInfo().isPhone())
{
{
double height = getScreenHeight();
double height = getScreenHeight();
double width = getScreenWidth();
double width = getScreenWidth();
logger.info("HEIGHT: "+height+", WIDTH: "+width);
if(height < 500)
if(height < 500)
setPrefHeight(320);
setPrefHeight(320);
if(width < 500)
if(width < 500)
setPrefWidth(240);
setPrefWidth(240);
}
}
}
}
@Override
@Override
public double getStageWidth()
public double getStageWidth()
{
{
if(getClientInfo().isPhone())
if(getClientInfo().isPhone())
{
{
return getScreenWidth();
return getScreenWidth();
}
}
else
else
{
{
return getStage().getWidth();
return getStage().getWidth();
}
}
}
}
public double getScreenWidth()
public double getScreenWidth()
{
{
return Screen.getPrimary().getBounds().getWidth();
return Screen.getPrimary().getBounds().getWidth();
}
}
@Override
@Override
public double getStageHeight()
public double getStageHeight()
{
{
if(ClientInfo.getInstance().getPlatform() == Platform.ANDROID)
if(ClientInfo.getInstance().getPlatform() == Platform.ANDROID)
{
{
return getScreenHeight();
return getScreenHeight();
}
}
else
else
{
{
return getStage().getHeight();
return getStage().getHeight();
}
}
}
}
public double getScreenHeight()
public double getScreenHeight()
{
{
return Screen.getPrimary().getBounds().getHeight();
return Screen.getPrimary().getBounds().getHeight();
}
}
private void checkPrePathDirectory() throws SevereException
private void checkPrePathDirectory() throws SevereException
{
{
try
try
{
{
String path = getClientInfo().getPrePath();
String path = getClientInfo().getPrePath();
System.out.println("PAAAAAAAAAAAATH : '"+path+"'");
System.out.println("PAAAAAAAAAAAATH : '"+path+"'");
if(path == null)
if(path == null)
{
{
throwStoragePermErrorAlert("Unable to access file system!");
throwStoragePermErrorAlert("Unable to access file system!");
return;
return;
}
}
File file = new File(path);
File file = new File(path);
if(!file.exists())
if(!file.exists())
{
{
boolean result = file.mkdirs();
boolean result = file.mkdirs();
if(result)
if(result)
{
{
Config.unzipToDefaultPrePath();
Config.unzipToDefaultPrePath();
initLogger();
initLogger();
}
}
else
else
{
{
throwStoragePermErrorAlert("No storage permission. Give it!");
throwStoragePermErrorAlert("No storage permission. Give it!");
}
}
}
}
}
}
catch (Exception e)
catch (Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
throw new SevereException(e.getMessage());
throw new SevereException(e.getMessage());
}
}
}
}
private void throwStoragePermErrorAlert(String msg) throws SevereException
private void throwStoragePermErrorAlert(String msg) throws SevereException
{
{
resizeAccordingToResolution();
resizeAccordingToResolution();
clearStylesheets();
clearStylesheets();
applyDefaultStylesheet();
applyDefaultStylesheet();
applyDefaultIconsStylesheet();
applyDefaultIconsStylesheet();
getStage().show();
getStage().show();
throw new SevereException(msg);
throw new SevereException(msg);
}
}
public void setupFlags()
public void setupFlags()
{
{
//Full Screen
//Full Screen
if(getConfig().getIsFullScreenMode())
if(getConfig().getIsFullScreenMode())
{
{
getStage().setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
getStage().setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
getStage().setFullScreen(true);
getStage().setFullScreen(true);
}
}
else
else
{
{
getStage().setFullScreenExitKeyCombination(KeyCombination.keyCombination("ESC"));
getStage().setFullScreenExitKeyCombination(KeyCombination.keyCombination("ESC"));
getStage().setFullScreen(false);
getStage().setFullScreen(false);
}
}
//Cursor
//Cursor
if(getConfig().isShowCursor())
if(getConfig().isShowCursor())
{
{
setCursor(Cursor.DEFAULT);
setCursor(Cursor.DEFAULT);
}
}
else
else
{
{
setCursor(Cursor.NONE);
setCursor(Cursor.NONE);
}
}
}
}
public SettingsBase getSettingsPane() {
public SettingsBase getSettingsPane() {
return settingsBase;
return settingsBase;
}
}
public DashboardBase getDashboardPane() {
public DashboardBase getDashboardPane() {
return dashboardBase;
return dashboardBase;
}
}
public void renderRootDefaultProfile()
public void renderRootDefaultProfile()
{
{
getDashboardPane().renderProfile(getClientProfiles().getProfileFromID(
getDashboardPane().renderProfile(getClientProfiles().getProfileFromID(
getConfig().getStartupProfileID()
getConfig().getStartupProfileID()
), true);
), true);
}
}
public void clearStylesheets()
public void clearStylesheets()
{
{
getStylesheets().clear();
getStylesheets().clear();
}
}
public void applyDefaultStylesheet()
public void applyDefaultStylesheet()
{
{
Font.loadFont(Main.class.getResourceAsStream("Roboto.ttf"), 13);
Font.loadFont(Main.class.getResourceAsStream("Roboto.ttf"), 13);
getStylesheets().add(Main.class.getResource("style.css").toExternalForm());
getStylesheets().add(Main.class.getResource("style.css").toExternalForm());
}
}
public void applyDefaultIconsStylesheet()
public void applyDefaultIconsStylesheet()
{
{
Font.loadFont(Main.class.getResourceAsStream("Roboto.ttf"), 13);
Font.loadFont(Main.class.getResourceAsStream("Roboto.ttf"), 13);
getStylesheets().add(Main.class.getResource("default_icons.css").toExternalForm());
getStylesheets().add(Main.class.getResource("default_icons.css").toExternalForm());
}
}
public Config getConfig()
public Config getConfig()
{
{
return config;
return config;
}
}
public ClientInfo getClientInfo()
public ClientInfo getClientInfo()
{
{
return clientInfo;
return clientInfo;
}
}
private Theme currentTheme;
private Theme currentTheme;
@Override
@Override
public Theme getCurrentTheme()
public Theme getCurrentTheme()
{
{
return currentTheme;
return currentTheme;
}
}
public void applyTheme(Theme t)
public void applyTheme(Theme t)
{
{
logger.info("Applying theme '"+t.getFullName()+"' ...");
logger.info("Applying theme '"+t.getFullName()+"' ...");
if(t.getFonts() != null)
if(t.getFonts() != null)
{
{
for(String fontFile : t.getFonts())
for(String fontFile : t.getFonts())
{
{
Font.loadFont(fontFile.replace("%20",""), 13);
Font.loadFont(fontFile.replace("%20",""), 13);
}
}
}
}
currentTheme = t;
currentTheme = t;
clearStylesheets();
clearStylesheets();
applyDefaultStylesheet();
applyDefaultStylesheet();
getStylesheets().addAll(t.getStylesheets());
getStylesheets().addAll(t.getStylesheets());
applyDefaultIconsStylesheet();
applyDefaultIconsStylesheet();
logger.info("... Done!");
logger.info("... Done!");
}
}
Themes themes;
Themes themes;
public void initThemes() throws SevereException
public void initThemes() throws SevereException
{
{
logger.info("Loading themes ...");
logger.info("Loading themes ...");
themes = new Themes(getConfig().getThemesPath(), getConfig().getCurrentThemeFullName(), clientInfo.getMinThemeSupportVersion());
themes = new Themes(getConfig().getThemesPath(), getConfig().getCurrentThemeFullName(), clientInfo.getMinThemeSupportVersion());
if(themes.getErrors().size()>0)
if(themes.getErrors().size()>0)
{
{
StringBuilder themeErrors = new StringBuilder();
StringBuilder themeErrors = new StringBuilder();
for(MinorException eachException : themes.getErrors())
for(MinorException eachException : themes.getErrors())
{
{
themeErrors.append("\n * ").append(eachException.getShortMessage());
themeErrors.append("\n * ").append(eachException.getShortMessage());
}
}
if(themes.getIsBadThemeTheCurrentOne())
if(themes.getIsBadThemeTheCurrentOne())
{
{
themeErrors.append("\n\nReverted to default theme! (").append(getConfig().getDefaultCurrentThemeFullName()).append(")");
themeErrors.append("\n\nReverted to default theme! (").append(getConfig().getDefaultCurrentThemeFullName()).append(")");
getConfig().setCurrentThemeFullName(getConfig().getDefaultCurrentThemeFullName());
getConfig().setCurrentThemeFullName(getConfig().getDefaultCurrentThemeFullName());
getConfig().save();
getConfig().save();
}
}
handleMinorException(new MinorException("Theme Loading issues", themeErrors.toString()));
handleMinorException(new MinorException("Theme Loading issues", themeErrors.toString()));
}
}
logger.info("... Done!");
logger.info("... Done!");
}
}
@Override
@Override
public Themes getThemes() {
public Themes getThemes() {
return themes;
return themes;
}
}
public void applyDefaultTheme()
public void applyDefaultTheme()
{
{
logger.info("Applying default theme ...");
logger.info("Applying default theme ...");
boolean foundTheme = false;
boolean foundTheme = false;
for(Theme t: themes.getThemeList())
for(Theme t: themes.getThemeList())
{
{
if(t.getFullName().equals(config.getCurrentThemeFullName()))
if(t.getFullName().equals(config.getCurrentThemeFullName()))
{
{
foundTheme = true;
foundTheme = true;
applyTheme(t);
applyTheme(t);
break;
break;
}
}
}
}
if(foundTheme)
if(foundTheme)
{
{
logger.info("... Done!");
logger.info("... Done!");
}
}
else
else
{
{
logger.info("Theme not found. reverting to light theme ...");
logger.info("Theme not found. reverting to light theme ...");
try {
try {
Config.getInstance().setCurrentThemeFullName("com.StreamPi.DefaultLight");
Config.getInstance().setCurrentThemeFullName("com.StreamPi.DefaultLight");
Config.getInstance().save();
Config.getInstance().save();
applyDefaultTheme();
applyDefaultTheme();
}
}
catch (SevereException e)
catch (SevereException e)
{
{
handleSevereException(e);
handleSevereException(e);
}
}
}
}
}
}
@Override
@Override
public String getDefaultThemeFullName()
public String getDefaultThemeFullName()
{
{
return config.getCurrentThemeFullName();
return config.getCurrentThemeFullName();
}
}
}
}
package com.stream_pi.client.window.dashboard.actiongridpane;
package com.stream_pi.client.window.dashboard.actiongridpane;
import java.util.logging.Logger;
import java.util.logging.Logger;
import com.stream_pi.action_api.action.Action;
import com.stream_pi.action_api.action.Action;
import com.stream_pi.action_api.action.ActionType;
import com.stream_pi.action_api.action.ActionType;
import com.stream_pi.action_api.action.Location;
import com.stream_pi.action_api.action.Location;
import com.stream_pi.client.connection.ClientListener;
import com.stream_pi.client.connection.ClientListener;
import com.stream_pi.client.profile.ClientProfile;
import com.stream_pi.client.profile.ClientProfile;
import com.stream_pi.client.profile.ClientProfiles;
import com.stream_pi.client.profile.ClientProfiles;
import com.stream_pi.client.window.ExceptionAndAlertHandler;
import com.stream_pi.client.window.ExceptionAndAlertHandler;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.exception.SevereException;
import javafx.concurrent.Task;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.Pos;
import javafx.scene.CacheHint;
import javafx.scene.CacheHint;
import javafx.scene.Node;
import javafx.scene.Node;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.paint.Color;
import org.kordamp.ikonli.javafx.FontIcon;
import org.kordamp.ikonli.javafx.FontIcon;
public class ActionGridPane extends GridPane implements ActionGridPaneListener
public class ActionGridPane extends ScrollPane implements ActionGridPaneListener
{
{
private ExceptionAndAlertHandler exceptionAndAlertHandler;
private ExceptionAndAlertHandler exceptionAndAlertHandler;
private ClientListener clientListener;
private ClientListener clientListener;
private ActionBox[][] actionBoxes;
private ActionBox[][] actionBoxes;
private GridPane actionsGridPane;
public ActionGridPane(ExceptionAndAlertHandler exceptionAndAlertHandler, ClientListener clientListener)
public ActionGridPane(ExceptionAndAlertHandler exceptionAndAlertHandler, ClientListener clientListener)
{
{
this.clientListener = clientListener;
this.clientListener = clientListener;
logger = Logger.getLogger(ActionGridPane.class.getName());
logger = Logger.getLogger(ActionGridPane.class.getName());
this.exceptionAndAlertHandler = exceptionAndAlertHandler;
this.exceptionAndAlertHandler = exceptionAndAlertHandler;
getStyleClass().add("action_grid_pane");
setPadding(new Insets(5.0));
getStyleClass().add("action_grid_pane_parent");
actionsGridPane = new GridPane();
actionsGridPane.setPadding(new Insets(5.0));
actionsGridPane.getStyleClass().add("action_grid_pane");
actionsGridPane.prefWidthProperty().bind(widthProperty().subtract(2));
actionsGridPane.prefHeightProperty().bind(heightProperty().subtract(2));
setPrefSize(USE_COMPUTED_SIZE, USE_COMPUTED_SIZE);
setContent(actionsGridPane);
actionsGridPane.setAlignment(Pos.CENTER);
setAlignment(Pos.CENTER);
VBox.setVgrow(this, Priority.ALWAYS);
VBox.setVgrow(this, Priority.ALWAYS);
setCache(true);
setCache(true);
setCacheHint(CacheHint.SPEED);
setCacheHint(CacheHint.SPEED);
}
}
private String currentParent;
private String currentParent;
public void setCurrentParent(String currentParent) {
public void setCurrentParent(String currentParent) {
this.currentParent = currentParent;
this.currentParent = currentParent;
}
}
public ClientProfile getClientProfile() {
public ClientProfile getClientProfile() {
return clientProfile;
return clientProfile;
}
}
private int rows, cols;
private int rows, cols;
private ClientProfile clientProfile;
private ClientProfile clientProfile;
public void setClientProfile(ClientProfile clientProfile)
public void setClientProfile(ClientProfile clientProfile)
{
{
this.clientProfile = clientProfile;
this.clientProfile = clientProfile;
setCurrentParent("root");
setCurrentParent("root");
setRows(clientProfile.getRows());
setRows(clientProfile.getRows());
setCols(clientProfile.getCols());
setCols(clientProfile.getCols());
}
}
public void actionFailed(String profileID, String actionID)
public void actionFailed(String profileID, String actionID)
{
{
if(getClientProfile().getID().equals(profileID))
if(getClientProfile().getID().equals(profileID))
{
{
Action action = getClientProfile().getActionFromID(actionID);
Action action = getClientProfile().getActionFromID(actionID);
if(action != null)
if(action != null)
{
{
if(currentParent.equals(action.getParent()))
if(currentParent.equals(action.getParent()))
{
{
failShow(action);
failShow(action);
}
}
else
else
{
{
if(action.getLocation().getCol() == -1)
if(action.getLocation().getCol() == -1)
{
{
failShow(getClientProfile().getActionFromID(action.getParent()));
failShow(getClientProfile().getActionFromID(action.getParent()));
}
}
}
}
}
}
}
}
}
}
public void failShow(Action action)
public void failShow(Action action)
{
{
/*for(Node node : getChildren())
/*for(Node node : getChildren())
{
{
if(GridPane.getColumnIndex(node) == action.getLocation().getRow() &&
if(GridPane.getColumnIndex(node) == action.getLocation().getRow() &&
GridPane.getRowIndex(node) == action.getLocation().getCol())
GridPane.getRowIndex(node) == action.getLocation().getCol())
{
{
ActionBox actionBox = (ActionBox) node;
ActionBox actionBox = (ActionBox) node;
actionBox.animateStatus();
actionBox.animateStatus();
break;
break;
}
}
}*/
}*/
actionBoxes[action.getLocation().getCol()][action.getLocation().getRow()].animateStatus();
actionBoxes[action.getLocation().getCol()][action.getLocation().getRow()].animateStatus();
}
}
public String getCurrentParent() {
public String getCurrentParent() {
return currentParent;
return currentParent;
}
}
public StackPane getFolderBackButton()
public StackPane getFolderBackButton()
{
{
StackPane stackPane = new StackPane();
StackPane stackPane = new StackPane();
stackPane.getStyleClass().add("action_box");
stackPane.getStyleClass().add("action_box");
stackPane.getStyleClass().add("action_box_valid");
stackPane.getStyleClass().add("action_box_valid");
stackPane.setPrefSize(
stackPane.setPrefSize(
getClientProfile().getActionSize(),
getClientProfile().getActionSize(),
getClientProfile().getActionSize()
getClientProfile().getActionSize()
);
);
FontIcon fontIcon = new FontIcon("fas-chevron-left");
FontIcon fontIcon = new FontIcon("fas-chevron-left");
fontIcon.getStyleClass().add("folder_action_back_button_icon");
fontIcon.getStyleClass().add("folder_action_back_button_icon");
fontIcon.setIconSize(getClientProfile().getActionSize() - 30);
fontIcon.setIconSize(getClientProfile().getActionSize() - 30);
stackPane.setAlignment(Pos.CENTER);
stackPane.setAlignment(Pos.CENTER);
stackPane.getChildren().add(fontIcon);
stackPane.getChildren().add(fontIcon);
stackPane.setOnMouseClicked(e->returnToPreviousParent());
stackPane.setOnMouseClicked(e->returnToPreviousParent());
return stackPane;
return stackPane;
}
}
private boolean isFreshRender = true;
private boolean isFreshRender = true;
private Node folderBackButton = null;
private Node folderBackButton = null;
public void renderGrid()
public void renderGrid()
{
{
setHgap(getClientProfile().getActionGap());
actionsGridPane.setHgap(getClientProfile().getActionGap());
setVgap(getClientProfile().getActionGap());
actionsGridPane.setVgap(getClientProfile().getActionGap());
if(isFreshRender)
if(isFreshRender)
{
{
clear();
clear();
actionBoxes = new ActionBox[cols][rows];
actionBoxes = new ActionBox[cols][rows];
}
}
boolean isFolder = false;
boolean isFolder = false;
if(getCurrentParent().equals("root"))
if(getCurrentParent().equals("root"))
{
{
if(folderBackButton != null)
if(folderBackButton != null)
{
{
getChildren().remove(folderBackButton);
actionsGridPane.getChildren().remove(folderBackButton);
folderBackButton = null;
folderBackButton = null;
actionBoxes[0][0] = addBlankActionBox(0,0);
actionBoxes[0][0] = addBlankActionBox(0,0);
}
}
}
}
else
else
{
{
isFolder = true;
isFolder = true;
if(folderBackButton != null)
if(folderBackButton != null)
{
{
getChildren().remove(folderBackButton);
actionsGridPane.getChildren().remove(folderBackButton);
folderBackButton = null;
folderBackButton = null;
}
}
else
else
{
{
getChildren().remove(actionBoxes[0][0]);
actionsGridPane.getChildren().remove(actionBoxes[0][0]);
}
}
folderBackButton = getFolderBackButton();
folderBackButton = getFolderBackButton();
add(folderBackButton, 0,0);
actionsGridPane.add(folderBackButton, 0,0);
}
}
for(int row = 0; row<rows; row++)
for(int row = 0; row<rows; row++)
{
{
for(int col = 0; col<cols; col++)
for(int col = 0; col<cols; col++)
{
{
if(row == 0 && col == 0 && isFolder)
if(row == 0 && col == 0 && isFolder)
continue;
continue;
if(isFreshRender)
if(isFreshRender)
{
{
actionBoxes[col][row] = addBlankActionBox(col, row);
actionBoxes[col][row] = addBlankActionBox(col, row);
}
}
else
else
{
{
if(actionBoxes[col][row].getAction() != null)
if(actionBoxes[col][row].getAction() != null)
{
{
actionBoxes[col][row].clear();
actionBoxes[col][row].clear();
}
}
}
}
}
}
}
}
isFreshRender = false;
isFreshRender = false;
}
}
public void setFreshRender(boolean isFreshRender) {
public void setFreshRender(boolean isFreshRender) {
this.isFreshRender = isFreshRender;
this.isFreshRender = isFreshRender;
}
}
public void renderActions()
public void renderActions()
{
{
StringBuilder errors = new StringBuilder();
StringBuilder errors = new StringBuilder();
for(Action eachAction : getClientProfile().getActions())
for(Action eachAction : getClientProfile().getActions())
{
{
logger.info("Action ID : "+eachAction.getID()+"\nInvalid : "+eachAction.isInvalid());
logger.info("Action ID : "+eachAction.getID()+"\nInvalid : "+eachAction.isInvalid());
try {
try {
renderAction(eachAction);
renderAction(eachAction);
}
}
catch (SevereException e)
catch (SevereException e)
{
{
exceptionAndAlertHandler.handleSevereException(e);
exceptionAndAlertHandler.handleSevereException(e);
}
}
catch (MinorException e)
catch (MinorException e)
{
{
errors.append("*").append(e.getShortMessage()).append("\n");
errors.append("*").append(e.getShortMessage()).append("\n");
}
}
}
}
if(!errors.toString().isEmpty())
if(!errors.toString().isEmpty())
{
{
exceptionAndAlertHandler.handleMinorException(new MinorException("Error while rendering following actions", errors.toString()));
exceptionAndAlertHandler.handleMinorException(new MinorException("Error while rendering following actions", errors.toString()));
}
}
}
}
public void clear()
public void clear()
{
{
getChildren().clear();
actionsGridPane.getChildren().clear();
}
}
private Logger logger;
private Logger logger;
public void clearActionBox(int col, int row)
public void clearActionBox(int col, int row)
{
{
actionBoxes[col][row].clear();
actionBoxes[col][row].clear();
}
}
public ActionBox getActionBox(int col, int row)
public ActionBox getActionBox(int col, int row)
{
{
return actionBoxes[col][row];
return actionBoxes[col][row];
}
}
public ActionBox addBlankActionBox(int col, int row)
public ActionBox addBlankActionBox(int col, int row)
{
{
ActionBox actionBox = new ActionBox(getClientProfile().getActionSize(), exceptionAndAlertHandler, clientListener, this, row, col);
ActionBox actionBox = new ActionBox(getClientProfile().getActionSize(), exceptionAndAlertHandler, clientListener, this, row, col);
actionBox.setStreamPiParent(currentParent);
actionBox.setStreamPiParent(currentParent);
add(actionBox, col, row);
actionsGridPane.add(actionBox, col, row);
return actionBox;
return actionBox;
}
}
public void toggleOffAllToggleActions()
public void toggleOffAllToggleActions()
{
{
for(Node each : getChildren())
for(Node each : actionsGridPane.getChildren())
{
{
if(each instanceof ActionBox)
if(each instanceof ActionBox)
{
{
ActionBox eachActionBox = (ActionBox) each;
ActionBox eachActionBox = (ActionBox) each;
if(eachActionBox.getAction() != null)
if(eachActionBox.getAction() != null)
{
{
if(eachActionBox.getAction().getActionType() == ActionType.TOGGLE)
if(eachActionBox.getAction().getActionType() == ActionType.TOGGLE)
{
{
if(eachActionBox.getCurrentToggleStatus()) // ON
if(eachActionBox.getCurrentToggleStatus()) // ON
{
{
eachActionBox.toggle();
eachActionBox.toggle();
}
}
}
}
}
}
}
}
}
}
}
}
public void renderAction(Action action) throws SevereException, MinorException
public void renderAction(Action action) throws SevereException, MinorException
{
{
if(!action.getParent().equals(currentParent))
if(!action.getParent().equals(currentParent))
{
{
logger.info("Skipping action "+action.getID()+", not current parent!");
logger.info("Skipping action "+action.getID()+", not current parent!");
return;
return;
}
}
if(action.getLocation().getRow()==-1)
if(action.getLocation().getRow()==-1)
{
{
logger.info("Action has -1 rowIndex. Probably Combine Action. Skipping ...");
logger.info("Action has -1 rowIndex. Probably Combine Action. Skipping ...");
return;
return;
}
}
if(action.getLocation().getRow() > rows || action.getLocation().getCol() > cols)
if(action.getLocation().getRow() > rows || action.getLocation().getCol() > cols)
{
{
throw new MinorException("Action "+action.getDisplayText()+" ("+action.getID()+") falls outside bounds.\n" +
throw new MinorException("Action "+action.getDisplayText()+" ("+action.getID()+") falls outside bounds.\n" +
" Consider increasing rows/cols from client settings and relocating/deleting it.");
" Consider increasing rows/cols from client settings and relocating/deleting it.");
}
}
Location location = action.getLocation();
Location location = action.getLocation();
ActionBox actionBox = actionBoxes[location.getCol()][location.getRow()];
ActionBox actionBox = actionBoxes[location.getCol()][location.getRow()];
actionBox.clear();
actionBox.clear();
boolean oldToggleStatus = actionBox.getCurrentToggleStatus();
boolean oldToggleStatus = actionBox.getCurrentToggleStatus();
actionBox.setAction(action);
actionBox.setAction(action);
actionBox.setCurrentToggleStatus(oldToggleStatus);
actionBox.setCurrentToggleStatus(oldToggleStatus);
actionBox.setStreamPiParent(currentParent);
actionBox.setStreamPiParent(currentParent);
actionBox.init();
actionBox.init();
/*ActionBox actionBox = new ActionBox(getClientProfile().getActionSize(), action, exceptionAndAlertHandler, this, location.getRow(), location.getCol());
/*ActionBox actionBox = new ActionBox(getClientProfile().getActionSize(), action, exceptionAndAlertHandler, this, location.getRow(), location.getCol());
actionBox.setStreamPiParent(currentParent);
actionBox.setStreamPiParent(currentParent);
clearActionBox(location.getCol(), location.getRow());
clearActionBox(location.getCol(), location.getRow());
System.out.println(location.getCol()+","+location.getRow());
System.out.println(location.getCol()+","+location.getRow());
add(actionBox, location.getRow(), location.getCol());
add(actionBox, location.getRow(), location.getCol());
actionBoxes[location.getCol()][location.getRow()] = actionBox;*/
actionBoxes[location.getCol()][location.getRow()] = actionBox;*/
}
}
public void setRows(int rows)
public void setRows(int rows)
{
{
this.rows = rows;
this.rows = rows;
}
}
public void setCols(int cols)
public void setCols(int cols)
{
{
this.cols = cols;
this.cols = cols;
}
}
public int getRows()
public int getRows()
{
{
return rows;
return rows;
}
}
public int getCols()
public int getCols()
{
{
return cols;
return cols;
}
}
private String previousParent;
private String previousParent;
public void setPreviousParent(String previousParent) {
public void setPreviousParent(String previousParent) {
this.previousParent = previousParent;
this.previousParent = previousParent;
}
}
public String getPreviousParent() {
public String getPreviousParent() {
return previousParent;
return previousParent;
}
}
@Override
@Override
public void renderFolder(String actionID) {
public void renderFolder(String actionID) {
setCurrentParent(clientProfile.getActionFromID(actionID).getID());
setCurrentParent(clientProfile.getActionFromID(actionID).getID());
setPreviousParent(clientProfile.getActionFromID(actionID).getParent());
setPreviousParent(clientProfile.getActionFromID(actionID).getParent());
renderGrid();
renderGrid();
renderActions();
renderActions();
}
}
@Override
@Override
public void normalActionClicked(String ID)
public void normalActionClicked(String ID)
{
{
clientListener.onActionClicked(getClientProfile().getID(), ID, false);
clientListener.onActionClicked(getClientProfile().getID(), ID, false);
}
}
@Override
@Override
public void toggleActionClicked(String ID, boolean toggleState)
public void toggleActionClicked(String ID, boolean toggleState)
{
{
clientListener.onActionClicked(getClientProfile().getID(), ID, toggleState);
clientListener.onActionClicked(getClientProfile().getID(), ID, toggleState);
}
}
@Override
@Override
public ActionBox getActionBoxByLocation(Location location)
public ActionBox getActionBoxByLocation(Location location)
{
{
return getActionBox(location.getCol(), location.getRow());
return getActionBox(location.getCol(), location.getRow());
}
}
@Override
@Override
public boolean isConnected()
public boolean isConnected()
{
{
return clientListener.isConnected();
return clientListener.isConnected();
}
}
@Override
@Override
public void combineActionClicked(String ID) {
public void combineActionClicked(String ID) {
if(clientListener.isConnected())
if(clientListener.isConnected())
{
{
new Thread(new Task<Void>() {
new Thread(new Task<Void>() {
@Override
@Override
protected Void call()
protected Void call()
{
{
Action action = getClientProfile().getActionFromID(ID);
Action action = getClientProfile().getActionFromID(ID);
for(int i = 0;i<action.getClientProperties().get().size();i++)
for(int i = 0;i<action.getClientProperties().get().size();i++)
{
{
try {
try {
logger.info("Clicking "+i+", '"+action.getClientProperties().getSingleProperty(i+"").getRawValue()+"'");
logger.info("Clicking "+i+", '"+action.getClientProperties().getSingleProperty(i+"").getRawValue()+"'");
normalActionClicked(action.getClientProperties().getSingleProperty(i+"").getRawValue());
normalActionClicked(action.getClientProperties().getSingleProperty(i+"").getRawValue());
} catch (MinorException e) {
} catch (MinorException e) {
e.printStackTrace();
e.printStackTrace();
exceptionAndAlertHandler.handleMinorException(e);
exceptionAndAlertHandler.handleMinorException(e);
}
}
}
}
return null;
return null;
}
}
}).start();
}).start();
}
}
}
}
public void returnToPreviousParent()
public void returnToPreviousParent()
{
{
setCurrentParent(getPreviousParent());
setCurrentParent(getPreviousParent());
if(!getPreviousParent().equals("root"))
if(!getPreviousParent().equals("root"))
{
{
System.out.println("parent : "+getPreviousParent());
System.out.println("parent : "+getPreviousParent());
setPreviousParent(getClientProfile().getActionFromID(
setPreviousParent(getClientProfile().getActionFromID(
getPreviousParent()
getPreviousParent()
).getParent());
).getParent());
}
}
renderGrid();
renderGrid();
renderActions();
renderActions();
}
}
}
}
module com.stream_pi.client {
module com.stream_pi.client {
requires javafx.base;
requires javafx.base;
requires javafx.graphics;
requires javafx.graphics;
requires javafx.controls;
requires javafx.controls;
requires org.kordamp.iconli.core;
requires org.kordamp.iconli.core;
requires org.kordamp.ikonli.javafx;
requires org.kordamp.ikonli.javafx;
requires com.gluonhq.attach.lifecycle;
requires com.gluonhq.attach.lifecycle;
requires com.gluonhq.attach.util;
requires com.gluonhq.attach.util;
requires com.gluonhq.attach.storage;
requires com.gluonhq.attach.storage;
requires com.gluonhq.attach.browser;
requires com.gluonhq.attach.browser;
requires com.gluonhq.attach.vibration;
requires com.gluonhq.attach.vibration;
requires com.gluonhq.attach.orientation;
requires java.xml;
requires java.xml;
requires com.stream_pi.util;
requires com.stream_pi.util;
requires com.stream_pi.theme_api;
requires com.stream_pi.theme_api;
requires com.stream_pi.action_api;
requires com.stream_pi.action_api;
requires org.kordamp.ikonli.fontawesome5;
requires org.kordamp.ikonli.fontawesome5;
exports com.stream_pi.client;
exports com.stream_pi.client;
}
}
.root {
.root {
-fx-font-family : 'Roboto';
-fx-font-family : 'Roboto';
}
}
.action_box
.action_box
{
{
-fx-border-width: 1px;
-fx-border-width: 1px;
-fx-border-color : grey;
-fx-border-color : grey;
}
}
.action_box_icon_present
.action_box_icon_present
{
{
}
}
.action_box_icon_not_present
.action_box_icon_not_present
{
{
}
}
.action_box_onclick
.action_box_onclick
{
{
}
}
.settings_heading_label
.settings_heading_label
{
{
-fx-font-size: 20;
-fx-font-size: 20;
}
}
.alert_header
.alert_header
{
{
-fx-padding: 5;
-fx-padding: 5;
}
}
.alert_pane
.alert_pane
{
{
-fx-border-width : 5;
-fx-border-width : 5;
-fx-border-radius : 5;
-fx-border-radius : 5;
-fx-background-radius : 5;
-fx-background-radius : 5;
-fx-max-width : 400;
-fx-max-width : 400;
-fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0.0 , 0 );
-fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0.0 , 0 );
}
}
.alert_header_icon
.alert_header_icon
{
{
-fx-icon-size : 30;
-fx-icon-size : 30;
}
}
.alert_content_pane
.alert_content_pane
{
{
-fx-padding: 5;
-fx-padding: 5;
}
}
.alert_pane_parent, .combobox_pane_parent
.alert_pane_parent, .combobox_pane_parent
{
{
-fx-background-color : rgba(0,0,0,0.5);
-fx-background-color : rgba(0,0,0,0.5);
}
}
.alert_pane_header_text
.alert_pane_header_text
{
{
-fx-font-size: 18;
-fx-font-size: 18;
}
}
.alert_button_bar
.alert_button_bar
{
{
-fx-alignment: CENTER_RIGHT;
-fx-alignment: CENTER_RIGHT;
-fx-spacing: 5;
-fx-spacing: 5;
-fx-padding: 5;
-fx-padding: 5;
}
}
.alert_scroll_pane {
.alert_scroll_pane {
-fx-max-height : 300;
-fx-max-height : 300;
/*-fx-focus-color: #FFFFFF;
/*-fx-focus-color: #FFFFFF;
-fx-faint-focus-color:#FFFFFF;*/
-fx-faint-focus-color:#FFFFFF;*/
}
}
.combo_box
.combo_box
{
{
-fx-alignment:CENTER_LEFT;
-fx-alignment:CENTER_LEFT;
-fx-pref-width:200;
-fx-pref-width:200;
-fx-padding: 5;
-fx-padding: 5;
-fx-border-width : 1;
-fx-border-width : 1;
-fx-border-color : grey;
-fx-border-color : grey;
-fx-border-radius : 3;
-fx-border-radius : 3;
}
}
.combo_box_popup
.combo_box_popup
{
{
-fx-border-width : 5;
-fx-border-width : 5;
-fx-border-radius : 5;
-fx-border-radius : 5;
-fx-background-radius : 5;
-fx-background-radius : 5;
-fx-max-height : 300;
-fx-max-height : 300;
-fx-max-width : 410;
-fx-max-width : 410;
-fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0.0 , 0 );
-fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0.0 , 0 );
}
}
.combo_box_popup_vbox
.combo_box_popup_vbox
{
{
-fx-padding: 5 5 0 5;
-fx-padding: 5 5 0 5;
-fx-spacing:5;
-fx-spacing:5;
}
}
.combo_box_drop_down_icon
.combo_box_drop_down_icon
{
{
-fx-icon-code: fas-caret-down;
-fx-icon-code: fas-caret-down;
-fx-icon-size: 14;
-fx-icon-size: 14;
}
}
.first_time_use_pane
.first_time_use_pane
{
{
-fx-background-color:white;
-fx-background-color:white;
-fx-padding : 5;
}
.action_grid_pane_parent
{
-fx-background-color:transparent;
}
}
.first_time_use_pane_heading_label
.first_time_use_pane_heading_label
{
{
-fx-font-size: 20;
-fx-font-size: 20;
}
}
.first_time_use_final_config_pane_scroll_pane
.first_time_use_final_config_pane_scroll_pane
{
{
-fx-background-color:transparent;
-fx-background-color:transparent;
}
}
.first_time_use_pane_stackpane
.first_time_use_pane_stackpane
{
{
}
}
.first_time_use_pane_welcome
.first_time_use_pane_welcome
{
{
}
}
.first_time_use_pane_license
.first_time_use_pane_license
{
{
-fx-spacing : 10;
-fx-spacing : 10;
}
}
.first_time_use_pane_final_config
.first_time_use_pane_final_config
{
{
}
}
.first_time_use_pane_final_config_label
.first_time_use_pane_final_config_label
{
{
}
}
.first_time_use_welcome_pane_welcome_label
.first_time_use_welcome_pane_welcome_label
{
{
-fx-font-size: 30;
-fx-font-size: 30;
}
}
.first_time_use_welcome_pane_next_to_continue_label
.first_time_use_welcome_pane_next_to_continue_label
{
{
-fx-font-size: 15;
-fx-font-size: 15;
}
}
.scroll-pane
.scroll-pane
{
{
-fx-focus-color:transparent;
-fx-focus-color:transparent;
-fx-faint-focus-color:transparent;
-fx-faint-focus-color:transparent;
}
}
/*Alert Classes added to default stylesheet to show init error, if occurs */
/*Alert Classes added to default stylesheet to show init error, if occurs */
.action_box_display_text_label
.action_box_display_text_label
{
{
-fx-font-size : 16;
-fx-font-size : 16;
-fx-background-color : transparent;
-fx-background-color : transparent;
}
}
.alert_pane
.alert_pane
{
{
-fx-background-color : white;
-fx-background-color : white;
-fx-border-color : white;
-fx-border-color : white;
}
}
.alert_content_pane
.alert_content_pane
{
{
-fx-background-color: white;
-fx-background-color: white;
-fx-padding: 5;
-fx-padding: 5;
}
}
.alert_scroll_pane
.alert_scroll_pane
{
{
-fx-background: white;
-fx-background: white;
-fx-border-color:white;
-fx-border-color:white;
}
}
.alert_button_bar
.alert_button_bar
{
{
-fx-background-color:white;
-fx-background-color:white;
}
}