list_view.py 6.4 KB

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