Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I implement a point-and-click user interaction model?

Context: I'm making a simple solar system simulation in c++/OpenGL.

Research: I've tried searching but I only ever find articles on widgets and flash and HCI stuff.

Problem: I'd like the user to be able to click on an actor, and then maybe deselect, or select something else. Maybe select multple actors at once. If the actor is destroyed, I'd like the selection to go away. I'd like the actor to know it's been selected.

I know how to get the mouse coordinates, and how to see if a click happened on this actor or that actor, or the closest actor. What I don't have any experience doing is modelling the interaction. I can think of something like CSS's model of active, hover, and pressed, so some sort of state, I guess. But then I get into the problem of ownership, and what happens if that actor is deleted or needs to be deleted? Should there be some sort of observer?

Obviously I don't understand the problem enough to try and solve it for my purposes. I have no experience with callbacks or events or whatever. Can anyone point me to some articles, guides, or similar help?

like image 695
whiterook6 Avatar asked Apr 26 '26 21:04

whiterook6


1 Answers

If you are using smart pointers for your actors (e.g. boost::shared_pointer) then you can solve the ownership problem easily by using weak pointers for your selection. For example:

std::set<boost::weak_pointer<Actor> >  selected_actors;

You just need to be aware that any pointer you retrieve from that set might be invalid, but Boost pretty much forces you to check that.


For the actor to know when it's selected, I would just make some virtual member functions that are called by your selection code, e.g.:

class Actor {
public:
  ...
  virtual void on_selected() { }
  virtual void on_deselected() { }
  ...
};

If you also need the actor to keep track of whether it's selected, do it like this:

class Actor {
bool selected;
public:
  Actor() : selected(false) { }
  ...
  void selected() { selected = true; on_selected(); } // not virtual
  void deselected() { selected = false; on_deselected(); } // not virtual
  ...
protected:
  ...
  virtual void on_selected() { }
  virtual void on_deselected() { }
};

Hope that helps!

like image 83
Thomas Avatar answered Apr 29 '26 09:04

Thomas