From a8b8d5aba1ad2f68407a95c5986028e8772d985e Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Mon, 25 Mar 2019 20:07:43 -0500 Subject: [PATCH] UX improvements for Button:active handling, added Style stub, Default element width/height is now window width/height instead of 0,0; may need tweaking. --- lib/cyberarm_engine.rb | 1 + lib/cyberarm_engine/ui/button.rb | 21 ++++++++++++++++---- lib/cyberarm_engine/ui/check_box.rb | 2 -- lib/cyberarm_engine/ui/edit_line.rb | 26 +++++++++++++++++++------ lib/cyberarm_engine/ui/element.rb | 24 +++++++++++++---------- lib/cyberarm_engine/ui/gui_state.rb | 8 +++++++- lib/cyberarm_engine/ui/image.rb | 6 +++--- lib/cyberarm_engine/ui/label.rb | 9 ++------- lib/cyberarm_engine/ui/style.rb | 15 ++++++++++++++ lib/cyberarm_engine/ui/theme.rb | 4 ++-- lib/cyberarm_engine/ui/toggle_button.rb | 1 + 11 files changed, 82 insertions(+), 35 deletions(-) create mode 100644 lib/cyberarm_engine/ui/style.rb diff --git a/lib/cyberarm_engine.rb b/lib/cyberarm_engine.rb index a8a7f7b..d473476 100644 --- a/lib/cyberarm_engine.rb +++ b/lib/cyberarm_engine.rb @@ -17,6 +17,7 @@ require_relative "cyberarm_engine/objects/multi_line_text" require_relative "cyberarm_engine/ui/theme" require_relative "cyberarm_engine/ui/event" +require_relative "cyberarm_engine/ui/style" require_relative "cyberarm_engine/ui/border_canvas" require_relative "cyberarm_engine/ui/element" require_relative "cyberarm_engine/ui/label" diff --git a/lib/cyberarm_engine/ui/button.rb b/lib/cyberarm_engine/ui/button.rb index 33c4bd0..c21c366 100644 --- a/lib/cyberarm_engine/ui/button.rb +++ b/lib/cyberarm_engine/ui/button.rb @@ -15,12 +15,21 @@ module CyberarmEngine end def enter(sender) - @background_canvas.background = default(:hover, :background) - @text.color = default(:hover, :color) + @focus = false unless window.button_down?(Gosu::MsLeft) + + if @focus + @background_canvas.background = default(:active, :background) + @text.color = default(:active, :color) + else + @background_canvas.background = default(:hover, :background) + @text.color = default(:hover, :color) + end end def left_mouse_button(sender, x, y) + @focus = true @background_canvas.background = default(:active, :background) + window.current_state.focus = self @text.color = default(:active, :color) end @@ -28,13 +37,17 @@ module CyberarmEngine enter(sender) end + def clicked_left_mouse_button(sender, x, y) + @block.call(self) if @block + end + def leave(sender) @background_canvas.background = default(:background) @text.color = default(:color) end - def clicked_left_mouse_button(sender, x, y) - @block.call(self) if @block + def blur(sender) + @focus = false end end end \ No newline at end of file diff --git a/lib/cyberarm_engine/ui/check_box.rb b/lib/cyberarm_engine/ui/check_box.rb index 4d06607..85433d5 100644 --- a/lib/cyberarm_engine/ui/check_box.rb +++ b/lib/cyberarm_engine/ui/check_box.rb @@ -14,8 +14,6 @@ module CyberarmEngine @width = @toggle_button.width + @label.width @height = @toggle_button.height + @label.height - - recalculate end def text=(text) diff --git a/lib/cyberarm_engine/ui/edit_line.rb b/lib/cyberarm_engine/ui/edit_line.rb index b28c8ba..73d7b41 100644 --- a/lib/cyberarm_engine/ui/edit_line.rb +++ b/lib/cyberarm_engine/ui/edit_line.rb @@ -40,23 +40,37 @@ module CyberarmEngine end end - def clicked_left_mouse_button(sender, x, y) - @focus = true - window.current_state.focus=self + def left_mouse_button(sender, x, y) + super window.text_input = @text_input - @block.call(self) if @block + end + + def enter(sender) + if @focus + @background_canvas.background = default(:active, :background) + @text.color = default(:active, :color) + else + @background_canvas.background = default(:hover, :background) + @text.color = default(:hover, :color) + end + end + + def leave(sender) end def blur(sender) @focus = false + @background_canvas.background = default(:background) + @text.color = default(:color) window.text_input = nil end + # TODO: Fix caret rendering in wrong position unless caret_pos is at end of text def caret_position if @type == :password - @text.x + @text.textobject.text_width(default(:password_character) * @text_input.text[0..@text_input.caret_pos].length) + @text.x + @text.textobject.text_width(default(:password_character) * @text_input.text[0..@text_input.caret_pos-1].length) else - @text.x + @text.textobject.text_width(@text_input.text[0..@text_input.caret_pos]) + @text.x + @text.textobject.text_width(@text_input.text[0..@text_input.caret_pos-1]) end end diff --git a/lib/cyberarm_engine/ui/element.rb b/lib/cyberarm_engine/ui/element.rb index e3fca11..c290086 100644 --- a/lib/cyberarm_engine/ui/element.rb +++ b/lib/cyberarm_engine/ui/element.rb @@ -19,6 +19,8 @@ module CyberarmEngine @options = options @block = block + @style = Style.new(options) + @focus = false @background_canvas = Background.new @border_canvas = BorderCanvas.new(element: self) @@ -29,8 +31,8 @@ module CyberarmEngine @fixed_x = @x if @x != 0 @fixed_y = @y if @y != 0 - @width = default(:width) - @height = default(:height) + @width = default(:width) || $window.width + @height = default(:height) || $window.height set_border_thickness(default(:border_thickness)) @@ -44,23 +46,17 @@ module CyberarmEngine raise "#{self.class} 'x' must be a number" unless @x.is_a?(Numeric) raise "#{self.class} 'y' must be a number" unless @y.is_a?(Numeric) raise "#{self.class} 'z' must be a number" unless @z.is_a?(Numeric) - raise "#{self.class} 'width' must be a number" unless @width.is_a?(Numeric) - raise "#{self.class} 'height' must be a number" unless @height.is_a?(Numeric) + raise "#{self.class} 'width' must be a number" unless @width.is_a?(Numeric) || @width.nil? + raise "#{self.class} 'height' must be a number" unless @height.is_a?(Numeric) || @height.nil? raise "#{self.class} 'options' must be a Hash" unless @options.is_a?(Hash) # raise "#{self.class} 'padding' must be a number" unless @padding.is_a?(Numeric) - @max_width = @width if @width != 0 - @max_height = @height if @height != 0 - @enabled = true default_events end - def width=(n); @max_width = n; end - def height=(n); @max_height = n; end - def set_background(background) @background = background @background_canvas.background = background @@ -165,6 +161,14 @@ module CyberarmEngine @margin_top + height + @margin_bottom end + def style(hash) + if hash + @style.set(hash) + else + @style.hash + end + end + def background=(_background) @background_canvas.background=(_background) update_background diff --git a/lib/cyberarm_engine/ui/gui_state.rb b/lib/cyberarm_engine/ui/gui_state.rb index 19a54c4..6c5660b 100644 --- a/lib/cyberarm_engine/ui/gui_state.rb +++ b/lib/cyberarm_engine/ui/gui_state.rb @@ -21,11 +21,17 @@ module CyberarmEngine setup end + # throws :blur event to focused element and sets GuiState focused element + # Does NOT throw :focus event at element or set element as focused def focus=(element) - @focus.publish(:blur) if @focus and element + @focus.publish(:blur) if @focus and element && @focus != element @focus = element end + def focused + @focus + end + def update super diff --git a/lib/cyberarm_engine/ui/image.rb b/lib/cyberarm_engine/ui/image.rb index f39d8fb..548bbeb 100644 --- a/lib/cyberarm_engine/ui/image.rb +++ b/lib/cyberarm_engine/ui/image.rb @@ -5,13 +5,13 @@ module CyberarmEngine @path = path @image = Gosu::Image.new(path, retro: @options[:image_retro]) - if @options[:width].nonzero? && @options[:height].nonzero? + if @options[:width] && @options[:height] @scale_x = @options[:width].to_f / @image.width @scale_y = @options[:height].to_f / @image.height - elsif @options[:width].nonzero? + elsif @options[:width] @scale_x = @options[:width].to_f / @image.width @scale_y = @scale_x - elsif @options[:height].nonzero? + elsif @options[:height] @scale_y = @options[:height].to_f / @image.height @scale_x = @scale_y else diff --git a/lib/cyberarm_engine/ui/label.rb b/lib/cyberarm_engine/ui/label.rb index 36dd0e5..4aeed2f 100644 --- a/lib/cyberarm_engine/ui/label.rb +++ b/lib/cyberarm_engine/ui/label.rb @@ -12,13 +12,8 @@ module CyberarmEngine @text.draw end - def button_up(id) - case id - when Gosu::MsLeft - if mouse_over? - @block.call(self) if @block - end - end + def clicked_left_mouse_button(sender, x, y) + @block.call(self) if @block end def recalculate diff --git a/lib/cyberarm_engine/ui/style.rb b/lib/cyberarm_engine/ui/style.rb new file mode 100644 index 0000000..0cbf1a7 --- /dev/null +++ b/lib/cyberarm_engine/ui/style.rb @@ -0,0 +1,15 @@ +module CyberarmEngine + class Style + def initialize(hash) + @hash = hash + end + + def hash + @hash + end + + def set(hash) + @hash.merge!(hash) + end + end +end \ No newline at end of file diff --git a/lib/cyberarm_engine/ui/theme.rb b/lib/cyberarm_engine/ui/theme.rb index 9346062..b8fb5f9 100644 --- a/lib/cyberarm_engine/ui/theme.rb +++ b/lib/cyberarm_engine/ui/theme.rb @@ -32,8 +32,8 @@ module CyberarmEngine y: 0, z: 30, - width: 0, - height: 0, + width: nil, + height: nil, color: Gosu::Color::WHITE, background: Gosu::Color::NONE, margin: 0, diff --git a/lib/cyberarm_engine/ui/toggle_button.rb b/lib/cyberarm_engine/ui/toggle_button.rb index ce2846b..6c633f3 100644 --- a/lib/cyberarm_engine/ui/toggle_button.rb +++ b/lib/cyberarm_engine/ui/toggle_button.rb @@ -39,6 +39,7 @@ module CyberarmEngine super @width = @text.textobject.text_width(@options[:checkmark]) + update_background end def value