X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-studio%2Ftags%2Fsynfigstudio_0_61_07%2Fsrc%2Fgtkmm%2Fdockdialog.cpp;fp=synfig-studio%2Ftags%2Fsynfigstudio_0_61_07%2Fsrc%2Fgtkmm%2Fdockdialog.cpp;h=1a9a6e47a9a17ea935bafcbfb88eb2fc3d290622;hb=1883964bcc348e89ed527bea27ce15b1ed87c6ed;hp=0000000000000000000000000000000000000000;hpb=746b97804526d553f8a7767409e01ee6d5137c76;p=synfig.git diff --git a/synfig-studio/tags/synfigstudio_0_61_07/src/gtkmm/dockdialog.cpp b/synfig-studio/tags/synfigstudio_0_61_07/src/gtkmm/dockdialog.cpp new file mode 100644 index 0000000..1a9a6e4 --- /dev/null +++ b/synfig-studio/tags/synfigstudio_0_61_07/src/gtkmm/dockdialog.cpp @@ -0,0 +1,560 @@ +/* === S Y N F I G ========================================================= */ +/*! \file dockdialog.cpp +** \brief Template File +** +** $Id$ +** +** \legal +** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** Copyright (c) 2007 Chris Moore +** +** This package is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License as +** published by the Free Software Foundation; either version 2 of +** the License, or (at your option) any later version. +** +** This package is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** \endlegal +*/ +/* ========================================================================= */ + +/* === H E A D E R S ======================================================= */ + +#ifdef USING_PCH +# include "pch.h" +#else +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "app.h" +#include + +#include "dockdialog.h" +#include "dockbook.h" +#include "dockmanager.h" +#include "toolbox.h" +#include "widget_compselect.h" +#include +#include +#include +#include +#include +#include +#include +#include "canvasview.h" +#include +#include +#include + +#endif + +/* === U S I N G =========================================================== */ + +using namespace std; +using namespace etl; +using namespace synfig; +using namespace studio; + +/* === M A C R O S ========================================================= */ + +#define GRAB_HINT_DATA(y,default) { \ + String x; \ + if(synfigapp::Main::settings().get_value(String("pref.")+y+"_hints",x)) \ + { \ + set_type_hint((Gdk::WindowTypeHint)atoi(x.c_str())); \ + } else {\ + set_type_hint(default); \ + } \ + } + +/* === G L O B A L S ======================================================= */ + +/* === P R O C E D U R E S ================================================= */ + +/* === M E T H O D S ======================================================= */ + +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)); + + set_role(strprintf("dock_dialog_%d",get_id())); + GRAB_HINT_DATA( + "dock_dialog", +#ifdef __APPLE__ + Gdk::WINDOW_TYPE_HINT_NORMAL +#else + Gdk::WINDOW_TYPE_HINT_UTILITY +#endif + ); + set_keep_above(false); + + //! \todo can we set dialog windows transient for all normal windows, not just the toolbox? + //! paragraph 3 of http://standards.freedesktop.org/wm-spec/1.3/ar01s07.html suggests we can + // this seems to have bad effects on KDE, so leave it disabled by default + if(getenv("SYNFIG_TRANSIENT_DIALOGS")) + set_transient_for(*App::toolbox); + + // Set up the window + //set_type_hint(Gdk::WINDOW_TYPE_HINT_UTILITY); + set_title("Dock Dialog"); + + // Register with the dock manager + App::dock_manager->dock_dialog_list_.push_back(this); + + + // connect our signals + signal_delete_event().connect( + sigc::hide( + sigc::mem_fun(*this,&DockDialog::close) + ) + ); + +/* + 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)); + +} + +DockDialog::~DockDialog() +{ + empty_sig.disconnect(); + + is_deleting=true; + + // Remove all of the dock books + for(;!dock_book_list.empty();dock_book_list.pop_front()) + { + dock_book_list.front()->clear(); + + //! \fixme: 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 + // theoreticly 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; + for(iter=App::dock_manager->dock_dialog_list_.begin();iter!=App::dock_manager->dock_dialog_list_.end();++iter) + if(*iter==this) + { + App::dock_manager->dock_dialog_list_.erase(iter); + break; + } + } + catch(...) + { + 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() +{ + Gtk::Window::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; +} + +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(); + pannels_.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)); + + pannels_.push_back(parent); + + if(pannels_.size()<=dock_book_sizes_.size()) + pannels_.back()->set_position(dock_book_sizes_[pannels_.size()-1]); + pannels_.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)); + pannels_.push_back(current); + + if(pannels_.size()<=dock_book_sizes_.size()) + pannels_.back()->set_position(dock_book_sizes_[pannels_.size()-1]); + pannels_.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() +{ + synfig::info("DockDialog::close(): DELETED!"); + empty_sig.disconnect(); + //get_dock_book().clear(); + 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 Dialog")); +}