blob: bb4f2577337c780da06d291938cc6eb3bb73edf1 [file] [log] [blame]
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""This module provides GUI for touch device firmware test using GTK."""
import re
import gobject
import gtk
import gtk.gdk
import pango
import firmware_utils
import test_conf as conf
from firmware_constants import TFK
TITLE = "Touch Firmware Test"
class BaseFrame(object):
"""A simple base frame class."""
def __init__(self, label=None, size=None, aspect=False):
# Create a regular/aspect frame
self.frame = gtk.AspectFrame() if aspect else gtk.Frame()
self.size = size
if label:
self.frame.set_label_align(0.0, 0.0)
frame_label = self.frame.get_label_widget()
markup_str = '<span foreground="%s" size="x-large">%s</span>'
frame_label.set_markup(markup_str % ('black', label))
if size:
width, height = size
self.frame.set_size_request(width, height)
if aspect:
self.frame.set(ratio=(float(width) / height))
class PromptFrame(BaseFrame):
"""A simple frame widget to display the prompt.
It consists of:
- A frame
- a label showing the gesture name
- a label showing the prompt
- a label showing the keyboard interactions
def __init__(self, label=None, size=None):
super(PromptFrame, self).__init__(label, size)
# Create a vertical packing box.
self.vbox = gtk.VBox(False, 0)
# Create a label to show the gesture name
self.label_gesture = gtk.Label('Gesture Name')
self.vbox.pack_start(self.label_gesture, True, True, 0)
# Expand the lable to be wider and wrap the line if necessary.
if self.size:
_, label_height = self.label_gesture.get_size_request()
width, _ = self.size
label_width = int(width * 0.9)
self.label_gesture.set_size_request(label_width, label_height)
# Pack a horizontal separator
self.vbox.pack_start(gtk.HSeparator(), True, True, 0)
# Create a label to show the prompt
self.label_prompt = gtk.Label('Prompt')
self.vbox.pack_start(self.label_prompt, True, True, 0)
# Create a label to show the choice
self.label_choice = gtk.Label('')
self.vbox.pack_start(self.label_choice, True, True, 0)
# Show all widgets added to this frame
def set_gesture_name(self, string, color='blue'):
"""Set the gesture name in label_gesture."""
markup_str = '<b><span foreground="%s" size="xx-large"> %s </span></b>'
self.label_gesture.set_markup(markup_str % (color, string))
def set_prompt(self, string, color='black'):
"""Set the prompt in label_prompt."""
markup_str = '<span foreground="%s" size="x-large"> %s </span>'
self.label_prompt.set_markup(markup_str % (color, string))
def set_choice(self, string):
"""Set the choice in label_choice."""
class ResultFrame(BaseFrame):
"""A simple frame widget to display the test result.
It consists of:
- A frame
- a scrolled window
- a label showing the test result
def __init__(self, label=None, size=None):
super(ResultFrame, self).__init__(label, size)
# Create a scrolled window widget
self.scrolled_window = gtk.ScrolledWindow()
# Create a vertical packing box.
self.vbox = gtk.VBox(False, 0)
# Create a label to show the gesture name
self.result = gtk.Label()
self.vbox.pack_start(self.result , False, False, 0)
# Show all widgets added to this frame
# Get the vertical and horizontal adjustments
self.vadj = self.scrolled_window.get_vadjustment()
self.hadj = self.scrolled_window.get_hadjustment()
self._scroll_func_dict = {TFK.UP: self._scroll_up,
TFK.DOWN: self._scroll_down,
TFK.LEFT: self._scroll_left,
TFK.RIGHT: self._scroll_right}
def _calc_result_font_size(self):
"""Calculate the font size so that it does not overflow."""
label_width_in_px, _ = self.size
font_size = int(float(label_width_in_px) / conf.num_chars_per_row *
return font_size
def set_result(self, text, color='black'):
"""Set the text in the result label."""
mod_text = re.sub('<', '&lt;', text)
mod_text = re.sub('>', '&gt;', mod_text)
markup_str = '<b><span foreground="%s" size="%d"> %s </span></b>'
font_size = self._calc_result_font_size()
self.result.set_markup(markup_str % (color, font_size, mod_text))
def _calc_inc_value(self, adj):
"""Calculate new increased value of the specified adjustement object."""
value = adj.get_value()
new_value = min(value + self.SCROLL_STEP, adj.upper - adj.page_size)
return new_value
def _calc_dec_value(self, adj):
"""Calculate new decreased value of the specified adjustement object."""
value = adj.get_value()
new_value = max(value - self.SCROLL_STEP, adj.lower)
return new_value
def _scroll_down(self):
"""Scroll the scrolled_window down."""
def _scroll_up(self):
"""Scroll the scrolled_window up."""
def _scroll_right(self):
"""Scroll the scrolled_window to the right."""
def _scroll_left(self):
"""Scroll the scrolled_window to the left."""
def scroll(self, choice):
"""Scroll the result frame using the choice key."""
scroll_method = self._scroll_func_dict.get(choice)
if scroll_method:
print 'Warning: the key choice "%s" is not legal!' % choice
class ImageFrame(BaseFrame):
"""A simple frame widget to display the mtplot window.
It consists of:
- An aspect frame
- an image widget showing mtplot
def __init__(self, label=None, size=None):
super(ImageFrame, self).__init__(label, size, aspect=True)
# Use a fixed widget to display the image.
self.fixed = gtk.Fixed()
# Create an image widget.
self.image = gtk.Image()
self.fixed.put(self.image, 0, 0)
# Show all widgets added to this frame
def set_from_file(self, filename):
"""Set the image file."""
class FirmwareWindow(object):
"""A simple window class to display the touch firmware test window."""
def __init__(self, size=None, prompt_size=None, result_size=None,
# Create a new window = gtk.Window(gtk.WINDOW_TOPLEVEL)
if size:
self.win_size = size*size)
# Create the prompt frame
self.prompt_frame = PromptFrame(TITLE, prompt_size)
# Create the result frame
self.result_frame = ResultFrame("Test results:", size=result_size)
# Create the image frame for mtplot
self.image_frame = ImageFrame(size=image_size)
# Handle layout below
self.box0 = gtk.VBox(False, 0)
self.box1 = gtk.HBox(False, 0)
# Arrange the layout about box0
self.box0.pack_start(self.prompt_frame.frame, True, True, 0)
self.box0.pack_start(self.box1, True, True, 0)
# Arrange the layout about box1
self.box1.pack_start(self.image_frame.frame, True, True, 0)
self.box1.pack_start(self.result_frame.frame, True, True, 0)
# Capture keyboard events. | gtk.gdk.KEY_RELEASE_MASK)
# Set a handler for delete_event that immediately exits GTK."delete_event", self.delete_event)
# Show all widgets.
def register_callback(self, event, callback):
"""Register a callback function for an event.""", callback)
def register_timeout_add(self, callback, timeout):
"""Register a callback function for gobject.timeout_add."""
return gobject.timeout_add(timeout, callback)
def register_io_add_watch(self, callback, fd, data=None,
"""Register a callback function for gobject.io_add_watch."""
if data:
return gobject.io_add_watch(fd, condition, callback, data)
return gobject.io_add_watch(fd, condition, callback)
def create_key_press_event(self, keyval):
"""Create a key_press_event."""
event = gtk.gdk.Event(gtk.gdk.KEY_PRESS)
# Assign current time to the event
event.time = 0
event.keyval = keyval'key_press_event', event)
def remove_event_source(self, tag):
"""Remove the registered callback."""
def delete_event(self, widget, event, data=None):
"""A handler to exit the window."""
return False
def set_input_focus(self):
"""Set input focus to this window."""
x = firmware_utils.SimpleX(TITLE)
def set_gesture_name(self, string, color='blue'):
"""A helper method to set gesture name."""
self.prompt_frame.set_gesture_name(string, color)
def set_prompt(self, string, color='black'):
"""A helper method to set the prompt."""
self.prompt_frame.set_prompt(string, color)
def set_choice(self, string):
"""A helper method to set the choice."""
def set_result(self, text):
"""A helper method to set the text in the result."""
def set_image(self, filename):
"""Set an image in the image frame."""
def scroll(self, choice):
"""Scroll the result frame using the choice key."""
def stop(self):
"""Quit the window."""
def main(self):
"""Main function of the window."""