3
votes

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 mousewheel.

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)

2

2 Answers

2
votes

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.

0
votes

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.