dialog_delegate.cc revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ui/views/window/dialog_delegate.h"
6
7#include "base/logging.h"
8#include "grit/ui_strings.h"
9#include "ui/base/l10n/l10n_util.h"
10#include "ui/base/ui_base_switches_util.h"
11#include "ui/views/bubble/bubble_border.h"
12#include "ui/views/bubble/bubble_frame_view.h"
13#include "ui/views/controls/button/label_button.h"
14#include "ui/views/controls/textfield/textfield.h"
15#include "ui/views/widget/widget.h"
16#include "ui/views/widget/widget_observer.h"
17#include "ui/views/window/dialog_client_view.h"
18
19#if defined(USE_AURA)
20#include "ui/views/corewm/shadow_types.h"
21#endif
22
23namespace views {
24
25////////////////////////////////////////////////////////////////////////////////
26// DialogDelegate:
27
28DialogDelegate::~DialogDelegate() {
29}
30
31// static
32bool DialogDelegate::UseNewStyle() {
33  return switches::IsNewDialogStyleEnabled() &&
34         Textfield::IsViewsTextfieldEnabled();
35}
36
37// static
38Widget* DialogDelegate::CreateDialogWidget(DialogDelegate* dialog,
39                                           gfx::NativeWindow context,
40                                           gfx::NativeWindow parent) {
41  views::Widget* widget = new views::Widget;
42  views::Widget::InitParams params;
43  params.delegate = dialog;
44  const bool use_new_style = dialog ?
45      dialog->UseNewStyleForThisDialog() : DialogDelegate::UseNewStyle();
46  if (use_new_style) {
47    // Note: Transparent widgets cannot host native Windows textfield controls.
48    params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW;
49    params.remove_standard_frame = true;
50  }
51  params.context = context;
52  params.parent = parent;
53  params.top_level = true;
54  widget->Init(params);
55  if (use_new_style) {
56#if defined(USE_AURA)
57    // TODO(msw): Add a matching shadow type and remove the bubble frame border?
58    corewm::SetShadowType(widget->GetNativeWindow(), corewm::SHADOW_TYPE_NONE);
59#endif
60  }
61  return widget;
62}
63
64View* DialogDelegate::CreateExtraView() {
65  return NULL;
66}
67
68View* DialogDelegate::CreateTitlebarExtraView() {
69  return NULL;
70}
71
72View* DialogDelegate::CreateFootnoteView() {
73  return NULL;
74}
75
76bool DialogDelegate::Cancel() {
77  return true;
78}
79
80bool DialogDelegate::Accept(bool window_closing) {
81  return Accept();
82}
83
84bool DialogDelegate::Accept() {
85  return true;
86}
87
88base::string16 DialogDelegate::GetDialogLabel() const {
89  return base::string16();
90}
91
92base::string16 DialogDelegate::GetDialogTitle() const {
93  return base::string16();
94}
95
96int DialogDelegate::GetDialogButtons() const {
97  return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
98}
99
100int DialogDelegate::GetDefaultDialogButton() const {
101  if (GetDialogButtons() & ui::DIALOG_BUTTON_OK)
102    return ui::DIALOG_BUTTON_OK;
103  if (GetDialogButtons() & ui::DIALOG_BUTTON_CANCEL)
104    return ui::DIALOG_BUTTON_CANCEL;
105  return ui::DIALOG_BUTTON_NONE;
106}
107
108bool DialogDelegate::ShouldDefaultButtonBeBlue() const {
109  return false;
110}
111
112base::string16 DialogDelegate::GetDialogButtonLabel(
113    ui::DialogButton button) const {
114  if (button == ui::DIALOG_BUTTON_OK)
115    return l10n_util::GetStringUTF16(IDS_APP_OK);
116  if (button == ui::DIALOG_BUTTON_CANCEL) {
117    if (GetDialogButtons() & ui::DIALOG_BUTTON_OK)
118      return l10n_util::GetStringUTF16(IDS_APP_CANCEL);
119    return l10n_util::GetStringUTF16(IDS_APP_CLOSE);
120  }
121  NOTREACHED();
122  return base::string16();
123}
124
125bool DialogDelegate::IsDialogButtonEnabled(ui::DialogButton button) const {
126  return true;
127}
128
129View* DialogDelegate::GetInitiallyFocusedView() {
130  // Focus the default button if any.
131  const DialogClientView* dcv = GetDialogClientView();
132  int default_button = GetDefaultDialogButton();
133  if (default_button == ui::DIALOG_BUTTON_NONE)
134    return NULL;
135
136  if ((default_button & GetDialogButtons()) == 0) {
137    // The default button is a button we don't have.
138    NOTREACHED();
139    return NULL;
140  }
141
142  if (default_button & ui::DIALOG_BUTTON_OK)
143    return dcv->ok_button();
144  if (default_button & ui::DIALOG_BUTTON_CANCEL)
145    return dcv->cancel_button();
146  return NULL;
147}
148
149DialogDelegate* DialogDelegate::AsDialogDelegate() {
150  return this;
151}
152
153ClientView* DialogDelegate::CreateClientView(Widget* widget) {
154  return new DialogClientView(widget, GetContentsView());
155}
156
157NonClientFrameView* DialogDelegate::CreateNonClientFrameView(Widget* widget) {
158  if (UseNewStyleForThisDialog())
159    return CreateNewStyleFrameView(widget);
160  return WidgetDelegate::CreateNonClientFrameView(widget);
161}
162
163// static
164NonClientFrameView* DialogDelegate::CreateNewStyleFrameView(Widget* widget) {
165  return CreateNewStyleFrameView(widget, false);
166}
167
168NonClientFrameView* DialogDelegate::CreateNewStyleFrameView(
169    Widget* widget,
170    bool force_opaque_border) {
171  BubbleFrameView* frame = new BubbleFrameView(gfx::Insets());
172  const SkColor color = widget->GetNativeTheme()->GetSystemColor(
173      ui::NativeTheme::kColorId_DialogBackground);
174  if (force_opaque_border) {
175    frame->SetBubbleBorder(new BubbleBorder(
176        BubbleBorder::NONE,
177        BubbleBorder::NO_SHADOW_OPAQUE_BORDER,
178        color));
179  } else {
180    frame->SetBubbleBorder(new BubbleBorder(BubbleBorder::FLOAT,
181                                            BubbleBorder::SMALL_SHADOW,
182                                            color));
183  }
184  frame->SetTitle(widget->widget_delegate()->GetWindowTitle());
185  DialogDelegate* delegate = widget->widget_delegate()->AsDialogDelegate();
186  if (delegate) {
187    View* titlebar_view = delegate->CreateTitlebarExtraView();
188    if (titlebar_view)
189      frame->SetTitlebarExtraView(titlebar_view);
190  }
191  frame->SetShowCloseButton(widget->widget_delegate()->ShouldShowCloseButton());
192  if (force_opaque_border)
193    widget->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM);
194  return frame;
195}
196
197bool DialogDelegate::UseNewStyleForThisDialog() const {
198  return UseNewStyle();
199}
200
201const DialogClientView* DialogDelegate::GetDialogClientView() const {
202  return GetWidget()->client_view()->AsDialogClientView();
203}
204
205DialogClientView* DialogDelegate::GetDialogClientView() {
206  return GetWidget()->client_view()->AsDialogClientView();
207}
208
209ui::AccessibilityTypes::Role DialogDelegate::GetAccessibleWindowRole() const {
210  return ui::AccessibilityTypes::ROLE_DIALOG;
211}
212
213////////////////////////////////////////////////////////////////////////////////
214// DialogDelegateView:
215
216DialogDelegateView::DialogDelegateView() {
217  // A WidgetDelegate should be deleted on DeleteDelegate.
218  set_owned_by_client();
219}
220
221DialogDelegateView::~DialogDelegateView() {}
222
223void DialogDelegateView::DeleteDelegate() {
224  delete this;
225}
226
227Widget* DialogDelegateView::GetWidget() {
228  return View::GetWidget();
229}
230
231const Widget* DialogDelegateView::GetWidget() const {
232  return View::GetWidget();
233}
234
235View* DialogDelegateView::GetContentsView() {
236  return this;
237}
238
239}  // namespace views
240