This article describes what to do to change how the editing of a feature starts off. By default, to start editing a feature, users need to select it on the map. By selecting it, they set the selected feature stateselected feature stateselected feature state to true. The goal is to change that, and select a feature for editing when users hover over it with the mouse cursor instead, or when a feature is configured.

Solution 1 - Configure the default edit candidate provider to use another feature state

The easiest way to change the feature statefeature statefeature state used to select a feature for editing, is to create your own instance of FeatureStateEditCandidateProviderFeatureStateEditCandidateProviderFeatureStateEditCandidateProvider, and configure it accordingly.

Program: Change a default FeatureStateEditCandidateProvider
auto easyCandidateProvider = std::make_shared<FeatureStateEditCandidateProvider>(map, FeatureState::hover());
auto hoveredEditor = Editor::newBuilder().map(map).editCandidateProvider(easyCandidateProvider).build();
var easyCandidateProvider = new FeatureStateEditCandidateProvider(map, FeatureState.Hover);
var hoveredEditor = Editor.NewBuilder().Map(map).EditCandidateProvider(easyCandidateProvider).Build();
FeatureStateEditCandidateProvider easyCandidateProvider = new FeatureStateEditCandidateProvider(map, FeatureState.Hover);
Editor hoveredEditor = Editor.newBuilder().map(map).editCandidateProvider(easyCandidateProvider).build();

Solution 2 - Create a custom IFeatureEditCandidateProvider to use a field

Your second, more complex option is to create your own implementation of IFeatureEditCandidateProviderIFeatureEditCandidateProviderIFeatureEditCandidateProvider.

In this implementation, we use a field to store which features can be edited.

Program: Create custom IFeatureEditCandidateProvider
class FixedEditCandidateProvider : public IFeatureEditCandidateProvider {
public:
  std::vector<LayerFeatureId> getEditCandidates() override {
    std::vector<LayerFeatureId> returnedVector;
    if (_candidate) {
      returnedVector.emplace_back(_candidate.value());
    }
    return returnedVector;
  }

  void setEditCandidate(const LayerFeatureId& featureId) {
    if (_candidate != featureId) {
      _candidate = featureId;
      FeatureEditCandidateEvent editCandidateEvent;
      editCandidateEvent.editCandidateAdded(featureId);
      for (const auto& observer : _observers) {
        observer->onEditCandidatesChanged(editCandidateEvent);
      }
    }
  }
  void addObserver(std::shared_ptr<IFeatureEditCandidateObserver> observer) override {
    if (findObserver(observer)) {
      throw InvalidArgumentException("Cannot add observer more than once.");
    }
    _observers.push_back(std::move(observer));
  }
  void removeObserver(const std::shared_ptr<IFeatureEditCandidateObserver>& observer) override {
    auto index = findObserver(observer);
    if (!index) {
      throw InvalidArgumentException("Cannot remove unknown observer.");
    }
    _observers.erase(_observers.cbegin() + *index);
  }

private:
  // returns the index of the observer if found, nullopt otherwise
  std::optional<size_t> findObserver(const std::shared_ptr<IFeatureEditCandidateObserver>& candidate) {
    for (size_t i = 0, max = _observers.size(); i < max; ++i) {
      if (_observers[i].get() == candidate.get()) {
        return i;
      }
    }
    return std::nullopt;
  }

  std::vector<std::shared_ptr<IFeatureEditCandidateObserver>> _observers;
  std::optional<LayerFeatureId> _candidate;
};
public class FixedEditCandidateProvider : IFeatureEditCandidateProvider
{
    private IList<IFeatureEditCandidateObserver> _observers = new List<IFeatureEditCandidateObserver>();
    private LayerFeatureId? _editCandidate;

    public IList<LayerFeatureId> GetEditCandidates()
    {
        if (_editCandidate != null)
        {
            return new List<LayerFeatureId>() {_editCandidate.Value};
        }

        return new List<LayerFeatureId>();
    }

    public void SetEditCandidate(LayerFeatureId featureId)
    {
        if (_editCandidate == featureId) return;
        _editCandidate = featureId;
        FeatureEditCandidateEvent editCandidateEvent = new FeatureEditCandidateEvent();
        editCandidateEvent.EditCandidateAdded(featureId);
        FireEvent(editCandidateEvent);
    }

    private void FireEvent(FeatureEditCandidateEvent editCandidateEvent)
    {
        lock (_observers)
        {
            foreach (var observer in _observers)
            {
                observer.OnEditCandidatesChanged(editCandidateEvent);
            }
        }
    }

    public void AddObserver(IFeatureEditCandidateObserver observer)
    {
        lock (_observers)
        {
            if (_observers.Contains(observer))
            {
                throw new Exception("Cannot add observer more than once.");
            }

            _observers.Add(observer);
        }
    }


    public void RemoveObserver(IFeatureEditCandidateObserver observer)
    {
        lock (_observers)
        {
            if (!_observers.Remove(observer))
            {
                throw new Exception("Cannot remove unknown observer.");
            }
        }
    }
}
public static class FixedEditCandidateProvider implements IFeatureEditCandidateProvider {
  private final List<IFeatureEditCandidateObserver> observers = new ArrayList<>();
  private LayerFeatureId editCandidate;

  @Override
  public List<LayerFeatureId> getEditCandidates() {
    if (editCandidate != null) {
      return Collections.singletonList(editCandidate);
    }

    return Collections.emptyList();
  }

  public void setEditCandidate(LayerFeatureId featureId) {
    if (editCandidate == featureId) {
      return;
    }
    editCandidate = featureId;
    FeatureEditCandidateEvent editCandidateEvent = new FeatureEditCandidateEvent();
    editCandidateEvent.editCandidateAdded(featureId);
    fireEvent(editCandidateEvent);
  }

  private void fireEvent(FeatureEditCandidateEvent editCandidateEvent) {
    synchronized (observers) {
      for (IFeatureEditCandidateObserver observer : observers) {
        observer.onEditCandidatesChanged(editCandidateEvent);
      }
    }
  }

  @Override
  public void addObserver(IFeatureEditCandidateObserver observer) {
    synchronized (observers) {
      if (observers.contains(observer)) {
        throw new IllegalArgumentException("Cannot add observer more than once.");
      }

      observers.add(observer);
    }
  }

  @Override
  public void removeObserver(IFeatureEditCandidateObserver observer) {
    synchronized (observers) {
      if (!observers.remove(observer)) {
        throw new IllegalArgumentException("Cannot remove unknown observer.");
      }
    }
  }
}

We can then use it in the Editor builder:

Program: Use the custom IFeatureEditCandidateProvider
auto myEditCandidateProvider = std::make_shared<FixedEditCandidateProvider>();

// only this feature will be editable.
myEditCandidateProvider->setEditCandidate({1, 10});
auto myEditor = Editor::newBuilder().map(map).editCandidateProvider(std::move(myEditCandidateProvider)).build();
var myEditCandidateProvider = new FixedEditCandidateProvider();

// only this feature will be editable.
myEditCandidateProvider.SetEditCandidate(new LayerFeatureId(1, 10));
var myEditor = Editor.NewBuilder().Map(map).EditCandidateProvider(myEditCandidateProvider).Build();
FixedEditCandidateProvider myEditCandidateProvider = new FixedEditCandidateProvider();

// only this feature will be editable.
myEditCandidateProvider.setEditCandidate(new LayerFeatureId(1, 10));
Editor myEditor = Editor.newBuilder().map(map).editCandidateProvider(myEditCandidateProvider).build();