Files
r_e_c_u_r/display_centre/display.py

229 lines
10 KiB
Python

from tkinter import Text, END
import math
import time
class Display(object):
MENU_HEIGHT = 10
SELECTOR_WIDTH = 0.47
ROW_OFFSET = 6.0
VIDEO_DISPLAY_TEXT = ' NOW [{}] {} NEXT [{}] {}'
VIDEO_DISPLAY_BANNER_TEXT = ' {} {} {}'
def __init__(self, tk, video_driver, message_handler, data):
self.tk = tk
self.video_driver = video_driver
self.message_handler = message_handler
self.data = data
self.display_mode = "SAMPLER"
self.control_mode = 'PLAYER'
self.top_menu_index = 0
self.selected_list_index = self.top_menu_index
self.browser_list = self.data.rewrite_browser_list()
self.display_text = self._create_display_text(self.tk)
self._add_tags()
self._update_screen_every_second()
@staticmethod
def _create_display_text(tk):
return Text(tk, bg="black", fg="white", font=('courier', 13))
def _add_tags(self):
self.display_text.tag_configure("SELECT", background="white", foreground="black")
self.display_text.tag_configure("TITLE", background="black", foreground="red")
self.display_text.tag_configure("DISPLAY_MODE", background="black", foreground="magenta")
self.display_text.tag_configure("ERROR_MESSAGE", background="red", foreground="white")
self.display_text.tag_configure("INFO_MESSAGE", background="blue", foreground="white")
self.display_text.tag_configure("PLAYER_INFO", background="black", foreground="yellow")
self.display_text.tag_configure("COLUMN_NAME", background="black", foreground="cyan")
self.display_text.tag_configure("FUNCTION", background="cyan", foreground="black")
def _load_display(self):
self._load_title()
self._load_player()
self._load_display_body()
self._load_message()
self.display_text.pack()
def _load_title(self):
self.display_text.insert(END, '================== r_e_c_u_r ================== \n')
self.display_text.tag_add("TITLE", 1.19, 1.28)
def _load_player(self):
text, banner = self._get_info_for_player()
end_of_text = float("3." + str(len(text)))
end_of_banner = float("3." + str(len(banner)))
self.display_text.insert(END, text + '\n')
self.display_text.tag_add("PLAYER_INFO", 2.0, end_of_text)
self.display_text.insert(END, banner + '\n')
self.display_text.tag_add("PLAYER_INFO", 3.0, end_of_banner)
def _load_display_body(self):
if self.display_mode == 'BROWSER':
self._load_browser()
elif self.display_mode == 'SETTINGS':
self._load_settings()
else:
self._load_sampler()
self.display_text.tag_add("COLUMN_NAME", 5.0, 6.0)
self._highlight_this_row(self.selected_list_index - self.top_menu_index)
def _load_sampler(self):
bank_data = self.data.get_sampler_data()
self.display_text.insert(END, '------------------ <SAMPLER> ------------------ \n')
self.display_text.tag_add("DISPLAY_MODE", 4.19, 4.29)
self.display_text.insert(END, '{:^4} {:<22} {:<4} {:<4} {:<4} \n'.format(
'slot', 'name', 'length', 'start', 'end'))
for index, slot in enumerate(bank_data):
name_without_extension = slot['name'].rsplit('.',1)[0]
self.display_text.insert(END, '{:^4} {:<22} {:<4} {:<4} {:<4} \n'.format(
index, name_without_extension[0:22], self.format_time_value(slot['length']),
self.format_time_value(slot['start']), self.format_time_value(slot['end'])))
if self.video_driver.current_player.slot_number is '-':
self.selected_list_index = 0
else:
self.selected_list_index = self.video_driver.current_player.slot_number
def _load_browser(self):
browser_list = self.data.return_browser_list()
number_of_lines_displayed = 0
self.display_text.insert(END, '------------------ <BROWSER> ------------------ \n')
self.display_text.tag_add("DISPLAY_MODE", 4.19, 4.29)
self.display_text.insert(END, '{:40} {:5} \n'.format('path', 'slot'))
number_of_browser_items = len(browser_list)
for index in range(number_of_browser_items):
if number_of_lines_displayed >= self.MENU_HEIGHT:
break
if index >= self.top_menu_index:
path = browser_list[index]
self.display_text.insert(END, '{:40} {:5} \n'.format(path['name'][0:35], path['slot']))
number_of_lines_displayed = number_of_lines_displayed + 1
for index in range(self.MENU_HEIGHT - number_of_browser_items):
self.display_text.insert(END, '\n')
def _load_settings(self):
line_count = 0
settings_list = self.data.get_settings_data()
self.display_text.insert(END, '------------------ <SETTINGS> ----------------- \n')
self.display_text.tag_add("DISPLAY_MODE", 4.19, 4.29)
self.display_text.insert(END, '{:^23} {:^22} \n'.format('SETTING', 'VALUE'))
number_of_settings_items = len(settings_list)
for index in range(number_of_settings_items):
if line_count >= self.MENU_HEIGHT:
break
if index >= self.top_menu_index:
setting = settings_list[index]
self.display_text.insert(END, '{:>23} {:<22} \n'.format(setting['name'], setting['options'][0][0:20]))
line_count = line_count + 1
for index in range(self.MENU_HEIGHT - number_of_settings_items):
self.display_text.insert(END, '\n')
def _load_message(self):
if self.message_handler.current_message[1]:
self.display_text.insert(END, '{:5} {:38}'.format(
self.message_handler.current_message[0], self.message_handler.current_message[1][0:38]))
self.display_text.tag_add('{}_MESSAGE'.format(
self.message_handler.current_message[0]), 16.0,16.0 + self.SELECTOR_WIDTH)
if self.message_handler.current_message[2]:
self.message_handler.current_message[2] = False
message_length = 4000
self.tk.after(message_length, self.message_handler.clear_message)
elif self.message_handler.function_on:
self.display_text.insert(END, '{:^45}'.format('< FUNCTION KEY ON >'))
self.display_text.tag_add('FUNCTION', 16.0,16.0 + self.SELECTOR_WIDTH)
else:
self.display_text.insert(END, '{:8} {:<10}'.format('CONTROL:', self.control_mode))
self.display_text.tag_add('TITLE', 16.0,16.0 + self.SELECTOR_WIDTH)
def _highlight_this_row(self, row):
self.display_text.tag_add("SELECT", self.ROW_OFFSET + row,
self.ROW_OFFSET + self.SELECTOR_WIDTH + row)
def _unhighlight_this_row(self, row):
self.display_text.tag_remove("SELECT", self.ROW_OFFSET + row,
self.ROW_OFFSET + self.SELECTOR_WIDTH + row)
def _get_info_for_player(self):
now_slot, now_status, next_slot, next_status, position, crop_length, start, end = self.video_driver.get_info_for_player_display()
banner = self.create_video_display_banner(start, end, crop_length, position)
time_been = self.format_time_value(position - start)
time_left = self.format_time_value(end - position)
return self.VIDEO_DISPLAY_BANNER_TEXT.format(time_been, banner, time_left), \
self.VIDEO_DISPLAY_TEXT.format(now_slot, now_status, next_slot, next_status)
@staticmethod
def create_video_display_banner(start, end, crop_length, position):
banner_list = ['[', '-', '-', '-', '-', '-', '-', '-', '-',
'-', '-', '-', '-', '-', '-', '-', '-', '-',
'-', '-', '-', '-', '-', '-', '-', '-', '-',
'-', '-', '-', '-', '-',
']']
max = len(banner_list) - 1
if position < start:
banner_list[0] = '<'
elif position > end:
banner_list[max] = '>'
elif crop_length != 0:
marker = int(math.floor(float(position - start) /
float(crop_length) * (max - 1)) + 1)
banner_list[marker] = '*'
return ''.join(banner_list)
def _update_screen_every_second(self):
self.refresh_display()
self.tk.after(500, self._update_screen_every_second)
def refresh_display(self):
self.display_text.configure(state='normal')
self.display_text.delete(1.0, END)
self._load_display()
self.display_text.configure(state='disable')
self.display_text.focus_set()
def navigate_menu(self, move_direction, number_items_in_list):
last_list_index = number_items_in_list - 1
bottom_menu_index = self.top_menu_index + self.MENU_HEIGHT - 1
self._unhighlight_this_row(self.selected_list_index - self.top_menu_index)
if move_direction == 'down':
if self.selected_list_index != last_list_index:
if self.selected_list_index == bottom_menu_index:
self.top_menu_index += 1
self.selected_list_index += 1
else:
self.top_menu_index = 0
self.selected_list_index = self.top_menu_index
elif move_direction == 'up':
if self.selected_list_index != 0:
if self.selected_list_index == self.top_menu_index:
self.top_menu_index -= 1
self.selected_list_index -= 1
else:
self.selected_list_index = last_list_index
self.top_menu_index = last_list_index - (self.MENU_HEIGHT - 1)
if self.top_menu_index < 0:
self.top_menu_index = 0
self._highlight_this_row(self.selected_list_index - self.top_menu_index)
return
@staticmethod
def format_time_value(time_in_seconds):
if time_in_seconds < 0:
return ''
elif time_in_seconds >= 6000:
return '99:99'
else:
return time.strftime("%M:%S", time.gmtime(time_in_seconds))