diff --git a/Modules/Bar/Bar.qml b/Modules/Bar/Bar.qml index 47ee604..6887f68 100644 --- a/Modules/Bar/Bar.qml +++ b/Modules/Bar/Bar.qml @@ -31,18 +31,37 @@ PanelWindow { layer.enabled: true } + // Testing widgets RowLayout { - // Just testing + NToggle { label: "Label" description: "Description" + onToggled: function(value: bool) { + console.log("NToggle: " + value) + } } NIconButton { + id: myIconButton icon: "refresh" + onEntered: function() { + myTooltip.tooltipVisible = true; + } + onExited: function() { + myTooltip.tooltipVisible = false; + } + } + NTooltip { + id: myTooltip + targetItem: myIconButton + positionAbove: false + text: "Hello world" } NSlider {} + + } } } diff --git a/Widgets/NIconButton.qml b/Widgets/NIconButton.qml index 41fafbf..70d475b 100644 --- a/Widgets/NIconButton.qml +++ b/Widgets/NIconButton.qml @@ -12,6 +12,8 @@ Rectangle { property string icon property bool enabled: true property bool hovering: false + property var onEntered: function () {} + property var onExited: function () {} implicitWidth: size implicitHeight: size @@ -35,7 +37,13 @@ Rectangle { anchors.fill: parent cursorShape: Qt.PointingHandCursor hoverEnabled: true - onEntered: hovering = true - onExited: hovering = false + onEntered: { + hovering = true + root.onEntered() + } + onExited: { + hovering = false + root.onExited() + } } } diff --git a/Widgets/NTooltip.qml b/Widgets/NTooltip.qml new file mode 100644 index 0000000..3f74281 --- /dev/null +++ b/Widgets/NTooltip.qml @@ -0,0 +1,129 @@ +import QtQuick +import QtQuick.Window 2.15 +import qs.Services +import qs.Theme + +Window { + id: tooltipWindow + + readonly property real scaling: Scaling.scale(screen) + property string text: "" + property bool tooltipVisible: false + property Item targetItem: null + property int delay: 300 + property bool positionAbove: true + + flags: Qt.ToolTip | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint + color: "transparent" + visible: false + + property var _timerObj: null + + onTooltipVisibleChanged: { + if (tooltipVisible) { + if (delay > 0) { + if (_timerObj) { + _timerObj.destroy() + _timerObj = null + } + _timerObj = Qt.createQmlObject( + 'import QtQuick 2.0; Timer { interval: ' + delay + + '; running: true; repeat: false; onTriggered: tooltipWindow._showNow() }', + tooltipWindow) + } else { + _showNow() + } + } else { + _hideNow() + } + } + + function _showNow() { + + width = Math.max(50 * scaling, tooltipText.implicitWidth + 24 * scaling) + height = Math.max(50 * scaling, tooltipText.implicitHeight + 16 * scaling) + + if (!targetItem) + return + + if (positionAbove) { + // Position tooltip above the target item + var pos = targetItem.mapToGlobal(0, 0) + x = pos.x - width / 2 + targetItem.width / 2 + y = pos.y - height - 12 // 12 px margin above + } else { + // Position tooltip below the target item + var pos = targetItem.mapToGlobal(0, targetItem.height) + x = pos.x - width / 2 + targetItem.width / 2 + y = pos.y + 12 // 12 px margin below + } + visible = true + } + + function _hideNow() { + visible = false + if (_timerObj) { + _timerObj.destroy() + _timerObj = null + } + } + + Connections { + target: tooltipWindow.targetItem + function onXChanged() { + if (tooltipWindow.visible) + tooltipWindow._showNow() + } + function onYChanged() { + if (tooltipWindow.visible) + tooltipWindow._showNow() + } + function onWidthChanged() { + if (tooltipWindow.visible) + tooltipWindow._showNow() + } + function onHeightChanged() { + if (tooltipWindow.visible) + tooltipWindow._showNow() + } + } + + Rectangle { + anchors.fill: parent + radius: 18 + color: Theme.backgroundTertiary || "#222" + border.color: Theme.outline || "#444" + border.width: 1 * scaling + opacity: 0.97 + z: 1 + } + + Text { + id: tooltipText + text: tooltipWindow.text + color: Theme.textPrimary + font.family: Theme.fontFamily + font.pixelSize: Theme.fontSizeSmall * scaling + anchors.centerIn: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Text.Wrap + padding: 8 + z: 2 + } + + MouseArea { + anchors.fill: parent + cursorShape: Qt.ArrowCursor + hoverEnabled: true + onExited: tooltipWindow.tooltipVisible = false + + } + + onTextChanged: { + width = Math.max(minimumWidth * scaling, + tooltipText.implicitWidth + 24 * scaling) + height = Math.max(minimumHeight * scaling, + tooltipText.implicitHeight + 16 * scaling) + } +}