I had blogged earlier about a program for a one year old.
Since then, my child has started identifying alphabets and has great fun hammering keys on his keyboard to produce letters. He has also started identifying numbers and lower case alphabets. Finally, he has strong preference on the color of the alphabets and the background.
So I present an update for my program, now for two year olds!
The basic structure is the same: it is a full screen GTK program that shows a number or alphabets. A number is shown in the middle of the screen. Alphabets are shown in both upper case and lower case. Finally, stars (an asterisk) is a recent favourite, so I allow typing that one special character. A brown bar at the bottom fills up as sleep-time approaches. This was useful in making the child aware of time: as the bar filled up, night time was approaching.
The full program is presented below.
Since then, my child has started identifying alphabets and has great fun hammering keys on his keyboard to produce letters. He has also started identifying numbers and lower case alphabets. Finally, he has strong preference on the color of the alphabets and the background.
So I present an update for my program, now for two year olds!
The basic structure is the same: it is a full screen GTK program that shows a number or alphabets. A number is shown in the middle of the screen. Alphabets are shown in both upper case and lower case. Finally, stars (an asterisk) is a recent favourite, so I allow typing that one special character. A brown bar at the bottom fills up as sleep-time approaches. This was useful in making the child aware of time: as the bar filled up, night time was approaching.
The full program is presented below.
#!/usr/bin/python import datetime, gtk, string, pango class BigChar(): """ Create a Gtk window for a single giant textview that accepts all keyboard input. """ def on_key_press(self, widget, data=None): """ Intercept all keypress events and show ascii characters. This requires the CAPS_LOCK to be off. We don't intercept CAPS NUM or SCROLL lock, probably should.""" # Start out by setting the current time self.set_time() ascii_value = data.keyval # Print the keycode received print ascii_value changedText = False # Lowercase alphabet should be shown as uppercase chars. if (ascii_value >= 97 and ascii_value <= 122): self.textBuffer.set_text(string.ascii_uppercase[ascii_value-97] + " " + string.ascii_lowercase[ascii_value-97]) changedText = True # Uppercase alphabet should be shown as uppercase chars. if (ascii_value >= 65 and ascii_value <= 90): self.textBuffer.set_text(string.ascii_uppercase[ascii_value-65] + " " + string.ascii_lowercase[ascii_value-65]) changedText = True # Numbers if (ascii_value >= 48 and ascii_value <= 57): self.textBuffer.set_text("%d" % (ascii_value - 48)) changedText = True if (ascii_value >= 65456 and ascii_value <= 65466): self.textBuffer.set_text("%d" % (ascii_value - 65456)) changedText = True if (ascii_value == 65450): self.textBuffer.set_text("*") changedText = True if (changedText): start = self.textBuffer.get_start_iter() end = self.textBuffer.get_end_iter() self.textBuffer.apply_tag_by_name("real_big", start, end) def realize_handler(self, widget): pixmap = gtk.gdk.Pixmap(None, 1, 1, 1) color = gtk.gdk.Color() cursor = gtk.gdk.Cursor(pixmap, pixmap, color, color, 0, 0) widget.window.set_cursor(cursor) def set_time(self): """Set the progress indicator to the current time. The idea is to show time in a horizontal access with the morning being near the left edge and night being near the right edge.""" current_time = datetime.datetime.now() # Total hours past since 6am # (Assume Dev wakes up at 6am) minutes_past = (current_time.hour - 6) * 60.0 + current_time.minute # Minutes are capped at 8am, which is when Dev goes to # bed. Expressed as minutes after 6am day_end = ((20 - 6) * 60.0) if (minutes_past < day_end): fraction = minutes_past / day_end else: fraction = 1.0 self.progress.set_fraction(fraction) def __init__(self): """ Create a window with a single giant text view. Disables all chrome. """ # Foreground and background color are read from here. background_color = "black" foreground_color = "#1133ff" self.w = gtk.Window(gtk.WINDOW_TOPLEVEL) # No border self.w.set_border_width(0) # Take over the entire screen self.w.fullscreen() # Connect the callback on_key_press to the signal key_press. self.w.connect("key_press_event", self.on_key_press) # self.w.connect("realize", self.realize_handler) # Make the widget aware of the signal to catch. self.w.set_events(gtk.gdk.KEY_PRESS_MASK) # Add a text view to show the key pressed textView = gtk.TextView() # Disable a cursor in the text view. textView.set_editable(False) textView.set_can_focus(False) # Show the single character in the middle textView.set_justification(gtk.JUSTIFY_CENTER) # This is the place we will write the character to self.textBuffer = textView.get_buffer() # Make the text view huge and bold fontdesc = pango.FontDescription("monospace bold 400") textView.modify_font(fontdesc) # Creates a tag that is applied to the text every time tag = self.textBuffer.create_tag( "real_big", background=background_color, foreground=foreground_color) # The progress bar shows the current proportion of awake-time for a child. self.progress = gtk.ProgressBar() self.set_time() # Make the text view take the entire window vbox = gtk.VBox(homogeneous=False, spacing=0) color = gtk.gdk.color_parse(background_color) self.progress.modify_bg(gtk.STATE_NORMAL, color) self.progress.modify_fg(gtk.STATE_NORMAL, color) textView.modify_base(gtk.STATE_NORMAL, color) vbox.pack_start(textView, expand=True, fill=False) vbox.pack_start(self.progress, expand=True, fill=True) self.w.modify_bg(gtk.STATE_NORMAL, color) self.w.add(vbox) def show(self): """ Show the window""" self.w.show_all() # gdkWindow = self.textView.get_window(gtk.TEXT_WINDOW_WIDGET) # display = self.textView.get_display() # cursor = gtk.gdk.Cursor(display, gtk.gdk.BLANK_CURSOR) # gdkWindow.set_cursor(cursor) if __name__ == '__main__': # Create a bigchar window, and show it. bigchar = BigChar() bigchar.show() gtk.main()