panel_view.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/panels/panel_view.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_command_ids.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/panels/panel.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/panels/panel_bounds_animation.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/panels/panel_manager.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/panels/panel_frame_view.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host_view.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_view.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/path.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/image_button.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/webview/webview.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_ASH) && !defined(USE_AURA)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/shell_integration.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/panels/taskbar_window_thumbnailer_win.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/win/shell.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/icon_util.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Supported accelerators.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: We can't use the acclerator table defined in chrome/browser/ui/views
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// due to checkdeps violation.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AcceleratorMapping {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::KeyboardCode keycode;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int modifiers;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int command_id;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const AcceleratorMapping kPanelAcceleratorMap[] = {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_W, ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW },
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW },
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_F4, ui::EF_ALT_DOWN, IDC_CLOSE_WINDOW },
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_R, ui::EF_CONTROL_DOWN, IDC_RELOAD },
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_F5, ui::EF_NONE, IDC_RELOAD },
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_R, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDC_RELOAD_IGNORING_CACHE },
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_F5, ui::EF_CONTROL_DOWN, IDC_RELOAD_IGNORING_CACHE },
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_F5, ui::EF_SHIFT_DOWN, IDC_RELOAD_IGNORING_CACHE },
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_ESCAPE, ui::EF_NONE, IDC_STOP },
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_OEM_MINUS, ui::EF_CONTROL_DOWN, IDC_ZOOM_MINUS },
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_SUBTRACT, ui::EF_CONTROL_DOWN, IDC_ZOOM_MINUS },
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_0, ui::EF_CONTROL_DOWN, IDC_ZOOM_NORMAL },
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_NUMPAD0, ui::EF_CONTROL_DOWN, IDC_ZOOM_NORMAL },
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_OEM_PLUS, ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS },
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_ADD, ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS },
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_I, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_DEV_TOOLS },
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_J, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDC_DEV_TOOLS_CONSOLE },
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::map<ui::Accelerator, int>& GetAcceleratorTable() {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::map<ui::Accelerator, int>* accelerators = NULL;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!accelerators) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    accelerators = new std::map<ui::Accelerator, int>();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < arraysize(kPanelAcceleratorMap); ++i) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::Accelerator accelerator(kPanelAcceleratorMap[i].keycode,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  kPanelAcceleratorMap[i].modifiers);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*accelerators)[accelerator] = kPanelAcceleratorMap[i].command_id;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *accelerators;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativePanelTesting implementation.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NativePanelTestingWin : public NativePanelTesting {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit NativePanelTestingWin(PanelView* panel_view);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void PressLeftMouseButtonTitlebar(
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const gfx::Point& mouse_location, panel::ClickModifier modifier) OVERRIDE;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ReleaseMouseButtonTitlebar(
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      panel::ClickModifier modifier) OVERRIDE;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DragTitlebar(const gfx::Point& mouse_location) OVERRIDE;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CancelDragTitlebar() OVERRIDE;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void FinishDragTitlebar() OVERRIDE;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool VerifyDrawingAttention() const OVERRIDE;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool VerifyActiveState(bool is_active) OVERRIDE;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool VerifyAppIcon() const OVERRIDE;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsWindowSizeKnown() const OVERRIDE;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsAnimatingBounds() const OVERRIDE;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsButtonVisible(
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      panel::TitlebarButtonType button_type) const OVERRIDE;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PanelView* panel_view_;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativePanelTestingWin::NativePanelTestingWin(PanelView* panel_view)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : panel_view_(panel_view) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativePanelTestingWin::PressLeftMouseButtonTitlebar(
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Point& mouse_location, panel::ClickModifier modifier) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_view_->OnTitlebarMousePressed(mouse_location);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativePanelTestingWin::ReleaseMouseButtonTitlebar(
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel::ClickModifier modifier) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_view_->OnTitlebarMouseReleased(modifier);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativePanelTestingWin::DragTitlebar(const gfx::Point& mouse_location) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_view_->OnTitlebarMouseDragged(mouse_location);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativePanelTestingWin::CancelDragTitlebar() {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_view_->OnTitlebarMouseCaptureLost();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativePanelTestingWin::FinishDragTitlebar() {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_view_->OnTitlebarMouseReleased(panel::NO_MODIFIER);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativePanelTestingWin::VerifyDrawingAttention() const {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return panel_view_->GetFrameView()->paint_state() ==
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         PanelFrameView::PAINT_FOR_ATTENTION;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativePanelTestingWin::VerifyActiveState(bool is_active) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return panel_view_->GetFrameView()->paint_state() ==
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         (is_active ? PanelFrameView::PAINT_AS_ACTIVE
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    : PanelFrameView::PAINT_AS_INACTIVE);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativePanelTestingWin::VerifyAppIcon() const {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_AURA)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We only care about Windows 7 and later.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::win::GetVersion() < base::win::VERSION_WIN7)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HWND native_window = panel_view_->GetNativePanelHandle();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HICON app_icon = reinterpret_cast<HICON>(
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::SendMessage(native_window, WM_GETICON, ICON_BIG, 0L));
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!app_icon)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SkBitmap> bitmap(IconUtil::CreateSkBitmapFromHICON(app_icon));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bitmap.get() &&
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         bitmap->width() == panel::kPanelAppIconSize &&
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         bitmap->height() == panel::kPanelAppIconSize;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativePanelTestingWin::IsWindowSizeKnown() const {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativePanelTestingWin::IsAnimatingBounds() const {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return panel_view_->IsAnimatingBounds();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativePanelTestingWin::IsButtonVisible(
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel::TitlebarButtonType button_type) const {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PanelFrameView* frame_view = panel_view_->GetFrameView();
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (button_type) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case panel::CLOSE_BUTTON:
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return frame_view->close_button()->visible();
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case panel::MINIMIZE_BUTTON:
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return frame_view->minimize_button()->visible();
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case panel::RESTORE_BUTTON:
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return frame_view->restore_button()->visible();
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativePanel* Panel::CreateNativePanel(Panel* panel, const gfx::Rect& bounds) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new PanelView(panel, bounds);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The panel window has to be created as always-on-top. We cannot create it
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as non-always-on-top and then change it to always-on-top because Windows
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// system might deny making a window always-on-top if the application is not
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a foreground application. In addition, we do not know if the panel should
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be created as always-on-top at its creation time. To solve this issue,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// always_on_top_ is default to true because we can always change from
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// always-on-top to not always-on-top but not the other way around.
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PanelView::PanelView(Panel* panel, const gfx::Rect& bounds)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : panel_(panel),
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bounds_(bounds),
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_(NULL),
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_view_(NULL),
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      always_on_top_(true),
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      focused_(false),
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_pressed_(false),
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_dragging_state_(NO_DRAGGING),
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_drawing_attention_(false),
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      force_to_paint_as_inactive_(false),
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      old_focused_view_(NULL) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_ = new views::Widget;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.delegate = this;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.remove_standard_frame = true;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.keep_on_top = true;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.bounds = bounds;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->Init(params);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->set_focus_on_creation(false);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->AddObserver(this);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_view_ = new views::WebView(NULL);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddChildView(web_view_);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnViewWasResized();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Register accelarators supported by panels.
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::FocusManager* focus_manager = GetFocusManager();
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::map<ui::Accelerator, int>& accelerator_table =
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetAcceleratorTable();
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::map<ui::Accelerator, int>::const_iterator iter =
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           accelerator_table.begin();
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != accelerator_table.end(); ++iter) {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    focus_manager->RegisterAccelerator(
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        iter->first, ui::AcceleratorManager::kNormalPriority, this);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_ASH) && !defined(USE_AURA)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::win::SetAppIdForWindow(
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ShellIntegration::GetAppModelIdForProfile(UTF8ToWide(panel->app_name()),
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                panel->profile()->GetPath()),
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_->GetNativeWindow());
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PanelView::~PanelView() {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::ShowPanel() {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShowPanelInactive();
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ActivatePanel();
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Give web contents view a chance to set focus to the appropriate element
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when it is created for the first time.
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WebContents* web_contents = panel_->GetWebContents();
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_contents->GetView()->RestoreFocus();
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::ShowPanelInactive() {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (window_->IsVisible())
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->ShowInactive();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No animation is used for initial creation of a panel on Win.
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Signal immediately that pending actions can be performed.
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->manager()->OnPanelAnimationEnded(panel_.get());
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect PanelView::GetPanelBounds() const {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bounds_;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::SetPanelBounds(const gfx::Rect& bounds) {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetBoundsInternal(bounds, true);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::SetPanelBoundsInstantly(const gfx::Rect& bounds) {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetBoundsInternal(bounds, false);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::SetBoundsInternal(const gfx::Rect& new_bounds, bool animate) {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bounds_ == new_bounds)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bounds_ = new_bounds;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!animate) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If no animation is in progress, apply bounds change instantly. Otherwise,
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // continue the animation with new target bounds.
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!IsAnimatingBounds())
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetWidgetBounds(bounds_);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation_start_bounds_ = window_->GetWindowBoundsInScreen();
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bounds_animator_.reset(new PanelBoundsAnimation(
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, panel_.get(), animation_start_bounds_, new_bounds));
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bounds_animator_->Start();
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::AnimationEnded(const ui::Animation* animation) {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->manager()->OnPanelAnimationEnded(panel_.get());
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::AnimationProgressed(const ui::Animation* animation) {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect new_bounds = bounds_animator_->CurrentValueBetween(
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      animation_start_bounds_, bounds_);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetWidgetBounds(new_bounds);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::SetWidgetBounds(const gfx::Rect& new_bounds) {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_ASH) && !defined(USE_AURA)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An overlapped window is a top-level window that has a titlebar, border,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and client area. The Windows system will automatically put the shadow
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // around the whole window. Also the system will enforce the minimum height
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (38 pixels based on observation) for the overlapped window such that it
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will always has the space for the titlebar.
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // On contrast, a popup window is a bare minimum window without border and
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // titlebar by default. It is often used for the popup menu and the window
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with short life. The Windows system does not add the shadow around the
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // whole window though CS_DROPSHADOW class style could be passed to add the
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // drop shadow which is only around the right and bottom edges.
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The height of the title-only or minimized panel is smaller than the minimum
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // overlapped window height. If the panel still uses the overlapped window
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // style, Windows system will automatically increase the window height. To
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // work around this limitation, we temporarily change the window style to
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // popup when the height to set is smaller than the minimum overlapped window
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // height and then restore the window style to overlapped when the height
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // grows.
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kMinimumOverlappedWindowHeight = 38;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect old_bounds = GetWidget()->GetRestoredBounds();
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (old_bounds.height() > kMinimumOverlappedWindowHeight &&
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_bounds.height() <= kMinimumOverlappedWindowHeight) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When the panel height shrinks below the minimum overlapped window height,
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // change the window style to popup such that we can show the title-only
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // and minimized panel without additional height being added by the system.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateWindowAttribute(GWL_STYLE,
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          WS_POPUP,
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU,
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          true);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (old_bounds.height() <= kMinimumOverlappedWindowHeight &&
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             new_bounds.height() > kMinimumOverlappedWindowHeight) {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Change the window style back to overlappped when the panel height grow
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // taller than the minimum overlapped window height.
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateWindowAttribute(GWL_STYLE,
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU,
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          WS_POPUP,
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          true);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetWidget()->SetBounds(new_bounds);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::ClosePanel() {
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We're already closing. Do nothing.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!window_)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!panel_->ShouldCloseWindow())
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel any currently running animation since we're closing down.
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bounds_animator_.get())
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bounds_animator_.reset();
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (panel_->GetWebContents()) {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Still have web contents. Allow renderer to shut down.
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When web contents are destroyed, we will be called back again.
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel_->OnWindowClosing();
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->OnNativePanelClosed();
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->Close();
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_ = NULL;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::ActivatePanel() {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->Activate();
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::DeactivatePanel() {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!focused_)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(AURA) && !defined(USE_ASH)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need custom behavior for always-on-top panels to avoid
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the OS activating a minimized panel when this one is
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deactivated.
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (always_on_top_) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::SetForegroundWindow(::GetDesktopWindow());
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->Deactivate();
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::IsPanelActive() const {
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return focused_;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::PreventActivationByOS(bool prevent_activation) {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_ASH) && !defined(USE_AURA)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the flags "NoActivate" and "AppWindow" to make sure
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the minimized panels do not get activated by the OS, but
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // do appear in the taskbar and Alt-Tab menu.
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int value_to_change = WS_EX_NOACTIVATE | WS_EX_APPWINDOW;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (prevent_activation)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateWindowAttribute(GWL_EXSTYLE, value_to_change, 0, false);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateWindowAttribute(GWL_EXSTYLE, 0, value_to_change, false);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::NativeWindow PanelView::GetNativePanelHandle() {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return window_->GetNativeWindow();
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::UpdatePanelTitleBar() {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateWindowTitle();
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateWindowIcon();
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::UpdatePanelLoadingAnimations(bool should_animate) {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetFrameView()->UpdateThrobber();
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::NotifyPanelOnUserChangedTheme() {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetFrameView()->SchedulePaint();
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::PanelWebContentsFocused(content::WebContents* contents) {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_view_->OnWebContentsFocused(contents);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::PanelCut() {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing to do since we do not have panel-specific system menu.
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::PanelCopy() {
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing to do since we do not have panel-specific system menu.
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::PanelPaste() {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing to do since we do not have panel-specific system menu.
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::DrawAttention(bool draw_attention) {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK((panel_->attention_mode() & Panel::USE_PANEL_ATTENTION) != 0);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_drawing_attention_ == draw_attention)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_drawing_attention_ = draw_attention;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetFrameView()->SchedulePaint();
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((panel_->attention_mode() & Panel::USE_SYSTEM_ATTENTION) != 0)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window_->FlashFrame(draw_attention);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::IsDrawingAttention() const {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return is_drawing_attention_;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::HandlePanelKeyboardEvent(
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NativeWebKeyboardEvent& event) {
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::FocusManager* focus_manager = GetFocusManager();
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (focus_manager->shortcut_handling_suspended())
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::Accelerator accelerator(
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<ui::KeyboardCode>(event.windowsKeyCode),
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::GetModifiersFromNativeWebKeyboardEvent(event));
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (event.type == WebKit::WebInputEvent::KeyUp)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    accelerator.set_type(ui::ET_KEY_RELEASED);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  focus_manager->ProcessAccelerator(accelerator);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::FullScreenModeChanged(bool is_full_screen) {
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_full_screen) {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (window_->IsVisible())
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_->Hide();
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShowPanelInactive();
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::IsPanelAlwaysOnTop() const {
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return always_on_top_;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::SetPanelAlwaysOnTop(bool on_top) {
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (always_on_top_ == on_top)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  always_on_top_ = on_top;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetAlwaysOnTop(on_top);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->non_client_view()->Layout();
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->client_view()->Layout();
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::EnableResizeByMouse(bool enable) {
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing to do since we use system resizing.
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::UpdatePanelMinimizeRestoreButtonVisibility() {
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetFrameView()->UpdateTitlebarMinimizeRestoreButtonVisibility();
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::PanelExpansionStateChanging(Panel::ExpansionState old_state,
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            Panel::ExpansionState new_state) {
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_ASH) && !defined(USE_AURA)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Live preview is only available since Windows 7.
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::win::GetVersion() < base::win::VERSION_WIN7)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_minimized = old_state != Panel::EXPANDED;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool will_be_minimized = new_state != Panel::EXPANDED;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_minimized == will_be_minimized)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HWND native_window = window_->GetNativeWindow();
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!thumbnailer_.get()) {
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(native_window);
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    thumbnailer_.reset(new TaskbarWindowThumbnailerWin(native_window));
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::HWNDSubclass::AddFilterToTarget(native_window, thumbnailer_.get());
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cache the image at this point.
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (will_be_minimized) {
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the panel is still active (we will deactivate the minimizd panel at
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // later time), we need to paint it immediately as inactive so that we can
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // take a snapshot of inactive panel.
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (focused_) {
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      force_to_paint_as_inactive_ = true;
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::RedrawWindow(native_window, NULL, NULL,
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     RDW_NOCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW);
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    thumbnailer_->Start();
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    force_to_paint_as_inactive_ = false;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    thumbnailer_->Stop();
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size PanelView::WindowSizeFromContentSize(
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& content_size) const {
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size frame = GetFrameView()->NonClientAreaSize();
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size(content_size.width() + frame.width(),
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   content_size.height() + frame.height());
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size PanelView::ContentSizeFromWindowSize(
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& window_size) const {
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size frame = GetFrameView()->NonClientAreaSize();
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size(window_size.width() - frame.width(),
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   window_size.height() - frame.height());
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int PanelView::TitleOnlyHeight() const {
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return panel::kTitlebarHeight;
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::AttachWebContents(content::WebContents* contents) {
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_view_->SetWebContents(contents);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::DetachWebContents(content::WebContents* contents) {
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_view_->SetWebContents(NULL);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativePanelTesting* PanelView::CreateNativePanelTesting() {
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new NativePanelTestingWin(this);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::OnDisplayChanged() {
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->manager()->display_settings_provider()->OnDisplaySettingsChanged();
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::OnWorkAreaChanged() {
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->manager()->display_settings_provider()->OnDisplaySettingsChanged();
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::WillProcessWorkAreaChange() const {
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* PanelView::GetContentsView() {
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::NonClientFrameView* PanelView::CreateNonClientFrameView(
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    views::Widget* widget) {
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PanelFrameView* frame_view = new PanelFrameView(this);
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frame_view->Init();
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return frame_view;
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::CanResize() const {
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::CanMaximize() const {
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 PanelView::GetWindowTitle() const {
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return panel_->GetWindowTitle();
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkia PanelView::GetWindowAppIcon() {
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Image app_icon = panel_->app_icon();
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (app_icon.IsEmpty())
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetWindowIcon();
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return *app_icon.ToImageSkia();
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkia PanelView::GetWindowIcon() {
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Image icon = panel_->GetCurrentPageIcon();
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return icon.IsEmpty() ? gfx::ImageSkia() : *icon.ToImageSkia();
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::WindowClosing() {
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When closing a panel via window.close, API or the close button,
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ClosePanel() is called first, destroying the native |window_|
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which results in this method being called. ClosePanel() sets
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |window_| to NULL.
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we still have a |window_| here, the close was triggered by the OS,
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (e.g. clicking on taskbar menu), which destroys the native |window_|
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // without invoking ClosePanel() beforehand.
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (window_) {
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel_->OnWindowClosing();
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClosePanel();
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!window_);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::DeleteDelegate() {
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::OnWindowBeginUserBoundsChange() {
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->OnPanelStartUserResizing();
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::OnWindowEndUserBoundsChange() {
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->OnPanelEndUserResizing();
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No need to proceed with post-resizing update when there is no size change.
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect new_bounds = window_->GetWindowBoundsInScreen();
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bounds_ == new_bounds)
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bounds_ = new_bounds;
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->IncreaseMaxSize(bounds_.size());
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->set_full_size(bounds_.size());
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->panel_strip()->RefreshLayout();
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::Widget* PanelView::GetWidget() {
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return window_;
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const views::Widget* PanelView::GetWidget() const {
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return window_;
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::UpdateLoadingAnimations(bool should_animate) {
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetFrameView()->UpdateThrobber();
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::UpdateWindowTitle() {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->UpdateWindowTitle();
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetFrameView()->UpdateTitle();
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::UpdateWindowIcon() {
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->UpdateWindowIcon();
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetFrameView()->UpdateIcon();
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::Layout() {
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |web_view_| might not be created yet when the window is first created.
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_view_)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_view_->SetBounds(0, 0, width(), height());
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnViewWasResized();
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size PanelView::GetMinimumSize() {
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size();
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size PanelView::GetMaximumSize() {
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size();
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::AcceleratorPressed(const ui::Accelerator& accelerator) {
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_pressed_ && accelerator.key_code() == ui::VKEY_ESCAPE) {
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnTitlebarMouseCaptureLost();
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No other accelerator is allowed when the drag begins.
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_dragging_state_ == DRAGGING_STARTED)
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::map<ui::Accelerator, int>& accelerator_table =
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetAcceleratorTable();
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<ui::Accelerator, int>::const_iterator iter =
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      accelerator_table.find(accelerator);
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(iter != accelerator_table.end());
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return panel_->ExecuteCommandIfEnabled(iter->second);
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::OnWidgetActivationChanged(views::Widget* widget, bool active) {
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_AURA)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The panel window is in focus (actually accepting keystrokes) if it is
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // active and belongs to a foreground application.
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool focused = active && widget->GetNativeWindow() == ::GetForegroundWindow();
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTIMPLEMENTED();
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool focused = active;
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (focused_ == focused)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  focused_ = focused;
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Expand the panel if the minimized panel is activated by means other than
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // clicking on its titlebar. This is the workaround to support restoring the
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // minimized panel by other means, like alt-tabbing, win-tabbing, or clicking
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the taskbar icon. Note that this workaround does not work for one edge
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // case: the mouse happens to be at the minimized panel when the user tries to
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bring up the panel with the above alternatives.
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When the user clicks on the minimized panel, the panel expansion will be
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // done when we process the mouse button pressed message.
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (focused_ && panel_->IsMinimized() &&
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Screen::GetScreenFor(widget->GetNativeWindow())->
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          GetWindowAtCursorScreenPoint() != widget->GetNativeWindow()) {
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel_->Restore();
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel()->OnActiveStateChanged(focused);
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::OnTitlebarMousePressed(const gfx::Point& mouse_location) {
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_pressed_ = true;
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_dragging_state_ = NO_DRAGGING;
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_mouse_location_ = mouse_location;
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::OnTitlebarMouseDragged(const gfx::Point& mouse_location) {
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!mouse_pressed_)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_dragging_state_ == NO_DRAGGING &&
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ExceededDragThreshold(mouse_location - last_mouse_location_)) {
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When a drag begins, we do not want to the client area to still receive
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the focus. We do not need to do this for the unfocused minimized panel.
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!panel_->IsMinimized()) {
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      old_focused_view_ = GetFocusManager()->GetFocusedView();
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetFocusManager()->SetFocusedView(GetFrameView());
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel_->manager()->StartDragging(panel_.get(), last_mouse_location_);
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mouse_dragging_state_ = DRAGGING_STARTED;
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_dragging_state_ == DRAGGING_STARTED) {
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel_->manager()->Drag(mouse_location);
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Once in drag, update |last_mouse_location_| on each drag fragment, since
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we already dragged the panel up to the current mouse location.
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_mouse_location_ = mouse_location;
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::OnTitlebarMouseReleased(panel::ClickModifier modifier) {
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_dragging_state_ != NO_DRAGGING) {
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ensure dragging a minimized panel does not leave it activated.
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Windows activates a panel on mouse-down, regardless of our attempts
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to prevent activation of a minimized panel. Now that we know mouse-down
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // resulted in a mouse-drag, we need to ensure the minimized panel is
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // deactivated.
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (panel_->IsMinimized() && focused_)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      panel_->Deactivate();
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mouse_dragging_state_ == DRAGGING_STARTED) {
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // When a drag ends, restore the focus.
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (old_focused_view_) {
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetFocusManager()->SetFocusedView(old_focused_view_);
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        old_focused_view_ = NULL;
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return EndDragging(false);
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The panel drag was cancelled before the mouse is released. Do not
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // treat this as a click.
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->OnTitlebarClicked(modifier);
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::OnTitlebarMouseCaptureLost() {
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_dragging_state_ == DRAGGING_STARTED)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return EndDragging(true);
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::EndDragging(bool cancelled) {
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only handle clicks that started in our window.
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!mouse_pressed_)
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_pressed_ = false;
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_dragging_state_ = DRAGGING_ENDED;
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->manager()->EndDragging(cancelled);
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PanelFrameView* PanelView::GetFrameView() const {
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<PanelFrameView*>(window_->non_client_view()->frame_view());
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::IsAnimatingBounds() const {
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bounds_animator_.get() && bounds_animator_->is_animating();
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::IsWithinResizingArea(const gfx::Point& mouse_location) const {
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect bounds = window_->GetWindowBoundsInScreen();
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bounds.Contains(mouse_location));
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return mouse_location.x() < bounds.x() + kResizeInsideBoundsSize ||
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         mouse_location.x() >= bounds.right() - kResizeInsideBoundsSize ||
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         mouse_location.y() < bounds.y() + kResizeInsideBoundsSize ||
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         mouse_location.y() >= bounds.bottom() - kResizeInsideBoundsSize;
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_ASH) && !defined(USE_AURA)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::UpdateWindowAttribute(int attribute_index,
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int attribute_value_to_set,
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int attribute_value_to_reset,
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      bool update_frame) {
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::NativeWindow native_window = window_->GetNativeWindow();
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int value = ::GetWindowLong(native_window, attribute_index);
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int expected_value = value;
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (attribute_value_to_set)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expected_value |=  attribute_value_to_set;
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (attribute_value_to_reset)
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expected_value &=  ~attribute_value_to_reset;
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value != expected_value)
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::SetWindowLong(native_window, attribute_index, expected_value);
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Per MSDN, if any of the frame styles is changed, SetWindowPos with the
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SWP_FRAMECHANGED flag must be called in order for the cached window data
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to be updated properly.
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // http://msdn.microsoft.com/en-us/library/windows/desktop/ms633591(v=vs.85).aspx
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (update_frame) {
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::SetWindowPos(native_window, NULL, 0, 0, 0, 0,
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE |
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       SWP_NOZORDER | SWP_NOACTIVATE);
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::OnViewWasResized() {
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_ASH) && !defined(USE_AURA)
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WebContents* web_contents = panel_->GetWebContents();
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!web_view_ || !web_contents)
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When the panel is frameless or has thin frame, the mouse resizing should
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // also be triggered from the part of client area that is close to the window
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // frame.
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int width = web_view_->size().width();
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int height = web_view_->size().height();
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Compute the thickness of the client area that needs to be counted towards
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mouse resizing.
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int thickness_for_mouse_resizing =
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kResizeInsideBoundsSize - GetFrameView()->BorderThickness();
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thickness_for_mouse_resizing > 0);
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRegion* region = new SkRegion;
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  region->op(0, 0, thickness_for_mouse_resizing, height, SkRegion::kUnion_Op);
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  region->op(width - thickness_for_mouse_resizing, 0, width, height,
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkRegion::kUnion_Op);
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  region->op(0, height - thickness_for_mouse_resizing, width, height,
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkRegion::kUnion_Op);
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_contents->GetRenderViewHost()->GetView()->SetClickthroughRegion(region);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
906