File: task_manager_search_bar_view.cc

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 (163 lines) | stat: -rw-r--r-- 5,999 bytes parent folder | download | duplicates (5)
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
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/task_manager_search_bar_view.h"

#include <memory>
#include <string>

#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "chrome/browser/ui/color/chrome_color_id.h"
#include "chrome/grit/branded_strings.h"
#include "components/vector_icons/vector_icons.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/color/color_id.h"
#include "ui/views/controls/button/image_button_factory.h"
#include "ui/views/controls/highlight_path_generator.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/flex_layout.h"

namespace task_manager {
TaskManagerSearchBarView::TaskManagerSearchBarView(
    const std::u16string& placeholder,
    const gfx::Insets& margins,
    Delegate& delegate)
    : delegate_(delegate)
#if BUILDFLAG(IS_LINUX)
      ,
      textfield_placeholder_color_id_(kColorTaskManagerSearchBarPlaceholderText)
#endif
{
  auto* layout_provider = ChromeLayoutProvider::Get();
  auto search_bar_layout = std::make_unique<views::BoxLayout>();
  search_bar_layout->SetOrientation(views::LayoutOrientation::kHorizontal);
  search_bar_layout->set_main_axis_alignment(views::LayoutAlignment::kStretch);
  search_bar_layout->set_cross_axis_alignment(views::LayoutAlignment::kCenter);

  auto search_icon =
      std::make_unique<views::ImageView>(ui::ImageModel::FromVectorIcon(
          vector_icons::kSearchChromeRefreshIcon, ui::kColorIcon,
          layout_provider->GetDistanceMetric(
              DISTANCE_TASK_MANAGER_SEARCH_ICON_SIZE)));
  search_icon->SetProperty(views::kMarginsKey, margins);

  auto input =
      views::Builder<views::Textfield>()
          .SetPlaceholderText(placeholder)
          .SetAccessibleName(l10n_util::GetStringUTF16(
              IDS_TASK_MANAGER_SEARCH_ACCESSIBILITY_NAME))
          .SetController(this)
          .SetBorder(nullptr)
          .SetBackgroundColor(kColorTaskManagerSearchBarBackground)
          .SetProperty(views::kElementIdentifierKey, kInputField)
          // Set margins to remove duplicate space between search
          // icon and textfield.
          .SetProperty(views::kMarginsKey, gfx::Insets::TLBR(0, 0, 0, 0))
          .Build();

  auto clear_btn =
      views::Builder<views::ImageButton>(
          views::CreateVectorImageButtonWithNativeTheme(
              base::BindRepeating(&TaskManagerSearchBarView::OnClearPressed,
                                  base::Unretained(this)),
              vector_icons::kCloseChromeRefreshIcon))
          // Reset the border set by
          // `CreateVectorImageButtonWithNativeTheme()` as it sets
          // an unnecessary padding to the highlighting circle.
          .SetBorder(nullptr)
          .SetAccessibleName(l10n_util::GetStringUTF16(
              IDS_TASK_MANAGER_CLEAR_SEARCH_BUTTON_ACCESSIBILITY_NAME))
          .SetProperty(views::kMarginsKey, margins)
          .Build();

  search_bar_layout->SetFlexForView(input.get(), 1);

  SetLayoutManager(std::move(search_bar_layout));

  AddChildView(std::move(search_icon));
  input_ = AddChildView(std::move(input));
  input_->RemoveHoverEffect();
  input_changed_subscription_ =
      input_->AddTextChangedCallback(base::BindRepeating(
          &TaskManagerSearchBarView::OnInputChanged, base::Unretained(this)));

  clear_ = AddChildView(std::move(clear_btn));
  views::InstallCircleHighlightPathGenerator(clear_);
  // Only visible when users type in search keywords.
  if (input_->GetText().empty()) {
    clear_->SetVisible(false);
  }
}

TaskManagerSearchBarView::~TaskManagerSearchBarView() = default;

void TaskManagerSearchBarView::OnThemeChanged() {
  views::View::OnThemeChanged();
  UpdateTextfield();
}

bool TaskManagerSearchBarView::HandleKeyEvent(views::Textfield* /*sender*/,
                                              const ui::KeyEvent& key_event) {
  // Clear button should be visible only if input text is not empty.
  // Early return if visibility is consistent with the input text.
  // Case 1 : clear button is visible and input text is not empty.
  // Case 2 : clear button is invisible and input text is empty.
  if (clear_->GetVisible() != input_->GetText().empty()) {
    return false;
  }
  if (key_event.type() == ui::EventType::kKeyReleased) {
    clear_->SetVisible(!input_->GetText().empty());
  }
  return false;
}

void TaskManagerSearchBarView::Focus() {
  input_->RequestFocus();
}

void TaskManagerSearchBarView::OnInputChanged() {
  input_change_notification_timer_.Start(
      FROM_HERE, kInputChangeCallbackDelay,
      // `delegate_` is expected to outlive `this`, the timer will either be
      // triggered when it is alive or canceled.
      base::BindOnce(&Delegate::SearchBarOnInputChanged,
                     base::Unretained(delegate_), input_->GetText()));
}

void TaskManagerSearchBarView::OnClearPressed() {
  input_->SetText(u"");
  clear_->SetVisible(false);
  input_->RequestFocus();
}

bool TaskManagerSearchBarView::GetClearButtonVisibleStatusForTesting() const {
  return clear_->GetVisible();
}

void TaskManagerSearchBarView::SetInputTextForTesting(
    const std::u16string& text) {
  input_->SetText(text);
}

gfx::Point TaskManagerSearchBarView::GetClearButtonScreenCenterPointForTesting()
    const {
  return clear_->GetBoundsInScreen().CenterPoint();
}

void TaskManagerSearchBarView::UpdateTextfield() {
  if (const auto* const color_provider = GetColorProvider(); color_provider) {
    input_->set_placeholder_text_color(
        color_provider->GetColor(textfield_placeholder_color_id_.value_or(
            ui::kColorTextfieldForegroundPlaceholder)));
  }
}

BEGIN_METADATA(TaskManagerSearchBarView)
END_METADATA

DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(TaskManagerSearchBarView, kInputField);
}  // namespace task_manager