Add Voice Recording to ChatScene

The ChatScene layout has been adjusted to include a voice message
button. When pressed, a recording starts. To finish the recording, press
the button again. The recording will be saved as a pending attachment.

The next message sent will include the attachment. When a pending
attachment is present, a message can be sent without text.

When the chat is switched, the pending attachment is discarded. This
does not stop active recordings, however.

The ChatScene layout handles large stages better now by ditching
percentage-wise row and column scaling in favor of absolute values for
all cells except the message list and text area.
This commit is contained in:
2020-07-03 23:32:22 +02:00
parent 7d15285da5
commit d9bf20b88e
2 changed files with 100 additions and 112 deletions

View File

@ -2,6 +2,7 @@
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.ContextMenu?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
@ -12,40 +13,21 @@
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<GridPane hgap="5.0" maxHeight="-Infinity" maxWidth="-Infinity"
minHeight="400.0" minWidth="350.0" prefHeight="400.0" prefWidth="600.0"
vgap="2.0" xmlns="http://javafx.com/javafx/11.0.1"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="envoy.client.ui.controller.ChatScene">
<GridPane hgap="5.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="400.0" minWidth="350.0" prefHeight="400.0" prefWidth="600.0" vgap="2.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="envoy.client.ui.controller.ChatScene">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES"
maxWidth="1.7976931348623157E308" minWidth="10.0" percentWidth="25.0"
prefWidth="161.0" />
<ColumnConstraints hgrow="SOMETIMES"
maxWidth="1.7976931348623157E308" minWidth="10.0" percentWidth="65.0"
prefWidth="357.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="10.0"
minWidth="10.0" percentWidth="10.0" prefWidth="10.0" />
<ColumnConstraints hgrow="NEVER" minWidth="60.0" prefWidth="160.0" />
<ColumnConstraints hgrow="ALWAYS" maxWidth="1.7976931348623157E308" minWidth="10.0" prefWidth="357.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="1.7976931348623157E308"
minHeight="10.0" percentHeight="10.0" prefHeight="70.0"
vgrow="SOMETIMES" />
<RowConstraints maxHeight="1.7976931348623157E308"
minHeight="10.0" percentHeight="7.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="1.7976931348623157E308"
minHeight="10.0" percentHeight="60.0" prefHeight="50.0"
vgrow="SOMETIMES" />
<RowConstraints maxHeight="50.0" minHeight="10.0"
percentHeight="2.0" prefHeight="50.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="1.7976931348623157E308"
minHeight="10.0" percentHeight="21.0" prefHeight="100.0"
vgrow="SOMETIMES" />
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="50.0" vgrow="NEVER" />
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="20.0" vgrow="NEVER" />
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="50.0" prefHeight="155.14286150251115" vgrow="ALWAYS" />
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="20.0" vgrow="NEVER" />
<RowConstraints maxHeight="120.0" minHeight="40.0" prefHeight="60.0" vgrow="NEVER" />
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="40.0" vgrow="NEVER" />
</rowConstraints>
<children>
<ListView fx:id="userList" onMouseClicked="#userListClicked"
prefHeight="211.0" prefWidth="300.0" GridPane.rowIndex="1"
GridPane.rowSpan="2147483647">
<ListView fx:id="userList" onMouseClicked="#userListClicked" prefHeight="211.0" prefWidth="300.0" GridPane.rowIndex="1" GridPane.rowSpan="2147483647">
<GridPane.margin>
<Insets bottom="10.0" left="10.0" />
</GridPane.margin>
@ -55,14 +37,12 @@
<contextMenu>
<ContextMenu anchorLocation="CONTENT_TOP_LEFT">
<items>
<MenuItem fx:id="deleteContactMenuItem"
mnemonicParsing="false" onAction="#deleteContact" text="Delete" />
<MenuItem fx:id="deleteContactMenuItem" mnemonicParsing="false" onAction="#deleteContact" text="Delete" />
</items>
</ContextMenu>
</contextMenu>
</ListView>
<Label fx:id="contactLabel" prefHeight="16.0" prefWidth="250.0"
text="Select a contact to chat with" GridPane.columnSpan="2">
<Label fx:id="contactLabel" prefHeight="27.0" prefWidth="134.0" GridPane.columnSpan="2">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin>
@ -70,10 +50,7 @@
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
</Label>
<Button fx:id="settingsButton" mnemonicParsing="true"
onAction="#settingsButtonClicked" text="_Settings"
GridPane.columnIndex="1" GridPane.columnSpan="2"
GridPane.halignment="RIGHT" GridPane.valignment="CENTER">
<Button fx:id="settingsButton" mnemonicParsing="true" onAction="#settingsButtonClicked" text="_Settings" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.valignment="CENTER">
<GridPane.margin>
<Insets bottom="10.0" right="10.0" top="10.0" />
</GridPane.margin>
@ -81,10 +58,7 @@
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
</Button>
<ListView fx:id="messageList" prefHeight="257.0"
prefWidth="465.0" GridPane.columnIndex="1"
GridPane.columnSpan="2147483647" GridPane.rowIndex="1"
GridPane.rowSpan="2">
<ListView fx:id="messageList" prefHeight="257.0" prefWidth="465.0" GridPane.columnIndex="1" GridPane.columnSpan="2147483647" GridPane.rowIndex="1" GridPane.rowSpan="2">
<GridPane.margin>
<Insets left="5.0" right="10.0" />
</GridPane.margin>
@ -94,74 +68,55 @@
<contextMenu>
<ContextMenu anchorLocation="CONTENT_TOP_LEFT">
<items>
<MenuItem mnemonicParsing="false" onAction="#copyMessage"
text="Copy" />
<MenuItem mnemonicParsing="false"
onAction="#deleteMessage" text="Delete" />
<MenuItem mnemonicParsing="false"
onAction="#forwardMessage" text="Forward" />
<MenuItem mnemonicParsing="false"
onAction="#quoteMessage" text="Quote" />
<MenuItem mnemonicParsing="false"
onAction="#loadMessageInfoScene" text="Info" />
<MenuItem mnemonicParsing="false" onAction="#copyMessage" text="Copy" />
<MenuItem mnemonicParsing="false" onAction="#deleteMessage" text="Delete" />
<MenuItem mnemonicParsing="false" onAction="#forwardMessage" text="Forward" />
<MenuItem mnemonicParsing="false" onAction="#quoteMessage" text="Quote" />
<MenuItem mnemonicParsing="false" onAction="#loadMessageInfoScene" text="Info" />
</items>
</ContextMenu>
</contextMenu>
</ListView>
<Button fx:id="postButton" defaultButton="true" disable="true"
mnemonicParsing="true" onAction="#postMessage" prefHeight="10.0"
prefWidth="75.0" text="_Post" GridPane.columnIndex="2"
GridPane.halignment="CENTER" GridPane.rowIndex="4"
GridPane.valignment="BOTTOM">
<ButtonBar prefWidth="436.0" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="5" GridPane.valignment="BOTTOM">
<GridPane.margin>
<Insets right="10.0" top="5.0" />
</GridPane.margin>
<buttons>
<Button fx:id="voiceButton" onAction="#voiceButtonClicked" text="_Record Voice Message" />
<Button fx:id="postButton" defaultButton="true" disable="true" mnemonicParsing="true" onAction="#postMessage" prefHeight="10.0" prefWidth="75.0" text="_Post">
<tooltip>
<Tooltip anchorLocation="WINDOW_TOP_LEFT" autoHide="true" maxWidth="350.0" text="Click this button to send the message. If it is disabled, you first have to select a contact to send it to. A message may automatically be sent when you press (Ctrl + ) Enter, according to your preferences. Additionally sends a message when pressing &quot;Alt&quot; + &quot;P&quot;." wrapText="true" />
</tooltip>
<contextMenu>
<ContextMenu anchorLocation="CONTENT_TOP_LEFT">
<items>
<MenuItem mnemonicParsing="false" onAction="#copyAndPostMessage" text="Copy and Send" />
</items>
</ContextMenu>
</contextMenu>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
</Button>
</buttons>
</ButtonBar>
<TextArea fx:id="messageTextArea" disable="true" onInputMethodTextChanged="#messageTextUpdated" onKeyPressed="#checkPostConditions" onKeyTyped="#checkKeyCombination" prefHeight="200.0" prefWidth="200.0" wrapText="true" GridPane.columnIndex="1" GridPane.rowIndex="4">
<GridPane.margin>
<Insets bottom="10.0" right="10.0" />
</GridPane.margin>
<tooltip>
<Tooltip anchorLocation="WINDOW_TOP_LEFT" autoHide="true"
maxWidth="350.0"
text="Click this button to send the message. If it is disabled, you first have to select a contact to send it to. A message may automatically be sent when you press (Ctrl + ) Enter, according to your preferences. Additionally sends a message when pressing &quot;Alt&quot; + &quot;P&quot;."
wrapText="true" />
</tooltip>
<contextMenu>
<ContextMenu anchorLocation="CONTENT_TOP_LEFT">
<items>
<MenuItem mnemonicParsing="false"
onAction="#copyAndPostMessage" text="Copy and Send" />
</items>
</ContextMenu>
</contextMenu>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
</Button>
<TextArea fx:id="messageTextArea" disable="true"
onInputMethodTextChanged="#messageTextUpdated"
onKeyPressed="#checkPostConditions" onKeyTyped="#checkKeyCombination"
prefHeight="200.0" prefWidth="200.0" wrapText="true"
GridPane.columnIndex="1" GridPane.rowIndex="4">
<GridPane.margin>
<Insets bottom="10.0" left="5.0" top="3.0" />
<Insets bottom="10.0" left="5.0" right="10.0" top="3.0" />
</GridPane.margin>
<opaqueInsets>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</opaqueInsets>
</TextArea>
<Button mnemonicParsing="true"
onAction="#addContactButtonClicked" text="_Add Contacts"
GridPane.halignment="CENTER" GridPane.rowIndex="4"
GridPane.valignment="CENTER">
<Button mnemonicParsing="true" onAction="#addContactButtonClicked" text="_Add Contacts" GridPane.halignment="CENTER" GridPane.rowIndex="5" GridPane.valignment="CENTER">
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
<GridPane.margin>
<Insets bottom="5.0" left="10.0" right="5.0" top="5.0" />
<Insets bottom="10.0" left="10.0" right="5.0" top="5.0" />
</GridPane.margin>
</Button>
<Label id="remainingCharsLabel" fx:id="remainingChars"
ellipsisString="" maxHeight="30.0" maxWidth="180.0" prefHeight="30.0"
prefWidth="180.0" text="remaining chars: 0/x" textFill="LIME"
textOverrun="LEADING_WORD_ELLIPSIS" visible="false"
GridPane.columnIndex="1" GridPane.rowIndex="3">
<Label id="remainingCharsLabel" fx:id="remainingChars" ellipsisString="" maxHeight="30.0" maxWidth="180.0" prefHeight="30.0" prefWidth="180.0" text="remaining chars: 0/x" textFill="LIME" textOverrun="LEADING_WORD_ELLIPSIS" visible="false" GridPane.columnIndex="1" GridPane.rowIndex="3">
<GridPane.margin>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</GridPane.margin>
@ -172,14 +127,10 @@
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</opaqueInsets>
<tooltip>
<Tooltip
text="Shows how many chars you can still enter in this message"
wrapText="true" />
<Tooltip text="Shows how many chars you can still enter in this message" wrapText="true" />
</tooltip>
</Label>
<Label fx:id="infoLabel" text="Something happened"
wrapText="true" textFill="#faa007" visible="false"
GridPane.columnIndex="1" GridPane.rowIndex="1">
<Label fx:id="infoLabel" text="Something happened" textFill="#faa007" visible="false" wrapText="true" GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</GridPane.margin>