fxruby-enhancement 0.1.0 → 0.2.0
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/.semver +1 -1
- data/Gemfile +5 -4
- data/Gemfile.lock +8 -7
- data/README.org +492 -13
- data/build/scrape-rdoc.rb +288 -0
- data/examples/bounce.rb +4 -2
- data/examples/data_target.rb +0 -0
- data/examples/debug +10 -0
- data/examples/dialog_box.rb +0 -0
- data/examples/hello.rb +0 -0
- data/examples/images/bounce.rb.png +0 -0
- data/examples/images/data_target.rb.png +0 -0
- data/examples/images/dialog_box.rb.png +0 -0
- data/examples/images/hello-world-new-and-old.png +0 -0
- data/examples/images/hello.rb.png +0 -0
- data/examples/images/rubyneat-panel.png +0 -0
- data/examples/images/scribble.rb.png +0 -0
- data/examples/scribble.rb +175 -0
- data/fxruby-enhancement.gemspec +21 -3
- data/lib/fxruby-enhancement.rb +4 -1
- data/lib/fxruby-enhancement/api-mapper.rb +4967 -3793
- data/lib/fxruby-enhancement/api-mapper.rb.erb +17 -12
- data/lib/fxruby-enhancement/color-mapper.rb +1103 -0
- data/lib/fxruby-enhancement/color-mapper.rb.erb +23 -0
- data/lib/fxruby-enhancement/enhancement.rb +41 -2
- data/lib/fxruby-enhancement/ostruct-monkey.rb +18 -3
- data/lib/fxruby-enhancement/rgb-monkey.rb +54 -0
- data/lib/fxruby-enhancement/xtras.rb +1 -0
- data/lib/fxruby-enhancement/xtras/charting-boxes.rb +247 -0
- data/lib/fxruby-enhancement/xtras/charting.rb +336 -0
- metadata +31 -2
@@ -0,0 +1,336 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require_relative 'charting-boxes'
|
3
|
+
|
4
|
+
module Fox
|
5
|
+
module Enhancement
|
6
|
+
module Xtras
|
7
|
+
# Charting constructs. Note that the
|
8
|
+
# rulers have built-in their own labeling, with orientation.
|
9
|
+
module Charting
|
10
|
+
# range in real coordinates, beginning and end points
|
11
|
+
class Range
|
12
|
+
attr_accessor :x1, :y1, :x2, :y2
|
13
|
+
|
14
|
+
def initialize x1, y1, x2, y2
|
15
|
+
@x1 = x1
|
16
|
+
@y1 = y1
|
17
|
+
@x2 = x2
|
18
|
+
@y2 = y2
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Chart
|
23
|
+
extend Forwardable
|
24
|
+
include RGB
|
25
|
+
|
26
|
+
def_delegators :@canvas, :width, :height, :visual
|
27
|
+
def_delegators :@cos, :type,
|
28
|
+
:axial, :data, :series, :domain, :range,
|
29
|
+
:background, :caption, :title
|
30
|
+
|
31
|
+
attr_accessor :buffer, :x_range, :y_range
|
32
|
+
|
33
|
+
def initialize cos, canvas
|
34
|
+
@cos = cos
|
35
|
+
@canvas = canvas
|
36
|
+
as (:app) {
|
37
|
+
@buffer = fx_image { opts IMAGE_KEEP }
|
38
|
+
}
|
39
|
+
# detailed chart parameters
|
40
|
+
@x_ruler_width = 20
|
41
|
+
@y_ruler_height = 20
|
42
|
+
@font_title = nil
|
43
|
+
@font_caption = nil
|
44
|
+
@font_ledgend = nil
|
45
|
+
@font_axis_name = nil
|
46
|
+
|
47
|
+
# chart layout
|
48
|
+
lytbox = ->(klass, **kv){ [kv[:name], klass.new(self, **kv)] }
|
49
|
+
@layout = lyt = [
|
50
|
+
lytbox.(NullBox, name: :null_left, placement: :left),
|
51
|
+
lytbox.(NullBox, name: :null_right, placement: :right),
|
52
|
+
lytbox.(NullBox, name: :null_top, placement: :top),
|
53
|
+
lytbox.(NullBox, name: :null_bottom, placement: :bottom),
|
54
|
+
lytbox.(Title, name: :title, float: true),
|
55
|
+
lytbox.(Ruler, name: :top_ruler, orient: :horizontal, placement: :top),
|
56
|
+
lytbox.(Ruler, name: :bottom_ruler, orient: :horizontal, placement: :bottom),
|
57
|
+
lytbox.(Ruler, name: :left_ruler, orient: :vertical, placement: :left),
|
58
|
+
lytbox.(Ruler, name: :right_ruler, orient: :vertical, placement: :right),
|
59
|
+
lytbox.(Caption, name: :caption, float: true),
|
60
|
+
lytbox.(Legend, name: :legend, float: true),
|
61
|
+
lytbox.(Graph, name: :graph)
|
62
|
+
].to_h
|
63
|
+
|
64
|
+
# bottom connections
|
65
|
+
lyt[:null_top].bottom_box = lyt[:title]
|
66
|
+
lyt[:title].bottom_box = lyt[:top_ruler]
|
67
|
+
lyt[:top_ruler].bottom_box = lyt[:graph]
|
68
|
+
lyt[:graph].bottom_box = lyt[:bottom_ruler]
|
69
|
+
lyt[:bottom_ruler].bottom_box = lyt[:caption]
|
70
|
+
lyt[:caption].bottom_box = lyt[:null_bottom]
|
71
|
+
|
72
|
+
# right connections
|
73
|
+
lyt[:null_left].right_box = lyt[:left_ruler]
|
74
|
+
lyt[:left_ruler].right_box = lyt[:graph]
|
75
|
+
lyt[:graph].right_box = lyt[:right_ruler]
|
76
|
+
lyt[:right_ruler].right_box = lyt[:legend]
|
77
|
+
lyt[:legend].right_box = lyt[:null_right]
|
78
|
+
|
79
|
+
backlink_boxes
|
80
|
+
end
|
81
|
+
|
82
|
+
def backlink_boxes
|
83
|
+
@layout.each{ |name, box|
|
84
|
+
box.bottom_box.top_box = box unless box.bottom_box.nil?
|
85
|
+
box.right_box.left_box = box unless box.right_box.nil?
|
86
|
+
}
|
87
|
+
end
|
88
|
+
|
89
|
+
# call inially and when there's an update.
|
90
|
+
def layout_boxes
|
91
|
+
clear_all_boxes
|
92
|
+
recalculate_dimensions
|
93
|
+
|
94
|
+
# first pass -- out to in
|
95
|
+
(0..Box::MAX_DOMINANCE).each do |dom|
|
96
|
+
boxes_of_dominance(dom).each{ |box| layout_box box }
|
97
|
+
end
|
98
|
+
|
99
|
+
# second pass -- in to out
|
100
|
+
(1..Box::MAX_DOMINANCE).to_a.reverse.each do |dom|
|
101
|
+
boxes_of_dominance(dom).each{ |box| layout_box box }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# All x,y,width,height are nilled for all boxes
|
106
|
+
def clear_all_boxes
|
107
|
+
@layout.each { |name, box|
|
108
|
+
box.x = box.y = box.width = box.height = nil
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
112
|
+
def recalculate_dimensions
|
113
|
+
@layout.each { |name, box|
|
114
|
+
box.calculate_dimensions
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
# Layout given box, as much as possible, given neighbors.
|
119
|
+
# may be called twice per box.
|
120
|
+
#
|
121
|
+
def layout_box box
|
122
|
+
if box.dominance == 0 # the only box with a dom of 0 are the null boxes
|
123
|
+
case box.name
|
124
|
+
when :null_left
|
125
|
+
box.x = 0
|
126
|
+
box.y = 0
|
127
|
+
box.width = 0
|
128
|
+
box.height = height
|
129
|
+
when :null_right
|
130
|
+
box.x = width
|
131
|
+
box.y = 0
|
132
|
+
box.width = 0
|
133
|
+
box.height = height
|
134
|
+
when :null_top
|
135
|
+
box.x = 0
|
136
|
+
box.y = 0
|
137
|
+
box.width = width
|
138
|
+
box.height = 0
|
139
|
+
when :null_bottom
|
140
|
+
box.x = 0
|
141
|
+
box.y = height
|
142
|
+
box.width = width
|
143
|
+
box.height = 0
|
144
|
+
end
|
145
|
+
else # we do what we can.
|
146
|
+
box.calculate_dimensions
|
147
|
+
subordinates(box).each { |sub|
|
148
|
+
begin
|
149
|
+
case sub
|
150
|
+
when box.left_box
|
151
|
+
box.x = sub.x + sub.width + sub.right_margin + box.left_margin
|
152
|
+
when box.right_box
|
153
|
+
box.x = sub.x - sub.left_margin - box.right_margin - box.width
|
154
|
+
when box.top_box
|
155
|
+
box.y = sub.y + sub.height + sub.bottom_margin + box.top_margin
|
156
|
+
when box.bottom_box
|
157
|
+
box.y = sub.y - sub.top_margin - box.bottom_margin - box.height
|
158
|
+
end
|
159
|
+
rescue NoMethodError, TypeError => e
|
160
|
+
#puts "-->subortinate unresolved: #{e}"
|
161
|
+
end
|
162
|
+
}
|
163
|
+
|
164
|
+
superiors(box).each { |sup|
|
165
|
+
begin
|
166
|
+
case sup
|
167
|
+
when box.left_box
|
168
|
+
box.height = sup.height
|
169
|
+
box.y = sup.y
|
170
|
+
box.x = sup.x + sup.width + sup.right_margin + box.left_margin
|
171
|
+
when box.right_box
|
172
|
+
box.height = sup.height
|
173
|
+
box.y = sup.y
|
174
|
+
when box.top_box
|
175
|
+
box.width = sup.width
|
176
|
+
box.x = sup.x
|
177
|
+
when box.bottom_box
|
178
|
+
box.width = sup.width
|
179
|
+
box.x = sup.x
|
180
|
+
end
|
181
|
+
rescue NoMethodError, TypeError => e
|
182
|
+
#puts "-->superior unresolved: #{e}"
|
183
|
+
end unless box.floating?
|
184
|
+
}
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# Give a list of subordinates
|
189
|
+
def subordinates box
|
190
|
+
Box::NÄHE.map{ |b| box.send(b) }
|
191
|
+
.compact
|
192
|
+
.select { |nbox| box.dominance > nbox.dominance }
|
193
|
+
end
|
194
|
+
|
195
|
+
# Give a list of superiors
|
196
|
+
def superiors box
|
197
|
+
Box::NÄHE.map{ |b| box.send(b) }
|
198
|
+
.compact
|
199
|
+
.select { |nbox| box.dominance < nbox.dominance }
|
200
|
+
end
|
201
|
+
|
202
|
+
# return all boxes with the proscribed dominance
|
203
|
+
def boxes_of_dominance dom
|
204
|
+
@layout.map{ |name, box| box }.select{ |box| box.dominance == dom }
|
205
|
+
end
|
206
|
+
|
207
|
+
def draw_dc &block
|
208
|
+
@buffer.starten if @buffer.inst.nil?
|
209
|
+
FXDCWindow.new(@buffer.inst) { |dc| block.(dc) }
|
210
|
+
end
|
211
|
+
|
212
|
+
def update_chart
|
213
|
+
layout_boxes
|
214
|
+
draw_dc { |dc|
|
215
|
+
dc.setForeground white
|
216
|
+
dc.fillRectangle 0, 0, width, height
|
217
|
+
dc.drawImage @buffer.inst, 0, 0
|
218
|
+
@layout.each{ |name, box| box.render(dc) }
|
219
|
+
}
|
220
|
+
@canvas.update
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
module Mapper
|
227
|
+
def fx_chart name = nil,
|
228
|
+
ii: 0,
|
229
|
+
pos: Enhancement.stack.last,
|
230
|
+
reuse: nil,
|
231
|
+
&block
|
232
|
+
Enhancement.stack << (@os = os =
|
233
|
+
OpenStruct.new(klass: FXCanvas,
|
234
|
+
op: [],
|
235
|
+
ii: ii,
|
236
|
+
fx: nil,
|
237
|
+
kinder: [],
|
238
|
+
inst: nil,
|
239
|
+
instance_result: nil,
|
240
|
+
reusable: reuse,
|
241
|
+
type: :cartesian,
|
242
|
+
axial: OpenStruct.new,
|
243
|
+
background: OpenStruct.new,
|
244
|
+
caption: OpenStruct.new,
|
245
|
+
title: OpenStruct.new))
|
246
|
+
Enhancement.components[name] = os unless name.nil?
|
247
|
+
unless pos.nil?
|
248
|
+
pos.kinder << os
|
249
|
+
else
|
250
|
+
Enhancement.base = os
|
251
|
+
end
|
252
|
+
|
253
|
+
@os.op[0] = OpenStruct.new(:parent => :required,
|
254
|
+
:target => nil,
|
255
|
+
:selector => 0,
|
256
|
+
:opts => FRAME_NORMAL,
|
257
|
+
:x => 0,
|
258
|
+
:y => 0,
|
259
|
+
:width => 0,
|
260
|
+
:height => 0)
|
261
|
+
|
262
|
+
# Initializers for the underlying
|
263
|
+
def target var; @os.op[@os.ii].target = var; end
|
264
|
+
def selector var; @os.op[@os.ii].selector = var; end
|
265
|
+
def opts var; @os.op[@os.ii].opts = var; end
|
266
|
+
def x var; @os.op[@os.ii].x = var; end
|
267
|
+
def y var; @os.op[@os.ii].y = var; end
|
268
|
+
def width var; @os.op[@os.ii].width = var; end
|
269
|
+
def height var; @os.op[@os.ii].height = var; end
|
270
|
+
|
271
|
+
# Chart specific
|
272
|
+
def type var; @os.type = var; end
|
273
|
+
|
274
|
+
def axis ax, **kv
|
275
|
+
@os.axial[ax] = OpenStruct.new(**kv)
|
276
|
+
end
|
277
|
+
|
278
|
+
def data *dat; @os.data = dat; end
|
279
|
+
def series ser; @os.series = ser; end
|
280
|
+
def domain a, b; @os.domain = [a, b]; end
|
281
|
+
def range a, b; @os.range = [a, b]; end
|
282
|
+
|
283
|
+
def background **kv; kv.each{ |k,v| @os.background[k] = v }; end
|
284
|
+
def caption **kv; kv.each{ |k,v| @os.caption[k] = v }; end
|
285
|
+
def title **kv; kv.each{ |k,v| @os.title[k] = v }; end
|
286
|
+
|
287
|
+
# What will be executed after FXCanvas is created.
|
288
|
+
def instance aname=nil, &block
|
289
|
+
@os.instance_name = aname
|
290
|
+
@os.instance_block ||= []
|
291
|
+
@os.instance_block << [aname, block]
|
292
|
+
end
|
293
|
+
|
294
|
+
# Internal use only.
|
295
|
+
def chart_instance os, &block
|
296
|
+
os.instance_name = nil
|
297
|
+
os.instance_block ||= []
|
298
|
+
os.instance_block << [nil, block]
|
299
|
+
return os
|
300
|
+
end
|
301
|
+
|
302
|
+
self.instance_eval &block
|
303
|
+
|
304
|
+
os.fx = ->(){
|
305
|
+
chart_instance (os) { |c|
|
306
|
+
os.chart = Xtras::Charting::Chart.new os, c
|
307
|
+
os.inst.instance_variable_set(:@chart, os.chart)
|
308
|
+
}
|
309
|
+
|
310
|
+
c = FXCanvas.new(*([pos.inst] + os.op[os.ii].to_h.values[1..-1]
|
311
|
+
.map{ |v| (v.is_a?(OpenStruct) ? v.inst : v)} ))
|
312
|
+
c.extend SingleForwardable
|
313
|
+
c.def_delegators :@chart, :update_chart
|
314
|
+
c.sel_configure { |sender, sel, event|
|
315
|
+
os.chart.buffer.starten if os.chart.buffer.inst.nil?
|
316
|
+
bb = os.chart.buffer.inst
|
317
|
+
bb.create unless bb.created?
|
318
|
+
bb.resize sender.width, sender.height
|
319
|
+
}
|
320
|
+
c.sel_paint { |sender, sel, event|
|
321
|
+
FXDCWindow.new(sender, event) { |dc|
|
322
|
+
os.chart.buffer.starten if os.chart.buffer.inst.nil?
|
323
|
+
dc.drawImage(os.chart.buffer.inst, 0, 0)
|
324
|
+
}
|
325
|
+
}
|
326
|
+
c
|
327
|
+
}
|
328
|
+
|
329
|
+
Enhancement.stack.pop
|
330
|
+
@os = Enhancement.stack.last
|
331
|
+
return os
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fxruby-enhancement
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Mitchell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-02-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: semver2
|
@@ -86,6 +86,20 @@ dependencies:
|
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: '0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rgb
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :runtime
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
89
103
|
- !ruby/object:Gem::Dependency
|
90
104
|
name: rspec
|
91
105
|
requirement: !ruby/object:Gem::Requirement
|
@@ -283,15 +297,30 @@ files:
|
|
283
297
|
- examples/.ruby-version
|
284
298
|
- examples/bounce.rb
|
285
299
|
- examples/data_target.rb
|
300
|
+
- examples/debug
|
286
301
|
- examples/dialog_box.rb
|
287
302
|
- examples/hello.rb
|
303
|
+
- examples/images/bounce.rb.png
|
304
|
+
- examples/images/data_target.rb.png
|
305
|
+
- examples/images/dialog_box.rb.png
|
306
|
+
- examples/images/hello-world-new-and-old.png
|
307
|
+
- examples/images/hello.rb.png
|
308
|
+
- examples/images/rubyneat-panel.png
|
309
|
+
- examples/images/scribble.rb.png
|
310
|
+
- examples/scribble.rb
|
288
311
|
- fxruby-enhancement.gemspec
|
289
312
|
- lib/fxruby-enhancement.rb
|
290
313
|
- lib/fxruby-enhancement/api-mapper.rb
|
291
314
|
- lib/fxruby-enhancement/api-mapper.rb.erb
|
315
|
+
- lib/fxruby-enhancement/color-mapper.rb
|
316
|
+
- lib/fxruby-enhancement/color-mapper.rb.erb
|
292
317
|
- lib/fxruby-enhancement/core-monkey.rb
|
293
318
|
- lib/fxruby-enhancement/enhancement.rb
|
294
319
|
- lib/fxruby-enhancement/ostruct-monkey.rb
|
320
|
+
- lib/fxruby-enhancement/rgb-monkey.rb
|
321
|
+
- lib/fxruby-enhancement/xtras.rb
|
322
|
+
- lib/fxruby-enhancement/xtras/charting-boxes.rb
|
323
|
+
- lib/fxruby-enhancement/xtras/charting.rb
|
295
324
|
- spec/fxruby-enhancement_spec.rb
|
296
325
|
- spec/spec_helper.rb
|
297
326
|
homepage: http://github.com/flajann2/fxruby-enhancement
|