1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef UI_VIEWS_WINDOW_NON_CLIENT_VIEW_H_
6#define UI_VIEWS_WINDOW_NON_CLIENT_VIEW_H_
7
8#include "ui/views/view.h"
9
10namespace gfx {
11class Path;
12}
13
14namespace views {
15
16class ClientView;
17
18////////////////////////////////////////////////////////////////////////////////
19// NonClientFrameView
20//
21//  An object that subclasses NonClientFrameView is a View that renders and
22//  responds to events within the frame portions of the non-client area of a
23//  window. This view does _not_ contain the ClientView, but rather is a sibling
24//  of it.
25class VIEWS_EXPORT NonClientFrameView : public View {
26 public:
27  // Internal class name.
28  static const char kViewClassName[];
29
30  enum {
31    // Various edges of the frame border have a 1 px shadow along their edges;
32    // in a few cases we shift elements based on this amount for visual appeal.
33    kFrameShadowThickness = 1,
34
35    // In restored mode, we draw a 1 px edge around the content area inside the
36    // frame border.
37    kClientEdgeThickness = 1,
38  };
39
40  // Sets whether the window should be rendered as active regardless of the
41  // actual active state. Used when bubbles become active to make their parent
42  // appear active. A value of true makes the window render as active always,
43  // false gives normal behavior.
44  void SetInactiveRenderingDisabled(bool disable);
45
46  // Helper for non-client view implementations to determine which area of the
47  // window border the specified |point| falls within. The other parameters are
48  // the size of the sizing edges, and whether or not the window can be
49  // resized.
50  int GetHTComponentForFrame(const gfx::Point& point,
51                             int top_resize_border_height,
52                             int resize_border_thickness,
53                             int top_resize_corner_height,
54                             int resize_corner_width,
55                             bool can_resize);
56
57  // Returns the bounds (in this View's parent's coordinates) that the client
58  // view should be laid out within.
59  virtual gfx::Rect GetBoundsForClientView() const = 0;
60
61  virtual gfx::Rect GetWindowBoundsForClientBounds(
62      const gfx::Rect& client_bounds) const = 0;
63
64  // This function must ask the ClientView to do a hittest.  We don't do this in
65  // the parent NonClientView because that makes it more difficult to calculate
66  // hittests for regions that are partially obscured by the ClientView, e.g.
67  // HTSYSMENU.
68  virtual int NonClientHitTest(const gfx::Point& point) = 0;
69  virtual void GetWindowMask(const gfx::Size& size,
70                             gfx::Path* window_mask) = 0;
71  virtual void ResetWindowControls() = 0;
72  virtual void UpdateWindowIcon() = 0;
73  virtual void UpdateWindowTitle() = 0;
74
75  // Overridden from View:
76  virtual bool HitTestRect(const gfx::Rect& rect) const OVERRIDE;
77  virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
78  virtual const char* GetClassName() const OVERRIDE;
79
80 protected:
81  virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
82
83  NonClientFrameView() : paint_as_active_(false) {}
84
85  // Used to determine if the frame should be painted as active. Keyed off the
86  // window's actual active state and the override, see
87  // SetInactiveRenderingDisabled() above.
88  bool ShouldPaintAsActive() const;
89
90  // Invoked from SetInactiveRenderingDisabled(). This implementation invokes
91  // SchedulesPaint as necessary.
92  virtual void ShouldPaintAsActiveChanged();
93
94 private:
95  // True when the non-client view should always be rendered as if the window
96  // were active, regardless of whether or not the top level window actually
97  // is active.
98  bool paint_as_active_;
99};
100
101////////////////////////////////////////////////////////////////////////////////
102// NonClientView
103//
104//  The NonClientView is the logical root of all Views contained within a
105//  Window, except for the RootView which is its parent and of which it is the
106//  sole child. The NonClientView has two children, the NonClientFrameView which
107//  is responsible for painting and responding to events from the non-client
108//  portions of the window, and the ClientView, which is responsible for the
109//  same for the client area of the window:
110//
111//  +- views::Widget ------------------------------------+
112//  | +- views::RootView ------------------------------+ |
113//  | | +- views::NonClientView ---------------------+ | |
114//  | | | +- views::NonClientFrameView subclass ---+ | | |
115//  | | | |                                        | | | |
116//  | | | | << all painting and event receiving >> | | | |
117//  | | | | << of the non-client areas of a     >> | | | |
118//  | | | | << views::Widget.                   >> | | | |
119//  | | | |                                        | | | |
120//  | | | +----------------------------------------+ | | |
121//  | | | +- views::ClientView or subclass --------+ | | |
122//  | | | |                                        | | | |
123//  | | | | << all painting and event receiving >> | | | |
124//  | | | | << of the client areas of a         >> | | | |
125//  | | | | << views::Widget.                   >> | | | |
126//  | | | |                                        | | | |
127//  | | | +----------------------------------------+ | | |
128//  | | +--------------------------------------------+ | |
129//  | +------------------------------------------------+ |
130//  +----------------------------------------------------+
131//
132// The NonClientFrameView and ClientView are siblings because due to theme
133// changes the NonClientFrameView may be replaced with different
134// implementations (e.g. during the switch from DWM/Aero-Glass to Vista Basic/
135// Classic rendering).
136//
137class VIEWS_EXPORT NonClientView : public View {
138 public:
139  // Internal class name.
140  static const char kViewClassName[];
141
142  NonClientView();
143  virtual ~NonClientView();
144
145  // Returns the current NonClientFrameView instance, or NULL if
146  // it does not exist.
147  NonClientFrameView* frame_view() const { return frame_view_.get(); }
148
149  // Replaces the current NonClientFrameView (if any) with the specified one.
150  void SetFrameView(NonClientFrameView* frame_view);
151
152  // Replaces the current |overlay_view_| (if any) with the specified one.
153  void SetOverlayView(View* view);
154
155  // Returns true if the ClientView determines that the containing window can be
156  // closed, false otherwise.
157  bool CanClose();
158
159  // Called by the containing Window when it is closed.
160  void WindowClosing();
161
162  // Replaces the frame view with a new one. Used when switching window theme
163  // or frame style.
164  void UpdateFrame();
165
166  // Prevents the window from being rendered as deactivated when |disable| is
167  // true, until called with |disable| false. Used when a sub-window is to be
168  // shown that shouldn't visually de-activate the window.
169  // Subclasses can override this to perform additional actions when this value
170  // changes.
171  void SetInactiveRenderingDisabled(bool disable);
172
173  // Returns the bounds of the window required to display the content area at
174  // the specified bounds.
175  gfx::Rect GetWindowBoundsForClientBounds(const gfx::Rect client_bounds) const;
176
177  // Determines the windows HT* code when the mouse cursor is at the
178  // specified point, in window coordinates.
179  int NonClientHitTest(const gfx::Point& point);
180
181  // Returns a mask to be used to clip the top level window for the given
182  // size. This is used to create the non-rectangular window shape.
183  void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask);
184
185  // Tells the window controls as rendered by the NonClientView to reset
186  // themselves to a normal state. This happens in situations where the
187  // containing window does not receive a normal sequences of messages that
188  // would lead to the controls returning to this normal state naturally, e.g.
189  // when the window is maximized, minimized or restored.
190  void ResetWindowControls();
191
192  // Tells the NonClientView to invalidate the NonClientFrameView's window icon.
193  void UpdateWindowIcon();
194
195  // Tells the NonClientView to invalidate the NonClientFrameView's window
196  // title.
197  void UpdateWindowTitle();
198
199  // Get/Set client_view property.
200  ClientView* client_view() const { return client_view_; }
201  void set_client_view(ClientView* client_view) {
202    client_view_ = client_view;
203  }
204
205  // Layout just the frame view. This is necessary on Windows when non-client
206  // metrics such as the position of the window controls changes independently
207  // of a window resize message.
208  void LayoutFrameView();
209
210  // Set the accessible name of this view.
211  void SetAccessibleName(const string16& name);
212
213  // NonClientView, View overrides:
214  virtual gfx::Size GetPreferredSize() OVERRIDE;
215  virtual gfx::Size GetMinimumSize() OVERRIDE;
216  virtual gfx::Size GetMaximumSize() OVERRIDE;
217  virtual void Layout() OVERRIDE;
218  virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
219  virtual const char* GetClassName() const OVERRIDE;
220
221  virtual views::View* GetEventHandlerForRect(const gfx::Rect& rect) OVERRIDE;
222  virtual views::View* GetTooltipHandlerForPoint(
223      const gfx::Point& point) OVERRIDE;
224
225 protected:
226  // NonClientView, View overrides:
227  virtual void ViewHierarchyChanged(
228      const ViewHierarchyChangedDetails& details) OVERRIDE;
229
230 private:
231  // A ClientView object or subclass, responsible for sizing the contents view
232  // of the window, hit testing and perhaps other tasks depending on the
233  // implementation.
234  ClientView* client_view_;
235
236  // The NonClientFrameView that renders the non-client portions of the window.
237  // This object is not owned by the view hierarchy because it can be replaced
238  // dynamically as the system settings change.
239  scoped_ptr<NonClientFrameView> frame_view_;
240
241  // The overlay view, when non-NULL and visible, takes up the entire widget and
242  // is placed on top of the ClientView and NonClientFrameView.
243  View* overlay_view_;
244
245  // The accessible name of this view.
246  string16 accessible_name_;
247
248  DISALLOW_COPY_AND_ASSIGN(NonClientView);
249};
250
251}  // namespace views
252
253#endif  // UI_VIEWS_WINDOW_NON_CLIENT_VIEW_H_
254