[Pythonmac-SIG] Re: password dialog (& toolbox interfaces followup)

Steven D. Majewski sdm7g@elvis.med.virginia.edu
Wed, 10 Feb 1999 21:14:22 -0500 (EST)


The 'use-special-font-in-dialog-text-edit' method does seem to be simpler.
There is a special custom font ".Pwd" with the DTS password C code,
which I have pasted into my PythonCore resources. ( All characters 
have the same diamond shaped glyph representation. ) 

We can add that as well as another window definition to the
distribution. On the previous pass, I used ResEdit to duplicate
the EasyDialogs AskString window ( id=257 ) and change it to
a Movable Modal Dialog style window. This pass, I made another
duplicate and also duplicated and changed the DITL resource. 
The required change is to make the static text item into a user
item.


If you don't add the password font, it works with the Symbol font,
which produces a close approximation of gibberish. In fact, it 
actually looks pretty cool as a normal dialog to have the text
item in a different font, like "Sand" ! 


The short summary of the code is that it changes the dialog font
to something other than the system font, so that edit text is 
unreadable, and instead of a static text item, it uses a user
defined drawing procedure to draw what was the static text string,
setting the font and size back to the system defaults. 


Questions:

[Q1] I've been trying to extract the event processing into two different
procedures for movable-modal vs modal dialogs. Either procedure 
should work -- the default is assigned to 'HandleDialog'. 
 [ These functions are also handy if you want to do some interactive
   window hacking. You can do a 'd=Dlg.GetNewDialog(id,-1)', ... 
   do some stuff interactively maybe using 'd' ... and then when
   you need to "activate" it or move it out of the way, you can
   type 'HandleDialog(d)' ]
 
 Is there any way in Python to get the 'style' of the window: 
 GetWindowKind just differentiates between Dialog and Document
 windows. ( and it used to identify "Desk Accessories" but I 
 guess that is obsolete. ). What I need is the Window Definition ID:
  dBoxProc vs. movableDBoxProc. ( Maybe the new 8.5 Window Class
  functions return this but the Win2 calls aren't wrapped into
  an extension yet. )  Does anyone know a path to this value from
 a MacPython Window or Dialog object ? 

 What I would like is for HandleDialog to dynamically choose between
 modal & movable modal. ( I may have to back up and get the info
 from the resource when the dialog is created. If it can be made
 to work in some fashion, maybe we can roll this back into EasyDialogs.
 Aesthetically and functionally, HI-wise, movable dialogs are 
 much nicer. If you have to enter something more than yes or now, 
 sometimes you need to look elsewhere for the answer. ) 

[Q2: -- this one's especially for Jack! ] 
 
 Is there any reason for the restriction of having only one 
 user item handler set? 

 I discovered that SetDialogItem won't take a Python procedure
 for the third arg -- it demands a resource -- and the way to
 coerce it to a resource is with SetUserItemHandler. (which 
 needs a call to unset it with a None arg before setting it 
 to another value. ) Is there any functional reason for this,
 other than that it makes it simpler just to manage a single
 possible callback. ( i.e. If I try to change this behavior, 
 it there some hole I'm going to fall into that you're aware of?) 

---|  Steven D. Majewski   (804-982-0831)  <sdm7g@Virginia.EDU>  |---
---|  Department of Molecular Physiology and Biological Physics  |---
---|  University of Virginia             Health Sciences Center  |---
---|  P.O. Box 10011            Charlottesville, VA  22906-0011  |---


#-----------------------
import Dlg,Win,Evt,Qd,TE,Fm
import MacOS,sys
from EasyDialogs import cr2lf,lf2cr,screenbounds
from Dlg import GetNewDialog, SetDialogItemText, GetDialogItemText,
ModalDialog
import Dialogs
from Events import *  		# for char-codes 
from Windows import inDrag,inMenuBar


#--- version 2: change dialog font and make static text prompt a UserItemProc

import Qd,TE,Fm			# in addition to all of the others 

# This is the closure to bind a userProc with required two args 
# to the text variable string.

class myTextItem:
	def __init__( self, text ):
		self.text = text
	def install(self, dialog, item ):
		Dlg.SetUserItemHandler(None)
		self.r =  Dlg.SetUserItemHandler(self.myUserItemProc)
		item_args = dialog.GetDialogItem(item)
		dialog.SetDialogItem( item, item_args[0], self.r, item_args[2] )
		return self.r
	def myUserItemProc( self, dialog, item ):
		Qd.SetPort( dialog )
		tp,h,rec = dialog.GetDialogItem( item )
		Qd.TextFont(0)
		Qd.TextSize(0)
		TE.TETextBox( self.text, rec, 0 )
	def __del__(self):
		Dlg.SetUserItemHandler(None)
		
		
	

def AskPwd(prompt,  font='Symbol', id=158, title='Password' ):
	Dlg.SetDialogFont(Fm.GetFNum(font))
	
	d = GetNewDialog(id, -1)	
	if not d:
		print "Can't get DLOG resource with id =", id
		return

	d.SetWTitle( title )

	mytextproc = myTextItem( prompt )
	mytextproc.install( d, 3 )

	tp, h, rect = d.GetDialogItem(4)	# EDIT TEXT ITEM 
	SetDialogItemText(h, '' )
	d.SetDialogDefaultItem(Dialogs.ok)
	d.SetDialogCancelItem(Dialogs.cancel)
	value = HandleDialog( d )
	Dlg.SetDialogFont(0)		# back to system font
	return value



def HandleModalDialog( d ):
	d.BringToFront()
	OK = d.GetDialogDefaultItem() or Dialogs.ok
	CANCEL = d.GetDialogCancelItem() or Dialogs.cancel
	while 1:
		n = ModalDialog(None)
		if n == OK:
			tp, h, rect = d.GetDialogItem(4)
			return cr2lf(GetDialogItemText(h))
		if n == CANCEL: return None


def HandleMovableModalDialog( d ):
	d.BringToFront()
	OK = d.GetDialogDefaultItem() or Dialogs.ok
	CANCEL = d.GetDialogCancelItem() or Dialogs.cancel
	while 1:
		ready,ev = Evt.WaitNextEvent( everyEvent, 6 )
		if not ready: continue
		what,msg,when,where,mod = ev
		if what == 0 : Dlg.DialogSelect(ev) # for blinking caret
		elif Dlg.IsDialogEvent(ev):
			if what == keyDown:
				charcode = msg & charCodeMask
				if charcode == kReturnCharCode:
					tp, h, rect = d.GetDialogItem(4)
					return cr2lf(GetDialogItemText(h))
				elif charcode == kEscapeCharCode: return None
			rs, win, item = Dlg.DialogSelect(ev)
			if item == OK : 
				tp, h, rect = d.GetDialogItem(4)
				return cr2lf(GetDialogItemText(h))
			elif item == CANCEL : 	return None
		elif what == mouseDown:
			part, win = Win.FindWindow(where)
			if part == inDrag and win:
				win.DragWindow(where, screenbounds) 
			else: MacOS.HandleEvent(ev)
		else: MacOS.HandleEvent(ev)


HandleDialog = HandleMovableModalDialog