gboolean rubberband_update (Sheet *sheet, GdkEvent *event) { GList *iter; Coords cur, cmin, cmax; double dx, dy; // TODO maybe keep track of subpixel changes, make em global/part of the rubberband_info struct and reset on finish double width, height, width_ng, height_ng; RubberbandInfo *rubberband_info; rubberband_info = sheet->priv->rubberband_info; g_assert (event->type == GDK_MOTION_NOTIFY); cur.x = event->motion.x; cur.y = event->motion.y; goo_canvas_convert_from_pixels (GOO_CANVAS (sheet), &cur.x, &cur.y); width = fabs(rubberband_info->end.x - rubberband_info->start.x); height = fabs(rubberband_info->end.y - rubberband_info->start.y); width_ng = fabs(cur.x - rubberband_info->start.x); height_ng = fabs(cur.y - rubberband_info->start.y); dx = fabs (width_ng - width); dy = fabs (height_ng - height); NG_DEBUG ("motion :: dx=%lf, dy=%lf :: x=%lf, y=%lf :: w_ng=%lf, h_ng=%lf", dx, dy, cur.x, cur.y, width_ng, height_ng); // TODO FIXME scroll window if needed (use http://developer.gnome.org/goocanvas/stable/GooCanvas.html#goo-canvas-scroll-to) if (dx > 0.1 || dy > 0.1) { //a 0.1 change in pixel coords would be the least visible, silently ignore everything else rubberband_info->end.x = cur.x; rubberband_info->end.y = cur.y; cmin.x = MIN(rubberband_info->start.x, rubberband_info->end.x); cmin.y = MIN(rubberband_info->start.y, rubberband_info->end.y); cmax.x = cmin.x + width_ng; cmax.y = cmin.y + height_ng; #if 1 for (iter = sheet->priv->items; iter; iter = iter->next) { sheet_item_select_in_area (iter->data, &cmin, &cmax); } #endif g_object_set (GOO_CANVAS_ITEM (rubberband_info->rectangle), "x", cmin.x, "y", cmin.y, "width", width_ng, "height", height_ng, "visibility", GOO_CANVAS_ITEM_VISIBLE, NULL); goo_canvas_item_raise (GOO_CANVAS_ITEM (rubberband_info->rectangle), NULL); } return TRUE; }
int sheet_motion_rubberband (Sheet *sheet, GdkEventMotion *event) { static double width_old = 0, height_old = 0; double x, y; double height, width; double dx, dy; GList *list = NULL; SheetPos p1, p2; // Obtains the current pointer position and modifier state. // The position is given in coordinates relative to window. sheet_get_pointer (sheet, &x, &y); if (x < sheet->priv->rubberband->start_x) { width = sheet->priv->rubberband->start_x - x; } else { double tmp = x; x = sheet->priv->rubberband->start_x; width = tmp - sheet->priv->rubberband->start_x; } if (y < sheet->priv->rubberband->start_y) { height = sheet->priv->rubberband->start_y - y; } else { double tmp = y; y = sheet->priv->rubberband->start_y; height = tmp - sheet->priv->rubberband->start_y; } p1.x = x; p1.y = y; p2.x = x + width; p2.y = y + height; // Scroll the sheet if needed. // Need FIX /*{ int width, height; int dx = 0, dy = 0; GtkAllocation allocation; sheet_get_pointer (sheet, &x, &y); gtk_widget_get_allocation (GTK_WIDGET (sheet), &allocation); width = allocation.width; height = allocation.height; if (_x < 0) dx = -1; else if (_x > width) dx = 1; if (_y < 0) dy = -1; else if (_y > height) dy = 1; if (!(_x > 0 && _x < width && _y > 0 && _y < height)) sheet_scroll (sheet, dx * 5, dy * 5); }*/ // Modify the rubberband rectangle if needed dx = fabs (width - width_old); dy = fabs (height - height_old); if (dx > 1.0 || dy > 1.0) { // Save old state width_old = width; height_old = height; for (list = sheet->priv->items; list; list = list->next) { sheet_item_select_in_area (list->data, &p1, &p2); } g_object_set (sheet->priv->rubberband->rectangle, "x", (double) x, "y", (double) y, "width", width, "height", height, NULL); //g_list_free_full (list, g_object_unref); //FIXME } return TRUE; }