./vdo_mega_list.lua

  1. Vdo_mega_list_tween_done = true 
  2.  
  3. local Vdo_mega_list_gamepad_listener = -1 
  4. local Vdo_mega_list_gamepad_listener_enabled = true 
  5.  
  6. -- Hold reference to all the buttons for when gamepad state is changed 
  7. local Buttons 
  8.  
  9. local Game_platform 
  10. local Toggle_mouse_input_tracker 
  11.  
  12. function vdo_mega_list_init() 
  13. 	Vdo_mega_list_gamepad_listener = vint_scriptevent_listen( "gamepad_active", "vdo_mega_list_update_gamepad_state" ) 
  14. end 
  15.  
  16. function vdo_mega_list_cleanup() 
  17. 	vint_scriptevent_stop_listening(  Vdo_mega_list_gamepad_listener ) 
  18. end 
  19.  
  20. function vdo_mega_list_scroll_done(tween_h, event_name) 
  21. 	-- remove this callback 
  22. 	--remove_tween_end_callback( vint_object_find("toggle_group_anchor_tween") ) 
  23. 	Vdo_mega_list_tween_done = true 
  24. end 
  25.  
  26. -- Inherited from Vdo_base_object 
  27. Vdo_mega_list = Vdo_base_object:new_base() 
  28.  
  29. local MEGA_LIST_DEFAULT_WIDTH = 465						--Default width of megalist... 
  30. local BUTTON_ANCHOR_OFFSET = 0.5 
  31. local ANCHOR_SLIDER_LABEL = 20 
  32. local SLIDER_PADDING_RIGHT =  5							--padding from right side for toggles and sliders... 
  33. local MEGA_LIST_BUTTON_SPACING = -3						--vertical button spacing between options, this is -3 because the highlight actually overlaps between the options. 
  34. local MEGA_LIST_BUTTON_PADDING = 15						--Padding for the right side of button 
  35. local MEGALIST_HIGHLIGHT_WIDTH_OFFSET = -7			-- offset width for the highlight bar... 
  36. local MEGALIST_SCROLLBAR_PADDING = 5					-- offset width for the highlight bar... 
  37. local WIDE_HITBOX_OFFSET = -36 
  38.  
  39. --HVS_JPM[KING] 12/11/2014: Flag values from invite friends screen 
  40. local MULTI_FRIEND_FLAG_ONLINE = 1 
  41. local MULTI_FRIEND_FLAG_IN_GAME = 2 
  42. local MULTI_FRIEND_FLAG_ONLINE_AND_IN_GAME = 3 
  43. local MULTI_FRIEND_FLAG_ONLINE_JOINABLE = 7 
  44.  
  45. function Vdo_mega_list:init() 
  46. 	-- Store of a reference to self for accessing when gamepad state changes 
  47. 	Buttons = self 
  48. 	-- Store common objects to self... 
  49. 	self.group_h = vint_object_find("toggle_group", self.handle, self.doc_handle)	 
  50. 	self.button_highlight =	Vdo_button_highlight:new("toggle_highlight", self.handle, self.doc_handle) 
  51. 	self.toggle_base = Vdo_button_toggle:new("toggle_base", self.handle, self.doc_handle) 
  52. 	self.toggle = Vdo_toggle:new("toggle_toggle", self.handle, self.doc_handle) 
  53. 	self.slider = Vdo_slider:new("toggle_slider", self.handle, self.doc_handle) 
  54. 	self.row = Vdo_row:new("toggle_row", self.handle, self.doc_handle) 
  55. 	self.toggle_color = Vdo_toggle_color:new("toggle_color", self.handle, self.doc_handle) 
  56. 	self.remap = Vdo_button_remap:new("toggle_remap", self.handle, self.doc_handle) 
  57. 	self.header = Vdo_button_header:new("toggle_header", self.handle, self.doc_handle) 
  58. 	self.pip = Vdo_button_pip:new("toggle_pip", self.handle, self.doc_handle) 
  59. 	self.scrollbar = Vdo_scrollbar:new("mega_list_scrollbar", self.handle, self.doc_handle) 
  60. 	 
  61. 	self.clip_h = vint_object_find("list_clip", self.handle) 
  62. 	 
  63. 	-- Hide our base objects... 
  64. 	vint_set_property(self.toggle_base.handle, "visible", false) 
  65. 	 
  66. 	vint_set_property(self.toggle.handle, "visible", false) 
  67. 	vint_set_property(self.toggle.handle, "alpha", 1) 
  68. 	 
  69. 	vint_set_property(self.slider.handle, "visible", false) 
  70. 	vint_set_property(self.slider.handle, "alpha", 1) 
  71.  
  72. 	vint_set_property(self.row.handle, "visible", false) 
  73. 	vint_set_property(self.row.handle, "alpha", 1) 
  74. 	 
  75. 	vint_set_property(self.toggle_color.handle, "visible", false) 
  76. 	vint_set_property(self.toggle_color.handle, "alpha", 1) 
  77. 	 
  78. 	vint_set_property(self.remap.handle, "visible", false) 
  79. 	vint_set_property(self.remap.handle, "alpha", 1) 
  80. 	 
  81. 	vint_set_property(self.header.handle, "visible", false) 
  82. 	vint_set_property(self.header.handle, "alpha", 1) 
  83. 	 
  84. 	vint_set_property(self.pip.handle, "visible", false) 
  85. 	vint_set_property(self.pip.handle, "alpha", 1) 
  86. 		 
  87. 	vint_set_property(self.scrollbar.handle, "visible", false) 
  88. 	vint_set_property(self.scrollbar.handle, "alpha", 1) 
  89.  
  90. 	self.pulse_anim = Vdo_anim_object:new("toggle_pulse_anim", self.handle) 
  91. 	self.pulse_twn = Vdo_tween_object:new("pulse_twn", self.pulse_anim.handle)		 
  92. 	 
  93. 	self.intro_anim_h = vint_object_find("toggle_intro_anim", self.handle) 
  94. 	self.intro_anchor_twn_h = vint_object_find("intro_anchor_twn", self.intro_anim_h) 
  95. 	self.option_twn_h = vint_object_find("intro_option_twn", self.intro_anim_h) 
  96. 	 
  97. 	self.highlight_anim_h = vint_object_find("toggle_highlight_anim", self.handle) 
  98. 	self.highlight_anchor_twn_h = vint_object_find("highlight_anchor_twn", self.highlight_anim_h) 
  99. 	 
  100. 	self.intro_twn_counter = 0 
  101. 	self.intro_twns = {}	 
  102. 	self.intro_anim_is_playing = false	 
  103. 	self.wrapped = false 
  104. 	self.animate_list = true 
  105. 	 
  106. 	 
  107. 	--This is to allow scaling of lists to not marquee but to scale the text in the list.  
  108. 	self.scale_text_if_too_big = false 
  109. 	self.text_is_too_big_font_scale = 1 
  110. 	self.text_is_to_big = false 
  111. 	 
  112. 	--default megalist tween to true...  
  113. 	Vdo_mega_list_tween_done = true 
  114. 	 
  115. 	-- Hide Marquee Mask TODO: MAKE THIS GLOBAL... 
  116. 	local marq_mask_h = vint_object_find("mega_marquee_mask", self.handle) 
  117. 	vint_set_property(marq_mask_h, "visible", false) 
  118. 	vint_set_property(marq_mask_h, "mask", false) 
  119.  
  120. 	--Enable clip for megalist... 
  121. 	vint_set_property(self.clip_h, "clip_enabled", true) 
  122. 	 
  123. 	Game_platform = game_get_platform() 
  124. 	self.visible_start_idx = 1 
  125. 	self.highlight_on = true		-- highlight is on by default... 
  126. 	if Game_platform == "PC" then 
  127. 		Toggle_mouse_input_tracker = Vdo_input_tracker:new() 
  128. 	end 
  129. end 
  130.  
  131. -- Deletes the internal data and destroys the button clones 
  132. function Vdo_mega_list:cleanup() 
  133. 	if self.draw_called then 
  134. 		for i, button in pairs(self.buttons) do 
  135. 			self:cleanup_single_item(button) 
  136. 			self.buttons[i] = nil 
  137. 		end 
  138. 		 
  139. 		for i, twn_pairs in pairs(self.intro_twns) do 
  140. 			for k, twn in pairs(twn_pairs) do 
  141. 				if twn ~= 0 then 
  142. 					vint_object_destroy(twn) 
  143. 				end 
  144. 			end 
  145. 		end 
  146. 		--debug_print("vint", "megalist cleanup \n") 
  147. 		self.intro_twn_counter = 0 
  148. 		table_clear(self.intro_twns, true) 
  149. 		self.intro_twns = {} 
  150. 		 
  151. 		if Toggle_mouse_input_tracker ~= nil then 
  152. 			Toggle_mouse_input_tracker:remove_all() 
  153. 		end 
  154. 		 
  155. 		self.draw_called = false 
  156. 		vint_force_lua_gc() 
  157. 	end	 
  158. end 
  159.  
  160. ------------------------------------------------------------------------------- 
  161. -- If the text is too big for the width of the list, set this to true. 
  162. -- (This only works for lists that do not have any controls) 
  163. -- was setup for the upgrade list in SR4. I love you. 
  164. -- 
  165. function Vdo_mega_list:set_scale_text_if_too_big(scale_text_if_too_big) 
  166. 	self.scale_text_if_too_big = scale_text_if_too_big 
  167. end 
  168.  
  169. function Vdo_mega_list:cleanup_single_item(button) 
  170. 	button:object_destroy() 
  171. 	if button.slider ~= nil then 
  172. 		button.slider:object_destroy() 
  173. 	elseif button.toggle ~= nil then 
  174. 		button.toggle:object_destroy() 
  175. 	elseif button.row ~= nil then 
  176. 		button.row:object_destroy() 
  177. 	elseif button.toggle_color ~= nil then 
  178. 		button.toggle_color:object_destroy() 
  179. 	elseif button.remap ~= nil then 
  180. 		button.remap:object_destroy() 
  181. 	elseif button.header ~= nil then 
  182. 		button.header:object_destroy() 
  183. 	elseif button.pip ~= nil then 
  184. 		button.pip:object_destroy() 
  185. 	end 
  186. 	 
  187. 	--Cleanup new tween if exists. 
  188. 	if button.new_tween ~= nil then 
  189. 		button.new_tween:object_destroy() 
  190. 	end 
  191. 	button = nil 
  192. end 
  193.  
  194. --This should only be called internally by Vdo_mega_list:draw_items() 
  195. function Vdo_mega_list:set_size(width) 
  196. 	 
  197. 	-- Handle clip size 
  198. 	 
  199. 	--TODO: FIX THIS FAKE PADDING... +2??? 
  200. 	--First Button height + max buttons in list + spacing between buttons) 
  201. 	local clip_height = LIST_BUTTON_HEIGHT + ((self.max_buttons - 1) * (LIST_BUTTON_HEIGHT + MEGA_LIST_BUTTON_SPACING ))  
  202. 	 
  203. 	local clip_height = clip_height 
  204. 	vint_set_property(self.clip_h, "clip_size", width, clip_height) 
  205. 	 
  206. 	--set width of highlight 
  207. 	self.button_highlight:set_width(width) 
  208. 	 
  209. 	-- Handle scrolling 
  210. 	if(#self.data > self.max_buttons) then 
  211. 		--show the scroll bar 
  212. 		self.scrollbar:set_property("visible", true) 
  213. 		 
  214. 		local scrollbar_height = clip_height 
  215. 		if Game_platform == "PC" then 
  216. 			local move_height = LIST_BUTTON_HEIGHT + MEGA_LIST_BUTTON_SPACING 
  217. 			local total_height = self.num_buttons * move_height 
  218. 			self.scrollbar:set_size(SCROLLBAR_WIDTH, scrollbar_height, total_height) 
  219. 		else 
  220. 			--set the size of the scrollbar 
  221. 			self.scrollbar:set_size(SCROLLBAR_WIDTH, scrollbar_height) 
  222. 		end 
  223. 		 
  224. 		--set position of scrollbar 
  225. 		local scrollbar_x = width + MEGALIST_SCROLLBAR_PADDING 
  226. 		self.scrollbar:set_property("anchor", scrollbar_x, 0)  
  227. 		 
  228. 	else 
  229. 		--show the scroll bar 
  230. 		self.scrollbar:set_property("visible", false) 
  231. 	end	 
  232.  
  233. 	self.width = width 
  234. end 
  235.  
  236.  
  237. ------------------------------------------------------------------------------- 
  238. -- Refreshes and Draws the mega list with new data 
  239. --	@param	data					table representing the list to display 
  240. -- @param	current_option		option you want highlighted 
  241. -- @param	width					min width for the menu(the selector will draw up to here) 
  242. -- @param	max_buttons			how many buttons in the list 
  243. -- @param	font_scale			scale of fonts in the list 
  244. -- @param	force_width			force the width of list. Buttons will marquee in this mode. 
  245. --										(Be sure to setup the lua_document, and Object reference, when	 
  246. --										setting this to true or it will explode.) 
  247. -- @param   animate_list		animate the list or not 
  248. ------------------------------------------------------------------------------- 
  249. function Vdo_mega_list:draw_items(data, current_option, width, max_buttons, font_scale, force_width, animate_list, was_new) 
  250. 	-- Error Check - use 1 to #, since we can have callbacks that aren't tables 
  251. 	for i = 1, #data do 
  252. 		if type(data[i]) ~= "table" then 
  253. 			debug_print("vint", "Vdo_mega_list:draw_items was called with impropperly formatted parameters!\n") 
  254. 			return 
  255. 		end 
  256. 	end 
  257. 	 
  258. 	-- Nuke the shit out of whatever was previously here 
  259. 	self:cleanup() 
  260.  
  261. 	-- Set up handle for base button 
  262. 	local button_copy = self.toggle_base 
  263. 	if button_copy.handle == 0 then 
  264. 		debug_print("vint", "Unable to find object \"toggle_base\"") 
  265. 		return 
  266. 	end 
  267.  
  268. 	--get the x and y of the button 
  269. 	button_copy.x, button_copy.y = button_copy:get_property("anchor") 
  270.  
  271. 	--check to make sure we haven't initialized these values if we are passing in nil... 
  272. 	if max_buttons == nil and self.max_buttons ~= nil then 
  273. 		max_buttons = self.max_buttons 
  274. 	else  
  275. 		self.max_buttons = max_buttons 
  276. 	end 
  277. 	 
  278. 	--Most lists should use LIST_FONT_SCALE, but cell_missions.lua needs a smaller font 
  279. 	font_scale = font_scale or LIST_FONT_SCALE 
  280. 	 
  281. 	if font_scale == nil and self.font_scale ~= nil then 
  282. 		font_scale = self.font_scale 
  283. 	else	 
  284. 		self.font_scale = font_scale 
  285. 	end 
  286. 	 
  287. 	if width == nil then 
  288. 		if self.width ~= nil then 
  289. 			width = self.width 
  290. 		else 
  291. 			width = MEGA_LIST_DEFAULT_WIDTH 
  292. 		end 
  293. 	end 
  294. 	 
  295. 	if force_width == nil and self.force_width ~= nil then 
  296. 		force_width = self.force_width 
  297. 	end 
  298. 	 
  299. 	if animate_list ~= nil then 
  300. 		self.animate_list = animate_list		 
  301. 	else 
  302. 		self.animate_list = true 
  303. 	end 
  304. 	 
  305. 	local include_scrollbar_in_width = nil 
  306. 	if self.include_scrollbar_in_width ~= nil then 
  307. 		include_scrollbar_in_width = self.include_scrollbar_in_width 
  308. 	end 
  309. 	 
  310. 	--Set the properties... 
  311. 	self:set_properties(nil, nil, max_buttons, font_scale, width, force_width, animate_list) 
  312. 	 
  313. 	-- Set up tables to manage handles and data for this object 
  314. 	self.draw_called = true 
  315. 	self.buttons = {} 
  316.  
  317. 	-- Try to only copy the data we need, instead of all of it 
  318. 	self.data = data 
  319.  
  320. 	self.old_slider_value = nil 
  321. 	self.old_toggle_value = nil 
  322. 	self.slider_anchor_y = 0 
  323. 	self.toggle_anchor_y = 0 
  324. 	self.button_x = button_copy.x			--Store x position of button... 
  325. 	self.label_x = 0 
  326. 	 
  327. 	self.list_y = 0 
  328. 	 
  329. 	self.item_range_min = 0 
  330. 	self.item_range_max = 0 
  331. 	 
  332. 	self.text_is_to_big = false --Reset tthe fact that text is too big 
  333. 	 
  334. 	--calculate new width based on scrollbar data... 
  335. 	if self.include_scrollbar_in_width == true and #self.data > self.max_buttons then 
  336. 		width = width - SCROLLBAR_WIDTH - (MEGALIST_SCROLLBAR_PADDING * 2) 
  337. 	end 
  338.  
  339. 	self.anims = {} 
  340. 	 
  341. 	--Stop the animation that handles scrolling... 
  342. 	local toggle_group_anim = Vdo_anim_object:new("toggle_group_anim", self.handle, self.doc_handle) 
  343. 	toggle_group_anim:stop() 
  344. 	Vdo_mega_list_tween_done = true 
  345. 	 
  346. 	-- Save the number of buttons 
  347. 	self.num_buttons = #data 
  348.  
  349. 	-- Find and store size of sliders 
  350. 	self.slider_width, self.toggle_slider_height = self.slider:get_size() 
  351. 	 
  352. 	self.toggle_width = 0 
  353. 	 
  354. 	-- Find and store size of toggle colors 
  355. 	self.toggle_color_width = self.toggle_color:get_width() 
  356. 	 
  357. 	-- Count how many sliders and toggles are in list 
  358. 	local num_toggles = 0 
  359. 	local num_sliders = 0 
  360. 	local num_rows = 0 
  361. 	local num_toggle_colors = 0 
  362. 	local num_remaps = 0 
  363. 	 
  364. 	--widths of the components to calculate layout. 
  365. 	self.max_label_width 			= 0 
  366. 	self.toggle_max_value_width 	= 0 
  367. 	self.row_largest_col_1 			= 10 
  368. 	self.row_largest_col_2 			= 10 
  369. 	self.row_largest_col_3 			= 10 
  370. 	self.row_largest_col_4 			= 0 
  371.  
  372. 	if font_scale ~= nil then 
  373. 		self.font_scale = font_scale 
  374. 	else 
  375. 		self.font_scale = 1 
  376. 	end 
  377.  
  378. 	--Loop through the items, draw them, but delete them afterwards. We will draw the right items we need afterwards. 
  379. 	--Count how many objects we have of each type. 
  380. 	for i = 1, self.num_buttons do 
  381. 		--Draw all the items and delete them when finished. 
  382. 		--This will run through all the calculations we need to calculate the positions and widths for items when we are completed. 
  383. 		self:draw_single_item(i, true) 
  384. 		 
  385. 		local item = data[i] 
  386. 		if item.type == TYPE_TOGGLE then 
  387. 			num_toggles = num_toggles + 1 
  388. 		elseif item.type == TYPE_SLIDER then 
  389. 			num_sliders = num_sliders + 1 
  390. 		elseif item.type == TYPE_ROW then 
  391. 			num_rows = num_rows + 1 
  392. 		elseif item.type == TYPE_TOGGLE_COLOR then 
  393. 			num_toggle_colors = num_toggle_colors + 1 
  394. 		elseif item.type == TYPE_REMAP then 
  395. 			num_remaps = num_remaps + 1 
  396. 		end			 
  397. 	end 
  398. 	 
  399. 	--If we have no sliders then we do not use slider width in calculating the width... 
  400. 	if num_sliders == 0 then 
  401. 		self.slider_width = 0 
  402. 	end 
  403. 	 
  404. 	if num_toggle_colors == 0 then 
  405. 		self.toggle_color_width = 0 
  406. 	end 
  407. 	 
  408. 	self.row_width = 0 
  409. 	if num_rows == 0 then 
  410. 		self.row_width = 0 
  411. 	else 
  412. 		--I couldn't figure out a better way to calculate the row width other than building one temporarily and deleting it...(JMH 8/5/2011) 
  413. 		local temp_row = Vdo_row:clone(self.row.handle) 
  414. 		temp_row:set_value("label_1", "label_2", "label_3", "label_4")	 
  415. 		temp_row:set_max_width(width) 
  416. 		temp_row:format_columns(self.row_largest_col_1, self.row_largest_col_2, self.row_largest_col_3, self.row_largest_col_4) 
  417. 		self.row_width = temp_row:get_width() 
  418. 		temp_row:object_destroy() 
  419. 	end 
  420. 	 
  421. 	if num_toggles ~= 0 then 
  422. 		--I couldn't figure out a better way to calculate the row width other than building one temporarily and deleting it...(JMH 8/5/2011) 
  423. 		local temp_toggle = Vdo_toggle:clone(self.toggle.handle) 
  424. 		temp_toggle:set_text_scale(self.font_scale) 
  425. 		temp_toggle:set_value("toggle") 
  426. 		temp_toggle:set_width(self.toggle_max_value_width) 
  427. 		self.toggle_width = temp_toggle:get_width() 
  428. 		temp_toggle:object_destroy() 
  429. 	end 
  430. 	 
  431. 	local remap_width = 0 
  432. 	if num_remaps == 0 then 
  433. 		remap_width = 0 
  434. 	else 
  435. 		-- TODO: Update this to actually come from somewhere 
  436. 		remap_width = 200 
  437. 	end 
  438. 	 
  439. 	-- If the string and slider are greater than the width passed into draw items  
  440. 	-- then expand the width to accomodate 
  441. 		 
  442. 	--Accomodate for button offset in the max_label_width... 
  443. 	self.button_offset = (self.button_x) 
  444. 	--if self.num_buttons == num_sliders or self.num_buttons == num_toggles then 
  445. 		self.button_offset = self.button_x + ANCHOR_SLIDER_LABEL		 
  446. 	--end 
  447. 	 
  448. 	self.max_label_width = self.max_label_width + self.button_offset 
  449. 	 
  450. 	--If the label is bigger than the width sent in for the list then we should resize the labels... 
  451. 	if self.scale_text_if_too_big then 
  452. 		if self.max_label_width > width - 35 then 
  453. 			--modify font size 
  454. 			local scale_ratio = (width - 35) / self.max_label_width 
  455. 			local font_scale = self.font_scale * scale_ratio 
  456. 			self.text_is_too_big_font_scale = font_scale 
  457. 			 
  458. 			self.max_label_width = self.max_label_width * scale_ratio 
  459. 			self.text_is_to_big = true 
  460. 		else 
  461. 			self.text_is_to_big = false 
  462. 		end 
  463. 	end 
  464. 	 
  465. 	--Calculate the new width 
  466. 	local new_width = width	 
  467. 	local width_of_slider_item = self.max_label_width + self.slider_width  
  468. 	local width_of_toggle_item = self.max_label_width + self.toggle_max_value_width 
  469. 	new_width = max(self.max_label_width, new_width)	--Compare against normal width of an item... 
  470. 	new_width = max(width_of_slider_item, new_width)	--Compare against slider... 
  471. 	new_width = max(width_of_toggle_item, new_width)	--Compare against toggles... 
  472. 	new_width = max(self.row_width, new_width)		--Compare against row width... 
  473. 	new_width = max(remap_width, new_width)	--Compare against remap width 
  474. 	self.new_width = new_width 
  475.  
  476. 	--Toggle X 
  477. 	self.slider_x 			= 0 
  478. 	self.toggle_x 			= 0 
  479. 	self.toggle_color_x 	= 0 
  480.  
  481. 	--Store positions for everything... 
  482. 	--These are all sliders, so they need to be repositioned... 
  483. 	--if self.num_buttons == num_sliders then 
  484. 	self.label_x = ANCHOR_SLIDER_LABEL 
  485. 	self.slider_x = new_width - self.slider_width 
  486. 	--else		 
  487. 	--	self.slider_x = new_width - self.slider_width 
  488. 	--end 
  489. 	 
  490. 	--Align toggles 
  491. 	--if self.num_buttons == num_toggles then 
  492. 	--	self.label_x = ANCHOR_SLIDER_LABEL 
  493. 	--end 
  494. 	 
  495. 	--Make sure this value is at least as big as our sliders 
  496. 	if self.slider_width ~= 0 then 
  497. 		--comparing against internal width (self.slider:get_internal_width()), the size without the arrows, 
  498. 		--we are comparing this with the internal of the toggle width so we can set the width of the toggle... 
  499. 		self.toggle_max_value_width = max(self.slider:get_internal_width(), self.toggle_max_value_width) 
  500. 	end 
  501. 	 
  502. 	--Find largest toggle and slider 
  503. 	local max_item_width = 0 
  504. 	max_item_width 		= max(max_item_width, self.toggle_width)	--TODO: There is a width for this somewhere... 
  505. 	max_item_width 		= max(max_item_width, self.slider_width) 
  506. 	max_item_width 		= max(max_item_width, self.toggle_color_width) 
  507. 	self.max_item_width = max_item_width 
  508. 	 
  509. 	-- Set initial cursor position 
  510. 	if current_option == nil then 
  511. 		current_option = 1 
  512. 	elseif current_option > self.num_buttons then 
  513. 		current_option = self.num_buttons 
  514. 	end 
  515. 	 
  516. 	--set the cuurent button to the passed in variable for the current option 
  517. 	self.current_idx = current_option 
  518. 	 
  519. 	self.visible_start_idx = 1 
  520. 	 
  521. 	 
  522. 	-- if we force width we should still draw at a certain width... 
  523. 	if force_width == true then 
  524. 		--calculate height of our list 
  525. 		local total_items = #self.data 
  526. 		local start_y = LIST_BUTTON_HEIGHT * BUTTON_ANCHOR_OFFSET	--height of button * .5 because button is aligned to middle... 
  527. 		local offset_y = (LIST_BUTTON_HEIGHT + MEGA_LIST_BUTTON_SPACING) * (total_items - 1) 	-- height of button + button spacing * the button index. (-1 because our index starts at 1 and the first item doesn't need offset...) 
  528. 		local mask_height = start_y + offset_y + (LIST_BUTTON_HEIGHT + MEGA_LIST_BUTTON_SPACING) 
  529.  
  530. 		 
  531. 		if self.marquee_anim == nil then 
  532. 			--only set up callbacks if we havn't done it already... 
  533. 			self.marquee_anim = Vdo_anim_object:new("marquee_anim", self.handle, self.doc_handle) 
  534. 			local marquee_end_twn_h = vint_object_find("marquee_end_twn", self.marquee_anim.handle) 
  535. 			local twn_cb = self:package_tween_callback("marquee_loop_cb") 
  536. 			vint_set_property(marquee_end_twn_h, "end_event", twn_cb) 
  537. 		end 
  538. 		 
  539. 		-- Show Marquee Mask 
  540. 		local marq_mask_h = vint_object_find("mega_marquee_mask", self.handle) 
  541. 		vint_set_property(marq_mask_h, "visible", true) 
  542. 		vint_set_property(marq_mask_h, "mask", true) 
  543. 		element_set_actual_size(marq_mask_h, width, mask_height) 
  544. 		new_width = width 
  545. 		self.force_width = true 
  546. 	else 
  547. 		local marq_mask_h = vint_object_find("mega_marquee_mask", self.handle) 
  548. 		vint_set_property(marq_mask_h, "visible", false) 
  549. 		vint_set_property(marq_mask_h, "mask", false) 
  550. 		self.force_width = false 
  551. 	end 
  552. 	 
  553. 	self:set_size(new_width) 
  554. 	 
  555. 	--Draw the items now just as if the script hasn't changed yet... 
  556. 	self:draw_item_range(self.current_idx) 	 
  557. 	 
  558. 	--reset the y of the list group 
  559. 	local list_x, list_y = vint_get_property(self.group_h, "anchor") 
  560. 	vint_set_property(self.group_h, "anchor", list_x, 0)	 
  561. 		 
  562. 	-- Draw the cursor 
  563. 	self:move_cursor(0, nil, was_new) 
  564. 	if self.highlight_on ~= nil then 
  565. 		self:toggle_highlight(self.highlight_on) 
  566. 	end 
  567. 	 
  568. 	--Animate the list in.  
  569. 	-- Only if we didn't just wrap and the list was told to animate. 
  570. 	if self.wrapped == false and self.animate_list == true then			 
  571. 	 
  572. 		--loop through created items 
  573. 		local visible_end_idx = self.visible_start_idx + (self.max_buttons - 1) 
  574. 		local item_min = current_option - self.max_buttons * 0.5 
  575. 		local item_max = current_option + self.max_buttons * 0.5 
  576. 		 
  577. 		--If list doesn't scroll... 
  578. 		if self.max_buttons > self.num_buttons then 
  579. 			item_max = self.num_buttons 
  580. 		end 
  581. 		 
  582. 		--Adjust item max for when at the top of list 
  583. 		if self.current_idx <= self.max_buttons * 0.5 then 
  584. 			item_max = self.max_buttons 
  585. 		end 
  586. 		 
  587. 		--Adjust item min for when at the bottom of list... 
  588. 		if self.current_idx >= self.num_buttons - self.max_buttons then 
  589. 			item_min = self.num_buttons - self.max_buttons 
  590. 		end 
  591. 		 
  592. 		--Sanity Check...make sure we aren't out of range... 
  593. 		if item_min < 1 then 
  594. 			item_min = 1 
  595. 		end 
  596. 		 
  597. 		if item_max > self.num_buttons then 
  598. 			item_max = self.num_buttons 
  599. 		end	 
  600. 		 
  601. 		item_min = floor(item_min) 
  602. 		item_max = floor(item_max) 
  603. 		 
  604. 		local VDO_MEGALIST_TWN_OFFSET = .05	 
  605. 		local VDO_MEGALIST_ANCHOR_TWN_PADDING = 100 
  606. 		 
  607. 		for idx = item_min, item_max do --visible_end_idx do 
  608.  
  609. 			local button = self.buttons[idx] 
  610.  
  611. 			--Save the button's current y position, only animating the x value 
  612. 			local x, y = vint_get_property(button.handle, "anchor")  
  613. 			 
  614. 			--Clone and retarget tween for button 
  615. 			local anchor_twn_copy_h = vint_object_clone(self.intro_anchor_twn_h, self.intro_anim_h) 
  616. 			vint_set_property(anchor_twn_copy_h, "target_handle", button.handle) 
  617. 						 
  618. 			vint_set_property(anchor_twn_copy_h, "start_value", self.width + VDO_MEGALIST_ANCHOR_TWN_PADDING, y) 
  619. 			vint_set_property(anchor_twn_copy_h, "end_value", x, y) 
  620. 			vint_set_property(anchor_twn_copy_h, "start_time", self.intro_twn_counter * VDO_MEGALIST_TWN_OFFSET)			 
  621. 			 
  622. 			--Fade in special widgets 
  623. 			local target_handle = button.widget_handle  
  624. 			local option_twn_copy_h = 0 
  625. 			if target_handle ~= 0 then 
  626. 				option_twn_copy_h = vint_object_clone(self.option_twn_h, self.intro_anim_h) 
  627. 				vint_set_property(option_twn_copy_h, "target_handle", target_handle) 
  628. 				vint_set_property(option_twn_copy_h, "start_time", self.intro_twn_counter * VDO_MEGALIST_TWN_OFFSET) 
  629. 			end 
  630. 			 
  631. 			--Store tweens off into table for cleanup later... 
  632. 			self.intro_twns[self.intro_twn_counter] = {anchor_twn_copy_h, option_twn_copy_h} 
  633. 			self.intro_twn_counter = self.intro_twn_counter + 1			 
  634. 			 
  635. 			--Slide in Highlight. 
  636. 			if idx == self.current_idx then 
  637. 				vint_set_property(self.highlight_anchor_twn_h, "start_value", self.width + VDO_MEGALIST_ANCHOR_TWN_PADDING, y) 
  638. 				vint_set_property(self.highlight_anchor_twn_h, "end_value", x, y) 
  639. 				vint_set_property(self.highlight_anchor_twn_h, "start_time", self.intro_twn_counter * VDO_MEGALIST_TWN_OFFSET) 
  640. 			end		 
  641. 		end		 
  642. 		 
  643. 		--Set callback for last animation to reset the animated state. 
  644. 		local twn_cb = self:package_tween_callback("intro_anim_cb") 
  645. 		local anchor_twn_copy_h = self.intro_twns[self.intro_twn_counter - 1][1] 
  646. 		vint_set_property(anchor_twn_copy_h, "end_event", twn_cb) 
  647. 		 
  648. 		--Set all start values to initial position. 
  649. 		vint_apply_start_values(self.intro_anim_h) 
  650. 		vint_apply_start_values(self.highlight_anim_h) 
  651. 		 
  652. 		--Play all animations to finally transition in the list. 
  653. 		lua_play_anim(self.intro_anim_h, 0) 
  654. 		lua_play_anim(self.highlight_anim_h, 0) 
  655. 		 
  656. 		--Set flag for animation state. 
  657. 		self.intro_anim_is_playing = true 
  658. 	end 
  659. 	 
  660. 	Buttons = self 
  661. end 
  662.  
  663.  
  664. ------------------------------------------------------------------------------- 
  665. -- Sets the properties of the megalist... 
  666. -- megalist_properties = { 
  667. --		max_buttons 
  668. --		font_scale 
  669. --		width, 
  670. --		force_width 
  671. --		include_scrollbar_in_width 
  672. --		highlight_color 
  673. --		non_highlight_color 
  674. --		set_highlight_color 
  675. -- } 
  676. function Vdo_mega_list:set_properties(highlight_color, non_highlight_color, max_buttons, font_scale, width, force_width, include_scrollbar_in_width) 
  677. 		 
  678. 	--Set highlight color 
  679. 	if highlight_color ~= nil and non_highlight_color ~= nil then 
  680. 		self:set_highlight_color(highlight_color, non_highlight_color) 
  681. 	end 
  682. 	 
  683. 	font_scale = 0.8 
  684. 	 
  685. 	self.max_buttons = max_buttons or 999	--Default max buttons 
  686. 	self.font_scale = font_scale or 1.0		--Default scale. 
  687. 	self.width = width or 465					--Default width 
  688. 	self.force_width = force_width or false		--force width is off by default.. 
  689. 	if include_scrollbar_in_width == nil then 
  690. 		--force width is off by default.. 
  691. 		self.include_scrollbar_in_width = false 
  692. 	else 
  693. 		self.include_scrollbar_in_width = include_scrollbar_in_width 
  694. 	end 
  695. end 
  696.  
  697.  
  698.  
  699. function Vdo_mega_list:draw_item_range(current_option) 
  700. 	if game_get_platform() == "PC" then 
  701. 		for i = 1, #self.data do  
  702. 			self.buttons[i] = self:draw_single_item(i, false)		 
  703. 		end 
  704. 		return 
  705. 	end 
  706.  
  707. 	--This could be streamlined... 
  708. 	local item_min = current_option - self.max_buttons 
  709. 	local item_max = current_option + self.max_buttons 
  710. 	 
  711. 	if item_min < 1 then 
  712. 		item_min = 1 
  713. 	end 
  714. 	local total_items = #self.data 
  715. 	if item_max > total_items then 
  716. 		item_max = total_items 
  717. 	end 
  718.  
  719. 	if item_max < item_min then 
  720. 		--fail 
  721. 		return 
  722. 	end 
  723. 	 
  724. 	--check if its equals... 
  725. 	 
  726. 	 
  727. 	for i, button in pairs(self.buttons) do 
  728. 		local destroy_button = false 
  729. 		 
  730. 		--remove the items below...		 
  731. 		if i < item_min then 
  732. 			destroy_button = true 
  733. 		elseif i > item_max then 
  734. 			destroy_button = true 
  735. 		end 
  736. 		 
  737. 		if destroy_button then 
  738. 			self:cleanup_single_item(button) 
  739. 			self.buttons[i] = nil 
  740. 		end 
  741. 	end 
  742. 	 
  743. 	--redraw all the items in range if we are redrawing the list... 
  744. 	local draw_all_items_in_range = false 
  745. 	if self.item_range_min == 0 and self.item_range_max == 0 then 
  746. 		draw_all_items_in_range =  true 
  747. 	end 
  748. 	 
  749. 	 
  750. 	for i = item_min, item_max do  -- item_min + item_max 
  751. 		local create_button = false 
  752. 		if i <= self.item_range_min then 
  753. 			create_button = true 
  754. 		elseif i >= self.item_range_max then 
  755. 			create_button = true 
  756. 		end 
  757.  
  758. 		if create_button or draw_all_items_in_range then 
  759. 			if self.buttons[i] == nil then 
  760. 				self.buttons[i] = self:draw_single_item(i, false) 
  761. 			end 
  762. 		end 
  763. 	end 
  764. 	 
  765. 	self.item_range_min = item_min 
  766. 	self.item_range_max = item_max 
  767. end 
  768.  
  769.  
  770. function Vdo_mega_list:draw_single_item(item_index, check_size, super_special_case) 
  771. 	-- Assign the button copy to the table that manages data for this object 
  772. 	local button_copy = self.toggle_base 
  773. 	button_copy.x, button_copy.y = button_copy:get_property("anchor") 
  774. 	 
  775. 	local button = Vdo_button_toggle:clone(button_copy.handle) 
  776. 	local item = self.data[item_index] 
  777. 	 
  778. 	--only show the odd number row backgrounds 
  779. 	if self.has_lines then 
  780. 		if item_index < self.num_buttons then 
  781. 			button:set_bg( true ) 
  782. 		end 
  783. 	end 
  784. 	 
  785. 	button.widget_handle = 0	--Reference to any widgets that get created on the right side of theb utton. 
  786. 						 
  787. 	if item.label ~= nil then 
  788. 		button:set_label(item.label) 
  789. 	else 
  790. 		button:set_label_crc(item.label_crc) 
  791. 	end 
  792. 	 
  793. 	--Reset Icon.... 
  794. 	button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NONE, BUTTON_TOGGLE_ICON_TYPE_NONE)		 
  795.  
  796. 	-- Clone new tween onto new items 
  797. 	if item.is_new == true and check_size == false then 
  798. 		 
  799. 		-- Set icon to new icon (arrow) 
  800. 		-- For Powers screen elements menu - show a chechbox in addition to the new icon 
  801. 		if item.is_element == true then  
  802. 			button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NEW, BUTTON_TOGGLE_ICON_TYPE_BOX) 
  803. 		elseif item.remote_objective == true then 
  804. 			button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NEW, BUTTON_TOGGLE_ICON_TYPE_QUEST_PINNED_COOP) 
  805. 		else 
  806. 			button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NEW, BUTTON_TOGGLE_ICON_TYPE_NONE) 
  807. 		end 
  808. 		button:set_color(self.highlight_color) 
  809. 		 
  810. 		-- clone and play pulse twn	 
  811. 		button.new_tween = Vdo_tween_object:clone(self.pulse_twn.handle) 
  812. 		button.new_tween:set_target_handle(button.handle) 
  813. 		 
  814. 		self.pulse_anim:play(0)			 
  815. 	end 
  816. 	 
  817. 	if item.is_dlc == true then			 
  818. 		-- set icon to new icon (exclamation point) 
  819. 		button:set_icon(BUTTON_TOGGLE_ICON_TYPE_DLC, BUTTON_TOGGLE_ICON_TYPE_NONE) 
  820. 	elseif item.is_dlc2 == true then 
  821. 		button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NONE, BUTTON_TOGGLE_ICON_TYPE_DLC) 
  822. 	end		 
  823. 	 
  824. 	if item.is_locked then 
  825. 		button:set_icon(BUTTON_TOGGLE_ICON_TYPE_LOCK, BUTTON_TOGGLE_ICON_TYPE_NONE) 
  826. 	else 
  827. 		if item.equipped ~= nil then 
  828. 			if item.equipped then 
  829. 				-- Display Checked Checkbox... 
  830. 				button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NONE, BUTTON_TOGGLE_ICON_TYPE_BOX_CHECKED) 
  831. 			elseif item.equipped == false and item.owned == true then 
  832. 				-- Display Empty Checkbox... 
  833. 				button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NONE, BUTTON_TOGGLE_ICON_TYPE_BOX) 
  834. 			else	 
  835. 				--Still indent icon... 
  836. 				button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NONE, BUTTON_TOGGLE_ICON_TYPE_INDENT) 
  837. 			end 
  838. 			button.is_indented = true 
  839. 		elseif item.is_purchased then 
  840. 			-- Display Checkbox... 
  841. 			button:set_icon(BUTTON_TOGGLE_ICON_TYPE_BOX_CHECKED, BUTTON_TOGGLE_ICON_TYPE_NONE) 
  842. 		elseif item.cheats_equipped ~= nil then 
  843. 			if item.cheats_equipped then 
  844. 				-- Display Checked Checkbox...greyed out 
  845. 				button:set_color(90/255,90/255,90/255) 
  846. 				button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NONE, BUTTON_TOGGLE_ICON_TYPE_BOX_CHECKED) 
  847. 			elseif item.cheats_equipped == false and item.owned == true then 
  848. 				-- Display Empty Checkbox... 
  849. 				button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NONE, BUTTON_TOGGLE_ICON_TYPE_BOX) 
  850. 			else 
  851. 				--Still indent icon... 
  852. 				button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NONE, BUTTON_TOGGLE_ICON_TYPE_INDENT) 
  853. 			end 
  854. 			button.is_indented = true		 
  855. 		end 
  856. 	end 
  857. 	 
  858. 	if item.disabled == true then 
  859. 		button:set_enabled(false) 
  860. 	else 
  861. 		button:set_enabled(true) 
  862. 	end 
  863. 	 
  864. 	if item.is_special == true then 
  865. 		button:set_icon(BUTTON_TOGGLE_ICON_TYPE_SPECIAL, BUTTON_TOGGLE_ICON_TYPE_NONE) 
  866. 	end 
  867. 	 
  868. 	if item.completed == true then 
  869. 		-- Display Checked Checkbox...greyed out 
  870. 		button:set_icon(BUTTON_TOGGLE_ICON_TYPE_COMPLETED, BUTTON_TOGGLE_ICON_TYPE_NONE)			 
  871. 	end 
  872. 	 
  873. 	if item.remote_objective == true then 
  874. 		-- Display a pinned icon with the number 2 indicating the coop player's active objective 
  875. 		button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NONE, BUTTON_TOGGLE_ICON_TYPE_QUEST_PINNED_COOP)			 
  876. 	end 
  877. 	 
  878. 	if item.quest_pinned == true then 
  879. 		-- Display double arrows indicating an active objective 
  880. 		button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NONE, BUTTON_TOGGLE_ICON_TYPE_QUEST_PINNED)				 
  881. 	end 
  882. 	 
  883. 	if item.obj_complete == true then 
  884. 		button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NONE, BUTTON_TOGGLE_ICON_TYPE_QUEST_COMPLETE)		 
  885. 		button:set_alpha(0.35) 
  886. 	end 
  887. 	 
  888. 	-- Move the button copy into the correct position 
  889. 	local new_y = 0 
  890. 	 
  891. 	local pre_scale_text_width = button:get_text_width() + MEGA_LIST_BUTTON_PADDING 
  892. 	if pre_scale_text_width >= self.width * 0.74 and item.type == TYPE_PIP then 
  893. 		--modify font size 
  894. 		local scale_ratio = (self.width * 0.70) / pre_scale_text_width 
  895. 		local font_scale = self.font_scale * scale_ratio 
  896. 		self.text_is_too_big_font_scale = font_scale 
  897. 			 
  898. 		self.text_is_to_big = true 
  899. 	elseif pre_scale_text_width < self.width * 0.74 and item.type == TYPE_PIP then 
  900. 		self.text_is_to_big = false 
  901. 	end 
  902. 	 
  903. 	--If text is too big then we are going to scale down the font scale... 
  904. 	local font_scale = self.font_scale 
  905. 	if self.text_is_to_big then 
  906. 		font_scale = self.text_is_too_big_font_scale 
  907. 	end 
  908. 	 
  909. 	--Set text scale on the button... 
  910. 	button:set_text_scale(font_scale, font_scale) 
  911. 	 
  912. 	local start_y = LIST_BUTTON_HEIGHT * BUTTON_ANCHOR_OFFSET	--height of button * .5 because button is aligned to middle... 
  913. 	local offset_y = (LIST_BUTTON_HEIGHT + MEGA_LIST_BUTTON_SPACING) * (item_index - 1) 	-- height of button + button spacing * the button index. (-1 because our index starts at 1 and the first item doesn't need offset...) 
  914. 	new_y = start_y + offset_y 
  915. 	button:set_property("anchor", button_copy.x, new_y) 
  916. 	 
  917. 	-- Make the button visible 
  918. 	button:set_property("visible", true) 
  919. 	 
  920. 	-- Find largest text string and store it to self... 
  921. 	local text_width = button:get_text_width() + MEGA_LIST_BUTTON_PADDING 
  922. 	self.max_label_width = max(text_width, self.max_label_width) 
  923.  
  924. 	-- If the item is more than a button then we will attach something special to it... 
  925. 	if item.type == TYPE_TOGGLE then 
  926. 		-- Clone toggle 
  927. 		local toggle = Vdo_toggle:clone(self.toggle.handle) 
  928. 		 
  929. 		--Show toggle 
  930. 		toggle:set_visible(true) 
  931. 		 
  932. 		--Set the scale of the toggle element... 
  933. 		toggle:set_text_scale(self.font_scale) 
  934. 		 
  935. 		--Re-set Highlight colors on objects before they are cloned... 
  936. 		toggle:set_highlight_color(self.highlight_color)	 
  937. 		 
  938. 		if item.disabled == true then 
  939. 			toggle:set_disabled(true) 
  940. 		end 
  941.  
  942. 		if check_size == true then 
  943. 			--Test width all the options in the toggle, store off the data to self, then destroy the object. 
  944. 			local max_value_width = 0  
  945. 	 
  946. 			local options = item.options 
  947. 			local num_options = #options 
  948. 			for option_idx = 1, num_options do 
  949. 				toggle:set_value(options[option_idx]) 
  950. 				local toggle_value_width = toggle:get_value_width() 
  951. 				max_value_width = max(toggle_value_width, max_value_width) 
  952. 			end 
  953. 			self.toggle_max_value_width = max(self.toggle_max_value_width, max_value_width) 
  954. 			 
  955. 			--Destroy Toggle 
  956. 			toggle:object_destroy() 
  957. 		else 
  958. 			--Populate the toggle with current data, align toggle, then store off toggle to button. 
  959. 			local options = item.options 
  960. 			local option_idx = item.current_value 
  961. 			local cur_value = options[option_idx] 
  962. 			toggle:set_value(cur_value)	 
  963. 			toggle:set_width(self.toggle_max_value_width) 
  964. 			 
  965. 			if not super_special_case or super_special_case == nil then 
  966. 				--Align toggle in the list 
  967. 				local toggle_x, toggle_y = button:get_anchor()	 
  968. 				local toggle_x = self.new_width - (self.max_item_width * .5) - (toggle:get_width() * .5) - SLIDER_PADDING_RIGHT 
  969. 				toggle:set_property("anchor", toggle_x , toggle_y) 
  970. 			end 
  971. 		 
  972. 			--Change button anchor... 
  973. 			button:set_label_anchor(self.label_x) 
  974. 		 
  975. 			-- Store Toggle 
  976. 			button.toggle = toggle 
  977. 			button.widget_handle = toggle.handle 
  978. 		end 
  979. 	elseif item.type == TYPE_SLIDER then 
  980. 		local slider = Vdo_slider:clone(self.slider.handle) 
  981. 		 
  982. 		--Show Slider 
  983. 		slider:set_visible(true) 
  984. 		 
  985. 		slider:set_highlight_color(self.highlight_color)	 
  986. 		 
  987. 		if item.disabled == true then 
  988. 			slider:set_disabled(true) 
  989. 		end			 
  990. 		 
  991. 		if check_size then 
  992. 			--Destroy Slider 
  993. 			slider:object_destroy() 
  994. 		else 
  995. 			-- Set value 
  996. 			slider:set_value(item.current_value, item.min, item.max, nil, item.mapping) 
  997. 		 
  998. 			--Align slider in list... 
  999. 			local slider_x, slider_y = button:get_anchor()		 
  1000. 			slider_x = self.new_width - (self.max_item_width * .5) - (self.slider_width *.5) - SLIDER_PADDING_RIGHT 
  1001. 			slider:set_property("anchor", slider_x, slider_y) 
  1002. 		 
  1003. 			--Change button anchor... 
  1004. 			button:set_label_anchor(self.label_x) 
  1005. 		 
  1006. 			-- Store Slider 
  1007. 			button.slider = slider 
  1008. 			button.widget_handle = slider.handle 
  1009. 		end 
  1010. 	elseif item.type == TYPE_ROW then 
  1011. 		button:set_label("") 
  1012. 		button:set_property("visible", false) 
  1013. 		--Clone Toggle and update values... 
  1014. 		local row = Vdo_row:clone(self.row.handle) 
  1015. 		 
  1016. 		row:set_font_scale(self.font_scale) 
  1017. 		 
  1018. 		local row_alignment = self.data.row_alignment 
  1019. 		if row_alignment ~= nil then 
  1020. 			row:set_alignment(row_alignment[1], row_alignment[2], row_alignment[3], row_alignment[4]) 
  1021. 		end 
  1022. 		 
  1023. 		local row_column_count = self.data.row_column_count 
  1024. 		if row_column_count ~= nil then 
  1025. 			row:set_column_count(row_column_count) 
  1026. 		end 
  1027. 	 
  1028. 		-- Set the button toggle value 
  1029. 		row:set_value(item.label_1, item.label_2, item.label_3, item.label_4)	 
  1030. 		row:set_property("anchor", button_copy.x, new_y) 
  1031. 		row:set_property("alpha", 1) 
  1032. 			 
  1033. 		row:set_visible(true) 
  1034. 		 
  1035. 		if check_size then 
  1036. 			--Check the sizes and store them to global... 
  1037. 			local row_col_1, row_col_2, row_col_3, row_col_4 = row:get_column_widths() 
  1038. 			self.row_largest_col_1 = max(row_col_1, self.row_largest_col_1) 
  1039. 			self.row_largest_col_2 = max(row_col_2, self.row_largest_col_2) 
  1040. 			self.row_largest_col_3 = max(row_col_3, self.row_largest_col_3) 
  1041. 			self.row_largest_col_4 = max(row_col_4, self.row_largest_col_4) 
  1042. 		 
  1043. 			--Destroy Row 
  1044. 			row:object_destroy() 
  1045. 		else 
  1046. 			row:set_max_width(self.width) 
  1047. 			row:format_columns(self.row_largest_col_1, self.row_largest_col_2, self.row_largest_col_3, self.row_largest_col_4) 
  1048. 			-- Store Row 
  1049. 			button.row = row 
  1050. 			button.widget_handle = row.handle 
  1051. 		end 
  1052. 	elseif item.type == TYPE_TOGGLE_COLOR then 
  1053. 		--Clone Color Toggle and update values... 
  1054. 		local toggle_color = Vdo_toggle_color:clone(self.toggle_color.handle) 
  1055. 		 
  1056. 		toggle_color:set_color_value(item.color) 
  1057. 		toggle_color:set_property("anchor", button_copy.x, new_y) 
  1058. 		 
  1059. 		toggle_color:set_property("alpha", 1) 
  1060. 		toggle_color:set_visible(true) 
  1061. 		 
  1062. 		if check_size then 
  1063. 			--Destroy Color 
  1064. 			toggle_color:object_destroy() 
  1065. 		else 
  1066. 			local toggle_color_x, toggle_color_y = button:get_anchor()		 
  1067. 			toggle_color_x = self.new_width - (self.max_item_width * .5) - (self.toggle_color_width *.5) - SLIDER_PADDING_RIGHT 
  1068. 			toggle_color:set_property("anchor", toggle_color_x, toggle_color_y) 
  1069. 		 
  1070. 			--Change button anchor... 
  1071. 			button:set_label_anchor(self.label_x) 
  1072. 		 
  1073. 			-- Store Color 
  1074. 			button.toggle_color = toggle_color 
  1075. 			button.widget_handle = toggle_color.handle 
  1076. 		end	 
  1077. 	elseif item.type == TYPE_REMAP then 
  1078. 		--Set all properties here... 
  1079. 		button:set_label("") 
  1080. 		button:set_property("visible", false) 
  1081. 		 
  1082. 		--Clone and update values... 
  1083. 		local remap = Vdo_button_remap:clone(self.remap.handle) 
  1084. 		 
  1085. 		-- TODO: Make this init correctly 
  1086. 		remap:set_label(item.label)	 
  1087. 		remap:set_shortcut(1, item.value1)	 
  1088. 		remap:set_shortcut(2, item.value2)	 
  1089. 		remap:set_property("anchor", button_copy.x, new_y) 
  1090. 		remap:set_property("alpha", 1) 
  1091. 		remap:set_visible(true) 
  1092. 		remap:set_value_offset(self.width - 450) 
  1093. 		 
  1094. 		--Change button anchor... 
  1095. 		button:set_label_anchor(self.label_x) 
  1096. 		 
  1097. 		-- Resize the click region to cover the label. 
  1098. 		local second_button_x = remap.value_bg[2]:get_property("anchor") 
  1099. 		local second_button_w = remap.value_bg[2]:get_actual_size() 
  1100. 		local new_width = (second_button_x - self.label_x - second_button_w / 2) / 2; 
  1101. 		local old_scale_x, old_scale_y = remap.value_bg[1]:get_property("scale") 
  1102. 		remap.value_bg[1]:set_property("anchor", self.label_x + new_width) 
  1103. 		remap.value_bg[1]:set_property("scale", new_width / (remap.value_bg[1]:get_actual_size() / 2) * old_scale_x, old_scale_y)			 
  1104. 		 
  1105. 		if check_size then 
  1106. 			--Destroy Remap 
  1107. 			remap:object_destroy() 
  1108. 		else 
  1109. 			-- Store Remap 
  1110. 			button.remap = remap 
  1111. 			button.widget_handle = remap.handle 
  1112. 		end 
  1113. 		 
  1114. 		--Set the remap column (used for non-mouse navigation) 
  1115. 		self.remap_column = 1 
  1116. 	elseif item.type == TYPE_HEADER then 
  1117. 		--Hide button 
  1118. 		button:set_label("") 
  1119. 		button:set_property("visible", false) 
  1120. 		 
  1121. 		local header = Vdo_button_header:clone(self.header.handle) 
  1122. 		 
  1123. 		if item.label ~= nil then 
  1124. 			header:set_label(item.label) 
  1125. 		else 
  1126. 			header:set_label_crc(item.label_crc) 
  1127. 		end 
  1128. 			 
  1129. 		header:set_visible(true) 
  1130. 		 
  1131. 		--Align header in the list 
  1132. 		local header_x, header_y = button:get_anchor()	 
  1133. 		header:set_property("anchor", header_x , header_y)		 
  1134. 		 
  1135. 		--Set header scrim width to list width 
  1136. 		header:set_width(self.width) 
  1137. 		 
  1138. 		item.disabled = true 
  1139. 		 
  1140. 		if check_size then 
  1141. 			--Destroy Header 
  1142. 			header:object_destroy() 
  1143. 		else 
  1144. 			-- Store Header 
  1145. 			button.header = header 
  1146. 			button.widget_handle = header.handle 
  1147. 		end 
  1148. 	elseif item.type == TYPE_PIP then 
  1149. 	 
  1150. 		--Create pip button 
  1151. 		local pip = Vdo_button_pip:clone(self.pip.handle) 
  1152. 		 
  1153. 		pip:set_visible(true) 
  1154. 		 
  1155. 		--Align pip in the list 
  1156. 		local button_x, button_y = button:get_anchor() 
  1157. 		pip:set_property("anchor", button_x, button_y) 
  1158. 		 
  1159. 		if check_size then 
  1160. 			pip:object_destroy() 
  1161. 		else 
  1162. 			--Set pips 
  1163. 			pip:set_pips(item.max_level, item.level, self.width, self.highlight_color)  
  1164. 		 
  1165. 			button.pip = pip 
  1166. 			button.widget_handle = pip.handle 
  1167. 		end		 
  1168. 		 
  1169. 	elseif item.type == TYPE_LINE_BREAK then 
  1170. 		button:set_label("") 
  1171. 		button:set_property("visible", false) 
  1172. 		item.disabled = true 
  1173. 	end 
  1174. 	 
  1175. 	--HVS_JPM[KING] 12/11/2014: if there are invite flags (from the invite friends screen) we will color the text differently) 
  1176. 	if item.invite_flags ~= nil then 
  1177. 		if item.invite_flags == MULTI_FRIEND_FLAG_ONLINE then --MULTI_FRIEND_FLAG_ONLINE 
  1178. 			button:set_highlight_color(COLOR_ONLINE_SELECTED, COLOR_ONLINE_UNSELECTED) 
  1179. 		elseif item.invite_flags == MULTI_FRIEND_FLAG_ONLINE_AND_IN_GAME or item.invite_flags == MULTI_FRIEND_FLAG_ONLINE_JOINABLE then --MULTI_FRIEND_FLAG_ONLINE_AND_IN_GAME 
  1180. 			button:set_highlight_color(COLOR_JOINABLE_SELECTED, COLOR_JOINABLE_UNSELECTED) 
  1181. 		else 
  1182. 			button:set_highlight_color(COLOR_PING_RED, COLOR_PING_RED) 
  1183. 		end 
  1184. 	end		 
  1185. 	 
  1186. 	if check_size == true then 
  1187. 		button:object_destroy() 
  1188. 		return 
  1189. 	else 
  1190. 		return button 
  1191. 	end 
  1192. end 
  1193.  
  1194.  
  1195. -- Updates the mega list.  Possibly changes the currently highlighted choice. 
  1196. -- 
  1197. -- direction: 0 means to redraw the megalist, but don't move the cursor.  1 means move down, -1 means move up. 
  1198. -- is_index_set: if the selected index was manually set (by the mouse), then is_index_set will be true 
  1199. -- 
  1200. function Vdo_mega_list:move_cursor(direction, is_index_set, was_new)	 
  1201.  
  1202. 	--debug_print("vint","Move cursor direction ::::::::: "..var_to_string(direction).."\n") 
  1203. 	 
  1204. 	if not self.draw_called then 
  1205. 		--debug_print("vint", "Vdo_mega_list:move_cursor called with invalid document handle\n") 
  1206. 		return 
  1207. 	end 
  1208. 	 
  1209. 	--Don't move if we're animating 
  1210. 	if self.intro_anim_is_playing == true and direction ~= 0 then 
  1211. 		return 
  1212. 	end 
  1213. 	 
  1214. 	-- Default is_index_set to false 
  1215. 	is_index_set = is_index_set or false 
  1216. 	 
  1217. 	local highlight = self.button_highlight 
  1218.  
  1219. 	-- Check if we can process input.  If we can't, we still need to redraw the list, or the state can get out of sync. 
  1220. 	-- But we need to change direction to 0 because we can't start scrolling while we are already scrolling. 
  1221. 	if Vdo_mega_list_tween_done == false then 
  1222. 		direction = 0 
  1223. 	end 
  1224. 	 
  1225. 	--toggle is closed so navigate the list normally 
  1226. 	local current_idx = self.current_idx 
  1227. 	self.current_idx = wrap_index(self.current_idx, direction, self.num_buttons) 
  1228. 		 
  1229. 	--Did we wrap?  Don't animate the list if we did and reset the tween counter 
  1230. 	self.wrapped = false	 
  1231. 	if current_idx == self.num_buttons and self.current_idx == 1 then 
  1232. 		self.wrapped = true		 
  1233. 	elseif current_idx == 1 and self.current_idx == self.num_buttons then 
  1234. 		self.wrapped = true		 
  1235. 	end 
  1236. 	 
  1237. 	--If list only has one button then set wrap to false 
  1238. 	if self.num_buttons == 1 then 
  1239. 		self.wrapped = false 
  1240. 	end 
  1241. 		 
  1242. 	--Skip the selection if disabled, type header, or type line break 
  1243. 	--Also, if we moved the direction here, don't play audio 
  1244. 	local play_move_cursor_audio = true 
  1245. 	if self.data[self.current_idx].disabled == true then 
  1246. 		--Increment the direction 
  1247. 		if direction == 0 then  
  1248. 			direction = 1 
  1249. 			play_move_cursor_audio = false 
  1250. 		end 
  1251.  
  1252. 		-- Makes sure this is in sync with the member variable before 
  1253. 		-- we loop through the list 
  1254. 		local current_idx = self.current_idx 
  1255. 		 
  1256. 		--check to make sure we are not disabled and keep cycling until we find one that isn't...		 
  1257. 		repeat  
  1258. 			self.current_idx = wrap_index(self.current_idx, direction, self.num_buttons) 
  1259. 		until self.data[self.current_idx].disabled ~= true or current_idx == self.current_idx 
  1260. 	end 
  1261. 	 
  1262. 	local total_buttons = #self.data 
  1263. 	local move_height = LIST_BUTTON_HEIGHT + MEGA_LIST_BUTTON_SPACING 
  1264.  
  1265. 	local new_y = 0 
  1266. 	 
  1267. 	--Store off current list x and list y... 
  1268. 	local list_x, list_y = vint_get_property(self.group_h, "anchor") 
  1269. 	 
  1270. 	--Set list_y to our stored list_y. 
  1271. 	--The menu may be mid tween, so for future calculations its new position must be based on the true list_y. 
  1272. 	list_y = self.list_y 
  1273. 	 
  1274. 	-- use max_buttons + 1 since the starting index is 1 
  1275. 	local visual_center = floor( (self.max_buttons + 1) * 0.5 ) 
  1276. 	local button_x, button_y = 0,0 
  1277.  
  1278. 	local scrolling = true		 
  1279.  
  1280. 	local pc_style_scrolling = false 
  1281. 	--if ( Game_platform == "PC" and game_is_active_input_gamepad() == false ) then 
  1282. 	if Game_platform == "PC" then	 
  1283. 		pc_style_scrolling = true 
  1284. 	end 
  1285.  
  1286. 	 
  1287. 	--do we need to scroll? 
  1288. 	if direction == 1 or direction == -1 then	-- moving down or up the list 
  1289. 		if pc_style_scrolling then 
  1290. 			local visible_end_idx = self.visible_start_idx + (self.max_buttons - 1) 
  1291. 			 
  1292. 			if self.current_idx < self.visible_start_idx then -- Current index is above the top of the visible list 
  1293. 				new_y = (self.current_idx - 1) * -move_height 
  1294. 				self.visible_start_idx = self.current_idx 
  1295. 			elseif self.current_idx > visible_end_idx then -- Current index is below the bottom of the visible list 
  1296. 				new_y = (self.current_idx - self.max_buttons) * -move_height 
  1297. 				self.visible_start_idx = self.current_idx - (self.max_buttons -1) 
  1298. 			else 
  1299. 				new_y = list_y 
  1300. 				scrolling = false 
  1301. 			end 
  1302. 			 
  1303. 			-- If the first item is disabled make sure we still show it 
  1304. 			if(self.data[1].disabled == true and self.current_idx == 2 ) then 
  1305. 				self.visible_start_idx = 1 
  1306. 				new_y = 0 
  1307. 			end 
  1308. 		else 
  1309. 			if self.num_buttons > self.max_buttons then			 
  1310. 				if self.current_idx < visual_center then 
  1311. 					new_y = 0 
  1312. 				elseif self.current_idx >= (self.num_buttons - ceil(visual_center * 0.5)) - 1 then 
  1313. 					new_y = (self.num_buttons - self.max_buttons) * -move_height  
  1314. 				else 
  1315. 					new_y = (self.current_idx - visual_center) * -move_height 
  1316. 				end 
  1317. 			end 
  1318. 			-- If list position changed then we scrolled 
  1319. 			scrolling = (new_y ~= list_y) 
  1320. 		end 
  1321. 	elseif direction == 0 then 
  1322. 		if pc_style_scrolling then 
  1323. 			if not is_index_set and self.num_buttons > self.max_buttons then 
  1324. 				-- handles the case where we are entering the menu from another menu, but our current 
  1325. 				-- selection requires us to position the megalist so we can see it. 
  1326. 				local visible_end_idx = self.visible_start_idx + (self.max_buttons - 1) 
  1327. 				if self.current_idx < self.visible_start_idx then 
  1328. 					self.current_idx = self.visible_start_idx 
  1329. 				elseif self.current_idx > visible_end_idx then 
  1330. 					if( self.current_idx <= self.num_buttons )then  
  1331. 						self.visible_start_idx = self.visible_start_idx + ( self.current_idx - visible_end_idx ) 
  1332. 					else 
  1333. 						self.current_idx = visible_end_idx 
  1334. 					end 
  1335. 				end 
  1336. 				 
  1337. 				new_y = -1 * move_height * (self.visible_start_idx - 1) 
  1338. 				new_y = limit(new_y, move_height * (self.max_buttons - self.num_buttons), 0) 
  1339. 			else 
  1340. 				new_y = list_y -- Since we aren't changing anything, set the new_y to its pre-exsisting y 
  1341. 			end 
  1342. 			scrolling = false 
  1343. 		else 
  1344. 			if self.current_idx > floor(visual_center) and self.num_buttons > self.max_buttons then 
  1345. 				-- handles the case where we are entering the menu from another menu, but our current 
  1346. 				-- selection requires us to position the megalist so we can see it. 
  1347. 				new_y = -1 * move_height * (self.current_idx - floor(visual_center)) 
  1348. 				new_y = limit(new_y, move_height * (self.max_buttons - self.num_buttons), 0) 
  1349. 				scrolling = false 
  1350. 			end 
  1351. 		end 
  1352. 	else 
  1353. 		new_y = list_y 
  1354. 		scrolling = false 
  1355. 	end 
  1356. 	 
  1357. 	-- Always start a scroll animation, unless we were not told to move.  We do this to make the timing between cursor moves 
  1358. 	-- that cause a scroll and those that don't to be the same. 
  1359. 	if direction ~= 0 then 
  1360. 		--animate the list for now 
  1361. 		 
  1362. 		local toggle_group_anim = Vdo_anim_object:new("toggle_group_anim", self.handle, self.doc_handle) 
  1363. 		toggle_group_anim:set_target_handle(self.handle) 
  1364. 		local anchor_tween = Vdo_tween_object:new("toggle_group_anchor_tween", self.handle, self.doc_handle) 
  1365. 				 
  1366. 		anchor_tween:set_property("start_value", list_x, list_y ) 
  1367. 		anchor_tween:set_property("end_value", list_x, new_y ) 
  1368. 		anchor_tween:set_property("end_event", "vdo_mega_list_scroll_done") 
  1369. 		toggle_group_anim:play(0) 
  1370. 		 
  1371. 		Vdo_mega_list_tween_done = false		 
  1372. 	elseif not is_index_set then 
  1373. 		-- We are entering the menu from another menu... don't animate the position of the menu, just set it. 
  1374. 		vint_set_property(self.group_h, "anchor",  list_x, new_y) 
  1375. 	end 
  1376.  
  1377. 	--Redraw the current item range... 
  1378. 	local current_idx = self.current_idx 
  1379. 	if game_get_platform() ~= "PC" then 
  1380. 		-- Get current button 
  1381. 		self:draw_item_range(current_idx)  
  1382. 	end 
  1383. 	 
  1384. 	--Store the new y off into list_y... 
  1385. 	self.list_y = new_y 
  1386. 	 
  1387. 	local current_button = self.buttons[current_idx] 
  1388. 			 
  1389. 	-- does the button have levels 
  1390. 	--if self.data[current_idx].max_level ~= nil then 
  1391. 	--	self.button_highlight:show_extended(true) 
  1392. 						 
  1393. 		-- set color BEFORE calling set level 
  1394. 	--	self.button_highlight:set_highlight_color(self.highlight_color) 
  1395. 		 
  1396. 		-- set level info 
  1397. 	--	self.button_highlight:set_level(self.data[current_idx].max_level, self.data[current_idx].level, self.data[current_idx].is_purchased, self.data[current_idx].show_next_level)		 
  1398. 	 
  1399. 	--	self:update_extended_position( current_idx ) 
  1400. 		 
  1401. 	--else 
  1402. 		--self.button_highlight:show_extended(false) 
  1403. 	--end 
  1404. 	 
  1405. 	if self.data[self.current_idx].disabled == true then 
  1406. 		current_button:set_highlight(false) 
  1407. 		current_button:set_property("alpha", 1.0) 
  1408. 		self.highlight_on = false 
  1409. 		self:highlight_show(false) 
  1410. 	else 
  1411. 		self.highlight_on = true 
  1412. 		-- Hide new flag 
  1413. 		if self.data[self.current_idx].is_new == true then 
  1414. 			 
  1415. 			-- hide new icon 
  1416. 			current_button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NONE, BUTTON_TOGGLE_ICON_TYPE_NONE) 
  1417. 			 
  1418. 			-- Keep second icon if item is a remote objective 
  1419. 			if self.data[self.current_idx].remote_objective == true then 
  1420. 				current_button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NONE, BUTTON_TOGGLE_ICON_TYPE_QUEST_PINNED_COOP) 
  1421. 			end 
  1422. 			 
  1423. 			-- change start and end values to make the tween not pulse when highlighted 
  1424. 			current_button.new_tween:set_start_value(1) 
  1425. 			current_button.new_tween:set_end_value(1) 
  1426. 		end 
  1427. 		 
  1428. 		-- Hide dlc flag 
  1429. 		if self.data[self.current_idx].is_dlc == true then 
  1430. 			-- hide dlc icon 
  1431. 			current_button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NONE, BUTTON_TOGGLE_ICON_TYPE_NONE) 
  1432. 		end 
  1433. 				 
  1434. 		highlight:set_visible(true) 
  1435. 		 
  1436. 		-- Highlight current button 
  1437. 		current_button:set_highlight(true) 
  1438. 		current_button:set_property("depth", -10) 
  1439. 		current_button:set_property("alpha", 1.0) 
  1440. 		self.button_highlight:set_property( "depth",  -1) 
  1441. 		 
  1442. 		-- Highlight different button types... 
  1443. 		if current_button.slider then 
  1444. 			current_button.slider:set_highlight(true) 
  1445. 		elseif current_button.toggle then 
  1446. 			current_button.toggle:set_highlight(true) 
  1447. 		elseif current_button.row then 
  1448. 			current_button.row:set_highlight(true) 
  1449. 		elseif current_button.remap then 
  1450. 			current_button.remap:set_highlight_column(self.remap_column) 
  1451. 			current_button.remap:set_highlight(true) 
  1452. 			highlight:show_button("") 
  1453. 		elseif current_button.pip then 
  1454. 			current_button.pip:set_highlight(true) 
  1455. 		end 
  1456. 	end	 
  1457.  
  1458. 	--get the current highlighted button x and y 
  1459. 	button_x, button_y = current_button:get_property("anchor") 
  1460. 	button_x = self.button_x -- always make sure x is our original position set in draw items... 
  1461. 	self.button_highlight:set_property( "anchor", button_x, button_y ) 
  1462.  
  1463. 	self.button_highlight:set_width(self.width) 
  1464. 				 
  1465. 	if self.data[current_idx].type == TYPE_BUTTON or self.data[current_idx].type == nil then 
  1466. 		-- is the button locked? 
  1467. 	 
  1468. 		if self.data[current_idx].is_locked or self.data[current_idx].is_purchased or self.data[current_idx].show_button == false or self.data[current_idx].completed == true then 
  1469. 			highlight:show_button("") 
  1470. 		else 
  1471. 			highlight:show_button(CTRL_MENU_BUTTON_A) 
  1472. 		end 
  1473. 		 
  1474. 		--Marquee only supported in forced width modes... 
  1475. 		if self.force_width then 
  1476. 			--Find tweens... 
  1477. 			local marquee_anchor_twn_h = vint_object_find("marquee_anchor_twn", self.marquee_anim.handle, self.doc_handle) 
  1478. 			local marquee_end_twn_h = vint_object_find("marquee_end_twn", self.marquee_anim.handle, self.doc_handle) 
  1479. 			 
  1480. 			-- calculate text width + starting position for the button... 
  1481. 			local text_width = current_button:get_text_width() + button_x 
  1482. 			local new_x = button_x 
  1483. 			 
  1484. 			--Only marquee if we forced the width of the box and if the highlight is turned on... 
  1485. 			-- HVS_JPM lets give this a little more of a chance to marquee 
  1486. 			local was_new_buffer = 0 
  1487. 			local was_new_multiplier = 1 
  1488. 			if was_new then 
  1489. 				was_new_buffer = 25 
  1490. 				was_new_multiplier = 3 
  1491. 			end 
  1492. 			if text_width + was_new_buffer > self.width and self.highlight_on then 
  1493. 				local new_x = self.width - text_width + button_x - (MEGA_LIST_BUTTON_PADDING * was_new_multiplier) 
  1494.  
  1495. 				local marquee_mask_h = vint_object_find("mega_marquee_mask", self.handle) 
  1496. 				local marquee_mask_pos_x, marquee_mask_pos_y = vint_get_property(marquee_mask_h, "anchor") 
  1497.  
  1498. 				local show_button = false 
  1499. 				local icon_h = vint_object_find("icon", self.button_highlight.handle) 
  1500. 				show_button = vint_get_property(icon_h, "visible") 
  1501.  
  1502. 				if show_button then -- the hint icon is showing 
  1503. 					vint_set_property(marquee_mask_h, "anchor", 47, marquee_mask_pos_y) -- hardcoded 47 from messing in Vinny, hacky but w/e 
  1504. 				else -- the icon is not showing 
  1505. 					vint_set_property(marquee_mask_h, "anchor", 30, marquee_mask_pos_y) -- hacky grabbed # from Vinny, w/e 
  1506. 				end 
  1507.  
  1508. 				--Retarget to current button 
  1509. 				vint_set_property(marquee_anchor_twn_h, "target_handle", current_button.handle) 
  1510. 				vint_set_property(marquee_end_twn_h, "target_handle",  current_button.handle) 
  1511. 				 
  1512. 				--Now set start and end values... 
  1513. 				vint_set_property(marquee_anchor_twn_h, "start_value", button_x, button_y) 
  1514. 				vint_set_property(marquee_anchor_twn_h, "end_value", new_x, button_y) 
  1515. 				 
  1516. 				local duration = abs(new_x - button_x)/60 
  1517. 				vint_set_property(marquee_anchor_twn_h, "duration", duration) 
  1518. 				vint_set_property(marquee_end_twn_h, "start_time", duration + 2.75) 
  1519. 				 
  1520. 				--play animation 
  1521. 				lua_play_anim(self.marquee_anim.handle) 
  1522. 				self.marquee_is_on = true 
  1523. 			else 
  1524. 				vint_set_property(self.marquee_anim.handle, "is_paused", true) 
  1525. 				self.marquee_is_on = false 
  1526. 			end 
  1527. 		end 
  1528. 		 
  1529. 		if self.input_tracker then 
  1530. 			self.input_tracker:highspeed_left_right(false) 
  1531. 		end 
  1532. 	elseif self.data[current_idx].type == TYPE_SLIDER then 
  1533. 		highlight:show_button("") 
  1534. 		 
  1535. 		if Game_platform == "PC" then 
  1536. 			self:update_toggle_mouse_inputs() 
  1537. 		end 
  1538. 		 
  1539. 		if self.input_tracker then 
  1540. 			self.input_tracker:highspeed_left_right(true) 
  1541. 		end	 
  1542. 	elseif self.data[current_idx].type == TYPE_TOGGLE then 
  1543. 		highlight:show_button("") 
  1544. 				 
  1545. 		if Game_platform == "PC" then 
  1546. 			self:update_toggle_mouse_inputs() 
  1547. 		end 
  1548. 		 
  1549. 		if self.input_tracker then 
  1550. 			self.input_tracker:highspeed_left_right(false) 
  1551. 		end 
  1552. 	elseif self.data[current_idx].type == TYPE_ROW then 
  1553. 		if self.data[current_idx].show_button == false then 
  1554. 			highlight:show_button("") 
  1555. 		else 
  1556. 			highlight:show_button(CTRL_MENU_BUTTON_A) 
  1557. 		end 
  1558. 		 
  1559. 		if self.input_tracker then 
  1560. 			self.input_tracker:highspeed_left_right(false) 
  1561. 		end 
  1562. 	end 
  1563. 	 
  1564. 	-- Clear out the old highlighted colors on buttons... 
  1565. 	for idx, button in pairs(self.buttons) do 
  1566. 		if idx ~= self.current_idx then 
  1567. 			button:set_highlight(false) 
  1568. 			button:set_property("depth", 0) 
  1569. 			button:set_property("alpha", 1) 
  1570. 			local button_x, button_y = button:get_anchor() 
  1571. 			 
  1572. 			--reset x position of button... 
  1573. 			button:set_anchor(self.button_x, button_y) 
  1574. 			 
  1575. 			--Unhighlight different button types... 
  1576. 			if button.slider then 
  1577. 				button.slider:set_highlight(false) 
  1578. 			elseif button.toggle then 
  1579. 				button.toggle:set_highlight(false) 
  1580. 			elseif button.row then 
  1581. 				button.row:set_highlight(false) 
  1582. 			elseif button.remap then 
  1583. 				button.remap:set_highlight(false) 
  1584. 			elseif button.pip then 
  1585. 				button.pip:set_highlight(false) 
  1586. 			end 
  1587. 		 
  1588. 			-- reneable new tween 
  1589. 			if self.data[idx].is_new == true then 
  1590. 				 
  1591. 				-- set new icon back 
  1592. 				if self.data[idx].is_element == true then  
  1593. 					button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NEW, BUTTON_TOGGLE_ICON_TYPE_BOX) 
  1594. 				elseif self.data[idx].remote_objective == true then 
  1595. 					button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NEW, BUTTON_TOGGLE_ICON_TYPE_QUEST_PINNED_COOP) 
  1596. 				else 
  1597. 					button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NEW, BUTTON_TOGGLE_ICON_TYPE_NONE) 
  1598. 				end 
  1599. 				 
  1600. 				-- change start and end values to make the tween pulse when highlighted 
  1601. 				button.new_tween:set_start_value(0.6) 
  1602. 				button.new_tween:set_end_value(1) 
  1603. 			end 
  1604.  
  1605. 			-- renedable dlc 
  1606. 			if self.data[idx].is_dlc == true then 
  1607. 				-- set new icon back 
  1608. 				button:set_icon(BUTTON_TOGGLE_ICON_TYPE_DLC, BUTTON_TOGGLE_ICON_TYPE_NONE) 
  1609. 			end 
  1610. 		end 
  1611. 		 
  1612. 		if self.data[idx].is_dlc2 == true and self.data[idx].quest_pinned == false then 
  1613. 				button:set_icon(BUTTON_TOGGLE_ICON_TYPE_NONE, BUTTON_TOGGLE_ICON_TYPE_DLC) 
  1614. 		end 
  1615. 	end	 
  1616. 	 
  1617. 	--handle the scrollbar tab position 
  1618. 	if Game_platform == "PC" then 
  1619. 		self.scrollbar:set_value( self.num_buttons - (self.max_buttons - 1), self.visible_start_idx, scrolling == false ) 
  1620. 	else 
  1621. 		self.scrollbar:set_value( total_buttons, current_idx, scrolling == false ) 
  1622. 	end 
  1623. 	 
  1624. 	--check if we should play scrolling audio 
  1625. 	if (direction ~= 0 or is_index_set) and play_move_cursor_audio == true then 
  1626. 		if self.num_buttons > 1 then 
  1627. 			game_UI_audio_play("UI_Reward_Store_Menu_Navigation") 
  1628. 		end 
  1629. 	end 
  1630. end 
  1631.  
  1632. function Vdo_mega_list:move_slider(direction, mouse_x, kill_audio) 
  1633. 	if not self.draw_called then 
  1634. 		debug_print("vint", "Vdo_pause_mega_list:move_slider called with invalid document handle\n") 
  1635. 		return 
  1636. 	end 
  1637.  
  1638. 	--get the button handle 
  1639. 	local current_idx = self.current_idx 
  1640. 	--check to see if we have a slider 
  1641.  
  1642. 	-- don't allow move if it's disabled 
  1643. 	if self.data[current_idx].disabled == true then 
  1644. 		return 
  1645. 	end 
  1646. 	 
  1647. 	if self.data[current_idx].type == TYPE_SLIDER then 
  1648. 		--Get the button handle 
  1649. 		local current_idx = self.current_idx 
  1650. 		local current_value = self.data[current_idx].current_value 
  1651. 		local current_max = self.data[current_idx].max 
  1652. 		local current_min = self.data[current_idx].min 
  1653. 		local current_step = self.data[current_idx].step 
  1654. 		local current_display = self.data[current_idx].display 
  1655. 		local current_mapping = self.data[current_idx].mapping 
  1656. 		local old_value = current_value 
  1657.  
  1658. 		if mouse_x ~= nil then 
  1659. 			if self.slider_hitboxes == nil then 
  1660. 				return 
  1661. 			end 
  1662. 			 
  1663. 			-- Get the hitbox of the slider that we care about 
  1664. 			local slider_hitbox 
  1665. 			for idx, hitbox in pairs(self.slider_hitboxes) do 
  1666. 				if hitbox.idx == current_idx then 
  1667. 					slider_hitbox = hitbox 
  1668. 				end 
  1669. 			end 
  1670. 			 
  1671. 			local slider_x, slider_y = vint_get_global_anchor(slider_hitbox.handle, self.doc_handle) 
  1672. 			local slider_width = element_get_actual_size(slider_hitbox.handle) 
  1673. 			 
  1674. 			-- Adjust the mouse position into the proper space. 
  1675. 			local screen_w, screen_h = vint_get_screen_size() 
  1676. 			if vint_is_std_res() then 
  1677. 				local doc_width = screen_h * 4 / 3 
  1678. 				local offset = (doc_width - screen_w) / 2 
  1679. 				mouse_x = ((mouse_x + offset) * 640 / doc_width) 
  1680. 				slider_width = slider_width * (0.666667) 
  1681. 			else  
  1682. 				local doc_width = screen_h * 16 / 9 
  1683. 				local offset = (doc_width - screen_w) / 2 
  1684. 				mouse_x = ((mouse_x + offset) * 1280 / doc_width) 
  1685. 			end 
  1686. 			 
  1687. 			-- The actual area of the slider that we care about is smaller than the bounding box 
  1688. 			local SIDE_OFFSET = 15 
  1689. 			local min_x = slider_x + SIDE_OFFSET 
  1690. 			local max_x = slider_x + slider_width - SIDE_OFFSET 
  1691. 			 
  1692. 			current_value = ((mouse_x - min_x) / (max_x - min_x)) * (current_max - current_min) + current_min 
  1693. 			 
  1694. 			-- For sliders with a max of 1 (or less), these are mapped to 100 times their value internally, so rounding is trickier 
  1695. 			if current_min < 1 and current_max <= 1 then 
  1696. 				current_value = floor((current_value * 100) + 0.5) -- 0.5 is for better rounding 
  1697. 				current_value = current_value * 0.01 
  1698. 			else		 
  1699. 				-- Round it off 
  1700. 				current_value = floor(current_value + 0.5) -- 0.5 is for better rounding 
  1701. 			end 
  1702. 		else 
  1703. 			-- Increment the value 
  1704. 			current_value = current_value + ( current_step * direction ) 
  1705. 		end 
  1706. 		 
  1707. 		-- Clamp the slider if necessary 
  1708. 		if current_value > current_max then 
  1709. 			current_value = current_max 
  1710. 		elseif current_value < current_min then 
  1711. 			current_value = current_min 
  1712. 		elseif kill_audio ~= true then 
  1713. 			if direction == 1 then 
  1714. 				game_UI_audio_play("UI_Main_Menu_Nav_Right") 
  1715. 			else 
  1716. 				game_UI_audio_play("UI_Main_Menu_Nav_Left") 
  1717. 			end 
  1718. 		end 
  1719. 		 
  1720. 		--Set the slider value 
  1721. 		self.buttons[current_idx].slider:set_value(current_value, current_min, current_max, nil, current_mapping ) 
  1722.  
  1723. 		--Store the current value in the table 
  1724. 		self.data[current_idx].current_value = current_value 
  1725. 		 
  1726. 		-- Add back in when fixed in wise 
  1727. 		--game_UI_audio_play("UI_Customization_Slider") 
  1728. 		 
  1729. 		-- Return true if it changed 
  1730. 		local changed = (old_value ~= current_value) 
  1731. 		old_value = current_value 
  1732. 		return changed 
  1733. 	elseif self.data[current_idx].type == TYPE_TOGGLE then 
  1734. 		local toggle = self.buttons[current_idx].toggle 
  1735. 		local current_value = self.data[current_idx].current_value 
  1736. 		local options = self.data[current_idx].options 
  1737. 		 
  1738. 		local new_value = current_value + direction 
  1739. 		local num_options = #options 
  1740. 		 
  1741. 		if new_value > num_options then 
  1742. 			new_value = 1 
  1743. 		elseif new_value < 1 then 
  1744. 			new_value = num_options 
  1745. 		end 
  1746. 		 
  1747. 		if num_options > 1 then 
  1748. 			game_UI_audio_play("UI_Reward_Store_Menu_Navigation") 
  1749. 		end 
  1750.  
  1751. 		--Set label... 
  1752. 		local val_label = options[new_value] 
  1753. 		toggle:set_value(val_label) 
  1754. 		 
  1755. 		self.data[current_idx].current_value = new_value 
  1756. 	elseif self.data[current_idx].type == TYPE_REMAP then 
  1757. 		--Toggle between the two columns 
  1758. 		if self.remap_column == 1 then 
  1759. 			self.remap_column = 2 
  1760. 		else 
  1761. 			self.remap_column = 1 
  1762. 		end 
  1763. 		self.buttons[current_idx].remap:set_highlight_column(self.remap_column) 
  1764. 	end 
  1765. end 
  1766.  
  1767. function Vdo_mega_list:get_selection() 
  1768. 	if not self.draw_called then 
  1769. 		debug_print("vint", "Vdo_mega_list:get_selection called with invalid document handle\n") 
  1770. 		return 
  1771. 	end 
  1772.  
  1773. 	return self.current_idx 
  1774. end 
  1775.  
  1776. ------------------------------------------------------------------------------- 
  1777. -- Returns the value of a toggle... 
  1778. -- 
  1779. function Vdo_mega_list:get_toggle_selection() 
  1780. 	if not self.draw_called then 
  1781. 		debug_print("vint", "Vdo_mega_list:get_toggle_selection called with invalid document handle\n") 
  1782. 		return 
  1783. 	end 
  1784. 	 
  1785. 	local selected_option = self.data[self.current_idx] 
  1786. 	if selected_option.type == TYPE_TOGGLE then 
  1787. 		return selected_option.current_value  
  1788. 	end 
  1789. 	 
  1790. 	-- Spit back out the current highlight position 
  1791. 	return 0 
  1792. end 
  1793.  
  1794. -- Gets an optional ID value if one is saved 
  1795. function Vdo_mega_list:get_id() 
  1796. 	if not self.draw_called then 
  1797. 		debug_print("vint", "Vdo_mega_list:get_toggle_selection called with invalid document handle\n") 
  1798. 		return 
  1799. 	end 
  1800. 	 
  1801. 	return self.data[self.current_idx].id 
  1802. end 
  1803.  
  1804. function Vdo_mega_list:get_data_from_id(id) 
  1805. 	for i, entry in pairs (self.data) do 
  1806. 		if entry.id == id then 
  1807. 			return entry 
  1808. 		end 
  1809. 	end 
  1810. end 
  1811.  
  1812. ------------------------------------------------------------------------------- 
  1813. -- Returns index from id 
  1814. -- 
  1815. function Vdo_mega_list:get_index_from_id(id) 
  1816. 	if self.data == nil then 
  1817. 		return 
  1818. 	end 
  1819. 	for index, entry in pairs (self.data) do 
  1820. 		-- Skip the non-scalar field. 
  1821. 		if type(index) == "number" then 
  1822. 			if entry.id == id then 
  1823. 				return index 
  1824. 			end 
  1825. 		end 
  1826. 	end 
  1827. 	return -1 
  1828. end 
  1829.  
  1830. function Vdo_mega_list:button_a() 
  1831. 	if not self.draw_called then 
  1832. 		debug_print("vint", "Vdo_mega_list:button_a called with invalid document handle\n") 
  1833. 		return 
  1834. 	end 
  1835. 	 
  1836. 	local current_idx = self.current_idx 
  1837. 	if self.data[current_idx].type == TYPE_BUTTON or self.data[current_idx].type == nil then 
  1838. 		debug_print("vint", "BUTTON SELECTED GO TO A SCREEN OR SOMETHING\n") 
  1839. 	end 
  1840.  
  1841. 	if self.data[current_idx].type == TYPE_TOGGLE then 
  1842. 		local num_options = #(self.data[current_idx].options) 
  1843. 		if num_options <= 1 then 
  1844. 			debug_print("vint", "Vdo_mega_list:We have one or no options, no need to open toggle") 
  1845. 			return 
  1846. 		end 
  1847. 	end 
  1848. 	 
  1849. 	--check if we can process input 
  1850. 	if not Vdo_mega_list_tween_done then 
  1851. 		return 
  1852. 	end 
  1853. 	 
  1854. 	-- SEH - we don't want to handle A button with sliders 
  1855. 	if self.data[current_idx].type == TYPE_SLIDER or self.data[current_idx].type == TYPE_TOGGLE  then		 
  1856. 		return 
  1857. 	end 
  1858. 	 
  1859. 	local current_button = self.buttons[current_idx] 
  1860. 	 
  1861. 	if self.data[current_idx].type == TYPE_REMAP then 
  1862. 		-- Show popup message for remapping buttons 
  1863. 		-- Make current selection flash a "?" 
  1864. 		current_button.remap:wait_for_key(current_idx, self.remap_column) 
  1865. 		return 
  1866. 	end 
  1867.  
  1868. 	-- Unhighlight current button	 
  1869. 	self:highlight_show(false) 
  1870. end 
  1871.  
  1872. function Vdo_mega_list:button_b() 
  1873. 	if not self.draw_called then 
  1874. 		debug_print("vint", "Vdo_mega_list:button_b called with invalid document handle\n") 
  1875. 		return 
  1876. 	end 
  1877. end 
  1878.  
  1879.  
  1880. function Vdo_mega_list:return_data() 
  1881. 	if not self.draw_called then 
  1882. 		debug_print("vint", "Vdo_mega_list:return_data called with invalid document handle\n") 
  1883. 		return 
  1884. 	end 
  1885. 	 
  1886. 	return self.data 
  1887. end 
  1888.  
  1889. function Vdo_mega_list:return_selected_data() 
  1890. 	if not self.draw_called then 
  1891. 		debug_print("vint", "Vdo_mega_list:return_selected_data called with invalid document handle\n") 
  1892. 		return 
  1893. 	end 
  1894. 	 
  1895. 	return self.data[self.current_idx] 
  1896. end 
  1897.  
  1898. function Vdo_mega_list:enable(state) 
  1899. 	if not self.draw_called then 
  1900. 		debug_print("vint", "Vdo_mega_list:enable called with invalid document handle\n") 
  1901. 		return 
  1902. 	end 
  1903. 	 
  1904. 	local current_idx = self.current_idx 
  1905. 	 
  1906. 	for idx, button in pairs(self.buttons) do 
  1907. 		button:set_enabled(state) 
  1908. 	end 
  1909. 	 
  1910. 	local current_button = self.buttons[current_idx] 
  1911. 	 
  1912. 	-- Highlight/unhighlight current button 
  1913. 	current_button:set_highlight(state) 
  1914. 	current_button:set_enabled(state)		 
  1915. end 
  1916.  
  1917. function Vdo_mega_list:toggle_highlight(is_on) 
  1918. 	if not self.draw_called then 
  1919. 		debug_print("vint", "Vdo_mega_list:toggle_highlight called with invalid document handle\n") 
  1920. 		return 
  1921. 	end 
  1922.  
  1923. 	self.button_highlight:set_property("visible", is_on) 
  1924. 	 
  1925. 	if is_on == false then 
  1926. 		if self.marquee_anim == nil then 
  1927. 			self.marquee_anim = Vdo_anim_object:new("marquee_anim", self.handle, self.doc_handle) 
  1928. 		end 
  1929. 		--pause marquee if there is no highlight... 
  1930. 		vint_set_property(self.marquee_anim.handle, "is_paused", true) 
  1931. 		 
  1932. 		--reset button position and alpha. 
  1933. 		local current_button = self.buttons[self.current_idx] 
  1934. 		local button_x, button_y = current_button:get_anchor() 
  1935. 		current_button:set_anchor(self.button_x, button_y) 
  1936. 		current_button:set_alpha(1) 
  1937. 	else  
  1938. 		--only turn the marquee on if we had one playing before... 
  1939. 		if self.marquee_is_on then 
  1940. 			lua_play_anim(self.marquee_anim.handle) 
  1941. 		end 
  1942. 	end 
  1943. 	 
  1944. 	local current_idx = self.current_idx 
  1945. 	 
  1946. 	for idx, button in pairs(self.buttons) do 
  1947. 		button:set_highlight(false) 
  1948. 	end 
  1949. 	 
  1950. 	self.buttons[current_idx]:set_highlight(is_on) 
  1951. 	self.highlight_on = is_on 
  1952. end 
  1953.  
  1954. function Vdo_mega_list:set_highlight_color(color, non_highlight_color) 
  1955. 	 
  1956. 	self.button_highlight:set_highlight_color(color) 
  1957. 	self.scrollbar:set_highlight_color(color) 
  1958. 	 
  1959. 	self.highlight_color = color 
  1960. 	self.non_highlight_color = non_highlight_color 
  1961. end 
  1962.  
  1963. --Shows the current highlight, 
  1964. --used to toggle the options on or off... 
  1965. function Vdo_mega_list:highlight_show(visible) 
  1966. 	local current_idx = self.current_idx 
  1967. 	local current_button = self.buttons[current_idx] 
  1968. 	current_button:set_highlight(visible) 
  1969. 	self.button_highlight:set_visible(visible) 
  1970. 	 
  1971. 	-- Highlight different button types... 
  1972. 	if current_button.slider then 
  1973. 		current_button.slider:set_highlight(visible) 
  1974. 	elseif current_button.toggle then 
  1975. 		current_button.toggle:set_highlight(visible) 
  1976. 	elseif current_button.remap then 
  1977. 		current_button.remap:set_highlight_column(self.remap_column) 
  1978. 		current_button.remap:set_highlight(visible) 
  1979. 		highlight:show_button("") 
  1980. 	end	 
  1981. end 
  1982.  
  1983. function Vdo_mega_list:highlight_set_button(button_img, override_show) 
  1984. 	self.button_highlight:show_button(button_img, override_show) 
  1985. end 
  1986.  
  1987. function Vdo_mega_list:refresh_values(data) 
  1988. 	if not self.draw_called then 
  1989. 		debug_print("vint", "Vdo_mega_list:refresh_values called with invalid document handle\n") 
  1990. 		return 
  1991. 	end 
  1992. 	 
  1993. 	for idx = 1,#data do 
  1994. 		--store the button toggle options 
  1995. 		if data[idx].type == TYPE_BUTTON or data[idx].type == nil then 
  1996. 			-- Set the button toggle value 
  1997. 			self.buttons[idx]:set_value("") 
  1998. 		elseif data[idx].type == TYPE_TOGGLE then 
  1999. 			--Store the value 
  2000. 			local option_idx = data[idx].current_value 
  2001. 			-- Set the button toggle value 
  2002. 			self.buttons[idx]:set_value(data[idx].options[option_idx]) 
  2003. 		elseif data[idx].type == TYPE_SLIDER then 
  2004. 			-- Set the button toggle value 
  2005. 			--self.buttons[idx]:set_value(data[idx].current_value) 
  2006. 			self.buttons[idx]:set_value("") 
  2007. 		end 
  2008. 	end 
  2009. end 
  2010.  
  2011. function Vdo_mega_list:is_tween_done() 
  2012. 	return Vdo_mega_list_tween_done 
  2013. end 
  2014.  
  2015. function Vdo_mega_list:return_size() 
  2016.  
  2017. 	--TODO: THIS IS COMPLETELY INCORRECT... it will return the size of the entire list unculled... 
  2018. 	local total_height = #data * (LIST_BUTTON_HEIGHT  +MEGA_LIST_BUTTON_SPACING) 
  2019. 	return self.width, total_height 
  2020. end 
  2021.  
  2022. --Returns width and height of megalist... corner to corner. includes scrollbar... 
  2023. --TODO: update this... to return proper width... 
  2024. function Vdo_mega_list:get_size() 
  2025. 	if self.width == 0 then 
  2026. 		return 
  2027. 	end 
  2028. 	 
  2029. 	--Scrollbar is always part of the width 
  2030. 	local width = self.width + SCROLLBAR_WIDTH + MEGALIST_SCROLLBAR_PADDING 
  2031. 	 
  2032. 	--Height 
  2033. 	local height = self.max_buttons * (LIST_BUTTON_HEIGHT + MEGA_LIST_BUTTON_SPACING ) 
  2034. 	return width, height 
  2035. end 
  2036.  
  2037. function Vdo_mega_list:set_selection(new_index) 
  2038. 	if self.data[self.current_idx].disabled == true or self.intro_anim_is_playing then 
  2039. 		return 
  2040. 	end 
  2041. 	 
  2042. 	self.current_idx = new_index 
  2043. end 
  2044.  
  2045.  
  2046. --Anim in is complete 
  2047. function Vdo_mega_list:intro_anim_cb() 
  2048. 	self.intro_twn_counter = 0 
  2049. 	self.intro_anim_is_playing = false 
  2050. end 
  2051.  
  2052.  
  2053. --Is the list still animating? 
  2054. function Vdo_mega_list:list_is_playing() 
  2055. 	return self.intro_anim_is_playing 
  2056. end 
  2057.  
  2058.  
  2059. -- loops the marquee animation via callback 
  2060. function Vdo_mega_list:marquee_loop_cb() 
  2061. 	lua_play_anim(self.marquee_anim.handle) 
  2062. end 
  2063.  
  2064.  
  2065. -- stop marquee animation 
  2066. function Vdo_mega_list:stop_marquee() 
  2067. 	 
  2068. 	--Only stop if we're currently playing 
  2069. 	if self.marquee_is_on == true then 
  2070. 		 
  2071. 		--pause animation 
  2072. 		vint_set_property(self.marquee_anim.handle, "is_paused", true) 
  2073. 		 
  2074. 		--reset button position and alpha. 
  2075. 		local current_button = self.buttons[self.current_idx] 
  2076. 		local button_x, button_y = current_button:get_anchor() 
  2077. 		current_button:set_anchor(self.button_x, button_y) 
  2078. 		current_button:set_alpha(1) 
  2079. 		 
  2080. 		self.marquee_is_on = false 
  2081. 	end	 
  2082. end 
  2083.  
  2084.  
  2085. function Vdo_mega_list:remove_new_flag(idx, super_special_case) 
  2086. 	if not self.draw_called then 
  2087. 		return 
  2088. 	end 
  2089. 	if self.data == nil then 
  2090. 		return 
  2091. 	end 
  2092. 	if self.data[idx] == nil then 
  2093. 		return 
  2094. 	end 
  2095. 	--remove new flag 
  2096. 	if self.data[idx].is_new then 
  2097. 		self.data[idx].is_new = false 
  2098. 		self:cleanup_single_item(self.buttons[idx]) 
  2099. 		if super_special_case then 
  2100. 			self.buttons[idx] = self:draw_single_item(idx, false, true) 
  2101. 		else 
  2102. 			self.buttons[idx] = self:draw_single_item(idx, false) 
  2103. 		end 
  2104. 	end 
  2105. end 
  2106.  
  2107. function Vdo_mega_list:refresh_single_item(idx) 
  2108. 	if not self.draw_called then 
  2109. 		return 
  2110. 	end 
  2111. 	if self.data == nil then 
  2112. 		return 
  2113. 	end 
  2114. 	if self.data[idx] == nil then 
  2115. 		return 
  2116. 	end 
  2117. 	 
  2118. 	--updates a specific item... 
  2119. 	self:cleanup_single_item(self.buttons[idx]) 
  2120. 	self.buttons[idx] = self:draw_single_item(idx, false) 
  2121. 	 
  2122. 	debug_print("vint", "refresh_single_item move cursor :::: 0\n") 
  2123. 	self:move_cursor(0) 
  2124. end 
  2125.  
  2126.  
  2127. -- ===================================== 
  2128. --       Mouse Specific Functions 
  2129. -- ===================================== 
  2130.  
  2131. function Vdo_mega_list:get_visible_indices() 
  2132. 	local visible_end_idx 
  2133. 	if self.num_buttons > self.max_buttons then 
  2134. 		visible_end_idx = self.visible_start_idx + (self.max_buttons - 1) 
  2135. 	else 
  2136. 		visible_end_idx = self.num_buttons 
  2137. 	end 
  2138. 	 
  2139. 	return self.visible_start_idx, visible_end_idx 
  2140. end 
  2141.  
  2142. -- Returns the button's index on the list based on the target handle. 
  2143. -- Returns 0 (invalid index) if no button was found 
  2144. -- 
  2145. function Vdo_mega_list:get_button_index(target_handle) 
  2146. 	if self.buttons == nil then 
  2147. 		return 0 
  2148. 	end 
  2149. 	 
  2150. 	for idx, button in pairs(self.buttons) do 
  2151. 		if self.data[idx].disabled ~= true and button.wide_handle ~= nil then 
  2152. 			if button.wide_handle == target_handle then 
  2153. 				return idx 
  2154. 			end 
  2155. 		end 
  2156. 	end 
  2157.  
  2158. 	-- Check the slider hitboxes 
  2159. 	if self.slider_hitboxes == nil then 
  2160. 		return 0 
  2161. 	end 
  2162. 	 
  2163. 	for idx, slider_hitbox in pairs(self.slider_hitboxes) do 
  2164. 		if slider_hitbox.handle == target_handle then 
  2165. 			return slider_hitbox.idx 
  2166. 		end 
  2167. 	end 
  2168.  
  2169. 	-- If no matching target handle was found, return an invalid index 
  2170. 	return 0 
  2171. end 
  2172.  
  2173. function Vdo_mega_list:get_remap_index(target_handle) 
  2174. 	local column = 0 
  2175. 	for i = 1, self.num_buttons do 
  2176. 		if self.buttons[i].remap ~= nil then 
  2177. 			column = self.buttons[i].remap:get_target_column(target_handle) 
  2178. 			if column > 0 then 
  2179. 				self.remap_column = column 
  2180. 				return i, self.buttons[i].remap, column 
  2181. 			end 
  2182. 		end 
  2183. 	end 
  2184. 	 
  2185. 	return 0, nil, 0 
  2186. end 
  2187.  
  2188. function Vdo_mega_list:get_scroll_region_handle() 
  2189. 	return self.clip_h 
  2190. end 
  2191.  
  2192. -- This is needed for the store UI screens, since each store should handle the 
  2193. -- mouse_move events itself, not through the store_common script 
  2194. -- 
  2195. function Vdo_mega_list:set_store(store_name) 
  2196. 	if store_name ~= nil then 
  2197. 		self.store_name = store_name 
  2198. 	end 
  2199. end 
  2200.  
  2201. -- callback_nav and callback_action are optional overrides (func_prefix is ignored if they are used) 
  2202. function Vdo_mega_list:add_mouse_inputs(func_prefix, input_tracker, priority, callback_nav, callback_action, mouse_depth, right_click_enabled) 
  2203. 	if (self.buttons == nil) or (func_prefix == nil) or (input_tracker == nil) then 
  2204. 		return 
  2205. 	end 
  2206. 	 
  2207. 	mouse_depth = mouse_depth or 5000 
  2208. 	 
  2209. 	-- Default priority value to 50 
  2210. 	self.priority = priority or 50 
  2211. 	 
  2212. 	if self.store_name == nil then 
  2213. 		self.mouse_move_function			= callback_nav or func_prefix.."_mouse_move" 
  2214. 	else 
  2215. 		self.mouse_move_function			= self.store_name.."_mouse_move" 
  2216. 	end 
  2217. 	self.mouse_click_function				= callback_action or func_prefix.."_mouse_click" 
  2218. 	self.mouse_right_click_function		= callback_action or func_prefix.."_mouse_right_click" 
  2219. 	local mouse_drag_function				= func_prefix.."_mouse_drag" 
  2220. 	local mouse_drag_release_function	= func_prefix.."_mouse_drag_release" 
  2221. 	 
  2222. 	local visible_end_idx = self.num_buttons 
  2223. 	if self.num_buttons > self.max_buttons then 
  2224. 		visible_end_idx = self.visible_start_idx + (self.max_buttons - 1) 
  2225. 	end 
  2226. 	 
  2227. 	-- Clear out the old slider hitboxes 
  2228. 	if self.slider_hitboxes ~= nil then 
  2229. 		for idx, slider_hitbox in pairs(self.slider_hitboxes) do 
  2230. 			vint_object_destroy(slider_hitbox.handle) 
  2231. 		end 
  2232. 	end 
  2233. 	self.slider_hitboxes = {} 
  2234. 	 
  2235. 	-- Clear out old wide hitboxes 
  2236. 	if self.wide_hitboxes ~= nil then 
  2237. 		for idx, wide_hitbox in pairs(self.wide_hitboxes) do 
  2238. 			vint_object_destroy(wide_hitbox.handle) 
  2239. 		end 
  2240. 	end 
  2241. 	self.wide_hitboxes = {} 
  2242. 	 
  2243. 	 
  2244. 	-- Add mouse_click and mouse_move events for each button in the list 
  2245. 	for idx = self.visible_start_idx, visible_end_idx do 
  2246. 		-- Create a hitbox based on the button 
  2247. 		local move_height = LIST_BUTTON_HEIGHT + MEGA_LIST_BUTTON_SPACING	 
  2248. 		local list_y = -1 * move_height * (self.visible_start_idx - 1) 
  2249. 		local button_x, button_y = vint_get_property(self.buttons[idx].handle, "anchor") 
  2250. 		 
  2251. 		if self.buttons[idx].handle ~= 0 then 
  2252. 			local wide_index = #self.wide_hitboxes + 1 
  2253. 			local wide_name = "wide_hitbox"..wide_index 
  2254. 			local wide_handle = vint_object_create(wide_name, "bitmap", self.handle) 
  2255. 			 
  2256. 			self.wide_hitboxes[wide_index] = {} 
  2257. 			self.wide_hitboxes[wide_index].handle = wide_handle 
  2258. 			self.wide_hitboxes[wide_index].idx = idx 
  2259. 			vint_set_property(wide_handle, "auto_offset", "w") 
  2260. 			vint_set_property(wide_handle, "visible", false) 
  2261. 			vint_set_property(wide_handle, "depth", 100) 
  2262. 			 
  2263. 			element_set_actual_size(wide_handle, self.width, LIST_BUTTON_HEIGHT - 2) 
  2264. 			 
  2265. 			--JAM and JMH:  Hardcoding button x to deal with intro tween.  Fixing issue with first wide hitbox being positioned outside of clip region.			 
  2266. 			--vint_set_property(wide_handle, "anchor", button_x + WIDE_HITBOX_OFFSET, button_y + list_y) 
  2267. 			vint_set_property(wide_handle, "anchor", 0, button_y + list_y) 
  2268. 			 
  2269. 			vint_set_property(wide_handle, "mouse_depth", mouse_depth) 
  2270. 			self.buttons[idx].wide_handle = wide_handle 
  2271. 		 
  2272. 			-- Everything highlights based on the wide hitbox, while each type has different click functionality (or not) 
  2273. 			input_tracker:add_mouse_input("mouse_move", self.mouse_move_function, self.priority, wide_handle) 
  2274. 			 
  2275. 			if self.data[idx].type == TYPE_BUTTON or self.data[idx].type == TYPE_ROW or self.data[idx].type == TYPE_TOGGLE_COLOR or self.data[idx].type == nil then 
  2276. 				input_tracker:add_mouse_input("mouse_click", self.mouse_click_function, self.priority, wide_handle) 
  2277. 				if right_click_enabled then 
  2278. 					input_tracker:add_mouse_input("mouse_right_click", self.mouse_right_click_function, self.priority, wide_handle) 
  2279. 				end 
  2280. 				 
  2281. 				 
  2282. 			elseif self.data[idx].type == TYPE_PIP or self.data[idx].type == TYPE_TOGGLE then 
  2283. 				-- Add hitbox for the whole button, plus the left arrow 
  2284. 				input_tracker:add_mouse_input("mouse_click", self.mouse_click_function, self.priority, wide_handle) 
  2285. 				 
  2286. 			elseif self.data[idx].type == TYPE_SLIDER then	 
  2287. 				-- If the button is a slider, then create a hitbox for the slider from scratch 
  2288. 				local move_height = LIST_BUTTON_HEIGHT + MEGA_LIST_BUTTON_SPACING	 
  2289. 				local list_y = -1 * move_height * (self.visible_start_idx - 1) 
  2290. 				local slider_bg_handle = vint_object_find("slider_bg", self.buttons[idx].slider.handle) 
  2291. 				local slider_bg_w, slider_bg_h = element_get_actual_size(slider_bg_handle) --vint_get_property(slider_bg_handle, "screen_size") 
  2292. 				local slider_bg_x, slider_bg_y = vint_get_property(slider_bg_handle, "anchor") 
  2293. 				local slider_x, slider_y = vint_get_property(self.buttons[idx].slider.handle, "anchor") 
  2294. 				 
  2295. 				local hitbox_index = #self.slider_hitboxes + 1 
  2296. 				local hitbox_name = "slider_hitbox"..hitbox_index 
  2297. 				local hitbox_handle = vint_object_create(hitbox_name, "bitmap", self.handle) 
  2298. 				 
  2299. 				self.slider_hitboxes[hitbox_index] = {} 
  2300. 				self.slider_hitboxes[hitbox_index].handle = hitbox_handle 
  2301. 				self.slider_hitboxes[hitbox_index].idx = idx 
  2302. 				vint_set_property(hitbox_handle, "visible", false) 
  2303. 				vint_set_property(hitbox_handle, "depth", -20) 
  2304. 				element_set_actual_size(hitbox_handle, slider_bg_w, slider_bg_h - 7) 
  2305. 			 
  2306. 				vint_set_property(hitbox_handle, "anchor", slider_x + slider_bg_x, slider_y - 12 + list_y) 
  2307. 				 
  2308. 				-- Finally add in the mouse input tracking for the sliders 
  2309. 				input_tracker:add_mouse_input("mouse_click", self.mouse_click_function, self.priority, hitbox_handle) 
  2310. 				input_tracker:add_mouse_input("mouse_move", self.mouse_move_function, self.priority, hitbox_handle) 
  2311. 				input_tracker:add_mouse_input("mouse_drag", mouse_drag_function, self.priority, hitbox_handle) 
  2312. 				input_tracker:add_mouse_input("mouse_drag_release", mouse_drag_release_function, self.priority, hitbox_handle) 
  2313. 				vint_set_property(hitbox_handle, "mouse_depth", mouse_depth) 
  2314. 				 
  2315. 			elseif self.data[idx].type == TYPE_REMAP then 
  2316. 				-- Two addition mouse moves/clicks for remapping buttons 
  2317. 				input_tracker:add_mouse_input("mouse_move", self.mouse_move_function, self.priority, self.buttons[idx].remap.value_bg[1].handle) 
  2318. 				input_tracker:add_mouse_input("mouse_move", self.mouse_move_function, self.priority, self.buttons[idx].remap.value_bg[2].handle) 
  2319. 				input_tracker:add_mouse_input("mouse_click", self.mouse_click_function, self.priority, self.buttons[idx].remap.value_bg[1].handle) 
  2320. 				input_tracker:add_mouse_input("mouse_click", self.mouse_click_function, self.priority, self.buttons[idx].remap.value_bg[2].handle) 
  2321. 				vint_set_property(self.buttons[idx].remap.value_bg[1].handle, "mouse_depth", mouse_depth) 
  2322. 				vint_set_property(self.buttons[idx].remap.value_bg[2].handle, "mouse_depth", mouse_depth) 
  2323. 			end 
  2324. 		end 
  2325. 	end 
  2326. 	 
  2327. 	self:update_toggle_mouse_inputs() 
  2328. 	 
  2329. 	-- Add mouse inputs for the scroll region and scrolltab if needed 
  2330. 	if self.num_buttons > self.max_buttons then 
  2331. 		input_tracker:add_mouse_input("mouse_scroll", func_prefix.."_mouse_scroll", self.priority, self.clip_h) 
  2332. 		self.scrollbar:add_mouse_inputs(func_prefix, input_tracker, self.priority) 
  2333. 	end 
  2334. end 
  2335.  
  2336. -- Rebuilds the mouse input subscriptions, usually done when the list was rebuilt with draw_items() 
  2337. -- 
  2338. function Vdo_mega_list:update_mouse_inputs(func_prefix, input_tracker, priority) 
  2339. 	-- If the list doesn't scroll, there's no need to update the mouse inputs 
  2340. 	if self.num_buttons <= self.max_buttons then 
  2341. 		return 
  2342. 	end 
  2343. 	 
  2344. 	input_tracker:remove_all() 
  2345. 	self:add_mouse_inputs(func_prefix, input_tracker, priority) 
  2346. 	input_tracker:subscribe(true) 
  2347. end 
  2348.  
  2349. function Vdo_mega_list:enable_toggle_input(enable) 
  2350. 	if Game_platform ~= "PC" or Toggle_mouse_input_tracker == nil then 
  2351. 		return 
  2352. 	end 
  2353. 	 
  2354. 	Toggle_mouse_input_tracker:subscribe(enable) 
  2355. end 
  2356.  
  2357. -- INTERNAL FUNCTION 
  2358. -- Updates the mouse input tracking for the toggle/slider arrows, since they only capture input for the currently selected button 
  2359. -- 
  2360. function Vdo_mega_list:update_toggle_mouse_inputs() 
  2361. 	Toggle_mouse_input_tracker:remove_all() 
  2362. 	 
  2363. 	if self.mouse_click_function == nil or self.mouse_move_function == nil or self.priority == nil then 
  2364. 		return 
  2365. 	end 
  2366. 	 
  2367. 	local start_idx, end_idx = self:get_visible_indices() 
  2368. 	if self.current_idx >= start_idx and self.current_idx <= end_idx then 
  2369. 		if self.data[self.current_idx].type == TYPE_SLIDER then 
  2370. 			local arrow_left_handle = vint_object_find("arrow_left", self.buttons[self.current_idx].slider.handle) 
  2371. 			local arrow_right_handle = vint_object_find("arrow_right", self.buttons[self.current_idx].slider.handle) 
  2372. 			vint_set_property(arrow_left_handle, "depth", -201) 
  2373. 			vint_set_property(arrow_right_handle, "depth", -201) 
  2374. 			 
  2375. 			Toggle_mouse_input_tracker:add_mouse_input("mouse_click", self.mouse_click_function, self.priority, arrow_left_handle) 
  2376. 			Toggle_mouse_input_tracker:add_mouse_input("mouse_move", self.mouse_move_function, self.priority, arrow_left_handle) 
  2377. 			Toggle_mouse_input_tracker:add_mouse_input("mouse_click", self.mouse_click_function, self.priority, arrow_right_handle) 
  2378. 			Toggle_mouse_input_tracker:add_mouse_input("mouse_move", self.mouse_move_function, self.priority, arrow_right_handle) 
  2379. 		elseif self.data[self.current_idx].type == TYPE_TOGGLE then 
  2380. 			local arrow_left_handle = vint_object_find("arrow_left", self.buttons[self.current_idx].toggle.handle) 
  2381. 			vint_set_property(arrow_left_handle, "depth", -201) 
  2382. 			 
  2383. 			Toggle_mouse_input_tracker:add_mouse_input("mouse_click", self.mouse_click_function, self.priority, arrow_left_handle) 
  2384. 			Toggle_mouse_input_tracker:add_mouse_input("mouse_move", self.mouse_move_function, self.priority, arrow_left_handle) 
  2385. 		end 
  2386. 	end 
  2387. 	 
  2388. 	Toggle_mouse_input_tracker:subscribe(true) 
  2389. end 
  2390.  
  2391. function Vdo_mega_list:is_left_arrow(target_handle) 
  2392. 	if self.buttons[self.current_idx].slider ~= nil then 
  2393. 		return ( target_handle == vint_object_find("arrow_left", self.buttons[self.current_idx].slider.handle) ) 
  2394. 	elseif self.data[self.current_idx].type == TYPE_TOGGLE then 
  2395. 		return ( target_handle == vint_object_find("arrow_left", self.buttons[self.current_idx].toggle.handle) ) 
  2396. 	else 
  2397. 		return false 
  2398. 	end 
  2399. end 
  2400.  
  2401. function Vdo_mega_list:is_right_arrow(target_handle) 
  2402. 	if self.buttons[self.current_idx].slider == nil then 
  2403. 		return false 
  2404. 	end 
  2405. 	 
  2406. 	return ( target_handle == vint_object_find("arrow_right", self.buttons[self.current_idx].slider.handle) ) 
  2407. end 
  2408.  
  2409. function Vdo_mega_list:highlight_left_arrow(highlight) 
  2410. 	if self.buttons[self.current_idx].slider == nil then 
  2411. 		return false 
  2412. 	end 
  2413. 	 
  2414. 	if highlight then 
  2415. 		vint_set_property(vint_object_find("arrow_left", self.buttons[self.current_idx].slider.handle), "tint", 255,255,255 ) 
  2416. 	else 
  2417. 		vint_set_property(vint_object_find("arrow_left", self.buttons[self.current_idx].slider.handle), "tint", 0,0,0 ) 
  2418. 	end 
  2419. end 
  2420.  
  2421. function Vdo_mega_list:highlight_right_arrow(highlight) 
  2422. 	if self.buttons[self.current_idx].slider == nil then 
  2423. 		return false 
  2424. 	end 
  2425. 	 
  2426. 	if highlight then 
  2427. 		vint_set_property(vint_object_find("arrow_right", self.buttons[self.current_idx].slider.handle), "tint", 255,255,255 ) 
  2428. 	else 
  2429. 		vint_set_property(vint_object_find("arrow_right", self.buttons[self.current_idx].slider.handle), "tint", 0,0,0 ) 
  2430. 	end 
  2431. end 
  2432.  
  2433. function Vdo_mega_list:is_slider(target_handle) 
  2434. 	if self.buttons[self.current_idx].slider == nil or self.slider_hitboxes == nil then 
  2435. 		return false 
  2436. 	end 
  2437. 	 
  2438. 	for idx, slider_hitbox in pairs(self.slider_hitboxes) do 
  2439. 		if slider_hitbox.handle == target_handle then 
  2440. 			return true 
  2441. 		end 
  2442. 	end 
  2443. 	 
  2444. 	-- No matching slider hitbox was found 
  2445. 	return false 
  2446. end 
  2447.  
  2448. function Vdo_mega_list:scroll_list(scroll_lines, new_start_index) 
  2449. 	local new_y = 0 
  2450.  
  2451. 	local move_height = LIST_BUTTON_HEIGHT + MEGA_LIST_BUTTON_SPACING 
  2452. 	local list_x, list_y =  vint_get_property(self.group_h, "anchor") 
  2453.  
  2454. 	-- Set the start index based on mouse wheel's scroll lines or the new start index calculated 
  2455. 	-- by the scroll tab's position 
  2456. 	if new_start_index ~= nil then 
  2457. 		self.visible_start_idx = new_start_index 
  2458. 		 
  2459. 	else 
  2460. 		self.visible_start_idx = self.visible_start_idx + scroll_lines 
  2461. 		local visible_end_idx = self.visible_start_idx + (self.max_buttons - 1) 
  2462. 		if self.visible_start_idx < 1 then 
  2463. 			self.visible_start_idx = 1 
  2464. 		elseif visible_end_idx > self.num_buttons then 
  2465. 			self.visible_start_idx = self.num_buttons - (self.max_buttons - 1) 
  2466. 		end 
  2467. 	end 
  2468. 	local visible_end_idx = self.visible_start_idx + (self.max_buttons - 1) 
  2469. 	 
  2470. 	-- Calculate the list's new position based on the starting visible index 
  2471. 	new_y = -1 * move_height * (self.visible_start_idx - 1) 
  2472. 	new_y = limit(new_y, move_height * (self.max_buttons - self.num_buttons), 0) 
  2473.  
  2474. 	-- if scrolling with the mouse wheel, animate the list and the scrolltab 
  2475. 	if scroll_lines ~= 0 then 
  2476. 		-- Start a scroll animation, unless we were not told to move.  We do this to make the timing between cursor moves 
  2477. 		-- that cause a scroll and those that don't to be the same. 
  2478.  
  2479. 		local toggle_group_anim = Vdo_anim_object:new("toggle_group_anim", self.handle, self.doc_handle) 
  2480. 		toggle_group_anim:set_target_handle(self.handle) 
  2481. 		local anchor_tween = Vdo_tween_object:new("toggle_group_anchor_tween", self.handle, self.doc_handle) 
  2482. 				 
  2483. 		anchor_tween:set_property("start_value", list_x, list_y ) 
  2484. 		anchor_tween:set_property("end_value", list_x, new_y ) 
  2485. 		anchor_tween:set_property("end_event", "vdo_mega_list_scroll_done") 
  2486. 		toggle_group_anim:play(0) 
  2487. 		 
  2488. 		Vdo_mega_list_tween_done = false 
  2489. 		 
  2490. 		self.scrollbar:set_value( self.num_buttons - (self.max_buttons - 1), self.visible_start_idx, false ) 
  2491. 	else 
  2492. 		-- only set the position of the list based on the new starting index 
  2493. 		vint_set_property(self.group_h, "anchor", list_x, new_y) 
  2494. 	end 
  2495. 	 
  2496. 	--Store the new y off into list_y... 
  2497. 	self.list_y = new_y 
  2498. end 
  2499.  
  2500. function Vdo_mega_list:set_list_alignment() 
  2501. 	--TODO add support 
  2502. end 
  2503.  
  2504. function Vdo_mega_list:set_width() 
  2505. 	--TODO add support 
  2506. end 
  2507.  
  2508. ------------------------------------------------------------------------------- 
  2509. -- Returns the column positions from the first row in the list... 
  2510. ------------------------------------------------------------------------------- 
  2511. function Vdo_mega_list:row_get_column_positions() 
  2512. 	for i = 1, self.num_buttons do 
  2513. 		local row = self.buttons[i].row 
  2514. 		if row then 
  2515. 			local col_1_x, col_2_x, col_3_x, col_4_x = row:get_column_positions() 
  2516. 			col_1_x = col_1_x + self.button_x 
  2517. 			col_2_x = col_2_x + self.button_x 
  2518. 			col_3_x = col_3_x + self.button_x 
  2519. 			col_4_x = col_4_x + self.button_x 
  2520. 			return col_1_x, col_2_x, col_3_x, col_4_x 
  2521. 		end 
  2522. 	end 
  2523. end 
  2524.  
  2525. function Vdo_mega_list:set_input_tracker(input_tracker) 
  2526. 	self.input_tracker = input_tracker 
  2527. end 
  2528.  
  2529. function Vdo_mega_list:set_mouse_highlight(new_index) 
  2530. 	 
  2531. 	-- Clear out the old highlighted colors on buttons... 
  2532. 	for idx, button in pairs(self.buttons) do 
  2533. 		if idx ~= new_index then 
  2534. 			button:set_alpha(1.0) 
  2535. 			--Unhighlight different button types... 
  2536. 			if button.slider then 
  2537. 				button.slider:set_mouse_highlight(false) 
  2538. 			elseif button.toggle then 
  2539. 				button.toggle:set_mouse_highlight(false) 
  2540. 			elseif button.row then 
  2541. 				--button.row:set_mouse_highlight(false) 
  2542. 				button.row:set_color(COLOR_CELL_MENU_HIGHLIGHT_TEXT) 
  2543. 			end 
  2544. 		end 
  2545. 	end 
  2546.  
  2547. 	--if we have a valid index then set the highlight 
  2548. 	if new_index > 0 then 
  2549. 		local current_button = self.buttons[new_index] 
  2550. 		-- Highlight different button types... 
  2551. 		if current_button.slider then 
  2552. 			current_button.slider:set_mouse_highlight(true) 
  2553. 		elseif current_button.toggle then 
  2554. 			current_button.toggle:set_mouse_highlight(true) 
  2555. 		elseif current_button.row then 
  2556. 			--current_button.row:set_mouse_highlight(true) 
  2557. 			current_button.row:set_color(COLOR_SAINTS_PURPLE) 
  2558. 		end 
  2559. 	end 
  2560. end 
  2561.  
  2562. --update y values for extended buttons 
  2563. function Vdo_mega_list:update_extended_position( current_idx ) 
  2564. 	local shift_down = 0 
  2565. 	-- reposition buttons for new higlight 
  2566. 	for i = 1, self.num_buttons do 
  2567. 		local new_y = 0						 
  2568. 		local button_x, button_y = vint_get_property(self.toggle_base.handle, "anchor") 
  2569.  
  2570. 		if i == 1 then 
  2571. 			--TODO FIX THIS... Y Position is probably incorrect... 
  2572. 			--buttons are aligned to the middle, so offset the y to fthe first iem... 
  2573. 			new_y = LIST_BUTTON_HEIGHT * BUTTON_ANCHOR_OFFSET 
  2574. 		else 
  2575. 			--shifting down allows us to accomodate for additional spacing taken by the  
  2576. 			--larger button... 
  2577. 			new_y = LIST_BUTTON_HEIGHT * (i + shift_down - BUTTON_ANCHOR_OFFSET) 
  2578. 		end 
  2579.  
  2580. 		self.buttons[i]:set_property("anchor", button_x, new_y) 
  2581. 		 
  2582. 		-- if we're highlighted shift the next buttons down 
  2583. 		if i == current_idx then 
  2584. 			shift_down = 1 
  2585. 		end 
  2586. 	end 
  2587. end 
  2588.  
  2589. function Vdo_mega_list:set_lines( has_lines ) 
  2590. 	self.has_lines = has_lines 
  2591. end 
  2592.  
  2593. --[[ --------------------------------------------------------------------- 
  2594. -- Function - vdo_mega_list_update_gamepad_state 
  2595. -- Description - Called by code anytime gamepad is changed from keyboard  
  2596. 						to gamepad and vice versa. 
  2597. -- Parameters - none 
  2598. -- Returns - nil 
  2599. ]]-- --------------------------------------------------------------------- 
  2600. function vdo_mega_list_update_gamepad_state() 
  2601. 	if Vdo_mega_list_gamepad_listener_enabled == true then 
  2602. 		if( Buttons ~= nil and Buttons.buttons ~= nil ) then 
  2603. 			if( Buttons.buttons[Buttons.current_idx].slider == nil or Buttons.slider_hitboxes == nil )then 
  2604. 				if game_is_active_input_gamepad() == false or Buttons.data[Buttons.current_idx].is_locked or Buttons.data[Buttons.current_idx].is_purchased or Buttons.data[Buttons.current_idx].show_button == false or Buttons.data[Buttons.current_idx].completed == true then 
  2605. 					Buttons.button_highlight:show_button("") 
  2606. 				else 
  2607. 					Buttons.button_highlight:show_button(CTRL_MENU_BUTTON_A) 
  2608. 				end 
  2609. 			end 
  2610. 		end 
  2611. 	end 
  2612. end 
  2613.  
  2614.  
  2615. ------------------------------------------------------------------------------- 
  2616. -- Disables/Enables listener for gamepad button updates. 
  2617. -- 
  2618. function vdo_mega_list_enable_listener(is_enabled) 
  2619. 	Vdo_mega_list_gamepad_listener_enabled = is_enabled 
  2620. end