Re: Scaling a Canvas to fit its scrolled window.


>    I am trying to scale the GnomeCanvas automatically so that it
> always matches the dimension of the scrolled window viewport in
> the y-direction, but can be set to various levels of scrolling in
> the x-direction.  Of course, the first and most obvious thing is
> to get the size of the CanvasWidget to precisely match the size of
> the viewport.  To that end, I'm getting the size of the scrolled
> window with the following code:
>     adjust = gtk_scrolled_window_get_hadjustment(
>       GTK_SCROLLED_WINDOW(charting_sw) );
>     view_width = adjust->page_size;
>     adjust = gtk_scrolled_window_get_vadjustment(
>       GTK_SCROLLED_WINDOW(charting_sw) );
>     view_height = adjust->page_size;
>    The first problem, of course, is that until I actually show
> the window with gtk_widget_show(), the page size of the scrolled
> window is 0.  Using gtk_widget_realize() instead does not help;
> I get completely different numbers after _realize() and _show().
> OK, so I suppose I could build the contents of the Canvas, show
> the window, get the sizes, re-do the affine transforms, and only
> *then* drop the Canvas into the scrolled window and show it, but
> it seems like there should be some way to get the whole thing
> put together before showing it.

I think you may want to install "realize" signal handler instead of
calling it manually. But I am not absolutely sure.
You may want to take a look into sodipodi (
code (src/desktop.c). There I have solved a pile of similar issues
- like mapping paper coordinates to canvas ones, implement autofit,
implement fit arbitrary canvas rectangle and so on. Unfortunately it
does not use scrolled window at all, but instead table with
hand-placed scrollbar.

>    The next problem is the affine transforms themselves.  As
> always, there's the infuriating problem of the y-coordinates
> increasing as you go *down* (will we *NEVER* get away from this
> old throwback to CRT scanning!?!) which means that there's the
> immediate requirement to do a negative-value scaling factor in
> the y-direction.  But I need to be able to place multiple
> graphs on the chart simultaneously, each positioned by its
> item-to-world affine transform so that they are all stacked on
> top of each other in the y-direction.  The way to do this, of
> course, is to make each chart a GnomeCanvasGroup, with its own
> independent transform from item-to-world coordinates (or should
> it be the item-to-canvas transform?).  Still, the transforms
> that I'm doing don't seem to be having the effects I expect.
>    Let's use a for-instance:
>    The data to be plotted runs from a minimum x-value of 0.0 to
> a maximum of ~20000.  The y-value runs from a minimum of ~25.0
> to a maximum of ~215.  So the rational transforming sequence
> seems to me to be:
>    1. Translate -25.0 in the y-direction.  Call this Aff1.
>    2. Scale by a negative factor to "flip" the data upright,
>      i.e. increasing y-values move upward on the chart, and
>      to get the y-size of the object to match the y-size of
>      the scrolled window viewport.  Call this Aff2.
>    3. Translate the object back 190.0 in the y-direction to
>      get it fully visible in the Canvas.  Call this Aff3.
>    I compose Aff1 and Aff2 into a temporary affine "foo"
> with the following:
>    art_affine_multiply( foo, Aff1, Aff2 );
>    Then get the final affine with:
>    art_affine_multiply( affine, foo, Aff3 );
>    And finally apply the affine to the chart group with:
>    gnome_canvas_item_affine_relative( GNOME_CANVAS_ITEM(group), affine );

You certainly want to use .._affine_absolute() here.
If you are dealing with classical (Y grows upwards) coordinates, I
suggest creating single root canvas group, transformed so 0,0 is
lower left and Y grows upwards. Then you can stack your graphs
without too much headache ;)

>    Unfortunately, this does *not* have the expected effects.
> Or, at least, I don't *think* it does.  One of the problems
> I'm having is that I can't "see" all of the pertinent info.
> What I'd like to do is get some sort of visible border on the
> viewport so I can see its "edge," and also get some sort of
> border around the entire Canvas so that I can see *its*
> boundaries to determine whether I'm in fact getting things
> matched up in size, but not matching up to the right things,
> if you get my meaning.  Anyone have any suggestions on how
> to improve my debugging capabilities in this respect?

Best wishes,

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]