Skip to content

Add context menu#439

Merged
JordanMartinez merged 3 commits intoFXMisc:masterfrom
JordanMartinez:addContextMenu
Jan 28, 2017
Merged

Add context menu#439
JordanMartinez merged 3 commits intoFXMisc:masterfrom
JordanMartinez:addContextMenu

Conversation

@JordanMartinez
Copy link
Copy Markdown
Contributor

@JordanMartinez JordanMartinez commented Jan 26, 2017

This addresses #363.

There is no ContextMenu by default: this matches the same behavior as all other nodes.

Questions

  • Should the default offset values be 5 or some positive non-zero value? In the TestFX test, having it as zero will fail the tests because the mouse clicks on the menu rather than the area once it is shown. Developer who set the menu in their code will also need to override the default values every time, which is unnecessary boilerplate.
    • Edit: I've updated the PR to set the default offset values to 2. There's no specific reason for this choice, so it's up for modification.

@JFormDesigner
Copy link
Copy Markdown
Contributor

IMHO it would be better to use ContextMenuEvent.CONTEXT_MENU_REQUESTED, instead of mouseClicked(MouseButton.SECONDARY), to show the context menu. Then the user can also use the keyboard to show the context menu.

javafx.scene.control.Control also uses ContextMenuEvent.CONTEXT_MENU_REQUESTED.

@JordanMartinez
Copy link
Copy Markdown
Contributor Author

Ah! Good point! I assumed it was just a right-click.

@JordanMartinez
Copy link
Copy Markdown
Contributor Author

I've included @JFormDesigner's point about the ContextMenuEvent.

@JordanMartinez
Copy link
Copy Markdown
Contributor Author

Since I haven't heard anything else about the default offset values, I'm going to merge this. They can always be modified later on if need be.

@Groostav
Copy link
Copy Markdown

If I wanted a context menu containing the usual copy, paste, undo, redo, etc, whats the easiest way to get it?

RichTextFX exposes the functionality of a text-field with methods simply named copy(), paste(), etc, which are pretty clearly meant for this purpose.

But:

  1. theres no delete() method
  2. the undo and redo disable if no previous state and disable if no next state bindings are non-trivial
  3. the cut and copy disable if no text selected is non-trivial,
  4. anything else im missing? icons?

I'm wondering if you would be kind enough to write one, and then let us do something like create a static method createDefaultContextMenu, such that I could write

styleClassedTextArea.contextMenu = StyleClassTextArea.makeDefaultContextMenu()

or even

<StyleClassedTextArea>
  <contextMenu>
    <StyleClassedTextArea fx:factory="makeDefaultContextMenu"/>
  </contextMenu>
</StyleClassedTextArea>

@Jugen
Copy link
Copy Markdown
Collaborator

Jugen commented Jan 14, 2020

@Groostav

I'm wondering if you would be kind enough to write one ....

Here you go, modify and style as needed, to use do: area.setContextMenu(new DefaultContextMenu())

private class DefaultContextMenu extends ContextMenu
{
    private MenuItem cut, copy, delete, paste, undo, redo;
    private GenericStyledArea area;
    private IndexRange range;
    
    public DefaultContextMenu()
    {
        showingProperty().addListener( (ob,ov,showing) -> checkMenuItems( showing ) );

        cut = new MenuItem( "Cut" );
        cut.setOnAction( AE -> { hide(); area.cut(); } );

        copy = new MenuItem( "Copy" );
        copy.setOnAction( AE -> { hide(); area.copy(); } );

        delete = new MenuItem( "Delete" );
        delete.setOnAction( AE -> { hide(); area.deleteText( range ); } );

        paste = new MenuItem( "Paste" );
        paste.setOnAction( AE -> { hide(); area.paste(); } );

        redo = new MenuItem( "Redo" );
        redo.setOnAction( AE -> { hide(); area.redo(); } );

        undo = new MenuItem( "Undo" );
        undo.setOnAction( AE -> { hide(); area.undo(); } );

        getItems().addAll( copy, cut, delete, paste, redo, undo );
    }
    
    private void checkMenuItems( boolean showing )
    {
        if ( ! showing ) return;

        area = (GenericStyledArea) getOwnerNode();
        UndoManager history = area.getUndoManager();
        undo.setDisable( ! history.isUndoAvailable() );
        redo.setDisable( ! history.isRedoAvailable() );

        range = area.getSelection();
        boolean noSelection = range.getLength() == 0;
        delete.setDisable( noSelection );
        copy.setDisable( noSelection );
        cut.setDisable( noSelection );
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants