Re: position of a widget?



On Mon, 17 Sep 2007 20:29:27 +1200
"Johan Aberg" <abergster gmail com> wrote:

Thanks for the code Zentara. I now have managed to get drag and drop
working from my table that holds thumb nails of images, dropped into
the canvas. I can also move around the images in the canvas and I've
added a function for snapping the image's border each other. Nice!

I was trying to sort the images based on their x values on the canvas,
for various reasons. Obviously, I lack some fundamental perl skills
since I can't get this to work. My plan was to
put my canvas items in a hash together with their x value, sort the
hash based on the value and the move them around based on the result
form the sort.
It all works pretty well, except that I can't figure out how to store
a canvas item in a hash and call it later when I want to move it.

Please consider this snippet of code:

@textArray = ("a", "b", "c", "d");
my $counter = 0;
my %textHash = ();

foreach (@textArray){

       #create a text item
       my $text = Gnome2::Canvas::Item->new ($root, 'Gnome2::Canvas::Text',
                            x => $counter,
                            y => 15,
                            fill_color => 'black',
                            font => 'Sans 14',
                            anchor => 'GTK_ANCHOR_NW',
                            text => '$_');

    #store text item together with its x value in the hash
   $imageHash{$text}  = $counter;

   $counter++;
}

# loop through the hash and do something
# (in this case move())

for my $key ( keys %textHash  ) {
   my $value = $textHash{$key};
   my $newX = $value + 10;
   $key->move($newX, 0);
}

This code above shows what I'm trying to do. When I call $key->move()
I get an error saying move() is not a part of $key.

I hope this make sense, if not, I'll try to explain better.
Any ideas what I'm missing?

Thanks heaps!

From your code, it looks like you are making the common mistake, of
using an object reference as a key, and setting it's value to identify it. 
You will get an error, something like "cannot use a reference as a hash key",
(but it's been a while since I made that error. :-),  it's close though )

Anyways, try something like

####################################################
foreach() {
   ....
   ....
  $imageHash{$counter}{'object'}  = $text;
  $counter++;
}

for my $key ( keys %textHash  ) {
    my $object = $textHash{$key};
    my $newX = $key + 10;
    $object->move($newX, 0);
}

####################################################

<some brainstorming>

Storing the objects and their locations in a hash, is the most obvious way
to go.
I would point out that if you think about it a bit, you may be able to devise a system
where you don't need to store their locations.

What you might consider, is in the drop callback, you detect the mouse pointer
location, at the drop point. Then find all items whose $item->get_bounds is greater
than the drop point. Then move those items ($item_size,0).  

You can even give it a cool animation effect, by setting up a timer, to move those
items (1,0) repeatedly until they move $item_size + padding.

The advantage of doing it dynamically like this, is if you have many differently
sized items, you don't have to worry about breaking your grid.
It also makes it easy to delete an item..... you just get_bounds of the item to be deleted, 
then find all items whose y location  is greater, and move them (-1,0) until they
are in position.


One other thing, is that the Gnome2::Canvas dosn't have tags, like Perl/Tk.
You need to make your own.
Like:
$text->{location} = (42,0};

Now you can ditch the hash, and push items into an array. Then just
loop thru the array and check each location.

Anyways, think about it for a few days, you may find a way that is superior
to hash locations and a grid. 

May you be inspired :-),

zentara


-- 
I'm not really a human, but I play one on earth.
http://zentara.net/japh.html



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