Blame synfig-studio/src/gui/docks/dock_toolbox.cpp

Carlos Lopez a09598
/* === S Y N F I G ========================================================= */
839371
/*!	\file dock_toolbox.cpp
Carlos Lopez a09598
**	\brief writeme
Carlos Lopez a09598
**
Carlos Lopez a09598
**	$Id$
Carlos Lopez a09598
**
Carlos Lopez a09598
**	\legal
Carlos Lopez a09598
**	Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
Carlos Lopez a09598
**	Copyright (c) 2007, 2008 Chris Moore
Carlos Lopez a09598
**  Copyright (c) 2008 Paul Wise
Carlos Lopez 233516
**	Copyright (c) 2009 Nikita Kitaev
Carlos Lopez a09598
**
Carlos Lopez a09598
**	This package is free software; you can redistribute it and/or
Carlos Lopez a09598
**	modify it under the terms of the GNU General Public License as
Carlos Lopez a09598
**	published by the Free Software Foundation; either version 2 of
Carlos Lopez a09598
**	the License, or (at your option) any later version.
Carlos Lopez a09598
**
Carlos Lopez a09598
**	This package is distributed in the hope that it will be useful,
Carlos Lopez a09598
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
Carlos Lopez a09598
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Carlos Lopez a09598
**	General Public License for more details.
Carlos Lopez a09598
**	\endlegal
Carlos Lopez a09598
**
Carlos Lopez a09598
** === N O T E S ===========================================================
Carlos Lopez a09598
**
Carlos Lopez a09598
** ========================================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
/* === H E A D E R S ======================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
#ifdef USING_PCH
Carlos Lopez a09598
#	include "pch.h"
Carlos Lopez a09598
#else
Carlos Lopez a09598
#ifdef HAVE_CONFIG_H
Carlos Lopez a09598
#	include <config.h></config.h>
Carlos Lopez a09598
#endif
Carlos Lopez a09598
bw 94d8a6
#include <synfig general.h=""></synfig>
bw 94d8a6
bw 94d8a6
#include <sstream></sstream>
Carlos Lopez a09598
bw 94d8a6
#include <gtk gtk.h=""></gtk>
bw 94d8a6
#include <gtkmm accelmap.h=""></gtkmm>
bw 94d8a6
abdbf2
#include "localization.h"
bw 94d8a6
bw 94d8a6
#include "dock_toolbox.h"
Carlos Lopez a09598
Carlos Lopez a09598
#include "instance.h"
Carlos Lopez a09598
#include "app.h"
Carlos Lopez a09598
#include "canvasview.h"
Nikita Kitaev 76ba27
#include "dialogs/dialog_gradient.h"
Nikita Kitaev 76ba27
#include "dialogs/dialog_color.h"
Nikita Kitaev 5fe12e
#include "docks/dialog_tooloptions.h"
Nikita Kitaev 5fe12e
#include "docks/dockable.h"
Nikita Kitaev 5fe12e
#include "docks/dockmanager.h"
Nikita Kitaev 5fe12e
#include "docks/dockdialog.h"
Nikita Kitaev 3c2324
#include "widgets/widget_defaults.h"
bw 94d8a6
Carlos Lopez a09598
#include <synfigapp main.h=""></synfigapp>
Carlos Lopez a09598
Carlos Lopez a09598
#endif
Carlos Lopez a09598
Carlos Lopez a09598
using namespace std;
Carlos Lopez a09598
using namespace etl;
Carlos Lopez a09598
using namespace synfig;
Carlos Lopez a09598
using namespace studio;
Carlos Lopez a09598
using namespace sigc;
Carlos Lopez a09598
Carlos Lopez a09598
/* === M A C R O S ========================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
/* === G L O B A L S ======================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
/* === P R O C E D U R E S ================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
/* === M E T H O D S ======================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
839371
Dock_Toolbox::Dock_Toolbox():
ee2f22
	Dockable("toolbox",_("Toolbox"),Gtk::StockID("synfig-about"))
Carlos Lopez a09598
{
650be2
	set_use_scrolled(false);
650be2
	set_size_request(-1,-1);
650be2
ca7825
	tool_item_group = manage(new class Gtk::ToolItemGroup());
ca7825
	gtk_tool_item_group_set_label(tool_item_group->gobj(), NULL);
ca7825
ca7825
	Gtk::ToolPalette *palette = manage(new Gtk::ToolPalette());
ca7825
	palette->add(*tool_item_group);
ca7825
	palette->set_expand(*tool_item_group);
ca7825
	palette->set_exclusive(*tool_item_group, true);
ca7825
	palette->set_icon_size(Gtk::IconSize::from_name("synfig-small_icon_16x16"));
[d.j.a.y] Jerome Blanchi 4613b9
	// let the palette propagate the scroll events
[d.j.a.y] Jerome Blanchi 4613b9
	palette->add_events(Gdk::SCROLL_MASK);
ca7825
	palette->show();
ca7825
ca7825
	Gtk::ScrolledWindow *scrolled_window = manage(new Gtk::ScrolledWindow());
ca7825
	scrolled_window->add(*palette);
e35148
	scrolled_window->set_border_width(2);
ca7825
	scrolled_window->show();
ca7825
Carlos Lopez 3794aa
	Widget_Defaults* widget_defaults(manage(new Widget_Defaults()));
Carlos Lopez a09598
Rodolfo Ribeiro Gomes 9277d9
	tool_box_paned = manage(new Gtk::Paned(Gtk::ORIENTATION_VERTICAL));
def4c6
	tool_box_paned->pack1(*scrolled_window, Gtk::PACK_EXPAND_WIDGET|Gtk::PACK_SHRINK, 3);
def4c6
	tool_box_paned->pack2(*widget_defaults, Gtk::PACK_EXPAND_WIDGET|Gtk::PACK_SHRINK, 3);
def4c6
	tool_box_paned->set_position(200);
def4c6
	tool_box_paned->show_all();
def4c6
	add(*tool_box_paned);
Carlos Lopez a09598
fda829
	App::signal_canvas_view_focus().connect(
Carlos Lopez a09598
		sigc::hide(
fda829
			sigc::mem_fun(*this,&studio::Dock_Toolbox::update_tools) ));
Carlos Lopez a09598
f586de
	std::vector<gtk::targetentry> listTargets;</gtk::targetentry>
Carlos Lopez a09598
	listTargets.push_back( Gtk::TargetEntry("text/plain") );
Carlos Lopez a09598
	listTargets.push_back( Gtk::TargetEntry("image") );
Carlos Lopez a09598
//	listTargets.push_back( Gtk::TargetEntry("image/x-sif") );
Carlos Lopez a09598
Carlos Lopez a09598
	drag_dest_set(listTargets);
839371
	signal_drag_data_received().connect( sigc::mem_fun(*this, &studio::Dock_Toolbox::on_drop_drag_data_received) );
Carlos Lopez a09598
Carlos Lopez a09598
	changing_state_=false;
Carlos Lopez a09598
839371
	App::signal_present_all().connect(sigc::mem_fun0(*this,&Dock_Toolbox::present));
Carlos Lopez a09598
}
Carlos Lopez a09598
839371
Dock_Toolbox::~Dock_Toolbox()
Carlos Lopez a09598
{
Carlos Lopez a09598
	hide();
Carlos Lopez a09598
	//studio::App::cb.task(_("Toolbox: I was nailed!"));
Carlos Lopez a09598
	//studio::App::quit();
Carlos Lopez a09598
839371
	if(studio::App::dock_toolbox==this)
839371
		studio::App::dock_toolbox=NULL;
Carlos Lopez a09598
}
Carlos Lopez a09598
Rodolfo Ribeiro Gomes 9277d9
void Dock_Toolbox::write_layout_string(string& params) const
Rodolfo Ribeiro Gomes 9277d9
{
Rodolfo Ribeiro Gomes 9277d9
	char num_str[6];
Rodolfo Ribeiro Gomes 9277d9
	snprintf(num_str, 5, "%d", tool_box_paned->get_position());
Rodolfo Ribeiro Gomes 9277d9
	params += std::string(num_str);
Rodolfo Ribeiro Gomes 9277d9
}
Rodolfo Ribeiro Gomes 9277d9
Rodolfo Ribeiro Gomes 9277d9
void Dock_Toolbox::read_layout_string(const string& params) const
Rodolfo Ribeiro Gomes 9277d9
{
Rodolfo Ribeiro Gomes 9277d9
	try {
Rodolfo Ribeiro Gomes 9277d9
		int pos = std::stoi(params.c_str());
Rodolfo Ribeiro Gomes 9277d9
		tool_box_paned->set_position(pos);
Rodolfo Ribeiro Gomes 9277d9
	} catch (...) {
Rodolfo Ribeiro Gomes 9277d9
		// ignores invalid value and let it use the default one
Rodolfo Ribeiro Gomes 9277d9
	}
Rodolfo Ribeiro Gomes 9277d9
}
Rodolfo Ribeiro Gomes 9277d9
Carlos Lopez a09598
void
839371
Dock_Toolbox::set_active_state(const synfig::String& statename)
Carlos Lopez a09598
{
ca7825
	std::map<synfig::string,gtk::toggletoolbutton *="">::iterator iter;</synfig::string,gtk::toggletoolbutton>
Carlos Lopez a09598
Carlos Lopez a09598
	changing_state_=true;
Carlos Lopez a09598
Carlos Lopez a09598
	synfigapp::Main::set_state(statename);
Carlos Lopez a09598
Carlos Lopez a09598
	try
Carlos Lopez a09598
	{
Carlos Lopez a09598
Carlos Lopez a09598
		for(iter=state_button_map.begin();iter!=state_button_map.end();++iter)
Carlos Lopez a09598
		{
Carlos Lopez a09598
			if(iter->first==statename)
Carlos Lopez a09598
			{
Carlos Lopez a09598
				if(!iter->second->get_active())
Carlos Lopez a09598
					iter->second->set_active(true);
Carlos Lopez a09598
			}
Carlos Lopez a09598
			else
Carlos Lopez a09598
			{
Carlos Lopez a09598
				if(iter->second->get_active())
Carlos Lopez a09598
					iter->second->set_active(false);
Carlos Lopez a09598
			}
Carlos Lopez a09598
		}
Carlos Lopez a09598
	}
Carlos Lopez a09598
	catch(...)
Carlos Lopez a09598
	{
Carlos Lopez a09598
		changing_state_=false;
Carlos Lopez a09598
		throw;
Carlos Lopez a09598
	}
Carlos Lopez a09598
	changing_state_=false;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void
795a47
Dock_Toolbox::change_state(const synfig::String& statename, bool force)
Carlos Lopez a09598
{
Carlos Lopez a09598
	etl::handle<studio::canvasview> canvas_view(studio::App::get_selected_canvas_view());</studio::canvasview>
Carlos Lopez a09598
	if(canvas_view)
Carlos Lopez a09598
	{
795a47
		if(!force && statename==canvas_view->get_smach().get_state_name())
Carlos Lopez a09598
		{
Carlos Lopez a09598
			return;
Carlos Lopez a09598
		}
Carlos Lopez a09598
Carlos Lopez a09598
		if(state_button_map.count(statename))
Carlos Lopez a09598
		{
ca7825
			state_button_map[statename]->activate();
Carlos Lopez a09598
		}
Carlos Lopez a09598
		else
Carlos Lopez a09598
		{
Carlos Lopez a09598
			synfig::error("Unknown state \"%s\"",statename.c_str());
Carlos Lopez a09598
		}
Carlos Lopez a09598
	}
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void
839371
Dock_Toolbox::change_state_(const Smach::state_base *state)
Carlos Lopez a09598
{
Carlos Lopez a09598
	if(changing_state_)
Carlos Lopez a09598
		return;
Carlos Lopez a09598
	changing_state_=true;
Carlos Lopez a09598
Carlos Lopez a09598
	try
Carlos Lopez a09598
	{
Carlos Lopez a09598
		etl::handle<studio::canvasview> canvas_view(studio::App::get_selected_canvas_view());</studio::canvasview>
Carlos Lopez a09598
		if(canvas_view)
Carlos Lopez a09598
				canvas_view->get_smach().enter(state);
Carlos Lopez a09598
		else
Carlos Lopez a09598
			refresh();
Carlos Lopez a09598
	}
Carlos Lopez a09598
	catch(...)
Carlos Lopez a09598
	{
Carlos Lopez a09598
		changing_state_=false;
Carlos Lopez a09598
		throw;
Carlos Lopez a09598
	}
Carlos Lopez a09598
Carlos Lopez a09598
	changing_state_=false;
Carlos Lopez a09598
}
Carlos Lopez a09598
[d.j.a.y] Jerome Blanchi f9d38c
839371
/*! \fn Dock_Toolbox::add_state(const Smach::state_base *state)
luz.paz 99f3ef
 *  \brief Add and connect a toggle button to the toolbox defined by a state
[d.j.a.y] Jerome Blanchi f9d38c
 *  \param state a const pointer to Smach::state_base
[d.j.a.y] Jerome Blanchi f9d38c
*/
Carlos Lopez a09598
void
839371
Dock_Toolbox::add_state(const Smach::state_base *state)
Carlos Lopez a09598
{
Carlos Lopez a09598
	assert(state);
Carlos Lopez a09598
Carlos Lopez a09598
	String name=state->get_name();
Carlos Lopez a09598
Carlos Lopez a09598
	Gtk::StockItem stock_item;
Carlos Lopez a09598
	Gtk::Stock::lookup(Gtk::StockID("synfig-"+name),stock_item);
Carlos Lopez a09598
ca7825
	Gtk::ToggleToolButton *tool_button = manage(new class Gtk::ToggleToolButton(
ca7825
		*manage(new Gtk::Image(
ca7825
			stock_item.get_stock_id(),
ca7825
			Gtk::IconSize::from_name("synfig-small_icon_16x16") )),
ca7825
		stock_item.get_label() ));
Carlos Lopez a09598
[d.j.a.y] Jerome Blanchi e2b28e
	Gtk::AccelKey key;
luz.paz 99f3ef
	//Have a look to global function init_ui_manager() from app.cpp for "accel_path" definition
[d.j.a.y] Jerome Blanchi e2b28e
	Gtk::AccelMap::lookup_entry ("<actions>/action_group_state_manager/state-"+name, key);</actions>
[d.j.a.y] Jerome Blanchi a7d9b7
	//Gets the, is exist, accelerator representation for labels
[d.j.a.y] Jerome Blanchi a7d9b7
	Glib::ustring accel_path = !key.is_null() ? key.get_abbrev () :"";
2d5cba
	
ca7825
	tool_button->set_tooltip_text(stock_item.get_label()+" "+accel_path);
ca7825
	tool_button->show();
Carlos Lopez a09598
ca7825
	tool_item_group->insert(*tool_button);
ca7825
	tool_item_group->show_all();
Carlos Lopez a09598
ca7825
	state_button_map[name] = tool_button;
Carlos Lopez a09598
ca7825
	tool_button->signal_clicked().connect(
Carlos Lopez a09598
		sigc::bind(
839371
			sigc::mem_fun(*this,&studio::Dock_Toolbox::change_state_),
Carlos Lopez a09598
			state
Carlos Lopez a09598
		)
Carlos Lopez a09598
	);
Carlos Lopez a09598
Carlos Lopez a09598
	refresh();
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
Carlos Lopez a09598
void
Yu Chen 5b5fd5
Dock_Toolbox::update_tools()
Carlos Lopez a09598
{
fda829
	etl::handle<instance> instance = App::get_selected_instance();</instance>
fda829
	etl::handle<canvasview> canvas_view = App::get_selected_canvas_view();</canvasview>
Carlos Lopez a09598
Carlos Lopez a09598
	// These next several lines just adjust the tool buttons
Carlos Lopez a09598
	// so that they are only clickable when they should be.
fda829
	bool sensitive = instance && canvas_view;
fda829
	std::map<synfig::string,gtk::toggletoolbutton *="">::iterator iter;</synfig::string,gtk::toggletoolbutton>
fda829
	for(iter=state_button_map.begin();iter!=state_button_map.end();++iter)
fda829
		iter->second->set_sensitive(sensitive);
Carlos Lopez a09598
fda829
	if (canvas_view && canvas_view->get_smach().get_state_name())
Carlos Lopez a09598
		set_active_state(canvas_view->get_smach().get_state_name());
Carlos Lopez a09598
	else
Carlos Lopez a09598
		set_active_state("none");
Carlos Lopez a09598
}
Carlos Lopez a09598
478b0d
478b0d
void
478b0d
Dock_Toolbox::refresh()
478b0d
{
478b0d
	update_tools();
478b0d
}
478b0d
478b0d
Carlos Lopez a09598
void
839371
Dock_Toolbox::on_drop_drag_data_received(const Glib::RefPtr<gdk::dragcontext>& context, int /*x*/, int /*y*/, const Gtk::SelectionData& selection_data_, guint /*info*/, guint time)</gdk::dragcontext>
Carlos Lopez a09598
{
Carlos Lopez a09598
	// We will make this true once we have a solid drop
Carlos Lopez a09598
	bool success(false);
Carlos Lopez a09598
Carlos Lopez a09598
	if ((selection_data_.get_length() >= 0) && (selection_data_.get_format() == 8))
Carlos Lopez a09598
	{
Carlos Lopez a09598
		synfig::String selection_data((gchar *)(selection_data_.get_data()));
Carlos Lopez a09598
Carlos Lopez a09598
		// For some reason, GTK hands us a list of URLs separated
Carlos Lopez a09598
		// by not only Carriage-Returns, but also Line-Feeds.
Carlos Lopez a09598
		// Line-Feeds will mess us up. Remove all the line-feeds.
Carlos Lopez a09598
		while(selection_data.find_first_of('\r')!=synfig::String::npos)
Carlos Lopez a09598
			selection_data.erase(selection_data.begin()+selection_data.find_first_of('\r'));
Carlos Lopez a09598
Carlos Lopez a09598
		std::stringstream stream(selection_data);
Carlos Lopez a09598
Carlos Lopez a09598
		while(stream)
Carlos Lopez a09598
		{
Carlos Lopez a09598
			synfig::String filename,URI;
Carlos Lopez a09598
			getline(stream,filename);
Carlos Lopez a09598
Carlos Lopez a09598
			// If we don't have a filename, move on.
Carlos Lopez a09598
			if(filename.empty())
Carlos Lopez a09598
				continue;
Carlos Lopez a09598
Carlos Lopez a09598
			// Make sure this URL is of the "file://" type.
Carlos Lopez a09598
			URI=String(filename.begin(),filename.begin()+sizeof("file://")-1);
Carlos Lopez a09598
			if(URI!="file://")
Carlos Lopez a09598
			{
Carlos Lopez a09598
				synfig::warning("Unknown URI (%s) in \"%s\"",URI.c_str(),filename.c_str());
Carlos Lopez a09598
				continue;
Carlos Lopez a09598
			}
Carlos Lopez a09598
Carlos Lopez a09598
			// Strip the "file://" part from the filename
Carlos Lopez a09598
			filename=synfig::String(filename.begin()+sizeof("file://")-1,filename.end());
Carlos Lopez a09598
Carlos Lopez a09598
			synfig::info("Attempting to open "+filename);
Carlos Lopez a09598
			if(App::open(filename))
Carlos Lopez a09598
				success=true;
Carlos Lopez a09598
			else
Carlos Lopez a09598
				synfig::error("Drop failed: Unable to open "+filename);
Carlos Lopez a09598
		}
Carlos Lopez a09598
	}
Carlos Lopez a09598
	else
Carlos Lopez a09598
		synfig::error("Drop failed: bad selection data");
Carlos Lopez a09598
Carlos Lopez a09598
	// Finish the drag
Carlos Lopez a09598
	context->drag_finish(success, false, time);
Carlos Lopez a09598
}