Skip to content

Utility class to help in defining and operating NativeApplication menus (macOs) and NativeWindow menus (win) ia unified way.

License

Notifications You must be signed in to change notification settings

ciacob/global-menu-library

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Global Menu Library

The Global Menu Library is a versatile utility designed to streamline the creation and management of menus within Adobe AIR applications, offering a unified approach for both macOS (NativeApplication menus) and Windows (NativeWindow menus). This library abstracts the platform-specific differences, allowing developers to define menus in a consistent format across operating systems.

Features

  • Unified Menu Definition: Define menus using a JSON/Object structure that is consistent across macOS and Windows.
  • Dynamic Menu Updates: Easily enable/disable menu items and update labels on the fly, enhancing interactivity.
  • Event Handling: Dispatch custom events upon menu item selection for seamless integration with application logic.

Sample Client Code

import eu.claudiusiacob.desktop.GlobalMenu;
import eu.claudiusiacob.desktop.GlobalMenuEvent;

// Initialize GlobalMenu with JSON structure and application reference
var globalMenu:GlobalMenu = new GlobalMenu(jsonMenuStructure, NativeApplication.nativeApplication, "MyApp");

// Register main application window (Windows)
globalMenu.registerMainWindow(this.nativeWindow);

// Attach the menu to the application or window
globalMenu.attach();

// Listen for menu item selections
globalMenu.addEventListener(GlobalMenuEvent.ITEM_SELECT, function(event:GlobalMenuEvent):void {
trace("Menu item selected: " + event.cmdName);
});

To build the menu in its initial form, you must provide a JSON String (or equivalent Object) that resembles to the following:

{
  "menu":[
    {
      "label":"File",
      "children":[
        {
          "label":"New...",
          "cmdName":"cmd_new_project",
          "kbShortcuts": [
            "alt",
            "n"
          ]
        },
        {
          "isSeparator":true
        },
        {
          "label":"Save",
          "cmdName":"cmd_save_project",
          "kbShortcuts":{
            "win":[
              "ctrl",
              "s"
            ],
            "mac":[
              "cmd",
              "s"
            ]
          }
        },
        {
          "label":"Save to Cloud (PRO Feature)",
          "cmdName":"cmd_cloud_save_project",
          "disabled":"true"
        },
        {
          "isSeparator":true
        },        {
          "label":"About MyApp 123...",
          "cmdName":"cmd_about_app",
          "isHomeItem": true
        }
      ]
    },
    {
      "label":"View",
      "children":[
        {
          "label":"Theme",
          "children":[
            {
              "label":"Light",
              "cmdName":"cmd_set_theme_light",
              "isChecked":true
            },
            {
              "label":"Dark",
              "cmdName":"cmd_set_theme_dark",
              "isChecked":false
            }
          ]
        }
      ]
    }
  ]
}

Mind a couple of things:

  • There is no home menu defined in the JSON. That menu is dynamically built on macOS based on the provided applicationName constructor argument (see the Public API overview, next) and the isHomeItem tag. Essentially, all menu items that are tagged as isHomeItem in the JSON are collected and displayed underneath the home menu, while on macOS. On Windows, they remain underneath their original menu. If no item is marked as isHomeItem in the JSON, the home menu will be empty on macOS. If you don't provide the optional applicationName constructor argument, there will be no home menu (which might confuse Mac users, beware).

  • Only items having a cmdName set are actionable, i.e., you can do something in response to the user selecting them via mouse or the keyboard. If you want to receive a GlobalMenuEvent for a specific item in the menu, make sure you give that item a cmdName. The received event will make that accessible via its cmdName property.

  • There are two ways of defining keyboard shortcuts in the JSON:

    1. "kbShortcuts" : [ "modifier1", "modifierN", "key" ]
    2. "kbShortcuts" : { "win": [ "modifier1", "modifierN", "key" ], "mac": [ "modifier1", "modifierN", "key" ] }

    In the first case, the same shortcut is registered on both Windows and macOS; in the second, the win and mac keys determine what to register, based on the current operating system. Note that you need not use both win and mac: if you want to have items that only have keyboard shortcuts on one operating system, just leave out the other key.

    For modifier1 ... modifierN use one of ctrl, cmd and/or alt. The presence of the SHIFT key is implied by the casing of key, e.g., ["alt", "s"] means ALT+S, whereas ["alt", "S"] means SHIFT+ALT+S.

Notes:

  • Due to original Adobe design of the NativeMenuItem class, you can only use printable chars as the key part of a shortcut.
  • You can leave out the modifier1 ... modifierN part altogether, e.g.: "kbShortcuts" : [ "o" ] sets the key O by itself as the keyboard shortcut a menu item will use.

Public API Overview

  • GlobalMenu(structure, application, applicationName): Constructor to initialize the menu.
  • registerMainWindow(window): Registers the main application window, essential for menu attachment on Windows.
  • attach(): Attaches the menu to the application (macOS) or the main window (Windows).
  • setItemEnablement(cmdName, state): Dynamically sets the enablement state of a menu item.
  • setItemLabel(cmdName, label): Updates the label of a menu item.
  • __setItemChecked(cmdName, checked): Adds or removes a checkmark next to a menu item.
  • block: removes al interaction, so that using the mouse or keyboard to select a menu item will have no effect. If supported by the OS, also disables all the root-level menu items.
  • unblock: reverses the effect of block.

Please note that dynamic updates to menu items (setItemEnablement, setItemLabel) may not take effect if a submenu is currently displayed. Ensure submenus are closed before making such updates.

This library aims to simplify menu management in cross-platform AIR applications, providing a clear and efficient way to handle native menus with minimal platform-specific code.

About

Utility class to help in defining and operating NativeApplication menus (macOs) and NativeWindow menus (win) ia unified way.

Topics

Resources

License

Stars

Watchers

Forks