summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJasper van de Gronde <jasper.vandegronde@gmail.com>2010-09-06 09:16:22 +0000
committerJasper van de Gronde <th.v.d.gronde@hccnet.nl>2010-09-06 09:16:22 +0000
commit17fbfe1ce12dd215eb9a8984ff8da0ea4e2416ad (patch)
tree7974c6e7493642ab70ff589bed0bcc71c09d75dc /src
parentmake hpgl document height compatible with dxf (Bug 487052) (diff)
downloadinkscape-17fbfe1ce12dd215eb9a8984ff8da0ea4e2416ad.tar.gz
inkscape-17fbfe1ce12dd215eb9a8984ff8da0ea4e2416ad.zip
Color preview in cursor
(bzr r9743)
Diffstat (limited to 'src')
-rw-r--r--src/arc-context.cpp1
-rw-r--r--src/desktop-style.cpp5
-rw-r--r--src/event-context.cpp46
-rw-r--r--src/event-context.h2
-rw-r--r--src/pixmaps/cursor-ellipse.xpm26
-rw-r--r--src/pixmaps/cursor-rect.xpm26
-rw-r--r--src/pixmaps/cursor-star.xpm34
-rw-r--r--src/rect-context.cpp1
-rw-r--r--src/sp-cursor.cpp83
-rw-r--r--src/sp-cursor.h1
-rw-r--r--src/star-context.cpp1
11 files changed, 170 insertions, 56 deletions
diff --git a/src/arc-context.cpp b/src/arc-context.cpp
index 3c0d9ccda..ddfb8f923 100644
--- a/src/arc-context.cpp
+++ b/src/arc-context.cpp
@@ -107,6 +107,7 @@ static void sp_arc_context_init(SPArcContext *arc_context)
event_context->tolerance = 0;
event_context->within_tolerance = false;
event_context->item_to_select = NULL;
+ event_context->tool_url = "/tools/shapes/arc";
arc_context->item = NULL;
diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp
index 5866b14fb..5615a8ea9 100644
--- a/src/desktop-style.cpp
+++ b/src/desktop-style.cpp
@@ -41,6 +41,7 @@
#include "xml/repr.h"
#include "libnrtype/font-style-to-pos.h"
#include "sp-path.h"
+#include "event-context.h"
#include "desktop-style.h"
#include "svg/svg-icc-color.h"
@@ -195,6 +196,10 @@ sp_desktop_set_style(SPDesktop *desktop, SPCSSAttr *css, bool change, bool write
// 3. If nobody has intercepted the signal, apply the style to the selection
if (!intercepted) {
+ // If we have an event context, update its cursor (TODO: it could be neater to do this with the signal sent above, but what if the signal gets intercepted?)
+ if (desktop->event_context) {
+ sp_event_context_update_cursor(desktop->event_context);
+ }
// Remove text attributes if not text...
// Do this once in case a zillion objects are selected.
diff --git a/src/event-context.cpp b/src/event-context.cpp
index 5d60379c8..56f875844 100644
--- a/src/event-context.cpp
+++ b/src/event-context.cpp
@@ -44,6 +44,7 @@
#include "desktop.h"
#include "desktop-handles.h"
#include "desktop-events.h"
+#include "desktop-style.h"
#include "widgets/desktop-widget.h"
#include "sp-namedview.h"
#include "selection.h"
@@ -62,6 +63,7 @@
#include "ui/tool/control-point.h"
#include "shape-editor.h"
#include "sp-guide.h"
+#include "color.h"
static void sp_event_context_class_init(SPEventContextClass *klass);
static void sp_event_context_init(SPEventContext *event_context);
@@ -141,6 +143,7 @@ static void sp_event_context_init(SPEventContext *event_context) {
event_context->shape_editor = NULL;
event_context->_delayed_snap_event = NULL;
event_context->_dse_callback_in_process = false;
+ event_context->tool_url = NULL;
}
/**
@@ -183,17 +186,38 @@ void sp_event_context_update_cursor(SPEventContext *ec) {
if (w->window) {
/* fixme: */
if (ec->cursor_shape) {
- GdkBitmap *bitmap = NULL;
- GdkBitmap *mask = NULL;
- sp_cursor_bitmap_and_mask_from_xpm(&bitmap, &mask, ec->cursor_shape);
- if ((bitmap != NULL) && (mask != NULL)) {
- if (ec->cursor)
- gdk_cursor_unref(ec->cursor);
- ec->cursor = gdk_cursor_new_from_pixmap(bitmap, mask,
- &w->style->black, &w->style->white, ec->hot_x,
- ec->hot_y);
- g_object_unref(bitmap);
- g_object_unref(mask);
+ GdkDisplay *display = gdk_display_get_default();
+ if (ec->tool_url && gdk_display_supports_cursor_alpha(display) && gdk_display_supports_cursor_color(display)) {
+ bool fillHasColor=false, strokeHasColor=false;
+ guint32 fillColor = sp_desktop_get_color_tool(ec->desktop, ec->tool_url, true, &fillHasColor);
+ guint32 strokeColor = sp_desktop_get_color_tool(ec->desktop, ec->tool_url, false, &strokeHasColor);
+ double fillOpacity = fillHasColor ? sp_desktop_get_opacity_tool(ec->desktop, ec->tool_url, true) : 0;
+ double strokeOpacity = strokeHasColor ? sp_desktop_get_opacity_tool(ec->desktop, ec->tool_url, false) : 0;
+ GdkPixbuf *pixbuf = sp_cursor_pixbuf_from_xpm(
+ ec->cursor_shape,
+ w->style->black, w->style->white,
+ SP_RGBA32_U_COMPOSE(SP_RGBA32_R_U(fillColor),SP_RGBA32_G_U(fillColor),SP_RGBA32_B_U(fillColor),SP_COLOR_F_TO_U(fillOpacity)),
+ SP_RGBA32_U_COMPOSE(SP_RGBA32_R_U(strokeColor),SP_RGBA32_G_U(strokeColor),SP_RGBA32_B_U(strokeColor),SP_COLOR_F_TO_U(strokeOpacity))
+ );
+ if (pixbuf != NULL) {
+ if (ec->cursor)
+ gdk_cursor_unref(ec->cursor);
+ ec->cursor = gdk_cursor_new_from_pixbuf(display, pixbuf, ec->hot_x, ec->hot_y);
+ g_object_unref(pixbuf);
+ }
+ } else {
+ GdkBitmap *bitmap = NULL;
+ GdkBitmap *mask = NULL;
+ sp_cursor_bitmap_and_mask_from_xpm(&bitmap, &mask, ec->cursor_shape);
+ if ((bitmap != NULL) && (mask != NULL)) {
+ if (ec->cursor)
+ gdk_cursor_unref(ec->cursor);
+ ec->cursor = gdk_cursor_new_from_pixmap(bitmap, mask,
+ &w->style->black, &w->style->white, ec->hot_x,
+ ec->hot_y);
+ g_object_unref(bitmap);
+ g_object_unref(mask);
+ }
}
}
gdk_window_set_cursor(w->window, ec->cursor);
diff --git a/src/event-context.h b/src/event-context.h
index 76c74e26c..fc22762fd 100644
--- a/src/event-context.h
+++ b/src/event-context.h
@@ -128,6 +128,8 @@ struct SPEventContext : public GObject {
DelayedSnapEvent *_delayed_snap_event;
bool _dse_callback_in_process;
+
+ char const * tool_url; ///< the (preferences) url for the tool (if a subclass corresponding to a tool is used)
};
/**
diff --git a/src/pixmaps/cursor-ellipse.xpm b/src/pixmaps/cursor-ellipse.xpm
index 7a230bd55..b0f20d18c 100644
--- a/src/pixmaps/cursor-ellipse.xpm
+++ b/src/pixmaps/cursor-ellipse.xpm
@@ -1,8 +1,10 @@
/* XPM */
static char const *cursor_ellipse_xpm[] = {
-"32 32 3 1",
+"32 32 5 1",
" c None",
". c #FFFFFF",
+"% c Stroke",
+"* c Fill",
"+ c #000000",
" ... ",
" .+. ",
@@ -12,17 +14,17 @@ static char const *cursor_ellipse_xpm[] = {
"....+.... ",
" .+. ",
" .+. ....... ",
-" ... ....+++++.... ",
-" ..+++.....+++.. ",
-" ..+...........+.. ",
-" ..+.............+.. ",
-" .+...............+. ",
-" .+...............+. ",
-" .+...............+. ",
-" ..+.............+.. ",
-" ..+...........+.. ",
-" ..+++.....+++.. ",
-" ....+++++.... ",
+" ... ....%%%%%.... ",
+" ..%%%*****%%%.. ",
+" ..%***********%.. ",
+" ..%*************%.. ",
+" .%***************%. ",
+" .%***************%. ",
+" .%***************%. ",
+" ..%*************%.. ",
+" ..%***********%.. ",
+" ..%%%*****%%%.. ",
+" ....%%%%%.... ",
" ....... ",
" ",
" ",
diff --git a/src/pixmaps/cursor-rect.xpm b/src/pixmaps/cursor-rect.xpm
index 149624aa7..69007bc77 100644
--- a/src/pixmaps/cursor-rect.xpm
+++ b/src/pixmaps/cursor-rect.xpm
@@ -1,8 +1,10 @@
/* XPM */
static char const *cursor_rect_xpm[] = {
-"32 32 3 1",
+"32 32 5 1",
" c None",
". c #FFFFFF",
+"% c Stroke",
+"* c Fill",
"+ c #000000",
" ... ",
" .+. ",
@@ -12,17 +14,17 @@ static char const *cursor_rect_xpm[] = {
"....+.... ",
" .+. ",
" .+. ................. ",
-" ... .+++++++++++++++. ",
-" .+.............+. ",
-" .+.............+. ",
-" .+.............+. ",
-" .+.............+. ",
-" .+.............+. ",
-" .+.............+. ",
-" .+.............+. ",
-" .+.............+. ",
-" .+.............+. ",
-" .+++++++++++++++. ",
+" ... .%%%%%%%%%%%%%%%. ",
+" .%*************%. ",
+" .%*************%. ",
+" .%*************%. ",
+" .%*************%. ",
+" .%*************%. ",
+" .%*************%. ",
+" .%*************%. ",
+" .%*************%. ",
+" .%*************%. ",
+" .%%%%%%%%%%%%%%%. ",
" ................. ",
" ",
" ",
diff --git a/src/pixmaps/cursor-star.xpm b/src/pixmaps/cursor-star.xpm
index 80d312ace..eedf448e4 100644
--- a/src/pixmaps/cursor-star.xpm
+++ b/src/pixmaps/cursor-star.xpm
@@ -1,8 +1,10 @@
/* XPM */
static char const *cursor_star_xpm[] = {
-"32 32 3 1",
+"32 32 5 1",
" c None",
". c #FFFFFF",
+"% c Stroke",
+"* c Fill",
"+ c #000000",
" ... ",
" .+. ",
@@ -10,21 +12,21 @@ static char const *cursor_star_xpm[] = {
"....+.... ",
".+++ +++. ",
"....+.... .. ",
-" .+. .++. ",
-" .+. .++. ",
-" ... .++. ",
-" .+..+. ",
-" ........+..+........ ",
-" .++++++....++++++. ",
-" .++..........++. ",
-" ..++......++.. ",
-" .+......+. ",
-" .+......+. ",
-" .+...++...+. ",
-" .+.++..++.+. ",
-" .+.+.. ..+.+. ",
-" .++. .++. ",
-" .+. .+. ",
+" .+. .%%. ",
+" .+. .%%. ",
+" ... .%%. ",
+" .%**%* ",
+" ........%**%........ ",
+" .%%%%%%****%%%%%%. ",
+" .%%**********%%. ",
+" ..%%******%%.. ",
+" .%******%. ",
+" .%******%. ",
+" .%***%%***%. ",
+" .%*%%..%%*%. ",
+" .%*%.. ..%*%. ",
+" .%%. .%%. ",
+" .%. .%. ",
" .. .. ",
" ",
" ",
diff --git a/src/rect-context.cpp b/src/rect-context.cpp
index d60a6630b..81f615571 100644
--- a/src/rect-context.cpp
+++ b/src/rect-context.cpp
@@ -110,6 +110,7 @@ static void sp_rect_context_init(SPRectContext *rect_context)
event_context->tolerance = 0;
event_context->within_tolerance = false;
event_context->item_to_select = NULL;
+ event_context->tool_url = "/tools/shapes/rect";
rect_context->item = NULL;
diff --git a/src/sp-cursor.cpp b/src/sp-cursor.cpp
index 4bbba5f10..5ec80c9f6 100644
--- a/src/sp-cursor.cpp
+++ b/src/sp-cursor.cpp
@@ -16,6 +16,8 @@
#include <cstring>
#include <string>
#include <ctype.h>
+#include <map>
+#include "color.h"
#include "sp-cursor.h"
void
@@ -32,7 +34,7 @@ sp_cursor_bitmap_and_mask_from_xpm(GdkBitmap **bitmap, GdkBitmap **mask, gchar c
g_return_if_fail (colors >= 3);
int transparent_color = ' ';
- int black_color = '.';
+ std::string black_colors;
char pixmap_buffer[(32 * 32)/8];
char mask_buffer[(32 * 32)/8];
@@ -51,12 +53,16 @@ sp_cursor_bitmap_and_mask_from_xpm(GdkBitmap **bitmap, GdkBitmap **mask, gchar c
p++;
}
- if (strcmp(p, "None") == 0) {
+ if (strcmp(p, "None") == 0) {
transparent_color = ccode;
}
+ if (strcmp(p, "Stroke") == 0) {
+ black_colors.push_back(ccode);
+ }
+
if (strcmp(p, "#000000") == 0) {
- black_color = ccode;
+ black_colors.push_back(ccode);
}
}
@@ -67,10 +73,10 @@ sp_cursor_bitmap_and_mask_from_xpm(GdkBitmap **bitmap, GdkBitmap **mask, gchar c
char maskv = 0;
for (int pix = 0; pix < 8; pix++, x++){
- if (xpm[4+y][x] != transparent_color) {
+ if (xpm[1+colors+y][x] != transparent_color) {
maskv |= 1 << pix;
- if (xpm[4+y][x] == black_color) {
+ if (black_colors.find(xpm[1+colors+y][x]) != std::string::npos) {
value |= 1 << pix;
}
}
@@ -85,6 +91,73 @@ sp_cursor_bitmap_and_mask_from_xpm(GdkBitmap **bitmap, GdkBitmap **mask, gchar c
*mask = gdk_bitmap_create_from_data(NULL, mask_buffer, 32, 32);
}
+static void free_cursor_data(guchar *pixels, gpointer data) {
+ delete [] reinterpret_cast<guint32*>(pixels);
+}
+
+struct RGBA {
+ guchar v[4];
+ RGBA() { v[0] = 0; v[1] = 0; v[2] = 0; v[3] = 0; }
+ RGBA(guchar r, guchar g, guchar b, guchar a) { v[0] = r; v[1] = g; v[2] = b; v[3] = a; }
+ operator guint32 const () const { return *reinterpret_cast<guint32 const *>(v); }
+};
+
+GdkPixbuf*
+sp_cursor_pixbuf_from_xpm(gchar const *const *xpm, GdkColor const& black, GdkColor const& white, guint32 fill, guint32 stroke)
+{
+ int height;
+ int width;
+ int colors;
+ int pix;
+ sscanf(xpm[0], "%d %d %d %d", &height, &width, &colors, &pix);
+
+ //g_return_if_fail (height == 32);
+ //g_return_if_fail (width == 32);
+ //g_return_if_fail (colors >= 3);
+
+ std::map<char,RGBA> colorMap;
+
+ for (int i = 0; i < colors; i++) {
+
+ char const *p = xpm[1 + i];
+ char const ccode = *p;
+
+ p++;
+ while (isspace(*p)) {
+ p++;
+ }
+ p++;
+ while (isspace(*p)) {
+ p++;
+ }
+
+ if (strcmp(p, "None") == 0) {
+ colorMap.insert(std::make_pair(ccode, RGBA()));
+ } else if (strcmp(p, "Fill") == 0) {
+ colorMap.insert(std::make_pair(ccode, RGBA(SP_RGBA32_R_U(fill),SP_RGBA32_G_U(fill),SP_RGBA32_B_U(fill),SP_RGBA32_A_U(fill))));
+ } else if (strcmp(p, "Stroke") == 0) {
+ colorMap.insert(std::make_pair(ccode, RGBA(SP_RGBA32_R_U(stroke),SP_RGBA32_G_U(stroke),SP_RGBA32_B_U(stroke),SP_RGBA32_A_U(stroke))));
+ } else if (strcmp(p, "#000000") == 0) {
+ colorMap.insert(std::make_pair(ccode, RGBA(black.red,black.green,black.blue,255)));
+ } else if (strcmp(p, "#FFFFFF") == 0) {
+ colorMap.insert(std::make_pair(ccode, RGBA(white.red,white.green,white.blue,255)));
+ } else {
+ colorMap.insert(std::make_pair(ccode, RGBA()));
+ }
+ }
+
+ guint32 *pixmap_buffer = new guint32[width * height];
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ std::map<char,RGBA>::const_iterator it = colorMap.find(xpm[1+colors+y][x]);
+ pixmap_buffer[y * width + x] = it==colorMap.end() ? 0u : it->second;
+ }
+ }
+
+ return gdk_pixbuf_new_from_data(reinterpret_cast<guchar*>(pixmap_buffer), GDK_COLORSPACE_RGB, TRUE, 8, width, height, width*sizeof(guint32), free_cursor_data, NULL);
+}
+
GdkCursor *
sp_cursor_new_from_xpm(gchar const *const *xpm, gint hot_x, gint hot_y)
{
diff --git a/src/sp-cursor.h b/src/sp-cursor.h
index 1c40bdc44..4ab90d169 100644
--- a/src/sp-cursor.h
+++ b/src/sp-cursor.h
@@ -4,6 +4,7 @@
#include <gdk/gdk.h>
void sp_cursor_bitmap_and_mask_from_xpm(GdkBitmap **bitmap, GdkBitmap **mask, gchar const *const *xpm);
+GdkPixbuf* sp_cursor_pixbuf_from_xpm(gchar const *const *xpm, GdkColor const& black, GdkColor const& white, guint32 fill, guint32 stroke);
GdkCursor *sp_cursor_new_from_xpm(gchar const *const *xpm, gint hot_x, gint hot_y);
#endif
diff --git a/src/star-context.cpp b/src/star-context.cpp
index 9a2a67a57..603865ce1 100644
--- a/src/star-context.cpp
+++ b/src/star-context.cpp
@@ -111,6 +111,7 @@ sp_star_context_init (SPStarContext * star_context)
event_context->tolerance = 0;
event_context->within_tolerance = false;
event_context->item_to_select = NULL;
+ event_context->tool_url = "/tools/shapes/star";
star_context->item = NULL;