Creating Complex Popovers in D and GtkD

I’m working on a new terminal emulator in my spare time and one UI element I definitely wanted to make use of was Popovers. While creating a simple Popover is quite easy, I was struggling a bit with how to handle the more complex layouts like horizontal buttons as the documentation does not make it very clear. Fortunately, Christian Hergert of Builder fame was on IRC one night and was able to point me in the right direction.

The Popover I created is shown in the image below, in the terminal emulator I’m working on it allows you to split the terminal into multiple views or tiles so the user can see multiple views at the same time in an easily managed container. The Popover allows the user to split the terminal horizontally or vertically (note the icons are temporary, plan on “borrowing” Builder’s icons for this at some point).

Popover

The issue I was struggling with was where to set the display-hint, the section being a gio.Menu doesn’t have methods to set an attribute. What Christian pointed out to me is that you need to create an empty MenuItem to represent the section, add the section to that and then add it the menu used in the Popover. You can then set the necessary attributes on the empty MenuItem to get the items displayed in the way you want.

Here is the code I ended up with:

Popover createPopover(Widget parent) {
GMenu model = new GMenu();
 
GMenuItem splitH = new GMenuItem(null, "view.splith");
splitH.setAttributeValue("verb-icon", new GVariant("go-next-symbolic"));
splitH.setIcon(new ThemedIcon("go-next-symbolic"));
 
GMenuItem splitV = new GMenuItem(null, "view.splitv");
splitV.setAttributeValue("verb-icon", new GVariant("go-down-symbolic"));
splitV.setIcon(new ThemedIcon("go-down-symbolic"));
 
GMenu section = new GMenu();
section.appendItem(splitH);
section.appendItem(splitV);
 
GMenuItem splits = new GMenuItem(null, null);
splits.setSection(section);
splits.setLabel("Split");
splits.setAttributeValue("display-hint", new GVariant("horizontal-buttons"));
 
model.appendItem(splits);
 
Popover pm = new Popover(parent, model);
return pm;
}

Leave a Reply

Your email address will not be published. Required fields are marked *


*