./vdo_dialog.lua

  1. -- Inherited from Vdo_base_object 
  2. Vdo_dialog = Vdo_base_object:new_base() 
  3.  
  4. -- Global Locals 
  5. local DIALOG_ALIGN_CENTER 	= 0 
  6. local DIALOG_ALIGN_LEFT		= 1 
  7.  
  8. local DIALOG_BOX_MIN_WIDTH = 450 
  9. local DIALOG_BOX_DEFAULT_TEXT_LINES = 11 
  10.  
  11. local DIALOG_BOX_CONTENT_START_X 			= 9 
  12. local DIALOG_BOX_CONTENT_START_Y 			= 36 
  13. local DIALOG_BOX_SPINNER_SIZE 				= 80					 
  14. local DIALOG_BOX_SPINNER_PADDING				= 20					 
  15. local DIALOG_BOX_CONTENT_VERTICAL_SPACING = 10 
  16. local DIALOG_BOX_CONTENT_OPTIONS_SPACING 	= 34 
  17. local DIALOG_BOX_CONTENT_OPTIONS_HORIZONTAL_SPACING 	= 20 
  18. local DIALOG_BOX_CONTENT_OPTIONS_HORIZONTAL_OFFSET = 20 
  19. local DIALOG_BOX_SCROLLBAR_WIDTH	= 18 								--width of scrollbar... 
  20. local DIALOG_BOX_SCROLLBAR_PADDING	= 10 							--spacing for scrollbar ... 
  21. local DIALOG_BOX_TEXT_MASK_PADDING	= 5 							--Padding for mask on text... 
  22.  
  23. local DIALOG_BOX_TEXT_UNSELECTED 	= {R = 218/255, G = 226/255; B = 230/255} 
  24. local DIALOG_BOX_TEXT_SELECTED		= {R = 0/255, G = 0/255; B = 0/255} 
  25.  
  26. -- Widget types... 
  27. DIALOG_WIDGET_TYPE_OPTION 		= 0 
  28. DIALOG_WIDGET_TYPE_TITLE	 	= 1 
  29. DIALOG_WIDGET_TYPE_TEXT			= 2 
  30. DIALOG_WIDGET_TYPE_IMAGE		= 3 
  31. DIALOG_WIDGET_TYPE_SPINNER		= 4 
  32.  
  33. DIALOG_ACTION_NONE 				= -1 
  34. DIALOG_ACTION_SELECT				= 0 
  35. DIALOG_ACTION_BACK				= 1 
  36.  
  37. --init dialog script 
  38. function vdo_dialog_init() 
  39. end 
  40.  
  41. --cleanup dialog script 
  42. function vdo_dialog_cleanup() 
  43. end 
  44.  
  45. ------------------------------------------------------------------------------- 
  46. -- Init Dialog VDO! 
  47. ------------------------------------------------------------------------------- 
  48. function Vdo_dialog:init() 
  49. 	self.header = "" 
  50. 	self.base_content_h = vint_object_find("content", self.handle) 
  51. 	self.previous_content_h = -1 
  52. 	 
  53. 	--Configure highlight for  
  54. 	self.highlight = Vdo_button_highlight:new("options_highlight", self.base_content_h) 
  55. 	self.highlight:show_button(CTRL_MENU_BUTTON_A) 
  56. 	 
  57. 	local h = vint_object_find("spinner_obj", self.handle) 
  58. 	vint_set_property(h, "visible", false) 
  59. 	vint_set_property(h, "visible", false) 
  60. 	local h = vint_object_find("text_obj", self.handle) 
  61. 	vint_set_property(h, "visible", false) 
  62. 	local h = vint_object_find("options_obj", self.handle) 
  63. 	vint_set_property(h, "visible", false) 
  64. 	local h = vint_object_find("hint_bar_grp", self.handle) 
  65. 	vint_set_property(h, "visible", false) 
  66. 	self.hint_bar = Vdo_hint_bar:new("hint_bar", self.handle) 
  67. 	 
  68. 	local h = vint_object_find("dialog_img", self.handle) 
  69. 	vint_set_property(h, "visible", false) 
  70. 	 
  71. 	--Store references to shadow... 
  72. 	self.shadow = {} 
  73. 	self.shadow.nw		= vint_object_find("shadow_nw", self.handle) 
  74. 	self.shadow.n		= vint_object_find("shadow_n", self.handle) 
  75. 	self.shadow.ne		= vint_object_find("shadow_ne", self.handle) 
  76. 	self.shadow.e 		= vint_object_find("shadow_e", self.handle) 
  77. 	self.shadow.se 	= vint_object_find("shadow_se", self.handle) 
  78. 	self.shadow.s 		= vint_object_find("shadow_s", self.handle) 
  79. 	self.shadow.sw 	= vint_object_find("shadow_sw", self.handle) 
  80. 	self.shadow.w 		= vint_object_find("shadow_w", self.handle) 
  81. 	 
  82. 	--Get and store the size of the body text element... 
  83. 	local h = vint_object_find("body_txt", self.handle) 
  84. 	vint_set_property(h, "text_tag", "XXXX") 
  85. 	local width, height = element_get_actual_size(h) 
  86. 	self.text_line_height = height 
  87. 	 
  88. 	self.alignment = DIALOG_ALIGN_CENTER 
  89. 	 
  90. 	self.current_dialog	 = -1 
  91. end 
  92.  
  93. --[[ 
  94. 	Dialogs[handle] = { 
  95. 		base_object = -1, 
  96. 		header = -1, 
  97. 		widgets = {}, 
  98. 		widget_count = 0, 
  99. 	} 
  100. ]] 
  101. ------------------------------------------------------------------------------- 
  102. -- Creates the dialog data.... 
  103. -- 
  104. -- @param	dialog_data			{ full of data...} 
  105. -- @param 	do_morph				bool (true or false) 
  106. ------------------------------------------------------------------------------- 
  107. function Vdo_dialog:create(dialog_data, do_morph, morph_complete_cb) 
  108.  
  109. 	if self.morph_playing == true then 
  110. 		self:morph_complete() 
  111. 	end 
  112. 	 
  113. 	if do_morph == true then 
  114. 		--Need to clone and delete old dialog content when finished... 
  115. 		--our morph callback will handle any remaining cleanup.. 
  116. 		self.previous_content_h = vint_object_clone(self.base_content_h) 
  117. 		 
  118. 		--Move content behind new content... 
  119. 		vint_set_property(self.previous_content_h, "depth", 5000) 
  120. 		 
  121. 		if morph_complete_cb ~= nil then 
  122. 			self.morph_complete_cb = morph_complete_cb 
  123. 		else 
  124. 			self.morph_complete_cb = nil 
  125. 		end 
  126. 	else 
  127. 		self.morph_complete_cb = nil 
  128. 	end 
  129. 	 
  130. 	-- Clear out old dialog cloned objects out of our current dialog... 
  131. 	if self.current_dialog ~= -1 then 
  132. 		local clones = self.current_dialog.widget_clones 
  133. 		for key, val in pairs(clones) do  
  134. 			vint_object_destroy(val) 
  135. 		end 
  136. 	end 
  137.  
  138.  
  139. 	--hide all objects that we clone from... 
  140. 	local widget_h = vint_object_find("text_obj", self.base_content_h) 
  141. 	vint_set_property(widget_h, "visible", false) 
  142. 	widget_h = vint_object_find("dialog_img", self.base_content_h) 
  143. 	vint_set_property(widget_h, "visible", false) 
  144. 	widget_h = vint_object_find("spinner_obj", self.base_content_h) 
  145. 	vint_set_property(widget_h, "visible", false) 
  146. 	widget_h = vint_object_find("options_obj", self.base_content_h) 
  147. 	vint_set_property(widget_h, "visible", false) 
  148. 	widget_h = vint_object_find("hint_bar_grp", self.base_content_h) 
  149. 	vint_set_property(widget_h, "visible", false) 
  150. 	 
  151. 	--Reset current dialog table... 
  152. 	self.current_dialog = {} 
  153.  
  154. 	-- handle body... 
  155. 	local title_txt = "" 
  156. 		 
  157. 	local options = {} 
  158. 	local option_count = 0 
  159. 	local selected_index = 0 
  160. 	 
  161. 	-- Tables and variables used to keep track of cloned objects... 
  162. 	self.current_dialog.widgets = {} 
  163. 	self.current_dialog.widget_clones = {} 
  164. 	self.current_dialog.option_has_clone 	= false 
  165. 	self.current_dialog.text_has_clone 		= false 
  166. 	self.current_dialog.image_has_clone 	= false 
  167. 	self.current_dialog.spinner_has_clone 	= false 
  168. 			 
  169. 	local widgets = {} 
  170. 	local widgets_count 		= 0 
  171. 	local widgets_width		= 0 
  172. 	local widgets_height		= DIALOG_BOX_CONTENT_START_Y			--Default height for widgets, in case there are none. 
  173. 	 
  174. 	--loop through widgets and unpack them into objects...... 
  175. 	for i = 0, dialog_data.widgets_count - 1 do 
  176. 		local widget = dialog_data[i]			 
  177. 		local widget_type = widget.type 
  178. 		local widget_h							-- Handle to current widget... 
  179. 		local do_position_widget = true	-- Should we position the widget? 
  180. 		local num_lines	= 0 
  181. 		local width 		= 0					-- Used to position the widgets... 
  182. 		local height 		= 0 					-- Used to position the widgets... 
  183. 		local is_waiting 	= widget.is_waiting or false 
  184. 		 
  185. 		--process odd type widgets first... 
  186. 		if widget_type == DIALOG_WIDGET_TYPE_TITLE then 
  187. 			-- Store  title to use later... 
  188. 			title_txt = widget.title 
  189. 			 
  190. 			do_position_widget = false 
  191. 		elseif widget_type == DIALOG_WIDGET_TYPE_OPTION then 
  192. 			-- Store options to process later... 
  193. 			options[option_count] =  { 
  194. 				has_second_option = widget.has_second_option, 
  195. 				tag_1		 	= widget.tag_1, 
  196. 				tag_2 		= widget.tag_2, 
  197. 				option_id 	= widget.option_id, 
  198. 				disabled 		= widget.disabled, 
  199. 			} 
  200. 			 
  201. 			--Set current option to be selected if we are... 
  202. 			if widget.selected == true then 
  203. 				selected_index = widget.option_id 
  204. 			end 
  205. 			 
  206. 			option_count = option_count + 1 
  207. 			do_position_widget = false 
  208. 		elseif widget_type == DIALOG_WIDGET_TYPE_TEXT then 
  209. 			--Text field for dialog... 
  210. 			local text_tag		= 	widget.text_tag 
  211. 			num_lines 			=	widget.num_lines  
  212.  
  213. 			if not is_waiting  then 
  214. 				if self.current_dialog.text_has_clone == false then 
  215. 					widget_h = vint_object_find("text_obj", self.base_content_h) 
  216. 					self.current_dialog.text_has_clone = true 
  217. 				else 
  218. 					local h = vint_object_find("text_obj", self.base_content_h) 
  219. 					widget_h = vint_object_clone(h) 
  220. 					self:add_clone_to_list(widget_h) 
  221. 				end 
  222. 				 
  223. 				local body_txt_h = vint_object_find("body_txt", widget_h) 
  224. 				if num_lines ~= 0 then 
  225. 					vint_set_property(body_txt_h, "text_tag_crc", text_tag) 
  226. 				else 
  227. 					vint_set_property(body_txt_h, "text_tag", text_tag) 
  228. 				end 
  229. 					 
  230. 				width, height = element_get_actual_size(body_txt_h) 
  231. 				vint_set_property(widget_h, "visible", true) 
  232. 			else 
  233. 				widget_h = vint_object_find("hint_bar_grp") 
  234. 				local data = { 
  235. 					{CTRL_MENU_BUTTON_B, "CONTROL_CANCEL"}, 
  236. 				} 
  237. 				self.hint_bar:set_hints(data) 
  238. 				height = self.text_line_height + 5 
  239. 				vint_set_property(widget_h, "visible", true) 
  240. 			end 
  241. 		elseif widget_type == DIALOG_WIDGET_TYPE_IMAGE then 
  242. 			--Image field for dialog... 
  243. 			local image_name 	= 	widget.image_name 
  244. 			 
  245. 			if self.current_dialog.image_has_clone == false then 
  246. 				widget_h = vint_object_find("dialog_img", self.base_content_h) 
  247. 				self.current_dialog.image_has_clone = true 
  248. 			else 
  249. 				local h = vint_object_find("dialog_img", self.base_content_h) 
  250. 				widget_h = vint_object_clone(h) 
  251. 				self:add_clone_to_list(widget_h) 
  252. 			end 
  253. 			 
  254. 			vint_set_property(widget_h, "visible", true) 
  255. 			vint_set_property(widget_h, "image", image_name) 
  256. 			width, height = element_get_actual_size(widget_h) 
  257. 		elseif widget_type == DIALOG_WIDGET_TYPE_SPINNER then 
  258. 			--Spinner field for dialog... 
  259. 			local spinner_txt = widget.spinner_txt 
  260. 			widget_h = vint_object_find("spinner_obj", self.base_content_h) 
  261. 			vint_set_property(widget_h, "visible", true) 
  262. 			 
  263. 			--Set text tag of spinner... 
  264. 			local spinner_txt_h = vint_object_find("spinner_txt", widget_h) 
  265. 			local spinner_txt_width, spinner_txt_height = element_get_actual_size(spinner_txt_h) 
  266. 			local spinner_txt_x, spinner_txt_y = vint_get_property(spinner_txt_h, "anchor") 
  267. 			vint_set_property(spinner_txt_h, "text_tag", spinner_txt) 
  268. 			 
  269. 			--Clone and target animation... 
  270. 			local spinner_anim_h = vint_object_find("spinner_anim", self.handle) 
  271. 			vint_set_property(spinner_anim_h, "target_handle", widget_h)  
  272. 			vint_set_property(spinner_anim_h, "is_paused", false) 
  273. 			 
  274. 			--get width/height for box... 
  275. 			local spinner_gfx_h = vint_object_find("spinner_gfx_1", self.base_content_h) 
  276. 			width = spinner_txt_width 
  277. 			height = DIALOG_BOX_SPINNER_SIZE 
  278. 		end 
  279. 		 
  280. 		if do_position_widget == true then 
  281. 			--store widget data for alignment later... 
  282. 			widgets[widgets_count] = { 
  283. 				h = widget_h, 
  284. 				type = widget_type, 
  285. 				width = width, 
  286. 				height = height, 
  287. 				num_lines = num_lines, 
  288. 				is_waiting = is_waiting, 
  289. 			} 
  290. 			widgets_count = widgets_count + 1 
  291. 			 
  292. 			widgets_width = max(widgets_width, width) 
  293. 		end 
  294. 	end 
  295. 	widgets.widgets_count = widgets_count 
  296. 	 
  297. 		 
  298. 	--Set Title 
  299. 	local title_txt_obj = Vdo_base_object:new("title_txt", self.base_content_h) 
  300. 	title_txt_obj:set_text(title_txt) 
  301. 	 
  302. 	local title_width, title_height = title_txt_obj:get_actual_size() 
  303. 	title_width = title_width + 6	--for padding 
  304. 	-- Build options... 
  305. 	 
  306. 	-- Position base options  
  307. 	local options_h = vint_object_find("options_obj", self.base_content_h) 
  308. 	local option_h = vint_object_find("option", options_h) 
  309. 	local option_1_width 
  310. 	local option_2_width 
  311. 	local option_1_largest_width = 0 
  312. 	local option_1_with_second_option_largest_width = 0 		 
  313. 	local option_2_largest_width = 125 	-- This is also the default width of the text box... Approximatly 8 characters... 
  314. 	if game_get_platform() == "PC" then 
  315. 		option_2_largest_width = 250 -- Double it on PC so typing directly in it isn't so jarring 
  316. 	end 
  317. 	local x = 0  
  318. 	local y = 0 
  319. 	for i = 0, option_count - 1 do 
  320. 		local current_option_h  
  321. 		local option_is_clone = false 
  322. 		if i == 0 then 
  323. 			current_option_h = option_h 
  324. 			x, y = vint_get_property(current_option_h, "anchor") 
  325. 		else 
  326. 			current_option_h = vint_object_clone(option_h) 
  327. 			y = y + DIALOG_BOX_CONTENT_OPTIONS_SPACING	 
  328. 			option_is_clone = true 
  329. 		end 
  330.  
  331. 		local option_txt_1_h = vint_object_find("option_txt_1", current_option_h) 
  332. 		local option_txt_2_h = vint_object_find("option_txt_2", current_option_h) 
  333. 		local option_2_grp_h = vint_object_find("option_2_grp", current_option_h) 
  334. 		 
  335. 		vint_set_property(current_option_h, "anchor", x, y) 
  336. 		 
  337. 		--force tags to nothing if no data was sent in... 
  338. 		if options[i].tag_1 == nil then 
  339. 			options[i].tag_1 = "" 
  340. 		end 
  341. 		 
  342. 		if options[i].tag_2 == nil then 
  343. 			options[i].tag_2 = "" 
  344. 		end 
  345. 		 
  346. 		--Set text tags... 
  347. 		vint_set_property(option_txt_1_h, "text_tag", options[i].tag_1) 
  348. 		vint_set_property(option_txt_2_h, "text_tag", options[i].tag_2) 
  349. 		 
  350. 		 
  351. 		--Find largest elements for alignment later... 
  352. 		option_1_width = element_get_actual_size(option_txt_1_h) 
  353. 		option_2_width = element_get_actual_size(option_txt_2_h) 
  354. 		 
  355. 		option_1_largest_width = max(option_1_width, option_1_largest_width) 
  356. 		 
  357. 		--Do we show the second option? 
  358. 		if options[i].has_second_option == true then 
  359. 			vint_set_property(option_2_grp_h, "visible", true) 
  360. 			--Now calculate the width of the largest first option with a second option... 
  361. 			option_1_with_second_option_largest_width = max(option_1_width, option_1_with_second_option_largest_width) 
  362. 			option_2_largest_width = max(option_2_width, option_2_largest_width) 
  363. 		else 
  364. 			vint_set_property(option_2_grp_h, "visible", false) 
  365. 		end 
  366. 		 
  367.  
  368. 		options[i].h = current_option_h 
  369. 	 
  370. 		--Add to widget clone table if option is clone... 
  371. 		if option_is_clone then 
  372. 			self.current_dialog.widget_clones[i] = current_option_h 
  373. 		end 
  374. 	end 
  375. 	 
  376. 	-- Align second options... 
  377. 	-- todo align right side of box to width of the shit... 
  378. 	for i = 0, option_count - 1 do 
  379. 		local current_option_h = options[i].h  
  380. 		local option_txt_1_h = vint_object_find("option_txt_1", current_option_h) 
  381. 		local option_2_grp_h = vint_object_find("option_2_grp", current_option_h) 
  382. 		local x, y = vint_get_property(option_txt_1_h, "anchor") 
  383. 		vint_set_property(option_2_grp_h, "anchor", x + option_1_with_second_option_largest_width + DIALOG_BOX_CONTENT_OPTIONS_HORIZONTAL_SPACING, y) 
  384. 		 
  385. 		--Set size of option2 box, + 10 to account for padding... 
  386. 		local option_2_box_width = option_2_largest_width + 10 
  387. 		 
  388. 		--Resize background  
  389. 		local box_bg_h = vint_object_find("option_box_bg", current_option_h) 
  390. 		local box_bg_width, box_bg_height = element_get_actual_size(box_bg_h) 
  391. 		element_set_actual_size(box_bg_h, option_2_box_width - 4, box_bg_height)	--its the box width.. - 4 is the width of the size so we subtract it... 
  392. 		 
  393. 		--Resize the north and south sides of the box... 
  394. 		local box_n_h = vint_object_find("option_box_n", current_option_h) 
  395. 		local box_s_h = vint_object_find("option_box_s", current_option_h) 
  396. 		 
  397. 		local box_width, box_height = element_get_actual_size(box_n_h) 
  398. 		element_set_actual_size(box_n_h, option_2_box_width, box_height) 
  399. 		element_set_actual_size(box_s_h, option_2_box_width, box_height) 
  400. 		 
  401. 		--Reposition right side of box... 
  402. 		local box_e_h = vint_object_find("option_box_e", current_option_h) 
  403. 		local box_x, box_y  = vint_get_property(box_e_h, "anchor") 
  404. 		vint_set_property(box_e_h, "anchor", option_2_box_width, box_y) 
  405. 	end 
  406. 	 
  407. 	local options_height 
  408. 	 
  409. 	--the largest width is either the first option or the combined width of first option or second option... 
  410. 	local options_largest_width = max(option_1_largest_width, option_1_with_second_option_largest_width + option_2_largest_width + 5) 
  411. 	 
  412. 	--calculate the total width of the options... 
  413. 	local options_width = x + options_largest_width + DIALOG_BOX_CONTENT_OPTIONS_HORIZONTAL_SPACING + DIALOG_BOX_CONTENT_OPTIONS_HORIZONTAL_OFFSET 
  414. 	 
  415. 	-- Show options if we have them... 
  416. 	if option_count > 0 then 
  417. 		vint_set_property(options_h, "visible", true) 
  418. 		--Use options height... 
  419. 		options_height = y + DIALOG_BOX_CONTENT_OPTIONS_SPACING - 12 
  420. 	else 
  421. 		vint_set_property(options_h, "visible", true) 
  422. 		options_height = 0 
  423. 	end 
  424.  
  425. 	--Store off option data for later... 
  426. 	options.option_count = option_count 
  427. 	self.current_dialog.options = options 
  428. 	 
  429. 	--Highlight current option... 
  430. 	self:highlight_option(selected_index, true) 
  431.  
  432. 	--Pre-calculate size of box...  
  433. 	local dialog_box_width = max(DIALOG_BOX_MIN_WIDTH, options_width) 
  434.  
  435. 	dialog_box_width = max(widgets_width, dialog_box_width) 
  436. 	dialog_box_width = max(title_width, dialog_box_width) 
  437.  
  438. 	local dialog_box_height = 0 			-- This will be calculated as we place everything... 
  439.  
  440. 	--Position widgets... 
  441. 	local widget_x = DIALOG_BOX_CONTENT_START_X 
  442. 	local widget_y = DIALOG_BOX_CONTENT_START_Y 
  443. 	 
  444. 	for i = 0, widgets_count - 1 do 
  445. 		local widget_h 	= widgets[i].h 
  446. 		local widget_type = widgets[i].type 
  447. 		local width 		= widgets[i].width 
  448. 		local height 		= widgets[i].height 
  449. 		local num_lines 	= widgets[i].num_lines 
  450. 		local	is_waiting 	= widgets[i].is_waiting  
  451. 		 
  452. 		if widget_type == DIALOG_WIDGET_TYPE_TEXT then 
  453. 			if not is_waiting then 
  454. 				local body_txt_h = vint_object_find("body_txt", widget_h) 
  455. 				if body_txt_h ~= 0 then 
  456. 					local scroll_h = vint_object_find("scroll", widget_h) 
  457. 					local wrap_width = dialog_box_width - DIALOG_BOX_SCROLLBAR_WIDTH - DIALOG_BOX_SCROLLBAR_PADDING 
  458. 					vint_set_property(body_txt_h, "wrap_width", wrap_width) 
  459. 					vint_set_property(body_txt_h, "word_wrap", true) 
  460. 					 
  461. 					--Move scrollbar to edge of text box... 
  462. 					local scroll_x, scroll_y = vint_get_property(scroll_h, "anchor") 
  463. 					local body_txt_x, body_txt_y = vint_get_property(body_txt_h, "anchor") 
  464. 					vint_set_property(scroll_h, "anchor", body_txt_x + wrap_width + DIALOG_BOX_SCROLLBAR_PADDING, scroll_y) 
  465. 					 
  466. 					--Replace width and height values... 
  467. 					local text_width, text_height = element_get_actual_size(body_txt_h) 
  468. 					 
  469. 					if num_lines == 0 then 
  470. 						num_lines = DIALOG_BOX_DEFAULT_TEXT_LINES 
  471. 					end 
  472. 					 
  473. 					height = self.text_line_height * num_lines  
  474. 					 
  475. 					--This means we don't need to scroll... 
  476. 		--[[ DAD - 8/17/11 - Removed the scroll bar.. keeping this here for SR4 though 
  477. 					if text_height <= height then 
  478. 						height = text_height 
  479. 						vint_set_property(scroll_h, "visible", false) 
  480. 					else 
  481. 						vint_set_property(scroll_h, "visible", true) 
  482. 					end 
  483. 					]]-- 
  484. 					 
  485. 					-- This section can be removed if the above is uncommented 
  486. 					if text_height <= height then 
  487. 						height = text_height 
  488. 					end 
  489. 					vint_set_property(scroll_h, "visible", false) 
  490. 					-- End section 
  491. 					 
  492. 					--adjust size of mask 
  493. 					local mask_h = vint_object_find("mask", widget_h) 
  494. 					element_set_actual_size(mask_h, dialog_box_width, height + DIALOG_BOX_TEXT_MASK_PADDING) 
  495. 				end 
  496. 				 
  497. 			else 
  498. 				height = self.text_line_height + 5 
  499. 			end	 
  500. 		elseif widget_type == DIALOG_WIDGET_TYPE_SPINNER then 
  501. 			--Set text tag of spinner... 
  502. 			local spinner_txt_h = vint_object_find("spinner_txt", widget_h) 
  503. 			local wrap_width = dialog_box_width - DIALOG_BOX_SPINNER_SIZE - DIALOG_BOX_SPINNER_PADDING 
  504. 			vint_set_property(spinner_txt_h, "wrap_width", wrap_width) 
  505. 			vint_set_property(spinner_txt_h, "word_wrap", true) 
  506. 			 
  507. 			---if the text is wrapping more than 3 lines we have problems and need to reposition the spinner... 
  508. 			local y = 0 
  509. 			local spinner_txt_width, spinner_txt_height = element_get_actual_size(spinner_txt_h) 
  510. 			local spinner_internal_grp_h = vint_object_find("spinner_internal_grp", widget_h) 
  511. 			 
  512. 			if  spinner_txt_height > DIALOG_BOX_SPINNER_SIZE then 
  513. 				y = (spinner_txt_height - DIALOG_BOX_SPINNER_SIZE) * .5 
  514. 			end 
  515. 			vint_set_property(spinner_internal_grp_h, "anchor", 0, y) 
  516. 			height = height + (y * 2) 
  517. 		end 
  518. 		 
  519. 		--position widget... 
  520. 		vint_set_property(widget_h, "anchor", widget_x, widget_y) 
  521. 		 
  522. 		--Calculate position for next widget... 
  523. 		widget_y = widget_y + height + DIALOG_BOX_CONTENT_VERTICAL_SPACING 
  524.  
  525. 		--Store off widget height (last positioned object plus the height of it... 
  526. 		widgets_height = widget_y 
  527. 	end 
  528. 	 
  529. 	-- Position base options  
  530. 	local options_h = vint_object_find("options_obj", self.base_content_h) 
  531. 	vint_set_property(options_h, "anchor", widget_x, widgets_height) 
  532. 	 
  533. 	dialog_box_height = 	widgets_height - DIALOG_BOX_CONTENT_START_Y + options_height 
  534. 	 
  535. 	self.current_dialog.widgets = widgets 
  536. 	 
  537. 	--Change to new size... 
  538. 	self:morph_size(dialog_box_width, dialog_box_height, do_morph) 
  539. end 
  540.  
  541. function Vdo_dialog:morph_size(width, height, do_morph) 
  542. 	if do_morph then 
  543. 		local morph_anim_h = vint_object_find("morph_anim", self.handle) 
  544. 		local morph_twn_h = vint_object_find("morph_twn",morph_anim_h) 
  545. 		local content_alpha_twn_h = vint_object_find("content_alpha_twn", morph_anim_h) 
  546. 		local new_content_alpha_twn_h = vint_object_find("new_content_alpha_twn", morph_anim_h) 
  547. 	 
  548. 		--Use the following data to convert pixels to widths... 
  549. 		local fill_h = vint_object_find("fill", self.handle) 
  550. 		local start_width, start_height = vint_get_property(fill_h, "unscaled_size") 
  551. 		 
  552. 		vint_set_property(morph_twn_h, "start_value", self.width/start_width, self.height/start_height) 
  553. 		vint_set_property(morph_twn_h, "end_value", width/start_width, height/start_height) 
  554. 		 
  555. 		local callback_string = self:package_tween_callback("size_update") 
  556. 		vint_set_property(morph_twn_h, "per_frame_event", callback_string) 
  557. 		 
  558. 		local callback_string = self:package_tween_callback("morph_complete") 
  559. 		vint_set_property(morph_twn_h, "end_event", callback_string) 
  560. 		 
  561. 		--set targets for fade in and out tweens... 
  562. 		vint_set_property(content_alpha_twn_h, "target_handle", self.previous_content_h)		--target the new content (this tween fades out) 
  563. 		vint_set_property(new_content_alpha_twn_h, "target_handle", self.content_h)			--target the new content (this tween fades in) 
  564. 		 
  565. 		lua_play_anim(morph_anim_h) 
  566. 		self.morph_playing = true 
  567. 	else 
  568. 		self:set_size(width, height) 
  569. 	end 
  570. end 
  571.  
  572. function Vdo_dialog:size_update() 
  573. 	local fill_h  = vint_object_find("fill", self.handle) 
  574. 	local width, height = element_get_actual_size(fill_h) 
  575. 	self:set_size(width, height) 
  576. end 
  577.  
  578. function Vdo_dialog:set_size(width, height) 
  579. 	local border_h 			= vint_object_find("border", self.handle) 
  580. 	local fill_h  				= vint_object_find("fill", self.handle) 
  581. 	local dialog_clip_h  	= vint_object_find("dialog_clip", self.handle) 
  582.  
  583. 	--Calculate background element sizes... 
  584. 	local border_width 	= width + 10 
  585. 	local border_height 	= height + 38 
  586. 	local clip_width 		= width + 1 
  587. 	local clip_height 	= height + 33 
  588. 	 
  589. 	--[[ 
  590. 		relative sizes... 
  591. 		fill: 	420, 217 
  592. 		border:	430, 255 
  593. 		dialog_clip:	420, 250 
  594. 	]] 
  595.  
  596. 	--Adjust background elements... 
  597. 	element_set_actual_size(fill_h, width, height) 
  598. 	element_set_actual_size(border_h, border_width, border_height) 
  599. 	element_set_actual_size(dialog_clip_h, clip_width, clip_height) 
  600. 	 
  601. 	self:set_shadow(width, height) 
  602. 	 
  603. 	--Set highlight width on option bar... 
  604. 	self.highlight:set_width(width) 
  605. 	 
  606. 	--Align box to screen... 
  607. 	local box_h = vint_object_find("dialog_grp", self.handle) 
  608. 	if self.alignment == DIALOG_ALIGN_CENTER then 
  609. 		--get parent scale... of object.(this isn't standard... but handles us if we are scaled by a parent document... 
  610. 		local scale_x, scale_y  
  611. 		if vint_is_std_res() then 
  612. 			scale_x = 0.667 
  613. 			scale_y = 0.667 
  614. 			vint_set_property(self.handle, "scale", scale_x, scale_y)			 
  615. 		else 
  616. 			scale_x = 1.0 
  617. 			scale_y = 1.0 
  618. 			vint_set_property(self.handle, "scale", scale_x, scale_y)	 
  619. 		end 
  620. 		 
  621. 		--Set box to center... screen center, minus half the box width... 
  622. 		local x = (((Screen_center_x / scale_x)- (border_width/2)) ) 
  623. 		local y = (((Screen_center_y / scale_y) - (border_height/2)) ) 
  624. 		vint_set_property(box_h, "anchor", x, y) 
  625. 	elseif self.alignment == DIALOG_ALIGN_LEFT then 
  626. 		 
  627. 	end 
  628. 	self.width = width 
  629. 	self.height = height 
  630. end 
  631.  
  632. function Vdo_dialog:morph_complete() 
  633. 	self.morph_playing = false 
  634. 	 
  635. 	--destroy content... 
  636. 	if self.previous_content_h ~= -1 then 
  637. 		vint_object_destroy(self.previous_content_h) 
  638. 		self.previous_content_h = -1 
  639. 	end 
  640. 	 
  641. 	if self.morph_complete_cb ~= nil then 
  642. 		self.morph_complete_cb() 
  643. 	end 
  644. end 
  645.  
  646. ------------------------------------------------------------------------------- 
  647. -- Sets the shadow for the dialog box... 
  648. -- @param	width			Width of shadow...	 
  649. -- @param	height		Height of shadow... 
  650. ------------------------------------------------------------------------------- 
  651. function Vdo_dialog:set_shadow(width, height) 
  652.  
  653. 	-- Find shadow objects 
  654. 	local nw_h 	= self.shadow.nw 
  655. 	local n_h 	= self.shadow.n	 
  656. 	local ne_h 	= self.shadow.ne 
  657. 	local e_h 	= self.shadow.e 
  658. 	local se_h 	= self.shadow.se 
  659. 	local s_h 	= self.shadow.s 
  660. 	local sw_h 	= self.shadow.sw 
  661. 	local w_h 	= self.shadow.w 
  662. 	 
  663. 	--Top left Corner 
  664. 	local start_x = 0 
  665. 	local start_y = 0 
  666. 	 
  667. 	--Padding if width/height are a bit less than the outside of the box... 
  668. 	local pad_width	= 10 
  669. 	local pad_height 	= 38 
  670. 	 
  671. 	width = width + pad_width 
  672. 	height = height + pad_height 
  673. 	 
  674. 	local sides_width, sides_height = element_get_actual_size(n_h) 
  675. 	 
  676. 	--N 
  677. 	element_set_actual_size(n_h, width, sides_height) 
  678. 	 
  679. 	--NE 
  680. 	vint_set_property(ne_h, "anchor", width + start_x, start_y) 
  681. 	 
  682. 	--E 
  683. 	vint_set_property(e_h, "anchor", width + start_x, start_y) 
  684. 	element_set_actual_size(e_h, height, sides_height) 
  685. 	 
  686. 	--SE 
  687. 	vint_set_property(se_h, "anchor", width + start_x, height + start_y) 
  688. 	 
  689. 	--S 
  690. 	vint_set_property(s_h, "anchor", start_x, height + start_y) 
  691. 	element_set_actual_size(s_h, width, -sides_height) 
  692. 	 
  693. 	--SW 
  694. 	vint_set_property(sw_h, "anchor", start_x, height + start_y) 
  695. 	--element_set_actual_size(sw_h, width, sides_height) 
  696. 	 
  697. 	--W 
  698. 	element_set_actual_size(w_h, height, sides_height)	 
  699. end 
  700.  
  701. ------------------------------------------------------------------------------- 
  702. -- Moves highlight bar to index... 
  703. ------------------------------------------------------------------------------- 
  704. function Vdo_dialog:add_clone_to_list(clone_h) 
  705. 	local clone_count = #self.current_dialog.widget_clones 
  706. 	self.current_dialog.widget_clones[clone_count] = clone_h 
  707. end 
  708.  
  709. ------------------------------------------------------------------------------- 
  710. -- Moves highlight bar to index... 
  711. ------------------------------------------------------------------------------- 
  712. function Vdo_dialog:highlight_option(idx, skip) 
  713.  
  714. 	local options = self.current_dialog.options 
  715. 	local selected_option = options.selected_option 
  716. 	 
  717. 	if skip == nil or skip == false then 
  718. 		if options.selected_option ~= nil then 
  719. 			dialog_option_end_kbd_input(self.dialog_handle, options.selected_option) 
  720. 		end 
  721. 	end 
  722. 	 
  723.  
  724. 	dialog_option_accept_kbd_input(self.dialog_handle, idx) 
  725. 	 
  726. 	--Check to make sure index isn't out of range... 
  727. 	if idx > options.option_count - 1 then 
  728. 		idx = options.option_count - 1 
  729. 	end 
  730. 	 
  731. 	if options[idx] ~= nil and options[idx].disabled ~= nil and options[idx].disabled then 
  732. 		return 
  733. 	end 
  734. 	 
  735. 	--hide highlight if there are no options... 
  736. 	if options.option_count == 0 then 
  737. 		vint_set_property(self.highlight.handle, "visible", false) 
  738. 		return 
  739. 	else 
  740. 		vint_set_property(self.highlight.handle, "visible", true) 
  741. 	end 
  742. 	--move highlight bar... 
  743. 	local x, y = vint_get_property(options[idx].h, "anchor") 
  744. 	vint_set_property(self.highlight.handle, "anchor", x, y) 
  745. 	 
  746. 	--Color options... 
  747. 	for i = 0, options.option_count - 1 do  
  748. 		local option_h = options[i].h 
  749. 		local option_1_h = vint_object_find("option_txt_1", option_h) 
  750. 		if idx == i then 
  751. 			vint_set_property(option_1_h, "tint", DIALOG_BOX_TEXT_SELECTED.R, DIALOG_BOX_TEXT_SELECTED.G, DIALOG_BOX_TEXT_SELECTED.B) 
  752. 		else 
  753. 			vint_set_property(option_1_h, "tint", DIALOG_BOX_TEXT_UNSELECTED.R, DIALOG_BOX_TEXT_UNSELECTED.G, DIALOG_BOX_TEXT_UNSELECTED.B) 
  754. 		end 
  755. 	end 
  756. 	 
  757. 	options.selected_option = idx 
  758. end 
  759.  
  760. ------------------------------------------------------------------------------- 
  761. --   
  762. ------------------------------------------------------------------------------- 
  763. function Vdo_dialog:set_dialog_callback() 
  764. end 
  765.  
  766. ------------------------------------------------------------------------------- 
  767. --  opens dialog... 
  768. ------------------------------------------------------------------------------- 
  769. function Vdo_dialog:open(do_trans_in) 
  770. 	self:show() 
  771.  
  772. 	-- stop fade out 
  773. 	local anim_h = vint_object_find("fade_out_anim", self.handle) 
  774. 	self:close_finished() 
  775. 	 
  776. 	if do_trans_in == true then 
  777. 		-- start fade in 
  778. 		anim_h = vint_object_find("fade_in_anim", self.handle) 
  779. 		vint_set_property(anim_h, "target_handle", self.handle) 
  780. 		lua_play_anim(anim_h) 
  781. 	else 
  782. 		vint_set_property(self.handle, "alpha", 1.0) 
  783. 	end 
  784. end 
  785.  
  786. ------------------------------------------------------------------------------- 
  787. --  Closes dialog... 
  788. ------------------------------------------------------------------------------- 
  789. function Vdo_dialog:close() 
  790.  
  791. 	--start fade out... 
  792. 	local anim_out_h = vint_object_find("fade_out_anim", self.handle) 
  793. 	local tween_h = vint_object_find("new_tween2_1", anim_out_h)	 
  794. 	vint_set_property(anim_out_h, "target_handle", self.handle) 
  795. 	 
  796. 	local callback_string = self:package_tween_callback("close_finished") 
  797. 	vint_set_property(tween_h, "end_event", callback_string) 
  798. 		 
  799. 	lua_play_anim(anim_out_h) 
  800. end 
  801.  
  802. function Vdo_dialog:close_finished() 
  803. 	dialog_close_finished() 
  804. end 
  805.  
  806. ------------------------------------------------------------------------------- 
  807. -- Show 
  808. ------------------------------------------------------------------------------- 
  809. function Vdo_dialog:show() 
  810. 	vint_set_property(self.handle, "visible", true) 
  811. end 
  812.  
  813. ------------------------------------------------------------------------------- 
  814. -- Hide 
  815. ------------------------------------------------------------------------------- 
  816. function Vdo_dialog:hide() 
  817. 	vint_set_property(self.handle, "visible", false) 
  818. end 
  819.  
  820. function Vdo_dialog:set_color(main_bg_color, highlight_color) 
  821. 	local border_h = vint_object_find("border", self.handle) 
  822. 	vint_set_property(border_h, "tint", main_bg_color.R, main_bg_color.G, main_bg_color.B) 
  823. 	 
  824. 	self.highlight:set_highlight_color(highlight_color) 
  825.  
  826. 	local spinner_gfx_h = vint_object_find("spinner_gfx_1", self.base_content_h) 
  827. 	vint_set_property(spinner_gfx_h, "tint", main_bg_color.R, main_bg_color.G, main_bg_color.B)	 
  828. end 
  829.  
  830.  
  831. ------------------------------------------------------------------------------- 
  832. -- Navigation... 
  833. ------------------------------------------------------------------------------- 
  834. function Vdo_dialog:nav(direction) 
  835. 	local options = self.current_dialog.options 
  836. 	local selected_option = options.selected_option 
  837. 	local option_count = options.option_count 
  838.  
  839. 	if option_count <= 0 then 
  840. 		return false 
  841. 	end 
  842. 	 
  843. 	if selected_option == nil then 
  844. 		options.selected_option = 0 
  845. 		selected_option = 0 
  846. 	end 
  847.  
  848. 	local new_option = selected_option + direction 
  849. 	if new_option < 0 then 
  850. 		new_option = options.option_count - 1 
  851. 	elseif new_option == options.option_count then 
  852. 		--exceeded limit go 
  853. 		new_option = 0 
  854. 	end 
  855. 	 
  856. 	if options[new_option] ~= nil and options[new_option].disabled ~= nil and options[new_option].disabled then -- if the option is disabled, try again. 
  857. 		if direction == 0 then 
  858. 			direction = direction + 1 
  859. 		end 
  860. 		new_option = new_option + direction 
  861. 		if new_option < 0 then 
  862. 			new_option = options.option_count - 1 
  863. 		elseif new_option == options.option_count then 
  864. 			--exceeded limit go 
  865. 			new_option = 0 
  866. 		end 
  867. 	end 
  868.  
  869. 	dialog_box_set_current_option(self.dialog_handle, new_option) 
  870. 	 
  871. 	self:highlight_option(new_option) 
  872.  
  873. 	return true 
  874. end 
  875.  
  876. -- Add mouse inputs to the options 
  877. function Vdo_dialog:add_mouse_inputs(callback_action, callback_nav, input_tracker, priority) 
  878. 	local options = self.current_dialog.options 
  879. 	if (options == nil) or (callback_action == nil) or (callback_nav == nil) then 
  880. 		return 
  881. 	end 
  882. 	 
  883. 	-- Default priority value to 200 
  884. 	priority = priority or 200 
  885. 	 
  886. 	-- Clear out old wide hitboxes 
  887. 	if self.wide_hitboxes ~= nil then 
  888. 		for idx, wide_hitbox in pairs(self.wide_hitboxes) do 
  889. 			vint_object_destroy(wide_hitbox.handle) 
  890. 		end 
  891. 	end 
  892. 	self.wide_hitboxes = {} 
  893.  
  894. 	local highlight_w, highlight_h = vint_get_property(self.highlight.handle, "screen_size") 
  895. 	local options_obj_handle = vint_object_find("options_obj", self.handle) 
  896. 	 
  897. 	for i = 0, options.option_count - 1 do 
  898. 		if options[i].disabled == nil or options[i].disabled == false then 
  899. 			-- X = 0 
  900. 			-- Width = highlight.width 
  901. 			-- Y = option[i].y 
  902. 			-- Height = option[i].height 
  903. 			local option_x, option_y = vint_get_property(options[i].h, "anchor") 
  904. 			local option_w, option_h = vint_get_property(options[i].h, "screen_size") 
  905. 			 
  906. 			local wide_index = #self.wide_hitboxes + 1 
  907. 			local wide_name = "wide_hitbox"..wide_index 
  908. 			local wide_handle = vint_object_create(wide_name, "bitmap", options_obj_handle) 
  909. 			 
  910. 			self.wide_hitboxes[wide_index] = {} 
  911. 			self.wide_hitboxes[wide_index].handle = wide_handle 
  912. 			self.wide_hitboxes[wide_index].idx = i 
  913. 			vint_set_property(wide_handle, "auto_offset", "w") 
  914. 			vint_set_property(wide_handle, "visible", false) 
  915. 			vint_set_property(wide_handle, "depth", 100) 
  916. 			vint_set_property(wide_handle, "screen_size", highlight_w - 8, option_h + 2) 
  917. 			vint_set_property(wide_handle, "anchor", 0, option_y + 1) 
  918. 			vint_set_property(wide_handle, "mouse_depth", -5000) 
  919. 			options[i].wide_handle = wide_handle 
  920. 		 
  921. 			input_tracker:add_mouse_input("mouse_click", callback_action, priority, options[i].wide_handle) 
  922. 			input_tracker:add_mouse_input("mouse_move", callback_nav, priority, options[i].wide_handle) 
  923. 		end 
  924. 	end 
  925. 	 
  926. 	local bg_h = vint_object_find("background", self.handle) 
  927. 	vint_set_property(bg_h, "mouse_depth", -4000) 
  928. 	input_tracker:add_mouse_input("mouse_move", callback_nav, priority, bg_h) 
  929. 	input_tracker:add_mouse_input("mouse_click", callback_action, priority, bg_h) 
  930.  
  931. 	--loop through and see if we have any hintbars to add inputs to... 
  932. 	local widgets_count = self.current_dialog.widgets.widgets_count	 
  933. 	for i = 0, widgets_count - 1 do 
  934. 		local widget = self.current_dialog.widgets[i] 
  935. 		local widget_type = widget.type 
  936. 		if widget_type == DIALOG_WIDGET_TYPE_TEXT then 
  937. 			local is_waiting 	=	widget.is_waiting  
  938. 			if is_waiting then 
  939. 				self.hint_bar:add_mouse_inputs("dialog", input_tracker) 
  940. 				self.hint_bar:override_mouse_depths(-5000) 
  941. 			end 
  942. 		end 
  943. 	end	 
  944. end 
  945.  
  946. -- Search through the options and match the index 
  947. function Vdo_dialog:get_option_index(handle) 
  948. 	local options = self.current_dialog.options 
  949. 	 
  950. 	for i = 0, options.option_count - 1 do 
  951. 		if options[i].wide_handle == handle then 
  952. 			return i 
  953. 		end 
  954. 	end 
  955. 	 
  956. 	return -1 
  957. end 
  958.  
  959. ------------------------------------------------------------------------------- 
  960. -- Selects current option, sends data to callback... 
  961. ------------------------------------------------------------------------------- 
  962. function Vdo_dialog:select() 
  963. 	local options = self.current_dialog.options 
  964. 	local selected_option = options.selected_option 
  965. 	 
  966. 	if selected_option ~= nil and options[selected_option] ~= nil and options[selected_option].disabled ~= nil and options[selected_option].disabled then 
  967. 		return 
  968. 	end 
  969. 	 
  970. 	if options[selected_option] ~= nil and options[selected_option].has_second_option then 
  971. 		return 
  972. 	end 
  973.  
  974. 	return dialog_box_set_result(self.dialog_handle, selected_option, DIALOG_ACTION_SELECT) 
  975. end 
  976.  
  977. ------------------------------------------------------------------------------- 
  978. -- Returns the currently selected option 
  979. ------------------------------------------------------------------------------- 
  980. function Vdo_dialog:get_selected() 
  981. 	return self.current_dialog.options.selected_option 
  982. end 
  983.  
  984. ------------------------------------------------------------------------------- 
  985. -- Returns whether the option has a second option 
  986. ------------------------------------------------------------------------------- 
  987. function Vdo_dialog:has_second_option(option_idx) 
  988. 	if self.current_dialog == nil or self.current_dialog.options == nil or self.current_dialog.options[option_idx] == nil then 
  989. 		return false 
  990. 	end 
  991. 	return self.current_dialog.options[option_idx].has_second_option 
  992. end 
  993.  
  994. ------------------------------------------------------------------------------- 
  995. -- Fires back event... 
  996. ------------------------------------------------------------------------------- 
  997. function Vdo_dialog:back() 
  998. 	local options = self.current_dialog.options 
  999. 	local selected_option = options.selected_option 
  1000. 	return dialog_box_set_result(self.dialog_handle, selected_option, DIALOG_ACTION_BACK) 
  1001. end 
  1002.  
  1003. ------------------------------------------------------------------------------- 
  1004. -- cleanup Dialog VDO! 
  1005. ------------------------------------------------------------------------------- 
  1006. function Vdo_dialog:cleanup() 
  1007. end 
  1008.  
  1009. -- Given a set of options, return several width metric about them 
  1010. -- 
  1011. -- options: Set of dialog options to work with. Usually self.current_dialog.options, unless called from create() 
  1012. -- 
  1013. -- return 1: the maximum width of all single options that has no second option 
  1014. -- return 2: the maximum width of all single options that does have a second option 
  1015. -- return 3: the maximum width of all second options 
  1016. function Vdo_dialog:get_option_widths(options) 
  1017. 	local option_count = options.option_count 
  1018. 	 
  1019. 	local solo_option_1_max_width = 0 
  1020. 	local paired_option_1_max_width = 0 
  1021. 	local paired_option_2_max_width = 125 	-- This is also the default width of the text box... Approximatly 8 characters... 
  1022. 	if game_get_platform() == "PC" then 
  1023. 		paired_option_2_max_width = 250 -- Double it on PC so typing directly in it isn't so jarring 
  1024. 	end 
  1025. 	 
  1026. 	for i = 0, option_count - 1 do 
  1027. 		local option_1_text_h = vint_object_find("option_txt_1", options[i].h)		 
  1028. 		local option_1_width = element_get_actual_size(option_1_text_h) 
  1029. 		 
  1030. 		if options[i].has_second_option == true then 
  1031. 			local option_2_text_h = vint_object_find("option_txt_2", options[i].h) 
  1032. 			local option_2_width = element_get_actual_size(option_2_text_h) 
  1033. 			 
  1034. 			paired_option_1_max_width = max(paired_option_1_max_width, option_1_width) 
  1035. 			paired_option_2_max_width = max(paired_option_2_max_width, option_2_width) 
  1036. 		else 
  1037. 			solo_option_1_max_width = max(solo_option_1_max_width, option_1_width) 
  1038. 		end 
  1039. 	end 
  1040. 	 
  1041. 	return solo_option_1_max_width, paired_option_1_max_width, paired_option_2_max_width 
  1042. end 
  1043.  
  1044. -- Given a set of options, return the necessary width of the dialog box to contain them 
  1045. -- 
  1046. -- options: Set of dialog options to work with. Usually self.current_dialog.options, unless called from create() 
  1047. -- 
  1048. -- return 1: the necessary width of the dialog box 
  1049. function Vdo_dialog:get_dialog_width(options, widgets) 
  1050. 	local options_obj_h = vint_object_find("options_obj", self.base_content_h) 
  1051. 	local base_option_obj_h = vint_object_find("option", options_obj_h)	 
  1052. 	 
  1053. 	local x, y = vint_get_property(base_option_obj_h, "anchor") 
  1054. 	 
  1055. 	local solo_option_1_max_width, paired_option_1_max_width, paired_option_2_max_width = self:get_option_widths(options) 
  1056. 	 
  1057. 	local options_largest_width = max(solo_option_1_max_width, paired_option_1_max_width + paired_option_2_max_width + 5) 
  1058. 	local options_width = x + options_largest_width + DIALOG_BOX_CONTENT_OPTIONS_HORIZONTAL_SPACING + DIALOG_BOX_CONTENT_OPTIONS_HORIZONTAL_OFFSET 
  1059.  
  1060. 	local widgets_width = self:get_widgets_width(widgets) 
  1061. 	 
  1062. -- SMH: I'm sure leaving these lines commented out is "wrong", but in the only case this 
  1063. -- function is being used, it's necessary to prevent lua from failing to find the title 
  1064. -- text obj and then try to index null when I try to get its size. 
  1065.  
  1066. --	local title_txt_obj = vint_object_find("title_txt", self.base_content_h) 
  1067. --	local title_width, title_height = title_txt_obj:get_actual_size() 
  1068. --	title_width = title_width + 6	--for padding 
  1069. 	 
  1070. 	local dialog_width = max(DIALOG_BOX_MIN_WIDTH, options_width) 
  1071. 	dialog_width = max(dialog_width, widgets_width) 
  1072. --	dialog_width = max(dialog_width, title_width) 
  1073.  
  1074. 	return dialog_width 
  1075. end 
  1076.  
  1077. -- Given a set of options, return their cumulative height 
  1078. -- 
  1079. -- options: Set of dialog options to work with. Usually self.current_dialog.options, unless called from create() 
  1080. -- 
  1081. function Vdo_dialog:get_options_height(options) 
  1082. 	local option_count = options.option_count 
  1083. 	 
  1084. 	if option_count <= 0 then 
  1085. 		return 0 
  1086. 	end 
  1087. 	 
  1088. 	local x, y = vint_get_property(options[option_count-1].h, "anchor") 
  1089. 	return y + DIALOG_BOX_CONTENT_OPTIONS_SPACING - 12 
  1090. end 
  1091.  
  1092. -- Given a set of options, return their cumulative height 
  1093. -- 
  1094. -- return 1: the maximum height of widgets 
  1095. function Vdo_dialog:get_widgets_height(widgets) 
  1096. 	local widgets_count = widgets.widgets_count 
  1097. 	 
  1098. 	local max_widget_y = DIALOG_BOX_CONTENT_START_Y 
  1099. 	for i = 0, widgets_count - 1 do 
  1100. 		local height = widgets[i].height 
  1101. 		local width = widgets[i].width 
  1102. 		local x, y 
  1103. 		 
  1104. 		if widgets[i].type == DIALOG_WIDGET_TYPE_TEXT then 
  1105. 			--height = self.text_line_height * widgets[i].num_lines 
  1106. 		end 
  1107.  
  1108. 		x, y = vint_get_property(widgets[i].h, "anchor") 
  1109. 		 
  1110. 		max_widget_y = max(max_widget_y, y + height + DIALOG_BOX_CONTENT_VERTICAL_SPACING) 
  1111. 	end 
  1112. 	 
  1113. 	return max_widget_y - DIALOG_BOX_CONTENT_START_Y 
  1114. end 
  1115.  
  1116. -- Given a set of options, return their cumulative width 
  1117. -- 
  1118. -- return 1: the maximum height of widgets 
  1119. function Vdo_dialog:get_widgets_width(widgets) 
  1120. 	local widgets_count = #widgets 
  1121. 	 
  1122. 	local widgets_width = 0 
  1123. 	for i = 0, widgets_count - 1 do 
  1124. 		widgets_width = max(widgets_width, widgets[i].width) 
  1125. 	end 
  1126. 	 
  1127. 	return widgets_width 
  1128. end 
  1129.  
  1130. function Vdo_dialog:resize_options(options) 
  1131. 	local option_count = options.option_count 
  1132. 	local solo_option_1_max_width, paired_option_1_max_width, paired_option_2_max_width = self:get_option_widths(options) 
  1133.  
  1134. 	-- Align second options... 
  1135. 	-- todo align right side of box to width of the shit... 
  1136. 	for i = 0, option_count - 1 do 
  1137. 		local current_option_h = options[i].h  
  1138. 		local option_txt_1_h = vint_object_find("option_txt_1", current_option_h) 
  1139. 		local option_2_grp_h = vint_object_find("option_2_grp", current_option_h) 
  1140. 		local x, y = vint_get_property(option_txt_1_h, "anchor") 
  1141. 		vint_set_property(option_2_grp_h, "anchor", x + paired_option_1_max_width + DIALOG_BOX_CONTENT_OPTIONS_HORIZONTAL_SPACING, y) 
  1142. 		 
  1143. 		--Set size of option2 box, + 10 to account for padding... 
  1144. 		local option_2_box_width = paired_option_2_max_width + 10 
  1145. 		 
  1146. 		--Resize background  
  1147. 		local box_bg_h = vint_object_find("option_box_bg", current_option_h) 
  1148. 		local box_bg_width, box_bg_height = element_get_actual_size(box_bg_h) 
  1149. 		element_set_actual_size(box_bg_h, option_2_box_width - 4, box_bg_height)	--its the box width.. - 4 is the width of the size so we subtract it... 
  1150. 		 
  1151. 		--Resize the north and south sides of the box... 
  1152. 		local box_n_h = vint_object_find("option_box_n", current_option_h) 
  1153. 		local box_s_h = vint_object_find("option_box_s", current_option_h) 
  1154. 		 
  1155. 		local box_width, box_height = element_get_actual_size(box_n_h) 
  1156. 		element_set_actual_size(box_n_h, option_2_box_width, box_height) 
  1157. 		element_set_actual_size(box_s_h, option_2_box_width, box_height) 
  1158. 		 
  1159. 		--Reposition right side of box... 
  1160. 		local box_e_h = vint_object_find("option_box_e", current_option_h) 
  1161. 		local box_x, box_y  = vint_get_property(box_e_h, "anchor") 
  1162. 		vint_set_property(box_e_h, "anchor", option_2_box_width, box_y) 
  1163. 	end 
  1164. end 
  1165.  
  1166. -- Given a set of options and widgets, return the necessary height of a dialog box to contain them 
  1167. -- 
  1168. -- return 1: The necessary height of the dialog box 
  1169. function Vdo_dialog:get_dialog_height(options, widgets) 
  1170. 	return self:get_options_height(options) + self:get_widgets_height(widgets) 
  1171. end 
  1172.  
  1173. function Vdo_dialog:set_option_text(option_idx, new_text, do_morph, morph_complete_cb) 
  1174. 	if self.morph_playing == true then 
  1175. 		self:morph_complete() 
  1176. 	end 
  1177. 	 
  1178. 	local options = self.current_dialog.options 
  1179. 	 
  1180. 	local option_1_text_h = vint_object_find("option_txt_1", options[option_idx].h)		 
  1181. 	 
  1182. 	if options[option_idx].has_second_option == true then 
  1183. 		options[option_idx].tag_2 = new_text 
  1184. 		local option_2_text_h = vint_object_find("option_txt_2", options[option_idx].h) 
  1185. 		vint_set_property(option_2_text_h, "text_tag", options[option_idx].tag_2) 
  1186. 	else 
  1187. 		options[option_idx].tag_1 = new_text 
  1188. 		local option_1_text_h = vint_object_find("option_txt_1", options[option_idx].h) 
  1189. 		vint_set_property(option_1_text_h, "text_tag", options[option_idx].tag_1)	 
  1190. 	end 
  1191. 	 
  1192. 	self:resize_options(options) 
  1193.  
  1194. 	local dialog_box_width = self:get_dialog_width(options, self.current_dialog.widgets) 
  1195. 	local dialog_box_height = self:get_dialog_height(options, self.current_dialog.widgets) 
  1196.  
  1197. 	if self.width ~= dialog_box_width or self.height ~= dialog_box_height then 
  1198. 		if do_morph == true then 
  1199. 			--Need to clone and delete old dialog content when finished... 
  1200. 			--our morph callback will handle any remaining cleanup.. 
  1201. 			self.previous_content_h = vint_object_clone(self.base_content_h) 
  1202. 			 
  1203. 			--Move content behind new content... 
  1204. 			vint_set_property(self.previous_content_h, "depth", 5000) 
  1205. 			 
  1206. 			if morph_complete_cb ~= nil then 
  1207. 				self.morph_complete_cb = morph_complete_cb 
  1208. 			else 
  1209. 				self.morph_complete_cb = nil 
  1210. 			end 
  1211. 		else 
  1212. 			self.morph_complete_cb = nil 
  1213. 		end 
  1214.  
  1215. 		--Change to new size... 
  1216. 		self:morph_size(dialog_box_width, dialog_box_height, do_morph) 
  1217. 	end 
  1218. end 
  1219.