Advertisement
here2share

# standard_py60_full_canvas.py

May 6th, 2019
903
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # -*- coding: utf-8 -*-
  2. from graphics import *
  3. import appuifw,time,e32,topwindow,copy,os,re
  4. import struct,zlib,tempfile,base64,math,bisect
  5. from array import array
  6. from key_codes import *
  7.  
  8. canvasUnnormal=[]
  9. mainCanvas=None
  10. def getCanvas(*arg,**kw):
  11.     global mainCanvas
  12.     mainCanvas=appuifw.Canvas(*arg,**kw)
  13.     return mainCanvas
  14. class canvas:
  15.     def __init__(self,redraw_callback=None,event_callback=None,resize_callback=None,screen='normal',appmenu=[],mouse=2):
  16.         self.inited=0
  17.         if mouse==2:mouse=(not appuifw.touch_enabled())
  18.         self.mouseEnabled=mouse
  19.         self.mouseX=0
  20.         self.mouseY=0      
  21.         self.appmenu=appmenu
  22.         self.lock=e32.Ao_lock()
  23.         self.old=(appuifw.app.body,appuifw.app.exit_key_handler,appuifw.app.menu,appuifw.app.screen)
  24.         self.menu=(u'show canvas',self.show)
  25.         self.screen=screen
  26.         #self.text=appuifw.Text()
  27.         self.redrawTimer=e32.Ao_timer()
  28.         self.lastRedraw=0
  29.         appuifw.app.screen=self.screen
  30.         appuifw.app.menu=appmenu
  31.         appuifw.app.exit_key_handler=self.hide
  32.         self.redraw_callback=redraw_callback
  33.         self.event_callback=event_callback
  34.         self.resize_callback=resize_callback
  35.         self.canvas=appuifw.Canvas(self.redraw,self.event,self.resize)
  36.         self.img=Image.new(self.canvas.size,mode='RGB')
  37.         size0=self.canvas.size
  38.         self.size0=(size0,self.screen)
  39.         appuifw.app.body=self.canvas
  40.         size1=appuifw.app.body.size
  41.         self.case=(size0==size1)
  42.         self.bindDict=dict()
  43.         if not self.case:
  44.             self.canvas=appuifw.Canvas(self.redraw,self.event,self.resize)
  45.         self.inited=1
  46.         self.hide()
  47.         if self.mouseEnabled:
  48.             self.bind((EStdKeyUpArrow,1),lambda:self.mouseMove('up',1))
  49.             self.bind((EStdKeyDownArrow,1),lambda:self.mouseMove('down',1))
  50.             self.bind((EStdKeyLeftArrow,1),lambda:self.mouseMove('left',1))
  51.             self.bind((EStdKeyRightArrow,1),lambda:self.mouseMove('right',1))
  52.            
  53.             self.bind((EStdKeyUpArrow,2),lambda:self.mouseMove('release',2))
  54.             self.bind((EStdKeyDownArrow,2),lambda:self.mouseMove('release',2))
  55.             self.bind((EStdKeyLeftArrow,2),lambda:self.mouseMove('release',2))
  56.             self.bind((EStdKeyRightArrow,2),lambda:self.mouseMove('release',2))
  57.         self.lock.wait()
  58.     def mouseMove(self,action,ty=1):
  59.         if ty==2:self.mouseSpeed=1
  60.         try:
  61.             if self.mouseSpeed<=30:self.mouseSpeed+=2
  62.             speed=self.mouseSpeed
  63.         except:
  64.             self.mouseSpeed=1
  65.             speed=self.mouseSpeed
  66.         w,h=self.canvas.size
  67.         if action=='up':self.mouseY+=-speed
  68.         elif action=='down':self.mouseY+=speed
  69.         elif action=='left':self.mouseX+=-speed
  70.         elif action=='right':self.mouseX+=speed
  71.         if self.mouseX<0:self.mouseX=0
  72.         if self.mouseY<0:self.mouseY=0
  73.         if self.mouseX>=w:self.mouseX=w-1
  74.         if self.mouseY>=h:self.mouseY=h-1
  75.         self.redraw(None)
  76.     def bind(self,key,fun):
  77.         self.bindDict[key]=fun
  78.     def redraw(self,rect):
  79.         if callable(self.redraw_callback):self.redraw_callback(self,None)
  80.         else:self.canvas.blit(self.img)
  81.         if self.mouseEnabled:
  82.             self.canvas.blit(systemMouse[0],target=(self.mouseX-7,self.mouseY-7),mask=systemMouse[1])
  83.            
  84.     def event(self,ev):
  85.         if type(ev) is dict and 'scancode' in ev  and (ev['scancode'],ev['type']) in self.bindDict:
  86.             self.bindDict[(ev['scancode'],ev['type'])]()
  87.         if callable(self.event_callback):self.event_callback(self,ev)
  88.          
  89.     def resize(self,size):
  90.         #if size!=self.size0[0] and appuifw.app.screen==self.size0[1]:self.canvas=getCanvas(self.redraw,self.event,self.resize)
  91.         if self.resize_callback!=None:
  92.             try:self.resize_callback(self,size)
  93.             except:pass
  94.     def show(self,fun=None):
  95.         appuifw.app.screen=self.screen
  96.         if self.case:
  97.             appuifw.app.body=self.canvas
  98.         else:
  99.             appuifw.app.body=self.canvas
  100.             self.canvas=appuifw.Canvas(self.redraw,self.event,self.resize)
  101.         appuifw.app.menu=self.appmenu
  102.         appuifw.app.exit_key_handler=self.hide
  103.         if callable(fun):fun(self)
  104.         try:self.lock.wait()
  105.         except:pass
  106.     def switch(self):pass
  107.     def hide(self):
  108.         appuifw.app.screen=self.old[3]
  109.         self.redrawTimer.cancel()
  110.         if self.case:pass
  111.         else:appuifw.app.body=self.canvas
  112.         appuifw.app.exit_key_handler=self.old[1]
  113.         appuifw.app.menu=self.old[2]
  114.         appuifw.app.body=self.old[0]
  115.         try:self.lock.signal()
  116.         except:pass
  117.  
  118. def drawMouse(width,color0=0xff00,color1=0):
  119.     i=Image.new((width,width))
  120.     iMask=Image.new(i.size,mode='1')
  121.     i.clear(0)
  122.     iMask.clear(0)
  123.     w=iRound(max(width*0.16,1))
  124.     i=color_fill(i,(color0,color1,2))
  125.     #i.ellipse( (0,0,width,width),fill=0)
  126.     #i.ellipse((w,w,width-w,width-w),fill=0xeee4aa)
  127.     cx,cy=centerPoint(0,0,width,width)
  128.     iMask.ellipse((0,0,width,width),fill=0xffffff)
  129.     iMask.ellipse((w,w,width-w,width-w),fill=0)
  130.     iMask.ellipse((cx-w,cy-w,cx+w,cy+w),fill=0xffffff)
  131.     return (i,iMask)
  132.  
  133. def getRoute():
  134.     cv=canvas(mouse=2)
  135.     bg,top=systemConfig['background'],systemConfig['top']
  136.     cv.img.clear(bg)
  137.     mid=mid_color(bg,top)
  138.     cv.mid,cv.top,cv.bg=mid,top,bg
  139.     imgBottom=Image.new(cv.img.size)
  140.     imgBottom.clear(cv.bg)
  141.     imgTop=Image.new(cv.img.size)
  142.     imgMask=Image.new(imgTop.size,mode='1')
  143.     imgTop.clear(top)
  144.     imgMask.clear(0)
  145.     points=[]
  146.     cv.routeType=None  #line,curve,polygon,curve polygon
  147.     def redraw(cv=cv,points=points):
  148.         imgMask.clear(0)
  149.         #imgTop.clear(cv.top)
  150.         if cv.routeType==None:
  151.             for p in points:imgMask.point(p,0xffffff,width=5)
  152.         elif cv.routeType==0:imgMask.line(points,0xffffff)
  153.         elif cv.routeType==1:imgMask.line(tuple(genCurveRoutePoints(points)),0xffffff)
  154.         elif cv.routeType==2:imgMask.polygon(points,fill=0xffffff)
  155.         elif cv.routeType==3:imgMask.polygon(tuple(genCurvePolygonPoints(points)),fill=0xffffff)
  156.         cv.img.blit(imgBottom)
  157.         cv.img.blit(imgTop,mask=imgMask)
  158.         cv.redraw(None)
  159.     def showMenu(cv=cv,bg=bg,top=top,mid=mid,points=points,selection=None):
  160.         pos=cv.mouseX
  161.         cv.mouseX=-1
  162.         menu=[u'line',u'curve',u'polygon',u'curve polygon',u'rotate',u'color',u'points',u'quit']
  163.         if selection==None:selection=selection_handler(menu,u'action')
  164.         if selection==None:return 0
  165.         elif selection==len(menu)-1:
  166.             cv.hide()
  167.             return 0
  168.         if selection<4:
  169.             cv.routeType=selection
  170.         elif selection==6:
  171.             cv.routeType=None
  172.         elif selection==5:
  173.             color=color_select()[0]
  174.             if color==None:
  175.                 cv.mouseX=pos
  176.                 return 0
  177.             else:
  178.                 cv.top=color
  179.                 imgTop.clear(cv.top)
  180.         elif selection==4:
  181.             d=appuifw.query(u'degrees of rotation','float')
  182.             if d==None:d=0
  183.             radians=math.radians(d)
  184.             cx,cy=centerPoint(max((x[0] for x in points)),max((x[1] for x in points)),min((x[0] for x in points)),min((x[1] for x in points)))
  185.             points[:]=[pointRotate(x[0],x[1],radians,cx,cy) for x in points]
  186.         cv.mouseX=pos
  187.         redraw()
  188.     def addPoints(cv=cv,bg=bg,top=top,mid=mid,points=points):
  189.         w,h=cv.img.size
  190.         w=iRound(w*0.75)
  191.         h=iRound(h*0.75)
  192.         if not 0<=cv.mouseX<w or not 0<=cv.mouseY<h:return 0
  193.         pos=(cv.mouseX,cv.mouseY)
  194.         cv.img.clear(bg)
  195.         points.append(pos)
  196.         redraw()
  197.     def init(self):
  198.         appuifw.app.exit_key_handler=showMenu
  199.         self.mouseX=-1
  200.     cv.bind((EScancodeSelect,2),addPoints)
  201.     cv.show(init)
  202.     del cv
  203.     return points
  204.  
  205. class columnsCanvas(object):
  206.     def __init__(self,c=4,screen='large',bg=0xeee4aa,top=0,eventCallback=None):
  207.         self.cv=canvas(screen=screen,mouse=2)
  208.         self.eventCallback=eventCallback
  209.         self.cv.top,self.cv.mid,self.cv.bg=top,mid_color(top,bg),bg
  210.         self.cv.dragLog=[]
  211.         self.cv.mouseX=-1
  212.         self.cv.img.clear(self.cv.mid)
  213.         w,h=self.cv.img.size
  214.         self.cv.columns=c
  215.         self.cv.column=(float(w)/c,float(h)/c)
  216.         self.cv.iColumn=(int(w/c)-1,int(h/c)-1)
  217.         self.cv.iMain=(int(w-1-float(w)/c),int(h-1-float(h)/c))
  218.         self.cv.tempColumn=[Image.new(self.cv.iColumn,mode='RGB'),Image.new(self.cv.iColumn,mode='1')]
  219.         self.cv.tempMain=[Image.new(self.cv.iMain,mode='RGB'),Image.new(self.cv.iMain,mode='1')]
  220.         self.cv.imgMain=Image.new(self.cv.iMain)
  221.         self.cv.imgMain.clear(self.cv.bg)
  222.         self.cv.img.clear(self.cv.top)
  223.         columns(self.cv.img,self.cv.column,self.cv.mid)
  224.         self.cv.img.blit(self.cv.imgMain,target=self.getPos(0))
  225.         #self.cv.img.rectangle((self.cv.column,self.cv.img.size),fill=self.cv.bg)
  226.         self.show=self.cv.show
  227.         self.hide=self.cv.hide
  228.         self.cv.event_callback=self.event
  229.     def getSize(self,n):
  230.         if n==0:return self.cv.iMain
  231.         else:return self.cv.iColumn
  232.     def logDrag(self,pos):
  233.         if self.cv.dragLog==[] or pos!=self.cv.dragLog[-1]:self.cv.dragLog.append(pos)
  234.     def clearDragLog(self):
  235.         self.cv.dragLog[:]=[]
  236.    
  237.    
  238.     def getPos(self,n):
  239.         cw,ch=self.cv.column
  240.         w,h=self.cv.img.size
  241.         if n==0:return (int(cw)+1,1)
  242.         elif 1<=n<=self.cv.columns:return (1,int(ch*(n-1))+1)
  243.         elif self.cv.columns<n<self.cv.columns*2:
  244.             n=n-self.cv.columns
  245.             h=int(h-ch)+1
  246.             return (int(cw*n)+1,h)
  247.     def getFocus(self,pos):
  248.         x,y=pos
  249.         if x<0 or y<0:return None
  250.         w,h=self.cv.img.size
  251.         cw,ch=self.cv.column
  252.         if cw<x<w and 0<=y<h-ch:return 0
  253.         elif 0<=x<cw:return int(y/ch)+1
  254.         elif h-ch<y<=h and cw<x<w:return int(x/cw)+self.cv.columns
  255.     def getTopBottom(self,n):
  256.         x,y=self.getPos(n)
  257.         w,h=self.getSize(n)
  258.         return (x,y,x+w,y+h)
  259.     def inFocus(self,pos,n):
  260.         ax,ay,bx,by=self.getTopBottom(n)
  261.         x,y=pos
  262.         return ax<=x<bx and ay<=y<by
  263.     def event(self,obj,ev):
  264.         if 'scancode' in ev and (ev['scancode'],ev['type'])[0]==EScancodeSelect:
  265.             pos=(self.cv.mouseX,self.cv.mouseY)
  266.             ty=ev['type']
  267.         elif 'pos' in ev:
  268.             pos=ev['pos']
  269.             ty=ev['type']
  270.         else:return 0
  271.         if ty in (2,258):self.clearDragLog()
  272.         elif ty in (3,263) and self.inFocus(pos,0):self.logDrag(pos)
  273.         focus=self.getFocus(pos)
  274.         if focus==None:return 0
  275.         if callable(self.eventCallback):
  276.             return self.eventCallback((focus,pos,ty))
  277.         tx=u'%s,%s,%s'%(focus,pos,ty)
  278.         self.cv.img.rectangle((self.getTopBottom(0)),fill=self.cv.bg)
  279.         self.cv.img.text((self.cv.column[0]*2,self.cv.column[1]*2),tx,self.cv.top,font=('normal',19))
  280.         if len(self.cv.dragLog)>1:self.cv.img.line(self.cv.dragLog,self.cv.mid)
  281.         self.cv.redraw(None)        
  282.     def focusRedrawCommands(self,n,commands):
  283.         px,py=self.getPos(n)
  284.         width,height=self.getSize(n)
  285.         cor=(px,py,px+width,py+height)
  286.         drawCommands(self.cv.img,commands,cor)
  287.         self.cv.redraw(None)
  288.         return 0
  289.  
  290.     def focusRedraw(self,n,img,mask=None,pos='0w,0h'):
  291.         ipos,size=self.getPos(n),self.getSize(n)
  292.         px,py=posUnpack(size[0],size[1],pos)
  293.         if n==0:i0,i1=self.cv.tempMain
  294.         else:i0,i1=self.cv.tempColumn
  295.         i1.clear(0)
  296.         w,h=img.size
  297.         i1.rectangle((px,py,px+w,py+h),fill=0xffffff)
  298.         if mask!=None:i1.blit(mask,target=(px,py))
  299.         i0.blit(img,target=(px,py))
  300.         self.cv.img.blit(i0,target=(ipos),mask=i1)
  301.         self.cv.redraw(None)
  302.     def focusRedrawResize(self,n,img,keepaspect=1):
  303.         size,pos=self.getSize(n),self.getPos(n)
  304.         if size==img.size:self.cv.img.blit(img,target=pos)
  305.         else:self.cv.img.blit(img.resize(size,keepaspect=keepaspect),target=pos)
  306.         self.cv.redraw(None)
  307.  
  308.  
  309. def circle(img,pos,r,*arg,**kw):
  310.     x,y=pos
  311.     cor=(x-r,y-r,x+r,y+r)
  312.     img.ellipse(cor,*arg,**kw)
  313.  
  314. def drawPad(background=0xeee4aa,top=0):
  315.     c=columnsCanvas(10,screen='full')
  316.     c.bg=background
  317.     c.top=top
  318.     c.commandsPadding=[]
  319.     c.commandLinePadding=[None,[],None,None]
  320.     def redraw(c=c):
  321.         color=c.top  
  322.         c.cv.img.blit(c.cv.imgMain,target=c.getPos(0))
  323.         ty,data,fill,fillstyle=c.commandLinePadding
  324.        
  325.         if ty=='points':
  326.             for p in data:
  327.                 c.cv.img.point(p,color)
  328.         elif ty!=None and data!=[]:
  329.             points=posPack(c.cv.img.size[0],c.cv.img.size[1],data)
  330.             commandLine=[ty,[points,c.top],dict(fill=fill),fillstyle]
  331.             try:drawCommands(c.cv.img,[commandLine])
  332.             except:pass
  333.         for p in data:c.cv.img.point(p,0x777255,width=5)
  334.         c.cv.redraw(None)
  335.     def event(ev,c=c):
  336.         focus,pos,ty=ev
  337.         tys=('line','curve','bezier','points',None,'polygon','curvePolygon')
  338.         if ty in (2,258):
  339.             if 1<=focus<8:
  340.                 c.commandLinePadding[0]=tys[focus-1]
  341.             elif focus==8:
  342.                 try:c.commandLinePadding[1].pop()
  343.                 except:pass
  344.             elif focus==10:
  345.                 if c.commandLinePadding[2]==None:c.commandLinePadding[2]=0
  346.                 else:c.commandLinePadding[2]=None
  347.             elif focus==11:
  348.                 f=[[u'Color #1','color',c.bg],
  349. [u'Color #2','color',c.top],
  350. [u'Fill Method','combo',[[u'Y',u'X',u'X and Y',u'From center'],0]]]
  351.                 if c.commandLinePadding[3]!=None:
  352.                      c1,c2,c3=c.commandLinePadding[3]
  353.                      f[0][2]=c1
  354.                      f[1][2]=c2
  355.                      f[2][2][1]=c3
  356.                 result=form_handler(f,u'Fill style')
  357.                 del f
  358.                 if result!=None:
  359.                     fillstyle=(result[0][2],result[1][2],result[2][2][1])
  360.                 c.commandLinePadding[3]=fillstyle
  361.                    
  362.            
  363.             redraw()
  364.         if focus==0 and ty in (2,258):
  365.             px,py=c.getPos(0)
  366.             if c.commandLinePadding[1]==[] or c.commandLinePadding[1][-1]!=pos:c.commandLinePadding[1].append(pos)
  367.             redraw()            
  368.         elif ty in (2,258):
  369.             if focus==c.cv.columns*2-1:c.hide()
  370.             elif focus==c.cv.columns*2-2:
  371.                 c.eventCallback=lambda a:1
  372.                 color=color_select(u'Select top color')
  373.                 if color!=None:
  374.                     c.top=color[0]
  375.                     c.focusRedrawCommands(c.cv.columns*2-2,[['clear',[color[0]]]])
  376.                     redraw()
  377.                 e32.ao_sleep(0.1)
  378.                 c.eventCallback=event
  379.     c.eventCallback=event
  380.     c.focusRedrawCommands(1,[
  381. ['line',['0.1w,0.5h,0.2w,0.2h,0.6w,0.7h,0.9w,0.5h',0xffff00,]]
  382. ])
  383.     c.focusRedrawCommands(2,[
  384. ['curve',['0.1w,0.9h,0.6w,0.2h,0.9w,0.9h',0xffff00]],
  385. ['line',['0.1w,0.9h,0.6w,0.2h,0.9w,0.9h',0xffff]]
  386. ])
  387.     c.focusRedrawCommands(3,[
  388. ['line',['0.1w,0.9h,0.25w,0.3h,0.8w,0.1h,0.9w,0.9h',0xffff]],
  389. ['bezier',['0.1w,0.9h,0.25w,0.3h,0.8w,0.1h,0.9w,0.9h',0xffff00]]
  390. ])
  391.    
  392.     c.focusRedrawCommands(4,[
  393. ['ellipse',['0.45w,0.45h,0.55w,0.55h',0xffff00,0xffff00]]
  394. ])
  395.     c.focusRedrawCommands(5,[
  396.         ['line',['0.2w,0.5h,0.7w,0.5h',0xffff00]],
  397.         ['polygon',['0.6w,0.4h,0.8w,0.5h,0.6w,0.6h',0xffff00,0xffff00]],
  398.         ['rectangle',['0.2w,0.42h,0.36w,0.58h',0xffff00,0xffff00]]
  399.         ])
  400.    
  401.     c.focusRedrawCommands(6,[
  402. ['polygon',['0.15w,0.15h,0.5w,0.5h,0.8w,0.15h,0.8w,0.8h,0.15w,0.8h',0xffff00]]
  403. ])
  404.     c.focusRedrawCommands(7,[
  405.         ['curvePolygon',['0.2w,0.8h,0.8w,0.8h,0.6w,0.3h,0.3w,0.3h',0xffff00]]
  406.         ])
  407.     c.focusRedrawCommands(8,(
  408.         ('line',['0.2w,0.2h,0.8w,0.8h',0xCa00]),
  409.         ('line',['0.8w,0.2h,0.2w,0.8h',0xCa00])
  410.         ))
  411.    
  412.     c.focusRedrawCommands(9,[['line',['0.1w,0.35h,0.3w,0.7h,0.8w,0.2h',0xca00]]])
  413.     c.focusRedrawCommands(10,(('rectangle',['0.2w,0.2h,0.8w,0.8h',0xca00,0xCa00]),))
  414.    
  415.    
  416.     c.focusRedrawCommands(11,[['rectangle',['0.2w,0.2h,0.8w,0.8h'],{},(0xca00,0,2)]])
  417.     c.focusRedrawCommands(12,[
  418. ['arc',['0.2w,0.2h,0.8w,0.8h',math.pi/2,0,0xca00]],
  419. ['polygon',['0.65w,0.55h,0.85w,0.55h,0.8w,0.4h',
  420. 0xca00,0xca00]]
  421. ])
  422.    
  423.     c.focusRedrawCommands(16,(
  424. ('rectangle',['0.2w,0.2h,0.8w,0.8h',0xeee4aa]),
  425. ))
  426.     c.focusRedrawCommands(17,(
  427. ('ellipse',['0.2w,0.2h,0.8w,0.8h',0xeee4aa]),
  428. ))
  429.     c.focusRedrawCommands(18,[
  430. ['rectangle',['0.2w,0.2h,0.8w,0.4h'],dict(fill=0xff0000)],
  431. ['rectangle',['0.2w,0.4h,0.8w,0.6h'],dict(fill=0xff00)],
  432. ['rectangle',['0.2w,0.6h,0.8w,0.8h'],dict(fill=0xff)],
  433. ])
  434.     c.focusRedrawResize(19,logo[0],0)
  435.     return c
  436. def gen_logo(size=100,bg=0xeee4aa,top=0):
  437.     img=Image.new((size,size))
  438.     imask=Image.new(img.size,mode='1')
  439.     imask.clear(0)
  440.     #mid=mid_color(bg,top)
  441.     mid=0x777255
  442.     img.clear(mid)
  443.     circle(img,(size*0.25,size*0.25),size*0.25,fill=top)
  444.     circle(img,(size*0.75,size*0.75),size*0.25,fill=top)
  445.     circle(img,(size*0.25,size*0.25),size*0.15,fill=bg)
  446.     circle(img,(size*0.75,size*0.75),size*0.15,fill=bg)
  447.     img.line((size*0.25,size*0.5,size*0.25,size),top,width=int(max(size*0.03,1)))
  448.     img.line((0,size*0.75,size*0.5,size*0.75),top,width=int(max(size*0.03,1)))
  449.     circle(img,(size*0.25,size*0.75),size*0.15,fill=top)
  450.     circle(img,(size*0.25,size*0.75),size*0.08,fill=bg)
  451.     img.rectangle((size*0.4,0,size,size*0.6),mid,fill=bg)
  452.     img.rectangle((size*0.4,0,size,size*0.18),fill=mid)
  453.     ##
  454.    
  455.     circle(imask,(size*0.25,size*0.25),size*0.25,fill=0xffffff)
  456.     circle(imask,(size*0.75,size*0.75),size*0.25,fill=0xffffff)
  457.     imask.line((size*0.25,size*0.5,size*0.25,size),0xffffff,width=int(max(size*0.03,1)))
  458.     imask.line((0,size*0.75,size*0.5,size*0.75),0xffffff,width=int(max(size*0.03,1)))
  459.     circle(imask,(size*0.25,size*0.75),size*0.15,fill=0xffffff)
  460.     imask.rectangle((size*0.4,0,size,size*0.6),fill=0xffffff)
  461.     return (img,imask)
  462. #*#*
  463. def web_logo(size=100,bg=0xeee4aa,top=0):
  464.     img=Image.new((size,size))
  465.     imask=Image.new(img.size,mode='1')
  466.     imask.clear(0)
  467.     #mid=mid_color(bg,top)
  468.     mid=0x777255
  469.     img.clear(mid)    
  470.     img.line((size*0.25,0,size*0.25,size),top,width=int(max(size*0.03,1)))
  471.     img.line((0,size*0.75,size,size*0.75),top,width=int(max(size*0.03,1)))
  472.     img.line((size*0.75,0,size*0.75,size),top,width=int(max(size*0.03,1)))
  473.     img.line((0,size*0.25,size,size*0.25),top,width=int(max(size*0.03,1)))
  474.    
  475.     circle(img,(size*0.25,size*0.25),size*0.25,fill=top)
  476.     circle(img,(size*0.75,size*0.75),size*0.25,fill=top)
  477.     circle(img,(size*0.25,size*0.25),size*0.15,fill=bg)
  478.     circle(img,(size*0.75,size*0.75),size*0.15,fill=bg)
  479.    
  480.     circle(img,(size*0.25,size*0.75),size*0.15,fill=top)
  481.     circle(img,(size*0.25,size*0.75),size*0.08,fill=bg)
  482.     circle(img,(size*0.75,size*0.25),size*0.15,fill=top)
  483.     circle(img,(size*0.75,size*0.25),size*0.08,fill=bg)
  484.    
  485.     ##
  486.     imask.line((size*0.25,0,size*0.25,size),0xffffff,width=int(max(size*0.03,1)))
  487.     imask.line((0,size*0.75,size,size*0.75),0xffffff,width=int(max(size*0.03,1)))
  488.     imask.line((size*0.75,0,size*0.75,size),0xffffff,width=int(max(size*0.03,1)))
  489.     imask.line((0,size*0.25,size,size*0.25),0xffffff,width=int(max(size*0.03,1)))
  490.     circle(imask,(size*0.25,size*0.25),size*0.25,fill=0xffffff)
  491.     circle(imask,(size*0.75,size*0.75),size*0.25,fill=0xffffff)
  492.     circle(imask,(size*0.75,size*0.25),size*0.15,fill=0xffffff)
  493.     circle(imask,(size*0.25,size*0.75),size*0.15,fill=0xffffff)
  494.     return (img,imask)
  495.  
  496. logo=web_logo(64)
  497.  
  498.  
  499. def columns(img,column,color=0xffffff,width=1):
  500.         if type(img) in (tuple,list):
  501.             img=Image.new(size,mode='1')
  502.             img.clear(0)
  503.             color=0xffffff
  504.         xl,yl=column
  505.         w,h=img.size
  506.         cols=int(w/xl)
  507.         lines=int(h/yl)
  508.         for x in xrange(cols+2):
  509.             cor=[int(x) for x in (x*xl-width*0.5,0,x*xl-width*0.5,h)]
  510.             img.line(cor,color,width=width)
  511.         for y in xrange(lines+2):
  512.             cor=[int(x) for x in (0,y*yl-width*0.5,w,y*yl-width*0.5)]
  513.             img.line(cor,color,width=width)
  514.         return img
  515. def in_layout(pos,layout):
  516.         try:
  517.             x0,y0=pos
  518.             w,h=layout[0]
  519.             x1,y1=layout[1]
  520.             return x1<=x0<=x1+w and y1<=y0<=y1+h
  521.         except:return 0
  522.  
  523. def in_line(a,b,c):
  524.         try:
  525.             x1,y1=a
  526.             x2,y2=b
  527.             x3,y3=c
  528.             ux,uy=(x2-x1,y2-y1)
  529.             vx,vy=(x3-x1,y3-y1)
  530.             return ux*vy==uy*vx
  531.         except:return 0
  532.  
  533. def num_to_rgb(color):
  534.         if type(color) is tuple:return color
  535.         r=int(color/0x10000)
  536.         g=int((color-r*0x10000)/0x100)
  537.         b=color-r*0x10000-g*0x100
  538.         return (r,g,b)
  539.  
  540. def rgb_to_num(color):
  541.         if type(color) in (tuple,list) and len(color)==3 and (type(color[0]),type(color[1]),type(color[2]))==(int,int,int):
  542.             r,g,b=color
  543.             return r*0x10000+g*0x100+b
  544. def mid_color(c1,c2):
  545.     if type(c1) not in (tuple,list):c1=num_to_rgb(c1)
  546.     if type(c2) not in (tuple,list):c2=num_to_rgb(c2)
  547.     return rgb_to_num(map(lambda a,b:(a+b)/2,c1,c2))
  548. def image_fill(fill,bottom):
  549.         fx,fy=fill.size
  550.         w,h=bottom.size
  551.         if 0 in (fx,fy,w,h):return bottom
  552.         xt,yt=(w/fx+(w/fx!=float(w)/fx),h/fy+(h/fy!=float(h)/fy))
  553.         bottom.blit(fill)
  554.         xpos=1
  555.         if (fx,fy)==(w,h):return bottom
  556.         for x in xrange(1,xt):
  557.             xamount=xpos*(xpos*2<xt)+(xt-xpos)*(xpos*2>=xt)
  558.             bottom.blit(bottom,target=(xpos*fx,0),source=(0,0,xamount*fx,fy))
  559.             xpos+=xamount
  560.             if xpos>=xt:break
  561.         ypos=1
  562.         for y in xrange(1,yt):
  563.             yamount=ypos*(ypos*2<yt)+(yt-ypos)*(ypos*2>=yt)
  564.             bottom.blit(bottom,target=(0,ypos*fy),source=(0,0,w,fy*yamount))
  565.             ypos+=yamount
  566.             if ypos>=yt:break
  567.         return bottom
  568.  
  569. def color_fill(img,styles):
  570.         if type(img) is tuple or type(img) is list:img=Image.new(img)
  571.         color0,color1,style=styles
  572.         w,h=img.size
  573.         if color0==color1:
  574.             img.clear(color0)
  575.             return img
  576.         elif style==0:
  577.             r0,g0,b0=num_to_rgb(color0)
  578.             r1,g1,b1=num_to_rgb(color1)
  579.             length=h
  580.             each_add=[(r1-r0)/float(length),(g1-g0)/float(length),(b1-b0)/float(length)]
  581.             for x in xrange(length):
  582.                 color_fill=(int(each_add[0]*x+r0),int(each_add[1]*x+g0),int(each_add[2]*x+b0))
  583.                 cor=(0,x,w,x)
  584.                 img.line(cor,color_fill,width=1)
  585.             return img
  586.         elif style==1:
  587.             r0,g0,b0=num_to_rgb(color0)
  588.             r1,g1,b1=num_to_rgb(color1)
  589.             length=w
  590.             each_add=[(r1-r0)/float(length),(g1-g0)/float(length),(b1-b0)/float(length)]
  591.             for x in xrange(length):
  592.                 color_fill=(int(each_add[0]*x+r0),int(each_add[1]*x+g0),int(each_add[2]*x+b0))
  593.                 cor=(x,0,x,h)
  594.                 img.line(cor,color_fill,width=1)
  595.             return img
  596.         elif style==2:
  597.             r0,g0,b0=num_to_rgb(color0)
  598.             r1,g1,b1=num_to_rgb(color1)
  599.             if w>=h:length=int(w)
  600.             else:length=int(h)
  601.             each_add=[(r1-r0)/float(length),(g1-g0)/float(length),(b1-b0)/float(length)]
  602.             for x in xrange(length):
  603.                 color_fill=(int(each_add[0]*x+r0),int(each_add[1]*x+g0),int(each_add[2]*x+b0))
  604.                 cor=(0,x*2,x*2,0)
  605.                 img.line(cor,color_fill,width=2)
  606.             return img
  607.         elif style==3:
  608.             r0,g0,b0=num_to_rgb(color0)
  609.             r1,g1,b1=num_to_rgb(color1)
  610.             if w>=h:length=int(w)
  611.             else:length=int(h)
  612.             each_add=[(r1-r0)/float(length),(g1-g0)/float(length),(b1-b0)/float(length)]
  613.             for x in xrange(length):
  614.                 color_fill=(int(each_add[0]*x+r0),int(each_add[1]*x+g0),int(each_add[2]*x+b0))
  615.                 cor=(w/2-x,h/2-x,w/2+x,h/2+x)
  616.                 img.ellipse(cor,color_fill,width=3)
  617.             return img
  618.         else:return img
  619.  
  620. def colorFill(img,style,cor=None):
  621.     if cor!=None:
  622.         return color_fill(img,style)
  623.     else:
  624.         a,b,c,d=cor
  625.         w,h=c-a,d-b
  626.         i=color_fill((w,h),style)
  627.         img.blit(i,target=(a,b))
  628.         del i
  629.         return img
  630.    
  631.  
  632. def break_text(txt,width,font,bp=0):
  633.     page=list()
  634.     point=list()
  635.     img=Image.new((1,1))
  636.     length=len(txt)
  637.     for x in xrange(length):
  638.         tx=txt[x]
  639.         measure=img.measure_text(tx[:200],font,width)
  640.         page.append(tx[:measure[2]])
  641.         if bp:point.append(x)
  642.         if len(tx)>measure[2]:
  643.             rest=tx[measure[2]:]
  644.             measure=img.measure_text(rest[:200],font,width)
  645.             while measure[2]<len(rest):
  646.                 page.append(rest[:measure[2]])
  647.                 if bp:point.append(x)
  648.                 rest=rest[measure[2]:]
  649.                 measure=img.measure_text(rest,font,width)
  650.             if len(rest)>0:
  651.                 page.append(rest)
  652.                 if bp:point.append(x)
  653.         if x<length-1:page[-1]+='\n'
  654.     del img
  655.     if bp:return (page,point)
  656.     else:return page
  657.  
  658. def round_mask(size,rsize):
  659.     mask=Image.new(size,mode='1')
  660.     mask.clear(0xffffff)
  661.     rmask=Image.new(rsize,mode='1')
  662.     rmask.clear(0)
  663.     rmask.ellipse(((0,0),rmask.size),0xffffff,fill=0xffffff)
  664.     hx=rsize[0]/2
  665.     hy=rsize[1]/2
  666.     mask.blit(rmask,target=(0,0),source=((0,0),(hx,hy)))
  667.     mask.blit(rmask,target=(mask.size[0]-hx,0),source=((hx,0),(rmask.size[0],hy)))
  668.     mask.blit(rmask,target=(0,mask.size[1]-hy),source=((0,hy),(hx,rmask.size[1])))
  669.     mask.blit(rmask,target=(mask.size[0]-hx,mask.size[1]-hy),source=((hx,hy),rmask.size))
  670.     return mask
  671.  
  672.  
  673. def get_filename(value=u'',note=u'input the name'):
  674.     rt=appuifw.query(note,'text',value)
  675.     if rt in (None,u''):return None
  676.     chars=u'<>/\|"*?:'
  677.     for x in rt:
  678.         if x in chars:
  679.             appuifw.note(u'name can\'t contain this chars :\n%s'%chars,'error')
  680.             return None
  681.     return rt
  682.  
  683.  
  684. def multi_select(obj,ft=None):
  685.     if len(obj.ls)==0:return None
  686.     config=obj.config()
  687.     if callable(ft)==0:
  688.         selection=multi_selection_handler(obj.ls,u"multi select",**config)
  689.     else:
  690.         ks=list()
  691.         ls=list()
  692.         for x in xrange(len(obj.ls)):
  693.             if ft(obj.ls[x]):
  694.                 ks.append(x)
  695.                 ls.append(obj.ls[x])
  696.         selection=multi_selection_handler(ls,u"multi select",**config)
  697.         if selection!=None:
  698.             selection=tuple([ks[x] for x in selection])
  699.         del ks
  700.         del ls
  701.     return selection
  702.  
  703. def get_fg(obj):
  704.     if len(obj.ls)==0:
  705.         obj.ls=[u'']
  706.         obj.bp=[0]
  707.         obj.focus=obj.focus1=0
  708.         return 0
  709.     elif obj.focus==None:
  710.         obj.focus=obj.focus1=0
  711.         return 0
  712.     elif obj.focus>=len(obj.ls):
  713.         obj.focus=len(obj.ls)-1
  714.         obj.focus1=0
  715.         return obj.focus
  716.     elif obj.focus1==None:
  717.         obj.focus1=0
  718.         return obj.focus
  719.     else:
  720.         maxFocus1=min(obj.lines-1,len(obj.ls)-obj.focus-1)
  721.         if obj.focus1>=maxFocus1:obj.focus1=maxFocus1
  722.         if obj.focus1<0:obj.focus1=0
  723.         return obj.focus+obj.focus1
  724. def get_fg_text(obj):
  725.     fg=get_fg(obj)
  726.     if fg==None:return None
  727.     return obj.ls[fg]
  728. def insert_fg(obj,tx):
  729.     fg=get_fg(obj)
  730.     if fg==None:fg=0
  731.     if type(obj.ls) is not list:obj.ls=list(obj)
  732.     obj.ls.insert(fg,tx)
  733.     force_refresh(obj)
  734.  
  735. def add_fg(obj,tx):
  736.     fg=get_fg(obj)
  737.     if fg==None:fg=0
  738.     if type(obj.ls) is not list:obj.ls=list(obj)
  739.     try:
  740.         obj.ls.insert(fg+1,tx)
  741.     except:
  742.         obj.ls.insert(fg,tx)
  743.     force_refresh(obj)
  744.     obj.page_control('linedown')
  745. def set_fg(obj,tx):
  746.     fg=get_fg(obj)
  747.     if fg==None:fg=0
  748.     if type(obj.ls) is not list:obj.ls=list(obj)
  749.     obj.ls[fg]=tx
  750.     force_refresh(obj)
  751. def del_fg(obj):
  752.     fg=get_fg(obj)
  753.     if fg==None:return 0
  754.     if type(obj.ls) is not list:obj.ls=list(obj)
  755.     del obj.ls[fg]
  756.     force_refresh(obj)
  757.     obj.page_control('focusup')
  758. def force_refresh(obj,title=1):
  759.     fg=get_fg(obj)
  760.     if title:obj.changed['title']=1
  761.     obj.changed['main']=1
  762.     obj.changed['focus']=None
  763.     obj.changed['focus1']=None
  764.     obj.redraw(None)
  765.  
  766. def image_base64(img,ty='png'):
  767.     if type(img) in (unicode,str):
  768.         if img.lower().endswith('jpg') or img.lower().endswith('jpeg'):ty='jpg'
  769.         else:ty='jpg'
  770.         temp_path=img
  771.         data=open(temp_path,'rb').read()
  772.     else:
  773.         temp_path=tempfile.mktemp('.%s'%ty)
  774.         img.save(temp_path)
  775.         data=open(temp_path,'rb').read()
  776.         os.remove(temp_path)
  777.     return '''data:image/%s;base64,%s'''%(ty,base64.encodestring(data))
  778.  
  779.  
  780. def list_select(self,ls,title,callback=None,init=None,background=0xeee4aa,top=0,show_lines=1,font=('normal',24),header_font=('normal',24),mode='select',search_control=None,appmenu=[],multiline=0,left=2,bp=[],left_draw=None,search_select='select',line_draw=None,focus=0,focus1=0):
  781.     def page_control(self,way,ty=None):
  782.         last=(self.focus,self.focus1)
  783.         l=len(self.ls)
  784.         lines=self.lines
  785.         self.this_line[1]=0
  786.         #self.dtimer.cancel()
  787.         if self.scrolling==3:return page_auto_scroll(self)
  788.         self.scrolling=0
  789.         if way=='lineup':
  790.             self.focus1+=-1
  791.             if self.focus1<0:self.focus+=-1
  792.             if self.focus<0:self.focus=len(self.ls)-1
  793.         if way=='scroll':
  794.             yamount=(self.drag_log[-1][1]-self.drag_log[0][1])/self.font[1]
  795.             if self.changed['scroll']==None:
  796.                 self.changed['scroll']=self.focus
  797.                 self.scrolling=5
  798.                 self.changed['scrolling']=time.time()
  799.             self.focus=self.changed['scroll']-yamount
  800.             speed=-yamount*(time.time()-self.changed['scrolling'])
  801.             if speed<-self.lines:speed=-self.lines
  802.             if speed>self.lines:speed=self.lines
  803.             if abs(yamount)>self.lines*4/10:
  804.                 self.changed['speed']=speed
  805.  
  806.         elif way=='focusup':self.focus+=-1
  807.         elif way=='focusdown':self.focus+=1
  808.         elif way=='linedown':
  809.             self.focus1+=1
  810.             fg=min(l-self.focus-1,self.lines-1)
  811.             if self.focus1>fg:self.focus+=1
  812.             if self.focus>=len(self.ls):self.focus=0
  813.         elif way=='pageup':self.focus+=-lines
  814.         elif way=='pagedown':self.focus+=lines
  815.         if self.focus>=l-1:self.focus=l-1
  816.         if self.focus<0:self.focus=0
  817.         fg=min(l-self.focus-1,self.lines-1)
  818.         if self.focus1>=fg:self.focus1=fg
  819.         if self.focus1<0:self.focus1=0
  820.         self.changed['focus']=last[0]
  821.         self.changed['focus1']=last[1]
  822.         if last!=(self.focus,self.focus1) or self.changed['main']:
  823.             self.changed['main']=1    
  824.             if (self.focus!=last[0] or self.focus1!=last[1]) and self.focus!=None and self.focus1!=None:
  825.                 if len(self.bp)==0:
  826.                     try:appuifw.app.title=u'%s/%s'%(self.focus+self.focus1+1,len(self.ls))
  827.                     except:pass
  828.                 else:
  829.                     try:appuifw.app.title=u'%s/%s'%(self.bp[self.focus+self.focus1]+1,self.bp[-1]+1)
  830.                     except:pass
  831.         self.redraw(None)
  832.         if self.focus!=last[0]:
  833.             self.dtimer.cancel()
  834.             self.scrolling=0
  835.         if self.scrolling!=3 and self.main.measure_text(self.this_line[0],self.font)[0][2]+self.left>=self.main.size[0]:
  836.             self.dtimer.cancel()
  837.             self.scrolling=1
  838.             self.dtimer.after(0.7,lambda:line_auto_scroll(self))  
  839.         if way=='select':
  840.             try:selected(self,self.focus+self.focus1)
  841.             except:pass
  842.    
  843.    
  844.     def search_handler(self):
  845.         qr=9
  846.         key=None
  847.         #if callable(self.search_control):return self.search_control(self)
  848.         if len(self.search[1])>0:
  849.             tx=u'%s(%s/%s)'%(self.search[2],self.search[0]+1,len(self.search[1]))
  850.             if len(self.bp)==0:qr=appuifw.popup_menu([u'next',u'previous',u'new search'],tx)
  851.             else:
  852.                 qr=appuifw.popup_menu([u'next',u'previous',u'new search',u'replace'],tx)
  853.             if qr==None:return 0
  854.             elif qr==0:self.search[0]+=1
  855.             elif qr==1:self.search[0]+=-1
  856.             l=len(self.search[1])
  857.             if self.search[0]>=l:self.search[0]=0
  858.             if self.search[0]<0:self.search[0]=l-1
  859.             if qr in (0,1):
  860.                 self.focus=self.search[1][self.search[0]]
  861.                 self.focus1=0
  862.         if qr==9 and len(self.bp)>0:
  863.             qr=appuifw.popup_menu([u'new search',u'replace'],u'next step')
  864.             if qr==0:qr=2
  865.             elif qr==1:qr=3
  866.         elif len(self.bp)==0 and qr==9:qr=2
  867.         if qr==3:
  868.             f=get_replace(**self.config())
  869.             if f==None:return 0
  870.             else:
  871.                 try:
  872.                     self.ls,self.bp=break_text((
  873.                     f(u''.join(self.ls))
  874.                     ).splitlines(),self.main.size[0]-1-self.left-self.bar_size,self.font,1)
  875.                 except:pass
  876.             del f    
  877.                
  878.         elif qr==2:
  879.             sfilter=get_filter(title=u'search',font=self.font,background=self.bg,top=self.top)
  880.             if sfilter==None:return 0
  881.             if len(self.ls)==0 and self.search[0]==[]:
  882.                 self.search=[0,[],'']
  883.                 return 0
  884.             self.search[1]=list()
  885.             self.search[2]=u'search'
  886.             ls=[]
  887.             if self.bp==[]:target=self.ls
  888.             else:target=''.join(self.ls).split(u'\n')
  889.            
  890.             for x in xrange(len(target)):
  891.                 if sfilter(target[x]):
  892.                     if self.bp==[]:
  893.                         ls.append(target[x])
  894.                         self.search[1].append(x)
  895.                    
  896.                     else:
  897.                         ls.append(target[x])
  898.                         self.search[1].append(self.bp.index(x,x))
  899.             selection=None
  900.             if len(self.search[1])>0:
  901.                 if self.bp==[]:ls=map(lambda x:target[x],self.search[1])
  902.                 title=u'search'
  903.                 config=self.config()
  904.                 config['show_lines']=1
  905.                 if callable(self.left_draw):
  906.                     fun=lambda son,pos,img:self.left_draw(son,self.search[1][pos],img)
  907.                     def init(son,self=self):
  908.                         son.marked=self.marked
  909.                         son.form=self.form
  910.                     config['left_draw']=fun
  911.                     config['init']=init
  912.                 if callable(self.line_draw):
  913.                     fun1=lambda son,pos,img:self.left_draw(son,self.search[1][pos],img)
  914.                     def init1(son,self=self):
  915.                         son.marked=self.marked
  916.                         son.form=self.form
  917.                     config['line_draw']=fun1
  918.                     config['init']=init1
  919.                 selection=selection_handler(ls,title,**config)
  920.             if selection!=None:
  921.                 self.focus=self.search[1][selection]
  922.                 self.search[0]=selection
  923.                 if self.search_select=='select':
  924.                     self.focus1=0
  925.                     return selected(self,self.focus)
  926.             else:
  927.                 if len(self.search[1])==0:appuifw.note(u'no match result')
  928.         if len(self.bp)==0:
  929.             try:appuifw.app.title=u'%s/%s'%(self.focus+self.focus1+1,len(self.ls))
  930.             except:pass
  931.         else:
  932.             try:appuifw.app.title=u'%s/%s'%(self.bp[self.focus+self.focus1]+1,self.bp[-1]+1)
  933.             except:pass
  934.         force_refresh(self)
  935.     self.len=len(ls)
  936.     self.focus=focus
  937.     self.left_draw=left_draw
  938.     if left=='font':left=font[1]
  939.     self.left=left
  940.     self.bp=bp
  941.     self.page_control=lambda *arg,**kw:page_control(self,*arg,**kw)
  942.     self.line_draw=line_draw
  943.     self.multiline=multiline
  944.     self.focus1=focus1
  945.     self.form=[]
  946.     self.search_select=search_select
  947.     self.callback=callback
  948.     self.init=init
  949.     self.lastFg=None
  950.     self.fgHook=None
  951.     self.marked=[]
  952.     if callable(search_control):self.search_control=lambda:search_control(self)
  953.     else:self.search_control=lambda:search_handler(self)
  954.     self.selected=None
  955.     self.mode=mode
  956.     self.bg=background
  957.     self.top=top
  958.     self.contentType='list'
  959.     newmenu=list()
  960.     self.config=lambda:{'show_lines':self.show_lines,'font':self.font,'background':self.bg,'top':self.top,'left':self.left}
  961.     self.content=lambda:{'ls':''.join(self.ls),'title':self.title,'focus':self.focus,'focus1':self.focus1}
  962.     self.wrap=lambda:{'show_lines':self.show_lines,'font':self.font,'background':self.bg,'top':self.top,'left':self.left,'ls':ls,'title':self.title,'bp':self.bp}
  963.     #
  964.     if len(appmenu)>0:
  965.         init=lambda x:(x[0],lambda:x[1](self))
  966.         for x in appmenu:
  967.             if type(x[1]) is tuple:m=(x[0],tuple(map(init,x[1])))
  968.             else:m=init(x)
  969.             newmenu.append(m)
  970.     self.appmenu=newmenu
  971.     self.show_lines=show_lines
  972.     self.mid=mid_color(self.bg,self.top)
  973.     self.font=(font[0],max((font[1],9)))
  974.     self.header_font=('normal',min((24,font[1])))
  975.     self.changed={'menu':1,'title':1,'main':1,'focus':None,'focus1':None,'main_mask':1,'main_top':1,'scroll':None,'scrolling':0,'speed':0}
  976.     self.img.clear(self.bg)
  977.     self.title=title
  978.     self.left_zone=Image.new((self.left,self.font[1]))
  979.    
  980.     self.header=color_fill((self.img.size[0],self.header_font[1]),(self.mid,self.mid,1))
  981.     #self.header.text((5,self.header_font[1]-1),self.title,self.bg,self.header_font)
  982.     global logo
  983.     self.logo=Image.new((self.header_font[1],self.header_font[1]))
  984.     self.logo.clear(self.mid)
  985.     self.logo.blit(logo[0].resize(self.logo.size),mask=logo[1].resize(self.logo.size))
  986.     self.ls=ls
  987.     self.search=[0,[],'']
  988.     self.img.blit(self.header)
  989.     self.bmenu=Image.new((self.img.size[0],min(32,self.img.size[1]/10)))
  990.     self.mfocus=None
  991.     bar_size=max(12,min(8,font[1]/2))
  992.     self.bar_size=bar_size
  993.     self.scroll_bar=color_fill((bar_size,self.img.size[1]-self.header_font[1]-self.bmenu.size[1]-bar_size*2),(self.bg,self.mid,1))
  994.     self.scroll_tap=color_fill((bar_size,bar_size/2),(self.top,self.mid,0))
  995.     self.main=Image.new((self.img.size[0]-bar_size,self.img.size[1]-self.bmenu.size[1]-self.header_font[1]),mode='RGB')
  996.     self.p_temp=Image.new(self.main.size,mode='RGB')
  997.     self.line_zone=Image.new((self.main.size[0]-self.left,self.font[1]))
  998.     self.lines=self.main.size[1]/self.font[1]
  999.     self.main.clear(self.bg)
  1000.     self.lastkey=(None,None)
  1001.     self.lastclick=(None,None,time.time())
  1002.     self.drag_log=list()
  1003.     self.drag_temp=list()
  1004.     self.dtimer=e32.Ao_timer()
  1005.     self.main_mask=Image.new(self.main.size,mode='1')
  1006.     self.main_top=Image.new(self.main.size)
  1007.     self.main_top.clear(self.top)
  1008.     self.main_mask.clear(0)
  1009.     self.line_mask=Image.new((self.main.size[0]-self.left,self.font[1]),mode='1')
  1010.     self.line_top=Image.new(self.line_mask.size)
  1011.     self.line_bottom=Image.new(self.line_mask.size)
  1012.     self.line_top.clear(self.top)
  1013.     self.line_bottom.clear(self.bg)
  1014.     self.line_mask.clear(0)    
  1015.     self.ttimer=e32.Ao_timer()
  1016.     self.this_page=[[],None,None]
  1017.     self.this_line=[u'',0]
  1018.     self.scrolling=0
  1019.     self.focus3=0
  1020.     self.last_page=None
  1021.     list_select_control(self)
  1022.    
  1023.  
  1024. #def list_select_control(self):
  1025.     def quit(self):
  1026.         self.ttimer.cancel()
  1027.         self.dtimer.cancel()
  1028.         self.hide()
  1029.     self.quit=lambda:quit(self)
  1030.     def search_handler(self):
  1031.         qr=9
  1032.         key=None
  1033.         #if callable(self.search_control):return self.search_control(self)
  1034.         if len(self.search[1])>0:
  1035.             tx=u'%s(%s/%s)'%(self.search[2],self.search[0]+1,len(self.search[1]))
  1036.             if len(self.bp)==0:qr=appuifw.popup_menu([u'next',u'previous',u'new search'],tx)
  1037.             else:
  1038.                 qr=appuifw.popup_menu([u'next',u'previous',u'new search',u'replace'],tx)
  1039.             if qr==None:return 0
  1040.             elif qr==0:self.search[0]+=1
  1041.             elif qr==1:self.search[0]+=-1
  1042.             l=len(self.search[1])
  1043.             if self.search[0]>=l:self.search[0]=0
  1044.             if self.search[0]<0:self.search[0]=l-1
  1045.             if qr in (0,1):
  1046.                 self.focus=self.search[1][self.search[0]]
  1047.                 self.focus1=0
  1048.         if qr==9 and len(self.bp)>0:
  1049.             qr=appuifw.popup_menu([u'new search',u'replace'],u'next step')
  1050.             if qr==0:qr=2
  1051.             elif qr==1:qr=3
  1052.         elif len(self.bp)==0 and qr==9:qr=2
  1053.         if qr==3:
  1054.             f=get_replace(**self.config())
  1055.             if f==None:return 0
  1056.             else:
  1057.                 try:
  1058.                     self.ls,self.bp=break_text((
  1059.                     f(u''.join(self.ls))
  1060.                     ).splitlines(),self.main.size[0]-1-self.left-self.bar_size,self.font,1)
  1061.                 except:pass
  1062.             del f    
  1063.                
  1064.         elif qr==2:
  1065.             sfilter=get_filter(title=u'search',font=self.font,background=self.bg,top=self.top)
  1066.             if sfilter==None:return 0
  1067.             if len(self.ls)==0 and self.search[0]==[]:
  1068.                 self.search=[0,[],'']
  1069.                 return 0
  1070.             self.search[1]=list()
  1071.             self.search[2]=u'search'
  1072.             ls=[]
  1073.             if self.bp==[]:target=self.ls
  1074.             else:target=''.join(self.ls).split(u'\n')
  1075.            
  1076.             for x in xrange(len(target)):
  1077.                 if sfilter(target[x]):
  1078.                     if self.bp==[]:
  1079.                         ls.append(target[x])
  1080.                         self.search[1].append(x)
  1081.                    
  1082.                     else:
  1083.                         ls.append(target[x])
  1084.                         self.search[1].append(self.bp.index(x,x))
  1085.             selection=None
  1086.             if len(self.search[1])>0:
  1087.                 if self.bp==[]:ls=map(lambda x:target[x],self.search[1])
  1088.                 title=u'search'
  1089.                 config=self.config()
  1090.                 config['show_lines']=1
  1091.                 if callable(self.left_draw):
  1092.                     fun=lambda son,pos,img:self.left_draw(son,self.search[1][pos],img)
  1093.                     def init(son,self=self):
  1094.                         son.marked=self.marked
  1095.                         son.form=self.form
  1096.                     config['left_draw']=fun
  1097.                     config['init']=init
  1098.                 if callable(self.line_draw):
  1099.                     fun1=lambda son,pos,img:self.left_draw(son,self.search[1][pos],img)
  1100.                     def init1(son,self=self):
  1101.                         son.marked=self.marked
  1102.                         son.form=self.form
  1103.                     config['line_draw']=fun1
  1104.                     config['init']=init1
  1105.                 selection=selection_handler(ls,title,**config)
  1106.             if selection!=None:
  1107.                 self.focus=self.search[1][selection]
  1108.                 self.search[0]=selection
  1109.                 if self.search_select=='select':
  1110.                     self.focus1=0
  1111.                     return selected(self,self.focus)
  1112.             else:
  1113.                 if len(self.search[1])==0:appuifw.note(u'no match result')
  1114.         if len(self.bp)==0:
  1115.             try:appuifw.app.title=u'%s/%s'%(self.focus+self.focus1+1,len(self.ls))
  1116.             except:pass
  1117.         else:
  1118.             try:appuifw.app.title=u'%s/%s'%(self.bp[self.focus+self.focus1]+1,self.bp[-1]+1)
  1119.             except:pass
  1120.         force_refresh(self)
  1121.     def menu_switch(self):
  1122.         if self.mfocus==None:self.mfocus=0
  1123.         else:self.mfocus=0
  1124.         self.redraw(None)
  1125.     def app_title(tx):
  1126.         try:appuifw.app.title=tx
  1127.         except:pass
  1128.     ##**#
  1129.     def selected(self,selection):
  1130.         l=len(self.ls)-1
  1131.         if len(self.ls)==0:selected=None
  1132.         elif selection>=l:selected=l
  1133.         elif selection<0:selected=0
  1134.         else:selected=selection
  1135.         if self.callback==None:
  1136.             self.selected=selected
  1137.             self.quit()
  1138.         else:
  1139.             self.callback(self,selected)
  1140.     def event(self,ev):
  1141.         if ev.has_key('scancode'):key_control(self,ev)
  1142.         elif ev.has_key('pos'):touch_control(self,ev)
  1143.         if callable(self.fgHook):
  1144.             fg=get_fg(self)
  1145.             if self.lastFg!=fg:self.fgHook(self)
  1146.             self.lastFg=fg
  1147.     def click_handler(self,pos):
  1148.         is_click=(len(self.drag_log)==1 and pos==self.drag_log[0])
  1149.         is_drag=(is_click==0)
  1150.         in_main=(self.header_font[1]<=pos[1]<self.header_font[1]+self.font[1]*min(self.lines,len(self.ls)-self.focus))
  1151.         in_scroll=(self.img.size[0]-self.bar_size*2<=pos[0]<self.img.size[0] and self.header_font[1]<=pos[1]<self.img.size[1]-self.bmenu.size[1])
  1152.         in_main2=(self.header_font[1]<=pos[1]<self.header_font[1]+self.main.size[1] and in_scroll==0)
  1153.         in_menu=(0<=pos[0]<self.img.size[0] and self.img.size[1]-self.bmenu.size[1]<=pos[1]<self.img.size[1])
  1154.         self.drag_log=[]
  1155.     def drag_record(self,pos,case=0):
  1156.         try:
  1157.             if self.drag_log[-1]==pos:pass
  1158.             elif len(self.drag_log)==1:self.drag_log.append(pos)
  1159.             elif len(self.drag_log)>1 and in_line(self.drag_log[-2],self.drag_log[-1],pos):self.drag_log[-1]=pos
  1160.             else:self.drag_log.append(pos)
  1161.         except:self.drag_log.append(pos)
  1162.     def touch_control(self,ev):
  1163.         last=(self.focus,self.focus1)
  1164.         #last=(self.changed['focus'],self.changed['focus1'])
  1165.         pos,ty=(ev['pos'],ev['type'])
  1166.         in_main=(self.header_font[1]<=pos[1]<self.header_font[1]+self.font[1]*min(self.lines,len(self.ls)-self.focus))
  1167.         in_scroll=(self.img.size[0]-self.bar_size*2<=pos[0]<self.img.size[0] and self.header_font[1]<=pos[1]<self.img.size[1]-self.bmenu.size[1])
  1168.         in_main2=(self.header_font[1]<=pos[1]<self.header_font[1]+self.main.size[1] and in_scroll==0)
  1169.         in_menu=(0<=pos[0]<self.img.size[0] and self.img.size[1]-self.bmenu.size[1]<=pos[1]<self.img.size[1])
  1170.         if in_main and ty==257 and in_scroll==0:
  1171.             fg=(pos[1]-self.header_font[1])/self.font[1]
  1172.             t=time.time()
  1173.             self.focus1=fg
  1174.             if self.scrolling in (0,1) and fg==self.lastclick[0] and t-self.lastclick[2]<2:
  1175.                 self.page_control('select')
  1176.             self.lastclick=(fg,None,t)
  1177.             #if self.scrolling not in  (0,1):self.lastclick=(fg,None,0)
  1178.             self.changed['focus1']=None
  1179.            
  1180.         elif in_scroll and len(self.ls)>0:
  1181.             if pos[1]<self.bar_size+self.header_font[1]:self.focus=self.focus1
  1182.             elif self.img.size[1]-self.bmenu.size[1]>pos[1]>=self.header_font[1]+self.bar_size+self.scroll_bar.size[1]:self.focus=len(self.ls)-1
  1183.             else:
  1184.                 fg=int(float(pos[1]-self.header_font[1]-self.bar_size)/self.scroll_bar.size[1]*len(self.ls))
  1185.                 self.focus=fg
  1186.            
  1187.         elif in_main2 and ty!=257:
  1188.             drag_record(self,pos)
  1189.             yamount=(self.drag_log[-1][1]-self.drag_log[0][1])/self.font[1]
  1190.             if yamount!=0:self.page_control('scroll')
  1191.         elif in_menu and ty==257:
  1192.             ml=float(len(self.menu_callback))
  1193.             mfocus=int(pos[0]/(self.img.size[0]/int(ml)))
  1194.             mfocus0=(pos[0]/(self.img.size[0]/ml))-mfocus
  1195.             if 0<=mfocus<len(self.menu_callback):self.menu_callback[mfocus]()
  1196.        
  1197.  
  1198.         if self.scrolling==3 and ty==257:
  1199.             self.scrolling=0
  1200.             self.changed['speed']=0
  1201.             self.changed['scrolling']=0
  1202.             self.changed['scroll']=None
  1203.             self.changed['main']=1
  1204.             self.changed['focus1']=None
  1205.            
  1206.         if ty==258:
  1207.             self.changed['main']=1
  1208.             self.changed['focus1']=None
  1209.             self.redraw(None)
  1210.         if self.changed['speed']!=0 and ty==2580:
  1211.                 self.scrolling=3
  1212.                 self.changed['scroll']=self.focus
  1213.                 self.changed['scrolling']=time.time()
  1214.                 return page_auto_scroll(self)
  1215.         if ty==257:    
  1216.             self.drag_log=[]
  1217.             self.drag_temp=[]
  1218.             self.scrolling=0
  1219.             self.changed['scroll']=None
  1220.             self.changed['scrolling']=0
  1221.             self.changed['speed']=0            
  1222.             self.page_control('')
  1223.  
  1224.         if last!=(self.focus,self.focus1):
  1225.             self.changed['main']=1
  1226.             self.changed['focus'],self.changed['focus1']=last
  1227.             if len(self.bp)==0:
  1228.                 try:appuifw.app.title=u'%s/%s'%(self.focus+self.focus1+1,len(self.ls))
  1229.                 except:pass
  1230.             else:
  1231.                 try:
  1232.                     appuifw.app.title=u'%s/%s'%(self.bp[self.focus+self.focus1]+1,self.bp[-1]+1)
  1233.                 except:pass
  1234.             self.redraw(None)
  1235.             self.page_control('')      
  1236.  
  1237.     def key_control(self,ev):
  1238.         ty,key=(ev['type'],ev['scancode'])
  1239.         if not self.mouseEnabled:return 0
  1240.         if key==EScancodeSelect:
  1241.             if ty==1:t=257
  1242.             elif ty==2:t=258
  1243.             elif ty==3:return 0
  1244.             return touch_control(self,dict(type=t,pos=(self.mouseX,self.mouseY)))
  1245.         elif key==EScancodeDownArrow and ty==1 and self.mouseY>=self.canvas.size[1]-1:
  1246.             return page_control(self,'linedown')
  1247.         elif key==EScancodeUpArrow and ty==1 and self.mouseY<=0:
  1248.             return page_control(self,'lineup')
  1249.         elif key==EScancodeLeftArrow and ty==1 and self.mouseX<=0:
  1250.             return page_control(self,'focusdown')
  1251.         elif key==EScancodeRightArrow and ty==1 and self.mouseX>=self.canvas.size[0]-1:
  1252.             return page_control(self,'focusup')
  1253.         elif ty==2 and 49<=key<58:
  1254.             fg=key-49
  1255.             try:self.menu_callback[fg]()
  1256.             except:pass
  1257.             return 0
  1258.         else:return 0
  1259.         if ty==2:
  1260.             self.scrolling=0
  1261.             self.changed['main']=1
  1262.             self.changed['focus1']=None
  1263.             self.redraw(None)
  1264.         if self.lastkey==(None,None):
  1265.             if ty==2:self.lastkey=(key,ty)
  1266.         elif ty==1 and key==EScancodeUpArrow:
  1267.             self.page_control('lineup')
  1268.         elif ty==1 and key==EScancodeDownArrow:
  1269.             self.page_control('linedown')
  1270.         elif ty==2 and key==EScancodeLeftArrow:
  1271.             if self.mfocus==None:self.page_control('pageup')
  1272.             else:
  1273.                 self.mfocus+=-1
  1274.                 if self.mfocus<0:self.mfocus=len(self.menu_callback)-1
  1275.                 if self.mfocus>=len(self.menu_callback):self.mfocus=0
  1276.                 self.redraw(None)
  1277.         elif ty==2 and key==EScancodeRightArrow:
  1278.             if self.mfocus==None:self.page_control('pagedown')
  1279.             else:
  1280.                 self.mfocus+=1
  1281.                 if self.mfocus<0:self.mfocus=len(self.menu_callback)-1
  1282.                 if self.mfocus>=len(self.menu_callback):self.mfocus=0
  1283.                 self.redraw(None)
  1284.         elif key==EScancodeSelect:
  1285.             if self.lastkey[0]==key and self.lastkey[1]==1 and ty==2:
  1286.                 if self.mfocus==None or len(self.menu_callback)==0:pass
  1287.                 elif 0<=self.mfocus<len(self.menu_callback):self.menu_callback[self.mfocus]()
  1288.             self.lastkey=(key,ty)
  1289.             if ty==2:
  1290.                 self.changed['main']=1
  1291.                 self.changed['focus1']=None
  1292.                 self.page_control('')
  1293.        
  1294.     def page_auto_scroll(self):
  1295.         self.dtimer.cancel()
  1296.         if len(self.bp)>0:
  1297.             self.scrolling=0
  1298.             return 0
  1299.         self.scrolling=3
  1300.        
  1301.         if self.changed['speed']!=0:
  1302.             last=self.focus
  1303.             last1=self.focus1
  1304.             self.focus=int(self.changed['scroll']+(time.time()-self.changed['scrolling'])*self.changed['speed'])
  1305.             l=len(self.ls)
  1306.             if self.focus>=l-1:self.focus=l-1
  1307.             if self.focus<0:self.focus=0
  1308.             fg=min(l-self.focus-1,self.lines-1)
  1309.             if self.focus1>=fg:self.focus1=fg
  1310.             if self.focus1<0:self.focus1=0
  1311.             self.changed['focus']=last
  1312.             self.changed['focus1']=self.focus1
  1313.             if last!=self.focus:
  1314.                 self.changed['main']=1
  1315.                 self.redraw(None)
  1316.             self.dtimer.after(0.05,lambda:page_auto_scroll(self))
  1317.             if (self.focus==0 and self.changed['speed']<0) or (self.focus==len(self.ls)-1 and self.changed['speed']>0):
  1318.                 self.dtimer.cancel()
  1319.                 self.scrolling=0
  1320.                 self.changed['scroll']=None
  1321.                 self.changed['speed']=0
  1322.                
  1323.     def line_auto_scroll(self):
  1324.         self.ttimer.cancel()
  1325.         if self.scrolling==3:return page_auto_scroll(self)
  1326.         if len(self.this_line)==2:
  1327.             self.this_line.append(Image.new((self.main.size[0]-self.left,self.font[1])))
  1328.             self.this_line.append(time.time())
  1329.         max_chars=self.main.size[0]*3/self.font[1]
  1330.         self.this_line[2].clear(self.top)
  1331.         t0=self.this_line[3]
  1332.         t1=time.time()
  1333.         t2=t1-t0
  1334.         pos=(0,self.focus1*self.font[1]-1)
  1335.         self.this_line[1]+=t2*5
  1336.         if len(self.this_line[0])-self.this_line[1]>2:
  1337.             tx=self.this_line[0][int(self.this_line[1]):]
  1338.             tx+=u'  ---  '+self.this_line[0]
  1339.         else:
  1340.             self.this_line[1]=0
  1341.             tx=self.this_line[0]
  1342.         tpos=((int(self.this_line[1])-self.this_line[1]+1)*self.font[1],self.font[1]-1)
  1343.         if tpos[0]>=1:tpos=(0,self.font[1]-1)
  1344.         self.this_line[2].text(tpos,tx[:max_chars],self.bg,self.font)
  1345.         self.img.blit(self.this_line[2],target=(self.left,pos[1]+self.header_font[1]))
  1346.         self.this_line[3]=time.time()
  1347.         self.dtimer.cancel()
  1348.         self.dtimer.after(1.0/30,lambda:self.redraw(None))
  1349.         self.scrolling=1
  1350.     def page_redraw(self,force=0):
  1351.         fg=get_fg(self)
  1352.         if self.changed['main']==0 and self.focus==self.changed['focus'] and self.changed['focus1']==self.focus1 and force==0 and self.changed['focus']!=None:return 0
  1353.         max_chars=self.main.size[0]*5/self.font[1]
  1354.         if (self.multiline==0 and len(self.ls)>0):
  1355.             low,hi=self.focus,min(self.focus+self.lines,len(self.ls))
  1356.             t=self.ls[fg]
  1357.             if t.endswith('\n'):t=t[:-1]
  1358.             if t.endswith('\r'):t=t[:-1]
  1359.             t=t.translate(editor_dict)
  1360.             self.this_line[0]=t
  1361.             if 1 or self.changed['focus']!=self.focus or self.changed['focus']==None:
  1362.                 self.main.clear(self.bg)
  1363.                 draw_map=xrange(low,hi)
  1364.                 for y in draw_map:
  1365.                     x=y-low
  1366.                     pos=(self.left,(x+1)*self.font[1]-1)
  1367.                     t=u'%s'%self.ls[y]
  1368.                     if t.endswith('\n'):t=t[:-1]
  1369.                     if t.endswith('\r'):t=t[:-1]
  1370.                     t=t.translate(editor_dict)              
  1371.                     if callable(self.line_draw):
  1372.                         self.line_zone=self.line_draw(self,self.focus+x,self.line_zone)
  1373.                         self.main.blit(self.line_zone,target=(self.left,pos[1]-self.font[1]+1))
  1374.                     else:self.main.text(pos,t[:max_chars],self.top,self.font)
  1375.                    
  1376.                     if callable(self.left_draw):
  1377.                         try:
  1378.                             self.left_zone=self.left_draw(self,self.focus+x,self.left_zone)
  1379.                         except:self.left_zone.clear(self.top)
  1380.                         self.main.blit(self.left_zone,target=(0,pos[1]-self.font[1]+1))
  1381.                     if self.bp!=[]:
  1382.                         try:
  1383.                             line0=self.bp[fg]
  1384.                             line1=self.bp[self.focus+x]
  1385.                             if line0==line1:self.main.line((0,pos[1],self.main.size[0],pos[1]),self.mid,width=1)
  1386.                         except:pass
  1387.                     elif self.show_lines:self.main.line((0,pos[1],self.main.size[0],pos[1]),self.mid,width=1)
  1388.                     self.changed['focus']=self.focus
  1389.         else:self.this_line[0]=u''
  1390.         if len(self.ls)==0:self.main.clear(self.bg)
  1391.         self.img.blit(self.main,target=(0,self.header_font[1]))
  1392.         if (self.mode=='select' and len(self.ls)>0 and self.scrolling==0) and not callable(self.line_draw):
  1393.             pos=(self.left,self.font[1]*self.focus1+self.header_font[1])
  1394.             self.line_top.clear(self.top)
  1395.             self.line_top.text((0,self.font[1]-1),self.this_line[0][:max_chars],self.bg,self.font)
  1396.             self.img.blit(self.line_top,target=pos)
  1397.             self.changed['focus1']=self.focus1
  1398.         self.changed['main']=0
  1399.     def set_title(self,title=None):
  1400.         if title==None:title=self.title
  1401.         self.title=u'%s'%title
  1402.         self.changed['title']=1
  1403.         self.redraw(None)
  1404.     def img_redraw(self):
  1405.         if self.changed['title']:
  1406.             self.header.clear(self.mid)
  1407.             self.header.blit(self.logo)
  1408.             self.header.text((self.header_font[1]+5,self.header_font[1]-1),self.title,self.bg,self.header_font)
  1409.             self.img.blit(self.header)
  1410.             self.changed['title']=0
  1411.             self.img.blit(self.scroll_bar,target=(self.main.size[0],self.header_font[1]+self.font[1]/2))
  1412.         if self.changed['menu']:
  1413.             self.draw_menu()
  1414.             self.img.blit(self.bmenu,target=(0,self.img.size[1]-self.bmenu.size[1]))
  1415.             self.changed['menu']=0
  1416.     def redraw(self,rect):
  1417.         if self.scrolling in (0,3,5):page_redraw(self)
  1418.         #if self.scrolling==3:page_auto_scroll(self)
  1419.         img_redraw(self)
  1420.         self.canvas.blit(self.img)
  1421.         if self.scrolling==1 and not callable(self.line_draw):line_auto_scroll(self)
  1422.         if len(self.ls)>0:
  1423.             self.canvas.blit(self.scroll_tap,target=(self.main.size[0],self.header_font[1]+self.bar_size/2+(self.focus+0.0)/len(self.ls)*(self.main.size[1]-self.bar_size*3/2)))
  1424.         if self.mfocus!=None:
  1425.             l=float(len(self.menu_callback))
  1426.             self.canvas.rectangle((self.mfocus*self.img.size[0]/l,self.img.size[1]-self.bmenu.size[1],(self.mfocus+1)*self.img.size[0]/l,self.img.size[1]),self.top,width=self.bmenu.size[1]*2/10)
  1427.     self.event_callback=event
  1428.     self.redraw_callback=redraw
  1429.     menuDefault(self)
  1430.     if callable(self.init):self.init(self)
  1431.     self.setTitle=lambda title:set_title(self,title)
  1432.     self.imenu=self.appmenu
  1433.     appuifw.app.menu=self.appmenu
  1434.     self.mouseX=15
  1435.     self.mouseY=self.font[1]+self.font[1]/2
  1436.     self.redraw(None)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement