172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/views/constrained_window_views.h"
672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <algorithm>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/app/chrome_command_ids.h"
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/toolbar/toolbar_model.h"
1221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/views/frame/browser_view.h"
1321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/window_sizer.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_constants.h"
15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents_view.h"
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/app_resources.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h"
2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h"
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/canvas.h"
2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/font.h"
2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/path.h"
2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/rect.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/button/image_button.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/focus/focus_manager.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/window/client_view.h"
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/window/native_window.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/window/non_client_view.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/window/window_resources.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/window/window_shape.h"
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/window/window.h"
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_WIN)
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/widget/widget_win.h"
3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "views/window/window_win.h"
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeDelta;
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace views {
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ClientView;
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// An enumeration of bitmap resources used by this window.
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum {
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRAME_PART_BITMAP_FIRST = 0,  // Must be first.
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Window Frame Border.
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRAME_BOTTOM_EDGE,
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRAME_BOTTOM_LEFT_CORNER,
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRAME_BOTTOM_RIGHT_CORNER,
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRAME_LEFT_EDGE,
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRAME_RIGHT_EDGE,
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRAME_TOP_EDGE,
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRAME_TOP_LEFT_CORNER,
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRAME_TOP_RIGHT_CORNER,
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FRAME_PART_BITMAP_COUNT  // Must be last.
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kXPFramePartIDs[] = {
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    0,
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IDR_WINDOW_BOTTOM_CENTER, IDR_WINDOW_BOTTOM_LEFT_CORNER,
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IDR_WINDOW_BOTTOM_RIGHT_CORNER, IDR_WINDOW_LEFT_SIDE,
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IDR_WINDOW_RIGHT_SIDE, IDR_WINDOW_TOP_CENTER,
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IDR_WINDOW_TOP_LEFT_CORNER, IDR_WINDOW_TOP_RIGHT_CORNER,
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    0 };
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kVistaFramePartIDs[] = {
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    0,
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IDR_CONSTRAINED_BOTTOM_CENTER_V, IDR_CONSTRAINED_BOTTOM_LEFT_CORNER_V,
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IDR_CONSTRAINED_BOTTOM_RIGHT_CORNER_V, IDR_CONSTRAINED_LEFT_SIDE_V,
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IDR_CONSTRAINED_RIGHT_SIDE_V, IDR_CONSTRAINED_TOP_CENTER_V,
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    IDR_CONSTRAINED_TOP_LEFT_CORNER_V, IDR_CONSTRAINED_TOP_RIGHT_CORNER_V,
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    0 };
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass XPWindowResources : public views::WindowResources {
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  XPWindowResources() {
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    InitClass();
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~XPWindowResources() {}
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual SkBitmap* GetPartBitmap(views::FramePartBitmap part_id) const {
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return bitmaps_[part_id];
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void InitClass() {
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    static bool initialized = false;
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!initialized) {
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle& rb = ResourceBundle::GetSharedInstance();
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i) {
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        int id = kXPFramePartIDs[i];
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (id != 0)
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          bitmaps_[i] = rb.GetBitmapNamed(id);
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      initialized = true;
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static SkBitmap* bitmaps_[FRAME_PART_BITMAP_COUNT];
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(XPWindowResources);
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass VistaWindowResources : public views::WindowResources {
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VistaWindowResources() {
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    InitClass();
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~VistaWindowResources() {}
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual SkBitmap* GetPartBitmap(views::FramePartBitmap part_id) const {
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return bitmaps_[part_id];
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void InitClass() {
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    static bool initialized = false;
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!initialized) {
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle& rb = ResourceBundle::GetSharedInstance();
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i) {
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        int id = kVistaFramePartIDs[i];
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (id != 0)
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          bitmaps_[i] = rb.GetBitmapNamed(id);
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      initialized = true;
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static SkBitmap* bitmaps_[FRAME_PART_BITMAP_COUNT];
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(VistaWindowResources);
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSkBitmap* XPWindowResources::bitmaps_[];
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSkBitmap* VistaWindowResources::bitmaps_[];
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ConstrainedWindowFrameView
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ConstrainedWindowFrameView
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : public views::NonClientFrameView,
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      public views::ButtonListener {
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  explicit ConstrainedWindowFrameView(ConstrainedWindowViews* container);
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~ConstrainedWindowFrameView();
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void UpdateWindowTitle();
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Overridden from views::NonClientFrameView:
156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual gfx::Rect GetBoundsForClientView() const OVERRIDE;
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual bool AlwaysUseCustomFrame() const OVERRIDE;
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual gfx::Rect GetWindowBoundsForClientBounds(
159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const gfx::Rect& client_bounds) const OVERRIDE;
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE;
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask)
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      OVERRIDE;
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void EnableClose(bool enable) OVERRIDE;
164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void ResetWindowControls() OVERRIDE {}
165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void UpdateWindowIcon() OVERRIDE {}
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Overridden from views::View:
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void Layout() OVERRIDE;
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void OnThemeChanged() OVERRIDE;
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Overridden from views::ButtonListener:
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void ButtonPressed(views::Button* sender, const views::Event& event)
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      OVERRIDE;
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns the thickness of the entire nonclient left, right, and bottom
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // borders, including both the window frame and any client edge.
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int NonClientBorderThickness() const;
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns the height of the entire nonclient top border, including the window
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // frame, any title area, and any connected client edge.
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int NonClientTopBorderHeight() const;
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns the thickness of the nonclient portion of the 3D edge along the
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // bottom of the titlebar.
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int TitlebarBottomThickness() const;
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns what the size of the titlebar icon would be if there was one.
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int IconSize() const;
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns what the titlebar icon's bounds would be if there was one.
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect IconBounds() const;
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Paints different parts of the window to the incoming canvas.
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void PaintFrameBorder(gfx::Canvas* canvas);
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void PaintTitleBar(gfx::Canvas* canvas);
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void PaintClientEdge(gfx::Canvas* canvas);
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Layout various sub-components of this view.
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void LayoutWindowControls();
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void LayoutTitleBar();
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns the bounds of the client area for the specified view size.
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect CalculateClientAreaBounds(int width, int height) const;
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SkColor GetTitleColor() const {
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return container_->owner()->profile()->IsOffTheRecord()
209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_WIN)
210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            || !views::WidgetWin::IsAeroGlassEnabled()
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            ? SK_ColorWHITE : SK_ColorBLACK;
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Loads the appropriate set of WindowResources for the frame view.
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void InitWindowResources();
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ConstrainedWindowViews* container_;
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<views::WindowResources> resources_;
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect title_bounds_;
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::ImageButton* close_button_;
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The bounds of the ClientView.
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect client_view_bounds_;
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void InitClass();
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The font to be used to render the titlebar text.
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static gfx::Font* title_font_;
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(ConstrainedWindowFrameView);
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Font* ConstrainedWindowFrameView::title_font_ = NULL;
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The frame border is only visible in restored mode and is hardcoded to 4 px on
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// each side regardless of the system window border size.
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kFrameBorderThickness = 4;
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Various edges of the frame border have a 1 px shadow along their edges; in a
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// few cases we shift elements based on this amount for visual appeal.
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kFrameShadowThickness = 1;
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// In the window corners, the resize areas don't actually expand bigger, but the
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 16 px at the end of each edge triggers diagonal resizing.
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kResizeAreaCornerSize = 16;
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The titlebar never shrinks too short to show the caption button plus some
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// padding below it.
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kCaptionButtonHeightWithPadding = 19;
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The titlebar has a 2 px 3D edge along the top and bottom.
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kTitlebarTopAndBottomEdgeThickness = 2;
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The icon would never shrink below 16 px on a side, if there was one.
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kIconMinimumSize = 16;
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The title text starts 2 px from the right edge of the left frame border.
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kTitleLeftSpacing = 2;
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// There is a 5 px gap between the title text and the caption buttons.
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kTitleCaptionSpacing = 5;
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst SkColor kContentsBorderShadow = SkColorSetARGB(51, 0, 0, 0);
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ConstrainedWindowFrameView, public:
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochConstrainedWindowFrameView::ConstrainedWindowFrameView(
268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ConstrainedWindowViews* container)
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        : NonClientFrameView(),
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          container_(container),
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          close_button_(new views::ImageButton(this)) {
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitClass();
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitWindowResources();
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  close_button_->SetImage(views::CustomButton::BS_NORMAL,
2773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                          rb.GetBitmapNamed(IDR_CLOSE_SA));
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  close_button_->SetImage(views::CustomButton::BS_HOT,
2793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                          rb.GetBitmapNamed(IDR_CLOSE_SA_H));
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  close_button_->SetImage(views::CustomButton::BS_PUSHED,
2813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                          rb.GetBitmapNamed(IDR_CLOSE_SA_P));
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  close_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   views::ImageButton::ALIGN_MIDDLE);
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddChildView(close_button_);
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochConstrainedWindowFrameView::~ConstrainedWindowFrameView() {
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ConstrainedWindowFrameView::UpdateWindowTitle() {
291dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SchedulePaintInRect(title_bounds_);
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ConstrainedWindowFrameView, views::NonClientFrameView implementation:
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Rect ConstrainedWindowFrameView::GetBoundsForClientView() const {
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return client_view_bounds_;
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ConstrainedWindowFrameView::AlwaysUseCustomFrame() const {
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Constrained windows always use the custom frame - they just have a
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // different set of bitmaps.
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Rect ConstrainedWindowFrameView::GetWindowBoundsForClientBounds(
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const gfx::Rect& client_bounds) const {
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int top_height = NonClientTopBorderHeight();
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int border_thickness = NonClientBorderThickness();
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return gfx::Rect(std::max(0, client_bounds.x() - border_thickness),
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   std::max(0, client_bounds.y() - top_height),
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   client_bounds.width() + (2 * border_thickness),
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   client_bounds.height() + top_height + border_thickness);
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint ConstrainedWindowFrameView::NonClientHitTest(const gfx::Point& point) {
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!bounds().Contains(point))
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return HTNOWHERE;
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int frame_component =
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      container_->GetWindow()->client_view()->NonClientHitTest(point);
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // See if we're in the sysmenu region.  (We check the ClientView first to be
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // consistent with OpaqueBrowserFrameView; it's not really necessary here.)
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect sysmenu_rect(IconBounds());
32772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  sysmenu_rect.set_x(GetMirroredXForRect(sysmenu_rect));
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (sysmenu_rect.Contains(point))
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU;
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (frame_component != HTNOWHERE)
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return frame_component;
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Then see if the point is within any of the window controls.
33572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (close_button_->GetMirroredBounds().Contains(point))
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return HTCLOSE;
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int window_component = GetHTComponentForFrame(point, kFrameBorderThickness,
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NonClientBorderThickness(), kResizeAreaCornerSize, kResizeAreaCornerSize,
340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      container_->GetWindow()->window_delegate()->CanResize());
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Fall back to the caption if no other component matches.
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return (window_component == HTNOWHERE) ? HTCAPTION : window_component;
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ConstrainedWindowFrameView::GetWindowMask(const gfx::Size& size,
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                               gfx::Path* window_mask) {
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(window_mask);
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::GetDefaultWindowMask(size, window_mask);
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ConstrainedWindowFrameView::EnableClose(bool enable) {
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  close_button_->SetEnabled(enable);
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ConstrainedWindowFrameView, views::View implementation:
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
358dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ConstrainedWindowFrameView::OnPaint(gfx::Canvas* canvas) {
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PaintFrameBorder(canvas);
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PaintTitleBar(canvas);
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PaintClientEdge(canvas);
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ConstrainedWindowFrameView::Layout() {
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LayoutWindowControls();
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LayoutTitleBar();
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  client_view_bounds_ = CalculateClientAreaBounds(width(), height());
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ConstrainedWindowFrameView::OnThemeChanged() {
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitWindowResources();
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ConstrainedWindowFrameView, views::ButtonListener implementation:
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ConstrainedWindowFrameView::ButtonPressed(
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    views::Button* sender, const views::Event& event) {
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (sender == close_button_)
380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    container_->CloseConstrainedWindow();
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ConstrainedWindowFrameView, private:
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint ConstrainedWindowFrameView::NonClientBorderThickness() const {
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return kFrameBorderThickness + kClientEdgeThickness;
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint ConstrainedWindowFrameView::NonClientTopBorderHeight() const {
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return std::max(kFrameBorderThickness + IconSize(),
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  kFrameShadowThickness + kCaptionButtonHeightWithPadding) +
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TitlebarBottomThickness();
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint ConstrainedWindowFrameView::TitlebarBottomThickness() const {
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return kTitlebarTopAndBottomEdgeThickness + kClientEdgeThickness;
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint ConstrainedWindowFrameView::IconSize() const {
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This metric scales up if either the titlebar height or the titlebar font
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // size are increased.
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return GetSystemMetrics(SM_CYSMICON);
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return std::max(title_font_->height(), kIconMinimumSize);
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Rect ConstrainedWindowFrameView::IconBounds() const {
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int size = IconSize();
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Our frame border has a different "3D look" than Windows'.  Theirs has a
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // more complex gradient on the top that they push their icon/title below;
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // then the maximized window cuts this off and the icon/title are centered
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // in the remaining space.  Because the apparent shape of our border is
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // simpler, using the same positioning makes things look slightly uncentered
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // with restored windows, so instead of calculating the remaining space from
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // below the frame border, we calculate from below the 3D edge.
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int unavailable_px_at_top = kTitlebarTopAndBottomEdgeThickness;
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // When the icon is shorter than the minimum space we reserve for the caption
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // button, we vertically center it.  We want to bias rounding to put extra
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // space above the icon, since the 3D edge + client edge below looks (to the
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // eye) more like additional space than does the 3D edge above; hence the +1.
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int y = unavailable_px_at_top + (NonClientTopBorderHeight() -
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      unavailable_px_at_top - size - TitlebarBottomThickness() + 1) / 2;
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return gfx::Rect(kFrameBorderThickness + kTitleLeftSpacing, y, size, size);
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ConstrainedWindowFrameView::PaintFrameBorder(gfx::Canvas* canvas) {
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SkBitmap* top_left_corner = resources_->GetPartBitmap(FRAME_TOP_LEFT_CORNER);
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SkBitmap* top_right_corner =
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      resources_->GetPartBitmap(FRAME_TOP_RIGHT_CORNER);
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SkBitmap* top_edge = resources_->GetPartBitmap(FRAME_TOP_EDGE);
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SkBitmap* right_edge = resources_->GetPartBitmap(FRAME_RIGHT_EDGE);
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SkBitmap* left_edge = resources_->GetPartBitmap(FRAME_LEFT_EDGE);
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SkBitmap* bottom_left_corner =
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      resources_->GetPartBitmap(FRAME_BOTTOM_LEFT_CORNER);
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SkBitmap* bottom_right_corner =
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      resources_->GetPartBitmap(FRAME_BOTTOM_RIGHT_CORNER);
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SkBitmap* bottom_edge = resources_->GetPartBitmap(FRAME_BOTTOM_EDGE);
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SkBitmap* theme_frame = rb.GetBitmapNamed(IDR_THEME_FRAME);
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SkColor frame_color = ResourceBundle::frame_color;
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Fill with the frame color first so we have a constant background for
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // areas not covered by the theme image.
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas->FillRectInt(frame_color, 0, 0, width(), theme_frame->height());
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now fill down the sides.
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas->FillRectInt(frame_color, 0, theme_frame->height(), left_edge->width(),
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      height() - theme_frame->height());
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas->FillRectInt(frame_color, width() - right_edge->width(),
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      theme_frame->height(), right_edge->width(),
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      height() - theme_frame->height());
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now fill the bottom area.
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas->FillRectInt(frame_color,
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      left_edge->width(), height() - bottom_edge->height(),
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      width() - left_edge->width() - right_edge->width(),
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      bottom_edge->height());
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Draw the theme frame.
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas->TileImageInt(*theme_frame, 0, 0, width(), theme_frame->height());
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Top.
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas->DrawBitmapInt(*top_left_corner, 0, 0);
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas->TileImageInt(*top_edge, top_left_corner->width(), 0,
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       width() - top_right_corner->width(), top_edge->height());
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas->DrawBitmapInt(*top_right_corner,
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        width() - top_right_corner->width(), 0);
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Right.
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas->TileImageInt(*right_edge, width() - right_edge->width(),
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      top_right_corner->height(), right_edge->width(),
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      height() - top_right_corner->height() - bottom_right_corner->height());
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Bottom.
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas->DrawBitmapInt(*bottom_right_corner,
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        width() - bottom_right_corner->width(),
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        height() - bottom_right_corner->height());
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas->TileImageInt(*bottom_edge, bottom_left_corner->width(),
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      height() - bottom_edge->height(),
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      width() - bottom_left_corner->width() - bottom_right_corner->width(),
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      bottom_edge->height());
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas->DrawBitmapInt(*bottom_left_corner, 0,
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        height() - bottom_left_corner->height());
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Left.
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas->TileImageInt(*left_edge, 0, top_left_corner->height(),
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      left_edge->width(),
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      height() - top_left_corner->height() - bottom_left_corner->height());
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ConstrainedWindowFrameView::PaintTitleBar(gfx::Canvas* canvas) {
494ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  canvas->DrawStringInt(
495ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      container_->GetWindow()->window_delegate()->GetWindowTitle(),
496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      *title_font_, GetTitleColor(), GetMirroredXForRect(title_bounds_),
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      title_bounds_.y(), title_bounds_.width(), title_bounds_.height());
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ConstrainedWindowFrameView::PaintClientEdge(gfx::Canvas* canvas) {
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect client_edge_bounds(CalculateClientAreaBounds(width(), height()));
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  client_edge_bounds.Inset(-kClientEdgeThickness, -kClientEdgeThickness);
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect frame_shadow_bounds(client_edge_bounds);
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  frame_shadow_bounds.Inset(-kFrameShadowThickness, -kFrameShadowThickness);
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas->FillRectInt(kContentsBorderShadow, frame_shadow_bounds.x(),
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      frame_shadow_bounds.y(), frame_shadow_bounds.width(),
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      frame_shadow_bounds.height());
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas->FillRectInt(ResourceBundle::toolbar_color, client_edge_bounds.x(),
511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      client_edge_bounds.y(), client_edge_bounds.width(),
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      client_edge_bounds.height());
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ConstrainedWindowFrameView::LayoutWindowControls() {
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Size close_button_size = close_button_->GetPreferredSize();
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  close_button_->SetBounds(
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      width() - kFrameBorderThickness - close_button_size.width(),
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      kFrameShadowThickness, close_button_size.width(),
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      close_button_size.height());
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ConstrainedWindowFrameView::LayoutTitleBar() {
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The window title is based on the calculated icon position, even though'
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // there is no icon in constrained windows.
526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect icon_bounds(IconBounds());
527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int title_x = icon_bounds.x();
5283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int title_height = title_font_->GetHeight();
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We bias the title position so that when the difference between the icon and
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // title heights is odd, the extra pixel of the title is above the vertical
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // midline rather than below.  This compensates for how the icon is already
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // biased downwards (see IconBounds()) and helps prevent descenders on the
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // title from overlapping the 3D edge at the bottom of the titlebar.
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  title_bounds_.SetRect(title_x,
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      icon_bounds.y() + ((icon_bounds.height() - title_height - 1) / 2),
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::max(0, close_button_->x() - kTitleCaptionSpacing - title_x),
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      title_height);
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Rect ConstrainedWindowFrameView::CalculateClientAreaBounds(
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int width,
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int height) const {
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int top_height = NonClientTopBorderHeight();
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int border_thickness = NonClientBorderThickness();
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return gfx::Rect(border_thickness, top_height,
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   std::max(0, width - (2 * border_thickness)),
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   std::max(0, height - top_height - border_thickness));
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ConstrainedWindowFrameView::InitWindowResources() {
55172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  resources_.reset(views::WidgetWin::IsAeroGlassEnabled() ?
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    static_cast<views::WindowResources*>(new VistaWindowResources) :
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    new XPWindowResources);
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ConstrainedWindowFrameView::InitClass() {
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static bool initialized = false;
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!initialized) {
560ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_WIN)
56172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    title_font_ = new gfx::Font(views::WindowWin::GetWindowTitleFont());
562ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    initialized = true;
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
568ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// ConstrainedWindowViews, public:
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenConstrainedWindowViews::ConstrainedWindowViews(
571ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TabContents* owner,
572ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    views::WindowDelegate* window_delegate)
573ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : owner_(owner),
574ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ALLOW_THIS_IN_INITIALIZER_LIST(native_constrained_window_(
575ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          NativeConstrainedWindow::CreateNativeConstrainedWindow(
576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              this, window_delegate))) {
577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GetWindow()->non_client_view()->SetFrameView(CreateFrameViewForWindow());
578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  native_constrained_window_->InitNativeConstrainedWindow(
579ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      owner->GetNativeView());
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
582ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenConstrainedWindowViews::~ConstrainedWindowViews() {
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
585ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenviews::Window* ConstrainedWindowViews::GetWindow() {
586ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return native_constrained_window_->AsNativeWindow()->GetWindow();
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// ConstrainedWindowViews, ConstrainedWindow implementation:
591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ConstrainedWindowViews::ShowConstrainedWindow() {
59372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // We marked the view as hidden during construction.  Mark it as
59472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // visible now so FocusManager will let us receive focus.
595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GetWindow()->non_client_view()->SetVisible(true);
5963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (owner_->delegate())
5973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    owner_->delegate()->WillShowConstrainedWindow(owner_);
598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GetWindow()->Activate();
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FocusConstrainedWindow();
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ConstrainedWindowViews::CloseConstrainedWindow() {
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Broadcast to all observers of NOTIFY_CWINDOW_CLOSED.
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // One example of such an observer is AutomationCWindowTracker in the
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // automation component.
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationService::current()->Notify(NotificationType::CWINDOW_CLOSED,
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         Source<ConstrainedWindow>(this),
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         NotificationService::NoDetails());
609ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GetWindow()->CloseWindow();
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
612ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ConstrainedWindowViews::FocusConstrainedWindow() {
613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if ((!owner_->delegate() ||
614ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen       owner_->delegate()->ShouldFocusConstrainedWindow()) &&
615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GetWindow()->window_delegate() &&
616ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GetWindow()->window_delegate()->GetInitiallyFocusedView()) {
617ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    GetWindow()->window_delegate()->GetInitiallyFocusedView()->RequestFocus();
618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
622ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// ConstrainedWindowViews, NativeConstrainedWindowDelegate implementation:
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
624ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ConstrainedWindowViews::OnNativeConstrainedWindowDestroyed() {
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Tell our constraining TabContents that we've gone so it can update its
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // list.
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  owner_->WillClose(this);
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
630ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ConstrainedWindowViews::OnNativeConstrainedWindowMouseActivate() {
631ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GetWindow()->Activate();
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
634ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenviews::NonClientFrameView* ConstrainedWindowViews::CreateFrameViewForWindow() {
635ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return new ConstrainedWindowFrameView(this);
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
638ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
639ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// ConstrainedWindow, public:
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochConstrainedWindow* ConstrainedWindow::CreateConstrainedDialog(
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TabContents* parent,
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    views::WindowDelegate* window_delegate) {
645ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return new ConstrainedWindowViews(parent, window_delegate);
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
647