Skip to content

Commit

Permalink
ViewChooser
Browse files Browse the repository at this point in the history
  • Loading branch information
lainsce committed Jan 9, 2023
1 parent 5f9044f commit 1c21bcc
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 0 deletions.
6 changes: 6 additions & 0 deletions demo/co.tauos.Helium1.Demo.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@
"type" : "git",
"url" : "https://github.com/tau-OS/libhelium.git",
"branch" : "main"
},
{
"type": "git",
"url": "https://gitlab.gnome.org/jwestman/blueprint-compiler.git",
"branch": "main",
"dest": "./subprojects/blueprint-compiler"
}
]
}
Expand Down
4 changes: 4 additions & 0 deletions demo/data/ui/window.blp
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,10 @@ template DemoMainWindow : He.ApplicationWindow {
Box {
spacing: 12;

.HeViewChooser {
stack: view_stack;
}

He.NavigationRail {
stack: view_stack;
}
Expand Down
172 changes: 172 additions & 0 deletions lib/Widgets/ViewChooser.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/*
* Copyright (c) 2023 Fyra Labs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/

/**
* A ViewChooser is a chooser switcher that filters a stack's view.
*/
public class He.ViewChooser : He.Bin {
private Gtk.SelectionModel _stack_pages;
private List<Gtk.ToggleButton> _buttons;
private Gtk.Box menu_box;
private Gtk.Label menu_label;

private Gtk.Stack _stack;
/**
* The stack that is controlled by this chooser switcher.
*
* @since 1.0
*/
public Gtk.Stack stack {
get { return this._stack; }
set {
if (this._stack == value) return;

if (this._stack_pages != null) {
this._stack_pages.selection_changed.disconnect (on_selected_stack_page_changed);
this._stack_pages.items_changed.disconnect (on_stack_pages_changed);
}

this._stack = value;
this._stack_pages = value.pages;

this._stack_pages.selection_changed.connect (on_selected_stack_page_changed);
this._stack_pages.items_changed.connect (on_stack_pages_changed);

on_stack_pages_changed (0, 0, this._stack_pages.get_n_items ());
}
}

public ViewChooser () {
base ();
}

static construct {
set_layout_manager_type (typeof (Gtk.BoxLayout));
}

construct {
this.valign = Gtk.Align.CENTER;

menu_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 6);

menu_label = new Gtk.Label ("");
menu_label.add_css_class ("view-title");
var menu_img = new Gtk.Image ();
menu_img.icon_name = "pan-down-symbolic";

var menu_child_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
menu_child_box.append (menu_label);
menu_child_box.append (menu_img);

var menu_popover = new Gtk.Popover ();
menu_popover.child = menu_box;

var menu = new Gtk.MenuButton ();
menu.add_css_class ("flat");
menu.popover = menu_popover;
menu.child = menu_child_box;

menu_box.width_request = menu_child_box.get_width ();
menu_child_box.notify["width"].connect (() => {
menu_box.width_request = menu_child_box.get_width ();
});

menu.set_parent (this);
}

private void on_stack_pages_changed (uint position, uint removed, uint added) {
while (removed-- > 0 && this._buttons.nth (position) != null) {
unowned var button_link = this._buttons.nth (position);

button_link.data.unparent ();

unowned var link = button_link;
button_link = button_link.next;

this._buttons.delete_link (link);
}

while (added-- > 0) {
unowned var button_link = this._buttons.nth (position);

var button = new Gtk.ToggleButton () {
active = this._stack_pages.is_selected (position)
};
button.add_css_class ("flat");

var button_label = new Gtk.Label ("");

var button_img = new Gtk.Image () {
hexpand = true,
halign = Gtk.Align.END,
icon_name = "emblem-ok-symbolic"
};

var button_child_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
button_child_box.append (button_label);
button_child_box.append (button_img);

button.child = button_child_box;

this._stack_pages.get_item (position).bind_property ("title", button_label, "label", SYNC_CREATE);

button.bind_property ("active", button_img, "visible", SYNC_CREATE);

menu_label.label = "";
menu_label.label = ((Gtk.StackPage)this._stack_pages.get_item (position)).title;

button.toggled.connect (() => on_button_toggled (button));
button.set_parent (menu_box);

if (!this._buttons.is_empty ()) {
button.set_group ((Gtk.ToggleButton) this._buttons.nth_data (0));
}

this._buttons.insert_before (button_link, button);

position++;
}
}

private void on_selected_stack_page_changed (uint position, uint n_items) {
unowned var button_link = this._buttons.nth (position);

while (n_items-- > 0 && button_link != null) {
button_link.data.active = this._stack_pages.is_selected (position++);
button_link = button_link.next;
}
}

private void on_button_toggled (Gtk.ToggleButton button) {
// Don't do anything if this stack has 1 or less items
if (this._stack_pages.get_n_items () <= 1) {
return;
}

unowned int position = this._buttons.index (button);
if (button.active) {
this._stack_pages.select_item (position, true);
menu_label.label = "";
menu_label.label = ((Gtk.StackPage)this._stack_pages.get_item (position)).title;
return;
}

this._stack_pages.unselect_item (position);
}
}
1 change: 1 addition & 0 deletions lib/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ libhelium_sources += files(
'Widgets/TintButton.vala',
'Widgets/Toast.vala',
'Widgets/ViewAux.vala',
'Widgets/ViewChooser.vala',
'Widgets/ViewDual.vala',
'Widgets/ViewMono.vala',
'Widgets/ViewSubTitle.vala',
Expand Down

0 comments on commit 1c21bcc

Please sign in to comment.