PullDownMenu.st
changeset 128 06a050529335
parent 119 59758ff5b841
child 130 338e856bddc9
equal deleted inserted replaced
127:462396b08e30 128:06a050529335
     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 SimpleView subclass:#PullDownMenu
    13 SimpleView subclass:#PullDownMenu
    14        instanceVariableNames:'menus titles selectors activeMenuNumber
    14        instanceVariableNames:'receiver menus titles selectors activeMenuNumber
    15 			      showSeparatingLines topMargin
    15 			      showSeparatingLines topMargin
    16 			      fgColor bgColor activeFgColor activeBgColor
    16 			      fgColor bgColor activeFgColor activeBgColor
    17 			      onLevel offLevel edgeStyle
    17 			      onLevel offLevel edgeStyle
    18 			      keepMenu toggleKeep'
    18 			      keepMenu toggleKeep'
    19        classVariableNames:'DefaultFont
    19        classVariableNames:'DefaultFont
    22 			   DefaultBackgroundColor
    22 			   DefaultBackgroundColor
    23 			   DefaultHilightForegroundColor 
    23 			   DefaultHilightForegroundColor 
    24 			   DefaultHilightBackgroundColor
    24 			   DefaultHilightBackgroundColor
    25 			   DefaultLevel DefaultHilightLevel
    25 			   DefaultLevel DefaultHilightLevel
    26 			   DefaultShadowColor DefaultLightColor 
    26 			   DefaultShadowColor DefaultLightColor 
    27 			   DefaultEdgeStyle DefaultKeepMenu DefaultToggleKeep'
    27 			   DefaultEdgeStyle DefaultKeepMenu DefaultToggleKeep
       
    28 			   DefaultSeparatingLines'
    28        poolDictionaries:''
    29        poolDictionaries:''
    29        category:'Views-Menus'
    30        category:'Views-Menus'
    30 !
    31 !
    31 
    32 
    32 PullDownMenu comment:'
    33 PullDownMenu comment:'
    33 COPYRIGHT (c) 1989 by Claus Gittinger
    34 COPYRIGHT (c) 1989 by Claus Gittinger
    34 	     All Rights Reserved
    35 	     All Rights Reserved
    35 
    36 
    36 $Header: /cvs/stx/stx/libwidg/PullDownMenu.st,v 1.17 1995-05-03 00:37:05 claus Exp $
    37 $Header: /cvs/stx/stx/libwidg/PullDownMenu.st,v 1.18 1995-05-17 12:25:49 claus Exp $
    37 '!
    38 '!
    38 
    39 
    39 !PullDownMenu class methodsFor:'documentation'!
    40 !PullDownMenu class methodsFor:'documentation'!
    40 
    41 
    41 copyright
    42 copyright
    52 "
    53 "
    53 !
    54 !
    54 
    55 
    55 version
    56 version
    56 "
    57 "
    57 $Header: /cvs/stx/stx/libwidg/PullDownMenu.st,v 1.17 1995-05-03 00:37:05 claus Exp $
    58 $Header: /cvs/stx/stx/libwidg/PullDownMenu.st,v 1.18 1995-05-17 12:25:49 claus Exp $
    58 "
    59 "
    59 !
    60 !
    60 
    61 
    61 documentation
    62 documentation
    62 "
    63 "
    63     PullDown menu provides the top (always visible) part of these menus. 
    64     PullDown menu provides the top (always visible) part of these menus. 
    64     It controls display of its menus, which become visible when one of the 
    65     It controls display of its menus, which become visible when one of the 
    65     PullDownMenus entries is pressed.
    66     PullDownMenus entries is pressed.
    66 
    67 
       
    68     A PullDownMenu itself consists of a single row of labels, which activate
       
    69     a pulled menu when clicked. Entries may be empty (i.e. have no menu)
       
    70     and empty entries may (optionally) also perform some action when clicked.
       
    71     An entries selector is used as the key to define and access submenus
       
    72     and (for empty entries:) the selector sent to the receiver of the menu.
       
    73 
    67     Instance variables:
    74     Instance variables:
    68 
    75 
    69       menus                   <aCollection>   the sub menus
    76       menus                   <Collection>    the sub menus
    70       titles                  <aCollection>   the strings in the menu
    77 
       
    78       titles                  <Collection>    the strings in the menu
       
    79 
       
    80       selectors               <Collection>    the selectors to send to the menu-
       
    81 					      receiver (for empty pull-menus)
       
    82 					      if nil (the default), title entries
       
    83 					      do not send anything.
       
    84 
    71       activeMenuNumber        <Number>        the index of the currently active menu
    85       activeMenuNumber        <Number>        the index of the currently active menu
       
    86 
    72       showSeparatingLines     <Boolean>       show separating lines between my menu-strings
    87       showSeparatingLines     <Boolean>       show separating lines between my menu-strings
       
    88 
    73       topMargin               <Number>        number of pixels at top
    89       topMargin               <Number>        number of pixels at top
    74       fgColor                 <Color>         color to draw passive menu-titles
    90 
    75       bgColor                 <Color>         color to draw passive menu-titles
    91       fgColor                 <Color>         fg color to draw passive menu-titles
    76       activeFgColor           <Color>         color to draw activated menu-titles
    92       bgColor                 <Color>         bg color to draw passive menu-titles
    77       activeBgColor           <Color>         color to draw activated menu-titles
    93 
    78       onLevel                 <Integer>       level of entry-buttons when pressed
    94       activeFgColor           <Color>         fg color to draw activated menu-titles
    79       offLevel                <Integer>       level of entry-buttons when released
    95       activeBgColor           <Color>         bg color to draw activated menu-titles
       
    96 
       
    97       onLevel                 <Integer>       3D level of entry-buttons when pressed
       
    98       offLevel                <Integer>       3D level of entry-buttons when released
       
    99 
       
   100       edgeStyle               <Symbol>        how to draw edges
       
   101 
    80       keepmenu                <Boolean>       if on, pulled menu stays on click,
   102       keepmenu                <Boolean>       if on, pulled menu stays on click,
    81 					      till clicked again (motif & windows behavior)
   103 					      till clicked again (motif & windows behavior)
    82 
   104 
       
   105       toggleKeep              <Boolean>       if on and keepMenu is on,
       
   106 					      clicking again on label closes menu
       
   107 
       
   108      except menus, titles and selectors, instvars are usually defined from
       
   109      defaults in the styleSheet; you should not care for them.
       
   110 
    83 
   111 
    84     StyleSheet values:
   112     StyleSheet values:
    85 
   113 
    86       pullDownMenuViewBackground              view background Color for the menu bar
   114       pullDownMenuViewBackground              view background Color for the menu bar
    87 					      default: menuViewBackground
   115 					      default: menuViewBackground
   102 					      default: menuHilightLevel
   130 					      default: menuHilightLevel
   103 
   131 
   104       pullDownMenuEdgeStyle                   edge style (nil or #soft)
   132       pullDownMenuEdgeStyle                   edge style (nil or #soft)
   105 
   133 
   106       pullDownMenuKeepMenu                    if true, pulled menu stays open until button
   134       pullDownMenuKeepMenu                    if true, pulled menu stays open until button
   107 					      is pressed again (motif behavior)
   135 					      is pressed again outside of the item-area (motif behavior)
   108 					      if false, menu closes on release (default)
   136 					      if false, menu closes on release (default)
   109 
   137 
   110       pullDownMenuToggleKeep                  if true, pulled menu closes when an entry is pressed
   138       pullDownMenuToggleKeep                  if true, pulled menu closes when an entry is pressed
   111 					      again. Otherwise, only press outside outside of
   139 					      again. Otherwise, only press outside of the items area
   112 					      the entry hides it.
   140 					      hides it. default is false
   113 					      default is false
       
   114 
   141 
   115       pullDownMenuLevel                       level (3D only)
   142       pullDownMenuLevel                       level (3D only)
   116 
   143 
   117       pullDownMenuFont                        font to use for the menu bar
   144       pullDownMenuFont                        font to use for the menu bar
   118 					      default: menuFont
   145 					      default: menuFont
       
   146 
       
   147       pullDownMenuShowSeparatingLines         if true, lines are drawn between items.
       
   148 					      default: false
   119 "
   149 "
   120 !
   150 !
   121 
   151 
   122 examples 
   152 examples 
   123 "
   153 "
   124     |top menu|
   154 	|top menu|
   125 
   155 
   126     top := StandardSystemView new.
   156 	top := StandardSystemView new.
   127     menu := PullDownMenu origin:0.0@0.0 corner:1.0@30 in:top.
   157 	top extent:300@300.
   128     menu labels:#('foo' 'bar').
   158 
   129     menu selectors:#(foo bar).
   159 	menu := PullDownMenu origin:0.0@0.0 corner:1.0@30 in:top.
   130     menu at:#foo
   160 	menu labels:#('foo' 'bar').
   131 	 putLabels:#('foo1' 'foo2' 'foo3')
   161 	menu selectors:#(foo bar).
   132 	 selectors:#(foo1 foo2 foo3)
   162 	menu at:#foo
   133 	 receiver:nil.
   163 	     putLabels:#('foo1' 'foo2' 'foo3')
   134     menu at:#bar 
   164 	     selectors:#(foo1 foo2 foo3)
   135 	 putLabels:#('bar1' 'bar2' 'bar3')
   165 	     receiver:nil.
   136 	 selectors:#(bar1 bar2 bar3)
   166 	menu at:#bar 
   137 	 receiver:nil.
   167 	     putLabels:#('bar1' 'bar2' 'bar3')
   138     top open
   168 	     selectors:#(bar1 bar2 bar3)
   139 
   169 	     receiver:nil.
   140 
   170 	top open
   141 
   171 
   142     'empty entries are possible ...'
   172 
   143 
   173 
   144     |top menu|
   174     empty entries are possible as selectable items (with non-nil seletor) ...
   145 
   175 
   146     top := StandardSystemView new.
   176 	|top menu|
   147     menu := PullDownMenu origin:0.0@0.0 corner:1.0@30 in:top.
   177 
   148     menu labels:#('foo' 'bar').
   178 	top := StandardSystemView new.
   149     menu selectors:#(foo bar).
   179 	top extent:300@300.
   150     menu at:#foo
   180 
   151 	 putLabels:#('foo1' 'foo2' 'foo3')
   181 	menu := PullDownMenu origin:0.0@0.0 corner:1.0@30 in:top.
   152 	 selectors:#(foo1 foo2 foo3)
   182 	menu labels:#('foo' 'bar' 'baz').
   153 	 receiver:nil.
   183 	menu selectors:#(foo bar baz).
   154     top open
   184 	menu at:#foo
   155 
   185 	     putLabels:#('foo1' 'foo2' 'foo3')
   156 
   186 	     selectors:#(foo1 foo2 foo3)
   157 
   187 	     receiver:nil.
   158     '... for example as separators'
   188 	menu at:#baz 
   159 
   189 	     putLabels:#('baz1' 'baz2' 'baz3')
   160     |top menu|
   190 	     selectors:#(baz1 baz2 baz3)
   161 
   191 	     receiver:nil.
   162     top := StandardSystemView new.
   192 	top open
   163     menu := PullDownMenu origin:0.0@0.0 corner:1.0@30 in:top.
   193 
   164     menu labels:#('foo' '    ' 'bar' ' baz' '    ' 'moreFoo' 'moreBar' 'moreBaz').
   194 
   165     menu selectors:#(foo nil bar baz nil moreFoo moreBar moreBaz).
   195 
   166     menu showSeparatingLines:true.
   196     ... or as separators (with nil selector)
   167     menu at:#foo
   197 
   168 	 putLabels:#('foo1' 'foo2' 'foo3')
   198 	|top menu|
   169 	 selectors:#(foo1 foo2 foo3)
   199 
   170 	 receiver:nil.
   200 	top := StandardSystemView new.
   171     menu at:#bar 
   201 	top extent:500@200.
   172 	 putLabels:#('bar1' 'bar2' 'bar3')
   202 
   173 	 selectors:#(bar1 bar2 bar3)
   203 	menu := PullDownMenu origin:0.0@0.0 corner:1.0@30 in:top.
   174 	 receiver:nil.
   204 	menu labels:#('foo' '    ' 'bar' ' baz' '    ' 'moreFoo' 'moreBar' 'moreBaz').
   175     menu at:#baz 
   205 	menu selectors:#(foo nil bar baz nil moreFoo moreBar moreBaz).
   176 	 putLabels:#('baz1' 'baz2' 'baz3')
   206 	menu at:#foo
   177 	 selectors:#(baz1 baz2 baz3)
   207 	     putLabels:#('foo1' 'foo2' 'foo3')
   178 	 receiver:nil.
   208 	     selectors:#(foo1 foo2 foo3)
   179     top open
   209 	     receiver:nil.
   180 
   210 	menu at:#bar 
   181 
   211 	     putLabels:#('bar1' 'bar2' 'bar3')
   182 
   212 	     selectors:#(bar1 bar2 bar3)
   183 
   213 	     receiver:nil.
   184     'use menus default height'
   214 	menu at:#baz 
   185 
   215 	     putLabels:#('baz1' 'baz2' 'baz3')
   186     |top menu|
   216 	     selectors:#(baz1 baz2 baz3)
   187 
   217 	     receiver:nil.
   188     top := StandardSystemView new.
   218 	top open
   189     menu := PullDownMenu in:top.
   219 
   190     menu origin:0.0@0.0 corner:1.0@(menu height).
   220 
   191     menu labels:#('foo' 'bar').
   221 
   192     menu selectors:#(foo bar).
   222 
   193     menu at:#foo
   223     use the menus default height
   194 	 putLabels:#('foo1' 'foo2' 'foo3')
   224 
   195 	 selectors:#(foo1 foo2 foo3)
   225 	|top menu|
   196 	 receiver:nil.
   226 
   197     top open
   227 	top := StandardSystemView new.
   198 
   228 	top extent:300@300.
   199 
   229 
   200 
   230 	menu := PullDownMenu in:top.
   201 
   231 	menu origin:0.0@0.0 corner:1.0@(menu height).
   202     'although you can change the font, colors etc (as shown below)
   232 	menu labels:#('foo' 'bar').
   203      you should NOT do it - since if you do so, the styleSheet settings
   233 	menu selectors:#(foo bar).
   204      are ineffective (which users wont like probably)
   234 	menu at:#foo
   205      BTW: The styleSheet entries for below are pullDownMenuForegroundColor,
   235 	     putLabels:#('foo1' 'foo2' 'foo3')
   206 	  pullDownMenuBackgroundColor and pullDownMenuFont'
   236 	     selectors:#(foo1 foo2 foo3)
   207 
   237 	     receiver:nil.
   208     |top menu|
   238 	top open
   209 
   239 
   210     top := StandardSystemView new.
   240 
   211     menu := PullDownMenu in:top.
   241 
   212     menu font:(Font family:'courier' size:20).
   242 
   213     menu foregroundColor:Color red.
   243     although you can change the font, colors etc (as shown below)
   214     menu backgroundColor:Color yellow.
   244     you should NOT do it - since if you do so, the styleSheet settings
   215     menu viewBackground:Color yellow.
   245     are ineffective (which users wont like probably)
   216     menu showSeparatingLines:true.
   246     BTW: The styleSheet entries for below are pullDownMenuForegroundColor,
   217 
   247 	 pullDownMenuBackgroundColor and pullDownMenuFont
   218     menu origin:0.0@0.0 corner:1.0@(menu height).
   248 
   219     menu labels:#('foo' 'bar').
   249 	|top menu|
   220     menu selectors:#(foo bar).
   250 
   221     menu at:#foo
   251 	top := StandardSystemView new.
   222 	 putLabels:#('foo1' 'foo2' 'foo3')
   252 	menu := PullDownMenu in:top.
   223 	 selectors:#(foo1 foo2 foo3)
   253 	menu font:(Font family:'courier' size:20).
   224 	 receiver:nil.
   254 	menu foregroundColor:Color red.
   225     (menu menuAt:#foo) font:(Font family:'courier' size:36).
   255 	menu backgroundColor:Color yellow.
   226     top open
   256 	menu viewBackground:Color yellow.
   227 
   257 	menu showSeparatingLines:true.
   228 
   258 
   229 
   259 	menu origin:0.0@0.0 corner:1.0@(menu height).
   230     'you can use icons, too ...'
   260 	menu labels:#('foo' 'bar').
   231 
   261 	menu selectors:#(foo bar).
   232     |labels top menu|
   262 	menu at:#foo
   233 
   263 	     putLabels:#('foo1' 'foo2' 'foo3')
   234     top := StandardSystemView new.
   264 	     selectors:#(foo1 foo2 foo3)
   235     menu := PullDownMenu in:top.
   265 	     receiver:nil.
   236     menu origin:0.0@0.0 corner:1.0@(menu height).
   266 	(menu menuAt:#foo) font:(Font family:'courier' size:36).
   237     labels := Array with:(Image fromFile:'SmalltalkX.xbm')
   267 	top open
   238 		    with:'foo'
   268 
   239 		    with:'bar'.
   269 
   240     menu labels:labels.
   270 
   241     menu selectors:#(about foo bar).
   271     you can use icons, too ...
   242     menu at:#about 
   272 
   243 	 putLabels:#('about PullDownMenus')
   273 	|labels top menu|
   244 	 selectors:#(aboutMenus)
   274 
   245 	 receiver:nil.
   275 	top := StandardSystemView new.
   246     menu at:#foo
   276 	top extent:300@300.
   247 	 putLabels:#('foo1' 'foo2' 'foo3')
   277 
   248 	 selectors:#(foo1 foo2 foo3)
   278 	menu := PullDownMenu in:top.
   249 	 receiver:nil.
   279 	menu origin:0.0@0.0 corner:1.0@(menu height).
   250     top open
   280 	labels := Array with:((Image fromFile:'SmalltalkX.xbm') magnifiedTo:16@16)
       
   281 			with:'foo'
       
   282 			with:'bar'.
       
   283 	menu labels:labels.
       
   284 	menu selectors:#(about foo bar).
       
   285 	menu at:#about 
       
   286 	     putLabels:#('about PullDownMenus')
       
   287 	     selectors:#(aboutMenus)
       
   288 	     receiver:nil.
       
   289 	menu at:#foo
       
   290 	     putLabels:#('foo1' 'foo2' 'foo3')
       
   291 	     selectors:#(foo1 foo2 foo3)
       
   292 	     receiver:nil.
       
   293 	top open
       
   294 
       
   295 
       
   296 
       
   297     a concrete example (combining things described above)
       
   298     (using a Plug, since we have no application class here):
       
   299 
       
   300 	|labels top menu textView appModel|
       
   301 
       
   302 	appModel := Plug new.
       
   303 	appModel respondTo:#quit with:[top destroy].
       
   304 	appModel respondTo:#showAbout with:[self information:'some info here ...'].
       
   305 	appModel respondTo:#help with:[self information:'some help here ...'].
       
   306 
       
   307 	top := StandardSystemView new.
       
   308 	top extent:300@300.
       
   309 
       
   310 	menu := PullDownMenu in:top.
       
   311 	menu receiver:appModel.
       
   312 	menu origin:0.0@0.0 corner:1.0@(menu height).
       
   313 
       
   314 	textView := ScrollableView forView:(EditTextView new).
       
   315 	textView origin:0.0@menu height corner:1.0@1.0.
       
   316 	top addSubView:textView.
       
   317 
       
   318 	labels := Array with:((Image fromFile:'SmalltalkX.xbm') magnifiedTo:16@16)
       
   319 			with:'file'
       
   320 			with:'edit'
       
   321 			with:'help'.
       
   322 	menu labels:labels.
       
   323 	menu selectors:#(about file edit help).
       
   324 	menu at:#about 
       
   325 	     putLabels:#('about PullDownMenus')
       
   326 	     selectors:#(showAbout)
       
   327 	     receiver:appModel.
       
   328 	menu at:#file 
       
   329 	     putLabels:#('quit')
       
   330 	     selectors:#(quit)
       
   331 	     receiver:appModel.
       
   332 	menu at:#edit 
       
   333 	     putLabels:#('copy' 'cut' 'paste')
       
   334 	     selectors:#(copySelection cut paste)
       
   335 	     receiver:textView.
       
   336 	top open
   251 "
   337 "
   252 ! !
   338 ! !
   253 
   339 
   254 !PullDownMenu class methodsFor:'defaults'!
   340 !PullDownMenu class methodsFor:'defaults'!
   255 
   341 
   290     DefaultLevel := StyleSheet at:'pullDownMenuLevel' default:1.
   376     DefaultLevel := StyleSheet at:'pullDownMenuLevel' default:1.
   291     DefaultFont := StyleSheet fontAt:'pullDownMenuFont'.
   377     DefaultFont := StyleSheet fontAt:'pullDownMenuFont'.
   292     DefaultFont isNil ifTrue:[
   378     DefaultFont isNil ifTrue:[
   293 	DefaultFont := StyleSheet fontAt:'menuFont'.
   379 	DefaultFont := StyleSheet fontAt:'menuFont'.
   294     ].
   380     ].
       
   381     DefaultSeparatingLines := StyleSheet at:'pullDownMenuSeparatingLines' default:false.
   295 
   382 
   296     "
   383     "
   297      PullDownMenu updateStyleCache
   384      PullDownMenu updateStyleCache
   298     "
   385     "
   299 ! !
   386 ! !
   317 !
   404 !
   318 
   405 
   319 initStyle
   406 initStyle
   320     super initStyle.
   407     super initStyle.
   321 
   408 
   322     showSeparatingLines := false.
   409     showSeparatingLines := DefaultSeparatingLines. "/ false.
   323     DefaultViewBackground notNil ifTrue:[
   410     DefaultViewBackground notNil ifTrue:[
   324 	viewBackground := DefaultViewBackground on:device
   411 	viewBackground := DefaultViewBackground on:device
   325     ].
   412     ].
   326 
   413 
   327     DefaultFont notNil ifTrue:[
   414     DefaultFont notNil ifTrue:[
   387     activeBgColor := activeBgColor on:device.
   474     activeBgColor := activeBgColor on:device.
   388     activeFgColor := activeFgColor on:device.
   475     activeFgColor := activeFgColor on:device.
   389 !
   476 !
   390 
   477 
   391 recreate
   478 recreate
   392     "if saved with an active menu, hide it"
   479     "if the image was saved with an active menu, hide it"
       
   480 
       
   481     |m|
   393 
   482 
   394     activeMenuNumber notNil ifTrue:[
   483     activeMenuNumber notNil ifTrue:[
   395 	(menus at:activeMenuNumber) unrealize.
   484 	(m := menus at:activeMenuNumber) notNil ifTrue:[
       
   485 	    m unrealize.
       
   486 	].
   396 	activeMenuNumber := nil.
   487 	activeMenuNumber := nil.
   397     ].
   488     ].
   398     super recreate.
   489     super recreate.
   399     self setMenuOrigins
   490     self setMenuOrigins
   400 !
   491 !
   403     super create.
   494     super create.
   404     self setMenuOrigins
   495     self setMenuOrigins
   405 !
   496 !
   406 
   497 
   407 destroy
   498 destroy
   408     "
   499     "have to destroy the menus manually here,
   409      have to destroy the menus manually here,
   500      since they are no real subviews of myself"
   410      since they are no real subviews of myself
   501 
   411     "
       
   412     menus notNil ifTrue:[
   502     menus notNil ifTrue:[
   413 	menus do:[:m |
   503 	menus do:[:m |
   414 	    m notNil ifTrue:[m destroy]
   504 	    m notNil ifTrue:[m destroy]
   415 	].
   505 	].
   416 	menus := nil
   506 	menus := nil
   417     ].
   507     ].
   418     activeMenuNumber := nil.
   508     activeMenuNumber := nil.
   419     super destroy.
   509     super destroy.
   420 ! !
   510 ! !
   421 
   511 
   422 !PullDownMenu methodsFor:'accessing'!
   512 !PullDownMenu methodsFor:'accessing-look'!
   423 
   513 
   424 showSeparatingLines:aBoolean
   514 showSeparatingLines:aBoolean
   425     "turn on/off drawing of separating lines"
   515     "turn on/off drawing of separating lines.
       
   516      You should not use this method; instead leave the value as
       
   517      defined in the StyleSheet."
   426 
   518 
   427     showSeparatingLines := aBoolean.
   519     showSeparatingLines := aBoolean.
   428     shown ifTrue:[
   520     shown ifTrue:[
       
   521 	self setMenuOrigins.
   429 	self redraw
   522 	self redraw
       
   523     ]
       
   524 !
       
   525 
       
   526 font:aFont
       
   527     "set the menus font.
       
   528      adjusts menu-origins when font changes.
       
   529      You should not use this method; instead leave the value as
       
   530      defined in the StyleSheet."
       
   531 
       
   532     aFont ~~ font ifTrue:[
       
   533 	super font:(aFont on:device).
       
   534 	self height:(font height + (font descent * 2)).
       
   535 	shown ifTrue:[
       
   536 	    self setMenuOrigins
       
   537 	]
       
   538     ]
       
   539 !
       
   540 
       
   541 foregroundColor:aColor
       
   542     "set the foreground drawing color.
       
   543      You should not use this method; instead leave the value as
       
   544      defined in the StyleSheet."
       
   545 
       
   546     fgColor := aColor on:device
       
   547 !
       
   548 
       
   549 backgroundColor:aColor
       
   550     "set the background drawing color.
       
   551      You should not use this method; instead leave the value as
       
   552      defined in the StyleSheet."
       
   553 
       
   554     bgColor := aColor on:device
       
   555 ! !
       
   556 
       
   557 
       
   558 !PullDownMenu methodsFor:'accessing'!
       
   559 
       
   560 receiver:anObject 
       
   561     "set the menu-receiver. Thats the one who gets the
       
   562      messages (both from myself and from my submenus).
       
   563      This only sets the receiver for menus which are already
       
   564      created - menus added later should get their receiver in
       
   565      the creation send."
       
   566 
       
   567     receiver := anObject.
       
   568     menus notNil ifTrue:[
       
   569 	menus do:[:aMenu |
       
   570 	    aMenu receiver:anObject
       
   571 	]
   430     ]
   572     ]
   431 !
   573 !
   432 
   574 
   433 numberOfTitles:n
   575 numberOfTitles:n
   434     "setup blank title-space to be filled in later"
   576     "setup blank title-space to be filled in later"
   472     "define the menu-selectors. These are used as accesskey only
   614     "define the menu-selectors. These are used as accesskey only
   473      in menuAt: accesses. This makes PullDownMenu accesss
   615      in menuAt: accesses. This makes PullDownMenu accesss
   474      somewhat more compatible to PopUpMenus."
   616      somewhat more compatible to PopUpMenus."
   475 
   617 
   476     selectors := selectorArray.
   618     selectors := selectorArray.
   477 !
       
   478 
       
   479 font:aFont
       
   480     "adjust menu-origins when font changes"
       
   481 
       
   482     super font:(aFont on:device).
       
   483     self height:(font height + (font descent * 2)).
       
   484     shown ifTrue:[
       
   485 	self setMenuOrigins
       
   486     ]
       
   487 !
       
   488 
       
   489 foregroundColor:aColor
       
   490     fgColor := aColor on:device
       
   491 !
       
   492 
       
   493 backgroundColor:aColor
       
   494     bgColor := aColor on:device
       
   495 !
   619 !
   496 
   620 
   497 menuAt:string
   621 menuAt:string
   498     "return the menu with the title; return nil if not found"
   622     "return the menu with the title; return nil if not found"
   499 
   623 
   664 
   788 
   665 hideActiveMenuRelease:aBoolean
   789 hideActiveMenuRelease:aBoolean
   666     "hide currently active menu - release grab if aBoolean is true
   790     "hide currently active menu - release grab if aBoolean is true
   667      and a grab was set (keepMenu)"
   791      and a grab was set (keepMenu)"
   668 
   792 
       
   793     |m|
       
   794 
   669     activeMenuNumber notNil ifTrue:[
   795     activeMenuNumber notNil ifTrue:[
   670 	(menus at:activeMenuNumber) unrealize.
   796 	(m := menus at:activeMenuNumber) notNil ifTrue:[
       
   797 	    m unrealize.
       
   798 	].
   671 	self unHighlightActiveTitle.
   799 	self unHighlightActiveTitle.
   672 	activeMenuNumber := nil
   800 	activeMenuNumber := nil
   673     ].
   801     ].
   674     aBoolean ifTrue:[
   802     aBoolean ifTrue:[
   675 	device ungrabPointer. 
   803 	device ungrabPointer. 
   687     "activate a menu, return it or nil"
   815     "activate a menu, return it or nil"
   688 
   816 
   689     |subMenu|
   817     |subMenu|
   690 
   818 
   691     activeMenuNumber notNil ifTrue:[self hideActiveMenuRelease:false].
   819     activeMenuNumber notNil ifTrue:[self hideActiveMenuRelease:false].
       
   820     activeMenuNumber := aNumber.
   692     subMenu := menus at:aNumber.
   821     subMenu := menus at:aNumber.
       
   822 
       
   823     (activeMenuNumber notNil 
       
   824     and:[
       
   825 	 subMenu notNil
       
   826 	 or:[(selectors at:activeMenuNumber) notNil]]) ifTrue:[
       
   827 	    self highlightActiveTitle.
       
   828 	 ].
       
   829 
   693     subMenu notNil ifTrue:[
   830     subMenu notNil ifTrue:[
   694 	activeMenuNumber := aNumber.
       
   695 	self highlightActiveTitle.
       
   696 	subMenu deselect.
   831 	subMenu deselect.
   697 	subMenu create.
   832 	subMenu create.
   698 	subMenu saveUnder:true.
   833 	subMenu saveUnder:true.
   699 	subMenu superMenu:self.
   834 	subMenu superMenu:self.
   700 	subMenu raise show
   835 	subMenu raise show
   710 ! !
   845 ! !
   711 
   846 
   712 !PullDownMenu methodsFor:'drawing '!
   847 !PullDownMenu methodsFor:'drawing '!
   713 
   848 
   714 redraw
   849 redraw
   715     |string
   850     |x     "{ Class: SmallInteger }"
   716      x     "{ Class: SmallInteger }"
       
   717      y     "{ Class: SmallInteger }"
   851      y     "{ Class: SmallInteger }"
   718      index "{ Class: SmallInteger }" 
   852      index "{ Class: SmallInteger }" 
   719      wSpace|
   853      wSpace|
   720 
   854 
   721     shown ifFalse: [ ^ self ].
   855     shown ifFalse: [ ^ self ].
   807 ! !
   941 ! !
   808 
   942 
   809 !PullDownMenu methodsFor:'submenu notifications'!
   943 !PullDownMenu methodsFor:'submenu notifications'!
   810 
   944 
   811 showActive
   945 showActive
   812     "sent by a submenu to tell me that it started to perform
   946     "sent by a menu to tell me that it starts to perform
   813      its menu action"
   947      its menu action."
   814 !
   948 !
   815 
   949 
   816 showPassive
   950 showPassive
   817     "sent by a submenu to tell me that it finished its menu-action."
   951     "sent by a menu to tell me that it finished its menu-action.
       
   952      Here, we hide the currently active menu."
   818 
   953 
   819     self hideActiveMenu
   954     self hideActiveMenu
   820 !
   955 !
   821 
   956 
   822 submenuTriggered 
   957 submenuTriggered 
   825     self showPassive
   960     self showPassive
   826 ! !
   961 ! !
   827 
   962 
   828 !PullDownMenu methodsFor:'event handling'!
   963 !PullDownMenu methodsFor:'event handling'!
   829 
   964 
       
   965 showNoFocus
       
   966     "when stepping focus, hide any active menu"
       
   967 
       
   968     self hideActiveMenu.
       
   969     super showNoFocus
       
   970 !
       
   971 
   830 keyPress:key x:x y:y
   972 keyPress:key x:x y:y
   831     |index m|
   973     |index m sel|
   832 
   974 
   833     "
   975     "
   834      handle CursorLeft/Right for non-mouse operation
   976      handle CursorLeft/Right for non-mouse operation
   835      (once it has the explicit focus)
   977      (once it has the explicit focus)
   836     "
   978     "
   846 	    index == 0 ifTrue:[index := menus size]
   988 	    index == 0 ifTrue:[index := menus size]
   847 	    ifFalse:[
   989 	    ifFalse:[
   848 		index > menus size ifTrue:[index := 1]
   990 		index > menus size ifTrue:[index := 1]
   849 	    ]
   991 	    ]
   850 	].
   992 	].
   851 	m := self pullMenu:index.
   993 	self pullMenu:index.
   852 	^ self
   994 	^ self
   853     ].
   995     ].
   854 
   996 
   855     activeMenuNumber isNil ifTrue:[^self].
   997     activeMenuNumber isNil ifTrue:[^self].
   856 
   998 
   857     "
   999     "
   858      pass it on to the active menu
  1000      pass it on to the active menu or perform the items action
   859     "
  1001     "
   860     m := menus at:activeMenuNumber.
  1002     m := menus at:activeMenuNumber.
   861     m keyPress:key x:0 y:0.
  1003     m isNil ifTrue:[
   862     ^ self
  1004 	key == #Return ifTrue:[
       
  1005 	    sel := selectors at:activeMenuNumber.
       
  1006 	    sel notNil ifTrue:[
       
  1007 		receiver perform:sel
       
  1008 	    ]
       
  1009 	].
       
  1010     ] ifFalse:[
       
  1011 	m keyPress:key x:0 y:0.
       
  1012     ].
   863 !
  1013 !
   864 
  1014 
   865 buttonPress:button x:x y:y
  1015 buttonPress:button x:x y:y
   866     |titleIndex activeMenu activeLeft activeTop m|
  1016     |titleIndex activeMenu activeLeft activeTop m|
   867 
  1017 
   921 	titleIndex := self titleIndexForX:x.
  1071 	titleIndex := self titleIndexForX:x.
   922 	titleIndex notNil ifTrue:[
  1072 	titleIndex notNil ifTrue:[
   923 	    (titleIndex ~~ activeMenuNumber) ifTrue:[
  1073 	    (titleIndex ~~ activeMenuNumber) ifTrue:[
   924 		self pullMenu:titleIndex
  1074 		self pullMenu:titleIndex
   925 	    ]
  1075 	    ]
       
  1076 	] ifFalse:[
       
  1077 	    self hideActiveMenu
   926 	]
  1078 	]
   927     ] ifFalse:[
  1079     ] ifFalse:[
   928 	"moving around below"
  1080 	"moving around below"
   929 	activeMenu isNil ifTrue:[^self].
  1081 	activeMenu isNil ifTrue:[^self].
   930 	activeLeft := activeMenu left.
  1082 	activeLeft := activeMenu left.
   942 	activeMenu selection:nil
  1094 	activeMenu selection:nil
   943     ]
  1095     ]
   944 !
  1096 !
   945 
  1097 
   946 buttonRelease:button x:x y:y
  1098 buttonRelease:button x:x y:y
   947     |activeMenu activeLeft activeTop hideMenu|
  1099     |activeMenu activeLeft activeTop hideMenu sel|
       
  1100 
       
  1101     activeMenuNumber isNil ifTrue:[^self].
       
  1102     activeMenu := menus at:activeMenuNumber.
   948 
  1103 
   949     hideMenu := false.
  1104     hideMenu := false.
   950     (y >= height) ifTrue:[
  1105     (y >= height) ifTrue:[
   951 	"release below title-line"
  1106 	"release below title-line"
   952 	activeMenuNumber isNil ifTrue:[^self].
       
   953 	activeMenu := menus at:activeMenuNumber.
       
   954 	activeLeft := activeMenu left.
  1107 	activeLeft := activeMenu left.
   955 	"
  1108 	"
   956 	 released in a submenu ?
  1109 	 released in a submenu ?
   957 	"
  1110 	"
   958 	(x between:activeLeft and:(activeMenu right)) ifTrue:[
  1111 	(x between:activeLeft and:(activeMenu right)) ifTrue:[
   969 	hideMenu := true.
  1122 	hideMenu := true.
   970     ] ifFalse:[
  1123     ] ifFalse:[
   971 	y < 0 ifTrue:[
  1124 	y < 0 ifTrue:[
   972 	    hideMenu := true
  1125 	    hideMenu := true
   973 	] ifFalse:[
  1126 	] ifFalse:[
   974 	    keepMenu ifFalse:[   
  1127 	    activeMenu isNil ifTrue:[
   975 		hideMenu := true
  1128 		sel := selectors at:activeMenuNumber.
       
  1129 		sel notNil ifTrue:[
       
  1130 		    receiver perform:sel
       
  1131 		].
       
  1132 		hideMenu := true.
       
  1133 	    ] ifFalse:[
       
  1134 		keepMenu ifFalse:[   
       
  1135 		    hideMenu := true
       
  1136 		]
   976 	    ]
  1137 	    ]
   977 	]
  1138 	]
   978     ].                  
  1139     ].                  
   979     hideMenu ifTrue:[
  1140     hideMenu ifTrue:[
   980        self hideActiveMenu.
  1141        self hideActiveMenu.