index f2c40b968252c16001d18635f00ce97edd82597b..b3dd1a7d0091301a5a841191f93be9e17f83e616 100644 (file)
#include "desktop.h"
#include "desktop-handles.h"
#include "dialog-manager.h"
+#include "dir-util.h"
#include "document.h"
#include "filter-chemistry.h"
#include "filter-effects-dialog.h"
#include "filter-enums.h"
#include "inkscape.h"
#include "path-prefix.h"
+#include "prefs-utils.h"
#include "selection.h"
#include "sp-feblend.h"
#include "sp-fecolormatrix.h"
#include "style.h"
#include "svg/svg-color.h"
+#include "ui/dialog/filedialog.h"
#include "verbs.h"
#include "xml/node.h"
#include "xml/node-observer.h"
#include "xml/repr.h"
#include <sstream>
+#include "io/sys.h"
#include <iostream>
using namespace NR;
double _angle_store;
};
+static Inkscape::UI::Dialog::FileOpenDialog * selectFeImageFileInstance = NULL;
+
+//Displays a chooser for feImage input
+//It may be a filename or the id for an SVG Element
+//described in xlink:href syntax
+class FileOrElementChooser : public Gtk::HBox, public AttrWidget
+{
+public:
+ FileOrElementChooser(const SPAttributeEnum a)
+ : AttrWidget(a)
+ {
+ pack_start(_entry, false, false);
+ pack_start(_fromFile, false, false);
+ //pack_start(_fromSVGElement, false, false);
+
+ _fromFile.set_label(_("Image File"));
+ _fromFile.signal_clicked().connect(sigc::mem_fun(*this, &FileOrElementChooser::select_file));
+
+ _fromSVGElement.set_label(_("Selected SVG Element"));
+ _fromSVGElement.signal_clicked().connect(sigc::mem_fun(*this, &FileOrElementChooser::select_svg_element));
+
+ _entry.signal_changed().connect(signal_attr_changed().make_slot());
+
+ show_all();
+
+ }
+
+ // Returns the element in xlink:href form.
+ Glib::ustring get_as_attribute() const
+ {
+ return _entry.get_text();
+ }
+
+
+ void set_from_attribute(SPObject* o)
+ {
+ const gchar* val = attribute_value(o);
+ if(val) {
+ _entry.set_text(val);
+ }
+ }
+
+ void set_desktop(SPDesktop* d){
+ _desktop = d;
+ }
+
+private:
+ void select_svg_element(){
+ Inkscape::Selection* sel = sp_desktop_selection(_desktop);
+ if (sel->isEmpty()) return;
+ Inkscape::XML::Node* node = (Inkscape::XML::Node*) g_slist_nth_data((GSList *)sel->reprList(), 0);
+ if (!node || !node->matchAttributeName("id")) return;
+
+ std::ostringstream xlikhref;
+ xlikhref << "#(" << node->attribute("id") << ")";
+ _entry.set_text(xlikhref.str());
+ }
+
+ void select_file(){
+
+ //# Get the current directory for finding files
+ Glib::ustring open_path;
+ char *attr = (char *)prefs_get_string_attribute("dialogs.open", "path");
+ if (attr)
+ open_path = attr;
+
+ //# Test if the open_path directory exists
+ if (!Inkscape::IO::file_test(open_path.c_str(),
+ (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
+ open_path = "";
+
+ //# If no open path, default to our home directory
+ if (open_path.size() < 1)
+ {
+ open_path = g_get_home_dir();
+ open_path.append(G_DIR_SEPARATOR_S);
+ }
+
+ //# Create a dialog if we don't already have one
+ if (!selectFeImageFileInstance) {
+ selectFeImageFileInstance =
+ Inkscape::UI::Dialog::FileOpenDialog::create(
+ *_desktop->getToplevel(),
+ open_path,
+ Inkscape::UI::Dialog::SVG_TYPES,/*TODO: any image, not justy svg*/
+ (char const *)_("Select an image to be used as feImage input"));
+ }
+
+ //# Show the dialog
+ bool const success = selectFeImageFileInstance->show();
+ if (!success)
+ return;
+
+ //# User selected something. Get name and type
+ Glib::ustring fileName = selectFeImageFileInstance->getFilename();
+
+ if (fileName.size() > 0) {
+
+ Glib::ustring newFileName = Glib::filename_to_utf8(fileName);
+
+ if ( newFileName.size() > 0)
+ fileName = newFileName;
+ else
+ g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" );
+
+ open_path = fileName;
+ open_path.append(G_DIR_SEPARATOR_S);
+ prefs_set_string_attribute("dialogs.open", "path", open_path.c_str());
+
+ _entry.set_text(fileName);
+ }
+ return;
+ }
+
+ Gtk::Entry _entry;
+ Gtk::Button _fromFile;
+ Gtk::Button _fromSVGElement;
+ SPDesktop* _desktop;
+};
+
class FilterEffectsDialog::Settings
{
public:
add_attr_widget(dsb);
return dsb;
}
-
+
// MultiSpinButton
MultiSpinButton* add_multispinbutton(const SPAttributeEnum attr1, const SPAttributeEnum attr2,
const Glib::ustring& label, const double lo, const double hi,
add_attr_widget(msb->get_spinbuttons()[i]);
return msb;
}
+
+ // FileOrElementChooser
+ FileOrElementChooser* add_fileorelement(const SPAttributeEnum attr, const Glib::ustring& label)
+ {
+ FileOrElementChooser* foech = new FileOrElementChooser(attr);
+ foech->set_desktop(_dialog.getDesktop());
+ add_widget(foech, label);
+ add_attr_widget(foech);
+ return foech;
+ }
// ComboBoxEnum
template<typename T> ComboBoxEnum<T>* add_combo(const SPAttributeEnum attr,
_sizegroup = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_HORIZONTAL);
_sizegroup->set_ignore_hidden();
- _add_primitive_type.remove_row(NR_FILTER_IMAGE);
_add_primitive_type.remove_row(NR_FILTER_TILE);
_add_primitive_type.remove_row(NR_FILTER_COMPONENTTRANSFER);
_settings->add_dualspinslider(SP_ATTR_RADIUS, _("Radius"), 0, 100, 1, 0.01, 1);
_settings->type(NR_FILTER_IMAGE);
- _settings->add_notimplemented();
-
+ _settings->add_fileorelement(SP_ATTR_XLINK_HREF, _("Source of Image"));
+ _settings->add_multispinbutton(SP_ATTR_X, SP_ATTR_Y, _("Coordinates"), -10000, 10000, 1, 1, 0);
+ _settings->add_multispinbutton(SP_ATTR_WIDTH, SP_ATTR_HEIGHT, _("Dimensions"), 0, 10000, 1, 1, 0);
+
_settings->type(NR_FILTER_OFFSET);
_settings->add_spinslider(SP_ATTR_DX, _("Delta X"), -100, 100, 1, 0.01, 1);
_settings->add_spinslider(SP_ATTR_DY, _("Delta Y"), -100, 100, 1, 0.01, 1);
switch(_add_primitive_type.get_active_data()->id){
case(NR::NR_FILTER_BLEND):
_infobox_icon.set(g_strdup_printf("%s/feBlend-icon.png", INKSCAPE_PIXMAPDIR));
- _infobox_desc.set_markup(_("The <b>feBlend</b> filter primitive gives us 4 image blending modes: screen, multiply, darken and lighten."));
+ _infobox_desc.set_markup(_("The <b>feBlend</b> filter primitive provides 4 image blending modes: screen, multiply, darken and lighten."));
break;
case(NR::NR_FILTER_COLORMATRIX):
_infobox_icon.set(g_strdup_printf("%s/feColorMatrix-icon.png", INKSCAPE_PIXMAPDIR));
_infobox_desc.set_markup(_("The <b>feColorMatrix</b> filter primitive applies a matrix transformation to colour of each rendered pixel. This allows for effects like turning object to grayscale, modifying colour saturation and changing colour hue."));
break;
case(NR::NR_FILTER_COMPONENTTRANSFER):
- //_infobox_icon.set(g_strdup_printf("%s/feComponentTransfer-icon.png", INKSCAPE_PIXMAPDIR));
- //_infobox_desc.set_markup(_(""));
+ _infobox_icon.set(g_strdup_printf("%s/feComponentTransfer-icon.png", INKSCAPE_PIXMAPDIR));
+ _infobox_desc.set_markup(_("The <b>feComponentTransfer</b> filter primitive manipulates the input's color components (red, green, blue, and alpha) according to particular transfer functions, allowing operations like brightness and contrast adjustment, color balance, and thresholding."));
break;
case(NR::NR_FILTER_COMPOSITE):
_infobox_icon.set(g_strdup_printf("%s/feComposite-icon.png", INKSCAPE_PIXMAPDIR));
break;
case(NR::NR_FILTER_DIFFUSELIGHTING):
_infobox_icon.set(g_strdup_printf("%s/feDiffuseLighting-icon.png", INKSCAPE_PIXMAPDIR));
- _infobox_desc.set_markup(_("Filter primitives <b>feDiffuseLighting</b> and feSpecularLighting create lighting maps for the object in input image. These filters use alpha channel of input image as a height map: the more opaque given point in input image is, the nearer spectator it is considered to be."));
+ _infobox_desc.set_markup(_("The <b>feDiffuseLighting</b> and feSpecularLighting filter primitives create \"embossed\" shadings. The input's alpha channel is used to provide depth information: higher opacity areas are raised toward the viewer and lower opacity areas recede away from the viewer."));
break;
case(NR::NR_FILTER_DISPLACEMENTMAP):
_infobox_icon.set(g_strdup_printf("%s/feDisplacementMap-icon.png", INKSCAPE_PIXMAPDIR));
break;
case(NR::NR_FILTER_FLOOD):
_infobox_icon.set(g_strdup_printf("%s/feFlood-icon.png", INKSCAPE_PIXMAPDIR));
- _infobox_desc.set_markup(_("The <b>feFlood</b> filter primitive fills its region with a given color and opacity. It can be used as an auxiliary tool, usualy in combination with other filter primitives, in order to facilitate some common color handling operations."));
+ _infobox_desc.set_markup(_("The <b>feFlood</b> filter primitive fills the region with a given color and opacity. It is usually used as an input to other filters to apply color to a graphic."));
break;
case(NR::NR_FILTER_GAUSSIANBLUR):
_infobox_icon.set(g_strdup_printf("%s/feGaussianBlur-icon.png", INKSCAPE_PIXMAPDIR));
- _infobox_desc.set_markup(_("The <b>feGaussianBlur</b> filter primitive gives an out-of-focus aspect to images. It is commonly used toghether with feOffset in order to create a drop shadow effect."));
+ _infobox_desc.set_markup(_("The <b>feGaussianBlur</b> filter primitive uniformly blurs its input. It is commonly used together with feOffset to create a drop shadow effect."));
break;
case(NR::NR_FILTER_IMAGE):
- //_infobox_icon.set(g_strdup_printf("%s/feImage-icon.png", INKSCAPE_PIXMAPDIR));
- //_infobox_desc.set_markup(_(""));
+ _infobox_icon.set(g_strdup_printf("%s/feImage-icon.png", INKSCAPE_PIXMAPDIR));
+ _infobox_desc.set_markup(_("The <b>feImage</b> filter primitive fills the region with an external image or another part of the document."));
break;
case(NR::NR_FILTER_MERGE):
_infobox_icon.set(g_strdup_printf("%s/feMerge-icon.png", INKSCAPE_PIXMAPDIR));
break;
case(NR::NR_FILTER_SPECULARLIGHTING):
_infobox_icon.set(g_strdup_printf("%s/feSpecularLighting-icon.png", INKSCAPE_PIXMAPDIR));
- _infobox_desc.set_markup(_("Filter primitives feDiffuseLighting and <b>feSpecularLighting</b> create lighting maps for the object in input image. These filters use alpha channel of input image as a height map: the more opaque given point in input image is, the nearer spectator it is considered to be."));
+ _infobox_desc.set_markup(_("The feDiffuseLighting and <b>feSpecularLighting</b> filter primitives create \"embossed\" shadings. The input's alpha channel is used to provide depth information: higher opacity areas are raised toward the viewer and lower opacity areas recede away from the viewer."));
break;
case(NR::NR_FILTER_TILE):
- //_infobox_icon.set(g_strdup_printf("%s/feTile-icon.png", INKSCAPE_PIXMAPDIR));
- //_infobox_desc.set_markup(_(""));
+ _infobox_icon.set(g_strdup_printf("%s/feTile-icon.png", INKSCAPE_PIXMAPDIR));
+ _infobox_desc.set_markup(_("The <b>feTile</b> filter primitive tiles a region with its input graphic"));
break;
case(NR::NR_FILTER_TURBULENCE):
_infobox_icon.set(g_strdup_printf("%s/feTurbulence-icon.png", INKSCAPE_PIXMAPDIR));