github.com/secoba/wails/v2@v2.6.4/internal/frontend/desktop/darwin/WailsMenu.m (about)

     1  //go:build darwin
     2  //
     3  //  WailsMenu.m
     4  //  test
     5  //
     6  //  Created by Lea Anthony on 25/10/21.
     7  //
     8  
     9  #import <Foundation/Foundation.h>
    10  #import "WailsMenu.h"
    11  #import "WailsMenuItem.h"
    12  #import "Role.h"
    13  
    14  @implementation WailsMenu
    15  
    16  - (NSMenuItem*) newMenuItem :(NSString*)title :(SEL)selector :(NSString*)key :(NSEventModifierFlags)flags {
    17      NSMenuItem *result = [[[NSMenuItem alloc] initWithTitle:title action:selector keyEquivalent:key] autorelease];
    18      [result setKeyEquivalentModifierMask:flags];
    19      return result;
    20  }
    21  
    22  - (NSMenuItem*) newMenuItemWithContext :(WailsContext*)ctx :(NSString*)title :(SEL)selector :(NSString*)key :(NSEventModifierFlags)flags {
    23      NSMenuItem *result = [NSMenuItem new];
    24      if ( title != nil ) {
    25          [result setTitle:title];
    26      }
    27      if (selector != nil) {
    28          [result setAction:selector];
    29      }
    30      if (key) {
    31          [result setKeyEquivalent:key];
    32      }
    33      if( flags != 0 ) {
    34          [result setKeyEquivalentModifierMask:flags];
    35      }
    36      result.target = ctx;
    37      return result;
    38  }
    39  
    40  - (NSMenuItem*) newMenuItem :(NSString*)title :(SEL)selector :(NSString*)key  {
    41      return [self newMenuItem :title :selector :key :0];
    42  }
    43  
    44  - (WailsMenu*) initWithNSTitle:(NSString *)title {
    45      if( title != nil ) {
    46          [super initWithTitle:title];
    47      } else {
    48          [self init];
    49      }
    50      [self setAutoenablesItems:NO];
    51      return self;
    52  }
    53  
    54  - (void) appendSubmenu :(WailsMenu*)child {
    55      NSMenuItem *childMenuItem = [[NSMenuItem new] autorelease];
    56      [childMenuItem setTitle:child.title];
    57      [self addItem:childMenuItem];
    58      [childMenuItem setSubmenu:child];
    59  }
    60  
    61  - (void) appendRole :(WailsContext*)ctx :(Role)role {
    62  
    63      switch(role) {
    64          case AppMenu:
    65          {
    66              NSString *appName = [NSRunningApplication currentApplication].localizedName;
    67              if( appName == nil ) {
    68                  appName = [[NSProcessInfo processInfo] processName];
    69              }
    70              WailsMenu *appMenu = [[[WailsMenu new] initWithNSTitle:appName] autorelease];
    71              
    72              if (ctx.aboutTitle != nil) {
    73                  [appMenu addItem:[self newMenuItemWithContext :ctx :[@"About " stringByAppendingString:appName] :@selector(About) :nil :0]];
    74                  [appMenu addItem:[NSMenuItem separatorItem]];
    75              }
    76  
    77              [appMenu addItem:[self newMenuItem:[@"Hide " stringByAppendingString:appName] :@selector(hide:) :@"h" :NSEventModifierFlagCommand]];
    78              [appMenu addItem:[self newMenuItem:@"Hide Others" :@selector(hideOtherApplications:) :@"h" :(NSEventModifierFlagOption | NSEventModifierFlagCommand)]];
    79              [appMenu addItem:[self newMenuItem:@"Show All" :@selector(unhideAllApplications:) :@""]];
    80              [appMenu addItem:[NSMenuItem separatorItem]];
    81  
    82              id quitTitle = [@"Quit " stringByAppendingString:appName];
    83              NSMenuItem* quitMenuItem = [self newMenuItem:quitTitle :@selector(Quit) :@"q" :NSEventModifierFlagCommand];
    84              quitMenuItem.target = ctx;
    85              [appMenu addItem:quitMenuItem];
    86              [self appendSubmenu:appMenu];
    87              break;
    88          }
    89          case EditMenu:
    90          {
    91              WailsMenu *editMenu = [[[WailsMenu new] initWithNSTitle:@"Edit"] autorelease];
    92              [editMenu addItem:[self newMenuItem:@"Undo" :@selector(undo:) :@"z" :NSEventModifierFlagCommand]];
    93              [editMenu addItem:[self newMenuItem:@"Redo" :@selector(redo:) :@"z" :(NSEventModifierFlagShift | NSEventModifierFlagCommand)]];
    94              [editMenu addItem:[NSMenuItem separatorItem]];
    95              [editMenu addItem:[self newMenuItem:@"Cut" :@selector(cut:) :@"x" :NSEventModifierFlagCommand]];
    96              [editMenu addItem:[self newMenuItem:@"Copy" :@selector(copy:) :@"c" :NSEventModifierFlagCommand]];
    97              [editMenu addItem:[self newMenuItem:@"Paste" :@selector(paste:) :@"v" :NSEventModifierFlagCommand]];
    98              [editMenu addItem:[self newMenuItem:@"Paste and Match Style" :@selector(pasteAsRichText:) :@"v" :(NSEventModifierFlagOption | NSEventModifierFlagShift | NSEventModifierFlagCommand)]];
    99              [editMenu addItem:[self newMenuItem:@"Delete" :@selector(delete:) :[self accel:@"backspace"] :0]];
   100              [editMenu addItem:[self newMenuItem:@"Select All" :@selector(selectAll:) :@"a" :NSEventModifierFlagCommand]];
   101              [editMenu addItem:[NSMenuItem separatorItem]];
   102  //            NSMenuItem *speechMenuItem = [[NSMenuItem new] autorelease];
   103  //            [speechMenuItem setTitle:@"Speech"];
   104  //            [editMenu addItem:speechMenuItem];
   105              WailsMenu *speechMenu =  [[[WailsMenu new] initWithNSTitle:@"Speech"] autorelease];
   106              [speechMenu addItem:[self newMenuItem:@"Start Speaking" :@selector(startSpeaking:) :@""]];
   107              [speechMenu addItem:[self newMenuItem:@"Stop Speaking" :@selector(stopSpeaking:) :@""]];
   108              [editMenu appendSubmenu:speechMenu];
   109              [self appendSubmenu:editMenu];
   110              
   111              break;
   112          }
   113          case WindowMenu:
   114          {
   115              WailsMenu *windowMenu = [[[WailsMenu new] initWithNSTitle:@"Window"] autorelease];
   116              [windowMenu addItem:[self newMenuItem:@"Minimize" :@selector(performMiniaturize:) :@"m" :NSEventModifierFlagCommand]];
   117              [windowMenu addItem:[self newMenuItem:@"Zoom" :@selector(performZoom:) :@""]];
   118              [windowMenu addItem:[NSMenuItem separatorItem]];
   119              [windowMenu addItem:[self newMenuItem:@"Full Screen" :@selector(enterFullScreenMode:) :@"f" :(NSEventModifierFlagControl | NSEventModifierFlagCommand)]];
   120              [self appendSubmenu:windowMenu];
   121              
   122              break;
   123          }
   124      }
   125  }
   126  
   127  - (void*) AppendMenuItem :(WailsContext*)ctx :(NSString*)label :(NSString *)shortcutKey :(int)modifiers :(bool)disabled :(bool)checked :(int)menuItemID {
   128      
   129      NSString *nslabel = @"";
   130      if (label != nil ) {
   131          nslabel = label;
   132      }
   133      WailsMenuItem *menuItem = [WailsMenuItem new];
   134      
   135      // Label
   136      menuItem.title = nslabel;
   137      
   138      // Process callback
   139      menuItem.menuItemID = menuItemID;
   140      menuItem.action = @selector(handleClick);
   141      menuItem.target = menuItem;
   142      
   143      // Shortcut
   144      if (shortcutKey != nil) {
   145          [menuItem setKeyEquivalent:[self accel:shortcutKey]];
   146          [menuItem setKeyEquivalentModifierMask:modifiers];
   147      }
   148          
   149      // Enabled/Disabled
   150      [menuItem setEnabled:!disabled];
   151      
   152      // Checked
   153      [menuItem setState:(checked ? NSControlStateValueOn : NSControlStateValueOff)];  
   154      
   155      [self addItem:menuItem];
   156      return menuItem;
   157  }
   158  
   159  - (void) AppendSeparator {
   160      [self addItem:[NSMenuItem separatorItem]];
   161  }
   162  
   163  
   164  - (NSString*) accel :(NSString*)key {
   165  
   166      // Guard against no accelerator key
   167      if( key == NULL ) {
   168          return @"";
   169      }
   170  
   171      if( [key isEqualToString:@"backspace"] ) {
   172          return unicode(0x0008);
   173      }
   174      if( [key isEqualToString:@"tab"] ) {
   175          return unicode(0x0009);
   176      }
   177      if( [key isEqualToString:@"return"] ) {
   178          return unicode(0x000d);
   179      }
   180      if( [key isEqualToString:@"enter"] ) {
   181          return unicode(0x000d);
   182      }
   183      if( [key isEqualToString:@"escape"] ) {
   184          return unicode(0x001b);
   185      }
   186      if( [key isEqualToString:@"left"] ) {
   187          return unicode(0x001c);
   188      }
   189      if( [key isEqualToString:@"right"] ) {
   190          return unicode(0x001d);
   191      }
   192      if( [key isEqualToString:@"up"] ) {
   193          return unicode(0x001e);
   194      }
   195      if( [key isEqualToString:@"down"] ) {
   196          return unicode(0x001f);
   197      }
   198      if( [key isEqualToString:@"space"] ) {
   199          return unicode(0x0020);
   200      }
   201      if( [key isEqualToString:@"delete"] ) {
   202          return unicode(0x007f);
   203      }
   204      if( [key isEqualToString:@"home"] ) {
   205          return unicode(0x2196);
   206      }
   207      if( [key isEqualToString:@"end"] ) {
   208          return unicode(0x2198);
   209      }
   210      if( [key isEqualToString:@"page up"] ) {
   211          return unicode(0x21de);
   212      }
   213      if( [key isEqualToString:@"page down"] ) {
   214          return unicode(0x21df);
   215      }
   216      if( [key isEqualToString:@"f1"] ) {
   217          return unicode(0xf704);
   218      }
   219      if( [key isEqualToString:@"f2"] ) {
   220          return unicode(0xf705);
   221      }
   222      if( [key isEqualToString:@"f3"] ) {
   223          return unicode(0xf706);
   224      }
   225      if( [key isEqualToString:@"f4"] ) {
   226          return unicode(0xf707);
   227      }
   228      if( [key isEqualToString:@"f5"] ) {
   229          return unicode(0xf708);
   230      }
   231      if( [key isEqualToString:@"f6"] ) {
   232          return unicode(0xf709);
   233      }
   234      if( [key isEqualToString:@"f7"] ) {
   235          return unicode(0xf70a);
   236      }
   237      if( [key isEqualToString:@"f8"] ) {
   238          return unicode(0xf70b);
   239      }
   240      if( [key isEqualToString:@"f9"] ) {
   241          return unicode(0xf70c);
   242      }
   243      if( [key isEqualToString:@"f10"] ) {
   244          return unicode(0xf70d);
   245      }
   246      if( [key isEqualToString:@"f11"] ) {
   247          return unicode(0xf70e);
   248      }
   249      if( [key isEqualToString:@"f12"] ) {
   250          return unicode(0xf70f);
   251      }
   252      if( [key isEqualToString:@"f13"] ) {
   253          return unicode(0xf710);
   254      }
   255      if( [key isEqualToString:@"f14"] ) {
   256          return unicode(0xf711);
   257      }
   258      if( [key isEqualToString:@"f15"] ) {
   259          return unicode(0xf712);
   260      }
   261      if( [key isEqualToString:@"f16"] ) {
   262          return unicode(0xf713);
   263      }
   264      if( [key isEqualToString:@"f17"] ) {
   265          return unicode(0xf714);
   266      }
   267      if( [key isEqualToString:@"f18"] ) {
   268          return unicode(0xf715);
   269      }
   270      if( [key isEqualToString:@"f19"] ) {
   271          return unicode(0xf716);
   272      }
   273      if( [key isEqualToString:@"f20"] ) {
   274          return unicode(0xf717);
   275      }
   276      if( [key isEqualToString:@"f21"] ) {
   277          return unicode(0xf718);
   278      }
   279      if( [key isEqualToString:@"f22"] ) {
   280          return unicode(0xf719);
   281      }
   282      if( [key isEqualToString:@"f23"] ) {
   283          return unicode(0xf71a);
   284      }
   285      if( [key isEqualToString:@"f24"] ) {
   286          return unicode(0xf71b);
   287      }
   288      if( [key isEqualToString:@"f25"] ) {
   289          return unicode(0xf71c);
   290      }
   291      if( [key isEqualToString:@"f26"] ) {
   292          return unicode(0xf71d);
   293      }
   294      if( [key isEqualToString:@"f27"] ) {
   295          return unicode(0xf71e);
   296      }
   297      if( [key isEqualToString:@"f28"] ) {
   298          return unicode(0xf71f);
   299      }
   300      if( [key isEqualToString:@"f29"] ) {
   301          return unicode(0xf720);
   302      }
   303      if( [key isEqualToString:@"f30"] ) {
   304          return unicode(0xf721);
   305      }
   306      if( [key isEqualToString:@"f31"] ) {
   307          return unicode(0xf722);
   308      }
   309      if( [key isEqualToString:@"f32"] ) {
   310          return unicode(0xf723);
   311      }
   312      if( [key isEqualToString:@"f33"] ) {
   313          return unicode(0xf724);
   314      }
   315      if( [key isEqualToString:@"f34"] ) {
   316          return unicode(0xf725);
   317      }
   318      if( [key isEqualToString:@"f35"] ) {
   319          return unicode(0xf726);
   320      }
   321  //  if( [key isEqualToString:@"Insert"] ) {
   322  //    return unicode(0xf727);
   323  //  }
   324  //  if( [key isEqualToString:@"PrintScreen"] ) {
   325  //    return unicode(0xf72e);
   326  //  }
   327  //  if( [key isEqualToString:@"ScrollLock"] ) {
   328  //    return unicode(0xf72f);
   329  //  }
   330      if( [key isEqualToString:@"numLock"] ) {
   331          return unicode(0xf739);
   332      }
   333  
   334      return key;
   335  }
   336  
   337  
   338  @end
   339  
   340