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 #ifndef UI_VIEWS_WINDOW_DIALOG_CLIENT_VIEW_H_
      6 #define UI_VIEWS_WINDOW_DIALOG_CLIENT_VIEW_H_
      7 
      8 #include "ui/base/ui_base_types.h"
      9 #include "ui/views/controls/button/button.h"
     10 #include "ui/views/focus/focus_manager.h"
     11 #include "ui/views/window/client_view.h"
     12 
     13 namespace views {
     14 
     15 class DialogDelegate;
     16 class LabelButton;
     17 class Widget;
     18 
     19 // DialogClientView provides adornments for a dialog's content view, including
     20 // custom-labeled [OK] and [Cancel] buttons with [Enter] and [Esc] accelerators.
     21 // The view also displays the delegate's extra view alongside the buttons and
     22 // the delegate's footnote view below the buttons. The view appears like below.
     23 // NOTE: The contents view is not inset on the top or side client view edges.
     24 //   +------------------------------+
     25 //   |        Contents View         |
     26 //   +------------------------------+
     27 //   | [Extra View]   [OK] [Cancel] |
     28 //   | [      Footnote View       ] |
     29 //   +------------------------------+
     30 class VIEWS_EXPORT DialogClientView : public ClientView,
     31                                       public ButtonListener,
     32                                       public FocusChangeListener {
     33  public:
     34   DialogClientView(Widget* widget, View* contents_view);
     35   virtual ~DialogClientView();
     36 
     37   // Accept or Cancel the dialog.
     38   void AcceptWindow();
     39   void CancelWindow();
     40 
     41   // Accessors in case the user wishes to adjust these buttons.
     42   LabelButton* ok_button() const { return ok_button_; }
     43   LabelButton* cancel_button() const { return cancel_button_; }
     44 
     45   // Update the dialog buttons to match the dialog's delegate.
     46   void UpdateDialogButtons();
     47 
     48   // ClientView implementation:
     49   virtual bool CanClose() OVERRIDE;
     50   virtual DialogClientView* AsDialogClientView() OVERRIDE;
     51   virtual const DialogClientView* AsDialogClientView() const OVERRIDE;
     52 
     53   // FocusChangeListener implementation:
     54   virtual void OnWillChangeFocus(View* focused_before,
     55                                  View* focused_now) OVERRIDE;
     56   virtual void OnDidChangeFocus(View* focused_before,
     57                                 View* focused_now) OVERRIDE;
     58 
     59   // View implementation:
     60   virtual gfx::Size GetPreferredSize() const OVERRIDE;
     61   virtual void Layout() OVERRIDE;
     62   virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
     63   virtual void ViewHierarchyChanged(
     64       const ViewHierarchyChangedDetails& details) OVERRIDE;
     65   virtual void NativeViewHierarchyChanged() OVERRIDE;
     66   virtual void OnNativeThemeChanged(const ui::NativeTheme* theme) OVERRIDE;
     67 
     68   // ButtonListener implementation:
     69   virtual void ButtonPressed(Button* sender, const ui::Event& event) OVERRIDE;
     70 
     71  protected:
     72   // For testing.
     73   DialogClientView(View* contents_view);
     74 
     75   // Returns the DialogDelegate for the window. Virtual for testing.
     76   virtual DialogDelegate* GetDialogDelegate() const;
     77 
     78   // Create and add the extra view, if supplied by the delegate.
     79   void CreateExtraView();
     80 
     81   // Creates and adds the footnote view, if supplied by the delegate.
     82   void CreateFootnoteView();
     83 
     84   // View implementation.
     85   virtual void ChildPreferredSizeChanged(View* child) OVERRIDE;
     86   virtual void ChildVisibilityChanged(View* child) OVERRIDE;
     87 
     88  private:
     89   FRIEND_TEST_ALL_PREFIXES(DialogClientViewTest, FocusManager);
     90 
     91   bool has_dialog_buttons() const { return ok_button_ || cancel_button_; }
     92 
     93   // Create a dialog button of the appropriate type.
     94   LabelButton* CreateDialogButton(ui::DialogButton type);
     95 
     96   // Update |button|'s text and enabled state according to the delegate's state.
     97   void UpdateButton(LabelButton* button, ui::DialogButton type);
     98 
     99   // Returns the height of the row containing the buttons and the extra view.
    100   int GetButtonsAndExtraViewRowHeight() const;
    101 
    102   // Returns the insets for the buttons and extra view.
    103   gfx::Insets GetButtonRowInsets() const;
    104 
    105   // Closes the widget.
    106   void Close();
    107 
    108   // The dialog buttons.
    109   LabelButton* ok_button_;
    110   LabelButton* cancel_button_;
    111 
    112   // The button that is currently default; may be NULL.
    113   LabelButton* default_button_;
    114 
    115   // Observe |focus_manager_| to update the default button with focus changes.
    116   FocusManager* focus_manager_;
    117 
    118   // The extra view shown in the row of buttons; may be NULL.
    119   View* extra_view_;
    120 
    121   // The footnote view shown below the buttons; may be NULL.
    122   View* footnote_view_;
    123 
    124   // True if we've notified the delegate the window is closing and the delegate
    125   // allosed the close. In some situations it's possible to get two closes (see
    126   // http://crbug.com/71940). This is used to avoid notifying the delegate
    127   // twice, which can have bad consequences.
    128   bool notified_delegate_;
    129 
    130   DISALLOW_COPY_AND_ASSIGN(DialogClientView);
    131 };
    132 
    133 }  // namespace views
    134 
    135 #endif  // UI_VIEWS_WINDOW_DIALOG_CLIENT_VIEW_H_
    136