mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-16 08:14:03 -04:00
island: resize to notifications based on title size
This commit is contained in:
@@ -20,27 +20,17 @@ Item {
|
||||
readonly property real itemSpacing: root.tight ? Theme.spacingXS : Theme.spacingS
|
||||
readonly property real dotSize: root.tight ? 3 : 4
|
||||
readonly property bool weatherSlotEnabled: root.controller.homeWeatherSlot !== "hidden"
|
||||
readonly property bool batteryStatus: BatteryService.batteryAvailable
|
||||
readonly property var leftSlotIds: root.slotsForSide("left")
|
||||
readonly property var rightSlotIds: root.slotsForSide("right")
|
||||
readonly property var clusterIds: root.clusterItemsForSide("left").concat(["clock"]).concat(root.clusterItemsForSide("right"))
|
||||
readonly property var clusterIds: root.itemsForSide("left").concat(["clock"]).concat(root.itemsForSide("right"))
|
||||
property bool weatherRefHeld: false
|
||||
|
||||
function slotsForSide(side) {
|
||||
function itemsForSide(side) {
|
||||
const ids = [];
|
||||
if (root.controller.homeMediaSlot === side)
|
||||
ids.push("media");
|
||||
if (root.controller.homeStatusSlot === side && !root.batteryStatus)
|
||||
ids.push("status");
|
||||
return ids;
|
||||
}
|
||||
|
||||
function clusterItemsForSide(side) {
|
||||
const ids = [];
|
||||
if (root.controller.homeWeatherSlot === side)
|
||||
ids.push("weather");
|
||||
if (root.controller.homeStatusSlot === side && root.batteryStatus)
|
||||
ids.push("battery");
|
||||
if (root.controller.homeStatusSlot === side)
|
||||
ids.push("status");
|
||||
return ids;
|
||||
}
|
||||
|
||||
@@ -76,66 +66,6 @@ Item {
|
||||
precision: SettingsData.showSeconds ? SystemClock.Seconds : SystemClock.Minutes
|
||||
}
|
||||
|
||||
component HomeActionSlot: Item {
|
||||
id: slot
|
||||
|
||||
required property string actionId
|
||||
|
||||
readonly property bool isMedia: slot.actionId === "media"
|
||||
|
||||
width: root.slotSize
|
||||
height: root.slotSize
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: height / 2
|
||||
color: slotArea.containsMouse ? Theme.surfaceTextHover : "transparent"
|
||||
}
|
||||
|
||||
AudioVisualization {
|
||||
anchors.centerIn: parent
|
||||
width: root.tight ? 16 : 20
|
||||
height: width
|
||||
maxBarHeight: Math.max(3, height - 2)
|
||||
idleIconName: "graphic_eq"
|
||||
visible: slot.isMedia && root.controller.mediaAvailable
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
visible: slot.isMedia && !root.controller.mediaAvailable
|
||||
name: "search"
|
||||
size: root.iconSize
|
||||
color: Theme.surfaceTextMedium
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
visible: !slot.isMedia
|
||||
name: "tune"
|
||||
size: root.iconSize
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
IslandSlotHoverArea {
|
||||
id: slotArea
|
||||
|
||||
anchors.fill: parent
|
||||
controller: root.controller
|
||||
onClicked: {
|
||||
if (!slot.isMedia) {
|
||||
root.controller.requestControlCenter("", false);
|
||||
return;
|
||||
}
|
||||
if (root.controller.mediaAvailable) {
|
||||
root.controller.requestActivity("media", false, false);
|
||||
return;
|
||||
}
|
||||
root.controller.requestLauncher("", "", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component ClusterDot: Rectangle {
|
||||
property bool unread: false
|
||||
|
||||
@@ -146,6 +76,16 @@ Item {
|
||||
color: unread ? Theme.secondary : Theme.primary
|
||||
}
|
||||
|
||||
component HoverBackdrop: Rectangle {
|
||||
property bool hovered: false
|
||||
|
||||
anchors.centerIn: parent
|
||||
width: parent.width + Theme.spacingS
|
||||
height: root.slotSize
|
||||
radius: height / 2
|
||||
color: hovered ? Theme.surfaceTextHover : "transparent"
|
||||
}
|
||||
|
||||
component ClusterItem: Row {
|
||||
id: item
|
||||
|
||||
@@ -153,8 +93,10 @@ Item {
|
||||
property int itemIndex: 0
|
||||
|
||||
readonly property bool isClock: item.itemId === "clock"
|
||||
readonly property bool isMedia: item.itemId === "media"
|
||||
readonly property bool isWeather: item.itemId === "weather"
|
||||
readonly property bool isBattery: item.itemId === "battery"
|
||||
readonly property bool isStatus: item.itemId === "status"
|
||||
readonly property bool usesBattery: item.isStatus && BatteryService.batteryAvailable
|
||||
|
||||
spacing: root.itemSpacing
|
||||
|
||||
@@ -177,7 +119,7 @@ Item {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: root.timeText
|
||||
color: Theme.surfaceText
|
||||
font.pixelSize: root.tight ? Theme.fontSizeSmall : Theme.fontSizeMedium
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.DemiBold
|
||||
}
|
||||
|
||||
@@ -189,7 +131,7 @@ Item {
|
||||
IslandSlotHoverArea {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width + Theme.spacingS
|
||||
height: parent.height + Theme.spacingS
|
||||
height: root.slotSize
|
||||
enabled: unreadDot.unread
|
||||
controller: root.controller
|
||||
onClicked: root.controller.requestNotificationCenter(false)
|
||||
@@ -206,17 +148,56 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: root.iconSize + Theme.spacingXS
|
||||
height: root.slotSize
|
||||
visible: item.isMedia
|
||||
|
||||
HoverBackdrop {
|
||||
hovered: mediaArea.containsMouse
|
||||
}
|
||||
|
||||
AudioVisualization {
|
||||
anchors.centerIn: parent
|
||||
width: root.iconSize + Theme.spacingXS
|
||||
height: width
|
||||
maxBarHeight: Math.max(3, height - 2)
|
||||
idleIconName: "graphic_eq"
|
||||
visible: root.controller.mediaAvailable
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
visible: !root.controller.mediaAvailable
|
||||
name: "search"
|
||||
size: root.iconSize
|
||||
color: Theme.surfaceTextMedium
|
||||
}
|
||||
|
||||
IslandSlotHoverArea {
|
||||
id: mediaArea
|
||||
|
||||
anchors.centerIn: parent
|
||||
width: parent.width + Theme.spacingS
|
||||
height: root.slotSize
|
||||
controller: root.controller
|
||||
onClicked: {
|
||||
if (root.controller.mediaAvailable) {
|
||||
root.controller.requestActivity("media", false, false);
|
||||
return;
|
||||
}
|
||||
root.controller.requestLauncher("", "", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: weatherRow.implicitWidth
|
||||
height: root.slotSize
|
||||
visible: item.isWeather
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width + Theme.spacingS
|
||||
height: parent.height
|
||||
radius: height / 2
|
||||
color: weatherArea.containsMouse ? Theme.surfaceTextHover : "transparent"
|
||||
HoverBackdrop {
|
||||
hovered: weatherArea.containsMouse
|
||||
}
|
||||
|
||||
Row {
|
||||
@@ -246,32 +227,45 @@ Item {
|
||||
|
||||
anchors.centerIn: parent
|
||||
width: parent.width + Theme.spacingS
|
||||
height: parent.height
|
||||
height: root.slotSize
|
||||
controller: root.controller
|
||||
onClicked: root.controller.requestWeather(false)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: batteryMeter.width
|
||||
width: item.usesBattery ? batteryMeter.width : root.iconSize
|
||||
height: root.slotSize
|
||||
visible: item.isBattery
|
||||
visible: item.isStatus
|
||||
|
||||
HoverBackdrop {
|
||||
hovered: statusArea.containsMouse && !item.usesBattery
|
||||
}
|
||||
|
||||
BatteryMeter {
|
||||
id: batteryMeter
|
||||
|
||||
anchors.centerIn: parent
|
||||
visible: item.usesBattery
|
||||
thickness: root.tight ? 12 : 14
|
||||
hovered: batteryArea.containsMouse
|
||||
hovered: statusArea.containsMouse
|
||||
outlined: SettingsData.dankIslandBatteryStyle === "outline"
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
visible: !item.usesBattery
|
||||
name: "tune"
|
||||
size: root.iconSize
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
IslandSlotHoverArea {
|
||||
id: batteryArea
|
||||
id: statusArea
|
||||
|
||||
anchors.centerIn: parent
|
||||
width: parent.width + Theme.spacingS
|
||||
height: parent.height
|
||||
height: root.slotSize
|
||||
controller: root.controller
|
||||
onClicked: root.controller.requestControlCenter("", false)
|
||||
}
|
||||
@@ -282,39 +276,17 @@ Item {
|
||||
id: compactRow
|
||||
|
||||
anchors.centerIn: parent
|
||||
spacing: root.controller.homeClusterGap
|
||||
height: root.slotSize
|
||||
spacing: root.itemSpacing
|
||||
|
||||
Repeater {
|
||||
model: root.leftSlotIds
|
||||
model: root.clusterIds
|
||||
|
||||
HomeActionSlot {
|
||||
ClusterItem {
|
||||
required property var modelData
|
||||
actionId: String(modelData)
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
height: root.slotSize
|
||||
spacing: root.itemSpacing
|
||||
|
||||
Repeater {
|
||||
model: root.clusterIds
|
||||
|
||||
ClusterItem {
|
||||
required property var modelData
|
||||
required property int index
|
||||
itemId: String(modelData)
|
||||
itemIndex: index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: root.rightSlotIds
|
||||
|
||||
HomeActionSlot {
|
||||
required property var modelData
|
||||
actionId: String(modelData)
|
||||
required property int index
|
||||
itemId: String(modelData)
|
||||
itemIndex: index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,38 @@ Item {
|
||||
id: root
|
||||
|
||||
required property var notificationModel
|
||||
required property var controller
|
||||
property bool dense: false
|
||||
property real iconSize: 36
|
||||
|
||||
readonly property string headerText: root.notificationModel.appName + (root.notificationModel.timeText ? " · " + root.notificationModel.timeText : "")
|
||||
readonly property string summaryText: root.dense && root.notificationModel.appName ? root.notificationModel.appName + " · " + root.notificationModel.summary : root.notificationModel.summary
|
||||
readonly property real criticalWidth: root.notificationModel.critical ? 3 + Theme.spacingS : 0
|
||||
readonly property real measuredWidth: Theme.spacingS * 3 + root.criticalWidth + root.iconSize + Math.max(root.dense ? 0 : headerMetrics.width, summaryMetrics.width)
|
||||
|
||||
function pushMeasuredWidth() {
|
||||
root.controller.setNotificationContentWidth(root.measuredWidth);
|
||||
}
|
||||
|
||||
onMeasuredWidthChanged: root.pushMeasuredWidth()
|
||||
Component.onCompleted: root.pushMeasuredWidth()
|
||||
|
||||
StyledTextMetrics {
|
||||
id: headerMetrics
|
||||
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
text: root.headerText
|
||||
}
|
||||
|
||||
StyledTextMetrics {
|
||||
id: summaryMetrics
|
||||
|
||||
font.pixelSize: root.dense ? Theme.fontSizeSmall : Theme.fontSizeMedium
|
||||
font.weight: Font.DemiBold
|
||||
text: root.summaryText
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors {
|
||||
fill: parent
|
||||
@@ -40,13 +69,13 @@ Item {
|
||||
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: parent.width - root.iconSize - parent.spacing - (root.notificationModel.critical ? 3 + parent.spacing : 0)
|
||||
width: parent.width - root.iconSize - parent.spacing - root.criticalWidth
|
||||
spacing: 1
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
visible: !root.dense
|
||||
text: root.notificationModel.appName + (root.notificationModel.timeText ? " · " + root.notificationModel.timeText : "")
|
||||
text: root.headerText
|
||||
color: Theme.surfaceTextSecondary
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
font.weight: Font.Medium
|
||||
@@ -55,7 +84,7 @@ Item {
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: root.dense && root.notificationModel.appName ? root.notificationModel.appName + " · " + root.notificationModel.summary : root.notificationModel.summary
|
||||
text: root.summaryText
|
||||
color: Theme.surfaceText
|
||||
font.pixelSize: root.dense ? Theme.fontSizeSmall : Theme.fontSizeMedium
|
||||
font.weight: Font.DemiBold
|
||||
|
||||
@@ -464,6 +464,7 @@ Item {
|
||||
|
||||
NotificationCompact {
|
||||
notificationModel: root.notificationModel
|
||||
controller: root.controller
|
||||
dense: root.controller.compactDense
|
||||
iconSize: root.controller.compactIconSize
|
||||
}
|
||||
|
||||
@@ -66,6 +66,9 @@ QtObject {
|
||||
property real homeContentWidth: 200
|
||||
property real mediaContentWidth: 360
|
||||
readonly property real mediaCompactMaxWidth: 360
|
||||
property real notificationContentWidth: 0
|
||||
readonly property real notificationCompactMinWidth: compactDense ? 200 : 240
|
||||
readonly property real notificationCompactMaxWidth: compactDense ? 320 : 360
|
||||
|
||||
signal sessionStarted(string activityId)
|
||||
|
||||
@@ -76,6 +79,13 @@ QtObject {
|
||||
homeContentWidth = next;
|
||||
}
|
||||
|
||||
function setNotificationContentWidth(width) {
|
||||
const next = Math.ceil(width);
|
||||
if (!isFinite(next) || next <= 0 || Math.abs(next - notificationContentWidth) < 2)
|
||||
return;
|
||||
notificationContentWidth = next;
|
||||
}
|
||||
|
||||
function setMediaContentWidth(width) {
|
||||
const next = Math.ceil(Math.min(root.mediaCompactMaxWidth, width));
|
||||
if (!isFinite(next) || next <= 0 || Math.abs(next - mediaContentWidth) < 2)
|
||||
@@ -306,7 +316,7 @@ QtObject {
|
||||
readonly property var weatherExpandedTarget: sheetTarget(SettingsData.showWeekNumber ? 736 : 700, 452)
|
||||
readonly property var systemCompactTarget: pillTarget(SettingsData.osdAlwaysShowValue ? 330 : 282, compactFaceHeight)
|
||||
readonly property var systemExpandedTarget: sheetTarget(460, 176)
|
||||
readonly property var notificationCompactTarget: pillTarget(compactDense ? 320 : 360, compactFaceHeight)
|
||||
readonly property var notificationCompactTarget: pillTarget(Math.ceil(Math.max(notificationCompactMinWidth, Math.min(notificationCompactMaxWidth, notificationContentWidth))), compactFaceHeight)
|
||||
readonly property var notificationExpandedTarget: sheetTarget(520, 220)
|
||||
readonly property var notificationCenterExpandedTarget: sheetTarget(480, notificationCenterHeight)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user