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()