diff options
author | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-19 21:41:39 +0000 |
---|---|---|
committer | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-19 21:41:39 +0000 |
commit | 7894b78eafb59d0cd5a9138db8d72315637b9fb7 (patch) | |
tree | 3662f5b280d869cc5e1c664a3f3bc1ae45624481 /ui | |
parent | e0281af2fe7687aa615a8a4c5bb621767c6cd111 (diff) | |
download | chromium_src-7894b78eafb59d0cd5a9138db8d72315637b9fb7.zip chromium_src-7894b78eafb59d0cd5a9138db8d72315637b9fb7.tar.gz chromium_src-7894b78eafb59d0cd5a9138db8d72315637b9fb7.tar.bz2 |
Move ash/wm's DialogFrameView to ui/views/window; etc.
Move ash/wm/dialog_frame_view.[h|cc] to ui/views/window/.
Move DialogFrameView to views namespace; export; cleanup.
Expose static DialogDelegate::UseNewStyle() for commandline flag.
OVERRIDE DialogDelegate::CreateNonClientFrameView to use DialogFrameView with flag.
OVERRIDE DialogDelegateView::GetContentsView to return |this|.
(nix redundant GetContentsView() OVERRIDEs from subclasses)
Cleanup DialogClientView ctor; encapsulate StyleParams struct.
Rewrite WidgetExample; nix transparency, add dialog widget, consolidate.
BUG=166075
TEST=views_examples WidgetExample changes with --enabled-new-dialog-style
R=sky@chromium.org
Review URL: https://chromiumcodereview.appspot.com/11571023
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@173993 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/views/examples/widget_example.cc | 139 | ||||
-rw-r--r-- | ui/views/examples/widget_example.h | 22 | ||||
-rw-r--r-- | ui/views/views.gyp | 2 | ||||
-rw-r--r-- | ui/views/window/dialog_client_view.cc | 47 | ||||
-rw-r--r-- | ui/views/window/dialog_client_view.h | 30 | ||||
-rw-r--r-- | ui/views/window/dialog_delegate.cc | 33 | ||||
-rw-r--r-- | ui/views/window/dialog_delegate.h | 15 | ||||
-rw-r--r-- | ui/views/window/dialog_frame_view.cc | 189 | ||||
-rw-r--r-- | ui/views/window/dialog_frame_view.h | 62 |
9 files changed, 351 insertions, 188 deletions
diff --git a/ui/views/examples/widget_example.cc b/ui/views/examples/widget_example.cc index f3ab572..112f57a 100644 --- a/ui/views/examples/widget_example.cc +++ b/ui/views/examples/widget_example.cc @@ -7,39 +7,12 @@ #include "base/utf_string_conversions.h" #include "ui/views/controls/button/text_button.h" #include "ui/views/layout/box_layout.h" -#include "ui/views/layout/layout_manager.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" +#include "ui/views/window/dialog_delegate.h" namespace views { namespace examples { -namespace { - -// A layout manager that layouts a single child at -// the center of the host view. -class CenterLayout : public LayoutManager { - public: - CenterLayout() {} - virtual ~CenterLayout() {} - - // Overridden from LayoutManager: - virtual void Layout(View* host) { - View* child = host->child_at(0); - gfx::Size size = child->GetPreferredSize(); - child->SetBounds((host->width() - size.width()) / 2, - (host->height() - size.height()) / 2, - size.width(), size.height()); - } - - virtual gfx::Size GetPreferredSize(View* host) { - return gfx::Size(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(CenterLayout); -}; - -} // namespace WidgetExample::WidgetExample() : ExampleBase("Widget") { } @@ -48,19 +21,12 @@ WidgetExample::~WidgetExample() { } void WidgetExample::CreateExampleView(View* container) { - container->SetLayoutManager( - new BoxLayout(BoxLayout::kHorizontal, 0, 0, 2)); - BuildButton(container, "Create a popup widget", POPUP); - BuildButton(container, "Create a transparent popup widget", - TRANSPARENT_POPUP); + container->SetLayoutManager(new BoxLayout(BoxLayout::kHorizontal, 0, 0, 2)); + BuildButton(container, "Popup widget", POPUP); + BuildButton(container, "Dialog widget", DIALOG); #if defined(OS_LINUX) - View* vert_container = new View(); - container->AddChildView(vert_container); - vert_container->SetLayoutManager( - new BoxLayout(BoxLayout::kVertical, 0, 0, 20)); - BuildButton(vert_container, "Create a child widget", CHILD); - BuildButton(vert_container, "Create a transparent child widget", - TRANSPARENT_CHILD); + // Windows does not support TYPE_CONTROL top-level widgets. + BuildButton(container, "Child widget", CHILD); #endif } @@ -72,92 +38,41 @@ void WidgetExample::BuildButton(View* container, container->AddChildView(button); } -void WidgetExample::InitWidget(Widget* widget, bool transparent) { - // Add view/native buttons to close the popup widget. - TextButton* close_button = new TextButton( - this, ASCIIToUTF16("Close")); - close_button->set_tag(CLOSE_WIDGET); - // TODO(oshima): support transparent native view. - NativeTextButton* native_button = new NativeTextButton( - this, ASCIIToUTF16("Native Close")); - native_button->set_tag(CLOSE_WIDGET); - - View* button_container = new View(); - button_container->SetLayoutManager( - new BoxLayout(BoxLayout::kHorizontal, 0, 0, 1)); - button_container->AddChildView(close_button); - button_container->AddChildView(native_button); - - View* widget_container = new View(); - widget_container->SetLayoutManager(new CenterLayout); - widget_container->AddChildView(button_container); +void WidgetExample::ShowWidget(View* sender, Widget::InitParams params) { + // Setup shared Widget heirarchy and bounds parameters. + params.parent = sender->GetWidget()->GetNativeView(); + params.bounds = gfx::Rect(sender->GetBoundsInScreen().CenterPoint(), + gfx::Size(200, 100)); - widget->SetContentsView(widget_container); + Widget* widget = new Widget(); + widget->Init(params); - if (!transparent) { - widget_container->set_background( - Background::CreateStandardPanelBackground()); + // If the Widget has no contents by default, add a view with a 'Close' button. + if (!widget->GetContentsView()) { + View* contents = new View(); + contents->SetLayoutManager(new BoxLayout(BoxLayout::kHorizontal, 0, 0, 0)); + contents->set_background(Background::CreateSolidBackground(SK_ColorGRAY)); + BuildButton(contents, "Close", CLOSE_WIDGET); + widget->SetContentsView(contents); } - // Show the widget. widget->Show(); } -#if defined(OS_LINUX) -void WidgetExample::CreateChild(View* parent, bool transparent) { - Widget* widget = new Widget; - // Compute where to place the child widget. - // We'll place it at the center of the root widget. - Widget* parent_widget = parent->GetWidget(); - gfx::Rect bounds = parent_widget->GetClientAreaBoundsInScreen(); - // Child widget is 200x200 square. - bounds.SetRect((bounds.width() - 200) / 2, (bounds.height() - 200) / 2, - 200, 200); - // Initialize the child widget with the computed bounds. - Widget::InitParams params(Widget::InitParams::TYPE_CONTROL); - params.transparent = transparent; - params.parent = parent_widget->GetNativeView(); - widget->Init(params); - InitWidget(widget, transparent); -} -#endif - -void WidgetExample::CreatePopup(View* parent, bool transparent) { - Widget* widget = new Widget; - - // Compute where to place the popup widget. - // We'll place it right below the create button. - gfx::Point point = parent->GetMirroredPosition(); - // The position in point is relative to the parent. Make it absolute. - View::ConvertPointToScreen(parent, &point); - // Add the height of create_button_. - point.Offset(0, parent->size().height()); - - // Initialize the popup widget with the computed bounds. - Widget::InitParams params(Widget::InitParams::TYPE_POPUP); - params.transparent = transparent; - params.parent = parent->GetWidget()->GetNativeView(); - params.bounds = gfx::Rect(point.x(), point.y(), 200, 300); - widget->Init(params); - InitWidget(widget, transparent); -} - void WidgetExample::ButtonPressed(Button* sender, const ui::Event& event) { switch (sender->tag()) { case POPUP: - CreatePopup(sender, false); + ShowWidget(sender, Widget::InitParams(Widget::InitParams::TYPE_POPUP)); break; - case TRANSPARENT_POPUP: - CreatePopup(sender, true); + case DIALOG: { + Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); + params.delegate = new DialogDelegateView(); + ShowWidget(sender, params); break; -#if defined(OS_LINUX) + } case CHILD: - CreateChild(sender, false); + ShowWidget(sender, Widget::InitParams(Widget::InitParams::TYPE_CONTROL)); break; - case TRANSPARENT_CHILD: - CreateChild(sender, true); - break; -#endif case CLOSE_WIDGET: sender->GetWidget()->Close(); break; diff --git a/ui/views/examples/widget_example.h b/ui/views/examples/widget_example.h index 88a8c42..7c3085e 100644 --- a/ui/views/examples/widget_example.h +++ b/ui/views/examples/widget_example.h @@ -9,7 +9,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" -#include "ui/views/controls/button/text_button.h" +#include "ui/views/controls/button/button.h" #include "ui/views/examples/example_base.h" #include "ui/views/widget/widget.h" @@ -26,23 +26,19 @@ class WidgetExample : public ExampleBase, public ButtonListener { virtual void CreateExampleView(View* container) OVERRIDE; private: + // Button tags used to identify various commands. enum Command { - POPUP, - CHILD, - TRANSPARENT_POPUP, - TRANSPARENT_CHILD, - CLOSE_WIDGET, + POPUP, // Show a popup widget. + DIALOG, // Show a dialog widget. + CHILD, // Show a child widget. + CLOSE_WIDGET, // Close the sender button's widget. }; + // Construct a button with the specified |label| and |tag| in |container|. void BuildButton(View* container, const std::string& label, int tag); - void InitWidget(Widget* widget, bool transparent); - -#if defined(OS_LINUX) - void CreateChild(View* parent, bool transparent); -#endif - - void CreatePopup(View* parent, bool transparent); + // Construct a Widget for |sender|, initialize with |params|, and call Show(). + void ShowWidget(View* sender, Widget::InitParams params); // Overridden from ButtonListener: virtual void ButtonPressed(Button* sender, const ui::Event& event) OVERRIDE; diff --git a/ui/views/views.gyp b/ui/views/views.gyp index 8a7bf0f..4ece2f1 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp @@ -430,6 +430,8 @@ 'window/dialog_client_view.h', 'window/dialog_delegate.cc', 'window/dialog_delegate.h', + 'window/dialog_frame_view.cc', + 'window/dialog_frame_view.h', 'window/frame_background.cc', 'window/frame_background.h', 'window/native_frame_view.cc', diff --git a/ui/views/window/dialog_client_view.cc b/ui/views/window/dialog_client_view.cc index b9bbc19..df2c83b 100644 --- a/ui/views/window/dialog_client_view.cc +++ b/ui/views/window/dialog_client_view.cc @@ -113,19 +113,8 @@ template <> const char DialogButton<TextButton>::kViewClassName[] = /////////////////////////////////////////////////////////////////////////////// // DialogClientView, public: -DialogClientView::StyleParams::StyleParams() - : button_vedge_margin(kButtonVEdgeMargin), - button_hedge_margin(kButtonHEdgeMargin), - button_shadow_margin(0), - button_content_spacing(kDialogButtonContentSpacing), - related_button_hspacing(kRelatedButtonHSpacing) { -} - -DialogClientView::DialogClientView(Widget* owner, - View* contents_view, - const StyleParams ¶ms) +DialogClientView::DialogClientView(Widget* owner, View* contents_view) : ClientView(owner, contents_view), - style_params_(params), ok_button_(NULL), cancel_button_(NULL), default_button_(NULL), @@ -194,7 +183,7 @@ void DialogClientView::OnWillChangeFocus(View* focused_before, // change once we move completely to Chrome style. See // http://codereview.chromium.org/10230 for a rough idea of changes to be // undone. - if (GetDialogDelegate()->UseChromeStyle()) + if (DialogDelegate::UseNewStyle()) return; TextButton* new_default_button = NULL; @@ -260,17 +249,6 @@ void DialogClientView::CancelWindow() { Close(); } -// static -DialogClientView::StyleParams DialogClientView::GetChromeStyleParams() { - StyleParams params; - params.button_vedge_margin = 0; - params.button_hedge_margin = 0; - params.button_shadow_margin = views::GetChromeStyleButtonShadowMargin(); - params.button_content_spacing = 0; - params.related_button_hspacing = 10; - return params; -} - int DialogClientView::GetBottomMargin() { return style_params_.button_shadow_margin; } @@ -418,15 +396,30 @@ void DialogClientView::ButtonPressed(Button* sender, const ui::Event& event) { //////////////////////////////////////////////////////////////////////////////// // DialogClientView, private: +DialogClientView::StyleParams::StyleParams() + : button_vedge_margin(kButtonVEdgeMargin), + button_hedge_margin(kButtonHEdgeMargin), + button_shadow_margin(0), + button_content_spacing(kDialogButtonContentSpacing), + related_button_hspacing(kRelatedButtonHSpacing) { + if (DialogDelegate::UseNewStyle()) { + button_vedge_margin = 0; + button_hedge_margin = 0; + button_shadow_margin = GetChromeStyleButtonShadowMargin(); + button_content_spacing = 0; + related_button_hspacing = 10; + } +} + TextButton* DialogClientView::CreateDialogButton(ui::DialogButton type, const string16& title) { TextButton* button = NULL; - if (GetDialogDelegate()->UseChromeStyle()) + if (DialogDelegate::UseNewStyle()) button = new DialogButton<TextButton>(this, GetWidget(), type, title); else button = new DialogButton<NativeTextButton>(this, GetWidget(), type, title); - if (!GetDialogDelegate()->UseChromeStyle()) + if (!DialogDelegate::UseNewStyle()) button->set_min_width(kDialogMinButtonWidth); button->SetGroup(kButtonGroup); @@ -436,7 +429,7 @@ TextButton* DialogClientView::CreateDialogButton(ui::DialogButton type, button->SetIsDefault(true); } - if (GetDialogDelegate()->UseChromeStyle()) + if (DialogDelegate::UseNewStyle()) ApplyChromeStyle(button); return button; diff --git a/ui/views/window/dialog_client_view.h b/ui/views/window/dialog_client_view.h index 97c0d9b..6550819 100644 --- a/ui/views/window/dialog_client_view.h +++ b/ui/views/window/dialog_client_view.h @@ -35,21 +35,7 @@ class VIEWS_EXPORT DialogClientView : public ClientView, public ButtonListener, public FocusChangeListener { public: - // Parameters for the internal dialog styling. Default construction - // produces parameters for native dialog styling. - struct VIEWS_EXPORT StyleParams { - StyleParams(); - - int button_vedge_margin; - int button_hedge_margin; - int button_shadow_margin; - int button_content_spacing; - int related_button_hspacing; - }; - - DialogClientView(Widget* widget, - View* contents_view, - const StyleParams ¶ms); + DialogClientView(Widget* widget, View* contents_view); virtual ~DialogClientView(); // Adds the dialog buttons required by the supplied DialogDelegate to the @@ -70,9 +56,6 @@ class VIEWS_EXPORT DialogClientView : public ClientView, TextButton* ok_button() const { return ok_button_; } TextButton* cancel_button() const { return cancel_button_; } - // Creates a StyleParams struct in Chrome style (default is native style). - static StyleParams GetChromeStyleParams(); - // Returns the number of pixels at the bottom of the dialog which are visually // part of the frame, but are actually rendered by the DialogClientView. int GetBottomMargin(); @@ -110,6 +93,17 @@ class VIEWS_EXPORT DialogClientView : public ClientView, const ui::Event& event) OVERRIDE; private: + // Parameters for the internal dialog styling. + struct StyleParams { + StyleParams(); + + int button_vedge_margin; + int button_hedge_margin; + int button_shadow_margin; + int button_content_spacing; + int related_button_hspacing; + }; + // Create a dialog button of the appropriate type. TextButton* CreateDialogButton(ui::DialogButton type, const string16& title); diff --git a/ui/views/window/dialog_delegate.cc b/ui/views/window/dialog_delegate.cc index 9f005d8..6ee2e43 100644 --- a/ui/views/window/dialog_delegate.cc +++ b/ui/views/window/dialog_delegate.cc @@ -4,21 +4,29 @@ #include "ui/views/window/dialog_delegate.h" +#include "base/command_line.h" #include "base/logging.h" +#include "ui/base/ui_base_switches.h" #include "ui/views/controls/button/text_button.h" #include "ui/views/widget/widget.h" #include "ui/views/window/dialog_client_view.h" +#include "ui/views/window/dialog_frame_view.h" namespace views { //////////////////////////////////////////////////////////////////////////////// // DialogDelegate: -DialogDelegate* DialogDelegate::AsDialogDelegate() { return this; } - DialogDelegate::~DialogDelegate() { } +// static +bool DialogDelegate::UseNewStyle() { + static const bool use_new_style = CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableNewDialogStyle); + return use_new_style; +} + int DialogDelegate::GetDialogButtons() const { return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL; } @@ -45,10 +53,6 @@ bool DialogDelegate::IsDialogButtonVisible(ui::DialogButton button) const { return true; } -bool DialogDelegate::UseChromeStyle() const { - return false; -} - bool DialogDelegate::AreAcceleratorsEnabled(ui::DialogButton button) { return true; } @@ -93,12 +97,17 @@ View* DialogDelegate::GetInitiallyFocusedView() { return NULL; } +DialogDelegate* DialogDelegate::AsDialogDelegate() { + return this; +} + ClientView* DialogDelegate::CreateClientView(Widget* widget) { - DialogClientView::StyleParams params = UseChromeStyle() ? - DialogClientView::GetChromeStyleParams() : - DialogClientView::StyleParams(); + return new DialogClientView(widget, GetContentsView()); +} - return new DialogClientView(widget, GetContentsView(), params); +NonClientFrameView* DialogDelegate::CreateNonClientFrameView(Widget* widget) { + return UseNewStyle() ? new DialogFrameView() : + WidgetDelegate::CreateNonClientFrameView(widget); } const DialogClientView* DialogDelegate::GetDialogClientView() const { @@ -130,4 +139,8 @@ const Widget* DialogDelegateView::GetWidget() const { return View::GetWidget(); } +View* DialogDelegateView::GetContentsView() { + return this; +} + } // namespace views diff --git a/ui/views/window/dialog_delegate.h b/ui/views/window/dialog_delegate.h index 59319c0..67eb954 100644 --- a/ui/views/window/dialog_delegate.h +++ b/ui/views/window/dialog_delegate.h @@ -14,7 +14,6 @@ namespace views { class DialogClientView; -class View; /////////////////////////////////////////////////////////////////////////////// // @@ -28,10 +27,11 @@ class View; /////////////////////////////////////////////////////////////////////////////// class VIEWS_EXPORT DialogDelegate : public WidgetDelegate { public: - virtual DialogDelegate* AsDialogDelegate() OVERRIDE; - virtual ~DialogDelegate(); + // Returns whether to use the new dialog style. + static bool UseNewStyle(); + // 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 @@ -58,10 +58,6 @@ class VIEWS_EXPORT DialogDelegate : public WidgetDelegate { // Returns whether the specified dialog button is visible. virtual bool IsDialogButtonVisible(ui::DialogButton button) const; - // Returns whether to use chrome style for the button strip (like WebUI). If - // false, native style padding is used. - virtual bool UseChromeStyle() const; - // Returns whether accelerators are enabled on the button. This is invoked // when an accelerator is pressed, not at construction time. This // returns true. @@ -95,9 +91,11 @@ class VIEWS_EXPORT DialogDelegate : public WidgetDelegate { virtual bool Accept(bool window_closing); virtual bool Accept(); - // Overridden from WindowDelegate: + // Overridden from WidgetDelegate: virtual View* GetInitiallyFocusedView() OVERRIDE; + virtual DialogDelegate* AsDialogDelegate() OVERRIDE; virtual ClientView* CreateClientView(Widget* widget) OVERRIDE; + virtual NonClientFrameView* CreateNonClientFrameView(Widget* widget) OVERRIDE; // Called when the window has been closed. virtual void OnClose() {} @@ -124,6 +122,7 @@ class VIEWS_EXPORT DialogDelegateView : public DialogDelegate, // Overridden from DialogDelegate: virtual Widget* GetWidget() OVERRIDE; virtual const Widget* GetWidget() const OVERRIDE; + virtual View* GetContentsView() OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(DialogDelegateView); diff --git a/ui/views/window/dialog_frame_view.cc b/ui/views/window/dialog_frame_view.cc new file mode 100644 index 0000000..06706d7 --- /dev/null +++ b/ui/views/window/dialog_frame_view.cc @@ -0,0 +1,189 @@ +// Copyright (c) 2012 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 "ui/views/window/dialog_frame_view.h" + +#include "grit/ui_resources.h" +#include "ui/base/hit_test.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/font.h" +#include "ui/gfx/image/image.h" +#include "ui/gfx/insets.h" +#include "ui/views/background.h" +#include "ui/views/border.h" +#include "ui/views/controls/button/image_button.h" +#include "ui/views/widget/widget.h" +#include "ui/views/widget/widget_delegate.h" + +namespace { + +// TODO(benrg): Make frame shadow and stroke agree with the spec. + +// TODO(benrg): Title bar text should be #222, not black. Text in the client +// area should also be #222, but is currently usually black. Punting on this +// until the overhaul of color handling that will be happening Real Soon Now. +const SkColor kDialogTitleColor = SK_ColorBLACK; +const SkColor kDialogBackgroundColor = SK_ColorWHITE; + +// Dialog-size-dependent padding values from the spec, in pixels. +const int kGoogleSmallDialogVPadding = 16; +const int kGoogleSmallDialogHPadding = 20; +const int kGoogleMediumDialogVPadding = 28; +const int kGoogleMediumDialogHPadding = 32; +const int kGoogleLargeDialogVPadding = 30; +const int kGoogleLargeDialogHPadding = 42; + +// Dialog layouts themselves contain some padding, which should be ignored in +// favor of the padding values above. Currently we hack it by nudging the +// client area outward. +const int kDialogHPaddingNudge = 13; +const int kDialogTopPaddingNudge = 5; +const int kDialogBottomPaddingNudge = 10; + +// TODO(benrg): There are no examples in the spec of close boxes on medium- or +// small-size dialogs, and the close button size is not factored into other +// sizing decisions. This value could cause problems with smaller dialogs. +const int kCloseButtonSize = 44; + +} // namespace + +namespace views { + +// static +const char DialogFrameView::kViewClassName[] = "ui/views/DialogFrameView"; + +//////////////////////////////////////////////////////////////////////////////// +// DialogFrameView, public: + +DialogFrameView::DialogFrameView() { + set_background(Background::CreateSolidBackground(kDialogBackgroundColor)); + + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + title_font_.reset(new gfx::Font(rb.GetFont(ui::ResourceBundle::MediumFont))); + close_button_ = new views::ImageButton(this); + close_button_->SetImage(views::CustomButton::STATE_NORMAL, + rb.GetImageNamed(IDR_CLOSE_BAR).ToImageSkia()); + close_button_->SetImage(CustomButton::STATE_HOVERED, + rb.GetImageNamed(IDR_CLOSE_BAR_H).ToImageSkia()); + close_button_->SetImage(CustomButton::STATE_PRESSED, + rb.GetImageNamed(IDR_CLOSE_BAR_P).ToImageSkia()); + close_button_->SetImageAlignment(ImageButton::ALIGN_CENTER, + ImageButton::ALIGN_MIDDLE); + AddChildView(close_button_); +} + +DialogFrameView::~DialogFrameView() { +} + +//////////////////////////////////////////////////////////////////////////////// +// DialogFrameView, NonClientFrameView: + +gfx::Rect DialogFrameView::GetBoundsForClientView() const { + gfx::Rect client_bounds = GetLocalBounds(); + client_bounds.Inset(GetClientInsets()); + return client_bounds; +} + +gfx::Rect DialogFrameView::GetWindowBoundsForClientBounds( + const gfx::Rect& client_bounds) const { + gfx::Rect window_bounds = client_bounds; + window_bounds.Inset(-GetClientInsets()); + return window_bounds; +} + +int DialogFrameView::NonClientHitTest(const gfx::Point& point) { + if (close_button_->GetMirroredBounds().Contains(point)) + return HTCLOSE; + return point.y() < GetClientInsets().top() ? HTCAPTION : HTCLIENT; +} + +void DialogFrameView::GetWindowMask(const gfx::Size& size, + gfx::Path* window_mask) { + // Nothing to do. +} + +void DialogFrameView::ResetWindowControls() { + // Nothing to do. +} + +void DialogFrameView::UpdateWindowIcon() { + // Nothing to do. +} + +void DialogFrameView::UpdateWindowTitle() { + // Nothing to do. +} + +//////////////////////////////////////////////////////////////////////////////// +// DialogFrameView, View overrides: + +std::string DialogFrameView::GetClassName() const { + return kViewClassName; +} + +void DialogFrameView::Layout() { + title_display_rect_ = GetLocalBounds(); + title_display_rect_.Inset(GetPaddingInsets()); + title_display_rect_.set_height(title_font_->GetHeight()); + + // The hot rectangle for the close button is flush with the upper right of the + // dialog. The close button image is smaller, and is centered in the hot rect. + close_button_->SetBounds( + width() - kCloseButtonSize, + 0, kCloseButtonSize, kCloseButtonSize); +} + +void DialogFrameView::OnPaint(gfx::Canvas* canvas) { + View::OnPaint(canvas); + WidgetDelegate* delegate = GetWidget()->widget_delegate(); + if (!delegate) + return; + canvas->DrawStringInt(delegate->GetWindowTitle(), *title_font_.get(), + kDialogTitleColor, title_display_rect_); +} + +//////////////////////////////////////////////////////////////////////////////// +// DialogFrameView, ButtonListener overrides: + +void DialogFrameView::ButtonPressed(Button* sender, const ui::Event& event) { + if (sender == close_button_) + GetWidget()->Close(); +} + +//////////////////////////////////////////////////////////////////////////////// +// DialogFrameView, private: + +gfx::Insets DialogFrameView::GetPaddingInsets() const { + // These three discrete padding sizes come from the spec. If we ever wanted + // our Google-style dialogs to be resizable, we would probably need to + // smoothly interpolate the padding size instead. + int v_padding, h_padding; + if (width() <= 280) { + v_padding = kGoogleSmallDialogVPadding; + h_padding = kGoogleSmallDialogHPadding; + } else if (width() <= 480) { + v_padding = kGoogleMediumDialogVPadding; + h_padding = kGoogleMediumDialogHPadding; + } else { + v_padding = kGoogleLargeDialogVPadding; + h_padding = kGoogleLargeDialogHPadding; + } + return gfx::Insets(v_padding, h_padding, v_padding, h_padding); +} + +gfx::Insets DialogFrameView::GetClientInsets() const { + gfx::Insets insets = GetPaddingInsets(); + // The title should be separated from the client area by 1 em (dialog spec), + // and one em is equal to the font size (CSS spec). + insets += gfx::Insets( + title_font_->GetHeight() + title_font_->GetFontSize() - + kDialogTopPaddingNudge, + -kDialogHPaddingNudge, + -kDialogBottomPaddingNudge, + -kDialogHPaddingNudge); + return insets; +} + +} // namespace views diff --git a/ui/views/window/dialog_frame_view.h b/ui/views/window/dialog_frame_view.h new file mode 100644 index 0000000..78ca0ed --- /dev/null +++ b/ui/views/window/dialog_frame_view.h @@ -0,0 +1,62 @@ +// Copyright (c) 2012 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 UI_VIEWS_WINDOW_DIALOG_FRAME_VIEW_H_ +#define UI_VIEWS_WINDOW_DIALOG_FRAME_VIEW_H_ + +#include "ui/views/controls/button/button.h" +#include "ui/views/window/non_client_view.h" + +namespace gfx { +class Font; +} + +namespace views { + +class ImageButton; + +// A NonClientFrameView that implements a new-style for dialogs. +class VIEWS_EXPORT DialogFrameView : public NonClientFrameView, + public ButtonListener { + public: + // Internal class name. + static const char kViewClassName[]; + + DialogFrameView(); + virtual ~DialogFrameView(); + + // Overridden from NonClientFrameView: + virtual gfx::Rect GetBoundsForClientView() const OVERRIDE; + virtual gfx::Rect GetWindowBoundsForClientBounds( + const gfx::Rect& client_bounds) const OVERRIDE; + virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE; + virtual void GetWindowMask(const gfx::Size& size, + gfx::Path* window_mask) OVERRIDE; + virtual void ResetWindowControls() OVERRIDE; + virtual void UpdateWindowIcon() OVERRIDE; + virtual void UpdateWindowTitle() OVERRIDE; + + // Overridden from View: + virtual std::string GetClassName() const OVERRIDE; + virtual void Layout() OVERRIDE; + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + + // Overridden from ButtonListener: + virtual void ButtonPressed(Button* sender, const ui::Event& event) OVERRIDE; + + private: + gfx::Insets GetPaddingInsets() const; + gfx::Insets GetClientInsets() const; + + scoped_ptr<gfx::Font> title_font_; + gfx::Rect title_display_rect_; + + ImageButton* close_button_; + + DISALLOW_COPY_AND_ASSIGN(DialogFrameView); +}; + +} // namespace views + +#endif // UI_VIEWS_WINDOW_DIALOG_FRAME_VIEW_H_ |