File: dialog_client_view.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (232 lines) | stat: -rw-r--r-- 8,847 bytes parent folder | download | duplicates (3)
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
// Copyright 2012 The Chromium Authors
// 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 <array>
#include <memory>
#include <utility>
#include <vector>

#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "ui/base/interaction/element_identifier.h"
#include "ui/base/mojom/dialog_button.mojom.h"
#include "ui/base/ui_base_types.h"
#include "ui/color/color_id.h"
#include "ui/gfx/geometry/rounded_corners_f.h"
#include "ui/views/input_event_activation_protector.h"
#include "ui/views/layout/delegating_layout_manager.h"
#include "ui/views/metadata/view_factory.h"
#include "ui/views/window/client_view.h"
#include "ui/views/window/dialog_observer.h"

namespace views {

class DialogDelegate;
class MdTextButton;
class Widget;

namespace features {
VIEWS_EXPORT BASE_DECLARE_FEATURE(kDialogVerticalButtonFallback);
}

// 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] |
//   +------------------------------+
//
// You must not directly depend on or use DialogClientView; it is internal to
// //ui/views. Access it through the public interfaces on DialogDelegate. It is
// only VIEWS_EXPORT to make it available to views_unittests.
class VIEWS_EXPORT DialogClientView : public ClientView,
                                      public DialogObserver,
                                      public LayoutDelegate {
  METADATA_HEADER(DialogClientView, ClientView)

 public:
  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kTopViewId);
  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kOkButtonElementId);
  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kCancelButtonElementId);

  DialogClientView(Widget* widget, View* contents_view);

  DialogClientView(const DialogClientView&) = delete;
  DialogClientView& operator=(const DialogClientView&) = delete;

  ~DialogClientView() override;

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

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

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

#if BUILDFLAG(IS_CHROMEOS)
  // ClientView implementation:
  void UpdateWindowRoundedCorners(
      const gfx::RoundedCornersF& window_radii) override;
#endif  // BUILDFLAG(IS_CHROMEOS)

  // Input protection is triggered upon prompt creation and updated on
  // visibility changes. Other situations such as top window changes in certain
  // situations should trigger the input protection manually by calling this
  // method. Input protection protects against certain kinds of clickjacking.
  // Essentially it prevents clicks that happen within a user's double click
  // interval from when the protection is started as well as any following
  // clicks that happen in shorter succession than the user's double click
  // interval. Refer to InputEventActivationProtector for more information. If
  // `force_early` is true, force to trigger even earlier (shortly before the
  // this view is visible).
  void TriggerInputProtection(bool force_early = false);

  bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
  void ViewHierarchyChanged(
      const ViewHierarchyChangedDetails& details) override;
  void OnThemeChanged() override;

  // Update the `view_shown_time_stamp_` of input protector. A short time
  // from this point onward, input event will be ignored.
  void UpdateInputProtectorTimeStamp();

  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();

  // Override the internal input protector for testing; usually to inject a mock
  // version whose return value can be controlled.
  void SetInputProtectorForTesting(
      std::unique_ptr<views::InputEventActivationProtector> input_protector) {
    input_protector_ = std::move(input_protector);
  }

  bool IsPossiblyUnintendedInteraction(const ui::Event& event,
                                       bool allow_key_events);

  // LayoutDelegate:
  ProposedLayout CalculateProposedLayout(
      const SizeBounds& size_bounds) const override;

  void SetBackgroundColor(ui::ColorId background_color_id);

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

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

  void SetBackgroundRadii(const gfx::RoundedCornersF& radii);

  void UpdateBackground();

  // DialogObserver:
  void OnDialogChanged() override;

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

  // 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(raw_ptr<MdTextButton>* member,
                          ui::mojom::DialogButton type);

  void ButtonPressed(ui::mojom::DialogButton type, const ui::Event& event);

  // Returns the spacing between the extra view and the ok/cancel buttons. 0 if
  // no extra view. Otherwise uses 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();

  // Returns Views in column order. This is used when the buttons don't fit in
  // a row, and the buttons are laid out vertically instead.
  std::vector<View*> GetButtonColumnViews() const;

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

  // Horizontal and vertical variations of button layout logic. The vertical
  // layout is utilized if the horizontal layout exceeds a maximum width
  // criteria.
  void SetupHorizontalLayout();
  void SetupVerticalLayout();

  // 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 UpdateButtonsFromModel();

  // Ask the delegate for a new extra view. If there is one, replace the
  // existing extra view with it.
  void UpdateExtraViewFromDelegate();

  // Adds/Removes a filler view depending on whether the corresponding live view
  // is present.
  void AddFillerView(size_t view_index);
  void RemoveFillerView(size_t view_index);

  // 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.
  raw_ptr<MdTextButton> ok_button_ = nullptr;
  raw_ptr<MdTextButton> cancel_button_ = nullptr;

  // The extra view shown in the row of buttons; may be nullptr.
  raw_ptr<View> extra_view_ = nullptr;

  // Container view for the button row.
  raw_ptr<ButtonRowContainer> button_row_container_ = nullptr;

  // List of "filler" views used to keep columns in sync for TableLayout.
  std::array<View*, kNumButtons> filler_views_ = {nullptr, nullptr, nullptr};

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

  std::unique_ptr<InputEventActivationProtector> input_protector_;

  ui::ColorId background_color_id_ = ui::kColorDialogBackground;
  gfx::RoundedCornersF background_radii_;
};

BEGIN_VIEW_BUILDER(VIEWS_EXPORT, DialogClientView, ClientView)
END_VIEW_BUILDER

}  // namespace views

DEFINE_VIEW_BUILDER(VIEWS_EXPORT, DialogClientView)

#endif  // UI_VIEWS_WINDOW_DIALOG_CLIENT_VIEW_H_