#!/usr/bin/env python import copy import numpy from gipsy import * from time import * from math import * # ========================= global variables ================================= NCI = 200 # number of color indices for plot field tabname = 'BLOT' # name of table with shape columns # ============================================================================ # ---------------------------------------------------------------------------- # dist2 # ---------------------------------------------------------------------------- # Utility to obtain the square of the distance between two points. # def dist2(a, b): dx = a[0]-b[0] dy = a[1]-b[1] return (dx*dx)+(dy*dy) # ---------------------------------------------------------------------------- # pgstate # ---------------------------------------------------------------------------- # Save and restore some PGPLOT parameters. # def pgstate(state=None): if state: pgsci(state[0]) pgslw(state[1]) pgsfs(state[2]) pgsch(state[3]) else: ci=[0]; lw=[0]; fs=[0]; ch=[0] ci = pgqci() lw = pgqlw() fs = pgqfs() ch = pgqch() return (ci, lw, fs, ch) # ============================================================================ # Shape # ---------------------------------------------------------------------------- # Abstract superclass for all shapes. # # All shapes have the following attribute: # center - a 2-tuple containing the coordinates of the center. # # All shapes define the following methods: # store() - stores the shape as a column the table 'BLOT' # in the specified set and subset. # draw() - draws the shape. # nearest_ctrl() - returns a 3-tuple containing the shape itself, # the index of the nearest point in the shape # (-1 designates the center) and the square # of the distance between this point and the # specified point. # movepoint() - changes the coordinates of the point to those # of the specified point. # class Shape: types = ['rect', 'elli', 'poly', 'spli'] # NOTE: *must* match MaxId names t_rectangle = 0 t_ellipse = 1 t_polygon = 2 t_spline = 3 delfromset = False # indicates whether delete also applies to shapes in set txtcolor = 5 # text color addcolor = 7 # outline color subcolor = 2 # outline color for subtracted shapes color = 8 # base hatch color selcolor = 10 # selected hatch color def __init__(self, type, id, mode): self.id = id self.name = "%s%d" % (self.types[type], id) self.mode = mode self.type = type self.set = None self.hide = False def __del__(self): if self.delfromset: try: self.set.delcol(tabname, self.name, subset=self.sub) except: pass def insertpoint(self, index): pass def delpoint(self, index): pass # ---------------------------------------------------------------------------- # Rectangle # ---------------------------------------------------------------------------- class Rectangle(Shape): def __init__(self, id, mode, low, high): Shape.__init__(self, self.t_rectangle, id, mode) self.xlo = low[0] self.ylo = low[1] self.xhi = high[0] self.yhi = high[1] def __getattr__(self, attr): if attr=='center': return ((self.xhi+self.xlo)/2.0, (self.yhi+self.ylo)/2.0) else: raise AttributeError, "No attribute %s" % attr def __setattr__(self, attr, value): if attr=='center': xc, yc = self.center dx = value[0]-xc dy = value[1]-yc self.xlo += dx self.ylo += dy self.xhi += dx self.yhi += dy else: self.__dict__[attr] = value def store(self, set=None, sub=None): if set==None: set = self.set if sub==None: sub = self.sub try: set.delcol(tabname, self.name, subset=sub) except: pass set.crecol(tabname, self.name, 'DBLE', subset=sub) params = [4.0, float(self.id), float(self.type), float(self.mode), self.xlo, self.ylo, self.xhi, self.yhi] set[sub, tabname, self.name, :] = params self.set = set self.sub = sub def draw(self): if self.hide: return if abs(self.xhi-self.xlo)<1.5 and abs(self.yhi-self.ylo)<1.5: pgs = pgstate() pgslw(1) pgsci(self.color) pgsfs(1) pgrect(self.xlo, self.xhi, self.ylo, self.yhi) pgstate(pgs) return bcolor = [self.addcolor, self.subcolor][self.mode] # border color pgs = pgstate() pgsci(self.color) pgslw(1) pgsfs(4) pgrect(self.xlo, self.xhi, self.ylo, self.yhi) pgslw(4) pgsfs(2) pgsci(bcolor) pgrect(self.xlo, self.xhi, self.ylo, self.yhi) xc, yc = self.center pgsci(self.txtcolor) ### pgsch(1) ### pgtext(xc, yc, ' '+self.name) pgsch(2) xmark = [self.xlo, xc, self.xhi, xc] ymark = [ yc, self.yhi, yc, self.ylo] pgpt(xmark, ymark, 2) pgpt(xc, yc, 18) pgsch(1) pgstate(pgs) def nearest_ctrl(self, point): xc, yc = self.center ctrls = [(self.xlo, yc), (self.xhi, yc), (xc, self.ylo), (xc, self.yhi)] index = -1 dist = dist2((xc, yc), point) i = 0 for curr in ctrls: currdist = dist2(curr, point) if currdist-1: del self.xvals[index] del self.yvals[index] def movepoint(self, index, point): if index==-1: self.center = point else: self.xvals[index], self.yvals[index] = point def store(self, set=None, sub=None): if set==None: set = self.set if sub==None: sub = self.sub try: set.delcol(tabname, self.name, subset=sub) except: pass set.crecol(tabname, self.name, 'DBLE', subset=sub) header = [4.0, float(self.id), float(self.type), float(self.mode)] set[sub, tabname, self.name, :] = header + self.xvals + self.yvals self.set = set self.sub = sub def nearest_ctrl(self, point): xc, yc = self.center index = -1 dist = dist2((xc, yc), point) i = 0 for x in self.xvals: currdist = dist2((x,self.yvals[i]), point) if currdist2: d2 = 10000000.0 # larger than can be expected in a map? for i in range(npoints): x0 = self.xvals[i-1] # previous point y0 = self.yvals[i-1] # ,, ,, x1 = self.xvals[i] # current ,, y1 = self.yvals[i] # ,, ,, xp, yp = point # position of point to be inserted dx = x1-x0 dy = y1-y0 det = -dx*dx - dy*dy c1 = dx*y0 - dy*x0 c2 = dx*xp + dy*yp xi = (-dx*c2 + c1*dy)/det # point of intersection with normal yi = (-c1*dx - dy*c2)/det # ,, ,, ,, ,, ,, xmin, ymin = min(x0, x1), min(y0, y1) xmax, ymax = max(x0, x1), max(y0, y1) if xi>=xmin and xi<=xmax and yi>=ymin and yi<=ymax: # on edge? curd2 = dist2(point, (xi, yi)) if curd2len(self.inset.subsets)-1: value = len(self.inset.subsets)-1 self.__dict__[attr] = value self.inset.selected = value self.select_shape(None) self.draw() self.showpos() elif 'intp' == attr or\ 'mode' == attr or\ 'aspr' == attr or\ 'labax' == attr or\ 'minmax' == attr: self.__dict__[attr] = value self.draw() elif 'hatch' == attr: if self.pid: pgshs(45.0, value, 0.0) self.update() else: self.__dict__[attr] = value elif 'hide' == attr: self.__dict__[attr] = value self.update() elif 'inset'==attr: self.__dict__[attr] = value minmax = None if userlog("FIX="): minmax = userreal("CLIP=", default=6, defval=None, nmax=2) if minmax: self.__dict__['minmax'] = minmax else: try: imgmin = value['DATAMIN'] imgmax = value['DATAMAX'] except: imgmin = None imgmax = None for subset in value.subsets: image = value.subimage(subset) curmin, curmax, curnbl = minmax3(image) if imgmax==None: imgmax = curmax imgmin = curmin else: imgmin = min(imgmin, curmin) imgmax = max(imgmax, curmax) self.__dict__['minmax'] = (float(imgmin), float(imgmax)) wkey("CLIP=%f %f" % (imgmin, imgmax)) else: self.__dict__[attr] = value # "catch-all" for other attributes def select_shape(self, shape): Interact.mode = Interact() # cancel any previous new shape if shape==None: self.shape_index = None self.inset.deselect_shape() self.shinfo.setLabel('No current shape.') else: if type(shape)==types.IntType: self.shape_index = shape else: self.shape_index = self.inset.shapes().index(shape) self.inset.select_shape(self.shape_index) shape = self.inset.shapes()[self.shape_index] self.shinfo.setLabel('Current shape: %s (%s)' % (shape.name, ['add', 'subtract'][shape.mode])) def draw(self): if self.inset!=None: inset = self.inset if not self.pid: # one-time initialization self.pid = self.plot.open() self.plot.frames(1) # backup frame for "static" image pgsbci(16) pgscir(17, NCI) pgeras() pgshs(45.0, self.hatch, 0.0) coled.limits(self.minmax[0], self.minmax[1]) try: coled.units(str(inset['BUNIT'])) except: coled.units('?') wkey('CE_RESET1=YES') pgeras() pgvstd() inset.setbox(self.zoombox) # temporarily trick Set object if self.aspr: if not self.labax: pgsvp(0.0, 1.0, 0.0, 1.0) pgwnad(inset.blo[0]-0.5, inset.bhi[0]+0.5, inset.blo[1]-0.5, inset.bhi[1]+0.5) else: if not self.labax: pgsvp(0.0, 1.0, 0.0, 1.0) pgswin(inset.blo[0]-0.5, inset.bhi[0]+0.5, inset.blo[1]-0.5, inset.bhi[1]+0.5) inset.setbox(self.defbox) # reset Set object trick if self.mode==0: pgsimi(self.intp) image = inset.subimage(inset.subsets[self.index]) imgmin, imgmax = self.minmax elif self.mode==1: pgsimi(self.intp) image = inset.maskedimage() imgmin, imgmax = self.minmax elif self.mode==2: mask = inset.mask() if mask==None: pgeras() pgmtxt('T', -20, 0.5, 0.5, 'No mask defined') return pgsimi(False) image = numpy.logical_not(mask).astype('Float32') imgmin, imgmax = 0.0, 1.0 tr = [inset.blo[0]-1, 1, 0.0, inset.blo[1]-1, 0.0, 1] jdim, idim = image.shape pgimag(image, idim, jdim, 1, idim, 1, jdim, imgmin, imgmax, tr) if self.labax: pgbox('BCINST', 0, 0, 'BCINST', 0, 0) else: pgbox('BC', 0, 0, 'BC', 0, 0) plotf.record(0) if self.mode==0 and not self.hide: inset.draw() def update(self): if self.inset and self.mode==0: self.plot.show(0) if not self.hide: self.inset.draw() def showpos(self): if self.info: level = self.inset.subsets[self.index] axes = self.inset.axes(level, mode='outside') message = '' comma = '' phys = self.inset.tophys(level=level, mode='outside') iphys = 0 for axis in axes: axname = axis.name axgrid = self.inset.grid(axis.axnum, level) message += "%s%s=%d" % (comma, axname, axgrid) message += " (%.4g %s)" % (phys[iphys], axis.cunit) iphys += 1 comma = ', ' self.info.setLabel(message) # ============================================================================ # Interact # ---------------------------------------------------------------------------- # Left cursor button interaction class. # class Interact: mode = None # the only instance of Interact and its subclasses. def __init__(self): self.shape = None def down(self, pos): index = frame.shape_index if index!=None: shape = frame.inset.shapes()[index] if shape.type==shape.t_polygon or shape.type==shape.t_spline: self.shape = shape shape.addpoint(pos) frame.update() def move(self, pos): shape = self.shape if shape: shape.movepoint(len(shape.xvals)-1, pos) frame.update() def up(self, pos): Interact.mode = Interact() class Interact_RE(Interact): def down(self, pos): self.pos = pos def move(self, pos): frame.update() pgsfs(2) pgrect(self.pos[0], pos[0], self.pos[1], pos[1]) pgsfs(4) class Interact_rect(Interact_RE): def __init__(self): self.info.setLabel('New shape: rectangle.') def up(self, pos): lo = [min(self.pos[0], pos[0]), min(self.pos[1], pos[1])] hi = [max(self.pos[0], pos[0]), max(self.pos[1], pos[1])] if (hi[0]-lo[0])<1.0 and (hi[1]-lo[1]<1.0): lo[0] = float(nint(lo[0]))-0.5; hi[0] = lo[0]+1.0 lo[1] = float(nint(lo[1]))-0.5; hi[1] = lo[1]+1.0 shape = frame.inset.Rectangle(frame.shmode, lo, hi) frame.update() class Interact_elli(Interact_RE): def __init__(self): self.info.setLabel('New shape: ellipse.') def up(self, pos): xlo, ylo = min(self.pos[0], pos[0]), min(self.pos[1], pos[1]) xhi, yhi = max(self.pos[0], pos[0]), max(self.pos[1], pos[1]) xc = (xhi+xlo)/2.0 yc = (yhi+ylo)/2.0 dx = xhi-xlo dy = yhi-ylo pa = 0.0 if dy>dx: pa = 90.0 ma = max(dx, dy) mi = min(dx, dy) shape = frame.inset.Ellipse(frame.shmode, (xc, yc), ma/2.0, mi/2.0, pa) frame.update() class Interact_PS(Interact): def move(self, pos): self.shape.center = pos frame.update() def up(self, pos): Interact.mode = Interact() class Interact_poly(Interact_PS): def __init__(self): self.info.setLabel('New shape: polygon.') def down(self, pos): self.shape = frame.inset.Polygon(frame.shmode, [pos[0]], [pos[1]]) frame.select_shape(self.shape) frame.update() class Interact_spli(Interact_PS): def __init__(self): self.info.setLabel('New shape: spline.') def down(self, pos): self.shape = frame.inset.Spline(frame.shmode, [pos[0]], [pos[1]]) frame.select_shape(self.shape) frame.update() # ---------------------------------------------------------------------------- # apply_mask # ---------------------------------------------------------------------------- def apply_mask(all=False): outset = frame.outset if outset!=None: inset = frame.inset if all: indices = range(len(inset.subsets)) else: indices = [frame.index] for index in indices: outset.subimage(inset.subsets[index])[:] = inset.maskedimage(index) if all: newsflash('all subset masks applied to outset') else: newsflash('This subset\'s mask applied to outset') else: newsflash('No outset - cannot apply mask(s)') # ---------------------------------------------------------------------------- # file_cb # ---------------------------------------------------------------------------- # FILE= keyword handler def file_cb(cb): choice = userint(cb.key, defval=-1) if frame.inset: if GgiBase().verify('Do you wish to save your work on this set?', 'Yes', 'No'): wkey('EDIT=1') GgiBase().handleEvents() if choice == 0: # open inset insetwindow = GgiBase.base.Inset('SETNAME=', 'SET=', 'BOX=').ndims(2) insetwindow.closeOnOK() elif choice == 1: # exit program finis() # ---------------------------------------------------------------------------- # edit_cb # ---------------------------------------------------------------------------- def edit_cb(cb): inset = frame.inset if inset: choice = userint(cb.key, defval=-1) if choice==0: inset.store() elif choice==1: inset.storeall() elif choice==2: if GgiBase().verify('OK to clear all shapes on this frame?', 'Yes', 'No'): inset.delshapes(fromset=False) frame.update() elif choice==3: if GgiBase().verify('OK to reload shapes from subset?', 'Yes', 'No'): inset.loadshapes() frame.update() elif choice==4: if GgiBase().verify('OK to delete all shapes from this subset?', 'Yes', 'No'): inset.delshapes(fromset=True) frame.update() elif choice==5: if GgiBase().verify('OK to delete all shapes on all subsets?', 'Yes', 'No'): inset.delallshapes(fromset=True) frame.update() elif choice==6: apply_mask(all=True) # ---------------------------------------------------------------------------- # inset_cb # ---------------------------------------------------------------------------- def inset_cb(cb): try: frame.inset.close() # close any set that might still be opened wkey('OUTSET=') # clear any current output set except: pass frame.inset = BlotSet(usertext(cb.key)) wkey("FRAME=0") cb.info.setLabel('(0 ... %d)' % (len(frame.inset.subsets)-1)) cb.outside.setLabel(['inside', 'outside'][frame.inset.outside]) # ---------------------------------------------------------------------------- # box_cb # ---------------------------------------------------------------------------- def box_cb(cb): inset = frame.inset frame.defbox = usertext(cb.key, defval='%d %d %d %d' % ( inset.blo[0], inset.blo[1], inset.bhi[0], inset.bhi[1])) frame.zoombox = frame.defbox inset.setbox(frame.defbox) frame.draw() # ---------------------------------------------------------------------------- # frame_cb # ---------------------------------------------------------------------------- def frame_cb(cb): frame.index = userint(cb.key) # ---------------------------------------------------------------------------- # intp_cb # ---------------------------------------------------------------------------- def intp_cb(cb): frame.intp = userlog(cb.key) # ---------------------------------------------------------------------------- # aspr_cb # ---------------------------------------------------------------------------- def aspr_cb(cb): frame.aspr = not userlog(cb.key) # ---------------------------------------------------------------------------- # labax_cb # ---------------------------------------------------------------------------- def labax_cb(cb): frame.labax = not userlog(cb.key) # ---------------------------------------------------------------------------- # viewmode_cb # ---------------------------------------------------------------------------- def viewmode_cb(cb): frame.mode = userint(cb.key) # ---------------------------------------------------------------------------- # new_cb # ---------------------------------------------------------------------------- def new_cb(cb): choice = userint(cb.key) if choice==0: Interact.mode=Interact_spli() elif choice==1: Interact.mode=Interact_poly() elif choice==2: Interact.mode=Interact_rect() elif choice==3: Interact.mode=Interact_elli() # ---------------------------------------------------------------------------- # hatch_cb # ---------------------------------------------------------------------------- def hatch_cb(cb): frame.hatch = userreal(cb.key) # ---------------------------------------------------------------------------- # clip_cb # ---------------------------------------------------------------------------- def clip_cb(cb): minmax = userreal(cb.key, default=4, defval=None, nmax=2) if minmax!=None: frame.minmax = minmax coled.limits(minmax[0], minmax[1]) # ---------------------------------------------------------------------------- # addsub_cb # ---------------------------------------------------------------------------- def addsub_cb(cb): if userlog(cb.key): wkey(cb.key) cb.mode = not cb.mode cb.button.setLabel(['ADD', 'SUB'][cb.mode]) frame.shmode = cb.mode # ---------------------------------------------------------------------------- # hide_cb # ---------------------------------------------------------------------------- def hide_cb(cb): frame.hide = userlog(cb.key) # ---------------------------------------------------------------------------- # outside_cb # ---------------------------------------------------------------------------- def outside_cb(cb): if userlog(cb.key): wkey(cb.key) frame.inset.outside = not frame.inset.outside cb.button.setLabel(['inside ', 'outside'][frame.inset.outside]) if frame.mode==1: # blotted image frame.draw() # ---------------------------------------------------------------------------- # stepper_cb # ---------------------------------------------------------------------------- def stepper_cb(cb): if frame.inset==None: return if userlog(cb.key): wkey(cb.key) current = userint('FRAME=') if cb.end==0: current = 0 elif cb.end==1: current = len(frame.inset.subsets)-1 else: current += cb.incr current = min(max(0, current), len(frame.inset.subsets)-1) wkey('FRAME=%d' % current) # ---------------------------------------------------------------------------- # outset_cb # ---------------------------------------------------------------------------- def outset_cb(cb): if not frame.inset: return try: frame.outset.close() except: pass frame.outset = None cb.apply.active(False) cb.label.setLabel('No current outset.') name = usertext(cb.key) if name: try: inparts = frame.inset.spec.split() inparts[0] = name outspec = ' '.join(inparts) outset = Set(outspec, write=True) if outset.image.shape != frame.inset.image.shape: reject(cb.key, 'Incompatible output set') outset.close() else: if GgiBase().verify('Set %s already exists,\nOK to modify?'%name, 'Yes', 'No'): frame.outset = outset else: outset.close() except: try: newsflash('creating output set') frame.outset = frame.inset.copy(name) status('output set created') except: status('Cannot copy inset to %s' % name) error(1, 'Cannot copy inset to %s' % name) if frame.outset: cb.apply.active(True) cb.label.setLabel('Current outset: %s' % name) frame.outset.setbox(frame.defbox) # ---------------------------------------------------------------------------- # apply_cb # ---------------------------------------------------------------------------- def apply_cb(cb): if userlog(cb.key): wkey(cb.key) apply_mask() newsflash('this frame\'s mask applied to output set') # ---------------------------------------------------------------------------- # save_cb # ---------------------------------------------------------------------------- def save_cb(cb): if userlog(cb.key): wkey(cb.key) frame.inset.store() newsflash('shapes stored') # ---------------------------------------------------------------------------- # autosave_cb # ---------------------------------------------------------------------------- def autosave_cb(cb): def saver(tcb): try: newsflash('autosave: storing all shapes') frame.inset.storeall() newsflash('autosave: shapes stored') except: newsflash('autosave: can NOT store shapes') if userlog(cb.key): try: cb.timer.schedule() except: cb.timer = TimeCallback(saver, 60.0) else: try: cb.timer.deschedule() except: pass # ---------------------------------------------------------------------------- # cursor_cb # ---------------------------------------------------------------------------- def cursor_cb(cb): inset = frame.inset if not inset: return if frame.mode==0 and not frame.hide: if cb.button==1 and cb.state==0: # --- press left button Interact.mode.down((cb.x, cb.y)) elif cb.button==0 and cb.state==1: # --- move left button Interact.mode.move((cb.x, cb.y)) elif cb.button==1 and cb.state==1: # --- release left button Interact.mode.up((cb.x, cb.y)) elif cb.button==2 and cb.state==0: # --- press middle button index = frame.shape_index if index!=None: shape = frame.inset.shapes()[index] if shape.type==shape.t_polygon or shape.type==shape.t_spline: cb.shape = shape point = (cb.x, cb.y) cb.index = shape.insertionpoint(point) shape.insertpoint(cb.index, point) frame.update() elif cb.button==0 and cb.state==2: # --- move middle button if cb.shape!=None: cb.shape.movepoint(cb.index, (cb.x, cb.y)) frame.update() elif cb.button==2 and cb.state==2: # --- release middle button cb.shape = None elif cb.button==4 and cb.state==0: # --- press right button point = (cb.x, cb.y) frame.select_shape(inset.nearest_shape(point)) if frame.shape_index!=None: cb.shape = inset.shapes()[frame.shape_index] cb.index = cb.shape.nearest_ctrl(point)[1] frame.update() elif cb.button==0 and cb.state==4: # --- move right button if cb.shape!=None: cb.shape.movepoint(cb.index, (cb.x, cb.y)) frame.update() elif cb.button==4 and cb.state==4: # --- release right button cb.shape = None elif cb.button==1 and cb.state==16: # --- CTRL-click: select shape point = (cb.x, cb.y) frame.select_shape(inset.nearest_shape(point)) frame.update() # --------------------------------- Shapes ---------------------------------- elif cb.key=='\x03': # --- CTRL-C: copy shape if frame.shape_index!=None: shapes = inset.shapes() shape = shapes[frame.shape_index] savset = shape.set shape.set = None # (copy should not contain set) frame.saved = copy.deepcopy(shape) shape.set = savset elif cb.key=='\x09': # --- TAB: step through shapes shapes = inset.shapes() if shapes: if frame.shape_index==None: frame.shape_index = 0 else: frame.shape_index = (frame.shape_index+1)%len(shapes) frame.select_shape(frame.shape_index) frame.update() elif cb.key=='\x16': # --- CTRL-V: paste shape if frame.saved: inset.addshape(copy.deepcopy(frame.saved)) frame.select_shape(len(inset.shapes())-1) frame.update() elif cb.key in ['\x7f', '\x18']: # --- DEL, CTRL-X: delete shape if frame.shape_index!=None: shapes = inset.shapes() shape = shapes[frame.shape_index] shape.set = None frame.saved = copy.deepcopy(shape) del shapes[frame.shape_index] frame.select_shape(None) frame.update() elif cb.key in ['D', 'd']: # --- 'D': delete point ### restrict to selected shape? point = (cb.x, cb.y) shindex = inset.nearest_shape(point) if shindex!=None: ctrl = inset.shapes()[shindex].nearest_ctrl(point) ctrl[0].delpoint(ctrl[1]) frame.select_shape(shindex) frame.update() elif cb.key in ['M', 'm']: # --- switch add/subtract shindex = inset.nearest_shape((cb.x, cb.y)) if shindex!=None: shape = inset.shapes()[shindex] shape.mode = not shape.mode frame.select_shape(shindex) frame.update() elif cb.key in ['R', 'r']: # --- 'R': new rectangle Interact.mode = Interact_rect() elif cb.key in ['E', 'e']: # --- 'E': new ellipse Interact.mode = Interact_elli() elif cb.key in ['P', 'p']: # --- 'P': new polygon Interact.mode = Interact_poly() elif cb.key in ['S', 's']: # --- 'S': new spline Interact.mode = Interact_spli() # --------------------------------- Zooming -------------------------------- if cb.key in ['+', '=']: # --- zoom in inset.setbox(frame.zoombox) # trick Set object ... hwx = max(2.0, abs(inset.bhi[0]-inset.blo[0])/4.0) hwy = max(2.0, abs(inset.bhi[1]-inset.blo[1])/4.0) frame.zoombox = "%d %d %d %d" % (int(cb.x-hwx), int(cb.y-hwy), int(cb.x+hwx), int(cb.y+hwy)) inset.setbox(frame.defbox) # ... untrick frame.draw() elif cb.key in ['-', '_']: # --- zoom out inset.setbox(frame.zoombox) # trick Set object ... hwx = (inset.bhi[0]-inset.blo[0]) hwy = (inset.bhi[1]-inset.blo[1]) cx = (inset.bhi[0]+inset.blo[0])/2.0 cy = (inset.bhi[1]+inset.blo[1])/2.0 box = (int(cx-hwx), int(cy-hwy), int(cx+hwx), int(cy+hwy)) frame.zoombox = "%d %d %d %d" % box inset.setbox(frame.defbox) # ... untrick frame.draw() elif cb.key in ['9', '(']: # --- pan inset.setbox(frame.zoombox) # trick Set object ... hwx = abs(inset.bhi[0]-inset.blo[0])/2.0 hwy = abs(inset.bhi[1]-inset.blo[1])/2.0 frame.zoombox = "%d %d %d %d" % (int(cb.x-hwx), int(cb.y-hwy), int(cb.x+hwx), int(cb.y+hwy)) inset.setbox(frame.defbox) # ... untrick frame.draw() elif cb.key=='0': # --- zoom back frame.zoombox = frame.defbox frame.draw() elif cb.button==1 and cb.state==8: # --- start zoom rectangle cb.px, cb.py = cb.x, cb.y elif cb.button==0 and cb.state==(1+8): # --- adjust zoom rectangle frame.update() pgsfs(2) pgrect(cb.px, cb.x, cb.py, cb.y) pgsfs(4) elif cb.button==1 and cb.state==(1+8): # --- finish zoom rectangle xlo, ylo = min(cb.px, cb.x), min(cb.py, cb.y) xhi, yhi = max(cb.px, cb.x), max(cb.py, cb.y) frame.zoombox = "%f %f %f %f" % (xlo, ylo, xhi, yhi) frame.draw() # ----------------------------- Miscellanea --------------------------------- elif cb.key in ['H', 'h']: # --- hide/unhide shapes wkey("HIDE=%s" % ['YES','NO'][userlog("HIDE=")]) elif cb.key=='\xd1': wkey('PREVIOUS=Y') elif cb.key=='\xd3': wkey('NEXT=Y') # -------------------------- Value and Position ----------------------------- if cb.state==0 and\ cb.button==0 and\ cb.x>inset.blo[0] and\ cb.xinset.blo[1] and\ cb.y') last = vp3.Button('LAST=', 'move to last frame').setLabel('>>') nsub = vp3.Label(' ') poslabel = vp3.Label(' ') shapelabel = vp3.Label(' ') outsidelb1 = vp3.Label('Transfer data') outsidebtn = vp3.Button('OUTSIDE=', 'Blot mode').setLabel(' ??? ') outsidelb2 = vp3.Label('mask.') modelabel = vp3.Label('Default shape mode: ') modebutton = vp3.Button('ADDSUB=', 'Add to or subtract from mask').setLabel('ADD') outsettf = vp3.TextField('OUTSET=', 'Name of output set', 15).setLabel('Outset:') outsetlb = vp3.Label('No current outset.') frame.setPosition(0, None, 0, None) first.setPosition(0, frame, 0, None) previous.setPosition(0, first, 0, None) next.setPosition(0, previous, 0, None) last.setPosition(0, next, 0, None) nsub.setPosition(5, last, 0, None) poslabel.setPosition(0, None, 0, first) outsidelb1.setPosition(0, None, 0, poslabel) outsidebtn.setPosition(0, outsidelb1, 0, poslabel) outsidelb2.setPosition(0, outsidebtn, 0, poslabel) modelabel.setPosition(0, None, 10, outsidebtn) modebutton.setPosition(0, modelabel, 10, outsidebtn) shapelabel.setPosition(0, None, 0, modebutton) outsettf.setPosition(0, None, 0, shapelabel) outsetlb.setPosition(0, None, 0, outsettf) # ---------------------------------------------------------------------------- # viewport 4 contents # ---------------------------------------------------------------------------- messagelb = vp4.Label(' ') messagelb.setPosition(0, None, 0, None) # ---------------------------------------------------------------------------- # viewport 5 contents # ---------------------------------------------------------------------------- hidebutton = vp5.Button('HIDE=', 'Hide/Show shapes') applybtn = vp5.Button('APPLY=', 'Apply mask to outset').active(False) savebtn = vp5.Button('SAVE=', 'Save shapes in inset') autobtn = vp5.Button('AUTOSAVE=', 'Every minute: save all shapes') logo = vp5.Logo() hidebutton.setPosition(0, None, 0, None) applybtn.setPosition (0, None, 0, hidebutton) savebtn.setPosition (0, None, 0, applybtn) autobtn.setPosition (0, None, 0, savebtn) logo.setPosition (0, None, vp3.height-logo.height-10, None) # ---------------------------------------------------------------------------- # event handler registration # ---------------------------------------------------------------------------- KeyCallback(file_cb, 'FILE=') KeyCallback(edit_cb, 'EDIT=') KeyCallback(inset_cb, 'SET=', info=nsub, outside=outsidebtn) KeyCallback(box_cb, 'BOX=') KeyCallback(frame_cb, 'FRAME=') KeyCallback(viewmode_cb, 'DPYMODE=') KeyCallback(intp_cb, 'INTERPOL=') KeyCallback(aspr_cb, 'ASPR=') KeyCallback(labax_cb, 'LABAX=') KeyCallback(new_cb, 'NEW=') KeyCallback(addsub_cb, 'ADDSUB=', button=modebutton, mode=False) KeyCallback(outside_cb, 'OUTSIDE=', button=outsidebtn, mode=False) KeyCallback(hatch_cb, 'HATCH=') KeyCallback(hide_cb, 'HIDE=') KeyCallback(clip_cb, 'CLIP=') KeyCallback(stepper_cb, 'FIRST=', end=0) KeyCallback(stepper_cb, 'PREVIOUS=', end=None, incr=-1) KeyCallback(stepper_cb, 'NEXT=', end=None, incr=+1) KeyCallback(stepper_cb, 'LAST=', end=1) KeyCallback(outset_cb, 'OUTSET=', apply=applybtn, label=outsetlb) KeyCallback(apply_cb, 'APPLY=') KeyCallback(save_cb, 'SAVE=') KeyCallback(autosave_cb, 'AUTOSAVE=') plotf.CursorCallback(cursor_cb, shape=None) # ---------------------------------------------------------------------------- # create and initialize some objects # ---------------------------------------------------------------------------- frame = Frame(plotf) frame.info = poslabel # where frame object shows subset position frame.shinfo = shapelabel # where frame object shows shape info Interact.info = shapelabel # where Interact class shows shape info Interact.mode = Interact() # start with default interaction # ---------------------------------------------------------------------------- # initialize some keywords # ---------------------------------------------------------------------------- triggerkey('ADD=', '0') triggerkey('INTERPOL=', 'NO') triggerkey('ASPR=', 'NO') triggerkey('LABAX=', 'NO') triggerkey('HATCH=', '2.0') triggerkey('AUTOSAVE=', 'NO') # ---------------------------------------------------------------------------- # Action! # ---------------------------------------------------------------------------- mainloop()