comparison src/xs_curve.c @ 908:8b4c016802ea

Cosmetics.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 10 Nov 2012 11:58:59 +0200
parents 9321ffa2ea7e
children 79f20427c99d
comparison
equal deleted inserted replaced
907:cc2789a06d44 908:8b4c016802ea
31 #include <gtk/gtkdrawingarea.h> 31 #include <gtk/gtkdrawingarea.h>
32 #include <gtk/gtkmain.h> 32 #include <gtk/gtkmain.h>
33 #include <gtk/gtksignal.h> 33 #include <gtk/gtksignal.h>
34 34
35 35
36 #define RADIUS 3 /* radius of the control points */ 36 #define CP_RADIUS 3 /* radius of the control points */
37 #define RADIUS2 (RADIUS * 2) 37 #define CP_RADIUS2 (CP_RADIUS * 2)
38 #define MIN_DISTANCE 7 /* min distance between control points */ 38 #define CP_MIN_DISTANCE 7 /* min distance between control points */
39 39
40 40
41 #define GRAPH_MASK (GDK_EXPOSURE_MASK | \ 41 #define GRAPH_MASK ( \
42 GDK_POINTER_MOTION_MASK | \ 42 GDK_EXPOSURE_MASK | \
43 GDK_POINTER_MOTION_HINT_MASK | \ 43 GDK_POINTER_MOTION_MASK | \
44 GDK_ENTER_NOTIFY_MASK | \ 44 GDK_POINTER_MOTION_HINT_MASK | \
45 GDK_BUTTON_PRESS_MASK | \ 45 GDK_ENTER_NOTIFY_MASK | \
46 GDK_BUTTON_RELEASE_MASK | \ 46 GDK_BUTTON_PRESS_MASK | \
47 GDK_BUTTON1_MOTION_MASK) 47 GDK_BUTTON_RELEASE_MASK | \
48 GDK_BUTTON1_MOTION_MASK)
48 49
49 #define GET_X(i) curve->ctlpoints[i].x 50 #define GET_X(i) curve->ctlpoints[i].x
50 #define GET_Y(i) curve->ctlpoints[i].y 51 #define GET_Y(i) curve->ctlpoints[i].y
51 52
52 53
71 72
72 GtkType xs_curve_get_type(void) 73 GtkType xs_curve_get_type(void)
73 { 74 {
74 static GtkType curve_type = 0; 75 static GtkType curve_type = 0;
75 76
76 if (!curve_type) { 77 if (!curve_type)
77 static const GtkTypeInfo curve_info = { 78 {
79 static const GtkTypeInfo curve_info =
80 {
78 "XSCurve", 81 "XSCurve",
79 sizeof(XSCurve), 82 sizeof(XSCurve),
80 sizeof(XSCurveClass), 83 sizeof(XSCurveClass),
81 (GtkClassInitFunc) xs_curve_class_init, 84 (GtkClassInitFunc) xs_curve_class_init,
82 (GtkObjectInitFunc) xs_curve_init, 85 (GtkObjectInitFunc) xs_curve_init,
134 137
135 static void xs_curve_set_arg(GtkObject *object, GtkArg *arg, guint arg_id) 138 static void xs_curve_set_arg(GtkObject *object, GtkArg *arg, guint arg_id)
136 { 139 {
137 XSCurve *curve = XS_CURVE(object); 140 XSCurve *curve = XS_CURVE(object);
138 141
139 switch (arg_id) { 142 switch (arg_id)
140 case ARG_MIN_X: 143 {
141 xs_curve_set_range(curve, GTK_VALUE_FLOAT(*arg), curve->max_x, curve->min_y, curve->max_y); 144 case ARG_MIN_X:
142 break; 145 xs_curve_set_range(curve, GTK_VALUE_FLOAT(*arg), curve->max_x, curve->min_y, curve->max_y);
143 case ARG_MAX_X: 146 break;
144 xs_curve_set_range(curve, curve->min_x, GTK_VALUE_FLOAT(*arg), curve->min_y, curve->max_y); 147 case ARG_MAX_X:
145 break; 148 xs_curve_set_range(curve, curve->min_x, GTK_VALUE_FLOAT(*arg), curve->min_y, curve->max_y);
146 case ARG_MIN_Y: 149 break;
147 xs_curve_set_range(curve, curve->min_x, curve->max_x, GTK_VALUE_FLOAT(*arg), curve->max_y); 150 case ARG_MIN_Y:
148 break; 151 xs_curve_set_range(curve, curve->min_x, curve->max_x, GTK_VALUE_FLOAT(*arg), curve->max_y);
149 case ARG_MAX_Y: 152 break;
150 xs_curve_set_range(curve, curve->min_x, curve->max_x, curve->min_y, GTK_VALUE_FLOAT(*arg)); 153 case ARG_MAX_Y:
151 break; 154 xs_curve_set_range(curve, curve->min_x, curve->max_x, curve->min_y, GTK_VALUE_FLOAT(*arg));
155 break;
152 } 156 }
153 } 157 }
154 158
155 159
156 static void xs_curve_get_arg(GtkObject *object, GtkArg *arg, guint arg_id) 160 static void xs_curve_get_arg(GtkObject *object, GtkArg *arg, guint arg_id)
157 { 161 {
158 XSCurve *curve = XS_CURVE(object); 162 XSCurve *curve = XS_CURVE(object);
159 163
160 switch (arg_id) { 164 switch (arg_id)
161 case ARG_MIN_X: 165 {
162 GTK_VALUE_FLOAT(*arg) = curve->min_x; 166 case ARG_MIN_X:
163 break; 167 GTK_VALUE_FLOAT(*arg) = curve->min_x;
164 case ARG_MAX_X: 168 break;
165 GTK_VALUE_FLOAT(*arg) = curve->max_x; 169 case ARG_MAX_X:
166 break; 170 GTK_VALUE_FLOAT(*arg) = curve->max_x;
167 case ARG_MIN_Y: 171 break;
168 GTK_VALUE_FLOAT(*arg) = curve->min_y; 172 case ARG_MIN_Y:
169 break; 173 GTK_VALUE_FLOAT(*arg) = curve->min_y;
170 case ARG_MAX_Y: 174 break;
171 GTK_VALUE_FLOAT(*arg) = curve->max_y; 175 case ARG_MAX_Y:
172 break; 176 GTK_VALUE_FLOAT(*arg) = curve->max_y;
173 default: 177 break;
174 arg->type = GTK_TYPE_INVALID; 178 default:
175 break; 179 arg->type = GTK_TYPE_INVALID;
180 break;
176 } 181 }
177 } 182 }
178 183
179 184
180 static int xs_project(gfloat value, gfloat min, gfloat max, int norm) 185 static int xs_project(gfloat value, gfloat min, gfloat max, int norm)
224 /* Clear the pixmap */ 229 /* Clear the pixmap */
225 gtk_paint_flat_box(style, curve->pixmap, 230 gtk_paint_flat_box(style, curve->pixmap,
226 GTK_STATE_NORMAL, GTK_SHADOW_NONE, 231 GTK_STATE_NORMAL, GTK_SHADOW_NONE,
227 NULL, GTK_WIDGET(curve), "curve_bg", 232 NULL, GTK_WIDGET(curve), "curve_bg",
228 0, 0, 233 0, 0,
229 width + RADIUS2, 234 width + CP_RADIUS2,
230 height + RADIUS2); 235 height + CP_RADIUS2);
231 236
232 237
233 /* Draw the grid */ 238 /* Draw the grid */
234 for (i = 0; i < 5; i++) { 239 for (i = 0; i < 5; i++)
240 {
235 gdk_draw_line(curve->pixmap, style->dark_gc[state], 241 gdk_draw_line(curve->pixmap, style->dark_gc[state],
236 RADIUS, i * (height / 4.0) + RADIUS, 242 CP_RADIUS, i * (height / 4.0) + CP_RADIUS,
237 width + RADIUS, i * (height / 4.0) + RADIUS); 243 width + CP_RADIUS, i * (height / 4.0) + CP_RADIUS);
238 244
239 gdk_draw_line(curve->pixmap, style->dark_gc[state], 245 gdk_draw_line(curve->pixmap, style->dark_gc[state],
240 i * (width / 4.0) + RADIUS, RADIUS, 246 i * (width / 4.0) + CP_RADIUS, CP_RADIUS,
241 i * (width / 4.0) + RADIUS, height + RADIUS); 247 i * (width / 4.0) + CP_RADIUS, height + CP_RADIUS);
242 } 248 }
243 249
244 #if 1 250 #if 1
245 /* Draw the spline/curve itself */ 251 /* Draw the spline/curve itself */
246 p0 = curve->ctlpoints; 252 p0 = curve->ctlpoints;
248 p2 = p1; p2++; 254 p2 = p1; p2++;
249 p3 = p2; p3++; 255 p3 = p2; p3++;
250 256
251 /* Draw each curve segment */ 257 /* Draw each curve segment */
252 if (curve->nctlpoints > 5) 258 if (curve->nctlpoints > 5)
253 for (i = 0; i < curve->nctlpoints; i++, ++p0, ++p1, ++p2, ++p3) { 259 for (i = 0; i < curve->nctlpoints; i++, ++p0, ++p1, ++p2, ++p3)
260 {
254 gint n; 261 gint n;
255 gfloat k1, k2, a, b, c, d, x; 262 gfloat k1, k2, a, b, c, d, x;
256 263
257 if (p1->x == p2->x) 264 if (p1->x == p2->x)
258 continue; 265 continue;
259 266
260 if (p0->x == p1->x && p2->x == p3->x) { 267 if (p0->x == p1->x && p2->x == p3->x)
268 {
261 k1 = k2 = (p2->y - p1->y) / (p2->x - p1->x); 269 k1 = k2 = (p2->y - p1->y) / (p2->x - p1->x);
262 } else if (p0->x == p1->x) { 270 }
271 else if (p0->x == p1->x)
272 {
263 k2 = (p3->y - p1->y) / (p3->x - p1->x); 273 k2 = (p3->y - p1->y) / (p3->x - p1->x);
264 k1 = (3 * (p2->y - p1->y) / (p2->x - p1->x) - k2) / 2; 274 k1 = (3 * (p2->y - p1->y) / (p2->x - p1->x) - k2) / 2;
265 } else if (p2->x == p3->x) { 275 }
276 else if (p2->x == p3->x)
277 {
266 k1 = (p2->y - p0->y) / (p2->x - p0->x); 278 k1 = (p2->y - p0->y) / (p2->x - p0->x);
267 k2 = (3 * (p2->y - p1->y) / (p2->x - p1->x) - k1) / 2; 279 k2 = (3 * (p2->y - p1->y) / (p2->x - p1->x) - k1) / 2;
268 } else { 280 }
281 else
282 {
269 k1 = (p2->y - p0->y) / (p2->x - p0->x); 283 k1 = (p2->y - p0->y) / (p2->x - p0->x);
270 k2 = (p3->y - p1->y) / (p3->x - p1->x); 284 k2 = (p3->y - p1->y) / (p3->x - p1->x);
271 } 285 }
272 286
273 xs_cubic_coeff(p1->x, p1->y, p2->x, p2->y, k1, k2, &a, &b, &c, &d); 287 xs_cubic_coeff(p1->x, p1->y, p2->x, p2->y, k1, k2, &a, &b, &c, &d);
274 288
275 for (x = p1->x; x <= p2->x; x += res, n++) { 289 for (x = p1->x; x <= p2->x; x += res, n++)
290 {
276 gfloat y = ((a * x + b) * x + c) * x + d; 291 gfloat y = ((a * x + b) * x + c) * x + d;
277 gint qx, qy; 292 gint qx, qy;
278 qx = RADIUS + xs_project(x, curve->min_x, curve->max_x, width); 293 qx = CP_RADIUS + xs_project(x, curve->min_x, curve->max_x, width);
279 qy = RADIUS + xs_project(y, curve->min_y, curve->max_y, height); 294 qy = CP_RADIUS + xs_project(y, curve->min_y, curve->max_y, height);
280 295
281 if (ox != -1) { 296 if (ox != -1)
297 {
282 gdk_draw_line(curve->pixmap, style->fg_gc[state], 298 gdk_draw_line(curve->pixmap, style->fg_gc[state],
283 ox, oy, qx, qy); 299 ox, oy, qx, qy);
284 } 300 }
285 ox = qx; oy = qy; 301 ox = qx; oy = qy;
286 } 302 }
287 } 303 }
288 304
289 #endif 305 #endif
290 306
291 /* Draw control points */ 307 /* Draw control points */
292 for (i = 0; i < curve->nctlpoints; ++i) { 308 for (i = 0; i < curve->nctlpoints; ++i)
309 {
293 gint x, y; 310 gint x, y;
294 GtkStateType cstate; 311 GtkStateType cstate;
295 312
296 if (GET_X(i) < curve->min_x || GET_Y(i) < curve->min_y || 313 if (GET_X(i) < curve->min_x || GET_Y(i) < curve->min_y ||
297 GET_X(i) >= curve->max_x || GET_Y(i) >= curve->max_y) 314 GET_X(i) >= curve->max_x || GET_Y(i) >= curve->max_y)
298 continue; 315 continue;
299 316
300 x = xs_project(GET_X(i), curve->min_x, curve->max_x, width); 317 x = xs_project(GET_X(i), curve->min_x, curve->max_x, width);
301 y = xs_project(GET_Y(i), curve->min_y, curve->max_y, height); 318 y = xs_project(GET_Y(i), curve->min_y, curve->max_y, height);
302 319
303 if (i == curve->grab_point) { 320 if (i == curve->grab_point)
321 {
304 cstate = GTK_STATE_SELECTED; 322 cstate = GTK_STATE_SELECTED;
305 gdk_draw_line(curve->pixmap, style->fg_gc[cstate], 323 gdk_draw_line(curve->pixmap, style->fg_gc[cstate],
306 x + RADIUS, RADIUS, x + RADIUS, height + RADIUS); 324 x + CP_RADIUS, CP_RADIUS, x + CP_RADIUS, height + CP_RADIUS);
307 gdk_draw_line(curve->pixmap, style->fg_gc[cstate], 325 gdk_draw_line(curve->pixmap, style->fg_gc[cstate],
308 RADIUS, y + RADIUS, width + RADIUS, y + RADIUS); 326 CP_RADIUS, y + CP_RADIUS, width + CP_RADIUS, y + CP_RADIUS);
309 } else 327 } else
310 cstate = state; 328 cstate = state;
311 329
312 gdk_draw_arc(curve->pixmap, style->fg_gc[cstate], TRUE, 330 gdk_draw_arc(curve->pixmap, style->fg_gc[cstate], TRUE,
313 x, y, RADIUS2, RADIUS2, 0, 360 * 64); 331 x, y, CP_RADIUS2, CP_RADIUS2, 0, 360 * 64);
314 } 332 }
315 333
316 /* Draw pixmap in the widget */ 334 /* Draw pixmap in the widget */
317 gdk_draw_pixmap(GTK_WIDGET(curve)->window, 335 gdk_draw_pixmap(GTK_WIDGET(curve)->window,
318 style->fg_gc[state], curve->pixmap, 336 style->fg_gc[state], curve->pixmap,
319 0, 0, 0, 0, 337 0, 0, 0, 0,
320 width + RADIUS2, 338 width + CP_RADIUS2,
321 height + RADIUS2); 339 height + CP_RADIUS2);
322 } 340 }
323 341
324 342
325 static gint xs_curve_graph_events(GtkWidget *widget, GdkEvent *event, XSCurve *curve) 343 static gint xs_curve_graph_events(GtkWidget *widget, GdkEvent *event, XSCurve *curve)
326 { 344 {
329 GtkWidget *w; 347 GtkWidget *w;
330 gint i, width, height, x, y, tx, ty, cx, closest_point = 0, min_x; 348 gint i, width, height, x, y, tx, ty, cx, closest_point = 0, min_x;
331 guint distance; 349 guint distance;
332 350
333 w = GTK_WIDGET(curve); 351 w = GTK_WIDGET(curve);
334 width = w->allocation.width - RADIUS2; 352 width = w->allocation.width - CP_RADIUS2;
335 height = w->allocation.height - RADIUS2; 353 height = w->allocation.height - CP_RADIUS2;
336 354
337 if ((width < 0) || (height < 0)) 355 if ((width < 0) || (height < 0))
338 return FALSE; 356 return FALSE;
339 357
340 /* get the pointer position */ 358 /* get the pointer position */
341 gdk_window_get_pointer(w->window, &tx, &ty, NULL); 359 gdk_window_get_pointer(w->window, &tx, &ty, NULL);
342 x = CLAMP((tx - RADIUS), 0, width - 1); 360 x = CLAMP((tx - CP_RADIUS), 0, width - 1);
343 y = CLAMP((ty - RADIUS), 0, height - 1); 361 y = CLAMP((ty - CP_RADIUS), 0, height - 1);
344 min_x = curve->min_x; 362 min_x = curve->min_x;
345 363
346 distance = ~0U; 364 distance = ~0U;
347 for (i = 0; i < curve->nctlpoints; ++i) { 365 for (i = 0; i < curve->nctlpoints; ++i)
366 {
348 cx = xs_project(GET_X(i), min_x, curve->max_x, width); 367 cx = xs_project(GET_X(i), min_x, curve->max_x, width);
349 if ((guint) abs(x - cx) < distance) { 368 if ((guint) abs(x - cx) < distance)
369 {
350 distance = abs(x - cx); 370 distance = abs(x - cx);
351 closest_point = i; 371 closest_point = i;
352 } 372 }
353 } 373 }
354 374
355 /* Act based on event type */ 375 /* Act based on event type */
356 switch (event->type) { 376 switch (event->type)
357 case GDK_CONFIGURE: 377 {
358 if (curve->pixmap) 378 case GDK_CONFIGURE:
359 gdk_pixmap_unref(curve->pixmap); 379 if (curve->pixmap)
360 curve->pixmap = 0; 380 gdk_pixmap_unref(curve->pixmap);
361 381 curve->pixmap = 0;
362 /* fall through */ 382
363 383 /* fall through */
364 case GDK_EXPOSE: 384
365 if (!curve->pixmap) { 385 case GDK_EXPOSE:
366 curve->pixmap = gdk_pixmap_new(w->window, 386 if (!curve->pixmap)
367 w->allocation.width, w->allocation.height, -1); 387 {
368 } 388 curve->pixmap = gdk_pixmap_new(w->window,
369 xs_curve_draw(curve, width, height); 389 w->allocation.width, w->allocation.height, -1);
370 break; 390 }
371 391 xs_curve_draw(curve, width, height);
372 case GDK_BUTTON_PRESS: 392 break;
373 gtk_grab_add(widget); 393
374 394 case GDK_BUTTON_PRESS:
375 bevent = (GdkEventButton *) event; 395 gtk_grab_add(widget);
376 new_type = GDK_TCROSS; 396
377 397 bevent = (GdkEventButton *) event;
378 if (distance > MIN_DISTANCE) { 398 new_type = GDK_TCROSS;
379 /* insert a new control point */ 399
380 if (curve->nctlpoints > 0) { 400 if (distance > CP_MIN_DISTANCE)
381 cx = xs_project(GET_X(closest_point), min_x, curve->max_x, width); 401 {
382 if (x > cx) closest_point++; 402 /* insert a new control point */
403 if (curve->nctlpoints > 0)
404 {
405 cx = xs_project(GET_X(closest_point), min_x, curve->max_x, width);
406 if (x > cx) closest_point++;
407 }
408
409 curve->nctlpoints++;
410
411 curve->ctlpoints = g_realloc(curve->ctlpoints,
412 curve->nctlpoints * sizeof(*curve->ctlpoints));
413
414 for (i = curve->nctlpoints - 1; i > closest_point; --i)
415 {
416 memcpy(curve->ctlpoints + i,
417 curve->ctlpoints + i - 1,
418 sizeof(*curve->ctlpoints));
419 }
383 } 420 }
384 421
385 curve->nctlpoints++; 422 curve->grab_point = closest_point;
423 GET_X(curve->grab_point) = xs_unproject(x, min_x, curve->max_x, width);
424 GET_Y(curve->grab_point) = xs_unproject(y, curve->min_y, curve->max_y, height);
425
426 xs_curve_draw(curve, width, height);
427 break;
428
429 case GDK_BUTTON_RELEASE:
430 {
431 gint src, dst;
386 432
387 curve->ctlpoints = g_realloc(curve->ctlpoints, 433 gtk_grab_remove(widget);
388 curve->nctlpoints * sizeof(*curve->ctlpoints)); 434
435 /* delete inactive points: */
436 for (src = dst = 0; src < curve->nctlpoints; ++src)
437 {
438 if (GET_X(src) >= min_x)
439 {
440 memcpy(curve->ctlpoints + dst,
441 curve->ctlpoints + src,
442 sizeof(*curve->ctlpoints));
443 dst++;
444 }
445 }
446
447 if (dst < src)
448 {
449 curve->nctlpoints -= (src - dst);
450 if (curve->nctlpoints <= 0)
451 {
452 curve->nctlpoints = 1;
453 GET_X(0) = min_x;
454 GET_Y(0) = curve->min_y;
455 xs_curve_draw(curve, width, height);
456 }
457 curve->ctlpoints = g_realloc(curve->ctlpoints,
458 curve->nctlpoints * sizeof(*curve->ctlpoints));
459 }
460
461 new_type = GDK_FLEUR;
462 curve->grab_point = -1;
463 }
464 xs_curve_draw(curve, width, height);
465 break;
466
467 case GDK_MOTION_NOTIFY:
468 if (curve->grab_point == -1)
469 {
470 /* if no point is grabbed... */
471 if (distance <= CP_MIN_DISTANCE)
472 new_type = GDK_FLEUR;
473 else
474 new_type = GDK_TCROSS;
475 } else {
476 gint leftbound, rightbound;
477
478 /* drag the grabbed point */
479 new_type = GDK_TCROSS;
480
481 leftbound = -CP_MIN_DISTANCE;
482 if (curve->grab_point > 0)
483 {
484 leftbound = xs_project(
485 GET_X(curve->grab_point-1),
486 min_x, curve->max_x, width);
487 }
488
489 rightbound = width + CP_RADIUS2 + CP_MIN_DISTANCE;
490 if (curve->grab_point + 1 < curve->nctlpoints)
491 {
492 rightbound = xs_project(
493 GET_X(curve->grab_point+1),
494 min_x, curve->max_x, width);
495 }
496
497 if ((tx <= leftbound) || (tx >= rightbound) ||
498 (ty > height + CP_RADIUS2 + CP_MIN_DISTANCE) || (ty < -CP_MIN_DISTANCE)) {
499 GET_X(curve->grab_point) = min_x - 1.0;
500 }
501 else
502 {
503 GET_X(curve->grab_point) =
504 xs_unproject(x, min_x, curve->max_x, width);
505 GET_Y(curve->grab_point) =
506 xs_unproject(y, curve->min_y, curve->max_y, height);
507 }
508
509 xs_curve_draw(curve, width, height);
510 }
389 511
390 for (i = curve->nctlpoints - 1; i > closest_point; --i) { 512 /* See if cursor type was changed and update accordingly */
391 memcpy(curve->ctlpoints + i, 513 if (new_type != (GdkCursorType) curve->cursor_type)
392 curve->ctlpoints + i - 1, 514 {
393 sizeof(*curve->ctlpoints)); 515 GdkCursor *cursor;
394 } 516 curve->cursor_type = new_type;
395 } 517 cursor = gdk_cursor_new(curve->cursor_type);
396 518 gdk_window_set_cursor(w->window, cursor);
397 curve->grab_point = closest_point; 519 gdk_cursor_destroy(cursor);
398 GET_X(curve->grab_point) = xs_unproject(x, min_x, curve->max_x, width); 520 }
399 GET_Y(curve->grab_point) = xs_unproject(y, curve->min_y, curve->max_y, height); 521 break;
400 522
401 xs_curve_draw(curve, width, height); 523 default:
402 break; 524 break;
403
404 case GDK_BUTTON_RELEASE:
405 {
406 gint src, dst;
407
408 gtk_grab_remove(widget);
409
410 /* delete inactive points: */
411 for (src = dst = 0; src < curve->nctlpoints; ++src) {
412 if (GET_X(src) >= min_x) {
413 memcpy(curve->ctlpoints + dst,
414 curve->ctlpoints + src,
415 sizeof(*curve->ctlpoints));
416 dst++;
417 }
418 }
419
420 if (dst < src) {
421 curve->nctlpoints -= (src - dst);
422 if (curve->nctlpoints <= 0) {
423 curve->nctlpoints = 1;
424 GET_X(0) = min_x;
425 GET_Y(0) = curve->min_y;
426 xs_curve_draw(curve, width, height);
427 }
428 curve->ctlpoints = g_realloc(curve->ctlpoints,
429 curve->nctlpoints * sizeof(*curve->ctlpoints));
430 }
431
432 new_type = GDK_FLEUR;
433 curve->grab_point = -1;
434 }
435 xs_curve_draw(curve, width, height);
436 break;
437
438 case GDK_MOTION_NOTIFY:
439 if (curve->grab_point == -1) {
440 /* if no point is grabbed... */
441 if (distance <= MIN_DISTANCE)
442 new_type = GDK_FLEUR;
443 else
444 new_type = GDK_TCROSS;
445 } else {
446 gint leftbound, rightbound;
447
448 /* drag the grabbed point */
449 new_type = GDK_TCROSS;
450
451 leftbound = -MIN_DISTANCE;
452 if (curve->grab_point > 0) {
453 leftbound = xs_project(
454 GET_X(curve->grab_point-1),
455 min_x, curve->max_x, width);
456 }
457
458 rightbound = width + RADIUS2 + MIN_DISTANCE;
459 if (curve->grab_point + 1 < curve->nctlpoints) {
460 rightbound = xs_project(
461 GET_X(curve->grab_point+1),
462 min_x, curve->max_x, width);
463 }
464
465 if ((tx <= leftbound) || (tx >= rightbound) ||
466 (ty > height + RADIUS2 + MIN_DISTANCE) || (ty < -MIN_DISTANCE)) {
467 GET_X(curve->grab_point) = min_x - 1.0;
468 } else {
469 GET_X(curve->grab_point) =
470 xs_unproject(x, min_x, curve->max_x, width);
471 GET_Y(curve->grab_point) =
472 xs_unproject(y, curve->min_y, curve->max_y, height);
473 }
474
475 xs_curve_draw(curve, width, height);
476 }
477
478 /* See if cursor type was changed and update accordingly */
479 if (new_type != (GdkCursorType) curve->cursor_type) {
480 GdkCursor *cursor;
481 curve->cursor_type = new_type;
482 cursor = gdk_cursor_new(curve->cursor_type);
483 gdk_window_set_cursor(w->window, cursor);
484 gdk_cursor_destroy(cursor);
485 }
486 break;
487
488 default:
489 break;
490 } 525 }
491 526
492 return FALSE; 527 return FALSE;
493 } 528 }
494 529
511 if (aspect < 1.0) 546 if (aspect < 1.0)
512 width = height * aspect; 547 width = height * aspect;
513 else 548 else
514 height = width / aspect; 549 height = width / aspect;
515 550
516 gtk_drawing_area_size(GTK_DRAWING_AREA(curve), width + RADIUS2, height + RADIUS2); 551 gtk_drawing_area_size(GTK_DRAWING_AREA(curve), width + CP_RADIUS2, height + CP_RADIUS2);
517 } 552 }
518 553
519 554
520 static void xs_curve_update(XSCurve *curve) 555 static void xs_curve_update(XSCurve *curve)
521 { 556 {
522 if (curve->pixmap) { 557 if (curve->pixmap)
558 {
523 gint width, height; 559 gint width, height;
524 560
525 width = GTK_WIDGET(curve)->allocation.width - RADIUS2; 561 width = GTK_WIDGET(curve)->allocation.width - CP_RADIUS2;
526 height = GTK_WIDGET(curve)->allocation.height - RADIUS2; 562 height = GTK_WIDGET(curve)->allocation.height - CP_RADIUS2;
527 xs_curve_draw(curve, width, height); 563 xs_curve_draw(curve, width, height);
528 } 564 }
529 } 565 }
530 566
531 567
564 } 600 }
565 601
566 602
567 gboolean xs_curve_realloc_data(XSCurve *curve, gint npoints) 603 gboolean xs_curve_realloc_data(XSCurve *curve, gint npoints)
568 { 604 {
569 if (npoints != curve->nctlpoints) { 605 if (npoints != curve->nctlpoints)
606 {
570 curve->nctlpoints = npoints; 607 curve->nctlpoints = npoints;
571 curve->ctlpoints = (xs_point_t *) g_realloc(curve->ctlpoints, 608 curve->ctlpoints = (xs_point_t *) g_realloc(curve->ctlpoints,
572 curve->nctlpoints * sizeof(*curve->ctlpoints)); 609 curve->nctlpoints * sizeof(*curve->ctlpoints));
573 610
574 if (curve->ctlpoints == NULL) 611 if (curve->ctlpoints == NULL)
596 GET_X(0) = curve->min_x; 633 GET_X(0) = curve->min_x;
597 GET_Y(0) = curve->min_y; 634 GET_Y(0) = curve->min_y;
598 GET_X(1) = curve->min_x; 635 GET_X(1) = curve->min_x;
599 GET_Y(1) = curve->min_y; 636 GET_Y(1) = curve->min_y;
600 637
601 for (i = 0; i < npoints; i++) { 638 for (i = 0; i < npoints; i++)
639 {
602 GET_X(i+2) = points[i].x; 640 GET_X(i+2) = points[i].x;
603 GET_Y(i+2) = points[i].y; 641 GET_Y(i+2) = points[i].y;
604 } 642 }
605 643
606 GET_X(npoints+2) = curve->max_x; 644 GET_X(npoints+2) = curve->max_x;
622 *points = g_malloc(n * sizeof(xs_int_point_t)); 660 *points = g_malloc(n * sizeof(xs_int_point_t));
623 if (*points == NULL) 661 if (*points == NULL)
624 return FALSE; 662 return FALSE;
625 663
626 *npoints = n; 664 *npoints = n;
627 for (i = 2; i < curve->nctlpoints - 2; i++) { 665 for (i = 2; i < curve->nctlpoints - 2; i++)
666 {
628 (*points)[i].x = GET_X(i); 667 (*points)[i].x = GET_X(i);
629 (*points)[i].y = GET_Y(i); 668 (*points)[i].y = GET_Y(i);
630 } 669 }
631 670
632 return TRUE; 671 return TRUE;