1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-25 05:52:50 -05:00

control center: open relevant tab based on click area, configurable

icons
This commit is contained in:
bbedward
2025-08-20 13:45:46 -04:00
parent 8c7b72fb6c
commit ee8ab26d45
7 changed files with 386 additions and 10 deletions

View File

@@ -27,6 +27,15 @@ DankPopout {
triggerScreen = screen
}
function openWithTab(tab) {
if (shouldBeVisible) {
close()
} else {
currentTab = tab
open()
}
}
signal powerActionRequested(string action, string title, string message)
signal lockRequested

View File

@@ -62,16 +62,20 @@ Item {
width: parent.width
}
Row {
Item {
id: communityIcons
anchors.horizontalCenter: parent.horizontalCenter
spacing: Theme.spacingL
height: 24
width: niriButton.width + matrixButton.width + 4 + discordButton.width + Theme.spacingM + redditButton.width + Theme.spacingM
// Niri logo
Item {
id: niriButton
width: 24
height: 24
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -2
x: 0
property bool hovered: false
property string tooltipText: "niri GitHub"
@@ -103,6 +107,7 @@ Item {
id: matrixButton
width: 30
height: 24
x: niriButton.x + niriButton.width + 4
property bool hovered: false
property string tooltipText: "niri Matrix Chat"
@@ -140,6 +145,8 @@ Item {
id: discordButton
width: 20
height: 20
x: matrixButton.x + matrixButton.width + Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
property bool hovered: false
property string tooltipText: "niri Discord Server"
@@ -171,6 +178,8 @@ Item {
id: redditButton
width: 20
height: 20
x: discordButton.x + discordButton.width + Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
property bool hovered: false
property string tooltipText: "r/niri Subreddit"
@@ -478,7 +487,7 @@ Item {
border.color: Theme.outlineMedium
x: hoveredButton ? hoveredButton.mapToItem(aboutTab, hoveredButton.width / 2, 0).x - width / 2 : 0
y: hoveredButton ? hoveredButton.mapToItem(aboutTab, 0, -height - 4).y : 0
y: hoveredButton ? communityIcons.mapToItem(aboutTab, 0, 0).y - height - 8 : 0
layer.enabled: true
layer.effect: MultiEffect {

View File

@@ -184,6 +184,11 @@ Item {
widgetObj.selectedGpuIndex = 0
widgetObj.pciId = ""
}
if (widgetId === "controlCenterButton") {
widgetObj.showNetworkIcon = true
widgetObj.showBluetoothIcon = true
widgetObj.showAudioIcon = true
}
var widgets = []
if (targetSection === "left") {
@@ -256,6 +261,11 @@ Item {
newWidget.pciId = widget.pciId
else if (widget.id === "gpuTemp")
newWidget.pciId = ""
if (widget.id === "controlCenterButton") {
newWidget.showNetworkIcon = widget.showNetworkIcon !== undefined ? widget.showNetworkIcon : true
newWidget.showBluetoothIcon = widget.showBluetoothIcon !== undefined ? widget.showBluetoothIcon : true
newWidget.showAudioIcon = widget.showAudioIcon !== undefined ? widget.showAudioIcon : true
}
widgets[i] = newWidget
}
break
@@ -306,6 +316,11 @@ Item {
newWidget.selectedGpuIndex = widget.selectedGpuIndex
if (widget.pciId !== undefined)
newWidget.pciId = widget.pciId
if (widget.id === "controlCenterButton") {
newWidget.showNetworkIcon = widget.showNetworkIcon !== undefined ? widget.showNetworkIcon : true
newWidget.showBluetoothIcon = widget.showBluetoothIcon !== undefined ? widget.showBluetoothIcon : true
newWidget.showAudioIcon = widget.showAudioIcon !== undefined ? widget.showAudioIcon : true
}
widgets[i] = newWidget
}
break
@@ -362,6 +377,17 @@ Item {
SettingsData.setTopBarRightWidgets(widgets)
}
function handleControlCenterSettingChanged(sectionId, widgetIndex, settingName, value) {
// Control Center settings are global, not per-widget instance
if (settingName === "showNetworkIcon") {
SettingsData.setControlCenterShowNetworkIcon(value)
} else if (settingName === "showBluetoothIcon") {
SettingsData.setControlCenterShowBluetoothIcon(value)
} else if (settingName === "showAudioIcon") {
SettingsData.setControlCenterShowAudioIcon(value)
}
}
function getItemsForSection(sectionId) {
var widgets = []
var widgetData = []
@@ -380,6 +406,9 @@ Item {
=== "string" ? undefined : widget.selectedGpuIndex
var widgetPciId = typeof widget
=== "string" ? undefined : widget.pciId
var widgetShowNetworkIcon = typeof widget === "string" ? undefined : widget.showNetworkIcon
var widgetShowBluetoothIcon = typeof widget === "string" ? undefined : widget.showBluetoothIcon
var widgetShowAudioIcon = typeof widget === "string" ? undefined : widget.showAudioIcon
var widgetDef = baseWidgetDefinitions.find(w => {
return w.id === widgetId
})
@@ -392,6 +421,12 @@ Item {
item.selectedGpuIndex = widgetSelectedGpuIndex
if (widgetPciId !== undefined)
item.pciId = widgetPciId
if (widgetShowNetworkIcon !== undefined)
item.showNetworkIcon = widgetShowNetworkIcon
if (widgetShowBluetoothIcon !== undefined)
item.showBluetoothIcon = widgetShowBluetoothIcon
if (widgetShowAudioIcon !== undefined)
item.showAudioIcon = widgetShowAudioIcon
widgets.push(item)
}
@@ -779,6 +814,9 @@ Item {
value)
}
}
onControlCenterSettingChanged: (sectionId, widgetIndex, settingName, value) => {
handleControlCenterSettingChanged(sectionId, widgetIndex, settingName, value)
}
onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => {
topBarTab.handleGpuSelectionChanged(
sectionId, widgetIndex,
@@ -846,6 +884,9 @@ Item {
value)
}
}
onControlCenterSettingChanged: (sectionId, widgetIndex, settingName, value) => {
handleControlCenterSettingChanged(sectionId, widgetIndex, settingName, value)
}
onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => {
topBarTab.handleGpuSelectionChanged(
sectionId, widgetIndex,
@@ -913,6 +954,9 @@ Item {
value)
}
}
onControlCenterSettingChanged: (sectionId, widgetIndex, settingName, value) => {
handleControlCenterSettingChanged(sectionId, widgetIndex, settingName, value)
}
onGpuSelectionChanged: (sectionId, widgetIndex, selectedIndex) => {
topBarTab.handleGpuSelectionChanged(
sectionId, widgetIndex,

View File

@@ -20,6 +20,7 @@ Column {
signal spacerSizeChanged(string sectionId, string itemId, int newSize)
signal compactModeChanged(string widgetId, var value)
signal gpuSelectionChanged(string sectionId, int widgetIndex, int selectedIndex)
signal controlCenterSettingChanged(string sectionId, int widgetIndex, string settingName, bool value)
width: parent.width
height: implicitHeight
@@ -372,6 +373,25 @@ Column {
}
}
DankActionButton {
visible: modelData.id === "controlCenterButton"
buttonSize: 32
iconName: "more_vert"
iconSize: 18
iconColor: Theme.outline
onClicked: {
console.log("Control Center three-dot button clicked for widget:", modelData.id)
controlCenterContextMenu.widgetData = modelData
controlCenterContextMenu.sectionId = root.sectionId
controlCenterContextMenu.widgetIndex = index
// Position relative to the action buttons row, not the specific button
var parentPos = parent.mapToItem(root, 0, 0)
controlCenterContextMenu.x = parentPos.x - 210 // Position to the left with margin
controlCenterContextMenu.y = parentPos.y - 10 // Slightly above
controlCenterContextMenu.open()
}
}
DankActionButton {
visible: modelData.id !== "spacer"
buttonSize: 32
@@ -537,4 +557,205 @@ Column {
}
}
}
Popup {
id: controlCenterContextMenu
property var widgetData: null
property string sectionId: ""
property int widgetIndex: -1
width: 200
height: 120
padding: 0
modal: true
focus: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
onOpened: {
console.log("Control Center context menu opened")
}
onClosed: {
console.log("Control Center context menu closed")
}
background: Rectangle {
color: Theme.popupBackground()
radius: Theme.cornerRadius
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
border.width: 1
}
contentItem: Item {
Column {
id: menuColumn
anchors.fill: parent
anchors.margins: Theme.spacingS
spacing: 2
Rectangle {
width: parent.width
height: 32
radius: Theme.cornerRadius
color: networkToggleArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingS
DankIcon {
name: "lan"
size: 16
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Network Icon"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal
anchors.verticalCenter: parent.verticalCenter
}
}
DankToggle {
id: networkToggle
anchors.right: parent.right
anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
width: 40
height: 20
checked: SettingsData.controlCenterShowNetworkIcon
onToggled: {
root.controlCenterSettingChanged(controlCenterContextMenu.sectionId, controlCenterContextMenu.widgetIndex, "showNetworkIcon", toggled)
}
}
MouseArea {
id: networkToggleArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: {
networkToggle.checked = !networkToggle.checked
root.controlCenterSettingChanged(controlCenterContextMenu.sectionId, controlCenterContextMenu.widgetIndex, "showNetworkIcon", networkToggle.checked)
}
}
}
Rectangle {
width: parent.width
height: 32
radius: Theme.cornerRadius
color: bluetoothToggleArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingS
DankIcon {
name: "bluetooth"
size: 16
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Bluetooth Icon"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal
anchors.verticalCenter: parent.verticalCenter
}
}
DankToggle {
id: bluetoothToggle
anchors.right: parent.right
anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
width: 40
height: 20
checked: SettingsData.controlCenterShowBluetoothIcon
onToggled: {
root.controlCenterSettingChanged(controlCenterContextMenu.sectionId, controlCenterContextMenu.widgetIndex, "showBluetoothIcon", toggled)
}
}
MouseArea {
id: bluetoothToggleArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: {
bluetoothToggle.checked = !bluetoothToggle.checked
root.controlCenterSettingChanged(controlCenterContextMenu.sectionId, controlCenterContextMenu.widgetIndex, "showBluetoothIcon", bluetoothToggle.checked)
}
}
}
Rectangle {
width: parent.width
height: 32
radius: Theme.cornerRadius
color: audioToggleArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingS
DankIcon {
name: "volume_up"
size: 16
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Audio Icon"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal
anchors.verticalCenter: parent.verticalCenter
}
}
DankToggle {
id: audioToggle
anchors.right: parent.right
anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
width: 40
height: 20
checked: SettingsData.controlCenterShowAudioIcon
onToggled: {
root.controlCenterSettingChanged(controlCenterContextMenu.sectionId, controlCenterContextMenu.widgetIndex, "showAudioIcon", toggled)
}
}
MouseArea {
id: audioToggleArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: {
audioToggle.checked = !audioToggle.checked
root.controlCenterSettingChanged(controlCenterContextMenu.sectionId, controlCenterContextMenu.widgetIndex, "showAudioIcon", audioToggle.checked)
}
}
}
}
}
}
}

View File

@@ -10,10 +10,16 @@ Rectangle {
property string section: "right"
property var popupTarget: null
property var parentScreen: null
property var widgetData: null
property bool showNetworkIcon: SettingsData.controlCenterShowNetworkIcon
property bool showBluetoothIcon: SettingsData.controlCenterShowBluetoothIcon
property bool showAudioIcon: SettingsData.controlCenterShowAudioIcon
signal clicked
signal iconClicked(string tab)
width: Math.max(80, controlIndicators.implicitWidth + Theme.spacingS * 2)
width: controlIndicators.implicitWidth + Theme.spacingS * 2
height: 30
radius: Theme.cornerRadius
color: {
@@ -30,6 +36,7 @@ Rectangle {
spacing: Theme.spacingXS
DankIcon {
id: networkIcon
name: {
if (NetworkService.networkStatus === "ethernet")
return "lan"
@@ -39,15 +46,16 @@ Rectangle {
color: NetworkService.networkStatus
!== "disconnected" ? Theme.primary : Theme.outlineButton
anchors.verticalCenter: parent.verticalCenter
visible: true
visible: root.showNetworkIcon
}
DankIcon {
id: bluetoothIcon
name: "bluetooth"
size: Theme.iconSize - 8
color: BluetoothService.enabled ? Theme.primary : Theme.outlineButton
anchors.verticalCenter: parent.verticalCenter
visible: BluetoothService.available && BluetoothService.enabled
visible: root.showBluetoothIcon && BluetoothService.available && BluetoothService.enabled
}
Rectangle {
@@ -55,6 +63,7 @@ Rectangle {
height: audioIcon.implicitHeight + 4
color: "transparent"
anchors.verticalCenter: parent.verticalCenter
visible: root.showAudioIcon
DankIcon {
id: audioIcon
@@ -72,9 +81,7 @@ Rectangle {
return "volume_up"
}
size: Theme.iconSize - 8
color: audioWheelArea.containsMouse
|| controlCenterArea.containsMouse
|| root.isActive ? Theme.primary : Theme.surfaceText
color: Theme.surfaceText
anchors.centerIn: parent
}
@@ -98,6 +105,7 @@ Rectangle {
if (AudioService.sink && AudioService.sink.audio) {
AudioService.sink.audio.muted = false
AudioService.sink.audio.volume = newVolume / 100
AudioService.volumeChanged()
}
wheelEvent.accepted = true
}
@@ -111,6 +119,15 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
visible: false // TODO: Add mic detection
}
// Fallback settings icon when all other icons are hidden
DankIcon {
name: "settings"
size: Theme.iconSize - 8
color: controlCenterArea.containsMouse || root.isActive ? Theme.primary : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
visible: !root.showNetworkIcon && !root.showBluetoothIcon && !root.showAudioIcon
}
}
MouseArea {
@@ -129,7 +146,46 @@ Rectangle {
relativeX, Theme.barHeight + Theme.spacingXS,
width, section, currentScreen)
}
root.clicked()
// Calculate which zone was clicked based on mouse position relative to controlIndicators
var indicatorsX = controlIndicators.x
var relativeX = mouseX - indicatorsX
var iconSpacing = Theme.spacingXS
var iconSize = Theme.iconSize - 8
var networkWidth = networkIcon.visible ? iconSize : 0
var bluetoothWidth = bluetoothIcon.visible ? iconSize : 0
var audioWidth = audioIcon.parent.visible ? (iconSize + 4) : 0
var currentX = 0
var clickedZone = ""
// Network zone
if (networkIcon.visible && relativeX >= currentX && relativeX < currentX + networkWidth) {
clickedZone = "network"
}
if (networkIcon.visible) {
currentX += networkWidth + iconSpacing
}
// Bluetooth zone
if (bluetoothIcon.visible && relativeX >= currentX && relativeX < currentX + bluetoothWidth) {
clickedZone = "bluetooth"
}
if (bluetoothIcon.visible) {
currentX += bluetoothWidth + iconSpacing
}
// Audio zone
if (audioIcon.parent.visible && relativeX >= currentX && relativeX < currentX + audioWidth) {
clickedZone = "audio"
}
if (clickedZone !== "") {
root.iconClicked(clickedZone)
} else {
root.clicked()
}
}
}

View File

@@ -995,6 +995,7 @@ PanelWindow {
return controlCenterLoader.item
}
parentScreen: root.screen
widgetData: parent.widgetData
onClicked: {
controlCenterLoader.active = true
if (controlCenterLoader.item) {
@@ -1006,6 +1007,15 @@ PanelWindow {
}
}
}
onIconClicked: (tab) => {
controlCenterLoader.active = true
if (controlCenterLoader.item) {
controlCenterLoader.item.triggerScreen = root.screen
controlCenterLoader.item.openWithTab(tab)
if (NetworkService.wifiEnabled)
NetworkService.scanWifi()
}
}
}
}