customize_row.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import Adw from 'gi://Adw';
  2. import GLib from 'gi://GLib';
  3. import GObject from 'gi://GObject';
  4. import Gio from 'gi://Gio';
  5. import Gtk from 'gi://Gtk';
  6. /// Given a component (described by its preferences node), a gschema key and
  7. /// a Gtk.ColorButton, binds everything transparently.
  8. let bind_color = function (component, key, widget) {
  9. let property_name = key.replaceAll('-', '_').toUpperCase();
  10. let parse_color = _ => {
  11. let [r, g, b, a] = component[property_name];
  12. let w = widget.rgba;
  13. w.red = r;
  14. w.green = g;
  15. w.blue = b;
  16. w.alpha = a;
  17. widget.rgba = w;
  18. };
  19. component.settings.connect('changed::' + key, parse_color);
  20. widget.connect('color-set', _ => {
  21. let c = widget.rgba;
  22. component[property_name] = [c.red, c.green, c.blue, c.alpha];
  23. });
  24. parse_color();
  25. };
  26. export const CustomizeRow = GObject.registerClass({
  27. GTypeName: 'CustomizeRow',
  28. Template: GLib.uri_resolve_relative(import.meta.url, '../ui/customize-row.ui', GLib.UriFlags.NONE),
  29. InternalChildren: [
  30. 'sigma',
  31. 'brightness',
  32. 'color',
  33. 'color_row',
  34. 'noise_amount',
  35. 'noise_amount_row',
  36. 'noise_lightness',
  37. 'noise_lightness_row',
  38. 'noise_color_notice'
  39. ],
  40. }, class CustomizeRow extends Adw.ExpanderRow {
  41. /// Makes the required connections between the widgets and the preferences.
  42. ///
  43. /// This function may be bound to another object than CustomizeRow, if we
  44. /// are using it for the General page; some things will then change (no
  45. /// expansion row, and no notice)
  46. ///
  47. /// The color_and_noise parameter is either a boolean (true by default) or
  48. /// a widget; and permits selecting weather or not we want to show the color
  49. /// and noise buttons to the user. If it is a widget, it means we need to
  50. /// dynamically update their visibility, according to the widget's state.
  51. connect_to(settings, component_settings, color_and_noise = true) {
  52. let s = component_settings.settings;
  53. // is not fired if in General page
  54. if (this instanceof CustomizeRow)
  55. // bind the customize button
  56. s.bind(
  57. 'customize', this, 'enable-expansion',
  58. Gio.SettingsBindFlags.DEFAULT
  59. );
  60. // bind sigma and brightness
  61. s.bind(
  62. 'sigma', this._sigma, 'value',
  63. Gio.SettingsBindFlags.DEFAULT
  64. );
  65. s.bind(
  66. 'brightness', this._brightness, 'value',
  67. Gio.SettingsBindFlags.DEFAULT
  68. );
  69. // bind the color button
  70. bind_color(component_settings, 'color', this._color);
  71. // bind noise sliders
  72. s.bind(
  73. 'noise-amount', this._noise_amount, 'value',
  74. Gio.SettingsBindFlags.DEFAULT
  75. );
  76. s.bind(
  77. 'noise-lightness', this._noise_lightness, 'value',
  78. Gio.SettingsBindFlags.DEFAULT
  79. );
  80. // color_and_noise is either a boolean or a widget, if true, or it is a
  81. // widget, this will appropriately show the required preferences about
  82. // setting the color and noise
  83. if (color_and_noise) {
  84. // if we gave the static_blur widget, we are dealing with the panel,
  85. // and binding it to enable/disable the required components when
  86. // switching between static and dynamic blur
  87. if (color_and_noise instanceof Gtk.Switch) {
  88. // bind its state to dynamically toggle the notice and rows
  89. color_and_noise.bind_property(
  90. 'active', this._color_row, 'visible',
  91. GObject.BindingFlags.SYNC_CREATE
  92. );
  93. color_and_noise.bind_property(
  94. 'active', this._noise_amount_row, 'visible',
  95. GObject.BindingFlags.SYNC_CREATE
  96. );
  97. color_and_noise.bind_property(
  98. 'active', this._noise_lightness_row, 'visible',
  99. GObject.BindingFlags.SYNC_CREATE
  100. );
  101. color_and_noise.bind_property(
  102. 'active', this._noise_color_notice, 'visible',
  103. GObject.BindingFlags.INVERT_BOOLEAN
  104. );
  105. // only way to get the correct state when first opening the
  106. // window...
  107. setTimeout(_ => {
  108. let is_visible = color_and_noise.active;
  109. this._color_row.visible = is_visible;
  110. this._noise_amount_row.visible = is_visible;
  111. this._noise_lightness_row.visible = is_visible;
  112. this._noise_color_notice.visible = !is_visible;
  113. }, 10);
  114. }
  115. // if in General page, there is no notice at all
  116. if (this instanceof CustomizeRow) {
  117. // disable the notice
  118. this._noise_color_notice.visible = false;
  119. }
  120. } else {
  121. // enable the notice and disable color and noise preferences
  122. this._color_row.visible = false;
  123. this._noise_amount_row.visible = false;
  124. this._noise_lightness_row.visible = false;
  125. this._noise_color_notice.visible = true;
  126. }
  127. // now we bind the color-and-noise preference to the sensitivity of the
  128. // associated widgets, this will grey them out if the user choose not to
  129. // have color and noise enabled
  130. // note: I would love to bind to the visibility instead, but this part
  131. // is already dirty enough, it would look like I obfuscate my code
  132. // intentionally... (I am not)
  133. settings.settings.bind(
  134. 'color-and-noise',
  135. this._color_row, 'sensitive',
  136. Gio.SettingsBindFlags.DEFAULT
  137. );
  138. settings.settings.bind(
  139. 'color-and-noise',
  140. this._noise_amount_row, 'sensitive',
  141. Gio.SettingsBindFlags.DEFAULT
  142. );
  143. settings.settings.bind(
  144. 'color-and-noise',
  145. this._noise_lightness_row, 'sensitive',
  146. Gio.SettingsBindFlags.DEFAULT
  147. );
  148. };
  149. });