summaryrefslogtreecommitdiffstats
path: root/chrome/views
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/views')
-rw-r--r--chrome/views/client_view.cc8
-rw-r--r--chrome/views/custom_frame_window.cc19
-rw-r--r--chrome/views/custom_frame_window.h14
-rw-r--r--chrome/views/focus_manager_unittest.cc16
-rw-r--r--chrome/views/view_unittest.cc6
-rw-r--r--chrome/views/window.cc181
-rw-r--r--chrome/views/window.h16
-rw-r--r--chrome/views/window_delegate.h22
8 files changed, 133 insertions, 149 deletions
diff --git a/chrome/views/client_view.cc b/chrome/views/client_view.cc
index 2ae6870..7bc7638 100644
--- a/chrome/views/client_view.cc
+++ b/chrome/views/client_view.cc
@@ -243,16 +243,16 @@ void ClientView::Layout() {
void ClientView::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
if (is_add && child == this) {
+ // Can only add and update the dialog buttons _after_ they are added to the
+ // view hierarchy since they are native controls and require the
+ // ViewContainer's HWND.
+ ShowDialogButtons();
// Only add the contents_view_ once, and only when we ourselves are added
// to the view hierarchy, since some contents_view_s assume that when they
// are added to the hierarchy a HWND exists, when it may not, since we are
// not yet added...
if (contents_view_ && contents_view_->GetParent() != this)
AddChildView(contents_view_);
- // Can only add and update the dialog buttons _after_ they are added to the
- // view hierarchy since they are native controls and require the
- // ViewContainer's HWND.
- ShowDialogButtons();
UpdateDialogButtons();
Layout();
}
diff --git a/chrome/views/custom_frame_window.cc b/chrome/views/custom_frame_window.cc
index 02af912..a7434aa 100644
--- a/chrome/views/custom_frame_window.cc
+++ b/chrome/views/custom_frame_window.cc
@@ -507,8 +507,7 @@ int DefaultNonClientView::HitTest(const gfx::Point& point) {
// If the window can't be resized, there are no resize boundaries, just
// window borders.
if (component != HTNOWHERE) {
- if (container_->window_delegate() &&
- !container_->window_delegate()->CanResize()) {
+ if (!container_->window_delegate()->CanResize()) {
return HTBORDER;
}
return component;
@@ -571,6 +570,7 @@ void DefaultNonClientView::Layout() {
LayoutWindowControls();
LayoutTitleBar();
LayoutClientView();
+ SchedulePaint();
}
void DefaultNonClientView::GetPreferredSize(CSize* out) {
@@ -880,15 +880,16 @@ void DefaultNonClientView::InitClass() {
////////////////////////////////////////////////////////////////////////////////
// CustomFrameWindow, public:
-CustomFrameWindow::CustomFrameWindow()
- : Window(),
+CustomFrameWindow::CustomFrameWindow(WindowDelegate* window_delegate)
+ : Window(window_delegate),
non_client_view_(new DefaultNonClientView(this)),
is_active_(false) {
InitClass();
}
-CustomFrameWindow::CustomFrameWindow(NonClientView* non_client_view)
- : Window(),
+CustomFrameWindow::CustomFrameWindow(WindowDelegate* window_delegate,
+ NonClientView* non_client_view)
+ : Window(window_delegate),
non_client_view_(non_client_view) {
InitClass();
}
@@ -896,10 +897,8 @@ CustomFrameWindow::CustomFrameWindow(NonClientView* non_client_view)
CustomFrameWindow::~CustomFrameWindow() {
}
-void CustomFrameWindow::Init(HWND owner, const gfx::Rect& bounds,
- View* contents_view,
- WindowDelegate* window_delegate) {
- Window::Init(owner, bounds, contents_view, window_delegate);
+void CustomFrameWindow::Init(HWND owner, const gfx::Rect& bounds) {
+ Window::Init(owner, bounds);
// We need to re-parent the client view to the non-client view.
GetRootView()->RemoveChildView(client_view_);
GetRootView()->AddChildView(non_client_view_);
diff --git a/chrome/views/custom_frame_window.h b/chrome/views/custom_frame_window.h
index 8dab9d9..52356b2 100644
--- a/chrome/views/custom_frame_window.h
+++ b/chrome/views/custom_frame_window.h
@@ -48,9 +48,10 @@ namespace ChromeViews {
////////////////////////////////////////////////////////////////////////////////
class CustomFrameWindow : public Window {
public:
- CustomFrameWindow();
+ explicit CustomFrameWindow(WindowDelegate* window_delegate);
class NonClientView;
- explicit CustomFrameWindow(NonClientView* non_client_view);
+ CustomFrameWindow(WindowDelegate* window_delegate,
+ NonClientView* non_client_view);
virtual ~CustomFrameWindow();
// Create the CustomFrameWindow.
@@ -58,14 +59,7 @@ class CustomFrameWindow : public Window {
// window that this window is dependent on, if this window is opened as a
// modal dialog or dependent window. This is NULL if the window is not
// dependent on any other window.
- // |contents_view| is the view to be displayed in the client area of the
- // window.
- // |window_delegate| is an object implementing the WindowDelegate interface
- // that supplies information to the window such as its title, icon, etc.
- virtual void Init(HWND owner,
- const gfx::Rect& bounds,
- View* contents_view,
- WindowDelegate* window_delegate);
+ virtual void Init(HWND owner, const gfx::Rect& bounds);
// Executes the specified SC_command.
void ExecuteSystemMenuCommand(int command);
diff --git a/chrome/views/focus_manager_unittest.cc b/chrome/views/focus_manager_unittest.cc
index a7a8379..ed5127e 100644
--- a/chrome/views/focus_manager_unittest.cc
+++ b/chrome/views/focus_manager_unittest.cc
@@ -192,14 +192,15 @@ private:
DISALLOW_EVIL_CONSTRUCTORS(BorderView);
};
-class TestViewWindow : public ChromeViews::Window,
- public ChromeViews::WindowDelegate {
+class TestViewWindow : public ChromeViews::HWNDViewContainer {
public:
explicit TestViewWindow(FocusManagerTest* test);
~TestViewWindow() { }
void Init();
- virtual std::wstring GetWindowTitle() const;
+
+ ChromeViews::View* contents() const { return contents_; }
+
// Return the ID of the component that currently has the focus.
int GetFocusedComponentID();
@@ -262,7 +263,7 @@ void TestViewWindow::Init() {
contents_->SetBackground(
ChromeViews::Background::CreateSolidBackground(255, 255, 255));
- Window::Init(NULL, bounds, contents_, this);
+ HWNDViewContainer::Init(NULL, bounds, contents_, true);
ChromeViews::CheckBox* cb =
new ChromeViews::CheckBox(L"This is a checkbox");
@@ -521,11 +522,6 @@ void TestViewWindow::Init() {
contents->SetBounds(200, y, 200, 50);
}
-// WindowDelegate Implementation.
-std::wstring TestViewWindow::GetWindowTitle() const {
- return L"Focus Manager Test Window";
-}
-
////////////////////////////////////////////////////////////////////////////////
// FocusManagerTest
////////////////////////////////////////////////////////////////////////////////
@@ -543,7 +539,7 @@ TestViewWindow* FocusManagerTest::GetWindow() {
void FocusManagerTest::SetUp() {
test_window_ = new TestViewWindow(this);
test_window_->Init();
- test_window_->Show();
+ ShowWindow(test_window_->GetHWND(), SW_SHOW);
}
void FocusManagerTest::TearDown() {
diff --git a/chrome/views/view_unittest.cc b/chrome/views/view_unittest.cc
index 0cb5af1..44de0c0 100644
--- a/chrome/views/view_unittest.cc
+++ b/chrome/views/view_unittest.cc
@@ -309,10 +309,10 @@ TEST_F(ViewTest, MouseEvent) {
TestView* v2 = new TestView();
v2->SetBounds (100, 100, 100, 100);
- ChromeViews::Window window;
+ ChromeViews::HWNDViewContainer window;
window.set_delete_on_destroy(false);
window.set_window_style(WS_OVERLAPPEDWINDOW);
- window.Init(NULL, gfx::Rect(50, 50, 650, 650), NULL, NULL);
+ window.Init(NULL, gfx::Rect(50, 50, 650, 650), NULL, false);
RootView* root = window.GetRootView();
root->AddChildView(v1);
@@ -470,7 +470,7 @@ TEST_F(ViewTest, RemoveNotification) {
NotificationService::current()->AddObserver(
observer.get(), NOTIFY_VIEW_REMOVED, NotificationService::AllSources());
- ChromeViews::Window* window = new ChromeViews::Window;
+ ChromeViews::HWNDViewContainer* window = new ChromeViews::HWNDViewContainer;
ChromeViews::RootView* root_view = window->GetRootView();
View* v1 = new View;
diff --git a/chrome/views/window.cc b/chrome/views/window.cc
index 24b4925..5976d53 100644
--- a/chrome/views/window.cc
+++ b/chrome/views/window.cc
@@ -55,11 +55,11 @@ static const int kMonitorEdgePadding = 10;
////////////////////////////////////////////////////////////////////////////////
// Window, public:
-Window::Window()
+Window::Window(WindowDelegate* window_delegate)
: HWNDViewContainer(),
focus_on_creation_(true),
+ window_delegate_(window_delegate),
client_view_(NULL),
- window_delegate_(NULL),
owning_hwnd_(NULL),
minimum_size_(100, 100),
is_modal_(false),
@@ -69,6 +69,8 @@ Window::Window()
accepted_(false),
window_closed_(false) {
InitClass();
+ DCHECK(window_delegate_);
+ window_delegate_->window_.reset(this);
// Initialize these values to 0 so that subclasses can override the default
// behavior before calling Init.
set_window_style(0);
@@ -83,34 +85,27 @@ Window::~Window() {
// static
Window* Window::CreateChromeWindow(HWND parent,
const gfx::Rect& bounds,
- View* contents_view,
WindowDelegate* window_delegate) {
+ Window* window = NULL;
if (win_util::ShouldUseVistaFrame()) {
- Window* window = new Window;
- window->Init(parent, bounds, contents_view, window_delegate);
- return window;
+ window = new Window(window_delegate);
+ } else {
+ window = new CustomFrameWindow(window_delegate);
}
- CustomFrameWindow* window = new CustomFrameWindow;
- window->Init(parent, bounds, contents_view, window_delegate);
+ window->Init(parent, bounds);
return window;
}
-void Window::Init(HWND parent,
- const gfx::Rect& bounds,
- View* contents_view,
- WindowDelegate* window_delegate) {
- window_delegate_ = window_delegate;
+void Window::Init(HWND parent, const gfx::Rect& bounds) {
// We need to save the parent window, since later calls to GetParent() will
// return NULL.
owning_hwnd_ = parent;
// We call this after initializing our members since our implementations of
// assorted HWNDViewContainer functions may be called during initialization.
- if (window_delegate_) {
- is_modal_ = window_delegate_->IsModal();
- if (is_modal_)
- BecomeModal();
- is_always_on_top_ = window_delegate_->IsAlwaysOnTop();
- }
+ is_modal_ = window_delegate_->IsModal();
+ if (is_modal_)
+ BecomeModal();
+ is_always_on_top_ = window_delegate_->IsAlwaysOnTop();
if (window_style() == 0)
set_window_style(CalculateWindowStyle());
@@ -120,6 +115,9 @@ void Window::Init(HWND parent,
// A child window never owns its own focus manager, it uses the one
// associated with the root of the window tree...
if (use_client_view_) {
+ View* contents_view = window_delegate_->GetContentsView();
+ if (!contents_view)
+ contents_view = new View;
client_view_ = new ClientView(this, contents_view);
// A Window almost always owns its own focus manager, even if it's a child
// window. File a bug if you find a circumstance where this isn't the case
@@ -128,21 +126,19 @@ void Window::Init(HWND parent,
// manager.
HWNDViewContainer::Init(parent, bounds, client_view_, true);
} else {
- HWNDViewContainer::Init(parent, bounds, contents_view, true);
+ HWNDViewContainer::Init(parent, bounds,
+ window_delegate_->GetContentsView(), true);
}
- if (window_delegate_) {
- std::wstring window_title = window_delegate_->GetWindowTitle();
- SetWindowText(GetHWND(), window_title.c_str());
- }
+ std::wstring window_title = window_delegate_->GetWindowTitle();
+ SetWindowText(GetHWND(), window_title.c_str());
win_util::SetWindowUserData(GetHWND(), this);
// Restore the window's placement from the controller.
CRect saved_bounds(0, 0, 0, 0);
bool maximized = false;
- if (window_delegate_ &&
- window_delegate_->RestoreWindowPosition(&saved_bounds,
+ if (window_delegate_->RestoreWindowPosition(&saved_bounds,
&maximized,
&is_always_on_top_)) {
// Make sure the bounds are at least the minimum size.
@@ -174,7 +170,7 @@ void Window::Init(HWND parent,
SizeWindowToDefault();
}
- if (window_delegate_ && window_delegate->HasAlwaysOnTopMenu())
+ if (window_delegate_->HasAlwaysOnTopMenu())
AddAlwaysOnTopSystemMenuItem();
}
@@ -243,7 +239,7 @@ void Window::Close() {
// process of being closed. Furthermore, if we have only an OK button, but no
// Cancel button, and we're closing without being accepted, call Accept to
// see if we should close.
- if (!accepted_ && window_delegate_) {
+ if (!accepted_) {
DialogDelegate* dd = window_delegate_->AsDialogDelegate();
if (dd) {
int buttons = dd->GetDialogButtons();
@@ -302,11 +298,9 @@ void Window::UpdateDialogButtons() {
void Window::AcceptWindow() {
accepted_ = true;
- if (window_delegate_) {
- DialogDelegate* dd = window_delegate_->AsDialogDelegate();
- if (dd)
- accepted_ = dd->Accept(false);
- }
+ DialogDelegate* dd = window_delegate_->AsDialogDelegate();
+ if (dd)
+ accepted_ = dd->Accept(false);
if (accepted_)
Close();
}
@@ -319,10 +313,8 @@ void Window::CancelWindow() {
}
void Window::UpdateWindowTitle() {
- if (window_delegate_) {
- std::wstring window_title = window_delegate_->GetWindowTitle();
- SetWindowText(GetHWND(), window_title.c_str());
- }
+ std::wstring window_title = window_delegate_->GetWindowTitle();
+ SetWindowText(GetHWND(), window_title.c_str());
}
// static
@@ -411,26 +403,24 @@ void Window::SetInitialFocus() {
return;
bool focus_set = false;
- if (window_delegate_) {
- ChromeViews::View* v = window_delegate_->GetInitiallyFocusedView();
- // For dialogs, try to focus either the OK or Cancel buttons if any.
- if (!v && window_delegate_->AsDialogDelegate() && client_view_) {
- if (client_view_->ok_button())
- v = client_view_->ok_button();
- else if (client_view_->cancel_button())
- v = client_view_->cancel_button();
- }
- if (v) {
- focus_set = true;
- // In order to make that view the initially focused one, we make it the
- // focused view on the focus manager and we store the focused view.
- // When the window is activated, the focus manager will restore the
- // stored focused view.
- FocusManager* focus_manager = FocusManager::GetFocusManager(GetHWND());
- DCHECK(focus_manager);
- focus_manager->SetFocusedView(v);
- focus_manager->StoreFocusedView();
- }
+ ChromeViews::View* v = window_delegate_->GetInitiallyFocusedView();
+ // For dialogs, try to focus either the OK or Cancel buttons if any.
+ if (!v && window_delegate_->AsDialogDelegate() && client_view_) {
+ if (client_view_->ok_button())
+ v = client_view_->ok_button();
+ else if (client_view_->cancel_button())
+ v = client_view_->cancel_button();
+ }
+ if (v) {
+ focus_set = true;
+ // In order to make that view the initially focused one, we make it the
+ // focused view on the focus manager and we store the focused view.
+ // When the window is activated, the focus manager will restore the
+ // stored focused view.
+ FocusManager* focus_manager = FocusManager::GetFocusManager(GetHWND());
+ DCHECK(focus_manager);
+ focus_manager->SetFocusedView(v);
+ focus_manager->StoreFocusedView();
}
if (!focus_set && focus_on_creation_) {
@@ -449,8 +439,7 @@ void Window::OnActivate(UINT action, BOOL minimized, HWND window) {
}
void Window::OnCommand(UINT notification_code, int command_id, HWND window) {
- if (window_delegate_)
- window_delegate_->ExecuteWindowsCommand(command_id);
+ window_delegate_->ExecuteWindowsCommand(command_id);
}
void Window::OnDestroy() {
@@ -596,57 +585,49 @@ void Window::AlwaysOnTopChanged() {
}
DWORD Window::CalculateWindowStyle() {
- if (window_delegate_) {
- DWORD window_styles = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_SYSMENU;
- bool can_resize = window_delegate_->CanResize();
- bool can_maximize = window_delegate_->CanMaximize();
- if ((can_resize && can_maximize) || can_maximize) {
- window_styles |= WS_OVERLAPPEDWINDOW;
- } else if (can_resize) {
- window_styles |= WS_OVERLAPPED | WS_THICKFRAME;
- }
- if (window_delegate_->AsDialogDelegate()) {
- window_styles |= DS_MODALFRAME;
- // NOTE: Turning this off means we lose the close button, which is bad.
- // Turning it on though means the user can maximize or size the window
- // from the system menu, which is worse. We may need to provide our own
- // menu to get the close button to appear properly.
- // window_styles &= ~WS_SYSMENU;
- }
- return window_styles;
+ DWORD window_styles = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_SYSMENU;
+ bool can_resize = window_delegate_->CanResize();
+ bool can_maximize = window_delegate_->CanMaximize();
+ if ((can_resize && can_maximize) || can_maximize) {
+ window_styles |= WS_OVERLAPPEDWINDOW;
+ } else if (can_resize) {
+ window_styles |= WS_OVERLAPPED | WS_THICKFRAME;
+ }
+ if (window_delegate_->AsDialogDelegate()) {
+ window_styles |= DS_MODALFRAME;
+ // NOTE: Turning this off means we lose the close button, which is bad.
+ // Turning it on though means the user can maximize or size the window
+ // from the system menu, which is worse. We may need to provide our own
+ // menu to get the close button to appear properly.
+ // window_styles &= ~WS_SYSMENU;
}
- return window_style();
+ return window_styles;
}
DWORD Window::CalculateWindowExStyle() {
- if (window_delegate_) {
- DWORD window_ex_styles = 0;
- if (window_delegate_->AsDialogDelegate()) {
- window_ex_styles |= WS_EX_DLGMODALFRAME;
- } else if (!(window_style() & WS_CHILD)) {
- window_ex_styles |= WS_EX_APPWINDOW;
- }
- if (window_delegate_->IsAlwaysOnTop())
- window_ex_styles |= WS_EX_TOPMOST;
- return window_ex_styles;
+ DWORD window_ex_styles = 0;
+ if (window_delegate_->AsDialogDelegate()) {
+ window_ex_styles |= WS_EX_DLGMODALFRAME;
+ } else if (!(window_style() & WS_CHILD)) {
+ window_ex_styles |= WS_EX_APPWINDOW;
}
- return window_ex_style();
+ if (window_delegate_->IsAlwaysOnTop())
+ window_ex_styles |= WS_EX_TOPMOST;
+ return window_ex_styles;
}
void Window::SaveWindowPosition() {
- if (window_delegate_) {
- WINDOWPLACEMENT win_placement = { 0 };
- win_placement.length = sizeof(WINDOWPLACEMENT);
+ WINDOWPLACEMENT win_placement = { 0 };
+ win_placement.length = sizeof(WINDOWPLACEMENT);
- BOOL r = GetWindowPlacement(GetHWND(), &win_placement);
- DCHECK(r);
+ BOOL r = GetWindowPlacement(GetHWND(), &win_placement);
+ DCHECK(r);
- bool maximized = (win_placement.showCmd == SW_SHOWMAXIMIZED);
- CRect window_bounds(win_placement.rcNormalPosition);
- window_delegate_->SaveWindowPosition(window_bounds,
- maximized,
- is_always_on_top_);
- }
+ bool maximized = (win_placement.showCmd == SW_SHOWMAXIMIZED);
+ CRect window_bounds(win_placement.rcNormalPosition);
+ window_delegate_->SaveWindowPosition(window_bounds,
+ maximized,
+ is_always_on_top_);
}
void Window::InitClass() {
diff --git a/chrome/views/window.h b/chrome/views/window.h
index 8e30ad9..0e86555 100644
--- a/chrome/views/window.h
+++ b/chrome/views/window.h
@@ -61,30 +61,22 @@ class Window : public HWNDViewContainer {
// ChromeViews. Users in browser/ should always construct with
// CreateChromeWindow which will give the right version,
// depending on platform & configuration.
- Window();
+ // Create a Window using the specified delegate. The delegate must not be
+ // NULL.
+ explicit Window(WindowDelegate* window_delegate);
virtual ~Window();
// Creates the appropriate Window class for a Chrome dialog or window. This
// means a ChromeWindow or a standard Windows frame.
static Window* CreateChromeWindow(HWND parent,
const gfx::Rect& bounds,
- View* contents_view,
WindowDelegate* window_delegate);
// Create the Window.
// If parent is NULL, this Window is top level on the desktop.
- // |contents_view| is a ChromeView that will be displayed in the client area
- // of the Window, as the sole child view of the RootView.
- // |window_delegate| is an object implementing WindowDelegate that can perform
- // controller-like tasks for this window, such as obtaining its preferred
- // placement and state from preferences (which override the default position
- // and size specified in |bounds|) and executing commands. Can be NULL.
// If |bounds| is empty, the view is queried for its preferred size and
// centered on screen.
- void Init(HWND parent,
- const gfx::Rect& bounds,
- View* contents_view,
- WindowDelegate* window_delegate);
+ virtual void Init(HWND parent, const gfx::Rect& bounds);
// Return the size of window (including non-client area) required to contain
// a window of the specified client size.
diff --git a/chrome/views/window_delegate.h b/chrome/views/window_delegate.h
index 17b81f0..8f506d2 100644
--- a/chrome/views/window_delegate.h
+++ b/chrome/views/window_delegate.h
@@ -35,6 +35,7 @@
#include <atlmisc.h>
#include <string>
+#include "chrome/views/window.h"
#include "skia/include/SkBitmap.h"
namespace ChromeViews {
@@ -53,6 +54,10 @@ class View;
///////////////////////////////////////////////////////////////////////////////
class WindowDelegate {
public:
+ virtual ~WindowDelegate() {
+ window_.release();
+ }
+
virtual DialogDelegate* AsDialogDelegate() { return NULL; }
// Returns true if the window can be resized.
@@ -128,6 +133,23 @@ class WindowDelegate {
// Called when the window closes.
virtual void WindowClosing() { }
+
+ // Returns the View that is contained within this Window.
+ virtual View* GetContentsView() {
+ return NULL;
+ }
+
+ // An accessor to the Window this delegate is bound to.
+ Window* window() const { return window_.get(); }
+
+ private:
+ friend Window;
+ // This is a little unusual. We use a scoped_ptr here because it's
+ // initialized to NULL automatically. We do this because we want to allow
+ // people using this helper to not have to call a ctor on this object.
+ // Instead we just release the owning ref this pointer has when we are
+ // destroyed.
+ scoped_ptr<ChromeViews::Window> window_;
};
} // namespace ChromeViews