File: side_panel.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 (157 lines) | stat: -rw-r--r-- 6,103 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
// 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 CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_SIDE_PANEL_H_
#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_SIDE_PANEL_H_

#include <memory>

#include "base/memory/raw_ptr.h"
#include "base/scoped_multi_source_observation.h"
#include "components/prefs/pref_change_registrar.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/geometry/rounded_corners_f.h"
#include "ui/views/accessible_pane_view.h"
#include "ui/views/animation/animation_delegate_views.h"
#include "ui/views/controls/resize_area_delegate.h"

class BrowserView;

class SidePanel : public views::AccessiblePaneView,
                  public views::ResizeAreaDelegate,
                  public views::AnimationDelegateViews {
  METADATA_HEADER(SidePanel, views::AccessiblePaneView)

 public:
  // Determines the side from which the side panel will appear.
  // LTR / RTL conversions are handled in
  // BrowserViewLayout::LayoutSidePanelView. As such, left will always be on the
  // left side of the browser regardless of LTR / RTL mode.
  enum class HorizontalAlignment { kLeft = 0, kRight };
  explicit SidePanel(
      BrowserView* browser_view,
      HorizontalAlignment horizontal_alignment = HorizontalAlignment::kRight);
  SidePanel(const SidePanel&) = delete;
  SidePanel& operator=(const SidePanel&) = delete;
  ~SidePanel() override;

  void SetPanelWidth(int width);
  bool ShouldRestrictMaxWidth() const;
  void UpdateWidthOnEntryChanged();
  void UpdateSidePanelWidthPref(const std::string& panel_id, int width);
  double GetAnimationValue() const;
  gfx::RoundedCornersF background_radii() const { return background_radii_; }
  void SetBackgroundRadii(const gfx::RoundedCornersF& radii);
  void SetHorizontalAlignment(HorizontalAlignment alignment);
  HorizontalAlignment GetHorizontalAlignment();
  bool IsRightAligned();
  gfx::Size GetMinimumSize() const override;
  bool IsClosing();
  void DisableAnimationsForTesting() { animations_disabled_ = true; }
  void SetKeyboardResized(bool keyboard_resized) {
    keyboard_resized_ = keyboard_resized;
  }

  // Add a header view that gets painted over the side panel border. The top
  // border area grows to accommodate the additional height of the header,
  // pushing the other side panel content down.
  void AddHeaderView(std::unique_ptr<views::View> view);

  // Gets the upper bound of the content area size if the side panel is shown
  // right now. If the side panel is not showing, returns the minimum width
  // and browser view height minus the padding insets. The actual content
  // size will be smaller than the returned result when the side panel header
  // is shown, for example.
  gfx::Size GetContentSizeUpperBound() const;

  // views::ResizeAreaDelegate:
  void OnResize(int resize_amount, bool done_resizing) override;

  // Log UMA data for the side panel resize feature. Will only log if the side
  // panel has been resized since metrics were last logged.
  void RecordMetricsIfResized();

  // Reflects the current state of the visibility of the side panel.
  enum class State { kClosed, kOpening, kOpen, kClosing };
  State state() { return state_; }

  // These two methods are the only mechanism to change visibility of the side
  // panel. `animated` may be ignored.
  void Open(bool animated);
  void Close(bool animated);

  // This is the parent view for the contents of the side panel.
  views::View* GetContentParentView();

 private:
  class VisibleBoundsViewClipper;

  // This method is the shared implementation of Open/Close.
  void UpdateVisibility(bool should_be_open, bool animated);

  bool ShouldShowAnimation() const;
  void AnnounceResize();

  // views::View:
  void OnBoundsChanged(const gfx::Rect& previous_bounds) override;

  // views::ViewObserver:
  void OnChildViewAdded(View* observed_view, View* child) override;
  void OnChildViewRemoved(View* observed_view, View* child) override;

  // views::AnimationDelegateViews:
  void AnimationProgressed(const gfx::Animation* animation) override;
  void AnimationEnded(const gfx::Animation* animation) override;

  // Timestamp of the last step in the side panel open/close animation. This is
  // used for metrics purposes.
  base::TimeTicks last_animation_step_timestamp_;
  std::optional<base::TimeDelta> largest_animation_step_time_;

  raw_ptr<View> border_view_ = nullptr;
  const raw_ptr<BrowserView> browser_view_;
  raw_ptr<View> resize_area_ = nullptr;
  raw_ptr<views::View> header_view_ = nullptr;

  // -1 if a side panel resize is not in progress, otherwise the width of the
  // side panel when the current resize was initiated.
  int starting_width_on_resize_ = -1;

  // Should be true if the side panel was resized since metrics were last
  // logged.
  bool did_resize_ = false;
  // Should be true if we have resized via keyboard and have not announced the
  // resize for accessibility users.
  bool keyboard_resized_ = false;

  bool animations_disabled_ = false;

  // Animation controlling showing and hiding of the side panel.
  gfx::SlideAnimation animation_{this};

  // Helps to clip layer backed children to their visible bounds.
  // TODO: 344626785 - Remove this once WebView layer behavior has been fixed.
  std::unique_ptr<VisibleBoundsViewClipper> visible_bounds_view_clipper_;

  // Monitors content views so we will be notified if their property
  // state changes.
  base::ScopedMultiSourceObservation<View, ViewObserver>
      content_view_observations_{this};

  gfx::RoundedCornersF background_radii_;

  // Keeps track of the side the side panel will appear on (left or right).
  HorizontalAlignment horizontal_alignment_;

  // Observes and listens to side panel alignment changes.
  PrefChangeRegistrar pref_change_registrar_;

  // Owned by `this` indirectly through the views tree.
  raw_ptr<views::View> content_parent_view_;

  State state_ = State::kClosed;
};

#endif  // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_SIDE_PANEL_H_