class Glimmer::LibUI::Shape

Represents LibUI lightweight shape objects nested under path (e.g. line, rectangle, arc, bezier)

Attributes

args[R]
block[R]
content_added[R]
content_added?[R]
keyword[R]
parent[R]

Public Class Methods

constant_symbol(keyword) click to toggle source
# File lib/glimmer/libui/shape.rb, line 62
def constant_symbol(keyword)
  "#{keyword.camelcase(:upper)}".to_sym
end
create(keyword, parent, args, &block) click to toggle source
# File lib/glimmer/libui/shape.rb, line 38
def create(keyword, parent, args, &block)
  shape_class(keyword).new(keyword, parent, args, &block)
end
exists?(keyword) click to toggle source
# File lib/glimmer/libui/shape.rb, line 32
def exists?(keyword)
  Shape.constants.include?(constant_symbol(keyword)) and
    shape_class(keyword).respond_to?(:ancestors) and
    shape_class(keyword).ancestors.include?(Shape)
end
new(keyword, parent, args, &block) click to toggle source
# File lib/glimmer/libui/shape.rb, line 73
def initialize(keyword, parent, args, &block)
  @keyword = keyword
  @parent = parent
  @args = args
  @block = block
  set_parameter_defaults
  build_control if implicit_path?
  post_add_content if @block.nil?
end
parameter_defaults(*defaults) click to toggle source
# File lib/glimmer/libui/shape.rb, line 54
def parameter_defaults(*defaults)
  if defaults.empty?
    @parameter_defaults
  else
    @parameter_defaults = defaults
  end
end
parameters(*params) click to toggle source
# File lib/glimmer/libui/shape.rb, line 46
def parameters(*params)
  if params.empty?
    @parameters
  else
    @parameters = params
  end
end
shape_class(keyword) click to toggle source
# File lib/glimmer/libui/shape.rb, line 42
def shape_class(keyword)
  Shape.const_get(constant_symbol(keyword))
end

Public Instance Methods

area_proxy() click to toggle source
# File lib/glimmer/libui/shape.rb, line 123
def area_proxy
  find_parent_in_ancestors { |parent| parent.nil? || parent.is_a?(ControlProxy::AreaProxy) }
end
bounding_box() click to toggle source

Returns bounding box Array consisting of

minx, miny, width, height
# File lib/glimmer/libui/shape.rb, line 170
def bounding_box
  perfect_shape_bounding_box = perfect_shape&.bounding_box
  return if perfect_shape_bounding_box.nil?
  [
    perfect_shape_bounding_box.x,
    perfect_shape_bounding_box.y,
    perfect_shape_bounding_box.width,
    perfect_shape_bounding_box.height,
  ]
end
contain?(*point, outline: false, distance_tolerance: 0) click to toggle source

Returns if shape contains point on the inside when outline is false (default) or if point is on the outline when outline is true distance_tolerance is used when outline is true to enable a fuzz factor in determining if a point lies on the outline (e.g. makes it easier to select a shape by mouse)

# File lib/glimmer/libui/shape.rb, line 154
def contain?(*point, outline: false, distance_tolerance: 0)
  perfect_shape&.contain?(*point, outline: outline, distance_tolerance: distance_tolerance)
end
content(&block) click to toggle source
# File lib/glimmer/libui/shape.rb, line 100
def content(&block)
  Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Libui::ShapeExpression.new, @keyword, {post_add_content: @content_added}, &block)
  request_auto_redraw
end
destroy() click to toggle source
# File lib/glimmer/libui/shape.rb, line 118
def destroy
  return if ControlProxy.main_window_proxy&.destroying?
  @parent.children.delete(self)
end
draw(area_draw_params) click to toggle source

Subclasses must override to perform draw work and call super afterwards to ensure calling destroy when semi-declarative in an on_draw method

# File lib/glimmer/libui/shape.rb, line 106
def draw(area_draw_params)
  destroy if area_proxy.nil?
end
fill(*args) click to toggle source
# File lib/glimmer/libui/shape.rb, line 131
def fill(*args)
  path_proxy.fill(*args)
end
Also aliased as: fill=, set_fill
fill=(*args)
Alias for: fill
include?(*point) click to toggle source

Returns if shape includes point on the inside when filled or if shape includes point on the outline when stroked

# File lib/glimmer/libui/shape.rb, line 160
def include?(*point)
  if fill.empty?
    contain?(*point, outline: true, distance_tolerance: ((stroke[:thickness] || 1) - 1))
  else
    contain?(*point)
  end
end
method_missing(method_name, *args, &block) click to toggle source
Calls superclass method
# File lib/glimmer/libui/shape.rb, line 194
def method_missing(method_name, *args, &block)
  method_name_parameter = method_name.to_s.sub(/=$/, '').sub(/^set_/, '').to_sym
  if self.class.parameters.include?(method_name_parameter)
    method_name = method_name.to_s
    parameter_index = self.class.parameters.index(method_name_parameter)
    if method_name.start_with?('set_') || method_name.end_with?('=') || !args.empty?
      args = [args] if args.size > 1
      if args.first != @args[parameter_index]
        @args[parameter_index] = args.first
        request_auto_redraw
      end
    else
      @args[parameter_index]
    end
  else # TODO consider if there is a need to redirect anything to path proxy or delete this TODO
    super
  end
end
path_proxy() click to toggle source
# File lib/glimmer/libui/shape.rb, line 127
def path_proxy
  find_parent_in_ancestors { |parent| parent.nil? || parent.is_a?(ControlProxy::PathProxy) }
end
perfect_shape() click to toggle source

Returns PerfectShape object matching this shape to enable executing computational geometry algorithms

Subclasses must implement

# File lib/glimmer/libui/shape.rb, line 185
def perfect_shape
  # No Op
end
post_add_content() click to toggle source

Subclasses may override to perform post add_content work (normally must call super)

# File lib/glimmer/libui/shape.rb, line 84
def post_add_content
  unless @content_added
    @parent&.post_initialize_child(self)
    @parent.post_add_content if implicit_path? && dynamic?
    @content_added = true
  end
end
post_initialize_child(child, add_child: true) click to toggle source
# File lib/glimmer/libui/shape.rb, line 92
def post_initialize_child(child, add_child: true)
  if child.is_a?(ControlProxy::MatrixProxy)
    path_proxy.post_initialize_child(child, add_child: add_child)
  else
    super(child, add_child: add_child)
  end
end
redraw() click to toggle source
# File lib/glimmer/libui/shape.rb, line 110
def redraw
  area_proxy&.redraw
end
request_auto_redraw() click to toggle source
# File lib/glimmer/libui/shape.rb, line 114
def request_auto_redraw
  area_proxy&.request_auto_redraw
end
respond_to?(method_name, *args, &block) click to toggle source
Calls superclass method
# File lib/glimmer/libui/shape.rb, line 189
def respond_to?(method_name, *args, &block)
  self.class.parameters.include?(method_name.to_s.sub(/=$/, '').sub(/^set_/, '').to_sym) or
    super(method_name, true)
end
set_fill(*args)
Alias for: fill
set_stroke(*args)
Alias for: stroke
set_transform(matrix = nil)
Alias for: transform
stroke(*args) click to toggle source
# File lib/glimmer/libui/shape.rb, line 137
def stroke(*args)
  path_proxy.stroke(*args)
end
Also aliased as: stroke=, set_stroke
stroke=(*args)
Alias for: stroke
transform(matrix = nil) click to toggle source
# File lib/glimmer/libui/shape.rb, line 143
def transform(matrix = nil)
  path_proxy.transform(matrix)
end
Also aliased as: transform=, set_transform
transform=(matrix = nil)
Alias for: transform

Private Instance Methods

build_control() click to toggle source
# File lib/glimmer/libui/shape.rb, line 215
def build_control
  block = Proc.new {} if dynamic?
  @parent = Glimmer::LibUI::ControlProxy::PathProxy.new('path', @parent, [], &block)
end
dynamic?() click to toggle source
# File lib/glimmer/libui/shape.rb, line 225
def dynamic?
  ((@parent.nil? || (@parent.is_a?(ControlProxy::PathProxy) && @parent.parent_proxy.nil?)) && Glimmer::LibUI::ControlProxy::AreaProxy.current_area_draw_params)
end
find_parent_in_ancestors(&condition) click to toggle source
# File lib/glimmer/libui/shape.rb, line 235
def find_parent_in_ancestors(&condition)
  found = self
  until condition.call(found)
    found = found.respond_to?(:parent_proxy) ? found.parent_proxy : found.parent
  end
  found
end
implicit_path?() click to toggle source

indicates if nested directly under area or on_draw event (having an implicit path not an explicit path parent)

# File lib/glimmer/libui/shape.rb, line 221
def implicit_path?
  @implicit_path ||= !!(@parent.is_a?(Glimmer::LibUI::ControlProxy::AreaProxy) || (@parent.nil? && Glimmer::LibUI::ControlProxy::AreaProxy.current_area_draw_params))
end
set_parameter_defaults() click to toggle source
# File lib/glimmer/libui/shape.rb, line 229
def set_parameter_defaults
  self.class.parameter_defaults.each_with_index do |default, i|
    @args[i] ||= default
  end
end