Bug in wxFlatNoteBook with wxRadioButton

BlitzMax Modules Forums/Brucey's Modules/Bug in wxFlatNoteBook with wxRadioButton

Hello, really weird one this. It seems that when you setvalue on a radio button that is on a flatnotebook page that isn't showing, switching a page thereafter creates a wxEVT_COMMAND_RADIOBUTTON_SELECTED event.

I've knocked up a quick and dirty example. A flat note book with 2 tabs, and three radio buttons on each tab. I've connected the radio button events and just told it to log the button press in the debuglog. I've also connected the page change event for the notebook just to be able to setvalue the radio button on the other page which seems to create the bug. Just run the program and select "Blue", then click the position tab, and straight away you will see that will create a radio button event, click back to the colour tab and it'll raise another radio button event. Change pages again and it won't do it any more, until you fiddle with the buttons again.

I tested this with a normal notebook and that seemed fine. Anyway here's the code:

'
' Example application stub generated by wxCodeGen v1.06 : 08 Jan 2009 22:38:00
'
SuperStrict

Framework wx.wxApp
Import wx.wxFrame
Import wx.wxFlatNotebook
Import wx.wxPanel
Import wx.wxRadioButton
Import wx.wxWindow

New MyApp.run()

Type MyApp Extends wxApp

	Method OnInit:Int()

		Local frame:MyFrame = MyFrame(New MyFrame.Create(,, "Test"))
		frame.Show()
		settopwindow(frame)

		Return True
	End Method

End Type

Type MyFrame Extends wxFrame

	Field m_notebook1:wxFlatNotebook
	Field m_panel1:wxPanel
	Field m_radioBtn2:wxRadioButton
	Field m_radioBtn3:wxRadioButton
	Field m_radioBtn4:wxRadioButton
	Field m_panel2:wxPanel
	Field m_radioBtn5:wxRadioButton
	Field m_radioBtn6:wxRadioButton
	Field m_radioBtn7:wxRadioButton


	Method Create:MyFrame(parent:wxWindow = Null, id:Int = wxID_ANY, title:String = "", x:Int = -1, y:Int = -1, w:Int = 500, h:Int = 300, style:Int = wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL)
		Return MyFrame(Super.Create(parent, id, title, x, y, w, h, style))
	End Method
	
	Const wxID_RED:Int = wxid_highest + 1
	Const wxID_BLUE:Int = wxid_highest + 2
	Const wxID_YELLOW:Int = wxid_highest + 3
	
	Const wxID_LEFT:Int = wxid_highest + 4
	Const wxID_RIGHT:Int = wxid_highest + 5
	Const wxID_MIDDLE:Int = wxid_highest + 6

	Method OnInit()

		Local bSizer1:wxBoxSizer
		bSizer1 = new wxBoxSizer.Create(wxVERTICAL)
		m_notebook1 = New wxFlatNotebook.Create(Self, wxID_ANY)
		m_panel1 = new wxPanel.Create(m_notebook1, wxID_ANY,,,,, wxTAB_TRAVERSAL)

		Local bSizer2:wxBoxSizer
		bSizer2 = new wxBoxSizer.Create(wxVERTICAL)
		m_radioBtn2 = New wxRadioButton.Create(m_panel1, wxID_RED, "Red",,, ,, wxRB_GROUP)
		bSizer2.Add(m_radioBtn2, 0, wxALL, 5)

		m_radioBtn3 = New wxRadioButton.Create(m_panel1, wxID_BLUE, "Blue")
		bSizer2.Add(m_radioBtn3, 0, wxALL, 5)

		m_radioBtn4 = New wxRadioButton.Create(m_panel1, wxID_YELLOW, "Yellow")
		bSizer2.Add(m_radioBtn4, 0, wxALL, 5)

		m_panel1.SetSizer(bSizer2)
		m_panel1.Layout()
		bSizer2.Fit(m_panel1)
		m_notebook1.AddPage(m_panel1, "Colours", True)

		m_panel2 = new wxPanel.Create(m_notebook1, wxID_ANY,,,,, wxTAB_TRAVERSAL)

		Local bSizer3:wxBoxSizer
		bSizer3 = new wxBoxSizer.Create(wxVERTICAL)
		m_radioBtn5 = New wxRadioButton.Create(m_panel2, wxID_LEFT, "Left")
		bSizer3.Add(m_radioBtn5, 0, wxALL, 5)

		m_radioBtn6 = New wxRadioButton.Create(m_panel2, wxID_RIGHT, "Right")
		bSizer3.Add(m_radioBtn6, 0, wxALL, 5)

		m_radioBtn7 = New wxRadioButton.Create(m_panel2, wxID_MIDDLE, "Middle")
		bSizer3.Add(m_radioBtn7, 0, wxALL, 5)

		m_panel2.SetSizer(bSizer3)
		m_panel2.Layout()
		bSizer3.Fit(m_panel2)
		m_notebook1.AddPage(m_panel2, "Position", False)


		bSizer1.Add(m_notebook1, 1, wxEXPAND | wxALL, 5)

		SetSizer(bSizer1)
		Layout()
		
		connect(wxID_RED, wxEVT_COMMAND_RADIOBUTTON_SELECTED, onRed)
		connect(wxID_BLUE, wxEVT_COMMAND_RADIOBUTTON_SELECTED, onBlue)
		connect(wxID_YELLOW, wxEVT_COMMAND_RADIOBUTTON_SELECTED, onYellow)
		connect(wxID_LEFT, wxEVT_COMMAND_RADIOBUTTON_SELECTED, onLeft)
		connect(wxID_RIGHT, wxEVT_COMMAND_RADIOBUTTON_SELECTED, onRight)
		connect(wxID_MIDDLE, wxEVT_COMMAND_RADIOBUTTON_SELECTED, onMiddle)
		connectany(wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CHANGED, onPageChanged)

	End Method
	
	Function onRed(event:wxEvent)
		DebugLog "Red"
	End Function
	Function onBlue(event:wxEvent)
		DebugLog "Blue"
	End Function
	Function onYellow(event:wxEvent)
		DebugLog "Yellow"
	End Function
	Function onLeft(event:wxEvent)
		DebugLog "Left"
	End Function
	Function onRight(event:wxEvent)
		DebugLog "Right"
	End Function
	Function onMiddle(event:wxEvent)
		DebugLog "Middle"
	End Function
	Function onPageChanged(event:wxEvent)
		Local frame:MyFrame = MyFrame(event.parent)
		frame.m_radioBtn2.SetValue(True)
	End Function

End Type


Any ideas?

Cheers!

Works as expected on Mac... (ie. no extra events).

I'll have a look at Win32 in the morning :-)

straight away you will see that will create a radio button event

You can fix this by defining your "left" button as the start of a new group with the wxRB_GROUP flag.

One down... one to go :-)

Ahh yeh, I must have assumed the form builder would add it for me as they were on a separate panel :)

This appears to be an "issue" with Windows. I can understand why it might be happening, but I'm not sure how one would avoid it entirely.

On a hidden window, you Set a different radio button. It is checked, the other is unchecked.
However, when shown again, I believe the Windows UI hasn't updated the visual state of the old radio button, which it then toggles off, causing a "unchecked" event to be raised.

One way to ignore this would be to catch the event as normal, but only be interested in the event if IsChecked is true (ie. the button has just been clicked on).

Thanks for your help brucey. I've just changed it to use a standard notebook which works fine, which is a shame as I preferred the different styles available of the flat notebook. I couldn't find any workarounds including your ischecked idea.

Basically in my particle editor each effect has different properties spread over a few tabs with radio buttons for setting the emitter type like point, area, line etc. So if you're on a different tab and select an effect that emits at a point, then select an area effect, switching the tab thereafter would change it from an area to a point. So the event did actually have the isChecked flag set as true. Unless there's some other way of differentiating between the user clicking and the tab clicking for you? I couldn't see any.