I''m trying to make a ComboBox that can be typed into but only accepts entries that are already in the drop-down list. I hoped a combination of the CB_DROPDOWN style and a TextValidator with the FILTER_INCLUDE_LIST would make that happen, but the validator seems to be ignored. Is that combination supposed to do what I want? If so, please review the code below and let me know where my mistake is. Relevant libraries/platform: Ubuntu 8.04, Ruby 1.8.6, wxWidgets 2.8.9 (deb from the apt.wxwidgets.org repository), wxruby 1.9.10 gem. David Peoples ----- #!/usr/bin/env ruby require ''wx'' class MyFrame < Wx::Frame def initialize(title) super(nil, :title => title, :size => [ 400, 300 ]) panel = Wx::Panel.new(self, -1) @combo_choices = ["Apple", "Aardvark", "Banana", "Berry", "Canada", "Cantaloupe", "Cauliflower", "Dummy"] validator = Wx::TextValidator.new(Wx::FILTER_INCLUDE_LIST) validator.includes = @combo_choices combobox = Wx::ComboBox.new(panel, -1, "", Wx::Point.new(15,15), Wx::Size.new(-1,-1), @combo_choices, Wx::CB_DROPDOWN, validator, "my_combobox") end end Wx::App.run do self.app_name = "Test validated combobox" frame = MyFrame.new("ComboBox test") frame.show end
David Peoples wrote:> I''m trying to make a ComboBox that can be typed into but only accepts > entries that are already in the drop-down list.I''m presumably missing something, but why not just use a Wx::Choice if you want a fixed list?> I hoped a combination of > the CB_DROPDOWN style and a TextValidator with the FILTER_INCLUDE_LIST > would make that happen, but the validator seems to be ignored. Is that > combination supposed to do what I want?Thanks for mentioning this, as I hadn''t really looked into this use of Validators before. Firstly, from an assertion failure I get with the debug build, it seems TextValidator is only for use with TextCtrl, not anything else like ComboBox. With INCLUDE_LIST and EXCLUDE_LIST, the Validator clearly can''t validate on each keystroke as it does with the other types, where it blocks incorrect characters (eg limiting it to numerics only). wxWidgets expects the control to be part of a Dialog, and validates it only when the Dialog is dismissed. Since the automatic message one gets on a validation failure is not very helpful anyway (it''s hardcoded to "XXXX is not valid"), I''d suggest it''d be easier to roll your own. Trap the event when the contents should be checked (eg evt_kill_focus, or clicking "OK" on a dialog button) and act accordingly, eg combobox.evt_kill_focus do unless @combo_choices.include?(combobox.value) # do some warning end end alex
On Thu, 2009-02-19 at 01:06 +0000, Alex Fenton wrote:> David Peoples wrote: > > I''m trying to make a ComboBox that can be typed into but only accepts > > entries that are already in the drop-down list. > > I''m presumably missing something, but why not just use a Wx::Choice if > you want a fixed list? >My application needs to allow fairly high speed heads-down text entry with as close to zero mouse use as possible. The Wx::Choice control has a very clumsy keyboard interface. The app I''m converting was written in Delphi on Windows, and the custom combobox controls there had an excellent keyboard driven autocomplete operation I''m trying to emulate here. After looking closer at the docs I realized that I can get fairly close to what I want with an evt_text() handler and manipulating the text with ComboBox#set_value. ComboBox#set_text_selection_range isn''t doing at all what I expected, so I''ll probably work around *that* by displaying the list of potential matches somewhere below the combobox control while text entry is going on. Kludgy and a lot of work, but at least probably *will* work. I''ve never stopped being shocked at how crude some of the controls are in Gtk and KDE, compared to what I was used to. At least wxWidgets gives fairly easy access to the edit control in the combobox, which none of the other ruby GUIs do, as far as I could work out. Thanks for your help! David
David Peoples wrote:> My application needs to allow fairly high speed heads-down text entry > with as close to zero mouse use as possible. The Wx::Choice control has > a very clumsy keyboard interface. The app I''m converting was written in > Delphi on Windows, and the custom combobox controls there had an > excellent keyboard driven autocomplete operation I''m trying to emulate > here. >Makes sense. I implemented a control similar to this, can''t find the code now but it went roughly like: evt_text(combobox) do val = combobox.value if @last_val == val # deletion val = val[0..-2] end matches = @combo_choices.grep(/^#{val}/) combobox.clear combobox.append matches if not matches.empty? combobox.value = matches.first combobox.set_text_selection_range( val.length, matches.first.length) end @last_val = val end Obviously you''d probably want to refine this and turn it into a self-contained class. But it should be usable completely keyboard-driven. a
Possibly Parallel Threads
- Patch to wxComboBox.rbw
- lose focus event?
- [906] branches/wxruby2/wxwidgets_282: Wx::ComboBox API 2.6 -> 2.8, plus some doc corrections
- [989] branches/wxruby2/wxwidgets_282: Fix a crasher with misdirected ComboBox#GetSelection method on GTK; clearer
- Related combobox