aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2011-10-03 12:09:50 +0200
committerThomas White <taw@bitwiz.org.uk>2011-10-03 12:10:12 +0200
commitf4ff26c955729f8b068c64fff806216eb6e34bd4 (patch)
tree577a756353ac09f53e818b8f19292d3ce6326e12 /src
parent9a5060c094813d908d4c9ef7b8631916939bb53d (diff)
Use dispatch tables for tool functions
Diffstat (limited to 'src')
-rw-r--r--src/mainwindow.c100
-rw-r--r--src/presentation.c6
-rw-r--r--src/presentation.h18
-rw-r--r--src/tool_select.c111
-rw-r--r--src/tool_select.h34
-rw-r--r--src/tool_text.c126
-rw-r--r--src/tool_text.h5
7 files changed, 313 insertions, 87 deletions
diff --git a/src/mainwindow.c b/src/mainwindow.c
index 84926f3..54f098e 100644
--- a/src/mainwindow.c
+++ b/src/mainwindow.c
@@ -357,15 +357,30 @@ static gint open_stylesheet_sig(GtkWidget *widget, struct presentation *p)
}
+enum tool_id
+{
+ TOOL_SELECT,
+ TOOL_TEXT,
+};
+
+
static gint set_tool_sig(GtkWidget *widget, GtkRadioAction *action,
struct presentation *p)
{
+ if ( p->editing_object != NULL ) {
+ p->cur_tool->deselect(p->editing_object, p->cur_tool);
+ }
+
switch ( gtk_radio_action_get_current_value(action) )
{
- case 0 : p->tool = TOOL_SELECT; break;
- case 1 : p->tool = TOOL_TEXT; break;
+ case TOOL_SELECT : p->cur_tool = p->select_tool; break;
+ case TOOL_TEXT : p->cur_tool = p->text_tool; break;
}
- p->editing_object = NULL;
+
+ if ( p->editing_object != NULL ) {
+ p->cur_tool->select(p->editing_object, p->cur_tool);
+ }
+
gdk_window_invalidate_rect(p->drawingarea->window, NULL, FALSE);
return 0;
@@ -376,17 +391,13 @@ static gint add_furniture(GtkWidget *widget, struct presentation *p)
{
gchar *name;
struct style *sty;
- struct object *n;
g_object_get(G_OBJECT(widget), "label", &name, NULL);
sty = find_style(p->ss, name);
g_free(name);
if ( sty == NULL ) return 0;
- n = add_text_object(p->view_slide, 0.0, 0.0, sty);
- p->editing_object = n;
-
- gdk_window_invalidate_rect(p->drawingarea->window, NULL, FALSE);
+ p->text_tool->create_default(p, sty);
return 0;
}
@@ -605,26 +616,10 @@ static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event,
static gboolean motion_sig(GtkWidget *da, GdkEventMotion *event,
struct presentation *p)
{
- if ( p->tool == TOOL_SELECT ) {
-
- if ( p->editing_object != NULL ) {
-
- gdouble x, y;
-
- x = event->x - p->border_offs_x;
- y = event->y - p->border_offs_y;
-
- p->editing_object->x = x + p->drag_offs_x;
- p->editing_object->y = y + p->drag_offs_y;
- p->view_slide->object_seq++;
-
- /* FIXME: Invalidate only the necessary region */
- gdk_window_invalidate_rect(p->drawingarea->window,
- NULL, FALSE);
-
-
- }
-
+ if ( p->editing_object != NULL ) {
+ p->cur_tool->drag_object(p->cur_tool, p, p->editing_object,
+ event->x - p->border_offs_x,
+ event->y - p->border_offs_y);
}
gdk_event_request_motions(event);
@@ -641,37 +636,26 @@ static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event,
x = event->x - p->border_offs_x;
y = event->y - p->border_offs_y;
- if ( p->editing_object && p->editing_object->empty ) {
- delete_object(p->editing_object);
- }
- p->editing_object = NULL;
+ clicked = find_object_at_position(p->view_slide, x, y);
- if ( (x>0.0) && (x<p->slide_width)
- && (y>0.0) && (y<p->slide_height) )
- {
- clicked = find_object_at_position(p->view_slide, x, y);
- switch ( p->tool ) {
- case TOOL_SELECT :
- if ( clicked ) {
- p->editing_object = clicked;
- p->drag_offs_x = clicked->x - x;
- p->drag_offs_y = clicked->y - y;
- }
- break;
- case TOOL_TEXT :
- if ( !clicked ) {
- struct object *n;
- /* FIXME: Insert ESP here and possibly
- * select a different style */
- n = add_text_object(p->view_slide, x, y,
- p->ss->styles[0]);
- p->editing_object = n;
- } else {
- p->editing_object = clicked;
- position_caret(clicked, x, y);
- }
- break;
+ if ( clicked == NULL ) {
+
+ if ( p->editing_object != NULL ) {
+ 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);
+
+ } else {
+
+ p->editing_object = clicked;
+ p->cur_tool->click_select(p, p->cur_tool, x, y);
+
+ }
+
+ /* FIXME: Tool is responsible for this */
+ if ( p->editing_object && p->editing_object->empty ) {
+ delete_object(p->editing_object);
}
gtk_widget_grab_focus(GTK_WIDGET(da));
@@ -685,7 +669,7 @@ static void draw_editing_box(cairo_t *cr, double xmin, double ymin,
{
cairo_new_path(cr);
cairo_rectangle(cr, xmin-5.0, ymin-5.0, width+10.0, height+10.0);
- cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
+ cairo_set_source_rgb(cr, 0.0, 0.69, 1.0);
cairo_set_line_width(cr, 0.5);
cairo_stroke(cr);
}
diff --git a/src/presentation.c b/src/presentation.c
index c66507d..a603b0d 100644
--- a/src/presentation.c
+++ b/src/presentation.c
@@ -33,6 +33,8 @@
#include "slide_render.h"
#include "objects.h"
#include "stylesheet.h"
+#include "tool_text.h"
+#include "tool_select.h"
struct slide *add_slide(struct presentation *p, int pos)
@@ -212,6 +214,10 @@ struct presentation *new_presentation()
new->slide_width = 1024.0;
new->slide_height = 768.0;
+ new->select_tool = initialise_select_tool();
+ new->text_tool = initialise_text_tool();
+ new->cur_tool = new->select_tool;
+
/* Add one blank slide and view it */
new->num_slides = 0;
new->slides = NULL;
diff --git a/src/presentation.h b/src/presentation.h
index a654978..2685f86 100644
--- a/src/presentation.h
+++ b/src/presentation.h
@@ -46,10 +46,17 @@ struct slide
};
-enum tool
+struct toolinfo
{
- TOOL_SELECT,
- TOOL_TEXT,
+ void (*click_create)(struct presentation *p, struct toolinfo *tip,
+ double x, double y);
+ void (*click_select)(struct presentation *p, struct toolinfo *tip,
+ double x, double y);
+ void (*create_default)(struct presentation *p, struct style *sty);
+ void (*select)(struct object *o, struct toolinfo *tip);
+ void (*deselect)(struct object *o, struct toolinfo *tip);
+ void (*drag_object)(struct toolinfo *tip, struct presentation *p,
+ struct object *o, double x, double y);
};
@@ -59,6 +66,9 @@ struct presentation
char *filename;
int completely_empty;
+ struct toolinfo *select_tool;
+ struct toolinfo *text_tool;
+
GtkWidget *window;
GtkWidget *drawingarea;
GtkUIManager *ui;
@@ -99,7 +109,7 @@ struct presentation
struct object *editing_object;
/* Tool status */
- enum tool tool;
+ struct toolinfo *cur_tool;
double drag_offs_x;
double drag_offs_y;
diff --git a/src/tool_select.c b/src/tool_select.c
new file mode 100644
index 0000000..2931372
--- /dev/null
+++ b/src/tool_select.c
@@ -0,0 +1,111 @@
+/*
+ * tool_sekect.c
+ *
+ * Colloquium - A tiny presentation program
+ *
+ * Copyright (c) 2011 Thomas White <taw@bitwiz.org.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "presentation.h"
+#include "objects.h"
+#include "mainwindow.h"
+
+
+struct select_toolinfo
+{
+ struct toolinfo base;
+ double drag_offs_x;
+ double drag_offs_y;
+};
+
+
+static void click_create(struct presentation *p, struct toolinfo *tip,
+ double x, double y)
+{
+ /* Do absolutely nothing */
+}
+
+
+static void create_default(struct presentation *p, struct style *sty)
+{
+ /* Do absolutely nothing */
+}
+
+
+static void click_select(struct presentation *p, struct toolinfo *tip,
+ double x, double y)
+{
+ struct select_toolinfo *ti = (struct select_toolinfo *)tip;
+ struct object *clicked = p->editing_object;
+
+ ti->drag_offs_x = clicked->x - x;
+ ti->drag_offs_y = clicked->y - y;
+}
+
+
+static void drag_object(struct toolinfo *tip, struct presentation *p,
+ struct object *o, double x, double y)
+{
+ struct select_toolinfo *ti = (struct select_toolinfo *)tip;
+
+ o->x = x + ti->drag_offs_x;
+ o->y = y + ti->drag_offs_y;
+
+ p->view_slide->object_seq++;
+
+ /* FIXME: Invalidate only the necessary region */
+ gdk_window_invalidate_rect(p->drawingarea->window,
+ NULL, FALSE);
+}
+
+
+static void select_object(struct object *o,struct toolinfo *tip)
+{
+ /* Do nothing */
+}
+
+
+static void deselect_object(struct object *o,struct toolinfo *tip)
+{
+ /* Do nothing */
+}
+
+
+struct toolinfo *initialise_select_tool()
+{
+ struct select_toolinfo *ti;
+
+ ti = malloc(sizeof(*ti));
+
+ ti->base.click_create = click_create;
+ ti->base.click_select = click_select;
+ ti->base.create_default = create_default;
+ ti->base.select = select_object;
+ ti->base.deselect = deselect_object;
+ ti->base.drag_object = drag_object;
+
+ return (struct toolinfo *)ti;
+}
diff --git a/src/tool_select.h b/src/tool_select.h
new file mode 100644
index 0000000..93aeb15
--- /dev/null
+++ b/src/tool_select.h
@@ -0,0 +1,34 @@
+/*
+ * tool_select.h
+ *
+ * Colloquium - A tiny presentation program
+ *
+ * Copyright (c) 2011 Thomas White <taw@bitwiz.org.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef TOOL_SELECT_H
+#define TOOL_SELECT_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+extern struct toolinfo *initialise_select_tool(void);
+
+
+#endif /* TOOL_SELECT_H */
diff --git a/src/tool_text.c b/src/tool_text.c
index 4881fec..46eb5a7 100644
--- a/src/tool_text.c
+++ b/src/tool_text.c
@@ -34,6 +34,11 @@
#include "mainwindow.h"
+struct text_toolinfo
+{
+ struct toolinfo base;
+};
+
void insert_text(struct object *o, char *t)
{
char *tmp;
@@ -159,23 +164,6 @@ void move_cursor_right(struct object *o)
}
-void position_caret(struct object *o, double x, double y)
-{
- int idx, trail;
- int xp, yp;
- gboolean v;
-
- assert(o->type == TEXT);
-
- xp = (x - o->x)*PANGO_SCALE;
- yp = (y - o->y)*PANGO_SCALE;
-
- v = pango_layout_xy_to_index(o->layout, xp, yp, &idx, &trail);
-
- o->insertion_point = idx+trail;
-}
-
-
static void calculate_size_from_style(struct object *o,
double *peright, double *pebottom,
double *pmw, double *pmh)
@@ -330,19 +318,36 @@ static void render_text_object(cairo_t *cr, struct object *o)
static void draw_caret(cairo_t *cr, struct object *o)
{
int line, xpos;
- double xposd;
+ double xposd, cx;
+ double clow, chigh;
+ const double t = 1.8;
assert(o->type == TEXT);
+
pango_layout_index_to_line_x(o->layout, o->insertion_point,
0, &line, &xpos);
xposd = xpos/PANGO_SCALE;
+ cx = o->x+xposd;
+ clow = o->y;
+ chigh = o->y+o->bb_height;
+
+ cairo_move_to(cr, cx, clow);
+ cairo_line_to(cr, cx, chigh);
+
+ cairo_move_to(cr, cx-t, clow-t);
+ cairo_line_to(cr, cx, clow);
+ cairo_move_to(cr, cx+t, clow-t);
+ cairo_line_to(cr, cx, clow);
- cairo_move_to(cr, o->x+xposd, o->y);
- cairo_line_to(cr, o->x+xposd, o->y+o->bb_height);
- cairo_set_source_rgb(cr, 1.0, 0.5, 0.0);
- cairo_set_line_width(cr, 2.0);
+ cairo_move_to(cr, cx-t, chigh+t);
+ cairo_line_to(cr, cx, chigh);
+ cairo_move_to(cr, cx+t, chigh+t);
+ cairo_line_to(cr, cx, chigh);
+
+ cairo_set_source_rgb(cr, 0.86, 0.0, 0.0);
+ cairo_set_line_width(cr, 1.0);
cairo_stroke(cr);
}
@@ -376,3 +381,80 @@ struct object *add_text_object(struct slide *s, double x, double y,
return new;
}
+
+
+static void click_create(struct presentation *p, struct toolinfo *tip,
+ double x, double y)
+{
+ struct object *n;
+
+ /* FIXME: Insert ESP here and possibly select a different style */
+ n = add_text_object(p->view_slide, x, y, p->ss->styles[0]);
+ p->editing_object = n;
+}
+
+
+static void click_select(struct presentation *p, struct toolinfo *tip,
+ double x, double y)
+{
+ int xp, yp;
+ gboolean v;
+ struct object *o = p->editing_object;
+ int idx, trail;
+
+ assert(o->type == TEXT);
+
+ xp = (x - o->x)*PANGO_SCALE;
+ yp = (y - o->y)*PANGO_SCALE;
+
+ v = pango_layout_xy_to_index(o->layout, xp, yp, &idx, &trail);
+
+ o->insertion_point = idx+trail;
+}
+
+
+
+static void drag_object(struct toolinfo *tip, struct presentation *p,
+ struct object *o, double x, double y)
+{
+ /* Do nothing */
+}
+
+
+static void create_default(struct presentation *p, struct style *sty)
+{
+ struct object *n;
+
+ n = add_text_object(p->view_slide, 0.0, 0.0, sty);
+ p->editing_object = n;
+
+}
+
+
+static void select_object(struct object *o,struct toolinfo *tip)
+{
+ /* Do nothing */
+}
+
+
+static void deselect_object(struct object *o,struct toolinfo *tip)
+{
+ /* Do nothing */
+}
+
+
+struct toolinfo *initialise_text_tool()
+{
+ struct text_toolinfo *ti;
+
+ ti = malloc(sizeof(*ti));
+
+ ti->base.click_create = click_create;
+ ti->base.click_select = click_select;
+ ti->base.create_default = create_default;
+ ti->base.select = select_object;
+ ti->base.deselect = deselect_object;
+ ti->base.drag_object = drag_object;
+
+ return (struct toolinfo *)ti;
+}
diff --git a/src/tool_text.h b/src/tool_text.h
index cd190ae..1ff512c 100644
--- a/src/tool_text.h
+++ b/src/tool_text.h
@@ -27,13 +27,12 @@
#include <config.h>
#endif
-extern struct object *add_text_object(struct slide *s, double x, double y,
- struct style *sty);
extern void insert_text(struct object *o, char *t);
extern void handle_text_backspace(struct object *o);
extern void move_cursor_left(struct object *o);
extern void move_cursor_right(struct object *o);
-extern void position_caret(struct object *o, double x, double y);
+
+extern struct toolinfo *initialise_text_tool(void);
#endif /* TOOL_TEXT_H */