333 lines
9.3 KiB
Java
333 lines
9.3 KiB
Java
package com.jens.rhasspy.visualtool;
|
|
|
|
import java.awt.AWTException;
|
|
import java.awt.Dimension;
|
|
import java.awt.Font;
|
|
import java.awt.Robot;
|
|
import java.awt.event.MouseEvent;
|
|
import java.awt.event.MouseListener;
|
|
import java.util.ArrayList;
|
|
import javax.swing.BoxLayout;
|
|
import javax.swing.JFrame;
|
|
import javax.swing.JLabel;
|
|
import javax.swing.JOptionPane;
|
|
import javax.swing.JPanel;
|
|
import javax.swing.JScrollBar;
|
|
import javax.swing.JScrollPane;
|
|
import javax.swing.JTextArea;
|
|
import javax.swing.border.Border;
|
|
import javax.swing.border.CompoundBorder;
|
|
import javax.swing.border.EmptyBorder;
|
|
|
|
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
|
import org.eclipse.paho.client.mqttv3.MqttTopic;
|
|
|
|
import com.jens.rhasspy.visualtool.lib.JSONObject;
|
|
|
|
/*
|
|
* Layout types
|
|
* https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
|
|
*/
|
|
|
|
public class GUI
|
|
{
|
|
static JFrame mainFrame = new JFrame(Settings.programName);
|
|
static JLabel connectionStatusTextField = new JLabel();
|
|
static JTextArea mainTextField = new JTextArea();
|
|
static JScrollPane mainTextFieldHolder = new JScrollPane(mainTextField);
|
|
static JPanel optionsFrame = new JPanel();
|
|
static GUI instance = null;
|
|
Font defaultFont = new Font(Font.SANS_SERIF, Font.PLAIN, 20);
|
|
|
|
static Dimension defaultContainerDim = new Dimension(700, 250);
|
|
static Dimension zeroDim = new Dimension(0, 0);
|
|
|
|
ArrayList<String> textEntriesList = new ArrayList<>();
|
|
|
|
public static void main(String[] args)
|
|
{
|
|
if(Settings.readSettings())
|
|
{
|
|
getInstance().openWindow();
|
|
|
|
// Subscribe to MQTT topics
|
|
|
|
MQTT.getInstance().subscribeToTopic(Settings.topicNameWakewordRecognized);
|
|
MQTT.getInstance().subscribeToTopic(Settings.topicNameDisplayText);
|
|
MQTT.getInstance().subscribeToTopic(Settings.topicNameDisplayOptions);
|
|
MQTT.getInstance().subscribeToTopic(Settings.topicNameIntentsRecognized);
|
|
MQTT.getInstance().subscribeToTopic(Settings.topicNameSayText);
|
|
MQTT.getInstance().subscribeToTopic(Settings.topicNamePlaySoundFinished);
|
|
MQTT.getInstance().subscribeToTopic(Settings.topicNameSessionEnded);
|
|
}
|
|
}
|
|
|
|
public static GUI getInstance()
|
|
{
|
|
if(instance == null)
|
|
instance = new GUI();
|
|
|
|
return instance;
|
|
}
|
|
|
|
void openWindow()
|
|
{
|
|
mainFrame.setLayout(new BoxLayout(mainFrame.getContentPane(), BoxLayout.Y_AXIS));
|
|
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
mainFrame.setSize(700, 320);
|
|
mainFrame.setLocation(50, 50);
|
|
|
|
try
|
|
{
|
|
Thread.sleep(1000);
|
|
}
|
|
catch (InterruptedException e)
|
|
{
|
|
Miscellaneous.logEvent(Miscellaneous.getStackTraceAsString(e), 1);
|
|
}
|
|
|
|
connectionStatusTextField.setText("Connected: " + String.valueOf(MQTT.getInstance().getClient().isConnected()));
|
|
Border border = connectionStatusTextField.getBorder();
|
|
Border margin = new EmptyBorder(10,10,10,10);
|
|
connectionStatusTextField.setBorder(new CompoundBorder(border, margin));
|
|
|
|
mainTextField.setText("Waiting for session...");
|
|
mainTextField.setFont(defaultFont);
|
|
if(mainTextField.isEditable())
|
|
mainTextField.setEditable(false);
|
|
Border borderMainTextField = mainTextField.getBorder();
|
|
Border marginMainTextField = new EmptyBorder(10,10,10,10);
|
|
mainTextField.setBorder(new CompoundBorder(borderMainTextField, marginMainTextField));
|
|
|
|
mainTextFieldHolder.setPreferredSize(defaultContainerDim);
|
|
mainTextFieldHolder.setVisible(true);
|
|
optionsFrame.setPreferredSize(defaultContainerDim);
|
|
optionsFrame.setVisible(false);
|
|
optionsFrame.setLayout(new BoxLayout(optionsFrame, BoxLayout.Y_AXIS));
|
|
|
|
mainFrame.add(connectionStatusTextField);
|
|
mainFrame.add(mainTextFieldHolder);
|
|
mainFrame.add(optionsFrame);
|
|
|
|
mainFrame.setVisible(true);
|
|
}
|
|
|
|
public void updateConnectionStatus(boolean connected)
|
|
{
|
|
if(connected)
|
|
connectionStatusTextField.setText("Connected to: " + Settings.mqttClientServerHostname);
|
|
else
|
|
connectionStatusTextField.setText("Not connected");
|
|
}
|
|
|
|
public void updateWindow()
|
|
{
|
|
if(mainTextField.isEditable())
|
|
mainTextField.setEditable(false);
|
|
|
|
mainTextField.setLineWrap(true);
|
|
mainTextField.setText(Miscellaneous.arrayImplode(Miscellaneous.lineSeparator, textEntriesList));
|
|
|
|
JScrollBar vertical = mainTextFieldHolder.getVerticalScrollBar();
|
|
vertical.setValue(vertical.getMaximum());
|
|
|
|
mainFrame.pack();
|
|
|
|
mainTextFieldHolder.setVisible(true);
|
|
optionsFrame.setVisible(false);
|
|
|
|
mainFrame.repaint();
|
|
}
|
|
|
|
public void displayOptions(String[] options)
|
|
{
|
|
optionsFrame.removeAll();
|
|
|
|
JLabel infoLabel = new JLabel("Select an option:");
|
|
infoLabel.setFont(defaultFont);
|
|
optionsFrame.add(infoLabel);
|
|
Border labelBorder = optionsFrame.getBorder();
|
|
Border labelMargin = new EmptyBorder(10,10,10,10);
|
|
optionsFrame.setBorder(new CompoundBorder(labelBorder, labelMargin));
|
|
|
|
for(String option : options)
|
|
{
|
|
JLabel optionTf = new JLabel(option);
|
|
optionTf.setFont(defaultFont);
|
|
Border border = optionTf.getBorder();
|
|
Border margin = new EmptyBorder(10,10,10,10);
|
|
optionTf.setBorder(new CompoundBorder(border, margin));
|
|
|
|
optionTf.addMouseListener(new MouseListener()
|
|
{
|
|
@Override
|
|
public void mouseReleased(MouseEvent e)
|
|
{
|
|
}
|
|
|
|
@Override
|
|
public void mousePressed(MouseEvent e)
|
|
{
|
|
}
|
|
|
|
@Override
|
|
public void mouseExited(MouseEvent e)
|
|
{
|
|
}
|
|
|
|
@Override
|
|
public void mouseEntered(MouseEvent e)
|
|
{
|
|
}
|
|
|
|
@Override
|
|
public void mouseClicked(MouseEvent e)
|
|
{
|
|
JOptionPane.showMessageDialog(mainFrame, "Option " + option + " selected.");
|
|
}
|
|
});
|
|
optionsFrame.add(optionTf);
|
|
}
|
|
|
|
// mainTextFieldHolder.setPreferredSize(zeroDim);
|
|
// optionsFrame.setPreferredSize(defaultContainerDim);
|
|
|
|
mainFrame.pack();
|
|
|
|
optionsFrame.setVisible(true);
|
|
mainTextFieldHolder.setVisible(false);
|
|
|
|
mainFrame.repaint();
|
|
}
|
|
|
|
public void handleNewMessage(Object[] messageArray)
|
|
{
|
|
/*
|
|
* Object[] object = new Object[3];
|
|
object[0] = message;
|
|
object[1] = topic;
|
|
object[2] = Calendar.getInstance();
|
|
*/
|
|
|
|
String payload = new String(((MqttMessage)messageArray[0]).getPayload());
|
|
|
|
String topic = (String)messageArray[1];
|
|
|
|
if(MqttTopic.isMatched(Settings.topicNameWakewordRecognized, topic))
|
|
{
|
|
turnOnScreen();
|
|
|
|
textEntriesList.clear();
|
|
textEntriesList.add(getMeString() + "Hello! What can I do for you?");
|
|
updateWindow();
|
|
}
|
|
else if(MqttTopic.isMatched(Settings.topicNameIntentsRecognized, topic))
|
|
{
|
|
turnOnScreen();
|
|
|
|
JSONObject jo = new JSONObject(payload);
|
|
textEntriesList.clear();
|
|
textEntriesList.add(getYouString() + jo.getString("input"));
|
|
updateWindow();
|
|
}
|
|
else if(MqttTopic.isMatched(Settings.topicNameDisplayText, topic))
|
|
{
|
|
JSONObject jo = new JSONObject(payload);
|
|
/*
|
|
* This is deactivated only for test purposes.
|
|
* Afterwards for a conversation flow sayText needs to be used.
|
|
*/
|
|
// textEntriesList.clear();
|
|
|
|
textEntriesList.add(getMeString() + jo.getString("text"));
|
|
updateWindow();
|
|
}
|
|
else if(MqttTopic.isMatched(Settings.topicNameDisplayOptions, topic))
|
|
{
|
|
JSONObject jo = new JSONObject(payload);
|
|
/*
|
|
* This is deactivated only for test purposes.
|
|
* Afterwards for a conversation flow sayText needs to be used.
|
|
*/
|
|
// textEntriesList.clear();
|
|
|
|
String[] options = jo.getString("text").split(";");
|
|
displayOptions(options);
|
|
|
|
}
|
|
else if(MqttTopic.isMatched(Settings.topicNameSayText, topic))
|
|
{
|
|
JSONObject jo = new JSONObject(payload);
|
|
textEntriesList.add(getMeString() + jo.getString("text"));
|
|
updateWindow();
|
|
}
|
|
else if(MqttTopic.isMatched(Settings.topicNameSessionEnded, topic))
|
|
{
|
|
textEntriesList.clear();
|
|
textEntriesList.add("Waiting for session...");
|
|
updateWindow();
|
|
}
|
|
}
|
|
|
|
static String getYouString()
|
|
{
|
|
return "You: \t";
|
|
}
|
|
|
|
static String getMeString()
|
|
{
|
|
return "Me: \t";
|
|
}
|
|
|
|
static void turnOnScreen()
|
|
{
|
|
/*
|
|
* pi@raspberrypi11:~ $ DISPLAY=:0 xset q
|
|
Keyboard Control:
|
|
auto repeat: on key click percent: 0 LED mask: 00000000
|
|
XKB indicators:
|
|
00: Caps Lock: off 01: Num Lock: off 02: Scroll Lock: off
|
|
03: Compose: off 04: Kana: off 05: Sleep: off
|
|
06: Suspend: off 07: Mute: off 08: Misc: off
|
|
09: Mail: off 10: Charging: off 11: Shift Lock: off
|
|
12: Group 2: off 13: Mouse Keys: off
|
|
auto repeat delay: 500 repeat rate: 33
|
|
auto repeating keys: 00ffffffdffffbbf
|
|
fadfffefffedffff
|
|
9fffffffffffffff
|
|
fff7ffffffffffff
|
|
bell percent: 50 bell pitch: 400 bell duration: 100
|
|
Pointer Control:
|
|
acceleration: 20/10 threshold: 10
|
|
Screen Saver:
|
|
prefer blanking: yes allow exposures: yes
|
|
timeout: 600 cycle: 600
|
|
Colors:
|
|
default colormap: 0x20 BlackPixel: 0x0 WhitePixel: 0xffffff
|
|
Font Path:
|
|
built-ins
|
|
DPMS (Energy Star):
|
|
Standby: 600 Suspend: 600 Off: 600
|
|
DPMS is Enabled
|
|
Monitor is Off
|
|
pi@raspberrypi11:~ $
|
|
*/
|
|
|
|
try
|
|
{
|
|
// These coordinates are screen coordinates
|
|
// int xCoord = 500;
|
|
// int yCoord = 500;
|
|
|
|
// Move the cursor
|
|
Robot robot = new Robot();
|
|
for(int xCoord = 500; xCoord < 505; xCoord++)
|
|
for(int yCoord = 500; yCoord < 505; yCoord++)
|
|
robot.mouseMove(xCoord, yCoord);
|
|
}
|
|
catch (AWTException e)
|
|
{
|
|
}
|
|
}
|
|
}
|