local TEXT_SCALE_NORMAL = 0.8 --Text size for mini hintbar
local TEXT_SCALE_MINI = 0.7 --Text size for mini hintbar
local BUTTON_SCALE_NORMAL = 1.0 --Button size for mini hintbar
local BUTTON_SCALE_MINI = 0.8 --Button size for mini hintbar
local HINT_PADDING_NORMAL = 5 --Spacing between button and text
local HINT_SPACING_NORMAL = 30 --Spacing between each button and text
local HINT_PADDING_MINI = 0 --Spacing between button and text
local HINT_SPACING_MINI = 25 --Spacing between each button and text
local COLOR_UNHIGHLIGHT_TEXT = {R=160/255,G=160/255,B=160/255}
Vdo_hint_bar_objects = { }
local Vdo_hint_bar_gamepad_listener = -1
function vdo_hint_bar_init()
local h = vint_object_find("button")
vint_set_property(h, "visible", false)
h = vint_object_find("hint_text")
vint_set_property(h, "visible", false)
Vdo_hint_bar_gamepad_listener = vint_scriptevent_listen( "gamepad_active", "vdo_hint_bar_update_gamepad_state" )
end
function vdo_hint_bar_cleanup()
vint_scriptevent_stop_listening( Vdo_hint_bar_gamepad_listener )
end
-- Inherited from Vdo_base_object
Vdo_hint_bar = Vdo_base_object:new_base()
function Vdo_hint_bar:init()
if self.is_initialized == nil then
self.hint_objects = {}
--Defaults for int spacing
self.hint_padding = HINT_PADDING_NORMAL --Spacing between button and text
self.hint_spacing = HINT_SPACING_NORMAL --Spacing between each button and text
self.hint_objects[1] = {
button = Vdo_hint_button:new("button", self.handle, self.doc_handle),
text = Vdo_base_object:new("hint_text", self.handle, self.doc_handle),
}
self.hint_objects.num = 1
self.hint_data = 0
self.height = 0
self.width = 0
--to store the buttons that we cloned and pulsed
self.pulse_buttons = {}
end
self.hint_data = 0
--Make sure we clear our old hints out
self:set_hints()
self.is_initialized = true
self.input_tracker = nil
-- We only need to store off the hint bar if we are running pc so we can change icons when gamepad updates
if game_get_platform() == "PC" then
for k,v in pairs( Vdo_hint_bar_objects ) do
-- Check if there are any unloaded docs that were using hint_bars and clear them
if vint_object_exists( v.hint_objects[1].text.handle ) == false then
Vdo_hint_bar_objects[k] = nil
end
end
Vdo_hint_bar_objects[ #Vdo_hint_bar_objects + 1 ] = self
end
end
function Vdo_hint_bar:cleanup()
for k,v in pairs( Vdo_hint_bar_objects ) do
if v == self or vint_object_exists( v.hint_objects[1].text.handle ) == false then
Vdo_hint_bar_objects[ k ] = nil
end
end
if( self.hint_objects ~= nil ) then
--Remove old buttons and clear out stored objects
for i = 2, self.hint_objects.num do
self.hint_objects[i].button:object_destroy()
self.hint_objects[i].text:object_destroy()
self.hint_objects[i] = nil
end
end
self.hint_data = nil
end
--Sets hints of hint object
-- Example of hint_data object param
--[[
hint_data = {
{CTRL_MENU_BUTTON_B, "BACK"},
{CTRL_BUTTON_X, "SAVE GAME"},
{CTRL_BUTTON_Y, "EAT DONG"},
}
]]
function Vdo_hint_bar:set_hints(hint_data, force_gamepad_icons, force_kbd_icons, force_scale)
self.hint_data = hint_data
self.hint_objects[1].button:set_visible(true)
self.hint_objects[1].text:set_visible(true)
--Only reset the scale if we are not doing a rebuild...
local do_force_scale = false
if force_scale == nil then
do_force_scale = true
force_scale = 1.0
end
--reset force_scale...
self.hint_objects[1].text:set_property("scale", force_scale, 1.0)
self:clear_mouse_input_subs()
--Remove old buttons and clear out stored objects
for i = 2, self.hint_objects.num do
self.hint_objects[i].button:object_destroy()
self.hint_objects[i].text:object_destroy()
self.hint_objects[i] = nil
end
self.hint_objects.num = 0
local button_width_total = 0
if hint_data == nil or hint_data == false then
self.hint_objects[1].button:set_visible(false)
self.hint_objects[1].text:set_visible(false)
else
local hint_data_count = #hint_data
local button, text, text_old
local text_width, text_height, text_x, text_y
local button_width, button_height, button_x, button_y
local button_x_new, text_x_new
local def_button_width
local x_start = 0
--Create new buttons and set
for i = 1, hint_data_count do
if i == 1 then
--First button in menu... (no clones)
button = self.hint_objects[1].button
text = self.hint_objects[1].text
else
--Clone Objects from original
button = Vdo_hint_button:clone(self.hint_objects[1].button.handle, self.handle)
text = Vdo_base_object:clone(self.hint_objects[1].text.handle, self.handle)
end
--Set Text and Button Image
local btn_img_string = hint_data[i][1]
local btn_pc_key_text = hint_data[i][3]
local btn_text_string = hint_data[i][2]
button:set_button(btn_img_string, btn_pc_key_text, force_gamepad_icons, force_kbd_icons)
text:set_text(btn_text_string)
-- Save the button width to make it easier to offset the buttons based on their size
local button_offset
if i == 1 then
--First button... we process differently.
text_x, text_y = text:get_anchor()
-- Only get the default width from the first button, though this might change later to be hardcoded (30 is the current width of a button image)
def_button_width = button:get_default_width()
button_x, button_y = button:get_anchor()
button_width, button_height = button:get_size()
button_offset = (button_width - def_button_width) / 2
button_x_new = button_offset
x_start = button_width * 0.5
--text position is the sum of button position, half the width fo the button and a hint padding value.
text_x_new = button_x_new + (button_width / 2 ) + self.hint_padding
button_width_total = button_width_total + (button_width) + self.hint_padding
else
--Reposition and align based on previous button
text_old = self.hint_objects[i - 1].text
text_width, text_height = text_old:get_actual_size()
text_x, text_y = text_old:get_anchor()
button_x, button_y = button:get_anchor()
button_width, button_height = button:get_size()
button_offset = (button_width - def_button_width) / 2
button_x_new = button_offset + text_x + text_width + self.hint_spacing
--text position is the sum of button position, half the width fo the button and a hint padding value.
text_x_new = button_x_new + (button_width / 2 ) + self.hint_padding
button_width_total = button_width_total + (button_width * .5) + self.hint_spacing
end
button:set_anchor(button_x_new, button_y)
text:set_anchor(text_x_new, text_y)
--Store into global for processing / cleanup
self.hint_objects[i] = {}
self.hint_objects[i].button = button
self.hint_objects[i].text = text
self.hint_objects.num = self.hint_objects.num + 1
end
--Calculate width and height of hint bar by checking the position and width of the last text field...
local text_h = self.hint_objects[self.hint_objects.num].text.handle
local width, height = element_get_actual_size(text_h)
local x, y = vint_get_property(text_h, "anchor")
width = width + x
self.height = button_height
self.width = width
self.hint_data = hint_data
--Re-enable text shadow...
if self.shadow_enabled then
self:enable_text_shadow(self.shadow_enabled)
end
if self.width_max ~= nil and do_force_scale == true then
local test_width = self.width
--button_width =
if test_width > self.width_max then
-- Add extra padding to our button widths...
button_width_total = button_width_total + 20
--scale text
local new_scale = (self.width_max - button_width_total )/(test_width - button_width_total)
--Reset our hints with the new scale.
self:set_hints(hint_data, force_gamepad_icons, force_kbd_icons, new_scale)
end
end
end
self:add_mouse_input_subs()
if game_machinima_hide_hints() then
local hint_data_count = #self.hint_objects
for i = 1, hint_data_count do
self.hint_objects[i].button:set_visible(false)
self.hint_objects[i].text:set_visible(false)
end
end
end
-- Pulses one of the buttons in the hint bar...
--
-- @param button_id id of button position that we want to pulse...
function Vdo_hint_bar:pulse(button_id)
--Wipe out any previously pulsing buttons...
for idx, val in pairs(self.pulse_buttons) do
val:object_destroy()
end
self.pulse_buttons = {}
local button = Vdo_base_object:clone(self.hint_objects[button_id].button.handle, self.handle)
local text = Vdo_base_object:clone(self.hint_objects[button_id].text.handle, self.handle)
button:set_depth(-100)
text:set_depth(-100)
button:set_property("render_mode", "additive_alpha")
text:set_property("render_mode", "additive_alpha")
self.pulse_buttons.button = button
self.pulse_buttons.text = text
local text_twn = Vdo_tween_object:new("pulse_text_twn", self.handle, self.doc_handle)
local btn_twn = Vdo_tween_object:new("pulse_btn_twn", self.handle, self.doc_handle)
local btn2_twn = Vdo_tween_object:new("pulse_btn2_twn", self.handle, self.doc_handle)
text_twn:set_target_handle(text.handle)
btn_twn:set_target_handle(button.handle)
btn2_twn:set_target_handle(button.handle)
local anim = Vdo_anim_object:new("button_pulse", self.handle, self.doc_handle)
anim:play()
end
function Vdo_hint_bar:enable_text_shadow(enable)
if enable then
for i = 1, self.hint_objects.num do
self.hint_objects[i].text:set_property("shadow_enabled", true)
self.hint_objects[i].text:set_property("shadow_offset", 2, 2)
self.hint_objects[i].text:set_property("shadow_alpha", .75)
self.hint_objects[i].text:set_property("shadow_tint", 0,0,0)
end
else
for i = 1, self.hint_objects.num do
self.hint_objects[i].text:set_property("shadow_enabled", false)
end
end
self.shadow_enabled = enable
end
-------------------------------------------------------------------------------
-- All objects get centered....
-------------------------------------------------------------------------------
function Vdo_hint_bar:enable_centered(enable)
self.centered = enable
end
function Vdo_hint_bar:set_color(color)
for i = 1, self.hint_objects.num do
self.hint_objects[i].text:set_color(color.R, color.G, color.B)
end
end
-------------------------------------------------------------------------------
-- Makes button hints 18 point and rebuilds the button list...
--
-- @param enable (bool) determines whether or the buttons should be 18pt.
-------------------------------------------------------------------------------
function Vdo_hint_bar:enable_mini_mode(enable)
if enable == true then
--If enabled resize button list...
self.hint_objects[1].button:set_scale(BUTTON_SCALE_MINI, BUTTON_SCALE_MINI)
self.hint_objects[1].text:set_property("text_scale", TEXT_SCALE_MINI, TEXT_SCALE_MINI)
self.hint_padding = HINT_PADDING_MINI
self.hint_spacing = HINT_SPACING_MINI
else
self.hint_objects[1].button:set_scale(BUTTON_SCALE_NORMAL, BUTTON_SCALE_NORMAL)
self.hint_objects[1].text:set_property("text_scale", TEXT_SCALE_NORMAL, TEXT_SCALE_NORMAL)
self.hint_padding = HINT_PADDING_NORMAL
self.hint_spacing = HINT_SPACING_NORMAL
end
--reset and rebuild hints...
if self.hint_data ~= 0 then
self:set_hints(self.hint_data)
end
end
-------------------------------------------------------------------------------
-- Returns the size of the hints in pixels.
--
-- @return width Width of the button hints in pixels
-- @return height Height of the button hints in pixels
-------------------------------------------------------------------------------
function Vdo_hint_bar:get_size()
return self.width, self.height
end
function Vdo_hint_bar:set_width_max(width_max)
self.width_max = width_max
end
function Vdo_hint_bar:get_hint_index(target_handle)
for i = 1, self.hint_objects.num do
if self.hint_objects[i].text.handle == target_handle or self.hint_objects[i].button.handle == target_handle then
return i
end
end
-- Return 0 as an invalid index
return 0
end
function Vdo_hint_bar:set_highlight(index, color)
for i = 1, self.hint_objects.num do
self.hint_objects[i].text:set_color(COLOR_UNHIGHLIGHT_TEXT.R, COLOR_UNHIGHLIGHT_TEXT. G, COLOR_UNHIGHLIGHT_TEXT.B)
end
if index ~= 0 then
if self.hint_objects[index] ~= nil then
if color == nil then
color = COLOR_SAINTS_PURPLE
end
game_UI_audio_play("Ui_main_menu_nav_up")
self.hint_objects[index].text:set_color(color.R, color.G, color.B)
else
debug_print("vint", "hint_bar:set_highlight - invalid index")
end
end
end
--[[ ---------------------------------------------------------------------
-- Function - vdo_hint_bar_update_gamepad_state
-- Description - Called by code anytime gamepad is plugged or unplugged.
-- Parameters - none
-- Returns - nil
]]-- ---------------------------------------------------------------------
function vdo_hint_bar_update_gamepad_state()
local v = Vdo_hint_bar_objects
for k, obj in pairs( Vdo_hint_bar_objects ) do
if( vint_document_find(obj.func_prefix) == 0 ) then
-- Should have been cleaned up in screen scripts, so lets do it here
Vdo_hint_bar_objects[k] = nil
elseif( obj.hint_data ~= nil and obj.hint_objects[1].text:get_visible() ~= nil )then
local is_input_tracker_subscribed = false
if( obj.input_tracker ~= nil )then
is_input_tracker_subscribed = obj.input_tracker.is_subscribed
end
obj:set_hints(obj.hint_data)
if( obj.input_tracker ~= nil and is_input_tracker_subscribed == true )then
obj.input_tracker:subscribe(true)
end
end
end
end
-------------------------------------------------------------------------------
-- Mouse/PC Functions
-------------------------------------------------------------------------------
-- Adds mouse input subscriptions to the input tracker
--
-- @param func_prefix Name of the screen that is currently using the hint bar
-- @param input_tracker The input tracker to hold the mouse inputs events
-- @param priority THe priority of the input event
function Vdo_hint_bar:add_mouse_inputs(func_prefix, input_tracker, priority)
if func_prefix == nil or input_tracker == nil then
return
end
self.priority = priority or 50
self.func_prefix = func_prefix
if( self.input_tracker == nil ) then
self:clear_mouse_input_subs()
end
if( self.input_tracker ~= input_tracker ) then
self.input_tracker = input_tracker
end
self:add_mouse_input_subs()
end
--[[ ---------------------------------------------------------------------
-- Function - clear_mouse_input_subs
-- Description - Clears out all the current mouse input subscriptions
-- Parameters - none
-- Returns - nil
]]-- ---------------------------------------------------------------------
function Vdo_hint_bar:clear_mouse_input_subs()
if( self.input_tracker == nil ) then
return
end
for i = 1, self.hint_objects.num do
if self.hint_objects[i].text:get_visible() then
self.input_tracker:remove_input_by_object_handle("mouse_click", self.hint_objects[i].text.handle)
self.input_tracker:remove_input_by_object_handle("mouse_move", self.hint_objects[i].text.handle)
self.input_tracker:remove_input_by_object_handle("mouse_click", self.hint_objects[i].button.handle)
self.input_tracker:remove_input_by_object_handle("mouse_move", self.hint_objects[i].button.handle)
end
end
end
--[[ ---------------------------------------------------------------------
-- Function - clear_mouse_input_subs
-- Description - Add all the current mouse input subscriptions
-- Parameters - none
-- Returns - nil
]]-- ---------------------------------------------------------------------
function Vdo_hint_bar:add_mouse_input_subs()
if( self.input_tracker == nil ) then
return
end
local mouse_click_function = self.func_prefix.."_mouse_click"
local mouse_move_function = self.func_prefix.."_mouse_move"
for i = 1, self.hint_objects.num do
if self.hint_objects[i].text:get_visible() then
self.input_tracker:add_mouse_input("mouse_click", mouse_click_function, self.priority, self.hint_objects[i].text.handle)
self.input_tracker:add_mouse_input("mouse_move", mouse_move_function, self.priority, self.hint_objects[i].text.handle)
self.input_tracker:add_mouse_input("mouse_click", mouse_click_function, self.priority, self.hint_objects[i].button.handle)
self.input_tracker:add_mouse_input("mouse_move", mouse_move_function, self.priority, self.hint_objects[i].button.handle)
end
end
end
function Vdo_hint_bar:override_mouse_depths(depth)
for i = 1, self.hint_objects.num do
if self.hint_objects[i].text:get_visible() then
vint_set_property(self.hint_objects[i].text.handle, "mouse_depth", depth)
vint_set_property(self.hint_objects[i].button.handle, "mouse_depth", depth)
end
end
end