#!/usr/bin/env python """ Copyright 2009 Adam Schreiber This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ import gtk import math class DrawFractionalArea(gtk.DrawingArea): def __init__(self): gtk.DrawingArea.__init__(self) self.connect_after("expose_event", self.expose) self.ones = 0 self.tenths = 0 self.hundredths = 0 def expose(self, widget, event): self.context = widget.window.cairo_create() # set a clip region for the expose event self.context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height) self.context.clip() self.draw(self.context) return False def draw (self, context): rect = self.get_allocation() width = min(rect.width, rect.height) - 10 x = int(round((rect.width - width)/2)) y = int(round((rect.height - width)/2)) context.rectangle(gtk.gdk.Rectangle(x, y, width, width)) context.set_source_rgba(1.0, 0, 0, 0.25) context.fill_preserve() context.set_source_rgb(1, 0, 0) context.stroke() if (self.ones != 0): context.rectangle(gtk.gdk.Rectangle(x + 10, y + 10, width - 20, width - 20)) context.set_source_rgba(0, 0, 1.0, 1) context.fill_preserve() else: tenthswidth = int(width/10) hundredthswidth = int(width/100) for m in range(1, self.tenths + 1): context.rectangle(gtk.gdk.Rectangle(x + 10, y + width - m * tenthswidth + 5, width - 20, tenthswidth - 10)) context.set_source_rgba(0, 0, 1.0, 1) context.fill_preserve() for m in range(1, self.hundredths + 1): context.rectangle(gtk.gdk.Rectangle(x + 10, y + width - self.tenths * tenthswidth - m * hundredthswidth + 1 - 5, width - 20, hundredthswidth - 1)) context.set_source_rgba(0, 0, 1.0, 1) context.fill_preserve() def set_value (self, value): val = round(value, 2) valt = val*100 self.ones = int(math.floor(math.fmod(valt,math.pow(10,3))/math.pow(10,2))) self.tenths = int(math.floor(math.fmod(valt,math.pow(10,2))/math.pow(10,1))) self.hundredths = int(math.floor(math.fmod(valt,math.pow(10,1)))) self.queue_draw () def get_value (): return (self.ones + self.tenths * 10**-1 + self.hundredths * 10**-2) def main(): window = gtk.Window(gtk.WINDOW_TOPLEVEL) window.connect("delete_event", delete_event) window.connect("destroy", gtk.main_quit) window.set_border_width(10) window.set_default_size(640, 480) window.set_title("Deci") vbox = gtk.VBox (False, 10) window.add(vbox) # Scrollbar Value Label hbox = gtk.HBox() spinbut = gtk.SpinButton() spinbut.set_range(0.01,1) spinbut.set_increments(0.01,0.1) spinbut.set_digits(2) spinbut.set_numeric(True) hbox.pack_start(spinbut, True, False) vbox.pack_start(hbox, False) # Scrollbar hscrollbar = gtk.HScrollbar() hscrollbar.set_range(0.01,1) hscrollbar.set_increments(0.01,0.1) hscrollbar.set_value(0.01) vbox.pack_start(hscrollbar, False) # Equivalent Label equivlab = gtk.Label("0 * 1 + 0 * 0.1 + 1 * 0.01 = 0.01") vbox.pack_start(equivlab, False) # Power of 10 Equivalent Label powequivlab = gtk.Label("0 * 100 + 0 * 10-1 + 1 * 10-2 = 0.01") powequivlab.set_use_markup(True) vbox.pack_start(powequivlab, False) # Start Figure Box fractbox = DrawFractionalArea() vbox.pack_start(fractbox) spinbut.connect("value-changed", scrollbar_changed, [spinbut, hscrollbar, equivlab, powequivlab, fractbox]) hscrollbar.connect("value-changed", scrollbar_changed, [spinbut, hscrollbar, equivlab, powequivlab, fractbox]) window.show_all() gtk.main() def scrollbar_changed(range, data=None): spinbut = data[0] hscrollbar = data[1] equivlab = data[2] powequivlab = data[3] fractbox = data[4] val = round(range.get_value(),2) valt = val*100 val2 = int(math.floor(math.fmod(valt,math.pow(10,3))/math.pow(10,2))) val1 = int(math.floor(math.fmod(valt,math.pow(10,2))/math.pow(10,1))) val0 = int(math.floor(math.fmod(valt,math.pow(10,1)))) spinbut.set_value(val) hscrollbar.set_value(val) equivlab.set_text("{0} * 1 + {1} * 0.1 + {2} * 0.01 = {3}".format(val2, val1, val0, val)) powequivlab.set_markup("{0} * 100 + {1} * 10-1 + {2} * 10-2 = {3}".format(val2, val1, val0, val)) fractbox.set_value(val) def delete_event(widget, event, data=None): return False if __name__ == "__main__": main()