Added Container#clear to remove child elements and optionally eval block, improvements to EditLine to show current selection.

This commit is contained in:
2019-11-21 14:07:42 -06:00
parent 89a54e90a1
commit 7f97ec85dd
5 changed files with 112 additions and 37 deletions

View File

@@ -24,6 +24,8 @@ require_relative "cyberarm_engine/background"
require_relative "cyberarm_engine/text"
require_relative "cyberarm_engine/timer"
require_relative "cyberarm_engine/ui/dsl"
require_relative "cyberarm_engine/ui/theme"
require_relative "cyberarm_engine/ui/event"
require_relative "cyberarm_engine/ui/style"
@@ -40,7 +42,5 @@ require_relative "cyberarm_engine/ui/elements/stack"
require_relative "cyberarm_engine/ui/elements/check_box"
require_relative "cyberarm_engine/ui/elements/progress"
require_relative "cyberarm_engine/ui/dsl"
require_relative "cyberarm_engine/game_state"
require_relative "cyberarm_engine/ui/gui_state"

View File

@@ -25,66 +25,52 @@ module CyberarmEngine
end
def label(text, options = {}, &block)
options[:parent] = @containers.last
options[:parent] = element_parent
options[:theme] = current_theme
_element = Element::Label.new(text, options, block)
@containers.last.add(_element)
return _element
add_element( Element::Label.new(text, options, block) )
end
def button(text, options = {}, &block)
options[:parent] = @containers.last
options[:parent] = element_parent
options[:theme] = current_theme
_element = Element::Button.new(text, options, block) { if block.is_a?(Proc); block.call; end }
@containers.last.add(_element)
return _element
add_element( Element::Button.new(text, options, block) { if block.is_a?(Proc); block.call; end } )
end
def edit_line(text, options = {}, &block)
options[:parent] = @containers.last
options[:parent] = element_parent
options[:theme] = current_theme
_element = Element::EditLine.new(text, options, block)
@containers.last.add(_element)
return _element
add_element( Element::EditLine.new(text, options, block) )
end
def toggle_button(options = {}, &block)
options[:parent] = @containers.last
options[:parent] = element_parent
options[:theme] = current_theme
_element = Element::ToggleButton.new(options, block)
@containers.last.add(_element)
return _element
add_element( Element::ToggleButton.new(options, block) )
end
def check_box(text, options = {}, &block)
options[:parent] = @containers.last
options[:parent] = element_parent
options[:theme] = current_theme
_element = Element::CheckBox.new(text, options, block)
@containers.last.add(_element)
return _element
add_element( Element::CheckBox.new(text, options, block) )
end
def image(path, options = {}, &block)
options[:parent] = @containers.last
options[:parent] = element_parent
options[:theme] = current_theme
_element = Element::Image.new(path, options, block)
@containers.last.add(_element)
return _element
add_element( Element::Image.new(path, options, block) )
end
def progress(options = {}, &block)
options[:parent] = @containers.last
options[:parent] = element_parent
options[:theme] = current_theme
_element = Element::Progress.new(options, block)
@containers.last.add(_element)
return _element
element_parent( Element::Progress.new(options, block) )
end
def background(color = Gosu::Color::NONE)
@@ -92,11 +78,23 @@ module CyberarmEngine
end
def theme(theme)
@containers.last.options[:theme] = theme
self.is_a?(CyberarmEngine::Element::Container) ? self : @containers.last
element_parent.options[:theme] = theme
end
def current_theme
@containers.last.options[:theme]
element_parent.options[:theme]
end
private def add_element(element)
element_parent.add(element)
return element
end
private def element_parent
self.is_a?(CyberarmEngine::Element::Container) ? self : @containers.last
end
end
end

View File

@@ -2,6 +2,7 @@ module CyberarmEngine
class Element
class Container < Element
include Common
include CyberarmEngine::DSL
attr_accessor :stroke_color, :fill_color
attr_reader :children, :gui_state
@@ -31,6 +32,12 @@ module CyberarmEngine
recalculate
end
def clear(&block)
@children.clear
block.call(self) if block
end
def render
Gosu.clip_to(@x, @y, width, height) do
@children.each(&:draw)

View File

@@ -16,16 +16,31 @@ module CyberarmEngine
@text_input = Gosu::TextInput.new
@text_input.text = text
@offset_x = 0
return self
end
def render
Gosu.clip_to(@text.x, @text.y, @style.width, @text.height) do
draw_text
Gosu.draw_rect(caret_position, @text.y, @caret_width, @caret_height, @caret_color, @z + 40) if @focus && @show_caret
Gosu.translate(-@offset_x, 0) do
draw_selection
draw_caret if @focus && @show_caret
draw_text
end
end
end
def draw_caret
Gosu.draw_rect(caret_position, @text.y, @caret_width, @caret_height, @caret_color, @z)
end
def draw_selection
selection_width = caret_position - selection_start_position
Gosu.draw_rect(selection_start_position, @text.y, selection_width, @text.height, default(:selection_color), @z)
end
def update
if @type == :password
@text.text = default(:password_character) * @text_input.text.length
@@ -38,6 +53,51 @@ module CyberarmEngine
@show_caret = !@show_caret
end
keep_caret_visible
end
def move_caret_to_mouse(mouse_x)
1.upto(@text.text.length) do |i|
if mouse_x < @text.x + @text.textobject.text_width(@text.text[0...i])
@text_input.caret_pos = @text_input.selection_start = i - 1;
return
end
end
@text_input.caret_pos = @text_input.selection_start = @text_input.text.length
end
def keep_caret_visible
caret_pos = (caret_position - @text.x) + @caret_width
@last_text ||= "/\\"
@last_pos ||= -1
puts "caret pos: #{caret_pos}, width: #{@width}, offset: #{@offset_x}" if (@last_text != @text.text) || (@last_pos != caret_pos)
@last_text = @text.text
@last_pos = caret_pos
if caret_pos.between?(@offset_x, @width + @offset_x)
# Do nothing
elsif caret_pos < @offset_x
if caret_pos > @width
@offset_x = caret_pos + @width
else
@offset_x = 0
end
elsif caret_pos > @width
@offset_x = caret_pos - @width
puts "triggered"
else
# Reset to Zero
@offset_x = 0
end
end
def left_mouse_button(sender, x, y)
@@ -47,6 +107,8 @@ module CyberarmEngine
@caret_last_interval = Gosu.milliseconds
@show_caret = true
move_caret_to_mouse(x)
return :handled
end
@@ -79,12 +141,19 @@ module CyberarmEngine
return :handled
end
# TODO: Fix caret rendering in wrong position unless caret_pos is at end of text
def caret_position
text_input_position_for(:caret_pos)
end
def selection_start_position
text_input_position_for(:selection_start)
end
def text_input_position_for(method)
if @type == :password
@text.x + @text.textobject.text_width(default(:password_character) * @text_input.text[0..@text_input.caret_pos-1].length)
@text.x + @text.textobject.text_width(default(:password_character) * @text_input.text[0..@text_input.send(method)].length)
else
@text.x + @text.textobject.text_width(@text_input.text[0..@text_input.caret_pos-1])
@text.x + @text.textobject.text_width(@text_input.text[0..@text_input.send(method)])
end
end

View File

@@ -88,6 +88,7 @@ module CyberarmEngine
caret_width: 2,
caret_color: Gosu::Color::WHITE,
caret_interval: 500,
selection_color: Gosu::Color::GREEN,
},
Image: { # < Element