diff options
Diffstat (limited to 'chrome/views')
-rw-r--r-- | chrome/views/client_view.cc | 8 | ||||
-rw-r--r-- | chrome/views/custom_frame_window.cc | 19 | ||||
-rw-r--r-- | chrome/views/custom_frame_window.h | 14 | ||||
-rw-r--r-- | chrome/views/focus_manager_unittest.cc | 16 | ||||
-rw-r--r-- | chrome/views/view_unittest.cc | 6 | ||||
-rw-r--r-- | chrome/views/window.cc | 181 | ||||
-rw-r--r-- | chrome/views/window.h | 16 | ||||
-rw-r--r-- | chrome/views/window_delegate.h | 22 |
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 |