diff options
author | Thomas White <taw@bitwiz.org.uk> | 2013-05-10 23:08:33 +0200 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2013-05-10 23:08:33 +0200 |
commit | bc477b0f599bb3b25c1a30bf9852a7f8de243030 (patch) | |
tree | bdf4fbc430a9481604f5bd5ec59fb8aea7ec6aa5 /src | |
parent | b7c3ebf468654c3ef5da50ac49f1bc01274057be (diff) |
Drag to create a new frame
Diffstat (limited to 'src')
-rw-r--r-- | src/mainwindow.c | 162 | ||||
-rw-r--r-- | src/presentation.h | 24 | ||||
-rw-r--r-- | src/render.c | 4 |
3 files changed, 189 insertions, 1 deletions
diff --git a/src/mainwindow.c b/src/mainwindow.c index d798256..312c905 100644 --- a/src/mainwindow.c +++ b/src/mainwindow.c @@ -805,6 +805,20 @@ static void draw_overlay(cairo_t *cr, struct presentation *p) if ( p->n_selection == 1 ) { draw_caret(cr, p->selection[0], p->cursor_pos); } + + if ( (p->drag_status == DRAG_STATUS_DRAGGING) + && ((p->drag_reason == DRAG_REASON_CREATE) + || (p->drag_reason == DRAG_REASON_IMPORT)) ) + { + cairo_new_path(cr); + cairo_rectangle(cr, p->start_corner_x, p->start_corner_y, + p->drag_corner_x - p->start_corner_x, + p->drag_corner_y - p->start_corner_y); + cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); + cairo_set_line_width(cr, 0.5); + cairo_stroke(cr); + } + } @@ -931,6 +945,148 @@ static gboolean im_commit_sig(GtkIMContext *im, gchar *str, } +static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event, + struct presentation *p) +{ + struct frame *clicked; + gdouble x, y; + + x = event->x - p->border_offs_x; + y = event->y - p->border_offs_y; + + clicked = NULL;//find_object_at_position(p->cur_edit_slide, x, y); + + if ( clicked == NULL ) { + + /* Clicked no object. Deselect old object and set up for + * (maybe) creating a new one. */ + + set_selection(p, NULL); + p->start_corner_x = event->x - p->border_offs_x; + p->start_corner_y = event->y - p->border_offs_y; + p->drag_status = DRAG_STATUS_COULD_DRAG; + p->drag_reason = DRAG_REASON_CREATE; + + } else { + + /* If the clicked object is not the same as the previously + * selected one, deselect the old one. */ + if ( p->selection[0] != clicked ) { + set_selection(p, NULL); + } + + p->drag_status = DRAG_STATUS_NONE; + p->drag_reason = DRAG_REASON_NONE; + + set_selection(p, clicked); + + } + + gtk_widget_grab_focus(GTK_WIDGET(da)); + redraw_editor(p); + return FALSE; +} + + +static gboolean motion_sig(GtkWidget *da, GdkEventMotion *event, + struct presentation *p) +{ + if ( p->drag_status == DRAG_STATUS_COULD_DRAG ) { + + /* We just got a motion signal, and the status was "could drag", + * therefore the drag has started. */ + p->drag_status = DRAG_STATUS_DRAGGING; + + } + + switch ( p->drag_reason ) { + + case DRAG_REASON_NONE : + break; + + case DRAG_REASON_CREATE : + p->drag_corner_x = event->x - p->border_offs_x; + p->drag_corner_y = event->y - p->border_offs_y; + redraw_editor(p); + break; + + case DRAG_REASON_IMPORT : + /* Do nothing, handled by dnd_motion() */ + break; + + } + + gdk_event_request_motions(event); + return FALSE; +} + + +static void create_frame(struct presentation *p, double x, double y, + double w, double h) +{ + struct frame *parent; + struct frame *fr; + + if ( p->n_selection != 1 ) { + parent = p->cur_edit_slide->top; + } else { + parent = p->selection[0]; + } + + fr = add_subframe(parent); + fr->sc = strdup("New frame!"); + fr->style = NULL; + fr->lop.x = x; + fr->lop.y = y; + fr->lop.w = w; + fr->lop.h = h; + rerender_slide(p); + set_selection(p, fr); +} + + +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; + + /* Not dragging? Then I don't care. */ + if ( p->drag_status != DRAG_STATUS_DRAGGING ) return FALSE; + + p->drag_corner_x = x; + p->drag_corner_y = y; + p->drag_status = DRAG_STATUS_NONE; + + switch ( p->drag_reason ) + { + + case DRAG_REASON_NONE : + printf("Release on pointless drag.\n"); + break; + + case DRAG_REASON_CREATE : + create_frame(p, p->start_corner_x, p->start_corner_y, + p->drag_corner_x - p->start_corner_x, + p->drag_corner_y - p->start_corner_y); + break; + + case DRAG_REASON_IMPORT : + /* Do nothing, handled in dnd_drop() or dnd_leave() */ + break; + + } + + p->drag_reason = DRAG_REASON_NONE; + + gtk_widget_grab_focus(GTK_WIDGET(da)); + redraw_editor(p); + return FALSE; +} + + static void move_cursor(struct presentation *p, signed int x, signed int y) { ssize_t pos = p->cursor_pos; @@ -1098,6 +1254,12 @@ int open_mainwindow(struct presentation *p) gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(p->drawingarea), "realize", G_CALLBACK(realise_sig), 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), "motion-notify-event", + G_CALLBACK(motion_sig), p); gtk_widget_set_can_focus(GTK_WIDGET(p->drawingarea), TRUE); gtk_widget_add_events(GTK_WIDGET(p->drawingarea), diff --git a/src/presentation.h b/src/presentation.h index 2af3d0e..7a43458 100644 --- a/src/presentation.h +++ b/src/presentation.h @@ -50,6 +50,22 @@ struct slide }; +enum drag_reason +{ + DRAG_REASON_NONE, + DRAG_REASON_CREATE, + DRAG_REASON_IMPORT, +}; + + +enum drag_status +{ + DRAG_STATUS_NONE, + DRAG_STATUS_COULD_DRAG, + DRAG_STATUS_DRAGGING, +}; + + struct presentation { char *titlebar; @@ -93,6 +109,14 @@ struct presentation double border_offs_x; double border_offs_y; + /* Rubber band boxes and related stuff */ + double start_corner_x; + double start_corner_y; + double drag_corner_x; + double drag_corner_y; + enum drag_reason drag_reason; + enum drag_status drag_status; + /* Slideshow stuff */ GtkWidget *slideshow; GtkWidget *ss_drawingarea; diff --git a/src/render.c b/src/render.c index b8eaec0..2c79253 100644 --- a/src/render.c +++ b/src/render.c @@ -211,7 +211,9 @@ static void run_render_sc(cairo_t *cr, struct frame *fr, const char *sc) static void do_background(cairo_t *cr, struct frame *fr) { - run_render_sc(cr, fr, fr->style->sc_prologue); + if ( fr->style != NULL ) { + run_render_sc(cr, fr, fr->style->sc_prologue); + } run_render_sc(cr, fr, fr->sc); } |