1/* 2 PPDocumentWindowController_MenuValidation.m 3 4 Copyright 2013-2018 Josh Freeman 5 http://www.twilightedge.com 6 7 This file is part of PikoPixel for Mac OS X and GNUstep. 8 PikoPixel is a graphical application for drawing & editing pixel-art images. 9 10 PikoPixel is free software: you can redistribute it and/or modify it under 11 the terms of the GNU Affero General Public License as published by the 12 Free Software Foundation, either version 3 of the License, or (at your 13 option) any later version approved for PikoPixel by its copyright holder (or 14 an authorized proxy). 15 16 PikoPixel is distributed in the hope that it will be useful, but WITHOUT ANY 17 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 18 FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more 19 details. 20 21 You should have received a copy of the GNU Affero General Public License 22 along with this program. If not, see <http://www.gnu.org/licenses/>. 23*/ 24 25#import "PPDocumentWindowController.h" 26 27#import "PPDocument.h" 28#import "PPCanvasView.h" 29#import "PPDocumentLayer.h" 30#import "PPPanelsController.h" 31 32 33static void SetupGlobals(void); 34static SEL SelectorFromDictForMenuActionName(NSDictionary *selectorDict, NSString *actionName); 35static NSDictionary *MenuItemValidationSelectorDict(void); 36static NSDictionary *MenuItemModificationSelectorDict(void); 37static bool MenuActionNameIsAllowedDuringMouseTracking(NSString *actionName); 38static bool MenuActionNameIsAllowedDuringPopupPanel(NSString *actionName); 39 40static bool gNeedToSetupGlobals = YES; 41static NSDictionary *gMenuItemModificationSelectorDict = nil; 42static NSDictionary *gMenuItemValidationSelectorDict = nil; 43static NSNumber *gNumber_YES = nil, *gNumber_NO = nil; 44 45 46@interface PPDocumentWindowController (MenuValidationPrivateMethods) 47 48- (NSNumber *) documentIsValid; 49- (NSNumber *) documentHasSelection; 50- (NSNumber *) documentHasSelectionAndDrawLayerIsEnabled; 51- (NSNumber *) documentHasSelectionAndEnabledTargetLayer; 52- (NSNumber *) documentHasSelectionOrEnabledTargetLayer; 53- (NSNumber *) documentHasMultipleLayers; 54- (NSNumber *) documentHasValidLayerAboveDrawingLayer; 55- (NSNumber *) documentHasValidLayerBelowDrawingLayer; 56- (NSNumber *) documentActiveLayerCanIncreaseOpacity; 57- (NSNumber *) documentActiveLayerCanDecreaseOpacity; 58- (NSNumber *) documentHasVisibleGrid; 59- (NSNumber *) documentHasBackgroundImage; 60- (NSNumber *) documentHasVisibleBackgroundImage; 61- (NSNumber *) documentHasActiveSamplerImageForPanel; 62- (NSNumber *) documentHasMultipleSamplerImagesAndSamplerPanelIsVisible; 63- (NSNumber *) documentCanReadFromPasteboard; 64- (NSNumber *) canvasViewCanZoomIn; 65- (NSNumber *) canvasViewCanZoomOut; 66 67- (void) modifyMenuItemForLayerEnabled: (NSMenuItem *) menuItem; 68- (void) modifyMenuItemForCanvasDisplayMode: (NSMenuItem *) menuItem; 69- (void) modifyMenuItemForLayerBlendingMode: (NSMenuItem *) menuItem; 70- (void) modifyMenuItemForGridVisibilityStatus: (NSMenuItem *) menuItem; 71- (void) modifyMenuItemForGridType: (NSMenuItem *) menuItem; 72- (void) modifyMenuItemForGridGuidelinesVisibilityStatus: (NSMenuItem *) menuItem; 73- (void) modifyMenuItemForBackgroundImageVisibilityStatus: (NSMenuItem *) menuItem; 74- (void) modifyMenuItemForBackgroundImageSmoothingStatus: (NSMenuItem *) menuItem; 75- (void) modifyMenuItemForLayerOperationTarget: (NSMenuItem *) menuItem; 76- (void) modifyMenuItemForToolsPanelVisibilityStatus: (NSMenuItem *) menuItem; 77- (void) modifyMenuItemForLayersPanelVisibilityStatus: (NSMenuItem *) menuItem; 78- (void) modifyMenuItemForPreviewPanelVisibilityStatus: (NSMenuItem *) menuItem; 79- (void) modifyMenuItemForSamplerImagePanelVisibilityStatus: (NSMenuItem *) menuItem; 80- (void) modifyMenuItemForToolModifierTipsPanelVisibilityStatus: (NSMenuItem *) menuItem; 81 82@end 83 84@interface NSMenuItem (PPUtilities_MenuValidationPrivateMethods) 85 86- (void) ppSetTitleModeNameSuffix: (NSString *) modeName; 87 88@end 89 90@implementation PPDocumentWindowController (MenuValidation) 91 92- (BOOL) validateMenuItem: (PPSDKNativeType_NSMenuItemPtr) menuItem 93{ 94 SEL menuItemAction, modificationSelector, validationSelector; 95 NSString *actionName; 96 97 if (gNeedToSetupGlobals) 98 { 99 SetupGlobals(); 100 } 101 102 if (!_documentWindowIsKey) 103 { 104 return NO; 105 } 106 107 menuItemAction = [menuItem action]; 108 109 if (!menuItemAction) 110 goto ERROR; 111 112 actionName = NSStringFromSelector(menuItemAction); 113 114 if (!actionName) 115 goto ERROR; 116 117 modificationSelector = 118 SelectorFromDictForMenuActionName(gMenuItemModificationSelectorDict, actionName); 119 120 if (modificationSelector) 121 { 122 [self performSelector: modificationSelector withObject: menuItem]; 123 } 124 125 if (_isTrackingMouseInCanvasView 126 && !MenuActionNameIsAllowedDuringMouseTracking(actionName)) 127 { 128 return NO; 129 } 130 131 if (_pressedHotkeyForActivePopupPanel 132 && !MenuActionNameIsAllowedDuringPopupPanel(actionName)) 133 { 134 return NO; 135 } 136 137 validationSelector = 138 SelectorFromDictForMenuActionName(gMenuItemValidationSelectorDict, actionName); 139 140 if (validationSelector) 141 { 142 return [[self performSelector: validationSelector] boolValue]; 143 } 144 145 return NO; 146 147ERROR: 148 return NO; 149} 150 151- (NSNumber *) documentIsValid 152{ 153 return ([_ppDocument numLayers]) ? gNumber_YES : gNumber_NO; 154} 155 156- (NSNumber *) documentHasSelection 157{ 158 return ([_ppDocument hasSelection]) ? gNumber_YES : gNumber_NO; 159} 160 161- (NSNumber *) documentHasSelectionAndDrawLayerIsEnabled 162{ 163 return ([_ppDocument hasSelection] && [[_ppDocument drawingLayer] isEnabled]) ? 164 gNumber_YES : gNumber_NO; 165} 166 167- (NSNumber *) documentHasSelectionAndEnabledTargetLayer 168{ 169 return ([_ppDocument hasSelection] && [_ppDocument layerOperationTargetHasEnabledLayer]) ? 170 gNumber_YES : gNumber_NO; 171} 172 173- (NSNumber *) documentHasSelectionOrEnabledTargetLayer 174{ 175 return ([_ppDocument hasSelection] || [_ppDocument layerOperationTargetHasEnabledLayer]) ? 176 gNumber_YES : gNumber_NO; 177} 178 179- (NSNumber *) documentHasMultipleLayers 180{ 181 return ([_ppDocument numLayers] > 1) ? gNumber_YES : gNumber_NO; 182} 183 184- (NSNumber *) documentHasValidLayerAboveDrawingLayer 185{ 186 return ([_ppDocument indexOfDrawingLayer] < ([_ppDocument numLayers] - 1)) ? 187 gNumber_YES : gNumber_NO; 188} 189 190- (NSNumber *) documentHasValidLayerBelowDrawingLayer 191{ 192 return ([_ppDocument indexOfDrawingLayer] > 0) ? gNumber_YES : gNumber_NO; 193} 194 195- (NSNumber *) documentActiveLayerCanIncreaseOpacity 196{ 197 return ([[_ppDocument drawingLayer] canIncreaseOpacity]) ? gNumber_YES : gNumber_NO; 198} 199 200- (NSNumber *) documentActiveLayerCanDecreaseOpacity 201{ 202 return ([[_ppDocument drawingLayer] canDecreaseOpacity]) ? gNumber_YES : gNumber_NO; 203} 204 205- (NSNumber *) documentHasVisibleGrid 206{ 207 return ([_ppDocument shouldDisplayGrid]) ? gNumber_YES : gNumber_NO; 208} 209 210- (NSNumber *) documentHasBackgroundImage 211{ 212 return ([_ppDocument backgroundImage]) ? gNumber_YES : gNumber_NO; 213} 214 215- (NSNumber *) documentHasVisibleBackgroundImage 216{ 217 return ([_ppDocument backgroundImage] && [_ppDocument shouldDisplayBackgroundImage]) ? 218 gNumber_YES : gNumber_NO; 219} 220 221- (NSNumber *) documentHasActiveSamplerImageForPanel 222{ 223 return ([_ppDocument hasActiveSamplerImageForPanelType: kPPSamplerImagePanelType_Panel]) ? 224 gNumber_YES : gNumber_NO; 225} 226 227- (NSNumber *) documentHasMultipleSamplerImagesAndSamplerPanelIsVisible 228{ 229 return (([_ppDocument numSamplerImages] > 1) 230 && [_panelsController panelOfTypeIsVisible: kPPPanelType_SamplerImage]) ? 231 gNumber_YES : gNumber_NO; 232} 233 234- (NSNumber *) documentCanReadFromPasteboard 235{ 236 return ([_ppDocument canReadFromPasteboard]) ? gNumber_YES : gNumber_NO; 237} 238 239- (NSNumber *) canvasViewCanZoomIn 240{ 241 return ([_canvasView canIncreaseZoomFactor]) ? gNumber_YES : gNumber_NO; 242} 243 244- (NSNumber *) canvasViewCanZoomOut 245{ 246 return ([_canvasView canDecreaseZoomFactor]) ? gNumber_YES : gNumber_NO; 247} 248 249#pragma mark Menu item modifications 250 251- (void) modifyMenuItemForLayerEnabled: (NSMenuItem *) menuItem 252{ 253 [menuItem setState: ([[_ppDocument drawingLayer] isEnabled]) ? NSOnState : NSOffState]; 254} 255 256- (void) modifyMenuItemForLayerBlendingMode: (NSMenuItem *) menuItem 257{ 258 NSString *modeName = nil; 259 260 if ([self documentIsValid]) 261 { 262 if ([_ppDocument layerBlendingMode] == kPPLayerBlendingMode_Linear) 263 { 264 modeName = @"LINEAR"; 265 } 266 else 267 { 268 modeName = @"STANDARD"; 269 } 270 } 271 272 [menuItem ppSetTitleModeNameSuffix: modeName]; 273} 274 275- (void) modifyMenuItemForCanvasDisplayMode: (NSMenuItem *) menuItem 276{ 277 NSString *modeName = nil; 278 279 if ([self documentIsValid]) 280 { 281 if (_canvasDisplayMode == kPPLayerDisplayMode_DrawingLayerOnly) 282 { 283 modeName = @"DRAW Layer"; 284 } 285 else 286 { 287 modeName = @"ENABLED Layers"; 288 } 289 } 290 291 [menuItem ppSetTitleModeNameSuffix: modeName]; 292} 293 294- (void) modifyMenuItemForGridVisibilityStatus: (NSMenuItem *) menuItem 295{ 296 [menuItem setState: ([_ppDocument shouldDisplayGrid]) ? NSOnState : NSOffState]; 297} 298 299- (void) modifyMenuItemForGridType: (NSMenuItem *) menuItem 300{ 301 NSString *modeName = nil; 302 303 if ([self documentIsValid]) 304 { 305 switch ([_ppDocument pixelGridPatternType]) 306 { 307 case kPPGridType_Crosshairs: 308 { 309 modeName = @"Crosshairs"; 310 } 311 break; 312 313 case kPPGridType_LargeDots: 314 { 315 modeName = @"Large Dots"; 316 } 317 break; 318 319 case kPPGridType_Dots: 320 { 321 modeName = @"Dots"; 322 } 323 break; 324 325 case kPPGridType_Lines: 326 default: 327 { 328 modeName = @"Lines"; 329 } 330 break; 331 } 332 } 333 334 [menuItem ppSetTitleModeNameSuffix: modeName]; 335} 336 337- (void) modifyMenuItemForGridGuidelinesVisibilityStatus: (NSMenuItem *) menuItem 338{ 339 [menuItem setState: 340 ([_ppDocument gridPatternShouldDisplayGuidelines]) ? NSOnState : NSOffState]; 341} 342 343- (void) modifyMenuItemForBackgroundImageVisibilityStatus: (NSMenuItem *) menuItem 344{ 345 [menuItem setState: ([_ppDocument shouldDisplayBackgroundImage]) ? NSOnState : NSOffState]; 346} 347 348- (void) modifyMenuItemForBackgroundImageSmoothingStatus: (NSMenuItem *) menuItem 349{ 350 [menuItem setState: ([_ppDocument shouldSmoothenBackgroundImage]) ? NSOnState : NSOffState]; 351} 352 353- (void) modifyMenuItemForLayerOperationTarget: (NSMenuItem *) menuItem 354{ 355 NSString *modeName = nil; 356 357 if ([self documentIsValid]) 358 { 359 if ([_ppDocument layerOperationTarget] == kPPLayerOperationTarget_DrawingLayerOnly) 360 { 361 modeName = @"DRAW Layer"; 362 } 363 else 364 { 365 modeName = @"ENABLED Layers"; 366 } 367 } 368 369 [menuItem ppSetTitleModeNameSuffix: modeName]; 370} 371 372- (void) modifyMenuItemForToolsPanelVisibilityStatus: (NSMenuItem *) menuItem 373{ 374 [menuItem setState: 375 ([_panelsController panelOfTypeIsVisible: kPPPanelType_Tools]) ? 376 NSOnState : NSOffState]; 377} 378 379- (void) modifyMenuItemForLayersPanelVisibilityStatus: (NSMenuItem *) menuItem 380{ 381 [menuItem setState: 382 ([_panelsController panelOfTypeIsVisible: kPPPanelType_Layers]) ? 383 NSOnState : NSOffState]; 384} 385 386- (void) modifyMenuItemForPreviewPanelVisibilityStatus: (NSMenuItem *) menuItem 387{ 388 [menuItem setState: 389 ([_panelsController panelOfTypeIsVisible: kPPPanelType_Preview]) ? 390 NSOnState : NSOffState]; 391} 392 393- (void) modifyMenuItemForSamplerImagePanelVisibilityStatus: (NSMenuItem *) menuItem 394{ 395 [menuItem setState: 396 ([_panelsController panelOfTypeIsVisible: kPPPanelType_SamplerImage]) ? 397 NSOnState : NSOffState]; 398} 399 400- (void) modifyMenuItemForToolModifierTipsPanelVisibilityStatus: (NSMenuItem *) menuItem 401{ 402 [menuItem setState: 403 ([_panelsController panelOfTypeIsVisible: kPPPanelType_ToolModifierTips]) ? 404 NSOnState : NSOffState]; 405} 406 407@end 408 409@implementation NSMenuItem (PPUtilities_MenuValidationPrivateMethods) 410 411- (void) ppSetTitleModeNameSuffix: (NSString *) modeName 412{ 413 NSString *currentTitle, *newTitle; 414 NSRange colonRange; 415 416 currentTitle = [self title]; 417 418 if (!currentTitle) 419 { 420 currentTitle = @""; 421 } 422 423 colonRange = [currentTitle rangeOfString: @":"]; 424 425 if (colonRange.length) 426 { 427 newTitle = [currentTitle substringToIndex: colonRange.location]; 428 } 429 else 430 { 431 newTitle = currentTitle; 432 } 433 434 if (modeName) 435 { 436 newTitle = [newTitle stringByAppendingFormat: @": %@", modeName]; 437 } 438 439 if (![newTitle isEqualToString: currentTitle]) 440 { 441 [self setTitle: newTitle]; 442 } 443} 444 445@end 446 447#pragma mark Private functions 448 449static void SetupGlobals(void) 450{ 451 if (!gNeedToSetupGlobals) 452 return; 453 454 gMenuItemModificationSelectorDict = [MenuItemModificationSelectorDict() retain]; 455 gMenuItemValidationSelectorDict = [MenuItemValidationSelectorDict() retain]; 456 457 gNumber_YES = [[NSNumber numberWithBool: YES] retain]; 458 gNumber_NO = [[NSNumber numberWithBool: NO] retain]; 459 460 gNeedToSetupGlobals = NO; 461} 462 463static SEL SelectorFromDictForMenuActionName(NSDictionary *selectorDict, NSString *actionName) 464{ 465 NSString *dictSelectorName; 466 467 if (!selectorDict || !actionName) 468 { 469 return NULL; 470 } 471 472 dictSelectorName = [selectorDict objectForKey: actionName]; 473 474 if (!dictSelectorName) 475 { 476 return NULL; 477 } 478 479 return NSSelectorFromString(dictSelectorName); 480} 481 482static NSDictionary *MenuItemValidationSelectorDict(void) 483{ 484 return [NSDictionary dictionaryWithObjectsAndKeys: 485 486 // File menu 487 488 @"documentHasSelectionAndEnabledTargetLayer", 489 @"newDocumentFromSelection:", 490 491 @"documentIsValid", 492 @"exportImage:", 493 494 // Edit menu 495 496 @"documentHasSelection", 497 @"cut:", 498 499 @"documentHasSelection", 500 @"copy:", 501 502 @"documentCanReadFromPasteboard", 503 @"paste:", 504 505 @"documentCanReadFromPasteboard", 506 @"pasteIntoActiveLayer:", 507 508 @"documentHasSelection", 509 @"delete:", 510 511 @"documentIsValid", 512 @"selectAll:", 513 514 @"documentHasSelection", 515 @"deselectAll:", 516 517 @"documentIsValid", 518 @"selectVisibleTargetPixels:", 519 520 @"documentHasSelection", 521 @"deselectInvisibleTargetPixels:", 522 523 @"documentIsValid", 524 @"invertSelection:", 525 526 @"documentHasSelection", 527 @"nudgeSelectionOutlineLeft:", 528 529 @"documentHasSelection", 530 @"nudgeSelectionOutlineRight:", 531 532 @"documentHasSelection", 533 @"nudgeSelectionOutlineUp:", 534 535 @"documentHasSelection", 536 @"nudgeSelectionOutlineDown:", 537 538 @"documentHasSelection", 539 @"closeHolesInSelection:", 540 541 @"documentHasSelectionAndDrawLayerIsEnabled", 542 @"fillSelectedPixels:", 543 544 @"documentHasSelectionAndDrawLayerIsEnabled", 545 @"eraseSelectedPixels:", 546 547 @"documentHasSelectionAndEnabledTargetLayer", 548 @"tileSelection:", 549 550 @"documentHasSelectionAndEnabledTargetLayer", 551 @"tileSelectionAsNewLayer:", 552 553 // Layer menu 554 555 @"documentIsValid", 556 @"newLayer:", 557 558 @"documentIsValid", 559 @"duplicateActiveLayer:", 560 561 @"documentIsValid", 562 @"deleteActiveLayer:", 563 564 @"documentIsValid", 565 @"toggleActiveLayerEnabledFlag:", 566 567 @"documentIsValid", 568 @"enableAllLayers:", 569 570 @"documentIsValid", 571 @"disableAllLayers:", 572 573 @"documentActiveLayerCanIncreaseOpacity", 574 @"increaseActiveLayerOpacity:", 575 576 @"documentActiveLayerCanDecreaseOpacity", 577 @"decreaseActiveLayerOpacity:", 578 579 @"documentHasValidLayerAboveDrawingLayer", 580 @"makePreviousLayerActive:", 581 582 @"documentHasValidLayerBelowDrawingLayer", 583 @"makeNextLayerActive:", 584 585 @"documentHasValidLayerAboveDrawingLayer", 586 @"moveActiveLayerUp:", 587 588 @"documentHasValidLayerBelowDrawingLayer", 589 @"moveActiveLayerDown:", 590 591 @"documentHasValidLayerAboveDrawingLayer", 592 @"mergeWithLayerAbove:", 593 594 @"documentHasValidLayerBelowDrawingLayer", 595 @"mergeWithLayerBelow:", 596 597 @"documentHasMultipleLayers", 598 @"mergeAllLayers:", 599 600 @"documentIsValid", 601 @"toggleLayerBlendingMode:", 602 603 // Canvas menu 604 605 @"documentHasMultipleLayers", 606 @"toggleCanvasDisplayMode:", 607 608 @"canvasViewCanZoomIn", 609 @"increaseZoom:", 610 611 @"canvasViewCanZoomOut", 612 @"decreaseZoom:", 613 614 @"documentIsValid", 615 @"zoomToFit:", 616 617 @"documentIsValid", 618 @"editGridSettings:", 619 620 @"documentIsValid", 621 @"toggleGridVisibility:", 622 623 @"documentHasVisibleGrid", 624 @"toggleGridType:", 625 626 @"documentHasVisibleGrid", 627 @"toggleGridGuidelinesVisibility:", 628 629 @"documentIsValid", 630 @"editBackgroundSettings:", 631 632 @"documentHasBackgroundImage", 633 @"toggleBackgroundImageVisibility:", 634 635 @"documentHasVisibleBackgroundImage", 636 @"toggleBackgroundImageSmoothing:", 637 638 @"documentIsValid", 639 @"flipCanvasHorizontally:", 640 641 @"documentIsValid", 642 @"flipCanvasVertically:", 643 644 @"documentIsValid", 645 @"rotateCanvas90Clockwise:", 646 647 @"documentIsValid", 648 @"rotateCanvas90Counterclockwise:", 649 650 @"documentIsValid", 651 @"rotateCanvas180:", 652 653 @"documentIsValid", 654 @"resize:", 655 656 @"documentIsValid", 657 @"scale:", 658 659 @"documentHasSelection", 660 @"cropToSelection:", 661 662 // Operation menu 663 664 @"documentHasMultipleLayers", 665 @"toggleLayerOperationTarget:", 666 667 @"documentHasSelectionOrEnabledTargetLayer", 668 @"flipHorizontally:", 669 670 @"documentHasSelectionOrEnabledTargetLayer", 671 @"flipVertically:", 672 673 @"documentHasSelectionOrEnabledTargetLayer", 674 @"rotate90Clockwise:", 675 676 @"documentHasSelectionOrEnabledTargetLayer", 677 @"rotate90Counterclockwise:", 678 679 @"documentHasSelectionOrEnabledTargetLayer", 680 @"rotate180:", 681 682 @"documentHasSelectionOrEnabledTargetLayer", 683 @"nudgeLeft:", 684 685 @"documentHasSelectionOrEnabledTargetLayer", 686 @"nudgeRight:", 687 688 @"documentHasSelectionOrEnabledTargetLayer", 689 @"nudgeUp:", 690 691 @"documentHasSelectionOrEnabledTargetLayer", 692 @"nudgeDown:", 693 694 // Panels menu 695 696 @"documentIsValid", 697 @"toggleToolsPanelVisibility:", 698 699 @"documentIsValid", 700 @"toggleLayersPanelVisibility:", 701 702 @"documentIsValid", 703 @"togglePreviewPanelVisibility:", 704 705 @"documentHasActiveSamplerImageForPanel", 706 @"toggleSamplerImagePanelVisibility:", 707 708 @"documentIsValid", 709 @"toggleToolModifierTipsPanelVisibility:", 710 711 @"documentIsValid", 712 @"toggleActivePanelsVisibility:", 713 714 @"documentIsValid", 715 @"toggleColorPickerVisibility:", 716 717 @"documentIsValid", 718 @"editSamplerImagesSettings:", 719 720 @"documentHasMultipleSamplerImagesAndSamplerPanelIsVisible", 721 @"nextSamplerPanelImage:", 722 723 @"documentHasMultipleSamplerImagesAndSamplerPanelIsVisible", 724 @"previousSamplerPanelImage:", 725 726 nil]; 727} 728 729static NSDictionary *MenuItemModificationSelectorDict(void) 730{ 731 return [NSDictionary dictionaryWithObjectsAndKeys: 732 733 @"modifyMenuItemForLayerEnabled:", 734 @"toggleActiveLayerEnabledFlag:", 735 736 @"modifyMenuItemForLayerBlendingMode:", 737 @"toggleLayerBlendingMode:", 738 739 @"modifyMenuItemForCanvasDisplayMode:", 740 @"toggleCanvasDisplayMode:", 741 742 @"modifyMenuItemForGridVisibilityStatus:", 743 @"toggleGridVisibility:", 744 745 @"modifyMenuItemForGridType:", 746 @"toggleGridType:", 747 748 @"modifyMenuItemForGridGuidelinesVisibilityStatus:", 749 @"toggleGridGuidelinesVisibility:", 750 751 @"modifyMenuItemForBackgroundImageVisibilityStatus:", 752 @"toggleBackgroundImageVisibility:", 753 754 @"modifyMenuItemForBackgroundImageSmoothingStatus:", 755 @"toggleBackgroundImageSmoothing:", 756 757 @"modifyMenuItemForLayerOperationTarget:", 758 @"toggleLayerOperationTarget:", 759 760 @"modifyMenuItemForToolsPanelVisibilityStatus:", 761 @"toggleToolsPanelVisibility:", 762 763 @"modifyMenuItemForLayersPanelVisibilityStatus:", 764 @"toggleLayersPanelVisibility:", 765 766 @"modifyMenuItemForPreviewPanelVisibilityStatus:", 767 @"togglePreviewPanelVisibility:", 768 769 @"modifyMenuItemForSamplerImagePanelVisibilityStatus:", 770 @"toggleSamplerImagePanelVisibility:", 771 772 @"modifyMenuItemForToolModifierTipsPanelVisibilityStatus:", 773 @"toggleToolModifierTipsPanelVisibility:", 774 775 nil]; 776} 777 778static bool MenuActionNameIsAllowedDuringMouseTracking(NSString *actionName) 779{ 780 static NSSet *allowedMouseTrackingActionNamesSet = nil; 781 782 if (!actionName) 783 goto ERROR; 784 785 if (!allowedMouseTrackingActionNamesSet) 786 { 787 allowedMouseTrackingActionNamesSet = 788 [[NSSet setWithObjects: 789 @"toggleGridVisibility:", 790 @"toggleGridType:", 791 @"toggleGridGuidelinesVisibility:", 792 @"toggleBackgroundImageVisibility:", 793 @"toggleBackgroundImageSmoothing:", 794 @"toggleToolsPanelVisibility:", 795 @"toggleLayersPanelVisibility:", 796 @"togglePreviewPanelVisibility:", 797 @"toggleSamplerImagePanelVisibility:", 798 @"toggleToolModifierTipsPanelVisibility:", 799 @"toggleActivePanelsVisibility:", 800 @"toggleColorPickerVisibility:", 801 @"nextSamplerPanelImage:", 802 @"previousSamplerPanelImage:", 803 nil] 804 retain]; 805 } 806 807 return ([allowedMouseTrackingActionNamesSet containsObject: actionName]) ? YES : NO; 808 809ERROR: 810 return NO; 811} 812 813static bool MenuActionNameIsAllowedDuringPopupPanel(NSString *actionName) 814{ 815 static NSSet *disallowedPopupPanelActionNamesSet = nil; 816 817 if (!actionName) 818 goto ERROR; 819 820 if (!disallowedPopupPanelActionNamesSet) 821 { 822 disallowedPopupPanelActionNamesSet = 823 [[NSSet setWithObjects: 824 @"nextSamplerPanelImage:", 825 @"previousSamplerPanelImage:", 826 nil] 827 retain]; 828 } 829 830 return ([disallowedPopupPanelActionNamesSet containsObject: actionName]) ? NO : YES; 831 832ERROR: 833 return NO; 834} 835