mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-07 13:15:01 +00:00
Implemented list control and basic animation-choosing screen for editor
This commit is contained in:
@@ -19,8 +19,8 @@ module GameData
|
|||||||
extend ClassMethodsIDNumbers
|
extend ClassMethodsIDNumbers
|
||||||
include InstanceMethods
|
include InstanceMethods
|
||||||
|
|
||||||
def register(hash)
|
def register(hash, id = -1)
|
||||||
DATA[DATA.keys.length] = self.new(hash)
|
DATA[(id >= 0) ? id : DATA.keys.length] = self.new(hash)
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: Rewrite this to query animations from other criteria. Remember that
|
# TODO: Rewrite this to query animations from other criteria. Remember that
|
||||||
@@ -59,5 +59,9 @@ module GameData
|
|||||||
def move_animation?
|
def move_animation?
|
||||||
return !@move.nil?
|
return !@move.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO: Create a def to_hash or something, which returns a hash copy version
|
||||||
|
# of this Animation object which can be edited. This hash should be
|
||||||
|
# able to be passed into def register (with an ID number).
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -85,6 +85,11 @@ class UIControls::BaseControl < BitmapSprite
|
|||||||
this_bitmap.draw_text(text_x, text_y, text_size.width, text_size.height, this_text, 0)
|
this_bitmap.draw_text(text_x, text_y, text_size.width, text_size.height, this_text, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def draw_text_centered(this_bitmap, text_x, text_y, wid, this_text)
|
||||||
|
text_size = this_bitmap.text_size(this_text)
|
||||||
|
this_bitmap.draw_text(text_x, text_y, wid, text_size.height, this_text, 1)
|
||||||
|
end
|
||||||
|
|
||||||
# Redraws the control only if it is invalid.
|
# Redraws the control only if it is invalid.
|
||||||
def repaint
|
def repaint
|
||||||
return if !invalid?
|
return if !invalid?
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
# NOTE: Strictly speaking, this is a toggle switch and not a checkbox.
|
# NOTE: Strictly speaking, this is a toggle switch and not a checkbox.
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
class UIControls::Checkbox < UIControls::BaseControl
|
class UIControls::Checkbox < UIControls::BaseControl
|
||||||
CHECKBOX_X = 0
|
CHECKBOX_X = 2
|
||||||
CHECKBOX_WIDTH = 40
|
CHECKBOX_WIDTH = 40
|
||||||
CHECKBOX_HEIGHT = 24
|
CHECKBOX_HEIGHT = 24
|
||||||
CHECKBOX_FILL_SIZE = CHECKBOX_HEIGHT - 8
|
CHECKBOX_FILL_SIZE = CHECKBOX_HEIGHT - 4
|
||||||
|
|
||||||
UNCHECKED_COLOR = Color.gray
|
UNCHECKED_COLOR = Color.gray
|
||||||
CHECKED_COLOR = Color.new(64, 255, 64) # Green
|
CHECKED_COLOR = Color.new(64, 255, 64) # Green
|
||||||
@@ -34,19 +34,19 @@ class UIControls::Checkbox < UIControls::BaseControl
|
|||||||
def refresh
|
def refresh
|
||||||
super
|
super
|
||||||
# Draw checkbox outline
|
# Draw checkbox outline
|
||||||
self.bitmap.outline_rect(@checkbox_rect.x + 2, @checkbox_rect.y + 2,
|
self.bitmap.outline_rect(@checkbox_rect.x, @checkbox_rect.y,
|
||||||
@checkbox_rect.width - 4, @checkbox_rect.height - 4,
|
@checkbox_rect.width, @checkbox_rect.height,
|
||||||
self.bitmap.font.color)
|
self.bitmap.font.color)
|
||||||
# Draw checkbox fill
|
# Draw checkbox fill
|
||||||
if @value # If checked
|
if @value # If checked
|
||||||
self.bitmap.fill_rect(@checkbox_rect.x + @checkbox_rect.width - CHECKBOX_FILL_SIZE - 4, @checkbox_rect.y + 4,
|
self.bitmap.fill_rect(@checkbox_rect.x + @checkbox_rect.width - CHECKBOX_FILL_SIZE - 2, @checkbox_rect.y + 2,
|
||||||
CHECKBOX_FILL_SIZE, CHECKBOX_FILL_SIZE, CHECKED_COLOR)
|
CHECKBOX_FILL_SIZE, CHECKBOX_FILL_SIZE, CHECKED_COLOR)
|
||||||
self.bitmap.outline_rect(@checkbox_rect.x + @checkbox_rect.width - CHECKBOX_FILL_SIZE - 4, @checkbox_rect.y + 4,
|
self.bitmap.outline_rect(@checkbox_rect.x + @checkbox_rect.width - CHECKBOX_FILL_SIZE - 2, @checkbox_rect.y + 2,
|
||||||
CHECKBOX_FILL_SIZE, CHECKBOX_FILL_SIZE, self.bitmap.font.color)
|
CHECKBOX_FILL_SIZE, CHECKBOX_FILL_SIZE, self.bitmap.font.color)
|
||||||
else
|
else
|
||||||
self.bitmap.fill_rect(@checkbox_rect.x + 4, @checkbox_rect.y + 4,
|
self.bitmap.fill_rect(@checkbox_rect.x + 2, @checkbox_rect.y + 2,
|
||||||
CHECKBOX_FILL_SIZE, CHECKBOX_FILL_SIZE, UNCHECKED_COLOR)
|
CHECKBOX_FILL_SIZE, CHECKBOX_FILL_SIZE, UNCHECKED_COLOR)
|
||||||
self.bitmap.outline_rect(@checkbox_rect.x + 4, @checkbox_rect.y + 4,
|
self.bitmap.outline_rect(@checkbox_rect.x + 2, @checkbox_rect.y + 2,
|
||||||
CHECKBOX_FILL_SIZE, CHECKBOX_FILL_SIZE, self.bitmap.font.color)
|
CHECKBOX_FILL_SIZE, CHECKBOX_FILL_SIZE, self.bitmap.font.color)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ class UIControls::Slider < UIControls::BaseControl
|
|||||||
VALUE_X = PLUS_X + PLUS_MINUS_SIZE + 5
|
VALUE_X = PLUS_X + PLUS_MINUS_SIZE + 5
|
||||||
TEXT_OFFSET_Y = 7
|
TEXT_OFFSET_Y = 7
|
||||||
|
|
||||||
SLIDER_KNOB_COLOR = Color.red
|
# TODO: Is there a better knob design than a big black rectangle? I'd rather
|
||||||
|
# it not be a different colour.
|
||||||
|
SLIDER_KNOB_COLOR = Color.black
|
||||||
|
|
||||||
def initialize(width, height, viewport, min_value, max_value, value)
|
def initialize(width, height, viewport, min_value, max_value, value)
|
||||||
super(width, height, viewport)
|
super(width, height, viewport)
|
||||||
|
|||||||
@@ -2,20 +2,28 @@
|
|||||||
#
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
class UIControls::Button < UIControls::BaseControl
|
class UIControls::Button < UIControls::BaseControl
|
||||||
BUTTON_X = 2
|
BUTTON_X = 2
|
||||||
BUTTON_PADDING = 10
|
BUTTON_Y = 2
|
||||||
BUTTON_HEIGHT = 28
|
BUTTON_PADDING = 10
|
||||||
TEXT_OFFSET_Y = 7
|
BUTTON_HEIGHT = 28
|
||||||
|
# TODO: This will also depend on the font size.
|
||||||
|
TEXT_BASE_OFFSET_Y = 18 # Text is centred vertically in the button
|
||||||
|
|
||||||
def initialize(width, height, viewport, text = "")
|
def initialize(width, height, viewport, text = "")
|
||||||
super(width, height, viewport)
|
super(width, height, viewport)
|
||||||
@text = text
|
@text = text
|
||||||
|
@fixed_size = false
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_fixed_size
|
||||||
|
@fixed_size = true
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_interactive_rects
|
def set_interactive_rects
|
||||||
text_width = self.bitmap.text_size(@text).width
|
button_width = (@fixed_size) ? width - (BUTTON_X * 2) : self.bitmap.text_size(@text).width + (BUTTON_PADDING * 2)
|
||||||
@button_rect = Rect.new(BUTTON_X, (height - BUTTON_HEIGHT) / 2,
|
button_height = (@fixed_size) ? height - (2 * BUTTON_Y) : BUTTON_HEIGHT
|
||||||
text_width + (BUTTON_PADDING * 2), BUTTON_HEIGHT)
|
button_height = [button_height, height - (2 * BUTTON_Y)].min
|
||||||
|
@button_rect = Rect.new(BUTTON_X, (height - button_height) / 2, button_width, button_height)
|
||||||
@interactions = {
|
@interactions = {
|
||||||
:button => @button_rect
|
:button => @button_rect
|
||||||
}
|
}
|
||||||
@@ -23,15 +31,22 @@ class UIControls::Button < UIControls::BaseControl
|
|||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
# TODO: Make buttons look more different to text boxes?
|
|
||||||
def refresh
|
def refresh
|
||||||
super
|
super
|
||||||
# Draw button outline
|
# Draw button outline
|
||||||
self.bitmap.outline_rect(@button_rect.x, @button_rect.y,
|
self.bitmap.outline_rect(@button_rect.x, @button_rect.y,
|
||||||
@button_rect.width, @button_rect.height,
|
@button_rect.width, @button_rect.height,
|
||||||
self.bitmap.font.color)
|
self.bitmap.font.color)
|
||||||
|
# TODO: Make buttons look more different to text boxes?
|
||||||
|
# shade = self.bitmap.font.color.clone
|
||||||
|
# shade.alpha = 96
|
||||||
|
# self.bitmap.outline_rect(@button_rect.x + 1, @button_rect.y + 1,
|
||||||
|
# @button_rect.width - 2, @button_rect.height - 2,
|
||||||
|
# shade, 3)
|
||||||
# Draw button text
|
# Draw button text
|
||||||
draw_text(self.bitmap, BUTTON_X + BUTTON_PADDING, TEXT_OFFSET_Y, @text)
|
draw_text_centered(self.bitmap, @button_rect.x,
|
||||||
|
@button_rect.y + (@button_rect.height - TEXT_BASE_OFFSET_Y) / 2,
|
||||||
|
@button_rect.width, @text)
|
||||||
end
|
end
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -1,13 +1,228 @@
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO
|
# TODO: Do I need to split self's bitmap into two (one for highlights and one
|
||||||
# TODO: Click an option to select it. It remains selected indefinitely. Once an
|
# for text/slider)? This would be to reduce lag caused by redrawing text
|
||||||
# option is selected, there's probably no way to unselect everything; the
|
# and the slider even if you're just waving the mouse over the control.
|
||||||
# selection can only be moved to a different option.
|
# There doesn't seem to be any lag at the moment with a tall list.
|
||||||
# TODO: Scrollable.
|
|
||||||
# TODO: Find some way to not redraw the entire thing if the hovered option
|
|
||||||
# changes. Maybe have another bitmap to write the text on (refreshed only
|
|
||||||
# when the list is scrolled), and self's bitmap draws the hover colour
|
|
||||||
# only.
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
class UIControls::List < UIControls::BaseControl
|
class UIControls::List < UIControls::BaseControl
|
||||||
|
LIST_X = 0
|
||||||
|
LIST_Y = 0
|
||||||
|
ROW_HEIGHT = 24
|
||||||
|
TEXT_PADDING_X = 4
|
||||||
|
TEXT_OFFSET_Y = 3
|
||||||
|
SLIDER_WIDTH = 16
|
||||||
|
|
||||||
|
SELECTED_ROW_COLOR = Color.green
|
||||||
|
|
||||||
|
def initialize(width, height, viewport, values = [])
|
||||||
|
super(width, height, viewport)
|
||||||
|
@rows_count = (height / ROW_HEIGHT).floor # Number of rows visible at once
|
||||||
|
@top_row = 0
|
||||||
|
@selected = -1
|
||||||
|
@show_slider = false
|
||||||
|
self.values = values
|
||||||
|
end
|
||||||
|
|
||||||
|
# Each value in @values is an array: [id, text].
|
||||||
|
def values=(new_vals)
|
||||||
|
@values = new_vals
|
||||||
|
@show_slider = (@values.length > @rows_count)
|
||||||
|
set_interactive_rects
|
||||||
|
if @show_slider
|
||||||
|
self.top_row = @top_row
|
||||||
|
else
|
||||||
|
self.top_row = 0
|
||||||
|
end
|
||||||
|
invalidate
|
||||||
|
end
|
||||||
|
|
||||||
|
def top_row=(val)
|
||||||
|
old_val = @top_row
|
||||||
|
@top_row = val
|
||||||
|
if @show_slider
|
||||||
|
@top_row = @top_row.clamp(0, @values.length - @rows_count)
|
||||||
|
@slider.y = lerp(0, height - @slider.height, @values.length - @rows_count, 0, @top_row).round
|
||||||
|
else
|
||||||
|
@top_row = 0
|
||||||
|
end
|
||||||
|
invalidate if @top_row != old_val
|
||||||
|
end
|
||||||
|
|
||||||
|
def selected=(val)
|
||||||
|
return if @selected == val
|
||||||
|
@selected = val
|
||||||
|
invalidate
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the ID of the selected row.
|
||||||
|
def value
|
||||||
|
return nil if @selected < 0
|
||||||
|
return @values[@selected][0]
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_interactive_rects
|
||||||
|
@interactions = {}
|
||||||
|
@slider = nil
|
||||||
|
if @show_slider
|
||||||
|
@slider = Rect.new(LIST_X + width - SLIDER_WIDTH, LIST_Y,
|
||||||
|
SLIDER_WIDTH, height * @rows_count / @values.length)
|
||||||
|
@interactions[:slider] = @slider
|
||||||
|
@slider_tray = Rect.new(LIST_X + width - SLIDER_WIDTH, LIST_Y, SLIDER_WIDTH, height)
|
||||||
|
@interactions[:slider_tray] = @slider_tray
|
||||||
|
end
|
||||||
|
@values.length.times do |i|
|
||||||
|
@interactions[i] = Rect.new(LIST_X, LIST_Y + (ROW_HEIGHT * i), width - LIST_X, ROW_HEIGHT)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def busy?
|
||||||
|
return !@captured_area.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def draw_area_highlight
|
||||||
|
# If a row is captured, it will automatically be selected and the selection
|
||||||
|
# colour will be drawn over the highlight. The slider tray background
|
||||||
|
# (white) is drawn over the slider/slider tray's highlight. Either way,
|
||||||
|
# there's no point drawing a highlight at all if anything is captured.
|
||||||
|
return if @captured_area
|
||||||
|
# The slider tray background (white) is drawn over the slider/slider tray's
|
||||||
|
# highlight. There's no point drawing any highlight for the slider now; this
|
||||||
|
# is done in def refresh instead.
|
||||||
|
return if [:slider, :slider_tray].include?(@hover_area)
|
||||||
|
# Draw mouse hover over row highlight
|
||||||
|
rect = @interactions[@hover_area]
|
||||||
|
if rect
|
||||||
|
rect_y = rect.y
|
||||||
|
rect_y -= @top_row * ROW_HEIGHT if @hover_area.is_a?(Integer)
|
||||||
|
self.bitmap.fill_rect(rect.x, rect_y, rect.width, rect.height, HOVER_COLOR)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def refresh
|
||||||
|
super
|
||||||
|
# Draw text options
|
||||||
|
@values.each_with_index do |val, i|
|
||||||
|
next if i < @top_row || i >= @top_row + @rows_count
|
||||||
|
if @selected == i
|
||||||
|
self.bitmap.fill_rect(
|
||||||
|
@interactions[i].x,
|
||||||
|
@interactions[i].y - (@top_row * ROW_HEIGHT),
|
||||||
|
@interactions[i].width, @interactions[i].height,
|
||||||
|
SELECTED_ROW_COLOR
|
||||||
|
)
|
||||||
|
end
|
||||||
|
draw_text(self.bitmap,
|
||||||
|
@interactions[i].x + TEXT_PADDING_X,
|
||||||
|
@interactions[i].y + TEXT_OFFSET_Y - (@top_row * ROW_HEIGHT),
|
||||||
|
val[1])
|
||||||
|
end
|
||||||
|
# Draw vertical slider
|
||||||
|
if @show_slider
|
||||||
|
self.bitmap.fill_rect(@slider_tray.x, @slider_tray.y, @slider_tray.width, @slider_tray.height, Color.white)
|
||||||
|
bar_color = self.bitmap.font.color
|
||||||
|
if @captured_area == :slider || (!@captured_area && @hover_area == :slider)
|
||||||
|
bar_color = HOVER_COLOR
|
||||||
|
end
|
||||||
|
self.bitmap.fill_rect(@slider.x + 1, @slider.y, @slider.width - 1, @slider.height, bar_color)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def on_mouse_press
|
||||||
|
@captured_area = nil
|
||||||
|
mouse_x, mouse_y = mouse_pos
|
||||||
|
return if !mouse_x || !mouse_y
|
||||||
|
# Check for mouse presses on slider/slider tray
|
||||||
|
@interactions.each_pair do |area, rect|
|
||||||
|
next if area.is_a?(Integer)
|
||||||
|
next if !rect.contains?(mouse_x, mouse_y)
|
||||||
|
@captured_area = area
|
||||||
|
@slider_mouse_offset = mouse_y - rect.y if area == :slider
|
||||||
|
invalidate
|
||||||
|
break
|
||||||
|
end
|
||||||
|
return if @captured_area
|
||||||
|
# Check for mouse presses on rows
|
||||||
|
mouse_y += @top_row * ROW_HEIGHT
|
||||||
|
@interactions.each_pair do |area, rect|
|
||||||
|
next if !area.is_a?(Integer) || area < @top_row || area >= @top_row + @rows_count
|
||||||
|
next if !rect.contains?(mouse_x, mouse_y)
|
||||||
|
@captured_area = area
|
||||||
|
invalidate
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def on_mouse_release
|
||||||
|
return if !@captured_area # Wasn't captured to begin with
|
||||||
|
set_changed if @captured_area != :slider
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_hover_highlight
|
||||||
|
# Remove the hover highlight if there are no interactions for this control
|
||||||
|
# or if the mouse is off-screen
|
||||||
|
mouse_x, mouse_y = mouse_pos
|
||||||
|
if !@interactions || @interactions.empty? || !mouse_x || !mouse_y
|
||||||
|
invalidate if @hover_area
|
||||||
|
@hover_area = nil
|
||||||
|
return
|
||||||
|
end
|
||||||
|
# Check each interactive area for whether the mouse is hovering over it, and
|
||||||
|
# set @hover_area accordingly
|
||||||
|
in_area = false
|
||||||
|
@interactions.each_pair do |area, rect|
|
||||||
|
next if area.is_a?(Integer)
|
||||||
|
next if !rect.contains?(mouse_x, mouse_y)
|
||||||
|
invalidate if @hover_area != area
|
||||||
|
@hover_area = area
|
||||||
|
in_area = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if !in_area
|
||||||
|
mouse_y += @top_row * ROW_HEIGHT
|
||||||
|
@interactions.each_pair do |area, rect|
|
||||||
|
next if !area.is_a?(Integer) || area < @top_row || area >= @top_row + @rows_count
|
||||||
|
next if !rect.contains?(mouse_x, mouse_y)
|
||||||
|
invalidate if @hover_area != area
|
||||||
|
@hover_area = area
|
||||||
|
in_area = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if !in_area
|
||||||
|
invalidate if @hover_area
|
||||||
|
@hover_area = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
super
|
||||||
|
# TODO: Disabled control stuff.
|
||||||
|
# return if self.disabled
|
||||||
|
if @captured_area == :slider
|
||||||
|
# TODO: Have a display y position for the slider bar which is in pixels,
|
||||||
|
# and round it to the nearest row when setting @top_row? This is
|
||||||
|
# just to make the slider bar movement smoother.
|
||||||
|
mouse_x, mouse_y = mouse_pos
|
||||||
|
return if !mouse_x || !mouse_y
|
||||||
|
self.top_row = lerp(0, @values.length - @rows_count, height - @slider.height, 0, mouse_y - @slider_mouse_offset).round
|
||||||
|
elsif @captured_area == :slider_tray
|
||||||
|
if Input.repeat?(Input::MOUSELEFT) && @hover_area == :slider_tray
|
||||||
|
if mouse_y < @slider.y
|
||||||
|
self.top_row = @top_row - (@rows_count / 2)
|
||||||
|
else
|
||||||
|
self.top_row = @top_row + (@rows_count / 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elsif @captured_area
|
||||||
|
# Have clicked on a row; set the selected row to the row themouse is over
|
||||||
|
@selected = @hover_area if @hover_area.is_a?(Integer)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,11 +9,19 @@ class AnimationEditorLoadScreen
|
|||||||
ANIMATIONS_LIST_WIDTH = 300
|
ANIMATIONS_LIST_WIDTH = 300
|
||||||
ANIMATIONS_LIST_HEIGHT = WINDOW_HEIGHT - (ANIMATIONS_LIST_Y * 2)
|
ANIMATIONS_LIST_HEIGHT = WINDOW_HEIGHT - (ANIMATIONS_LIST_Y * 2)
|
||||||
|
|
||||||
|
LOAD_BUTTON_WIDTH = 200
|
||||||
|
LOAD_BUTTON_HEIGHT = 48
|
||||||
|
LOAD_BUTTON_X = ANIMATIONS_LIST_WIDTH + 100
|
||||||
|
LOAD_BUTTON_Y = ANIMATIONS_LIST_Y + (ANIMATIONS_LIST_HEIGHT / 2) - (LOAD_BUTTON_HEIGHT / 2)
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@viewport = Viewport.new(0, 0, AnimationEditor::WINDOW_WIDTH, AnimationEditor::WINDOW_HEIGHT)
|
generate_list
|
||||||
|
@viewport = Viewport.new(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT)
|
||||||
@viewport.z = 99999
|
@viewport.z = 99999
|
||||||
@screen_bitmap = BitmapSprite.new(AnimationEditor::WINDOW_WIDTH, AnimationEditor::WINDOW_HEIGHT, @viewport)
|
@screen_bitmap = BitmapSprite.new(WINDOW_WIDTH, WINDOW_HEIGHT, @viewport)
|
||||||
draw_editor_background
|
draw_editor_background
|
||||||
|
@load_animation_id = nil
|
||||||
|
create_controls
|
||||||
end
|
end
|
||||||
|
|
||||||
def dispose
|
def dispose
|
||||||
@@ -21,32 +29,86 @@ class AnimationEditorLoadScreen
|
|||||||
@viewport.dispose
|
@viewport.dispose
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def generate_list
|
||||||
|
@animations = []
|
||||||
|
# TODO: Look through GameData to populate @animations; below is temporary.
|
||||||
|
# There will be separate arrays for move animations, common animations
|
||||||
|
# and overworld animations. The move animations one will primarily be
|
||||||
|
# a list of moves that have any animations, with the actual GameData
|
||||||
|
# animations being in a sub-array for each move.
|
||||||
|
67.times { |i| @animations.push([i, "Animation #{i + 1}"]) }
|
||||||
|
end
|
||||||
|
|
||||||
def draw_editor_background
|
def draw_editor_background
|
||||||
# Fill the whole screen with black
|
# Fill the whole screen with white
|
||||||
@screen_bitmap.bitmap.fill_rect(
|
@screen_bitmap.bitmap.fill_rect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, Color.black)
|
||||||
0, 0, AnimationEditor::WINDOW_WIDTH, AnimationEditor::WINDOW_HEIGHT, Color.black
|
|
||||||
)
|
|
||||||
# Outline around animations list
|
# Outline around animations list
|
||||||
@screen_bitmap.bitmap.outline_rect(
|
areas = [
|
||||||
ANIMATIONS_LIST_X - 3, ANIMATIONS_LIST_Y - 3,
|
[ANIMATIONS_LIST_X, ANIMATIONS_LIST_Y, ANIMATIONS_LIST_WIDTH, ANIMATIONS_LIST_HEIGHT],
|
||||||
ANIMATIONS_LIST_WIDTH + 6, ANIMATIONS_LIST_HEIGHT + 6, Color.white
|
[LOAD_BUTTON_X, LOAD_BUTTON_Y, LOAD_BUTTON_WIDTH, LOAD_BUTTON_HEIGHT]
|
||||||
)
|
]
|
||||||
@screen_bitmap.bitmap.outline_rect(
|
areas.each do |area|
|
||||||
ANIMATIONS_LIST_X - 2, ANIMATIONS_LIST_Y - 2,
|
# Draw outlines around area
|
||||||
ANIMATIONS_LIST_WIDTH + 4, ANIMATIONS_LIST_HEIGHT + 4, Color.black
|
@screen_bitmap.bitmap.outline_rect(area[0] - 3, area[1] - 3, area[2] + 6, area[3] + 6, Color.white)
|
||||||
)
|
@screen_bitmap.bitmap.outline_rect(area[0] - 2, area[1] - 2, area[2] + 4, area[3] + 4, Color.black)
|
||||||
@screen_bitmap.bitmap.outline_rect(
|
@screen_bitmap.bitmap.outline_rect(area[0] - 1, area[1] - 1, area[2] + 2, area[3] + 2, Color.white)
|
||||||
ANIMATIONS_LIST_X - 1, ANIMATIONS_LIST_Y - 1,
|
# Fill the area with white
|
||||||
ANIMATIONS_LIST_WIDTH + 2, ANIMATIONS_LIST_HEIGHT + 2, Color.white
|
# @screen_bitmap.bitmap.fill_rect(area[0], area[1], area[2], area[3], Color.white)
|
||||||
)
|
end
|
||||||
# Fill the animations list with white
|
end
|
||||||
@screen_bitmap.bitmap.fill_rect(
|
|
||||||
ANIMATIONS_LIST_X, ANIMATIONS_LIST_Y, ANIMATIONS_LIST_WIDTH, ANIMATIONS_LIST_HEIGHT, Color.white
|
def create_controls
|
||||||
)
|
@controls = {}
|
||||||
|
# TODO: Buttons to toggle between listing moves that have animations, and
|
||||||
|
# common animations (and overworld animations).
|
||||||
|
# Animations list
|
||||||
|
@list = UIControls::List.new(ANIMATIONS_LIST_WIDTH, ANIMATIONS_LIST_HEIGHT, @viewport, @animations)
|
||||||
|
@list.x = ANIMATIONS_LIST_X
|
||||||
|
@list.y = ANIMATIONS_LIST_Y
|
||||||
|
@controls[:list] = @list
|
||||||
|
# TODO: A secondary list for displaying all the animations related to the
|
||||||
|
# selected move. For common anims/overworld anims, this will only ever
|
||||||
|
# list one animation. The first animation listed in here will be
|
||||||
|
# selected by default.
|
||||||
|
# TODO: Filter text box for @list's contents. Applies the filter upon every
|
||||||
|
# change to the text box's value. Perhaps it should only do so after
|
||||||
|
# 0.5 seconds of non-typing. What exactly should the filter be applied
|
||||||
|
# to? Animation's name, move's name (if there is one), what else?
|
||||||
|
# TODO: Filter dropdown list to pick a type? Other filter options?
|
||||||
|
# "Load animation" button
|
||||||
|
@load_button = UIControls::Button.new(LOAD_BUTTON_WIDTH, LOAD_BUTTON_HEIGHT, @viewport, "Load animation")
|
||||||
|
@load_button.x = LOAD_BUTTON_X
|
||||||
|
@load_button.y = LOAD_BUTTON_Y
|
||||||
|
@load_button.set_fixed_size
|
||||||
|
@load_button.set_interactive_rects
|
||||||
|
@controls[:load] = @load_button
|
||||||
|
# TODO: "New animation" button, "Delete animation" button.
|
||||||
|
repaint
|
||||||
|
end
|
||||||
|
|
||||||
|
def repaint
|
||||||
|
@controls.each { |ctrl| ctrl[1].repaint }
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
# TODO: Update the controls (animations list, Load button, etc.).
|
# Update all controls
|
||||||
|
if @captured
|
||||||
|
@captured.update
|
||||||
|
@captured = nil if !@captured.busy?
|
||||||
|
else
|
||||||
|
@controls.each do |ctrl|
|
||||||
|
ctrl[1].update
|
||||||
|
@captured = ctrl[1] if ctrl[1].busy?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Check for changes in controls
|
||||||
|
@list.clear_changed if @list.changed? # We don't need @list's value now
|
||||||
|
if @load_button.changed?
|
||||||
|
# TODO: This will need to get the animation ID from the sublist instead.
|
||||||
|
@load_animation_id = @list.value
|
||||||
|
@load_button.clear_changed
|
||||||
|
end
|
||||||
|
repaint # Only repaints if needed
|
||||||
end
|
end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
@@ -56,15 +118,20 @@ class AnimationEditorLoadScreen
|
|||||||
Graphics.update
|
Graphics.update
|
||||||
Input.update
|
Input.update
|
||||||
update
|
update
|
||||||
if !inputting_text
|
if @load_animation_id
|
||||||
break if Input.trigger?(Input::BACK)
|
# Open editor with animation
|
||||||
end
|
# TODO: Add animation to be edited as an argument. This will be
|
||||||
# Open editor with animation
|
# GameData::Animation.get(@load_animation_id).to_hash.
|
||||||
# TODO: If the Load button is pressed while an animation is selected.
|
echoln "Anim number #{@load_animation_id}: #{@animations[@load_animation_id][1]}"
|
||||||
if Input.trigger?(Input::USE)
|
|
||||||
# TODO: Add animation to be edited as an argument.
|
|
||||||
screen = AnimationEditor.new
|
screen = AnimationEditor.new
|
||||||
screen.run
|
screen.run
|
||||||
|
@load_animation_id = nil
|
||||||
|
# TODO: Regenerate @animations in case the edited animation changed its
|
||||||
|
# name/move/version. Reapply @animations to @list and the sublist
|
||||||
|
# (this should invalidate them).
|
||||||
|
repaint
|
||||||
|
elsif !inputting_text
|
||||||
|
break if Input.trigger?(Input::BACK)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
dispose
|
dispose
|
||||||
|
|||||||
Reference in New Issue
Block a user