lib/cyberarm_engine/ui/element.rb in cyberarm_engine-0.17.1 vs lib/cyberarm_engine/ui/element.rb in cyberarm_engine-0.18.0

- old
+ new

@@ -16,10 +16,12 @@ @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 @@ -34,77 +36,101 @@ @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 def stylize set_static_position - set_border_thickness(@style.border_thickness) - set_padding(@style.padding) + set_padding + set_margin - set_margin(@style.margin) + set_background - set_background(@style.background) - set_border_color(@style.border_color) + set_border_thickness + set_border_color end + def safe_style_fetch(*args) + @style.hash.dig(@style_event, *args) || @style.hash.dig(:default, *args) || default(*args) + end + def set_static_position @x = @style.x if @style.x != 0 @y = @style.y if @style.y != 0 end - def set_background(background) - @style.background = background - @style.background_canvas.background = background + def set_background + @style.background = safe_style_fetch(:background) + + @style.background_canvas.background = @style.background end - def set_border_thickness(border_thickness) - @style.border_thickness = border_thickness + def set_border_thickness + @style.border_thickness = safe_style_fetch(:border_thickness) - @style.border_thickness_left = default(:border_thickness_left) || @style.border_thickness - @style.border_thickness_right = default(:border_thickness_right) || @style.border_thickness - @style.border_thickness_top = default(:border_thickness_top) || @style.border_thickness - @style.border_thickness_bottom = default(:border_thickness_bottom) || @style.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 - def set_border_color(color) - @style.border_color = color + def set_border_color + @style.border_color = safe_style_fetch(:border_color) - @style.border_color_left = default(:border_color_left) || @style.border_color - @style.border_color_right = default(:border_color_right) || @style.border_color - @style.border_color_top = default(:border_color_top) || @style.border_color - @style.border_color_bottom = default(:border_color_bottom) || @style.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 = color + @style.border_canvas.color = [ + @style.border_color_top, + @style.border_color_right, + @style.border_color_bottom, + @style.border_color_left + ] end - def set_padding(padding) - @style.padding = padding + def set_padding + @style.padding = safe_style_fetch(:padding) - @style.padding_left = default(:padding_left) || @style.padding - @style.padding_right = default(:padding_right) || @style.padding - @style.padding_top = default(:padding_top) || @style.padding - @style.padding_bottom = default(:padding_bottom) || @style.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 - def set_margin(margin) - @style.margin = margin + def set_margin + @style.margin = safe_style_fetch(:margin) - @style.margin_left = default(:margin_left) || @style.margin - @style.margin_right = default(:margin_right) || @style.margin - @style.margin_top = default(:margin_top) || @style.margin - @style.margin_bottom = default(:margin_bottom) || @style.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 + 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 + def default_events %i[left middle right].each do |button| event(:"#{button}_mouse_button") event(:"released_#{button}_mouse_button") event(:"clicked_#{button}_mouse_button") @@ -122,10 +148,72 @@ event(:blur) event(:changed) end + 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 + + 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 + + def released_left_mouse_button(sender, _x, _y) + enter(sender) + + :handled + end + + def clicked_left_mouse_button(_sender, _x, _y) + @block&.call(self) if @enabled && !self.is_a?(Container) + + :handled + end + + def leave(_sender) + if @enabled + update_styles + else + update_styles(:disabled) + end + + :handled + end + + def blur(_sender) + @focus = false + + if @enabled + update_styles + else + update_styles(:disabled) + end + + :handled + end + def enabled? @enabled end def visible? @@ -158,10 +246,35 @@ Gosu.clip_to(@x, @y, width, height) do render end end + 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 + def update end def button_down(id) end @@ -256,11 +369,11 @@ end end end def background=(_background) - @style.background_canvas.background = (_background) + @style.background_canvas.background = _background update_background end def update_background @style.background_canvas.x = @x @@ -279,14 +392,12 @@ unless @root && @root.parent.nil? @root = parent loop do - if @root.parent.nil? - break - else - @root = @root.parent - end + break unless @root&.parent + + @root = @root.parent end end @root end