summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authormsw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-19 21:41:39 +0000
committermsw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-19 21:41:39 +0000
commit7894b78eafb59d0cd5a9138db8d72315637b9fb7 (patch)
tree3662f5b280d869cc5e1c664a3f3bc1ae45624481 /ui
parente0281af2fe7687aa615a8a4c5bb621767c6cd111 (diff)
downloadchromium_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.cc139
-rw-r--r--ui/views/examples/widget_example.h22
-rw-r--r--ui/views/views.gyp2
-rw-r--r--ui/views/window/dialog_client_view.cc47
-rw-r--r--ui/views/window/dialog_client_view.h30
-rw-r--r--ui/views/window/dialog_delegate.cc33
-rw-r--r--ui/views/window/dialog_delegate.h15
-rw-r--r--ui/views/window/dialog_frame_view.cc189
-rw-r--r--ui/views/window/dialog_frame_view.h62
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 &params)
+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 &params);
+ 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_