Opened 4 years ago

Closed 3 years ago

#6510 closed defect (fixed)

Zoom/recenter with mouse

Reported by: Tristan Croll Owned by: Tristan Croll
Priority: normal Milestone:
Component: UI Version:
Keywords: Cc: chimera-programmers
Blocked By: Blocking:
Notify when closed: Platform: all
Project: ChimeraX

Description

The following bug report has been submitted:
Platform:        Linux-3.10.0-1160.25.1.el7.x86_64-x86_64-with-glibc2.17
ChimeraX Version: 1.4.dev202203280252 (2022-03-28 02:52:31 UTC)
Description
A fairly common request I get from ISOLDE users is a way to immediately zoom and recenter the view on a given atom without having to type - ideally just via some mouse-click combination. I was thinking just a simple double-click could work nicely, but the API doesn't let me map that without overriding the existing left-mouse binding in its entirety. I guess I could do that by subclassing `RotateMouseMode` and overriding the `mouse_double_click` method, but thought it best to ask/discuss first.

OpenGL version: 3.3.0 NVIDIA 465.19.01
OpenGL renderer: NVIDIA TITAN Xp/PCIe/SSE2
OpenGL vendor: NVIDIA Corporation

Python: 3.9.6
Locale: en_GB.UTF-8
Qt version: PyQt5 5.15.2, Qt 5.15.2
Qt platform: xcb

XDG_SESSION_TYPE=x11
DESKTOP_SESSION=gnome-classic
XDG_SESSION_DESKTOP=gnome-classic
XDG_CURRENT_DESKTOP=GNOME-Classic:GNOME
DISPLAY=:0
Manufacturer: Dell Inc.
Model: Precision T5600
OS: CentOS Linux 7 Core
Architecture: 64bit ELF
Virtual Machine: none
CPU: 32 Intel(R) Xeon(R) CPU E5-2687W 0 @ 3.10GHz
Cache Size: 20480 KB
Memory:
	              total        used        free      shared  buff/cache   available
	Mem:            62G         14G         15G        393M         33G         47G
	Swap:          4.9G          0B        4.9G

Graphics:
	03:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP102 [TITAN Xp] [10de:1b02] (rev a1)	
	Subsystem: NVIDIA Corporation Device [10de:11df]	
	Kernel driver in use: nvidia

Installed Packages:
    alabaster: 0.7.12
    appdirs: 1.4.4
    Babel: 2.9.1
    backcall: 0.2.0
    blockdiag: 3.0.0
    certifi: 2021.10.8
    cftime: 1.6.0
    charset-normalizer: 2.0.12
    ChimeraX-AddCharge: 1.2.3
    ChimeraX-AddH: 2.1.11
    ChimeraX-AlignmentAlgorithms: 2.0
    ChimeraX-AlignmentHdrs: 3.2.1
    ChimeraX-AlignmentMatrices: 2.0
    ChimeraX-Alignments: 2.3
    ChimeraX-AlphaFold: 1.0
    ChimeraX-AltlocExplorer: 1.0.1
    ChimeraX-AmberInfo: 1.0
    ChimeraX-Arrays: 1.0
    ChimeraX-Atomic: 1.36.3
    ChimeraX-AtomicLibrary: 6.1.1
    ChimeraX-AtomSearch: 2.0.1
    ChimeraX-AxesPlanes: 2.1
    ChimeraX-BasicActions: 1.1
    ChimeraX-BILD: 1.0
    ChimeraX-BlastProtein: 2.0
    ChimeraX-BondRot: 2.0
    ChimeraX-BugReporter: 1.0
    ChimeraX-BuildStructure: 2.6.1
    ChimeraX-Bumps: 1.0
    ChimeraX-BundleBuilder: 1.1
    ChimeraX-ButtonPanel: 1.0
    ChimeraX-CageBuilder: 1.0
    ChimeraX-CellPack: 1.0
    ChimeraX-Centroids: 1.2
    ChimeraX-ChemGroup: 2.0
    ChimeraX-Clashes: 2.2.2
    ChimeraX-Clipper: 0.18.0
    ChimeraX-ColorActions: 1.0
    ChimeraX-ColorGlobe: 1.0
    ChimeraX-ColorKey: 1.5.1
    ChimeraX-CommandLine: 1.2.3
    ChimeraX-ConnectStructure: 2.0.1
    ChimeraX-Contacts: 1.0
    ChimeraX-Core: 1.4.dev202203280252
    ChimeraX-CoreFormats: 1.1
    ChimeraX-coulombic: 1.3.2
    ChimeraX-Crosslinks: 1.0
    ChimeraX-Crystal: 1.0
    ChimeraX-CrystalContacts: 1.0
    ChimeraX-DataFormats: 1.2.2
    ChimeraX-Dicom: 1.0
    ChimeraX-DistMonitor: 1.1.5
    ChimeraX-Dssp: 2.0
    ChimeraX-EMDB-SFF: 1.0
    ChimeraX-ExperimentalCommands: 1.0
    ChimeraX-FileHistory: 1.0
    ChimeraX-FunctionKey: 1.0
    ChimeraX-Geometry: 1.1
    ChimeraX-gltf: 1.0
    ChimeraX-Graphics: 1.1
    ChimeraX-Hbonds: 2.1.2
    ChimeraX-Help: 1.2
    ChimeraX-HKCage: 1.3
    ChimeraX-IHM: 1.1
    ChimeraX-ImageFormats: 1.2
    ChimeraX-IMOD: 1.0
    ChimeraX-IO: 1.0.1
    ChimeraX-ISOLDE: 1.4.dev0
    ChimeraX-ItemsInspection: 1.0
    ChimeraX-Label: 1.1
    ChimeraX-LinuxSupport: 1.0
    ChimeraX-ListInfo: 1.1.1
    ChimeraX-Log: 1.1.5
    ChimeraX-LookingGlass: 1.1
    ChimeraX-Maestro: 1.8.1
    ChimeraX-Map: 1.1
    ChimeraX-MapData: 2.0
    ChimeraX-MapEraser: 1.0
    ChimeraX-MapFilter: 2.0
    ChimeraX-MapFit: 2.0
    ChimeraX-MapSeries: 2.1
    ChimeraX-Markers: 1.0
    ChimeraX-Mask: 1.0
    ChimeraX-MatchMaker: 2.0.6
    ChimeraX-MDcrds: 2.6
    ChimeraX-MedicalToolbar: 1.0.1
    ChimeraX-Meeting: 1.0
    ChimeraX-MLP: 1.1
    ChimeraX-mmCIF: 2.7
    ChimeraX-MMTF: 2.1
    ChimeraX-Modeller: 1.5.5
    ChimeraX-ModelPanel: 1.3.2
    ChimeraX-ModelSeries: 1.0
    ChimeraX-Mol2: 2.0
    ChimeraX-Morph: 1.0
    ChimeraX-MouseModes: 1.1
    ChimeraX-Movie: 1.0
    ChimeraX-Neuron: 1.0
    ChimeraX-Nucleotides: 2.0.2
    ChimeraX-OpenCommand: 1.8
    ChimeraX-PDB: 2.6.6
    ChimeraX-PDBBio: 1.0
    ChimeraX-PDBLibrary: 1.0.2
    ChimeraX-PDBMatrices: 1.0
    ChimeraX-PickBlobs: 1.0
    ChimeraX-Positions: 1.0
    ChimeraX-PresetMgr: 1.1
    ChimeraX-PubChem: 2.1
    ChimeraX-ReadPbonds: 1.0.1
    ChimeraX-Registration: 1.1
    ChimeraX-RemoteControl: 1.0
    ChimeraX-ResidueFit: 1.0
    ChimeraX-RestServer: 1.1
    ChimeraX-RNALayout: 1.0
    ChimeraX-RotamerLibMgr: 2.0.1
    ChimeraX-RotamerLibsDunbrack: 2.0
    ChimeraX-RotamerLibsDynameomics: 2.0
    ChimeraX-RotamerLibsRichardson: 2.0
    ChimeraX-SaveCommand: 1.5
    ChimeraX-SchemeMgr: 1.0
    ChimeraX-SDF: 2.0
    ChimeraX-Segger: 1.0
    ChimeraX-Segment: 1.0
    ChimeraX-SelInspector: 1.0
    ChimeraX-SeqView: 2.5
    ChimeraX-Shape: 1.0.1
    ChimeraX-Shell: 1.0
    ChimeraX-Shortcuts: 1.1
    ChimeraX-ShowAttr: 1.0
    ChimeraX-ShowSequences: 1.0
    ChimeraX-SideView: 1.0
    ChimeraX-Smiles: 2.1
    ChimeraX-SmoothLines: 1.0
    ChimeraX-SpaceNavigator: 1.0
    ChimeraX-StdCommands: 1.8
    ChimeraX-STL: 1.0
    ChimeraX-Storm: 1.0
    ChimeraX-StructMeasure: 1.0.1
    ChimeraX-Struts: 1.0.1
    ChimeraX-Surface: 1.0
    ChimeraX-SwapAA: 2.0
    ChimeraX-SwapRes: 2.1.1
    ChimeraX-TapeMeasure: 1.0
    ChimeraX-Test: 1.0
    ChimeraX-Toolbar: 1.1
    ChimeraX-ToolshedUtils: 1.2.1
    ChimeraX-Tug: 1.0
    ChimeraX-UI: 1.16.3
    ChimeraX-uniprot: 2.2
    ChimeraX-UnitCell: 1.0
    ChimeraX-ViewDockX: 1.1.2
    ChimeraX-VIPERdb: 1.0
    ChimeraX-Vive: 1.1
    ChimeraX-VolumeMenu: 1.0
    ChimeraX-VTK: 1.0
    ChimeraX-WavefrontOBJ: 1.0
    ChimeraX-WebCam: 1.0
    ChimeraX-WebServices: 1.0
    ChimeraX-Zone: 1.0
    colorama: 0.4.4
    cxservices: 1.1
    cycler: 0.11.0
    Cython: 0.29.26
    debugpy: 1.6.0
    decorator: 5.1.1
    distro: 1.6.0
    docutils: 0.17.1
    entrypoints: 0.4
    filelock: 3.4.2
    fonttools: 4.31.2
    funcparserlib: 1.0.0a0
    grako: 3.16.5
    h5py: 3.6.0
    html2text: 2020.1.16
    idna: 3.3
    ihm: 0.27
    imagecodecs: 2021.11.20
    imagesize: 1.3.0
    ipykernel: 6.6.1
    ipython: 7.31.1
    ipython-genutils: 0.2.0
    jedi: 0.18.1
    Jinja2: 3.0.3
    jupyter-client: 7.1.0
    jupyter-core: 4.9.2
    kiwisolver: 1.4.1
    line-profiler: 3.4.0
    lxml: 4.7.1
    lz4: 3.1.10
    MarkupSafe: 2.1.1
    matplotlib: 3.5.1
    matplotlib-inline: 0.1.3
    msgpack: 1.0.3
    nest-asyncio: 1.5.4
    netCDF4: 1.5.8
    networkx: 2.6.3
    numexpr: 2.8.1
    numpy: 1.22.1
    openvr: 1.16.802
    packaging: 21.3
    ParmEd: 3.4.3
    parso: 0.8.3
    pexpect: 4.8.0
    pickleshare: 0.7.5
    Pillow: 9.0.1
    pip: 21.3.1
    pkginfo: 1.8.2
    prompt-toolkit: 3.0.28
    psutil: 5.9.0
    ptyprocess: 0.7.0
    pycollada: 0.7.2
    pydicom: 2.2.2
    Pygments: 2.11.2
    PyOpenGL: 3.1.5
    PyOpenGL-accelerate: 3.1.5
    pyparsing: 3.0.7
    PyQt5-commercial: 5.15.2
    PyQt5-sip: 12.8.1
    PyQtWebEngine-commercial: 5.15.2
    python-dateutil: 2.8.2
    pytz: 2022.1
    pyzmq: 22.3.0
    qtconsole: 5.2.2
    QtPy: 2.0.1
    RandomWords: 0.3.0
    requests: 2.27.1
    scipy: 1.7.3
    setuptools: 59.8.0
    sfftk-rw: 0.7.1
    six: 1.16.0
    snowballstemmer: 2.2.0
    sortedcontainers: 2.4.0
    Sphinx: 4.3.2
    sphinx-autodoc-typehints: 1.15.2
    sphinxcontrib-applehelp: 1.0.2
    sphinxcontrib-blockdiag: 3.0.0
    sphinxcontrib-devhelp: 1.0.2
    sphinxcontrib-htmlhelp: 2.0.0
    sphinxcontrib-jsmath: 1.0.1
    sphinxcontrib-qthelp: 1.0.3
    sphinxcontrib-serializinghtml: 1.1.5
    suds-community: 1.0.0
    tables: 3.7.0
    tifffile: 2021.11.2
    tinyarray: 1.2.4
    tornado: 6.1
    traitlets: 5.1.1
    urllib3: 1.26.9
    wcwidth: 0.2.5
    webcolors: 1.11.1
    wheel: 0.37.1
    wheel-filename: 1.3.0

Change History (8)

comment:1 by Tristan Croll, 4 years ago

Platform: all
Project: ChimeraX

This is close to what I was after, except that it only works as I wanted (i.e. centers the view on the picked atom in all three dimensions, placing the center of rotation directly on the atom without changing the scale) in Clipper (i.e. cofr center showpivot t with near and far clipping planes active) if I monkey-patch View._shift_near_far_clip_planes to do nothing. There doesn't seem to be a built-in method that will achieve that.

from chimerax.mouse_modes import RotateMouseMode as RotateMouseMode_Base

class RotateMouseMode(RotateMouseMode_Base):
    PAD_FRACTION = 0.3
    def mouse_double_click(self,event):
        x,y = event.position()
        pick = self.view.picked_object(x,y)
        atoms = self._pick_atom_or_bond_atoms(pick)
        if atoms is not None:
            from chimerax.core.commands import run
            self.session.selection.clear()
            atoms.selected = True
            atoms.intra_bonds.selected=True
            self._center_on_picked_atoms(atoms)
    
    def _pick_atom_or_bond_atoms(self, pick):
        if pick is None:
            return None
        atoms = None
        from chimerax.atomic import Atoms
        if hasattr(pick, 'atom'):
            atoms = Atoms([pick.atom])
        elif hasattr(pick, 'bond'):
            b = pick.bond
            atoms = Atoms(b.atoms)
        return atoms
    
    def _center_on_picked_atoms(self, atoms):
        v = self.session.view
        cofr = v.center_of_rotation
        center = atoms.coords.mean(axis=0)
        cd = v.camera.view_direction()
        shift = cofr-center
        v.translate(shift)

session.ui.mouse_modes.bind_mouse_mode('left', [], RotateMouseMode(session))

comment:2 by Tristan Croll, 4 years ago

This works, although it feels a little hacky:

    def _center_on_picked_atoms(self, atoms):
        v = self.session.view
        cofr = v.center_of_rotation
        center = atoms.coords.mean(axis=0)
        cd = v.camera.view_direction()
        shift = cofr-center
        from chimerax.geometry import translation
        cofr_method = v.center_of_rotation_method
        v.move(translation(shift))
        v.center_of_rotation = center
        v.center_of_rotation_method = cofr_method

comment:3 by pett, 4 years ago

Cc: chimera-programmers added
Owner: set to Tristan Croll
Status: newassigned

comment:4 by pett, 4 years ago

Component: UnassignedUI
Summary: ChimeraX bug report submissionZoom/recenter with mouse

comment:5 by pett, 4 years ago

Overriding double click on RotateMouseMode is certainly one approach. Another is to add it to the double-click context menu (i.e. control-double-click). That's somewhat less convenient for the user but is directly supported.

comment:6 by Tom Goddard, 4 years ago

Here's an explanation of why double click works the way it does. When a user double-clicks, the code first receives a single click (mouse down then mouse up, possibly with a small mouse drag between), then it gets another click (mouse down) which is the "double click" event. Whatever the single click mouse mode did has already been done. There is no ability the way mouse events are handle on all operating systems to do just the double click action and not the single click action. For that reason they two actions need to be compatible with each other. In the case of model rotation and centering, those are probably fine, because the single click will at most result in a tiny rotation (due to pixel or two drag before the release happens). But for other combinations, like if single click placed a marker, or colored nearby residues (as discussed for alphafold PAE recently), then having double click do centering would be unusable. For ChimeraX we don't make it easy to change the left mouse assignment (Toolbar mouse modes change the right mouse button). So probably it is fine to have rotation single drag, center double click. But the user can reassign these to whatever they want. So logically being able to independently assign single and double click as requested in this ticket is a bit troublesome because the user probably will not realize that a double click cannot be done without the single click action taking place.

Because double click can only happen after a single click action took place, the API makes you define single and double click in a single mouse mode. It is constraining. I am not excited to change it. But of course you can hack around it.

I thought I added a "center on clicked atom" mouse mode in the past. Coot users and I think PyMol users are accustomed to this way of navigating. But looking now all I see is CenterOfRotationMode which changes the center of rotation to the clicked atom. I think Coot and PyMol center do both centering and fixing the center of rotation on the clicked atom.

I think the ChimeraX way to add this capability would be to go with the flow -- add a Right Mouse mode that does it. It could go in the Right Mouse toolbar. The user would right-click to center, not double-click. Of course this has the drawback that you might want to use right mouse click for something else. This is always a problem -- not enough mouse buttons to assign.

comment:7 by Tristan Croll, 4 years ago

As far as I'm aware Coot doesn't have the option to set a fixed center of rotation - the center of rotation is always the center of the screen (equivalent to cofr centerOfView) - so simply recentering on the atom puts the cofr there automatically.

I'm not really keen to use right-click in this instance - this is the sort of convenience action an active user will end up using a *lot* and would want to do without really thinking about it... if they have to switch right mouse mode to do it they'll most likely just not do it at all, and just get there using translate/rotate.

Just discovered an accidental bonus... turns out the double-click also works on Clipper's symmetry atoms, recentering the view on the equivalent "real" atom. That'll actually turn out really useful as well (although I should tweak it to make the orientation of the real atom match the symmetry view).

comment:8 by Tristan Croll, 3 years ago

Resolution: fixed
Status: assignedclosed

This is now all working quite nicely - with Clipper active, double-clicking on either a real or symmetry atom (or bond) will center the view on that atom. If it's a symmetry atom, the view is rotated/translated so the real model appears in the same orientation as the clicked symmetry copy.

Note: See TracTickets for help on using tickets.