summaryrefslogtreecommitdiffstats
path: root/src/ui/tools/dropper-tool.cpp
diff options
context:
space:
mode:
authorMartin Owens <doctormo@gmail.com>2017-07-05 23:27:24 +0000
committerMartin Owens <doctormo@gmail.com>2017-07-05 23:27:24 +0000
commit81f8acdd523508c1006e9041590152aff86f6075 (patch)
treeaf0b45f284e48e0057ebdbb1f56860372656a4fd /src/ui/tools/dropper-tool.cpp
parentcursors: rm deprecated gtkstyle custom black/white (diff)
downloadinkscape-81f8acdd523508c1006e9041590152aff86f6075.tar.gz
inkscape-81f8acdd523508c1006e9041590152aff86f6075.zip
Upgrade dropper with fixed for each of the modes
Diffstat (limited to 'src/ui/tools/dropper-tool.cpp')
-rw-r--r--src/ui/tools/dropper-tool.cpp204
1 files changed, 99 insertions, 105 deletions
diff --git a/src/ui/tools/dropper-tool.cpp b/src/ui/tools/dropper-tool.cpp
index 9b37aed17..53a99e481 100644
--- a/src/ui/tools/dropper-tool.cpp
+++ b/src/ui/tools/dropper-tool.cpp
@@ -64,6 +64,10 @@ DropperTool::DropperTool()
, G(0)
, B(0)
, alpha(0)
+ , radius(0)
+ , invert(false)
+ , stroke(false)
+ , dropping(false)
, dragging(false)
, grabbed(NULL)
, area(NULL)
@@ -120,16 +124,17 @@ void DropperTool::finish() {
/**
* Returns the current dropper context color.
*/
-guint32 DropperTool::get_color() {
+guint32 DropperTool::get_color(bool invert) {
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int pick = prefs->getInt("/tools/dropper/pick", SP_DROPPER_PICK_VISIBLE);
bool setalpha = prefs->getBool("/tools/dropper/setalpha", true);
- return SP_RGBA32_F_COMPOSE(this->R,
- this->G,
- this->B,
- (pick == SP_DROPPER_PICK_ACTUAL && setalpha) ? this->alpha : 1.0);
+ return SP_RGBA32_F_COMPOSE(
+ fabs(invert - this->R),
+ fabs(invert - this->G),
+ fabs(invert - this->B),
+ (pick == SP_DROPPER_PICK_ACTUAL && setalpha) ? this->alpha : 1.0);
}
bool DropperTool::root_handler(GdkEvent* event) {
@@ -137,26 +142,58 @@ bool DropperTool::root_handler(GdkEvent* event) {
int ret = FALSE;
int pick = prefs->getInt("/tools/dropper/pick", SP_DROPPER_PICK_VISIBLE);
- bool setalpha = prefs->getBool("/tools/dropper/setalpha", true);
- bool fill = !(event->button.state & GDK_SHIFT_MASK); // Stroke if Shift key held
- bool apply = event->button.state & GDK_CONTROL_MASK; // Apply if Ctrl key held
- int draw_cursor = fill ? DRAW_FILL_CURSOR : DRAW_STROKE_CURSOR;
+
+ // Decide first what kind of 'mode' we're in.
+ if (event->type == GDK_KEY_PRESS || event->type == GDK_KEY_RELEASE) {
+ switch (event->key.keyval) {
+ case GDK_KEY_Shift_L:
+ case GDK_KEY_Shift_R:
+ this->stroke = event->type == GDK_KEY_PRESS;
+ break;
+ case GDK_KEY_Control_L:
+ case GDK_KEY_Control_R:
+ this->dropping = event->type == GDK_KEY_PRESS;
+ break;
+ case GDK_KEY_Alt_L:
+ case GDK_KEY_Alt_R:
+ this->invert = event->type == GDK_KEY_PRESS;
+ break;
+ }
+ }
// Get color from selected object instead.
- guint32 apply_color = 0;
- if(apply) {
+ if(this->dropping) {
Inkscape::Selection *selection = desktop->getSelection();
g_assert(selection);
+ guint32 apply_color;
+ bool apply_set = false;
for (auto& obj: selection->objects()) {
- if(obj->style) {
- if(obj->style->fill.set) {
- double opacity = 1.0;
- if(obj->style->fill_opacity.set) {
- opacity = obj->style->fill_opacity.value;
- }
- apply_color = obj->style->fill.value.color.toRGBA32(opacity);
+ if(obj->style) {
+ double opacity = 1.0;
+ if(!this->stroke && obj->style->fill.set) {
+ if(obj->style->fill_opacity.set) {
+ opacity = obj->style->fill_opacity.value;
+ }
+ apply_color = obj->style->fill.value.color.toRGBA32(opacity);
+ apply_set = true;
+ } else if(this->stroke && obj->style->stroke.set) {
+ if(obj->style->stroke_opacity.set) {
+ opacity = obj->style->stroke_opacity.value;
+ }
+ apply_color = obj->style->stroke.value.color.toRGBA32(opacity);
+ apply_set = true;
+ }
}
- }
+ }
+ if(apply_set) {
+ this->R = SP_RGBA32_R_F(apply_color);
+ this->G = SP_RGBA32_G_F(apply_color);
+ this->B = SP_RGBA32_B_F(apply_color);
+ this->alpha = SP_RGBA32_A_F(apply_color);
+ } else {
+ // This means that having no selection or some other error
+ // we will default back to normal dropper mode.
+ this->dropping = false;
}
}
@@ -190,10 +227,10 @@ bool DropperTool::root_handler(GdkEvent* event) {
// radius
rw = std::min(Geom::L2(Geom::Point(event->button.x, event->button.y) - this->centre), 400.0);
-
if (rw == 0) { // happens sometimes, little idea why...
break;
}
+ this->radius = rw;
Geom::Point const cd = desktop->w2d(this->centre);
Geom::Affine const w2dt = desktop->w2d();
@@ -242,43 +279,18 @@ bool DropperTool::root_handler(GdkEvent* event) {
}
// remember color
- if(R != this->R || G != this->G || B != this->B || A != this->alpha) {
+ if(!this->dropping && (R != this->R || G != this->G || B != this->B || A != this->alpha)) {
this->R = R;
this->G = G;
this->B = B;
this->alpha = A;
}
-
- // status message
- double alpha_to_set = setalpha? this->alpha : 1.0;
- guint32 c32 = SP_RGBA32_F_COMPOSE(R, G, B, alpha_to_set);
-
- gchar c[64];
- sp_svg_write_color(c, sizeof(c), c32);
-
- // alpha of color under cursor, to show in the statusbar
- // locale-sensitive printf is OK, since this goes to the UI, not into SVG
- gchar *alpha = g_strdup_printf(_(" alpha %.3g"), alpha_to_set);
- // where the color is picked, to show in the statusbar
- gchar *where = this->dragging ? g_strdup_printf(_(", averaged with radius %d"), (int) rw) : g_strdup_printf("%s", _(" under cursor"));
- // message, to show in the statusbar
- const gchar *message = this->dragging ? _("<b>Release mouse</b> to set color.") : _("<b>Click</b> to set fill, <b>Shift+click</b> to set stroke; <b>drag</b> to average color in area; with <b>Alt</b> to pick inverse color; <b>Ctrl+C</b> to copy the color under mouse to clipboard");
-
- this->defaultMessageContext()->setF(
- Inkscape::NORMAL_MESSAGE,
- "<b>%s%s</b>%s. %s", c,
- (pick == SP_DROPPER_PICK_VISIBLE) ? "" : alpha, where, message);
-
- g_free(where);
- g_free(alpha);
-
ret = TRUE;
}
break;
case GDK_BUTTON_RELEASE:
if (event->button.button == 1 && !this->space_panning) {
- double alpha_to_set = setalpha? this->alpha : 1.0;
sp_canvas_item_hide(this->area);
this->dragging = false;
@@ -287,42 +299,37 @@ bool DropperTool::root_handler(GdkEvent* event) {
this->grabbed = NULL;
}
- if(apply) {
+ Inkscape::Selection *selection = desktop->getSelection();
+ g_assert(selection);
+ std::vector<SPItem *> old_selection(selection->items().begin(), selection->items().end());
+ if(this->dropping) {
Geom::Point const button_w(event->button.x, event->button.y);
// remember clicked item, disregarding groups, honoring Alt
this->item_to_select = sp_event_context_find_item (desktop, button_w, event->button.state & GDK_MOD1_MASK, TRUE);
// Change selected object to object under cursor
if (this->item_to_select) {
- Inkscape::Selection *selection = desktop->getSelection();
- g_assert(selection);
+ std::vector<SPItem *> vec(selection->items().begin(), selection->items().end());
selection->set(this->item_to_select);
}
-
- this->R = SP_RGBA32_R_F(apply_color);
- this->G = SP_RGBA32_G_F(apply_color);
- this->B = SP_RGBA32_B_F(apply_color);
- this->alpha = SP_RGBA32_A_F(apply_color);
- alpha_to_set = this->alpha;
-
} else {
if (prefs->getBool("/tools/dropper/onetimepick", false)) {
// "One time" pick from Fill/Stroke dialog stroke page, always apply fill or stroke (ignore <Shift> key)
- fill = (prefs->getInt("/dialogs/fillstroke/page", 0) == 0) ? true : false;
+ //fill = (prefs->getInt("/dialogs/fillstroke/page", 0) == 0) ? true : false;
}
}
// do the actual color setting
- sp_desktop_set_color(desktop,
- (event->button.state & GDK_MOD1_MASK)?
- ColorRGBA(1 - this->R, 1 - this->G, 1 - this->B, alpha_to_set) : ColorRGBA(this->R, this->G, this->B, alpha_to_set),
- false, fill);
+ sp_desktop_set_color(desktop, ColorRGBA(this->get_color(this->invert)), false, !this->stroke);
// REJON: set aux. toolbar input to hex color!
if (!(desktop->getSelection()->isEmpty())) {
DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_DROPPER,
_("Set picked color"));
}
+ if(this->dropping) {
+ selection->setList(old_selection);
+ }
if (prefs->getBool("/tools/dropper/onetimepick", false)) {
prefs->setBool("/tools/dropper/onetimepick", false);
@@ -339,61 +346,48 @@ bool DropperTool::root_handler(GdkEvent* event) {
case GDK_KEY_PRESS:
switch (get_group0_keyval(&event->key)) {
- case GDK_KEY_Up:
- case GDK_KEY_Down:
- case GDK_KEY_KP_Up:
- case GDK_KEY_KP_Down:
+ case GDK_KEY_Up:
+ case GDK_KEY_Down:
+ case GDK_KEY_KP_Up:
+ case GDK_KEY_KP_Down:
// prevent the zoom field from activation
if (!MOD__CTRL_ONLY(event)) {
ret = TRUE;
}
break;
-
- case GDK_KEY_Escape:
+ case GDK_KEY_Escape:
desktop->getSelection()->clear();
- case GDK_KEY_Shift_L:
- case GDK_KEY_Shift_R:
- draw_cursor = DRAW_STROKE_CURSOR;
- break;
- default:
break;
}
break;
-
- case GDK_KEY_RELEASE:
- switch (get_group0_keyval(&event->key)) {
- case GDK_KEY_Shift_L:
- case GDK_KEY_Shift_R:
- draw_cursor = DRAW_FILL_CURSOR;
- break;
-
- default:
- break;
- }
- break;
-
- default:
- break;
}
- if(draw_cursor != DONT_REDRAW_CURSOR && !desktop->isWaitingCursor() && !prefs->getBool("/tools/dropper/onetimepick", false)) {
- GdkCursor *cursor;
- if(apply) {
- if(draw_cursor == DRAW_FILL_CURSOR) {
- cursor = sp_cursor_from_xpm(cursor_dropping_f_xpm, apply_color);
- } else if(draw_cursor == DRAW_STROKE_CURSOR) {
- cursor = sp_cursor_from_xpm(cursor_dropping_s_xpm, apply_color);
- }
- } else {
- if(draw_cursor == DRAW_FILL_CURSOR) {
- cursor = sp_cursor_from_xpm(cursor_dropper_f_xpm, this->get_color());
- } else if(draw_cursor == DRAW_STROKE_CURSOR) {
- cursor = sp_cursor_from_xpm(cursor_dropper_s_xpm, this->get_color());
- }
- }
- GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(desktop->getCanvas()));
- gdk_window_set_cursor(window, cursor);
- }
+ // set the status message to the right text.
+ gchar c[64];
+ sp_svg_write_color(c, sizeof(c), this->get_color(this->invert));
+
+ // alpha of color under cursor, to show in the statusbar
+ // locale-sensitive printf is OK, since this goes to the UI, not into SVG
+ gchar *alpha = g_strdup_printf(_(" alpha %.3g"), this->alpha);
+ // where the color is picked, to show in the statusbar
+ gchar *where = this->dragging ? g_strdup_printf(_(", averaged with radius %d"), (int) this->radius) : g_strdup_printf("%s", _(" under cursor"));
+ // message, to show in the statusbar
+ const gchar *message = this->dragging ? _("<b>Release mouse</b> to set color.") : _("<b>Click</b> to set fill, <b>Shift+click</b> to set stroke; <b>drag</b> to average color in area; with <b>Alt</b> to pick inverse color; <b>Ctrl+C</b> to copy the color under mouse to clipboard");
+
+ this->defaultMessageContext()->setF(
+ Inkscape::NORMAL_MESSAGE,
+ "<b>%s%s</b>%s. %s", c,
+ (pick == SP_DROPPER_PICK_VISIBLE) ? "" : alpha, where, message);
+
+ g_free(where);
+ g_free(alpha);
+
+ // Set the right cursor for the mode and apply the special Fill color
+ auto xpm = (this->dropping ? (this->stroke ? cursor_dropping_s_xpm : cursor_dropping_f_xpm) :
+ (this->stroke ? cursor_dropper_s_xpm : cursor_dropper_f_xpm));
+ GdkCursor *cursor = sp_cursor_from_xpm(xpm, this->get_color(this->invert));
+ GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(desktop->getCanvas()));
+ gdk_window_set_cursor(window, cursor);
if (!ret) {
ret = ToolBase::root_handler(event);