| 23 |
23 |
| 24 #include "internal.h" |
24 #include "internal.h" |
| 25 #include "buddylist.h" |
25 #include "buddylist.h" |
| 26 #include "debug.h" |
26 #include "debug.h" |
| 27 #include "pidgin.h" |
27 #include "pidgin.h" |
| |
28 #include "whiteboard.h" |
| 28 |
29 |
| 29 #include "gtk3compat.h" |
30 #include "gtk3compat.h" |
| 30 #include "gtkwhiteboard.h" |
31 #include "gtkwhiteboard.h" |
| 31 #include "gtkutils.h" |
32 #include "gtkutils.h" |
| 32 |
33 |
| |
34 typedef enum { |
| |
35 PIDGIN_WHITEBOARD_BRUSH_UP, |
| |
36 PIDGIN_WHITEBOARD_BRUSH_DOWN, |
| |
37 PIDGIN_WHITEBOARD_BRUSH_MOTION |
| |
38 } PidginWhiteboardBrushState; |
| |
39 |
| |
40 typedef struct _PidginWhiteboard PidginWhiteboard; |
| |
41 typedef struct _PidginWhiteboardPrivate PidginWhiteboardPrivate; |
| |
42 |
| 33 struct _PidginWhiteboardPrivate { |
43 struct _PidginWhiteboardPrivate { |
| 34 cairo_t *cr; |
44 cairo_t *cr; |
| 35 cairo_surface_t *surface; |
45 cairo_surface_t *surface; |
| |
46 }; |
| |
47 |
| |
48 /** |
| |
49 * PidginWhiteboard: |
| |
50 * @priv: Internal data |
| |
51 * @wb: Backend data for this whiteboard |
| |
52 * @window: Window for the Doodle session |
| |
53 * @drawing_area: Drawing area |
| |
54 * @width: Canvas width |
| |
55 * @height: Canvas height |
| |
56 * @brush_color: Foreground color |
| |
57 * @brush_size: Brush size |
| |
58 * |
| |
59 * A PidginWhiteboard |
| |
60 */ |
| |
61 struct _PidginWhiteboard |
| |
62 { |
| |
63 PidginWhiteboardPrivate *priv; |
| |
64 |
| |
65 PurpleWhiteboard *wb; |
| |
66 |
| |
67 GtkWidget *window; |
| |
68 GtkWidget *drawing_area; |
| |
69 |
| |
70 int width; |
| |
71 int height; |
| |
72 int brush_color; |
| |
73 int brush_size; |
| 36 }; |
74 }; |
| 37 |
75 |
| 38 /****************************************************************************** |
76 /****************************************************************************** |
| 39 * Prototypes |
77 * Prototypes |
| 40 *****************************************************************************/ |
78 *****************************************************************************/ |
| 78 static void color_select_dialog(GtkWidget *widget, PidginWhiteboard *gtkwb); |
116 static void color_select_dialog(GtkWidget *widget, PidginWhiteboard *gtkwb); |
| 79 |
117 |
| 80 /****************************************************************************** |
118 /****************************************************************************** |
| 81 * Globals |
119 * Globals |
| 82 *****************************************************************************/ |
120 *****************************************************************************/ |
| 83 /* |
|
| 84 GList *buttonList = NULL; |
|
| 85 GdkColor DefaultColor[PIDGIN_PALETTE_NUM_COLORS]; |
|
| 86 */ |
|
| 87 |
121 |
| 88 static int LastX; /* Tracks last position of the mouse when drawing */ |
122 static int LastX; /* Tracks last position of the mouse when drawing */ |
| 89 static int LastY; |
123 static int LastY; |
| 90 static int MotionCount; /* Tracks how many brush motions made */ |
124 static int MotionCount; /* Tracks how many brush motions made */ |
| 91 static int BrushState = PIDGIN_BRUSH_STATE_UP; |
125 static PidginWhiteboardBrushState brush_state = PIDGIN_WHITEBOARD_BRUSH_UP; |
| 92 |
126 |
| 93 static PurpleWhiteboardUiOps ui_ops = |
127 static PurpleWhiteboardUiOps ui_ops = |
| 94 { |
128 { |
| 95 pidgin_whiteboard_create, |
129 pidgin_whiteboard_create, |
| 96 pidgin_whiteboard_destroy, |
130 pidgin_whiteboard_destroy, |
| 167 gtk_widget_set_name(window, purple_whiteboard_get_who(wb)); |
201 gtk_widget_set_name(window, purple_whiteboard_get_who(wb)); |
| 168 |
202 |
| 169 g_signal_connect(G_OBJECT(window), "delete_event", |
203 g_signal_connect(G_OBJECT(window), "delete_event", |
| 170 G_CALLBACK(whiteboard_close_cb), gtkwb); |
204 G_CALLBACK(whiteboard_close_cb), gtkwb); |
| 171 |
205 |
| 172 #if 0 |
|
| 173 int i; |
|
| 174 |
|
| 175 GtkWidget *hbox_palette; |
|
| 176 GtkWidget *vbox_palette_above_canvas_and_controls; |
|
| 177 GtkWidget *palette_color_box[PIDGIN_PALETTE_NUM_COLORS]; |
|
| 178 |
|
| 179 /* Create vertical box to place palette above the canvas and controls */ |
|
| 180 vbox_palette_above_canvas_and_controls = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); |
|
| 181 gtk_container_add(GTK_CONTAINER(window), vbox_palette_above_canvas_and_controls); |
|
| 182 gtk_widget_show(vbox_palette_above_canvas_and_controls); |
|
| 183 |
|
| 184 /* Create horizontal box for the palette and all its entries */ |
|
| 185 hbox_palette = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); |
|
| 186 gtk_box_pack_start(GTK_BOX(vbox_palette_above_canvas_and_controls), |
|
| 187 hbox_palette, FALSE, FALSE, PIDGIN_HIG_BORDER); |
|
| 188 gtk_widget_show(hbox_palette); |
|
| 189 |
|
| 190 /* Create horizontal box to seperate the canvas from the controls */ |
|
| 191 hbox_canvas_and_controls = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); |
|
| 192 gtk_box_pack_start(GTK_BOX(vbox_palette_above_canvas_and_controls), |
|
| 193 hbox_canvas_and_controls, FALSE, FALSE, PIDGIN_HIG_BORDER); |
|
| 194 gtk_widget_show(hbox_canvas_and_controls); |
|
| 195 |
|
| 196 for(i = 0; i < PIDGIN_PALETTE_NUM_COLORS; i++) |
|
| 197 { |
|
| 198 palette_color_box[i] = gtk_image_new_from_pixbuf(NULL); |
|
| 199 gtk_widget_set_size_request(palette_color_box[i], gtkwb->width / PIDGIN_PALETTE_NUM_COLORS ,32); |
|
| 200 gtk_container_add(GTK_CONTAINER(hbox_palette), palette_color_box[i]); |
|
| 201 |
|
| 202 gtk_widget_show(palette_color_box[i]); |
|
| 203 } |
|
| 204 #endif |
|
| 205 |
|
| 206 hbox_canvas_and_controls = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); |
206 hbox_canvas_and_controls = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); |
| 207 gtk_widget_show(hbox_canvas_and_controls); |
207 gtk_widget_show(hbox_canvas_and_controls); |
| 208 |
208 |
| 209 gtk_container_add(GTK_CONTAINER(window), hbox_canvas_and_controls); |
209 gtk_container_add(GTK_CONTAINER(window), hbox_canvas_and_controls); |
| 210 gtk_container_set_border_width(GTK_CONTAINER(window), PIDGIN_HIG_BORDER); |
210 gtk_container_set_border_width(GTK_CONTAINER(window), PIDGIN_HIG_BORDER); |
| 435 PidginWhiteboard *gtkwb = (PidginWhiteboard*)data; |
435 PidginWhiteboard *gtkwb = (PidginWhiteboard*)data; |
| 436 |
436 |
| 437 PurpleWhiteboard *wb = gtkwb->wb; |
437 PurpleWhiteboard *wb = gtkwb->wb; |
| 438 GList *draw_list = purple_whiteboard_get_draw_list(wb); |
438 GList *draw_list = purple_whiteboard_get_draw_list(wb); |
| 439 |
439 |
| 440 if(BrushState != PIDGIN_BRUSH_STATE_UP) |
440 if (brush_state != PIDGIN_WHITEBOARD_BRUSH_UP) { |
| 441 { |
|
| 442 /* Potential double-click DOWN to DOWN? */ |
441 /* Potential double-click DOWN to DOWN? */ |
| 443 BrushState = PIDGIN_BRUSH_STATE_DOWN; |
442 brush_state = PIDGIN_WHITEBOARD_BRUSH_DOWN; |
| 444 |
443 |
| 445 /* return FALSE; */ |
444 /* return FALSE; */ |
| 446 } |
445 } |
| 447 |
446 |
| 448 BrushState = PIDGIN_BRUSH_STATE_DOWN; |
447 brush_state = PIDGIN_WHITEBOARD_BRUSH_DOWN; |
| 449 |
448 |
| 450 if(event->button == 1 && gtkwb->priv->cr != NULL) |
449 if(event->button == 1 && gtkwb->priv->cr != NULL) |
| 451 { |
450 { |
| 452 /* Check if draw_list has contents; if so, clear it */ |
451 /* Check if draw_list has contents; if so, clear it */ |
| 453 if(draw_list) |
452 if(draw_list) |
| 503 state = event->state; |
502 state = event->state; |
| 504 } |
503 } |
| 505 |
504 |
| 506 if(state & GDK_BUTTON1_MASK && gtkwb->priv->cr != NULL) |
505 if(state & GDK_BUTTON1_MASK && gtkwb->priv->cr != NULL) |
| 507 { |
506 { |
| 508 if((BrushState != PIDGIN_BRUSH_STATE_DOWN) && (BrushState != PIDGIN_BRUSH_STATE_MOTION)) |
507 if ((brush_state != PIDGIN_WHITEBOARD_BRUSH_DOWN) && |
| |
508 (brush_state != PIDGIN_WHITEBOARD_BRUSH_MOTION)) |
| 509 { |
509 { |
| 510 purple_debug_error("gtkwhiteboard", "***Bad brush state transition %d to MOTION\n", BrushState); |
510 purple_debug_error("gtkwhiteboard", |
| 511 |
511 "***Bad brush state transition %d to MOTION\n", |
| 512 BrushState = PIDGIN_BRUSH_STATE_MOTION; |
512 brush_state); |
| |
513 |
| |
514 brush_state = PIDGIN_WHITEBOARD_BRUSH_MOTION; |
| 513 |
515 |
| 514 return FALSE; |
516 return FALSE; |
| 515 } |
517 } |
| 516 BrushState = PIDGIN_BRUSH_STATE_MOTION; |
518 brush_state = PIDGIN_WHITEBOARD_BRUSH_MOTION; |
| 517 |
519 |
| 518 dx = x - LastX; |
520 dx = x - LastX; |
| 519 dy = y - LastY; |
521 dy = y - LastY; |
| 520 |
522 |
| 521 MotionCount++; |
523 MotionCount++; |
| 571 PidginWhiteboard *gtkwb = (PidginWhiteboard*)data; |
573 PidginWhiteboard *gtkwb = (PidginWhiteboard*)data; |
| 572 |
574 |
| 573 PurpleWhiteboard *wb = gtkwb->wb; |
575 PurpleWhiteboard *wb = gtkwb->wb; |
| 574 GList *draw_list = purple_whiteboard_get_draw_list(wb); |
576 GList *draw_list = purple_whiteboard_get_draw_list(wb); |
| 575 |
577 |
| 576 if((BrushState != PIDGIN_BRUSH_STATE_DOWN) && (BrushState != PIDGIN_BRUSH_STATE_MOTION)) |
578 if ((brush_state != PIDGIN_WHITEBOARD_BRUSH_DOWN) && |
| 577 { |
579 (brush_state != PIDGIN_WHITEBOARD_BRUSH_MOTION)) |
| 578 purple_debug_error("gtkwhiteboard", "***Bad brush state transition %d to UP\n", BrushState); |
580 { |
| 579 |
581 purple_debug_error("gtkwhiteboard", |
| 580 BrushState = PIDGIN_BRUSH_STATE_UP; |
582 "***Bad brush state transition %d to UP\n", |
| |
583 brush_state); |
| |
584 |
| |
585 brush_state = PIDGIN_WHITEBOARD_BRUSH_UP; |
| 581 |
586 |
| 582 return FALSE; |
587 return FALSE; |
| 583 } |
588 } |
| 584 BrushState = PIDGIN_BRUSH_STATE_UP; |
589 brush_state = PIDGIN_WHITEBOARD_BRUSH_UP; |
| 585 |
590 |
| 586 if(event->button == 1 && gtkwb->priv->cr != NULL) |
591 if(event->button == 1 && gtkwb->priv->cr != NULL) |
| 587 { |
592 { |
| 588 /* If the brush was never moved, express two sets of two deltas That's a |
593 /* If the brush was never moved, express two sets of two deltas That's a |
| 589 * 'point,' but not for Yahoo! |
594 * 'point,' but not for Yahoo! |