In Smalltalk V .. there is a method which allows to handle all input
events in a block. Its called Nofifier consumeInputUntil: [:anEvent|]. Notifier is the single instance of NotificationManager. This is very useful to do any mouse inputs without loosing control if the mouse leaves the view. Its something like a modal dialog for graphics. The user have to make a choice by mouse - maybe selecting an additional object with left click - and tells to be ready by right click. Here again in different words out from our application. The customer has to click in normal mode on a view containing the construction of a roof with beams and walls. He selects a beam. He starts a command like "merge to wall" and at this point I need the consumeInputUntil: to force the user to click nothing else as a wall. Who has any idea. |
> This is very useful to do any mouse inputs without loosing control
> if the mouse leaves the view. "Capturing" the mouse is the usual way to do this, but, it can be annoying to a user if it's not transparent. Normally, one would capture the mouse the begin a drag and release it on a button up event; Dolphin's MouseTracker handles the details. However, it sounds like what you want would be better handled by having various modes, and a toolbar combined with #queryCommand: to show which modes are in effect at any one time. Ian's ChunkBrowser is a particularly nice example of this kind of interface. > Its something like a modal dialog for > graphics. The user have to make a choice by mouse - maybe selecting > an additional object with left click - and tells to be ready by right > click. > > Here again in different words out from our application. > The customer has to click in normal mode on a view containing the > construction of a roof with beams and walls. He selects a beam. > He starts a command like "merge to wall" and at this point I need the > consumeInputUntil: to force the user to click nothing else as a wall. An alternative would be to change the #cursor depending on the object under the mouse. By handling mouse move messages, you could look at the mode and the object (if any) at the cursor location and set an appropriate cursor. Clicking on a beam could cause one mode change (or the user can simply click a different toolbar button). #queryCommand: would "automatically" update your toolbar buttons and menu items accordingly. In your example, your mouse move handler would display a pointer cursor when over a wall, and otherwise, it would show a X or something. The State pattern will help you manage the transitions between modes, as well as get the cursor behavior the way you want it. Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
Sorry Bill I'm not happy with your answer. You may have right to say "do it by a
state machine" but in our construction software which is ported from Visual Smalltalk the above handling is used over and over. Has anybody an idea how the method consumeInputUntil: [] can be implemented. > |
"Familie Bachinger" <[hidden email]> wrote in message
news:[hidden email]... > Sorry Bill I'm not happy with your answer. You may have right to say "do it by a > > state machine" but in our construction software which is ported from Visual > Smalltalk > the above handling is used over and over. > > Has anybody an idea how the method > consumeInputUntil: [] > can be implemented. Without knowing exactly what it does, it is difficult to say. One would need an understanding of the low-level Windows message queue handling in both Dolphin and VS. I vaguely remember that VS does not use the normal, synchronous, Windows event handling model for mouse and keyboard input, i.e. it dequeues input from Windows' message queue, enqueues the message on its own internal queue, and then tells Windows it has handled the event (which of course it hasn't yet) by returning from the window procedure. It then handles the requeued events at some later stage. Dolphin, on the other hand, follows the normal synchronous event handling model that Windows expects, in that messages are dequeued and dispatched via a classic message loop, and the "window procedure" only returns when the message really has been handled. Given the difference in message queue handling architectures, I suspect it may be difficult to replicate VS's #consumeInputUntil: in Dolphin, and I think Bill is right to say that one simply doesn't do it that way in Dolphin (or in fact in standard event-driven Windows programming). One would have to review the uses you are making of #consumeInputUntil: in order to decide how to replace it, but Bill's suggestion of using a MouseTracker will probably fit many or most cases. If you are determine to pursue the path of emulating #consumeInputUntil:, then you should start looking at the InputState class, which is the nearest equivalent of VS's NotificationManager. Regards Blair |
Hi
I had just a look on consumeInputUntil: in VSE. In fact both systems have a rather similar mechanism for Windows message processing. Dolphin is much better designed. But the underlying VM mechanism is rather similar. So it should be possible to implement consumeInputUntil: MouseTracker should be used were consumeInputUntil: is used to catch the Mouse. But it cannot be used where other input need to becatched ( e.g. VSE Menu>>popUp:In: ) while I would thing there should be always more Dolphin like implementations. InputState deferredActions can be used in place of VSE's CurrentEvents. so find here a consumeInputUntil: which I haven't tested yet - I derived from loopWhile. InputState>>consumeInputUntil: aBlock "Consume all input events until aBlock evaluates true. aBlock takes one argument which is the current deferred Action." | deferred msg | msg := MSG new. [ deferredActions isEmpty ] whileTrue: [ (self isInputReady: msg) ifTrue: [self pumpMessage: msg] ]. [ deferred := deferredActions nextNoWait ] value "Process single deferred message". "Process any pending host system events" [ aBlock value: deferred ] whileFalse: [ [ deferredActions isEmpty ] whileTrue: [ (self isInputReady: msg) ifTrue: [self pumpMessage: msg] ]. [ deferred := deferredActions nextNoWait ] value "Process single deferred message". ] Also isEmpty must be implemented in SharedQueue. There are several things to take in mind: To use #consumeInputUntil: you must use SessionManager inputState queueDeferredAction: where VSE uses #sendInputEvent: . VSE's adds message sends to CurrentEvents to process host events, which is not done in Dolphin.( look at VSE Window>>wmKeyup:with: ) Dolphin uses queueDeferredAction: often with a Block argument but queueDeferredAction: can be used with a MessageSend object to make the checking of the selector easier. Frank, www.lesser-software.com |
Frank
You wrote in message news:9vpltp$9i4$02$[hidden email]... > > I had just a look on consumeInputUntil: in VSE. > In fact both systems have a rather similar mechanism for Windows message > processing. Dolphin is much better designed. But the underlying VM > mechanism is rather similar. So it should be possible to implement > consumeInputUntil: I'm not quite sure how you can say that Frank. I didn't think the source code to either VM was in the public domain :-). In fact there appear to be significant differences in the VM implementations. Obviously I know how the Dolphin VM handles callbacks, since I wrote it, but my understanding of the VS mechanism is based entirely on what can be deduced from looking at the related code in the image. I last looked at VS some years ago, and my deductions may be inaccurate. From what I can tell, a significant design difference is that Dolphin is able to serialize callback exits so that re-entrant callbacks handled by multiple Smalltalk processes are possible on a single OS thread. The last time I looked at VS in any depth (some years ago), it seemed fairly clear to me from the event handling code in the image that it could not do this, hence all the complexity related to the 'DropStack' class variable of Process, etc. Anyway I suspect this is the reason that VS dequeues input events, because if it didn't it would not be possible to debug through them. Certainly one cannot debug through a SendMessage() in VSE in the way that one can in Dolphin. In fact VS has to handle quite a lot of messages synchronously, sometimes because Windows needs a return value, e.g. WM_MOUSEACTIVATE, or just because the message _must_ be processed in the correct order, and if one puts a (conditional) halt in one of these handlers then when the VS Debugger comes up the process has already been terminated in order to allow the callback to exit, and one is just looking at a copy of the original process stack. My point is that this low-level difference in the capabilities of the VM in respect of handling callbacks (and specifically out-of-order return from recursive callbacks), means that Dolphin does not have to dequeue input events, and can stay closer to the standard synchronous Windows event handling model. This in turn means that certain other things are done differently as well. > > MouseTracker should be used were consumeInputUntil: is used to catch the > Mouse. But it cannot be used where other input need to becatched ( e.g. VSE > Menu>>popUp:In: ) while I would thing there should be always more Dolphin > like implementations. When the mouse is captured by a Window that also has keyboard focus, one enters a "mode" that allows one to control whether other Windows receive any input. As far as other modal states are concerned, we generally use whatever the "correct" Windows API is for that particular thing. In the particular case of Menus that you mention the Windows API used is TrackPopupMenu() (see Menu>>showIn:position:). > > InputState deferredActions can be used in place of VSE's CurrentEvents. > > so find here a consumeInputUntil: which I haven't tested yet - I derived > from loopWhile. > > InputState>>consumeInputUntil: aBlock > "Consume all input events until aBlock evaluates true. aBlock takes > one argument which is the current deferred Action." > ... [code snipped]... >... > Also isEmpty must be implemented in SharedQueue. >... #isEmpty is deliberately not implemented in SharedQueue, because in an IPC mechanism one needs to atomically test for the availability of data and return that data if available. If the test and data access are separated then one creates the potential for race conditions in client code (i.e. the queue might be empty when tested, but receive input immediately afterwards, or, worse, the queue may have input when tested that is removed before one attempts to read it). Hence if one wants to do a non-blocking read on a SharedQueue one should use #nextNoWait rather than a combination of #isEmpty and #next. Your use of a hypothetical #isEmpty would be safe because you follow it with #nextNoWait, but it could be coded more efficiently with just the #nextNoWait. >... > There are several things to take in mind: > To use #consumeInputUntil: you must use SessionManager inputState > queueDeferredAction: > where VSE uses #sendInputEvent: . VSE's adds message sends to CurrentEvents > to process host events, which is not done in Dolphin.( look at VSE > Window>>wmKeyup:with: ) > Dolphin uses queueDeferredAction: often with a Block argument but > queueDeferredAction: can be used with a MessageSend object to > make the checking of the selector easier. I am assuming that the purpose of #consumeInputUntil: is to intercept all input and direct it to a block, in order to prevent the original target receiving the events so that one can do something else with them (though of course the block could forward them on if it didn't want to handle them itself). If this is the case then your suggested Dolphin implementation would appear not to be the same since it will not do that, at least not without significant further modifications to the image. Remember that Dolphin is directly handling the Windows messages, and so when #pumpMessage: is called the message will be synchronously dispatched to the View instance associated with the window handle, and consequently will reach its original target rather than being intercepted. In order to make it work I think it would be necessary to modify the base system so that all the low-level Windows message handlers for "input" events in View so that they re-queued the events as deferred actions, and indeed you seem to imply this above. In conclusion, thank you for your input, but I don't see that this really helps the original poster at all. Porting is not always best done by emulation, sometimes one needs to redesign/rewrite to avoid swimming against the tide, and I believe this would be appropriate here. As an aside I should mention that an enhancement in D5 is the introduction of "interactors" into the MVP framework, something that we "simplified" out of our implementation of MVP originally. Each View has an <interactor> to which all mouse and keyboard input is directed. Normally this will be the Presenter as now. The interactor instance variable can be set to replace the recipient of input from the View. Interactors allow even more flexibility in the MVP framework since one can replace the input handling model of a view-presenter pair at will and without having to put any special code in the presenter. This could be used, for example, to install a null interactor that just discards all input. The <MouseTracker> has been refactored to be a particular type of <interactor>. Regards Blair |
"Blair McGlashan" <[hidden email]> wrote in message
news:9vpuvn$h22tv$[hidden email]... > Frank > > You wrote in message news:9vpltp$9i4$02$[hidden email]... > > > > I had just a look on consumeInputUntil: in VSE. > > In fact both systems have a rather similar mechanism for Windows message > > processing. Dolphin is much better designed. But the underlying VM > > mechanism is rather similar. So it should be possible to implement > > consumeInputUntil: > > I'm not quite sure how you can say that Frank. Blair, you are right - Dolphin's callback implementation is different and more powerful. I am aware of the Dolphin's clever design decision's ( especially in the corner of Callbacks ) to make a elegant binding to Windows possible. But for an implementation of ** non general ** consumeInputUntil: it should be not relevant. Let it be consumeInputUntilDeferredActionMatch: In the case were you want to use consumInputUntil you have to queue a deferred action. I believe it would help to port VSE code to Dolphin to have such things like consumeInputUntil: available. >> Also isEmpty must be implemented in SharedQueue. agreed - so my code should be changed to size = 0 In order to make it work I think it > would be necessary to modify the base system so that all the low-level > Windows message handlers for "input" events in View so that they re-queued > the events as deferred actions, and indeed you seem to imply this above. > I don't think that you have to modify the whole base system to advance with a VSE port. If effect of consumeInputUntil is limited to the current Window you need only local modifications. > In conclusion, thank you for your input, but I don't see that this really > helps the original poster at all. Porting is not always best done by > emulation, sometimes one needs to redesign/rewrite to avoid swimming against > the tide, and I believe this would be appropriate here. > You are right - but sometimes you need to do things in an ugly way to get some success. If you look through senders of consumeInputUntil: my hack would work in a lot of cases. > As an aside I should mention that an enhancement in D5 is the introduction > of "interactors" into the MVP framework, something that we "simplified" out > of our implementation of MVP originally. Each View has an <interactor> to > which all mouse and keyboard input is directed. Normally this will be the > Presenter as now. The interactor instance variable can be set to replace the > recipient of input from the View. Interactors allow even more flexibility in > the MVP framework since one can replace the input handling model of a > view-presenter pair at will and without having to put any special code in > the presenter. This could be used, for example, to install a null interactor > that just discards all input. The <MouseTracker> has been refactored to be a > particular type of <interactor>. great - so this should help to solve the above Problem. > > Regards > > Blair > > Regards, Frank |
Free forum by Nabble | Edit this page |