package textbender.a.r.page; // Copyright 2006-2007, Michael Allan. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Textbender Software"), to deal in the Textbender Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Textbender Software, and to permit persons to whom the Textbender Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Textbender Software. THE TEXTBENDER SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE TEXTBENDER SOFTWARE OR THE USE OR OTHER DEALINGS IN THE TEXTBENDER SOFTWARE. import java.awt.*; import java.awt.event.*; import java.rmi.*; import javax.swing.*; import javax.swing.event.*; import org.w3c.dom.*; import org.w3c.dom.events.*; import textbender.a.r.page.navdo.*; import textbender.a.u.branch.*; import textbender.d.gene.*; import textbender.g.lang.*; import textbender.g.util.logging.*; import textbender.o.awt.*; import textbender.o.rhinohide.events.RelaySIP; import textbender.o.swing.*; /** A pop-up menu for control of in-page tools. *
* Pop it context-aware by mouse (Ctrl-anyButton). *
** Pop it context-free by mouse (anyButton) in the toolbar applet. * For {@linkplain PageVisit#isPageSilent() silent pages}, * this is the only way to pop the menu. *
** Pop it context-free by keystroke (Ctrl-T). * [Maybe context-aware later, if we track browser's on-screen cursor.] * Child menu-items will usually have mnemonics, * making them invokable by additional keystrokes. *
** Mouse and key bindings are hard-coded. [Will later be configurable, * per a/z : general end-user config framework.] *
*/ final class PopupMenu { /** Constructs a PopupMenu, and installs it in-page. * It automatically releases itself at page exit. * There is no way to release it before then. ** Also gives the applet a hand cursor, as a cue. *
* * @param vP page visit, context */ @ThreadRestricted("AWT event dispatch") PopupMenu( PageVisit vP ) throws RemoteException { assert java.awt.EventQueue.isDispatchThread(); pageVisit = vP; // Dismisser button. Workaround for bug 'unwanted-guest'. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //popupMenuV.add( Box.createVerticalStrut( 10 )); ///// not clickable, so try: { JMenuItem button = new JMenuItem( "" ); button.setEnabled( false ); popupMenuV.add( button ); button.setBackground( ColorX.offBright( button.getBackground(), 0.05f )); } // Basic buttons. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { JMenuItem button = new JMenuItem( pageVisit.edt().reloadAction() ); // no need to unregister, registry does not outlive this listener button.setMnemonic( KeyEvent.VK_L ); popupMenuV.add( button ); } { JMenuItem button = new JMenuItem( pageVisit.edt().saveAction() ); button.setMnemonic( KeyEvent.VK_S ); popupMenuV.add( button ); } popupMenuV.addSeparator(); { JMenuItem button = new JMenuItem( new TestAction( pageVisit )); popupMenuV.add( button ); } { JMenuItem button = new JMenuItem( new InPageBrancher( pageVisit )); popupMenuV.add( button ); } // { // JCheckBoxMenuItem button = new JCheckBoxMenuItem( "Locus Pointer" ); // button.setModel( new EnableButton( pageVisit, pageVisit.spool() )); // button.setIcon( ImageIconX.tryCreate( getClass().getClassLoader().getResource // ( "toolbarButtonGraphics/development/BeanAdd16.gif" ), 16 )); // from textbender/o/jlfgr.jar // popupMenuV.add( button ); // } // Temporary test buttons. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // popupMenuV.addSeparator(); // { // JMenuItem button = new JMenuItem( "Test 1" ); // PRIVATE // button.addActionListener( new java.awt.event.ActionListener() // { // public void actionPerformed( java.awt.event.ActionEvent e ) // { // System.out.println( PageDaemons.i().connections().transferCHub().getTransferand() ); // } // }); // popupMenuV.add( button ); // } // { // JMenuItem button = new JMenuItem( "Test 2" ); // PRIVATE // button.addActionListener( new java.awt.event.ActionListener() // { // public void actionPerformed( java.awt.event.ActionEvent e ) // { // // registry.removeEventListener( "mouseover", testListener, /*use capture*/false ); // } // }); // popupMenuV.add( button ); // } // - - - new Popper(); } //// P r i v a t e /////////////////////////////////////////////////////////////////////// /** PopupMenu view. */ private final JPopupMenu popupMenuV = new JPopupMenu(); private final PageVisit pageVisit; // ==================================================================================== private final class Popper extends RelaySIP implements java.awt.event.MouseListener, PopupMenuListener { Popper() { assert java.awt.EventQueue.isDispatchThread(); popupMenuV.addPopupMenuListener( Popper.this ); // no need to unregister, registry does not outlive this listener // Pop from page's applet. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - pageVisit.applet().toolbar.addMouseListener( Popper.this ); // no need to unregister, registry does not outlive this listener // pageVisit.applet().toolbar.setCursor( Cursor.getPredefinedCursor( Cursor.HAND_CURSOR )); // Pop from page. // // If you ever need to disable the context menu in Gecko browsers // (maybe to prevent it appearing simultaneously with this menu) // look into altering JavaScript preferences: // window.oncontextmenu = function () { return false; } //