Menu behavior tinkering

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@5674 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 2000-01-05 20:16:59 +00:00
parent 623f5da51a
commit 26e56d11cf
3 changed files with 108 additions and 56 deletions

View file

@ -1,3 +1,9 @@
Wed Jan 5 20:04:00 2000 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Source/NSMenuView.m: Changes to mouse tracking loop to provide more
sophisticated handling of opening/closing of submenus in an attempt to
mimic the behavior of NeXTstep.
Wed Jan 5 16:27:00 2000 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Source/NSMenuItem.m: minor fixes and tidying.

View file

@ -51,15 +51,15 @@
#include <AppKit/NSPopUpButtonCell.h>
#include <AppKit/NSScreen.h>
static NSZone *menuZone = NULL;
static NSZone *menuZone = NULL;
static NSString* NSMenuLocationsKey = @"NSMenuLocations";
static NSString *NSMenuLocationsKey = @"NSMenuLocations";
@implementation NSMenu
//
// Class Methods
//
/*
* Class Methods
*/
+ (void) initialize
{
if (self == [NSMenu class])
@ -68,19 +68,19 @@ static NSString* NSMenuLocationsKey = @"NSMenuLocations";
}
}
+ (void) setMenuZone: (NSZone *)zone
+ (void) setMenuZone: (NSZone*)zone
{
menuZone = zone;
}
+ (NSZone *) menuZone
+ (NSZone*) menuZone
{
return menuZone;
}
//
// Initializing a New NSMenu
//
/*
* Initializing a New NSMenu
*/
- (id) init
{
return [self initWithTitle: @"Menu"];
@ -116,7 +116,7 @@ static NSString* NSMenuLocationsKey = @"NSMenuLocations";
[super dealloc];
}
- (id) initWithTitle: (NSString *)aTitle
- (id) initWithTitle: (NSString*)aTitle
{
NSNotificationCenter *theCenter = [NSNotificationCenter defaultCenter];
NSApplication *theApp = [NSApplication sharedApplication];
@ -172,9 +172,9 @@ static NSString* NSMenuLocationsKey = @"NSMenuLocations";
return self;
}
//
// Setting Up the Menu Commands
//
/*
* Setting Up the Menu Commands
*/
- (void) insertItem: (id <NSMenuItem>)newItem
atIndex: (int)index
{
@ -185,8 +185,10 @@ static NSString* NSMenuLocationsKey = @"NSMenuLocations";
{
if ([(id)newItem isKindOfClass: [NSMenuItem class]])
{
// If the item is already attached to another menu it
// isn't added.
/*
* If the item is already attached to another menu it
* isn't added.
*/
if ([(NSMenuItem *)newItem menu] != nil)
return;
@ -222,9 +224,9 @@ static NSString* NSMenuLocationsKey = @"NSMenuLocations";
menu_changed = YES;
}
- (id <NSMenuItem>) insertItemWithTitle: (NSString *)aString
- (id <NSMenuItem>) insertItemWithTitle: (NSString*)aString
action: (SEL)aSelector
keyEquivalent: (NSString *)charCode
keyEquivalent: (NSString*)charCode
atIndex: (unsigned int)index
{
id anItem = [NSMenuItem new];
@ -247,9 +249,9 @@ static NSString* NSMenuLocationsKey = @"NSMenuLocations";
[self insertItem: newItem atIndex: [menu_items count]];
}
- (id <NSMenuItem>) addItemWithTitle: (NSString *)aString
- (id <NSMenuItem>) addItemWithTitle: (NSString*)aString
action: (SEL)aSelector
keyEquivalent: (NSString *)keyEquiv
keyEquivalent: (NSString*)keyEquiv
{
return [self insertItemWithTitle: aString
action: aSelector
@ -321,9 +323,9 @@ static NSString* NSMenuLocationsKey = @"NSMenuLocations";
[self update];
}
//
// Finding Menu Items
//
/*
* Finding Menu Items
*/
- (id <NSMenuItem>) itemWithTag: (int)aTag
{
unsigned i;
@ -368,20 +370,20 @@ static NSString* NSMenuLocationsKey = @"NSMenuLocations";
return [menu_items count];
}
- (NSArray *) itemArray
- (NSArray*) itemArray
{
return (NSArray *)menu_items;
return (NSArray*)menu_items;
}
//
// Finding Indices of Menu Items
//
/*
* Finding Indices of Menu Items
*/
- (int) indexOfItem: (id <NSMenuItem>)anObject
{
return [menu_items indexOfObjectIdenticalTo: anObject];
}
- (int) indexOfItemWithTitle: (NSString *)aTitle
- (int) indexOfItemWithTitle: (NSString*)aTitle
{
id anItem;
@ -411,9 +413,13 @@ static NSString* NSMenuLocationsKey = @"NSMenuLocations";
{
NSMenuItem *menuItem = [menu_items objectAtIndex: i];
if ([[menuItem target] isEqual: anObject]
&& (!actionSelector || [menuItem action] == actionSelector))
return i;
if (actionSelector == 0 || sel_eq([menuItem action], actionSelector))
{
if ([[menuItem target] isEqual: anObject])
{
return i;
}
}
}
return -1;

View file

@ -409,9 +409,9 @@ static float GSMenuBarHeight = 25.0; // A wild guess.
float howHigh = (howMany * cellSize.height);
float neededImageAndTitleWidth = [[NSFont boldSystemFontOfSize: 12]
widthOfString: [menuv_menu title]] + 17;
float neededKeyEquivalentWidth = 0.;
float neededStateImageWidth = 0.;
float accumulatedOffset = 0.;
float neededKeyEquivalentWidth = 0.0;
float neededStateImageWidth = 0.0;
float accumulatedOffset = 0.0;
// TODO: Optimize this loop.
for (i = 0; i < howMany; i++)
@ -710,7 +710,7 @@ static float GSMenuBarHeight = 25.0; // A wild guess.
}
#define MOVE_THRESHOLD_DELTA 1.0
#define DELAY_MULTIPLIER 12
#define DELAY_MULTIPLIER 6
- (BOOL) trackWithEvent: (NSEvent *)event
{
@ -719,43 +719,81 @@ static float GSMenuBarHeight = 25.0; // A wild guess.
| NSLeftMouseDraggedMask
| NSPeriodicMask;
NSDate *theDistantFuture = [NSDate distantFuture];
int index;
NSPoint location;
NSPoint lastLocation = {0,0};
NSMenu *alreadyAttachedMenu = NO;
BOOL delayedSelect = NO;
int delayCount = DELAY_MULTIPLIER;
int index;
NSPoint location;
NSPoint lastLocation = {0,0};
NSMenu *alreadyAttachedMenu = NO;
BOOL mouseMoved = NO;
BOOL delayedSelect = NO;
int delayCount = 0;
float xDelta = MOVE_THRESHOLD_DELTA;
float yDelta = 0.0;
do
{
location = [window mouseLocationOutsideOfEventStream];
index = [self indexOfItemAtPoint: location];
if (index != menuv_highlightedItemIndex)
{
mouseMoved = YES; /* Ok - had an initial movement. */
}
if ([event type] == NSPeriodic)
{
if ([menuv_menu isPartlyOffScreen])
{
NSPoint pointerLoc = [window convertBaseToScreen:
location];
NSPoint pointerLoc = [window convertBaseToScreen: location];
// TODO: Why 1 in the Y axis?
if (pointerLoc.x == 0 || pointerLoc.y == 1 ||
pointerLoc.x == [[window screen] frame].size.width
- 1)
if (pointerLoc.x == 0 || pointerLoc.y == 1
|| pointerLoc.x == [[window screen] frame].size.width - 1)
[menuv_menu shiftOnScreen];
}
if ([event type] == NSPeriodic && delayedSelect && !delayCount)
if (delayedSelect && mouseMoved && [event type] == NSPeriodic)
{
if (location.x - lastLocation.x < MOVE_THRESHOLD_DELTA ||
abs(location.y - lastLocation.y) < MOVE_THRESHOLD_DELTA)
delayedSelect = NO;
float xDiff = location.x - lastLocation.x;
float yDiff = location.y - lastLocation.y;
/*
* Once the mouse movement has started in one vertical
* direction, it must continue in the same direction if
* selection is to be delayed.
*/
if (yDelta == 0.0)
{
if (yDiff < 0.0)
yDelta = -MOVE_THRESHOLD_DELTA;
else if (yDiff > 0.0)
yDelta = MOVE_THRESHOLD_DELTA;
}
/*
* Check to see if movement is less than the threshold.
*/
if (xDiff < xDelta
|| (yDelta < 0.0 && yDiff > yDelta)
|| (yDelta > 0.0 && yDiff < yDelta))
{
/*
* if we have had too many successive small movements, or
* a single movement too far in the wrong direction, we
* leave 'delayedSelect' mode.
*/
delayCount++;
if (delayCount >= DELAY_MULTIPLIER
|| (xDiff < -xDelta)
|| (yDelta < 0.0 && yDiff > -yDelta)
|| (yDelta > 0.0 && yDiff < -yDelta))
{
delayedSelect = NO;
}
}
else
{
delayCount = 0;
}
lastLocation = location;
}
delayCount = delayCount ? --delayCount : DELAY_MULTIPLIER;
}
if (index == -1)
@ -790,8 +828,10 @@ static float GSMenuBarHeight = 25.0; // A wild guess.
[[menuv_items_link objectAtIndex: index] submenu]))
{
[self attachSubmenuForItemAtIndex: index];
mouseMoved = NO;
delayedSelect = YES;
delayCount = DELAY_MULTIPLIER;
delayCount = 0;
yDelta = 0.0;
}
else
{
@ -863,7 +903,7 @@ static float GSMenuBarHeight = 25.0; // A wild guess.
masterMenuView->menuv_keepAttachedMenus = YES;
[NSEvent startPeriodicEventsAfterDelay: 0.2 withPeriod: 0.05];
[NSEvent startPeriodicEventsAfterDelay: 0.1 withPeriod: 0.05];
[masterMenuView trackWithEvent: theEvent];