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