aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2011-10-09 22:06:39 +0200
committerThomas White <taw@bitwiz.org.uk>2011-10-09 22:06:39 +0200
commitfc8f986b76af09d4f2dea80854cceaf1f8fdd43f (patch)
tree066dc7a194d77ffb254c53ff89a2199d8e4e989b
parent5ac069656c36aa1404d90cfad915d05736fa91d2 (diff)
Drag to create region
-rw-r--r--src/mainwindow.c118
-rw-r--r--src/presentation.h22
-rw-r--r--src/tool_select.c30
-rw-r--r--src/tool_text.c66
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;