Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReinier Heeres <reinier@heeres.eu>2007-09-10 09:57:56 (GMT)
committer Reinier Heeres <reinier@heeres.eu>2007-09-10 09:57:56 (GMT)
commitadc9ebd4ac938f16f804943139768b269bf4b497 (patch)
tree4269b988337ebf0ea06a8a0e740d5ef46bb1b132
parentb0cca9f16f0a57ea07c8a27f4421311e96b41680 (diff)
Bugfixes, plot axes labels, MANIFEST update
-rw-r--r--MANIFEST6
-rw-r--r--NEWS4
-rw-r--r--calculate.py5
-rw-r--r--eqnparser.py30
-rw-r--r--layout.py1
-rw-r--r--mathlib.py12
-rw-r--r--plotlib.py22
-rw-r--r--toolbars.py2
8 files changed, 65 insertions, 17 deletions
diff --git a/MANIFEST b/MANIFEST
index aacf97c..0075a42 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,8 +1,10 @@
calculate.py
-layout.py
-toolbars.py
eqnparser.py
+layout.py
mathlib.py
+plotlib.py
+svgimage.py
+toolbars.py
sharedstate/__init__.py
sharedstate/shareddict.py
sharedstate/sharedobject.py
diff --git a/NEWS b/NEWS
index c13d191..2009d9e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+* Plot support, plot(x^3,x=-2..2)
+* Fixed toolbar focus bug
+* Improved operator parsing ('*' vs '**' and '<' vs '<<')
+
7
6
diff --git a/calculate.py b/calculate.py
index ff00a1d..24e47de 100644
--- a/calculate.py
+++ b/calculate.py
@@ -578,7 +578,8 @@ class Calculate(activity.Activity):
self.remove_character(1)
def keypress_cb(self, widget, event):
- if self.label_entry.is_focus():
+ if self.label_entry.is_focus() or \
+ self.toolbox.get_activity_toolbar().title.is_focus():
return
key = gtk.gdk.keyval_name(event.keyval)
@@ -676,7 +677,7 @@ class Calculate(activity.Activity):
self.text_entry.set_position(pos + len(str))
else:
- _logger.error('Calculate.button_pressed(): invalid type')
+ _logger.error('button_pressed(): invalid type')
def receive_message(self, msg, val):
if msg == "add_eq":
diff --git a/eqnparser.py b/eqnparser.py
index 5e9a05c..bcc3f4f 100644
--- a/eqnparser.py
+++ b/eqnparser.py
@@ -58,6 +58,14 @@ class ParserState:
self.char = None
return self.char
+ def prev(self):
+ self.ofs -= 1
+ if self.ofs < self.strlen and self.ofs >= 0:
+ self.char = self.str[self.ofs]
+ else:
+ self.char = None
+ return self.char
+
def set_ofs(self, o):
self.ofs = o
self.char = self.str[o]
@@ -163,6 +171,7 @@ class EqnParser:
self.register_operator('/', self.OP_DIADIC, 1, lambda x: self.ml.div(x[0], x[1]))
self.register_operator('^', self.OP_DIADIC, 2, lambda x: self.ml.pow(x[0], x[1]))
+ self.register_operator('**', self.OP_DIADIC, 2, lambda x: self.ml.pow(x[0], x[1]))
self.register_operator('!', self.OP_POST, 0, lambda x: self.ml.factorial(x[0]))
@@ -330,21 +339,28 @@ class EqnParser:
def parse_operator(self, ps, left_val):
startofs = ps.ofs
+ op = None
while ps.more() and ps.char in self.OP_CHARS:
ps.next()
- op = self.valid_operator(ps.str[startofs:ps.ofs], left_val)
- if op is not None:
- _logger.debug('parse_operator(): %d - %d: %s', startofs, ps.ofs, ps.str[startofs:ps.ofs])
- return op
-
- return self.INVALID_OP
+ op2 = self.valid_operator(ps.str[startofs:ps.ofs], left_val)
+ if op2 is not None:
+ op = op2
+ elif op2 is None and op is not None:
+ ps.prev()
+ break
+
+ if op is not None:
+ _logger.debug('parse_operator(): %d - %d: %s', startofs, ps.ofs, ps.str[startofs:ps.ofs])
+ return op
+ else:
+ return self.INVALID_OP
def parse_func_args(self, ps):
startofs = ps.ofs
args = []
pcount = 1
while ps.more() and pcount > 0:
- if ps.char == ',':
+ if ps.char == ',' and pcount == 1:
args.append(ps.str[startofs:ps.ofs])
startofs = ps.ofs + 1
elif ps.char == '(':
diff --git a/layout.py b/layout.py
index 4f748c2..ca1ea35 100644
--- a/layout.py
+++ b/layout.py
@@ -144,6 +144,7 @@ class CalcLayout:
def show_it(self):
self._parent.set_canvas(self.grid)
self._parent.show_all()
+ self.text_entry.grab_focus()
def show_history(self, window_list):
if self.history is None:
diff --git a/mathlib.py b/mathlib.py
index e1a7eed..8cf1cca 100644
--- a/mathlib.py
+++ b/mathlib.py
@@ -252,6 +252,18 @@ class MathLib:
def ceil(self, x):
return self.d(math.ceil(x))
+ def shift_left(self, x, y):
+ if self.is_int(x) and self.is_int(y):
+ return self.d(int(x) << int(y))
+ else:
+ return 0
+
+ def shift_right(self, x, y):
+ if self.is_int(x) and self.is_int(y):
+ return self.d(int(x) >> int(y))
+ else:
+ return 0
+
def factorize(self, x):
if not self.is_int(x):
return 0
diff --git a/plotlib.py b/plotlib.py
index 07db19c..9ee173b 100644
--- a/plotlib.py
+++ b/plotlib.py
@@ -82,6 +82,13 @@ class PlotLib:
self.svg_data += '%f,%f ' % (c[0], c[1])
self.svg_data += '" />\n'
+ def add_text(self, c, text, rotate=0):
+ c = self.rcoords_to_coords(c)
+ self.svg_data += '<text x="%f" y="%f"' % (c[0], c[1])
+ if rotate != 0:
+ self.svg_data += ' transform="rotate(%d)"' % (rotate)
+ self.svg_data += '>%s</text>\n' % (text)
+
def determine_bounds(self, vals):
self.minx = self.miny = 1e99
self.maxx = self.maxy = -1e99
@@ -102,9 +109,6 @@ class PlotLib:
def add_curve(self, vals):
self.determine_bounds(vals)
- self.plot_line((0.08, 0.08), (0.08, 0.92), "black")
- self.plot_line((0.08, 0.92), (0.92, 0.92), "black")
-
c = []
for v in vals:
c.append(self.vals_to_rcoords(v))
@@ -112,6 +116,13 @@ class PlotLib:
self.plot_polyline(c, "blue")
+ def draw_axes(self, labelx, labely):
+ self.plot_line((0.08, 0.92), (0.92, 0.92), "black")
+ self.add_text((0.50, 0.98), labelx)
+
+ self.plot_line((0.08, 0.08), (0.08, 0.92), "black")
+ self.add_text((-0.50, 0.065), labely, rotate=-90)
+
def export_plot(self, fn):
f = open(fn, "w")
f.write(self.svg_data)
@@ -127,12 +138,13 @@ class PlotLib:
self.set_size(200, 200)
self.create_image()
+ self.draw_axes(var, eqn)
+
vals = self.evaluate(eqn, var, range)
# print 'vals: %r' % vals
self.add_curve(vals)
self.finish_image()
- self.export_plot("/tmp/calculate_graph.svg")
-
+# self.export_plot("/tmp/calculate_graph.svg")
return self.get_svg()
diff --git a/toolbars.py b/toolbars.py
index 8b06fae..cc137dd 100644
--- a/toolbars.py
+++ b/toolbars.py
@@ -164,4 +164,4 @@ class FormatToolbar(gtk.Toolbar):
calc.ml.set_angle_type(MathLib.ANGLE_DEG)
elif text == 'rad':
calc.ml.set_angle_type(MathLib.ANGLE_RAD)
- _logger.debug('Angle type: %s', self.calc.ml.angle_scaling)
+ _logger.debug('Angle type: %s', self.ml.angle_scaling)