gpanthera.cc
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