summaryrefslogtreecommitdiff
path: root/chromium/ui/views/window/dialog_client_view.h
blob: 3981e4f8b6c558c270ad759bfdc3d99895745307 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// 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_CLIENT_VIEW_H_
#define UI_VIEWS_WINDOW_DIALOG_CLIENT_VIEW_H_

#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/time/time.h"
#include "ui/base/ui_base_types.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/window/client_view.h"
#include "ui/views/window/dialog_observer.h"

namespace views {

class DialogDelegate;
class LabelButton;
class Widget;

// DialogClientView provides adornments for a dialog's content view, including
// custom-labeled [OK] and [Cancel] buttons with [Enter] and [Esc] accelerators.
// The view also displays the delegate's extra view alongside the buttons. The
// view appears like below. NOTE: The contents view is not inset on the top or
// side client view edges.
//   +------------------------------+
//   |        Contents View         |
//   +------------------------------+
//   | [Extra View]   [OK] [Cancel] |
//   +------------------------------+
class VIEWS_EXPORT DialogClientView : public ClientView,
                                      public ButtonListener,
                                      public DialogObserver {
 public:
  DialogClientView(Widget* widget, View* contents_view);
  ~DialogClientView() override;

  // Accept or Cancel the dialog.
  void AcceptWindow();
  void CancelWindow();

  // Accessors in case the user wishes to adjust these buttons.
  LabelButton* ok_button() const { return ok_button_; }
  LabelButton* cancel_button() const { return cancel_button_; }

  void SetButtonRowInsets(const gfx::Insets& insets);

  // ClientView implementation:
  bool CanClose() override;
  DialogClientView* AsDialogClientView() override;
  const DialogClientView* AsDialogClientView() const override;

  // View implementation:
  gfx::Size CalculatePreferredSize() const override;
  gfx::Size GetMinimumSize() const override;
  gfx::Size GetMaximumSize() const override;
  void VisibilityChanged(View* starting_from, bool is_visible) override;

  void Layout() override;
  bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
  void ViewHierarchyChanged(
      const ViewHierarchyChangedDetails& details) override;
  void OnNativeThemeChanged(const ui::NativeTheme* theme) override;

  // ButtonListener implementation:
  void ButtonPressed(Button* sender, const ui::Event& event) override;

  void set_minimum_size(const gfx::Size& size) { minimum_size_ = size; }

  // Resets the time when view has been shown. Tests may need to call this
  // method if they use events that could be otherwise treated as unintended.
  // See IsPossiblyUnintendedInteraction().
  void ResetViewShownTimeStampForTesting();

 private:
  enum {
    // The number of buttons that DialogClientView can support.
    kNumButtons = 3
  };
  class ButtonRowContainer;

  // Returns the DialogDelegate for the window.
  DialogDelegate* GetDialogDelegate() const;

  // View implementation.
  void ChildPreferredSizeChanged(View* child) override;
  void ChildVisibilityChanged(View* child) override;

  // DialogObserver:
  void OnDialogModelChanged() override;

  // Update the dialog buttons to match the dialog's delegate.
  void UpdateDialogButtons();

  // Creates, deletes, or updates the appearance of the button of type |type|
  // (which must be pointed to by |member|).  Which action is chosen is based on
  // whether DialogDelegate::GetDialogButtons() includes |type|, and whether
  // |member| points to a button that already exists.
  void UpdateDialogButton(LabelButton** member, ui::DialogButton type);

  // Returns the spacing between the extra view and the ok/cancel buttons. 0 if
  // no extra view. Otherwise uses GetExtraViewPadding() or the default padding.
  int GetExtraViewSpacing() const;

  // Returns Views in the button row, as they should appear in the layout. If
  // a View should not appear, it will be null.
  std::array<View*, kNumButtons> GetButtonRowViews();

  // Installs and configures the LayoutManager for |button_row_container_|.
  void SetupLayout();

  // Creates or deletes any buttons that are required. Updates data members.
  // After calling this, no button row Views will be in the view hierarchy.
  void SetupViews();

  // How much to inset the button row.
  gfx::Insets button_row_insets_;

  // The minimum size of this dialog, regardless of the size of its content
  // view.
  gfx::Size minimum_size_;

  // The dialog buttons.
  LabelButton* ok_button_ = nullptr;
  LabelButton* cancel_button_ = nullptr;

  // The extra view shown in the row of buttons; may be NULL.
  View* extra_view_ = nullptr;

  // Container view for the button row.
  ButtonRowContainer* button_row_container_ = nullptr;

  // True if we've notified the delegate the window is closing and the delegate
  // allowed the close. In some situations it's possible to get two closes (see
  // http://crbug.com/71940). This is used to avoid notifying the delegate
  // twice, which can have bad consequences.
  bool delegate_allowed_close_ = false;

  // Used to prevent unnecessary or potentially harmful changes during
  // SetupLayout(). Everything will be manually updated afterwards.
  bool adding_or_removing_views_ = false;

  // Time when view has been shown.
  base::TimeTicks view_shown_time_stamp_;

  DISALLOW_COPY_AND_ASSIGN(DialogClientView);
};

}  // namespace views

#endif  // UI_VIEWS_WINDOW_DIALOG_CLIENT_VIEW_H_