Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
AlignViewport | 44 | 98 | 46 |
1 | /* | |
2 | * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) | |
3 | * Copyright (C) $$Year-Rel$$ The Jalview Authors | |
4 | * | |
5 | * This file is part of Jalview. | |
6 | * | |
7 | * Jalview is free software: you can redistribute it and/or | |
8 | * modify it under the terms of the GNU General Public License | |
9 | * as published by the Free Software Foundation, either version 3 | |
10 | * of the License, or (at your option) any later version. | |
11 | * | |
12 | * Jalview is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty | |
14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |
15 | * PURPOSE. See the GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with Jalview. If not, see <http://www.gnu.org/licenses/>. | |
19 | * The Jalview Authors are detailed in the 'AUTHORS' file. | |
20 | */ | |
21 | package jalview.appletgui; | |
22 | ||
23 | import jalview.api.AlignViewportI; | |
24 | import jalview.api.FeatureSettingsModelI; | |
25 | import jalview.bin.JalviewLite; | |
26 | import jalview.commands.CommandI; | |
27 | import jalview.datamodel.AlignmentI; | |
28 | import jalview.datamodel.ColumnSelection; | |
29 | import jalview.datamodel.HiddenColumns; | |
30 | import jalview.datamodel.SearchResults; | |
31 | import jalview.datamodel.SearchResultsI; | |
32 | import jalview.datamodel.SequenceGroup; | |
33 | import jalview.renderer.ResidueShader; | |
34 | import jalview.schemes.ColourSchemeProperty; | |
35 | import jalview.schemes.UserColourScheme; | |
36 | import jalview.structure.SelectionSource; | |
37 | import jalview.structure.StructureSelectionManager; | |
38 | import jalview.structure.VamsasSource; | |
39 | import jalview.viewmodel.AlignmentViewport; | |
40 | ||
41 | import java.awt.Font; | |
42 | import java.awt.FontMetrics; | |
43 | ||
44 | public class AlignViewport extends AlignmentViewport | |
45 | implements SelectionSource | |
46 | { | |
47 | boolean cursorMode = false; | |
48 | ||
49 | Font font = new Font("SansSerif", Font.PLAIN, 10); | |
50 | ||
51 | boolean validCharWidth = true; | |
52 | ||
53 | public jalview.bin.JalviewLite applet; | |
54 | ||
55 | private AnnotationColumnChooser annotationColumnSelectionState; | |
56 | ||
57 | 0 | public AlignViewport(AlignmentI al, JalviewLite applet) |
58 | { | |
59 | 0 | super(al); |
60 | 0 | calculator = new jalview.workers.AlignCalcManager(); |
61 | 0 | this.applet = applet; |
62 | ||
63 | // we always pad gaps | |
64 | 0 | this.setPadGaps(true); |
65 | ||
66 | 0 | if (applet != null) |
67 | { | |
68 | // get the width and height scaling factors if they were specified | |
69 | 0 | String param = applet.getParameter("widthScale"); |
70 | 0 | if (param != null) |
71 | { | |
72 | 0 | try |
73 | { | |
74 | 0 | widthScale = Float.valueOf(param).floatValue(); |
75 | } catch (Exception e) | |
76 | { | |
77 | } | |
78 | 0 | if (widthScale <= 1.0) |
79 | { | |
80 | 0 | jalview.bin.Console.errPrintln( |
81 | "Invalid alignment character width scaling factor (" | |
82 | + widthScale + "). Ignoring."); | |
83 | 0 | widthScale = 1; |
84 | } | |
85 | 0 | if (JalviewLite.debug) |
86 | { | |
87 | 0 | jalview.bin.Console.errPrintln( |
88 | "Alignment character width scaling factor is now " | |
89 | + widthScale); | |
90 | } | |
91 | } | |
92 | 0 | param = applet.getParameter("heightScale"); |
93 | 0 | if (param != null) |
94 | { | |
95 | 0 | try |
96 | { | |
97 | 0 | heightScale = Float.valueOf(param).floatValue(); |
98 | } catch (Exception e) | |
99 | { | |
100 | } | |
101 | 0 | if (heightScale <= 1.0) |
102 | { | |
103 | 0 | jalview.bin.Console.errPrintln( |
104 | "Invalid alignment character height scaling factor (" | |
105 | + heightScale + "). Ignoring."); | |
106 | 0 | heightScale = 1; |
107 | } | |
108 | 0 | if (JalviewLite.debug) |
109 | { | |
110 | 0 | jalview.bin.Console.errPrintln( |
111 | "Alignment character height scaling factor is now " | |
112 | + heightScale); | |
113 | } | |
114 | } | |
115 | } | |
116 | 0 | setFont(font, true); |
117 | ||
118 | 0 | if (applet != null) |
119 | { | |
120 | 0 | setShowJVSuffix( |
121 | applet.getDefaultParameter("showFullId", getShowJVSuffix())); | |
122 | ||
123 | 0 | setShowAnnotation(applet.getDefaultParameter("showAnnotation", |
124 | isShowAnnotation())); | |
125 | ||
126 | 0 | showConservation = applet.getDefaultParameter("showConservation", |
127 | showConservation); | |
128 | ||
129 | 0 | showQuality = applet.getDefaultParameter("showQuality", showQuality); |
130 | ||
131 | 0 | showConsensus = applet.getDefaultParameter("showConsensus", |
132 | showConsensus); | |
133 | ||
134 | 0 | showOccupancy = applet.getDefaultParameter("showOccupancy", |
135 | showOccupancy); | |
136 | ||
137 | 0 | setShowUnconserved(applet.getDefaultParameter("showUnconserved", |
138 | getShowUnconserved())); | |
139 | ||
140 | 0 | setScaleProteinAsCdna(applet.getDefaultParameter("scaleProteinAsCdna", |
141 | isScaleProteinAsCdna())); | |
142 | ||
143 | 0 | String param = applet.getParameter("upperCase"); |
144 | 0 | if (param != null) |
145 | { | |
146 | 0 | if (param.equalsIgnoreCase("bold")) |
147 | { | |
148 | 0 | setUpperCasebold(true); |
149 | } | |
150 | } | |
151 | 0 | sortByTree = applet.getDefaultParameter("sortByTree", sortByTree); |
152 | ||
153 | 0 | setFollowHighlight(applet.getDefaultParameter("automaticScrolling", |
154 | isFollowHighlight())); | |
155 | 0 | followSelection = isFollowHighlight(); |
156 | ||
157 | 0 | showSequenceLogo = applet.getDefaultParameter("showSequenceLogo", |
158 | showSequenceLogo); | |
159 | ||
160 | 0 | normaliseSequenceLogo = applet.getDefaultParameter( |
161 | "normaliseSequenceLogo", applet.getDefaultParameter( | |
162 | "normaliseLogo", normaliseSequenceLogo)); | |
163 | ||
164 | 0 | showGroupConsensus = applet.getDefaultParameter("showGroupConsensus", |
165 | showGroupConsensus); | |
166 | ||
167 | 0 | showGroupConservation = applet.getDefaultParameter( |
168 | "showGroupConservation", showGroupConservation); | |
169 | ||
170 | 0 | showConsensusHistogram = applet.getDefaultParameter( |
171 | "showConsensusHistogram", showConsensusHistogram); | |
172 | ||
173 | } | |
174 | ||
175 | 0 | if (applet != null) |
176 | { | |
177 | 0 | String colour = al.isNucleotide() |
178 | ? applet.getParameter("defaultColourNuc") | |
179 | : applet.getParameter("defaultColourProt"); | |
180 | 0 | if (colour == null) |
181 | { | |
182 | 0 | colour = applet.getParameter("defaultColour"); |
183 | } | |
184 | 0 | if (colour == null) |
185 | { | |
186 | 0 | colour = applet.getParameter("userDefinedColour"); |
187 | 0 | if (colour != null) |
188 | { | |
189 | 0 | colour = "User Defined"; |
190 | } | |
191 | } | |
192 | ||
193 | 0 | if (colour != null) |
194 | { | |
195 | 0 | residueShading = new ResidueShader(ColourSchemeProperty |
196 | .getColourScheme(this, alignment, colour)); | |
197 | 0 | if (residueShading != null) |
198 | { | |
199 | 0 | residueShading.setConsensus(hconsensus); |
200 | } | |
201 | } | |
202 | ||
203 | 0 | if (applet.getParameter("userDefinedColour") != null) |
204 | { | |
205 | 0 | residueShading = new ResidueShader(new UserColourScheme( |
206 | applet.getParameter("userDefinedColour"))); | |
207 | } | |
208 | } | |
209 | 0 | initAutoAnnotation(); |
210 | ||
211 | } | |
212 | ||
213 | java.awt.Frame nullFrame; | |
214 | ||
215 | protected FeatureSettings featureSettings = null; | |
216 | ||
217 | private float heightScale = 1, widthScale = 1; | |
218 | ||
219 | /** | |
220 | * {@inheritDoc} | |
221 | */ | |
222 | 0 | @Override |
223 | public void setFont(Font f, boolean setGrid) | |
224 | { | |
225 | 0 | font = f; |
226 | 0 | if (nullFrame == null) |
227 | { | |
228 | 0 | nullFrame = new java.awt.Frame(); |
229 | 0 | nullFrame.addNotify(); |
230 | } | |
231 | ||
232 | 0 | if (setGrid) |
233 | { | |
234 | 0 | FontMetrics fm = nullFrame.getGraphics().getFontMetrics(font); |
235 | 0 | setCharHeight((int) (heightScale * fm.getHeight())); |
236 | 0 | setCharWidth((int) (widthScale * fm.charWidth('M'))); |
237 | } | |
238 | ||
239 | 0 | if (isUpperCasebold()) |
240 | { | |
241 | 0 | Font f2 = new Font(f.getName(), Font.BOLD, f.getSize()); |
242 | 0 | FontMetrics fm = nullFrame.getGraphics().getFontMetrics(f2); |
243 | 0 | setCharWidth( |
244 | (int) (widthScale * (fm.stringWidth("MMMMMMMMMMM") / 10))); | |
245 | } | |
246 | } | |
247 | ||
248 | 0 | public Font getFont() |
249 | { | |
250 | 0 | return font; |
251 | } | |
252 | ||
253 | 0 | public void resetSeqLimits(int height) |
254 | { | |
255 | 0 | ranges.setEndSeq(height / getCharHeight() - 1); // BH 2019.04.18 |
256 | } | |
257 | ||
258 | boolean centreColumnLabels; | |
259 | ||
260 | 0 | public boolean getCentreColumnLabels() |
261 | { | |
262 | 0 | return centreColumnLabels; |
263 | } | |
264 | ||
265 | public boolean followSelection = true; | |
266 | ||
267 | /** | |
268 | * @return true if view selection should always follow the selections | |
269 | * broadcast by other selection sources | |
270 | */ | |
271 | 0 | public boolean getFollowSelection() |
272 | { | |
273 | 0 | return followSelection; |
274 | } | |
275 | ||
276 | 0 | @Override |
277 | public void sendSelection() | |
278 | { | |
279 | 0 | getStructureSelectionManager().sendSelection( |
280 | new SequenceGroup(getSelectionGroup()), | |
281 | new ColumnSelection(getColumnSelection()), | |
282 | new HiddenColumns(getAlignment().getHiddenColumns()), this); | |
283 | } | |
284 | ||
285 | /** | |
286 | * Returns an instance of the StructureSelectionManager scoped to this applet | |
287 | * instance. | |
288 | * | |
289 | * @return | |
290 | */ | |
291 | 0 | @Override |
292 | public StructureSelectionManager getStructureSelectionManager() | |
293 | { | |
294 | 0 | return jalview.structure.StructureSelectionManager |
295 | .getStructureSelectionManager(applet); | |
296 | } | |
297 | ||
298 | 0 | @Override |
299 | public boolean isNormaliseSequenceLogo() | |
300 | { | |
301 | 0 | return normaliseSequenceLogo; |
302 | } | |
303 | ||
304 | 0 | public void setNormaliseSequenceLogo(boolean state) |
305 | { | |
306 | 0 | normaliseSequenceLogo = state; |
307 | } | |
308 | ||
309 | /** | |
310 | * | |
311 | * @return true if alignment characters should be displayed | |
312 | */ | |
313 | 0 | @Override |
314 | public boolean isValidCharWidth() | |
315 | { | |
316 | 0 | return validCharWidth; |
317 | } | |
318 | ||
319 | 0 | public AnnotationColumnChooser getAnnotationColumnSelectionState() |
320 | { | |
321 | 0 | return annotationColumnSelectionState; |
322 | } | |
323 | ||
324 | 0 | public void setAnnotationColumnSelectionState( |
325 | AnnotationColumnChooser annotationColumnSelectionState) | |
326 | { | |
327 | 0 | this.annotationColumnSelectionState = annotationColumnSelectionState; |
328 | } | |
329 | ||
330 | 0 | @Override |
331 | public void mirrorCommand(CommandI command, boolean undo, | |
332 | StructureSelectionManager ssm, VamsasSource source) | |
333 | { | |
334 | // TODO refactor so this can be pulled up to superclass or controller | |
335 | /* | |
336 | * Do nothing unless we are a 'complement' of the source. May replace this | |
337 | * with direct calls not via SSM. | |
338 | */ | |
339 | 0 | if (source instanceof AlignViewportI |
340 | && ((AlignViewportI) source).getCodingComplement() == this) | |
341 | { | |
342 | // ok to continue; | |
343 | } | |
344 | else | |
345 | { | |
346 | 0 | return; |
347 | } | |
348 | ||
349 | 0 | CommandI mappedCommand = ssm.mapCommand(command, undo, getAlignment(), |
350 | getGapCharacter()); | |
351 | 0 | if (mappedCommand != null) |
352 | { | |
353 | 0 | mappedCommand.doCommand(null); |
354 | 0 | firePropertyChange("alignment", null, getAlignment().getSequences()); |
355 | ||
356 | // ap.scalePanelHolder.repaint(); | |
357 | // ap.repaint(); | |
358 | } | |
359 | } | |
360 | ||
361 | 0 | @Override |
362 | public VamsasSource getVamsasSource() | |
363 | { | |
364 | 0 | return this; |
365 | } | |
366 | ||
367 | /** | |
368 | * If this viewport has a (Protein/cDNA) complement, then scroll the | |
369 | * complementary alignment to match this one. | |
370 | */ | |
371 | 0 | public void scrollComplementaryAlignment(AlignmentPanel complementPanel) |
372 | { | |
373 | 0 | if (complementPanel == null) |
374 | { | |
375 | 0 | return; |
376 | } | |
377 | ||
378 | /* | |
379 | * Populate a SearchResults object with the mapped location to scroll to. If | |
380 | * there is no complement, or it is not following highlights, or no mapping | |
381 | * is found, the result will be empty. | |
382 | */ | |
383 | 0 | SearchResultsI sr = new SearchResults(); |
384 | 0 | int seqOffset = findComplementScrollTarget(sr); |
385 | 0 | if (!sr.isEmpty()) |
386 | { | |
387 | 0 | complementPanel.setToScrollComplementPanel(false); |
388 | 0 | complementPanel.scrollToCentre(sr, seqOffset); |
389 | 0 | complementPanel.setToScrollComplementPanel(true); |
390 | } | |
391 | } | |
392 | ||
393 | /** | |
394 | * Applies the supplied feature settings descriptor to currently known | |
395 | * features. This supports an 'initial configuration' of feature colouring | |
396 | * based on a preset or user favourite. This may then be modified in the usual | |
397 | * way using the Feature Settings dialogue. NOT IMPLEMENTED FOR APPLET | |
398 | * | |
399 | * @param featureSettings | |
400 | */ | |
401 | 0 | @Override |
402 | public void applyFeaturesStyle(FeatureSettingsModelI featureSettings) | |
403 | { | |
404 | // TODO implement for applet | |
405 | } | |
406 | ||
407 | /** | |
408 | * Merges the supplied feature settings descriptor with existing feature | |
409 | * styles. This supports an 'initial configuration' of feature colouring based | |
410 | * on a preset or user favourite. This may then be modified in the usual way | |
411 | * using the Feature Settings dialogue. NOT IMPLEMENTED FOR APPLET | |
412 | * | |
413 | * @param featureSettings | |
414 | */ | |
415 | 0 | @Override |
416 | public void mergeFeaturesStyle(FeatureSettingsModelI featureSettings) | |
417 | { | |
418 | // TODO Auto-generated method stub | |
419 | ||
420 | } | |
421 | } |