From 5bb2d2f4785061216e0212a71837cabb021ad146 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Sun, 24 Aug 2008 13:33:58 +1000 Subject: [PATCH 1/1] Initial commit Just before writing recognition. --- scribble.png | Bin 0 -> 10593 bytes scribble.py | 333 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 333 insertions(+) create mode 100644 scribble.png create mode 100755 scribble.py diff --git a/scribble.png b/scribble.png new file mode 100644 index 0000000000000000000000000000000000000000..a5b9cbc338e840319b681a3f67209c581c6f891f GIT binary patch literal 10593 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 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() + -- 2.39.5