Re: gnome-canvas scrolling - simple example
- From: lytles alphatech com
- To: Havoc Pennington <hp redhat com>
- Cc: gnome-list gnome org, lytles alphatech com
- Subject: Re: gnome-canvas scrolling - simple example
- Date: Wed, 19 Jan 2000 13:54:47 -0500
Havoc,
I came up with a pretty clean work-around for the automatic recentering
of the scroll region that was causing me problems. This may be of
interest to others, so I am attaching the improved c code.
To summarize:
1. set the scrolled region to zero size, at the center of the area
of interest
2. use gnome_canvas_item_get_bounds to get an area of interest
(for a real application i would probably cache this)
3. use gnome_canvas_w2c to convert the bounds to pixels
4. convert from spot in the world (xo,yo) to pixels in the canvas(i,j)
5. set (hadj,vadj)->value to (i,j) - this effectively makes
(xo,yo) at the center of the window
this seems to work well and is pretty clean.
> If the visible region is
> larger than the scroll region, then IIRC the canvas just centers the
> scroll region in the visible region. It's hard to know what else the
> canvas should do in this case...
>
> Havoc
thanks for your help and a great book (it is the only computer book
that i have bought that i haven't regretted buying).
Seth
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gnome.h>
typedef struct { GnomeCanvas *canvas; GtkAdjustment *zadj; } mystuff;
static void destroy(GtkWidget *widget, gpointer data) { gtk_main_quit(); }
static gint my_events (GtkWidget *w,GdkEvent *event,mystuff *z) {
GdkEventButton *bevent;
GdkEventMotion *mevent;
gint tx,ty,x, y, width, height;
int b1;
GnomeCanvas *canvas;
int m2=(GDK_CONTROL_MASK|GDK_MOD1_MASK|GDK_MOD2_MASK|GDK_BUTTON2_MASK|GDK_BUTTON3_MASK);
int m1=(GDK_SHIFT_MASK|m2);
GtkAdjustment *adj;
int i,j;
canvas=GNOME_CANVAS(w);
gdk_window_get_size(w->window,&width,&height);
gdk_window_get_pointer (w->window, &tx, &ty, NULL);
x = (1.0*CLAMP (tx, 0, width-1));
y = (1.0*CLAMP (ty, 0, height-1));
b1=0;
if (event->type==GDK_BUTTON_PRESS) {
gtk_grab_add (w); bevent=(GdkEventButton *)event;
if (bevent->button==1 && !(bevent->state & m1)) { b1=1; }
else if (bevent->button==1 && (bevent->state & GDK_SHIFT_MASK) && !(bevent->state & m2)) { b1=2; }
else if (bevent->button==3 && (bevent->state & GDK_SHIFT_MASK) && !(bevent->state & m2)) { b1=3; }
}
else if (event->type==GDK_BUTTON_RELEASE) {
gtk_grab_remove(w); bevent=(GdkEventButton *)event;
if (bevent->button==1 && !(bevent->state & m1)) { b1=1; }
}
else if (event->type==GDK_MOTION_NOTIFY) {
mevent = (GdkEventMotion *) event;
if ((mevent->state & GDK_BUTTON1_MASK) && !(mevent->state & m1)) { b1=1; }
}
if (b1==1) {
double xc1,xc2,yc1,yc2;
gnome_canvas_item_get_bounds(canvas->root,&xc1,&yc1,&xc2,&yc2);
if (width>1 && height>1) gnome_canvas_w2c(canvas,xc1+(xc2-xc1)*x/(width-1),yc1+(yc2-yc1)*y/(height-1),&i,&j); else { i=0; j=0; }
}
else if (b1==2 || b1==3) {
gfloat zo,z1,z2;
double xo,yo;
i=GTK_LAYOUT(w)->hadjustment->value;
j=GTK_LAYOUT(w)->vadjustment->value;
gnome_canvas_c2w(canvas,i,j,&xo,&yo);
adj=z->zadj;
zo=adj->value;
z1=adj->lower;
z2=adj->upper;
if (b1==2) (adj->value) *= 2;
else if (b1==3) (adj->value) /= 2;
if (adj->value<z1) adj->value=z1;
if (adj->value>=z2) adj->value=z2;
if (adj->value != zo) gnome_canvas_set_pixels_per_unit(GNOME_CANVAS(canvas),adj->value);
gnome_canvas_w2c(canvas,xo,yo,&i,&j);
}
if (b1==1 || b1==2 || b1==3) {
adj=GTK_LAYOUT(w)->hadjustment;
if (adj && width>0) { adj->value=i; gtk_adjustment_value_changed(adj); }
adj=GTK_LAYOUT(w)->vadjustment;
if (adj && height>0) { adj->value=j; gtk_adjustment_value_changed(adj); }
}
if (0) printf("event: %5d %5d | %d %d \n",width,height,i,j);
return(0);
}
int main( int argc, char *argv[] ) {
GtkWidget *window,*canvas;
GnomeCanvasGroup *root;
mystuff *z;
gnome_init ("testGNOME", "1.2", argc, argv);
gdk_rgb_set_verbose (TRUE);
gdk_rgb_init ();
gtk_widget_set_default_colormap (gdk_rgb_get_cmap ());
gtk_widget_set_default_visual (gdk_rgb_get_visual ());
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_signal_connect (GTK_OBJECT (window), "destroy",(GtkSignalFunc) destroy, NULL);
gtk_widget_show( window );
canvas = gnome_canvas_new ();
root = gnome_canvas_root (GNOME_CANVAS (canvas));
gnome_canvas_item_new(root,
gnome_canvas_rect_get_type(),
"x1",0.0,"x2",100.0,
"y1",0.0,"y2",100.0,
"fill_color", "red",
"outline_color", "black",
"width_units", 1.0,
NULL);
z=(mystuff *)calloc(1,sizeof(mystuff));
z->canvas=GNOME_CANVAS(canvas);
z->zadj=GTK_ADJUSTMENT(gtk_adjustment_new (1.00, 0.0625,256, 0.05, 0.50, 0.50));
gnome_canvas_set_pixels_per_unit(GNOME_CANVAS(canvas),z->zadj->value);
gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas),50.0,50.0,50.0,50.0);
gtk_container_add (GTK_CONTAINER (window), canvas);
gtk_widget_show (canvas);
gtk_signal_connect_after (GTK_OBJECT (canvas),"event",(GtkSignalFunc) my_events,z);
GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_FOCUS);
gtk_widget_grab_focus (canvas);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
/* example-end */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]