""" python/ui/Annotation.py: CCP4MG Molecular Graphics Program Copyright (C) 2001-2008 University of York, CCLRC Copyright (C) 2009-2010 University of York This library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 3, modified in accordance with the provisions of the license to address the requirements of UK law. You should have received a copy of the modified GNU Lesser General Public License along with this library. If not, copies may be downloaded from http://www.ccp4.ac.uk/ccp4license.php This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. """ import dataobj from global_definitions import * #------------------------------------------------------------------------ #------------------------------------------------------------------------ #------------------------------------------------------------------------ class Annotation(dataobj.DispObj): #------------------------------------------------------------------------ #------------------------------------------------------------------------ #------------------------------------------------------------------------ class_dependents = {} def __init__(self,parent='',visible=1,name='', \ params = {},restore_from_version=0,**keywords): # Set defaults # 'colour' : 'complement', # 'font' : {} font = FONTMANAGER().getHtmlFont('annotation') pars = { 'text' : 'Annotation', 'position' : [0.0,0.0,0.0], 'centered': False, 'atom_position' : '' } # update from arguments pars.update(params) pars.update(keywords) # Check for pre-2.0 named parameters if pars.has_key('selection'): pars['text'] = pars['selection'] del pars['selection'] if pars.has_key('style'): pars['position'] = pars['style'][0:3] pars['atom_position'] = pars['style'][3] del pars['style'] # !!! HANDLE OLD FONT/COLOUR if pars.has_key('colour'): pass if pars.has_key('font'): pass dataobj.DispObj.__init__(self,'Annotation',name,parent=parent, \ visible=visible,params=pars ) self.delta = [0.0,0.0,0.0] self.extent = ['-5.0','5.0'] self.moving = 0 # Keep list of Text objects self.graph_objects = [] # update params based on input params self.set_text(text=self.text) self.set_position(atom_position=self.atom_position) self.update_dependents('create') #----------------------------------------------------------------------- def get_text_label(self): #----------------------------------------------------------------------- import ParseHTMLTextString parser = ParseHTMLTextString.MyHTMLParser() parser.feed(str(self.text)) data = parser.getAllData().strip().replace('\n',' ') return data[:min(15,len(data))] def get_selection_label(self): return self.get_text_label() #----------------------------------------------------------------------- def get_position(self): #----------------------------------------------------------------------- return self.position #----------------------------------------------------------------------- def get_position_label(self): #----------------------------------------------------------------------- if self.atom_position: return self.atom_position else: return '%.1f'%self.position[0]+' '+'%.1f'%self.position[1]+ \ ' '+'%.1f'%self.position[2] #----------------------------------------------------------------------- def set_text(self,text=''): #----------------------------------------------------------------------- self.text=text self.do_redraw = 2 #------------------------------------------------------------------- def transform(self,glwidget): #------------------------------------------------------------------- ''' Handle mouse input to translate objects ''' if glwidget.transformDeltaMode() == 'translate': dx,dy,dz = glwidget.worldTranslate() #print "Annotation.transform", dx,dy,dz self.set_position(dx=dx,dy=dy,dz=dz) #---------------------------------------------------------------------- def set_position(self,atom_position='',x='',y='',z='', dx='',dy='',dz='',zero=0,**keywords): #---------------------------------------------------------------------- ''' x,y,z are world coords to set position of annotation dx,dy,dz are delta screen coords to apply to existing postion ''' # Sort out the 'old' position - i.e. position before # application of any delta - is in world frame if zero or not self.position: xold,yold,zold = 0.0,0.0,0.0 else: xold,yold,zold = self.position if atom_position != '': rv = self.parent.get_centre(atom_position) #print 'set_position get_centre',rv if not rv[0]: xold,yold,zold = rv[1] self.atom_position = atom_position if x != '': xold = float(x) if y != '': yold = float(y) if z != '': zold = float(z) #print "Annotation.set_position old x,y,z",xold,yold,zold # Make sure deltas are converted to float or # are set to zero - deltas are in screen frame ddx,ddy,ddz = 0.0,0.0,0.0 if dx: ddx = float(dx) if dy: ddy = float(dy) if dz: ddz = float(dz) self.delta = [ddx,ddy,ddz] self.atom_position = '' #print "delta ", self.delta self.position = [ xold+ddx, yold+ddy,zold+ddz] self.do_redraw = max(self.do_redraw,1) #---------------------------------------------------------------- def handle_moving_data(self,attribute='',master='',**keywords): #---------------------------------------------------------------- #print "Annotation handle_moving_data",attribute self.do_redraw = 1 #------------------------------------------------------------------ def unthreadedDraw (self ): #------------------------------------------------------------------ #print "Annotation draw do_redraw", self.do_redraw,self.position # Recolour requires redraw # Put all drawing in the label_graphmod object since it is text and must be drawn in # unthreaded mode if not self.label_graphmod: import graphicsmodel self.label_graphmod = graphicsmodel.graphicsmodel( ) BUILD().append(self.label_graphmod) self.do_redraw = 2 if self.do_redraw > 1: # Delete all of the text objects from graphmod if len(self.graph_objects)>0 and self.label_graphmod: import cprim for graph_object in self.graph_objects: #print "deleting ",graph_object,'from',obj.graphmod cprim.DeleteTextLabel(self.label_graphmod.obj,graph_object.GetID()) self.graph_objects = [] self.create_annotation() elif self.do_redraw: if self.graph_objects: import pygl_coord self.graph_objects[0].SetVertices([pygl_coord.Cartesian(self.position[0],self.position[1],self.position[2])]) self.graph_objects[0].SetCentered(bool(self.centered)) self.do_rebuildGL.append('label_graphmod') self.do_redraw = 0 return 1 #----------------------------------------------------------------- def create_annotation(self): #------------------------------------------------------------------ import cprim,pygl_coord xyz = [] qmat = MAINWINDOW().glWidgets[0].quat.getInvMatrix() cart = pygl_coord.Cartesian(self.delta[0],self.delta[1],self.delta[2]) cartnew = qmat * cart atomxyz = [0.0,0.0,0.0] if self.atom_position: rv = self.parent.get_centre(self.atom_position) if not rv[0]: atomxyz = rv[1] self.position = [ cartnew.get_x()+self.position[0], \ cartnew.get_y()+self.position[1], \ cartnew.get_z()+self.position[2] ] pos1 = pygl_coord.Cartesian(self.position[0]+atomxyz[0], self.position[1]+atomxyz[1], self.position[2]+atomxyz[2]) pos2 = pygl_coord.Cartesian(self.position[0]+atomxyz[0], self.position[1]+atomxyz[1], self.position[2]+atomxyz[2]) text = self.text #print 'Annotation.create_annotation',text import TextLabel label_ob = TextLabel.CreateTextLabel(text,pos1,pos2) label_ob.thisown = 0 label_ob.SetCentered(bool(self.centered)) self.label_graphmod.obj.add_text_primitive(label_ob) self.graph_objects.append(label_ob) self.label_graphmod.obj.rebuild() self.do_redraw = 0 self.delta = [0.0,0.0,0.0] #----------------------------------------------------------------------- def centre_on(self,**keywords): #----------------------------------------------------------------------- import build atomxyz = [0.0,0.0,0.0] if self.atom_position: rv = self.parent.get_centre(self.atom_position) if not rv[0]: atomxyz = rv[1] xyz = [] for i in range(0,3): xyz.append(self.position[i]+atomxyz[i]) BUILD().glthread.glevent.centre_on(xyz,self.label_graphmod.obj) #---------------------------------------------------------------------- def delete(self,**keywords) : #----------------------------------------------------------------------- win = MAINWINDOW() if self.label_graphmod: win.removeGLDisplayObject(self.label_graphmod) BUILD().deletemod(self.label_graphmod) del self.label_graphmod dataobj.DispObj.delete(self) #------------------------------------------------------------------ def params(self,all=1): #------------------------------------------------------------------ pars = dataobj.DispObj.params(self) for item in ['text','position','atom_position','centered']: pars[item]=getattr(self,item,'') return pars #------------------------------------------------------------------ def movie_interpolation(self,initial_status=None,final_status=None, \ fraction=0.0,step=0,**keywords): #------------------------------------------------------------------ pkey = 'position' if initial_status and initial_status.params.has_key(pkey) and \ final_status and final_status.params.has_key(pkey): initial = initial_status.params[pkey] final = final_status.params[pkey] delta = [] for i in range(0,3): delta.append(float(final[i])-float(initial[i])) #print 'Annotation movie_interpolation delta',delta self.set_position(x = float(initial[0])+fraction*delta[0],\ y = float(initial[1])+fraction*delta[1], \ z = float(initial[2])+fraction*delta[2]) dataobj.DispObj.movie_interpolation(self,initial_status=initial_status, \ final_status=final_status,fraction=fraction,step=step) #------------------------------------------------------------------ def update_data_status(self,shadowdisp): #------------------------------------------------------------------ import utils diffs = utils.dict_diffs(self.params(),shadowdisp.params)[1] if not diffs: return [] rv = 0 if diffs.has_key('text'): rv = 1 self.set_text(shadowdisp.params.get('text')) if diffs.has_key('position') or diffs.has_key('atom_position'): xyz = shadowdisp.params.get('position') self.set_position(atom_position = shadowdisp.params.get('atom_position'), x= xyz[0],y=xyz[1],z=xyz[2]) rv = max(rv,dataobj.DispObj.update_data_status0(self,shadowdisp)) if rv: self.update_gui.append(['update']) return rv #--------------------------------------------------------------------------------- def createAnnotationParamsManager(): #--------------------------------------------------------------------------------- import services # This is used by annotationGui.annotateFormatWidget which provides # a gui to edit the format pm = services.ParamsManager ( name="annotation_format", help="twoDobjects", title='Annotation format', gui=[], default = { 'format' : [['','Res name'],[' ','Chain id'],['','Seq #']] }, definition = { 'format' : {} } ) return pm