wxPerl - custom grid renderer

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
james28909
Knows some wx things
Knows some wx things
Posts: 39
Joined: Mon Jul 01, 2019 8:27 pm

wxPerl - custom grid renderer

Post by james28909 »

i got the scroll events working flawless, for up, down, left and right. so i can track scroll events. i have not been able to get any custom renderer working other than the example in wxperl, which draws ellipses in each cell as directed. i have loaded an image with wxImage and rescaled it to a size to fit inside of a cell, and converted it to a bitmap but it does not seem to support transparency, as in when i draw the image it has a black border.

Let me explain better. this is how i setup the frame/panels/grids.

i have a frame, and on this frame is 2 panels. panel1 for grid1 (row and column headers are hidden) panel2 for grid2. grid2 acts as a substitute for the row labels of grid1. grid2 is just 1 column by 'n' rows. and is placed in the panel2 directly beside panel1/grid1 in such a way to hide the scrollbar of grid2

when i draw the image, since i am not sure how to use a cellrenderer, i draw the image directly to grid2, and it does show but has a black box around it instead of the original transparent edges the image has. i am unsure how to draw the image inside of the grid cell though. so currently i am doing this

Code: Select all

StaticBitmap->new($grid2, -1, $bmp);
which works but is most def not what i want.

i want to have the images transparency in the final result as well, so what would be the best approach to do this? wxDC to wxGraphicsContext? WxPaintDC? i just want to make sure the images transparency is preserved.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: left and right scroll events

Post by doublemax »

Drawing a bitmap with transparency should work. Can you show some code? Do you set the "useMask" flag when drawing the bitmap?

A screenshot might help, too.
Use the source, Luke!
james28909
Knows some wx things
Knows some wx things
Posts: 39
Joined: Mon Jul 01, 2019 8:27 pm

Re: left and right scroll events

Post by james28909 »

let me get a short code example that is compilable working and i will post. i do not set mask.

also, i have made some headway. i think i have set a custom renderer and am able to load the image with wxImage, and then rescale it, then convert it into a bitmap. it looks like it is adding it to the correct cell. ill have to try to place it into a different cell to confirm though. but when i scroll the grid, it smears the cell the image/bitmap is drawn in.

i will post a short self contianed code example in just a few. do you have wxperl installed? so far most of the code is easily ported to wxperl, but some things confuse the heck out of me lol. not to mention i have never tried to use an DC module on any other guis i have made. this grid/tv guide gui i am writing is quite complex and i can only work on it here and there because of my schedule.

when i am done and have the code polished and ironed out, i will be releasing the complete source as for others to tinker with and to use as examples. i have not found ANY WxPerl examples for custom drawing png/bitmap using a custom cell renderer with any DC module or anything. so this will definitely help the wxperl community if anything and your help is greatly appreciated.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: left and right scroll events

Post by doublemax »

No, i don't have wxPerl and did not intend to test the code. I just hoped it would be similar enough to the C++ calls so that i might be able to spot a mistake.
Use the source, Luke!
james28909
Knows some wx things
Knows some wx things
Posts: 39
Joined: Mon Jul 01, 2019 8:27 pm

Re: left and right scroll events

Post by james28909 »

yes, alot of it is pretty straight forward in figuring out the syntax. also, i am not able to do anything right now so it may be a little while before i can post the code. before i finished up this last little programming session, i was actually able to add the images to each cell, but it clobbered the background color and any text. but atleast the correct image was in the correct cell :D

as soon as i can i will post some code though, i am sure i am not doing something right and its probably just afluke that i was able to make the image show up in the cell to begin with lol

EDIT: just thought about something... if i set a new renderer for that cell then maybe i should write the text and background color through the new renderer? am i thinking right? because it seems like setting a new renderer would mean the old renderer and any data associated with it would have been deleted or undefined?
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: left and right scroll events

Post by doublemax »

When you look at the grid sample that comes with wxwidgets, you see that the custom renderer first calls the base renderer. That clears the background with the correct color, draws the text etc. Then it draws its own stuff on top.

It's also important to obey the "rect" parameter. You get a wxDC for the whole grid, not only the current cell, so you must make sure to draw into the correct coordinates.

Code: Select all

void MyGridCellRenderer::Draw(wxGrid& grid,
                              wxGridCellAttr& attr,
                              wxDC& dc,
                              const wxRect& rect,
                              int row, int col,
                              bool isSelected)
{
    wxGridCellStringRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);

    dc.SetPen(*wxGREEN_PEN);
    dc.SetBrush(*wxTRANSPARENT_BRUSH);
    dc.DrawEllipse(rect);
}
Use the source, Luke!
james28909
Knows some wx things
Knows some wx things
Posts: 39
Joined: Mon Jul 01, 2019 8:27 pm

Re: left and right scroll events

Post by james28909 »

ok here is the relevant code:

Code: Select all

#<--- is the comment character for perl;
#build the frame and panels and grids
#Then try to paint the image

$grid->SetCellRenderer($row, $col, CustomRenderer->new() );

package CustomRenderer;

use Wx qw(:everything);
use base 'Wx::PlGridCellRenderer';


sub Draw {

    my ( $self, $grid, $attr, $dc, $rect, $row, $col, $sel ) = ( shift, @_ );

    my $image = Wx::Image->new( "images/111.png", wxBITMAP_TYPE_PNG );
    $image->Rescale( 35, 35, 'wxIMAGE_QUALITY_HIGH' );

    my $bmp = Wx::Bitmap->new($image);

    if ( $bmp->Ok() ) {
    
		#$dc is Wx::PaintDC($grid);
		
        $dc->DrawBitmap( $bmp, $rect->x, $rect->y, 1 );
    }
}

sub Clone {
	my $self = shift;
	return $self->new;
}
the images are drawn, but as soon as you scroll it smears and you have to minimize and bring the window back up for it to display properly. I did read somewhere about loading images from a MemoryDC could cause issues with artifacts like i am experiencing but If i try to "use base "Wx::GridCellRenderer" " or any other renderer, no picture is drawn and no objects are imported into the CustomRenderer. if i try to dump the data from each variable $self, $grid, $attr, $dc etc, it is empty. so maybe i am not importing it right or something. its funny though because is i "use base 'Wx::PlGridCellRenderer' " then the images are displayed but they smear very badly until minimized and brought back up.

like i said earlier i know you are not a perl guru or anything so i appreciate your help this far. but do you have any speculation on what is going wrong?

EDIT: how can i copy the original renderer and all its data? maybe the problem is PlGridCellRenderer and how it draws. is there a way i can copy/clone just the cell renderer and/or anything within the cell including background color etc?
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: left and right scroll events

Post by doublemax »

I believe the redraw artifacts are caused by the fast that not the whole cell gets redrawn if it's bigger than 35 pixel in any dimension. Calling the base renderer would fix that. If you just want to draw the bitmap and nothing else, just clearing the background before drawing the bitmap should be enough.

Something like:

Code: Select all

$dc->SetBrush( wxColour(255,255,255) )   // you need to figure out the proper syntax for the color
$dc->DrawRect( $rect )
$dc->DrawBitmap( $bmp, $rect->x, $rect->y, 1 );
Use the source, Luke!
james28909
Knows some wx things
Knows some wx things
Posts: 39
Joined: Mon Jul 01, 2019 8:27 pm

Re: left and right scroll events

Post by james28909 »

well see, i dont want to clear the data in the cell. there is information and a colored background i want to preserve, and just update the cell with the image.

before the call to set renderer, i add this information to the cell, then $grid->SetCellRenderer(); clobbers all that, and then the image it draws has artifacts/smearing.

another thing is, anything i do to this $dc object causes the whole grid to not get painted. instead just displays a grey window that crashes in 3-4 secs. if i try to change the brush or anything like that.

i can change the $dc to Wx::ClientDC->new($grid); but then nothing gets drawn at all and its just a white (default color for msw) background that also smears on scroll. i will post some pictures later today or maybe a video of it. it works great until i attempt to draw pictures.

once thing i thought about is this 'PlGridCellRenderer'.. maybe somehow there is a method that is set (or not set) that is causing this artifacts? but sadly tearing through the source of Wx perl in my local site lib, i cannot find but one call to this PlGridCellRenderer. and the call is just a declaration, so there must be more going on under the hood.

if i 'use base Wx::PlGridCellRenderer' and dump the contents of $self, $grid, $attr, $rect, $row, $col etc, it shows they are defined and usable ($dc shows Wx::PaintDC) etc. if i try 'use base Wx::GridCellRenderer' or 'use base Wx::GridCellStringRenderer' then $self, $grid $attr $rect $row $col etc is all undefined. seems calling SetCellRenderer() needs PlGridCellRenderer. What i might do is try to replicate this in c++ (adding the image to cells) and see if it works on the latest stable version. im using wxwidgets 2.9.4 in wxperl because it is the only one and i have not figured out how to build it for wxperl yet.

but like i said, anything i do to $dc like SetBrush or etc, causes it to not paint any of the gui and it crashes 3-4 secs after the window is created

EDIT: should i start a new topic since the title of this one is for scrolling events, which has been resolved?
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxPerl - custom grid renderer

Post by doublemax »

EDIT: should i start a new topic since the title of this one is for scrolling events, which has been resolved?
I split the topic and made a new one.
well see, i dont want to clear the data in the cell. there is information and a colored background i want to preserve, and just update the cell with the image.
You can't do that, you need to draw everything. Either by calling a matching base renderer or by drawing everything yourself.
another thing is, anything i do to this $dc object causes the whole grid to not get painted. instead just displays a grey window that crashes in 3-4 secs. if i try to change the brush or anything like that.
That must be something wxPerl specific. I have no idea what could cause this.
i can change the $dc to Wx::ClientDC->new($grid);
Don't go that path, it leads nowhere.
Use the source, Luke!
james28909
Knows some wx things
Knows some wx things
Posts: 39
Joined: Mon Jul 01, 2019 8:27 pm

Re: wxPerl - custom grid renderer

Post by james28909 »

the thing that confuses me is, the PLGridCellRenderer has a Wx::PaintDC set for it. it is my understanding that i need to use wxPaintDC only with an EVT_PAINT event (which i am not using) and wxClientDC when not usung an EVT_PAINT.

when i try to draw the images, they are displayed but smear, but in my debug output ive created some print statements telling me when images are loaded and set, and it seems they are loading, and setting fine i mean i can see them but as soon as they are painted they start smearing so maybe it has to have something to do with the grid itself being updated per scroll but not the images since it is a custom renderer?

maybe i should use citrus perl to test since it has wx and alien wxwidgets already installed. i believe the version for citrus perl wx is 3.0.2 so it is updated and newer than the current version i am using now. will test and report back.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxPerl - custom grid renderer

Post by doublemax »

it is my understanding that i need to use wxPaintDC only with an EVT_PAINT event (which i am not using)
I think you are using a wxPaintDC, i'm sure the renderers are called from within wxGrid's paint event. But at least in the C++ version, all methods get a generic wxDC, so it shouldn't matter.
when i try to draw the images, they are displayed but smear,
Can you show a screenshot?

In the C++ version you just pass all parameters unmodified to a built-in renderer.

Code: Select all

wxGridCellStringRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
Can't you do the same in wxPerl?
Use the source, Luke!
james28909
Knows some wx things
Knows some wx things
Posts: 39
Joined: Mon Jul 01, 2019 8:27 pm

Re: wxPerl - custom grid renderer

Post by james28909 »

i will post some screen shots or a short video clip shortly.
james28909
Knows some wx things
Knows some wx things
Posts: 39
Joined: Mon Jul 01, 2019 8:27 pm

Re: wxPerl - custom grid renderer

Post by james28909 »

ok here is some pics. please do not worry about the black box in top left, i just need to add a panel and fill it in and havent got to it yet.

but to explain the layout, the main grid has row and col labels hidden. then another grid is set to the left side of the main grid, which has channel names and col and row labels hidden... and another grid on the top which has time slots and row and col labels hidden. the panel each of these grids are put on are of a size to hide all of the scroll bars. also the grids scroll bars are synced and work perfectly thanks to your help the other day so thanks again for that.

but the problem is in the channel grid (left of the main grid). also, i am using just one picture as filler material to show the problem. when i first run the gui, everything looks as if it is working perfectly:
Image

but as soon as you start scrolling is when the problem occurs:
Image

as you can see the image, actually the whole cell, smears as you scroll. it does this smearing even if i do not add images so i think it has something to do with the CustomRenderer, or something PlGridCellRenderer has loaded but i am not sure. when i use the default renderer (without calling CustomRenderer) everything is just fine and no smearing effect.

if you have any more advice to give i sure would appreciate it. either way thanks for your help this far
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxPerl - custom grid renderer

Post by doublemax »

But the redraw looks fine if the window is drawn completely?

Have you tried clearing the background like i wrote before:

Code: Select all

$dc->SetBrush( wxColour(255,255,255) )   // you need to figure out the proper syntax for the color
$dc->DrawRect( $rect )
$dc->DrawBitmap( $bmp, $rect->x, $rect->y, 1 );
Use the source, Luke!
Post Reply