[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 

Reply
  • 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 

Children