make buttons ripple

This commit is contained in:
end-4
2025-05-22 19:01:20 +02:00
parent 042a4d1c24
commit 927487c60f
26 changed files with 305 additions and 400 deletions
@@ -7,25 +7,14 @@ import QtQuick.Layouts
import Quickshell import Quickshell
import Quickshell.Io import Quickshell.Io
Button { RippleButton {
id: button id: button
required default property Item content required default property Item content
property bool extraActiveCondition: false property bool extraActiveCondition: false
PointingHandInteraction{}
implicitHeight: Math.max(content.implicitHeight, 26, content.implicitHeight) implicitHeight: Math.max(content.implicitHeight, 26, content.implicitHeight)
implicitWidth: Math.max(content.implicitHeight, 26, content.implicitWidth) implicitWidth: implicitHeight
contentItem: content contentItem: content
background: Rectangle {
anchors.fill: parent
radius: Appearance.rounding.full
color: (button.down || extraActiveCondition) ? Appearance.colors.colLayer1Active :
(button.hovered ? Appearance.colors.colLayer1Hover :
ColorUtils.transparentize(Appearance.colors.colLayer1, 1))
}
} }
@@ -81,11 +81,12 @@ Scope { // Scope
} }
} }
Button { // Close button RippleButton { // Close button
id: closeButton id: closeButton
focus: cheatsheetRoot.visible focus: cheatsheetRoot.visible
implicitWidth: 40 implicitWidth: 40
implicitHeight: 40 implicitHeight: 40
buttonRadius: Appearance.rounding.full
anchors { anchors {
top: parent.top top: parent.top
right: parent.right right: parent.right
@@ -93,28 +94,15 @@ Scope { // Scope
rightMargin: 20 rightMargin: 20
} }
PointingHandInteraction {}
onClicked: { onClicked: {
cheatsheetRoot.hide() cheatsheetRoot.hide()
} }
background: null contentItem: MaterialSymbol {
contentItem: Rectangle { anchors.centerIn: parent
anchors.fill: parent horizontalAlignment: Text.AlignHCenter
radius: Appearance.rounding.full font.pixelSize: Appearance.font.pixelSize.title
color: closeButton.pressed ? Appearance.colors.colLayer0Active : text: "close"
closeButton.hovered ? Appearance.colors.colLayer0Hover :
ColorUtils.transparentize(Appearance.colors.colLayer0, 1)
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
MaterialSymbol {
anchors.centerIn: parent
font.pixelSize: Appearance.font.pixelSize.title
text: "close"
}
} }
} }
@@ -115,7 +115,7 @@ Singleton {
property color colLayer2Disabled: ColorUtils.mix(colLayer2, m3colors.m3background, 0.8); property color colLayer2Disabled: ColorUtils.mix(colLayer2, m3colors.m3background, 0.8);
property color colLayer3Hover: ColorUtils.mix(colLayer3, colOnLayer3, 0.90); property color colLayer3Hover: ColorUtils.mix(colLayer3, colOnLayer3, 0.90);
property color colLayer3Active: ColorUtils.mix(colLayer3, colOnLayer3, 0.80); property color colLayer3Active: ColorUtils.mix(colLayer3, colOnLayer3, 0.80);
property color colPrimaryHover: ColorUtils.mix(m3colors.m3primary, colLayer1Hover, 0.85) property color colPrimaryHover: ColorUtils.mix(m3colors.m3primary, colLayer1Hover, 0.87)
property color colPrimaryActive: ColorUtils.mix(m3colors.m3primary, colLayer1Active, 0.7) property color colPrimaryActive: ColorUtils.mix(m3colors.m3primary, colLayer1Active, 0.7)
property color colPrimaryContainerHover: ColorUtils.mix(m3colors.m3primaryContainer, colLayer1Hover, 0.7) property color colPrimaryContainerHover: ColorUtils.mix(m3colors.m3primaryContainer, colLayer1Hover, 0.7)
property color colPrimaryContainerActive: ColorUtils.mix(m3colors.m3primaryContainer, colLayer1Active, 0.6) property color colPrimaryContainerActive: ColorUtils.mix(m3colors.m3primaryContainer, colLayer1Active, 0.6)
@@ -137,6 +137,7 @@ Singleton {
property int small: 12 property int small: 12
property int normal: 17 property int normal: 17
property int large: 23 property int large: 23
property int verylarge: 30
property int full: 9999 property int full: 9999
property int screenRounding: large property int screenRounding: large
property int windowRounding: 18 property int windowRounding: 18
@@ -147,7 +148,7 @@ Singleton {
property string main: "Rubik" property string main: "Rubik"
property string title: "Gabarito" property string title: "Gabarito"
property string iconMaterial: "Material Symbols Rounded" property string iconMaterial: "Material Symbols Rounded"
property string iconNerd: "JetBrains Mono NF" property string iconNerd: "SpaceMono NF"
property string monospace: "JetBrains Mono NF" property string monospace: "JetBrains Mono NF"
property string reading: "Readex Pro" property string reading: "Readex Pro"
} }
@@ -225,11 +226,16 @@ Singleton {
property int type: Easing.BezierSpline property int type: Easing.BezierSpline
property list<real> bezierCurve: animationCurves.standardDecel property list<real> bezierCurve: animationCurves.standardDecel
property int velocity: 850 property int velocity: 850
property Component colorAnimation: Component {ColorAnimation { property Component colorAnimation: Component { ColorAnimation {
duration: root.animation.elementMoveFast.duration duration: root.animation.elementMoveFast.duration
easing.type: root.animation.elementMoveFast.type easing.type: root.animation.elementMoveFast.type
easing.bezierCurve: root.animation.elementMoveFast.bezierCurve easing.bezierCurve: root.animation.elementMoveFast.bezierCurve
}} }}
property Component numberAnimation: Component { NumberAnimation {
duration: root.animation.elementMoveFast.duration
easing.type: root.animation.elementMoveFast.type
easing.bezierCurve: root.animation.elementMoveFast.bezierCurve
}}
} }
property QtObject scroll: QtObject { property QtObject scroll: QtObject {
property int duration: 400 property int duration: 400
@@ -6,28 +6,13 @@ import QtQuick.Layouts
import Quickshell import Quickshell
import Quickshell.Io import Quickshell.Io
Button { RippleButton {
id: button id: button
property string buttonText property string buttonText
implicitHeight: 30 implicitHeight: 30
implicitWidth: buttonTextWidget.implicitWidth + 15 * 2 implicitWidth: buttonTextWidget.implicitWidth + 15 * 2
buttonRadius: Appearance.rounding.full
PointingHandInteraction {}
background: Rectangle {
anchors.fill: parent
radius: Appearance.rounding.full
color: (button.down && button.enabled) ? Appearance.colors.colLayer1Active :
((button.hovered && button.enabled) ? Appearance.colors.colLayer1Hover :
ColorUtils.transparentize(Appearance.m3colors.m3surfaceContainerHigh, 1))
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
contentItem: StyledText { contentItem: StyledText {
id: buttonTextWidget id: buttonTextWidget
@@ -6,33 +6,19 @@ import QtQuick.Layouts
import Quickshell import Quickshell
import Quickshell.Io import Quickshell.Io
Button { RippleButton {
id: button id: button
property string buttonText buttonRadius: 0
implicitHeight: 36 implicitHeight: 36
implicitWidth: buttonTextWidget.implicitWidth + 14 * 2 implicitWidth: buttonTextWidget.implicitWidth + 14 * 2
PointingHandInteraction {}
background: Rectangle {
anchors.fill: parent
color: (button.down && button.enabled) ? ColorUtils.transparentize(Appearance.m3colors.m3onSurface, 0.84) :
((button.hovered && button.enabled) ? ColorUtils.transparentize(Appearance.m3colors.m3onSurface, 0.92) :
ColorUtils.transparentize(Appearance.m3colors.m3onSurface, 1))
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
contentItem: StyledText { contentItem: StyledText {
id: buttonTextWidget id: buttonTextWidget
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: 14 anchors.leftMargin: 14
anchors.rightMargin: 14 anchors.rightMargin: 14
text: buttonText text: button.buttonText
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
font.pixelSize: Appearance.font.pixelSize.small font.pixelSize: Appearance.font.pixelSize.small
color: button.enabled ? Appearance.m3colors.m3onSurface : Appearance.m3colors.m3outline color: button.enabled ? Appearance.m3colors.m3onSurface : Appearance.m3colors.m3outline
@@ -6,7 +6,7 @@ import QtQuick.Layouts
import Quickshell import Quickshell
import Quickshell.Services.Notifications import Quickshell.Services.Notifications
Button { RippleButton {
id: button id: button
property string buttonText property string buttonText
property string urgency property string urgency
@@ -14,20 +14,10 @@ Button {
implicitHeight: 30 implicitHeight: 30
leftPadding: 15 leftPadding: 15
rightPadding: 15 rightPadding: 15
buttonRadius: Appearance.rounding.small
// PointingHandInteraction {} colBackground: (urgency == NotificationUrgency.Critical) ? Appearance.m3colors.m3secondaryContainer : Appearance.m3colors.m3surfaceContainerHighest
colBackgroundHover: (urgency == NotificationUrgency.Critical) ? Appearance.colors.colSecondaryContainerHover : Appearance.colors.colSurfaceContainerHighestHover
background: Rectangle { colRipple: (urgency == NotificationUrgency.Critical) ? Appearance.colors.colSecondaryContainerActive : Appearance.colors.colSurfaceContainerHighestActive
radius: Appearance.rounding.small
color: (urgency == NotificationUrgency.Critical) ?
(button.down ? Appearance.colors.colSecondaryContainerActive :
button.hovered ? Appearance.colors.colSecondaryContainerHover :
Appearance.m3colors.m3secondaryContainer) :
(button.down ? Appearance.colors.colSurfaceContainerHighestActive :
button.hovered ? Appearance.colors.colSurfaceContainerHighestHover :
Appearance.m3colors.m3surfaceContainerHighest)
}
contentItem: StyledText { contentItem: StyledText {
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
@@ -389,27 +389,20 @@ Item {
} }
} }
Button { // Expand button RippleButton { // Expand button
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
id: expandButton id: expandButton
implicitWidth: 22 implicitWidth: 22
implicitHeight: 22 implicitHeight: 22
PointingHandInteraction{} buttonRadius: Appearance.rounding.full
colBackgroundHover: Appearance.colors.colLayer2Hover
colRipple: Appearance.colors.colLayer2Active
onClicked: { onClicked: {
root.toggleExpanded() root.toggleExpanded()
} }
background: Rectangle {
anchors.fill: parent
radius: Appearance.rounding.full
color: (expandButton.down) ? Appearance.colors.colLayer2Active : (expandButton.hovered ? Appearance.colors.colLayer2Hover : ColorUtils.transparentize(Appearance.colors.colLayer2, 1))
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
contentItem: MaterialSymbol { contentItem: MaterialSymbol {
anchors.centerIn: parent anchors.centerIn: parent
text: "keyboard_arrow_down" text: "keyboard_arrow_down"
@@ -0,0 +1,141 @@
import "root:/modules/common"
import "root:/modules/common/widgets"
import "root:/modules/common/functions/color_utils.js" as ColorUtils
import Qt5Compat.GraphicalEffects
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell.Io
import Quickshell.Widgets
Button {
id: root
property bool toggled
property string buttonText
property real buttonRadius: Appearance?.rounding?.small ?? 4
property int rippleDuration: 1200
property color colBackground: ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1)
property color colBackgroundHover: Appearance.colors.colLayer1Hover
property color colBackgroundToggled: Appearance.m3colors.m3primary
property color colBackgroundToggledHover: Appearance.colors.colPrimaryHover
property color colRipple: Appearance.colors.colLayer1Active
property color colRippleToggled: Appearance.colors.colPrimaryActive
property color buttonColor: root.enabled ? (root.toggled ?
(root.hovered ? colBackgroundToggledHover :
colBackgroundToggled) :
(root.hovered ? colBackgroundHover :
colBackground)) : colBackground
property color rippleColor: root.toggled ? colRippleToggled : colRipple
component RippleAnim: NumberAnimation {
duration: rippleDuration
easing.type: Appearance.animation.elementMoveEnter.type
easing.bezierCurve: Appearance.animationCurves.standardDecel
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onPressed: (event) => {
const {x,y} = event
const stateY = buttonBackground.y;
rippleAnim.x = x;
rippleAnim.y = y - stateY;
const dist = (ox,oy) => ox*ox + oy*oy
const stateEndY = stateY + buttonBackground.height
rippleAnim.radius = Math.sqrt(Math.max(dist(0, stateY), dist(0, stateEndY), dist(width, stateY), dist(width, stateEndY)))
rippleFadeAnim.complete();
rippleAnim.restart();
}
onReleased: (event) => {
root.click() // Because the MouseArea already consumed the event
rippleFadeAnim.restart();
}
onCanceled: (event) => {
rippleFadeAnim.restart();
}
}
RippleAnim {
id: rippleFadeAnim
target: ripple
property: "opacity"
to: 0
}
SequentialAnimation {
id: rippleAnim
property real x
property real y
property real radius
PropertyAction {
target: ripple
property: "x"
value: rippleAnim.x
}
PropertyAction {
target: ripple
property: "y"
value: rippleAnim.y
}
PropertyAction {
target: ripple
property: "opacity"
value: 1
}
ParallelAnimation {
RippleAnim {
target: ripple
properties: "implicitWidth,implicitHeight"
from: 0
to: rippleAnim.radius * 2
}
}
}
background: Rectangle {
id: buttonBackground
radius: root.buttonRadius
implicitHeight: 50
color: root.buttonColor
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Rectangle {
width: buttonBackground.width
height: buttonBackground.height
radius: buttonBackground.radius
}
}
Rectangle {
id: ripple
radius: Appearance.rounding.full
opacity: 0
color: root.rippleColor
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
transform: Translate {
x: -ripple.width / 2
y: -ripple.height / 2
}
}
}
contentItem: StyledText {
text: root.buttonText
}
}
@@ -25,24 +25,15 @@ Item { // Player instance
implicitWidth: widgetWidth implicitWidth: widgetWidth
implicitHeight: widgetHeight implicitHeight: widgetHeight
component TrackChangeButton: Button { component TrackChangeButton: RippleButton {
id: playPauseButton id: playPauseButton
implicitWidth: 24 implicitWidth: 24
implicitHeight: 24 implicitHeight: 24
property var iconName property var iconName
PointingHandInteraction {} colBackground: ColorUtils.transparentize(blendedColors.colSecondaryContainer, 1)
colBackgroundHover: blendedColors.colSecondaryContainerHover
background: Rectangle { colRipple: blendedColors.colSecondaryContainerActive
color: playPauseButton.pressed ? blendedColors.colSecondaryContainerActive :
playPauseButton.hovered ? blendedColors.colSecondaryContainerHover :
ColorUtils.transparentize(blendedColors.colSecondaryContainer, 1)
radius: Appearance.rounding.full
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
contentItem: MaterialSymbol { contentItem: MaterialSymbol {
iconSize: Appearance.font.pixelSize.huge iconSize: Appearance.font.pixelSize.huge
@@ -98,7 +89,7 @@ Item { // Player instance
property color colPrimaryActive: ColorUtils.mix(ColorUtils.adaptToAccent(Appearance.colors.colPrimaryActive, artDominantColor), artDominantColor, 0.3) property color colPrimaryActive: ColorUtils.mix(ColorUtils.adaptToAccent(Appearance.colors.colPrimaryActive, artDominantColor), artDominantColor, 0.3)
property color colSecondaryContainer: ColorUtils.mix(Appearance.m3colors.m3secondaryContainer, artDominantColor, 0.3) property color colSecondaryContainer: ColorUtils.mix(Appearance.m3colors.m3secondaryContainer, artDominantColor, 0.3)
property color colSecondaryContainerHover: ColorUtils.mix(Appearance.colors.colSecondaryContainerHover, artDominantColor, 0.3) property color colSecondaryContainerHover: ColorUtils.mix(Appearance.colors.colSecondaryContainerHover, artDominantColor, 0.3)
property color colSecondaryContainerActive: ColorUtils.mix(Appearance.colors.colSecondaryContainerActive, artDominantColor, 0.3) property color colSecondaryContainerActive: ColorUtils.mix(Appearance.colors.colSecondaryContainerActive, artDominantColor, 0.5)
property color colOnPrimary: ColorUtils.mix(ColorUtils.adaptToAccent(Appearance.m3colors.m3onPrimary, artDominantColor), artDominantColor, 0.5) property color colOnPrimary: ColorUtils.mix(ColorUtils.adaptToAccent(Appearance.m3colors.m3onPrimary, artDominantColor), artDominantColor, 0.5)
property color colOnSecondaryContainer: ColorUtils.mix(Appearance.m3colors.m3onSecondaryContainer, artDominantColor, 0.2) property color colOnSecondaryContainer: ColorUtils.mix(Appearance.m3colors.m3onSecondaryContainer, artDominantColor, 0.2)
@@ -247,7 +238,7 @@ Item { // Player instance
} }
} }
Button { RippleButton {
id: playPauseButton id: playPauseButton
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: sliderRow.top anchors.bottom: sliderRow.top
@@ -256,22 +247,10 @@ Item { // Player instance
implicitHeight: 44 implicitHeight: 44
onClicked: playerController.player.togglePlaying(); onClicked: playerController.player.togglePlaying();
PointingHandInteraction {} buttonRadius: Appearance.rounding.full
colBackground: playerController.player?.isPlaying ? blendedColors.colPrimary : blendedColors.colSecondaryContainer
background: Rectangle { colBackgroundHover: playerController.player?.isPlaying ? blendedColors.colPrimaryHover : blendedColors.colSecondaryContainerHover
color: playerController.player?.isPlaying ? colRipple: playerController.player?.isPlaying ? blendedColors.colPrimaryActive : blendedColors.colSecondaryContainerActive
(playPauseButton.pressed ? blendedColors.colPrimaryActive :
playPauseButton.hovered ? blendedColors.colPrimaryHover :
blendedColors.colPrimary) :
(playPauseButton.pressed ? blendedColors.colSecondaryContainerActive :
playPauseButton.hovered ? blendedColors.colSecondaryContainerHover :
blendedColors.colSecondaryContainer)
radius: Appearance.rounding.full
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
contentItem: MaterialSymbol { contentItem: MaterialSymbol {
iconSize: Appearance.font.pixelSize.huge iconSize: Appearance.font.pixelSize.huge
@@ -11,7 +11,7 @@ import Quickshell.Io
import Quickshell.Widgets import Quickshell.Widgets
import Quickshell.Hyprland import Quickshell.Hyprland
Button { RippleButton {
id: root id: root
property var entry property var entry
property bool entryShown: entry?.shown ?? true property bool entryShown: entry?.shown ?? true
@@ -33,6 +33,18 @@ Button {
anchors.right: parent?.right anchors.right: parent?.right
implicitHeight: rowLayout.implicitHeight + root.buttonVerticalPadding * 2 implicitHeight: rowLayout.implicitHeight + root.buttonVerticalPadding * 2
implicitWidth: rowLayout.implicitWidth + root.buttonHorizontalPadding * 2 implicitWidth: rowLayout.implicitWidth + root.buttonHorizontalPadding * 2
buttonRadius: Appearance.rounding.normal
colBackground: (root.down || root.keyboardDown) ? Appearance.colors.colLayer1Active :
((root.hovered || root.focus) ? Appearance.colors.colLayer1Hover :
ColorUtils.transparentize(Appearance.m3colors.m3surfaceContainerHigh, 1))
colBackgroundHover: Appearance.colors.colLayer1Hover
colRipple: Appearance.colors.colLayer1Active
background {
anchors.fill: root
anchors.leftMargin: root.horizontalMargin
anchors.rightMargin: root.horizontalMargin
}
PointingHandInteraction {} PointingHandInteraction {}
onClicked: { onClicked: {
@@ -53,16 +65,6 @@ Button {
} }
} }
background: Rectangle {
anchors.fill: parent
anchors.leftMargin: root.horizontalMargin
anchors.rightMargin: root.horizontalMargin
radius: Appearance.rounding.normal
color: (root.down || root.keyboardDown) ? Appearance.colors.colLayer1Active :
((root.hovered || root.focus) ? Appearance.colors.colLayer1Hover :
ColorUtils.transparentize(Appearance.m3colors.m3surfaceContainerHigh, 1))
}
RowLayout { RowLayout {
id: rowLayout id: rowLayout
spacing: 10 spacing: 10
@@ -82,8 +82,11 @@ Scope {
} }
} }
RowLayout { // First row of buttons GridLayout {
spacing: 15 columns: 4
columnSpacing: 15
rowSpacing: 15
SessionActionButton { SessionActionButton {
id: sessionLock id: sessionLock
focus: sessionRoot.visible focus: sessionRoot.visible
@@ -123,10 +126,7 @@ Scope {
KeyNavigation.left: sessionLogout KeyNavigation.left: sessionLogout
KeyNavigation.down: sessionFirmwareReboot KeyNavigation.down: sessionFirmwareReboot
} }
}
RowLayout { // Second row of buttons
spacing: 15
SessionActionButton { SessionActionButton {
id: sessionHibernate id: sessionHibernate
buttonIcon: "downloading" buttonIcon: "downloading"
@@ -1,22 +1,30 @@
import "root:/modules/common" import "root:/modules/common"
import "root:/modules/common/widgets/" import "root:/modules/common/widgets/"
import "root:/modules/common/functions/color_utils.js" as ColorUtils
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import Quickshell import Quickshell
import Quickshell.Io import Quickshell.Io
Button { RippleButton {
id: button id: button
property string buttonIcon property string buttonIcon
property string buttonText property string buttonText
property bool keyboardDown: false property bool keyboardDown: false
implicitHeight: 120 buttonRadius: button.focus ? Appearance.rounding.full : Appearance.rounding.verylarge
implicitWidth: 120 colBackground: button.keyboardDown ? Appearance.colors.colSecondaryContainerActive :
button.focus ? Appearance.colors.colSecondaryContainerHover :
Appearance.m3colors.m3secondaryContainer
colBackgroundHover: Appearance.colors.colSecondaryContainerHover
colRipple: Appearance.colors.colSecondaryContainerActive
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
background.implicitHeight: 120
background.implicitWidth: 120
PointingHandInteraction {}
Keys.onPressed: (event) => { Keys.onPressed: (event) => {
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
keyboardDown = true keyboardDown = true
@@ -31,21 +39,10 @@ Button {
} }
} }
background: Rectangle {
anchors.fill: parent
radius: Appearance.rounding.full
color: (button.down || button.keyboardDown) ? Appearance.colors.colLayer2Active : ((button.hovered || button.focus) ? Appearance.colors.colLayer2Hover : Appearance.colors.colLayer2)
Behavior on color {
animation: Appearance.animation.elementMove.colorAnimation.createObject(this)
}
}
contentItem: MaterialSymbol { contentItem: MaterialSymbol {
id: icon id: icon
anchors.fill: parent anchors.fill: parent
color: Appearance.colors.colOnLayer2 color: Appearance.colors.colOnLayer0
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
iconSize: 40 iconSize: 40
text: buttonIcon text: buttonIcon
@@ -282,14 +282,8 @@ int main(int argc, char* argv[]) {
} }
delegate: ApiCommandButton { delegate: ApiCommandButton {
id: commandButton id: commandButton
colBackground: suggestions.selectedIndex === index ? Appearance.colors.colLayer2Hover : Appearance.colors.colLayer2
background: Rectangle {
radius: Appearance.rounding.small
color: suggestions.selectedIndex === index ? Appearance.colors.colLayer2Hover :
commandButton.down ? Appearance.colors.colLayer2Active :
commandButton.hovered ? Appearance.colors.colLayer2Hover :
Appearance.colors.colLayer2
}
contentItem: RowLayout { contentItem: RowLayout {
spacing: 5 spacing: 5
StyledText { StyledText {
@@ -440,13 +434,15 @@ int main(int argc, char* argv[]) {
} }
} }
Button { // Send button RippleButton { // Send button
id: sendButton id: sendButton
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
Layout.rightMargin: 5 Layout.rightMargin: 5
implicitWidth: 40 implicitWidth: 40
implicitHeight: 40 implicitHeight: 40
buttonRadius: Appearance.rounding.small
enabled: messageInputField.text.length > 0 enabled: messageInputField.text.length > 0
toggled: enabled
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
@@ -458,17 +454,6 @@ int main(int argc, char* argv[]) {
} }
} }
background: Rectangle {
radius: Appearance.rounding.small
color: sendButton.enabled ? (sendButton.down ? Appearance.colors.colPrimaryActive :
sendButton.hovered ? Appearance.colors.colPrimaryHover :
Appearance.m3colors.m3primary) : Appearance.colors.colLayer2Disabled
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
contentItem: MaterialSymbol { contentItem: MaterialSymbol {
anchors.centerIn: parent anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
@@ -546,16 +531,6 @@ int main(int argc, char* argv[]) {
id: commandButton id: commandButton
property string commandRepresentation: `${root.commandPrefix}${modelData.name}` property string commandRepresentation: `${root.commandPrefix}${modelData.name}`
buttonText: commandRepresentation buttonText: commandRepresentation
background: Rectangle {
radius: Appearance.rounding.small
color: commandButton.down ? Appearance.colors.colLayer2Active :
commandButton.hovered ? Appearance.colors.colLayer2Hover :
Appearance.colors.colLayer2
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
onClicked: { onClicked: {
if(modelData.sendDirectly) { if(modelData.sendDirectly) {
root.handleInput(commandRepresentation) root.handleInput(commandRepresentation)
@@ -309,14 +309,8 @@ Item {
delegate: ApiCommandButton { delegate: ApiCommandButton {
id: tagButton id: tagButton
background: Rectangle { colBackground: tagSuggestions.selectedIndex === index ? Appearance.colors.colLayer2Hover : Appearance.colors.colLayer2
radius: Appearance.rounding.small
color: tagSuggestions.selectedIndex === index ? Appearance.colors.colLayer2Hover :
tagButton.down ? Appearance.colors.colLayer2Active :
tagButton.hovered ? Appearance.colors.colLayer2Hover :
Appearance.colors.colLayer2
}
contentItem: RowLayout { contentItem: RowLayout {
spacing: 5 spacing: 5
StyledText { StyledText {
@@ -487,13 +481,15 @@ Item {
} }
} }
Button { // Send button RippleButton { // Send button
id: sendButton id: sendButton
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
Layout.rightMargin: 5 Layout.rightMargin: 5
implicitWidth: 40 implicitWidth: 40
implicitHeight: 40 implicitHeight: 40
buttonRadius: Appearance.rounding.small
enabled: tagInputField.text.length > 0 enabled: tagInputField.text.length > 0
toggled: enabled
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
@@ -505,17 +501,6 @@ Item {
} }
} }
background: Rectangle {
radius: Appearance.rounding.small
color: sendButton.enabled ? (sendButton.down ? Appearance.colors.colPrimaryActive :
sendButton.hovered ? Appearance.colors.colPrimaryHover :
Appearance.m3colors.m3primary) : Appearance.colors.colLayer2Disabled
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
contentItem: MaterialSymbol { contentItem: MaterialSymbol {
anchors.centerIn: parent anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
@@ -637,16 +622,8 @@ Item {
id: tagButton id: tagButton
property string commandRepresentation: `${root.commandPrefix}${modelData.name}` property string commandRepresentation: `${root.commandPrefix}${modelData.name}`
buttonText: commandRepresentation buttonText: commandRepresentation
background: Rectangle { colBackground: Appearance.colors.colLayer2
radius: Appearance.rounding.small
color: tagButton.down ? Appearance.colors.colLayer2Active :
tagButton.hovered ? Appearance.colors.colLayer2Hover :
Appearance.colors.colLayer2
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
onClicked: { onClicked: {
if(modelData.sendDirectly) { if(modelData.sendDirectly) {
root.handleInput(commandRepresentation) root.handleInput(commandRepresentation)
@@ -6,7 +6,7 @@ import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import Quickshell import Quickshell
Button { RippleButton {
id: button id: button
property string buttonText property string buttonText
@@ -14,14 +14,9 @@ Button {
leftPadding: 10 leftPadding: 10
rightPadding: 10 rightPadding: 10
PointingHandInteraction {} colBackground: Appearance.colors.colLayer2
colBackgroundHover: Appearance.colors.colLayer2Hover
background: Rectangle { colRipple: Appearance.colors.colLayer2Active
radius: Appearance.rounding.small
color: (button.down ? Appearance.colors.colSurfaceContainerHighestActive :
button.hovered ? Appearance.colors.colSurfaceContainerHighestHover :
Appearance.m3colors.m3surfaceContainerHighest)
}
contentItem: StyledText { contentItem: StyledText {
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
@@ -7,31 +7,15 @@ import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import Quickshell import Quickshell
Button { RippleButton {
id: button id: button
property string buttonIcon property string buttonIcon
property bool activated: false property bool activated: false
toggled: activated
implicitHeight: 30 implicitHeight: 30
implicitWidth: 30 implicitWidth: 30
PointingHandInteraction {}
background: Rectangle {
radius: Appearance.rounding.small
color: !button.enabled ? ColorUtils.transparentize(Appearance.m3colors.m3surfaceContainerHighest, 1) :
button.activated ? (button.down ? Appearance.colors.colPrimaryActive :
button.hovered ? Appearance.colors.colPrimaryHover :
Appearance.m3colors.m3primary) :
(button.down ? Appearance.colors.colSurfaceContainerHighestActive :
button.hovered ? Appearance.colors.colSurfaceContainerHighestHover :
ColorUtils.transparentize(Appearance.m3colors.m3surfaceContainerHighest, 1))
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
contentItem: MaterialSymbol { contentItem: MaterialSymbol {
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
font.pixelSize: Appearance.font.pixelSize.large font.pixelSize: Appearance.font.pixelSize.large
@@ -11,7 +11,7 @@ import Quickshell.Io
import Quickshell.Widgets import Quickshell.Widgets
import Quickshell.Hyprland import Quickshell.Hyprland
Button { RippleButton {
id: root id: root
property string displayText property string displayText
property string url property string url
@@ -27,6 +27,10 @@ Button {
implicitHeight: 30 implicitHeight: 30
leftPadding: (implicitHeight - faviconSize) / 2 leftPadding: (implicitHeight - faviconSize) / 2
rightPadding: 10 rightPadding: 10
buttonRadius: Appearance.rounding.full
colBackground: Appearance.m3colors.m3surfaceContainerHighest
colBackgroundHover: Appearance.colors.colSurfaceContainerHighestHover
colRipple: Appearance.colors.colSurfaceContainerHighestActive
Process { Process {
id: faviconDownloadProcess id: faviconDownloadProcess
@@ -49,13 +53,6 @@ Button {
} }
} }
background: Rectangle {
radius: Appearance.rounding.full
color: (root.down ? Appearance.colors.colSurfaceContainerHighestActive :
root.hovered ? Appearance.colors.colSurfaceContainerHighestHover :
Appearance.m3colors.m3surfaceContainerHighest)
}
contentItem: RowLayout { contentItem: RowLayout {
spacing: 5 spacing: 5
IconImage { IconImage {
@@ -102,35 +102,18 @@ Item {
text: root.completed ? qsTr("Chain of Thought") : (qsTr("Thinking") + ".".repeat(Math.random() * 4)) text: root.completed ? qsTr("Chain of Thought") : (qsTr("Thinking") + ".".repeat(Math.random() * 4))
} }
Item { Layout.fillWidth: true } Item { Layout.fillWidth: true }
Button { // Expand button RippleButton { // Expand button
id: expandButton id: expandButton
visible: root.completed visible: root.completed
implicitWidth: 22 implicitWidth: 22
implicitHeight: 22 implicitHeight: 22
colBackground: headerMouseArea.containsMouse ? Appearance.colors.colLayer2Hover
: ColorUtils.transparentize(Appearance.colors.colLayer2, 1)
colBackgroundHover: Appearance.colors.colLayer2Hover
colRipple: Appearance.colors.colLayer2Active
PointingHandInteraction{} onClicked: { root.collapsed = !root.collapsed }
onClicked: {
root.collapsed = !root.collapsed
}
background: Rectangle {
anchors.fill: parent
radius: Appearance.rounding.full
color: (headerMouseArea.pressed) ? Appearance.colors.colLayer2Active
: (headerMouseArea.containsMouse ? Appearance.colors.colLayer2Hover
: ColorUtils.transparentize(Appearance.colors.colLayer2, 1))
Behavior on color {
ColorAnimation {
duration: collapseAnimation.duration
easing.type: collapseAnimation.type
easing.bezierCurve: collapseAnimation.bezierCurve
}
}
}
contentItem: MaterialSymbol { contentItem: MaterialSymbol {
anchors.centerIn: parent anchors.centerIn: parent
text: "keyboard_arrow_down" text: "keyboard_arrow_down"
@@ -46,8 +46,6 @@ Button {
implicitWidth: imageObject.width implicitWidth: imageObject.width
implicitHeight: imageObject.height implicitHeight: imageObject.height
// PointingHandInteraction {}
background: Rectangle { background: Rectangle {
implicitWidth: imageObject.width implicitWidth: imageObject.width
implicitHeight: imageObject.height implicitHeight: imageObject.height
@@ -84,7 +82,7 @@ Button {
} }
} }
Button { RippleButton {
id: menuButton id: menuButton
anchors.top: parent.top anchors.top: parent.top
anchors.right: parent.right anchors.right: parent.right
@@ -92,19 +90,15 @@ Button {
implicitHeight: 30 implicitHeight: 30
implicitWidth: 30 implicitWidth: 30
PointingHandInteraction {} buttonRadius: Appearance.rounding.full
colBackground: ColorUtils.transparentize(Appearance.m3colors.m3surface, 0.3)
colBackgroundHover: ColorUtils.transparentize(ColorUtils.mix(Appearance.m3colors.m3surface, Appearance.m3colors.m3onSurface, 0.8), 0.2)
colRipple: ColorUtils.transparentize(ColorUtils.mix(Appearance.m3colors.m3surface, Appearance.m3colors.m3onSurface, 0.6), 0.1)
StyledToolTip { StyledToolTip {
content: `${StringUtils.wordWrap(root.imageData.tags, root.maxTagStringLineLength)}\n${qsTr("Click for options")}` content: `${StringUtils.wordWrap(root.imageData.tags, root.maxTagStringLineLength)}\n${qsTr("Click for options")}`
} }
background: Rectangle {
color: menuButton.down ? ColorUtils.transparentize(ColorUtils.mix(Appearance.m3colors.m3surface, Appearance.m3colors.m3onSurface, 0.6), 0.1) :
menuButton.hovered ? ColorUtils.transparentize(ColorUtils.mix(Appearance.m3colors.m3surface, Appearance.m3colors.m3onSurface, 0.8), 0.2) :
ColorUtils.transparentize(Appearance.m3colors.m3surface, 0.3)
radius: Appearance.rounding.full
}
contentItem: MaterialSymbol { contentItem: MaterialSymbol {
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
iconSize: Appearance.font.pixelSize.large iconSize: Appearance.font.pixelSize.large
@@ -251,7 +251,7 @@ Rectangle {
} }
} }
Button { // Next page button RippleButton { // Next page button
id: button id: button
property string buttonText property string buttonText
visible: root.responseData.page != "" && root.responseData.page > 0 visible: root.responseData.page != "" && root.responseData.page > 0
@@ -261,18 +261,15 @@ Rectangle {
leftPadding: 10 leftPadding: 10
rightPadding: 5 rightPadding: 5
PointingHandInteraction {}
onClicked: { onClicked: {
tagInputField.text = `${responseData.tags.join(" ")} ${parseInt(root.responseData.page) + 1}` tagInputField.text = `${responseData.tags.join(" ")} ${parseInt(root.responseData.page) + 1}`
tagInputField.accept() tagInputField.accept()
} }
background: Rectangle { buttonRadius: Appearance.rounding.small
radius: Appearance.rounding.small colBackground: Appearance.m3colors.m3surfaceContainerHighest
color: (button.down ? Appearance.colors.colSurfaceContainerHighestActive : colBackgroundHover: Appearance.colors.colSurfaceContainerHighestHover
button.hovered ? Appearance.colors.colSurfaceContainerHighestHover : colRipple: Appearance.colors.colSurfaceContainerHighestActive
Appearance.m3colors.m3surfaceContainerHighest)
}
contentItem: Item { contentItem: Item {
anchors.fill: parent anchors.fill: parent
@@ -5,7 +5,7 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
Button { RippleButton {
id: button id: button
property string day property string day
property int isToday property int isToday
@@ -17,20 +17,8 @@ Button {
implicitWidth: 38; implicitWidth: 38;
implicitHeight: 38; implicitHeight: 38;
background: Rectangle { toggled: (isToday == 1)
anchors.fill: parent buttonRadius: Appearance.rounding.small
radius: Appearance.rounding.full
color: (isToday == 1) ? ((interactable && button.down) ? Appearance.colors.colPrimaryActive :
(interactable && button.hovered) ? Appearance.colors.colPrimaryHover :
Appearance.m3colors.m3primary) :
(interactable && button.down) ? Appearance.colors.colLayer1Active :
(interactable && button.hovered) ? Appearance.colors.colLayer1Hover :
ColorUtils.transparentize(Appearance.colors.colLayer1, 1)
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
contentItem: StyledText { contentItem: StyledText {
anchors.fill: parent anchors.fill: parent
@@ -4,7 +4,7 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
Button { RippleButton {
id: button id: button
property string buttonText: "" property string buttonText: ""
property string tooltipText: "" property string tooltipText: ""
@@ -18,18 +18,12 @@ Button {
} }
} }
PointingHandInteraction {} background.anchors.fill: button
buttonRadius: Appearance.rounding.full
colBackground: Appearance.colors.colLayer2
colBackgroundHover: Appearance.colors.colLayer2Hover
colRipple: Appearance.colors.colLayer2Active
background: Rectangle {
anchors.fill: parent
radius: Appearance.rounding.full
color: (button.down) ? Appearance.colors.colLayer2Active : (button.hovered ? Appearance.colors.colLayer2Hover : Appearance.colors.colLayer2)
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
contentItem: StyledText { contentItem: StyledText {
text: buttonText text: buttonText
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
@@ -4,12 +4,12 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
Button { RippleButton {
id: button id: button
property string buttonText: "" property string buttonText: ""
property string buttonIcon: "" property string buttonIcon: ""
// implicitHeight: 30 implicitHeight: 30
implicitWidth: contentRowLayout.implicitWidth + 10 * 2 implicitWidth: contentRowLayout.implicitWidth + 10 * 2
Behavior on implicitWidth { Behavior on implicitWidth {
SmoothedAnimation { SmoothedAnimation {
@@ -17,33 +17,29 @@ Button {
} }
} }
PointingHandInteraction {} buttonRadius: Appearance.rounding.full
colBackground: Appearance.colors.colLayer2
colBackgroundHover: Appearance.colors.colLayer2Hover
colRipple: Appearance.colors.colLayer2Active
background.anchors.fill: button
background: Rectangle { contentItem: Item {
anchors.fill: parent RowLayout {
radius: Appearance.rounding.full id: contentRowLayout
color: (button.down) ? Appearance.colors.colLayer2Active : (button.hovered ? Appearance.colors.colLayer2Hover : Appearance.colors.colLayer2) anchors.centerIn: parent
spacing: 0
Behavior on color { MaterialSymbol {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) text: buttonIcon
} Layout.fillWidth: false
iconSize: Appearance.font.pixelSize.larger
} color: Appearance.colors.colOnLayer1
contentItem: RowLayout { }
id: contentRowLayout StyledText {
anchors.centerIn: parent text: buttonText
spacing: 0 Layout.fillWidth: false
MaterialSymbol { font.pixelSize: Appearance.font.pixelSize.small
text: buttonIcon color: Appearance.colors.colOnLayer1
Layout.fillWidth: false }
iconSize: Appearance.font.pixelSize.larger
color: Appearance.colors.colOnLayer1
}
StyledText {
text: buttonText
Layout.fillWidth: false
font.pixelSize: Appearance.font.pixelSize.small
color: Appearance.colors.colOnLayer1
} }
} }
@@ -5,41 +5,27 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import Quickshell.Io import Quickshell.Io
Button { RippleButton {
id: button id: button
property bool toggled
property string buttonIcon property string buttonIcon
toggled: false
buttonRadius: Appearance?.rounding?.full ?? 9999
implicitWidth: 40 implicitWidth: 40
implicitHeight: 40 implicitHeight: 40
PointingHandInteraction {} contentItem: MaterialSymbol {
anchors.centerIn: parent
background: Rectangle { iconSize: Appearance.font.pixelSize.larger
anchors.fill: parent fill: toggled ? 1 : 0
radius: Appearance.rounding.full color: toggled ? Appearance.m3colors.m3onPrimary : Appearance.colors.colOnLayer1
color: toggled ? horizontalAlignment: Text.AlignHCenter
(button.down ? Appearance.colors.colPrimaryActive : button.hovered ? Appearance.colors.colPrimaryHover : Appearance.m3colors.m3primary) : verticalAlignment: Text.AlignVCenter
(button.down ? Appearance.colors.colLayer1Active : button.hovered ? Appearance.colors.colLayer1Hover : ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1)) text: buttonIcon
Behavior on color { Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
} }
MaterialSymbol {
anchors.centerIn: parent
iconSize: Appearance.font.pixelSize.larger
fill: toggled ? 1 : 0
text: buttonIcon
color: toggled ? Appearance.m3colors.m3onPrimary : Appearance.colors.colOnLayer1
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
} }
} }
@@ -5,7 +5,7 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
Button { RippleButton {
id: button id: button
property string buttonText: "" property string buttonText: ""
property string tooltipText: "" property string tooltipText: ""
@@ -13,24 +13,14 @@ Button {
implicitHeight: 30 implicitHeight: 30
implicitWidth: implicitHeight implicitWidth: implicitHeight
PointingHandInteraction {}
Behavior on implicitWidth { Behavior on implicitWidth {
SmoothedAnimation { SmoothedAnimation {
velocity: Appearance.animation.elementMove.velocity velocity: Appearance.animation.elementMove.velocity
} }
} }
background: Rectangle { buttonRadius: Appearance.rounding.small
anchors.fill: parent
radius: Appearance.rounding.full
color: (button.down) ? Appearance.colors.colLayer2Active : (button.hovered ? Appearance.colors.colLayer2Hover : ColorUtils.transparentize(Appearance.colors.colLayer2, 1))
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
contentItem: StyledText { contentItem: StyledText {
text: buttonText text: buttonText
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
@@ -8,21 +8,14 @@ import QtQuick.Layouts
import Quickshell.Widgets import Quickshell.Widgets
import Quickshell.Services.Pipewire import Quickshell.Services.Pipewire
Button { RippleButton {
id: button id: button
required property bool input required property bool input
background: Rectangle { buttonRadius: Appearance.rounding.small
anchors.fill: parent colBackground: Appearance.colors.colLayer2
radius: Appearance.rounding.small colBackgroundHover: Appearance.colors.colLayer2Hover
color: (button.down) ? Appearance.colors.colLayer2Active : (button.hovered ? Appearance.colors.colLayer2Hover : Appearance.colors.colLayer2) colRipple: Appearance.colors.colLayer2Active
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
}
PointingHandInteraction {}
contentItem: RowLayout { contentItem: RowLayout {
anchors.fill: parent anchors.fill: parent