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

Side by Side Diff: views/window/custom_frame_view.cc

Issue 8552005: views: Move views/window/ to ui/views/window directory. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 1 month 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
« no previous file with comments | « views/window/custom_frame_view.h ('k') | views/window/dialog_client_view.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "views/window/custom_frame_view.h"
6
7 #include <algorithm>
8
9 #include "base/utf_string_conversions.h"
10 #include "grit/ui_resources.h"
11 #include "grit/ui_strings.h"
12 #include "ui/base/hit_test.h"
13 #include "ui/base/l10n/l10n_util.h"
14 #include "ui/base/resource/resource_bundle.h"
15 #include "ui/gfx/canvas.h"
16 #include "ui/gfx/font.h"
17 #include "ui/gfx/path.h"
18 #include "views/widget/widget_delegate.h"
19 #include "views/window/client_view.h"
20 #include "views/window/window_resources.h"
21 #include "views/window/window_shape.h"
22
23 #if defined(USE_AURA)
24 #include "views/widget/native_widget_aura.h"
25 #elif defined(OS_WIN)
26 #include "views/widget/native_widget_win.h"
27 #endif
28
29 namespace views {
30
31 // static
32 gfx::Font* CustomFrameView::title_font_ = NULL;
33
34 namespace {
35 // The frame border is only visible in restored mode and is hardcoded to 4 px on
36 // each side regardless of the system window border size.
37 const int kFrameBorderThickness = 4;
38 // Various edges of the frame border have a 1 px shadow along their edges; in a
39 // few cases we shift elements based on this amount for visual appeal.
40 const int kFrameShadowThickness = 1;
41 // While resize areas on Windows are normally the same size as the window
42 // borders, our top area is shrunk by 1 px to make it easier to move the window
43 // around with our thinner top grabbable strip. (Incidentally, our side and
44 // bottom resize areas don't match the frame border thickness either -- they
45 // span the whole nonclient area, so there's no "dead zone" for the mouse.)
46 const int kTopResizeAdjust = 1;
47 // In the window corners, the resize areas don't actually expand bigger, but the
48 // 16 px at the end of each edge triggers diagonal resizing.
49 const int kResizeAreaCornerSize = 16;
50 // The titlebar never shrinks too short to show the caption button plus some
51 // padding below it.
52 const int kCaptionButtonHeightWithPadding = 19;
53 // The titlebar has a 2 px 3D edge along the top and bottom.
54 const int kTitlebarTopAndBottomEdgeThickness = 2;
55 // The icon is inset 2 px from the left frame border.
56 const int kIconLeftSpacing = 2;
57 // The icon never shrinks below 16 px on a side.
58 const int kIconMinimumSize = 16;
59 // There is a 4 px gap between the icon and the title text.
60 const int kIconTitleSpacing = 4;
61 // There is a 5 px gap between the title text and the caption buttons.
62 const int kTitleCaptionSpacing = 5;
63 }
64
65 ///////////////////////////////////////////////////////////////////////////////
66 // CustomFrameView, public:
67
68 CustomFrameView::CustomFrameView(Widget* frame)
69 : ALLOW_THIS_IN_INITIALIZER_LIST(close_button_(new ImageButton(this))),
70 ALLOW_THIS_IN_INITIALIZER_LIST(restore_button_(new ImageButton(this))),
71 ALLOW_THIS_IN_INITIALIZER_LIST(maximize_button_(new ImageButton(this))),
72 ALLOW_THIS_IN_INITIALIZER_LIST(minimize_button_(new ImageButton(this))),
73 window_icon_(NULL),
74 should_show_minmax_buttons_(false),
75 should_show_client_edge_(false),
76 frame_(frame) {
77 InitClass();
78
79 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
80
81 close_button_->SetAccessibleName(
82 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE));
83
84 // Close button images will be set in LayoutWindowControls().
85 AddChildView(close_button_);
86
87 restore_button_->SetAccessibleName(
88 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_RESTORE));
89 restore_button_->SetImage(CustomButton::BS_NORMAL,
90 rb.GetBitmapNamed(IDR_RESTORE));
91 restore_button_->SetImage(CustomButton::BS_HOT,
92 rb.GetBitmapNamed(IDR_RESTORE_H));
93 restore_button_->SetImage(CustomButton::BS_PUSHED,
94 rb.GetBitmapNamed(IDR_RESTORE_P));
95 AddChildView(restore_button_);
96
97 maximize_button_->SetAccessibleName(
98 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE));
99 maximize_button_->SetImage(CustomButton::BS_NORMAL,
100 rb.GetBitmapNamed(IDR_MAXIMIZE));
101 maximize_button_->SetImage(CustomButton::BS_HOT,
102 rb.GetBitmapNamed(IDR_MAXIMIZE_H));
103 maximize_button_->SetImage(CustomButton::BS_PUSHED,
104 rb.GetBitmapNamed(IDR_MAXIMIZE_P));
105 AddChildView(maximize_button_);
106
107 minimize_button_->SetAccessibleName(
108 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MINIMIZE));
109 minimize_button_->SetImage(CustomButton::BS_NORMAL,
110 rb.GetBitmapNamed(IDR_MINIMIZE));
111 minimize_button_->SetImage(CustomButton::BS_HOT,
112 rb.GetBitmapNamed(IDR_MINIMIZE_H));
113 minimize_button_->SetImage(CustomButton::BS_PUSHED,
114 rb.GetBitmapNamed(IDR_MINIMIZE_P));
115 AddChildView(minimize_button_);
116
117 should_show_minmax_buttons_ = frame_->widget_delegate()->CanMaximize();
118 should_show_client_edge_ = frame_->widget_delegate()->ShouldShowClientEdge();
119
120 if (frame_->widget_delegate()->ShouldShowWindowIcon()) {
121 window_icon_ = new ImageButton(this);
122 AddChildView(window_icon_);
123 }
124 }
125
126 CustomFrameView::~CustomFrameView() {
127 }
128
129 ///////////////////////////////////////////////////////////////////////////////
130 // CustomFrameView, NonClientFrameView implementation:
131
132 gfx::Rect CustomFrameView::GetBoundsForClientView() const {
133 return client_view_bounds_;
134 }
135
136 gfx::Rect CustomFrameView::GetWindowBoundsForClientBounds(
137 const gfx::Rect& client_bounds) const {
138 int top_height = NonClientTopBorderHeight();
139 int border_thickness = NonClientBorderThickness();
140 return gfx::Rect(std::max(0, client_bounds.x() - border_thickness),
141 std::max(0, client_bounds.y() - top_height),
142 client_bounds.width() + (2 * border_thickness),
143 client_bounds.height() + top_height + border_thickness);
144 }
145
146 int CustomFrameView::NonClientHitTest(const gfx::Point& point) {
147 // Sanity check.
148 if (!bounds().Contains(point))
149 return HTNOWHERE;
150
151 int frame_component = frame_->client_view()->NonClientHitTest(point);
152
153 // See if we're in the sysmenu region. (We check the ClientView first to be
154 // consistent with OpaqueBrowserFrameView; it's not really necessary here.)
155 gfx::Rect sysmenu_rect(IconBounds());
156 // In maximized mode we extend the rect to the screen corner to take advantage
157 // of Fitts' Law.
158 if (frame_->IsMaximized())
159 sysmenu_rect.SetRect(0, 0, sysmenu_rect.right(), sysmenu_rect.bottom());
160 sysmenu_rect.set_x(GetMirroredXForRect(sysmenu_rect));
161 if (sysmenu_rect.Contains(point))
162 return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU;
163
164 if (frame_component != HTNOWHERE)
165 return frame_component;
166
167 // Then see if the point is within any of the window controls.
168 if (close_button_->GetMirroredBounds().Contains(point))
169 return HTCLOSE;
170 if (restore_button_->GetMirroredBounds().Contains(point))
171 return HTMAXBUTTON;
172 if (maximize_button_->GetMirroredBounds().Contains(point))
173 return HTMAXBUTTON;
174 if (minimize_button_->GetMirroredBounds().Contains(point))
175 return HTMINBUTTON;
176 if (window_icon_ && window_icon_->GetMirroredBounds().Contains(point))
177 return HTSYSMENU;
178
179 int window_component = GetHTComponentForFrame(point, FrameBorderThickness(),
180 NonClientBorderThickness(), kResizeAreaCornerSize, kResizeAreaCornerSize,
181 frame_->widget_delegate()->CanResize());
182 // Fall back to the caption if no other component matches.
183 return (window_component == HTNOWHERE) ? HTCAPTION : window_component;
184 }
185
186 void CustomFrameView::GetWindowMask(const gfx::Size& size,
187 gfx::Path* window_mask) {
188 DCHECK(window_mask);
189 if (frame_->IsMaximized())
190 return;
191
192 views::GetDefaultWindowMask(size, window_mask);
193 }
194
195 void CustomFrameView::EnableClose(bool enable) {
196 close_button_->SetEnabled(enable);
197 }
198
199 void CustomFrameView::ResetWindowControls() {
200 restore_button_->SetState(CustomButton::BS_NORMAL);
201 minimize_button_->SetState(CustomButton::BS_NORMAL);
202 maximize_button_->SetState(CustomButton::BS_NORMAL);
203 // The close button isn't affected by this constraint.
204 }
205
206 void CustomFrameView::UpdateWindowIcon() {
207 window_icon_->SchedulePaint();
208 }
209
210 ///////////////////////////////////////////////////////////////////////////////
211 // CustomFrameView, View overrides:
212
213 void CustomFrameView::OnPaint(gfx::Canvas* canvas) {
214 if (frame_->IsMaximized())
215 PaintMaximizedFrameBorder(canvas);
216 else
217 PaintRestoredFrameBorder(canvas);
218 PaintTitleBar(canvas);
219 if (ShouldShowClientEdge())
220 PaintRestoredClientEdge(canvas);
221 }
222
223 void CustomFrameView::Layout() {
224 LayoutWindowControls();
225 LayoutTitleBar();
226 LayoutClientView();
227 }
228
229 gfx::Size CustomFrameView::GetPreferredSize() {
230 gfx::Size pref = frame_->client_view()->GetPreferredSize();
231 gfx::Rect bounds(0, 0, pref.width(), pref.height());
232 return frame_->non_client_view()->GetWindowBoundsForClientBounds(
233 bounds).size();
234 }
235
236 ///////////////////////////////////////////////////////////////////////////////
237 // CustomFrameView, ButtonListener implementation:
238
239 void CustomFrameView::ButtonPressed(Button* sender, const views::Event& event) {
240 if (sender == close_button_)
241 frame_->Close();
242 else if (sender == minimize_button_)
243 frame_->Minimize();
244 else if (sender == maximize_button_)
245 frame_->Maximize();
246 else if (sender == restore_button_)
247 frame_->Restore();
248 }
249
250 ///////////////////////////////////////////////////////////////////////////////
251 // CustomFrameView, private:
252
253 int CustomFrameView::FrameBorderThickness() const {
254 return frame_->IsMaximized() ? 0 : kFrameBorderThickness;
255 }
256
257 int CustomFrameView::NonClientBorderThickness() const {
258 // In maximized mode, we don't show a client edge.
259 return FrameBorderThickness() +
260 (ShouldShowClientEdge() ? kClientEdgeThickness : 0);
261 }
262
263 int CustomFrameView::NonClientTopBorderHeight() const {
264 return std::max(FrameBorderThickness() + IconSize(),
265 CaptionButtonY() + kCaptionButtonHeightWithPadding) +
266 TitlebarBottomThickness();
267 }
268
269 int CustomFrameView::CaptionButtonY() const {
270 // Maximized buttons start at window top so that even if their images aren't
271 // drawn flush with the screen edge, they still obey Fitts' Law.
272 return frame_->IsMaximized() ? FrameBorderThickness() : kFrameShadowThickness;
273 }
274
275 int CustomFrameView::TitlebarBottomThickness() const {
276 return kTitlebarTopAndBottomEdgeThickness +
277 (ShouldShowClientEdge() ? kClientEdgeThickness : 0);
278 }
279
280 int CustomFrameView::IconSize() const {
281 #if defined(OS_WIN)
282 // This metric scales up if either the titlebar height or the titlebar font
283 // size are increased.
284 return GetSystemMetrics(SM_CYSMICON);
285 #else
286 return std::max(title_font_->GetHeight(), kIconMinimumSize);
287 #endif
288 }
289
290 bool CustomFrameView::ShouldShowClientEdge() const {
291 return should_show_client_edge_ && !frame_->IsMaximized();
292 }
293
294 gfx::Rect CustomFrameView::IconBounds() const {
295 int size = IconSize();
296 int frame_thickness = FrameBorderThickness();
297 // Our frame border has a different "3D look" than Windows'. Theirs has a
298 // more complex gradient on the top that they push their icon/title below;
299 // then the maximized window cuts this off and the icon/title are centered
300 // in the remaining space. Because the apparent shape of our border is
301 // simpler, using the same positioning makes things look slightly uncentered
302 // with restored windows, so when the window is restored, instead of
303 // calculating the remaining space from below the frame border, we calculate
304 // from below the 3D edge.
305 int unavailable_px_at_top = frame_->IsMaximized() ?
306 frame_thickness : kTitlebarTopAndBottomEdgeThickness;
307 // When the icon is shorter than the minimum space we reserve for the caption
308 // button, we vertically center it. We want to bias rounding to put extra
309 // space above the icon, since the 3D edge (+ client edge, for restored
310 // windows) below looks (to the eye) more like additional space than does the
311 // 3D edge (or nothing at all, for maximized windows) above; hence the +1.
312 int y = unavailable_px_at_top + (NonClientTopBorderHeight() -
313 unavailable_px_at_top - size - TitlebarBottomThickness() + 1) / 2;
314 return gfx::Rect(frame_thickness + kIconLeftSpacing, y, size, size);
315 }
316
317 void CustomFrameView::PaintRestoredFrameBorder(gfx::Canvas* canvas) {
318 // Window frame mode.
319 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
320
321 SkBitmap* frame_image;
322 SkColor frame_color;
323 if (frame_->IsActive()) {
324 frame_image = rb.GetBitmapNamed(IDR_FRAME);
325 frame_color = ResourceBundle::frame_color;
326 } else {
327 frame_image = rb.GetBitmapNamed(IDR_FRAME_INACTIVE);
328 frame_color = ResourceBundle::frame_color_inactive;
329 }
330
331 SkBitmap* top_left_corner = rb.GetBitmapNamed(IDR_WINDOW_TOP_LEFT_CORNER);
332 SkBitmap* top_right_corner =
333 rb.GetBitmapNamed(IDR_WINDOW_TOP_RIGHT_CORNER);
334 SkBitmap* top_edge = rb.GetBitmapNamed(IDR_WINDOW_TOP_CENTER);
335 SkBitmap* right_edge = rb.GetBitmapNamed(IDR_WINDOW_RIGHT_SIDE);
336 SkBitmap* left_edge = rb.GetBitmapNamed(IDR_WINDOW_LEFT_SIDE);
337 SkBitmap* bottom_left_corner =
338 rb.GetBitmapNamed(IDR_WINDOW_BOTTOM_LEFT_CORNER);
339 SkBitmap* bottom_right_corner =
340 rb.GetBitmapNamed(IDR_WINDOW_BOTTOM_RIGHT_CORNER);
341 SkBitmap* bottom_edge = rb.GetBitmapNamed(IDR_WINDOW_BOTTOM_CENTER);
342
343 // Fill with the frame color first so we have a constant background for
344 // areas not covered by the theme image.
345 canvas->FillRect(frame_color,
346 gfx::Rect(0, 0, width(), frame_image->height()));
347
348 int remaining_height = height() - frame_image->height();
349 if (remaining_height > 0) {
350 // Now fill down the sides.
351 canvas->FillRect(frame_color,
352 gfx::Rect(0, frame_image->height(), left_edge->width(),
353 remaining_height));
354 canvas->FillRect(frame_color,
355 gfx::Rect(width() - right_edge->width(),
356 frame_image->height(), right_edge->width(),
357 remaining_height));
358 int center_width = width() - left_edge->width() - right_edge->width();
359 if (center_width > 0) {
360 // Now fill the bottom area.
361 canvas->FillRect(frame_color,
362 gfx::Rect(left_edge->width(),
363 height() - bottom_edge->height(),
364 center_width, bottom_edge->height()));
365 }
366 }
367
368 // Draw the theme frame.
369 canvas->TileImageInt(*frame_image, 0, 0, width(), frame_image->height());
370
371 // Top.
372 canvas->DrawBitmapInt(*top_left_corner, 0, 0);
373 canvas->TileImageInt(*top_edge, top_left_corner->width(), 0,
374 width() - top_right_corner->width(), top_edge->height());
375 canvas->DrawBitmapInt(*top_right_corner,
376 width() - top_right_corner->width(), 0);
377
378 // Right.
379 canvas->TileImageInt(*right_edge, width() - right_edge->width(),
380 top_right_corner->height(), right_edge->width(),
381 height() - top_right_corner->height() - bottom_right_corner->height());
382
383 // Bottom.
384 canvas->DrawBitmapInt(*bottom_right_corner,
385 width() - bottom_right_corner->width(),
386 height() - bottom_right_corner->height());
387 canvas->TileImageInt(*bottom_edge, bottom_left_corner->width(),
388 height() - bottom_edge->height(),
389 width() - bottom_left_corner->width() - bottom_right_corner->width(),
390 bottom_edge->height());
391 canvas->DrawBitmapInt(*bottom_left_corner, 0,
392 height() - bottom_left_corner->height());
393
394 // Left.
395 canvas->TileImageInt(*left_edge, 0, top_left_corner->height(),
396 left_edge->width(),
397 height() - top_left_corner->height() - bottom_left_corner->height());
398 }
399
400 void CustomFrameView::PaintMaximizedFrameBorder(gfx::Canvas* canvas) {
401 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
402
403 SkBitmap* frame_image = rb.GetBitmapNamed(frame_->IsActive() ?
404 IDR_FRAME : IDR_FRAME_INACTIVE);
405 canvas->TileImageInt(*frame_image, 0, FrameBorderThickness(), width(),
406 frame_image->height());
407
408 // The bottom of the titlebar actually comes from the top of the Client Edge
409 // graphic, with the actual client edge clipped off the bottom.
410 SkBitmap* titlebar_bottom = rb.GetBitmapNamed(IDR_APP_TOP_CENTER);
411 int edge_height = titlebar_bottom->height() -
412 (ShouldShowClientEdge() ? kClientEdgeThickness : 0);
413 canvas->TileImageInt(*titlebar_bottom, 0,
414 frame_->client_view()->y() - edge_height, width(), edge_height);
415 }
416
417 void CustomFrameView::PaintTitleBar(gfx::Canvas* canvas) {
418 WidgetDelegate* d = frame_->widget_delegate();
419
420 // It seems like in some conditions we can be asked to paint after the window
421 // that contains us is WM_DESTROYed. At this point, our delegate is NULL. The
422 // correct long term fix may be to shut down the RootView in WM_DESTROY.
423 if (!d)
424 return;
425
426 canvas->DrawStringInt(d->GetWindowTitle(), *title_font_,
427 SK_ColorWHITE, GetMirroredXForRect(title_bounds_),
428 title_bounds_.y(), title_bounds_.width(),
429 title_bounds_.height());
430 }
431
432 void CustomFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) {
433 gfx::Rect client_area_bounds = frame_->client_view()->bounds();
434 int client_area_top = client_area_bounds.y();
435
436 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
437 SkBitmap* top_left = rb.GetBitmapNamed(IDR_APP_TOP_LEFT);
438 SkBitmap* top = rb.GetBitmapNamed(IDR_APP_TOP_CENTER);
439 SkBitmap* top_right = rb.GetBitmapNamed(IDR_APP_TOP_RIGHT);
440 SkBitmap* right = rb.GetBitmapNamed(IDR_CONTENT_RIGHT_SIDE);
441 SkBitmap* bottom_right =
442 rb.GetBitmapNamed(IDR_CONTENT_BOTTOM_RIGHT_CORNER);
443 SkBitmap* bottom = rb.GetBitmapNamed(IDR_CONTENT_BOTTOM_CENTER);
444 SkBitmap* bottom_left =
445 rb.GetBitmapNamed(IDR_CONTENT_BOTTOM_LEFT_CORNER);
446 SkBitmap* left = rb.GetBitmapNamed(IDR_CONTENT_LEFT_SIDE);
447
448 // Top.
449 int top_edge_y = client_area_top - top->height();
450 canvas->DrawBitmapInt(*top_left, client_area_bounds.x() - top_left->width(),
451 top_edge_y);
452 canvas->TileImageInt(*top, client_area_bounds.x(), top_edge_y,
453 client_area_bounds.width(), top->height());
454 canvas->DrawBitmapInt(*top_right, client_area_bounds.right(), top_edge_y);
455
456 // Right.
457 int client_area_bottom =
458 std::max(client_area_top, client_area_bounds.bottom());
459 int client_area_height = client_area_bottom - client_area_top;
460 canvas->TileImageInt(*right, client_area_bounds.right(), client_area_top,
461 right->width(), client_area_height);
462
463 // Bottom.
464 canvas->DrawBitmapInt(*bottom_right, client_area_bounds.right(),
465 client_area_bottom);
466 canvas->TileImageInt(*bottom, client_area_bounds.x(), client_area_bottom,
467 client_area_bounds.width(), bottom_right->height());
468 canvas->DrawBitmapInt(*bottom_left,
469 client_area_bounds.x() - bottom_left->width(), client_area_bottom);
470
471 // Left.
472 canvas->TileImageInt(*left, client_area_bounds.x() - left->width(),
473 client_area_top, left->width(), client_area_height);
474
475 // Draw the toolbar color to fill in the edges.
476 canvas->DrawRectInt(ResourceBundle::toolbar_color,
477 client_area_bounds.x() - 1, client_area_top - 1,
478 client_area_bounds.width() + 1, client_area_bottom - client_area_top + 1);
479 }
480
481 void CustomFrameView::LayoutWindowControls() {
482 close_button_->SetImageAlignment(ImageButton::ALIGN_LEFT,
483 ImageButton::ALIGN_BOTTOM);
484 int caption_y = CaptionButtonY();
485 bool is_maximized = frame_->IsMaximized();
486 // There should always be the same number of non-shadow pixels visible to the
487 // side of the caption buttons. In maximized mode we extend the rightmost
488 // button to the screen corner to obey Fitts' Law.
489 int right_extra_width = is_maximized ?
490 (kFrameBorderThickness - kFrameShadowThickness) : 0;
491 gfx::Size close_button_size = close_button_->GetPreferredSize();
492 close_button_->SetBounds(width() - FrameBorderThickness() -
493 right_extra_width - close_button_size.width(), caption_y,
494 close_button_size.width() + right_extra_width,
495 close_button_size.height());
496
497 // When the window is restored, we show a maximized button; otherwise, we show
498 // a restore button.
499 bool is_restored = !is_maximized && !frame_->IsMinimized();
500 views::ImageButton* invisible_button = is_restored ?
501 restore_button_ : maximize_button_;
502 invisible_button->SetVisible(false);
503
504 views::ImageButton* visible_button = is_restored ?
505 maximize_button_ : restore_button_;
506 FramePartBitmap normal_part, hot_part, pushed_part;
507 if (should_show_minmax_buttons_) {
508 visible_button->SetVisible(true);
509 visible_button->SetImageAlignment(ImageButton::ALIGN_LEFT,
510 ImageButton::ALIGN_BOTTOM);
511 gfx::Size visible_button_size = visible_button->GetPreferredSize();
512 visible_button->SetBounds(close_button_->x() - visible_button_size.width(),
513 caption_y, visible_button_size.width(),
514 visible_button_size.height());
515
516 minimize_button_->SetVisible(true);
517 minimize_button_->SetImageAlignment(ImageButton::ALIGN_LEFT,
518 ImageButton::ALIGN_BOTTOM);
519 gfx::Size minimize_button_size = minimize_button_->GetPreferredSize();
520 minimize_button_->SetBounds(
521 visible_button->x() - minimize_button_size.width(), caption_y,
522 minimize_button_size.width(),
523 minimize_button_size.height());
524
525 normal_part = IDR_CLOSE;
526 hot_part = IDR_CLOSE_H;
527 pushed_part = IDR_CLOSE_P;
528 } else {
529 visible_button->SetVisible(false);
530 minimize_button_->SetVisible(false);
531
532 normal_part = IDR_CLOSE_SA;
533 hot_part = IDR_CLOSE_SA_H;
534 pushed_part = IDR_CLOSE_SA_P;
535 }
536
537 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
538
539 close_button_->SetImage(CustomButton::BS_NORMAL,
540 rb.GetBitmapNamed(normal_part));
541 close_button_->SetImage(CustomButton::BS_HOT,
542 rb.GetBitmapNamed(hot_part));
543 close_button_->SetImage(CustomButton::BS_PUSHED,
544 rb.GetBitmapNamed(pushed_part));
545 }
546
547 void CustomFrameView::LayoutTitleBar() {
548 // The window title is based on the calculated icon position, even when there
549 // is no icon.
550 gfx::Rect icon_bounds(IconBounds());
551 if (frame_->widget_delegate()->ShouldShowWindowIcon())
552 window_icon_->SetBoundsRect(icon_bounds);
553
554 // Size the title.
555 int title_x = frame_->widget_delegate()->ShouldShowWindowIcon() ?
556 icon_bounds.right() + kIconTitleSpacing : icon_bounds.x();
557 int title_height = title_font_->GetHeight();
558 // We bias the title position so that when the difference between the icon and
559 // title heights is odd, the extra pixel of the title is above the vertical
560 // midline rather than below. This compensates for how the icon is already
561 // biased downwards (see IconBounds()) and helps prevent descenders on the
562 // title from overlapping the 3D edge at the bottom of the titlebar.
563 title_bounds_.SetRect(title_x,
564 icon_bounds.y() + ((icon_bounds.height() - title_height - 1) / 2),
565 std::max(0, (should_show_minmax_buttons_ ?
566 minimize_button_->x() : close_button_->x()) - kTitleCaptionSpacing -
567 title_x), title_height);
568 }
569
570 void CustomFrameView::LayoutClientView() {
571 int top_height = NonClientTopBorderHeight();
572 int border_thickness = NonClientBorderThickness();
573 client_view_bounds_.SetRect(border_thickness, top_height,
574 std::max(0, width() - (2 * border_thickness)),
575 std::max(0, height() - top_height - border_thickness));
576 }
577
578 // static
579 void CustomFrameView::InitClass() {
580 static bool initialized = false;
581 if (!initialized) {
582 #if defined(USE_AURA)
583 title_font_ = new gfx::Font(NativeWidgetAura::GetWindowTitleFont());
584 #elif defined(OS_WIN)
585 title_font_ = new gfx::Font(NativeWidgetWin::GetWindowTitleFont());
586 #elif defined(OS_LINUX)
587 // TODO(ben): need to resolve what font this is.
588 title_font_ = new gfx::Font();
589 #endif
590 initialized = true;
591 }
592 }
593
594 } // namespace views
OLDNEW
« no previous file with comments | « views/window/custom_frame_view.h ('k') | views/window/dialog_client_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698