#54 Splitter drawing problem

closed-fixed
None
1
2006-10-15
2005-11-21
Robert May
No

The script below show the problem: drag the splitter to
the left a short distance, then back to the right an
equal amount. You’ll notice that there is a nasty
artifact showing up on the screen. Of course when your
test in the text field overlaps this artifact, it is
resolved within the relative area of the text

#!perl -w
use strict;
use warnings;
use Win32::GUI;

my $mw = Win32::GUI::Window->new(
-title => "Splitter Test",
-pos => [100,100],
-size => [500,400],
-onResize => \&main_resize,
);

$mw->AddTextfield(
-name => "TF1",
-multiline => 1,
-width => 200,
);

$mw->AddSplitter(
-name => "SP",
-left => 200,
-width => 10, #FATTY
-onRelease => \&do_splitter,
);

$mw->AddTextfield(
-name => "TF2",
-multiline => 1,
-left => 200 + $mw->SP->Width(),
);

$mw->Show();
Win32::GUI::Dialog();
exit(0);

sub do_splitter {
my ($splitter, $coord) = @_;

$mw->TF1->Width($coord);
$mw->TF2->Move($coord+$mw->SP->Width(), 0);

$mw->TF2->Resize($mw->ScaleWidth()-$mw->SP->Width(),
$mw->ScaleHeight());
}

sub main_resize
{
my $self = shift;

$mw->TF1->Height($self->ScaleHeight());
$mw->SP->Height($self->ScaleHeight());

$mw->TF2->Resize($mw->ScaleWidth()-$self->TF1->Width()-$mw->SP->Width(),
$mw->ScaleHeight());
}

__END__

Discussion

  • Nobody/Anonymous

    Logged In: NO

    Ok, this is probably a different issue/bug but as it
    involves a splitter...

    The example below has the same problem in the original
    script posted in this tracker. However, when the main
    radio button is checked, the window issues an
    InvalidateRect(1); which should repaint the whole window.
    InvalidateRect, doesn't repaint the screen fully - but
    when the background option is commented out,
    InvalidateRect works. I suspect that something odd is
    happening during WM_ERASEBKGND Notification when we have a
    background color set (?).

    use strict;
    use Win32::GUI;

    my $RichEditText = 'Some text';

    my $MainHeight = 600;
    my $MainWidth = 600;

    my $Desk = Win32::GUI::GetDesktopWindow();

    my $Main = new Win32::GUI::Window
    (
    -height => $MainHeight,
    -width => $MainWidth,
    -text => 'testing InvalidateRect()',
    -onResize => \&Main_OnResize,
    -onTerminate => \&Main_OnTerminate,
    -background => 0x0000FF,
    );

    my $Edit = $Main->AddRichEdit
    (
    -text => $RichEditText,
    -left=>10,-top=>10,
    -width=>$MainWidth-110,
    -height=>$MainHeight-20,
    );

    my $Splitter = $Main->AddSplitter
    (
    -left => 10, -top => 10,
    -width => 10, -height => $MainHeight-20,

    -onRelease => \&Splitter_OnRelease,
    );

    my $Test1 = $Main->AddRadioButton
    (
    -left => $MainWidth-90 , -top => 20,
    -text => 'None',
    -checked => 1,
    );

    my $Test2 = $Main->AddRadioButton
    (
    -left => $MainWidth-90 , -top => 40,
    -text => 'Main',
    );

    my $Test3 = $Main->AddRadioButton
    (
    -left=>0,-top=>0,# -width=>0,-height=>0,

    -left => $MainWidth-90 , -top => 60,
    -text => 'Desk',
    );

    sub Splitter_OnRelease
    {
    XY($Edit, 0,0, XY($Splitter,1,0),
    1,1, Dif(XY($Main,1,1),100,10) );

    if($Test1->Checked())
    {
    # no InvalidateRect()
    }
    elsif($Test2->Checked())
    {
    $Main->InvalidateRect(1);
    }
    elsif($Test3->Checked())
    {
    Win32::GUI::InvalidateRect(0,0);
    }

    }

    sub Main_OnResize
    {
    Y($Splitter,0,10, 1,Y($Main,1)-10);
    XY($Edit, 0,0, XY($Splitter,1,0),
    1,1, Dif(XY($Main,1,1),100,10) );
    X($Test1,0, X($Main,1)-90);
    X($Test2,0, X($Main,1)-90);
    X($Test3,0, X($Main,1)-90);

    }

    XY($Main, .5,.5, XY($Desk, .5,.5));

    Main_OnResize();

    $Main->Show();
    Win32::GUI::Dialog();
    sub Main_OnTerminate { -1 }

    # ---------------------------------------------------------
    ---------------

    sub Sum
    {
    my @sum;
    for(my($i,$j)=(0,@_/2);$j<=$#_;$i++,$j++)
    {
    push @sum,$_[$i]+$_[$j]
    }
    @sum;
    }

    sub Dif
    {
    my @dif;
    for(my($i,$j)=(0,@_/2);$j<=$#_;$i++,$j++)
    {
    push @dif,$_[$i]-$_[$j]
    }
    @dif;
    }

    sub X
    {
    if(@_ == 2)
    {
    my ($O,$x)=@_;
    my $parent = eval{$O->GetParent()};
    return $x * Win32::GUI::ScaleWidth($O) if ! defined
    ($parent);
    return $x * $O->Width() + $O->Left();
    }
    elsif(@_ == 3)
    {
    my ($A,$ax,$Px) = @_;
    $A->Left($Px-$ax*$A->Width());
    }
    else # @_ == 5
    {
    my ($A, $ax1,$Px1, $ax2,$Px2) = @_;
    my $ok1 = defined($ax1) && defined($Px1);
    my $ok2 = defined($ax2) && defined($Px2);
    if($ok1 && $ok2)
    {
    my $Aw = eval { int(($Px2-$Px1)/($ax2-$ax1))};
    $A->Width($Aw) if defined($Aw);

    my $Ax = eval { int(($ax2*$Px1-$ax1*$Px2)/($ax2-
    $ax1)) };
    $A->Left($Ax) if defined ($Ax);
    }
    elsif($ok1){$A->Left($Px1-$ax1*$A->Width())}
    elsif($ok2){$A->Left($Px2-$ax2*$A->Width())}
    }
    }

    sub Y
    {
    if(@_ == 2)
    {
    my ($O,$y)=@_;
    my $parent = eval{$O->GetParent()};
    return $y * Win32::GUI::ScaleHeight($O) if ! defined
    ($parent);
    return $y * $O->Height() + $O->Top();
    }
    elsif(@_ == 3)
    {
    my ($A,$ay,$Py) = @_;
    $A->Top( $Py - $ay*$A->Height());
    }
    else # @_ == 5
    {
    my ($A, $ay1,$Py1, $ay2,$Py2) = @_;
    my $ok1 = defined($ay1) && defined($Py1);
    my $ok2 = defined($ay2) && defined($Py2);
    if($ok1 && $ok2)
    {
    my $Ah = eval { int(($Py2-$Py1)/($ay2-$ay1))};
    $A->Height($Ah) if defined($Ah);

    my $Ay = eval { int(($ay2*$Py1-$ay1*$Py2)/($ay2-
    $ay1))};
    $A->Top($Ay) if defined $Ay;
    }
    elsif($ok1){$A->Top($Py1-$ay1*$A->Height())}
    elsif($ok2){$A->Top($Py2-$ay2*$A->Height())}
    }
    }

    sub XY
    {
    if(@_ == 3)
    {
    my ($O,$x,$y) = @_;
    return ( X($O,$x), Y($O,$y) )
    }
    elsif(@_ == 5)
    {
    my ($A,$ax,$ay,$Px,$Py) = @_;
    X($A,$ax,$Px);
    Y($A,$ay,$Py);
    }
    else # @_ == 9
    {
    my ($A, $ax1,$ay1, $Px1,$Py1,
    $ax2,$ay2, $Px2,$Py2) = @_;
    X($A,$ax1,$Px1,$ax2,$Px2);
    Y($A,$ay1,$Py1,$ay2,$Py2);
    }
    }

    __END__

     
  • Robert May

    Robert May - 2006-01-05

    Logged In: YES
    user_id=674651

    The InvalidateRect issue is resolved (will be in CVS soon).
    There was an issue with WM_ERASEBKGND and having a
    background colour set.

    Rob.

     
  • Robert May

    Robert May - 2006-06-07
    • priority: 5 --> 1
    • status: open --> open-fixed
     
  • Robert May

    Robert May - 2006-06-07

    Logged In: YES
    user_id=674651

    There is a problem with do_splitter code above. The line
    that reads:

    $mw->TF2->Resize($mw->ScaleWidth()-$mw->SP->Width(),$mw->ScaleHeight());

    should read:

    $mw->TF2->Resize($mw->ScaleWidth()-$mw->TF1->Width()-$mw->SP->Width(),
    $mw->ScaleHeight());

    The result of this omission is that the control i no resized
    as a result of the splitter move, and so it is not re-drawn.

    I re-wrote the splitter class before I discovered this, but
    the new code is more robust (covering several problems with
    the old code), and has a nicer (IMHO) splitter, that can't
    be made to move outside the window area.

    New code will be in the next release.

    Regards,
    Rob.

     
  • Robert May

    Robert May - 2006-10-15
    • status: open-fixed --> closed-fixed
     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks