From 2b57603271ce0bbd79aa341ac452d5888e1e4853 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Sun, 20 Nov 2011 14:10:48 +0100 Subject: [PATCH] Port PopupMenu to new Lang.Class framework The Lang module in gjs has recently gained a small yet powerful Class framework, that should help improve the readability of code when using complex inheritance. This commit starts porting shell code, by rewriting all classes in popupMenu.js (and all derived classes) to Lang.Class. https://bugzilla.gnome.org/show_bug.cgi?id=664436 --- js/ui/appDisplay.js | 13 +-- js/ui/popupMenu.js | 196 +++++++++++++++------------------------ js/ui/shellEntry.js | 17 ++-- js/ui/status/keyboard.js | 16 ++-- js/ui/status/network.js | 45 ++++----- js/ui/status/power.js | 13 +-- js/ui/userMenu.js | 47 ++++------ 7 files changed, 136 insertions(+), 211 deletions(-) diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js index ec86c37db..98f16e8b7 100644 --- a/js/ui/appDisplay.js +++ b/js/ui/appDisplay.js @@ -623,19 +623,16 @@ AppWellIcon.prototype = { }; Signals.addSignalMethods(AppWellIcon.prototype); -function AppIconMenu(source) { - this._init(source); -} - -AppIconMenu.prototype = { - __proto__: PopupMenu.PopupMenu.prototype, +const AppIconMenu = new Lang.Class({ + Name: 'AppIconMenu', + Extends: PopupMenu.PopupMenu, _init: function(source) { let side = St.Side.LEFT; if (St.Widget.get_default_direction() == St.TextDirection.RTL) side = St.Side.RIGHT; - PopupMenu.PopupMenu.prototype._init.call(this, source.actor, 0.5, side); + this.parent(source.actor, 0.5, side); // We want to keep the item hovered while the menu is up this.blockSourceEvents = true; @@ -723,5 +720,5 @@ AppIconMenu.prototype = { } this.close(); } -}; +}); Signals.addSignalMethods(AppIconMenu.prototype); diff --git a/js/ui/popupMenu.js b/js/ui/popupMenu.js index 6aee9f419..a8d3384f6 100644 --- a/js/ui/popupMenu.js +++ b/js/ui/popupMenu.js @@ -26,11 +26,9 @@ function _ensureStyle(actor) { actor.ensure_style(); } -function PopupBaseMenuItem(params) { - this._init(params); -} +const PopupBaseMenuItem = new Lang.Class({ + Name: 'PopupBaseMenuItem', -PopupBaseMenuItem.prototype = { _init: function (params) { params = Params.parse (params, { reactive: true, activate: true, @@ -377,33 +375,27 @@ PopupBaseMenuItem.prototype = { x -= availWidth + this._spacing; } } -}; +}); Signals.addSignalMethods(PopupBaseMenuItem.prototype); -function PopupMenuItem() { - this._init.apply(this, arguments); -} - -PopupMenuItem.prototype = { - __proto__: PopupBaseMenuItem.prototype, +const PopupMenuItem = new Lang.Class({ + Name: 'PopupMenuItem', + Extends: PopupBaseMenuItem, _init: function (text, params) { - PopupBaseMenuItem.prototype._init.call(this, params); + this.parent(params); this.label = new St.Label({ text: text }); this.addActor(this.label); } -}; +}); -function PopupSeparatorMenuItem() { - this._init(); -} - -PopupSeparatorMenuItem.prototype = { - __proto__: PopupBaseMenuItem.prototype, +const PopupSeparatorMenuItem = new Lang.Class({ + Name: 'PopupSeparatorMenuItem', + Extends: PopupBaseMenuItem, _init: function () { - PopupBaseMenuItem.prototype._init.call(this, { reactive: false }); + this.parent({ reactive: false }); this._drawingArea = new St.DrawingArea({ style_class: 'popup-separator-menu-item' }); this.addActor(this._drawingArea, { span: -1, expand: true }); @@ -429,22 +421,19 @@ PopupSeparatorMenuItem.prototype = { cr.rectangle(margin, gradientOffset, gradientWidth, gradientHeight); cr.fill(); } -}; +}); const PopupAlternatingMenuItemState = { DEFAULT: 0, ALTERNATIVE: 1 } -function PopupAlternatingMenuItem() { - this._init.apply(this, arguments); -} - -PopupAlternatingMenuItem.prototype = { - __proto__: PopupBaseMenuItem.prototype, +const PopupAlternatingMenuItem = new Lang.Class({ + Name: 'PopupAlternatingMenuItem', + Extends: PopupBaseMenuItem, _init: function(text, alternateText, params) { - PopupBaseMenuItem.prototype._init.call(this, params); + this.parent(params); this.actor.add_style_class_name('popup-alternating-menu-item'); this._text = text; @@ -530,17 +519,14 @@ PopupAlternatingMenuItem.prototype = { this._updateLabel(); } -}; +}); -function PopupSliderMenuItem() { - this._init.apply(this, arguments); -} - -PopupSliderMenuItem.prototype = { - __proto__: PopupBaseMenuItem.prototype, +const PopupSliderMenuItem = new Lang.Class({ + Name: 'PopupSliderMenuItem', + Extends: PopupBaseMenuItem, _init: function(value) { - PopupBaseMenuItem.prototype._init.call(this, { activate: false }); + this.parent({ activate: false }); this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent)); @@ -716,13 +702,11 @@ PopupSliderMenuItem.prototype = { } return false; } -}; +}); -function Switch() { - this._init.apply(this, arguments); -} +const Switch = new Lang.Class({ + Name: 'Switch', -Switch.prototype = { _init: function(state) { this.actor = new St.Bin({ style_class: 'toggle-switch' }); // Translators: this MUST be either "toggle-switch-us" @@ -745,17 +729,14 @@ Switch.prototype = { toggle: function() { this.setToggleState(!this.state); } -}; +}); -function PopupSwitchMenuItem() { - this._init.apply(this, arguments); -} - -PopupSwitchMenuItem.prototype = { - __proto__: PopupBaseMenuItem.prototype, +const PopupSwitchMenuItem = new Lang.Class({ + Name: 'PopupSwitchMenuItem', + Extends: PopupBaseMenuItem, _init: function(text, active, params) { - PopupBaseMenuItem.prototype._init.call(this, params); + this.parent(params); this.label = new St.Label({ text: text }); this._switch = new Switch(active); @@ -805,17 +786,14 @@ PopupSwitchMenuItem.prototype = { setToggleState: function(state) { this._switch.setToggleState(state); } -}; +}); -function PopupImageMenuItem() { - this._init.apply(this, arguments); -} - -PopupImageMenuItem.prototype = { - __proto__: PopupBaseMenuItem.prototype, +const PopupImageMenuItem = new Lang.Class({ + Name: 'PopupImageMenuItem', + Extends: PopupBaseMenuItem, _init: function (text, iconName, params) { - PopupBaseMenuItem.prototype._init.call(this, params); + this.parent(params); this.label = new St.Label({ text: text }); this.addActor(this.label); @@ -828,13 +806,12 @@ PopupImageMenuItem.prototype = { setIcon: function(name) { this._icon.icon_name = name; } -}; +}); -function PopupMenuBase() { - throw new TypeError('Trying to instantiate abstract class PopupMenuBase'); -} +const PopupMenuBase = new Lang.Class({ + Name: 'PopupMenuBase', + Abstract: true, -PopupMenuBase.prototype = { _init: function(sourceActor, styleClass) { this.sourceActor = sourceActor; @@ -1139,18 +1116,15 @@ PopupMenuBase.prototype = { this.emit('destroy'); } -}; +}); Signals.addSignalMethods(PopupMenuBase.prototype); -function PopupMenu() { - this._init.apply(this, arguments); -} - -PopupMenu.prototype = { - __proto__: PopupMenuBase.prototype, +const PopupMenu = new Lang.Class({ + Name: 'PopupMenu', + Extends: PopupMenuBase, _init: function(sourceActor, arrowAlignment, arrowSide) { - PopupMenuBase.prototype._init.call (this, sourceActor, 'popup-menu-content'); + this.parent(sourceActor, 'popup-menu-content'); this._arrowAlignment = arrowAlignment; this._arrowSide = arrowSide; @@ -1235,17 +1209,14 @@ PopupMenu.prototype = { this.isOpen = false; this.emit('open-state-changed', false); } -}; +}); -function PopupSubMenu() { - this._init.apply(this, arguments); -} - -PopupSubMenu.prototype = { - __proto__: PopupMenuBase.prototype, +const PopupSubMenu = new Lang.Class({ + Name: 'PopupSubMenu', + Extends: PopupMenuBase, _init: function(sourceActor, sourceArrow) { - PopupMenuBase.prototype._init.call(this, sourceActor); + this.parent(sourceActor); this._arrow = sourceArrow; this._arrow.rotation_center_z_gravity = Clutter.Gravity.CENTER; @@ -1400,7 +1371,7 @@ PopupSubMenu.prototype = { return false; } -}; +}); /** * PopupMenuSection: @@ -1410,15 +1381,12 @@ PopupSubMenu.prototype = { * can add it to another menu), but is completely transparent * to the user */ -function PopupMenuSection() { - this._init.apply(this, arguments); -} - -PopupMenuSection.prototype = { - __proto__: PopupMenuBase.prototype, +const PopupMenuSection = new Lang.Class({ + Name: 'PopupMenuSection', + Extends: PopupMenuBase, _init: function() { - PopupMenuBase.prototype._init.call(this); + this.parent(); this.actor = this.box; this.actor._delegate = this; @@ -1429,17 +1397,14 @@ PopupMenuSection.prototype = { // corresponding signal so children can still pick it up open: function(animate) { this.emit('open-state-changed', true); }, close: function() { this.emit('open-state-changed', false); }, -} +}); -function PopupSubMenuMenuItem() { - this._init.apply(this, arguments); -} - -PopupSubMenuMenuItem.prototype = { - __proto__: PopupBaseMenuItem.prototype, +const PopupSubMenuMenuItem = new Lang.Class({ + Name: 'PopupSubMenuMenuItem', + Extends: PopupBaseMenuItem, _init: function(text) { - PopupBaseMenuItem.prototype._init.call(this); + this.parent(); this.actor.add_style_class_name('popup-submenu-menu-item'); @@ -1461,7 +1426,8 @@ PopupSubMenuMenuItem.prototype = { destroy: function() { this.menu.destroy(); - PopupBaseMenuItem.prototype.destroy.call(this); + + this.parent(); }, _onKeyPressEvent: function(actor, event) { @@ -1476,7 +1442,7 @@ PopupSubMenuMenuItem.prototype = { return true; } - return PopupBaseMenuItem.prototype._onKeyPressEvent.call(this, actor, event); + return this.parent(actor, event); }, activate: function(event) { @@ -1486,18 +1452,15 @@ PopupSubMenuMenuItem.prototype = { _onButtonReleaseEvent: function(actor) { this.menu.toggle(); } -}; +}); -function PopupComboMenu() { - this._init.apply(this, arguments); -} - -PopupComboMenu.prototype = { - __proto__: PopupMenuBase.prototype, +const PopupComboMenu = new Lang.Class({ + Name: 'PopupComboMenu', + Extends: PopupMenuBase, _init: function(sourceActor) { - PopupMenuBase.prototype._init.call(this, - sourceActor, 'popup-combo-menu'); + this.parent(sourceActor, 'popup-combo-menu'); + this.actor = this.box; this.actor._delegate = this; this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent)); @@ -1602,17 +1565,14 @@ PopupComboMenu.prototype = { getItemVisible: function(position) { return this._getMenuItems()[position].actor.visible; } -}; +}); -function PopupComboBoxMenuItem() { - this._init.apply(this, arguments); -} - -PopupComboBoxMenuItem.prototype = { - __proto__: PopupBaseMenuItem.prototype, +const PopupComboBoxMenuItem = new Lang.Class({ + Name: 'PopupComboBoxMenuItem', + Extends: PopupBaseMenuItem, _init: function (params) { - PopupBaseMenuItem.prototype._init.call(this, params); + this.parent(params); this._itemBox = new Shell.Stack(); this.addActor(this._itemBox); @@ -1730,16 +1690,14 @@ PopupComboBoxMenuItem.prototype = { this.setActiveItem(position); this.emit('active-item-changed', position); } -}; +}); /* Basic implementation of a menu manager. * Call addMenu to add menus */ -function PopupMenuManager(owner) { - this._init(owner); -} +const PopupMenuManager = new Lang.Class({ + Name: 'PopupMenuManager', -PopupMenuManager.prototype = { _init: function(owner) { this._owner = owner; this.grabbed = false; @@ -2011,4 +1969,4 @@ PopupMenuManager.prototype = { if (this._activeMenu != null) this._activeMenu.close(true); } -}; +}); diff --git a/js/ui/shellEntry.js b/js/ui/shellEntry.js index 1dc00887a..e348a80b7 100644 --- a/js/ui/shellEntry.js +++ b/js/ui/shellEntry.js @@ -7,18 +7,14 @@ const Main = imports.ui.main; const Params = imports.misc.params; const PopupMenu = imports.ui.popupMenu; - -function _EntryMenu(entry, params) { - this._init(entry, params); -}; - -_EntryMenu.prototype = { - __proto__: PopupMenu.PopupMenu.prototype, +const _EntryMenu = new Lang.Class({ + Name: 'ShellEntryMenu', + Extends: PopupMenu.PopupMenu, _init: function(entry, params) { params = Params.parse (params, { isPassword: false }); - PopupMenu.PopupMenu.prototype._init.call(this, entry, 0, St.Side.TOP); + this.parent(entry, 0, St.Side.TOP); this.actor.add_style_class_name('entry-context-menu'); @@ -60,7 +56,7 @@ _EntryMenu.prototype = { if (!this.actor.navigate_focus(null, direction, false)) this.actor.grab_key_focus(); - PopupMenu.PopupMenu.prototype.open.call(this); + this.parent(); }, _updateCopyItem: function() { @@ -103,8 +99,7 @@ _EntryMenu.prototype = { let visible = !!(this._entry.clutter_text.password_char); this._entry.clutter_text.set_password_char(visible ? '' : '\u25cf'); } -}; - +}); function _setMenuAlignment(entry, stageX) { let [success, entryX, entryY] = entry.transform_stage_point(stageX, 0); diff --git a/js/ui/status/keyboard.js b/js/ui/status/keyboard.js index 231f0c78e..f6f2d456e 100644 --- a/js/ui/status/keyboard.js +++ b/js/ui/status/keyboard.js @@ -14,15 +14,12 @@ const PopupMenu = imports.ui.popupMenu; const PanelMenu = imports.ui.panelMenu; const Util = imports.misc.util; -function LayoutMenuItem() { - this._init.apply(this, arguments); -} - -LayoutMenuItem.prototype = { - __proto__: PopupMenu.PopupBaseMenuItem.prototype, +const LayoutMenuItem = new Lang.Class({ + Name: 'LayoutMenuItem', + Extends: PopupMenu.PopupBaseMenuItem, _init: function(config, id, indicator, long_name) { - PopupMenu.PopupBaseMenuItem.prototype._init.call(this); + this.parent(); this._config = config; this._id = id; @@ -33,10 +30,11 @@ LayoutMenuItem.prototype = { }, activate: function(event) { - PopupMenu.PopupBaseMenuItem.prototype.activate.call(this); + this.parent(event); + this._config.lock_group(this._id); } -}; +}); function XKBIndicator() { this._init.call(this); diff --git a/js/ui/status/network.js b/js/ui/status/network.js index 7265873b3..57edc9c86 100644 --- a/js/ui/status/network.js +++ b/js/ui/status/network.js @@ -97,15 +97,12 @@ function ssidToLabel(ssid) { return label; } -function NMNetworkMenuItem() { - this._init.apply(this, arguments); -} - -NMNetworkMenuItem.prototype = { - __proto__: PopupMenu.PopupBaseMenuItem.prototype, +const NMNetworkMenuItem = new Lang.Class({ + Name: 'NMNetworkMenuItem', + Extends: PopupMenu.PopupBaseMenuItem, _init: function(accessPoints, title, params) { - PopupMenu.PopupBaseMenuItem.prototype._init.call(this, params); + this.parent(params); accessPoints = sortAccessPoints(accessPoints); this.bestAP = accessPoints[0]; @@ -184,21 +181,18 @@ NMNetworkMenuItem.prototype = { apObj.updateId = 0; } - PopupMenu.PopupBaseMenuItem.prototype.destroy.call(this); + this.parent(); } -}; +}); -function NMWiredSectionTitleMenuItem() { - this._init.apply(this, arguments); -} - -NMWiredSectionTitleMenuItem.prototype = { - __proto__: PopupMenu.PopupSwitchMenuItem.prototype, +const NMWiredSectionTitleMenuItem = new Lang.Class({ + Name: 'NMWiredSectionTitleMenuItem', + Extends: PopupMenu.PopupSwitchMenuItem, _init: function(label, params) { params = params || { }; params.style_class = 'popup-subtitle-menu-item'; - PopupMenu.PopupSwitchMenuItem.prototype._init.call(this, label, false, params); + this.parent(label, false, params); }, updateForDevice: function(device) { @@ -211,7 +205,7 @@ NMWiredSectionTitleMenuItem.prototype = { }, activate: function(event) { - PopupMenu.PopupSwitchMenuItem.prototype.activate.call(this, event); + this.parent(event); if (!this._device) { log('Section title activated when there is more than one device, should be non reactive'); @@ -230,19 +224,16 @@ NMWiredSectionTitleMenuItem.prototype = { else this._device.deactivate(); } -}; +}); -function NMWirelessSectionTitleMenuItem() { - this._init.apply(this, arguments); -} - -NMWirelessSectionTitleMenuItem.prototype = { - __proto__: PopupMenu.PopupSwitchMenuItem.prototype, +const NMWirelessSectionTitleMenuItem = new Lang.Class({ + Name: 'NMWirelessSectionTitleMenuItem', + Extends: PopupMenu.PopupSwitchMenuItem, _init: function(client, property, title, params) { params = params || { }; params.style_class = 'popup-subtitle-menu-item'; - PopupMenu.PopupSwitchMenuItem.prototype._init.call(this, title, false, params); + this.parent(title, false, params); this._client = client; this._property = property + '_enabled'; @@ -268,7 +259,7 @@ NMWirelessSectionTitleMenuItem.prototype = { }, activate: function(event) { - PopupMenu.PopupSwitchMenuItem.prototype.activate.call(this, event); + this.parent(event); this._client[this._setEnabledFunc](this._switch.state); }, @@ -285,7 +276,7 @@ NMWirelessSectionTitleMenuItem.prototype = { this.emit('enabled-changed', enabled); } -}; +}); function NMDevice() { throw new TypeError('Instantanting abstract class NMDevice'); diff --git a/js/ui/status/power.js b/js/ui/status/power.js index fa77d552a..836b01089 100644 --- a/js/ui/status/power.js +++ b/js/ui/status/power.js @@ -165,15 +165,12 @@ Indicator.prototype = { } }; -function DeviceItem() { - this._init.apply(this, arguments); -} - -DeviceItem.prototype = { - __proto__: PopupMenu.PopupBaseMenuItem.prototype, +const DeviceItem = new Lang.Class({ + Name: 'DeviceItem', + Extends: PopupMenu.PopupBaseMenuItem, _init: function(device) { - PopupMenu.PopupBaseMenuItem.prototype._init.call(this, { reactive: false }); + this.parent({ reactive: false }); let [device_id, device_type, icon, percentage, state, time] = device; @@ -220,4 +217,4 @@ DeviceItem.prototype = { return _("Unknown"); } } -} +}); diff --git a/js/ui/userMenu.js b/js/ui/userMenu.js index 7e4fbe30c..c934020a9 100644 --- a/js/ui/userMenu.js +++ b/js/ui/userMenu.js @@ -40,15 +40,12 @@ const IMStatus = { // Copyright (C) 2008,2009 Red Hat, Inc. -function IMStatusItem(label, iconName) { - this._init(label, iconName); -} - -IMStatusItem.prototype = { - __proto__: PopupMenu.PopupBaseMenuItem.prototype, +const IMStatusItem = new Lang.Class({ + Name: 'IMStatusItem', + Extends: PopupMenu.PopupBaseMenuItem, _init: function(label, iconName) { - PopupMenu.PopupBaseMenuItem.prototype._init.call(this); + this.parent(); this.actor.add_style_class_name('status-chooser-status-item'); @@ -61,19 +58,15 @@ IMStatusItem.prototype = { this.label = new St.Label({ text: label }); this.addActor(this.label); } -}; +}); -function IMUserNameItem() { - this._init(); -} - -IMUserNameItem.prototype = { - __proto__: PopupMenu.PopupBaseMenuItem.prototype, +const IMUserNameItem = new Lang.Class({ + Name: 'IMUserNameItem', + Extends: PopupMenu.PopupBaseMenuItem, _init: function() { - PopupMenu.PopupBaseMenuItem.prototype._init.call(this, - { reactive: false, - style_class: 'status-chooser-user-name' }); + this.parent({ reactive: false, + style_class: 'status-chooser-user-name' }); this._wrapper = new Shell.GenericContainer(); this._wrapper.connect('get-preferred-width', @@ -102,19 +95,15 @@ IMUserNameItem.prototype = { _wrapperAllocate: function(actor, box, flags) { this.label.allocate(box, flags); } -}; +}); -function IMStatusChooserItem() { - this._init(); -} - -IMStatusChooserItem.prototype = { - __proto__: PopupMenu.PopupBaseMenuItem.prototype, +const IMStatusChooserItem = new Lang.Class({ + Name: 'IMStatusChooserItem', + Extends: PopupMenu.PopupBaseMenuItem, _init: function() { - PopupMenu.PopupBaseMenuItem.prototype._init.call (this, - { reactive: false, - style_class: 'status-chooser' }); + this.parent({ reactive: false, + style_class: 'status-chooser' }); this._iconBin = new St.Button({ style_class: 'status-chooser-user-icon' }); this.addActor(this._iconBin); @@ -220,7 +209,7 @@ IMStatusChooserItem.prototype = { this._userChangedId = 0; } - PopupMenu.PopupBaseMenuItem.prototype.destroy.call(this); + this.parent(); }, // Override getColumnWidths()/setColumnWidths() to make the item @@ -422,7 +411,7 @@ IMStatusChooserItem.prototype = { this._expectedPresence = newPresence; this._accountMgr.set_all_requested_presences(newPresence, status, msg); } -}; +}); function UserMenuButton() {