Initial commit
[debian/openrocket] / src / net / sf / openrocket / gui / scalefigure / ScaleSelector.java
1 package net.sf.openrocket.gui.scalefigure;
2
3 import java.awt.event.ActionEvent;
4 import java.awt.event.ActionListener;
5 import java.text.DecimalFormat;
6 import java.util.Arrays;
7
8 import javax.swing.JButton;
9 import javax.swing.JComboBox;
10 import javax.swing.JPanel;
11 import javax.swing.event.ChangeEvent;
12 import javax.swing.event.ChangeListener;
13
14 import net.miginfocom.swing.MigLayout;
15 import net.sf.openrocket.util.Icons;
16
17 public class ScaleSelector extends JPanel {
18
19         // Ready zoom settings
20         private static final DecimalFormat PERCENT_FORMAT = new DecimalFormat("0.#%");
21
22         private static final double[] ZOOM_LEVELS = { 0.15, 0.25, 0.5, 0.75, 1.0, 1.5, 2.0 }; 
23         private static final String ZOOM_FIT = "Fit";
24         private static final String[] ZOOM_SETTINGS;
25         static {
26                 ZOOM_SETTINGS = new String[ZOOM_LEVELS.length+1];
27                 for (int i=0; i<ZOOM_LEVELS.length; i++)
28                         ZOOM_SETTINGS[i] = PERCENT_FORMAT.format(ZOOM_LEVELS[i]);
29                 ZOOM_SETTINGS[ZOOM_SETTINGS.length-1] = ZOOM_FIT;
30         }
31         
32         
33         private final ScaleScrollPane scrollPane;
34         private JComboBox zoomSelector;
35         
36         
37         public ScaleSelector(ScaleScrollPane scroll) {
38                 super(new MigLayout());
39
40                 this.scrollPane = scroll;
41                 
42                 // Zoom out button
43                 JButton button = new JButton(Icons.ZOOM_OUT);
44                 button.addActionListener(new ActionListener() {
45                         public void actionPerformed(ActionEvent e) {
46                                 double scale = scrollPane.getScaling();
47                                 scale = getPreviousScale(scale);
48                                 scrollPane.setScaling(scale);
49                         }
50                 });
51                 add(button, "gap");
52
53                 // Zoom level selector
54                 String[] settings = ZOOM_SETTINGS;
55                 if (!scrollPane.isFittingAllowed()) {
56                         settings = Arrays.copyOf(settings, settings.length-1);
57                 }
58                 
59                 zoomSelector = new JComboBox(settings);
60                 zoomSelector.setEditable(true);
61                 setZoomText();
62                 zoomSelector.addActionListener(new ActionListener() {
63                         public void actionPerformed(ActionEvent e) {
64                                 try {
65                                         String text = (String)zoomSelector.getSelectedItem();
66                                         text = text.replaceAll("%", "").trim();
67
68                                         if (text.toLowerCase().startsWith(ZOOM_FIT.toLowerCase()) &&
69                                                         scrollPane.isFittingAllowed()) {
70                                                 scrollPane.setFitting(true);
71                                                 setZoomText();
72                                                 return;
73                                         }
74
75                                         double n = Double.parseDouble(text);
76                                         n /= 100;
77                                         if (n <= 0.005)
78                                                 n = 0.005;
79
80                                         scrollPane.setScaling(n);
81                                         setZoomText();
82                                 } catch (NumberFormatException ignore) {
83                                 } finally {
84                                         setZoomText();
85                                 }
86                         }
87                 });
88                 scrollPane.getFigure().addChangeListener(new ChangeListener() {
89                         @Override
90                         public void stateChanged(ChangeEvent e) {
91                                 setZoomText();
92                         }
93                 });
94                 add(zoomSelector,"gap rel");
95
96
97                 // Zoom in button
98                 button = new JButton(Icons.ZOOM_IN);
99                 button.addActionListener(new ActionListener() {
100                         public void actionPerformed(ActionEvent e) {
101                                 double scale = scrollPane.getScaling();
102                                 scale = getNextScale(scale);
103                                 scrollPane.setScaling(scale);
104                         }
105                 });
106                 add(button,"gapleft rel");
107
108         }       
109
110         
111
112         private void setZoomText() {
113                 String text;
114                 double zoom = scrollPane.getScaling();
115                 text = PERCENT_FORMAT.format(zoom);
116                 if (scrollPane.isFitting()) {
117                         text = "Fit ("+text+")";
118                 }
119                 if (!text.equals(zoomSelector.getSelectedItem()))
120                         zoomSelector.setSelectedItem(text);
121         }
122         
123
124         
125         private double getPreviousScale(double scale) {
126                 int i;
127                 for (i=0; i<ZOOM_LEVELS.length-1; i++) {
128                         if (scale > ZOOM_LEVELS[i]+0.05 && scale < ZOOM_LEVELS[i+1]+0.05)
129                                 return ZOOM_LEVELS[i];
130                 }
131                 if (scale > ZOOM_LEVELS[ZOOM_LEVELS.length/2]) {
132                         // scale is large, drop to next lowest full 100%
133                         scale = Math.ceil(scale-1.05);
134                         return Math.max(scale, ZOOM_LEVELS[i]);
135                 }
136                 // scale is small
137                 return scale/1.5;
138         }
139         
140         
141         private double getNextScale(double scale) {
142                 int i;
143                 for (i=0; i<ZOOM_LEVELS.length-1; i++) {
144                         if (scale > ZOOM_LEVELS[i]-0.05 && scale < ZOOM_LEVELS[i+1]-0.05)
145                                 return ZOOM_LEVELS[i+1];
146                 }
147                 if (scale > ZOOM_LEVELS[ZOOM_LEVELS.length/2]) {
148                         // scale is large, give next full 100%
149                         scale = Math.floor(scale+1.05);
150                         return scale;
151                 }
152                 return scale*1.5;
153         }
154         
155 }