summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorrohitrao@chromium.org <rohitrao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-06 00:57:40 +0000
committerrohitrao@chromium.org <rohitrao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-06 00:57:40 +0000
commitde1509c9e4b7322ef13b754acd4f500916b2e0f7 (patch)
treef35e47690f4ce382a18fa2e47493dfce8a6c0870 /chrome
parent189cf275c82afe58c656066cc4137ce9e95ece48 (diff)
downloadchromium_src-de1509c9e4b7322ef13b754acd4f500916b2e0f7.zip
chromium_src-de1509c9e4b7322ef13b754acd4f500916b2e0f7.tar.gz
chromium_src-de1509c9e4b7322ef13b754acd4f500916b2e0f7.tar.bz2
[Mac] Draw the results label correctly in the findbar.
Adds common base classes (StyledTextField and StyledTextFieldCell) for both the find bar and omnibox text fields. BUG=http://crbug.com/19550 TEST=Findbar results label should not be overdrawn by find text. TEST=Autocomplete drawing (keyword, hint, lock icon) should not be affected. Review URL: http://codereview.chromium.org/319005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31186 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/nibs/FindBar.xib218
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field.h14
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field.mm56
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_cell.h26
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_cell.mm73
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm33
-rw-r--r--chrome/browser/cocoa/find_bar_cocoa_controller.h4
-rw-r--r--chrome/browser/cocoa/find_bar_cocoa_controller.mm31
-rw-r--r--chrome/browser/cocoa/find_bar_cocoa_controller_unittest.mm8
-rw-r--r--chrome/browser/cocoa/find_bar_text_field.h21
-rw-r--r--chrome/browser/cocoa/find_bar_text_field.mm25
-rw-r--r--chrome/browser/cocoa/find_bar_text_field_cell.h24
-rw-r--r--chrome/browser/cocoa/find_bar_text_field_cell.mm109
-rw-r--r--chrome/browser/cocoa/find_bar_text_field_cell_unittest.mm138
-rw-r--r--chrome/browser/cocoa/find_bar_text_field_unittest.mm92
-rw-r--r--chrome/browser/cocoa/styled_text_field.h29
-rw-r--r--chrome/browser/cocoa/styled_text_field.mm65
-rw-r--r--chrome/browser/cocoa/styled_text_field_cell.h31
-rw-r--r--chrome/browser/cocoa/styled_text_field_cell.mm83
-rw-r--r--chrome/browser/cocoa/styled_text_field_cell_unittest.mm97
-rw-r--r--chrome/browser/cocoa/styled_text_field_test_helper.h16
-rw-r--r--chrome/browser/cocoa/styled_text_field_test_helper.mm18
-rw-r--r--chrome/browser/cocoa/styled_text_field_unittest.mm198
-rwxr-xr-xchrome/chrome.gyp14
24 files changed, 1086 insertions, 337 deletions
diff --git a/chrome/app/nibs/FindBar.xib b/chrome/app/nibs/FindBar.xib
index 7561a88..9965871 100644
--- a/chrome/app/nibs/FindBar.xib
+++ b/chrome/app/nibs/FindBar.xib
@@ -1,18 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
-<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.03">
<data>
<int key="IBDocument.SystemTarget">1050</int>
- <string key="IBDocument.SystemVersion">10B504</string>
- <string key="IBDocument.InterfaceBuilderVersion">732</string>
- <string key="IBDocument.AppKitVersion">1038.2</string>
- <string key="IBDocument.HIToolboxVersion">437.00</string>
- <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
- <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string key="NS.object.0">732</string>
- </object>
+ <string key="IBDocument.SystemVersion">9L31a</string>
+ <string key="IBDocument.InterfaceBuilderVersion">677</string>
+ <string key="IBDocument.AppKitVersion">949.54</string>
+ <string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="29"/>
+ <integer value="2"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -20,7 +16,7 @@
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys" id="0">
+ <object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
@@ -48,23 +44,24 @@
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSTextField" id="445667">
+ <object class="NSTextField" id="510660793">
<reference key="NSNextResponder" ref="612665518"/>
<int key="NSvFlags">290</int>
- <string key="NSFrame">{{200, 3}, {31, 22}}</string>
+ <string key="NSFrame">{{13, 5}, {216, 24}}</string>
<reference key="NSSuperview" ref="612665518"/>
<bool key="NSEnabled">YES</bool>
- <object class="NSTextFieldCell" key="NSCell" id="236923920">
- <int key="NSCellFlags">-1542324672</int>
- <int key="NSCellFlags2">71304192</int>
+ <object class="NSTextFieldCell" key="NSCell" id="926027568">
+ <int key="NSCellFlags">-1804468671</int>
+ <int key="NSCellFlags2">272630784</int>
<string key="NSContents"/>
<object class="NSFont" key="NSSupport" id="197084721">
<string key="NSName">LucidaGrande</string>
- <double key="NSSize">13</double>
+ <double key="NSSize">1.300000e+01</double>
<int key="NSfFlags">1044</int>
</object>
- <reference key="NSControlView" ref="445667"/>
- <object class="NSColor" key="NSBackgroundColor" id="649287797">
+ <reference key="NSControlView" ref="510660793"/>
+ <bool key="NSDrawsBackground">YES</bool>
+ <object class="NSColor" key="NSBackgroundColor">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">textBackgroundColor</string>
@@ -74,26 +71,6 @@
</object>
</object>
<object class="NSColor" key="NSTextColor">
- <int key="NSColorSpace">1</int>
- <bytes key="NSRGB">MC42MTk1NjUyNSAwLjYxOTU2NTI1IDAuNjE5NTY1MjUAA</bytes>
- </object>
- </object>
- </object>
- <object class="NSTextField" id="510660793">
- <reference key="NSNextResponder" ref="612665518"/>
- <int key="NSvFlags">290</int>
- <string key="NSFrame">{{13, 6}, {216, 22}}</string>
- <reference key="NSSuperview" ref="612665518"/>
- <bool key="NSEnabled">YES</bool>
- <object class="NSTextFieldCell" key="NSCell" id="926027568">
- <int key="NSCellFlags">-1804468671</int>
- <int key="NSCellFlags2">272630784</int>
- <string key="NSContents"/>
- <reference key="NSSupport" ref="197084721"/>
- <reference key="NSControlView" ref="510660793"/>
- <bool key="NSDrawsBackground">YES</bool>
- <reference key="NSBackgroundColor" ref="649287797"/>
- <object class="NSColor" key="NSTextColor">
<int key="NSColorSpace">6</int>
<string key="NSCatalogName">System</string>
<string key="NSColorName">textColor</string>
@@ -115,8 +92,8 @@
<int key="NSCellFlags2">134217728</int>
<string key="NSContents"/>
<reference key="NSSupport" ref="197084721"/>
- <reference key="NSControlView" ref="455192438"/>
<int key="NSTag">2</int>
+ <reference key="NSControlView" ref="455192438"/>
<int key="NSButtonFlags">-2033958657</int>
<int key="NSButtonFlags2">134</int>
<object class="NSCustomResource" key="NSNormalImage">
@@ -140,8 +117,8 @@
<int key="NSCellFlags2">134217728</int>
<string key="NSContents"/>
<reference key="NSSupport" ref="197084721"/>
- <reference key="NSControlView" ref="968135285"/>
<int key="NSTag">1</int>
+ <reference key="NSControlView" ref="968135285"/>
<int key="NSButtonFlags">-2033434369</int>
<int key="NSButtonFlags2">134</int>
<object class="NSCustomResource" key="NSNormalImage">
@@ -234,14 +211,6 @@
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
- <string key="label">resultsLabel_</string>
- <reference key="source" ref="1001"/>
- <reference key="destination" ref="445667"/>
- </object>
- <int key="connectionID">19</int>
- </object>
- <object class="IBConnectionRecord">
- <object class="IBOutletConnection" key="connection">
<string key="label">nextButton_</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="968135285"/>
@@ -278,26 +247,28 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBObjectRecord">
<int key="objectID">0</int>
- <reference key="object" ref="0"/>
+ <object class="NSArray" key="object" id="482098745">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="1001"/>
- <reference key="parent" ref="0"/>
- <string key="objectName">File's Owner</string>
+ <reference key="parent" ref="482098745"/>
+ <string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="1003"/>
- <reference key="parent" ref="0"/>
+ <reference key="parent" ref="482098745"/>
<string key="objectName">First Responder</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-3</int>
<reference key="object" ref="1004"/>
- <reference key="parent" ref="0"/>
+ <reference key="parent" ref="482098745"/>
<string key="objectName">Application</string>
</object>
<object class="IBObjectRecord">
@@ -307,14 +278,13 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="612665518"/>
</object>
- <reference key="parent" ref="0"/>
+ <reference key="parent" ref="482098745"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="612665518"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
- <reference ref="445667"/>
<reference ref="742622660"/>
<reference ref="510660793"/>
<reference ref="455192438"/>
@@ -323,15 +293,6 @@
<reference key="parent" ref="139541997"/>
</object>
<object class="IBObjectRecord">
- <int key="objectID">6</int>
- <reference key="object" ref="445667"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <reference ref="236923920"/>
- </object>
- <reference key="parent" ref="612665518"/>
- </object>
- <object class="IBObjectRecord">
<int key="objectID">7</int>
<reference key="object" ref="742622660"/>
<object class="NSMutableArray" key="children">
@@ -387,20 +348,16 @@
<reference key="object" ref="768031501"/>
<reference key="parent" ref="742622660"/>
</object>
- <object class="IBObjectRecord">
- <int key="objectID">9</int>
- <reference key="object" ref="236923920"/>
- <reference key="parent" ref="445667"/>
- </object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
+ <object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>-1.IBPluginDependency</string>
<string>-2.IBPluginDependency</string>
<string>-3.IBPluginDependency</string>
+ <string>10.CustomClassName</string>
<string>10.IBPluginDependency</string>
<string>11.CustomClassName</string>
<string>11.IBPluginDependency</string>
@@ -416,21 +373,17 @@
<string>29.IBPluginDependency</string>
<string>3.IBPluginDependency</string>
<string>4.IBPluginDependency</string>
+ <string>5.CustomClassName</string>
<string>5.IBPluginDependency</string>
- <string>6.IBPluginDependency</string>
- <string>6.IBViewIntegration.shadowBlurRadius</string>
- <string>6.IBViewIntegration.shadowColor</string>
- <string>6.IBViewIntegration.shadowOffsetHeight</string>
- <string>6.IBViewIntegration.shadowOffsetWidth</string>
<string>7.IBPluginDependency</string>
<string>8.IBPluginDependency</string>
- <string>9.IBPluginDependency</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>FindBarTextFieldCell</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>ToolbarButtonCell</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -438,20 +391,15 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{753, 971}, {310, 33}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <real value="0.0"/>
+ <real value="0.000000e+00"/>
<reference ref="817558590"/>
- <real value="0.0"/>
- <real value="0.0"/>
+ <real value="0.000000e+00"/>
+ <real value="0.000000e+00"/>
<string>{{805, 959}, {310, 33}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <real value="0.0"/>
- <reference ref="817558590"/>
- <real value="0.0"/>
- <real value="0.0"/>
+ <string>FindBarTextField</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -459,7 +407,9 @@
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
- <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
@@ -467,7 +417,9 @@
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
- <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
@@ -503,7 +455,7 @@
<string key="superclassName">NSViewController</string>
<object class="NSMutableDictionary" key="actions">
<bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
+ <object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>close:</string>
<string>nextResult:</string>
@@ -518,8 +470,9 @@
</object>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
+ <object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
+ <string>findBarView_</string>
<string>findText_</string>
<string>nextButton_</string>
<string>previousButton_</string>
@@ -527,7 +480,8 @@
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
- <string>NSTextField</string>
+ <string>NSView</string>
+ <string>FindBarTextField</string>
<string>NSButton</string>
<string>NSButton</string>
<string>NSTextField</string>
@@ -539,6 +493,22 @@
</object>
</object>
<object class="IBPartialClassDescription">
+ <string key="className">FindBarTextField</string>
+ <string key="superclassName">StyledTextField</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/find_bar_text_field.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">FindBarTextFieldCell</string>
+ <string key="superclassName">StyledTextFieldCell</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/find_bar_text_field_cell.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
<string key="className">FindBarView</string>
<string key="superclassName">BackgroundGradientView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@@ -569,70 +539,32 @@
</object>
</object>
<object class="IBPartialClassDescription">
- <string key="className">ToolbarButtonCell</string>
- <string key="superclassName">ClickHoldButtonCell</string>
+ <string key="className">StyledTextField</string>
+ <string key="superclassName">NSTextField</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
- <string key="minorKey">browser/cocoa/toolbar_button_cell.h</string>
+ <string key="minorKey">browser/cocoa/styled_text_field.h</string>
</object>
</object>
- </object>
- <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.1+">
- <bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
- <string key="className">FindBarCocoaController</string>
- <string key="superclassName">NSViewController</string>
- <object class="NSMutableDictionary" key="actions">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>close:</string>
- <string>nextResult:</string>
- <string>previousResult:</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>id</string>
- <string>id</string>
- <string>id</string>
- </object>
- </object>
- <object class="NSMutableDictionary" key="outlets">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>findBarView_</string>
- <string>findText_</string>
- <string>nextButton_</string>
- <string>previousButton_</string>
- <string>resultsLabel_</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>NSView</string>
- <string>NSTextField</string>
- <string>NSButton</string>
- <string>NSButton</string>
- <string>NSTextField</string>
- </object>
+ <string key="className">StyledTextFieldCell</string>
+ <string key="superclassName">NSTextFieldCell</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/styled_text_field_cell.h</string>
</object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">ToolbarButtonCell</string>
+ <string key="superclassName">ClickHoldButtonCell</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBDocumentRelativeSource</string>
- <string key="minorKey">../../browser/cocoa/find_bar_cocoa_controller.h</string>
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/toolbar_button_cell.h</string>
</object>
</object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
- <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
- <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
- <integer value="1050" key="NS.object.0"/>
- </object>
- <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
- <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string>
- <integer value="3000" key="NS.object.0"/>
- </object>
- <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<string key="IBDocument.LastKnownRelativeProjectPath">../../chrome.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
</data>
diff --git a/chrome/browser/cocoa/autocomplete_text_field.h b/chrome/browser/cocoa/autocomplete_text_field.h
index 7ffbb7e..112212c 100644
--- a/chrome/browser/cocoa/autocomplete_text_field.h
+++ b/chrome/browser/cocoa/autocomplete_text_field.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_COCOA_AUTOCOMPLETE_TEXT_FIELD_H_
#import <Cocoa/Cocoa.h>
+#import "chrome/browser/cocoa/styled_text_field.h"
@class AutocompleteTextFieldCell;
@@ -25,10 +26,8 @@
// Provides a hook so that we can call directly down to
// AutocompleteEditViewMac rather than traversing the delegate chain.
-
class AutocompleteTextFieldObserver {
public:
-
// Called when the control-key state changes while the field is
// first responder.
virtual void OnControlKeyChanged(bool pressed) = 0;
@@ -54,7 +53,7 @@ class AutocompleteTextFieldObserver {
virtual void OnFrameChanged() = 0;
};
-@interface AutocompleteTextField : NSTextField {
+@interface AutocompleteTextField : StyledTextField {
@private
AutocompleteTextFieldObserver* observer_; // weak, owned by location bar.
}
@@ -64,15 +63,6 @@ class AutocompleteTextFieldObserver {
// Convenience method to return the cell, casted appropriately.
- (AutocompleteTextFieldCell*)autocompleteTextFieldCell;
-// If the keyword, keyword hint, or search hint changed, then the
-// field editor may need to be repositioned.
-- (void)resetFieldEditorFrameIfNeeded;
-
-// Returns the amount of the field's width which is not being taken up
-// by the text contents. May be negative if the contents are large
-// enough to scroll.
-- (CGFloat)availableDecorationWidth;
-
// Superclass aborts editing before changing the string, which causes
// problems for undo. This version modifies the field editor's
// contents if the control is already being edited.
diff --git a/chrome/browser/cocoa/autocomplete_text_field.mm b/chrome/browser/cocoa/autocomplete_text_field.mm
index 9d995c11..c89fd17 100644
--- a/chrome/browser/cocoa/autocomplete_text_field.mm
+++ b/chrome/browser/cocoa/autocomplete_text_field.mm
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/cocoa/autocomplete_text_field.h"
+#import "chrome/browser/cocoa/autocomplete_text_field.h"
#include "base/logging.h"
-#include "chrome/browser/cocoa/autocomplete_text_field_cell.h"
+#import "chrome/browser/cocoa/autocomplete_text_field_cell.h"
@implementation AutocompleteTextField
@@ -29,48 +29,6 @@
return static_cast<AutocompleteTextFieldCell*>([self cell]);
}
-// Cocoa text fields are edited by placing an NSTextView as subview,
-// positioned by the cell's -editWithFrame:inView:... method. Using
-// the standard -makeFirstResponder: machinery to reposition the field
-// editor results in resetting the field editor's editing state, which
-// AutocompleteEditViewMac monitors. This causes problems because
-// editing can require the field editor to be repositioned, which
-// could disrupt editing. This code repositions the subview directly,
-// which causes no editing-state changes.
-- (void)resetFieldEditorFrameIfNeeded {
- // No action if not editing.
- NSText* editor = [self currentEditor];
- if (!editor) {
- return;
- }
-
- // When editing, we should have exactly one subview, which is a
- // clipview containing the editor (for purposes of scrolling).
- NSArray* subviews = [self subviews];
- DCHECK_EQ([subviews count], 1U);
- DCHECK([editor isDescendantOf:self]);
- if ([subviews count] == 0) {
- return;
- }
-
- // If the frame is already right, don't make any visible changes.
- AutocompleteTextFieldCell* cell = [self autocompleteTextFieldCell];
- const NSRect frame([cell drawingRectForBounds:[self bounds]]);
- NSView* subview = [subviews objectAtIndex:0];
- if (NSEqualRects(frame, [subview frame])) {
- return;
- }
-
- [subview setFrame:frame];
-
- // Make sure the selection remains visible.
- // TODO(shess) This could be janky if it jerks the visible region
- // around too much. I believe that text fields only scroll in
- // response to selection movement (continuing the selection past the
- // edge, or arrowing the cursor around).
- [editor scrollRangeToVisible:[editor selectedRange]];
-}
-
// Reroute events for the decoration area to the field editor. This
// will cause the cursor to be moved as close to the edge where the
// event was seen as possible.
@@ -104,7 +62,7 @@
const NSPoint locationInWindow = [theEvent locationInWindow];
const NSPoint location = [self convertPoint:locationInWindow fromView:nil];
- AutocompleteTextFieldCell* cell = [self cell];
+ AutocompleteTextFieldCell* cell = [self autocompleteTextFieldCell];
const NSRect textFrame([cell textFrameForFrame:[self bounds]]);
// A version of the textFrame which extends across the field's
@@ -174,13 +132,7 @@
[editor mouseDown:theEvent];
}
-- (CGFloat)availableDecorationWidth {
- NSAttributedString* as = [self attributedStringValue];
- const NSSize size([as size]);
- const NSRect bounds([self bounds]);
- return NSWidth(bounds) - size.width;
-}
-
+// Overriden to pass OnFrameChanged() notifications to |observer_|.
- (void)setFrame:(NSRect)frameRect {
[super setFrame:frameRect];
if (observer_) {
diff --git a/chrome/browser/cocoa/autocomplete_text_field_cell.h b/chrome/browser/cocoa/autocomplete_text_field_cell.h
index 2aa04a8..65749a6 100644
--- a/chrome/browser/cocoa/autocomplete_text_field_cell.h
+++ b/chrome/browser/cocoa/autocomplete_text_field_cell.h
@@ -4,20 +4,17 @@
#import <Cocoa/Cocoa.h>
+#import "chrome/browser/cocoa/styled_text_field_cell.h"
+
#include "base/scoped_nsobject.h"
#include "chrome/browser/cocoa/location_bar_view_mac.h"
-// AutocompleteTextFieldCell customizes the look of the Omnibox text
-// field. The border and focus ring are modified, as is the font
-// baseline.
-
-// The cell also provides support for certain decorations to be
-// applied to the field. These are the search hint ("Type to search"
-// on the right-hand side), the keyword hint ("Press [Tab] to search
-// Engine" on the right-hand side), and keyword mode ("Search Engine:"
-// in a button-like token on the left-hand side).
-
-@interface AutocompleteTextFieldCell : NSTextFieldCell {
+// AutocompleteTextFieldCell extends StyledTextFieldCell to provide support for
+// certain decorations to be applied to the field. These are the search hint
+// ("Type to search" on the right-hand side), the keyword hint ("Press [Tab] to
+// search Engine" on the right-hand side), and keyword mode ("Search Engine:" in
+// a button-like token on the left-hand side).
+@interface AutocompleteTextFieldCell : StyledTextFieldCell {
@private
// Set if there is a string to display in a rounded rect on the
// left-hand side of the field. Exclusive WRT |hintString_|.
@@ -58,13 +55,6 @@
// security_image_view_ to handle the click (i.e., show the page info dialog).
- (void)onSecurityIconMousePressed;
-// Return the portion of the cell to show the text cursor over.
-- (NSRect)textCursorFrameForFrame:(NSRect)cellFrame;
-
-// Return the portion of the cell to use for text display. This
-// corresponds to the frame with our added decorations sliced off.
-- (NSRect)textFrameForFrame:(NSRect)cellFrame;
-
// Return the portion of the cell to use for displaying the security (SSL lock)
// icon, leaving space for its label if any.
- (NSRect)securityImageFrameForFrame:(NSRect)cellFrame;
diff --git a/chrome/browser/cocoa/autocomplete_text_field_cell.mm b/chrome/browser/cocoa/autocomplete_text_field_cell.mm
index 56581ce..2104a31 100644
--- a/chrome/browser/cocoa/autocomplete_text_field_cell.mm
+++ b/chrome/browser/cocoa/autocomplete_text_field_cell.mm
@@ -6,12 +6,12 @@
#include "app/gfx/font.h"
#include "app/resource_bundle.h"
-#import "base/logging.h"
+#include "base/logging.h"
#import "third_party/GTM/AppKit/GTMTheme.h"
namespace {
-const NSInteger kBaselineAdjust = 2;
+const CGFloat kBaselineAdjust = 2.0;
// How far to offset the keyword token into the field.
const NSInteger kKeywordXOffset = 3;
@@ -36,11 +36,6 @@ const NSInteger kKeywordYInset = 4;
// technique would be nice to have, though.
const NSInteger kKeywordHintImageBaseline = -6;
-// Offset from the bottom of the field for drawing decoration text.
-// TODO(shess): Somehow determine the baseline for the text field and
-// use that.
-const NSInteger kBaselineOffset = 4;
-
// The amount of padding on either side reserved for drawing an icon.
const NSInteger kIconHorizontalPad = 3;
@@ -72,6 +67,10 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
return hintString_.get();
}
+- (CGFloat)baselineAdjust {
+ return kBaselineAdjust;
+}
+
- (void)setKeywordString:(NSString*)fullString
partialString:(NSString*)partialString
availableWidth:(CGFloat)width {
@@ -94,7 +93,6 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
}
keywordString_.reset(
[[NSAttributedString alloc] initWithString:s attributes:attributes]);
-
}
// Convenience for the attributes used in the right-justified info
@@ -204,52 +202,9 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
security_image_view_->OnMousePressed();
}
-// TODO(shess): This code is manually drawing the cell's border area,
-// but otherwise the cell assumes -setBordered:YES for purposes of
-// calculating things like the editing area. This is probably
-// incorrect. I know that this affects -drawingRectForBounds:.
-
-- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
- DCHECK([controlView isFlipped]);
- [[NSColor colorWithCalibratedWhite:1.0 alpha:0.25] set];
- NSFrameRectWithWidthUsingOperation(cellFrame, 1, NSCompositeSourceOver);
-
- // TODO(shess): This inset is also reflected in ToolbarController
- // -autocompletePopupPosition.
- NSRect frame = NSInsetRect(cellFrame, 0, 1);
- [[self backgroundColor] setFill];
- NSRect innerFrame = NSInsetRect(frame, 1, 1);
- NSRectFill(innerFrame);
-
- NSRect shadowFrame, restFrame;
- NSDivideRect(innerFrame, &shadowFrame, &restFrame, 1, NSMinYEdge);
-
- BOOL isMainWindow = [[controlView window] isMainWindow];
- GTMTheme *theme = [controlView gtm_theme];
- NSColor* stroke = [theme strokeColorForStyle:GTMThemeStyleToolBarButton
- state:isMainWindow];
- [stroke set];
- NSFrameRectWithWidthUsingOperation(frame, 1.0, NSCompositeSourceOver);
-
- // Draw the shadow.
- [[NSColor colorWithCalibratedWhite:0.0 alpha:0.05] setFill];
- NSRectFillUsingOperation(shadowFrame, NSCompositeSourceOver);
-
- if ([self showsFirstResponder]) {
- [[[NSColor keyboardFocusIndicatorColor] colorWithAlphaComponent:0.5] set];
- NSFrameRectWithWidthUsingOperation(NSInsetRect(frame, 0, 0), 2,
- NSCompositeSourceOver);
- }
-
- [self drawInteriorWithFrame:cellFrame inView:controlView];
-}
-
-- (NSRect)textCursorFrameForFrame:(NSRect)cellFrame {
- return NSInsetRect(cellFrame, 0, kBaselineAdjust);
-}
-
+// Overriden to account for the hint strings and hint icons.
- (NSRect)textFrameForFrame:(NSRect)cellFrame {
- NSRect textFrame([self textCursorFrameForFrame:cellFrame]);
+ NSRect textFrame([super textFrameForFrame:cellFrame]);
if (hintString_) {
DCHECK(!keywordString_);
@@ -323,13 +278,6 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
return [self imageFrameForFrame:cellFrame withImageView:security_image_view_];
}
-// For NSTextFieldCell this is the area within the borders. For our
-// purposes, we count the info decorations as being part of the
-// border.
-- (NSRect)drawingRectForBounds:(NSRect)theRect {
- return [super drawingRectForBounds:[self textFrameForFrame:theRect]];
-}
-
- (void)drawHintWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
DCHECK(hintString_);
@@ -413,9 +361,4 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
[super drawInteriorWithFrame:cellFrame inView:controlView];
}
-- (void)resetCursorRect:(NSRect)cellFrame inView:(NSView *)controlView {
- [super resetCursorRect:[self textCursorFrameForFrame:cellFrame]
- inView:controlView];
-}
-
@end
diff --git a/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm b/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm
index 3cc5703..79f0ecb 100644
--- a/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm
+++ b/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm
@@ -19,43 +19,42 @@ const CGFloat kWidth(300.0);
// A narrow width for tests which test things that don't fit.
const CGFloat kNarrowWidth(5.0);
-class AutocompleteTextFieldCellTest : public PlatformTest {
+class AutocompleteTextFieldCellTest : public CocoaTest {
public:
AutocompleteTextFieldCellTest() : security_image_view_(NULL, NULL) {
// Make sure this is wide enough to play games with the cell
// decorations.
const NSRect frame = NSMakeRect(0, 0, kWidth, 30);
- view_.reset([[NSTextField alloc] initWithFrame:frame]);
+
+ scoped_nsobject<NSTextField> view(
+ [[NSTextField alloc] initWithFrame:frame]);
+ view_ = view.get();
+
scoped_nsobject<AutocompleteTextFieldCell> cell(
[[AutocompleteTextFieldCell alloc] initTextCell:@"Testing"]);
[cell setEditable:YES];
[cell setBordered:YES];
- [view_ setCell:cell.get()];
[cell setSecurityImageView:&security_image_view_];
- [cocoa_helper_.contentView() addSubview:view_.get()];
+ [view_ setCell:cell.get()];
+
+ [[test_window() contentView] addSubview:view_];
}
- CocoaTestHelper cocoa_helper_; // Inits Cocoa, creates window, etc...
- scoped_nsobject<NSTextField> view_;
+ NSTextField* view_;
LocationBarViewMac::SecurityImageView security_image_view_;
};
-// Test adding/removing from the view hierarchy, mostly to ensure nothing
-// leaks or crashes.
-TEST_F(AutocompleteTextFieldCellTest, AddRemove) {
- EXPECT_EQ(cocoa_helper_.contentView(), [view_ superview]);
- [view_.get() removeFromSuperview];
- EXPECT_FALSE([view_ superview]);
-}
+// Basic view tests (AddRemove, Display).
+TEST_VIEW(AutocompleteTextFieldCellTest, view_);
// Test drawing, mostly to ensure nothing leaks or crashes.
-TEST_F(AutocompleteTextFieldCellTest, Display) {
+TEST_F(AutocompleteTextFieldCellTest, FocusedDisplay) {
[view_ display];
- // Test focussed drawing.
- cocoa_helper_.makeFirstResponder(view_);
+ // Test focused drawing.
+ [test_window() makePretendKeyWindowAndSetFirstResponder:view_];
[view_ display];
- cocoa_helper_.clearFirstResponder();
+ [test_window() clearPretendKeyWindowAndFirstResponder];
// Test display of various cell configurations.
AutocompleteTextFieldCell* cell =
diff --git a/chrome/browser/cocoa/find_bar_cocoa_controller.h b/chrome/browser/cocoa/find_bar_cocoa_controller.h
index b974fcf..21ce106 100644
--- a/chrome/browser/cocoa/find_bar_cocoa_controller.h
+++ b/chrome/browser/cocoa/find_bar_cocoa_controller.h
@@ -11,6 +11,7 @@
class BrowserWindowCocoa;
class FindBarBridge;
+@class FindBarTextField;
class FindNotificationDetails;
@class FocusTracker;
@@ -23,8 +24,7 @@ class FindNotificationDetails;
@interface FindBarCocoaController : NSViewController {
@private
IBOutlet NSView* findBarView_;
- IBOutlet NSTextField* findText_;
- IBOutlet NSTextField* resultsLabel_;
+ IBOutlet FindBarTextField* findText_;
IBOutlet NSButton* nextButton_;
IBOutlet NSButton* previousButton_;
diff --git a/chrome/browser/cocoa/find_bar_cocoa_controller.mm b/chrome/browser/cocoa/find_bar_cocoa_controller.mm
index dc39596..009370b 100644
--- a/chrome/browser/cocoa/find_bar_cocoa_controller.mm
+++ b/chrome/browser/cocoa/find_bar_cocoa_controller.mm
@@ -4,14 +4,14 @@
#import <Cocoa/Cocoa.h>
-#include "app/l10n_util.h"
#include "base/mac_util.h"
#include "base/sys_string_conversions.h"
-#include "grit/generated_resources.h"
#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/cocoa/browser_window_cocoa.h"
#import "chrome/browser/cocoa/find_bar_cocoa_controller.h"
#import "chrome/browser/cocoa/find_bar_bridge.h"
+#import "chrome/browser/cocoa/find_bar_text_field.h"
+#import "chrome/browser/cocoa/find_bar_text_field_cell.h"
#import "chrome/browser/cocoa/find_pasteboard.h"
#import "chrome/browser/cocoa/focus_tracker.h"
#import "chrome/browser/cocoa/tab_strip_controller.h"
@@ -276,33 +276,20 @@ static float kFindBarCloseDuration = 0.15;
result.number_of_matches() != -1;
NSString* searchString = [findText_ stringValue];
if ([searchString length] > 0 && validRange) {
- [resultsLabel_ setStringValue:base::SysWideToNSString(
- l10n_util::GetStringF(IDS_FIND_IN_PAGE_COUNT,
- IntToWString(result.active_match_ordinal()),
- IntToWString(result.number_of_matches())))];
+ [[findText_ findBarTextFieldCell]
+ setActiveMatch:result.active_match_ordinal()
+ of:result.number_of_matches()];
} else {
- // If there was no text entered, we don't show anything in the result count
- // area.
- [resultsLabel_ setStringValue:@""];
+ // If there was no text entered, we don't show anything in the results area.
+ [[findText_ findBarTextFieldCell] clearResults];
}
+ [findText_ resetFieldEditorFrameIfNeeded];
+
// If we found any results, reset the focus tracker, so we always
// restore focus to the tab contents.
if (result.number_of_matches() > 0)
focusTracker_.reset(nil);
-
- // Resize |resultsLabel_| to completely contain its string and right-justify
- // it within |findText_|. sizeToFit may shrink the frame vertically, which we
- // don't want, so we save the original vertical positioning.
- NSRect labelFrame = [resultsLabel_ frame];
- [resultsLabel_ sizeToFit];
- labelFrame.size.width = [resultsLabel_ frame].size.width;
- labelFrame.origin.x = NSMaxX([findText_ frame]) - labelFrame.size.width;
- [resultsLabel_ setFrame:labelFrame];
-
- // TODO(rohitrao): If the search string is too long, then it will overlap with
- // the results label. Fix. Perhaps use the code that fades out the tab titles
- // if they are too long.
}
- (BOOL)isFindBarVisible {
diff --git a/chrome/browser/cocoa/find_bar_cocoa_controller_unittest.mm b/chrome/browser/cocoa/find_bar_cocoa_controller_unittest.mm
index 5b48350..71614d8 100644
--- a/chrome/browser/cocoa/find_bar_cocoa_controller_unittest.mm
+++ b/chrome/browser/cocoa/find_bar_cocoa_controller_unittest.mm
@@ -13,6 +13,7 @@
#import "chrome/browser/cocoa/cocoa_test_helper.h"
#import "chrome/browser/cocoa/find_bar_cocoa_controller.h"
#import "chrome/browser/cocoa/find_pasteboard.h"
+#import "chrome/browser/cocoa/find_bar_text_field.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -20,8 +21,7 @@
@interface FindBarCocoaController(Testing)
- (NSView*)findBarView;
- (NSString*)findText;
-- (NSTextField*)findTextField;
-- (NSTextField*)resultsLabel;
+- (FindBarTextField*)findTextField;
@end
@implementation FindBarCocoaController(Testing)
@@ -36,10 +36,6 @@
- (NSTextField*)findTextField {
return findText_;
}
-
-- (NSTextField*)resultsLabel {
- return resultsLabel_;
-}
@end
namespace {
diff --git a/chrome/browser/cocoa/find_bar_text_field.h b/chrome/browser/cocoa/find_bar_text_field.h
new file mode 100644
index 0000000..714fbdb
--- /dev/null
+++ b/chrome/browser/cocoa/find_bar_text_field.h
@@ -0,0 +1,21 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Cocoa/Cocoa.h>
+#import "chrome/browser/cocoa/styled_text_field.h"
+
+@class FindBarTextFieldCell;
+
+// TODO(rohitrao): This class may not need to exist, since it does not really
+// add any functionality over StyledTextField. See if we can change the nib
+// file to put a FindBarTextFieldCell into a StyledTextField.
+
+// Extends StyledTextField to use a custom cell class (FindBarTextFieldCell).
+@interface FindBarTextField : StyledTextField {
+}
+
+// Convenience method to return the cell, casted appropriately.
+- (FindBarTextFieldCell*)findBarTextFieldCell;
+
+@end
diff --git a/chrome/browser/cocoa/find_bar_text_field.mm b/chrome/browser/cocoa/find_bar_text_field.mm
new file mode 100644
index 0000000..7873c02
--- /dev/null
+++ b/chrome/browser/cocoa/find_bar_text_field.mm
@@ -0,0 +1,25 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "chrome/browser/cocoa/find_bar_text_field.h"
+
+#include "base/logging.h"
+#import "chrome/browser/cocoa/find_bar_text_field_cell.h"
+
+@implementation FindBarTextField
+
++ (Class)cellClass {
+ return [FindBarTextFieldCell class];
+}
+
+- (void)awakeFromNib {
+ DCHECK([[self cell] isKindOfClass:[FindBarTextFieldCell class]]);
+}
+
+- (FindBarTextFieldCell*)findBarTextFieldCell {
+ DCHECK([[self cell] isKindOfClass:[FindBarTextFieldCell class]]);
+ return static_cast<FindBarTextFieldCell*>([self cell]);
+}
+
+@end
diff --git a/chrome/browser/cocoa/find_bar_text_field_cell.h b/chrome/browser/cocoa/find_bar_text_field_cell.h
new file mode 100644
index 0000000..2ca447ac
--- /dev/null
+++ b/chrome/browser/cocoa/find_bar_text_field_cell.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Cocoa/Cocoa.h>
+
+#import "chrome/browser/cocoa/styled_text_field_cell.h"
+
+#include "base/scoped_nsobject.h"
+
+// FindBarTextFieldCell extends StyledTextFieldCell to provide support for a
+// results label rooted at the right edge of the cell.
+@interface FindBarTextFieldCell : StyledTextFieldCell {
+ @private
+ // Set if there is a results label to display on the right side of the cell.
+ scoped_nsobject<NSAttributedString> resultsString_;
+}
+
+// Sets the results label to the localized equivalent of "X of Y".
+- (void)setActiveMatch:(NSInteger)current of:(NSInteger)total;
+
+- (void)clearResults;
+
+@end
diff --git a/chrome/browser/cocoa/find_bar_text_field_cell.mm b/chrome/browser/cocoa/find_bar_text_field_cell.mm
new file mode 100644
index 0000000..9b52c5f
--- /dev/null
+++ b/chrome/browser/cocoa/find_bar_text_field_cell.mm
@@ -0,0 +1,109 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "chrome/browser/cocoa/find_bar_text_field_cell.h"
+
+#include "app/l10n_util.h"
+#include "base/logging.h"
+#include "base/string_util.h"
+#include "base/sys_string_conversions.h"
+#include "grit/generated_resources.h"
+
+namespace {
+
+const CGFloat kBaselineAdjust = 1.0;
+
+// How far to offset the keyword token into the field.
+const NSInteger kResultsXOffset = 3;
+
+// How much width (beyond text) to add to the keyword token on each
+// side.
+const NSInteger kResultsTokenInset = 3;
+
+// How far to shift bounding box of hint down from top of field.
+// Assumes -setFlipped:YES.
+const NSInteger kResultsYOffset = 4;
+
+// How far the editor insets itself, for purposes of determining if
+// decorations need to be trimmed.
+const CGFloat kEditorHorizontalInset = 3.0;
+
+// Conveniences to centralize width+offset calculations.
+CGFloat WidthForResults(NSAttributedString* resultsString) {
+ return kResultsXOffset + ceil([resultsString size].width) +
+ 2 * kResultsTokenInset;
+}
+
+} // namespace
+
+@implementation FindBarTextFieldCell
+
+- (CGFloat)baselineAdjust {
+ return kBaselineAdjust;
+}
+
+// @synthesize doesn't seem to compile for this transition.
+- (NSAttributedString*)resultsString {
+ return resultsString_.get();
+}
+
+// Convenience for the attributes used in the right-justified info
+// cells. Sets the background color to red if |foundMatches| is YES.
+- (NSDictionary*)resultsAttributes:(BOOL)foundMatches {
+ scoped_nsobject<NSMutableParagraphStyle> style(
+ [[NSMutableParagraphStyle alloc] init]);
+ [style setAlignment:NSRightTextAlignment];
+
+ return [NSDictionary dictionaryWithObjectsAndKeys:
+ [self font], NSFontAttributeName,
+ [NSColor lightGrayColor], NSForegroundColorAttributeName,
+ [NSColor whiteColor], NSBackgroundColorAttributeName,
+ style.get(), NSParagraphStyleAttributeName,
+ nil];
+}
+
+- (void)setActiveMatch:(NSInteger)current of:(NSInteger)total {
+ NSString* results =
+ base::SysWideToNSString(l10n_util::GetStringF(IDS_FIND_IN_PAGE_COUNT,
+ IntToWString(current),
+ IntToWString(total)));
+ resultsString_.reset([[NSAttributedString alloc]
+ initWithString:results
+ attributes:[self resultsAttributes:(total > 0)]]);
+}
+
+- (void)clearResults {
+ resultsString_.reset(nil);
+}
+
+- (NSRect)textFrameForFrame:(NSRect)cellFrame {
+ NSRect textFrame([super textFrameForFrame:cellFrame]);
+ if (resultsString_)
+ textFrame.size.width -= WidthForResults(resultsString_);
+ return textFrame;
+}
+
+// Do not show the I-beam cursor over the results label.
+- (NSRect)textCursorFrameForFrame:(NSRect)cellFrame {
+ return [self textFrameForFrame:cellFrame];
+}
+
+- (void)drawResultsWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
+ DCHECK(resultsString_);
+
+ NSRect textFrame = [self textFrameForFrame:cellFrame];
+ NSRect infoFrame(NSMakeRect(NSMaxX(textFrame),
+ cellFrame.origin.y + kResultsYOffset,
+ ceil([resultsString_ size].width),
+ cellFrame.size.height - kResultsYOffset));
+ [resultsString_.get() drawInRect:infoFrame];
+}
+
+- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
+ if (resultsString_)
+ [self drawResultsWithFrame:cellFrame inView:controlView];
+ [super drawInteriorWithFrame:cellFrame inView:controlView];
+}
+
+@end
diff --git a/chrome/browser/cocoa/find_bar_text_field_cell_unittest.mm b/chrome/browser/cocoa/find_bar_text_field_cell_unittest.mm
new file mode 100644
index 0000000..50011a4
--- /dev/null
+++ b/chrome/browser/cocoa/find_bar_text_field_cell_unittest.mm
@@ -0,0 +1,138 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Cocoa/Cocoa.h>
+
+#include "base/scoped_nsobject.h"
+#import "chrome/browser/cocoa/find_bar_text_field_cell.h"
+#import "chrome/browser/cocoa/cocoa_test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+
+@interface FindBarTextFieldCell (ExposedForTesting)
+- (NSAttributedString*)resultsString;
+@end
+
+@implementation FindBarTextFieldCell (ExposedForTesting)
+- (NSAttributedString*)resultsString {
+ return resultsString_.get();
+}
+@end
+
+namespace {
+
+// Width of the field so that we don't have to ask |field_| for it all
+// the time.
+const CGFloat kWidth(300.0);
+
+// A narrow width for tests which test things that don't fit.
+const CGFloat kNarrowWidth(5.0);
+
+class FindBarTextFieldCellTest : public CocoaTest {
+ public:
+ FindBarTextFieldCellTest() {
+ // Make sure this is wide enough to play games with the cell
+ // decorations.
+ const NSRect frame = NSMakeRect(0, 0, kWidth, 30);
+
+ scoped_nsobject<FindBarTextFieldCell> cell(
+ [[FindBarTextFieldCell alloc] initTextCell:@"Testing"]);
+ cell_ = cell;
+ [cell_ setEditable:YES];
+ [cell_ setBordered:YES];
+
+ scoped_nsobject<NSTextField> view(
+ [[NSTextField alloc] initWithFrame:frame]);
+ view_ = view;
+ [view_ setCell:cell_];
+
+ [[test_window() contentView] addSubview:view_];
+ }
+
+ NSTextField* view_;
+ FindBarTextFieldCell* cell_;
+};
+
+// Basic view tests (AddRemove, Display).
+TEST_VIEW(FindBarTextFieldCellTest, view_);
+
+// Test drawing, mostly to ensure nothing leaks or crashes.
+TEST_F(FindBarTextFieldCellTest, FocusedDisplay) {
+ [view_ display];
+
+ // Test focused drawing.
+ [test_window() makePretendKeyWindowAndSetFirstResponder:view_];
+ [view_ display];
+ [test_window() clearPretendKeyWindowAndFirstResponder];
+
+ // Test display of various cell configurations.
+ [cell_ setActiveMatch:4 of:30];
+ [view_ display];
+
+ [cell_ setActiveMatch:0 of:0];
+ [view_ display];
+
+ [cell_ clearResults];
+ [view_ display];
+}
+
+// Verify that setting and clearing the find results changes the results string
+// appropriately.
+TEST_F(FindBarTextFieldCellTest, SetAndClearFindResults) {
+ [cell_ setActiveMatch:10 of:30];
+ scoped_nsobject<NSAttributedString> tenString([[cell_ resultsString] copy]);
+ EXPECT_GT([tenString length], 0U);
+
+ [cell_ setActiveMatch:0 of:0];
+ scoped_nsobject<NSAttributedString> zeroString([[cell_ resultsString] copy]);
+ EXPECT_GT([zeroString length], 0U);
+ EXPECT_FALSE([tenString isEqualToAttributedString:zeroString]);
+
+ [cell_ clearResults];
+ EXPECT_EQ(0U, [[cell_ resultsString] length]);
+}
+
+TEST_F(FindBarTextFieldCellTest, TextFrame) {
+ const NSRect bounds = [view_ bounds];
+ NSRect textFrame = [cell_ textFrameForFrame:bounds];
+ NSRect cursorFrame = [cell_ textCursorFrameForFrame:bounds];
+
+ // At default settings, everything goes to the text area.
+ EXPECT_FALSE(NSIsEmptyRect(textFrame));
+ EXPECT_TRUE(NSContainsRect(bounds, textFrame));
+ EXPECT_EQ(NSMinX(bounds), NSMinX(textFrame));
+ EXPECT_EQ(NSMaxX(bounds), NSMaxX(textFrame));
+ EXPECT_TRUE(NSEqualRects(cursorFrame, textFrame));
+
+ // Setting an active match leaves text frame to left.
+ [cell_ setActiveMatch:4 of:5];
+ textFrame = [cell_ textFrameForFrame:bounds];
+ cursorFrame = [cell_ textCursorFrameForFrame:bounds];
+ EXPECT_FALSE(NSIsEmptyRect(textFrame));
+ EXPECT_TRUE(NSContainsRect(bounds, textFrame));
+ EXPECT_LT(NSMaxX(textFrame), NSMaxX(bounds));
+ EXPECT_TRUE(NSEqualRects(cursorFrame, textFrame));
+
+}
+
+// The editor frame should be slightly inset from the text frame.
+TEST_F(FindBarTextFieldCellTest, DrawingRectForBounds) {
+ const NSRect bounds = [view_ bounds];
+ NSRect textFrame = [cell_ textFrameForFrame:bounds];
+ NSRect drawingRect = [cell_ drawingRectForBounds:bounds];
+
+ // Save the starting frame for after clear.
+ const NSRect originalDrawingRect(drawingRect);
+
+ EXPECT_FALSE(NSIsEmptyRect(drawingRect));
+ EXPECT_TRUE(NSContainsRect(textFrame, NSInsetRect(drawingRect, 1, 1)));
+
+ [cell_ setActiveMatch:4 of:5];
+ textFrame = [cell_ textFrameForFrame:bounds];
+ drawingRect = [cell_ drawingRectForBounds:bounds];
+ EXPECT_FALSE(NSIsEmptyRect(drawingRect));
+ EXPECT_TRUE(NSContainsRect(textFrame, NSInsetRect(drawingRect, 1, 1)));
+}
+
+} // namespace
diff --git a/chrome/browser/cocoa/find_bar_text_field_unittest.mm b/chrome/browser/cocoa/find_bar_text_field_unittest.mm
new file mode 100644
index 0000000..fdb1b38
--- /dev/null
+++ b/chrome/browser/cocoa/find_bar_text_field_unittest.mm
@@ -0,0 +1,92 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Cocoa/Cocoa.h>
+
+#import "base/cocoa_protocols_mac.h"
+#include "base/scoped_nsobject.h"
+#import "chrome/browser/cocoa/find_bar_text_field.h"
+#import "chrome/browser/cocoa/find_bar_text_field_cell.h"
+#import "chrome/browser/cocoa/cocoa_test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+#import "third_party/ocmock/OCMock/OCMock.h"
+
+// OCMock wants to mock a concrete class or protocol. This should
+// provide a correct protocol for newer versions of the SDK, while
+// providing something mockable for older versions.
+
+@protocol MockTextEditingDelegate<NSControlTextEditingDelegate>
+- (void)controlTextDidBeginEditing:(NSNotification*)aNotification;
+- (BOOL)control:(NSControl*)control textShouldEndEditing:(NSText*)fieldEditor;
+@end
+
+namespace {
+
+// Width of the field so that we don't have to ask |field_| for it all
+// the time.
+static const CGFloat kWidth(300.0);
+
+class FindBarTextFieldTest : public CocoaTest {
+ public:
+ FindBarTextFieldTest() {
+ // Make sure this is wide enough to play games with the cell
+ // decorations.
+ NSRect frame = NSMakeRect(0, 0, kWidth, 30);
+ scoped_nsobject<FindBarTextField> field(
+ [[FindBarTextField alloc] initWithFrame:frame]);
+ field_ = field.get();
+
+ [field_ setStringValue:@"Test test"];
+ [[test_window() contentView] addSubview:field_];
+ }
+
+ FindBarTextField* field_;
+};
+
+// Basic view tests (AddRemove, Display).
+TEST_VIEW(FindBarTextFieldTest, field_);
+
+// Test that we have the right cell class.
+TEST_F(FindBarTextFieldTest, CellClass) {
+ EXPECT_TRUE([[field_ cell] isKindOfClass:[FindBarTextFieldCell class]]);
+}
+
+// Test that we get the same cell from -cell and
+// -findBarTextFieldCell.
+TEST_F(FindBarTextFieldTest, Cell) {
+ FindBarTextFieldCell* cell = [field_ findBarTextFieldCell];
+ EXPECT_EQ(cell, [field_ cell]);
+ EXPECT_TRUE(cell != nil);
+}
+
+// Test that becoming first responder sets things up correctly.
+TEST_F(FindBarTextFieldTest, FirstResponder) {
+ EXPECT_EQ(nil, [field_ currentEditor]);
+ EXPECT_EQ([[field_ subviews] count], 0U);
+ [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
+ EXPECT_FALSE(nil == [field_ currentEditor]);
+ EXPECT_EQ([[field_ subviews] count], 1U);
+ EXPECT_TRUE([[field_ currentEditor] isDescendantOf:field_]);
+}
+
+// Test drawing, mostly to ensure nothing leaks or crashes.
+TEST_F(FindBarTextFieldTest, Display) {
+ [field_ display];
+
+ // Test focussed drawing.
+ [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
+ [field_ display];
+ [test_window() clearPretendKeyWindowAndFirstResponder];
+
+ // Test display of various cell configurations.
+ FindBarTextFieldCell* cell = [field_ findBarTextFieldCell];
+ [cell setActiveMatch:4 of:5];
+ [field_ display];
+
+ [cell clearResults];
+ [field_ display];
+}
+
+} // namespace
diff --git a/chrome/browser/cocoa/styled_text_field.h b/chrome/browser/cocoa/styled_text_field.h
new file mode 100644
index 0000000..68a65b7
--- /dev/null
+++ b/chrome/browser/cocoa/styled_text_field.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Cocoa/Cocoa.h>
+
+@class StyledTextFieldCell;
+
+// An implementation of NSTextField that is designed to work with
+// StyledTextFieldCell. Provides methods to redraw the field when cell
+// decorations have changed and overrides |mouseDown:| to properly handle clicks
+// in sections of the cell with decorations.
+@interface StyledTextField : NSTextField {
+}
+
+// Repositions and redraws the field editor. Call this method when the cell's
+// text frame has changed (whenever changing cell decorations).
+- (void)resetFieldEditorFrameIfNeeded;
+
+// Returns the amount of the field's width which is not being taken up
+// by the text contents. May be negative if the contents are large
+// enough to scroll.
+- (CGFloat)availableDecorationWidth;
+
+@end
+
+@interface StyledTextField (ExposedForTesting)
+- (StyledTextFieldCell*)styledTextFieldCell;
+@end
diff --git a/chrome/browser/cocoa/styled_text_field.mm b/chrome/browser/cocoa/styled_text_field.mm
new file mode 100644
index 0000000..bf2641c
--- /dev/null
+++ b/chrome/browser/cocoa/styled_text_field.mm
@@ -0,0 +1,65 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "chrome/browser/cocoa/styled_text_field.h"
+
+#include "base/logging.h"
+#import "chrome/browser/cocoa/styled_text_field_cell.h"
+
+@implementation StyledTextField
+
+- (StyledTextFieldCell*)styledTextFieldCell {
+ DCHECK([[self cell] isKindOfClass:[StyledTextFieldCell class]]);
+ return static_cast<StyledTextFieldCell*>([self cell]);
+}
+
+// Cocoa text fields are edited by placing an NSTextView as subview,
+// positioned by the cell's -editWithFrame:inView:... method. Using
+// the standard -makeFirstResponder: machinery to reposition the field
+// editor results in resetting the field editor's editing state, which
+// AutocompleteEditViewMac monitors. This causes problems because
+// editing can require the field editor to be repositioned, which
+// could disrupt editing. This code repositions the subview directly,
+// which causes no editing-state changes.
+- (void)resetFieldEditorFrameIfNeeded {
+ // No action if not editing.
+ NSText* editor = [self currentEditor];
+ if (!editor) {
+ return;
+ }
+
+ // When editing, we should have exactly one subview, which is a
+ // clipview containing the editor (for purposes of scrolling).
+ NSArray* subviews = [self subviews];
+ DCHECK_EQ([subviews count], 1U);
+ DCHECK([editor isDescendantOf:self]);
+ if ([subviews count] == 0) {
+ return;
+ }
+
+ // If the frame is already right, don't make any visible changes.
+ StyledTextFieldCell* cell = [self styledTextFieldCell];
+ const NSRect frame([cell drawingRectForBounds:[self bounds]]);
+ NSView* subview = [subviews objectAtIndex:0];
+ if (NSEqualRects(frame, [subview frame])) {
+ return;
+ }
+
+ [subview setFrame:frame];
+
+ // Make sure the selection remains visible.
+ // TODO(shess) This could be janky if it jerks the visible region
+ // around too much. I believe that text fields only scroll in
+ // response to selection movement (continuing the selection past the
+ // edge, or arrowing the cursor around).
+ [editor scrollRangeToVisible:[editor selectedRange]];
+}
+
+- (CGFloat)availableDecorationWidth {
+ NSAttributedString* as = [self attributedStringValue];
+ const NSSize size([as size]);
+ const NSRect bounds([self bounds]);
+ return NSWidth(bounds) - size.width;
+}
+@end
diff --git a/chrome/browser/cocoa/styled_text_field_cell.h b/chrome/browser/cocoa/styled_text_field_cell.h
new file mode 100644
index 0000000..476f765
--- /dev/null
+++ b/chrome/browser/cocoa/styled_text_field_cell.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Cocoa/Cocoa.h>
+
+// StyledTextFieldCell customizes the look of the standard Cocoa text field.
+// The border and focus ring are modified, as is the font baseline. Subclasses
+// can override |drawInteriorWithFrame:inView:| to provide custom drawing for
+// decorations, but they must make sure to call the superclass' implementation
+// with a modified frame after performing any custom drawing.
+
+@interface StyledTextFieldCell : NSTextFieldCell {
+}
+
+// Baseline adjust for the text in this cell. Defaults to 0. Subclasses should
+// override as needed.
+- (CGFloat)baselineAdjust;
+
+// Return the portion of the cell to show the text cursor over. The default
+// implementation returns the full |cellFrame|. Subclasses should override this
+// method if they add any decorations.
+- (NSRect)textCursorFrameForFrame:(NSRect)cellFrame;
+
+// Return the portion of the cell to use for text display. This corresponds to
+// the frame with our added decorations sliced off. The default implementation
+// returns the full |cellFrame|, as by default there are no decorations.
+// Subclasses should override this method if they add any decorations.
+- (NSRect)textFrameForFrame:(NSRect)cellFrame;
+
+@end
diff --git a/chrome/browser/cocoa/styled_text_field_cell.mm b/chrome/browser/cocoa/styled_text_field_cell.mm
new file mode 100644
index 0000000..79b1adf
--- /dev/null
+++ b/chrome/browser/cocoa/styled_text_field_cell.mm
@@ -0,0 +1,83 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "chrome/browser/cocoa/styled_text_field_cell.h"
+
+#include "app/gfx/font.h"
+#include "app/resource_bundle.h"
+#include "base/logging.h"
+#import "third_party/GTM/AppKit/GTMTheme.h"
+
+@implementation StyledTextFieldCell
+
+- (CGFloat)baselineAdjust {
+ return 0.0;
+}
+
+// Returns the same value as textCursorFrameForFrame, but does not call it
+// directly to avoid potential infinite loops.
+- (NSRect)textFrameForFrame:(NSRect)cellFrame {
+ return NSInsetRect(cellFrame, 0, [self baselineAdjust]);
+}
+
+// Returns the same value as textFrameForFrame, but does not call it directly to
+// avoid potential infinite loops.
+- (NSRect)textCursorFrameForFrame:(NSRect)cellFrame {
+ return NSInsetRect(cellFrame, 0, [self baselineAdjust]);
+}
+
+// Override to show the I-beam cursor only in the area given by
+// |textCursorFrameForFrame:|.
+- (void)resetCursorRect:(NSRect)cellFrame inView:(NSView *)controlView {
+ [super resetCursorRect:[self textCursorFrameForFrame:cellFrame]
+ inView:controlView];
+}
+
+// For NSTextFieldCell this is the area within the borders. For our
+// purposes, we count the info decorations as being part of the
+// border.
+- (NSRect)drawingRectForBounds:(NSRect)theRect {
+ return [super drawingRectForBounds:[self textFrameForFrame:theRect]];
+}
+
+// TODO(shess): This code is manually drawing the cell's border area,
+// but otherwise the cell assumes -setBordered:YES for purposes of
+// calculating things like the editing area. This is probably
+// incorrect. I know that this affects -drawingRectForBounds:.
+- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
+ DCHECK([controlView isFlipped]);
+ [[NSColor colorWithCalibratedWhite:1.0 alpha:0.25] set];
+ NSFrameRectWithWidthUsingOperation(cellFrame, 1, NSCompositeSourceOver);
+
+ // TODO(shess): This inset is also reflected in ToolbarController
+ // -autocompletePopupPosition.
+ NSRect frame = NSInsetRect(cellFrame, 0, 1);
+ [[self backgroundColor] setFill];
+ NSRect innerFrame = NSInsetRect(frame, 1, 1);
+ NSRectFill(innerFrame);
+
+ NSRect shadowFrame, restFrame;
+ NSDivideRect(innerFrame, &shadowFrame, &restFrame, 1, NSMinYEdge);
+
+ BOOL isMainWindow = [[controlView window] isMainWindow];
+ GTMTheme *theme = [controlView gtm_theme];
+ NSColor* stroke = [theme strokeColorForStyle:GTMThemeStyleToolBarButton
+ state:isMainWindow];
+ [stroke set];
+ NSFrameRectWithWidthUsingOperation(frame, 1.0, NSCompositeSourceOver);
+
+ // Draw the shadow.
+ [[NSColor colorWithCalibratedWhite:0.0 alpha:0.05] setFill];
+ NSRectFillUsingOperation(shadowFrame, NSCompositeSourceOver);
+
+ if ([self showsFirstResponder]) {
+ [[[NSColor keyboardFocusIndicatorColor] colorWithAlphaComponent:0.5] set];
+ NSFrameRectWithWidthUsingOperation(NSInsetRect(frame, 0, 0), 2,
+ NSCompositeSourceOver);
+ }
+
+ [self drawInteriorWithFrame:cellFrame inView:controlView];
+}
+
+@end
diff --git a/chrome/browser/cocoa/styled_text_field_cell_unittest.mm b/chrome/browser/cocoa/styled_text_field_cell_unittest.mm
new file mode 100644
index 0000000..5928d43
--- /dev/null
+++ b/chrome/browser/cocoa/styled_text_field_cell_unittest.mm
@@ -0,0 +1,97 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Cocoa/Cocoa.h>
+
+#include "base/scoped_nsobject.h"
+#import "chrome/browser/cocoa/styled_text_field_cell.h"
+#import "chrome/browser/cocoa/styled_text_field_test_helper.h"
+#import "chrome/browser/cocoa/cocoa_test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+
+namespace {
+
+// Width of the field so that we don't have to ask |field_| for it all
+// the time.
+const CGFloat kWidth(300.0);
+
+class StyledTextFieldCellTest : public CocoaTest {
+ public:
+ StyledTextFieldCellTest() {
+ // Make sure this is wide enough to play games with the cell
+ // decorations.
+ const NSRect frame = NSMakeRect(0, 0, kWidth, 30);
+
+ scoped_nsobject<StyledTextFieldTestCell> cell(
+ [[StyledTextFieldTestCell alloc] initTextCell:@"Testing"]);
+ cell_ = cell.get();
+ [cell_ setEditable:YES];
+ [cell_ setBordered:YES];
+
+ scoped_nsobject<NSTextField> view(
+ [[NSTextField alloc] initWithFrame:frame]);
+ view_ = view.get();
+ [view_ setCell:cell_];
+
+ [[test_window() contentView] addSubview:view_];
+ }
+
+ //CocoaTestHelper cocoa_helper_; // Inits Cocoa, creates window, etc...
+ NSTextField* view_;
+ StyledTextFieldTestCell* cell_;
+};
+
+// Basic view tests (AddRemove, Display).
+TEST_VIEW(StyledTextFieldCellTest, view_);
+
+// Test drawing, mostly to ensure nothing leaks or crashes.
+TEST_F(StyledTextFieldCellTest, FocusedDisplay) {
+ [view_ display];
+
+ // Test focused drawing.
+ [test_window() makePretendKeyWindowAndSetFirstResponder:view_];
+ [view_ display];
+ [test_window() clearPretendKeyWindowAndFirstResponder];
+
+ // Test display of various cell configurations.
+ [cell_ setLeftMargin:5];
+ [view_ display];
+
+ [cell_ setRightMargin:15];
+ [view_ display];
+}
+
+// The editor frame should be slightly inset from the text frame.
+TEST_F(StyledTextFieldCellTest, DrawingRectForBounds) {
+ const NSRect bounds = [view_ bounds];
+ NSRect textFrame = [cell_ textFrameForFrame:bounds];
+ NSRect drawingRect = [cell_ drawingRectForBounds:bounds];
+
+ EXPECT_FALSE(NSIsEmptyRect(drawingRect));
+ EXPECT_TRUE(NSContainsRect(textFrame, NSInsetRect(drawingRect, 1, 1)));
+
+ // Save the starting frame for after clear.
+ const NSRect originalDrawingRect = drawingRect;
+
+ [cell_ setLeftMargin:10];
+ textFrame = [cell_ textFrameForFrame:bounds];
+ drawingRect = [cell_ drawingRectForBounds:bounds];
+ EXPECT_FALSE(NSIsEmptyRect(drawingRect));
+ EXPECT_TRUE(NSContainsRect(textFrame, NSInsetRect(drawingRect, 1, 1)));
+
+ [cell_ setRightMargin:20];
+ textFrame = [cell_ textFrameForFrame:bounds];
+ drawingRect = [cell_ drawingRectForBounds:bounds];
+ EXPECT_FALSE(NSIsEmptyRect(drawingRect));
+ EXPECT_TRUE(NSContainsRect(NSInsetRect(textFrame, 1, 1), drawingRect));
+
+ [cell_ setLeftMargin:0];
+ textFrame = [cell_ textFrameForFrame:bounds];
+ drawingRect = [cell_ drawingRectForBounds:bounds];
+ EXPECT_FALSE(NSIsEmptyRect(drawingRect));
+ EXPECT_TRUE(NSContainsRect(NSInsetRect(textFrame, 1, 1), drawingRect));
+}
+
+} // namespace
diff --git a/chrome/browser/cocoa/styled_text_field_test_helper.h b/chrome/browser/cocoa/styled_text_field_test_helper.h
new file mode 100644
index 0000000..20788d4
--- /dev/null
+++ b/chrome/browser/cocoa/styled_text_field_test_helper.h
@@ -0,0 +1,16 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Cocoa/Cocoa.h>
+#import "chrome/browser/cocoa/styled_text_field_cell.h"
+
+// Subclass of StyledTextFieldCell that allows you to slice off sections on the
+// left and right of the cell.
+@interface StyledTextFieldTestCell : StyledTextFieldCell {
+ CGFloat leftMargin_;
+ CGFloat rightMargin_;
+}
+@property(assign) CGFloat leftMargin;
+@property(assign) CGFloat rightMargin;
+@end
diff --git a/chrome/browser/cocoa/styled_text_field_test_helper.mm b/chrome/browser/cocoa/styled_text_field_test_helper.mm
new file mode 100644
index 0000000..fcae06a
--- /dev/null
+++ b/chrome/browser/cocoa/styled_text_field_test_helper.mm
@@ -0,0 +1,18 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Cocoa/Cocoa.h>
+#import "chrome/browser/cocoa/styled_text_field_test_helper.h"
+
+@implementation StyledTextFieldTestCell
+@synthesize leftMargin = leftMargin_;
+@synthesize rightMargin = rightMargin_;
+
+- (NSRect)textFrameForFrame:(NSRect)frame {
+ NSRect textFrame = [super textFrameForFrame:frame];
+ textFrame.origin.x += leftMargin_;
+ textFrame.size.width -= (leftMargin_ + rightMargin_);
+ return textFrame;
+}
+@end
diff --git a/chrome/browser/cocoa/styled_text_field_unittest.mm b/chrome/browser/cocoa/styled_text_field_unittest.mm
new file mode 100644
index 0000000..000e77a
--- /dev/null
+++ b/chrome/browser/cocoa/styled_text_field_unittest.mm
@@ -0,0 +1,198 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <Cocoa/Cocoa.h>
+
+#import "base/cocoa_protocols_mac.h"
+#include "base/scoped_nsobject.h"
+#import "chrome/browser/cocoa/styled_text_field.h"
+#import "chrome/browser/cocoa/styled_text_field_cell.h"
+#import "chrome/browser/cocoa/styled_text_field_test_helper.h"
+#import "chrome/browser/cocoa/cocoa_test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#import "third_party/ocmock/OCMock/OCMock.h"
+
+namespace {
+
+// Width of the field so that we don't have to ask |field_| for it all
+// the time.
+static const CGFloat kWidth(300.0);
+
+class StyledTextFieldTest : public CocoaTest {
+ public:
+ StyledTextFieldTest() {
+ // Make sure this is wide enough to play games with the cell
+ // decorations.
+ NSRect frame = NSMakeRect(0, 0, kWidth, 30);
+
+ scoped_nsobject<StyledTextFieldTestCell> cell(
+ [[StyledTextFieldTestCell alloc] initTextCell:@"Testing"]);
+ cell_ = cell.get();
+ [cell_ setEditable:YES];
+ [cell_ setBordered:YES];
+
+ scoped_nsobject<StyledTextField> field(
+ [[StyledTextField alloc] initWithFrame:frame]);
+ field_ = field.get();
+ [field_ setCell:cell_];
+
+ [[test_window() contentView] addSubview:field_];
+ }
+
+ // Helper to return the field-editor frame being used w/in |field_|.
+ NSRect EditorFrame() {
+ EXPECT_TRUE([field_ currentEditor]);
+ EXPECT_EQ([[field_ subviews] count], 1U);
+ if ([[field_ subviews] count] > 0) {
+ return [[[field_ subviews] objectAtIndex:0] frame];
+ } else {
+ // Return something which won't work so the caller can soldier
+ // on.
+ return NSZeroRect;
+ }
+ }
+
+ StyledTextField* field_;
+ StyledTextFieldTestCell* cell_;
+};
+
+// Basic view tests (AddRemove, Display).
+TEST_VIEW(StyledTextFieldTest, field_);
+
+// Test that we get the same cell from -cell and
+// -styledTextFieldCell.
+TEST_F(StyledTextFieldTest, Cell) {
+ StyledTextFieldCell* cell = [field_ styledTextFieldCell];
+ EXPECT_EQ(cell, [field_ cell]);
+ EXPECT_TRUE(cell != nil);
+}
+
+// Test that becoming first responder sets things up correctly.
+TEST_F(StyledTextFieldTest, FirstResponder) {
+ EXPECT_EQ(nil, [field_ currentEditor]);
+ EXPECT_EQ([[field_ subviews] count], 0U);
+ [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
+ EXPECT_FALSE(nil == [field_ currentEditor]);
+ EXPECT_EQ([[field_ subviews] count], 1U);
+ EXPECT_TRUE([[field_ currentEditor] isDescendantOf:field_]);
+}
+
+TEST_F(StyledTextFieldTest, AvailableDecorationWidth) {
+ // A fudge factor to account for how much space the border takes up.
+ // The test shouldn't be too dependent on the field's internals, but
+ // it also shouldn't let deranged cases fall through the cracks
+ // (like nothing available with no text, or everything available
+ // with some text).
+ const CGFloat kBorderWidth = 20.0;
+
+ // With no contents, almost the entire width is available for
+ // decorations.
+ [field_ setStringValue:@""];
+ CGFloat availableWidth = [field_ availableDecorationWidth];
+ EXPECT_LE(availableWidth, kWidth);
+ EXPECT_GT(availableWidth, kWidth - kBorderWidth);
+
+ // With minor contents, most of the remaining width is available for
+ // decorations.
+ NSDictionary* attributes =
+ [NSDictionary dictionaryWithObject:[field_ font]
+ forKey:NSFontAttributeName];
+ NSString* string = @"Hello world";
+ const NSSize size([string sizeWithAttributes:attributes]);
+ [field_ setStringValue:string];
+ availableWidth = [field_ availableDecorationWidth];
+ EXPECT_LE(availableWidth, kWidth - size.width);
+ EXPECT_GT(availableWidth, kWidth - size.width - kBorderWidth);
+
+ // With huge contents, nothing at all is left for decorations.
+ string = @"A long string which is surely wider than field_ can hold.";
+ [field_ setStringValue:string];
+ availableWidth = [field_ availableDecorationWidth];
+ EXPECT_LT(availableWidth, 0.0);
+}
+
+// Test drawing, mostly to ensure nothing leaks or crashes.
+TEST_F(StyledTextFieldTest, Display) {
+ [field_ display];
+
+ // Test focused drawing.
+ [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
+ [field_ display];
+}
+
+// Test that the field editor gets the same bounds when focus is delivered by
+// the standard focusing machinery, or by -resetFieldEditorFrameIfNeeded.
+TEST_F(StyledTextFieldTest, ResetFieldEditorBase) {
+ // Capture the editor frame resulting from the standard focus machinery.
+ [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
+ const NSRect baseEditorFrame(EditorFrame());
+
+ // Setting a hint should result in a strictly smaller editor frame.
+ EXPECT_EQ(0, [cell_ leftMargin]);
+ EXPECT_EQ(0, [cell_ rightMargin]);
+ [cell_ setLeftMargin:10];
+ [field_ resetFieldEditorFrameIfNeeded];
+ EXPECT_FALSE(NSEqualRects(baseEditorFrame, EditorFrame()));
+ EXPECT_TRUE(NSContainsRect(baseEditorFrame, EditorFrame()));
+
+ // Resetting the margin and using -resetFieldEditorFrameIfNeeded should result
+ // in the same frame as the standard focus machinery.
+ [cell_ setLeftMargin:0];
+ [field_ resetFieldEditorFrameIfNeeded];
+ EXPECT_TRUE(NSEqualRects(baseEditorFrame, EditorFrame()));
+}
+
+// Test that the field editor gets the same bounds when focus is delivered by
+// the standard focusing machinery, or by -resetFieldEditorFrameIfNeeded.
+TEST_F(StyledTextFieldTest, ResetFieldEditorLeftMargin) {
+ const CGFloat kLeftMargin = 20;
+
+ // Start the cell off with a non-zero left margin.
+ [cell_ setLeftMargin:kLeftMargin];
+ [cell_ setRightMargin:0];
+
+ // Capture the editor frame resulting from the standard focus machinery.
+ [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
+ const NSRect baseEditorFrame(EditorFrame());
+
+ // Clearing the margin should result in a strictly larger editor frame.
+ [cell_ setLeftMargin:0];
+ [field_ resetFieldEditorFrameIfNeeded];
+ EXPECT_FALSE(NSEqualRects(baseEditorFrame, EditorFrame()));
+ EXPECT_TRUE(NSContainsRect(EditorFrame(), baseEditorFrame));
+
+ // Setting the same margin and using -resetFieldEditorFrameIfNeeded should
+ // result in the same frame as the standard focus machinery.
+ [cell_ setLeftMargin:kLeftMargin];
+ [field_ resetFieldEditorFrameIfNeeded];
+ EXPECT_TRUE(NSEqualRects(baseEditorFrame, EditorFrame()));
+}
+
+// Test that the field editor gets the same bounds when focus is delivered by
+// the standard focusing machinery, or by -resetFieldEditorFrameIfNeeded.
+TEST_F(StyledTextFieldTest, ResetFieldEditorRightMargin) {
+ const CGFloat kRightMargin = 20;
+
+ // Start the cell off with a non-zero right margin.
+ [cell_ setLeftMargin:0];
+ [cell_ setRightMargin:kRightMargin];
+
+ // Capture the editor frame resulting from the standard focus machinery.
+ [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
+ const NSRect baseEditorFrame(EditorFrame());
+
+ // Clearing the margin should result in a strictly larger editor frame.
+ [cell_ setRightMargin:0];
+ [field_ resetFieldEditorFrameIfNeeded];
+ EXPECT_FALSE(NSEqualRects(baseEditorFrame, EditorFrame()));
+ EXPECT_TRUE(NSContainsRect(EditorFrame(), baseEditorFrame));
+
+ // Setting the same margin and using -resetFieldEditorFrameIfNeeded should
+ // result in the same frame as the standard focus machinery.
+ [cell_ setRightMargin:kRightMargin];
+ [field_ resetFieldEditorFrameIfNeeded];
+ EXPECT_TRUE(NSEqualRects(baseEditorFrame, EditorFrame()));
+}
+
+} // namespace
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 9ac647f..43711d0 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1143,6 +1143,10 @@
'browser/cocoa/find_bar_bridge.mm',
'browser/cocoa/find_bar_cocoa_controller.h',
'browser/cocoa/find_bar_cocoa_controller.mm',
+ 'browser/cocoa/find_bar_text_field.h',
+ 'browser/cocoa/find_bar_text_field.mm',
+ 'browser/cocoa/find_bar_text_field_cell.h',
+ 'browser/cocoa/find_bar_text_field_cell.mm',
'browser/cocoa/find_bar_view.h',
'browser/cocoa/find_bar_view.mm',
'browser/cocoa/find_pasteboard.h',
@@ -1212,6 +1216,10 @@
'browser/cocoa/shell_dialogs_mac.mm',
'browser/cocoa/status_bubble_mac.h',
'browser/cocoa/status_bubble_mac.mm',
+ 'browser/cocoa/styled_text_field.h',
+ 'browser/cocoa/styled_text_field.mm',
+ 'browser/cocoa/styled_text_field_cell.h',
+ 'browser/cocoa/styled_text_field_cell.mm',
'browser/cocoa/tab_contents_controller.h',
'browser/cocoa/tab_contents_controller.mm',
'browser/cocoa/tab_controller.h',
@@ -4532,6 +4540,8 @@
'browser/cocoa/event_utils_unittest.mm',
'browser/cocoa/find_bar_bridge_unittest.mm',
'browser/cocoa/find_bar_cocoa_controller_unittest.mm',
+ 'browser/cocoa/find_bar_text_field_unittest.mm',
+ 'browser/cocoa/find_bar_text_field_cell_unittest.mm',
'browser/cocoa/find_bar_view_unittest.mm',
'browser/cocoa/find_pasteboard_unittest.mm',
'browser/cocoa/focus_tracker_unittest.mm',
@@ -4559,6 +4569,10 @@
'browser/cocoa/sad_tab_view_unittest.mm',
'browser/cocoa/search_engine_list_model_unittest.mm',
'browser/cocoa/status_bubble_mac_unittest.mm',
+ 'browser/cocoa/styled_text_field_test_helper.h',
+ 'browser/cocoa/styled_text_field_test_helper.mm',
+ 'browser/cocoa/styled_text_field_unittest.mm',
+ 'browser/cocoa/styled_text_field_cell_unittest.mm',
'browser/cocoa/tab_controller_unittest.mm',
'browser/cocoa/tab_strip_controller_unittest.mm',
'browser/cocoa/tab_strip_view_unittest.mm',