Standardize bar icon geometry
This commit is contained in:
@@ -341,6 +341,8 @@ QtObject {
|
|||||||
readonly property QtObject bar: QtObject {
|
readonly property QtObject bar: QtObject {
|
||||||
readonly property int sizeHorizontal: root.barToken("size-horizontal", 26)
|
readonly property int sizeHorizontal: root.barToken("size-horizontal", 26)
|
||||||
readonly property int sizeVertical: root.barToken("size-vertical", 28)
|
readonly property int sizeVertical: root.barToken("size-vertical", 28)
|
||||||
|
readonly property int iconSlot: root.barToken("icon-slot", 27)
|
||||||
|
readonly property int iconCanvas: root.barToken("icon-canvas", 16)
|
||||||
}
|
}
|
||||||
|
|
||||||
function refresh() {
|
function refresh() {
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import qs.Commons
|
||||||
|
|
||||||
|
WidgetButton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property Component iconComponent: null
|
||||||
|
property real opticalSize: Style.bar.iconCanvas
|
||||||
|
property bool debugOpticalBounds: Quickshell.env("OMARCHY_DEBUG_BAR_ICONS") === "1"
|
||||||
|
readonly property real opticalCenterErrorX: glyph.visible ? glyph.paintedCenterX - opticalCanvas.width / 2 : 0
|
||||||
|
readonly property real opticalCenterErrorY: glyph.visible ? glyph.paintedCenterY - opticalCanvas.height / 2 : 0
|
||||||
|
|
||||||
|
labelVisible: false
|
||||||
|
hasVisualContent: text !== "" || iconComponent !== null
|
||||||
|
fontSize: Style.font.body
|
||||||
|
fixedWidth: vertical ? -1 : Style.bar.iconSlot
|
||||||
|
fixedHeight: vertical ? Style.bar.iconSlot : -1
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: opticalCanvas
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: root.opticalSize
|
||||||
|
height: root.opticalSize
|
||||||
|
|
||||||
|
OpticalGlyph {
|
||||||
|
id: glyph
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: root.iconComponent === null
|
||||||
|
text: root.text
|
||||||
|
fontFamily: root.fontFamily
|
||||||
|
fontSize: root.fontSize
|
||||||
|
color: root.active && root.useActiveColor ? root.activeColor : root.foreground
|
||||||
|
rotation: root.textRotation
|
||||||
|
debugBounds: root.debugOpticalBounds
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: root.iconComponent !== null
|
||||||
|
sourceComponent: root.iconComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
visible: root.debugOpticalBounds && root.iconComponent !== null
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "transparent"
|
||||||
|
border.width: 1
|
||||||
|
border.color: "#4488ff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
visible: root.debugOpticalBounds
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "transparent"
|
||||||
|
border.width: 1
|
||||||
|
border.color: "#ff4455"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import QtQuick
|
||||||
|
import qs.Commons
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string text: ""
|
||||||
|
property string fontFamily: Style.font.family
|
||||||
|
property real fontSize: Style.font.body
|
||||||
|
property color color: Color.foreground
|
||||||
|
property real targetExtent: Math.min(width, height) * 0.82
|
||||||
|
property bool debugBounds: false
|
||||||
|
|
||||||
|
readonly property real baseTightWidth: Math.max(1, baseMetrics.tightBoundingRect.width)
|
||||||
|
readonly property real baseTightHeight: Math.max(1, baseMetrics.tightBoundingRect.height)
|
||||||
|
readonly property real normalizedScale: Math.min(1.5, targetExtent / Math.max(baseTightWidth, baseTightHeight))
|
||||||
|
readonly property int normalizedFontSize: Math.max(1, Math.round(fontSize * normalizedScale))
|
||||||
|
readonly property real tightWidth: Math.max(1, glyphMetrics.tightBoundingRect.width)
|
||||||
|
readonly property real tightHeight: Math.max(1, glyphMetrics.tightBoundingRect.height)
|
||||||
|
readonly property real horizontalCorrection: glyph.implicitWidth / 2 - (glyphMetrics.tightBoundingRect.x + tightWidth / 2)
|
||||||
|
readonly property real verticalCorrection: glyph.implicitHeight / 2 - (glyph.baselineOffset + glyphMetrics.tightBoundingRect.y + tightHeight / 2)
|
||||||
|
readonly property real paintedCenterX: glyph.x + glyphMetrics.tightBoundingRect.x + tightWidth / 2
|
||||||
|
readonly property real paintedCenterY: glyph.y + glyph.baselineOffset + glyphMetrics.tightBoundingRect.y + tightHeight / 2
|
||||||
|
|
||||||
|
TextMetrics {
|
||||||
|
id: baseMetrics
|
||||||
|
font.family: root.fontFamily
|
||||||
|
font.pixelSize: root.fontSize
|
||||||
|
text: root.text
|
||||||
|
}
|
||||||
|
|
||||||
|
TextMetrics {
|
||||||
|
id: glyphMetrics
|
||||||
|
font.family: root.fontFamily
|
||||||
|
font.pixelSize: root.normalizedFontSize
|
||||||
|
text: root.text
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: glyph
|
||||||
|
anchors.centerIn: parent
|
||||||
|
anchors.horizontalCenterOffset: root.horizontalCorrection
|
||||||
|
anchors.verticalCenterOffset: root.verticalCorrection
|
||||||
|
text: root.text
|
||||||
|
color: root.color
|
||||||
|
font.family: root.fontFamily
|
||||||
|
font.pixelSize: root.normalizedFontSize
|
||||||
|
renderType: Text.NativeRendering
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
visible: root.debugBounds
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "transparent"
|
||||||
|
border.width: 1
|
||||||
|
border.color: "#4488ff"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,6 @@ Item {
|
|||||||
property color activeColor: bar ? bar.urgent : Color.urgent
|
property color activeColor: bar ? bar.urgent : Color.urgent
|
||||||
property bool active: false
|
property bool active: false
|
||||||
property real horizontalMargin: 8.5
|
property real horizontalMargin: 8.5
|
||||||
property real rightExtraMargin: 0
|
|
||||||
property real verticalPadding: 6
|
property real verticalPadding: 6
|
||||||
property real fixedWidth: -1
|
property real fixedWidth: -1
|
||||||
property real fixedHeight: -1
|
property real fixedHeight: -1
|
||||||
@@ -24,6 +23,8 @@ Item {
|
|||||||
property bool pressable: true
|
property bool pressable: true
|
||||||
property bool useActiveColor: true
|
property bool useActiveColor: true
|
||||||
property bool maintainIndicatorReveal: false
|
property bool maintainIndicatorReveal: false
|
||||||
|
property bool labelVisible: true
|
||||||
|
property bool hasVisualContent: text !== ""
|
||||||
property var revealHost: bar
|
property var revealHost: bar
|
||||||
property string tooltipText: ""
|
property string tooltipText: ""
|
||||||
property var registeredBar: null
|
property var registeredBar: null
|
||||||
@@ -56,13 +57,12 @@ Item {
|
|||||||
readonly property bool vertical: bar ? bar.vertical : false
|
readonly property bool vertical: bar ? bar.vertical : false
|
||||||
readonly property int barSize: bar ? bar.barSize : Style.bar.sizeHorizontal
|
readonly property int barSize: bar ? bar.barSize : Style.bar.sizeHorizontal
|
||||||
readonly property real scaledHorizontalMargin: Style.spaceReal(horizontalMargin)
|
readonly property real scaledHorizontalMargin: Style.spaceReal(horizontalMargin)
|
||||||
readonly property real scaledRightExtraMargin: Style.spaceReal(rightExtraMargin)
|
|
||||||
readonly property real scaledVerticalPadding: Style.spaceReal(verticalPadding)
|
readonly property real scaledVerticalPadding: Style.spaceReal(verticalPadding)
|
||||||
readonly property bool tooltipHovered: visible && interactive && !concealed && mouseArea.containsMouse
|
readonly property bool tooltipHovered: visible && interactive && !concealed && mouseArea.containsMouse
|
||||||
|
|
||||||
visible: text !== "" || keepSpace
|
visible: hasVisualContent || keepSpace
|
||||||
opacity: text === "" || concealed ? 0 : (dimmed ? 0.45 : 1)
|
opacity: !hasVisualContent || concealed ? 0 : (dimmed ? 0.45 : 1)
|
||||||
implicitWidth: fixedWidth > 0 ? fixedWidth : (vertical ? barSize : Math.max(12, label.implicitWidth + scaledHorizontalMargin * 2 + scaledRightExtraMargin))
|
implicitWidth: fixedWidth > 0 ? fixedWidth : (vertical ? barSize : Math.max(12, label.implicitWidth + scaledHorizontalMargin * 2))
|
||||||
implicitHeight: fixedHeight > 0 ? fixedHeight : (vertical ? Math.max(12, label.implicitHeight + scaledVerticalPadding * 2) : barSize)
|
implicitHeight: fixedHeight > 0 ? fixedHeight : (vertical ? Math.max(12, label.implicitHeight + scaledVerticalPadding * 2) : barSize)
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
@@ -71,8 +71,8 @@ Item {
|
|||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: label
|
id: label
|
||||||
|
visible: root.labelVisible
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
anchors.horizontalCenterOffset: root.vertical ? 0 : -root.scaledRightExtraMargin / 2
|
|
||||||
text: root.text
|
text: root.text
|
||||||
color: root.active && root.useActiveColor ? root.activeColor : root.foreground
|
color: root.active && root.useActiveColor ? root.activeColor : root.foreground
|
||||||
font.family: root.fontFamily
|
font.family: root.fontFamily
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
module qs.Ui
|
module qs.Ui
|
||||||
|
|
||||||
BarIndicator 1.0 BarIndicator.qml
|
BarIndicator 1.0 BarIndicator.qml
|
||||||
|
BarIconButton 1.0 BarIconButton.qml
|
||||||
BarWidget 1.0 BarWidget.qml
|
BarWidget 1.0 BarWidget.qml
|
||||||
BorderOverlay 1.0 BorderOverlay.qml
|
BorderOverlay 1.0 BorderOverlay.qml
|
||||||
BorderSurface 1.0 BorderSurface.qml
|
BorderSurface 1.0 BorderSurface.qml
|
||||||
@@ -12,6 +13,7 @@ Dropdown 1.0 Dropdown.qml
|
|||||||
KeyboardPanel 1.0 KeyboardPanel.qml
|
KeyboardPanel 1.0 KeyboardPanel.qml
|
||||||
MultiSelect 1.0 MultiSelect.qml
|
MultiSelect 1.0 MultiSelect.qml
|
||||||
NumberField 1.0 NumberField.qml
|
NumberField 1.0 NumberField.qml
|
||||||
|
OpticalGlyph 1.0 OpticalGlyph.qml
|
||||||
Panel 1.0 Panel.qml
|
Panel 1.0 Panel.qml
|
||||||
PanelActionButton 1.0 PanelActionButton.qml
|
PanelActionButton 1.0 PanelActionButton.qml
|
||||||
PanelController 1.0 PanelController.qml
|
PanelController 1.0 PanelController.qml
|
||||||
|
|||||||
@@ -1297,13 +1297,6 @@ Item {
|
|||||||
readonly property bool hovered: moduleHover.hovered
|
readonly property bool hovered: moduleHover.hovered
|
||||||
readonly property bool dragSource: root.barDragSource === slot
|
readonly property bool dragSource: root.barDragSource === slot
|
||||||
readonly property bool panelOpen: root.activePopout === slot.activeItem
|
readonly property bool panelOpen: root.activePopout === slot.activeItem
|
||||||
readonly property real openIndicatorInlineOffset: {
|
|
||||||
var item = slot.activeItem
|
|
||||||
if (!item || !("openIndicatorInlineOffset" in item)) return 0
|
|
||||||
var offset = Number(item.openIndicatorInlineOffset)
|
|
||||||
return isFinite(offset) ? offset : 0
|
|
||||||
}
|
|
||||||
|
|
||||||
implicitWidth: activeItem && activeItem.visible ? (root.vertical ? root.barSize : activeItem.implicitWidth) : 0
|
implicitWidth: activeItem && activeItem.visible ? (root.vertical ? root.barSize : activeItem.implicitWidth) : 0
|
||||||
implicitHeight: activeItem && activeItem.visible ? activeItem.implicitHeight : 0
|
implicitHeight: activeItem && activeItem.visible ? activeItem.implicitHeight : 0
|
||||||
width: implicitWidth
|
width: implicitWidth
|
||||||
@@ -1377,9 +1370,9 @@ Item {
|
|||||||
height: root.vertical ? Math.max(Style.space(10), Math.round(parent.height * 0.55)) : Style.space(2)
|
height: root.vertical ? Math.max(Style.space(10), Math.round(parent.height * 0.55)) : Style.space(2)
|
||||||
x: root.vertical
|
x: root.vertical
|
||||||
? (root.position === "left" ? parent.width - width - inset : inset)
|
? (root.position === "left" ? parent.width - width - inset : inset)
|
||||||
: (slot.openIndicatorInlineOffset === 0 ? Math.round((parent.width - width) / 2) : (parent.width - width) / 2 + slot.openIndicatorInlineOffset)
|
: Math.round((parent.width - width) / 2)
|
||||||
y: root.vertical
|
y: root.vertical
|
||||||
? (slot.openIndicatorInlineOffset === 0 ? Math.round((parent.height - height) / 2) : (parent.height - height) / 2 + slot.openIndicatorInlineOffset)
|
? Math.round((parent.height - height) / 2)
|
||||||
: (root.position === "top" ? parent.height - height - inset : inset)
|
: (root.position === "top" ? parent.height - height - inset : inset)
|
||||||
z: 50
|
z: 50
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ BarWidget {
|
|||||||
|
|
||||||
PwObjectTracker { objects: root.source ? [root.source] : [] }
|
PwObjectTracker { objects: root.source ? [root.source] : [] }
|
||||||
|
|
||||||
WidgetButton {
|
BarIconButton {
|
||||||
id: button
|
id: button
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
bar: root.bar
|
bar: root.bar
|
||||||
|
|||||||
@@ -52,12 +52,11 @@ BarWidget {
|
|||||||
onTriggered: root.refresh()
|
onTriggered: root.refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetButton {
|
BarIconButton {
|
||||||
id: button
|
id: button
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
bar: root.bar
|
bar: root.bar
|
||||||
text: "\uf021"
|
text: "\uf021"
|
||||||
fontSize: Style.font.caption
|
|
||||||
tooltipText: ""
|
tooltipText: ""
|
||||||
onPressed: root.runUpdate()
|
onPressed: root.runUpdate()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ BarWidget {
|
|||||||
readonly property var drawerItems: bucket("drawer")
|
readonly property var drawerItems: bucket("drawer")
|
||||||
readonly property var allItems: bucket("all")
|
readonly property var allItems: bucket("all")
|
||||||
readonly property int drawerCount: drawerItems.length
|
readonly property int drawerCount: drawerItems.length
|
||||||
readonly property int trayItemExtent: Style.space(16)
|
readonly property int trayItemExtent: Style.bar.iconSlot
|
||||||
readonly property int trayItemGap: Style.space(9)
|
readonly property int trayItemGap: 0
|
||||||
readonly property int trayJoinGap: Style.space(4)
|
readonly property int trayJoinGap: 0
|
||||||
readonly property int drawerExtent: drawerCount > 0 ? drawerCount * trayItemExtent + (drawerCount - 1) * trayItemGap : 0
|
readonly property int drawerExtent: drawerCount > 0 ? drawerCount * trayItemExtent + (drawerCount - 1) * trayItemGap : 0
|
||||||
// Match Waybar's group/tray-expander drawer transition-duration.
|
// Match Waybar's group/tray-expander drawer transition-duration.
|
||||||
readonly property int animationDuration: 600
|
readonly property int animationDuration: 600
|
||||||
@@ -182,15 +182,13 @@ BarWidget {
|
|||||||
onHoveredChanged: root.expanded = hovered
|
onHoveredChanged: root.expanded = hovered
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetButton {
|
BarIconButton {
|
||||||
id: expandIcon
|
id: expandIcon
|
||||||
bar: root.bar
|
bar: root.bar
|
||||||
width: implicitWidth
|
width: implicitWidth
|
||||||
height: implicitHeight
|
height: implicitHeight
|
||||||
x: root.drawerExtent - root.revealExtent
|
x: root.drawerExtent - root.revealExtent
|
||||||
text: "\uf053"
|
text: "\uf053"
|
||||||
horizontalMargin: 9
|
|
||||||
verticalPadding: 6
|
|
||||||
onPressed: function(button) {
|
onPressed: function(button) {
|
||||||
if (button === Qt.RightButton) root.managePopupOpen = !root.managePopupOpen
|
if (button === Qt.RightButton) root.managePopupOpen = !root.managePopupOpen
|
||||||
}
|
}
|
||||||
@@ -266,7 +264,7 @@ BarWidget {
|
|||||||
onHoveredChanged: root.expanded = hovered
|
onHoveredChanged: root.expanded = hovered
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetButton {
|
BarIconButton {
|
||||||
id: expandIcon
|
id: expandIcon
|
||||||
bar: root.bar
|
bar: root.bar
|
||||||
width: implicitWidth
|
width: implicitWidth
|
||||||
@@ -274,8 +272,6 @@ BarWidget {
|
|||||||
y: root.drawerExtent - root.revealExtent
|
y: root.drawerExtent - root.revealExtent
|
||||||
text: "\uf053"
|
text: "\uf053"
|
||||||
textRotation: 90
|
textRotation: 90
|
||||||
horizontalMargin: 9
|
|
||||||
verticalPadding: 6
|
|
||||||
onPressed: function(button) {
|
onPressed: function(button) {
|
||||||
if (button === Qt.RightButton) root.managePopupOpen = !root.managePopupOpen
|
if (button === Qt.RightButton) root.managePopupOpen = !root.managePopupOpen
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -522,14 +522,11 @@ Panel {
|
|||||||
onTriggered: root.refreshDisplayAudioModels()
|
onTriggered: root.refreshDisplayAudioModels()
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetButton {
|
BarIconButton {
|
||||||
id: button
|
id: button
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
bar: root.bar
|
bar: root.bar
|
||||||
text: root.outputIcon()
|
text: root.outputIcon()
|
||||||
fontSize: Style.font.body
|
|
||||||
fixedWidth: root.bar && root.bar.vertical ? -1 : Style.space(27)
|
|
||||||
fixedHeight: root.bar && root.bar.vertical ? Style.space(26) : -1
|
|
||||||
onPressed: function(b) {
|
onPressed: function(b) {
|
||||||
if (b === Qt.RightButton) root.toggleOutputMute()
|
if (b === Qt.RightButton) root.toggleOutputMute()
|
||||||
else root.toggle()
|
else root.toggle()
|
||||||
|
|||||||
@@ -469,13 +469,11 @@ Panel {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetButton {
|
BarIconButton {
|
||||||
id: button
|
id: button
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
bar: root.bar
|
bar: root.bar
|
||||||
text: root.icon
|
text: root.icon
|
||||||
fixedWidth: root.bar && root.bar.vertical ? -1 : Style.space(27)
|
|
||||||
fixedHeight: root.bar && root.bar.vertical ? Style.space(26) : -1
|
|
||||||
onPressed: function(b) {
|
onPressed: function(b) {
|
||||||
if (b === Qt.RightButton) root.toggleBluetooth()
|
if (b === Qt.RightButton) root.toggleBluetooth()
|
||||||
else if (b === Qt.MiddleButton) root.bar.run("omarchy-launch-bluetooth")
|
else if (b === Qt.MiddleButton) root.bar.run("omarchy-launch-bluetooth")
|
||||||
|
|||||||
@@ -139,48 +139,25 @@ Panel {
|
|||||||
function status(): string { return dropbox.statusText }
|
function status(): string { return dropbox.statusText }
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
BarIconButton {
|
||||||
id: button
|
id: button
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
implicitWidth: root.bar && root.bar.vertical ? root.bar.barSize : Style.space(27)
|
bar: root.bar
|
||||||
implicitHeight: root.bar && root.bar.vertical ? Style.space(26) : (root.bar ? root.bar.barSize : Style.space(26))
|
iconComponent: Component {
|
||||||
|
Item {
|
||||||
property var registeredBar: null
|
DropboxIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
function triggerPress(buttonCode) {
|
iconSize: Style.space(12)
|
||||||
|
color: root.barIconColor
|
||||||
|
opacity: dropbox.authenticated ? 1.0 : 0.6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onPressed: function(buttonCode) {
|
||||||
if (buttonCode === Qt.RightButton) dropbox.refresh()
|
if (buttonCode === Qt.RightButton) dropbox.refresh()
|
||||||
else if (buttonCode === Qt.MiddleButton) dropbox.login()
|
else if (buttonCode === Qt.MiddleButton) dropbox.login()
|
||||||
else root.toggle()
|
else root.toggle()
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncClickRegistration() {
|
|
||||||
if (registeredBar && registeredBar.unregisterClickTarget) registeredBar.unregisterClickTarget(button)
|
|
||||||
registeredBar = root.bar
|
|
||||||
if (registeredBar && registeredBar.registerClickTarget) registeredBar.registerClickTarget(button)
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: syncClickRegistration()
|
|
||||||
Component.onDestruction: if (registeredBar && registeredBar.unregisterClickTarget) registeredBar.unregisterClickTarget(button)
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
function onBarChanged() { button.syncClickRegistration() }
|
|
||||||
}
|
|
||||||
|
|
||||||
DropboxIcon {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
iconSize: Style.space(12)
|
|
||||||
color: root.barIconColor
|
|
||||||
opacity: dropbox.authenticated ? 1.0 : 0.6
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: function(mouse) { button.triggerPress(mouse.button) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardPanel {
|
KeyboardPanel {
|
||||||
|
|||||||
@@ -337,15 +337,11 @@ Panel {
|
|||||||
onRunningChanged: if (!running) root.refresh()
|
onRunningChanged: if (!running) root.refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetButton {
|
BarIconButton {
|
||||||
id: button
|
id: button
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
bar: root.bar
|
bar: root.bar
|
||||||
text: root.displays.length > 1 ? "" : ""
|
text: root.displays.length > 1 ? "" : ""
|
||||||
fontSize: Style.font.subtitle
|
|
||||||
fixedWidth: root.bar && root.bar.vertical ? -1 : Style.space(27)
|
|
||||||
fixedHeight: root.bar && root.bar.vertical ? Style.space(26) : -1
|
|
||||||
rightExtraMargin: 4
|
|
||||||
onPressed: function(b) { root.toggle() }
|
onPressed: function(b) { root.toggle() }
|
||||||
onWheelMoved: function(delta) {
|
onWheelMoved: function(delta) {
|
||||||
if (root.brightnessAvailable) root.setBrightness(root.brightnessPercent + (delta > 0 ? 5 : -5))
|
if (root.brightnessAvailable) root.setBrightness(root.brightnessPercent + (delta > 0 ? 5 : -5))
|
||||||
|
|||||||
@@ -707,14 +707,11 @@ Panel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetButton {
|
BarIconButton {
|
||||||
id: button
|
id: button
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
bar: root.bar
|
bar: root.bar
|
||||||
text: root.icon
|
text: root.icon
|
||||||
fixedWidth: root.bar && root.bar.vertical ? -1 : Style.space(27)
|
|
||||||
fixedHeight: root.bar && root.bar.vertical ? Style.space(26) : -1
|
|
||||||
rightExtraMargin: 5.5
|
|
||||||
|
|
||||||
onPressed: function(b) {
|
onPressed: function(b) {
|
||||||
if (root.opened) root.close()
|
if (root.opened) root.close()
|
||||||
|
|||||||
@@ -249,13 +249,11 @@ Panel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetButton {
|
BarIconButton {
|
||||||
id: button
|
id: button
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
bar: root.bar
|
bar: root.bar
|
||||||
text: root.batteryIcon()
|
text: root.batteryIcon()
|
||||||
fixedWidth: root.bar && root.bar.vertical ? -1 : Style.space(27)
|
|
||||||
fixedHeight: root.bar && root.bar.vertical ? Style.space(26) : -1
|
|
||||||
tooltipText: ""
|
tooltipText: ""
|
||||||
onPressed: function(b) { if (root.batteryPresent) root.toggle() }
|
onPressed: function(b) { if (root.batteryPresent) root.toggle() }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ Panel {
|
|||||||
ipcTarget: "omarchy.tailscale"
|
ipcTarget: "omarchy.tailscale"
|
||||||
manageIpc: false
|
manageIpc: false
|
||||||
|
|
||||||
readonly property real openIndicatorInlineOffset: bar && bar.vertical ? 0 : Style.spaceReal(1.5)
|
|
||||||
property string focusSection: "header"
|
property string focusSection: "header"
|
||||||
property int headerIndex: 0
|
property int headerIndex: 0
|
||||||
property int accountIndex: 0
|
property int accountIndex: 0
|
||||||
@@ -360,53 +359,27 @@ Panel {
|
|||||||
function status(): string { return tailscale.statusText }
|
function status(): string { return tailscale.statusText }
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
BarIconButton {
|
||||||
id: button
|
id: button
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
implicitWidth: root.bar && root.bar.vertical ? root.bar.barSize : Style.space(27)
|
bar: root.bar
|
||||||
implicitHeight: root.bar && root.bar.vertical ? Style.space(26) : (root.bar ? root.bar.barSize : Style.space(26))
|
iconComponent: Component {
|
||||||
|
Item {
|
||||||
property var registeredBar: null
|
TailscaleIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
function triggerPress(buttonCode) {
|
iconSize: Style.space(11)
|
||||||
|
color: root.barIconColor
|
||||||
|
badgeColor: root.urgent
|
||||||
|
crossed: !tailscale.running && !tailscale.needsLogin
|
||||||
|
warning: tailscale.needsLogin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onPressed: function(buttonCode) {
|
||||||
if (buttonCode === Qt.RightButton) tailscale.toggleTailscale()
|
if (buttonCode === Qt.RightButton) tailscale.toggleTailscale()
|
||||||
else if (buttonCode === Qt.MiddleButton) tailscale.refresh()
|
else if (buttonCode === Qt.MiddleButton) tailscale.refresh()
|
||||||
else root.toggle()
|
else root.toggle()
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncClickRegistration() {
|
|
||||||
if (registeredBar && registeredBar.unregisterClickTarget) registeredBar.unregisterClickTarget(button)
|
|
||||||
registeredBar = root.bar
|
|
||||||
if (registeredBar && registeredBar.registerClickTarget) registeredBar.registerClickTarget(button)
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: syncClickRegistration()
|
|
||||||
Component.onDestruction: if (registeredBar && registeredBar.unregisterClickTarget) registeredBar.unregisterClickTarget(button)
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
function onBarChanged() { button.syncClickRegistration() }
|
|
||||||
}
|
|
||||||
|
|
||||||
TailscaleIcon {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
anchors.horizontalCenterOffset: root.openIndicatorInlineOffset
|
|
||||||
anchors.verticalCenterOffset: -Style.space(1)
|
|
||||||
iconSize: Style.space(12) * 0.85
|
|
||||||
color: root.barIconColor
|
|
||||||
badgeColor: root.urgent
|
|
||||||
crossed: !tailscale.running && !tailscale.needsLogin
|
|
||||||
warning: tailscale.needsLogin
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: mouseArea
|
|
||||||
anchors.fill: parent
|
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: function(mouse) { button.triggerPress(mouse.button) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardPanel {
|
KeyboardPanel {
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||||
|
|
||||||
|
if ! command -v quickshell >/dev/null 2>&1; then
|
||||||
|
pass "quickshell not installed; skipping bar icon geometry test"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
test_tmp=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$test_tmp"' EXIT
|
||||||
|
|
||||||
|
ln -s "$ROOT/shell/Ui" "$test_tmp/Ui"
|
||||||
|
ln -s "$ROOT/shell/Commons" "$test_tmp/Commons"
|
||||||
|
|
||||||
|
cat >"$test_tmp/shell.qml" <<'QML'
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import qs.Commons
|
||||||
|
import qs.Ui
|
||||||
|
|
||||||
|
ShellRoot {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
function fail(message) {
|
||||||
|
console.log("RESULT fail " + message)
|
||||||
|
Qt.quit()
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkIcon(icon, name) {
|
||||||
|
if (icon.implicitWidth !== Style.bar.iconSlot) {
|
||||||
|
fail(name + " slot width is " + icon.implicitWidth)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (icon.opticalSize !== Style.bar.iconCanvas) {
|
||||||
|
fail(name + " optical canvas is " + icon.opticalSize)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (Math.abs(icon.opticalCenterErrorX) > 0.5 || Math.abs(icon.opticalCenterErrorY) > 0.5) {
|
||||||
|
fail(name + " painted bounds are over half a pixel off center by " + icon.opticalCenterErrorX + "," + icon.opticalCenterErrorY)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: Qt.callLater(function() {
|
||||||
|
if (!checkIcon(bluetooth, "bluetooth")) return
|
||||||
|
if (!checkIcon(network, "network")) return
|
||||||
|
if (!checkIcon(audio, "audio")) return
|
||||||
|
if (!checkIcon(monitor, "monitor")) return
|
||||||
|
if (!checkIcon(power, "power")) return
|
||||||
|
if (vector.implicitWidth !== Style.bar.iconSlot || vector.opticalSize !== Style.bar.iconCanvas) {
|
||||||
|
fail("vector icon does not share glyph geometry")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log("RESULT pass")
|
||||||
|
Qt.quit()
|
||||||
|
})
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: testBar
|
||||||
|
property bool vertical: false
|
||||||
|
property int barSize: Style.bar.sizeHorizontal
|
||||||
|
property string fontFamily: Style.font.family
|
||||||
|
property color barForeground: "white"
|
||||||
|
property color urgent: "red"
|
||||||
|
property bool foregroundAnimationEnabled: false
|
||||||
|
function registerClickTarget(target) {}
|
||||||
|
function unregisterClickTarget(target) {}
|
||||||
|
function hideTooltip(target) {}
|
||||||
|
function showTooltip(target, text) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
BarIconButton { id: bluetooth; bar: testBar; text: "" }
|
||||||
|
BarIconButton { id: network; bar: testBar; text: "" }
|
||||||
|
BarIconButton { id: audio; bar: testBar; text: "" }
|
||||||
|
BarIconButton { id: monitor; bar: testBar; text: "" }
|
||||||
|
BarIconButton { id: power; bar: testBar; text: "" }
|
||||||
|
BarIconButton {
|
||||||
|
id: vector
|
||||||
|
bar: testBar
|
||||||
|
iconComponent: Component { Rectangle { width: 12; height: 12 } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QML
|
||||||
|
|
||||||
|
output=$(timeout 15 env \
|
||||||
|
QML2_IMPORT_PATH="$ROOT/shell${QML2_IMPORT_PATH:+:$QML2_IMPORT_PATH}" \
|
||||||
|
QML_IMPORT_PATH="$ROOT/shell${QML_IMPORT_PATH:+:$QML_IMPORT_PATH}" \
|
||||||
|
quickshell -p "$test_tmp" --no-color 2>&1) || {
|
||||||
|
printf '%s\n' "$output" >&2
|
||||||
|
fail "bar icon geometry fixture exits cleanly"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ! grep -q 'RESULT pass' <<<"$output"; then
|
||||||
|
printf '%s\n' "$output" >&2
|
||||||
|
fail "bar icons share centered optical geometry"
|
||||||
|
fi
|
||||||
|
|
||||||
|
pass "bar icons share centered optical geometry"
|
||||||
Reference in New Issue
Block a user