Add focused window controls to top bar
Introduces a new `WindowControls` component in the desktop top bar with minimize, maximize/restore, and close actions for the focused window. `WindowService` now exposes focused-window presence/maximized state plus focused-window convenience actions to support this UI. Also extends Nebula UI with a reusable `NebulaToolTip`, keyboard/pressed-state support in `NebulaIconButton`, new window-control glyphs in `NebulaIcon`, and theme tokens for pressed/danger hover states, with CMake and README updates to register/document the new components.
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string text: ""
|
||||
property bool active: false
|
||||
property int delay: 550
|
||||
property int timeout: 4000
|
||||
|
||||
width: 0
|
||||
height: 0
|
||||
enabled: false
|
||||
Accessible.ignored: true
|
||||
|
||||
Timer {
|
||||
id: showTimer
|
||||
interval: root.delay
|
||||
repeat: false
|
||||
onTriggered: root.open()
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: hideTimer
|
||||
interval: root.timeout
|
||||
repeat: false
|
||||
onTriggered: tip.visible = false
|
||||
}
|
||||
|
||||
Window {
|
||||
id: tip
|
||||
flags: Qt.Popup | Qt.ToolTip | Qt.FramelessWindowHint | Qt.WindowDoesNotAcceptFocus
|
||||
color: "transparent"
|
||||
visible: false
|
||||
width: Math.ceil(tipText.implicitWidth) + 16
|
||||
height: Math.ceil(tipText.implicitHeight) + 10
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: Theme.radiusSmall
|
||||
color: Theme.surfaceRaised
|
||||
border.color: Theme.borderStrong
|
||||
border.width: 1
|
||||
|
||||
Text {
|
||||
id: tipText
|
||||
anchors.centerIn: parent
|
||||
text: root.text
|
||||
color: Theme.textPrimary
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onActiveChanged: root.sync()
|
||||
onTextChanged: {
|
||||
if (tip.visible)
|
||||
root.place()
|
||||
else
|
||||
root.sync()
|
||||
}
|
||||
|
||||
function sync() {
|
||||
if (root.active && root.text.length > 0) {
|
||||
showTimer.restart()
|
||||
return
|
||||
}
|
||||
showTimer.stop()
|
||||
hideTimer.stop()
|
||||
tip.visible = false
|
||||
}
|
||||
|
||||
function open() {
|
||||
if (!root.active || root.text.length === 0)
|
||||
return
|
||||
const host = root.parent
|
||||
if (!host)
|
||||
return
|
||||
const win = host.Window.window
|
||||
if (win)
|
||||
tip.transientParent = win
|
||||
root.place()
|
||||
tip.visible = true
|
||||
hideTimer.restart()
|
||||
}
|
||||
|
||||
function place() {
|
||||
const host = root.parent
|
||||
if (!host)
|
||||
return
|
||||
const pos = host.mapToGlobal(host.width / 2, host.height + 6)
|
||||
const screenWidth = Screen.width
|
||||
tip.x = Math.round(Math.max(8, Math.min(pos.x - tip.width / 2, screenWidth - tip.width - 8)))
|
||||
tip.y = Math.round(pos.y)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user