diff options
author | Thomas White <taw@bitwiz.org.uk> | 2011-10-09 22:06:39 +0200 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2011-10-09 22:06:39 +0200 |
commit | fc8f986b76af09d4f2dea80854cceaf1f8fdd43f (patch) | |
tree | 066dc7a194d77ffb254c53ff89a2199d8e4e989b | |
parent | 5ac069656c36aa1404d90cfad915d05736fa91d2 (diff) |
Drag to create region
-rw-r--r-- | src/mainwindow.c | 118 | ||||
-rw-r--r-- | src/presentation.h | 22 | ||||
-rw-r--r-- | src/tool_select.c | 30 | ||||
-rw-r--r-- | src/tool_text.c | 66 |
4 files changed, 201 insertions, 35 deletions
diff --git a/src/mainwindow.c b/src/mainwindow.c index 6416027..2ab4175 100644 --- a/src/mainwindow.c +++ b/src/mainwindow.c @@ -610,12 +610,36 @@ static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event, static gboolean motion_sig(GtkWidget *da, GdkEventMotion *event, - struct presentation *p) + struct presentation *p) { - if ( p->editing_object != NULL ) { + switch ( p->drag_reason ) { + + case DRAG_REASON_NONE : + /* If there was no reason before, now there is */ + p->drag_reason = DRAG_REASON_CREATE; + + /* Start the drag, and send the first drag event */ + p->cur_tool->start_drag_create(p->cur_tool, p, + p->start_create_drag_x, + p->start_create_drag_y); + p->cur_tool->drag_create(p->cur_tool, p, + event->x - p->border_offs_x, + event->y - p->border_offs_y); + break; + + case DRAG_REASON_MOVE : p->cur_tool->drag_object(p->cur_tool, p, p->editing_object, event->x - p->border_offs_x, event->y - p->border_offs_y); + break; + + case DRAG_REASON_CREATE : + p->cur_tool->drag_create(p->cur_tool, p, + event->x - p->border_offs_x, + event->y - p->border_offs_y); + + break; + } gdk_event_request_motions(event); @@ -640,12 +664,48 @@ static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event, p->cur_tool->deselect(p->editing_object, p->cur_tool); p->editing_object = NULL; } - p->cur_tool->click_create(p, p->cur_tool, x, y); + p->start_create_drag_x = x; + p->start_create_drag_y = y; + p->drag_reason = DRAG_REASON_NONE; } else { + if ( p->editing_object != NULL ) { + p->cur_tool->deselect(p->editing_object, p->cur_tool); + } p->editing_object = clicked; p->cur_tool->click_select(p, p->cur_tool, x, y); + p->drag_reason = DRAG_REASON_MOVE; + + } + + gtk_widget_grab_focus(GTK_WIDGET(da)); + redraw_overlay(p); + return FALSE; +} + + +static gboolean button_release_sig(GtkWidget *da, GdkEventButton *event, + struct presentation *p) +{ + gdouble x, y; + + x = event->x - p->border_offs_x; + y = event->y - p->border_offs_y; + + switch ( p->drag_reason ) { + + case DRAG_REASON_NONE : + p->cur_tool->click_create(p, p->cur_tool, x, y); + break; + + case DRAG_REASON_CREATE : + p->cur_tool->finish_drag_create(p->cur_tool, p, x, y); + break; + + case DRAG_REASON_MOVE : + /* FIXME: Update presentation and other stuff? */ + break; } @@ -655,33 +715,36 @@ static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event, } -static void draw_editing_bits(cairo_t *cr, struct presentation *p, - struct object *o) +static void draw_overlay(cairo_t *cr, struct presentation *p) { - p->cur_tool->draw_editing_overlay(cr, o); + struct object *o = p->editing_object; + + p->cur_tool->draw_editing_overlay(p->cur_tool, cr, o); - /* Draw margins */ - cairo_move_to(cr, o->style->margin_left, -p->border_offs_y); - cairo_line_to(cr, o->style->margin_left, - p->slide_height+p->border_offs_y); + if ( o != NULL ) { + /* Draw margins */ + cairo_move_to(cr, o->style->margin_left, -p->border_offs_y); + cairo_line_to(cr, o->style->margin_left, + p->slide_height+p->border_offs_y); - cairo_move_to(cr, p->slide_width-o->style->margin_right, - -p->border_offs_y); - cairo_line_to(cr, p->slide_width-o->style->margin_right, - p->slide_height+p->border_offs_y); + cairo_move_to(cr, p->slide_width-o->style->margin_right, + -p->border_offs_y); + cairo_line_to(cr, p->slide_width-o->style->margin_right, + p->slide_height+p->border_offs_y); - cairo_move_to(cr, -p->border_offs_x, o->style->margin_top); - cairo_line_to(cr, p->slide_width+p->border_offs_x, - o->style->margin_top); + cairo_move_to(cr, -p->border_offs_x, o->style->margin_top); + cairo_line_to(cr, p->slide_width+p->border_offs_x, + o->style->margin_top); - cairo_move_to(cr, -p->border_offs_x, - p->slide_height-o->style->margin_bottom); - cairo_line_to(cr, p->slide_width+p->border_offs_x, - p->slide_height-o->style->margin_bottom); + cairo_move_to(cr, -p->border_offs_x, + p->slide_height-o->style->margin_bottom); + cairo_line_to(cr, p->slide_width+p->border_offs_x, + p->slide_height-o->style->margin_bottom); - cairo_set_source_rgb(cr, 0.2, 0.2, 0.2); - cairo_set_line_width(cr, 1.0); - cairo_stroke(cr); + cairo_set_source_rgb(cr, 0.2, 0.2, 0.2); + cairo_set_line_width(cr, 1.0); + cairo_stroke(cr); + } } @@ -720,10 +783,7 @@ static gboolean expose_sig(GtkWidget *da, GdkEventExpose *event, cairo_translate(cr, xoff, yoff); - /* Draw editing bits for selected object */ - if ( p->editing_object != NULL ) { - draw_editing_bits(cr, p, p->editing_object); - } + draw_overlay(cr, p); /* Draw dragging box if necessary */ if ( p->draw_drag_box ) { @@ -946,6 +1006,8 @@ int open_mainwindow(struct presentation *p) g_signal_connect(G_OBJECT(p->drawingarea), "button-press-event", G_CALLBACK(button_press_sig), p); + g_signal_connect(G_OBJECT(p->drawingarea), "button-release-event", + G_CALLBACK(button_release_sig), p); g_signal_connect(G_OBJECT(p->drawingarea), "key-press-event", G_CALLBACK(key_press_sig), p); g_signal_connect(G_OBJECT(p->drawingarea), "expose-event", diff --git a/src/presentation.h b/src/presentation.h index 3588eb6..2b6f67c 100644 --- a/src/presentation.h +++ b/src/presentation.h @@ -46,6 +46,14 @@ struct slide }; +enum drag_reason +{ + DRAG_REASON_NONE, + DRAG_REASON_CREATE, + DRAG_REASON_MOVE, +}; + + struct toolinfo { void (*click_create)(struct presentation *p, struct toolinfo *tip, @@ -58,7 +66,16 @@ struct toolinfo int (*deselect)(struct object *o, struct toolinfo *tip); void (*drag_object)(struct toolinfo *tip, struct presentation *p, struct object *o, double x, double y); - void (*draw_editing_overlay)(cairo_t *cr, struct object *o); + + void (*start_drag_create)(struct toolinfo *tip, struct presentation *p, + double x, double y); + void (*drag_create)(struct toolinfo *tip, struct presentation *p, + double x, double y); + void (*finish_drag_create)(struct toolinfo *tip, struct presentation *p, + double x, double y); + + void (*draw_editing_overlay)(struct toolinfo *tip, cairo_t *cr, + struct object *o); void (*key_pressed)(struct object *o, guint keyval, struct toolinfo *tip); void (*im_commit)(struct object *o, gchar *str, struct toolinfo *tip); @@ -117,6 +134,9 @@ struct presentation struct toolinfo *cur_tool; double drag_offs_x; double drag_offs_y; + double start_create_drag_x; + double start_create_drag_y; + enum drag_reason drag_reason; unsigned int num_slides; struct slide **slides; diff --git a/src/tool_select.c b/src/tool_select.c index 6a67ee9..39f4525 100644 --- a/src/tool_select.c +++ b/src/tool_select.c @@ -85,6 +85,27 @@ static void drag_object(struct toolinfo *tip, struct presentation *p, } +static void start_drag_create(struct toolinfo *tip, struct presentation *p, + double x, double y) +{ + /* Do nothing */ +} + + +static void drag_create(struct toolinfo *tip, struct presentation *p, + double x, double y) +{ + /* Do nothing */ +} + + +static void finish_drag_create(struct toolinfo *tip, struct presentation *p, + double x, double y) +{ + /* Do nothing */ +} + + static void select_object(struct object *o,struct toolinfo *tip) { /* Do nothing */ @@ -98,9 +119,11 @@ static int deselect_object(struct object *o,struct toolinfo *tip) } -static void draw_overlay(cairo_t *cr, struct object *o) +static void draw_overlay(struct toolinfo *tip, cairo_t *cr, struct object *o) { - draw_editing_box(cr, o->x, o->y, o->bb_width, o->bb_height); + if ( o != NULL ) { + draw_editing_box(cr, o->x, o->y, o->bb_width, o->bb_height); + } } @@ -128,6 +151,9 @@ struct toolinfo *initialise_select_tool() ti->base.select = select_object; ti->base.deselect = deselect_object; ti->base.drag_object = drag_object; + ti->base.start_drag_create = start_drag_create; + ti->base.drag_create = drag_create; + ti->base.finish_drag_create = finish_drag_create; ti->base.draw_editing_overlay = draw_overlay; ti->base.key_pressed = key_pressed; ti->base.im_commit = im_commit; diff --git a/src/tool_text.c b/src/tool_text.c index a6a17d5..038b375 100644 --- a/src/tool_text.c +++ b/src/tool_text.c @@ -40,6 +40,12 @@ struct text_toolinfo { struct toolinfo base; PangoContext *pc; + + int create_dragging; + double start_corner_x; + double start_corner_y; + double drag_corner_x; + double drag_corner_y; }; @@ -455,6 +461,42 @@ static void drag_object(struct toolinfo *tip, struct presentation *p, } +static void start_drag_create(struct toolinfo *tip, struct presentation *p, + double x, double y) +{ + struct text_toolinfo *ti = (struct text_toolinfo *)tip; + + ti->start_corner_x = x; + ti->start_corner_y = y; + ti->create_dragging = 1; +} + + +static void drag_create(struct toolinfo *tip, struct presentation *p, + double x, double y) +{ + struct text_toolinfo *ti = (struct text_toolinfo *)tip; + + ti->drag_corner_x = x; + ti->drag_corner_y = y; + + redraw_overlay(p); +} + + +static void finish_drag_create(struct toolinfo *tip, struct presentation *p, + double x, double y) +{ + struct text_toolinfo *ti = (struct text_toolinfo *)tip; + + ti->drag_corner_x = x; + ti->drag_corner_y = y; + ti->create_dragging = 0; + + redraw_overlay(p); +} + + static void create_default(struct presentation *p, struct style *sty, struct toolinfo *tip) { @@ -484,11 +526,24 @@ static int deselect_object(struct object *o, struct toolinfo *tip) } -static void draw_overlay(cairo_t *cr, struct object *o) +static void draw_overlay(struct toolinfo *tip, cairo_t *cr, struct object *o) { - draw_editing_box(cr, o->x, o->y, - o->bb_width, o->bb_height); - draw_caret(cr, o); + struct text_toolinfo *ti = (struct text_toolinfo *)tip; + + if ( o != NULL ) { + draw_editing_box(cr, o->x, o->y, o->bb_width, o->bb_height); + draw_caret(cr, o); + } + + if ( ti->create_dragging ) { + cairo_new_path(cr); + cairo_rectangle(cr, ti->start_corner_x, ti->start_corner_y, + ti->drag_corner_x - ti->start_corner_x, + ti->drag_corner_y - ti->start_corner_y); + cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); + cairo_set_line_width(cr, 0.5); + cairo_stroke(cr); + } } @@ -534,6 +589,9 @@ struct toolinfo *initialise_text_tool(GtkWidget *w) ti->base.select = select_object; ti->base.deselect = deselect_object; ti->base.drag_object = drag_object; + ti->base.start_drag_create = start_drag_create; + ti->base.drag_create = drag_create; + ti->base.finish_drag_create = finish_drag_create; ti->base.draw_editing_overlay = draw_overlay; ti->base.key_pressed = key_pressed; ti->base.im_commit = im_commit; |