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/panels/panel.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_command_ids.h"
117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/devtools/devtools_window.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/tabs/tabs_constants.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/tabs/tabs_windows_api.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/tabs/windows_event_router.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_tab_util.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/window_controller.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/window_controller_list.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/lifetime/application_lifetime.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/sessions/session_tab_helper.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/themes/theme_service.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/themes/theme_service_factory.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/panels/native_panel.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/panel_collection.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/panels/panel_host.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/panels/panel_manager.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/stacked_panel_collection.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/web_applications/web_app.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/extension_registry.h"
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "extensions/browser/image_loader.h"
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/common/constants.h"
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/manifest_handlers/icons_handler.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UserMetricsAction;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace panel_internal {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PanelExtensionWindowController : public extensions::WindowController {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PanelExtensionWindowController(Panel* panel, Profile* profile);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~PanelExtensionWindowController();
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from extensions::WindowController.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetWindowId() const OVERRIDE;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual std::string GetWindowTypeText() const OVERRIDE;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual base::DictionaryValue* CreateWindowValueWithTabs(
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const extensions::Extension* extension) const OVERRIDE;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual base::DictionaryValue* CreateTabValue(
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const extensions::Extension* extension, int tab_index) const OVERRIDE;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool CanClose(Reason* reason) const OVERRIDE;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetFullscreenMode(bool is_fullscreen,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const GURL& extension_url) const OVERRIDE;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsVisibleToExtension(
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const extensions::Extension* extension) const OVERRIDE;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Panel* panel_;  // Weak pointer. Owns us.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PanelExtensionWindowController);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PanelExtensionWindowController::PanelExtensionWindowController(
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Panel* panel, Profile* profile)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : extensions::WindowController(panel, profile),
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      panel_(panel) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions::WindowControllerList::GetInstance()->AddExtensionWindow(this);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PanelExtensionWindowController::~PanelExtensionWindowController() {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions::WindowControllerList::GetInstance()->RemoveExtensionWindow(this);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int PanelExtensionWindowController::GetWindowId() const {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<int>(panel_->session_id().id());
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string PanelExtensionWindowController::GetWindowTypeText() const {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extensions::tabs_constants::kWindowTypeValuePanel;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::DictionaryValue*
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PanelExtensionWindowController::CreateWindowValueWithTabs(
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const extensions::Extension* extension) const {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::DictionaryValue* result = CreateWindowValue();
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsVisibleToExtension(extension));
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue* tab_value = CreateTabValue(extension, 0);
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (tab_value) {
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::ListValue* tab_list = new base::ListValue();
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tab_list->Append(tab_value);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result->Set(extensions::tabs_constants::kTabsKey, tab_list);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::DictionaryValue* PanelExtensionWindowController::CreateTabValue(
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const extensions::Extension* extension, int tab_index) const {
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (tab_index > 0)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* web_contents = panel_->GetWebContents();
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!web_contents)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsVisibleToExtension(extension));
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue* tab_value = new base::DictionaryValue();
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_value->SetInteger(extensions::tabs_constants::kIdKey,
12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                        SessionTabHelper::IdForTab(web_contents));
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_value->SetInteger(extensions::tabs_constants::kIndexKey, 0);
12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  tab_value->SetInteger(
12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      extensions::tabs_constants::kWindowIdKey,
12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      SessionTabHelper::IdForWindowContainingTab(web_contents));
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_value->SetString(
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::tabs_constants::kUrlKey, web_contents->GetURL().spec());
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_value->SetString(extensions::tabs_constants::kStatusKey,
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       extensions::ExtensionTabUtil::GetTabStatusText(
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           web_contents->IsLoading()));
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_value->SetBoolean(
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::tabs_constants::kActiveKey, panel_->IsActive());
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_value->SetBoolean(extensions::tabs_constants::kSelectedKey, true);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_value->SetBoolean(extensions::tabs_constants::kHighlightedKey, true);
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_value->SetBoolean(extensions::tabs_constants::kPinnedKey, false);
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_value->SetString(
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::tabs_constants::kTitleKey, web_contents->GetTitle());
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_value->SetBoolean(
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::tabs_constants::kIncognitoKey,
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      web_contents->GetBrowserContext()->IsOffTheRecord());
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return tab_value;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelExtensionWindowController::CanClose(Reason* reason) const {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelExtensionWindowController::SetFullscreenMode(
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_fullscreen, const GURL& extension_url) const {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do nothing. Panels cannot be fullscreen.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelExtensionWindowController::IsVisibleToExtension(
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const extensions::Extension* extension) const {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extension->id() == panel_->extension_id();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace panel_internal
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Panel::~Panel() {
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!collection_);
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(USE_AURA)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoked by native panel destructor. Do not access native_panel_ here.
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  chrome::DecrementKeepAliveCount();  // Remove shutdown prevention.
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PanelManager* Panel::manager() const {
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PanelManager::GetInstance();
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const std::string Panel::extension_id() const {
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return web_app::GetExtensionIdFromApplicationName(app_name_);
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CommandUpdater* Panel::command_updater() {
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return &command_updater_;
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Profile* Panel::profile() const {
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return profile_;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const extensions::Extension* Panel::GetExtension() const {
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionService* extension_service =
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::ExtensionSystem::Get(profile())->extension_service();
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!extension_service || !extension_service->is_ready())
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return extension_service->GetExtensionById(extension_id(), false);
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)content::WebContents* Panel::GetWebContents() const {
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return panel_host_.get() ? panel_host_->web_contents() : NULL;
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::SetExpansionState(ExpansionState new_state) {
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (expansion_state_ == new_state)
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  native_panel_->PanelExpansionStateChanging(expansion_state_, new_state);
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expansion_state_ = new_state;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager()->OnPanelExpansionStateChanged(this);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(initialized_ && collection_ != NULL);
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  native_panel_->PreventActivationByOS(collection_->IsPanelMinimized(this));
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateMinimizeRestoreButtonVisibility();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::NotificationService::current()->Notify(
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      chrome::NOTIFICATION_PANEL_CHANGED_EXPANSION_STATE,
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::Source<Panel>(this),
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::NotificationService::NoDetails());
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Panel::IsDrawingAttention() const {
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return native_panel_->IsDrawingAttention();
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::FullScreenModeChanged(bool is_full_screen) {
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  native_panel_->FullScreenModeChanged(is_full_screen);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int Panel::TitleOnlyHeight() const {
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return native_panel_->TitleOnlyHeight();
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Panel::CanShowMinimizeButton() const {
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return collection_ && collection_->CanShowMinimizeButton(this);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Panel::CanShowRestoreButton() const {
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return collection_ && collection_->CanShowRestoreButton(this);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Panel::IsActive() const {
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return native_panel_->IsPanelActive();
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Panel::IsMaximized() const {
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Size of panels is managed by PanelManager, they are never 'zoomed'.
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Panel::IsMinimized() const {
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !collection_ || collection_->IsPanelMinimized(this);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Panel::IsFullscreen() const {
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::NativeWindow Panel::GetNativeWindow() {
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return native_panel_->GetNativePanelWindow();
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Rect Panel::GetRestoredBounds() const {
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect bounds = native_panel_->GetPanelBounds();
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bounds.set_y(bounds.bottom() - full_size_.height());
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bounds.set_x(bounds.right() - full_size_.width());
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bounds.set_size(full_size_);
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return bounds;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
262b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)ui::WindowShowState Panel::GetRestoredState() const {
263b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return ui::SHOW_STATE_NORMAL;
264b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
265b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Rect Panel::GetBounds() const {
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return native_panel_->GetPanelBounds();
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::Show() {
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (manager()->display_settings_provider()->is_full_screen() || !collection_)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  native_panel_->ShowPanel();
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::Hide() {
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Not implemented.
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::ShowInactive() {
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (manager()->display_settings_provider()->is_full_screen() || !collection_)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  native_panel_->ShowPanelInactive();
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Close() may be called multiple times if the panel window is not ready to
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// close on the first attempt.
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::Close() {
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  native_panel_->ClosePanel();
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::Activate() {
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!collection_)
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  collection_->ActivatePanel(this);
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  native_panel_->ActivatePanel();
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::Deactivate() {
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  native_panel_->DeactivatePanel();
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::Maximize() {
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Restore();
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::Minimize() {
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (collection_)
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    collection_->MinimizePanel(this);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Panel::IsMinimizedBySystem() const {
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return native_panel_->IsPanelMinimizedBySystem();
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool Panel::IsShownOnActiveDesktop() const {
3202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return native_panel_->IsPanelShownOnActiveDesktop();
3212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
3222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Panel::ShowShadow(bool show) {
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  native_panel_->ShowShadow(show);
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::Restore() {
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (collection_)
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    collection_->RestorePanel(this);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::SetBounds(const gfx::Rect& bounds) {
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ignore bounds position as the panel manager controls all positioning.
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!collection_)
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  collection_->ResizePanelWindow(this, bounds.size());
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetAutoResizable(false);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::FlashFrame(bool draw_attention) {
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsDrawingAttention() == draw_attention || !collection_)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't draw attention for an active panel.
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (draw_attention && IsActive())
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invoking native panel to draw attention must be done before informing the
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // panel collection because it needs to check internal state of the panel to
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // determine if the panel has been drawing attention.
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  native_panel_->DrawAttention(draw_attention);
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  collection_->OnPanelAttentionStateChanged(this);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Panel::IsAlwaysOnTop() const {
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return native_panel_->IsPanelAlwaysOnTop();
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Panel::SetAlwaysOnTop(bool on_top) {
3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  native_panel_->SetPanelAlwaysOnTop(on_top);
3614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::ExecuteCommandWithDisposition(int id,
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          WindowOpenDisposition disposition) {
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command "
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                << id;
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetWebContents())
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (id) {
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Navigation
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDC_RELOAD:
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      panel_host_->Reload();
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDC_RELOAD_IGNORING_CACHE:
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      panel_host_->ReloadIgnoringCache();
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDC_STOP:
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      panel_host_->StopLoading();
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Window management
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDC_CLOSE_WINDOW:
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::RecordAction(UserMetricsAction("CloseWindow"));
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Close();
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDC_EXIT:
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::RecordAction(UserMetricsAction("Exit"));
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      chrome::AttemptUserExit();
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Clipboard
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDC_COPY:
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::RecordAction(UserMetricsAction("Copy"));
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      native_panel_->PanelCopy();
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDC_CUT:
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::RecordAction(UserMetricsAction("Cut"));
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      native_panel_->PanelCut();
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDC_PASTE:
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::RecordAction(UserMetricsAction("Paste"));
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      native_panel_->PanelPaste();
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Zoom
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDC_ZOOM_PLUS:
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      panel_host_->Zoom(content::PAGE_ZOOM_IN);
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDC_ZOOM_NORMAL:
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      panel_host_->Zoom(content::PAGE_ZOOM_RESET);
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDC_ZOOM_MINUS:
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      panel_host_->Zoom(content::PAGE_ZOOM_OUT);
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // DevTools
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDC_DEV_TOOLS:
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
4216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      DevToolsWindow::OpenDevToolsWindow(GetWebContents(),
4226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                         DevToolsToggleAction::Show());
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case IDC_DEV_TOOLS_CONSOLE:
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
4266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      DevToolsWindow::OpenDevToolsWindow(GetWebContents(),
4276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                         DevToolsToggleAction::ShowConsole());
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(WARNING) << "Received unimplemented command: " << id;
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::Observe(int type,
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const content::NotificationSource& source,
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const content::NotificationDetails& details) {
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (type) {
4404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED:
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ConfigureAutoResize(content::Source<content::WebContents>(source).ptr());
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case chrome::NOTIFICATION_APP_TERMINATING:
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Close();
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED() << "Received unexpected notification " << type;
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid Panel::OnExtensionUnloaded(
4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    content::BrowserContext* browser_context,
4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const extensions::Extension* extension,
4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    extensions::UnloadedExtensionInfo::Reason reason) {
4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (extension->id() == extension_id())
4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Close();
4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::OnTitlebarClicked(panel::ClickModifier modifier) {
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (collection_)
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    collection_->OnPanelTitlebarClicked(this, modifier);
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Normally the system activates a window when the titlebar is clicked.
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // However, we prevent system activation of minimized panels, thus the
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // activation may not have occurred. Also, some OSes (Windows) will
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // activate a minimized panel on mouse-down regardless of our attempts to
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // prevent system activation. Attention state is not cleared in that case.
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // See Panel::OnActiveStateChanged().
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Therefore, we ensure activation and clearing of attention state if the
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // panel has been expanded. If the panel is in a stack, the titlebar click
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // might minimize the panel and we do not want to activate it to make it
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // expand again.
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These are no-ops if no changes are needed.
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsMinimized())
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Activate();
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FlashFrame(false);
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::OnMinimizeButtonClicked(panel::ClickModifier modifier) {
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (collection_)
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    collection_->OnMinimizeButtonClicked(this, modifier);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::OnRestoreButtonClicked(panel::ClickModifier modifier) {
485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Clicking the restore button has the same behavior as clicking the titlebar.
486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  OnTitlebarClicked(modifier);
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::OnWindowSizeAvailable() {
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ConfigureAutoResize(GetWebContents());
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::OnNativePanelClosed() {
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ensure previously enqueued OnImageLoaded callbacks are ignored.
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  image_loader_ptr_factory_.InvalidateWeakPtrs();
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registrar_.RemoveAll();
4971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  extension_registry_->RemoveObserver(this);
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager()->OnPanelClosed(this);
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!collection_);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StackedPanelCollection* Panel::stack() const {
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return collection_ && collection_->type() == PanelCollection::STACKED ?
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<StackedPanelCollection*>(collection_) : NULL;
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)panel::Resizability Panel::CanResizeByMouse() const {
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!collection_)
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return panel::NOT_RESIZABLE;
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return collection_->GetPanelResizability(this);
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void Panel::Initialize(const GURL& url,
51590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       const gfx::Rect& bounds,
51690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       bool always_on_top) {
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!initialized_);
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!collection_);  // Cannot be added to a collection until fully created.
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(EXPANDED, expansion_state_);
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!bounds.IsEmpty());
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  initialized_ = true;
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  full_size_ = bounds.size();
52390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  native_panel_ = CreateNativePanel(this, bounds, always_on_top);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extension_window_controller_.reset(
526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new panel_internal::PanelExtensionWindowController(this, profile_));
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitCommandState();
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set up hosting for web contents.
531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  panel_host_.reset(new PanelHost(this, profile_));
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  panel_host_->Init(url);
533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::WebContents* web_contents = GetWebContents();
534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The contents might be NULL for most of our tests.
535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (web_contents)
536868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    native_panel_->AttachWebContents(web_contents);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Close when the extension is unloaded or the browser is exiting.
5391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  extension_registry_->AddObserver(this);
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 content::NotificationService::AllSources());
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 content::Source<ThemeService>(
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    ThemeServiceFactory::GetForProfile(profile_)));
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(USE_AURA)
547a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Keep alive for AURA has been moved to panel_view.
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Prevent the browser process from shutting down while this window is open.
549a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  chrome::IncrementKeepAliveCount();
550a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAppIcon();
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::SetPanelBounds(const gfx::Rect& bounds) {
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (bounds != native_panel_->GetPanelBounds())
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    native_panel_->SetPanelBounds(bounds);
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::SetPanelBoundsInstantly(const gfx::Rect& bounds) {
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  native_panel_->SetPanelBoundsInstantly(bounds);
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::LimitSizeToWorkArea(const gfx::Rect& work_area) {
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int max_width = manager()->GetMaxPanelWidth(work_area);
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int max_height = manager()->GetMaxPanelHeight(work_area);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the custom max size is used, ensure that it does not exceed the display
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // area.
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (max_size_policy_ == CUSTOM_MAX_SIZE) {
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int current_max_width = max_size_.width();
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (current_max_width > max_width)
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      max_width = std::min(current_max_width, work_area.width());
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int current_max_height = max_size_.height();
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (current_max_height > max_height)
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      max_height = std::min(current_max_height, work_area.height());
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetSizeRange(min_size_, gfx::Size(max_width, max_height));
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ensure that full size does not exceed max size.
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  full_size_ = ClampSize(full_size_);
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::SetAutoResizable(bool resizable) {
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (auto_resizable_ == resizable)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  auto_resizable_ = resizable;
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* web_contents = GetWebContents();
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (auto_resizable_) {
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (web_contents)
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EnableWebContentsAutoResize(web_contents);
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (web_contents) {
5964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      registrar_.Remove(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        content::Source<content::WebContents>(web_contents));
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // NULL might be returned if the tab has not been added.
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RenderViewHost* render_view_host = web_contents->GetRenderViewHost();
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (render_view_host)
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        render_view_host->DisableAutoResize(full_size_);
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Panel::EnableWebContentsAutoResize(content::WebContents* web_contents) {
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(web_contents);
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConfigureAutoResize(web_contents);
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We also need to know when the render view host changes in order
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to turn on auto-resize notifications in the new render view host.
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!registrar_.IsRegistered(
6144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          content::Source<content::WebContents>(web_contents))) {
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    registrar_.Add(
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this,
6184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Source<content::WebContents>(web_contents));
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::OnContentsAutoResized(const gfx::Size& new_content_size) {
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(auto_resizable_);
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!collection_)
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size new_window_size =
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      native_panel_->WindowSizeFromContentSize(new_content_size);
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ignore content auto resizes until window frame size is known.
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This reduces extra resizes when panel is first shown.
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // After window frame size is known, it will trigger another content
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // auto resize.
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (new_content_size == new_window_size)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  collection_->ResizePanelWindow(this, new_window_size);
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::OnWindowResizedByMouse(const gfx::Rect& new_bounds) {
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (collection_)
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    collection_->OnPanelResizedByMouse(this, new_bounds);
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::SetSizeRange(const gfx::Size& min_size, const gfx::Size& max_size) {
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (min_size == min_size_ && max_size == max_size_)
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(min_size.width() <= max_size.width());
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(min_size.height() <= max_size.height());
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  min_size_ = min_size;
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  max_size_ = max_size;
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ConfigureAutoResize(GetWebContents());
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::IncreaseMaxSize(const gfx::Size& desired_panel_size) {
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size new_max_size = max_size_;
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (new_max_size.width() < desired_panel_size.width())
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new_max_size.set_width(desired_panel_size.width());
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (new_max_size.height() < desired_panel_size.height())
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new_max_size.set_height(desired_panel_size.height());
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetSizeRange(min_size_, new_max_size);
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::HandleKeyboardEvent(const content::NativeWebKeyboardEvent& event) {
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  native_panel_->HandlePanelKeyboardEvent(event);
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::SetPreviewMode(bool in_preview) {
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_NE(in_preview_mode_, in_preview);
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_preview_mode_ = in_preview;
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::UpdateMinimizeRestoreButtonVisibility() {
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  native_panel_->UpdatePanelMinimizeRestoreButtonVisibility();
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Size Panel::ClampSize(const gfx::Size& size) const {
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The panel width:
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // * cannot grow or shrink to go beyond [min_width, max_width]
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int new_width = size.width();
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (new_width > max_size_.width())
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new_width = max_size_.width();
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (new_width < min_size_.width())
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new_width = min_size_.width();
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The panel height:
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // * cannot grow or shrink to go beyond [min_height, max_height]
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int new_height = size.height();
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (new_height > max_size_.height())
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new_height = max_size_.height();
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (new_height < min_size_.height())
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new_height = min_size_.height();
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gfx::Size(new_width, new_height);
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Panel::OnActiveStateChanged(bool active) {
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear attention state when an expanded panel becomes active.
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // On some systems (e.g. Win), mouse-down activates a panel regardless of
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // its expansion state. However, we don't want to clear draw attention if
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // contents are not visible. In that scenario, if the mouse-down results
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in a mouse-click, draw attention will be cleared then.
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See Panel::OnTitlebarClicked().
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (active && IsDrawingAttention() && !IsMinimized())
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FlashFrame(false);
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (collection_)
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    collection_->OnPanelActiveStateChanged(this);
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Send extension event about window changing active state.
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::TabsWindowsAPI* tabs_windows_api =
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::TabsWindowsAPI::Get(profile());
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (tabs_windows_api) {
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tabs_windows_api->windows_event_router()->OnActiveWindowChanged(
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        active ? extension_window_controller_.get() : NULL);
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_PANEL_CHANGED_ACTIVE_STATUS,
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<Panel>(this),
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::NoDetails());
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Panel::OnPanelStartUserResizing() {
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetAutoResizable(false);
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetPreviewMode(true);
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  max_size_policy_ = CUSTOM_MAX_SIZE;
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Panel::OnPanelEndUserResizing() {
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetPreviewMode(false);
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Panel::ShouldCloseWindow() {
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Panel::OnWindowClosing() {
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetWebContents()) {
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    native_panel_->DetachWebContents(GetWebContents());
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel_host_->DestroyWebContents();
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Panel::ExecuteCommandIfEnabled(int id) {
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (command_updater()->SupportsCommand(id) &&
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_updater()->IsCommandEnabled(id)) {
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ExecuteCommandWithDisposition(id, CURRENT_TAB);
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
758a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 Panel::GetWindowTitle() const {
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WebContents* contents = GetWebContents();
760a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 title;
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |contents| can be NULL during the window's creation.
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (contents) {
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    title = contents->GetTitle();
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FormatTitleForDisplay(&title);
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (title.empty())
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    title = base::UTF8ToUTF16(app_name());
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return title;
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Image Panel::GetCurrentPageIcon() const {
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return panel_host_->GetPageIcon();
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Panel::UpdateTitleBar() {
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  native_panel_->UpdatePanelTitleBar();
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Panel::LoadingStateChanged(bool is_loading) {
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading);
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  native_panel_->UpdatePanelLoadingAnimations(is_loading);
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateTitleBar();
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Panel::WebContentsFocused(content::WebContents* contents) {
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  native_panel_->PanelWebContentsFocused(contents);
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::MoveByInstantly(const gfx::Vector2d& delta_origin) {
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect bounds = GetBounds();
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bounds.Offset(delta_origin);
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetPanelBoundsInstantly(bounds);
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::SetWindowCornerStyle(panel::CornerStyle corner_style) {
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  native_panel_->SetWindowCornerStyle(corner_style);
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::MinimizeBySystem() {
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  native_panel_->MinimizePanelBySystem();
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPanel::Panel(Profile* profile,
8071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci             const std::string& app_name,
8081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci             const gfx::Size& min_size,
8091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci             const gfx::Size& max_size)
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : app_name_(app_name),
811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_(profile),
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      collection_(NULL),
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      initialized_(false),
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      min_size_(min_size),
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      max_size_(max_size),
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      max_size_policy_(DEFAULT_MAX_SIZE),
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      auto_resizable_(false),
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      in_preview_mode_(false),
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      native_panel_(NULL),
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      attention_mode_(USE_PANEL_ATTENTION),
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      expansion_state_(EXPANDED),
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_updater_(this),
8231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      extension_registry_(extensions::ExtensionRegistry::Get(profile_)),
824c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      image_loader_ptr_factory_(this) {
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::OnImageLoaded(const gfx::Image& image) {
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!image.IsEmpty()) {
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    app_icon_ = image;
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    native_panel_->UpdatePanelTitleBar();
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_PANEL_APP_ICON_LOADED,
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<Panel>(this),
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::NoDetails());
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::InitCommandState() {
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // All supported commands whose state isn't set automagically some other way
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // (like Stop during a page load) must have their state initialized here,
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // otherwise they will be forever disabled.
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Navigation commands
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  command_updater_.UpdateCommandEnabled(IDC_RELOAD, true);
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, true);
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Window management commands
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true);
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  command_updater_.UpdateCommandEnabled(IDC_EXIT, true);
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Zoom
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true);
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true);
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, true);
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true);
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Clipboard
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  command_updater_.UpdateCommandEnabled(IDC_COPY, true);
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  command_updater_.UpdateCommandEnabled(IDC_CUT, true);
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  command_updater_.UpdateCommandEnabled(IDC_PASTE, true);
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // DevTools
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS, true);
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE, true);
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::ConfigureAutoResize(content::WebContents* web_contents) {
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!auto_resizable_ || !web_contents)
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // NULL might be returned if the tab has not been added.
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RenderViewHost* render_view_host = web_contents->GetRenderViewHost();
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!render_view_host)
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  render_view_host->EnableAutoResize(
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      min_size_,
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      native_panel_->ContentSizeFromWindowSize(max_size_));
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Panel::UpdateAppIcon() {
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const extensions::Extension* extension = GetExtension();
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!extension)
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::ImageLoader* loader = extensions::ImageLoader::Get(profile());
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  loader->LoadImageAsync(
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension,
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::IconsInfo::GetIconResource(
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          extension,
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          extension_misc::EXTENSION_ICON_SMALL,
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          ExtensionIconSet::MATCH_BIGGER),
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Size(extension_misc::EXTENSION_ICON_SMALL,
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                extension_misc::EXTENSION_ICON_SMALL),
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&Panel::OnImageLoaded,
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 image_loader_ptr_factory_.GetWeakPtr()));
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
9015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void Panel::FormatTitleForDisplay(base::string16* title) {
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t current_index = 0;
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t match_index;
904a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  while ((match_index = title->find(L'\n', current_index)) !=
905a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)         base::string16::npos) {
906a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    title->replace(match_index, 1, base::string16());
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    current_index = match_index;
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
910