Mercurial > cgi-bin > hgweb.cgi > ClipMan
comparison src/name/blackcap/clipman/CoerceDialog.kt @ 31:0c6c18a733b7
Compiles, new menu still a mess.
author | David Barts <n5jrn@me.com> |
---|---|
date | Thu, 30 Jan 2020 16:01:51 -0800 |
parents | |
children | 4d87bedb3f65 |
comparison
equal
deleted
inserted
replaced
30:0e88c6bed11e | 31:0c6c18a733b7 |
---|---|
1 /* | |
2 * The dialog that controls font corecion. | |
3 */ | |
4 package name.blackcap.clipman | |
5 | |
6 import java.awt.Color | |
7 import java.awt.Font | |
8 import java.awt.GraphicsEnvironment | |
9 import java.awt.Toolkit | |
10 import java.awt.event.ActionEvent | |
11 import java.awt.event.ActionListener | |
12 import java.util.logging.Level | |
13 import java.util.logging.Logger | |
14 import javax.swing.* | |
15 import javax.swing.event.DocumentEvent | |
16 import javax.swing.event.DocumentListener | |
17 | |
18 class CoerceDialog: JDialog(frame.v), ActionListener { | |
19 private val FONTS = | |
20 GraphicsEnvironment.getLocalGraphicsEnvironment().availableFontFamilyNames.copyOf().apply { | |
21 sort() | |
22 } | |
23 private val SIZES = | |
24 arrayOf(9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 16.0f, 18.0f, | |
25 24.0f, 36.0f, 48.0f, 64.0f, 72.0f, 96.0f, 144.0f, 288.0f) | |
26 private val DSIZEI = 6 /* SIZES[6] = 16 */ | |
27 | |
28 /* the proportional font family */ | |
29 private val _pFamily = JComboBox<String>(FONTS).apply { | |
30 selectedIndex = getFontIndex(Font.SERIF) | |
31 } | |
32 val pFamily: String | |
33 get() { | |
34 return _pFamily.selectedItem as String | |
35 } | |
36 | |
37 /* the proportional font size */ | |
38 private val _pSize = JComboBox<Float>(SIZES).also { | |
39 it.selectedIndex = DSIZEI | |
40 it.setEditable(true) | |
41 it.actionCommand = "Size" | |
42 it.addActionListener(this) | |
43 } | |
44 val pSize: Float | |
45 get() { | |
46 return _pSize.selectedItem as Float | |
47 } | |
48 | |
49 /* the monospaced font family */ | |
50 private val _mFamily = JComboBox<String>(FONTS).apply { | |
51 selectedIndex = getFontIndex(Font.MONOSPACED) | |
52 } | |
53 val mFamily: String | |
54 get() { | |
55 return _mFamily.selectedItem as String | |
56 } | |
57 | |
58 /* the monospaced font size */ | |
59 private val _mSize = JComboBox<Float>(SIZES).also { | |
60 it.selectedIndex = DSIZEI | |
61 it.setEditable(true) | |
62 it.actionCommand = "Size" | |
63 it.addActionListener(this) | |
64 } | |
65 val mSize: Float | |
66 get() { | |
67 return _mSize.selectedItem as Float | |
68 } | |
69 | |
70 /* standard spacing between elements (10 pixels ≅ 1/7") and half that */ | |
71 private val BW = 5 | |
72 private val BW2 = 10 | |
73 private val VSPACE = Box.createVerticalStrut(BW) | |
74 private val VSPACE2 = Box.createVerticalStrut(BW2) | |
75 private val HSPACE2 = Box.createHorizontalStrut(BW2) | |
76 | |
77 /* buttons */ | |
78 private val _coerce = JButton("Coerce").also { | |
79 it.actionCommand = "Coerce" | |
80 it.addActionListener(this) | |
81 } | |
82 | |
83 private val _cancel = JButton("Cancel").also { | |
84 it.actionCommand = "Cancel" | |
85 it.addActionListener(this) | |
86 } | |
87 | |
88 /* initializer */ | |
89 init { | |
90 title = "Coerce Fonts" | |
91 contentPane.apply { | |
92 add(Box(BoxLayout.Y_AXIS).apply { | |
93 add(VSPACE2) | |
94 add(leftLabel("Coerce proportionally-spaced text to:")) | |
95 add(VSPACE) | |
96 add(Box(BoxLayout.X_AXIS).apply { | |
97 add(HSPACE2) | |
98 add(Box.createGlue()) | |
99 add(Box(BoxLayout.Y_AXIS).apply { | |
100 add(leftLabel("Family:")) | |
101 add(_pFamily) | |
102 }) | |
103 add(Box.createGlue()) | |
104 add(Box(BoxLayout.Y_AXIS).apply { | |
105 add(leftLabel("Size:")) | |
106 add(_pSize) | |
107 }) | |
108 add(Box.createGlue()) | |
109 add(HSPACE2) | |
110 }) | |
111 add(VSPACE2) | |
112 add(JSeparator()) | |
113 add(VSPACE2) | |
114 add(leftLabel("Coerce monospaced text to:")) | |
115 add(VSPACE) | |
116 add(Box(BoxLayout.X_AXIS).apply { | |
117 add(HSPACE2) | |
118 add(Box.createGlue()) | |
119 add(Box(BoxLayout.Y_AXIS).apply { | |
120 add(leftLabel("Family:")) | |
121 add(_mFamily) | |
122 }) | |
123 add(Box.createGlue()) | |
124 add(Box(BoxLayout.Y_AXIS).apply { | |
125 add(leftLabel("Size:")) | |
126 add(_mSize) | |
127 }) | |
128 add(Box.createGlue()) | |
129 add(HSPACE2) | |
130 }) | |
131 add(VSPACE2) | |
132 add(JSeparator()) | |
133 add(VSPACE2) | |
134 add(Box(BoxLayout.X_AXIS).apply { | |
135 add(Box.createGlue()) | |
136 add(_cancel) | |
137 add(Box.createGlue()) | |
138 add(_coerce) | |
139 add(Box.createGlue()) | |
140 }) | |
141 add(VSPACE2) | |
142 }) | |
143 } | |
144 rootPane.setDefaultButton(_coerce) | |
145 pack() | |
146 } | |
147 | |
148 private fun leftLabel(text: String) = JLabel(text).apply { | |
149 horizontalAlignment = JLabel.LEFT | |
150 alignmentX = JLabel.LEFT_ALIGNMENT | |
151 } | |
152 | |
153 override fun actionPerformed(e: ActionEvent) { | |
154 when (e.actionCommand) { | |
155 "Size" -> { | |
156 val source = e.source as? JComboBox<Float> | |
157 if (source != null && (source.selectedItem as Float) < 1.0f) { | |
158 Toolkit.getDefaultToolkit().beep() | |
159 source.selectedIndex = DSIZEI | |
160 } | |
161 } | |
162 "Coerce" -> { | |
163 setVisible(false) | |
164 coerce() | |
165 } | |
166 "Cancel" -> setVisible(false) | |
167 } | |
168 } | |
169 | |
170 private fun coerce() { | |
171 val selected = queue.v.getSelected() | |
172 if (selected == null) { | |
173 JOptionPane.showMessageDialog(frame.v, | |
174 "No item selected.", | |
175 "Error", | |
176 JOptionPane.ERROR_MESSAGE) | |
177 } else { | |
178 val (plain, html) = when (selected.contents) { | |
179 is PasteboardItem.Plain -> | |
180 Pair(selected.contents.plain, null) | |
181 is PasteboardItem.HTML -> | |
182 Pair(selected.contents.plain, selected.contents.html) | |
183 is PasteboardItem.RTF -> | |
184 Pair(selected.contents.plain, selected.contents.html) | |
185 } | |
186 if (html == null) { | |
187 JOptionPane.showMessageDialog(frame.v, | |
188 "Only styled texts may be coerced.", | |
189 "Error", | |
190 JOptionPane.ERROR_MESSAGE) | |
191 } else { | |
192 PasteboardItem.write( | |
193 PasteboardItem.HTML( | |
194 plain, | |
195 coerceHTML(html, normalizeFont(pFamily), pSize, | |
196 normalizeFont(mFamily), mSize))) | |
197 } | |
198 } | |
199 } | |
200 | |
201 private fun getFontIndex(font: String): Int { | |
202 val found = FONTS.indexOf(font) | |
203 if (found < 0) { | |
204 LOGGER.log(Level.WARNING, "font '${font}' not found") | |
205 return 0 | |
206 } | |
207 return found | |
208 } | |
209 | |
210 private fun normalizeFont(font: String): String { | |
211 val lcFont = font.toLowerCase() | |
212 return when (lcFont) { | |
213 in setOf("monospace", "serif", "sans-serif") -> lcFont | |
214 "monospaced" -> "monospace" | |
215 "sansserif" -> "sans-serif" | |
216 else -> font | |
217 } | |
218 } | |
219 } | |
220 | |
221 val coerceDialog = CoerceDialog() |