Hello

On 02/09/2016 11:35 PM, Andreas Tille wrote:
Hi Michel,

thanks for the attempt to help.  To answer your question from the other
mail: In Debian we need to build from source and build against the
current development tools - thus the usage of higher Tcl/Tk version.
(Just a personal remark: I think there are better GUI tools available
for Python than Tcl/Tk - but that's just a side note and I have not
investigated how much work droping Tcl/Tk might create).
We actually stopped all TK-based developments and have started writing
the next generation tools based on Qt. These tools will be much more user friendly up to date and efficient, but unfortunately they do not yet provide the level
of functionality and stability needed to replace the existing AutoDockTools.

Regarding your attached file:  I tried to test it but I realised that we
are running into another issue first:

$ autodocktools
Run ADT from  /usr/lib/python2.7/dist-packages/AutoDockTools
Traceback (most recent call last):
   File "/usr/lib/python2.7/dist-packages/AutoDockTools/__init__.py", line 420, 
in runADT
     from mglutil.splashregister.splashscreen import SplashScreen
   File "/usr/lib/python2.7/dist-packages/mglutil/splashregister/splashscreen.py", 
line 7, in <module>
     from mglutil.util.misc import ensureFontCase
   File "/usr/lib/python2.7/dist-packages/mglutil/util/misc.py", line 19, in 
<module>
     import numpy.oldnumeric as Numeric
ImportError: No module named oldnumeric
hit enter to continue
This is the very reason we gave up on trying to use system wide packages and bundle up a self-consistent Python interpreter, python packages and libraries. Some third party packages we have been using sometime require a specific version of a python package and we have no choice other than using this specific version. IHMO this is bound to happen when you integrate a large number of software packages and you do not have control
over all of them.

For the new generation of our tools we already got rid of all Numeric references but this was not done for AutoDockTools which is out-of-date and not easy to maintain. However it has a large user base and the Tk version still is, as of today, the official stable version. So I will put one of my programmers on the project to update AutoDockTools to use numpy.

I hope this is the only instance left where we run into this kind of problems

-Michel


I think the following files are affected by this issue:

$ grep -Rw oldnumeric | grep -v '#.*oldnumeric'
AutoDockTools/AutoDockBondClassifier.py:    import numpy.oldnumeric as Numeric, 
math
AutoDockTools/autogpfCommands.py:import numpy.oldnumeric as Numeric
AutoDockTools/autogpfCommands.py:import numpy.oldnumeric as Numeric
AutoDockTools/histogram.py:import numpy.oldnumeric as Numeric; N = Numeric
AutoDockTools/Conformation.py:import numpy.oldnumeric as Numeric
AutoDockTools/pixelMap2D.py:import Image, numpy.oldnumeric as Numeric
AutoDockTools/pixelMap2D.py:    import numpy.oldnumeric as Numeric
AutoDockTools/Tests/test_PyAutoDock.py:import numpy.oldnumeric as Numeric
AutoDockTools/Utilities24/prepare_dpf42.py:from numpy import oldnumeric as 
Numeric
AutoDockTools/Utilities24/compute_interatomic_distance_per_vina_pose.py:import 
numpy.oldnumeric as Numeric
AutoDockTools/Utilities24/summarize_docking_directory.py:import 
numpy.oldnumeric as Numeric
AutoDockTools/Utilities24/prepare_covalent_flexres.py:    import 
numpy.oldnumeric as Numeric
AutoDockTools/Utilities24/rotate_molecule.py:import numpy.oldnumeric as Numeric
AutoDockTools/Utilities24/summarize_epdb_results4.py:from numpy import 
oldnumeric as Numeric
AutoDockTools/Utilities24/summarize_wcg_docking.py:import os, glob, 
numpy.oldnumeric as Numeric
AutoDockTools/Utilities24/compute_rms_between_methods.py:import 
numpy.oldnumeric as Numeric
AutoDockTools/Utilities24/write_clustering_histogram_postscript.py:import os, 
glob, Tkinter, numpy.oldnumeric as Numeric
AutoDockTools/Utilities24/compute_consensus_maps_from_dlgs.py:import os, glob, 
numpy.oldnumeric as Numeric, math
AutoDockTools/Utilities24/score_atoms_by_component.py:from numpy import 
oldnumeric as Numeric
AutoDockTools/Utilities24/compute_rms_between_conformations.py:import 
numpy.oldnumeric as Numeric
AutoDockTools/Utilities24/summarize_results_vif.py:from numpy import oldnumeric 
as Numeric
AutoDockTools/Utilities24/compute_interatomic_distance_per_pose.py:import 
numpy.oldnumeric as Numeric
AutoDockTools/Utilities24/summarize_time.py:import os, glob, numpy.oldnumeric 
as Numeric
AutoDockTools/AutoLigand.py:    from numpy.oldnumeric import zeros
AutoDockTools/autoanalyzeCommands.py:import numpy.oldnumeric as Numeric, math
AutoDockTools/autodpfCommands.py:import os, numpy.oldnumeric as Numeric
AutoDockTools/DlgParser.py:import numpy.oldnumeric as Numeric
AutoDockTools/autoflexCommands.py:import numpy.oldnumeric as Numeric
AutoDockTools/autotorsCommands.py:import numpy.oldnumeric as Numeric
AutoDockTools/DlgFilters.py:from numpy import oldnumeric as Numeric
AutoDockTools/cluster.py:import numpy.oldnumeric as Numeric
AutoDockTools/pyAutoDockCommands.py:import Tkinter, numpy.oldnumeric as 
Numeric, Pmw
AutoDockTools/GridParameters.py:import numpy.oldnumeric as Numeric
AutoDockTools/ConfPlayer.py:import numpy.oldnumeric as Numeric
AutoDockTools/InteractionDetector.py:from numpy import oldnumeric as Numeric
AutoDockTools/InteractionDetector.py:import numpy.oldnumeric as Numeric
AutoDockTools/LigandMixin.py:import numpy.oldnumeric as Numeric, math, types, os
AutoDockTools/cluster_ad.py:import numpy.oldnumeric as Numeric
AutoDockTools/energyCalculator.py:import numpy.oldnumeric as Numeric
AutoDockTools/MoleculePreparation.py:import numpy.oldnumeric as Numeric, math


As far as I dived into a websearch the needed replacements are not
really complex but I would consider it more sensible if you do it
right on your side to be prepared for latest numpy.

Kind regards

       Andreas.

On Tue, Feb 09, 2016 at 04:23:36PM -0800, Michel Sanner wrote:
Steffen


could you please check is replacing the file
mglutil/gui/BasicWidgets/Tk/vector3DGUI.py with the one attached solves the
problem ?

Thanks

On 12/29/2015 05:00 PM, Steffen Möller wrote:
Hello Michel, hello Stefano,

nice to hear from you, indeed. I happen to be a recent El Capitan user
myself and thus
can help testing on that front, too.

I was not aware of a release of 1.5.7, which I had seen only as a RC1,
using the
information shown on
http://mgltools.scripps.edu/downloads
The problem should manifest itself on any platform with TclTk 8.6 onwards.
Until a few seconds ago I had truly thought that you were working on
something
completely different already that would be released once it is ready and as
such you did not notice/care about that "works with 8.5" problem.

How shall we proceed? I propose that we get the code base and tools in sync
and I prepare an update of the Debian packages. Is the CVS repository of
yours
still the place where to look? What version of TclTk do you work with?
Just instruct me.

Concerning the time line I am swamped till mid January. We have our next
Debian meeting in Copenhagen on the first February weekend. Would be nice to
have the bug fixed till then.

Best,

Steffen


On 29/12/15 21:29, Andreas Tille wrote:
Hi Michel,

As far as I know installing Tcl/Tk 8.6 you should be able to reproduce
the problem.  The best resource of information is probably

     
https://lists.alioth.debian.org/pipermail/pkg-tcltk-devel/2015-December/002938.html

Hope this helps

        Andreas.

On Tue, Dec 29, 2015 at 11:20:20AM -0800, Michel Sanner wrote:
Happy Holidays all

I am not aware of this bug. Could you please let me know how to reproduce it
? and of course
if you have a patch I'll be happy to incorporate it. We are working on a bug
fix release of MGLTools 1.5.7

This release has been postponed a little as we are trying to address some
issues with the newest Mac OS
El Capitan. This delay will hopefully gives us time to incorporate a bug fix
for this problem as well

-Michel

On 12/29/15 10:22 AM, Stefano Forli wrote:
Hi Steffen (and Andreas),
I hope you're having happy Holidays yourselves. I'm currently in Italy enjoying 
some time with family.
No worries about bothering, you're all doing us a huge favor, so we're always 
in debt.

I'm CC'ing Michel in the conversation, since he's in charge of the source code.
I got bit by these issues with Tcl with the old Raccoon version you packaged, 
but I wasn't aware of the problems with the main package AutoDockTools.
If you think it is something that can be solved with a reasonable amount of 
patches, I believe there's no problem in adding them to our CVS (but I'll let 
Michel chip in about this).

I'll be happy to test the patched code, if you have any.

Thanks!

S


--

  Stefano Forli, PhD

  Assistant Professor of Integrative
  Structural and Computational Biology,
  Molecular Graphics Laboratory

  Dept. of Integrative Structural
   and Computational Biology, MB-112F
  The Scripps Research Institute
  10550  North Torrey Pines Road
  La Jolla,  CA 92037-1000,  USA.

     tel: +1 (858)784-2055
     fax: +1 (858)784-2860
     email: fo...@scripps.edu
     http://www.scripps.edu/~forli/
________________________________________
From: Steffen Möller [steffen_moel...@gmx.de]
Sent: Tuesday, December 29, 2015 12:55 AM
To: Andreas Tille; Stefano Forli
Subject: That long-standing nasty Tcl/Tk-bug with autodocktools Re: Bitte 
weiterleiten (Re: [Pkg-tcltk-devel] Tcl/Tk help needed (Was: Bug#767145: 
autodocktools: fails to start the GUI))

Hi Stefano,

some merry Christmas I hope you had and all the best for the New Year,
of course. The inter-annual time (as we say over here) is most likely
the most productive in the Open Source world :) Please forgive me
contacting you during all these festivities.

I admit to know about this Tcl bug for some time, and I had even kind of
traced it down: the autodocktools do not pack their widgets right, i.e.
they are missing absolute and relative positions. Later versions than
8.5 are apparently no longer tolerating it, and 8.6 is no longer any
recent version, I am afraid. Andreas is about to remove the package from
the distro as it is unusable as it is.

How are your feelings about it all? Would you accept patches? Is there
something in your CVS that we should address, instead?

All the best possible wishes

Steffen

On 29/12/15 08:40, Andreas Tille wrote:
Hi Steffen,

kannst Du das bitte mal an die Autoren weiterleiten (und den Bug in CC
setzen).  Ansonsten lasse ich das Paket entfernen, weil es ja
offensichtlich zu nichts nütze ist, wenn es nicht mal startet.

Viele Grüße

         Andreas.

----- Forwarded message from Sergei Golovan <sgolo...@nes.ru> -----

Date: Thu, 24 Dec 2015 10:52:27 +0300
From: Sergei Golovan <sgolo...@nes.ru>
To: Andreas Tille <andr...@an3as.eu>
Cc: Senthil Kumaran <style...@gmail.com>, 767...@bugs.debian.org, Tcl/Tk Debian 
Packagers <pkg-tcltk-de...@lists.alioth.debian.org>
Subject: Re: [Pkg-tcltk-devel] Tcl/Tk help needed (Was: Bug#767145: 
autodocktools: fails to start the GUI)

Hi Andreas,

On Wed, Dec 23, 2015 at 11:42 PM, Andreas Tille <andr...@an3as.eu> wrote:
Hi Tcl/Tk packaging team,

unfortunately I got no help on debian-mentors and since we somehow need
to tackle bug  #767144 I wonder if you Tcl/Tk experts might be able to
provide some help.
As far as I can see, you've stumbled on the change between Tcl/Tk 8.5
and 8.6. In Tcl/Tk 8.5 one could mix grid and pack geometry managers
in one master window. It often works but sometimes leads to
unpredictable results, sometimes an application which does that just
hangs. In Tcl/Tk 8.6 this mixing of grid and pack was explicitly
forbidden, hence this error message.

I don't think that there is an easy way to fix this. You can't just
revert to using Tcl/Tk 8.5 because Tkinter in Debian is already
switched to Tk 8.6 (and I guess using custom Tkinter is not an
option). So, one has to carefully find all mixed up packs and grids
and make sure that only one of them is used in every particular master
window. In plain Tcl/Tk I'd override the [pack] and [grid] routines to
print some debug information (something like

rename pack pack:orig
proc pack {args} {
     puts stderr "pack: [info level -1] $args"
     pack:orig {*}$args
}

and similar for grid). This would help to trace where exactly the
mixed geometry master windows appear. I don't know how you can do
something similar in Python, but I'm pretty sure it's possible.

Cheers!
--

-----------------------------------------------------------------------
    o
   /   Michel F. Sanner Ph.D.            The Scripps Research Institute
o     Associate Professor               Department of Molecular Biology
   \                                     10550 North Torrey Pines Road
    o  Tel. (858) 784-7742               La Jolla, CA 92037, TPC 26
   /   Fax. (858) 784-2341
o     san...@scripps.edu                http://www.scripps.edu/~sanner
-----------------------------------------------------------------------


--

-----------------------------------------------------------------------
    o
   /    Michel F. Sanner Ph.D.            The Scripps Research Institute
o      Associate Professor               Department of Molecular Biology
   \                                      10550 North Torrey Pines Road
    o   Tel. (858) 784-7742               La Jolla, CA 92037, TPC 26
   /    Fax. (858) 784-2341
o      san...@scripps.edu                http://www.scripps.edu/~sanner
-----------------------------------------------------------------------

## Automatically adapted for numpy.oldnumeric Jul 23, 2007 by

#########################################################################
#
# Date: Nov 2001 Authors: Michel Sanner, Daniel Stoffler
#
#    san...@scripps.edu
#    stoff...@scripps.edu
#
# Copyright: Michel Sanner, Daniel Stoffler and TSRI
#
#########################################################################

import Tkinter, numpy.oldnumeric as Numeric, string, math
from mglutil.math.rotax import rotax
from mglutil.gui.Misc.Tk.KeybdModMonitor import KeyboardModifierMonitor
from mglutil.util.callback import CallbackManager
from thumbwheel import ThumbWheel
from optionsPanel import VectorOptionsPanel

class vectorGUI(Tkinter.Frame, KeyboardModifierMonitor):

     """ This class implements a vector widget.
     The widget has a vector which can be moved within a sphere to generate
     a 3D vector. Values are normalized and stored in self.vector
     In addition, the vector can be rotated with 3 thumbwheels.
     Values can be entered directly by typing them into the 3 entry forms.
     Then, the 'normalize and set' button has to be pressed in order to
     normalize and set the new vector.

     The widget has a configure() method: vector, mode, precision and
     continuous can be set this way.
     vector is a list of 3 floating values, e.g. [0., 0., 1.]
     mode describes the axis movement (rotation around an axis): is type
     string and can be either 'X', 'Y' or 'Z'. Free movement (standard
     value) is 'XY'.
     continuous can be either 0 (or None) or 1. Default is 0
     precision is type int and ranges from 1 - 10
     master, name and size can be passed only to the constructor.

     a lock() method is used to disable the various gui components of the
     options panel. Usage: <instance>.lock(<component>=<value>)
     component is continuous, precision or mode. value is 0 or 1. 1 disables,
     0 enables.
     """
     def __init__(self, master=None, name='vector', size=200, continuous = 1,
                  vector=[0.0, 0.0, 1.0], mode='XY', precision=5,
                  lockContinuous=0,  lockPrecision=0, lockMode=0,
                  callback=None, labelSide='top'):
KeyboardModifierMonitor.__init__(self)

         self.callback = callback # user specified callback
         self.name=name             # title inside canvas
         self.labelSide=labelSide   # where title gets packed
        self.mode=mode             # axe mode: can be 'XY', 'X', 'Y' or 'Z'
         self.precision=precision   # floating number digits
         self.continuous=continuous # can be 1 or 0
         self.vector=vector         # initial vector value
         self.size=size             # size of vector widget

         self.lockContinuous = lockContinuous  # set to 1 to lock menus in
                                               # option panel
         self.lockPrecision = lockPrecision
         self.lockMode = lockMode

         self.r = self.size/2
         self.r2 = self.r*self.r

         self.drawShadowX = 0
         self.drawShadowY = 1
         self.drawShadowZ = 0
        self.fillShadowPlanes = 1

        Tkinter.Frame.__init__(self, master)
         Tkinter.Pack.config(self)

         self.callbacks = CallbackManager() # object to manage callback
                                         # functions. They get called with the
                                         # current value as an argument
         self.zeros = Numeric.array( (0,0,0), 's')
         self.viewingMatInv = Numeric.array(
             [[  0.96770716, -0.03229283, -0.25      ,  0.        ],
              [  0.03229283, -0.96770716,  0.25      ,  0.        ],
              [  0.25      ,  0.25      ,  0.93541437,  0.        ],
              [  0.        ,  0.        ,  0.        ,  1.        ]],'f')
         self.viewingMat = Numeric.transpose(self.viewingMatInv)
         self.createCanvas(master, size)
         self.createEntries(self.frame)
        Tkinter.Widget.bind(self.canvas, "<ButtonPress-1>", self.mouseDown)
        Tkinter.Widget.bind(self.canvas, "<ButtonRelease-1>", self.mouseUp)
        Tkinter.Widget.bind(self.canvas, "<B1-Motion>", self.mouseMove)

         self.setEntries()

         self.opPanel = VectorOptionsPanel(master = self,
                                           title="Vector GUI Options")
         Tkinter.Widget.bind(self.canvas, "<Button-3>", self.toggleOptPanel)

         if self.callback:
             self.callbacks.AddCallback(self.callback)


     def toggleOptPanel(self, event=None):
         # opens and closes options panel by right clicking on widget
         if self.opPanel.flag:
            self.opPanel.Dismiss_cb()
         else:
             if not hasattr(self.opPanel, 'optionsForm'):
                 self.opPanel.displayPanel(create=1)
             else:
                 self.opPanel.displayPanel(create=0)
     def mouseUp(self, event):
         if not self.continuous:
             self.callbacks.CallCallbacks(self.vector)

        
     def mouseDown(self, event):
        # remember where the mouse went down
         xc = event.x - self.xm
         yc = self.ym - event.y
         # compute the intersection point between
         z2 = self.r2-(xc*xc)-(yc*yc)

         if z2>=0: # we picked inside the sphere. going for a XY rotation
             self.lastPt3D = (xc, yc, math.sqrt(z2))
         else: # going for a Z rotation
             pass


     def mouseMove(self, event):
         # simple trackball, only works inside cirle
         # creates an XY rotation defined by pts intersecting the spheres
         xc = event.x - self.xm
         yc = self.ym - event.y
         # compute the intersection point between
         xc2 = xc*xc
         yc2 = yc*yc
         z2 = self.r2-xc2-yc2

         if z2 < 0:
             lInvMag = 1./math.sqrt(xc2 + yc2)
             xc *= lInvMag * (self.r)
             yc *= lInvMag * (self.r)
             z2 = 0

         # compute rotation angle
        a = self.lastPt3D
        b = (xc, yc, math.sqrt(z2))
         ang = math.acos((a[0]*b[0]+a[1]*b[1]+a[2]*b[2])/self.r2)
         if self.mode=='XY':
            #compute rotation axis
             rotaxis = Numeric.array( (a[1]*b[2] - a[2]*b[1],
                                  a[2]*b[0] - a[0]*b[2],
                                  a[0]*b[1] - a[1]*b[0] ), 'f' )
         elif self.mode=='X': rotaxis = Numeric.array( (1.,0.,0.), 'f')
         elif self.mode=='Y': rotaxis = Numeric.array( (0.,1.,0.), 'f')
         elif self.mode=='Z': rotaxis = Numeric.array( (0.,0.,1.), 'f')
         mat = rotax( self.zeros, rotaxis, ang )
         self.lastPt3D = b
         self.updateVector(mat)


     def updateVector(self, mat):
         mat = Numeric.reshape(mat, (4,4))
         newPts = self.vector + [1]
         newPts = Numeric.dot( [newPts], mat )[0]
         self.vector = [newPts[0], newPts[1], newPts[2]]
         self.setEntries()
         self.drawVector()
         if self.continuous:
             self.callbacks.CallCallbacks(self.vector)
def drawVector(self):
         coords3D = self.vector + [1]
        # apply viewing transformation to vector
         newPtsWithView = Numeric.dot( [coords3D],
                                                  self.viewingMat)[0]
        # compute 2D projection of vector (broken on 2 segments for
        # depth cueing
         x1 = self.xm+int(newPtsWithView[0]*(self.xm))
         y1 = self.ym+int(newPtsWithView[1]*(self.ym))

        # change vector's segments coordinates
         self.canvas.coords(self.lId1, self.xm, self.ym, x1, y1)

        # update vector shadows
        # Y=0 plane
        if self.drawShadowY:
            pt = [coords3D[0], 0, coords3D[2], 1.]
            newPtsWithView = Numeric.dot( [pt], self.viewingMat)[0]
            xm = self.xm+int(newPtsWithView[0]*(self.xm))
            ym = self.ym+int(newPtsWithView[1]*(self.ym))
            if self.fillShadowPlanes:
                self.canvas.coords(self.shadowPY,self.xm,self.ym,xm,ym,x1,y1)
            self.canvas.coords(self.shadowY,self.xm,self.ym,xm,ym,x1,y1)

        # X=0 plane
        if self.drawShadowX:
            pt = [0, coords3D[1], coords3D[2], 1.]
            newPtsWithView = Numeric.dot( [pt], self.viewingMat)[0]
            xm = self.xm+int(newPtsWithView[0]*(self.xm))
            ym = self.ym+int(newPtsWithView[1]*(self.ym))
            if self.fillShadowPlanes:
                self.canvas.coords(self.shadowPX,self.xm,self.ym,xm,ym,x1,y1)
            self.canvas.coords(self.shadowX, self.xm, self.ym, xm, ym, x1,y1)

        # Z=0 plane
        if self.drawShadowZ:
            pt = [coords3D[0], coords3D[1], 0, 1.]
            newPtsWithView = Numeric.dot( [pt], self.viewingMat)[0]
            xm = self.xm+int(newPtsWithView[0]*(self.xm))
            ym = self.ym+int(newPtsWithView[1]*(self.ym))
            if self.fillShadowPlanes:
                self.canvas.coords(self.shadowPZ,self.xm,self.ym,xm,ym,x1,y1)
            self.canvas.coords(self.shadowZ, self.xm, self.ym, xm, ym, x1,y1)

        if self.vector[0]<0.0:
            self.canvas.tag_raise('verticalCircle', 'moving')
        else:
            self.canvas.tag_lower('verticalCircle', 'moving')

        if self.vector[1]<0.0:
            self.canvas.tag_raise('horizontalCircle', 'moving')
        else:
            self.canvas.tag_lower('horizontalCircle', 'moving')

        if self.vector[2]<0.0 or self.vector[1]<0.0:
            self.canvas.tag_raise('axis', 'moving')
        else:
            self.canvas.tag_lower('axis', 'moving')


     def thumbx_cb(self, events=None):
         val=self.thumbx.value

##          valX=self.thumbx.value
##          valY=self.thumby.value
##          valZ=self.thumbz.value

##          n = math.sqrt(valX*valX+valY*valY+valZ*valZ)
##          if n == 0.0: v = [0.0, 0.0, 1.0]
##          else: v = [valX/n, valY/n, valZ/n]
##          val = v[0]

        rot = Numeric.zeros( (4,4), 'f' )
         rot[0][0] = 1.0
         rot[1][1] = math.cos(val)
         rot[1][2] = -math.sin(val)
         rot[2][1] = math.sin(val)
         rot[2][2] = math.cos(val)
         self.updateVector(rot)

     def thumby_cb(self, events=None):
         val=self.thumby.value
        rot = Numeric.zeros( (4,4), 'f' )
         rot[0][0] = math.cos(val)
         rot[0][2] = -math.sin(val)
         rot[1][1] = 1.0
         rot[2][0] = math.sin(val)
         rot[2][2] = math.cos(val)
         self.updateVector(rot)


     def thumbz_cb(self, events=None):
         val=self.thumbz.value
        rot = Numeric.zeros( (4,4), 'f' )
         rot[0][0] = math.cos(val)
         rot[0][1] = -math.sin(val)
         rot[1][0] = math.sin(val)
         rot[1][1] = math.cos(val)
         rot[2][2] = 1.0
         self.updateVector(rot)


     def entryX_cb(self, event=None):
         val = self.entryXTk.get()
         if len(val) == 0: val = self.vector[0]
         try:
             val = float(val)
             self.entryXTk.set(self.thumbx.labelFormat%val)
         except ValueError:
             # put back original value if someone types garbage
             self.entryXTk.set(self.thumbx.labelFormat%self.vector[0])


     def entryY_cb(self, event=None):
         val = self.entryYTk.get()
         if len(val) == 0: val = self.vector[1]
         try:
             val = float(val)
             self.entryYTk.set(self.thumby.labelFormat%val)
         except ValueError:
             # put back original value if someone types garbage
             self.entryYTk.set(self.thumby.labelFormat%self.vector[1])


     def entryZ_cb(self, event=None):
         val = self.entryZTk.get()
         if len(val) == 0: val = self.vector[2]
         try:
             val = float(val)
             self.entryZTk.set(self.thumbz.labelFormat%val)
         except ValueError:
             # put back original value if someone types garbage
             self.entryZTk.set(self.thumbz.labelFormat%self.vector[2])


     def entryV_cb(self, event=None):
         v = self.entryVTk.get()
         try: val = string.split(v)
         except:
             self.setEntries()
             return

         if val is None or len(val)!= 3:
             self.setEntries()
             return

         try:
             valX = float(val[0])
             valY = float(val[1])
             valZ = float(val[2])
         except:
             self.setEntries()
             return

         # compute normalized vector
         n = math.sqrt(valX*valX+valY*valY+valZ*valZ)
         if n == 0.0: v = [0.0, 0.0, 1.0]
         else: v = [valX/n, valY/n, valZ/n]
         self.vector = v
         self.setEntries()
         self.drawVector()
         if self.continuous:
             self.callbacks.CallCallbacks(self.vector)

     def setButton_cb(self, event=None):
         valX = float(self.entryXTk.get())
         valY = float(self.entryYTk.get())
         valZ = float(self.entryZTk.get())

         # compute normalized vector
         n = math.sqrt(valX*valX+valY*valY+valZ*valZ)
         if n == 0.0: v = [0.0, 0.0, 1.0]
         else: v = [valX/n, valY/n, valZ/n]
         self.vector = v
         self.setEntries()
         self.drawVector()
         if self.continuous:
             self.callbacks.CallCallbacks(self.vector)
     def createEntries(self, master):
         self.f = Tkinter.Frame(master)
        #self.f.grid(column=3, rowspan=3)
def fX(): self.vector = [1.,0.,0.]; self.setEntries(); self.callbacks.CallCallbacks(self.vector)
         def fY(): self.vector = [0.,1.,0.]; self.setEntries(); 
self.callbacks.CallCallbacks(self.vector)
         def fZ(): self.vector = [0.,0.,1.]; self.setEntries(); 
self.callbacks.CallCallbacks(self.vector)
         f1 = Tkinter.Frame(master)
         f2 = Tkinter.Frame(master)
         f3 = Tkinter.Frame(master)
         f1.pack(side='top')
         f2.pack(side='top')
         f3.pack(side='top')
         lX = Tkinter.Button(master=f1, text='x', command=fX)
         lX.pack(side='left')
         lY = Tkinter.Button(master=f2, text='y', command=fY)
         lY.pack(side='left')
         lZ = Tkinter.Button(master=f3, text='z', command=fZ)
         lZ.pack(side='left')
#lX = Tkinter.Button(master=self.f, text='x', command=fX)
         #lY = Tkinter.Button(master=self.f, text='y', command=fY)
         #lZ = Tkinter.Button(master=self.f, text='z', command=fZ)
         #lX.grid(row=0, column=0)
         #lY.grid(row=1, column=0)
         #lZ.grid(row=2, column=0)

         #self.thumbx = ThumbWheel(master=self.f, width=50,
         self.thumbx = ThumbWheel(master=f1, width=50,
                                  height=20, labcfg={'text':'X:','side':'left'},
                                  wheelPad=2, oneTurn=.1, min=-1, max=1,
                                  showLabel=0, precision=5, type=float)
         self.thumbx.callbacks.AddCallback(self.thumbx_cb)
         self.thumbx.unbind("<Button-3>")
         self.thumbx.canvas.unbind("<Button-3>")
         #self.thumbx.grid(row=0, column=1)
         self.thumbx.pack(side='left')

         #self.thumby = ThumbWheel(master=self.f, width=50,
         self.thumby = ThumbWheel(master=f2, width=50,
                                  height=20, labcfg={'text':'Y:','side':'left'},
                                  wheelPad=2, oneTurn=.1, min=-1, max=1,
                                  showLabel=0, precision=5, type=float)
         self.thumby.callbacks.AddCallback(self.thumby_cb)
         self.thumby.unbind("<Button-3>")
         self.thumby.canvas.unbind("<Button-3>")
         #self.thumby.grid(row=1, column=1)
         self.thumby.pack(side='left')

         #self.thumbz = ThumbWheel(master=self.f, width=50,
         self.thumbz = ThumbWheel(master=f3, width=50,
                                  height=20, labcfg={'text':'Z:','side':'left'},
                                  wheelPad=2, oneTurn=.1, min=-1, max=1,
                                  showLabel=0, precision=5, type=float)
         self.thumbz.callbacks.AddCallback(self.thumbz_cb)
         self.thumbz.unbind("<Button-3>")
         self.thumbz.canvas.unbind("<Button-3>")
         #self.thumbz.grid(row=2, column=1)
         self.thumbz.pack(side='left')

         self.entryXTk = Tkinter.StringVar()
         #self.entryX = Tkinter.Entry(master=self.f, textvariable=self.entryXTk,
         self.entryX = Tkinter.Entry(master=f1, textvariable=self.entryXTk,
                                     width=8)
         self.entryX.bind('<Return>', self.entryX_cb)
         #self.entryX.grid(row=0, column=2)
         self.entryX.pack(side='left')

         self.entryYTk = Tkinter.StringVar()
         #self.entryY = Tkinter.Entry(master=self.f, textvariable=self.entryYTk,
         self.entryY = Tkinter.Entry(master=f2, textvariable=self.entryYTk,
                                     width=8)
         self.entryY.bind('<Return>', self.entryY_cb)
         #self.entryY.grid(row=1, column=2)
         self.entryY.pack(side='left')

         self.entryZTk = Tkinter.StringVar()
         #self.entryZ = Tkinter.Entry(master=self.f, textvariable=self.entryZTk,
         self.entryZ = Tkinter.Entry(master=f3, textvariable=self.entryZTk,
                                     width=8)
         self.entryZ.bind('<Return>', self.entryZ_cb)
         #self.entryZ.grid(row=2, column=2)
         self.entryZ.pack(side='left')

         self.entryVTk = Tkinter.StringVar()
         self.entryV = Tkinter.Entry(master, textvariable=self.entryVTk,
                                     width=18)
self.entryV.bind('<Return>', self.entryV_cb) self.f.pack(side='top', expand=1)

         self.entryV.pack()
self.setButton=Tkinter.Button(master, text='normalize and set',
                                       command = self.setButton_cb)
        self.setButton.pack(side='bottom')


     def setEntries(self):
         self.entryXTk.set(self.thumbx.labelFormat%self.vector[0])
         self.entryYTk.set(self.thumby.labelFormat%self.vector[1])
         self.entryZTk.set(self.thumbz.labelFormat%self.vector[2])

         lf = '%.3f'
         self.entryVTk.set(lf%self.vector[0]+' '+lf%self.vector[1]+' '\
                           +lf%self.vector[2])
         self.drawVector()


     def createCanvas(self, master, size=200):

         self.frame = Tkinter.Frame(self, relief = 'sunken', borderwidth=5)

         if self.name is not None:
             self.title = Tkinter.Label(self.frame, text=self.name)
             self.title.pack(side=self.labelSide)

        self.canvas = Tkinter.Canvas(self.frame, width=size, height=size)

         # set the focus so that we get keyboard events, and add callbacks
         self.canvas.bind('<KeyPress>', self.modifierDown)
         self.canvas.bind("<KeyRelease>", self.modifierUp)

         xm = self.xm = ym = self.ym = self.r
        self.canvas.create_oval(0, 0, size, size)
        self.canvas.create_oval(xm-(xm/4), 0, xm+(xm/4), size,
                                tags='verticalCircle')
        self.canvas.create_oval(0, ym-(ym/4), size, ym+(ym/4),
                                tags='horizontalCircle')

         # apply viewing transformation to vector
         XaxisWithView = Numeric.dot([(1.,0.,0.,1.)],self.viewingMat)[0]
         x1 = self.xm+int(XaxisWithView[0]*(self.xm))
         y1 = self.ym+int(XaxisWithView[1]*(self.ym))
         self.canvas.create_line(xm, ym, x1, y1, fill='red', tags='axis')

         XaxisWithView = Numeric.dot([(0.,1.,0.,1.)],self.viewingMat)[0]
         x2 = self.xm+int(XaxisWithView[0]*(self.xm))
         y2 = self.ym+int(XaxisWithView[1]*(self.ym))
         self.canvas.create_line(xm, ym, x2, y2, fill='green', tags='axis')

         XaxisWithView = Numeric.dot([(0.,0.,1.,1.)],self.viewingMat)[0]
         x3 = self.xm+int(XaxisWithView[0]*(self.xm))
         y3 = self.ym+int(XaxisWithView[1]*(self.ym))
         self.canvas.create_line(xm, ym, x3, y3, fill='blue', tags='axis')

        self.textId = self.canvas.create_text(0, size, anchor='sw', text="XY")

        # shadow line in X=0 plane
        self.shadowPX = self.canvas.create_polygon(0,0,0,0,0,0, fill='red',
                                               tag='moving')
        self.shadowPY = self.canvas.create_polygon(0,0,0,0,0,0, fill='green',
                                               tag='moving')
        self.shadowPZ = self.canvas.create_polygon(0,0,0,0,0,0, fill='blue',
                                               tag='moving')

        self.shadowX = self.canvas.create_line(0, 0, 0, 0, fill='black',
                                               tag='moving')
        self.shadowY = self.canvas.create_line(0, 0, 0, 0, fill='black',
                                               tag='moving')
        self.shadowZ = self.canvas.create_line(0, 0, 0, 0, fill='black',
                                               tag='moving')

        self.lId1 = self.canvas.create_line(0, 0, 0, 0, fill='black', width=3,
                                            arrow='last')
        self.canvas.pack(side='top')
         self.frame.pack(expand=1, fill='x')
         self.xm = self.ym = self.r
         self.drawVector()


     def setVector(self, value):
         #setVector does not call a callback!
         v = value
         # compute normalized vector
         n = math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2])
         if n == 0.0: v = [0.0, 0.0, 1.0]
         else: v = [v[0]/n, v[1]/n, v[2]/n]
         self.vector = v
         self.setEntries()
         self.drawVector()


  #####################################################################
  # the 'configure' methods:
  #####################################################################

     def configure(self, **kw):
         for key,value in kw.items():
             # the 'set parameter' callbacks
             if key=='continuous': self.setContinuous(value)
             elif key=='mode': self.setMode(value)
             elif key=='precision': self.setPrecision(value)

             # the 'lock entries' callbacks
             elif key=='lockContinuous': self.lockContinuousCB(value)
             elif key=='lockMode': self.lockModeCB(value)
             elif key=='lockPrecision': self.lockPrecisionCB(value)


     def setContinuous(self, cont):
         """ cont can be None, 0 or 1 """
         if cont != 1:
             cont = None
         self.continuous = cont
         if hasattr(self.opPanel, 'optionsForm'):
             w=self.opPanel.idf.entryByName['togCont']['widget']
             if cont:
                 w.setvalue('on')
             else:
                 w.setvalue('off')


     def setMode(self, mode):
         if mode!='XY' and mode!='X' and mode!='Y' and mode!='Z': mode = 'XY'
        self.canvas.itemconfigure( self.textId, text=mode)
        self.mode = mode

         if hasattr(self.opPanel, 'optionsForm'):
             w=self.opPanel.idf.entryByName['togAxes']['widget']
             w.setvalue(mode)
     def setPrecision(self, val):
         val = int(val)
         if val > 10: val = 10
         if val < 1:  val = 1
self.thumbx.configure(precision=val)
         self.thumby.configure(precision=val)
         self.thumbz.configure(precision=val)

         self.entryXTk.set(self.thumbx.labelFormat%self.vector[0])
         self.entryYTk.set(self.thumby.labelFormat%self.vector[1])
         self.entryZTk.set(self.thumbz.labelFormat%self.vector[2])
if hasattr(self.opPanel, 'optionsForm'):
             w = self.opPanel.idf.entryByName['selPrec']['widget']
             w.setvalue(val)

         if self.opPanel:
             self.opPanel.updateDisplay()


  #####################################################################
  # the 'lock' methods:
  #####################################################################
     def lockContinuousCB(self, mode):
         if mode != 0: mode = 1
         self.lockContinuous = mode
         if hasattr(self.opPanel, 'optionsForm'):
             self.opPanel.lockUnlockDisplay()


     def lockPrecisionCB(self, mode):
         if mode != 0: mode = 1
         self.lockPrecision = mode
         if hasattr(self.opPanel, 'optionsForm'):
             self.opPanel.lockUnlockDisplay()


     def lockModeCB(self, mode):
         if mode != 0: mode = 1
         self.lockMode = mode
         if hasattr(self.opPanel, 'optionsForm'):
             self.opPanel.lockUnlockDisplay()

if __name__ == '__main__':
     test = vectorGUI(size = 200)
     def foo(val):
         print val
     test.callbacks.AddCallback(foo)


--

-----------------------------------------------------------------------
   o
  /    Michel F. Sanner Ph.D.            The Scripps Research Institute
o      Associate Professor               Department of Molecular Biology
  \                                      10550 North Torrey Pines Road
   o   Tel. (858) 784-7742               La Jolla, CA 92037, TPC 26
  /    Fax. (858) 784-2341
o      san...@scripps.edu                http://www.scripps.edu/~sanner
-----------------------------------------------------------------------

Reply via email to