GTK docking interfaces

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

 gpanthera.cc

View raw Download
text/x-c++ • 4.31 kiB
C++ source, ASCII text
        
            
1
#include "gpanthera.hh"
2
#include <iostream>
3
4
namespace gPanthera {
5
DockablePane::DockablePane(Gtk::Widget &child, const Glib::ustring &name, const Glib::ustring &label, Gtk::Image *icon, DockStack *stack, Gtk::Widget *custom_header)
6
: Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0), name(name) {
7
if(icon) {
8
this->icon = icon;
9
}
10
if(stack) {
11
this->stack = stack;
12
}
13
this->label.set_text(label);
14
auto header = Gtk::make_managed<Gtk::HeaderBar>();
15
header->set_show_close_button(false);
16
if(custom_header) {
17
header->set_custom_title(*custom_header);
18
} else {
19
header->set_custom_title(this->label);
20
}
21
auto header_menu_button = Gtk::make_managed<Gtk::MenuButton>();
22
auto header_menu = Gtk::make_managed<Gtk::Menu>();
23
header_menu_button->set_direction(Gtk::ARROW_NONE);
24
header_menu_button->set_popup(*header_menu);
25
auto close_menu_item = Gtk::make_managed<Gtk::MenuItem>("Close");
26
auto pop_out_menu_item = Gtk::make_managed<Gtk::MenuItem>("Pop out");
27
close_menu_item->signal_activate().connect([this]() {
28
if(this->stack) {
29
this->stack->set_visible_child("empty");
30
}
31
});
32
pop_out_menu_item->signal_activate().connect([this]() {
33
if(this->stack) {
34
this->pop_out();
35
}
36
});
37
header_menu->append(*close_menu_item);
38
header_menu->append(*pop_out_menu_item);
39
header_menu->show_all();
40
header->pack_end(*header_menu_button);
41
this->pack_start(*header, Gtk::PACK_SHRINK);
42
this->pack_end(child, Gtk::PACK_EXPAND_WIDGET);
43
show_all_children();
44
}
45
46
void DockablePane::redock(DockStack *stack) {
47
if(this->window) {
48
this->window->close();
49
this->window = nullptr;
50
}
51
this->stack = stack;
52
}
53
54
void DockablePane::pop_out() {
55
if(this->stack) {
56
this->stack->remove(*this);
57
this->stack = nullptr;
58
}
59
}
60
61
62
Glib::ustring DockablePane::get_identifier() const {
63
return name;
64
}
65
66
Gtk::Image *DockablePane::get_icon() const {
67
return icon;
68
}
69
70
Gtk::Label *DockablePane::get_label() {
71
return &label;
72
}
73
74
LayoutManager::LayoutManager() : Glib::ObjectBase("LayoutManager") {
75
}
76
77
void LayoutManager::add_pane(DockablePane *pane) {
78
panes.push_back(pane);
79
}
80
81
DockStack::DockStack(std::shared_ptr<LayoutManager> layout) : Gtk::Stack(), layout(layout) {
82
auto *empty_child = Gtk::make_managed<Gtk::Box>(Gtk::ORIENTATION_VERTICAL, 0);
83
add(*empty_child, "empty");
84
}
85
86
DockWindow::DockWindow(DockablePane *pane) {
87
this->pane = pane;
88
}
89
90
DockStackSwitcher::DockStackSwitcher(DockStack *stack) : Gtk::ButtonBox(Gtk::ORIENTATION_HORIZONTAL), stack(stack) {
91
this->stack->signal_add().connect([this](Gtk::Widget *child) {
92
this->update_buttons();
93
});
94
this->stack->signal_remove().connect([this](Gtk::Widget *child) {
95
this->update_buttons();
96
});
97
}
98
99
void DockStackSwitcher::update_buttons() {
100
for(auto const &child : get_children()) {
101
remove(*child);
102
}
103
for(auto const &widget : stack->get_children()) {
104
if(auto pane = dynamic_cast<DockablePane*>(widget)) {
105
auto *button = Gtk::make_managed<Gtk::Button>();
106
if(pane->get_icon()) {
107
button->set_image(*pane->get_icon());
108
}
109
button->signal_clicked().connect([this, pane]() {
110
if(stack->get_visible_child_name() == pane->get_identifier()) {
111
stack->set_visible_child("empty");
112
} else {
113
stack->set_visible_child(pane->get_identifier());
114
}
115
});
116
if(pane->get_identifier() != Glib::ustring("empty")) {
117
pack_start(*button);
118
}
119
}
120
}
121
}
122
123
void DockStack::add_pane(Gtk::Widget &child, const Glib::ustring &name) {
124
if(auto pane = dynamic_cast<DockablePane*>(&child)) {
125
pane->redock(this);
126
}
127
Gtk::Stack::add(child, name);
128
}
129
} // namespace gPanthera
130