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

Side by Side Diff: chrome/browser/ui/views/panels/panel_frame_view.cc

Issue 2263863002: Remove implementation of Panels on OSes other than ChromeOS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: CR feedback Created 4 years, 4 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
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "chrome/browser/ui/views/panels/panel_frame_view.h"
6
7 #include "build/build_config.h"
8 #include "chrome/browser/ui/panels/panel.h"
9 #include "chrome/browser/ui/panels/panel_constants.h"
10 #include "chrome/browser/ui/views/panels/panel_view.h"
11 #include "chrome/browser/ui/views/tab_icon_view.h"
12 #include "chrome/grit/generated_resources.h"
13 #include "content/public/browser/web_contents.h"
14 #include "grit/theme_resources.h"
15 #include "ui/base/hit_test.h"
16 #include "ui/base/l10n/l10n_util.h"
17 #include "ui/base/resource/resource_bundle.h"
18 #include "ui/display/screen.h"
19 #include "ui/gfx/canvas.h"
20 #include "ui/gfx/font_list.h"
21 #include "ui/gfx/path.h"
22 #include "ui/resources/grit/ui_resources.h"
23 #include "ui/views/controls/button/image_button.h"
24 #include "ui/views/controls/label.h"
25 #include "ui/views/resources/grit/views_resources.h"
26 #include "ui/views/widget/widget.h"
27 #include "ui/views/widget/widget_delegate.h"
28
29 #if defined(USE_AURA)
30 #include "ui/aura/window.h"
31 #endif
32
33 #if defined(OS_WIN)
34 #include "base/win/scoped_gdi_object.h"
35 #include "ui/base/win/shell.h"
36 #include "ui/gfx/path_win.h"
37 #include "ui/views/win/hwnd_util.h"
38 #endif
39
40 namespace {
41
42 // The thickness of the border when Aero is not enabled. In this case, the
43 // shadow around the window will not be painted by the system and we need to
44 // paint a frame in order to differentiate the client area from the background.
45 const int kNonAeroBorderThickness = 1;
46
47 // The height and width in pixels of the icon.
48 const int kIconSize = 16;
49
50 // The extra padding between the button and the top edge.
51 const int kExtraPaddingBetweenButtonAndTop = 1;
52
53 // Colors used to draw titlebar background under default theme.
54 const SkColor kActiveBackgroundDefaultColor = SkColorSetRGB(0x3a, 0x3d, 0x3d);
55 const SkColor kInactiveBackgroundDefaultColor = SkColorSetRGB(0x7a, 0x7c, 0x7c);
56 const SkColor kAttentionBackgroundDefaultColor =
57 SkColorSetRGB(0x53, 0xa9, 0x3f);
58
59 // Color used to draw the minimized panel.
60 const SkColor kMinimizeBackgroundDefaultColor = SkColorSetRGB(0xf5, 0xf4, 0xf0);
61
62 // Color used to draw the title text under default theme.
63 const SkColor kTitleTextDefaultColor = SkColorSetRGB(0xf9, 0xf9, 0xf9);
64
65 gfx::ImageSkia* CreateImageForColor(SkColor color) {
66 gfx::Canvas canvas(gfx::Size(1, 1), 1.0f, true);
67 canvas.DrawColor(color);
68 return new gfx::ImageSkia(canvas.ExtractImageRep());
69 }
70
71 #if defined(OS_WIN)
72 const gfx::ImageSkia& GetTopLeftCornerImage(panel::CornerStyle corner_style) {
73 static gfx::ImageSkia* rounded_image = NULL;
74 static gfx::ImageSkia* non_rounded_image = NULL;
75 if (!rounded_image) {
76 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
77 rounded_image = rb.GetImageSkiaNamed(IDR_WINDOW_TOP_LEFT_CORNER);
78 non_rounded_image = rb.GetImageSkiaNamed(IDR_PANEL_TOP_LEFT_CORNER);
79 }
80 return (corner_style & panel::TOP_ROUNDED) ? *rounded_image
81 : *non_rounded_image;
82 }
83
84 const gfx::ImageSkia& GetTopRightCornerImage(panel::CornerStyle corner_style) {
85 static gfx::ImageSkia* rounded_image = NULL;
86 static gfx::ImageSkia* non_rounded_image = NULL;
87 if (!rounded_image) {
88 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
89 rounded_image = rb.GetImageSkiaNamed(IDR_WINDOW_TOP_RIGHT_CORNER);
90 non_rounded_image = rb.GetImageSkiaNamed(IDR_PANEL_TOP_RIGHT_CORNER);
91 }
92 return (corner_style & panel::TOP_ROUNDED) ? *rounded_image
93 : *non_rounded_image;
94 }
95
96 const gfx::ImageSkia& GetBottomLeftCornerImage(
97 panel::CornerStyle corner_style) {
98 static gfx::ImageSkia* rounded_image = NULL;
99 static gfx::ImageSkia* non_rounded_image = NULL;
100 if (!rounded_image) {
101 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
102 rounded_image = rb.GetImageSkiaNamed(IDR_WINDOW_BOTTOM_LEFT_CORNER);
103 non_rounded_image = rb.GetImageSkiaNamed(IDR_PANEL_BOTTOM_LEFT_CORNER);
104 }
105 return (corner_style & panel::BOTTOM_ROUNDED) ? *rounded_image
106 : *non_rounded_image;
107 }
108
109 const gfx::ImageSkia& GetBottomRightCornerImage(
110 panel::CornerStyle corner_style) {
111 static gfx::ImageSkia* rounded_image = NULL;
112 static gfx::ImageSkia* non_rounded_image = NULL;
113 if (!rounded_image) {
114 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
115 rounded_image = rb.GetImageSkiaNamed(IDR_WINDOW_BOTTOM_RIGHT_CORNER);
116 non_rounded_image = rb.GetImageSkiaNamed(IDR_PANEL_BOTTOM_RIGHT_CORNER);
117 }
118 return (corner_style & panel::BOTTOM_ROUNDED) ? *rounded_image
119 : *non_rounded_image;
120 }
121
122 const gfx::ImageSkia& GetTopEdgeImage() {
123 static gfx::ImageSkia* image = NULL;
124 if (!image) {
125 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
126 image = rb.GetImageSkiaNamed(IDR_WINDOW_TOP_CENTER);
127 }
128 return *image;
129 }
130
131 const gfx::ImageSkia& GetBottomEdgeImage() {
132 static gfx::ImageSkia* image = NULL;
133 if (!image) {
134 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
135 image = rb.GetImageSkiaNamed(IDR_WINDOW_BOTTOM_CENTER);
136 }
137 return *image;
138 }
139
140 const gfx::ImageSkia& GetLeftEdgeImage() {
141 static gfx::ImageSkia* image = NULL;
142 if (!image) {
143 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
144 image = rb.GetImageSkiaNamed(IDR_WINDOW_LEFT_SIDE);
145 }
146 return *image;
147 }
148
149 const gfx::ImageSkia& GetRightEdgeImage() {
150 static gfx::ImageSkia* image = NULL;
151 if (!image) {
152 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
153 image = rb.GetImageSkiaNamed(IDR_WINDOW_RIGHT_SIDE);
154 }
155 return *image;
156 }
157 #endif // defined(OS_WIN)
158
159 const gfx::ImageSkia* GetActiveBackgroundDefaultImage() {
160 static gfx::ImageSkia* image = NULL;
161 if (!image)
162 image = CreateImageForColor(kActiveBackgroundDefaultColor);
163 return image;
164 }
165
166 const gfx::ImageSkia* GetInactiveBackgroundDefaultImage() {
167 static gfx::ImageSkia* image = NULL;
168 if (!image)
169 image = CreateImageForColor(kInactiveBackgroundDefaultColor);
170 return image;
171 }
172
173 const gfx::ImageSkia* GetAttentionBackgroundDefaultImage() {
174 static gfx::ImageSkia* image = NULL;
175 if (!image)
176 image = CreateImageForColor(kAttentionBackgroundDefaultColor);
177 return image;
178 }
179
180 const gfx::ImageSkia* GetMinimizeBackgroundDefaultImage() {
181 static gfx::ImageSkia* image = NULL;
182 if (!image)
183 image = CreateImageForColor(kMinimizeBackgroundDefaultColor);
184 return image;
185 }
186
187 int GetFrameEdgeHitTest(const gfx::Point& point,
188 const gfx::Size& frame_size,
189 int resize_area_size,
190 panel::Resizability resizability) {
191 int x = point.x();
192 int y = point.y();
193 int width = frame_size.width();
194 int height = frame_size.height();
195 if (x < resize_area_size) {
196 if (y < resize_area_size && (resizability & panel::RESIZABLE_TOP_LEFT)) {
197 return HTTOPLEFT;
198 } else if (y >= height - resize_area_size &&
199 (resizability & panel::RESIZABLE_BOTTOM_LEFT)) {
200 return HTBOTTOMLEFT;
201 } else if (resizability & panel::RESIZABLE_LEFT) {
202 return HTLEFT;
203 }
204 } else if (x >= width - resize_area_size) {
205 if (y < resize_area_size && (resizability & panel::RESIZABLE_TOP_RIGHT)) {
206 return HTTOPRIGHT;
207 } else if (y >= height - resize_area_size &&
208 (resizability & panel::RESIZABLE_BOTTOM_RIGHT)) {
209 return HTBOTTOMRIGHT;
210 } else if (resizability & panel::RESIZABLE_RIGHT) {
211 return HTRIGHT;
212 }
213 }
214
215 if (y < resize_area_size && (resizability & panel::RESIZABLE_TOP)) {
216 return HTTOP;
217 } else if (y >= height - resize_area_size &&
218 (resizability & panel::RESIZABLE_BOTTOM)) {
219 return HTBOTTOM;
220 }
221
222 return HTNOWHERE;
223 }
224
225 // Frameless is only supported when Aero is enabled and shadow effect is
226 // present.
227 bool ShouldRenderAsFrameless() {
228 #if defined(OS_WIN)
229 bool is_frameless = ui::win::IsAeroGlassEnabled();
230 if (is_frameless) {
231 BOOL shadow_enabled = FALSE;
232 if (::SystemParametersInfo(SPI_GETDROPSHADOW, 0, &shadow_enabled, 0) &&
233 !shadow_enabled)
234 is_frameless = false;
235 }
236 return is_frameless;
237 #else
238 return false;
239 #endif
240 }
241
242 } // namespace
243
244 // static
245 const char PanelFrameView::kViewClassName[] = "PanelFrameView";
246
247 PanelFrameView::PanelFrameView(PanelView* panel_view)
248 : is_frameless_(ShouldRenderAsFrameless()),
249 panel_view_(panel_view),
250 close_button_(NULL),
251 minimize_button_(NULL),
252 restore_button_(NULL),
253 title_icon_(NULL),
254 title_label_(NULL),
255 corner_style_(panel::ALL_ROUNDED) {
256 }
257
258 PanelFrameView::~PanelFrameView() {
259 }
260
261 void PanelFrameView::Init() {
262 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
263
264 close_button_ = new views::ImageButton(this);
265 close_button_->SetImage(views::CustomButton::STATE_NORMAL,
266 rb.GetImageSkiaNamed(IDR_PANEL_CLOSE));
267 close_button_->SetImage(views::CustomButton::STATE_HOVERED,
268 rb.GetImageSkiaNamed(IDR_PANEL_CLOSE_H));
269 close_button_->SetImage(views::CustomButton::STATE_PRESSED,
270 rb.GetImageSkiaNamed(IDR_PANEL_CLOSE_C));
271 close_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
272 views::ImageButton::ALIGN_MIDDLE);
273 base::string16 tooltip_text =
274 l10n_util::GetStringUTF16(IDS_PANEL_CLOSE_TOOLTIP);
275 close_button_->SetTooltipText(tooltip_text);
276 AddChildView(close_button_);
277
278 minimize_button_ = new views::ImageButton(this);
279 minimize_button_->SetImage(views::CustomButton::STATE_NORMAL,
280 rb.GetImageSkiaNamed(IDR_PANEL_MINIMIZE));
281 minimize_button_->SetImage(views::CustomButton::STATE_HOVERED,
282 rb.GetImageSkiaNamed(IDR_PANEL_MINIMIZE_H));
283 minimize_button_->SetImage(views::CustomButton::STATE_PRESSED,
284 rb.GetImageSkiaNamed(IDR_PANEL_MINIMIZE_C));
285 tooltip_text = l10n_util::GetStringUTF16(IDS_PANEL_MINIMIZE_TOOLTIP);
286 minimize_button_->SetTooltipText(tooltip_text);
287 minimize_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
288 views::ImageButton::ALIGN_MIDDLE);
289 AddChildView(minimize_button_);
290
291 restore_button_ = new views::ImageButton(this);
292 restore_button_->SetImage(views::CustomButton::STATE_NORMAL,
293 rb.GetImageSkiaNamed(IDR_PANEL_RESTORE));
294 restore_button_->SetImage(views::CustomButton::STATE_HOVERED,
295 rb.GetImageSkiaNamed(IDR_PANEL_RESTORE_H));
296 restore_button_->SetImage(views::CustomButton::STATE_PRESSED,
297 rb.GetImageSkiaNamed(IDR_PANEL_RESTORE_C));
298 restore_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
299 views::ImageButton::ALIGN_MIDDLE);
300 tooltip_text = l10n_util::GetStringUTF16(IDS_PANEL_RESTORE_TOOLTIP);
301 restore_button_->SetTooltipText(tooltip_text);
302 restore_button_->SetVisible(false); // only visible when panel is minimized
303 AddChildView(restore_button_);
304
305 title_icon_ = new TabIconView(this, NULL);
306 title_icon_->set_is_light(true);
307 AddChildView(title_icon_);
308 title_icon_->Update();
309
310 title_label_ = new views::Label(
311 panel_view_->panel()->GetWindowTitle(),
312 rb.GetFontList(ui::ResourceBundle::BoldFont));
313 title_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
314 title_label_->SetAutoColorReadabilityEnabled(false);
315 AddChildView(title_label_);
316
317 #if defined(USE_AURA)
318 // Compute the thickness of the client area that needs to be counted towards
319 // mouse resizing.
320 // TODO(tdanderson): Remove this if possible (crbug.com/344924).
321 int thickness_for_mouse_resizing =
322 PanelView::kResizeInsideBoundsSize - BorderThickness();
323 aura::Window* window = panel_view_->GetNativePanelWindow();
324 window->set_hit_test_bounds_override_inner(
325 gfx::Insets(thickness_for_mouse_resizing));
326 #endif
327 }
328
329 void PanelFrameView::UpdateTitle() {
330 UpdateWindowTitle();
331 }
332
333 void PanelFrameView::UpdateIcon() {
334 UpdateWindowIcon();
335 }
336
337 void PanelFrameView::UpdateThrobber() {
338 title_icon_->Update();
339 }
340
341 void PanelFrameView::UpdateTitlebarMinimizeRestoreButtonVisibility() {
342 Panel* panel = panel_view_->panel();
343 minimize_button_->SetVisible(panel->CanShowMinimizeButton());
344 restore_button_->SetVisible(panel->CanShowRestoreButton());
345
346 // Reset the button states in case that the hover states are not cleared when
347 // mouse is clicked but not moved.
348 minimize_button_->SetState(views::CustomButton::STATE_NORMAL);
349 restore_button_->SetState(views::CustomButton::STATE_NORMAL);
350 }
351
352 void PanelFrameView::SetWindowCornerStyle(panel::CornerStyle corner_style) {
353 corner_style_ = corner_style;
354
355 #if defined(OS_WIN)
356 // Changing the window region is going to force a paint. Only change the
357 // window region if the region really differs.
358 HWND native_window = views::HWNDForWidget(panel_view_->window());
359 base::win::ScopedRegion current_region(::CreateRectRgn(0, 0, 0, 0));
360 ::GetWindowRgn(native_window, current_region.get());
361
362 gfx::Path window_mask;
363 GetWindowMask(size(), &window_mask);
364 base::win::ScopedRegion new_region;
365 if (!window_mask.isEmpty())
366 new_region.reset(gfx::CreateHRGNFromSkPath(window_mask));
367
368 const bool has_current_region = current_region != NULL;
369 const bool has_new_region = new_region != NULL;
370 if (has_current_region != has_new_region ||
371 (has_current_region &&
372 !::EqualRgn(current_region.get(), new_region.get()))) {
373 // SetWindowRgn takes ownership of the new_region.
374 ::SetWindowRgn(native_window, new_region.release(), TRUE);
375 }
376 #endif
377 }
378
379 gfx::Rect PanelFrameView::GetBoundsForClientView() const {
380 // The origin of client-area bounds starts after left border and titlebar and
381 // spans until hitting the right and bottom borders.
382 // +------------------------------+
383 // | Top Titlebar |
384 // |-+--------------------------+-|
385 // |L| |R|
386 // |e| |i|
387 // |f| |g|
388 // |t| |h|
389 // | | Client |t|
390 // | | | |
391 // |B| Area |B|
392 // |o| |o|
393 // |r| |r|
394 // |d| |d|
395 // |e| |e|
396 // |r| |r|
397 // | +--------------------------+ |
398 // | Bottom Border |
399 // +------------------------------+
400 int titlebar_height = TitlebarHeight();
401 int border_thickness = BorderThickness();
402 return gfx::Rect(border_thickness,
403 titlebar_height,
404 std::max(0, width() - border_thickness * 2),
405 std::max(0, height() - titlebar_height - border_thickness));
406 }
407
408 gfx::Rect PanelFrameView::GetWindowBoundsForClientBounds(
409 const gfx::Rect& client_bounds) const {
410 int titlebar_height = TitlebarHeight();
411 int border_thickness = BorderThickness();
412 // The window bounds include both client area and non-client area (titlebar
413 // and left, right and bottom borders).
414 return gfx::Rect(client_bounds.x() - border_thickness,
415 client_bounds.y() - titlebar_height,
416 client_bounds.width() + border_thickness * 2,
417 client_bounds.height() + titlebar_height + border_thickness);
418 }
419
420 int PanelFrameView::NonClientHitTest(const gfx::Point& point) {
421 panel::Resizability resizability = panel_view_->panel()->CanResizeByMouse();
422
423 // Check the frame first, as we allow a small area overlapping the contents
424 // to be used for resize handles.
425 int frame_component = GetFrameEdgeHitTest(
426 point, size(), PanelView::kResizeInsideBoundsSize, resizability);
427
428 if (frame_component != HTNOWHERE)
429 return frame_component;
430
431 int client_component =
432 panel_view_->window()->client_view()->NonClientHitTest(point);
433 if (client_component != HTNOWHERE)
434 return client_component;
435
436 if (close_button_ && close_button_->visible() &&
437 close_button_->GetMirroredBounds().Contains(point))
438 return HTCLOSE;
439
440 if (minimize_button_ && minimize_button_->visible() &&
441 minimize_button_->GetMirroredBounds().Contains(point))
442 return HTMINBUTTON;
443
444 if (restore_button_ && restore_button_->visible() &&
445 restore_button_->GetMirroredBounds().Contains(point))
446 return HTMAXBUTTON;
447
448 return HTNOWHERE;
449 }
450
451 void PanelFrameView::GetWindowMask(const gfx::Size& size,
452 gfx::Path* window_mask) {
453 int width = size.width();
454 int height = size.height();
455
456 if (corner_style_ & panel::TOP_ROUNDED) {
457 window_mask->moveTo(0, 3);
458 window_mask->lineTo(1, 2);
459 window_mask->lineTo(1, 1);
460 window_mask->lineTo(2, 1);
461 window_mask->lineTo(3, 0);
462 window_mask->lineTo(SkIntToScalar(width - 3), 0);
463 window_mask->lineTo(SkIntToScalar(width - 2), 1);
464 window_mask->lineTo(SkIntToScalar(width - 1), 1);
465 window_mask->lineTo(SkIntToScalar(width - 1), 2);
466 window_mask->lineTo(SkIntToScalar(width - 1), 3);
467 } else {
468 window_mask->moveTo(0, 0);
469 window_mask->lineTo(width, 0);
470 }
471
472 if (corner_style_ & panel::BOTTOM_ROUNDED) {
473 window_mask->lineTo(SkIntToScalar(width - 1), SkIntToScalar(height - 4));
474 window_mask->lineTo(SkIntToScalar(width - 2), SkIntToScalar(height - 3));
475 window_mask->lineTo(SkIntToScalar(width - 2), SkIntToScalar(height - 2));
476 window_mask->lineTo(SkIntToScalar(width - 3), SkIntToScalar(height - 2));
477 window_mask->lineTo(SkIntToScalar(width - 4), SkIntToScalar(height - 1));
478 window_mask->lineTo(3, SkIntToScalar(height - 1));
479 window_mask->lineTo(2, SkIntToScalar(height - 2));
480 window_mask->lineTo(1, SkIntToScalar(height - 2));
481 window_mask->lineTo(1, SkIntToScalar(height - 3));
482 window_mask->lineTo(0, SkIntToScalar(height - 4));
483 } else {
484 window_mask->lineTo(SkIntToScalar(width), SkIntToScalar(height));
485 window_mask->lineTo(0, SkIntToScalar(height));
486 }
487
488 window_mask->close();
489 }
490
491 void PanelFrameView::ResetWindowControls() {
492 // The controls aren't affected by this constraint.
493 }
494
495 void PanelFrameView::UpdateWindowIcon() {
496 title_icon_->SchedulePaint();
497 }
498
499 void PanelFrameView::UpdateWindowTitle() {
500 title_label_->SetText(panel_view_->panel()->GetWindowTitle());
501 }
502
503 void PanelFrameView::SizeConstraintsChanged() {
504 }
505
506 gfx::Size PanelFrameView::GetPreferredSize() const {
507 gfx::Size pref_size =
508 panel_view_->window()->client_view()->GetPreferredSize();
509 gfx::Rect bounds(0, 0, pref_size.width(), pref_size.height());
510 return panel_view_->window()->non_client_view()->
511 GetWindowBoundsForClientBounds(bounds).size();
512 }
513
514 const char* PanelFrameView::GetClassName() const {
515 return kViewClassName;
516 }
517
518 gfx::Size PanelFrameView::GetMinimumSize() const {
519 return panel_view_->GetMinimumSize();
520 }
521
522 gfx::Size PanelFrameView::GetMaximumSize() const {
523 return panel_view_->GetMaximumSize();
524 }
525
526 void PanelFrameView::Layout() {
527 is_frameless_ = ShouldRenderAsFrameless();
528
529 // Layout the close button.
530 int right = width();
531 close_button_->SetBounds(
532 width() - panel::kTitlebarRightPadding - panel::kPanelButtonSize,
533 (TitlebarHeight() - panel::kPanelButtonSize) / 2 +
534 kExtraPaddingBetweenButtonAndTop,
535 panel::kPanelButtonSize,
536 panel::kPanelButtonSize);
537 right = close_button_->x();
538
539 // Layout the minimize and restore button. Both occupy the same space,
540 // but at most one is visible at any time.
541 minimize_button_->SetBounds(
542 right - panel::kButtonPadding - panel::kPanelButtonSize,
543 (TitlebarHeight() - panel::kPanelButtonSize) / 2 +
544 kExtraPaddingBetweenButtonAndTop,
545 panel::kPanelButtonSize,
546 panel::kPanelButtonSize);
547 restore_button_->SetBoundsRect(minimize_button_->bounds());
548 right = minimize_button_->x();
549
550 // Layout the icon.
551 int icon_y = (TitlebarHeight() - kIconSize) / 2;
552 title_icon_->SetBounds(
553 panel::kTitlebarLeftPadding,
554 icon_y,
555 kIconSize,
556 kIconSize);
557
558 // Layout the title.
559 int title_x = title_icon_->bounds().right() + panel::kIconAndTitlePadding;
560 int title_height = title_label_->font_list().GetHeight();
561 title_label_->SetBounds(
562 title_x,
563 icon_y + ((kIconSize - title_height - 1) / 2),
564 std::max(0, right - panel::kTitleAndButtonPadding - title_x),
565 title_height);
566 }
567
568 void PanelFrameView::OnPaint(gfx::Canvas* canvas) {
569 UpdateControlStyles(GetPaintState());
570 PaintFrameBackground(canvas);
571 PaintFrameEdge(canvas);
572 }
573
574 bool PanelFrameView::OnMousePressed(const ui::MouseEvent& event) {
575 // If the mouse location falls within the resizing area of the titlebar, do
576 // not handle the event so that the system resizing logic can kick in.
577 if (event.IsOnlyLeftMouseButton() &&
578 !IsWithinResizingArea(event.location())) {
579 // |event.location| is in the view's coordinate system. Convert it to the
580 // screen coordinate system.
581 gfx::Point mouse_location = event.location();
582 views::View::ConvertPointToScreen(this, &mouse_location);
583
584 if (panel_view_->OnTitlebarMousePressed(mouse_location))
585 return true;
586 }
587 return NonClientFrameView::OnMousePressed(event);
588 }
589
590 bool PanelFrameView::OnMouseDragged(const ui::MouseEvent& event) {
591 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
592 // Converting the mouse location to screen coordinates returns an incorrect
593 // location while the panel is moving. See crbug.com/353393 for more details.
594 // TODO(pkotwicz): Fix conversion to screen coordinates
595 display::Screen* screen = display::Screen::GetScreen();
596 gfx::Point mouse_location = screen->GetCursorScreenPoint();
597 #else
598 // |event.location| is in the view's coordinate system. Convert it to the
599 // screen coordinate system.
600 gfx::Point mouse_location = event.location();
601 views::View::ConvertPointToScreen(this, &mouse_location);
602 #endif
603
604 if (panel_view_->OnTitlebarMouseDragged(mouse_location))
605 return true;
606 return NonClientFrameView::OnMouseDragged(event);
607 }
608
609 void PanelFrameView::OnMouseReleased(const ui::MouseEvent& event) {
610 if (panel_view_->OnTitlebarMouseReleased(
611 event.IsControlDown() ? panel::APPLY_TO_ALL : panel::NO_MODIFIER))
612 return;
613 NonClientFrameView::OnMouseReleased(event);
614 }
615
616 void PanelFrameView::OnMouseCaptureLost() {
617 if (panel_view_->OnTitlebarMouseCaptureLost())
618 return;
619 NonClientFrameView::OnMouseCaptureLost();
620 }
621
622 void PanelFrameView::ButtonPressed(views::Button* sender,
623 const ui::Event& event) {
624 if (sender == close_button_) {
625 panel_view_->ClosePanel();
626 } else {
627 panel::ClickModifier modifier =
628 event.IsControlDown() ? panel::APPLY_TO_ALL : panel::NO_MODIFIER;
629 if (sender == minimize_button_)
630 panel_view_->panel()->OnMinimizeButtonClicked(modifier);
631 else if (sender == restore_button_)
632 panel_view_->panel()->OnRestoreButtonClicked(modifier);
633 }
634 }
635
636 bool PanelFrameView::ShouldTabIconViewAnimate() const {
637 // This function is queried during the creation of the window as the
638 // TabIconView we host is initialized, so we need to NULL check the selected
639 // WebContents because in this condition there is not yet a selected tab.
640 content::WebContents* contents = panel_view_->panel()->GetWebContents();
641 return contents ? contents->IsLoading() : false;
642 }
643
644 gfx::ImageSkia PanelFrameView::GetFaviconForTabIconView() {
645 return panel_view_->window()->widget_delegate()->GetWindowIcon();
646 }
647
648 gfx::Size PanelFrameView::NonClientAreaSize() const {
649 if (is_frameless_)
650 return gfx::Size(0, TitlebarHeight());
651 // When the frame is present, the width of non-client area consists of
652 // left and right borders, while the height consists of the top area
653 // (titlebar) and the bottom border.
654 return gfx::Size(2 * kNonAeroBorderThickness,
655 TitlebarHeight() + kNonAeroBorderThickness);
656 }
657
658 int PanelFrameView::TitlebarHeight() const {
659 return panel::kTitlebarHeight;
660 }
661
662 int PanelFrameView::BorderThickness() const {
663 return is_frameless_ ? 0 : kNonAeroBorderThickness;
664 }
665
666 PanelFrameView::PaintState PanelFrameView::GetPaintState() const {
667 if (panel_view_->panel()->IsDrawingAttention())
668 return PAINT_FOR_ATTENTION;
669 if (bounds().height() <= panel::kMinimizedPanelHeight)
670 return PAINT_AS_MINIMIZED;
671 if (panel_view_->IsPanelActive() &&
672 !panel_view_->force_to_paint_as_inactive())
673 return PAINT_AS_ACTIVE;
674 return PAINT_AS_INACTIVE;
675 }
676
677 SkColor PanelFrameView::GetTitleColor(PaintState paint_state) const {
678 return kTitleTextDefaultColor;
679 }
680
681 const gfx::ImageSkia* PanelFrameView::GetFrameBackground(
682 PaintState paint_state) const {
683 switch (paint_state) {
684 case PAINT_AS_INACTIVE:
685 return GetInactiveBackgroundDefaultImage();
686 case PAINT_AS_ACTIVE:
687 return GetActiveBackgroundDefaultImage();
688 case PAINT_AS_MINIMIZED:
689 return GetMinimizeBackgroundDefaultImage();
690 case PAINT_FOR_ATTENTION:
691 return GetAttentionBackgroundDefaultImage();
692 default:
693 NOTREACHED();
694 return GetInactiveBackgroundDefaultImage();
695 }
696 }
697
698 void PanelFrameView::UpdateControlStyles(PaintState paint_state) {
699 title_label_->SetEnabledColor(GetTitleColor(paint_state));
700 }
701
702 void PanelFrameView::PaintFrameBackground(gfx::Canvas* canvas) {
703 // We only need to paint the title-bar since no resizing border is shown.
704 // Instead, we allow part of the inner content area be used to trigger the
705 // mouse resizing.
706 int titlebar_height = TitlebarHeight();
707 const gfx::ImageSkia* image = GetFrameBackground(GetPaintState());
708 canvas->TileImageInt(*image, 0, 0, width(), titlebar_height);
709
710 if (is_frameless_)
711 return;
712
713 // Left border, below title-bar.
714 canvas->TileImageInt(*image, 0, titlebar_height, kNonAeroBorderThickness,
715 height() - titlebar_height);
716
717 // Right border, below title-bar.
718 canvas->TileImageInt(*image, width() - kNonAeroBorderThickness,
719 titlebar_height, kNonAeroBorderThickness, height() - titlebar_height);
720
721 // Bottom border.
722 canvas->TileImageInt(*image, 0, height() - kNonAeroBorderThickness, width(),
723 kNonAeroBorderThickness);
724 }
725
726 void PanelFrameView::PaintFrameEdge(gfx::Canvas* canvas) {
727 #if defined(OS_WIN)
728 // Border is not needed when panel is not shown as minimized.
729 if (GetPaintState() != PAINT_AS_MINIMIZED)
730 return;
731
732 const gfx::ImageSkia& top_left_image = GetTopLeftCornerImage(corner_style_);
733 const gfx::ImageSkia& top_right_image = GetTopRightCornerImage(corner_style_);
734 const gfx::ImageSkia& bottom_left_image =
735 GetBottomLeftCornerImage(corner_style_);
736 const gfx::ImageSkia& bottom_right_image =
737 GetBottomRightCornerImage(corner_style_);
738 const gfx::ImageSkia& top_image = GetTopEdgeImage();
739 const gfx::ImageSkia& bottom_image = GetBottomEdgeImage();
740 const gfx::ImageSkia& left_image = GetLeftEdgeImage();
741 const gfx::ImageSkia& right_image = GetRightEdgeImage();
742
743 // Draw the top border.
744 canvas->DrawImageInt(top_left_image, 0, 0);
745 canvas->TileImageInt(top_image,
746 top_left_image.width(),
747 0,
748 width() - top_right_image.width(),
749 top_image.height());
750 canvas->DrawImageInt(top_right_image, width() - top_right_image.width(), 0);
751
752 // Draw the right border.
753 canvas->TileImageInt(right_image,
754 width() - right_image.width(),
755 top_right_image.height(),
756 right_image.width(),
757 height() - top_right_image.height() -
758 bottom_right_image.height());
759
760 // Draw the bottom border.
761 canvas->DrawImageInt(bottom_right_image,
762 width() - bottom_right_image.width(),
763 height() - bottom_right_image.height());
764 canvas->TileImageInt(bottom_image,
765 bottom_left_image.width(),
766 height() - bottom_image.height(),
767 width() - bottom_left_image.width() -
768 bottom_right_image.width(),
769 bottom_image.height());
770 canvas->DrawImageInt(bottom_left_image,
771 0,
772 height() - bottom_left_image.height());
773
774 // Draw the left border.
775 canvas->TileImageInt(left_image,
776 0,
777 top_left_image.height(),
778 left_image.width(),
779 height() - top_left_image.height() -
780 bottom_left_image.height());
781 #endif
782 }
783
784 bool PanelFrameView::IsWithinResizingArea(
785 const gfx::Point& mouse_location) const {
786 panel::Resizability resizability = panel_view_->panel()->CanResizeByMouse();
787 int edge_hittest = GetFrameEdgeHitTest(
788 mouse_location, size(), PanelView::kResizeInsideBoundsSize, resizability);
789 return edge_hittest != HTNOWHERE;
790 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/panels/panel_frame_view.h ('k') | chrome/browser/ui/views/panels/panel_stack_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698