Mejor sistema de llamadas a eventos herramientas
authordanigm <danigm>
Sun, 14 Feb 2010 13:32:41 +0000 (13:32 +0000)
committerdanigm <danigm@aa302d1f-72b1-406a-902b-8593ca2b2744>
Sun, 14 Feb 2010 13:32:41 +0000 (13:32 +0000)
He mejorado el sistema de llamadas a funciones de cada herramienta
generalizando la llamada y evitando así tener un switch por cada
evento que se quiere llamar. Ahora sólo hay que llamar a una función
diciendo qué herramienta es y pasandole los datos necesarios.

git-svn-id: https://forja.rediris.es/svn/cusl4-tbo@42 aa302d1f-72b1-406a-902b-8593ca2b2744

16 files changed:
configure.ac
data/Makefile.am
data/doodle/Makefile.am [new file with mode: 0644]
data/doodle/doodle1/body/doodle1.svg [new file with mode: 0644]
src/Makefile.am
src/doodle-tool.c
src/doodle-tool.h
src/doodle-treeview.c [new file with mode: 0644]
src/doodle-treeview.h [new file with mode: 0644]
src/frame-tool.c
src/frame-tool.h
src/selector-tool.c
src/selector-tool.h
src/ui-drawing.c
src/ui-toolbar.c
src/ui-toolbar.h

index b862d1a..f12d22f 100644 (file)
@@ -28,6 +28,7 @@ AC_CONFIG_FILES([
     Makefile
     src/Makefile
     data/Makefile
+    data/doodle/Makefile
     po/Makefile.in
 ])
 
index 2b22bf1..968f192 100644 (file)
@@ -1,3 +1,5 @@
+SUBDIRS = doodle
+
 tbodir = $(datadir)/tbo
 tbo_DATA = *.png
 
@@ -10,4 +12,4 @@ tboicon_DATA = icons/*.svg
 EXTRA_DIST = \
        *.png \
        ui/*.xml \
-       icons/*.svg 
+       icons/*.svg
diff --git a/data/doodle/Makefile.am b/data/doodle/Makefile.am
new file mode 100644 (file)
index 0000000..77bd9d7
--- /dev/null
@@ -0,0 +1,5 @@
+doodle1bodydir = $(datadir)/tbo/doodle/doodle1/body
+doodle1body_DATA = doodle1/body/*.svg
+
+EXTRA_DIST = \
+       doodle1/body/*.svg
diff --git a/data/doodle/doodle1/body/doodle1.svg b/data/doodle/doodle1/body/doodle1.svg
new file mode 100644 (file)
index 0000000..176c9b8
--- /dev/null
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="103.29725"
+   height="267.52408"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="Documento nuevo 1">
+  <defs
+     id="defs4">
+    <inkscape:path-effect
+       effect="spiro"
+       id="path-effect3592"
+       is_visible="true" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective10" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.3830531"
+     inkscape:cx="51.648624"
+     inkscape:cy="133.76204"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1024"
+     inkscape:window-height="575"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Capa 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-234.95757,-339.65177)">
+    <path
+       sodipodi:type="arc"
+       style="fill:#2e3436;fill-opacity:1;stroke:none"
+       id="path2816"
+       sodipodi:cx="288.73358"
+       sodipodi:cy="391.173"
+       sodipodi:rx="51.521236"
+       sodipodi:ry="51.521236"
+       d="m 340.25482,391.173 c 0,28.4544 -23.06685,51.52124 -51.52124,51.52124 -28.45439,0 -51.52123,-23.06684 -51.52123,-51.52124 0,-28.45439 23.06684,-51.52123 51.52123,-51.52123 28.45439,0 51.52124,23.06684 51.52124,51.52123 z"
+       transform="translate(-2,0)" />
+    <path
+       style="fill:#2e3436;fill-opacity:1;stroke:none"
+       d="m 272.54338,432.44414 c -3.26678,54.27381 -30.2716,154.15483 -23.59199,167.97003 4.74993,7.03354 11.42798,4.34999 15.54868,1.38243 11.96786,-8.61876 -0.27415,-51.53162 6.43544,-65.37095 7.84845,2.36025 10.54844,2.68632 20.53698,-0.78229 9.98854,-3.46861 2.15346,60.90645 6.34488,66.17201 7.28399,9.15066 20.88862,5.58048 19.62332,-3.16161 -6.18176,-59.01938 -23.37853,-113.52319 -18.11559,-170.9358 l -26.78172,4.72618 z"
+       id="path3594"
+       sodipodi:nodetypes="ccsczsccc" />
+    <path
+       style="fill:#2e3436;fill-opacity:1;stroke:none"
+       d="m 273.04683,437.18561 c -6.19208,18.48097 -11.309,37.51722 -19.87607,55.00051 -4.22731,8.6269 -11.21282,15.66347 -17.16719,23.22112 -3.55884,13.71967 2.43868,13.1202 10.81668,8.9539 7.67915,-12.11497 15.20144,-23.95777 20.2561,-37.05823 4.63538,-12.0138 6.80312,-25.28528 8.81403,-38.28458"
+       id="path3600"
+       sodipodi:nodetypes="csccsc" />
+    <path
+       sodipodi:nodetypes="csccsc"
+       id="path3604"
+       d="m 295.80112,437.18561 c 6.19208,18.48097 11.309,37.51722 19.87607,55.00051 4.22731,8.6269 11.21282,15.66347 17.16719,23.22112 3.55884,13.71967 -2.43868,13.1202 -10.81668,8.9539 -7.67915,-12.11497 -15.20144,-23.95777 -20.2561,-37.05823 -4.63538,-12.0138 -6.80312,-25.28528 -8.81403,-38.28458"
+       style="fill:#2e3436;fill-opacity:1;stroke:none" />
+  </g>
+</svg>
index 867f405..f25c49b 100644 (file)
@@ -22,6 +22,7 @@ tbo_SOURCES = \
        selector-tool.c \
        doodle-tool.c \
        custom-stock.c \
+       doodle-treeview.c \
        tbo-window.h \
        comic.h \
        comic-new-dialog.h \
@@ -34,6 +35,7 @@ tbo_SOURCES = \
        frame-tool.h \
        selector-tool.h \
        doodle-tool.h \
+       doodle-treeview.h \
        custom-stock.h
 
 tbo_CFLAGS = @GTK_CFLAGS@ \
index dc4eced..fa3d5cf 100644 (file)
@@ -7,6 +7,19 @@
 #include "frame.h"
 #include "comic.h"
 #include "ui-drawing.h"
+#include "doodle-treeview.h"
+
+void
+doodle_tool_on_select (TboWindow *tbo)
+{
+    GtkWidget *tree;
+
+    tree = doodle_setup_tree ();
+    gtk_widget_show_all (tree);
+
+    tbo_empty_tool_area (tbo);
+    gtk_container_add (GTK_CONTAINER (tbo->toolarea), tree);
+}
 
 void doodle_tool_on_move (GtkWidget *widget, GdkEventMotion *event, TboWindow *tbo){}
 void doodle_tool_on_click (GtkWidget *widget, GdkEventButton *event, TboWindow *tbo){}
index f03f8de..4352c1e 100644 (file)
@@ -5,6 +5,7 @@
 #include <cairo.h>
 #include "tbo-window.h"
 
+void doodle_tool_on_select (TboWindow *tbo);
 void doodle_tool_on_move (GtkWidget *widget, GdkEventMotion *event, TboWindow *tbo);
 void doodle_tool_on_click (GtkWidget *widget, GdkEventButton *event, TboWindow *tbo);
 void doodle_tool_on_release (GtkWidget *widget, GdkEventButton *event, TboWindow *tbo);
diff --git a/src/doodle-treeview.c b/src/doodle-treeview.c
new file mode 100644 (file)
index 0000000..bf2a18b
--- /dev/null
@@ -0,0 +1,91 @@
+#include <gtk/gtk.h>
+#include "doodle-treeview.h"
+
+enum
+{
+   TITLE_COLUMN,
+   AUTHOR_COLUMN,
+   CHECKED_COLUMN,
+   N_COLUMNS
+};
+
+void
+populate_tree_model(GtkTreeStore *store)
+{
+    GtkTreeIter iter;
+    GtkTreeIter iter2;
+
+    /* Append a row and fill in some data */
+    gtk_tree_store_append (store, &iter, NULL);
+    gtk_tree_store_set (store, &iter,
+                    TITLE_COLUMN, "titulo",
+                    AUTHOR_COLUMN, "autor",
+                    CHECKED_COLUMN, TRUE,
+                    -1);
+    gtk_tree_store_append (store, &iter2, &iter);
+    gtk_tree_store_set (store, &iter2,
+                    TITLE_COLUMN, "titulo2",
+                    AUTHOR_COLUMN, "autor2",
+                    CHECKED_COLUMN, FALSE,
+                    -1);
+
+}
+
+GtkWidget *
+doodle_setup_tree (void)
+{
+   GtkTreeStore *store;
+   GtkWidget *tree;
+   GtkTreeViewColumn *column;
+   GtkCellRenderer *renderer;
+
+   /* Create a model.  We are using the store model for now, though we
+    * could use any other GtkTreeModel */
+   store = gtk_tree_store_new (N_COLUMNS,
+                               G_TYPE_STRING,
+                               G_TYPE_STRING,
+                               G_TYPE_BOOLEAN);
+
+   /* custom function to fill the model with data */
+   populate_tree_model (store);
+
+   /* Create a view */
+   tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
+
+   /* The view now holds a reference.  We can get rid of our own
+    * reference */
+   g_object_unref (G_OBJECT (store));
+
+   /* Create a cell render and arbitrarily make it red for demonstration
+    * purposes */
+   renderer = gtk_cell_renderer_text_new ();
+   g_object_set (G_OBJECT (renderer),
+                 "foreground", "red",
+                 NULL);
+
+   /* Create a column, associating the "text" attribute of the
+    * cell_renderer to the first column of the model */
+   column = gtk_tree_view_column_new_with_attributes ("Author", renderer,
+                                                      "text", AUTHOR_COLUMN,
+                                                      NULL);
+
+   /* Add the column to the view. */
+   gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
+
+   /* Second column.. title of the book. */
+   renderer = gtk_cell_renderer_text_new ();
+   column = gtk_tree_view_column_new_with_attributes ("Title",
+                                                      renderer,
+                                                      "text", TITLE_COLUMN,
+                                                      NULL);
+   gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
+
+   /* Last column.. whether a book is checked out. */
+   renderer = gtk_cell_renderer_toggle_new ();
+   column = gtk_tree_view_column_new_with_attributes ("Checked out",
+                                                      renderer,
+                                                      "active", CHECKED_COLUMN,
+                                                      NULL);
+   gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
+   return tree;
+}
diff --git a/src/doodle-treeview.h b/src/doodle-treeview.h
new file mode 100644 (file)
index 0000000..a8acbec
--- /dev/null
@@ -0,0 +1,4 @@
+#include <gtk/gtk.h>
+
+GtkWidget * doodle_setup_tree (void);
+
index 5dbaecf..eee594c 100644 (file)
@@ -19,6 +19,10 @@ min (int x, int y)
 }
 
 void
+frame_tool_on_select (TboWindow *tbo)
+{}
+
+void
 frame_tool_on_move (GtkWidget *widget,
         GdkEventMotion *event,
         TboWindow *tbo)
@@ -79,6 +83,10 @@ frame_tool_on_release (GtkWidget *widget,
     TMP_FRAME = NULL;
 }
 
+void
+frame_tool_on_key (GtkWidget *widget, GdkEventKey *event, TboWindow *tbo)
+{}
+
 Frame *
 get_tmp_frame (){
     return TMP_FRAME;
index 369fee8..afaafa3 100644 (file)
@@ -6,9 +6,11 @@
 #include "tbo-window.h"
 #include "frame.h"
 
+void frame_tool_on_select (TboWindow *tbo);
 void frame_tool_on_move (GtkWidget *widget, GdkEventMotion *event, TboWindow *tbo);
 void frame_tool_on_click (GtkWidget *widget, GdkEventButton *event, TboWindow *tbo);
 void frame_tool_on_release (GtkWidget *widget, GdkEventButton *event, TboWindow *tbo);
+void frame_tool_on_key (GtkWidget *widget, GdkEventKey *event, TboWindow *tbo);
 void frame_tool_drawing (cairo_t *cr);
 Frame * get_tmp_frame ();
 
index bfbe31b..4a1da71 100644 (file)
@@ -132,6 +132,10 @@ over_resizer (Frame *frame, int x, int y)
 }
 
 void
+selector_tool_on_select (TboWindow *tbo)
+{}
+
+void
 selector_tool_on_move (GtkWidget *widget,
         GdkEventMotion *event,
         TboWindow *tbo)
index c40a4a5..b7bdad1 100644 (file)
@@ -5,11 +5,13 @@
 #include <cairo.h>
 #include "tbo-window.h"
 
+void selector_tool_on_select (TboWindow *tbo);
 void selector_tool_on_move (GtkWidget *widget, GdkEventMotion *event, TboWindow *tbo);
 void selector_tool_on_click (GtkWidget *widget, GdkEventButton *event, TboWindow *tbo);
 void selector_tool_on_release (GtkWidget *widget, GdkEventButton *event, TboWindow *tbo);
 void selector_tool_on_key (GtkWidget *widget, GdkEventKey *event, TboWindow *tbo);
 void selector_tool_drawing (cairo_t *cr);
+
 Frame *selector_tool_get_selected_frame ();
 void frame_view_on_click (GtkWidget *widget, GdkEventButton *event, TboWindow *tbo);
 void page_view_on_click (GtkWidget *widget, GdkEventButton *event, TboWindow *tbo);
index 2181f20..607b111 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <cairo.h>
 #include <gtk/gtk.h>
+#include <stdlib.h>
 #include <glib/gi18n.h>
 
 #include "ui-toolbar.h"
@@ -26,27 +27,17 @@ on_key_cb (GtkWidget    *widget,
            TboWindow    *tbo)
 {
     enum Tool tool;
+    void **data = malloc (sizeof(void *)*3);
+    data[0] = widget;
+    data[1] = event;
+    data[2] = tbo;
 
     tool = get_selected_tool ();
-    switch (tool)
-    {
-        case SELECTOR:
-            selector_tool_on_key (widget, event, tbo);
-            update_drawing (tbo);
-            tbo_window_update_status (tbo, 0, 0);
-            break;
-
-        case DOODLE:
-            doodle_tool_on_key (widget, event, tbo);
-            update_drawing (tbo);
-            tbo_window_update_status (tbo, 0, 0);
-            break;
-
-        case NONE:
-        default:
-            break;
-    }
+    tool_signal (tool, TOOL_KEY, data);
+    free (data);
 
+    update_drawing (tbo);
+    tbo_window_update_status (tbo, 0, 0);
     return FALSE;
 }
 
@@ -97,25 +88,7 @@ on_expose_cb(GtkWidget      *widget,
     // Update drawing helpers
 
     tool = get_selected_tool ();
-    // different behavior for each tool
-    switch (tool)
-    {
-        case FRAME:
-            frame_tool_drawing (cr);
-            break;
-
-        case SELECTOR:
-            selector_tool_drawing (cr);
-            break;
-
-        case DOODLE:
-            doodle_tool_drawing (cr);
-            break;
-
-        case NONE:
-        default:
-            break;
-    }
+    tool_signal (tool, TOOL_DRAWING, cr);
 
     // TBO rulz text example :P
     /*
@@ -142,31 +115,16 @@ on_move_cb (GtkWidget     *widget,
 {
 
     enum Tool tool;
+    void **data = malloc (sizeof(void *)*3);
+    data[0] = widget;
+    data[1] = event;
+    data[2] = tbo;
 
     tool = get_selected_tool ();
-    // different behavior for each tool
-    switch (tool)
-    {
-        case FRAME:
-            frame_tool_on_move (widget, event, tbo);
-            update_drawing (tbo);
-            break;
-
-        case SELECTOR:
-            selector_tool_on_move (widget, event, tbo);
-            update_drawing (tbo);
-            break;
-
-        case DOODLE:
-            doodle_tool_on_move (widget, event, tbo);
-            update_drawing (tbo);
-            break;
-
-        case NONE:
-        default:
-            break;
-    }
+    tool_signal (tool, TOOL_MOVE, data);
+    free (data);
 
+    update_drawing (tbo);
     tbo_window_update_status (tbo, (int)event->x, (int)event->y);
     return FALSE;
 }
@@ -177,66 +135,36 @@ on_click_cb (GtkWidget    *widget,
            TboWindow      *tbo)
 {
     enum Tool tool;
+    void **data = malloc (sizeof(void *)*3);
+    data[0] = widget;
+    data[1] = event;
+    data[2] = tbo;
 
     tool = get_selected_tool ();
-    // different behavior for each tool
-    switch (tool)
-    {
-        case FRAME:
-            frame_tool_on_click (widget, event, tbo);
-            update_drawing (tbo);
-            break;
-
-        case SELECTOR:
-            selector_tool_on_click (widget, event, tbo);
-            update_drawing (tbo);
-            break;
-
-        case DOODLE:
-            doodle_tool_on_click (widget, event, tbo);
-            update_drawing (tbo);
-            break;
-
-        case NONE:
-        default:
-            break;
-    }
+    tool_signal (tool, TOOL_CLICK, data);
+    free (data);
 
+    update_drawing (tbo);
     tbo_window_update_status (tbo, (int)event->x, (int)event->y);
     return FALSE;
 }
 
 gboolean
 on_release_cb (GtkWidget    *widget,
-           GdkEventButton *event,
-           TboWindow      *tbo)
+           GdkEventButton   *event,
+           TboWindow        *tbo)
 {
     enum Tool tool;
+    void **data = malloc (sizeof(void *)*3);
+    data[0] = widget;
+    data[1] = event;
+    data[2] = tbo;
 
     tool = get_selected_tool ();
-    // different behavior for each tool
-    switch (tool)
-    {
-        case FRAME:
-            frame_tool_on_release (widget, event, tbo);
-            update_drawing (tbo);
-            break;
-
-        case SELECTOR:
-            selector_tool_on_release (widget, event, tbo);
-            update_drawing (tbo);
-            break;
-
-        case DOODLE:
-            doodle_tool_on_release (widget, event, tbo);
-            update_drawing (tbo);
-            break;
-
-        case NONE:
-        default:
-            break;
-    }
+    tool_signal (tool, TOOL_RELEASE, data);
+    free (data);
 
+    update_drawing (tbo);
     tbo_window_update_status (tbo, (int)event->x, (int)event->y);
     return FALSE;
 }
index 195db3e..a8b6b61 100644 (file)
 #include "custom-stock.h"
 #include "ui-drawing.h"
 
+#include "frame-tool.h"
+#include "selector-tool.h"
+#include "doodle-tool.h"
+
 static int SELECTED_TOOL = NONE;
 static GtkActionGroup *ACTION_GROUP;
 
+static ToolStruct TOOLS[] =
+{
+    {FRAME,
+     frame_tool_on_select,
+     frame_tool_on_move,
+     frame_tool_on_click,
+     frame_tool_on_release,
+     frame_tool_on_key,
+     frame_tool_drawing},
+
+    {SELECTOR,
+     selector_tool_on_select,
+     selector_tool_on_move,
+     selector_tool_on_click,
+     selector_tool_on_release,
+     selector_tool_on_key,
+     selector_tool_drawing},
+
+    {DOODLE,
+     doodle_tool_on_select,
+     doodle_tool_on_move,
+     doodle_tool_on_click,
+     doodle_tool_on_release,
+     doodle_tool_on_key,
+     doodle_tool_drawing},
+};
+
 typedef struct
 {
     enum Tool tool;
@@ -23,6 +54,7 @@ typedef struct
 
 void unselect (enum Tool tool);
 gboolean select_tool (GtkAction *action, TboWindow *tbo);
+void update_toolbar (TboWindow *tbo);
 
 enum Tool
 get_selected_tool ()
@@ -31,10 +63,13 @@ get_selected_tool ()
 }
 
 void
-set_selected_tool (enum Tool tool)
+set_selected_tool (enum Tool tool, TboWindow *tbo)
 {
     unselect (SELECTED_TOOL);
     SELECTED_TOOL = tool;
+
+    tool_signal (tool, TOOL_SELECT, tbo);
+    update_toolbar (tbo);
 }
 
 void
@@ -222,10 +257,9 @@ select_tool (GtkAction *action, TboWindow *tbo)
     }
 
     if (gtk_toggle_action_get_active (toggle_action))
-        set_selected_tool (tool);
+        set_selected_tool (tool, tbo);
     else
-        set_selected_tool (NONE);
-    update_toolbar (tbo);
+        set_selected_tool (NONE, tbo);
     tbo_window_update_status (tbo, 0, 0);
     return FALSE;
 }
@@ -259,3 +293,50 @@ GtkWidget *generate_toolbar (TboWindow *window){
     return toolbar;
 }
 
+void
+tool_signal (enum Tool tool, enum ToolSignal signal, gpointer data)
+{
+    int i;
+    ToolStruct *toolstruct = NULL;
+    void **pdata;
+
+    for (i=0; i<G_N_ELEMENTS (TOOLS); i++)
+    {
+        if (tool == TOOLS[i].tool)
+        {
+            toolstruct = &TOOLS[i];
+            break;
+        }
+    }
+
+    if (toolstruct)
+    {
+        switch (signal)
+        {
+            case TOOL_SELECT:
+                toolstruct->tool_on_select(data);
+                break;
+            case TOOL_MOVE:
+                pdata = data;
+                toolstruct->tool_on_move (pdata[0], pdata[1], pdata[2]);
+                break;
+            case TOOL_CLICK:
+                pdata = data;
+                toolstruct->tool_on_click (pdata[0], pdata[1], pdata[2]);
+                break;
+            case TOOL_RELEASE:
+                pdata = data;
+                toolstruct->tool_on_release (pdata[0], pdata[1], pdata[2]);
+                break;
+            case TOOL_KEY:
+                pdata = data;
+                toolstruct->tool_on_key (pdata[0], pdata[1], pdata[2]);
+                break;
+            case TOOL_DRAWING:
+                toolstruct->tool_drawing (data);
+                break;
+            default:
+                break;
+        }
+    }
+}
index 9a53aa9..271918c 100644 (file)
@@ -4,6 +4,16 @@
 #include <gtk/gtk.h>
 #include "tbo-window.h"
 
+enum ToolSignal
+{
+    TOOL_SELECT,
+    TOOL_MOVE,
+    TOOL_CLICK,
+    TOOL_RELEASE,
+    TOOL_KEY,
+    TOOL_DRAWING,
+};
+
 enum Tool
 {
     NONE,
@@ -12,8 +22,21 @@ enum Tool
     DOODLE,
 };
 
+typedef struct
+{
+    enum Tool tool;
+    void (*tool_on_select) (TboWindow *);
+    void (*tool_on_move) (GtkWidget *, GdkEventMotion *, TboWindow *);
+    void (*tool_on_click) (GtkWidget *, GdkEventButton *, TboWindow *);
+    void (*tool_on_release) (GtkWidget *, GdkEventButton *, TboWindow *);
+    void (*tool_on_key) (GtkWidget *, GdkEventKey *, TboWindow *);
+    void (*tool_drawing) (cairo_t *cr);
+} ToolStruct;
+
+void tool_signal (enum Tool tool, enum ToolSignal signal, gpointer data);
+
 enum Tool get_selected_tool ();
-void set_selected_tool (enum Tool tool);
+void set_selected_tool (enum Tool tool, TboWindow *tbo);
 
 GtkWidget *generate_toolbar (TboWindow *window);