- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I'm writing an add-in in C++. All works fine so far. Below is a screenshot of the Add-In.
I now wanted to add a final UI-feature. The user has to select 2 points. When "Select Point A" is selected, I want the UI to automatically jump to the second button to "Select Point B". I would use the "->hasFocus(true)".
The idea was to do this in the InputChangedEventHandler. When the "Select Point A" (type SelectionCommandInput) has a point selected, then I would grab the "Select Point B" (also type SelectionCommandInput) and focus it.
The code looks like this:
class ThickLineInputChangedEventHandler : public InputChangedEventHandler
{
public:
void notify(const Ptr<InputChangedEventArgs>& eventArgs) override
{
Ptr<CommandInputs> inputs = eventArgs->inputs();
Ptr<CommandInput> changed = eventArgs->input();
if (!inputs || !changed)
return;
if (changed->id() == kSelPointAId)
{
Ptr<SelectionCommandInput> selA = changed->cast<SelectionCommandInput>();
if (selA && selA->selectionCount() == 1)
{
// User just finished picking point A -> set focus to point B
Ptr<SelectionCommandInput> selB = inputs->itemById(kSelPointBId)->cast<SelectionCommandInput>();
if (selB)
selB->hasFocus(true);
}
}
... rest of code
(kSelPointAId and kSelPointBId are static const char* that contains the id's of the 2 fields)
This code crashes because of a nullPtr. And the reason is that "inputs->itemById(kSelPointBId)" returns a nullPtr. But WHY?
The reason seems to have to do with groups. In my CommandCreatedEventHandler, I create 2 groups. One for "Point A" and one for "Point B". If you look at the UI screenshot, you will see this. The relevant code in the CommandCreatedEventHandler looks like this:
... previous code of CommandCreatedEventHandler
// Group A & B to mirror UI layout
Ptr<GroupCommandInput> grpA = inputs->addGroupCommandInput(kGroupA, "Point A");
grpA->isExpanded(true);
Ptr<CommandInputs> giA = grpA->children();
Ptr<GroupCommandInput> grpB = inputs->addGroupCommandInput(kGroupB, "Point B");
grpB->isExpanded(true);
Ptr<CommandInputs> giB = grpB->children();
// ---- Point A block ----
{
// Select Point A
Ptr<SelectionCommandInput> selA = giA->addSelectionInput(kSelPointAId, "Select Point A", "Pick the start point (A)");
addPointSelectionFilters(selA);
... remaining items of group A
}
// ---- Point B block ----
{
// Select Point B
Ptr<SelectionCommandInput> selB = giB->addSelectionInput(kSelPointBId, "Select Point B", "Pick the end point (B)");
addPointSelectionFilters(selB);
... remaining items of group B
It now seems that the line "Ptr<CommandInputs> inputs = eventArgs->inputs();" in the InputChangedEventHandler does NOT ALWAYS return all the inputs of the dialog. If the changed input, retrieved through "Ptr<CommandInput> changed = eventArgs->input();", belongs to a group, then "inputs" seems only to return the inputs of that same group, and nothing more.
Is this by design, or is this some bug?
And this of course explains why my code is crashing. I can not reach to the kSelPointBId through the inputs provided when kSelPointAId has changed. Reason is that I only get the group A inputs, which means that "inputs->itemById(kSelPointBId)" returns a nullPtr.
Is there a way to get all inputs in InputChangedEventHandler? Of course, I can use a global variable "g_inputs" that is getting its value during the create event. But I was just wondering if there is a standard way.
I can not attach my cpp file (not allowed?). But I think that the necessary code fragments are in my post. If not, don't hesitate to ask more details.
Solved! Go to Solution.