Commit before breaking everything
[matches/honours.git] / research / transmission_spectroscopy / simulator / pgu-0.18 / scripts / tileedit
diff --git a/research/transmission_spectroscopy/simulator/pgu-0.18/scripts/tileedit b/research/transmission_spectroscopy/simulator/pgu-0.18/scripts/tileedit
new file mode 100644 (file)
index 0000000..6d3e367
--- /dev/null
@@ -0,0 +1,1121 @@
+#!/usr/bin/python
+"""<title>a simple tile editor for pygame</title>
+<pre>
+
+usage: tileedit tiles.tga [tile_w] [tile_h]
+windows: python tileedit tiles.tga [tile_w] [tile_h]
+
+options:
+  -h, --help            show this help message and exit
+  --sw=SCREEN_W         screen width (app)
+  --sh=SCREEN_H         screen height (app)
+  --tw=TILE_W           tile width (image)
+  --th=TILE_H           tile height (image)
+  --width=WIDTH         new width (image)
+  --height=HEIGHT       new height (image)
+  -pPALETTE, --pal=PALETTE
+                        filename of palette (image)
+  -d, --defaults        set default settings (image)
+
+example:
+tileedit tiles.tga 16 16
+
+note:
+the editor can only edit tga files.
+
+you may edit default options in tileedit.ini
+
+interface:
+- menus for common commands
+- toolbox
+- tile edit area
+    left click to use current tool
+    right click to select color
+- tile select area
+    left click to select a tile
+    right click to select any region
+- color select area
+    click to select a color
+
+keys:
+s - save
+d - reload
+
+z - undo
+x - cut selection
+c - copy selection
+v - paste clipboard
+delete - delete selection
+f - fill selection
+e - draw ellipse in selection
+a - select all
+
+[ - rotate -90
+] - rotate +90
+, - flip horizontal
+. - flip vertical
+
+arrows - change tile
+F10 - toggle fullscreen
+</pre>
+"""
+
+import os,sys    
+from optparse import OptionParser
+from ConfigParser import ConfigParser
+import pygame
+from pygame.locals import *
+
+# try:
+#     import Image
+#     have_pil=True
+# except:
+#     print "import Image failure; PIL not found."
+#     have_pil=False
+
+have_pil = False
+
+# the following line is not needed if pgl is installed
+import sys; sys.path.insert(0, "..")
+import shutil
+
+from pgu import gui, html
+
+
+#whatever...
+ini_fname = "tileedit.ini"
+ini = ConfigParser()
+
+cfg = {}
+
+class _app(gui.Container):
+    def __init__(self):
+        gui.Container.__init__(self)
+        #self.cls = "desktop"
+        #self.background = gui.Box(self.style.background)
+        
+        self.screen_w = cfg['screen_w']
+        self.screen_h = cfg['screen_h']
+        self.screen = pygame.display.set_mode((self.screen_w,self.screen_h),SWSURFACE)
+        
+        self.fname = cfg['fname']
+
+        if self.fname != None:
+            if have_pil==True:
+
+                im = Image.open(self.fname)
+                mode = im.mode
+                size = im.size
+                data = im.tostring()
+
+                assert mode in ("RGB", "RGBA")
+
+                self.tiles = pygame.image.fromstring(data, size, mode)
+
+            else:
+                self.tiles = pygame.image.load(self.fname) # old tga-only method
+        else:
+            w,h = cfg['width'],cfg['height']
+            s = pygame.Surface((w,h),SWSURFACE|SRCALPHA,32)
+            s.fill((0,0,0,0))
+            self.tiles = s
+
+        self.tiles_w, self.tiles_h = self.tiles.get_width(),self.tiles.get_height()
+            
+        
+        self.tile_w, self.tile_h = cfg['tile_w'],cfg['tile_h'] 
+        self.tile = self.tiles.subsurface((0,0,self.tile_w,self.tile_h))
+        
+        self.color = (255,255,255,255)
+        self.mode = 'draw'
+        self.clipboard = None
+        self.select = Rect(0,0,self.tile_w,self.tile_h)
+        self.history = []
+        self.dirty = 0
+        
+    def archive(self):
+        h = self.history
+        if len(h) >= 32:
+            del h[0]
+        c = pygame.Surface((self.tile_w,self.tile_h),SWSURFACE,self.tile)
+        c.fill((0,0,0,0))
+        c.blit(self.tile,(0,0))
+        h.append((c,self.tile.get_offset()))
+        self.dirty = 1
+        
+    def undo(self):
+        if len(self.history) == 0: return
+        c,off = self.history.pop()
+        self.tiles.fill((0,0,0,0),(off[0],off[1],self.tile_w,self.tile_h))
+        self.tiles.blit(c,off)
+        self.tdraw.repaint()
+        self.tpicker.repaint()
+        self.dirty = 1
+        
+    def __setattr__(self,k,v):
+        self.__dict__[k] = v
+        
+        if k == 'color':
+            if hasattr(self,'cpreview'): self.cpreview.repaint()
+        if k == 'tile':
+            if hasattr(self,'tdraw'): self.tdraw.repaint()
+            if hasattr(self,'tpicker'): self.tpicker.repaint()
+            if hasattr(self,'tpreview'): self.tpreview.repaint()
+    def event(self,e):
+        if e.type is KEYDOWN:
+            for key,cmd,value in keys:
+                if e.key == key:
+                    cmd(value)
+                    return
+        return gui.Container.event(self,e)
+    
+class cpreview(gui.Widget):
+    def __init__(self,w,h):
+        gui.Widget.__init__(self)
+        self.style.width = w 
+        self.style.height = h
+        
+    def paint(self,s):
+        s.fill((128,128,128))
+        s.fill(app.color)
+
+        
+class cpicker(gui.Widget):
+    def __init__(self,w,h,pal):
+        gui.Widget.__init__(self)
+        self.style.width = w
+        self.style.height = h
+        self.palette = pal
+        self.palette_w = pal.get_width()
+        self.palette_h = pal.get_height()
+    
+    def paint(self,s):
+        s.blit(pygame.transform.scale(self.palette,(self.rect.w,self.rect.h)),(0,0))
+            
+    def event(self,e):
+        if (e.type is MOUSEBUTTONDOWN) or (e.type is MOUSEMOTION and e.buttons[0] == 1 and self.container.myfocus == self):
+            x,y = e.pos[0]*self.palette_w/self.rect.w,e.pos[1]*self.palette_h/self.rect.h
+            x,y = max(0,x),max(0,y)
+            x,y = min(self.palette_w-1,x),min(self.palette_h-1,y)
+        
+            app.color = self.palette.get_at((x,y))
+
+class tpicker(gui.Widget):
+    def __init__(self):
+        gui.Widget.__init__(self)
+        self.style.width = app.tiles_w
+        self.style.height = app.tiles_h
+        
+    def paint(self,s):
+        s.fill((128,128,128))
+        s.blit(app.tiles,(0,0))
+        off = app.tile.get_offset()
+        pygame.draw.rect(s,(255,255,255),(off[0],off[1],app.tile_w,app.tile_h),2)
+        
+    def pick(self,pos):
+        x,y = pos
+        while x < 0: x += self.rect.w
+        while y < 0: y += self.rect.h
+        while x >= self.rect.w: x -= self.rect.w
+        while y >= self.rect.h: y -= self.rect.h
+        app.tile = app.tiles.subsurface((x,y,app.tile_w,app.tile_h))
+
+    def event(self,e):
+        if (e.type is MOUSEBUTTONDOWN and e.button == 1) or (e.type is MOUSEMOTION and e.buttons[0] == 1 and self.container.myfocus == self):
+            x,y = e.pos[0]/app.tile_w*app.tile_w,e.pos[1]/app.tile_h*app.tile_h
+            self.pick((x,y))
+            
+        if (e.type is MOUSEBUTTONDOWN and e.button == 3) or (e.type is MOUSEMOTION and e.buttons[2] == 1 and self.container.myfocus == self):
+            x,y = e.pos[0]-app.tile_w/2,e.pos[1]-app.tile_h/2
+            x = min(self.rect.w-app.tile_w-1,max(0,x))
+            y = min(self.rect.h-app.tile_h-1,max(0,y))
+            self.pick((x,y))
+
+class tpreview(gui.Widget):
+    def __init__(self):
+        gui.Widget.__init__(self)
+        self.style.width = app.tile_w*3
+        self.style.height = app.tile_h*3
+    def paint(self, s):
+        atw = app.tile_w
+        ath = app.tile_h
+        s.fill((100,100,100))
+        s.blit(app.tile,(0,0))
+        s.blit(app.tile,(1*atw,0))
+        s.blit(app.tile,(2*atw,0))
+        s.blit(app.tile,(0,1*ath))
+        s.blit(app.tile,(1*atw,1*ath))
+        s.blit(app.tile,(2*atw,1*ath))
+        s.blit(app.tile,(0,2*ath))
+        s.blit(app.tile,(1*atw,2*ath))
+        s.blit(app.tile,(2*atw,2*ath))        
+
+class tdraw(gui.Widget):
+    def __init__(self,w,h):
+        gui.Widget.__init__(self)
+        self.rect.w = self.style.width = w
+        self.rect.h = self.style.height = h
+        self.overlay = pygame.Surface((app.tile_w,app.tile_h)).convert_alpha()
+        self.overlay.fill((0,0,0,0))
+        s = pygame.Surface((self.rect.w,self.rect.h))
+        clrs = [(148,148,148),(108,108,108)]
+        for y in range(0,app.tile_h*2):
+            for x in range(0,app.tile_w*2):
+                s.fill(clrs[(x+y)%2],(
+                    self.rect.w*x/(app.tile_w*2),
+                    self.rect.h*y/(app.tile_h*2),
+                    self.rect.w/(app.tile_w*2)+1,
+                    self.rect.h/(app.tile_h*2)+2))
+        self.bg = s
+
+        s = pygame.Surface((self.rect.w,self.rect.h)).convert_alpha()
+        s.fill((0,0,0,0))
+        for x in range(0,app.tile_w):
+            pygame.draw.line(s,(0,0,0),(self.rect.w*x/app.tile_w,0),(self.rect.w*x/app.tile_w,self.rect.h))
+        for y in range(0,app.tile_h):
+            pygame.draw.line(s,(0,0,0),(0,self.rect.h*y/app.tile_h),(self.rect.w,self.rect.h*y/app.tile_h))
+        self.grid = s
+
+        
+    def paint(self,s):
+        s.blit(self.bg,(0,0))
+        s.blit(pygame.transform.scale(app.tile,(self.rect.w,self.rect.h)),(0,0))
+        s.blit(pygame.transform.scale(self.overlay,(self.rect.w,self.rect.h)),(0,0))
+        #if app.mode == 'select':
+        s.blit(self.grid,(0,0))
+        r = app.select
+        pygame.draw.rect(s,(255,255,255,128),Rect(r.x*self.rect.w/app.tile_w,r.y*self.rect.h/app.tile_h,r.w*self.rect.w/app.tile_w,r.h*self.rect.h/app.tile_h),4)
+        
+    def event(self,e):
+        if (e.type is MOUSEBUTTONDOWN and e.button == 3) or (e.type is MOUSEMOTION and e.buttons[2]==1 and self.container.myfocus == self):
+            self.picker_down(e)
+        if e.type is MOUSEBUTTONDOWN and e.button == 1:
+            a = '%s_down'%app.mode
+            if hasattr(self,a): getattr(self,a)(e)
+        if e.type is MOUSEMOTION and e.buttons[0] and self.container.myfocus == self:
+            a = '%s_drag'%app.mode
+            if hasattr(self,a): getattr(self,a)(e)
+        if e.type is MOUSEBUTTONUP and e.button == 1:
+            a = '%s_up'%app.mode
+            if hasattr(self,a): getattr(self,a)(e)
+            
+    #picker
+    def picker_down(self,e):
+        pos = self.getpos(e)
+        c = app.tile.get_at(pos)
+        app.color = c
+    
+    #fill
+    def fill_down(self,e):
+        app.archive()
+        pos = self.getpos(e)
+        bg = app.tile.get_at(pos)
+        if bg == app.color: return
+        self.fill_pixel(pos,bg)
+        self.repaint()
+        
+        
+    def fill_pixel(self,pos,bg): #worst algorithm
+        c = app.tile.get_at(pos)
+        if c != bg: return
+        app.tile.set_at(pos,app.color)
+        x,y = pos
+        if x > 0: self.fill_pixel((x-1,y),bg)
+        if x < app.tile_w-1: self.fill_pixel((x+1,y),bg)
+        if y > 0: self.fill_pixel((x,y-1),bg)
+        if y < app.tile_h-1: self.fill_pixel((x,y+1),bg)
+        
+    #pixel        
+    def pixel_down(self,e):
+        app.archive()
+        pos = self.getpos(e)
+        app.tile.set_at(pos,app.color)
+        self.repaint()
+        
+    #line
+    def line_down(self,e):
+        pos = self.getpos(e)
+        self.pos = pos
+        
+    def line_drag(self,e):
+        self.overlay.fill((0,0,0,0))
+        pos = self.getpos(e)
+        pygame.draw.line(self.overlay,app.color,self.pos,pos)
+        self.repaint()
+    
+    def line_up(self,e):
+        app.archive()
+        self.overlay.fill((0,0,0,0))
+        pos = self.getpos(e)
+        pygame.draw.line(app.tile,app.color,self.pos,pos)
+        self.repaint()
+        
+    #ellipse
+    def ellipse_down(self,e):
+        pos = self.getpos(e)
+        self.pos = pos
+        
+    def ellipse_drag(self,e):
+        self.overlay.fill((0,0,0,0))
+        pos = self.getpos(e)
+        r = pygame.Rect(self.pos[0],self.pos[1],pos[0]-self.pos[0],pos[1]-self.pos[1])
+        r.normalize()
+        r.width += 1
+        r.height += 1
+        r.width,r.height = max(2,r.width),max(2,r.height)
+        pygame.draw.ellipse(self.overlay,app.color,r,1)
+        self.repaint()
+    
+    def ellipse_up(self,e):
+        app.archive()
+        self.overlay.fill((0,0,0,0))
+        pos = self.getpos(e)
+        r = pygame.Rect(self.pos[0],self.pos[1],pos[0]-self.pos[0],pos[1]-self.pos[1])
+        r.normalize()
+        r.width += 1
+        r.height += 1
+        r.width,r.height = max(2,r.width),max(2,r.height)
+        pygame.draw.ellipse(app.tile,app.color,r,1)
+        self.repaint()
+        
+    #draw
+    def draw_down(self,e):
+        app.archive()
+        pos = self.getpos(e)
+        app.tile.set_at(pos,app.color)
+        self.pos = pos
+        self.repaint()
+        
+    def draw_drag(self,e):
+        pos = self.getpos(e)
+        pygame.draw.line(app.tile,app.color,self.pos,pos)
+        self.pos = pos
+        self.repaint()
+        
+    def getpos(self,e):
+        x,y = (e.pos[0])*app.tile_w/self.rect.w,(e.pos[1])*app.tile_h/self.rect.h
+        x = min(max(0,x),app.tile_w-1)
+        y = min(max(0,y),app.tile_h-1)
+        return x,y
+    
+    def getpos2(self,e):
+        w = self.rect.w/app.tile_w
+        h = self.rect.h/app.tile_h
+        x,y = (e.pos[0]+w/2)*app.tile_w/self.rect.w,(e.pos[1]+h/2)*app.tile_h/self.rect.h
+        x = min(max(0,x),app.tile_w)
+        y = min(max(0,y),app.tile_h)
+        return x,y
+    
+            
+    
+    #select
+    def select_down(self,e):
+        pos = self.getpos2(e)
+        app.select = Rect(pos[0],pos[1],0,0)
+        self.repaint()
+        
+    def select_drag(self,e):
+        pos = self.getpos2(e)
+        #pos = (e.pos[0]+app.tile_w/2)/app.tile_w,(e.pos[1]+app.tile_h/2)/app.tile_h
+        
+        app.select = Rect(app.select.x,app.select.y,pos[0]-app.select.x,pos[1]-app.select.y)
+        app.select.w = max(0,app.select.w)
+        app.select.h = max(0,app.select.h)
+        
+        #print app.select
+        
+        self.repaint()
+        
+
+        
+    #eraser
+    def eraser_down(self,e):
+        app.archive()
+        pos = self.getpos(e)
+        app.tile.set_at(pos,(0,0,0,0))
+        self.pos = pos
+        self.repaint()
+        
+    def eraser_drag(self,e):
+        pos = self.getpos(e)
+        pygame.draw.line(app.tile,(0,0,0,0),self.pos,pos)
+        self.pos = pos
+        self.repaint()
+        
+
+def cmd_quit(value):
+    if app.dirty: _dirty(_cmd_quit,value)
+    else: _cmd_quit(value)
+
+def _cmd_quit(value):
+    app.top.quit()
+
+def cmd_all(value):
+    app.select = Rect(0,0,app.tile_w,app.tile_h)
+    app.tdraw.repaint()
+
+def cmd_undo(value):
+    app.undo()
+    
+def cmd_redo(value):
+    pass
+    
+def cmd_copy(value):
+    #next version of pygame?
+    #app.clipboard = app.tile.subsurface(app.select).copy()
+    s = app.tile.subsurface(app.select)
+    app.clipboard = pygame.Surface((app.select.w,app.select.h),SWSURFACE,s)
+    app.clipboard.fill((0,0,0,0))
+    app.clipboard.blit(s,(0,0))
+    
+def cmd_paste(value):
+    if app.clipboard != None:
+        app.archive()
+        app.tile.fill((0,0,0,0),(app.select.x,app.select.y,app.clipboard.get_width(),app.clipboard.get_height()))
+        app.tile.blit(app.clipboard,app.select)
+        app.tdraw.repaint()
+
+def cmd_cut(value):
+    cmd_copy(value)
+    cmd_delete(value)
+    
+def cmd_fullscreen(value):
+    pygame.display.toggle_fullscreen()
+    
+def cmd_delete(value):
+    app.archive()
+    app.tile.fill((0,0,0,0),app.select)
+    app.tdraw.repaint()
+
+def cmd_fill(value):        
+    app.archive()
+    app.tile.fill(app.color,app.select)
+    app.tdraw.repaint()
+
+#NOTE: this feature is a temporary HACK, to be replaced by
+#an ellipse tool in the future
+def cmd_ellipse(value):
+    app.archive()
+    pygame.draw.ellipse(app.tile,app.color,app.select,1)
+    app.tdraw.repaint()
+        
+def cmd_rotate(value):
+    a = value
+    app.archive()
+    s = pygame.transform.rotate(app.tile,a)
+    app.tile.fill((0,0,0,0))
+    app.tile.blit(s,(0,0))
+    app.tdraw.repaint()
+    
+def cmd_flip(value):
+    fh,fv = value
+    app.archive()
+    s = pygame.transform.flip(app.tile,fh,fv)
+    app.tile.fill((0,0,0,0))
+    app.tile.blit(s,(0,0))
+    app.tdraw.repaint()
+
+def cmd_tpick(value):
+    dx,dy = value
+    off = app.tile.get_offset()
+    app.tpicker.pick((off[0]+dx*app.tile_w,off[1]+dy*app.tile_h))
+    
+def cmd_mode(value):
+    mode = value
+    app.mode = mode
+
+def cmd_load(value):
+    if app.dirty: _dirty(_cmd_load,value)
+    else: _cmd_load(value)
+
+
+def _cmd_load(value):
+    if app.fname == None:
+        ErrorDialog("Load failed","Image is untitled.").open()
+        return
+    raise Restart()
+    
+
+def cmd_active_save(value):
+    """ we check if we want to save on screen focus...
+    """
+
+    if app.save_activeevent_switch.value:
+        if app.dirty:
+            #"is dirty... saving"
+            return cmd_save(value)
+    else:
+        pass
+        #"is not dirty, not saving"
+
+
+
+
+def cmd_save(value):
+    if app.fname == None:
+        return cmd_saveas(value)
+    try:
+        # make a temp file... save it there, and then move it in.
+        # so as to avoid race with anything reading it.
+
+        temp_file_name = "tmp_" + app.fname
+        print temp_file_name
+        if have_pil==True:
+            stim = pygame.image.tostring(app.tiles, "RGB")
+            im=Image.fromstring("RGB", (app.tiles.get_width(),app.tiles.get_height()), stim)
+            im.save(temp_file_name)
+        else:
+            pygame.image.save(app.tiles,temp_file_name)
+        #move temp file into place.
+        shutil.move(temp_file_name, app.fname)
+        cfg_to_ini(['tile_w','tile_h','palette'],app.fname)
+        ini_save()
+        app.dirty = 0
+    except Exception, v:
+        ErrorDialog("Save failed.",v).open()
+        return
+    
+def cmd_saveas(value):
+    dialog = SaveAsDialog()
+    
+    def onchange(value):
+        value.close()
+        vv = value.value
+        fname = vv['fname'].value
+        if len(fname) == 0:
+            ErrorDialog("Save As failed.","File Name too short!").open()
+            return
+        global cfg
+        app.fname = cfg['fname'] = fname
+        return cmd_save(None)
+        
+    dialog.connect(gui.CHANGE,onchange,dialog)
+    dialog.open()
+
+def cmd_open(value):
+    if app.dirty: _dirty(_cmd_open,value)
+    else: _cmd_open(value)
+
+    
+def _cmd_open(value):
+    dialog = OpenDialog()
+    
+    def onchange(value):
+        value.close()
+        vv = value.value
+        ok = 0
+        
+        try:        
+            fname,tile_w,tile_h = vv['fname'].value,int(vv['tile_w'].value),int(vv['tile_h'].value)
+            global cfg
+            cfg['fname'] = fname
+            cfg['tile_w'] = tile_w
+            cfg['tile_h'] = tile_h
+            ok = 1
+        except Exception,v:
+            ErrorDialog("Open failed.",v).open()
+            
+        if ok: raise Restart()
+
+    
+    dialog.connect(gui.CHANGE,onchange,dialog)
+    dialog.open()
+
+
+class Restart(Exception):
+    pass
+def _dirty(fnc,v):
+    dialog = DirtyDialog()
+    def onchange(value):
+        value.close()
+        return fnc(v)
+    dialog.connect(gui.CHANGE,onchange,dialog)
+    dialog.open()
+    
+def cmd_new(value):
+    if app.dirty: _dirty(_cmd_new,value)
+    else: _cmd_new(value)
+    
+        
+def _cmd_new(value):
+    dialog = NewDialog()
+    
+    def onchange(value):
+        value.close()
+        vv = value.value
+        ok = 0
+        try:        
+            width,height,tile_w,tile_h = int(vv['width'].value),int(vv['height'].value),int(vv['tile_w'].value),int(vv['tile_h'].value)
+            global cfg
+            cfg['fname'] = None
+            cfg['width'] = width
+            cfg['height'] = height
+            cfg['tile_w'] = tile_w
+            cfg['tile_h'] = tile_h
+            ok = 1
+        except Exception, v:
+            ErrorDialog("New failed.",v).open()
+        if ok:
+            raise Restart()
+    
+    dialog.connect(gui.CHANGE,onchange,dialog)
+    dialog.open()
+
+
+menus = [
+    ('File/New',cmd_new,None),
+    ('File/Open',cmd_open,None),
+    ('File/Save',cmd_save,None),
+    ('File/Save As',cmd_saveas,None),
+    ('File/Reload',cmd_load,None),
+    ('File/Quit',cmd_quit,None),
+
+    ('Edit/Undo',cmd_undo,None),
+    #('Edit/Redo',None,None,None),
+    ('Edit/Cut',cmd_cut,None),
+    ('Edit/Copy',cmd_copy,None),
+    ('Edit/Paste',cmd_paste,None),
+    ('Edit/Delete',cmd_delete,None),
+    ('Edit/Fill',cmd_fill,None),
+        ('Edit/Ellipse',cmd_ellipse,None),
+    ('Edit/Select All',cmd_all,None),
+    
+    ('Transform/Rotate 90 CCW',cmd_rotate,90),
+    ('Transform/Rotate 90 CW',cmd_rotate,-90),
+    ('Transform/Flip Horizontal',cmd_flip,(1,0)),
+    ('Transform/Flip Vertical',cmd_flip,(0,1)),
+    ]
+
+keys = [
+    (K_s,cmd_save,None),
+    (K_d,cmd_load,None),
+
+    (K_a,cmd_all,None),
+    (K_z,cmd_undo,None),
+    #('Edit/Redo',None,None,None),
+    (K_c,cmd_copy,None),
+    (K_v,cmd_paste,None),
+    (K_x,cmd_cut,None),
+    (K_DELETE,cmd_delete,None),
+    (K_f,cmd_fill,None),
+        (K_e,cmd_ellipse,None),
+    
+    (K_LEFTBRACKET,cmd_rotate,90),
+    (K_RIGHTBRACKET,cmd_rotate,-90),
+    (K_COMMA,cmd_flip,(1,0)),
+    (K_PERIOD,cmd_flip,(0,1)),
+    
+    (K_UP,cmd_tpick,(0,-1)),
+    (K_DOWN,cmd_tpick,(0,1)),
+    (K_LEFT,cmd_tpick,(-1,0)),
+    (K_RIGHT,cmd_tpick,(1,0)),
+    
+    (K_F10,cmd_fullscreen,None),
+    ]
+    
+
+tools = [
+    ('draw','draw'),
+    ('pixel','pixel'),
+    ('line','line'),
+    #('ellipse','ellipse'),
+    ('fill','fill'),
+    ('select','select'),
+    ('eraser','eraser'),
+    ]
+
+
+def init_ini():
+    ini.read([ini_fname])
+
+def ini_save():
+    f = open(ini_fname,"wb")
+    ini.write(f)
+    f.close()
+    
+
+def init_opts():
+    usage = "%prog [tiles.tga] [tile_w] [tile_h]"
+
+    parser = OptionParser(usage)
+    parser.add_option("--sw",dest="screen_w",help="screen width (app)",type='int')
+    parser.add_option("--sh",dest="screen_h",help="screen height (app)",type='int')
+    parser.add_option("--tw",dest="tile_w",help="tile width (image)",type='int')
+    parser.add_option("--th",dest="tile_h",help="tile height (image)",type='int')
+    parser.add_option("--width",dest="width",help="new width (image)",type='int')
+    parser.add_option("--height",dest="height",help="new height (image)",type='int')
+    parser.add_option("-p","--pal",dest="palette",help="filename of palette (image)")
+    parser.add_option("-d","--defaults",dest="defaults",help="set default settings (image)",action="store_true")
+    #parser.add_option("-a","--app",dest="app",help="set application level defaults",action="store_true")
+    
+    (opts,args) = parser.parse_args()
+    
+    if len(args) > 3: parser.error("incorrect number of arguments")
+    
+    #parse arguments
+    if len(args) == 0:
+        opts.fname = "None"
+    elif len(args) == 1:
+        opts.fname = args[0]
+    elif len(args) == 2:
+        opts.fname = "None"
+        try: opts.tile_w,opts.tile_h = int(args[0]),int(args[1])
+        except: parser.error("tile width and height must be integers")
+        if opts.tile_w < 1 or opts.tile_h < 1: parser.error("width and height must be greater than 0")
+    else:
+        try: opts.fname,opts.tile_w,opts.tile_h = args[0],int(args[1]),int(args[2])
+        except: parser.error("tile width and height must be integers")
+        if opts.tile_w < 1 or opts.tile_h < 1: parser.error("width and height must be greater than 0")
+        
+    fname = opts.fname
+    
+    #create all sections
+    for k in [fname,"None","app"]:
+        if not ini.has_section(k):
+            ini.add_section(k)
+    
+    #set app level defaults
+    for k,v in [('screen_w',800),('screen_h',600)]:
+        if not ini.has_option('app',k):
+            ini.set('app',k,str(v))
+            
+    #set app level values
+    for k in ['screen_w','screen_h']:
+        if hasattr(opts,k):
+            v = getattr(opts,k)
+            if v != None: ini.set('app',k,str(v))
+            
+    #set default defaults
+    for k,v in [('width',256),('height',256),('tile_w',32),('tile_h',32),('palette','palette.tga')]:
+        if not ini.has_option('None',k):
+            ini.set('None',k,str(v))
+    
+    #name of keys for normal stuff
+    file_ks = ['width','height','tile_w','tile_h','palette']
+        
+    #set default values
+    if opts.defaults:
+        for k in file_ks:
+            if hasattr(opts,k):
+                v = getattr(opts,k)
+                if v != None: ini.set('None',k,str(v))
+    
+    #set fname values
+    for k in file_ks:
+        if hasattr(opts,k):
+            v = getattr(opts,k)
+            if v != None: ini.set(fname,k,str(v))
+    
+    #save the ini
+    ini_save()
+            
+    #convert ini to cfg stuff...
+    ini_to_cfg(['app','None',fname])
+    if fname == 'None': fname = None
+    cfg['fname'] = fname
+    
+            
+def ini_to_cfg(sections):
+    global cfg
+    ik = ['screen_w','screen_h','tile_w','tile_h','width','height']
+    for s in sections:
+        for k,v in ini.items(s):
+            if k in ik: v = int(v)
+            cfg[k] = v
+def ini_to_dict(section):
+    cfg = {}
+    ik = ['screen_w','screen_h','tile_w','tile_h','width','height']
+    for s in [section]:
+        for k,v in ini.items(s):
+            if k in ik: v = int(v)
+            cfg[k] = v
+    return cfg
+
+def cfg_to_ini(ks,section):
+    if not ini.has_section(section): ini.add_section(section)
+    for k in ks:
+        v = cfg[k]
+        ini.set(section,k,str(v))
+        
+        
+def init_gui():
+    #themes = cfg['theme'].split(",")
+    #gui.theme.load(themes)
+    #gui.theme.load(['default','tools'])
+    global top
+    top = gui.Desktop(theme=gui.Theme(['default','tools']))
+
+    #top = gui.Desktop()
+    #top.theme.load(['default','tools'])
+
+
+    #pass
+    
+def init_app():
+    global app
+    app = _app()
+
+    #
+    colors_height = 64
+    ss = 8
+        
+    #--- top
+    x,y,h = 0,0,0
+        
+    #menus
+    e = gui.Menus(menus)
+    e.rect.w,e.rect.h = e.resize()
+    app.add(e,x,y)
+    x,h = x+e.rect.w,max(h,e.rect.h)
+    menus_height = e.rect.h
+    
+    #--- row
+    x,y,h = 0,y+h,0
+    
+    #--- vspace
+    y += ss
+    
+    #--- hspace
+    x += ss
+    
+    #tools
+    e = gui.Toolbox(tools,1,0,value='draw') #,"icons48")
+    e.rect.w,e.rect.h = e.resize()
+    def _set_mode(value):
+        cmd_mode(value.value)
+    e.connect(gui.CHANGE,_set_mode,e)
+    app.add(e,x,y)
+
+    
+    #--- vspace
+    y += ss
+
+
+    #--- switchbox for saving.
+    sx, sy = x,y+(max(h,e.rect.h))
+
+    savelabel = gui.Label("Save on")
+    app.add(savelabel, sx,sy)
+    savelabel2 = gui.Label("focus:")
+    app.add(savelabel2, sx,sy+(ss*2))
+
+    #--- vspace
+    y += (ss *5)
+    sy += (ss *5)
+
+    save_activeevent_switch = gui.Switch(False)
+    app.add(save_activeevent_switch, sx,sy)
+    app.save_activeevent_switch = save_activeevent_switch
+
+    x,h = x+e.rect.w,max(h,e.rect.h)
+    toolbox_width = e.rect.w
+
+    #--- hspace
+    x += ss
+    y -= ss*6 #undo what was done above to the y val
+        
+    #tdraw
+    #tdraw-calcs
+    dw = app.screen_w - (toolbox_width+app.tiles.get_width()+ss*4)
+    dh = app.screen_h - (menus_height+colors_height+ss*2)
+    if dw/float(app.tile_w) > dh/float(app.tile_h): dw = dh/float(app.tile_h)*app.tile_w
+    else: dh = dw/float(app.tile_w)*app.tile_h
+    e = app.tdraw = tdraw(dw,dh)
+    app.add(e,x,y)
+    x,h = x+e.rect.w,max(h,e.rect.h)
+    
+    #--- hspace
+    x += ss
+    
+    #tpicker
+    e = app.tpicker = tpicker()
+    e.rect.w,e.rect.h = e.resize()
+    #--- right
+    x = app.screen_w-e.rect.w-ss
+    app.add(e,x,y)
+    h = max(h,e.rect.h)
+
+    #tpreview
+    y = y+e.rect.h
+    e = app.tpreview = tpreview()
+    e.rect.w,e.rect.h = e.resize()
+    app.add(e,x,y)
+    
+    #--- bottom
+    x,y,h = 0,app.screen_h - colors_height,0
+    
+    #cpreview
+    colors_width = toolbox_width + ss * 2
+    e = app.cpreview = cpreview(colors_width,colors_height)
+    e.rect.w,e.rect.h = e.resize()
+    app.add(e,x,y)
+    x,h = x+e.rect.w,max(h,e.rect.h)
+    
+    #cpicker
+    if os.path.isfile(cfg['palette']):
+        pal = pygame.image.load(cfg['palette'])
+    else:
+        #default to EGA / NES palette
+        
+        pw,ph = 16,6
+        pdata = [(0, 0, 0, 255), (0, 0, 170, 255), (0, 170, 0, 255), (0, 170, 170, 255), (170, 0, 0, 255), (170, 0, 170, 255), (170, 85, 0, 255), (170, 170, 170, 255), (85, 85, 85, 255), (85, 85, 255, 255), (85, 255, 85, 255), (85, 255, 255, 255), (255, 85, 85, 255), (255, 85, 255, 255), (255, 255, 85, 255), (255, 255, 255, 255), (0, 0, 0, 255), (0, 0, 0, 255), (0, 0, 0, 255), (0, 0, 0, 255), (0, 0, 0, 255), (0, 0, 0, 255), (0, 0, 0, 255), (0, 0, 0, 255), (0, 0, 0, 255), (0, 0, 0, 255), (0, 0, 0, 255), (0, 0, 0, 255), (0, 0, 0, 255), (0, 0, 0, 255), (0, 0, 0, 255), (0, 0, 0, 255), (255, 255, 255, 255), (173, 243, 255, 255), (223, 214, 255, 255), (255, 190, 255, 255), (255, 176, 255, 255), (255, 177, 237, 255), (255, 191, 185, 255), (255, 217, 145, 255), (237, 246, 128, 255), (185, 255, 138, 255), (145, 255, 173, 255), (128, 255, 223, 255), (138, 255, 255, 255), (197, 197, 197, 255), (0, 0, 0, 255), (0, 0, 0, 255), (255, 255, 255, 255), (129, 200, 255, 255), (179, 171, 255, 255), (231, 146, 255, 255), (255, 132, 244, 255), (255, 133, 194, 255), (255, 148, 141, 255), (244, 173, 101, 255), (194, 202, 84, 255), (141, 227, 94, 255), (101, 240, 129, 255), (84, 240, 179, 255), (94, 225, 231, 255), (120, 120, 120, 255), (0, 0, 0, 255), (0, 0, 0, 255), (192, 192, 192, 255), (57, 128, 200, 255), (108, 99, 217, 255), (160, 74, 207, 255), (200, 61, 172, 255), (217, 61, 122, 255), (207, 76, 70, 255), (172, 102, 30, 255), (122, 130, 13, 255), (70, 155, 23, 255), (30, 169, 57, 255), (13, 168, 108, 255), (23, 153, 160, 255), (61, 61, 61, 255), (0, 0, 0, 255), (0, 0, 0, 255), (128, 128, 128, 255), (16, 87, 159, 255), (67, 58, 176, 255), (119, 34, 166, 255), (159, 20, 131, 255), (176, 20, 81, 255), (166, 35, 29, 255), (131, 61, 0, 255), (81, 89, 0, 255), (29, 114, 0, 255), (0, 128, 16, 255), (0, 127, 67, 255), (0, 112, 119, 255), (0, 0, 0, 255), (0, 0, 0, 255), (0, 0, 0, 255)]
+
+        pal = pygame.Surface((pw,ph),SWSURFACE,32)
+        n=0
+        for py in range(0,ph):
+            for px in range(0,pw):
+                pal.set_at((px,py),pdata[n])
+                n+=1
+        
+        
+    e = app.cpicker = cpicker(app.screen_w-colors_width,colors_height,pal)
+    e.rect.w,e.rect.h = e.resize()
+    app.add(e,x,y)
+    x,h = x+e.rect.w,max(h,e.rect.h)
+    
+    pygame.key.set_repeat(500,30)
+    
+    app.screen.fill((255,255,255,255))
+    
+class NewDialog(gui.Dialog):
+    def __init__(self,**params):
+        title = gui.Label("New...")
+        
+        doc = html.HTML(globals={'gui':gui,'dialog':self},data="""<form id='form'><table>
+        <tr>
+        <td align=center>Image Size
+        <td align=center>Tile Size
+
+        <tr><td colspan='1' align='center' style='padding-right:8px;'><table>
+        <tr><td align=right>Width: <td><input type='text' size='4' value='%(width)s' name='width'>
+        <tr><td align=right>Height: <td><input type='text' size='4' value='%(height)s' name='height'>
+        </table>
+        
+        <td colspan='1' align='center'><table>
+        <tr><td align=right>Width: <td><input type='text' size='4' value='%(tile_w)s' name='tile_w'>
+        <tr><td align=right>Height: <td><input type='text' size='4' value='%(tile_h)s' name='tile_h'>
+        </table>
+        
+        <tr><td colspan=2>Palette: <input type='text' size=20 name='palette' value='%(palette)s'>
+        
+        <tr><td>&nbsp;
+        
+        <tr><td colspan=2><input type='button' value='Okay' onclick='dialog.send(gui.CHANGE)'> <input type='button' value='Cancel' onclick='dialog.close()'>
+        
+        </table>"""%ini_to_dict('None'))
+        gui.Dialog.__init__(self,title,doc)
+        
+        self.value = doc['form']
+
+class SaveAsDialog(gui.Dialog):
+    def __init__(self,**params):
+        title = gui.Label("Save As...")
+        
+        doc = html.HTML(globals={'gui':gui,'dialog':self},data="""
+        <form id='form'>
+        
+        <table>
+        
+        <tr><td colspan=2>File Name: <input type='file' size=20 name='fname' value=''>
+        
+        <tr><td>&nbsp;
+        
+        <tr><td colspan=2><input type='button' value='Okay' onclick='dialog.send(gui.CHANGE)'> <input type='button' value='Cancel' onclick='dialog.close()'>
+        
+        </table>""")
+        gui.Dialog.__init__(self,title,doc)
+        
+        self.value = doc['form']
+
+class OpenDialog(gui.Dialog):
+    def __init__(self,**params):
+        title = gui.Label("Open...")
+        
+        def load_vals(fname,form):
+            if not ini.has_section(fname): return
+            
+            for k,v in ini.items(fname):
+                if k in form:
+                    form[k].value = v
+        doc = html.HTML(globals={'load_vals':load_vals,'ini':ini,'gui':gui,'dialog':self},data="""<form id='form'><table>
+        
+        <tr><td align=right>File Name:&nbsp;<td  align=left><input type='file' size=20 name='fname' value='' onchange='load_vals(self.value,form)'>
+        <tr><td align=right>Tile Width:&nbsp;<td align=left><input type='text' size='4' value='%(tile_w)s' name='tile_w'>
+        <tr><td align=right>Tile Height:&nbsp;<td align=left><input type='text' size='4' value='%(tile_h)s' name='tile_h'>
+        
+        <tr><td align=right>Palette:&nbsp;<td align=left><input type='text' size=20 name='palette' value='%(palette)s'>
+        
+        <tr><td>&nbsp;
+        
+        <tr><td colspan=2><input type='button' value='Okay' onclick='dialog.send(gui.CHANGE)'> <input type='button' value='Cancel' onclick='dialog.close()'>
+        
+        </table>"""%ini_to_dict('None'))
+        gui.Dialog.__init__(self,title,doc)
+        
+        self.value = doc['form']
+
+class ErrorDialog(gui.Dialog):
+    def __init__(self,tt,data,**params):
+        title = gui.Label("Error: "+tt)
+        data = str(data)
+        
+        doc = html.HTML(globals={'gui':gui,'dialog':self},data="""
+        <form id='form'>
+        
+        <table>
+        <tr><td><h1>&lt;!&gt;&nbsp;</h1>
+        <td>"""+data+"""
+        <tr><td>&nbsp;
+        <tr><td colspan=2><input type='button' value='Okay' onclick='dialog.send(gui.CHANGE);dialog.close()'>
+        </table>""")
+        gui.Dialog.__init__(self,title,doc)
+        
+        self.value = doc['form']
+
+class DirtyDialog(gui.Dialog):
+    def __init__(self,**params):
+        title = gui.Label("File not yet saved...")
+        data = "Your file is not yet saved.<br>Are you sure you want to continue?"
+        
+        doc = html.HTML(globals={'gui':gui,'dialog':self},data="""
+        <form id='form'>
+        
+        <table>
+        <tr><td><h1>&lt;!&gt;&nbsp;</h1>
+        <td>"""+data+"""
+        <tr><td>&nbsp;
+        <tr><td colspan=2><input type='button' value='Okay' onclick='dialog.send(gui.CHANGE)'> <input type='button' value='Cancel' onclick='dialog.close()'>
+        </table>""")
+        gui.Dialog.__init__(self,title,doc)
+        
+        self.value = doc['form']
+
+
+
+def run():
+    #top.connect(gui.QUIT,top.quit,None)
+    top.connect(gui.QUIT,cmd_quit,None)
+    top.connect(pygame.ACTIVEEVENT, cmd_active_save,None)
+    top.init(app,app.screen)
+    app.top = top
+    top.run()
+    
+
+def main():
+    init_ini()
+    init_opts()
+    init_gui()
+    
+    restart = 1
+    while restart:
+        restart = 0
+        try:
+            init_app()
+            run()
+        except Restart: restart = 1
+        
+
+        
+    
+main()
+# vim: set filetype=python sts=4 sw=4 noet si :

UCC git Repository :: git.ucc.asn.au