status/network: Add NMSectionItem subclass
The class implements a menu item that contains a section which can be collapsed into a submenu. It is very common for network devices to only have one associated connection, so hiding away a single item in a submenu is fairly inconvenient. This class will address this, by only using a submenu when it is actually needed. Although the main issue it addresses is that menus (including sections) aren't GObjects. This gives us a GObject that can be added to a menu, and that can itself contain other menu items. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2407>
This commit is contained in:
parent
b4da69d474
commit
ad1a32749e
@ -200,6 +200,78 @@ const NMMenuItem = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item that contains a section, and can be collapsed
|
||||||
|
* into a submenu
|
||||||
|
*/
|
||||||
|
const NMSectionItem = GObject.registerClass({
|
||||||
|
Properties: {
|
||||||
|
'use-submenu': GObject.ParamSpec.boolean('use-submenu', '', '',
|
||||||
|
GObject.ParamFlags.READWRITE,
|
||||||
|
false),
|
||||||
|
},
|
||||||
|
}, class NMSectionItem extends NMMenuItem {
|
||||||
|
constructor() {
|
||||||
|
super({
|
||||||
|
activate: false,
|
||||||
|
can_focus: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
this._useSubmenu = false;
|
||||||
|
|
||||||
|
// Turn into an empty container with no padding
|
||||||
|
this.styleClass = '';
|
||||||
|
this.setOrnament(PopupMenu.Ornament.HIDDEN);
|
||||||
|
|
||||||
|
// Add intermediate section; we need this for submenu support
|
||||||
|
this._mainSection = new PopupMenu.PopupMenuSection();
|
||||||
|
this.add_child(this._mainSection.actor);
|
||||||
|
|
||||||
|
this._submenuItem = new PopupMenu.PopupSubMenuMenuItem('', true);
|
||||||
|
this._mainSection.addMenuItem(this._submenuItem);
|
||||||
|
this._submenuItem.hide();
|
||||||
|
|
||||||
|
this.section = new PopupMenu.PopupMenuSection();
|
||||||
|
this._mainSection.addMenuItem(this.section);
|
||||||
|
|
||||||
|
// Represents the item as a whole when shown
|
||||||
|
this.bind_property('name',
|
||||||
|
this._submenuItem.label, 'text',
|
||||||
|
GObject.BindingFlags.DEFAULT);
|
||||||
|
this.bind_property('icon-name',
|
||||||
|
this._submenuItem.icon, 'icon-name',
|
||||||
|
GObject.BindingFlags.DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
_setParent(parent) {
|
||||||
|
super._setParent(parent);
|
||||||
|
this._mainSection._setParent(parent);
|
||||||
|
|
||||||
|
parent?.connect('menu-closed',
|
||||||
|
() => this._mainSection.emit('menu-closed'));
|
||||||
|
}
|
||||||
|
|
||||||
|
get use_submenu() {
|
||||||
|
return this._useSubmenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
set use_submenu(useSubmenu) {
|
||||||
|
if (this._useSubmenu === useSubmenu)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._useSubmenu = useSubmenu;
|
||||||
|
this._submenuItem.visible = useSubmenu;
|
||||||
|
|
||||||
|
if (useSubmenu) {
|
||||||
|
this._mainSection.box.remove_child(this.section.actor);
|
||||||
|
this._submenuItem.menu.box.add_child(this.section.actor);
|
||||||
|
} else {
|
||||||
|
this._submenuItem.menu.box.remove_child(this.section.actor);
|
||||||
|
this._mainSection.box.add_child(this.section.actor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const NMConnectionItem = GObject.registerClass(
|
const NMConnectionItem = GObject.registerClass(
|
||||||
class NMConnectionItem extends NMMenuItem {
|
class NMConnectionItem extends NMMenuItem {
|
||||||
constructor(section, connection) {
|
constructor(section, connection) {
|
||||||
|
Loading…
Reference in New Issue
Block a user