#!/usr/bin/python # -*- coding: utf-8 -*- from GUI import Application, ScrollableView, Window, Font, Colors from pygments import highlight from pygments.lexers import ActionScriptLexer # from pygments.lexers import * if False: from pygments.lexers import text, templates, math, dotnet, parsers, hdl, asm, foxpro, special from pygments.styles import default from pygments.formatter import Formatter from pygments.filters import NameHighlightFilter from pygments.token import Token def hex2rgb(hex): a=hex[1] b=hex[2] c=hex[3] if len(hex)==7: d=hex[4] e=hex[5] f=hex[6] ab = a+b cd = c+d ef = e+f return (int(ab, 16)/256.0, int(cd, 16)/256.0, int(ef, 16)/256.0) elif len(hex)==9: d=hex[4] e=hex[5] f=hex[6] g=hex[7] h=hex[8] ab = a+b cd = c+d ef = e+f gh = g+h return (int(ab, 16)/256.0, int(cd, 16)/256.0, int(ef, 16)/256.0, int(gh, 16)/256.0) else: return (int(a, 16)/16.0, int(b, 16)/16.0, int(c, 16)/16.0) class EverythingHighlightFilter(NameHighlightFilter): def __init__(self, names, tokentype, names2, tokentype2, names3, tokentype3): NameHighlightFilter.__init__(self, names=names, tokentype=tokentype) self.names2 = names2 self.tokentype2 = tokentype2 self.names3 = names3 self.tokentype3 = tokentype3 def filter(self, lexer, stream): define = False for ttype, value in stream: if value in self.names: ttype = self.tokentype elif value in self.names2: ttype = self.tokentype2 elif value in self.names3: ttype = self.tokentype3 yield ttype, value class PyGUIFormatter(Formatter): def __init__(self, **options): Formatter.__init__(self, **options) self.styles = {} for token, style in self.style: self.styles[token] = {} if style['color']: self.styles[token]['color'] = Colors.rgb(*hex2rgb(style['color'])) def format(self, tokensource, outfile): for ttype, value in tokensource: self.lines = 0 self.tabs = 0 self.cr.gsave() if 'color' in self.styles[ttype]: self.cr.textcolor = self.styles[ttype]['color'] else: if ttype==Token.Text: self.lines+=value.count('\n') self.tabs+=value.count('\t') self.cr.show_text(value) self.cr.stroke() self.cr.grestore() if self.lines: self.cr.rmoveto(-self.cr.current_point[0],self.lines*self.height) if self.tabs: self.cr.rmoveto(self.tabwidth*self.tabs, 0) class CodeEditor(ScrollableView): def __init__(self): ScrollableView.__init__(self) self.text = "_root.onMouseDown = function () {\n\ttrace('Hi');\n};" self.font = Font('Courier', 16) self.selecting = False self.lexer = ActionScriptLexer() self.cursorpos = 0 self.scursorpos = 0 self.selection = (0,0) self.formatter = PyGUIFormatter() # self.filter = NameHighlightFilter( self.filter = EverythingHighlightFilter( names=['trace'], tokentype=Token.Keyword, names2=['_root', '_global'], tokentype2=Token.Name.Builtin, names3=['_alpha', 'blendMode', 'cacheAsBitmap', '_currentframe', '_droptarget', 'enabled', 'filters', 'focusEnabled', '_focusRect', 'forceSmoothing', '_framesloaded', '_height', '_highquality', 'hitArea', '_lockroot', 'menu', 'opaqueBackground', '_parent', '_quality', '_rotation', 'scale9Grid', 'scrollRect', '_soundbuftime', 'tabChildren', 'tabEnabled', 'tabIndex', '_target', 'totalframes', 'trackAsMenu', 'transform', '_url', 'useHandCursor', '_visible', '_width', '_x', '_xmouse', '_xscale', '_y', '_ymouse', '_yscale'], tokentype3=Token.Name.Variable.Class ) self.extent = (self.width, self.height) # Not working - no idea why - disabled to add speed self.lexer.add_filter(self.filter) def container_resized(self, event): self.extent = (self.width, self.height) ScrollableView.container_resized(self, event) def draw(self, cr, update_rect): cr.fillcolor = Colors.rgb(1,1,1) cr.fill_rect(update_rect) d = self.font.descent h = self.font.height w = self.font.width(' ') cr.font = self.font if '\n' in self.text[:self.scursorpos]: scw = self.font.width(self.text[self.text.rindex('\n',0,self.scursorpos):self.scursorpos]) else: scw = self.font.width(self.text[:self.scursorpos]) if '\n' in self.text[:self.cursorpos]: cw = self.font.width(self.text[self.text.rindex('\n',0,self.cursorpos):self.cursorpos]) else: cw = self.font.width(self.text[:self.cursorpos]) selines = self.text[:self.scursorpos].count('\n')+1 elines = self.text[:self.cursorpos].count('\n')+1 if self.selecting: cr.fillcolor = Colors.rgb(0.5,0.75,1) cr.moveto(scw,d+h*selines) cr.lineto(scw,-h+h*selines) if selines!=elines: cr.lineto(self.extent[0],-h+h*selines) cr.lineto(self.extent[0],-h+h*elines) cr.lineto(cw,-h+h*elines) cr.lineto(cw,d+h*elines) if selines != elines: cr.lineto(0,d+h*elines) cr.lineto(0,d+h*selines) cr.fill() # cr.fill_rect([scw,d+h*elines,cw,-h+h*elines]) cr.newpath() cr.moveto(0,self.font.height) self.formatter.cr = cr self.formatter.height = self.font.height self.formatter.tabwidth = self.font.width('\t') highlight(self.text, self.lexer, self.formatter) cr.newpath() cr.moveto(cw,d+h*elines) cr.lineto(cw,-h+h*elines) cr.stroke() # cr.show_text(self.text) # cr.stroke() def mouse_down(self, event): self.become_target() x, y = event.position self.selecting = False # self.cursorpos = self.text.replace('\n',' ',int(y/self.font.height)-1).find('\n') # if self.cursorpos==-1: # self.cursorpos = len(self.text)-1 # self.cursorpos+=1 # self.cursorpos = min(self.cursorpos+int(x/self.font.width(' ')), max(self.text.find('\n',self.cursorpos+1),0) or len(self.text)) lns = self.text.splitlines() self.cursorpos = sum([len(i) for i in lns[:int(y/self.font.height)]]) try: self.cursorpos += min(int(x/self.font.width(' '))+1,lns[int(y/self.font.height)]) except: pass self.scursorpos = self.cursorpos self.selection = (self.cursorpos, self.cursorpos) if int(y/self.font.height): self.cursorpos+=1 self.invalidate_rect([0,0,self.extent[0],self.extent[1]]) def mouse_drag(self, event): x, y = event.position self.selecting = True lns = self.text.splitlines() self.cursorpos = sum([len(i) for i in lns[:int(y/self.font.height)]]) try: self.cursorpos += min(int(x/self.font.width(' '))+1,lns[int(y/self.font.height)]) except: pass if int(y/self.font.height): self.cursorpos+=1 self.selection = (min(self.cursorpos, self.scursorpos), max(self.cursorpos, self.scursorpos)) self.invalidate_rect([0,0,self.extent[0],self.extent[1]]) def key_down(self, event): keydict = {127:"backspace",63272:"delete",63232:"up_arrow",63233:"down_arrow", 63235:"right_arrow",63234:"left_arrow",13:"enter",9:"tab", 63236:"F1",63237:"F2",63238:"F3",63239:"F4",63240:"F5", 63241:"F6",63242:"F7",63243:"F8",27:"escape"} if not event.unichars=='': if ord(event.unichars) in keydict: key = keydict[ord(event.unichars)] else: key = event.unichars print 'uni', key else: key = event.key#.upper() print key if key == "\b": if self.cursorpos>0: self.text = self.text[:self.cursorpos-1]+self.text[self.cursorpos:] elif key == "enter": self.text = self.text[:self.cursorpos]+"\n"+self.text[self.cursorpos:] self.height = self.font.height*(self.text.count('\n')+1) self.cursorpos += 1 elif key == "backspace": if self.cursorpos>0: self.text = self.text[:self.cursorpos-1]+self.text[self.cursorpos:] self.cursorpos -= 1 elif key == "delete": if self.cursorpos0: self.cursorpos -= 1 elif key == "right_arrow": if self.cursorpos