OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/glass_browser_frame_view.h" | 5 #include "chrome/browser/views/frame/glass_browser_frame_view.h" |
6 | 6 |
7 #include "app/resource_bundle.h" | 7 #include "app/resource_bundle.h" |
8 #include "app/theme_provider.h" | 8 #include "app/theme_provider.h" |
9 #include "chrome/app/chrome_dll_resource.h" | 9 #include "chrome/app/chrome_dll_resource.h" |
10 #include "chrome/browser/browser_theme_provider.h" | 10 #include "chrome/browser/browser_theme_provider.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 // There are 3 px of client edge drawn inside the outer frame borders. | 26 // There are 3 px of client edge drawn inside the outer frame borders. |
27 const int kNonClientBorderThickness = 3; | 27 const int kNonClientBorderThickness = 3; |
28 // Vertical tabs have 4 px border. | 28 // Vertical tabs have 4 px border. |
29 const int kNonClientVerticalTabStripBorderThickness = 4; | 29 const int kNonClientVerticalTabStripBorderThickness = 4; |
30 // Besides the frame border, there's another 11 px of empty space atop the | 30 // Besides the frame border, there's another 11 px of empty space atop the |
31 // window in restored mode, to use to drag the window around. | 31 // window in restored mode, to use to drag the window around. |
32 const int kNonClientRestoredExtraThickness = 11; | 32 const int kNonClientRestoredExtraThickness = 11; |
33 // In the window corners, the resize areas don't actually expand bigger, but the | 33 // In the window corners, the resize areas don't actually expand bigger, but the |
34 // 16 px at the end of the top and bottom edges triggers diagonal resizing. | 34 // 16 px at the end of the top and bottom edges triggers diagonal resizing. |
35 const int kResizeAreaCornerSize = 16; | 35 const int kResizeAreaCornerSize = 16; |
36 // In maximized mode, the OTR avatar starts 2 px below the top of the screen, so | |
37 // that it doesn't extend into the "3D edge" portion of the titlebar. | |
38 const int kOTRMaximizedTopSpacing = 2; | |
39 // The OTR avatar ends 2 px above the bottom of the tabstrip (which, given the | 36 // The OTR avatar ends 2 px above the bottom of the tabstrip (which, given the |
40 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the | 37 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the |
41 // user). | 38 // user). |
42 const int kOTRBottomSpacing = 2; | 39 const int kOTRBottomSpacing = 2; |
43 // There are 2 px on each side of the OTR avatar (between the frame border and | 40 // There are 2 px on each side of the OTR avatar (between the frame border and |
44 // it on the left, and between it and the tabstrip on the right). | 41 // it on the left, and between it and the tabstrip on the right). |
45 const int kOTRSideSpacing = 2; | 42 const int kOTRSideSpacing = 2; |
46 // The content left/right images have a shadow built into them. | 43 // The content left/right images have a shadow built into them. |
47 const int kContentEdgeShadowThickness = 2; | 44 const int kContentEdgeShadowThickness = 2; |
48 // The top 1 px of the tabstrip is shadow; in maximized mode we push this off | 45 // The top 1 px of the tabstrip is shadow; in maximized mode we push this off |
(...skipping 26 matching lines...) Expand all Loading... |
75 GlassBrowserFrameView::~GlassBrowserFrameView() { | 72 GlassBrowserFrameView::~GlassBrowserFrameView() { |
76 } | 73 } |
77 | 74 |
78 /////////////////////////////////////////////////////////////////////////////// | 75 /////////////////////////////////////////////////////////////////////////////// |
79 // GlassBrowserFrameView, BrowserNonClientFrameView implementation: | 76 // GlassBrowserFrameView, BrowserNonClientFrameView implementation: |
80 | 77 |
81 gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip( | 78 gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip( |
82 BaseTabStrip* tabstrip) const { | 79 BaseTabStrip* tabstrip) const { |
83 if (browser_view_->UseVerticalTabs()) { | 80 if (browser_view_->UseVerticalTabs()) { |
84 gfx::Size ps = tabstrip->GetPreferredSize(); | 81 gfx::Size ps = tabstrip->GetPreferredSize(); |
85 return gfx::Rect(NonClientBorderThickness(), NonClientTopBorderHeight(), | 82 return gfx::Rect(NonClientBorderThickness(), |
86 ps.width(), browser_view_->height()); | 83 NonClientTopBorderHeight(false, false), ps.width(), |
| 84 browser_view_->height()); |
87 } | 85 } |
88 int minimize_button_offset = frame_->GetMinimizeButtonOffset(); | 86 int minimize_button_offset = frame_->GetMinimizeButtonOffset(); |
89 int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ? | 87 int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ? |
90 (otr_avatar_bounds_.right() + kOTRSideSpacing) : | 88 (otr_avatar_bounds_.right() + kOTRSideSpacing) : |
91 NonClientBorderThickness(); | 89 NonClientBorderThickness(); |
92 // In RTL languages, we have moved an avatar icon left by the size of window | 90 // In RTL languages, we have moved an avatar icon left by the size of window |
93 // controls to prevent it from being rendered over them. So, we use its x | 91 // controls to prevent it from being rendered over them. So, we use its x |
94 // position to move this tab strip left when maximized. Also, we can render | 92 // position to move this tab strip left when maximized. Also, we can render |
95 // a tab strip until the left end of this window without considering the size | 93 // a tab strip until the left end of this window without considering the size |
96 // of window controls in RTL languages. | 94 // of window controls in RTL languages. |
97 if (base::i18n::IsRTL()) { | 95 if (base::i18n::IsRTL()) { |
98 if (!browser_view_->ShouldShowOffTheRecordAvatar() && | 96 if (!browser_view_->ShouldShowOffTheRecordAvatar() && |
99 frame_->GetWindow()->IsMaximized()) | 97 frame_->GetWindow()->IsMaximized()) |
100 tabstrip_x += otr_avatar_bounds_.x(); | 98 tabstrip_x += otr_avatar_bounds_.x(); |
101 minimize_button_offset = width(); | 99 minimize_button_offset = width(); |
102 } | 100 } |
103 int tabstrip_width = minimize_button_offset - tabstrip_x - | 101 int tabstrip_width = minimize_button_offset - tabstrip_x - |
104 (frame_->GetWindow()->IsMaximized() ? | 102 (frame_->GetWindow()->IsMaximized() ? |
105 kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing); | 103 kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing); |
106 return gfx::Rect(tabstrip_x, NonClientTopBorderHeight(), | 104 return gfx::Rect(tabstrip_x, GetHorizontalTabStripVerticalOffset(false), |
107 std::max(0, tabstrip_width), | 105 std::max(0, tabstrip_width), |
108 tabstrip->GetPreferredHeight()); | 106 tabstrip->GetPreferredHeight()); |
109 } | 107 } |
110 | 108 |
| 109 int GlassBrowserFrameView::GetHorizontalTabStripVerticalOffset( |
| 110 bool restored) const { |
| 111 return NonClientTopBorderHeight(restored, true); |
| 112 } |
| 113 |
111 void GlassBrowserFrameView::UpdateThrobber(bool running) { | 114 void GlassBrowserFrameView::UpdateThrobber(bool running) { |
112 if (throbber_running_) { | 115 if (throbber_running_) { |
113 if (running) { | 116 if (running) { |
114 DisplayNextThrobberFrame(); | 117 DisplayNextThrobberFrame(); |
115 } else { | 118 } else { |
116 StopThrobber(); | 119 StopThrobber(); |
117 } | 120 } |
118 } else if (running) { | 121 } else if (running) { |
119 StartThrobber(); | 122 StartThrobber(); |
120 } | 123 } |
(...skipping 17 matching lines...) Expand all Loading... |
138 // If we don't have a tabstrip, we're either a popup or an app window, in | 141 // If we don't have a tabstrip, we're either a popup or an app window, in |
139 // which case we have a standard size non-client area and can just use | 142 // which case we have a standard size non-client area and can just use |
140 // AdjustWindowRectEx to obtain it. We check for a non-NULL window handle in | 143 // AdjustWindowRectEx to obtain it. We check for a non-NULL window handle in |
141 // case this gets called before the window is actually created. | 144 // case this gets called before the window is actually created. |
142 RECT rect = client_bounds.ToRECT(); | 145 RECT rect = client_bounds.ToRECT(); |
143 AdjustWindowRectEx(&rect, GetWindowLong(hwnd, GWL_STYLE), FALSE, | 146 AdjustWindowRectEx(&rect, GetWindowLong(hwnd, GWL_STYLE), FALSE, |
144 GetWindowLong(hwnd, GWL_EXSTYLE)); | 147 GetWindowLong(hwnd, GWL_EXSTYLE)); |
145 return gfx::Rect(rect); | 148 return gfx::Rect(rect); |
146 } | 149 } |
147 | 150 |
148 int top_height = NonClientTopBorderHeight(); | 151 int top_height = NonClientTopBorderHeight(false, false); |
149 int border_thickness = NonClientBorderThickness(); | 152 int border_thickness = NonClientBorderThickness(); |
150 return gfx::Rect(std::max(0, client_bounds.x() - border_thickness), | 153 return gfx::Rect(std::max(0, client_bounds.x() - border_thickness), |
151 std::max(0, client_bounds.y() - top_height), | 154 std::max(0, client_bounds.y() - top_height), |
152 client_bounds.width() + (2 * border_thickness), | 155 client_bounds.width() + (2 * border_thickness), |
153 client_bounds.height() + top_height + border_thickness); | 156 client_bounds.height() + top_height + border_thickness); |
154 } | 157 } |
155 | 158 |
156 int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) { | 159 int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) { |
157 // If the browser isn't in normal mode, we haven't customized the frame, so | 160 // If the browser isn't in normal mode, we haven't customized the frame, so |
158 // Windows can figure this out. If the point isn't within our bounds, then | 161 // Windows can figure this out. If the point isn't within our bounds, then |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 int GlassBrowserFrameView::NonClientBorderThickness() const { | 218 int GlassBrowserFrameView::NonClientBorderThickness() const { |
216 views::Window* window = frame_->GetWindow(); | 219 views::Window* window = frame_->GetWindow(); |
217 if (window->IsMaximized() || window->IsFullscreen()) | 220 if (window->IsMaximized() || window->IsFullscreen()) |
218 return 0; | 221 return 0; |
219 | 222 |
220 return browser_view_->UseVerticalTabs() ? | 223 return browser_view_->UseVerticalTabs() ? |
221 kNonClientVerticalTabStripBorderThickness : | 224 kNonClientVerticalTabStripBorderThickness : |
222 kNonClientBorderThickness; | 225 kNonClientBorderThickness; |
223 } | 226 } |
224 | 227 |
225 int GlassBrowserFrameView::NonClientTopBorderHeight() const { | 228 int GlassBrowserFrameView::NonClientTopBorderHeight( |
226 if (frame_->GetWindow()->IsFullscreen()) | 229 bool restored, |
| 230 bool ignore_vertical_tabs) const { |
| 231 if (!restored && frame_->GetWindow()->IsFullscreen()) |
227 return 0; | 232 return 0; |
228 if (browser_view_->UseVerticalTabs()) | |
229 return static_cast<BrowserFrameWin*>(frame_)->GetTitleBarHeight(); | |
230 // We'd like to use FrameBorderThickness() here, but the maximized Aero glass | 233 // We'd like to use FrameBorderThickness() here, but the maximized Aero glass |
231 // frame has a 0 frame border around most edges and a CYSIZEFRAME-thick border | 234 // frame has a 0 frame border around most edges and a CYSIZEFRAME-thick border |
232 // at the top (see AeroGlassFrame::OnGetMinMaxInfo()). | 235 // at the top (see AeroGlassFrame::OnGetMinMaxInfo()). |
233 return GetSystemMetrics(SM_CYSIZEFRAME) + (browser_view_->IsMaximized() ? | 236 if (browser_view_->IsTabStripVisible() && !ignore_vertical_tabs && |
| 237 browser_view_->UseVerticalTabs()) |
| 238 return GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYCAPTION); |
| 239 return GetSystemMetrics(SM_CYSIZEFRAME) + |
| 240 ((!restored && browser_view_->IsMaximized()) ? |
234 -kTabstripTopShadowThickness : kNonClientRestoredExtraThickness); | 241 -kTabstripTopShadowThickness : kNonClientRestoredExtraThickness); |
235 } | 242 } |
236 | 243 |
237 void GlassBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) { | 244 void GlassBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) { |
238 ThemeProvider* tp = GetThemeProvider(); | 245 ThemeProvider* tp = GetThemeProvider(); |
239 | 246 |
240 gfx::Rect toolbar_bounds(browser_view_->GetToolbarBounds()); | 247 gfx::Rect toolbar_bounds(browser_view_->GetToolbarBounds()); |
241 gfx::Point toolbar_origin(toolbar_bounds.origin()); | 248 gfx::Point toolbar_origin(toolbar_bounds.origin()); |
242 View::ConvertPointToView(browser_view_, this, &toolbar_origin); | 249 View::ConvertPointToView(browser_view_, this, &toolbar_origin); |
243 toolbar_bounds.set_origin(toolbar_origin); | 250 toolbar_bounds.set_origin(toolbar_origin); |
| 251 int x = toolbar_bounds.x(); |
| 252 int w = toolbar_bounds.width(); |
| 253 int left_x = x - kContentEdgeShadowThickness; |
244 | 254 |
245 SkBitmap* theme_toolbar = tp->GetBitmapNamed(IDR_THEME_TOOLBAR); | 255 SkBitmap* theme_toolbar = tp->GetBitmapNamed(IDR_THEME_TOOLBAR); |
246 SkBitmap* toolbar_left = tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER); | 256 SkBitmap* toolbar_left = tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER); |
247 SkBitmap* toolbar_center = tp->GetBitmapNamed(IDR_CONTENT_TOP_CENTER); | 257 SkBitmap* toolbar_center = tp->GetBitmapNamed(IDR_CONTENT_TOP_CENTER); |
248 | 258 |
249 if (browser_view_->UseVerticalTabs()) { | 259 if (browser_view_->UseVerticalTabs()) { |
250 gfx::Rect tabstrip_bounds(browser_view_->tabstrip()->bounds()); | 260 gfx::Point tabstrip_origin(browser_view_->tabstrip()->bounds().origin()); |
251 gfx::Point tabstrip_origin(tabstrip_bounds.origin()); | |
252 View::ConvertPointToView(browser_view_, this, &tabstrip_origin); | 261 View::ConvertPointToView(browser_view_, this, &tabstrip_origin); |
253 tabstrip_bounds.set_origin(tabstrip_origin); | 262 int y = tabstrip_origin.y(); |
254 | 263 |
255 int x = tabstrip_bounds.x(); | 264 // Tile the toolbar image starting at the frame edge on the left and where |
256 int y = tabstrip_origin.y(); | 265 // the horizontal tabstrip would be on the top. |
257 int w = toolbar_bounds.right() - x; | 266 canvas->TileImageInt(*theme_toolbar, x, |
258 | 267 y - GetHorizontalTabStripVerticalOffset(false), x, y, |
259 canvas->TileImageInt(*theme_toolbar, 0, | 268 w, theme_toolbar->height()); |
260 Tab::GetMinimumUnselectedSize().height(), | |
261 MirroredLeftPointForRect(toolbar_bounds), y, | |
262 toolbar_bounds.width(), theme_toolbar->height()); | |
263 | 269 |
264 // Draw left edge. | 270 // Draw left edge. |
265 int dest_y = y - kNonClientBorderThickness; | 271 int dest_y = y - kNonClientBorderThickness; |
266 canvas->DrawBitmapInt(*toolbar_left, 0, 0, kNonClientBorderThickness, | 272 canvas->DrawBitmapInt(*toolbar_left, 0, 0, kNonClientBorderThickness, |
267 kNonClientBorderThickness, x - kNonClientBorderThickness, dest_y, | 273 kNonClientBorderThickness, left_x, dest_y, |
268 kNonClientBorderThickness, kNonClientBorderThickness, false); | 274 kNonClientBorderThickness, kNonClientBorderThickness, |
| 275 false); |
269 | 276 |
270 // Draw center edge. We need to draw a while line above the toolbar for the | 277 // Draw center edge. We need to draw a while line above the toolbar for the |
271 // image to overlay nicely. | 278 // image to overlay nicely. |
272 canvas->FillRectInt(SK_ColorWHITE, x, y - 1, w, 1); | 279 int center_offset = |
273 canvas->TileImageInt(*toolbar_center, x, dest_y, w, | 280 -kContentEdgeShadowThickness + kNonClientBorderThickness; |
274 toolbar_center->height()); | 281 canvas->FillRectInt(SK_ColorWHITE, x + center_offset, y - 1, |
| 282 w - (2 * center_offset), 1); |
| 283 canvas->TileImageInt(*toolbar_center, x + center_offset, dest_y, |
| 284 w - (2 * center_offset), toolbar_center->height()); |
275 | 285 |
276 // Right edge. | 286 // Right edge. |
277 SkBitmap* toolbar_right = tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER); | 287 SkBitmap* toolbar_right = tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER); |
278 canvas->DrawBitmapInt(*toolbar_right, | 288 canvas->DrawBitmapInt(*toolbar_right, |
279 toolbar_right->width() - kNonClientBorderThickness, 0, | 289 toolbar_right->width() - kNonClientBorderThickness, 0, |
280 kNonClientBorderThickness, kNonClientBorderThickness, | 290 kNonClientBorderThickness, kNonClientBorderThickness, |
281 x + w - kNonClientBorderThickness, dest_y, kNonClientBorderThickness, | 291 x + w - center_offset, dest_y, kNonClientBorderThickness, |
282 kNonClientBorderThickness, false); | 292 kNonClientBorderThickness, false); |
283 } else { | 293 } else { |
284 // Draw the toolbar background, setting src_y of the paint to the tab | 294 // Tile the toolbar image starting at the frame edge on the left and where |
285 // strip height as the toolbar background begins at the top of the tabs. | 295 // the tabstrip is on the top. |
286 int x = toolbar_bounds.x() - kClientEdgeThickness; | |
287 int y = toolbar_bounds.y(); | 296 int y = toolbar_bounds.y(); |
288 int src_y = browser_view_->GetTabStripHeight() - 1; | 297 int dest_y = y + (kFrameShadowThickness * 2); |
289 canvas->TileImageInt(*theme_toolbar, 0, src_y, x, | 298 canvas->TileImageInt(*theme_toolbar, x, |
290 y + (kFrameShadowThickness * 2), | 299 dest_y - GetHorizontalTabStripVerticalOffset(false), x, |
291 toolbar_bounds.width() + (2 * kClientEdgeThickness), | 300 dest_y, w, theme_toolbar->height()); |
292 theme_toolbar->height()); | |
293 | 301 |
294 // Draw rounded corners for the tab. | 302 // Draw rounded corners for the tab. |
295 SkBitmap* toolbar_left_mask = | 303 SkBitmap* toolbar_left_mask = |
296 tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER_MASK); | 304 tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER_MASK); |
297 SkBitmap* toolbar_right_mask = | 305 SkBitmap* toolbar_right_mask = |
298 tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER_MASK); | 306 tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER_MASK); |
299 | 307 |
300 // We mask out the corners by using the DestinationIn transfer mode, | 308 // We mask out the corners by using the DestinationIn transfer mode, |
301 // which keeps the RGB pixels from the destination and the alpha from | 309 // which keeps the RGB pixels from the destination and the alpha from |
302 // the source. | 310 // the source. |
303 SkPaint paint; | 311 SkPaint paint; |
304 paint.setXfermodeMode(SkXfermode::kDstIn_Mode); | 312 paint.setXfermodeMode(SkXfermode::kDstIn_Mode); |
305 | 313 |
306 // Mask out the top left corner. | 314 // Mask out the top left corner. |
307 int left_x = x - kContentEdgeShadowThickness; | |
308 canvas->DrawBitmapInt(*toolbar_left_mask, left_x, y, paint); | 315 canvas->DrawBitmapInt(*toolbar_left_mask, left_x, y, paint); |
309 | 316 |
310 // Mask out the top right corner. | 317 // Mask out the top right corner. |
311 int right_x = toolbar_bounds.right() - toolbar_right_mask->width() + | 318 int right_x = |
312 kContentEdgeShadowThickness + kClientEdgeThickness; | 319 x + w + kContentEdgeShadowThickness - toolbar_right_mask->width(); |
313 canvas->DrawBitmapInt(*toolbar_right_mask, right_x, y, paint); | 320 canvas->DrawBitmapInt(*toolbar_right_mask, right_x, y, paint); |
314 | 321 |
315 // Draw left edge. | 322 // Draw left edge. |
316 canvas->DrawBitmapInt(*toolbar_left, left_x, y); | 323 canvas->DrawBitmapInt(*toolbar_left, left_x, y); |
317 | 324 |
318 // Draw center edge. | 325 // Draw center edge. |
319 canvas->TileImageInt(*toolbar_center, left_x + toolbar_left->width(), y, | 326 canvas->TileImageInt(*toolbar_center, left_x + toolbar_left->width(), y, |
320 right_x - (left_x + toolbar_left->width()), toolbar_center->height()); | 327 right_x - (left_x + toolbar_left->width()), toolbar_center->height()); |
321 | 328 |
322 // Right edge. | 329 // Right edge. |
323 canvas->DrawBitmapInt(*tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER), | 330 canvas->DrawBitmapInt(*tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER), |
324 right_x, y); | 331 right_x, y); |
325 } | 332 } |
326 | 333 |
327 // Draw the content/toolbar separator. | 334 // Draw the content/toolbar separator. |
328 canvas->FillRectInt(ResourceBundle::toolbar_separator_color, | 335 canvas->FillRectInt(ResourceBundle::toolbar_separator_color, |
329 toolbar_bounds.x(), toolbar_bounds.bottom() - kClientEdgeThickness, | 336 x + kClientEdgeThickness, toolbar_bounds.bottom() - kClientEdgeThickness, |
330 toolbar_bounds.width(), kClientEdgeThickness); | 337 w - (2 * kClientEdgeThickness), kClientEdgeThickness); |
331 } | 338 } |
332 | 339 |
333 void GlassBrowserFrameView::PaintOTRAvatar(gfx::Canvas* canvas) { | 340 void GlassBrowserFrameView::PaintOTRAvatar(gfx::Canvas* canvas) { |
| 341 // In RTL mode, the avatar icon should be looking the opposite direction. |
| 342 canvas->Save(); |
| 343 if (base::i18n::IsRTL()) { |
| 344 canvas->TranslateInt(width(), 0); |
| 345 canvas->ScaleInt(-1, 1); |
| 346 } |
| 347 |
334 SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); | 348 SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); |
335 int src_x = 0; | |
336 int src_y = (otr_avatar_icon.height() - otr_avatar_bounds_.height()) / 2; | |
337 int dst_x = MirroredLeftPointForRect(otr_avatar_bounds_); | |
338 int dst_y = otr_avatar_bounds_.y(); | |
339 int w = otr_avatar_bounds_.width(); | 349 int w = otr_avatar_bounds_.width(); |
340 int h = otr_avatar_bounds_.height(); | 350 int h = otr_avatar_bounds_.height(); |
341 if (browser_view_->UseVerticalTabs()) { | 351 canvas->DrawBitmapInt(otr_avatar_icon, 0, |
342 // Only a portion of the otr icon is visible for vertical tabs. Clip it | 352 // Bias the rounding to select a region that's lower rather than higher, |
343 // so that it doesn't overlap shadows. | 353 // as the shadows at the image top mean the apparent center is below the |
344 gfx::Point tabstrip_origin(browser_view_->tabstrip()->bounds().origin()); | 354 // real center. |
345 View::ConvertPointToView(frame_->GetWindow()->GetClientView(), this, | 355 ((otr_avatar_icon.height() - otr_avatar_bounds_.height()) + 1) / 2, w, h, |
346 &tabstrip_origin); | 356 otr_avatar_bounds_.x(), otr_avatar_bounds_.y(), w, h, false); |
347 canvas->Save(); | 357 |
348 canvas->ClipRectInt(dst_x, 2, w, tabstrip_origin.y() - 4); | 358 canvas->Restore(); |
349 canvas->DrawBitmapInt(otr_avatar_icon, src_x, src_y, w, h, dst_x, dst_y, | |
350 w, h, false); | |
351 canvas->Restore(); | |
352 } else { | |
353 canvas->DrawBitmapInt(otr_avatar_icon, src_x, src_y, w, h, dst_x, dst_y, | |
354 w, h, false); | |
355 } | |
356 } | 359 } |
357 | 360 |
358 void GlassBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { | 361 void GlassBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { |
359 ThemeProvider* tp = GetThemeProvider(); | 362 ThemeProvider* tp = GetThemeProvider(); |
360 gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height()); | 363 gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height()); |
361 | 364 |
362 // The client edges start below the toolbar upper corner images regardless | 365 // The client edges start below the toolbar upper corner images regardless |
363 // of how tall the toolbar itself is. | 366 // of how tall the toolbar itself is. |
364 int client_area_top = browser_view_->UseVerticalTabs() ? | 367 int client_area_top = browser_view_->UseVerticalTabs() ? |
365 client_area_bounds.y() : | 368 client_area_bounds.y() : |
366 (frame_->GetWindow()->GetClientView()->y() + | 369 (frame_->GetWindow()->GetClientView()->y() + |
367 browser_view_->GetToolbarBounds().y() + | 370 browser_view_->GetToolbarBounds().y() + |
368 tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER)->height()); | 371 tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER)->height()); |
369 int client_area_bottom = | 372 int client_area_bottom = |
370 std::max(client_area_top, height() - NonClientBorderThickness()); | 373 std::max(client_area_top, height() - NonClientBorderThickness()); |
371 int client_area_height = client_area_bottom - client_area_top; | 374 int client_area_height = client_area_bottom - client_area_top; |
372 | 375 |
| 376 // Draw the client edge images. |
373 SkBitmap* right = tp->GetBitmapNamed(IDR_CONTENT_RIGHT_SIDE); | 377 SkBitmap* right = tp->GetBitmapNamed(IDR_CONTENT_RIGHT_SIDE); |
374 canvas->TileImageInt(*right, client_area_bounds.right(), client_area_top, | 378 canvas->TileImageInt(*right, client_area_bounds.right(), client_area_top, |
375 right->width(), client_area_height); | 379 right->width(), client_area_height); |
376 | |
377 // Draw the toolbar color so that the client edges show the right color even | |
378 // where not covered by the toolbar image. | |
379 SkColor toolbar_color = tp->GetColor(BrowserThemeProvider::COLOR_TOOLBAR); | |
380 canvas->FillRectInt(toolbar_color, | |
381 client_area_bounds.x() - kClientEdgeThickness, client_area_top, | |
382 kClientEdgeThickness, | |
383 client_area_bottom + kClientEdgeThickness - client_area_top); | |
384 canvas->FillRectInt(toolbar_color, client_area_bounds.x(), client_area_bottom, | |
385 client_area_bounds.width(), kClientEdgeThickness); | |
386 canvas->FillRectInt(toolbar_color, client_area_bounds.right(), | |
387 client_area_top, kClientEdgeThickness, | |
388 client_area_bottom + kClientEdgeThickness - client_area_top); | |
389 | |
390 canvas->DrawBitmapInt( | 380 canvas->DrawBitmapInt( |
391 *tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_RIGHT_CORNER), | 381 *tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_RIGHT_CORNER), |
392 client_area_bounds.right(), client_area_bottom); | 382 client_area_bounds.right(), client_area_bottom); |
393 SkBitmap* bottom = tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_CENTER); | 383 SkBitmap* bottom = tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_CENTER); |
394 canvas->TileImageInt(*bottom, client_area_bounds.x(), | 384 canvas->TileImageInt(*bottom, client_area_bounds.x(), |
395 client_area_bottom, client_area_bounds.width(), | 385 client_area_bottom, client_area_bounds.width(), |
396 bottom->height()); | 386 bottom->height()); |
397 SkBitmap* bottom_left = | 387 SkBitmap* bottom_left = |
398 tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_LEFT_CORNER); | 388 tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_LEFT_CORNER); |
399 canvas->DrawBitmapInt(*bottom_left, | 389 canvas->DrawBitmapInt(*bottom_left, |
400 client_area_bounds.x() - bottom_left->width(), client_area_bottom); | 390 client_area_bounds.x() - bottom_left->width(), client_area_bottom); |
401 SkBitmap* left = tp->GetBitmapNamed(IDR_CONTENT_LEFT_SIDE); | 391 SkBitmap* left = tp->GetBitmapNamed(IDR_CONTENT_LEFT_SIDE); |
402 canvas->TileImageInt(*left, client_area_bounds.x() - left->width(), | 392 canvas->TileImageInt(*left, client_area_bounds.x() - left->width(), |
403 client_area_top, left->width(), client_area_height); | 393 client_area_top, left->width(), client_area_height); |
| 394 |
| 395 // Draw the toolbar color so that the client edges show the right color even |
| 396 // where not covered by the toolbar image. NOTE: We do this after drawing the |
| 397 // images because the images are meant to alpha-blend atop the frame whereas |
| 398 // these rects are meant to be fully opaque, without anything overlaid. |
| 399 SkColor toolbar_color = tp->GetColor(BrowserThemeProvider::COLOR_TOOLBAR); |
| 400 canvas->FillRectInt(toolbar_color, |
| 401 client_area_bounds.x() - kClientEdgeThickness, client_area_top, |
| 402 kClientEdgeThickness, |
| 403 client_area_bottom + kClientEdgeThickness - client_area_top); |
| 404 canvas->FillRectInt(toolbar_color, client_area_bounds.x(), client_area_bottom, |
| 405 client_area_bounds.width(), kClientEdgeThickness); |
| 406 canvas->FillRectInt(toolbar_color, client_area_bounds.right(), |
| 407 client_area_top, kClientEdgeThickness, |
| 408 client_area_bottom + kClientEdgeThickness - client_area_top); |
404 } | 409 } |
405 | 410 |
406 void GlassBrowserFrameView::LayoutOTRAvatar() { | 411 void GlassBrowserFrameView::LayoutOTRAvatar() { |
407 int otr_x = NonClientBorderThickness() + kOTRSideSpacing; | 412 int otr_x = NonClientBorderThickness() + kOTRSideSpacing; |
408 // Move this avatar icon by the size of window controls to prevent it from | 413 // Move this avatar icon by the size of window controls to prevent it from |
409 // being rendered over them in RTL languages. This code also needs to adjust | 414 // being rendered over them in RTL languages. This code also needs to adjust |
410 // the width of a tab strip to avoid decreasing this size twice. (See the | 415 // the width of a tab strip to avoid decreasing this size twice. (See the |
411 // comment in GetBoundsForTabStrip().) | 416 // comment in GetBoundsForTabStrip().) |
412 if (base::i18n::IsRTL()) | 417 if (base::i18n::IsRTL()) |
413 otr_x += width() - frame_->GetMinimizeButtonOffset(); | 418 otr_x += width() - frame_->GetMinimizeButtonOffset(); |
414 | 419 |
415 SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); | 420 SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); |
416 int otr_height = browser_view_->IsTabStripVisible() ? | 421 int otr_bottom, otr_restored_y; |
417 otr_avatar_icon.height() : 0; | |
418 int otr_y = 0; | |
419 if (browser_view_->UseVerticalTabs()) { | 422 if (browser_view_->UseVerticalTabs()) { |
420 otr_y = NonClientTopBorderHeight() - otr_avatar_icon.height(); | 423 otr_bottom = NonClientTopBorderHeight(false, false) - kOTRBottomSpacing; |
421 } else if (browser_view_->IsTabStripVisible()) { | 424 otr_restored_y = kFrameShadowThickness; |
422 int top_height = NonClientTopBorderHeight(); | 425 } else { |
423 int tabstrip_height = | 426 otr_bottom = GetHorizontalTabStripVerticalOffset(false) + |
424 browser_view_->GetTabStripHeight() - kOTRBottomSpacing; | 427 browser_view_->GetTabStripHeight() - kOTRBottomSpacing; |
425 otr_height = frame_->GetWindow()->IsMaximized() ? | 428 otr_restored_y = otr_bottom - otr_avatar_icon.height(); |
426 (tabstrip_height - kOTRMaximizedTopSpacing) : otr_avatar_icon.height(); | |
427 otr_y = top_height + tabstrip_height - otr_height; | |
428 } | 429 } |
429 otr_avatar_bounds_.SetRect(otr_x, otr_y, otr_avatar_icon.width(), otr_height); | 430 int otr_y = frame_->GetWindow()->IsMaximized() ? |
| 431 (NonClientTopBorderHeight(false, true) + kTabstripTopShadowThickness) : |
| 432 otr_restored_y; |
| 433 otr_avatar_bounds_.SetRect(otr_x, otr_y, otr_avatar_icon.width(), |
| 434 otr_bottom - otr_y); |
430 } | 435 } |
431 | 436 |
432 void GlassBrowserFrameView::LayoutClientView() { | 437 void GlassBrowserFrameView::LayoutClientView() { |
433 client_view_bounds_ = CalculateClientAreaBounds(width(), height()); | 438 client_view_bounds_ = CalculateClientAreaBounds(width(), height()); |
434 } | 439 } |
435 | 440 |
436 gfx::Rect GlassBrowserFrameView::CalculateClientAreaBounds(int width, | 441 gfx::Rect GlassBrowserFrameView::CalculateClientAreaBounds(int width, |
437 int height) const { | 442 int height) const { |
438 if (!browser_view_->IsTabStripVisible()) | 443 if (!browser_view_->IsTabStripVisible()) |
439 return gfx::Rect(0, 0, this->width(), this->height()); | 444 return gfx::Rect(0, 0, this->width(), this->height()); |
440 | 445 |
441 int top_height = NonClientTopBorderHeight(); | 446 int top_height = NonClientTopBorderHeight(false, false); |
442 int border_thickness = NonClientBorderThickness(); | 447 int border_thickness = NonClientBorderThickness(); |
443 return gfx::Rect(border_thickness, top_height, | 448 return gfx::Rect(border_thickness, top_height, |
444 std::max(0, width - (2 * border_thickness)), | 449 std::max(0, width - (2 * border_thickness)), |
445 std::max(0, height - top_height - border_thickness)); | 450 std::max(0, height - top_height - border_thickness)); |
446 } | 451 } |
447 | 452 |
448 void GlassBrowserFrameView::StartThrobber() { | 453 void GlassBrowserFrameView::StartThrobber() { |
449 if (!throbber_running_) { | 454 if (!throbber_running_) { |
450 throbber_running_ = true; | 455 throbber_running_ = true; |
451 throbber_frame_ = 0; | 456 throbber_frame_ = 0; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 static bool initialized = false; | 501 static bool initialized = false; |
497 if (!initialized) { | 502 if (!initialized) { |
498 ResourceBundle &rb = ResourceBundle::GetSharedInstance(); | 503 ResourceBundle &rb = ResourceBundle::GetSharedInstance(); |
499 for (int i = 0; i < kThrobberIconCount; ++i) { | 504 for (int i = 0; i < kThrobberIconCount; ++i) { |
500 throbber_icons_[i] = rb.LoadThemeIcon(IDI_THROBBER_01 + i); | 505 throbber_icons_[i] = rb.LoadThemeIcon(IDI_THROBBER_01 + i); |
501 DCHECK(throbber_icons_[i]); | 506 DCHECK(throbber_icons_[i]); |
502 } | 507 } |
503 initialized = true; | 508 initialized = true; |
504 } | 509 } |
505 } | 510 } |
OLD | NEW |