Home | History | Annotate | Download | only in window
      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/views/bubble/bubble_border.h"
     11 #include "ui/views/bubble/bubble_frame_view.h"
     12 #include "ui/views/controls/button/label_button.h"
     13 #include "ui/views/widget/widget.h"
     14 #include "ui/views/widget/widget_observer.h"
     15 #include "ui/views/window/dialog_client_view.h"
     16 
     17 #if defined(OS_WIN)
     18 #include "ui/base/win/shell.h"
     19 #endif
     20 
     21 namespace views {
     22 
     23 ////////////////////////////////////////////////////////////////////////////////
     24 // DialogDelegate:
     25 
     26 DialogDelegate::DialogDelegate() : supports_new_style_(true) {
     27 }
     28 
     29 DialogDelegate::~DialogDelegate() {
     30 }
     31 
     32 // static
     33 Widget* DialogDelegate::CreateDialogWidget(WidgetDelegate* delegate,
     34                                            gfx::NativeView context,
     35                                            gfx::NativeView parent) {
     36   views::Widget* widget = new views::Widget;
     37   views::Widget::InitParams params;
     38   params.delegate = delegate;
     39   DialogDelegate* dialog = delegate->AsDialogDelegate();
     40 
     41 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
     42   // The new style doesn't support unparented dialogs on Linux desktop.
     43   if (dialog)
     44     dialog->supports_new_style_ &= parent != NULL;
     45 #elif defined(OS_WIN)
     46   // The new style doesn't support unparented dialogs on Windows Classic themes.
     47   if (dialog && !ui::win::IsAeroGlassEnabled())
     48     dialog->supports_new_style_ &= parent != NULL;
     49 #endif
     50 
     51   if (!dialog || dialog->UseNewStyleForThisDialog()) {
     52     params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW;
     53     params.remove_standard_frame = true;
     54     // The bubble frame includes its own shadow; remove any native shadowing.
     55     params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE;
     56   }
     57   params.context = context;
     58   params.parent = parent;
     59   // Web-modal (ui::MODAL_TYPE_CHILD) dialogs with parents are marked as child
     60   // widgets to prevent top-level window behavior (independent movement, etc).
     61   params.child = parent && (delegate->GetModalType() == ui::MODAL_TYPE_CHILD);
     62   widget->Init(params);
     63   return widget;
     64 }
     65 
     66 View* DialogDelegate::CreateExtraView() {
     67   return NULL;
     68 }
     69 
     70 View* DialogDelegate::CreateTitlebarExtraView() {
     71   return NULL;
     72 }
     73 
     74 View* DialogDelegate::CreateFootnoteView() {
     75   return NULL;
     76 }
     77 
     78 bool DialogDelegate::Cancel() {
     79   return true;
     80 }
     81 
     82 bool DialogDelegate::Accept(bool window_closing) {
     83   return Accept();
     84 }
     85 
     86 bool DialogDelegate::Accept() {
     87   return true;
     88 }
     89 
     90 bool DialogDelegate::Close() {
     91   int buttons = GetDialogButtons();
     92   if ((buttons & ui::DIALOG_BUTTON_CANCEL) ||
     93       (buttons == ui::DIALOG_BUTTON_NONE)) {
     94     return Cancel();
     95   }
     96   return Accept(true);
     97 }
     98 
     99 base::string16 DialogDelegate::GetDialogLabel() const {
    100   return base::string16();
    101 }
    102 
    103 base::string16 DialogDelegate::GetDialogTitle() const {
    104   return GetWindowTitle();
    105 }
    106 
    107 int DialogDelegate::GetDialogButtons() const {
    108   return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
    109 }
    110 
    111 int DialogDelegate::GetDefaultDialogButton() const {
    112   if (GetDialogButtons() & ui::DIALOG_BUTTON_OK)
    113     return ui::DIALOG_BUTTON_OK;
    114   if (GetDialogButtons() & ui::DIALOG_BUTTON_CANCEL)
    115     return ui::DIALOG_BUTTON_CANCEL;
    116   return ui::DIALOG_BUTTON_NONE;
    117 }
    118 
    119 bool DialogDelegate::ShouldDefaultButtonBeBlue() const {
    120   return false;
    121 }
    122 
    123 base::string16 DialogDelegate::GetDialogButtonLabel(
    124     ui::DialogButton button) const {
    125   if (button == ui::DIALOG_BUTTON_OK)
    126     return l10n_util::GetStringUTF16(IDS_APP_OK);
    127   if (button == ui::DIALOG_BUTTON_CANCEL) {
    128     if (GetDialogButtons() & ui::DIALOG_BUTTON_OK)
    129       return l10n_util::GetStringUTF16(IDS_APP_CANCEL);
    130     return l10n_util::GetStringUTF16(IDS_APP_CLOSE);
    131   }
    132   NOTREACHED();
    133   return base::string16();
    134 }
    135 
    136 bool DialogDelegate::IsDialogButtonEnabled(ui::DialogButton button) const {
    137   return true;
    138 }
    139 
    140 View* DialogDelegate::GetInitiallyFocusedView() {
    141   // Focus the default button if any.
    142   const DialogClientView* dcv = GetDialogClientView();
    143   int default_button = GetDefaultDialogButton();
    144   if (default_button == ui::DIALOG_BUTTON_NONE)
    145     return NULL;
    146 
    147   if ((default_button & GetDialogButtons()) == 0) {
    148     // The default button is a button we don't have.
    149     NOTREACHED();
    150     return NULL;
    151   }
    152 
    153   if (default_button & ui::DIALOG_BUTTON_OK)
    154     return dcv->ok_button();
    155   if (default_button & ui::DIALOG_BUTTON_CANCEL)
    156     return dcv->cancel_button();
    157   return NULL;
    158 }
    159 
    160 DialogDelegate* DialogDelegate::AsDialogDelegate() {
    161   return this;
    162 }
    163 
    164 ClientView* DialogDelegate::CreateClientView(Widget* widget) {
    165   return new DialogClientView(widget, GetContentsView());
    166 }
    167 
    168 NonClientFrameView* DialogDelegate::CreateNonClientFrameView(Widget* widget) {
    169   if (UseNewStyleForThisDialog())
    170     return CreateDialogFrameView(widget);
    171   return WidgetDelegate::CreateNonClientFrameView(widget);
    172 }
    173 
    174 // static
    175 NonClientFrameView* DialogDelegate::CreateDialogFrameView(Widget* widget) {
    176   BubbleFrameView* frame = new BubbleFrameView(gfx::Insets());
    177   scoped_ptr<BubbleBorder> border(new BubbleBorder(
    178       BubbleBorder::FLOAT, BubbleBorder::SMALL_SHADOW, SK_ColorRED));
    179   border->set_use_theme_background_color(true);
    180   frame->SetBubbleBorder(border.Pass());
    181   DialogDelegate* delegate = widget->widget_delegate()->AsDialogDelegate();
    182   if (delegate) {
    183     View* titlebar_view = delegate->CreateTitlebarExtraView();
    184     if (titlebar_view)
    185       frame->SetTitlebarExtraView(titlebar_view);
    186   }
    187   return frame;
    188 }
    189 
    190 bool DialogDelegate::UseNewStyleForThisDialog() const {
    191   return supports_new_style_;
    192 }
    193 
    194 const DialogClientView* DialogDelegate::GetDialogClientView() const {
    195   return GetWidget()->client_view()->AsDialogClientView();
    196 }
    197 
    198 DialogClientView* DialogDelegate::GetDialogClientView() {
    199   return GetWidget()->client_view()->AsDialogClientView();
    200 }
    201 
    202 ui::AXRole DialogDelegate::GetAccessibleWindowRole() const {
    203   return ui::AX_ROLE_DIALOG;
    204 }
    205 
    206 ////////////////////////////////////////////////////////////////////////////////
    207 // DialogDelegateView:
    208 
    209 DialogDelegateView::DialogDelegateView() {
    210   // A WidgetDelegate should be deleted on DeleteDelegate.
    211   set_owned_by_client();
    212 }
    213 
    214 DialogDelegateView::~DialogDelegateView() {}
    215 
    216 void DialogDelegateView::DeleteDelegate() {
    217   delete this;
    218 }
    219 
    220 Widget* DialogDelegateView::GetWidget() {
    221   return View::GetWidget();
    222 }
    223 
    224 const Widget* DialogDelegateView::GetWidget() const {
    225   return View::GetWidget();
    226 }
    227 
    228 View* DialogDelegateView::GetContentsView() {
    229   return this;
    230 }
    231 
    232 }  // namespace views
    233