OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/views/frame/aero_glass_non_client_view.h" | 5 #include "chrome/browser/views/frame/aero_glass_non_client_view.h" |
6 | 6 |
7 #include "chrome/app/theme/theme_resources.h" | 7 #include "chrome/app/theme/theme_resources.h" |
8 #include "chrome/browser/views/frame/browser_view.h" | 8 #include "chrome/browser/views/frame/browser_view.h" |
9 #include "chrome/browser/views/tabs/tab_strip.h" | 9 #include "chrome/browser/views/tabs/tab_strip.h" |
10 #include "chrome/common/gfx/chrome_canvas.h" | |
11 #include "chrome/common/gfx/chrome_font.h" | |
12 #include "chrome/common/gfx/path.h" | |
13 #include "chrome/common/resource_bundle.h" | 10 #include "chrome/common/resource_bundle.h" |
14 #include "chrome/views/client_view.h" | 11 #include "chrome/views/client_view.h" |
15 #include "chrome/views/window_delegate.h" | |
16 #include "chrome/views/window_resources.h" | 12 #include "chrome/views/window_resources.h" |
17 | 13 |
18 // An enumeration of bitmap resources used by this window. | 14 // An enumeration of bitmap resources used by this window. |
19 enum { | 15 enum { |
20 FRAME_PART_BITMAP_FIRST = 0, // must be first. | 16 FRAME_PART_BITMAP_FIRST = 0, // must be first. |
21 | 17 |
22 // Client Edge Border. | 18 // Client Edge Border. |
23 FRAME_CLIENT_EDGE_TOP_LEFT, | 19 FRAME_CLIENT_EDGE_TOP_LEFT, |
24 FRAME_CLIENT_EDGE_TOP, | 20 FRAME_CLIENT_EDGE_TOP, |
25 FRAME_CLIENT_EDGE_TOP_RIGHT, | 21 FRAME_CLIENT_EDGE_TOP_RIGHT, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 | 78 |
83 // static | 79 // static |
84 SkBitmap* AeroGlassWindowResources::standard_frame_bitmaps_[]; | 80 SkBitmap* AeroGlassWindowResources::standard_frame_bitmaps_[]; |
85 SkBitmap AeroGlassWindowResources::app_top_left_; | 81 SkBitmap AeroGlassWindowResources::app_top_left_; |
86 SkBitmap AeroGlassWindowResources::app_top_center_; | 82 SkBitmap AeroGlassWindowResources::app_top_center_; |
87 SkBitmap AeroGlassWindowResources::app_top_right_; | 83 SkBitmap AeroGlassWindowResources::app_top_right_; |
88 | 84 |
89 AeroGlassWindowResources* AeroGlassNonClientView::resources_ = NULL; | 85 AeroGlassWindowResources* AeroGlassNonClientView::resources_ = NULL; |
90 SkBitmap AeroGlassNonClientView::distributor_logo_; | 86 SkBitmap AeroGlassNonClientView::distributor_logo_; |
91 | 87 |
92 // The width of the client edge to the left and right of the window. | 88 namespace { |
93 static const int kClientEdgeWidth = 3; | 89 // There are 3 px of client edge drawn inside the outer frame borders. |
94 // The height of the client edge to the bottom of the window. | 90 const int kNonClientBorderThickness = 3; |
95 static const int kClientEdgeHeight = 2; | 91 // Besides the frame border, there's another 11 px of empty space atop the |
| 92 // window in restored mode, to use to drag the window around. |
| 93 const int kNonClientRestoredExtraThickness = 11; |
96 // In the window corners, the resize areas don't actually expand bigger, but the | 94 // In the window corners, the resize areas don't actually expand bigger, but the |
97 // 16 px at the end of the top and bottom edges triggers diagonal resizing. | 95 // 16 px at the end of the top and bottom edges triggers diagonal resizing. |
98 const int kResizeEdgeWidth = 16; | 96 const int kResizeAreaCornerSize = 16; |
99 // The horizontal distance between the left of the minimize button and the | 97 // The distributor logo is drawn 3 px from the top of the window. |
100 // right edge of the distributor logo. | 98 static const int kLogoTopSpacing = 3; |
101 static const int kDistributorLogoHorizontalOffset = 7; | |
102 // The distance from the top of the non-client view and the top edge of the | |
103 // distributor logo. | |
104 static const int kDistributorLogoVerticalOffset = 3; | |
105 // The distance of the TabStrip from the top of the window's client area. | |
106 static const int kTabStripY = 19; | |
107 // How much space on the right is not used for the tab strip (to provide | |
108 // separation between the tabs and the window controls). | |
109 static const int kTabStripRightHorizOffset = 30; | |
110 // A single pixel. | |
111 static const int kPixel = 1; | |
112 // The size (width/height) of the window icon. | |
113 static const int kWindowIconSize = 16; | |
114 // In maximized mode, the OTR avatar starts 2 px below the top of the screen, so | 99 // In maximized mode, the OTR avatar starts 2 px below the top of the screen, so |
115 // that it doesn't extend into the "3D edge" portion of the titlebar. | 100 // that it doesn't extend into the "3D edge" portion of the titlebar. |
116 const int kOTRMaximizedTopSpacing = 2; | 101 const int kOTRMaximizedTopSpacing = 2; |
117 // The OTR avatar ends 2 px above the bottom of the tabstrip (which, given the | 102 // The OTR avatar ends 2 px above the bottom of the tabstrip (which, given the |
118 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the | 103 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the |
119 // user). | 104 // user). |
120 const int kOTRBottomSpacing = 2; | 105 const int kOTRBottomSpacing = 2; |
121 // There are 2 px on each side of the OTR avatar (between the frame border and | 106 // There are 2 px on each side of the OTR avatar (between the frame border and |
122 // it on the left, and between it and the tabstrip on the right). | 107 // it on the left, and between it and the tabstrip on the right). |
123 const int kOTRSideSpacing = 2; | 108 const int kOTRSideSpacing = 2; |
| 109 // In restored mode, the New Tab button isn't at the same height as the caption |
| 110 // buttons, but the space will look cluttered if it actually slides under them, |
| 111 // so we stop it when the gap between the two is down to 5 px. |
| 112 const int kNewTabCaptionRestoredSpacing = 5; |
| 113 // In maximized mode, where the New Tab button and the caption buttons are at |
| 114 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid |
| 115 // looking too cluttered. |
| 116 const int kNewTabCaptionMaximizedSpacing = 16; |
| 117 // When there's a distributor logo, we leave a 7 px gap between it and the |
| 118 // caption buttons. |
| 119 const int kLogoCaptionSpacing = 7; |
| 120 } |
124 | 121 |
125 /////////////////////////////////////////////////////////////////////////////// | 122 /////////////////////////////////////////////////////////////////////////////// |
126 // AeroGlassNonClientView, public: | 123 // AeroGlassNonClientView, public: |
127 | 124 |
128 AeroGlassNonClientView::AeroGlassNonClientView(AeroGlassFrame* frame, | 125 AeroGlassNonClientView::AeroGlassNonClientView(AeroGlassFrame* frame, |
129 BrowserView* browser_view) | 126 BrowserView* browser_view) |
130 : frame_(frame), | 127 : frame_(frame), |
131 browser_view_(browser_view) { | 128 browser_view_(browser_view) { |
132 InitClass(); | 129 InitClass(); |
133 } | 130 } |
134 | 131 |
135 AeroGlassNonClientView::~AeroGlassNonClientView() { | 132 AeroGlassNonClientView::~AeroGlassNonClientView() { |
136 } | 133 } |
137 | 134 |
138 gfx::Rect AeroGlassNonClientView::GetBoundsForTabStrip(TabStrip* tabstrip) { | 135 gfx::Rect AeroGlassNonClientView::GetBoundsForTabStrip(TabStrip* tabstrip) { |
139 int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ? | 136 int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ? |
140 (otr_avatar_bounds_.right() + kOTRSideSpacing) : kClientEdgeWidth; | 137 (otr_avatar_bounds_.right() + kOTRSideSpacing) : |
141 int tabstrip_width = width() - tabstrip_x - kTabStripRightHorizOffset - | 138 NonClientBorderThickness(); |
142 (frame_->IsMaximized() ? frame_->GetMinimizeButtonOffset() : 0); | 139 int tabstrip_width = frame_->GetMinimizeButtonOffset() - tabstrip_x - |
143 int tabstrip_y = | 140 (frame_->IsMaximized() ? |
144 frame_->IsMaximized() ? (CalculateNonClientTopHeight() - 2) : kTabStripY; | 141 kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing); |
145 return gfx::Rect(tabstrip_x, tabstrip_y, std::max(0, tabstrip_width), | 142 return gfx::Rect(tabstrip_x, NonClientTopBorderHeight(), |
146 tabstrip->GetPreferredHeight()); | 143 std::max(0, tabstrip_width), tabstrip->GetPreferredHeight()); |
147 } | 144 } |
148 | 145 |
149 /////////////////////////////////////////////////////////////////////////////// | 146 /////////////////////////////////////////////////////////////////////////////// |
150 // AeroGlassNonClientView, views::NonClientView implementation: | 147 // AeroGlassNonClientView, views::NonClientView implementation: |
151 | 148 |
152 gfx::Rect AeroGlassNonClientView::CalculateClientAreaBounds(int win_width, | 149 gfx::Rect AeroGlassNonClientView::CalculateClientAreaBounds(int width, |
153 int win_height) cons
t { | 150 int height) const { |
154 if (!browser_view_->IsTabStripVisible()) | 151 if (!browser_view_->IsTabStripVisible()) |
155 return gfx::Rect(0, 0, width(), height()); | 152 return gfx::Rect(0, 0, this->width(), this->height()); |
156 | 153 |
157 int top_margin = CalculateNonClientTopHeight(); | 154 int top_height = NonClientTopBorderHeight(); |
158 return gfx::Rect(kClientEdgeWidth, top_margin, | 155 int border_thickness = NonClientBorderThickness(); |
159 std::max(0, win_width - (2 * kClientEdgeWidth)), | 156 return gfx::Rect(border_thickness, top_height, |
160 std::max(0, win_height - top_margin - kClientEdgeHeight)); | 157 std::max(0, width - (2 * border_thickness)), |
161 } | 158 std::max(0, height - top_height - border_thickness)); |
162 | |
163 gfx::Size AeroGlassNonClientView::CalculateWindowSizeForClientSize( | |
164 int width, | |
165 int height) const { | |
166 int top_margin = CalculateNonClientTopHeight(); | |
167 return gfx::Size(width + (2 * kClientEdgeWidth), | |
168 height + top_margin + kClientEdgeHeight); | |
169 } | 159 } |
170 | 160 |
171 CPoint AeroGlassNonClientView::GetSystemMenuPoint() const { | 161 CPoint AeroGlassNonClientView::GetSystemMenuPoint() const { |
172 CPoint offset(0, 0); | 162 CPoint offset; |
173 MapWindowPoints(GetWidget()->GetHWND(), HWND_DESKTOP, &offset, 1); | 163 MapWindowPoints(GetWidget()->GetHWND(), HWND_DESKTOP, &offset, 1); |
174 return offset; | 164 return offset; |
175 } | 165 } |
176 | 166 |
177 int AeroGlassNonClientView::NonClientHitTest(const gfx::Point& point) { | 167 int AeroGlassNonClientView::NonClientHitTest(const gfx::Point& point) { |
178 // If we don't have a tabstrip, we haven't customized the frame, so Windows | 168 // If we don't have a tabstrip, we haven't customized the frame, so Windows |
179 // can figure this out. If the point isn't within our bounds, then it's in | 169 // can figure this out. If the point isn't within our bounds, then it's in |
180 // the native portion of the frame, so again Windows can figure it out. | 170 // the native portion of the frame, so again Windows can figure it out. |
181 if (!browser_view_->IsTabStripVisible() || !bounds().Contains(point)) | 171 if (!browser_view_->IsTabStripVisible() || !bounds().Contains(point)) |
182 return HTNOWHERE; | 172 return HTNOWHERE; |
183 | 173 |
184 // See if the client view intersects the non-client area (e.g. blank areas | |
185 // of the TabStrip). | |
186 int frame_component = frame_->client_view()->NonClientHitTest(point); | 174 int frame_component = frame_->client_view()->NonClientHitTest(point); |
187 if (frame_component != HTNOWHERE) | 175 if (frame_component != HTNOWHERE) |
188 return frame_component; | 176 return frame_component; |
189 | 177 |
190 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); | 178 int border_thickness = FrameBorderThickness(); |
191 int resize_width = kResizeEdgeWidth - border_thickness; | 179 int window_component = GetHTComponentForFrame(point, border_thickness, |
192 if (point.x() < kClientEdgeWidth) { | 180 NonClientBorderThickness(), border_thickness, |
193 if (point.y() < border_thickness) | 181 kResizeAreaCornerSize - border_thickness, |
194 return HTTOPLEFT; | 182 frame_->window_delegate()->CanResize()); |
195 if (point.y() >= (height() - kClientEdgeHeight)) | 183 // Fall back to the caption if no other component matches. |
196 return HTBOTTOMLEFT; | 184 return (window_component == HTNOWHERE) ? HTCAPTION : window_component; |
197 return HTLEFT; | |
198 } | |
199 if (point.x() >= (width() - kClientEdgeWidth)) { | |
200 if (point.y() < border_thickness) | |
201 return HTTOPRIGHT; | |
202 if (point.y() >= (height() - kClientEdgeHeight)) | |
203 return HTBOTTOMRIGHT; | |
204 return HTRIGHT; | |
205 } | |
206 if (point.y() < border_thickness) { | |
207 if (point.x() < resize_width) | |
208 return HTTOPLEFT; | |
209 if (point.x() >= (width() - resize_width)) | |
210 return HTTOPRIGHT; | |
211 return HTTOP; | |
212 } | |
213 if (point.y() >= (height() - kClientEdgeHeight)) { | |
214 if (point.x() < resize_width) | |
215 return HTBOTTOMLEFT; | |
216 if (point.x() >= (width() - resize_width)) | |
217 return HTBOTTOMRIGHT; | |
218 return HTBOTTOM; | |
219 } | |
220 return HTCAPTION; | |
221 } | |
222 | |
223 void AeroGlassNonClientView::GetWindowMask(const gfx::Size& size, | |
224 gfx::Path* window_mask) { | |
225 // We use the native window region. | |
226 } | |
227 | |
228 void AeroGlassNonClientView::EnableClose(bool enable) { | |
229 // This is handled exclusively by Window. | |
230 } | |
231 | |
232 void AeroGlassNonClientView::ResetWindowControls() { | |
233 // Our window controls are rendered by the system and do not require reset. | |
234 } | 185 } |
235 | 186 |
236 /////////////////////////////////////////////////////////////////////////////// | 187 /////////////////////////////////////////////////////////////////////////////// |
237 // AeroGlassNonClientView, views::View overrides: | 188 // AeroGlassNonClientView, views::View overrides: |
238 | 189 |
239 void AeroGlassNonClientView::Paint(ChromeCanvas* canvas) { | 190 void AeroGlassNonClientView::Paint(ChromeCanvas* canvas) { |
240 PaintDistributorLogo(canvas); | 191 PaintDistributorLogo(canvas); |
241 if (browser_view_->IsTabStripVisible()) | 192 if (browser_view_->IsTabStripVisible()) |
242 PaintToolbarBackground(canvas); | 193 PaintToolbarBackground(canvas); |
243 PaintOTRAvatar(canvas); | 194 PaintOTRAvatar(canvas); |
244 if (browser_view_->IsTabStripVisible()) | 195 if (browser_view_->IsTabStripVisible()) |
245 PaintClientEdge(canvas); | 196 PaintClientEdge(canvas); |
246 } | 197 } |
247 | 198 |
248 void AeroGlassNonClientView::Layout() { | 199 void AeroGlassNonClientView::Layout() { |
| 200 LayoutDistributorLogo(); |
249 LayoutOTRAvatar(); | 201 LayoutOTRAvatar(); |
250 LayoutDistributorLogo(); | |
251 LayoutClientView(); | 202 LayoutClientView(); |
252 } | 203 } |
253 | 204 |
254 gfx::Size AeroGlassNonClientView::GetPreferredSize() { | |
255 gfx::Size prefsize = frame_->client_view()->GetPreferredSize(); | |
256 prefsize.Enlarge(2 * kClientEdgeWidth, | |
257 CalculateNonClientTopHeight() + kClientEdgeHeight); | |
258 return prefsize; | |
259 } | |
260 | |
261 void AeroGlassNonClientView::ViewHierarchyChanged(bool is_add, | 205 void AeroGlassNonClientView::ViewHierarchyChanged(bool is_add, |
262 views::View* parent, | 206 views::View* parent, |
263 views::View* child) { | 207 views::View* child) { |
264 if (is_add && child == this) { | 208 if (is_add && child == this) { |
265 DCHECK(GetWidget()); | 209 DCHECK(GetWidget()); |
266 DCHECK(frame_->client_view()->GetParent() != this); | 210 DCHECK(frame_->client_view()->GetParent() != this); |
267 AddChildView(frame_->client_view()); | 211 AddChildView(frame_->client_view()); |
268 } | 212 } |
269 } | 213 } |
270 | 214 |
271 /////////////////////////////////////////////////////////////////////////////// | 215 /////////////////////////////////////////////////////////////////////////////// |
272 // AeroGlassNonClientView, private: | 216 // AeroGlassNonClientView, private: |
273 | 217 |
274 int AeroGlassNonClientView::CalculateNonClientTopHeight() const { | 218 int AeroGlassNonClientView::FrameBorderThickness() const { |
275 return browser_view_->IsTabStripVisible() ? | 219 return GetSystemMetrics(SM_CXSIZEFRAME); |
276 GetSystemMetrics(SM_CYSIZEFRAME) : 0; | 220 } |
| 221 |
| 222 int AeroGlassNonClientView::NonClientBorderThickness() const { |
| 223 return kNonClientBorderThickness; |
| 224 } |
| 225 |
| 226 int AeroGlassNonClientView::NonClientTopBorderHeight() const { |
| 227 return FrameBorderThickness() + |
| 228 (frame_->IsMaximized() ? 0 : kNonClientRestoredExtraThickness); |
| 229 } |
| 230 |
| 231 void AeroGlassNonClientView::PaintDistributorLogo(ChromeCanvas* canvas) { |
| 232 // The distributor logo is only painted when the frame is not maximized and |
| 233 // when we actually have a logo. |
| 234 if (!frame_->IsMaximized() && !distributor_logo_.empty()) { |
| 235 // TODO: Do we need to mirror this? |
| 236 canvas->DrawBitmapInt(distributor_logo_, logo_bounds_.x(), |
| 237 logo_bounds_.y()); |
| 238 } |
| 239 } |
| 240 |
| 241 void AeroGlassNonClientView::PaintToolbarBackground(ChromeCanvas* canvas) { |
| 242 gfx::Rect toolbar_bounds(browser_view_->GetToolbarBounds()); |
| 243 gfx::Point toolbar_origin(toolbar_bounds.origin()); |
| 244 View::ConvertPointToView(frame_->client_view(), this, &toolbar_origin); |
| 245 toolbar_bounds.set_origin(toolbar_origin); |
| 246 |
| 247 SkBitmap* toolbar_left = |
| 248 resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_LEFT); |
| 249 canvas->DrawBitmapInt(*toolbar_left, |
| 250 toolbar_bounds.x() - toolbar_left->width(), |
| 251 toolbar_bounds.y()); |
| 252 |
| 253 SkBitmap* toolbar_center = |
| 254 resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP); |
| 255 canvas->TileImageInt(*toolbar_center, toolbar_bounds.x(), toolbar_bounds.y(), |
| 256 toolbar_bounds.width(), toolbar_center->height()); |
| 257 |
| 258 canvas->DrawBitmapInt(*resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_RIGHT), |
| 259 toolbar_bounds.right(), toolbar_bounds.y()); |
277 } | 260 } |
278 | 261 |
279 void AeroGlassNonClientView::PaintOTRAvatar(ChromeCanvas* canvas) { | 262 void AeroGlassNonClientView::PaintOTRAvatar(ChromeCanvas* canvas) { |
280 if (!browser_view_->ShouldShowOffTheRecordAvatar()) | 263 if (!browser_view_->ShouldShowOffTheRecordAvatar()) |
281 return; | 264 return; |
282 | 265 |
283 SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); | 266 SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); |
284 canvas->DrawBitmapInt(otr_avatar_icon, 0, | 267 canvas->DrawBitmapInt(otr_avatar_icon, 0, |
285 (otr_avatar_icon.height() - otr_avatar_bounds_.height()) / 2, | 268 (otr_avatar_icon.height() - otr_avatar_bounds_.height()) / 2, |
286 otr_avatar_bounds_.width(), otr_avatar_bounds_.height(), | 269 otr_avatar_bounds_.width(), otr_avatar_bounds_.height(), |
287 MirroredLeftPointForRect(otr_avatar_bounds_), otr_avatar_bounds_.y(), | 270 MirroredLeftPointForRect(otr_avatar_bounds_), otr_avatar_bounds_.y(), |
288 otr_avatar_bounds_.width(), otr_avatar_bounds_.height(), false); | 271 otr_avatar_bounds_.width(), otr_avatar_bounds_.height(), false); |
289 } | 272 } |
290 | 273 |
291 void AeroGlassNonClientView::PaintDistributorLogo(ChromeCanvas* canvas) { | 274 void AeroGlassNonClientView::PaintClientEdge(ChromeCanvas* canvas) { |
292 // The distributor logo is only painted when the frame is not maximized and | 275 int client_area_top = |
293 // when we actually have a logo. | 276 frame_->client_view()->y() + browser_view_->GetToolbarBounds().bottom(); |
294 if (!frame_->IsMaximized() && !frame_->IsMinimized() && | 277 gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height()); |
295 !distributor_logo_.empty()) { | 278 // The toolbar draws a client edge along its own bottom edge when it's visible |
296 canvas->DrawBitmapInt(distributor_logo_, logo_bounds_.x(), | 279 // and in normal mode. However, it only draws this for the width of the |
297 logo_bounds_.y()); | 280 // actual client area, leaving a gap at the left and right edges: |
298 } | 281 // |
| 282 // | Toolbar | <-- part of toolbar |
| 283 // ----- (toolbar client edge) ----- <-- gap |
| 284 // | Client area | <-- right client edge |
| 285 // |
| 286 // To address this, we extend the left and right client edges up to fill the |
| 287 // gap, by pretending the toolbar is shorter than it really is. |
| 288 client_area_top -= kClientEdgeThickness; |
| 289 |
| 290 int client_area_bottom = |
| 291 std::max(client_area_top, height() - NonClientBorderThickness()); |
| 292 int client_area_height = client_area_bottom - client_area_top; |
| 293 SkBitmap* right = resources_->GetPartBitmap(FRAME_CLIENT_EDGE_RIGHT); |
| 294 canvas->TileImageInt(*right, client_area_bounds.right(), client_area_top, |
| 295 right->width(), client_area_height); |
| 296 |
| 297 canvas->DrawBitmapInt( |
| 298 *resources_->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_RIGHT), |
| 299 client_area_bounds.right(), client_area_bottom); |
| 300 |
| 301 SkBitmap* bottom = resources_->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM); |
| 302 canvas->TileImageInt(*bottom, client_area_bounds.x(), |
| 303 client_area_bottom, client_area_bounds.width(), |
| 304 bottom->height()); |
| 305 |
| 306 SkBitmap* bottom_left = |
| 307 resources_->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_LEFT); |
| 308 canvas->DrawBitmapInt(*bottom_left, |
| 309 client_area_bounds.x() - bottom_left->width(), client_area_bottom); |
| 310 |
| 311 SkBitmap* left = resources_->GetPartBitmap(FRAME_CLIENT_EDGE_LEFT); |
| 312 canvas->TileImageInt(*left, client_area_bounds.x() - left->width(), |
| 313 client_area_top, left->width(), client_area_height); |
299 } | 314 } |
300 | 315 |
301 void AeroGlassNonClientView::PaintToolbarBackground(ChromeCanvas* canvas) { | 316 void AeroGlassNonClientView::LayoutDistributorLogo() { |
302 SkBitmap* toolbar_left = | 317 int logo_x = frame_->GetMinimizeButtonOffset() - (distributor_logo_.empty() ? |
303 resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_LEFT); | 318 0 : (distributor_logo_.width() + kLogoCaptionSpacing)); |
304 SkBitmap* toolbar_center = | 319 logo_bounds_.SetRect(logo_x, kLogoTopSpacing, distributor_logo_.width(), |
305 resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP); | 320 distributor_logo_.height()); |
306 SkBitmap* toolbar_right = | |
307 resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_RIGHT); | |
308 | |
309 gfx::Rect toolbar_bounds = browser_view_->GetToolbarBounds(); | |
310 gfx::Point topleft(toolbar_bounds.x(), toolbar_bounds.y()); | |
311 View::ConvertPointToView(frame_->client_view(), this, &topleft); | |
312 toolbar_bounds.set_x(topleft.x()); | |
313 toolbar_bounds.set_y(topleft.y()); | |
314 | |
315 // We use TileImageInt for the left and right caps to clip the rendering | |
316 // to the appropriate height of the toolbar. | |
317 canvas->TileImageInt(*toolbar_left, | |
318 toolbar_bounds.x() - toolbar_left->width(), | |
319 toolbar_bounds.y(), toolbar_left->width(), | |
320 toolbar_bounds.height()); | |
321 canvas->TileImageInt(*toolbar_center, | |
322 toolbar_bounds.x(), toolbar_bounds.y(), | |
323 toolbar_bounds.width(), toolbar_center->height()); | |
324 canvas->TileImageInt(*toolbar_right, toolbar_bounds.right(), | |
325 toolbar_bounds.y(), toolbar_right->width(), | |
326 toolbar_bounds.height()); | |
327 } | |
328 | |
329 void AeroGlassNonClientView::PaintClientEdge(ChromeCanvas* canvas) { | |
330 SkBitmap* right = resources_->GetPartBitmap(FRAME_CLIENT_EDGE_RIGHT); | |
331 SkBitmap* bottom_right = | |
332 resources_->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_RIGHT); | |
333 SkBitmap* bottom = resources_->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM); | |
334 SkBitmap* bottom_left = | |
335 resources_->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_LEFT); | |
336 SkBitmap* left = resources_->GetPartBitmap(FRAME_CLIENT_EDGE_LEFT); | |
337 | |
338 // The toolbar renders its own client edge in PaintToolbarBackground, however | |
339 // there are other bands that need to have a client edge rendered along their | |
340 // sides, such as the Bookmark bar, infobars, etc. | |
341 gfx::Rect toolbar_bounds = browser_view_->GetToolbarBounds(); | |
342 gfx::Rect client_area_bounds = browser_view_->GetClientAreaBounds(); | |
343 // For some reason things don't line up quite right, so we add and subtract | |
344 // pixels here and there for aesthetic bliss. | |
345 // Enlarge the client area to include the toolbar, since the top edge of | |
346 // the client area is the toolbar background and the client edge renders | |
347 // the left and right sides of the toolbar background. | |
348 client_area_bounds.SetRect( | |
349 client_area_bounds.x(), | |
350 frame_->client_view()->y() + toolbar_bounds.bottom() - kPixel, | |
351 client_area_bounds.width(), | |
352 std::max(0, height() - frame_->client_view()->y() - | |
353 toolbar_bounds.bottom() + kPixel)); | |
354 | |
355 int fudge = frame_->window_delegate()->ShouldShowWindowTitle() ? kPixel : 0; | |
356 canvas->TileImageInt(*right, client_area_bounds.right(), | |
357 client_area_bounds.y() + fudge, right->width(), | |
358 client_area_bounds.height() - bottom_right->height() + | |
359 kPixel - fudge); | |
360 canvas->DrawBitmapInt(*bottom_right, client_area_bounds.right(), | |
361 client_area_bounds.bottom() - bottom_right->height() + | |
362 kPixel); | |
363 canvas->TileImageInt(*bottom, client_area_bounds.x(), | |
364 client_area_bounds.bottom() - bottom_right->height() + | |
365 kPixel, client_area_bounds.width(), | |
366 bottom_right->height()); | |
367 canvas->DrawBitmapInt(*bottom_left, | |
368 client_area_bounds.x() - bottom_left->width(), | |
369 client_area_bounds.bottom() - bottom_left->height() + | |
370 kPixel); | |
371 canvas->TileImageInt(*left, client_area_bounds.x() - left->width(), | |
372 client_area_bounds.y() + fudge, left->width(), | |
373 client_area_bounds.height() - bottom_left->height() + | |
374 kPixel - fudge); | |
375 } | 321 } |
376 | 322 |
377 void AeroGlassNonClientView::LayoutOTRAvatar() { | 323 void AeroGlassNonClientView::LayoutOTRAvatar() { |
378 SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); | 324 SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); |
379 int top_height = (frame_->IsMaximized() ? | 325 int top_height = NonClientTopBorderHeight(); |
380 (CalculateNonClientTopHeight() - 2) : kTabStripY); | |
381 int tabstrip_height = browser_view_->GetTabStripHeight() - kOTRBottomSpacing; | 326 int tabstrip_height = browser_view_->GetTabStripHeight() - kOTRBottomSpacing; |
382 int otr_height = frame_->IsMaximized() ? | 327 int otr_height = frame_->IsMaximized() ? |
383 (tabstrip_height - kOTRMaximizedTopSpacing) : | 328 (tabstrip_height - kOTRMaximizedTopSpacing) : |
384 otr_avatar_icon.height(); | 329 otr_avatar_icon.height(); |
385 otr_avatar_bounds_.SetRect(kClientEdgeWidth + kOTRSideSpacing, | 330 otr_avatar_bounds_.SetRect(NonClientBorderThickness() + kOTRSideSpacing, |
386 top_height + tabstrip_height - otr_height, otr_avatar_icon.width(), | 331 top_height + tabstrip_height - otr_height, |
387 otr_height); | 332 otr_avatar_icon.width(), otr_height); |
388 } | |
389 | |
390 void AeroGlassNonClientView::LayoutDistributorLogo() { | |
391 if (distributor_logo_.empty()) | |
392 return; | |
393 | |
394 int logo_w = distributor_logo_.width(); | |
395 int logo_h = distributor_logo_.height(); | |
396 | |
397 int w = width(); | |
398 int mbx = frame_->GetMinimizeButtonOffset(); | |
399 | |
400 logo_bounds_.SetRect( | |
401 width() - frame_->GetMinimizeButtonOffset() - logo_w, | |
402 kDistributorLogoVerticalOffset, logo_w, logo_h); | |
403 } | 333 } |
404 | 334 |
405 void AeroGlassNonClientView::LayoutClientView() { | 335 void AeroGlassNonClientView::LayoutClientView() { |
406 gfx::Rect client_bounds = CalculateClientAreaBounds(width(), height()); | 336 frame_->client_view()->SetBounds(CalculateClientAreaBounds(width(), |
407 frame_->client_view()->SetBounds(client_bounds); | 337 height())); |
408 } | 338 } |
409 | 339 |
410 // static | 340 // static |
411 void AeroGlassNonClientView::InitClass() { | 341 void AeroGlassNonClientView::InitClass() { |
412 static bool initialized = false; | 342 static bool initialized = false; |
413 if (!initialized) { | 343 if (!initialized) { |
414 resources_ = new AeroGlassWindowResources; | 344 resources_ = new AeroGlassWindowResources; |
| 345 |
415 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 346 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
416 #if defined(GOOGLE_CHROME_BUILD) | 347 #if defined(GOOGLE_CHROME_BUILD) |
417 distributor_logo_ = *rb.GetBitmapNamed(IDR_DISTRIBUTOR_LOGO); | 348 distributor_logo_ = *rb.GetBitmapNamed(IDR_DISTRIBUTOR_LOGO); |
418 #endif | 349 #endif |
419 | 350 |
420 initialized = true; | 351 initialized = true; |
421 } | 352 } |
422 } | 353 } |
423 | 354 |
OLD | NEW |