Implement smooth source select with Loaders, implement vertical tabbar for settings, add header

This commit is contained in:
Dark Steveneq
2025-10-13 02:55:16 +02:00
parent b48a29935d
commit 362166cc1f
7 changed files with 243 additions and 69 deletions

106
Main.qml
View File

@@ -2,6 +2,7 @@ import QtQuick 6.8
import QtQuick.Controls 6.8 import QtQuick.Controls 6.8
import QtQuick.Controls.Basic 6.8 import QtQuick.Controls.Basic 6.8
import QtQuick.Layouts 6.8 import QtQuick.Layouts 6.8
import QtQuick.Dialogs 6.10
import QYRComponents 1.0 import QYRComponents 1.0
@@ -10,54 +11,105 @@ ApplicationWindow {
height: 800 height: 800
title: qsTr("QYouRadio") title: qsTr("QYouRadio")
Dialog {
id: dialogSettings
// modality: Qt.WindowModal
popupType: Popup.Window
title: qsTr("Settings")
ViewSettings {}
}
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
anchors.margins: 10 anchors.margins: 10
TabBar { RowLayout {
id: tabbar
Layout.fillWidth: true Layout.fillWidth: true
spacing: 10
TabButton { Label {
text: qsTr("Autoradio") text: "QYR"
heading: "h3"
font.bold: true
} }
// TabButton {
// text: qsTr("Live Mix") Item {
// } Layout.fillWidth: true
// TabButton { }
// text: qsTr("Deep Bass")
// } Label {
TabButton { visible: Player.playing
text: qsTr("Settings") text: "Playback active"
heading: "h4"
font.bold: true
}
Item {
Layout.fillWidth: true
}
TabBar {
id: tabbar
spacing: 10
TabButton {
text: qsTr("Autoradio")
}
TabButton {
text: qsTr("Live Mix")
}
TabButton {
text: qsTr("Deep Bass")
}
}
Button {
text: "S"
onClicked: function() {
dialogSettings.open()
}
} }
} }
StackLayout {
SwipeView {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
Layout.margins: 10 Layout.margins: 10
interactive: false
currentIndex: tabbar.currentIndex currentIndex: tabbar.currentIndex
ViewPlayer {
title: qsTr("Autoradio") Loader {
streamURL: "https://youradio.nonamesoft.xyz/api/autoradio" active: tabbar.currentIndex == 0
asynchronous: true
visible: status == Loader.Ready
sourceComponent: ViewPlayer {
title: qsTr("Autoradio")
streamURL: "https://youradio.nonamesoft.xyz/api/autoradio"
}
} }
// ViewPlayer { Loader {
// title: qsTr("Live Radio") active: tabbar.currentIndex == 1
// streamURL: "https://youradio.nonamesoft.xyz/api/live" asynchronous: true
// } visible: status == Loader.Ready
// ViewPlayer { sourceComponent: ViewPlayer {
// title: qsTr("Deep Bass") title: qsTr("Live Mix")
// streamURL: "https://youradio.nonamesoft.xyz/api/deepbass" streamURL: "https://youradio.nonamesoft.xyz/api/live"
// } }
ViewSettings { }
Loader {
active: tabbar.currentIndex == 2
asynchronous: true
visible: status == Loader.Ready
sourceComponent: ViewPlayer {
title: qsTr("Deep Bass")
streamURL: "https://youradio.nonamesoft.xyz/api/deepbass"
}
} }
} }
YouAds { YouAds {
Layout.fillWidth: false Layout.fillWidth: false
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
visible: tabbar.currentIndex != 1
} }
} }
} }

View File

@@ -6,25 +6,25 @@ MediaPlayer {
source: "" source: ""
function startPlaying(url) { function startPlaying(url) {
if (player.playing) { if (playing) {
return; return;
} }
console.log("Starting playback from " + url); console.log("Starting playback from " + url);
player.source = url; source = url;
player.play(); play();
} }
function stopPlaying() { function stopPlaying() {
console.log("Stopping playback..."); console.log("Stopping playback...");
player.source = ""; source = "";
player.stop(); stop();
} }
audioOutput: AudioOutput { audioOutput: AudioOutput {
volume: 0.4 volume: 0.4
} }
onErrorOccurred: function(error, errorString) { onErrorOccurred: function(error, errorString) {
player.stopPlaying(); stopPlaying();
} }
} }

View File

@@ -3,12 +3,13 @@ import QtQuick.Controls 6.8
import QtQuick.Controls.Basic 6.8 import QtQuick.Controls.Basic 6.8
Button { Button {
property bool outlined: false
implicitHeight: 36 implicitHeight: 36
contentItem: Text { contentItem: Text {
text: parent.text text: parent.text
font.family: Colors.fontFamily font.family: Colors.fontFamily
font.pointSize: Colors.fontSize.base font.pointSize: Colors.fontSize.button
opacity: enabled ? 1.0 : 0.3 opacity: enabled ? 1.0 : 0.3
color: Colors.text; color: Colors.text;
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
@@ -17,7 +18,9 @@ Button {
} }
background: Rectangle { background: Rectangle {
color: parent.hovered ? Colors.primaryAlt : Colors.primary color: parent.outlined ? "transparent" : (parent.hovered ? Colors.primaryAlt : Colors.primary)
border.color: (parent.hovered ? "#555" : "#777")
border.width: parent.outlined ? 2 : 0
opacity: enabled ? 1 : 0.3 opacity: enabled ? 1 : 0.3
radius: 5 radius: 5
} }

View File

@@ -37,8 +37,9 @@ Item {
h4: 16, h4: 16,
h5: 13, h5: 13,
h6: 10, h6: 10,
p: 12, p: 14,
base: 12 base: 14,
button: 12
}) })
property var currentTheme: themes.dark property var currentTheme: themes.dark

View File

@@ -10,7 +10,7 @@ TabButton {
contentItem: Text { contentItem: Text {
text: parent.text text: parent.text
font.family: Colors.fontFamily font.family: Colors.fontFamily
font.pointSize: Colors.fontSize.base font.pointSize: Colors.fontSize.button
opacity: enabled ? 1.0 : 0.3 opacity: enabled ? 1.0 : 0.3
color: Colors.text; color: Colors.text;
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter

View File

@@ -8,50 +8,168 @@ RowLayout {
// Layout.leftMargin: parent.width * 2 // Layout.leftMargin: parent.width * 2
// Layout.rightMargin: parent.width * 2 // Layout.rightMargin: parent.width * 2
TabBar { Container {
id: settingsCategory id: settingsCategory
Layout.fillWidth: false
Layout.fillHeight: true Layout.fillHeight: true
Layout.rightMargin: 15
spacing: 10 implicitWidth: 240
clip: true
contentItem: ListView { contentItem: ListView {
spacing: 7.5
model: settingsCategory.contentModel model: settingsCategory.contentModel
currentIndex: settingsCategory.currentIndex snapMode: ListView.SnapOneItem
spacing: settingsCategory.spacing
orientation: ListView.Vertical orientation: ListView.Vertical
boundsBehavior: Flickable.StopAtBounds
flickableDirection: Flickable.AutoFlickIfNeeded
snapMode: ListView.SnapToItem
highlightMoveDuration: 0
highlightRangeMode: ListView.ApplyRange
preferredHighlightBegin: 40
preferredHighlightEnd: width - 40
} }
TabButton {
Button {
text: qsTr("Appearance") text: qsTr("Appearance")
width: 284 width: 240
outlined: true
onClicked: settingsCategory.currentIndex = 0
} }
TabButton { Button {
text: qsTr("Language")
width: 240
outlined: true
onClicked: settingsCategory.currentIndex = 1
}
Button {
text: qsTr("Playback Settings")
width: 240
outlined: true
onClicked: settingsCategory.currentIndex = 2
}
Button {
text: qsTr("About") text: qsTr("About")
width: 284 width: 240
outlined: true
onClicked: settingsCategory.currentIndex = 3
} }
} }
Rectangle { SwipeView {
Layout.fillHeight: true
width: 5
color: Colors.text
radius: 5
}
StackLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
currentIndex: settingsCategory.currentIndex orientation: Qt.Vertical
interactive: false
currentIndex: tabbar.currentIndex
Loader {
active: tabbar.currentIndex == 0
asynchronous: true
visible: status == Loader.Ready
sourceComponent: ColumnLayout {
Label {
text: "Appearance"
heading: "h1"
font.bold: true
}
}
}
Loader {
active: tabbar.currentIndex == 1
asynchronous: true
visible: status == Loader.Ready
sourceComponent: ColumnLayout {
Label {
text: "Language"
heading: "h1"
font.bold: true
}
}
}
Loader {
active: tabbar.currentIndex == 2
asynchronous: true
visible: status == Loader.Ready
sourceComponent: ColumnLayout {
Label {
text: "Playback Settings"
heading: "h1"
font.bold: true
}
}
}
Loader {
active: tabbar.currentIndex == 3
asynchronous: true
visible: status == Loader.Ready
sourceComponent: ColumnLayout {
Label {
text: "About"
heading: "h1"
font.bold: true
}
Label {
text: "YouRadio"
heading: "h2"
font.bold: true
}
Label {
text: "by Youpiter"
heading: "h3"
font.bold: true
}
Label {
text: "Music source"
heading: "base"
font.bold: true
}
Label {
text: "QYouRadio"
heading: "h3"
font.bold: true
}
Label {
text: "by Ghostfox"
heading: "h3"
font.bold: true
}
Label {
text: "Client development"
heading: "base"
font.bold: true
}
Label {
text: "Attribution"
heading: "h1"
font.bold: true
}
Label {
text: "Qt"
heading: "h2"
font.bold: true
}
Label {
text: "by Qt Group Inc."
heading: "h3"
font.bold: true
}
Label {
text: "Open-Source library on which QYouRadio is built uppon, licensed under LGPL-3.0"
heading: "base"
font.bold: true
}
}
}
} }
} }

6
flake.lock generated
View File

@@ -20,11 +20,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1760036653, "lastModified": 1760315168,
"narHash": "sha256-FJOwW7YMxtnMi3R+MxwiVsUsrOtm3ubIBo8Jdc1nH6w=", "narHash": "sha256-qWDhFoiz6VSd+S+rVzC2m5u8xuAzxRsuDI8OojbPEZ4=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "b6bae5b8d26ef00d8df42206ac24d0665640286b", "rev": "160e3dfce302bb2fcd03761b84248c7534f3b948",
"type": "github" "type": "github"
}, },
"original": { "original": {