|
Class: PullDownMenu
Object
|
+--GraphicsMedium
|
+--DisplaySurface
|
+--SimpleView
|
+--View
|
+--PullDownMenu
- Package:
- stx:libwidg
- Category:
- Views-Menus
- Version:
- rev:
1.123
date: 2024/01/16 19:26:43
- user: cg
- file: PullDownMenu.st directory: libwidg
- module: stx stc-classLibrary: libwidg
Notice: this class is obsolete now
- please use a MenuPanel in new applications,
which provides all of this functionality, plus more and a nicer look.
PullDown menu provides the top (always visible) part of these menus.
It controls display of its menus, which become visible when one of the
PullDownMenus entries is pressed.
A PullDownMenu itself consists of a single row of labels, which activate
a pulled menu when clicked. Entries may be empty (i.e. have no menu)
and empty entries may (optionally) also perform some action when clicked.
An entries selector is used as the key to define and access submenus
and (for empty entries:) the selector sent to the receiver of the menu.
[Instance variables:]
menus <Collection> the sub menus
titles <Collection> the strings in the menu
selectors <Collection> the selectors to send to the menu-
receiver (for empty pull-menus)
if nil (the default), title entries
do not send anything.
activeMenuNumber <Number> the index of the currently active menu
showSeparatingLines <Boolean> show separating lines between my menu-strings
topMargin <Number> number of pixels at top
fgColor <Color> fg color to draw passive menu-titles
bgColor <Color> bg color to draw passive menu-titles
activeFgColor <Color> fg color to draw activated menu-titles
activeBgColor <Color> bg color to draw activated menu-titles
onLevel <Integer> 3D level of entry-buttons when pressed
offLevel <Integer> 3D level of entry-buttons when released
edgeStyle <Symbol> how to draw edges
toggleMode <Symbol> if #toggle, press pulls menu,
another press hides it.
if other, its hidden on release.
except menus, titles and selectors, instvars are usually defined from
defaults in the styleSheet; you should not care for them.
[StyleSheet values:]
pullDownMenuViewBackground view background Color for the menu bar
default: menuViewBackground
pullDownMenuForegroundColor foreground drawing color for the menu bar
default: menuForegroundColor
pullDownMenuBackgroundColor background drawing color for the menu bar
default: menuBackgroundColor
pullDownMenuHilightForegroundColor active foreground drawing color for the menu bar
default: menuHilightForegroundColor
pullDownMenuHilightBackgroundColor active background drawing color for the menu bar
default: menuHilightBackgroundColor
pullDownMenuHilightLevel level (3D only) when active
default: menuHilightLevel
pullDownMenuEdgeStyle edge style (nil or #soft)
pullDownMenuKeepMenu if true, pulled menu stays open until button
is pressed again outside of the item-area (motif behavior)
if false, menu closes on release (default)
pullDownMenuToggleKeep if true, pulled menu closes when an entry is pressed
again. Otherwise, only press outside of the items area
hides it. default is false
pullDownMenuLevel level (3D only)
pullDownMenuFont font to use for the menu bar
default: menuFont
pullDownMenuShowSeparatingLines if true, lines are drawn between items.
default: false
pullDownMenuRaiseTop if true, topview is raised whenever an entry
is activated.
default: true
copyrightCOPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
defaults
-
updateStyleCache
-
extract values from the styleSheet and cache them in class variables
Usage example(s):
PullDownMenu updateStyleCache
|
instance creation
-
labels: titleArray
-
create and return a new PullDownMenu
accessing
-
add: label selector: selector
-
add a new title-item at the end.
The corresponding label can later be set with #at:putMenu:
or #at:putLabels:selectors:...
-
add: label selector: selector after: indexOrString
-
add a new title-item after an existing item, indexOrString,
or at the end if the after-arg is nil.
The corresponding label can later be set with #at:putMenu:
or #at:putLabels:selectors:...
Usage example(s):
|top m|
top := StandardSystemView new.
m := PullDownMenu in:top.
m labels:#('file' 'edit').
m selectors:#(file #edit).
m add:'help' selector:#help after:#file.
m at:#help putMenu:(MenuView labels:#('foo' 'bar')
selectors:#(foo bar)
receiver:nil).
top open
|
-
add: label selector: selector before: indexOrString
-
add a new title-item before an existing item, indexOrString,
or at the beginning if the before-arg is nil.
The corresponding label can later be set with #at:putMenu:
or #at:putLabels:selectors:...
Usage example(s):
|top m|
top := StandardSystemView new.
m := PullDownMenu in:top.
m labels:#('file' 'edit').
m selectors:#(file #edit).
m add:'help' selector:#help before:#edit.
m at:#help putMenu:(MenuView labels:#('foo' 'bar')
selectors:#(foo bar)
receiver:nil).
m add:'foo' selector:#foo before:nil.
m at:#foo putMenu:(MenuView labels:#('foo1' 'foo2')
selectors:#(foo1 foo2)
receiver:nil).
top open
|
-
at: aString putLabels: labels selector: selector args: args receiver: anObject
-
create and set the menu under the title, aString
OBSOLETE protocol: labels:selectors:args:receiver: knows how to handle a
single symbol-arg for selectors ...
-
at: aString putLabels: labels selectors: selectors
-
create and set the menu under the title, aString
-
at: aString putLabels: labels selectors: selectors accelerators: shorties args: args receiver: anObject
-
create and set the menu under the title, aString
-
at: aString putLabels: labels selectors: selectors accelerators: shorties receiver: anObject
-
create and set the menu under the title, aString
-
at: aString putLabels: labels selectors: selectors args: args receiver: anObject
-
create and set the menu under the title, aString
-
at: aString putLabels: labels selectors: selectors receiver: anObject
-
create and set the menu under the title, aString
-
at: aString putMenu: aMenu
-
set the menu under the title, aString
-
labels
-
return the menu-titles (group-headers)
-
labels: titleArray
-
define the menu-titles (group-headers)
-
labels: titleArray selectors: selectorArray
-
define the menu-titles (group-headers) and selectors.
Selectors are mostly used as access keys to get to submenus later.
-
menuAt: stringOrNumber
-
return the menu with the title; nil if not found
-
numberOfTitles: n
-
setup blank title-space to be filled in later
-
receiver: anObject
-
set the menu-receiver.
That's the one who gets the messages (both from myself and from my submenus).
This only sets the receiver for menus which are already
created - menus added later should get their receiver in
the creation send.
-
remove: indexOrString
-
remove the menu, indexOrString.
Usage example(s):
|top m|
top := StandardSystemView new extent:300@200.
m := PullDownMenu in:top.
m labels:#('file' 'edit').
m selectors:#(file #edit).
top open.
Delay waitForSeconds:3.
m add:'help' selector:#help after:#file.
m at:#help putMenu:(MenuView labels:#('foo' 'bar')
selectors:#(foo bar)
receiver:nil).
Delay waitForSeconds:3.
m remove:'help'
|
-
selectors
-
return the menu-selectors
-
selectors: selectorArray
-
define the menu-selectors. These are used as accesskey only
in menuAt: accesses. This makes PullDownMenu access
somewhat more compatible to PopUpMenus.
-
subMenuAt: stringOrNumber
-
return the menu with the title; nil if not found.
accessing-behavior
-
actionAt: stringOrNumber
-
return the actionBlock associated with stringOrNumber;
nil if there is none (but there may be still a selector there).
-
actionAt: stringOrNumber put: aBlock
-
return the actionBlock associated with stringOrNumber;
nil if there is none (but there may be still a selector there).
-
disable: anItem
-
-
enable: anItem
-
accessing-look
-
backgroundColor: aColor
-
set the background drawing color.
You should not use this method; instead leave the value as
defined in the styleSheet.
-
font: aFont
-
set the menus font.
adjusts menu-origins when font changes.
You should not use this method; instead leave the value as
defined in the styleSheet.
CAVEAT: with the addition of Text objects,
this method is going to be obsoleted by a textStyle
method, which allows specific control over
normalFont/boldFont/italicFont parameters.
-
foregroundColor: aColor
-
set the foreground drawing color.
You should not use this method; instead leave the value as
defined in the styleSheet.
-
showSeparatingLines: aBoolean
-
turn on/off drawing of separating lines.
You should not use this method; instead leave the value as
defined in the styleSheet.
converting
-
asMenu
-
-
asMenu: aView
-
drawing
-
drawActiveTitleSelected: selected
-
-
drawTitle: stringOrImage x: x0 selected: selected
-
+ topMargin
-
highlightActiveTitle
-
-
redraw
-
}
-
unHighlightActiveTitle
-
event handling
-
buttonMotion: state x: x y: y
-
self hideActiveMenu.
-
buttonPress: button x: x y: y
-
now, titleIndex is non-nil if pressed within myself
-
buttonRelease: button x: x y: y
-
release below title-line
-
keyPress: key x: x y: y
-
handle CursorLeft/Right for non-mouse operation
(for example, if it has the explicit focus)
These will pull the previous/next menu
-
showNoFocus: explicit
-
when stepping focus, hide any active menu
hiding/showing menus
-
cancelDelayedSubmenuHideOrShowAction
-
-
hide
-
sent by an aborted menu
-
hideActiveMenu
-
hide currently active menu - release grab if there is any grab
-
hideActiveMenuRelease: aBoolean
-
hide currently active menu - release grab if aBoolean is true
and a grab was set
-
pullMenu: aNumber
-
activate a menu, return it or nil
-
regainControl
-
self cursor:Cursor upRightArrow
initialization & release
-
container: aView
-
when my container changes, all of my menus must change as well
-
create
-
(comment from inherited method)
create (i.e. tell my device about me) if not already created.
This does not make the view visible (needs a #map for that)
-
destroy
-
have to destroy the menus manually here,
since they are no real subviews of myself
-
fetchDeviceResources
-
fetch device colors, to avoid reallocation at redraw time
-
initCursor
-
set up a hand cursor
-
initStyle
-
initialize style specifics
-
initialize
-
(comment from inherited method)
must be called if redefined
-
recreate
-
sent after a snapin or a migration;
if the image was saved with an active menu, hide it
private
-
indexOf: stringOrNumber
-
return the index of the menu with title; return 0 if not found.
stringOrNumber may be a number, a selector from the selectorArray
or a string from the title array.
If stringOrNumber is not a valid item, return 0.
-
performEntry: itemIndex
-
-
performSelectedAction
-
-
setMenuOrigins
-
adjust origins of menus when font changes
-
titleIndexForX: x
-
given a click x-position, return index in title or nil
-
titleLenUpTo: index
-
answer len (in pixels) of all title-strings up-to
(but excluding) title-index. Used to compute x-position when drawing
individual entries.
queries
-
computePreferredExtent
-
return my preferredExtent from the title-item widths & font height
-
specClass
-
returns my spec class (for UI editor)
Usage example(s):
redefined, since the name of my specClass is nonStandard (i.e. not PullDownMenuSpec)
|
submenu notifications
-
hideSubmenu
-
sent by an escaped menu - ignored here
-
showActive
-
sent by a menu to tell me that it starts to perform
its menu action.
-
showPassive
-
sent by a menu to tell me that it finished its menu-action.
Here, we hide the currently active menu.
-
submenuTriggered
-
sent by a sub-submenu to tell me that it finished its menu-action.
with default level (from styleSheets 'pullDownMenuLevel' setting):
|top menu|
top := StandardSystemView new.
top extent:300@300.
menu := PullDownMenu origin:0.0@0.0 corner:1.0@30 in:top.
menu labels:#('foo' 'bar').
menu selectors:#(foo bar).
menu at:#foo
putLabels:#('foo1' 'foo2' 'foo3')
selectors:#(foo1 foo2 foo3)
receiver:nil.
menu at:#bar
putLabels:#('bar1' 'bar2' 'bar3')
selectors:#(bar1 bar2 bar3)
receiver:nil.
top open
|
with a defined level:
|top menu|
top := StandardSystemView new.
top extent:300@300.
menu := PullDownMenu origin:0.0@0.0 corner:1.0@30 in:top.
menu level:1.
menu labels:#('foo' 'bar').
menu selectors:#(foo bar).
menu at:#foo
putLabels:#('foo1' 'foo2' 'foo3')
selectors:#(foo1 foo2 foo3)
receiver:nil.
menu at:#bar
putLabels:#('bar1' 'bar2' 'bar3')
selectors:#(bar1 bar2 bar3)
receiver:nil.
top open
|
empty entries are possible as selectable items (with non-nil seletor) ...
|top menu|
top := StandardSystemView new.
top extent:300@300.
menu := PullDownMenu origin:0.0@0.0 corner:1.0@30 in:top.
menu labels:#('foo' 'bar' 'baz').
menu selectors:#(foo bar baz).
menu at:#foo
putLabels:#('foo1' 'foo2' 'foo3')
selectors:#(foo1 foo2 foo3)
receiver:nil.
menu at:#baz
putLabels:#('baz1' 'baz2' 'baz3')
selectors:#(baz1 baz2 baz3)
receiver:nil.
top open
|
... or as separators (with nil selector)
|top menu|
top := StandardSystemView new.
top extent:500@200.
menu := PullDownMenu origin:0.0@0.0 corner:1.0@30 in:top.
menu labels:#('foo' ' ' 'bar' ' baz' ' ' 'moreFoo' 'moreBar' 'moreBaz').
menu selectors:#(foo nil bar baz nil moreFoo moreBar moreBaz).
menu at:#foo
putLabels:#('foo1' 'foo2' 'foo3')
selectors:#(foo1 foo2 foo3)
receiver:nil.
menu at:#bar
putLabels:#('bar1' 'bar2' 'bar3')
selectors:#(bar1 bar2 bar3)
receiver:nil.
menu at:#baz
putLabels:#('baz1' 'baz2' 'baz3')
selectors:#(baz1 baz2 baz3)
receiver:nil.
top open
|
use the menus default height
|top menu|
top := StandardSystemView new.
top extent:300@300.
menu := PullDownMenu in:top.
menu origin:0.0@0.0 corner:1.0@(menu height).
menu labels:#('foo' 'bar').
menu selectors:#(foo bar).
menu at:#foo
putLabels:#('foo1' 'foo2' 'foo3')
selectors:#(foo1 foo2 foo3)
receiver:nil.
top open
|
although you can change the font, colors etc. (as shown below)
you should NOT do it - since if you do so, the styleSheet settings
are ineffective (which users probably won't like)
BTW: The styleSheet entries for below are pullDownMenuForegroundColor,
pullDownMenuBackgroundColor and pullDownMenuFont
|top menu|
top := StandardSystemView new.
menu := PullDownMenu in:top.
menu font:(Font family:'courier' size:20).
menu foregroundColor:Color red.
menu backgroundColor:Color yellow.
menu viewBackground:Color green.
menu showSeparatingLines:true.
menu origin:0.0@0.0 corner:1.0@(menu height).
menu labels:#('foo' 'bar').
menu selectors:#(foo bar).
menu at:#foo
putLabels:#('foo1' 'foo2' 'foo3')
selectors:#(foo1 foo2 foo3)
receiver:nil.
(menu menuAt:#foo) font:(Font family:'courier' size:36).
top open
|
you can use icons, too ...
|labels top menu|
top := StandardSystemView new.
top extent:300@300.
menu := PullDownMenu in:top.
menu origin:0.0@0.0 corner:1.0@(menu height).
labels := Array with:((Image fromFile:'SmalltalkX.xbm') magnifiedTo:16@16)
with:'foo'
with:'bar'.
menu labels:labels.
menu selectors:#(about foo bar).
menu at:#about
putLabels:#('about PullDownMenus')
selectors:#(aboutMenus)
receiver:nil.
menu at:#foo
putLabels:#('foo1' 'foo2' 'foo3')
selectors:#(foo1 foo2 foo3)
receiver:nil.
top open
|
a concrete example (combining things described above)
(using a Plug, since we have no application class here):
|labels top menu textView appModel|
appModel := Plug new.
appModel respondTo:#quit with:[top destroy].
appModel respondTo:#showAbout with:[self information:'some info here ...'].
appModel respondTo:#help with:[self information:'some help here ...'].
top := StandardSystemView new.
top extent:300@300.
menu := PullDownMenu in:top.
menu receiver:appModel.
menu origin:0.0@0.0 corner:1.0@(menu height).
textView := ScrollableView forView:(EditTextView new).
textView origin:0.0@menu height corner:1.0@1.0.
top addSubView:textView.
labels := Array with:((Image fromFile:'SmalltalkX.xbm') magnifiedTo:16@16)
with:'file'
with:'edit'
with:'help'.
menu labels:labels.
menu selectors:#(about file edit help).
menu at:#about
putLabels:#('about PullDownMenus')
selectors:#(showAbout)
receiver:appModel.
menu at:#file
putLabels:#('quit')
selectors:#(quit)
receiver:appModel.
menu at:#edit
putLabels:#('copy' 'cut' 'paste')
selectors:#(copySelection cut paste)
receiver:textView.
top open
|
|