diff options
-rw-r--r-- | chrome/browser/chromeos/options/options_window_view.cc | 302 | ||||
-rw-r--r-- | chrome/browser/chromeos/options/options_window_view.h | 16 | ||||
-rw-r--r-- | chrome/browser/gtk/options/options_window_gtk.cc | 4 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 6 | ||||
-rw-r--r-- | views/controls/native/native_view_host.cc | 10 | ||||
-rw-r--r-- | views/controls/tabbed_pane/tabbed_pane.h | 4 | ||||
-rw-r--r-- | views/window/custom_frame_view.cc | 15 | ||||
-rw-r--r-- | views/window/custom_frame_view.h | 5 | ||||
-rw-r--r-- | views/window/window_delegate.h | 5 |
9 files changed, 361 insertions, 6 deletions
diff --git a/chrome/browser/chromeos/options/options_window_view.cc b/chrome/browser/chromeos/options/options_window_view.cc new file mode 100644 index 0000000..2f7a7bd --- /dev/null +++ b/chrome/browser/chromeos/options/options_window_view.cc @@ -0,0 +1,302 @@ +// Copyright (c) 2010 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/browser/options_window.h" + +#include "app/l10n_util.h" +#include "app/resource_bundle.h" +#include "base/scoped_ptr.h" +#include "chrome/browser/browser_list.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_window.h" +#include "chrome/browser/chromeos/options/internet_page_view.h" +#include "chrome/browser/chromeos/options/system_page_view.h" +#include "chrome/browser/gtk/options/advanced_page_gtk.h" +#include "chrome/browser/gtk/options/content_page_gtk.h" +#include "chrome/browser/gtk/options/general_page_gtk.h" +#include "chrome/browser/pref_service.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/window_sizer.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/pref_names.h" +#include "grit/chromium_strings.h" +#include "grit/generated_resources.h" +#include "grit/locale_settings.h" +#include "views/controls/native/native_view_host.h" +#include "views/controls/tabbed_pane/native_tabbed_pane_gtk.h" +#include "views/controls/tabbed_pane/tabbed_pane.h" +#include "views/widget/root_view.h" +#include "views/window/dialog_delegate.h" +#include "views/window/window.h" +#include "views/window/window_gtk.h" + + +namespace chromeos { + +/////////////////////////////////////////////////////////////////////////////// +// OptionsWindowView +// +// The contents of the Options dialog window. +// +class OptionsWindowView : public views::View, + public views::DialogDelegate, + public views::TabbedPane::Listener { + public: + static const int kDialogPadding; + static const SkColor kDialogBackground; + static OptionsWindowView* instance_; + + explicit OptionsWindowView(Profile* profile); + virtual ~OptionsWindowView(); + + // Shows the Tab corresponding to the specified OptionsPage. + void ShowOptionsPage(OptionsPage page, OptionsGroup highlight_group); + + // views::DialogDelegate implementation: + virtual int GetDialogButtons() const { + return 0; + } + virtual std::wstring GetWindowTitle() const; + virtual void WindowClosing(); + virtual bool Cancel(); + virtual views::View* GetContentsView(); + virtual bool ShouldShowClientEdge() const { + return false; + } + + // views::TabbedPane::Listener implementation: + virtual void TabSelectedAt(int index); + + // views::View overrides: + virtual void Layout(); + virtual gfx::Size GetPreferredSize(); + + protected: + // views::View overrides: + virtual void ViewHierarchyChanged(bool is_add, + views::View* parent, + views::View* child); + private: + // Init the assorted Tabbed pages + void Init(); + + // Returns the currently selected OptionsPageView. + OptionsPageView* GetCurrentOptionsPageView() const; + + // Flag of whether we are fully initialized. + bool initialized_; + + // The Tab view that contains all of the options pages. + views::TabbedPane* tabs_; + + // The Profile associated with these options. + Profile* profile_; + + // Native Gtk options pages. + GeneralPageGtk general_page_; + ContentPageGtk content_page_; + AdvancedPageGtk advanced_page_; + + // The last page the user was on when they opened the Options window. + IntegerPrefMember last_selected_page_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(OptionsWindowView); +}; + +/////////////////////////////////////////////////////////////////////////////// +// OptionsWindowView, public: + +// No dialog padding. +const int OptionsWindowView::kDialogPadding = 0; + +// Shaded frame color that matches the rendered frame. It's the result +// of SRC_OVER frame top center image on top of frame color. +const SkColor OptionsWindowView::kDialogBackground = + SkColorSetRGB(0x4E, 0x7D, 0xD0); + +// Live instance of the options view. +OptionsWindowView* OptionsWindowView::instance_ = NULL; + +OptionsWindowView::OptionsWindowView(Profile* profile) + // Always show preferences for the original profile. Most state when off + // the record comes from the original profile, but we explicitly use + // the original profile to avoid potential problems. + : initialized_(false), + tabs_(NULL), + profile_(profile->GetOriginalProfile()), + general_page_(profile_), + content_page_(profile_), + advanced_page_(profile_) { + // We don't need to observe changes in this value. + last_selected_page_.Init(prefs::kOptionsWindowLastTabIndex, + g_browser_process->local_state(), NULL); + + set_background(views::Background::CreateSolidBackground(kDialogBackground)); +} + +OptionsWindowView::~OptionsWindowView() { +} + +void OptionsWindowView::ShowOptionsPage(OptionsPage page, + OptionsGroup highlight_group) { + // This will show invisible windows and bring visible windows to the front. + window()->Show(); + + if (page == OPTIONS_PAGE_DEFAULT) { + // Remember the last visited page from local state. + page = static_cast<OptionsPage>(last_selected_page_.GetValue()); + if (page == OPTIONS_PAGE_DEFAULT) + page = OPTIONS_PAGE_GENERAL; + } + // If the page number is out of bounds, reset to the first tab. + if (page < 0 || page >= tabs_->GetTabCount()) + page = OPTIONS_PAGE_GENERAL; + + tabs_->SelectTabAt(static_cast<int>(page)); + + // TODO(xiyuan): set highlight_group +} + +/////////////////////////////////////////////////////////////////////////////// +// OptionsWindowView, views::DialogDelegate implementation: + +std::wstring OptionsWindowView::GetWindowTitle() const { + return l10n_util::GetStringF(IDS_OPTIONS_DIALOG_TITLE, + l10n_util::GetString(IDS_PRODUCT_NAME)); +} + +void OptionsWindowView::WindowClosing() { + // Clear the static instance so that the next time ShowOptionsWindow() is + // called a new window is opened. + instance_ = NULL; +} + +bool OptionsWindowView::Cancel() { + return GetCurrentOptionsPageView()->CanClose(); +} + +views::View* OptionsWindowView::GetContentsView() { + return this; +} + +/////////////////////////////////////////////////////////////////////////////// +// OptionsWindowView, views::TabbedPane::Listener implementation: + +void OptionsWindowView::TabSelectedAt(int index) { + if (!initialized_) + return; + + DCHECK(index > OPTIONS_PAGE_DEFAULT && index < OPTIONS_PAGE_COUNT); + last_selected_page_.SetValue(index); +} + +/////////////////////////////////////////////////////////////////////////////// +// OptionsWindowView, views::View overrides: + +void OptionsWindowView::Layout() { + tabs_->SetBounds(kDialogPadding, kDialogPadding, + width() - (2 * kDialogPadding), + height() - (2 * kDialogPadding)); +} + +gfx::Size OptionsWindowView::GetPreferredSize() { + return gfx::Size(views::Window::GetLocalizedContentsSize( + IDS_OPTIONS_DIALOG_WIDTH_CHARS, + IDS_OPTIONS_DIALOG_HEIGHT_LINES)); +} + +void OptionsWindowView::ViewHierarchyChanged(bool is_add, + views::View* parent, + views::View* child) { + // Can't init before we're inserted into a Container, because we require a + // HWND to parent native child controls to. + if (is_add && child == this) + Init(); +} + +/////////////////////////////////////////////////////////////////////////////// +// OptionsWindowView, private: + +void OptionsWindowView::Init() { + tabs_ = new views::TabbedPane; + tabs_->SetListener(this); + AddChildView(tabs_); + + // Set vertical padding of tab header. + GtkWidget* notebook = static_cast<views::NativeTabbedPaneGtk*>( + tabs_->native_wrapper())->native_view(); + gtk_notebook_set_tab_vborder(GTK_NOTEBOOK(notebook), 5); + + // Setup tab pages. + int tab_index = 0; + + SystemPageView* system_page = new SystemPageView(profile_); + tabs_->AddTabAtIndex(tab_index++, + l10n_util::GetString(IDS_OPTIONS_SYSTEM_TAB_LABEL), + system_page, false); + + InternetPageView* internet_page = new InternetPageView(profile_); + tabs_->AddTabAtIndex(tab_index++, + l10n_util::GetString(IDS_OPTIONS_INTERNET_TAB_LABEL), + internet_page, false); + + views::NativeViewHost* general_page_view = new views::NativeViewHost(); + tabs_->AddTabAtIndex(tab_index++, + l10n_util::GetString(IDS_OPTIONS_GENERAL_TAB_LABEL), + general_page_view, false); + general_page_view->Attach(general_page_.get_page_widget()); + + views::NativeViewHost* content_page_view = new views::NativeViewHost(); + tabs_->AddTabAtIndex(tab_index++, + l10n_util::GetString(IDS_OPTIONS_CONTENT_TAB_LABEL), + content_page_view, false); + content_page_view->Attach(content_page_.get_page_widget()); + + views::NativeViewHost* advanced_page_view = new views::NativeViewHost(); + tabs_->AddTabAtIndex(tab_index++, + l10n_util::GetString(IDS_OPTIONS_ADVANCED_TAB_LABEL), + advanced_page_view, false); + advanced_page_view->Attach(advanced_page_.get_page_widget()); + + DCHECK(tabs_->GetTabCount() == OPTIONS_PAGE_COUNT); + + initialized_ = true; +} + +OptionsPageView* OptionsWindowView::GetCurrentOptionsPageView() const { + return static_cast<OptionsPageView*>(tabs_->GetSelectedTab()); +} + +gfx::NativeWindow GetOptionsViewParent() { + if (Browser* b = BrowserList::GetLastActive()) + return b->window()->GetNativeHandle(); + + return NULL; +} + +}; // namespace chromeos + +/////////////////////////////////////////////////////////////////////////////// +// Factory/finder method: + +void ShowOptionsWindow(OptionsPage page, + OptionsGroup highlight_group, + Profile* profile) { + DCHECK(profile); + + using chromeos::OptionsWindowView; + + // If there's already an existing options window, close it and create + // a new one for the current active browser. + if (OptionsWindowView::instance_) + OptionsWindowView::instance_->window()->Close(); + + OptionsWindowView::instance_ = new OptionsWindowView(profile); + views::Window::CreateChromeWindow(chromeos::GetOptionsViewParent(), + gfx::Rect(), + OptionsWindowView::instance_); + + OptionsWindowView::instance_->ShowOptionsPage(page, highlight_group); +} + diff --git a/chrome/browser/chromeos/options/options_window_view.h b/chrome/browser/chromeos/options/options_window_view.h new file mode 100644 index 0000000..abcc6ae --- /dev/null +++ b/chrome/browser/chromeos/options/options_window_view.h @@ -0,0 +1,16 @@ +// Copyright (c) 2010 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_CHROMEOS_OPTIONS_OPTIONS_WINDOW_VIEW_H_ +#define CHROME_BROWSER_CHROMEOS_OPTIONS_OPTIONS_WINDOW_VIEW_H_ + +namespace chromeos { + +// Get a proper parent for options dialogs. This returns the last active browser +// window for now. +gfx::NativeWindow GetOptionsViewParent(); + +} + +#endif // CHROME_BROWSER_CHROMEOS_OPTIONS_OPTIONS_WINDOW_VIEW_H_ diff --git a/chrome/browser/gtk/options/options_window_gtk.cc b/chrome/browser/gtk/options/options_window_gtk.cc index 5bd2409..80b82f4 100644 --- a/chrome/browser/gtk/options/options_window_gtk.cc +++ b/chrome/browser/gtk/options/options_window_gtk.cc @@ -235,6 +235,9 @@ void OptionsWindowGtk::OnWindowDestroy(GtkWidget* widget, /////////////////////////////////////////////////////////////////////////////// // Factory/finder method: +#if !defined(OS_CHROMEOS) +// ShowOptionsWindow for non ChromeOS build. For ChromeOS build, see +// chrome/browser/chromeos/options/options_window_view.h void ShowOptionsWindow(OptionsPage page, OptionsGroup highlight_group, Profile* profile) { @@ -256,3 +259,4 @@ void ShowOptionsWindow(OptionsPage page, } options_window->ShowOptionsPage(page, highlight_group); } +#endif // !defined(OS_CHROMEOS) diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 08663f8..dfad823 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -408,8 +408,8 @@ 'browser/chromeos/login/rounded_rect_painter.cc', 'browser/chromeos/login/rounded_rect_painter.h', 'browser/chromeos/login/screen_observer.h', - 'browser/chromeos/login/update_screen.cc', - 'browser/chromeos/login/update_screen.h', + 'browser/chromeos/login/update_screen.cc', + 'browser/chromeos/login/update_screen.h', 'browser/chromeos/login/update_view.cc', 'browser/chromeos/login/update_view.h', 'browser/chromeos/login/user_controller.cc', @@ -438,6 +438,8 @@ 'browser/chromeos/options/language_hangul_config_view.h', 'browser/chromeos/options/network_config_view.cc', 'browser/chromeos/options/network_config_view.h', + 'browser/chromeos/options/options_window_view.cc', + 'browser/chromeos/options/options_window_view.h', 'browser/chromeos/options/settings_page_view.cc', 'browser/chromeos/options/settings_page_view.h', 'browser/chromeos/options/system_page_view.cc', diff --git a/views/controls/native/native_view_host.cc b/views/controls/native/native_view_host.cc index bf6dd7f..91f34c1 100644 --- a/views/controls/native/native_view_host.cc +++ b/views/controls/native/native_view_host.cc @@ -113,6 +113,16 @@ void NativeViewHost::Layout() { } void NativeViewHost::Paint(gfx::Canvas* canvas) { + // Paint background if there is one. NativeViewHost needs to paint + // a background when it is hosted in a TabbedPane. For Gtk implementation, + // NativeTabbedPaneGtk uses a WidgetGtk as page container and because + // WidgetGtk hook "expose" with its root view's paint, we need to + // fill the content. Otherwise, the tab page's background is not properly + // cleared. For Windows case, it appears okay to not paint background because + // we don't have a container window in-between. However if you want to use + // customized background, then this becomes necessary. + PaintBackground(canvas); + // The area behind our window is black, so during a fast resize (where our // content doesn't draw over the full size of our native view, and the native // view background color doesn't show up), we need to cover that blackness diff --git a/views/controls/tabbed_pane/tabbed_pane.h b/views/controls/tabbed_pane/tabbed_pane.h index abbb9fa..2fe503e 100644 --- a/views/controls/tabbed_pane/tabbed_pane.h +++ b/views/controls/tabbed_pane/tabbed_pane.h @@ -73,6 +73,10 @@ class TabbedPane : public View { virtual void PaintFocusBorder(gfx::Canvas* canvas); virtual bool GetAccessibleRole(AccessibilityTypes::Role* role); + NativeTabbedPaneWrapper* native_wrapper() const { + return native_tabbed_pane_; + } + protected: // The object that actually implements the tabbed-pane. // Protected for tests access. diff --git a/views/window/custom_frame_view.cc b/views/window/custom_frame_view.cc index 8bdb3c4..e67a5c2 100644 --- a/views/window/custom_frame_view.cc +++ b/views/window/custom_frame_view.cc @@ -70,6 +70,7 @@ CustomFrameView::CustomFrameView(Window* frame) ALLOW_THIS_IN_INITIALIZER_LIST(minimize_button_(new ImageButton(this))), window_icon_(NULL), should_show_minmax_buttons_(false), + should_show_client_edge_(false), frame_(frame) { InitClass(); @@ -112,6 +113,7 @@ CustomFrameView::CustomFrameView(Window* frame) views::WindowDelegate* d = frame_->GetDelegate(); should_show_minmax_buttons_ = d->CanMaximize(); + should_show_client_edge_ = d->ShouldShowClientEdge(); if (d->ShouldShowWindowIcon()) { window_icon_ = new ImageButton(this); @@ -212,7 +214,7 @@ void CustomFrameView::Paint(gfx::Canvas* canvas) { else PaintRestoredFrameBorder(canvas); PaintTitleBar(canvas); - if (!frame_->IsMaximized()) + if (ShouldShowClientEdge()) PaintRestoredClientEdge(canvas); } @@ -253,7 +255,7 @@ int CustomFrameView::FrameBorderThickness() const { int CustomFrameView::NonClientBorderThickness() const { // In maximized mode, we don't show a client edge. return FrameBorderThickness() + - (frame_->IsMaximized() ? 0 : kClientEdgeThickness); + (ShouldShowClientEdge() ? kClientEdgeThickness : 0); } int CustomFrameView::NonClientTopBorderHeight() const { @@ -270,7 +272,7 @@ int CustomFrameView::CaptionButtonY() const { int CustomFrameView::TitlebarBottomThickness() const { return kTitlebarTopAndBottomEdgeThickness + - (frame_->IsMaximized() ? 0 : kClientEdgeThickness); + (ShouldShowClientEdge() ? kClientEdgeThickness : 0); } int CustomFrameView::IconSize() const { @@ -283,6 +285,10 @@ int CustomFrameView::IconSize() const { #endif } +bool CustomFrameView::ShouldShowClientEdge() const { + return should_show_client_edge_ && !frame_->IsMaximized(); +} + gfx::Rect CustomFrameView::IconBounds() const { int size = IconSize(); int frame_thickness = FrameBorderThickness(); @@ -390,7 +396,8 @@ void CustomFrameView::PaintMaximizedFrameBorder(gfx::Canvas* canvas) { // 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 = rb.GetBitmapNamed(IDR_APP_TOP_CENTER); - int edge_height = titlebar_bottom->height() - kClientEdgeThickness; + int edge_height = titlebar_bottom->height() - + ShouldShowClientEdge() ? kClientEdgeThickness : 0; canvas->TileImageInt(*titlebar_bottom, 0, frame_->GetClientView()->y() - edge_height, width(), edge_height); } diff --git a/views/window/custom_frame_view.h b/views/window/custom_frame_view.h index 5bb01a8..814a7a8 100644 --- a/views/window/custom_frame_view.h +++ b/views/window/custom_frame_view.h @@ -79,6 +79,10 @@ class CustomFrameView : public NonClientFrameView, // there was one). gfx::Rect IconBounds() const; + // Returns true if the client edge should be drawn. This is true if + // the window delegate wants a client edge and we are not maxmized. + bool ShouldShowClientEdge() const; + // Paint various sub-components of this view. void PaintRestoredFrameBorder(gfx::Canvas* canvas); void PaintMaximizedFrameBorder(gfx::Canvas* canvas); @@ -103,6 +107,7 @@ class CustomFrameView : public NonClientFrameView, ImageButton* minimize_button_; ImageButton* window_icon_; bool should_show_minmax_buttons_; + bool should_show_client_edge_; // The window that owns this view. Window* frame_; diff --git a/views/window/window_delegate.h b/views/window/window_delegate.h index a5a3e24..91491b9 100644 --- a/views/window/window_delegate.h +++ b/views/window/window_delegate.h @@ -68,6 +68,11 @@ class WindowDelegate { return true; } + // Returns true if the window's client view wants a client edge. + virtual bool ShouldShowClientEdge() const { + return true; + } + // Returns the app icon for the window. On Windows, this is the ICON_BIG used // in Alt-Tab list and Win7's taskbar. virtual SkBitmap GetWindowAppIcon(); |