Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QML client rewrite #3457

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
386 changes: 113 additions & 273 deletions Jamulus.pro
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You did quite a lot of changes to Jamulus.pro
It seems to be overkill.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you be specific?
In this commit there are a few extra changes in Jamulus.pro included from earlier dev / simplification work. There is quite a lot of cruft IMO anyway in the .pro file, but feel free to push or suggest changes.

Large diffs are not rendered by default.

98 changes: 98 additions & 0 deletions src/AppWindow.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

ApplicationWindow {
visible: true
minimumWidth: 600
minimumHeight: 490
title: qsTr("Jamulus")

ColumnLayout {
anchors.fill: parent

// Tab Bar
TabBar {
id: tabBar
Layout.fillWidth: true

TabButton {
text: qsTr("Home")
checked: stackLayout.currentIndex === 0
onClicked: stackLayout.currentIndex = 0
}

TabButton {
text: qsTr("Settings")
checked: stackLayout.currentIndex === 1
onClicked: stackLayout.currentIndex = 1
}
}

// Stack Layout for Tab Content
StackLayout {
id: stackLayout
Layout.fillWidth: true
Layout.fillHeight: true

// Home Tab Content
Item {
id: homeTab
Layout.fillWidth: true
Layout.fillHeight: true

MainView {
anchors.fill: parent
}
}

// Settings Tab Content
Item {
id: settingsTab
Layout.fillWidth: true
Layout.fillHeight: true

SettingsView {
// anchors.fill: parent
}
}
}

Popup {
id: userPopup
x: (parent.width - width) / 2
y: (parent.height - height) / 2
width: 300
height: 150
visible: _main.userMsg !== "" // Show the popup when there's a message
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside

Rectangle {
anchors.fill: parent
color: "white"

Label {
id: userMessage
text: _main.userMsg // Display the message from _main
anchors.centerIn: parent
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
width: parent.width - 20 // Ensure some padding from the edges
}
}

onVisibleChanged: {
if (!visible) {
_main.userMsg = ""
}
}
}
}

// React to changes in _client.userMsg
function onUserMsgChanged(newMsg) {
if (newMsg !== "") {
userPopup.open()
}
}
}
169 changes: 169 additions & 0 deletions src/ChannelFader.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

Rectangle {
id: channelFader
border.width: 2
radius: 5
border.color: "#d9d9d9"

property var channelModel
// use ? and ?? operators to suppress errors when channelModel is null
property string channelUserName: channelModel?.channelUserName ?? "" // channelUserNameText.text
property double channelLevel: channelModel?.channelMeter.doubleVal ?? 0
property bool channelClipStatus: channelModel?.channelMeter.clipStatus ?? false
property double faderLevel: channelModel?.faderLevel ?? 0 // volumeFader.value
property double panLevel: channelModel?.panLevel ?? 0 // panKnob.value
property bool isMuted: channelModel?.isMuted ?? 0 // muteButton.checked
property bool isSolo: channelModel?.isSolo ?? 0 // soloButton.checked
property int groupID: channelModel?.groupID ?? 0 // groupId

ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
anchors.centerIn: parent
spacing: 3

Text {
id: panKnobLabel
text: "PAN"
}

// Pan Knob
Dial {
id: panKnob
from: 0
to: 100
value: panLevel // default - set to AUD_MIX_PAN_MAX / 2
stepSize: 1
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: 32
Layout.preferredHeight: 32
Layout.bottomMargin: 4
background: Rectangle {
// color: "white"
border.width: 1
border.color: "#4e4e4e"
radius: width / 2
}

onMoved: {
channelModel.setPanLevel(value)
}
}

RowLayout {
spacing: 5
Layout.alignment: Qt.AlignHCenter
Layout.preferredHeight: 200
Layout.preferredWidth: 15

// Level Meter
SingleLevelMeter {
id: levelMeterRectangleUser
heightPercentage: channelLevel
chanClipStatus: channelClipStatus
}

// Fader
Slider {
id: volumeFader
orientation: Qt.Vertical
from: 0.0
to: 100.0
value: faderLevel // FIXME - set to AUD_MIX_FADER_MAX
Layout.alignment: Qt.AlignHCenter
Layout.preferredHeight: parent.height

onValueChanged: {
channelModel.setFaderLevel(value)
}
}
}

// GRPMTSOLO box
ColumnLayout {
Layout.alignment: Qt.AlignHCenter
spacing: 5

RowLayout {
spacing: 5
Layout.alignment: Qt.AlignHCenter

Button {
id: muteButton
checkable: true
text: "M"
Layout.preferredWidth: 30
Layout.preferredHeight: 30
font.bold: true
checked: isMuted
onClicked: {
channelModel.setIsMuted(!isMuted)
}
}

Button {
id: soloButton
checkable: true
text: "S"
Layout.preferredWidth: 30
Layout.preferredHeight: 30
font.bold: true
checked: isSolo
onClicked: {
channelModel.setIsSolo(!isSolo)
}
}
}

Button {
id: groupChooser
text: groupID > 0 ? groupID.toString() : "GRP"
Layout.preferredWidth: 50
Layout.preferredHeight: 25
Layout.alignment: Qt.AlignHCenter
font.bold: true
onClicked: menu.open()

Menu {
id: menu
y: groupChooser.height

Repeater {
model: 9 // Total number of items
delegate: MenuItem {
property int groupId: index
text: index === 0 ? "No group" : "Group " + index
onTriggered: channelModel.setGroupID(groupId)
}
}
}
}

}

// Username label
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 50
Layout.alignment: Qt.AlignHCenter
border.color: "#d9d9d9"
border.width: 1
radius: 3

Label {
id: channelUserNameText
anchors.fill: parent
text: channelUserName
font.bold: true
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}

}
}

75 changes: 75 additions & 0 deletions src/ChatBox.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

Item {
id: chatBox
width: 400
height: 300

ColumnLayout {
anchors.fill: parent
spacing: 6

ScrollView {
Layout.fillWidth: true
Layout.fillHeight: true

TextArea {
id: chatArea
Layout.fillWidth: true
Layout.fillHeight: true
readOnly: true
wrapMode: TextEdit.Wrap
textFormat: TextEdit.RichText // Enable HTML rendering
text: _chatBox.chatHistory
font.pixelSize: 12

// Add padding for better text display
leftPadding: 10
rightPadding: 10
topPadding: 10
bottomPadding: 10

// Auto-scroll to bottom when new messages arrive
onTextChanged: {
cursorPosition = length
if (length > 0) {
// ensure cursor is visible
chatArea.flickableItem.contentY = chatArea.flickableItem.contentHeight - chatArea.flickableItem.height
}
}
}
}

RowLayout {
Layout.fillWidth: true
spacing: 4

TextField {
id: chatInput
Layout.fillWidth: true
placeholderText: qsTr("Type a message…")
onAccepted: {
_chatBox.sendMessage(text)
text = ""
}
}

Button {
text: qsTr("Send")
onClicked: {
_chatBox.sendMessage(chatInput.text)
chatInput.text = ""
}
}
}

Button {
text: qsTr("Clear Chat")
onClicked: {
_chatBox.clearChat()
}
}
}
}
Loading
Loading