// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef VIEWS_WINDOW_NON_CLIENT_VIEW_H_ #define VIEWS_WINDOW_NON_CLIENT_VIEW_H_ #pragma once #include "base/task.h" #include "views/view.h" #include "views/window/client_view.h" namespace gfx { class Path; } namespace views { //////////////////////////////////////////////////////////////////////////////// // NonClientFrameView // // An object that subclasses NonClientFrameView is a View that renders and // responds to events within the frame portions of the non-client area of a // window. This view does _not_ contain the ClientView, but rather is a sibling // of it. class NonClientFrameView : public View { public: // Various edges of the frame border have a 1 px shadow along their edges; in // a few cases we shift elements based on this amount for visual appeal. static const int kFrameShadowThickness; // In restored mode, we draw a 1 px edge around the content area inside the // frame border. static const int kClientEdgeThickness; // Prevent the frame view from painting its inactive state. Prevents a related // window from causing its owner to appear deactivated. Used for windows like // bubbles. void DisableInactiveRendering(bool disable) { paint_as_active_ = disable; if (!paint_as_active_) SchedulePaint(); } // Returns the bounds (in this View's parent's coordinates) that the client // view should be laid out within. virtual gfx::Rect GetBoundsForClientView() const = 0; virtual gfx::Rect GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const = 0; // This function must ask the ClientView to do a hittest. We don't do this in // the parent NonClientView because that makes it more difficult to calculate // hittests for regions that are partially obscured by the ClientView, e.g. // HTSYSMENU. virtual int NonClientHitTest(const gfx::Point& point) = 0; virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) = 0; virtual void EnableClose(bool enable) = 0; virtual void ResetWindowControls() = 0; virtual void UpdateWindowIcon() = 0; // Overridden from View: virtual bool HitTest(const gfx::Point& l) const OVERRIDE; virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; protected: virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE; NonClientFrameView() : paint_as_active_(false) {} // Helper for non-client view implementations to determine which area of the // window border the specified |point| falls within. The other parameters are // the size of the sizing edges, and whether or not the window can be // resized. int GetHTComponentForFrame(const gfx::Point& point, int top_resize_border_height, int resize_border_thickness, int top_resize_corner_height, int resize_corner_width, bool can_resize); // Used to determine if the frame should be painted as active. Keyed off the // window's actual active state and the override, see // DisableInactiveRendering() above. bool ShouldPaintAsActive() const; private: // True when the non-client view should always be rendered as if the window // were active, regardless of whether or not the top level window actually // is active. bool paint_as_active_; }; //////////////////////////////////////////////////////////////////////////////// // NonClientView // // The NonClientView is the logical root of all Views contained within a // Window, except for the RootView which is its parent and of which it is the // sole child. The NonClientView has two children, the NonClientFrameView which // is responsible for painting and responding to events from the non-client // portions of the window, and the ClientView, which is responsible for the // same for the client area of the window: // // +- views::Window ------------------------------------+ // | +- views::RootView ------------------------------+ | // | | +- views::NonClientView ---------------------+ | | // | | | +- views::NonClientFrameView subclas ---+ | | | // | | | | | | | | // | | | | << all painting and event receiving >> | | | | // | | | | << of the non-client areas of a >> | | | | // | | | | << views::Window. >> | | | | // | | | | | | | | // | | | +----------------------------------------+ | | | // | | | +- views::ClientView or subclass --------+ | | | // | | | | | | | | // | | | | << all painting and event receiving >> | | | | // | | | | << of the client areas of a >> | | | | // | | | | << views::Window. >> | | | | // | | | | | | | | // | | | +----------------------------------------+ | | | // | | +--------------------------------------------+ | | // | +------------------------------------------------+ | // +----------------------------------------------------+ // // The NonClientFrameView and ClientView are siblings because due to theme // changes the NonClientFrameView may be replaced with different // implementations (e.g. during the switch from DWM/Aero-Glass to Vista Basic/ // Classic rendering). // class NonClientView : public View { public: explicit NonClientView(Window* frame); virtual ~NonClientView(); // Returns the current NonClientFrameView instance, or NULL if // it does not exist. NonClientFrameView* frame_view() const { return frame_view_.get(); } // Replaces the current NonClientFrameView (if any) with the specified one. void SetFrameView(NonClientFrameView* frame_view); // Returns true if the ClientView determines that the containing window can be // closed, false otherwise. bool CanClose(); // Called by the containing Window when it is closed. void WindowClosing(); // Changes the frame from native to custom depending on the value of // |use_native_frame|. void UpdateFrame(); // Prevents the window from being rendered as deactivated when |disable| is // true, until called with |disable| false. Used when a sub-window is to be // shown that shouldn't visually de-activate the window. // Subclasses can override this to perform additional actions when this value // changes. void DisableInactiveRendering(bool disable); // Returns the bounds of the window required to display the content area at // the specified bounds. gfx::Rect GetWindowBoundsForClientBounds(const gfx::Rect client_bounds) const; // Determines the windows HT* code when the mouse cursor is at the // specified point, in window coordinates. int NonClientHitTest(const gfx::Point& point); // Returns a mask to be used to clip the top level window for the given // size. This is used to create the non-rectangular window shape. void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask); // Toggles the enable state for the Close button (and the Close menu item in // the system menu). void EnableClose(bool enable); // Tells the window controls as rendered by the NonClientView to reset // themselves to a normal state. This happens in situations where the // containing window does not receive a normal sequences of messages that // would lead to the controls returning to this normal state naturally, e.g. // when the window is maximized, minimized or restored. void ResetWindowControls(); // Tells the NonClientView to invalidate the NonClientFrameView's window icon. void UpdateWindowIcon(); // Get/Set client_view property. ClientView* client_view() const { return client_view_; } void set_client_view(ClientView* client_view) { client_view_ = client_view; } // Layout just the frame view. This is necessary on Windows when non-client // metrics such as the position of the window controls changes independently // of a window resize message. void LayoutFrameView(); // Set the accessible name of this view. void SetAccessibleName(const string16& name); // NonClientView, View overrides: virtual gfx::Size GetPreferredSize() OVERRIDE; virtual gfx::Size GetMinimumSize() OVERRIDE; virtual void Layout() OVERRIDE; virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; virtual views::View* GetEventHandlerForPoint(const gfx::Point& point) OVERRIDE; protected: // NonClientView, View overrides: virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child) OVERRIDE; private: // The frame that hosts this NonClientView. Window* frame_; // A ClientView object or subclass, responsible for sizing the contents view // of the window, hit testing and perhaps other tasks depending on the // implementation. ClientView* client_view_; // The NonClientFrameView that renders the non-client portions of the window. // This object is not owned by the view hierarchy because it can be replaced // dynamically as the system settings change. scoped_ptr frame_view_; // The accessible name of this view. string16 accessible_name_; DISALLOW_COPY_AND_ASSIGN(NonClientView); }; } // namespace views #endif // #ifndef VIEWS_WINDOW_NON_CLIENT_VIEW_H_