Neben vielen anderen großartigen Verbesserungen, die GNOME 3.16 seinen Nutzern beschert, bringt natürlich auch GTK+ wieder Neuerungen mit. Eine davon ist die neue Gtk.StackSidebar, die als Übersicht für die schon älteren Gtk.Stacks dient und aussieht wie eine klassische Gtk.List.

Über ebendiese ließe sich auch ein ähnliches Verhalten erzeugen, wie es die Gtk.StackSidebar an den Tag legt: Bei einem Klick (oder Drücken) auf ein Item in der Liste wird das jeweilige Element des Gtk.Stacks angezeigt. Mit diesem neuen Widget nimmt man jedoch ganz klar eine Abkürzung! Denn während man sich mit einer Gtk.List mit Signalen und dergleichen rumärgern müsste, reicht es bei der Gtk.StackSidebar den Gtk.Stack anzugeben, mit dem man arbeiten will. Alles weitere wird intern geregelt und betrifft den Programmierer (also uns) nicht weiter. Das klingt doch super!

Minimalbeispiel

Wie immer bei mir folgt nun das obligatorische Minimalbeispiel. Diesmal habe ich mich wieder dazu entschlossen, ein anderes wiederzuverwenden, in diesem Fall den minimalistischen Bildbetrachter aus dem ActionBar-Tutorial. Diesem stünde doch eine Übersicht über die Bilder – vielleicht in Form von Dateinamen – nicht schlecht, oder? Da ich allerdings hier wie auch im ursprünglichen Tutorial zu Anschauungszwecken mit Stock-Icons arbeite, habe ich ihnen einfach Namen gegeben, das Vorgehen sollte aber klar sein.

Die StackSidebar als Erweiterung für den Bildbetrachter aus dem ActionBar-Tutorial.
Die StackSidebar als Erweiterung für den Bildbetrachter aus dem ActionBar-Tutorial.

Zunächst muss also ein neuer Gtk.Stack erzeugt werden. Diesem können anschließend beliebige Gtk.Widgets hinzugefügt werden. Wichtig ist bei der Benutzung der Gtk.StackSidebar nur, dass die Gtk.Widgets betitelt übergeben werden, also mit

add_titled (Gtk.Widget child, string name, string title)

da der String title das ist, was in der Gtk.StackSidebar angezeigt wird. Gtk.Widgets ohne Titel werden stillschweigend ignoriert.

Dies ist allerdings nicht der einzige Fallstrick, der bei der Benutzung der Gtk.StackSidebar lauert: Sie muss zwingend in einer Gtk.Box o. Ä. mit horizontaler Ausrichtung eingefügt werden, ansonsten wird sie schlicht und ergreifend nicht angezeigt (ohne Fehlermeldung). Aufgrund dessen und da sie – im Gegensatz zur Gtk.List – auch nur Strings enthalten kann, können mit ihr leider keine Slideshows unter der großen Bildansicht gebaut werden – schade!

Ansonsten ist die Benutzung wirklich mehr als einfach: Gtk.StackSidebar erzeugen und dem Gtk.Stack zuordnen, der verwendet werden soll.

Gtk.StackSidebar ssidebar = new Gtk.StackSidebar ();
ssidebar.set_stack (stack);

Wo die Gtk.StackSidebar dann am Ende im Fenster angezeigt werden soll, ist egal. Sie muss nicht direkt neben dem Gtk.Stack auftauchen. Hauptsache, sie befindet sich in einer horizontalen Umgebung (siehe oben).

Zusammen sieht das ganze dann so aus:

class Example : Gtk.Application {
	public Example () {
		Object (application_id: "com.example.app", flags: ApplicationFlags.FLAGS_NONE);
	}

	protected override void activate () {
		Gtk.Settings.get_default ().gtk_application_prefer_dark_theme = true;
		Gtk.ApplicationWindow window = new Gtk.ApplicationWindow (this);
		window.set_default_size (800, 500);
		window.set_title ("StackSidebar");
		
		/*
		 * Primäre Box
		 */
		Gtk.Box primary_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
		
		/*
		 * Innere Box
		 */
		Gtk.Box inner_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
		primary_box.pack_end (inner_box, true);
		
		/*
		 * Stack
		 */
		Gtk.Stack stack = new Gtk.Stack ();
		stack.set_transition_type (Gtk.StackTransitionType.SLIDE_UP);
		stack.add_titled (new Gtk.Image.from_icon_name ("document-open", Gtk.IconSize.DND), "open", "Öffnen");
		stack.add_titled (new Gtk.Image.from_icon_name ("document-save", Gtk.IconSize.DND), "save", "Speichern");
		
		inner_box.pack_start (stack, true);
		
		/*
		 * StackSidebar
		 */
		Gtk.StackSidebar ssidebar = new Gtk.StackSidebar ();
		ssidebar.set_stack (stack);
		
		primary_box.pack_start (ssidebar, false);
		
		
		
		/*
		 * Ab hier Actionbar
		 * 
		 * Näheres siehe letztes Tutorial.
		 */
		Gtk.ActionBar action_bar = new Gtk.ActionBar ();
		
		// Linke Buttons
		Gtk.Button left_button1 = new Gtk.Button.from_icon_name ("go-first", Gtk.IconSize.SMALL_TOOLBAR);
		action_bar.pack_start (left_button1);
		Gtk.Button left_button2 = new Gtk.Button.from_icon_name ("go-previous", Gtk.IconSize.SMALL_TOOLBAR);
		action_bar.pack_start (left_button2);
		
		// Rechte Buttons
		Gtk.Button right_button1 = new Gtk.Button.from_icon_name ("go-last", Gtk.IconSize.SMALL_TOOLBAR);
		action_bar.pack_end (right_button1);
		Gtk.Button right_button2 = new Gtk.Button.from_icon_name ("go-next", Gtk.IconSize.SMALL_TOOLBAR);
		action_bar.pack_end (right_button2);
		
		// Mittlere Buttons
		Gtk.Box secondary_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 3);
		
		Gtk.Button center_button1 = new Gtk.Button.from_icon_name ("zoom-original", Gtk.IconSize.SMALL_TOOLBAR);
		secondary_box.pack_start (center_button1);
		Gtk.Button center_button2 = new Gtk.Button.from_icon_name ("zoom-out", Gtk.IconSize.SMALL_TOOLBAR);
		secondary_box.pack_start (center_button2);
		Gtk.Button center_button3 = new Gtk.Button.from_icon_name ("zoom-in", Gtk.IconSize.SMALL_TOOLBAR);
		secondary_box.pack_start (center_button3);
		Gtk.Button center_button4 = new Gtk.Button.from_icon_name ("zoom-fit-best", Gtk.IconSize.SMALL_TOOLBAR);
		secondary_box.pack_start (center_button4);
		
		action_bar.set_center_widget (secondary_box);
		
		inner_box.pack_end (action_bar, false);
		
		window.add (primary_box);
		window.show_all ();
	}
}

int main (string[] args) {
	return new Example ().run (args);
}

Das Ganze in einer Datei namens stacksidebar.vala abspeichern und mit

valac --pkg=gtk+-3.0 stacksidebar.vala

kompilieren, fertig!

Viel Spaß damit!