diff --git a/synfig-studio/src/gui/docks/dockable.cpp b/synfig-studio/src/gui/docks/dockable.cpp index 30845a6ba60..007e6e91ae5 100644 --- a/synfig-studio/src/gui/docks/dockable.cpp +++ b/synfig-studio/src/gui/docks/dockable.cpp @@ -114,7 +114,8 @@ Dockable::Dockable(const synfig::String& name,const synfig::String& local_name,G header_box_.pack_end(*bttn_close,false,false); bttn_close->show(); bttn_close->set_relief(Gtk::RELIEF_NONE); - bttn_close->signal_clicked().connect(sigc::mem_fun(*this,&Dockable::detach)); + bttn_close->signal_clicked().connect( + sigc::bind(sigc::ptr_fun(&DockManager::remove_widget_by_pointer_recursive), this)); bttn_close->set_border_width(0); dynamic_cast(bttn_close->get_child())->set_padding(0,0); } @@ -183,7 +184,7 @@ Dockable::on_drag_end(const Glib::RefPtr&/*context*/) { if(!dnd_success_) { - detach(); + DockManager::remove_widget_recursive(*this); present(); } } @@ -303,13 +304,6 @@ Dockable::add_button(const Gtk::StockID& stock_id, const synfig::String& tooltip } -void -Dockable::detach() -{ - if(parent_) - parent_->remove(*this); -} - void Dockable::present() { @@ -320,8 +314,12 @@ Dockable::present() } else { + show(); + DockBook* book = manage(new DockBook()); + book->show(); + book->add(*this); DockDialog* dock_dialog(new DockDialog()); - dock_dialog->get_dock_book().add(*this); + dock_dialog->add(*book); /* //hack: always display composition selector on top of canvas browser if(get_name()=="canvases") dock_dialog->set_composition_selector(true); diff --git a/synfig-studio/src/gui/docks/dockable.h b/synfig-studio/src/gui/docks/dockable.h index dee8194693e..1d4d7b5013b 100644 --- a/synfig-studio/src/gui/docks/dockable.h +++ b/synfig-studio/src/gui/docks/dockable.h @@ -116,8 +116,6 @@ class Dockable : public Gtk::Table Gtk::ToolButton* add_button(const Gtk::StockID& stock_id, const synfig::String& tooltip=synfig::String()); - void detach(); - void present(); void attach_dnd_to(Gtk::Widget& widget); diff --git a/synfig-studio/src/gui/docks/dockbook.cpp b/synfig-studio/src/gui/docks/dockbook.cpp index 2e839b30388..e00130ff431 100644 --- a/synfig-studio/src/gui/docks/dockbook.cpp +++ b/synfig-studio/src/gui/docks/dockbook.cpp @@ -70,6 +70,34 @@ DockBook::DockBook() //set_extension_events(Gdk::EXTENSION_EVENTS_ALL); set_show_tabs(true); deleting_=false; + + Gtk::Button *button_left = manage(new Gtk::Button()); + Gtk::Button *button_right = manage(new Gtk::Button()); + Gtk::Button *button_top = manage(new Gtk::Button()); + Gtk::Button *button_bottom = manage(new Gtk::Button()); + + button_left->drag_dest_set(listTargets); + button_right->drag_dest_set(listTargets); + button_top->drag_dest_set(listTargets); + button_bottom->drag_dest_set(listTargets); + + button_left->signal_drag_data_received().connect( + sigc::mem_fun(*this,&DockBook::drop_on_left)); + button_right->signal_drag_data_received().connect( + sigc::mem_fun(*this,&DockBook::drop_on_right)); + button_top->signal_drag_data_received().connect( + sigc::mem_fun(*this,&DockBook::drop_on_top)); + button_bottom->signal_drag_data_received().connect( + sigc::mem_fun(*this,&DockBook::drop_on_bottom)); + + Gtk::Table *table = manage(new Gtk::Table(3, 3, true)); + table->attach(*button_left, 0, 1, 1, 2, Gtk::FILL, Gtk::FILL); + table->attach(*button_right, 2, 3, 1, 2, Gtk::FILL, Gtk::FILL); + table->attach(*button_top, 1, 2, 0, 1, Gtk::FILL, Gtk::FILL); + table->attach(*button_bottom, 1, 2, 2, 3, Gtk::FILL, Gtk::FILL); + table->show_all(); + + set_action_widget(table, Gtk::PACK_END); } DockBook::~DockBook() @@ -85,6 +113,45 @@ DockBook::clear() remove(static_cast(*get_nth_page(get_n_pages()-1))); } +void +DockBook::drop_on(bool vertical, bool first, const Glib::RefPtr& context, const Gtk::SelectionData& selection_data, guint time) +{ + if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8)) + { + Dockable& dockable(**reinterpret_cast(const_cast(selection_data.get_data()))); + if (DockManager::add_dockable(*this, dockable, vertical, first)) + { + context->drag_finish(true, false, time); + return; + } + } + context->drag_finish(false, false, time); +} + +void +DockBook::drop_on_left(const Glib::RefPtr& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time) +{ + drop_on(false, true, context, selection_data, time); +} + +void +DockBook::drop_on_right(const Glib::RefPtr& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time) +{ + drop_on(false, false, context, selection_data, time); +} + +void +DockBook::drop_on_top(const Glib::RefPtr& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time) +{ + drop_on(true, true, context, selection_data, time); +} + +void +DockBook::drop_on_bottom(const Glib::RefPtr& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time) +{ + drop_on(true, false, context, selection_data, time); +} + void DockBook::on_drag_data_received(const Glib::RefPtr& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time) { @@ -104,7 +171,7 @@ DockBook::on_drag_data_received(const Glib::RefPtr& context, i void DockBook::add(Dockable& dockable, int position) { - dockable.detach(); + DockManager::remove_widget_recursive(dockable); if(position==-1) append_page(dockable, " "); @@ -243,7 +310,7 @@ DockBook::tab_button_pressed(GdkEventButton* event, Dockable* dockable) tabmenu->items().push_back( Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-close"), - sigc::mem_fun(*dockable,&Dockable::detach) + sigc::bind(sigc::ptr_fun(&DockManager::remove_widget_by_pointer_recursive), this) ) ); diff --git a/synfig-studio/src/gui/docks/dockbook.h b/synfig-studio/src/gui/docks/dockbook.h index 17723a10700..aaa6fde202e 100644 --- a/synfig-studio/src/gui/docks/dockbook.h +++ b/synfig-studio/src/gui/docks/dockbook.h @@ -53,6 +53,12 @@ class DockBook : public Gtk::Notebook bool deleting_; protected: + void drop_on(bool vertical, bool first, const Glib::RefPtr& context, const Gtk::SelectionData& selection_data, guint time); + void drop_on_left(const Glib::RefPtr& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time); + void drop_on_right(const Glib::RefPtr& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time); + void drop_on_top(const Glib::RefPtr& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time); + void drop_on_bottom(const Glib::RefPtr& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time); + public: DockBook(); ~DockBook(); diff --git a/synfig-studio/src/gui/docks/dockdialog.cpp b/synfig-studio/src/gui/docks/dockdialog.cpp index 0ae6e5ee432..612f075b8ce 100644 --- a/synfig-studio/src/gui/docks/dockdialog.cpp +++ b/synfig-studio/src/gui/docks/dockdialog.cpp @@ -82,13 +82,7 @@ using namespace studio; DockDialog::DockDialog(): Gtk::Window(Gtk::WINDOW_TOPLEVEL) { - composition_selector_=false; is_deleting=false; - is_horizontal=false; - last_dock_book=0; - box=0; - - widget_comp_select=new Widget_CompSelect(); // Give ourselves an ID that is most likely unique set_id(synfig::UniqueID().get_uid()^reinterpret_cast(this)); @@ -117,7 +111,6 @@ DockDialog::DockDialog(): // Register with the dock manager App::dock_manager->dock_dialog_list_.push_back(this); - // connect our signals signal_delete_event().connect( sigc::hide( @@ -125,17 +118,6 @@ DockDialog::DockDialog(): ) ); -/* - App::signal_canvas_view_focus().connect( - sigc::hide( - sigc::mem_fun( - *this, - &DockDialog::refresh_accel_group - ) - ) - ); -*/ - add_accel_group(App::ui_manager()->get_accel_group()); App::signal_present_all().connect(sigc::mem_fun0(*this,&DockDialog::present)); @@ -147,30 +129,6 @@ DockDialog::~DockDialog() is_deleting=true; - // Remove all of the dock books - for(;!dock_book_list.empty();dock_book_list.pop_front()) - { - dock_book_list.front()->clear(); - - //! \todo Fix this UGLY HACK - // The following line really should be uncommented, - // but it causes crashes. Without it, a small - // memory hole is created--but at least it doesn't crash - // delete dock_book_list.front(); - - // Oddly enough, the following line should - // theoretically do the same thing after this - // class is destroyed, but it doesn't seem to - // cause a crash. It does, however, trigger this warning: - // - // A floating object was finalized. This means that someone - // called g_object_unref() on an object that had only a - // floating reference; the initial floating reference is not - // owned by anyone and must be removed with g_object_ref_sink(). - // - // manage(dock_book_list.front()); - } - // Remove us from the dock manager if(App::dock_manager)try{ std::list::iterator iter; @@ -185,39 +143,8 @@ DockDialog::~DockDialog() { synfig::warning("DockDialog::~DockDialog(): Exception thrown when trying to remove from dock manager...?"); } - - delete widget_comp_select; -} - -void -DockDialog::drop_on_prepend(const Glib::RefPtr& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time) -{ - if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8)) - { - Dockable& dockable(**reinterpret_cast(const_cast(selection_data.get_data()))); - prepend_dock_book()->add(dockable); - context->drag_finish(true, false, time); - return; - } - - context->drag_finish(false, false, time); } -void -DockDialog::drop_on_append(const Glib::RefPtr& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time) -{ - if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8)) - { - Dockable& dockable(**reinterpret_cast(const_cast(selection_data.get_data()))); - append_dock_book()->add(dockable); - context->drag_finish(true, false, time); - return; - } - - context->drag_finish(false, false, time); -} - - void DockDialog::on_hide() { @@ -225,246 +152,6 @@ DockDialog::on_hide() close(); } -DockBook* -DockDialog::prepend_dock_book() -{ - if(is_deleting)return 0; - - dock_book_list.push_front(new DockBook); - last_dock_book=dock_book_list.front(); - - - last_dock_book->signal_empty().connect( - sigc::bind( - sigc::mem_fun(*this,&DockDialog::erase_dock_book), - last_dock_book - ) - ); - - dock_book_sizes_.insert(dock_book_sizes_.begin(),225); - refresh(); - return last_dock_book; -} - -bool -DockDialog::on_key_press_event(GdkEventKey* event) -{ - Gtk::Widget* focused_widget = get_focus(); - if(focused_widget && focused_widget_has_priority(focused_widget)) - { - if(focused_widget->event((GdkEvent*)event)) - return true; - } - else if(Gtk::Window::on_key_press_event(event)) - return true; - else - if (focused_widget) return focused_widget->event((GdkEvent*)event); - return false; -} - -bool -DockDialog::focused_widget_has_priority(Gtk::Widget * focused) -{ - if(dynamic_cast(focused)) - return true; - return false; -} - -DockBook* -DockDialog::append_dock_book() -{ - if(is_deleting)return 0; - - dock_book_list.push_back(new DockBook); - last_dock_book=dock_book_list.back(); - last_dock_book->signal_empty().connect( - sigc::bind( - sigc::mem_fun(*this,&DockDialog::erase_dock_book), - last_dock_book - ) - ); - last_dock_book->signal_changed().connect( - sigc::mem_fun(*this,&DockDialog::refresh_title) - ); - last_dock_book->signal_changed().connect( - sigc::mem_fun(*this,&DockDialog::refresh_title) - ); - dock_book_sizes_.push_back(225); - - //last_dock_book->show(); - refresh(); - return last_dock_book; -} - -void -DockDialog::erase_dock_book(DockBook* dock_book) -{ - if(is_deleting)return; - - std::list::iterator iter; - for(iter=dock_book_list.begin();iter!=dock_book_list.end();++iter) - if(*iter==dock_book) - { - dock_book_list.erase(iter); - - if(dock_book_list.empty()) - { - last_dock_book=0; - close(); - return; - } - else - { - if(last_dock_book==dock_book) - last_dock_book=dock_book_list.front(); - } - - refresh(); - - return; - } -} - -void -DockDialog::refresh() -{ - // synfig::info("dock_book_list.size()=%d",dock_book_list.size()); - //remove(); - - if(dock_book_list.empty()) - return; - - if(box)delete box; - box=(manage(is_horizontal?(Gtk::Box*)new Gtk::HBox:(Gtk::Box*)new Gtk::VBox)); - add(*box); - - box->pack_start(*widget_comp_select,false,true); - - Gtk::Button* append_button(manage(new Gtk::Button)); - Gtk::Button* prepend_button(manage(new Gtk::Button)); - - std::list listTargets; - listTargets.push_back( Gtk::TargetEntry("DOCK") ); - - append_button->drag_dest_set(listTargets); - prepend_button->drag_dest_set(listTargets); - - append_button->signal_drag_data_received().connect( - sigc::mem_fun(*this,&DockDialog::drop_on_append) - ); - - prepend_button->signal_drag_data_received().connect( - sigc::mem_fun(*this,&DockDialog::drop_on_prepend) - ); - - box->pack_start(*prepend_button,false,true); - box->pack_end(*append_button,false,true); - - //prepend_button->show(); - //append_button->show(); - panels_.clear(); - - if(dock_book_list.size()==1) - { - box->pack_start(get_dock_book(),true,true); - } - else - { - Gtk::Paned* parent(manage(is_horizontal?(Gtk::Paned*)new Gtk::HPaned:(Gtk::Paned*)new Gtk::VPaned)); - - panels_.push_back(parent); - - if(panels_.size()<=dock_book_sizes_.size()) - panels_.back()->set_position(dock_book_sizes_[panels_.size()-1]); - panels_.back()->property_position().signal_changed().connect( - sigc::mem_fun(*this,&DockDialog::rebuild_sizes) - ); - //parent->show(); - parent->add1(*dock_book_list.front()); - //dock_book_list.front()->show(); - - box->pack_start(*parent,true,true); - - std::list::iterator iter,next; - for(next=dock_book_list.begin(),next++,iter=next++;next!=dock_book_list.end();iter=next++) - { - Gtk::Paned* current(manage(is_horizontal?(Gtk::Paned*)new Gtk::HPaned:(Gtk::Paned*)new Gtk::VPaned)); - panels_.push_back(current); - - if(panels_.size()<=dock_book_sizes_.size()) - panels_.back()->set_position(dock_book_sizes_[panels_.size()-1]); - panels_.back()->property_position().signal_changed().connect( - sigc::mem_fun(*this,&DockDialog::rebuild_sizes) - ); - - - parent->add2(*current); - - current->add1(**iter); - //(*iter)->show(); - //current->show(); - - parent=current; - } - parent->add2(**iter); - //(*iter)->show(); - } - - box->show_all(); - if(!composition_selector_) - widget_comp_select->hide(); - rebuild_sizes(); -} - -void -DockDialog::rebuild_sizes() -{ - unsigned int i=0; - dock_book_sizes_.clear(); - for(i=0;iget_position()); - } -} - -void -DockDialog::set_dock_book_sizes(const std::vector& new_sizes) -{ - unsigned int i=0; - for(i=0;iset_position(new_sizes[i]); - } - dock_book_sizes_=new_sizes; - //rebuild_sizes(); -} - -void -DockDialog::refresh_accel_group() -{ -/* - if(last_accel_group_) - { - last_accel_group_->unlock(); - remove_accel_group(last_accel_group_); - last_accel_group_=Glib::RefPtr(); - } - - etl::loose_handle canvas_view(App::get_selected_canvas_view()); - if(canvas_view) - { - last_accel_group_=canvas_view->get_accel_group(); - last_accel_group_->lock(); - add_accel_group(last_accel_group_); - } -*/ - etl::loose_handle canvas_view(App::get_selected_canvas_view()); - if(canvas_view) - { - canvas_view->mainmenu.accelerate(*this); - } -} - bool DockDialog::close() { @@ -476,113 +163,3 @@ DockDialog::close() delete this; return true; } - -DockBook& -DockDialog::get_dock_book() -{ - if(!last_dock_book) - return *append_dock_book(); - return *last_dock_book; -} - -const DockBook& -DockDialog::get_dock_book()const -{ - return *last_dock_book; -} - - -synfig::String -DockDialog::get_contents()const -{ - synfig::String ret; - - std::list::const_iterator iter; - for(iter=dock_book_list.begin();iter!=dock_book_list.end();++iter) - { - if(!ret.empty()) - ret+=is_horizontal?" | ":" - "; - ret+=(*iter)->get_contents(); - } - - - return ret; -} - -void -DockDialog::set_contents(const synfig::String& z) -{ - int x,y; - get_size(x,y); - - synfig::String str(z); - while(!str.empty()) - { - synfig::String::size_type separator=str.find_first_of('-'); - { - synfig::String::size_type sep2=str.find_first_of('|'); - if(separator!=synfig::String::npos || sep2!=synfig::String::npos) - { - if((separator==synfig::String::npos || sep2set_contents(book_contents); - }catch(...) { } - } - - resize(x,y); -} - -void -DockDialog::set_composition_selector(bool x) -{ - if(x==get_composition_selector()) - return; - composition_selector_=x; - if(x) - widget_comp_select->show(); - else - widget_comp_select->hide(); -} - -void -DockDialog::refresh_title() -{ - if(is_deleting)return; - if(dock_book_list.size()) - { - synfig::String title; - - std::list::const_iterator iter; - for(iter=dock_book_list.begin();iter!=dock_book_list.end();++iter) - { - if(!title.empty()) - title+=", "; - title+=(*iter)->get_local_contents(); - } - set_title(title); - } - else - set_title(_("Empty Dock Panel")); -} diff --git a/synfig-studio/src/gui/docks/dockdialog.h b/synfig-studio/src/gui/docks/dockdialog.h index 476ac3bd60c..d2980ecb7a0 100644 --- a/synfig-studio/src/gui/docks/dockdialog.h +++ b/synfig-studio/src/gui/docks/dockdialog.h @@ -59,71 +59,24 @@ class DockDialog : public Gtk::Window friend class DockManager; friend class DockBook; friend class Dockable; - sigc::connection empty_sig; - bool composition_selector_; + sigc::connection empty_sig; bool is_deleting; - bool is_horizontal; - private: - std::list dock_book_list; - - std::vector panels_; - std::vector dock_book_sizes_; - - - DockBook* last_dock_book; - - Widget_CompSelect* widget_comp_select; - Gtk::Box *box; - int id_; void on_hide(); - - void refresh(); - - void refresh_title(); - void set_id(int x) { id_=x; } - void refresh_accel_group(); - - void drop_on_append(const Glib::RefPtr& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time); - void drop_on_prepend(const Glib::RefPtr& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time); - - //! Keyboard event dispatcher following window priority - bool on_key_press_event(GdkEventKey* event); - - bool focused_widget_has_priority(Gtk::Widget* focused); - public: - - const std::vector& get_dock_book_sizes()const { return dock_book_sizes_;} - void set_dock_book_sizes(const std::vector&); - void rebuild_sizes(); - bool close(); int get_id()const { return id_; } - DockBook* append_dock_book(); - DockBook* prepend_dock_book(); - void erase_dock_book(DockBook*); - - void set_composition_selector(bool x); - bool get_composition_selector()const { return composition_selector_; } - DockDialog(); ~DockDialog(); - - DockBook& get_dock_book(); - const DockBook& get_dock_book()const; - - synfig::String get_contents()const; - void set_contents(const synfig::String& x); }; // END of studio::DockDialog }; // END of namespace studio diff --git a/synfig-studio/src/gui/docks/dockmanager.cpp b/synfig-studio/src/gui/docks/dockmanager.cpp index b3fe3ea952a..272ffa8f0dd 100644 --- a/synfig-studio/src/gui/docks/dockmanager.cpp +++ b/synfig-studio/src/gui/docks/dockmanager.cpp @@ -33,6 +33,7 @@ #include "docks/dockmanager.h" #include #include "docks/dockable.h" +#include "docks/dockbook.h" #include "docks/dockdialog.h" #include #include @@ -40,6 +41,10 @@ #include "general.h" +#include +#include + + #endif /* === U S I N G =========================================================== */ @@ -53,6 +58,51 @@ using namespace studio; /* === P R O C E D U R E S ================================================= */ +namespace studio { + class DockLinkPoint { + public: + Gtk::Paned *paned; + Gtk::Window *window; + bool is_first; + + DockLinkPoint(): paned(NULL), window(NULL), is_first(false) { } + DockLinkPoint(Gtk::Paned *paned, bool is_first): paned(paned), window(NULL), is_first(is_first) { } + DockLinkPoint(Gtk::Window *window): paned(NULL), window(window), is_first(false) { } + + explicit DockLinkPoint(Gtk::Widget &widget) { + Gtk::Container *container = widget.get_parent(); + paned = dynamic_cast(container); + window = dynamic_cast(container); + is_first = paned != NULL && paned->get_child1() == &widget; + } + + bool is_valid() { return paned || window; } + + void unlink() { + if (paned && is_first && paned->get_child1()) + paned->remove(*paned->get_child1()); + else + if (paned && !is_first && paned->get_child2()) + paned->remove(*paned->get_child2()); + else + if (window) + window->remove(); + } + + void link(Gtk::Widget &widget) + { + if (paned && is_first) + paned->add1(widget); + else + if (paned && !is_first) + paned->add2(widget); + else + if (window) + window->add(widget); + } + }; +} + class studio::DockSettings : public synfigapp::Settings { DockManager* dock_manager; @@ -81,12 +131,13 @@ class studio::DockSettings : public synfigapp::Settings if(key=="contents_size") { - dock_dialog.rebuild_sizes(); - vector::const_iterator iter(dock_dialog.get_dock_book_sizes().begin()); - vector::const_iterator end(dock_dialog.get_dock_book_sizes().end()); - value.clear(); - for(;iter!=end;++iter) - value+=strprintf("%d ",*iter); + // TODO: + //dock_dialog.rebuild_sizes(); + //vector::const_iterator iter(dock_dialog.get_dock_book_sizes().begin()); + //vector::const_iterator end(dock_dialog.get_dock_book_sizes().end()); + //value.clear(); + //for(;iter!=end;++iter) + // value+=strprintf("%d ",*iter); return true; } if(key=="pos") @@ -103,12 +154,14 @@ class studio::DockSettings : public synfigapp::Settings } if(key=="contents") { - value=dock_dialog.get_contents(); + // TODO: + //value=dock_dialog.get_contents(); return true; } if(key=="comp_selector") { - value=dock_dialog.get_composition_selector()?"1":"0"; + // TODO: + //value=dock_dialog.get_composition_selector()?"1":"0"; return true; } }catch (...) { return false; } @@ -148,7 +201,8 @@ class studio::DockSettings : public synfigapp::Settings break; n++; } - dock_dialog.set_dock_book_sizes(data); + // TODO: + //dock_dialog.set_dock_book_sizes(data); } catch(...) { @@ -178,15 +232,17 @@ class studio::DockSettings : public synfigapp::Settings } if(key=="contents") { - dock_dialog.set_contents(value); + // TODO: + //dock_dialog.set_contents(value); return true; } if(key=="comp_selector") { - if(value.empty() || value[0]=='0') - dock_dialog.set_composition_selector(false); - else - dock_dialog.set_composition_selector(true); + // TODO: + //if(value.empty() || value[0]=='0') + // dock_dialog.set_composition_selector(false); + //else + // dock_dialog.set_composition_selector(true); return true; } } @@ -248,7 +304,7 @@ DockManager::unregister_dockable(Dockable& x) { if(&x==*iter) { - x.detach(); + remove_widget_recursive(x); dockable_list_.erase(iter); synfig::info("DockManager::unregister_dockable(): \"%s\" has been Unregistered",x.get_name().c_str()); return true; @@ -311,3 +367,103 @@ DockManager::show_all_dock_dialogs() for(iter=dock_dialog_list_.begin();iter!=dock_dialog_list_.end();++iter) (*iter)->present(); } + +bool +DockManager::swap_widgets(Gtk::Widget &widget1, Gtk::Widget &widget2) +{ + DockLinkPoint point1(widget1); + DockLinkPoint point2(widget2); + if (point1.is_valid() && point2.is_valid()) + { + point1.unlink(); + point2.unlink(); + point1.link(widget2); + point2.link(widget1); + return true; + } + return false; +} + +void +DockManager::remove_widget_recursive(Gtk::Widget &widget) +{ + DockLinkPoint link(widget); + if (link.is_valid()) + { + link.unlink(); + if (link.paned) + { + Gtk::Widget &widget = link.is_first + ? *link.paned->get_child2() + : *link.paned->get_child1(); + DockLinkPoint paned_link(*link.paned); + if (paned_link.is_valid()) + { + link.paned->remove(widget); + paned_link.unlink(); + paned_link.link(widget); + delete link.paned; + } + } + else + if (link.window) link.window->hide(); + } + else + if (widget.get_parent()) + { + DockBook *book = dynamic_cast(widget.get_parent()); + widget.get_parent()->remove(widget); + if (book && book->pages().empty()) + { + remove_widget_recursive(*book); + delete book; + } + } + + Dockable *dockable = dynamic_cast(&widget); + if (dockable) dockable->parent_ = NULL; +} + + +bool +DockManager::add_widget(Gtk::Widget &dest_widget, Gtk::Widget &src_widget, bool vertical, bool first) +{ + if (&src_widget == &dest_widget) return false; + + // check for src widget is parent for dest_widget + for(Gtk::Widget *parent = src_widget.get_parent(); parent != NULL; parent = parent->get_parent()) + if (parent == &dest_widget) + return swap_widgets(src_widget, dest_widget); + + // unlink dest_widget + DockLinkPoint dest_link(dest_widget); + if (!dest_link.is_valid()) return false; + dest_link.unlink(); + + // unlink src_widget + remove_widget_recursive(src_widget); + + // create new paned and link all + Gtk::Paned *paned = manage(vertical ? (Gtk::Paned*)new Gtk::VPaned() : (Gtk::Paned*)new Gtk::HPaned()); + paned->show(); + DockLinkPoint(paned, first).link(src_widget); + DockLinkPoint(paned, !first).link(dest_widget); + dest_link.link(*paned); + return true; +} + +bool +DockManager::add_dockable(Gtk::Widget &dest_widget, Dockable &dockable, bool vertical, bool first) +{ + DockBook *book = manage(new DockBook()); + book->show(); + if (add_widget(dest_widget, *book, vertical, first)) + { + book->add(dockable); + return true; + } + delete book; + return false; +} + + diff --git a/synfig-studio/src/gui/docks/dockmanager.h b/synfig-studio/src/gui/docks/dockmanager.h index e92e06c51d6..25c58e62085 100644 --- a/synfig-studio/src/gui/docks/dockmanager.h +++ b/synfig-studio/src/gui/docks/dockmanager.h @@ -34,6 +34,8 @@ #include #include +#include + /* === M A C R O S ========================================================= */ /* === T Y P E D E F S ===================================================== */ @@ -74,6 +76,11 @@ class DockManager : public sigc::trackable void present(synfig::String x); void show_all_dock_dialogs(); + static bool swap_widgets(Gtk::Widget &widget1, Gtk::Widget &widget2); + static void remove_widget_recursive(Gtk::Widget &widget); + static void remove_widget_by_pointer_recursive(Gtk::Widget *widget) { remove_widget_recursive(*widget); } + static bool add_widget(Gtk::Widget &dest_widget, Gtk::Widget &src_widget, bool vertical, bool first); + static bool add_dockable(Gtk::Widget &dest_widget, Dockable &dockable, bool vertical, bool first); }; // END of class DockManager }; // END of namespace studio diff --git a/synfig-studio/src/gui/toolbox.cpp b/synfig-studio/src/gui/toolbox.cpp index 104e3b9e4c9..02cccbef1e9 100644 --- a/synfig-studio/src/gui/toolbox.cpp +++ b/synfig-studio/src/gui/toolbox.cpp @@ -185,16 +185,18 @@ show_dialog_input() void _create_stock_dialog1() { - DockDialog* dock_dialog(new DockDialog); - dock_dialog->set_contents("canvases history"); - dock_dialog->set_composition_selector(true); - dock_dialog->present(); + // TODO: + //DockDialog* dock_dialog(new DockDialog); + //dock_dialog->set_contents("canvases history"); + //dock_dialog->set_composition_selector(true); + //dock_dialog->present(); } void _create_stock_dialog2() { - DockDialog* dock_dialog(new DockDialog); - dock_dialog->set_contents("layers children keyframes | params"); - dock_dialog->present(); + // TODO: + //DockDialog* dock_dialog(new DockDialog); + //dock_dialog->set_contents("layers children keyframes | params"); + //dock_dialog->present(); } Toolbox::Toolbox():