Skip to content
This repository has been archived by the owner on Jun 4, 2022. It is now read-only.

Commit

Permalink
Allow tabs to be horizontal or vertical.
Browse files Browse the repository at this point in the history
  • Loading branch information
alcinnz committed Feb 27, 2021
1 parent 407dea0 commit 2f77dcd
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 3 deletions.
7 changes: 5 additions & 2 deletions src/BrowserWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public class Odysseus.BrowserWindow : Gtk.ApplicationWindow {

private void init_layout() {
tabs = new WebNotebook();
var vtabs = new VerticalTabs(tabs);
var header = new Header.HeaderBarWithMenus();
build_toolbar(header);
set_titlebar(header);
Expand All @@ -65,10 +66,12 @@ public class Odysseus.BrowserWindow : Gtk.ApplicationWindow {
if (Gdk.WindowState.FULLSCREEN in evt.new_window_state) {
tabs.tab_bar_behavior = DynamicNotebook.TabBarBehavior.NEVER;
downloads.expand = false;
} else tabs.tab_bar_behavior = DynamicNotebook.TabBarBehavior.ALWAYS;
} else if (vtabs.position != 0)
tabs.tab_bar_behavior = DynamicNotebook.TabBarBehavior.NEVER;
else tabs.tab_bar_behavior = DynamicNotebook.TabBarBehavior.ALWAYS;
return false;
});
prompt.add(tabs);
prompt.add(vtabs);

downloads = new DownloadsBar();
downloads.expand = false;
Expand Down
88 changes: 88 additions & 0 deletions src/Widgets/VerticalTabs.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/**
* This file is part of Odysseus Web Browser (Copyright Adrian Cochrane 2021).
*
* Odysseus 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.
*
* Odysseus 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 Odysseus. If not, see <http://www.gnu.org/licenses/>.
*/
/** Allows dragging a sidebar pane providing an alternative, vertical view of the tabs. */
using Granite.Widgets;
public class Odysseus.VerticalTabs : Gtk.Paned {
DynamicNotebook inner;
SourceList tabs;
Gee.Map<Tab, SourceList.Item> tab_map = new Gee.HashMap<Tab, SourceList.Item>();

construct {
wide_handle = true;
orientation = Gtk.Orientation.HORIZONTAL;
position = 0;
}

public VerticalTabs(Granite.Widgets.DynamicNotebook inner) {
this.inner = inner; pack2(inner, true, false);
var tabsGrid = new Gtk.Grid(); pack1(tabsGrid, true, true);

tabsGrid.orientation = Gtk.Orientation.VERTICAL;
this.tabs = new SourceList();
var actionbar = new Gtk.ActionBar();
actionbar.get_style_context ().add_class (Gtk.STYLE_CLASS_INLINE_TOOLBAR);

var add_button = new Gtk.Button.from_icon_name("list-add-symbolic", Gtk.IconSize.SMALL_TOOLBAR);
add_button.tooltip_text = inner.add_button_tooltip;
add_button.clicked.connect(() => inner.new_tab_requested());
actionbar.add(add_button);
var rm_button = new Gtk.Button.from_icon_name("list-remove-symbolic", Gtk.IconSize.SMALL_TOOLBAR);
rm_button.tooltip_text = _("Close tab");
rm_button.clicked.connect(() => inner.remove_tab(inner.current));
tabs.notify["selected"].connect((pspec) => rm_button.sensitive = tabs.selected != null);
actionbar.add(rm_button);

tabsGrid.add(tabs);
tabsGrid.add(actionbar);

connect_events();
}

private void connect_events() {
inner.tab_added.connect(tab => {
var row = new SourceList.Item();
tab.bind_property("label", row, "name", BindingFlags.SYNC_CREATE);
tab.bind_property("icon", row, "icon", BindingFlags.SYNC_CREATE);
WebTab webtab = tab as WebTab;
if (webtab != null) webtab.web.bind_property("uri", row, "tooltip", BindingFlags.SYNC_CREATE);

tab_map[tab] = row;
tabs.root.add(row);
});
inner.tab_removed.connect(tab => {
SourceList.Item item;
if (tab_map.unset(tab, out item)) item.parent.remove(item);
});
// Can't as trivially handle inner.tab_reordered()... Not as important.
inner.tab_switched.connect(tab => {
Idle.add(() => {
tabs.selected = tab_map[inner.current];
return Source.REMOVE;
});
});

tabs.item_selected.connect(row => {
foreach (var entry in tab_map.entries) {
if (entry.@value == row) inner.current = entry.key;
}
});
notify["position"].connect(pspec => {
inner.tab_bar_behavior = position == 0 ?
DynamicNotebook.TabBarBehavior.ALWAYS : DynamicNotebook.TabBarBehavior.NEVER;
});
}
}
2 changes: 1 addition & 1 deletion src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ liberate = ['Liberate', 'Reader']
tokenized = ['AutomaticScrollBox', 'Completer', 'tokenized']

sources = ['Odysseus', 'BrowserWindow', 'Persistance']
widgets = ['WebTab','ProgressBin','WebNotebook','DownloadButton','DownloadBar', 'Chromeless']
widgets = ['WebTab','ProgressBin','WebNotebook','DownloadButton','DownloadBar', 'Chromeless', 'VerticalTabs']
header_widgets = ['AddressBar2', 'ButtonWithMenu', 'HeaderBarWithMenus']
overlay_widgets = ['FindToolbar', 'InfoContainer', 'Bookmarker']
traits = ['init', 'download-progress', 'download-window']
Expand Down

0 comments on commit 2f77dcd

Please sign in to comment.