fxruby-enhancement 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile ADDED
@@ -0,0 +1,68 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+
6
+ begin
7
+ Bundler.setup(:default, :development)
8
+ rescue Bundler::BundlerError => e
9
+ $stderr.puts e.message
10
+ $stderr.puts "Run `bundle install` to install missing gems"
11
+ exit e.status_code
12
+ end
13
+ require 'rake'
14
+
15
+ require 'semver'
16
+
17
+ def s_version
18
+ SemVer.find.format "%M.%m.%p%s"
19
+ end
20
+
21
+ require 'juwelier'
22
+ Juwelier::Tasks.new do |gem|
23
+ # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
24
+ gem.name = "fxruby-enhancement"
25
+ gem.homepage = "http://github.com/flajann2/fxruby-enhancement"
26
+ gem.license = "MIT"
27
+ gem.summary = %Q{fxruby enhancements}
28
+ gem.description = %Q{The fxruby library is an excellent wrapper for the FOX toolkit. However, it reflects the
29
+ C++-ness of FOX, rather than being more Ruby-like. As such, creating composed objects with
30
+ it tends to be rather ugly and cumbersome.
31
+
32
+ fxruby-enhancement is a wrapper for the wrapper, to "rubyfy" it and make it more easy to
33
+ use for Rubyists.
34
+
35
+ fxruby-enhancement is basically a DSL of sorts, and every effort has been taken to make
36
+ it intuitive to use. Once you get the hang of it, you should be able to look at the FXRuby
37
+ API documentation and infer the DSL construct for fxruby-enhancement.}
38
+
39
+ gem.email = "fred.mitchell@gmx.de"
40
+ gem.authors = ["Fred Mitchell"]
41
+ gem.version = s_version
42
+ gem.required_ruby_version = '>= 2.3.1'
43
+
44
+ # dependencies defined in Gemfile
45
+ end
46
+ Juwelier::RubygemsDotOrgTasks.new
47
+
48
+ require 'rspec/core'
49
+ require 'rspec/core/rake_task'
50
+ RSpec::Core::RakeTask.new(:spec) do |spec|
51
+ spec.pattern = FileList['spec/**/*_spec.rb']
52
+ end
53
+
54
+ desc "Code coverage detail"
55
+ task :simplecov do
56
+ ENV['COVERAGE'] = "true"
57
+ Rake::Task['spec'].execute
58
+ end
59
+
60
+ task :default => :spec
61
+
62
+ desc "Convert rdoc-sources to a static introspection for DSL."
63
+ task :scrape do
64
+ ruby "build/scrape-rdoc.rb"
65
+ end
66
+
67
+ require 'yard'
68
+ YARD::Rake::YardocTask.new
@@ -0,0 +1,120 @@
1
+ # coding: utf-8
2
+
3
+ =begin rdoc
4
+ = Scrape RDoc from FXRuby
5
+ We need to scrape that and convert it to a form
6
+ suitable for static introspection of the FXRuby
7
+ API, with the implied parameters and their defaults
8
+ for the many classes in FXRuby
9
+ =end
10
+
11
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
12
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
13
+
14
+ SOURCES = File.expand_path("../fxruby/rdoc-sources", File.dirname(__FILE__))
15
+ SRC_DEFS = File.expand_path("../fxruby/fox-includes/fxdefs.h", File.dirname(__FILE__))
16
+ TARGET = File.expand_path("../lib/fxruby-enhancement/api-mapper.rb", File.dirname(__FILE__))
17
+ TEMPLATE = File.expand_path("api-mapper.rb.erb", File.dirname(TARGET))
18
+ File.delete TARGET unless not File.exists? TARGET
19
+ File.open(TARGET, 'w') {}
20
+
21
+ require 'fxruby-enhancement'
22
+ require 'erb'
23
+ require 'pp'
24
+
25
+ # Indeed we parse the rdoc-sources to glean the actual API
26
+ # for FXRuby, since live introspection of the actual API
27
+ # is underdeterimed, being a wrapper for the underlying C++
28
+ # library, which does things, unsurpringly, in a very C++
29
+ # way. And so, I fight evil with evil here. So let the evil
30
+ # begin.
31
+
32
+ last_class = nil
33
+ API = Dir.entries(SOURCES)
34
+ .select{ |f| /^FX.*\.rb$/ =~ f }
35
+ .sort
36
+ .map{ |f| File.expand_path(f, SOURCES) }
37
+ .map{ |f| File.open(f, "r").readlines }
38
+ .flatten
39
+ .reject{ |s| /^\s*#/ =~ s }
40
+ .map{ |s| s
41
+ .split(/#|;/).first
42
+ .split('def').last
43
+ .strip }
44
+ .select{ |s| /class|initialize(?!d)/ =~ s }
45
+ .map{ |s| s.split(/ |\(/, 2) }
46
+ .map{ |type, rest| [type.to_sym, rest] }
47
+ .map{ |type, rest| case type
48
+ when :class
49
+ [type, rest.split(/\b*<\b*/)]
50
+ when :initialize
51
+ [type,
52
+ (rest.nil?) ? nil
53
+ : rest.chop.scan(/(?:\(.*?\)|[^,])+/)
54
+ .map{ |s| s
55
+ .strip
56
+ .split('=')}]
57
+ else
58
+ raise "unknown type #{type} for #{rest}"
59
+ end }
60
+ .map{ |type, inf| [type,
61
+ case type
62
+ when :class
63
+ inf.map{ |s| s.strip.to_sym}
64
+ when :initialize
65
+ inf.map{ |var, deft|
66
+ [var.to_sym, deft] }.to_h unless inf.nil?
67
+ end ]}
68
+ .group_by{ |type, inf| case type
69
+ when :class
70
+ last_class = inf.first
71
+ when :initialize
72
+ last_class
73
+ end }
74
+ .map{ |klass, details| [klass,
75
+ details.group_by{ |type, inf| type }]}
76
+ .map{ |klass, details| [klass,
77
+ details.map{ |type, inf| case type
78
+ when :class
79
+ inf.last
80
+ when :initialize
81
+ [type, inf.map{ |t, h| h }]
82
+ end }.to_h
83
+ ]}
84
+ .to_h
85
+
86
+ # Scan for Selectors
87
+ File.open(SRC_DEFS, 'r') do |fd|
88
+ SEL = fd.readlines
89
+ .select{ |s| s =~ /SEL_/ }
90
+ .map{ |s| /(SEL_)([A-Z_]+),(.*)/.match s }
91
+ .compact
92
+ .map{ |md| [md[1], md[2], /\b*\/\/\/(.*)/.match(md[3])] }
93
+ .map{ |s, f, c| [s+f, f.downcase.to_sym, c.nil? ? '' : c[1].strip] }
94
+ end
95
+
96
+ # Now that we have the entire FXRuby API description,
97
+ # we now rely on the template to flesh out and create
98
+ # the DSL. Total insanity that I would attempt to use
99
+ # metaprograming to autogeneate a DSL. No worries. I've
100
+ # done worse. :p I aplogize for the apperent "ugliness"
101
+ # in this approach, but desperate times call for desperate
102
+ # measures...
103
+ #
104
+ # NOTE WELL
105
+ # Please bear in mind that in the API structure, you will
106
+ # see both nil and "nil" listed as default parameters. The
107
+ # nil indicates a required parameter, whereas "nil" indicates
108
+ # a default value for a parameter. Perhaps I should've gone
109
+ # through the extra step of slapping in :required for
110
+ # the nil entries, but getting the logic above was tricky
111
+ # enough, and only those maintaning THIS code will ever
112
+ # need be concerned about the distinctions.
113
+
114
+ File.open(TEMPLATE, 'r') do |template|
115
+ File.open(TARGET, 'w') do |target|
116
+ @api = API
117
+ @sel = SEL
118
+ target.write ERB.new(template.read).result(binding)
119
+ end
120
+ end
@@ -0,0 +1 @@
1
+ 2.4.0
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fxruby-enhancement'
3
+
4
+ include Fox
5
+ include Fox::Enhancement::Mapper
6
+
7
+ ANIMATION_TIME = 20
8
+
9
+ class Ball
10
+ attr_reader :color
11
+ attr_reader :center
12
+ attr_reader :radius
13
+ attr_reader :dir
14
+ attr_reader :x, :y
15
+ attr_reader :w, :h
16
+ attr_accessor :worldWidth
17
+ attr_accessor :worldHeight
18
+
19
+
20
+ def initialize r
21
+ @radius = r
22
+ @w = 2*@radius
23
+ @h = 2*@radius
24
+ @center = FXPoint.new(50, 50)
25
+ @x = @center.x - @radius
26
+ @y = @center.y - @radius
27
+ @color = FXRGB(255, 0, 0) # red
28
+ @dir = FXPoint.new(-1, -1)
29
+ setWorldSize(1000, 1000)
30
+ end
31
+
32
+ # Draw the ball into this device context
33
+ def draw(dc)
34
+ dc.setForeground(color)
35
+ dc.fillArc(x, y, w, h, 0, 64*90)
36
+ dc.fillArc(x, y, w, h, 64*90, 64*180)
37
+ dc.fillArc(x, y, w, h, 64*180, 64*270)
38
+ dc.fillArc(x, y, w, h, 64*270, 64*360)
39
+ end
40
+
41
+ def bounce_x
42
+ @dir.x=-@dir.x
43
+ end
44
+
45
+ def bounce_y
46
+ @dir.y=-@dir.y
47
+ end
48
+
49
+ def collision_y?
50
+ (y<0 && dir.y<0) || (y+h>worldHeight && dir.y>0)
51
+ end
52
+
53
+ def collision_x?
54
+ (x<0 && dir.x<0) || (x+w>worldWidth && dir.x>0)
55
+ end
56
+
57
+ def setWorldSize(ww, wh)
58
+ @worldWidth = ww
59
+ @worldHeight = wh
60
+ end
61
+
62
+ def move(units)
63
+ dx = dir.x*units
64
+ dy = dir.y*units
65
+ center.x += dx
66
+ center.y += dy
67
+ @x += dx
68
+ @y += dy
69
+ if collision_x?
70
+ bounce_x
71
+ move(units)
72
+ end
73
+ if collision_y?
74
+ bounce_y
75
+ move(units)
76
+ end
77
+ end
78
+ end
79
+
80
+ fx_app :app do
81
+ app_name "Bounce"
82
+ vendor_name "Example"
83
+
84
+ fx_image(:back_buffer) { opts IMAGE_KEEP }
85
+
86
+ fx_main_window(:bounce_window) {
87
+ title "Bounce Demo"
88
+ opts DECOR_ALL
89
+ width 400
90
+ height 300
91
+
92
+ instance { |w|
93
+ def w.ball
94
+ @ball ||= Ball.new(20)
95
+ end
96
+
97
+ def w.drawScene(drawable)
98
+ FXDCWindow.new(drawable) { |dc|
99
+ dc.setForeground(FXRGB(255, 255, 255))
100
+ dc.fillRectangle(0, 0, drawable.width, drawable.height)
101
+ ball.draw(dc)
102
+ }
103
+ end
104
+
105
+ def w.updateCanvas
106
+ ball.move(10)
107
+ drawScene(ref(:back_buffer))
108
+ ref(:canvas).update
109
+ end
110
+
111
+ #
112
+ # Handle timeout events
113
+ #
114
+ def w.onTimeout(sender, sel, ptr)
115
+ # Move the ball and re-draw the scene
116
+ updateCanvas
117
+
118
+ # Re-register the timeout
119
+ ref(:app).addTimeout(ANIMATION_TIME, ref(:bounce_window).method(:onTimeout))
120
+
121
+ # Done
122
+ return 1
123
+ end
124
+
125
+ w.show PLACEMENT_SCREEN
126
+ ref(:app).addTimeout(ANIMATION_TIME, w.method(:onTimeout))
127
+ }
128
+
129
+ fx_canvas(:canvas) {
130
+ opts LAYOUT_FILL_X|LAYOUT_FILL_Y
131
+
132
+ instance { |c|
133
+ c.sel_paint { |sender, sel, event|
134
+ FXDCWindow.new(sender, event) { |dc|
135
+ dc.drawImage(ref(:back_buffer), 0, 0)
136
+ }
137
+ }
138
+
139
+ c.sel_configure{ |sender, sel, event|
140
+ bb = ref(:back_buffer)
141
+ bb.create unless bb.created?
142
+ bb.resize(sender.width, sender.height)
143
+ ref(:bounce_window) do |bw|
144
+ bw.ball.setWorldSize(sender.width, sender.height)
145
+ bw.drawScene(bb)
146
+ end
147
+ }
148
+ }
149
+ }
150
+ }
151
+ end
152
+
153
+ if __FILE__ == $0
154
+ # alias for fox_component is fxc
155
+ fox_component :app do |app|
156
+ app.launch
157
+ end
158
+ end
data/examples/hello.rb ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fxruby-enhancement'
3
+
4
+ include Fox
5
+ include Fox::Enhancement::Mapper
6
+
7
+ fx_app :app do
8
+ app_name "Hello"
9
+ vendor_name "Example"
10
+
11
+ fx_main_window(:main) {
12
+ title "Hello"
13
+ opts DECOR_ALL
14
+
15
+ fx_button {
16
+ text "&Hello, World"
17
+ selector FXApp::ID_QUIT
18
+
19
+ instance { |b|
20
+ b.target = ref(:app)
21
+ }
22
+ }
23
+
24
+ instance { |w|
25
+ w.show PLACEMENT_SCREEN
26
+ }
27
+ }
28
+ end
29
+
30
+ # alias for fox_component is fxc
31
+ fox_component :app do |app|
32
+ app.launch
33
+ end
@@ -0,0 +1,112 @@
1
+ # Generated by juwelier
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+ # stub: fxruby-enhancement 0.0.2 ruby lib
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "fxruby-enhancement".freeze
9
+ s.version = "0.0.2"
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib".freeze]
13
+ s.authors = ["Fred Mitchell".freeze]
14
+ s.date = "2017-01-11"
15
+ s.description = "The fxruby library is an excellent wrapper for the FOX toolkit. However, it reflects the\n C++-ness of FOX, rather than being more Ruby-like. As such, creating composed objects with\n it tends to be rather ugly and cumbersome.\n\n fxruby-enhancement is a wrapper for the wrapper, to \"rubyfy\" it and make it more easy to \n use for Rubyists. \n\n fxruby-enhancement is basically a DSL of sorts, and every effort has been taken to make \n it intuitive to use. Once you get the hang of it, you should be able to look at the FXRuby\n API documentation and infer the DSL construct for fxruby-enhancement.".freeze
16
+ s.email = "fred.mitchell@gmx.de".freeze
17
+ s.extra_rdoc_files = [
18
+ "LICENSE.txt",
19
+ "README.org"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".gitmodules",
24
+ ".rspec",
25
+ ".ruby-version",
26
+ ".semver",
27
+ "Gemfile",
28
+ "Gemfile.lock",
29
+ "LICENSE.txt",
30
+ "README.org",
31
+ "Rakefile",
32
+ "build/scrape-rdoc.rb",
33
+ "examples/.ruby-version",
34
+ "examples/bounce.rb",
35
+ "examples/hello.rb",
36
+ "fxruby-enhancement.gemspec",
37
+ "lib/fxruby-enhancement.rb",
38
+ "lib/fxruby-enhancement/api-mapper.rb",
39
+ "lib/fxruby-enhancement/api-mapper.rb.erb",
40
+ "lib/fxruby-enhancement/core-monkey.rb",
41
+ "lib/fxruby-enhancement/enhancement.rb",
42
+ "lib/fxruby-enhancement/ostruct-monkey.rb",
43
+ "spec/fxruby-enhancement_spec.rb",
44
+ "spec/spec_helper.rb"
45
+ ]
46
+ s.homepage = "http://github.com/flajann2/fxruby-enhancement".freeze
47
+ s.licenses = ["MIT".freeze]
48
+ s.required_ruby_version = Gem::Requirement.new(">= 2.3.1".freeze)
49
+ s.rubygems_version = "2.6.8".freeze
50
+ s.summary = "fxruby enhancements".freeze
51
+
52
+ if s.respond_to? :specification_version then
53
+ s.specification_version = 4
54
+
55
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
56
+ s.add_runtime_dependency(%q<semver2>.freeze, ["~> 3"])
57
+ s.add_runtime_dependency(%q<fxruby>.freeze, ["~> 1.6"])
58
+ s.add_runtime_dependency(%q<awesome_print>.freeze, [">= 1"])
59
+ s.add_runtime_dependency(%q<json>.freeze, [">= 2.0.2", "~> 2.0"])
60
+ s.add_runtime_dependency(%q<queue_ding>.freeze, ["~> 0"])
61
+ s.add_development_dependency(%q<rspec>.freeze, ["~> 3"])
62
+ s.add_development_dependency(%q<yard>.freeze, ["~> 0.7"])
63
+ s.add_development_dependency(%q<rdoc>.freeze, ["~> 5"])
64
+ s.add_development_dependency(%q<bundler>.freeze, ["~> 1.0"])
65
+ s.add_development_dependency(%q<juwelier>.freeze, ["~> 2"])
66
+ s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
67
+ s.add_development_dependency(%q<pry>.freeze, [">= 0"])
68
+ s.add_development_dependency(%q<pry-byebug>.freeze, [">= 3"])
69
+ s.add_development_dependency(%q<pry-doc>.freeze, [">= 0"])
70
+ s.add_development_dependency(%q<pry-remote>.freeze, [">= 0"])
71
+ s.add_development_dependency(%q<pry-rescue>.freeze, [">= 1"])
72
+ s.add_development_dependency(%q<pry-stack_explorer>.freeze, [">= 0"])
73
+ else
74
+ s.add_dependency(%q<semver2>.freeze, ["~> 3"])
75
+ s.add_dependency(%q<fxruby>.freeze, ["~> 1.6"])
76
+ s.add_dependency(%q<awesome_print>.freeze, [">= 1"])
77
+ s.add_dependency(%q<json>.freeze, [">= 2.0.2", "~> 2.0"])
78
+ s.add_dependency(%q<queue_ding>.freeze, ["~> 0"])
79
+ s.add_dependency(%q<rspec>.freeze, ["~> 3"])
80
+ s.add_dependency(%q<yard>.freeze, ["~> 0.7"])
81
+ s.add_dependency(%q<rdoc>.freeze, ["~> 5"])
82
+ s.add_dependency(%q<bundler>.freeze, ["~> 1.0"])
83
+ s.add_dependency(%q<juwelier>.freeze, ["~> 2"])
84
+ s.add_dependency(%q<simplecov>.freeze, [">= 0"])
85
+ s.add_dependency(%q<pry>.freeze, [">= 0"])
86
+ s.add_dependency(%q<pry-byebug>.freeze, [">= 3"])
87
+ s.add_dependency(%q<pry-doc>.freeze, [">= 0"])
88
+ s.add_dependency(%q<pry-remote>.freeze, [">= 0"])
89
+ s.add_dependency(%q<pry-rescue>.freeze, [">= 1"])
90
+ s.add_dependency(%q<pry-stack_explorer>.freeze, [">= 0"])
91
+ end
92
+ else
93
+ s.add_dependency(%q<semver2>.freeze, ["~> 3"])
94
+ s.add_dependency(%q<fxruby>.freeze, ["~> 1.6"])
95
+ s.add_dependency(%q<awesome_print>.freeze, [">= 1"])
96
+ s.add_dependency(%q<json>.freeze, [">= 2.0.2", "~> 2.0"])
97
+ s.add_dependency(%q<queue_ding>.freeze, ["~> 0"])
98
+ s.add_dependency(%q<rspec>.freeze, ["~> 3"])
99
+ s.add_dependency(%q<yard>.freeze, ["~> 0.7"])
100
+ s.add_dependency(%q<rdoc>.freeze, ["~> 5"])
101
+ s.add_dependency(%q<bundler>.freeze, ["~> 1.0"])
102
+ s.add_dependency(%q<juwelier>.freeze, ["~> 2"])
103
+ s.add_dependency(%q<simplecov>.freeze, [">= 0"])
104
+ s.add_dependency(%q<pry>.freeze, [">= 0"])
105
+ s.add_dependency(%q<pry-byebug>.freeze, [">= 3"])
106
+ s.add_dependency(%q<pry-doc>.freeze, [">= 0"])
107
+ s.add_dependency(%q<pry-remote>.freeze, [">= 0"])
108
+ s.add_dependency(%q<pry-rescue>.freeze, [">= 1"])
109
+ s.add_dependency(%q<pry-stack_explorer>.freeze, [">= 0"])
110
+ end
111
+ end
112
+