mirror of
https://github.com/cyberarm/cyberarm_engine.git
synced 2025-12-16 13:12:34 +00:00
Added Image and Timer, Container and Element positioning and padding issues maybe fixed.
This commit is contained in:
@@ -8,6 +8,7 @@ require_relative "cyberarm_engine/game_object"
|
||||
require_relative "cyberarm_engine/engine"
|
||||
|
||||
require_relative "cyberarm_engine/objects/text"
|
||||
require_relative "cyberarm_engine/objects/timer"
|
||||
require_relative "cyberarm_engine/objects/multi_line_text"
|
||||
|
||||
require_relative "cyberarm_engine/ui/element"
|
||||
@@ -15,6 +16,7 @@ require_relative "cyberarm_engine/ui/label"
|
||||
require_relative "cyberarm_engine/ui/button"
|
||||
require_relative "cyberarm_engine/ui/check_box"
|
||||
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"
|
||||
|
||||
23
lib/cyberarm_engine/objects/timer.rb
Normal file
23
lib/cyberarm_engine/objects/timer.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
module CyberarmEngine
|
||||
class Timer
|
||||
def initialize(interval, looping = true, &block)
|
||||
@interval = interval
|
||||
@looping = looping
|
||||
@block = block
|
||||
|
||||
@last_interval = Gosu.milliseconds
|
||||
@triggered = false
|
||||
end
|
||||
|
||||
def update
|
||||
return if !@looping && @triggered
|
||||
|
||||
if Gosu.milliseconds >= @last_interval + @interval
|
||||
@last_interval = Gosu.milliseconds
|
||||
@triggered = true
|
||||
|
||||
@block.call if @block
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -3,7 +3,7 @@ module CyberarmEngine
|
||||
def draw
|
||||
@text.draw
|
||||
|
||||
$window.draw_rect(relative_x, relative_y, width, height, @options[:background], @z+1)
|
||||
$window.draw_rect(relative_x, relative_y, width, height, @options[:element_background], @z+1)
|
||||
|
||||
if mouse_over? && $window.button_down?(Gosu::MsLeft)
|
||||
$window.draw_rect(
|
||||
|
||||
@@ -5,8 +5,11 @@ module CyberarmEngine
|
||||
attr_accessor :stroke_color, :fill_color, :background_color, :x, :y, :z, :width, :height
|
||||
attr_reader :elements, :children, :options
|
||||
attr_reader :scroll_x, :scroll_y, :internal_width, :internal_height
|
||||
attr_reader :origin_x, :origin_y, :origin_width, :origin_height
|
||||
|
||||
def initialize(options = {}, block = nil)
|
||||
@parent = options[:parent] || nil
|
||||
|
||||
options = {
|
||||
x: 0, y: 0, z: 0,
|
||||
width: 0, height: 0
|
||||
@@ -27,15 +30,16 @@ module CyberarmEngine
|
||||
raise "#{self.class} 'options' must be a Hash" unless options.is_a?(Hash)
|
||||
|
||||
@x, @y, @z, @width, @height, @internal_width, @internal_height = x, y, z, width-x, height-y, width-x, height-y
|
||||
@origin_x, @origin_x = @x, @x
|
||||
@origin_width, @origin_height = @width, @height
|
||||
@scroll_x, @scroll_y = 0, 0
|
||||
@scroll_speed = 10
|
||||
|
||||
@block = block
|
||||
@options = options
|
||||
@parent = options[:parent] || nil
|
||||
|
||||
@text_color = options[:text_color] || Gosu::Color::WHITE
|
||||
@background_color = Gosu::Color::NONE
|
||||
@text_color = options[:text_color] || Element::THEME[:stroke]
|
||||
@background_color = Element::THEME[:background]
|
||||
|
||||
@elements = []
|
||||
@children = []
|
||||
@@ -65,11 +69,10 @@ module CyberarmEngine
|
||||
end
|
||||
|
||||
def draw
|
||||
Gosu.clip_to(@x, @y, @width, @height) do
|
||||
raise "width and height are 0!" if @width == 0 && @height == 0 && Gosu.milliseconds > 1500 && @elements.size > 0
|
||||
Gosu.clip_to(@x, @y, @width + @spacing_x, @height + @spacing_y) do
|
||||
background
|
||||
|
||||
Gosu.translate(scroll_x, scroll_y) do
|
||||
Gosu.translate(@scroll_x, @scroll_y) do
|
||||
@elements.each(&:draw)
|
||||
end
|
||||
end
|
||||
@@ -80,18 +83,18 @@ module CyberarmEngine
|
||||
end
|
||||
|
||||
def button_up(id)
|
||||
if $window.mouse_x.between?(@x, @x+@width)
|
||||
if $window.mouse_y.between?(@y, @y+@height)
|
||||
if $window.mouse_x.between?(@x, @x + @width)
|
||||
if $window.mouse_y.between?(@y, @y + @height)
|
||||
case id
|
||||
when Gosu::MsWheelUp
|
||||
@scroll_y+=@scroll_speed
|
||||
@scroll_y += @scroll_speed
|
||||
@scroll_y = 0 if @scroll_y > 0
|
||||
when Gosu::MsWheelDown
|
||||
@scroll_y-=@scroll_speed
|
||||
if $window.height-@internal_height-y > 0
|
||||
@scroll_y -= @scroll_speed
|
||||
if $window.height - @internal_height - @y > 0
|
||||
@scroll_y = 0
|
||||
else
|
||||
@scroll_y = @height-@internal_height if @scroll_y <= @height-@internal_height
|
||||
@scroll_y = @height - @internal_height if @scroll_y <= @height - @internal_height
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -113,7 +116,7 @@ module CyberarmEngine
|
||||
end
|
||||
|
||||
def background
|
||||
Gosu.draw_rect(@x, @y, @width, @height, @background_color, @z)
|
||||
Gosu.draw_rect(@x, @y, @width + @spacing_x, @height + @spacing_y, @background_color, @z)
|
||||
end
|
||||
|
||||
def recalculate
|
||||
@@ -123,8 +126,13 @@ module CyberarmEngine
|
||||
@packing_x = 0
|
||||
@packing_y = 0
|
||||
|
||||
@width = 0
|
||||
@height= 0
|
||||
@spacing_x = 0
|
||||
@spacing_y = 0
|
||||
|
||||
@spacer = 1
|
||||
|
||||
@width = @origin_width
|
||||
@height= @origin_height
|
||||
|
||||
@elements.each do |element|
|
||||
flow(element) if @mode == :flow
|
||||
@@ -132,29 +140,39 @@ module CyberarmEngine
|
||||
|
||||
case @mode
|
||||
when :flow
|
||||
@width += element.width
|
||||
@height = element.height if element.height > @height
|
||||
@width += element.width unless @origin_width.nonzero?
|
||||
@height = element.height if element.height > @height unless @origin_height.nonzero?
|
||||
when :stack
|
||||
@height += element.height
|
||||
@width = element.width if element.width > @width
|
||||
@width = element.width if element.width > @width unless @origin_width.nonzero?
|
||||
@height += element.height unless @origin_height.nonzero?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def flow(element)
|
||||
element.x = @packing_x
|
||||
if element.is_a?(Container)
|
||||
element.y = @y
|
||||
else
|
||||
element.y = 0
|
||||
end
|
||||
element.recalculate
|
||||
|
||||
@packing_x += element.width + 1
|
||||
@packing_x += element.width + @spacer
|
||||
@spacing_x += @spacer
|
||||
end
|
||||
|
||||
def stack(element)
|
||||
if element.is_a?(Container)
|
||||
element.x = @x
|
||||
else
|
||||
element.x = 0
|
||||
end
|
||||
element.y = @packing_y
|
||||
element.recalculate
|
||||
|
||||
@packing_y += element.height + 1
|
||||
@packing_y += element.height + @spacer
|
||||
@spacing_y += @spacer
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,8 +1,8 @@
|
||||
module CyberarmEngine
|
||||
module DSL
|
||||
def flow(options = {}, &block)
|
||||
puts "Flow"
|
||||
options[:parent] = @containers.last
|
||||
puts "Flow"
|
||||
_container = Flow.new(options, block)
|
||||
@containers << _container
|
||||
_container.build
|
||||
@@ -13,8 +13,8 @@ module CyberarmEngine
|
||||
end
|
||||
|
||||
def stack(options = {}, &block)
|
||||
puts "Stack"
|
||||
options[:parent] = @containers.last
|
||||
puts "Stack"
|
||||
_container = Stack.new(options, block)
|
||||
@containers << _container
|
||||
_container.build
|
||||
@@ -56,6 +56,14 @@ module CyberarmEngine
|
||||
return _element
|
||||
end
|
||||
|
||||
def image(path, options = {}, &block)
|
||||
options[:parent] = @containers.last
|
||||
_element = Image.new(path, options, block)
|
||||
@containers.last.add(_element)
|
||||
|
||||
return _element
|
||||
end
|
||||
|
||||
def background(color = Gosu::Color::NONE)
|
||||
@containers.last.background_color = color
|
||||
end
|
||||
|
||||
@@ -1,107 +1,80 @@
|
||||
module CyberarmEngine
|
||||
class EditLine < Element
|
||||
WIDTH = 200
|
||||
FOCUS_BACKGROUND_COLOR = Gosu::Color.rgb(150,150,144)
|
||||
NO_FOCUS_BACKGROUND_COLOR = Gosu::Color.rgb(130,130,130)
|
||||
class EditLine < Button
|
||||
def initialize(text, options = {}, block = nil)
|
||||
super(text, options, block)
|
||||
|
||||
attr_accessor :text, :x, :y, :width, :size, :color, :type, :focus
|
||||
attr_reader :text_object, :text_input, :height
|
||||
@type = @options[:type] || :plain
|
||||
|
||||
def initialize(text, options = {})
|
||||
@text = text
|
||||
@x, @y= x, y
|
||||
@width= width
|
||||
@size = size
|
||||
@color= color
|
||||
@tooltip=tooltip
|
||||
@type = type
|
||||
|
||||
@focus = false
|
||||
@caret_width = @options[:caret_width]
|
||||
@caret_height= @text.height
|
||||
@caret_color = @options[:caret_color]
|
||||
@caret_interval = @options[:caret_interval]
|
||||
@caret_last_interval = Gosu.milliseconds
|
||||
@show_caret = true
|
||||
|
||||
@text_object = Text.new(text, x: x, y: y, size: size, color: color, shadow: true)
|
||||
@height = @text_object.height
|
||||
@text_input = Gosu::TextInput.new
|
||||
@text_input.text = @text
|
||||
|
||||
@background_color = NO_FOCUS_BACKGROUND_COLOR
|
||||
|
||||
@carot_ticks = 0
|
||||
@carot_width = 2.5
|
||||
@carot_height= @text_object.height
|
||||
@carot_color = Gosu::Color.rgb(50,50,25)
|
||||
@carot_show_ticks = 25
|
||||
@show_carot = true
|
||||
@text_input.text = text
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
def text=(string)
|
||||
@text = string
|
||||
@text_input.text, @text_object.text = @text, @text
|
||||
end
|
||||
|
||||
def draw
|
||||
$window.draw_rect(x, y, width, height, Gosu::Color::BLACK)
|
||||
$window.draw_rect(x+1, y+1, width-2, height-2, @background_color)
|
||||
Gosu.clip_to(x, @text_object.y, width, @text_object.height) do
|
||||
@text_object.draw
|
||||
Gosu.clip_to(relative_x, relative_y, width, height) do
|
||||
super
|
||||
|
||||
# Carot (Cursor)
|
||||
$window.draw_rect((@x+@text_object.width)-@x_offset, @text_object.y, @carot_width, @carot_height, @carot_color) if @show_carot && @focus
|
||||
Gosu.draw_rect(caret_position, @text.y, @caret_width, @caret_height, @caret_color, @z + 40) if @show_caret
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def update
|
||||
@text_object.y = @y+BUTTON_PADDING
|
||||
|
||||
if (@text_object.width+@carot_width)-@width >= 0
|
||||
@x_offset = (@text_object.width+@carot_width)-@width
|
||||
if @type == :password
|
||||
@text.text = @options[:edit_line_password_character] * @text_input.text.length
|
||||
else
|
||||
@x_offset = 0
|
||||
@text.text = @text_input.text
|
||||
end
|
||||
|
||||
@text = @text_object.text
|
||||
@carot_ticks+=1
|
||||
if @carot_ticks >= @carot_show_ticks
|
||||
if @show_carot
|
||||
@show_carot = false
|
||||
else
|
||||
@show_carot = true
|
||||
if Gosu.milliseconds >= @caret_last_interval + @caret_interval
|
||||
@caret_last_interval = Gosu.milliseconds
|
||||
|
||||
@show_caret = !@show_caret
|
||||
end
|
||||
end
|
||||
|
||||
@carot_ticks = 0
|
||||
end
|
||||
def button_up(id)
|
||||
case id
|
||||
when Gosu::MsLeft
|
||||
if mouse_over?
|
||||
@focus = !@focus
|
||||
|
||||
if @focus
|
||||
@text_object.text = @text_input.text
|
||||
$window.text_input = @text_input unless $window.text_input == @text_input
|
||||
end
|
||||
|
||||
if mouse_over? && $window.button_down?(Gosu::MsLeft)
|
||||
@focus = true
|
||||
@background_color = FOCUS_BACKGROUND_COLOR
|
||||
end
|
||||
if !mouse_over? && $window.button_down?(Gosu::MsLeft)
|
||||
@focus = false
|
||||
$window.text_input = nil
|
||||
@background_color = NO_FOCUS_BACKGROUND_COLOR
|
||||
end
|
||||
|
||||
if @text_object.width >= @width
|
||||
@text_object.x = self.fixed_x-@x_offset
|
||||
$window.text_input = @text_input
|
||||
else
|
||||
@text_object.x = self.fixed_x
|
||||
$window.text_input = nil
|
||||
end
|
||||
@block.call(self) if @block
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def width(text_object = @text_object)
|
||||
# text_object.textobject.text_width(text_object.text)+BUTTON_PADDING*2
|
||||
@width
|
||||
def caret_position
|
||||
if $window.text_input && $window.text_input == @text_input
|
||||
if @type == :password
|
||||
@text.x + @text.textobject.text_width(@options[:edit_line_password_character] * @text_input.text[0..@text_input.caret_pos].length)
|
||||
else
|
||||
@text.x + @text.textobject.text_width(@text_input.text[0..@text_input.caret_pos])
|
||||
end
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
def height(text_object = @text_object)
|
||||
text_object.textobject.height+BUTTON_PADDING*2
|
||||
def width
|
||||
@options[:edit_line_width]
|
||||
end
|
||||
|
||||
def value
|
||||
@text_input.text
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -12,12 +12,14 @@ module CyberarmEngine
|
||||
THEME = {
|
||||
stroke: Gosu::Color::WHITE,
|
||||
fill: Gosu::Color::NONE,
|
||||
background: Gosu::Color.rgb(12,12,12),
|
||||
checkmark: "X", # ✓
|
||||
background: Gosu::Color::NONE,
|
||||
checkmark: "√", # √
|
||||
|
||||
padding: 20,
|
||||
margin: 0,
|
||||
|
||||
element_background: Gosu::Color.rgb(12,12,12),
|
||||
|
||||
interactive_stroke: Gosu::Color::WHITE,
|
||||
interactive_active_stroke: Gosu::Color::GRAY,
|
||||
|
||||
@@ -26,12 +28,20 @@ module CyberarmEngine
|
||||
interactive_active_background: Gosu::Color.rgb(50, 50, 50),
|
||||
interactive_border_size: 1,
|
||||
|
||||
edit_line_width: 200,
|
||||
edit_line_password_character: "•", # •
|
||||
caret_width: 2,
|
||||
caret_color: Gosu::Color.rgb(50,50,25),
|
||||
caret_interval: 500,
|
||||
|
||||
image_retro: false,
|
||||
|
||||
text_size: 22,
|
||||
text_shadow: true,
|
||||
font: "Consolas"
|
||||
}
|
||||
|
||||
attr_accessor :x, :y, :z, :width, :height, :padding, :margin
|
||||
attr_accessor :x, :y, :z, :width, :height, :padding, :margin, :focus
|
||||
|
||||
def initialize(options = {}, block = nil)
|
||||
@parent = options[:parent] # parent Container (i.e. flow/stack)
|
||||
@@ -48,6 +58,8 @@ module CyberarmEngine
|
||||
|
||||
@padding = options[:padding]
|
||||
@margin = options[:margin]
|
||||
|
||||
@focus = false
|
||||
end
|
||||
|
||||
def draw
|
||||
|
||||
35
lib/cyberarm_engine/ui/image.rb
Normal file
35
lib/cyberarm_engine/ui/image.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
module CyberarmEngine
|
||||
class Image < Element
|
||||
def initialize(path, options = {}, block = nil)
|
||||
super(options, block)
|
||||
|
||||
@image = Gosu::Image.new(path, retro: @options[:image_retro])
|
||||
if @options[:width].nonzero? && @options[:height].nonzero?
|
||||
@scale_x = @options[:width].to_f / @image.width
|
||||
@scale_y = @options[:height].to_f / @image.height
|
||||
elsif @options[:width].nonzero?
|
||||
@scale_x = @options[:width].to_f / @image.width
|
||||
@scale_y = @scale_x
|
||||
elsif @options[:height].nonzero?
|
||||
@scale_y = @options[:height].to_f / @image.height
|
||||
@scale_x = @scale_y
|
||||
else
|
||||
@scale_x, @scale_y = 1, 1
|
||||
end
|
||||
|
||||
raise "Scale X" unless @scale_x.is_a?(Numeric)
|
||||
raise "Scale Y" unless @scale_y.is_a?(Numeric)
|
||||
end
|
||||
|
||||
def draw
|
||||
$window.draw_rect(relative_x, relative_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?
|
||||
end
|
||||
|
||||
def recalculate
|
||||
@width = @image.width * @scale_x
|
||||
@height = @image.height * @scale_y
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user