settings.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import GLib from 'gi://GLib';
  2. const Signals = imports.signals;
  3. /// An enum non-extensively describing the type of gsettings key.
  4. export const Type = {
  5. B: 'Boolean',
  6. I: 'Integer',
  7. D: 'Double',
  8. S: 'String',
  9. C: 'Color',
  10. AS: 'StringArray'
  11. };
  12. /// An object to get and manage the gsettings preferences.
  13. ///
  14. /// Should be initialized with an array of keys, for example:
  15. ///
  16. /// let settings = new Settings([
  17. /// { type: Type.I, name: "panel-corner-radius" },
  18. /// { type: Type.B, name: "debug" }
  19. /// ]);
  20. ///
  21. /// Each {type, name} object represents a gsettings key, which must be created
  22. /// in the gschemas.xml file of the extension.
  23. export const Settings = class Settings {
  24. constructor(keys, settings) {
  25. this.settings = settings;
  26. this.keys = keys;
  27. this.keys.forEach(bundle => {
  28. let component = this;
  29. let component_settings = settings;
  30. if (bundle.component !== "general") {
  31. let bundle_component = bundle.component.replaceAll('-', '_');
  32. this[bundle_component] = {
  33. settings: this.settings.get_child(bundle.component)
  34. };
  35. component = this[bundle_component];
  36. component_settings = settings.get_child(bundle.component);
  37. }
  38. bundle.schemas.forEach(key => {
  39. let property_name = this.get_property_name(key.name);
  40. switch (key.type) {
  41. case Type.B:
  42. Object.defineProperty(component, property_name, {
  43. get() {
  44. return component_settings.get_boolean(key.name);
  45. },
  46. set(v) {
  47. component_settings.set_boolean(key.name, v);
  48. }
  49. });
  50. break;
  51. case Type.I:
  52. Object.defineProperty(component, property_name, {
  53. get() {
  54. return component_settings.get_int(key.name);
  55. },
  56. set(v) {
  57. component_settings.set_int(key.name, v);
  58. }
  59. });
  60. break;
  61. case Type.D:
  62. Object.defineProperty(component, property_name, {
  63. get() {
  64. return component_settings.get_double(key.name);
  65. },
  66. set(v) {
  67. component_settings.set_double(key.name, v);
  68. }
  69. });
  70. break;
  71. case Type.S:
  72. Object.defineProperty(component, property_name, {
  73. get() {
  74. return component_settings.get_string(key.name);
  75. },
  76. set(v) {
  77. component_settings.set_string(key.name, v);
  78. }
  79. });
  80. break;
  81. case Type.C:
  82. Object.defineProperty(component, property_name, {
  83. // returns the array [red, blue, green, alpha] with
  84. // values between 0 and 1
  85. get() {
  86. let val = component_settings.get_value(key.name);
  87. return val.deep_unpack();
  88. },
  89. // takes an array [red, blue, green, alpha] with
  90. // values between 0 and 1
  91. set(v) {
  92. let val = new GLib.Variant("(dddd)", v);
  93. component_settings.set_value(key.name, val);
  94. }
  95. });
  96. break;
  97. case Type.AS:
  98. Object.defineProperty(component, property_name, {
  99. get() {
  100. let val = component_settings.get_value(key.name);
  101. return val.deep_unpack();
  102. },
  103. set(v) {
  104. let val = new GLib.Variant("as", v);
  105. component_settings.set_value(key.name, val);
  106. }
  107. });
  108. break;
  109. }
  110. component[property_name + '_reset'] = function () {
  111. return component_settings.reset(key.name);
  112. };
  113. component[property_name + '_changed'] = function (cb) {
  114. return component_settings.connect('changed::' + key.name, cb);
  115. };
  116. component[property_name + '_disconnect'] = function () {
  117. return component_settings.disconnect.apply(
  118. component_settings, arguments
  119. );
  120. };
  121. });
  122. });
  123. };
  124. /// Reset the preferences.
  125. reset() {
  126. this.keys.forEach(bundle => {
  127. let component = this;
  128. if (bundle.component !== "general") {
  129. let bundle_component = bundle.component.replaceAll('-', '_');
  130. component = this[bundle_component];
  131. }
  132. bundle.schemas.forEach(key => {
  133. let property_name = this.get_property_name(key.name);
  134. component[property_name + '_reset']();
  135. });
  136. });
  137. this.emit('reset', true);
  138. }
  139. /// From the gschema name, returns the name of the associated property on
  140. /// the Settings object.
  141. get_property_name(name) {
  142. return name.replaceAll('-', '_').toUpperCase();
  143. }
  144. /// Remove all connections managed by the Settings object, i.e. created with
  145. /// `settings.PROPERTY_changed(callback)`.
  146. disconnect_all_settings() {
  147. this.keys.forEach(bundle => {
  148. let component = this;
  149. if (bundle.component !== "general") {
  150. let bundle_component = bundle.component.replaceAll('-', '_');
  151. component = this[bundle_component];
  152. }
  153. bundle.schemas.forEach(key => {
  154. let property_name = this.get_property_name(key.name);
  155. component[property_name + '_disconnect']();
  156. });
  157. });
  158. }
  159. };
  160. Signals.addSignalMethods(Settings.prototype);