diff options
author | jrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-14 00:58:17 +0000 |
---|---|---|
committer | jrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-14 00:58:17 +0000 |
commit | 7a1951a2d5a549f49714aa243c5f51fa9b86f7a8 (patch) | |
tree | 07805676229df685a71734c3a1b031168af057d1 | |
parent | 7cd22a5102842cfbb51e06c626d769d81bb78210 (diff) | |
download | chromium_src-7a1951a2d5a549f49714aa243c5f51fa9b86f7a8.zip chromium_src-7a1951a2d5a549f49714aa243c5f51fa9b86f7a8.tar.gz chromium_src-7a1951a2d5a549f49714aa243c5f51fa9b86f7a8.tar.bz2 |
More bookmark bar changes.
* Applied memory cleanliness fix in unit test; follow-up from
http://codereview.chromium.org/149308.
* Move bookmark bar into it's own nib; minor code refactor to
accomodate.
* The toolbar STAR button somehow lost it's action; added it back in.
* Implemented delete bookmark notification callback so we behave
(remove button from the screen) when a bookmark is deleted.
* Added context menus for the bookmark bar and bookmark buttons.
* Hooked up a handful of these menu items. E.g.
- open in new tab, window, incog window
- delete bookmark (finally)
- bookmark manager (which then hits a NOTIMPLEMENTED())
- always show bookmark bar
* Truncate bookmark button text on end, not on middle.
Experimental to look more like Windows.
It looks cleaner but is less Mac-like.
* Add "draws border when mouse goes over" for bookmark buttons. Need
to do it by hand since we have a custom button drawing method.
BUG=crbug.com/8381
TEST=Here's a list:
- Make sure the bookmark buttons don't have a border unless the mouse is over them
- Toolbar "STAR" should now add bookmarks when clicked
- Test context menus on bookmark buttons, and the bar itself
- Confirm a few of the behaviors as listed in the 'what I hooked up'; e.g.
Right click on bookmark --> delete menu item should delete button
Review URL: http://codereview.chromium.org/155358
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20591 0039d316-1c4b-4281-b951-d872f2087c98
21 files changed, 1285 insertions, 142 deletions
diff --git a/chrome/app/nibs/en.lproj/BookmarkBar.xib b/chrome/app/nibs/en.lproj/BookmarkBar.xib new file mode 100644 index 0000000..2002d9b --- /dev/null +++ b/chrome/app/nibs/en.lproj/BookmarkBar.xib @@ -0,0 +1,854 @@ +<?xml version="1.0" encoding="UTF-8"?> +<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.03"> + <data> + <int key="IBDocument.SystemTarget">1050</int> + <string key="IBDocument.SystemVersion">9J61</string> + <string key="IBDocument.InterfaceBuilderVersion">677</string> + <string key="IBDocument.AppKitVersion">949.46</string> + <string key="IBDocument.HIToolboxVersion">353.00</string> + <object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> + <bool key="EncodedWithXMLCoder">YES</bool> + <integer value="1"/> + <integer value="4"/> + <integer value="18"/> + </object> + <object class="NSArray" key="IBDocument.PluginDependencies"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + </object> + <object class="NSMutableDictionary" key="IBDocument.Metadata"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSArray" key="dict.sortedKeys"> + <bool key="EncodedWithXMLCoder">YES</bool> + </object> + <object class="NSMutableArray" key="dict.values"> + <bool key="EncodedWithXMLCoder">YES</bool> + </object> + </object> + <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSCustomObject" id="1001"> + <string key="NSClassName">BookmarkBarController</string> + </object> + <object class="NSCustomObject" id="1003"> + <string key="NSClassName">FirstResponder</string> + </object> + <object class="NSCustomObject" id="1004"> + <string key="NSClassName">NSApplication</string> + </object> + <object class="NSCustomView" id="620641226"> + <reference key="NSNextResponder"/> + <int key="NSvFlags">-2147483358</int> + <string key="NSFrameSize">{468, 65}</string> + <reference key="NSSuperview"/> + <string key="NSClassName">BookmarkBarView</string> + </object> + <object class="NSMenu" id="183701277"> + <string key="NSTitle"/> + <object class="NSMutableArray" key="NSMenuItems"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSMenuItem" id="6422781"> + <reference key="NSMenu" ref="183701277"/> + <string key="NSTitle">Open all bookmarks</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <object class="NSCustomResource" key="NSOnImage" id="636322919"> + <string key="NSClassName">NSImage</string> + <string key="NSResourceName">NSMenuCheckmark</string> + </object> + <object class="NSCustomResource" key="NSMixedImage" id="607448274"> + <string key="NSClassName">NSImage</string> + <string key="NSResourceName">NSMenuMixedState</string> + </object> + </object> + <object class="NSMenuItem" id="115646576"> + <reference key="NSMenu" ref="183701277"/> + <string key="NSTitle">Open all bookmarks in new window</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="509003741"> + <reference key="NSMenu" ref="183701277"/> + <string key="NSTitle">Open all bookmarks in incognito window</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="694014238"> + <reference key="NSMenu" ref="183701277"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="112128065"> + <reference key="NSMenu" ref="183701277"/> + <string key="NSTitle">Rename...</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="168951506"> + <reference key="NSMenu" ref="183701277"/> + <string key="NSTitle">Delete</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="1022383113"> + <reference key="NSMenu" ref="183701277"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="926809071"> + <reference key="NSMenu" ref="183701277"/> + <string key="NSTitle">Add page...</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="90793013"> + <reference key="NSMenu" ref="183701277"/> + <string key="NSTitle">Add folder...</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="149427359"> + <reference key="NSMenu" ref="183701277"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="61770624"> + <reference key="NSMenu" ref="183701277"/> + <string key="NSTitle">Bookmark manager</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + <int key="NSTag">40011</int> + </object> + <object class="NSMenuItem" id="23014313"> + <reference key="NSMenu" ref="183701277"/> + <string key="NSTitle">Always show bookmarks bar</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + <int key="NSTag">40009</int> + </object> + </object> + </object> + <object class="NSMenu" id="672481054"> + <string key="NSTitle"/> + <object class="NSMutableArray" key="NSMenuItems"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSMenuItem" id="1071747565"> + <reference key="NSMenu" ref="672481054"/> + <string key="NSTitle">Open in new tab</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="308357419"> + <reference key="NSMenu" ref="672481054"/> + <string key="NSTitle">Open in new window</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="300791080"> + <reference key="NSMenu" ref="672481054"/> + <string key="NSTitle">Open in incognito window</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="878416689"> + <reference key="NSMenu" ref="672481054"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="182996500"> + <reference key="NSMenu" ref="672481054"/> + <string key="NSTitle">Edit...</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="908072523"> + <reference key="NSMenu" ref="672481054"/> + <string key="NSTitle">Delete</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="554011295"> + <reference key="NSMenu" ref="672481054"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="527115352"> + <reference key="NSMenu" ref="672481054"/> + <string key="NSTitle">Add page...</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="595609715"> + <reference key="NSMenu" ref="672481054"/> + <string key="NSTitle">Add folder...</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="422582534"> + <reference key="NSMenu" ref="672481054"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + </object> + <object class="NSMenuItem" id="807677456"> + <reference key="NSMenu" ref="672481054"/> + <string key="NSTitle">Bookmark manager</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + <int key="NSTag">40011</int> + </object> + <object class="NSMenuItem" id="515274494"> + <reference key="NSMenu" ref="672481054"/> + <string key="NSTitle">Always show bookmarks bar</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="636322919"/> + <reference key="NSMixedImage" ref="607448274"/> + <int key="NSTag">40009</int> + </object> + </object> + </object> + </object> + <object class="IBObjectContainer" key="IBDocument.Objects"> + <object class="NSMutableArray" key="connectionRecords"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">view</string> + <reference key="source" ref="1001"/> + <reference key="destination" ref="620641226"/> + </object> + <int key="connectionID">3</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">barContextualMenu_</string> + <reference key="source" ref="620641226"/> + <reference key="destination" ref="183701277"/> + </object> + <int key="connectionID">17</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">buttonContextMenu_</string> + <reference key="source" ref="1001"/> + <reference key="destination" ref="672481054"/> + </object> + <int key="connectionID">31</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1003"/> + <reference key="destination" ref="6422781"/> + </object> + <int key="connectionID">32</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1003"/> + <reference key="destination" ref="115646576"/> + </object> + <int key="connectionID">33</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1003"/> + <reference key="destination" ref="509003741"/> + </object> + <int key="connectionID">34</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1003"/> + <reference key="destination" ref="112128065"/> + </object> + <int key="connectionID">35</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1003"/> + <reference key="destination" ref="168951506"/> + </object> + <int key="connectionID">36</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1003"/> + <reference key="destination" ref="926809071"/> + </object> + <int key="connectionID">37</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1003"/> + <reference key="destination" ref="90793013"/> + </object> + <int key="connectionID">38</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1003"/> + <reference key="destination" ref="61770624"/> + </object> + <int key="connectionID">39</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1003"/> + <reference key="destination" ref="23014313"/> + </object> + <int key="connectionID">40</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1003"/> + <reference key="destination" ref="182996500"/> + </object> + <int key="connectionID">44</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1003"/> + <reference key="destination" ref="527115352"/> + </object> + <int key="connectionID">46</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1003"/> + <reference key="destination" ref="595609715"/> + </object> + <int key="connectionID">47</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1003"/> + <reference key="destination" ref="807677456"/> + </object> + <int key="connectionID">48</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1003"/> + <reference key="destination" ref="515274494"/> + </object> + <int key="connectionID">49</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">openBookmarkInNewForegroundTab:</string> + <reference key="source" ref="1001"/> + <reference key="destination" ref="1071747565"/> + </object> + <int key="connectionID">52</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">openBookmarkInNewWindow:</string> + <reference key="source" ref="1001"/> + <reference key="destination" ref="308357419"/> + </object> + <int key="connectionID">53</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">openBookmarkInIncognitoWindow:</string> + <reference key="source" ref="1001"/> + <reference key="destination" ref="300791080"/> + </object> + <int key="connectionID">54</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">deleteBookmark:</string> + <reference key="source" ref="1001"/> + <reference key="destination" ref="908072523"/> + </object> + <int key="connectionID">55</int> + </object> + </object> + <object class="IBMutableOrderedSet" key="objectRecords"> + <object class="NSArray" key="orderedObjects"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="IBObjectRecord"> + <int key="objectID">0</int> + <object class="NSArray" key="object" id="1002"> + <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="1002"/> + <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="1002"/> + <string key="objectName">First Responder</string> + </object> + <object class="IBObjectRecord"> + <int key="objectID">-3</int> + <reference key="object" ref="1004"/> + <reference key="parent" ref="1002"/> + <string key="objectName">Application</string> + </object> + <object class="IBObjectRecord"> + <int key="objectID">1</int> + <reference key="object" ref="620641226"/> + <reference key="parent" ref="1002"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">4</int> + <reference key="object" ref="183701277"/> + <object class="NSMutableArray" key="children"> + <bool key="EncodedWithXMLCoder">YES</bool> + <reference ref="6422781"/> + <reference ref="115646576"/> + <reference ref="509003741"/> + <reference ref="694014238"/> + <reference ref="1022383113"/> + <reference ref="112128065"/> + <reference ref="168951506"/> + <reference ref="926809071"/> + <reference ref="90793013"/> + <reference ref="61770624"/> + <reference ref="23014313"/> + <reference ref="149427359"/> + </object> + <reference key="parent" ref="1002"/> + <string key="objectName">Bar Menu</string> + </object> + <object class="IBObjectRecord"> + <int key="objectID">5</int> + <reference key="object" ref="6422781"/> + <reference key="parent" ref="183701277"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">6</int> + <reference key="object" ref="115646576"/> + <reference key="parent" ref="183701277"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">7</int> + <reference key="object" ref="509003741"/> + <reference key="parent" ref="183701277"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">8</int> + <reference key="object" ref="694014238"/> + <reference key="parent" ref="183701277"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">9</int> + <reference key="object" ref="1022383113"/> + <reference key="parent" ref="183701277"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">10</int> + <reference key="object" ref="149427359"/> + <reference key="parent" ref="183701277"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">11</int> + <reference key="object" ref="112128065"/> + <reference key="parent" ref="183701277"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">12</int> + <reference key="object" ref="168951506"/> + <reference key="parent" ref="183701277"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">13</int> + <reference key="object" ref="926809071"/> + <reference key="parent" ref="183701277"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">14</int> + <reference key="object" ref="90793013"/> + <reference key="parent" ref="183701277"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">15</int> + <reference key="object" ref="61770624"/> + <reference key="parent" ref="183701277"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">16</int> + <reference key="object" ref="23014313"/> + <reference key="parent" ref="183701277"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">18</int> + <reference key="object" ref="672481054"/> + <object class="NSMutableArray" key="children"> + <bool key="EncodedWithXMLCoder">YES</bool> + <reference ref="422582534"/> + <reference ref="515274494"/> + <reference ref="807677456"/> + <reference ref="595609715"/> + <reference ref="527115352"/> + <reference ref="908072523"/> + <reference ref="182996500"/> + <reference ref="554011295"/> + <reference ref="878416689"/> + <reference ref="300791080"/> + <reference ref="308357419"/> + <reference ref="1071747565"/> + </object> + <reference key="parent" ref="1002"/> + <string key="objectName">Button Menu</string> + </object> + <object class="IBObjectRecord"> + <int key="objectID">19</int> + <reference key="object" ref="422582534"/> + <reference key="parent" ref="672481054"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">20</int> + <reference key="object" ref="515274494"/> + <reference key="parent" ref="672481054"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">21</int> + <reference key="object" ref="807677456"/> + <reference key="parent" ref="672481054"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">22</int> + <reference key="object" ref="595609715"/> + <reference key="parent" ref="672481054"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">23</int> + <reference key="object" ref="527115352"/> + <reference key="parent" ref="672481054"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">24</int> + <reference key="object" ref="908072523"/> + <reference key="parent" ref="672481054"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">25</int> + <reference key="object" ref="182996500"/> + <reference key="parent" ref="672481054"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">26</int> + <reference key="object" ref="554011295"/> + <reference key="parent" ref="672481054"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">27</int> + <reference key="object" ref="878416689"/> + <reference key="parent" ref="672481054"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">28</int> + <reference key="object" ref="300791080"/> + <reference key="parent" ref="672481054"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">29</int> + <reference key="object" ref="308357419"/> + <reference key="parent" ref="672481054"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">30</int> + <reference key="object" ref="1071747565"/> + <reference key="parent" ref="672481054"/> + </object> + </object> + </object> + <object class="NSMutableDictionary" key="flattenedProperties"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSMutableArray" key="dict.sortedKeys"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>-1.IBPluginDependency</string> + <string>-2.IBPluginDependency</string> + <string>-3.IBPluginDependency</string> + <string>1.IBEditorWindowLastContentRect</string> + <string>1.IBPluginDependency</string> + <string>10.IBPluginDependency</string> + <string>11.IBPluginDependency</string> + <string>12.IBPluginDependency</string> + <string>13.IBPluginDependency</string> + <string>14.IBPluginDependency</string> + <string>15.IBPluginDependency</string> + <string>16.IBPluginDependency</string> + <string>18.IBEditorWindowLastContentRect</string> + <string>18.IBPluginDependency</string> + <string>19.IBPluginDependency</string> + <string>20.IBPluginDependency</string> + <string>21.IBPluginDependency</string> + <string>22.IBPluginDependency</string> + <string>23.IBPluginDependency</string> + <string>24.IBPluginDependency</string> + <string>25.IBPluginDependency</string> + <string>26.IBPluginDependency</string> + <string>27.IBPluginDependency</string> + <string>28.IBPluginDependency</string> + <string>29.IBPluginDependency</string> + <string>30.IBPluginDependency</string> + <string>4.IBEditorWindowLastContentRect</string> + <string>4.IBPluginDependency</string> + <string>5.IBPluginDependency</string> + <string>6.IBPluginDependency</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>{{519, 625}, {468, 65}}</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> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>{{859, 729}, {249, 213}}</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> + <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> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>{{518, 726}, {334, 213}}</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> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + </object> + </object> + <object class="NSMutableDictionary" key="unlocalizedProperties"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSArray" key="dict.sortedKeys"> + <bool key="EncodedWithXMLCoder">YES</bool> + </object> + <object class="NSMutableArray" key="dict.values"> + <bool key="EncodedWithXMLCoder">YES</bool> + </object> + </object> + <nil key="activeLocalization"/> + <object class="NSMutableDictionary" key="localizations"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSArray" key="dict.sortedKeys"> + <bool key="EncodedWithXMLCoder">YES</bool> + </object> + <object class="NSMutableArray" key="dict.values"> + <bool key="EncodedWithXMLCoder">YES</bool> + </object> + </object> + <nil key="sourceID"/> + <int key="maxID">55</int> + </object> + <object class="IBClassDescriber" key="IBDocument.Classes"> + <object class="NSMutableArray" key="referencedPartialClassDescriptions"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="IBPartialClassDescription"> + <string key="className">BackgroundGradientView</string> + <string key="superclassName">NSView</string> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">browser/cocoa/background_gradient_view.h</string> + </object> + </object> + <object class="IBPartialClassDescription"> + <string key="className">BookmarkBarController</string> + <string key="superclassName">NSViewController</string> + <object class="NSMutableDictionary" key="actions"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSMutableArray" key="dict.sortedKeys"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>deleteBookmark:</string> + <string>openBookmark:</string> + <string>openBookmarkInIncognitoWindow:</string> + <string>openBookmarkInNewForegroundTab:</string> + <string>openBookmarkInNewWindow:</string> + </object> + <object class="NSMutableArray" key="dict.values"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>id</string> + <string>id</string> + <string>id</string> + <string>id</string> + <string>id</string> + </object> + </object> + <object class="NSMutableDictionary" key="outlets"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSMutableArray" key="dict.sortedKeys"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>buttonContextMenu_</string> + <string>delegate_</string> + </object> + <object class="NSMutableArray" key="dict.values"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>NSMenu</string> + <string>id</string> + </object> + </object> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">browser/cocoa/bookmark_bar_controller.h</string> + </object> + </object> + <object class="IBPartialClassDescription"> + <string key="className">BookmarkBarView</string> + <string key="superclassName">BackgroundGradientView</string> + <object class="NSMutableDictionary" key="outlets"> + <string key="NS.key.0">barContextualMenu_</string> + <string key="NS.object.0">NSMenu</string> + </object> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">browser/cocoa/bookmark_bar_view.h</string> + </object> + </object> + <object class="IBPartialClassDescription"> + <string key="className">NSObject</string> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">browser/cocoa/tab_strip_model_observer_bridge.h</string> + </object> + </object> + <object class="IBPartialClassDescription"> + <string key="className">TabController</string> + <string key="superclassName">NSViewController</string> + <object class="NSMutableDictionary" key="actions"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSMutableArray" key="dict.sortedKeys"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>closeTab:</string> + <string>commandDispatch:</string> + </object> + <object class="NSMutableArray" key="dict.values"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>id</string> + <string>id</string> + </object> + </object> + <object class="NSMutableDictionary" key="outlets"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSMutableArray" key="dict.sortedKeys"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>backgroundButton_</string> + <string>contextMenu_</string> + <string>iconView_</string> + <string>target_</string> + </object> + <object class="NSMutableArray" key="dict.values"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>NSButton</string> + <string>NSMenu</string> + <string>NSView</string> + <string>id</string> + </object> + </object> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">browser/cocoa/tab_controller.h</string> + </object> + </object> + </object> + </object> + <int key="IBDocument.localizationMode">0</int> + <string key="IBDocument.LastKnownRelativeProjectPath">../../../chrome.xcodeproj</string> + <int key="IBDocument.defaultPropertyAccessControl">3</int> + </data> +</archive> diff --git a/chrome/app/nibs/en.lproj/Toolbar.xib b/chrome/app/nibs/en.lproj/Toolbar.xib index c4949aa..0eeeffd 100644 --- a/chrome/app/nibs/en.lproj/Toolbar.xib +++ b/chrome/app/nibs/en.lproj/Toolbar.xib @@ -290,13 +290,6 @@ <int key="NSPeriodicInterval">75</int> </object> </object> - <object class="NSCustomView" id="1060691879"> - <reference key="NSNextResponder" ref="928520650"/> - <int key="NSvFlags">-2147483358</int> - <string key="NSFrameSize">{607, 20}</string> - <reference key="NSSuperview" ref="928520650"/> - <string key="NSClassName">BookmarkBarView</string> - </object> </object> <string key="NSFrameSize">{607, 39}</string> <reference key="NSSuperview"/> @@ -1051,12 +1044,12 @@ <int key="connectionID">118</int> </object> <object class="IBConnectionRecord"> - <object class="IBOutletConnection" key="connection"> - <string key="label">bookmarkBarView_</string> - <reference key="source" ref="1001"/> - <reference key="destination" ref="1060691879"/> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1003"/> + <reference key="destination" ref="559273956"/> </object> - <int key="connectionID">120</int> + <int key="connectionID">121</int> </object> </object> <object class="IBMutableOrderedSet" key="objectRecords"> @@ -1102,7 +1095,6 @@ <reference ref="559273956"/> <reference ref="571076484"/> <reference ref="602421009"/> - <reference ref="1060691879"/> </object> <reference key="parent" ref="1002"/> </object> @@ -1512,11 +1504,6 @@ <reference key="object" ref="510846575"/> <reference key="parent" ref="558188039"/> </object> - <object class="IBObjectRecord"> - <int key="objectID">119</int> - <reference key="object" ref="1060691879"/> - <reference key="parent" ref="928520650"/> - </object> </object> </object> <object class="NSMutableDictionary" key="flattenedProperties"> @@ -1539,7 +1526,6 @@ <string>105.IBPluginDependency</string> <string>106.IBPluginDependency</string> <string>107.IBPluginDependency</string> - <string>119.IBPluginDependency</string> <string>12.CustomClassName</string> <string>12.IBPluginDependency</string> <string>13.CustomClassName</string> @@ -1624,7 +1610,6 @@ <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>ToolbarButtonCell</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>LocationBarCell</string> @@ -1712,7 +1697,7 @@ </object> </object> <nil key="sourceID"/> - <int key="maxID">120</int> + <int key="maxID">121</int> </object> <object class="IBClassDescriber" key="IBDocument.Classes"> <object class="NSMutableArray" key="referencedPartialClassDescriptions"> @@ -1762,14 +1747,6 @@ </object> </object> <object class="IBPartialClassDescription"> - <string key="className">BookmarkBarView</string> - <string key="superclassName">BackgroundGradientView</string> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBProjectSource</string> - <string key="minorKey">browser/cocoa/bookmark_bar_view.h</string> - </object> - </object> - <object class="IBPartialClassDescription"> <string key="className">FirstResponder</string> <string key="superclassName">NSObject</string> <object class="NSMutableDictionary" key="actions"> @@ -1932,7 +1909,6 @@ <bool key="EncodedWithXMLCoder">YES</bool> <string>backButton_</string> <string>bookmarkBarDelegate_</string> - <string>bookmarkBarView_</string> <string>forwardButton_</string> <string>goButton_</string> <string>homeButton_</string> @@ -1948,7 +1924,6 @@ <bool key="EncodedWithXMLCoder">YES</bool> <string>NSButton</string> <string>id</string> - <string>BookmarkBarView</string> <string>NSButton</string> <string>NSButton</string> <string>NSButton</string> diff --git a/chrome/browser/cocoa/bookmark_bar_bridge.h b/chrome/browser/cocoa/bookmark_bar_bridge.h index 79805953..a6661cc 100644 --- a/chrome/browser/cocoa/bookmark_bar_bridge.h +++ b/chrome/browser/cocoa/bookmark_bar_bridge.h @@ -33,6 +33,9 @@ class BookmarkBarBridge : public BookmarkModelObserver { virtual void BookmarkNodeAdded(BookmarkModel* model, const BookmarkNode* parent, int index); + virtual void BookmarkNodeRemoved(BookmarkModel* model, + const BookmarkNode* parent, + int index); virtual void BookmarkNodeChanged(BookmarkModel* model, const BookmarkNode* node); virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, diff --git a/chrome/browser/cocoa/bookmark_bar_bridge.mm b/chrome/browser/cocoa/bookmark_bar_bridge.mm index 2263a3c..4e13218 100644 --- a/chrome/browser/cocoa/bookmark_bar_bridge.mm +++ b/chrome/browser/cocoa/bookmark_bar_bridge.mm @@ -44,6 +44,12 @@ void BookmarkBarBridge::BookmarkNodeAdded(BookmarkModel* model, [controller_ nodeAdded:model parent:parent index:index]; } +void BookmarkBarBridge::BookmarkNodeRemoved(BookmarkModel* model, + const BookmarkNode* parent, + int index) { + [controller_ nodeRemoved:model parent:parent index:index]; +} + void BookmarkBarBridge::BookmarkNodeChanged(BookmarkModel* model, const BookmarkNode* node) { [controller_ nodeChanged:model node:node]; diff --git a/chrome/browser/cocoa/bookmark_bar_bridge_unittest.mm b/chrome/browser/cocoa/bookmark_bar_bridge_unittest.mm index 687c64a..0a21e04 100644 --- a/chrome/browser/cocoa/bookmark_bar_bridge_unittest.mm +++ b/chrome/browser/cocoa/bookmark_bar_bridge_unittest.mm @@ -32,10 +32,12 @@ typedef std::pair<GURL,WindowOpenDisposition> OpenInfo; @implementation FakeBookmarkBarController -- (id)initWithProfile:(Profile*)profile view:(NSView*)view { +- (id)initWithProfile:(Profile*)profile + parentView:(NSView*)parentView + webContentView:(NSView*)webContentView { if ((self = [super initWithProfile:profile - view:(BookmarkBarView*)view - webContentView:nil + parentView:parentView + webContentView:webContentView delegate:self])) { callbacks_.reset([[NSMutableArray alloc] init]); } @@ -76,6 +78,11 @@ typedef std::pair<GURL,WindowOpenDisposition> OpenInfo; [callbacks_ addObject:[NSNumber numberWithInt:6]]; } +- (void)nodeRemoved:(BookmarkModel*)model + parent:(const BookmarkNode*)oldParent index:(int)index { + [callbacks_ addObject:[NSNumber numberWithInt:7]]; +} + // Save the request. - (void)openBookmarkURL:(const GURL&)url disposition:(WindowOpenDisposition)disposition { @@ -102,12 +109,16 @@ TEST_F(BookmarkBarBridgeTest, TestRedirect) { Profile *profile = browser_test_helper_.profile(); BookmarkModel *model = profile->GetBookmarkModel(); - scoped_nsobject<NSView> view([[NSView alloc] - initWithFrame:NSMakeRect(0,0,10,10)]); - [view.get() setHidden:YES]; + scoped_nsobject<NSView> parentView([[NSView alloc] + initWithFrame:NSMakeRect(0,0,100,100)]); + scoped_nsobject<NSView> webView([[NSView alloc] + initWithFrame:NSMakeRect(0,0,100,100)]); + scoped_nsobject<FakeBookmarkBarController> - controller([[FakeBookmarkBarController alloc] initWithProfile:profile - view:view.get()]); + controller([[FakeBookmarkBarController alloc] + initWithProfile:profile + parentView:parentView.get() + webContentView:webView.get()]); EXPECT_TRUE(controller.get()); scoped_ptr<BookmarkBarBridge> bridge(new BookmarkBarBridge(controller.get(), model)); @@ -120,11 +131,12 @@ TEST_F(BookmarkBarBridgeTest, TestRedirect) { bridge->BookmarkNodeChanged(NULL, NULL); bridge->BookmarkNodeFavIconLoaded(NULL, NULL); bridge->BookmarkNodeChildrenReordered(NULL, NULL); + bridge->BookmarkNodeRemoved(NULL, NULL, 0); - // 7 calls above plus an initial Loaded() in init routine makes 8 - EXPECT_TRUE([controller.get()->callbacks_ count] == 8); + // 8 calls above plus an initial Loaded() in init routine makes 9 + EXPECT_TRUE([controller.get()->callbacks_ count] == 9); - for (int x = 1; x < 8; x++) { + for (int x = 1; x < 9; x++) { NSNumber *num = [NSNumber numberWithInt:x-1]; EXPECT_TRUE([[controller.get()->callbacks_ objectAtIndex:x] isEqual:num]); } diff --git a/chrome/browser/cocoa/bookmark_bar_controller.h b/chrome/browser/cocoa/bookmark_bar_controller.h index 1993411..5d401de 100644 --- a/chrome/browser/cocoa/bookmark_bar_controller.h +++ b/chrome/browser/cocoa/bookmark_bar_controller.h @@ -27,7 +27,7 @@ class PrefService; // A controller for the bookmark bar in the browser window. Handles showing // and hiding based on the preference in the given profile. -@interface BookmarkBarController : NSObject { +@interface BookmarkBarController : NSViewController { @private BookmarkModel* bookmarkModel_; // weak; part of the profile owned by the // top-level Browser object. @@ -44,10 +44,7 @@ class PrefService; // Set when using fullscreen mode. BOOL barIsEnabled_; - // The view of the bookmark bar itself. - // Owned by the toolbar view, its parent view. - BookmarkBarView* bookmarkBarView_; // weak - + NSView* parentView_; // weak; our parent view NSView* webContentView_; // weak; where the web goes // Bridge from Chrome-style C++ notifications (e.g. derived from @@ -56,14 +53,15 @@ class PrefService; // Delegate which can open URLs for us. id<BookmarkURLOpener> delegate_; // weak + + IBOutlet NSMenu* buttonContextMenu_; } -// Initializes the controller with the given browser profile and -// content view. We use |webContentView| as the view for the bookmark -// bar view and for geometry management. |delegate| is used for -// opening URLs. |view| is expected to be hidden. +// Initializes the bookmark bar controller with the given browser +// profile, parent view (the toolbar), web content view, and delegate. +// |delegate| is used for opening URLs. - (id)initWithProfile:(Profile*)profile - view:(BookmarkBarView*)view + parentView:(NSView*)parentView webContentView:(NSView*)webContentView delegate:(id<BookmarkURLOpener>)delegate; @@ -78,6 +76,14 @@ class PrefService; // if needed. For fullscreen mode. - (void)setBookmarkBarEnabled:(BOOL)enabled; +// Actions for opening bookmarks. From a button, ... +- (IBAction)openBookmark:(id)sender; +// ... or from a context menu over the button. +- (IBAction)openBookmarkInNewForegroundTab:(id)sender; +- (IBAction)openBookmarkInNewWindow:(id)sender; +- (IBAction)openBookmarkInIncognitoWindow:(id)sender; +- (IBAction)deleteBookmark:(id)sender; + @end // Redirects from BookmarkBarBridge, the C++ object which glues us to @@ -90,6 +96,8 @@ class PrefService; newParent:(const BookmarkNode*)newParent newIndex:(int)newIndex; - (void)nodeAdded:(BookmarkModel*)model parent:(const BookmarkNode*)oldParent index:(int)index; +- (void)nodeRemoved:(BookmarkModel*)model + parent:(const BookmarkNode*)oldParent index:(int)index; - (void)nodeChanged:(BookmarkModel*)model node:(const BookmarkNode*)node; - (void)nodeFavIconLoaded:(BookmarkModel*)model @@ -101,12 +109,8 @@ class PrefService; // These APIs should only be used by unit tests (or used internally). @interface BookmarkBarController(TestingAPI) -// Access to the bookmark bar's view represented by this controller. -- (NSView*)view; // Set the delegate for a unit test. - (void)setDelegate:(id<BookmarkURLOpener>)delegate; -// Action for our bookmark buttons. -- (void)openBookmark:(id)sender; @end #endif // CHROME_BROWSER_COCOA_BOOKMARK_BAR_CONTROLLER_H_ diff --git a/chrome/browser/cocoa/bookmark_bar_controller.mm b/chrome/browser/cocoa/bookmark_bar_controller.mm index 7550c99..4cf5d07 100644 --- a/chrome/browser/cocoa/bookmark_bar_controller.mm +++ b/chrome/browser/cocoa/bookmark_bar_controller.mm @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/mac_util.h" #include "base/sys_string_conversions.h" #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/browser.h" @@ -22,6 +23,9 @@ namespace { +// TODO(jrg): this is the right proportional height but overlaps the +// "blue outline" of the omnibox. Fix. + // Our height, when opened. const int kBookmarkBarHeight = 30; // How much to adjust our parent view. @@ -38,35 +42,41 @@ const CGFloat kBookmarkHorizontalPadding = 8.0; @implementation BookmarkBarController - (id)initWithProfile:(Profile*)profile - view:(BookmarkBarView*)view + parentView:(NSView*)parentView webContentView:(NSView*)webContentView delegate:(id<BookmarkURLOpener>)delegate { - if ((self = [super init])) { + if ((self = [super initWithNibName:@"BookmarkBar" + bundle:mac_util::MainAppBundle()])) { bookmarkModel_ = profile->GetBookmarkModel(); - bookmarkBarView_ = view; - // We default to NOT open, which means height=0. - DCHECK([view isHidden]); // OK to change - NSRect frame = [view frame]; - frame.size.height = 0; - [view setFrame:frame]; - - // Make sure the nodes stay bottom-aligned. - [bookmarkBarView_ setAutoresizingMask:(NSViewWidthSizable | - NSViewMinYMargin)]; + preferences_ = profile->GetPrefs(); + parentView_ = parentView; webContentView_ = webContentView; delegate_ = delegate; - // Be sure to enable the bar before trying to show it... - barIsEnabled_ = YES; - preferences_ = profile->GetPrefs(); - if (preferences_->GetBoolean(prefs::kShowBookmarkBar)) - [self showBookmarkBar:YES immediately:YES]; } - // Don't pass ourself along until our init is done. - // Thus, this call is (almost) last. - bridge_.reset(new BookmarkBarBridge(self, bookmarkModel_)); return self; } +- (void)awakeFromNib { + // We default to NOT open, which means height=0. + DCHECK([[self view] isHidden]); // Hidden so it's OK to change. + NSRect frame = [[self view] frame]; + frame.size.height = 0; + frame.size.width = [parentView_ frame].size.width; + [[self view] setFrame:frame]; + + // Make sure the nodes stay bottom-aligned. + [[self view] setAutoresizingMask:(NSViewWidthSizable | + NSViewMinYMargin)]; + // Be sure to enable the bar before trying to show it... + barIsEnabled_ = YES; + if (preferences_->GetBoolean(prefs::kShowBookmarkBar)) + [self showBookmarkBar:YES immediately:YES]; + + // Don't pass ourself along (as 'self') until our init is completely + // done. Thus, this call is (almost) last. + bridge_.reset(new BookmarkBarBridge(self, bookmarkModel_)); +} + // Show or hide the bar based on the value of |show|. Handles // animating the resize of the content view. if |immediately| is YES, // make changes immediately instead of using an animator. If the bar @@ -76,7 +86,7 @@ const CGFloat kBookmarkHorizontalPadding = 8.0; - (void)showBookmarkBar:(BOOL)show immediately:(BOOL)immediately { if (barIsEnabled_ && (barShouldBeShown_ != show)) { contentViewHasOffset_ = show; - [bookmarkBarView_ setHidden:show ? NO : YES]; + [[self view] setHidden:show ? NO : YES]; barShouldBeShown_ = show; if (show) { [self loaded:bookmarkModel_]; @@ -97,7 +107,7 @@ const CGFloat kBookmarkHorizontalPadding = 8.0; // running. Thus, if you resize the window while the bookmark bar is // animating, you'll mess things up. Fix. - (void)applyContentAreaOffset:(BOOL)apply immediately:(BOOL)immediately { - if (bookmarkBarView_ == nil) { + if ([self view] == nil) { // We're too early, but awakeFromNib will call me again. return; } @@ -107,9 +117,8 @@ const CGFloat kBookmarkHorizontalPadding = 8.0; } // None of these locals are members of the Hall of Justice. - NSView* superview = [bookmarkBarView_ superview]; - NSRect superframe = [superview frame]; - NSRect frame = [bookmarkBarView_ frame]; + NSRect superframe = [parentView_ frame]; + NSRect frame = [[self view] frame]; NSRect webframe = [webContentView_ frame]; if (apply) { superframe.size.height += kBookmarkBarSuperviewHeightAdjustment; @@ -128,17 +137,17 @@ const CGFloat kBookmarkHorizontalPadding = 8.0; // expected. Fix, or clean out the animators as an option. // Odd racing is FAR worse than a lack of an animator. if (1 /* immediately */) { - [superview setFrame:superframe]; + [parentView_ setFrame:superframe]; [webContentView_ setFrame:webframe]; - [bookmarkBarView_ setFrame:frame]; + [[self view] setFrame:frame]; } else { - [[superview animator] setFrame:superframe]; + [[parentView_ animator] setFrame:superframe]; [[webContentView_ animator] setFrame:webframe]; - [[bookmarkBarView_ animator] setFrame:frame]; + [[[self view] animator] setFrame:frame]; } - [bookmarkBarView_ setNeedsDisplay:YES]; - [superview setNeedsDisplay:YES]; + [[self view] setNeedsDisplay:YES]; + [parentView_ setNeedsDisplay:YES]; [webContentView_ setNeedsDisplay:YES]; } @@ -168,20 +177,59 @@ const CGFloat kBookmarkHorizontalPadding = 8.0; } } -// Delete all items from the bookmark bar. -- (void)clearBookmarkBar { - [bookmarkBarView_ setSubviews:[NSArray array]]; +- (BookmarkNode*)nodeFromMenuItem:(id)menuItem { + NSCell* cell = [[menuItem menu] delegate]; + BookmarkNode* node = static_cast<BookmarkNode*>( + [[cell representedObject] pointerValue]); + DCHECK(node); + return node; } -// TODO(jrg): add an openBookmarkInBackground() for ctrl-click which -// has a different disposition. -- (void)openBookmark:(id)sender { - const BookmarkNode* node = static_cast<const BookmarkNode*>( - [[[sender cell] representedObject] pointerValue]); +- (BookmarkNode*)nodeFromButton:(id)button { + NSCell* cell = [button cell]; + BookmarkNode* node = static_cast<BookmarkNode*>( + [[cell representedObject] pointerValue]); DCHECK(node); + return node; +} + +- (IBAction)openBookmark:(id)sender { + BookmarkNode* node = [self nodeFromButton:sender]; [delegate_ openBookmarkURL:node->GetURL() disposition:CURRENT_TAB]; } +// As a convention we set the menu's delegate to be the button's cell +// so we can easily obtain bookmark info. Convention applied in +// -[BookmarkButtonCell menu]. + +- (IBAction)openBookmarkInNewForegroundTab:(id)sender { + BookmarkNode* node = [self nodeFromMenuItem:sender]; + [delegate_ openBookmarkURL:node->GetURL() disposition:NEW_FOREGROUND_TAB]; +} + +- (IBAction)openBookmarkInNewWindow:(id)sender { + BookmarkNode* node = [self nodeFromMenuItem:sender]; + [delegate_ openBookmarkURL:node->GetURL() disposition:NEW_WINDOW]; +} + +- (IBAction)openBookmarkInIncognitoWindow:(id)sender { + BookmarkNode* node = [self nodeFromMenuItem:sender]; + [delegate_ openBookmarkURL:node->GetURL() disposition:OFF_THE_RECORD]; +} + +- (IBAction)deleteBookmark:(id)sender { + BookmarkNode* node = [self nodeFromMenuItem:sender]; + bookmarkModel_->Remove(node->GetParent(), + node->GetParent()->IndexOfChild(node)); +} + +// Delete all items from the bookmark bar. TODO(jrg): once the +// bookmark bar has other subviews (e.g. "off the side" button/menu, +// "Other Bookmarks"), etc, this routine will need revisiting. +- (void)clearBookmarkBar { + [[self view] setSubviews:[NSArray array]]; +} + // Return an autoreleased NSCell suitable for a bookmark button. // TODO(jrg): move much of the cell config into the BookmarkButtonCell class. - (NSCell *)cellForBookmarkNode:(const BookmarkNode*)node frame:(NSRect)frame { @@ -190,9 +238,6 @@ const CGFloat kBookmarkHorizontalPadding = 8.0; autorelease]; DCHECK(cell); [cell setRepresentedObject:[NSValue valueWithPointer:node]]; - [cell setButtonType:NSMomentaryPushInButton]; - [cell setBezelStyle:NSShadowlessSquareBezelStyle]; - [cell setShowsBorderOnlyWhileMouseInside:YES]; // The favicon may be NULL if we haven't loaded it yet. Bookmarks // (and their icons) are loaded on the IO thread to speed launch. @@ -204,13 +249,8 @@ const CGFloat kBookmarkHorizontalPadding = 8.0; [cell setImagePosition:NSImageLeft]; } } - [cell setTitle:title]; - [cell setControlSize:NSSmallControlSize]; - [cell setAlignment:NSLeftTextAlignment]; - [cell setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - [cell setWraps:NO]; - [cell setLineBreakMode:NSLineBreakByTruncatingMiddle]; + [cell setMenu:buttonContextMenu_]; return cell; } @@ -257,7 +297,6 @@ const CGFloat kBookmarkHorizontalPadding = 8.0; // object. To honor the assumed semantics, we do nothing with // NSButton between alloc/init and setCell:. [button setCell:[self cellForBookmarkNode:child frame:frame]]; - // [button sizeToFit]; if (child->is_folder()) { // For now just disable the button if it's a folder. @@ -275,7 +314,7 @@ const CGFloat kBookmarkHorizontalPadding = 8.0; [button setToolTip:tooltip]; } // Finally, add it to the bookmark bar. - [bookmarkBarView_ addSubview:button]; + [[self view] addSubview:button]; } } @@ -309,6 +348,12 @@ const CGFloat kBookmarkHorizontalPadding = 8.0; } // TODO(jrg): for now this is brute force. +- (void)nodeRemoved:(BookmarkModel*)model + parent:(const BookmarkNode*)oldParent index:(int)index { + [self loaded:model]; +} + +// TODO(jrg): for now this is brute force. - (void)nodeChanged:(BookmarkModel*)model node:(const BookmarkNode*)node { [self loaded:model]; @@ -318,7 +363,7 @@ const CGFloat kBookmarkHorizontalPadding = 8.0; // Need a BookmarkNode-->NSCell mapping. - (void)nodeFavIconLoaded:(BookmarkModel*)model node:(const BookmarkNode*)node { - NSArray* views = [bookmarkBarView_ subviews]; + NSArray* views = [[self view] subviews]; for (NSButton* button in views) { NSButtonCell* cell = [button cell]; void* pointer = [[cell representedObject] pointerValue]; @@ -340,10 +385,6 @@ const CGFloat kBookmarkHorizontalPadding = 8.0; [self loaded:model]; } -- (NSView*)view { - return bookmarkBarView_; -} - - (void)setDelegate:(id<BookmarkURLOpener>)delegate { delegate_ = delegate; } diff --git a/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm b/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm index 671e9f1..e852d90 100644 --- a/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm +++ b/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm @@ -14,6 +14,7 @@ @interface BookmarkURLOpenerPong : NSObject<BookmarkURLOpener> { @public GURL url_; + WindowOpenDisposition disposition_; } @end @@ -21,6 +22,7 @@ - (void)openBookmarkURL:(const GURL&)url disposition:(WindowOpenDisposition)disposition { url_ = url; + disposition_ = disposition; } @end @@ -33,24 +35,21 @@ class BookmarkBarControllerTest : public testing::Test { public: BookmarkBarControllerTest() { NSRect content_frame = NSMakeRect(0, 0, 800, kContentAreaHeight); - NSRect bar_frame = NSMakeRect(0, 0, 800, 0); + NSRect parent_frame = NSMakeRect(0, 0, 800, 50); content_area_.reset([[NSView alloc] initWithFrame:content_frame]); - bar_view_.reset([[NSView alloc] initWithFrame:bar_frame]); - [bar_view_ setHidden:YES]; - BookmarkBarView *bbv = (BookmarkBarView*)bar_view_.get(); + parent_view_.reset([[NSView alloc] initWithFrame:parent_frame]); + [parent_view_ setHidden:YES]; bar_.reset( [[BookmarkBarController alloc] initWithProfile:helper_.profile() - view:bbv + parentView:parent_view_.get() webContentView:content_area_.get() delegate:nil]); - NSView* parent = cocoa_helper_.contentView(); - [parent addSubview:content_area_.get()]; - [parent addSubview:[bar_ view]]; + [bar_ view]; // force loading of the nib } CocoaTestHelper cocoa_helper_; // Inits Cocoa, creates window, etc... scoped_nsobject<NSView> content_area_; - scoped_nsobject<NSView> bar_view_; + scoped_nsobject<NSView> parent_view_; BrowserTestHelper helper_; scoped_nsobject<BookmarkBarController> bar_; }; @@ -59,7 +58,6 @@ TEST_F(BookmarkBarControllerTest, ShowHide) { // Assume hidden by default in a new profile. EXPECT_FALSE([bar_ isBookmarkBarVisible]); EXPECT_TRUE([[bar_ view] isHidden]); - EXPECT_EQ([bar_view_ frame].size.height, 0); // Show and hide it by toggling. [bar_ toggleBookmarkBar]; @@ -67,13 +65,14 @@ TEST_F(BookmarkBarControllerTest, ShowHide) { EXPECT_FALSE([[bar_ view] isHidden]); NSRect content_frame = [content_area_ frame]; EXPECT_NE(content_frame.size.height, kContentAreaHeight); - EXPECT_GT([bar_view_ frame].size.height, 0); + EXPECT_GT([[bar_ view] frame].size.height, 0); + [bar_ toggleBookmarkBar]; EXPECT_FALSE([bar_ isBookmarkBarVisible]); EXPECT_TRUE([[bar_ view] isHidden]); content_frame = [content_area_ frame]; EXPECT_EQ(content_frame.size.height, kContentAreaHeight); - EXPECT_EQ([bar_view_ frame].size.height, 0); + EXPECT_EQ([[bar_ view] frame].size.height, 0); } // Confirm openBookmark: forwards the request to the controller's delegate @@ -88,18 +87,61 @@ TEST_F(BookmarkBarControllerTest, OpenBookmark) { scoped_nsobject<NSButton> button([[NSButton alloc] init]); [button setCell:cell.get()]; [cell setRepresentedObject:[NSValue valueWithPointer:node.get()]]; - [bar_ openBookmark:button]; + [bar_ openBookmark:button]; EXPECT_EQ(pong.get()->url_, node->GetURL()); + EXPECT_EQ(pong.get()->disposition_, CURRENT_TAB); + + [bar_ setDelegate:nil]; } +// Confirm opening of bookmarks works from the menus (different +// dispositions than clicking on the button). +TEST_F(BookmarkBarControllerTest, OpenBookmarkFromMenus) { + scoped_nsobject<BookmarkURLOpenerPong> pong([[BookmarkURLOpenerPong alloc] + init]); + [bar_ setDelegate:pong.get()]; + + scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@"I_dont_care"]); + scoped_nsobject<NSMenuItem> item([[NSMenuItem alloc] + initWithTitle:@"still_dont_care" + action:NULL + keyEquivalent:@""]); + scoped_nsobject<NSButtonCell> cell([[NSButtonCell alloc] init]); + [item setMenu:menu.get()]; + [menu setDelegate:cell]; + + const char* urls[] = { "http://walla.walla.ding.dong.com", + "http://i_dont_know.com", + "http://cee.enn.enn.dot.com" }; + SEL selectors[] = { @selector(openBookmarkInNewForegroundTab:), + @selector(openBookmarkInNewWindow:), + @selector(openBookmarkInIncognitoWindow:) }; + WindowOpenDisposition dispositions[] = { NEW_FOREGROUND_TAB, + NEW_WINDOW, + OFF_THE_RECORD }; + for (unsigned int i = 0; + i < sizeof(dispositions)/sizeof(dispositions[0]); + i++) { + scoped_ptr<BookmarkNode> node(new BookmarkNode(GURL(urls[i]))); + [cell setRepresentedObject:[NSValue valueWithPointer:node.get()]]; + [bar_ performSelector:selectors[i] withObject:item.get()]; + EXPECT_EQ(pong.get()->url_, node->GetURL()); + EXPECT_EQ(pong.get()->disposition_, dispositions[i]); + [cell setRepresentedObject:nil]; + } +} + + // TODO(jrg): Make sure showing the bookmark bar calls loaded: (to // process bookmarks) TEST_F(BookmarkBarControllerTest, ShowAndLoad) { } -// TODO(jrg): Make sure a cleared bar has no subviews -TEST_F(BookmarkBarControllerTest, Clear) { +// TODO(jrg): Make sure adding 1 bookmark adds 1 subview, and removing +// 1 removes 1 subview. (We can't test for a simple Clear since there +// will soon be views in here which aren't bookmarks.) +TEST_F(BookmarkBarControllerTest, ViewChanges) { } // TODO(jrg): Make sure loaded: does something useful diff --git a/chrome/browser/cocoa/bookmark_bar_view.h b/chrome/browser/cocoa/bookmark_bar_view.h index a8b343e..c92cc7f 100644 --- a/chrome/browser/cocoa/bookmark_bar_view.h +++ b/chrome/browser/cocoa/bookmark_bar_view.h @@ -13,7 +13,13 @@ // I expect changes for new features (themes, extensions, etc). @interface BookmarkBarView : BackgroundGradientView { + @private + IBOutlet NSMenu* barContextualMenu_; } @end +@interface BookmarkBarView(TestingAPI) +- (void)setContextMenu:(NSMenu*)menu; +@end + #endif // CHROME_BROWSER_COCOA_BOOKMARK_BAR_VIEW_H_ diff --git a/chrome/browser/cocoa/bookmark_bar_view.mm b/chrome/browser/cocoa/bookmark_bar_view.mm index 63171e4..9bdab26 100644 --- a/chrome/browser/cocoa/bookmark_bar_view.mm +++ b/chrome/browser/cocoa/bookmark_bar_view.mm @@ -5,4 +5,18 @@ #include "chrome/browser/cocoa/bookmark_bar_view.h" @implementation BookmarkBarView + +// Only hit in a unit test. +- (void)setContextMenu:(NSMenu*)menu { + barContextualMenu_ = menu; +} + +// Unlike controls, generic views don't have a well-defined context +// menu (e.g. responds to the "menu" selector). So we add our own. +- (NSMenu *)menuForEvent:(NSEvent *)event { + if ([event type] == NSRightMouseDown) + return barContextualMenu_; + return nil; +} + @end diff --git a/chrome/browser/cocoa/bookmark_bar_view_unittest.mm b/chrome/browser/cocoa/bookmark_bar_view_unittest.mm index 51b9f12..a1cb121 100644 --- a/chrome/browser/cocoa/bookmark_bar_view_unittest.mm +++ b/chrome/browser/cocoa/bookmark_bar_view_unittest.mm @@ -2,5 +2,57 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file is intentionally empty; there is no code in -// BookmarkBarView to test yet. +#import <Cocoa/Cocoa.h> + +#import "chrome/browser/cocoa/bookmark_bar_view.h" +#import "chrome/browser/cocoa/cocoa_test_helper.h" +#include "testing/gtest/include/gtest/gtest.h" + +class BookmarkBarViewTest : public testing::Test { + CocoaTestHelper cocoa_helper_; // Inits Cocoa, creates window, etc... +}; + +// Make sure we only get a menu from a right-click. Not left-click or keyDown. +TEST_F(BookmarkBarViewTest, TestMenu) { + scoped_nsobject<BookmarkBarView> view([[BookmarkBarView alloc] + initWithFrame:NSMakeRect(0,0,10,10)]); + EXPECT_TRUE(view.get()); + + // Not loaded from a nib so we must set it explicitly + scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@"spork"]); + [view setContextMenu:menu.get()]; + + EXPECT_TRUE([view menuForEvent:[NSEvent mouseEventWithType:NSRightMouseDown + location:NSMakePoint(0,0) + modifierFlags:0 + timestamp:0 + windowNumber:0 + context:nil + eventNumber:0 + clickCount:0 + pressure:0.0]]); + EXPECT_FALSE([view menuForEvent:[NSEvent mouseEventWithType:NSLeftMouseDown + location:NSMakePoint(0,0) + modifierFlags:0 + timestamp:0 + windowNumber:0 + context:nil + eventNumber:0 + clickCount:0 + pressure:0.0]]); + EXPECT_FALSE([view menuForEvent:[NSEvent keyEventWithType:NSKeyDown + location:NSMakePoint(0,0) + modifierFlags:0 + timestamp:0 + windowNumber:0 + context:nil + characters:@"x" + charactersIgnoringModifiers:@"x" + isARepeat:NO + keyCode:7]]); + + [view setContextMenu:nil]; +} + + + diff --git a/chrome/browser/cocoa/bookmark_button_cell.mm b/chrome/browser/cocoa/bookmark_button_cell.mm index 8f78010..2a5a3eb 100644 --- a/chrome/browser/cocoa/bookmark_button_cell.mm +++ b/chrome/browser/cocoa/bookmark_button_cell.mm @@ -3,12 +3,26 @@ // found in the LICENSE file. #import "chrome/browser/cocoa/bookmark_button_cell.h" +#import "third_party/GTM/AppKit/GTMTheme.h" @implementation BookmarkButtonCell - (id)initTextCell:(NSString *)string { if ((self = [super initTextCell:string])) { - [self setBordered:NO]; + [self setButtonType:NSMomentaryPushInButton]; + [self setBezelStyle:NSShadowlessSquareBezelStyle]; + [self setShowsBorderOnlyWhileMouseInside:YES]; + [self setControlSize:NSSmallControlSize]; + [self setAlignment:NSLeftTextAlignment]; + [self setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; + [self setWraps:NO]; + // NSLineBreakByTruncatingMiddle seems more common on OSX but let's + // try to match Windows for a bit to see what happens. + [self setLineBreakMode:NSLineBreakByTruncatingTail]; + + // Theming doesn't work for bookmark buttons yet (text chucked). + [super setShouldTheme:NO]; + } return self; } @@ -20,4 +34,15 @@ return size; } +// We share the context menu among all bookmark buttons. To allow us +// to disambiguate when needed (e.g. "open bookmark"), we set the +// menu's delegate to be us. We (the cell) have the bookmark encoded +// in our represented object. +// Convention needed in -[BookmarkBarController openBookmarkIn***] calls. +- (NSMenu*)menu { + NSMenu* menu = [super menu]; + [menu setDelegate:self]; + return menu; +} + @end diff --git a/chrome/browser/cocoa/bookmark_button_cell_unittest.mm b/chrome/browser/cocoa/bookmark_button_cell_unittest.mm index 7b61ebd..7074084 100644 --- a/chrome/browser/cocoa/bookmark_button_cell_unittest.mm +++ b/chrome/browser/cocoa/bookmark_button_cell_unittest.mm @@ -30,5 +30,26 @@ TEST_F(BookmarkButtonCellTest, SizeForBounds) { EXPECT_TRUE(size.width < 200 && size.height < 200); } +// Make sure a cell's menu has the cell itself as the delegate. This +// is our convention for reusing the context menu across all bookmarks +// while being unambiguous when used. +TEST_F(BookmarkButtonCellTest, MenuDelegate) { + scoped_nsobject<BookmarkButtonCell> cell([[BookmarkButtonCell alloc] + initTextCell:@"Testing"]); + EXPECT_FALSE([cell.get() menu]); + + scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@"foo"]); + [cell setMenu:menu.get()]; + EXPECT_TRUE([cell.get() menu]); + EXPECT_EQ([[cell.get() menu] delegate], cell.get()); + [cell setMenu:nil]; +} + +// Make sure the default from the base class is overridden +TEST_F(BookmarkButtonCellTest, MouseEnterStuff) { + scoped_nsobject<BookmarkButtonCell> cell([[BookmarkButtonCell alloc] + initTextCell:@"Testing"]); + EXPECT_TRUE([cell.get() showsBorderOnlyWhileMouseInside]); +} } // namespace diff --git a/chrome/browser/cocoa/gradient_button_cell.h b/chrome/browser/cocoa/gradient_button_cell.h index ae85e6e..5aeb249 100644 --- a/chrome/browser/cocoa/gradient_button_cell.h +++ b/chrome/browser/cocoa/gradient_button_cell.h @@ -7,6 +7,8 @@ #import <Cocoa/Cocoa.h> +#include "base/scoped_nsobject.h" + // Base class for button cells for toolbar and bookmark bar. // // This is a button cell that handles drawing/highlighting of buttons. @@ -22,7 +24,19 @@ enum { typedef NSInteger ButtonType; @interface GradientButtonCell : NSButtonCell { + @private + // Custom drawing means we need to perform our own mouse tracking if + // the cell is setShowsBorderOnlyWhileMouseInside:YES. + BOOL isMouseInside_; + scoped_nsobject<NSTrackingArea> trackingArea_; + BOOL shouldTheme_; } +// Turn off theming. Temporary work-around. +- (void)setShouldTheme:(BOOL)shouldTheme; +@end + +@interface GradientButtonCell(TestingAPI) +- (BOOL)isMouseInside; @end #endif // CHROME_BROWSER_COCOA_CHROMIUM_BUTTON_CELL_H_ diff --git a/chrome/browser/cocoa/gradient_button_cell.mm b/chrome/browser/cocoa/gradient_button_cell.mm index 1ad72d4..87c87ba 100644 --- a/chrome/browser/cocoa/gradient_button_cell.mm +++ b/chrome/browser/cocoa/gradient_button_cell.mm @@ -8,11 +8,62 @@ @implementation GradientButtonCell +- (id)initTextCell:(NSString*)string { + if ((self = [super initTextCell:string])) { + shouldTheme_ = YES; + } + return self; +} + +- (void)setShouldTheme:(BOOL)shouldTheme { + shouldTheme_ = shouldTheme; +} + - (NSBackgroundStyle)interiorBackgroundStyle { return [self isHighlighted] ? NSBackgroundStyleLowered : NSBackgroundStyleRaised; } +- (void)mouseEntered:(NSEvent *)theEvent { + isMouseInside_ = YES; + [[self controlView] setNeedsDisplay:YES]; +} + +- (void)mouseExited:(NSEvent *)theEvent { + isMouseInside_ = NO; + [[self controlView] setNeedsDisplay:YES]; +} + +- (BOOL)isMouseInside { + return trackingArea_ && isMouseInside_; +} + +// Since we have our own drawWithFrame:, we need to also have our own +// logic for determining when the mouse is inside for honoring this +// request. +- (void)setShowsBorderOnlyWhileMouseInside:(BOOL)showOnly { + [super setShowsBorderOnlyWhileMouseInside:showOnly]; + if (showOnly) { + if (trackingArea_.get()) { + [self setShowsBorderOnlyWhileMouseInside:NO]; + } + trackingArea_.reset([[NSTrackingArea alloc] + initWithRect:[[self controlView] + bounds] + options:(NSTrackingMouseEnteredAndExited | + NSTrackingActiveInActiveApp) + owner:self + userInfo:nil]); + [[self controlView] addTrackingArea:trackingArea_]; + } else { + if (trackingArea_) { + [[self controlView] removeTrackingArea:trackingArea_]; + trackingArea_.reset(nil); + isMouseInside_ = NO; + } + } +} + - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { // Constants from Cole. Will kConstant them once the feedback loop // is complete. @@ -50,7 +101,9 @@ // Stroke the borders and appropriate fill gradient. If we're borderless, // the only time we want to draw the inner gradient is if we're highlighted. - if ([self isBordered] || pressed) { + if (([self isBordered] && ![self showsBorderOnlyWhileMouseInside]) || + pressed || + [self isMouseInside]) { [[NSColor colorWithCalibratedWhite:1.0 alpha:0.25] set]; [outerPath stroke]; @@ -129,8 +182,7 @@ - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { GTMTheme* theme = [controlView gtm_theme]; - BOOL shouldTheme = YES; - if (shouldTheme) { + if (shouldTheme_) { BOOL isTemplate = [[self image] isTemplate]; [NSGraphicsContext saveGraphicsState]; diff --git a/chrome/browser/cocoa/gradient_button_cell_unittest.mm b/chrome/browser/cocoa/gradient_button_cell_unittest.mm index 42abf28..3e0f162 100644 --- a/chrome/browser/cocoa/gradient_button_cell_unittest.mm +++ b/chrome/browser/cocoa/gradient_button_cell_unittest.mm @@ -39,4 +39,25 @@ TEST_F(GradientButtonCellTest, Display) { [view_ display]; } +// Tracking rects +TEST_F(GradientButtonCellTest, TrackingRects) { + GradientButtonCell* cell = [view_ cell]; + EXPECT_FALSE([cell showsBorderOnlyWhileMouseInside]); + EXPECT_FALSE([cell isMouseInside]); + + [cell setShowsBorderOnlyWhileMouseInside:YES]; + [cell mouseEntered:nil]; + EXPECT_TRUE([cell isMouseInside]); + [cell mouseExited:nil]; + EXPECT_FALSE([cell isMouseInside]); + + [cell setShowsBorderOnlyWhileMouseInside:NO]; + EXPECT_FALSE([cell isMouseInside]); + + [cell setShowsBorderOnlyWhileMouseInside:YES]; + [cell setShowsBorderOnlyWhileMouseInside:YES]; + [cell setShowsBorderOnlyWhileMouseInside:NO]; + [cell setShowsBorderOnlyWhileMouseInside:NO]; +} + } // namespace diff --git a/chrome/browser/cocoa/tab_window_controller.mm b/chrome/browser/cocoa/tab_window_controller.mm index 14b6b7b..35d9f8b 100644 --- a/chrome/browser/cocoa/tab_window_controller.mm +++ b/chrome/browser/cocoa/tab_window_controller.mm @@ -16,10 +16,6 @@ @synthesize tabContentArea = tabContentArea_; - (void)windowDidLoad { - // TODO(jrg): a non-normal window (e.g. for pop-ups) needs more work - // than just removal of the tab strip offset. But this is enough to - // avoid confusion (e.g. "new tab" on popup gets created in a - // different window). if ([self isNormalWindow]) { // Place the tab bar above the content box and add it to the view hierarchy // as a sibling of the content view so it can overlap with the window frame. @@ -27,8 +23,8 @@ tabFrame.origin = NSMakePoint(0, NSMaxY(tabFrame)); tabFrame.size.height = NSHeight([tabStripView_ frame]); [tabStripView_ setFrame:tabFrame]; + [[[[self window] contentView] superview] addSubview:tabStripView_]; } - [[[[self window] contentView] superview] addSubview:tabStripView_]; } - (void)removeOverlay { diff --git a/chrome/browser/cocoa/toolbar_controller.h b/chrome/browser/cocoa/toolbar_controller.h index b6ec8d4..31c896e 100644 --- a/chrome/browser/cocoa/toolbar_controller.h +++ b/chrome/browser/cocoa/toolbar_controller.h @@ -13,7 +13,6 @@ #import "chrome/browser/cocoa/bookmark_bar_controller.h" #include "chrome/common/pref_member.h" -@class BookmarkBarView; class CommandUpdater; class LocationBar; class LocationBarViewMac; @@ -71,7 +70,6 @@ class ToolbarView; IBOutlet NSButton* pageButton_; IBOutlet NSButton* wrenchButton_; IBOutlet NSTextField* locationBar_; - IBOutlet BookmarkBarView* bookmarkBarView_; } // Initialize the toolbar and register for command updates. The profile is diff --git a/chrome/browser/cocoa/toolbar_controller.mm b/chrome/browser/cocoa/toolbar_controller.mm index b9b219c..d1a44c6 100644 --- a/chrome/browser/cocoa/toolbar_controller.mm +++ b/chrome/browser/cocoa/toolbar_controller.mm @@ -120,9 +120,15 @@ class PrefObserverBridge : public NotificationObserver { // Create a sub-controller for the bookmark bar. bookmarkBarController_.reset([[BookmarkBarController alloc] initWithProfile:profile_ - view:bookmarkBarView_ + parentView:[self view] webContentView:webContentView_ delegate:bookmarkBarDelegate_]); + + // Add bookmark bar to the view hierarchy. This also triggers the + // nib load. The bookmark bar is defined (in the nib) to be + // bottom-aligned to it's parent view (among other things), so + // position and resize properties don't need to be set. + [[self view] addSubview:[bookmarkBarController_ view]]; } - (LocationBar*)locationBar { @@ -223,7 +229,7 @@ class PrefObserverBridge : public NotificationObserver { - (NSArray*)toolbarViews { return [NSArray arrayWithObjects:backButton_, forwardButton_, reloadButton_, homeButton_, starButton_, goButton_, pageButton_, wrenchButton_, - locationBar_, bookmarkBarView_, nil]; + locationBar_, nil]; } // Moves |rect| to the right by |delta|, keeping the right side fixed by diff --git a/chrome/browser/cocoa/toolbar_controller_unittest.mm b/chrome/browser/cocoa/toolbar_controller_unittest.mm index 93e1cfe..ed3cf89 100644 --- a/chrome/browser/cocoa/toolbar_controller_unittest.mm +++ b/chrome/browser/cocoa/toolbar_controller_unittest.mm @@ -22,7 +22,7 @@ class ToolbarControllerTest : public testing::Test { // |-toolbarViews| method. enum { kBackIndex, kForwardIndex, kReloadIndex, kHomeIndex, kStarIndex, kGoIndex, - kPageIndex, kWrenchIndex, kLocationIndex, kBookmarkIndex, + kPageIndex, kWrenchIndex, kLocationIndex, }; ToolbarControllerTest() { diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index c8d0eec..6b0c26f 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -2501,6 +2501,7 @@ # put any pdfs down in the sources block below so pdfsqueeze runs on # them. 'app/nibs/en.lproj/About.xib', + 'app/nibs/en.lproj/BookmarkBar.xib', 'app/nibs/en.lproj/BrowserWindow.xib', 'app/nibs/en.lproj/ClearBrowsingData.xib', 'app/nibs/en.lproj/DownloadItem.xib', |