mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
Added header variant of Label control, makde DropdownList control
This commit is contained in:
@@ -77,6 +77,12 @@ class UIControls::ControlsContainer
|
||||
add_control(id, UIControls::Label.new(*control_size(has_label), @viewport, label), has_label)
|
||||
end
|
||||
|
||||
def add_header_label(id, label)
|
||||
ctrl = UIControls::Label.new(*control_size, @viewport, label)
|
||||
ctrl.header = true
|
||||
add_control(id, ctrl)
|
||||
end
|
||||
|
||||
def add_checkbox(id, value, has_label = false)
|
||||
add_control(id, UIControls::Checkbox.new(*control_size(has_label), @viewport, value), has_label)
|
||||
end
|
||||
|
||||
@@ -46,6 +46,16 @@ class UIControls::BaseControl < BitmapSprite
|
||||
@interactions = {}
|
||||
end
|
||||
|
||||
def mouse_in_control?
|
||||
return false if !@interactions || @interactions.empty?
|
||||
mouse_x, mouse_y = mouse_pos
|
||||
return false if !mouse_x || !mouse_y
|
||||
@interactions.each_pair do |area, rect|
|
||||
return true if rect.contains?(mouse_x, mouse_y)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def invalid?
|
||||
|
||||
@@ -10,6 +10,7 @@ class UIControls::Label < UIControls::BaseControl
|
||||
def initialize(width, height, viewport, label)
|
||||
super(width, height, viewport)
|
||||
@label = label
|
||||
@header = false
|
||||
end
|
||||
|
||||
def label=(value)
|
||||
@@ -17,8 +18,19 @@ class UIControls::Label < UIControls::BaseControl
|
||||
refresh
|
||||
end
|
||||
|
||||
def header=(val)
|
||||
@header = val
|
||||
refresh
|
||||
end
|
||||
|
||||
def refresh
|
||||
super
|
||||
draw_text(self.bitmap, 4, TEXT_OFFSET_Y, @label)
|
||||
if @header
|
||||
draw_text_centered(self.bitmap, 0, TEXT_OFFSET_Y, width, @label)
|
||||
text_size = self.bitmap.text_size(@label)
|
||||
self.bitmap.fill_rect((width - text_size.width) / 2, TEXT_OFFSET_Y + text_size.height, text_size.width, 1, TEXT_COLOR)
|
||||
else
|
||||
draw_text(self.bitmap, 4, TEXT_OFFSET_Y, @label)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
# decide which characters are selected. Maybe? Note that this method
|
||||
# is only triggered upon the initial mouse press, and isn't repeated
|
||||
# while it's still held down.
|
||||
# TODO: Add a blacklist array. Can't type in any values in this array. Disable
|
||||
# this control if @value is in this array.
|
||||
#===============================================================================
|
||||
class UIControls::TextBox < UIControls::BaseControl
|
||||
TEXT_BOX_X = 2
|
||||
|
||||
@@ -66,7 +66,7 @@ class UIControls::Button < UIControls::BaseControl
|
||||
# Change this control's value
|
||||
if @captured_area == :button
|
||||
mouse_x, mouse_y = mouse_pos
|
||||
if mouse_x && mouse_y && @interactions[@captured_area].contains?(mouse_x, mouse_y)
|
||||
if mouse_x && mouse_y && @interactions[@captured_area].contains?(mouse_x, mouse_y)
|
||||
set_changed
|
||||
end
|
||||
end
|
||||
|
||||
@@ -43,6 +43,11 @@ class UIControls::List < UIControls::BaseControl
|
||||
@scrollbar.y = new_val + LIST_Y
|
||||
end
|
||||
|
||||
def z=(new_val)
|
||||
super(new_val)
|
||||
@scrollbar.z = new_val + 1
|
||||
end
|
||||
|
||||
# Each value in @values is an array: [id, text].
|
||||
def values=(new_vals)
|
||||
@values = new_vals
|
||||
@@ -77,7 +82,18 @@ class UIControls::List < UIControls::BaseControl
|
||||
# Returns the ID of the selected row.
|
||||
def value
|
||||
return nil if @selected < 0
|
||||
return @values[@selected][0]
|
||||
if @values.is_a?(Array)
|
||||
return (@values[@selected].is_a?(Array)) ? @values[@selected][0] : @selected
|
||||
elsif @values.is_a?(Hash)
|
||||
return @values.keys[@selected]
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
def mouse_in_control?
|
||||
return true if super
|
||||
return true if @scrollbar.mouse_in_control?
|
||||
return false
|
||||
end
|
||||
|
||||
def set_interactive_rects
|
||||
@@ -202,6 +218,17 @@ class UIControls::List < UIControls::BaseControl
|
||||
# Set the selected row to the row the mouse is over, if clicked on
|
||||
if @captured_area
|
||||
@selected = @hover_area if @hover_area.is_a?(Integer)
|
||||
elsif @hover_area
|
||||
wheel_v = Input.scroll_v
|
||||
if wheel_v > 0 # Scroll up
|
||||
@scrollbar.slider_top -= UIControls::Scrollbar::SCROLL_DISTANCE
|
||||
elsif wheel_v < 0 # Scroll down
|
||||
@scrollbar.slider_top += UIControls::Scrollbar::SCROLL_DISTANCE
|
||||
end
|
||||
if wheel_v != 0
|
||||
self.top_row = (@scrollbar.position.to_f / ROW_HEIGHT).round
|
||||
update_hover_highlight
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,9 +1,147 @@
|
||||
#===============================================================================
|
||||
# TODO
|
||||
#
|
||||
#===============================================================================
|
||||
class UIControls::DropdownList < UIControls::BaseControl
|
||||
TEXT_BOX_X = 2
|
||||
TEXT_BOX_WIDTH = 172
|
||||
TEXT_BOX_HEIGHT = 24
|
||||
TEXT_BOX_PADDING = 4 # Gap between sides of text box and text
|
||||
TEXT_OFFSET_Y = 5
|
||||
MAX_LIST_ROWS = 8
|
||||
|
||||
def initialize(width, height, viewport, options, value)
|
||||
# NOTE: options is a hash: keys are symbols, values are display names.
|
||||
super(width, height, viewport)
|
||||
@options = options
|
||||
@value = value
|
||||
@toggling_dropdown_list = false
|
||||
end
|
||||
|
||||
def dispose
|
||||
remove_dropdown_menu
|
||||
super
|
||||
end
|
||||
|
||||
def value=(new_value)
|
||||
return if @value == new_value
|
||||
@value = new_value
|
||||
invalidate
|
||||
end
|
||||
|
||||
def set_interactive_rects
|
||||
@button_rect = Rect.new(TEXT_BOX_X, (height - TEXT_BOX_HEIGHT) / 2,
|
||||
[TEXT_BOX_WIDTH, width].min, TEXT_BOX_HEIGHT)
|
||||
@interactions = {
|
||||
:button => @button_rect
|
||||
}
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def busy?
|
||||
return true if @dropdown_menu || @toggling_dropdown_list
|
||||
return super
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def make_dropdown_menu
|
||||
menu_height = UIControls::List::ROW_HEIGHT * [@options.length, MAX_LIST_ROWS].min
|
||||
# Draw menu's background
|
||||
@dropdown_menu_bg = BitmapSprite.new(@button_rect.width, menu_height + 4, self.viewport)
|
||||
@dropdown_menu_bg.x = self.x + @button_rect.x
|
||||
@dropdown_menu_bg.y = self.y + @button_rect.y + @button_rect.height
|
||||
@dropdown_menu_bg.z = self.z + 1
|
||||
@dropdown_menu_bg.bitmap.outline_rect(0, 0, @dropdown_menu_bg.width, @dropdown_menu_bg.height, Color.black)
|
||||
@dropdown_menu_bg.bitmap.fill_rect(1, 1, @dropdown_menu_bg.width - 2, @dropdown_menu_bg.height - 2, Color.white)
|
||||
# Create menu
|
||||
@dropdown_menu = UIControls::List.new(@button_rect.width - 4, menu_height, self.viewport, @options)
|
||||
@dropdown_menu.x = @dropdown_menu_bg.x + 2
|
||||
@dropdown_menu.y = @dropdown_menu_bg.y + 2
|
||||
@dropdown_menu.z = self.z + 2
|
||||
@dropdown_menu.set_interactive_rects
|
||||
@dropdown_menu.repaint
|
||||
end
|
||||
|
||||
def remove_dropdown_menu
|
||||
@dropdown_menu_bg&.dispose
|
||||
@dropdown_menu_bg = nil
|
||||
@dropdown_menu&.dispose
|
||||
@dropdown_menu = nil
|
||||
@captured_area = nil
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def draw_area_highlight
|
||||
return if @captured_area == :button
|
||||
super
|
||||
end
|
||||
|
||||
def refresh
|
||||
@dropdown_menu&.refresh
|
||||
super
|
||||
# Draw button outline
|
||||
self.bitmap.outline_rect(@button_rect.x, @button_rect.y,
|
||||
@button_rect.width, @button_rect.height,
|
||||
Color.black)
|
||||
# Draw value
|
||||
draw_text(self.bitmap, @button_rect.x + TEXT_BOX_PADDING, TEXT_OFFSET_Y, @options[@value] || "???")
|
||||
# Draw down arrow
|
||||
arrow_area_x = @button_rect.x + @button_rect.width - @button_rect.height + 1
|
||||
arrow_area_width = @button_rect.height - 2
|
||||
self.bitmap.fill_rect(arrow_area_x, @button_rect.y + 1, arrow_area_width, arrow_area_width,
|
||||
(@hover_area && @captured_area != :button) ? HOVER_COLOR : Color.white)
|
||||
6.times do |i|
|
||||
self.bitmap.fill_rect(arrow_area_x + (arrow_area_width / 2) - 5 + i,
|
||||
@button_rect.y + (arrow_area_width / 2) - 1 + i,
|
||||
11 - (2 * i), 1, Color.black)
|
||||
end
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def on_mouse_press
|
||||
if @dropdown_menu
|
||||
if !@dropdown_menu.mouse_in_control?
|
||||
remove_dropdown_menu
|
||||
@toggling_dropdown_list = true
|
||||
end
|
||||
else
|
||||
@captured_area = nil
|
||||
super
|
||||
if @captured_area == :button
|
||||
make_dropdown_menu
|
||||
@toggling_dropdown_list = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def on_mouse_release
|
||||
return if !@captured_area && !@dropdown_menu && !@toggling_dropdown_list
|
||||
if @toggling_dropdown_list
|
||||
@toggling_dropdown_list = false
|
||||
return
|
||||
end
|
||||
if @dropdown_menu
|
||||
if @dropdown_menu.changed?
|
||||
new_val = @dropdown_menu.value
|
||||
if new_val && new_val != @value
|
||||
@value = new_val
|
||||
set_changed
|
||||
end
|
||||
remove_dropdown_menu
|
||||
super # Make this control not busy again
|
||||
elsif !@dropdown_menu.mouse_in_control?
|
||||
remove_dropdown_menu
|
||||
super # Make this control not busy again
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@dropdown_menu&.update
|
||||
@dropdown_menu&.repaint
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
@@ -34,6 +34,8 @@ module GameData
|
||||
# TODO: DamageFrame (keyframe at which the battle continues, i.e. damage
|
||||
# animations start playing).
|
||||
"Flags" => [:flags, "*s"],
|
||||
# TODO: If this is changed to be more than just a string, edit the
|
||||
# compiler's current_particle definition accordingly.
|
||||
"Particle" => [:particles, "s"] # Is a subheader line like <text>
|
||||
}
|
||||
# For individual particles. Any property whose schema begins with "^" can
|
||||
|
||||
@@ -41,8 +41,6 @@ module Compiler
|
||||
# New subsection [particle_name]
|
||||
value = get_csv_record($~[1], schema["Particle"])
|
||||
current_particle = {
|
||||
# TODO: If "Particle" is changed to be more than just a single
|
||||
# string, add more properties accordingly.
|
||||
:name => value
|
||||
}
|
||||
data_hash[schema["Particle"][0]].push(current_particle)
|
||||
|
||||
@@ -118,6 +118,7 @@ class AnimationEditor
|
||||
end
|
||||
|
||||
def set_commands_pane_contents
|
||||
@commands_pane.add_header_label(:header, _INTL("Edit particle at keyframe"))
|
||||
# :frame (related to graphic) - If the graphic is user's sprite/target's
|
||||
# sprite, make this instead a choice of front/back/same as the main sprite/
|
||||
# opposite of the main sprite. Probably need two controls in the same space
|
||||
@@ -149,6 +150,7 @@ class AnimationEditor
|
||||
end
|
||||
|
||||
def set_se_pane_contents
|
||||
@se_pane.add_header_label(:header, _INTL("Edit sound effects at keyframe"))
|
||||
# TODO: A list containing all SE files that play this keyframe. Lists SE,
|
||||
# user cry and target cry.
|
||||
@se_pane.add_button(:add, _INTL("Add"))
|
||||
@@ -157,6 +159,7 @@ class AnimationEditor
|
||||
end
|
||||
|
||||
def set_particle_pane_contents
|
||||
@particle_pane.add_header_label(:header, _INTL("Edit particle properties"))
|
||||
# TODO: Name should blacklist certain names ("User", "Target", "SE") and
|
||||
# should be disabled if the value is one of those.
|
||||
@particle_pane.add_labelled_text_box(:name, _INTL("Name"), _INTL("Untitled"))
|
||||
@@ -178,7 +181,7 @@ class AnimationEditor
|
||||
end
|
||||
|
||||
def set_keyframe_pane_contents
|
||||
@keyframe_pane.add_label(:temp, _INTL("Keyframe pane"))
|
||||
@keyframe_pane.add_header_label(:header, _INTL("Edit keyframe"))
|
||||
# TODO: Various command-shifting options.
|
||||
end
|
||||
|
||||
@@ -267,7 +270,7 @@ class AnimationEditor
|
||||
next if !new_vals.include?(ctrl[0])
|
||||
ctrl[1].value = new_vals[ctrl[0]] if ctrl[1].respond_to?("value=")
|
||||
end
|
||||
# TODO: Disable the name and graphic controls for "User"/"Target".
|
||||
# TODO: Disable the name, graphic and focus controls for "User"/"Target".
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -131,12 +131,12 @@ class AnimationEditor::AnimationSelector
|
||||
Input.update
|
||||
update
|
||||
# Open editor with animation
|
||||
@load_animation_id = 2 # TODO: For quickstart testing purposes.
|
||||
# @load_animation_id = 2 # TODO: For quickstart testing purposes.
|
||||
if @load_animation_id
|
||||
screen = AnimationEditor.new(@load_animation_id, GameData::Animation.get(@load_animation_id).clone_as_hash)
|
||||
screen.run
|
||||
@load_animation_id = nil
|
||||
break # TODO: For quickstart testing purposes.
|
||||
# break # TODO: For quickstart testing purposes.
|
||||
# Refresh list of animations, in case the edited one changed its type,
|
||||
# move, version or name
|
||||
generate_list
|
||||
|
||||
@@ -127,6 +127,7 @@ class AnimationEditor::ParticleList < UIControls::BaseControl
|
||||
end
|
||||
|
||||
def particle_index
|
||||
return -1 if @row_index < 0
|
||||
ret = @particle_list[@row_index]
|
||||
return (ret.is_a?(Array)) ? ret[0] : ret
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user