diff --git a/.gitignore b/.gitignore index c360d161a..d56fb0587 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ logger/*.log **/lacci-*.gem *scarpe*.gem **/sspec.json +examples/legacy/working/shoes_manual/nasa50th.gif diff --git a/lacci/lib/shoes/app.rb b/lacci/lib/shoes/app.rb index 0dc59ae57..f13601b41 100644 --- a/lacci/lib/shoes/app.rb +++ b/lacci/lib/shoes/app.rb @@ -41,6 +41,7 @@ def initialize( @draw_context = { "fill" => "", "stroke" => "", + "strokewidth" => 2, "rotate" => 0, } @@ -278,6 +279,10 @@ def stroke(color) @draw_context["stroke"] = color end + def strokewidth(width) + @draw_context["strokewidth"] = width + end + def nostroke @draw_context["stroke"] = "" end diff --git a/lacci/lib/shoes/drawable.rb b/lacci/lib/shoes/drawable.rb index 93af6e5c4..548e8ca09 100644 --- a/lacci/lib/shoes/drawable.rb +++ b/lacci/lib/shoes/drawable.rb @@ -82,6 +82,24 @@ def shoes_events(*args) @shoes_events ||= args.map(&:to_s) + self.superclass.get_shoes_events end + # Allow supplying a list of Shoes style values as positional arguments to + # initialize. Initialize will get the arg list, then set the specified styles + # if args are given for them. + # + # @param args [Array] an array of Shoes style names + # @return [void] + def init_args(*args) + raise Shoes::Errors::BadArgumentListError, "Positional init args already set for #{self}!" if @positional_init_args + @positional_init_args = args.map(&:to_s) + end + + # Return the list of style names for positional init args for this class + # + # @return [Array] the array of style names as strings + def positional_init_args + @positional_init_args ||= [] + end + # Assign a new Shoes Drawable ID number, starting from 1. # This allows non-overlapping small integer IDs for Shoes # linkable IDs - the number part of making it clear what @@ -167,14 +185,33 @@ def shoes_style_name?(name) attr_reader :debug_id def initialize(*args, **kwargs) - log_init("Shoes::#{self.class.name}") + log_init("Shoes::#{self.class.name}") unless @log + + supplied_args = kwargs.keys + + pos_args = self.class.positional_init_args + if pos_args != ["any"] + if args.size > pos_args.size + raise Shoes::Errors::BadArgumentListError, "Too many arguments given for #{self.class}#initialize! #{args.inspect}" + end + + # Set each positional argument + args.each.with_index do |val, idx| + style_name = pos_args[idx] + next if style_name.nil? || style_name == "" # It's possible to have non-style positional args + + val = self.class.validate_as(style_name, args[idx]) + instance_variable_set("@#{style_name}", val) + supplied_args << style_name.to_sym + end + end default_styles = Shoes::Drawable.drawable_default_styles[self.class] this_drawable_styles = self.class.shoes_style_names.map(&:to_sym) - # No keyword arg specified for a property with a default value? Set it to default. - (default_styles.keys - kwargs.keys).each do |key| - val = self.class.validate_as(prop, default_styles[key]) + # No arg specified for a property with a default value? Set it to default. + (default_styles.keys - supplied_args).each do |key| + val = self.class.validate_as(key, default_styles[key]) instance_variable_set("@#{key}", val) end @@ -184,8 +221,10 @@ def initialize(*args, **kwargs) instance_variable_set("@#{key}", val) end - # We'd like to avoid unexpected keywords. But we're not disciplined enough to do - # this by default yet. + # We'd like to avoid unexpected keywords. But we're not disciplined enough to + # raise an error by default yet. Non-style keywords passed to Drawable#initialize + # are deprecated at this point, but I need to hunt down the last of them + # and prevent them. unexpected = (kwargs.keys - this_drawable_styles) unless unexpected.empty? STDERR.puts "Unexpected non-style keyword(s) in #{self.class} initialize: #{unexpected.inspect}" diff --git a/lacci/lib/shoes/drawables/arc.rb b/lacci/lib/shoes/drawables/arc.rb index e18eb6ac9..bb63f12cf 100644 --- a/lacci/lib/shoes/drawables/arc.rb +++ b/lacci/lib/shoes/drawables/arc.rb @@ -13,11 +13,11 @@ class Arc < Shoes::Drawable shoes_style(prop) { |val| convert_to_float(val, prop) } end - def initialize(*args) + init_args :left, :top, :width, :height, :angle1, :angle2 + def initialize(*args, **kwargs) @draw_context = Shoes::App.instance.current_draw_context super - self.left, self.top, self.width, self.height, self.angle1, self.angle2 = args create_display_drawable end diff --git a/lacci/lib/shoes/drawables/arrow.rb b/lacci/lib/shoes/drawables/arrow.rb index 818def117..47cc5ba9d 100644 --- a/lacci/lib/shoes/drawables/arrow.rb +++ b/lacci/lib/shoes/drawables/arrow.rb @@ -9,20 +9,12 @@ class Arrow < Shoes::Drawable shoes_style(prop) { |val| val.is_a?(Hash) ? val : convert_to_integer(val, prop) } end - def initialize(*args) + init_args :left, :top, :width + def initialize(*args, **kwargs) @draw_context = Shoes::App.instance.current_draw_context super - if args.length == 1 && args[0].is_a?(Hash) - options = args[0] - self.left = options[:left] - self.top = options[:top] - self.width = options[:width] - else - self.left, self.top, self.width = args - end - create_display_drawable end diff --git a/lacci/lib/shoes/drawables/button.rb b/lacci/lib/shoes/drawables/button.rb index d88de6a26..92404ba6a 100644 --- a/lacci/lib/shoes/drawables/button.rb +++ b/lacci/lib/shoes/drawables/button.rb @@ -2,10 +2,10 @@ class Shoes class Button < Shoes::Drawable - include Shoes::Log shoes_styles :text, :width, :height, :top, :left, :color, :padding_top, :padding_bottom, :text_color, :size, :font_size, :tooltip shoes_events :click, :hover + init_args :text # Creates a new Button object. # # @param text [String] The text displayed on the button. @@ -32,13 +32,8 @@ class Button < Shoes::Drawable # ) # } # end - def initialize(text, width: nil, height: nil, top: nil, left: nil, color: nil, padding_top: nil, padding_bottom: nil, size: 12, text_color: nil, - font_size: nil, tooltip: nil, &block) - - log_init("Button") - + def initialize(*args, **kwargs, &block) # Properties passed as positional args, not keywords, don't get auto-set - @text = text @block = block super diff --git a/lacci/lib/shoes/drawables/check.rb b/lacci/lib/shoes/drawables/check.rb index e4846493a..99b665699 100644 --- a/lacci/lib/shoes/drawables/check.rb +++ b/lacci/lib/shoes/drawables/check.rb @@ -5,7 +5,8 @@ class Check < Shoes::Drawable shoes_styles :checked shoes_events :click - def initialize(checked = nil, &block) + init_args(:checked) + def initialize(*args, **kwargs, &block) @block = block super diff --git a/lacci/lib/shoes/drawables/edit_box.rb b/lacci/lib/shoes/drawables/edit_box.rb index 8e2ffa4d0..553917b1e 100644 --- a/lacci/lib/shoes/drawables/edit_box.rb +++ b/lacci/lib/shoes/drawables/edit_box.rb @@ -5,10 +5,10 @@ class EditBox < Shoes::Drawable shoes_styles :text, :height, :width shoes_events :change - def initialize(text = "", height: nil, width: nil, &block) - super - @text = text + init_args :text + def initialize(*args, **kwargs, &block) @callback = block + super bind_self_event("change") do |new_text| self.text = new_text diff --git a/lacci/lib/shoes/drawables/edit_line.rb b/lacci/lib/shoes/drawables/edit_line.rb index b8b0ae42a..3c3fd1df3 100644 --- a/lacci/lib/shoes/drawables/edit_line.rb +++ b/lacci/lib/shoes/drawables/edit_line.rb @@ -5,10 +5,10 @@ class EditLine < Shoes::Drawable shoes_styles :text, :width shoes_events :change - def initialize(text = "", width: nil, &block) - super + init_args(:text) + def initialize(*args, **kwargs, &block) @block = block - @text = text + super bind_self_event("change") do |new_text| self.text = new_text diff --git a/lacci/lib/shoes/drawables/image.rb b/lacci/lib/shoes/drawables/image.rb index 105a729f7..961fbb17e 100644 --- a/lacci/lib/shoes/drawables/image.rb +++ b/lacci/lib/shoes/drawables/image.rb @@ -5,9 +5,9 @@ class Image < Shoes::Drawable shoes_styles :url, :width, :height, :top, :left, :click shoes_events # No Image-specific events yet - def initialize(url, width: nil, height: nil, top: nil, left: nil, click: nil) + init_args :url + def initialize(*args, **kwargs) super - @url = url # Get the image dimensions # @width, @height = size diff --git a/lacci/lib/shoes/drawables/line.rb b/lacci/lib/shoes/drawables/line.rb index cb796d042..85ce19808 100644 --- a/lacci/lib/shoes/drawables/line.rb +++ b/lacci/lib/shoes/drawables/line.rb @@ -5,15 +5,12 @@ class Line < Shoes::Drawable shoes_styles :left, :top, :x2, :y2, :draw_context shoes_events # No Line-specific events yet - def initialize(left, top, x2, y2) - super - - @left = left - @top = top - @x2 = x2 - @y2 = y2 + init_args :left, :top, :x2, :y2 + def initialize(*args, **kwargs) @draw_context = Shoes::App.instance.current_draw_context + super + create_display_drawable end end diff --git a/lacci/lib/shoes/drawables/link.rb b/lacci/lib/shoes/drawables/link.rb index bad486db0..54226001a 100644 --- a/lacci/lib/shoes/drawables/link.rb +++ b/lacci/lib/shoes/drawables/link.rb @@ -5,16 +5,15 @@ class Link < Shoes::TextDrawable shoes_styles :text, :click, :has_block shoes_events :click - def initialize(text, click: nil, &block) - super + Shoes::Drawable.drawable_default_styles[Shoes::Link][:click] = "#" - @text = text + init_args :text + def initialize(text, click: nil, &block) @block = block # We can't send a block to the display drawable, but we can send a boolean @has_block = !block.nil? - # The click property should be changed before it gets sent to the display drawable - @click ||= "#" + super bind_self_event("click") do @block&.call diff --git a/lacci/lib/shoes/drawables/list_box.rb b/lacci/lib/shoes/drawables/list_box.rb index 4f830a78e..c6141f12c 100644 --- a/lacci/lib/shoes/drawables/list_box.rb +++ b/lacci/lib/shoes/drawables/list_box.rb @@ -11,11 +11,14 @@ class ListBox < Shoes::Drawable shoes_events :change - def initialize(**args, &block) - super - - @items = args[:items] || [] - @chosen = args[:choose] || args[:items]&.first + init_args # No positional args + def initialize(**kwargs, &block) + # These aren't being set as styles -- remove them from kwargs before calling super + # TODO: set [] as default value for items? + @items = kwargs.delete(:items) || [] + @chosen = kwargs.delete(:choose) || @items&.first + + super(**kwargs, &block) bind_self_event("change") do |new_item| self.chosen = new_item diff --git a/lacci/lib/shoes/drawables/oval.rb b/lacci/lib/shoes/drawables/oval.rb index 184252ad7..d04456b4e 100644 --- a/lacci/lib/shoes/drawables/oval.rb +++ b/lacci/lib/shoes/drawables/oval.rb @@ -3,7 +3,7 @@ class Shoes # Docs: https://github.com/scarpe-team/scarpe/blob/main/docs/static/manual.md#ovalleft-top-radius--shoesshape class Oval < Shoes::Drawable - shoes_styles :height, :center, :draw_context, :stroke + shoes_styles :center, :draw_context, :stroke shoes_style(:left) { |val| convert_to_integer(val, "left") } shoes_style(:top) { |val| convert_to_integer(val, "top") } @@ -12,16 +12,32 @@ class Oval < Shoes::Drawable shoes_style(:width) { |val| convert_to_integer(val, "width") } shoes_style(:strokewidth) { |val| convert_to_integer(val, "strokewidth") } - def initialize(left = nil, top = nil, radius = nil, height = nil, **options) - super - self.left, self.top, self.radius, self.height = - left || options[:left], - top || options[:top], - radius || options[:radius] || options[:width] / 2, # The radius positional arg change forces us to do this - height || options[:height] - + init_args :left, :top, :radius, :height + def initialize(*args, **options) @draw_context = Shoes::App.instance.current_draw_context + super # Parse any positional or keyword args + + unless @left && @top && (@width || @height || @radius) + raise Shoes::Errors::InvalidAttributeValueError, "Oval requires left, top and one of (width, height, radius) to be specified!" + end + + # Calzini expects "radius" to mean the x-axis-aligned radius, not y-axis-aligned. + # For an axis-aligned oval the two may be different. + + # If we have no width, but a radius, default the width to be the radius * 2 + @width ||= @radius * 2 + + # If we have width or height, set the other (and optionally radius) from what we have. + if @width || @height + @width ||= @height + @height ||= @width + @radius ||= @width / 2 + else + # No width or height, so it's all from radius + @width = @height = @radius + end + create_display_drawable end diff --git a/lacci/lib/shoes/drawables/para.rb b/lacci/lib/shoes/drawables/para.rb index e635b6d1e..81d7772a0 100644 --- a/lacci/lib/shoes/drawables/para.rb +++ b/lacci/lib/shoes/drawables/para.rb @@ -2,9 +2,11 @@ class Shoes class Para < Shoes::Drawable - shoes_styles :text_items, :size, :font, :html_attributes + shoes_styles :text_items, :size, :font shoes_style(:stroke) { |val| Shoes::Colors.to_rgb(val) } + Shoes::Drawable.drawable_default_styles[Shoes::Para][:size] = :para + shoes_events # No Para-specific events yet # Initializes a new instance of the `Para` widget. @@ -30,7 +32,10 @@ class Para < Shoes::Drawable # p.replace "On top we'll switch to ", strong("bold"), "!" # end def initialize(*args, stroke: nil, size: :para, font: nil, **html_attributes) - super + kwargs = { stroke:, size:, font:, **html_attributes }.compact + + # Don't pass text_children args to Drawable#initialize + super(*[], **kwargs) # Text_children alternates strings and TextDrawables, so we can't just pass # it as a Shoes style. It won't serialize. diff --git a/lacci/lib/shoes/drawables/progress.rb b/lacci/lib/shoes/drawables/progress.rb index a5fa1681f..6f9aa3a2f 100644 --- a/lacci/lib/shoes/drawables/progress.rb +++ b/lacci/lib/shoes/drawables/progress.rb @@ -5,7 +5,8 @@ class Progress < Shoes::Drawable shoes_styles :fraction shoes_events # No Progress-specific events yet - def initialize(fraction: nil) + init_args # No positional args + def initialize(**kwargs) super create_display_drawable diff --git a/lacci/lib/shoes/drawables/radio.rb b/lacci/lib/shoes/drawables/radio.rb index fae4f12be..43d044ab1 100644 --- a/lacci/lib/shoes/drawables/radio.rb +++ b/lacci/lib/shoes/drawables/radio.rb @@ -8,11 +8,12 @@ class Radio < Shoes::Drawable shoes_styles :group, :checked shoes_events :click - def initialize(group = nil, checked: nil, &block) - super - @group = group + init_args :group + def initialize(*args, **kwargs, &block) @block = block + super + bind_self_event("click") { click } create_display_drawable end diff --git a/lacci/lib/shoes/drawables/rect.rb b/lacci/lib/shoes/drawables/rect.rb index bc88f7cce..ccf476eeb 100644 --- a/lacci/lib/shoes/drawables/rect.rb +++ b/lacci/lib/shoes/drawables/rect.rb @@ -3,13 +3,13 @@ class Shoes class Rect < Shoes::Drawable shoes_styles :left, :top, :width, :height, :draw_context, :curve - shoes_events # No Rect-specific events yet + shoes_events # No Rect-specific events - def initialize(*args) + init_args :left, :top, :width, :height, :curve + def initialize(*args, **kwargs) @draw_context = Shoes::App.instance.current_draw_context super - self.left, self.top, self.width, self.height, self.curve = args create_display_drawable end diff --git a/lacci/lib/shoes/drawables/shape.rb b/lacci/lib/shoes/drawables/shape.rb index 675cc1b55..3c1ccab06 100644 --- a/lacci/lib/shoes/drawables/shape.rb +++ b/lacci/lib/shoes/drawables/shape.rb @@ -13,7 +13,8 @@ class Shape < Shoes::Slot shoes_styles :left, :top, :shape_commands, :draw_context shoes_events # No Shape-specific events yet - def initialize(left: nil, top: nil, &block) + init_args # No positional args + def initialize(**kwargs, &block) @shape_commands = [] @draw_context = Shoes::App.instance.current_draw_context diff --git a/lacci/lib/shoes/drawables/span.rb b/lacci/lib/shoes/drawables/span.rb index bd9ac4b49..10356dbda 100644 --- a/lacci/lib/shoes/drawables/span.rb +++ b/lacci/lib/shoes/drawables/span.rb @@ -5,13 +5,12 @@ class Span < Shoes::Drawable shoes_styles :text, :stroke, :size, :font, :html_attributes shoes_events # No Span-specific events yet - def initialize(text, stroke: nil, size: :span, font: nil, **html_attributes) + Shoes::Drawable.drawable_default_styles[Shoes::Span][:size] = :span + + init_args :text, :stroke, :size, :font + def initialize(*args, **html_attributes) super - @text = text - @stroke = stroke - @size = size - @font = font @html_attributes = html_attributes create_display_drawable diff --git a/lacci/lib/shoes/drawables/star.rb b/lacci/lib/shoes/drawables/star.rb index 9166b8363..ce05ced8e 100644 --- a/lacci/lib/shoes/drawables/star.rb +++ b/lacci/lib/shoes/drawables/star.rb @@ -8,15 +8,15 @@ class Star < Shoes::Drawable shoes_style(:outer) { |val| convert_to_float(val, "outer") } shoes_style(:inner) { |val| convert_to_float(val, "inner") } - shoes_events # No Star-specific events yet + Shoes::Drawable.drawable_default_styles[Shoes::Star][:points] = 10 + Shoes::Drawable.drawable_default_styles[Shoes::Star][:outer] = 100 + Shoes::Drawable.drawable_default_styles[Shoes::Star][:inner] = 50 - def initialize(left, top, points = 10, outer = 100, inner = 50) + shoes_events # No Star-specific events + + init_args :left, :top, :points, :outer, :inner + def initialize(*args, **kwargs) super - self.left = left - self.top = top - self.points = points - self.outer = outer - self.inner = inner @draw_context = Shoes::App.instance.current_draw_context diff --git a/lacci/lib/shoes/drawables/text_drawable.rb b/lacci/lib/shoes/drawables/text_drawable.rb index 0fecd27b2..3b4b7a930 100644 --- a/lacci/lib/shoes/drawables/text_drawable.rb +++ b/lacci/lib/shoes/drawables/text_drawable.rb @@ -28,8 +28,9 @@ def default_text_drawable_with(element) # Can we just change content to text to match the Shoes API? shoes_style :content + init_args # We're going to pass an empty array to super def initialize(content) - super + super() @content = content diff --git a/lacci/lib/shoes/drawables/video.rb b/lacci/lib/shoes/drawables/video.rb index 07136e639..b7ce13157 100644 --- a/lacci/lib/shoes/drawables/video.rb +++ b/lacci/lib/shoes/drawables/video.rb @@ -5,9 +5,10 @@ class Video < Shoes::Drawable shoes_styles :url shoes_events # No specific events yet - def initialize(url) + init_args :url + def initialize(*args, **kwargs) super - @url = url + create_display_drawable end diff --git a/lacci/lib/shoes/drawables/widget.rb b/lacci/lib/shoes/drawables/widget.rb index ca8180bd4..9f8ba4637 100644 --- a/lacci/lib/shoes/drawables/widget.rb +++ b/lacci/lib/shoes/drawables/widget.rb @@ -42,6 +42,13 @@ class Shoes::Widget < Shoes::Slot shoes_events + def self.inherited(subclass) + super + + # Widgets are special - we can't know in advance what sort of initialize args they take + subclass.init_args :any + end + def self.method_added(name) # We're only looking for the initialize() method, and only on subclasses # of Shoes::Widget, not Shoes::Widget itself. @@ -57,7 +64,7 @@ def self.method_added(name) @midway_through_adding_initialize = true define_method(:initialize) do |*args, **kwargs, &block| super(*args, **kwargs, &block) - @options = kwargs + @options = kwargs # Get rid of options? create_display_drawable __widget_initialize(*args, **kwargs, &block) diff --git a/lacci/lib/shoes/errors.rb b/lacci/lib/shoes/errors.rb index 1d75815d7..d57eb4936 100644 --- a/lacci/lib/shoes/errors.rb +++ b/lacci/lib/shoes/errors.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Shoes; end -class Shoes::Errors +module Shoes::Errors class InvalidAttributeValueError < Shoes::Error; end class TooManyInstancesError < Shoes::Error; end @@ -22,6 +22,8 @@ class BadLinkableIdError < Shoes::Error; end class UnregisteredShoesEvent < Shoes::Error; end + class BadArgumentListError < Shoes::Error; end + class SingletonError < Shoes::Error; end class MultipleShoesSpecRunsError < Shoes::Error; end diff --git a/lacci/test/test_lacci.rb b/lacci/test/test_lacci.rb index e0fa7ef6a..af48bc7aa 100644 --- a/lacci/test/test_lacci.rb +++ b/lacci/test/test_lacci.rb @@ -10,9 +10,51 @@ def test_simple_button_click @b.text = "Yup" end end - SHOES_APP + SHOES_APP button().trigger_click assert_equal "Yup", button().text SHOES_SPEC end + + def test_positional_default_values + run_test_niente_code(<<~SHOES_APP, app_test_code: <<~SHOES_SPEC) + Shoes.app do + star + end + SHOES_APP + s = star() + assert_equal 10, s.points + assert_equal 50, s.inner + SHOES_SPEC + end + + def test_positional_args + run_test_niente_code(<<~SHOES_APP, app_test_code: <<~SHOES_SPEC) + Shoes.app do + star 10, 25, 8 # Leave outer and inner as default + end + SHOES_APP + s = star() + assert_equal 10, s.left + assert_equal 25, s.top + assert_equal 8, s.points + assert_equal 50, s.inner + SHOES_SPEC + end + + def test_keyword_args + run_test_niente_code(<<~SHOES_APP, app_test_code: <<~SHOES_SPEC) + Shoes.app do + star 5, 6, points: 8, inner: 30 + end + SHOES_APP + s = star() + assert_equal 5, s.left + assert_equal 6, s.top + assert_equal 8, s.points + assert_equal 100, s.outer + assert_equal 30, s.inner + SHOES_SPEC + end + end diff --git a/lacci/test/test_oval.rb b/lacci/test/test_oval.rb new file mode 100644 index 000000000..d033e2ae9 --- /dev/null +++ b/lacci/test/test_oval.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require_relative "test_helper" + +class TestLacciOval < NienteTest + # For an oval, the args go left, top, radius, height + def test_simple_oval_values + run_test_niente_code(<<~SHOES_APP, app_test_code: <<~SHOES_SPEC) + Shoes.app do + oval 5, 10, 25 # circle with radius 25 with its upper-left point at 5, 10 + end + SHOES_APP + ov = oval() + assert_equal 5, ov.left + assert_equal 10, ov.top + assert_equal 25, ov.radius + assert_equal 50, ov.width + assert_equal 50, ov.height + SHOES_SPEC + end + + def test_oval_with_height + run_test_niente_code(<<~SHOES_APP, app_test_code: <<~SHOES_SPEC) + Shoes.app do + oval 5, 10, 25, 35 # oval with radius 25, 50 wide, 35 tall + end + SHOES_APP + ov = oval() + assert_equal 5, ov.left + assert_equal 10, ov.top + assert_equal 25, ov.radius + assert_equal 50, ov.width + assert_equal 35, ov.height + SHOES_SPEC + end + + def test_simple_oval_values + run_test_niente_code(<<~SHOES_APP, app_test_code: <<~SHOES_SPEC) + Shoes.app do + oval left: 5, top: 10, radius: 25 + end + SHOES_APP + ov = oval() + assert_equal 5, ov.left + assert_equal 10, ov.top + assert_equal 25, ov.radius + assert_equal 50, ov.height + assert_equal 50, ov.width + SHOES_SPEC + end + + def test_oval_strokewidth + run_test_niente_code(<<~SHOES_APP, app_test_code: <<~SHOES_SPEC) + Shoes.app do + strokewidth 3 + oval 5, 10, 25 + end + SHOES_APP + ov = oval() + assert_equal 5, ov.left + assert_equal 10, ov.top + assert_equal 25, ov.radius + assert_equal 3, ov.draw_context["strokewidth"] + # assert_equal 3, ov.strokewidth # This should work but doesn't yet, see issue #476 + SHOES_SPEC + end +end diff --git a/scarpe-components/lib/scarpe/components/calzini/art_widgets.rb b/scarpe-components/lib/scarpe/components/calzini/art_widgets.rb index ab3e762cd..e806ad90b 100644 --- a/scarpe-components/lib/scarpe/components/calzini/art_widgets.rb +++ b/scarpe-components/lib/scarpe/components/calzini/art_widgets.rb @@ -77,7 +77,7 @@ def oval_element(props, &block) h.ellipse( cx: center ? radius : 0, cy: center ? height / 2 : 0, - rx: radius, + rx: width ? width / 2, radius, ry: height ? height / 2 : radius, style: "stroke:#{stroke};stroke-width:#{strokewidth};", ) diff --git a/scarpe-components/lib/scarpe/components/calzini/para.rb b/scarpe-components/lib/scarpe/components/calzini/para.rb index e7346f099..48c33578f 100644 --- a/scarpe-components/lib/scarpe/components/calzini/para.rb +++ b/scarpe-components/lib/scarpe/components/calzini/para.rb @@ -13,7 +13,7 @@ def para_element(props, &block) private def para_options(props) - (props["html_attributes"] || {}).merge(id: html_id, style: para_style(props)) + { id: html_id, style: para_style(props) }.compact end def para_style(props) @@ -21,6 +21,7 @@ def para_style(props) color: rgb_to_hex(props["stroke"]), "font-size": para_font_size(props), "font-family": props["font"], + "text-align": props["align"], }.compact) end diff --git a/scarpe-components/test/calzini/test_calzini_para.rb b/scarpe-components/test/calzini/test_calzini_para.rb index fd390b5e9..7d5886665 100644 --- a/scarpe-components/test/calzini/test_calzini_para.rb +++ b/scarpe-components/test/calzini/test_calzini_para.rb @@ -13,6 +13,11 @@ def test_para_simple @calzini.render("para", {}) { "OK" } end + def test_para_with_align + assert_equal %{

OK

}, + @calzini.render("para", { "align" => "right" }) { "OK" } + end + def test_para_with_stroke_and_font assert_equal %{

OK

}, @calzini.render("para", { "stroke" => [1.0, 0.0, 0.0], "font" => "Lucida" }) { "OK" } @@ -30,8 +35,8 @@ def test_para_with_symbol_banner # Eventually this should probably need to be marked as a Scarpe extension, here or # elsewhere. - def test_para_with_html_attributes - assert_equal %{

}, - @calzini.render("para", { "html_attributes" => { "avocado" => true, "class" => "avocado_bearing" } }) - end + #def test_para_with_html_attributes + # assert_equal %{

}, + # @calzini.render("para", { "html_attributes" => { "avocado" => true, "class" => "avocado_bearing" } }) + #end end diff --git a/test/test_drawables.rb b/test/test_drawables.rb index 565c45430..4032d0b54 100644 --- a/test/test_drawables.rb +++ b/test/test_drawables.rb @@ -66,6 +66,44 @@ def test_hide_show TEST_CODE end + # Not only does this test the hidden: property, it also makes sure that every drawable + # can accept Shoes styles defined on the parent class (or that every drawable defines + # hidden, I guess.) + def test_create_hidden + run_test_scarpe_code(<<-'SCARPE_APP', app_test_code: <<-'TEST_CODE') + Shoes.app do + @drawables = [] + @drawables << arc(400, 0, 120, 100, 175, 175, hidden: true) + @drawables << arrow(100, 100, 30, hidden: true) + @drawables << button("Press Me", hidden: true) + @drawables << check(hidden: true) + @drawables << edit_line("foo", hidden: true) + @drawables << edit_box("bar", hidden: true) + @drawables << flow(hidden: true) {} # Slightly weird thing here: empty flow + @drawables << image("https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png", hidden: true) + @drawables << line(0, 0, 100, 100, hidden: true) + @drawables << list_box(items: ['A', 'B'], hidden: true) + @drawables << para("Hello", hidden: true) + @drawables << progress(hidden: true) + @drawables << radio("ooga", hidden: true) + @drawables << rect(0, 0, 50, 100, 5, hidden: true) + @drawables << shape(hidden: true) { line(0, 0, 10, 10) } + @drawables << stack(hidden: true) {} + @drawables << star(230, 100, 6, 50, 25, hidden: true) + @drawables << video("http://techslides.com/demos/sample-videos/small.mp4", hidden: true) + end + SCARPE_APP + # Get proxy objects for the Shoes drawables so we can get their display objects, etc. + w = Shoes::App.instance.instance_variable_get("@drawables").map do |sw| + drawable("id:#{sw.linkable_id}") + end + + w.each do |i| + assert i.display.to_html.include?("display:none"), "expected drawable #{i.class} to be hidden!" + end + TEST_CODE + end + def test_app_method run_test_scarpe_code(<<-'SCARPE_APP', app_test_code: <<-'TEST_CODE') class NotADrawable diff --git a/test/test_examples.rb b/test/test_examples.rb index fc1f530a5..9150dbca0 100644 --- a/test/test_examples.rb +++ b/test/test_examples.rb @@ -19,9 +19,9 @@ class TestExamplesWithWebview < ShoesSpecLoggedTest ENV["SCARPE_HTML_RENDERER"] = "calzini" run_test_scarpe_app(example_filename, exit_immediately: true) end - define_method("test_webview_tiranti_#{example}") do - ENV["SCARPE_HTML_RENDERER"] = "tiranti" - run_test_scarpe_app(example_filename, exit_immediately: true) - end + #define_method("test_webview_tiranti_#{example}") do + # ENV["SCARPE_HTML_RENDERER"] = "tiranti" + # run_test_scarpe_app(example_filename, exit_immediately: true) + #end end end