./cell_phone.lua

  1. local Data = { } 
  2. Num_items = 0 
  3.  
  4. --Input Trackers... 
  5. local Input_tracker 
  6. local Input_tracker_garage 
  7. local Input_tracker_call 
  8. local Mouse_input_tracker = {} 
  9. local Mouse_input_tracker_garage = {} 
  10. local Mouse_input_tracker_garage_hint= {} 
  11. local Mouse_input_tracker_call = {} 
  12.  
  13. local List = nil 
  14. local Call_grp 
  15. local Cell_phone_handle = -1 
  16.  
  17. local MOUSE_INVALID_HANDLE = -1 
  18.  
  19. local Homie_data = {} 
  20. local Homie_data_cur_idx = 1 
  21. local HOMIE_MAX_ITEMS = 4 
  22. local Book_screen_is_scrolling = false 
  23.  
  24. local Hint_bar = -1 
  25. local Garage_hint_bar = -1 
  26.  
  27. local Visible_start_idx = 1 
  28. local Visible_end_idx = HOMIE_MAX_ITEMS 
  29. local Prev_y = -1 
  30.  
  31. CELL_PHONE_BOOK_MAX_WIDTH_LABEL = 224	--Max label width for the phone 
  32. CELL_PHONE_CALL_MAX_WIDTH_LABEL = 259	--Max label width for the calling screen. 
  33.  
  34. -- Enum to define which type of data to retrieve 
  35. local CELL_HOMIE_LIST	= 0 
  36. local CELL_VEHICLE_LIST	= 1 
  37.  
  38. --Connection States 
  39. local CELL_CALL_INVALID 			= -1 
  40. local CELL_CALL_CONNECTED 			= 0 
  41. local CELL_CALL_GARAGE_SHOW 		= 1 
  42.  
  43. --Hangup states 
  44. local CELL_CALL_HANGUP 				= 0 
  45. local CELL_CALL_RETURN_TO_PHONE 	= 1 
  46.  
  47. --Transition enums... 
  48. local CELL_MENU_TRANS_NONE 	= 0 
  49. local CELL_MENU_TRANS_LEFT 	= 1 
  50. local CELL_MENU_TRANS_RIGHT 	= 2 
  51.  
  52. -- Enums for pages on the phone... 
  53. local CELL_PHONE_MENU_BOOK			= 1 
  54. local CELL_PHONE_MENU_GARAGE		= 2 
  55. local CELL_PHONE_MENU_CALL			= 3 
  56.  
  57. --Layout constansts 
  58. local LIST_COLOR_HIGHLIGHT 	= COLOR_SAINTS_PURPLE 
  59. local LIST_COLOR_UNHIGHLIGHT	= {R=80/255,G=80/255,B=80/255} --COLOR_PLAYER_CREATION_TERTIARY 
  60. local LIST_COLOR_DISABLED 		= {R=30/255,G=30/255,B=30/255} 
  61.  
  62. local HOMIE_LIST_SPACING = 74		--Spacing between items 
  63. local GARAGE_LIST_WIDTH = 358		--Spacing between items 
  64.  
  65. local Cell_menus = {} 
  66.  
  67. local Menu_active = -1		--Active menu ID... 
  68.  
  69. --Garage stuff 
  70. local Garage_list = -1			--VDO reference to garage list 
  71. local Garage_list_data = -1	--Data for garage list... 
  72. local GARAGE_LIST_MAX_BUTTONS = 10 
  73.  
  74. local Cell_phone_cash = -1 
  75.  
  76. local Scrollbar = -1 
  77.  
  78. local Screen_start_x 
  79. local Screen_start_y  
  80.  
  81. local Game_platform 
  82.  
  83. function cell_phone_init() 
  84. 	Cell_phone_handle = vint_document_find("cell_phone") 
  85.  
  86. 	--Initialize list... 
  87. 	local contact_highlight_grp_h = vint_object_find("contact_highlight_grp") 
  88. 	local highlight_bg_h = vint_object_find("highlight_bg", contact_highlight_grp_h) 
  89. 	vint_set_property(highlight_bg_h, "tint", LIST_COLOR_HIGHLIGHT.R, LIST_COLOR_HIGHLIGHT.G, LIST_COLOR_HIGHLIGHT.B) 
  90. 	 
  91. 	--Set button on contact list... 
  92. 			 
  93. 	--if pc then hide ctrl button 
  94. 	local highlight_btn = Vdo_hint_button:new("highlight_btn", contact_highlight_grp_h) 
  95. 	 
  96. 	if game_is_active_input_gamepad() == false then		 
  97. 		highlight_btn:set_visible(false) 
  98. 	else	 
  99. 		highlight_btn:set_button(CTRL_MENU_BUTTON_A) 
  100. 	end 
  101. 	 
  102. 	--Set text for vehicle delivery 
  103. 	vint_set_property(vint_object_find("calling_info_txt_1"),"text_tag", "HOMIES_DRIVEUP") 
  104. 	 
  105. 	--Show screens... 
  106. 	local call_screen_grp_h = vint_object_find("call_screen_grp") 
  107. 	local book_screen_grp_h = vint_object_find("book_screen_grp") 
  108. 	local garage_screen_grp_h = vint_object_find("garage_screen_grp") 
  109. 	vint_set_property(call_screen_grp_h, "visible", false) 
  110. 	vint_set_property(garage_screen_grp_h, "visible", false) 
  111. 	vint_set_property(book_screen_grp_h, "visible", true) 
  112.  
  113. 	Screen_start_x, Screen_start_y = vint_get_property(call_screen_grp_h, "anchor") 
  114.  
  115. 	--Garage list init... 
  116. 	Garage_list = Vdo_mega_list:new("mega_list") 
  117. 	Garage_list:set_properties(LIST_COLOR_HIGHLIGHT, LIST_COLOR_UNHIGHLIGHT, 10, .8, GARAGE_LIST_WIDTH, false, true) 
  118. 	Garage_list:set_highlight_color(LIST_COLOR_HIGHLIGHT, LIST_COLOR_UNHIGHLIGHT) 
  119. 	 
  120. 	-- Subscribe to the button presses we need... 
  121. 	Input_tracker = Vdo_input_tracker:new() 
  122. 	Input_tracker:add_input("nav_up", 	"cell_phone_book_nav_up", 	50) 
  123. 	Input_tracker:add_input("nav_down", "cell_phone_book_nav_down", 	50)	 
  124. 	Input_tracker:add_input("back", 		"cell_phone_book_button_b", 	50) 
  125. 	Input_tracker:add_input("select", 	"cell_phone_book_button_a", 		50) 
  126. 	Input_tracker:add_input("map", 		"cell_phone_book_button_map", 	50) 
  127. 	Input_tracker:subscribe(false) 
  128. 	 
  129. 	--Input tracker for garage menu 
  130. 	Input_tracker_garage = Vdo_input_tracker:new() 
  131. 	Input_tracker_garage:add_input("nav_up", 		"cell_phone_garage_nav_up", 		50) 
  132. 	Input_tracker_garage:add_input("nav_down", 	"cell_phone_garage_nav_down", 	50)	 
  133. 	Input_tracker_garage:add_input("back", 		"cell_phone_garage_button_b", 	50) 
  134. 	Input_tracker_garage:add_input("select", 		"cell_phone_garage_button_a", 	50) 
  135. 	Input_tracker_garage:add_input("map", 			"cell_phone_garage_map", 			50) 
  136. 	Input_tracker_garage:subscribe(false) 
  137. 	 
  138. 	--Input tracker for garage menu 
  139. 	Input_tracker_call = Vdo_input_tracker:new() 
  140. 	Input_tracker_call:add_input("nav_up", 		"cell_phone_call_input", 		50) 
  141. 	Input_tracker_call:add_input("nav_down", 		"cell_phone_call_input", 		50)	 
  142. 	Input_tracker_call:add_input("back", 			"cell_phone_call_input",		50) 
  143. 	Input_tracker_call:add_input("select", 		"cell_phone_call_input",		50) 
  144. 	Input_tracker_call:add_input("map", 			"cell_phone_call_input",		50) 
  145. 	Input_tracker_call:subscribe(false) 
  146. 	 
  147. 	--Init scrollbar... 
  148. 	Scrollbar = Vdo_scrollbar:new("book_scrollbar")	 
  149. 	Scrollbar:set_highlight_color(LIST_COLOR_HIGHLIGHT) 
  150. 	 
  151. 	--Hint bar 
  152. 	Hint_bar 			= Vdo_hint_bar:new("hint_bar") 
  153. 	Garage_hint_bar	= Vdo_hint_bar:new("garage_hint_bar") 
  154. 	 
  155. 	local hints = { 
  156. 		{CTRL_MENU_BUTTON_B, "MENU_BACK"}, 
  157. 	} 
  158. 	 
  159. 	Hint_bar:set_hints(hints) 
  160. 	Garage_hint_bar:set_hints(hints) 
  161. 	 
  162. 	--setup call hintbar... 
  163. 	hints = { 
  164. 		{CTRL_MENU_BUTTON_A, "MENU_CONTINUE"}, 
  165. 	}	 
  166.  
  167. 	Game_platform = game_get_platform() 
  168. 	 
  169. 	local mouse_area_img_h = vint_object_find("mouse_area_img") 
  170. 	--create mouse input tracker and send it to the scrollbar vdo 
  171. 	if Game_platform == "PC" then 
  172. 		Mouse_input_tracker = Vdo_input_tracker:new() 
  173. 		Mouse_input_tracker_garage = Vdo_input_tracker:new() 
  174. 		Mouse_input_tracker_garage_hint = Vdo_input_tracker:new() 
  175. 		Mouse_input_tracker_call = Vdo_input_tracker:new() 
  176. 		 
  177. 		Mouse_input_tracker:add_mouse_input("mouse_scroll", "cell_phone_mouse_scroll", 50, mouse_area_img_h) 
  178. 		 
  179. 		Hint_bar:add_mouse_inputs("cell_phone", Mouse_input_tracker, 50) 
  180. 		Scrollbar:add_mouse_inputs("cell_phone",Mouse_input_tracker,50) 
  181. 		Garage_hint_bar:add_mouse_inputs("cell_phone",Mouse_input_tracker_garage_hint,50) 
  182. 		 
  183. 		Mouse_input_tracker:subscribe(true)	 
  184. 		Mouse_input_tracker_garage:subscribe(false) 
  185. 		Mouse_input_tracker_garage_hint:subscribe(false) 
  186. 		Mouse_input_tracker_call:subscribe(false) 
  187. 	end 
  188. 	 
  189. 	--Setup object for our menu functions and handling input... 
  190. 	Cell_menus = { 
  191. 		[CELL_PHONE_MENU_BOOK]		=	{h = book_screen_grp_h, input_tracker = Input_tracker, mouse_input_tracker = Mouse_input_tracker, hint_input_tracker = nil}, 
  192. 		[CELL_PHONE_MENU_GARAGE] 	= 	{h = garage_screen_grp_h, input_tracker = Input_tracker_garage, mouse_input_tracker = Mouse_input_tracker_garage, hint_input_tracker = Mouse_input_tracker_garage_hint}, 
  193. 		[CELL_PHONE_MENU_CALL]	 	= 	{h = 	call_screen_grp_h, input_tracker = Input_tracker_call, mouse_input_tracker = Mouse_input_tracker_call, hint_input_tracker = nil}, 
  194. 	} 
  195. 	 
  196. 	--Subscribe to player information for cash data 
  197. 	vint_dataitem_add_subscription("sr2_local_player_status_infrequent", "update", "cell_phone_cash_update") 
  198.  
  199. 	-- Populate homie call list 
  200. 	vint_dataresponder_request("cell_phone_pad_populate", "cell_phone_populate_list", 0, CELL_HOMIE_LIST)	 
  201. 	 
  202. 	if #Homie_data == 0 then 
  203. 		-- No homie data... we need to abort this screen 
  204. 		debug_print("vint", "no homie data... cannot enter cellphone\n") 
  205. 		cell_phone_exit(false) 
  206. 		local safe_h = vint_object_find("safe_frame") 
  207. 		vint_set_property(safe_h, "visible", false) 
  208. 		return 
  209. 	end 
  210. 	 
  211. 	-- Build Phonebook Screen 
  212. 	cell_phone_book_build() 
  213.  
  214. 	--Transition the screen in... 
  215. 	cell_transition_screen(CELL_STATE_PORTRAIT, CELL_SCREEN_PHONE, CELL_SCREEN_MAIN, cell_phone_menu_trans_in_complete) 
  216. end 
  217.  
  218. function cell_phone_menu_trans_in_complete() 
  219. 	--Show homies menu... 
  220. 	cell_phone_menu_show(CELL_PHONE_MENU_BOOK) 
  221. end 
  222.  
  223. --Transitions to a specific menu... 
  224.  
  225. function cell_phone_menu_show(menu_id, direction) 
  226.  
  227. 	--simply show the current menu id... 
  228. 	for i = 1, #Cell_menus do 
  229. 		local h = Cell_menus[i].h 
  230. 		vint_set_property(h, "visible", false) 
  231.  
  232. 		--Switch to the proper input tracker... 
  233. 		--unsubscribe all menus because we need to wait for transition... and then put subscribe in AFTER the transition callback... 
  234. 		local input_tracker = Cell_menus[i].input_tracker		 
  235. 		input_tracker:subscribe(false) 
  236. 		 
  237. 		local mouse_input_tracker = Cell_menus[i].mouse_input_tracker 
  238. 		mouse_input_tracker:subscribe(false) 
  239. 		 
  240. 		local hint_input_tracker = Cell_menus[i].hint_input_tracker 
  241. 		if hint_input_tracker ~= nil then 
  242. 			hint_input_tracker:subscribe(false) 
  243. 		end 
  244. 	end 
  245.  
  246.  
  247. 	if Menu_active == -1 then 
  248. 		--No transition allowed... 
  249. 		--Just do callback.. 
  250. 		local input_tracker = Cell_menus[menu_id].input_tracker 
  251. 		input_tracker:subscribe(true) 
  252. 		 
  253. 		local mouse_input_tracker = Cell_menus[menu_id].mouse_input_tracker 
  254. 		mouse_input_tracker:subscribe(true) 
  255. 		 
  256. 		local hint_input_tracker = Cell_menus[menu_id].hint_input_tracker 
  257. 		if hint_input_tracker ~= nil then 
  258. 			hint_input_tracker:subscribe(true) 
  259. 		end		 
  260. 		 
  261. 		local h = Cell_menus[menu_id].h 
  262. 		vint_set_property(h, "visible", true) 
  263. 	else 
  264. 		local h = Cell_menus[menu_id].h 
  265. 		local previous_menu_id = Menu_active 
  266. 		local prev_h = Cell_menus[previous_menu_id].h 
  267. 		 
  268. 		-- show the two menus we are gonna transition... 
  269. 		vint_set_property(prev_h, "visible", true) 
  270. 		vint_set_property(h, "visible", true) 
  271. 		 
  272. 		local menu_width = 365 + 10 
  273. 		--Always transition left for now... 
  274. 		vint_set_property(prev_h, "anchor", Screen_start_x, Screen_start_y) 
  275. 		vint_set_property(h, "anchor", menu_width, 0) 
  276. 		 
  277. 		local left_h 	= prev_h  
  278. 		local right_h 	= h  
  279. 		 
  280. 		if direction == CELL_MENU_TRANS_NONE or direction == nil then 
  281. 			vint_set_property(prev_h, "visible", false) 
  282. 			menu_width = 0 
  283. 		elseif direction == CELL_MENU_TRANS_LEFT then 
  284. 			menu_width = - menu_width 
  285. 		elseif direction == CELL_MENU_TRANS_RIGHT then 
  286. 			 
  287. 		end 
  288. 		 
  289. 		local cell_screen_trans_anim_h = vint_object_find("cell_screen_trans_anim") 
  290. 		local left_twn_h = vint_object_find("trans_left_twn", cell_screen_trans_anim_h) 
  291. 		local right_twn_h = vint_object_find("trans_right_twn", cell_screen_trans_anim_h) 
  292. 		vint_set_property(left_twn_h, "start_value", 	Screen_start_x , 					Screen_start_y) 
  293. 		vint_set_property(left_twn_h, "end_value",	 	Screen_start_x - menu_width, 	Screen_start_y) 
  294. 		vint_set_property(right_twn_h, "start_value", 	Screen_start_x + menu_width , Screen_start_y) 
  295. 		vint_set_property(right_twn_h, "end_value", 		Screen_start_x , 					Screen_start_y) 
  296. 		 
  297. 		vint_set_property(right_twn_h, "target_handle", right_h) 
  298. 		vint_set_property(left_twn_h, "target_handle", left_h) 
  299. 		  
  300. 		vint_set_property(left_twn_h, "end_event", "cell_phone_menu_trans_cb") 
  301. 		lua_play_anim(cell_screen_trans_anim_h) 
  302. 	end 
  303.  
  304. 	 
  305. 	Menu_active = menu_id 
  306. end 
  307.  
  308. ------------------------------------------------------------------------------- 
  309. -- Gets called after we transition a menu, via tween callback.. 
  310. ------------------------------------------------------------------------------- 
  311. function cell_phone_menu_trans_cb() 
  312. 	-- menu is displaying... now subscribe to its input... 
  313. 	local input_tracker = Cell_menus[Menu_active].input_tracker 
  314. 	input_tracker:subscribe(true) 
  315. 	 
  316. 	local mouse_input_tracker = Cell_menus[Menu_active].mouse_input_tracker 
  317. 	mouse_input_tracker:subscribe(true)	 
  318. 	 
  319. 	local hint_input_tracker = Cell_menus[Menu_active].hint_input_tracker 
  320. 	if hint_input_tracker ~= nil then 
  321. 		hint_input_tracker:subscribe(true) 
  322. 	end	 
  323. end 
  324.  
  325. ------------------------------------------------------------------------------- 
  326. -- Connection callback... 
  327. -- This gets called after we dial... 
  328. -- @param success	 
  329. ------------------------------------------------------------------------------- 
  330. function cell_phone_dial_connection_cb(success) 
  331. 	debug_print("vint", "cell_phone_dial_connection_cb()\n") 
  332. 	debug_print("vint", "success" .. var_to_string(success) .. "\n") 
  333. 	 
  334. 	if success == CELL_CALL_INVALID then 
  335. 		--wrong number 
  336. 		--use invalid number screen 
  337. 		--DON'T DO ANYTHING... 
  338. 		cell_phone_call_build(true) 
  339. 		cell_phone_menu_show(CELL_PHONE_MENU_CALL, CELL_MENU_TRANS_RIGHT) 
  340. 	elseif success == CELL_CALL_CONNECTED then 
  341. 		--Connection has been made, string of store name to display is stored in name 
  342. 		cell_phone_call_build(false) 
  343. 		cell_phone_menu_show(CELL_PHONE_MENU_CALL, CELL_MENU_TRANS_RIGHT) 
  344. 	elseif success  == CELL_CALL_GARAGE_SHOW then 
  345. 		--Show garage... 
  346. 		--build garage menu here... 
  347. 		local success = cell_phone_garage_build() 
  348. 		if success == false then 
  349. 			cell_phone_garage_no_vehicles_dialog() 
  350. 			debug_print("vint", "you need vehicles in your garage to access this feature\n") 
  351. 			return 
  352. 		end 
  353. 		 
  354. 		--Show it... 
  355. 		cell_phone_menu_show(CELL_PHONE_MENU_GARAGE, CELL_MENU_TRANS_RIGHT) 
  356. 	end 
  357. end 
  358.  
  359. ------------------------------------------------------------------------------- 
  360. -- Builds the phone book 
  361. ------------------------------------------------------------------------------- 
  362. function cell_phone_book_build() 
  363. 	local book_screen_grp_h = vint_object_find("book_screen_grp") 
  364. 	 
  365. 	--Base contact handle and hide... 
  366. 	local contact_grp_h = vint_object_find("contact_grp", book_screen_grp_h) 
  367. 	vint_set_property(contact_grp_h, "visible", false) 
  368.  
  369. 	local homie_count = #Homie_data  
  370. 	for i = 1, homie_count do 
  371. 		--get data out of table... 
  372. 		local homie_index = Homie_data[i].homie_index 
  373. 		local homie_name_crc = Homie_data[i].homie_name_crc 
  374. 		local description_crc = Homie_data[i].description_crc 
  375. 		local image_crc = Homie_data[i].image_crc 
  376. 		local is_available = Homie_data[i].is_available 
  377. 		 
  378. 		--clone base item... 
  379. 		local h = vint_object_clone(contact_grp_h) 
  380. 		 
  381. 		--Set Text 
  382. 		local name_txt_h = vint_object_find("name_txt", h) 
  383. 		vint_set_property(name_txt_h, "text_tag_crc", homie_name_crc) 
  384.  
  385. 		cell_phone_resize_text_element(name_txt_h, CELL_PHONE_BOOK_MAX_WIDTH_LABEL) 
  386. 				 
  387. 		--Set icon 
  388. 		local homie_icon_h = vint_object_find("homie_icon", h) 
  389. 		vint_set_property(homie_icon_h, "image_crc", image_crc) 
  390. 		 
  391. 		--Position Homie in list... 
  392. 		local x, y = vint_get_property(h, "anchor") 
  393. 		y = ( (i - 1) * HOMIE_LIST_SPACING ) 
  394. 		vint_set_property(h, "anchor", x, y ) 
  395. 		 
  396. 		--Show homie in list... 
  397. 		vint_set_property(h, "visible", true) 
  398. 		 
  399. 		if is_available == true then 
  400. 			--Reset to normal... 
  401. 			vint_set_property(h, "alpha", 1) 
  402. 		else 
  403. 			--Grey out homie in list... 
  404. 			vint_set_property(h, "alpha", .333) 
  405. 		end 
  406.  
  407. 		if Game_platform == "PC" then 
  408. 			Mouse_input_tracker:add_mouse_input("mouse_move", "cell_phone_mouse_move", 50, h) 
  409. 			Mouse_input_tracker:add_mouse_input("mouse_click", "cell_phone_mouse_click", 50, h)			 
  410. 		end 
  411. 		 
  412. 		--Store handle of cloned object into homie table... 
  413. 		Homie_data[i].h = h 
  414. 	end 
  415. 	 
  416. 	Mouse_input_tracker:subscribe(true) 
  417. 	 
  418. 	--do we need scrollbar? 
  419. 	 
  420. 	-- Handle scrolling 
  421. 	if(homie_count > HOMIE_MAX_ITEMS) then 
  422. 		--show the scroll bar 
  423. 		Scrollbar:set_property("visible", true) 
  424. 		--set the size of the scrollbar 
  425. 		local contact_base_grp_h = vint_object_find("contact_base_grp") 
  426. 		local contact_clip_h = vint_object_find("contact_clip", contact_base_grp_h) 
  427. 		local clip_width, clip_height = vint_get_property(contact_clip_h, "clip_size") 
  428. 		Scrollbar:set_size(SCROLLBAR_WIDTH, clip_height) 
  429. 	else 
  430. 		--show the scroll bar 
  431. 		Scrollbar:set_property("visible", false) 
  432. 	end	 
  433. 	 
  434. 	--Find first available homie... 
  435. 	local homie_count = #Homie_data 
  436. 	local is_available = Homie_data[Homie_data_cur_idx].is_available 
  437. 	local is_available_count = 0 
  438. 	local is_available_idx = Homie_data_cur_idx 
  439. 	if is_available == false then 
  440. 		local new_index 
  441. 		while not is_available do 
  442. 			is_available = Homie_data[is_available_idx].is_available 
  443. 			if is_available_count > homie_count then 
  444. 				new_index = Homie_data_cur_idx 
  445. 				is_available = true 
  446. 			end 
  447. 			 
  448. 			new_index = is_available_idx 
  449. 			is_available_count = is_available_count + 1 
  450. 			is_available_idx = is_available_idx + 1 
  451. 			if is_available_idx > homie_count then 
  452. 				is_available_idx = 1 
  453. 			end 
  454. 		end 
  455. 		Homie_data_cur_idx = new_index 
  456. 	end 
  457. 	 
  458. 	--Select item in list... 
  459. 	cell_phone_book_highlight(Homie_data_cur_idx) 
  460. end 
  461.  
  462. ------------------------------------------------------------------------------------ 
  463. -- Sets the current highlighted option on the phone book and resets everything else 
  464. -- @param idx					index of item to highlight  
  465. -- @param is_mouse_input	are we using the mouse? 
  466. -- @param is_scrollbar		are we using the scrollbar with the mouse? 
  467. ------------------------------------------------------------------------------------ 
  468. function cell_phone_book_highlight(idx, is_mouse_input, is_scrollbar) 
  469. 	 
  470. 	Homie_data_cur_idx = idx 
  471. 	 
  472. 	local homie_count = #Homie_data  
  473. 	 
  474. 	--if using scrollbar don't update the highlight, just scroll the list 
  475. 	if is_scrollbar ~= true then 
  476. 		local book_screen_grp_h = vint_object_find("book_screen_grp") 
  477. 				 
  478. 		--cant select this if its not available... 
  479. 		local is_available = Homie_data[idx].is_available 
  480. 		 
  481. 		local can_select = true 
  482. 		if is_available == false then 
  483. 			--hide highlight 
  484. 			local contact_highlight_grp_h = vint_object_find("contact_highlight_grp", book_screen_grp_h) 
  485. 			vint_set_property(contact_highlight_grp_h, "visible", false) 
  486. 			 
  487. 			--hide description... 
  488. 			local description_txt_h = vint_object_find("description_txt") 
  489. 			vint_set_property(description_txt_h, "visible", false) 
  490. 			 
  491. 			can_select = false 
  492. 		end 
  493. 			 
  494. 		for i = 1, homie_count do 
  495. 		 
  496. 			--Get base group out of homie data... 
  497. 			local h = Homie_data[i].h 
  498. 			local is_available = Homie_data[i].available 
  499. 			local border_grp_h = vint_object_find("border_grp", h) 
  500. 		 
  501. 			if i == idx and can_select == true then 
  502. 				--Highlight this option 
  503. 				 
  504. 				--Color border purple 
  505. 				 
  506. 				--Move the highlight bar to indexed location... 
  507. 				local contact_highlight_grp_h = vint_object_find("contact_highlight_grp", book_screen_grp_h) 
  508. 				vint_set_property(contact_highlight_grp_h, "visible", true) 
  509. 				 
  510. 				local x, y = vint_get_property(h, "anchor") 
  511. 				vint_set_property(contact_highlight_grp_h, "anchor", x, y) 
  512. 				 
  513. 				--Change text field of item... 
  514. 				local name_txt_h = vint_object_find("name_txt", contact_highlight_grp_h) 
  515. 				local homie_name_crc = Homie_data[i].homie_name_crc 
  516. 				vint_set_property(name_txt_h, "text_tag_crc", homie_name_crc) 
  517. 				vint_set_property(border_grp_h, "tint", LIST_COLOR_HIGHLIGHT.R, LIST_COLOR_HIGHLIGHT.G, LIST_COLOR_HIGHLIGHT.B) 
  518. 				 
  519. 				--Make sure it fits in the phone... 
  520. 				cell_phone_resize_text_element(name_txt_h, CELL_PHONE_BOOK_MAX_WIDTH_LABEL) 
  521. 		 
  522. 				--Update description text 
  523. 				local description_crc = Homie_data[i].description_crc 
  524. 				local description_txt_h = vint_object_find("description_txt") 
  525. 				vint_set_property(description_txt_h, "text_tag_crc", description_crc) 
  526. 				vint_set_property(description_txt_h, "visible", true) 
  527. 				 
  528. 			else 
  529. 				--Color border grey 
  530. 				vint_set_property(border_grp_h, "tint", LIST_COLOR_UNHIGHLIGHT.R, LIST_COLOR_UNHIGHLIGHT.G, LIST_COLOR_UNHIGHLIGHT.B) 
  531. 			end 
  532. 		end 
  533. 	end 
  534. 	--Adjust scrollbar 
  535. 	Scrollbar:set_value(homie_count, idx, false ) 
  536.  
  537. 	local visual_center = ( HOMIE_MAX_ITEMS * 0.5 ) 
  538. 	local move_height = HOMIE_LIST_SPACING 
  539. 	local new_y = 0 	 
  540. 	local list_x, list_y = vint_get_property(vint_object_find("contact_list_grp"), "anchor") 
  541. 		 
  542. 	if is_mouse_input then	 
  543. 		--if using mouse don't scroll and keep list where it's at. 
  544. 		new_y = Prev_y 
  545. 	else	 
  546. 		if idx < visual_center + 1 or homie_count <= HOMIE_MAX_ITEMS then 
  547. 			--scrolling in top of list... 
  548. 			-- or no scrolling because there isn't enough homies...  
  549. 			new_y = 0 
  550. 		elseif idx > homie_count - visual_center then 
  551. 			--Scrolling in bottom of list... 
  552. 			new_y = -(homie_count - HOMIE_MAX_ITEMS) * move_height 
  553. 		else 
  554. 			--move the list... 
  555. 			new_y = -move_height * (idx - visual_center) 
  556. 		end 
  557. 	end 
  558. 	 
  559. 	local book_scroll_anim_h = vint_object_find("book_scroll_anim") 
  560. 	local book_scroll_twn_h = vint_object_find("book_scroll_twn") 
  561. 	 
  562. 	local contact_list_grp_h = vint_object_find("contact_list_grp") 
  563. 	local start_x, start_y = vint_get_property(contact_list_grp_h, "anchor") 
  564. 	local end_x = start_x 
  565. 	local end_y = new_y 
  566.  
  567. 	vint_set_property(book_scroll_twn_h, "start_value", 	start_x, start_y) 
  568. 	vint_set_property(book_scroll_twn_h, "end_value", 		end_x, 	end_y) 
  569. 	vint_set_property(book_scroll_twn_h, "end_event", "cell_phone_book_scroll_cb") 
  570. 	lua_play_anim(book_scroll_anim_h) 
  571. 	Book_screen_is_scrolling = true 
  572. 	 
  573. 	--we scrolled so update visual indices	 
  574. 	if new_y ~= Prev_y then 
  575. 		if idx > 1 then 
  576. 			Visible_start_idx = idx - 1 
  577. 		else 
  578. 			Visible_start_idx = 1 
  579. 		end	 
  580. 		 
  581. 		Visible_end_idx = Visible_start_idx + (HOMIE_MAX_ITEMS - 1)	 
  582. 	end 
  583. 	 
  584. 	Prev_y = new_y 
  585. end 
  586.  
  587. ------------------------------------------------------------------------------- 
  588. -- Select 
  589. ------------------------------------------------------------------------------- 
  590. function cell_phone_book_scroll_cb(event) 
  591. 	Book_screen_is_scrolling = false 
  592. end 
  593.  
  594. ------------------------------------------------------------------------- 
  595. -- Populate cellphone homie list 
  596. ------------------------------------------------------------------------------- 
  597. --	@param	index					index of homie_icon 
  598. -- @param	homie_name_crc			crc of homie name 
  599. -- @param	description_crc			crc of the description for homie... 
  600. -- @param	image_crc				image of the homie 
  601. -- @param	is_available			is the homie available? 
  602. function cell_phone_populate_list(homie_index, homie_name_crc, description_crc, image_crc, is_available) 
  603. 	 
  604. 	local idx = #Homie_data + 1 
  605. 	Homie_data[idx] = { 
  606. 		homie_index = homie_index, 
  607. 		homie_name_crc = homie_name_crc, 
  608. 		description_crc = description_crc,  
  609. 		image_crc = image_crc,  
  610. 		is_available = is_available, 
  611. 	} 
  612. end 
  613.  
  614. function cell_phone_book_nav_up(event, acceleration) 
  615.  
  616. 	if Book_screen_is_scrolling == true then 
  617. 		return 
  618. 	end 
  619. 	 
  620. 	--move up 
  621. 	local loop_count = 0 
  622. 	local num_items =  #Homie_data 
  623. 	local stop_loop = true 
  624. 	while stop_loop do 
  625. 		Homie_data_cur_idx = Homie_data_cur_idx - 1 
  626. 			 
  627. 		if Homie_data_cur_idx < 1 then 
  628. 			Homie_data_cur_idx = #Homie_data 
  629. 		end 
  630.  
  631. 		if Homie_data[Homie_data_cur_idx].is_available == true then 
  632. 			stop_loop = false 
  633. 		end 
  634. 		 
  635. 		if loop_count > num_items then 
  636. 			--Cannot nav... 
  637. 			return 
  638. 		else 
  639. 			loop_count = loop_count + 1 
  640. 		end 
  641. 	end 
  642. 	 
  643. 	--Play sound 
  644. 	game_UI_audio_play("UI_Cell_Nav") 
  645. 	 
  646. 	--Highlight current option... 
  647. 	cell_phone_book_highlight(Homie_data_cur_idx) 
  648. end 
  649.  
  650. function cell_phone_book_nav_down(event, acceleration) 
  651. 	 
  652. 	if Book_screen_is_scrolling == true then 
  653. 		return 
  654. 	end 
  655.  
  656. 	--move down 
  657. 	local loop_count = 0 
  658. 	local num_items =  #Homie_data 
  659. 	local stop_loop = true 
  660. 	while stop_loop do 
  661. 		Homie_data_cur_idx = Homie_data_cur_idx + 1 
  662. 		 
  663. 		if Homie_data_cur_idx > #Homie_data  then 
  664. 			Homie_data_cur_idx = 1 
  665. 		end 
  666.  
  667. 		if Homie_data[Homie_data_cur_idx].is_available == true then 
  668. 			stop_loop = false 
  669. 		end 
  670. 		 
  671. 		if loop_count > num_items then 
  672. 			--Cannot nav... 
  673. 			return 
  674. 		else 
  675. 			loop_count = loop_count + 1 
  676. 		end 
  677. 	end 
  678. 	 
  679. 	--Play sound 
  680. 	game_UI_audio_play("UI_Cell_Nav") 
  681. 	 
  682. 	--Highlight current option... 
  683. 	cell_phone_book_highlight(Homie_data_cur_idx) 
  684. end 
  685.  
  686.  
  687. function cell_phone_book_button_a(event, acceleration) 
  688. 	if Book_screen_is_scrolling == true then 
  689. 		return 
  690. 	end 
  691. 	--Call homie 
  692. 	local homie_index = Homie_data[Homie_data_cur_idx].homie_index 
  693. 	local is_available = Homie_data[Homie_data_cur_idx].is_available 
  694.  
  695. 	--Check if homie is available and then call if so... 
  696. 	if is_available == true then 
  697. 		--Lock inputs 
  698. 		Input_tracker:subscribe(false) 
  699. 		 
  700. 		--Call homie 
  701. 		cellphone_dial(homie_index, "cell_phone_dial_connection_cb", "cell_phone_call_hangup_cb") 
  702. 	end 
  703. end 
  704.  
  705. function cell_phone_book_button_b(event, acceleration) 
  706. 	cell_phone_exit(false) 
  707. end 
  708.  
  709. function cell_phone_book_button_map(event, acceleration)	 
  710. 	cell_phone_exit(true) 
  711. end 
  712.  
  713.  
  714. ------------------------------------------------------------------------------- 
  715. -- GARAGE 
  716. ------------------------------------------------------------------------------- 
  717.  
  718. ------------------------------------------------------------------------------- 
  719. -- Builds the garage list 
  720. ------------------------------------------------------------------------------- 
  721. function cell_phone_garage_build() 
  722. 	Garage_list_data = {} 
  723. 	Mouse_input_tracker_garage:remove_all()	 
  724. 	--Dataresponder to the garage... 
  725. 	vint_dataresponder_request("cell_phone_pad_populate", "cell_phone_garage_populate", 0, CELL_VEHICLE_LIST)	 
  726. 	if #Garage_list_data == 0 then 
  727. 		--no items in list... 
  728. 		return false 
  729. 	end 
  730. 	Garage_list:draw_items(Garage_list_data, 1, GARAGE_LIST_WIDTH, GARAGE_LIST_MAX_BUTTONS) 
  731. 	 
  732. 	Garage_list:add_mouse_inputs("cell_phone", Mouse_input_tracker_garage, 50)	 
  733. 	Garage_hint_bar:add_mouse_inputs("cell_phone", Mouse_input_tracker_garage_hint, 50) 
  734. 	 
  735. 	Mouse_input_tracker_garage:subscribe(true) 
  736. 	Mouse_input_tracker_garage_hint:subscribe(true) 
  737. end 
  738.  
  739. function cell_phone_garage_populate(vehicle_index, vehicle_name, repair_cost) 
  740. 	--Add item to list... 
  741. 	local idx = #Garage_list_data + 1 
  742. 	Garage_list_data[idx] = { 
  743. 		type = TYPE_BUTTON, 
  744. 		label 			= vehicle_name, 
  745. 		id 				= 	vehicle_index, 
  746. 		repair_cost 	= 	repair_cost, 
  747. 	} 
  748. end 
  749.  
  750. function cell_phone_garage_no_vehicle_cb() 
  751. 	Input_tracker:subscribe(true) 
  752. end 
  753.  
  754. function cell_phone_garage_no_vehicles_dialog() 
  755. 	-- TODO: localize 
  756. 	dialog_box_message("CELL_PHONE_NO_VEHICLES", 
  757. 							"CELL_PHONE_MUST_ADD_VEHICLES", 
  758. 							nil, 
  759. 							nil, 
  760. 							"cell_phone_garage_no_vehicle_cb" 
  761. 	) 
  762. end 
  763.  
  764. function cell_phone_garage_map() 
  765. 	-- do nothing 
  766. end 
  767.  
  768. function cell_phone_garage_nav_up() 
  769. 	Garage_list:move_cursor(-1) 
  770. end 
  771.  
  772. function cell_phone_garage_nav_down() 
  773. 	Garage_list:move_cursor(1) 
  774. end 
  775.  
  776. function cell_phone_garage_button_a() 
  777. 	-- Attempt to retrive vehicle 
  778.  
  779. 	-- Get current selected vehicle data... 
  780. 	local data = Garage_list:return_selected_data() 
  781. 	local repair_cost = data.repair_cost  
  782. 	 
  783. 	--Check if player has enough cash 
  784. 	if Cell_phone_cash < repair_cost then 
  785. 		--Not enough cash dialog 
  786. 		dialog_box_message("CELL_VEHICLE_DIALOG_NO_CASH_HEADER","CELL_VEHICLE_DIALOG_NO_CASH_BODY") 
  787. 		return 
  788. 	end 
  789.  
  790. 	--Repair and Deliver if player has enough cash. 
  791. 	if repair_cost == 0 then 
  792. 		--Deliver if repair price = 0 
  793. 		cellphone_choose_vehicle(data.id) 
  794. 	 
  795. 		--Exit phone... 
  796. 		cell_phone_exit(true) 
  797. 		return 
  798. 	end 
  799. 	 
  800. 	--Car needs repairs, prepare localized dialog and display 
  801. 	 
  802. 	if repair_cost ~= 0 then 
  803. 		local values = {[0] = repair_cost} 
  804. 		local dialog_repairs_body = vint_insert_values_in_string("CELL_VEHICLE_DIALOG_REPAIRS_BODY", values) 
  805. 		dialog_box_confirmation("CELL_VEHICLE_DIALOG_REPAIRS_HEADER", dialog_repairs_body, "cellphone_garage_get_car_dialog_cb") 
  806. 	else  
  807. 		cellphone_choose_vehicle(data.id) 
  808. 		cell_phone_exit(true) 
  809. 	end 
  810. end 
  811.  
  812. function cell_phone_garage_button_b() 
  813. 	-- Nav back to homie list... 
  814. 	-- Nav back to homie list... 
  815. 	cell_phone_menu_show(CELL_PHONE_MENU_BOOK, CELL_MENU_TRANS_LEFT) 
  816. end 
  817.  
  818. function cell_phone_garage_button_map() 
  819. end 
  820.  
  821. ------------------------------------------------------------------------------- 
  822. -- Dialog response after selecting an option on the repair menu... 
  823. ------------------------------------------------------------------------------- 
  824. function cellphone_garage_get_car_dialog_cb(result, action) 
  825. 	if result == 0 then 
  826. 		--Result is good, retreive the car... 
  827. 		local vehicle_id = Garage_list:get_id() 
  828. 		cellphone_choose_vehicle(vehicle_id) 
  829. 		--Exit back to game... 
  830. 		cell_phone_exit(true) 
  831. 	end 
  832. 	 
  833. 	if result == 1 then 
  834. 		-- go back to the menu 
  835. 		return 
  836. 	end 
  837.  
  838. end 
  839.  
  840. ------------------------------------------------------------------------------- 
  841. -- Called when the game wants to hang up the phone... 
  842. -- This gets called after we dial... 
  843. -- @param is_busy 
  844. ------------------------------------------------------------------------------ 
  845. function cell_phone_call_build(is_busy) 
  846.  
  847. 	--Get homie data we need... 
  848. 	local homie_name_crc = Homie_data[Homie_data_cur_idx].homie_name_crc	 
  849. 	local image_crc = Homie_data[Homie_data_cur_idx].image_crc 
  850. 	 
  851. 	local call_contact_grp_h = vint_object_find("call_contact_grp")  
  852. 	 
  853. 	--Set text... 
  854. 	local call_name_txt_h = vint_object_find("call_name_txt", call_contact_grp_h) 
  855. 	vint_set_property(call_name_txt_h, "text_tag_crc", homie_name_crc) 
  856. 	 
  857. 	--Make sure it fits in the phone... 
  858. 	cell_phone_resize_text_element(call_name_txt_h, CELL_PHONE_CALL_MAX_WIDTH_LABEL) 
  859. 	 
  860. 	--Set icon 
  861. 	local call_icon_bmp_h = vint_object_find("call_icon_bmp", call_contact_grp_h) 
  862. 	vint_set_property(call_icon_bmp_h, "image_crc", image_crc) 
  863.  
  864. 	local calling_info_txt_h = vint_object_find("calling_info_txt")  
  865. 	if is_busy then 
  866. 		vint_set_property(calling_info_txt_h, "text_tag", "CELL_PHONE_BUSY") 
  867. 	else 
  868. 		vint_set_property(calling_info_txt_h, "text_tag", "CELL_PHONE_IN_CALL") 
  869. 	end 
  870. end 
  871.  
  872. -------------------------------------------------------------------------- 
  873. -- Called when the game wants to hang up the phone... 
  874. -- This gets called after we dial... 
  875. -- @param success			(CELL_CALL_HANGUP, CELL_CALL_RETURN_TO_PHONE) 
  876. ------------------------------------------------------------------------------- 
  877. function cell_phone_call_hangup_cb(success) 
  878. 	debug_print("vint", "cell_phone_call_hangup_cb()\n") 
  879. 	 
  880. 	if success == CELL_CALL_HANGUP then 
  881. 		--exit back to game.... 
  882. 		cell_phone_exit(true) 
  883. 	elseif success == CELL_CALL_RETURN_TO_PHONE then 
  884. 		--Return to phone 
  885. 		cell_phone_menu_show(CELL_PHONE_MENU_BOOK, CELL_MENU_TRANS_LEFT) 
  886. 	else 
  887. 		-- handle any other case exit back to game... 
  888. 		cell_phone_exit(true) 
  889. 	end 
  890. end 
  891.  
  892. -------------------------------------------------------------------------------- 
  893. -- Call screen input.. 
  894. -------------------------------------------------------------------------------- 
  895. function cell_phone_call_input(event) 
  896. 	--do something here 
  897. 	if event == "select" or event == "back" or event == "map" then 
  898. 		--exit to game... 
  899. 		cell_phone_exit(true) 
  900. 	end 
  901. end 
  902.  
  903. ------------------------------------------------------------------------------- 
  904. -- Updates player cash for this screen...  
  905. -- uses a hud data item and gets the first element from it. 
  906. ------------------------------------------------------------------------------- 
  907. function cell_phone_cash_update(di_h) 
  908. 	local cash = vint_dataitem_get(di_h) 
  909. 	Cell_phone_cash = floor(cash) 
  910. end 
  911.  
  912. ------------------------------------------------------------------------------- 
  913. -- Exits to a menu or back to game... 
  914. ------------------------------------------------------------------------------- 
  915. function cell_phone_exit(exit_to_game) 
  916. 	-- Next time come back to phone main... 
  917. 	vint_dataresponder_post("cell_menu_state_dr", "Set", ID_MAIN)  
  918. 	 
  919. 	--Unsubscribe from all controls while we make our transition... 
  920. 	Input_tracker:subscribe(false) 
  921. 	Input_tracker_garage:subscribe(false) 
  922. 	Input_tracker_call:subscribe(false) 
  923. 	 
  924. 	if exit_to_game then 
  925. 		--Exit to game... 
  926. 		cell_transition_screen(CELL_STATE_OUT, CELL_SCREEN_NONE, CELL_SCREEN_PHONE, cell_phone_exit_to_game) 
  927. 		game_UI_audio_play("UI_Cell_Nav_Back") 
  928. 	else 
  929. 		--Exit to main... 
  930. 		cell_transition_screen(CELL_STATE_PORTRAIT, CELL_SCREEN_MAIN, CELL_SCREEN_PHONE, cell_phone_exit_to_main) 
  931. 		game_UI_audio_play("UI_Cell_Close") 
  932. 	end 
  933. end 
  934.  
  935. function cell_phone_exit_to_main() 
  936. 	pop_screen()	 
  937. end 
  938.  
  939. function cell_phone_exit_to_game() 
  940. 	pop_screen() -- cell phone 
  941. 	pop_screen() -- cell main 
  942. 	pop_screen() -- cell fore/background	 
  943. end 
  944.  
  945. ------------------------------------------------------------------------------- 
  946. -- resize a specific text element... 
  947. ------------------------------------------------------------------------------- 
  948. function cell_phone_resize_text_element(element_h, max_width) 
  949. 	vint_set_property(element_h, "scale", 1, 1) 
  950. 	local text_width, text_height = element_get_actual_size(element_h)	 
  951.  
  952. 	if text_width > max_width then 
  953. 		local text_scale = max_width/text_width 
  954. 		vint_set_property(element_h, "scale", text_scale, text_scale) 
  955. 	end 
  956. end 
  957.  
  958. ------------------------------------------------------------------------------- 
  959. -- Mouse specific functions... 
  960. ------------------------------------------------------------------------------- 
  961.  
  962. --Search through active buttons and determine if the mouse is over a valid target 
  963. -- 
  964. function cell_phone_get_valid_handle(target_handle) 
  965. 	for idx, cur_selection in pairs(Homie_data) do 
  966. 		if cur_selection.h ~= nil and cur_selection.h == target_handle then			 
  967. 			--if selection is visible then return idx 
  968. 			if idx >= Visible_start_idx and idx <= Visible_end_idx then 
  969. 				return idx 
  970. 			end			 
  971. 		end 
  972. 	end 
  973. 	 
  974. 	return MOUSE_INVALID_HANDLE	 
  975. end 
  976.  
  977. function cell_phone_mouse_click(event, target_handle)	 
  978. 	local hint_index = Hint_bar:get_hint_index(target_handle) 
  979. 	if hint_index == 1 then 
  980. 		cell_phone_book_button_b() 
  981. 	end 
  982.  
  983. 	local phone_index =  cell_phone_get_valid_handle(target_handle) 
  984. 	if phone_index ~= MOUSE_INVALID_HANDLE then 
  985. 		cell_phone_book_button_a(event, nil) 
  986. 	end 
  987. 		 
  988. 	local garage_hint_index = Garage_hint_bar:get_hint_index(target_handle) 
  989. 	if garage_hint_index == 1 then 
  990. 		cell_phone_garage_button_b() 
  991. 	end 
  992. 	 
  993. 	local garage_idx = Garage_list:get_button_index(target_handle) 
  994. 	if garage_idx ~= 0 then 
  995. 		Garage_list:set_selection(garage_idx) 
  996. 		cell_phone_garage_button_a(event, nil) 
  997. 	end	 
  998. end 
  999.  
  1000. function cell_phone_mouse_move(event, target_handle)	 
  1001. 	-- Phone book inputs 
  1002. 	Hint_bar:set_highlight(0) 
  1003. 		 
  1004. 	local hint_index = Hint_bar:get_hint_index(target_handle) 
  1005. 	if hint_index ~= 0 then 
  1006. 		Hint_bar:set_highlight(hint_index) 
  1007. 		game_UI_audio_play("UI_Cell_Nav") 
  1008. 	end 
  1009. 	 
  1010. 	local phone_index = cell_phone_get_valid_handle(target_handle)	 
  1011. 	if phone_index ~= MOUSE_INVALID_HANDLE then 
  1012. 		cell_phone_book_highlight(phone_index, true) 
  1013. 		game_UI_audio_play("UI_Cell_Nav") 
  1014. 	end		 
  1015. 	 
  1016. 	-- Garage inputs 
  1017. 	Garage_hint_bar:set_highlight(0) 
  1018. 	 
  1019. 	local garage_hint_index = Garage_hint_bar:get_hint_index(target_handle) 
  1020. 	if garage_hint_index ~= 0 then 
  1021. 		Garage_hint_bar:set_highlight(garage_hint_index) 
  1022. 		game_UI_audio_play("UI_Cell_Nav") 
  1023. 	end 
  1024. 	 
  1025. 	local old_index = Garage_list:get_selection() 
  1026. 	local new_index = Garage_list:get_button_index(target_handle) 
  1027. 	 
  1028. 	if new_index ~= 0 and new_index ~= old_index then 
  1029. 		Garage_list:set_selection(new_index) 
  1030. 		Garage_list:move_cursor(0, true) 
  1031. 		 
  1032. 		-- If the item has a callback for navigation, do it 
  1033. 		local data_item = Garage_list:return_selected_data() 
  1034. 		if data_item.on_nav ~= nil then 
  1035. 			data_item.on_nav(data_item) 
  1036. 		end 
  1037. 	end	 
  1038. end 
  1039.  
  1040. function cell_phone_mouse_drag(event, target_handle, mouse_x, mouse_y, scroll_lines) 
  1041. 	if Scrollbar.tab.handle == target_handle then 
  1042. 		local new_start_index = Scrollbar:drag_scrolltab(mouse_y, #Homie_data) 
  1043. 		 
  1044. 		--don't highlight anything, just scroll the list. 
  1045. 		cell_phone_book_highlight(new_start_index, false, true) 
  1046. 	end 
  1047. 	 
  1048. 	if Garage_list.scrollbar.tab.handle == target_handle then 
  1049. 		local new_start_index = Garage_list.scrollbar:drag_scrolltab(mouse_y, Garage_list.num_buttons - (Garage_list.max_buttons - 1)) 
  1050. 		 
  1051. 		--scroll Garage list 
  1052. 		Garage_list:scroll_list(0, new_start_index) 
  1053. 	end 
  1054. end 
  1055.  
  1056. -- Updates the mouse inputs for the list and snaps the scrolltab to the closest notch based on the visible index 
  1057. -- 
  1058. function cell_phone_mouse_drag_release(event, target_handle, mouse_x, mouse_y) 
  1059. 	-- scroll phone book 
  1060. 	if Scrollbar.tab.handle == target_handle then 
  1061. 		Scrollbar:release_scrolltab(Homie_data_cur_idx, #Homie_data) 
  1062. 	end 
  1063. 	 
  1064. 	-- scroll garage list and update mouse inputs 
  1065. 	if Garage_list.scrollbar.tab.handle == target_handle then 
  1066. 		local start_index = Garage_list:get_visible_indices() 
  1067. 		Garage_list.scrollbar:release_scrolltab(start_index, Garage_list.num_buttons - (Garage_list.max_buttons - 1)) 
  1068. 		Garage_list:update_mouse_inputs("cell_phone",Mouse_input_tracker_garage,50) 
  1069. 	end	 
  1070. end 
  1071.  
  1072. function cell_phone_mouse_scroll(event, target_handle, mouse_x, mouse_y, scroll_lines)			 
  1073. 	--scroll lines are inverted for some reason 
  1074. 	scroll_lines = scroll_lines * -1 
  1075. 	 
  1076. 	-- scroll garage list if in garage 
  1077. 	if Menu_active == CELL_PHONE_MENU_GARAGE then 
  1078. 		if scroll_lines ~= 0 then 
  1079. 			Garage_list:scroll_list(scroll_lines) 
  1080. 			Garage_list:update_mouse_inputs("cell_phone",Mouse_input_tracker_garage,50)			 
  1081. 		end	 
  1082. 	else	 
  1083. 		local homie_count = #Homie_data	 
  1084. 		--if list has enough items to scroll then allow mouse wheel 
  1085. 		if homie_count > 4 then	 
  1086. 			local new_index = Homie_data_cur_idx 
  1087. 			new_index = Homie_data_cur_idx + scroll_lines 
  1088. 			 
  1089. 			if new_index >= 1 and new_index < homie_count then 
  1090. 				cell_phone_book_highlight(new_index, false, true) 
  1091. 			end	 
  1092. 		end 
  1093. 	end 
  1094. end 
  1095.