From d7a497b71e8da0bea07248e7c7f3f1825f03179b Mon Sep 17 00:00:00 2001 From: giskard Date: Sun, 9 Jun 2024 23:44:54 +0800 Subject: [PATCH] feat: add widget slider --- src/configSchema.json | 64 +++++++++++-- src/controlCenter/widgets/factory.vala | 3 + src/controlCenter/widgets/slider/slider.vala | 98 ++++++++++++++++++++ src/meson.build | 2 + 4 files changed, 160 insertions(+), 7 deletions(-) create mode 100644 src/controlCenter/widgets/slider/slider.vala diff --git a/src/configSchema.json b/src/configSchema.json index 64210075..e20ca2f6 100644 --- a/src/configSchema.json +++ b/src/configSchema.json @@ -324,6 +324,9 @@ "^menubar(#[a-zA-Z0-9_-]{1,}){0,1}?$": { "$ref": "#/widgets/menubar" }, + "^slider(#[a-zA-Z0-9_-]{1,}){0,1}?$": { + "$ref": "#/widgets/slider" + }, "^volume(#[a-zA-Z0-9_-]{1,}){0,1}?$": { "$ref": "#/widgets/volume" }, @@ -446,9 +449,9 @@ "default": "" }, "active": { - "type": "boolean", - "description": "Wether the toggle button is active as default or not", - "default": false + "type": "boolean", + "description": "Wether the toggle button is active as default or not", + "default": false } } } @@ -482,13 +485,13 @@ "description": "Animation type for menu", "enum": ["slide_down", "slide_up", "none"] }, - "animation-duration":{ + "animation-duration": { "type": "integer", "default": 250, "description": "Duration of animation in milliseconds" }, "actions": { - "$ref" : "#/widgets/buttons-grid/properties/actions" + "$ref": "#/widgets/buttons-grid/properties/actions" } } }, @@ -504,12 +507,59 @@ "enum": ["right", "left"] }, "actions": { - "$ref" : "#/widgets/buttons-grid/properties/actions" + "$ref": "#/widgets/buttons-grid/properties/actions" } } } } }, + "slider": { + "type": "object", + "description": "Slider to control pulse volume", + "additionalProperties": false, + "properties": { + "label": { + "type": "string", + "description": "Text displayed in front of the slider", + "default": "slider" + }, + "min": { + "type": "integer", + "description": "minimum value of the slider range", + "default": 0.0 + }, + "max": { + "type": "integer", + "description": "maximum value of the slider range", + "default": 100 + }, + "min_limit": { + "type": "integer", + "description": "limit minimum value of the slider", + "default": 0 + }, + "max_limit": { + "type": "integer", + "description": "limit maximum value of the slider", + "default": 100 + }, + "value_scale": { + "type": "integer", + "default": 0, + "description": "scale small value, slider round digits" + }, + "command": { + "type": "string", + "description": "command to run on value change", + "default": "" + }, + "update_command": { + "type": "string", + "description": "command to get the current actual value", + "default": "" + } + } + }, "volume": { "type": "object", "description": "Slider to control pulse volume", @@ -561,7 +611,7 @@ "description": "Animation type for menu", "enum": ["slide_down", "slide_up", "none"] }, - "animation-duration":{ + "animation-duration": { "type": "integer", "default": 250, "description": "Duration of animation in milliseconds" diff --git a/src/controlCenter/widgets/factory.vala b/src/controlCenter/widgets/factory.vala index 0302c895..e7819d63 100644 --- a/src/controlCenter/widgets/factory.vala +++ b/src/controlCenter/widgets/factory.vala @@ -26,6 +26,9 @@ namespace SwayNotificationCenter.Widgets { case "buttons-grid": widget = new ButtonsGrid (suffix, swaync_daemon, noti_daemon); break; + case "slider": + widget = new Slider (suffix, swaync_daemon, noti_daemon); + break; #if HAVE_PULSE_AUDIO case "volume": widget = new Volume (suffix, swaync_daemon, noti_daemon); diff --git a/src/controlCenter/widgets/slider/slider.vala b/src/controlCenter/widgets/slider/slider.vala new file mode 100644 index 00000000..184d18fe --- /dev/null +++ b/src/controlCenter/widgets/slider/slider.vala @@ -0,0 +1,98 @@ +namespace SwayNotificationCenter.Widgets { + public class Slider : BaseWidget { + public override string widget_name { + get { + return "slider"; + } + } + + Gtk.Label label_widget = new Gtk.Label (null); + Gtk.Scale slider = new Gtk.Scale.with_range (Gtk.Orientation.HORIZONTAL, 0, 100, 1); + + private double min_limit; + private double max_limit; + private double ? last_set; + + private string command; + private string update_command; + + public Slider (string suffix, SwayncDaemon swaync_daemon, NotiDaemon noti_daemon) { + base (suffix, swaync_daemon, noti_daemon); + + Json.Object ? config = get_config (this); + if (config != null) { + string ? label = get_prop (config, "label"); + label_widget.set_label (label ?? "Slider"); + + command = get_prop (config, "command") ?? ""; + update_command = get_prop (config, "update_command") ?? ""; + + int ? round_digits = get_prop (config, "value_scale"); + double scale = round_digits == null ? 1 : Math.pow (10, round_digits); + + int ? min = get_prop (config, "min"); + int ? max = get_prop (config, "max"); + int ? maxl = get_prop (config, "min_limit"); + int ? minl = get_prop (config, "max_limit"); + + if (min == null) + min = 0; + if (max == null) + min = 100; + + max_limit = maxl != null ? double.min (max, maxl) : max; + + min_limit = minl != null ? double.max (min, minl) : min; + + min_limit /= scale; + max_limit /= scale; + + slider.set_range (min / scale, max / scale); + slider.set_round_digits (round_digits); + } + + slider.set_draw_value (false); + slider.set_round_digits (0); + slider.value_changed.connect (() => { + double value = slider.get_value (); + if (value > max_limit) + value = max_limit; + if (value < min_limit) + value = min_limit; + slider.set_value (value); + + string value_str = value.to_string (); + slider.tooltip_text = value_str; + + if (command != "" && last_set != value) { + last_set = value; + Functions.execute_command.begin (command + " " + value_str); + } + }); + + add (label_widget); + pack_start (slider, true, true, 0); + + show_all (); + } + + public async void on_update () { + if (update_command == "") + return; + + string value_str = ""; + yield Functions.execute_command (update_command, {}, out value_str); + + double value = double.parse (value_str); + if (value <= max_limit && value >= min_limit) { + last_set = value; + slider.set_value (value); + } + } + + public override void on_cc_visibility_change (bool value) { + if (value) + on_update.begin (); + } + } +} diff --git a/src/meson.build b/src/meson.build index 2c26e4c0..6a926f2a 100644 --- a/src/meson.build +++ b/src/meson.build @@ -41,6 +41,8 @@ widget_sources = [ 'controlCenter/widgets/menubar/menubar.vala', # Widget: Buttons Grid 'controlCenter/widgets/buttonsGrid/buttonsGrid.vala', + # Widget: Slider + 'controlCenter/widgets/slider/slider.vala', # Widget: Backlight Slider 'controlCenter/widgets/backlight/backlight.vala', 'controlCenter/widgets/backlight/backlightUtil.vala',