Skip to content

Instantly share code, notes, and snippets.

@saikat
Created September 14, 2009 18:28
Show Gist options
  • Save saikat/186826 to your computer and use it in GitHub Desktop.
Save saikat/186826 to your computer and use it in GitHub Desktop.
// 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