summaryrefslogtreecommitdiffstats
path: root/views/window/non_client_view.h
blob: ced8063655a9cea75e392f81e2002db96e5bc7d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
// Copyright (c) 2010 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;

  // Returns true if this FrameView should always use the custom frame,
  // regardless of the system settings. An example is the Constrained Window,
  // which is a child window and must always provide its own frame.
  virtual bool AlwaysUseCustomFrame() const { return false; }

  // Like AlwaysUseCustomFrame, returns true if this FrameView should always use
  // the native frame, regardless of theme settings. An example is popup/app
  // windows, which we do not ever want to show themed.
  virtual bool AlwaysUseNativeFrame() const { return false; }

  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;

  // Overridden from View:
  virtual bool HitTest(const gfx::Point& l) const;

  virtual bool GetAccessibleRole(AccessibilityTypes::Role* role);

 protected:
  virtual void DidChangeBounds(const gfx::Rect& previous,
                               const gfx::Rect& current);

  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() const;

  // 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();

  // Returns true if the native window frame should be used, false if the
  // NonClientView provides its own frame implementation.
  bool UseNativeFrame() const;

  // 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();

  // 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();

  // NonClientView, View overrides:
  virtual gfx::Size GetPreferredSize();
  virtual gfx::Size GetMinimumSize();
  virtual void Layout();
  virtual bool GetAccessibleRole(AccessibilityTypes::Role* role);

 protected:
  // NonClientView, View overrides:
  virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
  virtual views::View* GetViewForPoint(const gfx::Point& point);

 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<NonClientFrameView> frame_view_;

  DISALLOW_COPY_AND_ASSIGN(NonClientView);
};

}  // namespace views

#endif  // #ifndef VIEWS_WINDOW_NON_CLIENT_VIEW_H_