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