diff options
| author | nippy <you@example.com> | 2026-04-18 13:49:56 +0200 |
|---|---|---|
| committer | nippy <you@example.com> | 2026-04-18 13:49:56 +0200 |
| commit | 5d94c0a7d44a2255b81815a52a7056a94a39842d (patch) | |
| tree | 759bdea9645c6a62f9e1e4c001f7d81cccd120d2 /raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences | |
| parent | e79cdf210b267f21a186255ce1a4d50029439d54 (diff) | |
| download | RaveOS-PKGBUILD-5d94c0a7d44a2255b81815a52a7056a94a39842d.tar.gz RaveOS-PKGBUILD-5d94c0a7d44a2255b81815a52a7056a94a39842d.zip | |
update Raveos themes
Diffstat (limited to 'raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences')
12 files changed, 1424 insertions, 0 deletions
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications.js new file mode 100644 index 0000000..a4dd5be --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications.js @@ -0,0 +1,217 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gio from 'gi://Gio'; + +import { ApplicationRow } from './applications_management/application_row.js'; + + +const make_array = prefs_group => { + let list_box = prefs_group + .get_first_child() + .get_last_child() + .get_first_child(); + + let elements = []; + let i = 0; + let element = list_box.get_row_at_index(i); + while (element) { + elements.push(element); + i++; + element = list_box.get_row_at_index(i); + } + + return elements; +}; + + +export const Applications = GObject.registerClass({ + GTypeName: 'Applications', + Template: GLib.uri_resolve_relative(import.meta.url, '../ui/applications.ui', GLib.UriFlags.NONE), + InternalChildren: [ + 'blur', + 'pipeline_choose_row', + 'mode_static', + 'mode_dynamic', + 'sigma_row', + 'sigma', + 'brightness_row', + 'brightness', + 'opacity', + 'dynamic_opacity', + 'blur_on_overview', + 'enable_all', + 'whitelist', + 'add_window_whitelist', + 'blacklist', + 'add_window_blacklist' + ], +}, class Applications extends Adw.PreferencesPage { + constructor(preferences, preferences_window, pipelines_manager, pipelines_page) { + super({}); + this._preferences_window = preferences_window; + + this.preferences = preferences; + this.pipelines_manager = pipelines_manager; + this.pipelines_page = pipelines_page; + + this.preferences.applications.settings.bind( + 'blur', this._blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + this._pipeline_choose_row.initialize( + this.preferences.applications, this.pipelines_manager, this.pipelines_page + ); + + this.change_blur_mode(this.preferences.applications.STATIC_BLUR, true); + + this._mode_static.connect('toggled', + () => this.preferences.applications.STATIC_BLUR = this._mode_static.active + ); + this.preferences.applications.STATIC_BLUR_changed( + () => this.change_blur_mode(this.preferences.applications.STATIC_BLUR, false) + ); + + this.preferences.applications.settings.bind( + 'opacity', this._opacity, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.applications.settings.bind( + 'dynamic-opacity', this._dynamic_opacity, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.applications.settings.bind( + 'blur-on-overview', this._blur_on_overview, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.applications.settings.bind( + 'enable-all', this._enable_all, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.applications.settings.bind( + 'sigma', this._sigma, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.applications.settings.bind( + 'brightness', this._brightness, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + + // connect 'enable all' button to whitelist/blacklist visibility + this._enable_all.bind_property( + 'active', this._whitelist, 'visible', + GObject.BindingFlags.INVERT_BOOLEAN + ); + this._enable_all.bind_property( + 'active', this._blacklist, 'visible', + GObject.BindingFlags.DEFAULT + ); + + // make sure that blacklist / whitelist is correctly hidden + if (this._enable_all.active) + this._whitelist.visible = false; + this._blacklist.visible = !this._whitelist.visible; + + // listen to app row addition + this._add_window_whitelist.connect('clicked', + () => this.add_to_whitelist() + ); + this._add_window_blacklist.connect('clicked', + () => this.add_to_blacklist() + ); + + // add initial applications + this.add_widgets_from_lists(); + + this.preferences.connect('reset', () => { + this.remove_all_widgets(); + this.add_widgets_from_lists(); + }); + } + + // A way to retriew the whitelist widgets. + get _whitelist_elements() { + return make_array(this._whitelist); + } + + // A way to retriew the blacklist widgets. + get _blacklist_elements() { + return make_array(this._blacklist); + } + + add_widgets_from_lists() { + this.preferences.applications.WHITELIST.forEach( + app_name => this.add_to_whitelist(app_name) + ); + + this.preferences.applications.BLACKLIST.forEach( + app_name => this.add_to_blacklist(app_name) + ); + + } + + close_all_expanded_rows() { + this._whitelist_elements.forEach( + element => element.set_expanded(false) + ); + this._blacklist_elements.forEach( + element => element.set_expanded(false) + ); + } + + remove_all_widgets() { + this._whitelist_elements.forEach( + element => this._whitelist.remove(element) + ); + this._blacklist_elements.forEach( + element => this._blacklist.remove(element) + ); + } + + add_to_whitelist(app_name = null) { + let window_row = new ApplicationRow('whitelist', this, app_name); + this._whitelist.add(window_row); + } + + add_to_blacklist(app_name = null) { + let window_row = new ApplicationRow('blacklist', this, app_name); + this._blacklist.add(window_row); + } + + update_whitelist_titles() { + let titles = this._whitelist_elements + .map(element => element._window_class.buffer.text) + .filter(title => title != ""); + + this.preferences.applications.WHITELIST = titles; + } + + update_blacklist_titles() { + let titles = this._blacklist_elements + .map(element => element._window_class.buffer.text) + .filter(title => title != ""); + + this.preferences.applications.BLACKLIST = titles; + } + + remove_from_whitelist(widget) { + this._whitelist.remove(widget); + this.update_whitelist_titles(); + } + + remove_from_blacklist(widget) { + this._blacklist.remove(widget); + this.update_blacklist_titles(); + } + + change_blur_mode(is_static_blur, first_run) { + this._mode_static.set_active(is_static_blur); + if (first_run) + this._mode_dynamic.set_active(!is_static_blur); + + this._pipeline_choose_row.set_visible(is_static_blur); + this._sigma_row.set_visible(!is_static_blur); + this._brightness_row.set_visible(!is_static_blur); + } +});
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications_management/application_row.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications_management/application_row.js new file mode 100644 index 0000000..4af3bf8 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications_management/application_row.js @@ -0,0 +1,112 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gio from 'gi://Gio'; +import Gtk from 'gi://Gtk'; + +import { pick, on_picking, on_picked } from '../../dbus/client.js'; + + +export const ApplicationRow = GObject.registerClass({ + GTypeName: 'ApplicationRow', + Template: GLib.uri_resolve_relative(import.meta.url, '../../ui/application-row.ui', GLib.UriFlags.NONE), + InternalChildren: [ + 'window_picker', + 'window_class', + 'picking_failure_toast', + 'window_not_found_toast' + ], +}, class ApplicationRow extends Adw.ExpanderRow { + constructor(list, app_page, app_name) { + super({}); + this._list = list; + this._app_page = app_page; + + // add a 'remove' button before the text + let action_row = this.child.get_first_child().get_first_child(); + let remove_button = new Gtk.Button({ + 'icon-name': 'remove-row-symbolic', + 'width-request': 38, + 'height-request': 38, + 'margin-top': 6, + 'margin-bottom': 6, + }); + remove_button.add_css_class('circular'); + remove_button.add_css_class('flat'); + action_row.add_prefix(remove_button); + + // connect the button to the whitelist / blacklist removal + remove_button.connect('clicked', () => this._remove_row()); + + // bind row title to text buffer + this._window_class.buffer.bind_property( + 'text', this, 'title', + Gio.SettingsBindFlags.BIDIRECTIONNAL + ); + + // set application name if it exists, or open the revealer and pick one + if (app_name) + this._window_class.buffer.text = app_name; + else { + app_page.close_all_expanded_rows(); + this.set_expanded(true); + this._do_pick_window(true); + } + + // pick a window when the picker button is clicked + this._window_picker.connect('clicked', () => this._do_pick_window()); + + // update list on text buffer change + this._window_class.connect('changed', + () => this._update_rows_titles() + ); + } + + _remove_row() { + this._app_page["remove_from_" + this._list](this); + } + + _update_rows_titles() { + this._app_page["update_" + this._list + "_titles"](this); + } + + _do_pick_window(remove_if_failed = false) { + // a mechanism to know if the extension is listening correcly + let has_responded = false; + let should_take_answer = true; + setTimeout(() => { + if (!has_responded) { + // show toast about failure + this._app_page._preferences_window.add_toast( + this._picking_failure_toast + ); + + // prevent title from changing with later picks + should_take_answer = false; + + // remove row if asked + if (remove_if_failed) + this._remove_row(); + } + }, 250); + + on_picking(() => + has_responded = true + ); + + on_picked(wm_class => { + if (should_take_answer) { + if (wm_class == 'window-not-found') { + console.warn("Can't pick window from here"); + this._app_page._preferences_window.add_toast( + this._window_not_found_toast + ); + return; + } + this._window_class.buffer.text = wm_class; + } + }); + + pick(); + } +}); diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/dash.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/dash.js new file mode 100644 index 0000000..aae3768 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/dash.js @@ -0,0 +1,81 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gio from 'gi://Gio'; + + +export const Dash = GObject.registerClass({ + GTypeName: 'Dash', + Template: GLib.uri_resolve_relative(import.meta.url, '../ui/dash.ui', GLib.UriFlags.NONE), + InternalChildren: [ + 'blur', + 'pipeline_choose_row', + 'mode_static', + 'mode_dynamic', + 'sigma_row', + 'sigma', + 'brightness_row', + 'brightness', + 'override_background', + 'style_dash_to_dock', + 'unblur_in_overview' + ], +}, class Dash extends Adw.PreferencesPage { + constructor(preferences, pipelines_manager, pipelines_page) { + super({}); + + this.preferences = preferences; + this.pipelines_manager = pipelines_manager; + this.pipelines_page = pipelines_page; + + this.preferences.dash_to_dock.settings.bind( + 'blur', this._blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + this._pipeline_choose_row.initialize( + this.preferences.dash_to_dock, this.pipelines_manager, this.pipelines_page + ); + + this.change_blur_mode(this.preferences.dash_to_dock.STATIC_BLUR, true); + + this._mode_static.connect('toggled', + () => this.preferences.dash_to_dock.STATIC_BLUR = this._mode_static.active + ); + this.preferences.dash_to_dock.STATIC_BLUR_changed( + () => this.change_blur_mode(this.preferences.dash_to_dock.STATIC_BLUR, false) + ); + + this.preferences.dash_to_dock.settings.bind( + 'sigma', this._sigma, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.dash_to_dock.settings.bind( + 'brightness', this._brightness, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.dash_to_dock.settings.bind( + 'override-background', + this._override_background, 'enable-expansion', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.dash_to_dock.settings.bind( + 'style-dash-to-dock', this._style_dash_to_dock, 'selected', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.dash_to_dock.settings.bind( + 'unblur-in-overview', this._unblur_in_overview, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + } + + change_blur_mode(is_static_blur, first_run) { + this._mode_static.set_active(is_static_blur); + if (first_run) + this._mode_dynamic.set_active(!is_static_blur); + + this._pipeline_choose_row.set_visible(is_static_blur); + this._sigma_row.set_visible(!is_static_blur); + this._brightness_row.set_visible(!is_static_blur); + } +});
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/menu.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/menu.js new file mode 100644 index 0000000..899fdcf --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/menu.js @@ -0,0 +1,68 @@ +import Gdk from 'gi://Gdk'; +import Gtk from 'gi://Gtk'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; + + +export function addMenu(window) { + const builder = new Gtk.Builder(); + + // add a dummy page and remove it immediately, to access headerbar + builder.add_from_file(GLib.filename_from_uri(GLib.uri_resolve_relative(import.meta.url, '../ui/menu.ui', GLib.UriFlags.NONE))[0]); + let menu_util = builder.get_object('menu_util'); + window.add(menu_util); + try { + addMenuToHeader(window, builder); + } catch (error) { + // could not add menu... not so bad + } + window.remove(menu_util); +} + +function addMenuToHeader(window, builder) { + // a little hack to get to the headerbar + const page = builder.get_object('menu_util'); + const pages_stack = page.get_parent(); // AdwViewStack + const content_stack = pages_stack.get_parent().get_parent(); // GtkStack + const preferences = content_stack.get_parent(); // GtkBox + const headerbar = preferences.get_first_child().get_next_sibling() + .get_first_child().get_first_child().get_first_child(); // AdwHeaderBar + headerbar.pack_start(builder.get_object('info_menu')); + + // setup menu actions + const actionGroup = new Gio.SimpleActionGroup(); + window.insert_action_group('prefs', actionGroup); + + // a list of actions with their associated link + const actions = [ + { + name: 'open-bug-report', + link: 'https://github.com/aunetx/blur-my-shell/issues' + }, + { + name: 'open-readme', + link: 'https://github.com/aunetx/blur-my-shell' + }, + { + name: 'open-license', + link: 'https://github.com/aunetx/blur-my-shell/blob/master/LICENSE' + }, + { + name: 'donate-github', + link: 'https://github.com/sponsors/aunetx' + }, + { + name: 'donate-kofi', + link: 'https://ko-fi.com/aunetx' + }, + ]; + + actions.forEach(action => { + let act = new Gio.SimpleAction({ name: action.name }); + act.connect( + 'activate', + () => Gtk.show_uri(window, action.link, Gdk.CURRENT_TIME) + ); + actionGroup.add_action(act); + }); +} diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/other.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/other.js new file mode 100644 index 0000000..0fac364 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/other.js @@ -0,0 +1,86 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gio from 'gi://Gio'; + + +export const Other = GObject.registerClass({ + GTypeName: 'Other', + Template: GLib.uri_resolve_relative(import.meta.url, '../ui/other.ui', GLib.UriFlags.NONE), + InternalChildren: [ + 'lockscreen_blur', + 'lockscreen_pipeline_choose_row', + + 'screenshot_blur', + 'screenshot_pipeline_choose_row', + + 'window_list_blur', + 'window_list_sigma', + 'window_list_brightness', + + 'coverflow_alt_tab_blur', + 'coverflow_alt_tab_pipeline_choose_row', + + 'hack_level', + 'debug', + 'reset' + ], +}, class Overview extends Adw.PreferencesPage { + constructor(preferences, pipelines_manager, pipelines_page) { + super({}); + + this.preferences = preferences; + this.pipelines_manager = pipelines_manager; + this.pipelines_page = pipelines_page; + + this.preferences.lockscreen.settings.bind( + 'blur', this._lockscreen_blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + this._lockscreen_pipeline_choose_row.initialize( + this.preferences.lockscreen, this.pipelines_manager, this.pipelines_page + ); + + this.preferences.screenshot.settings.bind( + 'blur', this._screenshot_blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + this._screenshot_pipeline_choose_row.initialize( + this.preferences.screenshot, this.pipelines_manager, this.pipelines_page + ); + + this.preferences.window_list.settings.bind( + 'blur', this._window_list_blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.window_list.settings.bind( + 'sigma', this._window_list_sigma, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.window_list.settings.bind( + 'brightness', this._window_list_brightness, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + + this.preferences.coverflow_alt_tab.settings.bind( + 'blur', this._coverflow_alt_tab_blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this._coverflow_alt_tab_pipeline_choose_row.initialize( + this.preferences.coverflow_alt_tab, this.pipelines_manager, this.pipelines_page + ); + + this.preferences.settings.bind( + 'hacks-level', this._hack_level, 'selected', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.settings.bind( + 'debug', this._debug, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + this._reset.connect('clicked', () => this.preferences.reset()); + } +});
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/overview.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/overview.js new file mode 100644 index 0000000..f6fe592 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/overview.js @@ -0,0 +1,59 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gio from 'gi://Gio'; + + +export const Overview = GObject.registerClass({ + GTypeName: 'Overview', + Template: GLib.uri_resolve_relative(import.meta.url, '../ui/overview.ui', GLib.UriFlags.NONE), + InternalChildren: [ + 'overview_blur', + 'pipeline_choose_row', + 'overview_style_components', + + 'appfolder_blur', + 'appfolder_sigma', + 'appfolder_brightness', + 'appfolder_style_dialogs' + ], +}, class Overview extends Adw.PreferencesPage { + constructor(preferences, pipelines_manager, pipelines_page) { + super({}); + + this.preferences = preferences; + this.pipelines_manager = pipelines_manager; + this.pipelines_page = pipelines_page; + + this.preferences.overview.settings.bind( + 'blur', this._overview_blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + this._pipeline_choose_row.initialize( + this.preferences.overview, this.pipelines_manager, this.pipelines_page + ); + + this.preferences.overview.settings.bind( + 'style-components', this._overview_style_components, 'selected', + Gio.SettingsBindFlags.DEFAULT + ); + + this.preferences.appfolder.settings.bind( + 'blur', this._appfolder_blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.appfolder.settings.bind( + 'sigma', this._appfolder_sigma, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.appfolder.settings.bind( + 'brightness', this._appfolder_brightness, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.appfolder.settings.bind( + 'style-dialogs', this._appfolder_style_dialogs, 'selected', + Gio.SettingsBindFlags.DEFAULT + ); + } +});
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/panel.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/panel.js new file mode 100644 index 0000000..c49f323 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/panel.js @@ -0,0 +1,102 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gio from 'gi://Gio'; + + +export const Panel = GObject.registerClass({ + GTypeName: 'Panel', + Template: GLib.uri_resolve_relative(import.meta.url, '../ui/panel.ui', GLib.UriFlags.NONE), + InternalChildren: [ + 'blur', + 'pipeline_choose_row', + 'mode_static', + 'mode_dynamic', + 'sigma_row', + 'sigma', + 'brightness_row', + 'brightness', + 'unblur_in_overview', + 'force_light_text', + 'override_background', + 'style_panel', + 'override_background_dynamically', + 'hidetopbar_compatibility', + 'dtp_blur_original_panel' + ], +}, class Panel extends Adw.PreferencesPage { + constructor(preferences, pipelines_manager, pipelines_page) { + super({}); + + this.preferences = preferences; + this.pipelines_manager = pipelines_manager; + this.pipelines_page = pipelines_page; + + this.preferences.panel.settings.bind( + 'blur', this._blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + this._pipeline_choose_row.initialize( + this.preferences.panel, this.pipelines_manager, this.pipelines_page + ); + + this.change_blur_mode(this.preferences.panel.STATIC_BLUR, true); + + this._mode_static.connect('toggled', + () => this.preferences.panel.STATIC_BLUR = this._mode_static.active + ); + this.preferences.panel.STATIC_BLUR_changed( + () => this.change_blur_mode(this.preferences.panel.STATIC_BLUR, false) + ); + + this.preferences.panel.settings.bind( + 'sigma', this._sigma, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'brightness', this._brightness, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'unblur-in-overview', this._unblur_in_overview, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'force-light-text', this._force_light_text, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'override-background', + this._override_background, 'enable-expansion', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'style-panel', this._style_panel, 'selected', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'override-background-dynamically', + this._override_background_dynamically, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.hidetopbar.settings.bind( + 'compatibility', this._hidetopbar_compatibility, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.dash_to_panel.settings.bind( + 'blur-original-panel', this._dtp_blur_original_panel, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + } + + change_blur_mode(is_static_blur, first_run) { + this._mode_static.set_active(is_static_blur); + if (first_run) + this._mode_dynamic.set_active(!is_static_blur); + + this._pipeline_choose_row.set_visible(is_static_blur); + this._sigma_row.set_visible(!is_static_blur); + this._brightness_row.set_visible(!is_static_blur); + } +});
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines.js new file mode 100644 index 0000000..158ea9a --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines.js @@ -0,0 +1,98 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import { gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; + +import { PipelineGroup } from './pipelines_management/pipeline_group.js'; +import { EffectsDialog } from './pipelines_management/effects_dialog.js'; + + +export const Pipelines = GObject.registerClass({ + GTypeName: 'Pipelines', + Template: GLib.uri_resolve_relative(import.meta.url, '../ui/pipelines.ui', GLib.UriFlags.NONE), + InternalChildren: [ + 'add_pipeline' + ], +}, class Pipelines extends Adw.PreferencesPage { + constructor(preferences, pipelines_manager, window) { + super({}); + + this.preferences = preferences; + this.pipelines_manager = pipelines_manager; + this.window = window; + + this.pipelines_map = new Map; + + for (let pipeline_id in this.pipelines_manager.pipelines) + this.add_pipeline(pipeline_id, false); + + this.preferences.connect('reset', _ => { + this.pipelines_map.forEach((_infos, pid) => this.remove_pipeline(pid)); + for (let pipeline_id in this.pipelines_manager.pipelines) + this.add_pipeline(pipeline_id, false); + }); + + this._add_pipeline.connect( + "clicked", + () => this.pipelines_manager.create_pipeline(_("New pipeline")) + ); + + this.pipelines_manager.connect( + "pipeline-created", + (_obj, id, _pipeline) => this.add_pipeline(id, true) + ); + } + + add_pipeline(pipeline_id, scroll_to_bottom) { + let pipeline = this.pipelines_manager.pipelines[pipeline_id]; + let pipeline_group = new PipelineGroup( + this.pipelines_manager, pipeline_id, pipeline, this + ); + + let pipeline_destroyed_id = this.pipelines_manager.connect( + pipeline_id + "::pipeline-destroyed", + () => this.remove_pipeline(pipeline_id) + ); + + let pipeline_renamed_id = this.pipelines_manager.connect( + pipeline_id + "::pipeline-renamed", + (_obj, name) => this.rename_pipeline(pipeline_id, name) + ); + + this.pipelines_map.set(pipeline_id, { + pipeline_group, pipeline_destroyed_id, pipeline_renamed_id + }); + + this.add(pipeline_group); + + // scroll to the bottom of the page + if (scroll_to_bottom) { + this.window.set_visible_page(this); + setTimeout(() => { + const scroll_adjustment = this.get_first_child().get_vadjustment(); + scroll_adjustment.value = scroll_adjustment.get_upper(); + }, 10); + pipeline_group._title.grab_focus(); + } + } + + remove_pipeline(pipeline_id) { + let pipeline_infos = this.pipelines_map.get(pipeline_id); + if (pipeline_infos) { + this.pipelines_manager.disconnect(pipeline_infos.pipeline_destroyed_id); + this.remove(pipeline_infos.pipeline_group); + this.pipelines_map.delete(pipeline_id); + } + } + + rename_pipeline(pipeline_id, name) { + let pipeline_infos = this.pipelines_map.get(pipeline_id); + if (pipeline_infos) + pipeline_infos.pipeline_group.set_title(name.length > 0 ? name : " "); + } + + open_effects_dialog(pipeline_id) { + let dialog = new EffectsDialog(this.pipelines_manager, pipeline_id); + dialog.present(this.window); + } +});
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/effect_row.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/effect_row.js new file mode 100644 index 0000000..130edfd --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/effect_row.js @@ -0,0 +1,222 @@ +import Adw from 'gi://Adw'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; +import { gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; + +import { get_supported_effects } from '../../effects/effects.js'; + + +export const EffectRow = GObject.registerClass({ + GTypeName: 'EffectRow', + InternalChildren: [], +}, class EffectRow extends Adw.ExpanderRow { + constructor(effect, effects_dialog) { + super({}); + + this.SUPPORTED_EFFECTS = get_supported_effects(_); + + this.effect = effect; + this.effects_dialog = effects_dialog; + this.pipeline_id = effects_dialog.pipeline_id; + this.pipelines_manager = effects_dialog.pipelines_manager; + + if (effect.type in this.SUPPORTED_EFFECTS) { + this.set_title(this.SUPPORTED_EFFECTS[effect.type].name); + this.set_subtitle(this.SUPPORTED_EFFECTS[effect.type].description); + this.populate_options(); + } + else { + this._warn(`could not assign effect ${effect.type} to its correct name`); + this.set_title(effect.type); + } + + let prefix_bin = new Gtk.Box({ + spacing: 6 + }); + this.add_prefix(prefix_bin); + + let move_bin = new Gtk.Box({ + orientation: Gtk.Orientation.VERTICAL, + 'width-request': 38, + 'height-request': 38, + 'margin-top': 6, + 'margin-bottom': 6 + }); + prefix_bin.append(move_bin); + move_bin.add_css_class('linked'); + + this._move_up_button = new Gtk.Button({ + 'icon-name': 'go-up-symbolic', + 'width-request': 38, + 'height-request': 19 + }); + this._move_down_button = new Gtk.Button({ + 'icon-name': 'go-down-symbolic', + 'width-request': 38, + 'height-request': 19 + }); + this._move_up_button.add_css_class('flat'); + this._move_down_button.add_css_class('flat'); + move_bin.append(this._move_up_button); + move_bin.append(this._move_down_button); + + this._move_up_button.connect('clicked', () => effects_dialog.move_row_by(this, -1)); + this._move_down_button.connect('clicked', () => effects_dialog.move_row_by(this, +1)); + + let remove_button = new Gtk.Button({ + 'icon-name': 'remove-row-symbolic', + 'width-request': 38, + 'height-request': 38, + 'margin-top': 6, + 'margin-bottom': 6, + 'valign': Gtk.Align.CENTER + }); + prefix_bin.append(remove_button); + remove_button.add_css_class('destructive-action'); + + remove_button.connect('clicked', () => effects_dialog.remove_row(this)); + } + + populate_options() { + const editable_params = this.SUPPORTED_EFFECTS[this.effect.type].editable_params; + + if (Object.keys(editable_params).length == 0) + this.enable_expansion = false; + + for (const param_key in editable_params) { + let param = editable_params[param_key]; + let row; + switch (param.type) { + case "integer": + row = new Adw.SpinRow({ + adjustment: new Gtk.Adjustment({ + lower: param.min, + upper: param.max, + step_increment: param.increment + }) + }); + row.adjustment.set_value(this.get_effect_param(param_key)); + row.adjustment.connect( + 'value-changed', () => this.set_effect_param(param_key, row.adjustment.value) + ); + break; + + case "float": + row = new Adw.ActionRow; + let scale = new Gtk.Scale({ + valign: Gtk.Align.CENTER, + hexpand: true, + width_request: 200, + draw_value: true, + value_pos: Gtk.PositionType.RIGHT, + digits: param.digits, + adjustment: new Gtk.Adjustment({ + lower: param.min, + upper: param.max, + step_increment: param.increment, + page_increment: param.big_increment + }) + }); + // TODO check if it's a good idea to set the default parameter, as the "good" + // value really change depending on the user wallpaper... if so, do for dynamic + // blur too + scale.add_mark( + this.get_default_effect_param(param_key), Gtk.PositionType.BOTTOM, null + ); + row.add_suffix(scale); + scale.adjustment.set_value(this.get_effect_param(param_key)); + scale.adjustment.connect( + 'value-changed', () => this.set_effect_param(param_key, scale.adjustment.value) + ); + break; + + case "boolean": + row = new Adw.SwitchRow; + row.set_active(this.get_effect_param(param_key)); + row.connect( + 'notify::active', () => this.set_effect_param(param_key, row.active) + ); + break; + + case "dropdown": + row = new Adw.ComboRow({ model: new Gtk.StringList }); + param.options.forEach(option => row.model.append(option)); + row.selected = this.get_effect_param(param_key); + row.connect( + 'notify::selected', () => this.set_effect_param(param_key, row.selected) + ); + break; + + case "rgba": + row = new Adw.ActionRow; + let color_button = new Gtk.ColorButton({ + valign: Gtk.Align.CENTER, + width_request: 75, + height_request: 45, + show_editor: true, + use_alpha: true + }); + row.add_suffix(color_button); + // set original color + let c = color_button.get_rgba().copy(); + [c.red, c.green, c.blue, c.alpha] = this.get_effect_param(param_key); + color_button.set_rgba(c); + // update on on 'color-set' + color_button.connect( + 'color-set', () => { + let c = color_button.get_rgba(); + this.set_effect_param(param_key, [c.red, c.green, c.blue, c.alpha]); + } + ); + break; + + default: + row = new Adw.ActionRow; + break; + } + row.set_title(param.name); + row.set_subtitle(param.description); + this.add_row(row); + } + } + + get_effect_param(key) { + let effects = this.pipelines_manager.pipelines[this.pipeline_id].effects; + const gsettings_effect = effects.find(e => e.id == this.effect.id); + + if ('params' in gsettings_effect && key in gsettings_effect.params) + return gsettings_effect.params[key]; + else + return this.get_default_effect_param(key); + } + + get_default_effect_param(key) { + return this.SUPPORTED_EFFECTS[this.effect.type].class.default_params[key]; + } + + set_effect_param(key, value) { + // we must pay attention not to change the effects in the pipelines manager before updating + // it in gsettings, else it won't be updated (or every effect will be) + let effects = this.pipelines_manager.pipelines[this.pipeline_id].effects; + const effect_index = effects.findIndex(e => e.id == this.effect.id); + + if (effect_index >= 0) { + effects[effect_index] = { + ...this.effect, params: { ...this.effect.params } + }; + effects[effect_index].params[key] = value; + this.effect = effects[effect_index]; + } + else + this._warn(`effect not found when setting key ${key}`); + + this.pipelines_manager.update_pipeline_effects(this.pipeline_id, effects, false); + } + + _warn(str) { + console.warn( + `[Blur my Shell > effect row] pipeline '${this.pipeline_id}',` + + ` effect '${this.effect.id}': ${str}` + ); + } +}); diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/effects_dialog.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/effects_dialog.js new file mode 100644 index 0000000..222a92e --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/effects_dialog.js @@ -0,0 +1,174 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; +import Gio from 'gi://Gio'; +import { gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; + +import { EffectRow } from './effect_row.js'; +import { get_effects_groups, get_supported_effects } from '../../effects/effects.js'; + +export const EffectsDialog = GObject.registerClass({ + GTypeName: 'EffectsDialog', + Template: GLib.uri_resolve_relative(import.meta.url, '../../ui/effects-dialog.ui', GLib.UriFlags.NONE), + InternalChildren: [ + "add_effect", + "add_effect_alt_menu", + "effects_list" + ], +}, class EffectsDialog extends Adw.PreferencesDialog { + constructor(pipelines_manager, pipeline_id) { + super({}); + + this.EFFECTS_GROUPS = get_effects_groups(_); + this.SUPPORTED_EFFECTS = get_supported_effects(_); + + this.pipelines_manager = pipelines_manager; + this.pipeline_id = pipeline_id; + + let pipeline = pipelines_manager.pipelines[pipeline_id]; + + this.set_title(pipeline.name.length > 0 ? _(`Effects for "${pipeline.name}"`) : _("Effects")); + + pipeline.effects.forEach(effect => { + const effect_row = new EffectRow(effect, this); + this._effects_list.add(effect_row); + this.update_rows_insensitive_mover(effect_row); + }); + + // setup advanced effects chooser action + this.show_advanced_effects = false; + let action_group = new Gio.SimpleActionGroup(); + this.insert_action_group('effects-dialog', action_group); + let advanced_effects_action = Gio.SimpleAction.new_stateful( + 'advanced-effects-bool', + null, + GLib.Variant.new_boolean(this.show_advanced_effects) + ); + advanced_effects_action.connect( + 'change-state', + (_, state) => { + this.show_advanced_effects = state.get_boolean(); + this.build_effects_chooser(); + advanced_effects_action.set_state(state); + } + ); + action_group.add_action(advanced_effects_action); + + this.build_effects_chooser(); + this._add_effect.connect('clicked', () => this.effects_chooser_dialog.present(this)); + } + + build_effects_chooser() { + this.effects_chooser_dialog = new Adw.Dialog({ + presentation_mode: Adw.DialogPresentationMode.BOTTOM_SHEET, + content_width: 450 + }); + + let page = new Adw.PreferencesPage; + this.effects_chooser_dialog.set_child(page); + + for (const effects_group in this.EFFECTS_GROUPS) { + const group_infos = this.EFFECTS_GROUPS[effects_group]; + + let group = new Adw.PreferencesGroup({ + title: group_infos.name + }); + page.add(group); + + for (const effect_type of group_infos.contains) { + if (!(effect_type in this.SUPPORTED_EFFECTS)) + continue; + + if (!this.show_advanced_effects && this.SUPPORTED_EFFECTS[effect_type].is_advanced) + continue; + + let action_row = new Adw.ActionRow({ + title: this.SUPPORTED_EFFECTS[effect_type].name, + subtitle: this.SUPPORTED_EFFECTS[effect_type].description + }); + let select_button = new Gtk.Button({ + 'icon-name': 'select-row-symbolic', + 'width-request': 38, + 'height-request': 38, + 'margin-top': 6, + 'margin-bottom': 6 + }); + group.add(action_row); + + select_button.add_css_class('flat'); + action_row.add_suffix(select_button); + action_row.set_activatable_widget(select_button); + select_button.connect('clicked', () => { + this.append_effect(effect_type); + this.effects_chooser_dialog.close(); + }); + } + } + } + + append_effect(effect_type) { + const effect = { + type: effect_type, id: "effect_" + ("" + Math.random()).slice(2, 16) + }; + this.pipelines_manager.update_pipeline_effects( + this.pipeline_id, + [...this.pipelines_manager.pipelines[this.pipeline_id].effects, effect] + ); + + const effect_row = new EffectRow(effect, this); + this._effects_list.add(effect_row); + this.move_row_by(effect_row, 0); + this.update_rows_insensitive_mover(effect_row); + } + + move_row_by(row, number) { + const effects = this.pipelines_manager.pipelines[this.pipeline_id].effects; + const effect_index = effects.findIndex(e => e.id == row.effect.id); + + if (effect_index >= 0) { + effects.splice(effect_index, 1); + effects.splice(effect_index + number, 0, row.effect); + + const listbox = row.get_parent(); + listbox.set_sort_func((row_a, row_b) => { + const id_a = effects.findIndex(e => e.id == row_a.effect.id); + const id_b = effects.findIndex(e => e.id == row_b.effect.id); + return id_a > id_b; + }); + + this.update_rows_insensitive_mover(row); + + this.pipelines_manager.update_pipeline_effects( + this.pipeline_id, effects + ); + } + } + + update_rows_insensitive_mover(any_row) { + if (this._insensitive_top) + this._insensitive_top.set_sensitive(true); + if (this._insensitive_bottom) + this._insensitive_bottom.set_sensitive(true); + + const listbox = any_row.get_parent(); + this._insensitive_top = listbox.get_first_child()._move_up_button; + this._insensitive_top?.set_sensitive(false); + this._insensitive_bottom = listbox.get_last_child()._move_down_button; + this._insensitive_bottom?.set_sensitive(false); + } + + remove_row(row) { + const effects = this.pipelines_manager.pipelines[this.pipeline_id].effects; + const effect_index = effects.findIndex(e => e.id == row.effect.id); + + if (effect_index >= 0) { + effects.splice(effect_index, 1); + this.pipelines_manager.update_pipeline_effects( + this.pipeline_id, effects + ); + } + + this._effects_list.remove(row); + } +}); diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_choose_row.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_choose_row.js new file mode 100644 index 0000000..e0c5165 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_choose_row.js @@ -0,0 +1,106 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; +import { gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; + + +export const PipelineChooseRow = GObject.registerClass({ + GTypeName: 'PipelineChooseRow', + Template: GLib.uri_resolve_relative(import.meta.url, '../../ui/pipeline-choose-row.ui', GLib.UriFlags.NONE), + InternalChildren: [ + 'pipeline_choose', + 'pipeline_model', + 'pipeline_edit' + ], +}, class PipelineChooseRow extends Adw.ActionRow { + initialize(preferences, pipelines_manager, pipelines_page) { + this.preferences = preferences; + this.pipelines_manager = pipelines_manager; + this.pipelines_page = pipelines_page; + + this.create_pipelines_list(); + + // display the correct pipeline name in the drop-down instead of their ids + const closure_func = string_object => { + const pipeline_id = string_object.get_string(); + if (pipeline_id == 'create_new') + return _("Create new pipeline"); + if (pipeline_id in this.pipelines_manager.pipelines) + return this.pipelines_manager.pipelines[pipeline_id].name; + else + return ""; + }; + + const expression = new Gtk.ClosureExpression(GObject.TYPE_STRING, closure_func, []); + this._pipeline_choose.expression = expression; + + // TODO fix the expression not being re-evaluated other than by setting it again + this.pipelines_manager.connect( + 'pipeline-names-changed', + () => this._pipeline_choose.expression = new Gtk.ClosureExpression( + GObject.TYPE_STRING, closure_func, [] + ) + ); + + this.preferences.PIPELINE_changed(() => this.on_settings_pipeline_changed()); + + this.pipelines_manager.connect('pipeline-list-changed', () => this.create_pipelines_list()); + + this._pipeline_choose.connect('notify::selected', () => this.on_selected_pipeline_changed()); + + this._pipeline_edit.connect( + 'clicked', + () => this.pipelines_page.open_effects_dialog(this.preferences.PIPELINE) + ); + } + + on_selected_pipeline_changed() { + if (!this._pipeline_choose.selected_item || this._is_creating_pipelines_list) + return; + + const pipeline_id = this._pipeline_choose.selected_item.get_string(); + if (pipeline_id == 'create_new') { + const id = this.pipelines_manager.create_pipeline(_("New pipeline")); + this.preferences.PIPELINE = id; + } + else + this.preferences.PIPELINE = pipeline_id; + } + + on_settings_pipeline_changed() { + for (let i = 0; i < this._pipeline_model.n_items; i++) { + const pipeline_id = this._pipeline_model.get_string(i); + // if we have more pipelines than we should have: rebuild... + // that is the case when resetting the preferences for example + if (!(pipeline_id in this.pipelines_manager)) { + this.create_pipelines_list(); + return; + } + if (pipeline_id == this.preferences.PIPELINE) + this._pipeline_choose.set_selected(i); + } + } + + create_pipelines_list() { + // prevent the pipeline selector from being updated while re-creating the list + this._is_creating_pipelines_list = true; + + // remove ancient items + this._pipeline_model.splice(0, this._pipeline_model.n_items, null); + + // add new ones + let i = 0; + for (let pipeline_id in this.pipelines_manager.pipelines) { + this._pipeline_model.append(pipeline_id); + if (pipeline_id == this.preferences.PIPELINE) + this._pipeline_choose.set_selected(i); + i++; + } + this._pipeline_model.append('create_new'); + + // now update the drop-down selector + this._is_creating_pipelines_list = false; + this.on_selected_pipeline_changed(); + } +});
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_group.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_group.js new file mode 100644 index 0000000..627b576 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_group.js @@ -0,0 +1,99 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; +import { gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; + +import { get_supported_effects } from '../../effects/effects.js'; + + +export const PipelineGroup = GObject.registerClass({ + GTypeName: 'PipelineGroup', + Template: GLib.uri_resolve_relative(import.meta.url, '../../ui/pipeline-group.ui', GLib.UriFlags.NONE), + InternalChildren: [ + "title", + "effects_description_row", + "manage_effects" + ], +}, class PipelineGroup extends Adw.PreferencesGroup { + constructor(pipelines_manager, pipeline_id, pipeline, pipelines_page) { + super({}); + + this.SUPPORTED_EFFECTS = get_supported_effects(_); + + this._pipelines_manager = pipelines_manager; + this._pipelines_page = pipelines_page; + this._pipeline_id = pipeline_id; + + // set the description + this.set_description(_(`Pipeline id: "${pipeline_id}"`)); + + // set the title and connect it to the text entry + this.set_title(pipeline.name.length > 0 ? pipeline.name : " "); + this._title.set_text(pipeline.name); + this._title.connect( + 'changed', + () => pipelines_manager.rename_pipeline(pipeline_id, this._title.get_text()) + ); + + // the bin containing the actions + let prefix_bin = new Gtk.Box; + prefix_bin.add_css_class('linked'); + this._title.add_prefix(prefix_bin); + + // add a 'remove' button if we are not the default pipeline + if (pipeline_id != "pipeline_default") { + let remove_button = new Gtk.Button({ + 'icon-name': 'remove-row-symbolic', + 'width-request': 38, + 'height-request': 38, + 'margin-top': 6, + 'margin-bottom': 6 + }); + remove_button.add_css_class('destructive-action'); + prefix_bin.append(remove_button); + remove_button.connect('clicked', () => pipelines_manager.delete_pipeline(pipeline_id)); + } + // add a 'duplicate' button + let duplicate_button = new Gtk.Button({ + 'icon-name': 'duplicate-row-symbolic', + 'width-request': 38, + 'height-request': 38, + 'margin-top': 6, + 'margin-bottom': 6 + }); + prefix_bin.append(duplicate_button); + duplicate_button.connect('clicked', () => pipelines_manager.duplicate_pipeline(pipeline_id)); + + this.update_effects_description_row(); + this._pipelines_manager.connect( + pipeline_id + '::pipeline-updated', + () => this.update_effects_description_row() + ); + + this._manage_effects.connect( + 'clicked', + () => pipelines_page.open_effects_dialog(pipeline_id) + ); + } + + update_effects_description_row() { + const effects = this._pipelines_manager.pipelines[this._pipeline_id].effects; + + if (effects.length == 0) + this._effects_description_row.set_title(_("No effect")); + else if (effects.length == 1) + this._effects_description_row.set_title(_("1 effect")); + else + this._effects_description_row.set_title(_(`${effects.length} effects`)); + + let subtitle = ""; + effects.forEach(effect => { + if (effect.type in this.SUPPORTED_EFFECTS) + subtitle += _(`${this.SUPPORTED_EFFECTS[effect.type].name}, `); + else + subtitle += _("Unknown effect, "); + }); + this._effects_description_row.set_subtitle(subtitle.slice(0, -2)); + } +}); |