[V8i C++] MstnElementSetTool and complex element "picking"

I've got a question about how to develop a MstnElementSetTool that needs to be able to select text elements in order to "fill-in" an existing Data Field. I imagine the tool to work in the following manner:

 

1. User "nominates" text element containing data field with datapoint.

2. User "accepts" text element with datapoint. I save the ElementRef.

3. User now "nominates" other text elements ( 1 or more ) via single element "picks" or DragSelect. Tool also supports CTRL+/- of text elements.

4. User "accepts" the second (possibly multiple) selection.

5. I do some magic with the second group of text elements and create a single, final text string that gets put into the initial text's enter data fields. 

 

I suspect it's somehow possible to determine when I complete step 2. but I'm not sure how to "restart" the element selection process for step 3 and beyond.

 

 

Bruce

Parents
  • Selecting multiple elements can be accomplished with WantAdditionalLocate...

    You can set your tool up so that it will complete on an un-qualified data point once a minimum of 2 elements have been selected, but ctrl can be held to locate N additional elements.

    What you would want to do, is in your post-locate filter, only accept an element with a data field when the tool's agenda is currently empty (so the first entry in your tool's agenda will be the data field to fill in).

    Now, only select text elements that you want to use to fill your data field (don't allow the data field to be selected again). The default tool behavior when selecting an already accepted element with ctrl held is to remove it from the tool agenda.

    I cobbled together the snippet below, it should get you started if you want to take this approach. NOTE: This should work fine if you also enable drag select, just be aware that since your post-locate filter isn't called in this case, you'll need to validate the elements that get selected by crossing line or box selection using FilterAgendaEntries.

    HTH

    -B

    /*=================================================================================**//**
    * Contrived example tool to demonstrate using WantAdditionalLocate.
    * Tool completes when a minimum of 2 elements are selected. if the control key is 
    * down, then additional elements can be identified.
    *
    * @bsiclass
    +===============+===============+===============+===============+===============+======*/
    struct ExampleTool : MstnElementSetTool
    {
    public:
    
    /*---------------------------------------------------------------------------------**//**
    * @bsimethod
    +---------------+---------------+---------------+---------------+---------------+------*/
    void ExampleTool::SetupForLocate (int count)
        {
        __super::SetLocateCursor (count < 2 ? true : false, -1);
    
        UInt32      msgId = PROMPT_ExampleToolComplete;
    
        switch (count)
            {
            case 0:
                msgId = PROMPT_ExampleToolFirst;
                break;
    
            case 1:
                msgId = PROMPT_ExampleToolNext;
                break;
            }
    
        mdlOutput_rscPrintf (MSG_PROMPT, NULL, STRINGLISTID_Prompts, msgId);
        }
    
    /*---------------------------------------------------------------------------------**//**
    * @bsimethod
    +---------------+---------------+---------------+---------------+---------------+------*/
    virtual void ExampleTool::SetupAndPromptForNextAction () override {SetupForLocate (GetElemAgendaP ()->GetCount ());} // All changes to auto-locate/accusnap state and user prompts are done here!!!
    
    /*---------------------------------------------------------------------------------**//**
    * @bsimethod
    +---------------+---------------+---------------+---------------+---------------+------*/
    virtual UsesSelection ExampleTool::AllowSelection () override {return USES_SS_None;} // In this example don't support selection sets...(or fences MstnElementSetTool default)
    virtual bool ExampleTool::DoGroups () override () ooverride {return false;} // For this example don't include graphic/named group members for located element...
    virtual bool ExampleTool::WantDynamics () override {return false;} // Don't start dynamics...
    virtual bool ExampleTool::NeedAcceptPoint () override {return true;} // Accept point is required for multi-locate to give the user a chance to identity additional elements...
    
    /*---------------------------------------------------------------------------------**//**
    * @bsimethod
    +---------------+---------------+---------------+---------------+---------------+------*/
    virtual bool ExampleTool::WantAdditionalLocate (MstnButtonEventCP ev) override
        {
        if (NULL == ev)
            return true; // This is a multi-locate tool...
    
        // Require a minumum of 2 elements, if control is down select additional elements...
        return (GetElemAgendaP ()->GetCount () < 2 || ev->IsControlKey ());
        }
    
    /*---------------------------------------------------------------------------------**//**
    * @bsimethod
    +---------------+---------------+---------------+---------------+---------------+------*/
    virtual bool ExampleTool::OnModifierKeyTransition (bool wentDown, int key) override
        {
        // Control key state change, may need to enable/disable auto-locate, change cursor, prompts. etc.
        if (TOGGLESELECT_MODKEY != key)
            return false;
    
        if (GetElemAgendaP ()->GetCount () < 2)
            return false;
    
        SetupForLocate (wentDown ? 1 : 2);
    
        return true;
        }



    Answer Verified By: Bruce Reeves SRNS 

  • Thanks !! I'll give this a test drive.

     

    A somewhat related question regarding selecting elements. When I allow DragSelect and I drag the "select" line across elements, the locate process "finds" the elements I intersected, and I can see them in FilterAgendaEntries(). However, if I datapoint/drag to begin the selection process when the cursor is currently "over" an element (i.e. the locate logic has nominated an element) and I continue to drag, nothing else is selected. Is there some way to "force" the selection/location process to NOT pick the element the cursor is over IF the mouse is down and held and use the "drag" line elements instead?

  • Unknown said:
    Is there some way to "force" the selection/location process to NOT pick the element the cursor is over IF the mouse is down and held and use the "drag" line elements instead?

    The first thing to understand is how drag selection works. On the data button down event, interest is registered for drag events using mdlState_setFunction with STATE_DRAG_INIT. Now if the cursor moves a sufficient distance before getting an up event for the data button, the drag is initiated.

    Because our tools process the data button on the down event in order to locate elements/advance the tool state (and don't get both down and up events for data, only down), it's not possible to support initiating drag selection while over an element without the element also being located. You would have to be able to do the locate on the up event, which wouldn't be sent when/if a drag started. But as already mentioned, tools don't get sent an up event for data button currently...and it might also feel "odd" to the user doing things on up instead of down.

    Anyway, this is the reason why MstnElementSetTool only registers for drag events when an element isn't located. NOTE: The user can set the locate interior preference to "never" tomake it easier to use drag selection in a rendered view, or when their are filled shapes, etc.

    Now, while it would be possible to make the tool only work using drag (i.e. you never call locate in your data point function)...that would be fairly non-standard tool behavior and not very discoverable either (user might click on things and be confused why nothing is happening). There's also a user preference that disables drag selection, which would make your tool non-functional.

    One approach to this problem is to add buttons for various selection modes to the tool settings like the Element Selection tool and some mesh tools do. Then you'll now to accumulate points for the selection line/box/shape, etc. in your data button method instead of calling locate.

    HTH

    -B



    Answer Verified By: Bruce Reeves SRNS 

Reply
  • Unknown said:
    Is there some way to "force" the selection/location process to NOT pick the element the cursor is over IF the mouse is down and held and use the "drag" line elements instead?

    The first thing to understand is how drag selection works. On the data button down event, interest is registered for drag events using mdlState_setFunction with STATE_DRAG_INIT. Now if the cursor moves a sufficient distance before getting an up event for the data button, the drag is initiated.

    Because our tools process the data button on the down event in order to locate elements/advance the tool state (and don't get both down and up events for data, only down), it's not possible to support initiating drag selection while over an element without the element also being located. You would have to be able to do the locate on the up event, which wouldn't be sent when/if a drag started. But as already mentioned, tools don't get sent an up event for data button currently...and it might also feel "odd" to the user doing things on up instead of down.

    Anyway, this is the reason why MstnElementSetTool only registers for drag events when an element isn't located. NOTE: The user can set the locate interior preference to "never" tomake it easier to use drag selection in a rendered view, or when their are filled shapes, etc.

    Now, while it would be possible to make the tool only work using drag (i.e. you never call locate in your data point function)...that would be fairly non-standard tool behavior and not very discoverable either (user might click on things and be confused why nothing is happening). There's also a user preference that disables drag selection, which would make your tool non-functional.

    One approach to this problem is to add buttons for various selection modes to the tool settings like the Element Selection tool and some mesh tools do. Then you'll now to accumulate points for the selection line/box/shape, etc. in your data button method instead of calling locate.

    HTH

    -B



    Answer Verified By: Bruce Reeves SRNS 

Children
No Data