Created
September 14, 2009 18:28
-
-
Save saikat/186826 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Couldn't just subclass because of the file scoped variables | |
/* | |
* CPTextField.j | |
* AppKit | |
* | |
* Created by Francisco Tolmasky. | |
* Copyright 2008, 280 North, Inc. | |
* | |
* This library is free software; you can redistribute it and/or | |
* modify it under the terms of the GNU Lesser General Public | |
* License as published by the Free Software Foundation; either | |
* version 2.1 of the License, or (at your option) any later version. | |
* | |
* This library is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
* Lesser General Public License for more details. | |
* | |
* You should have received a copy of the GNU Lesser General Public | |
* License along with this library; if not, write to the Free Software | |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
*/ | |
@import <AppKit/CPTextField.j> | |
/* | |
@global | |
@group CPLineBreakMode | |
*/ | |
CPLineBreakByWordWrapping = 0; | |
/* | |
@global | |
@group CPLineBreakMode | |
*/ | |
CPLineBreakByCharWrapping = 1; | |
/* | |
@global | |
@group CPLineBreakMode | |
*/ | |
CPLineBreakByClipping = 2; | |
/* | |
@global | |
@group CPLineBreakMode | |
*/ | |
CPLineBreakByTruncatingHead = 3; | |
/* | |
@global | |
@group CPLineBreakMode | |
*/ | |
CPLineBreakByTruncatingTail = 4; | |
/* | |
@global | |
@group CPLineBreakMode | |
*/ | |
CPLineBreakByTruncatingMiddle = 5; | |
/* | |
A textfield bezel with a squared corners. | |
@global | |
@group CPTextFieldBezelStyle | |
*/ | |
CPTextFieldSquareBezel = 0; | |
/* | |
A textfield bezel with rounded corners. | |
@global | |
@group CPTextFieldBezelStyle | |
*/ | |
CPTextFieldRoundedBezel = 1; | |
var CPTextFieldDOMInputElement = nil, | |
CPTextFieldDOMPasswordInputElement = nil, | |
CPTextFieldDOMStandardInputElement = nil, | |
CPTextFieldInputOwner = nil, | |
CPTextFieldTextDidChangeValue = nil, | |
CPTextFieldInputResigning = NO, | |
CPTextFieldInputDidBlur = NO, | |
CPTextFieldInputIsActive = NO, | |
CPTextFieldCachedSelectStartFunction = nil, | |
CPTextFieldCachedDragFunction = nil, | |
CPTextFieldBlurFunction = nil, | |
CPTextFieldKeyUpFunction = nil, | |
CPTextFieldKeyPressFunction = nil, | |
CPTextFieldKeyDownFunction = nil; | |
var CPSecureTextFieldCharacter = "\u2022"; | |
SearchFieldDidPressEnterNotification = @"SearchFieldDidPressEnterNotification"; | |
SearchFieldDidPressDownArrowNotification = @"SearchFieldDidPressDownArrowNotification"; | |
SearchFieldDidPressUpArrowNotification = @"SearchFieldDidPressUpArrowNotification"; | |
@implementation CPString (CPTextFieldAdditions) | |
/*! | |
Returns the string (<code>self</code>). | |
*/ | |
- (CPString)string | |
{ | |
return self; | |
} | |
@end | |
CPTextFieldStateRounded = CPThemeState("rounded"); | |
CPTextFieldStatePlaceholder = CPThemeState("placeholder"); | |
/*! | |
@ingroup appkit | |
This control displays editable text in a Cappuccino application. | |
*/ | |
@implementation SearchField : CPControl | |
{ | |
BOOL _isEditable; | |
BOOL _isSelectable; | |
BOOL _isSecure; | |
BOOL _drawsBackground; | |
CPColor _textFieldBackgroundColor; | |
id _placeholderString; | |
id _delegate; | |
CPString _textDidChangeValue; | |
// NS-style Display Properties | |
CPTextFieldBezelStyle _bezelStyle; | |
BOOL _isBordered; | |
CPControlSize _controlSize; | |
} | |
+ (CPTextField)textFieldWithStringValue:(CPString)aStringValue placeholder:(CPString)aPlaceholder width:(float)aWidth | |
{ | |
return [self textFieldWithStringValue:aStringValue placeholder:aPlaceholder width:aWidth theme:[CPTheme defaultTheme]]; | |
} | |
+ (CPTextField)textFieldWithStringValue:(CPString)aStringValue placeholder:(CPString)aPlaceholder width:(float)aWidth theme:(CPTheme)aTheme | |
{ | |
var textField = [[self alloc] initWithFrame:CGRectMake(0.0, 0.0, aWidth, 29.0)]; | |
[textField setTheme:aTheme]; | |
[textField setStringValue:aStringValue]; | |
[textField setPlaceholderString:aPlaceholder]; | |
[textField setBordered:YES]; | |
[textField setBezeled:YES]; | |
[textField setEditable:YES]; | |
[textField sizeToFit]; | |
return textField; | |
} | |
+ (CPTextField)roundedTextFieldWithStringValue:(CPString)aStringValue placeholder:(CPString)aPlaceholder width:(float)aWidth | |
{ | |
return [self roundedTextFieldWithStringValue:aStringValue placeholder:aPlaceholder width:aWidth theme:[CPTheme defaultTheme]]; | |
} | |
+ (CPTextField)roundedTextFieldWithStringValue:(CPString)aStringValue placeholder:(CPString)aPlaceholder width:(float)aWidth theme:(CPTheme)aTheme | |
{ | |
var textField = [[CPTextField alloc] initWithFrame:CGRectMake(0.0, 0.0, aWidth, 29.0)]; | |
[textField setTheme:aTheme]; | |
[textField setStringValue:aStringValue]; | |
[textField setPlaceholderString:aPlaceholder]; | |
[textField setBezelStyle:CPTextFieldRoundedBezel]; | |
[textField setBordered:YES]; | |
[textField setBezeled:YES]; | |
[textField setEditable:YES]; | |
[textField sizeToFit]; | |
return textField; | |
} | |
+ (CPTextField)labelWithTitle:(CPString)aTitle | |
{ | |
return [self labelWithTitle:aTitle theme:[CPTheme defaultTheme]]; | |
} | |
+ (CPTextField)labelWithTitle:(CPString)aTitle theme:(CPTheme)aTheme | |
{ | |
var textField = [[self alloc] init]; | |
[textField setStringValue:aTitle]; | |
[textField sizeToFit]; | |
return textField; | |
} | |
+ (CPString)themeClass | |
{ | |
return "textfield"; | |
} | |
+ (id)themeAttributes | |
{ | |
return [CPDictionary dictionaryWithObjects:[CGInsetMakeZero(), CGInsetMake(2.0, 2.0, 2.0, 2.0), nil] | |
forKeys:[@"bezel-inset", @"content-inset", @"bezel-color"]]; | |
} | |
/* @ignore */ | |
- (DOMElement)_inputElement | |
{ | |
if (!CPTextFieldDOMInputElement) | |
{ | |
CPTextFieldDOMInputElement = document.createElement("input"); | |
CPTextFieldDOMInputElement.style.position = "absolute"; | |
CPTextFieldDOMInputElement.style.border = "0px"; | |
CPTextFieldDOMInputElement.style.padding = "0px"; | |
CPTextFieldDOMInputElement.style.margin = "0px"; | |
CPTextFieldDOMInputElement.style.whiteSpace = "pre"; | |
CPTextFieldDOMInputElement.style.background = "transparent"; | |
CPTextFieldDOMInputElement.style.outline = "none"; | |
CPTextFieldBlurFunction = function(anEvent) | |
{ | |
if (CPTextFieldInputOwner && CPTextFieldInputOwner._DOMElement != CPTextFieldDOMInputElement.parentNode) | |
return; | |
if (!CPTextFieldInputResigning) | |
{ | |
[[CPTextFieldInputOwner window] makeFirstResponder:nil]; | |
return; | |
} | |
CPTextFieldHandleBlur(anEvent, CPTextFieldDOMInputElement); | |
CPTextFieldInputDidBlur = YES; | |
return true; | |
} | |
CPTextFieldKeyDownFunction = function(anEvent) | |
{ | |
CPTextFieldTextDidChangeValue = [CPTextFieldInputOwner stringValue]; | |
anEvent = anEvent || window.event; | |
var defaultCenter = [CPNotificationCenter defaultCenter]; | |
if (anEvent.keyCode == CPReturnKeyCode) { | |
[defaultCenter postNotificationName:SearchFieldDidPressEnterNotification | |
object:CPTextFieldInputOwner]; | |
} | |
else if (anEvent.keyCode == CPDownArrowKeyCode) { | |
[defaultCenter postNotificationName:SearchFieldDidPressDownArrowNotification | |
object:CPTextFieldInputOwner]; | |
} | |
else if (anEvent.keyCode == CPUpArrowKeyCode) { | |
[defaultCenter postNotificationName:SearchFieldDidPressUpArrowNotification | |
object:CPTextFieldInputOwner]; | |
} | |
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; | |
return true; | |
} | |
CPTextFieldKeyUpFunction = function() | |
{ | |
[CPTextFieldInputOwner setStringValue:CPTextFieldDOMInputElement.value]; | |
if ([CPTextFieldInputOwner stringValue] !== CPTextFieldTextDidChangeValue) | |
{ | |
CPTextFieldTextDidChangeValue = [CPTextFieldInputOwner stringValue]; | |
[CPTextFieldInputOwner textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:CPTextFieldInputOwner userInfo:nil]]; | |
} | |
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; | |
} | |
CPTextFieldHandleBlur = function(anEvent) | |
{ | |
var owner = CPTextFieldInputOwner; | |
CPTextFieldInputOwner = nil; | |
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; | |
} | |
if (document.attachEvent) | |
{ | |
CPTextFieldDOMInputElement.attachEvent("on" + CPDOMEventKeyUp, CPTextFieldKeyUpFunction); | |
CPTextFieldDOMInputElement.attachEvent("on" + CPDOMEventKeyDown, CPTextFieldKeyDownFunction); | |
//CPTextFieldDOMInputElement.attachEvent("on" + CPDOMEventKeyPress, CPTextFieldKeyPressFunction); | |
} | |
else | |
{ | |
CPTextFieldDOMInputElement.addEventListener(CPDOMEventKeyUp, CPTextFieldKeyUpFunction, NO); | |
CPTextFieldDOMInputElement.addEventListener(CPDOMEventKeyDown, CPTextFieldKeyDownFunction, NO); | |
//CPTextFieldDOMInputElement.addEventListener(CPDOMEventKeyPress, CPTextFieldKeyPressFunction, NO); | |
} | |
//FIXME make this not onblur | |
CPTextFieldDOMInputElement.onblur = CPTextFieldBlurFunction; | |
CPTextFieldDOMStandardInputElement = CPTextFieldDOMInputElement; | |
} | |
if (CPFeatureIsCompatible(CPInputTypeCanBeChangedFeature)) | |
{ | |
if ([self isSecure]) | |
CPTextFieldDOMInputElement.type = "password"; | |
else | |
CPTextFieldDOMInputElement.type = "text"; | |
return CPTextFieldDOMInputElement; | |
} | |
if ([self isSecure]) | |
{ | |
if (!CPTextFieldDOMPasswordInputElement) | |
{ | |
CPTextFieldDOMPasswordInputElement = document.createElement("input"); | |
CPTextFieldDOMPasswordInputElement.style.position = "absolute"; | |
CPTextFieldDOMPasswordInputElement.style.border = "0px"; | |
CPTextFieldDOMPasswordInputElement.style.padding = "0px"; | |
CPTextFieldDOMPasswordInputElement.style.margin = "0px"; | |
CPTextFieldDOMPasswordInputElement.style.whiteSpace = "pre"; | |
CPTextFieldDOMPasswordInputElement.style.background = "transparent"; | |
CPTextFieldDOMPasswordInputElement.style.outline = "none"; | |
CPTextFieldDOMPasswordInputElement.type = "password"; | |
CPTextFieldDOMPasswordInputElement.attachEvent("on" + CPDOMEventKeyUp, CPTextFieldKeyUpFunction); | |
CPTextFieldDOMPasswordInputElement.attachEvent("on" + CPDOMEventKeyDown, CPTextFieldKeyDownFunction); | |
CPTextFieldDOMPasswordInputElement.attachEvent("on" + CPDOMEventKeyPress, CPTextFieldKeyPressFunction); | |
CPTextFieldDOMPasswordInputElement.onblur = CPTextFieldBlurFunction; | |
} | |
CPTextFieldDOMInputElement = CPTextFieldDOMPasswordInputElement; | |
} | |
else | |
{ | |
CPTextFieldDOMInputElement = CPTextFieldDOMStandardInputElement; | |
} | |
return CPTextFieldDOMInputElement; | |
} | |
- (id)initWithFrame:(CGRect)aFrame | |
{ | |
self = [super initWithFrame:aFrame]; | |
if (self) | |
{ | |
[self setStringValue:@""]; | |
[self setPlaceholderString:@""]; | |
_sendActionOn = CPKeyUpMask | CPKeyDownMask; | |
[self setValue:CPLeftTextAlignment forThemeAttribute:@"alignment"]; | |
} | |
return self; | |
} | |
/*! | |
Sets whether or not the receiver text field can be edited | |
*/ | |
- (void)setEditable:(BOOL)shouldBeEditable | |
{ | |
_isEditable = shouldBeEditable; | |
} | |
/*! | |
Returns <code>YES</code> if |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment