popupMenu: add alternate menu item
This is special menu item that can alternate between two choices when you hit the alt key. It will be useful for getting a hybrid suspend/power off menu item. https://bugzilla.gnome.org/show_bug.cgi?id=636680
This commit is contained in:
parent
3c66455112
commit
610c2b5987
@ -140,6 +140,10 @@ StTooltip StLabel {
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
.popup-alternating-menu-item:alternate {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.popup-slider-menu-item {
|
||||
height: 1em;
|
||||
min-width: 15em;
|
||||
|
@ -328,6 +328,107 @@ PopupSeparatorMenuItem.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
const PopupAlternatingMenuItemState = {
|
||||
DEFAULT: 0,
|
||||
ALTERNATIVE: 1
|
||||
}
|
||||
|
||||
function PopupAlternatingMenuItem() {
|
||||
this._init.apply(this, arguments);
|
||||
}
|
||||
|
||||
PopupAlternatingMenuItem.prototype = {
|
||||
__proto__: PopupBaseMenuItem.prototype,
|
||||
|
||||
_init: function(text, alternateText, params) {
|
||||
PopupBaseMenuItem.prototype._init.call(this, params);
|
||||
this.actor.add_style_class_name('popup-alternating-menu-item');
|
||||
|
||||
this._text = text;
|
||||
this._alternateText = alternateText;
|
||||
this.label = new St.Label({ text: text });
|
||||
this.state = PopupAlternatingMenuItemState.DEFAULT;
|
||||
this.addActor(this.label);
|
||||
|
||||
this.actor.connect('notify::mapped', Lang.bind(this, this._onMapped));
|
||||
},
|
||||
|
||||
_onMapped: function() {
|
||||
if (this.actor.mapped) {
|
||||
this._capturedEventId = global.stage.connect('captured-event',
|
||||
Lang.bind(this, this._onCapturedEvent));
|
||||
this._updateStateFromModifiers();
|
||||
} else {
|
||||
if (this._capturedEventId != 0) {
|
||||
global.stage.disconnect(this._capturedEventId);
|
||||
this._capturedEventId = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_setState: function(state) {
|
||||
if (this.state != state) {
|
||||
if (state == PopupAlternatingMenuItemState.ALTERNATIVE && !this._canAlternate())
|
||||
return;
|
||||
|
||||
this.state = state;
|
||||
this._updateLabel();
|
||||
}
|
||||
},
|
||||
|
||||
_updateStateFromModifiers: function() {
|
||||
let [x, y, mods] = global.get_pointer();
|
||||
let state;
|
||||
|
||||
if ((mods & Clutter.ModifierType.MOD1_MASK) == 0) {
|
||||
state = PopupAlternatingMenuItemState.DEFAULT;
|
||||
} else {
|
||||
state = PopupAlternatingMenuItemState.ALTERNATIVE;
|
||||
}
|
||||
|
||||
this._setState(state);
|
||||
},
|
||||
|
||||
_onCapturedEvent: function(actor, event) {
|
||||
if (event.type() != Clutter.EventType.KEY_PRESS &&
|
||||
event.type() != Clutter.EventType.KEY_RELEASE)
|
||||
return false;
|
||||
|
||||
let key = event.get_key_symbol();
|
||||
|
||||
if (key == Clutter.KEY_Alt_L || key == Clutter.KEY_Alt_R)
|
||||
this._updateStateFromModifiers();
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_updateLabel: function() {
|
||||
if (this.state == PopupAlternatingMenuItemState.ALTERNATIVE) {
|
||||
this.actor.add_style_pseudo_class('alternate');
|
||||
this.label.set_text(this._alternateText);
|
||||
} else {
|
||||
this.actor.remove_style_pseudo_class('alternate');
|
||||
this.label.set_text(this._text);
|
||||
}
|
||||
},
|
||||
|
||||
_canAlternate: function() {
|
||||
if (this.state == PopupAlternatingMenuItemState.DEFAULT && !this._alternateText)
|
||||
return false;
|
||||
return true;
|
||||
},
|
||||
|
||||
updateText: function(text, alternateText) {
|
||||
this._text = text;
|
||||
this._alternateText = alternateText;
|
||||
|
||||
if (!this._canAlternate())
|
||||
this._setState(PopupAlternatingMenuItemState.DEFAULT);
|
||||
|
||||
this._updateLabel();
|
||||
}
|
||||
};
|
||||
|
||||
function PopupSliderMenuItem() {
|
||||
this._init.apply(this, arguments);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user