File: bubble_dialog_model_host.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 (159 lines) | stat: -rw-r--r-- 6,012 bytes parent folder | download | duplicates (6)
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
// Copyright 2020 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_BUBBLE_BUBBLE_DIALOG_MODEL_HOST_H_
#define UI_VIEWS_BUBBLE_BUBBLE_DIALOG_MODEL_HOST_H_

#include <memory>
#include <vector>

#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/types/pass_key.h"
#include "ui/base/models/dialog_model.h"
#include "ui/base/mojom/ui_base_types.mojom-shared.h"
#include "ui/color/color_provider.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/view.h"

namespace views {

class VIEWS_EXPORT DialogModelSectionHost : public BoxLayoutView,
                                            public ui::DialogModelFieldHost {
  METADATA_HEADER(DialogModelSectionHost, BoxLayoutView)

 public:
  [[nodiscard]] static std::unique_ptr<DialogModelSectionHost> Create(
      ui::DialogModelSection* section,
      ui::ElementIdentifier initially_focused_field_id =
          ui::ElementIdentifier());

 protected:
  // Prevent accidentally constructing this and not using ::Create().
  using BoxLayoutView::BoxLayoutView;
};

// TODO(pbos): Find a better name and move to a file separate from
// BubbleDialogModelHost. See if we can have BubbleDialogModelHost use
// DialogModelSectionHost directly (by removing more calls into
// BubbleDialogModelHostContentsView).
class BubbleDialogModelHostContentsView;

// BubbleDialogModelHost is a views implementation of ui::DialogModelHost which
// hosts a ui::DialogModel as a BubbleDialogDelegate. This exposes such as
// SetAnchorView(), SetArrow() and SetHighlightedButton(). For methods that are
// reflected in ui::DialogModelHost (such as ::Close()), prefer using the
// ui::DialogModelHost to avoid platform-specific code (GetWidget()->Close())
// where unnecessary. For those methods, note that this can be retrieved as a
// ui::DialogModelHost through DialogModel::host(). This helps minimize
// platform-specific code from platform-agnostic model-delegate code.
class VIEWS_EXPORT BubbleDialogModelHost : public BubbleDialogDelegate,
                                           public ui::DialogModelHost,
                                           public ui::DialogModelFieldHost {
 public:
  enum class FieldType { kText, kControl, kMenuItem };

  class VIEWS_EXPORT CustomView : public ui::DialogModelCustomField::Field {
   public:
    // The ElementIdentifier, ui::DialogModelCustomField::id(), is assigned to
    // `focusable_view` if it is non-null. Otherwiser, it is assigned to `view`.
    CustomView(std::unique_ptr<View> view,
               FieldType field_type,
               View* focusable_view = nullptr);
    CustomView(const CustomView&) = delete;
    CustomView& operator=(const CustomView&) = delete;
    ~CustomView() override;

    std::unique_ptr<View> TransferView();

    FieldType field_type() const { return field_type_; }

    View* TransferFocusableView() {
      return std::exchange(focusable_view_, nullptr);
    }

   private:
    // `view` is intended to be moved into the View hierarchy.
    std::unique_ptr<View> view_;
    const FieldType field_type_;
    raw_ptr<View> focusable_view_;
  };

  // Constructs a BubbleDialogModelHost, which for most purposes is to used as a
  // BubbleDialogDelegate. The BubbleDialogDelegate is nominally handed to
  // BubbleDialogDelegate::CreateBubble() which returns a Widget that has taken
  // ownership of the bubble. Widget::Show() finally shows the bubble.
  BubbleDialogModelHost(std::unique_ptr<ui::DialogModel> model,
                        View* anchor_view,
                        BubbleBorder::Arrow arrow,
                        bool autosize = true);

  // "Private" constructor (uses base::PassKey), use another constructor or
  // ::CreateModal().
  BubbleDialogModelHost(base::PassKey<BubbleDialogModelHost>,
                        std::unique_ptr<ui::DialogModel> model,
                        View* anchor_view,
                        BubbleBorder::Arrow arrow,
                        ui::mojom::ModalType modal_type,
                        bool autosize);

  ~BubbleDialogModelHost() override;

  static std::unique_ptr<BubbleDialogModelHost> CreateModal(
      std::unique_ptr<ui::DialogModel> model,
      ui::mojom::ModalType modal_type,
      bool autosize = true);

  // BubbleDialogDelegate:
  // TODO(pbos): Populate initparams with initial view instead of overriding
  // GetInitiallyFocusedView().
  View* GetInitiallyFocusedView() override;
  void OnWidgetInitialized() override;

  // ui::DialogModelHost:
  void Close() override;
  void OnDialogButtonChanged() override;

 private:
  // This class observes the ContentsView theme to make sure that the window
  // icon updates with the theme.
  class ThemeChangedObserver : public ViewObserver {
   public:
    ThemeChangedObserver(BubbleDialogModelHost* parent,
                         BubbleDialogModelHostContentsView* contents_view);
    ThemeChangedObserver(const ThemeChangedObserver&) = delete;
    ThemeChangedObserver& operator=(const ThemeChangedObserver&) = delete;
    ~ThemeChangedObserver() override;

    // ViewObserver:
    void OnViewThemeChanged(View*) override;

   private:
    const raw_ptr<BubbleDialogModelHost> parent_;
    base::ScopedObservation<View, ViewObserver> observation_{this};
  };

  [[nodiscard]] BubbleDialogModelHostContentsView* InitContentsView(
      ui::DialogModelSection* contents);

  void OnContentsViewChanged();

  void OnWindowClosing();

  void UpdateDialogButtons();

  void UpdateWindowIcon(const ui::ColorProvider* color_provider);
  void UpdateSpacingAndMargins();

  bool IsModalDialog() const;

  std::unique_ptr<ui::DialogModel> model_;
  const raw_ptr<BubbleDialogModelHostContentsView> contents_view_;
  base::CallbackListSubscription on_contents_changed_subscription_;
  ThemeChangedObserver theme_observer_;
};

}  // namespace views

#endif  // UI_VIEWS_BUBBLE_BUBBLE_DIALOG_MODEL_HOST_H_