view src/name/blackcap/clipman/Menus.kt @ 27:8aa2dfac27eb

Big reorg; compiled but untested.
author David Barts <n5jrn@me.com>
date Wed, 29 Jan 2020 10:50:07 -0800
parents
children f1fcc1281dad
line wrap: on
line source

/*
 * Menu-related stuff, pertaining to both the menu bar and popup menus.
 */
package name.blackcap.clipman

import java.awt.Toolkit
import java.awt.event.ActionEvent
import java.awt.event.ActionListener
import java.awt.event.KeyEvent
import java.util.LinkedList
import javax.swing.*

/**
 * Listen to actionEvents from both menu bar and popup menu selections.
 */
class MenuItemListener: ActionListener {
    override fun actionPerformed(e: ActionEvent) {
        when (e.actionCommand) {
            "File.Quit" -> System.exit(0)
            "Edit.Clone" -> onlyIfSelected { queue.v.add(it) }
            "Edit.Coerce" -> onlyIfSelected { doCoerceFonts(it) }
            "Edit.Delete" -> onlyIfSelected {
                queue.v.delete(it)
                SelectionRequired.disable()
            }
            "Edit.Find" -> searchDialog.setVisible(true)
            "Edit.FindAgain" -> searchDialog.find()
            else -> throw RuntimeException("unexpected actionCommand!")
        }
    }

    private fun onlyIfSelected(block: (QueueItem) -> Unit) {
        val selected = queue.v.getSelected()
        if (selected == null) {
            JOptionPane.showMessageDialog(frame.v,
                "No item selected.",
                "Error",
                JOptionPane.ERROR_MESSAGE);
         } else {
            block(selected)
        }
    }

    private fun doCoerceFonts(item: QueueItem) {
        /* not finished */
    }
}

val menuItemListener = MenuItemListener()

/**
 * Our menu bar. What we display depends somewhat on the system type, as
 * the Mac gives us a gratuitous menu bar entry for handling some stuff.
 */
class MyMenuBar: JMenuBar() {
    init {
        if (OS.type != OS.MAC) {
            add(JMenu("File").apply {
                add(JMenuItem("Quit").apply {
                    actionCommand = "File.Quit"
                    addActionListener(menuItemListener)
                    makeShortcut(KeyEvent.VK_Q)
                })
            })
        }
        add(JMenu("Edit").apply {
            add(SelectionRequired.add(JMenuItem("Clone").apply {
                setEnabled(false)
                actionCommand = "Edit.Clone"
                addActionListener(menuItemListener)
                makeShortcut(KeyEvent.VK_C)
            }))
            add(SelectionRequired.add(JMenuItem("Coerce…").apply {
                setEnabled(false)
                actionCommand = "Edit.Coerce"
                addActionListener(menuItemListener)
                makeShortcut(KeyEvent.VK_K)
            }))
            add(SelectionRequired.add(JMenuItem("Delete").apply {
                setEnabled(false)
                actionCommand = "Edit.Delete"
                addActionListener(menuItemListener)
                setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0))
            }))
            add(JMenuItem("Find…").apply {
                actionCommand = "Edit.Find"
                addActionListener(menuItemListener)
                makeShortcut(KeyEvent.VK_F)
            })
            add(JMenuItem("Find Again").apply {
                setEnabled(false)
                actionCommand = "Edit.FindAgain"
                addActionListener(menuItemListener)
                makeShortcut(KeyEvent.VK_G)
            })
        })
        if (OS.type != OS.MAC) {
            add(JMenu("Help").apply {
                add(JMenuItem("About ClipMan…").apply {
                    actionCommand = "Help.About"
                    addActionListener(menuItemListener)
                })
            })
        }
    }

    fun getMenu(name: String): JMenu? {
        subElements.forEach {
            val jmenu = it.component as? JMenu
            if (jmenu?.text == name) {
                return jmenu
            }
        }
        return null
    }
}

val menuBar = MyMenuBar()

/**
 * The popup menu we display when the user requests so atop a clipboard
 * item.
 */
class MyPopupMenu: JPopupMenu() {
    init {
        add(SelectionRequired.add(JMenuItem("Clone").apply {
            actionCommand = "Edit.Clone"
            addActionListener(menuItemListener)
        }))
        add(SelectionRequired.add(JMenuItem("Coerce…").apply {
            actionCommand = "Edit.Coerce"
            addActionListener(menuItemListener)
        }))
        add(SelectionRequired.add(JMenuItem("Delete").apply {
            actionCommand = "Edit.Delete"
            addActionListener(menuItemListener)
        }))
    }
}

val popupMenu = MyPopupMenu()

/**
 * Track menu items that require something to be selected in order
 * to work, and allow them to be enabled and disabled en masse.
 */
object SelectionRequired {
    private val cache = LinkedList<JMenuItem>()

    fun add(item: JMenuItem): JMenuItem {
        cache.add(item)
        return item
    }

    fun enable() {
        cache.forEach {
            it.setEnabled(true)
        }
    }

    fun disable() {
        cache.forEach {
            it.setEnabled(false)
        }
    }
}