aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2013-05-10 23:08:33 +0200
committerThomas White <taw@bitwiz.org.uk>2013-05-10 23:08:33 +0200
commitbc477b0f599bb3b25c1a30bf9852a7f8de243030 (patch)
treebdf4fbc430a9481604f5bd5ec59fb8aea7ec6aa5 /src
parentb7c3ebf468654c3ef5da50ac49f1bc01274057be (diff)
Drag to create a new frame
Diffstat (limited to 'src')
-rw-r--r--src/mainwindow.c162
-rw-r--r--src/presentation.h24
-rw-r--r--src/render.c4
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);
}