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