class CyberarmEngine::Element

Attributes

background_canvas[R]
border_canvas[R]
enabled[RW]
event_handler[R]
options[R]
parent[R]
style[R]
tip[RW]
x[RW]
y[RW]
z[RW]

Public Class Methods

new(options = {}, block = nil) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 10
def initialize(options = {}, block = nil)
  @parent = options.delete(:parent) # parent Container (i.e. flow/stack)
  options = theme_defaults(options)
  @options = options
  @block = block

  @focus   = @options[:focus].nil?   ? false : @options[:focus]
  @enabled = @options[:enabled].nil? ? true  : @options[:enabled]
  @visible = @options[:visible].nil? ? true  : @options[:visible]
  @tip     = @options[:tip] || ""

  @debug_color = @options[:debug_color].nil? ? Gosu::Color::RED : @options[:debug_color]

  @style = Style.new(options)

  @root ||= nil
  @gui_state ||= nil

  @x = @style.x
  @y = @style.y
  @z = @style.z

  @width  = 0
  @height = 0

  @style.width  = default(:width)  || nil
  @style.height = default(:height) || nil

  @style.background_canvas = Background.new
  @style.border_canvas     = BorderCanvas.new(element: self)

  @style_event = :default

  stylize

  default_events

  root.gui_state.request_focus(self) if @options[:autofocus]
end

Public Instance Methods

background=(_background) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 373
def background=(_background)
  @style.background_canvas.background = _background
  update_background
end
blur(_sender) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 203
def blur(_sender)
  @focus = false

  if @enabled
    update_styles
  else
    update_styles(:disabled)
  end

  :handled
end
button_down(id) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 279
def button_down(id)
end
button_up(id) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 282
def button_up(id)
end
clicked_left_mouse_button(_sender, _x, _y) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 187
def clicked_left_mouse_button(_sender, _x, _y)
  @block&.call(self) if @enabled && !self.is_a?(Container)

  :handled
end
content_height() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 329
def content_height
  @height
end
content_width() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 305
def content_width
  @width
end
debug_draw() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 251
def debug_draw
  return if defined?(GUI_DEBUG_ONLY_ELEMENT) && self.class == GUI_DEBUG_ONLY_ELEMENT

  Gosu.draw_line(
    x, y, @debug_color,
    x + outer_width, y, @debug_color,
    Float::INFINITY
  )
  Gosu.draw_line(
    x + outer_width, y, @debug_color,
    x + outer_width, y + outer_height, @debug_color,
    Float::INFINITY
  )
  Gosu.draw_line(
    x + outer_width, y + outer_height, @debug_color,
    x, y + outer_height, @debug_color,
    Float::INFINITY
  )
  Gosu.draw_line(
    x, outer_height, @debug_color,
    x, y, @debug_color,
    Float::INFINITY
  )
end
default_events() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 132
def default_events
  %i[left middle right].each do |button|
    event(:"#{button}_mouse_button")
    event(:"released_#{button}_mouse_button")
    event(:"clicked_#{button}_mouse_button")
    event(:"holding_#{button}_mouse_button")
  end

  event(:mouse_wheel_up)
  event(:mouse_wheel_down)

  event(:enter)
  event(:hover)
  event(:leave)

  event(:focus)
  event(:blur)

  event(:changed)
end
dimensional_size(size, dimension) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 361
def dimensional_size(size, dimension)
  raise "dimension must be either :width or :height" unless %i[width height].include?(dimension)

  if size && size.is_a?(Numeric)
    if size.between?(0.0, 1.0)
      ((@parent.send(:"content_#{dimension}") - send(:"noncontent_#{dimension}")) * size).round
    else
      size
    end
  end
end
draggable?(_button) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 285
def draggable?(_button)
  false
end
draw() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 240
def draw
  return unless visible?

  @style.background_canvas.draw
  @style.border_canvas.draw

  Gosu.clip_to(@x, @y, width, height) do
    render
  end
end
enabled?() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 215
def enabled?
  @enabled
end
enter(_sender) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 153
def enter(_sender)
  @focus = false unless window.button_down?(Gosu::MsLeft)

  if !@enabled
    update_styles(:disabled)
  elsif @focus
    update_styles(:active)
  else
    update_styles(:hover)
  end

  :handled
end
focus(_) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 410
def focus(_)
  warn "#{self.class}#focus was not overridden!"

  :handled
end
height() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 321
def height
  if visible?
    inner_height + @height
  else
    0
  end
end
hide() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 234
def hide
  bool = visible?
  @visible = false
  root.gui_state.request_recalculate if bool
end
hit?(x, y) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 292
def hit?(x, y)
  x.between?(@x, @x + width) &&
    y.between?(@y, @y + height)
end
inner_height() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 341
def inner_height
  (@style.border_thickness_top + @style.padding_top) + (@style.padding_bottom + @style.border_thickness_bottom)
end
inner_width() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 317
def inner_width
  (@style.border_thickness_left + @style.padding_left) + (@style.padding_right + @style.border_thickness_right)
end
inspect() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 435
def inspect
  to_s
end
is_root?() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 406
def is_root?
  @gui_state != nil
end
leave(_sender) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 193
def leave(_sender)
  if @enabled
    update_styles
  else
    update_styles(:disabled)
  end

  :handled
end
left_mouse_button(_sender, _x, _y) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 167
def left_mouse_button(_sender, _x, _y)
  @focus = true

  unless @enabled
    update_styles(:disabled)
  else
    update_styles(:active)
  end

  window.current_state.focus = self

  :handled
end
max_scroll_height() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 357
def max_scroll_height
  scroll_height - height
end
max_scroll_width() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 353
def max_scroll_width
  scroll_width - width
end
noncontent_height() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 333
def noncontent_height
  (inner_height + outer_height) - height
end
noncontent_width() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 309
def noncontent_width
  (inner_width + outer_width) - width
end
outer_height() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 337
def outer_height
  @style.margin_top + height + @style.margin_bottom
end
outer_width() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 313
def outer_width
  @style.margin_left + width + @style.margin_right
end
recalculate() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 416
def recalculate
  raise "#{self.class}#recalculate was not overridden!"
end
released_left_mouse_button(sender, _x, _y) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 181
def released_left_mouse_button(sender, _x, _y)
  enter(sender)

  :handled
end
render() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 289
def render
end
reposition() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 420
def reposition
end
root() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 390
def root
  return self if is_root?

  unless @root && @root.parent.nil?
    @root = parent

    loop do
      break unless @root&.parent

      @root = @root.parent
    end
  end

  @root
end
safe_style_fetch(*args) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 62
def safe_style_fetch(*args)
  @style.hash.dig(@style_event, *args) || @style.hash.dig(:default, *args) || default(*args)
end
scroll_height() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 349
def scroll_height
  @children.sum { |c| c.height } + noncontent_height
end
scroll_width() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 345
def scroll_width
  @children.sum { |c| c.width } + noncontent_width
end
set_background() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 71
def set_background
  @style.background = safe_style_fetch(:background)

  @style.background_canvas.background = @style.background
end
set_border_color() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 86
def set_border_color
  @style.border_color = safe_style_fetch(:border_color)

  @style.border_color_left   = safe_style_fetch(:border_color_left)   || @style.border_color
  @style.border_color_right  = safe_style_fetch(:border_color_right)  || @style.border_color
  @style.border_color_top    = safe_style_fetch(:border_color_top)    || @style.border_color
  @style.border_color_bottom = safe_style_fetch(:border_color_bottom) || @style.border_color

  @style.border_canvas.color = [
    @style.border_color_top,
    @style.border_color_right,
    @style.border_color_bottom,
    @style.border_color_left
  ]
end
set_border_thickness() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 77
def set_border_thickness
  @style.border_thickness = safe_style_fetch(:border_thickness)

  @style.border_thickness_left   = safe_style_fetch(:border_thickness_left)   || @style.border_thickness
  @style.border_thickness_right  = safe_style_fetch(:border_thickness_right)  || @style.border_thickness
  @style.border_thickness_top    = safe_style_fetch(:border_thickness_top)    || @style.border_thickness
  @style.border_thickness_bottom = safe_style_fetch(:border_thickness_bottom) || @style.border_thickness
end
set_margin() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 111
def set_margin
  @style.margin = safe_style_fetch(:margin)

  @style.margin_left   = safe_style_fetch(:margin_left)   || @style.margin
  @style.margin_right  = safe_style_fetch(:margin_right)  || @style.margin
  @style.margin_top    = safe_style_fetch(:margin_top)    || @style.margin
  @style.margin_bottom = safe_style_fetch(:margin_bottom) || @style.margin
end
set_padding() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 102
def set_padding
  @style.padding = safe_style_fetch(:padding)

  @style.padding_left   = safe_style_fetch(:padding_left)   || @style.padding
  @style.padding_right  = safe_style_fetch(:padding_right)  || @style.padding
  @style.padding_top    = safe_style_fetch(:padding_top)    || @style.padding
  @style.padding_bottom = safe_style_fetch(:padding_bottom) || @style.padding
end
set_static_position() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 66
def set_static_position
  @x = @style.x if @style.x != 0
  @y = @style.y if @style.y != 0
end
show() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 228
def show
  bool = visible?
  @visible = true
  root.gui_state.request_recalculate unless bool
end
stylize() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 50
def stylize
  set_static_position

  set_padding
  set_margin

  set_background

  set_border_thickness
  set_border_color
end
to_s() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 431
def to_s
  "#{self.class} x=#{x} y=#{y} width=#{width} height=#{height} value=#{value.is_a?(String) ? "\"#{value}\"" : value}"
end
toggle() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 223
def toggle
  @visible = !@visible
  root.gui_state.request_recalculate
end
update() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 276
def update
end
update_background() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 378
def update_background
  @style.background_canvas.x = @x
  @style.background_canvas.y = @y
  @style.background_canvas.z = @z
  @style.background_canvas.width  = width
  @style.background_canvas.height = height

  @style.background_canvas.update

  @style.border_canvas.update
end
update_styles(event = :default) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 120
def update_styles(event = :default)
  _style = @style.send(event)
  @style_event = event

  if @text.is_a?(CyberarmEngine::Text)
    @text.color = _style&.dig(:color) || @style.default[:color]
    @text.swap_font(_style&.dig(:text_size) || @style.default[:text_size], _style&.dig(:font) || @style.default[:font])
  end

  (root&.gui_state || @gui_state).request_recalculate
end
value() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 423
def value
  raise "#{self.class}#value was not overridden!"
end
value=(_value) click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 427
def value=(_value)
  raise "#{self.class}#value= was not overridden!"
end
visible?() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 219
def visible?
  @visible
end
width() click to toggle source
# File lib/cyberarm_engine/ui/element.rb, line 297
def width
  if visible?
    inner_width + @width
  else
    0
  end
end