description |
---|
Creating multi-pane app layouts |
So far, you've created apps with a single HeaderBar, but what about creating an app with a multi-pane layout like Mail or Tasks?
Before we begin, make sure you've included Granite in the build dependencies of your "meson.build" file. We'll be using it later for a couple of style classes.
{% code title="meson.build" %}
executable(
meson.project_name(),
'src' / 'Application.vala',
dependencies: [
dependency('granite-7'),
dependency('gtk4')
],
install: true
)
{% endcode %}
Start with a new Gtk.Application
, but this time set the titlebar
property of the ApplicationWindow to an invisible grid. This will replace the default HeaderBar of the window since we'll be creating our own HeaderBars inside the paned layout.
var main_window = new Gtk.ApplicationWindow (this) {
titlebar = new Gtk.Grid () { visible = false }
};
Then create a new Gtk.Paned
and set that as the child of the ApplicationWindow. A Paned is a resizable widget that can contain two children. There are various properties you can set to control the widgets behavior when the AppliactionWindow is resized; For the purposes of this tutorial we want the first pane to stay a fixed size and we don't want someone to be able to make the window smaller than the contents of both sides of the Paned.
var paned = new Gtk.Paned (Gtk.Orientation.HORIZONTAL) {
resize_start_child = false,
shrink_end_child = false,
shrink_start_child = false
};
var main_window = new Gtk.ApplicationWindow (this) {
child = paned,
titlebar = new Gtk.Grid () { visible = false }
};
Next, let's create a new Gtk.HeaderBar
and hide its title buttons. Then, we're going to pack our own Gtk.WindowControls
that only contain the buttons for one side of the Window. And finally, we'll put that HeaderBar in a Box and set that as the start_child
of the Paned.
var start_header = new Gtk.HeaderBar () {
show_title_buttons = false
};
start_header.add_css_class (Granite.STYLE_CLASS_FLAT);
start_header.pack_start (new Gtk.WindowControls (Gtk.PackType.START));
var start_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
start_box.append (start_header);
var paned = new Gtk.Paned (Gtk.Orientation.HORIZONTAL) {
start_child = start_box,
resize_start_child = false,
shrink_end_child = false,
shrink_start_child = false
};
var main_window = new Gtk.ApplicationWindow (this) {
child = paned,
titlebar = new Gtk.Grid () { visible = false }
};
Do the same thing again for the end_child
of the Paned: create a HeaderBar with END
WindowControls, inside a vertical Box.
var start_header = new Gtk.HeaderBar () {
show_title_buttons = false
};
start_header.add_css_class (Granite.STYLE_CLASS_FLAT);
start_header.pack_start (new Gtk.WindowControls (Gtk.PackType.START));
var start_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
start_box.append (start_header);
var end_header = new Gtk.HeaderBar () {
show_title_buttons = false
};
end_header.add_css_class (Granite.STYLE_CLASS_FLAT);
end_header.pack_end (new Gtk.WindowControls (Gtk.PackType.END));
var end_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
end_box.append (end_header);
var paned = new Gtk.Paned (Gtk.Orientation.HORIZONTAL) {
start_child = start_box,
end_child = end_box,
resize_start_child = false,
shrink_end_child = false,
shrink_start_child = false
};
var main_window = new Gtk.ApplicationWindow (this) {
child = paned,
titlebar = new Gtk.Grid () { visible = false }
};
Finally, make a few small tweaks:
- Set an empty label as the
title_widget
in the start header - Add
Granite.STYLE_CLASS_VIEW
to the end box - Set the default size and title properties of the ApplicationWindow
The final result should look like this:
{% code title="Application.vala" %}
public class MyApp : Gtk.Application {
public MyApp () {
Object (
application_id: "io.github.myteam.myapp",
flags: ApplicationFlags.FLAGS_NONE
);
}
protected override void activate () {
var start_header = new Gtk.HeaderBar () {
show_title_buttons = false,
title_widget = new Gtk.Label ("")
};
start_header.add_css_class (Granite.STYLE_CLASS_FLAT);
start_header.pack_start (new Gtk.WindowControls (Gtk.PackType.START));
var start_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
start_box.append (start_header);
var end_header = new Gtk.HeaderBar () {
show_title_buttons = false
};
end_header.add_css_class (Granite.STYLE_CLASS_FLAT);
end_header.pack_end (new Gtk.WindowControls (Gtk.PackType.END));
var end_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
end_box.add_css_class (Granite.STYLE_CLASS_VIEW);
end_box.append (end_header);
var paned = new Gtk.Paned (Gtk.Orientation.HORIZONTAL) {
start_child = start_box,
end_child = end_box,
resize_start_child = false,
shrink_end_child = false,
shrink_start_child = false
};
var main_window = new Gtk.ApplicationWindow (this) {
child = paned,
default_height = 300,
default_width = 300,
titlebar = new Gtk.Grid () { visible = false },
title = "Hello World"
};
main_window.present ();
}
public static int main (string[] args) {
return new MyApp ().run (args);
}
}
{% endcode %}