wxruby3 0.9.4 → 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/INSTALL.md +315 -78
- data/README.md +32 -21
- data/ext/wxruby3/include/wxruby-ComboPopup.h +777 -0
- data/lib/wx/core/combo_ctrl.rb +171 -0
- data/lib/wx/core/ext.rb +22 -3
- data/lib/wx/doc/comboctrl.rb +128 -3
- data/lib/wx/doc/owner_drawn_combobox.rb +5 -1
- data/lib/wx/version.rb +1 -1
- data/lib/wx/wxruby/base.rb +6 -4
- data/lib/wx/wxruby/cmd/sampler.rb +39 -29
- data/lib/wx/wxruby/cmd/setup.rb +122 -0
- data/lib/wx/wxruby/cmd/test.rb +56 -6
- data/rakefile +14 -0
- data/rakelib/bin.rake +48 -0
- data/rakelib/bin.rb +62 -0
- data/rakelib/build.rb +11 -7
- data/rakelib/config.rake +3 -1
- data/rakelib/configure.rb +28 -8
- data/rakelib/doc.rake +3 -1
- data/rakelib/gem.rake +169 -0
- data/rakelib/gem.rb +82 -0
- data/rakelib/install.rb +2 -0
- data/rakelib/lib/config/linux.rb +24 -2
- data/rakelib/lib/config/macosx.rb +16 -0
- data/rakelib/lib/config/mingw.rb +133 -9
- data/rakelib/lib/config/pkgman/arch.rb +53 -0
- data/rakelib/lib/config/pkgman/base.rb +169 -0
- data/rakelib/lib/config/pkgman/debian.rb +66 -0
- data/rakelib/lib/config/pkgman/macosx.rb +183 -0
- data/rakelib/lib/config/pkgman/rhel.rb +54 -0
- data/rakelib/lib/config/pkgman/suse.rb +54 -0
- data/rakelib/lib/config/unixish.rb +36 -19
- data/rakelib/lib/config.rb +254 -61
- data/rakelib/lib/core/include/funcall.inc +2 -1
- data/rakelib/lib/core/package.rb +47 -49
- data/rakelib/lib/director/comboctrl.rb +104 -3
- data/rakelib/lib/director/defs.rb +1 -3
- data/rakelib/lib/director/gdicommon.rb +5 -0
- data/rakelib/lib/director/menu_item.rb +1 -1
- data/rakelib/lib/director/num_validator.rb +5 -7
- data/rakelib/lib/director/owner_drawn_combobox.rb +1 -0
- data/rakelib/lib/director/persistent_window.rb +2 -2
- data/rakelib/lib/director/pgeditor.rb +1 -1
- data/rakelib/lib/director/pgproperties.rb +3 -3
- data/rakelib/lib/director/pgproperty.rb +5 -1
- data/rakelib/lib/director/richtext_style_listbox.rb +5 -0
- data/rakelib/lib/director/sizer.rb +1 -1
- data/rakelib/lib/director/window.rb +4 -0
- data/rakelib/lib/extractor/module.rb +15 -0
- data/rakelib/lib/generate/doc/combo_ctrl.yaml +135 -0
- data/rakelib/lib/generate/doc/file_dialog_customize_hook.yaml +62 -0
- data/rakelib/lib/generate/doc/file_system.yaml +28 -0
- data/rakelib/lib/generate/doc.rb +29 -14
- data/rakelib/lib/generate/interface.rb +16 -6
- data/rakelib/lib/swig_runner.rb +18 -15
- data/rakelib/lib/typemap/combo_popup.rb +42 -0
- data/rakelib/prepost.rake +9 -4
- data/rakelib/yard/templates/default/fulldoc/html/css/wxruby3.css +14 -0
- data/rakelib/yard/templates/default/fulldoc/html/setup.rb +5 -5
- data/rakelib/yard/yard/relative_markdown_links.rb +7 -1
- data/tests/test_combo_ctrl.rb +196 -0
- metadata +28 -17
- data/ext/mkrf_conf_srcgem.rb +0 -67
- data/rakelib/run.rake +0 -52
data/rakelib/lib/generate/doc.rb
CHANGED
@@ -26,22 +26,30 @@ module WXRuby3
|
|
26
26
|
WX_GLOBAL_CONSTANTS=false
|
27
27
|
require 'wx'
|
28
28
|
def handle_module(mod, table)
|
29
|
+
Wx.delayed_constants_for(mod).each do |key, delayed_const|
|
30
|
+
table[key.sym.to_s] = { type: true, value: delayed_const.to_s }
|
31
|
+
end
|
29
32
|
mod.constants.each do |c|
|
30
33
|
a_const = mod.const_get(c)
|
31
34
|
if (::Module === a_const || ::Class === a_const) && a_const.name.start_with?('Wx::') # Wx:: Package submodule or Class (possibly Enum)
|
32
35
|
handle_module(a_const, table[c.to_s] = {})
|
33
36
|
elsif Wx::Enum === a_const
|
34
|
-
table[c.to_s] = { type:
|
35
|
-
elsif !(::Hash === a_const || ::Array === a_const)
|
36
|
-
|
37
|
+
table[c.to_s] = { type: true, value: "\#{a_const.class}.new(\#{a_const.to_i})" }
|
38
|
+
elsif !(::Hash === a_const || ::Array === a_const)
|
39
|
+
case a_const
|
40
|
+
when Wx::Size
|
41
|
+
table[c.to_s] = { type: true, value: "Wx::Size.new(\#{a_const.width}, \#{a_const.height})" }
|
42
|
+
when Wx::Point
|
43
|
+
table[c.to_s] = { type: true, value: "Wx::Point.new(\#{a_const.x}, \#{a_const.y})" }
|
44
|
+
else
|
45
|
+
table[c.to_s] = { type: true, value: a_const } unless c == :THE_APP
|
46
|
+
end
|
37
47
|
end
|
38
48
|
end
|
39
49
|
end
|
40
|
-
Wx
|
41
|
-
|
42
|
-
|
43
|
-
STDOUT.puts JSON.dump(table)
|
44
|
-
end
|
50
|
+
table = { 'Wx' => {}}
|
51
|
+
handle_module(Wx, table['Wx'])
|
52
|
+
STDOUT.puts JSON.dump(table)
|
45
53
|
__SCRIPT
|
46
54
|
STDERR.puts "* executing constants collection script:\n#{script}" if Director.trace?
|
47
55
|
begin
|
@@ -693,15 +701,22 @@ module WXRuby3
|
|
693
701
|
# at least 2 newlines to make Yard skip/forget the header comment
|
694
702
|
fdoc.puts
|
695
703
|
fdoc.puts
|
696
|
-
|
697
|
-
|
698
|
-
|
704
|
+
mod_indent = 0
|
705
|
+
package.all_modules.each do |modnm|
|
706
|
+
fdoc.iputs("module #{package.fullname}", mod_indent)
|
707
|
+
fdoc.puts
|
708
|
+
mod_indent += 1
|
709
|
+
end
|
710
|
+
fdoc.indent(mod_indent) do
|
699
711
|
gen_constants_doc(fdoc)
|
700
712
|
gen_functions_doc(fdoc) unless no_gen?(:functions)
|
701
713
|
gen_class_doc(fdoc) unless no_gen?(:classes)
|
702
714
|
end
|
703
|
-
|
704
|
-
|
715
|
+
package.all_modules.each do |_|
|
716
|
+
fdoc.puts
|
717
|
+
fdoc.iputs('end', mod_indent)
|
718
|
+
mod_indent -= 1
|
719
|
+
end
|
705
720
|
end
|
706
721
|
end
|
707
722
|
|
@@ -742,7 +757,7 @@ module WXRuby3
|
|
742
757
|
end
|
743
758
|
|
744
759
|
def gen_constant_value(val)
|
745
|
-
if ::String === val && /\A(#<(.*)>|[\w:]
|
760
|
+
if ::String === val && /\A(#<(.*)>|[\w:]+\.\w+\(.*\))\Z/ =~ val
|
746
761
|
if $2
|
747
762
|
valstr = $2
|
748
763
|
if /\Awx/ =~ valstr
|
@@ -547,10 +547,18 @@ module WXRuby3
|
|
547
547
|
if Extractor::EnumDef === item && !item.ignored && !item.items.all? {|e| e.ignored }
|
548
548
|
fout.puts
|
549
549
|
fout.puts "// from enum #{item.is_anonymous ? '' : item.name}"
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
550
|
+
if item.is_anonymous
|
551
|
+
item.items.each do |e|
|
552
|
+
unless e.ignored
|
553
|
+
fout.puts "%constant int #{e.name} = #{e.fqn};"
|
554
|
+
end
|
555
|
+
end
|
556
|
+
else
|
557
|
+
fout.puts "enum #{item.name};"
|
558
|
+
item.items.each do |e|
|
559
|
+
unless e.ignored
|
560
|
+
fout.puts "%constant int #{item.name}_#{e.name} = #{e.fqn};"
|
561
|
+
end
|
554
562
|
end
|
555
563
|
end
|
556
564
|
end
|
@@ -595,7 +603,8 @@ module WXRuby3
|
|
595
603
|
elsif item.value =~ /wx(Colour|Font)(\(.*\))/
|
596
604
|
frbext = init_rb_ext_file unless frbext
|
597
605
|
frbext.indent do
|
598
|
-
|
606
|
+
code = "Wx::#{$1}.new#{$2}"
|
607
|
+
frbext.puts "Wx.add_delayed_constant(self, :#{rb_constant_name(item.name)}, '#{code}') { #{code} }"
|
599
608
|
end
|
600
609
|
frbext.puts
|
601
610
|
elsif item.value =~ /wxSystemSettings::(\w+)\((.*)\)/
|
@@ -603,7 +612,8 @@ module WXRuby3
|
|
603
612
|
setting_mtd = $1
|
604
613
|
args = $2.split(',').collect {|a| rb_constant_value(a) }.join(', ')
|
605
614
|
frbext.indent do
|
606
|
-
|
615
|
+
code = "Wx::SystemSettings.#{rb_method_name(setting_mtd)}(#{args})"
|
616
|
+
frbext.puts "Wx.add_delayed_constant(self, :#{rb_constant_name(item.name)}, '#{code}') { #{code} }"
|
607
617
|
end
|
608
618
|
frbext.puts
|
609
619
|
else
|
data/rakelib/lib/swig_runner.rb
CHANGED
@@ -43,24 +43,23 @@ module WXRuby3
|
|
43
43
|
@swig_version
|
44
44
|
end
|
45
45
|
|
46
|
-
|
47
46
|
def check_swig
|
48
47
|
begin
|
49
48
|
@swig_version = `#{WXRuby3::Config.get_config('swig')} -version`[/\d+\.\d+\.\d+/]
|
50
49
|
rescue Exception
|
51
|
-
|
50
|
+
$stderr.puts "ERROR: Could not run SWIG (#{WXRuby3::Config.get_config('swig')})"
|
52
51
|
exit(1)
|
53
52
|
end
|
54
53
|
|
55
|
-
# Very old versions put --version on
|
54
|
+
# Very old versions put --version on $stderr, not $stdout
|
56
55
|
unless @swig_version
|
57
|
-
|
56
|
+
$stderr.puts "Could not get version info from SWIG; " +
|
58
57
|
"is a very old version installed?.\n"
|
59
58
|
exit(1)
|
60
59
|
end
|
61
60
|
|
62
61
|
if @swig_version < SWIG_MINIMUM_VERSION
|
63
|
-
|
62
|
+
$stderr.puts "SWIG version #{@swig_version} is installed, " +
|
64
63
|
"minimum version required is #{SWIG_MINIMUM_VERSION}.\n"
|
65
64
|
exit(1)
|
66
65
|
end
|
@@ -72,11 +71,12 @@ module WXRuby3
|
|
72
71
|
check_swig unless swig_state
|
73
72
|
inc_paths = "-I#{config.wxruby_dir} -I#{config.swig_dir}/custom"
|
74
73
|
inc_paths << " -I#{config.swig_dir}/custom/swig#{swig_major}"
|
75
|
-
sh "#{config.get_config('swig')} #{config.wx_cppflags.join(' ')} " +
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
74
|
+
WXRuby3.config.sh "#{config.get_config('swig')} #{config.wx_cppflags.join(' ')} " +
|
75
|
+
"#{config.extra_cppflags.join(' ')} #{config.verbose_flag} #{inc_paths} " +
|
76
|
+
#"-w401 -w801 -w515 -c++ -ruby " +
|
77
|
+
"-w801 -c++ -ruby " +
|
78
|
+
"-o #{target} #{source}",
|
79
|
+
fail_on_error: true
|
80
80
|
end
|
81
81
|
|
82
82
|
end
|
@@ -205,7 +205,7 @@ module WXRuby3
|
|
205
205
|
end
|
206
206
|
|
207
207
|
def self.run(pid, director, target)
|
208
|
-
|
208
|
+
Config.instance.log_progress("Processor.#{pid}: #{target}")
|
209
209
|
const_get(camelize(pid.to_s)).new(director, target).run
|
210
210
|
end
|
211
211
|
|
@@ -262,7 +262,7 @@ module WXRuby3
|
|
262
262
|
def_items.each do |item|
|
263
263
|
case item
|
264
264
|
when Extractor::EnumDef
|
265
|
-
item.items.each { |e| enumerators[rb_wx_name(e.name
|
265
|
+
item.items.each { |e| enumerators["#{rb_wx_name(item.name)}_#{e.name}"] = item } if item.is_type
|
266
266
|
when Extractor::ClassDef
|
267
267
|
item.items.select { |itm| Extractor::EnumDef === itm }.each do |enum|
|
268
268
|
enum.items.each { |e| enumerators[rb_wx_name(e.name)] = enum } if enum.is_type
|
@@ -334,6 +334,7 @@ module WXRuby3
|
|
334
334
|
fix_enum = true
|
335
335
|
enum_item = enum_table[md[2]]
|
336
336
|
enum_name = rb_wx_name(enum_item.name)
|
337
|
+
enumerator_name = rb_wx_name(md[2].sub(/\A#{enum_name}_/, ''))
|
337
338
|
enum_id = enum_item.scope.empty? ? enum_name : "#{rb_wx_name(enum_item.scope)}::#{enum_name}"
|
338
339
|
enum_var = enum_id.gsub('::', '_')
|
339
340
|
line = [
|
@@ -343,7 +344,7 @@ module WXRuby3
|
|
343
344
|
# add enum class constant to current module (use unscoped name)
|
344
345
|
" rb_define_const(#{md[1]}, \"#{enum_name}\", cWx#{enum_var}); // Inserted by fixmodule.rb",
|
345
346
|
# create enumerator value const under new enum class
|
346
|
-
" wxRuby_AddEnumValue(cWx#{enum_var}, \"#{
|
347
|
+
" wxRuby_AddEnumValue(cWx#{enum_var}, \"#{enumerator_name}\"#{md[3]} // Updated by fixmodule.rb"
|
347
348
|
].join("\n")
|
348
349
|
end
|
349
350
|
else
|
@@ -352,13 +353,15 @@ module WXRuby3
|
|
352
353
|
# of the same enum?
|
353
354
|
if enum_item && enum_table[md[2]] == enum_item
|
354
355
|
enum_name = rb_wx_name(enum_item.name)
|
356
|
+
enumerator_name = rb_wx_name(md[2].sub(/\A#{enum_name}_/, ''))
|
355
357
|
enum_id = enum_item.scope.empty? ? enum_name : "#{rb_wx_name(enum_item.scope)}::#{enum_name}"
|
356
358
|
enum_var = enum_id.gsub('::', '_')
|
357
359
|
# create enumerator value const under new enum class
|
358
|
-
line = " wxRuby_AddEnumValue(cWx#{enum_var}, \"#{
|
360
|
+
line = " wxRuby_AddEnumValue(cWx#{enum_var}, \"#{enumerator_name}\"#{md[3]} // Updated by fixmodule.rb"
|
359
361
|
else # we found the start of another enum
|
360
362
|
enum_item = enum_table[md[2]]
|
361
363
|
enum_name = rb_wx_name(enum_item.name)
|
364
|
+
enumerator_name = rb_wx_name(md[2].sub(/\A#{enum_name}_/, ''))
|
362
365
|
enum_id = enum_item.scope.empty? ? enum_name : "#{rb_wx_name(enum_item.scope)}::#{enum_name}"
|
363
366
|
enum_var = enum_id.gsub('::', '_')
|
364
367
|
line = [
|
@@ -368,7 +371,7 @@ module WXRuby3
|
|
368
371
|
# add enum class constant to current module (use unscoped name)
|
369
372
|
" rb_define_const(#{md[1]}, \"#{enum_name}\", cWx#{enum_var}); // Inserted by fixmodule.rb",
|
370
373
|
# create enumerator value const under new enum class
|
371
|
-
" wxRuby_AddEnumValue(cWx#{enum_var}, \"#{
|
374
|
+
" wxRuby_AddEnumValue(cWx#{enum_var}, \"#{enumerator_name}\"#{md[3]} // Updated by fixmodule.rb"
|
372
375
|
].join("\n")
|
373
376
|
end
|
374
377
|
else # end of enum def
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
|
5
|
+
###
|
6
|
+
# wxRuby3 wxComboPopup typemap definition
|
7
|
+
###
|
8
|
+
|
9
|
+
require_relative '../core/mapping'
|
10
|
+
|
11
|
+
module WXRuby3
|
12
|
+
|
13
|
+
module Typemap
|
14
|
+
|
15
|
+
module ComboPopup
|
16
|
+
|
17
|
+
include Typemap::Module
|
18
|
+
|
19
|
+
define do
|
20
|
+
|
21
|
+
# for DoSetPopupControl
|
22
|
+
map 'wxComboPopup* popup' => 'Wx::ComboPopup,nil' do
|
23
|
+
|
24
|
+
add_header_code <<~__CODE
|
25
|
+
#include <wx/combo.h>
|
26
|
+
|
27
|
+
WXRUBY_EXPORT wxComboPopup* wxRuby_ComboPopupFromRuby(VALUE popup);
|
28
|
+
WXRUBY_EXPORT VALUE wxRuby_ComboPopupToRuby(wxComboPopup* popup);
|
29
|
+
__CODE
|
30
|
+
|
31
|
+
map_in code: '$1 = wxRuby_ComboPopupFromRuby($input);'
|
32
|
+
|
33
|
+
map_directorin code: '$input = wxRuby_ComboPopupToRuby($1);'
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
data/rakelib/prepost.rake
CHANGED
@@ -23,16 +23,21 @@ namespace 'wxruby' do
|
|
23
23
|
|
24
24
|
namespace 'post' do
|
25
25
|
|
26
|
-
task :srcgem => %w[gem:wxwin gem:install
|
26
|
+
task :srcgem => %w[gem:wxwin gem:install] do
|
27
|
+
$stdout.print "Generating wxRuby3 reference documentation..." if WXRuby3.config.run_silent?
|
28
|
+
Rake::Task['wxruby:doc'].invoke
|
29
|
+
$stdout.puts 'done!' if WXRuby3.config.run_silent?
|
27
30
|
# cleanup
|
28
|
-
rm_rf('rakelib')
|
29
|
-
rm_rf('ext/wxruby3')
|
30
|
-
|
31
|
+
rm_rf('rakelib', verbose: !WXRuby3.config.run_silent?)
|
32
|
+
rm_rf('ext/wxruby3', verbose: !WXRuby3.config.run_silent?)
|
33
|
+
WXRuby3.config.cleanup_bootstrap
|
34
|
+
File.open(File.join(WXRuby3::Config.wxruby_root, 'ext', 'wxruby.setup.done'), 'w') { |f| f << '1' }
|
31
35
|
end
|
32
36
|
|
33
37
|
task :bingem => 'gem:install' do
|
34
38
|
# cleanup
|
35
39
|
rm_rf('rakelib')
|
40
|
+
File.open(File.join(WXRuby3::Config.wxruby_root, 'ext', 'wxruby.setup.done'), 'w') { |f| f << '1' }
|
36
41
|
end
|
37
42
|
|
38
43
|
namespace 'gem' do
|
@@ -77,3 +77,17 @@ div.wxrb-logo table td {
|
|
77
77
|
font-weight: bold;
|
78
78
|
font-size: 0.9em;
|
79
79
|
}
|
80
|
+
|
81
|
+
#filecontents {
|
82
|
+
margin-right: 340px;
|
83
|
+
}
|
84
|
+
|
85
|
+
#filecontents blockquote {
|
86
|
+
border-left: .5em solid #e0e0e0;
|
87
|
+
margin: 10px;
|
88
|
+
padding-left: 10px;
|
89
|
+
}
|
90
|
+
|
91
|
+
#toc {
|
92
|
+
position: fixed;
|
93
|
+
}
|
@@ -1,19 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
def init
|
4
|
-
# It seems YARD messes things up so that a
|
4
|
+
# It seems YARD messes things up so that a lot of classes, modules and constants are not properly
|
5
5
|
# registered in their enclosing namespaces.
|
6
6
|
# This hack makes sure that if that is the case we fix that here.
|
7
|
-
|
8
|
-
|
7
|
+
all_objects = Registry.all(:class, :constant, :module)
|
8
|
+
all_objects.each do |c|
|
9
9
|
if (ns = c.namespace)
|
10
10
|
unless ns.children.any? { |nsc| nsc.path == c.path }
|
11
|
-
ns.children << c # class missing from child list of enclosing namespace -> add here
|
11
|
+
ns.children << c # class/module/constant missing from child list of enclosing namespace -> add here
|
12
12
|
end
|
13
13
|
end
|
14
14
|
if (ns = Registry[c.namespace.path])
|
15
15
|
unless ns.children.any? { |nsc| nsc.path == c.path }
|
16
|
-
ns.children << c # class missing from child list of enclosing namespace -> add here
|
16
|
+
ns.children << c # class/module/constant missing from child list of enclosing namespace -> add here
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -31,12 +31,18 @@ module YARD # rubocop:disable Style/Documentation
|
|
31
31
|
if fnames.include?(href.path)
|
32
32
|
link.replace "{file:#{href} #{link.inner_html}}"
|
33
33
|
elsif href.path.end_with?('_md.html') && (fname = fnames.find {|fnm| fnm.end_with?(href.path.sub(/_md.html\Z/, '.md')) })
|
34
|
-
link.replace "{file:#{fname} #{link.inner_html}}"
|
34
|
+
link.replace "{file:#{fname}#{href.fragment ? "##{fragment_to_yard(href.fragment)}" : ''} #{link.inner_html}}"
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
38
38
|
super(html.to_s)
|
39
39
|
end
|
40
|
+
|
41
|
+
# this does not work with mixed case labels but is good enough for us
|
42
|
+
def fragment_to_yard(s)
|
43
|
+
s.start_with?('label-') ? s : "label-#{s.gsub('-', '+').capitalize}"
|
44
|
+
end
|
45
|
+
|
40
46
|
end
|
41
47
|
|
42
48
|
Templates::Template.extra_includes << RelativeMarkdownLinks
|
@@ -0,0 +1,196 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
|
5
|
+
require_relative './lib/wxframe_runner'
|
6
|
+
require_relative './lib/text_entry_tests'
|
7
|
+
|
8
|
+
class ComboCtrlCtrlTests < WxRuby::Test::GUITests
|
9
|
+
|
10
|
+
include TextEntryTests
|
11
|
+
|
12
|
+
class LVComboPopup < Wx::ListView
|
13
|
+
|
14
|
+
include Wx::ComboPopup
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
# call default control ctor; need to call Wx::ListView#create later
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def init
|
22
|
+
@value = -1
|
23
|
+
end
|
24
|
+
|
25
|
+
def create(parent)
|
26
|
+
# need to finish creating the list view here
|
27
|
+
# as calling super here would just call Wx::ComboPopup#create and not Wx::ListView#create
|
28
|
+
# we need to use Ruby magic
|
29
|
+
wx_lv_create = (Wx::ListView.instance_method :create).bind(self)
|
30
|
+
wx_lv_create.call(parent, 1, [0,0], Wx::DEFAULT_SIZE)
|
31
|
+
evt_motion :on_mouse_move
|
32
|
+
evt_left_up :on_mouse_click
|
33
|
+
end
|
34
|
+
|
35
|
+
# Return pointer to the created control
|
36
|
+
def get_control
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def lv_find_item(*args)
|
41
|
+
unless @wx_lv_find_item
|
42
|
+
@wx_lv_find_item = (Wx::ListView.instance_method :find_item).bind(self)
|
43
|
+
end
|
44
|
+
@wx_lv_find_item.call(*args)
|
45
|
+
end
|
46
|
+
protected :lv_find_item
|
47
|
+
|
48
|
+
# Translate string into a list selection
|
49
|
+
def set_string_value(s)
|
50
|
+
n = lv_find_item(-1, s)
|
51
|
+
if n >= 0 && n < get_item_count
|
52
|
+
select(n)
|
53
|
+
@value = n
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Get list selection as a string
|
58
|
+
def get_string_value
|
59
|
+
return get_item_text(@value) if @value >= 0
|
60
|
+
''
|
61
|
+
end
|
62
|
+
|
63
|
+
# Do mouse hot-tracking (which is typical in list popups)
|
64
|
+
def on_mouse_move(event)
|
65
|
+
# Move selection to cursor ...
|
66
|
+
end
|
67
|
+
|
68
|
+
# On mouse left up, set the value and close the popup
|
69
|
+
def on_mouse_click(_event)
|
70
|
+
@value = get_first_selected
|
71
|
+
|
72
|
+
# Send event as well ...
|
73
|
+
|
74
|
+
dismiss
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
def setup
|
80
|
+
super
|
81
|
+
@combo = Wx::ComboCtrl.new(frame_win, name: 'ComboCtrl')
|
82
|
+
@combo.set_popup_control(LVComboPopup.new)
|
83
|
+
end
|
84
|
+
|
85
|
+
def cleanup
|
86
|
+
@combo.destroy
|
87
|
+
super
|
88
|
+
end
|
89
|
+
|
90
|
+
attr_reader :combo
|
91
|
+
alias :text_entry :combo
|
92
|
+
|
93
|
+
def fill_list(list)
|
94
|
+
list.insert_item(0, 'This is the first item')
|
95
|
+
list.insert_item(1, 'This is the second item')
|
96
|
+
list.insert_item(2, 'This is the third item')
|
97
|
+
list.insert_item(3, 'This is the fourth item')
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_popup
|
101
|
+
assert_equal('', combo.get_value)
|
102
|
+
|
103
|
+
assert_kind_of(Wx::ComboPopup, combo.get_popup_control)
|
104
|
+
assert_kind_of(Wx::ListView, combo.get_popup_control)
|
105
|
+
assert_kind_of(Wx::ListView, combo.get_popup_control.get_control)
|
106
|
+
|
107
|
+
assert_nothing_raised { fill_list(combo.get_popup_control) }
|
108
|
+
combo.popup
|
109
|
+
|
110
|
+
combo.set_value_by_user('This is the second item')
|
111
|
+
|
112
|
+
assert_equal('This is the second item', combo.get_popup_control.get_string_value)
|
113
|
+
|
114
|
+
combo.dismiss
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
class OwnerDrawnCBTests < WxRuby::Test::GUITests
|
120
|
+
|
121
|
+
include TextEntryTests
|
122
|
+
|
123
|
+
class TestODComboBox < Wx::OwnerDrawnComboBox
|
124
|
+
|
125
|
+
def on_draw_item(dc, rect, item, _flags)
|
126
|
+
return if item == Wx::NOT_FOUND
|
127
|
+
|
128
|
+
dc.set_text_foreground(Wx::BLACK)
|
129
|
+
dc.draw_text(get_string(item),
|
130
|
+
rect.x + 3,
|
131
|
+
rect.y + ((rect.height - dc.char_height)/2))
|
132
|
+
end
|
133
|
+
|
134
|
+
def on_draw_background(dc, rect, item, flags)
|
135
|
+
# If item is selected or even, or we are painting the
|
136
|
+
# combo control itself, use the default rendering.
|
137
|
+
if flags.anybits?(Wx::ODCB_PAINTING_CONTROL|Wx::ODCB_PAINTING_SELECTED) || (item & 1) == 0
|
138
|
+
super(dc,rect,item,flags)
|
139
|
+
return
|
140
|
+
end
|
141
|
+
|
142
|
+
# Otherwise, draw every other background with different colour.
|
143
|
+
bgCol = Wx::Colour.new(240,240,250)
|
144
|
+
dc.set_brush(Wx::Brush.new(bgCol))
|
145
|
+
dc.set_pen(Wx::Pen.new(bgCol))
|
146
|
+
dc.draw_rectangle(rect)
|
147
|
+
end
|
148
|
+
|
149
|
+
def on_measure_item(_item)
|
150
|
+
48
|
151
|
+
end
|
152
|
+
|
153
|
+
def on_measure_item_width(_item)
|
154
|
+
-1 # default - will be measured from text width
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
def setup
|
160
|
+
super
|
161
|
+
@combo = TestODComboBox.new(frame_win, name: 'ODComboBox')
|
162
|
+
end
|
163
|
+
|
164
|
+
def cleanup
|
165
|
+
@combo.destroy
|
166
|
+
super
|
167
|
+
end
|
168
|
+
|
169
|
+
attr_reader :combo
|
170
|
+
alias :text_entry :combo
|
171
|
+
|
172
|
+
def fill_list(list)
|
173
|
+
list.append('This is the first item')
|
174
|
+
list.append('This is the second item')
|
175
|
+
list.append('This is the third item')
|
176
|
+
list.append('This is the fourth item')
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_popup
|
180
|
+
assert_equal('', combo.get_value)
|
181
|
+
|
182
|
+
assert_kind_of(Wx::ComboPopup, combo.get_popup_control)
|
183
|
+
assert_kind_of(Wx::ComboPopupWx, combo.get_popup_control)
|
184
|
+
assert_kind_of(Wx::VListBox, combo.get_popup_control.get_control)
|
185
|
+
|
186
|
+
assert_nothing_raised { fill_list(combo) }
|
187
|
+
combo.popup
|
188
|
+
|
189
|
+
combo.set_value_by_user('This is the third item')
|
190
|
+
|
191
|
+
assert_equal('This is the third item', combo.get_popup_control.get_string_value)
|
192
|
+
|
193
|
+
combo.dismiss
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|