list_view.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import logging
  2. from screen_objects import ScreenObjectsManager, ScrollBar, \
  3. TouchAndTextItem
  4. from ..input import InputManager
  5. logger = logging.getLogger(__name__)
  6. class ListView():
  7. def __init__(self, pos, size, base_size, font):
  8. self.size = size
  9. self.pos = pos
  10. self.base_size = base_size
  11. self.screen_objects = ScreenObjectsManager()
  12. self.max_rows = self.size[1] / self.base_size
  13. self.current_item = 0
  14. self.font = font
  15. self.list_size = 0
  16. self.list = []
  17. self.scrollbar = False
  18. self.selected = None
  19. self.active = []
  20. self.set_list([])
  21. # Sets the list for the lisview.
  22. # It should be an iterable of strings
  23. def set_list(self, item_list):
  24. self.screen_objects.clear()
  25. self.list = item_list
  26. self.list_size = len(item_list)
  27. if self.max_rows < self.list_size:
  28. self.scrollbar = True
  29. scroll_bar = ScrollBar(
  30. (self.pos[0] + self.size[0] - self.base_size,
  31. self.pos[1]),
  32. (self.base_size, self.size[1]), self.list_size,
  33. self.max_rows)
  34. self.screen_objects.set_touch_object("scrollbar",
  35. scroll_bar)
  36. else:
  37. self.scrollbar = False
  38. if self.list_size > 0:
  39. self.selected = 0
  40. else:
  41. self.selected = None
  42. self.load_new_item_position(0)
  43. # Will load items currently displaying in item_pos
  44. def load_new_item_position(self, item_pos):
  45. self.current_item = item_pos
  46. if self.scrollbar:
  47. self.screen_objects.clear_touch(["scrollbar"])
  48. else:
  49. self.screen_objects.clear_touch(None)
  50. i = self.current_item
  51. z = 0
  52. if self.scrollbar:
  53. width = self.size[0] - self.base_size
  54. else:
  55. width = self.size[0]
  56. while i < self.list_size and z < self.max_rows:
  57. item = TouchAndTextItem(self.font, self.list[i], (
  58. self.pos[0],
  59. self.pos[1] + self.base_size * z), (width, -1))
  60. self.screen_objects.set_touch_object(str(i), item)
  61. i += 1
  62. z += 1
  63. self.reload_selected()
  64. def render(self, surface):
  65. self.screen_objects.render(surface)
  66. def touch_event(self, touch_event):
  67. if touch_event.type == InputManager.click \
  68. or touch_event.type == InputManager.long_click:
  69. objects = self.screen_objects.get_touch_objects_in_pos(
  70. touch_event.current_pos)
  71. if objects is not None:
  72. for key in objects:
  73. if key == "scrollbar":
  74. direction = \
  75. self.screen_objects.get_touch_object(
  76. key).touch(touch_event.current_pos)
  77. if direction != 0:
  78. self.move_to(direction)
  79. else:
  80. return int(key)
  81. elif (touch_event.type == InputManager.key and
  82. self.selected is not None):
  83. if touch_event.direction == InputManager.enter:
  84. if self.selected is not None:
  85. return self.selected
  86. elif touch_event.direction == InputManager.up:
  87. self.set_selected(self.selected-1)
  88. elif touch_event.direction == InputManager.down:
  89. self.set_selected(self.selected+1)
  90. elif touch_event.type == InputManager.swipe:
  91. if touch_event.direction == InputManager.up:
  92. self.move_to(-1)
  93. elif touch_event.direction == InputManager.down:
  94. self.move_to(1)
  95. # Scroll to direction
  96. # direction == 1 will scroll down
  97. # direction == -1 will scroll up
  98. def move_to(self, direction):
  99. if self.scrollbar:
  100. if direction == 1:
  101. self.current_item += self.max_rows
  102. if self.current_item + self.max_rows > self.list_size:
  103. self.current_item = self.list_size - self.max_rows
  104. self.load_new_item_position(self.current_item)
  105. self.screen_objects.get_touch_object(
  106. "scrollbar").set_item(
  107. self.current_item)
  108. elif direction == -1:
  109. self.current_item -= self.max_rows
  110. if self.current_item < 0:
  111. self.current_item = 0
  112. self.load_new_item_position(self.current_item)
  113. self.screen_objects.get_touch_object(
  114. "scrollbar").set_item(
  115. self.current_item)
  116. self.set_active(self.active)
  117. # Set active items
  118. def set_active(self, active):
  119. for number in self.active:
  120. try:
  121. self.screen_objects.get_touch_object(
  122. str(number)).set_active(
  123. False)
  124. except KeyError:
  125. pass
  126. for number in active:
  127. try:
  128. self.screen_objects.get_touch_object(
  129. str(number)).set_active(
  130. True)
  131. except KeyError:
  132. pass
  133. self.active = active
  134. def set_selected(self, selected):
  135. if selected > -1 and selected < len(self.list):
  136. if self.selected is not None:
  137. try:
  138. self.screen_objects.get_touch_object(
  139. str(self.selected)).set_selected(
  140. False)
  141. except KeyError:
  142. pass
  143. if selected is not None:
  144. try:
  145. self.screen_objects.get_touch_object(
  146. str(selected)).set_selected(
  147. True)
  148. except KeyError:
  149. pass
  150. self.selected = selected
  151. self.set_selected_on_screen()
  152. def set_selected_on_screen(self):
  153. if self.current_item + self.max_rows <= self.selected:
  154. self.move_to(1)
  155. self.set_selected_on_screen()
  156. elif self.current_item > self.selected:
  157. self.move_to(-1)
  158. self.set_selected_on_screen()
  159. def reload_selected(self):
  160. if self.selected is not None:
  161. try:
  162. self.screen_objects.get_touch_object(
  163. str(self.selected)).set_selected(
  164. True)
  165. except KeyError:
  166. pass