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

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: sky fixes 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 leading_button_start_(0),
79 trailing_button_start_(0),
80 minimum_size_for_buttons_(0),
81 has_leading_buttons_(false),
82 has_trailing_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) {
91 trailing_buttons_.push_back(BUTTON_MINIMIZE);
92 trailing_buttons_.push_back(BUTTON_MAXIMIZE);
93 trailing_buttons_.push_back(BUTTON_CLOSE);
86 } 94 }
87 95
88 OpaqueBrowserFrameViewLayout::~OpaqueBrowserFrameViewLayout() {} 96 OpaqueBrowserFrameViewLayout::~OpaqueBrowserFrameViewLayout() {}
89 97
90 // static 98 // static
91 bool OpaqueBrowserFrameViewLayout::ShouldAddDefaultCaptionButtons() { 99 bool OpaqueBrowserFrameViewLayout::ShouldAddDefaultCaptionButtons() {
92 #if defined(OS_WIN) 100 #if defined(OS_WIN)
93 return !win8::IsSingleWindowMetroMode(); 101 return !win8::IsSingleWindowMetroMode();
94 #endif // OS_WIN 102 #endif // OS_WIN
95 return true; 103 return true;
96 } 104 }
97 105
98 gfx::Rect OpaqueBrowserFrameViewLayout::GetBoundsForTabStrip( 106 gfx::Rect OpaqueBrowserFrameViewLayout::GetBoundsForTabStrip(
99 const gfx::Size& tabstrip_preferred_size, 107 const gfx::Size& tabstrip_preferred_size,
100 int available_width) const { 108 int available_width) const {
101 gfx::Rect bounds = GetBoundsForTabStripAndAvatarArea( 109 available_width -= trailing_button_start_;
102 tabstrip_preferred_size, available_width); 110 available_width -= leading_button_start_;
103 int space_left_of_tabstrip = kTabStripIndent; 111
112 if (delegate_->GetAdditionalReservedSpaceInTabStrip())
113 available_width -= delegate_->GetAdditionalReservedSpaceInTabStrip();
114
115 const int caption_spacing = delegate_->IsMaximized() ?
116 kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing;
117 const int tabstrip_width = available_width - caption_spacing;
118 gfx::Rect bounds(leading_button_start_, GetTabStripInsetsTop(false),
119 std::max(0, tabstrip_width),
120 tabstrip_preferred_size.height());
121
122 int leading_tabstrip_indent = kTabStripIndent;
104 if (delegate_->ShouldShowAvatar()) { 123 if (delegate_->ShouldShowAvatar()) {
105 if (avatar_label_ && avatar_label_->bounds().width()) { 124 if (avatar_label_ && avatar_label_->bounds().width()) {
106 // Space between the right edge of the avatar label and the tabstrip. 125 // Space between the trailing edge of the avatar label and the tabstrip.
107 const int kAvatarLabelRightSpacing = -10; 126 const int kAvatarLabelRightSpacing = -10;
108 space_left_of_tabstrip = 127 leading_tabstrip_indent -= kAvatarLabelRightSpacing;
109 avatar_label_->bounds().right() + kAvatarLabelRightSpacing;
110 } else { 128 } else {
111 space_left_of_tabstrip = 129 leading_tabstrip_indent -= kAvatarRightSpacing;
112 kAvatarLeftSpacing + avatar_bounds_.width() +
113 kAvatarRightSpacing;
114 } 130 }
115 } 131 }
116 bounds.Inset(space_left_of_tabstrip, 0, 0, 0); 132 bounds.Inset(leading_tabstrip_indent, 0, 0, 0);
117 return bounds; 133 return bounds;
118 } 134 }
119 135
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( 136 gfx::Size OpaqueBrowserFrameViewLayout::GetMinimumSize(
138 int available_width) const { 137 int available_width) const {
139 gfx::Size min_size = delegate_->GetBrowserViewMinimumSize(); 138 gfx::Size min_size = delegate_->GetBrowserViewMinimumSize();
140 int border_thickness = NonClientBorderThickness(); 139 int border_thickness = NonClientBorderThickness();
141 min_size.Enlarge(2 * border_thickness, 140 min_size.Enlarge(2 * border_thickness,
142 NonClientTopBorderHeight(false) + border_thickness); 141 NonClientTopBorderHeight(false) + border_thickness);
143 142
144 int min_titlebar_width = (2 * FrameBorderThickness(false)) + 143 // Ensure that we can, at minimum, hold our window controls and avatar icon.
145 kIconLeftSpacing + 144 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 145
156 // Ensure that the minimum width is enough to hold a minimum width tab strip 146 // Ensure that the minimum width is enough to hold a minimum width tab strip
157 // and avatar icon at their usual insets. 147 // at its usual insets.
158 if (delegate_->IsTabStripVisible()) { 148 if (delegate_->IsTabStripVisible()) {
159 gfx::Size preferred_size = delegate_->GetTabstripPreferredSize(); 149 gfx::Size preferred_size = delegate_->GetTabstripPreferredSize();
160 const int min_tabstrip_width = preferred_size.width(); 150 const int min_tabstrip_width = preferred_size.width();
161 const int min_tabstrip_area_width = 151 const int caption_spacing = delegate_->IsMaximized() ?
162 available_width - 152 kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing;
163 GetBoundsForTabStripAndAvatarArea( 153 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 } 154 }
169 155
170 return min_size; 156 return min_size;
171 } 157 }
172 158
173 gfx::Rect OpaqueBrowserFrameViewLayout::GetWindowBoundsForClientBounds( 159 gfx::Rect OpaqueBrowserFrameViewLayout::GetWindowBoundsForClientBounds(
174 const gfx::Rect& client_bounds) const { 160 const gfx::Rect& client_bounds) const {
175 int top_height = NonClientTopBorderHeight(false); 161 int top_height = NonClientTopBorderHeight(false);
176 int border_thickness = NonClientBorderThickness(); 162 int border_thickness = NonClientBorderThickness();
177 return gfx::Rect(std::max(0, client_bounds.x() - border_thickness), 163 return gfx::Rect(std::max(0, client_bounds.x() - border_thickness),
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 208
223 int OpaqueBrowserFrameViewLayout::CaptionButtonY(bool restored) const { 209 int OpaqueBrowserFrameViewLayout::CaptionButtonY(bool restored) const {
224 // Maximized buttons start at window top so that even if their images aren't 210 // 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. 211 // drawn flush with the screen edge, they still obey Fitts' Law.
226 return (!restored && delegate_->IsMaximized()) ? 212 return (!restored && delegate_->IsMaximized()) ?
227 FrameBorderThickness(false) : 213 FrameBorderThickness(false) :
228 views::NonClientFrameView::kFrameShadowThickness; 214 views::NonClientFrameView::kFrameShadowThickness;
229 } 215 }
230 216
231 gfx::Rect OpaqueBrowserFrameViewLayout::IconBounds() const { 217 gfx::Rect OpaqueBrowserFrameViewLayout::IconBounds() const {
232 int size = delegate_->GetIconSize(); 218 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 } 219 }
262 220
263 gfx::Rect OpaqueBrowserFrameViewLayout::CalculateClientAreaBounds( 221 gfx::Rect OpaqueBrowserFrameViewLayout::CalculateClientAreaBounds(
264 int width, 222 int width,
265 int height) const { 223 int height) const {
266 int top_height = NonClientTopBorderHeight(false); 224 int top_height = NonClientTopBorderHeight(false);
267 int border_thickness = NonClientBorderThickness(); 225 int border_thickness = NonClientBorderThickness();
268 return gfx::Rect(border_thickness, top_height, 226 return gfx::Rect(border_thickness, top_height,
269 std::max(0, width - (2 * border_thickness)), 227 std::max(0, width - (2 * border_thickness)),
270 std::max(0, height - top_height - border_thickness)); 228 std::max(0, height - top_height - border_thickness));
271 } 229 }
272 230
273 /////////////////////////////////////////////////////////////////////////////// 231 ///////////////////////////////////////////////////////////////////////////////
274 // OpaqueBrowserFrameView, private: 232 // OpaqueBrowserFrameView, private:
275 233
276 void OpaqueBrowserFrameViewLayout::LayoutWindowControls(views::View* host) { 234 void OpaqueBrowserFrameViewLayout::LayoutWindowControls(views::View* host) {
277 if (!ShouldAddDefaultCaptionButtons()) 235 if (!ShouldAddDefaultCaptionButtons())
278 return; 236 return;
279 bool is_maximized = delegate_->IsMaximized(); 237
280 close_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT,
281 views::ImageButton::ALIGN_BOTTOM);
282 int caption_y = CaptionButtonY(false); 238 int caption_y = CaptionButtonY(false);
283 // There should always be the same number of non-shadow pixels visible to the
284 // side of the caption buttons. In maximized mode we extend the rightmost
285 // button to the screen corner to obey Fitts' Law.
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 239
295 // When the window is restored, we show a maximized button; otherwise, we show 240 // Keep a list of all buttons that we don't show.
296 // a restore button. 241 std::vector<ButtonID> buttons_not_shown;
297 bool is_restored = !is_maximized && !delegate_->IsMinimized(); 242 buttons_not_shown.push_back(BUTTON_MAXIMIZE);
298 views::ImageButton* invisible_button = is_restored ? 243 buttons_not_shown.push_back(BUTTON_MINIMIZE);
299 restore_button_ : maximize_button_; 244 buttons_not_shown.push_back(BUTTON_CLOSE);
300 invisible_button->SetVisible(false);
301 245
302 views::ImageButton* visible_button = is_restored ? 246 for (std::vector<ButtonID>::const_iterator it = leading_buttons_.begin();
303 maximize_button_ : restore_button_; 247 it != leading_buttons_.end(); ++it) {
304 visible_button->SetVisible(true); 248 ConfigureButton(host, *it, ALIGN_LEADING, caption_y);
305 visible_button->SetImageAlignment(views::ImageButton::ALIGN_LEFT, 249 buttons_not_shown.erase(
306 views::ImageButton::ALIGN_BOTTOM); 250 std::remove(buttons_not_shown.begin(), buttons_not_shown.end(), *it),
307 gfx::Size visible_button_size = visible_button->GetPreferredSize(); 251 buttons_not_shown.end());
308 visible_button->SetBounds(close_button_->x() - visible_button_size.width(), 252 }
309 caption_y, visible_button_size.width(),
310 visible_button_size.height());
311 253
312 minimize_button_->SetVisible(true); 254 for (std::vector<ButtonID>::const_reverse_iterator it =
313 minimize_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, 255 trailing_buttons_.rbegin(); it != trailing_buttons_.rend(); ++it) {
314 views::ImageButton::ALIGN_BOTTOM); 256 ConfigureButton(host, *it, ALIGN_TRAILING, caption_y);
315 gfx::Size minimize_button_size = minimize_button_->GetPreferredSize(); 257 buttons_not_shown.erase(
316 minimize_button_->SetBounds( 258 std::remove(buttons_not_shown.begin(), buttons_not_shown.end(), *it),
317 visible_button->x() - minimize_button_size.width(), caption_y, 259 buttons_not_shown.end());
318 minimize_button_size.width(), 260 }
319 minimize_button_size.height()); 261
262 for (std::vector<ButtonID>::const_iterator it = buttons_not_shown.begin();
263 it != buttons_not_shown.end(); ++it) {
264 HideButton(*it);
265 }
320 } 266 }
321 267
322 void OpaqueBrowserFrameViewLayout::LayoutTitleBar() { 268 void OpaqueBrowserFrameViewLayout::LayoutTitleBar(views::View* host) {
323 gfx::Rect icon_bounds(IconBounds()); 269 bool use_hidden_icon_location = true;
324 if (delegate_->ShouldShowWindowIcon() && window_icon_) 270
325 window_icon_->SetBoundsRect(icon_bounds); 271 int size = delegate_->GetIconSize();
272 int frame_thickness = FrameBorderThickness(false);
273 bool should_show_icon = delegate_->ShouldShowWindowIcon();
274 bool should_show_title = delegate_->ShouldShowWindowTitle();
275
276 if (should_show_icon || should_show_title) {
277 use_hidden_icon_location = false;
278
279 // Our frame border has a different "3D look" than Windows'. Theirs has
280 // a more complex gradient on the top that they push their icon/title
281 // below; then the maximized window cuts this off and the icon/title are
282 // centered in the remaining space. Because the apparent shape of our
283 // border is simpler, using the same positioning makes things look
284 // slightly uncentered with restored windows, so when the window is
285 // restored, instead of calculating the remaining space from below the
286 // frame border, we calculate from below the 3D edge.
287 int unavailable_px_at_top = delegate_->IsMaximized() ?
288 frame_thickness : kTitlebarTopAndBottomEdgeThickness;
289 // When the icon is shorter than the minimum space we reserve for the
290 // caption button, we vertically center it. We want to bias rounding to
291 // put extra space above the icon, since the 3D edge (+ client edge, for
292 // restored windows) below looks (to the eye) more like additional space
293 // than does the 3D edge (or nothing at all, for maximized windows)
294 // above; hence the +1.
295 int y = unavailable_px_at_top + (NonClientTopBorderHeight(false) -
296 unavailable_px_at_top - size -
297 TitlebarBottomThickness(false) + 1) / 2;
298
299 window_icon_bounds_ = gfx::Rect(leading_button_start_ + kIconLeftSpacing, y,
300 size, size);
301 leading_button_start_ += size + kIconLeftSpacing;
302 minimum_size_for_buttons_ += size + kIconLeftSpacing;
303 }
304
305 if (should_show_icon)
306 window_icon_->SetBoundsRect(window_icon_bounds_);
326 307
327 if (window_title_) { 308 if (window_title_) {
328 bool should_show = delegate_->ShouldShowWindowTitle(); 309 window_title_->SetVisible(should_show_title);
329 window_title_->SetVisible(should_show); 310 if (should_show_title) {
311 window_title_->SetText(delegate_->GetWindowTitle());
330 312
331 if (should_show) { 313 int text_width = std::max(
332 window_title_->SetText(delegate_->GetWindowTitle()); 314 0, host->width() - trailing_button_start_ - kTitleLogoSpacing -
333 const int title_x = delegate_->ShouldShowWindowIcon() ? 315 leading_button_start_ - kIconTitleSpacing);
334 icon_bounds.right() + kIconTitleSpacing : icon_bounds.x(); 316 window_title_->SetBounds(leading_button_start_ + kIconTitleSpacing,
335 window_title_->SetBounds(title_x, icon_bounds.y(), 317 window_icon_bounds_.y(),
336 std::max(0, minimize_button_->x() - kTitleLogoSpacing - title_x), 318 text_width, window_icon_bounds_.height());
337 icon_bounds.height()); 319 leading_button_start_ += text_width + kIconTitleSpacing;
320 }
321 }
322
323 if (use_hidden_icon_location) {
324 if (has_leading_buttons_) {
325 // There are window button icons on the left. Don't size the hidden window
326 // icon that people can double click on to close the window.
327 window_icon_bounds_ = gfx::Rect();
328 } else {
329 // We set the icon bounds to a small rectangle in the top leading corner
330 // if there are no icons on the leading side.
331 window_icon_bounds_ = gfx::Rect(
332 frame_thickness + kIconLeftSpacing, frame_thickness, size, size);
338 } 333 }
339 } 334 }
340 } 335 }
341 336
342 void OpaqueBrowserFrameViewLayout::LayoutAvatar() { 337 void OpaqueBrowserFrameViewLayout::LayoutAvatar() {
343 // Even though the avatar is used for both incognito and profiles we always 338 // 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 339 // 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. 340 // can be customized so we can't depend on its size to perform layout.
346 gfx::ImageSkia incognito_icon = delegate_->GetOTRAvatarIcon(); 341 gfx::ImageSkia incognito_icon = delegate_->GetOTRAvatarIcon();
347 342
348 int avatar_bottom = GetTabStripInsetsTop(false) + 343 int avatar_bottom = GetTabStripInsetsTop(false) +
349 delegate_->GetTabStripHeight() - kAvatarBottomSpacing; 344 delegate_->GetTabStripHeight() - kAvatarBottomSpacing;
350 int avatar_restored_y = avatar_bottom - incognito_icon.height(); 345 int avatar_restored_y = avatar_bottom - incognito_icon.height();
351 int avatar_y = delegate_->IsMaximized() ? 346 int avatar_y = delegate_->IsMaximized() ?
352 (NonClientTopBorderHeight(false) + kTabstripTopShadowThickness) : 347 (NonClientTopBorderHeight(false) + kTabstripTopShadowThickness) :
353 avatar_restored_y; 348 avatar_restored_y;
354 avatar_bounds_.SetRect(NonClientBorderThickness() + kAvatarLeftSpacing, 349 avatar_bounds_.SetRect(leading_button_start_ + kAvatarLeftSpacing,
355 avatar_y, incognito_icon.width(), 350 avatar_y, incognito_icon.width(),
356 delegate_->ShouldShowAvatar() ? (avatar_bottom - avatar_y) : 0); 351 delegate_->ShouldShowAvatar() ? (avatar_bottom - avatar_y) : 0);
357 if (avatar_button_) 352 if (avatar_button_) {
358 avatar_button_->SetBoundsRect(avatar_bounds_); 353 avatar_button_->SetBoundsRect(avatar_bounds_);
354 leading_button_start_ += kAvatarLeftSpacing + incognito_icon.width();
355 minimum_size_for_buttons_ += kAvatarLeftSpacing + incognito_icon.width();
356 }
359 357
360 if (avatar_label_) { 358 if (avatar_label_) {
361 // Space between the bottom of the avatar and the bottom of the avatar 359 // Space between the bottom of the avatar and the bottom of the avatar
362 // label. 360 // label.
363 const int kAvatarLabelBottomSpacing = 3; 361 const int kAvatarLabelBottomSpacing = 3;
364 // Space between the frame border and the left edge of the avatar label. 362 // Space between the frame border and the left edge of the avatar label.
365 const int kAvatarLabelLeftSpacing = -1; 363 const int kAvatarLabelLeftSpacing = -1;
366 gfx::Size label_size = avatar_label_->GetPreferredSize(); 364 gfx::Size label_size = avatar_label_->GetPreferredSize();
367 gfx::Rect label_bounds( 365 gfx::Rect label_bounds(
368 FrameBorderThickness(false) + kAvatarLabelLeftSpacing, 366 leading_button_start_ + kAvatarLabelLeftSpacing,
369 avatar_bottom - kAvatarLabelBottomSpacing - label_size.height(), 367 avatar_bottom - kAvatarLabelBottomSpacing - label_size.height(),
370 label_size.width(), 368 label_size.width(),
371 delegate_->ShouldShowAvatar() ? label_size.height() : 0); 369 delegate_->ShouldShowAvatar() ? label_size.height() : 0);
372 avatar_label_->SetBoundsRect(label_bounds); 370 avatar_label_->SetBoundsRect(label_bounds);
371 leading_button_start_ += kAvatarLabelLeftSpacing + label_size.width();
373 } 372 }
374 } 373 }
375 374
375 void OpaqueBrowserFrameViewLayout::ConfigureButton(
376 views::View* host,
377 ButtonID button_id,
378 ButtonAlignment alignment,
379 int caption_y) {
380 switch (button_id) {
381 case BUTTON_MINIMIZE: {
382 minimize_button_->SetVisible(true);
383 SetBoundsForButton(host, minimize_button_, alignment, caption_y);
384 break;
385 }
386 case BUTTON_MAXIMIZE: {
387 // When the window is restored, we show a maximized button; otherwise, we
388 // show a restore button.
389 bool is_restored = !delegate_->IsMaximized() && !delegate_->IsMinimized();
390 views::ImageButton* invisible_button = is_restored ?
391 restore_button_ : maximize_button_;
392 invisible_button->SetVisible(false);
393
394 views::ImageButton* visible_button = is_restored ?
395 maximize_button_ : restore_button_;
396 visible_button->SetVisible(true);
397 SetBoundsForButton(host, visible_button, alignment, caption_y);
398 break;
399 }
400 case BUTTON_CLOSE: {
401 close_button_->SetVisible(true);
402 SetBoundsForButton(host, close_button_, alignment, caption_y);
403 break;
404 }
405 }
406 }
407
408 void OpaqueBrowserFrameViewLayout::HideButton(ButtonID button_id) {
409 switch (button_id) {
410 case BUTTON_MINIMIZE:
411 minimize_button_->SetVisible(false);
412 break;
413 case BUTTON_MAXIMIZE:
414 restore_button_->SetVisible(false);
415 maximize_button_->SetVisible(false);
416 break;
417 case BUTTON_CLOSE:
418 close_button_->SetVisible(false);
419 break;
420 }
421 }
422
423 void OpaqueBrowserFrameViewLayout::SetBoundsForButton(
424 views::View* host,
425 views::ImageButton* button,
426 ButtonAlignment alignment,
427 int caption_y) {
428 gfx::Size button_size = button->GetPreferredSize();
429
430 button->SetImageAlignment(
431 (alignment == ALIGN_LEADING) ?
432 views::ImageButton::ALIGN_RIGHT : views::ImageButton::ALIGN_LEFT,
433 views::ImageButton::ALIGN_BOTTOM);
434
435 // There should always be the same number of non-shadow pixels visible to the
436 // side of the caption buttons. In maximized mode we extend the rightmost
437 // button to the screen corner to obey Fitts' Law.
438 bool is_maximized = delegate_->IsMaximized();
439
440 switch (alignment) {
441 case ALIGN_LEADING: {
442 // TODO(erg): This works well enough as a basic case, but needs to be
443 // expanded for Linux. Inter-button spacing, for example. Also, extending
444 // the leading edge of the first button all the way to the leading edge.
445 button->SetBounds(
446 leading_button_start_,
447 caption_y,
448 button_size.width(),
449 button_size.height());
450
451 leading_button_start_ += button_size.width();
452 minimum_size_for_buttons_ += button_size.width();
453 has_leading_buttons_ = true;
454 break;
455 }
456 case ALIGN_TRAILING: {
457 // If we're the first button on the right and maximized, add with to the
458 // right hand side of the screen.
459 int extra_width = (is_maximized && !has_trailing_buttons_) ?
460 (kFrameBorderThickness -
461 views::NonClientFrameView::kFrameShadowThickness) : 0;
462
463 button->SetBounds(
464 host->width() - trailing_button_start_ - extra_width -
465 button_size.width(),
466 caption_y,
467 button_size.width() + extra_width,
468 button_size.height());
469
470 trailing_button_start_ += extra_width + button_size.width();
471 minimum_size_for_buttons_ += extra_width + button_size.width();
472 has_trailing_buttons_ = true;
473 break;
474 }
475 }
476 }
477
376 void OpaqueBrowserFrameViewLayout::SetView(int id, views::View* view) { 478 void OpaqueBrowserFrameViewLayout::SetView(int id, views::View* view) {
377 // Why do things this way instead of having an Init() method, where we're 479 // 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 480 // 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 481 // 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. 482 // added and removed by the base class of OpaqueBrowserFrameView.
381 switch (id) { 483 switch (id) {
382 case VIEW_ID_MINIMIZE_BUTTON: 484 case VIEW_ID_MINIMIZE_BUTTON:
383 if (view) { 485 if (view) {
384 DCHECK_EQ(std::string(views::ImageButton::kViewClassName), 486 DCHECK_EQ(std::string(views::ImageButton::kViewClassName),
385 view->GetClassName()); 487 view->GetClassName());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 default: 528 default:
427 NOTIMPLEMENTED() << "Unknown view id " << id; 529 NOTIMPLEMENTED() << "Unknown view id " << id;
428 break; 530 break;
429 } 531 }
430 } 532 }
431 533
432 /////////////////////////////////////////////////////////////////////////////// 534 ///////////////////////////////////////////////////////////////////////////////
433 // OpaqueBrowserFrameView, views::LayoutManager: 535 // OpaqueBrowserFrameView, views::LayoutManager:
434 536
435 void OpaqueBrowserFrameViewLayout::Layout(views::View* host) { 537 void OpaqueBrowserFrameViewLayout::Layout(views::View* host) {
538 // Reset all our data so that everything is invisible.
539 int thickness = FrameBorderThickness(false);
540 leading_button_start_ = thickness;
541 trailing_button_start_ = thickness;
542 minimum_size_for_buttons_ = leading_button_start_ + trailing_button_start_;
543 has_leading_buttons_ = false;
544 has_trailing_buttons_ = false;
545
436 LayoutWindowControls(host); 546 LayoutWindowControls(host);
437 LayoutTitleBar(); 547 LayoutTitleBar(host);
548
549 // We now add a single pixel to the leading spacing. We do this because the
550 // avatar and tab strip start one pixel inward compared to where things start
551 // on the trailing side.
552 leading_button_start_++;
553
438 LayoutAvatar(); 554 LayoutAvatar();
439 555
440 client_view_bounds_ = CalculateClientAreaBounds( 556 client_view_bounds_ = CalculateClientAreaBounds(
441 host->width(), host->height()); 557 host->width(), host->height());
442 } 558 }
443 559
444 gfx::Size OpaqueBrowserFrameViewLayout::GetPreferredSize(views::View* host) { 560 gfx::Size OpaqueBrowserFrameViewLayout::GetPreferredSize(views::View* host) {
445 // This is never used; NonClientView::GetPreferredSize() will be called 561 // This is never used; NonClientView::GetPreferredSize() will be called
446 // instead. 562 // instead.
447 NOTREACHED(); 563 NOTREACHED();
448 return gfx::Size(); 564 return gfx::Size();
449 } 565 }
450 566
451 void OpaqueBrowserFrameViewLayout::ViewAdded(views::View* host, 567 void OpaqueBrowserFrameViewLayout::ViewAdded(views::View* host,
452 views::View* view) { 568 views::View* view) {
453 SetView(view->id(), view); 569 SetView(view->id(), view);
454 } 570 }
455 571
456 void OpaqueBrowserFrameViewLayout::ViewRemoved(views::View* host, 572 void OpaqueBrowserFrameViewLayout::ViewRemoved(views::View* host,
457 views::View* view) { 573 views::View* view) {
458 SetView(view->id(), NULL); 574 SetView(view->id(), NULL);
459 } 575 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698