diff options
author | Walter Bender <walter@sugarlabs.org> | 2010-05-29 17:24:25 (GMT) |
---|---|---|
committer | Walter Bender <walter@sugarlabs.org> | 2010-05-29 17:24:25 (GMT) |
commit | d1f977f78f9e162a4552c5fea64c4441ac8d47f2 (patch) | |
tree | ce4440edcc906df368e6f7a76b7d6a369cfe2ce3 | |
parent | 5a1e185108e3f103d837724d2578f2378e80fccd (diff) |
added binary abacus
-rw-r--r-- | AbacusActivity.py | 66 | ||||
-rw-r--r-- | NEWS | 6 | ||||
-rwxr-xr-x | abacus.py | 30 | ||||
-rw-r--r-- | abacus_window.py | 132 | ||||
-rw-r--r-- | icons/Boff.svg | 54 | ||||
-rw-r--r-- | icons/Bon.svg | 54 |
6 files changed, 252 insertions, 90 deletions
diff --git a/AbacusActivity.py b/AbacusActivity.py index e2a5921..78efdd7 100644 --- a/AbacusActivity.py +++ b/AbacusActivity.py @@ -91,6 +91,14 @@ class AbacusActivity(activity.Activity): toolbar_box.toolbar.insert(self.mayan, -1) self.mayan.show() + # Binary (base 2) + self.binary = ToolButton( "Boff" ) + self.binary.set_tooltip(_('binary')) + self.binary.props.sensitive = True + self.binary.connect('clicked', self._binary_cb) + toolbar_box.toolbar.insert(self.binary, -1) + self.binary.show() + separator = gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) @@ -136,8 +144,12 @@ class AbacusActivity(activity.Activity): self._japanese_cb(None) elif self.metadata['abacus'] == 'schety': self._russian_cb(None) - else: + elif self.metadata['abacus'] == 'nepohualtzintzin': self._mayan_cb(None) + elif self.metadata['abacus'] == 'binary': + self._binary_cb(None) + else: + self._chinese_cb(None) except: pass try: @@ -146,58 +158,58 @@ class AbacusActivity(activity.Activity): except: pass - def _chinese_cb(self, button): - """ Display the suanpan; hide the others """ - self.chinese.set_icon("Con") + def _all_off(self): + self.chinese.set_icon("Coff") self.japanese.set_icon("Joff") self.russian.set_icon("Roff") self.mayan.set_icon("Moff") - self.abacus.chinese.show() + self.binary.set_icon("Boff") + self.abacus.chinese.hide() self.abacus.japanese.hide() self.abacus.russian.hide() self.abacus.mayan.hide() + self.abacus.binary.hide() + + def _chinese_cb(self, button): + """ Display the suanpan; hide the others """ + self._all_off() + self.chinese.set_icon("Con") + self.abacus.chinese.show() self.abacus.mode = self.abacus.chinese _logger.debug("Setting mode to %s" % (self.abacus.mode.name)) def _japanese_cb(self, button): """ Display the soroban; hide the others """ - self.chinese.set_icon("Coff") + self._all_off() self.japanese.set_icon("Jon") - self.russian.set_icon("Roff") - self.mayan.set_icon("Moff") - self.abacus.chinese.hide() self.abacus.japanese.show() - self.abacus.russian.hide() - self.abacus.mayan.hide() self.abacus.mode = self.abacus.japanese _logger.debug("Setting mode to %s" % (self.abacus.mode.name)) def _russian_cb(self, button): """ Display the schety; hide the others """ - self.chinese.set_icon("Coff") - self.japanese.set_icon("Joff") + self._all_off() self.russian.set_icon("Ron") - self.mayan.set_icon("Moff") - self.abacus.chinese.hide() - self.abacus.japanese.hide() self.abacus.russian.show() - self.abacus.mayan.hide() self.abacus.mode = self.abacus.russian _logger.debug("Setting mode to %s" % (self.abacus.mode.name)) def _mayan_cb(self, button): """ Display the nepohualtzintzin; hide the others """ - self.chinese.set_icon("Coff") - self.japanese.set_icon("Joff") - self.russian.set_icon("Roff") + self._all_off() self.mayan.set_icon("Mon") - self.abacus.chinese.hide() - self.abacus.japanese.hide() - self.abacus.russian.hide() self.abacus.mayan.show() self.abacus.mode = self.abacus.mayan _logger.debug("Setting mode to %s" % (self.abacus.mode.name)) + def _binary_cb(self, button): + """ Display the binary; hide the others """ + self._all_off() + self.binary.set_icon("Bon") + self.abacus.binary.show() + self.abacus.mode = self.abacus.binary + _logger.debug("Setting mode to %s" % (self.abacus.mode.name)) + def write_file(self, file_path): """ Write the bead positions to the Journal """ _logger.debug("Saving current abacus to Journal: %s " % ( @@ -249,3 +261,11 @@ class ProjectToolbar(gtk.Toolbar): self.activity.mayan.connect('clicked', self.activity._mayan_cb) self.insert(self.activity.mayan, -1) self.activity.mayan.show() + + # Binary style + self.activity.binary = ToolButton( "Boff" ) + self.activity.binary.set_tooltip(_('binary')) + self.activity.binary.props.sensitive = True + self.activity.binary.connect('clicked', self.activity._binary_cb) + self.insert(self.activity.binary, -1) + self.activity.binary.show() @@ -1,3 +1,9 @@ +6 + +* added binary abacus +* autogenerate SVG +* general code clean-up/consolidation + 5 * highlight recently moved beads @@ -71,6 +71,9 @@ class AbacusMain: menu_items = gtk.MenuItem(_("Nepohualtzintzin")) menu.append(menu_items) menu_items.connect("activate", self._m_cb) + menu_items = gtk.MenuItem(_("Binary")) + menu.append(menu_items) + menu_items.connect("activate", self._b_cb) menu_items.show() menu_items = gtk.MenuItem(_("Quit")) menu.append(menu_items) @@ -131,38 +134,43 @@ class AbacusMain: def set_title(self, title): self.win.set_title(title) - def _c_cb(self, widget): - self.abacus.chinese.show() + def _hide_all(self): + self.abacus.chinese.hide() self.abacus.japanese.hide() self.abacus.russian.hide() self.abacus.mayan.hide() + self.abacus.binary.hide() + + def _c_cb(self, widget): + self._hide_all() + self.abacus.chinese.show() self.abacus.mode = self.abacus.chinese return True def _j_cb(self, widget): - self.abacus.chinese.hide() + self._hide_all() self.abacus.japanese.show() - self.abacus.russian.hide() - self.abacus.mayan.hide() self.abacus.mode = self.abacus.japanese return True def _r_cb(self, widget): - self.abacus.chinese.hide() - self.abacus.japanese.hide() + self._hide_all() self.abacus.russian.show() - self.abacus.mayan.hide() self.abacus.mode = self.abacus.russian return True def _m_cb(self, widget): - self.abacus.chinese.hide() - self.abacus.japanese.hide() - self.abacus.russian.hide() + self._hide_all() self.abacus.mayan.show() self.abacus.mode = self.abacus.mayan return True + def _b_cb(self, widget): + self._hide_all() + self.abacus.binary.show() + self.abacus.mode = self.abacus.binary + return True + def destroy(self, event, data=None): """ Callback for destroy event. """ gtk.main_quit() diff --git a/abacus_window.py b/abacus_window.py index 6c97577..cee4a20 100644 --- a/abacus_window.py +++ b/abacus_window.py @@ -14,7 +14,7 @@ BWIDTH = 40 BHEIGHT = 30 BOFFSET = 10 -FSTROKE = 60 +FSTROKE = 45 import pygtk pygtk.require('2.0') @@ -87,7 +87,6 @@ def _svg_header(w, h, scale): svg_string += "%s%f%s%f%s" % ("<g\n transform=\"matrix(", scale, ",0,0,", scale, ",0,0)\">\n") - # svg_string += _svg_background() return svg_string def _svg_footer(): @@ -100,10 +99,6 @@ def _svg_style(extras=""): """ Returns SVG style for shape rendering """ return "%s%s%s" % ("style=\"", extras, "\"/>\n") -def load_image(path, name, w, h): - """ create a pixbuf from a SVG stored in a file """ - return gtk.gdk.pixbuf_new_from_file_at_size( - os.path.join(path+name+'.svg'), int(w), int(h)) class Abacus(): @@ -140,11 +135,13 @@ class Abacus(): self.russian = Schety(self) # self.russian = Fractions(self) self.mayan = Nepohualtzintzin(self) + self.binary = Binary(self) self.chinese.show() self.japanese.hide() self.russian.hide() self.mayan.hide() + self.binary.hide() self.mode = self.chinese def _button_press_cb(self, win, event): @@ -201,7 +198,6 @@ class AbacusGeneric(): self.num_rods = 15 self.bot_beads = 2 self.top_beads = 5 - self.base = 10 self.create() def create(self): @@ -309,10 +305,16 @@ class AbacusGeneric(): y+b*BHEIGHT*self.abacus.scale, self.colors[0])) for b in range(self.bot_beads): - self.beads.append(Sprite(self.abacus.sprites, x+i*dx+bo, - y+(self.top_beads+5+b)*BHEIGHT\ - *self.abacus.scale, - self.colors[0])) + if self.top_beads > 0: + self.beads.append(Sprite(self.abacus.sprites, x+i*dx+bo, + y+(self.top_beads+5+b)*BHEIGHT\ + *self.abacus.scale, + self.colors[0])) + else: + self.beads.append(Sprite(self.abacus.sprites, x+i*dx+bo, + y+(2+b)*BHEIGHT\ + *self.abacus.scale, + self.colors[0])) for i in self.beads: i.type = 'bead' @@ -508,7 +510,6 @@ class Nepohualtzintzin(AbacusGeneric): self.num_rods = 13 self.bot_beads = 4 self.top_beads = 3 - self.base = 20 self.create() def value(self, count_beads=False): @@ -561,7 +562,6 @@ class Suanpan(AbacusGeneric): self.num_rods = 15 self.bot_beads = 5 self.top_beads = 2 - self.base = 10 self.create() @@ -574,10 +574,50 @@ class Soroban(AbacusGeneric): self.num_rods = 15 self.bot_beads = 4 self.top_beads = 1 - self.base = 10 self.create() +class Binary(AbacusGeneric): + + def __init__(self, abacus): + """ create a Binary abacus: 15 by (1,0) """ + self.abacus = abacus + self.name = 'binary' + self.num_rods = 15 + self.bot_beads = 1 + self.top_beads = 0 + self.create() + + def value(self, count_beads=False): + """ Override for base 2 """ + string = '' + value = 0 + v = [] + for r in range(self.num_rods+1): # +1 for overflow + v.append(0) + + # Tally the values on each rod. + for i, b in enumerate(self.beads): + r = i/(self.top_beads+self.bot_beads) + j = i % (self.top_beads+self.bot_beads) + if b.state == 1: + if j < self.top_beads: + v[r+1] += 5 + else: + v[r+1] += 1 + + if count_beads: + # Save the value associated with each rod as a 2-byte integer. + for j in v[1:]: + string += "%2d" % (j) + else: + for j in range(self.num_rods): + if v[len(v)-j-1] == 1: + value += pow(2,j) + string = str(int(value)) + + return(string) + class Schety(AbacusGeneric): def __init__(self, abacus): @@ -587,7 +627,6 @@ class Schety(AbacusGeneric): self.num_rods = 15 self.top_beads = 0 self.bot_beads = 10 - self.base = 10 self.create() def draw_rods_and_beads(self, x, y): @@ -605,7 +644,6 @@ class Schety(AbacusGeneric): self.white = _svg_str_to_pixbuf(white) self.black = _svg_str_to_pixbuf(black) - # 10 beads + 2 spaces dx = (BWIDTH+BOFFSET)*self.abacus.scale self.beads = [] @@ -621,6 +659,7 @@ class Schety(AbacusGeneric): self.rods.append(Sprite(self.abacus.sprites, x+i*dx+ro, y, _svg_str_to_pixbuf(rod))) + if i == 10: for b in range(4): if b in [1,2]: @@ -780,40 +819,38 @@ class Fractions(AbacusGeneric): self.name = "schety" self.num_rods = 15 self.top_beads = 0 - self.bot_beads = 10 - self.frame_width = 810 - self.frame_height = 420 - self.base = 10 + self.bot_beads = 12 self.create() - def create(self): - """ Override default in order to make fraction rods. """ - # 10 beads + 2 spaces - rod_h = (self.bot_beads+2)*BHEIGHT*self.abacus.scale - dx = (BWIDTH+BOFFSET)*self.abacus.scale - w = (self.num_rods+1)*(BWIDTH+BOFFSET)*self.abacus.scale - x = (self.abacus.width-w)/2 - y = (self.abacus.height-rod_h)/2 - - # Draw the frame. - self.frame = Sprite(self.abacus.sprites, x-BHEIGHT*self.abacus.scale, - y-BHEIGHT*self.abacus.scale, - load_image(self.abacus.path, self.name+"_frame", - self.frame_width*self.abacus.scale, - self.frame_height*self.abacus.scale)) - self.frame.type = 'frame' + def draw_rods_and_beads(self, x, y): + """ Override default in order to make a short rod """ + rod_colors = ["#006ffe", "#007ee7", "#0082c4", "#0089ab", "#008c8b", + "#008e68", "#008e4c", "#008900", "#5e7700", "#787000", + "#876a00", "#986200", "#ab5600", "#d60000", "#e30038"] - # and then the beads. white = _svg_header(BWIDTH, BHEIGHT, self.abacus.scale) +\ _svg_bead("#ffffff", "#000000") +\ _svg_footer() self.white = _svg_str_to_pixbuf(white) + + dx = (BWIDTH+BOFFSET)*self.abacus.scale + self.beads = [] self.rods = [] - o = (BWIDTH-BOFFSET)/2*self.abacus.scale/2 + bo = (BWIDTH-BOFFSET)*self.abacus.scale/4 + ro = (BWIDTH+5)*self.abacus.scale/2 for i in range(self.num_rods): + rod = _svg_header(10, self.frame_height-(FSTROKE*2), + self.abacus.scale) +\ + _svg_rect(10, self.frame_height-(FSTROKE*2), 0, 0, 0, 0, + rod_colors[(i+5)%len(rod_colors)], "#404040") +\ + _svg_footer() + self.rods.append(Sprite(self.abacus.sprites, x+i*dx+ro, + y, + _svg_str_to_pixbuf(rod))) + for b in range(self.bead_count[i]): - self.beads.append(Sprite(self.abacus.sprites, x+i*dx+o, + self.beads.append(Sprite(self.abacus.sprites, x+i*dx+bo, y+(12-self.bead_count[i]+b)*BHEIGHT*\ self.abacus.scale, self.white)) @@ -822,23 +859,6 @@ class Fractions(AbacusGeneric): i.type = 'bead' i.state = 0 - # Draw a bar for the label on top. - self.bar = Sprite(self.abacus.sprites, x, y-BHEIGHT*self.abacus.scale, - load_image(self.abacus.path, self.name+"_bar", - w, BHEIGHT*self.abacus.scale)) - - self.bar.type = 'frame' - self.bar.set_label_color('white') - - # and the mark. - o = (BWIDTH+BOFFSET-15)*self.abacus.scale/2 - self.mark = Sprite(self.abacus.sprites, x+(self.num_rods-1)*dx+o, - y-(BHEIGHT-15)*self.abacus.scale, - load_image(self.abacus.path, "indicator", - 20*self.abacus.scale, - 15*self.abacus.scale)) - self.mark.type = 'mark' - def value(self, count_beads=False): """ Override to account for fourths """ string = '' diff --git a/icons/Boff.svg b/icons/Boff.svg new file mode 100644 index 0000000..4f919c5 --- /dev/null +++ b/icons/Boff.svg @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.1" + width="45" + height="45" + id="svg2"> + <defs + id="defs41" /> + <rect + width="10.439099" + height="43" + x="-41.738712" + y="1" + transform="matrix(0,-1,1,0,0,0)" + id="rect4" + style="fill:#aaaaaa;fill-opacity:1;stroke:#000000;stroke-width:2" /> + <line + y1="39.500004" + y2="30.433235" + x1="22.5" + x2="22.5" + style="fill:#aaaaaa;stroke:#000000;stroke-width:2;stroke-miterlimit:0;stroke-dasharray:none" + id="line10-68" /> + <path + d="m 26.5,39.195828 a 4,1.8542272 0 1 1 -7.999999,0 4,1.8542272 0 1 1 7.999999,0 z" + id="path3633-3-49" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + <line + y1="39.500004" + y2="30.433235" + x1="9.724575" + x2="9.724575" + style="fill:#aaaaaa;stroke:#000000;stroke-width:2;stroke-miterlimit:0;stroke-dasharray:none" + id="line10-68-3" /> + <path + d="m 13.724576,39.195828 a 4,1.8542272 0 1 1 -7.9999992,0 4,1.8542272 0 1 1 7.9999992,0 z" + id="path3633-3-49-7" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + <line + y1="39.500004" + y2="30.433235" + x1="35.084743" + x2="35.084743" + style="fill:#aaaaaa;stroke:#000000;stroke-width:2;stroke-miterlimit:0;stroke-dasharray:none" + id="line10-68-3-8" /> + <path + d="m 39.084746,39.195828 a 4,1.8542272 0 1 1 -7.999999,0 4,1.8542272 0 1 1 7.999999,0 z" + id="path3633-3-49-7-9" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /> +</svg> diff --git a/icons/Bon.svg b/icons/Bon.svg new file mode 100644 index 0000000..0ddd963 --- /dev/null +++ b/icons/Bon.svg @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.1" + width="45" + height="45" + id="svg2"> + <defs + id="defs41" /> + <rect + width="10.439099" + height="43" + x="-41.738712" + y="1" + transform="matrix(0,-1,1,0,0,0)" + id="rect4" + style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2" /> + <line + y1="39.500004" + y2="30.433235" + x1="22.5" + x2="22.5" + style="fill:#aaaaaa;stroke:#000000;stroke-width:2;stroke-miterlimit:0;stroke-dasharray:none" + id="line10-68" /> + <path + d="m 26.5,39.195828 a 4,1.8542272 0 1 1 -7.999999,0 4,1.8542272 0 1 1 7.999999,0 z" + id="path3633-3-49" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + <line + y1="39.500004" + y2="30.433235" + x1="9.724575" + x2="9.724575" + style="fill:#aaaaaa;stroke:#000000;stroke-width:2;stroke-miterlimit:0;stroke-dasharray:none" + id="line10-68-3" /> + <path + d="m 13.724576,39.195828 a 4,1.8542272 0 1 1 -7.9999992,0 4,1.8542272 0 1 1 7.9999992,0 z" + id="path3633-3-49-7" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + <line + y1="39.500004" + y2="30.433235" + x1="35.084743" + x2="35.084743" + style="fill:#aaaaaa;stroke:#000000;stroke-width:2;stroke-miterlimit:0;stroke-dasharray:none" + id="line10-68-3-8" /> + <path + d="m 39.084746,39.195828 a 4,1.8542272 0 1 1 -7.999999,0 4,1.8542272 0 1 1 7.999999,0 z" + id="path3633-3-49-7-9" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /> +</svg> |