mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-07 19:59:14 -04:00
(Control Center): revamp of 25% pill option (#2568)
* revamp of control center * update comment of SmallCompoundButton.qml
This commit is contained in:
@@ -12,7 +12,7 @@ PluginComponent {
|
|||||||
service: CupsService
|
service: CupsService
|
||||||
}
|
}
|
||||||
|
|
||||||
ccWidgetIcon: CupsService.cupsAvailable && CupsService.getPrintersNum() > 0 ? "print" : "print_disabled"
|
ccWidgetIcon: "print"
|
||||||
ccWidgetPrimaryText: I18n.tr("Printers")
|
ccWidgetPrimaryText: I18n.tr("Printers")
|
||||||
ccWidgetSecondaryText: {
|
ccWidgetSecondaryText: {
|
||||||
if (CupsService.cupsAvailable && CupsService.getPrintersNum() > 0) {
|
if (CupsService.cupsAvailable && CupsService.getPrintersNum() > 0) {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ PluginComponent {
|
|||||||
service: DMSNetworkService
|
service: DMSNetworkService
|
||||||
}
|
}
|
||||||
|
|
||||||
ccWidgetIcon: DMSNetworkService.isBusy ? "sync" : (DMSNetworkService.connected ? "vpn_lock" : "vpn_key_off")
|
ccWidgetIcon: "vpn_key"
|
||||||
ccWidgetPrimaryText: I18n.tr("VPN")
|
ccWidgetPrimaryText: I18n.tr("VPN")
|
||||||
ccWidgetSecondaryText: {
|
ccWidgetSecondaryText: {
|
||||||
if (!DMSNetworkService.connected)
|
if (!DMSNetworkService.connected)
|
||||||
|
|||||||
@@ -102,6 +102,120 @@ Column {
|
|||||||
item.z = 1000;
|
item.z = 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCompoundPillIconBlinking(id) {
|
||||||
|
if (id === "wifi") return NetworkService.isWifiConnecting;
|
||||||
|
if (id === "bluetooth") return BluetoothService.connecting;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCompoundPillIconName(id, widgetDef) {
|
||||||
|
switch (id) {
|
||||||
|
case "wifi": {
|
||||||
|
if (NetworkService.wifiToggling) return "sync";
|
||||||
|
if (NetworkService.isConnecting && !NetworkService.ethernetConnected) return NetworkService.wifiSignalIcon;
|
||||||
|
const status = NetworkService.networkStatus;
|
||||||
|
if (status === "ethernet") return "settings_ethernet";
|
||||||
|
if (status === "vpn") return NetworkService.ethernetConnected ? "settings_ethernet" : NetworkService.wifiSignalIcon;
|
||||||
|
if (status === "wifi") return NetworkService.wifiSignalIcon;
|
||||||
|
return "wifi";
|
||||||
|
}
|
||||||
|
case "bluetooth": {
|
||||||
|
return "bluetooth";
|
||||||
|
}
|
||||||
|
case "audioOutput": {
|
||||||
|
if (!AudioService.sink?.audio) return "volume_off";
|
||||||
|
let volume = AudioService.sink.audio.volume;
|
||||||
|
let muted = AudioService.sink.audio.muted;
|
||||||
|
if (muted) return "volume_off";
|
||||||
|
if (volume === 0.0) return "volume_mute";
|
||||||
|
if (volume <= 0.33) return "volume_down";
|
||||||
|
if (volume <= 0.66) return "volume_up";
|
||||||
|
return "volume_up";
|
||||||
|
}
|
||||||
|
case "audioInput": {
|
||||||
|
if (!AudioService.source?.audio) return "mic_off";
|
||||||
|
return AudioService.source.audio.muted ? "mic_off" : "mic";
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return widgetDef?.icon || "help";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCompoundPillIsActive(id) {
|
||||||
|
switch (id) {
|
||||||
|
case "wifi": {
|
||||||
|
if (NetworkService.wifiToggling) return false;
|
||||||
|
const status = NetworkService.networkStatus;
|
||||||
|
if (status === "ethernet") return true;
|
||||||
|
if (status === "vpn") return NetworkService.ethernetConnected || NetworkService.wifiConnected;
|
||||||
|
if (status === "wifi") return true;
|
||||||
|
return NetworkService.wifiEnabled;
|
||||||
|
}
|
||||||
|
case "bluetooth":
|
||||||
|
return !!(BluetoothService.available && BluetoothService.adapter && BluetoothService.adapter.enabled);
|
||||||
|
case "audioOutput":
|
||||||
|
return !!(AudioService.sink?.audio && !AudioService.sink.audio.muted);
|
||||||
|
case "audioInput":
|
||||||
|
return !!(AudioService.source?.audio && !AudioService.source.audio.muted);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCompoundPillToggled(id) {
|
||||||
|
switch (id) {
|
||||||
|
case "wifi": {
|
||||||
|
if (NetworkService.networkStatus !== "ethernet" && !NetworkService.wifiToggling) {
|
||||||
|
NetworkService.toggleWifiRadio();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "bluetooth": {
|
||||||
|
if (BluetoothService.available && BluetoothService.adapter) {
|
||||||
|
BluetoothService.adapter.enabled = !BluetoothService.adapter.enabled;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "audioOutput": {
|
||||||
|
if (AudioService.sink && AudioService.sink.audio) {
|
||||||
|
AudioService.sink.audio.muted = !AudioService.sink.audio.muted;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "audioInput": {
|
||||||
|
if (AudioService.source && AudioService.source.audio) {
|
||||||
|
AudioService.source.audio.muted = !AudioService.source.audio.muted;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCompoundPillWheelEvent(id, wheelEvent) {
|
||||||
|
if (id === "audioOutput") {
|
||||||
|
if (!AudioService.sink || !AudioService.sink.audio) return;
|
||||||
|
let delta = wheelEvent.angleDelta.y;
|
||||||
|
let maxVol = AudioService.sinkMaxVolume;
|
||||||
|
let currentVolume = AudioService.sink.audio.volume * 100;
|
||||||
|
let newVolume;
|
||||||
|
if (delta > 0) newVolume = Math.min(maxVol, currentVolume + 5);
|
||||||
|
else newVolume = Math.max(0, currentVolume - 5);
|
||||||
|
AudioService.sink.audio.muted = false;
|
||||||
|
AudioService.sink.audio.volume = newVolume / 100;
|
||||||
|
wheelEvent.accepted = true;
|
||||||
|
} else if (id === "audioInput") {
|
||||||
|
if (!AudioService.source || !AudioService.source.audio) return;
|
||||||
|
let delta = wheelEvent.angleDelta.y;
|
||||||
|
let currentVolume = AudioService.source.audio.volume * 100;
|
||||||
|
let newVolume;
|
||||||
|
if (delta > 0) newVolume = Math.min(100, currentVolume + 5);
|
||||||
|
else newVolume = Math.max(0, currentVolume - 5);
|
||||||
|
AudioService.source.audio.muted = false;
|
||||||
|
AudioService.source.audio.volume = newVolume / 100;
|
||||||
|
wheelEvent.accepted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function componentForWidget(widgetData) {
|
function componentForWidget(widgetData) {
|
||||||
const id = widgetData.id || "";
|
const id = widgetData.id || "";
|
||||||
const widgetWidth = widgetData.width || 50;
|
const widgetWidth = widgetData.width || 50;
|
||||||
@@ -114,7 +228,7 @@ Column {
|
|||||||
case "bluetooth":
|
case "bluetooth":
|
||||||
case "audioOutput":
|
case "audioOutput":
|
||||||
case "audioInput":
|
case "audioInput":
|
||||||
return compoundPillComponent;
|
return widgetWidth <= 25 ? smallCompoundComponent : compoundPillComponent;
|
||||||
case "volumeSlider":
|
case "volumeSlider":
|
||||||
return audioSliderComponent;
|
return audioSliderComponent;
|
||||||
case "brightnessSlider":
|
case "brightnessSlider":
|
||||||
@@ -126,7 +240,7 @@ Column {
|
|||||||
case "diskUsage":
|
case "diskUsage":
|
||||||
return widgetWidth <= 25 ? smallDiskUsageComponent : diskUsagePillComponent;
|
return widgetWidth <= 25 ? smallDiskUsageComponent : diskUsagePillComponent;
|
||||||
case "colorPicker":
|
case "colorPicker":
|
||||||
return colorPickerPillComponent;
|
return widgetWidth <= 25 ? smallColorPickerComponent : colorPickerPillComponent;
|
||||||
case "doNotDisturb":
|
case "doNotDisturb":
|
||||||
return widgetWidth <= 25 ? smallToggleComponent : dndPillComponent;
|
return widgetWidth <= 25 ? smallToggleComponent : dndPillComponent;
|
||||||
default:
|
default:
|
||||||
@@ -329,69 +443,8 @@ Column {
|
|||||||
property var widgetDef: root.model?.getWidgetForId(widgetData.id || "")
|
property var widgetDef: root.model?.getWidgetForId(widgetData.id || "")
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 60
|
height: 60
|
||||||
iconBlinking: {
|
iconBlinking: root.getCompoundPillIconBlinking(widgetData.id || "")
|
||||||
const id = widgetData.id || "";
|
iconName: root.getCompoundPillIconName(widgetData.id || "", widgetDef)
|
||||||
if (id === "wifi")
|
|
||||||
return NetworkService.isWifiConnecting;
|
|
||||||
if (id === "bluetooth")
|
|
||||||
return BluetoothService.connecting;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
iconName: {
|
|
||||||
switch (widgetData.id || "") {
|
|
||||||
case "wifi":
|
|
||||||
{
|
|
||||||
if (NetworkService.wifiToggling)
|
|
||||||
return "sync";
|
|
||||||
if (NetworkService.isConnecting && !NetworkService.ethernetConnected)
|
|
||||||
return NetworkService.wifiSignalIcon;
|
|
||||||
|
|
||||||
const status = NetworkService.networkStatus;
|
|
||||||
if (status === "ethernet")
|
|
||||||
return "settings_ethernet";
|
|
||||||
if (status === "vpn")
|
|
||||||
return NetworkService.ethernetConnected ? "settings_ethernet" : NetworkService.wifiSignalIcon;
|
|
||||||
if (status === "wifi")
|
|
||||||
return NetworkService.wifiSignalIcon;
|
|
||||||
if (NetworkService.wifiEnabled)
|
|
||||||
return "wifi_off";
|
|
||||||
return "wifi_off";
|
|
||||||
}
|
|
||||||
case "bluetooth":
|
|
||||||
{
|
|
||||||
if (!BluetoothService.available)
|
|
||||||
return "bluetooth_disabled";
|
|
||||||
if (!BluetoothService.adapter || !BluetoothService.adapter.enabled)
|
|
||||||
return "bluetooth_disabled";
|
|
||||||
return "bluetooth";
|
|
||||||
}
|
|
||||||
case "audioOutput":
|
|
||||||
{
|
|
||||||
if (!AudioService.sink?.audio)
|
|
||||||
return "volume_off";
|
|
||||||
let volume = AudioService.sink.audio.volume;
|
|
||||||
let muted = AudioService.sink.audio.muted;
|
|
||||||
if (muted)
|
|
||||||
return "volume_off";
|
|
||||||
if (volume === 0.0)
|
|
||||||
return "volume_mute";
|
|
||||||
if (volume <= 0.33)
|
|
||||||
return "volume_down";
|
|
||||||
if (volume <= 0.66)
|
|
||||||
return "volume_up";
|
|
||||||
return "volume_up";
|
|
||||||
}
|
|
||||||
case "audioInput":
|
|
||||||
{
|
|
||||||
if (!AudioService.source?.audio)
|
|
||||||
return "mic_off";
|
|
||||||
let muted = AudioService.source.audio.muted;
|
|
||||||
return muted ? "mic_off" : "mic";
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return widgetDef?.icon || "help";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
primaryText: {
|
primaryText: {
|
||||||
switch (widgetData.id || "") {
|
switch (widgetData.id || "") {
|
||||||
case "wifi":
|
case "wifi":
|
||||||
@@ -506,66 +559,12 @@ Column {
|
|||||||
return widgetDef?.description || "";
|
return widgetDef?.description || "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isActive: {
|
isActive: root.getCompoundPillIsActive(widgetData.id || "")
|
||||||
switch (widgetData.id || "") {
|
|
||||||
case "wifi":
|
|
||||||
{
|
|
||||||
if (NetworkService.wifiToggling)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const status = NetworkService.networkStatus;
|
|
||||||
if (status === "ethernet")
|
|
||||||
return true;
|
|
||||||
if (status === "vpn")
|
|
||||||
return NetworkService.ethernetConnected || NetworkService.wifiConnected;
|
|
||||||
if (status === "wifi")
|
|
||||||
return true;
|
|
||||||
return NetworkService.wifiEnabled;
|
|
||||||
}
|
|
||||||
case "bluetooth":
|
|
||||||
return !!(BluetoothService.available && BluetoothService.adapter && BluetoothService.adapter.enabled);
|
|
||||||
case "audioOutput":
|
|
||||||
return !!(AudioService.sink?.audio && !AudioService.sink.audio.muted);
|
|
||||||
case "audioInput":
|
|
||||||
return !!(AudioService.source?.audio && !AudioService.source.audio.muted);
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enabled: widgetDef?.enabled ?? true
|
enabled: widgetDef?.enabled ?? true
|
||||||
onToggled: {
|
onToggled: {
|
||||||
if (root.editMode)
|
if (root.editMode)
|
||||||
return;
|
return;
|
||||||
switch (widgetData.id || "") {
|
root.handleCompoundPillToggled(widgetData.id || "");
|
||||||
case "wifi":
|
|
||||||
{
|
|
||||||
if (NetworkService.networkStatus !== "ethernet" && !NetworkService.wifiToggling) {
|
|
||||||
NetworkService.toggleWifiRadio();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "bluetooth":
|
|
||||||
{
|
|
||||||
if (BluetoothService.available && BluetoothService.adapter) {
|
|
||||||
BluetoothService.adapter.enabled = !BluetoothService.adapter.enabled;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "audioOutput":
|
|
||||||
{
|
|
||||||
if (AudioService.sink && AudioService.sink.audio) {
|
|
||||||
AudioService.sink.audio.muted = !AudioService.sink.audio.muted;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "audioInput":
|
|
||||||
{
|
|
||||||
if (AudioService.source && AudioService.source.audio) {
|
|
||||||
AudioService.source.audio.muted = !AudioService.source.audio.muted;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
onExpandClicked: {
|
onExpandClicked: {
|
||||||
if (root.editMode)
|
if (root.editMode)
|
||||||
@@ -575,35 +574,7 @@ Column {
|
|||||||
onWheelEvent: function (wheelEvent) {
|
onWheelEvent: function (wheelEvent) {
|
||||||
if (root.editMode)
|
if (root.editMode)
|
||||||
return;
|
return;
|
||||||
const id = widgetData.id || "";
|
root.handleCompoundPillWheelEvent(widgetData.id || "", wheelEvent);
|
||||||
if (id === "audioOutput") {
|
|
||||||
if (!AudioService.sink || !AudioService.sink.audio)
|
|
||||||
return;
|
|
||||||
let delta = wheelEvent.angleDelta.y;
|
|
||||||
let maxVol = AudioService.sinkMaxVolume;
|
|
||||||
let currentVolume = AudioService.sink.audio.volume * 100;
|
|
||||||
let newVolume;
|
|
||||||
if (delta > 0)
|
|
||||||
newVolume = Math.min(maxVol, currentVolume + 5);
|
|
||||||
else
|
|
||||||
newVolume = Math.max(0, currentVolume - 5);
|
|
||||||
AudioService.sink.audio.muted = false;
|
|
||||||
AudioService.sink.audio.volume = newVolume / 100;
|
|
||||||
wheelEvent.accepted = true;
|
|
||||||
} else if (id === "audioInput") {
|
|
||||||
if (!AudioService.source || !AudioService.source.audio)
|
|
||||||
return;
|
|
||||||
let delta = wheelEvent.angleDelta.y;
|
|
||||||
let currentVolume = AudioService.source.audio.volume * 100;
|
|
||||||
let newVolume;
|
|
||||||
if (delta > 0)
|
|
||||||
newVolume = Math.min(100, currentVolume + 5);
|
|
||||||
else
|
|
||||||
newVolume = Math.max(0, currentVolume - 5);
|
|
||||||
AudioService.source.audio.muted = false;
|
|
||||||
AudioService.source.audio.volume = newVolume / 100;
|
|
||||||
wheelEvent.accepted = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -736,7 +707,7 @@ Column {
|
|||||||
case "darkMode":
|
case "darkMode":
|
||||||
return "contrast";
|
return "contrast";
|
||||||
case "idleInhibitor":
|
case "idleInhibitor":
|
||||||
return SessionService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle";
|
return "motion_sensor_active";
|
||||||
default:
|
default:
|
||||||
return "help";
|
return "help";
|
||||||
}
|
}
|
||||||
@@ -821,9 +792,9 @@ Column {
|
|||||||
case "darkMode":
|
case "darkMode":
|
||||||
return "contrast";
|
return "contrast";
|
||||||
case "doNotDisturb":
|
case "doNotDisturb":
|
||||||
return SessionData.doNotDisturb ? "do_not_disturb_on" : "do_not_disturb_off";
|
return "do_not_disturb_on";
|
||||||
case "idleInhibitor":
|
case "idleInhibitor":
|
||||||
return SessionService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle";
|
return "motion_sensor_active";
|
||||||
default:
|
default:
|
||||||
return "help";
|
return "help";
|
||||||
}
|
}
|
||||||
@@ -1223,4 +1194,47 @@ Column {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: smallCompoundComponent
|
||||||
|
SmallCompoundButton {
|
||||||
|
property var widgetData: parent.widgetData || {}
|
||||||
|
property int widgetIndex: parent.widgetIndex || 0
|
||||||
|
property var widgetDef: root.model?.getWidgetForId(widgetData.id || "")
|
||||||
|
width: parent.width
|
||||||
|
height: 48
|
||||||
|
iconBlinking: root.getCompoundPillIconBlinking(widgetData.id || "")
|
||||||
|
iconName: root.getCompoundPillIconName(widgetData.id || "", widgetDef)
|
||||||
|
isActive: root.getCompoundPillIsActive(widgetData.id || "")
|
||||||
|
enabled: (widgetDef?.enabled ?? true) && !root.editMode
|
||||||
|
onToggled: {
|
||||||
|
if (root.editMode) return;
|
||||||
|
root.handleCompoundPillToggled(widgetData.id || "");
|
||||||
|
}
|
||||||
|
onExpandClicked: {
|
||||||
|
if (root.editMode) return;
|
||||||
|
root.expandClicked(widgetData, widgetIndex);
|
||||||
|
}
|
||||||
|
onWheelEvent: function(wheelEvent) {
|
||||||
|
if (root.editMode) return;
|
||||||
|
root.handleCompoundPillWheelEvent(widgetData.id || "", wheelEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: smallColorPickerComponent
|
||||||
|
SmallColorPickerButton {
|
||||||
|
property var widgetData: parent.widgetData || {}
|
||||||
|
property int widgetIndex: parent.widgetIndex || 0
|
||||||
|
width: parent.width
|
||||||
|
height: 48
|
||||||
|
colorPickerModal: root.colorPickerModal
|
||||||
|
onClicked: {
|
||||||
|
if (root.editMode) return;
|
||||||
|
if (root.colorPickerModal)
|
||||||
|
root.colorPickerModal.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import qs.Modules.ControlCenter.Widgets
|
|||||||
CompoundPill {
|
CompoundPill {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
iconName: SessionData.doNotDisturb ? "do_not_disturb_on" : "do_not_disturb_off"
|
iconName: "do_not_disturb_on"
|
||||||
iconColor: SessionData.doNotDisturb ? Theme.primary : Theme.surfaceText
|
iconColor: SessionData.doNotDisturb ? Theme.primary : Theme.surfaceText
|
||||||
primaryText: I18n.tr("Do Not Disturb")
|
primaryText: I18n.tr("Do Not Disturb")
|
||||||
isActive: SessionData.doNotDisturb
|
isActive: SessionData.doNotDisturb
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import QtQuick
|
||||||
|
import qs.Common
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
LayoutMirroring.enabled: I18n.isRtl
|
||||||
|
LayoutMirroring.childrenInherit: true
|
||||||
|
|
||||||
|
property var colorPickerModal: null
|
||||||
|
|
||||||
|
signal clicked
|
||||||
|
|
||||||
|
width: parent ? ((parent.width - parent.spacing * 3) / 4) : 48
|
||||||
|
height: 48
|
||||||
|
radius: Theme.cornerRadius === 0 ? 0 : Theme.cornerRadius
|
||||||
|
|
||||||
|
function hoverTint(base) {
|
||||||
|
const factor = 1.2;
|
||||||
|
return Theme.isLightMode ? Qt.darker(base, factor) : Qt.lighter(base, factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
color: Theme.primary
|
||||||
|
border.color: Theme.ccTileRing
|
||||||
|
border.width: 1
|
||||||
|
antialiasing: true
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: parent.radius
|
||||||
|
color: hoverTint(root.color)
|
||||||
|
opacity: mouseArea.pressed ? 0.3 : (mouseArea.containsMouse ? 0.2 : 0.0)
|
||||||
|
visible: opacity > 0
|
||||||
|
antialiasing: true
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "palette"
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: Theme.primaryText
|
||||||
|
}
|
||||||
|
|
||||||
|
DankRipple {
|
||||||
|
id: ripple
|
||||||
|
cornerRadius: root.radius
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
enabled: root.enabled
|
||||||
|
onPressed: mouse => ripple.trigger(mouse.x, mouse.y)
|
||||||
|
onClicked: root.clicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
import QtQuick
|
||||||
|
import qs.Common
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
LayoutMirroring.enabled: I18n.isRtl
|
||||||
|
LayoutMirroring.childrenInherit: true
|
||||||
|
|
||||||
|
property string iconName: ""
|
||||||
|
property bool isActive: false
|
||||||
|
property bool iconBlinking: false
|
||||||
|
|
||||||
|
// Left click expands the widget (primary detail action), right click toggles on/off.
|
||||||
|
signal toggled
|
||||||
|
signal expandClicked
|
||||||
|
signal wheelEvent(var wheelEvent)
|
||||||
|
|
||||||
|
width: parent ? ((parent.width - parent.spacing * 3) / 4) : 48
|
||||||
|
height: 48
|
||||||
|
radius: {
|
||||||
|
if (Theme.cornerRadius === 0)
|
||||||
|
return 0;
|
||||||
|
return isActive ? Theme.cornerRadius : Theme.cornerRadius + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hoverTint(base) {
|
||||||
|
const factor = 1.2;
|
||||||
|
return Theme.isLightMode ? Qt.darker(base, factor) : Qt.lighter(base, factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property color _tileBgActive: Theme.ccTileActiveBg
|
||||||
|
readonly property color _tileBgInactive: Theme.ccPillInactiveBg
|
||||||
|
readonly property color _tileRingActive: Theme.ccTileRing
|
||||||
|
readonly property color _tileIconActive: Theme.ccTileActiveText
|
||||||
|
readonly property color _tileIconInactive: Theme.ccTileInactiveIcon
|
||||||
|
|
||||||
|
color: {
|
||||||
|
if (isActive)
|
||||||
|
return _tileBgActive;
|
||||||
|
const baseColor = mouseArea.containsMouse ? Theme.ccPillInactiveHoverBg : _tileBgInactive;
|
||||||
|
return baseColor;
|
||||||
|
}
|
||||||
|
border.color: isActive ? _tileRingActive : Theme.outlineMedium
|
||||||
|
border.width: isActive ? 1 : Theme.layerOutlineWidth
|
||||||
|
antialiasing: true
|
||||||
|
opacity: enabled ? 1.0 : 0.6
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: parent.radius
|
||||||
|
color: hoverTint(root.color)
|
||||||
|
opacity: mouseArea.pressed ? 0.3 : (mouseArea.containsMouse ? 0.2 : 0.0)
|
||||||
|
visible: opacity > 0
|
||||||
|
antialiasing: true
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
id: tileIcon
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: iconName
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: isActive ? _tileIconActive : _tileIconInactive
|
||||||
|
|
||||||
|
DankBlink {
|
||||||
|
target: tileIcon
|
||||||
|
running: root.iconBlinking
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankRipple {
|
||||||
|
id: ripple
|
||||||
|
cornerRadius: root.radius
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
enabled: root.enabled
|
||||||
|
onPressed: mouse => ripple.trigger(mouse.x, mouse.y)
|
||||||
|
onClicked: mouse => {
|
||||||
|
if (mouse.button === Qt.RightButton)
|
||||||
|
root.toggled();
|
||||||
|
else
|
||||||
|
root.expandClicked();
|
||||||
|
}
|
||||||
|
onWheel: function (ev) {
|
||||||
|
root.wheelEvent(ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on radius {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user