scarpe 0.2.1 → 0.2.2
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/.rubocop.yml +4 -0
- data/.yardopts +11 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +112 -0
- data/README.md +31 -24
- data/Rakefile +13 -1
- data/docs/yard/catscradle.md +44 -0
- data/docs/yard/template/default/fulldoc/html/setup.rb +13 -0
- data/docs/yard/template/default/layout/html/setup.rb +9 -0
- data/examples/background_with_image.rb +16 -0
- data/examples/bloopsaphone/working/bronx_army_knife.rb +66 -0
- data/examples/bloopsaphone/working/morning_serenity.rb +21 -0
- data/examples/bloopsaphone/working/simpsons_theme_song_by_why.rb +6 -4
- data/examples/button_go_away.rb +1 -1
- data/examples/check.rb +18 -0
- data/examples/clear_and_append.rb +24 -0
- data/examples/download_and_show_image.rb +28 -0
- data/examples/edit_box.rb +3 -5
- data/examples/fonts.rb +2 -2
- data/examples/get_headers.rb +10 -0
- data/examples/highlander.rb +2 -0
- data/examples/link.rb +2 -2
- data/examples/local_fonts.rb +4 -0
- data/examples/local_images.rb +4 -0
- data/examples/motion_events.rb +20 -0
- data/examples/parse_xl_funnies.rb +58 -0
- data/examples/radio/radio.rb +16 -0
- data/examples/radio/radio_groups.rb +18 -0
- data/examples/radio/radio_same_slot.rb +6 -0
- data/examples/ruby_racer.rb +13 -15
- data/examples/selfitude.rb +18 -0
- data/examples/shapes/shapes_fill.rb +4 -3
- data/examples/shoes_school.rb +2 -4
- data/examples/show_hide.rb +6 -0
- data/examples/skip_ci/change_my_audio_source.rb +21 -0
- data/examples/skip_ci/guitar_fretboard.rb +137 -0
- data/examples/video.rb +10 -0
- data/exe/scarpe +42 -66
- data/fonts/Pacifico.ttf +0 -0
- data/lacci/Gemfile +22 -0
- data/lacci/Gemfile.lock +72 -0
- data/lacci/Rakefile +12 -0
- data/lacci/lacci.gemspec +37 -0
- data/lacci/lib/lacci/scarpe_cli.rb +70 -0
- data/lacci/lib/lacci/scarpe_core.rb +21 -0
- data/lacci/lib/lacci/version.rb +13 -0
- data/lacci/lib/shoes/app.rb +264 -0
- data/{lib/scarpe → lacci/lib/shoes}/background.rb +1 -1
- data/{lib/scarpe → lacci/lib/shoes}/border.rb +1 -1
- data/{lib/scarpe → lacci/lib/shoes}/colors.rb +1 -1
- data/lacci/lib/shoes/constants.rb +29 -0
- data/{lib/scarpe → lacci/lib/shoes}/display_service.rb +40 -45
- data/lacci/lib/shoes/download.rb +123 -0
- data/lacci/lib/shoes/log.rb +71 -0
- data/lacci/lib/shoes/spacing.rb +9 -0
- data/{lib/scarpe → lacci/lib/shoes}/widget.rb +63 -43
- data/{lib/scarpe → lacci/lib/shoes/widgets}/alert.rb +3 -3
- data/{lib/scarpe → lacci/lib/shoes/widgets}/arc.rb +7 -5
- data/{lib/scarpe → lacci/lib/shoes/widgets}/button.rb +3 -3
- data/lacci/lib/shoes/widgets/check.rb +28 -0
- data/lacci/lib/shoes/widgets/document_root.rb +20 -0
- data/{lib/scarpe → lacci/lib/shoes/widgets}/edit_box.rb +10 -5
- data/{lib/scarpe → lacci/lib/shoes/widgets}/edit_line.rb +2 -2
- data/lacci/lib/shoes/widgets/flow.rb +22 -0
- data/lacci/lib/shoes/widgets/font.rb +14 -0
- data/{lib/scarpe → lacci/lib/shoes/widgets}/image.rb +3 -7
- data/lacci/lib/shoes/widgets/line.rb +18 -0
- data/{lib/scarpe → lacci/lib/shoes/widgets}/link.rb +2 -2
- data/{lib/scarpe → lacci/lib/shoes/widgets}/list_box.rb +2 -2
- data/{lib/scarpe → lacci/lib/shoes/widgets}/para.rb +4 -26
- data/lacci/lib/shoes/widgets/radio.rb +35 -0
- data/lacci/lib/shoes/widgets/shape.rb +37 -0
- data/lacci/lib/shoes/widgets/slot.rb +75 -0
- data/{lib/scarpe → lacci/lib/shoes/widgets}/span.rb +2 -2
- data/lacci/lib/shoes/widgets/stack.rb +24 -0
- data/{lib/scarpe → lacci/lib/shoes/widgets}/star.rb +6 -9
- data/lacci/lib/shoes/widgets/subscription_item.rb +60 -0
- data/lacci/lib/shoes/widgets/text_widget.rb +51 -0
- data/lacci/lib/shoes/widgets/video.rb +15 -0
- data/lacci/lib/shoes/widgets.rb +29 -0
- data/lacci/lib/shoes.rb +127 -0
- data/lacci/test/test_colors.rb +39 -0
- data/lacci/test/test_helper.rb +9 -0
- data/lacci/test/test_lacci.rb +9 -0
- data/lib/scarpe/cats_cradle.rb +249 -0
- data/lib/scarpe/evented_assertions.rb +88 -0
- data/lib/scarpe/version.rb +1 -1
- data/lib/scarpe/wv/alert.rb +3 -2
- data/lib/scarpe/wv/app.rb +30 -8
- data/lib/scarpe/wv/arc.rb +5 -6
- data/lib/scarpe/wv/background.rb +10 -1
- data/lib/scarpe/wv/border.rb +5 -3
- data/lib/scarpe/wv/button.rb +11 -9
- data/lib/scarpe/wv/check.rb +29 -0
- data/lib/scarpe/wv/control_interface.rb +14 -20
- data/lib/scarpe/wv/control_interface_test.rb +13 -28
- data/lib/scarpe/wv/document_root.rb +3 -45
- data/lib/scarpe/wv/edit_box.rb +5 -7
- data/lib/scarpe/wv/edit_line.rb +2 -2
- data/lib/scarpe/wv/flow.rb +10 -20
- data/lib/scarpe/wv/font.rb +36 -0
- data/lib/scarpe/wv/html.rb +3 -2
- data/lib/scarpe/wv/image.rb +7 -2
- data/lib/scarpe/wv/line.rb +4 -7
- data/lib/scarpe/wv/link.rb +1 -0
- data/lib/scarpe/wv/list_box.rb +3 -3
- data/lib/scarpe/wv/para.rb +16 -14
- data/lib/scarpe/wv/radio.rb +34 -0
- data/lib/scarpe/wv/shape.rb +44 -8
- data/lib/scarpe/wv/slot.rb +81 -0
- data/lib/scarpe/wv/spacing.rb +1 -1
- data/lib/scarpe/wv/span.rb +10 -8
- data/lib/scarpe/wv/stack.rb +10 -30
- data/lib/scarpe/wv/star.rb +11 -12
- data/lib/scarpe/wv/subscription_item.rb +50 -0
- data/lib/scarpe/wv/video.rb +34 -0
- data/lib/scarpe/wv/web_wrangler.rb +238 -58
- data/lib/scarpe/wv/webview_local_display.rb +27 -5
- data/lib/scarpe/wv/webview_relay_display.rb +18 -119
- data/lib/scarpe/wv/webview_relay_util.rb +143 -0
- data/lib/scarpe/wv/widget.rb +80 -11
- data/lib/scarpe/wv/wv_display_worker.rb +17 -4
- data/lib/scarpe/wv.rb +33 -4
- data/lib/scarpe/wv_local.rb +1 -1
- data/lib/scarpe/wv_relay.rb +1 -1
- data/lib/scarpe.rb +3 -32
- data/scarpe-components/.gitignore +1 -0
- data/scarpe-components/Gemfile +22 -0
- data/scarpe-components/README.md +35 -0
- data/scarpe-components/Rakefile +12 -0
- data/scarpe-components/lib/scarpe/components/base64.rb +29 -0
- data/scarpe-components/lib/scarpe/components/file_helpers.rb +65 -0
- data/scarpe-components/lib/scarpe/components/modular_logger.rb +113 -0
- data/scarpe-components/lib/scarpe/components/print_logger.rb +43 -0
- data/{lib/scarpe → scarpe-components/lib/scarpe/components}/promises.rb +102 -35
- data/scarpe-components/lib/scarpe/components/segmented_file_loader.rb +170 -0
- data/scarpe-components/lib/scarpe/components/unit_test_helpers.rb +217 -0
- data/scarpe-components/lib/scarpe/components/version.rb +7 -0
- data/scarpe-components/scarpe-components.gemspec +38 -0
- data/scarpe-components/test/test_components.rb +9 -0
- data/scarpe-components/test/test_helper.rb +23 -0
- data/scarpe-components/test/test_promises.rb +260 -0
- data/scarpe-components/test/test_segmented_app_files.rb +182 -0
- data/{lib/scarpe → spikes}/glibui/widget.rb +2 -2
- data/{lib/scarpe → spikes}/glibui.rb +1 -1
- data/templates/basic_class_template.erb +1 -1
- data/templates/class_template_with_event_bind.erb +1 -1
- data/templates/class_template_with_shapes.erb +1 -1
- data/templates/webview_template.erb +0 -3
- metadata +151 -118
- data/examples/fill.rb +0 -25
- data/examples/legacy/not_checked/shoes-contrib/basic/class-book.yaml +0 -387
- data/examples/legacy/not_checked/shoes-contrib/good/good-clock.rb +0 -51
- data/examples/legacy/not_checked/shoes-contrib/good/good-follow.rb +0 -26
- data/examples/legacy/not_checked/shoes-contrib/good/good-reminder.rb +0 -174
- data/examples/legacy/not_checked/shoes-contrib/good/good-vjot.rb +0 -56
- data/examples/legacy/not_checked/shoes-contrib/simple/simple-timer.rb +0 -13
- data/examples/legacy/not_checked/shoes-dep-samples/good-clock.rb +0 -51
- data/examples/legacy/not_checked/shoes-dep-samples/good-follow.rb +0 -26
- data/examples/legacy/not_checked/shoes-dep-samples/good-reminder.rb +0 -174
- data/examples/legacy/not_checked/shoes-dep-samples/good-vjot.rb +0 -56
- data/examples/legacy/not_checked/shoes-dep-samples/simple-accordion.rb +0 -75
- data/examples/legacy/not_checked/shoes-dep-samples/simple-anim-shapes.rb +0 -17
- data/examples/legacy/not_checked/shoes-dep-samples/simple-anim-text.rb +0 -13
- data/examples/legacy/not_checked/shoes-dep-samples/simple-arc.rb +0 -23
- data/examples/legacy/not_checked/shoes-dep-samples/simple-bounce.rb +0 -24
- data/examples/legacy/not_checked/shoes-dep-samples/simple-calc.rb +0 -70
- data/examples/legacy/not_checked/shoes-dep-samples/simple-chipmunk.rb +0 -26
- data/examples/legacy/not_checked/shoes-dep-samples/simple-control-sizes.rb +0 -24
- data/examples/legacy/not_checked/shoes-dep-samples/simple-curve.rb +0 -26
- data/examples/legacy/not_checked/shoes-dep-samples/simple-dialogs.rb +0 -29
- data/examples/legacy/not_checked/shoes-dep-samples/simple-draw.rb +0 -13
- data/examples/legacy/not_checked/shoes-dep-samples/simple-editor.rb +0 -28
- data/examples/legacy/not_checked/shoes-dep-samples/simple-form.rb +0 -28
- data/examples/legacy/not_checked/shoes-dep-samples/simple-form.shy +0 -0
- data/examples/legacy/not_checked/shoes-dep-samples/simple-mask.rb +0 -21
- data/examples/legacy/not_checked/shoes-dep-samples/simple-menu.rb +0 -31
- data/examples/legacy/not_checked/shoes-dep-samples/simple-menu1.rb +0 -35
- data/examples/legacy/not_checked/shoes-dep-samples/simple-rubygems.rb +0 -29
- data/examples/legacy/not_checked/shoes-dep-samples/simple-slide.rb +0 -45
- data/examples/legacy/not_checked/shoes-dep-samples/simple-sphere.rb +0 -28
- data/examples/legacy/not_checked/shoes-dep-samples/simple-sqlite3.rb +0 -13
- data/examples/legacy/not_checked/shoes-dep-samples/simple-timer.rb +0 -13
- data/examples/legacy/not_checked/shoes-dep-samples/simple-video.rb +0 -13
- data/examples/legacy/not_checked/simple/anim-text.rb +0 -13
- data/examples/legacy/not_checked/simple/arc.rb +0 -23
- data/examples/legacy/not_checked/simple/bounce.rb +0 -24
- data/examples/legacy/not_checked/simple/chipmunk.rb +0 -26
- data/examples/legacy/not_checked/simple/curve.rb +0 -26
- data/examples/legacy/not_checked/simple/dialogs.rb +0 -29
- data/examples/legacy/not_checked/simple/downloader.rb +0 -40
- data/examples/legacy/not_checked/simple/draw.rb +0 -13
- data/examples/legacy/not_checked/simple/mask.rb +0 -21
- data/examples/legacy/not_checked/simple/slide.rb +0 -45
- data/examples/legacy/not_checked/simple/sphere.rb +0 -28
- data/lib/constants.rb +0 -5
- data/lib/scarpe/app.rb +0 -78
- data/lib/scarpe/document_root.rb +0 -20
- data/lib/scarpe/fill.rb +0 -23
- data/lib/scarpe/flow.rb +0 -19
- data/lib/scarpe/line.rb +0 -25
- data/lib/scarpe/logger.rb +0 -155
- data/lib/scarpe/shape.rb +0 -19
- data/lib/scarpe/spacing.rb +0 -9
- data/lib/scarpe/stack.rb +0 -70
- data/lib/scarpe/text_widget.rb +0 -42
- data/lib/scarpe/unit_test_helpers.rb +0 -163
- data/lib/scarpe/widgets.rb +0 -30
- data/lib/scarpe/wv/fill.rb +0 -30
- data/lib/scarpe/wv/shape_helper.rb +0 -44
- data/scarpe-0.2.0.gem +0 -0
- /data/{lib/scarpe → spikes}/glibui/README.md +0 -0
- /data/{lib/scarpe → spikes}/glibui/alert.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/app.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/background.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/border.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/button.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/dimensions.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/document_root.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/edit_box.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/edit_line.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/flow.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/html.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/image.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/link.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/local_display.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/para.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/spacing.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/stack.rb +0 -0
- /data/{lib/scarpe → spikes}/glibui/text_widget.rb +0 -0
- /data/{lib/scarpe → spikes}/libui/alert.rb +0 -0
- /data/{lib/scarpe → spikes}/libui/button.rb +0 -0
- /data/{lib/scarpe → spikes}/libui/colors.rb +0 -0
- /data/{lib/scarpe → spikes}/libui/core.rb +0 -0
- /data/{lib/scarpe → spikes}/libui/flow.rb +0 -0
- /data/{lib/scarpe → spikes}/libui/libui.rb +0 -0
- /data/{lib/scarpe → spikes}/libui/notepad.md +0 -0
- /data/{lib/scarpe → spikes}/libui/para.rb +0 -0
- /data/{lib/scarpe → spikes}/libui/stack.rb +0 -0
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
class Para <
|
|
5
|
-
class << self
|
|
6
|
-
def inherited(subclass)
|
|
7
|
-
Scarpe::Widget.widget_classes ||= []
|
|
8
|
-
Scarpe::Widget.widget_classes << subclass
|
|
9
|
-
super
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
3
|
+
module Shoes
|
|
4
|
+
class Para < Shoes::Widget
|
|
13
5
|
display_properties :text_items, :stroke, :size, :font, :html_attributes, :hidden
|
|
14
6
|
|
|
15
7
|
def initialize(*args, stroke: nil, size: :para, font: nil, hidden: false, **html_attributes)
|
|
@@ -42,24 +34,10 @@ class Scarpe
|
|
|
42
34
|
# This should signal the display widget to change
|
|
43
35
|
self.text_items = text_children_to_items(@text_children)
|
|
44
36
|
end
|
|
45
|
-
|
|
46
|
-
def hide
|
|
47
|
-
# idempotent
|
|
48
|
-
return unless @hidden_text_items.empty?
|
|
49
|
-
|
|
50
|
-
@hidden_text_items = self.text_items
|
|
51
|
-
self.text_items = []
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def show
|
|
55
|
-
# idempotent
|
|
56
|
-
return unless self.text_items.empty?
|
|
57
|
-
|
|
58
|
-
self.text_items = @hidden_text_items
|
|
59
|
-
@hidden_text_items = []
|
|
60
|
-
end
|
|
61
37
|
end
|
|
38
|
+
end
|
|
62
39
|
|
|
40
|
+
module Shoes
|
|
63
41
|
class Widget
|
|
64
42
|
def banner(*args, **kwargs)
|
|
65
43
|
para(*args, **{ size: :banner }.merge(kwargs))
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shoes
|
|
4
|
+
class Radio < Shoes::Widget
|
|
5
|
+
display_properties :group, :checked
|
|
6
|
+
|
|
7
|
+
def initialize(group = nil, checked = nil, &block)
|
|
8
|
+
@group = group
|
|
9
|
+
@block = block
|
|
10
|
+
super
|
|
11
|
+
|
|
12
|
+
bind_self_event("click") { click }
|
|
13
|
+
create_display_widget
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def click(&block)
|
|
17
|
+
@block = block
|
|
18
|
+
self.checked = !checked?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def checked?
|
|
22
|
+
@checked ? true : false
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def checked(value)
|
|
26
|
+
self.checked = value
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def group_name
|
|
32
|
+
@group || @parent
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shoes
|
|
4
|
+
# A Shape acts as a sort of union type for drawn shapes. In Shoes you can use it to merge multiple
|
|
5
|
+
# ovals, arcs, stars, etc. into a single drawn shape.
|
|
6
|
+
#
|
|
7
|
+
# In Shoes3, a Shape isn't really a Slot. It's a kind of DSL with drawing commands that happen
|
|
8
|
+
# to have the same name as the Art widgets like star, arc, etc. Here we're treating it as
|
|
9
|
+
# a slot containing those widgets, which is wrong but not *too* wrong.
|
|
10
|
+
#
|
|
11
|
+
# @incompatibility A Shoes3 Shape is *not* a slot; Scarpe does *not* do union shapes
|
|
12
|
+
class Shape < Shoes::Slot
|
|
13
|
+
display_properties :left, :top, :shape_commands, :draw_context
|
|
14
|
+
|
|
15
|
+
def initialize(left: nil, top: nil, &block)
|
|
16
|
+
@left = left
|
|
17
|
+
@top = top
|
|
18
|
+
@shape_commands = []
|
|
19
|
+
@draw_context = Shoes::App.instance.current_draw_context
|
|
20
|
+
|
|
21
|
+
super
|
|
22
|
+
create_display_widget
|
|
23
|
+
|
|
24
|
+
Shoes::App.instance.with_slot(self, &block) if block_given?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# The cmd should be an array of the form:
|
|
28
|
+
#
|
|
29
|
+
# [cmd_name, *args]
|
|
30
|
+
#
|
|
31
|
+
# such as ["move_to", 50, 50]. Note that these must
|
|
32
|
+
# be JSON-serializable.
|
|
33
|
+
def add_shape_command(cmd)
|
|
34
|
+
@shape_commands << cmd
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Shoes::Slot < Shoes::Widget
|
|
4
|
+
# @incompatibility Shoes uses #content, not #children, for this
|
|
5
|
+
attr_reader :children
|
|
6
|
+
|
|
7
|
+
# Do not call directly, use set_parent
|
|
8
|
+
def remove_child(child)
|
|
9
|
+
@children ||= []
|
|
10
|
+
unless @children.include?(child)
|
|
11
|
+
@log.warn("remove_child: no such child(#{child.inspect}) for parent(#{parent.inspect})!")
|
|
12
|
+
end
|
|
13
|
+
@children.delete(child)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Do not call directly, use set_parent
|
|
17
|
+
def add_child(child)
|
|
18
|
+
@children ||= []
|
|
19
|
+
@children << child
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Get a list of child widgets
|
|
23
|
+
def contents
|
|
24
|
+
@children ||= []
|
|
25
|
+
@children.dup
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Calling stack.app or flow.app will execute the block
|
|
29
|
+
# with the Shoes::App as self, and with that stack or
|
|
30
|
+
# flow as the current slot.
|
|
31
|
+
#
|
|
32
|
+
# @incompatibility Shoes Classic will only change self
|
|
33
|
+
# via this method, while Scarpe will also change self
|
|
34
|
+
# with the other Slot Manipulation methods: #clear,
|
|
35
|
+
# #append, #prepend, #before and #after.
|
|
36
|
+
#
|
|
37
|
+
# @return [Shoes::App] the Shoes app
|
|
38
|
+
# @yield the block to call with the Shoes App as self
|
|
39
|
+
def app(&block)
|
|
40
|
+
Shoes::App.instance.with_slot(self, &block) if block_given?
|
|
41
|
+
Shoes::App.instance
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Remove all children from this widget. If a block
|
|
45
|
+
# is given, call the block to replace the children with
|
|
46
|
+
# new contents from that block.
|
|
47
|
+
#
|
|
48
|
+
# Should only be called on Slots, which can
|
|
49
|
+
# have children.
|
|
50
|
+
#
|
|
51
|
+
# @incompatibility Shoes Classic calls the clear block with current self, while Scarpe uses the Shoes::App as self
|
|
52
|
+
#
|
|
53
|
+
# @yield The block to call to replace the contents of the widget (optional)
|
|
54
|
+
# @return [void]
|
|
55
|
+
def clear(&block)
|
|
56
|
+
@children.dup.each(&:destroy)
|
|
57
|
+
append(&block) if block_given?
|
|
58
|
+
nil
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Call the block to append new children to a Slot.
|
|
62
|
+
#
|
|
63
|
+
# Should only be called on a Slot, since only Slots can have children.
|
|
64
|
+
#
|
|
65
|
+
# @incompatibility Shoes Classic calls the append block with current self, while Scarpe uses the Shoes::App as self
|
|
66
|
+
#
|
|
67
|
+
# @yield the block to call to replace children; will be called on the Shoes::App, appending to the called Slot as the current slot
|
|
68
|
+
# @return [void]
|
|
69
|
+
def append(&block)
|
|
70
|
+
raise("append requires a block!") unless block_given?
|
|
71
|
+
raise("Don't append to something that isn't a slot!") unless self.is_a?(Shoes::Slot)
|
|
72
|
+
|
|
73
|
+
Shoes::App.instance.with_slot(self, &block)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
class Span <
|
|
3
|
+
module Shoes
|
|
4
|
+
class Span < Shoes::Widget
|
|
5
5
|
display_properties :text, :stroke, :size, :font, :html_attributes
|
|
6
6
|
|
|
7
7
|
def initialize(text, stroke: nil, size: :span, font: nil, **html_attributes)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shoes
|
|
4
|
+
class Stack < Shoes::Slot
|
|
5
|
+
include Shoes::Background
|
|
6
|
+
include Shoes::Border
|
|
7
|
+
include Shoes::Spacing
|
|
8
|
+
|
|
9
|
+
# TODO: sort out various margin and padding properties, including putting stuff into spacing
|
|
10
|
+
display_properties :width, :height, :scroll
|
|
11
|
+
|
|
12
|
+
def initialize(width: nil, height: nil, margin: nil, padding: nil, scroll: false, margin_top: nil, margin_bottom: nil, margin_left: nil,
|
|
13
|
+
margin_right: nil, **options, &block)
|
|
14
|
+
|
|
15
|
+
@options = options
|
|
16
|
+
|
|
17
|
+
super
|
|
18
|
+
|
|
19
|
+
create_display_widget
|
|
20
|
+
# Create the display-side widget *before* running the block, which will add child widgets with their display widgets
|
|
21
|
+
Shoes::App.instance.with_slot(self, &block) if block_given?
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
class
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class Star < Scarpe::Widget
|
|
8
|
-
include ShapeHelper
|
|
9
|
-
display_properties :left, :top, :points, :outer, :inner, :color
|
|
3
|
+
module Shoes
|
|
4
|
+
class Star < Shoes::Widget
|
|
5
|
+
display_properties :left, :top, :points, :outer, :inner, :draw_context
|
|
10
6
|
|
|
11
7
|
def initialize(left, top, points = 10, outer = 100, inner = 50)
|
|
12
8
|
@points = convert_to_integer(points, "points", 10)
|
|
13
9
|
@outer = convert_to_float(outer, "outer", 100.0)
|
|
14
10
|
@inner = convert_to_float(inner, "inner", 50.0)
|
|
15
|
-
@color = color_for_fill
|
|
16
11
|
|
|
17
|
-
|
|
12
|
+
@draw_context = Shoes::App.instance.current_draw_context
|
|
13
|
+
|
|
14
|
+
super
|
|
18
15
|
create_display_widget
|
|
19
16
|
end
|
|
20
17
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Certain Shoes calls like motion and keydown are basically an
|
|
4
|
+
# event subscription, with no other visible presence. However,
|
|
5
|
+
# they have a place in the widget tree and can be deleted.
|
|
6
|
+
#
|
|
7
|
+
# Depending on the display library they may not have any
|
|
8
|
+
# direct visual (or similar) presence there either.
|
|
9
|
+
#
|
|
10
|
+
# Inheriting from Widget gives these a parent slot and a
|
|
11
|
+
# linkable_id automatically.
|
|
12
|
+
class Shoes::SubscriptionItem < Shoes::Widget
|
|
13
|
+
display_property :shoes_api_name
|
|
14
|
+
|
|
15
|
+
def initialize(shoes_api_name:, &block)
|
|
16
|
+
super
|
|
17
|
+
|
|
18
|
+
@callback = block
|
|
19
|
+
|
|
20
|
+
case shoes_api_name
|
|
21
|
+
when "hover"
|
|
22
|
+
# Hover passes the Shoes widget as the block param
|
|
23
|
+
@unsub_id = bind_self_event("hover") do
|
|
24
|
+
@callback&.call(self)
|
|
25
|
+
end
|
|
26
|
+
when "motion"
|
|
27
|
+
# Shoes sends back x, y, mods as the args.
|
|
28
|
+
# Shoes3 uses the strings "control" "shift" and
|
|
29
|
+
# "control_shift" as the mods arg.
|
|
30
|
+
@unsub_id = bind_self_event("motion") do |x, y, ctrl_key, shift_key, **_kwargs|
|
|
31
|
+
mods = [ctrl_key ? "control" : nil, shift_key ? "shift" : nil].compact.join("_")
|
|
32
|
+
@callback&.call(x, y, mods)
|
|
33
|
+
end
|
|
34
|
+
when "click"
|
|
35
|
+
# Click has block params button, left, top
|
|
36
|
+
# button is the button number, left and top are coords
|
|
37
|
+
@unsub_id = bind_self_event("click") do |button, x, y, **_kwargs|
|
|
38
|
+
@callback&.call(button, x, y)
|
|
39
|
+
end
|
|
40
|
+
else
|
|
41
|
+
raise "Unknown Shoes API call #{shoes_api_name.inspect} passed to SubscriptionItem!"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
@unsub_id = bind_self_event(shoes_api_name) do |*args|
|
|
45
|
+
@callback&.call(*args)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# This won't create a visible display widget, but will turn into
|
|
49
|
+
# an invisible widget and a stream of events.
|
|
50
|
+
create_display_widget
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def destroy
|
|
54
|
+
# TODO: we need a better way to do this automatically. See https://github.com/scarpe-team/scarpe/issues/291
|
|
55
|
+
unsub_shoes_event(@unsub_id) if @unsub_id
|
|
56
|
+
@unsub_id = nil
|
|
57
|
+
|
|
58
|
+
super
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Shoes::TextWidget
|
|
4
|
+
|
|
5
|
+
module Shoes
|
|
6
|
+
class TextWidget < Shoes::Widget
|
|
7
|
+
class << self
|
|
8
|
+
# rubocop:disable Lint/MissingSuper
|
|
9
|
+
def inherited(subclass)
|
|
10
|
+
Shoes::Widget.widget_classes ||= []
|
|
11
|
+
Shoes::Widget.widget_classes << subclass
|
|
12
|
+
end
|
|
13
|
+
# rubocop:enable Lint/MissingSuper
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class << self
|
|
18
|
+
def default_text_widget_with(element)
|
|
19
|
+
class_name = element.capitalize
|
|
20
|
+
|
|
21
|
+
widget_class = Class.new(Shoes::TextWidget) do
|
|
22
|
+
# Can we just change content to text to match the Shoes API?
|
|
23
|
+
display_property :content
|
|
24
|
+
|
|
25
|
+
def initialize(content)
|
|
26
|
+
@content = content
|
|
27
|
+
|
|
28
|
+
super
|
|
29
|
+
|
|
30
|
+
create_display_widget
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def text
|
|
34
|
+
self.content
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def text=(new_text)
|
|
38
|
+
self.content = new_text
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
Shoes.const_set class_name, widget_class
|
|
42
|
+
widget_class.class_eval do
|
|
43
|
+
display_property :content
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
Shoes.default_text_widget_with(:code)
|
|
50
|
+
Shoes.default_text_widget_with(:em)
|
|
51
|
+
Shoes.default_text_widget_with(:strong)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "shoes/widgets/slot"
|
|
4
|
+
require "shoes/widgets/stack"
|
|
5
|
+
require "shoes/widgets/flow"
|
|
6
|
+
require "shoes/widgets/document_root"
|
|
7
|
+
|
|
8
|
+
require "shoes/widgets/text_widget"
|
|
9
|
+
|
|
10
|
+
require "shoes/widgets/font"
|
|
11
|
+
require "shoes/widgets/subscription_item"
|
|
12
|
+
|
|
13
|
+
require "shoes/widgets/arc"
|
|
14
|
+
require "shoes/widgets/line"
|
|
15
|
+
require "shoes/widgets/shape"
|
|
16
|
+
require "shoes/widgets/star"
|
|
17
|
+
|
|
18
|
+
require "shoes/widgets/alert"
|
|
19
|
+
require "shoes/widgets/button"
|
|
20
|
+
require "shoes/widgets/check"
|
|
21
|
+
require "shoes/widgets/edit_box"
|
|
22
|
+
require "shoes/widgets/edit_line"
|
|
23
|
+
require "shoes/widgets/image"
|
|
24
|
+
require "shoes/widgets/link"
|
|
25
|
+
require "shoes/widgets/list_box"
|
|
26
|
+
require "shoes/widgets/para"
|
|
27
|
+
require "shoes/widgets/radio"
|
|
28
|
+
require "shoes/widgets/span"
|
|
29
|
+
require "shoes/widgets/video"
|
data/lacci/lib/shoes.rb
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# We're separating Shoes from Scarpe, a little at a time. This should be requirable
|
|
4
|
+
# without using Scarpe at all.
|
|
5
|
+
#
|
|
6
|
+
# The Lacci gem is like the old Shoes-core from Shoes4: a way
|
|
7
|
+
# to handle the DSL and command-line parts of Shoes without knowing anything about how the
|
|
8
|
+
# display side works at all.
|
|
9
|
+
|
|
10
|
+
if RUBY_VERSION[0..2] < "3.2"
|
|
11
|
+
Shoes::Log.logger("Shoes").error("Lacci (Scarpe, Shoes) requires Ruby 3.2 or higher!")
|
|
12
|
+
exit(-1)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module Shoes; end
|
|
16
|
+
class Shoes::Error < StandardError; end
|
|
17
|
+
|
|
18
|
+
require_relative "shoes/constants"
|
|
19
|
+
|
|
20
|
+
# Shoes adds some top-level methods and constants that can be used everywhere. Kernel is where they go.
|
|
21
|
+
module Kernel
|
|
22
|
+
include Shoes::Constants
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
require_relative "shoes/log"
|
|
26
|
+
require_relative "shoes/display_service"
|
|
27
|
+
require_relative "shoes/colors"
|
|
28
|
+
|
|
29
|
+
require_relative "shoes/background"
|
|
30
|
+
require_relative "shoes/border"
|
|
31
|
+
require_relative "shoes/spacing"
|
|
32
|
+
|
|
33
|
+
require_relative "shoes/widget"
|
|
34
|
+
require_relative "shoes/app"
|
|
35
|
+
require_relative "shoes/widgets"
|
|
36
|
+
|
|
37
|
+
require_relative "shoes/download"
|
|
38
|
+
|
|
39
|
+
# The module containing Shoes in all its glory.
|
|
40
|
+
# Shoes is a platform-independent GUI library, designed to create
|
|
41
|
+
# small visual applications in Ruby.
|
|
42
|
+
#
|
|
43
|
+
module Shoes
|
|
44
|
+
class << self
|
|
45
|
+
# Creates a Shoes app with a new window. The block parameter is used to create
|
|
46
|
+
# widgets and set up handlers. Arguments are passed to Shoes::App.new internally.
|
|
47
|
+
#
|
|
48
|
+
# @incompatibility In Shoes3, this method will return normally.
|
|
49
|
+
# In Scarpe, after the block is executed, the method will not return and Scarpe
|
|
50
|
+
# will retain control of execution until the window is closed and the app quits.
|
|
51
|
+
#
|
|
52
|
+
# @incompatibility In Shoes3 the parameters were a hash of options, not keyword arguments.
|
|
53
|
+
#
|
|
54
|
+
# @example Simple one-button app
|
|
55
|
+
# Shoes.app(title: "Button!", width: 200, height: 200) do
|
|
56
|
+
# @p = para "Press it NOW!"
|
|
57
|
+
# button("clicky") { @p.replace("You pressed it! CELEBRATION!") }
|
|
58
|
+
# end
|
|
59
|
+
#
|
|
60
|
+
# @param title [String] The new app window title
|
|
61
|
+
# @param width [Integer] The new app window width
|
|
62
|
+
# @param height [Integer] The new app window height
|
|
63
|
+
# @param resizable [Boolean] Whether the app window should be resizeable
|
|
64
|
+
# @return [void]
|
|
65
|
+
# @see Shoes::App#new
|
|
66
|
+
def app(
|
|
67
|
+
title: "Shoes!",
|
|
68
|
+
width: 480,
|
|
69
|
+
height: 420,
|
|
70
|
+
resizable: true,
|
|
71
|
+
&app_code_body
|
|
72
|
+
)
|
|
73
|
+
app = Shoes::App.new(title:, width:, height:, resizable:, &app_code_body)
|
|
74
|
+
app.init
|
|
75
|
+
app.run
|
|
76
|
+
nil
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Load a Shoes app from a file. By default, this will load old-style Shoes apps
|
|
80
|
+
# from a .rb file with all the appropriate libraries loaded. By setting one or
|
|
81
|
+
# more loaders, a Lacci-based display library can accept new file formats as
|
|
82
|
+
# well, not just raw Shoes .rb files.
|
|
83
|
+
#
|
|
84
|
+
# @param path [String] The current-dir-relative path to the file
|
|
85
|
+
# @return [void]
|
|
86
|
+
# @see Shoes.add_file_loader
|
|
87
|
+
def run_app(relative_path)
|
|
88
|
+
path = File.expand_path relative_path
|
|
89
|
+
loaded = false
|
|
90
|
+
file_loaders.each do |loader|
|
|
91
|
+
if loader.call(path)
|
|
92
|
+
loaded = true
|
|
93
|
+
break
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
raise "Could not find a file loader for #{path.inspect}!" unless loaded
|
|
97
|
+
|
|
98
|
+
nil
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def default_file_loaders
|
|
102
|
+
[
|
|
103
|
+
# By default we will always try to load any file, regardless of extension, as a Shoes Ruby file.
|
|
104
|
+
proc do |path|
|
|
105
|
+
load path
|
|
106
|
+
true
|
|
107
|
+
end,
|
|
108
|
+
]
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def file_loaders
|
|
112
|
+
@file_loaders ||= default_file_loaders
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def add_file_loader(loader)
|
|
116
|
+
file_loaders.prepend(loader)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def reset_file_loaders
|
|
120
|
+
@file_loaders = default_file_loaders
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def set_file_loaders(loaders)
|
|
124
|
+
@file_loaders = loaders
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
class TestColors < Minitest::Test
|
|
6
|
+
class Dummy
|
|
7
|
+
include Shoes::Colors
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def test_default_colors_are_accessible_via_methods
|
|
11
|
+
assert_equal [0, 0, 0, 255], Dummy.new.black
|
|
12
|
+
assert_equal [255, 255, 255, 255], Dummy.new.white
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def test_default_colors_can_accept_alpha
|
|
16
|
+
assert_equal [0, 0, 0, 0.5], Dummy.new.black(0.5)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_gray_accepts_single_value_for_darkness
|
|
20
|
+
assert_equal [0, 0, 0, 255], Dummy.new.gray(0)
|
|
21
|
+
assert_equal [255, 255, 255, 255], Dummy.new.gray(255)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_gray_accepts_darkness_and_alpha
|
|
25
|
+
assert_equal [0, 0, 0, 128], Dummy.new.gray(0, 128)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_gray_defaults_to_50_percent_darkness
|
|
29
|
+
assert_equal [128, 128, 128, 255], Dummy.new.gray
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def test_rgb_accepts_three_values
|
|
33
|
+
assert_equal [255, 0, 0, 255], Dummy.new.rgb(255, 0, 0)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_rgb_accepts_alpha
|
|
37
|
+
assert_equal [255, 0, 0, 128], Dummy.new.rgb(255, 0, 0, 128)
|
|
38
|
+
end
|
|
39
|
+
end
|