From 478c8498f390c152161689b128401151709b2079 Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Fri, 1 Mar 2019 15:57:22 -0600 Subject: [PATCH] Added padding and margin left,right,top,bottom, changed CheckBox to ToggleButton, added new CheckBox which uses a Flow with ToggleButton and Label. --- lib/cyberarm_engine.rb | 3 +- lib/cyberarm_engine/engine.rb | 4 ++ lib/cyberarm_engine/game_state.rb | 2 +- lib/cyberarm_engine/ui/button.rb | 8 +-- lib/cyberarm_engine/ui/check_box.rb | 50 ++++++++---------- lib/cyberarm_engine/ui/container.rb | 14 ++--- lib/cyberarm_engine/ui/dsl.rb | 12 ++++- lib/cyberarm_engine/ui/edit_line.rb | 12 ++++- lib/cyberarm_engine/ui/element.rb | 69 +++++++++++++++---------- lib/cyberarm_engine/ui/flow.rb | 7 +-- lib/cyberarm_engine/ui/gui_state.rb | 4 +- lib/cyberarm_engine/ui/image.rb | 13 ++--- lib/cyberarm_engine/ui/label.rb | 6 +-- lib/cyberarm_engine/ui/stack.rb | 7 +-- lib/cyberarm_engine/ui/theme.rb | 6 +-- lib/cyberarm_engine/ui/toggle_button.rb | 48 +++++++++++++++++ 16 files changed, 162 insertions(+), 103 deletions(-) create mode 100644 lib/cyberarm_engine/ui/toggle_button.rb diff --git a/lib/cyberarm_engine.rb b/lib/cyberarm_engine.rb index 7771e1c..3c5dd8f 100644 --- a/lib/cyberarm_engine.rb +++ b/lib/cyberarm_engine.rb @@ -16,13 +16,14 @@ require_relative "cyberarm_engine/ui/event" require_relative "cyberarm_engine/ui/element" require_relative "cyberarm_engine/ui/label" require_relative "cyberarm_engine/ui/button" -require_relative "cyberarm_engine/ui/check_box" +require_relative "cyberarm_engine/ui/toggle_button" require_relative "cyberarm_engine/ui/edit_line" require_relative "cyberarm_engine/ui/image" require_relative "cyberarm_engine/ui/container" require_relative "cyberarm_engine/ui/flow" require_relative "cyberarm_engine/ui/stack" +require_relative "cyberarm_engine/ui/check_box" require_relative "cyberarm_engine/ui/dsl" require_relative "cyberarm_engine/game_state" diff --git a/lib/cyberarm_engine/engine.rb b/lib/cyberarm_engine/engine.rb index 0c6f421..f45de64 100644 --- a/lib/cyberarm_engine/engine.rb +++ b/lib/cyberarm_engine/engine.rb @@ -45,6 +45,10 @@ module CyberarmEngine @last_frame_time/1000.0 end + def button_down(id) + current_state.button_down(id) if current_state + end + def button_up(id) current_state.button_up(id) if current_state end diff --git a/lib/cyberarm_engine/game_state.rb b/lib/cyberarm_engine/game_state.rb index b14e109..2a7426a 100644 --- a/lib/cyberarm_engine/game_state.rb +++ b/lib/cyberarm_engine/game_state.rb @@ -29,7 +29,7 @@ module CyberarmEngine @game_objects = nil end - def down_up(id) + def button_down(id) @game_objects.each do |o| o.button_down(id) end diff --git a/lib/cyberarm_engine/ui/button.rb b/lib/cyberarm_engine/ui/button.rb index 78a8a82..ca2c6bc 100644 --- a/lib/cyberarm_engine/ui/button.rb +++ b/lib/cyberarm_engine/ui/button.rb @@ -20,16 +20,16 @@ module CyberarmEngine end def clicked_left_mouse_button(sender, x, y) - @block.call if block + @block.call(self) if @block end def draw_button - $window.draw_rect(relative_x, relative_y, width, height, @options[:element_background], @z+1) + $window.draw_rect(@x, @y, width, height, @options[:element_background], @z+1) @background ||= @options[:interactive_background] $window.draw_rect( - relative_x + @options[:interactive_border_size], - relative_y + @options[:interactive_border_size], + @x + @options[:interactive_border_size], + @y + @options[:interactive_border_size], width - (@options[:interactive_border_size]*2), height- (@options[:interactive_border_size]*2), @background, diff --git a/lib/cyberarm_engine/ui/check_box.rb b/lib/cyberarm_engine/ui/check_box.rb index 15d804f..214dc30 100644 --- a/lib/cyberarm_engine/ui/check_box.rb +++ b/lib/cyberarm_engine/ui/check_box.rb @@ -1,39 +1,33 @@ module CyberarmEngine - class CheckBox < Button - def initialize(options, block = nil) - super(options[:checkmark], options, block) - @checked = options[:checked] || false - if @checked - @text.text = @options[:checkmark] - else - @text.text = "" - end + class CheckBox < Flow + def initialize(text, options, block = nil) + super(options = {}, block = nil) - return self + @toggle_button = ToggleButton.new(options) + @label = Label.new(text, options) + + add(@toggle_button) + add(@label) + + @width = @toggle_button.width + @label.width + @height = @toggle_button.height + @label.height + + @background_color = Gosu::Color::RED + + recalculate end - def button_up(id) - if mouse_over? && id == Gosu::MsLeft - if @checked - @checked = false - @text.text = "" - else - @checked = true - @text.text = @options[:checkmark] - end - - @block.call(self) if @block - end + def text=(text) + @label.text = text + recalculate end - def recalculate - super - - @width = @text.textobject.text_width(@options[:checkmark]) + def hover(sender) + # puts "a-#{Gosu.milliseconds}" end - def value - @checked + def clicked_left_mouse_button(sender, x, y) + @toggle_button.toggled = !@toggle_button.toggled end end end \ No newline at end of file diff --git a/lib/cyberarm_engine/ui/container.rb b/lib/cyberarm_engine/ui/container.rb index 2b27797..bb12fc9 100644 --- a/lib/cyberarm_engine/ui/container.rb +++ b/lib/cyberarm_engine/ui/container.rb @@ -47,10 +47,6 @@ module CyberarmEngine @children.each(&:update) end - def mouse_over? - $window.mouse_x.between?(@x, @x + @width) && $window.mouse_y.between?(@y, @y + @height) - end - def theme @theme end @@ -83,8 +79,7 @@ module CyberarmEngine end def recalculate - raise "mode was not defined!" unless @mode - @current_position = Vector.new(@x, @y) + @current_position = Vector.new(@margin_left + @x, @margin_top + @y) layout end @@ -98,21 +93,22 @@ module CyberarmEngine end def fits_on_line?(element) - @current_position.x + element.width <= max_width + @current_position.x + element.margin_left + element.width + element.margin_right <= max_width end def position_on_current_line(element) element.x = @current_position.x element.y = @current_position.y - @current_position.x += element.outer_width + @current_position.x += element.width + element.margin_right @current_position.x = @x if @current_position.x >= max_width end def move_to_next_line(element) element.x = @current_position.x element.y = @current_position.y - @current_position.y += element.outer_height + + @current_position.y += element.height + element.margin_bottom end end end \ No newline at end of file diff --git a/lib/cyberarm_engine/ui/dsl.rb b/lib/cyberarm_engine/ui/dsl.rb index 48c9dea..d63c765 100644 --- a/lib/cyberarm_engine/ui/dsl.rb +++ b/lib/cyberarm_engine/ui/dsl.rb @@ -48,9 +48,17 @@ module CyberarmEngine return _element end - def check_box(options = {}, &block) + def toggle_button(options = {}, &block) options[:parent] = @containers.last - _element = CheckBox.new(options, block) + _element = ToggleButton.new(options, block) + @containers.last.add(_element) + + return _element + end + + def check_box(text, options = {}, &block) + options[:parent] = @containers.last + _element = CheckBox.new(text, options, block) @containers.last.add(_element) return _element diff --git a/lib/cyberarm_engine/ui/edit_line.rb b/lib/cyberarm_engine/ui/edit_line.rb index a99ffe0..aca158f 100644 --- a/lib/cyberarm_engine/ui/edit_line.rb +++ b/lib/cyberarm_engine/ui/edit_line.rb @@ -20,7 +20,7 @@ module CyberarmEngine end def draw - Gosu.clip_to(relative_x, relative_y, width, height) do + Gosu.clip_to(@x, @y, width, height) do draw_text Gosu.draw_rect(caret_position, @text.y, @caret_width, @caret_height, @caret_color, @z + 40) if @show_caret end @@ -58,6 +58,16 @@ module CyberarmEngine end end + def clicked_left_mouse_button(sender, x, y) + window.current_state.focus=self + window.text_input = @text_input + @block.call(self) if @block + end + + def blur(sender) + window.text_input = nil + end + def caret_position if $window.text_input && $window.text_input == @text_input if @type == :password diff --git a/lib/cyberarm_engine/ui/element.rb b/lib/cyberarm_engine/ui/element.rb index 8686333..460ab21 100644 --- a/lib/cyberarm_engine/ui/element.rb +++ b/lib/cyberarm_engine/ui/element.rb @@ -2,14 +2,16 @@ module CyberarmEngine class Element include Theme include Event + include Common - attr_accessor :x, :y, :z, :width, :height, :padding, :margin, :enabled + attr_accessor :x, :y, :z, :width, :height, :enabled attr_reader :parent, :options, :event_handler + attr_reader :padding, :padding_left, :padding_right, :padding_top, :padding_bottom + attr_reader :margin, :margin_left, :margin_right, :margin_top, :margin_bottom def initialize(options = {}, block = nil) @parent = options[:parent] # parent Container (i.e. flow/stack) - parent_theme = @parent ? @parent.theme : {} - options = (THEME).merge(DEFAULTS).merge(parent_theme).merge(options) + options = (THEME).merge(DEFAULTS).merge(options) @options = options @block = block @@ -23,8 +25,17 @@ module CyberarmEngine @width = options.dig(:width) @height = options.dig(:height) - @padding = options.dig(:padding) - @margin = options.dig(:margin) + set_padding(options.dig(:padding)) + @padding_left = options.dig(:padding_left) || @padding + @padding_right = options.dig(:padding_right) || @padding + @padding_top = options.dig(:padding_top) || @padding + @padding_bottom = options.dig(:padding_bottom) || @padding + + set_margin(options.dig(:margin)) + @margin_left = options.dig(:margin_left) || @margin + @margin_right = options.dig(:margin_right) || @margin + @margin_top = options.dig(:margin_top) || @margin + @margin_bottom = options.dig(:margin_bottom) || @margin 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) @@ -33,8 +44,7 @@ module CyberarmEngine raise "#{self.class} 'height' must be a number" unless @height.is_a?(Numeric) 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) - raise "#{self.class} 'margin' must be a number" unless @margin.is_a?(Numeric) + # 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 @@ -44,10 +54,29 @@ module CyberarmEngine default_events end + def set_padding(padding) + @padding = padding + + @padding_left = padding + @padding_right = padding + @padding_top = padding + @padding_bottom = padding + end + + def set_margin(margin) + @margin = margin + + @margin_left = margin + @margin_right = margin + @margin_top = margin + @margin_bottom = margin + end + def default_events [: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 @@ -57,6 +86,8 @@ module CyberarmEngine event(:enter) event(:hover) event(:leave) + + event(:blur) end def enabled? @@ -76,32 +107,16 @@ module CyberarmEngine end def hit?(x, y) - x.between?(relative_x, relative_x + width) && - y.between?(relative_y, relative_y + height) + x.between?(@x, @x + width) && + y.between?(@y, @y + height) end def width - @width + (@padding * 2) + @padding_left + @width + @padding_right end def height - @height + (@padding * 2) - end - - def outer_width - width + (@margin * 2) - end - - def outer_height - height + (@margin * 2) - end - - def relative_x - @x# + @margin - end - - def relative_y - @y# + @margin + @padding_top + @height + @padding_bottom end def recalculate diff --git a/lib/cyberarm_engine/ui/flow.rb b/lib/cyberarm_engine/ui/flow.rb index 0d86592..69f3489 100644 --- a/lib/cyberarm_engine/ui/flow.rb +++ b/lib/cyberarm_engine/ui/flow.rb @@ -2,11 +2,6 @@ module CyberarmEngine class Flow < Container include Common - def initialize(options = {}, block = nil) - @mode = :flow - super - end - def layout @children.each do |child| if fits_on_line?(child) @@ -18,7 +13,7 @@ module CyberarmEngine child.recalculate end - @width = @max_width ? @max_width : (@children.map {|c| c.x + c.width}.max || 0) + @width = @max_width ? @max_width : (@children.map {|c| c.x + c.width }.max || 0) @height = @max_height ? @max_height : (@children.map {|c| c.y + c.height}.max || 0) end end diff --git a/lib/cyberarm_engine/ui/gui_state.rb b/lib/cyberarm_engine/ui/gui_state.rb index e861538..c20a34f 100644 --- a/lib/cyberarm_engine/ui/gui_state.rb +++ b/lib/cyberarm_engine/ui/gui_state.rb @@ -32,7 +32,7 @@ module CyberarmEngine new_mouse_over = @root_container.hit_element?(window.mouse_x, window.mouse_y) if new_mouse_over new_mouse_over.publish(:enter) if new_mouse_over != @mouse_over - new_mouse_over.publish(:hover, window.mouse_x, window.mouse_y) + new_mouse_over.publish(:hover) end @mouse_over.publish(:leave) if @mouse_over && new_mouse_over != @mouse_over @mouse_over = new_mouse_over @@ -93,8 +93,6 @@ module CyberarmEngine @mouse_over.publish(:"released_#{button}_mouse_button", window.mouse_x, window.mouse_y) if @mouse_over @mouse_over.publish(:"clicked_#{button}_mouse_button", window.mouse_x, window.mouse_y) if @mouse_over == @mouse_down_on[button] - p @mouse_over.class, @mouse_down_on[button].class - @mouse_down_position[button] = nil @mouse_down_on[button] = nil end diff --git a/lib/cyberarm_engine/ui/image.rb b/lib/cyberarm_engine/ui/image.rb index 808af47..cc2998f 100644 --- a/lib/cyberarm_engine/ui/image.rb +++ b/lib/cyberarm_engine/ui/image.rb @@ -22,18 +22,13 @@ module CyberarmEngine end def draw - $window.draw_rect(relative_x, relative_y, width, height, @options[:fill], @z+1) + $window.draw_rect(@x, @y, width, height, @options[:fill], @z+1) - @image.draw(relative_x + @padding, relative_y + @padding, @z + 2, @scale_x, @scale_y) # TODO: Add color support? + @image.draw(@x + @padding_left, @y + @padding_top, @z + 2, @scale_x, @scale_y) # TODO: Add color support? 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/label.rb b/lib/cyberarm_engine/ui/label.rb index 1fc128c..5b20e10 100644 --- a/lib/cyberarm_engine/ui/label.rb +++ b/lib/cyberarm_engine/ui/label.rb @@ -9,7 +9,7 @@ module CyberarmEngine end def draw - $window.draw_rect(relative_x, relative_y, width, height, @options[:fill], @z+1) + $window.draw_rect(@x, @y, width, height, @options[:fill], @z+1) @text.draw end @@ -27,8 +27,8 @@ module CyberarmEngine @width = @text.width @height= @text.height - @text.x = relative_x + @padding - @text.y = relative_y + @padding + @text.x = @x + @padding_left + @text.y = @y + @padding_top @text.z = @z + 3 end diff --git a/lib/cyberarm_engine/ui/stack.rb b/lib/cyberarm_engine/ui/stack.rb index 9fe97b2..224ba0a 100644 --- a/lib/cyberarm_engine/ui/stack.rb +++ b/lib/cyberarm_engine/ui/stack.rb @@ -2,11 +2,6 @@ module CyberarmEngine class Stack < Container include Common - def initialize(options = {}, block = nil) - @mode = :stack - super - end - def layout @children.each do |child| move_to_next_line(child) @@ -14,7 +9,7 @@ module CyberarmEngine child.recalculate end - @width = @max_width ? @max_width : (@children.map {|c| c.x + c.width}.max || 0) + @width = @max_width ? @max_width : (@children.map {|c| c.x + c.width }.max || 0) @height = @max_height ? @max_height : (@children.map {|c| c.y + c.height}.max || 0) end end diff --git a/lib/cyberarm_engine/ui/theme.rb b/lib/cyberarm_engine/ui/theme.rb index ea84e53..c993bd8 100644 --- a/lib/cyberarm_engine/ui/theme.rb +++ b/lib/cyberarm_engine/ui/theme.rb @@ -15,8 +15,8 @@ module CyberarmEngine background: Gosu::Color::NONE, checkmark: "√", # √ - padding: 20, - margin: 2, + margin: 0, + padding: 5, element_background: Gosu::Color.rgb(12,12,12), @@ -38,7 +38,7 @@ module CyberarmEngine text_size: 22, text_shadow: true, - font: "Consolas" + font: "Sans Serif" } end end \ No newline at end of file diff --git a/lib/cyberarm_engine/ui/toggle_button.rb b/lib/cyberarm_engine/ui/toggle_button.rb new file mode 100644 index 0000000..ce2846b --- /dev/null +++ b/lib/cyberarm_engine/ui/toggle_button.rb @@ -0,0 +1,48 @@ +module CyberarmEngine + class ToggleButton < Button + attr_reader :toggled + + def initialize(options, block = nil) + super(options[:checkmark], options, block) + @toggled = options[:toggled] || false + if @toggled + @text.text = @options[:checkmark] + else + @text.text = "" + end + + return self + end + + def toggled=(boolean) + @toggled = !boolean + toggle + end + + def clicked_left_mouse_button(sender, x, y) + toggle + + @block.call(self) if @block + end + + def toggle + if @toggled + @toggled = false + @text.text = "" + else + @toggled = true + @text.text = @options[:checkmark] + end + end + + def recalculate + super + + @width = @text.textobject.text_width(@options[:checkmark]) + end + + def value + @toggled + end + end +end \ No newline at end of file