# Copyright (c) 2023 M.J.N. Corino, The Netherlands # # This software is released under the MIT license. module Wx if has_feature?(:USE_VALIDATORS) class GenericValidator < Wx::Validator class << self def handlers @handlers ||= ::Hash.new(Proc.new { |win, *rest| raise NotImplementedError, "#{win.class} not supported" }) end def define_handler(klass, meth=nil, &block) raise ArgumentError, 'Expected a Class for arg 1' unless klass.is_a?(::Class) h = if block and not meth block else case meth when Proc, Method meth else raise ArgumentError, 'Expected a Proc or Method for arg 2' end end handlers[klass] = h end end def initialize(*arg) super @value = arg.empty? ? nil : arg.first.value @handler = nil @klass = nil end attr_accessor :value private def do_transfer_from_window get_handler.call(get_window) end def do_transfer_to_window(val) get_handler.call(get_window, val) unless val.nil? true end def do_on_transfer_from_window(data) super(@value = data) end def do_on_transfer_to_window @value = super || @value end def get_handler if @handler && @klass == get_window.class @handler else @klass = get_window.class @handler = GenericValidator.handlers[@klass] || GenericValidator.handlers.each_key.detect { |k| k > klass } @handler || ::Kernel.raise(NotImplementedError, "#{@klass} not supported") end end end # GenericValidator # define standard handlers # boolean controls if Wx.has_feature?(:USE_CHECKBOX) GenericValidator.define_handler(Wx::CheckBox) do |win, *val| if val.empty? !!win.get_value else win.set_value(!!val.shift) end end end if Wx.has_feature?(:USE_RADIOBTN) GenericValidator.define_handler(Wx::RadioButton) do |win, *val| if val.empty? !!win.get_value else win.set_value(!!val.shift) end end end if Wx.has_feature?(:USE_TOGGLEBTN) # also covers Wx::BitmapToggleButton GenericValidator.define_handler(Wx::ToggleButton) do |win, *val| if val.empty? !!win.get_value else win.set_value(!!val.shift) end end end # integer controls if Wx.has_feature?(:USE_GAUGE) GenericValidator.define_handler(Wx::Gauge) do |win, *val| if val.empty? win.get_value else win.set_value(val.shift) end end end if Wx.has_feature?(:USE_RADIOBOX) GenericValidator.define_handler(Wx::RadioBox) do |win, *val| if val.empty? win.get_selection else win.set_selection(val.shift) end end end if Wx.has_feature?(:USE_SCROLLBAR) GenericValidator.define_handler(Wx::ScrollBar) do |win, *val| if val.empty? win.get_thumb_position else win.set_thumb_position(val.shift) end end end if Wx.has_feature?(:USE_SPINCTRL) GenericValidator.define_handler(Wx::SpinCtrl) do |win, *val| if val.empty? win.get_value else win.set_value(val.shift) end end end if Wx.has_feature?(:USE_SPINBTN) GenericValidator.define_handler(Wx::SpinButton) do |win, *val| if val.empty? win.get_value else win.set_value(val.shift) end end end if Wx.has_feature?(:USE_SLIDER) GenericValidator.define_handler(Wx::Slider) do |win, *val| if val.empty? win.get_value else win.set_value(val.shift) end end end if Wx.has_feature?(:USE_CHOICE) GenericValidator.define_handler(Wx::Choice) do |win, *val| if val.empty? win.get_selection else win.set_selection(val.shift) end end end if Wx.has_feature?(:USE_COMBOBOX) GenericValidator.define_handler(Wx::ComboBox) do |win, *val| if val.empty? if (win.get_window_style & Wx::CB_READONLY) == Wx::CB_READONLY win.get_selection else win.get_string_selection end else if (win.get_window_style & Wx::CB_READONLY) == Wx::CB_READONLY win.set_selection(val.shift) else win.set_string_selection(val.shift) end end end end # date/time controls if Wx.has_feature?(:USE_DATEPICKCTRL) GenericValidator.define_handler(Wx::DatePickerCtrl) do |win, *val| if val.empty? win.get_value else win.set_value(val.shift) end end end if Wx.has_feature?(:USE_TIMEPICKCTRL) GenericValidator.define_handler(Wx::TimePickerCtrl) do |win, *val| if val.empty? win.get_value else win.set_value(val.shift) end end end # string controls if Wx.has_feature?(:USE_BUTTON) GenericValidator.define_handler(Wx::Button) do |win, *val| if val.empty? win.get_label else win.set_label(val.shift) end end end if Wx.has_feature?(:USE_STATTEXT) GenericValidator.define_handler(Wx::StaticText) do |win, *val| if val.empty? win.get_label else win.set_label(val.shift) end end end if Wx.has_feature?(:USE_TEXTCTRL) GenericValidator.define_handler(Wx::TextCtrl) do |win, *val| if val.empty? win.get_value else win.set_value(val.shift) end end end # array controls if Wx.has_feature?(:USE_CHECKLISTBOX) GenericValidator.define_handler(Wx::CheckListBox) do |win, *val| if val.empty? if (win.get_window_style & Wx::LB_SINGLE) == Wx::LB_SINGLE win.get_checked_items.first else win.get_checked_items end else if (win.get_window_style & Wx::LB_SINGLE) == Wx::LB_SINGLE win.check(val.shift, true) else win.get_count.times { |i| win.check(i, false) } [val].flatten.each { |i| win.check(i, true) } end end end end if Wx.has_feature?(:USE_LISTBOX) GenericValidator.define_handler(Wx::ListBox) do |win, *val| if val.empty? # test this the hard since on WXOSX LB_SINGLE is default but does get set # by default i.e. on WXOSX no selection type bit set == LB_SINGLE if (win.get_window_style & (Wx::LB_MULTIPLE|Wx::LB_EXTENDED)) == 0 win.get_selection else win.get_selections end else if (win.get_window_style & (Wx::LB_MULTIPLE|Wx::LB_EXTENDED)) == 0 win.set_selection(val.shift) else win.get_count.times { |i| win.deselect(i) } [val].flatten.each { |i| win.set_selection(i) } end end end end end # if USE_VALIDATORS end