/* === S Y N F I G ========================================================= */ /*! \file dockable.cpp ** \brief Template File ** ** $Id$ ** ** \legal ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley ** ** 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 "docks/dockable.h" #include "docks/dockmanager.h" #include "docks/dockbook.h" #include "docks/dockdialog.h" #include #include #include #include "general.h" #endif /* === U S I N G =========================================================== */ using namespace std; using namespace etl; using namespace synfig; using namespace studio; /* === M A C R O S ========================================================= */ #ifdef WIN32 # ifdef IMAGE_DIR # undef IMAGE_DIR # define IMAGE_DIR "share\\pixmaps" # endif #endif #ifndef IMAGE_DIR # define IMAGE_DIR "/usr/local/share/pixmaps" #endif #ifndef IMAGE_EXT # define IMAGE_EXT "png" #endif /* === G L O B A L S ======================================================= */ /* === P R O C E D U R E S ================================================= */ /* === M E T H O D S ======================================================= */ Dockable::Dockable(const synfig::String& name,const synfig::String& local_name,Gtk::StockID stock_id_): // Gtk::Window(Gtk::WINDOW_TOPLEVEL), name_(name), local_name_(local_name), // dialog_settings(this,name), title_label_(local_name,Gtk::ALIGN_START), stock_id_(stock_id_) { scrolled_=0; use_scrolled_=true; attach_dnd_to(title_label_); toolbar_=0; //button_box_.show(); Gtk::Table* table(this); { title_label_.set_padding(0,0); //title_label_.show(); Gtk::EventBox* event_box(manage(new Gtk::EventBox())); event_box->set_border_width(0); event_box->add(title_label_); //table->attach(*event_box, 0, 1, 0,1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); header_box_.pack_start(*event_box); attach_dnd_to(*event_box); event_box->show(); // event_box->set_events(Gdk::ALL_EVENTS_MASK); //!< \todo change this to only allow what is necessary for DnD Gtk::Button* bttn_close(manage(new Gtk::Button(_("X")))); //table->attach(*bttn_close, 1, 2, 0,1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); header_box_.pack_end(*bttn_close,false,false); bttn_close->show(); bttn_close->set_relief(Gtk::RELIEF_NONE); 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); } prev_widget_=manage(new Gtk::Label(" ")); //table->attach(header_box_, 0, 1, 0,1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); table->attach(*prev_widget_, 0, 1, 1,2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); //table->attach(*toolbar_, 0, 1, 2,3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); set_toolbar(*manage(new Gtk::Toolbar)); table->show(); prev_widget_->show(); set_size_request(175,120); } Dockable::~Dockable() { if(scrolled_) { delete scrolled_; scrolled_=0; } } void Dockable::attach_dnd_to(Gtk::Widget& widget) { std::vector listTargets; listTargets.push_back( Gtk::TargetEntry("SYNFIG_DOCK") ); Gtk::StockItem item; widget.drag_source_set(listTargets); if(Gtk::Stock::lookup(get_stock_id(),item)) widget.drag_source_set_icon(get_stock_id()); widget.drag_dest_set(listTargets); widget.signal_drag_data_get().connect(sigc::mem_fun(*this,&Dockable::on_drag_data_get)); widget.signal_drag_end().connect(sigc::mem_fun(*this,&Dockable::on_drag_end)); widget.signal_drag_begin().connect(sigc::mem_fun(*this,&Dockable::on_drag_begin)); widget.signal_drag_data_received().connect(sigc::mem_fun(*this,&Dockable::on_drag_data_received)); } void Dockable::on_drag_data_received(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 && selection_data.get_data_type() == "SYNFIG_DOCK") { Dockable& dockable(**reinterpret_cast(const_cast(selection_data.get_data()))); DockBook *parent = dynamic_cast(get_parent()); DockBook *dockable_parent = dynamic_cast(dockable.get_parent()); if (parent) { if (dockable_parent != parent) parent->add(dockable,parent->page_num(*this)); else parent->reorder_child(dockable,parent->page_num(*this)); dockable.present(); context->drag_finish(true, false, time); App::dock_manager->update_window_titles(); return; } } context->drag_finish(false, false, time); } void Dockable::on_drag_end(const Glib::RefPtr&/*context*/) { if(!dnd_success_) { DockManager::remove_widget_recursive(*this); present(); } } void Dockable::on_drag_begin(const Glib::RefPtr&/*context*/) { dnd_success_=false; } void Dockable::on_drag_data_get(const Glib::RefPtr&, Gtk::SelectionData& selection_data, guint /*info*/, guint /*time*/) { Dockable* tmp(this); dnd_success_=true; selection_data.set(8, reinterpret_cast(&tmp), sizeof(Dockable**)); } void Dockable::set_local_name(const synfig::String& local_name) { //set_title(local_name); local_name_ = local_name; title_label_.set_text(local_name); signal_stock_id_changed()(); } void Dockable::clear() { //if(!toolbar_->children().empty()) // toolbar_->children().clear(); set_toolbar(*manage(new Gtk::Toolbar)); } void Dockable::set_toolbar(Gtk::Toolbar& toolbar) { if(toolbar_)remove(*toolbar_); toolbar_=0; toolbar_=&toolbar; if(toolbar_) { attach(*toolbar_, 0, 1, 2,3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); gtk_toolbar_set_icon_size(toolbar_->gobj(),GtkIconSize(1)/*GTK_ICON_SIZE_MENU*/); toolbar_->set_property("toolbar-style", Gtk::TOOLBAR_ICONS); toolbar_->show(); } } bool Dockable::clear_previous() { prev_widget_=0; prev_widget_delete_connection.disconnect(); return false; } void Dockable::add(Gtk::Widget& x) { if(prev_widget_) { remove(*prev_widget_); clear_previous(); } if(scrolled_) { delete scrolled_; scrolled_=0; } if(use_scrolled_) { scrolled_=new Gtk::ScrolledWindow; scrolled_->add(x); attach(*scrolled_, 0, 1, 1,2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); x.show(); scrolled_->show(); scrolled_->set_shadow_type(Gtk::SHADOW_NONE); scrolled_->set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC); prev_widget_=scrolled_; } else { attach(x, 0, 1, 1,2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); x.show(); prev_widget_=&x; } prev_widget_delete_connection=prev_widget_->signal_delete_event().connect( sigc::hide( sigc::mem_fun( *this, &Dockable::clear_previous ) ) ); } Gtk::ToolButton* Dockable::add_button(const Gtk::StockID& stock_id, const synfig::String& tooltip) { if(!toolbar_) set_toolbar(*manage(new Gtk::Toolbar)); Gtk::ToolButton* ret(manage(new Gtk::ToolButton(stock_id))); ret->set_tooltip_text(tooltip); ret->show(); toolbar_->set_has_tooltip(); toolbar_->append(*ret); return ret; } void Dockable::present() { DockBook *parent = dynamic_cast(get_parent()); if(parent) { parent->set_current_page(parent->page_num(*this)); parent->present(); } else { show(); DockBook* book = manage(new DockBook()); book->show(); book->add(*this); DockDialog* dock_dialog(new DockDialog()); dock_dialog->add(*book); /* //hack: always display composition selector on top of canvas browser if(get_name()=="canvases") dock_dialog->set_composition_selector(true); */ dock_dialog->present(); } App::dock_manager->update_window_titles(); } Gtk::Widget* Dockable::create_tab_label() { Gtk::EventBox* event_box(manage(new Gtk::EventBox())); attach_dnd_to(*event_box); { Gtk::StockID stock_id(get_stock_id()); Gtk::StockItem item; // Check to make sure the icon is valid if(Gtk::Stock::lookup(stock_id,item)) { Gtk::IconSize iconsize = Gtk::IconSize::from_name("synfig-small_icon_16x16"); Gtk::Image* icon(manage(new Gtk::Image(stock_id,iconsize))); event_box->add(*icon); event_box->set_tooltip_text(get_local_name()); icon->show(); } else { // Bad icon, try to make a label Glib::ustring text(get_local_name()); Gtk::Label* label(manage(new Gtk::Label(text))); event_box->add(*label); label->show(); } } return event_box; }