Mercurial > cgi-bin > hgweb.cgi > ClipMan
view src/name/blackcap/clipman/SettingsDialog.kt @ 41:33fbe3a78d84
Got the settings stuff compiling (untested).
author | David Barts <n5jrn@me.com> |
---|---|
date | Sat, 08 Feb 2020 22:10:01 -0700 |
parents | |
children | 339e2da5bf83 |
line wrap: on
line source
/* * The dialog that controls font corecion. */ package name.blackcap.clipman import java.awt.Color import java.awt.Container import java.awt.Dimension import java.awt.Font import java.awt.GraphicsEnvironment import java.awt.Toolkit import java.awt.event.ActionEvent import java.awt.event.ActionListener import java.io.BufferedWriter import java.io.FileOutputStream import java.io.IOException import java.io.OutputStreamWriter import java.util.Hashtable import java.util.Properties import java.util.logging.Level import java.util.logging.Logger import javax.swing.* import javax.swing.event.ChangeEvent import javax.swing.event.ChangeListener import kotlin.math.log10 import kotlin.math.pow import kotlin.math.roundToInt import kotlin.text.toFloat import kotlin.text.toInt /* work around name shadowing */ private val _PROPS = PROPERTIES class SettingsDialog: JDialog(frame.v), ActionListener, ChangeListener { /* the proportional font family */ private val _pFamily = JComboBox<String>(FONTS).apply { selectedItem = _PROPS.getString("prop.family") alignmentX = JComboBox.LEFT_ALIGNMENT } val pFamily: String get() { return _pFamily.selectedItem as String } /* the proportional font size */ private val _pSize = JComboBox<Float>(SIZES).also { it.selectedItem = _PROPS.getFloat("prop.size") it.alignmentX = JComboBox.LEFT_ALIGNMENT it.setEditable(true) } val pSize: Float get() { return _pSize.selectedItem as Float } /* the monospaced font family */ private val _mFamily = JComboBox<String>(FONTS).apply { selectedItem = _PROPS.getString("mono.family") alignmentX = JComboBox.LEFT_ALIGNMENT } val mFamily: String get() { return _mFamily.selectedItem as String } /* the monospaced font size */ private val _mSize = JComboBox<Float>(SIZES).also { it.selectedItem = _PROPS.getFloat("mono.size") it.alignmentX = JComboBox.LEFT_ALIGNMENT it.setEditable(true) } val mSize: Float get() { return _mSize.selectedItem as Float } /* max queue length */ private val _qLength = _PROPS.getInt("queue.length") private val _qlSlider = JSlider(10000, 30000, spinToSlide(_qLength)).also { it.majorTickSpacing = 10000 it.paintTicks = true it.labelTable = Hashtable<Int, String>().apply { put(10000, "10") put(20000, "100") put(30000, "1000") } it.addChangeListener(this) } private val _qlSpinner = JSpinner(SpinnerNumberModel(_qLength, 10, 1000, 1)).also { it.addChangeListener(this) } val qLength: Int get() { return _qlSpinner.value as Int } /* standard spacing between elements (10 pixels ≅ 1/7") and half that */ private val BW = 5 private val BW2 = 10 /* buttons */ private val _ok = JButton("OK").also { it.actionCommand = "OK" it.addActionListener(this) } private val _cancel = JButton("Cancel").also { it.actionCommand = "Cancel" it.addActionListener(this) } private val _rad = JButton("Restore All Defaults").also { it.actionCommand = "Restore" it.addActionListener(this) } /* initializer */ init { title = "Preferences" contentPane.apply { add(Box(BoxLayout.Y_AXIS).apply { add(Box(BoxLayout.Y_AXIS).apply { border = BorderFactory.createEmptyBorder(BW2, BW2, BW, BW2) alignmentX = Box.CENTER_ALIGNMENT add(leftLabel("Default proportionally-spaced font:")) add(Box.createVerticalStrut(BW)) add(Box(BoxLayout.X_AXIS).apply { alignmentX = Box.LEFT_ALIGNMENT 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(JSeparator()) add(Box(BoxLayout.Y_AXIS).apply { alignmentX = Box.CENTER_ALIGNMENT border = BorderFactory.createEmptyBorder(BW, BW2, BW, BW2) add(leftLabel("Default monospaced font:")) add(Box.createVerticalStrut(BW)) add(Box(BoxLayout.X_AXIS).apply { alignmentX = Box.LEFT_ALIGNMENT 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(JSeparator()) add(Box(BoxLayout.Y_AXIS).apply { alignmentX = Box.CENTER_ALIGNMENT border = BorderFactory.createEmptyBorder(BW, BW2, BW, BW2) add(leftLabel("Maximum queue size:")) add(Box.createVerticalStrut(BW)) add(Box(BoxLayout.X_AXIS).apply { alignmentX = Box.LEFT_ALIGNMENT add(Box.createGlue()) add(_qlSlider) add(Box.createGlue()) add(_qlSpinner) add(Box.createGlue()) }) }) add(JSeparator()) add(Box(BoxLayout.X_AXIS).apply { alignmentX = Box.CENTER_ALIGNMENT border = BorderFactory.createEmptyBorder(BW, BW2, BW, BW2) add(Box.createGlue()) add(_rad) add(Box.createGlue()) add(_cancel) add(Box.createGlue()) add(_ok) add(Box.createGlue()) }) }) } rootPane.setDefaultButton(_ok) pack() setResizable(false) } override fun actionPerformed(e: ActionEvent) { when (e.actionCommand) { "OK" -> { writeProperties() queue.v.maxSize = qLength setVisible(false) } "Cancel" -> setVisible(false) "Restore" -> revertProperties() } } override fun stateChanged(e: ChangeEvent) { when (val source = e.source) { source === _qlSlider -> _qlSpinner.value = (10.0).pow(_qlSlider.value.toDouble() / 10000.0).roundToInt() source === _qlSpinner -> _qlSlider.value = spinToSlide(_qlSpinner.value as Int) } } private fun spinToSlide(value: Int): Int = (log10(value.toDouble()) * 10000.0).roundToInt() private fun leftLabel(text: String) = JLabel(text).apply { alignmentX = JLabel.LEFT_ALIGNMENT } private fun badSize(control: JComboBox<Float>, default: Float, fontType: String): Boolean { val size = control.selectedItem as? Float if (size == null || size < 1.0f) { JOptionPane.showMessageDialog(frame.v, "Invalid ${fontType} font size.", "Error", JOptionPane.ERROR_MESSAGE) control.selectedItem = default return true } return false } private fun revertProperties() { val params = arrayOf("mono.family", "mono.size", "prop.family", "prop.size", "queue.length") for (param in params) { _PROPS.put(param, DPROPERTIES.get(param)) } _mFamily.selectedItem = _PROPS.getString("mono.family") _mSize.selectedItem = _PROPS.getFloat("mono.size") _pFamily.selectedItem = _PROPS.getString("prop.family") _pSize.selectedItem = _PROPS.getFloat("prop.size") val ql = _PROPS.getInt("queue.length") _qlSpinner.value = ql _qlSlider.value = spinToSlide(ql) } private fun writeProperties() { try { BufferedWriter(OutputStreamWriter(FileOutputStream(PROP_FILE), CHARSET)).use { _PROPS.put("mono.family", mFamily) _PROPS.put("mono.size", mSize.toString()) _PROPS.put("prop.family", pFamily) _PROPS.put("prop.size", pSize.toString()) _PROPS.put("queue.length", qLength.toString()) _PROPS.store(it, null) } } catch (e: IOException) { LOGGER.log(Level.WARNING, "IOException writing properties file") val message = e.message if (message != null && !message.isEmpty()) { LOGGER.log(Level.WARNING, message) } JOptionPane.showMessageDialog(frame.v, "Unable to write settings.", "Error", JOptionPane.ERROR_MESSAGE) } } } val settingsDialog = SettingsDialog() fun Properties.getString(key: String): String = get(key) as String fun Properties.getInt(key: String): Int = getString(key).toInt() fun Properties.getFloat(key: String): Float = getString(key).toFloat()