Opened 9 years ago
Closed 9 years ago
#504 closed defect (not a bug)
Changing the .selected attribute of Drawing objects doesn't propagate to child drawings
| Reported by: | Owned by: | Tom Goddard | |
|---|---|---|---|
| Priority: | blocker | Milestone: | |
| Component: | Core | Version: | |
| Keywords: | Cc: | ||
| Blocked By: | Blocking: | ||
| Notify when closed: | Platform: | all | |
| Project: | ChimeraX |
Description
TL;DR: changing the .selected attribute of Drawing objects doesn't propagate to child drawings, breaking deselection functionality.
Longer version: in my most recent ISOLDE versions, starting it creates a Model called "ISOLDE annotations" in which I plan to add various Drawing objects for marking up specific structural features. The tree is currently three levels deep:
Level 0: The Model object registered with ISOLDE
Level 1: A Drawing object acting as a container for all the cis-peptide bond annotations
Level 2: The actual drawings (one per omega dihedral, each of which will only ever be updated/shown if its associated dihedral moves more than 30 degrees from trans)
At the moment it's just used to mark cis-peptide bonds (by drawing a simple pseudo-quadrilateral filling in the "cup" of the dihedral). When I do a selection by ctrl-click-and-drag in the main window these get selected like anything else, but they do not deselect either in response to further main-window mouse clicks or "select clear" in the command line interface. If d is the top-level Model holding the drawings, then:
d.selected = False
doesn't work, but:
for dr in d.all_drawings():
dr.selected = False
does.
Change History (2)
comment:1 by , 9 years ago
comment:2 by , 9 years ago
| Resolution: | → not a bug |
|---|---|
| Status: | new → closed |
A few of the selection APIs are hard to find. Drawing.clear_selection() clears the selection for the drawing but not children and Model inherits from Drawing. There is a pretty obscure "selection_promotion()" method of Model for handling promoting the selection for pieces of models like atoms to residues. This is not listed as a Model method, should be, but it is so rare I will leave it out for now.
The selection behavior you describe is as all the intended behavior -- maybe it can be improved. Object selection is controlled by the Model class. Any Drawing child of a Model is managed by the Model, including setting or clearing its selection. Model has a clear_selection() method where it should clear the selection of its child drawings if it needs to. Some model types don't to that, for example AtomicStructure clears the selection state of its atoms, and that later causes the Drawings to have their selection changed. Part of the confusion is that the Drawing selection capabilities are just about displaying a green outline around objects. The Model level selection is about defining a "selected" set of objects, not related to its visual depiction.
The fact that "Drawing.selected = False" does not effect the selection state of child models is intentional. Drawings support an arbitrary tree, and each node can be selected. In order to control the selection state of every node Drawing.selected only effects the node it is applied to. If it instead effected all children, it would be very difficult to set the selection of one node and not the children. So the current behavior is the most flexible. We would need two APIs to also offer the mode where all children have their state set. We haven't gotten their yet, so loop over all children is the way it is currently done (for c in d.all_drawings(): c.selected = False". I don't have a good idea about how to offer the two APIs (include children / don't include children) in a clear way.
In summary you need to add a "clear_selection()" method to your Model. You can look at some examples core/map/volume.py or core/atomic/structure.py. I see the selection API is not defined in the Model class. That needs to be added. I'll do that. The selection code is in core/selection.py. It handles other things like promoting the selection with the uparrow key, which requires other Model methods "selection_promotion()". This is also not shown in the Model API currently.