GTK: Read-Only Text Entry (Label-Like)? - c

I need to make a gtk.Entry read-only like without using set_sensitive, specifically gtk_widget_set_sensitive will turn off all events, where as I'm only looking to make the entry clearly read-only, but to continue to receive signals.
It also has to be editable under certain circumstances, so gtk.Label is not an option - whereas gtk.Entry does not have a selectable attribute that can be modified.
The only thing I could think of so far is creating a gtk.Entry, waiting for a user to complete input and then replacing it with a gtk.Label, this doesn't sound very nice though.

Set both editable and can_focus properties to false.
The former ensures that the entry is read-only (while still receiving events such as selection), and the latter avoids the problem mentioned in the comment where the appearance of the cursor makes the entry appear editable when it's in fact not.

Related

Detect unpost of ttk::combobox

I have a Tcl/Tk program. In it I have a combobox, like so:
set cb [ttk::combobox .cb -state readonly -textvariable selection -postcommand [list choices .cb]]
The proc choices runs when the combobox posts, which is what I want. My question is, how do I detect when the combobox unposts?
I've tried both binding on <<ComboboxSelected>> and setting a variable trace on selection. The problem with each is that they only fire when the user actually changes the selection. I need some way to always detect when the combobox unposts.
Thanks!
edit
What I'm trying to accomplish: When the combobox posts it presents the user with a list of options. I don't expect the user to know what the options mean, therefor I am highlighting the options visually in a different area of my program. I have this highlighting triggering and working well with -postcommand. The issue is to know when to turn the highlighting back off.
<<ComboboxSelected>> doesn't fire if the user doesn't change the selected value.
<Leave> and <FocusOut> fire too soon (e.g. as soon as the box posts).
The combobox's popdown is actually its own nest of windows, and if your combobox is called .cb then the popdown has the imaginative name .cb.popdown (note that this implementation and is not guaranteed). If you add a binding to that widget's <Unmap> event you'll get to see the unposting; <Unmap> events are exactly the notifications sent when a window ceases to be displayed in the virtual desktop layer sense (as opposed to just ceasing to be visible, say because there's another window on top; there's events for that too, but they're not cross-platform).
The tricky bits:
The popdown is usually created when needed, i.e., the first time it appears. You need the window to exist (but not necessarily be visible) before you bind to it. You can get the handle of the popdown widget with ttk::combobox::PopdownWindow, which will make the widget if it doesn't already exist. (It's part of the implementation, but it is more likely to be stable than the name.)
set popdown [ttk::combobox::PopdownWindow .cb]
bind $popdown <Unmap> {yourCallback %W}
It is possible to dig around within the internal arrangement of the popdown, but I don't recommend it; it's much more likely to change without warning.
Binding to the toplevel has the usual issues with events also being delivered for subwindows. Your callback should check that the event it has been given is actually for the toplevel:
proc yourCallback {w} {
if {$w ne [winfo toplevel $w]} { return }
# The rest of your code here...
}
The window name of the listbox used by ttk::combobox is:
set popdown [ttk::combobox::PopdownWindow .combobox].f.l
I believe this is what you need.
bind <Leave> $popdown mycommand

Changing ListView.ShowItemToolTips raises ItemChecked events

Hi when I set ShowItemToolTips of a ListView with checkbox items to true in designer and change it to false in the code, the event ItemChecked is raised. The checked state itself is not changed though. But inside the (also raised) ItemCheck event the old value is not equal to the new value but the new value is the value that was previously visible. It seems like the items are re-inserted or reset in some way.
I tested this on two machines and projects. Why does this happen and how can I avoid it?
I'll explain the "why", a workaround is hard to come by. Some control properties are very impactful and can have odd side-effects when you change them. Like ShowItemToolTips, changing it after the ListView is created requires Winforms to completely destroy the native control and recreate it from scratch. Under the hood, it is a style flag (LVS_EX_INFOTIP) that's specified in the CreateWindowEx() call. The Control.RecreateHandle() method ensures it is effective. You'll see the flicker that this causes if you look closely.
So for a brief moment, the native control exists without yet being initialized with the original checkbox states. Getting a flaky event for that is a bug, but it is the kind that was either never fixed because doing so was too difficult or was just never discovered because nobody ever changes the ShowItemToolTips property after the control was created. It is very uncommon to do so.
In general, this native control re-creation trick has been a significant bug generator in Winforms. And workarounds are hard to come by, they fit either in the "deal with it" or the "don't do it" category. With the latter one strongly recommended in this case.

How to determine if WPF TextBox is dirty (when using UpdateSourceTrigger=LostFocus)

How can I determine when a user has updated the text in a textbox before the Binding has updated the source?
I was expecting to find an "IsDirty" property on either the TextBox or the Binding ...
My problem is that the "Cancel" button Enabled property is bound to the ViewModel's IsDirty property and is disabled until the focus moves out of the textbox.
"IsDirty" needs to be defined as ViewModel.IsDirty || TextBox.IsDirty
WPF can't support the typical IsDirty behaviour that users would expect in a high quality application.
The problem stems from the strange design of the Binder class.
Furthermore WPF architecture is kind of hard-coded to using the default Binder implementation, replacing it is a huge job and requires many "dirty tricks" to work around the endless WPF design flaws.
The easiest way I found to workaround this limitation is to move all value conversion logic to the view model and use UpdateSourceTrigger=PropertyChanged, and implement your own IsDirty and IsInvalid logic and flags.
This approach also plays nicely with Caliburn.Micro
First, why is Cancel disabled? It should be enabled all the time. Any other behavior would be odd. The user should be able to cancel although he hasn't done anything.
Second, I would use Commands so that it can determine whether it can be executed or not based on the state of the viewmodel. Should be easy to implement, if the viewmodel also provide the implementation of the command.
I'd recommend to read some articles and/or tutorials about it. Google for the interface ICommand.
And to answer your question. Assuming you're using binding you could use the INotifyPropertyChanging interface to determine when a value is about to change. You could then store the current value in a backup field or something.
EDIT - Regarding "let him lose data"
Sure it's a valid strategy. Think on a larger input dialog e.g. 5 input controls, which must be validated before persisting the input. I'm assuming that the data is very important according to your arguments. Furthermore, you started to hack your data into the dialog. On input control 3 you decide to press 'ALT + F4'.
First, ask yourself, why did the user press the keys? IMHO he doesn't care about what's happening to his data.
If 'ALT + F4' is just an example for being robust. Forget about it. I think absolute robustness cannot be implemented without being very expensive.
Second, regarding consistency and validity after the restart of the application, you have to throw the data away so that you don't start with an undefined state. Remember, the entity the user began to fill is not valid at this state. Neither the states respectively the values of the properties are.
So IMHO the much better strategy is to restart with a clean and defined state, so that the user is able to continue with whatever you want him to do with your application.
Why is this strategy better? Well, it's much easier to implement. And the much more important argument, the user never gets lost because of an odd state.

When Should I Retrieve Values from Textbox?

Suppose I have a Window with TextBoxes I want to use the values. Right now I'm thinking of either:
1) Updating each associated value once the cursor is out of focus, and once the user presses Ok I start the program
2) Once the user presses Ok, I retrieve all the values at once then start the program
I'm not sure which one is better though. First alternative seems more modular, but there's more semantic coupling since I each new box is supposed to be updating its respective value.
I realize this isn't all that important, but I'm trying to understand when to centralize and when not to. Other better approachers are appreciated too.
Use data binding to bind the text boxes' contents to objects in your code behind. WPF will take care of updating your attributes. Usually updating the data-bound value is done when the focus is lost on text boxes. However, you can also specify that it will happen whenever the value changes.

contextsensitive RoutedUICommand.CanExecute, Execute

I have a single RoutedUICommand that can be accessed through various places in the UI. Such as global Keyboardshortcut, Menu, ContextMenu or Button. The code that is to be executed in the RoutedUICommand.CanExecute and RoutedUICommand.Execute methods depends on what UI element was used. How can I achieve this differentiation. I was thinking that I could use the (Can)ExecutedRoutedEventArgs.Source or OrigianlSource but the source is always the same. It is the main Root window. How is this usually achieved? What could I possibly be doing wrong?
If you need different code to run depending on the UI that invoked the command you are probably doing something wrong.
If you have something like a just doing something from a keystroke or opening a dialog asking for more information from a menu you should break this apart into two commands (like MS Office "Print" and "Quick Print" commands).
If you truly have to do different things from each UI element you are not getting any advantage from using commands and should think about using old fashioned event handlers, at least then the element specific code is tied to the element and not stored in a central all encompassing "Execute" code .
And if you choose to ignore my advice above, take a look at the CommandParameter property, you can set a different value fro the parameter for each UI element, at least with it you can keep an illusion of the UI/Logic separation commands are designed to provide.
Normally you could have different CommandBinding implementations for different 'Targets' - having different behavior for each 'Source' is unusual.
Could you give an example of what you are trying to do?

Resources