lacci 0.3.0 → 0.4.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/lib/lacci/scarpe_cli.rb +0 -1
- data/lib/lacci/version.rb +1 -1
- data/lib/scarpe/niente/display_service.rb +5 -1
- data/lib/scarpe/niente/drawable.rb +2 -0
- data/lib/scarpe/niente/shoes_spec.rb +7 -1
- data/lib/scarpe/niente.rb +14 -2
- data/lib/shoes/app.rb +44 -50
- data/lib/shoes/constants.rb +23 -2
- data/lib/shoes/display_service.rb +43 -4
- data/lib/shoes/drawable.rb +309 -35
- data/lib/shoes/drawables/arc.rb +2 -24
- data/lib/shoes/drawables/arrow.rb +2 -22
- data/lib/shoes/drawables/border.rb +28 -0
- data/lib/shoes/drawables/button.rb +4 -20
- data/lib/shoes/drawables/check.rb +7 -3
- data/lib/shoes/drawables/document_root.rb +4 -4
- data/lib/shoes/drawables/edit_box.rb +6 -5
- data/lib/shoes/drawables/edit_line.rb +5 -4
- data/lib/shoes/drawables/flow.rb +3 -5
- data/lib/shoes/drawables/font_helper.rb +62 -0
- data/lib/shoes/drawables/image.rb +2 -2
- data/lib/shoes/drawables/line.rb +4 -7
- data/lib/shoes/drawables/link.rb +5 -8
- data/lib/shoes/drawables/list_box.rb +8 -5
- data/lib/shoes/drawables/oval.rb +48 -0
- data/lib/shoes/drawables/para.rb +106 -18
- data/lib/shoes/drawables/progress.rb +2 -1
- data/lib/shoes/drawables/radio.rb +5 -3
- data/lib/shoes/drawables/rect.rb +5 -4
- data/lib/shoes/drawables/shape.rb +2 -1
- data/lib/shoes/drawables/slot.rb +99 -8
- data/lib/shoes/drawables/stack.rb +6 -11
- data/lib/shoes/drawables/star.rb +8 -30
- data/lib/shoes/drawables/text_drawable.rb +93 -34
- data/lib/shoes/drawables/video.rb +3 -2
- data/lib/shoes/drawables/widget.rb +8 -3
- data/lib/shoes/drawables.rb +2 -1
- data/lib/shoes/errors.rb +13 -3
- data/lib/shoes/margin_helper.rb +79 -0
- data/lib/shoes.rb +4 -3
- metadata +11 -11
- data/lib/scarpe/niente/logger.rb +0 -29
- data/lib/shoes/drawables/span.rb +0 -27
- data/lib/shoes/spacing.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3bf9fa7d8c25eece259eb65e02ac680c3004762fa86951597ae1721010a8af52
|
4
|
+
data.tar.gz: b997f33fc1f63480f38144f89c54af16a3f99c7eafaf960b53770ea4894b51e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7eb784a865dfd9add9ade9861a62cfa2192e407d1371e49cdd23eb6205c55c36f67d6a31347775ee6b3d43c6e025ea1788e6c51dedf4251a562dcb62f2cda1e5
|
7
|
+
data.tar.gz: ea5b4aef895ee41ea78699bac827f8404ebbef97f0d7e8ed93b41382076c3188538e70aa32016b5ff90bd81b05feca8effc977f5452efe30744f25a7d3fe845f
|
data/lib/lacci/scarpe_cli.rb
CHANGED
@@ -28,7 +28,6 @@ module Scarpe
|
|
28
28
|
"Lacci" => [
|
29
29
|
env_or_default("SCARPE_DISPLAY_SERVICE", "(none)"),
|
30
30
|
env_or_default("SCARPE_LOG_CONFIG", "(default)#{Shoes::Log::DEFAULT_LOG_CONFIG.inspect}"),
|
31
|
-
env_or_default("SCARPE_APP_TEST", "(none)"),
|
32
31
|
],
|
33
32
|
"Ruby and Shell" => [
|
34
33
|
["RUBY_DESCRIPTION", RUBY_DESCRIPTION],
|
data/lib/lacci/version.rb
CHANGED
@@ -29,7 +29,7 @@ module Niente
|
|
29
29
|
# @param properties [Hash] a JSON-serialisable Hash with the drawable's Shoes styles
|
30
30
|
# @param is_widget [Boolean] whether the class is a user-defined Shoes::Widget subclass
|
31
31
|
# @return [Webview::Drawable] the newly-created Webview drawable
|
32
|
-
def create_display_drawable_for(drawable_class_name, drawable_id, properties, is_widget:)
|
32
|
+
def create_display_drawable_for(drawable_class_name, drawable_id, properties, parent_id:, is_widget:)
|
33
33
|
existing = query_display_drawable_for(drawable_id, nil_ok: true)
|
34
34
|
if existing
|
35
35
|
@log.warn("There is already a display drawable for #{drawable_id.inspect}! Returning #{existing.class.name}.")
|
@@ -47,6 +47,10 @@ module Niente
|
|
47
47
|
display_drawable.shoes_type = drawable_class_name
|
48
48
|
set_drawable_pairing(drawable_id, display_drawable)
|
49
49
|
|
50
|
+
# Nil parent is okay for DocumentRoot and TextDrawables, so we have to specify it.
|
51
|
+
parent = DisplayService.instance.query_display_drawable_for(parent_id, nil_ok: true)
|
52
|
+
display_drawable.set_parent(parent)
|
53
|
+
|
50
54
|
return display_drawable
|
51
55
|
end
|
52
56
|
|
@@ -12,6 +12,7 @@ module Niente
|
|
12
12
|
|
13
13
|
super(linkable_id: @shoes_linkable_id)
|
14
14
|
|
15
|
+
# This should only be used for reparenting after a drawable was initially created.
|
15
16
|
bind_shoes_event(event_name: "parent", target: shoes_linkable_id) do |new_parent_id|
|
16
17
|
display_parent = DisplayService.instance.query_display_drawable_for(new_parent_id)
|
17
18
|
if @parent != display_parent
|
@@ -28,6 +29,7 @@ module Niente
|
|
28
29
|
end
|
29
30
|
|
30
31
|
bind_shoes_event(event_name: "destroy", target: shoes_linkable_id) do
|
32
|
+
set_parent(nil)
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
@@ -30,7 +30,6 @@ class Niente::Test
|
|
30
30
|
Object.const_set(Scarpe::Components::StringHelpers.camelize(class_name), test_class)
|
31
31
|
test_name = "test_" + test_name unless test_name.start_with?("test_")
|
32
32
|
test_class.define_method(test_name) do
|
33
|
-
STDERR.puts "Started running #{class_name.inspect}::#{test_name.inspect}"
|
34
33
|
eval(code)
|
35
34
|
end
|
36
35
|
end
|
@@ -50,6 +49,13 @@ class Niente::ShoesSpecTest < Minitest::Test
|
|
50
49
|
Niente::ShoesSpecProxy.new(drawables[0])
|
51
50
|
end
|
52
51
|
end
|
52
|
+
|
53
|
+
def drawable(*specs)
|
54
|
+
drawables = Shoes::App.instance.find_drawables_by(*specs)
|
55
|
+
raise Shoes::Errors::MultipleDrawablesFoundError, "Found more than one #{finder_name} matching #{args.inspect}!" if drawables.size > 1
|
56
|
+
raise Shoes::Errors::NoDrawablesFoundError, "Found no #{finder_name} matching #{args.inspect}!" if drawables.empty?
|
57
|
+
Niente::ShoesSpecProxy.new(drawables[0])
|
58
|
+
end
|
53
59
|
end
|
54
60
|
|
55
61
|
class Niente::ShoesSpecProxy
|
data/lib/scarpe/niente.rb
CHANGED
@@ -6,8 +6,16 @@
|
|
6
6
|
# how a real display service should act.
|
7
7
|
module Niente; end
|
8
8
|
|
9
|
-
|
10
|
-
Shoes::Log.instance =
|
9
|
+
require "scarpe/components/print_logger"
|
10
|
+
Shoes::Log.instance = Scarpe::Components::PrintLogImpl.new
|
11
|
+
if ENV["NIENTE_LOG_LEVEL"]
|
12
|
+
pl = Scarpe::Components::PrintLogImpl::PrintLogger
|
13
|
+
level = ENV["NIENTE_LOG_LEVEL"].strip.downcase.to_sym
|
14
|
+
unless pl::LEVELS.key?(level)
|
15
|
+
raise "Unrecognized Niente log level: #{level.inspect}!"
|
16
|
+
end
|
17
|
+
pl.min_level = pl::LEVELS[level]
|
18
|
+
end
|
11
19
|
|
12
20
|
require_relative "niente/drawable"
|
13
21
|
require_relative "niente/app"
|
@@ -16,5 +24,9 @@ require_relative "niente/display_service"
|
|
16
24
|
require_relative "niente/shoes_spec"
|
17
25
|
Shoes::Spec.instance = Niente::Test
|
18
26
|
|
27
|
+
require "scarpe/components/segmented_file_loader"
|
28
|
+
loader = Scarpe::Components::SegmentedFileLoader.new
|
29
|
+
Shoes.add_file_loader loader
|
30
|
+
|
19
31
|
Shoes::DisplayService.set_display_service_class(Niente::DisplayService)
|
20
32
|
|
data/lib/shoes/app.rb
CHANGED
@@ -8,17 +8,29 @@ class Shoes
|
|
8
8
|
attr_accessor :instance
|
9
9
|
end
|
10
10
|
|
11
|
+
# The Shoes root of the drawable tree
|
11
12
|
attr_reader :document_root
|
12
13
|
|
13
|
-
|
14
|
+
# The application directory for this app. Often this will be the directory
|
15
|
+
# containing the launched application file.
|
16
|
+
attr_reader :dir
|
17
|
+
|
18
|
+
shoes_styles :title, :width, :height, :resizable, :features
|
19
|
+
|
20
|
+
# This is defined to avoid the linkable-id check in the Shoes-style method_missing def'n
|
21
|
+
def features
|
22
|
+
@features
|
23
|
+
end
|
14
24
|
|
15
25
|
CUSTOM_EVENT_LOOP_TYPES = ["displaylib", "return", "wait"]
|
16
26
|
|
27
|
+
init_args
|
17
28
|
def initialize(
|
18
29
|
title: "Shoes!",
|
19
30
|
width: 480,
|
20
31
|
height: 420,
|
21
32
|
resizable: true,
|
33
|
+
features: [],
|
22
34
|
&app_code_body
|
23
35
|
)
|
24
36
|
log_init("Shoes::App")
|
@@ -30,36 +42,35 @@ class Shoes
|
|
30
42
|
Shoes::App.instance = self
|
31
43
|
end
|
32
44
|
|
45
|
+
# We cd to the app's containing dir when running the app
|
46
|
+
@dir = Dir.pwd
|
47
|
+
|
33
48
|
@do_shutdown = false
|
34
49
|
@event_loop_type = "displaylib" # the default
|
35
50
|
|
36
|
-
|
51
|
+
@features = features
|
52
|
+
|
53
|
+
unknown_ext = features - Shoes::FEATURES - Shoes::EXTENSIONS
|
54
|
+
unsupported_features = unknown_ext & Shoes::KNOWN_FEATURES
|
55
|
+
unless unsupported_features.empty?
|
56
|
+
@log.error("Shoes app requires feature(s) not supported by this display service: #{unsupported_features.inspect}!")
|
57
|
+
raise Shoes::Errors::UnsupportedFeatureError, "Shoes app needs features: #{unsupported_features.inspect}"
|
58
|
+
end
|
59
|
+
unless unknown_ext.empty?
|
60
|
+
@log.warn("Shoes app requested unknown features #{unknown_ext.inspect}! Known: #{(Shoes::FEATURES + Shoes::EXTENSIONS).inspect}")
|
61
|
+
end
|
62
|
+
|
63
|
+
@slots = []
|
37
64
|
|
38
|
-
|
39
|
-
# plus potentially other current state that changes from drawable
|
40
|
-
# to drawable and slot to slot.
|
41
|
-
@draw_context = {
|
42
|
-
"fill" => "",
|
43
|
-
"stroke" => "",
|
44
|
-
"rotate" => 0,
|
45
|
-
}
|
65
|
+
super
|
46
66
|
|
47
67
|
# This creates the DocumentRoot, including its corresponding display drawable
|
48
68
|
@document_root = Shoes::DocumentRoot.new
|
49
69
|
|
50
|
-
@slots = []
|
51
|
-
|
52
70
|
# Now create the App display drawable
|
53
71
|
create_display_drawable
|
54
72
|
|
55
|
-
# Set up testing
|
56
|
-
if ENV["SCARPE_APP_TEST"]
|
57
|
-
test_code = File.read ENV["SCARPE_APP_TEST"]
|
58
|
-
if test_code != ""
|
59
|
-
@test_obj = Object.new
|
60
|
-
@test_obj.instance_eval test_code
|
61
|
-
end
|
62
|
-
end
|
73
|
+
# Set up testing *after* Display Service basic objects exist
|
63
74
|
|
64
75
|
if ENV["SHOES_SPEC_TEST"]
|
65
76
|
test_code = File.read ENV["SHOES_SPEC_TEST"]
|
@@ -133,22 +144,17 @@ class Shoes
|
|
133
144
|
return super unless klass
|
134
145
|
|
135
146
|
::Shoes::App.define_method(name) do |*args, **kwargs, &block|
|
136
|
-
|
137
|
-
drawable_instance = klass.new(*args, **kwargs, &block)
|
138
|
-
|
139
|
-
unless klass.ancestors.include?(::Shoes::TextDrawable)
|
140
|
-
# Create this drawable in the current app slot
|
141
|
-
drawable_instance.set_parent ::Shoes::App.instance.current_slot
|
142
|
-
end
|
143
|
-
|
144
|
-
drawable_instance
|
147
|
+
klass.new(*args, **kwargs, &block)
|
145
148
|
end
|
146
149
|
|
147
150
|
send(name, *args, **kwargs, &block)
|
148
151
|
end
|
149
152
|
|
153
|
+
# Get the current draw context for the current slot
|
154
|
+
#
|
155
|
+
# @return [Hash] a hash of Shoes styles for the current draw context
|
150
156
|
def current_draw_context
|
151
|
-
|
157
|
+
current_slot&.current_draw_context
|
152
158
|
end
|
153
159
|
|
154
160
|
# This usually doesn't return. The display service may take control
|
@@ -190,7 +196,7 @@ class Shoes
|
|
190
196
|
def all_drawables
|
191
197
|
out = []
|
192
198
|
|
193
|
-
to_add = @document_root.children
|
199
|
+
to_add = [@document_root, @document_root.children]
|
194
200
|
until to_add.empty?
|
195
201
|
out.concat(to_add)
|
196
202
|
to_add = to_add.flat_map { |w| w.respond_to?(:children) ? w.children : [] }.compact
|
@@ -256,30 +262,21 @@ end
|
|
256
262
|
|
257
263
|
# These methods will need to be defined on Slots too, but probably need a rework in general.
|
258
264
|
class Shoes::App < Shoes::Drawable
|
265
|
+
# This is going to go away. See issue #496
|
259
266
|
def background(...)
|
260
267
|
current_slot.background(...)
|
261
268
|
end
|
262
269
|
|
270
|
+
# This is going to go away. See issue #498
|
263
271
|
def border(...)
|
264
272
|
current_slot.border(...)
|
265
273
|
end
|
266
274
|
|
267
|
-
# Draw
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
def nofill
|
274
|
-
@draw_context["fill"] = ""
|
275
|
-
end
|
276
|
-
|
277
|
-
def stroke(color)
|
278
|
-
@draw_context["stroke"] = color
|
279
|
-
end
|
280
|
-
|
281
|
-
def nostroke
|
282
|
-
@draw_context["stroke"] = ""
|
275
|
+
# Draw Context methods -- forward to the current slot
|
276
|
+
[:fill, :nofill, :stroke, :strokewidth, :nostroke, :rotate].each do |dc_method|
|
277
|
+
define_method(dc_method) do |*args|
|
278
|
+
current_slot.send(dc_method, *args)
|
279
|
+
end
|
283
280
|
end
|
284
281
|
|
285
282
|
# Shape DSL methods
|
@@ -300,9 +297,6 @@ class Shoes::App < Shoes::Drawable
|
|
300
297
|
end
|
301
298
|
end
|
302
299
|
|
303
|
-
def rotate(angle)
|
304
|
-
@draw_context["rotate"] = angle
|
305
|
-
end
|
306
300
|
# Not implemented yet: curve_to, arc_to
|
307
301
|
|
308
302
|
alias_method :info, :puts
|
data/lib/shoes/constants.rb
CHANGED
@@ -13,10 +13,10 @@ class Shoes
|
|
13
13
|
[ENV["LOCALAPPDATA"], "Shoes"],
|
14
14
|
[ENV["APPDATA"], "Shoes"],
|
15
15
|
[ENV["HOME"], ".shoes"],
|
16
|
-
[Dir.tmpdir, "shoes"],
|
17
16
|
]
|
18
17
|
|
19
18
|
top, file = homes.detect { |home_top, _| home_top && File.exist?(home_top) }
|
19
|
+
return nil if top.nil?
|
20
20
|
File.join(top, file)
|
21
21
|
end
|
22
22
|
|
@@ -32,8 +32,29 @@ class Shoes
|
|
32
32
|
HALF_PI = 1.57079632679489661923
|
33
33
|
PI = 3.14159265358979323846
|
34
34
|
|
35
|
-
#
|
35
|
+
# These should be set up by the Display Service when it loads. They are intentionally
|
36
|
+
# *not* frozen so that the Display Service can add to them (and then optionally
|
37
|
+
# freeze them.)
|
38
|
+
|
39
|
+
# Fonts currently loaded and available
|
36
40
|
FONTS = []
|
41
|
+
|
42
|
+
# Standard features available in this display service - see KNOWN_FEATURES.
|
43
|
+
# These may or may not require the Shoes.app requesting them per-app.
|
44
|
+
FEATURES = []
|
45
|
+
|
46
|
+
# Nonstandard extensions, e.g. Scarpe extensions, supported by this display lib.
|
47
|
+
# An application may have to request the extensions for them to be available so
|
48
|
+
# that a casual reader can see Shoes.app(features: :scarpe) and realize why
|
49
|
+
# there are nonstandard styles or drawables.
|
50
|
+
EXTENSIONS = []
|
51
|
+
|
52
|
+
# These are all known features supported by this version of Lacci.
|
53
|
+
# Features on this list are allowed to be in FEATURES. Anything else
|
54
|
+
# goes in EXTENSIONS and is nonstandard.
|
55
|
+
KNOWN_FEATURES = [
|
56
|
+
:html, # Supports .to_html on display objects, HTML classes on drawables, etc.
|
57
|
+
].freeze
|
37
58
|
end
|
38
59
|
|
39
60
|
# Access and assign the release constants
|
@@ -32,7 +32,14 @@ class Shoes
|
|
32
32
|
# This is in the eigenclass/metaclass, *not* instances of DisplayService
|
33
33
|
include Shoes::Log
|
34
34
|
|
35
|
+
# Send a Shoes event to all subscribers.
|
35
36
|
# An event_target may be nil, to indicate there is no target.
|
37
|
+
#
|
38
|
+
# @param event_name [String] the name of the event
|
39
|
+
# @param event_target [String] the specific target, if any
|
40
|
+
# @param args [Array] arguments to pass to the subscribing block
|
41
|
+
# @param args [Array] keyword arguments to pass to the subscribing block
|
42
|
+
# @return [void]
|
36
43
|
def dispatch_event(event_name, event_target, *args, **kwargs)
|
37
44
|
@@display_event_handlers ||= {}
|
38
45
|
|
@@ -69,10 +76,20 @@ class Shoes
|
|
69
76
|
kwargs[:event_name] = event_name
|
70
77
|
kwargs[:event_target] = event_target if event_target
|
71
78
|
handlers.each { |h| h[:handler].call(*args, **kwargs) }
|
79
|
+
nil
|
72
80
|
end
|
73
81
|
|
74
|
-
#
|
75
|
-
#
|
82
|
+
# Subscribe to the given event name and target.
|
83
|
+
# It's permitted to subscribe to event_name :any for all event names,
|
84
|
+
# and event_target :any for all targets. An event_target of nil means
|
85
|
+
# "no target", and only matches events dispatched with a nil target.
|
86
|
+
# The subscription will return an unsubscribe ID, which can be used
|
87
|
+
# later to unsubscribe from the notification.
|
88
|
+
#
|
89
|
+
# @param event_name [String,Symbol] the event name to subscribe to, or :any for all event names
|
90
|
+
# @param event_target [String,Symbol,NilClass] the event target to subscribe to, or :any for all targets - nil is a valid target
|
91
|
+
# @block the block to call when the event occurs - it will receive arguments from the event-dispatch call
|
92
|
+
# @return [Integer] an unsubscription ID which can be used later to cancel the subscription
|
76
93
|
def subscribe_to_event(event_name, event_target, &handler)
|
77
94
|
@@display_event_handlers ||= {}
|
78
95
|
@@display_event_unsub_id ||= 0
|
@@ -96,6 +113,10 @@ class Shoes
|
|
96
113
|
id
|
97
114
|
end
|
98
115
|
|
116
|
+
# Unsubscribe from any event subscriptions matching the unsub ID.
|
117
|
+
#
|
118
|
+
# @param unsub_id [Integer] the unsub ID returned when subscribing
|
119
|
+
# @return [void]
|
99
120
|
def unsub_from_events(unsub_id)
|
100
121
|
raise "Must provide an unsubscribe ID!" if unsub_id.nil?
|
101
122
|
|
@@ -106,17 +127,32 @@ class Shoes
|
|
106
127
|
end
|
107
128
|
end
|
108
129
|
|
130
|
+
# Reset the display service, for instance between unit tests.
|
131
|
+
# This destroys all existing subscriptions.
|
132
|
+
#
|
133
|
+
# @return [void]
|
109
134
|
def full_reset!
|
110
135
|
@@display_event_handlers = {}
|
111
136
|
@json_debug_serialize = nil
|
112
137
|
end
|
113
138
|
|
139
|
+
# Set the Display Service class which will handle display service functions
|
140
|
+
# for this process. This can only be set once. The display service can be
|
141
|
+
# a subclass of Shoes::DisplayService, but isn't required to be.
|
142
|
+
#
|
143
|
+
# Shoes will create an instance of this class with no arguments passed to
|
144
|
+
# initialize, and use it as the display service for the lifetime of the
|
145
|
+
# process.
|
146
|
+
#
|
147
|
+
# @param klass [Class] the class for the display service
|
114
148
|
def set_display_service_class(klass)
|
115
149
|
raise "Can only set a single display service class!" if @display_service_klass
|
116
150
|
|
117
151
|
@display_service_klass = klass
|
118
152
|
end
|
119
153
|
|
154
|
+
# Get the current display service instance. This requires a display service
|
155
|
+
# class having been set first. @see set_display_service_class
|
120
156
|
def display_service
|
121
157
|
return @service if @service
|
122
158
|
|
@@ -126,9 +162,13 @@ class Shoes
|
|
126
162
|
end
|
127
163
|
end
|
128
164
|
|
165
|
+
def initialize
|
166
|
+
@display_drawable_for = {}
|
167
|
+
end
|
168
|
+
|
129
169
|
# These methods are an interface to DisplayService objects.
|
130
170
|
|
131
|
-
def create_display_drawable_for(drawable_class_name, drawable_id, properties, is_widget:)
|
171
|
+
def create_display_drawable_for(drawable_class_name, drawable_id, properties, parent_id:, is_widget:)
|
132
172
|
raise "Override in DisplayService implementation!"
|
133
173
|
end
|
134
174
|
|
@@ -174,7 +214,6 @@ class Shoes
|
|
174
214
|
def initialize(linkable_id: object_id)
|
175
215
|
@linkable_id = linkable_id
|
176
216
|
@subscriptions = {}
|
177
|
-
@display_drawable_for ||= {}
|
178
217
|
end
|
179
218
|
|
180
219
|
def send_self_event(*args, event_name:, **kwargs)
|