PullDownMenu.st
changeset 59 450ce95a72a4
parent 38 4b9b70b2cc87
child 60 f3c738c24ce6
equal deleted inserted replaced
58:28815246bbc1 59:450ce95a72a4
     1 "
     1 "
     2  COPYRIGHT (c) 1989 by Claus Gittinger
     2  COPYRIGHT (c) 1989 by Claus Gittinger
     3               All Rights Reserved
     3 	      All Rights Reserved
     4 
     4 
     5  This software is furnished under a license and may be used
     5  This software is furnished under a license and may be used
     6  only in accordance with the terms of that license and with the
     6  only in accordance with the terms of that license and with the
     7  inclusion of the above copyright notice.   This software may not
     7  inclusion of the above copyright notice.   This software may not
     8  be provided or otherwise made available to, or used by, any
     8  be provided or otherwise made available to, or used by, any
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
    12 
    13 View subclass:#PullDownMenu
    13 View subclass:#PullDownMenu
    14        instanceVariableNames:'menus titles activeMenuNumber
    14        instanceVariableNames:'menus titles activeMenuNumber
    15                               showSeparatingLines topMargin
    15 			      showSeparatingLines topMargin
    16                               fgColor bgColor activeFgColor activeBgColor
    16 			      fgColor bgColor activeFgColor activeBgColor
    17                               onLevel offLevel
    17 			      onLevel offLevel
    18                               keepMenu'
    18 			      keepMenu'
    19        classVariableNames:''
    19        classVariableNames:'DefaultFont
       
    20 			   DefaultViewBackground 
       
    21 			   DefaultForegroundColor 
       
    22 			   DefaultBackgroundColor
       
    23 			   DefaultHilightForegroundColor 
       
    24 			   DefaultHilightBackgroundColor
       
    25 			   DefaultLevel DefaultHilightLevel
       
    26 			   DefaultShadowColor DefaultLightColor'
    20        poolDictionaries:''
    27        poolDictionaries:''
    21        category:'Views-Menus'
    28        category:'Views-Menus'
    22 !
    29 !
    23 
    30 
    24 PullDownMenu comment:'
    31 PullDownMenu comment:'
    25 COPYRIGHT (c) 1989 by Claus Gittinger
    32 COPYRIGHT (c) 1989 by Claus Gittinger
    26              All Rights Reserved
    33 	     All Rights Reserved
    27 
    34 
    28 $Header: /cvs/stx/stx/libwidg/PullDownMenu.st,v 1.5 1994-08-07 13:23:11 claus Exp $
    35 $Header: /cvs/stx/stx/libwidg/PullDownMenu.st,v 1.6 1994-10-10 03:02:41 claus Exp $
    29 '!
    36 '!
    30 
    37 
    31 !PullDownMenu class methodsFor:'documentation'!
    38 !PullDownMenu class methodsFor:'documentation'!
    32 
    39 
    33 copyright
    40 copyright
    34 "
    41 "
    35  COPYRIGHT (c) 1989 by Claus Gittinger
    42  COPYRIGHT (c) 1989 by Claus Gittinger
    36               All Rights Reserved
    43 	      All Rights Reserved
    37 
    44 
    38  This software is furnished under a license and may be used
    45  This software is furnished under a license and may be used
    39  only in accordance with the terms of that license and with the
    46  only in accordance with the terms of that license and with the
    40  inclusion of the above copyright notice.   This software may not
    47  inclusion of the above copyright notice.   This software may not
    41  be provided or otherwise made available to, or used by, any
    48  be provided or otherwise made available to, or used by, any
    44 "
    51 "
    45 !
    52 !
    46 
    53 
    47 version
    54 version
    48 "
    55 "
    49 $Header: /cvs/stx/stx/libwidg/PullDownMenu.st,v 1.5 1994-08-07 13:23:11 claus Exp $
    56 $Header: /cvs/stx/stx/libwidg/PullDownMenu.st,v 1.6 1994-10-10 03:02:41 claus Exp $
    50 "
    57 "
    51 !
    58 !
    52 
    59 
    53 documentation
    60 documentation
    54 "
    61 "
    68     activeFgColor           <Color>         color to draw activated menu-titles
    75     activeFgColor           <Color>         color to draw activated menu-titles
    69     activeBgColor           <Color>         color to draw activated menu-titles
    76     activeBgColor           <Color>         color to draw activated menu-titles
    70     onLevel                 <Integer>       level of entry-buttons when pressed
    77     onLevel                 <Integer>       level of entry-buttons when pressed
    71     offLevel                <Integer>       level of entry-buttons when released
    78     offLevel                <Integer>       level of entry-buttons when released
    72     keepmenu                <Boolean>       if on, pulled menu stays on click,
    79     keepmenu                <Boolean>       if on, pulled menu stays on click,
    73                                             till clicked again (motif & windows behavior)
    80 					    till clicked again (motif & windows behavior)
    74 "
    81 "
       
    82 ! !
       
    83 
       
    84 !PullDownMenu class methodsFor:'defaults'!
       
    85 
       
    86 updateStyleCache
       
    87     DefaultViewBackground := StyleSheet at:'pullDownMenuViewBackground'.
       
    88     DefaultForegroundColor := StyleSheet at:'pullDownMenuForegroundColor' default:Black.
       
    89     DefaultBackgroundColor := StyleSheet at:'pullDownMenuBackgroundColor'.
       
    90     DefaultHilightForegroundColor := StyleSheet at:'pullDownMenuHilightForegroundColor'.
       
    91     DefaultHilightBackgroundColor := StyleSheet at:'pullDownMenuHilightBackgroundColor'.
       
    92     DefaultHilightLevel := StyleSheet at:'pullDownMenuHilightLevel' default:-1.
       
    93     DefaultLevel := StyleSheet at:'pullDownMenuLevel' default:1.
       
    94     DefaultFont := StyleSheet at:'pullDownMenuFont'.
       
    95 
       
    96     DefaultForegroundColor notNil ifTrue:[
       
    97 	DefaultForegroundColor := DefaultForegroundColor on:Display
       
    98     ].
       
    99     DefaultBackgroundColor notNil ifTrue:[
       
   100 	DefaultBackgroundColor := DefaultBackgroundColor on:Display
       
   101     ].
       
   102     DefaultShadowColor notNil ifTrue:[
       
   103 	DefaultShadowColor := DefaultShadowColor on:Display
       
   104     ].
       
   105     DefaultLightColor notNil ifTrue:[
       
   106 	DefaultLightColor := DefaultLightColor on:Display
       
   107     ].
       
   108     DefaultHilightForegroundColor notNil ifTrue:[
       
   109 	DefaultHilightForegroundColor := DefaultHilightForegroundColor on:Display
       
   110     ].
       
   111     DefaultHilightBackgroundColor notNil ifTrue:[
       
   112 	DefaultHilightBackgroundColor := DefaultHilightBackgroundColor on:Display
       
   113     ].
       
   114     DefaultFont notNil ifTrue:[
       
   115 	DefaultFont := DefaultFont on:Display
       
   116     ].
    75 ! !
   117 ! !
    76 
   118 
    77 !PullDownMenu class methodsFor:'instance creation'!
   119 !PullDownMenu class methodsFor:'instance creation'!
    78 
   120 
    79 labels:titleArray
   121 labels:titleArray
    87 initialize
   129 initialize
    88     super initialize.
   130     super initialize.
    89 
   131 
    90     font := font on:device.
   132     font := font on:device.
    91     self origin:(0.0 @ 0.0)
   133     self origin:(0.0 @ 0.0)
    92          extent:(1.0 @ (font height + (font descent * 2)  + topMargin)).
   134 	 extent:(1.0 @ (font height + (font descent * 2)  + topMargin)).
    93 !
   135 !
    94 
   136 
    95 initStyle
   137 initStyle
    96     super initStyle.
   138     super initStyle.
    97 
   139 
    98     showSeparatingLines := false.
   140     showSeparatingLines := false.
    99     fgColor := Black.
   141     DefaultViewBackground notNil ifTrue:[
   100     bgColor := viewBackground.
   142 	viewBackground := DefaultViewBackground
   101     onLevel := -1.
   143     ].
   102     offLevel := 1.
   144 
       
   145     DefaultForegroundColor notNil ifTrue:[
       
   146 	fgColor := DefaultForegroundColor
       
   147     ] ifFalse:[
       
   148 	fgColor := Black.
       
   149     ].
       
   150     DefaultBackgroundColor notNil ifTrue:[
       
   151 	bgColor := DefaultBackgroundColor
       
   152     ] ifFalse:[
       
   153 	bgColor := viewBackground.
       
   154     ].
       
   155     onLevel := DefaultHilightLevel.
       
   156     offLevel := DefaultLevel.
   103 
   157 
   104     self is3D ifTrue:[
   158     self is3D ifTrue:[
   105         device hasColors ifTrue:[
   159 	device hasColors ifTrue:[
   106             activeFgColor := Color name:'yellow'
   160 	    activeFgColor := Color name:'yellow'
   107         ] ifFalse:[
   161 	] ifFalse:[
   108             activeFgColor := White
   162 	    activeFgColor := White
   109         ].
   163 	].
   110         device hasGreyscales ifTrue:[
   164 	device hasGreyscales ifTrue:[
   111             activeBgColor := bgColor.
   165 	    activeBgColor := bgColor.
   112         ] ifFalse:[
   166 	] ifFalse:[
   113             activeBgColor := fgColor.
   167 	    activeBgColor := fgColor.
   114         ].
   168 	].
   115         topMargin := 2.
   169 	topMargin := 2.
   116 
   170 
   117         ((style == #iris) or:[style == #motif]) ifTrue:[
   171 	((style == #iris) or:[style == #motif]) ifTrue:[
   118             self level:2.
   172 	    self level:2.
   119             softEdge := true.
   173 	    softEdge := true.
   120             onLevel := 2.
   174 	    onLevel := 2.
   121             offLevel := 0.
   175 	    offLevel := 0.
   122             activeFgColor := fgColor
   176 	    activeFgColor := fgColor
   123         ]
   177 	]
   124     ] ifFalse:[
   178     ] ifFalse:[
   125         activeFgColor := bgColor.
   179 	activeFgColor := bgColor.
   126         activeBgColor := fgColor.
   180 	activeBgColor := fgColor.
   127         topMargin := 0
   181 	topMargin := 0
   128     ].
   182     ].
       
   183 
       
   184     DefaultHilightForegroundColor notNil ifTrue:[
       
   185 	activeFgColor := DefaultHilightForegroundColor
       
   186     ].
       
   187     DefaultHilightBackgroundColor notNil ifTrue:[
       
   188 	activeBgColor := DefaultHilightBackgroundColor
       
   189     ].
       
   190     DefaultShadowColor notNil ifTrue:[
       
   191 	shadowColor := DefaultShadowColor on:device
       
   192     ].
       
   193     DefaultLightColor notNil ifTrue:[
       
   194 	lightColor := DefaultLightColor on:device
       
   195     ].
       
   196 
       
   197     bgColor := bgColor on:device.
       
   198     fgColor := fgColor on:device.
       
   199     activeBgColor := activeBgColor on:device.
       
   200     activeFgColor := activeFgColor on:device.
       
   201 
   129     keepMenu := (style == #motif) or:[(style == #iris) or:[style == #mswindows]].
   202     keepMenu := (style == #motif) or:[(style == #iris) or:[style == #mswindows]].
   130 !
   203 !
   131 
   204 
   132 initEvents
   205 initEvents
   133     self enableButtonMotionEvents.
   206     self enableButtonMotionEvents.
   149 showSeparatingLines:aBoolean
   222 showSeparatingLines:aBoolean
   150     "turn on/off drawing of separating lines"
   223     "turn on/off drawing of separating lines"
   151 
   224 
   152     showSeparatingLines := aBoolean.
   225     showSeparatingLines := aBoolean.
   153     shown ifTrue:[
   226     shown ifTrue:[
   154         self redraw
   227 	self redraw
   155     ]
   228     ]
   156 !
   229 !
   157 
   230 
   158 numberOfTitles:n
   231 numberOfTitles:n
   159     "setup blank title-space to be filled in later"
   232     "setup blank title-space to be filled in later"
   169 
   242 
   170     numberOfLabels := titleArray size.
   243     numberOfLabels := titleArray size.
   171     menus := Array new:numberOfLabels.
   244     menus := Array new:numberOfLabels.
   172     titles := Array new:numberOfLabels.
   245     titles := Array new:numberOfLabels.
   173     1 to:numberOfLabels do:[:index |
   246     1 to:numberOfLabels do:[:index |
   174         titles at:index put:(titleArray at:index) printString
   247 	titles at:index put:(titleArray at:index) printString
   175     ].
   248     ].
   176     shown ifTrue:[
   249     shown ifTrue:[
   177         self clear.
   250 	self clear.
   178         self redraw
   251 	self redraw
   179     ]
   252     ]
   180 !
   253 !
   181 
   254 
   182 labels
   255 labels
   183     "return the menu-titles (group-headers)"
   256     "return the menu-titles (group-headers)"
   209     |index|
   282     |index|
   210 
   283 
   211     index := self indexOf:aString.
   284     index := self indexOf:aString.
   212     (index == 0) ifTrue:[^ nil].
   285     (index == 0) ifTrue:[^ nil].
   213     aMenu origin:((left + (self titleLenUpTo:index)) 
   286     aMenu origin:((left + (self titleLenUpTo:index)) 
   214                   @
   287 		  @
   215                   (height + aMenu borderWidth)).
   288 		  (height + aMenu borderWidth)).
   216     aMenu hidden:true.
   289     aMenu hidden:true.
   217     menus at:index put:aMenu
   290     menus at:index put:aMenu
   218 !
   291 !
   219 
   292 
   220 at:aString putLabels:labels selectors:selectors args:args receiver:anObject
   293 at:aString putLabels:labels selectors:selectors args:args receiver:anObject
   221     "create and set the menu under the title, aString"
   294     "create and set the menu under the title, aString"
   222 
   295 
   223     |menuView|
   296     |menuView|
   224 
   297 
   225     menuView := MenuView labels:labels
   298     menuView := MenuView labels:labels
   226                       selectors:selectors
   299 		      selectors:selectors
   227                            args:args
   300 			   args:args
   228                        receiver:anObject
   301 		       receiver:anObject
   229                             for:self.
   302 			    for:self.
   230     self at:aString putMenu:menuView
   303     self at:aString putMenu:menuView
   231 !
   304 !
   232 
   305 
   233 at:aString putLabels:labels selector:selector args:args receiver:anObject
   306 at:aString putLabels:labels selector:selector args:args receiver:anObject
   234     "create and set the menu under the title, aString"
   307     "create and set the menu under the title, aString"
   235 
   308 
   236     |menuView|
   309     |menuView|
   237 
   310 
   238     menuView := MenuView labels:labels
   311     menuView := MenuView labels:labels
   239                        selector:selector
   312 		       selector:selector
   240                            args:args
   313 			   args:args
   241                        receiver:anObject
   314 		       receiver:anObject
   242                             for:self.
   315 			    for:self.
   243     self at:aString putMenu:menuView
   316     self at:aString putMenu:menuView
   244 !
   317 !
   245 
   318 
   246 at:aString putLabels:labels selectors:selectors receiver:anObject
   319 at:aString putLabels:labels selectors:selectors receiver:anObject
   247     "create and set the menu under the title, aString"
   320     "create and set the menu under the title, aString"
   248 
   321 
   249     |menuView|
   322     |menuView|
   250 
   323 
   251     menuView := MenuView labels:labels
   324     menuView := MenuView labels:labels
   252                       selectors:selectors
   325 		      selectors:selectors
   253                        receiver:anObject
   326 		       receiver:anObject
   254                             for:self.
   327 			    for:self.
   255     self at:aString putMenu:menuView
   328     self at:aString putMenu:menuView
   256 ! !
   329 ! !
   257 
   330 
   258 !PullDownMenu methodsFor:'private'!
   331 !PullDownMenu methodsFor:'private'!
   259 
   332 
   263     |len "{ Class: SmallInteger }" |
   336     |len "{ Class: SmallInteger }" |
   264 
   337 
   265     (index <= 1) ifTrue:[^ 0].
   338     (index <= 1) ifTrue:[^ 0].
   266     len := 0.
   339     len := 0.
   267     titles from:1 to:(index - 1) do:[:string |
   340     titles from:1 to:(index - 1) do:[:string |
   268         len := len + (font widthOf:(' ' , string , ' ')).
   341 	len := len + (font widthOf:(' ' , string , ' ')).
   269         showSeparatingLines ifTrue:[
   342 	showSeparatingLines ifTrue:[
   270             self is3D ifTrue:[
   343 	    self is3D ifTrue:[
   271                 len := len + 2
   344 		len := len + 2
   272             ] ifFalse:[
   345 	    ] ifFalse:[
   273                 len := len + 1
   346 		len := len + 1
   274             ]
   347 	    ]
   275         ]
   348 	]
   276     ].
   349     ].
   277     ^ len
   350     ^ len
   278 !
   351 !
   279 
   352 
   280 indexOf:stringOrNumber
   353 indexOf:stringOrNumber
   281     "return the index of the menu with title; return 0 if not found"
   354     "return the index of the menu with title; return 0 if not found"
   282 
   355 
   283     (stringOrNumber isMemberOf:SmallInteger) ifTrue:[
   356     (stringOrNumber isMemberOf:SmallInteger) ifTrue:[
   284         ^ stringOrNumber
   357 	^ stringOrNumber
   285     ].
   358     ].
   286     ^ titles indexOf:stringOrNumber
   359     ^ titles indexOf:stringOrNumber
   287 !
   360 !
   288 
   361 
   289 setMenuOrigins
   362 setMenuOrigins
   290     "adjust origins of menus when font changes"
   363     "adjust origins of menus when font changes"
   291 
   364 
   292     |index|
   365     |index|
   293 
   366 
   294     (font device == device) ifTrue:[
   367     (font device == device) ifTrue:[
   295         index := 1.
   368 	index := 1.
   296         menus do:[:aMenu |
   369 	menus do:[:aMenu |
   297             aMenu notNil ifTrue:[
   370 	    aMenu notNil ifTrue:[
   298                 aMenu origin:((left + (self titleLenUpTo:index)) 
   371 		aMenu origin:((left + (self titleLenUpTo:index)) 
   299                               @
   372 			      @
   300                               (height + aMenu borderWidth))
   373 			      (height + aMenu borderWidth))
   301             ].
   374 	    ].
   302             index := index + 1
   375 	    index := index + 1
   303         ]
   376 	]
   304     ]
   377     ]
   305 ! !
   378 ! !
   306 
   379 
   307 !PullDownMenu methodsFor:'hiding/showing menus'!
   380 !PullDownMenu methodsFor:'hiding/showing menus'!
   308 
   381 
   310     |yText w|
   383     |yText w|
   311 
   384 
   312     yText := ((height - (font height)) // 2) + (font ascent) "+ topMargin".
   385     yText := ((height - (font height)) // 2) + (font ascent) "+ topMargin".
   313     w := font widthOf:string.
   386     w := font widthOf:string.
   314     selected ifTrue:[
   387     selected ifTrue:[
   315         self paint:activeBgColor
   388 	self paint:activeBgColor
   316     ] ifFalse:[
   389     ] ifFalse:[
   317         self paint:bgColor
   390 	self paint:bgColor
   318     ].
   391     ].
   319     self fillRectangleX:x y:0 width:w height:height.
   392     self fillRectangleX:x y:0 width:w height:height.
   320 
   393 
   321     self is3D ifTrue:[
   394     self is3D ifTrue:[
   322         self drawEdgesForX:x y:0
   395 	self drawEdgesForX:x y:0
   323                      width:w
   396 		     width:w
   324                     height:height
   397 		    height:height
   325                      level:(selected ifTrue:[onLevel] ifFalse:[offLevel])
   398 		     level:(selected ifTrue:[onLevel] ifFalse:[offLevel])
   326     ].
   399     ].
   327     selected ifTrue:[
   400     selected ifTrue:[
   328         self paint:activeFgColor
   401 	self paint:activeFgColor
   329     ] ifFalse:[
   402     ] ifFalse:[
   330         self paint:fgColor
   403 	self paint:fgColor
   331     ].
   404     ].
   332     self displayString:string x:x y:yText
   405     self displayString:string x:x y:yText
   333 !
   406 !
   334 
   407 
   335 highlightActiveTitle
   408 highlightActiveTitle
   336     |x string|
   409     |x string|
   337     activeMenuNumber notNil ifTrue:[
   410     activeMenuNumber notNil ifTrue:[
   338         x := self titleLenUpTo:activeMenuNumber.
   411 	x := self titleLenUpTo:activeMenuNumber.
   339         string := ' ' , (titles at:activeMenuNumber) , ' '.
   412 	string := ' ' , (titles at:activeMenuNumber) , ' '.
   340         self drawTitle:string x:x selected:true
   413 	self drawTitle:string x:x selected:true
   341     ]
   414     ]
   342 !
   415 !
   343 
   416 
   344 unHighlightActiveTitle
   417 unHighlightActiveTitle
   345     |x string|
   418     |x string|
   346     activeMenuNumber notNil ifTrue:[
   419     activeMenuNumber notNil ifTrue:[
   347         x := self titleLenUpTo:activeMenuNumber.
   420 	x := self titleLenUpTo:activeMenuNumber.
   348         string := ' ' , (titles at:activeMenuNumber) , ' '.
   421 	string := ' ' , (titles at:activeMenuNumber) , ' '.
   349         self drawTitle:string x:x selected:false
   422 	self drawTitle:string x:x selected:false
   350     ]
   423     ]
   351 !
   424 !
   352 
   425 
   353 hideActiveMenuRelease:aBoolean
   426 hideActiveMenuRelease:aBoolean
   354     activeMenuNumber notNil ifTrue:[
   427     activeMenuNumber notNil ifTrue:[
   355         (menus at:activeMenuNumber) unrealize.
   428 	(menus at:activeMenuNumber) unrealize.
   356         self unHighlightActiveTitle.
   429 	self unHighlightActiveTitle.
   357         aBoolean ifTrue:[device ungrabPointer. self cursor:Cursor normal].
   430 	aBoolean ifTrue:[device ungrabPointer. self cursor:Cursor normal].
   358         activeMenuNumber := nil
   431 	activeMenuNumber := nil
   359     ]
   432     ]
   360 !
   433 !
   361 
   434 
   362 hideActiveMenu
   435 hideActiveMenu
   363     ^ self hideActiveMenuRelease:true
   436     ^ self hideActiveMenuRelease:true
   369     |subMenu|
   442     |subMenu|
   370 
   443 
   371     activeMenuNumber notNil ifTrue:[self hideActiveMenuRelease:false].
   444     activeMenuNumber notNil ifTrue:[self hideActiveMenuRelease:false].
   372     subMenu := menus at:aNumber.
   445     subMenu := menus at:aNumber.
   373     subMenu notNil ifTrue:[
   446     subMenu notNil ifTrue:[
   374         activeMenuNumber := aNumber.
   447 	activeMenuNumber := aNumber.
   375         self highlightActiveTitle.
   448 	self highlightActiveTitle.
   376         subMenu deselect.
   449 	subMenu deselect.
   377         subMenu create.
   450 	subMenu create.
   378         subMenu saveUnder:true.
   451 	subMenu saveUnder:true.
   379         subMenu raise show
   452 	subMenu raise show
   380     ]
   453     ]
   381 ! !
   454 ! !
   382 
   455 
   383 !PullDownMenu methodsFor:'events'!
   456 !PullDownMenu methodsFor:'events'!
   384 
   457 
   392     titles isNil ifTrue:[^ self].
   465     titles isNil ifTrue:[^ self].
   393     x := 0.
   466     x := 0.
   394     y := height "- 1".
   467     y := height "- 1".
   395     index := 0.
   468     index := 0.
   396     titles do:[:title |
   469     titles do:[:title |
   397         string := ' ' , title , ' '.
   470 	string := ' ' , title , ' '.
   398         self drawTitle:string x:x selected:(index == activeMenuNumber).
   471 	self drawTitle:string x:x selected:(index == activeMenuNumber).
   399         x := x + (font widthOf:string).
   472 	x := x + (font widthOf:string).
   400         showSeparatingLines ifTrue:[
   473 	showSeparatingLines ifTrue:[
   401             self is3D ifTrue:[
   474 	    self is3D ifTrue:[
   402                 self paint:shadowColor.
   475 		self paint:shadowColor.
   403                 self displayLineFromX:x y:0 toX:x y:y.
   476 		self displayLineFromX:x y:0 toX:x y:y.
   404                 x := x + 1.
   477 		x := x + 1.
   405                 self paint:lightColor.
   478 		self paint:lightColor.
   406                 self displayLineFromX:x y:0 toX:x y:y
   479 		self displayLineFromX:x y:0 toX:x y:y
   407             ] ifFalse:[
   480 	    ] ifFalse:[
   408                 self paint:fgColor.
   481 		self paint:fgColor.
   409                 self displayLineFromX:x y:0 toX:x y:y
   482 		self displayLineFromX:x y:0 toX:x y:y
   410             ].
   483 	    ].
   411             x := x + 1
   484 	    x := x + 1
   412         ].
   485 	].
   413         index := index + 1
   486 	index := index + 1
   414     ]
   487     ]
   415 !
   488 !
   416 
   489 
   417 titleIndexForX:x
   490 titleIndexForX:x
   418     "given a click x-position, return index in title or nil"
   491     "given a click x-position, return index in title or nil"
   421      xstart "{ Class: SmallInteger }"
   494      xstart "{ Class: SmallInteger }"
   422      xend   "{ Class: SmallInteger }" |
   495      xend   "{ Class: SmallInteger }" |
   423 
   496 
   424     xstart := 0.
   497     xstart := 0.
   425     1 to:(titles size) do:[:index |
   498     1 to:(titles size) do:[:index |
   426         string := ' ' , (titles at:index) , ' '.
   499 	string := ' ' , (titles at:index) , ' '.
   427         xend := xstart + (font widthOf:string).
   500 	xend := xstart + (font widthOf:string).
   428         showSeparatingLines ifTrue:[
   501 	showSeparatingLines ifTrue:[
   429             self is3D ifTrue:[
   502 	    self is3D ifTrue:[
   430                 xend := xend + 2
   503 		xend := xend + 2
   431             ] ifFalse:[
   504 	    ] ifFalse:[
   432                 xend := xend + 1
   505 		xend := xend + 1
   433             ]
   506 	    ]
   434         ].
   507 	].
   435         (x between:xstart and:xend) ifTrue:[^ index].
   508 	(x between:xstart and:xend) ifTrue:[^ index].
   436         xstart := xend
   509 	xstart := xend
   437     ].
   510     ].
   438     ^ nil
   511     ^ nil
   439 !
   512 !
   440 
   513 
   441 buttonPress:button x:x y:y
   514 buttonPress:button x:x y:y
   442     |titleIndex activeMenu activeLeft activeTop|
   515     |titleIndex activeMenu activeLeft activeTop|
   443 
   516 
   444     (y between:0 and:height) ifTrue:[
   517     (y between:0 and:height) ifTrue:[
   445         titleIndex := self titleIndexForX:x.
   518 	titleIndex := self titleIndexForX:x.
   446     ].
   519     ].
   447 
   520 
   448     "
   521     "
   449      now, titleIndex is non-nil if pressed within myself
   522      now, titleIndex is non-nil if pressed within myself
   450     "
   523     "
   451     (titleIndex notNil and:[titleIndex ~~ activeMenuNumber]) ifTrue:[
   524     (titleIndex notNil and:[titleIndex ~~ activeMenuNumber]) ifTrue:[
   452         self pullMenu:titleIndex.
   525 	self pullMenu:titleIndex.
   453         keepMenu ifTrue:[
   526 	keepMenu ifTrue:[
   454             device grabPointerIn:self id.
   527 	    device grabPointerIn:self id.
   455             self cursor:Cursor upRightArrow
   528 	    self cursor:Cursor upRightArrow
   456         ]
   529 	]
   457     ] ifFalse:[
   530     ] ifFalse:[
   458         keepMenu ifTrue:[
   531 	keepMenu ifTrue:[
   459             titleIndex == activeMenuNumber ifTrue:[
   532 	    titleIndex == activeMenuNumber ifTrue:[
   460                 "same pressed again ... stay"
   533 		"same pressed again ... stay"
   461                 ^ self
   534 		^ self
   462             ].
   535 	    ].
   463             "moving around below"
   536 	    "moving around below"
   464             activeMenuNumber isNil ifTrue:[^self].
   537 	    activeMenuNumber isNil ifTrue:[^self].
   465             activeMenu := menus at:activeMenuNumber.
   538 	    activeMenu := menus at:activeMenuNumber.
   466             activeLeft := activeMenu left.
   539 	    activeLeft := activeMenu left.
   467             (x between:activeLeft and:(activeMenu right)) ifTrue:[
   540 	    (x between:activeLeft and:(activeMenu right)) ifTrue:[
   468                 activeTop := activeMenu top.
   541 		activeTop := activeMenu top.
   469                 (y between:activeTop and:(activeMenu bottom)) ifTrue:[
   542 		(y between:activeTop and:(activeMenu bottom)) ifTrue:[
   470                     "moving around in menu"
   543 		    "moving around in menu"
   471                     activeMenu buttonPress:button
   544 		    activeMenu buttonPress:button
   472                                          x:(x - activeLeft)
   545 					 x:(x - activeLeft)
   473                                          y:(y - activeTop).
   546 					 y:(y - activeTop).
   474                     ^ self
   547 		    ^ self
   475                 ]
   548 		]
   476             ].
   549 	    ].
   477         ].
   550 	].
   478         self hideActiveMenu
   551 	self hideActiveMenu
   479     ]
   552     ]
   480 !
   553 !
   481 
   554 
   482 buttonMotion:button x:x y:y
   555 buttonMotion:button x:x y:y
   483     |titleIndex activeMenu activeLeft activeTop|
   556     |titleIndex activeMenu activeLeft activeTop|
   484 
   557 
   485     (y < height) ifTrue:[
   558     (y < height) ifTrue:[
   486         "moving around in title line"
   559 	"moving around in title line"
   487         activeMenuNumber notNil ifTrue:[
   560 	activeMenuNumber notNil ifTrue:[
   488             (menus at:activeMenuNumber) selection:nil
   561 	    (menus at:activeMenuNumber) selection:nil
   489         ].
   562 	].
   490         titleIndex := self titleIndexForX:x.
   563 	titleIndex := self titleIndexForX:x.
   491         titleIndex notNil ifTrue:[
   564 	titleIndex notNil ifTrue:[
   492             (titleIndex ~~ activeMenuNumber) ifTrue:[
   565 	    (titleIndex ~~ activeMenuNumber) ifTrue:[
   493                 self pullMenu:titleIndex
   566 		self pullMenu:titleIndex
   494             ]
   567 	    ]
   495         ]
   568 	]
   496     ] ifFalse:[
   569     ] ifFalse:[
   497         "moving around below"
   570 	"moving around below"
   498         activeMenuNumber isNil ifTrue:[^self].
   571 	activeMenuNumber isNil ifTrue:[^self].
   499         activeMenu := menus at:activeMenuNumber.
   572 	activeMenu := menus at:activeMenuNumber.
   500         activeLeft := activeMenu left.
   573 	activeLeft := activeMenu left.
   501         (x between:activeLeft and:(activeMenu right)) ifTrue:[
   574 	(x between:activeLeft and:(activeMenu right)) ifTrue:[
   502             activeTop := activeMenu top.
   575 	    activeTop := activeMenu top.
   503             (y between:activeTop and:(activeMenu bottom)) ifTrue:[
   576 	    (y between:activeTop and:(activeMenu bottom)) ifTrue:[
   504                 "moving around in menu"
   577 		"moving around in menu"
   505                 activeMenu buttonMotion:button
   578 		activeMenu buttonMotion:button
   506                                       x:(x - activeLeft)
   579 				      x:(x - activeLeft)
   507                                       y:(y - activeTop).
   580 				      y:(y - activeTop).
   508                 ^ self
   581 		^ self
   509             ]
   582 	    ]
   510         ].
   583 	].
   511         "moved outside menu"
   584 	"moved outside menu"
   512         activeMenu selection:nil
   585 	activeMenu selection:nil
   513     ]
   586     ]
   514 !
   587 !
   515 
   588 
   516 buttonRelease:button x:x y:y
   589 buttonRelease:button x:x y:y
   517     |activeMenu activeLeft activeTop hideMenu|
   590     |activeMenu activeLeft activeTop hideMenu|
   518 
   591 
   519     hideMenu := false.
   592     hideMenu := false.
   520     (y >= height) ifTrue:[
   593     (y >= height) ifTrue:[
   521         "release below title-line"
   594 	"release below title-line"
   522         activeMenuNumber isNil ifTrue:[^self].
   595 	activeMenuNumber isNil ifTrue:[^self].
   523         activeMenu := menus at:activeMenuNumber.
   596 	activeMenu := menus at:activeMenuNumber.
   524         activeLeft := activeMenu left.
   597 	activeLeft := activeMenu left.
   525         "
   598 	"
   526          released in a submenu ?
   599 	 released in a submenu ?
   527         "
   600 	"
   528         (x between:activeLeft and:(activeMenu right)) ifTrue:[
   601 	(x between:activeLeft and:(activeMenu right)) ifTrue:[
   529             activeTop := activeMenu top.
   602 	    activeTop := activeMenu top.
   530             (y between:activeTop and:(activeMenu bottom)) ifTrue:[
   603 	    (y between:activeTop and:(activeMenu bottom)) ifTrue:[
   531                 "release in menu"
   604 		"release in menu"
   532                 self hideActiveMenu.   
   605 		self hideActiveMenu.   
   533                 activeMenu buttonRelease:button
   606 		activeMenu buttonRelease:button
   534                                        x:(x - activeLeft)
   607 				       x:(x - activeLeft)
   535                                        y:(y - activeTop).
   608 				       y:(y - activeTop).
   536                 ^ self
   609 		^ self
   537             ]
   610 	    ]
   538         ].
   611 	].
   539         hideMenu := true.
   612 	hideMenu := true.
   540     ] ifFalse:[
   613     ] ifFalse:[
   541         y < 0 ifTrue:[
   614 	y < 0 ifTrue:[
   542             hideMenu := true
   615 	    hideMenu := true
   543         ] ifFalse:[
   616 	] ifFalse:[
   544             keepMenu ifFalse:[   
   617 	    keepMenu ifFalse:[   
   545                 hideMenu := true
   618 		hideMenu := true
   546             ]
   619 	    ]
   547         ]
   620 	]
   548     ].                  
   621     ].                  
   549     hideMenu ifTrue:[
   622     hideMenu ifTrue:[
   550        self hideActiveMenu.
   623        self hideActiveMenu.
   551     ]
   624     ]
   552 ! !
   625 ! !