Array of BitmapButtons display only first bitmap Topic is solved

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.
Post Reply
van_user
Experienced Solver
Experienced Solver
Posts: 55
Joined: Wed Jun 11, 2008 9:28 pm
Location: UA

Array of BitmapButtons display only first bitmap

Post by van_user »

Hello. First, sorry for my English.
Now problem: I can`t find the reason why every element in array of wxBitmapButton(s) show bitmap assigned to the first bitmapbutton.
Here my code:
Initialization of colours:

Code: Select all

for( i = 0; i < 9; ++i)
	fun_colours[ i] = wxColour( 255/ ( i + 1), 0, 0);
fun_colours[ 7] = wxColour( 30, 140, 49);
And here main part ( fun_colours_e = fun_colours, fun_quantity_e = 9):

Code: Select all

	const int bitmap_width( 75);
	const int bitmap_height( 25);
	int bitmap_width1( bitmap_width);
	--bitmap_width1;
	int bitmap_height1( bitmap_height);
	--bitmap_height1;

	wxPanel* Main_panel;
	Main_panel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxSize( 85, 300));

	button_mas = new wxBitmapButton*[ fun_quantity_e];
	bitmap_mas = new wxBitmap*[ fun_quantity_e];
	wxMemoryDC fill_bitmap_dc;
	wxPen* fill_pen = new wxPen( fun_colours_e[ 0]);
	wxBrush* fill_brush = new wxBrush( fun_colours_e[ 0]);

	int i( 0);
	for( ; i < fun_quantity_e; ++i)
	{
		bitmap_mas[ i] = new wxBitmap( bitmap_width, bitmap_height, -1);
		fill_pen -> SetColour( fun_colours_e[ i]);
		fill_bitmap_dc. SetPen( *fill_pen);
		fill_brush -> SetColour( fun_colours_e[ i]);
		fill_bitmap_dc. SetBrush( *fill_brush);
		fill_bitmap_dc. SelectObject( *( bitmap_mas[ i]));
		fill_bitmap_dc. DrawRectangle( 0, 0, bitmap_width1, bitmap_height1/ 2 + i * bitmap_height1/ ( 2 * fun_quantity_e));
		if( i != 0)
		{
			fill_bitmap_dc. SetPen( *wxWHITE_PEN);
			fill_bitmap_dc. DrawLine( 0, 0, bitmap_width1, bitmap_height1/ 2 + i * bitmap_height1/ ( 2 * fun_quantity_e));
		}
		button_mas[ i] = new wxBitmapButton( Main_panel, FIRST_COLOUR_BUTTON_PRESS, *( bitmap_mas[ i]));
		fill_bitmap_dc. SelectObject( wxNullBitmap);
	}
	fill_bitmap_dc. SetPen( wxNullPen);
	fill_bitmap_dc. SetBrush( wxNullBrush);
	fill_bitmap_dc. SelectObject( wxNullBitmap);

	wxBitmap* bitmap_s_a = new wxBitmap( bitmap_width, bitmap_height);
	fill_bitmap_dc. SelectObject( *bitmap_s_a);
	fill_pen -> SetColour( 134, 20, 120);
	fill_brush -> SetColour( 255 - 134, 255 - 20, 255 - 120);
	--bitmap_width1;
	--bitmap_height1;
	fill_bitmap_dc. DrawRectangle( 1, 1, bitmap_width1, bitmap_height1);
	wxBitmapButton* button_s_a = new wxBitmapButton( this, FIRST_COLOUR_BUTTON_PRESS, *bitmap_s_a);

	Main_sizer = new wxBoxSizer( wxVERTICAL);
	Main_sizer -> AddSpacer( 5);
	for( i = 0; i < fun_quantity_e; ++i)
		Main_sizer -> Add( button_mas[ i]);

	wxBoxSizer* top_sizer;
	top_sizer = new wxBoxSizer( wxHORIZONTAL);
	top_sizer -> Add( Main_sizer);
	Main_panel -> SetSizer( Main_sizer);
	Main_sizer -> Fit( Main_panel);
	Main_sizer -> SetSizeHints( this);
	Main_sizer -> AddSpacer( 15);
	Main_sizer -> Add( button_s_a);
	SetSizer( top_sizer);

Code: Select all

void Colour_Frame :: On_paint( wxPaintEvent& event)
{
	wxPaintDC paint_dc( this);
	int width( 200);
	int height( 0);
	const int bitmap_width( 75);
	const int bitmap_height( 25);
	for( int i( 0); i < 9; ++i)
		paint_dc. DrawBitmap( *( bitmap_mas[ i]), width, height + i * bitmap_height + i);
	wxPen debug_pen( *wxWHITE_PEN);
	paint_dc. SetPen( debug_pen);
	paint_dc. DrawLine( width, 0, width + bitmap_width, height + 9 * bitmap_height + 9);
	paint_dc. SetPen( wxNullPen);
//	event. Skip( );
	return;
}
result of execution this code in attachment.[/code]
Attachments
Frame_shot
Frame_shot
post.JPG (15.03 KiB) Viewed 2728 times
Win XP (SP0), mingw, wx 2.9.0
Grrr
Earned some good credits
Earned some good credits
Posts: 126
Joined: Fri Apr 11, 2008 8:48 am
Location: Netherlands

Post by Grrr »

In the for-loop you are modifying the pen and brush that are already selected in the DC. I think this causes the problem.

Try and move the 3 lines after the loop into the loop.

Code: Select all

int i( 0);
for( ; i < fun_quantity_e; ++i)
{
    bitmap_mas[ i] = new wxBitmap( bitmap_width, bitmap_height, -1);
    fill_pen -> SetColour( fun_colours_e[ i]);
    fill_bitmap_dc. SetPen( *fill_pen);
    fill_brush -> SetColour( fun_colours_e[ i]);
    fill_bitmap_dc. SetBrush( *fill_brush);
    fill_bitmap_dc. SelectObject( *( bitmap_mas[ i]));
    fill_bitmap_dc. DrawRectangle( 0, 0, bitmap_width1, bitmap_height1/ 2 + i * bitmap_height1/ ( 2 * fun_quantity_e));
    if( i != 0)
    {
        fill_bitmap_dc. SetPen( *wxWHITE_PEN);
        fill_bitmap_dc. DrawLine( 0, 0, bitmap_width1, bitmap_height1/ 2 + i * bitmap_height1/ ( 2 * fun_quantity_e));
    }
    button_mas[ i] = new wxBitmapButton( Main_panel, FIRST_COLOUR_BUTTON_PRESS, *( bitmap_mas[ i]));
    fill_bitmap_dc. SelectObject( wxNullBitmap);

    fill_bitmap_dc. SetPen( wxNullPen);
    fill_bitmap_dc. SetBrush( wxNullBrush);
    fill_bitmap_dc. SelectObject( wxNullBitmap);
}
Personally, I would define the pen and brush as local variables inside the for loop. This avoids using pointers, although it might be more time consuming (as the resource needs to be created by the OS).
van_user
Experienced Solver
Experienced Solver
Posts: 55
Joined: Wed Jun 11, 2008 9:28 pm
Location: UA

Post by van_user »

Grrr wrote:In the for-loop you are modifying the pen and brush that are already selected in the DC. I think this causes the problem.

Try and move the 3 lines after the loop into the loop.

Code: Select all

int i( 0);
for( ; i < fun_quantity_e; ++i)
{
    bitmap_mas[ i] = new wxBitmap( bitmap_width, bitmap_height, -1);
    fill_pen -> SetColour( fun_colours_e[ i]);
    fill_bitmap_dc. SetPen( *fill_pen);
    fill_brush -> SetColour( fun_colours_e[ i]);
    fill_bitmap_dc. SetBrush( *fill_brush);
    fill_bitmap_dc. SelectObject( *( bitmap_mas[ i]));
    fill_bitmap_dc. DrawRectangle( 0, 0, bitmap_width1, bitmap_height1/ 2 + i * bitmap_height1/ ( 2 * fun_quantity_e));
    if( i != 0)
    {
        fill_bitmap_dc. SetPen( *wxWHITE_PEN);
        fill_bitmap_dc. DrawLine( 0, 0, bitmap_width1, bitmap_height1/ 2 + i * bitmap_height1/ ( 2 * fun_quantity_e));
    }
    button_mas[ i] = new wxBitmapButton( Main_panel, FIRST_COLOUR_BUTTON_PRESS, *( bitmap_mas[ i]));
    fill_bitmap_dc. SelectObject( wxNullBitmap);

    fill_bitmap_dc. SetPen( wxNullPen);
    fill_bitmap_dc. SetBrush( wxNullBrush);
    fill_bitmap_dc. SelectObject( wxNullBitmap);
}
Personally, I would define the pen and brush as local variables inside the for loop.
I have realized this variant. But result, as I expected, was the same. Sadly I can`t reach in gdb this piece of code to observe the execution.
This avoids using pointers, although it might be more time consuming (as the resource needs to be created by the OS).
I use opposite way in programming ( less calculations, more optimizations). And I don`t see reason why anybody need to avoid using pointers ( except for some object in wxWidgets).
Win XP (SP0), mingw, wx 2.9.0
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

Can you reproduce this issue in a minimal compilable sample?
van_user
Experienced Solver
Experienced Solver
Posts: 55
Joined: Wed Jun 11, 2008 9:28 pm
Location: UA

Post by van_user »

Auria wrote:Can you reproduce this issue in a minimal compilable sample?
Same result. I create application with 1 frame (in attachment directory (7-zip) with code and makefile), initailization of colours is in wxApp::OnInit(). Maybe I don`t understend your reply?
Attachments
minimal.7z
(3.31 KiB) Downloaded 45 times
Win XP (SP0), mingw, wx 2.9.0
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

This is what I get when I run this sample on my computer, IIRC this is the correct expected result, or have I misunderstood?
Attachments
wxbutton.png
wxbutton.png (13.62 KiB) Viewed 2684 times
van_user
Experienced Solver
Experienced Solver
Posts: 55
Joined: Wed Jun 11, 2008 9:28 pm
Location: UA

Post by van_user »

Auria wrote:This is what I get when I run this sample on my computer, IIRC this is the correct expected result, or have I misunderstood?
:shock: !!! Yes, this is what I want to receve. I have tried ( hope you understand what I wrote) to compile again - but receive my screen_shot. And where could be the reason of wrong execution? I compile in 2 different computers ( but with same version of wxWidgets).
Win XP (SP0), mingw, wx 2.9.0
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

Hmm... are both on Windows? It might be a bug in wxMSW, after all I'm in wxMAC

What wxWidgets version are you using? If it's not the latest try updating. Otherwise, it might be a case for mailing list and/or bug report and/or digging into wx code

EDIT: ah noticed your sigtnature. So try updating to 2.8.7 first
EDIT2: maybe you could also check if bitmap buttons display fine in samples
van_user
Experienced Solver
Experienced Solver
Posts: 55
Joined: Wed Jun 11, 2008 9:28 pm
Location: UA

Post by van_user »

Thanks for help. Will try to do these steps. Result will be on next week (internet is not accessible).
About samples - I don`t find any with wxBitmapButtons in wx/samples directory.
Win XP (SP0), mingw, wx 2.9.0
van_user
Experienced Solver
Experienced Solver
Posts: 55
Joined: Wed Jun 11, 2008 9:28 pm
Location: UA

Post by van_user »

I have tried to compile wx_2.8.7 but receive some errors. Will try again. And when will see execution of the code.
Win XP (SP0), mingw, wx 2.9.0
van_user
Experienced Solver
Experienced Solver
Posts: 55
Joined: Wed Jun 11, 2008 9:28 pm
Location: UA

Post by van_user »

Finally I successfully compile wx 2.8.7. But my program still doesn`t work correct.
Edit: correct - display different bitmaps for bitmapbuttons.
What to do?
Last edited by van_user on Thu Jul 03, 2008 11:57 pm, edited 1 time in total.
tan
wxWorld Domination!
wxWorld Domination!
Posts: 1471
Joined: Tue Nov 14, 2006 7:58 am
Location: Saint-Petersburg, Russia

Post by tan »

Hi,
van_user wrote:Finally I successfully compile wx 2.8.7. But my program still doesn`t work correct. What to do?
Don't use the same ID for all buttons:

Code: Select all

		button_mas[ i] = new wxBitmapButton( Main_panel, FIRST_COLOUR_BUTTON_PRESS, *( bitmap_mas[ i]));
// It will work
		button_mas[ i] = new wxBitmapButton( Main_panel, FIRST_COLOUR_BUTTON_PRESS+i, *( bitmap_mas[ i]));
OS: Windows XP Pro
Compiler: MSVC++ 7.1
wxWidgets: 2.8.10
van_user
Experienced Solver
Experienced Solver
Posts: 55
Joined: Wed Jun 11, 2008 9:28 pm
Location: UA

Post by van_user »

tan wrote:Hi
Hello to Rus.
tan wrote: Don't use the same ID for all buttons:

Code: Select all

button_mas[ i] = new wxBitmapButton( Main_panel, FIRST_COLOUR_BUTTON_PRESS, *( bitmap_mas[ i]));
This is for debug. In release handling may change (this is not actually problem).
The question - what to do with buttons. I can draw rectangles on frame and handle clicks in certain area, but this is "bad" way (as for me).
I have a favour to ask of you. Can you download minimal sample (see above), execute in your system and post result? Sample work correct on Mac, but what will be in winwows on another computers?
Thanks for help.
Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria »

Ah I understand tan's point - please do try with different IDs. On some systems, it is possible that widgets are identified by ID. If they all have the same ID, perhaps they will be assumed to all be the same
van_user
Experienced Solver
Experienced Solver
Posts: 55
Joined: Wed Jun 11, 2008 9:28 pm
Location: UA

Post by van_user »

:shock: . The reason was ID`s. I thought this IDs are used for event handling. Now works fine. Thanks a lot.
Win XP (SP0), mingw, wx 2.9.0
Post Reply