./vdo_mega_list.lua

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