]> git.neil.brown.name Git - scribble.git/commitdiff
Initial commit
authorNeil Brown <neilb@notabene.brown>
Sun, 24 Aug 2008 03:33:58 +0000 (13:33 +1000)
committerNeil Brown <neilb@notabene.brown>
Sun, 24 Aug 2008 03:33:58 +0000 (13:33 +1000)
Just before writing recognition.

scribble.png [new file with mode: 0644]
scribble.py [new file with mode: 0755]

diff --git a/scribble.png b/scribble.png
new file mode 100644 (file)
index 0000000..a5b9cbc
Binary files /dev/null and b/scribble.png differ
diff --git a/scribble.py b/scribble.py
new file mode 100755 (executable)
index 0000000..486088c
--- /dev/null
@@ -0,0 +1,333 @@
+#!/usr/bin/env python
+
+import pygtk
+import gtk
+import os
+
+def page_cmp(a,b):
+    if a < b:
+        return -1
+    if a > b:
+        return 1
+    return 0
+
+def inc_name(a):
+    l = len(a)
+    while l > 0 and a[l-1] >= '0' and a[l-1] <= '9':
+        l -= 1
+    # a[l:] is the last number
+    if l == len(a):
+        # there is no number
+        return a + ".1"
+    num = 0 + int(a[l:])
+    return a[0:l] + ("%d" % (num+1))
+
+class ScribblePad:
+
+    def __init__(self):
+        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+        window.connect("destroy", self.close_application)
+        window.set_title("ScribblePad")
+        #window.set_size_request(480,640)
+
+        vb = gtk.VBox()
+        window.add(vb)
+        vb.show()
+
+        bar = gtk.HBox()
+        vb.add(bar)
+        bar.show()
+
+        page = gtk.DrawingArea()
+        page.set_size_request(480,540)
+        vb.add(page)
+        page.show()
+
+        # Now the widgets:
+        #  < > R u r A D C name
+        #back = gtk.Button(stock = gtk.STOCK_GO_BACK) ; back.show()
+        #fore = gtk.Button(stock = gtk.STOCK_GO_FORWARD) ; fore.show()
+        #red = gtk.ToggleButton("red"); red.show()
+        #undo = gtk.Button(stock = gtk.STOCK_UNDO) ; undo.show()
+        #redo = gtk.Button(stock = gtk.STOCK_REDO) ; redo.show()
+        #add = gtk.Button(stock = gtk.STOCK_ADD) ; add.show()
+        #delete = gtk.Button(stock = gtk.STOCK_REMOVE) ; delete.show()
+        #clear = gtk.Button(stock = gtk.STOCK_CLEAR) ; clear.show()
+        #name = gtk.Label("1.2.3.4.5") ; name.show()
+
+        back = gtk.Button("<") ; back.show()
+        fore = gtk.Button(">") ; fore.show()
+        red = gtk.ToggleButton("red"); red.show()
+        undo = gtk.Button("u") ; undo.show()
+        redo = gtk.Button("r") ; redo.show()
+        add = gtk.Button("+") ; add.show()
+        delete = gtk.Button("-") ; delete.show()
+        clear = gtk.Button("C") ; clear.show()
+        name = gtk.Label("1.2.3.4.5") ; name.show()
+
+        bar.add(back)
+        bar.add(fore)
+        bar.add(red)
+        bar.add(undo)
+        bar.add(redo)
+        bar.add(add)
+        bar.add(delete)
+        bar.add(clear)
+        bar.add(name)
+
+        back.connect("clicked", self.back)
+        fore.connect("clicked", self.fore)
+        red.connect("toggled", self.colour_change)
+        undo.connect("clicked", self.undo)
+        redo.connect("clicked", self.redo)
+        add.connect("clicked", self.add)
+        delete.connect("clicked", self.delete)
+        clear.connect("clicked", self.clear)
+        self.name = name
+        self.page = page
+        self.line = None
+        self.lines = []
+        self.hist = [] # undo history
+
+
+        page.connect("button_press_event", self.press)
+        page.connect("button_release_event", self.release)
+        page.connect("motion_notify_event", self.motion)
+        page.connect("expose-event", self.refresh)
+        page.set_events(gtk.gdk.EXPOSURE_MASK
+                        | gtk.gdk.BUTTON_PRESS_MASK
+                        | gtk.gdk.BUTTON_RELEASE_MASK
+                        | gtk.gdk.POINTER_MOTION_MASK
+                        | gtk.gdk.POINTER_MOTION_HINT_MASK)
+
+        window.show()
+        colourmap = page.get_colormap()
+        black = gtk.gdk.color_parse("black")
+        red = gtk.gdk.color_parse("red")
+        self.colour_black = page.window.new_gc()
+        self.colour_black.line_width = 2
+        self.colour_black.set_foreground(colourmap.alloc_color(black))
+
+        self.colour_red = page.window.new_gc()
+        self.colour_red.line_width = 2
+        self.colour_red.set_foreground(colourmap.alloc_color(red))
+
+        self.colour = self.colour_black
+        self.colourname = "black"
+        self.bg = page.get_style().bg_gc[gtk.STATE_NORMAL]
+
+       self.page_dir = os.environ['HOME'] + '/Pages'
+        self.load_pages()
+
+        window.show()
+
+    def close_application(self, widget):
+        self.save_page()
+        gtk.main_quit()
+
+    def load_pages(self):
+        try:
+            os.mkdir(self.page_dir)
+        except:
+            pass
+        self.names = os.listdir(self.page_dir)
+        if len(self.names) == 0:
+            self.names.append("1")
+        self.names.sort(page_cmp)
+        self.pages = {}
+        self.pagenum = 0
+        self.load_page()
+        return
+    
+    def press(self, c, ev):
+        # Start a new line
+        
+        self.line = [ self.colourname, [int(ev.x), int(ev.y)] ]
+        return
+    def release(self, c, ev):
+        #FIXME ignore line if only one dot.
+        if self.line:
+            self.lines.append(self.line)
+        self.line = None
+        return
+    def motion(self, c, ev):
+        if self.line:
+            if ev.is_hint:
+                x, y, state = ev.window.get_pointer()
+            else:
+                x = ev.x
+                y = ev.y
+            x = int(x)
+            y = int(y)
+            prev = self.line[-1]
+            c.window.draw_line(self.colour, prev[0],prev[1],x,y)
+            self.line.append([x,y])
+        return
+
+    def refresh(self, area, ev):
+        self.redraw()
+    def redraw(self):
+        self.name.set_text(self.names[self.pagenum])
+        self.page.window.draw_rectangle(self.bg, True, 0, 0,
+                                        480,640)
+        for l in self.lines:
+            if l[0] == "red":
+                col = self.colour_red
+            else:
+                col = self.colour_black
+            st = l[1]
+            for p in l[2:]:
+                self.page.window.draw_line(col, st[0], st[1],
+                                           p[0],p[1])
+                st = p
+        return
+
+    def back(self,b):
+        self.save_page()
+        if self.pagenum <= 0:
+            return
+        self.pagenum -= 1
+        self.load_page()
+        self.redraw()
+        return
+    def fore(self,b):
+        if self.pagenum >= len(self.names)-1:
+            return self.add(b)
+        self.save_page()
+        self.pagenum += 1
+        self.load_page()
+        self.redraw()
+        
+        return
+    def colour_change(self,t):
+        if t.get_active():
+            self.colour = self.colour_red
+            self.colourname = "red"
+        else:
+            self.colour = self.colour_black
+            self.colourname = "black"
+        return
+    def undo(self,b):
+        if len(self.lines) == 0:
+            return
+        self.hist.append(self.lines.pop())
+        self.redraw()
+        return
+    def redo(self,b):
+        if len(self.hist) == 0:
+            return
+        self.lines.append(self.hist.pop())
+        self.redraw()
+        return
+    def add(self,b):
+        # New name is either
+        #  - take last number and increment it
+        #  - add .1
+        if len(self.lines) == 0:
+            # don't add after a blank page
+            return
+        self.save_page()
+        newname = self.names[self.pagenum]
+        while newname in self.pages:
+            new2 = inc_name(newname)
+            if new2 not in self.pages:
+                newname = new2
+            elif (newname + ".1") not in self.pages:
+                newname = newname + ".1"
+            else:
+                newname = newname + ".0.1"
+
+        self.names = self.names[0:self.pagenum+1] + [ newname ] + \
+                     self.names[self.pagenum+1:]
+        self.pagenum += 1;
+        self.lines = []
+        self.redraw()
+        return
+    def delete(self,b):
+        if len(self.names) <= 1:
+            return
+        if len(self.lines) > 0:
+            return
+        self.save_page()
+        nm = self.names[self.pagenum]
+        if nm in self.pages:
+            del self.pages[nm]
+        self.names = self.names[0:self.pagenum] + self.names[self.pagenum+1:]
+        if self.pagenum >= len(self.names):
+            self.pagenum -= 1
+        self.load_page()
+        self.redraw()
+            
+        return
+    def clear(self,b):
+        while len(self.lines) > 0:
+            self.hist.append(self.lines.pop())
+        self.redraw()
+        return
+
+    def parseline(self, l):
+        # string in "", or num,num.  ':' separates words
+        words = l.strip().split(':')
+        line = []
+        for w in words:
+            if w[0] == '"':
+                w = w[1:-1]
+            elif w.find(',') >= 0:
+                n = w.find(',')
+                x = int(w[:n])
+                y = int(w[n+1:])
+                w = [x,y]
+            line.append(w)
+        return line
+    
+    def load_page(self):
+        nm = self.names[self.pagenum]
+        if nm in self.pages:
+            if self.names[self.pagenum] in self.pages:
+                self.lines = self.pages[self.names[self.pagenum]]
+            return
+        self.lines = [];
+        try:
+            f = open(self.page_dir + "/" + self.names[self.pagenum], "r")
+        except:
+            f = None
+        if f:
+            l = f.readline()
+            while len(l) > 0:
+                self.lines.append(self.parseline(l))
+                l = f.readline()
+            f.close()
+        return
+
+    def save_page(self):
+        self.pages[self.names[self.pagenum]] = self.lines
+        fn = self.page_dir + "/" + self.names[self.pagenum]
+        if len(self.lines) == 0:
+            try:
+                os.unlink(fn)
+            except:
+                pass
+            return
+        f = open(fn, "w")
+        for l in self.lines:
+            start = True
+            if not l:
+                continue
+            for w in l:
+                if not start:
+                    f.write(":")
+                start = False
+                if isinstance(w, str):
+                    f.write('"%s"' % w)
+                elif isinstance(w, list):
+                    f.write("%d,%d" %( w[0],w[1]))
+            f.write("\n")
+        f.close()
+        
+def main():
+    gtk.main()
+    return 0
+if __name__ == "__main__":
+    ScribblePad()
+    main()
+