Introduction
With CNS Menu, there are multiple ways you can position menus to be shown on a layout. You can have it show up under your mouse cursor, or you can specify specific coordinates on your layout. With the aid of FileMaker’s “GetLayoutObjectAttribute” function, you can actually attach a menu to a layout object like a button or field.
Download Example File
Test the Example
To test this example, click any of the five buttons. For the “Specific Coordinates”, “Minimum Width”, and “Alignment” buttons, try changing the options to see how the menu displayed in different ways or locations. You can also enter Layout mode, move any of the the bottom three buttons, and then view the menus in Browse mode to see the menus move with the buttons. This can save you development time in the future if you decide to later move the button to a different location on your layout.
How it Works
To understand how each button looks, take a look at the scripts in Manage Scripts/ScriptMaker. Note, the “Specific Coordinates”, “Object Location”, “Minimum Width”, and “Alignment” buttons scripts all build on the basic functionality of the Cursor button script.
###Cursor button The Cursor button is the simplest of the buttons in this example. Edit the “Show Menu - Cursor” script to see the single Set Field script step that is used in this script. Select the Set Field script step and click the Calculated result: “Specify” button in the bottom right corner. Now you will see the following calculation.
CNSMenu_DefineQuickMenu( “QuickMenuExample” ; Menu::Items ; “You chose…” ) & ¶ &
CNSMenu_ShowMenu ( “QuickMenuExample” )For the rest of the explanation, see the How it Works section of the Quick Menu example.
###Specific Coordinates button In Manage Scripts/ScriptMaker, edit the “Show Menu - Specific Coordinates” script. You will see a single Set Field script step, select it, and click the Calculated result: “Specify” button in the bottom right corner. Now you will see the following calculation.
CNSMenu_DefineQuickMenu( “MenuExample” ; Menu::Items ; “You chose…” ) & ¶ &
CNSMenu_ShowMenu( “MenuExample” ; Menu::Left ; Menu::Top )The only difference in this calculation and the one from the Cursor button is the “Menu::Left” and “Menu::Top” fields have been passed to the CNSMenu_ShowMenu function.
###Object Location button In Manage Scripts/ScriptMaker, edit the “Show Menu - Object Location” script. You will see a single Set Field script step, select it, and click the Calculated result: “Specify” button in the bottom right corner. Now you will see the following calculation.
Let( [
objleft = GetLayoutObjectAttribute( “View Menu Button” ; “left” ) ;
objbottom = GetLayoutObjectAttribute( “View Menu Button” ; “bottom” )
];
CNSMenu_DefineQuickMenu( “MenuExample” ; Menu::Items ; “You chose…” ) & ¶ &
CNSMenu_ShowMenu( “MenuExample” ; GetAsText( objleft ) & “!” ; GetAsText( objbottom ) & “!” )
)This calculation is using FileMaker’s GetLayoutObjectAttribute function to get the coordinates of the button which is this passed to the CNSMenu_ShowMenu function. In order for this to work, we must give the button an object name. To see how this is done, change to Layout mode by clicking FileMaker’s View menu and selecting “Layout Mode”. Next, make sure the Inspector/Object Info dialog is open by clicking FileMaker’s View menu and clicking “Inspector” or “Object Info” (depending on your version of FileMaker). Now, select the “Object Location” button, and then look at the Inspector/Object Info dialog. Notice the Name for this object is “View Menu Button”. Now looking back at the calculation:
Let( [
objleft = GetLayoutObjectAttribute( “View Menu Button” ; “left” ) ;
objbottom = GetLayoutObjectAttribute( “View Menu Button” ; “bottom” )
];
CNSMenu_DefineQuickMenu( “MenuExample” ; Menu::Items ; “You chose…” ) & ¶ &
CNSMenu_ShowMenu( “MenuExample” ; GetAsText( objleft ) & “!” ; GetAsText( objbottom ) & “!” )
)The same name “View Menu Button” is found in the GetLayoutObjectAttribute function. The two calls to the GetLayoutObjectAttribute function is getting the “left” and the “bottom” coordinate for the “View Menu Button” button and putting them in the “objleft” and “objbottom” variables.
We have already looked at what is happening with the CNSMenu_DefineQuickMenu function in the previous button explanations, so look at the CNSMenu_ShowMenu function:
CNSMenu_ShowMenu( “MenuExample” ; GetAsText( objleft ) & “!” ; GetAsText( objbottom ) & “!” )
Now the “objleft” and “objbottom” variables are passed to the plug-in as the coordinates where the menu should be displayed. The last thing to notice is the exclamation points that are being placed at the end of each of the coordinates. This tells the plug-in to display the menu using absolute coordinates instead of layout-based coordinates. See the CNSMenu_ShowMenu listing in the function reference for more information.
###Minimum Width button In Manage Scripts/ScriptMaker, edit the “Show Menu - Minimum Width” script. You will see a single Set Field script step, select it, and click the Calculated result: “Specify” button in the bottom right corner. Now you will see the following calculation.
Let( [
objleft = GetLayoutObjectAttribute( “MinWidth” ; “left” ) ;
objbottom = GetLayoutObjectAttribute( “MinWidth” ; “bottom” )
];
CNSMenu_DefineQuickMenu( “MenuExample” ; Menu::Items ; “You chose…” ) & ¶ &
CNSMenu_ShowMenu( “MenuExample” ; GetAsText( objleft ) & “!” ; GetAsText( objbottom ) & “!” ; “” ; Menu::MinWidth )
)The only difference in this calculation and the one from the Object Location button is the “Menu::MinWidth” field has been passed to the CNSMenu_ShowMenu function as the 5th parameter. The 5th parameter of the CNSMenu_ShowMenu function defines the minimum width, in pixels, the menu will always appear.
###Alignment button In Manage Scripts/ScriptMaker, edit the “Show Menu - Alignment” script. You will see a single Set Field script step, select it, and click the Calculated result: “Specify” button in the bottom right corner. Now you will see the following calculation.
Let( [
objname = “Alignment”;
objleft = GetLayoutObjectAttribute( objname ; “left” ) ;
objright = GetLayoutObjectAttribute( objname ; “right” ) ;
objbottom = GetLayoutObjectAttribute( objname ; “bottom” );
objwidth = GetLayoutObjectAttribute( objname ; “width” );
menuleft = Case( Menu::Align = “Left” ; objleft;
Menu::Align = “Right” ; objright;
Menu::Align = “Center” ; objleft + (objwidth/2)
) ];
CNSMenu_DefineQuickMenu( “MenuExample” ; Menu::Items ; “You chose…” ) & ¶ &
CNSMenu_ShowMenu( “MenuExample” ; GetAsText( menuleft ) & “!” ; GetAsText( objbottom ) & “!” ; Menu::Align )
)Like the “Minimum Width” button, this calculation builds on what the “Object Location” button is doing. Notice this calculation uses GetLayoutObjectAttribute to also get the right coordinate of the button and the width of the button. The menuleft variable is then calculated to get the correct coordinate based on which alignment is defined in the “Menu::Align” field.