Class: Shoes::Drawable
- Includes:
- MarginHelper, Colors, Log
- Defined in:
- lacci/lib/shoes.rb,
lacci/lib/shoes/download.rb,
lacci/lib/shoes/drawable.rb,
lacci/lib/shoes/drawables/para.rb
Overview
Shoes::Drawable
This is the display-service portable Shoes Drawable interface. Visible Shoes drawables like buttons inherit from this. Compound drawables made of multiple different smaller Drawables inherit from it in their various apps or libraries. The Shoes Drawable helps build a Shoes-side drawable tree, with parents and children. Any API that applies to all drawables (e.g. remove) should be defined here.
Direct Known Subclasses
App, Arc, Arrow, Border, Button, Check, EditBox, EditLine, Image, Line, ListBox, Oval, Para, Progress, Radio, Rect, Slot, Star, SubscriptionItem, TextDrawable, Video
Defined Under Namespace
Classes: ResponseWrapper
Constant Summary collapse
- DRAW_CONTEXT_STYLES =
These styles can be set to a current per-slot value and inherited from parent slots. Their value is set at drawable-create time.
[:fill, :stroke, :strokewidth, :rotate, :transform, :translate]
Constants included from Log
Log::DEFAULT_COMPONENT, Log::DEFAULT_DEBUG_LOG_CONFIG, Log::DEFAULT_LOG_CONFIG
Class Attribute Summary collapse
-
.drawable_classes ⇒ Object
Returns the value of attribute drawable_classes.
-
.drawable_default_styles ⇒ Object
Returns the value of attribute drawable_default_styles.
-
.widget_classes ⇒ Object
Returns the value of attribute widget_classes.
Instance Attribute Summary collapse
-
#debug_id ⇒ Object
readonly
Returns the value of attribute debug_id.
-
#destroyed ⇒ Object
readonly
Returns the value of attribute destroyed.
-
#parent ⇒ Object
readonly
Returns the value of attribute parent.
Attributes inherited from Linkable
Class Method Summary collapse
-
.allocate_drawable_id ⇒ Object
Assign a new Shoes Drawable ID number, starting from 1.
- .convert_to_float(value, attribute_name) ⇒ Object
- .convert_to_integer(value, attribute_name) ⇒ Object
- .drawable_by_id(id, none_ok: false) ⇒ Object
- .drawable_class_by_name(name) ⇒ Object
- .dsl_name ⇒ Object
- .expects_parent? ⇒ Boolean
-
.feature_for_shoes_style(style_name) ⇒ Object
Query what feature, if any, is required to use a specific shoes_style.
-
.get_shoes_events ⇒ Object
Return a list of Shoes events for this class.
-
.init_args(*args) ⇒ void
Require supplying these Shoes style values as positional arguments to initialize.
- .is_widget_class?(name) ⇒ Boolean
-
.opt_init_args(*args) ⇒ void
Allow supplying these Shoes style values as optional positional arguments to initialize after the mandatory args.
-
.optional_init_args ⇒ Array<String>
Return the list of style names for optional init args for this class.
- .register_drawable_id(id, drawable) ⇒ Object
-
.registered_shoes_events? ⇒ Boolean
Return whether Shoes events have already been registered for this class.
-
.required_init_args ⇒ Array<String>
Return the list of style names for required init args for this class.
-
.shoes_events(*args) ⇒ void
Set the list of Shoes event names that are allowed for this class.
-
.shoes_style(name, feature: nil, &validator) ⇒ Object
Shoes styles in Shoes Linkables are automatically sync'd with the display side objects.
- .shoes_style_hashes ⇒ Object
- .shoes_style_name?(name) ⇒ Boolean
-
.shoes_style_names(with_features: nil) ⇒ Object
Return a list of shoes_style names with the given features.
-
.shoes_styles(*names, feature: nil, &validator) ⇒ Object
Add these names as Shoes styles with the given validator and feature, if any.
- .unregister_drawable_id(id) ⇒ Object
- .validate_as(prop_name, value) ⇒ Object
Instance Method Summary collapse
-
#app { ... } ⇒ Shoes::App
Calling stack.app or drawable.app will execute the block with the Shoes::App as self, and with that stack or flow as the current slot.
-
#banner(*args, **kwargs) ⇒ Shoes::Para
Return a banner-sized para.
-
#caption(*args, **kwargs) ⇒ Shoes::Para
Return a caption-sized para.
-
#destroy ⇒ Object
(also: #remove)
Removes the element from the Shoes::Drawable tree and removes all event subscriptions.
- #download(url, method: "GET", save: nil, styles: {}, &block) ⇒ Object
- #event(event_name, *args, **kwargs) ⇒ Object
-
#hide ⇒ Object
Hide the drawable.
-
#hover { ... } ⇒ Object
Set the hover handler.
-
#initialize(*args, **kwargs) ⇒ Drawable
constructor
A new instance of Drawable.
-
#inscription(*args, **kwargs) ⇒ Shoes::Para
Return an inscription-sized para.
- #inspect ⇒ Object
-
#leave { ... } ⇒ Object
Set the leave handler.
-
#method_missing(name, *args, **kwargs, &block) ⇒ Object
We use method_missing to auto-create Shoes style getters and setters.
-
#motion { ... } ⇒ Object
Set the motion handler, called with x and y coordinates as params.
- #respond_to_missing?(name, include_private = false) ⇒ Boolean
-
#set_parent(new_parent, notify: true) ⇒ Object
Set the Drawable's parent drawable.
- #shoes_style_values ⇒ Object
-
#show ⇒ Object
Show the drawable.
- #style(*args, **kwargs) ⇒ Object
-
#subtitle(*args, **kwargs) ⇒ Shoes::Para
Return a subtitle-sized para.
-
#tagline(*args, **kwargs) ⇒ Shoes::Para
Return a tagline-sized para.
-
#title(*args, **kwargs) ⇒ Shoes::Para
Return a title-sized para.
-
#toggle ⇒ Object
Hide the drawable if it is currently shown.
Methods included from MarginHelper
Methods included from Colors
Methods included from Log
configure_logger, #log_init, logger
Methods inherited from Linkable
#bind_shoes_event, #send_self_event, #send_shoes_event, #unsub_all_shoes_events, #unsub_shoes_event
Constructor Details
#initialize(*args, **kwargs) ⇒ Drawable
Returns a new instance of Drawable.
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 |
# File 'lacci/lib/shoes/drawable.rb', line 261 def initialize(*args, **kwargs) kwargs = margin_parse(kwargs) log_init("Shoes::#{self.class.name}") unless @log # First, get the list of allowed and disallowed styles for the given features # and make sure no disallowed styles were given. app_features = Shoes::App.instance.features this_app_styles = self.class.shoes_style_names.map(&:to_sym) not_this_app_styles = self.class.shoes_style_names(with_features: :all).map(&:to_sym) - this_app_styles bad_styles = kwargs.keys & not_this_app_styles unless bad_styles.empty? features_needed = bad_styles.map { |s| self.class.feature_for_shoes_style(s) }.uniq raise Shoes::Errors::UnsupportedFeatureError, "The style(s) #{bad_styles.inspect} are only defined for applications that request specific features: #{features_needed.inspect} (you requested #{app_features.inspect})!" end # Next, check positional arguments and make sure the correct number and type # were passed and match positional args with style names. supplied_args = kwargs.keys req_args = self.class.required_init_args opt_args = self.class.optional_init_args pos_args = req_args + opt_args if req_args != ["any"] if args.size > pos_args.size raise Shoes::Errors::BadArgumentListError, "Too many arguments given for #{self.class}#initialize! #{args.inspect}" end if args.size == 0 # It's fine to use keyword args instead, but we should make sure they're actually there needed_args = req_args.map(&:to_sym) - kwargs.keys unless needed_args.empty? raise Shoes::Errors::BadArgumentListError, "Keyword arguments for #{self.class}#initialize should also supply #{needed_args.inspect}! #{args.inspect}" end elsif args.size < req_args.size raise Shoes::Errors::BadArgumentListError, "Too few 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 this_drawable_styles = self.class.shoes_style_names.map(&:to_sym) dc = Shoes::App.instance.current_draw_context || {} # Styles not passed as arguments can come from the draw context # What styles are in the draw context, are used by this drawable, and weren't # given as positional or keyword arguments? draw_context_styles = (DRAW_CONTEXT_STYLES & this_drawable_styles) - supplied_args unless draw_context_styles.empty? # When we first call this, there is no parent. We don't want to set the parent # yet because that will send a notification, and *that* should wait until after # we've told the display service that this drawable was created. So instead # we'll query the parent object's draw context directly. draw_context_styles.each do |style| dc_val = dc[style.to_s] next if dc_val.nil? val = self.class.validate_as(style, dc[style.to_s]) instance_variable_set("@#{style}", val) supplied_args << style end end # Styles that were *not* passed should be set to defaults default_styles = Shoes::Drawable.drawable_default_styles[self.class] # 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 # If we have a keyword arg for a style, set it as specified. (this_drawable_styles & kwargs.keys).each do |key| val = self.class.validate_as(key, kwargs[key]) instance_variable_set("@#{key}", val) end # 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}" end super(linkable_id: Shoes::Drawable.allocate_drawable_id) Shoes::Drawable.register_drawable_id(self.linkable_id, self) generate_debug_id parent = ::Shoes::App.instance.current_slot if self.class.expects_parent? set_parent(parent, notify: false) end unless self.class.registered_shoes_events? # No Shoes events declared and we're creating an instance? # Default to no class-specific events. self.class.shoes_events end # Binding the motion events here isn't perfect. # What about drawables like SubscriptionItem that # have no motion events? With the current Lacci # implementation, the answer is that those events # will never be sent. Calling .hover on one will # be useless, harmless, and allowed. If you want # to make it disallowed, you can do something like # define a SubscriptionItem#hover that raises an # exception instead. bind_self_event("hover") do @hover&.call end bind_self_event("leave") do @leave&.call end bind_self_event("motion") do |x, y| @motion&.call(x, y) end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, **kwargs, &block) ⇒ Object
We use method_missing to auto-create Shoes style getters and setters.
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 |
# File 'lacci/lib/shoes/drawable.rb', line 590 def method_missing(name, *args, **kwargs, &block) name_s = name.to_s if name_s[-1] == "=" prop_name = name_s[0..-2] if self.class.shoes_style_name?(prop_name) self.class.define_method(name) do |new_value| raise(Shoes::Errors::NoSuchLinkableIdError, "Trying to set Shoes styles in a #{self.class} with no linkable ID!") unless linkable_id new_value = self.class.validate_as(prop_name, new_value) instance_variable_set("@" + prop_name, new_value) send_shoes_event({ prop_name => new_value }, event_name: "prop_change", target: linkable_id) end return self.send(name, *args, **kwargs, &block) end end if self.class.shoes_style_name?(name_s) self.class.define_method(name) do raise(Shoes::Errors::NoSuchLinkableIdError, "Trying to get Shoes styles in an object with no linkable ID! #{inspect}") unless linkable_id instance_variable_get("@" + name_s) end return self.send(name, *args, **kwargs, &block) end super(name, *args, **kwargs, &block) end |
Class Attribute Details
.drawable_classes ⇒ Object
Returns the value of attribute drawable_classes.
21 22 23 |
# File 'lacci/lib/shoes/drawable.rb', line 21 def drawable_classes @drawable_classes end |
.drawable_default_styles ⇒ Object
Returns the value of attribute drawable_default_styles.
22 23 24 |
# File 'lacci/lib/shoes/drawable.rb', line 22 def drawable_default_styles @drawable_default_styles end |
.widget_classes ⇒ Object
Returns the value of attribute widget_classes.
23 24 25 |
# File 'lacci/lib/shoes/drawable.rb', line 23 def @widget_classes end |
Instance Attribute Details
#debug_id ⇒ Object (readonly)
Returns the value of attribute debug_id.
253 254 255 |
# File 'lacci/lib/shoes/drawable.rb', line 253 def debug_id @debug_id end |
#destroyed ⇒ Object (readonly)
Returns the value of attribute destroyed.
526 527 528 |
# File 'lacci/lib/shoes/drawable.rb', line 526 def destroyed @destroyed end |
#parent ⇒ Object (readonly)
Returns the value of attribute parent.
525 526 527 |
# File 'lacci/lib/shoes/drawable.rb', line 525 def parent @parent end |
Class Method Details
.allocate_drawable_id ⇒ Object
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 widget you're talking about.
137 138 139 140 141 |
# File 'lacci/lib/shoes/drawable.rb', line 137 def allocate_drawable_id @drawable_id_counter ||= 0 @drawable_id_counter += 1 @drawable_id_counter end |
.convert_to_float(value, attribute_name) ⇒ Object
642 643 644 645 646 647 648 649 650 651 652 |
# File 'lacci/lib/shoes/drawable.rb', line 642 def self.convert_to_float(value, attribute_name) begin value = Float(value) raise Shoes::Errors::InvalidAttributeValueError, "Negative number '#{value}' not allowed for attribute '#{attribute_name}'" if value < 0 value rescue ArgumentError = "Invalid value '#{value}' provided for attribute '#{attribute_name}'. The value should be a number." raise Shoes::Errors::InvalidAttributeValueError, end end |
.convert_to_integer(value, attribute_name) ⇒ Object
630 631 632 633 634 635 636 637 638 639 640 |
# File 'lacci/lib/shoes/drawable.rb', line 630 def self.convert_to_integer(value, attribute_name) begin value = Integer(value) raise Shoes::Errors::InvalidAttributeValueError, "Negative number '#{value}' not allowed for attribute '#{attribute_name}'" if value < 0 value rescue ArgumentError = "Invalid value '#{value}' provided for attribute '#{attribute_name}'. The value should be a number." raise Shoes::Errors::InvalidAttributeValueError, end end |
.drawable_by_id(id, none_ok: false) ⇒ Object
153 154 155 156 157 158 159 160 |
# File 'lacci/lib/shoes/drawable.rb', line 153 def drawable_by_id(id, none_ok: false) val = @drawables_by_id[id] unless val || none_ok raise "No Drawable Found! #{@drawables_by_id.inspect}" end val end |
.drawable_class_by_name(name) ⇒ Object
45 46 47 48 |
# File 'lacci/lib/shoes/drawable.rb', line 45 def drawable_class_by_name(name) name = name.to_s drawable_classes.detect { |k| k.dsl_name == name } end |
.dsl_name ⇒ Object
40 41 42 43 |
# File 'lacci/lib/shoes/drawable.rb', line 40 def dsl_name n = name.split("::").last.chomp("Drawable") n.gsub(/(.)([A-Z])/, '\1_\2').downcase end |
.expects_parent? ⇒ Boolean
400 401 402 403 404 405 |
# File 'lacci/lib/shoes/drawable.rb', line 400 def self.expects_parent? return false if [::Shoes::App, ::Shoes::DocumentRoot].include?(self) return false if self < ::Shoes::TextDrawable true end |
.feature_for_shoes_style(style_name) ⇒ Object
Query what feature, if any, is required to use a specific shoes_style. If no specific feature is needed, nil will be returned.
200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lacci/lib/shoes/drawable.rb', line 200 def feature_for_shoes_style(style_name) style_name = style_name.to_s lp = linkable_properties.detect { |prop| prop[:name] == style_name } return lp[:feature] if lp # If we get to the top of the superclass tree and we didn't find it, it's not here if self.class == ::Shoes::Drawable raise Shoes::Errors::NoSuchStyleError, "Can't find information for style #{style_name.inspect}!" end super end |
.get_shoes_events ⇒ Object
Return a list of Shoes events for this class.
70 71 72 73 74 75 76 |
# File 'lacci/lib/shoes/drawable.rb', line 70 def get_shoes_events if @shoes_events.nil? raise Shoes::Errors::UnknownEventsForClassError, "Drawable type #{self} hasn't defined its list of Shoes events!" end @shoes_events end |
.init_args(*args) ⇒ void
This method returns an undefined value.
Require supplying these 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. @see opt_init_args for additional non-required init args.
103 104 105 106 |
# File 'lacci/lib/shoes/drawable.rb', line 103 def init_args(*args) raise Shoes::Errors::BadArgumentListError, "Positional init args already set for #{self}!" if @required_init_args @required_init_args = args.map(&:to_s) end |
.is_widget_class?(name) ⇒ Boolean
50 51 52 |
# File 'lacci/lib/shoes/drawable.rb', line 50 def (name) !!Shoes::Drawable..intersect?([name.to_s]) end |
.opt_init_args(*args) ⇒ void
This method returns an undefined value.
Allow supplying these Shoes style values as optional positional arguments to initialize after the mandatory args. @see init_args for setting required init args.
114 115 116 117 |
# File 'lacci/lib/shoes/drawable.rb', line 114 def opt_init_args(*args) raise Shoes::Errors::BadArgumentListError, "Positional init args already set for #{self}!" if @opt_init_args @opt_init_args = args.map(&:to_s) end |
.optional_init_args ⇒ Array<String>
Return the list of style names for optional init args for this class
129 130 131 |
# File 'lacci/lib/shoes/drawable.rb', line 129 def optional_init_args @opt_init_args ||= [] end |
.register_drawable_id(id, drawable) ⇒ Object
143 144 145 146 |
# File 'lacci/lib/shoes/drawable.rb', line 143 def register_drawable_id(id, drawable) @drawables_by_id ||= {} @drawables_by_id[id] = drawable end |
.registered_shoes_events? ⇒ Boolean
Return whether Shoes events have already been registered for this class
81 82 83 |
# File 'lacci/lib/shoes/drawable.rb', line 81 def registered_shoes_events? !@shoes_events.nil? end |
.required_init_args ⇒ Array<String>
Return the list of style names for required init args for this class
122 123 124 |
# File 'lacci/lib/shoes/drawable.rb', line 122 def required_init_args @required_init_args ||= [] # TODO: eventually remove the ||= here end |
.shoes_events(*args) ⇒ void
This method returns an undefined value.
Set the list of Shoes event names that are allowed for this class.
89 90 91 92 93 94 |
# File 'lacci/lib/shoes/drawable.rb', line 89 def shoes_events(*args) if @shoes_events raise Shoes::Errors::DoubleRegisteredShoesEventError, "Registering shoes events #{args.inspect} for class #{self} but already registered events as #{@shoes_events.inspect}!" end @shoes_events = args.map(&:to_s) + self.superclass.get_shoes_events end |
.shoes_style(name, feature: nil, &validator) ⇒ Object
Shoes styles in Shoes Linkables are automatically sync'd with the display side objects. If a block is passed to shoes_style, that's the validation for the property. It should convert a given value to a valid value for the property or throw an exception.
If feature is non-nil, it's the feature that an app must request in order to see this property.
184 185 186 187 188 189 190 191 |
# File 'lacci/lib/shoes/drawable.rb', line 184 def shoes_style(name, feature: nil, &validator) name = name.to_s return if linkable_properties_hash[name] linkable_properties << { name: name, validator:, feature: } linkable_properties_hash[name] = true end |
.shoes_style_hashes ⇒ Object
229 230 231 232 233 |
# File 'lacci/lib/shoes/drawable.rb', line 229 def shoes_style_hashes parent_hashes = self != Shoes::Drawable ? self.superclass.shoes_style_hashes : [] parent_hashes + linkable_properties end |
.shoes_style_name?(name) ⇒ Boolean
235 236 237 238 |
# File 'lacci/lib/shoes/drawable.rb', line 235 def shoes_style_name?(name) linkable_properties_hash[name.to_s] || (self != Shoes::Drawable && superclass.shoes_style_name?(name)) end |
.shoes_style_names(with_features: nil) ⇒ Object
Return a list of shoes_style names with the given features. If with_features is nil, return them with a list of features for the current Shoes::App. For the list of styles available with no features requested, pass nil to with_features.
216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lacci/lib/shoes/drawable.rb', line 216 def shoes_style_names(with_features: nil) # No with_features given? Use the ones requested by this Shoes::App with_features ||= Shoes::App.instance.features parent_prop_names = self != Shoes::Drawable ? self.superclass.shoes_style_names(with_features:) : [] if with_features == :all subclass_props = linkable_properties else subclass_props = linkable_properties.select { |prop| !prop[:feature] || with_features.include?(prop[:feature]) } end parent_prop_names | subclass_props.map { |prop| prop[:name] } end |
.shoes_styles(*names, feature: nil, &validator) ⇒ Object
Add these names as Shoes styles with the given validator and feature, if any
194 195 196 |
# File 'lacci/lib/shoes/drawable.rb', line 194 def shoes_styles(*names, feature: nil, &validator) names.each { |n| shoes_style(n, feature:, &validator) } end |
.unregister_drawable_id(id) ⇒ Object
148 149 150 151 |
# File 'lacci/lib/shoes/drawable.rb', line 148 def unregister_drawable_id(id) @drawables_by_id ||= {} @drawables_by_id.delete(id) end |
.validate_as(prop_name, value) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lacci/lib/shoes/drawable.rb', line 54 def validate_as(prop_name, value) prop_name = prop_name.to_s hashes = shoes_style_hashes h = hashes.detect { |hash| hash[:name] == prop_name } raise(Shoes::Errors::NoSuchStyleError, "Can't find property #{prop_name.inspect} in #{self} property list: #{hashes.inspect}!") unless h return value if h[:validator].nil? # Pass both the property name and value to the validator block h[:validator].call(value,prop_name) end |
Instance Method Details
#app { ... } ⇒ Shoes::App
Calling stack.app or drawable.app will execute the block with the Shoes::App as self, and with that stack or flow as the current slot.
418 419 420 421 |
# File 'lacci/lib/shoes/drawable.rb', line 418 def app(&block) Shoes::App.instance.with_slot(self, &block) if block_given? Shoes::App.instance end |
#banner(*args, **kwargs) ⇒ Shoes::Para
Return a banner-sized para. This can use all the normal Para styles and arguments. See Para#initialize for details.
157 158 159 |
# File 'lacci/lib/shoes/drawables/para.rb', line 157 def (*args, **kwargs) para(*args, **{ size: :banner }.merge(kwargs)) end |
#caption(*args, **kwargs) ⇒ Shoes::Para
Return a caption-sized para. This can use all the normal Para styles and arguments. See Para#initialize for details.
193 194 195 |
# File 'lacci/lib/shoes/drawables/para.rb', line 193 def (*args, **kwargs) para(*args, **{ size: :caption }.merge(kwargs)) end |
#destroy ⇒ Object Also known as: remove
Removes the element from the Shoes::Drawable tree and removes all event subscriptions
542 543 544 545 546 547 548 549 |
# File 'lacci/lib/shoes/drawable.rb', line 542 def destroy @parent&.remove_child(self) @parent = nil @destroyed = true unsub_all_shoes_events send_shoes_event(event_name: "destroy", target: linkable_id) Shoes::Drawable.unregister_drawable_id(linkable_id) end |
#download(url, method: "GET", save: nil, styles: {}, &block) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lacci/lib/shoes/download.rb', line 21 def download(url, method: "GET", save: nil, styles: {}, &block) require "net/http" require "openssl" require "nokogiri" @block = block Thread.new do logger = Shoes::Log.logger("Shoes::App#download") begin uri = URI(url) response = perform_request(uri, method, styles) if response.is_a?(Net::HTTPRedirection) new_location = response["location"] new_uri = URI(new_location) response = perform_request(new_uri, method, styles) end wrapped_response = ResponseWrapper.new(response) # Wrap the response handle_response(wrapped_response, save, styles) rescue Net::HTTPError, Net::OpenTimeout, Net::ReadTimeout => e handle_error(e, logger) rescue StandardError => e handle_error(e., logger) # Pass the error message as a string end end end |
#event(event_name, *args, **kwargs) ⇒ Object
468 469 470 471 472 |
# File 'lacci/lib/shoes/drawable.rb', line 468 def event(event_name, *args, **kwargs) validate_event_name(event_name) send_shoes_event(*args, **kwargs, event_name:, target: linkable_id) end |
#hide ⇒ Object
Hide the drawable.
553 554 555 |
# File 'lacci/lib/shoes/drawable.rb', line 553 def hide self.hidden = true end |
#hover { ... } ⇒ Object
Set the hover handler. Not every drawable may do something useful with this.
570 571 572 |
# File 'lacci/lib/shoes/drawable.rb', line 570 def hover(&block) @hover = block end |
#inscription(*args, **kwargs) ⇒ Shoes::Para
Return an inscription-sized para. This can use all the normal Para styles and arguments. See Para#initialize for details.
202 203 204 |
# File 'lacci/lib/shoes/drawables/para.rb', line 202 def inscription(*args, **kwargs) para(*args, **{ size: :inscription }.merge(kwargs)) end |
#inspect ⇒ Object
437 438 439 440 441 |
# File 'lacci/lib/shoes/drawable.rb', line 437 def inspect "#<#{debug_id} " + " @parent=#{@parent ? @parent.debug_id : "(none)"} " + "@children=#{@children ? @children.map(&:debug_id) : "(none)"} properties=#{shoes_style_values.inspect}>" end |
#leave { ... } ⇒ Object
Set the leave handler. Not every drawable may do something useful with this.
577 578 579 |
# File 'lacci/lib/shoes/drawable.rb', line 577 def leave(&block) @leave = block end |
#motion { ... } ⇒ Object
Set the motion handler, called with x and y coordinates as params. Not every drawable may do something useful with this.
585 586 587 |
# File 'lacci/lib/shoes/drawable.rb', line 585 def motion(&block) @motion = block end |
#respond_to_missing?(name, include_private = false) ⇒ Boolean
621 622 623 624 625 626 627 628 |
# File 'lacci/lib/shoes/drawable.rb', line 621 def respond_to_missing?(name, include_private = false) name_s = name.to_s return true if self.class.shoes_style_name?(name_s) return true if self.class.shoes_style_name?(name_s[0..-2]) && name_s[-1] == "=" return true if Drawable.drawable_class_by_name(name_s) super end |
#set_parent(new_parent, notify: true) ⇒ Object
Set the Drawable's parent drawable. Notify the display service that the parent has changed unless instructed not to. We don't notify when first creating the Drawable. The create event that is first sent will include the parent.
532 533 534 535 536 537 538 539 |
# File 'lacci/lib/shoes/drawable.rb', line 532 def set_parent(new_parent, notify: true) @parent&.remove_child(self) new_parent&.add_child(self) @parent = new_parent return unless notify send_shoes_event(new_parent&.linkable_id, event_name: "parent", target: linkable_id) end |
#shoes_style_values ⇒ Object
474 475 476 477 478 479 480 481 482 483 |
# File 'lacci/lib/shoes/drawable.rb', line 474 def shoes_style_values all_property_names = self.class.shoes_style_names properties = {} all_property_names.each do |prop| properties[prop] = instance_variable_get("@" + prop) end properties["shoes_linkable_id"] = self.linkable_id properties end |
#show ⇒ Object
Show the drawable.
558 559 560 |
# File 'lacci/lib/shoes/drawable.rb', line 558 def show self.hidden = false end |
#style(*args, **kwargs) ⇒ Object
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 |
# File 'lacci/lib/shoes/drawable.rb', line 485 def style(*args, **kwargs) if args.empty? && kwargs.empty? # Just called as .style() shoes_style_values elsif args.empty? # This is called to set one or more Shoes styles prop_names = self.class.shoes_style_names unknown_styles = kwargs.keys.select { |k| !prop_names.include?(k.to_s) } unless unknown_styles.empty? raise Shoes::Errors::NoSuchStyleError, "Unknown styles for drawable type #{self.class.name}: #{unknown_styles.join(", ")}" end kwargs.each do |name, val| instance_variable_set("@#{name}", val) end elsif args.length == 1 && args[0] < Shoes::Drawable # Shoes supports calling .style with a Shoes class, e.g. .style(Shoes::Button, displace_left: 5) kwargs.each do |name, val| Shoes::Drawable.drawable_default_styles[args[0]][name.to_sym] = val end else raise Shoes::Errors::InvalidAttributeValueError, "Unexpected arguments to style! args: #{args.inspect}, keyword args: #{kwargs.inspect}" end end |
#subtitle(*args, **kwargs) ⇒ Shoes::Para
Return a subtitle-sized para. This can use all the normal Para styles and arguments. See Para#initialize for details.
175 176 177 |
# File 'lacci/lib/shoes/drawables/para.rb', line 175 def subtitle(*args, **kwargs) para(*args, **{ size: :subtitle }.merge(kwargs)) end |
#tagline(*args, **kwargs) ⇒ Shoes::Para
Return a tagline-sized para. This can use all the normal Para styles and arguments. See Para#initialize for details.
184 185 186 |
# File 'lacci/lib/shoes/drawables/para.rb', line 184 def tagline(*args, **kwargs) para(*args, **{ size: :tagline }.merge(kwargs)) end |
#title(*args, **kwargs) ⇒ Shoes::Para
Return a title-sized para. This can use all the normal Para styles and arguments. See Para#initialize for details.
166 167 168 |
# File 'lacci/lib/shoes/drawables/para.rb', line 166 def title(*args, **kwargs) para(*args, **{ size: :title }.merge(kwargs)) end |
#toggle ⇒ Object
Hide the drawable if it is currently shown. Show it if it is currently hidden.
563 564 565 |
# File 'lacci/lib/shoes/drawable.rb', line 563 def toggle self.hidden = !self.hidden end |