JAL-3026 srcjar files for VARNA and log4j
[jalview.git] / srcjar / fr / orsay / lri / varna / views / VueAnnotation.java
1 /*
2  VARNA is a tool for the automated drawing, visualization and annotation of the secondary structure of RNA, designed as a companion software for web servers and databases.
3  Copyright (C) 2008  Kevin Darty, Alain Denise and Yann Ponty.
4  electronic mail : Yann.Ponty@lri.fr
5  paper mail : LRI, bat 490 Université Paris-Sud 91405 Orsay Cedex France
6
7  This file is part of VARNA version 3.1.
8  VARNA version 3.1 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
9  as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
10
11  VARNA version 3.1 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  See the GNU General Public License for more details.
14
15  You should have received a copy of the GNU General Public License along with VARNA version 3.1.
16  If not, see http://www.gnu.org/licenses.
17  */
18 package fr.orsay.lri.varna.views;
19
20 import java.awt.BorderLayout;
21 import java.awt.Color;
22 import java.awt.Dimension;
23 import java.awt.FlowLayout;
24 import java.awt.GridLayout;
25 import java.awt.geom.Point2D.Double;
26
27 import javax.swing.JButton;
28 import javax.swing.JLabel;
29 import javax.swing.JPanel;
30 import javax.swing.JSlider;
31 import javax.swing.JTextArea;
32 import javax.swing.border.Border;
33 import javax.swing.plaf.basic.BasicBorders;
34
35 import fr.orsay.lri.varna.VARNAPanel;
36 import fr.orsay.lri.varna.controlers.ControleurSliderLabel;
37 import fr.orsay.lri.varna.controlers.ControleurVueAnnotation;
38 import fr.orsay.lri.varna.models.annotations.TextAnnotation;
39
40 /**
41  * 
42  * BH SwingJS using asynchronous JOptionPane.showConfirmDialog
43  * 
44  * annoted text view for edition
45  * 
46  * @author Darty@lri.fr
47  * 
48  */
49 public class VueAnnotation {
50
51         protected VARNAPanel _vp;
52         private JSlider ySlider, xSlider;
53         private JButton colorButton;
54         private JTextArea textArea;
55         private JPanel panel;
56         protected TextAnnotation textAnnotation, textAnnotationSave;
57         private VueFont vueFont;
58         private ControleurVueAnnotation _controleurVueAnnotation;
59         protected boolean newAnnotation, limited;
60         private Double position;
61         private JSlider rotationSlider;
62
63         /**
64          * creates a view for a new annoted text
65          * 
66          * @param vp
67          * @param limited
68          *            if true, lets custom position and angle.
69          */
70         public VueAnnotation(VARNAPanel vp, boolean limited) {
71                 this(
72                                 vp,
73                                 (int) (vp.getExtendedRNABBox().x + vp.getExtendedRNABBox().width / 2.0),
74                                 (int) (vp.getExtendedRNABBox().y + vp.getExtendedRNABBox().height / 2.0),
75                                 limited);
76         }
77
78         /**
79          * creates a view for a new annoted text, without limited option
80          * 
81          * @param vp
82          */
83         public VueAnnotation(VARNAPanel vp) {
84                 this(vp, false);
85         }
86
87         /**
88          * creates a view for a new annoted text at a given position, without
89          * limited option
90          * 
91          * @param vp
92          */
93         public VueAnnotation(VARNAPanel vp, int x, int y) {
94                 this(vp, x, y, false);
95         }
96
97         /**
98          * creates a view for a new annoted text at a given position, without
99          * limited option
100          * 
101          * @param vp
102          */
103         public VueAnnotation(VARNAPanel vp, int x, int y, boolean limited) {
104                 this(vp, new TextAnnotation("", x, y), false, true);
105         }
106
107         /**
108          * creates a view for an annoted text, without limited option
109          * 
110          * @param vp
111          * @param textAnnot
112          */
113         public VueAnnotation(VARNAPanel vp, TextAnnotation textAnnot,
114                         boolean newAnnotation) {
115                 this(vp, textAnnot, (textAnnot.getType()!=TextAnnotation.AnchorType.POSITION), newAnnotation);
116         }
117
118         /**
119          * creates a view for an annoted text
120          * 
121          * 
122          * @param vp
123          * @param textAnnot
124          * @param reduite
125          *            if true, lets custom position and angle.
126          * @param newAnnotation
127          *            if true, deleted if cancelled.
128          */
129         public VueAnnotation(VARNAPanel vp, TextAnnotation textAnnot,
130                         boolean reduite, boolean newAnnotation) {
131                 this.limited = reduite;
132                 this.newAnnotation = newAnnotation;
133                 _vp = vp;
134                 textAnnotation = textAnnot;
135                 textAnnotationSave = textAnnotation.clone();
136
137                 if (!_vp.getListeAnnotations().contains(textAnnot)) {
138                         _vp.addAnnotation(textAnnotation);
139                 }
140
141                 _controleurVueAnnotation = new ControleurVueAnnotation(this);
142
143                 position = textAnnotation.getCenterPosition();
144
145                 /*
146                  * if (textAnnotation.getType() != TextAnnotation.POSITION) { position =
147                  * _vp.transformCoord(position); }
148                  */
149
150                 JPanel py = new JPanel();
151                 JPanel px = new JPanel();
152                 panel = new JPanel();
153                 panel.setLayout(new GridLayout(0, 1));
154                 py.setLayout(new FlowLayout(FlowLayout.LEFT));
155                 px.setLayout(new FlowLayout(FlowLayout.LEFT));
156
157                 ySlider = new JSlider(JSlider.HORIZONTAL, 0, (int) (_vp
158                                 .getExtendedRNABBox().height), Math.max(0, Math.min((int) (_vp
159                                 .getExtendedRNABBox().height), (int) (position.y - _vp
160                                 .getExtendedRNABBox().y))));
161                 // Turn on labels at major tick marks.
162                 ySlider.setMajorTickSpacing(500);
163                 ySlider.setMinorTickSpacing(100);
164                 ySlider.setPaintTicks(true);
165                 ySlider.setPaintLabels(true);
166                 ySlider.setPreferredSize(new Dimension(400,
167                                 ySlider.getPreferredSize().height));
168
169                 JLabel yValueLabel = new JLabel(String.valueOf((int) position.y
170                                 - _vp.getExtendedRNABBox().y));
171                 yValueLabel.setPreferredSize(new Dimension(50, yValueLabel
172                                 .getPreferredSize().height));
173                 ySlider
174                                 .addChangeListener(new ControleurSliderLabel(yValueLabel, false));
175                 ySlider.addChangeListener(_controleurVueAnnotation);
176
177                 xSlider = new JSlider(JSlider.HORIZONTAL, 0, (int) (_vp
178                                 .getExtendedRNABBox().width), Math.max(0, Math.min((int) _vp
179                                 .getExtendedRNABBox().width, (int) (position.x - _vp
180                                 .getExtendedRNABBox().x))));
181                 // Turn on labels at major tick marks.
182                 xSlider.setMajorTickSpacing(500);
183                 xSlider.setMinorTickSpacing(100);
184                 xSlider.setPaintTicks(true);
185                 xSlider.setPaintLabels(true);
186                 xSlider.setPreferredSize(new Dimension(400,
187                                 xSlider.getPreferredSize().height));
188
189                 JLabel xValueLabel = new JLabel(String.valueOf((int) position.x
190                                 - _vp.getExtendedRNABBox().x));
191                 xValueLabel.setPreferredSize(new Dimension(50, xValueLabel
192                                 .getPreferredSize().height));
193                 xSlider
194                                 .addChangeListener(new ControleurSliderLabel(xValueLabel, false));
195                 xSlider.addChangeListener(_controleurVueAnnotation);
196
197                 JLabel labelY = new JLabel("Y:");
198                 JLabel labelX = new JLabel("X:");
199
200                 py.add(labelY);
201                 py.add(ySlider);
202                 py.add(yValueLabel);
203                 px.add(labelX);
204                 px.add(xSlider);
205                 px.add(xValueLabel);
206
207                 /*if (!limited) {
208                         panel.add(px);
209                         panel.add(py);
210                 }*/
211
212                 JPanel panelTexte = new JPanel();
213                 panelTexte.setLayout(new BorderLayout());
214                 textArea = new JTextArea(textAnnotation.getTexte());
215                 textArea.addCaretListener(_controleurVueAnnotation);
216                 textArea.setPreferredSize(panelTexte.getSize());
217                 Border border = new BasicBorders.FieldBorder(Color.black, Color.black,
218                                 Color.black, Color.black);
219                 textArea.setBorder(border);
220                 JLabel labelTexte = new JLabel("Text:");
221                 panelTexte.add(textArea, BorderLayout.CENTER);
222                 panelTexte.add(labelTexte, BorderLayout.NORTH);
223                 panel.add(panelTexte);
224
225                 vueFont = new VueFont(textAnnot.getFont());
226                 vueFont.getBoxPolice().addActionListener(_controleurVueAnnotation);
227                 vueFont.getSizeSlider().addChangeListener(_controleurVueAnnotation);
228                 vueFont.getStylesBox().addActionListener(_controleurVueAnnotation);
229
230                 colorButton = new JButton("Set color");
231                 colorButton.setActionCommand("setcolor");
232                 colorButton.setForeground(textAnnot.getColor());
233                 colorButton.addActionListener(_controleurVueAnnotation);
234
235                 JPanel fontAndColor = new JPanel();
236                 fontAndColor.add(vueFont.getPanel());
237                 fontAndColor.add(colorButton);
238
239                 panel.add(fontAndColor);
240
241                 JPanel rotationPanel = new JPanel();
242
243                 rotationSlider = new JSlider(JSlider.HORIZONTAL, -360, 360,
244                                 (int) textAnnotation.getAngleInDegres());
245                 rotationSlider.setMajorTickSpacing(60);
246                 rotationSlider.setPaintTicks(true);
247                 rotationSlider.setPaintLabels(true);
248                 rotationSlider.setPreferredSize(new Dimension(500, 50));
249
250                 JLabel rotationLabel = new JLabel(String.valueOf(0));
251                 rotationLabel.setPreferredSize(new Dimension(50, rotationLabel
252                                 .getPreferredSize().height));
253                 rotationSlider.addChangeListener(new ControleurSliderLabel(
254                                 rotationLabel, false));
255                 rotationSlider.addChangeListener(_controleurVueAnnotation);
256
257                 JLabel labelZ = new JLabel("Rotation (degrees):");
258
259                 rotationPanel.add(labelZ);
260                 rotationPanel.add(rotationSlider);
261                 rotationPanel.add(rotationLabel);
262
263                 /*
264                  * if (!limited) { panel.add(rotationPanel); }
265                  */
266
267                 if (limited) {
268                         ySlider.setEnabled(false);
269                         xSlider.setEnabled(false);
270                         rotationSlider.setEnabled(false);
271                 }
272                 textArea.requestFocusInWindow();
273                 
274         }
275
276         private void applyFont() {
277                 textAnnotation.setFont(vueFont.getFont());
278         }
279
280         /**
281          * update the annoted text on the VARNAPanel
282          */
283         public void update() {
284                 applyFont();
285                 if (textAnnotation.getType() == TextAnnotation.AnchorType.POSITION)
286                         textAnnotation.setAncrage((double) xSlider.getValue()
287                                         + _vp.getExtendedRNABBox().x, ySlider.getValue()
288                                         + _vp.getExtendedRNABBox().y);
289                 textAnnotation.setText(textArea.getText());
290                 textAnnotation.setAngleInDegres(rotationSlider.getValue());
291                 _vp.clearSelection();
292                 _vp.repaint();
293         }
294
295         public JPanel getPanel() {
296                 return panel;
297         }
298
299         /**
300          * 
301          * @return the annoted text
302          */
303         public TextAnnotation getTextAnnotation() {
304                 return textAnnotation;
305         }
306
307         public VARNAPanel get_vp() {
308                 return _vp;
309         }
310
311         /**
312          * shows the dialog which add it to the VARNAPanel for previsualization.
313          * <p>
314          * if validate, just update the annoted text
315          * <p>
316          * if cancelled : remove the annoted text if it was a new one, otherwise
317          * cancel modifications
318          * <p>
319          * 
320          */
321         public void show() {
322                 _vp.set_selectedAnnotation(textAnnotation);
323                 _vp.highlightSelectedAnnotation();
324                 
325                 // BH SwingjS using asynchronous dialog
326                 Runnable ok = new Runnable() {
327
328                         @Override
329                         public void run() {
330                                 update();
331                         }
332                         
333                 };
334
335                 Runnable cancel = new Runnable() {
336
337                         @Override
338                         public void run() {
339                                 if (newAnnotation) {
340                                         _vp.set_selectedAnnotation(null);
341                                         if (!_vp.removeAnnotation(textAnnotation))
342                                                 _vp.errorDialog(new Exception("Impossible de supprimer"));
343                                 } else {
344                                         textAnnotation.copy(textAnnotationSave);
345                                 }
346                         }
347                         
348                 };
349
350                 Runnable final_ = new Runnable() {
351
352                         @Override
353                         public void run() {
354                                 _vp.resetAnnotationHighlight();
355                                 _vp.set_selectedAnnotation(null);
356                                 _vp.repaint();
357                         }
358                         
359                 };
360                 
361                 _vp.getVARNAUI().showConfirmDialog(getPanel(), "Add/edit annotation", ok, cancel, cancel, final_);
362         }
363
364         public boolean isLimited() {
365                 return limited;
366         }
367
368         public void setLimited(boolean limited) {
369                 this.limited = limited;
370         }
371
372         public boolean isNewAnnotation() {
373                 return this.newAnnotation;
374         }
375
376         public void updateColor(Color c) {
377                 colorButton.setForeground(c);
378                 textAnnotation.setColor(c);
379
380         }
381         
382 }