glimmer-dsl-libui 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +684 -215
- data/VERSION +1 -1
- data/examples/area_gallery.rb +36 -38
- data/examples/area_gallery2.rb +90 -92
- data/examples/area_gallery3.rb +39 -41
- data/examples/area_gallery4.rb +96 -98
- data/examples/basic_area2.rb +1 -1
- data/examples/basic_transform.rb +27 -0
- data/examples/dynamic_area.rb +1 -1
- data/examples/histogram.rb +119 -0
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/libui/arc.rb +1 -1
- data/lib/glimmer/libui/area_proxy.rb +21 -11
- data/lib/glimmer/libui/box.rb +1 -1
- data/lib/glimmer/libui/color_button_proxy.rb +67 -15
- data/lib/glimmer/libui/control_proxy.rb +4 -12
- data/lib/glimmer/libui/form_proxy.rb +1 -1
- data/lib/glimmer/libui/grid_proxy.rb +1 -1
- data/lib/glimmer/libui/matrix_proxy.rb +145 -0
- data/lib/glimmer/libui/parent.rb +36 -0
- data/lib/glimmer/libui/path_proxy.rb +14 -17
- data/lib/glimmer/libui/shape.rb +8 -9
- data/lib/glimmer/libui/transformable.rb +72 -0
- data/lib/glimmer/libui/window_proxy.rb +8 -1
- data/lib/glimmer/libui.rb +50 -0
- data/lib/glimmer-dsl-libui.rb +1 -0
- metadata +8 -2
@@ -0,0 +1,119 @@
|
|
1
|
+
# https://github.com/jamescook/libui-ruby/blob/master/example/histogram.rb
|
2
|
+
|
3
|
+
require 'glimmer-dsl-libui'
|
4
|
+
|
5
|
+
include Glimmer
|
6
|
+
|
7
|
+
X_OFF_LEFT = 20
|
8
|
+
Y_OFF_TOP = 20
|
9
|
+
X_OFF_RIGHT = 20
|
10
|
+
Y_OFF_BOTTOM = 20
|
11
|
+
POINT_RADIUS = 5
|
12
|
+
|
13
|
+
COLOR_BLUE = 0x1E90FF
|
14
|
+
|
15
|
+
def graph_size(area_width, area_height)
|
16
|
+
graph_width = area_width - X_OFF_LEFT - X_OFF_RIGHT
|
17
|
+
graph_height = area_height - Y_OFF_TOP - Y_OFF_BOTTOM
|
18
|
+
[graph_width, graph_height]
|
19
|
+
end
|
20
|
+
|
21
|
+
def point_locations(datapoints, width, height)
|
22
|
+
xincr = width / 9.0 # 10 - 1 to make the last point be at the end
|
23
|
+
yincr = height / 100.0
|
24
|
+
|
25
|
+
data = []
|
26
|
+
datapoints.each_with_index do |dp, i|
|
27
|
+
val = 100 - dp.value
|
28
|
+
data << [xincr * i, yincr * val]
|
29
|
+
i += 1
|
30
|
+
end
|
31
|
+
|
32
|
+
data
|
33
|
+
end
|
34
|
+
|
35
|
+
def graph_path(datapoints, width, height, should_extend, &block)
|
36
|
+
locations = point_locations(datapoints, width, height)
|
37
|
+
path {
|
38
|
+
first_location = locations[0] # x and y
|
39
|
+
figure(first_location[0], first_location[1]) {
|
40
|
+
locations.each do |loc|
|
41
|
+
line(loc[0], loc[1])
|
42
|
+
end
|
43
|
+
if should_extend
|
44
|
+
line(width, height)
|
45
|
+
line(0, height)
|
46
|
+
|
47
|
+
closed true
|
48
|
+
end
|
49
|
+
}
|
50
|
+
|
51
|
+
# now transform the coordinate space so (0, 0) is the top-left corner of the graph
|
52
|
+
transform {
|
53
|
+
translate X_OFF_LEFT, Y_OFF_TOP
|
54
|
+
}
|
55
|
+
|
56
|
+
block.call
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
window('histogram example', 640, 480) {
|
61
|
+
margined true
|
62
|
+
|
63
|
+
horizontal_box {
|
64
|
+
vertical_box {
|
65
|
+
stretchy false
|
66
|
+
|
67
|
+
@datapoints = 10.times.map do
|
68
|
+
spinbox(0, 100) { |datapoint|
|
69
|
+
stretchy false
|
70
|
+
value Random.new.rand(90)
|
71
|
+
|
72
|
+
on_changed do
|
73
|
+
@area.queue_redraw_all
|
74
|
+
end
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
@color_button = color_button {
|
79
|
+
stretchy false
|
80
|
+
color COLOR_BLUE
|
81
|
+
|
82
|
+
on_changed do
|
83
|
+
@area.queue_redraw_all
|
84
|
+
end
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
@area = area {
|
89
|
+
on_draw do |area_draw_params|
|
90
|
+
path {
|
91
|
+
rectangle(0, 0, area_draw_params[:area_width], area_draw_params[:area_height])
|
92
|
+
|
93
|
+
fill color: 0xFFFFFF
|
94
|
+
}
|
95
|
+
|
96
|
+
graph_width, graph_height = *graph_size(area_draw_params[:area_width], area_draw_params[:area_height])
|
97
|
+
|
98
|
+
path {
|
99
|
+
figure(X_OFF_LEFT, Y_OFF_TOP) {
|
100
|
+
line(X_OFF_LEFT, Y_OFF_TOP + graph_height)
|
101
|
+
line(X_OFF_LEFT + graph_width, Y_OFF_TOP + graph_height)
|
102
|
+
}
|
103
|
+
|
104
|
+
stroke color: 0x000000, thickness: 2, miter_limit: 10
|
105
|
+
}
|
106
|
+
|
107
|
+
# now create the fill for the graph below the graph line
|
108
|
+
graph_path(@datapoints, graph_width, graph_height, true) {
|
109
|
+
fill @color_button.color.merge(a: 0.5)
|
110
|
+
}
|
111
|
+
|
112
|
+
# now draw the histogram line
|
113
|
+
graph_path(@datapoints, graph_width, graph_height, false) {
|
114
|
+
stroke @color_button.color.merge(thickness: 2, miter_limit: 10)
|
115
|
+
}
|
116
|
+
end
|
117
|
+
}
|
118
|
+
}
|
119
|
+
}.show
|
data/glimmer-dsl-libui.gemspec
CHANGED
Binary file
|
data/lib/glimmer/libui/arc.rb
CHANGED
@@ -28,7 +28,7 @@ module Glimmer
|
|
28
28
|
parameter_defaults 0, 0, 0, 0, 360, false
|
29
29
|
|
30
30
|
def draw(area_draw_params)
|
31
|
-
@args[5] ||=
|
31
|
+
@args[5] ||= Glimmer::LibUI.boolean_to_integer(@args[5], allow_nil: false)
|
32
32
|
if parent.is_a?(Figure) && parent.x.nil? && parent.y.nil?
|
33
33
|
::LibUI.draw_path_new_figure_with_arc(path_proxy.libui, *@args)
|
34
34
|
else
|
@@ -21,6 +21,8 @@
|
|
21
21
|
|
22
22
|
require 'glimmer/libui/control_proxy'
|
23
23
|
require 'glimmer/fiddle_consumer'
|
24
|
+
require 'glimmer/libui/parent'
|
25
|
+
require 'glimmer/libui/transformable'
|
24
26
|
|
25
27
|
module Glimmer
|
26
28
|
module LibUI
|
@@ -28,24 +30,22 @@ module Glimmer
|
|
28
30
|
#
|
29
31
|
# Follows the Proxy Design Pattern
|
30
32
|
class AreaProxy < ControlProxy
|
33
|
+
class << self
|
34
|
+
# this attribute is only populated during on_draw call
|
35
|
+
attr_accessor :current_area_draw_params
|
36
|
+
end
|
37
|
+
|
31
38
|
include Glimmer::FiddleConsumer
|
39
|
+
include Parent
|
40
|
+
prepend Transformable
|
32
41
|
|
33
42
|
attr_reader :area_handler
|
34
43
|
|
35
|
-
def post_initialize_child(child)
|
36
|
-
super
|
37
|
-
children << child
|
38
|
-
end
|
39
|
-
|
40
44
|
def post_add_content
|
41
45
|
super
|
42
46
|
install_listeners
|
43
47
|
end
|
44
48
|
|
45
|
-
def children
|
46
|
-
@children ||= []
|
47
|
-
end
|
48
|
-
|
49
49
|
def on_draw(&block)
|
50
50
|
@on_draw_procs ||= []
|
51
51
|
if block.nil?
|
@@ -69,6 +69,15 @@ module Glimmer
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
+
def draw(area_draw_params)
|
73
|
+
children.dup.each {|child| child.draw(area_draw_params)}
|
74
|
+
on_draw.each {|listener| listener.call(area_draw_params)}
|
75
|
+
end
|
76
|
+
|
77
|
+
def redraw
|
78
|
+
queue_redraw_all
|
79
|
+
end
|
80
|
+
|
72
81
|
private
|
73
82
|
|
74
83
|
def build_control
|
@@ -80,8 +89,9 @@ module Glimmer
|
|
80
89
|
@area_handler.Draw = fiddle_closure_block_caller(0, [1, 1, 1]) do |_, _, area_draw_params|
|
81
90
|
area_draw_params = ::LibUI::FFI::AreaDrawParams.new(area_draw_params)
|
82
91
|
area_draw_params = area_draw_params_hash(area_draw_params)
|
83
|
-
|
84
|
-
|
92
|
+
AreaProxy.current_area_draw_params = area_draw_params
|
93
|
+
draw(area_draw_params)
|
94
|
+
AreaProxy.current_area_draw_params = nil
|
85
95
|
end
|
86
96
|
@area_handler.MouseEvent = fiddle_closure_block_caller(0, [0]) {}
|
87
97
|
@area_handler.MouseCrossed = fiddle_closure_block_caller(0, [0]) {}
|
data/lib/glimmer/libui/box.rb
CHANGED
@@ -28,7 +28,7 @@ module Glimmer
|
|
28
28
|
|
29
29
|
def post_initialize_child(child)
|
30
30
|
child.stretchy = true if child.stretchy.nil?
|
31
|
-
::LibUI.box_append(@libui, child.libui,
|
31
|
+
::LibUI.box_append(@libui, child.libui, Glimmer::LibUI.boolean_to_integer(child.stretchy))
|
32
32
|
children << child
|
33
33
|
end
|
34
34
|
|
@@ -27,30 +27,82 @@ module Glimmer
|
|
27
27
|
#
|
28
28
|
# Follows the Proxy Design Pattern
|
29
29
|
class ColorButtonProxy < ControlProxy
|
30
|
-
def color
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
30
|
+
def color(value = nil)
|
31
|
+
# TODO support hex color value
|
32
|
+
if value.nil?
|
33
|
+
@red ||= Fiddle::Pointer.malloc(8) # double
|
34
|
+
@green ||= Fiddle::Pointer.malloc(8) # double
|
35
|
+
@blue ||= Fiddle::Pointer.malloc(8) # double
|
36
|
+
@alpha ||= Fiddle::Pointer.malloc(8) # double
|
37
|
+
::LibUI.color_button_color(@libui, @red, @green, @blue, @alpha)
|
38
|
+
{
|
39
|
+
r: @red[0, 8].unpack1('d') * 255.0,
|
40
|
+
g: @green[0, 8].unpack1('d') * 255.0,
|
41
|
+
b: @blue[0, 8].unpack1('d') * 255.0,
|
42
|
+
a: @alpha[0, 8].unpack1('d')
|
43
|
+
}
|
44
|
+
else
|
45
|
+
current_color = color
|
46
|
+
value = Glimmer::LibUI.hex_to_rgb(value)
|
47
|
+
value[:r] ||= current_color[:r]
|
48
|
+
value[:g] ||= current_color[:g]
|
49
|
+
value[:b] ||= current_color[:b]
|
50
|
+
value[:a] ||= current_color[:a]
|
51
|
+
::LibUI.color_button_set_color(@libui, value[:r].to_f / 255.0, value[:g].to_f / 255.0, value[:b].to_f / 255.0, value[:a])
|
52
|
+
end
|
37
53
|
end
|
38
54
|
|
39
|
-
def red
|
40
|
-
|
55
|
+
def red(value = nil)
|
56
|
+
if value.nil?
|
57
|
+
color[:r]
|
58
|
+
else
|
59
|
+
self.color = {r: value}
|
60
|
+
end
|
41
61
|
end
|
62
|
+
alias red= red
|
63
|
+
alias set_red red
|
64
|
+
alias r red
|
65
|
+
alias r= red
|
66
|
+
alias set_r red
|
42
67
|
|
43
|
-
def green
|
44
|
-
|
68
|
+
def green(value = nil)
|
69
|
+
if value.nil?
|
70
|
+
color[:g]
|
71
|
+
else
|
72
|
+
self.color = {g: value}
|
73
|
+
end
|
45
74
|
end
|
75
|
+
alias green= green
|
76
|
+
alias set_green green
|
77
|
+
alias g green
|
78
|
+
alias g= green
|
79
|
+
alias set_g green
|
46
80
|
|
47
|
-
def blue
|
48
|
-
|
81
|
+
def blue(value = nil)
|
82
|
+
if value.nil?
|
83
|
+
color[:b]
|
84
|
+
else
|
85
|
+
self.color = {b: value}
|
86
|
+
end
|
49
87
|
end
|
88
|
+
alias blue= blue
|
89
|
+
alias set_blue blue
|
90
|
+
alias b blue
|
91
|
+
alias b= blue
|
92
|
+
alias set_b blue
|
50
93
|
|
51
|
-
def alpha
|
52
|
-
|
94
|
+
def alpha(value = nil)
|
95
|
+
if value.nil?
|
96
|
+
color[:a]
|
97
|
+
else
|
98
|
+
self.color = {a: value}
|
99
|
+
end
|
53
100
|
end
|
101
|
+
alias alpha= alpha
|
102
|
+
alias set_alpha alpha
|
103
|
+
alias a alpha
|
104
|
+
alias a= alpha
|
105
|
+
alias set_a alpha
|
54
106
|
|
55
107
|
def destroy
|
56
108
|
Fiddle.free @red unless @red.nil?
|
@@ -55,14 +55,6 @@ module Glimmer
|
|
55
55
|
control_proxies.find {|c| c.is_a?(Glimmer::LibUI::WindowProxy)}
|
56
56
|
end
|
57
57
|
|
58
|
-
def integer_to_boolean(int, allow_nil: true)
|
59
|
-
int.nil? ? (allow_nil ? nil : false) : int == 1
|
60
|
-
end
|
61
|
-
|
62
|
-
def boolean_to_integer(bool, allow_nil: true)
|
63
|
-
bool.nil? ? (allow_nil ? nil : 0) : (bool ? 1 : 0)
|
64
|
-
end
|
65
|
-
|
66
58
|
def menu_proxies
|
67
59
|
control_proxies.select {|c| c.keyword == 'menu' }
|
68
60
|
end
|
@@ -173,7 +165,7 @@ module Glimmer
|
|
173
165
|
handle_string_property(property, handle_boolean_property(property, value))
|
174
166
|
elsif ::LibUI.respond_to?("#{libui_api_keyword}_set_#{method_name.to_s.sub(/=$/, '')}") && !args.empty?
|
175
167
|
property = method_name.to_s.sub(/=$/, '')
|
176
|
-
args[0] =
|
168
|
+
args[0] = Glimmer::LibUI.boolean_to_integer(args.first) if BOOLEAN_PROPERTIES.include?(property) && (args.first.is_a?(TrueClass) || args.first.is_a?(FalseClass))
|
177
169
|
::LibUI.send("#{libui_api_keyword}_set_#{property}", @libui, *args)
|
178
170
|
elsif ::LibUI.respond_to?("#{libui_api_keyword}_#{method_name}") && !args.empty?
|
179
171
|
::LibUI.send("#{libui_api_keyword}_#{method_name}", @libui, *args)
|
@@ -183,7 +175,7 @@ module Glimmer
|
|
183
175
|
handle_string_property(property, handle_boolean_property(property, value))
|
184
176
|
elsif ::LibUI.respond_to?("control_set_#{method_name.to_s.sub(/=$/, '')}")
|
185
177
|
property = method_name.to_s.sub(/=$/, '')
|
186
|
-
args[0] =
|
178
|
+
args[0] = Glimmer::LibUI.boolean_to_integer(args.first) if BOOLEAN_PROPERTIES.include?(property) && (args.first.is_a?(TrueClass) || args.first.is_a?(FalseClass))
|
187
179
|
::LibUI.send("control_set_#{method_name.to_s.sub(/=$/, '')}", @libui, *args)
|
188
180
|
elsif ::LibUI.respond_to?("control_#{method_name}") && !args.empty?
|
189
181
|
::LibUI.send("control_#{method_name}", @libui, *args)
|
@@ -201,7 +193,7 @@ module Glimmer
|
|
201
193
|
value = @append_property_hash[property]
|
202
194
|
handle_string_property(property, handle_boolean_property(property, value))
|
203
195
|
else
|
204
|
-
value =
|
196
|
+
value = Glimmer::LibUI.boolean_to_integer(value) if BOOLEAN_PROPERTIES.include?(property) && (value.is_a?(TrueClass) || value.is_a?(FalseClass))
|
205
197
|
@append_property_hash[property] = value
|
206
198
|
end
|
207
199
|
end
|
@@ -274,7 +266,7 @@ module Glimmer
|
|
274
266
|
end
|
275
267
|
|
276
268
|
def handle_boolean_property(property, value)
|
277
|
-
BOOLEAN_PROPERTIES.include?(property) ?
|
269
|
+
BOOLEAN_PROPERTIES.include?(property) ? Glimmer::LibUI.integer_to_boolean(value) : value
|
278
270
|
end
|
279
271
|
|
280
272
|
def handle_string_property(property, value)
|
@@ -29,7 +29,7 @@ module Glimmer
|
|
29
29
|
def post_initialize_child(child)
|
30
30
|
child.label = '' if child.label.nil?
|
31
31
|
child.stretchy = true if child.stretchy.nil?
|
32
|
-
::LibUI.form_append(@libui, child.label, child.libui,
|
32
|
+
::LibUI.form_append(@libui, child.label, child.libui, Glimmer::LibUI.boolean_to_integer(child.stretchy))
|
33
33
|
children << child
|
34
34
|
end
|
35
35
|
|
@@ -35,7 +35,7 @@ module Glimmer
|
|
35
35
|
child.halign = 0 if child.halign.nil?
|
36
36
|
child.vexpand = false if child.vexpand.nil?
|
37
37
|
child.valign = 0 if child.valign.nil?
|
38
|
-
::LibUI.grid_append(@libui, child.libui, child.left, child.top, child.xspan, child.yspan,
|
38
|
+
::LibUI.grid_append(@libui, child.libui, child.left, child.top, child.xspan, child.yspan, Glimmer::LibUI.boolean_to_integer(child.hexpand), child.halign, Glimmer::LibUI.boolean_to_integer(child.vexpand), child.valign)
|
39
39
|
children << child
|
40
40
|
end
|
41
41
|
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# Copyright (c) 2021 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
require 'glimmer/libui/control_proxy'
|
23
|
+
|
24
|
+
module Glimmer
|
25
|
+
module LibUI
|
26
|
+
# Proxy for LibUI matrix objects
|
27
|
+
#
|
28
|
+
# Follows the Proxy Design Pattern
|
29
|
+
class MatrixProxy < ControlProxy
|
30
|
+
def libui_api_keyword
|
31
|
+
'draw_matrix'
|
32
|
+
end
|
33
|
+
|
34
|
+
def clone
|
35
|
+
MatrixProxy.new('matrix', nil, [@libui.M11, @libui.M12, @libui.M21, @libui.M22, @libui.M31, @libui.M32])
|
36
|
+
end
|
37
|
+
|
38
|
+
def dup
|
39
|
+
clone
|
40
|
+
end
|
41
|
+
|
42
|
+
def m11(value = nil)
|
43
|
+
if value.nil?
|
44
|
+
@libui.M11
|
45
|
+
else
|
46
|
+
@libui.M11 = value.to_f
|
47
|
+
end
|
48
|
+
end
|
49
|
+
alias m11= m11
|
50
|
+
alias set_m11 m11
|
51
|
+
|
52
|
+
def m12(value = nil)
|
53
|
+
if value.nil?
|
54
|
+
@libui.M12
|
55
|
+
else
|
56
|
+
@libui.M12 = value.to_f
|
57
|
+
end
|
58
|
+
end
|
59
|
+
alias m12= m12
|
60
|
+
alias set_m12 m12
|
61
|
+
|
62
|
+
def m21(value = nil)
|
63
|
+
if value.nil?
|
64
|
+
@libui.M21
|
65
|
+
else
|
66
|
+
@libui.M21 = value.to_f
|
67
|
+
end
|
68
|
+
end
|
69
|
+
alias m21= m21
|
70
|
+
alias set_m21 m21
|
71
|
+
|
72
|
+
def m22(value = nil)
|
73
|
+
if value.nil?
|
74
|
+
@libui.M22
|
75
|
+
else
|
76
|
+
@libui.M22 = value.to_f
|
77
|
+
end
|
78
|
+
end
|
79
|
+
alias m22= m22
|
80
|
+
alias set_m22 m22
|
81
|
+
|
82
|
+
def m31(value = nil)
|
83
|
+
if value.nil?
|
84
|
+
@libui.M31
|
85
|
+
else
|
86
|
+
@libui.M31 = value.to_f
|
87
|
+
end
|
88
|
+
end
|
89
|
+
alias m31= m31
|
90
|
+
alias set_m31 m31
|
91
|
+
|
92
|
+
def m32(value = nil)
|
93
|
+
if value.nil?
|
94
|
+
@libui.M32
|
95
|
+
else
|
96
|
+
@libui.M32 = value.to_f
|
97
|
+
end
|
98
|
+
end
|
99
|
+
alias m32= m32
|
100
|
+
alias set_m32 m32
|
101
|
+
|
102
|
+
def identity
|
103
|
+
set_identity
|
104
|
+
end
|
105
|
+
|
106
|
+
def rotate(x = 0, y = 0, degrees)
|
107
|
+
super(x, y, (Math::PI*2.0/360.0)*degrees)
|
108
|
+
end
|
109
|
+
|
110
|
+
def scale(x_center = 0, y_center = 0, x, y)
|
111
|
+
super
|
112
|
+
end
|
113
|
+
|
114
|
+
def skew(x = 0, y = 0, x_amount, y_amount)
|
115
|
+
super
|
116
|
+
end
|
117
|
+
|
118
|
+
def multiply(matrix)
|
119
|
+
super(matrix.respond_to?(:libui) ? matrix.libui : matrix)
|
120
|
+
end
|
121
|
+
|
122
|
+
def invertible
|
123
|
+
Glimmer::LibUI.integer_to_boolean(super, allow_nil: false)
|
124
|
+
end
|
125
|
+
alias invertible? invertible
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
def build_control
|
130
|
+
@libui = ::LibUI::FFI::DrawMatrix.malloc
|
131
|
+
if @args.empty?
|
132
|
+
set_identity
|
133
|
+
else
|
134
|
+
@libui.M11 = @args[0].to_f
|
135
|
+
@libui.M12 = @args[1].to_f
|
136
|
+
@libui.M21 = @args[2].to_f
|
137
|
+
@libui.M22 = @args[3].to_f
|
138
|
+
@libui.M31 = @args[4].to_f
|
139
|
+
@libui.M32 = @args[5].to_f
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
TransformProxy = MatrixProxy # alias
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Copyright (c) 2021 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
module Glimmer
|
23
|
+
module LibUI
|
24
|
+
# Parent controls and shapes who have children and add child post_initialize_child
|
25
|
+
module Parent
|
26
|
+
# Subclasses can override and must call super (passing add_child: false to cancel adding child to children)
|
27
|
+
def post_initialize_child(child, add_child: true)
|
28
|
+
children << child if add_child
|
29
|
+
end
|
30
|
+
|
31
|
+
def children
|
32
|
+
@children ||= []
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -20,6 +20,9 @@
|
|
20
20
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
21
|
|
22
22
|
require 'glimmer/libui/control_proxy'
|
23
|
+
require 'glimmer/libui/area_proxy'
|
24
|
+
require 'glimmer/libui/parent'
|
25
|
+
require 'glimmer/libui/transformable'
|
23
26
|
|
24
27
|
module Glimmer
|
25
28
|
module LibUI
|
@@ -27,6 +30,9 @@ module Glimmer
|
|
27
30
|
#
|
28
31
|
# Follows the Proxy Design Pattern
|
29
32
|
class PathProxy < ControlProxy
|
33
|
+
include Parent
|
34
|
+
prepend Transformable
|
35
|
+
|
30
36
|
# TODO support mode without parent proxy
|
31
37
|
def initialize(keyword, parent, args, &block)
|
32
38
|
@keyword = keyword
|
@@ -37,23 +43,14 @@ module Glimmer
|
|
37
43
|
post_add_content if @block.nil?
|
38
44
|
end
|
39
45
|
|
40
|
-
def post_initialize_child(child)
|
41
|
-
super
|
42
|
-
children << child
|
43
|
-
end
|
44
|
-
|
45
46
|
def post_add_content
|
46
47
|
super
|
47
|
-
if @parent_proxy.nil? &&
|
48
|
-
draw(
|
48
|
+
if @parent_proxy.nil? && AreaProxy.current_area_draw_params
|
49
|
+
draw(AreaProxy.current_area_draw_params)
|
49
50
|
destroy
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
53
|
-
def children
|
54
|
-
@children ||= []
|
55
|
-
end
|
56
|
-
|
57
54
|
def draw(area_draw_params)
|
58
55
|
build_control
|
59
56
|
children.dup.each {|child| child.draw(area_draw_params)}
|
@@ -128,16 +125,15 @@ module Glimmer
|
|
128
125
|
@draw_stroke_params
|
129
126
|
end
|
130
127
|
|
131
|
-
# returns area_draw_params if built inside on_draw listener (not needed if declared outside)
|
132
|
-
def area_draw_params
|
133
|
-
@args[0] if @parent_proxy.nil?
|
134
|
-
end
|
135
|
-
|
136
128
|
def destroy
|
137
|
-
@parent_proxy
|
129
|
+
@parent_proxy&.children&.delete(self)
|
138
130
|
ControlProxy.control_proxies.delete(self)
|
139
131
|
end
|
140
132
|
|
133
|
+
def redraw
|
134
|
+
@parent_proxy&.queue_redraw_all
|
135
|
+
end
|
136
|
+
|
141
137
|
private
|
142
138
|
|
143
139
|
def build_control
|
@@ -159,6 +155,7 @@ module Glimmer
|
|
159
155
|
else
|
160
156
|
draw_brush.Type = 0
|
161
157
|
end
|
158
|
+
draw_brush_args = draw_brush_args.merge(Glimmer::LibUI.hex_to_rgb(draw_brush_args[:color])) if draw_brush_args[:color]
|
162
159
|
draw_brush.R = (draw_brush_args[:r] || draw_brush_args[:red]).to_f / 255.0
|
163
160
|
draw_brush.G = (draw_brush_args[:g] || draw_brush_args[:green]).to_f / 255.0
|
164
161
|
draw_brush.B = (draw_brush_args[:b] || draw_brush_args[:blue]).to_f / 255.0
|
data/lib/glimmer/libui/shape.rb
CHANGED
@@ -19,6 +19,8 @@
|
|
19
19
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
20
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
21
|
|
22
|
+
require 'glimmer/libui/parent'
|
23
|
+
|
22
24
|
module Glimmer
|
23
25
|
module LibUI
|
24
26
|
# Represents LibUI lightweight shape objects nested under path (e.g. line, rectangle, arc, bezier)
|
@@ -61,6 +63,8 @@ module Glimmer
|
|
61
63
|
end
|
62
64
|
end
|
63
65
|
|
66
|
+
include Parent
|
67
|
+
|
64
68
|
attr_reader :parent, :args, :keyword, :block
|
65
69
|
|
66
70
|
def initialize(keyword, parent, args, &block)
|
@@ -77,20 +81,15 @@ module Glimmer
|
|
77
81
|
@parent&.post_initialize_child(self)
|
78
82
|
end
|
79
83
|
|
80
|
-
# Subclasses may override to perform post initialization work on an added child (normally must call super)
|
81
|
-
def post_initialize_child(child)
|
82
|
-
children << child
|
83
|
-
end
|
84
|
-
|
85
|
-
def children
|
86
|
-
@children ||= []
|
87
|
-
end
|
88
|
-
|
89
84
|
# Subclasses must override to perform draw work and call super afterwards to ensure calling destroy when semi-declarative in an on_draw method
|
90
85
|
def draw(area_draw_params)
|
91
86
|
destroy if area_proxy.nil?
|
92
87
|
end
|
93
88
|
|
89
|
+
def redraw
|
90
|
+
area_proxy&.queue_redraw_all
|
91
|
+
end
|
92
|
+
|
94
93
|
def destroy
|
95
94
|
@parent.children.delete(self)
|
96
95
|
end
|