How to use the mousewheel in a Squeak / Morphic GUI
I am implementing a graphical user interface with Morphic / Squeak. Some of the items have drag & drop functionality. While dragging, I want to be able to rotate these items with the mo开发者_开发百科usewheel.
The first problem is that using the mousewheel ends the drag-action and leads to a drop (attempt). How can I suppress that - and fire the mouseWheelEvent at the same time?
The second problem: How can I assign a mousewheel-event to my Morph? As mentioned above, this event only is relevant while dragging this Morph. (solved)
Appears that on VM implementations that have chosen to support it, Squeak maps the mouse wheel to Ctrl Up-Arrow and Ctrl-Down-Arrow key events. For instance, on Win32 in sqWin32Window.c:
if( WM_MOUSEWHEEL == message || g_WM_MOUSEWHEEL == message ) {
/* Record mouse wheel msgs as CTRL-Up/Down */
short zDelta = (short) HIWORD(wParam);
if(inputSemaphoreIndex) {
sqKeyboardEvent *evt = (sqKeyboardEvent*) sqNextEventPut();
evt->type = EventTypeKeyboard;
evt->timeStamp = lastMessage->time;
evt->charCode = (zDelta > 0) ? 30 : 31;
evt->pressCode = EventKeyChar;
evt->modifiers = CtrlKeyBit;
evt->utf32Code = 0;
evt->reserved1 = 0;
} else {
buttonState = 64;
if (zDelta < 0) {
recordVirtualKey(message,VK_DOWN,lParam);
} else {
recordVirtualKey(message,VK_UP,lParam);
}
}
return 1;
}
So that's pretty much what you've got to work with inside Squeak. (If you're using the Polymorph extensions, there is a special mouseWheel
event, but all they're doing is filtering Ctrl-Up and Ctrl-Down and generating a "fake" MouseWheelEvent
message.)
Looking at a bit of code for handleEvent
in HandMorph
:
evt isMouse ifTrue:[
self sendListenEvent: evt to: self mouseListeners.
lastMouseEvent _ evt].
"Check for pending drag or double click operations."
mouseClickState ifNotNil:[
(mouseClickState handleEvent: evt from: self) ifFalse:[
"Possibly dispatched #click: or something and will not re-establish otherwise"
^self mouseOverHandler processMouseOver: lastMouseEvent]].
evt isMove ifTrue:[
self position: evt position.
self sendMouseEvent: evt.
] ifFalse:[
"Issue a synthetic move event if we're not at the position of the event"
(evt position = self position) ifFalse:[self moveToEvent: evt].
"Drop submorphs on button events"
(self hasSubmorphs)
ifTrue:[self dropMorphs: evt]
ifFalse:[self sendMouseEvent: evt].
].
The Polymorph MouseWheelEvent
is a subclass of MouseEvent that doesn't return true to isMove
, hence you get a drop. You'll have to change something here if you want this to work.
Your best bet is to find a morph that does something like what you want and then browse its methods to see how it does it. Having said that, I haven't come across any that support wheel-specific functions, and of course the original Xerox mouse had no such feature.
精彩评论