diff options
author | Walter Bender <walter@sugarlabs.org> | 2010-09-29 10:03:33 (GMT) |
---|---|---|
committer | Walter Bender <walter@sugarlabs.org> | 2010-09-29 10:03:33 (GMT) |
commit | c76e411c2c50224288f2cbe783c30e8ae0821cbd (patch) | |
tree | 1f9579fd2cedd8fdef45457ce8f1e2fab3835624 /abacus_window.py | |
parent | a58036585661cfd3048796d35b44615a684e0553 (diff) |
added set value from number typed on results display
Diffstat (limited to 'abacus_window.py')
-rw-r--r-- | abacus_window.py | 129 |
1 files changed, 113 insertions, 16 deletions
diff --git a/abacus_window.py b/abacus_window.py index d28adc5..924eb83 100644 --- a/abacus_window.py +++ b/abacus_window.py @@ -22,6 +22,7 @@ BEAD_LAYER = 102 BAR_LAYER = 103 MARK_LAYER = 104 MAX_FADE_LEVEL = 3 +CURSOR = '█' ROD_COLORS = ["#006ffe", "#007ee7", "#0082c4", "#0089ab", "#008c8b", "#008e68", "#008e4c", "#008900", "#5e7700", "#787000", @@ -31,6 +32,9 @@ import pygtk pygtk.require('2.0') import gtk from math import pow, floor, ceil + +import os +import locale from gettext import gettext as _ import logging @@ -279,12 +283,21 @@ class Abacus(): self.canvas.connect("button-press-event", self._button_press_cb) self.canvas.connect("button-release-event", self._button_release_cb) self.canvas.connect("motion-notify-event", self._mouse_move_cb) + self.canvas.connect("key_press_event", self._keypress_cb) self.width = gtk.gdk.screen_width() self.height = gtk.gdk.screen_height()-GRID_CELL_SIZE self.sprites = Sprites(self.canvas) self.scale = gtk.gdk.screen_height()/900.0 self.dragpos = 0 self.press = None + self.last = None + + lang = os.environ['LANG'] + if lang != '' and lang is not None: + locale.setlocale(locale.LC_NUMERIC, lang) + self.decimal_point = locale.localeconv()['decimal_point'] + if self.decimal_point == '' or self.decimal_point is None: + self.decimal_point = '.' self.chinese = Suanpan(self) self.japanese = None @@ -306,6 +319,7 @@ class Abacus(): win.grab_focus() x, y = map(int, event.get_coords()) self.press = self.sprites.find_sprite((x,y)) + self.last = self.press if self.press is not None: if self.press.type == 'bead': self.dragpos = y @@ -313,6 +327,9 @@ class Abacus(): self.dragpos = x elif self.press.type == 'reset': self.mode.reset_abacus() + elif self.press == self.mode.bar: # prepare for typing in a value + self.mode.label(self.generate_label(sum_only=True)+CURSOR) + self.press = None else: self.press = None return True @@ -339,9 +356,68 @@ class Abacus(): if self.press.type == 'bead': self.mode.move_bead(self.press, y-self.dragpos) self.press = None - self.mode.label(self.generate_label()) + self.mode.label(self.generate_label()) + return True + + def _keypress_cb(self, area, event): + """ Keypress: moving the slides with the arrow keys """ + k = gtk.gdk.keyval_name(event.keyval) + if k in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'period', + 'minus', 'Return', 'BackSpace', 'comma']: + if self.last == self.mode.bar: + self._process_numeric_input(self.last, k) + else: + print self.last, '!= bar', k + elif k == 'r': + self.mode.reset_abacus() return True + def _process_numeric_input(self, sprite, keyname): + ''' Make sure numeric input is valid. ''' + oldnum = sprite.labels[0].replace(CURSOR, '') + newnum = oldnum + if len(oldnum) == 0: + oldnum = '0' + if keyname == 'minus': + if oldnum == '0': + newnum = '-' + elif oldnum[0] != '-': + newnum = '-' + oldnum + else: + newnum = oldnum + elif keyname == 'comma' and self.decimal_point == ',' and \ + ',' not in oldnum: + newnum = oldnum + ',' + elif keyname == 'period' and self.decimal_point == '.' and \ + '.' not in oldnum: + newnum = oldnum + '.' + elif keyname == 'BackSpace': + if len(oldnum) > 0: + newnum = oldnum[:len(oldnum)-1] + else: + newnum = '' + elif keyname in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']: + if oldnum == '0': + newnum = keyname + else: + newnum = oldnum + keyname + elif keyname == 'Return': + self.mode.reset_abacus() + self.mode.set_value_from_number( + float(newnum.replace(self.decimal_point, '.'))) + self.mode.label(self.generate_label()) + return + else: + newnum = oldnum + if newnum == '.': + newnum = '0.' + if len(newnum) > 0 and newnum != '-': + try: + float(newnum.replace(self.decimal_point, '.')) + except ValueError, e: + newnum = oldnum + sprite.set_label(newnum + CURSOR) + def _expose_cb(self, win, event): """ Callback to handle window expose events """ self.sprites.redraw_sprites(event.area) @@ -351,7 +427,7 @@ class Abacus(): """ Callback to handle quit """ gtk.main_quit() - def generate_label(self): + def generate_label(self, sum_only=False): """ The complexity below is to make the label as simple as possible """ sum = "" multiple_rods = False @@ -392,7 +468,7 @@ class Abacus(): value = "–%d %s" % (-whole, dec2frac(-fraction)) if value == "" or value == "–": value = "0" - if multiple_rods: + if multiple_rods and not sum_only: return sum + " = " + value else: return value @@ -584,7 +660,7 @@ class AbacusGeneric(): if len(string) == 2*self.num_rods: for i in range(self.num_rods): v[self.num_rods-i-1] = int( - string[2*self.num_rods-i*2-2:2*self.num_rods-i*2]) + string[2*self.num_rods-i*2-2:2*self.num_rods-i*2]) else: _logger.debug("bad saved string %s (%d != 2*%d)" % (string, len(string), self.num_rods)) @@ -594,13 +670,32 @@ class AbacusGeneric(): self.set_rod_value(r, v[r]) return + def set_value_from_number(self, number): + """ Set abacus to value in string """ + for r in range(self.num_rods): + number -= self.set_rod(r, number) + if number == 0: + break + + def set_rod(self, rod, number): + bead = rod * (self.top_beads + self.bot_beads) + bead_value = self.beads[bead + self.top_beads].value + if bead_value != 0: + count = int(number / bead_value) + print rod, bead_value, count + self.set_rod_value(rod, count) + return count * bead_value + def set_rod_value(self, r, v): """ Move beads on rod r to represent value v """ - bot = v % self.top_factor - top = (v-bot)/self.top_factor - top_bead_index = r*(self.top_beads+self.bot_beads) - bot_bead_index = r*(self.top_beads+self.bot_beads)+self.top_beads - + if self.top_beads > 0: + bot = v % self.top_factor + top = (v - bot) / self.top_factor + else: + bot = v + top = 0 + top_bead_index = r * (self.top_beads + self.bot_beads) + bot_bead_index = top_bead_index + self.top_beads # Clear the top. for i in range(self.top_beads): if self.beads[top_bead_index+i].get_state() == 1: @@ -626,14 +721,16 @@ class AbacusGeneric(): # Clear the top. for i in range(self.top_beads): #if self.name != 'fraction' and self.name != 'schety': - self.beads[top_bead_index+i].set_color(self.colors[0]) + if hasattr(self, 'colors'): + self.beads[top_bead_index+i].set_color(self.colors[0]) if self.beads[top_bead_index+i].get_state() == 1: self.beads[top_bead_index+i].move_up() # Clear the bottom. for i in range(self.bot_beads): #if self.name != 'fraction' and self.name != 'schety': - self.beads[bot_bead_index+i].set_color(self.colors[0]) + if hasattr(self, 'colors'): + self.beads[bot_bead_index+i].set_color(self.colors[0]) if self.beads[bot_bead_index+i].get_state() == 1: self.beads[bot_bead_index+i].move_down() @@ -842,7 +939,7 @@ class Decimal(AbacusGeneric): self.bot_beads = 10 self.top_beads = 0 self.base = 10 - self.top_factor = 5 + self.top_factor = 1 return def draw_rods_and_beads(self, x, y): @@ -912,7 +1009,7 @@ class Schety(AbacusGeneric): self.bead_count = (10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 4, 10, 10, 10, 10) self.base = 10 - self.top_factor = 5 + self.top_factor = 1 return def reset_abacus(self): @@ -1115,7 +1212,7 @@ class Fractions(Schety): self.top_beads = 0 self.bot_beads = 12 self.base = 10 - self.top_factor = 5 + self.top_factor = 1 return def draw_rods_and_beads(self, x, y): @@ -1181,7 +1278,7 @@ class Caacupe(Fractions): self.top_beads = 0 self.bot_beads = 12 self.base = 10 - self.top_factor = 5 + self.top_factor = 1 return def draw_rods_and_beads(self, x, y): @@ -1319,7 +1416,7 @@ class Cuisenaire(Caacupe): self.top_beads = 0 self.bot_beads = 10 self.base = 10 - self.top_factor = 5 + self.top_factor = 1 return def draw_rods_and_beads(self, x, y): |