In need to do something (set focus on a TextEdit) but I tried doing this in
#onViewOpened. It doesn't do anything, because the view hasn't the focus. Could somebody explain to me when is the view shown ? Does it triggers an event? TIA Osvaldo |
Osvaldo Aufiero wrote:
> In need to do something (set focus on a TextEdit) but I tried doing this in > #onViewOpened. It doesn't do anything, because the view hasn't the focus. > Could somebody explain to me when is the view shown ? Does it triggers an > event? Hopefully, someone here can give you the "right" answer. I just wanted to point out the hack that can sometimes be useful to bail out of situations. In your case something like: [aPresenter setFocus] postToInputQueue. might give you what you need. ------------------------------------------- Bill Dargel [hidden email] Shoshana Technologies 100 West Joy Road, Ann Arbor, MI 48105 USA |
it works great!
tks Bill! "Bill Dargel" <[hidden email]> wrote in message news:[hidden email]... > Osvaldo Aufiero wrote: > > In need to do something (set focus on a TextEdit) but I tried doing this in > > #onViewOpened. It doesn't do anything, because the view hasn't the focus. > > Could somebody explain to me when is the view shown ? Does it triggers an > > event? > > Hopefully, someone here can give you the "right" answer. I just wanted > to point out the hack that can sometimes be useful to bail out of > situations. In your case something like: > [aPresenter setFocus] postToInputQueue. > might give you what you need. > > ------------------------------------------- > Bill Dargel [hidden email] > Shoshana Technologies > 100 West Joy Road, Ann Arbor, MI 48105 USA |
In reply to this post by Osvaldo Aufiero-2
Osvaldo,
> In need to do something (set focus on a TextEdit) but I tried doing > this in #onViewOpened. It doesn't do anything, because the view > hasn't the focus. Could somebody explain to me when is the view shown > ? Does it triggers an event? If I'm reading this right you want a Dialog to open with the focus within the new Dialog set to a TextEdit subview? If so then the easiest way is to rearrange the order of the views (using the ViewComposer) so that the TextEdit is the first subview in the View Hierarchy tree- Dolphin sets the initial focus on the first subview that is a tab stop. Another way of doing it would to be to defer the #setFocus until Windows has fully displayed the Dialog .... onViewOpened super onViewOpened. [yourTextEdit setFocus] postToInputQueue -- Ian Use the Reply-To address to contact me. Mail sent to the From address is ignored. |
Ian,
> Another way of doing it would to be to defer the #setFocus until Windows > has fully displayed the Dialog .... > > onViewOpened > super onViewOpened. > [yourTextEdit setFocus] postToInputQueue FWIW, I'm starting to think that this should be last resort because it makes the code unfriendly to unit tests. However, I suspect that it is more necessary in dialogs than other presenters. I also don't like to be forced to break up every dialog into a regular presenter that I can unit test, only to wrap it in a trivial dialog simply to obtain modal operation. Sometimes such a split helps reuse, which is of course the right thing to do. Other times, it walks, talks, and sounds like a workaround, and makes the code much harder to understand. To the the group at large: has anyone created a non-dialog modal presenter? I think it might help. One of my older manuals (IIRC, WindowBuilder's) makes a good case for having control over the message loop, and the more I write unit tests for GUI elements, the more I want to give it a try. Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
Ian and I had suggested:
> [yourTextEdit setFocus] postToInputQueue Bill Schwab wrote: > FWIW, I'm starting to think that this should be last resort because it makes > the code unfriendly to unit tests. However, I suspect that it is more > necessary in dialogs than other presenters. I also don't like to be forced > to break up every dialog into a regular presenter that I can unit test, only > to wrap it in a trivial dialog simply to obtain modal operation. It probably _should_ be the last resort. But being Smalltalk, one can usually do just about anything. So a while ago, I set aside any semblance of good sense, showed no fear, and hacked together a couple of methods that do help to make modal dialogs and unit tests a bit more harmonious. I've attached them for everyone's amusement. A word of warning though, they're not pretty to look at, and could easily trigger a gag reflex. The #waitForUIProcessToIdle method, when called from a TestCase, allows any pending UI messages and defferedActions to complete. With this, a testCase can check for expected state in its scripted mode and get (closer at least to) what the user would be seeing in the normal interactive mode. It works by just forking off a low priority process and then blocking the execution of the testCase (keeping the UI pumping) until the low priority process has gotten an opportunity to run. The rather more involved #should:openModalShell:answer: method can be utilized by TestCases where doing some GUI operation is expected to open a model dialog. For instance, you can use it to test that pressing a button opens a Prompter, and then check that the caption, prompt, etc., are as expected. You can also go on further to set values into the dialog and then give it an #ok or #cancel, and check afterwards that the main window has responded appropriately. An example of using it within a testCase might be: self should: [(self viewNamed: 'addCopy') performAction] openModalShell: [:topShell | self assert: topShell class = DatePrompter. self assert: topShell caption = 'Select new effective start date:'. self assert: topShell value = Date today firstOfWeek. topShell value: '7/7/03' asDate] answer: #ok. self assert: model startDate = '7/7/03' asDate. I'd be interested to see if anyone else has done something similar? The methods have been working for me as they stand. But I'm sure there must be cases that I haven't run into where they'll break down. So if there's a more robust way, that would be great. -Bill ------------------------- !InputState methodsFor! waitForUIProcessToIdle "General hack to simulate the idling of the system so that testCases can proceed once everything in the UI process has been taken care of." | uiWorking semaphore | uiWorking := true. semaphore := Semaphore new. [uiWorking := false. semaphore signal. SessionManager inputState prod] forkAt: Processor userBackgroundPriority. Processor isActiveMain ifTrue: [SessionManager inputState loopWhile: [uiWorking]] ifFalse: [semaphore wait]! ! !TestCase methodsFor! should: activationBlock openModalShell: verificationBlock answer: aSymbol | activationProcess previousTopShell topShell semaphore activationError | semaphore := Semaphore new. previousTopShell := View active presenter. "Flush any UI events so that another window won't become the top view after we cause the dialog to open." SessionManager inputState waitForUIProcessToIdle. "Evaluate the <activationBlock> which should popup a modal dialog. Grab any errors in the forked process to later resignal in this process." activationProcess := [[[activationBlock value] on: Error do: [:ex | activationError := ex copy]] ensure: [semaphore signal]] forkAt: Processor userHigherPriority. "Set a timeout just in case the activation block never completes" [Processor sleep: 2000. activationProcess terminate] fork. [SessionManager inputState waitForUIProcessToIdle. "Verify that the dialog opened" topShell := View active presenter. self assert: topShell ~= previousTopShell. "Perform any user validation" verificationBlock value: topShell. "Execute the dialog answer, such as #yourself, #ok or #cancel" topShell perform: aSymbol. SessionManager inputState processDeferredActions] ensure: [topShell view close. "Closing the dialog signals the waiting window via a deferredAction, which will cause the button's performAction to finally complete" SessionManager inputState waitForUIProcessToIdle. "Wait for that to happen so that nesting of Cursors won't get messed up" semaphore wait]. activationError notNil ifTrue: [activationError signal]! ! ------------------------------------------- Bill Dargel [hidden email] Shoshana Technologies 100 West Joy Road, Ann Arbor, MI 48105 USA |
In reply to this post by Osvaldo Aufiero-2
"Osvaldo Aufiero" <[hidden email]> wrote in message
news:[hidden email]... > In need to do something (set focus on a TextEdit) but I tried doing this in > #onViewOpened. It doesn't do anything, because the view hasn't the focus. > Could somebody explain to me when is the view shown ? Does it triggers an > event? To explicitly set the initial focus in a dialog (or any other shell) you should override #setInitialFocus. However the default behaviour of setting focus to the first child control with #isTabStop = true is normally appropriate, so there should be no need to define #setInitialFocus in most cases. Regards Blair |
Free forum by Nabble | Edit this page |