omnibox_popup_view_mac.h revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_UI_COCOA_OMNIBOX_OMNIBOX_POPUP_VIEW_MAC_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_UI_COCOA_OMNIBOX_OMNIBOX_POPUP_VIEW_MAC_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import <Cocoa/Cocoa.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_nsobject.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_match.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/omnibox/omnibox_popup_view.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/font.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)@class AutocompleteMatrix; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OmniboxEditModel; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OmniboxPopupModel; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OmniboxView; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implements OmniboxPopupView using a raw NSWindow containing an 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NSTableView. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(rohitrao): This class is set up in a way that makes testing hard. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Refactor and write unittests. http://crbug.com/9977 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OmniboxPopupViewMac : public OmniboxPopupView { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static OmniboxPopupView* Create(OmniboxView* omnibox_view, 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OmniboxEditModel* edit_model, 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NSTextField* field); 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OmniboxPopupViewMac(OmniboxView* omnibox_view, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OmniboxEditModel* edit_model, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSTextField* field); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~OmniboxPopupViewMac(); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Overridden from OmniboxPopupView: 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsOpen() const OVERRIDE; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void InvalidateLine(size_t line) OVERRIDE { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(shess): Verify that there is no need to implement this. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is currently used in two places in the model: 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When setting the selected line, the selected line is 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // invalidated, then the selected line is changed, then the new 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // selected line is invalidated, then PaintUpdatesNow() is called. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For us PaintUpdatesNow() should be sufficient. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Same thing happens when changing the hovered line, except with 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no call to PaintUpdatesNow(). Since this code does not 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // currently support special display of the hovered line, there's 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // nothing to do here. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // deanm indicates that this is an anti-flicker optimization, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which we probably cannot utilize (and may not need) so long as 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we're using NSTableView to implement the popup contents. We 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // may need to move away from NSTableView to implement hover, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // though. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void UpdatePopupAppearance() OVERRIDE; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual gfx::Rect GetTargetBounds() OVERRIDE; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set |line| to be selected. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetSelectedLine(size_t line); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is only called by model in SetSelectedLine() after updating 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // everything. Popup should already be visible. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void PaintUpdatesNow() OVERRIDE; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnDragCanceled() OVERRIDE {} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Opens the URL corresponding to the given |row|. If |force_background| is 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // true, forces the URL to open in a background tab. Otherwise, determines 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the proper window open disposition from the modifier flags on |[NSApp 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // currentEvent]|. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OpenURLForRow(int row, bool force_background); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return the text to show for the match, based on the match's 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // contents and description. Result will be in |font|, with the 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // boldfaced version used for matches. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static NSAttributedString* MatchText(const AutocompleteMatch& match, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Font& font, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float cellWidth); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper for MatchText() to allow sharing code between the contents 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and description cases. Returns NSMutableAttributedString as a 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // convenience for MatchText(). 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static NSMutableAttributedString* DecorateMatchedString( 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16 &matchString, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AutocompleteMatch::ACMatchClassifications &classifications, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSColor* textColor, NSColor* dimTextColor, gfx::Font& font); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper for MatchText() to elide a marked-up string using 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // gfx::ElideText() as a model. Modifies |aString| in place. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(shess): Consider breaking AutocompleteButtonCell out of this 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // code, and modifying it to have something like -setMatch:, so that 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // these convolutions to expose internals for testing can be 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cleaner. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static NSMutableAttributedString* ElideString( 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSMutableAttributedString* aString, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16 originalString, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Font& font, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const float cellWidth); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the popup_ instance if needed. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CreatePopupIfNeeded(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Calculate the appropriate position for the popup based on the 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // field's screen position and the given target for the matrix 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // height, and makes the popup visible. Animates to the new frame 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if the popup shrinks, snaps to the new frame if the popup grows, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // allows existing animations to continue if the size doesn't 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // change. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PositionPopup(const CGFloat matrixHeight); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the NSImage that should be used as an icon for the given match. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSImage* ImageForMatch(const AutocompleteMatch& match); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(shess): |omnibox_view_| should already be accessible via 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |field_|, or perhaps via |model_|. Consider refactoring. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OmniboxView* omnibox_view_; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<OmniboxPopupModel> model_; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSTextField* field_; // owned by tab controller 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Child window containing a matrix which implements the popup. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_nsobject<NSWindow> popup_; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSRect targetPopupFrame_; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_nsobject<AutocompleteMatrix> autocomplete_matrix_; 1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(OmniboxPopupViewMac); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CHROME_BROWSER_UI_COCOA_OMNIBOX_OMNIBOX_POPUP_VIEW_MAC_H_ 138