dunbarx wrote:

> "doMenu", a command, is replaced by sending "menuPick", a message,
> to a button, an object, renamed in this special case a "menu"?

Not necessarily. You can also use "button" to refer to the object. I believe the "menu" token was added mostly for HC compatibility, along with a few other things like "menuItem".

There's a subtle difference between "menu" and "button" when addressing menu buttons so they're not true synonyms, but in practice it seems "button" is more commonly used.


> Well, OK, it works alright, but why not a simple command, oh, like,
> um, "doMenu"? Instead we have a procedure.

As a general-purpose way of triggering menu items I also prefer HyperTalk's syntax to Transcript's, but the difference may be reflective of a very different philosophy of what the menu bar is all about, and why one would ever have a need to trigger a menu's script armed only with the item name and no knowledge of the scripts it calls: it becomes necessary when a menu is hard wired into the engine and has no script at all.


In HC the engine owned and controlled the menu bar, and allowed you to modify its contents to some degree but every time you booted HC it always started out with its own menus, requiring you to tear them down and rebuild them on the fly with scripts.

And even that only came later. If memory serves, HC 1.0 provided little if any control over the menu bar other than limiting choices by changing the userLevel.

HC started out by defining its world as one in which the engine provided the environment and your stacks were more or less documents within that environment, almost like web pages in a browser.

As it grew, and as SuperCard, Plus, and others came along and pushed the xTalk envelope in new directions, HC expanded its vision to think of stacks more like applications, allowing full modification of the menu bar and eventually even deploying standalone applications.

In contrast, tools like SC and MC/Rev were built from the start as systems for deploying standalone applications. As such, rather than providing a set of menus at runtime those engines have none at all, leaving the menu bar entirely up to the developer.

In a world where stacks are documents and the menu bar is provided by the engine, it makes sense to provide a way to trigger those commands. In fact, since HC menus had no scripts of their own, there was really no other way to do it but to send messages from outside the menu.

But in a world where the developer is responsible for the menu bar and everything in the menu bar has its own script, the approach used by SC and MC turns this around: rather than prodding menus from the outside, SC and MC work from the inside out, letting you call the shots from within the menu's own scripts.

Whether one way may seem better than another depends on a lot of things, not the least of which is one's own habits. :)

When I first signed on to the MetaCard list way back in the day I was a rantfest, screaming up one side and down the other about how "wrong" MC was in every way it differed from SC.

Over time I've come to appreciate the differences as largely borne of multi-platform considerations, as may also be at least a contributing factor with this:

> If the formal syntax for the invoking of menu commands was written
> down:
>
> send "menuPick" && "menuItem" to menu "menuName"
>
> then it would imply that Rev contains a native menu object, like HC.
> You can only send messages to objects, right?

HC did not have menu objects, at least not anything like its buttons and fields. HC menus had no scripts of their own, no true properties (though some clever syntax made menuItems almost feel like objects), and most of all no persistence: whatever you built in the menu bar during a session would disappear as soon as you quit, requiring that you rebuild it again from scratch on startup or openStack, often with rather long scripts.

SC is one of the very few xTalks that has true menu and menuItem objects.

Rev goes halfway between the two, implementing menus as buttons. This gives you the speed of being able to replace an entire menu's contents in one move as with HC, but also the persistence and discrete script space SC offers.

The rationale Scott Raney gave me for using the button class is that a menu is in the generic sense a selector control, and so the differences between a checkbox and an option menu are conceptually minor; indeed even HyperCard implemented option controls, a form of popup menu, as buttons.

Remember that MC was born on Unix, where menus are part of the window. While I appreciate why Apple has a detached menu bar and believe it's measurably more efficient to use, I have to admit it's just not how the other 90% live.

So in an environment where menus are a part of the window, and inspired by HC which has option menus as buttons, it's just a short skip to extend the button class to handle all of the menu types, even pulldowns.

Sure, Mac folks often find this confusing at first. I didn't much care for it myself when I first started working with MC. But the more time I spent working on Windows, Linux, Irix and Solaris (ah, the good ol' days) the more I began to kinda like the flexibility that comes with using buttons for other types of menus beyond option controls.



All that said, I appreciate that it can be useful to have something like DoMenu, so below is a replacement handler I wrote for you that may help.

Because we can't have custom handlers overriding built-in commands (a small price to pay for an order-of-magnitude speed bump by streamlining the token table), this handler is named "MenuDo", which could also be capitalized as "menudo" which is regarded in my neighborhood as a cure for hangovers; maybe it'll help take the edge off of the nausea and headaches that come with the unlearning process as well. :)

Along with MenuDo is a function named MenuItemsToText, which isn't very interesting but is needed by MenuDo.

Use MenuDo just like DoMenu:

  MenuDo "Open Stack..."

It's kinda tossed together, but should work for most menus.

Put these handlers in your library, and hopefully they'll make a reasonable substitute for DoMenu as you continue to learn the wu wei of Rev.

Happy scripting -

--
 Richard Gaskin
 Fourth World
 Revolution training and consulting: http://www.fourthworld.com
 Webzine for Rev developers: http://www.revjournal.com

-----------------------

--
-- Call this instead of "DoMenu", using the label of any
-- menu item as the param in pItem
--
on MenuDo pItem
  put the menubar of this stack into tMbar
  if tMbar is empty then put the defaultMenuBar into tMbar
  if tMBar is empty then return "No menu bar active"
  --
  put empty into tMenuString
  repeat with i = 1 to the number of btns of tMBar
    put the long id of btn i of tMBar into tMenuObj
    put MenuItemsToText(the text of tMenuObj) into tMenuItems
    --
    put lineoffset(cr& pItem &cr, cr&tMenuItems &cr) into tOS
    if tOS > 1 then
      put line tOS of tMenuItems into tMenuString
      exit repeat
    end if
    if tMenuString is not empty then exit repeat
  end repeat
  --
  send "menuPick "&tMenuString to tMenuObj
end MenuDo


--
-- This function takes the contents of a menu object
-- and removes the metacharacter stuff to arrive at
-- a string which is hopefully like the one which
-- you'd get as a param to menuPick.  It's called
-- by MenuDo to reformat menu object contents into
-- a form which can be used to send a menuPick
-- message.  Needs some work, but handles most
-- basic cases okay:
--
function MenuItemsToText pItems
  put "!r,!u,!c,!n" into tEntities
  repeat for each item tEntity in tEntities
    replace cr&tEntity with cr in pItems
    replace tab&tEntity with tab in pItems
    replace tEntity&tab with tab in pItems
  end repeat
  replace "&" with empty in pItems
  put empty into tList
  set the itemdel to "/"
  put empty into tLastSubMemu
  repeat for each line tLine in pItems
    put item 1 of tLine into tMenuItem
    if char 1 of tMenuItem = tab then
      put tLastSubMenu &"|" into char 1 of tMenuItem
    else
      put tMenuItem into tLastSubMenu
    end if
    put tMenuItem &cr after tList
  end repeat
  --
  if char 1 of last item of tMenuItem = "(" then
    delete char 1 of last item of tMenuItem
  end if
  --
  return tList
end MenuItemsToText

_______________________________________________
use-revolution mailing list
[email protected]
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-revolution

Reply via email to