in reply to Total Newbies TkZinc questions

Very nice looking GUI. I'm not much of an expert on POE, and usually just rely on Tk's event-loop.....but you may have your reasons.

To your questions:

1. Is there a Tk::Zinc(::Graphics) way of building multiple items with similar characteristics? (and how good is my hacked solution)

Yes, look at the clone() method. Look in the zinc-demos, under User Contributed Demos, for TripleRotatingWheel. I make one wheel object, then clone it, then translate it into position. Like: my $arc2 = $zinc->clone($arc1);

2.Is there a reliable way to position text at center of group?

Here is a snippet to show you how. I also throw in a useful trick for reversing the y-axis direction, so coords are more like standard cartesian.

#!/usr/bin/perl use warnings; use strict; use Tk; use Tk::Zinc; my $mw = MainWindow->new; my $width = 700; my $height = 600; $mw->geometry($width.'x'.$height); my $zinc = $mw->Zinc(-width => $width, -height => $height, -backcolor => 'black', -borderwidth => 3, -relief => 'sunken', )->pack; $zinc->fontCreate( "fonta", -family => 'arial', -size => 30, -weight => 'normal' ); #create a group with it's origin at center my $centergroup= $zinc->add('group',1,-visible=> 1); $zinc->scale($centergroup,1,-1); #reverse direction of y axis $zinc->translate($centergroup,$width/2,$height/2); # Then we create a gray filled rectangle, in which we will display exp +lain text. $zinc->add('rectangle', $centergroup , [-100, -100, 100, 100], -linewidth => 2, -filled => 1, -fillcolor => 'SkyBlue', ); my $text = $zinc->add('text', $centergroup, -position => [0,0], -text => 'foobaz', -font => 'fonta', -anchor => 'center', -priority => 2 ); MainLoop;

3. Is there a way to correctly calulate delta x/y if scaling is active?

Your dragging works fine by itself, and your scaling works fine by itself. Maybe just make them mutually exclusive, and pop a warning saying scaling is disabled during dragging? How often is someone going to want to do that anyways? I saw a similar problem in the Gnome2::Canvas and Goo::Canvas where I needed to do some clever multiplications/divisions to account for the current scale when saving to pdf. All I can say is I spent a few hours experimenting before I got it right. :-)

4. Did I missing something when it comes to calculating positions of items relative to display settings?

If you are referring to the drag/scale problem, what I think you will need to do is have 2 separate code blocks for calculating dx/dy. One if scaling is active, and 1 for simple dragging. Since your scaling factor can constantly be changing while the darg is occurring, I think it will mean alot of recalculations for each pixel of drag. Think about it....how can Zinc know what your dx/dy is, if the scale is changing while you drag. At best, it will be jerky( visually not codewise :-) ). I have 2 suggestions. One is to pop a warning, saying scaling is disabled during a drag. Or two, get rid of the +/- button press for scaling, and use a SpinBox instead, to set the scale. That way, the mouse can only be in 1 place at a time...either setting the scale-SpinBox or dragging an item.


I'm not really a human, but I play one on earth Remember How Lucky You Are

Replies are listed 'Best First'.
Re^2: Total Newbies TkZinc questions
by rocklee (Beadle) on Oct 21, 2008 at 21:47 UTC
    "Very nice looking GUI. [..]..but you may have your reasons."

    I appreciate that comment from a Chancellor, that must be like a Warlock or something ;-) And no, I really don't have my reasons, except it seemed cool, and this initial experiment confirms so.

    Thank you very much for the text positioning snippet, I wonder how many digits away I was ;-)

    Can't believe I didn't notice/realize what the clone() function was for *blush*. But there is a different feature of the ButtonFactory() approach - it allows me to isolate a number of arbitrary-depth group/item definitions (i.e. Tk::Zinc::Graphics).

    So, does spawning the initial item from a ButtonFactory() and then cloning make any sense? What is the Warlock approach to isolating item templates? - Subclassing, or?

    "[..] pop a warning saying scaling is disabled during dragging? How often is someone going to want to do that anyways?"

    Considering I will most likely be the only user of this program ever, it is clearly not that much of an issue. Nevertheless, I want to get it right. I can easily imagine doing different tasks on different scale levels, say, zooming out and selecting some items to drag them to the other other side of the workspace, then zoom back in over that area to fine-tune alignment etc. If the program was usable, I would do this all the time.

    In mostly any visual GUI sense that I can think of, retaining 1:1 relation between the user's input and visual translation makes the most sense. I expect this to be possible by somehow transforming the coordinates between the two systems, the question is how!;-) (this "feature" seems to be present in the Zinc demos that have both scale and drag, by the way)

    "[..] All I can say is I spent a few hours experimenting before I got it right. :-)"

    In that case, I think I'll leave it for the next Big Rewrite ;-)

    "If you are referring to the drag/scale problem, .."
    No, actually I was not. Let me clarify. In the interface_math sub, I perform some calculations based on totally random factors;
    • Menu area's height is set to 1/5 of screen height, which would easily break if the user has a nonstandard resolution.
    • Four lines defining (x,y,z) font sizes for different resolutions, taken from thin air.
    • if (widescreen) and if (display_x_size > 1400).

    The point is, this code can break under a huge number of circumstances. My question is if there exists a framework or standardised method for making these interface related decisions?

    "[..] if the scale is changing while you drag [..]"

    I think you may have missed the point here; The problem is not while you zoom, it's that, once you have zoomed, to any level but the startup factor 1, the dx/dy is borked for the application lifetime. It gets worse the further you are from scale 1, so hit + or - a few times and then move items to see the bug at work.

    Apologies for the comment on code clarity in the demos, I was referring to the testGraphics.pl demonstrating tabBox in particular..No spells, please! Will update the main post.

    Thanks for your valuable input!

      ".. if the scale is changing while you drag .."

      I think you may have missed the point here; The problem is not while you zoom, it's that, once you have zoomed, to any level but the startup factor 1, the dx/dy is borked for the application lifetime. It gets worse the further you are from scale 1, so hit + or - a few times and then move items to see the bug at work.

      I don't see any bug on my system, I'm using PDL-2.4.3 on linux. I can scale up, and scale down repeatedly, and the mouse drag works just fine. The only problem I see is the draggable item may go off screen during a scale procedure, and then dragging is prevented. If that is the bug you are referring to, make a Scrolled Zinc window in your workspaces. If it isn't your bug, are you on Win32 ? Or what version platform are you on?

      Also remember scaling is done by default with respect to the (0,0) point of the group, so you either need to put your draggable item in it's own group and center it, or specify the center-of-zoom when scaling.


      I'm not really a human, but I play one on earth Remember How Lucky You Are
Re^2: Total Newbies TkZinc questions
by rocklee (Beadle) on Oct 21, 2008 at 23:39 UTC

    Answering my own questions, indeed it took a few hours to figure out ;-) The dragging issue is solved by the zinc->transform() command, like magic! Here is some pseudocode in case someone else ponders this, I suppose it's obvious to the gurus.. :-\

    # -- PSEUDOCODE, DOES NOT WORK -- my ($dx, $dy); sub mobile_start { my $ev = $zinc->XEvent; ($dx, $dy) = $zinc->transform(1, $scaled_group, [$ev->x, $ev->y]); } sub mobile_move { my $ev = $zinc->XEvent; my ($tr_evx, $tr_evy) = $zinc->transform(1, $scaled_group, [$ev->x, +$ev->y]); $zinc->translate($some_group, $tr_evx-$dx, $tr_evy-$dy); ($dx, $dy) = ($tr_evx, $tr_evy); }
      Since "I" didn't see your bug before your transform addition, I suspect I will see it after you modify the code. :-) Maybe update your original code, and let me try again. There may be some hidden bug related to versions and platforms, but if you will be the only user, it really dosn't matter.......do whatever works for you.

      I'm not really a human, but I play one on earth Remember How Lucky You Are

        There is a (somewhat subtle) bug in the previous code. Indeed, drag does work at any scale factor, but you'll see it clearly once you understand what I mean:

        1. Start the program and add a media item (no scaling!)
        2. Position pointer in the exact center of the media item, click and drag it somewhere on the stage.
        3. Notice that when you release the item from drag, the pointer is still located in the exact position of the media item that you initiated drag from. In other words the item is translated exactly 1:1 with the mouse pointer.
        4. Hit "+" five times.
        5. Position the pointer in the exact center of media item, and drag it to the far side of the screen. You will notice that, while the item has been dragged, the pointer has offset from the point at which it was located when you first grabbed the item.

        Once I understand why, it's completely logical ;-)

        Try the updated version below, with good text centering, (visually) correct dragging and possibly other minor experiments.