class Glimmer::LibUI::ControlProxy::ImageProxy

Proxy for LibUI image object and Glimmer custom control

Follows the Proxy Design Pattern

Attributes

data[R]
options[R]
pixels[R]
shapes[R]

Public Class Methods

create(keyword, parent, args, &block) click to toggle source

creates or returns existing instance for passed in arguments if parent is nil and block is nil

# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 39
def create(keyword, parent, args, &block)
  if parent.nil? && block.nil?
    instances[args] ||= new(keyword, parent, args.dup, &block)
  else
    new(keyword, parent, args, &block)
  end
end
instances() click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 47
def instances
  @@instances = {} unless defined? @@instances
  @@instances
end
new(keyword, parent, args, &block) click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 59
def initialize(keyword, parent, args, &block)
  @keyword = keyword
  @parent_proxy = parent
  @options = args.last.is_a?(Hash) ? args.pop : {}
  @args = args
  @block = block
  @enabled = true
  post_add_content if @block.nil?
end

Public Instance Methods

area_image?() click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 178
def area_image?
  @area_image ||= !!(@parent_proxy&.is_a?(AreaProxy) || AreaProxy.current_area_draw_params)
end
destroy() click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 182
def destroy
  return if ControlProxy.main_window_proxy&.destroying?
  deregister_all_custom_listeners
  @parent_proxy&.children&.delete(self)
  ControlProxy.control_proxies.delete(self)
end
draw(area_draw_params) click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 169
def draw(area_draw_params)
  if @shapes.nil?
    load_image
    parse_pixels
    calculate_shapes
  end
  ImagePathRenderer.new(@parent_proxy, @shapes).render
end
file(value = nil) click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 83
def file(value = nil)
  if value.nil?
    @args[0]
  else
    @args[0] = value
    if area_image? && @content_added
      post_add_content
      request_auto_redraw
    end
  end
end
Also aliased as: file=, set_file
file=(value = nil)
Alias for: file
height(value = nil) click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 147
def height(value = nil)
  if value.nil?
    @args.size > 3 ? @args[4] : (@options[:height] || @args[2])
  else
    set_height_variable(value)
    if area_image? && @content_added
      post_add_content
      request_auto_redraw
    end
  end
end
Also aliased as: height=, set_height
height=(value = nil)
Alias for: height
post_add_content() click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 69
def post_add_content
  if area_image?
    @shapes = nil
    super
    if @parent_proxy.nil? && AreaProxy.current_area_draw_params
      draw(AreaProxy.current_area_draw_params)
      destroy
    end
  else # image object not control
    build_control unless @content_added
    super
  end
end
redraw() click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 161
def redraw
  @parent_proxy&.redraw
end
request_auto_redraw() click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 165
def request_auto_redraw
  @parent_proxy&.request_auto_redraw if area_image?
end
set_file(value = nil)
Alias for: file
set_height(value = nil)
Alias for: height
set_width(value = nil)
Alias for: width
set_x(value = nil)
Alias for: x
set_y(value = nil)
Alias for: y
width(value = nil) click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 133
def width(value = nil)
  if value.nil?
    @args.size > 3 ? @args[3] : (@options[:width] || @args[1])
  else
    set_width_variable(value)
    if area_image? && @content_added
      post_add_content
      request_auto_redraw
    end
  end
end
Also aliased as: width=, set_width
width=(value = nil)
Alias for: width
x(value = nil) click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 97
def x(value = nil)
  if value.nil?
    @args.size > 3 ? @args[1] : (@options[:x] || 0)
  else
    if @args.size > 3
      @args[1] = value
    else
      @options[:x] = value
    end
    if area_image? && @content_added
      post_add_content
      request_auto_redraw
    end
  end
end
Also aliased as: x=, set_x
x=(value = nil)
Alias for: x
y(value = nil) click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 115
def y(value = nil)
  if value.nil?
    @args.size > 3 ? @args[2] : (@options[:y] || 0)
  else
    if @args.size > 3
      @args[2] = value
    else
      @options[:y] = value
    end
    if area_image? && @content_added
      post_add_content
      request_auto_redraw
    end
  end
end
Also aliased as: y=, set_y
y=(value = nil)
Alias for: y

Private Instance Methods

build_control() click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 211
def build_control
  unless area_image? # image object
    if file
      load_image
      ImagePartProxy.new('image_part', self, [@data, width, height, width * 4])
    end
    @args[1] = @children.first.args[1] if @children.size == 1 && @args[1].nil?
    @args[2] = @children.first.args[2] if @children.size == 1 && @args[2].nil?
    @libui = ControlProxy.new_control(@keyword, [width, height])
    @libui.tap do
      @children.each {|child| child&.send(:build_control) }
    end
  end
rescue => e
  Glimmer::Config.logger.error {"Failed to load image file: #{file}"}
  Glimmer::Config.logger.error {e.full_message}
  raise e
end
calculate_shapes() click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 267
def calculate_shapes
  @shapes = []
  original_pixels = @pixels.dup
  indexed_original_pixels = Hash[original_pixels.each_with_index.to_a]
  x_offset = x
  y_offset = y
  @pixels.each do |pixel|
    index = indexed_original_pixels[pixel]
    @rectangle_start_x ||= pixel[:x]
    @rectangle_width ||= 1
    if pixel[:x] < width - 1 && pixel[:color] == original_pixels[index + 1][:color]
      @rectangle_width += 1
    else
      if pixel[:x] > 0 && pixel[:color] == original_pixels[index - 1][:color]
        @shapes << {x: x_offset + @rectangle_start_x, y: y_offset + pixel[:y], width: @rectangle_width, height: 1, color: pixel[:color]}
      else
        @shapes << {x: x_offset + pixel[:x], y: y_offset + pixel[:y], width: 1, height: 1, color: pixel[:color]}
      end
      @rectangle_width = 1
      @rectangle_start_x = pixel[:x] == width - 1 ? 0 : pixel[:x] + 1
    end
  end
  @shapes
end
load_image() click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 230
def load_image
  require 'chunky_png'
  canvas = nil
  if file.start_with?('http')
    require 'net/http'
    require 'open-uri'
    uri = URI(file)
    canvas = ChunkyPNG::Canvas.from_string(Net::HTTP.get(uri))
  else
    f = File.open(file)
    canvas = ChunkyPNG::Canvas.from_io(f)
    f.close
  end
  original_width = canvas.width
  original_height = canvas.height
  require 'bigdecimal'
  calculated_width = ((BigDecimal(height)/BigDecimal(original_height))*original_width).to_i if height && !width
  calculated_height = ((BigDecimal(width)/BigDecimal(original_width))*original_height).to_i if width && !height
  canvas.resample_nearest_neighbor!(calculated_width || width, calculated_height || height) if width || height
  @data = canvas.to_rgba_stream
  set_width_variable(canvas.width) unless width
  set_height_variable(canvas.height) unless height
  [@data, width, height]
end
parse_pixels() click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 255
def parse_pixels
  @pixels = height.times.map do |y|
    width.times.map do |x|
      r = @data[(y*width + x)*4].ord
      g = @data[(y*width + x)*4 + 1].ord
      b = @data[(y*width + x)*4 + 2].ord
      a = @data[(y*width + x)*4 + 3].ord
      {x: x, y: y, color: {r: r, g: g, b: b, a: a}}
    end
  end.flatten
end
set_height_variable(value) click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 201
def set_height_variable(value)
  if @args.size > 3
    @args[4] = value
  elsif @options[:height]
    @options[:height] = value
  else
    @args[2] = value
  end
end
set_width_variable(value) click to toggle source
# File lib/glimmer/libui/control_proxy/image_proxy.rb, line 191
def set_width_variable(value)
  if @args.size > 3
    @args[3] = value
  elsif @options[:width]
    @options[:width] = value
  else
    @args[1] = value
  end
end