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

Copy detach handlers

roundabout,
created on Monday, 24 March 2025, 10:06:13 (1742810773), received on Monday, 24 March 2025, 10:06:17 (1742810777)
Author identity: vlad <vlad.muntoiu@gmail.com>

ce1c866435dce414e3a866cfc3f771c337839367

gpanthera.cc

@@ -459,10 +459,16 @@ namespace gPanthera {

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    signal_child_removed.emit(&child);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                }
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            ContentStack::ContentStack(std::shared_ptr<ContentManager> content_manager)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            ContentStack::ContentStack(std::shared_ptr<ContentManager> content_manager, std::function<bool(ContentPage*)> detach_handler)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    : BaseStack(), content_manager(std::move(content_manager)) {
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    this->set_name("gpanthera_content_stack");
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    this->content_manager->add_stack(this);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                if(detach_handler) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    this->detach_handler = detach_handler;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    this->signal_detach.connect([this](ContentPage *widget) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        return this->detach_handler(widget);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    });
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    drop_target = Gtk::DropTarget::create(ContentPage::get_type(), Gdk::DragAction::MOVE);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    this->add_controller(drop_target);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -486,7 +492,7 @@ namespace gPanthera {

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                                this->add_page(*page);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                                return true;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                            }
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        auto new_stack = Gtk::make_managed<ContentStack>(this->content_manager);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        auto new_stack = Gtk::make_managed<ContentStack>(this->content_manager, this->detach_handler);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                            auto this_notebook = dynamic_cast<ContentNotebook*>(this->get_parent());
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                            auto new_switcher = Gtk::make_managed<ContentTabBar>(new_stack, this_notebook ? this_notebook->get_switcher()->get_orientation() : Gtk::Orientation::HORIZONTAL);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                            auto new_notebook = Gtk::make_managed<ContentNotebook>(new_stack, new_switcher, this_notebook ? this_notebook->get_tab_position() : Gtk::PositionType::TOP);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -522,6 +528,10 @@ namespace gPanthera {

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    }, false);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                }
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            std::function<bool(ContentPage*)> ContentStack::get_detach_handler() const {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                return this->detach_handler;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                ContentNotebook::ContentNotebook(ContentStack *stack, ContentTabBar *switcher, Gtk::PositionType tab_position) : Gtk::Box(), stack(stack), switcher(switcher), tab_position(tab_position) {
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    this->append(*stack);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    if(tab_position == Gtk::PositionType::TOP || tab_position == Gtk::PositionType::BOTTOM) {
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -777,6 +787,37 @@ namespace gPanthera {

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    });
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    action_group->add_action(close_action);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    context_menu->append(_("Close"), "win.close");
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto close_all_action = Gio::SimpleAction::create("close-all");
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                close_all_action->signal_activate().connect([this](const Glib::VariantBase&) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    for(auto page : collect_children(*this->page->get_stack())) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        if(auto content_page = dynamic_cast<ContentPage*>(page)) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            if(!content_page->signal_close.emit()) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                content_page->redock(nullptr);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                });
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                action_group->add_action(close_all_action);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                context_menu->append(_("Close all"), "win.close-all");
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto close_others_action = Gio::SimpleAction::create("close-others");
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                close_others_action->signal_activate().connect([this](const Glib::VariantBase&) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    for(auto page : collect_children(*this->page->get_stack())) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        if(auto content_page = dynamic_cast<ContentPage*>(page)) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            if(content_page != this->page && !content_page->signal_close.emit()) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                content_page->redock(nullptr);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                });
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                action_group->add_action(close_others_action);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                context_menu->append(_("Close others"), "win.close-others");
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto detach_action = Gio::SimpleAction::create("detach");
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                detach_action->signal_activate().connect([this](const Glib::VariantBase&) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    auto stack = dynamic_cast<ContentStack*>(this->page->get_stack());
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    bool result = stack->signal_detach.emit(this->page);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                });
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                action_group->add_action(detach_action);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                context_menu->append(_("New window"), "win.detach");
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    // TODO: Add more actions: "New window", "Split left", "Split right", "Split top", "Split bottom", "Close all", "Close others", "Close to the right", "Close to the left"
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    this->insert_action_group("win", action_group);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    // Attach the context menu to the button
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                            
                                

gpanthera.hh

@@ -152,13 +152,15 @@ namespace gPanthera {

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                };
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                class ContentStack : public BaseStack {
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            private:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            protected:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                std::function<bool(ContentPage*)> detach_handler;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                public:
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    sigc::signal<bool(ContentPage*)> signal_detach;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                std::function<bool(ContentPage*)> get_detach_handler() const;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    std::shared_ptr<ContentManager> content_manager;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    std::shared_ptr<Gtk::DropTarget> drop_target;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    sigc::signal<void()> signal_leave_empty;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                explicit ContentStack(std::shared_ptr<ContentManager> content_manager);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                explicit ContentStack(std::shared_ptr<ContentManager> content_manager, std::function<bool(ContentPage*)> detach_handler = nullptr);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    void make_paned(Gtk::Orientation orientation, Gtk::PackType pack_type);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    void add_page(ContentPage &child);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    void remove_with_paned();
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                            
                                

panthera-www.cc

@@ -54,17 +54,9 @@ protected:

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    auto inner_paned = Gtk::make_managed<Gtk::Paned>(Gtk::Orientation::VERTICAL);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    auto content = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 0);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    auto content_manager = std::make_shared<gPanthera::ContentManager>();
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto content_stack = Gtk::make_managed<gPanthera::ContentStack>(content_manager);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto content_stack_switcher = Gtk::make_managed<gPanthera::ContentTabBar>(content_stack, Gtk::Orientation::HORIZONTAL);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                content_manager->add_stack(content_stack);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto page_1_content = Gtk::make_managed<Gtk::Label>("Page 1...");
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto page_1_tab = new Gtk::Label("Page 1");
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto page_1 = Gtk::make_managed<gPanthera::ContentPage>(content_manager, content_stack, page_1_content, page_1_tab);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto page_2_content = Gtk::make_managed<Gtk::Label>("Page 2...");
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto page_2_tab = new Gtk::Label("Page 2");
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto page_2 = Gtk::make_managed<gPanthera::ContentPage>(content_manager, content_stack, page_2_content, page_2_tab);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                content_stack->signal_detach.connect([](gPanthera::ContentPage *widget) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    auto new_stack = Gtk::make_managed<gPanthera::ContentStack>(widget->content_manager);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                std::function<bool(gPanthera::ContentPage*)> detach_handler;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                detach_handler = [](gPanthera::ContentPage *widget) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    auto new_stack = Gtk::make_managed<gPanthera::ContentStack>(widget->content_manager, widget->get_stack()->get_detach_handler());
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        auto new_switcher = Gtk::make_managed<gPanthera::ContentTabBar>(new_stack, Gtk::Orientation::HORIZONTAL);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        auto new_notebook = Gtk::make_managed<gPanthera::ContentNotebook>(new_stack, new_switcher);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        auto window = new gPanthera::ContentWindow(new_notebook);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -75,7 +67,17 @@ protected:

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                            delete window;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        });
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        return true;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                });
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                };
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto content_stack = Gtk::make_managed<gPanthera::ContentStack>(content_manager, detach_handler);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto content_stack_switcher = Gtk::make_managed<gPanthera::ContentTabBar>(content_stack, Gtk::Orientation::HORIZONTAL);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                content_manager->add_stack(content_stack);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto page_1_content = Gtk::make_managed<Gtk::Label>("Page 1...");
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto page_1_tab = new Gtk::Label("Page 1");
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto page_1 = Gtk::make_managed<gPanthera::ContentPage>(content_manager, content_stack, page_1_content, page_1_tab);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto page_2_content = Gtk::make_managed<Gtk::Label>("Page 2...");
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto page_2_tab = new Gtk::Label("Page 2");
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                auto page_2 = Gtk::make_managed<gPanthera::ContentPage>(content_manager, content_stack, page_2_content, page_2_tab);
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    content->set_name("content_box");
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    auto content_notebook = Gtk::make_managed<gPanthera::ContentNotebook>(content_stack, content_stack_switcher, Gtk::PositionType::TOP);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    content->append(*content_notebook);