RhasspyVisualConversationTool/RhasspyVisualConversationTool/src/com/jens/rhasspy/visualtool/GUI.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)
{
}
}
}