Minor problem with invalidateUserInterface

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Minor problem with invalidateUserInterface

Ian Bartholomew
Andy/Blair,

I've got a feeling this has been mentioned before, although I can't find it
in the archive.  It still happens in 4.01 so I thought it might be worth
mentioning it again for a rainy afternoon when you have nothing to do.

Create a Shell subclass called 'Test' with an instVar, 'canActivate' and a
view with one PushButton that sends #activate as it's command.

Add two methods -

queryCommand: aCommandQuery
    super queryCommand: aCommandQuery.
    aCommandQuery command == #activate
        ifTrue: [aCommandQuery enabled:
            (canActivate isNil or: [canActivate])]

activate
    canActivate := false.
    [   15000 factorial.
        canActivate := true.
        self invalidateUserInterface]
    forkAt: Processor userBackgroundPriority

The idea being that when I press the button the button is immediately
disabled, something happens in the background and when it is finished the
button is re-enabled. The problem is that the button is only redrawn, and
the enabled state displayed, if the mouse is moved either during the
background operation or after it has finished. If you click on the button
and don't move the mouse then the button's view is never re-enabled.

I can get round it by replacing the last line in the block with the
following but I 'm not sure that this should be necessary?.

SessionManager inputState
    queueDeferredAction: [self invalidateUserInterface]

Regards
    Ian


Reply | Threaded
Open this post in threaded view
|

Re: Minor problem with invalidateUserInterface

Bill Schwab-2
Ian,

> SessionManager inputState
>     queueDeferredAction: [self invalidateUserInterface]

I wonder if this will help my "stubborn buttons" problem.  In that scenario,
buttons that should be enabled are disabled until the user selects from a
drop down list that also happens to be on the page.  I'll put this on my
to-do list to try.

Have a good one,

Bill

--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Minor problem with invalidateUserInterface

Bill Schwab-2
Ian,

> > SessionManager inputState
> >     queueDeferredAction: [self invalidateUserInterface]
>
> I wonder if this will help my "stubborn buttons" problem.  In that
scenario,
> buttons that should be enabled are disabled until the user selects from a
> drop down list that also happens to be on the page.  I'll put this on my
> to-do list to try.

As a quick test, I added this after the super send in the "offending"
presenter's #onViewOpened.  I should mention that this is not really Dolphin
out of the box, because I have a shell with a PaneHolder and change
presenters within it.  Perhaps #invalidateUserInterface should be sent
routinely from a PaneHolder and this is the first time it's actually been
needed.

Caveat: the modified code has yet to see battle conditions :)

Thanks for the suggestion!

Bill

--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Minor problem with invalidateUserInterface

Ian Bartholomew
In reply to this post by Ian Bartholomew
> I can get round it by replacing the last line in the block with the
> following but I 'm not sure that this should be necessary?.

With a dull grinding sound from the vicinity of my brain (sic) I finally
realised that replacing #invalidateUserInterface with #validateUserInterface
will short-cut the idle loop and force an immediate update of the button's
display. duh!  This solves my immediate problem but I still think there is
something not quite right about the idle loop invalidation - although it's
even more minor that I previously thought <g>

Ian


Reply | Threaded
Open this post in threaded view
|

Re: Minor problem with invalidateUserInterface

Ian Bartholomew
In reply to this post by Bill Schwab-2
Bill,

> As a quick test, I added this after the super send in the "offending"
> presenter's #onViewOpened.  I should mention that this is not really
Dolphin
> out of the box, because I have a shell with a PaneHolder and change
> presenters within it.  Perhaps #invalidateUserInterface should be sent
> routinely from a PaneHolder and this is the first time it's actually been
> needed.

I can't hurt and may well solve the problem. I've found that you quite often
do have to manually force an update when you programmatically change the
status of a command source, toolbar buttons are the main "culprit" for this.
PaneHolder would probably also come into that category as you will need to
force a redraw of the visual status of any command sources after you add the
pane.

Ian


Reply | Threaded
Open this post in threaded view
|

Re: Minor problem with invalidateUserInterface

Blair McGlashan
In reply to this post by Ian Bartholomew
Ian

You wrote in message news:9bhc5q$145$[hidden email]...
>
> I've got a feeling this has been mentioned before, although I can't find
it

> in the archive.  It still happens in 4.01 so I thought it might be worth
> mentioning it again for a rainy afternoon when you have nothing to do.
>
> ...[code snipped]...
>
> The idea being that when I press the button the button is immediately
> disabled, something happens in the background and when it is finished the
> button is re-enabled. The problem is that the button is only redrawn, and
> the enabled state displayed, if the mouse is moved either during the
> background operation or after it has finished. If you click on the button
> and don't move the mouse then the button's view is never re-enabled.

Well really that is by design. Invalidating the user interface state from a
background process will not get noticed unless the foreground process is
woken up (causing a mouse event is obviously one way to do that).

I agree though that it would be useful if the
>
> I can get round it by replacing the last line in the block with the
> following but I 'm not sure that this should be necessary?.
>
> SessionManager inputState
>     queueDeferredAction: [self invalidateUserInterface]
>

A less expensive (though 'private') way to achieve the same effect is:

    SessionManager inputState inputSemaphore signal.

This just prods the UI process sufficiently to allow it to notice that some
UI validation is needed.

I agree that it might be useful if #invalidateUserInterface did this itself
so that it could be used successfully from background processes.

Regards

Blair