Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / views / panels / panel_frame_view.cc
blob6dda80077d230771cf91af9d94133a113e0f468f
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/base/hit_test.h"
16 #include "ui/base/l10n/l10n_util.h"
17 #include "ui/base/resource/resource_bundle.h"
18 #include "ui/gfx/canvas.h"
19 #include "ui/gfx/font_list.h"
20 #include "ui/gfx/path.h"
21 #include "ui/views/controls/button/image_button.h"
22 #include "ui/views/controls/label.h"
23 #include "ui/views/widget/widget.h"
24 #include "ui/views/widget/widget_delegate.h"
26 #if defined(OS_WIN)
27 #include "base/win/scoped_gdi_object.h"
28 #include "ui/base/win/shell.h"
29 #include "ui/gfx/path_win.h"
30 #include "ui/views/win/hwnd_util.h"
31 #endif
33 #if defined(USE_AURA)
34 #include "ui/aura/window.h"
35 #endif
37 namespace {
39 // The thickness of the border when Aero is not enabled. In this case, the
40 // shadow around the window will not be painted by the system and we need to
41 // paint a frame in order to differentiate the client area from the background.
42 const int kNonAeroBorderThickness = 1;
44 // The height and width in pixels of the icon.
45 const int kIconSize = 16;
47 // The extra padding between the button and the top edge.
48 const int kExtraPaddingBetweenButtonAndTop = 1;
50 // Colors used to draw titlebar background under default theme.
51 const SkColor kActiveBackgroundDefaultColor = SkColorSetRGB(0x3a, 0x3d, 0x3d);
52 const SkColor kInactiveBackgroundDefaultColor = SkColorSetRGB(0x7a, 0x7c, 0x7c);
53 const SkColor kAttentionBackgroundDefaultColor =
54 SkColorSetRGB(0x53, 0xa9, 0x3f);
56 // Color used to draw the minimized panel.
57 const SkColor kMinimizeBackgroundDefaultColor = SkColorSetRGB(0xf5, 0xf4, 0xf0);
59 // Color used to draw the title text under default theme.
60 const SkColor kTitleTextDefaultColor = SkColorSetRGB(0xf9, 0xf9, 0xf9);
62 gfx::ImageSkia* CreateImageForColor(SkColor color) {
63 gfx::Canvas canvas(gfx::Size(1, 1), 1.0f, true);
64 canvas.DrawColor(color);
65 return new gfx::ImageSkia(canvas.ExtractImageRep());
68 #if defined(OS_WIN)
69 const gfx::ImageSkia& GetTopLeftCornerImage(panel::CornerStyle corner_style) {
70 static gfx::ImageSkia* rounded_image = NULL;
71 static gfx::ImageSkia* non_rounded_image = NULL;
72 if (!rounded_image) {
73 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
74 rounded_image = rb.GetImageSkiaNamed(IDR_WINDOW_TOP_LEFT_CORNER);
75 non_rounded_image = rb.GetImageSkiaNamed(IDR_PANEL_TOP_LEFT_CORNER);
77 return (corner_style & panel::TOP_ROUNDED) ? *rounded_image
78 : *non_rounded_image;
81 const gfx::ImageSkia& GetTopRightCornerImage(panel::CornerStyle corner_style) {
82 static gfx::ImageSkia* rounded_image = NULL;
83 static gfx::ImageSkia* non_rounded_image = NULL;
84 if (!rounded_image) {
85 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
86 rounded_image = rb.GetImageSkiaNamed(IDR_WINDOW_TOP_RIGHT_CORNER);
87 non_rounded_image = rb.GetImageSkiaNamed(IDR_PANEL_TOP_RIGHT_CORNER);
89 return (corner_style & panel::TOP_ROUNDED) ? *rounded_image
90 : *non_rounded_image;
93 const gfx::ImageSkia& GetBottomLeftCornerImage(
94 panel::CornerStyle corner_style) {
95 static gfx::ImageSkia* rounded_image = NULL;
96 static gfx::ImageSkia* non_rounded_image = NULL;
97 if (!rounded_image) {
98 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
99 rounded_image = rb.GetImageSkiaNamed(IDR_WINDOW_BOTTOM_LEFT_CORNER);
100 non_rounded_image = rb.GetImageSkiaNamed(IDR_PANEL_BOTTOM_LEFT_CORNER);
102 return (corner_style & panel::BOTTOM_ROUNDED) ? *rounded_image
103 : *non_rounded_image;
106 const gfx::ImageSkia& GetBottomRightCornerImage(
107 panel::CornerStyle corner_style) {
108 static gfx::ImageSkia* rounded_image = NULL;
109 static gfx::ImageSkia* non_rounded_image = NULL;
110 if (!rounded_image) {
111 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
112 rounded_image = rb.GetImageSkiaNamed(IDR_WINDOW_BOTTOM_RIGHT_CORNER);
113 non_rounded_image = rb.GetImageSkiaNamed(IDR_PANEL_BOTTOM_RIGHT_CORNER);
115 return (corner_style & panel::BOTTOM_ROUNDED) ? *rounded_image
116 : *non_rounded_image;
119 const gfx::ImageSkia& GetTopEdgeImage() {
120 static gfx::ImageSkia* image = NULL;
121 if (!image) {
122 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
123 image = rb.GetImageSkiaNamed(IDR_WINDOW_TOP_CENTER);
125 return *image;
128 const gfx::ImageSkia& GetBottomEdgeImage() {
129 static gfx::ImageSkia* image = NULL;
130 if (!image) {
131 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
132 image = rb.GetImageSkiaNamed(IDR_WINDOW_BOTTOM_CENTER);
134 return *image;
137 const gfx::ImageSkia& GetLeftEdgeImage() {
138 static gfx::ImageSkia* image = NULL;
139 if (!image) {
140 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
141 image = rb.GetImageSkiaNamed(IDR_WINDOW_LEFT_SIDE);
143 return *image;
146 const gfx::ImageSkia& GetRightEdgeImage() {
147 static gfx::ImageSkia* image = NULL;
148 if (!image) {
149 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
150 image = rb.GetImageSkiaNamed(IDR_WINDOW_RIGHT_SIDE);
152 return *image;
154 #endif // defined(OS_WIN)
156 const gfx::ImageSkia* GetActiveBackgroundDefaultImage() {
157 static gfx::ImageSkia* image = NULL;
158 if (!image)
159 image = CreateImageForColor(kActiveBackgroundDefaultColor);
160 return image;
163 const gfx::ImageSkia* GetInactiveBackgroundDefaultImage() {
164 static gfx::ImageSkia* image = NULL;
165 if (!image)
166 image = CreateImageForColor(kInactiveBackgroundDefaultColor);
167 return image;
170 const gfx::ImageSkia* GetAttentionBackgroundDefaultImage() {
171 static gfx::ImageSkia* image = NULL;
172 if (!image)
173 image = CreateImageForColor(kAttentionBackgroundDefaultColor);
174 return image;
177 const gfx::ImageSkia* GetMinimizeBackgroundDefaultImage() {
178 static gfx::ImageSkia* image = NULL;
179 if (!image)
180 image = CreateImageForColor(kMinimizeBackgroundDefaultColor);
181 return image;
184 int GetFrameEdgeHitTest(const gfx::Point& point,
185 const gfx::Size& frame_size,
186 int resize_area_size,
187 panel::Resizability resizability) {
188 int x = point.x();
189 int y = point.y();
190 int width = frame_size.width();
191 int height = frame_size.height();
192 if (x < resize_area_size) {
193 if (y < resize_area_size && (resizability & panel::RESIZABLE_TOP_LEFT)) {
194 return HTTOPLEFT;
195 } else if (y >= height - resize_area_size &&
196 (resizability & panel::RESIZABLE_BOTTOM_LEFT)) {
197 return HTBOTTOMLEFT;
198 } else if (resizability & panel::RESIZABLE_LEFT) {
199 return HTLEFT;
201 } else if (x >= width - resize_area_size) {
202 if (y < resize_area_size && (resizability & panel::RESIZABLE_TOP_RIGHT)) {
203 return HTTOPRIGHT;
204 } else if (y >= height - resize_area_size &&
205 (resizability & panel::RESIZABLE_BOTTOM_RIGHT)) {
206 return HTBOTTOMRIGHT;
207 } else if (resizability & panel::RESIZABLE_RIGHT) {
208 return HTRIGHT;
212 if (y < resize_area_size && (resizability & panel::RESIZABLE_TOP)) {
213 return HTTOP;
214 } else if (y >= height - resize_area_size &&
215 (resizability & panel::RESIZABLE_BOTTOM)) {
216 return HTBOTTOM;
219 return HTNOWHERE;
222 // Frameless is only supported when Aero is enabled and shadow effect is
223 // present.
224 bool ShouldRenderAsFrameless() {
225 #if defined(OS_WIN)
226 bool is_frameless = ui::win::IsAeroGlassEnabled();
227 if (is_frameless) {
228 BOOL shadow_enabled = FALSE;
229 if (::SystemParametersInfo(SPI_GETDROPSHADOW, 0, &shadow_enabled, 0) &&
230 !shadow_enabled)
231 is_frameless = false;
233 return is_frameless;
234 #else
235 return false;
236 #endif
239 } // namespace
241 // static
242 const char PanelFrameView::kViewClassName[] = "PanelFrameView";
244 PanelFrameView::PanelFrameView(PanelView* panel_view)
245 : is_frameless_(ShouldRenderAsFrameless()),
246 panel_view_(panel_view),
247 close_button_(NULL),
248 minimize_button_(NULL),
249 restore_button_(NULL),
250 title_icon_(NULL),
251 title_label_(NULL),
252 corner_style_(panel::ALL_ROUNDED) {
255 PanelFrameView::~PanelFrameView() {
258 void PanelFrameView::Init() {
259 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
261 close_button_ = new views::ImageButton(this);
262 close_button_->SetImage(views::CustomButton::STATE_NORMAL,
263 rb.GetImageSkiaNamed(IDR_PANEL_CLOSE));
264 close_button_->SetImage(views::CustomButton::STATE_HOVERED,
265 rb.GetImageSkiaNamed(IDR_PANEL_CLOSE_H));
266 close_button_->SetImage(views::CustomButton::STATE_PRESSED,
267 rb.GetImageSkiaNamed(IDR_PANEL_CLOSE_C));
268 close_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
269 views::ImageButton::ALIGN_MIDDLE);
270 base::string16 tooltip_text =
271 l10n_util::GetStringUTF16(IDS_PANEL_CLOSE_TOOLTIP);
272 close_button_->SetTooltipText(tooltip_text);
273 AddChildView(close_button_);
275 minimize_button_ = new views::ImageButton(this);
276 minimize_button_->SetImage(views::CustomButton::STATE_NORMAL,
277 rb.GetImageSkiaNamed(IDR_PANEL_MINIMIZE));
278 minimize_button_->SetImage(views::CustomButton::STATE_HOVERED,
279 rb.GetImageSkiaNamed(IDR_PANEL_MINIMIZE_H));
280 minimize_button_->SetImage(views::CustomButton::STATE_PRESSED,
281 rb.GetImageSkiaNamed(IDR_PANEL_MINIMIZE_C));
282 tooltip_text = l10n_util::GetStringUTF16(IDS_PANEL_MINIMIZE_TOOLTIP);
283 minimize_button_->SetTooltipText(tooltip_text);
284 minimize_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
285 views::ImageButton::ALIGN_MIDDLE);
286 AddChildView(minimize_button_);
288 restore_button_ = new views::ImageButton(this);
289 restore_button_->SetImage(views::CustomButton::STATE_NORMAL,
290 rb.GetImageSkiaNamed(IDR_PANEL_RESTORE));
291 restore_button_->SetImage(views::CustomButton::STATE_HOVERED,
292 rb.GetImageSkiaNamed(IDR_PANEL_RESTORE_H));
293 restore_button_->SetImage(views::CustomButton::STATE_PRESSED,
294 rb.GetImageSkiaNamed(IDR_PANEL_RESTORE_C));
295 restore_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
296 views::ImageButton::ALIGN_MIDDLE);
297 tooltip_text = l10n_util::GetStringUTF16(IDS_PANEL_RESTORE_TOOLTIP);
298 restore_button_->SetTooltipText(tooltip_text);
299 restore_button_->SetVisible(false); // only visible when panel is minimized
300 AddChildView(restore_button_);
302 title_icon_ = new TabIconView(this, NULL);
303 title_icon_->set_is_light(true);
304 AddChildView(title_icon_);
305 title_icon_->Update();
307 title_label_ = new views::Label(
308 panel_view_->panel()->GetWindowTitle(),
309 rb.GetFontList(ui::ResourceBundle::BoldFont));
310 title_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
311 title_label_->SetAutoColorReadabilityEnabled(false);
312 AddChildView(title_label_);
314 #if defined(USE_AURA)
315 // Compute the thickness of the client area that needs to be counted towards
316 // mouse resizing.
317 int thickness_for_mouse_resizing =
318 PanelView::kResizeInsideBoundsSize - BorderThickness();
319 aura::Window* window = panel_view_->GetNativePanelWindow();
320 window->set_hit_test_bounds_override_inner(
321 gfx::Insets(thickness_for_mouse_resizing, thickness_for_mouse_resizing,
322 thickness_for_mouse_resizing, thickness_for_mouse_resizing));
323 #endif
326 void PanelFrameView::UpdateTitle() {
327 UpdateWindowTitle();
330 void PanelFrameView::UpdateIcon() {
331 UpdateWindowIcon();
334 void PanelFrameView::UpdateThrobber() {
335 title_icon_->Update();
338 void PanelFrameView::UpdateTitlebarMinimizeRestoreButtonVisibility() {
339 Panel* panel = panel_view_->panel();
340 minimize_button_->SetVisible(panel->CanShowMinimizeButton());
341 restore_button_->SetVisible(panel->CanShowRestoreButton());
343 // Reset the button states in case that the hover states are not cleared when
344 // mouse is clicked but not moved.
345 minimize_button_->SetState(views::CustomButton::STATE_NORMAL);
346 restore_button_->SetState(views::CustomButton::STATE_NORMAL);
349 void PanelFrameView::SetWindowCornerStyle(panel::CornerStyle corner_style) {
350 corner_style_ = corner_style;
352 #if defined(OS_WIN)
353 // Changing the window region is going to force a paint. Only change the
354 // window region if the region really differs.
355 HWND native_window = views::HWNDForWidget(panel_view_->window());
356 base::win::ScopedRegion current_region(::CreateRectRgn(0, 0, 0, 0));
357 int current_region_result = ::GetWindowRgn(native_window, current_region);
359 gfx::Path window_mask;
360 GetWindowMask(size(), &window_mask);
361 base::win::ScopedRegion new_region(gfx::CreateHRGNFromSkPath(window_mask));
363 if (current_region_result == ERROR ||
364 !::EqualRgn(current_region, new_region)) {
365 // SetWindowRgn takes ownership of the new_region.
366 ::SetWindowRgn(native_window, new_region.release(), TRUE);
368 #endif
371 gfx::Rect PanelFrameView::GetBoundsForClientView() const {
372 // The origin of client-area bounds starts after left border and titlebar and
373 // spans until hitting the right and bottom borders.
374 // +------------------------------+
375 // | Top Titlebar |
376 // |-+--------------------------+-|
377 // |L| |R|
378 // |e| |i|
379 // |f| |g|
380 // |t| |h|
381 // | | Client |t|
382 // | | | |
383 // |B| Area |B|
384 // |o| |o|
385 // |r| |r|
386 // |d| |d|
387 // |e| |e|
388 // |r| |r|
389 // | +--------------------------+ |
390 // | Bottom Border |
391 // +------------------------------+
392 int titlebar_height = TitlebarHeight();
393 int border_thickness = BorderThickness();
394 return gfx::Rect(border_thickness,
395 titlebar_height,
396 std::max(0, width() - border_thickness * 2),
397 std::max(0, height() - titlebar_height - border_thickness));
400 gfx::Rect PanelFrameView::GetWindowBoundsForClientBounds(
401 const gfx::Rect& client_bounds) const {
402 int titlebar_height = TitlebarHeight();
403 int border_thickness = BorderThickness();
404 // The window bounds include both client area and non-client area (titlebar
405 // and left, right and bottom borders).
406 return gfx::Rect(client_bounds.x() - border_thickness,
407 client_bounds.y() - titlebar_height,
408 client_bounds.width() + border_thickness * 2,
409 client_bounds.height() + titlebar_height + border_thickness);
412 int PanelFrameView::NonClientHitTest(const gfx::Point& point) {
413 panel::Resizability resizability = panel_view_->panel()->CanResizeByMouse();
415 // Check the frame first, as we allow a small area overlapping the contents
416 // to be used for resize handles.
417 int frame_component = GetFrameEdgeHitTest(
418 point, size(), PanelView::kResizeInsideBoundsSize, resizability);
420 if (frame_component != HTNOWHERE)
421 return frame_component;
423 int client_component =
424 panel_view_->window()->client_view()->NonClientHitTest(point);
425 if (client_component != HTNOWHERE)
426 return client_component;
428 if (close_button_ && close_button_->visible() &&
429 close_button_->GetMirroredBounds().Contains(point))
430 return HTCLOSE;
432 if (minimize_button_ && minimize_button_->visible() &&
433 minimize_button_->GetMirroredBounds().Contains(point))
434 return HTMINBUTTON;
436 if (restore_button_ && restore_button_->visible() &&
437 restore_button_->GetMirroredBounds().Contains(point))
438 return HTMAXBUTTON;
440 return HTNOWHERE;
443 void PanelFrameView::GetWindowMask(const gfx::Size& size,
444 gfx::Path* window_mask) {
445 int width = size.width();
446 int height = size.height();
448 if (corner_style_ & panel::TOP_ROUNDED) {
449 window_mask->moveTo(0, 3);
450 window_mask->lineTo(1, 2);
451 window_mask->lineTo(1, 1);
452 window_mask->lineTo(2, 1);
453 window_mask->lineTo(3, 0);
454 window_mask->lineTo(SkIntToScalar(width - 3), 0);
455 window_mask->lineTo(SkIntToScalar(width - 2), 1);
456 window_mask->lineTo(SkIntToScalar(width - 1), 1);
457 window_mask->lineTo(SkIntToScalar(width - 1), 2);
458 window_mask->lineTo(SkIntToScalar(width - 1), 3);
459 } else {
460 window_mask->moveTo(0, 0);
461 window_mask->lineTo(width, 0);
464 if (corner_style_ & panel::BOTTOM_ROUNDED) {
465 window_mask->lineTo(SkIntToScalar(width - 1), SkIntToScalar(height - 4));
466 window_mask->lineTo(SkIntToScalar(width - 2), SkIntToScalar(height - 3));
467 window_mask->lineTo(SkIntToScalar(width - 2), SkIntToScalar(height - 2));
468 window_mask->lineTo(SkIntToScalar(width - 3), SkIntToScalar(height - 2));
469 window_mask->lineTo(SkIntToScalar(width - 4), SkIntToScalar(height - 1));
470 window_mask->lineTo(3, SkIntToScalar(height - 1));
471 window_mask->lineTo(2, SkIntToScalar(height - 2));
472 window_mask->lineTo(1, SkIntToScalar(height - 2));
473 window_mask->lineTo(1, SkIntToScalar(height - 3));
474 window_mask->lineTo(0, SkIntToScalar(height - 4));
475 } else {
476 window_mask->lineTo(SkIntToScalar(width), SkIntToScalar(height));
477 window_mask->lineTo(0, SkIntToScalar(height));
480 window_mask->close();
483 void PanelFrameView::ResetWindowControls() {
484 // The controls aren't affected by this constraint.
487 void PanelFrameView::UpdateWindowIcon() {
488 title_icon_->SchedulePaint();
491 void PanelFrameView::UpdateWindowTitle() {
492 title_label_->SetText(panel_view_->panel()->GetWindowTitle());
495 gfx::Size PanelFrameView::GetPreferredSize() {
496 gfx::Size pref_size =
497 panel_view_->window()->client_view()->GetPreferredSize();
498 gfx::Rect bounds(0, 0, pref_size.width(), pref_size.height());
499 return panel_view_->window()->non_client_view()->
500 GetWindowBoundsForClientBounds(bounds).size();
503 const char* PanelFrameView::GetClassName() const {
504 return kViewClassName;
507 gfx::Size PanelFrameView::GetMinimumSize() {
508 return panel_view_->GetMinimumSize();
511 gfx::Size PanelFrameView::GetMaximumSize() {
512 return panel_view_->GetMaximumSize();
515 void PanelFrameView::Layout() {
516 is_frameless_ = ShouldRenderAsFrameless();
518 // Layout the close button.
519 int right = width();
520 close_button_->SetBounds(
521 width() - panel::kTitlebarRightPadding - panel::kPanelButtonSize,
522 (TitlebarHeight() - panel::kPanelButtonSize) / 2 +
523 kExtraPaddingBetweenButtonAndTop,
524 panel::kPanelButtonSize,
525 panel::kPanelButtonSize);
526 right = close_button_->x();
528 // Layout the minimize and restore button. Both occupy the same space,
529 // but at most one is visible at any time.
530 minimize_button_->SetBounds(
531 right - panel::kButtonPadding - panel::kPanelButtonSize,
532 (TitlebarHeight() - panel::kPanelButtonSize) / 2 +
533 kExtraPaddingBetweenButtonAndTop,
534 panel::kPanelButtonSize,
535 panel::kPanelButtonSize);
536 restore_button_->SetBoundsRect(minimize_button_->bounds());
537 right = minimize_button_->x();
539 // Layout the icon.
540 int icon_y = (TitlebarHeight() - kIconSize) / 2;
541 title_icon_->SetBounds(
542 panel::kTitlebarLeftPadding,
543 icon_y,
544 kIconSize,
545 kIconSize);
547 // Layout the title.
548 int title_x = title_icon_->bounds().right() + panel::kIconAndTitlePadding;
549 int title_height = title_label_->font_list().GetHeight();
550 title_label_->SetBounds(
551 title_x,
552 icon_y + ((kIconSize - title_height - 1) / 2),
553 std::max(0, right - panel::kTitleAndButtonPadding - title_x),
554 title_height);
557 void PanelFrameView::OnPaint(gfx::Canvas* canvas) {
558 UpdateControlStyles(GetPaintState());
559 PaintFrameBackground(canvas);
560 PaintFrameEdge(canvas);
563 bool PanelFrameView::OnMousePressed(const ui::MouseEvent& event) {
564 if (event.IsOnlyLeftMouseButton()) {
565 // |event.location| is in the view's coordinate system. Convert it to the
566 // screen coordinate system.
567 gfx::Point mouse_location = event.location();
568 views::View::ConvertPointToScreen(this, &mouse_location);
570 // If the mouse location falls within the resizing area of the titlebar,
571 // do not handle the event so that the system resizing logic could kick in.
572 if (!panel_view_->IsWithinResizingArea(mouse_location) &&
573 panel_view_->OnTitlebarMousePressed(mouse_location))
574 return true;
576 return NonClientFrameView::OnMousePressed(event);
579 bool PanelFrameView::OnMouseDragged(const ui::MouseEvent& event) {
580 // |event.location| is in the view's coordinate system. Convert it to the
581 // screen coordinate system.
582 gfx::Point mouse_location = event.location();
583 views::View::ConvertPointToScreen(this, &mouse_location);
585 if (panel_view_->OnTitlebarMouseDragged(mouse_location))
586 return true;
587 return NonClientFrameView::OnMouseDragged(event);
590 void PanelFrameView::OnMouseReleased(const ui::MouseEvent& event) {
591 if (panel_view_->OnTitlebarMouseReleased(
592 event.IsControlDown() ? panel::APPLY_TO_ALL : panel::NO_MODIFIER))
593 return;
594 NonClientFrameView::OnMouseReleased(event);
597 void PanelFrameView::OnMouseCaptureLost() {
598 if (panel_view_->OnTitlebarMouseCaptureLost())
599 return;
600 NonClientFrameView::OnMouseCaptureLost();
603 void PanelFrameView::ButtonPressed(views::Button* sender,
604 const ui::Event& event) {
605 if (sender == close_button_) {
606 panel_view_->ClosePanel();
607 } else {
608 panel::ClickModifier modifier =
609 event.IsControlDown() ? panel::APPLY_TO_ALL : panel::NO_MODIFIER;
610 if (sender == minimize_button_)
611 panel_view_->panel()->OnMinimizeButtonClicked(modifier);
612 else if (sender == restore_button_)
613 panel_view_->panel()->OnRestoreButtonClicked(modifier);
617 bool PanelFrameView::ShouldTabIconViewAnimate() const {
618 // This function is queried during the creation of the window as the
619 // TabIconView we host is initialized, so we need to NULL check the selected
620 // WebContents because in this condition there is not yet a selected tab.
621 content::WebContents* contents = panel_view_->panel()->GetWebContents();
622 return contents ? contents->IsLoading() : false;
625 gfx::ImageSkia PanelFrameView::GetFaviconForTabIconView() {
626 return panel_view_->window()->widget_delegate()->GetWindowIcon();
629 gfx::Size PanelFrameView::NonClientAreaSize() const {
630 if (is_frameless_)
631 return gfx::Size(0, TitlebarHeight());
632 // When the frame is present, the width of non-client area consists of
633 // left and right borders, while the height consists of the top area
634 // (titlebar) and the bottom border.
635 return gfx::Size(2 * kNonAeroBorderThickness,
636 TitlebarHeight() + kNonAeroBorderThickness);
639 int PanelFrameView::TitlebarHeight() const {
640 return panel::kTitlebarHeight;
643 int PanelFrameView::BorderThickness() const {
644 return is_frameless_ ? 0 : kNonAeroBorderThickness;
647 PanelFrameView::PaintState PanelFrameView::GetPaintState() const {
648 if (panel_view_->panel()->IsDrawingAttention())
649 return PAINT_FOR_ATTENTION;
650 if (bounds().height() <= panel::kMinimizedPanelHeight)
651 return PAINT_AS_MINIMIZED;
652 if (panel_view_->IsPanelActive() &&
653 !panel_view_->force_to_paint_as_inactive())
654 return PAINT_AS_ACTIVE;
655 return PAINT_AS_INACTIVE;
658 SkColor PanelFrameView::GetTitleColor(PaintState paint_state) const {
659 return kTitleTextDefaultColor;
662 const gfx::ImageSkia* PanelFrameView::GetFrameBackground(
663 PaintState paint_state) const {
664 switch (paint_state) {
665 case PAINT_AS_INACTIVE:
666 return GetInactiveBackgroundDefaultImage();
667 case PAINT_AS_ACTIVE:
668 return GetActiveBackgroundDefaultImage();
669 case PAINT_AS_MINIMIZED:
670 return GetMinimizeBackgroundDefaultImage();
671 case PAINT_FOR_ATTENTION:
672 return GetAttentionBackgroundDefaultImage();
673 default:
674 NOTREACHED();
675 return GetInactiveBackgroundDefaultImage();
679 void PanelFrameView::UpdateControlStyles(PaintState paint_state) {
680 title_label_->SetEnabledColor(GetTitleColor(paint_state));
683 void PanelFrameView::PaintFrameBackground(gfx::Canvas* canvas) {
684 // We only need to paint the title-bar since no resizing border is shown.
685 // Instead, we allow part of the inner content area be used to trigger the
686 // mouse resizing.
687 int titlebar_height = TitlebarHeight();
688 const gfx::ImageSkia* image = GetFrameBackground(GetPaintState());
689 canvas->TileImageInt(*image, 0, 0, width(), titlebar_height);
691 if (is_frameless_)
692 return;
694 // Left border, below title-bar.
695 canvas->TileImageInt(*image, 0, titlebar_height, kNonAeroBorderThickness,
696 height() - titlebar_height);
698 // Right border, below title-bar.
699 canvas->TileImageInt(*image, width() - kNonAeroBorderThickness,
700 titlebar_height, kNonAeroBorderThickness, height() - titlebar_height);
702 // Bottom border.
703 canvas->TileImageInt(*image, 0, height() - kNonAeroBorderThickness, width(),
704 kNonAeroBorderThickness);
707 void PanelFrameView::PaintFrameEdge(gfx::Canvas* canvas) {
708 #if defined(OS_WIN)
709 // Border is not needed when panel is not shown as minimized.
710 if (GetPaintState() != PAINT_AS_MINIMIZED)
711 return;
713 const gfx::ImageSkia& top_left_image = GetTopLeftCornerImage(corner_style_);
714 const gfx::ImageSkia& top_right_image = GetTopRightCornerImage(corner_style_);
715 const gfx::ImageSkia& bottom_left_image =
716 GetBottomLeftCornerImage(corner_style_);
717 const gfx::ImageSkia& bottom_right_image =
718 GetBottomRightCornerImage(corner_style_);
719 const gfx::ImageSkia& top_image = GetTopEdgeImage();
720 const gfx::ImageSkia& bottom_image = GetBottomEdgeImage();
721 const gfx::ImageSkia& left_image = GetLeftEdgeImage();
722 const gfx::ImageSkia& right_image = GetRightEdgeImage();
724 // Draw the top border.
725 canvas->DrawImageInt(top_left_image, 0, 0);
726 canvas->TileImageInt(top_image,
727 top_left_image.width(),
729 width() - top_right_image.width(),
730 top_image.height());
731 canvas->DrawImageInt(top_right_image, width() - top_right_image.width(), 0);
733 // Draw the right border.
734 canvas->TileImageInt(right_image,
735 width() - right_image.width(),
736 top_right_image.height(),
737 right_image.width(),
738 height() - top_right_image.height() -
739 bottom_right_image.height());
741 // Draw the bottom border.
742 canvas->DrawImageInt(bottom_right_image,
743 width() - bottom_right_image.width(),
744 height() - bottom_right_image.height());
745 canvas->TileImageInt(bottom_image,
746 bottom_left_image.width(),
747 height() - bottom_image.height(),
748 width() - bottom_left_image.width() -
749 bottom_right_image.width(),
750 bottom_image.height());
751 canvas->DrawImageInt(bottom_left_image,
753 height() - bottom_left_image.height());
755 // Draw the left border.
756 canvas->TileImageInt(left_image,
758 top_left_image.height(),
759 left_image.width(),
760 height() - top_left_image.height() -
761 bottom_left_image.height());
762 #endif