Forum: wxRuby Validation and ComboBox

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
251086a67766003b417ef869c0121c7e?d=identicon&s=25 David Peoples (Guest)
on 2009-02-19 01:02
(Received via mailing list)
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
06f6780c99d4a8dd71f2b474082ea9ce?d=identicon&s=25 Alex Fenton (Guest)
on 2009-02-19 02:19
(Received via mailing list)
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
251086a67766003b417ef869c0121c7e?d=identicon&s=25 David Peoples (Guest)
on 2009-02-19 06:11
(Received via mailing list)
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
06f6780c99d4a8dd71f2b474082ea9ce?d=identicon&s=25 Alex Fenton (Guest)
on 2009-02-19 07:38
(Received via mailing list)
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
This topic is locked and can not be replied to.