Minor suggestion: if a hotspot callback returns false, continue looking for other hotspots to call as well (which may be in other miniwindows logically "beneath" the hotspot). It would be the hotspot equivalent of a trigger's "keep evaluating" option, allowing you to layer hotspots that do different things on top of each-other without causing conflicts. A silly but plausible example use could be a window/hotspot that "follows" the mouse without blocking mouse input on other windows. Coupled with a pixel-precision hotspot, one could also create hotspots with "holes" in them.
I think it's a more general and more functional alternative to (a) miniwindows flagged as not accepting mouse events, and (b) perhaps OnPluginMouseMoved as well, though of course they would still be available.
I'll explain my motives for suggesting this, but please note that I do believe they have uses outside my own personal goals. I also have to give a bit of backstory as to how I got here.
I've been brainstorming my widget framework lately, mostly about how my event system works (or doesn't, as the case may be). I had the idea of dropping the View construct - visible widgets had to be the child of a movable View - and simply extending the widget composition technique to the whole output window. That is, visible widgets would be children of a MainWindow object.
This simplifies a lot of things, and also gives a definite place for system events to "spawn" from, which was one of my annoyances previously: there was no "good" way to tell whether you wanted to listen to a system event on a widget, or a user-created event. But the new approach would make system events identical to user widgets, except that they come from MainWindow.
Anyways, I also need a good way to actually manage MainWindow's children. The approach I first favoured was just maintaining a single visible window for each child, but it felt immensely clunky the more I thought about it. It was hardly any better than simply keeping separate Views; The other approach, that I didn't really want to take, was covering the output window with one big miniwindow and just blitting each child to it on redraw.
The more I've thought about it, the more I think this approach is the better one. It feels so much cleaner implementation-wise - though I must stress that so far everything is just a thought experiment. The two main problems I face are: (1) the main window must not hide anything below it, and (2) the main window must not block mouse events from anything below it. I think I can manage (1) with some creative use of transparency, but (2) is insurmountable as far as I can tell.
And now I've come full circle. This is why I'd like a "passthrough", or "keep evaluating" functionality for hotspot callbacks. From what I know, it's not a major change or addition, just a matter of checking a return value and continuing the search. Of course, I could be wrong: I've still barely touched the MUSHclient source in its entirety.
As a final note on the behavior of such a feature, certain hotspot callbacks would naturally be excluded from this keep-evaluating functionality. Specifically, the callbacks that rely on a previous stimulus on a specific hotspot: cancelmousedown/mouseup both rely on a mouse action on a specific hotspot, as do dragmove/dragrelease and cancelmouseover. Hence, I suppose mouseover and mousedown are the only two affected.
Now that I think about it, mouseover is pretty central, as it marks which miniwindow the mouse is over. I would suggest that if all hotspots on a given miniwindow return false to a mouseover, that miniwindow not be counted as moused over at all. At this point I think it's just a change in algorithm, I don't think any extra state variables would be required.
Now... if you happen to agree with this suggestion, I'd be happy to look into implementing it. And I'm sorry for the long post, tl;dr much? |