Prima::RubberBand - draw rubberbands |
Prima::RubberBand - draw rubberbands
The motivation for this module was that I was tired to see corrupted screens on Windows 7 when dragging rubberbands in Prima code. Even though MS somewhere warned of not doing any specific hacks to circumvent the bug, I decided to give it a go anyway.
This module thus is a Prima::Widget/rect_focus
with a safeguard. The only
thing it can do is to draw a static rubberband - but also remember the last
coordinates drawn, so cleaning comes for free.
The idea is that a rubberband object is meant to be a short-lived one: as soon as it get instantiatet it draws itself on the screen. When it is destroyed, the rubberband is erased too.
use strict; use Prima qw(Application RubberBand); sub xordraw { my ($self, @new_rect) = @_; my $o = $::application; $o-> begin_paint; $o-> rubberband( @new_rect ? ( rect => \@new_rect ) : ( destroy => 1 ) ); $o-> end_paint; } Prima::MainWindow-> create( onMouseDown => sub { my ( $self, $btn, $mod, $x, $y) = @_; $self-> {anchor} = [$self-> client_to_screen( $x, $y)]; xordraw( $self, @{$self-> {anchor}}, $self-> client_to_screen( $x, $y)); $self-> capture(1); }, onMouseMove => sub { my ( $self, $mod, $x, $y) = @_; xordraw( $self, @{$self-> {anchor}}, $self-> client_to_screen( $x, $y)) if $self-> {anchor}; }, onMouseUp => sub { my ( $self, $btn, $mod, $x, $y) = @_; xordraw if delete $self-> {anchor}; $self-> capture(0); }, ); run Prima;
Allowed modes: auto, xor, full
Prima::Widget
, but read-only.
The module adds a single method to Prima::Widget
namespace, rubberband
(see example of use in the synopsis).
rubberband(%profile)
Prima::RubberBand
with %profile
, also sets canvas
to $self
unless canvas
is set explicitly.
rubberband()
Prima::RubberBand
object
Prima::RubberBand
object
Dmitry Karasik, <dmitry@karasik.eu.org>.
rect_focus in the Prima::Widget manpage, examples/grip.pl
Quote from http://blogs.msdn.com/b/greg_schechter/archive/2006/05/02/588934.aspx :
``One particularly dangerous practice is writing to the screen, either through
the use of GetDC(NULL)
and writing to that, or attempting to do XOR rubber-band
lines, etc ... Since the UCE doesn't know about it, it may get cleared in the
next frame refresh, or it may persist for a very long time, depending on what
else needs to be updated on the screen. (We really don't allow direct writing
to the primary anyhow, for that very reason... if you try to access the
DirectDraw primary, for instance, the DWM will turn off until the accessing
application exits)''
This quote seems to explain the effect why screen sometimes gets badly corrupted when using a normal xor rubberband. UCE ( Update Compatibility Evaluator ?? ) seems to be hacky enough to recognize some situations, but not all. It seems that depending on which widget received mouse button just before initialting rubberband drawing matters somehow. Anyway, the module tries to see if we're under Windows 7 aero, and if so, turns the 'full' mode on.
Prima::RubberBand - draw rubberbands |