From f4ff26c955729f8b068c64fff806216eb6e34bd4 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 3 Oct 2011 12:09:50 +0200 Subject: Use dispatch tables for tool functions --- src/mainwindow.c | 100 ++++++++++++++++++------------------------ src/presentation.c | 6 +++ src/presentation.h | 18 ++++++-- src/tool_select.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++ src/tool_select.h | 34 +++++++++++++++ src/tool_text.c | 126 +++++++++++++++++++++++++++++++++++++++++++---------- src/tool_text.h | 5 +-- 7 files changed, 313 insertions(+), 87 deletions(-) create mode 100644 src/tool_select.c create mode 100644 src/tool_select.h (limited to 'src') 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) && (xslide_width) - && (y>0.0) && (yslide_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 + * + * 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 . + * + */ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#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 + * + * 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 . + * + */ + +#ifndef TOOL_SELECT_H +#define TOOL_SELECT_H + +#ifdef HAVE_CONFIG_H +#include +#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 #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 */ -- cgit v1.2.3