home *** CD-ROM | disk | FTP | other *** search
/ CLIX - Fazer Clix Custa Nix / CLIX-CD.cdr / mac / lib / Mac / Menus.pm < prev    next >
Text File  |  1998-04-05  |  8KB  |  405 lines

  1.  
  2. =head1 NAME
  3.  
  4. Mac::Menus - Macintosh Toolbox Interface to Menu Manager
  5.  
  6. =head1 SYNOPSIS
  7.  
  8.  
  9. =head1 DESCRIPTION
  10.  
  11. Access to Inside Macintosh is essential for proper use of these functions.
  12. Explanations of terms, processes and procedures are provided there.
  13. Any attempt to use these functions without guidance can cause severe errors in 
  14. your machine, including corruption of data. B<You have been warned.>
  15.  
  16. =cut
  17.  
  18. use strict;
  19.  
  20. package Mac::Menus;
  21.  
  22. BEGIN {
  23.     use Exporter    ();
  24.     use DynaLoader  ();
  25.     use Mac::Events ();
  26.     
  27.     use vars qw(@ISA @EXPORT @EXPORT_OK %Menu);
  28.     
  29.     @ISA = qw(Exporter DynaLoader);
  30.     @EXPORT = qw(
  31.         GetMBarHeight
  32.         NewMenu
  33.         GetMenu
  34.         DisposeMenu
  35.         AppendMenu
  36.         AppendResMenu
  37.         InsertResMenu
  38.         InsertMenu
  39.         DrawMenuBar
  40.         InvalMenuBar
  41.         DeleteMenu
  42.         ClearMenuBar
  43.         GetNewMBar
  44.         GetMenuBar
  45.         SetMenuBar
  46.         InsertMenuItem
  47.         DeleteMenuItem
  48.         HiliteMenu
  49.         SetMenuItemText
  50.         GetMenuItemText
  51.         DisableItem
  52.         EnableItem
  53.         CheckItem
  54.         SetItemMark
  55.         GetItemMark
  56.         SetItemIcon
  57.         GetItemIcon
  58.         SetItemStyle
  59.         GetItemStyle
  60.         CalcMenuSize
  61.         CountMItems
  62.         GetMenuHandle
  63.         FlashMenuBar
  64.         SetMenuFlash
  65.         GetItemCmd
  66.         SetItemCmd
  67.         PopUpMenuSelect
  68.         MenuChoice
  69.         InsertFontResMenu
  70.         InsertIntlResMenu
  71.         
  72.         noMark
  73.         textMenuProc
  74.         hMenuCmd
  75.         hierMenu
  76.     );
  77.     
  78.     @EXPORT_OK = qw(
  79.         %Menu
  80.     );
  81. }
  82. #
  83. # _HandleMenu handles a menu selection
  84. #
  85. sub _HandleMenu {
  86.     my($menuid, $item) = @_;
  87.     my($handler);
  88.     if ($handler = $Menu{sprintf("%04X", $menuid)}) {
  89.         $handler->handle($menuid, $item);
  90.     } elsif ($handler = $Menu{sprintf("%04X%04X", $menuid, $item)}) {
  91.         &$handler($menuid, $item);
  92.     }
  93. }
  94.  
  95. #
  96. # _PrepareMenus prepares all menus before a MenuSelect or MenuKey
  97. #
  98. sub _PrepareMenus {
  99.     for my $menu (keys %Menu) {
  100.         $Menu{$menu}->prepare if length($menu) == 4;
  101.     }
  102. }
  103.  
  104. my %MDEF;
  105.  
  106. #
  107. # _MenuDefProc calls a custom MDEF
  108. #
  109. sub _MenuDefProc {
  110.     my($item, $menu) = @_;
  111.     my $mdef = $MDEF{$menu};
  112.     
  113.     &$mdef(@_) unless !defined $mdef;
  114. }
  115.  
  116. package MenuHandle;
  117.  
  118. sub menuProc {
  119.     my($menu, $proc) = @_;
  120.     
  121.     if (defined($proc)) {
  122.         Mac::Menus::_SetMDEFProc($menu);
  123.         $MDEF{$menu} = $proc;
  124.     } else {
  125.         $MDEF{$menu};
  126.     }
  127. }
  128.  
  129. package Mac::Menus;
  130.  
  131. bootstrap Mac::Menus;
  132.  
  133. =head2 Constants
  134.  
  135. =over 4
  136.  
  137. =item noMark
  138.  
  139. Don't mark this menu item.
  140.  
  141. =item textMenuProc
  142.  
  143. The standard menu definition procedure ID.
  144.  
  145. =item hierMenu
  146.  
  147. Insert as a hierarchical menu.
  148.  
  149. =back
  150.  
  151. =cut
  152. sub noMark ()                      {          0; }
  153. sub textMenuProc ()                {          0; }
  154. sub hMenuCmd ()                    {    chr(27); }
  155. sub hierMenu ()                    {         -1; }
  156.  
  157. =include Menus.xs
  158.  
  159. =item PopUpMenuSelect MENU, TOP, LEFT, POPITEM;
  160.  
  161. =cut
  162. sub PopUpMenuSelect {
  163.     &_HandleMenu(&_PopUpMenuSelect);
  164. }
  165.  
  166. =item MenuChoice()
  167.  
  168. =cut
  169. sub MenuChoice {
  170.     &_HandleMenu(&_MenuChoice);
  171. }
  172.  
  173. sub DisposeMenu {
  174.     my($menu) = @_;
  175.     delete $MDEF{$menu};
  176.     _DisposeMenu($menu);
  177. }
  178.  
  179. =back
  180.  
  181. =cut
  182.  
  183. =head2 MacMenu - The Object Interface
  184.  
  185. The C<MacMenu> class provides a convenient way of handling menus.
  186.  
  187. =over 4
  188.  
  189. =cut
  190.  
  191. package MacMenu;
  192.  
  193. BEGIN {
  194.     use Carp;
  195.     use Mac::Hooks ();
  196.     import Mac::Menus;
  197.     import Mac::Menus qw(%Menu);
  198.  
  199.     use vars qw(@ISA);
  200.     
  201.     @ISA = qw(Mac::Hooks);
  202. }
  203.  
  204. =item new MacMenu ID, TITLE [, HANDLER] [, ITEMS]
  205.  
  206. =item new MacMenu MENU [, HANDLER] [, ITEMS]
  207.  
  208. Create a new C<MacMenu> and optionally install a default handler and items.
  209.  
  210. =cut
  211. sub new {
  212.     my($class, $id) = @_;
  213.     
  214.     if (ref($id) eq "MenuHandle") { # Existing menu
  215.         my($class, $menu, $handler) = @_;
  216.         splice(@_, 0, 3);
  217.         if (ref($handler) eq "ARRAY") {
  218.             unshift @_, $handler;
  219.             $handler = "";
  220.         }
  221.         my($ident) = sprintf("%04X", $id = $menu->menuID);
  222.         my(%my) = 
  223.             (   id      => $id, 
  224.                 ident   => $ident,
  225.                 inserted=> 0,
  226.                 menu    => $menu, 
  227.                 items   => [$handler]
  228.             );
  229.         my($me) = bless \%my, $class;
  230.         $Menu{$ident} = $me;
  231.         for (@_) {
  232.             push @{$me->{items}}, ${$_}[0];
  233.         }
  234.         $me;
  235.     } else {
  236.         my($class, $id, $title, $handler) = @_;
  237.         splice(@_, 0, 4);
  238.         if (ref($handler) eq "ARRAY") {
  239.             unshift @_, $handler;
  240.             $handler = "";
  241.         }
  242.         my($ident) = sprintf("%04X", $id);
  243.         my($menu) = NewMenu($id, $title) or croak "NewMenu failed";
  244.         my(%my) = 
  245.             (   id      => $id, 
  246.                 ident   => $ident,
  247.                 inserted=> 0,
  248.                 menu    => $menu, 
  249.                 items   => [$handler]
  250.             );
  251.         my($me) = bless \%my, $class;
  252.         $Menu{$ident} = $me;
  253.         for (@_) {
  254.             if (scalar(@{$_})) {
  255.                 $me->add_item(@{$_});
  256.             } else {
  257.                 $me->add_separator;
  258.             }
  259.         }
  260.         $me;
  261.     }
  262. }
  263.  
  264. =item dispose 
  265.  
  266. Unregisters and disposes the menu.
  267.  
  268. =cut
  269. sub dispose {
  270.     my($my) = @_;
  271.     return unless $my->{menu};
  272.     defined($_[0]->callhook("dispose", @_)) and return;
  273.     $my->delete;
  274.     delete $Mac::Menus::Menu{$my->{ident}};
  275.     DisposeMenu($my->{menu});
  276.     $my->{menu} = "";
  277. }
  278.  
  279. sub DESTROY {
  280.     my($my) = @_;
  281.     $my->dispose;
  282. }
  283.  
  284. =item handle MENUID, ITEM
  285.  
  286. Item handle an item selection.
  287.  
  288. =cut
  289. sub handle {
  290.     my($handled);
  291.     defined($handled = $_[0]->callhook("handle", @_)) and return $handled;
  292.     my($my,$menuid,$item) = @_;
  293.     my($handler) = $my->{items}[$item] || $my->{items}[0];
  294.     $handler or return 0;
  295.     &$handler($menuid, $item);
  296.     1;
  297. }
  298.  
  299. =item prepare 
  300.  
  301. Prepare menu before MenuSelect or MenuKey.
  302.  
  303. =cut
  304. sub prepare {
  305.     defined($_[0]->callhook("prepare", @_)) and return;
  306. }
  307.  
  308. =item insert [BEFORE] 
  309.  
  310. Insert menu in menubar.
  311.  
  312. =cut
  313. sub insert {
  314.     return if $_[0]->{inserted};
  315.     defined($_[0]->callhook("insert", @_)) and return;
  316.     my($my) = shift;
  317.     InsertMenu($my->{menu}, @_) ;
  318.     $my->{inserted} = 1;
  319.     InvalMenuBar();
  320. }
  321.  
  322. =item delete
  323.  
  324. Delete menu from menubar.
  325.  
  326. =cut
  327. sub delete {
  328.     return unless $_[0]->{inserted};
  329.     defined($_[0]->callhook("delete", @_)) and return;
  330.     my($my) = @_;
  331.     DeleteMenu($my->{id});
  332.     $my->{inserted} = 0;
  333.     InvalMenuBar();
  334. }
  335.  
  336. =item ITEM = add_item TEXT, HANDLER, [, KEY [, MARK [, ICON]]]
  337.  
  338. Add an item.
  339.  
  340. =cut
  341. sub add_item {
  342.     defined($_[0]->callhook("add_item", @_)) and return;
  343.     my($my, $text, $handler, $key, $mark, $icon) = @_;
  344.     my($item) = scalar(@{$my->{items}});
  345.     push @{$my->{items}}, $handler;
  346.     AppendMenu($my->{menu}, "-");
  347.     SetMenuItemText($my->{menu}, $item, $text);
  348.     SetItemCmd($my->{menu}, $item, $key)        if defined($key);
  349.     SetItemMark($my->{menu}, $item, $mark)      if defined($mark);
  350.     SetItemIcon($my->{menu}, $item, $icon)      if defined($icon);
  351.     $item;
  352. }
  353.  
  354. =item ITEM = add_separator
  355.  
  356. Add an separator line.
  357.  
  358. =cut
  359. sub add_separator {
  360.     defined($_[0]->callhook("add_separator", @_)) and return;
  361.     my($my) = @_;
  362.     my($item) = scalar(@{$my->{items}});
  363.     push @{$my->{items}}, "";
  364.     AppendMenu($my->{menu}, "-(");
  365.     $item;
  366. }
  367.  
  368. =head2 MacHierMenu - The Object Interface to hierarchical menus.
  369.  
  370. The C<MacHierMenu> class provides a convenient way of handling hierarchical menus.
  371. everything works identically to C<MacMenu>, except that C<insert> always inserts
  372. hierachically.
  373.  
  374. =over 4
  375.  
  376. =cut
  377. package MacHierMenu;
  378.  
  379. BEGIN {
  380.     import Mac::Menus;
  381.  
  382.     use vars qw(@ISA);
  383.     
  384.     @ISA = qw(MacMenu);
  385. }
  386.  
  387. sub insert {
  388.     my($my) = @_;
  389.     MacMenu::insert($my, &hierMenu);
  390. }
  391.  
  392. =head1 BUGS/LIMITATIONS
  393.  
  394. =head1 FILES
  395.  
  396. =head1 AUTHOR(S)
  397.  
  398. Matthias Ulrich Neeracher <neeri@iis.ee.ethz.ch> 
  399.  
  400. =cut
  401.  
  402. 1;
  403.  
  404. __END__
  405.