Read Only Checkbox

Are you writing your own components and need help with how to set them up or have questions about the components you are deriving from ? Ask them here.
kaede
In need of some credit
In need of some credit
Posts: 7
Joined: Thu Feb 28, 2008 4:01 am

Read Only Checkbox

Post by kaede » Thu Feb 28, 2008 4:55 am

Hi,

I am trying to create a read-only checkbox. I add my event handler via EVT_CHECKBOX

Code: Select all

EVT_CHECKBOX(wxID_ANY, MyCheckBox::OnToggle)

MyCheckBox : public wxCheckBox

MyCheckBox::OnToggle(wxCommandEvent& event)
{
   if(readOnly) return;
   event.Skip()
}
However, when I clicked on the checkbox (even readOnly is true) the checkbox is still clickable. I was wondering what is the proper way to do it?

I know I could use Disable() but then I don't like that it gray out the text. Is there a way not to gray out the text if Disable is called>

Thanks,

clyde729
Super wx Problem Solver
Super wx Problem Solver
Posts: 426
Joined: Mon May 29, 2006 10:50 pm
Location: Jena, Germany

Post by clyde729 » Thu Feb 28, 2008 11:20 am

You will need to catch some mouse events and "eat" them. I think catching "left down" and "left double click" would be a good start. Also remain that a checkbox is toggable via "space" key if it has focus. So this needs to be changed, too.

Another way would be to catch the "checkbox clicked" event and just reset the value.

Last: Owner written control. Replace the checkbox by an image an toggle it, if it is editable, or not, if it is read only.
OS: Windows XP Home, Compiler: MingW, Version: wxWidgets 2.8.0, IDE: wx-Devcpp

Jorg
Moderator
Moderator
Posts: 3971
Joined: Fri Aug 27, 2004 9:38 pm
Location: Delft, Netherlands
Contact:

Post by Jorg » Thu Feb 28, 2008 12:26 pm

To do it really fancy, I would create my own control that shows a checkbox next to a bit of text, and when it's read only, show an "obvious" image and hide the wxCheckBox. Any other way will confuse the user. If it's clickable but not changable the user wonders WHY. If it's disabled the user thinks it is not applicable to click it, thus read only. A way in between is creating a wxPanel with a wxCheckBox and a wxStaticText as text in a horizontal sizer. Then, when you set it to read only, hide the wxCheckBox and in your OnPaint routine of the parent panel, draw the check state of the wxCheckBox with an empty square or a cross (or use some other fancy icons)

Regards,
- Jorgen
Forensic Software Engineer
Netherlands Forensic Insitute
http://english.forensischinstituut.nl/
-------------------------------------
Jorg's WasteBucket
http://www.xs4all.nl/~jorgb/wb

kaede
In need of some credit
In need of some credit
Posts: 7
Joined: Thu Feb 28, 2008 4:01 am

Post by kaede » Thu Feb 28, 2008 4:12 pm

I have try catching mouse click event as well as the checkbox event. But it is of no use. The checkbox is still clickable.

It looks like that the event goes thru to the motif event handler then back to wxWidget event handler. The motif has already trigger the change to update the GUI, and thus the checkbox is still clickable. Shouldn't the event being catch by wxWdiget then forward down to the motif or the underlying OS to do the GUI update?

I am abit lost here. Is this how wxWidget works or I am interpretting it wrongly? This is so different than how the TextCtrl widget behave or does the TextCtrl redraw the textbox itself? Any1 can give me some idea?

Thanks,

Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria » Thu Feb 28, 2008 5:44 pm

Lokk at wxEvent::Skip() to stop event propagation. Thogh right now you tried stopping the toggle event - but when yu get this event it's already done. try stopping the mouse instead.

Clyde is probably right that the easiest way is to catch the event when the checkboxe's stae changes, and jus put t back. it would happen so fast the user would maybe not even see it happen.

But I wonder... the one and only goal of check boxes is to be toggable by the user. What's the use of a non-checkable checkbox? perhaps you're not using the right component here

kaede
In need of some credit
In need of some credit
Posts: 7
Joined: Thu Feb 28, 2008 4:01 am

Post by kaede » Thu Feb 28, 2008 8:22 pm

Not only the checkbox, I need to be able to make every component read-only when needed.

Using Disable() will cause the text/control to gray out. This is not very ideal for me since the text/control (esp. the text) becomes really hard to read. Consider it using a disabled widget on presentation, people in the back row will not be able to read the text.

Given a panel of control, I would like the user to be able to edit it, once it is done. It should become read-only unless the user decided to overrides it by clicking a button or via password control.

I am hoping there is a easier way to make each component can behaves like a TextCtrl, where it could be set to Disable, Enable or Read-Only. Or if there is a way to not gray out the text/control when Disable() is invoke.

Catching Moouse Event via EVT_MOUSE_EVENTS didn't help either.

Any help will be appreciated. Thanks

mc2r
wxWorld Domination!
wxWorld Domination!
Posts: 1195
Joined: Thu Feb 22, 2007 4:47 pm
Location: Denver, Co
Contact:

Post by mc2r » Thu Feb 28, 2008 9:56 pm

I might be missing something as this seems to simple but couldn't you just do

Code: Select all

someCheckBox->Enable(false);
The user can see the checkbox but it is greyed out and clicking on it does nothing.

EDIT: Yeah, i missed reading all the way through where you mention you don't like the grey.

-Max

Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria » Fri Feb 29, 2008 12:18 am

wxApp::FilterEvent might help, but once again that's rather low-level.

If you just want to "freeze" the window, a nice little hack would be using a window DC to capture the window contents as an image, and then replace your window contents with a blank panel and draw the captured image on it (not ideal solution, I know... AFAIK wxSmith does that)

You might also have some success pushing a custom event handler to your panel, and make it stop almost all events but a few ones (paint events maybe). Note that I never tested this so I'm not sure if/how it would work but it sounds it could work

Perhaps explain what applciation you are building? It's hard to answer without knowing.

kaede
In need of some credit
In need of some credit
Posts: 7
Joined: Thu Feb 28, 2008 4:01 am

Post by kaede » Fri Feb 29, 2008 5:16 am

It is actually a simple app.

Consider a panel with TextCtrl, Grid, checkbox and etc.
Super user will be able to enter the info into this panel. Once it is complete, they could lock the panel (i.e. no one else, other than the super user has privilege to change the data in the panel).

Other user can open the same panel, but will be in Read-only mode. The GUI should be no difference from the Super User, since, the super user can can the data on the fly by simply unlocking the panel via password.

This is what I am trying to do. The panel should be able to go into Read-only or Read-write mode. I like how Disable() does it. But I don't like the text becomes blurry and not readable.

Like TextCtrl, it can turn the edit more on or off. Is it possible to apply the same to other widget? I am new to wx, but then it seems wierd to me that overriding the events on other componet does not work somehow.

Has anyone written any read-only control/widget for common control like checkbox and etc?

BTW, Auria, do u have some code snippet to show me the hack u metioned (using DC to capture) ..

Thanks,

mc2r
wxWorld Domination!
wxWorld Domination!
Posts: 1195
Joined: Thu Feb 22, 2007 4:47 pm
Location: Denver, Co
Contact:

Post by mc2r » Fri Feb 29, 2008 6:41 am

kaede wrote:This is what I am trying to do. The panel should be able to go into Read-only or Read-write mode. I like how Disable() does it. But I don't like the text becomes blurry and not readable.
Maybe you want to reconsider this point. Other than ease in implementation is the fact that this is a standard interface concept for controls which the user is not allowed/able to change. Your users when seeing the greyed control will understand what it means. If you change this you run the risk of confusing the user. Remember what you see as obvious and clear isn't when dealing with the typical end user as anyone who has ever worked any kind of techinical support can attest.

Just putting it out there that you may want to stick with convention that is easy to implement than go the hard to implement and users won't get it route.

-Max

clyde729
Super wx Problem Solver
Super wx Problem Solver
Posts: 426
Joined: Mon May 29, 2006 10:50 pm
Location: Jena, Germany

Post by clyde729 » Fri Feb 29, 2008 6:45 am

Could you post a little sample we could try out and see why it is not working (i.e. catching mouse events)?
OS: Windows XP Home, Compiler: MingW, Version: wxWidgets 2.8.0, IDE: wx-Devcpp

Jorg
Moderator
Moderator
Posts: 3971
Joined: Fri Aug 27, 2004 9:38 pm
Location: Delft, Netherlands
Contact:

Post by Jorg » Fri Feb 29, 2008 7:22 am

Consider a panel with TextCtrl, Grid, checkbox and etc.
Super user will be able to enter the info into this panel. Once it is complete, they could lock the panel (i.e. no one else, other than the super user has privilege to change the data in the panel).
There is your answer, the most simple and effective way to tell the user is writing a red string on top or bottom of the properties, telling them only the super user can edit the disabled controls. This way they *know* why it is disabled, and *know* what to do to be able to edit it again. I would not go down the road of coming up with a non standard way of denying clicks and making it appear to the user the controls do not do what they are supposed to do. It will only confuse them. After spending 10 years of mapping requirements to user functionality I have learned you should to everything as simple and standardized as possible for your application to be accepted.

- Jorgen
Forensic Software Engineer
Netherlands Forensic Insitute
http://english.forensischinstituut.nl/
-------------------------------------
Jorg's WasteBucket
http://www.xs4all.nl/~jorgb/wb

Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria » Fri Feb 29, 2008 2:30 pm

If the problem is that the text becomes blurry, you could just seperate text and component... like, use a checkbox with no name,and put a static text control next to it. So you can disable the check box but the text remains readable.

Sorry, I do not have any code snippet for window capture but the wxClientDC docs should be sufficient (look at drawing if you choose to go this way... but it's definitely not the best one IMO)

more importantly, I have never seen any application do this, wx or not. Maybe you should present current settings differently to those who can't edit it.

And just like others said, for your event catching problem, code will be necessary

kaede
In need of some credit
In need of some credit
Posts: 7
Joined: Thu Feb 28, 2008 4:01 am

Post by kaede » Fri Feb 29, 2008 3:01 pm

I will post some code later .. but it is just very similar to the code posted in the first post. When an event is caught, check if it is set to read-only or not, if so, return and skip the event processing. I just added the event macro for the different event (i.e. EVT_MOUSE_CLICK, EVT_MOUSE_DCLICK)

I do understand using standard way to present the panel (i.e via Disable() ) .. But the problem is the text blurrying.

Allowing user to know that the GUI is not editable/modifiable doesn't meant that the text has to go blurry and become non-readable.

I agreed that GRAYing out the control is the standard. Consider a TextCtrl, a non-editable text control gray out the control, but the text is readable. A selected list, graying out the list indicates the control is not editable, but not graying out the text in the list. A checkbox, graying out the checkbox indicates the control is not editable, but not blurring out the text. Now, the difference is a button, graying out and blurring the text in a button meant that it is not CLICKABLE. I hope there is no such thing as you an editable button. I have never see one so far.

I think GRAYing is the standard way to indicate a control is not editable. But honestly, I don't think the blurring of text is part of it. Try out some source control system, Clearcase, SVN, CVS. See how they represent non-editable control, regardless it is run in window or X11-based system.
I have no problem with button having it gray out w/ the text blurry effect. But not text, listbox, checkbox and etc.

This is just my thought.

In addition, has anyone thought about why TextControl has 2 different way to indicate Non-editable and Disable()? I think this is two different concept (Gray-out) via (Gray-out + text blurring). Maybe I am wrong.

If I offensed anyone, I apologize. But I do think that Gray-out and Gray-out + text blurrying is different and has different intent.

Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria » Fri Feb 29, 2008 3:32 pm

kaede: instead of existential rants, you could have looked at the solutions i proposed ;)

i have proposed solutions, you just complain instead of responding to them

Post Reply