GTK docking interfaces and more

By using this site, you agree to have cookies stored on your device, strictly for functional purposes, such as storing your session and preferences.

Dismiss

 panthera-www.cc

View raw Download
text/x-c++ • 8.35 kiB
C++ source, ASCII text
        
            
1
#include "gpanthera.hh"
2
#include <gtkmm.h>
3
#include <glibmm.h>
4
#include <glibmm/ustring.h>
5
#include <iostream>
6
#include <memory>
7
#include <libintl.h>
8
#include <locale.h>
9
#include <gtk/gtk.h>
10
#include <gdk/gdk.h>
11
#include <webkit/webkit.h>
12
13
class PantheraWww : public Gtk::Application {
14
Gtk::Window *window = Gtk::make_managed<Gtk::Window>();
15
protected:
16
std::shared_ptr<gPanthera::LayoutManager> layout_manager;
17
std::shared_ptr<gPanthera::ContentManager> content_manager;
18
19
static void notify_callback(GObject *object, GParamSpec *pspec, gpointer data) {
20
auto parent = gtk_widget_get_parent(gtk_widget_get_parent(GTK_WIDGET(object)));
21
if(auto page = dynamic_cast<gPanthera::ContentPage*>(Glib::wrap(parent))) {
22
if(g_strcmp0(pspec->name, "title") == 0) {
23
if(auto label = dynamic_cast<Gtk::Label*>(page->tab_widget)) {
24
label->set_label(webkit_web_view_get_title(WEBKIT_WEB_VIEW(object)));
25
}
26
}
27
}
28
}
29
30
void on_new_tab(gPanthera::ContentStack *stack) {
31
if(!stack) {
32
// Find the current area
33
stack = content_manager->get_last_operated_page()->get_stack();
34
}
35
36
WebKitWebView *webview = WEBKIT_WEB_VIEW(webkit_web_view_new());
37
gtk_widget_set_hexpand(GTK_WIDGET(webview), true);
38
gtk_widget_set_vexpand(GTK_WIDGET(webview), true);
39
auto page_content = Gtk::make_managed<Gtk::Box>();
40
gtk_box_append(page_content->gobj(), GTK_WIDGET(webview));
41
auto page_tab = new Gtk::Label("Untitled");
42
auto page = Gtk::make_managed<gPanthera::ContentPage>(content_manager, stack, page_content, page_tab);
43
g_signal_connect(webview, "notify", G_CALLBACK(notify_callback), page->gobj());
44
webkit_web_view_load_uri(webview, "about:blank");
45
stack->add_page(*page);
46
}
47
48
void on_startup() override {
49
Gtk::Application::on_startup();
50
add_window(*window);
51
window->set_default_size(600, 400);
52
layout_manager = std::make_shared<gPanthera::LayoutManager>();
53
auto dock_stack_1 = Gtk::make_managed<gPanthera::DockStack>(layout_manager, "One");
54
auto switcher_1 = Gtk::make_managed<gPanthera::DockStackSwitcher>(dock_stack_1, Gtk::Orientation::HORIZONTAL);
55
auto dock_stack_2 = Gtk::make_managed<gPanthera::DockStack>(layout_manager, "Two");
56
auto switcher_2 = Gtk::make_managed<gPanthera::DockStackSwitcher>(dock_stack_2, Gtk::Orientation::VERTICAL);
57
auto pane_1_content = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 0);
58
auto debug_button = Gtk::make_managed<Gtk::Button>("Debug");
59
pane_1_content->append(*debug_button);
60
auto pane_2_content = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 0);
61
pane_2_content->append(*Gtk::make_managed<Gtk::Label>("Pane 2 content"));
62
auto pane_3_content = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 0);
63
pane_3_content->append(*Gtk::make_managed<Gtk::Label>("Pane 3 content"));
64
auto pane_1_icon = Gtk::make_managed<Gtk::Image>();
65
pane_1_icon->set_from_icon_name("go-home-symbolic");
66
auto pane_2_icon = Gtk::make_managed<Gtk::Image>();
67
pane_2_icon->set_from_icon_name("folder-symbolic");
68
auto pane_3_icon = Gtk::make_managed<Gtk::Image>();
69
pane_3_icon->set_from_icon_name("network-transmit-receive-symbolic");
70
auto pane_1 = Gtk::make_managed<gPanthera::DockablePane>(layout_manager, *pane_1_content, "pane1", "Pane 1", pane_1_icon);
71
auto pane_2 = Gtk::make_managed<gPanthera::DockablePane>(layout_manager, *pane_2_content, "pane2", "Pane 2", pane_2_icon);
72
auto pane_3 = Gtk::make_managed<gPanthera::DockablePane>(layout_manager, *pane_3_content, "pane3", "Pane 3", pane_3_icon);
73
74
dock_stack_1->set_transition_type(Gtk::StackTransitionType::SLIDE_LEFT_RIGHT);
75
dock_stack_1->set_transition_duration(125);
76
dock_stack_1->set_expand(true);
77
dock_stack_2->set_transition_type(Gtk::StackTransitionType::SLIDE_UP_DOWN);
78
dock_stack_2->set_transition_duration(125);
79
dock_stack_2->set_expand(true);
80
81
dock_stack_1->add_pane(*pane_1);
82
dock_stack_1->add_pane(*pane_3);
83
dock_stack_2->add_pane(*pane_2);
84
85
auto outer_grid = Gtk::make_managed<Gtk::Grid>();
86
outer_grid->attach(*switcher_2, 0, 1, 1, 1);
87
outer_grid->attach(*switcher_1, 1, 2, 1, 1);
88
auto outer_paned = Gtk::make_managed<Gtk::Paned>(Gtk::Orientation::HORIZONTAL);
89
outer_paned->set_start_child(*dock_stack_2);
90
auto inner_paned = Gtk::make_managed<Gtk::Paned>(Gtk::Orientation::VERTICAL);
91
auto content = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 0);
92
content_manager = std::make_shared<gPanthera::ContentManager>();
93
std::function<bool(gPanthera::ContentPage*)> detach_handler;
94
detach_handler = [](gPanthera::ContentPage *widget) {
95
auto new_stack = Gtk::make_managed<gPanthera::ContentStack>(widget->content_manager, widget->get_stack()->get_detach_handler());
96
auto new_switcher = Gtk::make_managed<gPanthera::ContentTabBar>(new_stack, Gtk::Orientation::HORIZONTAL, dynamic_cast<gPanthera::ContentTabBar*>(widget->get_stack()->get_parent()->get_first_child())->get_extra_child_function());
97
auto new_notebook = Gtk::make_managed<gPanthera::ContentNotebook>(new_stack, new_switcher);
98
auto window = new gPanthera::ContentWindow(new_notebook);
99
widget->redock(new_stack);
100
window->present();
101
new_stack->signal_leave_empty.connect([window]() {
102
window->close();
103
delete window;
104
});
105
return true;
106
};
107
108
auto return_extra_child = [this](gPanthera::ContentTabBar *switcher) {
109
auto new_tab_button = Gtk::make_managed<Gtk::Button>();
110
new_tab_button->set_child(*Gtk::make_managed<Gtk::Image>(Gio::Icon::create("list-add-symbolic")));
111
new_tab_button->set_tooltip_text("New tab");
112
new_tab_button->signal_clicked().connect([this, switcher]() {
113
on_new_tab(switcher->get_stack());
114
});
115
return new_tab_button;
116
};
117
auto content_stack = Gtk::make_managed<gPanthera::ContentStack>(content_manager, detach_handler);
118
auto content_stack_switcher = Gtk::make_managed<gPanthera::ContentTabBar>(content_stack, Gtk::Orientation::HORIZONTAL, return_extra_child);
119
content_manager->add_stack(content_stack);
120
WebKitWebView *webview = WEBKIT_WEB_VIEW(webkit_web_view_new());
121
webkit_web_view_load_uri(webview, "https://www.example.com");
122
gtk_widget_set_hexpand(GTK_WIDGET(webview), true);
123
gtk_widget_set_vexpand(GTK_WIDGET(webview), true);
124
auto page_1_content = Gtk::make_managed<Gtk::Box>();
125
gtk_box_append(page_1_content->gobj(), GTK_WIDGET(webview));
126
auto page_1_tab = new Gtk::Label("Page 1");
127
auto page_1 = Gtk::make_managed<gPanthera::ContentPage>(content_manager, content_stack, page_1_content, page_1_tab);
128
auto page_2_content = Gtk::make_managed<Gtk::Label>("Page 2...");
129
auto page_2_tab = new Gtk::Label("Page 2");
130
auto page_2 = Gtk::make_managed<gPanthera::ContentPage>(content_manager, content_stack, page_2_content, page_2_tab);
131
content->set_name("content_box");
132
auto content_notebook = Gtk::make_managed<gPanthera::ContentNotebook>(content_stack, content_stack_switcher, Gtk::PositionType::TOP);
133
content->append(*content_notebook);
134
inner_paned->set_start_child(*content);
135
inner_paned->set_end_child(*dock_stack_1);
136
outer_paned->set_end_child(*inner_paned);
137
outer_grid->attach(*outer_paned, 1, 1, 1, 1);
138
window->set_child(*outer_grid);
139
debug_button->signal_clicked().connect([this]() {
140
std::cout << "Last operated page: " << content_manager->get_last_operated_page()->get_name() << std::endl;
141
});
142
// TODO: Use the last operated page and allow opening tabs next to the last operated page using panes
143
}
144
145
void on_activate() override {
146
window->present();
147
}
148
public:
149
static Glib::RefPtr<PantheraWww> create() {
150
return Glib::make_refptr_for_instance<PantheraWww>(new PantheraWww());
151
}
152
};
153
154
int main(int argc, char *argv[]) {
155
gPanthera::init();
156
auto app = PantheraWww::create();
157
return app->run(argc, argv);
158
}
159