1 /*
2  * Copyright (c) 2014 European Bioinformatics Institute (EMBL-EBI)
3  *                    John May <jwmay@users.sf.net>
4  *
5  * Contact: cdk-devel@lists.sourceforge.net
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation; either version 2.1 of the License, or (at
10  * your option) any later version. All we ask is that proper credit is given
11  * for our work, which includes - but is not limited to - adding the above
12  * copyright notice to the beginning of your source code files, and to any
13  * copyright notice that you may distribute with programs based on this work.
14  *
15  * This program is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
18  * License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 
25 package org.openscience.cdk.renderer.generators.standard;
26 
27 import org.openscience.cdk.interfaces.IAtom;
28 import org.openscience.cdk.interfaces.IBond;
29 import org.openscience.cdk.interfaces.IChemObject;
30 import org.openscience.cdk.renderer.RendererModel;
31 import org.openscience.cdk.renderer.SymbolVisibility;
32 
33 import java.util.List;
34 
35 /**
36  * Extended existing symbol visibility options to account for selection of atoms in the standard
37  * generator.
38  *
39  * The selection viability displays an atom symbol regardless as to whether it is normally 'shown'.
40  * By default, the symbol is shown if the atom is selected an not next to any selected bonds
41  * (disconnected). Alternatively, all select atoms can be displayed.
42  *
43  * An atom or bond is selected if the {@link StandardGenerator#HIGHLIGHT_COLOR} is non-null.
44  *
45  * @author John May
46  */
47 public final class SelectionVisibility extends SymbolVisibility {
48 
49     private final SymbolVisibility delegate;
50     private final boolean          showAll;
51 
52     /**
53      * Internal constructor.
54      *
55      * @param delegate default viability
56      * @param showAll      all select atoms are displayed
57      */
SelectionVisibility(SymbolVisibility delegate, boolean showAll)58     private SelectionVisibility(SymbolVisibility delegate, boolean showAll) {
59         this.delegate = delegate;
60         this.showAll = showAll;
61     }
62 
63     /**
64      * Display the atom symbol if is disconnected from any other selected atoms or bonds. The
65      * provided visibility is used when the atom is not selected.
66      *
67      * @param visibility visibility when not selected
68      * @return visibility instance
69      */
disconnected(SymbolVisibility visibility)70     public static SymbolVisibility disconnected(SymbolVisibility visibility) {
71         return new SelectionVisibility(visibility, false);
72     }
73 
74     /**
75      * Display the atom symbol if is selected, otherwise use the provided visibility.
76      *
77      * @param visibility visibility when not selected
78      * @return visibility instance
79      */
all(SymbolVisibility visibility)80     public static SymbolVisibility all(SymbolVisibility visibility) {
81         return new SelectionVisibility(visibility, true);
82     }
83 
84     /**
85      *{@inheritDoc}
86      */
87     @Override
visible(IAtom atom, List<IBond> neighbors, RendererModel model)88     public boolean visible(IAtom atom, List<IBond> neighbors, RendererModel model) {
89         if (isSelected(atom, model) && (showAll || !hasSelectedBond(neighbors, model))) return true;
90         return delegate.visible(atom, neighbors, model);
91     }
92 
93     /**
94      * Determine if an object is selected.
95      *
96      * @param object the object
97      * @return object is selected
98      */
isSelected(IChemObject object, RendererModel model)99     static boolean isSelected(IChemObject object, RendererModel model) {
100         if (object.getProperty(StandardGenerator.HIGHLIGHT_COLOR) != null) return true;
101         if (model.getSelection() != null) return model.getSelection().contains(object);
102         return false;
103     }
104 
105     /**
106      * Determines if any bond in the list is selected
107      *
108      * @param bonds list of bonds
109      * @return at least bond bond is selected
110      */
hasSelectedBond(List<IBond> bonds, RendererModel model)111     static boolean hasSelectedBond(List<IBond> bonds, RendererModel model) {
112         for (IBond bond : bonds) {
113             if (isSelected(bond, model)) return true;
114         }
115         return false;
116     }
117 }
118