46
51
shift_color_byte (guchar b,
49
return CLAMP(b + shift, 0, 255);
54
return CLAMP(b + shift, 0, 255);
53
58
shift_colors (GdkPixbuf *pixbuf,
59
gint x, y, offset, y_offset, rowstride, width, height;
63
width = gdk_pixbuf_get_width (pixbuf);
64
height = gdk_pixbuf_get_height (pixbuf);
65
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
66
pixels = gdk_pixbuf_get_pixels (pixbuf);
67
channels = gdk_pixbuf_get_n_channels (pixbuf);
69
for (y = 0; y < height; y++) {
70
y_offset = y * rowstride;
71
for (x = 0; x < width; x++) {
72
offset = y_offset + x * channels;
74
pixels[offset] = shift_color_byte (pixels[offset], red);
76
pixels[offset + 1] = shift_color_byte (pixels[offset + 1], green);
78
pixels[offset + 2] = shift_color_byte (pixels[offset + 2], blue);
79
if (alpha != 0 && channels >= 4)
80
pixels[offset + 3] = shift_color_byte (pixels[offset + 3], blue);
64
gint x, y, offset, y_offset, rowstride, width, height;
68
width = gdk_pixbuf_get_width (pixbuf);
69
height = gdk_pixbuf_get_height (pixbuf);
70
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
71
pixels = gdk_pixbuf_get_pixels (pixbuf);
72
channels = gdk_pixbuf_get_n_channels (pixbuf);
74
for (y = 0; y < height; y++) {
75
y_offset = y * rowstride;
76
for (x = 0; x < width; x++) {
77
offset = y_offset + x * channels;
79
pixels[offset] = shift_color_byte (pixels[offset], red);
81
pixels[offset + 1] = shift_color_byte (pixels[offset + 1], green);
83
pixels[offset + 2] = shift_color_byte (pixels[offset + 2], blue);
84
if (alpha != 0 && channels >= 4)
85
pixels[offset + 3] = shift_color_byte (pixels[offset + 3], blue);
86
91
update_pixbufs (UmCropArea *area)
88
GtkAllocation allocation;
95
gint dest_x, dest_y, dest_width, dest_height;
98
widget = GTK_WIDGET (area);
99
gtk_widget_get_allocation (widget, &allocation);
101
if (area->priv->pixbuf == NULL ||
102
gdk_pixbuf_get_width (area->priv->pixbuf) != allocation.width ||
103
gdk_pixbuf_get_height (area->priv->pixbuf) != allocation.height) {
104
if (area->priv->pixbuf != NULL)
105
g_object_unref (area->priv->pixbuf);
106
area->priv->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
107
allocation.width, allocation.height);
109
style = gtk_widget_get_style (widget);
110
color = &style->bg[gtk_widget_get_state (widget)];
111
pixel = ((color->red & 0xff00) << 16) |
112
((color->green & 0xff00) << 8) |
113
(color->blue & 0xff00);
114
gdk_pixbuf_fill (area->priv->pixbuf, pixel);
116
width = gdk_pixbuf_get_width (area->priv->browse_pixbuf);
117
height = gdk_pixbuf_get_height (area->priv->browse_pixbuf);
119
scale = allocation.height / (gdouble)height;
120
if (scale * width > allocation.width)
121
scale = allocation.width / (gdouble)width;
123
dest_width = width * scale;
124
dest_height = height * scale;
125
dest_x = (allocation.width - dest_width) / 2;
126
dest_y = (allocation.height - dest_height) / 2,
128
gdk_pixbuf_scale (area->priv->browse_pixbuf,
131
dest_width, dest_height,
134
GDK_INTERP_BILINEAR);
136
if (area->priv->color_shifted)
137
g_object_unref (area->priv->color_shifted);
138
area->priv->color_shifted = gdk_pixbuf_copy (area->priv->pixbuf);
139
shift_colors (area->priv->color_shifted, -32, -32, -32, 0);
141
if (area->priv->scale == 0.0) {
142
area->priv->crop.width = 96.0 / scale;
143
area->priv->crop.height = 96.0 / scale;
144
area->priv->crop.x = (gdk_pixbuf_get_width (area->priv->browse_pixbuf) - area->priv->crop.width) / 2;
145
area->priv->crop.y = (gdk_pixbuf_get_height (area->priv->browse_pixbuf) - area->priv->crop.height) / 2;
148
area->priv->scale = scale;
149
area->priv->image.x = dest_x;
150
area->priv->image.y = dest_y;
151
area->priv->image.width = dest_width;
152
area->priv->image.height = dest_height;
95
GtkAllocation allocation;
99
gint dest_x, dest_y, dest_width, dest_height;
101
GtkStyleContext *context;
103
widget = GTK_WIDGET (area);
104
gtk_widget_get_allocation (widget, &allocation);
105
context = gtk_widget_get_style_context (widget);
107
if (area->priv->pixbuf == NULL ||
108
gdk_pixbuf_get_width (area->priv->pixbuf) != allocation.width ||
109
gdk_pixbuf_get_height (area->priv->pixbuf) != allocation.height) {
110
if (area->priv->pixbuf != NULL)
111
g_object_unref (area->priv->pixbuf);
112
area->priv->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
113
gdk_pixbuf_get_has_alpha (area->priv->browse_pixbuf),
115
allocation.width, allocation.height);
117
gtk_style_context_get_background_color (context, gtk_style_context_get_state (context), &color);
118
pixel = (((gint)(color.red * 1.0)) << 16) |
119
(((gint)(color.green * 1.0)) << 8) |
120
((gint)(color.blue * 1.0));
121
gdk_pixbuf_fill (area->priv->pixbuf, pixel);
123
width = gdk_pixbuf_get_width (area->priv->browse_pixbuf);
124
height = gdk_pixbuf_get_height (area->priv->browse_pixbuf);
126
scale = allocation.height / (gdouble)height;
127
if (scale * width > allocation.width)
128
scale = allocation.width / (gdouble)width;
130
dest_width = width * scale;
131
dest_height = height * scale;
132
dest_x = (allocation.width - dest_width) / 2;
133
dest_y = (allocation.height - dest_height) / 2,
135
gdk_pixbuf_scale (area->priv->browse_pixbuf,
138
dest_width, dest_height,
141
GDK_INTERP_BILINEAR);
143
if (area->priv->color_shifted)
144
g_object_unref (area->priv->color_shifted);
145
area->priv->color_shifted = gdk_pixbuf_copy (area->priv->pixbuf);
146
shift_colors (area->priv->color_shifted, -32, -32, -32, 0);
148
if (area->priv->scale == 0.0) {
149
area->priv->crop.width = 2 * area->priv->base_width / scale;
150
area->priv->crop.height = 2 * area->priv->base_height / scale;
151
area->priv->crop.x = (gdk_pixbuf_get_width (area->priv->browse_pixbuf) - area->priv->crop.width) / 2;
152
area->priv->crop.y = (gdk_pixbuf_get_height (area->priv->browse_pixbuf) - area->priv->crop.height) / 2;
155
area->priv->scale = scale;
156
area->priv->image.x = dest_x;
157
area->priv->image.y = dest_y;
158
area->priv->image.width = dest_width;
159
area->priv->image.height = dest_height;
157
164
crop_to_widget (UmCropArea *area,
158
165
GdkRectangle *crop)
160
crop->x = area->priv->image.x + area->priv->crop.x * area->priv->scale;
161
crop->y = area->priv->image.y + area->priv->crop.y * area->priv->scale;
162
crop->width = area->priv->crop.width * area->priv->scale;
163
crop->height = area->priv->crop.height * area->priv->scale;
167
crop->x = area->priv->image.x + area->priv->crop.x * area->priv->scale;
168
crop->y = area->priv->image.y + area->priv->crop.y * area->priv->scale;
169
crop->width = area->priv->crop.width * area->priv->scale;
170
crop->height = area->priv->crop.height * area->priv->scale;
180
um_crop_area_expose (GtkWidget *widget,
181
GdkEventExpose *event)
187
um_crop_area_draw (GtkWidget *widget,
190
UmCropArea *uarea = UM_CROP_AREA (widget);
192
if (uarea->priv->browse_pixbuf == NULL)
195
update_pixbufs (uarea);
197
window = gtk_widget_get_window (widget);
198
style = gtk_widget_get_style (widget);
199
state = gtk_widget_get_state (widget);
201
width = gdk_pixbuf_get_width (uarea->priv->pixbuf);
202
height = gdk_pixbuf_get_height (uarea->priv->pixbuf);
203
crop_to_widget (uarea, &crop);
208
area.height = crop.y;
209
gdk_rectangle_intersect (&area, &event->area, &area);
210
gdk_draw_pixbuf (window,
212
uarea->priv->color_shifted,
215
area.width, area.height,
216
GDK_RGB_DITHER_NONE, 0, 0);
221
area.height = crop.height;
222
gdk_rectangle_intersect (&area, &event->area, &area);
223
gdk_draw_pixbuf (window,
225
uarea->priv->color_shifted,
228
area.width, area.height,
229
GDK_RGB_DITHER_NONE, 0, 0);
233
area.width = crop.width;
234
area.height = crop.height;
235
gdk_rectangle_intersect (&area, &event->area, &area);
236
gdk_draw_pixbuf (window,
241
area.width, area.height,
242
GDK_RGB_DITHER_NONE, 0, 0);
244
area.x = crop.x + crop.width;
246
area.width = width - area.x;
247
area.height = crop.height;
248
gdk_rectangle_intersect (&area, &event->area, &area);
249
gdk_draw_pixbuf (window,
251
uarea->priv->color_shifted,
254
area.width, area.height,
255
GDK_RGB_DITHER_NONE, 0, 0);
258
area.y = crop.y + crop.width;
260
area.height = height - area.y;
261
gdk_rectangle_intersect (&area, &event->area, &area);
262
gdk_draw_pixbuf (window,
264
uarea->priv->color_shifted,
267
area.width, area.height,
268
GDK_RGB_DITHER_NONE, 0, 0);
270
cr = gdk_cairo_create (window);
271
gdk_cairo_rectangle (cr, &event->area);
274
if (uarea->priv->active_region != OUTSIDE) {
276
gdk_cairo_set_source_color (cr, &style->white);
277
cairo_set_line_width (cr, 1.0);
278
x1 = crop.x + crop.width / 3.0;
279
x2 = crop.x + 2 * crop.width / 3.0;
280
y1 = crop.y + crop.height / 3.0;
281
y2 = crop.y + 2 * crop.height / 3.0;
283
cairo_move_to (cr, x1 + 0.5, crop.y);
284
cairo_line_to (cr, x1 + 0.5, crop.y + crop.height);
286
cairo_move_to (cr, x2 + 0.5, crop.y);
287
cairo_line_to (cr, x2 + 0.5, crop.y + crop.height);
289
cairo_move_to (cr, crop.x, y1 + 0.5);
290
cairo_line_to (cr, crop.x + crop.width, y1 + 0.5);
292
cairo_move_to (cr, crop.x, y2 + 0.5);
293
cairo_line_to (cr, crop.x + crop.width, y2 + 0.5);
297
gdk_cairo_set_source_color (cr, &style->black);
298
cairo_set_line_width (cr, 1.0);
192
UmCropArea *uarea = UM_CROP_AREA (widget);
194
if (uarea->priv->browse_pixbuf == NULL)
197
update_pixbufs (uarea);
199
width = gdk_pixbuf_get_width (uarea->priv->pixbuf);
200
height = gdk_pixbuf_get_height (uarea->priv->pixbuf);
201
crop_to_widget (uarea, &crop);
203
gdk_cairo_set_source_pixbuf (cr, uarea->priv->color_shifted, 0, 0);
204
cairo_rectangle (cr, 0, 0, width, crop.y);
205
cairo_rectangle (cr, 0, crop.y, crop.x, crop.height);
206
cairo_rectangle (cr, crop.x + crop.width, crop.y, width - crop.x - crop.width, crop.height);
207
cairo_rectangle (cr, 0, crop.y + crop.height, width, height - crop.y - crop.height);
210
gdk_cairo_set_source_pixbuf (cr, uarea->priv->pixbuf, 0, 0);
211
cairo_rectangle (cr, crop.x, crop.y, crop.width, crop.height);
214
if (uarea->priv->active_region != OUTSIDE) {
216
cairo_set_source_rgb (cr, 1, 1, 1);
217
cairo_set_line_width (cr, 1.0);
218
x1 = crop.x + crop.width / 3.0;
219
x2 = crop.x + 2 * crop.width / 3.0;
220
y1 = crop.y + crop.height / 3.0;
221
y2 = crop.y + 2 * crop.height / 3.0;
223
cairo_move_to (cr, x1 + 0.5, crop.y);
224
cairo_line_to (cr, x1 + 0.5, crop.y + crop.height);
226
cairo_move_to (cr, x2 + 0.5, crop.y);
227
cairo_line_to (cr, x2 + 0.5, crop.y + crop.height);
229
cairo_move_to (cr, crop.x, y1 + 0.5);
230
cairo_line_to (cr, crop.x + crop.width, y1 + 0.5);
232
cairo_move_to (cr, crop.x, y2 + 0.5);
233
cairo_line_to (cr, crop.x + crop.width, y2 + 0.5);
237
cairo_set_source_rgb (cr, 0, 0, 0);
238
cairo_set_line_width (cr, 1.0);
302
242
crop.width - 1.0,
303
243
crop.height - 1.0);
304
244
cairo_stroke (cr);
306
gdk_cairo_set_source_color (cr, &style->white);
307
cairo_set_line_width (cr, 2.0);
246
cairo_set_source_rgb (cr, 1, 1, 1);
247
cairo_set_line_width (cr, 2.0);
311
251
crop.width - 4.0,
312
252
crop.height - 4.0);
313
253
cairo_stroke (cr);
374
crop_to_widget (area, &crop);
376
switch (find_location (&crop, x, y)) {
378
cursor_type = GDK_LEFT_PTR;
381
cursor_type = GDK_TOP_LEFT_CORNER;
384
cursor_type = GDK_TOP_SIDE;
387
cursor_type = GDK_TOP_RIGHT_CORNER;
390
cursor_type = GDK_LEFT_SIDE;
393
cursor_type = GDK_FLEUR;
396
cursor_type = GDK_RIGHT_SIDE;
399
cursor_type = GDK_BOTTOM_LEFT_CORNER;
402
cursor_type = GDK_BOTTOM_SIDE;
405
cursor_type = GDK_BOTTOM_RIGHT_CORNER;
409
if (cursor_type != area->priv->current_cursor) {
410
GdkCursor *cursor = gdk_cursor_new (cursor_type);
411
gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (area)), cursor);
412
gdk_cursor_unref (cursor);
413
area->priv->current_cursor = cursor_type;
313
region = area->priv->active_region;
314
if (region == OUTSIDE) {
315
crop_to_widget (area, &crop);
316
region = find_location (&crop, x, y);
321
cursor_type = GDK_LEFT_PTR;
324
cursor_type = GDK_TOP_LEFT_CORNER;
327
cursor_type = GDK_TOP_SIDE;
330
cursor_type = GDK_TOP_RIGHT_CORNER;
333
cursor_type = GDK_LEFT_SIDE;
336
cursor_type = GDK_FLEUR;
339
cursor_type = GDK_RIGHT_SIDE;
342
cursor_type = GDK_BOTTOM_LEFT_CORNER;
345
cursor_type = GDK_BOTTOM_SIDE;
348
cursor_type = GDK_BOTTOM_RIGHT_CORNER;
351
g_assert_not_reached ();
354
if (cursor_type != area->priv->current_cursor) {
355
GdkCursor *cursor = gdk_cursor_new (cursor_type);
356
gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (area)), cursor);
357
g_object_unref (cursor);
358
area->priv->current_cursor = cursor_type;
363
eval_radial_line (gdouble center_x, gdouble center_y,
364
gdouble bounds_x, gdouble bounds_y,
367
gdouble decision_slope;
368
gdouble decision_intercept;
370
decision_slope = (bounds_y - center_y) / (bounds_x - center_x);
371
decision_intercept = -(decision_slope * bounds_x);
373
return (int) (decision_slope * user_x + decision_intercept);
418
377
um_crop_area_motion_notify_event (GtkWidget *widget,
419
GdkEventMotion *event)
378
GdkEventMotion *event)
423
gint delta_x, delta_y;
424
gint width, height, d;
425
UmCropArea *area = UM_CROP_AREA (widget);
427
width = gdk_pixbuf_get_width (area->priv->browse_pixbuf);
428
height = gdk_pixbuf_get_height (area->priv->browse_pixbuf);
430
x = (event->x - area->priv->image.x) / area->priv->scale;
431
y = (event->y - area->priv->image.y) / area->priv->scale;
432
x = CLAMP (x, 0, width);
433
y = CLAMP (y, 0, height);
435
delta_x = x - area->priv->last_press_x;
436
delta_y = y - area->priv->last_press_y;
437
area->priv->last_press_x = x;
438
area->priv->last_press_y = y;
440
x2 = area->priv->crop.x + area->priv->crop.width;
441
y2 = area->priv->crop.y + area->priv->crop.height;
443
switch (area->priv->active_region) {
445
area->priv->crop.x = CLAMP (area->priv->crop.x + delta_x, 0, width - area->priv->crop.width);
446
area->priv->crop.y = CLAMP (area->priv->crop.y + delta_y, 0, height - area->priv->crop.height);
450
d = MAX (x2 - x, y2 - y);
451
if (d < 48 / area->priv->scale)
452
d = 48 / area->priv->scale;
457
area->priv->crop.x = x2 - d;
458
area->priv->crop.y = y2 - d;
459
area->priv->crop.width = area->priv->crop.height = d;
464
d = MAX (y2 - y, x - area->priv->crop.x);
465
if (d < 48 / area->priv->scale)
466
d = 48 / area->priv->scale;
467
if (area->priv->crop.x + d > width)
468
d = width - area->priv->crop.x;
471
area->priv->crop.y = y2 - d;
472
area->priv->crop.width = area->priv->crop.height = d;
477
d = MAX (x2 - x, y - area->priv->crop.y);
478
if (d < 48 / area->priv->scale)
479
d = 48 / area->priv->scale;
480
if (area->priv->crop.y + d > height)
481
d = height - area->priv->crop.y;
484
area->priv->crop.x = x2 - d;
485
area->priv->crop.width = area->priv->crop.height = d;
491
area->priv->crop.width = MAX (x - area->priv->crop.x, y - area->priv->crop.y);
492
if (area->priv->crop.width < 48 / area->priv->scale)
493
area->priv->crop.width = 48 / area->priv->scale;
494
if (area->priv->crop.x + area->priv->crop.width > width)
495
area->priv->crop.width = width - area->priv->crop.x;
496
area->priv->crop.height = area->priv->crop.width;
497
if (area->priv->crop.y + area->priv->crop.height > height)
498
area->priv->crop.height = height - area->priv->crop.y;
499
area->priv->crop.width = area->priv->crop.height;
507
update_cursor (area, event->x, event->y);
508
gtk_widget_queue_draw (widget);
380
UmCropArea *area = UM_CROP_AREA (widget);
382
gint delta_x, delta_y;
384
gint adj_width, adj_height;
385
gint pb_width, pb_height;
387
gint left, right, top, bottom;
388
gdouble new_width, new_height;
389
gdouble center_x, center_y;
390
gint min_width, min_height;
392
if (area->priv->browse_pixbuf == NULL)
395
update_cursor (area, event->x, event->y);
397
crop_to_widget (area, &damage);
398
gtk_widget_queue_draw_area (widget,
399
damage.x - 1, damage.y - 1,
400
damage.width + 2, damage.height + 2);
402
pb_width = gdk_pixbuf_get_width (area->priv->browse_pixbuf);
403
pb_height = gdk_pixbuf_get_height (area->priv->browse_pixbuf);
405
x = (event->x - area->priv->image.x) / area->priv->scale;
406
y = (event->y - area->priv->image.y) / area->priv->scale;
408
delta_x = x - area->priv->last_press_x;
409
delta_y = y - area->priv->last_press_y;
410
area->priv->last_press_x = x;
411
area->priv->last_press_y = y;
413
left = area->priv->crop.x;
414
right = area->priv->crop.x + area->priv->crop.width - 1;
415
top = area->priv->crop.y;
416
bottom = area->priv->crop.y + area->priv->crop.height - 1;
418
center_x = (left + right) / 2.0;
419
center_y = (top + bottom) / 2.0;
421
switch (area->priv->active_region) {
423
width = right - left + 1;
424
height = bottom - top + 1;
435
if (right > pb_width)
437
if (bottom > pb_height)
440
adj_width = right - left + 1;
441
adj_height = bottom - top + 1;
442
if (adj_width != width) {
444
right = left + width - 1;
446
left = right - width + 1;
448
if (adj_height != height) {
450
bottom = top + height - 1;
452
top = bottom - height + 1;
458
if (area->priv->aspect < 0) {
462
else if (y < eval_radial_line (center_x, center_y, left, top, x)) {
464
new_width = (bottom - top) * area->priv->aspect;
465
left = right - new_width;
469
new_height = (right - left) / area->priv->aspect;
470
top = bottom - new_height;
476
if (area->priv->aspect > 0) {
477
new_width = (bottom - top) * area->priv->aspect;
478
right = left + new_width;
483
if (area->priv->aspect < 0) {
487
else if (y < eval_radial_line (center_x, center_y, right, top, x)) {
489
new_width = (bottom - top) * area->priv->aspect;
490
right = left + new_width;
494
new_height = (right - left) / area->priv->aspect;
495
top = bottom - new_height;
501
if (area->priv->aspect > 0) {
502
new_height = (right - left) / area->priv->aspect;
503
bottom = top + new_height;
508
if (area->priv->aspect < 0) {
512
else if (y < eval_radial_line (center_x, center_y, left, bottom, x)) {
514
new_height = (right - left) / area->priv->aspect;
515
bottom = top + new_height;
519
new_width = (bottom - top) * area->priv->aspect;
520
left = right - new_width;
526
if (area->priv->aspect > 0) {
527
new_height = (right - left) / area->priv->aspect;
528
bottom = top + new_height;
533
if (area->priv->aspect < 0) {
537
else if (y < eval_radial_line (center_x, center_y, right, bottom, x)) {
539
new_height = (right - left) / area->priv->aspect;
540
bottom = top + new_height;
544
new_width = (bottom - top) * area->priv->aspect;
545
right = left + new_width;
551
if (area->priv->aspect > 0) {
552
new_width = (bottom - top) * area->priv->aspect;
553
right= left + new_width;
561
min_width = area->priv->base_width / area->priv->scale;
562
min_height = area->priv->base_height / area->priv->scale;
564
width = right - left + 1;
565
height = bottom - top + 1;
566
if (area->priv->aspect < 0) {
571
if (right > pb_width)
573
if (bottom > pb_height)
576
width = right - left + 1;
577
height = bottom - top + 1;
579
switch (area->priv->active_region) {
583
if (width < min_width)
584
left = right - min_width;
589
if (width < min_width)
590
right = left + min_width;
596
switch (area->priv->active_region) {
600
if (height < min_height)
601
top = bottom - min_height;
606
if (height < min_height)
607
bottom = top + min_height;
614
if (left < 0 || top < 0 ||
615
right > pb_width || bottom > pb_height ||
616
width < min_width || height < min_height) {
617
left = area->priv->crop.x;
618
right = area->priv->crop.x + area->priv->crop.width - 1;
619
top = area->priv->crop.y;
620
bottom = area->priv->crop.y + area->priv->crop.height - 1;
624
area->priv->crop.x = left;
625
area->priv->crop.y = top;
626
area->priv->crop.width = right - left + 1;
627
area->priv->crop.height = bottom - top + 1;
629
crop_to_widget (area, &damage);
630
gtk_widget_queue_draw_area (widget,
631
damage.x - 1, damage.y - 1,
632
damage.width + 2, damage.height + 2);
514
638
um_crop_area_button_press_event (GtkWidget *widget,
515
GdkEventButton *event)
639
GdkEventButton *event)
518
UmCropArea *area = UM_CROP_AREA (widget);
520
crop_to_widget (area, &crop);
522
area->priv->last_press_x = (event->x - area->priv->image.x) / area->priv->scale;
523
area->priv->last_press_y = (event->y - area->priv->image.y) / area->priv->scale;
524
area->priv->active_region = find_location (&crop, event->x, event->y);
526
gtk_widget_queue_draw (widget);
641
UmCropArea *area = UM_CROP_AREA (widget);
644
if (area->priv->browse_pixbuf == NULL)
647
crop_to_widget (area, &crop);
649
area->priv->last_press_x = (event->x - area->priv->image.x) / area->priv->scale;
650
area->priv->last_press_y = (event->y - area->priv->image.y) / area->priv->scale;
651
area->priv->active_region = find_location (&crop, event->x, event->y);
653
gtk_widget_queue_draw_area (widget,
654
crop.x - 1, crop.y - 1,
655
crop.width + 2, crop.height + 2);
532
661
um_crop_area_button_release_event (GtkWidget *widget,
533
GdkEventButton *event)
662
GdkEventButton *event)
535
UmCropArea *area = UM_CROP_AREA (widget);
537
area->priv->last_press_x = -1;
538
area->priv->last_press_y = -1;
539
area->priv->active_region = OUTSIDE;
541
gtk_widget_queue_draw (widget);
664
UmCropArea *area = UM_CROP_AREA (widget);
667
if (area->priv->browse_pixbuf == NULL)
670
crop_to_widget (area, &crop);
672
area->priv->last_press_x = -1;
673
area->priv->last_press_y = -1;
674
area->priv->active_region = OUTSIDE;
676
gtk_widget_queue_draw_area (widget,
677
crop.x - 1, crop.y - 1,
678
crop.width + 2, crop.height + 2);
547
684
um_crop_area_finalize (GObject *object)
549
UmCropArea *area = UM_CROP_AREA (object);
686
UmCropArea *area = UM_CROP_AREA (object);
551
if (area->priv->browse_pixbuf) {
552
g_object_unref (area->priv->browse_pixbuf);
553
area->priv->browse_pixbuf = NULL;
555
if (area->priv->pixbuf) {
556
g_object_unref (area->priv->pixbuf);
557
area->priv->pixbuf = NULL;
559
if (area->priv->color_shifted) {
560
g_object_unref (area->priv->color_shifted);
561
area->priv->color_shifted = NULL;
688
if (area->priv->browse_pixbuf) {
689
g_object_unref (area->priv->browse_pixbuf);
690
area->priv->browse_pixbuf = NULL;
692
if (area->priv->pixbuf) {
693
g_object_unref (area->priv->pixbuf);
694
area->priv->pixbuf = NULL;
696
if (area->priv->color_shifted) {
697
g_object_unref (area->priv->color_shifted);
698
area->priv->color_shifted = NULL;
566
703
um_crop_area_class_init (UmCropAreaClass *klass)
568
GObjectClass *object_class = G_OBJECT_CLASS (klass);
569
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
571
object_class->finalize = um_crop_area_finalize;
572
widget_class->expose_event = um_crop_area_expose;
573
widget_class->button_press_event = um_crop_area_button_press_event;
574
widget_class->button_release_event = um_crop_area_button_release_event;
575
widget_class->motion_notify_event = um_crop_area_motion_notify_event;
577
g_type_class_add_private (klass, sizeof (UmCropAreaPrivate));
705
GObjectClass *object_class = G_OBJECT_CLASS (klass);
706
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
708
object_class->finalize = um_crop_area_finalize;
709
widget_class->draw = um_crop_area_draw;
710
widget_class->button_press_event = um_crop_area_button_press_event;
711
widget_class->button_release_event = um_crop_area_button_release_event;
712
widget_class->motion_notify_event = um_crop_area_motion_notify_event;
714
g_type_class_add_private (klass, sizeof (UmCropAreaPrivate));
581
718
um_crop_area_init (UmCropArea *area)
583
area->priv = (G_TYPE_INSTANCE_GET_PRIVATE ((area), UM_TYPE_CROP_AREA,
586
gtk_widget_add_events (GTK_WIDGET (area), GDK_POINTER_MOTION_MASK |
587
GDK_BUTTON_PRESS_MASK |
588
GDK_BUTTON_RELEASE_MASK);
590
area->priv->scale = 0.0;
591
area->priv->image.x = 0;
592
area->priv->image.y = 0;
593
area->priv->image.width = 0;
594
area->priv->image.height = 0;
595
area->priv->active_region = OUTSIDE;
720
area->priv = (G_TYPE_INSTANCE_GET_PRIVATE ((area), UM_TYPE_CROP_AREA,
723
gtk_widget_add_events (GTK_WIDGET (area), GDK_POINTER_MOTION_MASK |
724
GDK_BUTTON_PRESS_MASK |
725
GDK_BUTTON_RELEASE_MASK);
727
area->priv->scale = 0.0;
728
area->priv->image.x = 0;
729
area->priv->image.y = 0;
730
area->priv->image.width = 0;
731
area->priv->image.height = 0;
732
area->priv->active_region = OUTSIDE;
733
area->priv->base_width = 48;
734
area->priv->base_height = 48;
735
area->priv->aspect = 1;
599
739
um_crop_area_new (void)
601
return g_object_new (UM_TYPE_CROP_AREA, NULL);
741
return g_object_new (UM_TYPE_CROP_AREA, NULL);
605
745
um_crop_area_get_picture (UmCropArea *area)
607
return gdk_pixbuf_new_subpixbuf (area->priv->browse_pixbuf,
608
area->priv->crop.x, area->priv->crop.y,
609
area->priv->crop.width, area->priv->crop.height);
749
width = gdk_pixbuf_get_width (area->priv->browse_pixbuf);
750
height = gdk_pixbuf_get_height (area->priv->browse_pixbuf);
751
width = MIN (area->priv->crop.width, width - area->priv->crop.x);
752
height = MIN (area->priv->crop.height, height - area->priv->crop.y);
754
return gdk_pixbuf_new_subpixbuf (area->priv->browse_pixbuf,
613
761
um_crop_area_set_picture (UmCropArea *area,
619
if (area->priv->browse_pixbuf) {
620
g_object_unref (area->priv->browse_pixbuf);
621
area->priv->browse_pixbuf = NULL;
624
area->priv->browse_pixbuf = g_object_ref (pixbuf);
625
width = gdk_pixbuf_get_width (pixbuf);
626
height = gdk_pixbuf_get_height (pixbuf);
633
gtk_widget_get_allocation (um->browse_drawing_area, &allocation);
634
um->priv->crop.width = 96;
635
um->priv->crop.height = 96;
636
um->priv->crop.x = (allocation.width - um->priv->crop.width) / 2;
637
um->priv->crop.y = (allocation.height - um->priv->crop.height) / 2;
639
area->priv->crop.width = 96;
640
area->priv->crop.height = 96;
641
area->priv->crop.x = (width - area->priv->crop.width) / 2;
642
area->priv->crop.y = (height - area->priv->crop.height) / 2;
644
area->priv->scale = 0.0;
645
area->priv->image.x = 0;
646
area->priv->image.y = 0;
647
area->priv->image.width = 0;
648
area->priv->image.height = 0;
650
gtk_widget_queue_draw (GTK_WIDGET (area));
767
if (area->priv->browse_pixbuf) {
768
g_object_unref (area->priv->browse_pixbuf);
769
area->priv->browse_pixbuf = NULL;
772
area->priv->browse_pixbuf = g_object_ref (pixbuf);
773
width = gdk_pixbuf_get_width (pixbuf);
774
height = gdk_pixbuf_get_height (pixbuf);
780
area->priv->crop.width = 2 * area->priv->base_width;
781
area->priv->crop.height = 2 * area->priv->base_height;
782
area->priv->crop.x = (width - area->priv->crop.width) / 2;
783
area->priv->crop.y = (height - area->priv->crop.height) / 2;
785
area->priv->scale = 0.0;
786
area->priv->image.x = 0;
787
area->priv->image.y = 0;
788
area->priv->image.width = 0;
789
area->priv->image.height = 0;
791
gtk_widget_queue_draw (GTK_WIDGET (area));
795
um_crop_area_set_min_size (UmCropArea *area,
799
area->priv->base_width = width;
800
area->priv->base_height = height;
802
if (area->priv->aspect > 0) {
803
area->priv->aspect = area->priv->base_width / (gdouble)area->priv->base_height;
808
um_crop_area_set_constrain_aspect (UmCropArea *area,
812
area->priv->aspect = area->priv->base_width / (gdouble)area->priv->base_height;
815
area->priv->aspect = -1;