diff --git a/qt6/src/qml/AlertToolTip.qml b/qt6/src/qml/AlertToolTip.qml index 400e82c4b..d749ba986 100644 --- a/qt6/src/qml/AlertToolTip.qml +++ b/qt6/src/qml/AlertToolTip.qml @@ -6,31 +6,98 @@ import QtQuick import org.deepin.dtk 1.0 as D import org.deepin.dtk.style 1.0 as DS -ToolTip { +// AlertToolTip is implemented with Control (not Popup) so it stays in the visual +// tree, scrolls with content and gets clipped properly. Enter/exit animation +// is driven by the visible state. +Control { id: control property Item target + property string text + property alias font: contentText.font + property int timeout: 0 x: 0 - y: target ? target.height + DS.Style.control.spacing : 0 + y: _displayY + z: D.DTK.TopOrder + topPadding: DS.Style.alertToolTip.verticalPadding bottomPadding: DS.Style.alertToolTip.verticalPadding leftPadding: DS.Style.alertToolTip.horizontalPadding rightPadding: DS.Style.alertToolTip.horizontalPadding - implicitWidth: Math.min(DS.Style.control.implicitWidth(control), target.width) - implicitHeight: DS.Style.control.implicitHeight(control) - margins: 0 - closePolicy: Popup.NoAutoClose - background: FloatingPanel { - radius: DS.Style.alertToolTip.radius + readonly property real __naturalWidth: Math.max(DS.Style.alertToolTip.width, + contentText.implicitWidth + DS.Style.alertToolTip.horizontalPadding * 2) + implicitWidth: target ? Math.min(__naturalWidth, target.width) : __naturalWidth + implicitHeight: Math.max(DS.Style.alertToolTip.height, + contentText.implicitHeight + DS.Style.alertToolTip.verticalPadding * 2) + width: implicitWidth + height: implicitHeight + + // Animated y so tip stays attached to target; enter = from below target to final, exit = back. + property real _displayY: target ? target.height : 0 + function _updateDisplayY() { + if (target) { + if (visible) + _displayY = target.height + DS.Style.control.spacing + else + _displayY = target.height + } + } + onVisibleChanged: _updateDisplayY() + onTargetChanged: _updateDisplayY() + Connections { + target: control.target + function onHeightChanged() { control._updateDisplayY() } + } + Component.onCompleted: _updateDisplayY() + Behavior on _displayY { + NumberAnimation { duration: 200 } + } + + Timer { + interval: control.timeout + running: control.timeout > 0 && control.visible + onTriggered: control.visible = false + } + + background: Item { implicitWidth: DS.Style.alertToolTip.width implicitHeight: DS.Style.alertToolTip.height - backgroundColor: DS.Style.alertToolTip.background - insideBorderColor: DS.Style.alertToolTip.insideBorder - outsideBorderColor: DS.Style.alertToolTip.outsideBorder + + FloatingPanel { + anchors.fill: parent + radius: DS.Style.alertToolTip.radius + implicitWidth: DS.Style.alertToolTip.width + implicitHeight: DS.Style.alertToolTip.height + backgroundColor: DS.Style.alertToolTip.background + insideBorderColor: DS.Style.alertToolTip.insideBorder + outsideBorderColor: DS.Style.alertToolTip.outsideBorder + } + + BoxShadow { + id: connector + property D.Palette dropShadowColor: DS.Style.alertToolTip.connecterdropShadow + property D.Palette backgroundColor: DS.Style.alertToolTip.connecterBackground + property D.Palette borderColor: DS.Style.control.border + y: -height * 0.75 + width: DS.Style.alertToolTip.connectorWidth + height: DS.Style.alertToolTip.connectorHeight + shadowBlur: 4 + shadowOffsetY: 2 + shadowColor: D.ColorSelector.dropShadowColor + cornerRadius: DS.Style.control.radius + + Rectangle { + anchors.fill: parent + color: connector.D.ColorSelector.backgroundColor + border.color: connector.D.ColorSelector.borderColor + border.width: 1 + } + } } contentItem: Text { + id: contentText property D.Palette textColor: DS.Style.alertToolTip.text horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter @@ -39,36 +106,4 @@ ToolTip { color: D.ColorSelector.textColor wrapMode: Text.Wrap } - - enter: Transition { - // TODO: Transparency causes tooltips to appear through the window background - temporarily removed - // NumberAnimation { properties: "opacity"; from: 0.0; to: 1.0; duration: 200 } - NumberAnimation { properties: "y"; from: control.target.height; to: control.target.height + DS.Style.control.spacing; duration: 200 } - } - - exit: Transition { - // NumberAnimation { properties: "opacity"; from: 1.0; to: 0.0 } - NumberAnimation { properties: "y"; from: control.target.height + DS.Style.control.spacing ; to: control.target.height } - } - - BoxShadow { - id: line - property D.Palette dropShadowColor: DS.Style.alertToolTip.connecterdropShadow - property D.Palette backgroundColor: DS.Style.alertToolTip.connecterBackground - property D.Palette borderColor: DS.Style.control.border - y: - height * (0.75) - control.topMargin - control.topPadding - width: DS.Style.alertToolTip.connectorWidth - height: DS.Style.alertToolTip.connectorHeight - shadowBlur: 4 - shadowOffsetY: 2 - shadowColor: D.ColorSelector.dropShadowColor - cornerRadius: DS.Style.control.radius - - Rectangle { - anchors.fill: parent - color: line.D.ColorSelector.backgroundColor - border.color: line.D.ColorSelector.borderColor - border.width: 1 - } - } }