client

Clone or download

refactored to java naming convention

Modified Files

M pom.xml
+9 −9
--- 'a/pom.xml'
+++ b/pom.xml
@@ -4,8 +4,8 @@
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.StreamPi</groupId>
- <artifactId>Client</artifactId>
+ <groupId>com.stream_pi</groupId>
+ <artifactId>client</artifactId>
<version>1.0.0</version>
<url>https://stream-pi.com/</url>
@@ -27,7 +27,7 @@
<UtilVersion>1.0.0</UtilVersion>
<ThemeAPIVersion>1.0.0</ThemeAPIVersion>
- <MainClassName>com.StreamPi.Client.Main</MainClassName>
+ <MainClassName>com.stream_pi.client.Main</MainClassName>
<JavaFXSDK>/path/to/sdk</JavaFXSDK>
</properties>
@@ -62,20 +62,20 @@
</dependency>
<dependency>
- <groupId>com.StreamPi</groupId>
- <artifactId>ActionAPI</artifactId>
+ <groupId>com.stream_pi</groupId>
+ <artifactId>action_api</artifactId>
<version>${ActionAPIVersion}</version>
</dependency>
<dependency>
- <groupId>com.StreamPi</groupId>
- <artifactId>ThemeAPI</artifactId>
+ <groupId>com.stream_pi</groupId>
+ <artifactId>themeapi</artifactId>
<version>${ThemeAPIVersion}</version>
</dependency>
<dependency>
- <groupId>com.StreamPi</groupId>
- <artifactId>Util</artifactId>
+ <groupId>com.stream_pi</groupId>
+ <artifactId>util</artifactId>
<version>${UtilVersion}</version>
</dependency>
--- 'a/src/main/java/com/StreamPi/Client/Connection/Client.java'
+++ /dev/null
@@ -1,966 +0,0 @@
-package com.StreamPi.Client.Connection;
-
-import com.StreamPi.ActionAPI.Action.Action;
-import com.StreamPi.ActionAPI.Action.ActionType;
-import com.StreamPi.ActionAPI.Action.DisplayTextAlignment;
-import com.StreamPi.ActionAPI.Action.Location;
-import com.StreamPi.ActionAPI.ActionProperty.ClientProperties;
-import com.StreamPi.ActionAPI.ActionProperty.Property.Property;
-import com.StreamPi.ActionAPI.ActionProperty.Property.Type;
-import com.StreamPi.Client.IO.Config;
-import com.StreamPi.Client.Info.ClientInfo;
-import com.StreamPi.Client.Profile.ClientProfile;
-import com.StreamPi.Client.Profile.ClientProfiles;
-import com.StreamPi.Client.Window.ExceptionAndAlertHandler;
-import com.StreamPi.Client.Window.Dashboard.ActionGridPane.ActionBox;
-import com.StreamPi.ThemeAPI.Theme;
-import com.StreamPi.Util.Alert.StreamPiAlertType;
-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.Platform.ReleaseStatus;
-import com.StreamPi.Util.Version.Version;
-import javafx.concurrent.Task;
-import javafx.scene.control.Alert;
-
-import java.io.*;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.logging.LogManager;
-import java.util.logging.Logger;
-
-public class Client extends Thread{
-
- private Socket socket;
-
- //private Logger logger;
-
- private DataOutputStream dos;
- private DataInputStream dis;
-
- private AtomicBoolean stop = new AtomicBoolean(false);
-
- private ClientListener clientListener;
- private ExceptionAndAlertHandler exceptionAndAlertHandler;
-
- private ClientInfo clientInfo;
-
- private String serverIP;
- private int serverPort;
- private Logger logger;
-
- public Client(String serverIP, int serverPort, ClientListener clientListener, ExceptionAndAlertHandler exceptionAndAlertHandler)
- {
- this.serverIP = serverIP;
- this.serverPort = serverPort;
-
- this.exceptionAndAlertHandler = exceptionAndAlertHandler;
- this.clientInfo = ClientInfo.getInstance();
- this.clientListener = clientListener;
-
- logger = Logger.getLogger(Client.class.getName());
-
- new Thread(new Task<Void>() {
- @Override
- protected Void call()
- {
- try
- {
- try {
- logger.info("Trying to connect to server at "+serverIP+":"+serverPort);
- socket = new Socket();
- socket.connect(new InetSocketAddress(serverIP, serverPort), 5000);
- clientListener.setConnected(true);
- clientListener.updateSettingsConnectDisconnectButton();
- logger.info("Connected to "+socket.getRemoteSocketAddress()+" !");
- } catch (IOException e) {
- e.printStackTrace();
-
- clientListener.setConnected(false);
- clientListener.updateSettingsConnectDisconnectButton();
- throw new MinorException("Connection Error", "Unable to connect to server. Please check settings and connection and try again.");
- }
-
- try
- {
- dos = new DataOutputStream(socket.getOutputStream());
- dis = new DataInputStream(socket.getInputStream());
- }
- catch (IOException e)
- {
- logger.severe(e.getMessage());
- e.printStackTrace();
- throw new MinorException("Unable to set up IO Streams to server. Check connection and try again.");
- }
- start();
- } catch (MinorException e)
- {
- exceptionAndAlertHandler.handleMinorException(e);
- }
- return null;
- }
- }).start();
- }
-
- public synchronized void exit()
- {
- if(stop.get())
- return;
-
- logger.info("Stopping ...");
-
- try
- {
- if(socket!=null)
- {
- disconnect();
- }
- }
- catch (SevereException e)
- {
- logger.severe(e.getMessage());
- exceptionAndAlertHandler.handleSevereException(e);
- e.printStackTrace();
- }
- }
-
-
-
- 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
- {
- byte[] txtBytes = text.getBytes();
-
- 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!");
- }
-
- }
-
- public void write(byte[] array) throws SevereException
- {
- try
- {
- dos.write(array);
- }
- catch (IOException e)
- {
- logger.severe(e.getMessage());
- e.printStackTrace();
- throw new SevereException("Unable to write to IO Stream!");
- }
- }
-
- @Override
- public void run() {
- try
- {
- while(!stop.get())
- {
- String msg = "";
-
- try
- {
- String raw = dis.readUTF();
-
- System.out.println("AAAAAAAAAAAAAAAAAA : "+raw);
-
- int length = dis.readInt();
-
- String[] precursor = raw.split("::");
-
- String inputType = precursor[0];
- String secondArg = precursor[1];
-
-
- //ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-
- /*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);
-
- 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);
- }
-
-
- byteArrayOutputStream.close();
-
- byte[] bArr = byteArrayOutputStream.toByteArray();*/
-
- byte[] bArr = new byte[length];
-
- dis.readFully(bArr);
-
- if(inputType.equals("string"))
- {
- msg = new String(bArr);
- }
- else if(inputType.equals("action_icon"))
- {
- System.out.println("asdsdsxxxxxxxxxxxxxxxxxxxxxxxxxxx");
- String[] secondArgSep = secondArg.split("!!");
-
- String profileID = secondArgSep[0];
- String actionID = secondArgSep[1];
-
- clientListener.getClientProfiles().getProfileFromID(profileID).saveActionIcon(actionID, bArr);
-
- Action a = clientListener.getClientProfiles().getProfileFromID(profileID).getActionFromID(actionID);
- clientListener.clearActionBox(a.getLocation().getCol(), a.getLocation().getRow());
- clientListener.renderAction(profileID, a);
-
-
- continue;
- }
- }
- catch (IOException e)
- {
- logger.severe(e.getMessage());
- e.printStackTrace();
-
- clientListener.setConnected(false);
- clientListener.updateSettingsConnectDisconnectButton();
-
- if(!stop.get())
- {
- //isDisconnect.set(true); //Prevent running disconnect
- throw new MinorException("Accidentally disconnected from Server! (Failed at readUTF)");
- }
-
- exit();
-
- return;
- }
-
-
- logger.info("Received text : '"+msg+"'");
-
- String[] sep = msg.split("::");
-
- String command = sep[0];
-
- switch (command)
- {
- case "disconnect" : serverDisconnected(msg);
- break;
-
- case "get_client_details" : sendClientDetails();
- break;
-
- case "get_profiles" : sendProfileNamesToServer();
- break;
-
- case "get_profile_details": sendProfileDetailsToServer(sep[1]);
- break;
-
- case "save_action_details": saveActionDetails(sep);
- break;
-
- case "delete_action": deleteAction(sep[1], sep[2]);
- break;
-
- case "get_themes": sendThemesToServer();
- break;
-
- case "save_client_details": saveClientDetails(sep);
- break;
-
- case "save_client_profile": saveProfileDetails(sep);
- break;
-
- case "delete_profile": deleteProfile(sep[1]);
- break;
-
- case "action_failed": actionFailed(sep[1], sep[2]);
- break;
-
-
- default: logger.warning("Command '"+command+"' does not match records. Make sure client and server versions are equal.");
-
- }
- }
- }
- catch (SevereException e)
- {
- logger.severe(e.getMessage());
- e.printStackTrace();
-
- exceptionAndAlertHandler.handleSevereException(e);
- }
- catch (MinorException e)
- {
- logger.severe(e.getMessage());
- e.printStackTrace();
-
- exceptionAndAlertHandler.handleMinorException(e);
- }
- }
-
-
-
-
- //commands
-
- /*public void receiveActionIcon(String[] sep) throws MinorException {
- String profileID = sep[1];
- String actionID = sep[2];
- int bytesToRead = Integer.parseInt(sep[3]);
- int port = Integer.parseInt(sep[4]);
-
- try
- {
- Socket tempSocket = new Socket(socket.getInetAddress(), port);
- tempSocket.setReceiveBufferSize(bytesToRead);
-
- tempSocket.setSoTimeout(10000);
-
- DataInputStream dataInputStream = new DataInputStream(tempSocket.getInputStream());
-
- byte[] dataIcon = new byte[bytesToRead];
-
- dataInputStream.read(dataIcon);
-
- clientProfiles.getProfileFromID(profileID).getActionFromID(actionID).setIcon(dataIcon);
-
- dataInputStream.close();
- tempSocket.close();
- }
- catch (IOException e)
- {
- e.printStackTrace();
- throw new MinorException("Unable to Receive icon");
- }
- }*/
-
-
- public void sendIcon(String profileID, String actionID, byte[] icon) throws SevereException
- {
- try
- {
- Thread.sleep(50);
- dos.writeUTF("action_icon::"+profileID+"!!"+actionID+"!!::"+icon.length);
- dos.flush();
- dos.writeInt(icon.length);
- dos.flush();
- write(icon);
- dos.flush();
- }
- catch (IOException | InterruptedException e)
- {
- e.printStackTrace();
- throw new SevereException("Unable to write to IO Stream!");
- }
- }
-
-
-
- /*public void sendIcon(String profileID, String actionID, byte[] icon) throws SevereException
- {
- try
- {
-
- ServerSocket tmpServer = new ServerSocket(0);
-
- dos.writeUTF("action_icon::"+
- profileID+"::"+
- actionID+"::"+
- icon.length+"::"+
- tmpServer.getLocalPort()+"::");
-
-
- Socket socket = tmpServer.accept();
- socket.setSendBufferSize(icon.length);
-
- DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
-
- dataOutputStream.write(icon);
-
- dataOutputStream.close();
-
- tmpServer.close();
-
- }
- catch (IOException e)
- {
- e.printStackTrace();
- throw new SevereException(e.getMessage());
- }
- }*/
-
- public void disconnect() throws SevereException
- {
- disconnect("");
- }
-
- public void disconnect(String message) throws SevereException
- {
- if(stop.get())
- return;
-
- stop.set(true);
-
- logger.info("Sending server disconnect message ...");
- writeToStream("disconnect::"+message+"::");
-
- try
- {
- if(!socket.isClosed())
- socket.close();
-
- clientListener.setConnected(false);
- clientListener.updateSettingsConnectDisconnectButton();
- }
- catch (IOException e)
- {
- e.printStackTrace();
- throw new SevereException("Unable to close socket");
- }
- }
-
- public void sendThemesToServer() throws SevereException
- {
- StringBuilder finalQuery = new StringBuilder("themes::");
-
- for(Theme theme : clientListener.getThemes().getThemeList())
- {
- finalQuery.append(theme.getFullName())
- .append("__")
- .append(theme.getShortName())
- .append("__")
- .append(theme.getAuthor())
- .append("__")
- .append(theme.getVersion().getText())
- .append("__::");
- }
-
- writeToStream(finalQuery.toString());
- }
-
-
- public void sendActionIcon(String clientProfileID, String actionID) throws SevereException
- {
- System.out.println("sending action icon "+clientProfileID+", "+actionID);
- sendIcon(clientProfileID, actionID, clientListener.getClientProfiles().getProfileFromID(clientProfileID).getActionFromID(actionID).getIconAsByteArray());
- }
-
- public void serverDisconnected(String message)
- {
- stop.set(true);
- String txt = "Disconnected!";
-
- if(!message.equals("disconnect::::"))
- txt = "Message : "+message.split("::")[1];
-
- exceptionAndAlertHandler.onAlert("Disconnected from Server", txt, StreamPiAlertType.WARNING);
-
- if(!socket.isClosed()) {
- try {
- socket.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- clientListener.setConnected(false);
- clientListener.updateSettingsConnectDisconnectButton();
-
- }
-
- public void sendClientDetails() throws SevereException
- {
- Version clientVersion = clientInfo.getVersion();
- ReleaseStatus releaseStatus = clientInfo.getReleaseStatus();
- Version clientCommsStandard = clientInfo.getCommsStandardVersion();
- Version clientMinThemeStandard = clientInfo.getMinThemeSupportVersion();
- String clientNickname = Config.getInstance().getClientNickName();
- double screenWidth = Config.getInstance().getStartupWindowWidth();
- double screenHeight = Config.getInstance().getStartupWindowHeight();
- Platform OS = clientInfo.getPlatformType();
- String defaultProfileID = Config.getInstance().getStartupProfileID();
-
- writeToStream("client_details::"+
- clientVersion.getText()+"::"+
- releaseStatus+"::"+
- clientCommsStandard.getText()+"::"+
- clientMinThemeStandard.getText()+"::"+
- clientNickname+"::"+
- screenWidth+"::"+
- screenHeight+"::"+
- OS+"::" +
- defaultProfileID+"::"+
- clientListener.getDefaultThemeFullName()+"::");
- }
-
-
- public void sendProfileNamesToServer() throws SevereException
- {
- StringBuilder finalQuery = new StringBuilder("profiles::");
-
- finalQuery.append(clientListener.getClientProfiles().getClientProfiles().size()).append("::");
-
- for(ClientProfile clientProfile : clientListener.getClientProfiles().getClientProfiles())
- {
- finalQuery.append(clientProfile.getID()).append("::");
- }
-
- writeToStream(finalQuery.toString());
- }
-
- public void sendProfileDetailsToServer(String ID) throws SevereException
- {
- StringBuilder finalQuery = new StringBuilder("profile_details::");
-
- ClientProfile clientProfile = clientListener.getClientProfiles().getProfileFromID(ID);
-
- finalQuery.append(ID).append("::");
-
- finalQuery.append(clientProfile.getName())
- .append("::")
- .append(clientProfile.getRows())
- .append("::")
- .append(clientProfile.getCols())
- .append("::")
- .append(clientProfile.getActionSize())
- .append("::")
- .append(clientProfile.getActionGap())
- .append("::");
-
-
- writeToStream(finalQuery.toString());
-
-
- for(Action action : clientProfile.getActions())
- {
- sendActionDetails(clientProfile.getID(), action);
- }
-
- for(Action action : clientProfile.getActions())
- {
- if(action.isHasIcon())
- {
- System.out.println("23123123123 : "+action.getID() + action.isHasIcon());
- sendActionIcon(clientProfile.getID(), action.getID());
- }
- }
-
- }
-
- public void sendActionDetails(String profileID, Action action) throws SevereException {
-
- if(action == null)
- {
- logger.info("NO SUCH ACTION");
- return;
- }
-
- StringBuilder finalQuery = new StringBuilder("action_details::");
-
- finalQuery.append(profileID)
- .append("::")
- .append(action.getID())
- .append("::")
- .append(action.getActionType())
- .append("::");
-
- if(action.getActionType() == ActionType.NORMAL) {
- finalQuery.append(action.getVersion().getText());
- }
-
- finalQuery.append("::");
-
- if(action.getActionType() ==ActionType.NORMAL)
- {
- finalQuery.append(action.getModuleName());
- }
-
-
- finalQuery.append("::");
-
- //display
-
- finalQuery.append(action.getBgColourHex())
- .append("::");
-
- //icon
- finalQuery.append(action.isHasIcon())
- .append("::")
- .append(action.isShowIcon())
- .append("::");
-
- //text
- finalQuery.append(action.isShowDisplayText())
- .append("::")
- .append(action.getDisplayTextFontColourHex())
- .append("::")
- .append(action.getDisplayText())
- .append("::")
- .append(action.getDisplayTextAlignment())
- .append("::");
-
- //location
-
- if(action.getLocation() == null)
- finalQuery.append("-1::-1::");
- else
- finalQuery.append(action.getLocation().getRow())
- .append("::")
- .append(action.getLocation().getCol())
- .append("::");
-
- //client properties
-
- ClientProperties clientProperties = action.getClientProperties();
-
- finalQuery.append(clientProperties.getSize())
- .append("::");
-
- for(Property property : clientProperties.get())
- {
- finalQuery.append(property.getName())
- .append("__")
- .append(property.getRawValue())
- .append("__");
-
- finalQuery.append("!!");
- }
-
- finalQuery.append("::")
- .append(action.getParent())
- .append("::");
-
-
- writeToStream(finalQuery.toString());
-
-
- }
-
- public void saveActionDetails(String[] sep)
- {
- String profileID = sep[1];
-
- String ID = sep[2];
- ActionType actionType = ActionType.valueOf(sep[3]);
-
- //4 - Version
- //5 - ModuleName
-
- //display
- String bgColorHex = sep[6];
-
- //icon
- boolean isHasIcon = sep[7].equals("true");
- boolean isShowIcon = sep[8].equals("true");
-
- //text
- boolean isShowDisplayText = sep[9].equals("true");
- String displayFontColor = sep[10];
- String displayText = sep[11];
- DisplayTextAlignment displayTextAlignment = DisplayTextAlignment.valueOf(sep[12]);
-
- //location
- String row = sep[13];
- String col = sep[14];
-
- Location location = new Location(Integer.parseInt(row), Integer.parseInt(col));
-
- Action action = new Action(ID, actionType);
-
- if(actionType == ActionType.NORMAL)
- {
- try
- {
- action.setVersion(new Version(sep[4]));
- action.setModuleName(sep[5]);
- }
- catch (Exception e)
- {
- logger.severe(e.getMessage());
- e.printStackTrace();
- }
- }
-
-
- action.setBgColourHex(bgColorHex);
-
- action.setShowIcon(isShowIcon);
- action.setHasIcon(isHasIcon);
-
- System.out.println("IS HAS ICON : "+isHasIcon+", IS SHOW ICON :"+isShowIcon);
-
-
- action.setShowDisplayText(isShowDisplayText);
- action.setDisplayTextFontColourHex(displayFontColor);
- action.setDisplayText(displayText);
- action.setDisplayTextAlignment(displayTextAlignment);
-
-
- action.setLocation(location);
-
- //client properties
-
- int clientPropertiesSize = Integer.parseInt(sep[15]);
-
- String[] clientPropertiesRaw = sep[16].split("!!");
-
- ClientProperties clientProperties = new ClientProperties();
-
- if(actionType == ActionType.FOLDER)
- clientProperties.setDuplicatePropertyAllowed(true);
-
- for(int i = 0;i<clientPropertiesSize; i++)
- {
- String[] clientPraw = clientPropertiesRaw[i].split("__");
-
- Property property = new Property(clientPraw[0], Type.STRING);
-
- if(clientPraw.length > 1)
- property.setRawValue(clientPraw[1]);
-
- clientProperties.addProperty(property);
- }
-
- action.setClientProperties(clientProperties);
-
-
- String parent = sep[17];
- action.setParent(parent);
-
-
- try
- {
- Action old = clientListener.getClientProfiles().getProfileFromID(profileID).getActionFromID(action.getID());
-
- if(old != null)
- {
- if(action.isHasIcon())
- action.setIcon(clientListener.getClientProfiles().getProfileFromID(profileID).getActionFromID(action.getID()).getIconAsByteArray());
- }
-
- clientListener.getClientProfiles().getProfileFromID(profileID).addAction(action);
-
- System.out.println("XXXXXXXXXXX " +action.isHasIcon());
-
- //clientListener.getClientProfiles().getProfileFromID(profileID).saveActions();
-
- clientListener.getClientProfiles().getProfileFromID(profileID).saveAction(action);
-
- if(clientListener.getCurrentProfile().getID().equals(profileID) && action.getLocation().getCol()!=-1)
- {
- javafx.application.Platform.runLater(()->{
- ActionBox box = clientListener.getActionBox(action.getLocation().getCol(), action.getLocation().getRow());
- System.out.println(box==null);
- System.out.println("GATYYY : "+action.getLocation().getCol()+","+action.getLocation().getRow());
- box.clear();
- box.setAction(action);
- box.baseInit();
- box.init();
- });
- }
-
- //clientListener.clearActionBox(action.getLocation().getCol(), action.getLocation().getRow());
- //clientListener.renderAction(profileID, action);
-
- }
- catch (Exception e)
- {
- e.printStackTrace();
- exceptionAndAlertHandler.handleMinorException(new MinorException(e.getMessage()));
- }
- }
-
- public void deleteAction(String profileID, String actionID)
- {
- try
- {
-
-
- Action acc = clientListener.getClientProfiles().getProfileFromID(profileID).getActionFromID(actionID);
-
- if(acc.getActionType() == ActionType.FOLDER)
- {
- ArrayList<String> idsToBeRemoved = new ArrayList<>();
-
- ArrayList<String> folders = new ArrayList<>();
- String folderToBeDeletedID = clientListener.getClientProfiles().getProfileFromID(profileID).getActionFromID(actionID).getID();
-
- folders.add(folderToBeDeletedID);
-
- boolean startOver = true;
- while(startOver)
- {
- startOver = false;
- for(Action action : clientListener.getClientProfiles().getProfileFromID(profileID).getActions())
- {
- if(folders.contains(action.getParent()))
- {
- if(!idsToBeRemoved.contains(action.getID()))
- {
- idsToBeRemoved.add(action.getID());
- if(action.getActionType() == ActionType.FOLDER)
- {
- folders.add(action.getID());
- startOver = true;
- }
- }
- }
- }
- }
-
-
- for(String ids : idsToBeRemoved)
- {
- clientListener.getClientProfiles().getProfileFromID(profileID).removeAction(ids);
- }
-
- }
- else if (acc.getActionType() == ActionType.COMBINE)
- {
- for(Property property : acc.getClientProperties().get())
- {
- clientListener.getClientProfiles().getProfileFromID(profileID).removeAction(property.getRawValue());
- }
- }
-
-
- clientListener.getClientProfiles().getProfileFromID(profileID).removeAction(acc.getID());
-
- clientListener.getClientProfiles().getProfileFromID(profileID).saveActions();
-
- if(acc.getLocation().getCol()!=-1)
- {
- clientListener.clearActionBox(acc.getLocation().getCol(), acc.getLocation().getRow());
- clientListener.addBlankActionBox(acc.getLocation().getCol(), acc.getLocation().getRow());
- }
-
-
- }
- catch (Exception e)
- {
- e.printStackTrace();
- exceptionAndAlertHandler.handleMinorException(new MinorException(e.getMessage()));
- }
- }
-
- public void saveClientDetails(String[] sep)
- {
- try
- {
-
- Config.getInstance().setNickName(sep[1]);
-
- String oldWidth = Config.getInstance().getStartupWindowWidth()+"";
- String oldHeight = Config.getInstance().getStartupWindowHeight()+"";
-
-
- Config.getInstance().setStartupWindowSize(
- Double.parseDouble(sep[2]),
- Double.parseDouble(sep[3])
- );
-
- Config.getInstance().setStartupProfileID(sep[4]);
-
- String oldThemeFullName = Config.getInstance().getCurrentThemeFullName();
-
- Config.getInstance().setCurrentThemeFullName(sep[5]);
-
- if(!oldHeight.equals(sep[3]) || !oldWidth.equals(sep[2]) || !oldThemeFullName.equals(sep[5]))
- javafx.application.Platform.runLater(()-> clientListener.init());
-
-
- Config.getInstance().save();
- javafx.application.Platform.runLater(()->clientListener.loadSettings());
- }
- catch (SevereException e)
- {
- e.printStackTrace();
- exceptionAndAlertHandler.handleSevereException(e);
- }
- }
-
- public void saveProfileDetails(String[] sep) throws SevereException, MinorException
- {
- ClientProfile clientProfile = clientListener.getClientProfiles().getProfileFromID(sep[1]);
-
- if(clientProfile == null)
- {
- clientProfile = new ClientProfile(new File(Config.getInstance().getProfilesPath().toString()+"/"+sep[1]+".xml"),
- Config.getInstance().getIconsPath());
- }
-
- clientProfile.setName(sep[2]);
- clientProfile.setRows(Integer.parseInt(sep[3]));
- clientProfile.setCols(Integer.parseInt(sep[4]));
- clientProfile.setActionSize(Integer.parseInt(sep[5]));
- clientProfile.setActionGap(Integer.parseInt(sep[6]));
-
- try
- {
- clientListener.getClientProfiles().addProfile(clientProfile);
- clientProfile.saveProfileDetails();
- clientListener.refreshGridIfCurrent(sep[1]);
- javafx.application.Platform.runLater(()->clientListener.loadSettings());
- }
- catch (Exception e)
- {
- e.printStackTrace();
- throw new SevereException(e.getMessage());
- }
- }
-
- public void deleteProfile(String ID)
- {
- clientListener.getClientProfiles().deleteProfile(clientListener.getClientProfiles().getProfileFromID(ID));
- }
-
- public void onActionClicked(String profileID, String actionID) throws SevereException {
- writeToStream("action_clicked::"+profileID+"::"+actionID+"::");
- }
-
- public void actionFailed(String profileID, String actionID)
- {
- clientListener.onActionFailed(profileID, actionID);
- }
-}
--- 'a/src/main/java/com/StreamPi/Client/Connection/ClientListener.java'
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.StreamPi.Client.Connection;
-
-import com.StreamPi.ActionAPI.Action.Action;
-import com.StreamPi.ActionAPI.Action.Location;
-import com.StreamPi.Client.Profile.ClientProfile;
-import com.StreamPi.Client.Profile.ClientProfiles;
-import com.StreamPi.Client.Window.Dashboard.ActionGridPane.ActionBox;
-import com.StreamPi.Client.Window.FirstTimeUse.FirstTimeUse;
-import com.StreamPi.ThemeAPI.Theme;
-import com.StreamPi.ThemeAPI.Themes;
-import com.StreamPi.Util.Exception.MinorException;
-import com.StreamPi.Util.Exception.SevereException;
-import com.StreamPi.Util.Exception.StreamPiException;
-
-import javafx.stage.WindowEvent;
-
-public interface ClientListener {
- void onActionFailed(String profileID, String actionID);
- void onNormalActionClicked(String profileID, String actionID);
-
- ClientProfiles getClientProfiles();
-
- Themes getThemes();
- String getDefaultThemeFullName();
-
- void renderRootDefaultProfile() throws SevereException;
-
- void setConnected(boolean isConnected);
- boolean isConnected();
-
- void renderProfile(ClientProfile clientProfile);
-
- void clearActionBox(int col, int row);
- void addBlankActionBox(int col, int row);
- void renderAction(String currentProfileID, Action action);
- void refreshGridIfCurrent(String currentProfileID);
-
- ActionBox getActionBox(int col, int row);
-
- ClientProfile getCurrentProfile();
-
- Theme getCurrentTheme();
-
- void init();
-
- void disconnect(String message) throws SevereException;
-
- void setupClientConnection();
-
- void updateSettingsConnectDisconnectButton();
-
- void onCloseRequest();
-
- void loadSettings();
-}
--- 'a/src/main/java/com/StreamPi/Client/Connection/protos/ClientConnectionProtos.proto'
+++ /dev/null
@@ -1,49 +0,0 @@
-syntax = "proto3";
-
-package protos;
-
-option java_package = "com.StreamPi.Client.Connection.protos";
-option java_outer_classname = "ClientConnectionProtos";
-
-message ClientAction
-{
- string moduleName = 1;
- string id = 2;
-
- enum ActionType
- {
- FOLDER = 0;
- COMBINE = 1;
- NORMAL = 2;
- }
-
- ActionType actionType = 3;
- int32 locationX = 4;
- int32 locationY = 5;
- bool hasIcon = 6;
- string name = 7;
- string actionName = 8;
-
- repeated ClientProperty clientProperties = 9;
-}
-
-message ClientProperty
-{
- string name = 1;
- string value = 2;
-}
-
-message ClientProfile
-{
- string name = 1;
- string id = 2;
-
- int32 rows = 3;
- int32 cols = 4;
-
- int32 actionSize = 5;
- int32 actionGap = 6;
-
- repeated ClientAction actions = 7;
-}
-
--- 'a/src/main/java/com/StreamPi/Client/Connection/protos/ClientGRPC.proto'
+++ /dev/null
@@ -1,13 +0,0 @@
-syntax = "proto3";
-
-package protos;
-
-option java_package = "com.StreamPi.Client.Connection.protos";
-option java_outer_classname = "ClientGRPC";
-
-import "com/StreamPi/Client/Connection/protos/ClientConnectionProtos.proto";
-
-service Connection
-{
-
-}
\ No newline at end of file
--- 'a/src/main/java/com/StreamPi/Client/Controller/Controller.java'
+++ /dev/null
@@ -1,398 +0,0 @@
-package com.StreamPi.Client.Controller;
-
-import com.StreamPi.ActionAPI.Action.Action;
-import com.StreamPi.ActionAPI.Action.Location;
-import com.StreamPi.Client.Connection.Client;
-import com.StreamPi.Client.IO.Config;
-import com.StreamPi.Client.Info.ClientInfo;
-import com.StreamPi.Client.Main;
-import com.StreamPi.Client.Profile.ClientProfile;
-import com.StreamPi.Client.Profile.ClientProfiles;
-import com.StreamPi.Client.Window.Base;
-import com.StreamPi.Client.Window.Dashboard.ActionGridPane.ActionBox;
-import com.StreamPi.Client.Window.FirstTimeUse.FirstTimeUse;
-import com.StreamPi.Client.Window.Settings.SettingsBase;
-import com.StreamPi.Util.Alert.StreamPiAlert;
-import com.StreamPi.Util.Alert.StreamPiAlertListener;
-import com.StreamPi.Util.Alert.StreamPiAlertType;
-import com.StreamPi.Util.Exception.MinorException;
-import com.StreamPi.Util.Exception.SevereException;
-import com.StreamPi.Util.Exception.StreamPiException;
-import com.StreamPi.Util.IOHelper.IOHelper;
-import com.gluonhq.attach.lifecycle.LifecycleService;
-import com.gluonhq.attach.util.Services;
-
-import javafx.animation.Interpolator;
-import javafx.animation.KeyFrame;
-import javafx.animation.KeyValue;
-import javafx.animation.Timeline;
-import javafx.application.Platform;
-import javafx.beans.value.ChangeListener;
-import javafx.concurrent.Task;
-import javafx.event.Event;
-import javafx.scene.Node;
-import javafx.scene.Scene;
-import javafx.scene.control.Alert;
-import javafx.stage.Stage;
-import javafx.stage.StageStyle;
-import javafx.stage.WindowEvent;
-import javafx.util.Duration;
-
-import java.io.*;
-import java.net.URL;
-import java.nio.channels.Channels;
-import java.nio.channels.FileChannel;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
-import java.util.Enumeration;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-
-public class Controller extends Base
-{
- private Client client;
-
- public Controller()
- {
- client = null;
- }
-
-
- private boolean firstRun = true;
-
- @Override
- public void init()
- {
- try
- {
- if(firstRun)
- initBase();
-
-
- if(getClientInfo().getPlatformType()!= com.StreamPi.Util.Platform.Platform.ANDROID && getClientInfo().getPlatformType() != com.StreamPi.Util.Platform.Platform.IOS) {
- getStage().setWidth(getConfig().getStartupWindowWidth());
- getStage().setHeight(getConfig().getStartupWindowHeight());
- getStage().centerOnScreen();
- setupFlags();
- }
-
-
- setupDashWindow();
-
- getStage().show();
-
- requestFocus();
-
- if(Config.getInstance().isFirstTimeUse())
- return;
-
- setupSettingsWindowsAnimations();
-
-
-
- getDashboardPane().getSettingsButton().setOnAction(event -> {
- openSettingsTimeLine.play();
- });
-
- getSettingsPane().getCloseButton().setOnAction(event -> {
- closeSettingsTimeLine.play();
- });
-
- setClientProfiles(new ClientProfiles(new File(getConfig().getProfilesPath()), getConfig().getStartupProfileID()));
-
- if(getClientProfiles().getLoadingErrors().size() > 0)
- {
- StringBuilder errors = new StringBuilder("Please rectify the following errors and try again");
-
- for(MinorException exception : getClientProfiles().getLoadingErrors())
- {
- errors.append("\n * ")
- .append(exception.getMessage());
- }
-
- throw new MinorException("Profiles", errors.toString());
- }
-
- renderRootDefaultProfile();
- loadSettings();
-
- if(firstRun)
- {
- setupClientConnection();
- firstRun = false;
- }
-
- }
- catch (SevereException e)
- {
- handleSevereException(e);
- return;
- }
- catch (MinorException e)
- {
- handleMinorException(e);
- return;
- }
-
-
- }
-
-
-
- @Override
- public void setupClientConnection()
- {
- Platform.runLater(()->getSettingsPane().setDisableStatus(true));
- client = new Client(getConfig().getSavedServerHostNameOrIP(), getConfig().getSavedServerPort(), this, this);
- }
-
- @Override
- public void updateSettingsConnectDisconnectButton() {
- getSettingsPane().setConnectDisconnectButtonStatus();
- }
-
- @Override
- public void disconnect(String message) throws SevereException {
- client.disconnect(message);
- }
-
-
- public void setupDashWindow()
- {
- getStage().setTitle("Stream-Pi Client");
- getStage().setOnCloseRequest(e->onCloseRequest());
- }
-
-
- @Override
- public void onCloseRequest()
- {
- if(isConnected())
- client.exit();
-
-
- getLogger().info("Shut down");
- closeLogger();
-
- if (ClientInfo.getInstance().getPlatformType() == com.StreamPi.Util.Platform.Platform.ANDROID)
- Services.get(LifecycleService.class).ifPresent(LifecycleService::shutdown);
- }
-
- @Override
- public void loadSettings() {
- try {
- getSettingsPane().loadData();
- } catch (SevereException e) {
- e.printStackTrace();
- handleSevereException(e);
- }
- }
-
-
- private Timeline openSettingsTimeLine;
- private Timeline closeSettingsTimeLine;
-
-
- 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 KeyFrame(Duration.millis(90.0D),
- new KeyValue(settingsNode.opacityProperty(),
- 1.0D, Interpolator.LINEAR)),
-
- new KeyFrame(Duration.millis(0.0D),
- new KeyValue(dashboardNode.opacityProperty(),
- 1.0D, Interpolator.LINEAR)),
- new KeyFrame(Duration.millis(90.0D),
- new KeyValue(dashboardNode.opacityProperty(),
- 0.0D, 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 KeyFrame(Duration.millis(90.0D),
- new KeyValue(settingsNode.opacityProperty(),
- 0.0D, Interpolator.LINEAR)),
- new KeyFrame(Duration.millis(0.0D),
- new KeyValue(dashboardNode.opacityProperty(),
- 0.0D, Interpolator.LINEAR)),
- new KeyFrame(Duration.millis(90.0D),
- new KeyValue(dashboardNode.opacityProperty(),
- 1.0D, Interpolator.LINEAR))
- );
-
- closeSettingsTimeLine.setOnFinished(event1 -> {
- dashboardNode.toFront();
- Platform.runLater(()-> {
- try {
- getSettingsPane().loadData();
- } catch (SevereException e) {
- e.printStackTrace();
-
- handleSevereException(e);
- }
- });
- });
- }
-
-
-
-
-
- @Override
- public void handleMinorException(MinorException e)
- {
- Platform.runLater(()-> genNewAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.WARNING).show());
- }
-
- @Override
- public void handleSevereException(SevereException e)
- {
- Platform.runLater(()->
- {
- StreamPiAlert alert = genNewAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.ERROR);
-
- alert.setOnClicked(new StreamPiAlertListener()
- {
- @Override
- public void onClick(String txt)
- {
- onCloseRequest();
- Platform.exit();
- }
- });
- alert.show();
- });
- }
-
- @Override
- public void onAlert(String title, String body, StreamPiAlertType alertType) {
- Platform.runLater(()-> genNewAlert(title, body, alertType).show());
- }
-
- public StreamPiAlert genNewAlert(String title, String message, StreamPiAlertType alertType)
- {
- StreamPiAlert alert = new StreamPiAlert(title, message, alertType);
- return alert;
- }
-
-
- private boolean isConnected = false;
-
- @Override
- public void onActionFailed(String profileID, String actionID) {
- Platform.runLater(()-> getDashboardPane().getActionGridPane().actionFailed(profileID, actionID));
- }
-
- @Override
- public void onNormalActionClicked(String profileID, String actionID) {
- try {
- client.onActionClicked(profileID, actionID);
- } catch (SevereException e) {
- e.printStackTrace();
- handleSevereException(e);
- }
- }
-
- @Override
- public void setConnected(boolean isConnected) {
- this.isConnected = isConnected;
- }
-
- @Override
- public ActionBox getActionBox(int col, int row)
- {
- return getDashboardPane().getActionGridPane().getActionBox(col, row);
- }
-
- @Override
- public boolean isConnected()
- {
- return isConnected;
- }
-
- @Override
- public void renderProfile(ClientProfile clientProfile) {
- try {
- getDashboardPane().renderProfile(clientProfile);
- } catch (SevereException e) {
- e.printStackTrace();
- handleSevereException(e);
- }
- }
-
- @Override
- public void clearActionBox(int col, int row)
- {
- Platform.runLater(()->getDashboardPane().getActionGridPane().clearActionBox(col, row));
- }
-
- @Override
- public void addBlankActionBox(int col, int row)
- {
- Platform.runLater(()->getDashboardPane().getActionGridPane().addBlankActionBox(col, row));
- }
-
- @Override
- public void renderAction(String currentProfileID, Action action)
- {
- Platform.runLater(()->{
- try {
- if(getDashboardPane().getActionGridPane().getCurrentParent().equals(action.getParent()) &&
- getDashboardPane().getActionGridPane().getClientProfile().getID().equals(currentProfileID))
- {
- getDashboardPane().getActionGridPane().renderAction(action);
- }
-
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- });
- }
-
- @Override
- public void refreshGridIfCurrent(String profileID) {
- ClientProfile clientProfile = getDashboardPane().getActionGridPane().getClientProfile();
-
- if(clientProfile.getID().equals(profileID))
- {
- Platform.runLater(()->{
- try {
- getDashboardPane().renderProfile(getClientProfiles().getProfileFromID(profileID));
- } catch (SevereException e) {
- e.printStackTrace();
- handleSevereException(e);
- }
- });
- }
- }
-
- @Override
- public ClientProfile getCurrentProfile() {
- return getDashboardPane().getActionGridPane().getClientProfile();
- }
-
-}
--- 'a/src/main/java/com/StreamPi/Client/IO/Config.java'
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
-Config.java
-
-Contributor(s) : Debayan Sutradhar (@rnayabed)
-
-handler for config.xml
- */
-
-package com.StreamPi.Client.IO;
-
-import java.io.File;
-
-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.StreamPi.Client.Info.ClientInfo;
-import com.StreamPi.Util.Exception.SevereException;
-import com.StreamPi.Util.Platform.Platform;
-import com.StreamPi.Util.XMLConfigHelper.XMLConfigHelper;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class Config {
- private static Config instance = null;
-
- private final File configFile;
-
- private Document document;
-
- private Config() throws SevereException
- {
- try
- {
- configFile = new File(ClientInfo.getInstance().getPrePath()+"config.xml");
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
- document = docBuilder.parse(configFile);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- throw new SevereException("Config", "unable to read config.xml");
- }
- }
-
- public static synchronized Config getInstance() throws SevereException
- {
- if(instance == null)
- instance = new Config();
-
- return instance;
- }
-
- public void save() throws SevereException
- {
- 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 SevereException("Config", "unable to save config.xml");
- }
- }
-
-
- //Client Element
- public Element getClientElement()
- {
- return (Element) document.getElementsByTagName("client").item(0);
- }
-
- //Default Values
- public String getDefaultClientNickName()
- {
- return "StreamPi Client";
- }
-
- public String getDefaultStartupProfileID()
- {
- return "default";
- }
-
- public String getDefaultCurrentThemeFullName()
- {
- return "com.StreamPi.DefaultLight";
- }
-
- public String getDefaultThemesPath()
- {
- return "Themes/";
- }
-
- public String getDefaultProfilesPath()
- {
- return "Profiles/";
- }
-
- public String getDefaultIconsPath()
- {
- return "Icons/";
- }
-
- public int getDefaultStartupWindowWidth()
- {
- return 800;
- }
-
- public int getDefaultStartupWindowHeight()
- {
- return 400;
- }
-
- //Getters
-
- public String getClientNickName()
- {
- return XMLConfigHelper.getStringProperty(getClientElement(), "nickname", getDefaultClientNickName(), false, true, document, configFile);
- }
-
- public String getStartupProfileID()
- {
- return XMLConfigHelper.getStringProperty(getClientElement(), "startup-profile", getDefaultStartupProfileID(), false, true, document, configFile);
- }
-
- public String getCurrentThemeFullName()
- {
- return XMLConfigHelper.getStringProperty(getClientElement(), "current-theme-full-name", getDefaultCurrentThemeFullName(), false, true, document, configFile);
- }
-
- public String getThemesPath()
- {
- if(ClientInfo.getInstance().getPlatformType() == Platform.ANDROID)
- return ClientInfo.getInstance().getPrePath() + "Themes/";
-
- return XMLConfigHelper.getStringProperty(getClientElement(), "themes-path", getDefaultThemesPath(), false, true, document, configFile);
- }
-
- public String getProfilesPath()
- {
-
- if(ClientInfo.getInstance().getPlatformType() == Platform.ANDROID)
- return ClientInfo.getInstance().getPrePath() + "Profiles/";
-
- return XMLConfigHelper.getStringProperty(getClientElement(), "profiles-path", getDefaultThemesPath(), false, true, document, configFile);
- }
-
- public String getIconsPath()
- {
- if(ClientInfo.getInstance().getPlatformType() == Platform.ANDROID)
- return ClientInfo.getInstance().getPrePath() + "Icons/";
-
- return XMLConfigHelper.getStringProperty(getClientElement(), "icons-path", getDefaultThemesPath(), false, true, document, configFile);
- }
-
- public double getStartupWindowWidth()
- {
- return XMLConfigHelper.getDoubleProperty((Element) getClientElement().getElementsByTagName("startup-window-size").item(0), "width", getDefaultStartupWindowWidth(), false, true, document, configFile);
- }
-
- public double getStartupWindowHeight()
- {
- return XMLConfigHelper.getDoubleProperty((Element) getClientElement().getElementsByTagName("startup-window-size").item(0), "height", getDefaultStartupWindowHeight(), false, true, document, configFile);
- }
-
-
-
- //Setters
-
- public void setNickName(String nickName)
- {
- getClientElement().getElementsByTagName("nickname").item(0).setTextContent(nickName);
- }
-
- public void setStartupProfileID(String id)
- {
- getClientElement().getElementsByTagName("startup-profile").item(0).setTextContent(id);
- }
-
- public void setCurrentThemeFullName(String name)
- {
- getClientElement().getElementsByTagName("current-theme-full-name").item(0).setTextContent(name);
- }
-
- public void setProfilesPath(String profilesPath)
- {
- getClientElement().getElementsByTagName("profiles-path").item(0).setTextContent(profilesPath);
- }
-
- public void setIconsPath(String iconsPath)
- {
- getClientElement().getElementsByTagName("icons-path").item(0).setTextContent(iconsPath);
- }
-
- public void setThemesPath(String themesPath)
- {
- getClientElement().getElementsByTagName("themes-path").item(0).setTextContent(themesPath);
- }
-
- //client > startup-window-size
- public void setStartupWindowSize(double width, double height)
- {
- setStartupWindowWidth(width);
- setStartupWindowHeight(height);
- }
-
- public void setStartupWindowWidth(double width)
- {
- ((Element) getClientElement().getElementsByTagName("startup-window-size").item(0))
- .getElementsByTagName("width").item(0).setTextContent(width+"");
- }
-
- public void setStartupWindowHeight(double height)
- {
- ((Element) getClientElement().getElementsByTagName("startup-window-size").item(0))
- .getElementsByTagName("height").item(0).setTextContent(height+"");
- }
-
-
-
-
-
-
-
-
-
-
-
- //comms-server
- public Element getCommsServerElement()
- {
- return (Element) document.getElementsByTagName("comms-server").item(0);
- }
-
- public String getDefaultSavedServerHostNameOrIP()
- {
- return "127.0.0.1";
- }
-
- public int getDefaultSavedServerPort()
- {
- return -1;
- }
-
-
- public String getSavedServerHostNameOrIP()
- {
- return XMLConfigHelper.getStringProperty(getCommsServerElement(), "hostname-ip", getDefaultSavedServerHostNameOrIP(), false, true, document, configFile);
- }
-
- public int getSavedServerPort()
- {
- return XMLConfigHelper.getIntProperty(getCommsServerElement(), "port", getDefaultSavedServerPort(), false, true, document, configFile);
- }
-
-
- public void setServerHostNameOrIP(String hostNameOrIP)
- {
- getCommsServerElement().getElementsByTagName("hostname-ip").item(0).setTextContent(hostNameOrIP);
- }
-
- public void setServerPort(int port)
- {
- getCommsServerElement().getElementsByTagName("port").item(0).setTextContent(port+"");
- }
-
-
-
-
-
-
-
-
- //others
- public Element getOthersElement()
- {
- return (Element) document.getElementsByTagName("others").item(0);
- }
-
- //others-default
-
- public boolean getDefaultStartOnBoot()
- {
- return false;
- }
-
- public boolean getDefaultFullscreen()
- {
- return true;
- }
-
- public boolean getDefaultIsShowCursor()
- {
- return true;
- }
-
- public boolean getDefaultFirstTimeUse()
- {
- return true;
- }
-
-
-
- public boolean isShowCursor()
- {
- return XMLConfigHelper.getBooleanProperty(getOthersElement(), "show-cursor", getDefaultIsShowCursor(), false, true, document, configFile);
- }
-
-
- public boolean isStartOnBoot()
- {
- return XMLConfigHelper.getBooleanProperty(getOthersElement(), "start-on-boot", getDefaultStartOnBoot(), false, true, document, configFile);
- }
-
-
- public boolean isFullscreen()
- {
- return XMLConfigHelper.getBooleanProperty(getOthersElement(), "fullscreen", getDefaultFullscreen(), false, true, document, configFile);
- }
-
-
- public boolean isFirstTimeUse()
- {
- return XMLConfigHelper.getBooleanProperty(getOthersElement(), "first-time-use", true, false, true, document, configFile);
- }
-
-
- public void setStartOnBoot(boolean value)
- {
- getOthersElement().getElementsByTagName("start-on-boot").item(0).setTextContent(value+"");
- }
-
- public void setShowCursor(boolean value)
- {
- getOthersElement().getElementsByTagName("show-cursor").item(0).setTextContent(value+"");
- }
-
- public void setFullscreen(boolean value)
- {
- getOthersElement().getElementsByTagName("fullscreen").item(0).setTextContent(value+"");
- }
-
- public void setFirstTimeUse(boolean value)
- {
- getOthersElement().getElementsByTagName("first-time-use").item(0).setTextContent(value+"");
- }
-
-}
--- 'a/src/main/java/com/StreamPi/Client/Info/ClientInfo.java'
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
-ServerInfo.java
-
-Stores basic information about the server - name, platform type
-
-Contributors: Debayan Sutradhar (@dubbadhar)
- */
-
-package com.StreamPi.Client.Info;
-
-import java.io.File;
-import java.util.Optional;
-import java.util.function.Function;
-
-import com.StreamPi.Util.Exception.MinorException;
-import com.StreamPi.Util.Platform.Platform;
-import com.StreamPi.Util.Platform.ReleaseStatus;
-import com.StreamPi.Util.Version.Version;
-
-public class ClientInfo {
- private Version version;
- private final ReleaseStatus releaseStatus;
- private Platform platformType = null;
-
- private String prePath;
-
- private Version minThemeSupportVersion;
- private Version minPluginSupportVersion;
- private Version commsStandardVersion;
-
- private String runnerFileName;
-
- private static ClientInfo instance = null;
-
- private ClientInfo(){
-
- try {
- version = new Version("1.0.0");
- minThemeSupportVersion = new Version("1.0.0");
- minPluginSupportVersion = new Version("1.0.0");
- commsStandardVersion = new Version("1.0.0");
- } catch (MinorException e) {
- e.printStackTrace();
- }
-
- releaseStatus = ReleaseStatus.EA;
-
- if(platformType == null)
- {
- String osName = System.getProperty("os.name").toLowerCase();
-
- if(osName.contains("windows"))
- {
- prePath = "data/";
- platformType = Platform.WINDOWS;
- }
- else if (osName.contains("linux"))
- {
- if(osName.contains("raspberrypi"))
- {
- prePath = "data/";
- platformType = Platform.LINUX_RPI;
- }
- else
- {
- prePath = "data/";
- platformType = Platform.LINUX;
- }
- }
- else if(osName.contains("android")) // SPECIFY -Dsvm.targetName=android WHILE BUILDING ANDROID NATIVE IMAGE
- {
- prePath = "/sdcard/StreamPiClient/";
- platformType = Platform.ANDROID;
- }
- else if (osName.contains("mac"))
- {
- prePath = "data/";
- platformType = Platform.MAC;
- }
- else
- {
- prePath = "data/";
- platformType = Platform.UNKNOWN;
- }
- }
-
-
- }
-
- public void setRunnerFileName(String runnerFileName)
- {
- this.runnerFileName = runnerFileName;
- }
-
- public String getRunnerFileName()
- {
- return runnerFileName;
- }
-
- public static synchronized ClientInfo getInstance(){
- if(instance == null)
- {
- instance = new ClientInfo();
- }
-
- return instance;
- }
-
- private boolean isShowShutDownButton = false;
-
- public void setShowShutDownButton(boolean showShutDownButton) {
- isShowShutDownButton = showShutDownButton;
- }
-
- public boolean isShowShutDownButton() {
- return isShowShutDownButton;
- }
-
- public String getPrePath() {
- return prePath;
- }
-
- public Platform getPlatformType()
- {
- return platformType;
- }
-
- public Version getVersion() {
- return version;
- }
-
- public ReleaseStatus getReleaseStatus()
- {
- return releaseStatus;
- }
-
- public Version getMinThemeSupportVersion()
- {
- return minThemeSupportVersion;
- }
-
- public Version getMinPluginSupportVersion()
- {
- return minPluginSupportVersion;
- }
-
- public Version getCommsStandardVersion()
- {
- return commsStandardVersion;
- }
-}
--- 'a/src/main/java/com/StreamPi/Client/Info/License.java'
+++ /dev/null
@@ -1,41 +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.StreamPi.Client.Info;
-
-public class License {
- public static String getLicense()
- {
- return "Stream-Pi - Free & Open-Source Modular Cross-Platform Programmable Macro Pad\n" +
- "Copyright (C) 2019-2021 Debayan Sutradhar (rnayabed), Samuel Quiñones (SamuelQuinones)\n" +
- "\n" +
- "This program is free software: you can redistribute it and/or modify\n" +
- "it under the terms of the GNU General Public License as published by\n" +
- "the Free Software Foundation, either version 3 of the License, or\n" +
- "(at your option) any later version.\n" +
- "\n" +
- "This program is distributed in the hope that it will be useful,\n" +
- "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +
- "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +
- "GNU General Public License for more details.\n" +
- "\n\n"+
- "Opensource Libraries/Tech used :\n"+
- "1. JavaFX - GNU General Public License with Classpath Exception\nhttp://openjdk.java.net/legal/gplv2+ce.html\n\n"+
- "2. Gluon Attach - GPL License\nhttps://github.com/gluonhq/attach/blob/master/LICENSE\n\n"+
- "3. Gluon Client Maven Plugin - BSD-3 License\nhttps://github.com/gluonhq/client-maven-plugin/blob/master/LICENSE\n\n" +
- "4. Ikonli - Apache License\nhttps://github.com/kordamp/ikonli/blob/master/LICENSE\n\n";
- }
-}
--- 'a/src/main/java/com/StreamPi/Client/Main.java'
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.StreamPi.Client;
-
-import com.StreamPi.Client.Controller.Controller;
-import com.StreamPi.Client.Info.ClientInfo;
-
-import javafx.application.Application;
-import javafx.scene.Scene;
-import javafx.stage.Stage;
-
-public class Main extends Application {
-
-
- @Override
- public void start(Stage stage)
- {
- Controller d = new Controller();
- Scene s = new Scene(d);
- stage.setScene(s);
- d.init();
- }
-
-
- public static void main(String[] args)
- {
- for(String eachArg : args)
- {
- String[] r = eachArg.split("=");
- if(r[0].equals("-DStreamPi.startupRunnerFileName"))
- ClientInfo.getInstance().setRunnerFileName(r[1]);
- else if(r[0].equals("-DStreamPi.showShutDownButton"))
- ClientInfo.getInstance().setShowShutDownButton(r[1].equals("true"));
- }
-
- launch(args);
- }
-}
--- 'a/src/main/java/com/StreamPi/Client/Profile/ClientProfile.java'
+++ /dev/null
@@ -1,682 +0,0 @@
-package com.StreamPi.Client.Profile;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.file.Files;
-import java.nio.file.NoSuchFileException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.logging.Logger;
-
-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.StreamPi.ActionAPI.Action.Action;
-import com.StreamPi.ActionAPI.Action.ActionType;
-import com.StreamPi.ActionAPI.Action.DisplayTextAlignment;
-import com.StreamPi.ActionAPI.Action.Location;
-import com.StreamPi.ActionAPI.ActionProperty.ClientProperties;
-import com.StreamPi.ActionAPI.ActionProperty.Property.Property;
-import com.StreamPi.ActionAPI.ActionProperty.Property.Type;
-import com.StreamPi.Client.Info.ClientInfo;
-import com.StreamPi.Util.Exception.MinorException;
-import com.StreamPi.Util.Version.Version;
-import com.StreamPi.Util.XMLConfigHelper.XMLConfigHelper;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-public class ClientProfile implements Cloneable{
- private String name, ID;
-
- private int rows, cols, actionSize, actionGap;
-
-
- private HashMap<String, Action> actions;
- private String iconsPath;
-
- private File file;
-
- private Logger logger;
- private Document document;
-
- public ClientProfile(File file, String iconsPath) throws MinorException
- {
- this.file = file;
- this.iconsPath = iconsPath;
-
- actions = new HashMap<>();
-
- logger = Logger.getLogger(ClientProfile.class.getName());
-
- if(!file.exists() && !file.isFile())
- createConfigFile(file);
-
- try
- {
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
- document = docBuilder.parse(file);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- throw new MinorException("Profile", "Unable to read profile config file.");
- }
-
-
- setID(file.getName().replace(".xml", ""));
- load();
- }
-
-
- private Element getProfileElement()
- {
- return (Element) document.getElementsByTagName("profile").item(0);
- }
-
- private Element getActionsElement()
- {
- return (Element) document.getElementsByTagName("actions").item(0);
- }
-
- public void load() throws MinorException
- {
- try
- {
- actions.clear();
-
- logger.info("Loading profile "+getID()+" ...");
-
- String name = XMLConfigHelper.getStringProperty(getProfileElement(), "name");
- int rows = XMLConfigHelper.getIntProperty(getProfileElement(), "rows");
- int cols = XMLConfigHelper.getIntProperty(getProfileElement(), "cols");
- int actionSize = XMLConfigHelper.getIntProperty(getProfileElement(), "action-size");
- int actionGap = XMLConfigHelper.getIntProperty(getProfileElement(), "action-gap");
-
- setName(name);
- setRows(rows);
- setCols(cols);
- setActionSize(actionSize);
- setActionGap(actionGap);
-
-
- //Load Actions
-
- NodeList actionsNodesList = getActionsElement().getChildNodes();
-
- int actionsSize = actionsNodesList.getLength();
-
- logger.info("Actions Size : "+actionsSize);
-
- for(int item = 0; item<actionsSize; item++)
- {
- Node eachActionNode = actionsNodesList.item(item);
-
- if(eachActionNode.getNodeType() != Node.ELEMENT_NODE)
- continue;
-
- Element eachActionElement = (Element) eachActionNode;
-
- if(!eachActionElement.getNodeName().equals("action"))
- continue;
-
-
-
- String id = XMLConfigHelper.getStringProperty(eachActionElement, "id");
- String parent = XMLConfigHelper.getStringProperty(eachActionElement, "parent");
-
- logger.info("Loading action "+id+" ...");
-
- ActionType actionType = ActionType.valueOf(XMLConfigHelper.getStringProperty(eachActionElement, "action-type"));
-
- Action action = new Action(id, actionType);
- action.setParent(parent);
-
- ClientProperties properties = new ClientProperties();
-
- if(actionType == ActionType.FOLDER)
- properties.setDuplicatePropertyAllowed(true);
-
-
- if(actionType == ActionType.NORMAL)
- {
- action.setVersion(new Version(XMLConfigHelper.getStringProperty(eachActionElement, "version")));
- action.setModuleName(XMLConfigHelper.getStringProperty(eachActionElement, "module-name"));
- }
-
- Node propertiesNode = eachActionElement.getElementsByTagName("properties").item(0);
-
- NodeList propertiesNodesList = propertiesNode.getChildNodes();
-
- int propertiesSize = propertiesNodesList.getLength();
-
- for(int propItem = 0; propItem < propertiesSize; propItem++)
- {
- Node eachPropertyNode = propertiesNodesList.item(propItem);
-
- if(eachPropertyNode.getNodeType() != Node.ELEMENT_NODE)
- continue;
-
- Element eachPropertyElement = (Element) eachPropertyNode;
-
- if(eachPropertyElement.getNodeName() != "property")
- continue;
-
-
-
- String propertyName = XMLConfigHelper.getStringProperty(eachPropertyElement, "name");
- String propertyValue = XMLConfigHelper.getStringProperty(eachPropertyElement, "value");
-
- logger.info("Property Name : "+propertyName);
- logger.info("Property Value : "+propertyValue);
-
- Property p = new Property(propertyName, Type.STRING);
- p.setRawValue(propertyValue);
-
- properties.addProperty(p);
- }
-
- action.setClientProperties(properties);
-
-
-
- Element displayElement = (Element) eachActionElement.getElementsByTagName("display").item(0);
-
- //display
-
- //location
-
- try
- {
- Element locationElement = (Element) displayElement.getElementsByTagName("location").item(0);
- int row = XMLConfigHelper.getIntProperty(locationElement, "row");
- int col = XMLConfigHelper.getIntProperty(locationElement, "col");
- action.setLocation(new Location(row, col));
- }
- catch (Exception e)
- {
- logger.info("Action has no location, most probably a combine action child");
- }
-
- //background
-
- Element backgroundElement = (Element) displayElement.getElementsByTagName("background").item(0);
-
- action.setBgColourHex(XMLConfigHelper.getStringProperty(backgroundElement, "colour-hex"));
-
- Element iconElement = (Element) backgroundElement.getElementsByTagName("icon").item(0);
-
- boolean showIcon = XMLConfigHelper.getBooleanProperty(iconElement, "show");
- boolean hasIcon = XMLConfigHelper.getBooleanProperty(iconElement, "has");
-
- Element textElement = (Element) displayElement.getElementsByTagName("text").item(0);
-
- boolean showText = XMLConfigHelper.getBooleanProperty(textElement, "show");
- String displayTextFontColour = XMLConfigHelper.getStringProperty(textElement, "colour-hex");
- DisplayTextAlignment displayTextAlignment = DisplayTextAlignment.valueOf(XMLConfigHelper.getStringProperty(textElement, "alignment"));
-
-
- action.setDisplayTextAlignment(displayTextAlignment);
- action.setShowIcon(showIcon);
- action.setHasIcon(hasIcon);
- action.setShowDisplayText(showText);
-
- action.setDisplayTextFontColourHex(displayTextFontColour);
-
-
- String displayText = XMLConfigHelper.getStringProperty(textElement, "display-text");
-
- action.setDisplayText(displayText);
-
-
-
- if(hasIcon)
- {
- File f = new File(iconsPath+"/"+id);
-
- try
- {
- byte[] iconFileByteArray = Files.readAllBytes(f.toPath());
- action.setIcon(iconFileByteArray);
- }
- catch(NoSuchFileException e)
- {
- action.setIcon(null);
- action.setHasIcon(false);
- action.setShowIcon(false);
- saveAction(action);
- }
- }
-
-
-
- addAction(action);
-
-
- logger.info("... Done!");
- }
-
- logger.info("Loaded profile "+getID()+" ("+getName()+") !");
- }
- catch (Exception e)
- {
- e.printStackTrace();
-
- throw new MinorException("Profile", "Profile is corrupt.");
- }
-
- }
-
- public void addAction(Action action) throws CloneNotSupportedException {
- actions.put(action.getID(), (Action) action.clone());
- }
-
-
-
-
- private void createConfigFile(File file) throws MinorException
- {
- try
- {
- file.createNewFile();
-
- DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
- Document newDocument = dBuilder.newDocument();
-
-
- Element rootElement = newDocument.createElement("config");
- newDocument.appendChild(rootElement);
-
- Element profileElement = newDocument.createElement("profile");
- rootElement.appendChild(profileElement);
-
- Element actionsElement = newDocument.createElement("actions");
- rootElement.appendChild(actionsElement);
-
- Element nameElement = newDocument.createElement("name");
- nameElement.setTextContent("Untitled Profile");
- profileElement.appendChild(nameElement);
-
- Element rowsElement = newDocument.createElement("rows");
- rowsElement.setTextContent("3");
- profileElement.appendChild(rowsElement);
-
- Element colsElement = newDocument.createElement("cols");
- colsElement.setTextContent("3");
- profileElement.appendChild(colsElement);
-
- Element actionSizeElement = newDocument.createElement("action-size");
- actionSizeElement.setTextContent("100");
- profileElement.appendChild(actionSizeElement);
-
- Element actionGapElement = newDocument.createElement("action-gap");
- actionGapElement.setTextContent("5");
- profileElement.appendChild(actionGapElement);
-
-
-
-
- TransformerFactory transformerFactory = TransformerFactory.newInstance();
- Transformer transformer = transformerFactory.newTransformer();
- DOMSource source = new DOMSource(newDocument);
- StreamResult result = new StreamResult(file);
- transformer.transform(source, result);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- throw new MinorException(e.getMessage());
- }
- }
-
-
-
- public void deleteProfile()
- {
- file.delete();
- }
-
-
- public void saveAction(Action action) throws Exception {
-
- Element newActionElement = document.createElement("action");
- getActionsElement().appendChild(newActionElement);
-
- Element idElement = document.createElement("id");
- idElement.setTextContent(action.getID());
- newActionElement.appendChild(idElement);
-
- Element parentElement = document.createElement("parent");
- parentElement.setTextContent(action.getParent());
- newActionElement.appendChild(parentElement);
-
- Element actionTypeElement = document.createElement("action-type");
- actionTypeElement.setTextContent(action.getActionType()+"");
- newActionElement.appendChild(actionTypeElement);
-
- if(action.getActionType() == ActionType.NORMAL)
- {
- Element versionElement = document.createElement("version");
- versionElement.setTextContent(action.getVersion().getText());
- newActionElement.appendChild(versionElement);
-
- System.out.println(action.getModuleName());
-
- Element moduleNameElement = document.createElement("module-name");
- moduleNameElement.setTextContent(action.getModuleName());
- newActionElement.appendChild(moduleNameElement);
- }
-
- Element displayElement = document.createElement("display");
- newActionElement.appendChild(displayElement);
-
- Element backgroundElement = document.createElement("background");
- displayElement.appendChild(backgroundElement);
-
- Element colourHexElement = document.createElement("colour-hex");
- colourHexElement.setTextContent(action.getBgColourHex());
- backgroundElement.appendChild(colourHexElement);
-
- Element iconElement = document.createElement("icon");
-
- Element iconShowElement = document.createElement("show");
- iconShowElement.setTextContent(action.isShowIcon()+"");
- iconElement.appendChild(iconShowElement);
-
- Element iconHasElement = document.createElement("has");
- iconHasElement.setTextContent(action.isHasIcon()+"");
- iconElement.appendChild(iconHasElement);
-
- backgroundElement.appendChild(iconElement);
-
- Element textElement = document.createElement("text");
- displayElement.appendChild(textElement);
-
- Element textTolourHexElement = document.createElement("colour-hex");
- textTolourHexElement.setTextContent(action.getDisplayTextFontColourHex());
- textElement.appendChild(textTolourHexElement);
-
- Element textShowElement = document.createElement("show");
- textShowElement.setTextContent(action.isShowDisplayText()+"");
- textElement.appendChild(textShowElement);
-
- Element textDisplayTextElement = document.createElement("display-text");
- textDisplayTextElement.setTextContent(action.getDisplayText());
- textElement.appendChild(textDisplayTextElement);
-
- Element textAlignmentElement = document.createElement("alignment");
- textAlignmentElement.setTextContent(action.getDisplayTextAlignment()+"");
- textElement.appendChild(textAlignmentElement);
-
-
- Element locationElement = document.createElement("location");
- displayElement.appendChild(locationElement);
-
- Element colElement = document.createElement("col");
- colElement.setTextContent(action.getLocation().getCol()+"");
- locationElement.appendChild(colElement);
-
- Element rowElement = document.createElement("row");
- rowElement.setTextContent(action.getLocation().getRow()+"");
- locationElement.appendChild(rowElement);
-
-
- Element propertiesElement = document.createElement("properties");
- newActionElement.appendChild(propertiesElement);
-
- for(String key : action.getClientProperties().getNames())
- {
- for(Property eachProperty : action.getClientProperties().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 int getActionIndexInConfig(String actionID)
- {
- NodeList actionsList = getActionsElement().getChildNodes();
-
- int actionsSize = actionsList.getLength();
-
- int index = 0;
-
- for(int i = 0;i<actionsSize;i++)
- {
- Node eachActionNode = actionsList.item(index);
-
- if(eachActionNode.getNodeType() != Node.ELEMENT_NODE)
- continue;
-
- if(!eachActionNode.getNodeName().equals("action"))
- continue;
-
- Element eachActionElement = (Element) eachActionNode;
-
- Element idElement = (Element) eachActionElement.getElementsByTagName("id").item(0);
-
-
- if(idElement.getTextContent().equals(actionID))
- return index;
-
-
- index++;
- }
-
-
- return -1;
- }
-
- public void saveActionIcon(String actionID, byte[] array){
- int index = getActionIndexInConfig(actionID);
-
- getActionFromID(actionID).setIcon(array);
-
- File iconFile = new File(iconsPath+"/"+actionID);
- if(iconFile.exists())
- {
- boolean result = iconFile.delete();
- System.out.println("result : "+result);
- }
-
- try
- {
- OutputStream outputStream = new FileOutputStream(iconFile);
- outputStream.write(array);
- outputStream.flush();
- outputStream.close();
-
- Element actionElement = (Element) getActionsElement().getElementsByTagName("action").item(index);
-
- Element displayElement = (Element) actionElement.getElementsByTagName("display").item(0);
- Element backgroundElement = (Element) displayElement.getElementsByTagName("background").item(0);
- Element iconElement = (Element) backgroundElement.getElementsByTagName("icon").item(0);
-
- Element hasElement = (Element) iconElement.getElementsByTagName("has").item(0);
- hasElement.setTextContent("true");
-
- save();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- private void save() throws Exception
- {
- Transformer transformer = TransformerFactory.newInstance().newTransformer();
- Result output = new StreamResult(file);
- Source input = new DOMSource(document);
-
- transformer.transform(input, output);
- }
-
- public void saveProfileDetails() throws Exception {
- XMLConfigHelper.removeChilds(getProfileElement());
-
- Element nameElement = document.createElement("name");
- nameElement.setTextContent(getName());
- getProfileElement().appendChild(nameElement);
-
- Element rowsElement = document.createElement("rows");
- rowsElement.setTextContent(getRows()+"");
- getProfileElement().appendChild(rowsElement);
-
- Element colsElement = document.createElement("cols");
- colsElement.setTextContent(getCols()+"");
- getProfileElement().appendChild(colsElement);
-
- Element actionSizeElement = document.createElement("action-size");
- actionSizeElement.setTextContent(getActionSize()+"");
- getProfileElement().appendChild(actionSizeElement);
-
- Element actionGapElement = document.createElement("action-gap");
- actionGapElement.setTextContent(getActionGap()+"");
- getProfileElement().appendChild(actionGapElement);
-
- save();
- }
-
- public void saveActions() throws Exception
- {
- XMLConfigHelper.removeChilds(getActionsElement());
- save();
- for(Action action : getActions())
- {
- logger.info("ACTION ID :"+action.getID());
- logger.info("Action ICON : "+action.isHasIcon());
- saveAction(action);
- }
- }
-
-
-
- public void removeAction(String ID) throws Exception {
- int index = getActionIndexInConfig(ID);
-
- if(index>-1)
- {
-
- Element actionElement = (Element) getActionsElement().getElementsByTagName("action").item(index);
-
- Element displayElement = (Element) actionElement.getElementsByTagName("display").item(0);
- Element backgroundElement = (Element) displayElement.getElementsByTagName("background").item(0);
- Element iconElement = (Element) backgroundElement.getElementsByTagName("icon").item(0);
-
- if(XMLConfigHelper.getBooleanProperty(iconElement, "has"))
- {
- File file = new File(ClientInfo.getInstance().getPrePath()+iconsPath+"/"+ID);
-
- System.out.println(file.delete());
- }
- actions.remove(ID);
- }
-
- }
-
- public ArrayList<Action> getActions()
- {
- ArrayList<Action> p = new ArrayList<>();
- for(String profile : actions.keySet())
- p.add(actions.get(profile));
- return p;
- }
-
- public String getID()
- {
- return ID;
- }
-
- public String getName()
- {
- return name;
- }
-
- public int getRows()
- {
- return rows;
- }
-
- public int getCols()
- {
- return cols;
- }
-
- public int getActionSize()
- {
- return actionSize;
- }
-
- public Action getActionFromID(String ID)
- {
- return actions.getOrDefault(ID, null);
- }
-
- public int getActionGap()
- {
- return actionGap;
- }
-
- public void setRows(int rows)
- {
- this.rows = rows;
- }
-
- public void setCols(int cols)
- {
- this.cols = cols;
- }
-
- public void setID(String ID)
- {
- this.ID = ID;
- }
-
- public void setActionSize(int actionSize)
- {
- this.actionSize = actionSize;
- }
-
- public void setActionGap(int actionGap)
- {
- this.actionGap = actionGap;
- }
-
- public void setName(String name)
- {
- this.name = name;
- }
-
-
- public Object clone() throws CloneNotSupportedException
- {
- return super.clone();
- }
-}
--- 'a/src/main/java/com/StreamPi/Client/Profile/ClientProfiles.java'
+++ /dev/null
@@ -1,121 +0,0 @@
-package com.StreamPi.Client.Profile;
-
-import com.StreamPi.ActionAPI.Action.Action;
-import com.StreamPi.Client.IO.Config;
-import com.StreamPi.Util.Exception.MinorException;
-import com.StreamPi.Util.Exception.SevereException;
-
-import java.io.File;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.logging.Logger;
-
-public class ClientProfiles {
-
-
- private File profilesFolder;
- private String defaultProfileID;
-
- private Logger logger;
-
- public ClientProfiles(File profilesFolder, String defaultProfileID) throws SevereException
- {
- logger = Logger.getLogger(ClientProfiles.class.getName());
-
- this.defaultProfileID = defaultProfileID;
- this.profilesFolder = profilesFolder;
- clientProfiles = new HashMap<>();
- loadingErrors = new ArrayList<>();
-
- loadProfiles();
- }
-
- public void addProfile(ClientProfile clientProfile) throws CloneNotSupportedException {
- clientProfiles.put(clientProfile.getID(), (ClientProfile) clientProfile.clone());
- }
-
- public void deleteProfile(ClientProfile clientProfile)
- {
- clientProfiles.remove(clientProfile.getID());
-
- clientProfile.deleteProfile();
- }
-
- private ArrayList<MinorException> loadingErrors;
- private HashMap<String, ClientProfile> clientProfiles;
-
- public void loadProfiles() throws SevereException
- {
- logger.info("Loading profiles ...");
-
-
- String iconsPath = Config.getInstance().getIconsPath();
-
- clientProfiles.clear();
- loadingErrors.clear();
-
- if(!profilesFolder.isDirectory())
- {
- throw new SevereException("Profiles","Profile folder doesn't exist! Cant continue.");
- }
-
-
- File[] profilesFiles = profilesFolder.listFiles();
- if(profilesFiles == null)
- {
- throw new SevereException("Profiles","profilesFiles returned null. Cant continue!");
- }
-
- for(File eachProfileFile : profilesFiles)
- {
- try
- {
- ClientProfile profile = new ClientProfile(eachProfileFile, iconsPath);
- try
- {
- addProfile(profile);
- }
- catch (CloneNotSupportedException e)
- {
- e.printStackTrace();
- throw new SevereException(e.getMessage());
- }
- }
- catch (MinorException e)
- {
- if(eachProfileFile.getName().replace(".xml","").equals(defaultProfileID))
- {
- throw new SevereException("Profiles", "Default Profile bad. Can't continue");
- }
-
- loadingErrors.add(new MinorException(e.getMessage()+" ("+eachProfileFile.getName().replace(".xml", "")));
-
- e.printStackTrace();
- }
- }
-
- logger.info("Loaded all profiles!");
- }
-
- public ArrayList<MinorException> getLoadingErrors()
- {
- return loadingErrors;
- }
-
- public ArrayList<ClientProfile> getClientProfiles()
- {
- ArrayList<ClientProfile> p = new ArrayList<>();
- for(String profile : clientProfiles.keySet())
- p.add(clientProfiles.get(profile));
- return p;
- }
-
- public ClientProfile getProfileFromID(String profileID)
- {
- return clientProfiles.getOrDefault(profileID, null);
- }
-
-
-
-}
--- 'a/src/main/java/com/StreamPi/Client/Window/Base.java'
+++ /dev/null
@@ -1,384 +0,0 @@
-package com.StreamPi.Client.Window;
-
-import com.StreamPi.Client.Connection.ClientListener;
-import com.StreamPi.Client.IO.Config;
-import com.StreamPi.Client.Info.ClientInfo;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.logging.Logger;
-
-import com.StreamPi.Client.Main;
-import com.StreamPi.Client.Profile.ClientProfiles;
-import com.StreamPi.Client.Window.Dashboard.DashboardBase;
-import com.StreamPi.Client.Window.FirstTimeUse.FirstTimeUse;
-import com.StreamPi.Client.Window.Settings.SettingsBase;
-import com.StreamPi.ThemeAPI.Theme;
-import com.StreamPi.ThemeAPI.Themes;
-import com.StreamPi.Util.Alert.StreamPiAlert;
-import com.StreamPi.Util.ComboBox.StreamPiComboBox;
-import com.StreamPi.Util.Exception.MinorException;
-import com.StreamPi.Util.Exception.SevereException;
-import com.StreamPi.Util.IOHelper.IOHelper;
-import com.StreamPi.Util.LoggerHelper.StreamPiLogFallbackHandler;
-import com.StreamPi.Util.LoggerHelper.StreamPiLogFileHandler;
-import com.StreamPi.Util.Platform.Platform;
-import com.gluonhq.attach.lifecycle.LifecycleService;
-import com.gluonhq.attach.util.Services;
-
-import javafx.geometry.Dimension2D;
-import javafx.scene.CacheHint;
-import javafx.scene.Cursor;
-import javafx.scene.input.KeyCombination;
-import javafx.scene.layout.StackPane;
-import javafx.scene.text.Font;
-import javafx.stage.Stage;
-
-public abstract class Base extends StackPane implements ExceptionAndAlertHandler, ClientListener {
-
- private Config config;
-
- private ClientProfiles clientProfiles;
-
- private ClientInfo clientInfo;
-
- private Stage stage;
-
- public Stage getStage()
- {
- return stage;
- }
-
- public Logger getLogger()
- {
- return logger;
- }
-
- private DashboardBase dashboardBase;
- private SettingsBase settingsBase;
-
- private FirstTimeUse firstTimeUse;
-
- public FirstTimeUse getFirstTimeUse() {
- return firstTimeUse;
- }
-
-
- private StackPane alertStackPane;
-
- @Override
- public ClientProfiles getClientProfiles() {
- return clientProfiles;
- }
-
- public void setClientProfiles(ClientProfiles clientProfiles) {
- this.clientProfiles = clientProfiles;
- }
-
- private Logger logger = null;
- private StreamPiLogFileHandler logFileHandler = null;
- private StreamPiLogFallbackHandler logFallbackHandler = null;
-
- public void initLogger()
- {
- try
- {
- if(logger != null || logFileHandler != null)
- return;
-
- closeLogger();
- logger = Logger.getLogger("");
-
- if(new File(ClientInfo.getInstance().getPrePath()).getAbsoluteFile().getParentFile().canWrite())
- {
-
- String path = ClientInfo.getInstance().getPrePath()+"../streampi.log";
-
- if(ClientInfo.getInstance().getPlatformType() == Platform.ANDROID)
- path = ClientInfo.getInstance().getPrePath()+"streampi.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!");
- }
- }
-
- public void closeLogger()
- {
- if(logFileHandler != null)
- logFileHandler.close();
- else if(logFallbackHandler != null)
- logFallbackHandler.close();
- }
-
- public void initBase() throws SevereException
- {
-
- stage = (Stage) getScene().getWindow();
-
- initLogger();
-
- clientInfo = ClientInfo.getInstance();
- dashboardBase = new DashboardBase(this, this);
- dashboardBase.setCache(true);
- dashboardBase.setCacheHint(CacheHint.SPEED);
- dashboardBase.prefWidthProperty().bind(widthProperty());
- dashboardBase.prefHeightProperty().bind(heightProperty());
-
- settingsBase = new SettingsBase(this, this);
- settingsBase.setCache(true);
- settingsBase.setCacheHint(CacheHint.SPEED);
-
- alertStackPane = new StackPane();
- alertStackPane.setVisible(false);
-
- StreamPiAlert.setParent(alertStackPane);
- StreamPiComboBox.setParent(alertStackPane);
-
- firstTimeUse = new FirstTimeUse(this, this);
-
- getChildren().clear();
- getChildren().addAll(settingsBase, dashboardBase, alertStackPane);
-
- setStyle(null);
- clearStylesheets();
- applyDefaultStylesheet();
-
- checkPrePathDirectory();
-
- config = Config.getInstance();
-
- if(config.isFirstTimeUse())
- {
- getChildren().add(firstTimeUse);
- firstTimeUse.toFront();
- }
- else
- {
- dashboardBase.toFront();
- }
-
- initThemes();
- }
-
- private void checkPrePathDirectory() throws SevereException
- {
- try
- {
- File filex = new File(ClientInfo.getInstance().getPrePath());
-
- if(filex.getAbsoluteFile().getParentFile().canWrite())
- {
- if(!filex.exists())
- {
- filex.mkdirs();
- IOHelper.unzip(Main.class.getResourceAsStream("Default.obj"), ClientInfo.getInstance().getPrePath());
- }
- }
- else
- {
- throw new SevereException("No storage permission. Give it!");
- }
-
- }
- catch (Exception e)
- {
- e.printStackTrace();
- throw new SevereException(e.getMessage());
- }
- }
-
- public void setupFlags()
- {
- //Full Screen
- if(getConfig().isFullscreen())
- {
- getStage().setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
- getStage().setFullScreen(true);
- }
- else
- {
- getStage().setFullScreenExitKeyCombination(KeyCombination.keyCombination("Esc"));
- getStage().setFullScreen(false);
- }
-
- //Cursor
- if(getConfig().isShowCursor())
- {
- setCursor(Cursor.DEFAULT);
- }
- else
- {
- setCursor(Cursor.NONE);
- }
- }
-
-
- public SettingsBase getSettingsPane() {
- return settingsBase;
- }
-
- public DashboardBase getDashboardPane() {
- return dashboardBase;
- }
-
- public void renderRootDefaultProfile() throws SevereException {
- getDashboardPane().renderProfile(getClientProfiles().getProfileFromID(
- Config.getInstance().getStartupProfileID()
- ));
- }
-
-
-
- public void clearStylesheets()
- {
- getStylesheets().clear();
- }
-
- public void initThemes() throws SevereException
- {
- registerThemes();
-
- applyDefaultTheme();
- }
-
-
-
- public void applyDefaultStylesheet()
- {
- Font.loadFont(Main.class.getResourceAsStream("Roboto.ttf"), 13);
- getStylesheets().add(Main.class.getResource("style.css").toExternalForm());
- }
-
-
-
- public Config getConfig()
- {
- return config;
- }
-
- public ClientInfo getClientInfo()
- {
- return clientInfo;
- }
-
- private Theme currentTheme;
-
- @Override
- public Theme getCurrentTheme()
- {
- return currentTheme;
- }
-
-
- public void applyTheme(Theme t)
- {
- logger.info("Applying theme '"+t.getFullName()+"' ...");
-
- if(t.getFonts() != null)
- {
- for(String fontFile : t.getFonts())
- {
- Font.loadFont(fontFile.replace("%20",""), 13);
- }
- }
- currentTheme = t;
- getStylesheets().addAll(t.getStylesheets());
-
- logger.info("... Done!");
- }
-
- Themes themes;
- public void registerThemes() throws SevereException
- {
- logger.info("Loading themes ...");
- themes = new Themes(getConfig().getThemesPath(), getConfig().getCurrentThemeFullName(), clientInfo.getMinThemeSupportVersion());
-
-
- if(themes.getErrors().size()>0)
- {
- StringBuilder themeErrors = new StringBuilder();
-
- for(MinorException eachException : themes.getErrors())
- {
- themeErrors.append("\n * ").append(eachException.getShortMessage());
- }
-
- if(themes.getIsBadThemeTheCurrentOne())
- {
- themeErrors.append("\n\nReverted to default theme! (").append(getConfig().getDefaultCurrentThemeFullName()).append(")");
-
- getConfig().setCurrentThemeFullName(getConfig().getDefaultCurrentThemeFullName());
- getConfig().save();
- }
-
- handleMinorException(new MinorException("Theme Loading issues", themeErrors.toString()));
- }
-
- logger.info("... Done!");
- }
-
- @Override
- public Themes getThemes() {
- return themes;
- }
-
-
-
- public void applyDefaultTheme()
- {
- logger.info("Applying default theme ...");
-
-
- boolean foundTheme = false;
- for(Theme t: themes.getThemeList())
- {
- if(t.getFullName().equals(config.getCurrentThemeFullName()))
- {
- foundTheme = true;
- applyTheme(t);
- break;
- }
- }
-
- if(foundTheme)
- {
- logger.info("... Done!");
- }
- else
- {
- logger.info("Theme not found. reverting to light theme ...");
- try {
- Config.getInstance().setCurrentThemeFullName("com.StreamPi.DefaultLight");
- Config.getInstance().save();
-
- applyDefaultTheme();
- }
- catch (SevereException e)
- {
- handleSevereException(e);
- }
- }
-
-
- }
-
- @Override
- public String getDefaultThemeFullName()
- {
- return config.getCurrentThemeFullName();
- }
-
-
-}
--- 'a/src/main/java/com/StreamPi/Client/Window/Dashboard/ActionGridPane/ActionBox.java'
+++ /dev/null
@@ -1,333 +0,0 @@
-package com.StreamPi.Client.Window.Dashboard.ActionGridPane;
-
-import com.StreamPi.ActionAPI.Action.Action;
-import com.StreamPi.ActionAPI.Action.ActionType;
-import com.StreamPi.ActionAPI.Action.DisplayTextAlignment;
-import com.StreamPi.ActionAPI.Action.Location;
-import com.StreamPi.Client.Main;
-import com.StreamPi.Client.IO.Config;
-import com.StreamPi.Client.Window.ExceptionAndAlertHandler;
-import com.StreamPi.Util.Exception.MinorException;
-import javafx.animation.Interpolator;
-import javafx.animation.KeyFrame;
-import javafx.animation.KeyValue;
-import javafx.animation.Timeline;
-import javafx.geometry.Insets;
-import javafx.geometry.Pos;
-import javafx.scene.CacheHint;
-import javafx.scene.control.Label;
-import javafx.scene.image.Image;
-import javafx.scene.image.ImageView;
-import javafx.scene.input.ClipboardContent;
-import javafx.scene.input.Dragboard;
-import javafx.scene.input.MouseButton;
-import javafx.scene.input.TouchEvent;
-import javafx.scene.input.TransferMode;
-import javafx.scene.layout.Background;
-import javafx.scene.layout.BackgroundFill;
-import javafx.scene.layout.BackgroundImage;
-import javafx.scene.layout.BackgroundPosition;
-import javafx.scene.layout.BackgroundRepeat;
-import javafx.scene.layout.BackgroundSize;
-import javafx.scene.layout.CornerRadii;
-import javafx.scene.layout.StackPane;
-import javafx.scene.paint.Color;
-import javafx.scene.paint.ImagePattern;
-import javafx.scene.paint.Paint;
-import javafx.scene.shape.Rectangle;
-import javafx.scene.text.TextAlignment;
-import javafx.util.Duration;
-import org.kordamp.ikonli.javafx.FontIcon;
-
-import java.io.ByteArrayInputStream;
-import java.io.ObjectInputStream;
-import java.nio.ByteBuffer;
-
-public class ActionBox extends StackPane{
-
- private Label displayTextLabel;
-
- private int row;
- private int col;
-
- public int getRow() {
- return row;
- }
-
- public int getCol() {
- return col;
- }
-
-
-
- public void clear()
- {
- setAction(null);
- setBackground(Background.EMPTY);
- setStyle(null);
- getChildren().clear();
- }
-
- private FontIcon statusIcon;
-
- public void baseInit()
- {
-
- displayTextLabel = new Label();
- displayTextLabel.setWrapText(true);
- displayTextLabel.setTextAlignment(TextAlignment.CENTER);
- displayTextLabel.getStyleClass().add("action_box_display_text_label");
-
- displayTextLabel.prefHeightProperty().bind(heightProperty());
- displayTextLabel.prefWidthProperty().bind(widthProperty());
-
-
- statusIcon = new FontIcon();
- statusIcon.setOpacity(0);
- statusIcon.setCache(true);
- statusIcon.setCacheHint(CacheHint.SPEED);
- statusIcon.setIconSize(size - 30);
-
-
- getChildren().addAll(statusIcon, displayTextLabel);
-
- setMinSize(size, size);
- setMaxSize(size, size);
-
- getStyleClass().clear();
- getStyleClass().add("action_box");
- getStyleClass().add("action_box_icon_not_present");
- getStyleClass().add("action_box_"+row+"_"+col);
-
- setOnMouseClicked(touchEvent -> actionClicked());
-
- setOnMousePressed(TouchEvent -> {
- if(action != null)
- {
- getStyleClass().add("action_box_onclick");
- }
- });
- setOnMouseReleased(TouchEvent ->{
- if(action != null)
- {
- getStyleClass().remove("action_box_onclick");
- }
- });
-
- statusIconAnimation = new Timeline(
- new KeyFrame(
- Duration.millis(0.0D),
- new KeyValue(statusIcon.opacityProperty(), 0.0D, Interpolator.EASE_IN)),
- new KeyFrame(
- Duration.millis(100.0D),
- new KeyValue(statusIcon.opacityProperty(), 1.0D, Interpolator.EASE_IN)),
- new KeyFrame(
- Duration.millis(600.0D),
- new KeyValue(statusIcon.opacityProperty(), 1.0D, Interpolator.EASE_OUT)),
- new KeyFrame(
- Duration.millis(700.0D),
- new KeyValue(statusIcon.opacityProperty(), 0.0D, Interpolator.EASE_OUT))
- );
-
- statusIconAnimation.setOnFinished(event -> {
- statusIcon.toBack();
- });
-
-
- }
-
- public void actionClicked()
- {
- if(action!=null)
- {
- if(action.getActionType() == ActionType.FOLDER)
- {
- getActionGridPaneListener().renderFolder(action.getID());
- }
- else
- {
- if(action.getActionType() == ActionType.COMBINE)
- {
- getActionGridPaneListener().combineActionClicked(action.getID());
- }
- else if(action.getActionType() == ActionType.NORMAL)
- {
- getActionGridPaneListener().normalActionClicked(action.getID());
- }
- }
- }
- }
-
- public FontIcon getStatusIcon() {
- return statusIcon;
- }
-
- private Timeline statusIconAnimation;
-
- public Timeline getStatusIconAnimation() {
- return statusIconAnimation;
- }
-
- public ActionGridPaneListener getActionGridPaneListener() {
- return actionGridPaneListener;
- }
-
- private int size;
- private ActionGridPaneListener actionGridPaneListener;
-
- public ActionBox(int size, ActionGridPaneListener actionGridPaneListener, int row, int col)
- {
- this.actionGridPaneListener = actionGridPaneListener;
- this.size = size;
- this.row = row;
- this.col = col;
-
- baseInit();
- }
-
- public static Action deserialize(ByteBuffer buffer) {
- try {
- ByteArrayInputStream is = new ByteArrayInputStream(buffer.array());
- ObjectInputStream ois = new ObjectInputStream(is);
- Action obj = (Action) ois.readObject();
- return obj;
- } catch (Exception e) {
- e.printStackTrace();
- throw new RuntimeException(e);
- }
- }
-
- public void setIcon(byte[] iconByteArray)
- {
- if(iconByteArray == null)
- {
- getStyleClass().remove("action_box_icon_present");
- getStyleClass().add("action_box_icon_not_present");
- setBackground(Background.EMPTY);
- }
- 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))
- )
- );
- }
- }
-
- private Action action;
-
- public Action getAction() {
- return action;
- }
-
- private ExceptionAndAlertHandler exceptionAndAlertHandler;
-
- private String parent;
-
- public String getStreamPiParent() {
- return parent;
- }
-
- public void setStreamPiParent(String parent) {
- this.parent = parent;
- }
-
- public ActionBox(int size, Action action, ExceptionAndAlertHandler exceptionAndAlertHandler,
- ActionGridPaneListener actionGridPaneListener, int row, int col)
- {
- this.actionGridPaneListener = actionGridPaneListener;
- this.exceptionAndAlertHandler = exceptionAndAlertHandler;
- this.action = action;
- this.size = size;
-
- this.row = row;
- this.col = col;
-
- baseInit();
-
- init();
-
- }
-
- public void setAction(Action action)
- {
- this.action = action;
- }
-
- public void init()
- {
-
- setDisplayTextFontColour(action.getDisplayTextFontColourHex());
-
- if(action.isShowDisplayText())
- setDisplayTextLabel(action.getDisplayText());
- else
- setDisplayTextLabel("");
-
- setDisplayTextAlignment(action.getDisplayTextAlignment());
- setBackgroundColour(action.getBgColourHex());
-
- if(action.isHasIcon() && action.isShowIcon())
- {
- setIcon(action.getIconAsByteArray());
- }
- else
- {
- setIcon(null);
- }
-
-
- }
-
- public void animateStatus()
- {
- statusIcon.toFront();
- statusIconAnimation.play();
- }
-
- public void setDisplayTextLabel(String text)
- {
- displayTextLabel.setText(text);
- }
-
- public void setDisplayTextAlignment(DisplayTextAlignment displayTextAlignment)
- {
- if(displayTextAlignment == DisplayTextAlignment.CENTER)
- displayTextLabel.setAlignment(Pos.CENTER);
- else if (displayTextAlignment == DisplayTextAlignment.BOTTOM)
- displayTextLabel.setAlignment(Pos.BOTTOM_CENTER);
- else if (displayTextAlignment == DisplayTextAlignment.TOP)
- displayTextLabel.setAlignment(Pos.TOP_CENTER);
- }
- public void setDisplayTextFontColour(String colour)
- {
- System.out.println("'"+colour+"'COLOR");
- if(!colour.isEmpty())
- {
- System.out.println(
- "putting ..." + Thread.currentThread().getName()
- );
-
-
- displayTextLabel.setStyle("-fx-text-fill : "+colour+";");
- }
-
- }
-
-
- public void setBackgroundColour(String colour)
- {
- System.out.println("COLOr : "+colour);
- if(!colour.isEmpty() && action.getIconAsByteArray() == null)
- setStyle("-fx-background-color : "+colour);
- }
-}
--- 'a/src/main/java/com/StreamPi/Client/Window/Dashboard/ActionGridPane/ActionGridPane.java'
+++ /dev/null
@@ -1,380 +0,0 @@
-package com.StreamPi.Client.Window.Dashboard.ActionGridPane;
-
-import java.util.logging.Logger;
-
-import com.StreamPi.ActionAPI.Action.Action;
-import com.StreamPi.ActionAPI.Action.Location;
-import com.StreamPi.ActionAPI.OtherActions.FolderAction;
-import com.StreamPi.Client.Connection.ClientListener;
-import com.StreamPi.Client.IO.Config;
-import com.StreamPi.Client.Profile.ClientProfile;
-import com.StreamPi.Client.Window.ExceptionAndAlertHandler;
-import com.StreamPi.Util.Alert.StreamPiAlertType;
-import com.StreamPi.Util.Exception.MinorException;
-import com.StreamPi.Util.Exception.SevereException;
-import javafx.animation.KeyFrame;
-import javafx.animation.KeyValue;
-import javafx.animation.Timeline;
-import javafx.application.Platform;
-import javafx.concurrent.Task;
-import javafx.geometry.Insets;
-import javafx.geometry.Pos;
-import javafx.scene.CacheHint;
-import javafx.scene.Node;
-import javafx.scene.control.ScrollPane;
-import javafx.scene.image.Image;
-import javafx.scene.layout.GridPane;
-import javafx.scene.layout.Priority;
-import javafx.scene.layout.StackPane;
-import javafx.scene.layout.VBox;
-import javafx.scene.paint.Color;
-import javafx.scene.paint.Paint;
-import javafx.util.Duration;
-import org.kordamp.ikonli.javafx.FontIcon;
-
-public class ActionGridPane extends GridPane implements ActionGridPaneListener {
-
- private ExceptionAndAlertHandler exceptionAndAlertHandler;
-
- private ClientListener clientListener;
-
- public ActionGridPane(ExceptionAndAlertHandler exceptionAndAlertHandler, ClientListener clientListener)
- {
- this.clientListener = clientListener;
-
- logger = Logger.getLogger(ActionGridPane.class.getName());
- this.exceptionAndAlertHandler = exceptionAndAlertHandler;
- getStyleClass().add("action_grid_pane");
-
- setPadding(new Insets(5.0));
-
- setPrefSize(USE_COMPUTED_SIZE, USE_COMPUTED_SIZE);
-
-
- setAlignment(Pos.CENTER);
-
- VBox.setVgrow(this, Priority.ALWAYS);
- }
-
- private String currentParent;
-
- public void setCurrentParent(String currentParent) {
- this.currentParent = currentParent;
- }
-
- public ClientProfile getClientProfile() {
- return clientProfile;
- }
-
- private int rows, cols;
-
- private ClientProfile clientProfile;
-
- public void setClientProfile(ClientProfile clientProfile)
- {
- this.clientProfile = clientProfile;
-
- setCurrentParent("root");
- setRows(clientProfile.getRows());
- setCols(clientProfile.getCols());
- }
-
- public void actionFailed(String profileID, String actionID)
- {
- if(getClientProfile().getID().equals(profileID))
- {
- Action action = getClientProfile().getActionFromID(actionID);
- if(action != null)
- {
- if(currentParent.equals(action.getParent()))
- {
- failShow(action);
- }
- else
- {
- if(action.getLocation().getCol() == -1)
- {
- failShow(getClientProfile().getActionFromID(action.getParent()));
- }
- }
- }
- }
- }
-
- public void failShow(Action action)
- {
- for(Node node : getChildren())
- {
- if(GridPane.getColumnIndex(node) == action.getLocation().getRow() &&
- GridPane.getRowIndex(node) == action.getLocation().getCol())
- {
-
- ActionBox actionBox = (ActionBox) node;
-
- actionBox.getStatusIcon().setIconLiteral("fas-exclamation-triangle");
- actionBox.getStatusIcon().setIconColor(Color.RED);
-
- actionBox.animateStatus();
-
- break;
- }
- }
- }
-
-
- public String getCurrentParent() {
- return currentParent;
- }
-
- public StackPane getFolderBackButton() throws SevereException
- {
- StackPane stackPane = new StackPane();
- stackPane.getStyleClass().add("action_box");
- stackPane.getStyleClass().add("action_box_valid");
-
- stackPane.setPrefSize(
- getClientProfile().getActionSize(),
- getClientProfile().getActionSize()
- );
-
- FontIcon fontIcon = new FontIcon("fas-chevron-left");
-
- fontIcon.setIconSize(getClientProfile().getActionSize() - 30);
-
- stackPane.setAlignment(Pos.CENTER);
- stackPane.getChildren().add(fontIcon);
-
- stackPane.setOnMouseClicked(e->returnToPreviousParent());
-
- return stackPane;
- }
-
- public void renderGrid() throws SevereException {
- clear();
-
- setHgap(getClientProfile().getActionGap());
- setVgap(getClientProfile().getActionGap());
-
- boolean isFolder = false;
-
- if(!getCurrentParent().equals("root"))
- {
- isFolder = true;
-
- add(getFolderBackButton(), 0,0);
- }
-
- for(int row = 0; row<rows; row++)
- {
- for(int col = 0; col<cols; col++)
- {
- if(row == 0 && col == 0 && isFolder)
- continue;
-
- addBlankActionBox(col, row);
-
- }
- }
- }
-
- public void renderActions()
- {
- StringBuilder errors = new StringBuilder();
- for(Action eachAction : getClientProfile().getActions())
- {
- logger.info("Action ID : "+eachAction.getID()+"\nInvalid : "+eachAction.isInvalid());
-
- try {
- renderAction(eachAction);
- }
- catch (SevereException e)
- {
- exceptionAndAlertHandler.handleSevereException(e);
- }
- catch (MinorException e)
- {
- errors.append("*").append(e.getShortMessage()).append("\n");
- }
- }
-
- if(!errors.toString().isEmpty())
- {
- exceptionAndAlertHandler.handleMinorException(new MinorException("Error while rendering following actions", errors.toString()));
- }
- }
-
- public void clear()
- {
- getChildren().clear();
- }
-
- private Logger logger;
-
-
- public void clearActionBox(int col, int row)
- {
- for(Node node : getChildren())
- {
- if(GridPane.getColumnIndex(node) == row &&
- GridPane.getRowIndex(node) == col)
- {
- getChildren().remove(node);
- break;
- }
- }
- }
-
- public ActionBox getActionBox(int col, int row)
- {
- for(Node node : getChildren())
- {
- if(GridPane.getColumnIndex(node) == row &&
- GridPane.getRowIndex(node) == col)
- {
- return (ActionBox) node;
- }
- }
-
- return null;
- }
-
- public void addBlankActionBox(int col, int row)
- {
- ActionBox actionBox = new ActionBox(getClientProfile().getActionSize(), this, row, col);
-
- actionBox.setStreamPiParent(currentParent);
-
- add(actionBox, row, col);
- }
-
- public void renderAction(Action action) throws SevereException, MinorException
- {
- if(!action.getParent().equals(currentParent))
- {
- logger.info("Skipping action "+action.getID()+", not current parent!");
- return;
- }
-
- if(action.getLocation().getRow()==-1)
- {
- logger.info("Action has -1 rowIndex. Probably Combine Action. Skipping ...");
- return;
- }
-
- if(action.getLocation().getRow() > rows || action.getLocation().getCol() > cols)
- {
- throw new MinorException("Action "+action.getDisplayText()+" ("+action.getID()+") falls outside bounds.\n" +
- " Consider increasing rows/cols from client settings and relocating/deleting it.");
- }
-
-
- Location location = action.getLocation();
-
- ActionBox actionBox = new ActionBox(getClientProfile().getActionSize(), action, exceptionAndAlertHandler, this, location.getRow(), location.getCol());
-
- actionBox.setStreamPiParent(currentParent);
-
- clearActionBox(location.getCol(), location.getRow());
-
- System.out.println(location.getCol()+","+location.getRow());
- add(actionBox, location.getRow(), location.getCol());
-
- }
-
- public void setRows(int rows)
- {
- this.rows = rows;
- }
-
- public void setCols(int cols)
- {
- this.cols = cols;
- }
-
- public int getRows()
- {
- return rows;
- }
-
- public int getCols()
- {
- return cols;
- }
-
- private String previousParent;
-
- public void setPreviousParent(String previousParent) {
- this.previousParent = previousParent;
- }
-
- public String getPreviousParent() {
- return previousParent;
- }
-
- @Override
- public void renderFolder(String actionID) {
- setCurrentParent(clientProfile.getActionFromID(actionID).getID());
- setPreviousParent(clientProfile.getActionFromID(actionID).getParent());
- try {
- renderGrid();
- renderActions();
- } catch (SevereException e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public void normalActionClicked(String ID) {
- if(clientListener.isConnected())
- clientListener.onNormalActionClicked(getClientProfile().getID(), ID);
- else
- exceptionAndAlertHandler.onAlert("Not Connected", "Not Connected to any Server", StreamPiAlertType.ERROR);
- }
-
- @Override
- public void combineActionClicked(String ID) {
- if(clientListener.isConnected())
- {
- new Thread(new Task<Void>() {
- @Override
- protected Void call()
- {
- Action action = getClientProfile().getActionFromID(ID);
-
- for(int i = 0;i<action.getClientProperties().get().size();i++)
- {
- try {
- logger.info("Clicking "+i+", '"+action.getClientProperties().getSingleProperty(i+"").getRawValue()+"'");
- normalActionClicked(action.getClientProperties().getSingleProperty(i+"").getRawValue());
- } catch (MinorException e) {
- e.printStackTrace();
- exceptionAndAlertHandler.handleMinorException(e);
- }
- }
-
- return null;
- }
- }).start();
- }
- }
-
- public void returnToPreviousParent()
- {
- setCurrentParent(getPreviousParent());
-
- if(!getPreviousParent().equals("root"))
- {
- System.out.println("parent : "+getPreviousParent());
- setPreviousParent(getClientProfile().getActionFromID(
- getPreviousParent()
- ).getParent());
- }
-
- try {
- renderGrid();
- renderActions();
- } catch (SevereException e) {
- e.printStackTrace();
- }
- }
-}
--- 'a/src/main/java/com/StreamPi/Client/Window/Dashboard/ActionGridPane/ActionGridPaneListener.java'
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.StreamPi.Client.Window.Dashboard.ActionGridPane;
-
-import com.StreamPi.ActionAPI.Action.Action;
-import com.StreamPi.ActionAPI.OtherActions.FolderAction;
-
-public interface ActionGridPaneListener {
-
- void renderFolder(String ID);
-
- void normalActionClicked(String ID);
- void combineActionClicked(String ID);
-}
--- 'a/src/main/java/com/StreamPi/Client/Window/Dashboard/DashboardBase.java'
+++ /dev/null
@@ -1,81 +0,0 @@
-package com.StreamPi.Client.Window.Dashboard;
-
-import com.StreamPi.Client.Connection.ClientListener;
-import com.StreamPi.Client.IO.Config;
-import com.StreamPi.Client.Profile.ClientProfile;
-import com.StreamPi.Client.Window.ExceptionAndAlertHandler;
-import com.StreamPi.Client.Window.Dashboard.ActionGridPane.ActionGridPane;
-import com.StreamPi.Util.Exception.SevereException;
-import javafx.geometry.Insets;
-import javafx.geometry.Pos;
-import javafx.scene.CacheHint;
-import javafx.scene.control.Button;
-import javafx.scene.control.ScrollPane;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.VBox;
-import javafx.scene.paint.Paint;
-import org.kordamp.ikonli.javafx.FontIcon;
-
-public class DashboardBase extends VBox {
- private ExceptionAndAlertHandler exceptionAndAlertHandler;
-
- private ActionGridPane actionGridPane;
- private Button settingsButton;
-
- public DashboardBase(ExceptionAndAlertHandler exceptionAndAlertHandler, ClientListener clientListener)
- {
- this.exceptionAndAlertHandler = exceptionAndAlertHandler;
-
- actionGridPane = new ActionGridPane(exceptionAndAlertHandler, clientListener);
-
- FontIcon fontIcon = new FontIcon("fas-cog");
- fontIcon.getStyleClass().addAll("dashboard_settings_button_icon");
-
- settingsButton = new Button();
- settingsButton.setGraphic(fontIcon);
-
- HBox hBox = new HBox(settingsButton);
- hBox.setPadding(new Insets(0,5,5,0));
- hBox.setAlignment(Pos.CENTER_RIGHT);
-
-
- getChildren().addAll(actionGridPane,hBox);
-
- getStyleClass().add("dashboard");
-
- setCache(true);
- setCacheHint(CacheHint.SPEED);
- }
-
- public void renderProfile(ClientProfile clientProfile) throws SevereException
- {
- renderProfile(clientProfile, "root");
- }
-
- public void renderProfile(ClientProfile clientProfile, String currentParent) throws SevereException
- {
- actionGridPane.setClientProfile(clientProfile);
- actionGridPane.setCurrentParent(currentParent);
-
- actionGridPane.renderGrid();
- actionGridPane.renderActions();
- }
-
- public void addBlankActionBox(int col, int row)
- {
- actionGridPane.addBlankActionBox(col, row);
- }
-
- public void clearActionBox(int col, int row)
- {
- actionGridPane.clearActionBox(col, row);
- }
-
- public ActionGridPane getActionGridPane() {
- return actionGridPane;
- }
-
- public Button getSettingsButton() {
- return settingsButton;
- }
-}
--- 'a/src/main/java/com/StreamPi/Client/Window/ExceptionAndAlertHandler.java'
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.StreamPi.Client.Window;
-
-import com.StreamPi.Util.Alert.StreamPiAlertType;
-import com.StreamPi.Util.Exception.MinorException;
-import com.StreamPi.Util.Exception.SevereException;
-
-public interface ExceptionAndAlertHandler {
- void handleMinorException(MinorException e);
- void handleSevereException(SevereException e);
- void onAlert(String title, String body, StreamPiAlertType alertType);
-}
--- 'a/src/main/java/com/StreamPi/Client/Window/FirstTimeUse/FinalConfigPane.java'
+++ /dev/null
@@ -1,178 +0,0 @@
-package com.StreamPi.Client.Window.FirstTimeUse;
-
-import com.StreamPi.Client.Connection.Client;
-import com.StreamPi.Client.Connection.ClientListener;
-import com.StreamPi.Client.IO.Config;
-import com.StreamPi.Client.Info.ClientInfo;
-import com.StreamPi.Client.Window.ExceptionAndAlertHandler;
-import com.StreamPi.Util.Alert.StreamPiAlert;
-import com.StreamPi.Util.Alert.StreamPiAlertListener;
-import com.StreamPi.Util.Alert.StreamPiAlertType;
-import com.StreamPi.Util.Exception.SevereException;
-import com.StreamPi.Util.FormHelper.HBoxInputBox;
-import com.StreamPi.Util.FormHelper.SpaceFiller;
-import com.StreamPi.Util.FormHelper.SpaceFiller.FillerType;
-import com.StreamPi.Util.Platform.Platform;
-
-import javafx.geometry.Pos;
-import javafx.scene.control.Alert;
-import javafx.scene.control.Button;
-import javafx.scene.control.Label;
-import javafx.scene.control.ScrollPane;
-import javafx.scene.control.TextField;
-import javafx.scene.control.Alert.AlertType;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Priority;
-import javafx.scene.layout.VBox;
-import javafx.stage.Stage;
-
-public class FinalConfigPane extends VBox
-{
- private TextField clientNicknameTextField;
- private TextField serverIPHostNameTextField;
- private TextField serverPortTextField;
- private TextField displayWidthTextField;
- private TextField displayHeightTextField;
-
- private ExceptionAndAlertHandler exceptionAndAlertHandler;
- private ClientListener clientListener;
-
- public FinalConfigPane(ExceptionAndAlertHandler exceptionAndAlertHandler, ClientListener clientListener)
- {
- this.exceptionAndAlertHandler = exceptionAndAlertHandler;
- this.clientListener = clientListener;
-
- getStyleClass().add("first_time_use_pane_final_config");
-
- Label label = new Label("Thats it. Now just a little bit and then youre set!");
- label.setWrapText(true);
- VBox.setVgrow(label, Priority.ALWAYS);
- label.getStyleClass().add("first_time_use_pane_final_config_label");
-
- clientNicknameTextField = new TextField();
- serverIPHostNameTextField = new TextField();
- serverPortTextField = new TextField();
-
- displayWidthTextField = new TextField();
- displayHeightTextField = new TextField();
-
- HBoxInputBox clientNickNameInputBox = new HBoxInputBox("Nickname", clientNicknameTextField);
- HBoxInputBox serverIPHostNameInputBox = new HBoxInputBox("Server IP", serverIPHostNameTextField);
- HBoxInputBox serverIPPortInputBox = new HBoxInputBox("Server Port", serverPortTextField);
- HBoxInputBox displayWidthInputBox = new HBoxInputBox("Display Width", displayWidthTextField);
- HBoxInputBox displayHeightInputBox = new HBoxInputBox("Display Height", displayHeightTextField);
-
- if(ClientInfo.getInstance().getPlatformType() == Platform.ANDROID)
- {
- displayWidthInputBox.setVisible(false);
- displayHeightInputBox.setVisible(false);
- }
-
- Button confirmButton = new Button("Confirm");
- confirmButton.setOnAction(event -> onConfirmButtonClicked());
- HBox bBar = new HBox(confirmButton);
- bBar.setAlignment(Pos.CENTER_RIGHT);
-
- VBox v = new VBox(clientNickNameInputBox, serverIPHostNameInputBox, serverIPPortInputBox,
- displayWidthInputBox, displayHeightInputBox);
- v.setSpacing(10.0);
-
- ScrollPane scrollPane = new ScrollPane(v);
- v.prefWidthProperty().bind(scrollPane.widthProperty().subtract(25));
-
- getChildren().addAll(label, scrollPane,new SpaceFiller(FillerType.VBox), bBar);
-
- setSpacing(10.0);
-
- setVisible(false);
- }
-
- private void onConfirmButtonClicked()
- {
- StringBuilder errors = new StringBuilder();
-
- if(clientNicknameTextField.getText().isBlank())
- {
- errors.append("* Nick name cannot be blank.\n");
- }
-
- if(serverIPHostNameTextField.getText().isBlank())
- {
- errors.append("* Server IP cannot be empty.\n");
- }
-
- int port = -1;
- try
- {
- port = Integer.parseInt(serverPortTextField.getText());
-
- if(port < 1024)
- errors.append("* Server IP should be above 1024.\n");
- }
- catch (NumberFormatException exception)
- {
- errors.append("* Server IP should be a number.\n");
- }
-
- double width=-1,height=-1;
-
- if(ClientInfo.getInstance().getPlatformType() != Platform.ANDROID)
- {
- try
- {
- width = Double.parseDouble(displayWidthTextField.getText());
-
- if(width < 0)
- errors.append("* Display Width should be above 0.\n");
- }
- catch (NumberFormatException exception)
- {
- errors.append("* Display Width should be a number.\n");
- }
-
- try
- {
- height = Double.parseDouble(displayHeightTextField.getText());
-
- if(height < 0)
- errors.append("* Display Height should be above 0.\n");
- }
- catch (NumberFormatException exception)
- {
- errors.append("* Display Height should be a number.\n");
- }
- }
-
- if(errors.toString().isEmpty())
- {
- try
- {
- Config.getInstance().setNickName(clientNicknameTextField.getText());
- Config.getInstance().setServerHostNameOrIP(serverIPHostNameTextField.getText());
- Config.getInstance().setServerPort(port);
- Config.getInstance().setFirstTimeUse(false);
-
- if(ClientInfo.getInstance().getPlatformType() != Platform.ANDROID)
- {
- Config.getInstance().setStartupWindowSize(
- width, height
- );
- }
-
-
- Config.getInstance().save();
-
- clientListener.init();
-
- }
- catch(SevereException e)
- {
- exceptionAndAlertHandler.handleSevereException(e);
- }
- }
- else
- {
- new StreamPiAlert("Uh Oh", "Please rectify the following errors and try again:\n"+errors.toString(), StreamPiAlertType.ERROR).show();
- }
- }
-}
--- 'a/src/main/java/com/StreamPi/Client/Window/FirstTimeUse/FirstTimeUse.java'
+++ /dev/null
@@ -1,146 +0,0 @@
-package com.StreamPi.Client.Window.FirstTimeUse;
-
-import com.StreamPi.Client.Main;
-import com.StreamPi.Client.Connection.ClientListener;
-import com.StreamPi.Client.Window.ExceptionAndAlertHandler;
-import com.StreamPi.Util.FormHelper.SpaceFiller;
-import com.StreamPi.Util.FormHelper.SpaceFiller.FillerType;
-
-import javafx.event.ActionEvent;
-import javafx.geometry.Insets;
-import javafx.geometry.Pos;
-import javafx.scene.control.Button;
-import javafx.scene.control.Label;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Pane;
-import javafx.scene.layout.Priority;
-import javafx.scene.layout.StackPane;
-import javafx.scene.layout.VBox;
-import javafx.scene.text.Font;
-
-public class FirstTimeUse extends VBox{
-
-
- public FirstTimeUse(ExceptionAndAlertHandler exceptionAndAlertHandler, ClientListener clientListener)
- {
- Font.loadFont(Main.class.getResourceAsStream("Roboto.ttf"), 13);
- getStylesheets().add(Main.class.getResource("style.css").toExternalForm());
-
- getStyleClass().add("first_time_use_pane");
-
- setSpacing(10.0);
- setPadding(new Insets(5));
-
- headingLabel = new Label();
- headingLabel.getStyleClass().add("first_time_use_pane_heading_label");
-
- StackPane stackPane = new StackPane();
- stackPane.getStyleClass().add("first_time_use_pane_stackpane");
-
- VBox.setVgrow(stackPane, Priority.ALWAYS);
-
- welcomePane = new WelcomePane();
- licensePane = new LicensePane();
- finalConfigPane = new FinalConfigPane(exceptionAndAlertHandler, clientListener);
-
- stackPane.getChildren().addAll(
- welcomePane,
- licensePane,
- finalConfigPane
- );
-
-
- nextButton = new Button("Next");
- nextButton.setOnAction(event-> onNextButtonClicked());
-
- previousButton = new Button("Previous");
- previousButton.setOnAction(event-> onPreviousButtonClicked());
-
-
- HBox buttonBar = new HBox(previousButton, new SpaceFiller(FillerType.HBox), nextButton);
- buttonBar.setSpacing(10.0);
-
- getChildren().addAll(headingLabel, stackPane, buttonBar);
-
- setWindow(WindowName.WELCOME);
- }
-
- private Label headingLabel;
- private Button nextButton;
- private Button previousButton;
- private WelcomePane welcomePane;
- private LicensePane licensePane;
- private FinalConfigPane finalConfigPane;
-
- private WindowName windowName;
-
- private void onNextButtonClicked()
- {
- if(windowName == WindowName.WELCOME)
- {
- setWindow(WindowName.LICENSE);
- }
- else if(windowName == WindowName.LICENSE)
- {
- setWindow(WindowName.FINAL);
- }
- }
-
- private void onPreviousButtonClicked()
- {
- if(windowName == WindowName.FINAL)
- {
- setWindow(WindowName.LICENSE);
- }
- else if(windowName == WindowName.LICENSE)
- {
- setWindow(WindowName.WELCOME);
- }
- }
-
- private void setWindow(WindowName windowName)
- {
- if (windowName == WindowName.WELCOME)
- {
- this.windowName = WindowName.WELCOME;
- welcomePane.toFront();
- welcomePane.setVisible(true);
- licensePane.setVisible(false);
- finalConfigPane.setVisible(false);
-
- headingLabel.setText("");
-
- nextButton.setDisable(false);
- previousButton.setDisable(true);
- }
- else if (windowName == WindowName.LICENSE)
- {
- this.windowName = WindowName.LICENSE;
- licensePane.toFront();
- welcomePane.setVisible(false);
- licensePane.setVisible(true);
- finalConfigPane.setVisible(false);
-
- headingLabel.setText("License Agreement");
-
- nextButton.setDisable(false);
- previousButton.setDisable(false);
- }
- else if (windowName == WindowName.FINAL)
- {
- this.windowName = WindowName.FINAL;
- finalConfigPane.toFront();
- welcomePane.setVisible(false);
- licensePane.setVisible(false);
- finalConfigPane.setVisible(true);
-
- headingLabel.setText("Finishing up ...");
-
- nextButton.setDisable(true);
- previousButton.setDisable(false);
- }
- }
-
-
-
-}
--- 'a/src/main/java/com/StreamPi/Client/Window/FirstTimeUse/LicensePane.java'
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.StreamPi.Client.Window.FirstTimeUse;
-
-import com.StreamPi.Client.Info.License;
-
-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 LicensePane()
- {
- getStyleClass().add("first_time_use_pane_license");
-
- Label label = new Label("By Clicking on 'Next', you agree with the license.");
- label.prefWidthProperty().bind(widthProperty());
- label.setWrapText(true);
-
- TextArea licenseTextArea = new TextArea(License.getLicense());
- licenseTextArea.setWrapText(false);
- licenseTextArea.setEditable(false);
-
- licenseTextArea.prefWidthProperty().bind(widthProperty());
- VBox.setVgrow(licenseTextArea, Priority.ALWAYS);
-
- getChildren().addAll(label, licenseTextArea);
- }
-}
--- 'a/src/main/java/com/StreamPi/Client/Window/FirstTimeUse/WelcomePane.java'
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.StreamPi.Client.Window.FirstTimeUse;
-
-import javafx.geometry.Pos;
-import javafx.scene.control.Label;
-import javafx.scene.layout.VBox;
-
-public class WelcomePane extends VBox{
- public WelcomePane()
- {
- getStyleClass().add("first_time_use_pane_welcome");
-
- Label welcomeLabel = new Label("Welcome!");
- welcomeLabel.getStyleClass().add("first_time_use_welcome_pane_welcome_label");
-
- Label nextToContinue = new Label("Click on Next to continue with the setup.");
- nextToContinue.getStyleClass().add("first_time_use_welcome_pane_next_to_continue_label");
-
-
- setAlignment(Pos.CENTER);
- setSpacing(5.0);
- getChildren().addAll(welcomeLabel, nextToContinue);
-
- setVisible(false);
- }
-}
--- 'a/src/main/java/com/StreamPi/Client/Window/FirstTimeUse/WindowName.java'
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.StreamPi.Client.Window.FirstTimeUse;
-
-public enum WindowName {
- WELCOME, LICENSE, FINAL
-}
--- 'a/src/main/java/com/StreamPi/Client/Window/Settings/SettingsBase.java'
+++ /dev/null
@@ -1,527 +0,0 @@
-package com.StreamPi.Client.Window.Settings;
-
-import java.io.File;
-
-import com.StreamPi.Client.Connection.Client;
-import com.StreamPi.Client.Connection.ClientListener;
-import com.StreamPi.Client.IO.Config;
-import com.StreamPi.Client.Info.ClientInfo;
-import com.StreamPi.Client.Profile.ClientProfile;
-import com.StreamPi.Client.Window.ExceptionAndAlertHandler;
-import com.StreamPi.ThemeAPI.Theme;
-import com.StreamPi.Util.Alert.StreamPiAlert;
-import com.StreamPi.Util.Alert.StreamPiAlertType;
-import com.StreamPi.Util.ComboBox.StreamPiComboBox;
-import com.StreamPi.Util.ComboBox.StreamPiComboBoxFactory;
-import com.StreamPi.Util.ComboBox.StreamPiComboBoxListener;
-import com.StreamPi.Util.Exception.MinorException;
-import com.StreamPi.Util.Exception.SevereException;
-import com.StreamPi.Util.FormHelper.HBoxInputBox;
-import com.StreamPi.Util.FormHelper.SpaceFiller;
-import com.StreamPi.Util.Platform.ReleaseStatus;
-import com.StreamPi.Util.StartAtBoot.SoftwareType;
-import com.StreamPi.Util.StartAtBoot.StartAtBoot;
-import com.gluonhq.attach.util.Services;
-
-import javafx.application.Platform;
-import javafx.collections.FXCollections;
-import javafx.geometry.Insets;
-import javafx.geometry.Pos;
-import javafx.scene.control.*;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Priority;
-import javafx.scene.layout.VBox;
-import javafx.util.Callback;
-import org.w3c.dom.Text;
-
-public class SettingsBase extends VBox {
- private TextField serverPortTextField;
- private TextField serverHostNameOrIPTextField;
-
- private StreamPiComboBox<ClientProfile> clientProfileComboBox;
- private StreamPiComboBox<Theme> themeComboBox;
-
- private TextField displayWidthTextField;
- private TextField displayHeightTextField;
-
- private TextField nickNameTextField;
-
- private Button closeButton;
- private Button saveButton;
- private Button connectDisconnectButton;
- private Button shutdownButton;
-
- private ToggleButton startOnBootToggleButton;
-
- private ToggleButton showCursorToggleButton;
- private ToggleButton fullScreenToggleButton;
-
- private ClientListener clientListener;
- private ExceptionAndAlertHandler exceptionAndAlertHandler;
-
- private TextField themesPathTextField;
- private TextField iconsPathTextField;
- private TextField profilesPathTextField;
-
- public SettingsBase(ExceptionAndAlertHandler exceptionAndAlertHandler, ClientListener clientListener) {
-
- getStyleClass().add("settings_base");
- this.clientListener = clientListener;
- this.exceptionAndAlertHandler = exceptionAndAlertHandler;
-
- serverPortTextField = new TextField();
- serverHostNameOrIPTextField = new TextField();
- nickNameTextField = new TextField();
-
- clientProfileComboBox = new StreamPiComboBox<>();
-
- clientProfileComboBox.setStreamPiComboBoxFactory(new StreamPiComboBoxFactory<ClientProfile>()
- {
- @Override
- public String getOptionDisplayText(ClientProfile object)
- {
- return object.getName();
- }
- });
-
- clientProfileComboBox.setStreamPiComboBoxListener(new StreamPiComboBoxListener<ClientProfile>(){
- @Override
- public void onNewItemSelected(ClientProfile selectedItem)
- {
- clientListener.renderProfile(selectedItem);
- }
- });
-
-
- themeComboBox = new StreamPiComboBox<>();
- themeComboBox.setStreamPiComboBoxFactory(new StreamPiComboBoxFactory<Theme>()
- {
- @Override
- public String getOptionDisplayText(Theme object)
- {
- return object.getShortName();
- }
- });
-
- displayHeightTextField = new TextField();
- displayWidthTextField = new TextField();
-
- themesPathTextField = new TextField();
- iconsPathTextField = new TextField();
- profilesPathTextField = new TextField();
-
- startOnBootToggleButton = new ToggleButton("Start On Boot");
- startOnBootToggleButton.managedProperty().bind(startOnBootToggleButton.visibleProperty());
-
- showCursorToggleButton = new ToggleButton("Show Cursor");
- showCursorToggleButton.managedProperty().bind(showCursorToggleButton.visibleProperty());
-
- fullScreenToggleButton = new ToggleButton("Full Screen");
- fullScreenToggleButton.managedProperty().bind(fullScreenToggleButton.visibleProperty());
-
- int prefWidth = 200;
-
- Label licenseLabel = new Label("This software is licensed to GNU GPLv3. Check StreamPi Server > Settings > About to see full License Statement.");
- licenseLabel.setWrapText(true);
-
- Label versionLabel = new Label(ClientInfo.getInstance().getReleaseStatus().getUIName() +" "+ClientInfo.getInstance().getVersion().getText());
-
-
- HBoxInputBox themesPathInputBox = new HBoxInputBox("Themes Path", themesPathTextField, prefWidth);
- themesPathInputBox.managedProperty().bind(themesPathInputBox.visibleProperty());
-
-
- HBoxInputBox iconsPathInputBox = new HBoxInputBox("Icons Path", iconsPathTextField, prefWidth);
- iconsPathInputBox.managedProperty().bind(iconsPathInputBox.visibleProperty());
-
-
- HBoxInputBox profilesPathInputBox = new HBoxInputBox("Profiles Path", profilesPathTextField, prefWidth);
- profilesPathInputBox.managedProperty().bind(profilesPathInputBox.visibleProperty());
-
-
- HBoxInputBox screenHeightInputBox = new HBoxInputBox("Screen Height", displayHeightTextField, prefWidth);
- screenHeightInputBox.managedProperty().bind(screenHeightInputBox.visibleProperty());
-
-
- HBoxInputBox screenWidthInputBox = new HBoxInputBox("Screen Width", displayWidthTextField, prefWidth);
- screenWidthInputBox.managedProperty().bind(screenWidthInputBox.visibleProperty());
-
- if(ClientInfo.getInstance().getPlatformType() == com.StreamPi.Util.Platform.Platform.ANDROID)
- {
- themesPathInputBox.setVisible(false);
- iconsPathInputBox.setVisible(false);
- profilesPathInputBox.setVisible(false);
-
- startOnBootToggleButton.setVisible(false);
- showCursorToggleButton.setVisible(false);
- fullScreenToggleButton.setVisible(false);
-
- screenHeightInputBox.setVisible(false);
- screenWidthInputBox.setVisible(false);
- }
-
-
- VBox vBox = new VBox(
- new HBoxInputBox("Nick Name", nickNameTextField, prefWidth),
- new HBoxInputBox("Host Name/IP", serverHostNameOrIPTextField, prefWidth),
- new HBoxInputBox("Port", serverPortTextField, prefWidth),
- new HBox(
- new Label("Current Profile"),
- new SpaceFiller(SpaceFiller.FillerType.HBox),
- clientProfileComboBox
- ),
- new HBox(
- new Label("Theme"),
- new SpaceFiller(SpaceFiller.FillerType.HBox),
- themeComboBox
- ),
- screenHeightInputBox,
- screenWidthInputBox,
- themesPathInputBox,
- iconsPathInputBox,
- profilesPathInputBox,
- startOnBootToggleButton,
- showCursorToggleButton,
- fullScreenToggleButton,
- licenseLabel,
- versionLabel
- );
- vBox.getStyleClass().add("settings_base_vbox");
-
- vBox.setSpacing(5.0);
- vBox.setPadding(new Insets(5));
-
- ScrollPane scrollPane = new ScrollPane();
- scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
- VBox.setVgrow(scrollPane, Priority.ALWAYS);
- scrollPane.getStyleClass().add("settings_base_scrollpane");
- scrollPane.setContent(vBox);
-
- vBox.setMinWidth(300);
-
- vBox.prefWidthProperty().bind(scrollPane.widthProperty().subtract(25));
-
-
- Label settingsLabel = new Label("Settings");
- settingsLabel.setPadding(new Insets(5,0,0,5));
- settingsLabel.getStyleClass().add("settings_heading");
-
- saveButton = new Button("Save");
- saveButton.setOnAction(event->onSaveButtonClicked());
-
- closeButton = new Button("Close");
-
- connectDisconnectButton = new Button("Connect");
- connectDisconnectButton.setOnAction(event -> onConnectDisconnectButtonClicked());
-
- shutdownButton = new Button("Shutdown");
- shutdownButton.setOnAction(event -> onShutdownButtonClicked());
-
- Button exitButton = new Button("Exit");
- exitButton.setOnAction(event -> onExitButtonClicked());
-
- HBox buttonBar = new HBox(connectDisconnectButton, saveButton, exitButton, closeButton);
-
- if(ClientInfo.getInstance().getPlatformType() == com.StreamPi.Util.Platform.Platform.LINUX &&
- ClientInfo.getInstance().isShowShutDownButton())
- {
- buttonBar.getChildren().add(shutdownButton);
- }
-
-
- buttonBar.setPadding(new Insets(0,5,5,0));
- buttonBar.setSpacing(5.0);
- buttonBar.setAlignment(Pos.CENTER_RIGHT);
-
- setSpacing(5.0);
-
- getChildren().addAll(
- settingsLabel,
- scrollPane,
- buttonBar
- );
- }
-
- public void onExitButtonClicked()
- {
- clientListener.onCloseRequest();
- Platform.exit();
- }
-
- public void setDisableStatus(boolean status)
- {
- saveButton.setDisable(status);
- connectDisconnectButton.setDisable(status);
- }
-
- public void onShutdownButtonClicked()
- {
- clientListener.onCloseRequest();
- try {
- Runtime.getRuntime().exec("sudo halt");
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- public void onConnectDisconnectButtonClicked()
- {
- try
- {
- if(clientListener.isConnected())
- clientListener.disconnect("Client disconnected from settings");
- else
- clientListener.setupClientConnection();
- }
- catch (SevereException e)
- {
- e.printStackTrace();
- exceptionAndAlertHandler.handleSevereException(e);
- }
- }
-
- public void setConnectDisconnectButtonStatus()
- {
- Platform.runLater(()->{
- setDisableStatus(false);
-
- System.out.println("q24qwdqwd : "+clientListener.isConnected());
-
- if(clientListener.isConnected())
- connectDisconnectButton.setText("Disconnect");
- else
- connectDisconnectButton.setText("Connect");
- });
-
- }
-
- public Button getCloseButton() {
- return closeButton;
- }
-
- public void loadData() throws SevereException
- {
- nickNameTextField.setText(Config.getInstance().getClientNickName());
-
- serverHostNameOrIPTextField.setText(Config.getInstance().getSavedServerHostNameOrIP());
- serverPortTextField.setText(Config.getInstance().getSavedServerPort()+"");
-
- clientProfileComboBox.setOptions(clientListener.getClientProfiles().getClientProfiles());
-
- int ind = 0;
- for(int i = 0;i<clientProfileComboBox.getOptions().size();i++)
- {
- if(clientProfileComboBox.getOptions().get(i).getID().equals(clientListener.getCurrentProfile().getID()))
- {
- ind = i;
- break;
- }
- }
-
- clientProfileComboBox.setCurrentSelectedItemIndex(ind);
-
- themeComboBox.setOptions(clientListener.getThemes().getThemeList());
-
- int ind2 = 0;
- for(int i = 0;i<themeComboBox.getOptions().size();i++)
- {
- if(themeComboBox.getOptions().get(i).getFullName().equals(clientListener.getCurrentTheme().getFullName()))
- {
- ind2 = i;
- break;
- }
- }
-
- themeComboBox.setCurrentSelectedItemIndex(ind2);
-
- displayWidthTextField.setText(Config.getInstance().getStartupWindowWidth()+"");
- displayHeightTextField.setText(Config.getInstance().getStartupWindowHeight()+"");
-
- themesPathTextField.setText(Config.getInstance().getThemesPath());
- iconsPathTextField.setText(Config.getInstance().getIconsPath());
- profilesPathTextField.setText(Config.getInstance().getProfilesPath());
-
- startOnBootToggleButton.setSelected(Config.getInstance().isStartOnBoot());
-
- fullScreenToggleButton.setSelected(Config.getInstance().isFullscreen());
- showCursorToggleButton.setSelected(Config.getInstance().isShowCursor());
- }
-
- public void onSaveButtonClicked()
- {
- StringBuilder errors = new StringBuilder();
-
- int port = -1;
- try
- {
- port = Integer.parseInt(serverPortTextField.getText());
-
- if(port < 1024)
- errors.append("* Server IP should be above 1024.\n");
- }
- catch (NumberFormatException exception)
- {
- errors.append("* Server IP should be a number.\n");
- }
-
- double width = -1;
- try
- {
- width = Double.parseDouble(displayWidthTextField.getText());
-
- if(width < 0)
- errors.append("* Display Width should be above 0.\n");
- }
- catch (NumberFormatException exception)
- {
- errors.append("* Display Width should be a number.\n");
- }
-
- double height = -1;
- try
- {
- height = Double.parseDouble(displayHeightTextField.getText());
-
- if(height < 0)
- errors.append("* Display Height should be above 0.\n");
- }
- catch (NumberFormatException exception)
- {
- errors.append("* Display Height should be a number.\n");
- }
-
- if(serverHostNameOrIPTextField.getText().isBlank())
- {
- errors.append("* Server IP cannot be empty.\n");
- }
-
- if(nickNameTextField.getText().isBlank())
- {
- errors.append("* Nick name cannot be blank.\n");
- }
-
-
- if(!errors.toString().isEmpty())
- {
- exceptionAndAlertHandler.handleMinorException(new MinorException(
- "You made mistakes",
- "Please fix the errors and try again :\n"+errors.toString()
- ));
- return;
- }
-
-
-
- try {
- boolean toBeReloaded = false;
-
- boolean breakConnection = false;
-
- if(!Config.getInstance().getCurrentThemeFullName().equals(themeComboBox.getCurrentSelectedItem().getFullName()))
- toBeReloaded = true;
-
- Config.getInstance().setCurrentThemeFullName(themeComboBox.getCurrentSelectedItem().getFullName());
-
- if(width != Config.getInstance().getStartupWindowWidth() || height != Config.getInstance().getStartupWindowHeight())
- toBeReloaded = true;
-
- Config.getInstance().setStartupWindowSize(width, height);
-
-
- if(!Config.getInstance().getClientNickName().equals(nickNameTextField.getText()))
- breakConnection = true;
-
- Config.getInstance().setNickName(nickNameTextField.getText());
-
- if(port != Config.getInstance().getSavedServerPort() || !serverHostNameOrIPTextField.getText().equals(Config.getInstance().getSavedServerHostNameOrIP()))
- breakConnection = true;
-
- Config.getInstance().setServerPort(port);
- Config.getInstance().setServerHostNameOrIP(serverHostNameOrIPTextField.getText());
-
- boolean startOnBoot = startOnBootToggleButton.isSelected();
-
- if(Config.getInstance().isStartOnBoot() != startOnBoot)
- {
- if(ClientInfo.getInstance().getRunnerFileName() == null)
- {
- new StreamPiAlert("Uh Oh", "No Runner File Name Specified as startup arguments. Cant set run at boot.", StreamPiAlertType.ERROR).show();
- startOnBoot = false;
- }
- else
- {
- StartAtBoot startAtBoot = new StartAtBoot(SoftwareType.CLIENT, ClientInfo.getInstance().getPlatformType());
- if(startOnBoot)
- {
- startAtBoot.create(new File(ClientInfo.getInstance().getRunnerFileName()));
- }
- else
- {
- boolean result = startAtBoot.delete();
- if(!result)
- new StreamPiAlert("Uh Oh!", "Unable to delete starter file", StreamPiAlertType.ERROR).show();
- }
- }
- }
-
- Config.getInstance().setStartOnBoot(startOnBoot);
-
- if(Config.getInstance().isFullscreen() != fullScreenToggleButton.isSelected() ||
- Config.getInstance().isShowCursor() != showCursorToggleButton.isSelected())
- toBeReloaded = true;
-
-
- Config.getInstance().setFullscreen(fullScreenToggleButton.isSelected());
- Config.getInstance().setShowCursor(showCursorToggleButton.isSelected());
-
-
-
- if(!Config.getInstance().getThemesPath().equals(themesPathTextField.getText()))
- toBeReloaded = true;
-
- Config.getInstance().setThemesPath(themesPathTextField.getText());
-
-
- if(!Config.getInstance().getIconsPath().equals(iconsPathTextField.getText()))
- toBeReloaded = true;
-
- Config.getInstance().setIconsPath(iconsPathTextField.getText());
-
- if(!Config.getInstance().getProfilesPath().equals(profilesPathTextField.getText()))
- toBeReloaded = true;
-
- Config.getInstance().setProfilesPath(profilesPathTextField.getText());
-
-
- Config.getInstance().save();
-
- loadData();
-
-
- if(breakConnection)
- {
- if(clientListener.isConnected())
- clientListener.disconnect("Client connection settings were changed.");
- }
-
- if(toBeReloaded)
- {
- clientListener.init();
- clientListener.renderRootDefaultProfile();
- }
- }
- catch (SevereException e)
- {
- e.printStackTrace();
- exceptionAndAlertHandler.handleSevereException(e);
- }
- catch (MinorException e)
- {
- e.printStackTrace();
- exceptionAndAlertHandler.handleMinorException(e);
- }
- }
-
-}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/Main.java
@@ -0,0 +1,36 @@
+package com.stream_pi.client;
+
+import com.stream_pi.client.controller.Controller;
+import com.stream_pi.client.info.ClientInfo;
+
+import javafx.application.Application;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+public class Main extends Application {
+
+
+ @Override
+ public void start(Stage stage)
+ {
+ Controller d = new Controller();
+ Scene s = new Scene(d);
+ stage.setScene(s);
+ d.init();
+ }
+
+
+ public static void main(String[] args)
+ {
+ for(String eachArg : args)
+ {
+ String[] r = eachArg.split("=");
+ if(r[0].equals("-DStreamPi.startupRunnerFileName"))
+ ClientInfo.getInstance().setRunnerFileName(r[1]);
+ else if(r[0].equals("-DStreamPi.showShutDownButton"))
+ ClientInfo.getInstance().setShowShutDownButton(r[1].equals("true"));
+ }
+
+ launch(args);
+ }
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/connection/Client.java
@@ -0,0 +1,962 @@
+package com.stream_pi.client.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.client.io.Config;
+import com.stream_pi.client.info.ClientInfo;
+import com.stream_pi.client.profile.ClientProfile;
+import com.stream_pi.client.window.ExceptionAndAlertHandler;
+import com.stream_pi.client.window.dashboard.actiongridpane.ActionBox;
+import com.stream_pi.themeapi.Theme;
+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.platform.Platform;
+import com.stream_pi.util.platform.ReleaseStatus;
+import com.stream_pi.util.version.Version;
+import javafx.concurrent.Task;
+
+import java.io.*;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.logging.Logger;
+
+public class Client extends Thread{
+
+ private Socket socket;
+
+ //private Logger logger;
+
+ private DataOutputStream dos;
+ private DataInputStream dis;
+
+ private AtomicBoolean stop = new AtomicBoolean(false);
+
+ private ClientListener clientListener;
+ private ExceptionAndAlertHandler exceptionAndAlertHandler;
+
+ private ClientInfo clientInfo;
+
+ private String serverIP;
+ private int serverPort;
+ private Logger logger;
+
+ public Client(String serverIP, int serverPort, ClientListener clientListener, ExceptionAndAlertHandler exceptionAndAlertHandler)
+ {
+ this.serverIP = serverIP;
+ this.serverPort = serverPort;
+
+ this.exceptionAndAlertHandler = exceptionAndAlertHandler;
+ this.clientInfo = ClientInfo.getInstance();
+ this.clientListener = clientListener;
+
+ logger = Logger.getLogger(Client.class.getName());
+
+ new Thread(new Task<Void>() {
+ @Override
+ protected Void call()
+ {
+ try
+ {
+ try {
+ logger.info("Trying to connect to server at "+serverIP+":"+serverPort);
+ socket = new Socket();
+ socket.connect(new InetSocketAddress(serverIP, serverPort), 5000);
+ clientListener.setConnected(true);
+ clientListener.updateSettingsConnectDisconnectButton();
+ logger.info("Connected to "+socket.getRemoteSocketAddress()+" !");
+ } catch (IOException e) {
+ e.printStackTrace();
+
+ clientListener.setConnected(false);
+ clientListener.updateSettingsConnectDisconnectButton();
+ throw new MinorException("connection Error", "Unable to connect to server. Please check settings and connection and try again.");
+ }
+
+ try
+ {
+ dos = new DataOutputStream(socket.getOutputStream());
+ dis = new DataInputStream(socket.getInputStream());
+ }
+ catch (IOException e)
+ {
+ logger.severe(e.getMessage());
+ e.printStackTrace();
+ throw new MinorException("Unable to set up io Streams to server. Check connection and try again.");
+ }
+ start();
+ } catch (MinorException e)
+ {
+ exceptionAndAlertHandler.handleMinorException(e);
+ }
+ return null;
+ }
+ }).start();
+ }
+
+ public synchronized void exit()
+ {
+ if(stop.get())
+ return;
+
+ logger.info("Stopping ...");
+
+ try
+ {
+ if(socket!=null)
+ {
+ disconnect();
+ }
+ }
+ catch (SevereException e)
+ {
+ logger.severe(e.getMessage());
+ exceptionAndAlertHandler.handleSevereException(e);
+ e.printStackTrace();
+ }
+ }
+
+
+
+ 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
+ {
+ byte[] txtBytes = text.getBytes();
+
+ 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!");
+ }
+
+ }
+
+ public void write(byte[] array) throws SevereException
+ {
+ try
+ {
+ dos.write(array);
+ }
+ catch (IOException e)
+ {
+ logger.severe(e.getMessage());
+ e.printStackTrace();
+ throw new SevereException("Unable to write to io Stream!");
+ }
+ }
+
+ @Override
+ public void run() {
+ try
+ {
+ while(!stop.get())
+ {
+ String msg = "";
+
+ try
+ {
+ String raw = dis.readUTF();
+
+ System.out.println("AAAAAAAAAAAAAAAAAA : "+raw);
+
+ int length = dis.readInt();
+
+ String[] precursor = raw.split("::");
+
+ String inputType = precursor[0];
+ String secondArg = precursor[1];
+
+
+ //ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+
+ /*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);
+
+ 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);
+ }
+
+
+ byteArrayOutputStream.close();
+
+ byte[] bArr = byteArrayOutputStream.toByteArray();*/
+
+ byte[] bArr = new byte[length];
+
+ dis.readFully(bArr);
+
+ if(inputType.equals("string"))
+ {
+ msg = new String(bArr);
+ }
+ else if(inputType.equals("action_icon"))
+ {
+ System.out.println("asdsdsxxxxxxxxxxxxxxxxxxxxxxxxxxx");
+ String[] secondArgSep = secondArg.split("!!");
+
+ String profileID = secondArgSep[0];
+ String actionID = secondArgSep[1];
+
+ clientListener.getClientProfiles().getProfileFromID(profileID).saveActionIcon(actionID, bArr);
+
+ Action a = clientListener.getClientProfiles().getProfileFromID(profileID).getActionFromID(actionID);
+ clientListener.clearActionBox(a.getLocation().getCol(), a.getLocation().getRow());
+ clientListener.renderAction(profileID, a);
+
+
+ continue;
+ }
+ }
+ catch (IOException e)
+ {
+ logger.severe(e.getMessage());
+ e.printStackTrace();
+
+ clientListener.setConnected(false);
+ clientListener.updateSettingsConnectDisconnectButton();
+
+ if(!stop.get())
+ {
+ //isDisconnect.set(true); //Prevent running disconnect
+ throw new MinorException("Accidentally disconnected from Server! (Failed at readUTF)");
+ }
+
+ exit();
+
+ return;
+ }
+
+
+ logger.info("Received text : '"+msg+"'");
+
+ String[] sep = msg.split("::");
+
+ String command = sep[0];
+
+ switch (command)
+ {
+ case "disconnect" : serverDisconnected(msg);
+ break;
+
+ case "get_client_details" : sendClientDetails();
+ break;
+
+ case "get_profiles" : sendProfileNamesToServer();
+ break;
+
+ case "get_profile_details": sendProfileDetailsToServer(sep[1]);
+ break;
+
+ case "save_action_details": saveActionDetails(sep);
+ break;
+
+ case "delete_action": deleteAction(sep[1], sep[2]);
+ break;
+
+ case "get_themes": sendThemesToServer();
+ break;
+
+ case "save_client_details": saveClientDetails(sep);
+ break;
+
+ case "save_client_profile": saveProfileDetails(sep);
+ break;
+
+ case "delete_profile": deleteProfile(sep[1]);
+ break;
+
+ case "action_failed": actionFailed(sep[1], sep[2]);
+ break;
+
+
+ default: logger.warning("Command '"+command+"' does not match records. Make sure client and server versions are equal.");
+
+ }
+ }
+ }
+ catch (SevereException e)
+ {
+ logger.severe(e.getMessage());
+ e.printStackTrace();
+
+ exceptionAndAlertHandler.handleSevereException(e);
+ }
+ catch (MinorException e)
+ {
+ logger.severe(e.getMessage());
+ e.printStackTrace();
+
+ exceptionAndAlertHandler.handleMinorException(e);
+ }
+ }
+
+
+
+
+ //commands
+
+ /*public void receiveActionIcon(String[] sep) throws MinorException {
+ String profileID = sep[1];
+ String actionID = sep[2];
+ int bytesToRead = Integer.parseInt(sep[3]);
+ int port = Integer.parseInt(sep[4]);
+
+ try
+ {
+ Socket tempSocket = new Socket(socket.getInetAddress(), port);
+ tempSocket.setReceiveBufferSize(bytesToRead);
+
+ tempSocket.setSoTimeout(10000);
+
+ DataInputStream dataInputStream = new DataInputStream(tempSocket.getInputStream());
+
+ byte[] dataIcon = new byte[bytesToRead];
+
+ dataInputStream.read(dataIcon);
+
+ clientProfiles.getProfileFromID(profileID).getActionFromID(actionID).setIcon(dataIcon);
+
+ dataInputStream.close();
+ tempSocket.close();
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ throw new MinorException("Unable to Receive icon");
+ }
+ }*/
+
+
+ public void sendIcon(String profileID, String actionID, byte[] icon) throws SevereException
+ {
+ try
+ {
+ Thread.sleep(50);
+ dos.writeUTF("action_icon::"+profileID+"!!"+actionID+"!!::"+icon.length);
+ dos.flush();
+ dos.writeInt(icon.length);
+ dos.flush();
+ write(icon);
+ dos.flush();
+ }
+ catch (IOException | InterruptedException e)
+ {
+ e.printStackTrace();
+ throw new SevereException("Unable to write to io Stream!");
+ }
+ }
+
+
+
+ /*public void sendIcon(String profileID, String actionID, byte[] icon) throws SevereException
+ {
+ try
+ {
+
+ ServerSocket tmpServer = new ServerSocket(0);
+
+ dos.writeUTF("action_icon::"+
+ profileID+"::"+
+ actionID+"::"+
+ icon.length+"::"+
+ tmpServer.getLocalPort()+"::");
+
+
+ Socket socket = tmpServer.accept();
+ socket.setSendBufferSize(icon.length);
+
+ DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
+
+ dataOutputStream.write(icon);
+
+ dataOutputStream.close();
+
+ tmpServer.close();
+
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ throw new SevereException(e.getMessage());
+ }
+ }*/
+
+ public void disconnect() throws SevereException
+ {
+ disconnect("");
+ }
+
+ public void disconnect(String message) throws SevereException
+ {
+ if(stop.get())
+ return;
+
+ stop.set(true);
+
+ logger.info("Sending server disconnect message ...");
+ writeToStream("disconnect::"+message+"::");
+
+ try
+ {
+ if(!socket.isClosed())
+ socket.close();
+
+ clientListener.setConnected(false);
+ clientListener.updateSettingsConnectDisconnectButton();
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ throw new SevereException("Unable to close socket");
+ }
+ }
+
+ public void sendThemesToServer() throws SevereException
+ {
+ StringBuilder finalQuery = new StringBuilder("themes::");
+
+ for(Theme theme : clientListener.getThemes().getThemeList())
+ {
+ finalQuery.append(theme.getFullName())
+ .append("__")
+ .append(theme.getShortName())
+ .append("__")
+ .append(theme.getAuthor())
+ .append("__")
+ .append(theme.getVersion().getText())
+ .append("__::");
+ }
+
+ writeToStream(finalQuery.toString());
+ }
+
+
+ public void sendActionIcon(String clientProfileID, String actionID) throws SevereException
+ {
+ System.out.println("sending action icon "+clientProfileID+", "+actionID);
+ sendIcon(clientProfileID, actionID, clientListener.getClientProfiles().getProfileFromID(clientProfileID).getActionFromID(actionID).getIconAsByteArray());
+ }
+
+ public void serverDisconnected(String message)
+ {
+ stop.set(true);
+ String txt = "Disconnected!";
+
+ if(!message.equals("disconnect::::"))
+ txt = "Message : "+message.split("::")[1];
+
+ exceptionAndAlertHandler.onAlert("Disconnected from Server", txt, StreamPiAlertType.WARNING);
+
+ if(!socket.isClosed()) {
+ try {
+ socket.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ clientListener.setConnected(false);
+ clientListener.updateSettingsConnectDisconnectButton();
+
+ }
+
+ public void sendClientDetails() throws SevereException
+ {
+ Version clientVersion = clientInfo.getVersion();
+ ReleaseStatus releaseStatus = clientInfo.getReleaseStatus();
+ Version clientCommsStandard = clientInfo.getCommsStandardVersion();
+ Version clientMinThemeStandard = clientInfo.getMinThemeSupportVersion();
+ String clientNickname = Config.getInstance().getClientNickName();
+ double screenWidth = Config.getInstance().getStartupWindowWidth();
+ double screenHeight = Config.getInstance().getStartupWindowHeight();
+ Platform OS = clientInfo.getPlatformType();
+ String defaultProfileID = Config.getInstance().getStartupProfileID();
+
+ writeToStream("client_details::"+
+ clientVersion.getText()+"::"+
+ releaseStatus+"::"+
+ clientCommsStandard.getText()+"::"+
+ clientMinThemeStandard.getText()+"::"+
+ clientNickname+"::"+
+ screenWidth+"::"+
+ screenHeight+"::"+
+ OS+"::" +
+ defaultProfileID+"::"+
+ clientListener.getDefaultThemeFullName()+"::");
+ }
+
+
+ public void sendProfileNamesToServer() throws SevereException
+ {
+ StringBuilder finalQuery = new StringBuilder("profiles::");
+
+ finalQuery.append(clientListener.getClientProfiles().getClientProfiles().size()).append("::");
+
+ for(ClientProfile clientProfile : clientListener.getClientProfiles().getClientProfiles())
+ {
+ finalQuery.append(clientProfile.getID()).append("::");
+ }
+
+ writeToStream(finalQuery.toString());
+ }
+
+ public void sendProfileDetailsToServer(String ID) throws SevereException
+ {
+ StringBuilder finalQuery = new StringBuilder("profile_details::");
+
+ ClientProfile clientProfile = clientListener.getClientProfiles().getProfileFromID(ID);
+
+ finalQuery.append(ID).append("::");
+
+ finalQuery.append(clientProfile.getName())
+ .append("::")
+ .append(clientProfile.getRows())
+ .append("::")
+ .append(clientProfile.getCols())
+ .append("::")
+ .append(clientProfile.getActionSize())
+ .append("::")
+ .append(clientProfile.getActionGap())
+ .append("::");
+
+
+ writeToStream(finalQuery.toString());
+
+
+ for(Action action : clientProfile.getActions())
+ {
+ sendActionDetails(clientProfile.getID(), action);
+ }
+
+ for(Action action : clientProfile.getActions())
+ {
+ if(action.isHasIcon())
+ {
+ System.out.println("23123123123 : "+action.getID() + action.isHasIcon());
+ sendActionIcon(clientProfile.getID(), action.getID());
+ }
+ }
+
+ }
+
+ public void sendActionDetails(String profileID, Action action) throws SevereException {
+
+ if(action == null)
+ {
+ logger.info("NO SUCH ACTION");
+ return;
+ }
+
+ StringBuilder finalQuery = new StringBuilder("action_details::");
+
+ finalQuery.append(profileID)
+ .append("::")
+ .append(action.getID())
+ .append("::")
+ .append(action.getActionType())
+ .append("::");
+
+ if(action.getActionType() == ActionType.NORMAL) {
+ finalQuery.append(action.getVersion().getText());
+ }
+
+ finalQuery.append("::");
+
+ if(action.getActionType() ==ActionType.NORMAL)
+ {
+ finalQuery.append(action.getModuleName());
+ }
+
+
+ finalQuery.append("::");
+
+ //display
+
+ finalQuery.append(action.getBgColourHex())
+ .append("::");
+
+ //icon
+ finalQuery.append(action.isHasIcon())
+ .append("::")
+ .append(action.isShowIcon())
+ .append("::");
+
+ //text
+ finalQuery.append(action.isShowDisplayText())
+ .append("::")
+ .append(action.getDisplayTextFontColourHex())
+ .append("::")
+ .append(action.getDisplayText())
+ .append("::")
+ .append(action.getDisplayTextAlignment())
+ .append("::");
+
+ //location
+
+ if(action.getLocation() == null)
+ finalQuery.append("-1::-1::");
+ else
+ finalQuery.append(action.getLocation().getRow())
+ .append("::")
+ .append(action.getLocation().getCol())
+ .append("::");
+
+ //client properties
+
+ ClientProperties clientProperties = action.getClientProperties();
+
+ finalQuery.append(clientProperties.getSize())
+ .append("::");
+
+ for(Property property : clientProperties.get())
+ {
+ finalQuery.append(property.getName())
+ .append("__")
+ .append(property.getRawValue())
+ .append("__");
+
+ finalQuery.append("!!");
+ }
+
+ finalQuery.append("::")
+ .append(action.getParent())
+ .append("::");
+
+
+ writeToStream(finalQuery.toString());
+
+
+ }
+
+ public void saveActionDetails(String[] sep)
+ {
+ String profileID = sep[1];
+
+ String ID = sep[2];
+ ActionType actionType = ActionType.valueOf(sep[3]);
+
+ //4 - Version
+ //5 - ModuleName
+
+ //display
+ String bgColorHex = sep[6];
+
+ //icon
+ boolean isHasIcon = sep[7].equals("true");
+ boolean isShowIcon = sep[8].equals("true");
+
+ //text
+ boolean isShowDisplayText = sep[9].equals("true");
+ String displayFontColor = sep[10];
+ String displayText = sep[11];
+ DisplayTextAlignment displayTextAlignment = DisplayTextAlignment.valueOf(sep[12]);
+
+ //location
+ String row = sep[13];
+ String col = sep[14];
+
+ Location location = new Location(Integer.parseInt(row), Integer.parseInt(col));
+
+ Action action = new Action(ID, actionType);
+
+ if(actionType == ActionType.NORMAL)
+ {
+ try
+ {
+ action.setVersion(new Version(sep[4]));
+ action.setModuleName(sep[5]);
+ }
+ catch (Exception e)
+ {
+ logger.severe(e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+
+ action.setBgColourHex(bgColorHex);
+
+ action.setShowIcon(isShowIcon);
+ action.setHasIcon(isHasIcon);
+
+ System.out.println("IS HAS ICON : "+isHasIcon+", IS SHOW ICON :"+isShowIcon);
+
+
+ action.setShowDisplayText(isShowDisplayText);
+ action.setDisplayTextFontColourHex(displayFontColor);
+ action.setDisplayText(displayText);
+ action.setDisplayTextAlignment(displayTextAlignment);
+
+
+ action.setLocation(location);
+
+ //client properties
+
+ int clientPropertiesSize = Integer.parseInt(sep[15]);
+
+ String[] clientPropertiesRaw = sep[16].split("!!");
+
+ ClientProperties clientProperties = new ClientProperties();
+
+ if(actionType == ActionType.FOLDER)
+ clientProperties.setDuplicatePropertyAllowed(true);
+
+ for(int i = 0;i<clientPropertiesSize; i++)
+ {
+ String[] clientPraw = clientPropertiesRaw[i].split("__");
+
+ Property property = new Property(clientPraw[0], Type.STRING);
+
+ if(clientPraw.length > 1)
+ property.setRawValue(clientPraw[1]);
+
+ clientProperties.addProperty(property);
+ }
+
+ action.setClientProperties(clientProperties);
+
+
+ String parent = sep[17];
+ action.setParent(parent);
+
+
+ try
+ {
+ Action old = clientListener.getClientProfiles().getProfileFromID(profileID).getActionFromID(action.getID());
+
+ if(old != null)
+ {
+ if(action.isHasIcon())
+ action.setIcon(clientListener.getClientProfiles().getProfileFromID(profileID).getActionFromID(action.getID()).getIconAsByteArray());
+ }
+
+ clientListener.getClientProfiles().getProfileFromID(profileID).addAction(action);
+
+ System.out.println("XXXXXXXXXXX " +action.isHasIcon());
+
+ //clientListener.getClientProfiles().getProfileFromID(profileID).saveActions();
+
+ clientListener.getClientProfiles().getProfileFromID(profileID).saveAction(action);
+
+ if(clientListener.getCurrentProfile().getID().equals(profileID) && action.getLocation().getCol()!=-1)
+ {
+ javafx.application.Platform.runLater(()->{
+ ActionBox box = clientListener.getActionBox(action.getLocation().getCol(), action.getLocation().getRow());
+ System.out.println(box==null);
+ System.out.println("GATYYY : "+action.getLocation().getCol()+","+action.getLocation().getRow());
+ box.clear();
+ box.setAction(action);
+ box.baseInit();
+ box.init();
+ });
+ }
+
+ //clientListener.clearActionBox(action.getLocation().getCol(), action.getLocation().getRow());
+ //clientListener.renderAction(profileID, action);
+
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ exceptionAndAlertHandler.handleMinorException(new MinorException(e.getMessage()));
+ }
+ }
+
+ public void deleteAction(String profileID, String actionID)
+ {
+ try
+ {
+
+
+ Action acc = clientListener.getClientProfiles().getProfileFromID(profileID).getActionFromID(actionID);
+
+ if(acc.getActionType() == ActionType.FOLDER)
+ {
+ ArrayList<String> idsToBeRemoved = new ArrayList<>();
+
+ ArrayList<String> folders = new ArrayList<>();
+ String folderToBeDeletedID = clientListener.getClientProfiles().getProfileFromID(profileID).getActionFromID(actionID).getID();
+
+ folders.add(folderToBeDeletedID);
+
+ boolean startOver = true;
+ while(startOver)
+ {
+ startOver = false;
+ for(Action action : clientListener.getClientProfiles().getProfileFromID(profileID).getActions())
+ {
+ if(folders.contains(action.getParent()))
+ {
+ if(!idsToBeRemoved.contains(action.getID()))
+ {
+ idsToBeRemoved.add(action.getID());
+ if(action.getActionType() == ActionType.FOLDER)
+ {
+ folders.add(action.getID());
+ startOver = true;
+ }
+ }
+ }
+ }
+ }
+
+
+ for(String ids : idsToBeRemoved)
+ {
+ clientListener.getClientProfiles().getProfileFromID(profileID).removeAction(ids);
+ }
+
+ }
+ else if (acc.getActionType() == ActionType.COMBINE)
+ {
+ for(Property property : acc.getClientProperties().get())
+ {
+ clientListener.getClientProfiles().getProfileFromID(profileID).removeAction(property.getRawValue());
+ }
+ }
+
+
+ clientListener.getClientProfiles().getProfileFromID(profileID).removeAction(acc.getID());
+
+ clientListener.getClientProfiles().getProfileFromID(profileID).saveActions();
+
+ if(acc.getLocation().getCol()!=-1)
+ {
+ clientListener.clearActionBox(acc.getLocation().getCol(), acc.getLocation().getRow());
+ clientListener.addBlankActionBox(acc.getLocation().getCol(), acc.getLocation().getRow());
+ }
+
+
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ exceptionAndAlertHandler.handleMinorException(new MinorException(e.getMessage()));
+ }
+ }
+
+ public void saveClientDetails(String[] sep)
+ {
+ try
+ {
+
+ Config.getInstance().setNickName(sep[1]);
+
+ String oldWidth = Config.getInstance().getStartupWindowWidth()+"";
+ String oldHeight = Config.getInstance().getStartupWindowHeight()+"";
+
+
+ Config.getInstance().setStartupWindowSize(
+ Double.parseDouble(sep[2]),
+ Double.parseDouble(sep[3])
+ );
+
+ Config.getInstance().setStartupProfileID(sep[4]);
+
+ String oldThemeFullName = Config.getInstance().getCurrentThemeFullName();
+
+ Config.getInstance().setCurrentThemeFullName(sep[5]);
+
+ if(!oldHeight.equals(sep[3]) || !oldWidth.equals(sep[2]) || !oldThemeFullName.equals(sep[5]))
+ javafx.application.Platform.runLater(()-> clientListener.init());
+
+
+ Config.getInstance().save();
+ javafx.application.Platform.runLater(()->clientListener.loadSettings());
+ }
+ catch (SevereException e)
+ {
+ e.printStackTrace();
+ exceptionAndAlertHandler.handleSevereException(e);
+ }
+ }
+
+ public void saveProfileDetails(String[] sep) throws SevereException, MinorException
+ {
+ ClientProfile clientProfile = clientListener.getClientProfiles().getProfileFromID(sep[1]);
+
+ if(clientProfile == null)
+ {
+ clientProfile = new ClientProfile(new File(Config.getInstance().getProfilesPath().toString()+"/"+sep[1]+".xml"),
+ Config.getInstance().getIconsPath());
+ }
+
+ clientProfile.setName(sep[2]);
+ clientProfile.setRows(Integer.parseInt(sep[3]));
+ clientProfile.setCols(Integer.parseInt(sep[4]));
+ clientProfile.setActionSize(Integer.parseInt(sep[5]));
+ clientProfile.setActionGap(Integer.parseInt(sep[6]));
+
+ try
+ {
+ clientListener.getClientProfiles().addProfile(clientProfile);
+ clientProfile.saveProfileDetails();
+ clientListener.refreshGridIfCurrent(sep[1]);
+ javafx.application.Platform.runLater(()->clientListener.loadSettings());
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new SevereException(e.getMessage());
+ }
+ }
+
+ public void deleteProfile(String ID)
+ {
+ clientListener.getClientProfiles().deleteProfile(clientListener.getClientProfiles().getProfileFromID(ID));
+ }
+
+ public void onActionClicked(String profileID, String actionID) throws SevereException {
+ writeToStream("action_clicked::"+profileID+"::"+actionID+"::");
+ }
+
+ public void actionFailed(String profileID, String actionID)
+ {
+ clientListener.onActionFailed(profileID, actionID);
+ }
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/connection/ClientListener.java
@@ -0,0 +1,49 @@
+package com.stream_pi.client.connection;
+
+import com.stream_pi.actionapi.action.Action;
+import com.stream_pi.client.profile.ClientProfile;
+import com.stream_pi.client.profile.ClientProfiles;
+import com.stream_pi.client.window.dashboard.actiongridpane.ActionBox;
+import com.stream_pi.themeapi.Theme;
+import com.stream_pi.themeapi.Themes;
+import com.stream_pi.util.exception.SevereException;
+
+public interface ClientListener {
+ void onActionFailed(String profileID, String actionID);
+ void onNormalActionClicked(String profileID, String actionID);
+
+ ClientProfiles getClientProfiles();
+
+ Themes getThemes();
+ String getDefaultThemeFullName();
+
+ void renderRootDefaultProfile() throws SevereException;
+
+ void setConnected(boolean isConnected);
+ boolean isConnected();
+
+ void renderProfile(ClientProfile clientProfile);
+
+ void clearActionBox(int col, int row);
+ void addBlankActionBox(int col, int row);
+ void renderAction(String currentProfileID, Action action);
+ void refreshGridIfCurrent(String currentProfileID);
+
+ ActionBox getActionBox(int col, int row);
+
+ ClientProfile getCurrentProfile();
+
+ Theme getCurrentTheme();
+
+ void init();
+
+ void disconnect(String message) throws SevereException;
+
+ void setupClientConnection();
+
+ void updateSettingsConnectDisconnectButton();
+
+ void onCloseRequest();
+
+ void loadSettings();
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/connection/protos/ClientConnectionProtos.proto
@@ -0,0 +1,49 @@
+syntax = "proto3";
+
+package protos;
+
+option java_package = "com.StreamPi.Client.Connection.protos";
+option java_outer_classname = "ClientConnectionProtos";
+
+message ClientAction
+{
+ string moduleName = 1;
+ string id = 2;
+
+ enum ActionType
+ {
+ FOLDER = 0;
+ COMBINE = 1;
+ NORMAL = 2;
+ }
+
+ ActionType actionType = 3;
+ int32 locationX = 4;
+ int32 locationY = 5;
+ bool hasIcon = 6;
+ string name = 7;
+ string actionName = 8;
+
+ repeated ClientProperty clientProperties = 9;
+}
+
+message ClientProperty
+{
+ string name = 1;
+ string value = 2;
+}
+
+message ClientProfile
+{
+ string name = 1;
+ string id = 2;
+
+ int32 rows = 3;
+ int32 cols = 4;
+
+ int32 actionSize = 5;
+ int32 actionGap = 6;
+
+ repeated ClientAction actions = 7;
+}
+
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/connection/protos/ClientGRPC.proto
@@ -0,0 +1,13 @@
+syntax = "proto3";
+
+package protos;
+
+option java_package = "com.StreamPi.Client.Connection.protos";
+option java_outer_classname = "ClientGRPC";
+
+import "com/StreamPi/Client/Connection/protos/ClientConnectionProtos.proto";
+
+service Connection
+{
+
+}
\ No newline at end of file
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/controller/Controller.java
@@ -0,0 +1,374 @@
+package com.stream_pi.client.controller;
+
+import com.stream_pi.actionapi.action.Action;
+import com.stream_pi.client.connection.Client;
+import com.stream_pi.client.io.Config;
+import com.stream_pi.client.info.ClientInfo;
+import com.stream_pi.client.profile.ClientProfile;
+import com.stream_pi.client.profile.ClientProfiles;
+import com.stream_pi.client.window.Base;
+import com.stream_pi.client.window.dashboard.actiongridpane.ActionBox;
+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.gluonhq.attach.lifecycle.LifecycleService;
+import com.gluonhq.attach.util.Services;
+
+import javafx.animation.Interpolator;
+import javafx.animation.KeyFrame;
+import javafx.animation.KeyValue;
+import javafx.animation.Timeline;
+import javafx.application.Platform;
+import javafx.scene.Node;
+import javafx.util.Duration;
+
+import java.io.*;
+
+
+public class Controller extends Base
+{
+ private Client client;
+
+ public Controller()
+ {
+ client = null;
+ }
+
+
+ private boolean firstRun = true;
+
+ @Override
+ public void init()
+ {
+ try
+ {
+ if(firstRun)
+ initBase();
+
+
+ if(getClientInfo().getPlatformType()!= com.stream_pi.util.platform.Platform.ANDROID && getClientInfo().getPlatformType() != com.stream_pi.util.platform.Platform.IOS) {
+ getStage().setWidth(getConfig().getStartupWindowWidth());
+ getStage().setHeight(getConfig().getStartupWindowHeight());
+ getStage().centerOnScreen();
+ setupFlags();
+ }
+
+
+ setupDashWindow();
+
+ getStage().show();
+
+ requestFocus();
+
+ if(Config.getInstance().isFirstTimeUse())
+ return;
+
+ setupSettingsWindowsAnimations();
+
+
+
+ getDashboardPane().getSettingsButton().setOnAction(event -> {
+ openSettingsTimeLine.play();
+ });
+
+ getSettingsPane().getCloseButton().setOnAction(event -> {
+ closeSettingsTimeLine.play();
+ });
+
+ setClientProfiles(new ClientProfiles(new File(getConfig().getProfilesPath()), getConfig().getStartupProfileID()));
+
+ if(getClientProfiles().getLoadingErrors().size() > 0)
+ {
+ StringBuilder errors = new StringBuilder("Please rectify the following errors and try again");
+
+ for(MinorException exception : getClientProfiles().getLoadingErrors())
+ {
+ errors.append("\n * ")
+ .append(exception.getMessage());
+ }
+
+ throw new MinorException("Profiles", errors.toString());
+ }
+
+ renderRootDefaultProfile();
+ loadSettings();
+
+ if(firstRun)
+ {
+ setupClientConnection();
+ firstRun = false;
+ }
+
+ }
+ catch (SevereException e)
+ {
+ handleSevereException(e);
+ return;
+ }
+ catch (MinorException e)
+ {
+ handleMinorException(e);
+ return;
+ }
+
+
+ }
+
+
+
+ @Override
+ public void setupClientConnection()
+ {
+ Platform.runLater(()->getSettingsPane().setDisableStatus(true));
+ client = new Client(getConfig().getSavedServerHostNameOrIP(), getConfig().getSavedServerPort(), this, this);
+ }
+
+ @Override
+ public void updateSettingsConnectDisconnectButton() {
+ getSettingsPane().setConnectDisconnectButtonStatus();
+ }
+
+ @Override
+ public void disconnect(String message) throws SevereException {
+ client.disconnect(message);
+ }
+
+
+ public void setupDashWindow()
+ {
+ getStage().setTitle("Stream-Pi Client");
+ getStage().setOnCloseRequest(e->onCloseRequest());
+ }
+
+
+ @Override
+ public void onCloseRequest()
+ {
+ if(isConnected())
+ client.exit();
+
+
+ getLogger().info("Shut down");
+ closeLogger();
+
+ if (ClientInfo.getInstance().getPlatformType() == com.stream_pi.util.platform.Platform.ANDROID)
+ Services.get(LifecycleService.class).ifPresent(LifecycleService::shutdown);
+ }
+
+ @Override
+ public void loadSettings() {
+ try {
+ getSettingsPane().loadData();
+ } catch (SevereException e) {
+ e.printStackTrace();
+ handleSevereException(e);
+ }
+ }
+
+
+ private Timeline openSettingsTimeLine;
+ private Timeline closeSettingsTimeLine;
+
+
+ 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 KeyFrame(Duration.millis(90.0D),
+ new KeyValue(settingsNode.opacityProperty(),
+ 1.0D, Interpolator.LINEAR)),
+
+ new KeyFrame(Duration.millis(0.0D),
+ new KeyValue(dashboardNode.opacityProperty(),
+ 1.0D, Interpolator.LINEAR)),
+ new KeyFrame(Duration.millis(90.0D),
+ new KeyValue(dashboardNode.opacityProperty(),
+ 0.0D, 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 KeyFrame(Duration.millis(90.0D),
+ new KeyValue(settingsNode.opacityProperty(),
+ 0.0D, Interpolator.LINEAR)),
+ new KeyFrame(Duration.millis(0.0D),
+ new KeyValue(dashboardNode.opacityProperty(),
+ 0.0D, Interpolator.LINEAR)),
+ new KeyFrame(Duration.millis(90.0D),
+ new KeyValue(dashboardNode.opacityProperty(),
+ 1.0D, Interpolator.LINEAR))
+ );
+
+ closeSettingsTimeLine.setOnFinished(event1 -> {
+ dashboardNode.toFront();
+ Platform.runLater(()-> {
+ try {
+ getSettingsPane().loadData();
+ } catch (SevereException e) {
+ e.printStackTrace();
+
+ handleSevereException(e);
+ }
+ });
+ });
+ }
+
+
+
+
+
+ @Override
+ public void handleMinorException(MinorException e)
+ {
+ Platform.runLater(()-> genNewAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.WARNING).show());
+ }
+
+ @Override
+ public void handleSevereException(SevereException e)
+ {
+ Platform.runLater(()->
+ {
+ StreamPiAlert alert = genNewAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.ERROR);
+
+ alert.setOnClicked(new StreamPiAlertListener()
+ {
+ @Override
+ public void onClick(String txt)
+ {
+ onCloseRequest();
+ Platform.exit();
+ }
+ });
+ alert.show();
+ });
+ }
+
+ @Override
+ public void onAlert(String title, String body, StreamPiAlertType alertType) {
+ Platform.runLater(()-> genNewAlert(title, body, alertType).show());
+ }
+
+ public StreamPiAlert genNewAlert(String title, String message, StreamPiAlertType alertType)
+ {
+ StreamPiAlert alert = new StreamPiAlert(title, message, alertType);
+ return alert;
+ }
+
+
+ private boolean isConnected = false;
+
+ @Override
+ public void onActionFailed(String profileID, String actionID) {
+ Platform.runLater(()-> getDashboardPane().getActionGridPane().actionFailed(profileID, actionID));
+ }
+
+ @Override
+ public void onNormalActionClicked(String profileID, String actionID) {
+ try {
+ client.onActionClicked(profileID, actionID);
+ } catch (SevereException e) {
+ e.printStackTrace();
+ handleSevereException(e);
+ }
+ }
+
+ @Override
+ public void setConnected(boolean isConnected) {
+ this.isConnected = isConnected;
+ }
+
+ @Override
+ public ActionBox getActionBox(int col, int row)
+ {
+ return getDashboardPane().getActionGridPane().getActionBox(col, row);
+ }
+
+ @Override
+ public boolean isConnected()
+ {
+ return isConnected;
+ }
+
+ @Override
+ public void renderProfile(ClientProfile clientProfile) {
+ try {
+ getDashboardPane().renderProfile(clientProfile);
+ } catch (SevereException e) {
+ e.printStackTrace();
+ handleSevereException(e);
+ }
+ }
+
+ @Override
+ public void clearActionBox(int col, int row)
+ {
+ Platform.runLater(()->getDashboardPane().getActionGridPane().clearActionBox(col, row));
+ }
+
+ @Override
+ public void addBlankActionBox(int col, int row)
+ {
+ Platform.runLater(()->getDashboardPane().getActionGridPane().addBlankActionBox(col, row));
+ }
+
+ @Override
+ public void renderAction(String currentProfileID, Action action)
+ {
+ Platform.runLater(()->{
+ try {
+ if(getDashboardPane().getActionGridPane().getCurrentParent().equals(action.getParent()) &&
+ getDashboardPane().getActionGridPane().getClientProfile().getID().equals(currentProfileID))
+ {
+ getDashboardPane().getActionGridPane().renderAction(action);
+ }
+
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ });
+ }
+
+ @Override
+ public void refreshGridIfCurrent(String profileID) {
+ ClientProfile clientProfile = getDashboardPane().getActionGridPane().getClientProfile();
+
+ if(clientProfile.getID().equals(profileID))
+ {
+ Platform.runLater(()->{
+ try {
+ getDashboardPane().renderProfile(getClientProfiles().getProfileFromID(profileID));
+ } catch (SevereException e) {
+ e.printStackTrace();
+ handleSevereException(e);
+ }
+ });
+ }
+ }
+
+ @Override
+ public ClientProfile getCurrentProfile() {
+ return getDashboardPane().getActionGridPane().getClientProfile();
+ }
+
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/info/ClientInfo.java
@@ -0,0 +1,147 @@
+/*
+ServerInfo.java
+
+Stores basic information about the server - name, platform type
+
+Contributors: Debayan Sutradhar (@dubbadhar)
+ */
+
+package com.stream_pi.client.info;
+
+import com.stream_pi.util.exception.MinorException;
+import com.stream_pi.util.platform.Platform;
+import com.stream_pi.util.platform.ReleaseStatus;
+import com.stream_pi.util.version.Version;
+
+public class ClientInfo {
+ private Version version;
+ private final ReleaseStatus releaseStatus;
+ private Platform platformType = null;
+
+ private String prePath;
+
+ private Version minThemeSupportVersion;
+ private Version minPluginSupportVersion;
+ private Version commsStandardVersion;
+
+ private String runnerFileName;
+
+ private static ClientInfo instance = null;
+
+ private ClientInfo(){
+
+ try {
+ version = new Version("1.0.0");
+ minThemeSupportVersion = new Version("1.0.0");
+ minPluginSupportVersion = new Version("1.0.0");
+ commsStandardVersion = new Version("1.0.0");
+ } catch (MinorException e) {
+ e.printStackTrace();
+ }
+
+ releaseStatus = ReleaseStatus.EA;
+
+ if(platformType == null)
+ {
+ String osName = System.getProperty("os.name").toLowerCase();
+
+ if(osName.contains("windows"))
+ {
+ prePath = "data/";
+ platformType = Platform.WINDOWS;
+ }
+ else if (osName.contains("linux"))
+ {
+ if(osName.contains("raspberrypi"))
+ {
+ prePath = "data/";
+ platformType = Platform.LINUX_RPI;
+ }
+ else
+ {
+ prePath = "data/";
+ platformType = Platform.LINUX;
+ }
+ }
+ else if(osName.contains("android")) // SPECIFY -Dsvm.targetName=android WHILE BUILDING ANDROID NATIVE IMAGE
+ {
+ prePath = "/sdcard/StreamPiClient/";
+ platformType = Platform.ANDROID;
+ }
+ else if (osName.contains("mac"))
+ {
+ prePath = "data/";
+ platformType = Platform.MAC;
+ }
+ else
+ {
+ prePath = "data/";
+ platformType = Platform.UNKNOWN;
+ }
+ }
+
+
+ }
+
+ public void setRunnerFileName(String runnerFileName)
+ {
+ this.runnerFileName = runnerFileName;
+ }
+
+ public String getRunnerFileName()
+ {
+ return runnerFileName;
+ }
+
+ public static synchronized ClientInfo getInstance(){
+ if(instance == null)
+ {
+ instance = new ClientInfo();
+ }
+
+ return instance;
+ }
+
+ private boolean isShowShutDownButton = false;
+
+ public void setShowShutDownButton(boolean showShutDownButton) {
+ isShowShutDownButton = showShutDownButton;
+ }
+
+ public boolean isShowShutDownButton() {
+ return isShowShutDownButton;
+ }
+
+ public String getPrePath() {
+ return prePath;
+ }
+
+ public Platform getPlatformType()
+ {
+ return platformType;
+ }
+
+ public Version getVersion() {
+ return version;
+ }
+
+ public ReleaseStatus getReleaseStatus()
+ {
+ return releaseStatus;
+ }
+
+ public Version getMinThemeSupportVersion()
+ {
+ return minThemeSupportVersion;
+ }
+
+ public Version getMinPluginSupportVersion()
+ {
+ return minPluginSupportVersion;
+ }
+
+ public Version getCommsStandardVersion()
+ {
+ return commsStandardVersion;
+ }
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/info/License.java
@@ -0,0 +1,41 @@
+/*
+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.client.info;
+
+public class License {
+ public static String getLicense()
+ {
+ return "Stream-Pi - Free & Open-Source Modular Cross-Platform Programmable Macro Pad\n" +
+ "Copyright (C) 2019-2021 Debayan Sutradhar (rnayabed), Samuel Quiñones (SamuelQuinones)\n" +
+ "\n" +
+ "This program is free software: you can redistribute it and/or modify\n" +
+ "it under the terms of the GNU General Public License as published by\n" +
+ "the Free Software Foundation, either version 3 of the License, or\n" +
+ "(at your option) any later version.\n" +
+ "\n" +
+ "This program is distributed in the hope that it will be useful,\n" +
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +
+ "GNU General Public License for more details.\n" +
+ "\n\n"+
+ "Opensource Libraries/Tech used :\n"+
+ "1. JavaFX - GNU General Public License with Classpath Exception\nhttp://openjdk.java.net/legal/gplv2+ce.html\n\n"+
+ "2. Gluon Attach - GPL License\nhttps://github.com/gluonhq/attach/blob/master/LICENSE\n\n"+
+ "3. Gluon Client Maven Plugin - BSD-3 License\nhttps://github.com/gluonhq/client-maven-plugin/blob/master/LICENSE\n\n" +
+ "4. Ikonli - Apache License\nhttps://github.com/kordamp/ikonli/blob/master/LICENSE\n\n";
+ }
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/io/Config.java
@@ -0,0 +1,359 @@
+/*
+Config.java
+
+Contributor(s) : Debayan Sutradhar (@rnayabed)
+
+handler for config.xml
+ */
+
+package com.stream_pi.client.io;
+
+import java.io.File;
+
+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.client.info.ClientInfo;
+import com.stream_pi.util.exception.SevereException;
+import com.stream_pi.util.platform.Platform;
+import com.stream_pi.util.xmlconfighelper.XMLConfigHelper;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class Config {
+ private static Config instance = null;
+
+ private final File configFile;
+
+ private Document document;
+
+ private Config() throws SevereException
+ {
+ try
+ {
+ configFile = new File(ClientInfo.getInstance().getPrePath()+"config.xml");
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+ document = docBuilder.parse(configFile);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new SevereException("Config", "unable to read config.xml");
+ }
+ }
+
+ public static synchronized Config getInstance() throws SevereException
+ {
+ if(instance == null)
+ instance = new Config();
+
+ return instance;
+ }
+
+ public void save() throws SevereException
+ {
+ 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 SevereException("Config", "unable to save config.xml");
+ }
+ }
+
+
+ //Client Element
+ public Element getClientElement()
+ {
+ return (Element) document.getElementsByTagName("client").item(0);
+ }
+
+ //Default Values
+ public String getDefaultClientNickName()
+ {
+ return "StreamPi Client";
+ }
+
+ public String getDefaultStartupProfileID()
+ {
+ return "default";
+ }
+
+ public String getDefaultCurrentThemeFullName()
+ {
+ return "com.StreamPi.DefaultLight";
+ }
+
+ public String getDefaultThemesPath()
+ {
+ return "Themes/";
+ }
+
+ public String getDefaultProfilesPath()
+ {
+ return "Profiles/";
+ }
+
+ public String getDefaultIconsPath()
+ {
+ return "Icons/";
+ }
+
+ public int getDefaultStartupWindowWidth()
+ {
+ return 800;
+ }
+
+ public int getDefaultStartupWindowHeight()
+ {
+ return 400;
+ }
+
+ //Getters
+
+ public String getClientNickName()
+ {
+ return XMLConfigHelper.getStringProperty(getClientElement(), "nickname", getDefaultClientNickName(), false, true, document, configFile);
+ }
+
+ public String getStartupProfileID()
+ {
+ return XMLConfigHelper.getStringProperty(getClientElement(), "startup-profile", getDefaultStartupProfileID(), false, true, document, configFile);
+ }
+
+ public String getCurrentThemeFullName()
+ {
+ return XMLConfigHelper.getStringProperty(getClientElement(), "current-theme-full-name", getDefaultCurrentThemeFullName(), false, true, document, configFile);
+ }
+
+ public String getThemesPath()
+ {
+ if(ClientInfo.getInstance().getPlatformType() == Platform.ANDROID)
+ return ClientInfo.getInstance().getPrePath() + "Themes/";
+
+ return XMLConfigHelper.getStringProperty(getClientElement(), "themes-path", getDefaultThemesPath(), false, true, document, configFile);
+ }
+
+ public String getProfilesPath()
+ {
+
+ if(ClientInfo.getInstance().getPlatformType() == Platform.ANDROID)
+ return ClientInfo.getInstance().getPrePath() + "Profiles/";
+
+ return XMLConfigHelper.getStringProperty(getClientElement(), "profiles-path", getDefaultThemesPath(), false, true, document, configFile);
+ }
+
+ public String getIconsPath()
+ {
+ if(ClientInfo.getInstance().getPlatformType() == Platform.ANDROID)
+ return ClientInfo.getInstance().getPrePath() + "Icons/";
+
+ return XMLConfigHelper.getStringProperty(getClientElement(), "icons-path", getDefaultThemesPath(), false, true, document, configFile);
+ }
+
+ public double getStartupWindowWidth()
+ {
+ return XMLConfigHelper.getDoubleProperty((Element) getClientElement().getElementsByTagName("startup-window-size").item(0), "width", getDefaultStartupWindowWidth(), false, true, document, configFile);
+ }
+
+ public double getStartupWindowHeight()
+ {
+ return XMLConfigHelper.getDoubleProperty((Element) getClientElement().getElementsByTagName("startup-window-size").item(0), "height", getDefaultStartupWindowHeight(), false, true, document, configFile);
+ }
+
+
+
+ //Setters
+
+ public void setNickName(String nickName)
+ {
+ getClientElement().getElementsByTagName("nickname").item(0).setTextContent(nickName);
+ }
+
+ public void setStartupProfileID(String id)
+ {
+ getClientElement().getElementsByTagName("startup-profile").item(0).setTextContent(id);
+ }
+
+ public void setCurrentThemeFullName(String name)
+ {
+ getClientElement().getElementsByTagName("current-theme-full-name").item(0).setTextContent(name);
+ }
+
+ public void setProfilesPath(String profilesPath)
+ {
+ getClientElement().getElementsByTagName("profiles-path").item(0).setTextContent(profilesPath);
+ }
+
+ public void setIconsPath(String iconsPath)
+ {
+ getClientElement().getElementsByTagName("icons-path").item(0).setTextContent(iconsPath);
+ }
+
+ public void setThemesPath(String themesPath)
+ {
+ getClientElement().getElementsByTagName("themes-path").item(0).setTextContent(themesPath);
+ }
+
+ //client > startup-window-size
+ public void setStartupWindowSize(double width, double height)
+ {
+ setStartupWindowWidth(width);
+ setStartupWindowHeight(height);
+ }
+
+ public void setStartupWindowWidth(double width)
+ {
+ ((Element) getClientElement().getElementsByTagName("startup-window-size").item(0))
+ .getElementsByTagName("width").item(0).setTextContent(width+"");
+ }
+
+ public void setStartupWindowHeight(double height)
+ {
+ ((Element) getClientElement().getElementsByTagName("startup-window-size").item(0))
+ .getElementsByTagName("height").item(0).setTextContent(height+"");
+ }
+
+
+
+
+
+
+
+
+
+
+
+ //comms-server
+ public Element getCommsServerElement()
+ {
+ return (Element) document.getElementsByTagName("comms-server").item(0);
+ }
+
+ public String getDefaultSavedServerHostNameOrIP()
+ {
+ return "127.0.0.1";
+ }
+
+ public int getDefaultSavedServerPort()
+ {
+ return -1;
+ }
+
+
+ public String getSavedServerHostNameOrIP()
+ {
+ return XMLConfigHelper.getStringProperty(getCommsServerElement(), "hostname-ip", getDefaultSavedServerHostNameOrIP(), false, true, document, configFile);
+ }
+
+ public int getSavedServerPort()
+ {
+ return XMLConfigHelper.getIntProperty(getCommsServerElement(), "port", getDefaultSavedServerPort(), false, true, document, configFile);
+ }
+
+
+ public void setServerHostNameOrIP(String hostNameOrIP)
+ {
+ getCommsServerElement().getElementsByTagName("hostname-ip").item(0).setTextContent(hostNameOrIP);
+ }
+
+ public void setServerPort(int port)
+ {
+ getCommsServerElement().getElementsByTagName("port").item(0).setTextContent(port+"");
+ }
+
+
+
+
+
+
+
+
+ //others
+ public Element getOthersElement()
+ {
+ return (Element) document.getElementsByTagName("others").item(0);
+ }
+
+ //others-default
+
+ public boolean getDefaultStartOnBoot()
+ {
+ return false;
+ }
+
+ public boolean getDefaultFullscreen()
+ {
+ return true;
+ }
+
+ public boolean getDefaultIsShowCursor()
+ {
+ return true;
+ }
+
+ public boolean getDefaultFirstTimeUse()
+ {
+ return true;
+ }
+
+
+
+ public boolean isShowCursor()
+ {
+ return XMLConfigHelper.getBooleanProperty(getOthersElement(), "show-cursor", getDefaultIsShowCursor(), false, true, document, configFile);
+ }
+
+
+ public boolean isStartOnBoot()
+ {
+ return XMLConfigHelper.getBooleanProperty(getOthersElement(), "start-on-boot", getDefaultStartOnBoot(), false, true, document, configFile);
+ }
+
+
+ public boolean isFullscreen()
+ {
+ return XMLConfigHelper.getBooleanProperty(getOthersElement(), "fullscreen", getDefaultFullscreen(), false, true, document, configFile);
+ }
+
+
+ public boolean isFirstTimeUse()
+ {
+ return XMLConfigHelper.getBooleanProperty(getOthersElement(), "first-time-use", true, false, true, document, configFile);
+ }
+
+
+ public void setStartOnBoot(boolean value)
+ {
+ getOthersElement().getElementsByTagName("start-on-boot").item(0).setTextContent(value+"");
+ }
+
+ public void setShowCursor(boolean value)
+ {
+ getOthersElement().getElementsByTagName("show-cursor").item(0).setTextContent(value+"");
+ }
+
+ public void setFullscreen(boolean value)
+ {
+ getOthersElement().getElementsByTagName("fullscreen").item(0).setTextContent(value+"");
+ }
+
+ public void setFirstTimeUse(boolean value)
+ {
+ getOthersElement().getElementsByTagName("first-time-use").item(0).setTextContent(value+"");
+ }
+
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/profile/ClientProfile.java
@@ -0,0 +1,679 @@
+package com.stream_pi.client.profile;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.logging.Logger;
+
+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.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.client.info.ClientInfo;
+import com.stream_pi.util.exception.MinorException;
+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;
+
+public class ClientProfile implements Cloneable{
+ private String name, ID;
+
+ private int rows, cols, actionSize, actionGap;
+
+
+ private HashMap<String, Action> actions;
+ private String iconsPath;
+
+ private File file;
+
+ private Logger logger;
+ private Document document;
+
+ public ClientProfile(File file, String iconsPath) throws MinorException
+ {
+ this.file = file;
+ this.iconsPath = iconsPath;
+
+ actions = new HashMap<>();
+
+ logger = Logger.getLogger(ClientProfile.class.getName());
+
+ if(!file.exists() && !file.isFile())
+ createConfigFile(file);
+
+ try
+ {
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+ document = docBuilder.parse(file);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new MinorException("profile", "Unable to read profile config file.");
+ }
+
+
+ setID(file.getName().replace(".xml", ""));
+ load();
+ }
+
+
+ private Element getProfileElement()
+ {
+ return (Element) document.getElementsByTagName("profile").item(0);
+ }
+
+ private Element getActionsElement()
+ {
+ return (Element) document.getElementsByTagName("actions").item(0);
+ }
+
+ public void load() throws MinorException
+ {
+ try
+ {
+ actions.clear();
+
+ logger.info("Loading profile "+getID()+" ...");
+
+ String name = XMLConfigHelper.getStringProperty(getProfileElement(), "name");
+ int rows = XMLConfigHelper.getIntProperty(getProfileElement(), "rows");
+ int cols = XMLConfigHelper.getIntProperty(getProfileElement(), "cols");
+ int actionSize = XMLConfigHelper.getIntProperty(getProfileElement(), "action-size");
+ int actionGap = XMLConfigHelper.getIntProperty(getProfileElement(), "action-gap");
+
+ setName(name);
+ setRows(rows);
+ setCols(cols);
+ setActionSize(actionSize);
+ setActionGap(actionGap);
+
+
+ //Load Actions
+
+ NodeList actionsNodesList = getActionsElement().getChildNodes();
+
+ int actionsSize = actionsNodesList.getLength();
+
+ logger.info("Actions Size : "+actionsSize);
+
+ for(int item = 0; item<actionsSize; item++)
+ {
+ Node eachActionNode = actionsNodesList.item(item);
+
+ if(eachActionNode.getNodeType() != Node.ELEMENT_NODE)
+ continue;
+
+ Element eachActionElement = (Element) eachActionNode;
+
+ if(!eachActionElement.getNodeName().equals("action"))
+ continue;
+
+
+
+ String id = XMLConfigHelper.getStringProperty(eachActionElement, "id");
+ String parent = XMLConfigHelper.getStringProperty(eachActionElement, "parent");
+
+ logger.info("Loading action "+id+" ...");
+
+ ActionType actionType = ActionType.valueOf(XMLConfigHelper.getStringProperty(eachActionElement, "action-type"));
+
+ Action action = new Action(id, actionType);
+ action.setParent(parent);
+
+ ClientProperties properties = new ClientProperties();
+
+ if(actionType == ActionType.FOLDER)
+ properties.setDuplicatePropertyAllowed(true);
+
+
+ if(actionType == ActionType.NORMAL)
+ {
+ action.setVersion(new Version(XMLConfigHelper.getStringProperty(eachActionElement, "version")));
+ action.setModuleName(XMLConfigHelper.getStringProperty(eachActionElement, "module-name"));
+ }
+
+ Node propertiesNode = eachActionElement.getElementsByTagName("properties").item(0);
+
+ NodeList propertiesNodesList = propertiesNode.getChildNodes();
+
+ int propertiesSize = propertiesNodesList.getLength();
+
+ for(int propItem = 0; propItem < propertiesSize; propItem++)
+ {
+ Node eachPropertyNode = propertiesNodesList.item(propItem);
+
+ if(eachPropertyNode.getNodeType() != Node.ELEMENT_NODE)
+ continue;
+
+ Element eachPropertyElement = (Element) eachPropertyNode;
+
+ if(eachPropertyElement.getNodeName() != "property")
+ continue;
+
+
+
+ String propertyName = XMLConfigHelper.getStringProperty(eachPropertyElement, "name");
+ String propertyValue = XMLConfigHelper.getStringProperty(eachPropertyElement, "value");
+
+ logger.info("Property Name : "+propertyName);
+ logger.info("Property Value : "+propertyValue);
+
+ Property p = new Property(propertyName, Type.STRING);
+ p.setRawValue(propertyValue);
+
+ properties.addProperty(p);
+ }
+
+ action.setClientProperties(properties);
+
+
+
+ Element displayElement = (Element) eachActionElement.getElementsByTagName("display").item(0);
+
+ //display
+
+ //location
+
+ try
+ {
+ Element locationElement = (Element) displayElement.getElementsByTagName("location").item(0);
+ int row = XMLConfigHelper.getIntProperty(locationElement, "row");
+ int col = XMLConfigHelper.getIntProperty(locationElement, "col");
+ action.setLocation(new Location(row, col));
+ }
+ catch (Exception e)
+ {
+ logger.info("Action has no location, most probably a combine action child");
+ }
+
+ //background
+
+ Element backgroundElement = (Element) displayElement.getElementsByTagName("background").item(0);
+
+ action.setBgColourHex(XMLConfigHelper.getStringProperty(backgroundElement, "colour-hex"));
+
+ Element iconElement = (Element) backgroundElement.getElementsByTagName("icon").item(0);
+
+ boolean showIcon = XMLConfigHelper.getBooleanProperty(iconElement, "show");
+ boolean hasIcon = XMLConfigHelper.getBooleanProperty(iconElement, "has");
+
+ Element textElement = (Element) displayElement.getElementsByTagName("text").item(0);
+
+ boolean showText = XMLConfigHelper.getBooleanProperty(textElement, "show");
+ String displayTextFontColour = XMLConfigHelper.getStringProperty(textElement, "colour-hex");
+ DisplayTextAlignment displayTextAlignment = DisplayTextAlignment.valueOf(XMLConfigHelper.getStringProperty(textElement, "alignment"));
+
+
+ action.setDisplayTextAlignment(displayTextAlignment);
+ action.setShowIcon(showIcon);
+ action.setHasIcon(hasIcon);
+ action.setShowDisplayText(showText);
+
+ action.setDisplayTextFontColourHex(displayTextFontColour);
+
+
+ String displayText = XMLConfigHelper.getStringProperty(textElement, "display-text");
+
+ action.setDisplayText(displayText);
+
+
+
+ if(hasIcon)
+ {
+ File f = new File(iconsPath+"/"+id);
+
+ try
+ {
+ byte[] iconFileByteArray = Files.readAllBytes(f.toPath());
+ action.setIcon(iconFileByteArray);
+ }
+ catch(NoSuchFileException e)
+ {
+ action.setIcon(null);
+ action.setHasIcon(false);
+ action.setShowIcon(false);
+ saveAction(action);
+ }
+ }
+
+
+
+ addAction(action);
+
+
+ logger.info("... Done!");
+ }
+
+ logger.info("Loaded profile "+getID()+" ("+getName()+") !");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+
+ throw new MinorException("profile", "profile is corrupt.");
+ }
+
+ }
+
+ public void addAction(Action action) throws CloneNotSupportedException {
+ actions.put(action.getID(), (Action) action.clone());
+ }
+
+
+
+
+ private void createConfigFile(File file) throws MinorException
+ {
+ try
+ {
+ file.createNewFile();
+
+ DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+ Document newDocument = dBuilder.newDocument();
+
+
+ Element rootElement = newDocument.createElement("config");
+ newDocument.appendChild(rootElement);
+
+ Element profileElement = newDocument.createElement("profile");
+ rootElement.appendChild(profileElement);
+
+ Element actionsElement = newDocument.createElement("actions");
+ rootElement.appendChild(actionsElement);
+
+ Element nameElement = newDocument.createElement("name");
+ nameElement.setTextContent("Untitled profile");
+ profileElement.appendChild(nameElement);
+
+ Element rowsElement = newDocument.createElement("rows");
+ rowsElement.setTextContent("3");
+ profileElement.appendChild(rowsElement);
+
+ Element colsElement = newDocument.createElement("cols");
+ colsElement.setTextContent("3");
+ profileElement.appendChild(colsElement);
+
+ Element actionSizeElement = newDocument.createElement("action-size");
+ actionSizeElement.setTextContent("100");
+ profileElement.appendChild(actionSizeElement);
+
+ Element actionGapElement = newDocument.createElement("action-gap");
+ actionGapElement.setTextContent("5");
+ profileElement.appendChild(actionGapElement);
+
+
+
+
+ TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ Transformer transformer = transformerFactory.newTransformer();
+ DOMSource source = new DOMSource(newDocument);
+ StreamResult result = new StreamResult(file);
+ transformer.transform(source, result);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new MinorException(e.getMessage());
+ }
+ }
+
+
+
+ public void deleteProfile()
+ {
+ file.delete();
+ }
+
+
+ public void saveAction(Action action) throws Exception {
+
+ Element newActionElement = document.createElement("action");
+ getActionsElement().appendChild(newActionElement);
+
+ Element idElement = document.createElement("id");
+ idElement.setTextContent(action.getID());
+ newActionElement.appendChild(idElement);
+
+ Element parentElement = document.createElement("parent");
+ parentElement.setTextContent(action.getParent());
+ newActionElement.appendChild(parentElement);
+
+ Element actionTypeElement = document.createElement("action-type");
+ actionTypeElement.setTextContent(action.getActionType()+"");
+ newActionElement.appendChild(actionTypeElement);
+
+ if(action.getActionType() == ActionType.NORMAL)
+ {
+ Element versionElement = document.createElement("version");
+ versionElement.setTextContent(action.getVersion().getText());
+ newActionElement.appendChild(versionElement);
+
+ System.out.println(action.getModuleName());
+
+ Element moduleNameElement = document.createElement("module-name");
+ moduleNameElement.setTextContent(action.getModuleName());
+ newActionElement.appendChild(moduleNameElement);
+ }
+
+ Element displayElement = document.createElement("display");
+ newActionElement.appendChild(displayElement);
+
+ Element backgroundElement = document.createElement("background");
+ displayElement.appendChild(backgroundElement);
+
+ Element colourHexElement = document.createElement("colour-hex");
+ colourHexElement.setTextContent(action.getBgColourHex());
+ backgroundElement.appendChild(colourHexElement);
+
+ Element iconElement = document.createElement("icon");
+
+ Element iconShowElement = document.createElement("show");
+ iconShowElement.setTextContent(action.isShowIcon()+"");
+ iconElement.appendChild(iconShowElement);
+
+ Element iconHasElement = document.createElement("has");
+ iconHasElement.setTextContent(action.isHasIcon()+"");
+ iconElement.appendChild(iconHasElement);
+
+ backgroundElement.appendChild(iconElement);
+
+ Element textElement = document.createElement("text");
+ displayElement.appendChild(textElement);
+
+ Element textTolourHexElement = document.createElement("colour-hex");
+ textTolourHexElement.setTextContent(action.getDisplayTextFontColourHex());
+ textElement.appendChild(textTolourHexElement);
+
+ Element textShowElement = document.createElement("show");
+ textShowElement.setTextContent(action.isShowDisplayText()+"");
+ textElement.appendChild(textShowElement);
+
+ Element textDisplayTextElement = document.createElement("display-text");
+ textDisplayTextElement.setTextContent(action.getDisplayText());
+ textElement.appendChild(textDisplayTextElement);
+
+ Element textAlignmentElement = document.createElement("alignment");
+ textAlignmentElement.setTextContent(action.getDisplayTextAlignment()+"");
+ textElement.appendChild(textAlignmentElement);
+
+
+ Element locationElement = document.createElement("location");
+ displayElement.appendChild(locationElement);
+
+ Element colElement = document.createElement("col");
+ colElement.setTextContent(action.getLocation().getCol()+"");
+ locationElement.appendChild(colElement);
+
+ Element rowElement = document.createElement("row");
+ rowElement.setTextContent(action.getLocation().getRow()+"");
+ locationElement.appendChild(rowElement);
+
+
+ Element propertiesElement = document.createElement("properties");
+ newActionElement.appendChild(propertiesElement);
+
+ for(String key : action.getClientProperties().getNames())
+ {
+ for(Property eachProperty : action.getClientProperties().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 int getActionIndexInConfig(String actionID)
+ {
+ NodeList actionsList = getActionsElement().getChildNodes();
+
+ int actionsSize = actionsList.getLength();
+
+ int index = 0;
+
+ for(int i = 0;i<actionsSize;i++)
+ {
+ Node eachActionNode = actionsList.item(index);
+
+ if(eachActionNode.getNodeType() != Node.ELEMENT_NODE)
+ continue;
+
+ if(!eachActionNode.getNodeName().equals("action"))
+ continue;
+
+ Element eachActionElement = (Element) eachActionNode;
+
+ Element idElement = (Element) eachActionElement.getElementsByTagName("id").item(0);
+
+
+ if(idElement.getTextContent().equals(actionID))
+ return index;
+
+
+ index++;
+ }
+
+
+ return -1;
+ }
+
+ public void saveActionIcon(String actionID, byte[] array){
+ int index = getActionIndexInConfig(actionID);
+
+ getActionFromID(actionID).setIcon(array);
+
+ File iconFile = new File(iconsPath+"/"+actionID);
+ if(iconFile.exists())
+ {
+ boolean result = iconFile.delete();
+ System.out.println("result : "+result);
+ }
+
+ try
+ {
+ OutputStream outputStream = new FileOutputStream(iconFile);
+ outputStream.write(array);
+ outputStream.flush();
+ outputStream.close();
+
+ Element actionElement = (Element) getActionsElement().getElementsByTagName("action").item(index);
+
+ Element displayElement = (Element) actionElement.getElementsByTagName("display").item(0);
+ Element backgroundElement = (Element) displayElement.getElementsByTagName("background").item(0);
+ Element iconElement = (Element) backgroundElement.getElementsByTagName("icon").item(0);
+
+ Element hasElement = (Element) iconElement.getElementsByTagName("has").item(0);
+ hasElement.setTextContent("true");
+
+ save();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void save() throws Exception
+ {
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ Result output = new StreamResult(file);
+ Source input = new DOMSource(document);
+
+ transformer.transform(input, output);
+ }
+
+ public void saveProfileDetails() throws Exception {
+ XMLConfigHelper.removeChilds(getProfileElement());
+
+ Element nameElement = document.createElement("name");
+ nameElement.setTextContent(getName());
+ getProfileElement().appendChild(nameElement);
+
+ Element rowsElement = document.createElement("rows");
+ rowsElement.setTextContent(getRows()+"");
+ getProfileElement().appendChild(rowsElement);
+
+ Element colsElement = document.createElement("cols");
+ colsElement.setTextContent(getCols()+"");
+ getProfileElement().appendChild(colsElement);
+
+ Element actionSizeElement = document.createElement("action-size");
+ actionSizeElement.setTextContent(getActionSize()+"");
+ getProfileElement().appendChild(actionSizeElement);
+
+ Element actionGapElement = document.createElement("action-gap");
+ actionGapElement.setTextContent(getActionGap()+"");
+ getProfileElement().appendChild(actionGapElement);
+
+ save();
+ }
+
+ public void saveActions() throws Exception
+ {
+ XMLConfigHelper.removeChilds(getActionsElement());
+ save();
+ for(Action action : getActions())
+ {
+ logger.info("ACTION ID :"+action.getID());
+ logger.info("Action ICON : "+action.isHasIcon());
+ saveAction(action);
+ }
+ }
+
+
+
+ public void removeAction(String ID) throws Exception {
+ int index = getActionIndexInConfig(ID);
+
+ if(index>-1)
+ {
+
+ Element actionElement = (Element) getActionsElement().getElementsByTagName("action").item(index);
+
+ Element displayElement = (Element) actionElement.getElementsByTagName("display").item(0);
+ Element backgroundElement = (Element) displayElement.getElementsByTagName("background").item(0);
+ Element iconElement = (Element) backgroundElement.getElementsByTagName("icon").item(0);
+
+ if(XMLConfigHelper.getBooleanProperty(iconElement, "has"))
+ {
+ File file = new File(ClientInfo.getInstance().getPrePath()+iconsPath+"/"+ID);
+
+ System.out.println(file.delete());
+ }
+ actions.remove(ID);
+ }
+
+ }
+
+ public ArrayList<Action> getActions()
+ {
+ ArrayList<Action> p = new ArrayList<>();
+ for(String profile : actions.keySet())
+ p.add(actions.get(profile));
+ return p;
+ }
+
+ public String getID()
+ {
+ return ID;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public int getRows()
+ {
+ return rows;
+ }
+
+ public int getCols()
+ {
+ return cols;
+ }
+
+ public int getActionSize()
+ {
+ return actionSize;
+ }
+
+ public Action getActionFromID(String ID)
+ {
+ return actions.getOrDefault(ID, null);
+ }
+
+ public int getActionGap()
+ {
+ return actionGap;
+ }
+
+ public void setRows(int rows)
+ {
+ this.rows = rows;
+ }
+
+ public void setCols(int cols)
+ {
+ this.cols = cols;
+ }
+
+ public void setID(String ID)
+ {
+ this.ID = ID;
+ }
+
+ public void setActionSize(int actionSize)
+ {
+ this.actionSize = actionSize;
+ }
+
+ public void setActionGap(int actionGap)
+ {
+ this.actionGap = actionGap;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+
+ public Object clone() throws CloneNotSupportedException
+ {
+ return super.clone();
+ }
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/profile/ClientProfiles.java
@@ -0,0 +1,119 @@
+package com.stream_pi.client.profile;
+
+import com.stream_pi.client.io.Config;
+import com.stream_pi.util.exception.MinorException;
+import com.stream_pi.util.exception.SevereException;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.logging.Logger;
+
+public class ClientProfiles {
+
+
+ private File profilesFolder;
+ private String defaultProfileID;
+
+ private Logger logger;
+
+ public ClientProfiles(File profilesFolder, String defaultProfileID) throws SevereException
+ {
+ logger = Logger.getLogger(ClientProfiles.class.getName());
+
+ this.defaultProfileID = defaultProfileID;
+ this.profilesFolder = profilesFolder;
+ clientProfiles = new HashMap<>();
+ loadingErrors = new ArrayList<>();
+
+ loadProfiles();
+ }
+
+ public void addProfile(ClientProfile clientProfile) throws CloneNotSupportedException {
+ clientProfiles.put(clientProfile.getID(), (ClientProfile) clientProfile.clone());
+ }
+
+ public void deleteProfile(ClientProfile clientProfile)
+ {
+ clientProfiles.remove(clientProfile.getID());
+
+ clientProfile.deleteProfile();
+ }
+
+ private ArrayList<MinorException> loadingErrors;
+ private HashMap<String, ClientProfile> clientProfiles;
+
+ public void loadProfiles() throws SevereException
+ {
+ logger.info("Loading profiles ...");
+
+
+ String iconsPath = Config.getInstance().getIconsPath();
+
+ clientProfiles.clear();
+ loadingErrors.clear();
+
+ if(!profilesFolder.isDirectory())
+ {
+ throw new SevereException("Profiles","profile folder doesn't exist! Cant continue.");
+ }
+
+
+ File[] profilesFiles = profilesFolder.listFiles();
+ if(profilesFiles == null)
+ {
+ throw new SevereException("Profiles","profilesFiles returned null. Cant continue!");
+ }
+
+ for(File eachProfileFile : profilesFiles)
+ {
+ try
+ {
+ ClientProfile profile = new ClientProfile(eachProfileFile, iconsPath);
+ try
+ {
+ addProfile(profile);
+ }
+ catch (CloneNotSupportedException e)
+ {
+ e.printStackTrace();
+ throw new SevereException(e.getMessage());
+ }
+ }
+ catch (MinorException e)
+ {
+ if(eachProfileFile.getName().replace(".xml","").equals(defaultProfileID))
+ {
+ throw new SevereException("Profiles", "Default profile bad. Can't continue");
+ }
+
+ loadingErrors.add(new MinorException(e.getMessage()+" ("+eachProfileFile.getName().replace(".xml", "")));
+
+ e.printStackTrace();
+ }
+ }
+
+ logger.info("Loaded all profiles!");
+ }
+
+ public ArrayList<MinorException> getLoadingErrors()
+ {
+ return loadingErrors;
+ }
+
+ public ArrayList<ClientProfile> getClientProfiles()
+ {
+ ArrayList<ClientProfile> p = new ArrayList<>();
+ for(String profile : clientProfiles.keySet())
+ p.add(clientProfiles.get(profile));
+ return p;
+ }
+
+ public ClientProfile getProfileFromID(String profileID)
+ {
+ return clientProfiles.getOrDefault(profileID, null);
+ }
+
+
+
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/window/Base.java
@@ -0,0 +1,380 @@
+package com.stream_pi.client.window;
+
+import com.stream_pi.client.connection.ClientListener;
+import com.stream_pi.client.io.Config;
+import com.stream_pi.client.info.ClientInfo;
+
+import java.io.File;
+import java.util.logging.Logger;
+
+import com.stream_pi.client.Main;
+import com.stream_pi.client.profile.ClientProfiles;
+import com.stream_pi.client.window.dashboard.DashboardBase;
+import com.stream_pi.client.window.firsttimeuse.FirstTimeUse;
+import com.stream_pi.client.window.settings.SettingsBase;
+import com.stream_pi.themeapi.Theme;
+import com.stream_pi.themeapi.Themes;
+import com.stream_pi.util.alert.StreamPiAlert;
+import com.stream_pi.util.combobox.StreamPiComboBox;
+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.scene.CacheHint;
+import javafx.scene.Cursor;
+import javafx.scene.input.KeyCombination;
+import javafx.scene.layout.StackPane;
+import javafx.scene.text.Font;
+import javafx.stage.Stage;
+
+public abstract class Base extends StackPane implements ExceptionAndAlertHandler, ClientListener {
+
+ private Config config;
+
+ private ClientProfiles clientProfiles;
+
+ private ClientInfo clientInfo;
+
+ private Stage stage;
+
+ public Stage getStage()
+ {
+ return stage;
+ }
+
+ public Logger getLogger()
+ {
+ return logger;
+ }
+
+ private DashboardBase dashboardBase;
+ private SettingsBase settingsBase;
+
+ private FirstTimeUse firstTimeUse;
+
+ public FirstTimeUse getFirstTimeUse() {
+ return firstTimeUse;
+ }
+
+
+ private StackPane alertStackPane;
+
+ @Override
+ public ClientProfiles getClientProfiles() {
+ return clientProfiles;
+ }
+
+ public void setClientProfiles(ClientProfiles clientProfiles) {
+ this.clientProfiles = clientProfiles;
+ }
+
+ private Logger logger = null;
+ private StreamPiLogFileHandler logFileHandler = null;
+ private StreamPiLogFallbackHandler logFallbackHandler = null;
+
+ public void initLogger()
+ {
+ try
+ {
+ if(logger != null || logFileHandler != null)
+ return;
+
+ closeLogger();
+ logger = Logger.getLogger("");
+
+ if(new File(ClientInfo.getInstance().getPrePath()).getAbsoluteFile().getParentFile().canWrite())
+ {
+
+ String path = ClientInfo.getInstance().getPrePath()+"../streampi.log";
+
+ if(ClientInfo.getInstance().getPlatformType() == Platform.ANDROID)
+ path = ClientInfo.getInstance().getPrePath()+"streampi.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!");
+ }
+ }
+
+ public void closeLogger()
+ {
+ if(logFileHandler != null)
+ logFileHandler.close();
+ else if(logFallbackHandler != null)
+ logFallbackHandler.close();
+ }
+
+ public void initBase() throws SevereException
+ {
+
+ stage = (Stage) getScene().getWindow();
+
+ initLogger();
+
+ clientInfo = ClientInfo.getInstance();
+ dashboardBase = new DashboardBase(this, this);
+ dashboardBase.setCache(true);
+ dashboardBase.setCacheHint(CacheHint.SPEED);
+ dashboardBase.prefWidthProperty().bind(widthProperty());
+ dashboardBase.prefHeightProperty().bind(heightProperty());
+
+ settingsBase = new SettingsBase(this, this);
+ settingsBase.setCache(true);
+ settingsBase.setCacheHint(CacheHint.SPEED);
+
+ alertStackPane = new StackPane();
+ alertStackPane.setVisible(false);
+
+ StreamPiAlert.setParent(alertStackPane);
+ StreamPiComboBox.setParent(alertStackPane);
+
+ firstTimeUse = new FirstTimeUse(this, this);
+
+ getChildren().clear();
+ getChildren().addAll(settingsBase, dashboardBase, alertStackPane);
+
+ setStyle(null);
+ clearStylesheets();
+ applyDefaultStylesheet();
+
+ checkPrePathDirectory();
+
+ config = Config.getInstance();
+
+ if(config.isFirstTimeUse())
+ {
+ getChildren().add(firstTimeUse);
+ firstTimeUse.toFront();
+ }
+ else
+ {
+ dashboardBase.toFront();
+ }
+
+ initThemes();
+ }
+
+ private void checkPrePathDirectory() throws SevereException
+ {
+ try
+ {
+ File filex = new File(ClientInfo.getInstance().getPrePath());
+
+ if(filex.getAbsoluteFile().getParentFile().canWrite())
+ {
+ if(!filex.exists())
+ {
+ filex.mkdirs();
+ IOHelper.unzip(Main.class.getResourceAsStream("Default.obj"), ClientInfo.getInstance().getPrePath());
+ }
+ }
+ else
+ {
+ throw new SevereException("No storage permission. Give it!");
+ }
+
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new SevereException(e.getMessage());
+ }
+ }
+
+ public void setupFlags()
+ {
+ //Full Screen
+ if(getConfig().isFullscreen())
+ {
+ getStage().setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
+ getStage().setFullScreen(true);
+ }
+ else
+ {
+ getStage().setFullScreenExitKeyCombination(KeyCombination.keyCombination("Esc"));
+ getStage().setFullScreen(false);
+ }
+
+ //Cursor
+ if(getConfig().isShowCursor())
+ {
+ setCursor(Cursor.DEFAULT);
+ }
+ else
+ {
+ setCursor(Cursor.NONE);
+ }
+ }
+
+
+ public SettingsBase getSettingsPane() {
+ return settingsBase;
+ }
+
+ public DashboardBase getDashboardPane() {
+ return dashboardBase;
+ }
+
+ public void renderRootDefaultProfile() throws SevereException {
+ getDashboardPane().renderProfile(getClientProfiles().getProfileFromID(
+ Config.getInstance().getStartupProfileID()
+ ));
+ }
+
+
+
+ public void clearStylesheets()
+ {
+ getStylesheets().clear();
+ }
+
+ public void initThemes() throws SevereException
+ {
+ registerThemes();
+
+ applyDefaultTheme();
+ }
+
+
+
+ public void applyDefaultStylesheet()
+ {
+ Font.loadFont(Main.class.getResourceAsStream("Roboto.ttf"), 13);
+ getStylesheets().add(Main.class.getResource("style.css").toExternalForm());
+ }
+
+
+
+ public Config getConfig()
+ {
+ return config;
+ }
+
+ public ClientInfo getClientInfo()
+ {
+ return clientInfo;
+ }
+
+ private Theme currentTheme;
+
+ @Override
+ public Theme getCurrentTheme()
+ {
+ return currentTheme;
+ }
+
+
+ public void applyTheme(Theme t)
+ {
+ logger.info("Applying theme '"+t.getFullName()+"' ...");
+
+ if(t.getFonts() != null)
+ {
+ for(String fontFile : t.getFonts())
+ {
+ Font.loadFont(fontFile.replace("%20",""), 13);
+ }
+ }
+ currentTheme = t;
+ getStylesheets().addAll(t.getStylesheets());
+
+ logger.info("... Done!");
+ }
+
+ Themes themes;
+ public void registerThemes() throws SevereException
+ {
+ logger.info("Loading themes ...");
+ themes = new Themes(getConfig().getThemesPath(), getConfig().getCurrentThemeFullName(), clientInfo.getMinThemeSupportVersion());
+
+
+ if(themes.getErrors().size()>0)
+ {
+ StringBuilder themeErrors = new StringBuilder();
+
+ for(MinorException eachException : themes.getErrors())
+ {
+ themeErrors.append("\n * ").append(eachException.getShortMessage());
+ }
+
+ if(themes.getIsBadThemeTheCurrentOne())
+ {
+ themeErrors.append("\n\nReverted to default theme! (").append(getConfig().getDefaultCurrentThemeFullName()).append(")");
+
+ getConfig().setCurrentThemeFullName(getConfig().getDefaultCurrentThemeFullName());
+ getConfig().save();
+ }
+
+ handleMinorException(new MinorException("Theme Loading issues", themeErrors.toString()));
+ }
+
+ logger.info("... Done!");
+ }
+
+ @Override
+ public Themes getThemes() {
+ return themes;
+ }
+
+
+
+ public void applyDefaultTheme()
+ {
+ logger.info("Applying default theme ...");
+
+
+ boolean foundTheme = false;
+ for(Theme t: themes.getThemeList())
+ {
+ if(t.getFullName().equals(config.getCurrentThemeFullName()))
+ {
+ foundTheme = true;
+ applyTheme(t);
+ break;
+ }
+ }
+
+ if(foundTheme)
+ {
+ logger.info("... Done!");
+ }
+ else
+ {
+ logger.info("Theme not found. reverting to light theme ...");
+ try {
+ Config.getInstance().setCurrentThemeFullName("com.StreamPi.DefaultLight");
+ Config.getInstance().save();
+
+ applyDefaultTheme();
+ }
+ catch (SevereException e)
+ {
+ handleSevereException(e);
+ }
+ }
+
+
+ }
+
+ @Override
+ public String getDefaultThemeFullName()
+ {
+ return config.getCurrentThemeFullName();
+ }
+
+
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/window/ExceptionAndAlertHandler.java
@@ -0,0 +1,11 @@
+package com.stream_pi.client.window;
+
+import com.stream_pi.util.alert.StreamPiAlertType;
+import com.stream_pi.util.exception.MinorException;
+import com.stream_pi.util.exception.SevereException;
+
+public interface ExceptionAndAlertHandler {
+ void handleMinorException(MinorException e);
+ void handleSevereException(SevereException e);
+ void onAlert(String title, String body, StreamPiAlertType alertType);
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/window/dashboard/DashboardBase.java
@@ -0,0 +1,79 @@
+package com.stream_pi.client.window.dashboard;
+
+import com.stream_pi.client.connection.ClientListener;
+import com.stream_pi.client.profile.ClientProfile;
+import com.stream_pi.client.window.ExceptionAndAlertHandler;
+import com.stream_pi.client.window.dashboard.actiongridpane.ActionGridPane;
+import com.stream_pi.util.exception.SevereException;
+
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.CacheHint;
+import javafx.scene.control.Button;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import org.kordamp.ikonli.javafx.FontIcon;
+
+public class DashboardBase extends VBox {
+ private ExceptionAndAlertHandler exceptionAndAlertHandler;
+
+ private ActionGridPane actionGridPane;
+ private Button settingsButton;
+
+ public DashboardBase(ExceptionAndAlertHandler exceptionAndAlertHandler, ClientListener clientListener)
+ {
+ this.exceptionAndAlertHandler = exceptionAndAlertHandler;
+
+ actionGridPane = new ActionGridPane(exceptionAndAlertHandler, clientListener);
+
+ FontIcon fontIcon = new FontIcon("fas-cog");
+ fontIcon.getStyleClass().addAll("dashboard_settings_button_icon");
+
+ settingsButton = new Button();
+ settingsButton.setGraphic(fontIcon);
+
+ HBox hBox = new HBox(settingsButton);
+ hBox.setPadding(new Insets(0,5,5,0));
+ hBox.setAlignment(Pos.CENTER_RIGHT);
+
+
+ getChildren().addAll(actionGridPane,hBox);
+
+ getStyleClass().add("dashboard");
+
+ setCache(true);
+ setCacheHint(CacheHint.SPEED);
+ }
+
+ public void renderProfile(ClientProfile clientProfile) throws SevereException
+ {
+ renderProfile(clientProfile, "root");
+ }
+
+ public void renderProfile(ClientProfile clientProfile, String currentParent) throws SevereException
+ {
+ actionGridPane.setClientProfile(clientProfile);
+ actionGridPane.setCurrentParent(currentParent);
+
+ actionGridPane.renderGrid();
+ actionGridPane.renderActions();
+ }
+
+ public void addBlankActionBox(int col, int row)
+ {
+ actionGridPane.addBlankActionBox(col, row);
+ }
+
+ public void clearActionBox(int col, int row)
+ {
+ actionGridPane.clearActionBox(col, row);
+ }
+
+ public ActionGridPane getActionGridPane() {
+ return actionGridPane;
+ }
+
+ public Button getSettingsButton() {
+ return settingsButton;
+ }
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/window/dashboard/actiongridpane/ActionBox.java
@@ -0,0 +1,316 @@
+package com.stream_pi.client.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.client.window.ExceptionAndAlertHandler;
+import javafx.animation.Interpolator;
+import javafx.animation.KeyFrame;
+import javafx.animation.KeyValue;
+import javafx.animation.Timeline;
+import javafx.geometry.Pos;
+import javafx.scene.CacheHint;
+import javafx.scene.control.Label;
+import javafx.scene.image.Image;
+import javafx.scene.layout.Background;
+import javafx.scene.layout.BackgroundImage;
+import javafx.scene.layout.BackgroundPosition;
+import javafx.scene.layout.BackgroundRepeat;
+import javafx.scene.layout.BackgroundSize;
+import javafx.scene.layout.StackPane;
+import javafx.scene.text.TextAlignment;
+import javafx.util.Duration;
+import org.kordamp.ikonli.javafx.FontIcon;
+
+import java.io.ByteArrayInputStream;
+import java.io.ObjectInputStream;
+import java.nio.ByteBuffer;
+
+public class ActionBox extends StackPane{
+
+ private Label displayTextLabel;
+
+ private int row;
+ private int col;
+
+ public int getRow() {
+ return row;
+ }
+
+ public int getCol() {
+ return col;
+ }
+
+
+
+ public void clear()
+ {
+ setAction(null);
+ setBackground(Background.EMPTY);
+ setStyle(null);
+ getChildren().clear();
+ }
+
+ private FontIcon statusIcon;
+
+ public void baseInit()
+ {
+
+ displayTextLabel = new Label();
+ displayTextLabel.setWrapText(true);
+ displayTextLabel.setTextAlignment(TextAlignment.CENTER);
+ displayTextLabel.getStyleClass().add("action_box_display_text_label");
+
+ displayTextLabel.prefHeightProperty().bind(heightProperty());
+ displayTextLabel.prefWidthProperty().bind(widthProperty());
+
+
+ statusIcon = new FontIcon();
+ statusIcon.setOpacity(0);
+ statusIcon.setCache(true);
+ statusIcon.setCacheHint(CacheHint.SPEED);
+ statusIcon.setIconSize(size - 30);
+
+
+ getChildren().addAll(statusIcon, displayTextLabel);
+
+ setMinSize(size, size);
+ setMaxSize(size, size);
+
+ getStyleClass().clear();
+ getStyleClass().add("action_box");
+ getStyleClass().add("action_box_icon_not_present");
+ getStyleClass().add("action_box_"+row+"_"+col);
+
+ setOnMouseClicked(touchEvent -> actionClicked());
+
+ setOnMousePressed(TouchEvent -> {
+ if(action != null)
+ {
+ getStyleClass().add("action_box_onclick");
+ }
+ });
+ setOnMouseReleased(TouchEvent ->{
+ if(action != null)
+ {
+ getStyleClass().remove("action_box_onclick");
+ }
+ });
+
+ statusIconAnimation = new Timeline(
+ new KeyFrame(
+ Duration.millis(0.0D),
+ new KeyValue(statusIcon.opacityProperty(), 0.0D, Interpolator.EASE_IN)),
+ new KeyFrame(
+ Duration.millis(100.0D),
+ new KeyValue(statusIcon.opacityProperty(), 1.0D, Interpolator.EASE_IN)),
+ new KeyFrame(
+ Duration.millis(600.0D),
+ new KeyValue(statusIcon.opacityProperty(), 1.0D, Interpolator.EASE_OUT)),
+ new KeyFrame(
+ Duration.millis(700.0D),
+ new KeyValue(statusIcon.opacityProperty(), 0.0D, Interpolator.EASE_OUT))
+ );
+
+ statusIconAnimation.setOnFinished(event -> {
+ statusIcon.toBack();
+ });
+
+
+ }
+
+ public void actionClicked()
+ {
+ if(action!=null)
+ {
+ if(action.getActionType() == ActionType.FOLDER)
+ {
+ getActionGridPaneListener().renderFolder(action.getID());
+ }
+ else
+ {
+ if(action.getActionType() == ActionType.COMBINE)
+ {
+ getActionGridPaneListener().combineActionClicked(action.getID());
+ }
+ else if(action.getActionType() == ActionType.NORMAL)
+ {
+ getActionGridPaneListener().normalActionClicked(action.getID());
+ }
+ }
+ }
+ }
+
+ public FontIcon getStatusIcon() {
+ return statusIcon;
+ }
+
+ private Timeline statusIconAnimation;
+
+ public Timeline getStatusIconAnimation() {
+ return statusIconAnimation;
+ }
+
+ public ActionGridPaneListener getActionGridPaneListener() {
+ return actionGridPaneListener;
+ }
+
+ private int size;
+ private ActionGridPaneListener actionGridPaneListener;
+
+ public ActionBox(int size, ActionGridPaneListener actionGridPaneListener, int row, int col)
+ {
+ this.actionGridPaneListener = actionGridPaneListener;
+ this.size = size;
+ this.row = row;
+ this.col = col;
+
+ baseInit();
+ }
+
+ public static Action deserialize(ByteBuffer buffer) {
+ try {
+ ByteArrayInputStream is = new ByteArrayInputStream(buffer.array());
+ ObjectInputStream ois = new ObjectInputStream(is);
+ Action obj = (Action) ois.readObject();
+ return obj;
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void setIcon(byte[] iconByteArray)
+ {
+ if(iconByteArray == null)
+ {
+ getStyleClass().remove("action_box_icon_present");
+ getStyleClass().add("action_box_icon_not_present");
+ setBackground(Background.EMPTY);
+ }
+ 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))
+ )
+ );
+ }
+ }
+
+ private Action action;
+
+ public Action getAction() {
+ return action;
+ }
+
+ private ExceptionAndAlertHandler exceptionAndAlertHandler;
+
+ private String parent;
+
+ public String getStreamPiParent() {
+ return parent;
+ }
+
+ public void setStreamPiParent(String parent) {
+ this.parent = parent;
+ }
+
+ public ActionBox(int size, Action action, ExceptionAndAlertHandler exceptionAndAlertHandler,
+ ActionGridPaneListener actionGridPaneListener, int row, int col)
+ {
+ this.actionGridPaneListener = actionGridPaneListener;
+ this.exceptionAndAlertHandler = exceptionAndAlertHandler;
+ this.action = action;
+ this.size = size;
+
+ this.row = row;
+ this.col = col;
+
+ baseInit();
+
+ init();
+
+ }
+
+ public void setAction(Action action)
+ {
+ this.action = action;
+ }
+
+ public void init()
+ {
+
+ setDisplayTextFontColour(action.getDisplayTextFontColourHex());
+
+ if(action.isShowDisplayText())
+ setDisplayTextLabel(action.getDisplayText());
+ else
+ setDisplayTextLabel("");
+
+ setDisplayTextAlignment(action.getDisplayTextAlignment());
+ setBackgroundColour(action.getBgColourHex());
+
+ if(action.isHasIcon() && action.isShowIcon())
+ {
+ setIcon(action.getIconAsByteArray());
+ }
+ else
+ {
+ setIcon(null);
+ }
+
+
+ }
+
+ public void animateStatus()
+ {
+ statusIcon.toFront();
+ statusIconAnimation.play();
+ }
+
+ public void setDisplayTextLabel(String text)
+ {
+ displayTextLabel.setText(text);
+ }
+
+ public void setDisplayTextAlignment(DisplayTextAlignment displayTextAlignment)
+ {
+ if(displayTextAlignment == DisplayTextAlignment.CENTER)
+ displayTextLabel.setAlignment(Pos.CENTER);
+ else if (displayTextAlignment == DisplayTextAlignment.BOTTOM)
+ displayTextLabel.setAlignment(Pos.BOTTOM_CENTER);
+ else if (displayTextAlignment == DisplayTextAlignment.TOP)
+ displayTextLabel.setAlignment(Pos.TOP_CENTER);
+ }
+ public void setDisplayTextFontColour(String colour)
+ {
+ System.out.println("'"+colour+"'COLOR");
+ if(!colour.isEmpty())
+ {
+ System.out.println(
+ "putting ..." + Thread.currentThread().getName()
+ );
+
+
+ displayTextLabel.setStyle("-fx-text-fill : "+colour+";");
+ }
+
+ }
+
+
+ public void setBackgroundColour(String colour)
+ {
+ System.out.println("COLOr : "+colour);
+ if(!colour.isEmpty() && action.getIconAsByteArray() == null)
+ setStyle("-fx-background-color : "+colour);
+ }
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/window/dashboard/actiongridpane/ActionGridPane.java
@@ -0,0 +1,369 @@
+package com.stream_pi.client.window.dashboard.actiongridpane;
+
+import java.util.logging.Logger;
+
+import com.stream_pi.actionapi.action.Action;
+import com.stream_pi.actionapi.action.Location;
+import com.stream_pi.client.connection.ClientListener;
+import com.stream_pi.client.profile.ClientProfile;
+import com.stream_pi.client.window.ExceptionAndAlertHandler;
+import com.stream_pi.util.alert.StreamPiAlertType;
+import com.stream_pi.util.exception.MinorException;
+import com.stream_pi.util.exception.SevereException;
+import javafx.concurrent.Task;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.StackPane;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import org.kordamp.ikonli.javafx.FontIcon;
+
+public class ActionGridPane extends GridPane implements ActionGridPaneListener {
+
+ private ExceptionAndAlertHandler exceptionAndAlertHandler;
+
+ private ClientListener clientListener;
+
+ public ActionGridPane(ExceptionAndAlertHandler exceptionAndAlertHandler, ClientListener clientListener)
+ {
+ this.clientListener = clientListener;
+
+ logger = Logger.getLogger(ActionGridPane.class.getName());
+ this.exceptionAndAlertHandler = exceptionAndAlertHandler;
+ getStyleClass().add("action_grid_pane");
+
+ setPadding(new Insets(5.0));
+
+ setPrefSize(USE_COMPUTED_SIZE, USE_COMPUTED_SIZE);
+
+
+ setAlignment(Pos.CENTER);
+
+ VBox.setVgrow(this, Priority.ALWAYS);
+ }
+
+ private String currentParent;
+
+ public void setCurrentParent(String currentParent) {
+ this.currentParent = currentParent;
+ }
+
+ public ClientProfile getClientProfile() {
+ return clientProfile;
+ }
+
+ private int rows, cols;
+
+ private ClientProfile clientProfile;
+
+ public void setClientProfile(ClientProfile clientProfile)
+ {
+ this.clientProfile = clientProfile;
+
+ setCurrentParent("root");
+ setRows(clientProfile.getRows());
+ setCols(clientProfile.getCols());
+ }
+
+ public void actionFailed(String profileID, String actionID)
+ {
+ if(getClientProfile().getID().equals(profileID))
+ {
+ Action action = getClientProfile().getActionFromID(actionID);
+ if(action != null)
+ {
+ if(currentParent.equals(action.getParent()))
+ {
+ failShow(action);
+ }
+ else
+ {
+ if(action.getLocation().getCol() == -1)
+ {
+ failShow(getClientProfile().getActionFromID(action.getParent()));
+ }
+ }
+ }
+ }
+ }
+
+ public void failShow(Action action)
+ {
+ for(Node node : getChildren())
+ {
+ if(GridPane.getColumnIndex(node) == action.getLocation().getRow() &&
+ GridPane.getRowIndex(node) == action.getLocation().getCol())
+ {
+
+ ActionBox actionBox = (ActionBox) node;
+
+ actionBox.getStatusIcon().setIconLiteral("fas-exclamation-triangle");
+ actionBox.getStatusIcon().setIconColor(Color.RED);
+
+ actionBox.animateStatus();
+
+ break;
+ }
+ }
+ }
+
+
+ public String getCurrentParent() {
+ return currentParent;
+ }
+
+ public StackPane getFolderBackButton() throws SevereException
+ {
+ StackPane stackPane = new StackPane();
+ stackPane.getStyleClass().add("action_box");
+ stackPane.getStyleClass().add("action_box_valid");
+
+ stackPane.setPrefSize(
+ getClientProfile().getActionSize(),
+ getClientProfile().getActionSize()
+ );
+
+ FontIcon fontIcon = new FontIcon("fas-chevron-left");
+
+ fontIcon.setIconSize(getClientProfile().getActionSize() - 30);
+
+ stackPane.setAlignment(Pos.CENTER);
+ stackPane.getChildren().add(fontIcon);
+
+ stackPane.setOnMouseClicked(e->returnToPreviousParent());
+
+ return stackPane;
+ }
+
+ public void renderGrid() throws SevereException {
+ clear();
+
+ setHgap(getClientProfile().getActionGap());
+ setVgap(getClientProfile().getActionGap());
+
+ boolean isFolder = false;
+
+ if(!getCurrentParent().equals("root"))
+ {
+ isFolder = true;
+
+ add(getFolderBackButton(), 0,0);
+ }
+
+ for(int row = 0; row<rows; row++)
+ {
+ for(int col = 0; col<cols; col++)
+ {
+ if(row == 0 && col == 0 && isFolder)
+ continue;
+
+ addBlankActionBox(col, row);
+
+ }
+ }
+ }
+
+ public void renderActions()
+ {
+ StringBuilder errors = new StringBuilder();
+ for(Action eachAction : getClientProfile().getActions())
+ {
+ logger.info("Action ID : "+eachAction.getID()+"\nInvalid : "+eachAction.isInvalid());
+
+ try {
+ renderAction(eachAction);
+ }
+ catch (SevereException e)
+ {
+ exceptionAndAlertHandler.handleSevereException(e);
+ }
+ catch (MinorException e)
+ {
+ errors.append("*").append(e.getShortMessage()).append("\n");
+ }
+ }
+
+ if(!errors.toString().isEmpty())
+ {
+ exceptionAndAlertHandler.handleMinorException(new MinorException("Error while rendering following actions", errors.toString()));
+ }
+ }
+
+ public void clear()
+ {
+ getChildren().clear();
+ }
+
+ private Logger logger;
+
+
+ public void clearActionBox(int col, int row)
+ {
+ for(Node node : getChildren())
+ {
+ if(GridPane.getColumnIndex(node) == row &&
+ GridPane.getRowIndex(node) == col)
+ {
+ getChildren().remove(node);
+ break;
+ }
+ }
+ }
+
+ public ActionBox getActionBox(int col, int row)
+ {
+ for(Node node : getChildren())
+ {
+ if(GridPane.getColumnIndex(node) == row &&
+ GridPane.getRowIndex(node) == col)
+ {
+ return (ActionBox) node;
+ }
+ }
+
+ return null;
+ }
+
+ public void addBlankActionBox(int col, int row)
+ {
+ ActionBox actionBox = new ActionBox(getClientProfile().getActionSize(), this, row, col);
+
+ actionBox.setStreamPiParent(currentParent);
+
+ add(actionBox, row, col);
+ }
+
+ public void renderAction(Action action) throws SevereException, MinorException
+ {
+ if(!action.getParent().equals(currentParent))
+ {
+ logger.info("Skipping action "+action.getID()+", not current parent!");
+ return;
+ }
+
+ if(action.getLocation().getRow()==-1)
+ {
+ logger.info("Action has -1 rowIndex. Probably Combine Action. Skipping ...");
+ return;
+ }
+
+ if(action.getLocation().getRow() > rows || action.getLocation().getCol() > cols)
+ {
+ throw new MinorException("Action "+action.getDisplayText()+" ("+action.getID()+") falls outside bounds.\n" +
+ " Consider increasing rows/cols from client settings and relocating/deleting it.");
+ }
+
+
+ Location location = action.getLocation();
+
+ ActionBox actionBox = new ActionBox(getClientProfile().getActionSize(), action, exceptionAndAlertHandler, this, location.getRow(), location.getCol());
+
+ actionBox.setStreamPiParent(currentParent);
+
+ clearActionBox(location.getCol(), location.getRow());
+
+ System.out.println(location.getCol()+","+location.getRow());
+ add(actionBox, location.getRow(), location.getCol());
+
+ }
+
+ public void setRows(int rows)
+ {
+ this.rows = rows;
+ }
+
+ public void setCols(int cols)
+ {
+ this.cols = cols;
+ }
+
+ public int getRows()
+ {
+ return rows;
+ }
+
+ public int getCols()
+ {
+ return cols;
+ }
+
+ private String previousParent;
+
+ public void setPreviousParent(String previousParent) {
+ this.previousParent = previousParent;
+ }
+
+ public String getPreviousParent() {
+ return previousParent;
+ }
+
+ @Override
+ public void renderFolder(String actionID) {
+ setCurrentParent(clientProfile.getActionFromID(actionID).getID());
+ setPreviousParent(clientProfile.getActionFromID(actionID).getParent());
+ try {
+ renderGrid();
+ renderActions();
+ } catch (SevereException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void normalActionClicked(String ID) {
+ if(clientListener.isConnected())
+ clientListener.onNormalActionClicked(getClientProfile().getID(), ID);
+ else
+ exceptionAndAlertHandler.onAlert("Not Connected", "Not Connected to any Server", StreamPiAlertType.ERROR);
+ }
+
+ @Override
+ public void combineActionClicked(String ID) {
+ if(clientListener.isConnected())
+ {
+ new Thread(new Task<Void>() {
+ @Override
+ protected Void call()
+ {
+ Action action = getClientProfile().getActionFromID(ID);
+
+ for(int i = 0;i<action.getClientProperties().get().size();i++)
+ {
+ try {
+ logger.info("Clicking "+i+", '"+action.getClientProperties().getSingleProperty(i+"").getRawValue()+"'");
+ normalActionClicked(action.getClientProperties().getSingleProperty(i+"").getRawValue());
+ } catch (MinorException e) {
+ e.printStackTrace();
+ exceptionAndAlertHandler.handleMinorException(e);
+ }
+ }
+
+ return null;
+ }
+ }).start();
+ }
+ }
+
+ public void returnToPreviousParent()
+ {
+ setCurrentParent(getPreviousParent());
+
+ if(!getPreviousParent().equals("root"))
+ {
+ System.out.println("parent : "+getPreviousParent());
+ setPreviousParent(getClientProfile().getActionFromID(
+ getPreviousParent()
+ ).getParent());
+ }
+
+ try {
+ renderGrid();
+ renderActions();
+ } catch (SevereException e) {
+ e.printStackTrace();
+ }
+ }
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/window/dashboard/actiongridpane/ActionGridPaneListener.java
@@ -0,0 +1,12 @@
+package com.stream_pi.client.window.dashboard.actiongridpane;
+
+import com.stream_pi.actionapi.action.Action;
+import com.stream_pi.actionapi.otheractions.FolderAction;
+
+public interface ActionGridPaneListener {
+
+ void renderFolder(String ID);
+
+ void normalActionClicked(String ID);
+ void combineActionClicked(String ID);
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/window/firsttimeuse/FinalConfigPane.java
@@ -0,0 +1,173 @@
+package com.stream_pi.client.window.firsttimeuse;
+
+import com.stream_pi.client.connection.ClientListener;
+import com.stream_pi.client.io.Config;
+import com.stream_pi.client.info.ClientInfo;
+import com.stream_pi.client.window.ExceptionAndAlertHandler;
+import com.stream_pi.util.alert.StreamPiAlert;
+import com.stream_pi.util.alert.StreamPiAlertType;
+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 com.stream_pi.util.platform.Platform;
+
+import javafx.geometry.Pos;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.control.TextField;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.VBox;
+
+public class FinalConfigPane extends VBox
+{
+ private TextField clientNicknameTextField;
+ private TextField serverIPHostNameTextField;
+ private TextField serverPortTextField;
+ private TextField displayWidthTextField;
+ private TextField displayHeightTextField;
+
+ private ExceptionAndAlertHandler exceptionAndAlertHandler;
+ private ClientListener clientListener;
+
+ public FinalConfigPane(ExceptionAndAlertHandler exceptionAndAlertHandler, ClientListener clientListener)
+ {
+ this.exceptionAndAlertHandler = exceptionAndAlertHandler;
+ this.clientListener = clientListener;
+
+ getStyleClass().add("first_time_use_pane_final_config");
+
+ Label label = new Label("Thats it. Now just a little bit and then youre set!");
+ label.setWrapText(true);
+ VBox.setVgrow(label, Priority.ALWAYS);
+ label.getStyleClass().add("first_time_use_pane_final_config_label");
+
+ clientNicknameTextField = new TextField();
+ serverIPHostNameTextField = new TextField();
+ serverPortTextField = new TextField();
+
+ displayWidthTextField = new TextField();
+ displayHeightTextField = new TextField();
+
+ HBoxInputBox clientNickNameInputBox = new HBoxInputBox("Nickname", clientNicknameTextField);
+ HBoxInputBox serverIPHostNameInputBox = new HBoxInputBox("Server IP", serverIPHostNameTextField);
+ HBoxInputBox serverIPPortInputBox = new HBoxInputBox("Server Port", serverPortTextField);
+ HBoxInputBox displayWidthInputBox = new HBoxInputBox("Display Width", displayWidthTextField);
+ HBoxInputBox displayHeightInputBox = new HBoxInputBox("Display Height", displayHeightTextField);
+
+ if(ClientInfo.getInstance().getPlatformType() == Platform.ANDROID)
+ {
+ displayWidthInputBox.setVisible(false);
+ displayHeightInputBox.setVisible(false);
+ }
+
+ Button confirmButton = new Button("Confirm");
+ confirmButton.setOnAction(event -> onConfirmButtonClicked());
+ HBox bBar = new HBox(confirmButton);
+ bBar.setAlignment(Pos.CENTER_RIGHT);
+
+ VBox v = new VBox(clientNickNameInputBox, serverIPHostNameInputBox, serverIPPortInputBox,
+ displayWidthInputBox, displayHeightInputBox);
+ v.setSpacing(10.0);
+
+ ScrollPane scrollPane = new ScrollPane(v);
+ v.prefWidthProperty().bind(scrollPane.widthProperty().subtract(25));
+
+ getChildren().addAll(label, scrollPane,new SpaceFiller(FillerType.VBox), bBar);
+
+ setSpacing(10.0);
+
+ setVisible(false);
+ }
+
+ private void onConfirmButtonClicked()
+ {
+ StringBuilder errors = new StringBuilder();
+
+ if(clientNicknameTextField.getText().isBlank())
+ {
+ errors.append("* Nick name cannot be blank.\n");
+ }
+
+ if(serverIPHostNameTextField.getText().isBlank())
+ {
+ errors.append("* Server IP cannot be empty.\n");
+ }
+
+ int port = -1;
+ try
+ {
+ port = Integer.parseInt(serverPortTextField.getText());
+
+ if(port < 1024)
+ errors.append("* Server IP should be above 1024.\n");
+ }
+ catch (NumberFormatException exception)
+ {
+ errors.append("* Server IP should be a number.\n");
+ }
+
+ double width=-1,height=-1;
+
+ if(ClientInfo.getInstance().getPlatformType() != Platform.ANDROID)
+ {
+ try
+ {
+ width = Double.parseDouble(displayWidthTextField.getText());
+
+ if(width < 0)
+ errors.append("* Display Width should be above 0.\n");
+ }
+ catch (NumberFormatException exception)
+ {
+ errors.append("* Display Width should be a number.\n");
+ }
+
+ try
+ {
+ height = Double.parseDouble(displayHeightTextField.getText());
+
+ if(height < 0)
+ errors.append("* Display Height should be above 0.\n");
+ }
+ catch (NumberFormatException exception)
+ {
+ errors.append("* Display Height should be a number.\n");
+ }
+ }
+
+ if(errors.toString().isEmpty())
+ {
+ try
+ {
+ Config.getInstance().setNickName(clientNicknameTextField.getText());
+ Config.getInstance().setServerHostNameOrIP(serverIPHostNameTextField.getText());
+ Config.getInstance().setServerPort(port);
+ Config.getInstance().setFirstTimeUse(false);
+
+ if(ClientInfo.getInstance().getPlatformType() != Platform.ANDROID)
+ {
+ Config.getInstance().setStartupWindowSize(
+ width, height
+ );
+ }
+
+
+ Config.getInstance().save();
+
+ clientListener.init();
+
+ }
+ catch(SevereException e)
+ {
+ exceptionAndAlertHandler.handleSevereException(e);
+ }
+ }
+ else
+ {
+ new StreamPiAlert("Uh Oh", "Please rectify the following errors and try again:\n"+errors.toString(), StreamPiAlertType.ERROR).show();
+ }
+ }
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/window/firsttimeuse/FirstTimeUse.java
@@ -0,0 +1,143 @@
+package com.stream_pi.client.window.firsttimeuse;
+
+import com.stream_pi.client.Main;
+import com.stream_pi.client.connection.ClientListener;
+import com.stream_pi.client.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;
+import javafx.scene.control.Label;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.StackPane;
+import javafx.scene.layout.VBox;
+import javafx.scene.text.Font;
+
+public class FirstTimeUse extends VBox{
+
+
+ public FirstTimeUse(ExceptionAndAlertHandler exceptionAndAlertHandler, ClientListener clientListener)
+ {
+ Font.loadFont(Main.class.getResourceAsStream("Roboto.ttf"), 13);
+ getStylesheets().add(Main.class.getResource("style.css").toExternalForm());
+
+ getStyleClass().add("first_time_use_pane");
+
+ setSpacing(10.0);
+ setPadding(new Insets(5));
+
+ headingLabel = new Label();
+ headingLabel.getStyleClass().add("first_time_use_pane_heading_label");
+
+ StackPane stackPane = new StackPane();
+ stackPane.getStyleClass().add("first_time_use_pane_stackpane");
+
+ VBox.setVgrow(stackPane, Priority.ALWAYS);
+
+ welcomePane = new WelcomePane();
+ licensePane = new LicensePane();
+ finalConfigPane = new FinalConfigPane(exceptionAndAlertHandler, clientListener);
+
+ stackPane.getChildren().addAll(
+ welcomePane,
+ licensePane,
+ finalConfigPane
+ );
+
+
+ nextButton = new Button("Next");
+ nextButton.setOnAction(event-> onNextButtonClicked());
+
+ previousButton = new Button("Previous");
+ previousButton.setOnAction(event-> onPreviousButtonClicked());
+
+
+ HBox buttonBar = new HBox(previousButton, new SpaceFiller(FillerType.HBox), nextButton);
+ buttonBar.setSpacing(10.0);
+
+ getChildren().addAll(headingLabel, stackPane, buttonBar);
+
+ setWindow(WindowName.WELCOME);
+ }
+
+ private Label headingLabel;
+ private Button nextButton;
+ private Button previousButton;
+ private WelcomePane welcomePane;
+ private LicensePane licensePane;
+ private FinalConfigPane finalConfigPane;
+
+ private WindowName windowName;
+
+ private void onNextButtonClicked()
+ {
+ if(windowName == WindowName.WELCOME)
+ {
+ setWindow(WindowName.LICENSE);
+ }
+ else if(windowName == WindowName.LICENSE)
+ {
+ setWindow(WindowName.FINAL);
+ }
+ }
+
+ private void onPreviousButtonClicked()
+ {
+ if(windowName == WindowName.FINAL)
+ {
+ setWindow(WindowName.LICENSE);
+ }
+ else if(windowName == WindowName.LICENSE)
+ {
+ setWindow(WindowName.WELCOME);
+ }
+ }
+
+ private void setWindow(WindowName windowName)
+ {
+ if (windowName == WindowName.WELCOME)
+ {
+ this.windowName = WindowName.WELCOME;
+ welcomePane.toFront();
+ welcomePane.setVisible(true);
+ licensePane.setVisible(false);
+ finalConfigPane.setVisible(false);
+
+ headingLabel.setText("");
+
+ nextButton.setDisable(false);
+ previousButton.setDisable(true);
+ }
+ else if (windowName == WindowName.LICENSE)
+ {
+ this.windowName = WindowName.LICENSE;
+ licensePane.toFront();
+ welcomePane.setVisible(false);
+ licensePane.setVisible(true);
+ finalConfigPane.setVisible(false);
+
+ headingLabel.setText("License Agreement");
+
+ nextButton.setDisable(false);
+ previousButton.setDisable(false);
+ }
+ else if (windowName == WindowName.FINAL)
+ {
+ this.windowName = WindowName.FINAL;
+ finalConfigPane.toFront();
+ welcomePane.setVisible(false);
+ licensePane.setVisible(false);
+ finalConfigPane.setVisible(true);
+
+ headingLabel.setText("Finishing up ...");
+
+ nextButton.setDisable(true);
+ previousButton.setDisable(false);
+ }
+ }
+
+
+
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/window/firsttimeuse/LicensePane.java
@@ -0,0 +1,28 @@
+package com.stream_pi.client.window.firsttimeuse;
+
+import com.stream_pi.client.info.License;
+
+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 LicensePane()
+ {
+ getStyleClass().add("first_time_use_pane_license");
+
+ Label label = new Label("By Clicking on 'Next', you agree with the license.");
+ label.prefWidthProperty().bind(widthProperty());
+ label.setWrapText(true);
+
+ TextArea licenseTextArea = new TextArea(License.getLicense());
+ licenseTextArea.setWrapText(false);
+ licenseTextArea.setEditable(false);
+
+ licenseTextArea.prefWidthProperty().bind(widthProperty());
+ VBox.setVgrow(licenseTextArea, Priority.ALWAYS);
+
+ getChildren().addAll(label, licenseTextArea);
+ }
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/window/firsttimeuse/WelcomePane.java
@@ -0,0 +1,25 @@
+package com.stream_pi.client.window.firsttimeuse;
+
+import javafx.geometry.Pos;
+import javafx.scene.control.Label;
+import javafx.scene.layout.VBox;
+
+public class WelcomePane extends VBox{
+ public WelcomePane()
+ {
+ getStyleClass().add("first_time_use_pane_welcome");
+
+ Label welcomeLabel = new Label("Welcome!");
+ welcomeLabel.getStyleClass().add("first_time_use_welcome_pane_welcome_label");
+
+ Label nextToContinue = new Label("Click on Next to continue with the setup.");
+ nextToContinue.getStyleClass().add("first_time_use_welcome_pane_next_to_continue_label");
+
+
+ setAlignment(Pos.CENTER);
+ setSpacing(5.0);
+ getChildren().addAll(welcomeLabel, nextToContinue);
+
+ setVisible(false);
+ }
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/window/firsttimeuse/WindowName.java
@@ -0,0 +1,5 @@
+package com.stream_pi.client.window.firsttimeuse;
+
+public enum WindowName {
+ WELCOME, LICENSE, FINAL
+}
--- /dev/null
+++ b/src/main/java/com/stream_pi/client/window/settings/SettingsBase.java
@@ -0,0 +1,521 @@
+package com.stream_pi.client.window.settings;
+
+import java.io.File;
+
+import com.stream_pi.client.connection.ClientListener;
+import com.stream_pi.client.io.Config;
+import com.stream_pi.client.info.ClientInfo;
+import com.stream_pi.client.profile.ClientProfile;
+import com.stream_pi.client.window.ExceptionAndAlertHandler;
+import com.stream_pi.themeapi.Theme;
+import com.stream_pi.util.alert.StreamPiAlert;
+import com.stream_pi.util.alert.StreamPiAlertType;
+import com.stream_pi.util.combobox.StreamPiComboBox;
+import com.stream_pi.util.combobox.StreamPiComboBoxFactory;
+import com.stream_pi.util.combobox.StreamPiComboBoxListener;
+import com.stream_pi.util.exception.MinorException;
+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.startatboot.SoftwareType;
+import com.stream_pi.util.startatboot.StartAtBoot;
+
+import javafx.application.Platform;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.control.*;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.VBox;
+
+public class SettingsBase extends VBox {
+ private TextField serverPortTextField;
+ private TextField serverHostNameOrIPTextField;
+
+ private StreamPiComboBox<ClientProfile> clientProfileComboBox;
+ private StreamPiComboBox<Theme> themeComboBox;
+
+ private TextField displayWidthTextField;
+ private TextField displayHeightTextField;
+
+ private TextField nickNameTextField;
+
+ private Button closeButton;
+ private Button saveButton;
+ private Button connectDisconnectButton;
+ private Button shutdownButton;
+
+ private ToggleButton startOnBootToggleButton;
+
+ private ToggleButton showCursorToggleButton;
+ private ToggleButton fullScreenToggleButton;
+
+ private ClientListener clientListener;
+ private ExceptionAndAlertHandler exceptionAndAlertHandler;
+
+ private TextField themesPathTextField;
+ private TextField iconsPathTextField;
+ private TextField profilesPathTextField;
+
+ public SettingsBase(ExceptionAndAlertHandler exceptionAndAlertHandler, ClientListener clientListener) {
+
+ getStyleClass().add("settings_base");
+ this.clientListener = clientListener;
+ this.exceptionAndAlertHandler = exceptionAndAlertHandler;
+
+ serverPortTextField = new TextField();
+ serverHostNameOrIPTextField = new TextField();
+ nickNameTextField = new TextField();
+
+ clientProfileComboBox = new StreamPiComboBox<>();
+
+ clientProfileComboBox.setStreamPiComboBoxFactory(new StreamPiComboBoxFactory<ClientProfile>()
+ {
+ @Override
+ public String getOptionDisplayText(ClientProfile object)
+ {
+ return object.getName();
+ }
+ });
+
+ clientProfileComboBox.setStreamPiComboBoxListener(new StreamPiComboBoxListener<ClientProfile>(){
+ @Override
+ public void onNewItemSelected(ClientProfile selectedItem)
+ {
+ clientListener.renderProfile(selectedItem);
+ }
+ });
+
+
+ themeComboBox = new StreamPiComboBox<>();
+ themeComboBox.setStreamPiComboBoxFactory(new StreamPiComboBoxFactory<Theme>()
+ {
+ @Override
+ public String getOptionDisplayText(Theme object)
+ {
+ return object.getShortName();
+ }
+ });
+
+ displayHeightTextField = new TextField();
+ displayWidthTextField = new TextField();
+
+ themesPathTextField = new TextField();
+ iconsPathTextField = new TextField();
+ profilesPathTextField = new TextField();
+
+ startOnBootToggleButton = new ToggleButton("Start On Boot");
+ startOnBootToggleButton.managedProperty().bind(startOnBootToggleButton.visibleProperty());
+
+ showCursorToggleButton = new ToggleButton("Show Cursor");
+ showCursorToggleButton.managedProperty().bind(showCursorToggleButton.visibleProperty());
+
+ fullScreenToggleButton = new ToggleButton("Full Screen");
+ fullScreenToggleButton.managedProperty().bind(fullScreenToggleButton.visibleProperty());
+
+ int prefWidth = 200;
+
+ Label licenseLabel = new Label("This software is licensed to GNU GPLv3. Check StreamPi Server > settings > About to see full License Statement.");
+ licenseLabel.setWrapText(true);
+
+ Label versionLabel = new Label(ClientInfo.getInstance().getReleaseStatus().getUIName() +" "+ClientInfo.getInstance().getVersion().getText());
+
+
+ HBoxInputBox themesPathInputBox = new HBoxInputBox("Themes Path", themesPathTextField, prefWidth);
+ themesPathInputBox.managedProperty().bind(themesPathInputBox.visibleProperty());
+
+
+ HBoxInputBox iconsPathInputBox = new HBoxInputBox("Icons Path", iconsPathTextField, prefWidth);
+ iconsPathInputBox.managedProperty().bind(iconsPathInputBox.visibleProperty());
+
+
+ HBoxInputBox profilesPathInputBox = new HBoxInputBox("Profiles Path", profilesPathTextField, prefWidth);
+ profilesPathInputBox.managedProperty().bind(profilesPathInputBox.visibleProperty());
+
+
+ HBoxInputBox screenHeightInputBox = new HBoxInputBox("Screen Height", displayHeightTextField, prefWidth);
+ screenHeightInputBox.managedProperty().bind(screenHeightInputBox.visibleProperty());
+
+
+ HBoxInputBox screenWidthInputBox = new HBoxInputBox("Screen Width", displayWidthTextField, prefWidth);
+ screenWidthInputBox.managedProperty().bind(screenWidthInputBox.visibleProperty());
+
+ if(ClientInfo.getInstance().getPlatformType() == com.stream_pi.util.platform.Platform.ANDROID)
+ {
+ themesPathInputBox.setVisible(false);
+ iconsPathInputBox.setVisible(false);
+ profilesPathInputBox.setVisible(false);
+
+ startOnBootToggleButton.setVisible(false);
+ showCursorToggleButton.setVisible(false);
+ fullScreenToggleButton.setVisible(false);
+
+ screenHeightInputBox.setVisible(false);
+ screenWidthInputBox.setVisible(false);
+ }
+
+
+ VBox vBox = new VBox(
+ new HBoxInputBox("Nick Name", nickNameTextField, prefWidth),
+ new HBoxInputBox("Host Name/IP", serverHostNameOrIPTextField, prefWidth),
+ new HBoxInputBox("Port", serverPortTextField, prefWidth),
+ new HBox(
+ new Label("Current profile"),
+ new SpaceFiller(SpaceFiller.FillerType.HBox),
+ clientProfileComboBox
+ ),
+ new HBox(
+ new Label("Theme"),
+ new SpaceFiller(SpaceFiller.FillerType.HBox),
+ themeComboBox
+ ),
+ screenHeightInputBox,
+ screenWidthInputBox,
+ themesPathInputBox,
+ iconsPathInputBox,
+ profilesPathInputBox,
+ startOnBootToggleButton,
+ showCursorToggleButton,
+ fullScreenToggleButton,
+ licenseLabel,
+ versionLabel
+ );
+ vBox.getStyleClass().add("settings_base_vbox");
+
+ vBox.setSpacing(5.0);
+ vBox.setPadding(new Insets(5));
+
+ ScrollPane scrollPane = new ScrollPane();
+ scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
+ VBox.setVgrow(scrollPane, Priority.ALWAYS);
+ scrollPane.getStyleClass().add("settings_base_scrollpane");
+ scrollPane.setContent(vBox);
+
+ vBox.setMinWidth(300);
+
+ vBox.prefWidthProperty().bind(scrollPane.widthProperty().subtract(25));
+
+
+ Label settingsLabel = new Label("settings");
+ settingsLabel.setPadding(new Insets(5,0,0,5));
+ settingsLabel.getStyleClass().add("settings_heading");
+
+ saveButton = new Button("Save");
+ saveButton.setOnAction(event->onSaveButtonClicked());
+
+ closeButton = new Button("Close");
+
+ connectDisconnectButton = new Button("Connect");
+ connectDisconnectButton.setOnAction(event -> onConnectDisconnectButtonClicked());
+
+ shutdownButton = new Button("Shutdown");
+ shutdownButton.setOnAction(event -> onShutdownButtonClicked());
+
+ Button exitButton = new Button("Exit");
+ exitButton.setOnAction(event -> onExitButtonClicked());
+
+ HBox buttonBar = new HBox(connectDisconnectButton, saveButton, exitButton, closeButton);
+
+ if(ClientInfo.getInstance().getPlatformType() == com.stream_pi.util.platform.Platform.LINUX &&
+ ClientInfo.getInstance().isShowShutDownButton())
+ {
+ buttonBar.getChildren().add(shutdownButton);
+ }
+
+
+ buttonBar.setPadding(new Insets(0,5,5,0));
+ buttonBar.setSpacing(5.0);
+ buttonBar.setAlignment(Pos.CENTER_RIGHT);
+
+ setSpacing(5.0);
+
+ getChildren().addAll(
+ settingsLabel,
+ scrollPane,
+ buttonBar
+ );
+ }
+
+ public void onExitButtonClicked()
+ {
+ clientListener.onCloseRequest();
+ Platform.exit();
+ }
+
+ public void setDisableStatus(boolean status)
+ {
+ saveButton.setDisable(status);
+ connectDisconnectButton.setDisable(status);
+ }
+
+ public void onShutdownButtonClicked()
+ {
+ clientListener.onCloseRequest();
+ try {
+ Runtime.getRuntime().exec("sudo halt");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public void onConnectDisconnectButtonClicked()
+ {
+ try
+ {
+ if(clientListener.isConnected())
+ clientListener.disconnect("Client disconnected from settings");
+ else
+ clientListener.setupClientConnection();
+ }
+ catch (SevereException e)
+ {
+ e.printStackTrace();
+ exceptionAndAlertHandler.handleSevereException(e);
+ }
+ }
+
+ public void setConnectDisconnectButtonStatus()
+ {
+ Platform.runLater(()->{
+ setDisableStatus(false);
+
+ System.out.println("q24qwdqwd : "+clientListener.isConnected());
+
+ if(clientListener.isConnected())
+ connectDisconnectButton.setText("Disconnect");
+ else
+ connectDisconnectButton.setText("Connect");
+ });
+
+ }
+
+ public Button getCloseButton() {
+ return closeButton;
+ }
+
+ public void loadData() throws SevereException
+ {
+ nickNameTextField.setText(Config.getInstance().getClientNickName());
+
+ serverHostNameOrIPTextField.setText(Config.getInstance().getSavedServerHostNameOrIP());
+ serverPortTextField.setText(Config.getInstance().getSavedServerPort()+"");
+
+ clientProfileComboBox.setOptions(clientListener.getClientProfiles().getClientProfiles());
+
+ int ind = 0;
+ for(int i = 0;i<clientProfileComboBox.getOptions().size();i++)
+ {
+ if(clientProfileComboBox.getOptions().get(i).getID().equals(clientListener.getCurrentProfile().getID()))
+ {
+ ind = i;
+ break;
+ }
+ }
+
+ clientProfileComboBox.setCurrentSelectedItemIndex(ind);
+
+ themeComboBox.setOptions(clientListener.getThemes().getThemeList());
+
+ int ind2 = 0;
+ for(int i = 0;i<themeComboBox.getOptions().size();i++)
+ {
+ if(themeComboBox.getOptions().get(i).getFullName().equals(clientListener.getCurrentTheme().getFullName()))
+ {
+ ind2 = i;
+ break;
+ }
+ }
+
+ themeComboBox.setCurrentSelectedItemIndex(ind2);
+
+ displayWidthTextField.setText(Config.getInstance().getStartupWindowWidth()+"");
+ displayHeightTextField.setText(Config.getInstance().getStartupWindowHeight()+"");
+
+ themesPathTextField.setText(Config.getInstance().getThemesPath());
+ iconsPathTextField.setText(Config.getInstance().getIconsPath());
+ profilesPathTextField.setText(Config.getInstance().getProfilesPath());
+
+ startOnBootToggleButton.setSelected(Config.getInstance().isStartOnBoot());
+
+ fullScreenToggleButton.setSelected(Config.getInstance().isFullscreen());
+ showCursorToggleButton.setSelected(Config.getInstance().isShowCursor());
+ }
+
+ public void onSaveButtonClicked()
+ {
+ StringBuilder errors = new StringBuilder();
+
+ int port = -1;
+ try
+ {
+ port = Integer.parseInt(serverPortTextField.getText());
+
+ if(port < 1024)
+ errors.append("* Server IP should be above 1024.\n");
+ }
+ catch (NumberFormatException exception)
+ {
+ errors.append("* Server IP should be a number.\n");
+ }
+
+ double width = -1;
+ try
+ {
+ width = Double.parseDouble(displayWidthTextField.getText());
+
+ if(width < 0)
+ errors.append("* Display Width should be above 0.\n");
+ }
+ catch (NumberFormatException exception)
+ {
+ errors.append("* Display Width should be a number.\n");
+ }
+
+ double height = -1;
+ try
+ {
+ height = Double.parseDouble(displayHeightTextField.getText());
+
+ if(height < 0)
+ errors.append("* Display Height should be above 0.\n");
+ }
+ catch (NumberFormatException exception)
+ {
+ errors.append("* Display Height should be a number.\n");
+ }
+
+ if(serverHostNameOrIPTextField.getText().isBlank())
+ {
+ errors.append("* Server IP cannot be empty.\n");
+ }
+
+ if(nickNameTextField.getText().isBlank())
+ {
+ errors.append("* Nick name cannot be blank.\n");
+ }
+
+
+ if(!errors.toString().isEmpty())
+ {
+ exceptionAndAlertHandler.handleMinorException(new MinorException(
+ "You made mistakes",
+ "Please fix the errors and try again :\n"+errors.toString()
+ ));
+ return;
+ }
+
+
+
+ try {
+ boolean toBeReloaded = false;
+
+ boolean breakConnection = false;
+
+ if(!Config.getInstance().getCurrentThemeFullName().equals(themeComboBox.getCurrentSelectedItem().getFullName()))
+ toBeReloaded = true;
+
+ Config.getInstance().setCurrentThemeFullName(themeComboBox.getCurrentSelectedItem().getFullName());
+
+ if(width != Config.getInstance().getStartupWindowWidth() || height != Config.getInstance().getStartupWindowHeight())
+ toBeReloaded = true;
+
+ Config.getInstance().setStartupWindowSize(width, height);
+
+
+ if(!Config.getInstance().getClientNickName().equals(nickNameTextField.getText()))
+ breakConnection = true;
+
+ Config.getInstance().setNickName(nickNameTextField.getText());
+
+ if(port != Config.getInstance().getSavedServerPort() || !serverHostNameOrIPTextField.getText().equals(Config.getInstance().getSavedServerHostNameOrIP()))
+ breakConnection = true;
+
+ Config.getInstance().setServerPort(port);
+ Config.getInstance().setServerHostNameOrIP(serverHostNameOrIPTextField.getText());
+
+ boolean startOnBoot = startOnBootToggleButton.isSelected();
+
+ if(Config.getInstance().isStartOnBoot() != startOnBoot)
+ {
+ if(ClientInfo.getInstance().getRunnerFileName() == null)
+ {
+ new StreamPiAlert("Uh Oh", "No Runner File Name Specified as startup arguments. Cant set run at boot.", StreamPiAlertType.ERROR).show();
+ startOnBoot = false;
+ }
+ else
+ {
+ StartAtBoot startAtBoot = new StartAtBoot(SoftwareType.CLIENT, ClientInfo.getInstance().getPlatformType());
+ if(startOnBoot)
+ {
+ startAtBoot.create(new File(ClientInfo.getInstance().getRunnerFileName()));
+ }
+ else
+ {
+ boolean result = startAtBoot.delete();
+ if(!result)
+ new StreamPiAlert("Uh Oh!", "Unable to delete starter file", StreamPiAlertType.ERROR).show();
+ }
+ }
+ }
+
+ Config.getInstance().setStartOnBoot(startOnBoot);
+
+ if(Config.getInstance().isFullscreen() != fullScreenToggleButton.isSelected() ||
+ Config.getInstance().isShowCursor() != showCursorToggleButton.isSelected())
+ toBeReloaded = true;
+
+
+ Config.getInstance().setFullscreen(fullScreenToggleButton.isSelected());
+ Config.getInstance().setShowCursor(showCursorToggleButton.isSelected());
+
+
+
+ if(!Config.getInstance().getThemesPath().equals(themesPathTextField.getText()))
+ toBeReloaded = true;
+
+ Config.getInstance().setThemesPath(themesPathTextField.getText());
+
+
+ if(!Config.getInstance().getIconsPath().equals(iconsPathTextField.getText()))
+ toBeReloaded = true;
+
+ Config.getInstance().setIconsPath(iconsPathTextField.getText());
+
+ if(!Config.getInstance().getProfilesPath().equals(profilesPathTextField.getText()))
+ toBeReloaded = true;
+
+ Config.getInstance().setProfilesPath(profilesPathTextField.getText());
+
+
+ Config.getInstance().save();
+
+ loadData();
+
+
+ if(breakConnection)
+ {
+ if(clientListener.isConnected())
+ clientListener.disconnect("Client connection settings were changed.");
+ }
+
+ if(toBeReloaded)
+ {
+ clientListener.init();
+ clientListener.renderRootDefaultProfile();
+ }
+ }
+ catch (SevereException e)
+ {
+ e.printStackTrace();
+ exceptionAndAlertHandler.handleSevereException(e);
+ }
+ catch (MinorException e)
+ {
+ e.printStackTrace();
+ exceptionAndAlertHandler.handleMinorException(e);
+ }
+ }
+
+}
--- 'a/src/main/java/module-info.java'
+++ b/src/main/java/module-info.java
@@ -1,4 +1,4 @@
-module com.StreamPi.Client {
+module com.stream_pi.client {
requires javafx.base;
requires javafx.graphics;
requires javafx.controls;
@@ -10,11 +10,11 @@ module com.StreamPi.Client {
requires java.xml;
- requires com.StreamPi.Util;
- requires com.StreamPi.ActionAPI;
- requires com.StreamPi.ThemeAPI;
+ requires com.stream_pi.util;
+ requires com.stream_pi.actionapi;
+ requires com.stream_pi.themeapi;
requires org.kordamp.ikonli.fontawesome5;
- exports com.StreamPi.Client;
+ exports com.stream_pi.client;
}
\ No newline at end of file
Binary files 'a/src/main/resources/com/StreamPi/Client/Default.obj' and /dev/null differ
Binary files 'a/src/main/resources/com/StreamPi/Client/Roboto.ttf' and /dev/null differ
--- 'a/src/main/resources/com/StreamPi/Client/style.css'
+++ /dev/null
@@ -1,216 +0,0 @@
-.root {
- -fx-font-family : 'Roboto';
-}
-
-
-.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
-{
-
-}
-
-.action_box_icon_not_present
-{
-
-}
-
-.action_box_onclick
-{
-
-}
-
-.action_box_not_onclick
-{
-
-}
-
-.action_box_display_text_label
-{
- -fx-font-size : 16;
-}
-
-.action_box_icon
-{
- -fx-arc-width:20px;
- -fx-arc-height:20px;
-}
-
-.settings_heading
-{
- -fx-font-size: 20;
-}
-
-
-.alert_header
-{
- -fx-padding: 5;
-}
-
-.alert_pane
-{
- -fx-background-color : white;
- -fx-border-color : white;
- -fx-border-width : 5;
- -fx-border-radius : 5;
- -fx-background-radius : 5;
- -fx-max-width : 400;
- -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0.0 , 0 );
-}
-
-.alert_header_icon
-{
- -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-background-color: white;
- -fx-padding: 5;
-}
-
-.alert_pane_parent, .combobox_pane_parent
-{
- -fx-background-color : rgba(0,0,0,0.5);
-}
-
-.alert_pane_header_text
-{
- -fx-font-size: 18;
-}
-
-.alert_button_bar
-{
- -fx-background-color: white;
- -fx-alignment: CENTER_RIGHT;
- -fx-spacing: 5;
- -fx-padding: 5;
-}
-
-.alert_scroll_pane {
- -fx-background: #FFFFFF;
- -fx-border-color:#FFFFFF;
- -fx-max-height : 300;
- /*-fx-focus-color: #FFFFFF;
- -fx-faint-focus-color:#FFFFFF;*/
-}
-
-
-.combo_box
-{
- -fx-alignment:CENTER_LEFT;
- -fx-pref-width:200;
- -fx-padding: 5;
- -fx-border-width : 1;
- -fx-border-color : grey;
- -fx-border-radius : 3;
-}
-
-.combo_box_popup
-{
- -fx-border-width : 5;
- -fx-border-radius : 5;
- -fx-background-radius : 5;
- -fx-max-height : 300;
- -fx-max-width : 410;
- -fx-background: #FFFFFF;
- -fx-border-color:#FFFFFF;
- -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0.0 , 0 );
-}
-
-.combo_box_popup_vbox
-{
- -fx-background-color: white;
- -fx-padding: 5;
- -fx-spacing:5;
-}
-
-.combo_box_drop_down_icon
-{
- -fx-icon-code: fas-caret-down;
- -fx-icon-size: 14;
-}
-
-.settings_base
-{
- -fx-background-color:white;
-}
-
-.first_time_use_pane
-{
- -fx-padding : 5;
- -fx-background-color: white;
-}
-
-.first_time_use_pane_heading_label
-{
- -fx-font-size: 20;
-}
-
-.first_time_use_pane_stackpane
-{
-
-}
-
-.first_time_use_pane_welcome
-{
-
-}
-
-.first_time_use_pane_license
-{
- -fx-spacing : 10;
-}
-
-.first_time_use_pane_final_config
-{
-
-}
-
-.first_time_use_pane_final_config_label
-{
-
-}
-
-.scroll-pane{
- -fx-background-color:transparent;
-}
-
-
-.scroll-pane .viewport {
- -fx-background-color: transparent;
-}
-
-.dashboard{
- -fx-background-color: white;
-}
-
-.first_time_use_welcome_pane_welcome_label
-{
- -fx-font-size: 30;
-}
-
-.first_time_use_welcome_pane_next_to_continue_label
-{
- -fx-font-size: 15;
-}
\ No newline at end of file
Binary files /dev/null and b/src/main/resources/com/stream_pi/client/Default.obj differ
Binary files /dev/null and b/src/main/resources/com/stream_pi/client/Roboto.ttf differ
--- /dev/null
+++ b/src/main/resources/com/stream_pi/client/style.css
@@ -0,0 +1,216 @@
+.root {
+ -fx-font-family : 'Roboto';
+}
+
+
+.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
+{
+
+}
+
+.action_box_icon_not_present
+{
+
+}
+
+.action_box_onclick
+{
+
+}
+
+.action_box_not_onclick
+{
+
+}
+
+.action_box_display_text_label
+{
+ -fx-font-size : 16;
+}
+
+.action_box_icon
+{
+ -fx-arc-width:20px;
+ -fx-arc-height:20px;
+}
+
+.settings_heading
+{
+ -fx-font-size: 20;
+}
+
+
+.alert_header
+{
+ -fx-padding: 5;
+}
+
+.alert_pane
+{
+ -fx-background-color : white;
+ -fx-border-color : white;
+ -fx-border-width : 5;
+ -fx-border-radius : 5;
+ -fx-background-radius : 5;
+ -fx-max-width : 400;
+ -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0.0 , 0 );
+}
+
+.alert_header_icon
+{
+ -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-background-color: white;
+ -fx-padding: 5;
+}
+
+.alert_pane_parent, .combobox_pane_parent
+{
+ -fx-background-color : rgba(0,0,0,0.5);
+}
+
+.alert_pane_header_text
+{
+ -fx-font-size: 18;
+}
+
+.alert_button_bar
+{
+ -fx-background-color: white;
+ -fx-alignment: CENTER_RIGHT;
+ -fx-spacing: 5;
+ -fx-padding: 5;
+}
+
+.alert_scroll_pane {
+ -fx-background: #FFFFFF;
+ -fx-border-color:#FFFFFF;
+ -fx-max-height : 300;
+ /*-fx-focus-color: #FFFFFF;
+ -fx-faint-focus-color:#FFFFFF;*/
+}
+
+
+.combo_box
+{
+ -fx-alignment:CENTER_LEFT;
+ -fx-pref-width:200;
+ -fx-padding: 5;
+ -fx-border-width : 1;
+ -fx-border-color : grey;
+ -fx-border-radius : 3;
+}
+
+.combo_box_popup
+{
+ -fx-border-width : 5;
+ -fx-border-radius : 5;
+ -fx-background-radius : 5;
+ -fx-max-height : 300;
+ -fx-max-width : 410;
+ -fx-background: #FFFFFF;
+ -fx-border-color:#FFFFFF;
+ -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0.0 , 0 );
+}
+
+.combo_box_popup_vbox
+{
+ -fx-background-color: white;
+ -fx-padding: 5;
+ -fx-spacing:5;
+}
+
+.combo_box_drop_down_icon
+{
+ -fx-icon-code: fas-caret-down;
+ -fx-icon-size: 14;
+}
+
+.settings_base
+{
+ -fx-background-color:white;
+}
+
+.first_time_use_pane
+{
+ -fx-padding : 5;
+ -fx-background-color: white;
+}
+
+.first_time_use_pane_heading_label
+{
+ -fx-font-size: 20;
+}
+
+.first_time_use_pane_stackpane
+{
+
+}
+
+.first_time_use_pane_welcome
+{
+
+}
+
+.first_time_use_pane_license
+{
+ -fx-spacing : 10;
+}
+
+.first_time_use_pane_final_config
+{
+
+}
+
+.first_time_use_pane_final_config_label
+{
+
+}
+
+.scroll-pane{
+ -fx-background-color:transparent;
+}
+
+
+.scroll-pane .viewport {
+ -fx-background-color: transparent;
+}
+
+.dashboard{
+ -fx-background-color: white;
+}
+
+.first_time_use_welcome_pane_welcome_label
+{
+ -fx-font-size: 30;
+}
+
+.first_time_use_welcome_pane_next_to_continue_label
+{
+ -fx-font-size: 15;
+}
\ No newline at end of file