mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-10-07 01:18:02 +00:00
Merge branch 'menu-validation' into 0.9.1
This commit is contained in:
commit
592328f604
6 files changed
+102
-10
No files matched your search
+22
-2
@@ -536,7 +536,6 @@ var _CPMenuBarVisible = NO,
|
||||
*/
|
||||
- (void)submenuAction:(id)aSender
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -584,11 +583,30 @@ var _CPMenuBarVisible = NO,
|
||||
}
|
||||
|
||||
/*!
|
||||
Not implemented.
|
||||
Enables or disables the receiver’s menu items.
|
||||
If the target does not implement the menu item's action method the item is disabled.
|
||||
If the target responsds to selector validateMenuItem: or validateUserInterfaceItem: (in that order) the return value is used.
|
||||
*/
|
||||
- (void)update
|
||||
{
|
||||
if (![self autoenablesItems])
|
||||
return;
|
||||
|
||||
var items = [self itemArray];
|
||||
for (var i = 0; i < [items count]; i++)
|
||||
{
|
||||
var item = [items objectAtIndex:i],
|
||||
validator = [CPApp targetForAction:[item action] to:[item target] from:item];
|
||||
|
||||
if (!validator || ![validator respondsToSelector:[item action]])
|
||||
[item _setEnabled:NO];
|
||||
else if ([validator respondsToSelector:@selector(validateMenuItem:)])
|
||||
[item _setEnabled:[validator validateMenuItem:item]];
|
||||
else if ([validator respondsToSelector:@selector(validateUserInterfaceItem:)])
|
||||
[item _setEnabled:[validator validateUserInterfaceItem:item]];
|
||||
}
|
||||
|
||||
[[_menuWindow _menuView] tile];
|
||||
}
|
||||
|
||||
// Managing the Title
|
||||
@@ -1100,6 +1118,8 @@ var CPMenuTitleKey = @"CPMenuTitleKey",
|
||||
|
||||
_showsStateColumn = ![aCoder containsValueForKey:CPMenuShowsStateColumnKey] || [aCoder decodeBoolForKey:CPMenuShowsStateColumnKey];
|
||||
|
||||
_autoenablesItems = YES;
|
||||
|
||||
[self setMinimumWidth:0];
|
||||
}
|
||||
|
||||
|
||||
@@ -243,9 +243,15 @@ var STICKY_TIME_INTERVAL = 500,
|
||||
// Close the current menu item because we are going to select a new one after a short delay
|
||||
[self showMenu:nil fromMenu:activeMenu atPoint:CGPointMakeZero()];
|
||||
|
||||
_showTimerID = setTimeout(function() {
|
||||
|
||||
if (![activeMenuContainer isMenuBar])
|
||||
{
|
||||
_showTimerID = setTimeout(function() {
|
||||
[self showMenu:[activeItem submenu] fromMenu:[activeItem menu] atPoint:newMenuOrigin];
|
||||
}, 250);
|
||||
}
|
||||
else
|
||||
[self showMenu:[activeItem submenu] fromMenu:[activeItem menu] atPoint:newMenuOrigin];
|
||||
}, 250);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -208,8 +208,14 @@ var STICKY_TIME_INTERVAL = 500,
|
||||
return [_menuView menu];
|
||||
}
|
||||
|
||||
- (_CPMenuView)_menuView
|
||||
{
|
||||
return _menuView;
|
||||
}
|
||||
|
||||
- (void)orderFront:(id)aSender
|
||||
{
|
||||
[[self menu] update];
|
||||
[self setFrame:_unconstrainedFrame];
|
||||
|
||||
[super orderFront:aSender];
|
||||
|
||||
@@ -133,10 +133,17 @@
|
||||
if ([_menu autoenablesItems])
|
||||
return;
|
||||
|
||||
_isEnabled = isEnabled;
|
||||
[self _setEnabled:isEnabled];
|
||||
}
|
||||
|
||||
- (void)_setEnabled:(BOOL)isEnabled
|
||||
{
|
||||
if (_isEnabled === isEnabled)
|
||||
return;
|
||||
|
||||
_isEnabled = !!isEnabled;
|
||||
|
||||
[_menuItemView setDirty];
|
||||
|
||||
[_menu itemChanged:self];
|
||||
}
|
||||
|
||||
@@ -851,6 +858,11 @@ CPControlKeyMask
|
||||
return ![self submenu] && [self menu] === [CPApp mainMenu];
|
||||
}
|
||||
|
||||
- (CPString)description
|
||||
{
|
||||
return [super description] + @" target: " + [self target] + @" action: " + CPStringFromSelector([self action]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey",
|
||||
|
||||
@@ -47,12 +47,8 @@
|
||||
|
||||
// If the destination doesn't respond to this selector, warn but don't die.
|
||||
if (_destination && ![_destination respondsToSelector:selector])
|
||||
{
|
||||
CPLog.warn(@"Could not connect the action " + selector + @" to target of class " + [_destination className]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Not being able to set the action is a fatal error.
|
||||
if ([_source respondsToSelector:@selector(setAction:)])
|
||||
objj_msgSend(_source, @selector(setAction:), selector);
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
@implementation CPMenuValidatedUserInterfaceItemTest : OJTestCase
|
||||
{
|
||||
CPMenu _menu @accessors(property=menu);
|
||||
}
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[[CPApplication sharedApplication] setDelegate:[[MenuTarget alloc] init]];
|
||||
|
||||
_menu = [[CPMenu alloc] init];
|
||||
|
||||
[_menu addItem:[[CPMenuItem alloc] initWithTitle:@"implemented" action:@selector(implementedAction:) keyEquivalent:nil]];
|
||||
[_menu addItem:[[CPMenuItem alloc] initWithTitle:@"disabled" action:@selector(disabledAction:) keyEquivalent:nil]];
|
||||
[_menu addItem:[[CPMenuItem alloc] initWithTitle:@"unimplemented" action:@selector(unimplementedAction:) keyEquivalent:nil]];
|
||||
}
|
||||
|
||||
- (void)testAutoenable
|
||||
{
|
||||
// Update is what actually performs the autoenabling so we need to call it manually.
|
||||
// It's normally called automatically just before a menu becomes visible.
|
||||
[[self menu] update];
|
||||
|
||||
[self assertTrue:[[[self menu] itemWithTitle:@"implemented"] isEnabled] message:@"The implemented action should be enabled"];
|
||||
[self assertFalse:[[[self menu] itemWithTitle:@"disabled"] isEnabled] message:@"The disbabled action should be disabled"];
|
||||
[self assertFalse:[[[self menu] itemWithTitle:@"unimplemented"] isEnabled] message:@"The unimplemented action should be disabled"];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MenuTarget : CPObject
|
||||
{
|
||||
}
|
||||
|
||||
- (BOOL)validateMenuItem:(CPMenuItem)theMenuItem
|
||||
{
|
||||
if ([theMenuItem action] === @selector(disabledAction:))
|
||||
return NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (@action)implementedAction:(id)theSender
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (@action)disabledAction:(id)theSender
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in new issue
Block a user