Added support for image icon for ToggleButton, added initial implementation of EditBox, fixed a few ruby -w warnings by initializing select instance nilable variables, added clipboard support to EditLine, added drag selection to EditLine, added keyboard shortcuts to EditLine, GuiState now passes button_down/button_up callbacks to @focus

This commit is contained in:
2020-06-16 00:16:13 -05:00
parent d902e5d111
commit 5d7e2028b1
10 changed files with 192 additions and 19 deletions

View File

@@ -6,6 +6,7 @@ rescue LoadError => e
end
require "json"
require "gosu_more_drawables"
require "clipboard"
require_relative "cyberarm_engine/version"
require_relative "cyberarm_engine/stats"

View File

@@ -29,6 +29,13 @@ module CyberarmEngine
add_element( Element::EditLine.new(text, options, block) )
end
def edit_box(text, options = {}, &block)
options[:parent] = element_parent
options[:theme] = current_theme
add_element( Element::EditBox.new(text, options, block) )
end
def toggle_button(options = {}, &block)
options[:parent] = element_parent
options[:theme] = current_theme

View File

@@ -20,6 +20,9 @@ module CyberarmEngine
@style = Style.new(options)
@root ||= nil
@gui_state ||= nil
@x = @style.x
@y = @style.y
@z = @style.z

View File

@@ -2,9 +2,10 @@ module CyberarmEngine
class Element
class Button < Label
def initialize(text_or_image, options = {}, block = nil)
@image, @scale_x, @scale_y = nil, 1, 1
if text_or_image.is_a?(Gosu::Image)
@image = text_or_image
@scale_x, @scale_y = 1, 1
end
super(text_or_image, options, block)

View File

@@ -1,6 +1,60 @@
module CyberarmEngine
class Element
class EditBox < Element
class EditBox < EditLine
def initialize(*args)
super(*args)
@active_line = 0
end
def draw_caret
Gosu.draw_rect(caret_position, @text.y + @active_line * @text.textobject.height, @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.textobject.height, default(:selection_color), @z)
end
def text_input_position_for(method)
if @type == :password
@text.x + @text.width(default(:password_character) * @text_input.text[0...@text_input.send(method)].length)
else
@text.x + @text.width(@text_input.text[0...@text_input.send(method)])
end
end
def caret_position_under_mouse(mouse_x, mouse_y)
1.upto(@text.text.length) do |i|
if mouse_x < @text.x - @offset_x + @text.textobject.text_width(@text.text[0...i])
return i - 1;
end
end
@text_input.text.length
end
def move_caret_to_mouse(mouse_x, mouse_y)
@text_input.caret_pos = @text_input.selection_start = caret_position_under_mouse(mouse_x, mouse_y)
end
def button_down(id)
super
case id
when Gosu::KB_ENTER, Gosu::KB_RETURN
caret_pos = @text_input.caret_pos
@text_input.text = @text_input.text.insert(@text_input.caret_pos, "\n")
@text_input.caret_pos = @text_input.selection_start = caret_pos + 1
end
end
def drag_update(sender, x, y, button)
@text_input.caret_pos = caret_position_under_mouse(x, y)
:handled
end
end
end
end

View File

@@ -7,7 +7,7 @@ module CyberarmEngine
@type = default(:type)
@caret_width = default(:caret_width)
@caret_height= @text.height
@caret_height= @text.textobject.height
@caret_color = default(:caret_color)
@caret_interval = default(:caret_interval)
@caret_last_interval = Gosu.milliseconds
@@ -15,15 +15,18 @@ module CyberarmEngine
@text_input = Gosu::TextInput.new
@text_input.text = text
@last_text_value = text
@offset_x = 0
@offset_x, @offset_y = 0, 0
return self
event(:begin_drag)
event(:drag_update)
event(:end_drag)
end
def render
Gosu.clip_to(@text.x, @text.y, @width, @height) do
Gosu.translate(-@offset_x, 0) do
Gosu.translate(-@offset_x, -@offset_y) do
draw_selection
draw_caret if @focus && @show_caret
draw_text
@@ -48,6 +51,12 @@ module CyberarmEngine
@text.text = @text_input.text
end
if @last_text_value != self.value
@last_text_value = self.value
publish(:changed, self.value)
end
if Gosu.milliseconds >= @caret_last_interval + @caret_interval
@caret_last_interval = Gosu.milliseconds
@@ -57,15 +66,60 @@ module CyberarmEngine
keep_caret_visible
end
def move_caret_to_mouse(mouse_x)
def button_down(id)
handle_keyboard_shortcuts(id)
end
def handle_keyboard_shortcuts(id)
return unless @focus && @enabled
if Gosu.button_down?(Gosu::KB_LEFT_CONTROL) or Gosu.button_down?(Gosu::KB_RIGHT_CONTROL)
case id
when Gosu::KB_A
@text_input.selection_start = 0
@text_input.caret_pos = @text_input.text.length
when Gosu::KB_C
if @text_input.selection_start < @text_input.caret_pos
Clipboard.copy(@text_input.text[@text_input.selection_start...@text_input.caret_pos])
else
Clipboard.copy(@text_input.text[@text_input.caret_pos...@text_input.selection_start])
end
when Gosu::KB_X
chars = @text_input.text.chars
if @text_input.selection_start < @text_input.caret_pos
Clipboard.copy(@text_input.text[@text_input.selection_start...@text_input.caret_pos])
chars.slice!(@text_input.selection_start, @text_input.caret_pos)
else
Clipboard.copy(@text_input.text[@text_input.caret_pos...@text_input.selection_start])
chars.slice!(@text_input.caret_pos, @text_input.selection_start)
end
@text_input.text = chars.join
when Gosu::KB_V
if instance_of?(EditLine) # EditLine assumes a single line of text
@text_input.text = @text_input.text.insert(@text_input.caret_pos, Clipboard.paste.encode("UTF-8").gsub("\n", ""))
else
@text_input.text = @text_input.text.insert(@text_input.caret_pos, Clipboard.paste.encode("UTF-8"))
end
end
end
end
def caret_position_under_mouse(mouse_x)
1.upto(@text.text.length) do |i|
if mouse_x < @text.x - @offset_x + @text.textobject.text_width(@text.text[0...i])
@text_input.caret_pos = @text_input.selection_start = i - 1;
return
return i - 1;
end
end
@text_input.caret_pos = @text_input.selection_start = @text_input.text.length
@text_input.text.length
end
def move_caret_to_mouse(mouse_x, mouse_y)
@text_input.caret_pos = @text_input.selection_start = caret_position_under_mouse(mouse_x)
end
def keep_caret_visible
@@ -120,7 +174,7 @@ module CyberarmEngine
@caret_last_interval = Gosu.milliseconds
@show_caret = true
move_caret_to_mouse(x)
move_caret_to_mouse(x, y)
return :handled
end
@@ -154,6 +208,29 @@ module CyberarmEngine
return :handled
end
def draggable?(button)
button == :left
end
def begin_drag(sender, x, y, button)
@drag_start = x
@offset_drag_start = @offset_x
@drag_caret_position = @text_input.caret_pos
:handled
end
def drag_update(sender, x, y, button)
@text_input.caret_pos = caret_position_under_mouse(x)
:handled
end
def end_drag(sender, x, y, button)
:handled
end
def recalculate
super

View File

@@ -4,7 +4,12 @@ module CyberarmEngine
def initialize(text, options = {}, block = nil)
super(options, block)
@text = Text.new(text, font: @options[:font], z: @z, color: @options[:color], size: @options[:text_size], shadow: @options[:text_shadow])
@text = Text.new(
text, font: @options[:font], z: @z, color: @options[:color],
size: @options[:text_size], shadow: @options[:text_shadow],
shadow_size: @options[:text_shadow_size],
shadow_color: @options[:text_shadow_color]
)
end
def render

View File

@@ -4,11 +4,22 @@ module CyberarmEngine
attr_reader :toggled
def initialize(options, block = nil)
super(options[:checkmark], options, block)
if options.dig(:theme, :ToggleButton, :checkmark_image)
options[:theme][:ToggleButton][:image_width] ||= options[:theme][:Label][:text_size]
super(get_image(options.dig(:theme, :ToggleButton, :checkmark_image)), options, block)
@_image = @image
else
super(options[:checkmark], options, block)
end
@value = options[:checked] || false
if @value
@image = @_image if @_image
@text.text = @options[:checkmark]
else
@image = nil
@text.text = ""
end
@@ -24,15 +35,19 @@ module CyberarmEngine
end
def recalculate
super
if @image
super
else
super
_width = dimensional_size(@style.width, :width)
_height= dimensional_size(@style.height,:height)
_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
@width = _width ? _width : @text.textobject.text_width(@options[:checkmark])
@height = _height ? _height : @text.height
update_background
update_background
end
end
def value
@@ -43,8 +58,10 @@ module CyberarmEngine
@value = boolean
if boolean
@image = @_image if @_image
@text.text = @options[:checkmark]
else
@image = nil
@text.text = ""
end

View File

@@ -21,6 +21,8 @@ module CyberarmEngine
@mouse_over = nil
@mouse_down_on = {}
@mouse_down_position = {}
@last_mouse_pos = nil
@dragging_element = nil
@pending_recalculate_request = false
@tip = CyberarmEngine::Text.new("", size: 22, z: Float::INFINITY)
@@ -110,6 +112,8 @@ module CyberarmEngine
when Gosu::KbF5
request_recalculate
end
@focus.button_down(id) if @focus.respond_to?(:button_down)
end
def button_up(id)
@@ -127,6 +131,8 @@ module CyberarmEngine
when Gosu::MsWheelDown
redirect_mouse_wheel(:down)
end
@focus.button_up(id) if @focus.respond_to?(:button_up)
end
def redirect_mouse_button(button)