Mercurial > cgi-bin > hgweb.cgi > ClipMan
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/name/blackcap/clipman/CoerceDialog.kt Thu Jan 30 16:01:51 2020 -0800 @@ -0,0 +1,221 @@ +/* + * The dialog that controls font corecion. + */ +package name.blackcap.clipman + +import java.awt.Color +import java.awt.Font +import java.awt.GraphicsEnvironment +import java.awt.Toolkit +import java.awt.event.ActionEvent +import java.awt.event.ActionListener +import java.util.logging.Level +import java.util.logging.Logger +import javax.swing.* +import javax.swing.event.DocumentEvent +import javax.swing.event.DocumentListener + +class CoerceDialog: JDialog(frame.v), ActionListener { + private val FONTS = + GraphicsEnvironment.getLocalGraphicsEnvironment().availableFontFamilyNames.copyOf().apply { + sort() + } + private val SIZES = + arrayOf(9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 16.0f, 18.0f, + 24.0f, 36.0f, 48.0f, 64.0f, 72.0f, 96.0f, 144.0f, 288.0f) + private val DSIZEI = 6 /* SIZES[6] = 16 */ + + /* the proportional font family */ + private val _pFamily = JComboBox<String>(FONTS).apply { + selectedIndex = getFontIndex(Font.SERIF) + } + val pFamily: String + get() { + return _pFamily.selectedItem as String + } + + /* the proportional font size */ + private val _pSize = JComboBox<Float>(SIZES).also { + it.selectedIndex = DSIZEI + it.setEditable(true) + it.actionCommand = "Size" + it.addActionListener(this) + } + val pSize: Float + get() { + return _pSize.selectedItem as Float + } + + /* the monospaced font family */ + private val _mFamily = JComboBox<String>(FONTS).apply { + selectedIndex = getFontIndex(Font.MONOSPACED) + } + val mFamily: String + get() { + return _mFamily.selectedItem as String + } + + /* the monospaced font size */ + private val _mSize = JComboBox<Float>(SIZES).also { + it.selectedIndex = DSIZEI + it.setEditable(true) + it.actionCommand = "Size" + it.addActionListener(this) + } + val mSize: Float + get() { + return _mSize.selectedItem as Float + } + + /* standard spacing between elements (10 pixels ≅ 1/7") and half that */ + private val BW = 5 + private val BW2 = 10 + private val VSPACE = Box.createVerticalStrut(BW) + private val VSPACE2 = Box.createVerticalStrut(BW2) + private val HSPACE2 = Box.createHorizontalStrut(BW2) + + /* buttons */ + private val _coerce = JButton("Coerce").also { + it.actionCommand = "Coerce" + it.addActionListener(this) + } + + private val _cancel = JButton("Cancel").also { + it.actionCommand = "Cancel" + it.addActionListener(this) + } + + /* initializer */ + init { + title = "Coerce Fonts" + contentPane.apply { + add(Box(BoxLayout.Y_AXIS).apply { + add(VSPACE2) + add(leftLabel("Coerce proportionally-spaced text to:")) + add(VSPACE) + add(Box(BoxLayout.X_AXIS).apply { + add(HSPACE2) + add(Box.createGlue()) + add(Box(BoxLayout.Y_AXIS).apply { + add(leftLabel("Family:")) + add(_pFamily) + }) + add(Box.createGlue()) + add(Box(BoxLayout.Y_AXIS).apply { + add(leftLabel("Size:")) + add(_pSize) + }) + add(Box.createGlue()) + add(HSPACE2) + }) + add(VSPACE2) + add(JSeparator()) + add(VSPACE2) + add(leftLabel("Coerce monospaced text to:")) + add(VSPACE) + add(Box(BoxLayout.X_AXIS).apply { + add(HSPACE2) + add(Box.createGlue()) + add(Box(BoxLayout.Y_AXIS).apply { + add(leftLabel("Family:")) + add(_mFamily) + }) + add(Box.createGlue()) + add(Box(BoxLayout.Y_AXIS).apply { + add(leftLabel("Size:")) + add(_mSize) + }) + add(Box.createGlue()) + add(HSPACE2) + }) + add(VSPACE2) + add(JSeparator()) + add(VSPACE2) + add(Box(BoxLayout.X_AXIS).apply { + add(Box.createGlue()) + add(_cancel) + add(Box.createGlue()) + add(_coerce) + add(Box.createGlue()) + }) + add(VSPACE2) + }) + } + rootPane.setDefaultButton(_coerce) + pack() + } + + private fun leftLabel(text: String) = JLabel(text).apply { + horizontalAlignment = JLabel.LEFT + alignmentX = JLabel.LEFT_ALIGNMENT + } + + override fun actionPerformed(e: ActionEvent) { + when (e.actionCommand) { + "Size" -> { + val source = e.source as? JComboBox<Float> + if (source != null && (source.selectedItem as Float) < 1.0f) { + Toolkit.getDefaultToolkit().beep() + source.selectedIndex = DSIZEI + } + } + "Coerce" -> { + setVisible(false) + coerce() + } + "Cancel" -> setVisible(false) + } + } + + private fun coerce() { + val selected = queue.v.getSelected() + if (selected == null) { + JOptionPane.showMessageDialog(frame.v, + "No item selected.", + "Error", + JOptionPane.ERROR_MESSAGE) + } else { + val (plain, html) = when (selected.contents) { + is PasteboardItem.Plain -> + Pair(selected.contents.plain, null) + is PasteboardItem.HTML -> + Pair(selected.contents.plain, selected.contents.html) + is PasteboardItem.RTF -> + Pair(selected.contents.plain, selected.contents.html) + } + if (html == null) { + JOptionPane.showMessageDialog(frame.v, + "Only styled texts may be coerced.", + "Error", + JOptionPane.ERROR_MESSAGE) + } else { + PasteboardItem.write( + PasteboardItem.HTML( + plain, + coerceHTML(html, normalizeFont(pFamily), pSize, + normalizeFont(mFamily), mSize))) + } + } + } + + private fun getFontIndex(font: String): Int { + val found = FONTS.indexOf(font) + if (found < 0) { + LOGGER.log(Level.WARNING, "font '${font}' not found") + return 0 + } + return found + } + + private fun normalizeFont(font: String): String { + val lcFont = font.toLowerCase() + return when (lcFont) { + in setOf("monospace", "serif", "sans-serif") -> lcFont + "monospaced" -> "monospace" + "sansserif" -> "sans-serif" + else -> font + } + } +} + +val coerceDialog = CoerceDialog()