./vdo_scrollbox.lua

  1. --NEXT: Figure out scroll direction in smooth_nav() 
  2.  
  3.  
  4. Vdo_scrollbox_threads = {} 
  5. Vdo_scrollbox_thread_count = 0 
  6.  
  7. VDO_SCROLLBOX_BAR_SPACING = 5 
  8. VDO_SCROLLBOX_DURATION					= 0.05		--TODO: OUTLINE THESE NUMBERS... 
  9. VDO_SCROLLBOX_DURATION_PIXEL_RATE	= 20 
  10.  
  11. -- Inherited from Vdo_base_object 
  12. Vdo_scrollbox = Vdo_base_object:new_base() 
  13.  
  14. function vdo_scrollbox_init() 
  15. 	debug_print("vint", "Vdo_scrollbox:init()\n")	 
  16. end 
  17.  
  18. function vdo_scrollbox_cleanup() 
  19. end 
  20.  
  21.  
  22. function Vdo_scrollbox:init() 
  23. 	--Create references to all the objects.... 
  24. 	self.scroll_box_h				= vint_object_find("scroll_box", self.handle, self.doc_handle) 
  25. 	self.clip_h						= vint_object_find("clip", self.handle, self.doc_handle) 
  26. 	self.scroll_item_h			= vint_object_find("scroll_item", self.handle, self.doc_handle) 
  27. 	self.text_h						= vint_object_find("scroll_text", self.handle, self.doc_handle) 
  28. 	self.scrollbar					= Vdo_scrollbar:new("scrollbar", self.handle, self.doc_handle) 
  29. 	self.scroll_anim_h			= vint_object_find("scroll_anim", self.handle, self.doc_handle) 
  30. 	self.main_scroll_twn_h		= vint_object_find("main_scroll_twn", self.handle, self.doc_handle) 
  31. 	 
  32. 	--Callback string... 
  33. 	local callback_string = self:package_tween_callback("scroll_finished") 
  34. 	vint_set_property(self.main_scroll_twn_h, "end_event", callback_string) 
  35. 	vint_set_property(self.main_scroll_twn_h, "target_handle", self.scroll_item_h) 
  36. 	 
  37. 	--scrolling defaults 
  38. 	self.scroll_thread = 0 
  39. 	self:set_size(400, 200) 
  40. 	self.content_height = 0 
  41. 	self.content_width = 0 
  42. 	self.scroll_direction = 0 
  43. 	 
  44. end 
  45.  
  46. function vdo_scrollbox_thread(awesome) 
  47.  
  48. end 
  49.  
  50. --Events need to be registered on the main screen and sent through this function... 
  51. function Vdo_scrollbox:nav_smooth(value) 
  52. 	-- First check if the stick is pointed in any direction 
  53. 	debug_print("vint", "nav_smooth(value): " .. value .. "\n") 
  54. 	 
  55. 	-- No scrolling if we dont needs to. 
  56. 	if self.clip_height > self.content_height then 
  57. 		-- Kill the thread if it exists, and reset the scrollbar 
  58. 		if self.scroll_thread ~= 0 then 
  59. 			thread_kill(self.scroll_thread) 
  60. 			self.scroll_thread = 0 
  61. 		end 
  62. 		return 
  63. 	end 
  64. 	 
  65. 	if abs(value) < 0.5 then 
  66. 		-- Stop scrolling if it's not 
  67. 		if self.scroll_direction ~= 0 then 
  68. 			 
  69. 			-- Kill the thread for scrolling 
  70. 			if self.scroll_thread ~= 0 then 
  71. 				thread_kill(self.scroll_thread) 
  72. 				self.scroll_thread = 0 
  73. 			end 
  74.  
  75. 			-- Pause the animation 
  76. 			vint_set_property(self.scroll_anim_h, "is_paused", true) 
  77. 			self.scroll_direction = 0 
  78. 			self:scrollbar_set() 
  79. 		end 
  80. 	else 
  81. 		-- Just continue tweening if we're still going in the same direction 
  82. 		if (self.scroll_direction > 0 and value > 0) or 
  83. 			(self.scroll_direction < 0 and value < 0) then 
  84. 			return 
  85. 		elseif self.scroll_direction ~= 0 then 
  86. 			-- Stop the animation if we're changing direction 
  87. 			vint_set_property(self.scroll_anim_h, "is_paused", true) 
  88. 		end 
  89. 		 
  90. 		-- Kill the thread if it exists, and reset the scrollbar 
  91. 		if self.scroll_thread ~= 0 then 
  92. 			thread_kill(self.scroll_thread) 
  93. 			self.scroll_thread = 0 
  94. 			self:scrollbar_set() 
  95. 		end 
  96. 		 
  97. 		-- If the value is negative, we're naving down 
  98. 		local nav_down = (value < 0) 
  99. 		local movement = 0 
  100. 		local pixel_per_duration = 0 
  101.  
  102. 		local x, y = vint_get_property(self.scroll_item_h, "anchor") 
  103. 		local bottom_y = y + self.clip_height		 
  104.  
  105. 		-- Find the bottom of the text 
  106. 		local bottom_y = y + self.content_height		 
  107. 		 
  108. 		-- Prepare for movement 
  109. 		if nav_down == false then 
  110. 			-- Move to the top 
  111. 			if y < 0 then  
  112. 				movement = -(y) 
  113. 			end 
  114. 		else  
  115. 			-- Move to the bottom 
  116. 			movement = -(bottom_y - self.clip_height) 
  117. 		end 
  118. 		 
  119. 		debug_print("vint", "y: " .. y .. "\n") 
  120. 		debug_print("vint", "movement: " .. movement .. "\n") 
  121. 		debug_print("vint", "self.scroll_item_h: " .. self.scroll_item_h .. "\n") 
  122. 		debug_print("vint", "bottom_y: " .. bottom_y .. "\n") 
  123. 		debug_print("vint", "self.clip_height: " .. self.clip_height .. "\n") 
  124. 		debug_print("vint", "self.content_height: " .. self.content_height .. "\n\n") 
  125. 		 
  126. 		-- If we're going to be moving, then start the tween 
  127. 		if movement ~= 0 then 
  128. 			local twn_h = self.main_scroll_twn_h 
  129. 			 
  130. 			-- Calculate the duration of the tween, this is the amount of time it should take to scroll from the current position to bottom 
  131. 			-- This speed should be consistent no matter how much movement is left 
  132. 			local duration = VDO_SCROLLBOX_DURATION * (abs(movement) / VDO_SCROLLBOX_DURATION_PIXEL_RATE) 
  133. 			 
  134. 			-- Create the tween, its told to scroll until it gets all the way to the top or the bottom, but will be killed when the  
  135. 			-- stick is released 
  136. 			vint_set_property(twn_h, "duration", duration) 
  137. 			vint_set_property(twn_h, "start_value", x, y) 
  138. 			vint_set_property(twn_h, "end_value", x, y + movement) 
  139. 			lua_play_anim(self.scroll_anim_h, 0)	 
  140.  
  141. 			-- Start the thread for scrolling 
  142. 			self.scroll_thread = thread_new("vdo_scrollbox_scroll_thread", self) 
  143. 			 
  144. 			-- Store our scroll direction 
  145. 			if nav_down == true then  
  146. 				self.scroll_direction = -1 
  147. 			else  
  148. 				self.scroll_direction = 1 
  149. 			end				 
  150. 		end 
  151. 	end 
  152. end 
  153.  
  154. function Vdo_scrollbox:scroll_finished() 
  155. 	-- Reset the start values for the tween when the scroll is no longer occuring 
  156. 	local twn_h = self.main_scroll_twn_h 
  157. 	local new_x, new_y = vint_get_property(twn_h, "end_value") 
  158. 	vint_set_property(twn_h, "start_value", new_x, new_y) 
  159.  
  160. 	-- Kill the thread that runs while the button is held 
  161. 	if self.scroll_thread ~= 0 then 
  162. 		thread_kill(self.scroll_thread) 
  163. 		self.scroll_thread = 0 
  164. 		self:scrollbar_set() 
  165. 	end 
  166. 	 
  167. 	self.scroll_direction = 0 
  168. end 
  169.  
  170.  
  171. function Vdo_scrollbox:on_destroy() 
  172. 	if self.scroll_thread ~= nil then 
  173. 		thread_kill(self.scroll_thread) 
  174. 	end 
  175. end 
  176.  
  177. ------------------------------------------------------------------------------- 
  178. -- Sets text tag of default element... 
  179. -- @param	width		Width of scroll box without scrollbar 
  180. -- @param	height	Width of scroll box with scrollbar 
  181. function Vdo_scrollbox:set_size(width, height) 
  182. 	--set size of clip region... 
  183. 	vint_set_property(self.clip_h, "clip_size", width, height) 
  184. 	self.clip_width = width 
  185. 	self.clip_height = height 
  186. 	 
  187. 	vint_set_property(self.text_h, "wrap_width", width) 
  188. 	 
  189. 	--position scrollbar 
  190. 	vint_set_property(self.scrollbar.handle, "anchor", width + VDO_SCROLLBOX_BAR_SPACING, 0) 
  191. end 
  192.  
  193. ------------------------------------------------------------------------------- 
  194. -- Sets text tag of default element... 
  195. -- @param	text_tag		text tag to set the element to. 
  196. -- 
  197. function Vdo_scrollbox:set_text(text_tag) 
  198. 	--reset position 
  199. 	vint_set_property(self.scroll_item_h, "anchor", 0, 0) 
  200. 	 
  201. 	vint_set_property(self.text_h, "text_tag", text_tag) 
  202. 	 
  203. 	self.content_width, self.content_height = element_get_actual_size(self.text_h) 
  204. 	self.content_height = self.content_height + 4---+ 8 -- padd the box because the text height is deceiving. 
  205. 	--Determine if we need a scrollbar or not... if our content height is greater than 
  206. 	if self.clip_height < self.content_height then 
  207. 		-- Show scrollbar and set its properties... 
  208. 		self.scrollbar:set_property("visible", true) 
  209. 		self.scrollbar:set_size(SCROLLBAR_WIDTH, self.clip_height)		 
  210. 		self:scrollbar_set() 
  211. 	else 
  212. 		-- No scrollbar needed. 
  213. 		self.scrollbar:set_property("visible", false)	 
  214. 	end 
  215. end 
  216.  
  217. ------------------------------------------------------------------------------- 
  218. -- Resets the scroll bar to current state of our box... 
  219. -- 
  220. function Vdo_scrollbox:scrollbar_set() 
  221. 	local x, y = vint_get_property(self.scroll_item_h, "anchor") 
  222. 	local bottom_y = y + self.content_height 
  223.  
  224. 	-- Create the 'indices' to reference with the scroll bar.. we do this in pixel amoutns 
  225.  
  226. 	-- Our current index is how far the task_bottom is from the entire height of the text 
  227. 	local index = floor(self.content_height - bottom_y) + 1-- not sure about this +1 
  228. 	 
  229. 	-- The max index is the height of the item, minus the visible area of the text 
  230. 	local max_index = floor(self.content_height - self.clip_height) + 1 
  231. 	 
  232. 	if index > max_index then 
  233. 		index = max_index 
  234. 	end 
  235. 	 
  236. 	self.scrollbar:set_value(max_index, index, true) 
  237. end 
  238.  
  239. function Vdo_scrollbox:reset() 
  240. 	--Reset  
  241. end 
  242.  
  243. function vdo_scrollbox_scroll_thread(vdo_object) 
  244. 	while true do 
  245. 		-- Set the scrollbar position based on where the text currently is (should be tweening) 
  246. 		vdo_object:scrollbar_set() 
  247. 		debug_print("vint", "self.scroll_direction".. vdo_object.scroll_direction .. "\n") 
  248. 		thread_yield() 
  249. 	end 
  250. end 
  251.  
  252. function Vdo_scrollbox:set_color(color) 
  253. 	self.scrollbar:set_highlight_color(color) 
  254. end 
  255.  
  256. --[[ 
  257.  
  258. --MOVE TO VINTLIB 
  259. local Internal_threaded_objects = { } 
  260.  
  261. function vint_lua_create_threaded_object(func_name, object) 
  262. 	local id = thread_new(vint_lua_threaded_object_thread) 
  263. 	Internal_threaded_objects[id] = { object = object, function_name = func_name } 
  264. 	object.internal_thread_handle = id 
  265. 	return id 
  266. end 
  267.  
  268. function vint_lua_threaded_object_thread() 
  269. 	thread_yield() 
  270. 	local object = Internal_threaded_objects[thread_get_handle()] 
  271. 	 
  272. 	object.func_name(object.object) 
  273. 	 
  274. 	vint_lua_exit_threaded_object() 
  275. end 
  276.  
  277. function test_function(object) 
  278. 	-- object = thing you want to process 
  279. end 
  280.  
  281. function vint_lua_create_threaded_object(func_name, object) 
  282. 	local id = thread_new(func_name) 
  283. 	Internal_threaded_objects[id] = object 
  284. 	object.internal_thread_handle = id 
  285. 	return id 
  286. end 
  287.  
  288. function vint_lua_get_threaded_object() 
  289. 	thread_yield() 
  290. 	return Internal_threaded_objects[thread_get_handle()] 
  291. end 
  292.  
  293. function vint_lua_get_threaded_object_handle(object) 
  294. 	if Internal_threaded_objects[object.internal_thread_handle] ~= nil then 
  295. 		return object.internal_thread_handle 
  296. 	else  
  297. 		return nil 
  298. 	end 
  299. end 
  300.  
  301. function vint_lua_exit_threaded_object() 
  302. 	local id = thread_get_handle() 
  303. 	local object = Internal_threaded_objects[id] 
  304. 	object.internal_thread_handle = nil 
  305. 	Internal_threaded_objects[id] = nil 
  306. end 
  307.  
  308. function vint_lua_kill_threaded_object(object) 
  309. 	local thread_handle = object.internal_thread_handle 
  310. 	thread_kill(thread_handle) 
  311. 	Internal_threaded_objects[thread_handle] = nil 
  312. end 
  313.  
  314. --Example creating thread object... 
  315. function Vdo_scrollbar:create_thread() 
  316. 	vint_lua_create_threaded_object("test_thread", self) 
  317. end 
  318.  
  319. --Example killing thread object... 
  320. function Vdo_scrollbar:kill_thread() 
  321. 	vint_lua_kill_threaded_object(self) 
  322. end 
  323.  
  324.  
  325. --Example thread... 
  326. function test_thread() 
  327. 	local cur_obj = vint_lua_get_threaded_object() 
  328. 	 
  329. 	--Do thread logic in here... 
  330. 	 
  331. 	--MUST BE CALLED, or you will have a memory leak(A really bad memory leak.) 
  332. 	vint_lua_exit_threaded_object() 
  333. end 
  334.  
  335.  
  336.  
  337.  
  338. ------------------ 
  339. ------------------- 
  340. ------------------ 
  341. --Call this to create a new threaded object... 
  342. function vint_lua_threaded_object_create(func_name, object) 
  343. 	local id = thread_new(vint_lua_threaded_object_thread) 
  344. 	Internal_threaded_objects[id] = { object = object, function_name = func_name } 
  345. 	object.vint_lua_internal_thread_handle = id 
  346. 	return id 
  347. end 
  348.  
  349. -- Use this to get the handle to the  
  350. function vint_lua_get_threaded_object_handle(object) 
  351. 	if Internal_threaded_objects[object.vint_lua_internal_thread_handle] ~= nil then 
  352. 		return object.vint_lua_internal_thread_handle 
  353. 	else  
  354. 		return nil 
  355. 	end 
  356. end 
  357.  
  358. function vint_lua_kill_threaded_object(object) 
  359. 	local thread_handle = object.internal_thread_handle 
  360. 	thread_kill(thread_handle) 
  361. 	Internal_threaded_objects[thread_handle] = nil 
  362. end 
  363.  
  364. --Internal to vint_lua_threaded_object...() 
  365. function vint_lua_threaded_object_thread() 
  366. 	thread_yield() 
  367. 	local id = thread_get_handle() 
  368. 	local object = Internal_threaded_objects[id] 
  369.  
  370. 	object.func_name(object.object) 
  371.  
  372. 	object.internal_thread_handle = nil 
  373. 	Internal_threaded_objects[id] = nil 
  374. end 
  375.  
  376. --Example creating thread object... 
  377. function Vdo_scrollbar:create_thread() 
  378. 	vint_lua_create_threaded_object("test_thread", self) 
  379. end 
  380.  
  381. --Example killing thread object... 
  382. function Vdo_scrollbar:kill_thread() 
  383. 	vint_lua_kill_threaded_object(self) 
  384. end 
  385.  
  386.  
  387. --Example thread... 
  388. --object is your reference.. 
  389. function test_thread(object) 
  390. 	--object... 
  391. end 
  392. ]] 
  393.