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