Ensure autocomplete menu is on top.

The menu should appear above other normal windows and controls like a regular CPMenu. To do this, put the pop up in its own window with the `CPPopUpMenuWindowLevel` window level.
This commit is contained in:
Alexander Ljungberg
2012-06-16 12:31:48 +01:00
parent 2574fac44a
commit 33fe1573ad
2 changed files with 31 additions and 43 deletions
+8 -29
View File
@@ -63,7 +63,7 @@ var CPScrollDestinationNone = 0,
CPRange _selectedRange;
_CPAutocompleteMenu _autocompleteMenu @accessors;
_CPAutocompleteMenu _autocompleteMenu;
CPTimeInterval _completionDelay;
@@ -119,8 +119,13 @@ var CPScrollDestinationNone = 0,
[_tokenScrollView setDocumentView:contentView];
[self addSubview:_tokenScrollView];
}
_autocompleteMenu = [[_CPAutocompleteMenu alloc] initWithTextField:self];
- (_CPAutocompleteMenu)_autocompleteMenu
{
if (!_autocompleteMenu)
_autocompleteMenu = [[_CPAutocompleteMenu alloc] initWithTextField:self];
return _autocompleteMenu;
}
- (void)_autocompleteWithDOMEvent:(JSObject)DOMEvent
@@ -352,8 +357,6 @@ var CPScrollDestinationNone = 0,
- (BOOL)resignFirstResponder
{
CPLog("%@ resignFirstResponder", self);
if (_preventResign)
return NO;
@@ -566,25 +569,6 @@ var CPScrollDestinationNone = 0,
{
}
// ========
// = VIEW =
// ========
- (void)viewDidMoveToWindow
{
// TODO Switch to a window.
[[[self window] contentView] addSubview:[_autocompleteMenu contentView]];
#if PLATFORM(DOM)
[_autocompleteMenu contentView]._DOMElement.style.zIndex = 1000; // Anything else doesn't seem to work
#endif
}
- (void)removeFromSuperview
{
// TODO
[[_autocompleteMenu contentView] removeFromSuperview];
}
// =============
// = TEXTFIELD =
// =============
@@ -1014,11 +998,6 @@ var CPScrollDestinationNone = 0,
return [[_tokenScrollView documentView] scrollRectToVisible:[aToken frame]];
}
- (CPTableView)_autocompleteView
{
return _autocompleteView;
}
@end
@implementation CPTokenField (CPTokenFieldDelegate)
@@ -1125,7 +1104,7 @@ var CPScrollDestinationNone = 0,
- (void)_delayedShowCompletions
{
[_autocompleteMenu _delayedShowCompletions];
[[self _autocompleteMenu] _delayedShowCompletions];
}
- (void)_hideCompletions
+23 -14
View File
@@ -34,7 +34,7 @@
CPTextField textField @accessors;
CPArray contentArray @accessors;
CPView contentView @accessors;
CPWindow _menuWindow;
CPScrollView scrollView;
CPTableView tableView;
@@ -47,9 +47,15 @@
{
textField = aTextField;
contentView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
_menuWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0, 0, 100, 100) styleMask:CPBorderlessWindowMask];
[contentView setBackgroundColor:[_CPMenuWindow backgroundColorForBackgroundStyle:_CPMenuWindowPopUpBackgroundStyle]];
[_menuWindow setLevel:CPPopUpMenuWindowLevel];
[_menuWindow setHasShadow:YES];
[_menuWindow setShadowStyle:CPMenuWindowShadowStyle];
[_menuWindow setAcceptsMouseMovedEvents:NO];
[_menuWindow setBackgroundColor:[_CPMenuWindow backgroundColorForBackgroundStyle:_CPMenuWindowPopUpBackgroundStyle]];
var contentView = [_menuWindow contentView];
scrollView = [[CPScrollView alloc] initWithFrame:CGRectMakeZero()];
[scrollView setAutohidesScrollers:YES];
@@ -107,11 +113,14 @@
- (void)layoutSubviews
{
// TODO
// The autocompletion menu should be underneath the current token, it should at least be wide enough to fit the widest
// option but no wider than the width of the token field. It might stick out on the right side, so that if the token
// is small enough to fit on the right side the menu might extend a full token field width more into space on the right
// side. It should not stick out outside of the screen. The height should be the smallest possible to fit all options
// or at most ~307px (based on Cocoa). If the options don't fit horizontally they should be truncated with an ellipsis.
/*
The autocompletion menu should be underneath the word/text being autocompleted. It should at least be wide enough to
fit the widest
option but no wider than the width of the text field. It might stick out on the right side, so that if the edited text
is on the right of the text field the menu might extend a full text field width more into space on the right
side. It should not stick out outside of the screen. The height should be the smallest possible to fit all options
or at most ~307px (based on Cocoa). If the options don't fit horizontally they should be truncated with an ellipsis.
*/
var frame = [textField frame];
@@ -120,10 +129,10 @@
[[[tableView tableColumns] firstObject] setWidth:[[scrollView contentView] frame].size.width];
// Manually sizeToFit because CPTableView's sizeToFit doesn't work properly
var frameOrigin = [textField convertPoint:[textField bounds].origin toView:[contentView superview]],
var frameOrigin = [textField convertPoint:[textField bounds].origin toView:nil],
newFrame = CGRectMake(frameOrigin.x, frameOrigin.y + frame.size.height, CPRectGetWidth([textField bounds]), 92.0);
[contentView setFrame:newFrame];
[scrollView setFrame:CGRectInset([contentView bounds], 1.0, 1.0)];
[_menuWindow setFrame:[_menuWindow frameRectForContentRect:newFrame]];
[scrollView setFrame:CGRectInset([[_menuWindow contentView] bounds], 1.0, 1.0)];
}
- (void)_showCompletions:(CPTimer)timer
@@ -136,7 +145,7 @@
[self setIndexOfSelectedItem:indexOfSelectedItem];
[textField setThemeState:CPThemeStateAutocompleting];
[contentView setHidden:NO];
[_menuWindow orderFront:self];
[self layoutSubviews];
}
@@ -161,7 +170,7 @@
_showCompletionsTimer = nil;
[textField unsetThemeState:CPThemeStateAutocompleting];
[contentView setHidden:YES];
[_menuWindow orderOut:self];
[self layoutSubviews];
}
@@ -201,7 +210,7 @@
// make sure a mouse click in the tableview doesn't steal first responder state
window.setTimeout(function()
{
[[contentView window] makeFirstResponder:textField];
[[textField window] makeFirstResponder:textField];
}, 2.0);
}