1f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang# Use of this source code is governed by a BSD-style license that can be 3f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang# found in the LICENSE file. 4f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 58c5e275df682ef5b0ad52574ae1e2e31fc724509Joseph Hwang"""This module provides GUI for touch device firmware test using GTK.""" 6f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 78abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwangimport os 8f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwangimport re 98abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwangimport shutil 10f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 11f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwangimport gobject 12f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwangimport gtk 13f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwangimport gtk.gdk 141ab9e6de0a658633e76b27fe00acce2039741694Joseph Hwangimport pango 158abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwangimport tempfile 16f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 178abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwangimport common_util 18f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwangimport firmware_utils 191ab9e6de0a658633e76b27fe00acce2039741694Joseph Hwangimport test_conf as conf 20f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 215a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwangfrom firmware_constants import TFK 225a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang 23f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 248c5e275df682ef5b0ad52574ae1e2e31fc724509Joseph HwangTITLE = "Touch Firmware Test" 25f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 26f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 27f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwangclass BaseFrame(object): 28f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """A simple base frame class.""" 29f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def __init__(self, label=None, size=None, aspect=False): 30f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Create a regular/aspect frame 31f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.frame = gtk.AspectFrame() if aspect else gtk.Frame() 32f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.frame.set_shadow_type(gtk.SHADOW_ETCHED_OUT) 3387df9932d281d5db1cbe9779eb049925424f46eaJoseph Hwang self.size = size 34f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang if label: 35f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.frame.set_label(label) 36f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.frame.set_label_align(0.0, 0.0) 37f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang frame_label = self.frame.get_label_widget() 38f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang markup_str = '<span foreground="%s" size="x-large">%s</span>' 39f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang frame_label.set_markup(markup_str % ('black', label)) 40f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang if size: 41f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang width, height = size 42f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.frame.set_size_request(width, height) 43f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang if aspect: 44f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.frame.set(ratio=(float(width) / height)) 45f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 46f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 47f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwangclass PromptFrame(BaseFrame): 48f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """A simple frame widget to display the prompt. 49f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 50f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang It consists of: 51f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang - A frame 52f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang - a label showing the gesture name 53f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang - a label showing the prompt 54f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang - a label showing the keyboard interactions 55f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """ 56f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 57f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def __init__(self, label=None, size=None): 58f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang super(PromptFrame, self).__init__(label, size) 59f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 60f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Create a vertical packing box. 61f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.vbox = gtk.VBox(False, 0) 62f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.frame.add(self.vbox) 63f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 64f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Create a label to show the gesture name 65f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.label_gesture = gtk.Label('Gesture Name') 66f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.label_gesture.set_justify(gtk.JUSTIFY_LEFT) 67f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.vbox.pack_start(self.label_gesture, True, True, 0) 6887df9932d281d5db1cbe9779eb049925424f46eaJoseph Hwang # Expand the lable to be wider and wrap the line if necessary. 6987df9932d281d5db1cbe9779eb049925424f46eaJoseph Hwang if self.size: 7087df9932d281d5db1cbe9779eb049925424f46eaJoseph Hwang _, label_height = self.label_gesture.get_size_request() 7187df9932d281d5db1cbe9779eb049925424f46eaJoseph Hwang width, _ = self.size 7287df9932d281d5db1cbe9779eb049925424f46eaJoseph Hwang label_width = int(width * 0.9) 7387df9932d281d5db1cbe9779eb049925424f46eaJoseph Hwang self.label_gesture.set_size_request(label_width, label_height) 7487df9932d281d5db1cbe9779eb049925424f46eaJoseph Hwang self.label_gesture.set_line_wrap(True) 7587df9932d281d5db1cbe9779eb049925424f46eaJoseph Hwang 7687df9932d281d5db1cbe9779eb049925424f46eaJoseph Hwang # Pack a horizontal separator 7787df9932d281d5db1cbe9779eb049925424f46eaJoseph Hwang self.vbox.pack_start(gtk.HSeparator(), True, True, 0) 78f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 79f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Create a label to show the prompt 80f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.label_prompt = gtk.Label('Prompt') 81f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.label_prompt.set_justify(gtk.JUSTIFY_CENTER) 82f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.vbox.pack_start(self.label_prompt, True, True, 0) 83f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 84f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Create a label to show the choice 85f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.label_choice = gtk.Label('') 86f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.label_choice.set_justify(gtk.JUSTIFY_LEFT) 87f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.vbox.pack_start(self.label_choice, True, True, 0) 88f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 89f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Show all widgets added to this frame 90f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.frame.show_all() 91f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 92f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def set_gesture_name(self, string, color='blue'): 93f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """Set the gesture name in label_gesture.""" 94f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang markup_str = '<b><span foreground="%s" size="xx-large"> %s </span></b>' 95f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.label_gesture.set_markup(markup_str % (color, string)) 96f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 97f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def set_prompt(self, string, color='black'): 98f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """Set the prompt in label_prompt.""" 99f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang markup_str = '<span foreground="%s" size="x-large"> %s </span>' 100f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.label_prompt.set_markup(markup_str % (color, string)) 101f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 102f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def set_choice(self, string): 103f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """Set the choice in label_choice.""" 104f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.label_choice.set_text(string) 105f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 106f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 107f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwangclass ResultFrame(BaseFrame): 108f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """A simple frame widget to display the test result. 109f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 110f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang It consists of: 111f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang - A frame 1125a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang - a scrolled window 113f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang - a label showing the test result 114f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """ 1155a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang SCROLL_STEP = 100.0 116f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 117f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def __init__(self, label=None, size=None): 118f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang super(ResultFrame, self).__init__(label, size) 119f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 1205a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang # Create a scrolled window widget 1215a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang self.scrolled_window = gtk.ScrolledWindow() 1225a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, 1235a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang gtk.POLICY_AUTOMATIC) 1245a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang self.frame.add(self.scrolled_window) 1255a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang 126f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Create a vertical packing box. 127f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.vbox = gtk.VBox(False, 0) 1285a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang self.scrolled_window.add_with_viewport(self.vbox) 129f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 130f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Create a label to show the gesture name 131f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.result = gtk.Label() 132f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.vbox.pack_start(self.result , False, False, 0) 133f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 134f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Show all widgets added to this frame 135f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.frame.show_all() 136f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 1375a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang # Get the vertical and horizontal adjustments 1385a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang self.vadj = self.scrolled_window.get_vadjustment() 1395a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang self.hadj = self.scrolled_window.get_hadjustment() 1405a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang 1415a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang self._scroll_func_dict = {TFK.UP: self._scroll_up, 1425a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang TFK.DOWN: self._scroll_down, 1435a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang TFK.LEFT: self._scroll_left, 1445a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang TFK.RIGHT: self._scroll_right} 1455a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang 1461ab9e6de0a658633e76b27fe00acce2039741694Joseph Hwang def _calc_result_font_size(self): 1471ab9e6de0a658633e76b27fe00acce2039741694Joseph Hwang """Calculate the font size so that it does not overflow.""" 1481ab9e6de0a658633e76b27fe00acce2039741694Joseph Hwang label_width_in_px, _ = self.size 1491ab9e6de0a658633e76b27fe00acce2039741694Joseph Hwang font_size = int(float(label_width_in_px) / conf.num_chars_per_row * 1501ab9e6de0a658633e76b27fe00acce2039741694Joseph Hwang pango.SCALE) 1511ab9e6de0a658633e76b27fe00acce2039741694Joseph Hwang return font_size 1521ab9e6de0a658633e76b27fe00acce2039741694Joseph Hwang 153f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def set_result(self, text, color='black'): 154f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """Set the text in the result label.""" 155f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang mod_text = re.sub('<', '<', text) 156f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang mod_text = re.sub('>', '>', mod_text) 1571ab9e6de0a658633e76b27fe00acce2039741694Joseph Hwang markup_str = '<b><span foreground="%s" size="%d"> %s </span></b>' 1581ab9e6de0a658633e76b27fe00acce2039741694Joseph Hwang font_size = self._calc_result_font_size() 1591ab9e6de0a658633e76b27fe00acce2039741694Joseph Hwang self.result.set_markup(markup_str % (color, font_size, mod_text)) 160f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 1615a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang def _calc_inc_value(self, adj): 1625a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang """Calculate new increased value of the specified adjustement object.""" 1635a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang value = adj.get_value() 1645a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang new_value = min(value + self.SCROLL_STEP, adj.upper - adj.page_size) 1655a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang return new_value 1665a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang 1675a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang def _calc_dec_value(self, adj): 1685a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang """Calculate new decreased value of the specified adjustement object.""" 1695a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang value = adj.get_value() 1705a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang new_value = max(value - self.SCROLL_STEP, adj.lower) 1715a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang return new_value 1725a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang 1735a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang def _scroll_down(self): 1745a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang """Scroll the scrolled_window down.""" 1755a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang self.vadj.set_value(self._calc_inc_value(self.vadj)) 1765a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang 1775a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang def _scroll_up(self): 1785a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang """Scroll the scrolled_window up.""" 1795a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang self.vadj.set_value(self._calc_dec_value(self.vadj)) 1805a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang 1815a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang def _scroll_right(self): 1825a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang """Scroll the scrolled_window to the right.""" 1835a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang self.hadj.set_value(self._calc_inc_value(self.hadj)) 1845a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang 1855a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang def _scroll_left(self): 1865a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang """Scroll the scrolled_window to the left.""" 1875a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang self.hadj.set_value(self._calc_dec_value(self.hadj)) 1885a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang 1895a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang def scroll(self, choice): 1905a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang """Scroll the result frame using the choice key.""" 1915a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang scroll_method = self._scroll_func_dict.get(choice) 1925a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang if scroll_method: 1935a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang scroll_method() 1945a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang else: 1955a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang print 'Warning: the key choice "%s" is not legal!' % choice 1965a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang 197f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 198f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwangclass ImageFrame(BaseFrame): 199f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """A simple frame widget to display the mtplot window. 200f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 201f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang It consists of: 202f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang - An aspect frame 203f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang - an image widget showing mtplot 204f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """ 205f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 206f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def __init__(self, label=None, size=None): 207f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang super(ImageFrame, self).__init__(label, size, aspect=True) 208f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 209f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Use a fixed widget to display the image. 210f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.fixed = gtk.Fixed() 211f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.frame.add(self.fixed) 212f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 213f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Create an image widget. 214f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.image = gtk.Image() 215f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.fixed.put(self.image, 0, 0) 216f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 217f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Show all widgets added to this frame 218f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.frame.show_all() 219f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 220f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def set_from_file(self, filename): 221f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """Set the image file.""" 222f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.image.set_from_file(filename) 223f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.frame.show_all() 224f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 225f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 226f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwangclass FirmwareWindow(object): 2278c5e275df682ef5b0ad52574ae1e2e31fc724509Joseph Hwang """A simple window class to display the touch firmware test window.""" 228f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 229f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def __init__(self, size=None, prompt_size=None, result_size=None, 230f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang image_size=None): 2318abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Setup gtk environment correctly. 2328abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang self._setup_gtk_environment() 23321df1fa2829a71c8c43ea807c75595d39352b229Joseph Hwang 234f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Create a new window 235f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.win = gtk.Window(gtk.WINDOW_TOPLEVEL) 236f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang if size: 237f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.win_size = size 238f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.win.resize(*size) 239f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.win.set_title(TITLE) 240f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.win.set_border_width(0) 241f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 242f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Create the prompt frame 243f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.prompt_frame = PromptFrame(TITLE, prompt_size) 244f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 245f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Create the result frame 246f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.result_frame = ResultFrame("Test results:", size=result_size) 247f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 248f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Create the image frame for mtplot 249f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.image_frame = ImageFrame(size=image_size) 250f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 251f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Handle layout below 252f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.box0 = gtk.VBox(False, 0) 253f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.box1 = gtk.HBox(False, 0) 254f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Arrange the layout about box0 255f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.win.add(self.box0) 256f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.box0.pack_start(self.prompt_frame.frame, True, True, 0) 257f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.box0.pack_start(self.box1, True, True, 0) 258f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Arrange the layout about box1 259f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.box1.pack_start(self.image_frame.frame, True, True, 0) 260f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.box1.pack_start(self.result_frame.frame, True, True, 0) 261f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 262f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Capture keyboard events. 263f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.win.add_events(gtk.gdk.KEY_PRESS_MASK | gtk.gdk.KEY_RELEASE_MASK) 264f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 265f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Set a handler for delete_event that immediately exits GTK. 266f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.win.connect("delete_event", self.delete_event) 267f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 268f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang # Show all widgets. 269f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.win.show_all() 270f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 2718abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang def _setup_gtk_environment(self): 2728abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang """Set up the gtk environment correctly.""" 2738abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang 2748abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang def _warning(msg=None): 2758abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang print 'Warning: fail to setup gtk environment.' 2768abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang if msg: 2778abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang print '\t' + msg 2788abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang print '\tImage files would not be shown properly.' 2798abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang print '\tIt does not affect the test results though.' 2808abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang 2818abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang def _make_symlink(path, symlink): 2828abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang """Remove the symlink if exists. Create a new symlink to point to 2838abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang the given path. 2848abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang """ 2858abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang if os.path.islink(symlink): 2868abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang os.remove(symlink) 2878abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang os.symlink(real_gtk_dir, self.gtk_symlink) 2888abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang self.new_symlink = True 2898abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang 2908abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang self.gtk_symlink = None 2918abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang self.tmp = tempfile.mkdtemp() 2928abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang self.moved_flag = False 2938abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang self.original_gtk_realpath = None 2948abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang self.new_symlink = False 2958abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang 2968abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Get LoaderDir: 2978abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # The output of gdk-pixbuf-query-loaders looks like: 2988abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # 2998abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # GdkPixbuf Image Loader Modules file 3008abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Automatically generated file, do not edit 3018abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Created by gdk-pixbuf-query-loaders from gtk+-2.20.1 3028abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # 3038abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # LoaderDir = /usr/lib64/gtk-2.0/2.10.0/loaders 3048abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang loader_dir_str = common_util.simple_system_output( 3058abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang 'gdk-pixbuf-query-loaders | grep LoaderDir') 3068abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang result = re.search('(/.*?)/(gtk-.*?)/', loader_dir_str) 3078abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang if result: 3088abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang prefix = result.group(1) 3098abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang self.gtk_version = result.group(2) 3108abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang else: 3118abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang _warning('Cannot derive gtk version from LoaderDir.') 3128abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang return 3138abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang 3148abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Verify the existence of the loaders file. 3158abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang gdk_pixbuf_loaders = ('/usr/local/etc/%s/gdk-pixbuf.loaders' % 3168abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang self.gtk_version) 3178abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang if not os.path.isfile(gdk_pixbuf_loaders): 3188abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang msg = 'The loaders file "%s" does not exist.' % gdk_pixbuf_loaders 3198abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang _warning(msg) 3208abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang return 3218abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang 3228abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Setup the environment variable for GdkPixbuf Image Loader Modules file 3238abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # so that gtk library could find it. 3248abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang os.environ['GDK_PIXBUF_MODULE_FILE'] = gdk_pixbuf_loaders 3258abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang 3268abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # In the loaders file, it specifies the paths of various 3278abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # sharable objects (.so) which are used to load images of corresponding 3288abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # image formats. For example, for png loader, the path looks like 3298abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # 3308abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # "/usr/lib64/gtk-2.0/2.10.0/loaders/libpixbufloader-png.so" 3318abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # "png" 5 "gtk20" "The PNG image format" "LGPL" 3328abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # "image/png" "" 3338abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # "png" "" 3348abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # "\211PNG\r\n\032\n" "" 100 3358abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # 3368abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # However, the real path for the .so file is under 3378abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # "/usr/local/lib64/..." 3388abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Hence, we would like to make a temporary symlink so that 3398abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # gtk library could find the .so file correctly. 3408abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang self.gtk_symlink = os.path.join(prefix, self.gtk_version) 3418abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang prefix_list = prefix.split('/') 3428abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang prefix_list.insert(prefix_list.index('usr') + 1, 'local') 3438abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang real_gtk_dir = os.path.join('/', *(prefix_list + [self.gtk_version])) 3448abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang 3458abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Make sure that the directory of .so files does exist. 3468abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang if not os.path.isdir(real_gtk_dir): 3478abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang msg = 'The directory of gtk image loaders "%s" does not exist.' 3488abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang _warning(msg % real_gtk_dir) 3498abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang return 3508abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang 3518abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Take care of an existing symlink. 3528abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang if os.path.islink(self.gtk_symlink): 3538abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # If the symlink does not point to the correct path, 3548abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # save the real path of the symlink and re-create the symlink. 3558abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang if not os.path.samefile(self.gtk_symlink, real_gtk_dir): 3568abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang self.original_gtk_realpath = os.path.realpath(self.gtk_symlink) 3578abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang _make_symlink(real_gtk_dir, self.gtk_symlink) 3588abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang 3598abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Take care of an existing directory. 3608abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang elif os.path.isdir(self.gtk_symlink): 3618abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Move the directory only if it is not what we expect. 3628abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang if not os.path.samefile(self.gtk_symlink, real_gtk_dir): 3638abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang shutil.move(self.gtk_symlink, self.tmp) 3648abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang self.moved_flag = True 3658abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang _make_symlink(real_gtk_dir, self.gtk_symlink) 3668abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang 3678abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Take care of an existing file. 3688abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Such a file is not supposed to exist here. Move it anyway. 3698abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang elif os.path.isfile(self.gtk_symlink): 3708abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang shutil.move(self.gtk_symlink, self.tmp) 3718abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang self.moved_flag = True 3728abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang _make_symlink(real_gtk_dir, self.gtk_symlink) 3738abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang 3748abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Just create the temporary symlink since there is nothing here. 3758abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang else: 3768abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang _make_symlink(real_gtk_dir, self.gtk_symlink) 3778abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang 3788abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang def close(self): 3798abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang """Cleanup by restoring any symlink, file, or directory if necessary.""" 3808abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Remove the symlink that the test created. 3818abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang if self.new_symlink: 3828abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang os.remove(self.gtk_symlink) 3838abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang 3848abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Restore the original symlink. 3858abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang if self.original_gtk_realpath: 3868abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang os.symlink(self.original_gtk_realpath, self.gtk_symlink) 3878abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang # Restore the original file or directory. 3888abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang elif self.moved_flag: 3898abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang tmp_gtk_path = os.path.join(self.tmp, self.gtk_version) 3908abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang if (os.path.isdir(tmp_gtk_path) or os.path.isfile(tmp_gtk_path)): 3918abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang shutil.move(tmp_gtk_path, os.path.dirname(self.gtk_symlink)) 3928abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang self.moved_flag = False 3938abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang shutil.rmtree(self.tmp) 3948abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang 395f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def register_callback(self, event, callback): 396f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """Register a callback function for an event.""" 397f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.win.connect(event, callback) 398f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 399f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def register_timeout_add(self, callback, timeout): 400f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """Register a callback function for gobject.timeout_add.""" 401f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang return gobject.timeout_add(timeout, callback) 402f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 403ed82f0322e54196f116566309594b7e5f958fae4Joseph Hwang def register_io_add_watch(self, callback, fd, data=None, 404f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang condition=gobject.IO_IN): 405f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """Register a callback function for gobject.io_add_watch.""" 406ed82f0322e54196f116566309594b7e5f958fae4Joseph Hwang if data: 407ed82f0322e54196f116566309594b7e5f958fae4Joseph Hwang return gobject.io_add_watch(fd, condition, callback, data) 408ed82f0322e54196f116566309594b7e5f958fae4Joseph Hwang else: 409ed82f0322e54196f116566309594b7e5f958fae4Joseph Hwang return gobject.io_add_watch(fd, condition, callback) 410f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 4115a61f5a19dfde799a3ca407e761f400184ae5fddJoseph Hwang def create_key_press_event(self, keyval): 4125a61f5a19dfde799a3ca407e761f400184ae5fddJoseph Hwang """Create a key_press_event.""" 4135a61f5a19dfde799a3ca407e761f400184ae5fddJoseph Hwang event = gtk.gdk.Event(gtk.gdk.KEY_PRESS) 4145a61f5a19dfde799a3ca407e761f400184ae5fddJoseph Hwang # Assign current time to the event 4155a61f5a19dfde799a3ca407e761f400184ae5fddJoseph Hwang event.time = 0 4165a61f5a19dfde799a3ca407e761f400184ae5fddJoseph Hwang event.keyval = keyval 4175a61f5a19dfde799a3ca407e761f400184ae5fddJoseph Hwang self.win.emit('key_press_event', event) 4185a61f5a19dfde799a3ca407e761f400184ae5fddJoseph Hwang 419f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def remove_event_source(self, tag): 420f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """Remove the registered callback.""" 421f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang gobject.source_remove(tag) 422f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 423f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def delete_event(self, widget, event, data=None): 424f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """A handler to exit the window.""" 425f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.stop() 426f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang return False 427f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 428f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def set_gesture_name(self, string, color='blue'): 429f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """A helper method to set gesture name.""" 430f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.prompt_frame.set_gesture_name(string, color) 431f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 432f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def set_prompt(self, string, color='black'): 433f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """A helper method to set the prompt.""" 434f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.prompt_frame.set_prompt(string, color) 435f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 436f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def set_choice(self, string): 437f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """A helper method to set the choice.""" 438f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.prompt_frame.set_choice(string) 439f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 440f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def set_result(self, text): 441f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """A helper method to set the text in the result.""" 442f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.result_frame.set_result(text) 443f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 444f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def set_image(self, filename): 445f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """Set an image in the image frame.""" 446f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang self.image_frame.set_from_file(filename) 447f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 4485a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang def scroll(self, choice): 4495a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang """Scroll the result frame using the choice key.""" 4505a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang self.result_frame.scroll(choice) 4515a90d71e179bcc3b1fac4897806db4a58a450ba4Joseph Hwang 4521fd993155b6d1c6996daafd5789101d3342c7bc9Joseph Hwang def stop(self): 453f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """Quit the window.""" 4548abd550453a67f7abb6eb2042ed4298dd10ec5b0Joseph Hwang self.close() 455f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang gtk.main_quit() 456f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang 457f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang def main(self): 458f20171fad5962655690812bfed2b76ec9001ae55Joseph Hwang """Main function of the window.""" 459f669f3062ea1192553f2305432c568ad1eb64217Joseph Hwang try: 460f669f3062ea1192553f2305432c568ad1eb64217Joseph Hwang gtk.main() 461f669f3062ea1192553f2305432c568ad1eb64217Joseph Hwang except KeyboardInterrupt: 462f669f3062ea1192553f2305432c568ad1eb64217Joseph Hwang self.close() 463