summaryrefslogtreecommitdiff
path: root/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/DankDash/DankDashPopout.qml
diff options
context:
space:
mode:
authorAlexanderCurl <alexc@alexc.hu>2026-04-18 17:46:06 +0100
committerAlexanderCurl <alexc@alexc.hu>2026-04-18 17:46:06 +0100
commit70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69 (patch)
treeab1123d4067c1b086dd6faa7ee4ea643236b565a /raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/DankDash/DankDashPopout.qml
parent5d94c0a7d44a2255b81815a52a7056a94a39842d (diff)
downloadRaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.tar.gz
RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.zip
Replaced file structures for themes in the correct format
Diffstat (limited to 'raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/DankDash/DankDashPopout.qml')
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/DankDash/DankDashPopout.qml425
1 files changed, 425 insertions, 0 deletions
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/DankDash/DankDashPopout.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/DankDash/DankDashPopout.qml
new file mode 100644
index 0000000..34b324c
--- /dev/null
+++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/DankDash/DankDashPopout.qml
@@ -0,0 +1,425 @@
+import QtQuick
+import qs.Common
+import qs.Services
+import qs.Widgets
+
+DankPopout {
+ id: root
+
+ layerNamespace: "dms:dash"
+
+ property bool dashVisible: false
+ property var triggerScreen: null
+ property int currentTabIndex: 0
+
+ popupWidth: SettingsData.showWeekNumber ? 736 : 700
+ popupHeight: contentLoader.item ? contentLoader.item.implicitHeight : 500
+ triggerWidth: 80
+ screen: triggerScreen
+ shouldBeVisible: dashVisible
+
+ property bool __focusArmed: false
+ property bool __contentReady: false
+
+ property var __mediaTabRef: null
+
+ property int __dropdownType: 0
+ property point __dropdownAnchor: Qt.point(0, 0)
+ property bool __dropdownRightEdge: false
+ property var __dropdownPlayer: null
+ property var __dropdownPlayers: []
+
+ function __showVolumeDropdown(pos, rightEdge, player, players) {
+ __dropdownAnchor = pos;
+ __dropdownRightEdge = rightEdge;
+ __dropdownPlayer = player;
+ __dropdownPlayers = players;
+ __dropdownType = 1;
+ }
+
+ function __showAudioDevicesDropdown(pos, rightEdge) {
+ __dropdownAnchor = pos;
+ __dropdownRightEdge = rightEdge;
+ __dropdownType = 2;
+ }
+
+ function __showPlayersDropdown(pos, rightEdge, player, players) {
+ __dropdownAnchor = pos;
+ __dropdownRightEdge = rightEdge;
+ __dropdownPlayer = player;
+ __dropdownPlayers = players;
+ __dropdownType = 3;
+ }
+
+ function __hideDropdowns() {
+ __volumeCloseTimer.stop();
+ __dropdownType = 0;
+ __mediaTabRef?.resetDropdownStates();
+ }
+
+ function __startCloseTimer() {
+ __volumeCloseTimer.restart();
+ }
+
+ function __stopCloseTimer() {
+ __volumeCloseTimer.stop();
+ }
+
+ Timer {
+ id: __volumeCloseTimer
+ interval: 400
+ onTriggered: {
+ if (__dropdownType === 1) {
+ __hideDropdowns();
+ }
+ }
+ }
+
+ overlayContent: Component {
+ MediaDropdownOverlay {
+ dropdownType: root.__dropdownType
+ anchorPos: root.__dropdownAnchor
+ isRightEdge: root.__dropdownRightEdge
+ activePlayer: root.__dropdownPlayer
+ allPlayers: root.__dropdownPlayers
+ onCloseRequested: root.__hideDropdowns()
+ onPanelEntered: root.__stopCloseTimer()
+ onPanelExited: root.__startCloseTimer()
+ onVolumeChanged: volume => {
+ const player = root.__dropdownPlayer;
+ const isChrome = player?.identity?.toLowerCase().includes("chrome") || player?.identity?.toLowerCase().includes("chromium");
+ const usePlayerVolume = player && player.volumeSupported && !isChrome;
+ if (usePlayerVolume) {
+ player.volume = volume;
+ } else if (AudioService.sink?.audio) {
+ AudioService.sink.audio.volume = volume;
+ }
+ }
+ onPlayerSelected: player => {
+ const currentPlayer = MprisController.activePlayer;
+ if (currentPlayer && currentPlayer !== player && currentPlayer.canPause) {
+ currentPlayer.pause();
+ }
+ MprisController.setActivePlayer(player);
+ root.__hideDropdowns();
+ }
+ onDeviceSelected: device => {
+ root.__hideDropdowns();
+ }
+ }
+ }
+
+ function __tryFocusOnce() {
+ if (!__focusArmed)
+ return;
+ const win = root.window;
+ if (!win || !win.visible)
+ return;
+ if (!contentLoader.item)
+ return;
+ if (win.requestActivate)
+ win.requestActivate();
+ contentLoader.item.forceActiveFocus(Qt.TabFocusReason);
+
+ if (contentLoader.item.activeFocus)
+ __focusArmed = false;
+ }
+
+ onDashVisibleChanged: {
+ if (dashVisible) {
+ __focusArmed = true;
+ __contentReady = !!contentLoader.item;
+ open();
+ __tryFocusOnce();
+ } else {
+ __focusArmed = false;
+ __contentReady = false;
+ __hideDropdowns();
+ close();
+ }
+ }
+
+ Connections {
+ target: contentLoader
+ function onLoaded() {
+ __contentReady = true;
+ if (__focusArmed)
+ __tryFocusOnce();
+ }
+ }
+
+ Connections {
+ target: root.window ? root.window : null
+ enabled: !!root.window
+ function onVisibleChanged() {
+ if (__focusArmed)
+ __tryFocusOnce();
+ }
+ }
+
+ onBackgroundClicked: {
+ dashVisible = false;
+ }
+
+ content: Component {
+ Rectangle {
+ id: mainContainer
+
+ LayoutMirroring.enabled: I18n.isRtl
+ LayoutMirroring.childrenInherit: true
+
+ implicitWidth: Math.max(700, pages.implicitWidth + (Theme.spacingM * 2))
+ implicitHeight: contentColumn.height + Theme.spacingM * 2
+ color: "transparent"
+ focus: true
+
+ Component.onCompleted: {
+ if (root.shouldBeVisible) {
+ mainContainer.forceActiveFocus();
+ }
+ }
+
+ Connections {
+ target: root
+ function onShouldBeVisibleChanged() {
+ if (root.shouldBeVisible) {
+ Qt.callLater(function () {
+ mainContainer.forceActiveFocus();
+ });
+ }
+ }
+ }
+
+ Keys.onPressed: function (event) {
+ if (event.key === Qt.Key_Escape) {
+ root.dashVisible = false;
+ event.accepted = true;
+ return;
+ }
+
+ if (event.key === Qt.Key_Tab && !(event.modifiers & Qt.ShiftModifier)) {
+ let nextIndex = root.currentTabIndex + 1;
+ while (nextIndex < tabBar.model.length && tabBar.model[nextIndex] && tabBar.model[nextIndex].isAction) {
+ nextIndex++;
+ }
+ if (nextIndex >= tabBar.model.length) {
+ nextIndex = 0;
+ }
+ root.currentTabIndex = nextIndex;
+ event.accepted = true;
+ return;
+ }
+
+ if (event.key === Qt.Key_Backtab || (event.key === Qt.Key_Tab && (event.modifiers & Qt.ShiftModifier))) {
+ let prevIndex = root.currentTabIndex - 1;
+ while (prevIndex >= 0 && tabBar.model[prevIndex] && tabBar.model[prevIndex].isAction) {
+ prevIndex--;
+ }
+ if (prevIndex < 0) {
+ prevIndex = tabBar.model.length - 1;
+ while (prevIndex >= 0 && tabBar.model[prevIndex] && tabBar.model[prevIndex].isAction) {
+ prevIndex--;
+ }
+ }
+ if (prevIndex >= 0) {
+ root.currentTabIndex = prevIndex;
+ }
+ event.accepted = true;
+ return;
+ }
+
+ if (root.currentTabIndex === 2 && wallpaperLoader.item?.handleKeyEvent) {
+ if (wallpaperLoader.item.handleKeyEvent(event)) {
+ event.accepted = true;
+ return;
+ }
+ }
+ }
+
+ Column {
+ id: contentColumn
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.margins: Theme.spacingM
+ spacing: Theme.spacingS
+
+ DankTabBar {
+ id: tabBar
+
+ width: parent.width
+ height: 48
+ currentIndex: root.currentTabIndex
+ spacing: Theme.spacingS
+ equalWidthTabs: true
+ enableArrowNavigation: false
+ focus: false
+ activeFocusOnTab: false
+ nextFocusTarget: {
+ const item = pages.currentItem;
+ if (!item)
+ return null;
+ if (item.focusTarget)
+ return item.focusTarget;
+ return item;
+ }
+
+ model: {
+ let tabs = [
+ {
+ "icon": "dashboard",
+ "text": I18n.tr("Overview")
+ },
+ {
+ "icon": "music_note",
+ "text": I18n.tr("Media")
+ },
+ {
+ "icon": "wallpaper",
+ "text": I18n.tr("Wallpapers")
+ }
+ ];
+
+ if (SettingsData.weatherEnabled) {
+ tabs.push({
+ "icon": "wb_sunny",
+ "text": I18n.tr("Weather")
+ });
+ }
+
+ tabs.push({
+ "icon": "settings",
+ "text": I18n.tr("Settings"),
+ "isAction": true
+ });
+ return tabs;
+ }
+
+ onTabClicked: function (index) {
+ root.currentTabIndex = index;
+ }
+
+ onActionTriggered: function (index) {
+ let settingsIndex = SettingsData.weatherEnabled ? 4 : 3;
+ if (index === settingsIndex) {
+ dashVisible = false;
+ PopoutService.focusOrToggleSettings();
+ }
+ }
+ }
+
+ Item {
+ width: parent.width
+ height: Theme.spacingXS
+ }
+
+ Item {
+ id: pages
+ width: parent.width
+ height: implicitHeight
+ implicitWidth: currentItem && currentItem.implicitWidth > 0 ? currentItem.implicitWidth : (700 - Theme.spacingM * 2)
+ implicitHeight: {
+ if (root.currentTabIndex === 0)
+ return overviewLoader.item?.implicitHeight ?? 410;
+ if (root.currentTabIndex === 1)
+ return mediaLoader.item?.implicitHeight ?? 410;
+ if (root.currentTabIndex === 2)
+ return wallpaperLoader.item?.implicitHeight ?? 410;
+ if (SettingsData.weatherEnabled && root.currentTabIndex === 3)
+ return weatherLoader.item?.implicitHeight ?? 410;
+ return 410;
+ }
+
+ readonly property var currentItem: {
+ if (root.currentTabIndex === 0)
+ return overviewLoader.item;
+ if (root.currentTabIndex === 1)
+ return mediaLoader.item;
+ if (root.currentTabIndex === 2)
+ return wallpaperLoader.item;
+ if (root.currentTabIndex === 3)
+ return weatherLoader.item;
+ return null;
+ }
+
+ Loader {
+ id: overviewLoader
+ anchors.fill: parent
+ active: root.currentTabIndex === 0
+ visible: active
+ sourceComponent: Component {
+ OverviewTab {
+ onCloseDash: root.dashVisible = false
+ onSwitchToWeatherTab: {
+ if (SettingsData.weatherEnabled) {
+ root.currentTabIndex = 3;
+ }
+ }
+ onSwitchToMediaTab: {
+ root.currentTabIndex = 1;
+ }
+ }
+ }
+ }
+
+ Loader {
+ id: mediaLoader
+ anchors.fill: parent
+ active: root.currentTabIndex === 1
+ visible: active
+ sourceComponent: Component {
+ MediaPlayerTab {
+ targetScreen: root.screen
+ popoutX: root.alignedX
+ popoutY: root.alignedY
+ popoutWidth: root.alignedWidth
+ popoutHeight: root.alignedHeight
+ contentOffsetY: Theme.spacingM + 48 + Theme.spacingS + Theme.spacingXS
+ section: root.triggerSection
+ barPosition: root.effectiveBarPosition
+ Component.onCompleted: root.__mediaTabRef = this
+ onShowVolumeDropdown: (pos, screen, rightEdge, player, players) => {
+ root.__showVolumeDropdown(pos, rightEdge, player, players);
+ }
+ onShowAudioDevicesDropdown: (pos, screen, rightEdge) => {
+ root.__showAudioDevicesDropdown(pos, rightEdge);
+ }
+ onShowPlayersDropdown: (pos, screen, rightEdge, player, players) => {
+ root.__showPlayersDropdown(pos, rightEdge, player, players);
+ }
+ onHideDropdowns: root.__hideDropdowns()
+ onVolumeButtonExited: root.__startCloseTimer()
+ }
+ }
+ }
+
+ Loader {
+ id: wallpaperLoader
+ anchors.fill: parent
+ active: root.currentTabIndex === 2
+ visible: active
+ sourceComponent: Component {
+ WallpaperTab {
+ active: true
+ tabBarItem: tabBar
+ keyForwardTarget: mainContainer
+ targetScreen: root.screen
+ parentPopout: root
+ }
+ }
+ }
+
+ Loader {
+ id: weatherLoader
+ anchors.fill: parent
+ active: SettingsData.weatherEnabled && root.currentTabIndex === 3
+ visible: active
+ sourceComponent: Component {
+ WeatherTab {}
+ }
+ }
+ }
+ }
+ }
+ }
+}