controlcenter: add floating mode

Closes #363
This commit is contained in:
2 * r + 2 * t 2025-08-07 15:38:17 +10:00
parent 5bcface15a
commit d9ffc13825
8 changed files with 187 additions and 24 deletions

View file

@ -1,4 +1,5 @@
import qs.components.misc
import qs.modules.controlcenter
import qs.services
import Quickshell
import Quickshell.Io
@ -8,6 +9,12 @@ Scope {
property bool launcherInterrupted
CustomShortcut {
name: "controlCenter"
description: "Open control center"
onPressed: WindowFactory.create()
}
CustomShortcut {
name: "showall"
description: "Toggle launcher, dashboard and osd"
@ -62,4 +69,12 @@ Scope {
return Object.keys(visibilities).filter(k => typeof visibilities[k] === "boolean").join("\n");
}
}
IpcHandler {
target: "controlCenter"
function open(): void {
WindowFactory.create();
}
}
}

View file

@ -101,6 +101,10 @@ Item {
sourceComponent: ControlCenter {
screen: root.screen
active: root.queuedMode
function close(): void {
root.close();
}
}
}

View file

@ -12,9 +12,19 @@ Item {
id: root
required property ShellScreen screen
property bool floating
readonly property int rounding: floating ? 0 : Appearance.rounding.normal
property alias active: session.active
property alias navExpanded: session.navExpanded
readonly property Session session: Session {
id: session
root: root
}
function close(): void {
}
implicitWidth: implicitHeight * Config.controlCenter.sizes.ratio
@ -28,8 +38,8 @@ Item {
StyledRect {
Layout.fillHeight: true
topLeftRadius: Appearance.rounding.normal
bottomLeftRadius: Appearance.rounding.normal
topLeftRadius: root.rounding
bottomLeftRadius: root.rounding
implicitWidth: navRail.implicitWidth
color: Colours.palette.m3surfaceContainer
@ -47,6 +57,7 @@ Item {
NavRail {
id: navRail
screen: root.screen
session: root.session
}
}
@ -55,6 +66,8 @@ Item {
Layout.fillWidth: true
Layout.fillHeight: true
topRightRadius: root.rounding
bottomRightRadius: root.rounding
session: root.session
}
}

View file

@ -3,14 +3,15 @@ pragma ComponentBehavior: Bound
import qs.components
import qs.services
import qs.config
import Quickshell
import QtQuick
import QtQuick.Layouts
Item {
id: root
required property ShellScreen screen
required property Session session
property bool expanded
implicitWidth: layout.implicitWidth + Appearance.padding.large * 4
implicitHeight: layout.implicitHeight + Appearance.padding.large * 2
@ -23,7 +24,7 @@ Item {
states: State {
name: "expanded"
when: root.expanded
when: root.session.navExpanded
PropertyChanges {
layout.spacing: Appearance.spacing.small
@ -32,14 +33,6 @@ Item {
menuIcon.rotation: 180
menuIconExpanded.rotation: 0
}
AnchorChanges {
target: menuIcon
anchors.horizontalCenter: undefined
}
AnchorChanges {
target: menuIconExpanded
anchors.horizontalCenter: undefined
}
}
transitions: Transition {
@ -49,23 +42,27 @@ Item {
}
Item {
id: menuBtn
Layout.topMargin: Appearance.spacing.large
Layout.fillWidth: true
Layout.bottomMargin: Appearance.spacing.large * 2
implicitHeight: Math.max(menuIcon.implicitHeight, menuIconExpanded.implicitHeight) + Appearance.padding.normal * 2
implicitHeight: menuIcon.implicitHeight + Appearance.padding.normal * 2
StateLayer {
radius: Appearance.rounding.small
function onClicked(): void {
root.expanded = !root.expanded;
root.session.navExpanded = !root.session.navExpanded;
}
}
MaterialIcon {
id: menuIcon
anchors.horizontalCenter: parent.horizontalCenter
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Appearance.padding.large
text: "menu"
font.pointSize: Appearance.font.size.large
}
@ -73,15 +70,86 @@ Item {
MaterialIcon {
id: menuIconExpanded
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
anchors.fill: menuIcon
text: "menu_open"
font.pointSize: Appearance.font.size.large
font.pointSize: menuIcon.font.pointSize
opacity: 0
rotation: -180
}
}
StyledRect {
id: normalWinBtn
readonly property int nonAnimWidth: normalWinIcon.implicitWidth + (root.session.navExpanded ? normalWinLabel.anchors.leftMargin + normalWinLabel.implicitWidth : 0) + normalWinIcon.anchors.leftMargin * 2
Layout.bottomMargin: Appearance.spacing.large * 2
implicitWidth: nonAnimWidth
implicitHeight: root.session.navExpanded ? normalWinIcon.implicitHeight + Appearance.padding.normal * 2 : nonAnimWidth
color: Colours.palette.m3primaryContainer
radius: Appearance.rounding.small
StateLayer {
id: normalWinState
color: Colours.palette.m3onPrimaryContainer
function onClicked(): void {
root.session.root.close();
WindowFactory.create(null, {
screen: root.screen,
active: root.session.active,
navExpanded: root.session.navExpanded
});
}
}
MaterialIcon {
id: normalWinIcon
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Appearance.padding.large
text: "select_window"
font.pointSize: Appearance.font.size.large
fill: 1
}
StyledText {
id: normalWinLabel
anchors.left: normalWinIcon.right
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Appearance.spacing.normal
text: qsTr("Open in window")
opacity: root.session.navExpanded ? 1 : 0
Behavior on opacity {
Anim {
duration: Appearance.anim.durations.small
}
}
}
Behavior on implicitWidth {
Anim {
duration: Appearance.anim.durations.expressiveDefaultSpatial
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
}
}
Behavior on implicitHeight {
Anim {
duration: Appearance.anim.durations.expressiveDefaultSpatial
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
}
}
}
NavItem {
icon: "network_manage"
label: "network"
@ -110,7 +178,7 @@ Item {
states: State {
name: "expanded"
when: root.expanded
when: root.session.navExpanded
PropertyChanges {
expandedLabel.opacity: 1

View file

@ -14,8 +14,6 @@ ClippingRectangle {
required property Session session
topRightRadius: Appearance.rounding.normal
bottomRightRadius: Appearance.rounding.normal
color: "transparent"
ColumnLayout {

View file

@ -4,8 +4,10 @@ import QtQuick
QtObject {
readonly property list<string> panes: ["network", "bluetooth", "audio"]
property string active
property int activeIndex
required property var root
property string active: panes[0]
property int activeIndex: 0
property bool navExpanded: false
readonly property Bt bt: Bt {}

View file

@ -0,0 +1,62 @@
pragma Singleton
import qs.services
import qs.config
import Quickshell
import QtQuick
Singleton {
id: root
function create(parent: Item, props: var): void {
controlCenter.createObject(parent ?? dummy, props);
}
QtObject {
id: dummy
}
Component {
id: controlCenter
FloatingWindow {
id: win
property alias active: cc.active
property alias navExpanded: cc.navExpanded
color: Colours.palette.m3surface
onVisibleChanged: {
if (!visible)
destroy();
}
minimumSize.width: 1000
minimumSize.height: 600
implicitWidth: cc.implicitWidth
implicitHeight: cc.implicitHeight
ControlCenter {
id: cc
anchors.fill: parent
screen: win.screen
floating: true
function close(): void {
win.visible = false;
}
}
Behavior on color {
ColorAnimation {
duration: Appearance.anim.durations.normal
easing.type: Easing.BezierSpline
easing.bezierCurve: Appearance.anim.curves.standard
}
}
}
}
}

View file

@ -19,6 +19,7 @@ RowLayout {
Item {
Layout.preferredWidth: Math.floor(parent.width * 0.4)
Layout.minimumWidth: 420
Layout.fillHeight: true
DeviceList {