renameFolderMenu: Use a custom menu item inheriting from PopupBaseMenuItem

The RenameFolderMenu uses the internal box as a menu item, while PopupMenu
expects to have PopupBaseMenuItem based children with a delegate set.

Instead of using a custom menu with a customized box acting as menu
item,just add a RenameFolderMenuItem that inherits from the parent,
adjusting the features as we need them. In fact, the rename folder menu item
doesn't need any label, padding or default styling so we can reuse
PopupMenuBaseItem after we use our styling properties and we set the
Ornament to HIDDEN.

To get the proper style in place, define rename-folder-popup and
rename-folder-popup-item to override the default popup-menu-item rule
padding instead of using margins.

Pass the menu item as menu's focusActor as this will key-focus it on pop-up,
by overriding the key_focus_in() vfunc we can then delegate the focus
handling to the entry's clutter-text.

Also override the map() vfunc in order to update the entry's content before
mapping the entry.

Finally, use the item's activate method in order to tell the parent menu
we're done with it and that the menu can be closed.

As consequence we can also remove the menu's popup() method, and just use
the default open().

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/720
This commit is contained in:
Marco Trevisan (Treviño) 2019-09-14 03:03:15 +02:00 committed by Florian Müllner
parent 8e3aac8ed7
commit dab60d5580
2 changed files with 53 additions and 40 deletions

View File

@ -610,13 +610,12 @@ StScrollBar {
border-bottom-style: solid; border-bottom-style: solid;
} }
// Rename popup // Rename popup
.rename-folder-popup {
.rename-folder-popup-box { .rename-folder-popup-item {
spacing: 6px; spacing: 6px;
margin-left: 12px; &:ltr, &:rtl { padding: 0, 12px; }
margin-right: 12px; }
} }
// Background menu // Background menu

View File

@ -1699,7 +1699,7 @@ var FolderIcon = class FolderIcon {
} }
this.actor.set_hover(true); this.actor.set_hover(true);
this._menu.popup(); this._menu.open();
this._menuManager.ignoreRelease(); this._menuManager.ignoreRelease();
} }
@ -1713,27 +1713,23 @@ var FolderIcon = class FolderIcon {
}; };
Signals.addSignalMethods(FolderIcon.prototype); Signals.addSignalMethods(FolderIcon.prototype);
var RenameFolderMenu = class RenameFolderMenu extends PopupMenu.PopupMenu { var RenameFolderMenuItem = GObject.registerClass(
constructor(source, folder) { class RenameFolderMenuItem extends PopupMenu.PopupBaseMenuItem {
super(source.actor, 0.5, St.Side.BOTTOM); _init(folder) {
super._init({
style_class: 'rename-folder-popup-item',
reactive: false,
});
this.setOrnament(PopupMenu.Ornament.HIDDEN);
this._folder = folder; this._folder = folder;
// We want to keep the item hovered while the menu is up
this.blockSourceEvents = true;
let box = new St.BoxLayout({ style_class: 'rename-folder-popup-box' });
this.box.add_child(box);
// Entry // Entry
this._entry = new St.Entry({ this._entry = new St.Entry({
x_expand: true, x_expand: true,
width: 200, width: 200,
}); });
box.add_child(this._entry); this.add_child(this._entry);
// Focus the text entry on menu pop-up
this.focusActor = this._entry.clutter_text;
this._entry.clutter_text.connect( this._entry.clutter_text.connect(
'notify::text', this._validate.bind(this)); 'notify::text', this._validate.bind(this));
@ -1748,30 +1744,20 @@ var RenameFolderMenu = class RenameFolderMenu extends PopupMenu.PopupMenu {
can_focus: true, can_focus: true,
label: _('Rename'), label: _('Rename'),
}); });
box.add_child(this._button); this.add_child(this._button);
this._button.connect('clicked', this._updateFolderName.bind(this)); this._button.connect('clicked', this._updateFolderName.bind(this));
// Chain our visibility and lifecycle to that of the source
this._sourceMappedId = source.actor.connect('notify::mapped', () => {
if (!source.actor.mapped)
this.close();
});
source.actor.connect('destroy', () => {
source.actor.disconnect(this._sourceMappedId);
this.destroy();
});
Main.uiGroup.add_actor(this.actor);
} }
popup() { vfunc_map() {
let folderName = _getFolderName(this._folder); this._entry.text = _getFolderName(this._folder);
this._entry.clutter_text.set_selection(0, -1);
super.vfunc_map();
}
this._entry.text = folderName; vfunc_key_focus_in() {
this._entry.clutter_text.set_selection(0, folderName.length); super.vfunc_key_focus_in();
this._entry.clutter_text.grab_key_focus();
this.open();
} }
_isValidFolderName() { _isValidFolderName() {
@ -1794,7 +1780,35 @@ var RenameFolderMenu = class RenameFolderMenu extends PopupMenu.PopupMenu {
let newFolderName = this._entry.text.trim(); let newFolderName = this._entry.text.trim();
this._folder.set_string('name', newFolderName); this._folder.set_string('name', newFolderName);
this._folder.set_boolean('translate', false); this._folder.set_boolean('translate', false);
this.activate(Clutter.get_current_event());
}
});
var RenameFolderMenu = class RenameFolderMenu extends PopupMenu.PopupMenu {
constructor(source, folder) {
super(source.actor, 0.5, St.Side.BOTTOM);
this.actor.add_style_class_name('rename-folder-popup');
// We want to keep the item hovered while the menu is up
this.blockSourceEvents = true;
let menuItem = new RenameFolderMenuItem(folder);
this.addMenuItem(menuItem);
// Focus the text entry on menu pop-up
this.focusActor = menuItem;
// Chain our visibility and lifecycle to that of the source
this._sourceMappedId = source.actor.connect('notify::mapped', () => {
if (!source.actor.mapped)
this.close(); this.close();
});
source.actor.connect('destroy', () => {
source.actor.disconnect(this._sourceMappedId);
this.destroy();
});
Main.uiGroup.add_actor(this.actor);
} }
}; };
Signals.addSignalMethods(RenameFolderMenu.prototype); Signals.addSignalMethods(RenameFolderMenu.prototype);