From 0e8588c1528cad6732d172775aba8e891baebdef Mon Sep 17 00:00:00 2001 From: "ben@chromium.org" Date: Tue, 17 Mar 2009 01:44:36 +0000 Subject: Move windowing related objects into chrome/views/window subdir. TBR=sky Review URL: http://codereview.chromium.org/42272 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11819 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/app_modal_dialog_queue.h | 2 +- chrome/browser/automation/automation_provider.cc | 4 +- chrome/browser/bookmarks/bookmark_context_menu.cc | 2 +- chrome/browser/browser_focus_uitest.cc | 2 +- chrome/browser/debugger/debugger_window.h | 4 +- chrome/browser/first_run.cc | 2 +- chrome/browser/jsmessage_box_handler_win.cc | 2 +- chrome/browser/jsmessage_box_handler_win.h | 2 +- chrome/browser/task_manager.cc | 2 +- chrome/browser/task_manager.h | 4 +- chrome/browser/unload_uitest.cc | 2 +- chrome/browser/views/about_chrome_view.cc | 2 +- chrome/browser/views/about_chrome_view.h | 2 +- chrome/browser/views/about_ipc_dialog.cc | 2 +- chrome/browser/views/about_ipc_dialog.h | 2 +- chrome/browser/views/about_network_dialog.cc | 2 +- chrome/browser/views/about_network_dialog.h | 2 +- chrome/browser/views/bookmark_bar_view.cc | 2 +- chrome/browser/views/bookmark_editor_view.cc | 2 +- chrome/browser/views/bookmark_editor_view.h | 2 +- chrome/browser/views/bookmark_manager_view.cc | 2 +- chrome/browser/views/bookmark_manager_view.h | 2 +- chrome/browser/views/bug_report_view.cc | 4 +- chrome/browser/views/bug_report_view.h | 2 +- chrome/browser/views/clear_browsing_data.cc | 2 +- chrome/browser/views/clear_browsing_data.h | 2 +- chrome/browser/views/constrained_window_impl.cc | 6 +- chrome/browser/views/constrained_window_impl.h | 2 +- chrome/browser/views/edit_keyword_controller.cc | 2 +- chrome/browser/views/edit_keyword_controller.h | 2 +- chrome/browser/views/first_run_bubble.cc | 2 +- chrome/browser/views/first_run_customize_view.cc | 2 +- chrome/browser/views/first_run_customize_view.h | 2 +- chrome/browser/views/first_run_view.cc | 2 +- chrome/browser/views/first_run_view.h | 2 +- chrome/browser/views/first_run_view_base.cc | 4 +- chrome/browser/views/first_run_view_base.h | 2 +- chrome/browser/views/frame/browser_frame.cc | 2 +- chrome/browser/views/frame/browser_frame.h | 2 +- chrome/browser/views/frame/browser_view.cc | 4 +- chrome/browser/views/frame/browser_view.h | 4 +- .../views/frame/glass_browser_frame_view.cc | 4 +- .../browser/views/frame/glass_browser_frame_view.h | 2 +- .../views/frame/opaque_browser_frame_view.cc | 2 +- .../views/frame/opaque_browser_frame_view.h | 2 +- chrome/browser/views/html_dialog_view.cc | 2 +- chrome/browser/views/html_dialog_view.h | 2 +- chrome/browser/views/importer_view.cc | 2 +- chrome/browser/views/importer_view.h | 2 +- chrome/browser/views/info_bubble.cc | 2 +- chrome/browser/views/input_window.cc | 2 +- chrome/browser/views/input_window.h | 2 +- chrome/browser/views/keyword_editor_view.cc | 4 +- chrome/browser/views/keyword_editor_view.h | 2 +- chrome/browser/views/new_profile_dialog.cc | 2 +- chrome/browser/views/new_profile_dialog.h | 2 +- chrome/browser/views/options/cookies_view.h | 4 +- .../views/options/fonts_languages_window_view.cc | 2 +- .../views/options/fonts_languages_window_view.h | 4 +- .../browser/views/options/options_window_view.cc | 4 +- chrome/browser/views/page_info_window.h | 4 +- .../views/password_manager_exceptions_view.h | 4 +- chrome/browser/views/password_manager_view.h | 4 +- chrome/browser/views/restart_message_box.cc | 2 +- chrome/browser/views/restart_message_box.h | 2 +- chrome/browser/views/select_profile_dialog.cc | 2 +- chrome/browser/views/select_profile_dialog.h | 2 +- chrome/browser/views/shelf_item_dialog.h | 4 +- chrome/browser/views/tabs/tab_renderer.cc | 4 +- chrome/browser/views/tabs/tab_strip.cc | 4 +- chrome/browser/views/toolbar_view.cc | 4 +- chrome/browser/views/user_data_dir_dialog.cc | 2 +- chrome/browser/views/user_data_dir_dialog.h | 2 +- chrome/test/automation/automation_proxy.cc | 2 +- chrome/test/automation/automation_proxy.h | 2 +- chrome/test/automation/automation_proxy_uitest.cc | 2 +- chrome/views/SConscript | 64 +- chrome/views/app_modal_dialog_delegate.h | 24 - chrome/views/client_view.cc | 61 - chrome/views/client_view.h | 84 -- chrome/views/custom_frame_view.cc | 696 ----------- chrome/views/custom_frame_view.h | 122 -- chrome/views/dialog_client_view.cc | 434 ------- chrome/views/dialog_client_view.h | 122 -- chrome/views/dialog_delegate.cc | 53 - chrome/views/dialog_delegate.h | 111 -- chrome/views/focus_manager_unittest.cc | 4 +- chrome/views/native_frame_view.cc | 60 - chrome/views/native_frame_view.h | 39 - chrome/views/non_client_view.cc | 244 ---- chrome/views/non_client_view.h | 221 ---- chrome/views/table_view_unittest.cc | 4 +- chrome/views/view_unittest.cc | 4 +- chrome/views/views.vcproj | 152 +-- chrome/views/widget/accelerator_handler.h | 6 +- chrome/views/widget/aero_tooltip_manager.h | 6 +- chrome/views/widget/hwnd_notification_source.h | 6 +- chrome/views/widget/root_view.h | 6 +- chrome/views/widget/root_view_drop_target.h | 6 +- chrome/views/widget/tooltip_manager.h | 8 +- chrome/views/widget/widget.h | 6 +- chrome/views/widget/widget_win.h | 6 +- chrome/views/window.h | 118 -- chrome/views/window/app_modal_dialog_delegate.h | 24 + chrome/views/window/client_view.cc | 61 + chrome/views/window/client_view.h | 84 ++ chrome/views/window/custom_frame_view.cc | 696 +++++++++++ chrome/views/window/custom_frame_view.h | 122 ++ chrome/views/window/dialog_client_view.cc | 434 +++++++ chrome/views/window/dialog_client_view.h | 122 ++ chrome/views/window/dialog_delegate.cc | 53 + chrome/views/window/dialog_delegate.h | 111 ++ chrome/views/window/native_frame_view.cc | 60 + chrome/views/window/native_frame_view.h | 39 + chrome/views/window/non_client_view.cc | 244 ++++ chrome/views/window/non_client_view.h | 221 ++++ chrome/views/window/window.h | 118 ++ chrome/views/window/window_delegate.cc | 96 ++ chrome/views/window/window_delegate.h | 162 +++ chrome/views/window/window_resources.h | 30 + chrome/views/window/window_win.cc | 1234 ++++++++++++++++++++ chrome/views/window/window_win.h | 278 +++++ chrome/views/window_delegate.cc | 96 -- chrome/views/window_delegate.h | 162 --- chrome/views/window_resources.h | 30 - chrome/views/window_win.cc | 1234 -------------------- chrome/views/window_win.h | 278 ----- 127 files changed, 4431 insertions(+), 4419 deletions(-) delete mode 100644 chrome/views/app_modal_dialog_delegate.h delete mode 100644 chrome/views/client_view.cc delete mode 100644 chrome/views/client_view.h delete mode 100644 chrome/views/custom_frame_view.cc delete mode 100644 chrome/views/custom_frame_view.h delete mode 100644 chrome/views/dialog_client_view.cc delete mode 100644 chrome/views/dialog_client_view.h delete mode 100644 chrome/views/dialog_delegate.cc delete mode 100644 chrome/views/dialog_delegate.h delete mode 100644 chrome/views/native_frame_view.cc delete mode 100644 chrome/views/native_frame_view.h delete mode 100644 chrome/views/non_client_view.cc delete mode 100644 chrome/views/non_client_view.h delete mode 100644 chrome/views/window.h create mode 100644 chrome/views/window/app_modal_dialog_delegate.h create mode 100644 chrome/views/window/client_view.cc create mode 100644 chrome/views/window/client_view.h create mode 100644 chrome/views/window/custom_frame_view.cc create mode 100644 chrome/views/window/custom_frame_view.h create mode 100644 chrome/views/window/dialog_client_view.cc create mode 100644 chrome/views/window/dialog_client_view.h create mode 100644 chrome/views/window/dialog_delegate.cc create mode 100644 chrome/views/window/dialog_delegate.h create mode 100644 chrome/views/window/native_frame_view.cc create mode 100644 chrome/views/window/native_frame_view.h create mode 100644 chrome/views/window/non_client_view.cc create mode 100644 chrome/views/window/non_client_view.h create mode 100644 chrome/views/window/window.h create mode 100644 chrome/views/window/window_delegate.cc create mode 100644 chrome/views/window/window_delegate.h create mode 100644 chrome/views/window/window_resources.h create mode 100644 chrome/views/window/window_win.cc create mode 100644 chrome/views/window/window_win.h delete mode 100644 chrome/views/window_delegate.cc delete mode 100644 chrome/views/window_delegate.h delete mode 100644 chrome/views/window_resources.h delete mode 100644 chrome/views/window_win.cc delete mode 100644 chrome/views/window_win.h (limited to 'chrome') diff --git a/chrome/browser/app_modal_dialog_queue.h b/chrome/browser/app_modal_dialog_queue.h index 4926968..2482d5a 100644 --- a/chrome/browser/app_modal_dialog_queue.h +++ b/chrome/browser/app_modal_dialog_queue.h @@ -7,7 +7,7 @@ #include -#include "chrome/views/app_modal_dialog_delegate.h" +#include "chrome/views/window/app_modal_dialog_delegate.h" // Keeps a queue of AppModalDialogDelegates, making sure only one app modal // dialog is shown at a time. diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index ca473d6..4ea5e283 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -42,8 +42,8 @@ #include "chrome/browser/printing/print_job.h" #include "chrome/browser/views/bookmark_bar_view.h" #include "chrome/browser/views/location_bar_view.h" -#include "chrome/views/app_modal_dialog_delegate.h" -#include "chrome/views/window.h" +#include "chrome/views/window/app_modal_dialog_delegate.h" +#include "chrome/views/window/window.h" #endif // defined(OS_WIN) using base::Time; diff --git a/chrome/browser/bookmarks/bookmark_context_menu.cc b/chrome/browser/bookmarks/bookmark_context_menu.cc index 7e9f525..6e00094 100644 --- a/chrome/browser/bookmarks/bookmark_context_menu.cc +++ b/chrome/browser/bookmarks/bookmark_context_menu.cc @@ -23,7 +23,7 @@ #include "chrome/browser/views/bookmark_editor_view.h" #include "chrome/browser/views/bookmark_manager_view.h" #include "chrome/browser/views/input_window.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #endif namespace { diff --git a/chrome/browser/browser_focus_uitest.cc b/chrome/browser/browser_focus_uitest.cc index 81edcc2..0cd1b1a 100644 --- a/chrome/browser/browser_focus_uitest.cc +++ b/chrome/browser/browser_focus_uitest.cc @@ -17,7 +17,7 @@ #include "chrome/common/notification_type.h" #include "chrome/views/focus_manager.h" #include "chrome/views/view.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "chrome/test/in_process_browser_test.h" #include "chrome/test/ui_test_utils.h" diff --git a/chrome/browser/debugger/debugger_window.h b/chrome/browser/debugger/debugger_window.h index 39158cb..ab916ff 100644 --- a/chrome/browser/debugger/debugger_window.h +++ b/chrome/browser/debugger/debugger_window.h @@ -6,8 +6,8 @@ #define CHROME_BROWSER_DEBUGGER_DEBUGGER_WINDOW_H__ #include "chrome/browser/debugger/debugger_io.h" -#include "chrome/views/window.h" -#include "chrome/views/window_delegate.h" +#include "chrome/views/window/window.h" +#include "chrome/views/window/window_delegate.h" class DebuggerView; class ListValue; diff --git a/chrome/browser/first_run.cc b/chrome/browser/first_run.cc index 5916928..84d0cb9 100644 --- a/chrome/browser/first_run.cc +++ b/chrome/browser/first_run.cc @@ -41,7 +41,7 @@ #include "chrome/installer/util/shell_util.h" #include "chrome/installer/util/util_constants.h" #include "chrome/views/widget/accelerator_handler.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "google_update_idl.h" diff --git a/chrome/browser/jsmessage_box_handler_win.cc b/chrome/browser/jsmessage_box_handler_win.cc index 5a6e02c..a31bed6 100644 --- a/chrome/browser/jsmessage_box_handler_win.cc +++ b/chrome/browser/jsmessage_box_handler_win.cc @@ -16,7 +16,7 @@ #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" #include "chrome/views/message_box_view.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "grit/generated_resources.h" void RunJavascriptMessageBox(WebContents* web_contents, diff --git a/chrome/browser/jsmessage_box_handler_win.h b/chrome/browser/jsmessage_box_handler_win.h index 4bfc286..ff2b152 100644 --- a/chrome/browser/jsmessage_box_handler_win.h +++ b/chrome/browser/jsmessage_box_handler_win.h @@ -9,7 +9,7 @@ #include "chrome/common/ipc_message.h" #include "chrome/common/notification_observer.h" #include "chrome/common/notification_registrar.h" -#include "chrome/views/app_modal_dialog_delegate.h" +#include "chrome/views/window/app_modal_dialog_delegate.h" #include "googleurl/src/gurl.h" class MessageBoxView; diff --git a/chrome/browser/task_manager.cc b/chrome/browser/task_manager.cc index 290a8a0..b2919d2 100644 --- a/chrome/browser/task_manager.cc +++ b/chrome/browser/task_manager.cc @@ -24,7 +24,7 @@ #include "chrome/views/menu.h" #include "chrome/views/native_button.h" #include "chrome/views/widget/widget.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/task_manager.h b/chrome/browser/task_manager.h index 7776177..a1f54a3 100644 --- a/chrome/browser/task_manager.h +++ b/chrome/browser/task_manager.h @@ -13,10 +13,10 @@ #include "base/singleton.h" #include "base/ref_counted.h" #include "base/timer.h" -#include "chrome/views/dialog_delegate.h" -#include "chrome/views/group_table_view.h" #include "chrome/browser/cache_manager_host.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/views/group_table_view.h" +#include "chrome/views/window/dialog_delegate.h" #include "net/url_request/url_request_job_tracker.h" class MessageLoop; diff --git a/chrome/browser/unload_uitest.cc b/chrome/browser/unload_uitest.cc index d166c93..a0e5a24 100644 --- a/chrome/browser/unload_uitest.cc +++ b/chrome/browser/unload_uitest.cc @@ -8,7 +8,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome/test/automation/browser_proxy.h" #include "chrome/test/ui/ui_test.h" -#include "chrome/views/dialog_delegate.h" +#include "chrome/views/window/dialog_delegate.h" #include "net/url_request/url_request_unittest.h" const std::string NOLISTENERS_HTML = diff --git a/chrome/browser/views/about_chrome_view.cc b/chrome/browser/views/about_chrome_view.cc index c997c1d..6547523 100644 --- a/chrome/browser/views/about_chrome_view.cc +++ b/chrome/browser/views/about_chrome_view.cc @@ -22,7 +22,7 @@ #include "chrome/installer/util/install_util.h" #include "chrome/views/text_field.h" #include "chrome/views/throbber.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" diff --git a/chrome/browser/views/about_chrome_view.h b/chrome/browser/views/about_chrome_view.h index e965c3c..5f775de7 100644 --- a/chrome/browser/views/about_chrome_view.h +++ b/chrome/browser/views/about_chrome_view.h @@ -6,11 +6,11 @@ #define CHROME_BROWSER_VIEWS_ABOUT_CHROME_VIEW_H_ #include "chrome/browser/google_update.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/image_view.h" #include "chrome/views/label.h" #include "chrome/views/link.h" #include "chrome/views/view.h" +#include "chrome/views/window/dialog_delegate.h" namespace views { class TextField; diff --git a/chrome/browser/views/about_ipc_dialog.cc b/chrome/browser/views/about_ipc_dialog.cc index f4de76f..4e174c1 100644 --- a/chrome/browser/views/about_ipc_dialog.cc +++ b/chrome/browser/views/about_ipc_dialog.cc @@ -29,7 +29,7 @@ #include "chrome/views/text_button.h" #include "chrome/views/widget/root_view.h" #include "chrome/views/widget/widget.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_job.h" #include "net/url_request/url_request_job_tracker.h" diff --git a/chrome/browser/views/about_ipc_dialog.h b/chrome/browser/views/about_ipc_dialog.h index 15c41c2..a5ff38d 100644 --- a/chrome/browser/views/about_ipc_dialog.h +++ b/chrome/browser/views/about_ipc_dialog.h @@ -14,7 +14,7 @@ #include "base/singleton.h" #include "chrome/common/ipc_logging.h" #include "chrome/views/button.h" -#include "chrome/views/dialog_delegate.h" +#include "chrome/views/window/dialog_delegate.h" #include "chrome/views/table_view.h" #if defined(OS_WIN) && defined(IPC_MESSAGE_LOG_ENABLED) diff --git a/chrome/browser/views/about_network_dialog.cc b/chrome/browser/views/about_network_dialog.cc index 7028d2b..3386043a 100644 --- a/chrome/browser/views/about_network_dialog.cc +++ b/chrome/browser/views/about_network_dialog.cc @@ -11,7 +11,7 @@ #include "chrome/views/grid_layout.h" #include "chrome/views/text_button.h" #include "chrome/views/text_field.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_job.h" #include "net/url_request/url_request_job_tracker.h" diff --git a/chrome/browser/views/about_network_dialog.h b/chrome/browser/views/about_network_dialog.h index 768cd97..389e582 100644 --- a/chrome/browser/views/about_network_dialog.h +++ b/chrome/browser/views/about_network_dialog.h @@ -7,7 +7,7 @@ #include "base/singleton.h" #include "chrome/views/button.h" -#include "chrome/views/dialog_delegate.h" +#include "chrome/views/window/dialog_delegate.h" namespace views { class TextButton; diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc index 7855ffc..79b3ce9 100644 --- a/chrome/browser/views/bookmark_bar_view.cc +++ b/chrome/browser/views/bookmark_bar_view.cc @@ -36,7 +36,7 @@ #include "chrome/views/view_constants.h" #include "chrome/views/widget/tooltip_manager.h" #include "chrome/views/widget/widget.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "skia/ext/skia_utils.h" diff --git a/chrome/browser/views/bookmark_editor_view.cc b/chrome/browser/views/bookmark_editor_view.cc index a233179..9407179 100644 --- a/chrome/browser/views/bookmark_editor_view.cc +++ b/chrome/browser/views/bookmark_editor_view.cc @@ -17,7 +17,7 @@ #include "chrome/views/grid_layout.h" #include "chrome/views/label.h" #include "chrome/views/widget/widget.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "googleurl/src/gurl.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" diff --git a/chrome/browser/views/bookmark_editor_view.h b/chrome/browser/views/bookmark_editor_view.h index 280e9cf..bf9be29 100644 --- a/chrome/browser/views/bookmark_editor_view.h +++ b/chrome/browser/views/bookmark_editor_view.h @@ -9,12 +9,12 @@ #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/views/checkbox.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/menu.h" #include "chrome/views/native_button.h" #include "chrome/views/text_field.h" #include "chrome/views/tree_node_model.h" #include "chrome/views/tree_view.h" +#include "chrome/views/window/dialog_delegate.h" namespace views { class Window; diff --git a/chrome/browser/views/bookmark_manager_view.cc b/chrome/browser/views/bookmark_manager_view.cc index cb4fe7c..1aec366 100644 --- a/chrome/browser/views/bookmark_manager_view.cc +++ b/chrome/browser/views/bookmark_manager_view.cc @@ -31,7 +31,7 @@ #include "chrome/views/menu_button.h" #include "chrome/views/single_split_view.h" #include "chrome/views/widget/widget.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" #include "skia/ext/skia_utils.h" diff --git a/chrome/browser/views/bookmark_manager_view.h b/chrome/browser/views/bookmark_manager_view.h index f8754bb..aef8896 100644 --- a/chrome/browser/views/bookmark_manager_view.h +++ b/chrome/browser/views/bookmark_manager_view.h @@ -15,7 +15,7 @@ #include "chrome/views/tree_view.h" #include "chrome/views/view.h" #include "chrome/views/view_menu_delegate.h" -#include "chrome/views/window_delegate.h" +#include "chrome/views/window/window_delegate.h" #include "webkit/glue/window_open_disposition.h" class BookmarkFolderTreeModel; diff --git a/chrome/browser/views/bug_report_view.cc b/chrome/browser/views/bug_report_view.cc index 63308aa..b5c3725 100644 --- a/chrome/browser/views/bug_report_view.cc +++ b/chrome/browser/views/bug_report_view.cc @@ -19,10 +19,10 @@ #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" #include "chrome/views/checkbox.h" -#include "chrome/views/client_view.h" #include "chrome/views/grid_layout.h" #include "chrome/views/label.h" -#include "chrome/views/Window.h" +#include "chrome/views/window/client_view.h" +#include "chrome/views/window/window.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" diff --git a/chrome/browser/views/bug_report_view.h b/chrome/browser/views/bug_report_view.h index 3f2d8a3..b539b3c 100644 --- a/chrome/browser/views/bug_report_view.h +++ b/chrome/browser/views/bug_report_view.h @@ -7,10 +7,10 @@ #include "chrome/browser/net/url_fetcher.h" #include "chrome/views/combo_box.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/native_button.h" #include "chrome/views/text_field.h" #include "chrome/views/view.h" +#include "chrome/views/window/dialog_delegate.h" #include "googleurl/src/gurl.h" namespace views { diff --git a/chrome/browser/views/clear_browsing_data.cc b/chrome/browser/views/clear_browsing_data.cc index cfcb7f5..d61faba 100644 --- a/chrome/browser/views/clear_browsing_data.cc +++ b/chrome/browser/views/clear_browsing_data.cc @@ -13,7 +13,7 @@ #include "chrome/views/label.h" #include "chrome/views/native_button.h" #include "chrome/views/throbber.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" #include "grit/generated_resources.h" diff --git a/chrome/browser/views/clear_browsing_data.h b/chrome/browser/views/clear_browsing_data.h index 02e60d5..e70f058 100644 --- a/chrome/browser/views/clear_browsing_data.h +++ b/chrome/browser/views/clear_browsing_data.h @@ -7,10 +7,10 @@ #include "chrome/browser/browsing_data_remover.h" #include "chrome/views/combo_box.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/label.h" #include "chrome/views/native_button.h" #include "chrome/views/view.h" +#include "chrome/views/window/dialog_delegate.h" namespace views { class CheckBox; diff --git a/chrome/browser/views/constrained_window_impl.cc b/chrome/browser/views/constrained_window_impl.cc index ba436f0..4c588c7 100644 --- a/chrome/browser/views/constrained_window_impl.cc +++ b/chrome/browser/views/constrained_window_impl.cc @@ -26,11 +26,11 @@ #include "chrome/common/resource_bundle.h" #include "chrome/common/win_util.h" #include "chrome/views/image_button.h" -#include "chrome/views/client_view.h" #include "chrome/views/focus_manager.h" #include "chrome/views/hwnd_view.h" -#include "chrome/views/non_client_view.h" -#include "chrome/views/window_resources.h" +#include "chrome/views/window/client_view.h" +#include "chrome/views/window/non_client_view.h" +#include "chrome/views/window/window_resources.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/views/constrained_window_impl.h b/chrome/browser/views/constrained_window_impl.h index 0fb6763..4afec31 100644 --- a/chrome/browser/views/constrained_window_impl.h +++ b/chrome/browser/views/constrained_window_impl.h @@ -8,7 +8,7 @@ #include "base/gfx/rect.h" #include "chrome/browser/tab_contents/constrained_window.h" #include "chrome/browser/tab_contents/tab_contents_delegate.h" -#include "chrome/views/window_win.h" +#include "chrome/views/window/window_win.h" class ConstrainedTabContentsWindowDelegate; class ConstrainedWindowAnimation; diff --git a/chrome/browser/views/edit_keyword_controller.cc b/chrome/browser/views/edit_keyword_controller.cc index 05bf8fd..0f336d0 100644 --- a/chrome/browser/views/edit_keyword_controller.cc +++ b/chrome/browser/views/edit_keyword_controller.cc @@ -18,7 +18,7 @@ #include "chrome/views/grid_layout.h" #include "chrome/views/image_view.h" #include "chrome/views/table_view.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "googleurl/src/gurl.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/views/edit_keyword_controller.h b/chrome/browser/views/edit_keyword_controller.h index 34244b2..f6f693b 100644 --- a/chrome/browser/views/edit_keyword_controller.h +++ b/chrome/browser/views/edit_keyword_controller.h @@ -12,8 +12,8 @@ #include -#include "chrome/views/dialog_delegate.h" #include "chrome/views/text_field.h" +#include "chrome/views/window/dialog_delegate.h" namespace views { class Label; diff --git a/chrome/browser/views/first_run_bubble.cc b/chrome/browser/views/first_run_bubble.cc index dc14153..313689d 100644 --- a/chrome/browser/views/first_run_bubble.cc +++ b/chrome/browser/views/first_run_bubble.cc @@ -17,7 +17,7 @@ #include "chrome/views/event.h" #include "chrome/views/label.h" #include "chrome/views/native_button.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" diff --git a/chrome/browser/views/first_run_customize_view.cc b/chrome/browser/views/first_run_customize_view.cc index e9ad65e..307753c 100644 --- a/chrome/browser/views/first_run_customize_view.cc +++ b/chrome/browser/views/first_run_customize_view.cc @@ -15,7 +15,7 @@ #include "chrome/views/image_view.h" #include "chrome/views/label.h" #include "chrome/views/throbber.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" diff --git a/chrome/browser/views/first_run_customize_view.h b/chrome/browser/views/first_run_customize_view.h index 4138d62..9a7a596 100644 --- a/chrome/browser/views/first_run_customize_view.h +++ b/chrome/browser/views/first_run_customize_view.h @@ -7,9 +7,9 @@ #include "chrome/browser/views/first_run_view_base.h" #include "chrome/views/combo_box.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/native_button.h" #include "chrome/views/view.h" +#include "chrome/views/window/dialog_delegate.h" namespace views { class Label; diff --git a/chrome/browser/views/first_run_view.cc b/chrome/browser/views/first_run_view.cc index f2df7be..910cab6 100644 --- a/chrome/browser/views/first_run_view.cc +++ b/chrome/browser/views/first_run_view.cc @@ -16,7 +16,7 @@ #include "chrome/views/label.h" #include "chrome/views/throbber.h" #include "chrome/views/separator.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" diff --git a/chrome/browser/views/first_run_view.h b/chrome/browser/views/first_run_view.h index 5565b9a..e17f78d 100644 --- a/chrome/browser/views/first_run_view.h +++ b/chrome/browser/views/first_run_view.h @@ -7,9 +7,9 @@ #include "chrome/browser/views/first_run_view_base.h" #include "chrome/browser/views/first_run_customize_view.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/link.h" #include "chrome/views/view.h" +#include "chrome/views/window/dialog_delegate.h" namespace views { class Label; diff --git a/chrome/browser/views/first_run_view_base.cc b/chrome/browser/views/first_run_view_base.cc index 2d4f68d..f0dc653 100644 --- a/chrome/browser/views/first_run_view_base.cc +++ b/chrome/browser/views/first_run_view_base.cc @@ -21,12 +21,12 @@ #include "chrome/common/resource_bundle.h" #include "chrome/views/background.h" #include "chrome/views/checkbox.h" -#include "chrome/views/client_view.h" #include "chrome/views/image_view.h" #include "chrome/views/label.h" #include "chrome/views/throbber.h" #include "chrome/views/separator.h" -#include "chrome/views/window.h" +#include "chrome/views/window/client_view.h" +#include "chrome/views/window/window.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/views/first_run_view_base.h b/chrome/browser/views/first_run_view_base.h index ef7fdf3..0790414 100644 --- a/chrome/browser/views/first_run_view_base.h +++ b/chrome/browser/views/first_run_view_base.h @@ -6,8 +6,8 @@ #define CHROME_BROWSER_VIEWS_FIRST_RUN_VIEW_BASE_H_ #include "chrome/browser/importer/importer.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/view.h" +#include "chrome/views/window/dialog_delegate.h" namespace views { class CheckBox; diff --git a/chrome/browser/views/frame/browser_frame.cc b/chrome/browser/views/frame/browser_frame.cc index 10003af..b837c4b 100644 --- a/chrome/browser/views/frame/browser_frame.cc +++ b/chrome/browser/views/frame/browser_frame.cc @@ -14,7 +14,7 @@ #include "chrome/browser/views/frame/opaque_browser_frame_view.h" #include "chrome/common/resource_bundle.h" #include "chrome/common/win_util.h" -#include "chrome/views/window_delegate.h" +#include "chrome/views/window/window_delegate.h" #include "grit/theme_resources.h" // static diff --git a/chrome/browser/views/frame/browser_frame.h b/chrome/browser/views/frame/browser_frame.h index 94d099b..17813af 100644 --- a/chrome/browser/views/frame/browser_frame.h +++ b/chrome/browser/views/frame/browser_frame.h @@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_ #define CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_ -#include "chrome/views/window_win.h" +#include "chrome/views/window/window_win.h" class AeroGlassNonClientView; class BrowserView; diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index 0a4d6e3..19e3e56 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -51,11 +51,11 @@ #include "chrome/common/resource_bundle.h" #include "chrome/common/win_util.h" #include "chrome/views/native_scroll_bar.h" -#include "chrome/views/non_client_view.h" #include "chrome/views/view.h" #include "chrome/views/widget/hwnd_notification_source.h" #include "chrome/views/widget/root_view.h" -#include "chrome/views/window.h" +#include "chrome/views/window/non_client_view.h" +#include "chrome/views/window/window.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h index 889ded3..0796ed9 100644 --- a/chrome/browser/views/frame/browser_view.h +++ b/chrome/browser/views/frame/browser_view.h @@ -11,11 +11,11 @@ #include "chrome/browser/hang_monitor/hung_window_detector.h" #include "chrome/browser/tabs/tab_strip_model.h" #include "chrome/browser/views/frame/browser_frame.h" -#include "chrome/views/client_view.h" -#include "chrome/views/window_delegate.h" #ifdef CHROME_PERSONALIZATION #include "chrome/personalization/personalization.h" #endif +#include "chrome/views/window/client_view.h" +#include "chrome/views/window/window_delegate.h" // NOTE: For more information about the objects and files in this directory, // view: https://sites.google.com/a/google.com/the-chrome-project/developers/design-documents/browser-window diff --git a/chrome/browser/views/frame/glass_browser_frame_view.cc b/chrome/browser/views/frame/glass_browser_frame_view.cc index c822aa1..1b736cf 100644 --- a/chrome/browser/views/frame/glass_browser_frame_view.cc +++ b/chrome/browser/views/frame/glass_browser_frame_view.cc @@ -8,8 +8,8 @@ #include "chrome/browser/views/tabs/tab_strip.h" #include "chrome/common/gfx/chrome_canvas.h" #include "chrome/common/resource_bundle.h" -#include "chrome/views/client_view.h" -#include "chrome/views/window_resources.h" +#include "chrome/views/window/client_view.h" +#include "chrome/views/window/window_resources.h" #include "grit/theme_resources.h" // An enumeration of bitmap resources used by this window. diff --git a/chrome/browser/views/frame/glass_browser_frame_view.h b/chrome/browser/views/frame/glass_browser_frame_view.h index 585e075..b2ca45b 100644 --- a/chrome/browser/views/frame/glass_browser_frame_view.h +++ b/chrome/browser/views/frame/glass_browser_frame_view.h @@ -7,7 +7,7 @@ #include "chrome/browser/views/frame/browser_frame.h" #include "chrome/views/button.h" -#include "chrome/views/non_client_view.h" +#include "chrome/views/window/non_client_view.h" class BrowserView; class GlassBrowserWindowResources; diff --git a/chrome/browser/views/frame/opaque_browser_frame_view.cc b/chrome/browser/views/frame/opaque_browser_frame_view.cc index 99d9d8d..665cefd 100644 --- a/chrome/browser/views/frame/opaque_browser_frame_view.cc +++ b/chrome/browser/views/frame/opaque_browser_frame_view.cc @@ -15,7 +15,7 @@ #include "chrome/common/win_util.h" #include "chrome/views/image_button.h" #include "chrome/views/widget/root_view.h" -#include "chrome/views/window_resources.h" +#include "chrome/views/window/window_resources.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/views/frame/opaque_browser_frame_view.h b/chrome/browser/views/frame/opaque_browser_frame_view.h index 3a47ac4..df255fe 100644 --- a/chrome/browser/views/frame/opaque_browser_frame_view.h +++ b/chrome/browser/views/frame/opaque_browser_frame_view.h @@ -7,8 +7,8 @@ #include "chrome/browser/views/frame/browser_frame.h" #include "chrome/browser/views/tab_icon_view.h" -#include "chrome/views/non_client_view.h" #include "chrome/views/button.h" +#include "chrome/views/window/non_client_view.h" class BrowserView; class ChromeFont; diff --git a/chrome/browser/views/html_dialog_view.cc b/chrome/browser/views/html_dialog_view.cc index c18f002..c26bdaf 100644 --- a/chrome/browser/views/html_dialog_view.cc +++ b/chrome/browser/views/html_dialog_view.cc @@ -6,7 +6,7 @@ #include "chrome/browser/browser.h" #include "chrome/views/widget/root_view.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" //////////////////////////////////////////////////////////////////////////////// // HtmlDialogView, public: diff --git a/chrome/browser/views/html_dialog_view.h b/chrome/browser/views/html_dialog_view.h index c7a91fa..54bace6 100644 --- a/chrome/browser/views/html_dialog_view.h +++ b/chrome/browser/views/html_dialog_view.h @@ -11,7 +11,7 @@ #include "chrome/browser/dom_ui/html_dialog_contents.h" #include "chrome/browser/tab_contents/tab_contents_delegate.h" #include "chrome/browser/views/dom_view.h" -#include "chrome/views/window_delegate.h" +#include "chrome/views/window/window_delegate.h" class Browser; namespace views { diff --git a/chrome/browser/views/importer_view.cc b/chrome/browser/views/importer_view.cc index def2826..76fb533 100644 --- a/chrome/browser/views/importer_view.cc +++ b/chrome/browser/views/importer_view.cc @@ -10,7 +10,7 @@ #include "chrome/views/checkbox.h" #include "chrome/views/grid_layout.h" #include "chrome/views/label.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" diff --git a/chrome/browser/views/importer_view.h b/chrome/browser/views/importer_view.h index 1e9aaad..fcae46d 100644 --- a/chrome/browser/views/importer_view.h +++ b/chrome/browser/views/importer_view.h @@ -7,9 +7,9 @@ #include "chrome/browser/importer/importer.h" #include "chrome/views/combo_box.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/native_button.h" #include "chrome/views/view.h" +#include "chrome/views/window/dialog_delegate.h" namespace views { class CheckBox; diff --git a/chrome/browser/views/info_bubble.cc b/chrome/browser/views/info_bubble.cc index 9638899..c4352c6 100644 --- a/chrome/browser/views/info_bubble.cc +++ b/chrome/browser/views/info_bubble.cc @@ -12,7 +12,7 @@ #include "chrome/common/resource_bundle.h" #include "chrome/common/win_util.h" #include "chrome/views/widget/root_view.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "grit/theme_resources.h" using views::View; diff --git a/chrome/browser/views/input_window.cc b/chrome/browser/views/input_window.cc index a2bc55b..eb61945 100644 --- a/chrome/browser/views/input_window.cc +++ b/chrome/browser/views/input_window.cc @@ -11,7 +11,7 @@ #include "chrome/views/grid_layout.h" #include "chrome/views/label.h" #include "chrome/views/text_field.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "grit/generated_resources.h" // Width to make the text field, in pixels. diff --git a/chrome/browser/views/input_window.h b/chrome/browser/views/input_window.h index 879ac92..d88ed98 100644 --- a/chrome/browser/views/input_window.h +++ b/chrome/browser/views/input_window.h @@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_VIEWS_INPUT_WINDOW_H__ #define CHROME_BROWSER_VIEWS_INPUT_WINDOW_H__ -#include "chrome/views/dialog_delegate.h" +#include "chrome/views/window/dialog_delegate.h" // InputWindowDelegate -------------------------------------------------------- diff --git a/chrome/browser/views/keyword_editor_view.cc b/chrome/browser/views/keyword_editor_view.cc index 61d81c2..e2267eb 100644 --- a/chrome/browser/views/keyword_editor_view.cc +++ b/chrome/browser/views/keyword_editor_view.cc @@ -22,11 +22,11 @@ #include "chrome/common/stl_util-inl.h" #include "chrome/views/background.h" #include "chrome/views/checkbox.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/grid_layout.h" #include "chrome/views/text_field.h" #include "chrome/views/widget/widget.h" -#include "chrome/views/window.h" +#include "chrome/views/window/dialog_delegate.h" +#include "chrome/views/window/window.h" #include "googleurl/src/gurl.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" diff --git a/chrome/browser/views/keyword_editor_view.h b/chrome/browser/views/keyword_editor_view.h index a576430..8b0f1d1 100644 --- a/chrome/browser/views/keyword_editor_view.h +++ b/chrome/browser/views/keyword_editor_view.h @@ -9,10 +9,10 @@ #include #include "chrome/browser/search_engines/template_url_model.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/native_button.h" #include "chrome/views/table_view.h" #include "chrome/views/view.h" +#include "chrome/views/window/dialog_delegate.h" namespace views { class CheckBox; diff --git a/chrome/browser/views/new_profile_dialog.cc b/chrome/browser/views/new_profile_dialog.cc index 7574789..8690116 100644 --- a/chrome/browser/views/new_profile_dialog.cc +++ b/chrome/browser/views/new_profile_dialog.cc @@ -13,7 +13,7 @@ #include "chrome/views/message_box_view.h" #include "chrome/views/text_field.h" #include "chrome/views/view.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" diff --git a/chrome/browser/views/new_profile_dialog.h b/chrome/browser/views/new_profile_dialog.h index 737cce5..4e43570 100644 --- a/chrome/browser/views/new_profile_dialog.h +++ b/chrome/browser/views/new_profile_dialog.h @@ -11,8 +11,8 @@ #include "base/basictypes.h" #include "base/message_loop.h" #include "chrome/browser/shell_dialogs.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/text_field.h" +#include "chrome/views/window/dialog_delegate.h" class MessageBoxView; namespace views { diff --git a/chrome/browser/views/options/cookies_view.h b/chrome/browser/views/options/cookies_view.h index 503bbfa..1f300cb 100644 --- a/chrome/browser/views/options/cookies_view.h +++ b/chrome/browser/views/options/cookies_view.h @@ -6,12 +6,12 @@ #define CHROME_BROWSER_VIEWS_OPTIONS_COOKIES_VIEW_H__ #include "base/task.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/native_button.h" #include "chrome/views/table_view.h" #include "chrome/views/text_field.h" #include "chrome/views/view.h" -#include "chrome/views/window.h" +#include "chrome/views/window/dialog_delegate.h" +#include "chrome/views/window/window.h" namespace views { class Label; diff --git a/chrome/browser/views/options/fonts_languages_window_view.cc b/chrome/browser/views/options/fonts_languages_window_view.cc index 1e4372d..fd8ef61 100644 --- a/chrome/browser/views/options/fonts_languages_window_view.cc +++ b/chrome/browser/views/options/fonts_languages_window_view.cc @@ -12,7 +12,7 @@ #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" #include "chrome/common/resource_bundle.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" diff --git a/chrome/browser/views/options/fonts_languages_window_view.h b/chrome/browser/views/options/fonts_languages_window_view.h index 8d27727..0ddc3d5 100644 --- a/chrome/browser/views/options/fonts_languages_window_view.h +++ b/chrome/browser/views/options/fonts_languages_window_view.h @@ -5,10 +5,10 @@ #ifndef CHROME_BROWSER_FONTS_LANGUAGE_WINDOW_H__ #define CHROME_BROWSER_FONTS_LANGUAGE_WINDOW_H__ -#include "chrome/views/dialog_delegate.h" #include "chrome/views/tabbed_pane.h" #include "chrome/views/view.h" -#include "chrome/views/window.h" +#include "chrome/views/window/dialog_delegate.h" +#include "chrome/views/window/window.h" class Profile; class FontsPageView; diff --git a/chrome/browser/views/options/options_window_view.cc b/chrome/browser/views/options/options_window_view.cc index 353b52e..bd423ec 100644 --- a/chrome/browser/views/options/options_window_view.cc +++ b/chrome/browser/views/options/options_window_view.cc @@ -18,10 +18,10 @@ #include "chrome/personalization/personalization.h" #include "chrome/personalization/views/user_data_page_view.h" #endif -#include "chrome/views/dialog_delegate.h" #include "chrome/views/tabbed_pane.h" #include "chrome/views/widget/root_view.h" -#include "chrome/views/window.h" +#include "chrome/views/window/dialog_delegate.h" +#include "chrome/views/window/window.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" diff --git a/chrome/browser/views/page_info_window.h b/chrome/browser/views/page_info_window.h index 1d3bbac..297b049 100644 --- a/chrome/browser/views/page_info_window.h +++ b/chrome/browser/views/page_info_window.h @@ -6,9 +6,9 @@ #define CHROME_BROWSER_VIEWS_PAGE_INFO_WINDOW_H__ #include "chrome/browser/tab_contents/navigation_entry.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/native_button.h" -#include "chrome/views/window.h" +#include "chrome/views/window/dialog_delegate.h" +#include "chrome/views/window/window.h" #include "googleurl/src/gurl.h" // The page info window displays information regarding the current page, diff --git a/chrome/browser/views/password_manager_exceptions_view.h b/chrome/browser/views/password_manager_exceptions_view.h index 3313211..8efc422 100644 --- a/chrome/browser/views/password_manager_exceptions_view.h +++ b/chrome/browser/views/password_manager_exceptions_view.h @@ -11,11 +11,11 @@ #include "chrome/browser/webdata/web_data_service.h" #include "chrome/common/stl_util-inl.h" #include "chrome/common/gfx/text_elider.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/label.h" #include "chrome/views/native_button.h" #include "chrome/views/table_view.h" -#include "chrome/views/window.h" +#include "chrome/views/window/dialog_delegate.h" +#include "chrome/views/window/window.h" #include "webkit/glue/password_form.h" class PasswordManagerExceptionsTableModel : public PasswordManagerTableModel { diff --git a/chrome/browser/views/password_manager_view.h b/chrome/browser/views/password_manager_view.h index 143567f..e382cec 100644 --- a/chrome/browser/views/password_manager_view.h +++ b/chrome/browser/views/password_manager_view.h @@ -11,11 +11,11 @@ #include "chrome/browser/webdata/web_data_service.h" #include "chrome/common/stl_util-inl.h" #include "chrome/common/gfx/text_elider.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/label.h" #include "chrome/views/native_button.h" #include "chrome/views/table_view.h" -#include "chrome/views/window.h" +#include "chrome/views/window/dialog_delegate.h" +#include "chrome/views/window/window.h" #include "webkit/glue/password_form.h" class Profile; diff --git a/chrome/browser/views/restart_message_box.cc b/chrome/browser/views/restart_message_box.cc index bd0c8ff..199e5e9 100644 --- a/chrome/browser/views/restart_message_box.cc +++ b/chrome/browser/views/restart_message_box.cc @@ -6,7 +6,7 @@ #include "chrome/common/l10n_util.h" #include "chrome/views/message_box_view.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" diff --git a/chrome/browser/views/restart_message_box.h b/chrome/browser/views/restart_message_box.h index 6721d20..893bf43 100644 --- a/chrome/browser/views/restart_message_box.h +++ b/chrome/browser/views/restart_message_box.h @@ -6,7 +6,7 @@ #define CHROME_BROWSER_VIEWS_RESTART_MESSAGE_BOX_H_ #include "base/basictypes.h" -#include "chrome/views/dialog_delegate.h" +#include "chrome/views/window/dialog_delegate.h" class MessageBoxView; diff --git a/chrome/browser/views/select_profile_dialog.cc b/chrome/browser/views/select_profile_dialog.cc index 0600cd8..c0b48b4 100644 --- a/chrome/browser/views/select_profile_dialog.cc +++ b/chrome/browser/views/select_profile_dialog.cc @@ -17,7 +17,7 @@ #include "chrome/views/label.h" #include "chrome/views/message_box_view.h" #include "chrome/views/view.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" diff --git a/chrome/browser/views/select_profile_dialog.h b/chrome/browser/views/select_profile_dialog.h index 179e754..dbfb355 100644 --- a/chrome/browser/views/select_profile_dialog.h +++ b/chrome/browser/views/select_profile_dialog.h @@ -16,7 +16,7 @@ #include "chrome/browser/shell_dialogs.h" #include "chrome/browser/user_data_manager.h" #include "chrome/views/combo_box.h" -#include "chrome/views/dialog_delegate.h" +#include "chrome/views/window/dialog_delegate.h" class SelectProfileDialogHelper; namespace views { diff --git a/chrome/browser/views/shelf_item_dialog.h b/chrome/browser/views/shelf_item_dialog.h index 8aff06c..8e61493 100644 --- a/chrome/browser/views/shelf_item_dialog.h +++ b/chrome/browser/views/shelf_item_dialog.h @@ -7,12 +7,12 @@ #include "chrome/browser/cancelable_request.h" #include "chrome/browser/history/history.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/native_button.h" #include "chrome/views/table_view.h" #include "chrome/views/text_field.h" #include "chrome/views/view.h" -#include "chrome/views/window.h" +#include "chrome/views/window/dialog_delegate.h" +#include "chrome/views/window/window.h" namespace views { class Button; diff --git a/chrome/browser/views/tabs/tab_renderer.cc b/chrome/browser/views/tabs/tab_renderer.cc index 8bfec23..4ee10cf 100644 --- a/chrome/browser/views/tabs/tab_renderer.cc +++ b/chrome/browser/views/tabs/tab_renderer.cc @@ -15,9 +15,9 @@ #include "chrome/common/l10n_util.h" #include "chrome/common/resource_bundle.h" #include "chrome/common/win_util.h" -#include "chrome/views/non_client_view.h" #include "chrome/views/widget/widget.h" -#include "chrome/views/window.h" +#include "chrome/views/window/non_client_view.h" +#include "chrome/views/window/window.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "skia/ext/image_operations.h" diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc index 2829289..037da49 100644 --- a/chrome/browser/views/tabs/tab_strip.cc +++ b/chrome/browser/views/tabs/tab_strip.cc @@ -25,8 +25,8 @@ #include "chrome/common/win_util.h" #include "chrome/views/image_view.h" #include "chrome/views/painter.h" -#include "chrome/views/non_client_view.h" -#include "chrome/views/window.h" +#include "chrome/views/window/non_client_view.h" +#include "chrome/views/window/window.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/views/toolbar_view.cc b/chrome/browser/views/toolbar_view.cc index 1aa7b9f..1f80ed1 100644 --- a/chrome/browser/views/toolbar_view.cc +++ b/chrome/browser/views/toolbar_view.cc @@ -45,9 +45,9 @@ #include "chrome/views/button_dropdown.h" #include "chrome/views/hwnd_view.h" #include "chrome/views/label.h" -#include "chrome/views/non_client_view.h" #include "chrome/views/widget/tooltip_manager.h" -#include "chrome/views/window.h" +#include "chrome/views/window/non_client_view.h" +#include "chrome/views/window/window.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/views/user_data_dir_dialog.cc b/chrome/browser/views/user_data_dir_dialog.cc index b45e0ca..3a19a64 100644 --- a/chrome/browser/views/user_data_dir_dialog.cc +++ b/chrome/browser/views/user_data_dir_dialog.cc @@ -7,7 +7,7 @@ #include "chrome/common/l10n_util.h" #include "chrome/views/message_box_view.h" #include "chrome/views/widget/widget.h" -#include "chrome/views/window.h" +#include "chrome/views/window/window.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" diff --git a/chrome/browser/views/user_data_dir_dialog.h b/chrome/browser/views/user_data_dir_dialog.h index edc3894..87f0275 100644 --- a/chrome/browser/views/user_data_dir_dialog.h +++ b/chrome/browser/views/user_data_dir_dialog.h @@ -11,7 +11,7 @@ #include "base/basictypes.h" #include "base/message_loop.h" #include "chrome/browser/shell_dialogs.h" -#include "chrome/views/dialog_delegate.h" +#include "chrome/views/window/dialog_delegate.h" class MessageBoxView; namespace views { diff --git a/chrome/test/automation/automation_proxy.cc b/chrome/test/automation/automation_proxy.cc index 8f79680..35d44f8 100644 --- a/chrome/test/automation/automation_proxy.cc +++ b/chrome/test/automation/automation_proxy.cc @@ -20,7 +20,7 @@ #if defined(OS_WIN) // TODO(port): Enable when dialog_delegate is ported. -#include "chrome/views/dialog_delegate.h" +#include "chrome/views/window/dialog_delegate.h" #endif using base::TimeDelta; diff --git a/chrome/test/automation/automation_proxy.h b/chrome/test/automation/automation_proxy.h index fa2d33f..e80259f 100644 --- a/chrome/test/automation/automation_proxy.h +++ b/chrome/test/automation/automation_proxy.h @@ -21,7 +21,7 @@ #if defined(OS_WIN) // TODO(port): Enable this or equivalent. -#include "chrome/views/dialog_delegate.h" +#include "chrome/views/window/dialog_delegate.h" #endif class AutomationRequest; diff --git a/chrome/test/automation/automation_proxy_uitest.cc b/chrome/test/automation/automation_proxy_uitest.cc index 6b3cab5..1445061 100644 --- a/chrome/test/automation/automation_proxy_uitest.cc +++ b/chrome/test/automation/automation_proxy_uitest.cc @@ -17,8 +17,8 @@ #include "chrome/test/automation/tab_proxy.h" #include "chrome/test/automation/window_proxy.h" #include "chrome/test/ui/ui_test.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/event.h" +#include "chrome/views/window/dialog_delegate.h" #include "net/base/net_util.h" class AutomationProxyTest : public UITest { diff --git a/chrome/views/SConscript b/chrome/views/SConscript index 6030612..a4c541a 100644 --- a/chrome/views/SConscript +++ b/chrome/views/SConscript @@ -42,7 +42,6 @@ input_files = ChromeFileList([ ]), 'accelerator.cc', 'accelerator.h', - 'app_modal_dialog_delegate.h', 'background.cc', 'background.h', 'base_button.cc', @@ -59,19 +58,11 @@ input_files = ChromeFileList([ 'checkbox.h', 'chrome_menu.cc', 'chrome_menu.h', - 'client_view.cc', - 'client_view.h', 'combo_box.cc', 'combo_box.h', 'controller.h', - 'custom_frame_window.cc', - 'custom_frame_window.h', 'decision.cc', 'decision.h', - 'dialog_client_view.cc', - 'dialog_client_view.h', - 'dialog_delegate.cc', - 'dialog_delegate.h', 'event.cc', 'event.h', 'external_focus_tracker.cc', @@ -104,8 +95,6 @@ input_files = ChromeFileList([ 'native_control.h', 'native_scroll_bar.cc', 'native_scroll_bar.h', - 'non_client_view.cc', - 'non_client_view.h', 'painter.cc', 'painter.h', '$CHROME_DIR/tools/build/win/precompiled_wtl$OBJSUFFIX', @@ -160,11 +149,24 @@ input_files = ChromeFileList([ 'widget/widget.h', 'widget/widget_win.cc', 'widget/widget_win.h', - 'window.cc', - 'window.h', - 'window_delegate.cc', - 'window_delegate.h', - 'window_resources.h', + 'window/app_modal_dialog_delegate.h', + 'window/client_view.cc', + 'window/client_view.h', + 'window/custom_frame_view.cc', + 'window/custom_frame_view.h', + 'window/dialog_client_view.cc', + 'window/dialog_client_view.h', + 'window/dialog_delegate.cc', + 'window/dialog_delegate.h', + 'window/native_frame_view.cc', + 'window/native_frame_view.h', + 'window/non_client_view.cc', + 'window/non_client_view.h', + 'window/window.cc', + 'window/window.h', + 'window/window_delegate.cc', + 'window/window_delegate.h', + 'window/window_resources.h', ]) if not env.Bit('windows'): @@ -220,11 +222,7 @@ if env.Bit('linux'): 'button_dropdown.cc', 'checkbox.cc', 'chrome_menu.cc', - 'client_view.cc', 'combo_box.cc', - 'custom_frame_window.cc', - 'dialog_delegate.cc', - 'dialog_client_view.cc', 'decision.cc', 'event.cc', 'focus_manager.cc', @@ -237,7 +235,6 @@ if env.Bit('linux'): 'native_button.cc', 'native_control.cc', 'native_scroll_bar.cc', - 'non_client_view.cc', 'radio_button.cc', 'resize_corner.cc', 'separator.cc', @@ -252,8 +249,14 @@ if env.Bit('linux'): 'widget/root_view_drop_target.cc', 'widget/tooltip_manager.cc', 'widget/widget_win.cc', - 'window.cc', - 'window_delegate.cc', + 'window/client_view.cc', + 'window/custom_frame_view.cc', + 'window/dialog_delegate.cc', + 'window/dialog_client_view.cc', + 'window/native_frame_view.cc', + 'window/non_client_view.cc', + 'window/window_delegate.cc', + 'window/window_win.cc', ) if env.Bit('mac'): @@ -271,11 +274,7 @@ if env.Bit('mac'): 'button_dropdown.cc', 'checkbox.cc', 'chrome_menu.cc', - 'client_view.cc', 'combo_box.cc', - 'custom_frame_window.cc', - 'dialog_delegate.cc', - 'dialog_client_view.cc', 'decision.cc', 'event.cc', 'external_focus_tracker.cc', @@ -293,7 +292,6 @@ if env.Bit('mac'): 'native_button.cc', 'native_control.cc', 'native_scroll_bar.cc', - 'non_client_view.cc', 'painter.cc', 'radio_button.cc', 'repeat_controller.cc', @@ -315,8 +313,14 @@ if env.Bit('mac'): 'widget/root_view_drop_target.cc', 'widget/tooltip_manager.cc', 'widget/widget_win.cc', - 'window.cc', - 'window_delegate.cc', + 'window/client_view.cc', + 'window/custom_frame_view.cc', + 'window/dialog_delegate.cc', + 'window/dialog_client_view.cc', + 'window/native_frame_view.cc', + 'window/non_client_view.cc', + 'window/window_delegate.cc', + 'window/window_win.cc', ) env.ChromeLibrary('views', input_files) diff --git a/chrome/views/app_modal_dialog_delegate.h b/chrome/views/app_modal_dialog_delegate.h deleted file mode 100644 index 399b593..0000000 --- a/chrome/views/app_modal_dialog_delegate.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2006-2008 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_VIEWS_APP_MODAL_DIALOG_DELEGATE_H__ -#define CHROME_VIEWS_APP_MODAL_DIALOG_DELEGATE_H__ - -#include "chrome/views/dialog_delegate.h" - -namespace views { - -// Pure virtual interface for a window which is app modal. -class AppModalDialogDelegate : public DialogDelegate { - public: - // Called by the app modal window queue when it is time to show this window. - virtual void ShowModalDialog() = 0; - - // Called by the app modal window queue to activate the window. - virtual void ActivateModalDialog() = 0; -}; - -} // namespace views - -#endif // #ifndef CHROME_VIEWS_APP_MODAL_DIALOG_DELEGATE_H__ diff --git a/chrome/views/client_view.cc b/chrome/views/client_view.cc deleted file mode 100644 index 319dd56..0000000 --- a/chrome/views/client_view.cc +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "base/logging.h" -#include "chrome/views/client_view.h" -#include "chrome/views/window.h" -#include "chrome/views/window_delegate.h" - -namespace views { - -/////////////////////////////////////////////////////////////////////////////// -// ClientView, public: - -ClientView::ClientView(Window* window, View* contents_view) - : window_(window), - contents_view_(contents_view) { -} - -int ClientView::NonClientHitTest(const gfx::Point& point) { - return bounds().Contains(point) ? HTCLIENT : HTNOWHERE; -} - -void ClientView::WindowClosing() { - window_->GetDelegate()->WindowClosing(); -} - -/////////////////////////////////////////////////////////////////////////////// -// ClientView, View overrides: - -gfx::Size ClientView::GetPreferredSize() { - // |contents_view_| is allowed to be NULL up until the point where this view - // is attached to a Container. - if (contents_view_) - return contents_view_->GetPreferredSize(); - return gfx::Size(); -} - -void ClientView::Layout() { - // |contents_view_| is allowed to be NULL up until the point where this view - // is attached to a Container. - if (contents_view_) - contents_view_->SetBounds(0, 0, width(), height()); -} - -void ClientView::ViewHierarchyChanged(bool is_add, View* parent, View* child) { - if (is_add && child == this) { - DCHECK(GetWidget()); - DCHECK(contents_view_); // |contents_view_| must be valid now! - AddChildView(contents_view_); - } -} - -void ClientView::DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current) { - // Overridden to do nothing. The NonClientView manually calls Layout on the - // ClientView when it is itself laid out, see comment in - // NonClientView::Layout. -} - -} // namespace views diff --git a/chrome/views/client_view.h b/chrome/views/client_view.h deleted file mode 100644 index b9b60e3..0000000 --- a/chrome/views/client_view.h +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2006-2008 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_VIEWS_CLIENT_VIEW_H_ -#define CHROME_VIEWS_CLIENT_VIEW_H_ - -#include "chrome/views/view.h" - -namespace views { - -class DialogClientView; -class Window; - -/////////////////////////////////////////////////////////////////////////////// -// ClientView -// -// A ClientView is a View subclass that is used to occupy the "client area" -// of a window. It provides basic information to the window that contains it -// such as non-client hit testing information, sizing etc. Sub-classes of -// ClientView are used to create more elaborate contents, e.g. -// "DialogClientView". -class ClientView : public View { - public: - // Constructs a ClientView object for the specified window with the specified - // contents. Since this object is created during the process of creating - // |window|, |contents_view| must be valid if you want the initial size of - // the window to be based on |contents_view|'s preferred size. - ClientView(Window* window, View* contents_view); - virtual ~ClientView() {} - - // Manual RTTI ftw. - virtual DialogClientView* AsDialogClientView() { return NULL; } - - // Returns true to signal that the Window can be closed. Specialized - // ClientView subclasses can override this default behavior to allow the - // close to be blocked until the user corrects mistakes, accepts a warning - // dialog, etc. - virtual bool CanClose() const { return true; } - - // Notification that the window is closing. The default implementation - // forwards the notification to the delegate. - virtual void WindowClosing(); - - // Tests to see if the specified point (in view coordinates) is within the - // bounds of this view. If so, it returns HTCLIENT in this default - // implementation. If it is outside the bounds of this view, this must return - // HTNOWHERE to tell the caller to do further processing to determine where - // in the non-client area it is (if it is). - // Subclasses of ClientView can extend this logic by overriding this method - // to detect if regions within the client area count as parts of the "non- - // client" area. A good example of this is the size box at the bottom right - // corner of resizable dialog boxes. - virtual int NonClientHitTest(const gfx::Point& point); - - // Overridden from View: - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - - protected: - // Overridden from View: - virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); - virtual void DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current); - - // Accessors for private data members. - Window* window() const { return window_; } - void set_window(Window* window) { window_ = window; } - View* contents_view() const { return contents_view_; } - void set_contents_view(View* contents_view) { - contents_view_ = contents_view; - } - - private: - // The Window that hosts this ClientView. - Window* window_; - - // The View that this ClientView contains. - View* contents_view_; -}; - -} // namespace views - -#endif // #ifndef CHROME_VIEWS_CLIENT_VIEW_H_ diff --git a/chrome/views/custom_frame_view.cc b/chrome/views/custom_frame_view.cc deleted file mode 100644 index d330be0..0000000 --- a/chrome/views/custom_frame_view.cc +++ /dev/null @@ -1,696 +0,0 @@ -// 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. - -#include "chrome/views/custom_frame_view.h" - -#include "base/win_util.h" -#include "chrome/common/gfx/path.h" -#include "chrome/common/gfx/chrome_canvas.h" -#include "chrome/common/gfx/chrome_font.h" -#include "chrome/common/resource_bundle.h" -#include "chrome/common/win_util.h" -#include "chrome/views/client_view.h" -#include "chrome/views/window_delegate.h" -#include "grit/theme_resources.h" - -namespace views { - -// An enumeration of bitmap resources used by this window. -enum { - FRAME_PART_BITMAP_FIRST = 0, // Must be first. - - // Window Controls. - FRAME_CLOSE_BUTTON_ICON, - FRAME_CLOSE_BUTTON_ICON_H, - FRAME_CLOSE_BUTTON_ICON_P, - FRAME_CLOSE_BUTTON_ICON_SA, - FRAME_CLOSE_BUTTON_ICON_SA_H, - FRAME_CLOSE_BUTTON_ICON_SA_P, - FRAME_RESTORE_BUTTON_ICON, - FRAME_RESTORE_BUTTON_ICON_H, - FRAME_RESTORE_BUTTON_ICON_P, - FRAME_MAXIMIZE_BUTTON_ICON, - FRAME_MAXIMIZE_BUTTON_ICON_H, - FRAME_MAXIMIZE_BUTTON_ICON_P, - FRAME_MINIMIZE_BUTTON_ICON, - FRAME_MINIMIZE_BUTTON_ICON_H, - FRAME_MINIMIZE_BUTTON_ICON_P, - - // Window Frame Border. - FRAME_BOTTOM_EDGE, - FRAME_BOTTOM_LEFT_CORNER, - FRAME_BOTTOM_RIGHT_CORNER, - FRAME_LEFT_EDGE, - FRAME_RIGHT_EDGE, - FRAME_TOP_EDGE, - FRAME_TOP_LEFT_CORNER, - FRAME_TOP_RIGHT_CORNER, - - // Client Edge Border. - FRAME_CLIENT_EDGE_TOP_LEFT, - FRAME_CLIENT_EDGE_TOP, - FRAME_CLIENT_EDGE_TOP_RIGHT, - FRAME_CLIENT_EDGE_RIGHT, - FRAME_CLIENT_EDGE_BOTTOM_RIGHT, - FRAME_CLIENT_EDGE_BOTTOM, - FRAME_CLIENT_EDGE_BOTTOM_LEFT, - FRAME_CLIENT_EDGE_LEFT, - - FRAME_PART_BITMAP_COUNT // Must be last. -}; - -class ActiveWindowResources : public WindowResources { - public: - ActiveWindowResources() { - InitClass(); - } - virtual ~ActiveWindowResources() { - } - - // WindowResources implementation: - virtual SkBitmap* GetPartBitmap(FramePartBitmap part) const { - return standard_frame_bitmaps_[part]; - } - - private: - static void InitClass() { - static bool initialized = false; - if (!initialized) { - static const int kFramePartBitmapIds[] = { - 0, - IDR_CLOSE, IDR_CLOSE_H, IDR_CLOSE_P, - IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P, - IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P, - IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P, - IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P, - IDR_WINDOW_BOTTOM_CENTER, IDR_WINDOW_BOTTOM_LEFT_CORNER, - IDR_WINDOW_BOTTOM_RIGHT_CORNER, IDR_WINDOW_LEFT_SIDE, - IDR_WINDOW_RIGHT_SIDE, IDR_WINDOW_TOP_CENTER, - IDR_WINDOW_TOP_LEFT_CORNER, IDR_WINDOW_TOP_RIGHT_CORNER, - IDR_APP_TOP_LEFT, IDR_APP_TOP_CENTER, IDR_APP_TOP_RIGHT, - IDR_CONTENT_RIGHT_SIDE, IDR_CONTENT_BOTTOM_RIGHT_CORNER, - IDR_CONTENT_BOTTOM_CENTER, IDR_CONTENT_BOTTOM_LEFT_CORNER, - IDR_CONTENT_LEFT_SIDE, - 0 - }; - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i) { - int id = kFramePartBitmapIds[i]; - if (id != 0) - standard_frame_bitmaps_[i] = rb.GetBitmapNamed(id); - } - initialized = true; - } - } - - static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT]; - static ChromeFont title_font_; - - DISALLOW_EVIL_CONSTRUCTORS(ActiveWindowResources); -}; - -class InactiveWindowResources : public WindowResources { - public: - InactiveWindowResources() { - InitClass(); - } - virtual ~InactiveWindowResources() { - } - - // WindowResources implementation: - virtual SkBitmap* GetPartBitmap(FramePartBitmap part) const { - return standard_frame_bitmaps_[part]; - } - - private: - static void InitClass() { - static bool initialized = false; - if (!initialized) { - static const int kFramePartBitmapIds[] = { - 0, - IDR_CLOSE, IDR_CLOSE_H, IDR_CLOSE_P, - IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P, - IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P, - IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P, - IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P, - IDR_DEWINDOW_BOTTOM_CENTER, IDR_DEWINDOW_BOTTOM_LEFT_CORNER, - IDR_DEWINDOW_BOTTOM_RIGHT_CORNER, IDR_DEWINDOW_LEFT_SIDE, - IDR_DEWINDOW_RIGHT_SIDE, IDR_DEWINDOW_TOP_CENTER, - IDR_DEWINDOW_TOP_LEFT_CORNER, IDR_DEWINDOW_TOP_RIGHT_CORNER, - IDR_APP_TOP_LEFT, IDR_APP_TOP_CENTER, IDR_APP_TOP_RIGHT, - IDR_CONTENT_RIGHT_SIDE, IDR_CONTENT_BOTTOM_RIGHT_CORNER, - IDR_CONTENT_BOTTOM_CENTER, IDR_CONTENT_BOTTOM_LEFT_CORNER, - IDR_CONTENT_LEFT_SIDE, - 0 - }; - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i) { - int id = kFramePartBitmapIds[i]; - if (id != 0) - standard_frame_bitmaps_[i] = rb.GetBitmapNamed(id); - } - initialized = true; - } - } - - static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT]; - - DISALLOW_EVIL_CONSTRUCTORS(InactiveWindowResources); -}; - -// static -SkBitmap* ActiveWindowResources::standard_frame_bitmaps_[]; -SkBitmap* InactiveWindowResources::standard_frame_bitmaps_[]; - -// static -WindowResources* CustomFrameView::active_resources_ = NULL; -WindowResources* CustomFrameView::inactive_resources_ = NULL; -ChromeFont CustomFrameView::title_font_; - -namespace { -// The frame border is only visible in restored mode and is hardcoded to 4 px on -// each side regardless of the system window border size. -const int kFrameBorderThickness = 4; -// Various edges of the frame border have a 1 px shadow along their edges; in a -// few cases we shift elements based on this amount for visual appeal. -const int kFrameShadowThickness = 1; -// While resize areas on Windows are normally the same size as the window -// borders, our top area is shrunk by 1 px to make it easier to move the window -// around with our thinner top grabbable strip. (Incidentally, our side and -// bottom resize areas don't match the frame border thickness either -- they -// span the whole nonclient area, so there's no "dead zone" for the mouse.) -const int kTopResizeAdjust = 1; -// In the window corners, the resize areas don't actually expand bigger, but the -// 16 px at the end of each edge triggers diagonal resizing. -const int kResizeAreaCornerSize = 16; -// The titlebar never shrinks to less than 18 px tall, plus the height of the -// frame border and any bottom edge. -const int kTitlebarMinimumHeight = 18; -// The icon is inset 2 px from the left frame border. -const int kIconLeftSpacing = 2; -// The icon takes up 16/25th of the available titlebar height. (This is -// expressed as two ints to avoid precision losses leading to off-by-one pixel -// errors.) -const int kIconHeightFractionNumerator = 16; -const int kIconHeightFractionDenominator = 25; -// The icon never shrinks below 16 px on a side. -const int kIconMinimumSize = 16; -// Because our frame border has a different "3D look" than Windows', with a less -// cluttered top edge, we need to shift the icon up by 1 px in restored mode so -// it looks more centered. -const int kIconRestoredAdjust = 1; -// There is a 4 px gap between the icon and the title text. -const int kIconTitleSpacing = 4; -// The title text starts 2 px below the bottom of the top frame border. -const int kTitleTopSpacing = 2; -// There is a 5 px gap between the title text and the caption buttons. -const int kTitleCaptionSpacing = 5; -// The caption buttons are always drawn 1 px down from the visible top of the -// window (the true top in restored mode, or the top of the screen in maximized -// mode). -const int kCaptionTopSpacing = 1; -} - -/////////////////////////////////////////////////////////////////////////////// -// CustomFrameView, public: - -CustomFrameView::CustomFrameView(Window* frame) - : NonClientFrameView(), - close_button_(new ImageButton(this)), - restore_button_(new ImageButton(this)), - maximize_button_(new ImageButton(this)), - minimize_button_(new ImageButton(this)), - system_menu_button_(new ImageButton(this)), - should_show_minmax_buttons_(false), - frame_(frame) { - InitClass(); - WindowResources* resources = active_resources_; - - // Close button images will be set in LayoutWindowControls(). - AddChildView(close_button_); - - restore_button_->SetImage(CustomButton::BS_NORMAL, - resources->GetPartBitmap(FRAME_RESTORE_BUTTON_ICON)); - restore_button_->SetImage(CustomButton::BS_HOT, - resources->GetPartBitmap(FRAME_RESTORE_BUTTON_ICON_H)); - restore_button_->SetImage(CustomButton::BS_PUSHED, - resources->GetPartBitmap(FRAME_RESTORE_BUTTON_ICON_P)); - AddChildView(restore_button_); - - maximize_button_->SetImage(CustomButton::BS_NORMAL, - resources->GetPartBitmap(FRAME_MAXIMIZE_BUTTON_ICON)); - maximize_button_->SetImage(CustomButton::BS_HOT, - resources->GetPartBitmap(FRAME_MAXIMIZE_BUTTON_ICON_H)); - maximize_button_->SetImage(CustomButton::BS_PUSHED, - resources->GetPartBitmap(FRAME_MAXIMIZE_BUTTON_ICON_P)); - AddChildView(maximize_button_); - - minimize_button_->SetImage(CustomButton::BS_NORMAL, - resources->GetPartBitmap(FRAME_MINIMIZE_BUTTON_ICON)); - minimize_button_->SetImage(CustomButton::BS_HOT, - resources->GetPartBitmap(FRAME_MINIMIZE_BUTTON_ICON_H)); - minimize_button_->SetImage(CustomButton::BS_PUSHED, - resources->GetPartBitmap(FRAME_MINIMIZE_BUTTON_ICON_P)); - AddChildView(minimize_button_); - - should_show_minmax_buttons_ = frame_->GetDelegate()->CanMaximize(); - - AddChildView(system_menu_button_); -} - -CustomFrameView::~CustomFrameView() { -} - -/////////////////////////////////////////////////////////////////////////////// -// CustomFrameView, NonClientFrameView implementation: - -gfx::Rect CustomFrameView::GetBoundsForClientView() const { - return client_view_bounds_; -} - -gfx::Rect CustomFrameView::GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const { - int top_height = NonClientTopBorderHeight(); - int border_thickness = NonClientBorderThickness(); - return gfx::Rect(std::max(0, client_bounds.x() - border_thickness), - std::max(0, client_bounds.y() - top_height), - client_bounds.width() + (2 * border_thickness), - client_bounds.height() + top_height + border_thickness); -} - -gfx::Point CustomFrameView::GetSystemMenuPoint() const { - gfx::Point system_menu_point(FrameBorderThickness(), - NonClientTopBorderHeight() - BottomEdgeThicknessWithinNonClientHeight()); - ConvertPointToScreen(this, &system_menu_point); - return system_menu_point; -} - -int CustomFrameView::NonClientHitTest(const gfx::Point& point) { - // Then see if the point is within any of the window controls. - if (close_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(point)) - return HTCLOSE; - if (restore_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains( - point)) - return HTMAXBUTTON; - if (maximize_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains( - point)) - return HTMAXBUTTON; - if (minimize_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains( - point)) - return HTMINBUTTON; - if (system_menu_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains( - point)) - return HTSYSMENU; - - int window_component = GetHTComponentForFrame(point, FrameBorderThickness(), - NonClientBorderThickness(), kResizeAreaCornerSize, kResizeAreaCornerSize, - frame_->GetDelegate()->CanResize()); - // Fall back to the caption if no other component matches. - return (window_component == HTNOWHERE) ? HTCAPTION : window_component; -} - -void CustomFrameView::GetWindowMask(const gfx::Size& size, - gfx::Path* window_mask) { - DCHECK(window_mask); - - // Redefine the window visible region for the new size. - window_mask->moveTo(0, 3); - window_mask->lineTo(1, 2); - window_mask->lineTo(1, 1); - window_mask->lineTo(2, 1); - window_mask->lineTo(3, 0); - - window_mask->lineTo(SkIntToScalar(size.width() - 3), 0); - window_mask->lineTo(SkIntToScalar(size.width() - 2), 1); - window_mask->lineTo(SkIntToScalar(size.width() - 1), 1); - window_mask->lineTo(SkIntToScalar(size.width() - 1), 2); - window_mask->lineTo(SkIntToScalar(size.width()), 3); - - window_mask->lineTo(SkIntToScalar(size.width()), - SkIntToScalar(size.height())); - window_mask->lineTo(0, SkIntToScalar(size.height())); - window_mask->close(); -} - -void CustomFrameView::EnableClose(bool enable) { - close_button_->SetEnabled(enable); -} - -void CustomFrameView::ResetWindowControls() { - restore_button_->SetState(CustomButton::BS_NORMAL); - minimize_button_->SetState(CustomButton::BS_NORMAL); - maximize_button_->SetState(CustomButton::BS_NORMAL); - // The close button isn't affected by this constraint. -} - -/////////////////////////////////////////////////////////////////////////////// -// CustomFrameView, View overrides: - -void CustomFrameView::Paint(ChromeCanvas* canvas) { - if (frame_->IsMaximized()) - PaintMaximizedFrameBorder(canvas); - else - PaintRestoredFrameBorder(canvas); - PaintTitleBar(canvas); - if (!frame_->IsMaximized()) - PaintRestoredClientEdge(canvas); -} - -void CustomFrameView::Layout() { - LayoutWindowControls(); - LayoutTitleBar(); - LayoutClientView(); -} - -gfx::Size CustomFrameView::GetPreferredSize() { - gfx::Size pref = frame_->GetClientView()->GetPreferredSize(); - DCHECK(pref.width() > 0 && pref.height() > 0); - gfx::Rect bounds(0, 0, pref.width(), pref.height()); - return frame_->GetNonClientView()->GetWindowBoundsForClientBounds( - bounds).size(); -} - -/////////////////////////////////////////////////////////////////////////////// -// CustomFrameView, ButtonListener implementation: - -void CustomFrameView::ButtonPressed(Button* sender) { - if (sender == close_button_) - frame_->Close(); - else if (sender == minimize_button_) - frame_->Minimize(); - else if (sender == maximize_button_) - frame_->Maximize(); - else if (sender == restore_button_) - frame_->Restore(); -} - -/////////////////////////////////////////////////////////////////////////////// -// CustomFrameView, private: - -int CustomFrameView::FrameBorderThickness() const { - return frame_->IsMaximized() ? - GetSystemMetrics(SM_CXSIZEFRAME) : kFrameBorderThickness; -} - -int CustomFrameView::NonClientBorderThickness() const { - // In maximized mode, we don't show a client edge. - return FrameBorderThickness() + - (frame_->IsMaximized() ? 0 : kClientEdgeThickness); -} - -int CustomFrameView::NonClientTopBorderHeight() const { - int title_top_spacing, title_thickness; - return TitleCoordinates(&title_top_spacing, &title_thickness); -} - -int CustomFrameView::BottomEdgeThicknessWithinNonClientHeight() const { - return kFrameShadowThickness + - (frame_->IsMaximized() ? 0 : kClientEdgeThickness); -} - -int CustomFrameView::TitleCoordinates(int* title_top_spacing, - int* title_thickness) const { - int frame_thickness = FrameBorderThickness(); - int min_titlebar_height = kTitlebarMinimumHeight + frame_thickness; - *title_top_spacing = frame_thickness + kTitleTopSpacing; - // The bottom spacing should be the same apparent height as the top spacing. - // Because the actual top spacing height varies based on the system border - // thickness, we calculate this based on the restored top spacing and then - // adjust for maximized mode. We also don't include the frame shadow here, - // since while it's part of the bottom spacing it will be added in at the end. - int title_bottom_spacing = - kFrameBorderThickness + kTitleTopSpacing - kFrameShadowThickness; - if (frame_->IsMaximized()) { - // When we maximize, the top border appears to be chopped off; shift the - // title down to stay centered within the remaining space. - int title_adjust = (kFrameBorderThickness / 2); - *title_top_spacing += title_adjust; - title_bottom_spacing -= title_adjust; - } - *title_thickness = std::max(title_font_.height(), - min_titlebar_height - *title_top_spacing - title_bottom_spacing); - return *title_top_spacing + *title_thickness + title_bottom_spacing + - BottomEdgeThicknessWithinNonClientHeight(); -} - -void CustomFrameView::PaintRestoredFrameBorder(ChromeCanvas* canvas) { - SkBitmap* top_left_corner = resources()->GetPartBitmap(FRAME_TOP_LEFT_CORNER); - SkBitmap* top_right_corner = - resources()->GetPartBitmap(FRAME_TOP_RIGHT_CORNER); - SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE); - SkBitmap* right_edge = resources()->GetPartBitmap(FRAME_RIGHT_EDGE); - SkBitmap* left_edge = resources()->GetPartBitmap(FRAME_LEFT_EDGE); - SkBitmap* bottom_left_corner = - resources()->GetPartBitmap(FRAME_BOTTOM_LEFT_CORNER); - SkBitmap* bottom_right_corner = - resources()->GetPartBitmap(FRAME_BOTTOM_RIGHT_CORNER); - SkBitmap* bottom_edge = resources()->GetPartBitmap(FRAME_BOTTOM_EDGE); - - // Top. - canvas->DrawBitmapInt(*top_left_corner, 0, 0); - canvas->TileImageInt(*top_edge, top_left_corner->width(), 0, - width() - top_right_corner->width(), top_edge->height()); - canvas->DrawBitmapInt(*top_right_corner, - width() - top_right_corner->width(), 0); - - // Right. - canvas->TileImageInt(*right_edge, width() - right_edge->width(), - top_right_corner->height(), right_edge->width(), - height() - top_right_corner->height() - - bottom_right_corner->height()); - - // Bottom. - canvas->DrawBitmapInt(*bottom_right_corner, - width() - bottom_right_corner->width(), - height() - bottom_right_corner->height()); - canvas->TileImageInt(*bottom_edge, bottom_left_corner->width(), - height() - bottom_edge->height(), - width() - bottom_left_corner->width() - - bottom_right_corner->width(), - bottom_edge->height()); - canvas->DrawBitmapInt(*bottom_left_corner, 0, - height() - bottom_left_corner->height()); - - // Left. - canvas->TileImageInt(*left_edge, 0, top_left_corner->height(), - left_edge->width(), - height() - top_left_corner->height() - bottom_left_corner->height()); -} - -void CustomFrameView::PaintMaximizedFrameBorder( - ChromeCanvas* canvas) { - SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE); - canvas->TileImageInt(*top_edge, 0, FrameBorderThickness(), width(), - top_edge->height()); - - // The bottom of the titlebar actually comes from the top of the Client Edge - // graphic, with the actual client edge clipped off the bottom. - SkBitmap* titlebar_bottom = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP); - int edge_height = titlebar_bottom->height() - kClientEdgeThickness; - canvas->TileImageInt(*titlebar_bottom, 0, - frame_->GetClientView()->y() - edge_height, width(), edge_height); -} - -void CustomFrameView::PaintTitleBar(ChromeCanvas* canvas) { - WindowDelegate* d = frame_->GetDelegate(); - - // It seems like in some conditions we can be asked to paint after the window - // that contains us is WM_DESTROYed. At this point, our delegate is NULL. The - // correct long term fix may be to shut down the RootView in WM_DESTROY. - if (!d) - return; - - canvas->DrawStringInt(d->GetWindowTitle(), title_font_, SK_ColorWHITE, - MirroredLeftPointForRect(title_bounds_), title_bounds_.y(), - title_bounds_.width(), title_bounds_.height()); -} - -void CustomFrameView::PaintRestoredClientEdge(ChromeCanvas* canvas) { - gfx::Rect client_area_bounds = frame_->GetClientView()->bounds(); - int client_area_top = client_area_bounds.y(); - - SkBitmap* top_left = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_LEFT); - SkBitmap* top = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP); - SkBitmap* top_right = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_RIGHT); - SkBitmap* right = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_RIGHT); - SkBitmap* bottom_right = - resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_RIGHT); - SkBitmap* bottom = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM); - SkBitmap* bottom_left = - resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_LEFT); - SkBitmap* left = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_LEFT); - - // Top. - // This next calculation is necessary because the top center bitmap is shorter - // than the top left and right bitmaps. We need their top edges to line up, - // and we need the left and right edges to start below the corners' bottoms. - int top_edge_y = client_area_top - top->height(); - client_area_top = top_edge_y + top_left->height(); - canvas->DrawBitmapInt(*top_left, client_area_bounds.x() - top_left->width(), - top_edge_y); - canvas->TileImageInt(*top, client_area_bounds.x(), top_edge_y, - client_area_bounds.width(), top->height()); - canvas->DrawBitmapInt(*top_right, client_area_bounds.right(), top_edge_y); - - // Right. - int client_area_bottom = - std::max(client_area_top, client_area_bounds.bottom()); - int client_area_height = client_area_bottom - client_area_top; - canvas->TileImageInt(*right, client_area_bounds.right(), client_area_top, - right->width(), client_area_height); - - // Bottom. - canvas->DrawBitmapInt(*bottom_right, client_area_bounds.right(), - client_area_bottom); - canvas->TileImageInt(*bottom, client_area_bounds.x(), client_area_bottom, - client_area_bounds.width(), bottom_right->height()); - canvas->DrawBitmapInt(*bottom_left, - client_area_bounds.x() - bottom_left->width(), client_area_bottom); - - // Left. - canvas->TileImageInt(*left, client_area_bounds.x() - left->width(), - client_area_top, left->width(), client_area_height); -} - -void CustomFrameView::LayoutWindowControls() { - close_button_->SetImageAlignment(ImageButton::ALIGN_LEFT, - ImageButton::ALIGN_BOTTOM); - // Maximized buttons start at window top so that even if their images aren't - // drawn flush with the screen edge, they still obey Fitts' Law. - bool is_maximized = frame_->IsMaximized(); - int frame_thickness = FrameBorderThickness(); - int caption_y = is_maximized ? frame_thickness : kCaptionTopSpacing; - int top_extra_height = is_maximized ? kCaptionTopSpacing : 0; - // There should always be the same number of non-shadow pixels visible to the - // side of the caption buttons. In maximized mode we extend the rightmost - // button to the screen corner to obey Fitts' Law. - int right_extra_width = is_maximized ? - (kFrameBorderThickness - kFrameShadowThickness) : 0; - int right_spacing = is_maximized ? - (GetSystemMetrics(SM_CXSIZEFRAME) + right_extra_width) : frame_thickness; - gfx::Size close_button_size = close_button_->GetPreferredSize(); - close_button_->SetBounds(width() - close_button_size.width() - right_spacing, - caption_y, - close_button_size.width() + right_extra_width, - close_button_size.height() + top_extra_height); - - // When the window is restored, we show a maximized button; otherwise, we show - // a restore button. - bool is_restored = !is_maximized && !frame_->IsMinimized(); - views::ImageButton* invisible_button = is_restored ? - restore_button_ : maximize_button_; - invisible_button->SetVisible(false); - - views::ImageButton* visible_button = is_restored ? - maximize_button_ : restore_button_; - FramePartBitmap normal_part, hot_part, pushed_part; - if (should_show_minmax_buttons_) { - visible_button->SetVisible(true); - visible_button->SetImageAlignment(ImageButton::ALIGN_LEFT, - ImageButton::ALIGN_BOTTOM); - gfx::Size visible_button_size = visible_button->GetPreferredSize(); - visible_button->SetBounds(close_button_->x() - visible_button_size.width(), - caption_y, visible_button_size.width(), - visible_button_size.height() + top_extra_height); - - minimize_button_->SetVisible(true); - minimize_button_->SetImageAlignment(ImageButton::ALIGN_LEFT, - ImageButton::ALIGN_BOTTOM); - gfx::Size minimize_button_size = minimize_button_->GetPreferredSize(); - minimize_button_->SetBounds( - visible_button->x() - minimize_button_size.width(), caption_y, - minimize_button_size.width(), - minimize_button_size.height() + top_extra_height); - - normal_part = FRAME_CLOSE_BUTTON_ICON; - hot_part = FRAME_CLOSE_BUTTON_ICON_H; - pushed_part = FRAME_CLOSE_BUTTON_ICON_P; - } else { - visible_button->SetVisible(false); - minimize_button_->SetVisible(false); - - normal_part = FRAME_CLOSE_BUTTON_ICON_SA; - hot_part = FRAME_CLOSE_BUTTON_ICON_SA_H; - pushed_part = FRAME_CLOSE_BUTTON_ICON_SA_P; - } - - close_button_->SetImage(CustomButton::BS_NORMAL, - active_resources_->GetPartBitmap(normal_part)); - close_button_->SetImage(CustomButton::BS_HOT, - active_resources_->GetPartBitmap(hot_part)); - close_button_->SetImage(CustomButton::BS_PUSHED, - active_resources_->GetPartBitmap(pushed_part)); -} - -void CustomFrameView::LayoutTitleBar() { - // Always lay out the icon, even when it's not present, so we can lay out the - // window title based on its position. - int frame_thickness = FrameBorderThickness(); - int icon_x = frame_thickness + kIconLeftSpacing; - - // The usable height of the titlebar area is the total height minus the top - // resize border and any edge area we draw at its bottom. - int title_top_spacing, title_thickness; - int top_height = TitleCoordinates(&title_top_spacing, &title_thickness); - int available_height = top_height - frame_thickness - - BottomEdgeThicknessWithinNonClientHeight(); - - // The icon takes up a constant fraction of the available height, down to a - // minimum size, and is always an even number of pixels on a side (presumably - // to make scaled icons look better). It's centered within the usable height. - int icon_size = std::max((available_height * kIconHeightFractionNumerator / - kIconHeightFractionDenominator) / 2 * 2, kIconMinimumSize); - int icon_y = ((available_height - icon_size) / 2) + frame_thickness; - - // Hack: Our frame border has a different "3D look" than Windows'. Theirs has - // a more complex gradient on the top that they push their icon/title below; - // then the maximized window cuts this off and the icon/title are centered in - // the remaining space. Because the apparent shape of our border is simpler, - // using the same positioning makes things look slightly uncentered with - // restored windows, so we come up to compensate. - if (!frame_->IsMaximized()) - icon_y -= kIconRestoredAdjust; - - views::WindowDelegate* d = frame_->GetDelegate(); - if (!d->ShouldShowWindowIcon()) - icon_size = 0; - system_menu_button_->SetBounds(icon_x, icon_y, icon_size, icon_size); - - // Size the title. - int icon_right = icon_x + icon_size; - int title_x = - icon_right + (d->ShouldShowWindowIcon() ? kIconTitleSpacing : 0); - int title_right = (should_show_minmax_buttons_ ? - minimize_button_->x() : close_button_->x()) - kTitleCaptionSpacing; - title_bounds_.SetRect(title_x, - title_top_spacing + ((title_thickness - title_font_.height()) / 2), - std::max(0, title_right - title_x), title_font_.height()); -} - -void CustomFrameView::LayoutClientView() { - int top_height = NonClientTopBorderHeight(); - int border_thickness = NonClientBorderThickness(); - client_view_bounds_.SetRect( - border_thickness, - top_height, - std::max(0, width() - (2 * border_thickness)), - std::max(0, height() - top_height - border_thickness)); -} - -// static -void CustomFrameView::InitClass() { - static bool initialized = false; - if (!initialized) { - active_resources_ = new ActiveWindowResources; - inactive_resources_ = new InactiveWindowResources; - - title_font_ = win_util::GetWindowTitleFont(); - - initialized = true; - } -} - -} // namespace views diff --git a/chrome/views/custom_frame_view.h b/chrome/views/custom_frame_view.h deleted file mode 100644 index 2edc3f9..0000000 --- a/chrome/views/custom_frame_view.h +++ /dev/null @@ -1,122 +0,0 @@ -// 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_VIEWS_CUSTOM_FRAME_VIEW_H_ -#define CHROME_VIEWS_CUSTOM_FRAME_VIEW_H_ - -#include "chrome/views/image_button.h" -#include "chrome/views/non_client_view.h" -#include "chrome/views/window.h" -#include "chrome/views/window_resources.h" - -namespace gfx{ -class Size; -class Path; -class Point; -} -class ChromeCanvas; -class ChromeFont; - -namespace views { - -/////////////////////////////////////////////////////////////////////////////// -// -// CustomFrameView -// -// A ChromeView that provides the non client frame for Windows. This means -// rendering the non-standard window caption, border, and controls. -// -//////////////////////////////////////////////////////////////////////////////// -class CustomFrameView : public NonClientFrameView, - public ButtonListener { - public: - explicit CustomFrameView(Window* frame); - virtual ~CustomFrameView(); - - // Overridden from views::NonClientFrameView: - virtual gfx::Rect GetBoundsForClientView() const; - virtual gfx::Rect GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const; - virtual gfx::Point GetSystemMenuPoint() const; - virtual int NonClientHitTest(const gfx::Point& point); - virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask); - virtual void EnableClose(bool enable); - virtual void ResetWindowControls(); - - // View overrides: - virtual void Paint(ChromeCanvas* canvas); - virtual void Layout(); - virtual gfx::Size GetPreferredSize(); - - // ButtonListener implementation: - virtual void ButtonPressed(Button* sender); - - private: - // Returns the thickness of the border that makes up the window frame edges. - // This does not include any client edge. - int FrameBorderThickness() const; - - // Returns the thickness of the entire nonclient left, right, and bottom - // borders, including both the window frame and any client edge. - int NonClientBorderThickness() const; - - // Returns the height of the entire nonclient top border, including the window - // frame, any title area, and any connected client edge. - int NonClientTopBorderHeight() const; - - // A bottom border, and, in restored mode, a client edge are drawn at the - // bottom of the titlebar. This returns the total height drawn. - int BottomEdgeThicknessWithinNonClientHeight() const; - - // Calculates multiple values related to title layout. Returns the height of - // the entire titlebar including any connected client edge. - int TitleCoordinates(int* title_top_spacing, - int* title_thickness) const; - - // Paint various sub-components of this view. - void PaintRestoredFrameBorder(ChromeCanvas* canvas); - void PaintMaximizedFrameBorder(ChromeCanvas* canvas); - void PaintTitleBar(ChromeCanvas* canvas); - void PaintRestoredClientEdge(ChromeCanvas* canvas); - - // Layout various sub-components of this view. - void LayoutWindowControls(); - void LayoutTitleBar(); - void LayoutClientView(); - - // Returns the resource collection to be used when rendering the window. - WindowResources* resources() const { - return frame_->IsActive() || paint_as_active() ? active_resources_ - : inactive_resources_; - } - - // The bounds of the client view, in this view's coordinates. - gfx::Rect client_view_bounds_; - - // The layout rect of the title, if visible. - gfx::Rect title_bounds_; - - // Window controls. - ImageButton* close_button_; - ImageButton* restore_button_; - ImageButton* maximize_button_; - ImageButton* minimize_button_; - ImageButton* system_menu_button_; // Uses the window icon if visible. - bool should_show_minmax_buttons_; - - // The window that owns this view. - Window* frame_; - - // Initialize various static resources. - static void InitClass(); - static WindowResources* active_resources_; - static WindowResources* inactive_resources_; - static ChromeFont title_font_; - - DISALLOW_EVIL_CONSTRUCTORS(CustomFrameView); -}; - -} // namespace views - -#endif // #ifndef CHROME_VIEWS_CUSTOM_FRAME_VIEW_H_ diff --git a/chrome/views/dialog_client_view.cc b/chrome/views/dialog_client_view.cc deleted file mode 100644 index 74732a3..0000000 --- a/chrome/views/dialog_client_view.cc +++ /dev/null @@ -1,434 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include -#include -#include - -#include "chrome/views/dialog_client_view.h" - -#include "base/gfx/native_theme.h" -#include "chrome/browser/views/standard_layout.h" -#include "chrome/common/gfx/chrome_canvas.h" -#include "chrome/common/gfx/chrome_font.h" -#include "chrome/common/l10n_util.h" -#include "chrome/common/resource_bundle.h" -#include "chrome/common/win_util.h" -#include "chrome/views/dialog_delegate.h" -#include "chrome/views/window.h" -#include "grit/generated_resources.h" - -namespace views { - -namespace { - -// Updates any of the standard buttons according to the delegate. -void UpdateButtonHelper(NativeButton* button_view, - DialogDelegate* delegate, - DialogDelegate::DialogButton button) { - std::wstring label = delegate->GetDialogButtonLabel(button); - if (!label.empty()) - button_view->SetLabel(label); - button_view->SetEnabled(delegate->IsDialogButtonEnabled(button)); - button_view->SetVisible(delegate->IsDialogButtonVisible(button)); -} - -void FillViewWithSysColor(ChromeCanvas* canvas, View* view, COLORREF color) { - SkColor sk_color = - SkColorSetRGB(GetRValue(color), GetGValue(color), GetBValue(color)); - canvas->FillRectInt(sk_color, 0, 0, view->width(), view->height()); -} - -// DialogButton ---------------------------------------------------------------- - -// DialogButtons is used for the ok/cancel buttons of the window. DialogButton -// forwards AcceleratorPressed to the delegate. - -class DialogButton : public NativeButton { - public: - DialogButton(Window* owner, - DialogDelegate::DialogButton type, - const std::wstring& title, - bool is_default) - : NativeButton(title, is_default), owner_(owner), type_(type) { - } - - // Overridden to forward to the delegate. - virtual bool AcceleratorPressed(const Accelerator& accelerator) { - if (!owner_->GetDelegate()->AsDialogDelegate()-> - AreAcceleratorsEnabled(type_)) { - return false; - } - return NativeButton::AcceleratorPressed(accelerator); - } - - private: - Window* owner_; - const DialogDelegate::DialogButton type_; - - DISALLOW_COPY_AND_ASSIGN(DialogButton); -}; - -} // namespace - -// static -ChromeFont DialogClientView::dialog_button_font_; -static const int kDialogMinButtonWidth = 75; -static const int kDialogButtonLabelSpacing = 16; -static const int kDialogButtonContentSpacing = 5; - -// The group used by the buttons. This name is chosen voluntarily big not to -// conflict with other groups that could be in the dialog content. -static const int kButtonGroup = 6666; - -/////////////////////////////////////////////////////////////////////////////// -// DialogClientView, public: - -DialogClientView::DialogClientView(Window* owner, View* contents_view) - : ClientView(owner, contents_view), - ok_button_(NULL), - cancel_button_(NULL), - extra_view_(NULL), - accepted_(false), - default_button_(NULL) { - InitClass(); -} - -DialogClientView::~DialogClientView() { -} - -void DialogClientView::ShowDialogButtons() { - DialogDelegate* dd = GetDialogDelegate(); - int buttons = dd->GetDialogButtons(); - if (buttons & DialogDelegate::DIALOGBUTTON_OK && !ok_button_) { - std::wstring label = - dd->GetDialogButtonLabel(DialogDelegate::DIALOGBUTTON_OK); - if (label.empty()) - label = l10n_util::GetString(IDS_OK); - bool is_default_button = - (dd->GetDefaultDialogButton() & DialogDelegate::DIALOGBUTTON_OK) != 0; - ok_button_ = new DialogButton(window(), DialogDelegate::DIALOGBUTTON_OK, - label, is_default_button); - ok_button_->SetListener(this); - ok_button_->SetGroup(kButtonGroup); - if (is_default_button) - default_button_ = ok_button_; - if (!(buttons & DialogDelegate::DIALOGBUTTON_CANCEL)) - ok_button_->AddAccelerator(Accelerator(VK_ESCAPE, false, false, false)); - AddChildView(ok_button_); - } - if (buttons & DialogDelegate::DIALOGBUTTON_CANCEL && !cancel_button_) { - std::wstring label = - dd->GetDialogButtonLabel(DialogDelegate::DIALOGBUTTON_CANCEL); - if (label.empty()) { - if (buttons & DialogDelegate::DIALOGBUTTON_OK) { - label = l10n_util::GetString(IDS_CANCEL); - } else { - label = l10n_util::GetString(IDS_CLOSE); - } - } - bool is_default_button = - (dd->GetDefaultDialogButton() & DialogDelegate::DIALOGBUTTON_CANCEL) - != 0; - cancel_button_ = new DialogButton(window(), - DialogDelegate::DIALOGBUTTON_CANCEL, - label, is_default_button); - cancel_button_->SetListener(this); - cancel_button_->SetGroup(kButtonGroup); - cancel_button_->AddAccelerator(Accelerator(VK_ESCAPE, false, false, false)); - if (is_default_button) - default_button_ = ok_button_; - AddChildView(cancel_button_); - } - if (!buttons) { - // Register the escape key as an accelerator which will close the window - // if there are no dialog buttons. - AddAccelerator(Accelerator(VK_ESCAPE, false, false, false)); - } -} - -void DialogClientView::SetDefaultButton(NativeButton* new_default_button) { - if (default_button_ && default_button_ != new_default_button) { - default_button_->SetDefaultButton(false); - default_button_ = NULL; - } - - if (new_default_button) { - default_button_ = new_default_button; - default_button_->SetDefaultButton(true); - } -} - -void DialogClientView::FocusWillChange(View* focused_before, - View* focused_now) { - NativeButton* new_default_button = NULL; - if (focused_now && - focused_now->GetClassName() == NativeButton::kViewClassName) { - new_default_button = static_cast(focused_now); - } else { - // The focused view is not a button, get the default button from the - // delegate. - DialogDelegate* dd = GetDialogDelegate(); - if ((dd->GetDefaultDialogButton() & DialogDelegate::DIALOGBUTTON_OK) != 0) - new_default_button = ok_button_; - if ((dd->GetDefaultDialogButton() & DialogDelegate::DIALOGBUTTON_CANCEL) - != 0) - new_default_button = cancel_button_; - } - SetDefaultButton(new_default_button); -} - -// Changing dialog labels will change button widths. -void DialogClientView::UpdateDialogButtons() { - DialogDelegate* dd = GetDialogDelegate(); - int buttons = dd->GetDialogButtons(); - - if (buttons & DialogDelegate::DIALOGBUTTON_OK) - UpdateButtonHelper(ok_button_, dd, DialogDelegate::DIALOGBUTTON_OK); - - if (buttons & DialogDelegate::DIALOGBUTTON_CANCEL) - UpdateButtonHelper(cancel_button_, dd, DialogDelegate::DIALOGBUTTON_CANCEL); - - LayoutDialogButtons(); - SchedulePaint(); -} - -void DialogClientView::AcceptWindow() { - if (accepted_) { - // We should only get into AcceptWindow once. - NOTREACHED(); - return; - } - accepted_ = true; - if (GetDialogDelegate()->Accept(false)) - window()->Close(); -} - -void DialogClientView::CancelWindow() { - // Call the standard Close handler, which checks with the delegate before - // proceeding. This checking _isn't_ done here, but in the WM_CLOSE handler, - // so that the close box on the window also shares this code path. - window()->Close(); -} - -/////////////////////////////////////////////////////////////////////////////// -// DialogClientView, ClientView overrides: - -bool DialogClientView::CanClose() const { - if (!accepted_) { - DialogDelegate* dd = GetDialogDelegate(); - int buttons = dd->GetDialogButtons(); - if (buttons & DialogDelegate::DIALOGBUTTON_CANCEL) - return dd->Cancel(); - if (buttons & DialogDelegate::DIALOGBUTTON_OK) - return dd->Accept(true); - } - return true; -} - -void DialogClientView::WindowClosing() { - FocusManager* focus_manager = GetFocusManager(); - DCHECK(focus_manager); - if (focus_manager) - focus_manager->RemoveFocusChangeListener(this); - ClientView::WindowClosing(); -} - -int DialogClientView::NonClientHitTest(const gfx::Point& point) { - if (size_box_bounds_.Contains(point.x() - x(), point.y() - y())) - return HTBOTTOMRIGHT; - return ClientView::NonClientHitTest(point); -} - -//////////////////////////////////////////////////////////////////////////////// -// DialogClientView, View overrides: - -void DialogClientView::Paint(ChromeCanvas* canvas) { - FillViewWithSysColor(canvas, this, GetSysColor(COLOR_3DFACE)); -} - -void DialogClientView::PaintChildren(ChromeCanvas* canvas) { - View::PaintChildren(canvas); - if (!window()->IsMaximized() && !window()->IsMinimized()) - PaintSizeBox(canvas); -} - -void DialogClientView::Layout() { - if (has_dialog_buttons()) - LayoutDialogButtons(); - LayoutContentsView(); -} - -void DialogClientView::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 - // Container's HWND. - ShowDialogButtons(); - ClientView::ViewHierarchyChanged(is_add, parent, child); - - FocusManager* focus_manager = GetFocusManager(); - // Listen for focus change events so we can update the default button. - DCHECK(focus_manager); // bug #1291225: crash reports seem to indicate it - // can be NULL. - if (focus_manager) - focus_manager->AddFocusChangeListener(this); - - // The "extra view" must be created and installed after the contents view - // has been inserted into the view hierarchy. - CreateExtraView(); - UpdateDialogButtons(); - Layout(); - } -} - -gfx::Size DialogClientView::GetPreferredSize() { - gfx::Size prefsize = contents_view()->GetPreferredSize(); - int button_height = 0; - if (has_dialog_buttons()) { - if (cancel_button_) - button_height = cancel_button_->height(); - else - button_height = ok_button_->height(); - // Account for padding above and below the button. - button_height += kDialogButtonContentSpacing + kButtonVEdgeMargin; - } - prefsize.Enlarge(0, button_height); - return prefsize; -} - -bool DialogClientView::AcceleratorPressed(const Accelerator& accelerator) { - DCHECK(accelerator.GetKeyCode() == VK_ESCAPE); // We only expect Escape key. - window()->Close(); - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// DialogClientView, NativeButton::Listener implementation: - -void DialogClientView::ButtonPressed(NativeButton* sender) { - if (sender == ok_button_) { - AcceptWindow(); - } else if (sender == cancel_button_) { - CancelWindow(); - } else { - NOTREACHED(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// DialogClientView, private: - -void DialogClientView::PaintSizeBox(ChromeCanvas* canvas) { - if (window()->GetDelegate()->CanResize() || - window()->GetDelegate()->CanMaximize()) { - HDC dc = canvas->beginPlatformPaint(); - SIZE gripper_size = { 0, 0 }; - gfx::NativeTheme::instance()->GetThemePartSize( - gfx::NativeTheme::STATUS, dc, SP_GRIPPER, 1, NULL, TS_TRUE, - &gripper_size); - - // TODO(beng): (http://b/1085509) In "classic" rendering mode, there isn't - // a theme-supplied gripper. We should probably improvise - // something, which would also require changing |gripper_size| - // to have different default values, too... - size_box_bounds_ = GetLocalBounds(false); - size_box_bounds_.set_x(size_box_bounds_.right() - gripper_size.cx); - size_box_bounds_.set_y(size_box_bounds_.bottom() - gripper_size.cy); - RECT native_bounds = size_box_bounds_.ToRECT(); - gfx::NativeTheme::instance()->PaintStatusGripper( - dc, SP_PANE, 1, 0, &native_bounds); - canvas->endPlatformPaint(); - } -} - -int DialogClientView::GetButtonWidth(int button) const { - DialogDelegate* dd = GetDialogDelegate(); - std::wstring button_label = dd->GetDialogButtonLabel( - static_cast(button)); - int string_width = dialog_button_font_.GetStringWidth(button_label); - return std::max(string_width + kDialogButtonLabelSpacing, - kDialogMinButtonWidth); -} - -int DialogClientView::GetButtonsHeight() const { - if (has_dialog_buttons()) { - if (cancel_button_) - return cancel_button_->height() + kDialogButtonContentSpacing; - return ok_button_->height() + kDialogButtonContentSpacing; - } - return 0; -} - -void DialogClientView::LayoutDialogButtons() { - gfx::Rect extra_bounds; - if (cancel_button_) { - gfx::Size ps = cancel_button_->GetPreferredSize(); - gfx::Rect lb = GetLocalBounds(false); - int button_width = GetButtonWidth(DialogDelegate::DIALOGBUTTON_CANCEL); - int button_x = lb.right() - button_width - kButtonHEdgeMargin; - int button_y = lb.bottom() - ps.height() - kButtonVEdgeMargin; - cancel_button_->SetBounds(button_x, button_y, button_width, ps.height()); - // The extra view bounds are dependent on this button. - extra_bounds.set_width(std::max(0, cancel_button_->x())); - extra_bounds.set_y(cancel_button_->y()); - } - if (ok_button_) { - gfx::Size ps = ok_button_->GetPreferredSize(); - gfx::Rect lb = GetLocalBounds(false); - int button_width = GetButtonWidth(DialogDelegate::DIALOGBUTTON_OK); - int ok_button_right = lb.right() - kButtonHEdgeMargin; - if (cancel_button_) - ok_button_right = cancel_button_->x() - kRelatedButtonHSpacing; - int button_x = ok_button_right - button_width; - int button_y = lb.bottom() - ps.height() - kButtonVEdgeMargin; - ok_button_->SetBounds(button_x, button_y, ok_button_right - button_x, - ps.height()); - // The extra view bounds are dependent on this button. - extra_bounds.set_width(std::max(0, ok_button_->x())); - extra_bounds.set_y(ok_button_->y()); - } - if (extra_view_) { - gfx::Size ps = extra_view_->GetPreferredSize(); - gfx::Rect lb = GetLocalBounds(false); - extra_bounds.set_x(lb.x() + kButtonHEdgeMargin); - extra_bounds.set_height(ps.height()); - extra_view_->SetBounds(extra_bounds); - } -} - -void DialogClientView::LayoutContentsView() { - gfx::Rect lb = GetLocalBounds(false); - lb.set_height(std::max(0, lb.height() - GetButtonsHeight())); - contents_view()->SetBounds(lb); - contents_view()->Layout(); -} - -void DialogClientView::CreateExtraView() { - View* extra_view = GetDialogDelegate()->GetExtraView(); - if (extra_view && !extra_view_) { - extra_view_ = extra_view; - extra_view_->SetGroup(kButtonGroup); - AddChildView(extra_view_); - } -} - -DialogDelegate* DialogClientView::GetDialogDelegate() const { - DialogDelegate* dd = window()->GetDelegate()->AsDialogDelegate(); - DCHECK(dd); - return dd; -} - -// static -void DialogClientView::InitClass() { - static bool initialized = false; - if (!initialized) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - dialog_button_font_ = rb.GetFont(ResourceBundle::BaseFont); - initialized = true; - } -} - -} // namespace views diff --git a/chrome/views/dialog_client_view.h b/chrome/views/dialog_client_view.h deleted file mode 100644 index e8bbdc2..0000000 --- a/chrome/views/dialog_client_view.h +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) 2006-2008 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_VIEWS_DIALOG_CLIENT_VIEW_H_ -#define CHROME_VIEWS_DIALOG_CLIENT_VIEW_H_ - -#include "chrome/common/gfx/chrome_font.h" -#include "chrome/views/client_view.h" -#include "chrome/views/focus_manager.h" -#include "chrome/views/native_button.h" - -namespace views { - -class DialogDelegate; -class Window; - -/////////////////////////////////////////////////////////////////////////////// -// DialogClientView -// -// This ClientView subclass provides the content of a typical dialog box, -// including a strip of buttons at the bottom right of the window, default -// accelerator handlers for accept and cancel, and the ability for the -// embedded contents view to provide extra UI to be shown in the row of -// buttons. -// -class DialogClientView : public ClientView, - public NativeButton::Listener, - public FocusChangeListener { - public: - DialogClientView(Window* window, View* contents_view); - virtual ~DialogClientView(); - - // Adds the dialog buttons required by the supplied WindowDelegate to the - // view. - void ShowDialogButtons(); - - // Updates the enabled state and label of the buttons required by the - // supplied WindowDelegate - void UpdateDialogButtons(); - - // Accept the changes made in the window that contains this ClientView. - void AcceptWindow(); - - // Cancel the changes made in the window that contains this ClientView. - void CancelWindow(); - - // Accessors in case the user wishes to adjust these buttons. - NativeButton* ok_button() const { return ok_button_; } - NativeButton* cancel_button() const { return cancel_button_; } - - // Overridden from ClientView: - virtual bool CanClose() const; - virtual void WindowClosing(); - virtual int NonClientHitTest(const gfx::Point& point); - virtual DialogClientView* AsDialogClientView() { return this; } - - // FocusChangeListener implementation: - virtual void FocusWillChange(View* focused_before, View* focused_now); - - protected: - // View overrides: - virtual void Paint(ChromeCanvas* canvas); - virtual void PaintChildren(ChromeCanvas* canvas); - virtual void Layout(); - virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); - virtual gfx::Size GetPreferredSize(); - virtual bool AcceleratorPressed(const Accelerator& accelerator); - - // NativeButton::Listener implementation: - virtual void ButtonPressed(NativeButton* sender); - - private: - // Paint the size box in the bottom right corner of the window if it is - // resizable. - void PaintSizeBox(ChromeCanvas* canvas); - - // Returns the width of the specified dialog button using the correct font. - int GetButtonWidth(int button) const; - int DialogClientView::GetButtonsHeight() const; - - // Position and size various sub-views. - void LayoutDialogButtons(); - void LayoutContentsView(); - - // Makes the specified button the default button. - void SetDefaultButton(NativeButton* button); - - bool has_dialog_buttons() const { return ok_button_ || cancel_button_; } - - // Create and add the extra view, if supplied by the delegate. - void CreateExtraView(); - - // Returns the DialogDelegate for the window. - DialogDelegate* GetDialogDelegate() const; - - // The dialog buttons. - NativeButton* ok_button_; - NativeButton* cancel_button_; - - // The button that is currently the default button if any. - NativeButton* default_button_; - - // The button-level extra view, NULL unless the dialog delegate supplies one. - View* extra_view_; - - // The layout rect of the size box, when visible. - gfx::Rect size_box_bounds_; - - // True if the window was Accepted by the user using the OK button. - bool accepted_; - - // Static resource initialization - static void InitClass(); - static ChromeFont dialog_button_font_; - - DISALLOW_EVIL_CONSTRUCTORS(DialogClientView); -}; - -} // namespace views - -#endif // #ifndef CHROME_VIEWS_DIALOG_CLIENT_VIEW_H_ diff --git a/chrome/views/dialog_delegate.cc b/chrome/views/dialog_delegate.cc deleted file mode 100644 index d873318..0000000 --- a/chrome/views/dialog_delegate.cc +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "chrome/views/dialog_delegate.h" - -#include "base/logging.h" -#include "chrome/views/window.h" - -namespace views { - -// Overridden from WindowDelegate: - -int DialogDelegate::GetDefaultDialogButton() const { - if (GetDialogButtons() & DIALOGBUTTON_OK) - return DIALOGBUTTON_OK; - if (GetDialogButtons() & DIALOGBUTTON_CANCEL) - return DIALOGBUTTON_CANCEL; - return DIALOGBUTTON_NONE; -} - -View* DialogDelegate::GetInitiallyFocusedView() { - // Focus the default button if any. - DialogClientView* dcv = GetDialogClientView(); - int default_button = GetDefaultDialogButton(); - if (default_button == DIALOGBUTTON_NONE) - return NULL; - - if ((default_button & GetDialogButtons()) == 0) { - // The default button is a button we don't have. - NOTREACHED(); - return NULL; - } - - if (default_button & DIALOGBUTTON_OK) - return dcv->ok_button(); - if (default_button & DIALOGBUTTON_CANCEL) - return dcv->cancel_button(); - return NULL; -} - -ClientView* DialogDelegate::CreateClientView(Window* window) { - return new DialogClientView(window, GetContentsView()); -} - -DialogClientView* DialogDelegate::GetDialogClientView() const { - ClientView* client_view = window()->GetClientView(); - DialogClientView* dialog_client_view = client_view->AsDialogClientView(); - DCHECK(dialog_client_view); - return dialog_client_view; -} - -} // namespace views diff --git a/chrome/views/dialog_delegate.h b/chrome/views/dialog_delegate.h deleted file mode 100644 index d077e60..0000000 --- a/chrome/views/dialog_delegate.h +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2006-2008 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_VIEWS_DIALOG_DELEGATE_H_ -#define CHROME_VIEWS_DIALOG_DELEGATE_H_ - -#include "chrome/views/dialog_client_view.h" -#include "chrome/views/window_delegate.h" - -namespace views { - -class View; - -/////////////////////////////////////////////////////////////////////////////// -// -// DialogDelegate -// -// DialogDelegate is an interface implemented by objects that wish to show a -// dialog box Window. The window that is displayed uses this interface to -// determine how it should be displayed and notify the delegate object of -// certain events. -// -/////////////////////////////////////////////////////////////////////////////// -class DialogDelegate : public WindowDelegate { - public: - virtual DialogDelegate* AsDialogDelegate() { return this; } - - enum DialogButton { - DIALOGBUTTON_NONE = 0, // No dialog buttons, for WindowType == WINDOW. - DIALOGBUTTON_OK = 1, // Has an OK button. - DIALOGBUTTON_CANCEL = 2, // Has a Cancel button (becomes a Close button if - }; // no OK button). - - // Returns a mask specifying which of the available DialogButtons are visible - // for the dialog. Note: If an OK button is provided, you should provide a - // CANCEL button. A dialog box with just an OK button is frowned upon and - // considered a very special case, so if you're planning on including one, - // you should reconsider, or beng says there will be stabbings. - // - // To use the extra button you need to override GetDialogButtons() - virtual int GetDialogButtons() const { - return DIALOGBUTTON_OK | DIALOGBUTTON_CANCEL; - } - - // Returns whether accelerators are enabled on the button. This is invoked - // when an accelerator is pressed, not at construction time. This - // returns true. - virtual bool AreAcceleratorsEnabled(DialogButton button) { return true; } - - // Returns the label of the specified DialogButton. - virtual std::wstring GetDialogButtonLabel(DialogButton button) const { - // empty string results in defaults for DIALOGBUTTON_OK, - // DIALOGBUTTON_CANCEL. - return L""; - } - - // Override this function if with a view which will be shown in the same - // row as the OK and CANCEL buttons but flush to the left and extending - // up to the buttons. - virtual View* GetExtraView() { return NULL; } - - // Returns the default dialog button. This should not be a mask as only one - // button should ever be the default button. Return DIALOGBUTTON_NONE if - // there is no default. Default behavior is to return DIALOGBUTTON_OK or - // DIALOGBUTTON_CANCEL (in that order) if they are present, DIALOGBUTTON_NONE - // otherwise. - virtual int GetDefaultDialogButton() const; - - // Returns whether the specified dialog button is enabled. - virtual bool IsDialogButtonEnabled(DialogButton button) const { - return true; - } - - // Returns whether the specified dialog button is visible. - virtual bool IsDialogButtonVisible(DialogButton button) const { - return true; - } - - // For Dialog boxes, if there is a "Cancel" button, this is called when the - // user presses the "Cancel" button or the Close button on the window or - // in the system menu, or presses the Esc key. This function should return - // true if the window can be closed after it returns, or false if it must - // remain open. - virtual bool Cancel() { return true; } - - // For Dialog boxes, this is called when the user presses the "OK" button, - // or the Enter key. Can also be called on Esc key or close button presses if - // there is no "Cancel" button. This function should return true if the window - // can be closed after the window can be closed after it returns, or false if - // it must remain open. If |window_closing| is true, it means that this - // handler is being called because the window is being closed (e.g. by - // Window::Close) and there is no Cancel handler, so Accept is being called - // instead. - virtual bool Accept(bool window_closing) { return Accept(); } - virtual bool Accept() { return true; } - - // Overridden from WindowDelegate: - virtual View* GetInitiallyFocusedView(); - - // Overridden from WindowDelegate: - virtual ClientView* CreateClientView(Window* window); - - // A helper for accessing the DialogClientView object contained by this - // delegate's Window. - DialogClientView* GetDialogClientView() const; -}; - -} // namespace views - -#endif // CHROME_VIEWS_DIALOG_DELEGATE_H_ diff --git a/chrome/views/focus_manager_unittest.cc b/chrome/views/focus_manager_unittest.cc index b08e19a..e41920c 100644 --- a/chrome/views/focus_manager_unittest.cc +++ b/chrome/views/focus_manager_unittest.cc @@ -23,8 +23,8 @@ #include "chrome/views/widget/accelerator_handler.h" #include "chrome/views/widget/root_view.h" #include "chrome/views/widget/widget_win.h" -#include "chrome/views/window.h" -#include "chrome/views/window_delegate.h" +#include "chrome/views/window/window.h" +#include "chrome/views/window/window_delegate.h" #include "SkColor.h" diff --git a/chrome/views/native_frame_view.cc b/chrome/views/native_frame_view.cc deleted file mode 100644 index 898e105..0000000 --- a/chrome/views/native_frame_view.cc +++ /dev/null @@ -1,60 +0,0 @@ -// 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. - -#include "chrome/views/native_frame_view.h" - -#include "chrome/views/window_win.h" - -namespace views { - -//////////////////////////////////////////////////////////////////////////////// -// NativeFrameView, public: - -NativeFrameView::NativeFrameView(WindowWin* frame) - : NonClientFrameView(), - frame_(frame) { -} - -NativeFrameView::~NativeFrameView() { -} - -//////////////////////////////////////////////////////////////////////////////// -// NativeFrameView, NonClientFrameView overrides: - -gfx::Rect NativeFrameView::GetBoundsForClientView() const { - return gfx::Rect(0, 0, width(), height()); -} - -gfx::Rect NativeFrameView::GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const { - RECT rect = client_bounds.ToRECT(); - AdjustWindowRectEx(&rect, frame_->window_style(), FALSE, - frame_->window_ex_style()); - return gfx::Rect(rect); -} - -gfx::Point NativeFrameView::GetSystemMenuPoint() const { - POINT temp = {0, -kFrameShadowThickness }; - MapWindowPoints(frame_->GetNativeView(), HWND_DESKTOP, &temp, 1); - return gfx::Point(temp); -} - -int NativeFrameView::NonClientHitTest(const gfx::Point& point) { - return HTNOWHERE; -} - -void NativeFrameView::GetWindowMask(const gfx::Size& size, - gfx::Path* window_mask) { - // Nothing to do, we use the default window mask. -} - -void NativeFrameView::EnableClose(bool enable) { - // Nothing to do, handled automatically by Window. -} - -void NativeFrameView::ResetWindowControls() { - // Nothing to do. -} - -} // namespace views diff --git a/chrome/views/native_frame_view.h b/chrome/views/native_frame_view.h deleted file mode 100644 index c13784d..0000000 --- a/chrome/views/native_frame_view.h +++ /dev/null @@ -1,39 +0,0 @@ -// 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_VIEWS_NATIVE_FRAME_VIEW_H_ -#define CHROME_VIEWS_NATIVE_FRAME_VIEW_H_ - -#include "chrome/views/non_client_view.h" - -namespace views { - -class WindowWin; - -class NativeFrameView : public NonClientFrameView { - public: - explicit NativeFrameView(WindowWin* frame); - virtual ~NativeFrameView(); - - // NonClientFrameView overrides: - virtual gfx::Rect GetBoundsForClientView() const; - virtual gfx::Rect GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const; - virtual gfx::Point GetSystemMenuPoint() const; - virtual int NonClientHitTest(const gfx::Point& point); - virtual void GetWindowMask(const gfx::Size& size, - gfx::Path* window_mask); - virtual void EnableClose(bool enable); - virtual void ResetWindowControls(); - - private: - // Our containing frame. - WindowWin* frame_; - - DISALLOW_COPY_AND_ASSIGN(NativeFrameView); -}; - -} // namespace views - -#endif // #ifndef CHROME_VIEWS_NATIVE_FRAME_VIEW_H_ diff --git a/chrome/views/non_client_view.cc b/chrome/views/non_client_view.cc deleted file mode 100644 index c234f23..0000000 --- a/chrome/views/non_client_view.cc +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "chrome/views/non_client_view.h" - -#include "chrome/common/win_util.h" -#include "chrome/views/widget/root_view.h" -#include "chrome/views/widget/widget.h" -#include "chrome/views/window.h" - -namespace views { - -const int NonClientFrameView::kFrameShadowThickness = 1; -const int NonClientFrameView::kClientEdgeThickness = 1; - -// The frame view and the client view are always at these specific indices, -// because the RootView message dispatch sends messages to items higher in the -// z-order first and we always want the client view to have first crack at -// handling mouse messages. -static const int kFrameViewIndex = 0; -static const int kClientViewIndex = 1; - -//////////////////////////////////////////////////////////////////////////////// -// NonClientView, public: - -NonClientView::NonClientView(Window* frame) - : frame_(frame), - client_view_(NULL), - use_native_frame_(win_util::ShouldUseVistaFrame()) { -} - -NonClientView::~NonClientView() { - // This value may have been reset before the window hierarchy shuts down, - // so we need to manually remove it. - RemoveChildView(frame_view_.get()); -} - -void NonClientView::SetFrameView(NonClientFrameView* frame_view) { - // See comment in header about ownership. - frame_view->SetParentOwned(false); - if (frame_view_.get()) - RemoveChildView(frame_view_.get()); - frame_view_.reset(frame_view); - if (GetParent()) - AddChildView(kFrameViewIndex, frame_view_.get()); -} - -bool NonClientView::CanClose() const { - return client_view_->CanClose(); -} - -void NonClientView::WindowClosing() { - client_view_->WindowClosing(); -} - -void NonClientView::SetUseNativeFrame(bool use_native_frame) { - use_native_frame_ = use_native_frame; - SetFrameView(frame_->CreateFrameViewForWindow()); - GetRootView()->ThemeChanged(); - Layout(); - SchedulePaint(); - frame_->UpdateFrameAfterFrameChange(); -} - -bool NonClientView::UseNativeFrame() const { - // The frame view may always require a custom frame, e.g. Constrained Windows. - bool always_use_custom_frame = - frame_view_.get() && frame_view_->AlwaysUseCustomFrame(); - return !always_use_custom_frame && use_native_frame_; -} - -void NonClientView::DisableInactiveRendering(bool disable) { - frame_view_->DisableInactiveRendering(disable); -} - -gfx::Rect NonClientView::GetWindowBoundsForClientBounds( - const gfx::Rect client_bounds) const { - return frame_view_->GetWindowBoundsForClientBounds(client_bounds); -} - -gfx::Point NonClientView::GetSystemMenuPoint() const { - return frame_view_->GetSystemMenuPoint(); -} - -int NonClientView::NonClientHitTest(const gfx::Point& point) { - // Sanity check. - if (!bounds().Contains(point)) - return HTNOWHERE; - - // The ClientView gets first crack, since it overlays the NonClientFrameView - // in the display stack. - int frame_component = client_view_->NonClientHitTest(point); - if (frame_component != HTNOWHERE) - return frame_component; - - // Finally ask the NonClientFrameView. It's at the back of the display stack - // so it gets asked last. - return frame_view_->NonClientHitTest(point); -} - -void NonClientView::GetWindowMask(const gfx::Size& size, - gfx::Path* window_mask) { - frame_view_->GetWindowMask(size, window_mask); -} - -void NonClientView::EnableClose(bool enable) { - frame_view_->EnableClose(enable); -} - -void NonClientView::ResetWindowControls() { - frame_view_->ResetWindowControls(); -} - -//////////////////////////////////////////////////////////////////////////////// -// NonClientView, View overrides: - -gfx::Size NonClientView::GetPreferredSize() { - gfx::Rect client_bounds(gfx::Point(), client_view_->GetPreferredSize()); - return GetWindowBoundsForClientBounds(client_bounds).size(); -} - -void NonClientView::Layout() { - // First layout the NonClientFrameView, which determines the size of the - // ClientView... - frame_view_->SetBounds(0, 0, width(), height()); - - // We need to manually call Layout here because layout for the frame view can - // change independently of the bounds changing - e.g. after the initial - // display of the window the metrics of the native window controls can change, - // which does not change the bounds of the window but requires a re-layout to - // trigger a repaint. We override DidChangeBounds for the NonClientFrameView - // to do nothing so that SetBounds above doesn't cause Layout to be called - // twice. - frame_view_->Layout(); - - // Then layout the ClientView, using those bounds. - client_view_->SetBounds(frame_view_->GetBoundsForClientView()); - - // We need to manually call Layout on the ClientView as well for the same - // reason as above. - client_view_->Layout(); -} - -void NonClientView::ViewHierarchyChanged(bool is_add, View* parent, - View* child) { - // Add our two child views here as we are added to the Widget so that if we - // are subsequently resized all the parent-child relationships are - // established. - if (is_add && GetWidget() && child == this) { - AddChildView(kFrameViewIndex, frame_view_.get()); - AddChildView(kClientViewIndex, client_view_); - } -} - -views::View* NonClientView::GetViewForPoint(const gfx::Point& point) { - return GetViewForPoint(point, false); -} - -views::View* NonClientView::GetViewForPoint(const gfx::Point& point, - bool can_create_floating) { - // Because of the z-ordering of our child views (the client view is positioned - // over the non-client frame view, if the client view ever overlaps the frame - // view visually (as it does for the browser window), then it will eat mouse - // events for the window controls. We override this method here so that we can - // detect this condition and re-route the events to the non-client frame view. - // The assumption is that the frame view's implementation of HitTest will only - // return true for area not occupied by the client view. - gfx::Point point_in_child_coords(point); - View::ConvertPointToView(this, frame_view_.get(), &point_in_child_coords); - if (frame_view_->HitTest(point_in_child_coords)) - return frame_view_->GetViewForPoint(point); - - return View::GetViewForPoint(point, can_create_floating); -} - -//////////////////////////////////////////////////////////////////////////////// -// NonClientFrameView, View overrides: - -bool NonClientFrameView::HitTest(const gfx::Point& l) const { - // For the default case, we assume the non-client frame view never overlaps - // the client view. - return !GetWidget()->AsWindow()->GetClientView()->bounds().Contains(l); -} - -void NonClientFrameView::DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current) { - // Overridden to do nothing. The NonClientView manually calls Layout on the - // FrameView when it is itself laid out, see comment in NonClientView::Layout. -} - -//////////////////////////////////////////////////////////////////////////////// -// NonClientFrameView, protected: - -int NonClientFrameView::GetHTComponentForFrame(const gfx::Point& point, - int top_resize_border_height, - int resize_border_thickness, - int top_resize_corner_height, - int resize_corner_width, - bool can_resize) { - // Tricky: In XP, native behavior is to return HTTOPLEFT and HTTOPRIGHT for - // a |resize_corner_size|-length strip of both the side and top borders, but - // only to return HTBOTTOMLEFT/HTBOTTOMRIGHT along the bottom border + corner - // (not the side border). Vista goes further and doesn't return these on any - // of the side borders. We allow callers to match either behavior. - int component; - if (point.x() < resize_border_thickness) { - if (point.y() < top_resize_corner_height) - component = HTTOPLEFT; - else if (point.y() >= (height() - resize_border_thickness)) - component = HTBOTTOMLEFT; - else - component = HTLEFT; - } else if (point.x() >= (width() - resize_border_thickness)) { - if (point.y() < top_resize_corner_height) - component = HTTOPRIGHT; - else if (point.y() >= (height() - resize_border_thickness)) - component = HTBOTTOMRIGHT; - else - component = HTRIGHT; - } else if (point.y() < top_resize_border_height) { - if (point.x() < resize_corner_width) - component = HTTOPLEFT; - else if (point.x() >= (width() - resize_corner_width)) - component = HTTOPRIGHT; - else - component = HTTOP; - } else if (point.y() >= (height() - resize_border_thickness)) { - if (point.x() < resize_corner_width) - component = HTBOTTOMLEFT; - else if (point.x() >= (width() - resize_corner_width)) - component = HTBOTTOMRIGHT; - else - component = HTBOTTOM; - } else { - return HTNOWHERE; - } - - // If the window can't be resized, there are no resize boundaries, just - // window borders. - return can_resize ? component : HTBORDER; -} - -} // namespace views diff --git a/chrome/views/non_client_view.h b/chrome/views/non_client_view.h deleted file mode 100644 index d2ed5c1..0000000 --- a/chrome/views/non_client_view.h +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright (c) 2006-2008 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_VIEWS_NON_CLIENT_VIEW_H_ -#define CHROME_VIEWS_NON_CLIENT_VIEW_H_ - -#include "base/task.h" -#include "chrome/views/view.h" -#include "chrome/views/client_view.h" - -namespace gfx { -class Path; -} - -namespace views { - -//////////////////////////////////////////////////////////////////////////////// -// NonClientFrameView -// -// An object that subclasses NonClientFrameView is a View that renders and -// responds to events within the frame portions of the non-client area of a -// window. This view does _not_ contain the ClientView, but rather is a sibling -// of it. -class NonClientFrameView : public View { - public: - // Various edges of the frame border have a 1 px shadow along their edges; in - // a few cases we shift elements based on this amount for visual appeal. - static const int kFrameShadowThickness; - // In restored mode, we draw a 1 px edge around the content area inside the - // frame border. - static const int kClientEdgeThickness; - - void DisableInactiveRendering(bool disable) { - paint_as_active_ = disable; - if (!paint_as_active_) - SchedulePaint(); - } - - // Returns the bounds (in this View's parent's coordinates) that the client - // view should be laid out within. - virtual gfx::Rect GetBoundsForClientView() const = 0; - - // Returns true if this FrameView should always use the custom frame, - // regardless of the system settings. An example is the Constrained Window, - // which is a child window and must always provide its own frame. - virtual bool AlwaysUseCustomFrame() const { return false; } - - virtual gfx::Rect GetWindowBoundsForClientBounds( - const gfx::Rect& client_bounds) const = 0; - virtual gfx::Point GetSystemMenuPoint() const = 0; - virtual int NonClientHitTest(const gfx::Point& point) = 0; - virtual void GetWindowMask(const gfx::Size& size, - gfx::Path* window_mask) = 0; - virtual void EnableClose(bool enable) = 0; - virtual void ResetWindowControls() = 0; - - // Overridden from View: - virtual bool HitTest(const gfx::Point& l) const; - - protected: - virtual void DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current); - - NonClientFrameView() : paint_as_active_(false) {} - - - // Helper for non-client view implementations to determine which area of the - // window border the specified |point| falls within. The other parameters are - // the size of the sizing edges, and whether or not the window can be - // resized. - int GetHTComponentForFrame(const gfx::Point& point, - int top_resize_border_height, - int resize_border_thickness, - int top_resize_corner_height, - int resize_corner_width, - bool can_resize); - - // Accessor for paint_as_active_. - bool paint_as_active() const { return paint_as_active_; } - - private: - // True when the non-client view should always be rendered as if the window - // were active, regardless of whether or not the top level window actually - // is active. - bool paint_as_active_; -}; - -//////////////////////////////////////////////////////////////////////////////// -// NonClientView -// -// The NonClientView is the logical root of all Views contained within a -// Window, except for the RootView which is its parent and of which it is the -// sole child. The NonClientView has two children, the NonClientFrameView which -// is responsible for painting and responding to events from the non-client -// portions of the window, and the ClientView, which is responsible for the -// same for the client area of the window: -// -// +- views::Window ------------------------------------+ -// | +- views::RootView ------------------------------+ | -// | | +- views::NonClientView ---------------------+ | | -// | | | +- views::NonClientView subclass ---+ | | | -// | | | | | | | | -// | | | | << all painting and event receiving >> | | | | -// | | | | << of the non-client areas of a >> | | | | -// | | | | << views::Window. >> | | | | -// | | | | | | | | -// | | | +----------------------------------------+ | | | -// | | | +- views::ClientView or subclass --------+ | | | -// | | | | | | | | -// | | | | << all painting and event receiving >> | | | | -// | | | | << of the client areas of a >> | | | | -// | | | | << views::Window. >> | | | | -// | | | | | | | | -// | | | +----------------------------------------+ | | | -// | | +--------------------------------------------+ | | -// | +------------------------------------------------+ | -// +----------------------------------------------------+ -// -// The NonClientFrameView and ClientView are siblings because due to theme -// changes the NonClientFrameView may be replaced with different -// implementations (e.g. during the switch from DWM/Aero-Glass to Vista Basic/ -// Classic rendering). -// -class NonClientView : public View { - public: - explicit NonClientView(Window* frame); - virtual ~NonClientView(); - - // Replaces the current NonClientFrameView (if any) with the specified one. - void SetFrameView(NonClientFrameView* frame_view); - - // Returns true if the ClientView determines that the containing window can be - // closed, false otherwise. - bool CanClose() const; - - // Called by the containing Window when it is closed. - void WindowClosing(); - - // Changes the frame from native to custom depending on the value of - // |use_native_frame|. - void SetUseNativeFrame(bool use_native_frame); - - // Returns true if the native window frame should be used, false if the - // NonClientView provides its own frame implementation. - bool UseNativeFrame() const; - - // Prevents the window from being rendered as deactivated when |disable| is - // true, until called with |disable| false. Used when a sub-window is to be - // shown that shouldn't visually de-activate the window. - // Subclasses can override this to perform additional actions when this value - // changes. - void DisableInactiveRendering(bool disable); - - // Returns the bounds of the window required to display the content area at - // the specified bounds. - gfx::Rect GetWindowBoundsForClientBounds(const gfx::Rect client_bounds) const; - - // Returns the point, in screen coordinates, where the system menu should - // be shown so it shows up anchored to the system menu icon. - gfx::Point GetSystemMenuPoint() const; - - // Determines the windows HT* code when the mouse cursor is at the - // specified point, in window coordinates. - int NonClientHitTest(const gfx::Point& point); - - // Returns a mask to be used to clip the top level window for the given - // size. This is used to create the non-rectangular window shape. - void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask); - - // Toggles the enable state for the Close button (and the Close menu item in - // the system menu). - void EnableClose(bool enable); - - // Tells the window controls as rendered by the NonClientView to reset - // themselves to a normal state. This happens in situations where the - // containing window does not receive a normal sequences of messages that - // would lead to the controls returning to this normal state naturally, e.g. - // when the window is maximized, minimized or restored. - void ResetWindowControls(); - - // Get/Set client_view property. - ClientView* client_view() const { return client_view_; } - void set_client_view(ClientView* client_view) { - client_view_ = client_view; - } - - // NonClientView, View overrides: - virtual gfx::Size GetPreferredSize(); - virtual void Layout(); - - protected: - // NonClientView, View overrides: - virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); - virtual views::View* GetViewForPoint(const gfx::Point& point); - virtual views::View* GetViewForPoint(const gfx::Point& point, - bool can_create_floating); - - private: - // The frame that hosts this NonClientView. - Window* frame_; - - // A ClientView object or subclass, responsible for sizing the contents view - // of the window, hit testing and perhaps other tasks depending on the - // implementation. - ClientView* client_view_; - - // The NonClientFrameView that renders the non-client portions of the window. - // This object is not owned by the view hierarchy because it can be replaced - // dynamically as the system settings change. - scoped_ptr frame_view_; - - // Whether or not we should use the native frame. - bool use_native_frame_; - - DISALLOW_COPY_AND_ASSIGN(NonClientView); -}; - -} // namespace views - -#endif // #ifndef CHROME_VIEWS_NON_CLIENT_VIEW_H_ diff --git a/chrome/views/table_view_unittest.cc b/chrome/views/table_view_unittest.cc index 06f3458..f94e86d 100644 --- a/chrome/views/table_view_unittest.cc +++ b/chrome/views/table_view_unittest.cc @@ -7,8 +7,8 @@ #include "base/message_loop.h" #include "base/string_util.h" #include "chrome/views/table_view.h" -#include "chrome/views/window_win.h" -#include "chrome/views/window_delegate.h" +#include "chrome/views/window/window_delegate.h" +#include "chrome/views/window/window_win.h" #include "testing/gtest/include/gtest/gtest.h" using views::TableView; diff --git a/chrome/views/view_unittest.cc b/chrome/views/view_unittest.cc index 7da9f42..dcb49f7 100644 --- a/chrome/views/view_unittest.cc +++ b/chrome/views/view_unittest.cc @@ -8,12 +8,12 @@ #include "chrome/common/notification_service.h" #include "chrome/views/background.h" #include "chrome/views/checkbox.h" -#include "chrome/views/dialog_delegate.h" #include "chrome/views/event.h" #include "chrome/views/view.h" #include "chrome/views/widget/root_view.h" #include "chrome/views/widget/widget_win.h" -#include "chrome/views/window.h" +#include "chrome/views/window/dialog_delegate.h" +#include "chrome/views/window/window.h" #include "testing/gtest/include/gtest/gtest.h" using namespace views; diff --git a/chrome/views/views.vcproj b/chrome/views/views.vcproj index 890347a..a9c31cb 100644 --- a/chrome/views/views.vcproj +++ b/chrome/views/views.vcproj @@ -331,6 +331,86 @@ > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -400,14 +480,6 @@ > - - - - @@ -428,14 +500,6 @@ > - - - - @@ -444,22 +508,6 @@ > - - - - - - - - @@ -592,14 +640,6 @@ > - - - - @@ -608,14 +648,6 @@ > - - - - @@ -779,30 +811,6 @@ RelativePath=".\view_win.cc" > - - - - - - - - - - - - diff --git a/chrome/views/widget/accelerator_handler.h b/chrome/views/widget/accelerator_handler.h index f71be26..6c2278c 100644 --- a/chrome/views/widget/accelerator_handler.h +++ b/chrome/views/widget/accelerator_handler.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_VIEWS_ACCELERATOR_HANDLER_H__ -#define CHROME_VIEWS_ACCELERATOR_HANDLER_H__ +#ifndef CHROME_VIEWS_WIDGET_ACCELERATOR_HANDLER_H_ +#define CHROME_VIEWS_WIDGET_ACCELERATOR_HANDLER_H_ #include "base/message_loop.h" @@ -27,4 +27,4 @@ class AcceleratorHandler : public MessageLoopForUI::Dispatcher { } // namespace views -#endif // CHROME_VIEWS_ACCELERATOR_HANDLER_H__ +#endif // CHROME_VIEWS_WIDGET_ACCELERATOR_HANDLER_H_ diff --git a/chrome/views/widget/aero_tooltip_manager.h b/chrome/views/widget/aero_tooltip_manager.h index 17fab05..fac5a39 100644 --- a/chrome/views/widget/aero_tooltip_manager.h +++ b/chrome/views/widget/aero_tooltip_manager.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_VIEWS_AERO_TOOLTIP_MANAGER_H__ -#define CHROME_VIEWS_AERO_TOOLTIP_MANAGER_H__ +#ifndef CHROME_VIEWS_WIDGET_AERO_TOOLTIP_MANAGER_H_ +#define CHROME_VIEWS_WIDGET_AERO_TOOLTIP_MANAGER_H_ #include "base/ref_counted.h" #include "base/task.h" @@ -54,4 +54,4 @@ class AeroTooltipManager : public TooltipManager { } // namespace views -#endif // #ifndef CHROME_VIEWS_AERO_TOOLTIP_MANAGER_H__ +#endif // #ifndef CHROME_VIEWS_WIDGET_AERO_TOOLTIP_MANAGER_H_ diff --git a/chrome/views/widget/hwnd_notification_source.h b/chrome/views/widget/hwnd_notification_source.h index 9f33c2b..602ae44 100644 --- a/chrome/views/widget/hwnd_notification_source.h +++ b/chrome/views/widget/hwnd_notification_source.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_VIEWS_WIDGET_HWND_NOTIFICATION_SOURCE_H__ -#define CHROME_VIEWS_WIDGET_HWND_NOTIFICATION_SOURCE_H__ +#ifndef CHROME_VIEWS_WIDGET_HWND_NOTIFICATION_SOURCE_H_ +#define CHROME_VIEWS_WIDGET_HWND_NOTIFICATION_SOURCE_H_ #include "chrome/common/notification_source.h" @@ -21,4 +21,4 @@ class Source : public NotificationSource { HWND ptr() const { return static_cast(ptr_); } }; -#endif // #define CHROME_VIEWS_WIDGET_HWND_NOTIFICATION_SOURCE_H__ +#endif // #define CHROME_VIEWS_WIDGET_HWND_NOTIFICATION_SOURCE_H_ diff --git a/chrome/views/widget/root_view.h b/chrome/views/widget/root_view.h index 57ea710..a97f2ec 100644 --- a/chrome/views/widget/root_view.h +++ b/chrome/views/widget/root_view.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_VIEWS_ROOT_VIEW_H__ -#define CHROME_VIEWS_ROOT_VIEW_H__ +#ifndef CHROME_VIEWS_WIDGET_ROOT_VIEW_H_ +#define CHROME_VIEWS_WIDGET_ROOT_VIEW_H_ #include "base/ref_counted.h" #include "chrome/views/focus_manager.h" @@ -355,4 +355,4 @@ class RootView : public View, } // namespace views -#endif // CHROME_VIEWS_ROOT_VIEW_H__ +#endif // CHROME_VIEWS_WIDGET_ROOT_VIEW_H_ diff --git a/chrome/views/widget/root_view_drop_target.h b/chrome/views/widget/root_view_drop_target.h index 72a5a87..02ce6c6 100644 --- a/chrome/views/widget/root_view_drop_target.h +++ b/chrome/views/widget/root_view_drop_target.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_VIEWS_ROOT_VIEW_DROP_TARGET_H__ -#define CHROME_VIEWS_ROOT_VIEW_DROP_TARGET_H__ +#ifndef CHROME_VIEWS_WIDGET_ROOT_VIEW_DROP_TARGET_H_ +#define CHROME_VIEWS_WIDGET_ROOT_VIEW_DROP_TARGET_H_ #include #include @@ -72,4 +72,4 @@ class RootViewDropTarget : public BaseDropTarget { } // namespace views -#endif // CHROME_VIEWS_ROOT_VIEW_DROP_TARGET_H__ +#endif // CHROME_VIEWS_WIDGET_ROOT_VIEW_DROP_TARGET_H_ diff --git a/chrome/views/widget/tooltip_manager.h b/chrome/views/widget/tooltip_manager.h index 2800fb0..312e30e 100644 --- a/chrome/views/widget/tooltip_manager.h +++ b/chrome/views/widget/tooltip_manager.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_VIEWS_TOOLTIP_MANAGER_H_ -#define CHROME_VIEWS_TOOLTIP_MANAGER_H_ +#ifndef CHROME_VIEWS_WIDGET_TOOLTIP_MANAGER_H_ +#define CHROME_VIEWS_WIDGET_TOOLTIP_MANAGER_H_ #include #include @@ -153,7 +153,7 @@ class TooltipManager { // control window for tooltip displayed using keyboard. HWND keyboard_tooltip_hwnd_; - // Used to register DestroyTooltipWindow function with postdelayedtask + // Used to register DestroyTooltipWindow function with PostDelayedTask // function. ScopedRunnableMethodFactory keyboard_tooltip_factory_; @@ -162,4 +162,4 @@ class TooltipManager { } // namespace views -#endif // CHROME_VIEWS_TOOLTIP_MANAGER_H_ +#endif // CHROME_VIEWS_WIDGET_TOOLTIP_MANAGER_H_ diff --git a/chrome/views/widget/widget.h b/chrome/views/widget/widget.h index 46aa754..d1d0fff 100644 --- a/chrome/views/widget/widget.h +++ b/chrome/views/widget/widget.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_VIEWS_WIDGET_H_ -#define CHROME_VIEWS_WIDGET_H_ +#ifndef CHROME_VIEWS_WIDGET_WIDGET_H_ +#define CHROME_VIEWS_WIDGET_WIDGET_H_ #include "base/gfx/native_widget_types.h" @@ -82,4 +82,4 @@ class Widget { } // namespace views -#endif // CHROME_VIEWS_WIDGET_H_ +#endif // CHROME_VIEWS_WIDGET_WIDGET_H_ diff --git a/chrome/views/widget/widget_win.h b/chrome/views/widget/widget_win.h index d5d5bad..c9fe810 100644 --- a/chrome/views/widget/widget_win.h +++ b/chrome/views/widget/widget_win.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_VIEWS_WIDGET_WIN_H_ -#define CHROME_VIEWS_WIDGET_WIN_H_ +#ifndef CHROME_VIEWS_WIDGET_WIDGET_WIN_H_ +#define CHROME_VIEWS_WIDGET_WIDGET_WIN_H_ #include #include @@ -632,4 +632,4 @@ class WidgetWin : public Widget, } // namespace views -#endif // #ifndef CHROME_VIEWS_WIDGET_WIN_H_ +#endif // #ifndef CHROME_VIEWS_WIDGET_WIDGET_WIN_H_ diff --git a/chrome/views/window.h b/chrome/views/window.h deleted file mode 100644 index 6ac5fb7..0000000 --- a/chrome/views/window.h +++ /dev/null @@ -1,118 +0,0 @@ -// 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_VIEWS_WINDOW_H__ -#define CHROME_VIEWS_WINDOW_H__ - -#include "base/gfx/native_widget_types.h" - -namespace gfx { -class Rect; -class Size; -} - -namespace views { - -class ClientView; -class NonClientFrameView; -class NonClientView; -class WindowDelegate; - -// An interface implemented by an object that provides a top level window. -class Window { - public: - virtual ~Window() {} - - // Creates an instance of an object implementing this interface. - static Window* CreateChromeWindow(gfx::NativeWindow parent, - const gfx::Rect& bounds, - WindowDelegate* window_delegate); - - // Returns the preferred size of the contents view of this window based on - // its localized size data. The width in cols is held in a localized string - // resource identified by |col_resource_id|, the height in the same fashion. - // TODO(beng): This should eventually live somewhere else, probably closer to - // ClientView. - static int GetLocalizedContentsWidth(int col_resource_id); - static int GetLocalizedContentsHeight(int row_resource_id); - static gfx::Size GetLocalizedContentsSize(int col_resource_id, - int row_resource_id); - - // Retrieves the window's bounds, including its frame. - virtual gfx::Rect GetBounds() const = 0; - - // Sizes and/or places the window to the specified bounds, size or position. - virtual void SetBounds(const gfx::Rect& bounds) = 0; - - // As above, except the window is inserted after |other_window| in the window - // Z-order. If this window is not yet visible, other_window's monitor is used - // as the constraining rectangle, rather than this window's monitor. - virtual void SetBounds(const gfx::Rect& bounds, - gfx::NativeWindow other_window) = 0; - - // Makes the window visible. - virtual void Show() = 0; - - // Activate the window, assuming it already exists and is visible. - virtual void Activate() = 0; - - // Closes the window, ultimately destroying it. This isn't immediate (it - // occurs after a return to the message loop. Implementors must also make sure - // that invoking Close multiple times doesn't cause bad things to happen, - // since it can happen. - virtual void Close() = 0; - - // Maximizes/minimizes/restores the window. - virtual void Maximize() = 0; - virtual void Minimize() = 0; - virtual void Restore() = 0; - - // Whether or not the window is currently active. - virtual bool IsActive() const = 0; - - // Whether or not the window is currently visible. - virtual bool IsVisible() const = 0; - - // Whether or not the window is maximized or minimized. - virtual bool IsMaximized() const = 0; - virtual bool IsMinimized() const = 0; - - // Toggles the enable state for the Close button (and the Close menu item in - // the system menu). - virtual void EnableClose(bool enable) = 0; - - // Prevents the window from being rendered as deactivated the next time it is. - // This state is reset automatically as soon as the window becomes activated - // again. There is no ability to control the state through this API as this - // leads to sync problems. - virtual void DisableInactiveRendering() = 0; - - // Tell the window to update its title from the delegate. - virtual void UpdateWindowTitle() = 0; - - // Tell the window to update its icon from the delegate. - virtual void UpdateWindowIcon() = 0; - - // Creates an appropriate NonClientFrameView for this window. - virtual NonClientFrameView* CreateFrameViewForWindow() = 0; - - // Updates the frame after an event caused it to be changed. - virtual void UpdateFrameAfterFrameChange() = 0; - - // Retrieves the Window's delegate. - virtual WindowDelegate* GetDelegate() const = 0; - - // Retrieves the Window's non-client view. - virtual NonClientView* GetNonClientView() const = 0; - - // Retrieves the Window's client view. - virtual ClientView* GetClientView() const = 0; - - // Retrieves the Window's native window handle. - virtual gfx::NativeWindow GetNativeWindow() const = 0; -}; - -} // namespace views - -#endif // #ifndef CHROME_VIEWS_WINDOW_H__ diff --git a/chrome/views/window/app_modal_dialog_delegate.h b/chrome/views/window/app_modal_dialog_delegate.h new file mode 100644 index 0000000..6ccfc28 --- /dev/null +++ b/chrome/views/window/app_modal_dialog_delegate.h @@ -0,0 +1,24 @@ +// Copyright (c) 2006-2008 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_VIEWS_WINDOW_APP_MODAL_DIALOG_DELEGATE_H_ +#define CHROME_VIEWS_WINDOW_APP_MODAL_DIALOG_DELEGATE_H_ + +#include "chrome/views/window/dialog_delegate.h" + +namespace views { + +// Pure virtual interface for a window which is app modal. +class AppModalDialogDelegate : public DialogDelegate { + public: + // Called by the app modal window queue when it is time to show this window. + virtual void ShowModalDialog() = 0; + + // Called by the app modal window queue to activate the window. + virtual void ActivateModalDialog() = 0; +}; + +} // namespace views + +#endif // #ifndef CHROME_VIEWS_WINDOW_APP_MODAL_DIALOG_DELEGATE_H_ diff --git a/chrome/views/window/client_view.cc b/chrome/views/window/client_view.cc new file mode 100644 index 0000000..37ae937 --- /dev/null +++ b/chrome/views/window/client_view.cc @@ -0,0 +1,61 @@ +// Copyright (c) 2006-2008 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. + +#include "base/logging.h" +#include "chrome/views/window/client_view.h" +#include "chrome/views/window/window.h" +#include "chrome/views/window/window_delegate.h" + +namespace views { + +/////////////////////////////////////////////////////////////////////////////// +// ClientView, public: + +ClientView::ClientView(Window* window, View* contents_view) + : window_(window), + contents_view_(contents_view) { +} + +int ClientView::NonClientHitTest(const gfx::Point& point) { + return bounds().Contains(point) ? HTCLIENT : HTNOWHERE; +} + +void ClientView::WindowClosing() { + window_->GetDelegate()->WindowClosing(); +} + +/////////////////////////////////////////////////////////////////////////////// +// ClientView, View overrides: + +gfx::Size ClientView::GetPreferredSize() { + // |contents_view_| is allowed to be NULL up until the point where this view + // is attached to a Container. + if (contents_view_) + return contents_view_->GetPreferredSize(); + return gfx::Size(); +} + +void ClientView::Layout() { + // |contents_view_| is allowed to be NULL up until the point where this view + // is attached to a Container. + if (contents_view_) + contents_view_->SetBounds(0, 0, width(), height()); +} + +void ClientView::ViewHierarchyChanged(bool is_add, View* parent, View* child) { + if (is_add && child == this) { + DCHECK(GetWidget()); + DCHECK(contents_view_); // |contents_view_| must be valid now! + AddChildView(contents_view_); + } +} + +void ClientView::DidChangeBounds(const gfx::Rect& previous, + const gfx::Rect& current) { + // Overridden to do nothing. The NonClientView manually calls Layout on the + // ClientView when it is itself laid out, see comment in + // NonClientView::Layout. +} + +} // namespace views diff --git a/chrome/views/window/client_view.h b/chrome/views/window/client_view.h new file mode 100644 index 0000000..9db0c69 --- /dev/null +++ b/chrome/views/window/client_view.h @@ -0,0 +1,84 @@ +// Copyright (c) 2006-2008 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_VIEWS_WINDOW_CLIENT_VIEW_H_ +#define CHROME_VIEWS_WINDOW_CLIENT_VIEW_H_ + +#include "chrome/views/view.h" + +namespace views { + +class DialogClientView; +class Window; + +/////////////////////////////////////////////////////////////////////////////// +// ClientView +// +// A ClientView is a View subclass that is used to occupy the "client area" +// of a window. It provides basic information to the window that contains it +// such as non-client hit testing information, sizing etc. Sub-classes of +// ClientView are used to create more elaborate contents, e.g. +// "DialogClientView". +class ClientView : public View { + public: + // Constructs a ClientView object for the specified window with the specified + // contents. Since this object is created during the process of creating + // |window|, |contents_view| must be valid if you want the initial size of + // the window to be based on |contents_view|'s preferred size. + ClientView(Window* window, View* contents_view); + virtual ~ClientView() {} + + // Manual RTTI ftw. + virtual DialogClientView* AsDialogClientView() { return NULL; } + + // Returns true to signal that the Window can be closed. Specialized + // ClientView subclasses can override this default behavior to allow the + // close to be blocked until the user corrects mistakes, accepts a warning + // dialog, etc. + virtual bool CanClose() const { return true; } + + // Notification that the window is closing. The default implementation + // forwards the notification to the delegate. + virtual void WindowClosing(); + + // Tests to see if the specified point (in view coordinates) is within the + // bounds of this view. If so, it returns HTCLIENT in this default + // implementation. If it is outside the bounds of this view, this must return + // HTNOWHERE to tell the caller to do further processing to determine where + // in the non-client area it is (if it is). + // Subclasses of ClientView can extend this logic by overriding this method + // to detect if regions within the client area count as parts of the "non- + // client" area. A good example of this is the size box at the bottom right + // corner of resizable dialog boxes. + virtual int NonClientHitTest(const gfx::Point& point); + + // Overridden from View: + virtual gfx::Size GetPreferredSize(); + virtual void Layout(); + + protected: + // Overridden from View: + virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); + virtual void DidChangeBounds(const gfx::Rect& previous, + const gfx::Rect& current); + + // Accessors for private data members. + Window* window() const { return window_; } + void set_window(Window* window) { window_ = window; } + View* contents_view() const { return contents_view_; } + void set_contents_view(View* contents_view) { + contents_view_ = contents_view; + } + + private: + // The Window that hosts this ClientView. + Window* window_; + + // The View that this ClientView contains. + View* contents_view_; +}; + +} // namespace views + +#endif // #ifndef CHROME_VIEWS_WINDOW_CLIENT_VIEW_H_ diff --git a/chrome/views/window/custom_frame_view.cc b/chrome/views/window/custom_frame_view.cc new file mode 100644 index 0000000..d3843a4 --- /dev/null +++ b/chrome/views/window/custom_frame_view.cc @@ -0,0 +1,696 @@ +// 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. + +#include "chrome/views/window/custom_frame_view.h" + +#include "base/win_util.h" +#include "chrome/common/gfx/path.h" +#include "chrome/common/gfx/chrome_canvas.h" +#include "chrome/common/gfx/chrome_font.h" +#include "chrome/common/resource_bundle.h" +#include "chrome/common/win_util.h" +#include "chrome/views/window/client_view.h" +#include "chrome/views/window/window_delegate.h" +#include "grit/theme_resources.h" + +namespace views { + +// An enumeration of bitmap resources used by this window. +enum { + FRAME_PART_BITMAP_FIRST = 0, // Must be first. + + // Window Controls. + FRAME_CLOSE_BUTTON_ICON, + FRAME_CLOSE_BUTTON_ICON_H, + FRAME_CLOSE_BUTTON_ICON_P, + FRAME_CLOSE_BUTTON_ICON_SA, + FRAME_CLOSE_BUTTON_ICON_SA_H, + FRAME_CLOSE_BUTTON_ICON_SA_P, + FRAME_RESTORE_BUTTON_ICON, + FRAME_RESTORE_BUTTON_ICON_H, + FRAME_RESTORE_BUTTON_ICON_P, + FRAME_MAXIMIZE_BUTTON_ICON, + FRAME_MAXIMIZE_BUTTON_ICON_H, + FRAME_MAXIMIZE_BUTTON_ICON_P, + FRAME_MINIMIZE_BUTTON_ICON, + FRAME_MINIMIZE_BUTTON_ICON_H, + FRAME_MINIMIZE_BUTTON_ICON_P, + + // Window Frame Border. + FRAME_BOTTOM_EDGE, + FRAME_BOTTOM_LEFT_CORNER, + FRAME_BOTTOM_RIGHT_CORNER, + FRAME_LEFT_EDGE, + FRAME_RIGHT_EDGE, + FRAME_TOP_EDGE, + FRAME_TOP_LEFT_CORNER, + FRAME_TOP_RIGHT_CORNER, + + // Client Edge Border. + FRAME_CLIENT_EDGE_TOP_LEFT, + FRAME_CLIENT_EDGE_TOP, + FRAME_CLIENT_EDGE_TOP_RIGHT, + FRAME_CLIENT_EDGE_RIGHT, + FRAME_CLIENT_EDGE_BOTTOM_RIGHT, + FRAME_CLIENT_EDGE_BOTTOM, + FRAME_CLIENT_EDGE_BOTTOM_LEFT, + FRAME_CLIENT_EDGE_LEFT, + + FRAME_PART_BITMAP_COUNT // Must be last. +}; + +class ActiveWindowResources : public WindowResources { + public: + ActiveWindowResources() { + InitClass(); + } + virtual ~ActiveWindowResources() { + } + + // WindowResources implementation: + virtual SkBitmap* GetPartBitmap(FramePartBitmap part) const { + return standard_frame_bitmaps_[part]; + } + + private: + static void InitClass() { + static bool initialized = false; + if (!initialized) { + static const int kFramePartBitmapIds[] = { + 0, + IDR_CLOSE, IDR_CLOSE_H, IDR_CLOSE_P, + IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P, + IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P, + IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P, + IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P, + IDR_WINDOW_BOTTOM_CENTER, IDR_WINDOW_BOTTOM_LEFT_CORNER, + IDR_WINDOW_BOTTOM_RIGHT_CORNER, IDR_WINDOW_LEFT_SIDE, + IDR_WINDOW_RIGHT_SIDE, IDR_WINDOW_TOP_CENTER, + IDR_WINDOW_TOP_LEFT_CORNER, IDR_WINDOW_TOP_RIGHT_CORNER, + IDR_APP_TOP_LEFT, IDR_APP_TOP_CENTER, IDR_APP_TOP_RIGHT, + IDR_CONTENT_RIGHT_SIDE, IDR_CONTENT_BOTTOM_RIGHT_CORNER, + IDR_CONTENT_BOTTOM_CENTER, IDR_CONTENT_BOTTOM_LEFT_CORNER, + IDR_CONTENT_LEFT_SIDE, + 0 + }; + + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i) { + int id = kFramePartBitmapIds[i]; + if (id != 0) + standard_frame_bitmaps_[i] = rb.GetBitmapNamed(id); + } + initialized = true; + } + } + + static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT]; + static ChromeFont title_font_; + + DISALLOW_EVIL_CONSTRUCTORS(ActiveWindowResources); +}; + +class InactiveWindowResources : public WindowResources { + public: + InactiveWindowResources() { + InitClass(); + } + virtual ~InactiveWindowResources() { + } + + // WindowResources implementation: + virtual SkBitmap* GetPartBitmap(FramePartBitmap part) const { + return standard_frame_bitmaps_[part]; + } + + private: + static void InitClass() { + static bool initialized = false; + if (!initialized) { + static const int kFramePartBitmapIds[] = { + 0, + IDR_CLOSE, IDR_CLOSE_H, IDR_CLOSE_P, + IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P, + IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P, + IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P, + IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P, + IDR_DEWINDOW_BOTTOM_CENTER, IDR_DEWINDOW_BOTTOM_LEFT_CORNER, + IDR_DEWINDOW_BOTTOM_RIGHT_CORNER, IDR_DEWINDOW_LEFT_SIDE, + IDR_DEWINDOW_RIGHT_SIDE, IDR_DEWINDOW_TOP_CENTER, + IDR_DEWINDOW_TOP_LEFT_CORNER, IDR_DEWINDOW_TOP_RIGHT_CORNER, + IDR_APP_TOP_LEFT, IDR_APP_TOP_CENTER, IDR_APP_TOP_RIGHT, + IDR_CONTENT_RIGHT_SIDE, IDR_CONTENT_BOTTOM_RIGHT_CORNER, + IDR_CONTENT_BOTTOM_CENTER, IDR_CONTENT_BOTTOM_LEFT_CORNER, + IDR_CONTENT_LEFT_SIDE, + 0 + }; + + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i) { + int id = kFramePartBitmapIds[i]; + if (id != 0) + standard_frame_bitmaps_[i] = rb.GetBitmapNamed(id); + } + initialized = true; + } + } + + static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT]; + + DISALLOW_EVIL_CONSTRUCTORS(InactiveWindowResources); +}; + +// static +SkBitmap* ActiveWindowResources::standard_frame_bitmaps_[]; +SkBitmap* InactiveWindowResources::standard_frame_bitmaps_[]; + +// static +WindowResources* CustomFrameView::active_resources_ = NULL; +WindowResources* CustomFrameView::inactive_resources_ = NULL; +ChromeFont CustomFrameView::title_font_; + +namespace { +// The frame border is only visible in restored mode and is hardcoded to 4 px on +// each side regardless of the system window border size. +const int kFrameBorderThickness = 4; +// Various edges of the frame border have a 1 px shadow along their edges; in a +// few cases we shift elements based on this amount for visual appeal. +const int kFrameShadowThickness = 1; +// While resize areas on Windows are normally the same size as the window +// borders, our top area is shrunk by 1 px to make it easier to move the window +// around with our thinner top grabbable strip. (Incidentally, our side and +// bottom resize areas don't match the frame border thickness either -- they +// span the whole nonclient area, so there's no "dead zone" for the mouse.) +const int kTopResizeAdjust = 1; +// In the window corners, the resize areas don't actually expand bigger, but the +// 16 px at the end of each edge triggers diagonal resizing. +const int kResizeAreaCornerSize = 16; +// The titlebar never shrinks to less than 18 px tall, plus the height of the +// frame border and any bottom edge. +const int kTitlebarMinimumHeight = 18; +// The icon is inset 2 px from the left frame border. +const int kIconLeftSpacing = 2; +// The icon takes up 16/25th of the available titlebar height. (This is +// expressed as two ints to avoid precision losses leading to off-by-one pixel +// errors.) +const int kIconHeightFractionNumerator = 16; +const int kIconHeightFractionDenominator = 25; +// The icon never shrinks below 16 px on a side. +const int kIconMinimumSize = 16; +// Because our frame border has a different "3D look" than Windows', with a less +// cluttered top edge, we need to shift the icon up by 1 px in restored mode so +// it looks more centered. +const int kIconRestoredAdjust = 1; +// There is a 4 px gap between the icon and the title text. +const int kIconTitleSpacing = 4; +// The title text starts 2 px below the bottom of the top frame border. +const int kTitleTopSpacing = 2; +// There is a 5 px gap between the title text and the caption buttons. +const int kTitleCaptionSpacing = 5; +// The caption buttons are always drawn 1 px down from the visible top of the +// window (the true top in restored mode, or the top of the screen in maximized +// mode). +const int kCaptionTopSpacing = 1; +} + +/////////////////////////////////////////////////////////////////////////////// +// CustomFrameView, public: + +CustomFrameView::CustomFrameView(Window* frame) + : NonClientFrameView(), + close_button_(new ImageButton(this)), + restore_button_(new ImageButton(this)), + maximize_button_(new ImageButton(this)), + minimize_button_(new ImageButton(this)), + system_menu_button_(new ImageButton(this)), + should_show_minmax_buttons_(false), + frame_(frame) { + InitClass(); + WindowResources* resources = active_resources_; + + // Close button images will be set in LayoutWindowControls(). + AddChildView(close_button_); + + restore_button_->SetImage(CustomButton::BS_NORMAL, + resources->GetPartBitmap(FRAME_RESTORE_BUTTON_ICON)); + restore_button_->SetImage(CustomButton::BS_HOT, + resources->GetPartBitmap(FRAME_RESTORE_BUTTON_ICON_H)); + restore_button_->SetImage(CustomButton::BS_PUSHED, + resources->GetPartBitmap(FRAME_RESTORE_BUTTON_ICON_P)); + AddChildView(restore_button_); + + maximize_button_->SetImage(CustomButton::BS_NORMAL, + resources->GetPartBitmap(FRAME_MAXIMIZE_BUTTON_ICON)); + maximize_button_->SetImage(CustomButton::BS_HOT, + resources->GetPartBitmap(FRAME_MAXIMIZE_BUTTON_ICON_H)); + maximize_button_->SetImage(CustomButton::BS_PUSHED, + resources->GetPartBitmap(FRAME_MAXIMIZE_BUTTON_ICON_P)); + AddChildView(maximize_button_); + + minimize_button_->SetImage(CustomButton::BS_NORMAL, + resources->GetPartBitmap(FRAME_MINIMIZE_BUTTON_ICON)); + minimize_button_->SetImage(CustomButton::BS_HOT, + resources->GetPartBitmap(FRAME_MINIMIZE_BUTTON_ICON_H)); + minimize_button_->SetImage(CustomButton::BS_PUSHED, + resources->GetPartBitmap(FRAME_MINIMIZE_BUTTON_ICON_P)); + AddChildView(minimize_button_); + + should_show_minmax_buttons_ = frame_->GetDelegate()->CanMaximize(); + + AddChildView(system_menu_button_); +} + +CustomFrameView::~CustomFrameView() { +} + +/////////////////////////////////////////////////////////////////////////////// +// CustomFrameView, NonClientFrameView implementation: + +gfx::Rect CustomFrameView::GetBoundsForClientView() const { + return client_view_bounds_; +} + +gfx::Rect CustomFrameView::GetWindowBoundsForClientBounds( + const gfx::Rect& client_bounds) const { + int top_height = NonClientTopBorderHeight(); + int border_thickness = NonClientBorderThickness(); + return gfx::Rect(std::max(0, client_bounds.x() - border_thickness), + std::max(0, client_bounds.y() - top_height), + client_bounds.width() + (2 * border_thickness), + client_bounds.height() + top_height + border_thickness); +} + +gfx::Point CustomFrameView::GetSystemMenuPoint() const { + gfx::Point system_menu_point(FrameBorderThickness(), + NonClientTopBorderHeight() - BottomEdgeThicknessWithinNonClientHeight()); + ConvertPointToScreen(this, &system_menu_point); + return system_menu_point; +} + +int CustomFrameView::NonClientHitTest(const gfx::Point& point) { + // Then see if the point is within any of the window controls. + if (close_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(point)) + return HTCLOSE; + if (restore_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains( + point)) + return HTMAXBUTTON; + if (maximize_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains( + point)) + return HTMAXBUTTON; + if (minimize_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains( + point)) + return HTMINBUTTON; + if (system_menu_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains( + point)) + return HTSYSMENU; + + int window_component = GetHTComponentForFrame(point, FrameBorderThickness(), + NonClientBorderThickness(), kResizeAreaCornerSize, kResizeAreaCornerSize, + frame_->GetDelegate()->CanResize()); + // Fall back to the caption if no other component matches. + return (window_component == HTNOWHERE) ? HTCAPTION : window_component; +} + +void CustomFrameView::GetWindowMask(const gfx::Size& size, + gfx::Path* window_mask) { + DCHECK(window_mask); + + // Redefine the window visible region for the new size. + window_mask->moveTo(0, 3); + window_mask->lineTo(1, 2); + window_mask->lineTo(1, 1); + window_mask->lineTo(2, 1); + window_mask->lineTo(3, 0); + + window_mask->lineTo(SkIntToScalar(size.width() - 3), 0); + window_mask->lineTo(SkIntToScalar(size.width() - 2), 1); + window_mask->lineTo(SkIntToScalar(size.width() - 1), 1); + window_mask->lineTo(SkIntToScalar(size.width() - 1), 2); + window_mask->lineTo(SkIntToScalar(size.width()), 3); + + window_mask->lineTo(SkIntToScalar(size.width()), + SkIntToScalar(size.height())); + window_mask->lineTo(0, SkIntToScalar(size.height())); + window_mask->close(); +} + +void CustomFrameView::EnableClose(bool enable) { + close_button_->SetEnabled(enable); +} + +void CustomFrameView::ResetWindowControls() { + restore_button_->SetState(CustomButton::BS_NORMAL); + minimize_button_->SetState(CustomButton::BS_NORMAL); + maximize_button_->SetState(CustomButton::BS_NORMAL); + // The close button isn't affected by this constraint. +} + +/////////////////////////////////////////////////////////////////////////////// +// CustomFrameView, View overrides: + +void CustomFrameView::Paint(ChromeCanvas* canvas) { + if (frame_->IsMaximized()) + PaintMaximizedFrameBorder(canvas); + else + PaintRestoredFrameBorder(canvas); + PaintTitleBar(canvas); + if (!frame_->IsMaximized()) + PaintRestoredClientEdge(canvas); +} + +void CustomFrameView::Layout() { + LayoutWindowControls(); + LayoutTitleBar(); + LayoutClientView(); +} + +gfx::Size CustomFrameView::GetPreferredSize() { + gfx::Size pref = frame_->GetClientView()->GetPreferredSize(); + DCHECK(pref.width() > 0 && pref.height() > 0); + gfx::Rect bounds(0, 0, pref.width(), pref.height()); + return frame_->GetNonClientView()->GetWindowBoundsForClientBounds( + bounds).size(); +} + +/////////////////////////////////////////////////////////////////////////////// +// CustomFrameView, ButtonListener implementation: + +void CustomFrameView::ButtonPressed(Button* sender) { + if (sender == close_button_) + frame_->Close(); + else if (sender == minimize_button_) + frame_->Minimize(); + else if (sender == maximize_button_) + frame_->Maximize(); + else if (sender == restore_button_) + frame_->Restore(); +} + +/////////////////////////////////////////////////////////////////////////////// +// CustomFrameView, private: + +int CustomFrameView::FrameBorderThickness() const { + return frame_->IsMaximized() ? + GetSystemMetrics(SM_CXSIZEFRAME) : kFrameBorderThickness; +} + +int CustomFrameView::NonClientBorderThickness() const { + // In maximized mode, we don't show a client edge. + return FrameBorderThickness() + + (frame_->IsMaximized() ? 0 : kClientEdgeThickness); +} + +int CustomFrameView::NonClientTopBorderHeight() const { + int title_top_spacing, title_thickness; + return TitleCoordinates(&title_top_spacing, &title_thickness); +} + +int CustomFrameView::BottomEdgeThicknessWithinNonClientHeight() const { + return kFrameShadowThickness + + (frame_->IsMaximized() ? 0 : kClientEdgeThickness); +} + +int CustomFrameView::TitleCoordinates(int* title_top_spacing, + int* title_thickness) const { + int frame_thickness = FrameBorderThickness(); + int min_titlebar_height = kTitlebarMinimumHeight + frame_thickness; + *title_top_spacing = frame_thickness + kTitleTopSpacing; + // The bottom spacing should be the same apparent height as the top spacing. + // Because the actual top spacing height varies based on the system border + // thickness, we calculate this based on the restored top spacing and then + // adjust for maximized mode. We also don't include the frame shadow here, + // since while it's part of the bottom spacing it will be added in at the end. + int title_bottom_spacing = + kFrameBorderThickness + kTitleTopSpacing - kFrameShadowThickness; + if (frame_->IsMaximized()) { + // When we maximize, the top border appears to be chopped off; shift the + // title down to stay centered within the remaining space. + int title_adjust = (kFrameBorderThickness / 2); + *title_top_spacing += title_adjust; + title_bottom_spacing -= title_adjust; + } + *title_thickness = std::max(title_font_.height(), + min_titlebar_height - *title_top_spacing - title_bottom_spacing); + return *title_top_spacing + *title_thickness + title_bottom_spacing + + BottomEdgeThicknessWithinNonClientHeight(); +} + +void CustomFrameView::PaintRestoredFrameBorder(ChromeCanvas* canvas) { + SkBitmap* top_left_corner = resources()->GetPartBitmap(FRAME_TOP_LEFT_CORNER); + SkBitmap* top_right_corner = + resources()->GetPartBitmap(FRAME_TOP_RIGHT_CORNER); + SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE); + SkBitmap* right_edge = resources()->GetPartBitmap(FRAME_RIGHT_EDGE); + SkBitmap* left_edge = resources()->GetPartBitmap(FRAME_LEFT_EDGE); + SkBitmap* bottom_left_corner = + resources()->GetPartBitmap(FRAME_BOTTOM_LEFT_CORNER); + SkBitmap* bottom_right_corner = + resources()->GetPartBitmap(FRAME_BOTTOM_RIGHT_CORNER); + SkBitmap* bottom_edge = resources()->GetPartBitmap(FRAME_BOTTOM_EDGE); + + // Top. + canvas->DrawBitmapInt(*top_left_corner, 0, 0); + canvas->TileImageInt(*top_edge, top_left_corner->width(), 0, + width() - top_right_corner->width(), top_edge->height()); + canvas->DrawBitmapInt(*top_right_corner, + width() - top_right_corner->width(), 0); + + // Right. + canvas->TileImageInt(*right_edge, width() - right_edge->width(), + top_right_corner->height(), right_edge->width(), + height() - top_right_corner->height() - + bottom_right_corner->height()); + + // Bottom. + canvas->DrawBitmapInt(*bottom_right_corner, + width() - bottom_right_corner->width(), + height() - bottom_right_corner->height()); + canvas->TileImageInt(*bottom_edge, bottom_left_corner->width(), + height() - bottom_edge->height(), + width() - bottom_left_corner->width() - + bottom_right_corner->width(), + bottom_edge->height()); + canvas->DrawBitmapInt(*bottom_left_corner, 0, + height() - bottom_left_corner->height()); + + // Left. + canvas->TileImageInt(*left_edge, 0, top_left_corner->height(), + left_edge->width(), + height() - top_left_corner->height() - bottom_left_corner->height()); +} + +void CustomFrameView::PaintMaximizedFrameBorder( + ChromeCanvas* canvas) { + SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE); + canvas->TileImageInt(*top_edge, 0, FrameBorderThickness(), width(), + top_edge->height()); + + // The bottom of the titlebar actually comes from the top of the Client Edge + // graphic, with the actual client edge clipped off the bottom. + SkBitmap* titlebar_bottom = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP); + int edge_height = titlebar_bottom->height() - kClientEdgeThickness; + canvas->TileImageInt(*titlebar_bottom, 0, + frame_->GetClientView()->y() - edge_height, width(), edge_height); +} + +void CustomFrameView::PaintTitleBar(ChromeCanvas* canvas) { + WindowDelegate* d = frame_->GetDelegate(); + + // It seems like in some conditions we can be asked to paint after the window + // that contains us is WM_DESTROYed. At this point, our delegate is NULL. The + // correct long term fix may be to shut down the RootView in WM_DESTROY. + if (!d) + return; + + canvas->DrawStringInt(d->GetWindowTitle(), title_font_, SK_ColorWHITE, + MirroredLeftPointForRect(title_bounds_), title_bounds_.y(), + title_bounds_.width(), title_bounds_.height()); +} + +void CustomFrameView::PaintRestoredClientEdge(ChromeCanvas* canvas) { + gfx::Rect client_area_bounds = frame_->GetClientView()->bounds(); + int client_area_top = client_area_bounds.y(); + + SkBitmap* top_left = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_LEFT); + SkBitmap* top = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP); + SkBitmap* top_right = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_RIGHT); + SkBitmap* right = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_RIGHT); + SkBitmap* bottom_right = + resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_RIGHT); + SkBitmap* bottom = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM); + SkBitmap* bottom_left = + resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_LEFT); + SkBitmap* left = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_LEFT); + + // Top. + // This next calculation is necessary because the top center bitmap is shorter + // than the top left and right bitmaps. We need their top edges to line up, + // and we need the left and right edges to start below the corners' bottoms. + int top_edge_y = client_area_top - top->height(); + client_area_top = top_edge_y + top_left->height(); + canvas->DrawBitmapInt(*top_left, client_area_bounds.x() - top_left->width(), + top_edge_y); + canvas->TileImageInt(*top, client_area_bounds.x(), top_edge_y, + client_area_bounds.width(), top->height()); + canvas->DrawBitmapInt(*top_right, client_area_bounds.right(), top_edge_y); + + // Right. + int client_area_bottom = + std::max(client_area_top, client_area_bounds.bottom()); + int client_area_height = client_area_bottom - client_area_top; + canvas->TileImageInt(*right, client_area_bounds.right(), client_area_top, + right->width(), client_area_height); + + // Bottom. + canvas->DrawBitmapInt(*bottom_right, client_area_bounds.right(), + client_area_bottom); + canvas->TileImageInt(*bottom, client_area_bounds.x(), client_area_bottom, + client_area_bounds.width(), bottom_right->height()); + canvas->DrawBitmapInt(*bottom_left, + client_area_bounds.x() - bottom_left->width(), client_area_bottom); + + // Left. + canvas->TileImageInt(*left, client_area_bounds.x() - left->width(), + client_area_top, left->width(), client_area_height); +} + +void CustomFrameView::LayoutWindowControls() { + close_button_->SetImageAlignment(ImageButton::ALIGN_LEFT, + ImageButton::ALIGN_BOTTOM); + // Maximized buttons start at window top so that even if their images aren't + // drawn flush with the screen edge, they still obey Fitts' Law. + bool is_maximized = frame_->IsMaximized(); + int frame_thickness = FrameBorderThickness(); + int caption_y = is_maximized ? frame_thickness : kCaptionTopSpacing; + int top_extra_height = is_maximized ? kCaptionTopSpacing : 0; + // There should always be the same number of non-shadow pixels visible to the + // side of the caption buttons. In maximized mode we extend the rightmost + // button to the screen corner to obey Fitts' Law. + int right_extra_width = is_maximized ? + (kFrameBorderThickness - kFrameShadowThickness) : 0; + int right_spacing = is_maximized ? + (GetSystemMetrics(SM_CXSIZEFRAME) + right_extra_width) : frame_thickness; + gfx::Size close_button_size = close_button_->GetPreferredSize(); + close_button_->SetBounds(width() - close_button_size.width() - right_spacing, + caption_y, + close_button_size.width() + right_extra_width, + close_button_size.height() + top_extra_height); + + // When the window is restored, we show a maximized button; otherwise, we show + // a restore button. + bool is_restored = !is_maximized && !frame_->IsMinimized(); + views::ImageButton* invisible_button = is_restored ? + restore_button_ : maximize_button_; + invisible_button->SetVisible(false); + + views::ImageButton* visible_button = is_restored ? + maximize_button_ : restore_button_; + FramePartBitmap normal_part, hot_part, pushed_part; + if (should_show_minmax_buttons_) { + visible_button->SetVisible(true); + visible_button->SetImageAlignment(ImageButton::ALIGN_LEFT, + ImageButton::ALIGN_BOTTOM); + gfx::Size visible_button_size = visible_button->GetPreferredSize(); + visible_button->SetBounds(close_button_->x() - visible_button_size.width(), + caption_y, visible_button_size.width(), + visible_button_size.height() + top_extra_height); + + minimize_button_->SetVisible(true); + minimize_button_->SetImageAlignment(ImageButton::ALIGN_LEFT, + ImageButton::ALIGN_BOTTOM); + gfx::Size minimize_button_size = minimize_button_->GetPreferredSize(); + minimize_button_->SetBounds( + visible_button->x() - minimize_button_size.width(), caption_y, + minimize_button_size.width(), + minimize_button_size.height() + top_extra_height); + + normal_part = FRAME_CLOSE_BUTTON_ICON; + hot_part = FRAME_CLOSE_BUTTON_ICON_H; + pushed_part = FRAME_CLOSE_BUTTON_ICON_P; + } else { + visible_button->SetVisible(false); + minimize_button_->SetVisible(false); + + normal_part = FRAME_CLOSE_BUTTON_ICON_SA; + hot_part = FRAME_CLOSE_BUTTON_ICON_SA_H; + pushed_part = FRAME_CLOSE_BUTTON_ICON_SA_P; + } + + close_button_->SetImage(CustomButton::BS_NORMAL, + active_resources_->GetPartBitmap(normal_part)); + close_button_->SetImage(CustomButton::BS_HOT, + active_resources_->GetPartBitmap(hot_part)); + close_button_->SetImage(CustomButton::BS_PUSHED, + active_resources_->GetPartBitmap(pushed_part)); +} + +void CustomFrameView::LayoutTitleBar() { + // Always lay out the icon, even when it's not present, so we can lay out the + // window title based on its position. + int frame_thickness = FrameBorderThickness(); + int icon_x = frame_thickness + kIconLeftSpacing; + + // The usable height of the titlebar area is the total height minus the top + // resize border and any edge area we draw at its bottom. + int title_top_spacing, title_thickness; + int top_height = TitleCoordinates(&title_top_spacing, &title_thickness); + int available_height = top_height - frame_thickness - + BottomEdgeThicknessWithinNonClientHeight(); + + // The icon takes up a constant fraction of the available height, down to a + // minimum size, and is always an even number of pixels on a side (presumably + // to make scaled icons look better). It's centered within the usable height. + int icon_size = std::max((available_height * kIconHeightFractionNumerator / + kIconHeightFractionDenominator) / 2 * 2, kIconMinimumSize); + int icon_y = ((available_height - icon_size) / 2) + frame_thickness; + + // Hack: Our frame border has a different "3D look" than Windows'. Theirs has + // a more complex gradient on the top that they push their icon/title below; + // then the maximized window cuts this off and the icon/title are centered in + // the remaining space. Because the apparent shape of our border is simpler, + // using the same positioning makes things look slightly uncentered with + // restored windows, so we come up to compensate. + if (!frame_->IsMaximized()) + icon_y -= kIconRestoredAdjust; + + views::WindowDelegate* d = frame_->GetDelegate(); + if (!d->ShouldShowWindowIcon()) + icon_size = 0; + system_menu_button_->SetBounds(icon_x, icon_y, icon_size, icon_size); + + // Size the title. + int icon_right = icon_x + icon_size; + int title_x = + icon_right + (d->ShouldShowWindowIcon() ? kIconTitleSpacing : 0); + int title_right = (should_show_minmax_buttons_ ? + minimize_button_->x() : close_button_->x()) - kTitleCaptionSpacing; + title_bounds_.SetRect(title_x, + title_top_spacing + ((title_thickness - title_font_.height()) / 2), + std::max(0, title_right - title_x), title_font_.height()); +} + +void CustomFrameView::LayoutClientView() { + int top_height = NonClientTopBorderHeight(); + int border_thickness = NonClientBorderThickness(); + client_view_bounds_.SetRect( + border_thickness, + top_height, + std::max(0, width() - (2 * border_thickness)), + std::max(0, height() - top_height - border_thickness)); +} + +// static +void CustomFrameView::InitClass() { + static bool initialized = false; + if (!initialized) { + active_resources_ = new ActiveWindowResources; + inactive_resources_ = new InactiveWindowResources; + + title_font_ = win_util::GetWindowTitleFont(); + + initialized = true; + } +} + +} // namespace views diff --git a/chrome/views/window/custom_frame_view.h b/chrome/views/window/custom_frame_view.h new file mode 100644 index 0000000..9b06c3f --- /dev/null +++ b/chrome/views/window/custom_frame_view.h @@ -0,0 +1,122 @@ +// 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_VIEWS_WINDOW_CUSTOM_FRAME_VIEW_H_ +#define CHROME_VIEWS_WINDOW_CUSTOM_FRAME_VIEW_H_ + +#include "chrome/views/image_button.h" +#include "chrome/views/window/non_client_view.h" +#include "chrome/views/window/window.h" +#include "chrome/views/window/window_resources.h" + +namespace gfx{ +class Size; +class Path; +class Point; +} +class ChromeCanvas; +class ChromeFont; + +namespace views { + +/////////////////////////////////////////////////////////////////////////////// +// +// CustomFrameView +// +// A ChromeView that provides the non client frame for Windows. This means +// rendering the non-standard window caption, border, and controls. +// +//////////////////////////////////////////////////////////////////////////////// +class CustomFrameView : public NonClientFrameView, + public ButtonListener { + public: + explicit CustomFrameView(Window* frame); + virtual ~CustomFrameView(); + + // Overridden from views::NonClientFrameView: + virtual gfx::Rect GetBoundsForClientView() const; + virtual gfx::Rect GetWindowBoundsForClientBounds( + const gfx::Rect& client_bounds) const; + virtual gfx::Point GetSystemMenuPoint() const; + virtual int NonClientHitTest(const gfx::Point& point); + virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask); + virtual void EnableClose(bool enable); + virtual void ResetWindowControls(); + + // View overrides: + virtual void Paint(ChromeCanvas* canvas); + virtual void Layout(); + virtual gfx::Size GetPreferredSize(); + + // ButtonListener implementation: + virtual void ButtonPressed(Button* sender); + + private: + // Returns the thickness of the border that makes up the window frame edges. + // This does not include any client edge. + int FrameBorderThickness() const; + + // Returns the thickness of the entire nonclient left, right, and bottom + // borders, including both the window frame and any client edge. + int NonClientBorderThickness() const; + + // Returns the height of the entire nonclient top border, including the window + // frame, any title area, and any connected client edge. + int NonClientTopBorderHeight() const; + + // A bottom border, and, in restored mode, a client edge are drawn at the + // bottom of the titlebar. This returns the total height drawn. + int BottomEdgeThicknessWithinNonClientHeight() const; + + // Calculates multiple values related to title layout. Returns the height of + // the entire titlebar including any connected client edge. + int TitleCoordinates(int* title_top_spacing, + int* title_thickness) const; + + // Paint various sub-components of this view. + void PaintRestoredFrameBorder(ChromeCanvas* canvas); + void PaintMaximizedFrameBorder(ChromeCanvas* canvas); + void PaintTitleBar(ChromeCanvas* canvas); + void PaintRestoredClientEdge(ChromeCanvas* canvas); + + // Layout various sub-components of this view. + void LayoutWindowControls(); + void LayoutTitleBar(); + void LayoutClientView(); + + // Returns the resource collection to be used when rendering the window. + WindowResources* resources() const { + return frame_->IsActive() || paint_as_active() ? active_resources_ + : inactive_resources_; + } + + // The bounds of the client view, in this view's coordinates. + gfx::Rect client_view_bounds_; + + // The layout rect of the title, if visible. + gfx::Rect title_bounds_; + + // Window controls. + ImageButton* close_button_; + ImageButton* restore_button_; + ImageButton* maximize_button_; + ImageButton* minimize_button_; + ImageButton* system_menu_button_; // Uses the window icon if visible. + bool should_show_minmax_buttons_; + + // The window that owns this view. + Window* frame_; + + // Initialize various static resources. + static void InitClass(); + static WindowResources* active_resources_; + static WindowResources* inactive_resources_; + static ChromeFont title_font_; + + DISALLOW_EVIL_CONSTRUCTORS(CustomFrameView); +}; + +} // namespace views + +#endif // #ifndef CHROME_VIEWS_WINDOW_CUSTOM_FRAME_VIEW_H_ diff --git a/chrome/views/window/dialog_client_view.cc b/chrome/views/window/dialog_client_view.cc new file mode 100644 index 0000000..dbc3b179 --- /dev/null +++ b/chrome/views/window/dialog_client_view.cc @@ -0,0 +1,434 @@ +// Copyright (c) 2006-2008 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. + +#include "chrome/views/window/dialog_client_view.h" + +#include +#include +#include + +#include "base/gfx/native_theme.h" +#include "chrome/browser/views/standard_layout.h" +#include "chrome/common/gfx/chrome_canvas.h" +#include "chrome/common/gfx/chrome_font.h" +#include "chrome/common/l10n_util.h" +#include "chrome/common/resource_bundle.h" +#include "chrome/common/win_util.h" +#include "chrome/views/window/dialog_delegate.h" +#include "chrome/views/window/window.h" +#include "grit/generated_resources.h" + +namespace views { + +namespace { + +// Updates any of the standard buttons according to the delegate. +void UpdateButtonHelper(NativeButton* button_view, + DialogDelegate* delegate, + DialogDelegate::DialogButton button) { + std::wstring label = delegate->GetDialogButtonLabel(button); + if (!label.empty()) + button_view->SetLabel(label); + button_view->SetEnabled(delegate->IsDialogButtonEnabled(button)); + button_view->SetVisible(delegate->IsDialogButtonVisible(button)); +} + +void FillViewWithSysColor(ChromeCanvas* canvas, View* view, COLORREF color) { + SkColor sk_color = + SkColorSetRGB(GetRValue(color), GetGValue(color), GetBValue(color)); + canvas->FillRectInt(sk_color, 0, 0, view->width(), view->height()); +} + +// DialogButton ---------------------------------------------------------------- + +// DialogButtons is used for the ok/cancel buttons of the window. DialogButton +// forwards AcceleratorPressed to the delegate. + +class DialogButton : public NativeButton { + public: + DialogButton(Window* owner, + DialogDelegate::DialogButton type, + const std::wstring& title, + bool is_default) + : NativeButton(title, is_default), owner_(owner), type_(type) { + } + + // Overridden to forward to the delegate. + virtual bool AcceleratorPressed(const Accelerator& accelerator) { + if (!owner_->GetDelegate()->AsDialogDelegate()-> + AreAcceleratorsEnabled(type_)) { + return false; + } + return NativeButton::AcceleratorPressed(accelerator); + } + + private: + Window* owner_; + const DialogDelegate::DialogButton type_; + + DISALLOW_COPY_AND_ASSIGN(DialogButton); +}; + +} // namespace + +// static +ChromeFont DialogClientView::dialog_button_font_; +static const int kDialogMinButtonWidth = 75; +static const int kDialogButtonLabelSpacing = 16; +static const int kDialogButtonContentSpacing = 5; + +// The group used by the buttons. This name is chosen voluntarily big not to +// conflict with other groups that could be in the dialog content. +static const int kButtonGroup = 6666; + +/////////////////////////////////////////////////////////////////////////////// +// DialogClientView, public: + +DialogClientView::DialogClientView(Window* owner, View* contents_view) + : ClientView(owner, contents_view), + ok_button_(NULL), + cancel_button_(NULL), + extra_view_(NULL), + accepted_(false), + default_button_(NULL) { + InitClass(); +} + +DialogClientView::~DialogClientView() { +} + +void DialogClientView::ShowDialogButtons() { + DialogDelegate* dd = GetDialogDelegate(); + int buttons = dd->GetDialogButtons(); + if (buttons & DialogDelegate::DIALOGBUTTON_OK && !ok_button_) { + std::wstring label = + dd->GetDialogButtonLabel(DialogDelegate::DIALOGBUTTON_OK); + if (label.empty()) + label = l10n_util::GetString(IDS_OK); + bool is_default_button = + (dd->GetDefaultDialogButton() & DialogDelegate::DIALOGBUTTON_OK) != 0; + ok_button_ = new DialogButton(window(), DialogDelegate::DIALOGBUTTON_OK, + label, is_default_button); + ok_button_->SetListener(this); + ok_button_->SetGroup(kButtonGroup); + if (is_default_button) + default_button_ = ok_button_; + if (!(buttons & DialogDelegate::DIALOGBUTTON_CANCEL)) + ok_button_->AddAccelerator(Accelerator(VK_ESCAPE, false, false, false)); + AddChildView(ok_button_); + } + if (buttons & DialogDelegate::DIALOGBUTTON_CANCEL && !cancel_button_) { + std::wstring label = + dd->GetDialogButtonLabel(DialogDelegate::DIALOGBUTTON_CANCEL); + if (label.empty()) { + if (buttons & DialogDelegate::DIALOGBUTTON_OK) { + label = l10n_util::GetString(IDS_CANCEL); + } else { + label = l10n_util::GetString(IDS_CLOSE); + } + } + bool is_default_button = + (dd->GetDefaultDialogButton() & DialogDelegate::DIALOGBUTTON_CANCEL) + != 0; + cancel_button_ = new DialogButton(window(), + DialogDelegate::DIALOGBUTTON_CANCEL, + label, is_default_button); + cancel_button_->SetListener(this); + cancel_button_->SetGroup(kButtonGroup); + cancel_button_->AddAccelerator(Accelerator(VK_ESCAPE, false, false, false)); + if (is_default_button) + default_button_ = ok_button_; + AddChildView(cancel_button_); + } + if (!buttons) { + // Register the escape key as an accelerator which will close the window + // if there are no dialog buttons. + AddAccelerator(Accelerator(VK_ESCAPE, false, false, false)); + } +} + +void DialogClientView::SetDefaultButton(NativeButton* new_default_button) { + if (default_button_ && default_button_ != new_default_button) { + default_button_->SetDefaultButton(false); + default_button_ = NULL; + } + + if (new_default_button) { + default_button_ = new_default_button; + default_button_->SetDefaultButton(true); + } +} + +void DialogClientView::FocusWillChange(View* focused_before, + View* focused_now) { + NativeButton* new_default_button = NULL; + if (focused_now && + focused_now->GetClassName() == NativeButton::kViewClassName) { + new_default_button = static_cast(focused_now); + } else { + // The focused view is not a button, get the default button from the + // delegate. + DialogDelegate* dd = GetDialogDelegate(); + if ((dd->GetDefaultDialogButton() & DialogDelegate::DIALOGBUTTON_OK) != 0) + new_default_button = ok_button_; + if ((dd->GetDefaultDialogButton() & DialogDelegate::DIALOGBUTTON_CANCEL) + != 0) + new_default_button = cancel_button_; + } + SetDefaultButton(new_default_button); +} + +// Changing dialog labels will change button widths. +void DialogClientView::UpdateDialogButtons() { + DialogDelegate* dd = GetDialogDelegate(); + int buttons = dd->GetDialogButtons(); + + if (buttons & DialogDelegate::DIALOGBUTTON_OK) + UpdateButtonHelper(ok_button_, dd, DialogDelegate::DIALOGBUTTON_OK); + + if (buttons & DialogDelegate::DIALOGBUTTON_CANCEL) + UpdateButtonHelper(cancel_button_, dd, DialogDelegate::DIALOGBUTTON_CANCEL); + + LayoutDialogButtons(); + SchedulePaint(); +} + +void DialogClientView::AcceptWindow() { + if (accepted_) { + // We should only get into AcceptWindow once. + NOTREACHED(); + return; + } + accepted_ = true; + if (GetDialogDelegate()->Accept(false)) + window()->Close(); +} + +void DialogClientView::CancelWindow() { + // Call the standard Close handler, which checks with the delegate before + // proceeding. This checking _isn't_ done here, but in the WM_CLOSE handler, + // so that the close box on the window also shares this code path. + window()->Close(); +} + +/////////////////////////////////////////////////////////////////////////////// +// DialogClientView, ClientView overrides: + +bool DialogClientView::CanClose() const { + if (!accepted_) { + DialogDelegate* dd = GetDialogDelegate(); + int buttons = dd->GetDialogButtons(); + if (buttons & DialogDelegate::DIALOGBUTTON_CANCEL) + return dd->Cancel(); + if (buttons & DialogDelegate::DIALOGBUTTON_OK) + return dd->Accept(true); + } + return true; +} + +void DialogClientView::WindowClosing() { + FocusManager* focus_manager = GetFocusManager(); + DCHECK(focus_manager); + if (focus_manager) + focus_manager->RemoveFocusChangeListener(this); + ClientView::WindowClosing(); +} + +int DialogClientView::NonClientHitTest(const gfx::Point& point) { + if (size_box_bounds_.Contains(point.x() - x(), point.y() - y())) + return HTBOTTOMRIGHT; + return ClientView::NonClientHitTest(point); +} + +//////////////////////////////////////////////////////////////////////////////// +// DialogClientView, View overrides: + +void DialogClientView::Paint(ChromeCanvas* canvas) { + FillViewWithSysColor(canvas, this, GetSysColor(COLOR_3DFACE)); +} + +void DialogClientView::PaintChildren(ChromeCanvas* canvas) { + View::PaintChildren(canvas); + if (!window()->IsMaximized() && !window()->IsMinimized()) + PaintSizeBox(canvas); +} + +void DialogClientView::Layout() { + if (has_dialog_buttons()) + LayoutDialogButtons(); + LayoutContentsView(); +} + +void DialogClientView::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 + // Container's HWND. + ShowDialogButtons(); + ClientView::ViewHierarchyChanged(is_add, parent, child); + + FocusManager* focus_manager = GetFocusManager(); + // Listen for focus change events so we can update the default button. + DCHECK(focus_manager); // bug #1291225: crash reports seem to indicate it + // can be NULL. + if (focus_manager) + focus_manager->AddFocusChangeListener(this); + + // The "extra view" must be created and installed after the contents view + // has been inserted into the view hierarchy. + CreateExtraView(); + UpdateDialogButtons(); + Layout(); + } +} + +gfx::Size DialogClientView::GetPreferredSize() { + gfx::Size prefsize = contents_view()->GetPreferredSize(); + int button_height = 0; + if (has_dialog_buttons()) { + if (cancel_button_) + button_height = cancel_button_->height(); + else + button_height = ok_button_->height(); + // Account for padding above and below the button. + button_height += kDialogButtonContentSpacing + kButtonVEdgeMargin; + } + prefsize.Enlarge(0, button_height); + return prefsize; +} + +bool DialogClientView::AcceleratorPressed(const Accelerator& accelerator) { + DCHECK(accelerator.GetKeyCode() == VK_ESCAPE); // We only expect Escape key. + window()->Close(); + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// DialogClientView, NativeButton::Listener implementation: + +void DialogClientView::ButtonPressed(NativeButton* sender) { + if (sender == ok_button_) { + AcceptWindow(); + } else if (sender == cancel_button_) { + CancelWindow(); + } else { + NOTREACHED(); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// DialogClientView, private: + +void DialogClientView::PaintSizeBox(ChromeCanvas* canvas) { + if (window()->GetDelegate()->CanResize() || + window()->GetDelegate()->CanMaximize()) { + HDC dc = canvas->beginPlatformPaint(); + SIZE gripper_size = { 0, 0 }; + gfx::NativeTheme::instance()->GetThemePartSize( + gfx::NativeTheme::STATUS, dc, SP_GRIPPER, 1, NULL, TS_TRUE, + &gripper_size); + + // TODO(beng): (http://b/1085509) In "classic" rendering mode, there isn't + // a theme-supplied gripper. We should probably improvise + // something, which would also require changing |gripper_size| + // to have different default values, too... + size_box_bounds_ = GetLocalBounds(false); + size_box_bounds_.set_x(size_box_bounds_.right() - gripper_size.cx); + size_box_bounds_.set_y(size_box_bounds_.bottom() - gripper_size.cy); + RECT native_bounds = size_box_bounds_.ToRECT(); + gfx::NativeTheme::instance()->PaintStatusGripper( + dc, SP_PANE, 1, 0, &native_bounds); + canvas->endPlatformPaint(); + } +} + +int DialogClientView::GetButtonWidth(int button) const { + DialogDelegate* dd = GetDialogDelegate(); + std::wstring button_label = dd->GetDialogButtonLabel( + static_cast(button)); + int string_width = dialog_button_font_.GetStringWidth(button_label); + return std::max(string_width + kDialogButtonLabelSpacing, + kDialogMinButtonWidth); +} + +int DialogClientView::GetButtonsHeight() const { + if (has_dialog_buttons()) { + if (cancel_button_) + return cancel_button_->height() + kDialogButtonContentSpacing; + return ok_button_->height() + kDialogButtonContentSpacing; + } + return 0; +} + +void DialogClientView::LayoutDialogButtons() { + gfx::Rect extra_bounds; + if (cancel_button_) { + gfx::Size ps = cancel_button_->GetPreferredSize(); + gfx::Rect lb = GetLocalBounds(false); + int button_width = GetButtonWidth(DialogDelegate::DIALOGBUTTON_CANCEL); + int button_x = lb.right() - button_width - kButtonHEdgeMargin; + int button_y = lb.bottom() - ps.height() - kButtonVEdgeMargin; + cancel_button_->SetBounds(button_x, button_y, button_width, ps.height()); + // The extra view bounds are dependent on this button. + extra_bounds.set_width(std::max(0, cancel_button_->x())); + extra_bounds.set_y(cancel_button_->y()); + } + if (ok_button_) { + gfx::Size ps = ok_button_->GetPreferredSize(); + gfx::Rect lb = GetLocalBounds(false); + int button_width = GetButtonWidth(DialogDelegate::DIALOGBUTTON_OK); + int ok_button_right = lb.right() - kButtonHEdgeMargin; + if (cancel_button_) + ok_button_right = cancel_button_->x() - kRelatedButtonHSpacing; + int button_x = ok_button_right - button_width; + int button_y = lb.bottom() - ps.height() - kButtonVEdgeMargin; + ok_button_->SetBounds(button_x, button_y, ok_button_right - button_x, + ps.height()); + // The extra view bounds are dependent on this button. + extra_bounds.set_width(std::max(0, ok_button_->x())); + extra_bounds.set_y(ok_button_->y()); + } + if (extra_view_) { + gfx::Size ps = extra_view_->GetPreferredSize(); + gfx::Rect lb = GetLocalBounds(false); + extra_bounds.set_x(lb.x() + kButtonHEdgeMargin); + extra_bounds.set_height(ps.height()); + extra_view_->SetBounds(extra_bounds); + } +} + +void DialogClientView::LayoutContentsView() { + gfx::Rect lb = GetLocalBounds(false); + lb.set_height(std::max(0, lb.height() - GetButtonsHeight())); + contents_view()->SetBounds(lb); + contents_view()->Layout(); +} + +void DialogClientView::CreateExtraView() { + View* extra_view = GetDialogDelegate()->GetExtraView(); + if (extra_view && !extra_view_) { + extra_view_ = extra_view; + extra_view_->SetGroup(kButtonGroup); + AddChildView(extra_view_); + } +} + +DialogDelegate* DialogClientView::GetDialogDelegate() const { + DialogDelegate* dd = window()->GetDelegate()->AsDialogDelegate(); + DCHECK(dd); + return dd; +} + +// static +void DialogClientView::InitClass() { + static bool initialized = false; + if (!initialized) { + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + dialog_button_font_ = rb.GetFont(ResourceBundle::BaseFont); + initialized = true; + } +} + +} // namespace views diff --git a/chrome/views/window/dialog_client_view.h b/chrome/views/window/dialog_client_view.h new file mode 100644 index 0000000..0b4da5f --- /dev/null +++ b/chrome/views/window/dialog_client_view.h @@ -0,0 +1,122 @@ +// Copyright (c) 2006-2008 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_VIEWS_WINDOW_DIALOG_CLIENT_VIEW_H_ +#define CHROME_VIEWS_WINDOW_DIALOG_CLIENT_VIEW_H_ + +#include "chrome/common/gfx/chrome_font.h" +#include "chrome/views/focus_manager.h" +#include "chrome/views/native_button.h" +#include "chrome/views/window/client_view.h" + +namespace views { + +class DialogDelegate; +class Window; + +/////////////////////////////////////////////////////////////////////////////// +// DialogClientView +// +// This ClientView subclass provides the content of a typical dialog box, +// including a strip of buttons at the bottom right of the window, default +// accelerator handlers for accept and cancel, and the ability for the +// embedded contents view to provide extra UI to be shown in the row of +// buttons. +// +class DialogClientView : public ClientView, + public NativeButton::Listener, + public FocusChangeListener { + public: + DialogClientView(Window* window, View* contents_view); + virtual ~DialogClientView(); + + // Adds the dialog buttons required by the supplied WindowDelegate to the + // view. + void ShowDialogButtons(); + + // Updates the enabled state and label of the buttons required by the + // supplied WindowDelegate + void UpdateDialogButtons(); + + // Accept the changes made in the window that contains this ClientView. + void AcceptWindow(); + + // Cancel the changes made in the window that contains this ClientView. + void CancelWindow(); + + // Accessors in case the user wishes to adjust these buttons. + NativeButton* ok_button() const { return ok_button_; } + NativeButton* cancel_button() const { return cancel_button_; } + + // Overridden from ClientView: + virtual bool CanClose() const; + virtual void WindowClosing(); + virtual int NonClientHitTest(const gfx::Point& point); + virtual DialogClientView* AsDialogClientView() { return this; } + + // FocusChangeListener implementation: + virtual void FocusWillChange(View* focused_before, View* focused_now); + + protected: + // View overrides: + virtual void Paint(ChromeCanvas* canvas); + virtual void PaintChildren(ChromeCanvas* canvas); + virtual void Layout(); + virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); + virtual gfx::Size GetPreferredSize(); + virtual bool AcceleratorPressed(const Accelerator& accelerator); + + // NativeButton::Listener implementation: + virtual void ButtonPressed(NativeButton* sender); + + private: + // Paint the size box in the bottom right corner of the window if it is + // resizable. + void PaintSizeBox(ChromeCanvas* canvas); + + // Returns the width of the specified dialog button using the correct font. + int GetButtonWidth(int button) const; + int DialogClientView::GetButtonsHeight() const; + + // Position and size various sub-views. + void LayoutDialogButtons(); + void LayoutContentsView(); + + // Makes the specified button the default button. + void SetDefaultButton(NativeButton* button); + + bool has_dialog_buttons() const { return ok_button_ || cancel_button_; } + + // Create and add the extra view, if supplied by the delegate. + void CreateExtraView(); + + // Returns the DialogDelegate for the window. + DialogDelegate* GetDialogDelegate() const; + + // The dialog buttons. + NativeButton* ok_button_; + NativeButton* cancel_button_; + + // The button that is currently the default button if any. + NativeButton* default_button_; + + // The button-level extra view, NULL unless the dialog delegate supplies one. + View* extra_view_; + + // The layout rect of the size box, when visible. + gfx::Rect size_box_bounds_; + + // True if the window was Accepted by the user using the OK button. + bool accepted_; + + // Static resource initialization + static void InitClass(); + static ChromeFont dialog_button_font_; + + DISALLOW_EVIL_CONSTRUCTORS(DialogClientView); +}; + +} // namespace views + +#endif // #ifndef CHROME_VIEWS_WINDOW_DIALOG_CLIENT_VIEW_H_ diff --git a/chrome/views/window/dialog_delegate.cc b/chrome/views/window/dialog_delegate.cc new file mode 100644 index 0000000..8a1c671 --- /dev/null +++ b/chrome/views/window/dialog_delegate.cc @@ -0,0 +1,53 @@ +// Copyright (c) 2006-2008 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. + +#include "chrome/views/window/dialog_delegate.h" + +#include "base/logging.h" +#include "chrome/views/window/window.h" + +namespace views { + +// Overridden from WindowDelegate: + +int DialogDelegate::GetDefaultDialogButton() const { + if (GetDialogButtons() & DIALOGBUTTON_OK) + return DIALOGBUTTON_OK; + if (GetDialogButtons() & DIALOGBUTTON_CANCEL) + return DIALOGBUTTON_CANCEL; + return DIALOGBUTTON_NONE; +} + +View* DialogDelegate::GetInitiallyFocusedView() { + // Focus the default button if any. + DialogClientView* dcv = GetDialogClientView(); + int default_button = GetDefaultDialogButton(); + if (default_button == DIALOGBUTTON_NONE) + return NULL; + + if ((default_button & GetDialogButtons()) == 0) { + // The default button is a button we don't have. + NOTREACHED(); + return NULL; + } + + if (default_button & DIALOGBUTTON_OK) + return dcv->ok_button(); + if (default_button & DIALOGBUTTON_CANCEL) + return dcv->cancel_button(); + return NULL; +} + +ClientView* DialogDelegate::CreateClientView(Window* window) { + return new DialogClientView(window, GetContentsView()); +} + +DialogClientView* DialogDelegate::GetDialogClientView() const { + ClientView* client_view = window()->GetClientView(); + DialogClientView* dialog_client_view = client_view->AsDialogClientView(); + DCHECK(dialog_client_view); + return dialog_client_view; +} + +} // namespace views diff --git a/chrome/views/window/dialog_delegate.h b/chrome/views/window/dialog_delegate.h new file mode 100644 index 0000000..b8b2d1b --- /dev/null +++ b/chrome/views/window/dialog_delegate.h @@ -0,0 +1,111 @@ +// Copyright (c) 2006-2008 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_VIEWS_WINDOW_DIALOG_DELEGATE_H_ +#define CHROME_VIEWS_WINDOW_DIALOG_DELEGATE_H_ + +#include "chrome/views/window/dialog_client_view.h" +#include "chrome/views/window/window_delegate.h" + +namespace views { + +class View; + +/////////////////////////////////////////////////////////////////////////////// +// +// DialogDelegate +// +// DialogDelegate is an interface implemented by objects that wish to show a +// dialog box Window. The window that is displayed uses this interface to +// determine how it should be displayed and notify the delegate object of +// certain events. +// +/////////////////////////////////////////////////////////////////////////////// +class DialogDelegate : public WindowDelegate { + public: + virtual DialogDelegate* AsDialogDelegate() { return this; } + + enum DialogButton { + DIALOGBUTTON_NONE = 0, // No dialog buttons, for WindowType == WINDOW. + DIALOGBUTTON_OK = 1, // Has an OK button. + DIALOGBUTTON_CANCEL = 2, // Has a Cancel button (becomes a Close button if + }; // no OK button). + + // Returns a mask specifying which of the available DialogButtons are visible + // for the dialog. Note: If an OK button is provided, you should provide a + // CANCEL button. A dialog box with just an OK button is frowned upon and + // considered a very special case, so if you're planning on including one, + // you should reconsider, or beng says there will be stabbings. + // + // To use the extra button you need to override GetDialogButtons() + virtual int GetDialogButtons() const { + return DIALOGBUTTON_OK | DIALOGBUTTON_CANCEL; + } + + // Returns whether accelerators are enabled on the button. This is invoked + // when an accelerator is pressed, not at construction time. This + // returns true. + virtual bool AreAcceleratorsEnabled(DialogButton button) { return true; } + + // Returns the label of the specified DialogButton. + virtual std::wstring GetDialogButtonLabel(DialogButton button) const { + // empty string results in defaults for DIALOGBUTTON_OK, + // DIALOGBUTTON_CANCEL. + return L""; + } + + // Override this function if with a view which will be shown in the same + // row as the OK and CANCEL buttons but flush to the left and extending + // up to the buttons. + virtual View* GetExtraView() { return NULL; } + + // Returns the default dialog button. This should not be a mask as only one + // button should ever be the default button. Return DIALOGBUTTON_NONE if + // there is no default. Default behavior is to return DIALOGBUTTON_OK or + // DIALOGBUTTON_CANCEL (in that order) if they are present, DIALOGBUTTON_NONE + // otherwise. + virtual int GetDefaultDialogButton() const; + + // Returns whether the specified dialog button is enabled. + virtual bool IsDialogButtonEnabled(DialogButton button) const { + return true; + } + + // Returns whether the specified dialog button is visible. + virtual bool IsDialogButtonVisible(DialogButton button) const { + return true; + } + + // For Dialog boxes, if there is a "Cancel" button, this is called when the + // user presses the "Cancel" button or the Close button on the window or + // in the system menu, or presses the Esc key. This function should return + // true if the window can be closed after it returns, or false if it must + // remain open. + virtual bool Cancel() { return true; } + + // For Dialog boxes, this is called when the user presses the "OK" button, + // or the Enter key. Can also be called on Esc key or close button presses if + // there is no "Cancel" button. This function should return true if the window + // can be closed after the window can be closed after it returns, or false if + // it must remain open. If |window_closing| is true, it means that this + // handler is being called because the window is being closed (e.g. by + // Window::Close) and there is no Cancel handler, so Accept is being called + // instead. + virtual bool Accept(bool window_closing) { return Accept(); } + virtual bool Accept() { return true; } + + // Overridden from WindowDelegate: + virtual View* GetInitiallyFocusedView(); + + // Overridden from WindowDelegate: + virtual ClientView* CreateClientView(Window* window); + + // A helper for accessing the DialogClientView object contained by this + // delegate's Window. + DialogClientView* GetDialogClientView() const; +}; + +} // namespace views + +#endif // CHROME_VIEWS_WINDOW_DIALOG_DELEGATE_H_ diff --git a/chrome/views/window/native_frame_view.cc b/chrome/views/window/native_frame_view.cc new file mode 100644 index 0000000..4446f30 --- /dev/null +++ b/chrome/views/window/native_frame_view.cc @@ -0,0 +1,60 @@ +// 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. + +#include "chrome/views/window/native_frame_view.h" + +#include "chrome/views/window/window_win.h" + +namespace views { + +//////////////////////////////////////////////////////////////////////////////// +// NativeFrameView, public: + +NativeFrameView::NativeFrameView(WindowWin* frame) + : NonClientFrameView(), + frame_(frame) { +} + +NativeFrameView::~NativeFrameView() { +} + +//////////////////////////////////////////////////////////////////////////////// +// NativeFrameView, NonClientFrameView overrides: + +gfx::Rect NativeFrameView::GetBoundsForClientView() const { + return gfx::Rect(0, 0, width(), height()); +} + +gfx::Rect NativeFrameView::GetWindowBoundsForClientBounds( + const gfx::Rect& client_bounds) const { + RECT rect = client_bounds.ToRECT(); + AdjustWindowRectEx(&rect, frame_->window_style(), FALSE, + frame_->window_ex_style()); + return gfx::Rect(rect); +} + +gfx::Point NativeFrameView::GetSystemMenuPoint() const { + POINT temp = {0, -kFrameShadowThickness }; + MapWindowPoints(frame_->GetNativeView(), HWND_DESKTOP, &temp, 1); + return gfx::Point(temp); +} + +int NativeFrameView::NonClientHitTest(const gfx::Point& point) { + return HTNOWHERE; +} + +void NativeFrameView::GetWindowMask(const gfx::Size& size, + gfx::Path* window_mask) { + // Nothing to do, we use the default window mask. +} + +void NativeFrameView::EnableClose(bool enable) { + // Nothing to do, handled automatically by Window. +} + +void NativeFrameView::ResetWindowControls() { + // Nothing to do. +} + +} // namespace views diff --git a/chrome/views/window/native_frame_view.h b/chrome/views/window/native_frame_view.h new file mode 100644 index 0000000..336d7c4 --- /dev/null +++ b/chrome/views/window/native_frame_view.h @@ -0,0 +1,39 @@ +// 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_VIEWS_WINDOW_NATIVE_FRAME_VIEW_H_ +#define CHROME_VIEWS_WINDOW_NATIVE_FRAME_VIEW_H_ + +#include "chrome/views/window/non_client_view.h" + +namespace views { + +class WindowWin; + +class NativeFrameView : public NonClientFrameView { + public: + explicit NativeFrameView(WindowWin* frame); + virtual ~NativeFrameView(); + + // NonClientFrameView overrides: + virtual gfx::Rect GetBoundsForClientView() const; + virtual gfx::Rect GetWindowBoundsForClientBounds( + const gfx::Rect& client_bounds) const; + virtual gfx::Point GetSystemMenuPoint() const; + virtual int NonClientHitTest(const gfx::Point& point); + virtual void GetWindowMask(const gfx::Size& size, + gfx::Path* window_mask); + virtual void EnableClose(bool enable); + virtual void ResetWindowControls(); + + private: + // Our containing frame. + WindowWin* frame_; + + DISALLOW_COPY_AND_ASSIGN(NativeFrameView); +}; + +} // namespace views + +#endif // #ifndef CHROME_VIEWS_WINDOW_NATIVE_FRAME_VIEW_H_ diff --git a/chrome/views/window/non_client_view.cc b/chrome/views/window/non_client_view.cc new file mode 100644 index 0000000..327656b --- /dev/null +++ b/chrome/views/window/non_client_view.cc @@ -0,0 +1,244 @@ +// Copyright (c) 2006-2008 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. + +#include "chrome/views/window/non_client_view.h" + +#include "chrome/common/win_util.h" +#include "chrome/views/widget/root_view.h" +#include "chrome/views/widget/widget.h" +#include "chrome/views/window/window.h" + +namespace views { + +const int NonClientFrameView::kFrameShadowThickness = 1; +const int NonClientFrameView::kClientEdgeThickness = 1; + +// The frame view and the client view are always at these specific indices, +// because the RootView message dispatch sends messages to items higher in the +// z-order first and we always want the client view to have first crack at +// handling mouse messages. +static const int kFrameViewIndex = 0; +static const int kClientViewIndex = 1; + +//////////////////////////////////////////////////////////////////////////////// +// NonClientView, public: + +NonClientView::NonClientView(Window* frame) + : frame_(frame), + client_view_(NULL), + use_native_frame_(win_util::ShouldUseVistaFrame()) { +} + +NonClientView::~NonClientView() { + // This value may have been reset before the window hierarchy shuts down, + // so we need to manually remove it. + RemoveChildView(frame_view_.get()); +} + +void NonClientView::SetFrameView(NonClientFrameView* frame_view) { + // See comment in header about ownership. + frame_view->SetParentOwned(false); + if (frame_view_.get()) + RemoveChildView(frame_view_.get()); + frame_view_.reset(frame_view); + if (GetParent()) + AddChildView(kFrameViewIndex, frame_view_.get()); +} + +bool NonClientView::CanClose() const { + return client_view_->CanClose(); +} + +void NonClientView::WindowClosing() { + client_view_->WindowClosing(); +} + +void NonClientView::SetUseNativeFrame(bool use_native_frame) { + use_native_frame_ = use_native_frame; + SetFrameView(frame_->CreateFrameViewForWindow()); + GetRootView()->ThemeChanged(); + Layout(); + SchedulePaint(); + frame_->UpdateFrameAfterFrameChange(); +} + +bool NonClientView::UseNativeFrame() const { + // The frame view may always require a custom frame, e.g. Constrained Windows. + bool always_use_custom_frame = + frame_view_.get() && frame_view_->AlwaysUseCustomFrame(); + return !always_use_custom_frame && use_native_frame_; +} + +void NonClientView::DisableInactiveRendering(bool disable) { + frame_view_->DisableInactiveRendering(disable); +} + +gfx::Rect NonClientView::GetWindowBoundsForClientBounds( + const gfx::Rect client_bounds) const { + return frame_view_->GetWindowBoundsForClientBounds(client_bounds); +} + +gfx::Point NonClientView::GetSystemMenuPoint() const { + return frame_view_->GetSystemMenuPoint(); +} + +int NonClientView::NonClientHitTest(const gfx::Point& point) { + // Sanity check. + if (!bounds().Contains(point)) + return HTNOWHERE; + + // The ClientView gets first crack, since it overlays the NonClientFrameView + // in the display stack. + int frame_component = client_view_->NonClientHitTest(point); + if (frame_component != HTNOWHERE) + return frame_component; + + // Finally ask the NonClientFrameView. It's at the back of the display stack + // so it gets asked last. + return frame_view_->NonClientHitTest(point); +} + +void NonClientView::GetWindowMask(const gfx::Size& size, + gfx::Path* window_mask) { + frame_view_->GetWindowMask(size, window_mask); +} + +void NonClientView::EnableClose(bool enable) { + frame_view_->EnableClose(enable); +} + +void NonClientView::ResetWindowControls() { + frame_view_->ResetWindowControls(); +} + +//////////////////////////////////////////////////////////////////////////////// +// NonClientView, View overrides: + +gfx::Size NonClientView::GetPreferredSize() { + gfx::Rect client_bounds(gfx::Point(), client_view_->GetPreferredSize()); + return GetWindowBoundsForClientBounds(client_bounds).size(); +} + +void NonClientView::Layout() { + // First layout the NonClientFrameView, which determines the size of the + // ClientView... + frame_view_->SetBounds(0, 0, width(), height()); + + // We need to manually call Layout here because layout for the frame view can + // change independently of the bounds changing - e.g. after the initial + // display of the window the metrics of the native window controls can change, + // which does not change the bounds of the window but requires a re-layout to + // trigger a repaint. We override DidChangeBounds for the NonClientFrameView + // to do nothing so that SetBounds above doesn't cause Layout to be called + // twice. + frame_view_->Layout(); + + // Then layout the ClientView, using those bounds. + client_view_->SetBounds(frame_view_->GetBoundsForClientView()); + + // We need to manually call Layout on the ClientView as well for the same + // reason as above. + client_view_->Layout(); +} + +void NonClientView::ViewHierarchyChanged(bool is_add, View* parent, + View* child) { + // Add our two child views here as we are added to the Widget so that if we + // are subsequently resized all the parent-child relationships are + // established. + if (is_add && GetWidget() && child == this) { + AddChildView(kFrameViewIndex, frame_view_.get()); + AddChildView(kClientViewIndex, client_view_); + } +} + +views::View* NonClientView::GetViewForPoint(const gfx::Point& point) { + return GetViewForPoint(point, false); +} + +views::View* NonClientView::GetViewForPoint(const gfx::Point& point, + bool can_create_floating) { + // Because of the z-ordering of our child views (the client view is positioned + // over the non-client frame view, if the client view ever overlaps the frame + // view visually (as it does for the browser window), then it will eat mouse + // events for the window controls. We override this method here so that we can + // detect this condition and re-route the events to the non-client frame view. + // The assumption is that the frame view's implementation of HitTest will only + // return true for area not occupied by the client view. + gfx::Point point_in_child_coords(point); + View::ConvertPointToView(this, frame_view_.get(), &point_in_child_coords); + if (frame_view_->HitTest(point_in_child_coords)) + return frame_view_->GetViewForPoint(point); + + return View::GetViewForPoint(point, can_create_floating); +} + +//////////////////////////////////////////////////////////////////////////////// +// NonClientFrameView, View overrides: + +bool NonClientFrameView::HitTest(const gfx::Point& l) const { + // For the default case, we assume the non-client frame view never overlaps + // the client view. + return !GetWidget()->AsWindow()->GetClientView()->bounds().Contains(l); +} + +void NonClientFrameView::DidChangeBounds(const gfx::Rect& previous, + const gfx::Rect& current) { + // Overridden to do nothing. The NonClientView manually calls Layout on the + // FrameView when it is itself laid out, see comment in NonClientView::Layout. +} + +//////////////////////////////////////////////////////////////////////////////// +// NonClientFrameView, protected: + +int NonClientFrameView::GetHTComponentForFrame(const gfx::Point& point, + int top_resize_border_height, + int resize_border_thickness, + int top_resize_corner_height, + int resize_corner_width, + bool can_resize) { + // Tricky: In XP, native behavior is to return HTTOPLEFT and HTTOPRIGHT for + // a |resize_corner_size|-length strip of both the side and top borders, but + // only to return HTBOTTOMLEFT/HTBOTTOMRIGHT along the bottom border + corner + // (not the side border). Vista goes further and doesn't return these on any + // of the side borders. We allow callers to match either behavior. + int component; + if (point.x() < resize_border_thickness) { + if (point.y() < top_resize_corner_height) + component = HTTOPLEFT; + else if (point.y() >= (height() - resize_border_thickness)) + component = HTBOTTOMLEFT; + else + component = HTLEFT; + } else if (point.x() >= (width() - resize_border_thickness)) { + if (point.y() < top_resize_corner_height) + component = HTTOPRIGHT; + else if (point.y() >= (height() - resize_border_thickness)) + component = HTBOTTOMRIGHT; + else + component = HTRIGHT; + } else if (point.y() < top_resize_border_height) { + if (point.x() < resize_corner_width) + component = HTTOPLEFT; + else if (point.x() >= (width() - resize_corner_width)) + component = HTTOPRIGHT; + else + component = HTTOP; + } else if (point.y() >= (height() - resize_border_thickness)) { + if (point.x() < resize_corner_width) + component = HTBOTTOMLEFT; + else if (point.x() >= (width() - resize_corner_width)) + component = HTBOTTOMRIGHT; + else + component = HTBOTTOM; + } else { + return HTNOWHERE; + } + + // If the window can't be resized, there are no resize boundaries, just + // window borders. + return can_resize ? component : HTBORDER; +} + +} // namespace views diff --git a/chrome/views/window/non_client_view.h b/chrome/views/window/non_client_view.h new file mode 100644 index 0000000..45a089f --- /dev/null +++ b/chrome/views/window/non_client_view.h @@ -0,0 +1,221 @@ +// Copyright (c) 2006-2008 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_VIEWS_WINDOW_NON_CLIENT_VIEW_H_ +#define CHROME_VIEWS_WINDOW_NON_CLIENT_VIEW_H_ + +#include "base/task.h" +#include "chrome/views/view.h" +#include "chrome/views/window/client_view.h" + +namespace gfx { +class Path; +} + +namespace views { + +//////////////////////////////////////////////////////////////////////////////// +// NonClientFrameView +// +// An object that subclasses NonClientFrameView is a View that renders and +// responds to events within the frame portions of the non-client area of a +// window. This view does _not_ contain the ClientView, but rather is a sibling +// of it. +class NonClientFrameView : public View { + public: + // Various edges of the frame border have a 1 px shadow along their edges; in + // a few cases we shift elements based on this amount for visual appeal. + static const int kFrameShadowThickness; + // In restored mode, we draw a 1 px edge around the content area inside the + // frame border. + static const int kClientEdgeThickness; + + void DisableInactiveRendering(bool disable) { + paint_as_active_ = disable; + if (!paint_as_active_) + SchedulePaint(); + } + + // Returns the bounds (in this View's parent's coordinates) that the client + // view should be laid out within. + virtual gfx::Rect GetBoundsForClientView() const = 0; + + // Returns true if this FrameView should always use the custom frame, + // regardless of the system settings. An example is the Constrained Window, + // which is a child window and must always provide its own frame. + virtual bool AlwaysUseCustomFrame() const { return false; } + + virtual gfx::Rect GetWindowBoundsForClientBounds( + const gfx::Rect& client_bounds) const = 0; + virtual gfx::Point GetSystemMenuPoint() const = 0; + virtual int NonClientHitTest(const gfx::Point& point) = 0; + virtual void GetWindowMask(const gfx::Size& size, + gfx::Path* window_mask) = 0; + virtual void EnableClose(bool enable) = 0; + virtual void ResetWindowControls() = 0; + + // Overridden from View: + virtual bool HitTest(const gfx::Point& l) const; + + protected: + virtual void DidChangeBounds(const gfx::Rect& previous, + const gfx::Rect& current); + + NonClientFrameView() : paint_as_active_(false) {} + + + // Helper for non-client view implementations to determine which area of the + // window border the specified |point| falls within. The other parameters are + // the size of the sizing edges, and whether or not the window can be + // resized. + int GetHTComponentForFrame(const gfx::Point& point, + int top_resize_border_height, + int resize_border_thickness, + int top_resize_corner_height, + int resize_corner_width, + bool can_resize); + + // Accessor for paint_as_active_. + bool paint_as_active() const { return paint_as_active_; } + + private: + // True when the non-client view should always be rendered as if the window + // were active, regardless of whether or not the top level window actually + // is active. + bool paint_as_active_; +}; + +//////////////////////////////////////////////////////////////////////////////// +// NonClientView +// +// The NonClientView is the logical root of all Views contained within a +// Window, except for the RootView which is its parent and of which it is the +// sole child. The NonClientView has two children, the NonClientFrameView which +// is responsible for painting and responding to events from the non-client +// portions of the window, and the ClientView, which is responsible for the +// same for the client area of the window: +// +// +- views::Window ------------------------------------+ +// | +- views::RootView ------------------------------+ | +// | | +- views::NonClientView ---------------------+ | | +// | | | +- views::NonClientView subclass ---+ | | | +// | | | | | | | | +// | | | | << all painting and event receiving >> | | | | +// | | | | << of the non-client areas of a >> | | | | +// | | | | << views::Window. >> | | | | +// | | | | | | | | +// | | | +----------------------------------------+ | | | +// | | | +- views::ClientView or subclass --------+ | | | +// | | | | | | | | +// | | | | << all painting and event receiving >> | | | | +// | | | | << of the client areas of a >> | | | | +// | | | | << views::Window. >> | | | | +// | | | | | | | | +// | | | +----------------------------------------+ | | | +// | | +--------------------------------------------+ | | +// | +------------------------------------------------+ | +// +----------------------------------------------------+ +// +// The NonClientFrameView and ClientView are siblings because due to theme +// changes the NonClientFrameView may be replaced with different +// implementations (e.g. during the switch from DWM/Aero-Glass to Vista Basic/ +// Classic rendering). +// +class NonClientView : public View { + public: + explicit NonClientView(Window* frame); + virtual ~NonClientView(); + + // Replaces the current NonClientFrameView (if any) with the specified one. + void SetFrameView(NonClientFrameView* frame_view); + + // Returns true if the ClientView determines that the containing window can be + // closed, false otherwise. + bool CanClose() const; + + // Called by the containing Window when it is closed. + void WindowClosing(); + + // Changes the frame from native to custom depending on the value of + // |use_native_frame|. + void SetUseNativeFrame(bool use_native_frame); + + // Returns true if the native window frame should be used, false if the + // NonClientView provides its own frame implementation. + bool UseNativeFrame() const; + + // Prevents the window from being rendered as deactivated when |disable| is + // true, until called with |disable| false. Used when a sub-window is to be + // shown that shouldn't visually de-activate the window. + // Subclasses can override this to perform additional actions when this value + // changes. + void DisableInactiveRendering(bool disable); + + // Returns the bounds of the window required to display the content area at + // the specified bounds. + gfx::Rect GetWindowBoundsForClientBounds(const gfx::Rect client_bounds) const; + + // Returns the point, in screen coordinates, where the system menu should + // be shown so it shows up anchored to the system menu icon. + gfx::Point GetSystemMenuPoint() const; + + // Determines the windows HT* code when the mouse cursor is at the + // specified point, in window coordinates. + int NonClientHitTest(const gfx::Point& point); + + // Returns a mask to be used to clip the top level window for the given + // size. This is used to create the non-rectangular window shape. + void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask); + + // Toggles the enable state for the Close button (and the Close menu item in + // the system menu). + void EnableClose(bool enable); + + // Tells the window controls as rendered by the NonClientView to reset + // themselves to a normal state. This happens in situations where the + // containing window does not receive a normal sequences of messages that + // would lead to the controls returning to this normal state naturally, e.g. + // when the window is maximized, minimized or restored. + void ResetWindowControls(); + + // Get/Set client_view property. + ClientView* client_view() const { return client_view_; } + void set_client_view(ClientView* client_view) { + client_view_ = client_view; + } + + // NonClientView, View overrides: + virtual gfx::Size GetPreferredSize(); + virtual void Layout(); + + protected: + // NonClientView, View overrides: + virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); + virtual views::View* GetViewForPoint(const gfx::Point& point); + virtual views::View* GetViewForPoint(const gfx::Point& point, + bool can_create_floating); + + private: + // The frame that hosts this NonClientView. + Window* frame_; + + // A ClientView object or subclass, responsible for sizing the contents view + // of the window, hit testing and perhaps other tasks depending on the + // implementation. + ClientView* client_view_; + + // The NonClientFrameView that renders the non-client portions of the window. + // This object is not owned by the view hierarchy because it can be replaced + // dynamically as the system settings change. + scoped_ptr frame_view_; + + // Whether or not we should use the native frame. + bool use_native_frame_; + + DISALLOW_COPY_AND_ASSIGN(NonClientView); +}; + +} // namespace views + +#endif // #ifndef CHROME_VIEWS_WINDOW_NON_CLIENT_VIEW_H_ diff --git a/chrome/views/window/window.h b/chrome/views/window/window.h new file mode 100644 index 0000000..48c1ad8 --- /dev/null +++ b/chrome/views/window/window.h @@ -0,0 +1,118 @@ +// 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_VIEWS_WINDOW_WINDOW_H_ +#define CHROME_VIEWS_WINDOW_WINDOW_H_ + +#include "base/gfx/native_widget_types.h" + +namespace gfx { +class Rect; +class Size; +} + +namespace views { + +class ClientView; +class NonClientFrameView; +class NonClientView; +class WindowDelegate; + +// An interface implemented by an object that provides a top level window. +class Window { + public: + virtual ~Window() {} + + // Creates an instance of an object implementing this interface. + static Window* CreateChromeWindow(gfx::NativeWindow parent, + const gfx::Rect& bounds, + WindowDelegate* window_delegate); + + // Returns the preferred size of the contents view of this window based on + // its localized size data. The width in cols is held in a localized string + // resource identified by |col_resource_id|, the height in the same fashion. + // TODO(beng): This should eventually live somewhere else, probably closer to + // ClientView. + static int GetLocalizedContentsWidth(int col_resource_id); + static int GetLocalizedContentsHeight(int row_resource_id); + static gfx::Size GetLocalizedContentsSize(int col_resource_id, + int row_resource_id); + + // Retrieves the window's bounds, including its frame. + virtual gfx::Rect GetBounds() const = 0; + + // Sizes and/or places the window to the specified bounds, size or position. + virtual void SetBounds(const gfx::Rect& bounds) = 0; + + // As above, except the window is inserted after |other_window| in the window + // Z-order. If this window is not yet visible, other_window's monitor is used + // as the constraining rectangle, rather than this window's monitor. + virtual void SetBounds(const gfx::Rect& bounds, + gfx::NativeWindow other_window) = 0; + + // Makes the window visible. + virtual void Show() = 0; + + // Activate the window, assuming it already exists and is visible. + virtual void Activate() = 0; + + // Closes the window, ultimately destroying it. This isn't immediate (it + // occurs after a return to the message loop. Implementors must also make sure + // that invoking Close multiple times doesn't cause bad things to happen, + // since it can happen. + virtual void Close() = 0; + + // Maximizes/minimizes/restores the window. + virtual void Maximize() = 0; + virtual void Minimize() = 0; + virtual void Restore() = 0; + + // Whether or not the window is currently active. + virtual bool IsActive() const = 0; + + // Whether or not the window is currently visible. + virtual bool IsVisible() const = 0; + + // Whether or not the window is maximized or minimized. + virtual bool IsMaximized() const = 0; + virtual bool IsMinimized() const = 0; + + // Toggles the enable state for the Close button (and the Close menu item in + // the system menu). + virtual void EnableClose(bool enable) = 0; + + // Prevents the window from being rendered as deactivated the next time it is. + // This state is reset automatically as soon as the window becomes activated + // again. There is no ability to control the state through this API as this + // leads to sync problems. + virtual void DisableInactiveRendering() = 0; + + // Tell the window to update its title from the delegate. + virtual void UpdateWindowTitle() = 0; + + // Tell the window to update its icon from the delegate. + virtual void UpdateWindowIcon() = 0; + + // Creates an appropriate NonClientFrameView for this window. + virtual NonClientFrameView* CreateFrameViewForWindow() = 0; + + // Updates the frame after an event caused it to be changed. + virtual void UpdateFrameAfterFrameChange() = 0; + + // Retrieves the Window's delegate. + virtual WindowDelegate* GetDelegate() const = 0; + + // Retrieves the Window's non-client view. + virtual NonClientView* GetNonClientView() const = 0; + + // Retrieves the Window's client view. + virtual ClientView* GetClientView() const = 0; + + // Retrieves the Window's native window handle. + virtual gfx::NativeWindow GetNativeWindow() const = 0; +}; + +} // namespace views + +#endif // #ifndef CHROME_VIEWS_WINDOW_WINDOW_H_ diff --git a/chrome/views/window/window_delegate.cc b/chrome/views/window/window_delegate.cc new file mode 100644 index 0000000..917836f --- /dev/null +++ b/chrome/views/window/window_delegate.cc @@ -0,0 +1,96 @@ +// Copyright (c) 2006-2008 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. + +#include "chrome/views/window/window_delegate.h" + +// TODO(beng): hrmp. Fix this in http://crbug.com/4406 +#include "chrome/browser/browser_process.h" +#include "chrome/common/pref_service.h" +#include "chrome/views/window/client_view.h" +#include "chrome/views/window/window.h" +#include "skia/include/SkBitmap.h" + +namespace views { + +WindowDelegate::WindowDelegate() { +} + +WindowDelegate::~WindowDelegate() { + ReleaseWindow(); +} + +// Returns the icon to be displayed in the window. +SkBitmap WindowDelegate::GetWindowIcon() { + return SkBitmap(); +} + +void WindowDelegate::SaveWindowPlacement(const gfx::Rect& bounds, + bool maximized, + bool always_on_top) { + std::wstring window_name = GetWindowName(); + if (window_name.empty() || !g_browser_process->local_state()) + return; + + DictionaryValue* window_preferences = + g_browser_process->local_state()->GetMutableDictionary( + window_name.c_str()); + window_preferences->SetInteger(L"left", bounds.x()); + window_preferences->SetInteger(L"top", bounds.y()); + window_preferences->SetInteger(L"right", bounds.right()); + window_preferences->SetInteger(L"bottom", bounds.bottom()); + window_preferences->SetBoolean(L"maximized", maximized); + window_preferences->SetBoolean(L"always_on_top", always_on_top); +} + +bool WindowDelegate::GetSavedWindowBounds(gfx::Rect* bounds) const { + std::wstring window_name = GetWindowName(); + if (window_name.empty()) + return false; + + const DictionaryValue* dictionary = + g_browser_process->local_state()->GetDictionary(window_name.c_str()); + int left, top, right, bottom; + if (!dictionary || !dictionary->GetInteger(L"left", &left) || + !dictionary->GetInteger(L"top", &top) || + !dictionary->GetInteger(L"right", &right) || + !dictionary->GetInteger(L"bottom", &bottom)) + return false; + + bounds->SetRect(left, top, right - left, bottom - top); + return true; +} + +bool WindowDelegate::GetSavedMaximizedState(bool* maximized) const { + std::wstring window_name = GetWindowName(); + if (window_name.empty()) + return false; + + const DictionaryValue* dictionary = + g_browser_process->local_state()->GetDictionary(window_name.c_str()); + return dictionary && dictionary->GetBoolean(L"maximized", maximized); +} + +bool WindowDelegate::GetSavedAlwaysOnTopState(bool* always_on_top) const { + if (!g_browser_process->local_state()) + return false; + + std::wstring window_name = GetWindowName(); + if (window_name.empty()) + return false; + + const DictionaryValue* dictionary = + g_browser_process->local_state()->GetDictionary(window_name.c_str()); + return dictionary && dictionary->GetBoolean(L"always_on_top", always_on_top); +} + + +ClientView* WindowDelegate::CreateClientView(Window* window) { + return new ClientView(window, GetContentsView()); +} + +void WindowDelegate::ReleaseWindow() { + window_.release(); +} + +} // namespace views diff --git a/chrome/views/window/window_delegate.h b/chrome/views/window/window_delegate.h new file mode 100644 index 0000000..52dd86a8 --- /dev/null +++ b/chrome/views/window/window_delegate.h @@ -0,0 +1,162 @@ +// Copyright (c) 2006-2008 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_VIEWS_WINDOW_WINDOW_DELEGATE_H_ +#define CHROME_VIEWS_WINDOW_WINDOW_DELEGATE_H_ + +#include + +#include "base/scoped_ptr.h" + +class SkBitmap; + +namespace gfx { +class Rect; +} +// TODO(maruel): Remove once gfx::Rect is used instead. +namespace WTL { +class CRect; +} +using WTL::CRect; + +namespace views { + +class ClientView; +class DialogDelegate; +class View; +class Window; + +/////////////////////////////////////////////////////////////////////////////// +// +// WindowDelegate +// +// WindowDelegate is an interface implemented by objects that wish to show a +// Window. The window that is displayed uses this interface to determine how +// it should be displayed and notify the delegate object of certain events. +// +/////////////////////////////////////////////////////////////////////////////// +class WindowDelegate { + public: + WindowDelegate(); + virtual ~WindowDelegate(); + + virtual DialogDelegate* AsDialogDelegate() { return NULL; } + + // Returns true if the window can ever be resized. + virtual bool CanResize() const { + return false; + } + + // Returns true if the window can ever be maximized. + virtual bool CanMaximize() const { + return false; + } + + // Returns true if the window should be placed on top of all other windows on + // the system, even when it is not active. If HasAlwaysOnTopMenu() returns + // true, then this method is only used the first time the window is opened, it + // is stored in the preferences for next runs. + virtual bool IsAlwaysOnTop() const { + return false; + } + + // Returns whether an "always on top" menu should be added to the system menu + // of the window. + virtual bool HasAlwaysOnTopMenu() const { + return false; + } + + // Returns true if the dialog should be displayed modally to the window that + // opened it. Only windows with WindowType == DIALOG can be modal. + virtual bool IsModal() const { + return false; + } + + // Returns the text to be displayed in the window title. + virtual std::wstring GetWindowTitle() const { + return L""; + } + + // Returns the view that should have the focus when the dialog is opened. If + // NULL no view is focused. + virtual View* GetInitiallyFocusedView() { return NULL; } + + // Returns true if the window should show a title in the title bar. + virtual bool ShouldShowWindowTitle() const { + return true; + } + + // Returns the icon to be displayed in the window. + virtual SkBitmap GetWindowIcon(); + + // Returns true if a window icon should be shown. + virtual bool ShouldShowWindowIcon() const { + return false; + } + + // Execute a command in the window's controller. Returns true if the command + // was handled, false if it was not. + virtual bool ExecuteWindowsCommand(int command_id) { return false; } + + // Returns the window's name identifier. Used to identify this window for + // state restoration. + virtual std::wstring GetWindowName() const { + return std::wstring(); + } + + // Saves the window's bounds, maximized and always-on-top states. By default + // this uses the process' local state keyed by window name (See GetWindowName + // above). This behavior can be overridden to provide additional + // functionality. + virtual void SaveWindowPlacement(const gfx::Rect& bounds, + bool maximized, + bool always_on_top); + + // Retrieves the window's bounds, maximized and always-on-top states. By + // default, this uses the process' local state keyed by window name (See + // GetWindowName above). This behavior can be overridden to provide + // additional functionality. + virtual bool GetSavedWindowBounds(gfx::Rect* bounds) const; + virtual bool GetSavedMaximizedState(bool* maximized) const; + virtual bool GetSavedAlwaysOnTopState(bool* always_on_top) const; + + // Called when the window closes. + virtual void WindowClosing() { } + + // Called when the window is destroyed. No events must be sent or received + // after this point. The delegate can use this opportunity to delete itself at + // this time if necessary. + virtual void DeleteDelegate() { } + + // Returns the View that is contained within this Window. + virtual View* GetContentsView() { + return NULL; + } + + // Called by the Window to create the Client View used to host the contents + // of the window. + virtual ClientView* CreateClientView(Window* window); + + // An accessor to the Window this delegate is bound to. + Window* window() const { return window_.get(); } + + protected: + // Releases the Window* we maintain. This should be done by a delegate in its + // WindowClosing handler if it intends to be re-cycled to be used on a + // different Window. + void ReleaseWindow(); + + private: + friend class WindowWin; + // 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 window_; +}; + +} // namespace views + +#endif // CHROME_VIEWS_WINDOW_WINDOW_DELEGATE_H_ diff --git a/chrome/views/window/window_resources.h b/chrome/views/window/window_resources.h new file mode 100644 index 0000000..9db078e --- /dev/null +++ b/chrome/views/window/window_resources.h @@ -0,0 +1,30 @@ +// Copyright (c) 2006-2008 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_VIEWS_WINDOW_WINDOW_RESOURCES_H_ +#define CHROME_VIEWS_WINDOW_WINDOW_RESOURCES_H_ + +class SkBitmap; + +namespace views { + +typedef int FramePartBitmap; + +/////////////////////////////////////////////////////////////////////////////// +// WindowResources +// +// An interface implemented by an object providing bitmaps to render the +// contents of a window frame. The Window may swap in different +// implementations of this interface to render different modes. The definition +// of FramePartBitmap depends on the implementation. +// +class WindowResources { + public: + virtual ~WindowResources() { } + virtual SkBitmap* GetPartBitmap(FramePartBitmap part) const = 0; +}; + +} // namespace views + +#endif // CHROME_VIEWS_WINDOW_WINDOW_RESOURCES_H_ diff --git a/chrome/views/window/window_win.cc b/chrome/views/window/window_win.cc new file mode 100644 index 0000000..7d2fc9a --- /dev/null +++ b/chrome/views/window/window_win.cc @@ -0,0 +1,1234 @@ +// Copyright (c) 2006-2008 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. + +#include "chrome/views/window/window_win.h" + +#include + +#include "base/win_util.h" +#include "chrome/app/chrome_dll_resource.h" +#include "chrome/common/gfx/chrome_canvas.h" +#include "chrome/common/gfx/chrome_font.h" +#include "chrome/common/gfx/icon_util.h" +#include "chrome/common/gfx/path.h" +#include "chrome/common/l10n_util.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/pref_service.h" +#include "chrome/common/resource_bundle.h" +#include "chrome/common/win_util.h" +#include "chrome/views/widget/root_view.h" +#include "chrome/views/window/client_view.h" +#include "chrome/views/window/custom_frame_view.h" +#include "chrome/views/window/native_frame_view.h" +#include "chrome/views/window/non_client_view.h" +#include "chrome/views/window/window_delegate.h" +#include "grit/generated_resources.h" + +namespace views { + +// A scoping class that prevents a window from being able to redraw in response +// to invalidations that may occur within it for the lifetime of the object. +// +// Why would we want such a thing? Well, it turns out Windows has some +// "unorthodox" behavior when it comes to painting its non-client areas. +// Occasionally, Windows will paint portions of the default non-client area +// right over the top of the custom frame. This is not simply fixed by handling +// WM_NCPAINT/WM_PAINT, with some investigation it turns out that this +// rendering is being done *inside* the default implementation of some message +// handlers and functions: +// . WM_SETTEXT +// . WM_SETICON +// . WM_NCLBUTTONDOWN +// . EnableMenuItem, called from our WM_INITMENU handler +// The solution is to handle these messages and call DefWindowProc ourselves, +// but prevent the window from being able to update itself for the duration of +// the call. We do this with this class, which automatically calls its +// associated Window's lock and unlock functions as it is created and destroyed. +// See documentation in those methods for the technique used. +// +// IMPORTANT: Do not use this scoping object for large scopes or periods of +// time! IT WILL PREVENT THE WINDOW FROM BEING REDRAWN! (duh). +// +// I would love to hear Raymond Chen's explanation for all this. And maybe a +// list of other messages that this applies to ;-) +class WindowWin::ScopedRedrawLock { + public: + explicit ScopedRedrawLock(WindowWin* window) : window_(window) { + window_->LockUpdates(); + } + + ~ScopedRedrawLock() { + window_->UnlockUpdates(); + } + + private: + // The window having its style changed. + WindowWin* window_; +}; + +HCURSOR WindowWin::resize_cursors_[6]; + +// If the hung renderer warning doesn't fit on screen, the amount of padding to +// be left between the edge of the window and the edge of the nearest monitor, +// after the window is nudged back on screen. Pixels. +static const int kMonitorEdgePadding = 10; + +//////////////////////////////////////////////////////////////////////////////// +// WindowWin, public: + +WindowWin::~WindowWin() { +} + +// static +Window* Window::CreateChromeWindow(gfx::NativeWindow parent, + const gfx::Rect& bounds, + WindowDelegate* window_delegate) { + WindowWin* window = new WindowWin(window_delegate); + window->GetNonClientView()->SetFrameView(window->CreateFrameViewForWindow()); + window->Init(parent, bounds); + return window; +} + +gfx::Rect WindowWin::GetBounds() const { + gfx::Rect bounds; + WidgetWin::GetBounds(&bounds, true); + return bounds; +} + +void WindowWin::SetBounds(const gfx::Rect& bounds) { + SetBounds(bounds, NULL); +} + +void WindowWin::SetBounds(const gfx::Rect& bounds, + gfx::NativeWindow other_window) { + win_util::SetChildBounds(GetNativeView(), GetParent(), other_window, bounds, + kMonitorEdgePadding, 0); +} + +void WindowWin::Show(int show_state) { + ShowWindow(show_state); + // When launched from certain programs like bash and Windows Live Messenger, + // show_state is set to SW_HIDE, so we need to correct that condition. We + // don't just change show_state to SW_SHOWNORMAL because MSDN says we must + // always first call ShowWindow with the specified value from STARTUPINFO, + // otherwise all future ShowWindow calls will be ignored (!!#@@#!). Instead, + // we call ShowWindow again in this case. + if (show_state == SW_HIDE) { + show_state = SW_SHOWNORMAL; + ShowWindow(show_state); + } + + // We need to explicitly activate the window if we've been shown with a state + // that should activate, because if we're opened from a desktop shortcut while + // an existing window is already running it doesn't seem to be enough to use + // one of these flags to activate the window. + if (show_state == SW_SHOWNORMAL) + Activate(); + + SetInitialFocus(); +} + +int WindowWin::GetShowState() const { + return SW_SHOWNORMAL; +} + +void WindowWin::ExecuteSystemMenuCommand(int command) { + if (command) + SendMessage(GetNativeView(), WM_SYSCOMMAND, command, 0); +} + +// static +int Window::GetLocalizedContentsWidth(int col_resource_id) { + double chars = _wtof(l10n_util::GetString(col_resource_id).c_str()); + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + ChromeFont font = rb.GetFont(ResourceBundle::BaseFont); + int width = font.GetExpectedTextWidth(static_cast(chars)); + DCHECK(width > 0); + return width; +} + +// static +int Window::GetLocalizedContentsHeight(int row_resource_id) { + double lines = _wtof(l10n_util::GetString(row_resource_id).c_str()); + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + ChromeFont font = rb.GetFont(ResourceBundle::BaseFont); + int height = static_cast(font.height() * lines); + DCHECK(height > 0); + return height; +} + +// static +gfx::Size Window::GetLocalizedContentsSize(int col_resource_id, + int row_resource_id) { + return gfx::Size(GetLocalizedContentsWidth(col_resource_id), + GetLocalizedContentsHeight(row_resource_id)); +} + +//////////////////////////////////////////////////////////////////////////////// +// WindowWin, Window implementation: + +void WindowWin::Show() { + int show_state = GetShowState(); + if (saved_maximized_state_) + show_state = SW_SHOWMAXIMIZED; + Show(show_state); +} + +void WindowWin::Activate() { + if (IsMinimized()) + ::ShowWindow(GetNativeView(), SW_RESTORE); + ::SetWindowPos(GetNativeView(), HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + SetForegroundWindow(GetNativeView()); +} + +void WindowWin::Close() { + if (window_closed_) { + // It appears we can hit this code path if you close a modal dialog then + // close the last browser before the destructor is hit, which triggers + // invoking Close again. I'm short circuiting this code path to avoid + // calling into the delegate twice, which is problematic. + return; + } + + if (non_client_view_->CanClose()) { + SaveWindowPosition(); + RestoreEnabledIfNecessary(); + WidgetWin::Close(); + // If the user activates another app after opening us, then comes back and + // closes us, we want our owner to gain activation. But only if the owner + // is visible. If we don't manually force that here, the other app will + // regain activation instead. + if (owning_hwnd_ && GetNativeView() == GetForegroundWindow() && + IsWindowVisible(owning_hwnd_)) { + SetForegroundWindow(owning_hwnd_); + } + window_closed_ = true; + } +} + +void WindowWin::Maximize() { + ExecuteSystemMenuCommand(SC_MAXIMIZE); +} + +void WindowWin::Minimize() { + ExecuteSystemMenuCommand(SC_MINIMIZE); +} + +void WindowWin::Restore() { + ExecuteSystemMenuCommand(SC_RESTORE); +} + +bool WindowWin::IsActive() const { + return is_active_; +} + +bool WindowWin::IsVisible() const { + return !!::IsWindowVisible(GetNativeView()); +} + +bool WindowWin::IsMaximized() const { + return !!::IsZoomed(GetNativeView()); +} + +bool WindowWin::IsMinimized() const { + return !!::IsIconic(GetNativeView()); +} + +void WindowWin::EnableClose(bool enable) { + // If the native frame is rendering its own close button, ask it to disable. + non_client_view_->EnableClose(enable); + + // Disable the native frame's close button regardless of whether or not the + // native frame is in use, since this also affects the system menu. + EnableMenuItem(GetSystemMenu(GetNativeView(), false), + SC_CLOSE, enable ? MF_ENABLED : MF_GRAYED); + + // Let the window know the frame changed. + SetWindowPos(NULL, 0, 0, 0, 0, + SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS | + SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION | + SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER); +} + +void WindowWin::DisableInactiveRendering() { + disable_inactive_rendering_ = true; + non_client_view_->DisableInactiveRendering(disable_inactive_rendering_); +} + +void WindowWin::UpdateWindowTitle() { + // If the non-client view is rendering its own title, it'll need to relayout + // now. + non_client_view_->Layout(); + + // Update the native frame's text. We do this regardless of whether or not + // the native frame is being used, since this also updates the taskbar, etc. + std::wstring window_title = window_delegate_->GetWindowTitle(); + std::wstring localized_text; + if (l10n_util::AdjustStringForLocaleDirection(window_title, &localized_text)) + window_title.assign(localized_text); + SetWindowText(GetNativeView(), window_title.c_str()); +} + +void WindowWin::UpdateWindowIcon() { + // If the non-client view is rendering its own icon, we need to tell it to + // repaint. + non_client_view_->SchedulePaint(); + + // Update the native frame's icon. We do this regardless of whether or not + // the native frame is being used, since this also updates the taskbar, etc. + SkBitmap icon = window_delegate_->GetWindowIcon(); + if (!icon.isNull()) { + HICON windows_icon = IconUtil::CreateHICONFromSkBitmap(icon); + // We need to make sure to destroy the previous icon, otherwise we'll leak + // these GDI objects until we crash! + HICON old_icon = reinterpret_cast( + SendMessage(GetNativeView(), WM_SETICON, ICON_SMALL, + reinterpret_cast(windows_icon))); + if (old_icon) + DestroyIcon(old_icon); + old_icon = reinterpret_cast( + SendMessage(GetNativeView(), WM_SETICON, ICON_BIG, + reinterpret_cast(windows_icon))); + if (old_icon) + DestroyIcon(old_icon); + } +} + +NonClientFrameView* WindowWin::CreateFrameViewForWindow() { + if (non_client_view_->UseNativeFrame()) + return new NativeFrameView(this); + return new CustomFrameView(this); +} + +void WindowWin::UpdateFrameAfterFrameChange() { + // We've either gained or lost a custom window region, so reset it now. + ResetWindowRegion(true); +} + +WindowDelegate* WindowWin::GetDelegate() const { + return window_delegate_; +} + +NonClientView* WindowWin::GetNonClientView() const { + return non_client_view_; +} + +ClientView* WindowWin::GetClientView() const { + return non_client_view_->client_view(); +} + +gfx::NativeWindow WindowWin::GetNativeWindow() const { + return GetNativeView(); +} + +//////////////////////////////////////////////////////////////////////////////// +// WindowWin, NotificationObserver implementation: + +void WindowWin::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + // This window is closed when the last app window is closed. + DCHECK(type == NotificationType::ALL_APPWINDOWS_CLOSED); + // Only registered as an observer when we're not an app window. + // XXX DCHECK(!IsAppWindow()); + Close(); +} + +/////////////////////////////////////////////////////////////////////////////// +// WindowWin, protected: + +WindowWin::WindowWin(WindowDelegate* window_delegate) + : WidgetWin(), + focus_on_creation_(true), + window_delegate_(window_delegate), + non_client_view_(new NonClientView(this)), + owning_hwnd_(NULL), + minimum_size_(100, 100), + is_modal_(false), + restored_enabled_(false), + is_always_on_top_(false), + window_closed_(false), + disable_inactive_rendering_(false), + is_active_(false), + lock_updates_(false), + saved_window_style_(0), + saved_maximized_state_(0), + force_hidden_(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); + set_window_ex_style(0); +} + +void WindowWin::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 WidgetWin functions may be called during initialization. + is_modal_ = window_delegate_->IsModal(); + if (is_modal_) + BecomeModal(); + is_always_on_top_ = window_delegate_->IsAlwaysOnTop(); + + if (window_style() == 0) + set_window_style(CalculateWindowStyle()); + if (window_ex_style() == 0) + set_window_ex_style(CalculateWindowExStyle()); + + WidgetWin::Init(parent, bounds, true); + win_util::SetWindowUserData(GetNativeView(), this); + + // Create the ClientView, add it to the NonClientView and add the + // NonClientView to the RootView. This will cause everything to be parented. + non_client_view_->set_client_view(window_delegate_->CreateClientView(this)); + WidgetWin::SetContentsView(non_client_view_); + + UpdateWindowTitle(); + + SetInitialBounds(bounds); + InitAlwaysOnTopState(); + + if (!IsAppWindow()) { + notification_registrar_.Add( + this, + NotificationType::ALL_APPWINDOWS_CLOSED, + NotificationService::AllSources()); + } + + ResetWindowRegion(false); +} + +void WindowWin::SizeWindowToDefault() { + win_util::CenterAndSizeWindow(owning_window(), GetNativeView(), + non_client_view_->GetPreferredSize().ToSIZE(), + false); +} + +void WindowWin::RunSystemMenu(const gfx::Point& point) { + // We need to reset and clean up any currently created system menu objects. + // We need to call this otherwise there's a small chance that we aren't going + // to get a system menu. We also can't take the return value of this + // function. We need to call it *again* to get a valid HMENU. + //::GetSystemMenu(GetNativeView(), TRUE); + HMENU system_menu = ::GetSystemMenu(GetNativeView(), FALSE); + int id = ::TrackPopupMenu(system_menu, + TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD, + point.x(), point.y(), 0, GetNativeView(), NULL); + ExecuteSystemMenuCommand(id); +} + +/////////////////////////////////////////////////////////////////////////////// +// WindowWin, WidgetWin overrides: + +void WindowWin::OnActivate(UINT action, BOOL minimized, HWND window) { + if (action == WA_INACTIVE) + SaveWindowPosition(); +} + +void WindowWin::OnActivateApp(BOOL active, DWORD thread_id) { + if (!active && thread_id != GetCurrentThreadId()) { + // Another application was activated, we should reset any state that + // disables inactive rendering now. + disable_inactive_rendering_ = false; + non_client_view_->DisableInactiveRendering(false); + // Update the native frame too, since it could be rendering the non-client + // area. + CallDefaultNCActivateHandler(FALSE); + } +} + +LRESULT WindowWin::OnAppCommand(HWND window, short app_command, WORD device, + int keystate) { + // We treat APPCOMMAND ids as an extension of our command namespace, and just + // let the delegate figure out what to do... + if (!window_delegate_->ExecuteWindowsCommand(app_command)) + return WidgetWin::OnAppCommand(window, app_command, device, keystate); + return 0; +} + +void WindowWin::OnCommand(UINT notification_code, int command_id, HWND window) { + // If the notification code is > 1 it means it is control specific and we + // should ignore it. + if (notification_code > 1 || + window_delegate_->ExecuteWindowsCommand(command_id)) { + WidgetWin::OnCommand(notification_code, command_id, window); + } +} + +void WindowWin::OnDestroy() { + non_client_view_->WindowClosing(); + RestoreEnabledIfNecessary(); + WidgetWin::OnDestroy(); +} + +namespace { +static BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) { + SendMessage(window, WM_DWMCOMPOSITIONCHANGED, 0, 0); + return TRUE; +} +} // namespace + +LRESULT WindowWin::OnDwmCompositionChanged(UINT msg, WPARAM w_param, + LPARAM l_param) { + // The window may try to paint in SetUseNativeFrame, and as a result it can + // get into a state where it is very unhappy with itself - rendering black + // behind the entire client area. This is because for some reason the + // SkPorterDuff::kClear_mode erase done in the RootView thinks the window is + // still opaque. So, to work around this we hide the window as soon as we can + // (now), saving off its placement so it can be properly restored once + // everything has settled down. + WINDOWPLACEMENT saved_window_placement; + saved_window_placement.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement(GetNativeView(), &saved_window_placement); + Hide(); + + // Important step: restore the window first, since our hiding hack doesn't + // work for maximized windows! We tell the frame not to allow itself to be + // made visible though, which removes the brief flicker. + force_hidden_ = true; + ::ShowWindow(GetNativeView(), SW_RESTORE); + force_hidden_ = false; + + // We respond to this in response to WM_DWMCOMPOSITIONCHANGED since that is + // the only thing we care about - we don't actually respond to WM_THEMECHANGED + // messages. + non_client_view_->SetUseNativeFrame(win_util::ShouldUseVistaFrame()); + + // Now that we've updated the frame, we'll want to restore our saved placement + // since the display should have settled down and we can be properly rendered. + SetWindowPlacement(GetNativeView(), &saved_window_placement); + + // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want + // to notify our children too, since we can have MDI child windows who need to + // update their appearance. + EnumChildWindows(GetNativeView(), &SendDwmCompositionChanged, NULL); + return 0; +} + +void WindowWin::OnFinalMessage(HWND window) { + // Delete and NULL the delegate here once we're guaranteed to get no more + // messages. + window_delegate_->DeleteDelegate(); + window_delegate_ = NULL; + WidgetWin::OnFinalMessage(window); +} + +namespace { +static void EnableMenuItem(HMENU menu, UINT command, bool enabled) { + UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED); + EnableMenuItem(menu, command, flags); +} +} // namespace + +void WindowWin::OnInitMenu(HMENU menu) { + // We only need to manually enable the system menu if we're not using a native + // frame. + if (non_client_view_->UseNativeFrame()) + WidgetWin::OnInitMenu(menu); + + bool is_minimized = IsMinimized(); + bool is_maximized = IsMaximized(); + bool is_restored = !is_minimized && !is_maximized; + + ScopedRedrawLock lock(this); + EnableMenuItem(menu, SC_RESTORE, !is_restored); + EnableMenuItem(menu, SC_MOVE, is_restored); + EnableMenuItem(menu, SC_SIZE, window_delegate_->CanResize() && is_restored); + EnableMenuItem(menu, SC_MAXIMIZE, + window_delegate_->CanMaximize() && !is_maximized); + EnableMenuItem(menu, SC_MINIMIZE, + window_delegate_->CanMaximize() && !is_minimized); +} + +void WindowWin::OnMouseLeave() { + // We only need to manually track WM_MOUSELEAVE messages between the client + // and non-client area when we're not using the native frame. + if (non_client_view_->UseNativeFrame()) { + SetMsgHandled(FALSE); + return; + } + + bool process_mouse_exited = true; + POINT pt; + if (GetCursorPos(&pt)) { + LRESULT ht_component = + ::SendMessage(GetNativeView(), WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y)); + if (ht_component != HTNOWHERE) { + // If the mouse moved into a part of the window's non-client area, then + // don't send a mouse exited event since the mouse is still within the + // bounds of the ChromeView that's rendering the frame. Note that we do + // _NOT_ do this for windows with native frames, since in that case the + // mouse really will have left the bounds of the RootView. + process_mouse_exited = false; + } + } + + if (process_mouse_exited) + ProcessMouseExited(); +} + +LRESULT WindowWin::OnNCActivate(BOOL active) { + is_active_ = !!active; + + // If we're not using the native frame, we need to force a synchronous repaint + // otherwise we'll be left in the wrong activation state until something else + // causes a repaint later. + if (!non_client_view_->UseNativeFrame()) { + // We can get WM_NCACTIVATE before we're actually visible. If we're not + // visible, no need to paint. + if (IsWindowVisible(GetNativeView())) { + non_client_view_->SchedulePaint(); + // We need to force a paint now, as a user dragging a window will block + // painting operations while the move is in progress. + PaintNow(root_view_->GetScheduledPaintRect()); + } + } + + // If we're active again, we should be allowed to render as inactive, so + // tell the non-client view. This must be done independently of the check for + // disable_inactive_rendering_ since that check is valid even if the frame + // is not active, but this can only be done if we've become active. + if (IsActive()) + non_client_view_->DisableInactiveRendering(false); + + // Reset the disable inactive rendering state since activation has changed. + if (disable_inactive_rendering_) { + disable_inactive_rendering_ = false; + return CallDefaultNCActivateHandler(TRUE); + } + return CallDefaultNCActivateHandler(active); +} + +LRESULT WindowWin::OnNCCalcSize(BOOL mode, LPARAM l_param) { + // We only need to adjust the client size/paint handling when we're not using + // the native frame. + if (non_client_view_->UseNativeFrame()) + return WidgetWin::OnNCCalcSize(mode, l_param); + + RECT* client_rect = mode ? + &reinterpret_cast(l_param)->rgrc[0] : + reinterpret_cast(l_param); + if (IsMaximized()) { + // Make the maximized mode client rect fit the screen exactly, by + // subtracting the border Windows automatically adds for maximized mode. + int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); + InflateRect(client_rect, -border_thickness, -border_thickness); + + // Find all auto-hide taskbars along the screen edges and adjust in by the + // thickness of the auto-hide taskbar on each such edge, so the window isn't + // treated as a "fullscreen app", which would cause the taskbars to + // disappear. + HMONITOR monitor = MonitorFromWindow(GetNativeView(), + MONITOR_DEFAULTTONEAREST); + if (win_util::EdgeHasAutoHideTaskbar(ABE_LEFT, monitor)) + client_rect->left += win_util::kAutoHideTaskbarThicknessPx; + if (win_util::EdgeHasAutoHideTaskbar(ABE_TOP, monitor)) + client_rect->top += win_util::kAutoHideTaskbarThicknessPx; + if (win_util::EdgeHasAutoHideTaskbar(ABE_RIGHT, monitor)) + client_rect->right -= win_util::kAutoHideTaskbarThicknessPx; + if (win_util::EdgeHasAutoHideTaskbar(ABE_BOTTOM, monitor)) + client_rect->bottom -= win_util::kAutoHideTaskbarThicknessPx; + + // We cannot return WVR_REDRAW when there is nonclient area, or Windows + // exhibits bugs where client pixels and child HWNDs are mispositioned by + // the width/height of the upper-left nonclient area. + return 0; + } + + // If the window bounds change, we're going to relayout and repaint anyway. + // Returning WVR_REDRAW avoids an extra paint before that of the old client + // pixels in the (now wrong) location, and thus makes actions like resizing a + // window from the left edge look slightly less broken. + return mode ? WVR_REDRAW : 0; +} + +LRESULT WindowWin::OnNCHitTest(const CPoint& point) { + // First, give the NonClientView a chance to test the point to see if it + // provides any of the non-client area. + CPoint temp = point; + MapWindowPoints(HWND_DESKTOP, GetNativeView(), &temp, 1); + int component = non_client_view_->NonClientHitTest(gfx::Point(temp)); + if (component != HTNOWHERE) + return component; + + // Otherwise, we let Windows do all the native frame non-client handling for + // us. + return WidgetWin::OnNCHitTest(point); +} + +namespace { +struct ClipState { + // The window being painted. + HWND parent; + + // DC painting to. + HDC dc; + + // Origin of the window in terms of the screen. + int x; + int y; +}; + +// See comments in OnNCPaint for details of this function. +static BOOL CALLBACK ClipDCToChild(HWND window, LPARAM param) { + ClipState* clip_state = reinterpret_cast(param); + if (GetParent(window) == clip_state->parent && IsWindowVisible(window)) { + RECT bounds; + GetWindowRect(window, &bounds); + ExcludeClipRect(clip_state->dc, + bounds.left - clip_state->x, + bounds.top - clip_state->y, + bounds.right - clip_state->x, + bounds.bottom - clip_state->y); + } + return TRUE; +} +} // namespace + +void WindowWin::OnNCPaint(HRGN rgn) { + // We only do non-client painting if we're not using the native frame. + if (non_client_view_->UseNativeFrame()) { + WidgetWin::OnNCPaint(rgn); + return; + } + + // We have an NC region and need to paint it. We expand the NC region to + // include the dirty region of the root view. This is done to minimize + // paints. + CRect window_rect; + GetWindowRect(&window_rect); + + if (window_rect.Width() != root_view_->width() || + window_rect.Height() != root_view_->height()) { + // If the size of the window differs from the size of the root view it + // means we're being asked to paint before we've gotten a WM_SIZE. This can + // happen when the user is interactively resizing the window. To avoid + // mass flickering we don't do anything here. Once we get the WM_SIZE we'll + // reset the region of the window which triggers another WM_NCPAINT and + // all is well. + return; + } + + CRect dirty_region; + // A value of 1 indicates paint all. + if (!rgn || rgn == reinterpret_cast(1)) { + dirty_region = CRect(0, 0, window_rect.Width(), window_rect.Height()); + } else { + RECT rgn_bounding_box; + GetRgnBox(rgn, &rgn_bounding_box); + if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect)) + return; // Dirty region doesn't intersect window bounds, bale. + + // rgn_bounding_box is in screen coordinates. Map it to window coordinates. + OffsetRect(&dirty_region, -window_rect.left, -window_rect.top); + } + + // In theory GetDCEx should do what we want, but I couldn't get it to work. + // In particular the docs mentiond DCX_CLIPCHILDREN, but as far as I can tell + // it doesn't work at all. So, instead we get the DC for the window then + // manually clip out the children. + HDC dc = GetWindowDC(GetNativeView()); + ClipState clip_state; + clip_state.x = window_rect.left; + clip_state.y = window_rect.top; + clip_state.parent = GetNativeView(); + clip_state.dc = dc; + EnumChildWindows(GetNativeView(), &ClipDCToChild, + reinterpret_cast(&clip_state)); + + RootView* root_view = GetRootView(); + CRect old_paint_region = root_view->GetScheduledPaintRectConstrainedToSize(); + + if (!old_paint_region.IsRectEmpty()) { + // The root view has a region that needs to be painted. Include it in the + // region we're going to paint. + + CRect tmp = dirty_region; + UnionRect(&dirty_region, &tmp, &old_paint_region); + } + + root_view->SchedulePaint(gfx::Rect(dirty_region), false); + + // ChromeCanvasPaints destructor does the actual painting. As such, wrap the + // following in a block to force paint to occur so that we can release the dc. + { + ChromeCanvasPaint canvas(dc, opaque(), dirty_region.left, dirty_region.top, + dirty_region.Width(), dirty_region.Height()); + + root_view->ProcessPaint(&canvas); + } + + ReleaseDC(GetNativeView(), dc); +} + +void WindowWin::OnNCLButtonDown(UINT ht_component, const CPoint& point) { + // When we're using a native frame, window controls work without us + // interfering. + if (!non_client_view_->UseNativeFrame()) { + switch (ht_component) { + case HTCLOSE: + case HTMINBUTTON: + case HTMAXBUTTON: { + // When the mouse is pressed down in these specific non-client areas, + // we need to tell the RootView to send the mouse pressed event (which + // sets capture, allowing subsequent WM_LBUTTONUP (note, _not_ + // WM_NCLBUTTONUP) to fire so that the appropriate WM_SYSCOMMAND can be + // sent by the applicable button's ButtonListener. We _have_ to do this + // way rather than letting Windows just send the syscommand itself (as + // would happen if we never did this dance) because for some insane + // reason DefWindowProc for WM_NCLBUTTONDOWN also renders the pressed + // window control button appearance, in the Windows classic style, over + // our view! Ick! By handling this message we prevent Windows from + // doing this undesirable thing, but that means we need to roll the + // sys-command handling ourselves. + ProcessNCMousePress(point, MK_LBUTTON); + return; + } + } + } + + // TODO(beng): figure out why we need to run the system menu manually + // ourselves. This is wrong and causes many subtle bugs. + // From my initial research, it looks like DefWindowProc tries + // to run it but fails before sending the initial WM_MENUSELECT + // for the sysmenu. + if (ht_component == HTSYSMENU) + RunSystemMenu(non_client_view_->GetSystemMenuPoint()); + else + WidgetWin::OnNCLButtonDown(ht_component, point); + + /* TODO(beng): Fix the standard non-client over-painting bug. This code + doesn't work but identifies the problem. + if (!IsMsgHandled()) { + // WindowWin::OnNCLButtonDown set the message as unhandled. This normally + // means WidgetWin::ProcessWindowMessage will pass it to + // DefWindowProc. Sadly, DefWindowProc for WM_NCLBUTTONDOWN does weird + // non-client painting, so we need to call it directly here inside a + // scoped update lock. + ScopedRedrawLock lock(this); + DefWindowProc(GetNativeView(), WM_NCLBUTTONDOWN, ht_component, + MAKELPARAM(point.x, point.y)); + SetMsgHandled(TRUE); + } + */ +} + +void WindowWin::OnNCRButtonDown(UINT ht_component, const CPoint& point) { + if (ht_component == HTCAPTION || ht_component == HTSYSMENU) + RunSystemMenu(gfx::Point(point)); + else + WidgetWin::OnNCRButtonDown(ht_component, point); +} + +LRESULT WindowWin::OnNCUAHDrawCaption(UINT msg, WPARAM w_param, + LPARAM l_param) { + // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for + // an explanation about why we need to handle this message. + SetMsgHandled(!non_client_view_->UseNativeFrame()); + return 0; +} + +LRESULT WindowWin::OnNCUAHDrawFrame(UINT msg, WPARAM w_param, + LPARAM l_param) { + // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for + // an explanation about why we need to handle this message. + SetMsgHandled(!non_client_view_->UseNativeFrame()); + return 0; +} + +LRESULT WindowWin::OnSetCursor(HWND window, UINT hittest_code, UINT message) { + // If the window is disabled, it's because we're showing a modal dialog box. + // We need to let DefWindowProc handle the message. That's because + // DefWindowProc for WM_SETCURSOR with message = some kind of mouse button + // down message sends the top level window a WM_ACTIVATEAPP message, which we + // otherwise wouldn't get. The symptom of not doing this is that if the user + // has a window in the background with a modal dialog open, they can't click + // on the disabled background window to bring the entire stack to the front. + // This is annoying because they then have to move all the foreground windows + // out of the way to be able to activate said window. I love how on Windows, + // the answer isn't always logical. + if (!IsWindowEnabled(GetNativeView())) + return WidgetWin::OnSetCursor(window, hittest_code, message); + + int index = RC_NORMAL; + switch (hittest_code) { + case HTTOP: + case HTBOTTOM: + index = RC_VERTICAL; + break; + case HTTOPLEFT: + case HTBOTTOMRIGHT: + index = RC_NWSE; + break; + case HTTOPRIGHT: + case HTBOTTOMLEFT: + index = RC_NESW; + break; + case HTLEFT: + case HTRIGHT: + index = RC_HORIZONTAL; + break; + case HTCAPTION: + case HTCLIENT: + index = RC_NORMAL; + break; + } + SetCursor(resize_cursors_[index]); + return 0; +} + +LRESULT WindowWin::OnSetIcon(UINT size_type, HICON new_icon) { + // This shouldn't hurt even if we're using the native frame. + ScopedRedrawLock lock(this); + return DefWindowProc(GetNativeView(), WM_SETICON, size_type, + reinterpret_cast(new_icon)); +} + +LRESULT WindowWin::OnSetText(const wchar_t* text) { + // This shouldn't hurt even if we're using the native frame. + ScopedRedrawLock lock(this); + return DefWindowProc(GetNativeView(), WM_SETTEXT, NULL, + reinterpret_cast(text)); +} + +void WindowWin::OnSize(UINT size_param, const CSize& new_size) { + // Don't no-op if the new_size matches current size. If our normal bounds + // and maximized bounds are the same, then we need to layout (because we + // layout differently when maximized). + SaveWindowPosition(); + ChangeSize(size_param, new_size); + RedrawWindow(GetNativeView(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); + + // ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've + // invoked OnSize we ensure the RootView has been laid out. + ResetWindowRegion(false); +} + +void WindowWin::OnSysCommand(UINT notification_code, CPoint click) { + if (!non_client_view_->UseNativeFrame()) { + // Windows uses the 4 lower order bits of |notification_code| for type- + // specific information so we must exclude this when comparing. + static const int sc_mask = 0xFFF0; + if ((notification_code & sc_mask) == SC_MINIMIZE || + (notification_code & sc_mask) == SC_MAXIMIZE || + (notification_code & sc_mask) == SC_RESTORE) { + non_client_view_->ResetWindowControls(); + } else if ((notification_code & sc_mask) == SC_MOVE || + (notification_code & sc_mask) == SC_SIZE) { + if (lock_updates_) { + // We were locked, before entering a resize or move modal loop. Now that + // we've begun to move the window, we need to unlock updates so that the + // sizing/moving feedback can be continuous. + UnlockUpdates(); + } + } + } + + // First see if the delegate can handle it. + if (window_delegate_->ExecuteWindowsCommand(notification_code)) + return; + + if (notification_code == IDC_ALWAYS_ON_TOP) { + is_always_on_top_ = !is_always_on_top_; + + // Change the menu check state. + HMENU system_menu = GetSystemMenu(GetNativeView(), FALSE); + MENUITEMINFO menu_info; + memset(&menu_info, 0, sizeof(MENUITEMINFO)); + menu_info.cbSize = sizeof(MENUITEMINFO); + BOOL r = GetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, + FALSE, &menu_info); + DCHECK(r); + menu_info.fMask = MIIM_STATE; + if (is_always_on_top_) + menu_info.fState = MFS_CHECKED; + r = SetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, FALSE, &menu_info); + + // Now change the actual window's behavior. + AlwaysOnTopChanged(); + } else if ((notification_code == SC_KEYMENU) && (click.x == VK_SPACE)) { + // Run the system menu at the NonClientView's desired location. + RunSystemMenu(non_client_view_->GetSystemMenuPoint()); + } else { + // Use the default implementation for any other command. + DefWindowProc(GetNativeView(), WM_SYSCOMMAND, notification_code, + MAKELPARAM(click.y, click.x)); + } +} + +void WindowWin::OnWindowPosChanging(WINDOWPOS* window_pos) { + if (force_hidden_) { + // Prevent the window from being made visible if we've been asked to do so. + // See comment in header as to why we might want this. + window_pos->flags &= ~SWP_SHOWWINDOW; + } + WidgetWin::OnWindowPosChanging(window_pos); +} + +//////////////////////////////////////////////////////////////////////////////// +// WindowWin, private: + +void WindowWin::BecomeModal() { + // We implement modality by crawling up the hierarchy of windows starting + // at the owner, disabling all of them so that they don't receive input + // messages. + DCHECK(owning_hwnd_) << "Can't create a modal dialog without an owner"; + HWND start = owning_hwnd_; + while (start != NULL) { + ::EnableWindow(start, FALSE); + start = ::GetParent(start); + } +} + +void WindowWin::SetInitialFocus() { + if (!focus_on_creation_) + return; + + View* v = window_delegate_->GetInitiallyFocusedView(); + if (v) { + v->RequestFocus(); + } else { + // The window does not get keyboard messages unless we focus it, not sure + // why. + SetFocus(GetNativeView()); + } +} + +void WindowWin::SetInitialBounds(const gfx::Rect& create_bounds) { + // First we obtain the window's saved show-style and store it. We need to do + // this here, rather than in Show() because by the time Show() is called, + // the window's size will have been reset (below) and the saved maximized + // state will have been lost. Sadly there's no way to tell on Windows when + // a window is restored from maximized state, so we can't more accurately + // track maximized state independently of sizing information. + window_delegate_->GetSavedMaximizedState(&saved_maximized_state_); + + // Restore the window's placement from the controller. + gfx::Rect saved_bounds(create_bounds.ToRECT()); + if (window_delegate_->GetSavedWindowBounds(&saved_bounds)) { + // Make sure the bounds are at least the minimum size. + if (saved_bounds.width() < minimum_size_.cx) { + saved_bounds.SetRect(saved_bounds.x(), saved_bounds.y(), + saved_bounds.right() + minimum_size_.cx - + saved_bounds.width(), + saved_bounds.bottom()); + } + + if (saved_bounds.height() < minimum_size_.cy) { + saved_bounds.SetRect(saved_bounds.x(), saved_bounds.y(), + saved_bounds.right(), + saved_bounds.bottom() + minimum_size_.cy - + saved_bounds.height()); + } + + // "Show state" (maximized, minimized, etc) is handled by Show(). + // Don't use SetBounds here. SetBounds constrains to the size of the + // monitor, but we don't want that when creating a new window as the result + // of dragging out a tab to create a new window. + SetWindowPos(NULL, saved_bounds.x(), saved_bounds.y(), + saved_bounds.width(), saved_bounds.height(), 0); + } else { + if (create_bounds.IsEmpty()) { + // No initial bounds supplied, so size the window to its content and + // center over its parent. + SizeWindowToDefault(); + } else { + // Use the supplied initial bounds. + SetBounds(create_bounds); + } + } +} + +void WindowWin::InitAlwaysOnTopState() { + is_always_on_top_ = false; + if (window_delegate_->GetSavedAlwaysOnTopState(&is_always_on_top_) && + is_always_on_top_ != window_delegate_->IsAlwaysOnTop()) { + AlwaysOnTopChanged(); + } + + if (window_delegate_->HasAlwaysOnTopMenu()) + AddAlwaysOnTopSystemMenuItem(); +} + +void WindowWin::AddAlwaysOnTopSystemMenuItem() { + // The Win32 API requires that we own the text. + always_on_top_menu_text_ = l10n_util::GetString(IDS_ALWAYS_ON_TOP); + + // Let's insert a menu to the window. + HMENU system_menu = ::GetSystemMenu(GetNativeView(), FALSE); + int index = ::GetMenuItemCount(system_menu) - 1; + if (index < 0) { + // Paranoia check. + NOTREACHED(); + index = 0; + } + // First we add the separator. + MENUITEMINFO menu_info; + memset(&menu_info, 0, sizeof(MENUITEMINFO)); + menu_info.cbSize = sizeof(MENUITEMINFO); + menu_info.fMask = MIIM_FTYPE; + menu_info.fType = MFT_SEPARATOR; + ::InsertMenuItem(system_menu, index, TRUE, &menu_info); + + // Then the actual menu. + menu_info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING | MIIM_STATE; + menu_info.fType = MFT_STRING; + menu_info.fState = MFS_ENABLED; + if (is_always_on_top_) + menu_info.fState |= MFS_CHECKED; + menu_info.wID = IDC_ALWAYS_ON_TOP; + menu_info.dwTypeData = const_cast(always_on_top_menu_text_.c_str()); + ::InsertMenuItem(system_menu, index, TRUE, &menu_info); +} + +void WindowWin::RestoreEnabledIfNecessary() { + if (is_modal_ && !restored_enabled_) { + restored_enabled_ = true; + // If we were run modally, we need to undo the disabled-ness we inflicted on + // the owner's parent hierarchy. + HWND start = owning_hwnd_; + while (start != NULL) { + ::EnableWindow(start, TRUE); + start = ::GetParent(start); + } + } +} + +void WindowWin::AlwaysOnTopChanged() { + ::SetWindowPos(GetNativeView(), + is_always_on_top_ ? HWND_TOPMOST : HWND_NOTOPMOST, + 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); +} + +DWORD WindowWin::CalculateWindowStyle() { + DWORD window_styles = + WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_SYSMENU | WS_CAPTION; + bool can_resize = window_delegate_->CanResize(); + bool can_maximize = window_delegate_->CanMaximize(); + if (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 WindowWin::CalculateWindowExStyle() { + DWORD window_ex_styles = 0; + if (window_delegate_->AsDialogDelegate()) + window_ex_styles |= WS_EX_DLGMODALFRAME; + if (window_delegate_->IsAlwaysOnTop()) + window_ex_styles |= WS_EX_TOPMOST; + return window_ex_styles; +} + +void WindowWin::SaveWindowPosition() { + // The window delegate does the actual saving for us. It seems like (judging + // by go/crash) that in some circumstances we can end up here after + // WM_DESTROY, at which point the window delegate is likely gone. So just + // bail. + if (!window_delegate_) + return; + + WINDOWPLACEMENT win_placement = { 0 }; + win_placement.length = sizeof(WINDOWPLACEMENT); + + BOOL r = GetWindowPlacement(GetNativeView(), &win_placement); + DCHECK(r); + + bool maximized = (win_placement.showCmd == SW_SHOWMAXIMIZED); + CRect window_bounds(win_placement.rcNormalPosition); + window_delegate_->SaveWindowPlacement( + gfx::Rect(win_placement.rcNormalPosition), maximized, is_always_on_top_); +} + +void WindowWin::LockUpdates() { + lock_updates_ = true; + saved_window_style_ = GetWindowLong(GetNativeView(), GWL_STYLE); + SetWindowLong(GetNativeView(), GWL_STYLE, saved_window_style_ & ~WS_VISIBLE); +} + +void WindowWin::UnlockUpdates() { + SetWindowLong(GetNativeView(), GWL_STYLE, saved_window_style_); + lock_updates_ = false; +} + +void WindowWin::ResetWindowRegion(bool force) { + // A native frame uses the native window region, and we don't want to mess + // with it. + if (non_client_view_->UseNativeFrame()) { + if (force) + SetWindowRgn(NULL, TRUE); + return; + } + + // Changing the window region is going to force a paint. Only change the + // window region if the region really differs. + HRGN current_rgn = CreateRectRgn(0, 0, 0, 0); + int current_rgn_result = GetWindowRgn(GetNativeView(), current_rgn); + + CRect window_rect; + GetWindowRect(&window_rect); + HRGN new_region; + gfx::Path window_mask; + non_client_view_->GetWindowMask( + gfx::Size(window_rect.Width(), window_rect.Height()), &window_mask); + new_region = window_mask.CreateHRGN(); + + if (current_rgn_result == ERROR || !EqualRgn(current_rgn, new_region)) { + // SetWindowRgn takes ownership of the HRGN created by CreateHRGN. + SetWindowRgn(new_region, TRUE); + } else { + DeleteObject(new_region); + } + + DeleteObject(current_rgn); +} + +void WindowWin::ProcessNCMousePress(const CPoint& point, int flags) { + CPoint temp = point; + MapWindowPoints(HWND_DESKTOP, GetNativeView(), &temp, 1); + UINT message_flags = 0; + if ((GetKeyState(VK_CONTROL) & 0x80) == 0x80) + message_flags |= MK_CONTROL; + if ((GetKeyState(VK_SHIFT) & 0x80) == 0x80) + message_flags |= MK_SHIFT; + message_flags |= flags; + ProcessMousePressed(temp, message_flags, false); +} + +LRESULT WindowWin::CallDefaultNCActivateHandler(BOOL active) { + // The DefWindowProc handling for WM_NCACTIVATE renders the classic-look + // window title bar directly, so we need to use a redraw lock here to prevent + // it from doing so. + ScopedRedrawLock lock(this); + return DefWindowProc(GetNativeView(), WM_NCACTIVATE, active, 0); +} + +void WindowWin::InitClass() { + static bool initialized = false; + if (!initialized) { + resize_cursors_[RC_NORMAL] = LoadCursor(NULL, IDC_ARROW); + resize_cursors_[RC_VERTICAL] = LoadCursor(NULL, IDC_SIZENS); + resize_cursors_[RC_HORIZONTAL] = LoadCursor(NULL, IDC_SIZEWE); + resize_cursors_[RC_NESW] = LoadCursor(NULL, IDC_SIZENESW); + resize_cursors_[RC_NWSE] = LoadCursor(NULL, IDC_SIZENWSE); + initialized = true; + } +} + +} // namespace views diff --git a/chrome/views/window/window_win.h b/chrome/views/window/window_win.h new file mode 100644 index 0000000..6c33093 --- /dev/null +++ b/chrome/views/window/window_win.h @@ -0,0 +1,278 @@ +// Copyright (c) 2006-2008 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_VIEWS_WINDOW_WINDOW_WIN_H__ +#define CHROME_VIEWS_WINDOW_WINDOW_WIN_H__ + +#include "chrome/common/notification_registrar.h" +#include "chrome/views/widget/widget_win.h" +#include "chrome/views/window/client_view.h" +#include "chrome/views/window/non_client_view.h" +#include "chrome/views/window/window.h" + +namespace gfx { +class Point; +class Size; +}; + +namespace views { + +class Client; +class WindowDelegate; + +/////////////////////////////////////////////////////////////////////////////// +// +// WindowWin +// +// A WindowWin is a WidgetWin that has a caption and a border. The frame is +// rendered by the operating system. +// +/////////////////////////////////////////////////////////////////////////////// +class WindowWin : public WidgetWin, + public Window, + public NotificationObserver { + public: + virtual ~WindowWin(); + + // Show the window with the specified show command. + void Show(int show_state); + + // Retrieve the show state of the window. This is one of the SW_SHOW* flags + // passed into Windows' ShowWindow method. For normal windows this defaults + // to SW_SHOWNORMAL, however windows (e.g. the main window) can override this + // method to provide different values (e.g. retrieve the user's specified + // show state from the shortcut starutp info). + virtual int GetShowState() const; + + // Executes the specified SC_command. + void ExecuteSystemMenuCommand(int command); + + // Accessors and setters for various properties. + HWND owning_window() const { return owning_hwnd_; } + void set_focus_on_creation(bool focus_on_creation) { + focus_on_creation_ = focus_on_creation; + } + void set_force_hidden(bool force_hidden) { force_hidden_ = force_hidden; } + + // Window overrides: + virtual gfx::Rect GetBounds() const; + virtual void SetBounds(const gfx::Rect& bounds); + virtual void SetBounds(const gfx::Rect& bounds, + gfx::NativeWindow other_window); + virtual void Show(); + virtual void Activate(); + virtual void Close(); + virtual void Maximize(); + virtual void Minimize(); + virtual void Restore(); + virtual bool IsActive() const; + virtual bool IsVisible() const; + virtual bool IsMaximized() const; + virtual bool IsMinimized() const; + virtual void EnableClose(bool enable); + virtual void DisableInactiveRendering(); + virtual void UpdateWindowTitle(); + virtual void UpdateWindowIcon(); + virtual NonClientFrameView* CreateFrameViewForWindow(); + virtual void UpdateFrameAfterFrameChange(); + virtual WindowDelegate* GetDelegate() const; + virtual NonClientView* GetNonClientView() const; + virtual ClientView* GetClientView() const; + virtual gfx::NativeWindow GetNativeWindow() const; + + // NotificationObserver overrides: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + protected: + friend Window; + + // Constructs the WindowWin. |window_delegate| cannot be NULL. + explicit WindowWin(WindowDelegate* window_delegate); + + // Create the Window. + // If parent is NULL, this WindowWin is top level on the desktop. + // If |bounds| is empty, the view is queried for its preferred size and + // centered on screen. + virtual void Init(HWND parent, const gfx::Rect& bounds); + + // Sizes the window to the default size specified by its ClientView. + virtual void SizeWindowToDefault(); + + // Returns true if the WindowWin is considered to be an "app window" - i.e. + // any window which when it is the last of its type closed causes the + // application to exit. + virtual bool IsAppWindow() const { return false; } + + // Shows the system menu at the specified screen point. + void RunSystemMenu(const gfx::Point& point); + + // Overridden from WidgetWin: + virtual void OnActivate(UINT action, BOOL minimized, HWND window); + virtual void OnActivateApp(BOOL active, DWORD thread_id); + virtual LRESULT OnAppCommand(HWND window, short app_command, WORD device, + int keystate); + virtual void OnCommand(UINT notification_code, int command_id, HWND window); + virtual void OnDestroy(); + virtual LRESULT OnDwmCompositionChanged(UINT msg, WPARAM w_param, + LPARAM l_param); + virtual void OnFinalMessage(HWND window); + virtual void OnInitMenu(HMENU menu); + virtual void OnMouseLeave(); + virtual LRESULT OnNCActivate(BOOL active); + virtual LRESULT OnNCCalcSize(BOOL mode, LPARAM l_param); + virtual LRESULT OnNCHitTest(const CPoint& point); + virtual void OnNCPaint(HRGN rgn); + virtual void OnNCLButtonDown(UINT ht_component, const CPoint& point); + virtual void OnNCRButtonDown(UINT ht_component, const CPoint& point); + virtual LRESULT OnNCUAHDrawCaption(UINT msg, WPARAM w_param, LPARAM l_param); + virtual LRESULT OnNCUAHDrawFrame(UINT msg, WPARAM w_param, LPARAM l_param); + virtual LRESULT OnSetCursor(HWND window, UINT hittest_code, UINT message); + virtual LRESULT OnSetIcon(UINT size_type, HICON new_icon); + virtual LRESULT OnSetText(const wchar_t* text); + virtual void OnSize(UINT size_param, const CSize& new_size); + virtual void OnSysCommand(UINT notification_code, CPoint click); + virtual void OnWindowPosChanging(WINDOWPOS* window_pos); + virtual Window* AsWindow() { return this; } + virtual const Window* AsWindow() const { return this; } + + // Accessor for disable_inactive_rendering_. + bool disable_inactive_rendering() const { + return disable_inactive_rendering_; + } + + private: + // Set the window as modal (by disabling all the other windows). + void BecomeModal(); + + // Sets-up the focus manager with the view that should have focus when the + // window is shown the first time. If NULL is returned, the focus goes to the + // button if there is one, otherwise the to the Cancel button. + void SetInitialFocus(); + + // Place and size the window when it is created. |create_bounds| are the + // bounds used when the window was created. + void SetInitialBounds(const gfx::Rect& create_bounds); + + // Restore saved always on stop state and add the always on top system menu + // if needed. + void InitAlwaysOnTopState(); + + // Add an item for "Always on Top" to the System Menu. + void AddAlwaysOnTopSystemMenuItem(); + + // If necessary, enables all ancestors. + void RestoreEnabledIfNecessary(); + + // Update the window style to reflect the always on top state. + void AlwaysOnTopChanged(); + + // Calculate the appropriate window styles for this window. + DWORD CalculateWindowStyle(); + DWORD CalculateWindowExStyle(); + + // Asks the delegate if any to save the window's location and size. + void SaveWindowPosition(); + + // Lock or unlock the window from being able to redraw itself in response to + // updates to its invalid region. + class ScopedRedrawLock; + void LockUpdates(); + void UnlockUpdates(); + + // Resets the window region for the current window bounds if necessary. + // If |force| is true, the window region is reset to NULL even for native + // frame windows. + void ResetWindowRegion(bool force); + + // Converts a non-client mouse down message to a regular ChromeViews event + // and handle it. |point| is the mouse position of the message in screen + // coords. |flags| are flags that would be passed with a WM_L/M/RBUTTON* + // message and relate to things like which button was pressed. These are + // combined with flags relating to the current key state. + void ProcessNCMousePress(const CPoint& point, int flags); + + // Calls the default WM_NCACTIVATE handler with the specified activation + // value, safely wrapping the call in a ScopedRedrawLock to prevent frame + // flicker. + LRESULT CallDefaultNCActivateHandler(BOOL active); + + // Static resource initialization. + static void InitClass(); + enum ResizeCursor { + RC_NORMAL = 0, RC_VERTICAL, RC_HORIZONTAL, RC_NESW, RC_NWSE + }; + static HCURSOR resize_cursors_[6]; + + // Our window delegate (see Init method for documentation). + WindowDelegate* window_delegate_; + + // The View that provides the non-client area of the window (title bar, + // window controls, sizing borders etc). To use an implementation other than + // the default, this class must be subclassed and this value set to the + // desired implementation before calling |Init|. + NonClientView* non_client_view_; + + // Whether we should SetFocus() on a newly created window after + // Init(). Defaults to true. + bool focus_on_creation_; + + // We need to save the parent window that spawned us, since GetParent() + // returns NULL for dialogs. + HWND owning_hwnd_; + + // The smallest size the window can be. + CSize minimum_size_; + + // Whether or not the window is modal. This comes from the delegate and is + // cached at Init time to avoid calling back to the delegate from the + // destructor. + bool is_modal_; + + // Whether all ancestors have been enabled. This is only used if is_modal_ is + // true. + bool restored_enabled_; + + // Whether the window is currently always on top. + bool is_always_on_top_; + + // We need to own the text of the menu, the Windows API does not copy it. + std::wstring always_on_top_menu_text_; + + // Set to true if the window is in the process of closing . + bool window_closed_; + + // True when the window should be rendered as active, regardless of whether + // or not it actually is. + bool disable_inactive_rendering_; + + // True if this window is the active top level window. + bool is_active_; + + // True if updates to this window are currently locked. + bool lock_updates_; + + // The window styles of the window before updates were locked. + DWORD saved_window_style_; + + // The saved maximized state for this window. See note in SetInitialBounds + // that explains why we save this. + bool saved_maximized_state_; + + // True if we should prevent attempts to make the window visible when we + // handle WM_WINDOWPOSCHANGING. Some calls like ShowWindow(SW_RESTORE) make + // the window visible in addition to restoring it, when all we want to do is + // restore it. + bool force_hidden_; + + // Hold onto notifications. + NotificationRegistrar notification_registrar_; + + DISALLOW_COPY_AND_ASSIGN(WindowWin); +}; + +} // namespace views + +#endif // CHROME_VIEWS_WINDOW_WINDOW_WIN_H__ diff --git a/chrome/views/window_delegate.cc b/chrome/views/window_delegate.cc deleted file mode 100644 index 1ac5d31..0000000 --- a/chrome/views/window_delegate.cc +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "chrome/views/window_delegate.h" - -// TODO(beng): hrmp. Fix this in http://crbug.com/4406 -#include "chrome/browser/browser_process.h" -#include "chrome/common/pref_service.h" -#include "chrome/views/client_view.h" -#include "chrome/views/window.h" -#include "skia/include/SkBitmap.h" - -namespace views { - -WindowDelegate::WindowDelegate() { -} - -WindowDelegate::~WindowDelegate() { - ReleaseWindow(); -} - -// Returns the icon to be displayed in the window. -SkBitmap WindowDelegate::GetWindowIcon() { - return SkBitmap(); -} - -void WindowDelegate::SaveWindowPlacement(const gfx::Rect& bounds, - bool maximized, - bool always_on_top) { - std::wstring window_name = GetWindowName(); - if (window_name.empty() || !g_browser_process->local_state()) - return; - - DictionaryValue* window_preferences = - g_browser_process->local_state()->GetMutableDictionary( - window_name.c_str()); - window_preferences->SetInteger(L"left", bounds.x()); - window_preferences->SetInteger(L"top", bounds.y()); - window_preferences->SetInteger(L"right", bounds.right()); - window_preferences->SetInteger(L"bottom", bounds.bottom()); - window_preferences->SetBoolean(L"maximized", maximized); - window_preferences->SetBoolean(L"always_on_top", always_on_top); -} - -bool WindowDelegate::GetSavedWindowBounds(gfx::Rect* bounds) const { - std::wstring window_name = GetWindowName(); - if (window_name.empty()) - return false; - - const DictionaryValue* dictionary = - g_browser_process->local_state()->GetDictionary(window_name.c_str()); - int left, top, right, bottom; - if (!dictionary || !dictionary->GetInteger(L"left", &left) || - !dictionary->GetInteger(L"top", &top) || - !dictionary->GetInteger(L"right", &right) || - !dictionary->GetInteger(L"bottom", &bottom)) - return false; - - bounds->SetRect(left, top, right - left, bottom - top); - return true; -} - -bool WindowDelegate::GetSavedMaximizedState(bool* maximized) const { - std::wstring window_name = GetWindowName(); - if (window_name.empty()) - return false; - - const DictionaryValue* dictionary = - g_browser_process->local_state()->GetDictionary(window_name.c_str()); - return dictionary && dictionary->GetBoolean(L"maximized", maximized); -} - -bool WindowDelegate::GetSavedAlwaysOnTopState(bool* always_on_top) const { - if (!g_browser_process->local_state()) - return false; - - std::wstring window_name = GetWindowName(); - if (window_name.empty()) - return false; - - const DictionaryValue* dictionary = - g_browser_process->local_state()->GetDictionary(window_name.c_str()); - return dictionary && dictionary->GetBoolean(L"always_on_top", always_on_top); -} - - -ClientView* WindowDelegate::CreateClientView(Window* window) { - return new ClientView(window, GetContentsView()); -} - -void WindowDelegate::ReleaseWindow() { - window_.release(); -} - -} // namespace views diff --git a/chrome/views/window_delegate.h b/chrome/views/window_delegate.h deleted file mode 100644 index 985ed60..0000000 --- a/chrome/views/window_delegate.h +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) 2006-2008 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_VIEWS_WINDOW_DELEGATE_H_ -#define CHROME_VIEWS_WINDOW_DELEGATE_H_ - -#include - -#include "base/scoped_ptr.h" - -class SkBitmap; - -namespace gfx { -class Rect; -} -// TODO(maruel): Remove once gfx::Rect is used instead. -namespace WTL { -class CRect; -} -using WTL::CRect; - -namespace views { - -class ClientView; -class DialogDelegate; -class View; -class Window; - -/////////////////////////////////////////////////////////////////////////////// -// -// WindowDelegate -// -// WindowDelegate is an interface implemented by objects that wish to show a -// Window. The window that is displayed uses this interface to determine how -// it should be displayed and notify the delegate object of certain events. -// -/////////////////////////////////////////////////////////////////////////////// -class WindowDelegate { - public: - WindowDelegate(); - virtual ~WindowDelegate(); - - virtual DialogDelegate* AsDialogDelegate() { return NULL; } - - // Returns true if the window can ever be resized. - virtual bool CanResize() const { - return false; - } - - // Returns true if the window can ever be maximized. - virtual bool CanMaximize() const { - return false; - } - - // Returns true if the window should be placed on top of all other windows on - // the system, even when it is not active. If HasAlwaysOnTopMenu() returns - // true, then this method is only used the first time the window is opened, it - // is stored in the preferences for next runs. - virtual bool IsAlwaysOnTop() const { - return false; - } - - // Returns whether an "always on top" menu should be added to the system menu - // of the window. - virtual bool HasAlwaysOnTopMenu() const { - return false; - } - - // Returns true if the dialog should be displayed modally to the window that - // opened it. Only windows with WindowType == DIALOG can be modal. - virtual bool IsModal() const { - return false; - } - - // Returns the text to be displayed in the window title. - virtual std::wstring GetWindowTitle() const { - return L""; - } - - // Returns the view that should have the focus when the dialog is opened. If - // NULL no view is focused. - virtual View* GetInitiallyFocusedView() { return NULL; } - - // Returns true if the window should show a title in the title bar. - virtual bool ShouldShowWindowTitle() const { - return true; - } - - // Returns the icon to be displayed in the window. - virtual SkBitmap GetWindowIcon(); - - // Returns true if a window icon should be shown. - virtual bool ShouldShowWindowIcon() const { - return false; - } - - // Execute a command in the window's controller. Returns true if the command - // was handled, false if it was not. - virtual bool ExecuteWindowsCommand(int command_id) { return false; } - - // Returns the window's name identifier. Used to identify this window for - // state restoration. - virtual std::wstring GetWindowName() const { - return std::wstring(); - } - - // Saves the window's bounds, maximized and always-on-top states. By default - // this uses the process' local state keyed by window name (See GetWindowName - // above). This behavior can be overridden to provide additional - // functionality. - virtual void SaveWindowPlacement(const gfx::Rect& bounds, - bool maximized, - bool always_on_top); - - // Retrieves the window's bounds, maximized and always-on-top states. By - // default, this uses the process' local state keyed by window name (See - // GetWindowName above). This behavior can be overridden to provide - // additional functionality. - virtual bool GetSavedWindowBounds(gfx::Rect* bounds) const; - virtual bool GetSavedMaximizedState(bool* maximized) const; - virtual bool GetSavedAlwaysOnTopState(bool* always_on_top) const; - - // Called when the window closes. - virtual void WindowClosing() { } - - // Called when the window is destroyed. No events must be sent or received - // after this point. The delegate can use this opportunity to delete itself at - // this time if necessary. - virtual void DeleteDelegate() { } - - // Returns the View that is contained within this Window. - virtual View* GetContentsView() { - return NULL; - } - - // Called by the Window to create the Client View used to host the contents - // of the window. - virtual ClientView* CreateClientView(Window* window); - - // An accessor to the Window this delegate is bound to. - Window* window() const { return window_.get(); } - - protected: - // Releases the Window* we maintain. This should be done by a delegate in its - // WindowClosing handler if it intends to be re-cycled to be used on a - // different Window. - void ReleaseWindow(); - - private: - friend class WindowWin; - // 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 window_; -}; - -} // namespace views - -#endif // CHROME_VIEWS_WINDOW_DELEGATE_H_ diff --git a/chrome/views/window_resources.h b/chrome/views/window_resources.h deleted file mode 100644 index 6face56..0000000 --- a/chrome/views/window_resources.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2006-2008 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_VIEWS_WINDOW_RESOURCES_H_ -#define CHROME_BROWSER_VIEWS_WINDOW_RESOURCES_H_ - -class SkBitmap; - -namespace views { - -typedef int FramePartBitmap; - -/////////////////////////////////////////////////////////////////////////////// -// WindowResources -// -// An interface implemented by an object providing bitmaps to render the -// contents of a window frame. The Window may swap in different -// implementations of this interface to render different modes. The definition -// of FramePartBitmap depends on the implementation. -// -class WindowResources { - public: - virtual ~WindowResources() { } - virtual SkBitmap* GetPartBitmap(FramePartBitmap part) const = 0; -}; - -} // namespace views - -#endif // CHROME_BROWSER_VIEWS_WINDOW_RESOURCES_H_ diff --git a/chrome/views/window_win.cc b/chrome/views/window_win.cc deleted file mode 100644 index fda6eb7..0000000 --- a/chrome/views/window_win.cc +++ /dev/null @@ -1,1234 +0,0 @@ -// Copyright (c) 2006-2008 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. - -#include "chrome/views/window_win.h" - -#include - -#include "base/win_util.h" -#include "chrome/app/chrome_dll_resource.h" -#include "chrome/common/gfx/chrome_canvas.h" -#include "chrome/common/gfx/chrome_font.h" -#include "chrome/common/gfx/icon_util.h" -#include "chrome/common/gfx/path.h" -#include "chrome/common/l10n_util.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/pref_service.h" -#include "chrome/common/resource_bundle.h" -#include "chrome/common/win_util.h" -#include "chrome/views/client_view.h" -#include "chrome/views/custom_frame_view.h" -#include "chrome/views/native_frame_view.h" -#include "chrome/views/non_client_view.h" -#include "chrome/views/widget/root_view.h" -#include "chrome/views/window_delegate.h" -#include "grit/generated_resources.h" - -namespace views { - -// A scoping class that prevents a window from being able to redraw in response -// to invalidations that may occur within it for the lifetime of the object. -// -// Why would we want such a thing? Well, it turns out Windows has some -// "unorthodox" behavior when it comes to painting its non-client areas. -// Occasionally, Windows will paint portions of the default non-client area -// right over the top of the custom frame. This is not simply fixed by handling -// WM_NCPAINT/WM_PAINT, with some investigation it turns out that this -// rendering is being done *inside* the default implementation of some message -// handlers and functions: -// . WM_SETTEXT -// . WM_SETICON -// . WM_NCLBUTTONDOWN -// . EnableMenuItem, called from our WM_INITMENU handler -// The solution is to handle these messages and call DefWindowProc ourselves, -// but prevent the window from being able to update itself for the duration of -// the call. We do this with this class, which automatically calls its -// associated Window's lock and unlock functions as it is created and destroyed. -// See documentation in those methods for the technique used. -// -// IMPORTANT: Do not use this scoping object for large scopes or periods of -// time! IT WILL PREVENT THE WINDOW FROM BEING REDRAWN! (duh). -// -// I would love to hear Raymond Chen's explanation for all this. And maybe a -// list of other messages that this applies to ;-) -class WindowWin::ScopedRedrawLock { - public: - explicit ScopedRedrawLock(WindowWin* window) : window_(window) { - window_->LockUpdates(); - } - - ~ScopedRedrawLock() { - window_->UnlockUpdates(); - } - - private: - // The window having its style changed. - WindowWin* window_; -}; - -HCURSOR WindowWin::resize_cursors_[6]; - -// If the hung renderer warning doesn't fit on screen, the amount of padding to -// be left between the edge of the window and the edge of the nearest monitor, -// after the window is nudged back on screen. Pixels. -static const int kMonitorEdgePadding = 10; - -//////////////////////////////////////////////////////////////////////////////// -// WindowWin, public: - -WindowWin::~WindowWin() { -} - -// static -Window* Window::CreateChromeWindow(gfx::NativeWindow parent, - const gfx::Rect& bounds, - WindowDelegate* window_delegate) { - WindowWin* window = new WindowWin(window_delegate); - window->GetNonClientView()->SetFrameView(window->CreateFrameViewForWindow()); - window->Init(parent, bounds); - return window; -} - -gfx::Rect WindowWin::GetBounds() const { - gfx::Rect bounds; - WidgetWin::GetBounds(&bounds, true); - return bounds; -} - -void WindowWin::SetBounds(const gfx::Rect& bounds) { - SetBounds(bounds, NULL); -} - -void WindowWin::SetBounds(const gfx::Rect& bounds, - gfx::NativeWindow other_window) { - win_util::SetChildBounds(GetNativeView(), GetParent(), other_window, bounds, - kMonitorEdgePadding, 0); -} - -void WindowWin::Show(int show_state) { - ShowWindow(show_state); - // When launched from certain programs like bash and Windows Live Messenger, - // show_state is set to SW_HIDE, so we need to correct that condition. We - // don't just change show_state to SW_SHOWNORMAL because MSDN says we must - // always first call ShowWindow with the specified value from STARTUPINFO, - // otherwise all future ShowWindow calls will be ignored (!!#@@#!). Instead, - // we call ShowWindow again in this case. - if (show_state == SW_HIDE) { - show_state = SW_SHOWNORMAL; - ShowWindow(show_state); - } - - // We need to explicitly activate the window if we've been shown with a state - // that should activate, because if we're opened from a desktop shortcut while - // an existing window is already running it doesn't seem to be enough to use - // one of these flags to activate the window. - if (show_state == SW_SHOWNORMAL) - Activate(); - - SetInitialFocus(); -} - -int WindowWin::GetShowState() const { - return SW_SHOWNORMAL; -} - -void WindowWin::ExecuteSystemMenuCommand(int command) { - if (command) - SendMessage(GetNativeView(), WM_SYSCOMMAND, command, 0); -} - -// static -int Window::GetLocalizedContentsWidth(int col_resource_id) { - double chars = _wtof(l10n_util::GetString(col_resource_id).c_str()); - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - ChromeFont font = rb.GetFont(ResourceBundle::BaseFont); - int width = font.GetExpectedTextWidth(static_cast(chars)); - DCHECK(width > 0); - return width; -} - -// static -int Window::GetLocalizedContentsHeight(int row_resource_id) { - double lines = _wtof(l10n_util::GetString(row_resource_id).c_str()); - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - ChromeFont font = rb.GetFont(ResourceBundle::BaseFont); - int height = static_cast(font.height() * lines); - DCHECK(height > 0); - return height; -} - -// static -gfx::Size Window::GetLocalizedContentsSize(int col_resource_id, - int row_resource_id) { - return gfx::Size(GetLocalizedContentsWidth(col_resource_id), - GetLocalizedContentsHeight(row_resource_id)); -} - -//////////////////////////////////////////////////////////////////////////////// -// WindowWin, Window implementation: - -void WindowWin::Show() { - int show_state = GetShowState(); - if (saved_maximized_state_) - show_state = SW_SHOWMAXIMIZED; - Show(show_state); -} - -void WindowWin::Activate() { - if (IsMinimized()) - ::ShowWindow(GetNativeView(), SW_RESTORE); - ::SetWindowPos(GetNativeView(), HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); - SetForegroundWindow(GetNativeView()); -} - -void WindowWin::Close() { - if (window_closed_) { - // It appears we can hit this code path if you close a modal dialog then - // close the last browser before the destructor is hit, which triggers - // invoking Close again. I'm short circuiting this code path to avoid - // calling into the delegate twice, which is problematic. - return; - } - - if (non_client_view_->CanClose()) { - SaveWindowPosition(); - RestoreEnabledIfNecessary(); - WidgetWin::Close(); - // If the user activates another app after opening us, then comes back and - // closes us, we want our owner to gain activation. But only if the owner - // is visible. If we don't manually force that here, the other app will - // regain activation instead. - if (owning_hwnd_ && GetNativeView() == GetForegroundWindow() && - IsWindowVisible(owning_hwnd_)) { - SetForegroundWindow(owning_hwnd_); - } - window_closed_ = true; - } -} - -void WindowWin::Maximize() { - ExecuteSystemMenuCommand(SC_MAXIMIZE); -} - -void WindowWin::Minimize() { - ExecuteSystemMenuCommand(SC_MINIMIZE); -} - -void WindowWin::Restore() { - ExecuteSystemMenuCommand(SC_RESTORE); -} - -bool WindowWin::IsActive() const { - return is_active_; -} - -bool WindowWin::IsVisible() const { - return !!::IsWindowVisible(GetNativeView()); -} - -bool WindowWin::IsMaximized() const { - return !!::IsZoomed(GetNativeView()); -} - -bool WindowWin::IsMinimized() const { - return !!::IsIconic(GetNativeView()); -} - -void WindowWin::EnableClose(bool enable) { - // If the native frame is rendering its own close button, ask it to disable. - non_client_view_->EnableClose(enable); - - // Disable the native frame's close button regardless of whether or not the - // native frame is in use, since this also affects the system menu. - EnableMenuItem(GetSystemMenu(GetNativeView(), false), - SC_CLOSE, enable ? MF_ENABLED : MF_GRAYED); - - // Let the window know the frame changed. - SetWindowPos(NULL, 0, 0, 0, 0, - SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS | - SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION | - SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER); -} - -void WindowWin::DisableInactiveRendering() { - disable_inactive_rendering_ = true; - non_client_view_->DisableInactiveRendering(disable_inactive_rendering_); -} - -void WindowWin::UpdateWindowTitle() { - // If the non-client view is rendering its own title, it'll need to relayout - // now. - non_client_view_->Layout(); - - // Update the native frame's text. We do this regardless of whether or not - // the native frame is being used, since this also updates the taskbar, etc. - std::wstring window_title = window_delegate_->GetWindowTitle(); - std::wstring localized_text; - if (l10n_util::AdjustStringForLocaleDirection(window_title, &localized_text)) - window_title.assign(localized_text); - SetWindowText(GetNativeView(), window_title.c_str()); -} - -void WindowWin::UpdateWindowIcon() { - // If the non-client view is rendering its own icon, we need to tell it to - // repaint. - non_client_view_->SchedulePaint(); - - // Update the native frame's icon. We do this regardless of whether or not - // the native frame is being used, since this also updates the taskbar, etc. - SkBitmap icon = window_delegate_->GetWindowIcon(); - if (!icon.isNull()) { - HICON windows_icon = IconUtil::CreateHICONFromSkBitmap(icon); - // We need to make sure to destroy the previous icon, otherwise we'll leak - // these GDI objects until we crash! - HICON old_icon = reinterpret_cast( - SendMessage(GetNativeView(), WM_SETICON, ICON_SMALL, - reinterpret_cast(windows_icon))); - if (old_icon) - DestroyIcon(old_icon); - old_icon = reinterpret_cast( - SendMessage(GetNativeView(), WM_SETICON, ICON_BIG, - reinterpret_cast(windows_icon))); - if (old_icon) - DestroyIcon(old_icon); - } -} - -NonClientFrameView* WindowWin::CreateFrameViewForWindow() { - if (non_client_view_->UseNativeFrame()) - return new NativeFrameView(this); - return new CustomFrameView(this); -} - -void WindowWin::UpdateFrameAfterFrameChange() { - // We've either gained or lost a custom window region, so reset it now. - ResetWindowRegion(true); -} - -WindowDelegate* WindowWin::GetDelegate() const { - return window_delegate_; -} - -NonClientView* WindowWin::GetNonClientView() const { - return non_client_view_; -} - -ClientView* WindowWin::GetClientView() const { - return non_client_view_->client_view(); -} - -gfx::NativeWindow WindowWin::GetNativeWindow() const { - return GetNativeView(); -} - -//////////////////////////////////////////////////////////////////////////////// -// WindowWin, NotificationObserver implementation: - -void WindowWin::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - // This window is closed when the last app window is closed. - DCHECK(type == NotificationType::ALL_APPWINDOWS_CLOSED); - // Only registered as an observer when we're not an app window. - // XXX DCHECK(!IsAppWindow()); - Close(); -} - -/////////////////////////////////////////////////////////////////////////////// -// WindowWin, protected: - -WindowWin::WindowWin(WindowDelegate* window_delegate) - : WidgetWin(), - focus_on_creation_(true), - window_delegate_(window_delegate), - non_client_view_(new NonClientView(this)), - owning_hwnd_(NULL), - minimum_size_(100, 100), - is_modal_(false), - restored_enabled_(false), - is_always_on_top_(false), - window_closed_(false), - disable_inactive_rendering_(false), - is_active_(false), - lock_updates_(false), - saved_window_style_(0), - saved_maximized_state_(0), - force_hidden_(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); - set_window_ex_style(0); -} - -void WindowWin::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 WidgetWin functions may be called during initialization. - is_modal_ = window_delegate_->IsModal(); - if (is_modal_) - BecomeModal(); - is_always_on_top_ = window_delegate_->IsAlwaysOnTop(); - - if (window_style() == 0) - set_window_style(CalculateWindowStyle()); - if (window_ex_style() == 0) - set_window_ex_style(CalculateWindowExStyle()); - - WidgetWin::Init(parent, bounds, true); - win_util::SetWindowUserData(GetNativeView(), this); - - // Create the ClientView, add it to the NonClientView and add the - // NonClientView to the RootView. This will cause everything to be parented. - non_client_view_->set_client_view(window_delegate_->CreateClientView(this)); - WidgetWin::SetContentsView(non_client_view_); - - UpdateWindowTitle(); - - SetInitialBounds(bounds); - InitAlwaysOnTopState(); - - if (!IsAppWindow()) { - notification_registrar_.Add( - this, - NotificationType::ALL_APPWINDOWS_CLOSED, - NotificationService::AllSources()); - } - - ResetWindowRegion(false); -} - -void WindowWin::SizeWindowToDefault() { - win_util::CenterAndSizeWindow(owning_window(), GetNativeView(), - non_client_view_->GetPreferredSize().ToSIZE(), - false); -} - -void WindowWin::RunSystemMenu(const gfx::Point& point) { - // We need to reset and clean up any currently created system menu objects. - // We need to call this otherwise there's a small chance that we aren't going - // to get a system menu. We also can't take the return value of this - // function. We need to call it *again* to get a valid HMENU. - //::GetSystemMenu(GetNativeView(), TRUE); - HMENU system_menu = ::GetSystemMenu(GetNativeView(), FALSE); - int id = ::TrackPopupMenu(system_menu, - TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD, - point.x(), point.y(), 0, GetNativeView(), NULL); - ExecuteSystemMenuCommand(id); -} - -/////////////////////////////////////////////////////////////////////////////// -// WindowWin, WidgetWin overrides: - -void WindowWin::OnActivate(UINT action, BOOL minimized, HWND window) { - if (action == WA_INACTIVE) - SaveWindowPosition(); -} - -void WindowWin::OnActivateApp(BOOL active, DWORD thread_id) { - if (!active && thread_id != GetCurrentThreadId()) { - // Another application was activated, we should reset any state that - // disables inactive rendering now. - disable_inactive_rendering_ = false; - non_client_view_->DisableInactiveRendering(false); - // Update the native frame too, since it could be rendering the non-client - // area. - CallDefaultNCActivateHandler(FALSE); - } -} - -LRESULT WindowWin::OnAppCommand(HWND window, short app_command, WORD device, - int keystate) { - // We treat APPCOMMAND ids as an extension of our command namespace, and just - // let the delegate figure out what to do... - if (!window_delegate_->ExecuteWindowsCommand(app_command)) - return WidgetWin::OnAppCommand(window, app_command, device, keystate); - return 0; -} - -void WindowWin::OnCommand(UINT notification_code, int command_id, HWND window) { - // If the notification code is > 1 it means it is control specific and we - // should ignore it. - if (notification_code > 1 || - window_delegate_->ExecuteWindowsCommand(command_id)) { - WidgetWin::OnCommand(notification_code, command_id, window); - } -} - -void WindowWin::OnDestroy() { - non_client_view_->WindowClosing(); - RestoreEnabledIfNecessary(); - WidgetWin::OnDestroy(); -} - -namespace { -static BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) { - SendMessage(window, WM_DWMCOMPOSITIONCHANGED, 0, 0); - return TRUE; -} -} // namespace - -LRESULT WindowWin::OnDwmCompositionChanged(UINT msg, WPARAM w_param, - LPARAM l_param) { - // The window may try to paint in SetUseNativeFrame, and as a result it can - // get into a state where it is very unhappy with itself - rendering black - // behind the entire client area. This is because for some reason the - // SkPorterDuff::kClear_mode erase done in the RootView thinks the window is - // still opaque. So, to work around this we hide the window as soon as we can - // (now), saving off its placement so it can be properly restored once - // everything has settled down. - WINDOWPLACEMENT saved_window_placement; - saved_window_placement.length = sizeof(WINDOWPLACEMENT); - GetWindowPlacement(GetNativeView(), &saved_window_placement); - Hide(); - - // Important step: restore the window first, since our hiding hack doesn't - // work for maximized windows! We tell the frame not to allow itself to be - // made visible though, which removes the brief flicker. - force_hidden_ = true; - ::ShowWindow(GetNativeView(), SW_RESTORE); - force_hidden_ = false; - - // We respond to this in response to WM_DWMCOMPOSITIONCHANGED since that is - // the only thing we care about - we don't actually respond to WM_THEMECHANGED - // messages. - non_client_view_->SetUseNativeFrame(win_util::ShouldUseVistaFrame()); - - // Now that we've updated the frame, we'll want to restore our saved placement - // since the display should have settled down and we can be properly rendered. - SetWindowPlacement(GetNativeView(), &saved_window_placement); - - // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want - // to notify our children too, since we can have MDI child windows who need to - // update their appearance. - EnumChildWindows(GetNativeView(), &SendDwmCompositionChanged, NULL); - return 0; -} - -void WindowWin::OnFinalMessage(HWND window) { - // Delete and NULL the delegate here once we're guaranteed to get no more - // messages. - window_delegate_->DeleteDelegate(); - window_delegate_ = NULL; - WidgetWin::OnFinalMessage(window); -} - -namespace { -static void EnableMenuItem(HMENU menu, UINT command, bool enabled) { - UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED); - EnableMenuItem(menu, command, flags); -} -} // namespace - -void WindowWin::OnInitMenu(HMENU menu) { - // We only need to manually enable the system menu if we're not using a native - // frame. - if (non_client_view_->UseNativeFrame()) - WidgetWin::OnInitMenu(menu); - - bool is_minimized = IsMinimized(); - bool is_maximized = IsMaximized(); - bool is_restored = !is_minimized && !is_maximized; - - ScopedRedrawLock lock(this); - EnableMenuItem(menu, SC_RESTORE, !is_restored); - EnableMenuItem(menu, SC_MOVE, is_restored); - EnableMenuItem(menu, SC_SIZE, window_delegate_->CanResize() && is_restored); - EnableMenuItem(menu, SC_MAXIMIZE, - window_delegate_->CanMaximize() && !is_maximized); - EnableMenuItem(menu, SC_MINIMIZE, - window_delegate_->CanMaximize() && !is_minimized); -} - -void WindowWin::OnMouseLeave() { - // We only need to manually track WM_MOUSELEAVE messages between the client - // and non-client area when we're not using the native frame. - if (non_client_view_->UseNativeFrame()) { - SetMsgHandled(FALSE); - return; - } - - bool process_mouse_exited = true; - POINT pt; - if (GetCursorPos(&pt)) { - LRESULT ht_component = - ::SendMessage(GetNativeView(), WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y)); - if (ht_component != HTNOWHERE) { - // If the mouse moved into a part of the window's non-client area, then - // don't send a mouse exited event since the mouse is still within the - // bounds of the ChromeView that's rendering the frame. Note that we do - // _NOT_ do this for windows with native frames, since in that case the - // mouse really will have left the bounds of the RootView. - process_mouse_exited = false; - } - } - - if (process_mouse_exited) - ProcessMouseExited(); -} - -LRESULT WindowWin::OnNCActivate(BOOL active) { - is_active_ = !!active; - - // If we're not using the native frame, we need to force a synchronous repaint - // otherwise we'll be left in the wrong activation state until something else - // causes a repaint later. - if (!non_client_view_->UseNativeFrame()) { - // We can get WM_NCACTIVATE before we're actually visible. If we're not - // visible, no need to paint. - if (IsWindowVisible(GetNativeView())) { - non_client_view_->SchedulePaint(); - // We need to force a paint now, as a user dragging a window will block - // painting operations while the move is in progress. - PaintNow(root_view_->GetScheduledPaintRect()); - } - } - - // If we're active again, we should be allowed to render as inactive, so - // tell the non-client view. This must be done independently of the check for - // disable_inactive_rendering_ since that check is valid even if the frame - // is not active, but this can only be done if we've become active. - if (IsActive()) - non_client_view_->DisableInactiveRendering(false); - - // Reset the disable inactive rendering state since activation has changed. - if (disable_inactive_rendering_) { - disable_inactive_rendering_ = false; - return CallDefaultNCActivateHandler(TRUE); - } - return CallDefaultNCActivateHandler(active); -} - -LRESULT WindowWin::OnNCCalcSize(BOOL mode, LPARAM l_param) { - // We only need to adjust the client size/paint handling when we're not using - // the native frame. - if (non_client_view_->UseNativeFrame()) - return WidgetWin::OnNCCalcSize(mode, l_param); - - RECT* client_rect = mode ? - &reinterpret_cast(l_param)->rgrc[0] : - reinterpret_cast(l_param); - if (IsMaximized()) { - // Make the maximized mode client rect fit the screen exactly, by - // subtracting the border Windows automatically adds for maximized mode. - int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); - InflateRect(client_rect, -border_thickness, -border_thickness); - - // Find all auto-hide taskbars along the screen edges and adjust in by the - // thickness of the auto-hide taskbar on each such edge, so the window isn't - // treated as a "fullscreen app", which would cause the taskbars to - // disappear. - HMONITOR monitor = MonitorFromWindow(GetNativeView(), - MONITOR_DEFAULTTONEAREST); - if (win_util::EdgeHasAutoHideTaskbar(ABE_LEFT, monitor)) - client_rect->left += win_util::kAutoHideTaskbarThicknessPx; - if (win_util::EdgeHasAutoHideTaskbar(ABE_TOP, monitor)) - client_rect->top += win_util::kAutoHideTaskbarThicknessPx; - if (win_util::EdgeHasAutoHideTaskbar(ABE_RIGHT, monitor)) - client_rect->right -= win_util::kAutoHideTaskbarThicknessPx; - if (win_util::EdgeHasAutoHideTaskbar(ABE_BOTTOM, monitor)) - client_rect->bottom -= win_util::kAutoHideTaskbarThicknessPx; - - // We cannot return WVR_REDRAW when there is nonclient area, or Windows - // exhibits bugs where client pixels and child HWNDs are mispositioned by - // the width/height of the upper-left nonclient area. - return 0; - } - - // If the window bounds change, we're going to relayout and repaint anyway. - // Returning WVR_REDRAW avoids an extra paint before that of the old client - // pixels in the (now wrong) location, and thus makes actions like resizing a - // window from the left edge look slightly less broken. - return mode ? WVR_REDRAW : 0; -} - -LRESULT WindowWin::OnNCHitTest(const CPoint& point) { - // First, give the NonClientView a chance to test the point to see if it - // provides any of the non-client area. - CPoint temp = point; - MapWindowPoints(HWND_DESKTOP, GetNativeView(), &temp, 1); - int component = non_client_view_->NonClientHitTest(gfx::Point(temp)); - if (component != HTNOWHERE) - return component; - - // Otherwise, we let Windows do all the native frame non-client handling for - // us. - return WidgetWin::OnNCHitTest(point); -} - -namespace { -struct ClipState { - // The window being painted. - HWND parent; - - // DC painting to. - HDC dc; - - // Origin of the window in terms of the screen. - int x; - int y; -}; - -// See comments in OnNCPaint for details of this function. -static BOOL CALLBACK ClipDCToChild(HWND window, LPARAM param) { - ClipState* clip_state = reinterpret_cast(param); - if (GetParent(window) == clip_state->parent && IsWindowVisible(window)) { - RECT bounds; - GetWindowRect(window, &bounds); - ExcludeClipRect(clip_state->dc, - bounds.left - clip_state->x, - bounds.top - clip_state->y, - bounds.right - clip_state->x, - bounds.bottom - clip_state->y); - } - return TRUE; -} -} // namespace - -void WindowWin::OnNCPaint(HRGN rgn) { - // We only do non-client painting if we're not using the native frame. - if (non_client_view_->UseNativeFrame()) { - WidgetWin::OnNCPaint(rgn); - return; - } - - // We have an NC region and need to paint it. We expand the NC region to - // include the dirty region of the root view. This is done to minimize - // paints. - CRect window_rect; - GetWindowRect(&window_rect); - - if (window_rect.Width() != root_view_->width() || - window_rect.Height() != root_view_->height()) { - // If the size of the window differs from the size of the root view it - // means we're being asked to paint before we've gotten a WM_SIZE. This can - // happen when the user is interactively resizing the window. To avoid - // mass flickering we don't do anything here. Once we get the WM_SIZE we'll - // reset the region of the window which triggers another WM_NCPAINT and - // all is well. - return; - } - - CRect dirty_region; - // A value of 1 indicates paint all. - if (!rgn || rgn == reinterpret_cast(1)) { - dirty_region = CRect(0, 0, window_rect.Width(), window_rect.Height()); - } else { - RECT rgn_bounding_box; - GetRgnBox(rgn, &rgn_bounding_box); - if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect)) - return; // Dirty region doesn't intersect window bounds, bale. - - // rgn_bounding_box is in screen coordinates. Map it to window coordinates. - OffsetRect(&dirty_region, -window_rect.left, -window_rect.top); - } - - // In theory GetDCEx should do what we want, but I couldn't get it to work. - // In particular the docs mentiond DCX_CLIPCHILDREN, but as far as I can tell - // it doesn't work at all. So, instead we get the DC for the window then - // manually clip out the children. - HDC dc = GetWindowDC(GetNativeView()); - ClipState clip_state; - clip_state.x = window_rect.left; - clip_state.y = window_rect.top; - clip_state.parent = GetNativeView(); - clip_state.dc = dc; - EnumChildWindows(GetNativeView(), &ClipDCToChild, - reinterpret_cast(&clip_state)); - - RootView* root_view = GetRootView(); - CRect old_paint_region = root_view->GetScheduledPaintRectConstrainedToSize(); - - if (!old_paint_region.IsRectEmpty()) { - // The root view has a region that needs to be painted. Include it in the - // region we're going to paint. - - CRect tmp = dirty_region; - UnionRect(&dirty_region, &tmp, &old_paint_region); - } - - root_view->SchedulePaint(gfx::Rect(dirty_region), false); - - // ChromeCanvasPaints destructor does the actual painting. As such, wrap the - // following in a block to force paint to occur so that we can release the dc. - { - ChromeCanvasPaint canvas(dc, opaque(), dirty_region.left, dirty_region.top, - dirty_region.Width(), dirty_region.Height()); - - root_view->ProcessPaint(&canvas); - } - - ReleaseDC(GetNativeView(), dc); -} - -void WindowWin::OnNCLButtonDown(UINT ht_component, const CPoint& point) { - // When we're using a native frame, window controls work without us - // interfering. - if (!non_client_view_->UseNativeFrame()) { - switch (ht_component) { - case HTCLOSE: - case HTMINBUTTON: - case HTMAXBUTTON: { - // When the mouse is pressed down in these specific non-client areas, - // we need to tell the RootView to send the mouse pressed event (which - // sets capture, allowing subsequent WM_LBUTTONUP (note, _not_ - // WM_NCLBUTTONUP) to fire so that the appropriate WM_SYSCOMMAND can be - // sent by the applicable button's ButtonListener. We _have_ to do this - // way rather than letting Windows just send the syscommand itself (as - // would happen if we never did this dance) because for some insane - // reason DefWindowProc for WM_NCLBUTTONDOWN also renders the pressed - // window control button appearance, in the Windows classic style, over - // our view! Ick! By handling this message we prevent Windows from - // doing this undesirable thing, but that means we need to roll the - // sys-command handling ourselves. - ProcessNCMousePress(point, MK_LBUTTON); - return; - } - } - } - - // TODO(beng): figure out why we need to run the system menu manually - // ourselves. This is wrong and causes many subtle bugs. - // From my initial research, it looks like DefWindowProc tries - // to run it but fails before sending the initial WM_MENUSELECT - // for the sysmenu. - if (ht_component == HTSYSMENU) - RunSystemMenu(non_client_view_->GetSystemMenuPoint()); - else - WidgetWin::OnNCLButtonDown(ht_component, point); - - /* TODO(beng): Fix the standard non-client over-painting bug. This code - doesn't work but identifies the problem. - if (!IsMsgHandled()) { - // WindowWin::OnNCLButtonDown set the message as unhandled. This normally - // means WidgetWin::ProcessWindowMessage will pass it to - // DefWindowProc. Sadly, DefWindowProc for WM_NCLBUTTONDOWN does weird - // non-client painting, so we need to call it directly here inside a - // scoped update lock. - ScopedRedrawLock lock(this); - DefWindowProc(GetNativeView(), WM_NCLBUTTONDOWN, ht_component, - MAKELPARAM(point.x, point.y)); - SetMsgHandled(TRUE); - } - */ -} - -void WindowWin::OnNCRButtonDown(UINT ht_component, const CPoint& point) { - if (ht_component == HTCAPTION || ht_component == HTSYSMENU) - RunSystemMenu(gfx::Point(point)); - else - WidgetWin::OnNCRButtonDown(ht_component, point); -} - -LRESULT WindowWin::OnNCUAHDrawCaption(UINT msg, WPARAM w_param, - LPARAM l_param) { - // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for - // an explanation about why we need to handle this message. - SetMsgHandled(!non_client_view_->UseNativeFrame()); - return 0; -} - -LRESULT WindowWin::OnNCUAHDrawFrame(UINT msg, WPARAM w_param, - LPARAM l_param) { - // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for - // an explanation about why we need to handle this message. - SetMsgHandled(!non_client_view_->UseNativeFrame()); - return 0; -} - -LRESULT WindowWin::OnSetCursor(HWND window, UINT hittest_code, UINT message) { - // If the window is disabled, it's because we're showing a modal dialog box. - // We need to let DefWindowProc handle the message. That's because - // DefWindowProc for WM_SETCURSOR with message = some kind of mouse button - // down message sends the top level window a WM_ACTIVATEAPP message, which we - // otherwise wouldn't get. The symptom of not doing this is that if the user - // has a window in the background with a modal dialog open, they can't click - // on the disabled background window to bring the entire stack to the front. - // This is annoying because they then have to move all the foreground windows - // out of the way to be able to activate said window. I love how on Windows, - // the answer isn't always logical. - if (!IsWindowEnabled(GetNativeView())) - return WidgetWin::OnSetCursor(window, hittest_code, message); - - int index = RC_NORMAL; - switch (hittest_code) { - case HTTOP: - case HTBOTTOM: - index = RC_VERTICAL; - break; - case HTTOPLEFT: - case HTBOTTOMRIGHT: - index = RC_NWSE; - break; - case HTTOPRIGHT: - case HTBOTTOMLEFT: - index = RC_NESW; - break; - case HTLEFT: - case HTRIGHT: - index = RC_HORIZONTAL; - break; - case HTCAPTION: - case HTCLIENT: - index = RC_NORMAL; - break; - } - SetCursor(resize_cursors_[index]); - return 0; -} - -LRESULT WindowWin::OnSetIcon(UINT size_type, HICON new_icon) { - // This shouldn't hurt even if we're using the native frame. - ScopedRedrawLock lock(this); - return DefWindowProc(GetNativeView(), WM_SETICON, size_type, - reinterpret_cast(new_icon)); -} - -LRESULT WindowWin::OnSetText(const wchar_t* text) { - // This shouldn't hurt even if we're using the native frame. - ScopedRedrawLock lock(this); - return DefWindowProc(GetNativeView(), WM_SETTEXT, NULL, - reinterpret_cast(text)); -} - -void WindowWin::OnSize(UINT size_param, const CSize& new_size) { - // Don't no-op if the new_size matches current size. If our normal bounds - // and maximized bounds are the same, then we need to layout (because we - // layout differently when maximized). - SaveWindowPosition(); - ChangeSize(size_param, new_size); - RedrawWindow(GetNativeView(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); - - // ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've - // invoked OnSize we ensure the RootView has been laid out. - ResetWindowRegion(false); -} - -void WindowWin::OnSysCommand(UINT notification_code, CPoint click) { - if (!non_client_view_->UseNativeFrame()) { - // Windows uses the 4 lower order bits of |notification_code| for type- - // specific information so we must exclude this when comparing. - static const int sc_mask = 0xFFF0; - if ((notification_code & sc_mask) == SC_MINIMIZE || - (notification_code & sc_mask) == SC_MAXIMIZE || - (notification_code & sc_mask) == SC_RESTORE) { - non_client_view_->ResetWindowControls(); - } else if ((notification_code & sc_mask) == SC_MOVE || - (notification_code & sc_mask) == SC_SIZE) { - if (lock_updates_) { - // We were locked, before entering a resize or move modal loop. Now that - // we've begun to move the window, we need to unlock updates so that the - // sizing/moving feedback can be continuous. - UnlockUpdates(); - } - } - } - - // First see if the delegate can handle it. - if (window_delegate_->ExecuteWindowsCommand(notification_code)) - return; - - if (notification_code == IDC_ALWAYS_ON_TOP) { - is_always_on_top_ = !is_always_on_top_; - - // Change the menu check state. - HMENU system_menu = GetSystemMenu(GetNativeView(), FALSE); - MENUITEMINFO menu_info; - memset(&menu_info, 0, sizeof(MENUITEMINFO)); - menu_info.cbSize = sizeof(MENUITEMINFO); - BOOL r = GetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, - FALSE, &menu_info); - DCHECK(r); - menu_info.fMask = MIIM_STATE; - if (is_always_on_top_) - menu_info.fState = MFS_CHECKED; - r = SetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, FALSE, &menu_info); - - // Now change the actual window's behavior. - AlwaysOnTopChanged(); - } else if ((notification_code == SC_KEYMENU) && (click.x == VK_SPACE)) { - // Run the system menu at the NonClientView's desired location. - RunSystemMenu(non_client_view_->GetSystemMenuPoint()); - } else { - // Use the default implementation for any other command. - DefWindowProc(GetNativeView(), WM_SYSCOMMAND, notification_code, - MAKELPARAM(click.y, click.x)); - } -} - -void WindowWin::OnWindowPosChanging(WINDOWPOS* window_pos) { - if (force_hidden_) { - // Prevent the window from being made visible if we've been asked to do so. - // See comment in header as to why we might want this. - window_pos->flags &= ~SWP_SHOWWINDOW; - } - WidgetWin::OnWindowPosChanging(window_pos); -} - -//////////////////////////////////////////////////////////////////////////////// -// WindowWin, private: - -void WindowWin::BecomeModal() { - // We implement modality by crawling up the hierarchy of windows starting - // at the owner, disabling all of them so that they don't receive input - // messages. - DCHECK(owning_hwnd_) << "Can't create a modal dialog without an owner"; - HWND start = owning_hwnd_; - while (start != NULL) { - ::EnableWindow(start, FALSE); - start = ::GetParent(start); - } -} - -void WindowWin::SetInitialFocus() { - if (!focus_on_creation_) - return; - - View* v = window_delegate_->GetInitiallyFocusedView(); - if (v) { - v->RequestFocus(); - } else { - // The window does not get keyboard messages unless we focus it, not sure - // why. - SetFocus(GetNativeView()); - } -} - -void WindowWin::SetInitialBounds(const gfx::Rect& create_bounds) { - // First we obtain the window's saved show-style and store it. We need to do - // this here, rather than in Show() because by the time Show() is called, - // the window's size will have been reset (below) and the saved maximized - // state will have been lost. Sadly there's no way to tell on Windows when - // a window is restored from maximized state, so we can't more accurately - // track maximized state independently of sizing information. - window_delegate_->GetSavedMaximizedState(&saved_maximized_state_); - - // Restore the window's placement from the controller. - gfx::Rect saved_bounds(create_bounds.ToRECT()); - if (window_delegate_->GetSavedWindowBounds(&saved_bounds)) { - // Make sure the bounds are at least the minimum size. - if (saved_bounds.width() < minimum_size_.cx) { - saved_bounds.SetRect(saved_bounds.x(), saved_bounds.y(), - saved_bounds.right() + minimum_size_.cx - - saved_bounds.width(), - saved_bounds.bottom()); - } - - if (saved_bounds.height() < minimum_size_.cy) { - saved_bounds.SetRect(saved_bounds.x(), saved_bounds.y(), - saved_bounds.right(), - saved_bounds.bottom() + minimum_size_.cy - - saved_bounds.height()); - } - - // "Show state" (maximized, minimized, etc) is handled by Show(). - // Don't use SetBounds here. SetBounds constrains to the size of the - // monitor, but we don't want that when creating a new window as the result - // of dragging out a tab to create a new window. - SetWindowPos(NULL, saved_bounds.x(), saved_bounds.y(), - saved_bounds.width(), saved_bounds.height(), 0); - } else { - if (create_bounds.IsEmpty()) { - // No initial bounds supplied, so size the window to its content and - // center over its parent. - SizeWindowToDefault(); - } else { - // Use the supplied initial bounds. - SetBounds(create_bounds); - } - } -} - -void WindowWin::InitAlwaysOnTopState() { - is_always_on_top_ = false; - if (window_delegate_->GetSavedAlwaysOnTopState(&is_always_on_top_) && - is_always_on_top_ != window_delegate_->IsAlwaysOnTop()) { - AlwaysOnTopChanged(); - } - - if (window_delegate_->HasAlwaysOnTopMenu()) - AddAlwaysOnTopSystemMenuItem(); -} - -void WindowWin::AddAlwaysOnTopSystemMenuItem() { - // The Win32 API requires that we own the text. - always_on_top_menu_text_ = l10n_util::GetString(IDS_ALWAYS_ON_TOP); - - // Let's insert a menu to the window. - HMENU system_menu = ::GetSystemMenu(GetNativeView(), FALSE); - int index = ::GetMenuItemCount(system_menu) - 1; - if (index < 0) { - // Paranoia check. - NOTREACHED(); - index = 0; - } - // First we add the separator. - MENUITEMINFO menu_info; - memset(&menu_info, 0, sizeof(MENUITEMINFO)); - menu_info.cbSize = sizeof(MENUITEMINFO); - menu_info.fMask = MIIM_FTYPE; - menu_info.fType = MFT_SEPARATOR; - ::InsertMenuItem(system_menu, index, TRUE, &menu_info); - - // Then the actual menu. - menu_info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING | MIIM_STATE; - menu_info.fType = MFT_STRING; - menu_info.fState = MFS_ENABLED; - if (is_always_on_top_) - menu_info.fState |= MFS_CHECKED; - menu_info.wID = IDC_ALWAYS_ON_TOP; - menu_info.dwTypeData = const_cast(always_on_top_menu_text_.c_str()); - ::InsertMenuItem(system_menu, index, TRUE, &menu_info); -} - -void WindowWin::RestoreEnabledIfNecessary() { - if (is_modal_ && !restored_enabled_) { - restored_enabled_ = true; - // If we were run modally, we need to undo the disabled-ness we inflicted on - // the owner's parent hierarchy. - HWND start = owning_hwnd_; - while (start != NULL) { - ::EnableWindow(start, TRUE); - start = ::GetParent(start); - } - } -} - -void WindowWin::AlwaysOnTopChanged() { - ::SetWindowPos(GetNativeView(), - is_always_on_top_ ? HWND_TOPMOST : HWND_NOTOPMOST, - 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); -} - -DWORD WindowWin::CalculateWindowStyle() { - DWORD window_styles = - WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_SYSMENU | WS_CAPTION; - bool can_resize = window_delegate_->CanResize(); - bool can_maximize = window_delegate_->CanMaximize(); - if (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 WindowWin::CalculateWindowExStyle() { - DWORD window_ex_styles = 0; - if (window_delegate_->AsDialogDelegate()) - window_ex_styles |= WS_EX_DLGMODALFRAME; - if (window_delegate_->IsAlwaysOnTop()) - window_ex_styles |= WS_EX_TOPMOST; - return window_ex_styles; -} - -void WindowWin::SaveWindowPosition() { - // The window delegate does the actual saving for us. It seems like (judging - // by go/crash) that in some circumstances we can end up here after - // WM_DESTROY, at which point the window delegate is likely gone. So just - // bail. - if (!window_delegate_) - return; - - WINDOWPLACEMENT win_placement = { 0 }; - win_placement.length = sizeof(WINDOWPLACEMENT); - - BOOL r = GetWindowPlacement(GetNativeView(), &win_placement); - DCHECK(r); - - bool maximized = (win_placement.showCmd == SW_SHOWMAXIMIZED); - CRect window_bounds(win_placement.rcNormalPosition); - window_delegate_->SaveWindowPlacement( - gfx::Rect(win_placement.rcNormalPosition), maximized, is_always_on_top_); -} - -void WindowWin::LockUpdates() { - lock_updates_ = true; - saved_window_style_ = GetWindowLong(GetNativeView(), GWL_STYLE); - SetWindowLong(GetNativeView(), GWL_STYLE, saved_window_style_ & ~WS_VISIBLE); -} - -void WindowWin::UnlockUpdates() { - SetWindowLong(GetNativeView(), GWL_STYLE, saved_window_style_); - lock_updates_ = false; -} - -void WindowWin::ResetWindowRegion(bool force) { - // A native frame uses the native window region, and we don't want to mess - // with it. - if (non_client_view_->UseNativeFrame()) { - if (force) - SetWindowRgn(NULL, TRUE); - return; - } - - // Changing the window region is going to force a paint. Only change the - // window region if the region really differs. - HRGN current_rgn = CreateRectRgn(0, 0, 0, 0); - int current_rgn_result = GetWindowRgn(GetNativeView(), current_rgn); - - CRect window_rect; - GetWindowRect(&window_rect); - HRGN new_region; - gfx::Path window_mask; - non_client_view_->GetWindowMask( - gfx::Size(window_rect.Width(), window_rect.Height()), &window_mask); - new_region = window_mask.CreateHRGN(); - - if (current_rgn_result == ERROR || !EqualRgn(current_rgn, new_region)) { - // SetWindowRgn takes ownership of the HRGN created by CreateHRGN. - SetWindowRgn(new_region, TRUE); - } else { - DeleteObject(new_region); - } - - DeleteObject(current_rgn); -} - -void WindowWin::ProcessNCMousePress(const CPoint& point, int flags) { - CPoint temp = point; - MapWindowPoints(HWND_DESKTOP, GetNativeView(), &temp, 1); - UINT message_flags = 0; - if ((GetKeyState(VK_CONTROL) & 0x80) == 0x80) - message_flags |= MK_CONTROL; - if ((GetKeyState(VK_SHIFT) & 0x80) == 0x80) - message_flags |= MK_SHIFT; - message_flags |= flags; - ProcessMousePressed(temp, message_flags, false); -} - -LRESULT WindowWin::CallDefaultNCActivateHandler(BOOL active) { - // The DefWindowProc handling for WM_NCACTIVATE renders the classic-look - // window title bar directly, so we need to use a redraw lock here to prevent - // it from doing so. - ScopedRedrawLock lock(this); - return DefWindowProc(GetNativeView(), WM_NCACTIVATE, active, 0); -} - -void WindowWin::InitClass() { - static bool initialized = false; - if (!initialized) { - resize_cursors_[RC_NORMAL] = LoadCursor(NULL, IDC_ARROW); - resize_cursors_[RC_VERTICAL] = LoadCursor(NULL, IDC_SIZENS); - resize_cursors_[RC_HORIZONTAL] = LoadCursor(NULL, IDC_SIZEWE); - resize_cursors_[RC_NESW] = LoadCursor(NULL, IDC_SIZENESW); - resize_cursors_[RC_NWSE] = LoadCursor(NULL, IDC_SIZENWSE); - initialized = true; - } -} - -} // namespace views diff --git a/chrome/views/window_win.h b/chrome/views/window_win.h deleted file mode 100644 index 7b27ee0..0000000 --- a/chrome/views/window_win.h +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright (c) 2006-2008 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_VIEWS_WINDOW_WIN_H__ -#define CHROME_VIEWS_WINDOW_WIN_H__ - -#include "chrome/common/notification_registrar.h" -#include "chrome/views/client_view.h" -#include "chrome/views/non_client_view.h" -#include "chrome/views/widget/widget_win.h" -#include "chrome/views/window.h" - -namespace gfx { -class Point; -class Size; -}; - -namespace views { - -class Client; -class WindowDelegate; - -/////////////////////////////////////////////////////////////////////////////// -// -// WindowWin -// -// A WindowWin is a WidgetWin that has a caption and a border. The frame is -// rendered by the operating system. -// -/////////////////////////////////////////////////////////////////////////////// -class WindowWin : public WidgetWin, - public Window, - public NotificationObserver { - public: - virtual ~WindowWin(); - - // Show the window with the specified show command. - void Show(int show_state); - - // Retrieve the show state of the window. This is one of the SW_SHOW* flags - // passed into Windows' ShowWindow method. For normal windows this defaults - // to SW_SHOWNORMAL, however windows (e.g. the main window) can override this - // method to provide different values (e.g. retrieve the user's specified - // show state from the shortcut starutp info). - virtual int GetShowState() const; - - // Executes the specified SC_command. - void ExecuteSystemMenuCommand(int command); - - // Accessors and setters for various properties. - HWND owning_window() const { return owning_hwnd_; } - void set_focus_on_creation(bool focus_on_creation) { - focus_on_creation_ = focus_on_creation; - } - void set_force_hidden(bool force_hidden) { force_hidden_ = force_hidden; } - - // Window overrides: - virtual gfx::Rect GetBounds() const; - virtual void SetBounds(const gfx::Rect& bounds); - virtual void SetBounds(const gfx::Rect& bounds, - gfx::NativeWindow other_window); - virtual void Show(); - virtual void Activate(); - virtual void Close(); - virtual void Maximize(); - virtual void Minimize(); - virtual void Restore(); - virtual bool IsActive() const; - virtual bool IsVisible() const; - virtual bool IsMaximized() const; - virtual bool IsMinimized() const; - virtual void EnableClose(bool enable); - virtual void DisableInactiveRendering(); - virtual void UpdateWindowTitle(); - virtual void UpdateWindowIcon(); - virtual NonClientFrameView* CreateFrameViewForWindow(); - virtual void UpdateFrameAfterFrameChange(); - virtual WindowDelegate* GetDelegate() const; - virtual NonClientView* GetNonClientView() const; - virtual ClientView* GetClientView() const; - virtual gfx::NativeWindow GetNativeWindow() const; - - // NotificationObserver overrides: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - protected: - friend Window; - - // Constructs the WindowWin. |window_delegate| cannot be NULL. - explicit WindowWin(WindowDelegate* window_delegate); - - // Create the Window. - // If parent is NULL, this WindowWin is top level on the desktop. - // If |bounds| is empty, the view is queried for its preferred size and - // centered on screen. - virtual void Init(HWND parent, const gfx::Rect& bounds); - - // Sizes the window to the default size specified by its ClientView. - virtual void SizeWindowToDefault(); - - // Returns true if the WindowWin is considered to be an "app window" - i.e. - // any window which when it is the last of its type closed causes the - // application to exit. - virtual bool IsAppWindow() const { return false; } - - // Shows the system menu at the specified screen point. - void RunSystemMenu(const gfx::Point& point); - - // Overridden from WidgetWin: - virtual void OnActivate(UINT action, BOOL minimized, HWND window); - virtual void OnActivateApp(BOOL active, DWORD thread_id); - virtual LRESULT OnAppCommand(HWND window, short app_command, WORD device, - int keystate); - virtual void OnCommand(UINT notification_code, int command_id, HWND window); - virtual void OnDestroy(); - virtual LRESULT OnDwmCompositionChanged(UINT msg, WPARAM w_param, - LPARAM l_param); - virtual void OnFinalMessage(HWND window); - virtual void OnInitMenu(HMENU menu); - virtual void OnMouseLeave(); - virtual LRESULT OnNCActivate(BOOL active); - virtual LRESULT OnNCCalcSize(BOOL mode, LPARAM l_param); - virtual LRESULT OnNCHitTest(const CPoint& point); - virtual void OnNCPaint(HRGN rgn); - virtual void OnNCLButtonDown(UINT ht_component, const CPoint& point); - virtual void OnNCRButtonDown(UINT ht_component, const CPoint& point); - virtual LRESULT OnNCUAHDrawCaption(UINT msg, WPARAM w_param, LPARAM l_param); - virtual LRESULT OnNCUAHDrawFrame(UINT msg, WPARAM w_param, LPARAM l_param); - virtual LRESULT OnSetCursor(HWND window, UINT hittest_code, UINT message); - virtual LRESULT OnSetIcon(UINT size_type, HICON new_icon); - virtual LRESULT OnSetText(const wchar_t* text); - virtual void OnSize(UINT size_param, const CSize& new_size); - virtual void OnSysCommand(UINT notification_code, CPoint click); - virtual void OnWindowPosChanging(WINDOWPOS* window_pos); - virtual Window* AsWindow() { return this; } - virtual const Window* AsWindow() const { return this; } - - // Accessor for disable_inactive_rendering_. - bool disable_inactive_rendering() const { - return disable_inactive_rendering_; - } - - private: - // Set the window as modal (by disabling all the other windows). - void BecomeModal(); - - // Sets-up the focus manager with the view that should have focus when the - // window is shown the first time. If NULL is returned, the focus goes to the - // button if there is one, otherwise the to the Cancel button. - void SetInitialFocus(); - - // Place and size the window when it is created. |create_bounds| are the - // bounds used when the window was created. - void SetInitialBounds(const gfx::Rect& create_bounds); - - // Restore saved always on stop state and add the always on top system menu - // if needed. - void InitAlwaysOnTopState(); - - // Add an item for "Always on Top" to the System Menu. - void AddAlwaysOnTopSystemMenuItem(); - - // If necessary, enables all ancestors. - void RestoreEnabledIfNecessary(); - - // Update the window style to reflect the always on top state. - void AlwaysOnTopChanged(); - - // Calculate the appropriate window styles for this window. - DWORD CalculateWindowStyle(); - DWORD CalculateWindowExStyle(); - - // Asks the delegate if any to save the window's location and size. - void SaveWindowPosition(); - - // Lock or unlock the window from being able to redraw itself in response to - // updates to its invalid region. - class ScopedRedrawLock; - void LockUpdates(); - void UnlockUpdates(); - - // Resets the window region for the current window bounds if necessary. - // If |force| is true, the window region is reset to NULL even for native - // frame windows. - void ResetWindowRegion(bool force); - - // Converts a non-client mouse down message to a regular ChromeViews event - // and handle it. |point| is the mouse position of the message in screen - // coords. |flags| are flags that would be passed with a WM_L/M/RBUTTON* - // message and relate to things like which button was pressed. These are - // combined with flags relating to the current key state. - void ProcessNCMousePress(const CPoint& point, int flags); - - // Calls the default WM_NCACTIVATE handler with the specified activation - // value, safely wrapping the call in a ScopedRedrawLock to prevent frame - // flicker. - LRESULT CallDefaultNCActivateHandler(BOOL active); - - // Static resource initialization. - static void InitClass(); - enum ResizeCursor { - RC_NORMAL = 0, RC_VERTICAL, RC_HORIZONTAL, RC_NESW, RC_NWSE - }; - static HCURSOR resize_cursors_[6]; - - // Our window delegate (see Init method for documentation). - WindowDelegate* window_delegate_; - - // The View that provides the non-client area of the window (title bar, - // window controls, sizing borders etc). To use an implementation other than - // the default, this class must be subclassed and this value set to the - // desired implementation before calling |Init|. - NonClientView* non_client_view_; - - // Whether we should SetFocus() on a newly created window after - // Init(). Defaults to true. - bool focus_on_creation_; - - // We need to save the parent window that spawned us, since GetParent() - // returns NULL for dialogs. - HWND owning_hwnd_; - - // The smallest size the window can be. - CSize minimum_size_; - - // Whether or not the window is modal. This comes from the delegate and is - // cached at Init time to avoid calling back to the delegate from the - // destructor. - bool is_modal_; - - // Whether all ancestors have been enabled. This is only used if is_modal_ is - // true. - bool restored_enabled_; - - // Whether the window is currently always on top. - bool is_always_on_top_; - - // We need to own the text of the menu, the Windows API does not copy it. - std::wstring always_on_top_menu_text_; - - // Set to true if the window is in the process of closing . - bool window_closed_; - - // True when the window should be rendered as active, regardless of whether - // or not it actually is. - bool disable_inactive_rendering_; - - // True if this window is the active top level window. - bool is_active_; - - // True if updates to this window are currently locked. - bool lock_updates_; - - // The window styles of the window before updates were locked. - DWORD saved_window_style_; - - // The saved maximized state for this window. See note in SetInitialBounds - // that explains why we save this. - bool saved_maximized_state_; - - // True if we should prevent attempts to make the window visible when we - // handle WM_WINDOWPOSCHANGING. Some calls like ShowWindow(SW_RESTORE) make - // the window visible in addition to restoring it, when all we want to do is - // restore it. - bool force_hidden_; - - // Hold onto notifications. - NotificationRegistrar notification_registrar_; - - DISALLOW_COPY_AND_ASSIGN(WindowWin); -}; - -} // namespace views - -#endif // CHROME_VIEWS_WINDOW_WIN_H__ -- cgit v1.1