Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

Multi-Selecting Nodes #40

Open
Seneral opened this issue Feb 18, 2016 · 8 comments
Open

Multi-Selecting Nodes #40

Seneral opened this issue Feb 18, 2016 · 8 comments

Comments

@Seneral
Copy link
Owner

Seneral commented Feb 18, 2016

Description: Selecting, moving, deleting and duplicating multiple nodes.

State: None. May need adjustements to NodeEditorState and the input checking system.

@rudinesurya
Copy link

I am trying to implement this now, I removed left click condition from the window panning and create another functions to listen when left click is performed in the window area and while not selecting any nodes.

How can I draw a rect in the canvas ?

`

    #region Window Selecting

    static Vector2 startSelectionPos;

    [EventHandlerAttribute(EventType.MouseDown, priority = 105)] // Priority over hundred to make it call after the GUI
    private static void HandleWindowSelectionStart(NodeEditorInputInfo inputInfo)
    {
        if (GUIUtility.hotControl > 0)
            return; // GUI has control

        NodeEditorState state = inputInfo.editorState;
        if (inputInfo.inputEvent.button == 0 && state.focusedNode == null)
        { // Left clicked on the empty canvas -> Start the selection process
            state.boxSelecting = true;
            Debug.Log("box selecting start");
            startSelectionPos = inputInfo.inputPos;
        }
    }

    [EventHandlerAttribute(EventType.MouseDrag)]
    private static void HandleWindowSelection(NodeEditorInputInfo inputInfo)
    {
        NodeEditorState state = inputInfo.editorState;
        if (state.boxSelecting)
        {
            Debug.Log("box selecting");

            Rect handleRect = new Rect();

            handleRect.min = startSelectionPos;
            handleRect.max = inputInfo.inputPos;

            //handleRect.position += state.zoomPanAdjust + state.panOffset;

            GUI.Box(handleRect, GUIContent.none);


            NodeEditor.RepaintClients();
        }
    }

    [EventHandlerAttribute(EventType.MouseDown)]
    [EventHandlerAttribute(EventType.MouseUp)]
    private static void HandleWindowSelectionEnd(NodeEditorInputInfo inputInfo)
    {
        if (inputInfo.editorState.boxSelecting)
        {
            Debug.Log("box selecting end");

            inputInfo.editorState.boxSelecting = false;
        }
    }

    #endregion

`

@Seneral
Copy link
Owner Author

Seneral commented Mar 29, 2016

Hi @rudinesurya, cool that you're working on that. It will be very easy to draw the box, as it would probably need to be unscaled, so you could do that right before starting the scaling in the drawing function. You could also do that in HandleWindowSelection, just add the Repaint EventHandler in that case and also limit further instructions based on the eventType.
Regarding the style, there is an editor style that the editor uses for the selection rect, so it could be used in the editor version atleast (when I'm back home I can search it for you, I've used it in a previous project).
One note though, instead of disabling or replacing the panning controls, it'd be better to use different controls for the multi selection, like Shift or Shift-Left click. Left-click and dragging is simply the best and expected control for panning I think...
Also, there might be issues regarding input when you're at the point where you're able to select ultiple nodes. You would have to search for references of both the active and focusd node and decide if it's apropriate to perform the action on all selected nodes instead. Selected/Active and focused nodes should still be seperate in the editor state though.

@rudinesurya
Copy link

I am thinking of similar idea with the group feature. OnWindowSelectionEnd I will add all the nodes within the box into a static list. Then I might need to add another condition to the current drag node function to check if the selected node is inside the list. if it is then drag the whole list. What do you think =)

@rudinesurya
Copy link

i think left clicking and dragging is usually used to group select, and middle mouse for panning. I know ue4, playmaker, mecanim uses this.

@Seneral
Copy link
Owner Author

Seneral commented Mar 29, 2016

Ok, change panning controls to the middle button.
Yes, it should work similar to this. But don't make it static, remember it has to do with the editor state, so it belongs there. Also shift-click to multi select would be nice. Not only drag, but also other controls have to be adjusted to the multi select if apropriate. I let you decide:)

@wqaetly
Copy link

wqaetly commented Aug 15, 2020

I got inspiration from this old man’s speech and completed this multi-box selection function
image
10

This is the core code,
`

    private static void HandleMultipleSelect()
    {
        if (curEditorState.boxSelecting)
        {
            Rect handleRect = new Rect();

            handleRect.min = NodeEditorInputControls.startSelectionPos;
            handleRect.max = Event.current.mousePosition;
            
            GUI.Box(handleRect, GUIContent.none, NodeEditorGUI.nodeBox);

            Rect canvasRect = new Rect();
            Vector2 start = ScreenToCanvasSpace(NodeEditorInputControls.startSelectionPos);
            Vector2 end = ScreenToCanvasSpace(Event.current.mousePosition);

            canvasRect.min = Vector2.Min(start, end);
            canvasRect.max = Vector2.Max(start, end);
            
            curEditorState.selectedNodes.Clear();
            foreach (var node in curNodeCanvas.nodes)
            {
                if (canvasRect.Contains(node.position))
                {
                    curEditorState.selectedNodes.Add(node);
                }
            }
        }
    }

`
Hope it is useful to people who see this issue

As Seneral said, implementing these functions requires a lot of modification of the framework code, so I have no way to mention PR, sorry

If you want to see a more complete sample code, including the implementation of highlighting Node, please go to
A state-synchronized Moba project

@Seneral
Copy link
Owner Author

Seneral commented Aug 15, 2020

@wqaetly Thanks, that looks really good. I currently don't have a lot of time working on new features, I am currently focussing on my other project, MakersVR. But I will try implementing it soon.
Contrary to popular bindings (Middle click to pan, left click to multi-select) I'd go with different bindings to preserve the current ones as much as possible. I thought about adding multi-select using shift-left-click (or control-left-click), which resembles the common keybinding for multi-selecting list items. I imagine that would be a lot more clunky, but I don't wan't to break existing user's muscle memory.

@wqaetly
Copy link

wqaetly commented Aug 16, 2020

Yes, for example, the function of holding down shift to select multiple Nodes is also very important, because in some cases the Nodes you want to select may be scattered in various places in Canvas
But one thing is very important, that is, the selectedNode field in editorState must be changed to List, and then the logic of dragging, copying, and deleting is handled, so that whether it is frame selection or shift selection, it is easier to implement

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants