gradient-context.cpp revision 3da8c9f095f6e1d434809a58940f93585c58ebf3
7042N/A#define __SP_GRADIENT_CONTEXT_C__
7042N/A#ifdef HAVE_CONFIG_H
7042N/A#include "document.h"
7042N/A#include "selection.h"
7042N/A#include "desktop-handles.h"
7042N/A#include "message-context.h"
7042N/A#include "message-stack.h"
7042N/A#include "pixmaps/cursor-gradient.xpm"
7042N/A#include "pixmaps/cursor-gradient-add.xpm"
7042N/A#include "gradient-context.h"
7042N/A#include "gradient-chemistry.h"
7042N/A#include "prefs-utils.h"
7042N/A#include "gradient-drag.h"
7042N/A#include "gradient-chemistry.h"
7042N/A#include "display/sp-ctrlline.h"
7042N/A#include "sp-linear-gradient.h"
7042N/A#include "sp-radial-gradient.h"
7042N/A#include "svg/css-ostringstream.h"
7042N/A#include "svg/svg-color.h"
7042N/A#include "sp-namedview.h"
7042N/A#include "rubberband.h"
7042N/Astatic gint sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event);
7042N/Astatic void sp_gradient_drag(SPGradientContext &rc, NR::Point const pt, guint state, guint32 etime);
7042N/A sizeof(SPGradientContextClass),
7042N/A sizeof(SPGradientContext),
7042N/A type = g_type_register_static(SP_TYPE_EVENT_CONTEXT, "SPGradientContext", &info, (GTypeFlags) 0);
return type;
//The use of ngettext in the following code is intentional even if the English singular form would never be used
//TRANSLATORS: %s will be substituted with the point name (see previous messages); This is part of a compound message
//TRANSLATORS: This is a part of a compound message (out of two more indicating: grandint handle count & object count)
"One handle merging %d stops (drag with <b>Shift</b> to separate) selected",drag->singleSelectedDraggerNumDraggables()),
rc->_message_context->setF(Inkscape::NORMAL_MESSAGE,message,drag->singleSelectedDraggerNumDraggables(), n_tot, n_obj);
//TRANSLATORS: The plural refers to number of selected gradient handles. This is part of a compound message (part two indicates selected object count)
gchar * message = g_strconcat(ngettext("<b>%d</b> gradient handle selected out of %d","<b>%d</b> gradient handles selected out of %d",n_sel),
//TRANSLATORS: Mind the space in front. (Refers to gradient handles selected). This is part of a compound message
} else if (n_sel == 0) {
rc->selcon = new sigc::connection (selection->connectChanged( sigc::bind (sigc::ptr_fun(&gradient_selection_changed), rc)));
rc->subselcon = new sigc::connection (ec->desktop->connectToolSubselectionChanged(sigc::bind (sigc::ptr_fun(&gradient_subselection_changed), rc)));
return close;
if (next_stop) {
return coords;
std::vector<NR::Point> coords = sp_gradient_context_get_stop_intervals (drag, &these_stops, &next_stops);
double sqr(double x) {return x*x;}
std::vector<NR::Point> coords = sp_gradient_context_get_stop_intervals (drag, &these_stops, &next_stops);
if (next_next) {
double diff =
sp_gradient_context_add_stop_near_point (SPGradientContext *rc, SPItem *item, NR::Point mouse_p, guint32 /*etime*/)
static gint
static bool dragging;
event_context->tolerance = prefs_get_int_attribute_limited("options.dragtolerance", "value", 0, 0, 100);
double const nudge = prefs_get_double_attribute_limited("options.nudgedistance", "value", 2, 0, 1000); // in px
case GDK_2BUTTON_PRESS:
bool over_line = false;
over_line |= sp_gradient_context_is_over_line (rc, (SPItem*) line, NR::Point(event->motion.x, event->motion.y));
if (over_line) {
sp_gradient_context_add_stop_near_point(rc, SP_ITEM(selection->itemList()->data), rc->mousepoint_doc, event->button.time);
SPGradientType new_type = (SPGradientType) prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR);
SPGradient *vector = sp_gradient_vector_for_object(sp_desktop_document(desktop), desktop, SP_OBJECT (item), new_fill);
case GDK_BUTTON_PRESS:
dragging = true;
event_context->item_to_select = sp_event_context_find_item (desktop, button_w, event->button.state & GDK_MOD1_MASK, TRUE);
case GDK_MOTION_NOTIFY:
if ( dragging
event_context->defaultMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Draw around</b> handles to select them"));
bool over_line = false;
over_line |= sp_gradient_context_is_over_line (rc, (SPItem*) l->data, NR::Point(event->motion.x, event->motion.y));
case GDK_BUTTON_RELEASE:
bool over_line = false;
over_line = sp_gradient_context_is_over_line (rc, (SPItem*) line, NR::Point(event->motion.x, event->motion.y));
if (over_line)
dragging = false;
case GDK_KEY_PRESS:
case GDK_Alt_L:
case GDK_Alt_R:
case GDK_Control_L:
case GDK_Control_R:
case GDK_Shift_L:
case GDK_Shift_R:
case GDK_Meta_R:
NULL);
case GDK_x:
case GDK_X:
if (MOD__ALT_ONLY) {
case GDK_A:
case GDK_a:
case GDK_L:
case GDK_l:
case GDK_Escape:
case GDK_KP_Left:
case GDK_KP_4:
case GDK_KP_Up:
case GDK_KP_8:
case GDK_KP_Right:
case GDK_KP_6:
case GDK_KP_Down:
case GDK_KP_2:
case GDK_r:
case GDK_R:
if (MOD__SHIFT_ONLY) {
case GDK_Insert:
case GDK_KP_Insert:
case GDK_Delete:
case GDK_KP_Delete:
case GDK_BackSpace:
case GDK_KEY_RELEASE:
case GDK_Alt_L:
case GDK_Alt_R:
case GDK_Control_L:
case GDK_Control_R:
case GDK_Shift_L:
case GDK_Shift_R:
case GDK_Meta_R:
if (!ret) {
return ret;
static void sp_gradient_drag(SPGradientContext &rc, NR::Point const pt, guint /*state*/, guint32 etime)
vector = sp_gradient_vector_for_object(document, desktop, SP_ITEM(g_slist_last(items)->data), fill_or_stroke);
// HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
sp_item_gradient_set_coords (SP_ITEM(i->data), POINT_LG_BEGIN, 0, rc.origin, fill_or_stroke, true, false);
sp_item_gradient_set_coords (SP_ITEM(i->data), POINT_RG_CENTER, 0, rc.origin, fill_or_stroke, true, false);
sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>objects</b> on which to create gradient."));