| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/ui/views/frame/glass_browser_frame_view.h" | 5 #include "chrome/browser/ui/views/frame/glass_browser_frame_view.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
| 9 #include "chrome/app/chrome_command_ids.h" | 9 #include "chrome/app/chrome_command_ids.h" |
| 10 #include "chrome/app/chrome_dll_resource.h" | 10 #include "chrome/app/chrome_dll_resource.h" |
| 11 #include "chrome/browser/prefs/pref_service.h" | 11 #include "chrome/browser/prefs/pref_service.h" |
| 12 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
| 13 #include "chrome/browser/themes/theme_service.h" | 13 #include "chrome/browser/themes/theme_service.h" |
| 14 #include "chrome/browser/ui/profile_menu_model.h" | |
| 15 #include "chrome/browser/ui/views/avatar_menu_button.h" | |
| 16 #include "chrome/browser/ui/views/frame/browser_view.h" | 14 #include "chrome/browser/ui/views/frame/browser_view.h" |
| 15 #include "chrome/browser/ui/views/profile_menu_button.h" |
| 16 #include "chrome/browser/ui/views/profile_tag_view.h" |
| 17 #include "chrome/browser/ui/views/tabs/side_tab_strip.h" | 17 #include "chrome/browser/ui/views/tabs/side_tab_strip.h" |
| 18 #include "chrome/browser/ui/views/tabs/tab.h" | 18 #include "chrome/browser/ui/views/tabs/tab.h" |
| 19 #include "chrome/browser/ui/views/tabs/tab_strip.h" | 19 #include "chrome/browser/ui/views/tabs/tab_strip.h" |
| 20 #include "chrome/common/chrome_switches.h" | 20 #include "chrome/common/chrome_switches.h" |
| 21 #include "chrome/common/pref_names.h" | 21 #include "chrome/common/pref_names.h" |
| 22 #include "content/common/notification_service.h" | 22 #include "content/common/notification_service.h" |
| 23 #include "grit/app_resources.h" | 23 #include "grit/app_resources.h" |
| 24 #include "grit/generated_resources.h" | 24 #include "grit/generated_resources.h" |
| 25 #include "grit/theme_resources.h" | 25 #include "grit/theme_resources.h" |
| 26 #include "grit/theme_resources_standard.h" | 26 #include "grit/theme_resources_standard.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 39 // There are 3 px of client edge drawn inside the outer frame borders. | 39 // There are 3 px of client edge drawn inside the outer frame borders. |
| 40 const int kNonClientBorderThickness = 3; | 40 const int kNonClientBorderThickness = 3; |
| 41 // Vertical tabs have 4 px border. | 41 // Vertical tabs have 4 px border. |
| 42 const int kNonClientVerticalTabStripBorderThickness = 4; | 42 const int kNonClientVerticalTabStripBorderThickness = 4; |
| 43 // Besides the frame border, there's another 11 px of empty space atop the | 43 // Besides the frame border, there's another 11 px of empty space atop the |
| 44 // window in restored mode, to use to drag the window around. | 44 // window in restored mode, to use to drag the window around. |
| 45 const int kNonClientRestoredExtraThickness = 11; | 45 const int kNonClientRestoredExtraThickness = 11; |
| 46 // In the window corners, the resize areas don't actually expand bigger, but the | 46 // In the window corners, the resize areas don't actually expand bigger, but the |
| 47 // 16 px at the end of the top and bottom edges triggers diagonal resizing. | 47 // 16 px at the end of the top and bottom edges triggers diagonal resizing. |
| 48 const int kResizeAreaCornerSize = 16; | 48 const int kResizeAreaCornerSize = 16; |
| 49 // The avatar ends 2 px above the bottom of the tabstrip (which, given the | 49 // The OTR avatar ends 2 px above the bottom of the tabstrip (which, given the |
| 50 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the | 50 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the |
| 51 // user). | 51 // user). |
| 52 const int kAvatarBottomSpacing = 2; | 52 const int kOTRBottomSpacing = 2; |
| 53 // There are 2 px on each side of the avatar (between the frame border and | 53 // There are 2 px on each side of the OTR avatar (between the frame border and |
| 54 // it on the left, and between it and the tabstrip on the right). | 54 // it on the left, and between it and the tabstrip on the right). |
| 55 const int kAvatarSideSpacing = 2; | 55 const int kOTRSideSpacing = 2; |
| 56 // The content left/right images have a shadow built into them. | 56 // The content left/right images have a shadow built into them. |
| 57 const int kContentEdgeShadowThickness = 2; | 57 const int kContentEdgeShadowThickness = 2; |
| 58 // The top 1 px of the tabstrip is shadow; in maximized mode we push this off | 58 // The top 1 px of the tabstrip is shadow; in maximized mode we push this off |
| 59 // the top of the screen so the tabs appear flush against the screen edge. | 59 // the top of the screen so the tabs appear flush against the screen edge. |
| 60 const int kTabstripTopShadowThickness = 1; | 60 const int kTabstripTopShadowThickness = 1; |
| 61 // In restored mode, the New Tab button isn't at the same height as the caption | 61 // In restored mode, the New Tab button isn't at the same height as the caption |
| 62 // buttons, but the space will look cluttered if it actually slides under them, | 62 // buttons, but the space will look cluttered if it actually slides under them, |
| 63 // so we stop it when the gap between the two is down to 5 px. | 63 // so we stop it when the gap between the two is down to 5 px. |
| 64 const int kNewTabCaptionRestoredSpacing = 5; | 64 const int kNewTabCaptionRestoredSpacing = 5; |
| 65 // In maximized mode, where the New Tab button and the caption buttons are at | 65 // In maximized mode, where the New Tab button and the caption buttons are at |
| 66 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid | 66 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid |
| 67 // looking too cluttered. | 67 // looking too cluttered. |
| 68 const int kNewTabCaptionMaximizedSpacing = 16; | 68 const int kNewTabCaptionMaximizedSpacing = 16; |
| 69 // Y position for profile button inside the frame. |
| 70 const int kProfileButtonYPosition = 2; |
| 71 // Y position for profile tag inside the frame. |
| 72 const int kProfileTagYPosition = 1; |
| 73 // Offset y position of profile button and tag by this amount when maximized. |
| 74 const int kProfileElementMaximizedYOffset = 6; |
| 69 } | 75 } |
| 70 | 76 |
| 71 /////////////////////////////////////////////////////////////////////////////// | 77 /////////////////////////////////////////////////////////////////////////////// |
| 72 // GlassBrowserFrameView, public: | 78 // GlassBrowserFrameView, public: |
| 73 | 79 |
| 74 GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, | 80 GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, |
| 75 BrowserView* browser_view) | 81 BrowserView* browser_view) |
| 76 : BrowserNonClientFrameView(), | 82 : BrowserNonClientFrameView(), |
| 77 frame_(frame), | 83 frame_(frame), |
| 78 browser_view_(browser_view), | 84 browser_view_(browser_view), |
| 79 throbber_running_(false), | 85 throbber_running_(false), |
| 80 throbber_frame_(0) { | 86 throbber_frame_(0) { |
| 81 if (browser_view_->ShouldShowWindowIcon()) | 87 if (browser_view_->ShouldShowWindowIcon()) |
| 82 InitThrobberIcons(); | 88 InitThrobberIcons(); |
| 83 | 89 // If multi-profile is enabled set up profile button and login notifications. |
| 84 if (browser_view_->ShouldShowAvatar()) { | |
| 85 ui::MenuModel* menu_model = browser_view_->IsOffTheRecord() ? | |
| 86 NULL : new ProfileMenuModel; | |
| 87 // AvatarMenuButton takes ownership of |menu_model|. | |
| 88 avatar_button_.reset(new AvatarMenuButton(std::wstring(), menu_model)); | |
| 89 AddChildView(avatar_button_.get()); | |
| 90 | |
| 91 if (browser_view_->IsOffTheRecord()) { | |
| 92 avatar_button_->SetIcon(browser_view_->GetOTRAvatarIcon()); | |
| 93 } else { | |
| 94 // TODO(sail) Get the avatar icon assigned to this profile. | |
| 95 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | |
| 96 avatar_button_->SetIcon(*rb.GetBitmapNamed(IDR_PROFILE_AVATAR_1)); | |
| 97 // TODO(sail) Also need to call SetHoverIcon() and SetPushedIcon(). | |
| 98 } | |
| 99 } | |
| 100 | |
| 101 // If multi-profile is enabled set up login notifications. | |
| 102 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 90 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
| 103 if (browser_command_line.HasSwitch(switches::kMultiProfiles) && | 91 if (browser_command_line.HasSwitch(switches::kMultiProfiles) && |
| 104 !browser_view->IsOffTheRecord()) { | 92 !browser_view->ShouldShowOffTheRecordAvatar()) { |
| 105 RegisterLoginNotifications(); | 93 RegisterLoginNotifications(); |
| 94 profile_button_.reset(new ProfileMenuButton(std::wstring(), |
| 95 browser_view_->browser()->profile())); |
| 96 profile_button_->SetVisible(false); |
| 97 profile_tag_.reset(new ProfileTagView(frame_, profile_button_.get())); |
| 98 profile_tag_->SetVisible(false); |
| 99 AddChildView(profile_tag_.get()); |
| 100 AddChildView(profile_button_.get()); |
| 106 } | 101 } |
| 107 } | 102 } |
| 108 | 103 |
| 109 GlassBrowserFrameView::~GlassBrowserFrameView() { | 104 GlassBrowserFrameView::~GlassBrowserFrameView() { |
| 110 } | 105 } |
| 111 | 106 |
| 112 /////////////////////////////////////////////////////////////////////////////// | 107 /////////////////////////////////////////////////////////////////////////////// |
| 113 // GlassBrowserFrameView, BrowserNonClientFrameView implementation: | 108 // GlassBrowserFrameView, BrowserNonClientFrameView implementation: |
| 114 | 109 |
| 115 gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip( | 110 gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip( |
| 116 views::View* tabstrip) const { | 111 views::View* tabstrip) const { |
| 117 if (browser_view_->UseVerticalTabs()) { | 112 if (browser_view_->UseVerticalTabs()) { |
| 118 gfx::Size ps = tabstrip->GetPreferredSize(); | 113 gfx::Size ps = tabstrip->GetPreferredSize(); |
| 119 return gfx::Rect(NonClientBorderThickness(), | 114 return gfx::Rect(NonClientBorderThickness(), |
| 120 NonClientTopBorderHeight(false, false), ps.width(), | 115 NonClientTopBorderHeight(false, false), ps.width(), |
| 121 browser_view_->height()); | 116 browser_view_->height()); |
| 122 } | 117 } |
| 123 int minimize_button_offset = | 118 int minimize_button_offset = |
| 124 std::min(frame_->GetMinimizeButtonOffset(), width()); | 119 std::min(frame_->GetMinimizeButtonOffset(), width()); |
| 125 int tabstrip_x = browser_view_->ShouldShowAvatar() ? | 120 int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ? |
| 126 (avatar_bounds_.right() + kAvatarSideSpacing) : | 121 (otr_avatar_bounds_.right() + kOTRSideSpacing) : |
| 127 NonClientBorderThickness(); | 122 NonClientBorderThickness(); |
| 128 // In RTL languages, we have moved an avatar icon left by the size of window | 123 // In RTL languages, we have moved an avatar icon left by the size of window |
| 129 // controls to prevent it from being rendered over them. So, we use its x | 124 // controls to prevent it from being rendered over them. So, we use its x |
| 130 // position to move this tab strip left when maximized. Also, we can render | 125 // position to move this tab strip left when maximized. Also, we can render |
| 131 // a tab strip until the left end of this window without considering the size | 126 // a tab strip until the left end of this window without considering the size |
| 132 // of window controls in RTL languages. | 127 // of window controls in RTL languages. |
| 133 if (base::i18n::IsRTL()) { | 128 if (base::i18n::IsRTL()) { |
| 134 if (!browser_view_->ShouldShowAvatar() && frame_->IsMaximized()) | 129 if (!browser_view_->ShouldShowOffTheRecordAvatar() && frame_->IsMaximized()) |
| 135 tabstrip_x += avatar_bounds_.x(); | 130 tabstrip_x += otr_avatar_bounds_.x(); |
| 136 minimize_button_offset = width(); | 131 minimize_button_offset = width(); |
| 137 } | 132 } |
| 138 int maximized_spacing = kNewTabCaptionMaximizedSpacing; | 133 int maximized_spacing = |
| 134 kNewTabCaptionMaximizedSpacing + |
| 135 (show_profile_button() && profile_button_->IsVisible() ? |
| 136 profile_button_->GetPreferredSize().width() + |
| 137 ProfileMenuButton::kProfileTagHorizontalSpacing : 0); |
| 139 int tabstrip_width = minimize_button_offset - tabstrip_x - | 138 int tabstrip_width = minimize_button_offset - tabstrip_x - |
| 140 (frame_->IsMaximized() ? | 139 (frame_->IsMaximized() ? |
| 141 maximized_spacing : kNewTabCaptionRestoredSpacing); | 140 maximized_spacing : kNewTabCaptionRestoredSpacing); |
| 142 return gfx::Rect(tabstrip_x, GetHorizontalTabStripVerticalOffset(false), | 141 return gfx::Rect(tabstrip_x, GetHorizontalTabStripVerticalOffset(false), |
| 143 std::max(0, tabstrip_width), | 142 std::max(0, tabstrip_width), |
| 144 tabstrip->GetPreferredSize().height()); | 143 tabstrip->GetPreferredSize().height()); |
| 145 } | 144 } |
| 146 | 145 |
| 147 int GlassBrowserFrameView::GetHorizontalTabStripVerticalOffset( | 146 int GlassBrowserFrameView::GetHorizontalTabStripVerticalOffset( |
| 148 bool restored) const { | 147 bool restored) const { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 } | 190 } |
| 192 | 191 |
| 193 int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) { | 192 int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) { |
| 194 // If the browser isn't in normal mode, we haven't customized the frame, so | 193 // If the browser isn't in normal mode, we haven't customized the frame, so |
| 195 // Windows can figure this out. If the point isn't within our bounds, then | 194 // Windows can figure this out. If the point isn't within our bounds, then |
| 196 // it's in the native portion of the frame, so again Windows can figure it | 195 // it's in the native portion of the frame, so again Windows can figure it |
| 197 // out. | 196 // out. |
| 198 if (!browser_view_->IsBrowserTypeNormal() || !bounds().Contains(point)) | 197 if (!browser_view_->IsBrowserTypeNormal() || !bounds().Contains(point)) |
| 199 return HTNOWHERE; | 198 return HTNOWHERE; |
| 200 | 199 |
| 201 // See if the point is within the avatar menu button. | |
| 202 if (avatar_button_.get() && | |
| 203 avatar_button_->GetMirroredBounds().Contains(point)) | |
| 204 return HTCLIENT; | |
| 205 | |
| 206 int frame_component = frame_->client_view()->NonClientHitTest(point); | 200 int frame_component = frame_->client_view()->NonClientHitTest(point); |
| 207 | 201 |
| 208 // See if we're in the sysmenu region. We still have to check the tabstrip | 202 // See if we're in the sysmenu region. We still have to check the tabstrip |
| 209 // first so that clicks in a tab don't get treated as sysmenu clicks. | 203 // first so that clicks in a tab don't get treated as sysmenu clicks. |
| 210 int nonclient_border_thickness = NonClientBorderThickness(); | 204 int nonclient_border_thickness = NonClientBorderThickness(); |
| 211 if (gfx::Rect(nonclient_border_thickness, GetSystemMetrics(SM_CXSIZEFRAME), | 205 if (gfx::Rect(nonclient_border_thickness, GetSystemMetrics(SM_CXSIZEFRAME), |
| 212 GetSystemMetrics(SM_CXSMICON), | 206 GetSystemMetrics(SM_CXSMICON), |
| 213 GetSystemMetrics(SM_CYSMICON)).Contains(point)) | 207 GetSystemMetrics(SM_CYSMICON)).Contains(point)) |
| 214 return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; | 208 return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; |
| 215 | 209 |
| 216 if (frame_component != HTNOWHERE) | 210 if (frame_component != HTNOWHERE) |
| 217 return frame_component; | 211 return frame_component; |
| 218 | 212 |
| 213 // See if the point is within the profile menu button. |
| 214 if (show_profile_button() && profile_button_->IsVisible() && |
| 215 profile_button_->GetMirroredBounds().Contains(point)) |
| 216 return HTCLIENT; |
| 217 |
| 219 int frame_border_thickness = FrameBorderThickness(); | 218 int frame_border_thickness = FrameBorderThickness(); |
| 220 int window_component = GetHTComponentForFrame(point, frame_border_thickness, | 219 int window_component = GetHTComponentForFrame(point, frame_border_thickness, |
| 221 nonclient_border_thickness, frame_border_thickness, | 220 nonclient_border_thickness, frame_border_thickness, |
| 222 kResizeAreaCornerSize - frame_border_thickness, | 221 kResizeAreaCornerSize - frame_border_thickness, |
| 223 frame_->window_delegate()->CanResize()); | 222 frame_->window_delegate()->CanResize()); |
| 224 // Fall back to the caption if no other component matches. | 223 // Fall back to the caption if no other component matches. |
| 225 return (window_component == HTNOWHERE) ? HTCAPTION : window_component; | 224 return (window_component == HTNOWHERE) ? HTCAPTION : window_component; |
| 226 } | 225 } |
| 227 | 226 |
| 228 /////////////////////////////////////////////////////////////////////////////// | 227 /////////////////////////////////////////////////////////////////////////////// |
| 229 // GlassBrowserFrameView, views::View overrides: | 228 // GlassBrowserFrameView, views::View overrides: |
| 230 | 229 |
| 231 void GlassBrowserFrameView::OnPaint(gfx::Canvas* canvas) { | 230 void GlassBrowserFrameView::OnPaint(gfx::Canvas* canvas) { |
| 232 if (!browser_view_->IsTabStripVisible()) | 231 if (!browser_view_->IsTabStripVisible()) |
| 233 return; // Nothing is visible, so don't bother to paint. | 232 return; // Nothing is visible, so don't bother to paint. |
| 234 | 233 |
| 235 PaintToolbarBackground(canvas); | 234 PaintToolbarBackground(canvas); |
| 235 if (browser_view_->ShouldShowOffTheRecordAvatar()) |
| 236 PaintOTRAvatar(canvas); |
| 236 if (!frame_->IsMaximized()) | 237 if (!frame_->IsMaximized()) |
| 237 PaintRestoredClientEdge(canvas); | 238 PaintRestoredClientEdge(canvas); |
| 238 } | 239 } |
| 239 | 240 |
| 240 void GlassBrowserFrameView::Layout() { | 241 void GlassBrowserFrameView::Layout() { |
| 241 LayoutAvatar(); | 242 LayoutOTRAvatar(); |
| 242 LayoutClientView(); | 243 LayoutClientView(); |
| 244 LayoutProfileTag(); |
| 243 } | 245 } |
| 244 | 246 |
| 245 bool GlassBrowserFrameView::HitTest(const gfx::Point& l) const { | 247 bool GlassBrowserFrameView::HitTest(const gfx::Point& l) const { |
| 246 return (avatar_button_.get() && | 248 // The ProfileMenuButton intrudes into the client area when the window is |
| 247 avatar_button_->GetMirroredBounds().Contains(l)) || | 249 // maximized. |
| 250 return (frame_->IsMaximized() && show_profile_button() && |
| 251 profile_button_->IsVisible() && |
| 252 profile_button_->GetMirroredBounds().Contains(l)) || |
| 248 !frame_->client_view()->bounds().Contains(l); | 253 !frame_->client_view()->bounds().Contains(l); |
| 249 } | 254 } |
| 250 | 255 |
| 251 /////////////////////////////////////////////////////////////////////////////// | 256 /////////////////////////////////////////////////////////////////////////////// |
| 252 // GlassBrowserFrameView, private: | 257 // GlassBrowserFrameView, private: |
| 253 | 258 |
| 254 int GlassBrowserFrameView::FrameBorderThickness() const { | 259 int GlassBrowserFrameView::FrameBorderThickness() const { |
| 255 return (frame_->IsMaximized() || frame_->IsFullscreen()) ? | 260 return (frame_->IsMaximized() || frame_->IsFullscreen()) ? |
| 256 0 : GetSystemMetrics(SM_CXSIZEFRAME); | 261 0 : GetSystemMetrics(SM_CXSIZEFRAME); |
| 257 } | 262 } |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 canvas->DrawBitmapInt(*tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER), | 375 canvas->DrawBitmapInt(*tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER), |
| 371 right_x, y); | 376 right_x, y); |
| 372 } | 377 } |
| 373 | 378 |
| 374 // Draw the content/toolbar separator. | 379 // Draw the content/toolbar separator. |
| 375 canvas->FillRectInt(ResourceBundle::toolbar_separator_color, | 380 canvas->FillRectInt(ResourceBundle::toolbar_separator_color, |
| 376 x + kClientEdgeThickness, toolbar_bounds.bottom() - kClientEdgeThickness, | 381 x + kClientEdgeThickness, toolbar_bounds.bottom() - kClientEdgeThickness, |
| 377 w - (2 * kClientEdgeThickness), kClientEdgeThickness); | 382 w - (2 * kClientEdgeThickness), kClientEdgeThickness); |
| 378 } | 383 } |
| 379 | 384 |
| 385 void GlassBrowserFrameView::PaintOTRAvatar(gfx::Canvas* canvas) { |
| 386 // In RTL mode, the avatar icon should be looking the opposite direction. |
| 387 canvas->Save(); |
| 388 if (base::i18n::IsRTL()) { |
| 389 canvas->TranslateInt(width(), 0); |
| 390 canvas->ScaleInt(-1, 1); |
| 391 } |
| 392 |
| 393 SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); |
| 394 int w = otr_avatar_bounds_.width(); |
| 395 int h = otr_avatar_bounds_.height(); |
| 396 canvas->DrawBitmapInt(otr_avatar_icon, 0, |
| 397 // Bias the rounding to select a region that's lower rather than higher, |
| 398 // as the shadows at the image top mean the apparent center is below the |
| 399 // real center. |
| 400 ((otr_avatar_icon.height() - otr_avatar_bounds_.height()) + 1) / 2, w, h, |
| 401 otr_avatar_bounds_.x(), otr_avatar_bounds_.y(), w, h, false); |
| 402 |
| 403 canvas->Restore(); |
| 404 } |
| 405 |
| 380 void GlassBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { | 406 void GlassBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { |
| 381 ui::ThemeProvider* tp = GetThemeProvider(); | 407 ui::ThemeProvider* tp = GetThemeProvider(); |
| 382 gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height()); | 408 gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height()); |
| 383 | 409 |
| 384 // The client edges start below the toolbar upper corner images regardless | 410 // The client edges start below the toolbar upper corner images regardless |
| 385 // of how tall the toolbar itself is. | 411 // of how tall the toolbar itself is. |
| 386 int client_area_top = browser_view_->UseVerticalTabs() ? | 412 int client_area_top = browser_view_->UseVerticalTabs() ? |
| 387 client_area_bounds.y() : | 413 client_area_bounds.y() : |
| 388 (frame_->client_view()->y() + | 414 (frame_->client_view()->y() + |
| 389 browser_view_->GetToolbarBounds().y() + | 415 browser_view_->GetToolbarBounds().y() + |
| (...skipping 30 matching lines...) Expand all Loading... |
| 420 client_area_bounds.x() - kClientEdgeThickness, client_area_top, | 446 client_area_bounds.x() - kClientEdgeThickness, client_area_top, |
| 421 kClientEdgeThickness, | 447 kClientEdgeThickness, |
| 422 client_area_bottom + kClientEdgeThickness - client_area_top); | 448 client_area_bottom + kClientEdgeThickness - client_area_top); |
| 423 canvas->FillRectInt(toolbar_color, client_area_bounds.x(), client_area_bottom, | 449 canvas->FillRectInt(toolbar_color, client_area_bounds.x(), client_area_bottom, |
| 424 client_area_bounds.width(), kClientEdgeThickness); | 450 client_area_bounds.width(), kClientEdgeThickness); |
| 425 canvas->FillRectInt(toolbar_color, client_area_bounds.right(), | 451 canvas->FillRectInt(toolbar_color, client_area_bounds.right(), |
| 426 client_area_top, kClientEdgeThickness, | 452 client_area_top, kClientEdgeThickness, |
| 427 client_area_bottom + kClientEdgeThickness - client_area_top); | 453 client_area_bottom + kClientEdgeThickness - client_area_top); |
| 428 } | 454 } |
| 429 | 455 |
| 430 void GlassBrowserFrameView::LayoutAvatar() { | 456 void GlassBrowserFrameView::LayoutOTRAvatar() { |
| 431 int avatar_x = NonClientBorderThickness() + kAvatarSideSpacing; | 457 int otr_x = NonClientBorderThickness() + kOTRSideSpacing; |
| 432 // Move this avatar icon by the size of window controls to prevent it from | 458 // Move this avatar icon by the size of window controls to prevent it from |
| 433 // being rendered over them in RTL languages. This code also needs to adjust | 459 // being rendered over them in RTL languages. This code also needs to adjust |
| 434 // the width of a tab strip to avoid decreasing this size twice. (See the | 460 // the width of a tab strip to avoid decreasing this size twice. (See the |
| 435 // comment in GetBoundsForTabStrip().) | 461 // comment in GetBoundsForTabStrip().) |
| 436 if (base::i18n::IsRTL()) | 462 if (base::i18n::IsRTL()) |
| 437 avatar_x += width() - frame_->GetMinimizeButtonOffset(); | 463 otr_x += width() - frame_->GetMinimizeButtonOffset(); |
| 438 | 464 |
| 439 gfx::Size preferred_size = AvatarMenuButton::GetPreferredAvatarSize(); | 465 SkBitmap otr_avatar_icon = browser_view_->GetOTRAvatarIcon(); |
| 440 | 466 int otr_bottom, otr_restored_y; |
| 441 int avatar_bottom, avatar_restored_y; | |
| 442 if (browser_view_->UseVerticalTabs()) { | 467 if (browser_view_->UseVerticalTabs()) { |
| 443 avatar_bottom = NonClientTopBorderHeight(false, false) - | 468 otr_bottom = NonClientTopBorderHeight(false, false) - kOTRBottomSpacing; |
| 444 kAvatarBottomSpacing; | 469 otr_restored_y = kFrameShadowThickness; |
| 445 avatar_restored_y = kFrameShadowThickness; | |
| 446 } else { | 470 } else { |
| 447 avatar_bottom = GetHorizontalTabStripVerticalOffset(false) + | 471 otr_bottom = GetHorizontalTabStripVerticalOffset(false) + |
| 448 browser_view_->GetTabStripHeight() - kAvatarBottomSpacing; | 472 browser_view_->GetTabStripHeight() - kOTRBottomSpacing; |
| 449 avatar_restored_y = avatar_bottom - preferred_size.height(); | 473 otr_restored_y = otr_bottom - otr_avatar_icon.height(); |
| 450 } | 474 } |
| 451 int avatar_y = frame_->IsMaximized() ? | 475 int otr_y = frame_->IsMaximized() ? |
| 452 (NonClientTopBorderHeight(false, true) + kTabstripTopShadowThickness) : | 476 (NonClientTopBorderHeight(false, true) + kTabstripTopShadowThickness) : |
| 453 avatar_restored_y; | 477 otr_restored_y; |
| 454 avatar_bounds_.SetRect(avatar_x, avatar_y, preferred_size.width(), | 478 otr_avatar_bounds_.SetRect(otr_x, otr_y, otr_avatar_icon.width(), |
| 455 browser_view_->ShouldShowAvatar() ? (avatar_bottom - avatar_y) : 0); | 479 browser_view_->ShouldShowOffTheRecordAvatar() ? (otr_bottom - otr_y) : 0); |
| 456 | |
| 457 if (avatar_button_.get()) | |
| 458 avatar_button_->SetBoundsRect(avatar_bounds_); | |
| 459 } | 480 } |
| 460 | 481 |
| 461 void GlassBrowserFrameView::LayoutClientView() { | 482 void GlassBrowserFrameView::LayoutClientView() { |
| 462 client_view_bounds_ = CalculateClientAreaBounds(width(), height()); | 483 client_view_bounds_ = CalculateClientAreaBounds(width(), height()); |
| 463 } | 484 } |
| 464 | 485 |
| 486 void GlassBrowserFrameView::LayoutProfileTag() { |
| 487 if (!show_profile_button()) |
| 488 return; |
| 489 |
| 490 string16 profile_name = UTF8ToUTF16(browser_view_->browser()->profile()-> |
| 491 GetPrefs()->GetString(prefs::kGoogleServicesUsername)); |
| 492 if (!profile_name.empty()) { |
| 493 profile_button_->SetText(profile_name); |
| 494 profile_button_->SetTextShadowColors( |
| 495 ProfileMenuButton::kDefaultActiveTextShadow, |
| 496 ProfileMenuButton::kDefaultInactiveTextShadow); |
| 497 } else { |
| 498 profile_button_->SetText(l10n_util::GetStringUTF16( |
| 499 IDS_PROFILES_NOT_SIGNED_IN_MENU)); |
| 500 profile_button_->SetTextShadowColors( |
| 501 ProfileMenuButton::kDarkTextShadow, |
| 502 ProfileMenuButton::kDefaultInactiveTextShadow); |
| 503 } |
| 504 |
| 505 profile_button_->ClearMaxTextSize(); |
| 506 profile_button_->SetVisible(true); |
| 507 int x_tag = |
| 508 // The x position of minimize button in the frame |
| 509 frame_->GetMinimizeButtonOffset() - |
| 510 // - the space between the minimize button and the profile button |
| 511 ProfileMenuButton::kProfileTagHorizontalSpacing - |
| 512 // - the width of the profile button |
| 513 profile_button_->GetPreferredSize().width(); |
| 514 int y_maximized_offset = frame_->IsMaximized() ? |
| 515 kProfileElementMaximizedYOffset : 0; |
| 516 profile_button_->SetBounds( |
| 517 x_tag, |
| 518 kProfileButtonYPosition + y_maximized_offset, |
| 519 profile_button_->GetPreferredSize().width(), |
| 520 profile_button_->GetPreferredSize().height()); |
| 521 |
| 522 profile_tag_->SetVisible(true); |
| 523 profile_tag_->set_is_signed_in(!profile_name.empty()); |
| 524 profile_tag_->SetBounds( |
| 525 x_tag, |
| 526 kProfileTagYPosition + y_maximized_offset, |
| 527 profile_button_->GetPreferredSize().width(), |
| 528 ProfileTagView::kProfileTagHeight); |
| 529 } |
| 530 |
| 465 gfx::Rect GlassBrowserFrameView::CalculateClientAreaBounds(int width, | 531 gfx::Rect GlassBrowserFrameView::CalculateClientAreaBounds(int width, |
| 466 int height) const { | 532 int height) const { |
| 467 if (!browser_view_->IsTabStripVisible()) | 533 if (!browser_view_->IsTabStripVisible()) |
| 468 return gfx::Rect(0, 0, this->width(), this->height()); | 534 return gfx::Rect(0, 0, this->width(), this->height()); |
| 469 | 535 |
| 470 int top_height = NonClientTopBorderHeight(false, false); | 536 int top_height = NonClientTopBorderHeight(false, false); |
| 471 int border_thickness = NonClientBorderThickness(); | 537 int border_thickness = NonClientBorderThickness(); |
| 472 return gfx::Rect(border_thickness, top_height, | 538 return gfx::Rect(border_thickness, top_height, |
| 473 std::max(0, width - (2 * border_thickness)), | 539 std::max(0, width - (2 * border_thickness)), |
| 474 std::max(0, height - top_height - border_thickness)); | 540 std::max(0, height - top_height - border_thickness)); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 static_cast<WPARAM>(ICON_SMALL), | 585 static_cast<WPARAM>(ICON_SMALL), |
| 520 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); | 586 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); |
| 521 } | 587 } |
| 522 | 588 |
| 523 void GlassBrowserFrameView::Observe(NotificationType type, | 589 void GlassBrowserFrameView::Observe(NotificationType type, |
| 524 const NotificationSource& source, | 590 const NotificationSource& source, |
| 525 const NotificationDetails& details) { | 591 const NotificationDetails& details) { |
| 526 DCHECK_EQ(NotificationType::PREF_CHANGED, type.value); | 592 DCHECK_EQ(NotificationType::PREF_CHANGED, type.value); |
| 527 std::string* name = Details<std::string>(details).ptr(); | 593 std::string* name = Details<std::string>(details).ptr(); |
| 528 if (prefs::kGoogleServicesUsername == *name) | 594 if (prefs::kGoogleServicesUsername == *name) |
| 529 LayoutAvatar(); | 595 LayoutProfileTag(); |
| 530 } | 596 } |
| 531 | 597 |
| 532 void GlassBrowserFrameView::RegisterLoginNotifications() { | 598 void GlassBrowserFrameView::RegisterLoginNotifications() { |
| 533 PrefService* pref_service = browser_view_->browser()->profile()->GetPrefs(); | 599 PrefService* pref_service = browser_view_->browser()->profile()->GetPrefs(); |
| 534 DCHECK(pref_service); | 600 DCHECK(pref_service); |
| 535 username_pref_.Init(prefs::kGoogleServicesUsername, pref_service, this); | 601 username_pref_.Init(prefs::kGoogleServicesUsername, pref_service, this); |
| 536 } | 602 } |
| 537 | 603 |
| 538 // static | 604 // static |
| 539 void GlassBrowserFrameView::InitThrobberIcons() { | 605 void GlassBrowserFrameView::InitThrobberIcons() { |
| 540 static bool initialized = false; | 606 static bool initialized = false; |
| 541 if (!initialized) { | 607 if (!initialized) { |
| 542 ResourceBundle &rb = ResourceBundle::GetSharedInstance(); | 608 ResourceBundle &rb = ResourceBundle::GetSharedInstance(); |
| 543 for (int i = 0; i < kThrobberIconCount; ++i) { | 609 for (int i = 0; i < kThrobberIconCount; ++i) { |
| 544 throbber_icons_[i] = rb.LoadThemeIcon(IDI_THROBBER_01 + i); | 610 throbber_icons_[i] = rb.LoadThemeIcon(IDI_THROBBER_01 + i); |
| 545 DCHECK(throbber_icons_[i]); | 611 DCHECK(throbber_icons_[i]); |
| 546 } | 612 } |
| 547 initialized = true; | 613 initialized = true; |
| 548 } | 614 } |
| 549 } | 615 } |
| OLD | NEW |