Esempio n. 1
0
void finalize_movesel(void)
{
  GList *list, *link;
  
  if (ui.selection->items != NULL) {
    prepare_new_undo();
    undo->type = ITEM_MOVESEL;
    undo->itemlist = g_list_copy(ui.selection->items);
    undo->val_x = ui.selection->last_x - ui.selection->anchor_x;
    undo->val_y = ui.selection->last_y - ui.selection->anchor_y;
    undo->layer = ui.selection->layer;
    undo->layer2 = ui.selection->move_layer;
    undo->auxlist = NULL;
    // build auxlist = pointers to Item's just before ours (for depths)
    for (list = ui.selection->items; list!=NULL; list = list->next) {
      link = g_list_find(ui.selection->layer->items, list->data);
      if (link!=NULL) link = link->prev;
      undo->auxlist = g_list_append(undo->auxlist, ((link!=NULL) ? link->data : NULL));
    }
    ui.selection->layer = ui.selection->move_layer;
    move_journal_items_by(undo->itemlist, undo->val_x, undo->val_y,
                          undo->layer, undo->layer2, 
                          (undo->layer == undo->layer2)?undo->auxlist:NULL);
  }

  if (ui.selection->move_pageno!=ui.selection->orig_pageno) 
    do_switch_page(ui.selection->move_pageno, FALSE, FALSE);
    
  if (ui.cur_item_type == ITEM_MOVESEL_VERT)
    reset_selection();
  else {
    ui.selection->bbox.left += undo->val_x;
    ui.selection->bbox.right += undo->val_x;
    ui.selection->bbox.top += undo->val_y;
    ui.selection->bbox.bottom += undo->val_y;
    make_dashed(ui.selection->canvas_item);
    /* update selection box object's offset to be trivial, and its internal 
       coordinates to agree with those of the bbox; need this since resize
       operations will modify the box by setting its coordinates directly */
    gnome_canvas_item_affine_absolute(ui.selection->canvas_item, NULL);
    gnome_canvas_item_set(ui.selection->canvas_item, 
      "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right,
      "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL);
  }
  ui.cur_item_type = ITEM_NONE;
  update_cursor();
}
Esempio n. 2
0
static int affine( Tcl_Interp *interp, int objc, Tcl_Obj * const objv[], 
      CanvasParams *param, GPtrArray *items, int type )
{
   GnoclOption options[] = {
      { "-absolute", GNOCL_BOOL, NULL },
      { "-reverseOrder", GNOCL_BOOL, NULL },
      { NULL }
   };
   static const int absoluteIdx     = 0;
   static const int reverseOrderIdx = 1;

   guint m; 
   int   noCoords;
   int   absolute = 0; 
   int   reverse = 0;

   if( objc < 4  )
   {
      /* canvas (affine|move|scale|rotate) tag-or-id  coords ?options ? */
      Tcl_WrongNumArgs( interp, 3, objv, 
            "list-of-coordinates ?option val ...?" );
      return TCL_ERROR;
   }
   if( gnoclParseOptions( interp, objc - 3, objv + 3, options ) != TCL_OK )
      return TCL_ERROR;

   if( options[absoluteIdx].status == GNOCL_STATUS_CHANGED )
      absolute = options[absoluteIdx].val.b;
   if( options[reverseOrderIdx].status == GNOCL_STATUS_CHANGED )
      reverse = options[reverseOrderIdx].val.b;
   gnoclClearOptions( options );

   if( absolute && reverse )
   {
      Tcl_SetResult( interp, "Options \"-reverseOrder\" is only valid "
            "for relative transformations.", TCL_STATIC );
      return TCL_ERROR;
   }

   if( Tcl_ListObjLength( interp, objv[3], &noCoords ) != TCL_OK )
      return TCL_ERROR;

   for( m = 0; m < items->len; ++m )
   {
      Gnocl_CanvasItemInfo *info = GET_INFO( items, m );
      int k;
      double af[6];
      Tcl_Obj *tp;

      for( k = 0; k < 6 && k < noCoords; ++k )
      {
         if( Tcl_ListObjIndex( interp, objv[3], k, &tp ) != TCL_OK )
            return TCL_ERROR;
         if( Tcl_GetDoubleFromObj( interp, tp, &af[k] ) != TCL_OK )
            return TCL_ERROR;
      }

      /*
         x' = af[0] * x + af[2] * y + af[4];
         y' = af[1] * x + af[3] * y + af[5];
      */
      switch( type )
      {
         case Affine:
               if( noCoords != 6 )
               {
                  Tcl_SetResult( interp, 
                        "size of list-of-coordinates must be 6", TCL_STATIC );
                  return TCL_ERROR;
               }
               break;
         case Move:
               if( noCoords != 2 )
               {
                  Tcl_SetResult( interp, "size of list-of-coordinates must "
                        "be 2 (delta-x and delta-y)", TCL_STATIC );
                  return TCL_ERROR;
               }
               af[4] = af[0];
               af[5] = af[1];

               af[0] = 1.; af[2] = 0.;
               af[1] = 0.; af[3] = 1.;
               break;
         case Scale:
               if( noCoords != 3 && noCoords != 4 )
               {
                  Tcl_SetResult( interp, "size of list-of-coordinates must "
                        "be 3 or 4 (center, x-scale and y-scale)", 
                        TCL_STATIC );
                  return TCL_ERROR;
               }
               else
               {
                  double x = af[0];
                  double y = af[1];
                  double scalex = af[2];
                  double scaley = (noCoords == 4) ? af[3] : scalex;
                  af[0] = scalex; af[2] = .0;     af[4] = x * (1. - scalex);
                  af[1] = .0;     af[3] = scaley; af[5] = y * (1. - scaley);
               }
               break;
         case Rotate:
               /* there seems to be some problems with the 
                  canvas without antialiasing and rotating 
                  (bizarre drawings)
               */
               if( noCoords != 3 )
               {
                  Tcl_SetResult( interp, "size of list-of-coordinates must "
                        "be 3 (center and angle)", TCL_STATIC );
                  return TCL_ERROR;
               }
               else
               {
                  double x = af[0];
                  double y = af[1];
                  double w = af[2];
                  const double cw = cos( w );
                  const double sw = sin( w );

                  af[0] = cw; af[2] = -sw; af[4] = x - x * cw + y * sw;
                  af[1] = sw; af[3] =  cw; af[5] = y - x * sw - y * cw;
               }
               break;
      }

      /*
      printf( "\nitem: %p absolute: %d\n", info->item, absolute );
      printf( "before:\n" );
      {
         int k;
         double af[6];
         gnome_canvas_item_i2c_affine( info->item, af );
         for( k = 0; k < 6; k += 2 )
            printf( "%d: %f ", k, af[k] );
         printf( "\n" );
         for( k = 1; k < 6; k += 2 )
            printf( "%d: %f ", k, af[k] );
         printf( "\n" );
      }
      printf( "affine:\n" );
      for( k = 0; k < 6; k += 2 )
         printf( "%d: %f ", k, af[k] );
      printf( "\n" );
      for( k = 1; k < 6; k += 2 )
         printf( "%d: %f ", k, af[k] );
      printf( "\n" );
      */

      if( absolute )
         gnome_canvas_item_affine_absolute( info->item, af );
      else
      {
         /* Well, *I* think this is a bug in gnome: 
            affine_relative should not be the reverse of what one
            would expect. Or do I have wrong expectations? */
         if( reverse )
            gnome_canvas_item_affine_relative( info->item, af );
         else
         {
            double bf[6];
            gnome_canvas_item_i2w_affine( info->item, bf );
            gnome_canvas_item_affine_absolute( info->item, af );
            gnome_canvas_item_affine_relative( info->item, bf );
         }
      }
   }

   return TCL_OK;
}