I'm working in SWT (no JFace), and I'm attempting to customize the behavior of a Tree that I'm using a sidebar.
The top-level items in the tree shouldn't be selectable; they're basically headers. Only the children of these items should be selectable. As a result, I would like the UI to behave in a way that indicates this; clicking on one of these top-level items should expand or collapse but shouldn't provide any sort of visual feedback outside of the indicator changing its state and the children's visibility changing.
The problem seems to be that on OS X, the expand/collapse indicator is a triangle (don't know if it's an image or a unicode character) that either points right or down, but is also colored based on the "selection" state. I've managed to override all of the relevant behavior for the top-level items except for the arrow changing color.
- I've used an
SWT.EraseItem
listener to hook in to the background drawing so that the background doesn't change color. This works as expected. - I've used an
SWT.PaintItem
listener to make sure that the text in the top-level item doesn't change color. This works as expected, but doesn't seem to have any influence over the indicator; I've even tried not resetting the GC's foreground color, but the color of the indicator still changes:
Not Selected:
Selected
Some of the things that I've attempted to do, all of which have failed:
Just drawing a rectangle on top of indicator. The indicator seems to always be on top, no matter what I attach the PaintListener to.
Using a Listener on the Selection event type, checking to see if the
event.item
is one of the top-level items, and then fiddling with the event bits and redraw flags. This doesn't seem to work well at all; the behavior is completely unpredictable. The code looks something like this:sideBar.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { TreeItem eventItem = (TreeItem) event.item; if(sideBarRoots.contains(event.item)) { event.detail = 0; event.type = 0; event.doit = false; sideBar.setRedraw(false); } else { sideBar.setRedraw(true); event.type = SWT.Selection; event.doit = true; } } });
Since the redraw flag is just a hint, sometimes it gets set properly and others it doesn't. It can have either no effect, or can get locked in to a state where nothing redraws in the sidebar.
I'm aware that a lot of this behavior is highly coupled to the behavior of the underlying native widgets, but I was wondering if there was any way to get the behavior that I'm looking for without roll a custom widget from scratch?