indicator.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. "use strict";
  2. // Global modules
  3. const Lang = imports.lang;
  4. const St = imports.gi.St;
  5. const Main = imports.ui.main;
  6. const PanelMenu = imports.ui.panelMenu;
  7. const PopupMenu = imports.ui.popupMenu;
  8. // Internal modules
  9. const ExtensionUtils = imports.misc.extensionUtils;
  10. const Me = ExtensionUtils.getCurrentExtension();
  11. const PopupSliderMenuItem = Me.imports.popupSliderMenuItem.PopupSliderMenuItem;
  12. const Bundle = Me.imports.bundle;
  13. const Polygnome = Me.imports.polygnome;
  14. const Preview = Me.imports.preview;
  15. // Utilities
  16. const getWorkspaceWindowsArray = Polygnome.getWorkspaceWindowsArray;
  17. const spliceTitle = Bundle.spliceTitle;
  18. // Preview default values
  19. const MIN_ZOOM = Preview.MIN_ZOOM;
  20. const MAX_ZOOM = Preview.MAX_ZOOM;
  21. const MAX_CROP_RATIO = Preview.MAX_CROP_RATIO;
  22. const DEFAULT_ZOOM = Preview.DEFAULT_ZOOM;
  23. const DEFAULT_CROP_RATIO = Preview.DEFAULT_CROP_RATIO;
  24. var WindowCornerIndicator = new Lang.Class({
  25. Name: "WindowCornerPreview.indicator",
  26. Extends: PanelMenu.Button,
  27. _init: function() {
  28. this.parent(null, "WindowCornerPreview.indicator");
  29. },
  30. // Handler to turn preview on / off
  31. _onMenuIsEnabled: function(item) {
  32. (item.state) ? this.preview.show() : this.preview.hide();
  33. },
  34. _updateSliders: function() {
  35. this.menuZoom.value = this.preview.zoom;
  36. this.menuZoomLabel.label.set_text("Monitor Zoom: " + Math.floor(this.preview.zoom * 100).toString() + "%");
  37. this.menuLeftCrop.value = this.preview.leftCrop;
  38. this.menuRightCrop.value = this.preview.rightCrop;
  39. this.menuTopCrop.value = this.preview.topCrop;
  40. this.menuBottomCrop.value = this.preview.bottomCrop;
  41. },
  42. _onZoomChanged: function(source, value) {
  43. this.preview.zoom = value;
  44. this._updateSliders();
  45. this.preview.emit("zoom-changed");
  46. },
  47. _onLeftCropChanged: function(source, value) {
  48. this.preview.leftCrop = value;
  49. this._updateSliders();
  50. this.preview.emit("crop-changed");
  51. },
  52. _onRightCropChanged: function(source, value) {
  53. this.preview.rightCrop = value;
  54. this._updateSliders();
  55. this.preview.emit("crop-changed");
  56. },
  57. _onTopCropChanged: function(source, value) {
  58. this.preview.topCrop = value;
  59. this._updateSliders();
  60. this.preview.emit("crop-changed");
  61. },
  62. _onBottomCropChanged: function(source, value) {
  63. this.preview.bottomCrop = value;
  64. this._updateSliders();
  65. this.preview.emit("crop-changed");
  66. },
  67. _onSettings: function() {
  68. Main.Util.trySpawnCommandLine("gnome-shell-extension-prefs window-corner-preview@fabiomereu.it");
  69. },
  70. // Update windows list and other menus before menu pops up
  71. _onUserTriggered: function() {
  72. this.menuIsEnabled.setToggleState(this.preview.visible);
  73. this.menuIsEnabled.actor.reactive = this.preview.window;
  74. this._updateSliders()
  75. this.menuWindows.menu.removeAll();
  76. getWorkspaceWindowsArray().forEach(function(workspace, i) {
  77. if (i > 0) {
  78. this.menuWindows.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
  79. }
  80. // Populate window list on submenu
  81. workspace.windows.forEach(function(window) {
  82. let winMenuItem = new PopupMenu.PopupMenuItem(spliceTitle(window.get_title()));
  83. winMenuItem.connect("activate", Lang.bind(this, function() {
  84. this.preview.window = window;
  85. this.preview.show();
  86. }));
  87. this.menuWindows.menu.addMenuItem(winMenuItem);
  88. }, this);
  89. }, this);
  90. },
  91. enable: function() {
  92. // Add icon
  93. this.icon = new St.Icon({
  94. icon_name: "face-monkey-symbolic",
  95. style_class: "system-status-icon"
  96. });
  97. this.actor.add_actor(this.icon);
  98. // Prepare Menu...
  99. // 1. Preview ON/OFF
  100. this.menuIsEnabled = new PopupMenu.PopupSwitchMenuItem("Preview", false, {
  101. hover: false,
  102. reactive: true
  103. });
  104. this.menuIsEnabled.connect("toggled", Lang.bind(this, this._onMenuIsEnabled));
  105. this.menu.addMenuItem(this.menuIsEnabled);
  106. this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
  107. // 2. Windows list
  108. this.menuWindows = new PopupMenu.PopupSubMenuMenuItem("Windows");
  109. this.menu.addMenuItem(this.menuWindows);
  110. this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
  111. // 3a. Zoom label
  112. this.menuZoomLabel = new PopupMenu.PopupMenuItem("", {
  113. activate: false,
  114. reactive: false
  115. });
  116. this.menu.addMenuItem(this.menuZoomLabel);
  117. // 3b, Zoom slider
  118. this.menuZoom = new PopupSliderMenuItem(false, DEFAULT_ZOOM, MIN_ZOOM, MAX_ZOOM, 0.005); // slider step: 0.5%
  119. this.menuZoom.connect("value-changed", Lang.bind(this, this._onZoomChanged));
  120. this.menu.addMenuItem(this.menuZoom);
  121. // 4. Crop Sliders
  122. this.menuCrop = new PopupMenu.PopupSubMenuMenuItem("Crop");
  123. this.menu.addMenuItem(this.menuCrop);
  124. this.menuTopCrop = new PopupSliderMenuItem("Top", DEFAULT_CROP_RATIO, 0.0, MAX_CROP_RATIO);
  125. this.menuTopCrop.connect("value-changed", Lang.bind(this, this._onTopCropChanged));
  126. this.menuCrop.menu.addMenuItem(this.menuTopCrop);
  127. this.menuLeftCrop = new PopupSliderMenuItem("Left", DEFAULT_CROP_RATIO, 0.0, MAX_CROP_RATIO);
  128. this.menuLeftCrop.connect("value-changed", Lang.bind(this, this._onLeftCropChanged));
  129. this.menuCrop.menu.addMenuItem(this.menuLeftCrop);
  130. this.menuRightCrop = new PopupSliderMenuItem("Right", DEFAULT_CROP_RATIO, 0.0, MAX_CROP_RATIO);
  131. this.menuRightCrop.connect("value-changed", Lang.bind(this, this._onRightCropChanged));
  132. this.menuCrop.menu.addMenuItem(this.menuRightCrop);
  133. this.menuBottomCrop = new PopupSliderMenuItem("Bottom", DEFAULT_CROP_RATIO, 0.0, MAX_CROP_RATIO);
  134. this.menuBottomCrop.connect("value-changed", Lang.bind(this, this._onBottomCropChanged));
  135. this.menuCrop.menu.addMenuItem(this.menuBottomCrop);
  136. this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
  137. // 5. Settings
  138. this.menuSettings = new PopupMenu.PopupMenuItem("Settings");
  139. this.menuSettings.connect("activate", Lang.bind(this, this._onSettings));
  140. this.menu.addMenuItem(this.menuSettings);
  141. this.actor.connect("enter-event", Lang.bind(this, this._onUserTriggered));
  142. },
  143. disable: function() {
  144. this.menu.removeAll();
  145. }
  146. });