Skip to content

Commit

Permalink
Update drawables to use positional arguments.
Browse files Browse the repository at this point in the history
  • Loading branch information
noahgibbs committed Dec 5, 2023
1 parent e8e8986 commit 1fd0a36
Show file tree
Hide file tree
Showing 32 changed files with 317 additions and 98 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ logger/*.log
**/lacci-*.gem
*scarpe*.gem
**/sspec.json
examples/legacy/working/shoes_manual/nasa50th.gif
5 changes: 5 additions & 0 deletions lacci/lib/shoes/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def initialize(
@draw_context = {
"fill" => "",
"stroke" => "",
"strokewidth" => 2,
"rotate" => 0,
}

Expand Down Expand Up @@ -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
Expand Down
51 changes: 45 additions & 6 deletions lacci/lib/shoes/drawable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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<String,Symbol>] 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<String>] 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
Expand Down Expand Up @@ -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

Expand All @@ -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}"
Expand Down
4 changes: 2 additions & 2 deletions lacci/lib/shoes/drawables/arc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 2 additions & 10 deletions lacci/lib/shoes/drawables/arrow.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
9 changes: 2 additions & 7 deletions lacci/lib/shoes/drawables/button.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down
3 changes: 2 additions & 1 deletion lacci/lib/shoes/drawables/check.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 3 additions & 3 deletions lacci/lib/shoes/drawables/edit_box.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions lacci/lib/shoes/drawables/edit_line.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions lacci/lib/shoes/drawables/image.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 4 additions & 7 deletions lacci/lib/shoes/drawables/line.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 4 additions & 5 deletions lacci/lib/shoes/drawables/link.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 8 additions & 5 deletions lacci/lib/shoes/drawables/list_box.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
34 changes: 25 additions & 9 deletions lacci/lib/shoes/drawables/oval.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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") }
Expand All @@ -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

Expand Down
9 changes: 7 additions & 2 deletions lacci/lib/shoes/drawables/para.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
3 changes: 2 additions & 1 deletion lacci/lib/shoes/drawables/progress.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 4 additions & 3 deletions lacci/lib/shoes/drawables/radio.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions lacci/lib/shoes/drawables/rect.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 1fd0a36

Please sign in to comment.