Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(361)

Side by Side Diff: chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc

Issue 23724019: Rework OpaqueBrowserFrameViewLayout. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/opaque_browser_frame_view_layout.h" 5 #include "chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h"
6 6
7 #include "ui/gfx/font.h" 7 #include "ui/gfx/font.h"
8 #include "ui/views/controls/button/image_button.h" 8 #include "ui/views/controls/button/image_button.h"
9 #include "ui/views/controls/label.h" 9 #include "ui/views/controls/label.h"
10 10
(...skipping 29 matching lines...) Expand all
40 40
41 // The avatar ends 2 px above the bottom of the tabstrip (which, given the 41 // The avatar ends 2 px above the bottom of the tabstrip (which, given the
42 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the 42 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the
43 // user). 43 // user).
44 const int kAvatarBottomSpacing = 2; 44 const int kAvatarBottomSpacing = 2;
45 45
46 // Space between the frame border and the left edge of the avatar. 46 // Space between the frame border and the left edge of the avatar.
47 const int kAvatarLeftSpacing = 2; 47 const int kAvatarLeftSpacing = 2;
48 48
49 // Space between the right edge of the avatar and the tabstrip. 49 // Space between the right edge of the avatar and the tabstrip.
50 const int kAvatarRightSpacing = -2; 50 const int kAvatarRightSpacing = -4;
51 51
52 // In restored mode, the New Tab button isn't at the same height as the caption 52 // In restored mode, the New Tab button isn't at the same height as the caption
53 // buttons, but the space will look cluttered if it actually slides under them, 53 // buttons, but the space will look cluttered if it actually slides under them,
54 // so we stop it when the gap between the two is down to 5 px. 54 // so we stop it when the gap between the two is down to 5 px.
55 const int kNewTabCaptionRestoredSpacing = 5; 55 const int kNewTabCaptionRestoredSpacing = 5;
56 56
57 // In maximized mode, where the New Tab button and the caption buttons are at 57 // In maximized mode, where the New Tab button and the caption buttons are at
58 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid 58 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid
59 // looking too cluttered. 59 // looking too cluttered.
60 const int kNewTabCaptionMaximizedSpacing = 16; 60 const int kNewTabCaptionMaximizedSpacing = 16;
61 61
62 // The top 3 px of the tabstrip is shadow; in maximized mode we push this off 62 // The top 3 px of the tabstrip is shadow; in maximized mode we push this off
63 // the top of the screen so the tabs appear flush against the screen edge. 63 // the top of the screen so the tabs appear flush against the screen edge.
64 const int kTabstripTopShadowThickness = 3; 64 const int kTabstripTopShadowThickness = 3;
65 65
66 // How far to indent the tabstrip from the left side of the screen when there 66 // How far to indent the tabstrip from the left side of the screen when there
67 // is no avatar icon. 67 // is no avatar icon.
68 const int kTabStripIndent = -6; 68 const int kTabStripIndent = -6;
69 69
70 } // namespace 70 } // namespace
71 71
72 /////////////////////////////////////////////////////////////////////////////// 72 ///////////////////////////////////////////////////////////////////////////////
73 // OpaqueBrowserFrameView, public: 73 // OpaqueBrowserFrameView, public:
74 74
75 OpaqueBrowserFrameViewLayout::OpaqueBrowserFrameViewLayout( 75 OpaqueBrowserFrameViewLayout::OpaqueBrowserFrameViewLayout(
76 OpaqueBrowserFrameViewLayoutDelegate* delegate) 76 OpaqueBrowserFrameViewLayoutDelegate* delegate)
77 : delegate_(delegate), 77 : delegate_(delegate),
78 left_button_start_(0),
79 right_button_start_(0),
80 minimum_size_for_buttons_(0),
81 has_left_buttons_(false),
82 has_right_buttons_(false),
78 minimize_button_(NULL), 83 minimize_button_(NULL),
79 maximize_button_(NULL), 84 maximize_button_(NULL),
80 restore_button_(NULL), 85 restore_button_(NULL),
81 close_button_(NULL), 86 close_button_(NULL),
82 window_icon_(NULL), 87 window_icon_(NULL),
83 window_title_(NULL), 88 window_title_(NULL),
84 avatar_label_(NULL), 89 avatar_label_(NULL),
85 avatar_button_(NULL) { 90 avatar_button_(NULL) {
86 } 91 }
87 92
88 OpaqueBrowserFrameViewLayout::~OpaqueBrowserFrameViewLayout() {} 93 OpaqueBrowserFrameViewLayout::~OpaqueBrowserFrameViewLayout() {}
89 94
90 // static 95 // static
91 bool OpaqueBrowserFrameViewLayout::ShouldAddDefaultCaptionButtons() { 96 bool OpaqueBrowserFrameViewLayout::ShouldAddDefaultCaptionButtons() {
92 #if defined(OS_WIN) 97 #if defined(OS_WIN)
93 return !win8::IsSingleWindowMetroMode(); 98 return !win8::IsSingleWindowMetroMode();
94 #endif // OS_WIN 99 #endif // OS_WIN
95 return true; 100 return true;
96 } 101 }
97 102
98 gfx::Rect OpaqueBrowserFrameViewLayout::GetBoundsForTabStrip( 103 gfx::Rect OpaqueBrowserFrameViewLayout::GetBoundsForTabStrip(
99 const gfx::Size& tabstrip_preferred_size, 104 const gfx::Size& tabstrip_preferred_size,
100 int available_width) const { 105 int available_width) const {
101 gfx::Rect bounds = GetBoundsForTabStripAndAvatarArea( 106 available_width -= right_button_start_;
102 tabstrip_preferred_size, available_width); 107 available_width -= left_button_start_;
103 int space_left_of_tabstrip = kTabStripIndent; 108
109 if (delegate_->GetAdditionalReservedSpaceInTabStrip())
110 available_width -= delegate_->GetAdditionalReservedSpaceInTabStrip();
111
112 const int caption_spacing = delegate_->IsMaximized() ?
113 kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing;
114 const int tabstrip_width = available_width - caption_spacing;
115 gfx::Rect bounds(left_button_start_, GetTabStripInsetsTop(false),
116 std::max(0, tabstrip_width),
117 tabstrip_preferred_size.height());
118
119 int left_tabstrip_indent = kTabStripIndent;
104 if (delegate_->ShouldShowAvatar()) { 120 if (delegate_->ShouldShowAvatar()) {
105 if (avatar_label_ && avatar_label_->bounds().width()) { 121 if (avatar_label_ && avatar_label_->bounds().width()) {
106 // Space between the right edge of the avatar label and the tabstrip. 122 // Space between the right edge of the avatar label and the tabstrip.
107 const int kAvatarLabelRightSpacing = -10; 123 const int kAvatarLabelRightSpacing = -10;
108 space_left_of_tabstrip = 124 left_tabstrip_indent -= kAvatarLabelRightSpacing;
109 avatar_label_->bounds().right() + kAvatarLabelRightSpacing;
110 } else { 125 } else {
111 space_left_of_tabstrip = 126 left_tabstrip_indent -= kAvatarRightSpacing;
112 kAvatarLeftSpacing + avatar_bounds_.width() +
113 kAvatarRightSpacing;
114 } 127 }
115 } 128 }
116 bounds.Inset(space_left_of_tabstrip, 0, 0, 0); 129 bounds.Inset(left_tabstrip_indent, 0, 0, 0);
117 return bounds; 130 return bounds;
118 } 131 }
119 132
120 gfx::Rect OpaqueBrowserFrameViewLayout::GetBoundsForTabStripAndAvatarArea(
121 const gfx::Size& tabstrip_preferred_size,
122 int available_width) const {
123 if (minimize_button_) {
124 available_width = minimize_button_->x();
125 } else if (delegate_->GetAdditionalReservedSpaceInTabStrip()) {
126 available_width -= delegate_->GetAdditionalReservedSpaceInTabStrip();
127 }
128 const int caption_spacing = delegate_->IsMaximized() ?
129 kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing;
130 const int tabstrip_x = NonClientBorderThickness();
131 const int tabstrip_width = available_width - tabstrip_x - caption_spacing;
132 return gfx::Rect(tabstrip_x, GetTabStripInsetsTop(false),
133 std::max(0, tabstrip_width),
134 tabstrip_preferred_size.height());
135 }
136
137 gfx::Size OpaqueBrowserFrameViewLayout::GetMinimumSize( 133 gfx::Size OpaqueBrowserFrameViewLayout::GetMinimumSize(
138 int available_width) const { 134 int available_width) const {
139 gfx::Size min_size = delegate_->GetBrowserViewMinimumSize(); 135 gfx::Size min_size = delegate_->GetBrowserViewMinimumSize();
140 int border_thickness = NonClientBorderThickness(); 136 int border_thickness = NonClientBorderThickness();
141 min_size.Enlarge(2 * border_thickness, 137 min_size.Enlarge(2 * border_thickness,
142 NonClientTopBorderHeight(false) + border_thickness); 138 NonClientTopBorderHeight(false) + border_thickness);
143 139
144 int min_titlebar_width = (2 * FrameBorderThickness(false)) + 140 // Ensure that we can, at minimum, hold our window controls and avatar icon.
145 kIconLeftSpacing + 141 min_size.set_width(std::max(min_size.width(), minimum_size_for_buttons_));
146 (delegate_->ShouldShowWindowIcon() ?
147 (delegate_->GetIconSize() + kTitleLogoSpacing) : 0);
148 if (ShouldAddDefaultCaptionButtons()) {
149 min_titlebar_width +=
150 minimize_button_->GetMinimumSize().width() +
151 restore_button_->GetMinimumSize().width() +
152 close_button_->GetMinimumSize().width();
153 }
154 min_size.set_width(std::max(min_size.width(), min_titlebar_width));
155 142
156 // Ensure that the minimum width is enough to hold a minimum width tab strip 143 // Ensure that the minimum width is enough to hold a minimum width tab strip
157 // and avatar icon at their usual insets. 144 // at its usual insets.
158 if (delegate_->IsTabStripVisible()) { 145 if (delegate_->IsTabStripVisible()) {
159 gfx::Size preferred_size = delegate_->GetTabstripPreferredSize(); 146 gfx::Size preferred_size = delegate_->GetTabstripPreferredSize();
160 const int min_tabstrip_width = preferred_size.width(); 147 const int min_tabstrip_width = preferred_size.width();
161 const int min_tabstrip_area_width = 148 const int caption_spacing = delegate_->IsMaximized() ?
162 available_width - 149 kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing;
163 GetBoundsForTabStripAndAvatarArea( 150 min_size.Enlarge(min_tabstrip_width + caption_spacing, 0);
164 preferred_size, available_width).width() +
165 min_tabstrip_width + delegate_->GetOTRAvatarIcon().width() +
166 kAvatarLeftSpacing + kAvatarRightSpacing;
167 min_size.set_width(std::max(min_size.width(), min_tabstrip_area_width));
168 } 151 }
169 152
170 return min_size; 153 return min_size;
171 } 154 }
172 155
173 gfx::Rect OpaqueBrowserFrameViewLayout::GetWindowBoundsForClientBounds( 156 gfx::Rect OpaqueBrowserFrameViewLayout::GetWindowBoundsForClientBounds(
174 const gfx::Rect& client_bounds) const { 157 const gfx::Rect& client_bounds) const {
175 int top_height = NonClientTopBorderHeight(false); 158 int top_height = NonClientTopBorderHeight(false);
176 int border_thickness = NonClientBorderThickness(); 159 int border_thickness = NonClientBorderThickness();
177 return gfx::Rect(std::max(0, client_bounds.x() - border_thickness), 160 return gfx::Rect(std::max(0, client_bounds.x() - border_thickness),
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 205
223 int OpaqueBrowserFrameViewLayout::CaptionButtonY(bool restored) const { 206 int OpaqueBrowserFrameViewLayout::CaptionButtonY(bool restored) const {
224 // Maximized buttons start at window top so that even if their images aren't 207 // Maximized buttons start at window top so that even if their images aren't
225 // drawn flush with the screen edge, they still obey Fitts' Law. 208 // drawn flush with the screen edge, they still obey Fitts' Law.
226 return (!restored && delegate_->IsMaximized()) ? 209 return (!restored && delegate_->IsMaximized()) ?
227 FrameBorderThickness(false) : 210 FrameBorderThickness(false) :
228 views::NonClientFrameView::kFrameShadowThickness; 211 views::NonClientFrameView::kFrameShadowThickness;
229 } 212 }
230 213
231 gfx::Rect OpaqueBrowserFrameViewLayout::IconBounds() const { 214 gfx::Rect OpaqueBrowserFrameViewLayout::IconBounds() const {
232 int size = delegate_->GetIconSize(); 215 return window_icon_bounds_;
233 int frame_thickness = FrameBorderThickness(false);
234 int y;
235 if (delegate_->ShouldShowWindowIcon() ||
236 delegate_->ShouldShowWindowTitle()) {
237 // Our frame border has a different "3D look" than Windows'. Theirs has a
238 // more complex gradient on the top that they push their icon/title below;
239 // then the maximized window cuts this off and the icon/title are centered
240 // in the remaining space. Because the apparent shape of our border is
241 // simpler, using the same positioning makes things look slightly uncentered
242 // with restored windows, so when the window is restored, instead of
243 // calculating the remaining space from below the frame border, we calculate
244 // from below the 3D edge.
245 int unavailable_px_at_top = delegate_->IsMaximized() ?
246 frame_thickness : kTitlebarTopAndBottomEdgeThickness;
247 // When the icon is shorter than the minimum space we reserve for the
248 // caption button, we vertically center it. We want to bias rounding to put
249 // extra space above the icon, since the 3D edge (+ client edge, for
250 // restored windows) below looks (to the eye) more like additional space
251 // than does the 3D edge (or nothing at all, for maximized windows) above;
252 // hence the +1.
253 y = unavailable_px_at_top + (NonClientTopBorderHeight(false) -
254 unavailable_px_at_top - size - TitlebarBottomThickness(false) + 1) / 2;
255 } else {
256 // For "browser mode" windows, we use the native positioning, which is just
257 // below the top frame border.
258 y = frame_thickness;
259 }
260 return gfx::Rect(frame_thickness + kIconLeftSpacing, y, size, size);
261 } 216 }
262 217
263 gfx::Rect OpaqueBrowserFrameViewLayout::CalculateClientAreaBounds( 218 gfx::Rect OpaqueBrowserFrameViewLayout::CalculateClientAreaBounds(
264 int width, 219 int width,
265 int height) const { 220 int height) const {
266 int top_height = NonClientTopBorderHeight(false); 221 int top_height = NonClientTopBorderHeight(false);
267 int border_thickness = NonClientBorderThickness(); 222 int border_thickness = NonClientBorderThickness();
268 return gfx::Rect(border_thickness, top_height, 223 return gfx::Rect(border_thickness, top_height,
269 std::max(0, width - (2 * border_thickness)), 224 std::max(0, width - (2 * border_thickness)),
270 std::max(0, height - top_height - border_thickness)); 225 std::max(0, height - top_height - border_thickness));
271 } 226 }
272 227
273 /////////////////////////////////////////////////////////////////////////////// 228 ///////////////////////////////////////////////////////////////////////////////
274 // OpaqueBrowserFrameView, private: 229 // OpaqueBrowserFrameView, private:
275 230
276 void OpaqueBrowserFrameViewLayout::LayoutWindowControls(views::View* host) { 231 void OpaqueBrowserFrameViewLayout::LayoutWindowControls(views::View* host) {
277 if (!ShouldAddDefaultCaptionButtons()) 232 if (!ShouldAddDefaultCaptionButtons())
278 return; 233 return;
279 bool is_maximized = delegate_->IsMaximized(); 234
280 close_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, 235 // Reset the visibility of the buttons.
281 views::ImageButton::ALIGN_BOTTOM); 236 minimize_button_->SetVisible(false);
sky 2013/09/05 15:54:32 Initially making hidden and then making visible ri
Elliot Glaysher 2013/09/05 19:35:48 While I can't have ConfigureButton() control this
237 restore_button_->SetVisible(false);
238 maximize_button_->SetVisible(false);
239 close_button_->SetVisible(false);
240
241 // TODO(erg): Replace this with configurable calls in the next patch.
282 int caption_y = CaptionButtonY(false); 242 int caption_y = CaptionButtonY(false);
283 // There should always be the same number of non-shadow pixels visible to the 243 ConfigureButton(host, BUTTON_CLOSE, ALIGN_RIGHT, caption_y);
284 // side of the caption buttons. In maximized mode we extend the rightmost 244 ConfigureButton(host, BUTTON_MAXIMIZE, ALIGN_RIGHT, caption_y);
285 // button to the screen corner to obey Fitts' Law. 245 ConfigureButton(host, BUTTON_MINIMIZE, ALIGN_RIGHT, caption_y);
286 int right_extra_width = is_maximized ?
287 (kFrameBorderThickness -
288 views::NonClientFrameView::kFrameShadowThickness) : 0;
289 gfx::Size close_button_size = close_button_->GetPreferredSize();
290 close_button_->SetBounds(host->width() - FrameBorderThickness(false) -
291 right_extra_width - close_button_size.width(), caption_y,
292 close_button_size.width() + right_extra_width,
293 close_button_size.height());
294
295 // When the window is restored, we show a maximized button; otherwise, we show
296 // a restore button.
297 bool is_restored = !is_maximized && !delegate_->IsMinimized();
298 views::ImageButton* invisible_button = is_restored ?
299 restore_button_ : maximize_button_;
300 invisible_button->SetVisible(false);
301
302 views::ImageButton* visible_button = is_restored ?
303 maximize_button_ : restore_button_;
304 visible_button->SetVisible(true);
305 visible_button->SetImageAlignment(views::ImageButton::ALIGN_LEFT,
306 views::ImageButton::ALIGN_BOTTOM);
307 gfx::Size visible_button_size = visible_button->GetPreferredSize();
308 visible_button->SetBounds(close_button_->x() - visible_button_size.width(),
309 caption_y, visible_button_size.width(),
310 visible_button_size.height());
311
312 minimize_button_->SetVisible(true);
313 minimize_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT,
314 views::ImageButton::ALIGN_BOTTOM);
315 gfx::Size minimize_button_size = minimize_button_->GetPreferredSize();
316 minimize_button_->SetBounds(
317 visible_button->x() - minimize_button_size.width(), caption_y,
318 minimize_button_size.width(),
319 minimize_button_size.height());
320 } 246 }
321 247
322 void OpaqueBrowserFrameViewLayout::LayoutTitleBar() { 248 void OpaqueBrowserFrameViewLayout::LayoutTitleBar(views::View* host) {
323 gfx::Rect icon_bounds(IconBounds()); 249 bool use_hidden_icon_location = true;
324 if (delegate_->ShouldShowWindowIcon() && window_icon_) 250
325 window_icon_->SetBoundsRect(icon_bounds); 251 int size = delegate_->GetIconSize();
252 int frame_thickness = FrameBorderThickness(false);
253 bool should_show_icon = delegate_->ShouldShowWindowIcon();
254 bool should_show_title = delegate_->ShouldShowWindowTitle();
255
256 if (should_show_icon || should_show_title) {
257 use_hidden_icon_location = false;
258
259 // Our frame border has a different "3D look" than Windows'. Theirs has
260 // a more complex gradient on the top that they push their icon/title
261 // below; then the maximized window cuts this off and the icon/title are
262 // centered in the remaining space. Because the apparent shape of our
263 // border is simpler, using the same positioning makes things look
264 // slightly uncentered with restored windows, so when the window is
265 // restored, instead of calculating the remaining space from below the
266 // frame border, we calculate from below the 3D edge.
267 int unavailable_px_at_top = delegate_->IsMaximized() ?
268 frame_thickness : kTitlebarTopAndBottomEdgeThickness;
269 // When the icon is shorter than the minimum space we reserve for the
270 // caption button, we vertically center it. We want to bias rounding to
271 // put extra space above the icon, since the 3D edge (+ client edge, for
272 // restored windows) below looks (to the eye) more like additional space
273 // than does the 3D edge (or nothing at all, for maximized windows)
274 // above; hence the +1.
275 int y = unavailable_px_at_top + (NonClientTopBorderHeight(false) -
276 unavailable_px_at_top - size -
277 TitlebarBottomThickness(false) + 1) / 2;
278
279 window_icon_bounds_ = gfx::Rect(left_button_start_ + kIconLeftSpacing, y,
280 size, size);
281 left_button_start_ += size + kIconLeftSpacing;
282 minimum_size_for_buttons_ += size + kIconLeftSpacing;
283 }
284
285 if (should_show_icon)
286 window_icon_->SetBoundsRect(window_icon_bounds_);
326 287
327 if (window_title_) { 288 if (window_title_) {
328 bool should_show = delegate_->ShouldShowWindowTitle(); 289 window_title_->SetVisible(should_show_title);
329 window_title_->SetVisible(should_show); 290 if (should_show_title) {
291 window_title_->SetText(delegate_->GetWindowTitle());
330 292
331 if (should_show) { 293 int text_width = std::max(
332 window_title_->SetText(delegate_->GetWindowTitle()); 294 0, host->width() - right_button_start_ - kTitleLogoSpacing -
333 const int title_x = delegate_->ShouldShowWindowIcon() ? 295 left_button_start_ - kIconTitleSpacing);
334 icon_bounds.right() + kIconTitleSpacing : icon_bounds.x(); 296 window_title_->SetBounds(left_button_start_ + kIconTitleSpacing,
335 window_title_->SetBounds(title_x, icon_bounds.y(), 297 window_icon_bounds_.y(),
336 std::max(0, minimize_button_->x() - kTitleLogoSpacing - title_x), 298 text_width, window_icon_bounds_.height());
337 icon_bounds.height()); 299 left_button_start_ += text_width + kIconTitleSpacing;
300 }
301 }
302
303 if (use_hidden_icon_location) {
304 if (has_left_buttons_) {
305 // There are window button icons on the left. Don't size the hidden window
306 // icon that people can double click on to close the window.
307 window_icon_bounds_ = gfx::Rect();
308 } else {
309 // We set the icon bounds to a small rectangle in the top left corner if
310 // there are no icons on the left side.
311 window_icon_bounds_ = gfx::Rect(
312 frame_thickness + kIconLeftSpacing, frame_thickness, size, size);
338 } 313 }
339 } 314 }
340 } 315 }
341 316
342 void OpaqueBrowserFrameViewLayout::LayoutAvatar() { 317 void OpaqueBrowserFrameViewLayout::LayoutAvatar() {
343 // Even though the avatar is used for both incognito and profiles we always 318 // Even though the avatar is used for both incognito and profiles we always
344 // use the incognito icon to layout the avatar button. The profile icon 319 // use the incognito icon to layout the avatar button. The profile icon
345 // can be customized so we can't depend on its size to perform layout. 320 // can be customized so we can't depend on its size to perform layout.
346 gfx::ImageSkia incognito_icon = delegate_->GetOTRAvatarIcon(); 321 gfx::ImageSkia incognito_icon = delegate_->GetOTRAvatarIcon();
347 322
348 int avatar_bottom = GetTabStripInsetsTop(false) + 323 int avatar_bottom = GetTabStripInsetsTop(false) +
349 delegate_->GetTabStripHeight() - kAvatarBottomSpacing; 324 delegate_->GetTabStripHeight() - kAvatarBottomSpacing;
350 int avatar_restored_y = avatar_bottom - incognito_icon.height(); 325 int avatar_restored_y = avatar_bottom - incognito_icon.height();
351 int avatar_y = delegate_->IsMaximized() ? 326 int avatar_y = delegate_->IsMaximized() ?
352 (NonClientTopBorderHeight(false) + kTabstripTopShadowThickness) : 327 (NonClientTopBorderHeight(false) + kTabstripTopShadowThickness) :
353 avatar_restored_y; 328 avatar_restored_y;
354 avatar_bounds_.SetRect(NonClientBorderThickness() + kAvatarLeftSpacing, 329 avatar_bounds_.SetRect(left_button_start_ + kAvatarLeftSpacing,
355 avatar_y, incognito_icon.width(), 330 avatar_y, incognito_icon.width(),
356 delegate_->ShouldShowAvatar() ? (avatar_bottom - avatar_y) : 0); 331 delegate_->ShouldShowAvatar() ? (avatar_bottom - avatar_y) : 0);
357 if (avatar_button_) 332 if (avatar_button_) {
358 avatar_button_->SetBoundsRect(avatar_bounds_); 333 avatar_button_->SetBoundsRect(avatar_bounds_);
334 left_button_start_ += kAvatarLeftSpacing + incognito_icon.width();
335 minimum_size_for_buttons_ += kAvatarLeftSpacing + incognito_icon.width();
336 }
359 337
360 if (avatar_label_) { 338 if (avatar_label_) {
361 // Space between the bottom of the avatar and the bottom of the avatar 339 // Space between the bottom of the avatar and the bottom of the avatar
362 // label. 340 // label.
363 const int kAvatarLabelBottomSpacing = 3; 341 const int kAvatarLabelBottomSpacing = 3;
364 // Space between the frame border and the left edge of the avatar label. 342 // Space between the frame border and the left edge of the avatar label.
365 const int kAvatarLabelLeftSpacing = -1; 343 const int kAvatarLabelLeftSpacing = -1;
366 gfx::Size label_size = avatar_label_->GetPreferredSize(); 344 gfx::Size label_size = avatar_label_->GetPreferredSize();
367 gfx::Rect label_bounds( 345 gfx::Rect label_bounds(
368 FrameBorderThickness(false) + kAvatarLabelLeftSpacing, 346 left_button_start_ + kAvatarLabelLeftSpacing,
369 avatar_bottom - kAvatarLabelBottomSpacing - label_size.height(), 347 avatar_bottom - kAvatarLabelBottomSpacing - label_size.height(),
370 label_size.width(), 348 label_size.width(),
371 delegate_->ShouldShowAvatar() ? label_size.height() : 0); 349 delegate_->ShouldShowAvatar() ? label_size.height() : 0);
372 avatar_label_->SetBoundsRect(label_bounds); 350 avatar_label_->SetBoundsRect(label_bounds);
351 left_button_start_ += kAvatarLabelLeftSpacing + label_size.width();
373 } 352 }
374 } 353 }
375 354
355 void OpaqueBrowserFrameViewLayout::ConfigureButton(
356 views::View* host,
357 ButtonID button_id,
358 ButtonAlignment alignment,
359 int caption_y) {
360 if (button_id == BUTTON_MINIMIZE) {
361 minimize_button_->SetVisible(true);
362 SetBoundsForButton(host, minimize_button_, alignment, caption_y);
363 } else if (button_id == BUTTON_MAXIMIZE) {
364 // When the window is restored, we show a maximized button; otherwise, we
365 // show a restore button.
366 bool is_restored = !delegate_->IsMaximized() && !delegate_->IsMinimized();
367 views::ImageButton* invisible_button = is_restored ?
368 restore_button_ : maximize_button_;
369 invisible_button->SetVisible(false);
370
371 views::ImageButton* visible_button = is_restored ?
372 maximize_button_ : restore_button_;
373 visible_button->SetVisible(true);
374 SetBoundsForButton(host, visible_button, alignment, caption_y);
375 } else if (button_id == BUTTON_CLOSE) {
376 close_button_->SetVisible(true);
377 SetBoundsForButton(host, close_button_, alignment, caption_y);
378 }
379 }
sky 2013/09/05 15:54:32 else NOTREACHED? Although I would likely just use
380
381 void OpaqueBrowserFrameViewLayout::SetBoundsForButton(
382 views::View* host,
383 views::ImageButton* button,
384 ButtonAlignment alignment,
385 int caption_y) {
386 gfx::Size button_size = button->GetPreferredSize();
387
388 button->SetImageAlignment(
389 (alignment == ALIGN_LEFT) ?
390 views::ImageButton::ALIGN_RIGHT : views::ImageButton::ALIGN_LEFT,
391 views::ImageButton::ALIGN_BOTTOM);
392
393 // There should always be the same number of non-shadow pixels visible to the
394 // side of the caption buttons. In maximized mode we extend the rightmost
395 // button to the screen corner to obey Fitts' Law.
396 bool is_maximized = delegate_->IsMaximized();
397
398 if (alignment == ALIGN_LEFT) {
399 button->SetBounds(
400 left_button_start_,
401 caption_y,
402 button_size.width(),
403 button_size.height());
Elliot Glaysher 2013/09/05 00:49:30 The whole left alignment case here does work, but
404
405 left_button_start_ += button_size.width();
406 minimum_size_for_buttons_ += button_size.width();
407 has_left_buttons_ = true;
408 } else {
409 // If we're the first button on the right and maximized, add with to the
410 // right hand side of the screen.
411 int extra_width = (is_maximized && !has_right_buttons_) ?
412 (kFrameBorderThickness -
413 views::NonClientFrameView::kFrameShadowThickness) : 0;
414
415 button->SetBounds(
416 host->width() - right_button_start_ - extra_width - button_size.width(),
417 caption_y,
418 button_size.width() + extra_width,
419 button_size.height());
420
421 right_button_start_ += extra_width + button_size.width();
422 minimum_size_for_buttons_ += extra_width + button_size.width();
423 has_right_buttons_ = true;
424 }
425 }
426
376 void OpaqueBrowserFrameViewLayout::SetView(int id, views::View* view) { 427 void OpaqueBrowserFrameViewLayout::SetView(int id, views::View* view) {
377 // Why do things this way instead of having an Init() method, where we're 428 // Why do things this way instead of having an Init() method, where we're
378 // passed the views we'll handle? Because OpaqueBrowserFrameView doesn't own 429 // passed the views we'll handle? Because OpaqueBrowserFrameView doesn't own
379 // all the views which are part of it. The avatar stuff, for example, will be 430 // all the views which are part of it. The avatar stuff, for example, will be
380 // added and removed by the base class of OpaqueBrowserFrameView. 431 // added and removed by the base class of OpaqueBrowserFrameView.
381 switch (id) { 432 switch (id) {
382 case VIEW_ID_MINIMIZE_BUTTON: 433 case VIEW_ID_MINIMIZE_BUTTON:
383 if (view) { 434 if (view) {
384 DCHECK_EQ(std::string(views::ImageButton::kViewClassName), 435 DCHECK_EQ(std::string(views::ImageButton::kViewClassName),
385 view->GetClassName()); 436 view->GetClassName());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 default: 477 default:
427 NOTIMPLEMENTED() << "Unknown view id " << id; 478 NOTIMPLEMENTED() << "Unknown view id " << id;
428 break; 479 break;
429 } 480 }
430 } 481 }
431 482
432 /////////////////////////////////////////////////////////////////////////////// 483 ///////////////////////////////////////////////////////////////////////////////
433 // OpaqueBrowserFrameView, views::LayoutManager: 484 // OpaqueBrowserFrameView, views::LayoutManager:
434 485
435 void OpaqueBrowserFrameViewLayout::Layout(views::View* host) { 486 void OpaqueBrowserFrameViewLayout::Layout(views::View* host) {
487 // Reset all our data so that everything is invisible.
488 int thickness = FrameBorderThickness(false);
489 left_button_start_ = thickness;
490 right_button_start_ = thickness;
491 minimum_size_for_buttons_ = left_button_start_ + right_button_start_;
492 has_left_buttons_ = false;
493 has_right_buttons_ = false;
494
436 LayoutWindowControls(host); 495 LayoutWindowControls(host);
437 LayoutTitleBar(); 496 LayoutTitleBar(host);
497
498 // We now add a single pixel to the left spacing. We do this because the
499 // avatar and tab strip start one pixel inward compared to where things start
500 // on the right side.
501 left_button_start_++;
502
438 LayoutAvatar(); 503 LayoutAvatar();
439 504
440 client_view_bounds_ = CalculateClientAreaBounds( 505 client_view_bounds_ = CalculateClientAreaBounds(
441 host->width(), host->height()); 506 host->width(), host->height());
442 } 507 }
443 508
444 gfx::Size OpaqueBrowserFrameViewLayout::GetPreferredSize(views::View* host) { 509 gfx::Size OpaqueBrowserFrameViewLayout::GetPreferredSize(views::View* host) {
445 // This is never used; NonClientView::GetPreferredSize() will be called 510 // This is never used; NonClientView::GetPreferredSize() will be called
446 // instead. 511 // instead.
447 NOTREACHED(); 512 NOTREACHED();
448 return gfx::Size(); 513 return gfx::Size();
449 } 514 }
450 515
451 void OpaqueBrowserFrameViewLayout::ViewAdded(views::View* host, 516 void OpaqueBrowserFrameViewLayout::ViewAdded(views::View* host,
452 views::View* view) { 517 views::View* view) {
453 SetView(view->id(), view); 518 SetView(view->id(), view);
454 } 519 }
455 520
456 void OpaqueBrowserFrameViewLayout::ViewRemoved(views::View* host, 521 void OpaqueBrowserFrameViewLayout::ViewRemoved(views::View* host,
457 views::View* view) { 522 views::View* view) {
458 SetView(view->id(), NULL); 523 SetView(view->id(), NULL);
459 } 524 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698