blob: 0fc6f923524f44975eebe08828749e62f005b982 [file] [log] [blame]
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_POPUP_H_
#define CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_POPUP_H_
#pragma once
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/views/browser_bubble.h"
#include "chrome/browser/views/extensions/extension_view.h"
#include "chrome/browser/views/bubble_border.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
#include "gfx/native_widget_types.h"
#include "googleurl/src/gurl.h"
class Browser;
class ExtensionHost;
class Profile;
namespace views {
class Widget;
}
class ExtensionPopup : public BrowserBubble,
public BrowserBubble::Delegate,
public NotificationObserver,
public ExtensionView::Container {
public:
// Observer to ExtensionPopup events.
class Observer {
public:
// Called when the ExtensionPopup is closing. Note that it
// is ref-counted, and thus will be released shortly after
// making this delegate call.
virtual void ExtensionPopupIsClosing(ExtensionPopup* popup) {}
// Called after the ExtensionPopup has been closed and deleted.
// |popup_token| is the address of the deleted ExtensionPopup.
virtual void ExtensionPopupClosed(void* popup_token) {}
// Called when the ExtensionHost is first created for the pop-up view.
// Note that this is invoked BEFORE the ExtensionPopup is created, and can
// be used to provide extra configuration of the host before it is pushed
// into the popup. An example use is for automation resource routing in
// Chrome-Frame. See extension_popup_api.cc.
virtual void ExtensionHostCreated(ExtensionHost* host) {}
// Called immediately after a popup is created, but before the hosted
// extension has loaded and before the popup has been displayed. Use to
// finalize configuration of |popup|.
virtual void ExtensionPopupCreated(ExtensionPopup* popup) {}
// Called when the ExtensionPopup is resized. Note that the popup may have
// an empty bounds, if a popup is repositioned before the hosted content
// has loaded.
virtual void ExtensionPopupResized(ExtensionPopup* popup) {}
};
enum PopupChrome {
BUBBLE_CHROME,
RECTANGLE_CHROME
};
virtual ~ExtensionPopup();
// Create and show a popup with |url| positioned adjacent to |relative_to| in
// screen coordinates.
// |browser| is the browser to which the pop-up will be attached. NULL is a
// valid parameter for pop-ups not associated with a browser.
// |profile| is the user profile instance associated with the popup. A
// non NULL value must be given.
// |frame_window| is the native window that hosts the view inside which the
// popup will be anchored.
// The positioning of the pop-up is determined by |arrow_location| according
// to the following logic: The popup is anchored so that the corner indicated
// by value of |arrow_location| remains fixed during popup resizes.
// If |arrow_location| is BOTTOM_*, then the popup 'pops up', otherwise
// the popup 'drops down'.
// Pass |activate_on_show| as true to activate the popup window.
// Pass |inspect_with_devtools| as true to pin the popup open and show the
// devtools window for it.
// The |chrome| argument controls the chrome that surrounds the pop-up.
// Passing BUBBLE_CHROME will give the pop-up a bubble-like appearance,
// including the arrow mentioned above. Passing RECTANGLE_CHROME will give
// the popup a rectangular, black border with a drop-shadow with no arrow.
// The positioning of the popup is still governed by the arrow-location
// parameter.
//
// The actual display of the popup is delayed until the page contents
// finish loading in order to minimize UI flashing and resizing.
static ExtensionPopup* Show(const GURL& url, Browser* browser,
Profile* profile,
gfx::NativeWindow frame_window,
const gfx::Rect& relative_to,
BubbleBorder::ArrowLocation arrow_location,
bool activate_on_show,
bool inspect_with_devtools,
PopupChrome chrome,
Observer* observer);
// Assigns the maximal width and height, respectively, to which the popup
// may expand. If these routines are not called, the popup will resize to
// no larger than |kMaxWidth| x |kMaxHeight|. Note that the popup will
// never expand to larger than the dimensions of the screen.
void set_max_width(int width) { max_size_.set_width(width); }
void set_max_height(int height) { max_size_.set_height(height); }
// Closes the ExtensionPopup (this will cause the delegate
// ExtensionPopupIsClosing and ExtensionPopupClosed to fire.
void Close();
// Some clients wish to do their own custom focus change management. If this
// is set to false, then the ExtensionPopup will not do anything in response
// to the BubbleLostFocus() calls it gets from the BrowserBubble.
void set_close_on_lost_focus(bool close_on_lost_focus) {
close_on_lost_focus_ = close_on_lost_focus;
}
ExtensionHost* host() const { return extension_host_.get(); }
// Assigns the arrow location of the popup view, and updates the popup
// border widget, if necessary.
void SetArrowPosition(BubbleBorder::ArrowLocation arrow_location);
BubbleBorder::ArrowLocation arrow_position() const {
return anchor_position_;
}
// Gives the desired bounds (in screen coordinates) given the rect to point
// to and the size of the contained contents. Includes all of the
// border-chrome surrounding the pop-up as well.
gfx::Rect GetOuterBounds() const;
// BrowserBubble overrides.
virtual void Hide();
virtual void Show(bool activate);
virtual void ResizeToView();
// BrowserBubble::Delegate methods.
virtual void BubbleBrowserWindowMoved(BrowserBubble* bubble);
virtual void BubbleBrowserWindowClosing(BrowserBubble* bubble);
virtual void BubbleGotFocus(BrowserBubble* bubble);
virtual void BubbleLostFocus(BrowserBubble* bubble,
bool lost_focus_to_child);
// NotificationObserver overrides.
virtual void Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details);
// ExtensionView::Container overrides.
virtual void OnExtensionMouseMove(ExtensionView* view) { }
virtual void OnExtensionMouseLeave(ExtensionView* view) { }
virtual void OnExtensionPreferredSizeChanged(ExtensionView* view);
// Export the refrence-counted interface required for use as template
// arguments for RefCounted. ExtensionPopup does not inherit from RefCounted
// because it must override the behaviour of Release.
void AddRef() { instance_lifetime_->AddRef(); }
static bool ImplementsThreadSafeReferenceCounting() {
return InternalRefCounter::ImplementsThreadSafeReferenceCounting();
}
// Implements the standard RefCounted<T>::Release behaviour, except
// signals Observer::ExtensionPopupClosed after final release.
void Release();
// The min/max height of popups.
static const int kMinWidth;
static const int kMinHeight;
static const int kMaxWidth;
static const int kMaxHeight;
private:
ExtensionPopup(ExtensionHost* host,
views::Widget* frame,
const gfx::Rect& relative_to,
BubbleBorder::ArrowLocation arrow_location,
bool activate_on_show,
bool inspect_with_devtools,
PopupChrome chrome,
Observer* observer);
// The area on the screen that the popup should be positioned relative to.
gfx::Rect relative_to_;
// The contained host for the view.
scoped_ptr<ExtensionHost> extension_host_;
// Flag used to indicate if the pop-up should be activated upon first display.
bool activate_on_show_;
// Flag used to indicate if the pop-up should open a devtools window once
// it is shown inspecting it.
bool inspect_with_devtools_;
// If false, ignore BrowserBubble::Delegate::BubbleLostFocus() calls.
bool close_on_lost_focus_;
// Whether the ExtensionPopup is current going about closing itself.
bool closing_;
NotificationRegistrar registrar_;
// A separate widget and associated pieces to draw a border behind the
// popup. This has to be a separate window in order to support transparency.
// Layered windows can't contain native child windows, so we wouldn't be
// able to have the ExtensionView child.
views::Widget* border_widget_;
BubbleBorder* border_;
views::View* border_view_;
// The type of chrome associated with the popup window.
PopupChrome popup_chrome_;
// The maximal size to which the popup may expand.
gfx::Size max_size_;
// The observer of this popup.
Observer* observer_;
// A cached copy of the arrow-position for the bubble chrome.
// If a black-border was requested, we still need this value to determine
// the position of the pop-up in relation to |relative_to_|.
BubbleBorder::ArrowLocation anchor_position_;
// ExtensionPopup's lifetime is managed via reference counting, but it does
// not expose the RefCounted interface. Instead, the lifetime is tied to
// this member variable.
class InternalRefCounter : public base::RefCounted<InternalRefCounter> {
};
InternalRefCounter* instance_lifetime_;
DISALLOW_COPY_AND_ASSIGN(ExtensionPopup);
};
#endif // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_POPUP_H_