29 @protocol CPTextFieldDelegate <CPControlTextEditingDelegate>
41 @
typedef CPTextFieldBezelStyle
67 if (owner && domElement != inputElement.parentNode)
70 var ownerWindow = [owner window];
72 if (!resigning && [ownerWindow isKeyWindow] && [ownerWindow firstResponder] === owner)
81 [ownerWindow makeFirstResponder:nil];
85 @deref(didBlurRef) = YES;
92 @deref(ownerRef) = nil;
124 BOOL _willBecomeFirstResponderByClick;
125 BOOL _invokedByUserEvent;
127 BOOL _drawsBackground;
129 CPColor _textFieldBackgroundColor;
134 id <CPTextFieldDelegate> _delegate;
135 unsigned _implementedDelegateMethods;
138 CPTextFieldBezelStyle _bezelStyle;
140 BOOL _usesSingleLineMode;
145 + (Class)_binderClassForBinding:(
CPString)aBinding
147 if (aBinding === CPValueBinding)
148 return [_CPTextFieldValueBinder class];
149 else if ([aBinding hasPrefix:CPDisplayPatternValueBinding])
150 return [_CPTextFieldPatternValueBinder class];
151 else if ([aBinding hasPrefix:CPEditableBinding])
154 return [
super _binderClassForBinding:aBinding];
164 var textField = [[
self alloc] initWithFrame:CGRectMake(0.0, 0.0, aWidth, 29.0)];
166 [textField setTheme:aTheme];
167 [textField setStringValue:aStringValue];
168 [textField setPlaceholderString:aPlaceholder];
169 [textField setBordered:YES];
170 [textField setBezeled:YES];
171 [textField setEditable:YES];
173 [textField sizeToFit];
185 var textField = [[
CPTextField alloc] initWithFrame:CGRectMake(0.0, 0.0, aWidth, 29.0)];
187 [textField setTheme:aTheme];
188 [textField setStringValue:aStringValue];
189 [textField setPlaceholderString:aPlaceholder];
190 [textField setBezelStyle:CPTextFieldRoundedBezel];
191 [textField setBordered:YES];
192 [textField setBezeled:YES];
193 [textField setEditable:YES];
195 [textField sizeToFit];
207 var textField = [[
self alloc] init];
209 [textField setStringValue:aTitle];
210 [textField sizeToFit];
223 @"bezel-inset": CGInsetMakeZero(),
224 @"content-inset": CGInsetMake(1.0, 0.0, 0.0, 0.0),
231 #pragma mark Control Size 233 - (void)setControlSize:(CPControlSize)aControlSize
237 if ([
self isBezeled])
238 [
self _sizeToControlSize];
245 - (DOMElement)_inputElement
323 [CPTextFieldInputOwner keyUp:cappEvent];
341 else if (_usesSingleLineMode)
350 - (id)initWithFrame:(CGRect)aFrame
367 #pragma mark Controlling Editability and Selectability 373 - (void)setEditable:(BOOL)shouldBeEditable
375 if (_isEditable === shouldBeEditable)
378 _isEditable = shouldBeEditable;
380 if (shouldBeEditable)
390 [[
self window] makeFirstResponder:nil];
392 if (shouldBeEditable)
412 - (void)setEnabled:(BOOL)shouldBeEnabled
417 if (!shouldBeEnabled && [[
self window] firstResponder] ===
self)
427 - (void)setSelectable:(BOOL)aFlag
429 _isSelectable = aFlag;
439 return _isSelectable;
446 - (void)setSecure:(BOOL)aFlag
464 - (void)setBezeled:(BOOL)shouldBeBezeled
477 return [
self hasThemeState:CPThemeStateBezeled];
484 - (void)setBezelStyle:(CPTextFieldBezelStyle)aBezelStyle
497 - (CPTextFieldBezelStyle)bezelStyle
509 - (void)setBordered:(BOOL)shouldBeBordered
511 if (shouldBeBordered)
522 return [
self hasThemeState:CPThemeStateBordered];
529 - (void)setDrawsBackground:(BOOL)shouldDrawBackground
531 if (_drawsBackground == shouldDrawBackground)
534 _drawsBackground = shouldDrawBackground;
543 - (BOOL)drawsBackground
545 return _drawsBackground;
552 - (void)setTextFieldBackgroundColor:(
CPColor)aColor
554 if (_textFieldBackgroundColor == aColor)
557 _textFieldBackgroundColor = aColor;
568 return _textFieldBackgroundColor;
572 - (void)_setUsesSingleLineMode:(BOOL)aFlag
574 _usesSingleLineMode = aFlag;
578 - (void)_setWraps:(BOOL)aFlag
584 - (void)_setScrolls:(BOOL)aFlag
590 - (BOOL)acceptsFirstResponder
596 - (BOOL)becomeFirstResponder
598 if (![
self isEnabled] || ![super becomeFirstResponder])
602 [
self _setObserveWindowKeyNotifications:YES];
606 if ([[
self window] isKeyWindow] && [
self isEditable])
607 return [
self _becomeFirstKeyResponder];
620 - (BOOL)_becomeFirstKeyResponder
624 if (![
self _isWithinUsablePlatformRect])
629 if (![
self isEditable])
632 [
self setThemeState:CPThemeStateEditing];
634 [
self _updatePlaceholderState];
636 [
self setNeedsLayout];
638 _stringValue = [
self stringValue];
643 [
self _setCSSStyleForInputElement];
645 var element = [
self _inputElement];
646 element.value = _stringValue;
647 _DOMElement.appendChild(element);
651 if (document.attachEvent)
656 [[
self window] platformWindow]._DOMBodyElement.ondrag =
function () {};
657 [[
self window] platformWindow]._DOMBodyElement.onselectstart =
function () {};
664 if (CPTextFieldInputOwner !== self)
668 var previousScrollingOrigin = [
self _scrollToVisibleRectAndReturnPreviousOrigin];
672 [
self _restorePreviousScrollingOrigin:previousScrollingOrigin];
675 if (!_willBecomeFirstResponderByClick)
677 [
self _selectText:self immediately:YES];
681 var point = CGPointMake([
self convertPointFromBase:[[CPApp currentEvent] locationInWindow]].x - [
self currentValueForThemeAttribute:@"content-inset"].left, 0),
682 position = [
CPPlatformString charPositionOfString:[
self stringValue] withFont:[
self font] forPoint:point];
684 [
self setSelectedRange:CPMakeRange(position, 0)];
687 _willBecomeFirstResponderByClick = NO;
701 - (void)_setEnableCSSSelection:(BOOL)shouldEnable
708 _DOMElement.style[CPBrowserStyleProperty(@"user-select")] = shouldEnable ?
@"text" :
@"none";
716 - (void)_setCSSStyleForInputElement
720 var element = [
self _inputElement],
721 font = [
self currentValueForThemeAttribute:@"font"],
722 lineHeight = [font defaultLineHeightForFont],
723 contentRect = [
self contentRectForBounds:[
self bounds]],
724 verticalAlign = [
self currentValueForThemeAttribute:"vertical-alignment"],
725 left = CGRectGetMinX(contentRect);
731 switch (verticalAlign)
734 var topPoint = CGRectGetMinY(contentRect) + "px";
738 var topPoint = (CGRectGetMidY(contentRect) - (lineHeight / 2)) + "px";
742 var topPoint = (CGRectGetMaxY(contentRect) - lineHeight) + "px";
746 var topPoint = CGRectGetMinY(contentRect) + "px";
751 element.style.color = [[
self valueForThemeAttribute:@"text-color" inState:CPTextFieldStatePlaceholder] cssString];
753 element.style.color = [[
self valueForThemeAttribute:@"text-color" inState:CPThemeStateEditing] cssString];
755 switch ([
self alignment])
758 element.style.textAlign =
"center";
762 element.style.textAlign =
"right";
766 element.style.textAlign =
"";
770 element.style.textAlign =
"left";
773 var isTextArea = element.nodeName.toUpperCase() ==
"TEXTAREA";
775 element.style.zIndex = 1000;
776 element.style.top = topPoint;
777 element.style.lineHeight = ROUND(lineHeight) + "px";
778 element.style.height = isTextArea ? CGRectGetHeight(contentRect) + "px" : ROUND(lineHeight) + "px";;
779 element.style.width = CGRectGetWidth(contentRect) + "px";
780 element.style.left = left + "px";
781 element.style.verticalAlign =
"top";
782 element.style.cursor =
"auto";
783 element.style.font = [font cssString];
786 element.style.whiteSpace = _wraps ?
"pre" :
"nowrap";
792 - (BOOL)resignFirstResponder
798 var element = [
self _inputElement],
799 newValue = element.value,
802 if (newValue !== _stringValue)
804 [
self _setStringValue:newValue];
809 if ([
self _valueIsValid:newValue] === NO)
812 var previousScrollingOrigin = [
self _scrollToVisibleRectAndReturnPreviousOrigin];
816 [
self _restorePreviousScrollingOrigin:previousScrollingOrigin];
824 [
self _setObserveWindowKeyNotifications:NO];
826 if ([[
self window] isKeyWindow])
827 [
self _resignFirstKeyResponder];
831 if ([
self isEditable])
835 if ([
self sendsActionOnEndEditing])
844 - (void)_resignFirstKeyResponder
846 [
self unsetThemeState:CPThemeStateEditing];
849 _stringValue = [
self stringValue];
851 _willBecomeFirstResponderByClick = NO;
853 [
self _updatePlaceholderState];
854 [
self setNeedsLayout];
858 var element = [
self _inputElement];
868 if (element.parentNode == _DOMElement)
869 element.parentNode.removeChild(element);
882 if (document.attachEvent)
894 - (void)_setObserveWindowKeyNotifications:(BOOL)shouldObserve
908 - (void)_removeObservers
913 [
super _removeObservers];
914 [
self _setObserveWindowKeyNotifications:NO];
917 - (void)_addObservers
922 [
super _addObservers];
924 if ([[
self window] firstResponder] ===
self)
925 [
self _setObserveWindowKeyNotifications:YES];
930 if (![[
self window] isKeyWindow])
931 [
self _resignFirstKeyResponder];
936 if (!([
self isEnabled] && [
self isEditable]))
939 var wind = [
self window];
941 if ([wind isKeyWindow] && [wind firstResponder] ===
self)
942 if (![
self _becomeFirstKeyResponder])
943 [wind makeFirstResponder:nil];
946 - (BOOL)_valueIsValid:(
CPString)aValue
952 if ([
self _setStringValue:aValue isNewValue:NO errorDescription:@ref(error)] === NO)
954 var acceptInvalidValue = NO;
957 acceptInvalidValue = [_delegate control:self didFailToFormatString:aValue errorDescription:error];
959 if (acceptInvalidValue === NO)
972 - (BOOL)needsPanelToBecomeKey
998 if (![
self isEnabled])
999 return [[
self nextResponder] mouseDown:anEvent];
1002 if ([
self isEditable] && [
self isEnabled])
1004 _willBecomeFirstResponderByClick = YES;
1007 else if ([
self isSelectable])
1009 [
self _setEnableCSSSelection:YES];
1010 if (document.attachEvent)
1021 return [[
self nextResponder] mouseDown:anEvent];
1026 if (![
self isEnabled] || !([
self isSelectable] || [
self isEditable]))
1027 [[
self nextResponder] mouseUp:anEvent];
1028 else if ([
self isSelectable])
1030 if (document.attachEvent)
1041 if ([[
CPApp currentEvent] clickCount] === 3)
1053 if ([
self menuForEvent:anEvent] || [[
self nextResponder] isKindOfClass:
CPView])
1061 if (![
self isEnabled] || !([
self isSelectable] || [
self isEditable]))
1062 [[
self nextResponder] mouseDragged:anEvent];
1063 else if ([
self isSelectable])
1069 if (!([
self isEnabled] && [
self isEditable]))
1073 var newValue = [
self _inputElement].value;
1075 if (newValue !== _stringValue)
1077 [
self _setStringValue:newValue];
1087 if (!([
self isEnabled] && [
self isEditable]))
1098 _invokedByUserEvent = !!anEvent._DOMEvent;
1099 [
self interpretKeyEvents:[anEvent]];
1100 _invokedByUserEvent = NO;
1114 - (void)doCommandBySelector:(
SEL)aSelector
1116 if ([
self respondsToSelector:aSelector])
1117 [
self performSelector:aSelector];
1120 - (void)insertNewline:(
id)sender
1122 if (!([
self isEnabled] && [
self isEditable]))
1125 var newValue = [
self _inputElement].value;
1127 if (newValue !== _stringValue)
1129 [
self _setStringValue:newValue];
1133 if ([
self _valueIsValid:_stringValue])
1148 if (![
self action] || [
self sendAction:[
self action] to:[
self target]])
1157 - (void)insertNewlineIgnoringFieldEditor:(
id)sender
1159 [
self _insertCharacterIgnoringFieldEditor:CPNewlineCharacter];
1162 - (void)insertTabIgnoringFieldEditor:(
id)sender
1164 [
self _insertCharacterIgnoringFieldEditor:CPTabCharacter];
1167 - (void)_insertCharacterIgnoringFieldEditor:(
CPString)aCharacter
1169 if (!([
self isEnabled] && [
self isEditable]))
1174 var oldValue = _stringValue,
1175 range = [
self selectedRange],
1176 element = [
self _inputElement];
1181 element.value = [element.value stringByReplacingCharactersInRange:[
self selectedRange] withString:aCharacter];
1183 [
self _setStringValue:element.value];
1186 if (oldValue !== _stringValue)
1197 if ([note
object] !=
self)
1201 [_delegate controlTextDidBlur:note];
1209 if ([note
object] !==
self)
1213 [_delegate controlTextDidFocus:note];
1220 if ([note
object] !==
self)
1223 [
self _continuouslyReverseSetBinding];
1226 [_delegate controlTextDidChange:note];
1234 if ([note
object] !=
self)
1246 if ([note
object] !=
self)
1252 [_delegate controlTextDidEndEditing:note];
1267 - (BOOL)_setStringValue:(
CPString)aValue
1269 return [
self _setStringValue:aValue isNewValue:YES errorDescription:nil];
1276 - (BOOL)_setStringValue:(
CPString)aValue isNewValue:(BOOL)isNewValue errorDescription:(CPStringRef)anError
1278 _stringValue = aValue;
1280 var objectValue = aValue,
1281 formatter = [
self formatter],
1288 if ([formatter getObjectValue:@ref(
object) forString:aValue errorDescription:anError])
1289 objectValue =
object;
1292 objectValue = undefined;
1296 isNewValue |= objectValue !== [
super objectValue];
1301 [
self willChangeValueForKey:@"objectValue"];
1302 [
super setObjectValue:objectValue];
1303 [
self _updatePlaceholderState];
1304 [
self didChangeValueForKey:@"objectValue"];
1310 - (void)setObjectValue:(
id)aValue
1312 [
self _setObjectValue:aValue useFormatter:YES];
1315 - (void)_setObjectValue:(
id)aValue useFormatter:(BOOL)useFormatter
1317 [
super setObjectValue:aValue];
1319 var formatter = [
self formatter];
1321 if (useFormatter && formatter)
1324 var formattedString = [
self hasThemeState:CPThemeStateEditing] ? [formatter editingStringForObjectValue:aValue] : [formatter stringForObjectValue:aValue];
1326 if (formattedString === nil)
1332 if ([formatter getObjectValue:@ref(value) forString:
@"" errorDescription:nil] === NO)
1335 [
super setObjectValue:value];
1336 _stringValue = (value === nil || value === undefined) ?
@"" : String(value);
1339 _stringValue = formattedString;
1342 _stringValue = [
self stringValue];
1346 if ((
CPTextFieldInputOwner ===
self || [[
self window] firstResponder] ===
self) && [[
self window] isKeyWindow])
1347 [
self _inputElement].value = _stringValue;
1351 [
self _updatePlaceholderState];
1354 - (void)_updatePlaceholderState
1356 if (!_stringValue || _stringValue.
length === 0)
1357 [
self setThemeState:CPTextFieldStatePlaceholder];
1359 [
self unsetThemeState:CPTextFieldStatePlaceholder];
1368 if (_placeholderString === aStringValue)
1371 _placeholderString = aStringValue;
1386 return _placeholderString;
1414 - (CGSize)_minimumFrameSize
1416 var frameSize = [
self frameSize],
1417 contentInset = [
self currentValueForThemeAttribute:@"content-inset"],
1418 minSize = [
self currentValueForThemeAttribute:@"min-size"],
1419 maxSize = [
self currentValueForThemeAttribute:@"max-size"],
1420 lineBreakMode = [
self lineBreakMode],
1421 text = (_stringValue ||
@" "),
1422 textSize = CGSizeMakeCopy(frameSize),
1423 font = [
self currentValueForThemeAttribute:@"font"];
1425 textSize.width -= contentInset.left + contentInset.right;
1426 textSize.height -= contentInset.top + contentInset.bottom;
1428 if (frameSize.width !== 0 &&
1429 ![
self isBezeled] &&
1432 textSize = [text sizeWithFont:font inWidth:textSize.width];
1436 textSize = [text sizeWithFont:font];
1439 textSize.width += 1;
1443 textSize.height += 1;
1445 frameSize.height = textSize.height + contentInset.top + contentInset.bottom;
1447 if ([
self isBezeled])
1449 frameSize.height = MAX(frameSize.height, minSize.height);
1451 if (maxSize.width > 0.0)
1452 frameSize.width = MIN(frameSize.width, maxSize.width);
1454 if (maxSize.height > 0.0)
1455 frameSize.height = MIN(frameSize.height, maxSize.height);
1458 frameSize.width = textSize.width + contentInset.left + contentInset.right;
1460 frameSize.width = MAX(frameSize.width, minSize.width);
1468 - (void)selectText:(
id)sender
1470 [
self _selectText:sender immediately:NO];
1473 - (void)_selectText:(
id)sender immediately:(BOOL)immediately
1476 if ([
self isEditable] || [
self isSelectable])
1478 var wind = [
self window];
1481 if ([
self isEditable])
1483 var element = [
self _inputElement];
1485 if ([wind firstResponder] ===
self)
1492 else if (wind !== nil && [wind makeFirstResponder:
self])
1493 [
self _selectText:sender immediately:immediately];
1497 [
self setSelectedRange:CPMakeRange(0, _stringValue.length)];
1502 if (wind !== nil && [wind firstResponder] !==
self)
1503 [wind makeFirstResponder:self];
1509 - (void)copy:(
id)sender
1512 var stringToCopy = nil;
1514 if ([
self isEditable])
1518 if (selectedRange.length < 1)
1521 stringToCopy = [_stringValue substringWithRange:selectedRange];
1534 [pasteboard declareTypes:[CPStringPboardType] owner:nil];
1535 [pasteboard setString:stringToCopy forType:CPStringPboardType];
1544 - (void)cut:(
id)sender
1546 if (![
self isEnabled])
1551 if (![
self isEditable])
1554 if (![[
CPApp currentEvent] _platformIsEffectingCutOrPaste])
1569 - (void)paste:(
id)sender
1571 if (!([
self isEnabled] && [
self isEditable]))
1574 if (![[
CPApp currentEvent] _platformIsEffectingCutOrPaste])
1584 pasteString = [pasteboard stringForType:CPStringPboardType],
1585 newValue = [_stringValue stringByReplacingCharactersInRange:selectedRange withString:pasteString];
1589 [
self setSelectedRange:CPMakeRange(selectedRange.location + pasteString.length, 0)];
1602 - (CPRange)selectedRange
1606 if ([[
self window] firstResponder] !==
self)
1614 var inputElement = [
self _inputElement],
1615 selectionStart = inputElement.selectionStart,
1616 selectionEnd = inputElement.selectionEnd;
1618 if ([selectionStart isKindOfClass:
CPNumber])
1619 return CPMakeRange(selectionStart, selectionEnd - selectionStart);
1622 var theDocument = inputElement.ownerDocument || inputElement.document,
1623 selectionRange = theDocument.selection.createRange(),
1624 range = inputElement.createTextRange();
1626 if (range.inRange(selectionRange))
1628 range.setEndPoint(
'EndToStart', selectionRange);
1629 return CPMakeRange(range.text.length, selectionRange.text.length);
1642 - (void)setSelectedRange:(CPRange)aRange
1644 if (![[
self window] firstResponder] ===
self)
1649 if (![
self isEditable])
1657 [contentView setSelectedRange:aRange];
1662 var inputElement = [
self _inputElement];
1666 if ([inputElement.selectionStart isKindOfClass:
CPNumber])
1668 inputElement.selectionStart = aRange.location;
1669 inputElement.selectionEnd =
CPMaxRange(aRange);
1674 var theDocument = inputElement.ownerDocument || inputElement.document,
1675 existingRange = theDocument.selection.createRange(),
1676 range = inputElement.createTextRange();
1678 if (range.inRange(existingRange))
1680 range.collapse(
true);
1681 range.move(
'character', aRange.location);
1682 range.moveEnd(
'character', aRange.length);
1694 - (void)selectAll:(
id)sender
1699 - (void)deleteBackward:(
id)sender
1701 if (!([
self isEnabled] && [
self isEditable]))
1706 if (selectedRange.length === 0)
1708 if (selectedRange.location < 1)
1712 selectedRange.location -= 1;
1713 selectedRange.length += 1;
1716 [
self _replaceCharactersInRange:selectedRange withCharacters:@""];
1719 - (void)delete:(
id)sender
1721 if (!([
self isEnabled] && [
self isEditable]))
1727 if (selectedRange.length < 1)
1730 [
self _replaceCharactersInRange:selectedRange withCharacters:@""];
1733 - (void)deleteForward:(
id)sender
1735 if (!([
self isEnabled] && [
self isEditable]))
1740 if (selectedRange.length === 0)
1742 if (selectedRange.location >= _stringValue.
length)
1746 selectedRange.length += 1;
1749 [
self _replaceCharactersInRange:selectedRange withCharacters:@""];
1752 - (void)_replaceCharactersInRange:(CPRange)range withCharacters:(
CPString)characters
1754 var newValue = [_stringValue stringByReplacingCharactersInRange:range withString:characters];
1756 if (_invokedByUserEvent)
1758 [
self _setStringValue:newValue];
1762 [
self _setObjectValue:newValue useFormatter:NO];
1763 [
self setSelectedRange:CPMakeRange(range.location, 0)];
1767 [[[
self window] platformWindow] _propagateCurrentDOMEvent:NO];
1774 #pragma mark Setting the Delegate 1776 - (void)setDelegate:(
id <CPTextFieldDelegate>)aDelegate
1778 if (_delegate === aDelegate)
1781 _delegate = aDelegate;
1782 _implementedDelegateMethods = 0;
1784 if ([_delegate respondsToSelector:
@selector(control:didFailToFormatString:errorDescription:)])
1787 if ([_delegate respondsToSelector:
@selector(controlTextDidBeginEditing:)])
1790 if ([_delegate respondsToSelector:
@selector(controlTextDidChange:)])
1793 if ([_delegate respondsToSelector:
@selector(controlTextDidEndEditing:)])
1796 if ([_delegate respondsToSelector:
@selector(controlTextDidFocus:)])
1799 if ([_delegate respondsToSelector:
@selector(controlTextDidBlur:)])
1808 - (CGRect)contentRectForBounds:(CGRect)bounds
1810 var contentInset = [
self currentValueForThemeAttribute:@"content-inset"];
1812 return CGRectInsetByInset(
bounds, contentInset);
1815 - (CGRect)bezelRectForBounds:(CGRect)bounds
1817 var bezelInset = [
self currentValueForThemeAttribute:@"bezel-inset"];
1819 return CGRectInsetByInset(
bounds, bezelInset);
1824 if (aName ===
"bezel-view")
1827 else if (aName ===
"content-view")
1835 if (aName ===
"bezel-view")
1837 var view = [[
CPView alloc] initWithFrame:CGRectMakeZero()];
1839 [view setHitTests:NO];
1845 var view = [[_CPImageAndTextView alloc] initWithFrame:CGRectMakeZero()];
1847 [view setHitTests:NO];
1855 - (void)layoutSubviews
1862 [bezelView setBackgroundColor:[
self currentValueForThemeAttribute:@"bezel-color"]];
1870 [contentView setHidden:(_stringValue && _stringValue.length > 0) && [
self hasThemeState:CPThemeStateEditing]];
1878 string = _stringValue;
1880 if ([
self isSecure])
1884 [contentView setText:string];
1886 [contentView setTextColor:[
self currentValueForThemeAttribute:@"text-color"]];
1887 [contentView setFont:[
self currentValueForThemeAttribute:@"font"]];
1888 [contentView setAlignment:[
self currentValueForThemeAttribute:@"alignment"]];
1889 [contentView setVerticalAlignment:[
self currentValueForThemeAttribute:@"vertical-alignment"]];
1890 [contentView setLineBreakMode:[
self currentValueForThemeAttribute:@"line-break-mode"]];
1891 [contentView setTextShadowColor:[
self currentValueForThemeAttribute:@"text-shadow-color"]];
1892 [contentView setTextShadowOffset:[
self currentValueForThemeAttribute:@"text-shadow-offset"]];
1896 [
self _setCSSStyleForInputElement];
1899 - (void)takeValueFromKeyPath:(
CPString)aKeyPath ofObjects:(CPArray)objects
1901 var count = objects.
length,
1902 value = [objects[0] valueForKeyPath:aKeyPath];
1908 if (value !== [objects[count] valueForKeyPath:aKeyPath])
1915 #pragma mark Overrides 1925 var placeholderColor = [
self valueForThemeAttribute:@"text-color" inState:CPTextFieldStatePlaceholder];
1935 if ([[
self window] firstResponder] ===
self)
1936 [
self _resignFirstKeyResponder];
1939 - (void)viewDidUnhide
1943 if ([
self isEditable] && [[
self window] firstResponder] ===
self)
1944 [
self _becomeFirstKeyResponder];
1947 - (BOOL)validateUserInterfaceItem:(
id )anItem
1949 var theAction = [anItem action];
1951 if (![
self isEditable] && (theAction ==
@selector(cut:) || theAction ==
@selector(paste:) || theAction ==
@selector(
delete:)))
1955 if (![
self isEditable])
1958 if (theAction ==
@selector(copy:) || theAction ==
@selector(cut:) || theAction ==
@selector(
delete:))
1964 #pragma mark Private 1966 - (BOOL)_isWithinUsablePlatformRect
1971 var wind = [
self window];
1977 var scrollView = [
self enclosingScrollView],
1978 previousContentViewBoundsOrigin;
1981 var previousScrollingOrigin = [
self _scrollToVisibleRectAndReturnPreviousOrigin];
1983 var
frame = [
self convertRectToBase:[
self contentRectForBounds:[
self bounds]]],
1984 usableRect = [[wind platformWindow] usableContentFrame];
1986 frame.origin = [wind convertBaseToGlobal:frame.origin];
1989 [
self _restorePreviousScrollingOrigin:previousScrollingOrigin];
1991 return (CGRectGetMinX(
frame) >= CGRectGetMinX(usableRect) &&
1992 CGRectGetMaxX(
frame) <= CGRectGetMaxX(usableRect) &&
1993 CGRectGetMinY(
frame) >= CGRectGetMinY(usableRect) &&
1994 CGRectGetMaxY(
frame) <= CGRectGetMaxY(usableRect));
2000 - (CGPoint)_scrollToVisibleRectAndReturnPreviousOrigin
2002 var scrollView = [
self enclosingScrollView],
2003 previousContentViewBoundsOrigin;
2008 previousContentViewBoundsOrigin = CGPointMakeCopy([[scrollView contentView] boundsOrigin]);
2010 if (![[
self superview] scrollRectToVisible:[
self frame]])
2011 previousContentViewBoundsOrigin = nil;
2014 return previousContentViewBoundsOrigin;
2020 - (void)_restorePreviousScrollingOrigin:(CGPoint)scrollingOrigin
2022 if (scrollingOrigin)
2023 [[[
self enclosingScrollView] contentView] setBoundsOrigin:scrollingOrigin];
2066 [
self setEditable:[aCoder decodeBoolForKey:CPTextFieldIsEditableKey]];
2067 [
self setSelectable:[aCoder decodeBoolForKey:CPTextFieldIsSelectableKey]];
2073 [
self setLineBreakMode:[aCoder decodeIntForKey:CPTextFieldLineBreakModeKey]];
2074 [
self setAlignment:[aCoder decodeIntForKey:CPTextFieldAlignmentKey]];
2078 [
self _setUsesSingleLineMode:[aCoder decodeBoolForKey:CPTextFieldUsesSingleLineMode]];
2079 [
self _setWraps:[aCoder decodeBoolForKey:CPTextFieldWraps]];
2080 [
self _setScrolls:[aCoder decodeBoolForKey:CPTextFieldScrolls]];
2094 [aCoder encodeBool:_isEditable forKey:CPTextFieldIsEditableKey];
2095 [aCoder encodeBool:_isSelectable forKey:CPTextFieldIsSelectableKey];
2097 [aCoder encodeBool:_drawsBackground forKey:CPTextFieldDrawsBackgroundKey];
2099 [aCoder encodeObject:_textFieldBackgroundColor forKey:CPTextFieldBackgroundColorKey];
2101 [aCoder encodeInt:[
self lineBreakMode] forKey:CPTextFieldLineBreakModeKey];
2102 [aCoder encodeInt:[
self alignment] forKey:CPTextFieldAlignmentKey];
2104 [aCoder encodeObject:_placeholderString forKey:CPTextFieldPlaceholderStringKey];
2106 [aCoder encodeBool:_usesSingleLineMode forKey:CPTextFieldUsesSingleLineMode];
2107 [aCoder encodeBool:_wraps forKey:CPTextFieldWraps];
2108 [aCoder encodeBool:_scrolls forKey:CPTextFieldScrolls];
2112 @implementation _CPTextFieldValueBinder :
CPBinder 2119 [
super _updatePlaceholdersWithOptions:options];
2121 [
self _setPlaceholder:@"Multiple Values" forMarker:CPMultipleValuesMarker isDefault:YES];
2122 [
self _setPlaceholder:@"No Selection" forMarker:CPNoSelectionMarker isDefault:YES];
2123 [
self _setPlaceholder:@"Not Applicable" forMarker:CPNotApplicableMarker isDefault:YES];
2124 [
self _setPlaceholder:@"" forMarker:CPNullMarker isDefault:YES];
2127 - (void)setPlaceholderValue:(
id)aValue withMarker:(
CPString)aMarker forBinding:(
CPString)aBinding
2129 [_source setPlaceholderString:aValue];
2130 [_source setObjectValue:nil];
2133 - (void)setValue:(
id)aValue forBinding:(
CPString)aBinding
2135 if (!aValue || (aValue.isa && [aValue isMemberOfClass:
CPNull]))
2136 [_source setPlaceholderString:[
self _placeholderForMarker:CPNullMarker]];
2138 [_source setObjectValue:aValue];
2141 - (void)reverseSetValueFor:(
CPString)aBinding
2143 var destination = [_info objectForKey:CPObservedObjectKey],
2144 keyPath = [_info objectForKey:CPObservedKeyPathKey],
2145 options = [_info objectForKey:CPOptionsKey],
2146 newValue = [
self valueForBinding:aBinding],
2147 value = [destination valueForKeyPath:keyPath];
2149 if (CPIsControllerMarker(value) && newValue === nil)
2152 newValue = [
self reverseTransformValue:newValue withOptions:options];
2154 [
self suppressSpecificNotificationFromObject:destination keyPath:keyPath];
2155 [destination setValue:newValue forKeyPath:keyPath];
2156 [
self unsuppressSpecificNotificationFromObject:destination keyPath:keyPath];
2165 - (void)setPlaceholderValue:(
id)aValue withMarker:(
CPString)aMarker forBinding:(
CPString)aBinding
2167 [_source setPlaceholderString:aValue];
2168 [_source setObjectValue:nil];
2171 - (void)setValue:(
id)aValue forBinding:(
CPString)aBinding
2173 if (!aValue || (aValue.isa && [aValue isMemberOfClass:
CPNull]))
2174 [_source setPlaceholderString:[
self _placeholderForMarker:CPNullMarker]];
2176 [_source setObjectValue:aValue];
2186 - (void)updateTrackingAreas
2188 if (_textFieldTrackingArea)
2191 _textFieldTrackingArea = nil;
2194 if ([
self isEnabled] && (_isEditable || _isSelectable))
2196 var myBounds = CGRectMakeCopy([
self bounds]),
2197 contentInset = [
self currentValueForThemeAttribute:@"content-inset"];
2200 options:CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow
2226 - (void)setValue:(
id)aValue forThemeAttribute:(
CPString)aName
CPEvent keyEventWithType:location:modifierFlags:timestamp:windowNumber:context:characters:charactersIgnoringModifiers:isARepeat:keyCode:(CPEventType anEventType, [location] CGPoint aPoint, [modifierFlags] unsigned int modifierFlags, [timestamp] CPTimeInterval aTimestamp, [windowNumber] int aWindowNumber, [context] CPGraphicsContext aGraphicsContext, [characters] CPString characters, [charactersIgnoringModifiers] CPString unmodCharacters, [isARepeat] BOOL repeatKey, [keyCode] unsigned short code)
BOOL makeFirstResponder:(CPResponder aResponder)
void setDrawsBackground:(BOOL shouldDrawBackground)
var CPTextFieldDOMStandardInputElement
void postNotification:(CPNotification aNotification)
var CPTextFieldIsBorderedKey
var CPTextFieldIsBezeledKey
var CPTextFieldAlignmentKey
BOOL setThemeState:(ThemeState aState)
var CPTextFieldTextDidChangeValue
void selectText:(id sender)
void setValue:forThemeAttribute:inState:(id aValue, [forThemeAttribute] CPString aName, [inState] ThemeState aState)
An object representation of nil.
var CPTextFieldCachedSelectStartFunction
void setSelectedRange:(CPRange aRange)
var CPTextFieldDelegate_controlTextDidBeginEditing_
The main run loop for the application.
var CPTextFieldDelegate_controlTextDidEndEditing_
CPTextField labelWithTitle:theme:(CPString aTitle, [theme] CPTheme aTheme)
void addObserver:selector:name:object:(id anObserver, [selector] SEL aSelector, [name] CPString aNotificationName, [object] id anObject)
void setLineBreakMode:(CPLineBreakMode mode)
var CPTextFieldInputOwner
CPResponder firstResponder()
void textDidChange:(CPNotification note)
var CPTextFieldDelegate_controlTextDidBlur_
var CPTextFieldInputFunction
function CPTextFieldHandleBlur(anEvent, ownerRef)
CPInputOnInputEventFeature
void selectAll:(id sender)
CPLineBreakByCharWrapping
CPTextField textFieldWithStringValue:placeholder:width:theme:(CPString aStringValue, [placeholder] CPString aPlaceholder, [width] float aWidth, [theme] CPTheme aTheme)
void textDidBeginEditing:(CPNotification note)
void textDidEndEditing:(CPNotification note)
id initWithFrame:(CGRect aFrame)
CPTextFieldDidBlurNotification
void deleteBackward:(id sender)
void setControlSize:(CPControlSize aControlSize)
void setEnabled:(BOOL isEnabled)
void setValue:forThemeAttribute:(id aValue, [forThemeAttribute] CPString aName)
CPTextFieldBezelStyle CPTextFieldSquareBezel
CPNotificationCenter defaultCenter()
A mutable key-value pair collection.
void rightMouseDown:(CPEvent anEvent)
var CPTextFieldIsSelectableKey
CPRunLoop currentRunLoop()
void setEditable:(BOOL shouldBeEditable)
void textDidBlur:(CPNotification note)
var CPTextFieldCachedDragFunction
CPView createEphemeralSubviewNamed:(CPString aViewName)
id initWithName:object:userInfo:(CPString aNotificationName, [object] id anObject, [userInfo] CPDictionary aUserInfo)
void setPlaceholderString:(CPString aStringValue)
function CPMaxRange(aRange)
An immutable string (collection of characters).
CPAltEnterTextAreaFeature
if(CPFeatureIsCompatible(CPHTMLCanvasFeature))
var CPTextFieldInputIsActive
BOOL sendAction:to:(SEL anAction, [to] id anObject)
function CPFeatureIsCompatible(aFeature)
id initWithCoder:(CPCoder aCoder)
var CPTextFieldBezelStyleKey
void performBlock:argument:order:modes:(Function aBlock, [argument] id anArgument, [order] int anOrder, [modes] CPArray modes)
BOOL acceptsFirstResponder()
void setTextColor:(CPColor aColor)
var CPTextFieldDOMPasswordInputElement
CGRect contentRectForBounds:(CGRect bounds)
void setNeedsDisplay:(BOOL aFlag)
var CPTextFieldPlaceholderStringKey
var CPTextFieldDelegate_controlTextDidChange_
CPTextAlignment alignment()
var CPSecureTextFieldCharacter
CGRect bezelRectForBounds:(CGRect bounds)
CPVerticalTextAlignment CPTopVerticalTextAlignment
var secureStringForString
void setStringValue:(CPString aString)
A notification that can be posted to a CPNotificationCenter.
CPTimer scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:(CPTimeInterval seconds, [target] id aTarget, [selector] SEL aSelector, [userInfo] id userInfo, [repeats] BOOL shouldRepeat)
CPDate limitDateForMode:(CPString aMode)
var CPTextFieldIsEditableKey
CPBottomVerticalTextAlignment
var CPTextFieldDOMCurrentElement
A timer object that can send a message after the given time interval.
Defines methods for use when archiving & restoring (enc/decoding).
void setAlignment:(CPTextAlignment alignment)
BOOL unsetThemeState:(ThemeState aState)
Sends messages (CPNotification) between objects.
CPNotification notificationWithName:object:userInfo:(CPString aNotificationName, [object] id anObject, [userInfo] CPDictionary aUserInfo)
CPString placeholderString()
void addTrackingArea:(CPTrackingArea trackingArea)
void setSelectable:(BOOL aFlag)
CPLineBreakMode lineBreakMode()
CPTimeInterval currentTimestamp()
void setValue:forThemeAttribute:(id aValue, [forThemeAttribute] CPString aName)
var CPTextFieldDelegate_controlTextDidFocus_
var CPTextFieldLineBreakModeKey
var CPTextFieldBlurHandler
void textDidEndEditing:(CPNotification note)
CPTextField roundedTextFieldWithStringValue:placeholder:width:theme:(CPString aStringValue, [placeholder] CPString aPlaceholder, [width] float aWidth, [theme] CPTheme aTheme)
var CPTextFieldInputDidBlur
CPLineBreakMode CPLineBreakByWordWrapping
void setFrameSize:(CGSize aSize)
var CPTextFieldUsesSingleLineMode
var CPTextFieldDOMTextAreaElement
void updateTrackingAreas()
CPTextFieldStatePlaceholder
void removeObserver:name:object:(id anObserver, [name] CPString aNotificationName, [object] id anObject)
var CPTexFieldCurrentCSSSelectableField
var CPTextFieldDrawsBackgroundKey
void setTextFieldBackgroundColor:(CPColor aColor)
var CPTextFieldBackgroundColorKey
CPTrackingArea initWithRect:options:owner:userInfo:(CGRect aRect, [options] CPTrackingAreaOptions options, [owner] id owner, [userInfo] CPDictionary userInfo)
CPPlatformWindow platformWindow()
void updateTrackingAreas()
CPTextFieldDidFocusNotification
var CPTextFieldInputResigning
A bridged object to native Javascript numbers.
void encodeWithCoder:(CPCoder aCoder)
CPRange function CPMakeRange(location, length)
function CPTextFieldBlurFunction(anEvent, owner, domElement, inputElement, resigning, didBlurRef)
var CPTextFieldDelegate_control_didFailToFormatString_errorDescription_
CPView layoutEphemeralSubviewNamed:positioned:relativeToEphemeralSubviewNamed:(CPString aViewName, [positioned] CPWindowOrderingMode anOrderingMode, [relativeToEphemeralSubviewNamed] CPString relativeToViewName)
void removeTrackingArea:(CPTrackingArea trackingArea)
CPCenterVerticalTextAlignment
CGRect rectForEphemeralSubviewNamed:(CPString aViewName)