mirror of
https://github.com/hyprwm/hyprland-qt-support.git
synced 2025-05-13 05:30: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
|
||||||
import QtQuick.Controls.Basic as T
|
import QtQuick.Templates as T
|
||||||
import org.hyprland.style.impl
|
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 {
|
T.Button {
|
||||||
id: control
|
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 {
|
background: Rectangle {
|
||||||
implicitWidth: 50
|
implicitWidth: 50
|
||||||
implicitHeight: 30
|
implicitHeight: 30
|
||||||
|
@ -12,14 +37,26 @@ T.Button {
|
||||||
radius: HyprlandStyle.radius
|
radius: HyprlandStyle.radius
|
||||||
border.width: HyprlandStyle.borderWidth
|
border.width: HyprlandStyle.borderWidth
|
||||||
|
|
||||||
MotionBehavior on color { ColorAnimation { duration: 50 } }
|
MotionBehavior on color { ColorAnimation { duration: 60 } }
|
||||||
color: control.down || control.checked
|
color: {
|
||||||
? Qt.tint(control.palette.button, Qt.alpha(control.palette.highlight, 0.4))
|
let highlightTint = control.down || control.checked ? 0.3 : control.highlighted ? 0.25 : 0.0;
|
||||||
: control.flat ? "transparent" : control.palette.button
|
|
||||||
|
|
||||||
MotionBehavior on border.color { ColorAnimation { duration: 50 } }
|
if (control.flat && highlightTint)
|
||||||
border.color: control.hovered || control.highlighted || control.down || control.checked
|
highlightTint += 0.3;
|
||||||
? control.palette.highlight
|
|
||||||
: control.flat ? "transparent" : control.palette.light
|
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
|
import QtQuick
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
property real radius: 8
|
id: root
|
||||||
|
|
||||||
property real borderWidth: 1
|
property real borderWidth: 1
|
||||||
|
property real radius: 7
|
||||||
property bool reduceMotion: false
|
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 <qguiapplication.h>
|
||||||
#include <qqmlapplicationengine.h>
|
#include <qqmlapplicationengine.h>
|
||||||
#include <qquickstyle.h>
|
#include <qquickstyle.h>
|
||||||
|
#include <qtenvironmentvariables.h>
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
auto app = QGuiApplication(argc, argv);
|
auto app = QGuiApplication(argc, argv);
|
||||||
|
|
||||||
QGuiApplication::setApplicationName("Hyprland style gallery");
|
QGuiApplication::setApplicationName("Hyprland style gallery");
|
||||||
QQuickStyle::setStyle("org.hyprland.style");
|
|
||||||
|
if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE"))
|
||||||
|
QQuickStyle::setStyle("org.hyprland.style");
|
||||||
|
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import QtQuick.Controls
|
||||||
import org.hyprland.style.impl
|
import org.hyprland.style.impl
|
||||||
|
|
||||||
ApplicationWindow {
|
ApplicationWindow {
|
||||||
|
id: window
|
||||||
visible: true
|
visible: true
|
||||||
|
|
||||||
ScrollView {
|
ScrollView {
|
||||||
|
@ -61,6 +62,55 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
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 {
|
ColumnLayout {
|
||||||
Layout.maximumWidth: 200
|
Layout.maximumWidth: 200
|
||||||
Label { text: "Button" }
|
Label { text: "Button" }
|
||||||
|
@ -71,10 +121,13 @@ ApplicationWindow {
|
||||||
TestButton { text: "Flat"; flat: true; }
|
TestButton { text: "Flat"; flat: true; }
|
||||||
TestButton { text: "Highlighted"; highlighted: true }
|
TestButton { text: "Highlighted"; highlighted: true }
|
||||||
TestButton { text: "Flat Highlighted"; flat: true; highlighted: true }
|
TestButton { text: "Flat Highlighted"; flat: true; highlighted: true }
|
||||||
TestButton { text: "Checked"; checked: true }
|
TestButton { text: "Checked"; checkable: true; checked: true }
|
||||||
TestButton { text: "Flat Checked"; flat: true; checked: true }
|
TestButton { text: "Flat Checked"; flat: true; checkable: true; checked: true }
|
||||||
TestButton { text: "Down"; down: true }
|
TestButton { text: "Down"; down: true }
|
||||||
TestButton { text: "Flat Down"; flat: true; 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 }
|
Item { Layout.fillWidth: true }
|
||||||
|
|
Loading…
Reference in a new issue