Exemplo n.º 1
0
static int windowToCanvas( Tcl_Interp *interp,
      int objc, Tcl_Obj * const objv[], CanvasParams *params, int reverse )
{
   Tcl_Obj *resList;
   int     noCoords, n;
   if( objc != 3 )
   {
      Tcl_WrongNumArgs( interp, 2, objv, 
            /* canvas windowToCanvas */
            "list-of-coordinates ?option val ...?" );
      return TCL_ERROR;
   }
   /* TODO  
         -only [xy]:          only x, y coordinates
         -pairs [true|false]: list of coordinate pairs (lists)
   */
   if( Tcl_ListObjLength( interp, objv[2], &noCoords ) != TCL_OK
         || ( noCoords % 2 ) )
   {
      Tcl_SetResult( interp, 
            "size of list-of-coordinates must be even", 
            TCL_STATIC );
      return TCL_ERROR;
   }
   resList = Tcl_NewListObj( 0, NULL );
   for( n = 0; n < noCoords; n += 2 )
   {
      Tcl_Obj *tp;
      double xw, yw, x, y;
      int ret = Tcl_ListObjIndex( interp, objv[2], n, &tp );
      if( ret == TCL_OK )
         ret = Tcl_GetDoubleFromObj( interp, tp, &xw );
      if( ret == TCL_OK )
         ret = Tcl_ListObjIndex( interp, objv[2], n + 1, &tp );
      if( ret == TCL_OK )
         ret = Tcl_GetDoubleFromObj( interp, tp, &yw );

      if( ret != TCL_OK )
      {
         Tcl_DecrRefCount( resList );  /* FIXME: is this correct? */
         return TCL_ERROR;
      }
      if( reverse )
         gnome_canvas_world_to_window( params->canvas, xw, yw, &x, &y );
      else
         gnome_canvas_window_to_world( params->canvas, xw, yw, &x, &y );
      Tcl_ListObjAppendElement( interp, resList, Tcl_NewDoubleObj( x ) );
      Tcl_ListObjAppendElement( interp, resList, Tcl_NewDoubleObj( y ) );
   }
   Tcl_SetObjResult( interp, resList );

   return TCL_OK;
}
Exemplo n.º 2
0
void
ghack_handle_button_press(GtkWidget *widget, GdkEventButton *event,
                          gpointer data)
{
    GHClick *click;
    double x1, y1;

    if (event->type != GDK_BUTTON_PRESS)
        return;

    gnome_canvas_window_to_world(GNOME_CANVAS(widget), event->x, event->y,
                                 &x1, &y1);
    /*
        g_message("I got a click at %f,%f with button %d \n",
                x1, y1, event->button);
    */

    /* We allocate storage here, so we need to remember if (g_numClicks>0)
     * to blow this away when closing the app using something like
     *  while (g_clickBuffer)
     *       {
     *		g_free((GHClick)g_clickBuffer->data);
     *          g_clickBuffer = g_clickBuffer->next;
     *       }
     *  g_list_free( g_clickBuffer );
     *
     */
    click = g_new(GHClick, 1);

    click->x = (int) x1 / ghack_glyph_width();
    click->y = (int) y1 / ghack_glyph_height();
    click->mod = (event->button == 1) ? CLICK_1 : CLICK_2;

    g_clickBuffer = g_list_prepend(g_clickBuffer, click);
    /* Could use g_list_length(), but it is stupid and just
     * traverses the list while counting, so we'll just do
     * the counting ourselves in advance. */
    g_numClicks++;
}
Exemplo n.º 3
0
// paste xournal native data
void clipboard_paste_from_xournal(GtkSelectionData *sel_data)
{
  unsigned char *p;
  int nitems, npts, i, len;
  struct Item *item;
  double hoffset, voffset, cx, cy;
  double *pf;
  int sx, sy, wx, wy;
  
  reset_selection();
  
  ui.selection = g_new(struct Selection, 1);
  p = sel_data->data + sizeof(int);
  g_memmove(&nitems, p, sizeof(int)); p+= sizeof(int);
  ui.selection->type = ITEM_SELECTRECT;
  ui.selection->layer = ui.cur_layer;
  g_memmove(&ui.selection->bbox, p, sizeof(struct BBox)); p+= sizeof(struct BBox);
  ui.selection->items = NULL;
  
  // find by how much we translate the pasted selection
  gnome_canvas_get_scroll_offsets(canvas, &sx, &sy);
  gdk_window_get_geometry(GTK_WIDGET(canvas)->window, NULL, NULL, &wx, &wy, NULL);
  gnome_canvas_window_to_world(canvas, sx + wx/2, sy + wy/2, &cx, &cy);
  cx -= ui.cur_page->hoffset;
  cy -= ui.cur_page->voffset;
  if (cx + (ui.selection->bbox.right-ui.selection->bbox.left)/2 > ui.cur_page->width)
    cx = ui.cur_page->width - (ui.selection->bbox.right-ui.selection->bbox.left)/2;
  if (cx - (ui.selection->bbox.right-ui.selection->bbox.left)/2 < 0)
    cx = (ui.selection->bbox.right-ui.selection->bbox.left)/2;
  if (cy + (ui.selection->bbox.bottom-ui.selection->bbox.top)/2 > ui.cur_page->height)
    cy = ui.cur_page->height - (ui.selection->bbox.bottom-ui.selection->bbox.top)/2;
  if (cy - (ui.selection->bbox.bottom-ui.selection->bbox.top)/2 < 0)
    cy = (ui.selection->bbox.bottom-ui.selection->bbox.top)/2;
  hoffset = cx - (ui.selection->bbox.right+ui.selection->bbox.left)/2;
  voffset = cy - (ui.selection->bbox.top+ui.selection->bbox.bottom)/2;
  ui.selection->bbox.left += hoffset;
  ui.selection->bbox.right += hoffset;
  ui.selection->bbox.top += voffset;
  ui.selection->bbox.bottom += voffset;

  ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
      gnome_canvas_rect_get_type(), "width-pixels", 1,
      "outline-color-rgba", 0x000000ff,
      "fill-color-rgba", 0x80808040,
      "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right, 
      "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL);
  make_dashed(ui.selection->canvas_item);

  while (nitems-- > 0) {
    item = g_new(struct Item, 1);
    ui.selection->items = g_list_append(ui.selection->items, item);
    ui.cur_layer->items = g_list_append(ui.cur_layer->items, item);
    ui.cur_layer->nitems++;
    g_memmove(&item->type, p, sizeof(int)); p+= sizeof(int);
    if (item->type == ITEM_STROKE) {
      g_memmove(&item->brush, p, sizeof(struct Brush)); p+= sizeof(struct Brush);
      g_memmove(&npts, p, sizeof(int)); p+= sizeof(int);
      item->path = gnome_canvas_points_new(npts);
      pf = (double *)p;
      for (i=0; i<npts; i++) {
        item->path->coords[2*i] = pf[2*i] + hoffset;
        item->path->coords[2*i+1] = pf[2*i+1] + voffset;
      }
      p+= 2*item->path->num_points*sizeof(double);
      if (item->brush.variable_width) {
        item->widths = g_memdup(p, (item->path->num_points-1)*sizeof(double));
        p+= (item->path->num_points-1)*sizeof(double);
      }
      else item->widths = NULL;
      update_item_bbox(item);
      make_canvas_item_one(ui.cur_layer->group, item);
    }
    if (item->type == ITEM_TEXT) {
      g_memmove(&item->brush, p, sizeof(struct Brush)); p+= sizeof(struct Brush);
      g_memmove(&item->bbox.left, p, sizeof(double)); p+= sizeof(double);
      g_memmove(&item->bbox.top, p, sizeof(double)); p+= sizeof(double);
      item->bbox.left += hoffset;
      item->bbox.top += voffset;
      g_memmove(&len, p, sizeof(int)); p+= sizeof(int);
      item->text = g_malloc(len+1);
      g_memmove(item->text, p, len+1); p+= len+1;
      g_memmove(&len, p, sizeof(int)); p+= sizeof(int);
      item->font_name = g_malloc(len+1);
      g_memmove(item->font_name, p, len+1); p+= len+1;
      g_memmove(&item->font_size, p, sizeof(double)); p+= sizeof(double);
      make_canvas_item_one(ui.cur_layer->group, item);
    }
    if (item->type == ITEM_IMAGE) {
      item->canvas_item = NULL;
      item->image_png = NULL;
      item->image_png_len = 0;
      g_memmove(&item->bbox, p, sizeof(struct BBox)); p+= sizeof(struct BBox);
      item->bbox.left += hoffset;
      item->bbox.right += hoffset;
      item->bbox.top += voffset;
      item->bbox.bottom += voffset;
      g_memmove(&item->image_png_len, p, sizeof(gsize)); p+= sizeof(gsize);
      if (item->image_png_len > 0) {
        item->image_png = g_memdup(p, item->image_png_len);
        item->image = pixbuf_from_buffer(item->image_png, item->image_png_len);
        p+= item->image_png_len;
      } else {
        item->image = NULL;
      }
      make_canvas_item_one(ui.cur_layer->group, item);
    }
  }

  prepare_new_undo();
  undo->type = ITEM_PASTE;
  undo->layer = ui.cur_layer;
  undo->itemlist = g_list_copy(ui.selection->items);  
  
  gtk_selection_data_free(sel_data);
  update_copy_paste_enabled();
  update_color_menu();
  update_thickness_buttons();
  update_color_buttons();
  update_font_button();  
  update_cursor(); // FIXME: can't know if pointer is within selection!
}
Exemplo n.º 4
0
/* Emits an event for an item in the canvas, be it the current item, grabbed
 * item, or focused item, as appropriate.
 */
static int
emit_event (GnomeCanvas *canvas, GdkEvent *event)
{
	GdkEvent *ev;
	gint finished;
	GnomeCanvasItem *item;
	GnomeCanvasItem *parent;
	guint mask;

	/* Choose where we send the event */

	item = canvas->current_item;

	if (canvas->focused_item
	    && ((event->type == GDK_KEY_PRESS) || (event->type == GDK_KEY_RELEASE) || (event->type == GDK_FOCUS_CHANGE)))
		item = canvas->focused_item;

	if (canvas->grabbed_item)
		item = canvas->grabbed_item;

	/* Perform checks for grabbed items */

	if (canvas->grabbed_item) {
		switch (event->type) {
		case GDK_ENTER_NOTIFY:
			mask = GDK_ENTER_NOTIFY_MASK;
			break;

		case GDK_LEAVE_NOTIFY:
			mask = GDK_LEAVE_NOTIFY_MASK;
			break;

		case GDK_MOTION_NOTIFY:
			mask = GDK_POINTER_MOTION_MASK;
			break;

		case GDK_BUTTON_PRESS:
		case GDK_2BUTTON_PRESS:
		case GDK_3BUTTON_PRESS:
			mask = GDK_BUTTON_PRESS_MASK;
			break;

		case GDK_BUTTON_RELEASE:
			mask = GDK_BUTTON_RELEASE_MASK;
			break;

		case GDK_KEY_PRESS:
			mask = GDK_KEY_PRESS_MASK;
			break;

		case GDK_KEY_RELEASE:
			mask = GDK_KEY_RELEASE_MASK;
			break;

		default:
			mask = 0;
			break;
		}

		if (!(mask & canvas->grabbed_event_mask))
			return FALSE;
	}

	/* Convert to world coordinates -- we have two cases because of diferent
	 * offsets of the fields in the event structures.
	 */

	ev = gdk_event_copy (event);

	switch (ev->type) {
	case GDK_ENTER_NOTIFY:
	case GDK_LEAVE_NOTIFY:
		gnome_canvas_window_to_world (canvas,
					      ev->crossing.x, ev->crossing.y,
					      &ev->crossing.x, &ev->crossing.y);
		break;

	case GDK_MOTION_NOTIFY:
	case GDK_BUTTON_PRESS:
	case GDK_2BUTTON_PRESS:
	case GDK_3BUTTON_PRESS:
	case GDK_BUTTON_RELEASE:
		gnome_canvas_window_to_world (canvas,
					      ev->motion.x, ev->motion.y,
					      &ev->motion.x, &ev->motion.y);
		break;

	default:
		break;
	}

	/* The event is propagated up the hierarchy (for if someone connected to
	 * a group instead of a leaf event), and emission is stopped if a
	 * handler returns TRUE, just like for GtkWidget events.
	 */

	finished = FALSE;

	while (item && !finished) {
		g_object_ref (item);

		g_signal_emit_by_name (item, "event", ev, &finished);

		parent = item->parent;
		g_object_unref (item);

		item = parent;
	}

	gdk_event_free (ev);

	return finished;
}