// Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef CHROME_BROWSER_VISTA_FRAME_H__ #define CHROME_BROWSER_VISTA_FRAME_H__ #include #include #include #include #include #include "base/message_loop.h" #include "chrome/app/chrome_dll_resource.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/frame_view.h" #include "chrome/browser/views/status_bubble.h" #include "chrome/views/view_container.h" #include "chrome/views/root_view.h" #include "chrome/views/hwnd_view.h" #include "chrome/views/image_view.h" #include "chrome/views/tooltip_manager.h" #define VISTA_FRAME_CLASSNAME L"Chrome_VistaFrame" class BookmarkBarView; class Browser; class BrowserView; class TabContentsContainerView; class ChromeViews::FocusManager; class SkBitmap; class TabStrip; //////////////////////////////////////////////////////////////////////////////// // // VistaFrame class // // A CWindowImpl subclass that implements our main frame on Windows Vista // //////////////////////////////////////////////////////////////////////////////// class VistaFrame : public BrowserWindow, public CWindowImpl>, public ChromeViews::ViewContainer, public ChromeViews::AcceleratorTarget { public: // Create a new VistaFrame given the bounds and provided browser. // |bounds| may be empty to let Windows decide where to place the window. // The browser_window object acts both as a container for the actual // browser contents as well as a source for the tab strip and the toolbar. // |is_off_the_record| defines whether this window should represent an off the // record session. // // Note: this method creates an HWND for the frame but doesn't initialize // the view hierarchy. The browser creates its HWND from the frame HWND // and then calls Init() on the frame to finalize the initialization static VistaFrame* CreateFrame(const gfx::Rect& bounds, Browser* browser, bool is_off_the_record); virtual ~VistaFrame(); //////////////////////////////////////////////////////////////////////////////// // Events //////////////////////////////////////////////////////////////////////////////// DECLARE_FRAME_WND_CLASS_EX(VISTA_FRAME_CLASSNAME, IDR_MAINFRAME, CS_DBLCLKS, NULL) BEGIN_MSG_MAP(VistaFrame) MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseRange) MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseRange) MESSAGE_HANDLER(WM_NCMOUSELEAVE, OnMouseRange) MESSAGE_HANDLER(WM_NCMOUSEMOVE, OnMouseRange) MESSAGE_RANGE_HANDLER(WM_SETTINGCHANGE, WM_SETTINGCHANGE, OnSettingChange) MSG_WM_LBUTTONDOWN(OnMouseButtonDown) MSG_WM_LBUTTONUP(OnLButtonUp); MSG_WM_LBUTTONDBLCLK(OnMouseButtonDblClk) MSG_WM_MBUTTONDOWN(OnMouseButtonDown) MSG_WM_MBUTTONUP(OnMButtonUp); MSG_WM_MBUTTONDBLCLK(OnMouseButtonDblClk); MSG_WM_RBUTTONDOWN(OnMouseButtonDown) MSG_WM_RBUTTONUP(OnRButtonUp); MSG_WM_NCMBUTTONDOWN(OnNCMButtonDown) MSG_WM_NCRBUTTONDOWN(OnNCRButtonDown) MSG_WM_RBUTTONDBLCLK(OnMouseButtonDblClk); MESSAGE_HANDLER_EX(WM_GETOBJECT, OnGetObject); // To avoid edit atlcrack.h. MSG_WM_KEYDOWN(OnKeyDown); MSG_WM_KEYUP(OnKeyUp); MSG_WM_MOUSEMOVE(OnMouseMove) MSG_WM_MOUSELEAVE(OnMouseLeave) MSG_WM_CLOSE(Close) // Note: Calls Close() directly, there is no OnClose() MSG_WM_ENDSESSION(OnEndSession) MSG_WM_APPCOMMAND(OnAppCommand) MSG_WM_COMMAND(OnCommand) MSG_WM_SYSCOMMAND(OnSysCommand) MSG_WM_SIZE(OnSize) MSG_WM_MOVE(OnMove) MSG_WM_MOVING(OnMoving) MSG_WM_ACTIVATE(OnActivate) MSG_WM_PAINT(OnPaint) MSG_WM_ERASEBKGND(OnEraseBkgnd) MSG_WM_NCHITTEST(OnNCHitTest) MSG_WM_NCCALCSIZE(OnNCCalcSize) MSG_WM_CAPTURECHANGED(OnCaptureChanged) MSG_WM_NOTIFY(OnNotify) MSG_WM_NCLBUTTONDOWN(OnNCLButtonDown) MSG_WM_NCACTIVATE(OnNCActivate) MSG_WM_MOUSEACTIVATE(OnMouseActivate) MSG_WM_POWERBROADCAST(OnPowerBroadcast) MSG_WM_THEMECHANGED(OnThemeChanged) REFLECT_NOTIFICATIONS() END_MSG_MAP() void OnEndSession(BOOL ending, UINT logoff); void OnActivate(UINT n_state, BOOL is_minimized, HWND other); int OnMouseActivate(CWindow wndTopLevel, UINT nHitTest, UINT message); void OnMouseButtonDown(UINT flags, const CPoint& pt); void OnMouseButtonUp(UINT flags, const CPoint& pt); void OnLButtonUp(UINT flags, const CPoint& pt); void OnMouseButtonDblClk(UINT flags, const CPoint& pt); void OnMButtonUp(UINT flags, const CPoint& pt); void OnRButtonUp(UINT flags, const CPoint& pt); void OnNCMButtonDown(UINT flags, const CPoint& pt); void OnNCRButtonDown(UINT flags, const CPoint& pt); void OnMouseMove(UINT flags, const CPoint& pt); void OnMouseLeave(); void OnKeyDown(TCHAR c, UINT rep_cnt, UINT flags); void OnKeyUp(TCHAR c, UINT rep_cnt, UINT flags); LRESULT OnGetObject(UINT uMsg, WPARAM w_param, LPARAM l_param); LRESULT OnAppCommand( HWND w_param, short app_command, WORD device, int keystate); void OnCommand(UINT notification_code, int command_id, HWND window); void OnSysCommand(UINT notification_code, CPoint click); void OnMove(const CSize& size); void OnMoving(UINT param, const LPRECT new_bounds); void OnSize(UINT param, const CSize& size); void OnFinalMessage(HWND hwnd); void OnPaint(HDC dc); LRESULT OnEraseBkgnd(HDC dc); void ArmOnMouseLeave(); void OnCaptureChanged(HWND hwnd); LRESULT OnMouseRange(UINT u_msg, WPARAM w_param, LPARAM l_param, BOOL& handled); LRESULT OnNotify(int w_param, NMHDR* hdr); LRESULT OnSettingChange(UINT u_msg, WPARAM w_param, LPARAM l_param, BOOL& handled); LRESULT OnNCActivate(BOOL param); BOOL OnPowerBroadcast(DWORD power_event, DWORD data); void OnThemeChanged(); //////////////////////////////////////////////////////////////////////////////// // BrowserWindow implementation //////////////////////////////////////////////////////////////////////////////// virtual void Init(); virtual void Show(int command, bool adjust_to_fit); virtual void Close(); virtual void* GetPlatformID(); virtual void ShowTabContents(TabContents* contents); virtual TabStrip* GetTabStrip() const; virtual void ContinueDetachConstrainedWindowDrag( const gfx::Point& mouse_pt, int frame_component); virtual void SizeToContents(const gfx::Rect& contents_bounds); virtual void SetAcceleratorTable( std::map* accelerator_table); virtual bool AcceleratorPressed(const ChromeViews::Accelerator& accelerator); virtual gfx::Rect GetNormalBounds(); virtual bool IsMaximized(); virtual gfx::Rect GetBoundsForContentBounds(const gfx::Rect content_rect); virtual void InfoBubbleShowing(); virtual ToolbarStarToggle* GetStarButton() const; virtual LocationBarView* GetLocationBarView() const; virtual GoButton* GetGoButton() const; virtual BookmarkBarView* GetBookmarkBarView(); virtual BrowserView* GetBrowserView() const; virtual void UpdateToolbar(TabContents* contents, bool should_restore_state); virtual void ProfileChanged(Profile* profile); virtual void FocusToolbar(); //////////////////////////////////////////////////////////////////////////////// // ChromeViews::ViewContainer //////////////////////////////////////////////////////////////////////////////// virtual void GetBounds(CRect *out, bool including_frame) const; virtual void MoveToFront(bool should_activate); virtual HWND GetHWND() const; virtual void PaintNow(const CRect& update_rect); virtual ChromeViews::RootView* GetRootView(); virtual bool IsVisible(); virtual bool IsActive(); virtual ChromeViews::TooltipManager* GetTooltipManager(); virtual StatusBubble* GetStatusBubble(); virtual bool GetAccelerator(int cmd_id, ChromeViews::Accelerator* accelerator); virtual void ShelfVisibilityChanged(); virtual void SelectedTabToolbarSizeChanged(bool is_animating); virtual void SetWindowTitle(const std::wstring& title); virtual void Activate(); virtual void FlashFrame(); protected: explicit VistaFrame(Browser* browser); // For subclassers. virtual bool IsTabStripVisible() const { return true; } virtual bool IsToolBarVisible() const { return true; } virtual bool SupportsBookmarkBar() const { return true; } // Invoked after the HWND has been created but before the window is showing. // This registers tooltips. If you override, be sure and invoke this // implementation. virtual void InitAfterHWNDCreated(); // Override as needed. virtual LRESULT OnNCHitTest(const CPoint& pt); virtual LRESULT OnNCCalcSize(BOOL w_param, LPARAM l_param); virtual void OnNCLButtonDown(UINT flags, const CPoint& pt); // Create a default tab strip. Override as needed. virtual TabStrip* CreateTabStrip(Browser* browser); // Set whether this frame represents an off the record session. This is // currently only called during initialization. void SetIsOffTheRecord(bool value); // Layout the various views virtual void Layout(); // Return the tab contents container. TabContentsContainerView* GetTabContentsContainer(); virtual void DestroyBrowser(); // The Browser that created this frame Browser* browser_; // Top level frame view class VistaFrameView; VistaFrameView* frame_view_; friend class VistaFrameView; // The view we use to display the background under tab / toolbar area class VistaFrameView : public FrameView { public: explicit VistaFrameView(VistaFrame* parent) : FrameView(parent), contents_offset_(0), parent_(parent) { } virtual void Paint(ChromeCanvas* canvas); void SetContentsOffset(int o); // Accessibility information bool GetAccessibleRole(VARIANT* role); // Returns a brief, identifying string, containing a unique, readable name. bool GetAccessibleName(std::wstring* name); // Assigns an accessible string name. void SetAccessibleName(const std::wstring& name); protected: // Overriden to return false if over the min/max/close buttons of the frame. virtual bool ShouldForwardToTabStrip( const ChromeViews::DropTargetEvent& event); private: void PaintContentsBorder(ChromeCanvas* canvas, int x, int y, int w, int h); int contents_offset_; VistaFrame* parent_; // Storage of strings needed for accessibility. std::wstring accessible_name_; DISALLOW_EVIL_CONSTRUCTORS(VistaFrameView); }; private: // // View events propagation // bool ProcessMousePressed(const CPoint& pt, UINT flags, bool dbl_click); void ProcessMouseDragged(const CPoint& pt, UINT flags); void ProcessMouseReleased(const CPoint& pt, UINT flags); void ProcessMouseMoved(const CPoint &pt, UINT flags); void ProcessMouseExited(); // Reset the black DWM frame (the black non-glass area with lightly-colored // border that sits behind our content). Generally there's no single place // to call this, as Vista likes to reset the frame in different situations // (return from maximize, non-composited > composited, app launch), and // the notifications we receive and the timing of those notifications // varies so wildly that we end up having to call this in many different // message handlers. void ResetDWMFrame(); // Initialize static members the first time this is invoked static void InitializeIfNeeded(); // Updates a single view. If *view differs from new_view the old view is // removed and the new view is added. // // This is intended to be used when swapping in/out child views that are // referenced via a field. // // This function returns true if anything was changed. The caller should // ensure that Layout() is eventually called in this case. bool UpdateChildViewAndLayout(ChromeViews::View* new_view, ChromeViews::View** view); // Implementation for ShelfVisibilityChanged(). Updates the various shelf // fields. If one of the shelves has changed (or it's size has changed) and // current_tab is non-NULL layout occurs. void ShelfVisibilityChangedImpl(TabContents* current_tab); // Root view ChromeViews::RootView root_view_; // Tooltip Manager scoped_ptr tooltip_manager_; // The optional container for the off the record icon. ChromeViews::ImageView* off_the_record_image_; // The container for the distributor logo. ChromeViews::ImageView* distributor_logo_; // The view that contains the tabs and any associated controls. TabStrip* tabstrip_; // The bookmark bar. This is lazily created. scoped_ptr bookmark_bar_view_; // The visible bookmark bar. NULL if none is visible. ChromeViews::View* active_bookmark_bar_; // Browser contents TabContentsContainerView* tab_contents_container_; // Whether we enabled our custom window yet. bool custom_window_enabled_; // Whether we saved the window placement yet. bool saved_window_placement_; // whether we are expecting a mouse leave event bool on_mouse_leave_armed_; // whether we are currently processing a view level drag session bool in_drag_session_; // A view positioned at the bottom of the frame. ChromeViews::View* shelf_view_; // A view positioned beneath the bookmark bar view. // Implementation mirrors shelf_view_ ChromeViews::View* info_bar_view_; // We need to own the text of the menu, the Windows API does not copy it. std::wstring task_manager_label_text_; // A mapping between accelerators and commands. scoped_ptr> accelerator_table_; // Whether this frame represents an off the record session. bool is_off_the_record_; // Static resources static bool g_initialized; static SkBitmap** g_bitmaps; // Instance of accessibility information and handling for MSAA root CComPtr accessibility_root_; // This is used to make sure we visually look active when the bubble is shown // even though we aren't active. When the info bubble is shown it takes // activation. Visually we still want the frame to look active. To make the // frame look active when we get WM_NCACTIVATE and ignore_ncactivate_ is // true, we tell the frame it is still active. When the info bubble closes we // tell the window it is no longer active. This results in painting the // active frame even though we aren't active. bool ignore_ncactivate_; // Whether we should save the bounds of the window. We don't want to // save the default size of windows for certain classes of windows // like unconstrained popups. Defaults to true. bool should_save_window_placement_; // A view that holds the client-area contents of the browser window. BrowserView* browser_view_; DISALLOW_EVIL_CONSTRUCTORS(VistaFrame); }; #endif // CHROME_BROWSER_VISTA_FRAME_H__