void gv_shapes_replace_shapes(GvShapes *shapes, gint num_shapes, gint *shape_id, GvShape **shps, int make_copy) { gint i; GvShapeChangeInfo change_info = {GV_CHANGE_REPLACE, 0, NULL}; change_info.num_shapes = num_shapes; change_info.shape_id = shape_id; gv_data_changing(GV_DATA(shapes), &change_info); for (i=0; i < num_shapes; ++i) { GvShape *shape; if( shape_id[i] < 0 || shape_id[i] >= shapes->shapes->len ) continue; else if( gv_shapes_get_shape(shapes, shape_id[i]) != NULL ) gv_shape_unref( gv_shapes_get_shape(shapes, shape_id[i]) ); else g_warning( "Missing shape in gv_shapes_replace_shapes()" ); if( make_copy ) shape = gv_shape_copy(shps[i]); else shape = shps[i]; gv_shape_ref( shape ); g_ptr_array_index(shapes->shapes, shape_id[i]) = shape; } gv_data_changed(GV_DATA(shapes), &change_info); }
static void gv_rect_tool_reshape( GvRectTool *r_tool, gvgeocoord x, gvgeocoord y ) { GvShape *shape; gvgeocoord x1, y1, x2, y2; gv_tool_clamp_to_bounds( GV_TOOL(r_tool), &x, &y ); shape = gv_shapes_get_shape( r_tool->layer->data, r_tool->shape_id ); if( shape == NULL || gv_shape_get_nodes( shape, 0 ) != 5 ) return; shape = gv_shape_copy( shape ); x1 = gv_shape_get_x(shape,0,0); y1 = gv_shape_get_y(shape,0,0); x2 = gv_shape_get_x(shape,0,2); y2 = gv_shape_get_y(shape,0,2); if( r_tool->picked == PICK_SIDE_TOP ) y1 = y; else if( r_tool->picked == PICK_SIDE_RIGHT ) x2 = x; else if( r_tool->picked == PICK_SIDE_BOTTOM ) y2 = y; else if( r_tool->picked == PICK_SIDE_LEFT ) x1 = x; else if( r_tool->picked == PICK_CORNER_TOPLEFT ) { x1 = x; y1 = y; } else if( r_tool->picked == PICK_CORNER_TOPRIGHT ) { x2 = x; y1 = y; } else if( r_tool->picked == PICK_CORNER_BOTTOMRIGHT ) { x2 = x; y2 = y; } else if( r_tool->picked == PICK_CORNER_BOTTOMLEFT ) { x1 = x; y2 = y; } gv_shape_set_xyz( shape, 0, 0, x1, y1, 0 ); gv_shape_set_xyz( shape, 0, 1, x1, y2, 0 ); gv_shape_set_xyz( shape, 0, 2, x2, y2, 0 ); gv_shape_set_xyz( shape, 0, 3, x2, y1, 0 ); gv_shape_set_xyz( shape, 0, 4, x1, y1, 0 ); gv_shapes_replace_shapes( r_tool->layer->data, 1, &(r_tool->shape_id), &shape, FALSE ); }
static void gv_shapes_get_memento(GvData *gv_data, gpointer data, GvDataMemento **memento) { GvShapes *shapes = GV_SHAPES(gv_data); GvShapesMemento *mem; GvShapeChangeInfo *info = (GvShapeChangeInfo *) data; int i; mem = g_new(GvShapesMemento, 1); mem->base.data = GV_DATA(shapes); mem->base.type = info->change_type; mem->ids = g_array_new(FALSE, FALSE, sizeof(gint)); g_array_append_vals(mem->ids, info->shape_id, info->num_shapes); /* Grab in ascending order */ if (info->num_shapes > 1) { g_sort_type(mem->ids->data, gint, mem->ids->len); } if (info->change_type == GV_CHANGE_ADD) { mem->shapes = NULL; } else { mem->shapes = g_ptr_array_new(); for (i=0; i < info->num_shapes; ++i) { GvShape *shape = gv_shapes_get_shape(shapes,info->shape_id[i]); shape = gv_shape_copy( shape ); gv_shape_ref( shape ); g_ptr_array_add(mem->shapes, shape ); } } *memento = (GvDataMemento*)mem; }
static void gv_rotate_tool_motion_notify(GvTool *r_tool, GdkEventMotion *event) { GvRotateTool *tool = GV_ROTATE_TOOL(r_tool); GvShape *wrk_shape; if (tool->rrmode == RRMODE_DISPLAY ) return; wrk_shape = gv_shape_copy(tool->original); /* Map pointer position to tail vertex */ gv_view_area_map_pointer(GV_TOOL(tool)->view, event->x, event->y, &tool->v_tail.x, &tool->v_tail.y); /* Compute rotation from base. */ if( tool->rrmode == RRMODE_ROTATE || tool->rrmode == RRMODE_ROTATESCALE ) { double dx = tool->v_tail.x - tool->v_pivot.x; double dy = tool->v_tail.y - tool->v_pivot.y; if( fabs(dy) < fabs(dx)/1000000.0 ) tool->rotation = M_PI/2; else tool->rotation = atan(fabs(dx/dy)); if( dy < 0.0 && dx >= 0.0 ) tool->rotation = M_PI - tool->rotation; else if( dy >= 0.0 && dx < 0.0 ) tool->rotation = -tool->rotation; else if( dy < 0.0 && dx < 0.0 ) tool->rotation -= M_PI; tool->rotation = (tool->rotation / M_PI) * 180; gv_shape_rotate( wrk_shape, tool->rotation ); } /* Compute Scaling from base. */ if( tool->rrmode == RRMODE_SCALE || tool->rrmode == RRMODE_ROTATESCALE ) { double dx, dy, old_length, new_length; dx = tool->v_tail.x - tool->v_pivot.x; dy = tool->v_tail.y - tool->v_pivot.y; new_length = sqrt(dx*dx + dy*dy); dx = tool->v_head.x - tool->v_pivot.x; dy = tool->v_head.y - tool->v_pivot.y; old_length = sqrt(dx*dx + dy*dy); tool->scaling = new_length / old_length; gv_shape_scale( wrk_shape, tool->scaling ); } /* Apply to the shapes object ... this will create an undo step */ gv_shapes_replace_shapes( tool->layer->data, 1, &(tool->shape_id), &wrk_shape, FALSE ); gv_view_area_queue_draw(GV_TOOL(tool)->view); }
static void gv_rotate_tool_button_press(GvTool *r_tool, GdkEventButton *event) { GvRotateTool *tool = GV_ROTATE_TOOL(r_tool); if( event->state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK) ) return; /* -------------------------------------------------------------------- */ /* Have we selected an active control point on the scale/rotate */ /* dohickey? */ /* -------------------------------------------------------------------- */ if( tool->rrmode == RRMODE_DISPLAY && tool->shape_id != -1 ) { gv_view_area_map_pointer(GV_TOOL(tool)->view, event->x, event->y, &tool->v_head.x, &tool->v_head.y); /* ** Is this location a hit on an arrow head? */ tool->rrmode = gv_rotate_tool_classify_hit( tool, tool->v_head.x, tool->v_head.y ); /* ** Copy the original state of this shape, and disable undo till we are ** done. */ if( tool->rrmode != RRMODE_DISPLAY ) { if( event->button != 1 ) tool->rrmode = RRMODE_ROTATESCALE; tool->original = gv_shape_copy( gv_shapes_get_shape( tool->layer->data, tool->shape_id )); gv_undo_close(); gv_undo_disable(); } } /* -------------------------------------------------------------------- */ /* Are we selecting a shape? Note, currently we cannot clear */ /* our selection in resize/rotate mode - should we be able to? */ /* -------------------------------------------------------------------- */ if (event->button == 1 && tool->rrmode == RRMODE_DISPLAY ) { int shape_id; if (!gv_rotate_tool_configure(tool)) return; if (gv_shape_layer_pick_shape(GV_SHAPE_LAYER(tool->layer), GV_TOOL(tool)->view, event->x, event->y, &shape_id)) { GvShape *shape; /* Is the shape rotatable? */ shape = gv_shapes_get_shape( tool->layer->data, shape_id ); if( TRUE ) { gv_shape_layer_clear_selection( GV_SHAPE_LAYER(tool->layer)); gv_shape_layer_select_shape( GV_SHAPE_LAYER(tool->layer), shape_id); tool->shape_id = shape_id; gv_view_area_queue_draw(GV_TOOL(tool)->view); } } return; } }