[comp.sys.mac.programmer] Modeless dialogs, what am I doing wrong?

dfs059@ipl.jpl.nasa.gov (Dan Stanfill) (07/17/89)

>In article <1484@ndmath.UUCP> milo@ndmath.UUCP (Greg Corson) writes:
>....
>>What do I have to do to get the cursor to blink normally in the EditText
>>items of a modeless dialog?
>
>        DialogPeek xyzzy;       /* Points to your Modeless dialog. */
>
>        TEIdle(xyzzy->textH);
>
>Earle R. Horton

NO!  While that may work, for a modeless dialog, IsDialogEvent() handles the 
cursor blinking.  The secret is to make sure you call it even when there is no
event, as in the following example:


    something_happened = GetNextEvent(everyEvent, &event);
    if (IsDialogEvent(&event))                /* call even if nothing happened */
    {                                         /* to make cursor blink          */
      doDialogs(&event);
      if (event.what != keyDown) continue;
    }
    if (something_happened)
    {
        .
        .
        .


Dan Stanfill
dfs@mipl8.jpl.nasa.gov

milo@ndmath.UUCP (Greg Corson) (07/17/89)

I recently converted some of my modal dialog boxes to modeless ones...everything
works as I expected it to except for one thing.  In my EditText items in the
dialog, the cursor does not blink.

What do I have to do to get the cursor to blink normally in the EditText
items of a modeless dialog?

Thanks!

Greg Corson
19141 Summers Drive
South Bend, IN 46637
(219) 277-5306 
{pur-ee,rutgers,uunet}!iuvax!ndmath!milo
 

earleh@eleazar.dartmouth.edu (Earle R. Horton) (07/18/89)

In article <1484@ndmath.UUCP> milo@ndmath.UUCP (Greg Corson) writes:
...
>What do I have to do to get the cursor to blink normally in the EditText
>items of a modeless dialog?

	DialogPeek xyzzy;	/* Points to your Modeless dialog. */

	TEIdle(xyzzy->textH);

Earle R. Horton

tim@hoptoad.uucp (Tim Maroney) (07/18/89)

In article <1484@ndmath.UUCP> milo@ndmath.UUCP (Greg Corson) writes:
>What do I have to do to get the cursor to blink normally in the EditText
>items of a modeless dialog?

In article <14455@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu
(Earle R. Horton) writes:
>	DialogPeek xyzzy;	/* Points to your Modeless dialog. */
>
>	TEIdle(xyzzy->textH);

That will work, but a better way is to call DialogSelect in response
to null events.  I have philosophical objections to using DialogPeek.
After all, why be low level when you can be high level?
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"Satanic is merely the name they give to the behavior of those who would
 disrupt the orderly way in which men want to live."
    -- Gabrielle, THE VAMPIRE LESTAT, Anne Rice

earleh@eleazar.dartmouth.edu (Earle R. Horton) (07/18/89)

In article <8029@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:
>In article <1484@ndmath.UUCP> milo@ndmath.UUCP (Greg Corson) writes:
>>What do I have to do to get the cursor to blink normally in the EditText
>>items of a modeless dialog?
>
>In article <14455@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu
>(Earle R. Horton) writes:
>>	DialogPeek xyzzy;	/* Points to your Modeless dialog. */
>>
>>	TEIdle(xyzzy->textH);
>
>That will work, but a better way is to call DialogSelect in response
>to null events.  I have philosophical objections to using DialogPeek.
>After all, why be low level when you can be high level?

     Well, that seems to work too.  I suppose your method is the
better one, being high level and all.  One thing puzzles me though.
Nowhere can I find actual Apple documentation on how to do this, or
even a hint that I should do anything with null events except toss
them.  I looked at the description of IsDialogEvent() just now, and
just maybe you could interpret it to mean that the function wants to
look at null events, but then again, maybe not.

     It looks to me as if this is one case where you have to guess how
to make it work, and TEIdle() was my first guess.

Earle R. Horton

tim@hoptoad.uucp (Tim Maroney) (07/18/89)

In article <5266@ipl.jpl.nasa.gov> dfs059@ipl.jpl.nasa.gov (Dan Stanfill)
writes:
>NO!  While that may work, for a modeless dialog, IsDialogEvent() handles the 
>cursor blinking.  The secret is to make sure you call it even when there is no
>event, as in the following example:
>
>    something_happened = GetNextEvent(everyEvent, &event);
>    if (IsDialogEvent(&event))             /* call even if nothing happened */
>    {                                      /* to make cursor blink          */
>      doDialogs(&event);
>      if (event.what != keyDown) continue;
>    }

No, I'm sorry, but if you'd taken the ten seconds to consult Inside Mac
before you posted this, you'd have seen that IsDialogEvent does no such
thing.  It is DialogSelect that will do the cursor blinking on a null
event.  IsDialogEvent by itself will do exactly nothing.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"A book is the product of a contract with the Devil that inverts the Faustian
 contract, he'd told Allie.  Dr Faustus sacrificed eternity in return for two
 dozen years of power; the writer agrees to the ruination of his life, and
 gains (but only if he's lucky) maybe not eternity, but posterity, at least.
 Either way (this was Jumpy's point) it's the Devil who wins."
	-- Salman Rushdie, THE SATANIC VERSES

dfs059@ipl.jpl.nasa.gov (Dan Stanfill) (07/18/89)

tim@toad.com (Tim Maroney) writes:

>In article <5266@ipl.jpl.nasa.gov> dfs059@ipl.jpl.nasa.gov (Dan Stanfill)
>writes:
>>NO!  While that may work, for a modeless dialog, IsDialogEvent() handles the
>>cursor blinking.  The secret is to make sure you call it even when there is no
>>event, as in the following example:
>>
>>    something_happened = GetNextEvent(everyEvent, &event);
>>    if (IsDialogEvent(&event))           /* call even if nothing happened */
>>    {                                    /* to make cursor blink          */
>>      doDialogs(&event);
>>      if (event.what != keyDown) continue;
>>    }
>
>No, I'm sorry, but if you'd taken the ten seconds to consult Inside Mac
>before you posted this, you'd have seen that IsDialogEvent does no such
>thing.  It is DialogSelect that will do the cursor blinking on a null
>event.  IsDialogEvent by itself will do exactly nothing.
>--
>Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

Well, instead of the ten seconds Mr. Maroney took to consult his manual,
I actually read it.  Inside Mac I-416 says under IsDialogEvent:

  Warning:  If your modeless dialog contains any editText items, you
  must call IsDialogEvent (and then DialogSelect) even if GetNextEvent
  returns FALSE; otherwise your dialog won't receive null events and
  the caret won't blink.

In the code fragment above, doDialogs() calls DialogSelect(), only when
IsDialogEvent() returns TRUE.  This code works flawlessly, and editable
text items always blink just fine.  I have verified with the debugger that
indeed DialogSelect is not called except in response to an actual user
event, thus it is clearly IsDialogEvent which causes the caret to blink.

Also, responses such as "if you'd taken the ten seconds to consult Inside
Mac..." are ridiculously juvenile and uncalled for on a forum in which 
people are trying to help others.

Dan Stanfill
Image Processing Laboratory
Jet Propulsion Laboratory

dfs@mipl8.jpl.nasa.gov
dfs059@ipl.jpl.nasa.gov

sdh@wind.bellcore.com (Stephen D Hawley) (07/19/89)

In article <14466@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu (Earle R. Horton) writes:
>>>What do I have to do to get the cursor to blink normally in the EditText
>>>items of a modeless dialog?
>>(Earle R. Horton) writes:
>>>	DialogPeek xyzzy;	/* Points to your Modeless dialog. */
>>>
>>>	TEIdle(xyzzy->textH);
>>
>>That will work, but a better way is to call DialogSelect in response
>>to null events.  I have philosophical objections to using DialogPeek.
>>After all, why be low level when you can be high level?


DialogSelect() is the way to go.  I just stumbled through this myself.
If you use TEIdle(), it will work, but you will get a mysterious
dot in upper-left corner of each of your edit text items that will not
go away (because, I assume, you are making TEIdle() and DialogSelect()
fight for the same action -technically, this should make no difference,
but it does).


Steve Hawley
sdh@flash.bellcore.com
"1) Never get involved in a land war in Asia and 2) Never go in with a
Sicilian when death is on the line."

tim@hoptoad.uucp (Tim Maroney) (07/19/89)

In article <14466@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu
(Earle R. Horton) writes:
>     Well, that seems to work too.  I suppose your method is the
>better one, being high level and all.  One thing puzzles me though.
>Nowhere can I find actual Apple documentation on how to do this, or
>even a hint that I should do anything with null events except toss
>them.  I looked at the description of IsDialogEvent() just now, and
>just maybe you could interpret it to mean that the function wants to
>look at null events, but then again, maybe not.

Uh, this is kind of a strange comment.  Inside Mac volume I, pages
I-416 and I-418 spell this all out.  "If your modeless dialog contains
any editText items, you must call IsDialogEvent (and then DialogSelect)
even if GetNextEvent returns FALSE; otherwise your dialog won't receive
null events and the caret won't blink."  "If the event isn't one that
DialogSelect specifically checks for (if it's a null event, for
example), and there's an editText item in the dialog, DialogSelect
calls the TextEdit procedure TEIdle to make the caret blink."

Still, astute readers may recall that I've also been bitten here by
missing things in Inside Macintosh (such as the relocatable assignment
problem), so perhaps it isn't really a strange comment after all....
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"He goes on about the wailing and gnashing of teeth.  It comes in one
 verse after another, and it is quite manifest to the reader that there
 is a certain pleasure in contemplating the wailing and gnashing of
 teeth, or else it would not occur so often."
	-- Bertrand Russell, "Why I Am Not a Christian"

dfs059@ipl.jpl.nasa.gov (Dan Stanfill) (07/19/89)

I am glad to see no one has pounced on me yet (at least not in
the messages we have received here) for my last posting, although
I am sure Mr. Maroney will not want to miss the opportunity :-).

I realized after posting that in fact my code does use DialogSelect
to blink the insertion point in editText items, and that IsDialogEvent
is simply used to give those null events to DialogSelect.  My apologies
to the net for misinformation (I wrote that code 2 years ago, and
haven't done an event loop since...).

Both the code and my previous comment to Mr. Maroney are still valid,
though.

Dan Stanfill
Image Processing Laboratory
Jet Propulsion Laboratory

dfs@mipl8.jpl.nasa.gov
dfs059@ipl.jpl.nasa.gov

tim@hoptoad.uucp (Tim Maroney) (07/20/89)

In article <5266@ipl.jpl.nasa.gov> dfs059@ipl.jpl.nasa.gov (Dan Stanfill)
writes:
>NO!  While that may work, for a modeless dialog, IsDialogEvent() handles the
>cursor blinking.

tim@toad.com (Tim Maroney) writes:
>No, I'm sorry, but if you'd taken the ten seconds to consult Inside Mac
>before you posted this, you'd have seen that IsDialogEvent does no such
>thing.  It is DialogSelect that will do the cursor blinking on a null
>event.  IsDialogEvent by itself will do exactly nothing.

In article <5331@ipl.jpl.nasa.gov> dfs059@ipl.jpl.nasa.gov (Dan Stanfill)
writes:
>Well, instead of the ten seconds Mr. Maroney took to consult his manual,
>I actually read it.  Inside Mac I-416 says under IsDialogEvent:
>
>  Warning:  If your modeless dialog contains any editText items, you
>  must call IsDialogEvent (and then DialogSelect) even if GetNextEvent
>  returns FALSE; otherwise your dialog won't receive null events and
>  the caret won't blink.

As you've pointed out in another message, this in fact says that
DialogSelect is necessary -- and if you had taken the two seconds
necessary to turn the page and read the note under the DialogSelect
routine, you would have seen this spelled out in words of one
syllable.

>I have verified with the debugger that
>indeed DialogSelect is not called except in response to an actual user
>event, thus it is clearly IsDialogEvent which causes the caret to blink.

Which turned out to be false.  DialogSelect was indeed called in
response to null events.  One wonders whether the mention of the
debugger data was a deliberate fabrication.

>Also, responses such as "if you'd taken the ten seconds to consult Inside
>Mac..." are ridiculously juvenile and uncalled for on a forum in which 
>people are trying to help others.

No, Mr. Stanfill, they are not.  I grow increasingly tired of people
who post messages to the network on technical subjects without
bothering to spend a miniscule amount of time checking their statements
in the references.  I have very right to point this out.  What is
juvenile and uncalled for is to defend a demonstrably false point by
shouting "NO!", misreading references, providing specious debugger
data, and impugning the personalities of those better informed than
yourself.  You had the minimal decency to correct your technical
errors in a later message, but rather than apologize for your personal
attacks, you reaffirmed them explicitly.  It is you who lowered the
conversation to this level; I have been quite circumspect throughout.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"Every institution I've ever been associated with has tried to screw me."
	-- Stephen Wolfram

tim@hoptoad.uucp (Tim Maroney) (07/20/89)

In article <14490@dartvax.Dartmouth.EDU> earleh@northstar.dartmouth.edu
(Earle Horton) writes:
>     If you're using modeless dialogs, you might also want to set the
>mouse cursor to the iBeamCursor cursor whenever the mouse is in an
>active editText item.
>
>plugh = GetCursor(iBeamCursor);
>GetMouse(&plover);
>if( xyzzy == (DialogPeek)FrontWindow()){
>	if(PtInRect(mouse,&(*xyzzy->textH)->viewRect)){
>		SetCursor(*plugh);
>	}else{
>		SetCursor(&qd.arrow);
>	}
>}
>     I was kind of wondering how Mr. Mahoney gets around his
>philosophical problem with DialogPeek here.

Well, Mr. Norton (or should I say, Emperor Norton), you use the
FindDItem call.  As it says in Inside Mac IV-60, "FindDItem is useful
for changing the cursor when it's over a particular item."  Something
along the lines of:

	if (Rom85 > 0 && (item = FindDItem(win, &where)) >= 0) {
		GetDItem(win, ++item, &type, &h, &box);
		if (type == editText || type == editText + itemDisable)
			SetCursor(*GetCursor(iBeamCursor));
		else	SetCursor(&arrow);
	}
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"Please help support the moratorium on meaningless quotes in .signatures."
  -- Doug Asherman on rec.music.cd

earleh@eleazar.dartmouth.edu (Earle R. Horton) (07/20/89)

In article <8070@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:
>In article <14490@dartvax.Dartmouth.EDU> earleh@northstar.dartmouth.edu
>(Earle Horton) writes:
>>     If you're using modeless dialogs, you might also want to set the
>>mouse cursor to the iBeamCursor cursor whenever the mouse is in an
>>active editText item.

	[Example using DialogPeek->textH]

>>     I was kind of wondering how Mr. Mahoney gets around his
>>philosophical problem with DialogPeek here.
>
>Well, Mr. Norton (or should I say, Emperor Norton), you use the
>FindDItem call.  As it says in Inside Mac IV-60, "FindDItem is useful
>for changing the cursor when it's over a particular item."  Something
>along the lines of:

	[Example using FindDItem]

     Hmm, that's not bad.  It doesn't give the effect I was trying to
describe, however.  I consider the "active" editText item to be that
item with the insertion point or active selection range in it.  The
idea is to use the iBeamCursor only when the cursor is over this item,
and not over other, non-selected editText items.  Before anyone
accuses me of using a strange User Interface technique, let me say
that the effect I am suggesting is also used by the MPW Commando tool,
although I don't know what method Commando uses.

     (*DialogPeek->textH)->viewRect gives you the Rect enclosing the
active editText item, which is what I need for my cursor changing
algorithm to work.  I don't suppose you could find that without using
DialogPeek?

Earle R. Horton
         *

tim@hoptoad.uucp (Tim Maroney) (07/21/89)

In article <14522@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu
(Earle R. Horton) writes:
>     Hmm, that's not bad.  It doesn't give the effect I was trying to
>describe, however.  I consider the "active" editText item to be that
>item with the insertion point or active selection range in it.  The
>idea is to use the iBeamCursor only when the cursor is over this item,
>and not over other, non-selected editText items.

I don't think this is desirable, but I can't really prove one way or
the other to be better, either.

>Before anyone
>accuses me of using a strange User Interface technique, let me say
>that the effect I am suggesting is also used by the MPW Commando tool,
>although I don't know what method Commando uses.

I think Commando is a major mess, and extraordinarily ugly all around.
I really liked it when it first came out, but over time I've come to
realize that its incredibly busy dialogs and non-intuitive pop-ups are
a very bad solution to the problem it's addressing.

>     (*DialogPeek->textH)->viewRect gives you the Rect enclosing the
>active editText item, which is what I need for my cursor changing
>algorithm to work.  I don't suppose you could find that without using
>DialogPeek?

Nope.  You have to look at the DialogPeek to figure out which item is
the current editText item.  This is an oversight in the dialog manager
-- they forgot to put the "fetch" equivalent of SelIText in there.  I
prefer having the i-beam cursor over any editText item, but this is
really just a personal preference.  Still, it does let you have higher
level code than putting it just over the active item.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"There are no Famous People on the net.  Only some of us with bigger mouths
 than others."  -- Dan'l Danehy-Oakes, The Roach

earleh@northstar.dartmouth.edu (Earle Horton) (08/15/89)

In article <8029@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:
>In article <1484@ndmath.UUCP> milo@ndmath.UUCP (Greg Corson) writes:
>>What do I have to do to get the cursor to blink normally in the EditText
>>items of a modeless dialog?
>
>In article <14455@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu
>(Earle R. Horton) writes:
>>	DialogPeek xyzzy;	/* Points to your Modeless dialog. */
>>
>>	TEIdle(xyzzy->textH);
>
>That will work, but a better way is to call DialogSelect in response
>to null events.  I have philosophical objections to using DialogPeek.
>After all, why be low level when you can be high level?

     If you're using modeless dialogs, you might also want to set the
mouse cursor to the iBeamCursor cursor whenever the mouse is in an
active editText item.

Point 		plover;
DialogPeek	xyzzy;
CursHandle	plugh;

plugh = GetCursor(iBeamCursor);
GetMouse(&plover);

if( xyzzy == (DialogPeek)FrontWindow()){
	if(PtInRect(mouse,&(*xyzzy->textH)->viewRect)){
		SetCursor(*plugh);
	}else{
		SetCursor(&qd.arrow);
	}
}
     I was kind of wondering how Mr. Mahoney gets around his
philosophical problem with DialogPeek here.

Earle R. Horton
"People forget how fast you did a job, but they remember how well you
did it."  Salada Tag Lines

pepke@loligo (Eric Pepke) (08/28/89)

In article <14490@dartvax.Dartmouth.EDU> earleh@northstar.dartmouth.edu (Earle Horton) writes:
>     If you're using modeless dialogs, you might also want to set the
>mouse cursor to the iBeamCursor cursor whenever the mouse is in an
>active editText item.
>
>Point 		plover;
>DialogPeek	xyzzy;
>CursHandle	plugh;
>
>plugh = GetCursor(iBeamCursor);
>GetMouse(&plover);
>
>if( xyzzy == (DialogPeek)FrontWindow()){
>	if(PtInRect(mouse,&(*xyzzy->textH)->viewRect)){
>		SetCursor(*plugh);
>	}else{
>		SetCursor(&qd.arrow);
>	}
>}
>     I was kind of wondering how Mr. Mahoney gets around his
>philosophical problem with DialogPeek here.

Your code only sets the cursor to an I-beam when it is in the current editText
item.  I prefer to have my cursor be an I-beam whenever it is in any editText
item.  After all, one of the main functions of the I-beam is to show where
the insertion point will go when you click.  This information is important
whether there had been a prior click in that item or not.  As the modality
of the current editText item does not affect the behavior of the mouse, it 
should not affect the shape of the cursor.

All you have to do is determine whether the cursor is within any of the 
editText items in the dialog.  You can easily do this with GetDItem and do 
not require any DialogPeek access.

I'm not going to post any armchair code because I would probably make a
mistake and also becuase the method you use to determine what a given window
contains is a matter of personal preference.

Eric Pepke                                     INTERNET: pepke@gw.scri.fsu.edu
Supercomputer Computations Research Institute  MFENET:   pepke@fsu
Florida State University                       SPAN:     scri::pepke
Tallahassee, FL 32306-4052                     BITNET:   pepke@fsu

Disclaimer: My employers seldom even LISTEN to my opinions.
Meta-disclaimer: Any society that needs disclaimers has too many lawyers.