X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-studio%2Fsrc%2Fgtkmm%2Fcellrenderer_value.cpp;fp=synfig-studio%2Fsrc%2Fgtkmm%2Fcellrenderer_value.cpp;h=456dee77180fcd9fd8fcd9ddbd1ace7180299175;hb=a095981e18cc37a8ecc7cd237cc22b9c10329264;hp=0000000000000000000000000000000000000000;hpb=9459638ad6797b8139f1e9f0715c96076dbf0890;p=synfig.git diff --git a/synfig-studio/src/gtkmm/cellrenderer_value.cpp b/synfig-studio/src/gtkmm/cellrenderer_value.cpp new file mode 100644 index 0000000..456dee7 --- /dev/null +++ b/synfig-studio/src/gtkmm/cellrenderer_value.cpp @@ -0,0 +1,604 @@ +/* === S Y N F I G ========================================================= */ +/*! \file cellrenderer_value.cpp +** \brief Template File +** +** $Id$ +** +** \legal +** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** Copyright (c) 2007, 2008 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 +#include +#include +#include +#include +#include +#include /* see XXX below */ + +#include "app.h" +#include "widget_value.h" +#include "widget_vector.h" +#include "widget_filename.h" +#include "widget_enum.h" +#include "widget_color.h" +#include "widget_canvaschooser.h" +#include "widget_time.h" + +#include "cellrenderer_gradient.h" +#include "cellrenderer_value.h" + +#include "widget_gradient.h" +#include "dialog_gradient.h" +#include "dialog_color.h" +#include + +#include "general.h" + +#endif + +using namespace synfig; +using namespace etl; +using namespace std; +using namespace studio; + +/* === M A C R O S ========================================================= */ + +#define DIGITS 15 + +/* === G L O B A L S ======================================================= */ + +class studio::ValueBase_Entry : public Gtk::EventBox, public Gtk::CellEditable +{ + Glib::ustring path; + Widget_ValueBase *valuewidget; + bool edit_done_called; + Gtk::Widget *parent; +public: + ValueBase_Entry(): + Glib::ObjectBase (typeid(ValueBase_Entry)), + Gtk::EventBox (), + Gtk::CellEditable () + { + parent=0; + edit_done_called=false; +/* + Gtk::HBox *const hbox = new Gtk::HBox(false, 0); + add(*Gtk::manage(hbox)); + + Gtk::Entry *entry_ = new Gtk::Entry(); + entry_->set_text("bleh"); + hbox->pack_start(*Gtk::manage(entry_), Gtk::PACK_EXPAND_WIDGET); + entry_->set_has_frame(false); + entry_->gobj()->is_cell_renderer = true; // XXX + +*/ + valuewidget=manage(new class Widget_ValueBase()); + valuewidget->inside_cellrenderer(); + add(*valuewidget); + valuewidget->show(); + + //set_flags(Gtk::CAN_FOCUS); + //set_events(Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK); + + /* + set_events(//(Gdk::ALL_EVENTS_MASK) + ~( Gdk::EXPOSURE_MASK + | Gdk::ENTER_NOTIFY_MASK + | Gdk::LEAVE_NOTIFY_MASK + | Gdk::FOCUS_CHANGE_MASK + | Gdk::STRUCTURE_MASK + | Gdk::PROPERTY_CHANGE_MASK + | Gdk::VISIBILITY_NOTIFY_MASK + | Gdk::PROXIMITY_IN_MASK + | Gdk::PROXIMITY_OUT_MASK + | Gdk::SUBSTRUCTURE_MASK + ) + ); + */ + //signal_editing_done().connect(sigc::mem_fun(*this, &studio::ValueBase_Entry::hide)); + //signal_remove_widget().connect(sigc::mem_fun(*this, &studio::ValueBase_Entry::hide)); + + show_all_children(); + + //signal_show().connect(sigc::mem_fun(*this, &ValueBase_Entry::grab_focus)); + } + ~ValueBase_Entry() + { + } + + void on_editing_done() + { + hide(); + if(parent)parent->grab_focus(); + if(!edit_done_called) + { + edit_done_called=true; + Gtk::CellEditable::on_editing_done(); + } + else + { + synfig::error("on_editing_done(): Called twice!"); + } + } + void set_parent(Gtk::Widget*x) { parent=x; } + void on_remove_widget() + { + hide(); + edit_done_called=true; + if(parent)parent->grab_focus(); + Gtk::CellEditable::on_remove_widget(); + } + void start_editing_vfunc(GdkEvent */*event*/) + { + valuewidget->signal_activate().connect(sigc::mem_fun(*this, &studio::ValueBase_Entry::editing_done)); + show(); + //valuewidget->grab_focus(); + //get_window()->set_focus(*valuewidget); + } + bool on_event(GdkEvent *event) + { + if(event->any.type==GDK_BUTTON_PRESS || + event->any.type==GDK_2BUTTON_PRESS || + event->any.type==GDK_KEY_PRESS || + event->any.type==GDK_KEY_RELEASE || + event->any.type==GDK_SCROLL || + event->any.type==GDK_3BUTTON_PRESS) + return true; + return Gtk::EventBox::on_event(event); + } + void on_grab_focus() + { + Gtk::EventBox::on_grab_focus(); + if(valuewidget) + valuewidget->grab_focus(); + } + void set_path(const Glib::ustring &p) + { + path=p; + } + void set_value(const synfig::ValueBase &data) + { + if(valuewidget) + valuewidget->set_value(data); + //valuewidget->grab_focus(); + } + void set_canvas(const etl::handle &data) + { + assert(data); + if(valuewidget) + valuewidget->set_canvas(data); + } + void set_param_desc(const synfig::ParamDesc &data) + { + if(valuewidget) + valuewidget->set_param_desc(data); + } + + const synfig::ValueBase &get_value() + { + if(valuewidget) + return valuewidget->get_value(); + + warning("%s:%d this code shouldn't be reached", __FILE__, __LINE__); + return *(new synfig::ValueBase()); + } + + const Glib::ustring &get_path() + { + return path; + } + +}; + +/* === P R O C E D U R E S ================================================= */ + +bool get_paragraph(synfig::String& text) +{ + Gtk::Dialog dialog( + _("Paragraph"), // Title + true, // Modal + true // use_separator + ); + Gtk::Label label(_("Enter Paragraph Text Here:")); + label.show(); + dialog.get_vbox()->pack_start(label); + + + Glib::RefPtr text_buffer(Gtk::TextBuffer::create()); + text_buffer->set_text(text); + + Gtk::TextView text_view(text_buffer); + text_view.show(); + dialog.get_vbox()->pack_start(text_view); + +/* + Gtk::Entry entry; + entry.set_text(text); + entry.show(); + entry.set_activates_default(true); + dialog.get_vbox()->pack_start(entry); +*/ + + dialog.add_button(Gtk::StockID("gtk-ok"),Gtk::RESPONSE_OK); + dialog.add_button(Gtk::StockID("gtk-cancel"),Gtk::RESPONSE_CANCEL); + dialog.set_default_response(Gtk::RESPONSE_OK); + + //text_entry.signal_activate().connect(sigc::bind(sigc::mem_fun(dialog,&Gtk::Dialog::response),Gtk::RESPONSE_OK)); + + dialog.show(); + + if(dialog.run()!=Gtk::RESPONSE_OK) + return false; + + text=text_buffer->get_text(); + + return true; +} + +/* === M E T H O D S ======================================================= */ + +CellRenderer_ValueBase::CellRenderer_ValueBase(): + Glib::ObjectBase (typeid(CellRenderer_ValueBase)), + Gtk::CellRendererText (), + property_value_ (*this,"value",synfig::ValueBase()), + property_canvas_(*this,"canvas",etl::handle()), + property_param_desc_(*this,"param_desc",synfig::ParamDesc()) +{ + CellRendererText::signal_edited().connect(sigc::mem_fun(*this,&CellRenderer_ValueBase::string_edited_)); + value_entry=new ValueBase_Entry(); + value_entry->hide(); + + Pango::AttrList attr_list; + { + Pango::AttrInt pango_size(Pango::Attribute::create_attr_size(Pango::SCALE*8)); + pango_size.set_start_index(0); + pango_size.set_end_index(64); + attr_list.change(pango_size); + } + property_attributes()=attr_list; + + property_foreground()=Glib::ustring("#7f7f7f"); + property_inconsistent()=false; +} + +CellRenderer_ValueBase::~CellRenderer_ValueBase() +{ + if (getenv("SYNFIG_DEBUG_DESTRUCTORS")) + synfig::info("CellRenderer_ValueBase::~CellRenderer_ValueBase(): Deleted"); +} + +void +CellRenderer_ValueBase::string_edited_(const Glib::ustring&path,const Glib::ustring&str) +{ + ValueBase old_value=property_value_.get_value(); + ValueBase value; + + if(old_value.get_type()==ValueBase::TYPE_TIME) + { + value=ValueBase(Time((String)str,get_canvas()->rend_desc().get_frame_rate())); + } + else + value=ValueBase((String)str); + + if(old_value!=value) + signal_edited_(path,value); +} + +void +CellRenderer_ValueBase::render_vfunc( + const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& ca, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags) +{ + if(!window) + return; +// const unsigned int cell_xpad = property_xpad(); +// const unsigned int cell_ypad = property_ypad(); + + //int x_offset = 0, y_offset = 0; +// int width = ca.get_width(); + int height = ca.get_height(); +// get_size(widget, ca, x_offset, y_offset, width, height); + +// width -= cell_xpad * 2; +// height -= cell_ypad * 2; + +// if(width <= 0 || height <= 0) +// return; + + Gtk::StateType state = Gtk::STATE_INSENSITIVE; + if(property_editable()) + state = Gtk::STATE_NORMAL; + if((flags & Gtk::CELL_RENDERER_SELECTED) != 0) + state = (widget.has_focus()) ? Gtk::STATE_SELECTED : Gtk::STATE_ACTIVE; + + ValueBase data=property_value_.get_value(); + + switch(data.get_type()) + { + case ValueBase::TYPE_REAL: + if(((synfig::ParamDesc)property_param_desc_).get_is_distance()) + { + Distance x(data.get(Real()),Distance::SYSTEM_UNITS); + x.convert(App::distance_system,get_canvas()->rend_desc()); + property_text()=(Glib::ustring)x.get_string(6).c_str(); + } + else + property_text()=(Glib::ustring)strprintf("%.6f",data.get(Real())); + break; + case ValueBase::TYPE_TIME: + property_text()=(Glib::ustring)data.get(Time()).get_string(get_canvas()->rend_desc().get_frame_rate(),App::get_time_format()); + break; + case ValueBase::TYPE_ANGLE: + property_text()=(Glib::ustring)strprintf("%.2f DEG",(Real)Angle::deg(data.get(Angle())).get()); + break; + case ValueBase::TYPE_INTEGER: + if(((synfig::ParamDesc)property_param_desc_).get_hint()!="enum") + { + property_text()=(Glib::ustring)strprintf("%i",data.get(int())); + } + else + { + property_text()=(Glib::ustring)strprintf("(%i)",data.get(int())); + std::list enum_list=((synfig::ParamDesc)property_param_desc_).get_enum_list(); + std::list::iterator iter; + + for(iter=enum_list.begin();iter!=enum_list.end();iter++) + if(iter->value==data.get(int())) + { + // don't show the key_board s_hortcut under_scores + String local_name = iter->local_name; + String::size_type pos = local_name.find_first_of('_'); + if (pos != String::npos) + property_text() = local_name.substr(0,pos) + local_name.substr(pos+1); + else + property_text() = local_name; + break; + } + } + + break; + case ValueBase::TYPE_VECTOR: + { + Vector vector=data.get(Vector()); + Distance x(vector[0],Distance::SYSTEM_UNITS),y(vector[1],Distance::SYSTEM_UNITS); + x.convert(App::distance_system,get_canvas()->rend_desc()); + y.convert(App::distance_system,get_canvas()->rend_desc()); + property_text()=static_cast(strprintf("%s,%s",x.get_string(6).c_str(),y.get_string(6).c_str())); + } + break; + + case ValueBase::TYPE_STRING: + + if(data.get_type()==ValueBase::TYPE_STRING) + { + if(!data.get(synfig::String()).empty()) + property_text()=static_cast(data.get(synfig::String())); + else + property_text()=Glib::ustring(""); + } + break; + case ValueBase::TYPE_CANVAS: + if(data.get(etl::handle())) + { + if(data.get(etl::handle())->is_inline()) + property_text()=_(""); + else + property_text()=(Glib::ustring)data.get(etl::handle())->get_id(); + } + else + property_text()=""; + break; + case ValueBase::TYPE_COLOR: + { + render_color_to_window(window,ca,data.get(Color())); + return; + } + break; + case ValueBase::TYPE_BOOL: + { + widget.get_style()->paint_check( + Glib::RefPtr::cast_static(window), state, + data.get(bool())?Gtk::SHADOW_IN:Gtk::SHADOW_OUT, + ca, widget, "cellcheck", + ca.get_x()/* + x_offset + cell_xpad*/, + ca.get_y()/* + y_offset + cell_ypad*/, + height-1,height-1); + return; + } + break; + case ValueBase::TYPE_NIL: + //property_text()=(Glib::ustring)" "; + return; + break; + case ValueBase::TYPE_SEGMENT: + property_text()=(Glib::ustring)_("Segment"); + break; + case ValueBase::TYPE_GRADIENT: + render_gradient_to_window(window,ca,data.get(Gradient())); + return; + break; + case ValueBase::TYPE_LIST: + property_text()=(Glib::ustring)_("List"); + break; + case ValueBase::TYPE_BLINEPOINT: + property_text()=(Glib::ustring)_("BLine Point"); + break; + default: + property_text()=static_cast(_("UNKNOWN")); + break; + } + CellRendererText::render_vfunc(window,widget,background_area,ca,expose_area,flags); +} + + +/* +bool +CellRenderer_ValueBase::activate_vfunc( GdkEvent* event, + Gtk::Widget& widget, + const Glib::ustring& path, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags) +{ + ValueBase data=(ValueBase)property_value_.get_value(); + + switch(data.type) + { + case ValueBase::TYPE_BOOL: + if(property_editable()) + signal_edited_(path,ValueBase(!data.get(bool()))); + return true; + case ValueBase::TYPE_STRING: + return CellRendererText::activate_vfunc(event,widget,path,background_area,cell_area,flags); + } + return false; +} +*/ + +void +CellRenderer_ValueBase::gradient_edited(synfig::Gradient gradient, Glib::ustring path) +{ + ValueBase old_value(property_value_.get_value()); + ValueBase value(gradient); + if(old_value!=value) + signal_edited_(path,value); +} + +void +CellRenderer_ValueBase::color_edited(synfig::Color color, Glib::ustring path) +{ + ValueBase old_value(property_value_.get_value()); + ValueBase value(color); + if(old_value!=value) + signal_edited_(path,value); +} + +Gtk::CellEditable* +CellRenderer_ValueBase::start_editing_vfunc( + GdkEvent* event __attribute__ ((unused)), + Gtk::Widget& widget, + const Glib::ustring& path, + const Gdk::Rectangle& background_area __attribute__ ((unused)), + const Gdk::Rectangle& cell_area __attribute__ ((unused)), + Gtk::CellRendererState flags __attribute__ ((unused))) +{ + edit_value_done_called = false; + // If we aren't editable, then there is nothing to do + if(!property_editable()) + return 0; + + ValueBase data=property_value_.get_value(); + + switch(data.get_type()) + { + case ValueBase::TYPE_BOOL: + signal_edited_(path,ValueBase(!data.get(bool()))); + return NULL; + //case ValueBase::TYPE_TIME: + // property_text()=(Glib::ustring)data.get(Time()).get_string(get_canvas()->rend_desc().get_frame_rate(),App::get_time_format()|Time::FORMAT_FULL); + // return CellRendererText::start_editing_vfunc(event,widget,path,background_area,cell_area,flags); + + case ValueBase::TYPE_GRADIENT: + App::dialog_gradient->reset(); + App::dialog_gradient->set_gradient(data.get(Gradient())); + App::dialog_gradient->signal_edited().connect( + sigc::bind( + sigc::mem_fun(*this,&studio::CellRenderer_ValueBase::gradient_edited), + path + ) + ); + App::dialog_gradient->grab_button_set_sensitive(true); + App::dialog_gradient->present(); + + return NULL; + + case ValueBase::TYPE_COLOR: + App::dialog_color->reset(); + App::dialog_color->set_color(data.get(Color())); + App::dialog_color->signal_edited().connect( + sigc::bind( + sigc::mem_fun(*this,&studio::CellRenderer_ValueBase::color_edited), + path + ) + ); + App::dialog_color->present(); + + return NULL; + case ValueBase::TYPE_STRING: + if(get_param_desc().get_hint()=="paragraph") + { + synfig::String string; + string=data.get(string); + if(get_paragraph(string)) + signal_edited_(path,ValueBase(string)); + return NULL; + } + // if(get_param_desc().get_hint()!="filename") + // return CellRendererText::start_editing_vfunc(event,widget,path,background_area,cell_area,flags); + default: + { + assert(get_canvas()); + //delete value_entry; + value_entry=manage(new ValueBase_Entry()); + value_entry->set_path(path); + value_entry->set_canvas(get_canvas()); + value_entry->set_param_desc(get_param_desc()); + value_entry->set_value(data); + value_entry->set_parent(&widget); + value_entry->signal_editing_done().connect(sigc::mem_fun(*this, &CellRenderer_ValueBase::on_value_editing_done)); + return value_entry; + } + } + return NULL; +} + +void +CellRenderer_ValueBase::on_value_editing_done() +{ + if (edit_value_done_called) + { + synfig::error("on_value_editing_done(): Called twice!"); + return; + } + + edit_value_done_called = true; + + if(value_entry) + { + ValueBase old_value(property_value_.get_value()); + ValueBase value(value_entry->get_value()); + + if(old_value!=value) + signal_edited_(value_entry->get_path(),value); + + //delete value_entry; + //value_entry=0; + } +}