Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWalter Bender <walter@sugarlabs.org>2010-05-29 17:24:25 (GMT)
committer Walter Bender <walter@sugarlabs.org>2010-05-29 17:24:25 (GMT)
commitd1f977f78f9e162a4552c5fea64c4441ac8d47f2 (patch)
treece4440edcc906df368e6f7a76b7d6a369cfe2ce3
parent5a1e185108e3f103d837724d2578f2378e80fccd (diff)
added binary abacus
-rw-r--r--AbacusActivity.py66
-rw-r--r--NEWS6
-rwxr-xr-xabacus.py30
-rw-r--r--abacus_window.py132
-rw-r--r--icons/Boff.svg54
-rw-r--r--icons/Bon.svg54
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()
diff --git a/NEWS b/NEWS
index a2eb040..ac8a3d4 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+6
+
+* added binary abacus
+* autogenerate SVG
+* general code clean-up/consolidation
+
5
* highlight recently moved beads
diff --git a/abacus.py b/abacus.py
index 82ae3ee..7c59d15 100755
--- a/abacus.py
+++ b/abacus.py
@@ -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>