235 lines
5.7 KiB
Python
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()
|