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

 gpanthera.cc

View raw Download
text/x-c++ • 4.83 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
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->child = &child;
43
this->pack_end(child, Gtk::PACK_EXPAND_WIDGET);
44
show_all_children();
45
}
46
47
void DockablePane::redock(DockStack *stack) {
48
if(this->window != nullptr) {
49
this->window->close();
50
delete this->window;
51
this->window = nullptr;
52
}
53
this->stack = stack;
54
}
55
56
void DockablePane::pop_out() {
57
if(this->stack != nullptr) {
58
this->stack->remove(*this);
59
this->stack = nullptr;
60
}
61
62
if(this->window == nullptr) {
63
this->remove(*this->header);
64
this->window = new DockWindow(this);
65
this->window->set_titlebar(*this->header);
66
this->window->show_all();
67
}
68
}
69
70
Glib::ustring DockablePane::get_identifier() const {
71
return name;
72
}
73
74
Gtk::Image *DockablePane::get_icon() const {
75
return icon;
76
}
77
78
Gtk::HeaderBar *DockablePane::get_header() const {
79
return header;
80
}
81
82
Gtk::Widget *DockablePane::get_child() const {
83
return child;
84
}
85
86
Gtk::Label *DockablePane::get_label() {
87
return &label;
88
}
89
90
LayoutManager::LayoutManager() : Glib::ObjectBase("LayoutManager") {
91
}
92
93
void LayoutManager::add_pane(DockablePane *pane) {
94
panes.push_back(pane);
95
}
96
97
DockStack::DockStack(std::shared_ptr<LayoutManager> layout) : Gtk::Stack(), layout(layout) {
98
auto *empty_child = Gtk::make_managed<Gtk::Box>(Gtk::ORIENTATION_VERTICAL, 0);
99
add(*empty_child, "empty");
100
}
101
102
DockWindow::DockWindow(DockablePane *pane) {
103
this->pane = pane;
104
this->add(*pane);
105
}
106
107
DockStackSwitcher::DockStackSwitcher(DockStack *stack) : Gtk::ButtonBox(Gtk::ORIENTATION_HORIZONTAL), stack(stack) {
108
this->stack->signal_add().connect([this](Gtk::Widget *child) {
109
this->update_buttons();
110
});
111
this->stack->signal_remove().connect([this](Gtk::Widget *child) {
112
this->update_buttons();
113
});
114
}
115
116
void DockStackSwitcher::update_buttons() {
117
for(auto &child : get_children()) {
118
if(child) {
119
remove(*child);
120
}
121
}
122
for(auto const &widget : stack->get_children()) {
123
if(auto pane = dynamic_cast<DockablePane*>(widget)) {
124
auto *button = Gtk::make_managed<Gtk::Button>();
125
if(pane->get_icon()) {
126
button->set_image(*pane->get_icon());
127
}
128
button->signal_clicked().connect([this, pane]() {
129
if(stack->get_visible_child_name() == pane->get_identifier()) {
130
stack->set_visible_child("empty");
131
} else {
132
stack->set_visible_child(pane->get_identifier());
133
}
134
});
135
if(pane->get_identifier() != Glib::ustring("empty")) {
136
pack_start(*button);
137
}
138
}
139
}
140
}
141
142
void DockStack::add_pane(Gtk::Widget &child, const Glib::ustring &name) {
143
if(auto pane = dynamic_cast<DockablePane*>(&child)) {
144
pane->redock(this);
145
}
146
Gtk::Stack::add(child, name);
147
}
148
} // namespace gPanthera
149