Re: signals, objects, user_data and stuff.



>>>>> "J" == Jeroen Benckhuijsen <jeroen@benck.demon.nl> writes:

 J> Add to the connector a list of connected points (identified by a
 J> number) check within the signal callback if the point is connected
 J> and move it if it is.

I'm not sure I follow you here, at least the way I read the above it
solves another problem than the one I have.  My problem is not that
when I move the connector I want to move points along, rather it is
when I move either an endpoint or a bend-point, I want to update the
connector.

Let me give an example.  Consider the drawing below.  The boxes are my
nodes, the line is my connector.  The '+' on the connector is a
bend-point.


 +---+
 |   |
 |   +-----------------+
 |   |                 |
 +---+                 |
                       |
                     +-+-+
                     |   |
                     +---+


The boxes are objects with a "moved" signal

  node_signals[MOVED] =
    gtk_signal_new ("moved",
                    GTK_RUN_FIRST,
                    object_class->type,
                    0, /* no handler, we're only interested in the signal */
                    marshal_NONE__DOUBLE_DOUBLE,
                    GTK_TYPE_NONE, 2, GTK_TYPE_DOUBLE, GTK_TYPE_DOUBLE);

which is emitted when I move them

void
gcpn_canvasnode_move (GcpnCanvasnode *node,
                      gdouble         dx,
                      gdouble         dy)
{
  gnome_canvas_item_move (GNOME_CANVAS_ITEM (node), dx, dy);
  gtk_signal_emit (GTK_OBJECT (node), node_signals[MOVED], dx, dy);
}

The connector(s) linked to a node listens for this signal and updates
its endpoint when the node moves:

  gtk_signal_connect_object_while_alive (GTK_OBJECT (node1), "moved",
                                         GTK_SIGNAL_FUNC (node1_moved),
                                         GTK_OBJECT (connector));
  gtk_signal_connect_object_while_alive (GTK_OBJECT (node2), "moved",
                                         GTK_SIGNAL_FUNC (node2_moved),
                                         GTK_OBJECT (connector));

where 'node1' is the first endpoint of the connector and 'node2' is
the second.  The callbacks looks like this

static void
conn_moved (GnomeCanvasLine *line, gdouble dx, gdouble dy, int index)
{
  GnomeCanvasPoints *points;

  g_return_if_fail (index < line->num_points);

  points = read_line_points (line); /* reads points and compensate for
                                       arrow heads */

  points->coords[2*index] += dx;
  points->coords[2*index+1] += dy;
  
  gnome_canvas_item_set (GNOME_CANVAS_ITEM (line), "points", points, NULL);
  gnome_canvas_points_free (points);
}


static void
node1_moved (GnomeCanvasLine *line, gdouble dx, gdouble dy)
{
  conn_moved (line, dx, dy, 0);
}
static void
node2_moved (GnomeCanvasLine *line, gdouble dx, gdouble dy)
{
  conn_moved (line, dx, dy, line->num_points - 1);
}

so by calling 'gcpn_canvasnode_move (node, dx, dy)' the node 'node'
will be moved by (dx,dy), and all connectors linked to the node will
be updated.

          Node          Conn1    Conn2    Conn3
           |              |        |        |
 move ---->+              |        |        |
           |              |        |        |
           +-- moved ---->+        |        |
           +-- moved ------------->+        |
           +-- moved ---------------------->+
           |              |        |        |


With this design I don't have to worry about keeping track of
connectors in the individual nodes so there is virtually no
bookkeeping.

The problem now is the bend points.  When I move a bend-point I simply
want to call 'conn_moved' with the right index, i.e. in the example
above, if I want to move the bend point what I want is to update the
middle point of the line, i.e. to call 'conn_moved' with index 1.
(The first endpoint has index 0, the second endpoint has index 2, the
bend point has index 1).

My thoughts were that I could do this by adding a small 'node' for
each bend-point

 +---+
 |   |
 |   +----------------++  <= new "bend-point" node
 |   |                ++
 +---+                 |
                       |
                     +-+-+
                     |   |
                     +---+

and connect to its "moved" signal.  But then I want to pass the index
(in this case 1) along with the signal

  gtk_signal_connect_object_with_data_while_alive
                                        (GTK_OBJECT (bendpoint), "moved",
                                         GTK_SIGNAL_FUNC (conn_moved_cb),
                                         GTK_OBJECT (connector)
                                         GINT_TO_POINTER (1));

so the callback could behave like

static void
conn_moved_cb (GnomeCanvasLine *line,
               gdouble dx, gdouble dy,
               GtkObject *dummy,
               int index)
{
  conn_moved (line, dx, dy, index);
}

or something similar.

Of course, I _could_ hack this by associating the bend-points to the
connector and then lookup the index of the node object

static void
conn_moved_cb (GnomeCanvasLine *line,
               gdouble dx, gdouble dy,
               GtkObject *node)
{
  GList *bend_points = gtk_object_get_data (line, "bend-points");
  conn_moved (line, dx, dy, g_list_index (bend_points, node));
}

This is probably what I'll do, I was just hoping for a way to actually
pass the index along with the call, but hey, life's tough.

        /mailund



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]