SSM_PiMonitor/pimonitor/ui/PMScreen.py
2013-12-02 22:00:58 -07:00

235 lines
5.7 KiB
Python

'''
Created on 18-04-2013
@author: citan
'''
import pygame
import os.path
import os
import sys
from pimonitor.PM import PM
from pimonitor.PMUtils import PMUtils
class PMScreen(object):
'''
classdocs
'''
LOG_FPS_EVENT = pygame.USEREVENT + 1
LOG_STATS_EVENT = LOG_FPS_EVENT + 1
ONE_SEC_EVENT = LOG_STATS_EVENT + 1
def __init__(self):
'''
Constructor
'''
pygame.init()
pygame.mouse.set_visible(False)
# seems to suit RPi
self._color_depth = 16
pygame.display.set_mode((0, 0), pygame.FULLSCREEN, self._color_depth)
#pygame.display.set_mode((640, 480), 0, self._color_depth)
self._surface = pygame.display.get_surface()
self._clock = pygame.time.Clock()
self._width = self._surface.get_width();
self._height = self._surface.get_height();
self._subwindow_alpha = 200
self._font_size = int(self._height / 14)
self._font = pygame.font.SysFont(pygame.font.get_default_font(), self._font_size)
self._font_aa = 0
self._fg_color = pygame.Color(255, 191, 0)
self._bg_color = pygame.Color(0, 0, 0)
self._dim_color = pygame.Color(200, 140, 0)
self._log_lines = 4
self._log_msg_id = 0
self._log_surface = pygame.Surface((self._width / 2, self._font_size * self._log_lines), 0, self._color_depth)
self._log_surface.set_alpha(self._subwindow_alpha)
self._log_queue = []
logger = PM()
logger.set(self.log)
self._fps_log_id = 0
self._frame_no = 0
self.load_resources()
pygame.time.set_timer(PMScreen.LOG_FPS_EVENT, 10000)
pygame.time.set_timer(PMScreen.LOG_STATS_EVENT, 30000)
pygame.time.set_timer(PMScreen.ONE_SEC_EVENT, 1000)
self._window = None
self._windows = []
self._pos_log_id = 0;
self._mouse_down_pos = (0, 0);
self._mouse_down_mark_timeout = 0
def clear(self):
self._surface.fill(self._bg_color)
def load_resources(self):
self._bg_img = pygame.image.load(os.path.join('res', 'subaru_logo.png')).convert()
self._bg_img_rect = self._bg_img.get_rect()
def render(self):
self._clock.tick()
for event in pygame.event.get():
if event.type == PMScreen.LOG_FPS_EVENT:
self._frame_no += 1
self._fps_log_id = PM.log("FPS %.2f" % self._clock.get_fps(), self._fps_log_id)
elif event.type == PMScreen.LOG_STATS_EVENT:
PMUtils.log_os_stats()
elif event.type == pygame.QUIT:
self.close()
sys.exit()
elif event.type == pygame.MOUSEBUTTONUP:
self._mouse_down_mark_timeout = 0
self._mouse_down_pos = pygame.mouse.get_pos();
self._pos_log_id = PM.log('Mouse up at: %s/%s' % pygame.mouse.get_pos(), self._pos_log_id);
if self._mouse_down_pos[0] < self._width / 2:
self.prev_window()
else:
self.next_window()
elif event.type == PMScreen.ONE_SEC_EVENT:
self._mouse_down_mark_timeout += 1
self.clear()
if self._window == None:
self.render_bg()
if self._window != None:
self._window.render()
self.render_log()
if self._mouse_down_mark_timeout < 2:
pygame.draw.circle(self._surface, self._dim_color, self._mouse_down_pos, 16);
pygame.display.update()
def render_log(self):
self.purge_logs()
if len(self._log_queue) == 0:
return
self._log_surface.fill(self._bg_color)
log_pos = 0
for msg_entry in self._log_queue:
msg_entry[2] = msg_entry[2] + 1
message = msg_entry[1]
message_lbl = self._font.render(message, self._font_aa, self._fg_color, self._bg_color)
self._log_surface.blit(message_lbl, (0, log_pos))
log_pos += self._font_size
self._surface.blit(self._log_surface, (0, self._height - self._log_surface.get_height()))
def render_bg(self):
#self._surface.blit(self._bg_img, self._bg_img_rect)
pass
def purge_oldest_log(self):
oldest = pygame.time.get_ticks()
for log_entry in self._log_queue:
if log_entry[2] < oldest:
oldest = log_entry[2]
to_be_deleted = log_entry
self._log_queue.remove(to_be_deleted)
def purge_logs(self):
to_be_deleted = []
for log_entry in self._log_queue:
if pygame.time.get_ticks() - log_entry[2] > 5000:
to_be_deleted.append(log_entry)
for log_entry in to_be_deleted:
self._log_queue.remove(log_entry)
def add_window(self, window):
self._windows.append(window);
if self._window == None:
self.next_window()
pass
def set_window(self, window):
if self._window != None:
self._window.set_surface(None)
self._window = window
self._window.set_surface(self._surface)
def get_window(self):
return self._window
def next_window(self):
if not self._windows:
return
if self._window != None:
index = self._windows.index(self._window)
else:
index = -1
new_index = (index + 1) % len(self._windows)
self.set_window(self._windows[new_index])
self.log_window(new_index)
def prev_window(self):
if not self._windows:
return
if self._window != None:
index = self._windows.index(self._window)
else:
index = 1
new_index = (index - 1) % len(self._windows)
self.set_window(self._windows[new_index])
self.log_window(new_index)
def log_window(self, index):
if self._window != None:
PM.log(str(index + 1) + '/' + str(len(self._windows)) + ': ' + self._window.get_parameter().get_id(), 0)
def log(self, message, mid):
ticks = pygame.time.get_ticks()
if mid == 0:
self._log_msg_id = (self._log_msg_id % 1000) + 1
mid = self._log_msg_id
found = False
for log_entry in self._log_queue:
if log_entry[0] == mid:
log_entry[1] = message
found = True
log_entry[2] = ticks
self.purge_logs()
# remove old messages if necessary
if not found:
if len(self._log_queue) >= self._log_lines :
self.purge_oldest_log()
self._log_queue.append([mid, message, ticks])
self.render()
return mid
def close(self):
pygame.display.quit()