Package org.jmol.viewer

Source Code of org.jmol.viewer.SelectionManager

/* $RCSfile$
* $Author: hansonr $
* $Date: 2011-05-11 05:10:44 +0200 (mer., 11 mai 2011) $
* $Revision: 15454 $
*
* Copyright (C) 2003-2005  Miguel, Jmol Development
*
* Contact: jmol-developers@lists.sf.net, jmol-developers@lists.sf.net
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2.1 of the License, or (at your option) any later version.
*
*  This library 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.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jmol.viewer;

import org.jmol.script.Token;
import org.jmol.util.ArrayUtil;
import org.jmol.util.BitSetUtil;
import org.jmol.util.Escape;

import org.jmol.api.JmolSelectionListener;
import org.jmol.i18n.GT;
import org.jmol.modelset.ModelSet;

import java.util.BitSet;
import java.util.Hashtable;

class SelectionManager {

  private Viewer viewer;

  private JmolSelectionListener[] listeners = new JmolSelectionListener[0];

  SelectionManager(Viewer viewer) {
    this.viewer = viewer;
  }

  private final BitSet bsHidden = new BitSet();
  private final BitSet bsSelection = new BitSet();
  private final BitSet bsFixed = new BitSet();

  BitSet bsSubset; // set in Eval and only pointed to here
  private BitSet bsDeleted;

  public void deleteModelAtoms(int firstAtomIndex, int nAtoms, BitSet bsDeleted) {
    BitSetUtil.deleteBits(bsHidden, bsDeleted);
    BitSetUtil.deleteBits(bsSelection, bsDeleted);
    BitSetUtil.deleteBits(bsSubset, bsDeleted);
    BitSetUtil.deleteBits(bsFixed, bsDeleted);
    BitSetUtil.deleteBits(this.bsDeleted, bsDeleted);
  }


  // this is a tri-state. the value -1 means unknown
  private final static int TRUE = 1;
  private final static int FALSE = 0;
  private final static int UNKNOWN = -1;
  private int empty = TRUE;

  private boolean hideNotSelected;

  void clear() {
    clearSelection(true);
    hide(null, true);
    setSelectionSubset(null);
    bsDeleted = null;
    setMotionFixedAtoms(null);
  }

  void hide(BitSet bs, boolean isQuiet) {
    bsHidden.clear();
    if (bs != null)
      bsHidden.or(bs);
    ModelSet modelSet = viewer.getModelSet();
    if (modelSet != null)
      modelSet.setBsHidden(bsHidden);
    if (!isQuiet)
      viewer.reportSelection(GT._("{0} atoms hidden", ""
          + bsHidden.cardinality()));
  }

  void display(BitSet bsAll, BitSet bs, boolean isQuiet) {
    if (bs == null) {
      bsHidden.clear();
    } else {
      bsHidden.or(bsAll);
      bsHidden.andNot(bs);
    }
    BitSetUtil.andNot(bsHidden, bsDeleted);
    ModelSet modelSet = viewer.getModelSet();
    if (modelSet != null)
      modelSet.setBsHidden(bsHidden);
    if (!isQuiet)
      viewer.reportSelection(GT._("{0} atoms hidden", ""
          + bsHidden.cardinality()));
  }

  BitSet getHiddenSet() {
    return bsHidden;
  }

  boolean getHideNotSelected() {
    return hideNotSelected;
  }

  void setHideNotSelected(boolean TF) {
    hideNotSelected = TF;
    if (TF)
      selectionChanged(false);
  }

  boolean isSelected(int atomIndex) {
    return (atomIndex >= 0 && bsSelection.get(atomIndex));
  }

  void select(BitSet bs, boolean isQuiet) {
    if (bs == null) {
      selectAll(true);
      if (!viewer.getRasmolSetting(Token.hydrogen))
        excludeSelectionSet(viewer.getAtomBits(Token.hydrogen, null));
      if (!viewer.getRasmolSetting(Token.hetero))
        excludeSelectionSet(viewer.getAtomBits(Token.hetero, null));
      selectionChanged(false);
    } else {
      setSelectionSet(bs);
    }
    boolean reportChime = viewer.getMessageStyleChime();
    if (!reportChime && isQuiet)
      return;
    int n = getSelectionCount();
    if (reportChime)
      viewer.reportSelection((n == 0 ? "No atoms" : n == 1 ? "1 atom" : n
          + " atoms")
          + " selected!");
    else if (!isQuiet)
      viewer.reportSelection(GT._("{0} atoms selected", n));
  }

  void selectAll(boolean isQuiet) {
    int count = viewer.getAtomCount();
    empty = (count == 0) ? TRUE : FALSE;
    for (int i = count; --i >= 0;)
      bsSelection.set(i);
    BitSetUtil.andNot(bsSelection, bsDeleted);
    selectionChanged(isQuiet);
  }

  void clearSelection(boolean isQuiet) {
    setHideNotSelected(false);
    bsSelection.clear();
    empty = TRUE;
    selectionChanged(isQuiet);
  }

  public boolean isAtomSelected(int atomIndex) {
    return (
        (bsSubset == null || bsSubset.get(atomIndex))
        && bsDeleted == null || !bsDeleted.get(atomIndex))
        && bsSelection.get(atomIndex);
  }
 
  public void setSelectedAtom(int atomIndex, boolean TF) {
    if (atomIndex < 0) {
      selectionChanged(true);
      return;
    }
    if (bsSubset != null && !bsSubset.get(atomIndex)
        || bsDeleted != null && bsDeleted.get(atomIndex))
      return;
    bsSelection.set(atomIndex, TF);
    if (TF)
      empty = FALSE;
    else
      empty = UNKNOWN;
  }

  void setSelectionSet(BitSet set) {
    bsSelection.clear();
    if (set != null)
      bsSelection.or(set);
    empty = UNKNOWN;
    selectionChanged(false);
  }

  void setSelectionSubset(BitSet bs) {

    // for informational purposes only
    // the real copy is in Eval so that eval operations
    // can all use it directly, and so that all these
    // operations still work properly on the full set of atoms

    bsSubset = bs;
  }

  boolean isInSelectionSubset(int atomIndex) {
    return (atomIndex < 0 || bsSubset == null || bsSubset.get(atomIndex));
  }

  void invertSelection() {
    BitSetUtil.invertInPlace(bsSelection, viewer.getAtomCount());
    empty = (bsSelection.length() > 0 ? FALSE : TRUE);
    selectionChanged(false);
  }

  private void excludeSelectionSet(BitSet setExclude) {
    if (setExclude == null || empty == TRUE)
      return;
    bsSelection.andNot(setExclude);
    empty = UNKNOWN;
  }

  private final BitSet bsTemp = new BitSet();

  int getSelectionCount() {
    if (empty == TRUE)
      return 0;
    empty = TRUE;
    BitSet bs;
    if (bsSubset != null) {
      bsTemp.clear();
      bsTemp.or(bsSubset);
      bsTemp.and(bsSelection);
      bs = bsTemp;
    } else {
      bs = bsSelection;
    }
    int count = bs.cardinality();
    if (count > 0)
      empty = FALSE;
    return count;
  }

  void addListener(JmolSelectionListener listener) {
    for (int i = listeners.length; --i >= 0;)
      if (listeners[i] == listener) {
        listeners[i] = null;
        break;
      }
    int len = listeners.length;
    for (int i = len; --i >= 0;)
      if (listeners[i] == null) {
        listeners[i] = listener;
        return;
      }
    if (listeners.length == 0)
      listeners = new JmolSelectionListener[1];
    else
      listeners = (JmolSelectionListener[]) ArrayUtil.doubleLength(listeners);
    listeners[len] = listener;
  }

  private void selectionChanged(boolean isQuiet) {
    if (hideNotSelected)
      hide(BitSetUtil.copyInvert(bsSelection, viewer.getAtomCount()), isQuiet);
    if (isQuiet || listeners.length == 0)
      return;
    for (int i = listeners.length; --i >= 0;)
      if (listeners[i] != null)
        listeners[i].selectionChanged(bsSelection);
  }

  String getState(StringBuffer sfunc) {
    StringBuffer commands = new StringBuffer();
    if (sfunc != null) {
      sfunc.append("  _setSelectionState;\n");
      commands.append("function _setSelectionState() {\n");
    }
    StateManager.appendCmd(commands, viewer.getTrajectoryInfo());
    Hashtable temp = new Hashtable();
    String cmd = null;
    addBs(commands, "hide ", bsHidden);
    addBs(commands, "subset ", bsSubset);
    addBs(commands, "delete ", bsDeleted);
    addBs(commands, "fix ", bsFixed);
    temp.put("-", bsSelection);
    cmd = StateManager.getCommands(temp, null);
    if (cmd == null)
      StateManager.appendCmd(commands, "select none");
    else
      commands.append(cmd);
    StateManager.appendCmd(commands, "set hideNotSelected " + hideNotSelected);
    commands.append(viewer.getShapeProperty(JmolConstants.SHAPE_STICKS,
        "selectionState"));
    if (viewer.getSelectionHaloEnabled(false))
      StateManager.appendCmd(commands, "SelectionHalos ON");
    if (sfunc != null)
      commands.append("}\n\n");
    return commands.toString();
  }

  private static void addBs(StringBuffer sb, String key,
                            BitSet bs) {
    if (bs == null || bs.length() == 0)
      return;
    StateManager.appendCmd(sb, key + Escape.escape(bs));
  }

  int deleteAtoms(BitSet bs) {
    BitSet bsNew = BitSetUtil.copy(bs);
    if (bsDeleted == null) {
      bsDeleted = bsNew;
    } else {
      bsNew.andNot(bsDeleted);
      bsDeleted.or(bs);
    }
    bsHidden.andNot(bsDeleted);
    bsSelection.andNot(bsDeleted);
    return bsNew.cardinality();
  }

  BitSet getDeletedAtoms() {
    return bsDeleted;
  }

  BitSet getSelectionSet(boolean includeDeleted) {
    if (includeDeleted || bsDeleted == null && bsSubset == null)
      return bsSelection;
    BitSet bs = new BitSet();
    bs.or(bsSelection);
    excludeAtoms(bs, false);
    return bs;
  }

  BitSet getSelectionSubset() {
    return bsSubset;
  }

  void excludeAtoms(BitSet bs, boolean ignoreSubset) {
    if (bsDeleted != null)
      bs.andNot(bsDeleted);
    if (!ignoreSubset && bsSubset != null)
      bs.and(bsSubset);
  }

  void processDeletedModelAtoms(BitSet bsAtoms) {
    if (bsDeleted != null)
      BitSetUtil.deleteBits(bsDeleted, bsAtoms);
    if (bsSubset != null)
      BitSetUtil.deleteBits(bsSubset, bsAtoms);
    BitSetUtil.deleteBits(bsFixed, bsAtoms);
    BitSetUtil.deleteBits(bsHidden, bsAtoms);
    BitSet bs = BitSetUtil.copy(bsSelection);
    BitSetUtil.deleteBits(bs, bsAtoms);
    setSelectionSet(bs);
  }

  void setMotionFixedAtoms(BitSet bs) {
    bsFixed.clear();
    if (bs != null)
      bsFixed.or(bs);
  }

  BitSet getMotionFixedAtoms() {
    return bsFixed;
  }

}
TOP

Related Classes of org.jmol.viewer.SelectionManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.