mirror of
https://github.com/hyprwm/hyprland-qt-support.git
synced 2025-05-12 21:20:35 +01:00
style: get button to consistently look ok in reasonable palettes
This commit is contained in:
parent
9a1c66532b
commit
ed177913b0
4 changed files with 143 additions and 13 deletions
|
@ -1,10 +1,35 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls.Basic as T
|
||||
import QtQuick.Templates as T
|
||||
import org.hyprland.style.impl
|
||||
|
||||
// This is private and we shouldn't use it, however rewriting IconLabel would take hundreds of
|
||||
// lines of C++ to end up with something worse.
|
||||
import QtQuick.Controls.impl as ControlsPrivate
|
||||
|
||||
T.Button {
|
||||
id: control
|
||||
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitContentHeight + topPadding + bottomPadding)
|
||||
|
||||
padding: 6
|
||||
spacing: 6
|
||||
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
icon.color: control.palette.buttonText
|
||||
|
||||
contentItem: ControlsPrivate.IconLabel {
|
||||
spacing: control.spacing
|
||||
mirrored: control.mirrored
|
||||
display: control.display
|
||||
|
||||
icon: control.icon
|
||||
text: control.text
|
||||
font: control.font
|
||||
color: control.palette.buttonText
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
implicitWidth: 50
|
||||
implicitHeight: 30
|
||||
|
@ -12,14 +37,26 @@ T.Button {
|
|||
radius: HyprlandStyle.radius
|
||||
border.width: HyprlandStyle.borderWidth
|
||||
|
||||
MotionBehavior on color { ColorAnimation { duration: 50 } }
|
||||
color: control.down || control.checked
|
||||
? Qt.tint(control.palette.button, Qt.alpha(control.palette.highlight, 0.4))
|
||||
: control.flat ? "transparent" : control.palette.button
|
||||
MotionBehavior on color { ColorAnimation { duration: 60 } }
|
||||
color: {
|
||||
let highlightTint = control.down || control.checked ? 0.3 : control.highlighted ? 0.25 : 0.0;
|
||||
|
||||
MotionBehavior on border.color { ColorAnimation { duration: 50 } }
|
||||
border.color: control.hovered || control.highlighted || control.down || control.checked
|
||||
? control.palette.highlight
|
||||
: control.flat ? "transparent" : control.palette.light
|
||||
if (control.flat && highlightTint)
|
||||
highlightTint += 0.3;
|
||||
|
||||
const base = HyprlandStyle.flat(control.palette.button, control.flat);
|
||||
return HyprlandStyle.overlay(base, control.palette.highlight, highlightTint);
|
||||
}
|
||||
|
||||
MotionBehavior on border.color { ColorAnimation { duration: 60 } }
|
||||
border.color: {
|
||||
let highlightTint = control.down || control.checked ? 0.8 : (control.enabled && control.hovered) || control.highlighted ? 0.6 : 0.0;
|
||||
|
||||
if (control.flat && highlightTint)
|
||||
highlightTint += 0.2;
|
||||
|
||||
const base = HyprlandStyle.flat(HyprlandStyle.lightenOrDarken(control.palette.button, 1.4), control.flat);
|
||||
return HyprlandStyle.overlay(base, control.palette.highlight, highlightTint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,44 @@ pragma Singleton
|
|||
import QtQuick
|
||||
|
||||
QtObject {
|
||||
property real radius: 8
|
||||
id: root
|
||||
|
||||
property real borderWidth: 1
|
||||
property real radius: 7
|
||||
property bool reduceMotion: false
|
||||
|
||||
function flat(color: color, flat: bool): color {
|
||||
return flat ? root.transparent(color) : color;
|
||||
}
|
||||
|
||||
function isDark(cg: ColorGroup): bool {
|
||||
return cg.windowText.hsvValue > cg.window.hsvValue;
|
||||
}
|
||||
|
||||
function lightenOrDarken(color: color, factor: real): color {
|
||||
return color.hsvValue > 0.5 ? Qt.darker(color, factor) : Qt.lighter(color, factor);
|
||||
}
|
||||
|
||||
function overlay(base: color, tint: color, tintOpacity: real): color {
|
||||
return Qt.tint(base, Qt.alpha(tint, tintOpacity));
|
||||
}
|
||||
|
||||
function scaledColor(cg: ColorGroup, index: int): color {
|
||||
switch (index * (root.isDark(cg) ? 1 : -1)) {
|
||||
case -2:
|
||||
return cg.light;
|
||||
case -1:
|
||||
return cg.midlight;
|
||||
case 1:
|
||||
return cg.mid;
|
||||
case 2:
|
||||
return cg.dark;
|
||||
}
|
||||
}
|
||||
|
||||
// ColorAnimation animates all properties of a color, instead of mixing normally, so
|
||||
// transparency has to have the same RGB.
|
||||
function transparent(color: color): color {
|
||||
return Qt.alpha(color, 0.0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,15 @@
|
|||
#include <qguiapplication.h>
|
||||
#include <qqmlapplicationengine.h>
|
||||
#include <qquickstyle.h>
|
||||
#include <qtenvironmentvariables.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
auto app = QGuiApplication(argc, argv);
|
||||
|
||||
QGuiApplication::setApplicationName("Hyprland style gallery");
|
||||
QQuickStyle::setStyle("org.hyprland.style");
|
||||
|
||||
if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE"))
|
||||
QQuickStyle::setStyle("org.hyprland.style");
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import QtQuick.Controls
|
|||
import org.hyprland.style.impl
|
||||
|
||||
ApplicationWindow {
|
||||
id: window
|
||||
visible: true
|
||||
|
||||
ScrollView {
|
||||
|
@ -61,6 +62,55 @@ ApplicationWindow {
|
|||
}
|
||||
|
||||
RowLayout {
|
||||
ColumnLayout {
|
||||
Layout.maximumWidth: 300
|
||||
Label { text: "Palette" }
|
||||
|
||||
SystemPalette { id: activePalette; colorGroup: SystemPalette.Active }
|
||||
SystemPalette { id: inactivePalette; colorGroup: SystemPalette.Inactive }
|
||||
SystemPalette { id: disabledPalette; colorGroup: SystemPalette.Disabled }
|
||||
|
||||
component PaletteColor: Rectangle {
|
||||
required property string name;
|
||||
required property var cg;
|
||||
implicitWidth: 50
|
||||
implicitHeight: 20
|
||||
color: cg[name]
|
||||
}
|
||||
|
||||
component PaletteItem: RowLayout {
|
||||
id: pi
|
||||
|
||||
property alias text: label.text
|
||||
property string color;
|
||||
|
||||
Label {
|
||||
id: label
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
PaletteColor { name: pi.color; cg: activePalette }
|
||||
PaletteColor { name: pi.color; cg: inactivePalette }
|
||||
PaletteColor { name: pi.color; cg: disabledPalette }
|
||||
}
|
||||
|
||||
PaletteItem { text: "Light"; color: "light" }
|
||||
PaletteItem { text: "Midlight"; color: "midlight" }
|
||||
PaletteItem { text: "Button"; color: "button" }
|
||||
PaletteItem { text: "Window"; color: "window" }
|
||||
PaletteItem { text: "Mid"; color: "mid" }
|
||||
PaletteItem { text: "Dark"; color: "dark" }
|
||||
PaletteItem { text: "Base"; color: "base" }
|
||||
PaletteItem { text: "Text"; color: "text" }
|
||||
PaletteItem { text: "Button Text"; color: "buttonText" }
|
||||
PaletteItem { text: "Window Text"; color: "windowText" }
|
||||
PaletteItem { text: "Highli Text"; color: "highlightedText" }
|
||||
PaletteItem { text: "Placeholder"; color: "placeholderText" }
|
||||
PaletteItem { text: "Shadow"; color: "shadow" }
|
||||
PaletteItem { text: "Highlight"; color: "highlight" }
|
||||
PaletteItem { text: "Accent"; color: "accent" }
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.maximumWidth: 200
|
||||
Label { text: "Button" }
|
||||
|
@ -71,10 +121,13 @@ ApplicationWindow {
|
|||
TestButton { text: "Flat"; flat: true; }
|
||||
TestButton { text: "Highlighted"; highlighted: true }
|
||||
TestButton { text: "Flat Highlighted"; flat: true; highlighted: true }
|
||||
TestButton { text: "Checked"; checked: true }
|
||||
TestButton { text: "Flat Checked"; flat: true; checked: true }
|
||||
TestButton { text: "Checked"; checkable: true; checked: true }
|
||||
TestButton { text: "Flat Checked"; flat: true; checkable: true; checked: true }
|
||||
TestButton { text: "Down"; down: true }
|
||||
TestButton { text: "Flat Down"; flat: true; down: true }
|
||||
TestButton { text: "Disabled"; enabled: false }
|
||||
TestButton { text: "With Icon"; icon.name: "folder" }
|
||||
TestButton { icon.name: "folder" }
|
||||
}
|
||||
|
||||
Item { Layout.fillWidth: true }
|
||||
|
|
Loading…
Reference in a new issue