Implemented Slider (still have some positioning issues to resolve but it works), added files for ListBox, Radio, and EditBox, implemented dragging support in GuiState.

This commit is contained in:
2020-04-10 18:45:55 -05:00
parent 185ab000d6
commit 4055f645f3
12 changed files with 198 additions and 4 deletions

View File

@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
spec.require_paths = ["lib"]
spec.add_dependency "gosu", "~> 0.15.0"
spec.add_dependency "gosu_more_drawables", "~> 0.3"
spec.add_development_dependency "bundler", "~> 1.16"
spec.add_development_dependency "rake", "~> 13.0"

View File

@@ -5,6 +5,7 @@ rescue LoadError => e
require "gosu"
end
require "json"
require "gosu_more_drawables"
require_relative "cyberarm_engine/version"
@@ -35,15 +36,19 @@ require_relative "cyberarm_engine/ui/style"
require_relative "cyberarm_engine/ui/border_canvas"
require_relative "cyberarm_engine/ui/element"
require_relative "cyberarm_engine/ui/elements/label"
require_relative "cyberarm_engine/ui/elements/list_box"
require_relative "cyberarm_engine/ui/elements/button"
require_relative "cyberarm_engine/ui/elements/toggle_button"
require_relative "cyberarm_engine/ui/elements/edit_line"
require_relative "cyberarm_engine/ui/elements/edit_box"
require_relative "cyberarm_engine/ui/elements/image"
require_relative "cyberarm_engine/ui/elements/container"
require_relative "cyberarm_engine/ui/elements/flow"
require_relative "cyberarm_engine/ui/elements/stack"
require_relative "cyberarm_engine/ui/elements/check_box"
require_relative "cyberarm_engine/ui/elements/radio"
require_relative "cyberarm_engine/ui/elements/progress"
require_relative "cyberarm_engine/ui/elements/slider"
require_relative "cyberarm_engine/game_state"
require_relative "cyberarm_engine/ui/gui_state"

View File

@@ -57,6 +57,13 @@ module CyberarmEngine
add_element( Element::Progress.new(options, block) )
end
def slider(options = {}, &block)
options[:parent] = element_parent
options[:theme] = current_theme
add_element( Element::Slider.new(options, block) )
end
def background(color = Gosu::Color::NONE)
element_parent.style.background = color
end

View File

@@ -4,7 +4,7 @@ module CyberarmEngine
include Event
include Common
attr_accessor :x, :y, :z, :enabled
attr_accessor :x, :y, :z, :enabled, :tip
attr_reader :parent, :options, :style, :event_handler, :background_canvas, :border_canvas
def initialize(options = {}, block = nil)
@@ -16,6 +16,7 @@ module CyberarmEngine
@focus = false
@enabled = true
@visible = true
@tip = @options[:tip] ? @options[:tip] : ""
@style = Style.new(options)
@@ -152,6 +153,10 @@ module CyberarmEngine
def button_up(id)
end
def draggable?(button)
false
end
def render
end

View File

@@ -93,8 +93,8 @@ module CyberarmEngine
# Move child to parent after positioning
@children.each do |child|
child.x += @x - style.margin_left
child.y += @y - style.margin_top
child.x += (@x + @style.border_thickness_left) - style.margin_left
child.y += (@y + @style.border_thickness_top) - style.margin_top
child.stylize
child.recalculate

View File

@@ -0,0 +1,6 @@
module CyberarmEngine
class Element
class EditBox < Element
end
end
end

View File

@@ -0,0 +1,6 @@
module CyberarmEngine
class Element
class ListBox < Element
end
end
end

View File

@@ -0,0 +1,6 @@
module CyberarmEngine
class Element
class Radio < Element
end
end
end

View File

@@ -0,0 +1,101 @@
module CyberarmEngine
class Element
class Slider < Container
class Handle < Button
def initialize(*args)
super(*args)
event(:begin_drag)
event(:drag_update)
event(:end_drag)
end
def draggable?(button)
button == :left
end
def begin_drag(sender, x, y, button)
@drag_start_pos = Vector.new(x, y)
:handled
end
def drag_update(sender, x, y, button)
# ratio = (@parent.x - (x - @drag_start_pos.x) / (@parent.width - width) * -1).clamp(0.0, 1.0)
# @x = @parent.x + width + ((@parent.width * ratio) - width * 2)
@parent.handle_dragged_to(x, y)
:handled
end
def end_drag(sender, x, y, button)
@drag_start_pos = nil
:handled
end
end
attr_reader :range, :step_size
def initialize(options = {}, block = nil)
super(options, block)
@range = @options[:range] ? @options[:range] : 0.0..1.0
@step_size = @options[:step] ? @options[:step] : 0.1
@value = @options[:value] ? @options[:value] : 0.5
@handle = Handle.new("", parent: self, width: 8) { close }
self.add(@handle)
end
def recalculate
_width = dimensional_size(@style.width, :width)
_height= dimensional_size(@style.height,:height)
@width = _width
@height = _height
@handle.x = @x + @style.border_thickness_left + @style.padding_left
@handle.y = @y + @style.border_thickness_top + @style.padding_left
@handle.recalculate
update_background
end
def draw
super
@handle.draw
end
def update
super
@tip = value.to_s
@handle.tip = @tip
end
def holding_left_mouse_button(sender, x, y)
handle_dragged_to(x, y)
end
def handle_dragged_to(x, y)
@ratio = ((x - @handle.width) - @x) / content_width
# p [@ratio, @value]
self.value = @ratio.clamp(0.0, 1.0) * (@range.max - @range.min) + @range.min
end
def value
@value
end
def value=(n)
@value = n
@handle.x = @x + @style.padding_left + @style.border_thickness_left +
(content_width * (@value - @range.min) / (@range.max - @range.min).to_f)
@handle.recalculate
end
end
end
end

View File

@@ -43,8 +43,10 @@ module CyberarmEngine
_width = dimensional_size(@style.width, :width)
_height= dimensional_size(@style.height,:height)
@width = _width ? _width : @text.textobject.text_width(@options[:checkmark])
@height = _height ? _height : @text.height
update_background
end

View File

@@ -22,6 +22,11 @@ module CyberarmEngine
@mouse_down_on = {}
@mouse_down_position = {}
@pending_recalculate_request = false
@tip = CyberarmEngine::Text.new("", size: 22, z: Float::INFINITY)
@menu = nil
@min_drag_distance = 0
@mouse_pos = Vector.new
end
# throws :blur event to focused element and sets GuiState focused element
@@ -35,6 +40,15 @@ module CyberarmEngine
@focus
end
def draw
super
if @tip.text.length > 0
Gosu.draw_rect(@tip.x - 2, @tip.y - 2, @tip.width + 4, @tip.height + 4, 0xff020202, Float::INFINITY)
@tip.draw
end
end
def update
if @pending_recalculate_request
@root_container.recalculate
@@ -56,12 +70,30 @@ module CyberarmEngine
redirect_holding_mouse_button(:middle) if @mouse_over && Gosu.button_down?(Gosu::MsMiddle)
redirect_holding_mouse_button(:right) if @mouse_over && Gosu.button_down?(Gosu::MsRight)
if Vector.new(window.mouse_x, window.mouse_y) == @last_mouse_pos
if @mouse_over && (Gosu.milliseconds - @mouse_moved_at) > tool_tip_delay
@tip.text = @mouse_over.tip if @mouse_over
@tip.x, @tip.y = window.mouse_x - @tip.width / 2, window.mouse_y - @tip.height - 4
else
@tip.text = ""
end
else
@mouse_moved_at = Gosu.milliseconds
end
@last_mouse_pos = Vector.new(window.mouse_x, window.mouse_y)
@mouse_pos = @last_mouse_pos.clone
request_recalculate if @active_width != window.width || @active_height != window.height
@active_width = window.width
@active_height = window.height
end
def tool_tip_delay
500 # ms
end
def button_down(id)
super
@@ -115,13 +147,27 @@ module CyberarmEngine
@mouse_over.publish(:"clicked_#{button}_mouse_button", window.mouse_x, window.mouse_y) if @mouse_over == @mouse_down_on[button]
end
if @dragging_element
@dragging_element.publish(:end_drag, window.mouse_x, window.mouse_y, button)
@dragging_element = nil
end
@mouse_down_position[button] = nil
@mouse_down_on[button] = nil
end
def redirect_holding_mouse_button(button)
if !@dragging_element && @mouse_down_on[button] && @mouse_down_on[button].draggable?(button) && @mouse_pos.distance(@mouse_down_position[button]) > @min_drag_distance
@dragging_element = @mouse_down_on[button]
@dragging_element.publish(:"begin_drag", window.mouse_x, window.mouse_y, button)
end
if @dragging_element
@dragging_element.publish(:"drag_update", window.mouse_x, window.mouse_y, button) if @dragging_element
else
@mouse_over.publish(:"holding_#{button}_mouse_button", window.mouse_x, window.mouse_y) if @mouse_over
end
end
def redirect_mouse_wheel(button)
@mouse_over.publish(:"mouse_wheel_#{button}", window.mouse_x, window.mouse_y) if @mouse_over

View File

@@ -114,6 +114,15 @@ module CyberarmEngine
fraction_background: [0xffc75e61, 0xffe26623],
border_thickness: 1,
border_color: [0xffd59674, 0xffff8746]
},
Slider: { # < Element
width: 250,
height: 36,
background: 0xff111111,
fraction_background: [0xffc75e61, 0xffe26623],
border_thickness: 1,
border_color: [0xffd59674, 0xffff8746]
}
}.freeze
end