PopUpList.st
changeset 1052 59f182d1304f
parent 1035 c7cfaead1621
child 1063 b315e2580bc7
equal deleted inserted replaced
1051:52111b0631da 1052:59f182d1304f
     9  other person.  No title to or ownership of the software is
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
    12 
    13 Button subclass:#PopUpList
    13 Button subclass:#PopUpList
    14 	instanceVariableNames:'menu menuAction values useIndex listMsg defaultLabel'
    14 	instanceVariableNames:'menu menuAction values useIndex listMsg defaultLabel
       
    15 			       listHolder selectionHolder'
    15 	classVariableNames:''
    16 	classVariableNames:''
    16 	poolDictionaries:''
    17 	poolDictionaries:''
    17 	category:'Views-Interactors'
    18 	category:'Views-Interactors'
    18 !
    19 !
    19 
    20 
    39     The PopUpLists label is showing the current selection from the
    40     The PopUpLists label is showing the current selection from the
    40     list.
    41     list.
    41     When an entry is selected, an actionBlock (if nonNil) is evaluated
    42     When an entry is selected, an actionBlock (if nonNil) is evaluated
    42     and (if nonNil), the model is notified via the changeMessage.
    43     and (if nonNil), the model is notified via the changeMessage.
    43 
    44 
       
    45     If no model is set, the list is assumed to be a static list, which
       
    46     is defined via #list:, and the popUpList evaluates the action block,
       
    47     as defined via #action:.
       
    48 
       
    49     If a model is provided, it should return the list from the listMsg (default
       
    50     is #list) and the current selected items index via 
       
    51     #selection or: #selectionIndex (depending on the setting of useIndex).
       
    52 
    44     The default changeMessage used is #selection:, which allows a
    53     The default changeMessage used is #selection:, which allows a
    45     PopUpList to be used with a SelectionInList as model.
    54     PopUpList to be used with a SelectionInList as model.
    46     (if used with some other model, either use an adaptor, or set the
    55     (if used with some other model, either use an adaptor, or set the
    47      changeMessage to something else ..)
    56      changeMessage to something else ..)
    48 
    57 
    49     [Instance variables:]
    58     [Instance variables:]
    50 
    59 
    51         menu                            helpers for the popup menu
    60 	menu                            helpers for the popup menu
    52         menuAction 
    61 	menuAction 
    53         values 
    62 	values 
    54 
    63 
    55         useIndex             <Boolean>  if true, the index of the selected entry
    64 	useIndex             <Boolean>  if true, the index of the selected entry
    56                                         is passed to the action block and the
    65 					is passed to the action block and the
    57                                         model in a change-message.
    66 					model in a change-message.
    58                                         If false (the default), the value is passed.
    67 					If false (the default), the value is passed.
    59                                         Notice that the default changeMessage is
    68 					Notice that the default changeMessage is
    60                                         #selection:, which is not ok to be used
    69 					#selection:, which is not ok to be used
    61                                         with useIndex:true and a selectionInList model.
    70 					with useIndex:true and a selectionInList model.
    62                                         (set the changeMessage to #selectionIndex: then)
    71 					(set the changeMessage to #selectionIndex: then)
    63 
    72 
    64         listMsg              <Symbol>   message to aquire a new list from the
    73 	listMsg              <Symbol>   message to aquire a new list from the
    65                                         model. Default is #list.
    74 					model. Default is #list.
       
    75 
       
    76 
       
    77 	listHolder           <Object>   if non-nil, this object is assumed to return the
       
    78 					list via the listMsg (instead of the model).
       
    79 					Default is nil.
       
    80 
       
    81 	selectionHolder      <Object>   if non-nil, this object is assumed to return the
       
    82 					selection via the changeMsg (instead of the model).
       
    83 					UseIndex specifies if its numeric (i.e. a selectionindex) 
       
    84 					Default is nil.
    66 
    85 
    67     [see also:]
    86     [see also:]
    68         SelectionInListView
    87 	SelectionInListView
    69         SelectionInList
    88 	SelectionInList
    70 
    89 
    71     [author:]
    90     [author:]
    72         Claus Gittinger
    91 	Claus Gittinger
    73 "
    92 "
    74 !
    93 !
    75 
    94 
    76 examples
    95 examples
    77 "
    96 "
    78     example use:
    97     example use:
    79                                                                         [exBegin]
    98 									[exBegin]
    80      |p|
    99      |p|
    81      p := PopUpList label:'healthy fruit'.
   100      p := PopUpList label:'healthy fruit'.
    82      p list:#('apples' 'bananas' 'grape' 'lemon' 'margaritas').
   101      p list:#('apples' 'bananas' 'grape' 'lemon' 'margaritas').
    83      p open
   102      p open
    84                                                                         [exEnd]
   103 									[exEnd]
    85 
   104 
    86 
   105 
    87     with an initial selection:
   106     with an initial selection:
    88                                                                         [exBegin]
   107 									[exBegin]
    89      |p|
   108      |p|
    90      p := PopUpList label:'dummy'.
   109      p := PopUpList label:'dummy'.
    91      p list:#('apples' 'bananas' 'grape' 'lemon' 'margaritas').
   110      p list:#('apples' 'bananas' 'grape' 'lemon' 'margaritas').
    92      p selection:'apples'.
   111      p selection:'apples'.
    93      p open
   112      p open
    94                                                                         [exEnd]
   113 									[exEnd]
    95 
   114 
    96 
   115 
    97     with separating lines:
   116     with separating lines:
    98                                                                         [exBegin]
   117 									[exBegin]
    99      |p|
   118      |p|
   100      p := PopUpList label:'fruit'.
   119      p := PopUpList label:'fruit'.
   101      p list:#('apples' 'bananas' 'grape' 'lemon' '-' 'margaritas').
   120      p list:#('apples' 'bananas' 'grape' 'lemon' '-' 'margaritas').
   102      p selection:'apples'.
   121      p selection:'apples'.
   103      p open
   122      p open
   104                                                                         [exEnd]
   123 									[exEnd]
   105 
   124 
   106 
   125 
   107     with an action:
   126     with an action:
   108                                                                         [exBegin]
   127 									[exBegin]
   109      |p|
   128      |p|
   110      p := PopUpList label:'dummy'.
   129      p := PopUpList label:'dummy'.
   111      p list:#('apples' 'bananas' 'grape' 'lemon' '-' 'margaritas').
   130      p list:#('apples' 'bananas' 'grape' 'lemon' '-' 'margaritas').
   112      p selection:'apples'.
   131      p selection:'apples'.
   113      p action:[:what | Transcript showCR:'you selected: ' , what].
   132      p action:[:what | Transcript showCR:'you selected: ' , what].
   114      p open
   133      p open
   115                                                                         [exEnd]
   134 									[exEnd]
   116 
   135 
   117 
   136 
   118     sometimes, you may like the index instead of the value:
   137     sometimes, you may like the index instead of the value:
   119     (notice, that the separating line counts, so you have to take care ...)
   138     (notice, that the separating line counts, so you have to take care ...)
   120                                                                         [exBegin]
   139 									[exBegin]
   121      |p|
   140      |p|
   122      p := PopUpList label:'dummy'.
   141      p := PopUpList label:'dummy'.
   123      p list:#('apples' 'bananas' 'grape' 'lemon' '-' 'margaritas').
   142      p list:#('apples' 'bananas' 'grape' 'lemon' '-' 'margaritas').
   124      p selection:'apples'.
   143      p selection:'apples'.
   125      p action:[:what | Transcript show:'you selected: '; showCR:what].
   144      p action:[:what | Transcript show:'you selected: '; showCR:what].
   126      p useIndex:true.
   145      p useIndex:true.
   127      p open
   146      p open
   128                                                                         [exEnd]
   147 									[exEnd]
   129 
   148 
   130 
   149 
   131     since the list is actually a popupMenu, you can add double-separators:
   150     since the list is actually a popupMenu, you can add double-separators:
   132                                                                         [exBegin]
   151 									[exBegin]
   133      |p|
   152      |p|
   134      p := PopUpList label:'dummy'.
   153      p := PopUpList label:'dummy'.
   135      p list:#('apples' 'bananas' 'grape' 'lemon' 
   154      p list:#('apples' 'bananas' 'grape' 'lemon' 
   136               '=' 
   155 	      '=' 
   137               'margaritas' 'pina colada'
   156 	      'margaritas' 'pina colada'
   138               '=' 
   157 	      '=' 
   139               'smalltalk' 'c++' 'eiffel' 'java').
   158 	      'smalltalk' 'c++' 'eiffel' 'java').
   140      p values:#(apples bananas grape lemon 
   159      p values:#(apples bananas grape lemon 
   141                 nil 
   160 		nil 
   142                 'mhmh - so good' 'makes headache'
   161 		'mhmh - so good' 'makes headache'
   143                 nil
   162 		nil
   144                 'great' 'another headache' 'not bad' 'neat').
   163 		'great' 'another headache' 'not bad' 'neat').
   145      p selection:'apples'.
   164      p selection:'apples'.
   146      p action:[:what | Transcript show:'you selected: '; showCR:what].
   165      p action:[:what | Transcript show:'you selected: '; showCR:what].
   147      p open
   166      p open
   148                                                                         [exEnd]
   167 									[exEnd]
   149 
   168 
   150 
   169 
   151     since the list is actually represented by a menuView,
   170     since the list is actually represented by a menuView,
   152     which itself is inheriting from listView, which itself can display
   171     which itself is inheriting from listView, which itself can display
   153     things different from strings, arbitrary lists can be constructed:
   172     things different from strings, arbitrary lists can be constructed:
   154     (see ListEntry classes)
   173     (see ListEntry classes)
   155                                                                         [exBegin]
   174 									[exBegin]
   156      |p l|
   175      |p l|
   157      p := PopUpList label:'dummy'.
   176      p := PopUpList label:'dummy'.
   158      l := OrderedCollection new.
   177      l := OrderedCollection new.
   159      l add:(ColoredListEntry string:'apples' color:Color red).
   178      l add:(ColoredListEntry string:'apples' color:Color red).
   160      l add:(ColoredListEntry string:'bananas' color:Color red).
   179      l add:(ColoredListEntry string:'bananas' color:Color red).
   168      l add:(ColoredListEntry string:'c++' color:Color blue).
   187      l add:(ColoredListEntry string:'c++' color:Color blue).
   169      l add:(ColoredListEntry string:'eiffel' color:Color blue).
   188      l add:(ColoredListEntry string:'eiffel' color:Color blue).
   170      l add:(ColoredListEntry string:'java' color:Color blue).
   189      l add:(ColoredListEntry string:'java' color:Color blue).
   171      p list:l.
   190      p list:l.
   172      p values:#(apples bananas grape lemon 
   191      p values:#(apples bananas grape lemon 
   173                 nil 
   192 		nil 
   174                 'mhmh - so good' 'makes headache'
   193 		'mhmh - so good' 'makes headache'
   175                 nil
   194 		nil
   176                 'great' 'another headache' 'not bad' 'neat').
   195 		'great' 'another headache' 'not bad' 'neat').
   177      p selection:'apples'.
   196      p selection:'apples'.
   178      p action:[:what | Transcript show:'you selected: '; showCR:what].
   197      p action:[:what | Transcript show:'you selected: '; showCR:what].
   179      p open
   198      p open
   180                                                                         [exEnd]
   199 									[exEnd]
   181 
   200 
   182 
   201 
   183     with values different from the label strings:
   202     with values different from the label strings:
   184                                                                         [exBegin]
   203 									[exBegin]
   185      |p|
   204      |p|
   186      p := PopUpList label:'dummy'.
   205      p := PopUpList label:'dummy'.
   187      p list:#('apples' 'bananas' 'grape' 'lemon' '-' 'margaritas').
   206      p list:#('apples' 'bananas' 'grape' 'lemon' '-' 'margaritas').
   188      p selection:'apples'.
   207      p selection:'apples'.
   189      p values:#(10 20 30 40 nil 50).
   208      p values:#(10 20 30 40 nil 50).
   190      p action:[:what | Transcript show:'you selected: '; showCR:what].
   209      p action:[:what | Transcript show:'you selected: '; showCR:what].
   191      p open
   210      p open
   192                                                                         [exEnd]
   211 									[exEnd]
   193 
   212 
   194 
   213 
   195     with a model (see in the inspector, how the valueHolders index-value changes):
   214     with a model (see in the inspector, how the valueHolders index-value changes):
   196                                                                         [exBegin]
   215 									[exBegin]
   197      |p model|
   216      |p model|
   198 
   217 
   199      model := SelectionInList with:#('apples' 'bananas' 'grape' 'lemon' 'margaritas').
   218      model := SelectionInList with:#('apples' 'bananas' 'grape' 'lemon' 'margaritas').
   200 
   219 
   201      p := PopUpList label:'healthy fruit'.
   220      p := PopUpList label:'healthy fruit'.
   202      p model:model.
   221      p model:model.
   203      p open.
   222      p open.
   204      model selectionIndexHolder inspect
   223      model selectionIndexHolder inspect
   205                                                                         [exEnd]
   224 									[exEnd]
   206 
   225 
   207 
   226 
   208     a popupList and a SelectionInListView on the same model:
   227     a popupList and a SelectionInListView on the same model:
   209                                                                         [exBegin]
   228 									[exBegin]
   210      |p slv model|
   229      |p slv model|
   211 
   230 
   212      model := SelectionInList with:#('apples' 'bananas' 'grape' 'lemon' 'margaritas').
   231      model := SelectionInList with:#('apples' 'bananas' 'grape' 'lemon' 'margaritas').
   213      model selection:'apples'.
   232      model selection:'apples'.
   214 
   233 
   219      slv := SelectionInListView on:model.
   238      slv := SelectionInListView on:model.
   220      slv open.
   239      slv open.
   221 
   240 
   222      p inspect.
   241      p inspect.
   223      model selectionIndexHolder inspect
   242      model selectionIndexHolder inspect
   224                                                                         [exEnd]
   243 									[exEnd]
   225 
   244 
   226 
   245 
   227     two PopUpLists on the same model, different aspects:
   246     two PopUpLists on the same model, different aspects:
   228                                                                         [exBegin]
   247 									[exBegin]
   229      |top panel p model|
   248      |top panel p model|
   230 
   249 
   231      model := Plug new.
   250      model := Plug new.
   232      model respondTo:#eat: with:[:val | Transcript showCR:'eat: ' , val].
   251      model respondTo:#eat: with:[:val | Transcript showCR:'eat: ' , val].
   233      model respondTo:#drink: with:[:val | Transcript showCR:'drink: ' , val].
   252      model respondTo:#drink: with:[:val | Transcript showCR:'drink: ' , val].
   246      p := PopUpList label:'drinks'.
   265      p := PopUpList label:'drinks'.
   247      p model:model; listMessage:#drinks; aspect:nil; change:#drink:.
   266      p model:model; listMessage:#drinks; aspect:nil; change:#drink:.
   248      panel add:p.
   267      panel add:p.
   249 
   268 
   250      top open
   269      top open
   251                                                                         [exEnd]
   270 									[exEnd]
       
   271 
       
   272 
       
   273     with separate list- and indexHolders:
       
   274 									[exBegin]
       
   275      |p selectionHolder listHolder|
       
   276 
       
   277      listHolder := #('apples' 'bananas' 'grape' 'lemon' 'margaritas') asValue.
       
   278      selectionHolder := 'apples' asValue.
       
   279 
       
   280      p := PopUpList label:'healthy fruit'.
       
   281      p listHolder:listHolder.
       
   282      p selectionHolder:selectionHolder.
       
   283      p open.
       
   284      selectionHolder inspect
       
   285 									[exEnd]
       
   286 
       
   287     same, using index:
       
   288 									[exBegin]
       
   289      |p selectionIndexHolder listHolder|
       
   290 
       
   291      listHolder := #('apples' 'bananas' 'grape' 'lemon' 'margaritas') asValue.
       
   292      selectionIndexHolder := 3 asValue.
       
   293 
       
   294      p := PopUpList new.
       
   295      p listHolder:listHolder.
       
   296      p selectionHolder:selectionIndexHolder.
       
   297      p useIndex:true.
       
   298      p open.
       
   299      selectionIndexHolder inspect
       
   300 									[exEnd]
       
   301 
       
   302 
   252 "
   303 "
   253 ! !
   304 ! !
   254 
   305 
   255 !PopUpList class methodsFor:'defaults'!
   306 !PopUpList class methodsFor:'defaults'!
   256 
   307 
   305      p action:[:val | Transcript showCR:'selected: ' , val printString].   
   356      p action:[:val | Transcript showCR:'selected: ' , val printString].   
   306      p open
   357      p open
   307     "
   358     "
   308 !
   359 !
   309 
   360 
       
   361 listHolder
       
   362     "return the listHolder if any"
       
   363 
       
   364     ^ listHolder
       
   365 !
       
   366 
       
   367 listHolder:aValueHolder
       
   368     "set the listHolder and change the listMessage to #value."
       
   369 
       
   370     listHolder notNil ifTrue:[
       
   371 	listHolder removeDependent:self.
       
   372     ].
       
   373     listHolder := aValueHolder.
       
   374     listHolder notNil ifTrue:[
       
   375 	listHolder addDependent:self.
       
   376     ].
       
   377     listMsg := #value.
       
   378     shown ifTrue:[
       
   379 	self getListFromModel
       
   380     ]
       
   381 !
       
   382 
   310 selection:indexOrString
   383 selection:indexOrString
   311     "set (force) a selection - usually done to set
   384     "set (force) a selection - usually done to set
   312      an initial selection without updating others"
   385      an initial selection without updating others"
   313 
   386 
   314     |index wasFix|
   387     |index wasFix|
   315 
   388 
       
   389     menu isNil ifTrue:[
       
   390 	self getListFromModel.
       
   391     ].
       
   392     menu isNil ifTrue:[^ self].
       
   393 
   316     index := menu indexOf:indexOrString.
   394     index := menu indexOf:indexOrString.
   317     index == 0 ifTrue:[
   395     index == 0 ifTrue:[
   318         self label:defaultLabel.
   396 	self label:defaultLabel.
   319         ^ self
   397 	^ self
   320     ].
   398     ].
   321 
   399 
   322     "kludge: dont want label to resize ..."
   400     "kludge: dont want label to resize ..."
   323     wasFix := fixSize. fixSize := true.
   401     wasFix := fixSize. fixSize := true.
   324     self label:(menu labels at:index) printString.
   402     self label:(menu labels at:index) printString.
   339     "
   417     "
   340 
   418 
   341     "Modified: 8.2.1996 / 12:55:01 / cg"
   419     "Modified: 8.2.1996 / 12:55:01 / cg"
   342 !
   420 !
   343 
   421 
       
   422 selectionHolder
       
   423     "return the selectionHolder if any"
       
   424 
       
   425     ^ selectionHolder
       
   426 !
       
   427 
       
   428 selectionHolder:aValueHolder
       
   429     "set the selectionHolder and change the aspect/changeMessage to #value / #value:"
       
   430 
       
   431     selectionHolder notNil ifTrue:[
       
   432 	selectionHolder removeDependent:self.
       
   433     ].
       
   434     selectionHolder := aValueHolder.
       
   435     selectionHolder notNil ifTrue:[
       
   436 	selectionHolder addDependent:self.
       
   437     ].
       
   438     aspectMsg := #value.
       
   439     changeMsg := #value:.
       
   440     shown ifTrue:[
       
   441 	self getSelectionFromModel
       
   442     ]
       
   443 !
       
   444 
   344 values:aList
   445 values:aList
   345     "set a value list - these are reported via the action or changeSymbol instead of
   446     "set a value list - these are reported via the action or changeSymbol instead of
   346      the labe strings."
   447      the label strings."
   347 
   448 
   348     values := aList.
   449     values := aList.
   349     menu args:(1 to:aList size).
   450     menu args:(1 to:aList size).
   350 
   451 
   351     "
   452     "
   402 !
   503 !
   403 
   504 
   404 getListFromModel
   505 getListFromModel
   405     "if I have a model and a listMsg, get my list from it"
   506     "if I have a model and a listMsg, get my list from it"
   406 
   507 
   407     (model notNil 
   508     |l|
   408     and:[listMsg notNil]) ifTrue:[
   509 
   409 	self list:(model perform:listMsg).
   510     listMsg notNil ifTrue:[
   410     ].
   511 	listHolder notNil ifTrue:[
       
   512 	    l := listHolder perform:listMsg
       
   513 	] ifFalse:[
       
   514 	    model notNil ifTrue:[
       
   515 		l := model perform:listMsg.
       
   516 	    ]
       
   517 	].
       
   518 	self list:l
       
   519     ]
   411 !
   520 !
   412 
   521 
   413 getSelectionFromModel
   522 getSelectionFromModel
   414     "if I have a model and an aspectMsg, get my current value from it"
   523     "if I have a model and an aspectMsg, get my current value from it"
   415 
   524 
   416     (model notNil 
   525     |sel|
   417     and:[aspectMsg notNil]) ifTrue:[
   526 
   418         menu isNil ifTrue:[
   527     aspectMsg notNil ifTrue:[
   419             self getListFromModel
   528 	selectionHolder notNil ifTrue:[
   420         ].
   529 	    sel := selectionHolder perform:aspectMsg
   421         self selection:(model perform:aspectMsg).
   530 	] ifFalse:[
       
   531 	    model notNil ifTrue:[
       
   532 		sel := model perform:aspectMsg.
       
   533 	    ]
       
   534 	].
       
   535 	self selection:sel
   422     ].
   536     ].
   423 
   537 
   424     "Modified: 25.5.1996 / 14:21:07 / cg"
   538     "Modified: 25.5.1996 / 14:21:07 / cg"
   425 !
   539 !
   426 
   540 
   427 listMessage
   541 listMessage
   428     "return the selector by which we ask the model for the list.
   542     "return the selector by which we ask the model for the list.
   429      Default is #list."
   543      The default is #list if used with a model 
       
   544      or #value, if used with a listHolder."
   430 
   545 
   431     ^ listMsg
   546     ^ listMsg
   432 !
   547 !
   433 
   548 
   434 listMessage:aSelector
   549 listMessage:aSelector
   435     "set the selector by which we ask the model for the list.
   550     "set the selector by which we ask the model for the list.
   436      Default is #list."
   551      The default is #list if used with a model 
       
   552      or #value, if used with a listHolder."
   437 
   553 
   438     listMsg := aSelector
   554     listMsg := aSelector
   439 ! !
   555 ! !
   440 
   556 
   441 !PopUpList methodsFor:'change & update'!
   557 !PopUpList methodsFor:'change & update'!
   442 
   558 
   443 update:something with:aParameter from:changedObject
   559 update:something with:aParameter from:changedObject
       
   560     changedObject == listHolder ifTrue:[
       
   561 	self getListFromModel.
       
   562 	^ self
       
   563     ].
       
   564     changedObject == selectionHolder ifTrue:[
       
   565 	self getSelectionFromModel.
       
   566 	^ self
       
   567     ].
       
   568 
   444     changedObject == model ifTrue:[
   569     changedObject == model ifTrue:[
   445 	(something == aspectMsg 
   570 	(something == aspectMsg 
   446 	or:[something == #selectionIndex]) ifTrue:[
   571 	or:[something == #selectionIndex]) ifTrue:[
   447 	    self getSelectionFromModel.
   572 	    self getSelectionFromModel.
   448 	    ^ self
   573 	    ^ self
   490 
   615 
   491 popMenu
   616 popMenu
   492     |org mv w|
   617     |org mv w|
   493 
   618 
   494     menu notNil ifTrue:[
   619     menu notNil ifTrue:[
   495         self turnOffWithoutRedraw. 
   620 	self turnOffWithoutRedraw. 
   496 
   621 
   497         menu labels size == 0 ifTrue:[
   622 	menu labels size == 0 ifTrue:[
   498             ^ self
   623 	    ^ self
   499         ].
   624 	].
   500 
   625 
   501         menu font:font.
   626 	menu font:font.
   502 
   627 
   503         "
   628 	"
   504          adjust the menus width to my current width
   629 	 adjust the menus width to my current width
   505         "
   630 	"
   506         mv := menu menuView.
   631 	mv := menu menuView.
   507         mv create.      "/ stupid: it resizes itself upon first create
   632 	mv create.      "/ stupid: it resizes itself upon first create
   508         w := mv width.  "/ to its preferred size.
   633 	w := mv width.  "/ to its preferred size.
   509         w := w max:(self width - (2 * menu margin) - (menu borderWidth*2)).
   634 	w := w max:(self width - (2 * menu margin) - (menu borderWidth*2)).
   510         mv width:w.
   635 	mv width:w.
   511         mv level:0; borderWidth:0.
   636 	mv level:0; borderWidth:0.
   512 
   637 
   513         "
   638 	"
   514          the popupMenu wants Display coordinates in its showAt: method
   639 	 the popupMenu wants Display coordinates in its showAt: method
   515         "
   640 	"
   516         org := device translatePoint:0@0 
   641 	org := device translatePoint:0@0 
   517                                 from:(self id)
   642 				from:(self id)
   518                                   to:(device rootView id).
   643 				  to:(device rootView id).
   519 
   644 
   520         menu showAt:org "resizing:false"
   645 	menu showAt:org "resizing:false"
   521     ].
   646     ].
   522 ! !
   647 ! !
   523 
   648 
   524 !PopUpList methodsFor:'initialization'!
   649 !PopUpList methodsFor:'initialization'!
   525 
   650 
   544 !PopUpList methodsFor:'private'!
   669 !PopUpList methodsFor:'private'!
   545 
   670 
   546 computeLabelSize
   671 computeLabelSize
   547     "compute the extent needed to hold the label plus the mark"
   672     "compute the extent needed to hold the label plus the mark"
   548 
   673 
   549     |mmH mmV savedLogo longest longestWidth|
   674     |mmH mmV savedLogo longest longestWidth labels|
   550 
   675 
   551     menu isNil ifTrue:[
   676     menu isNil ifTrue:[
   552         super computeLabelSize
   677 	super computeLabelSize
   553     ] ifFalse:[
   678     ] ifFalse:[
   554         "hack: simulate logo change to longest menu entry"
   679 	"hack: simulate logo change to longest menu entry"
   555 
   680 
   556         font := font on:device.
   681 	font := font on:device.
   557         longest := logo.
   682 	longest := logo.
   558         longestWidth := font widthOf:logo.
   683 	logo isNil ifTrue:[
   559         menu labels do:[:entry |
   684 	    longestWidth := 0
   560             |this|
   685 	] ifFalse:[
   561 
   686 	    longestWidth := font widthOf:logo.
   562             this := font widthOf:entry printString.
   687 	].
   563             this > longestWidth ifTrue:[
   688 	labels := menu labels.
   564                 longest := entry.
   689 	labels notNil ifTrue:[
   565                 longestWidth := this
   690 	    labels do:[:entry |
   566             ].
   691 		|this|
   567         ].
   692 
   568         savedLogo := logo.
   693 		this := font widthOf:entry printString.
   569         logo := longest printString.
   694 		this > longestWidth ifTrue:[
   570         super computeLabelSize.
   695 		    longest := entry.
   571         logo := savedLogo.
   696 		    longestWidth := this
   572 "self halt.     "
   697 		].
       
   698 	    ].
       
   699 	].
       
   700 	savedLogo := logo.
       
   701 	logo := longest printString.
       
   702 	super computeLabelSize.
       
   703 	logo := savedLogo.
   573     ].
   704     ].
   574     mmH := device horizontalPixelPerMillimeter.
   705     mmH := device horizontalPixelPerMillimeter.
   575     mmV := device verticalPixelPerMillimeter.
   706     mmV := device verticalPixelPerMillimeter.
   576     labelWidth := labelWidth + hSpace + (mmH * 2.5) rounded + hSpace.
   707     labelWidth := labelWidth + hSpace + (mmH * 2.5) rounded + hSpace.
   577     labelHeight := labelHeight max: (mmV * 2) rounded
   708     labelHeight := labelHeight max: (mmV * 2) rounded
   588 		     for:self.
   719 		     for:self.
   589 !
   720 !
   590 
   721 
   591 realize
   722 realize
   592     super realize.
   723     super realize.
   593     model notNil ifTrue:[
   724     (model notNil or:[listHolder notNil]) ifTrue:[
   594 	self getListFromModel.
   725         self getListFromModel.
   595 	self getSelectionFromModel.
   726     ].
   596     ].
   727     (model notNil or:[selectionHolder notNil]) ifTrue:[
       
   728         self getSelectionFromModel.
       
   729     ]
   597 ! !
   730 ! !
   598 
   731 
   599 !PopUpList methodsFor:'private-controller access'!
   732 !PopUpList methodsFor:'private-controller access'!
   600 
   733 
   601 menu
   734 menu
   610     "redefined to make certain that the menu is fully defined"
   743     "redefined to make certain that the menu is fully defined"
   611 
   744 
   612     "/ If I have an explicit preferredExtent ..
   745     "/ If I have an explicit preferredExtent ..
   613 
   746 
   614     preferredExtent notNil ifTrue:[
   747     preferredExtent notNil ifTrue:[
   615         ^ preferredExtent
   748 	^ preferredExtent
   616     ].
   749     ].
   617 
   750 
   618     menu isNil ifTrue:[
   751     menu isNil ifTrue:[
   619         self getListFromModel
   752 	self getListFromModel
   620     ].
   753     ].
   621     self computeLabelSize.
   754     self computeLabelSize.
   622     ^ super preferredExtent.
   755     ^ super preferredExtent.
   623 
   756 
   624     "Modified: 19.7.1996 / 20:45:16 / cg"
   757     "Modified: 19.7.1996 / 20:45:16 / cg"
   625 !
   758 !
   626 
   759 
   627 specClass
   760 specClass
   628     self class == PopUpList ifTrue:[^ PopUpListSpec].
   761     self class == PopUpList ifTrue:[^ PopUpListSpec].
   629     ^ nil
   762     ^ super specClass
   630 ! !
   763 ! !
   631 
   764 
   632 !PopUpList methodsFor:'user actions'!
   765 !PopUpList methodsFor:'user actions'!
   633 
   766 
   634 select:anEntry
   767 select:anEntry
   636 
   769 
   637     |value label|
   770     |value label|
   638 
   771 
   639     label := menu labels at:anEntry.
   772     label := menu labels at:anEntry.
   640     values isNil ifTrue:[
   773     values isNil ifTrue:[
   641         value := anEntry.
   774 	value := anEntry.
   642         useIndex ifFalse:[
   775 	useIndex ifFalse:[
   643             value := menu labels at:anEntry.
   776 	    value := menu labels at:anEntry.
   644         ]
   777 	]
   645     ] ifFalse:[
   778     ] ifFalse:[
   646         value := values at:anEntry
   779 	value := values at:anEntry
   647     ].
       
   648 
       
   649     menuAction notNil ifTrue:[
       
   650         menuAction value:value.
       
   651     ].
   780     ].
   652 
   781 
   653     self sizeFixed:true.
   782     self sizeFixed:true.
   654     self label:label printString.
   783     self label:label printString.
       
   784 
       
   785     selectionHolder notNil ifTrue:[
       
   786 	selectionHolder perform:changeMsg with:value
       
   787     ].
   655 
   788 
   656     "/
   789     "/
   657     "/ ST-80 way of doing it
   790     "/ ST-80 way of doing it
   658     "/ tell my model - if any
   791     "/ tell my model - if any
   659     "/
   792     "/
   660     self sendChangeMessageWith:value
   793     self sendChangeMessageWith:value.
       
   794 
       
   795     "/
       
   796     "/ ST/X action blocks
       
   797     "/
       
   798     menuAction notNil ifTrue:[
       
   799 	menuAction value:value.
       
   800     ].
   661 
   801 
   662     "Modified: 14.2.1997 / 16:47:09 / cg"
   802     "Modified: 14.2.1997 / 16:47:09 / cg"
   663 ! !
   803 ! !
   664 
   804 
   665 !PopUpList class methodsFor:'documentation'!
   805 !PopUpList class methodsFor:'documentation'!
   666 
   806 
   667 version
   807 version
   668     ^ '$Header: /cvs/stx/stx/libwidg/PopUpList.st,v 1.31 1997-02-21 19:24:57 ca Exp $'
   808     ^ '$Header: /cvs/stx/stx/libwidg/PopUpList.st,v 1.32 1997-02-25 14:51:44 cg Exp $'
   669 ! !
   809 ! !