From: Shaun Deacon on

> Hmmm... After a bit more testing, the above isn't quite accurate.  It
> seems the effect is more related to amount of canvas geometry found
> "within" the rectangle I'm dragging out.  As the rectangle surrounds
> more geometry, the effect gets worse.

Do you notice the same effect when the canvas is empty ?

I have a similar function in one of my apps for doing an 'area
selection'. I noticed that the rectangle re-display becomes less
smooth the further I drag out, even when the canvas is empty - but not
annoyingly so. The re-display is slightly less smooth when dragging
over a large number of canvas items although, to be honest, not
significantly different from the empty canvas case.

BTW, I found that canvas performance, in general, is improved for very
large numbers of items by limiting the number of added tags and using
my own structures/lists of canvas items for doing canvas operations
rather than using the tag mechanism.

Shaun

From: Jeff Godfrey on
On 4/30/2010 2:13 PM, Will Duquette wrote:
> Well, you could try this:
>
> 1. Using Img, you can capture the visible area of the canvas as a
> Tk image.
> 2. Delete the contents of the canvas. (You're going to redraw it
> anyway, once you get the rectangle, right?)
> 3. Position the Tk image on the visible area of the canvas. Now
> there's no geometry to slow things down.
> 4. When they've selected the rectangle, delete the image, and redraw.

Will,

Thanks for the input. In my case though, it falls apart at #2, as I
don't ever delete the canvas contents until I'm through with them. It
takes too long to load the data for that to be workable.

Currently, once I have the rectangle, zooming things is basically just a
simple [move] and [scale] command - which is much lighter weight than
reconstructing the contents of the canvas.

Jeff

From: Jeff Godfrey on
On 4/30/2010 2:15 PM, Shaun Deacon wrote:
>
>> Hmmm... After a bit more testing, the above isn't quite accurate. It
>> seems the effect is more related to amount of canvas geometry found
>> "within" the rectangle I'm dragging out. As the rectangle surrounds
>> more geometry, the effect gets worse.
>
> Do you notice the same effect when the canvas is empty ?

Hey Shaun,

No, in my case the issue definitely doesn't exist when the canvas is
empty. However, it's *very* noticeable when I'm dragging over 10's of
thousands of items.

> BTW, I found that canvas performance, in general, is improved for very
> large numbers of items by limiting the number of added tags and using
> my own structures/lists of canvas items for doing canvas operations
> rather than using the tag mechanism.

Yep, that's been exactly my experience too. For that very reason, I'm
managing everything via an in-memory SQLite database, and avoiding
canvas tags except for very specific (and mostly temporary) cases.

That's unfortunate too, as I really like the canvas tagging mechanism.
For this app though, due to the sheer amount of geometry I'm working
with, I just can't afford to use them for general data management.

Jeff

From: Aric Bills on
On Apr 30, 1:45 pm, Jeff Godfrey <jeff_godf...(a)pobox.com> wrote:
> On 4/30/2010 2:13 PM, Will Duquette wrote:
>
> > Well, you could try this:
>
> > 1. Using Img, you can capture the visible area of the canvas as a
> >     Tk image.
> > 2. Delete the contents of the canvas.  (You're going to redraw it
> >     anyway, once you get the rectangle, right?)
> > 3. Position the Tk image on the visible area of the canvas.  Now
> >     there's no geometry to slow things down.
> > 4. When they've selected the rectangle, delete the image, and redraw.
>
> Will,
>
> Thanks for the input.  In my case though, it falls apart at #2, as I
> don't ever delete the canvas contents until I'm through with them. It
> takes too long to load the data for that to be workable.
>
> Currently, once I have the rectangle, zooming things is basically just a
> simple [move] and [scale] command - which is much lighter weight than
> reconstructing the contents of the canvas.
>
> Jeff

In that case, how about this procedure:

1. same as above
2. create a second canvas with the same dimensions as the first; put
the image in this canvas and put this canvas in the place of the first
canvas
3. let the users execute the drag on the second canvas
4. remove the second canvas and put the first one back

In my test code (below), I get some brief flashing when I switch
canvases, but the rectangle-dragging is smooth and responsive.

package require img::window

proc demo {} {
variable c1
variable c2

toplevel .demo
set c1 [canvas .demo.c1]
set c2 [canvas .demo.c2]
grid $c1 -sticky nsew

# populate c1
set colorlist [list red orange yellow green blue purple]
for {set i 0} {$i < 300000} {incr i} {
set x1 [expr {int(rand() * [winfo reqwidth $c1])}]
set y1 [expr {int(rand() * [winfo reqheight $c1])}]
set x2 [expr {$x1 + 1}]
set y2 [expr {$y1 + 1}]
set color [lindex $colorlist \
[expr {int(rand() * [llength $colorlist])}]]
$c1 create rectangle $x1 $y1 $x2 $y2 \
-width 0 \
-fill $color
}

# create bindings
bind $c1 <Button-1> [list dragstart %x %y]
bind $c2 <Motion> [list dragcontinue %x %y]
bind $c2 <ButtonRelease-1> [list dragstop %x %y]
}

proc dragstart {x y} {
variable dragx $x
variable dragy $y
variable dragitem
variable dragimg
variable c1
variable c2

# redimension c2 to the size of c1
$c2 configure -width [winfo width $c1]
$c2 configure -height [winfo height $c1]

# take a snapshot of the contents of c1; put it in c2
# also create the draggable rectangle
set dragimg [image create photo \
-format window \
-data $c1]
$c2 create image 0 0 \
-anchor nw \
-image $dragimg
set dragitem [$c2 create rectangle \
$dragx $dragy $dragx $dragy]

# replace c1 with c2
grid remove $c1
grid $c2 -sticky nsew
}

proc dragcontinue {x y} {
variable dragx
variable dragy
variable dragitem
variable c2

if {![info exists dragitem]} {
return
}
$c2 coords $dragitem $dragx $dragy $x $y
}

proc dragstop {x y} {
variable dragx
variable dragy
variable dragitem
variable dragimg
variable dragzone
variable c1
variable c2

# remember final coordinates
set dragzone [list $dragx $dragy $x $y]

# put c1 back
grid forget $c2
grid $c1

# clean up
$c2 delete all
image delete $dragimg
unset dragx dragy dragitem dragimg
}

demo
From: Jeff Godfrey on
On 4/30/2010 3:20 PM, Aric Bills wrote:

> In that case, how about this procedure:

Aric,

The ingenuity of this group is always quite impressive... ;^)

Thanks for working up an example. Unfortunately, when I tried it here
is was completely non-responsive. Curious about why, I started digging
and found the culprit:

The call to [image create photo ...] takes 32 seconds to return (doh!).

That's running an AS build (8.5.8) under Win7 x64 and using v1.4 of
img::window. I really don't use the img extension, so I don't know if
it needs to be updated, if it's (nearly) broken on Windows, or something
else.

Thoughts?

Jeff

First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9
Prev: Problem Setting Color in ttk combobox
Next: wm geometry