blob: 7b22cb22385c89dff1e6a425451e4145b463ed78 [file] [log] [blame]
// 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.
#include <string>
#include <vector>
#include "ash/app_list/model/app_list_model.h"
#include "ash/app_list/model/search/search_box_model_observer.h"
#include "ash/app_list/model/search/search_model.h"
#include "ash/app_list/model/speech/speech_ui_model_observer.h"
#include "base/macros.h"
#include "ui/app_list/app_list_constants.h"
#include "ui/app_list/app_list_view_delegate_observer.h"
#include "ui/gfx/shadow_value.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/textfield/textfield_controller.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget_delegate.h"
namespace views {
class BoxLayout;
class ImageView;
class Textfield;
} // namespace views
namespace app_list {
class AppListView;
class AppListViewDelegate;
class SearchBoxModel;
class SearchBoxViewDelegate;
class SearchBoxBackground;
class SearchBoxImageButton;
// SearchBoxView consists of an icon and a Textfield. SearchBoxModel is its data
// model that controls what icon to display, what placeholder text to use for
// Textfield. The text and selection model part could be set to change the
// contents and selection model of the Textfield.
class APP_LIST_EXPORT SearchBoxView : public views::WidgetDelegateView,
public views::TextfieldController,
public views::ButtonListener,
public SearchBoxModelObserver,
public SpeechUIModelObserver,
public AppListViewDelegateObserver {
SearchBoxView(SearchBoxViewDelegate* delegate,
AppListViewDelegate* view_delegate,
AppListView* app_list_view = nullptr);
~SearchBoxView() override;
void ModelChanged();
bool HasSearch() const;
void ClearSearch();
// Returns the bounds to use for the view (including the shadow) given the
// desired bounds of the search box contents.
gfx::Rect GetViewBoundsForSearchBoxContentsBounds(
const gfx::Rect& rect) const;
views::ImageButton* back_button();
views::ImageButton* close_button();
views::Textfield* search_box() { return search_box_; }
void set_contents_view(views::View* contents_view) {
contents_view_ = contents_view;
// Sets voice label for Back button depending on whether a folder is open.
void SetBackButtonLabel(bool folder);
// Swaps the google icon with the back button.
void ShowBackOrGoogleIcon(bool show_back_button);
// Setting the search box active left aligns the placeholder text, changes
// the color of the placeholder text, and enables cursor blink. Setting the
// search box inactive center aligns the placeholder text, sets the color, and
// disables cursor blink.
void SetSearchBoxActive(bool active);
// Shows/hides the virtual keyboard if the search box is active.
void UpdateKeyboardVisibility();
// Detects |ET_MOUSE_PRESSED| and |ET_GESTURE_TAP| events on the white
// background of the search box.
void HandleSearchBoxEvent(ui::LocatedEvent* located_event);
// Handles Gesture and Mouse Events sent from |search_box_|.
bool OnTextfieldEvent();
// Overridden from views::View:
bool OnMouseWheel(const ui::MouseWheelEvent& event) override;
void OnEnabledChanged() override;
const char* GetClassName() const override;
void OnGestureEvent(ui::GestureEvent* event) override;
void OnMouseEvent(ui::MouseEvent* event) override;
void OnKeyEvent(ui::KeyEvent* evetn) override;
// Overridden from views::WidgetDelegate:
ui::AXRole GetAccessibleWindowRole() const override;
bool ShouldAdvanceFocusToTopLevelWidget() const override;
// Overridden from views::ButtonListener:
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
// Updates the search box's background corner radius and color based on the
// state of AppListModel.
void UpdateBackground(double progress,
AppListModel::State current_state,
AppListModel::State target_state);
// Updates the search box's layout based on the state of AppListModel.
void UpdateLayout(double progress,
AppListModel::State current_state,
AppListModel::State target_state);
// Called when tablet mode starts and ends.
void OnTabletModeChanged(bool started);
// Returns background border corner radius in the given state.
int GetSearchBoxBorderCornerRadiusForState(AppListModel::State state) const;
// Returns background color for the given state.
SkColor GetBackgroundColorForState(AppListModel::State state) const;
// Updates the opacity of the searchbox.
void UpdateOpacity();
// Used only in the tests to get the current search icon.
views::ImageView* get_search_icon_for_test() { return search_icon_; }
// Whether the search box is active.
bool is_search_box_active() const { return is_search_box_active_; }
// Returns selected view in contents view.
views::View* GetSelectedViewInContentsView() const;
bool selected() { return selected_; }
void SetSelected(bool selected);
// Updates model text and selection model with current Textfield info.
void UpdateModel(bool initiated_by_user);
// Fires query change notification.
void NotifyQueryChanged();
// Updates the search icon.
void UpdateSearchIcon();
// Gets the wallpaper prominent colors.
void GetWallpaperProminentColors(std::vector<SkColor>* colors);
// Sets the background color.
void SetBackgroundColor(SkColor light_vibrant);
// Sets the search box color.
void SetSearchBoxColor(SkColor color);
// Updates the search box's background color.
void UpdateBackgroundColor(SkColor color);
// Updates the visibility of close button.
void UpdateCloseButtonVisisbility();
// Gets the search box background.
SearchBoxBackground* GetSearchBoxBackground() const;
// Whether the trimmed query in the search box is empty.
bool IsSearchBoxTrimmedQueryEmpty() const;
// Overridden from views::TextfieldController:
void ContentsChanged(views::Textfield* sender,
const base::string16& new_contents) override;
bool HandleKeyEvent(views::Textfield* sender,
const ui::KeyEvent& key_event) override;
bool HandleMouseEvent(views::Textfield* sender,
const ui::MouseEvent& mouse_event) override;
bool HandleGestureEvent(views::Textfield* sender,
const ui::GestureEvent& gesture_event) override;
// Overridden from SearchBoxModelObserver:
void SpeechRecognitionButtonPropChanged() override;
void HintTextChanged() override;
void SelectionModelChanged() override;
void Update() override;
// Overridden from SpeechUIModelObserver:
void OnSpeechRecognitionStateChanged(
SpeechRecognitionState new_state) override;
// Overridden from AppListViewDelegateObserver:
void OnWallpaperColorsChanged() override;
// Update search box border based on whether the search box is activated.
void UpdateSearchBoxBorder();
SearchBoxViewDelegate* delegate_; // Not owned.
AppListViewDelegate* view_delegate_; // Not owned.
SearchModel* search_model_ = nullptr; // Owned by the profile-keyed service.
// Owned by views hierarchy.
views::View* content_container_;
views::ImageView* search_icon_ = nullptr;
SearchBoxImageButton* back_button_ = nullptr;
SearchBoxImageButton* speech_button_ = nullptr;
SearchBoxImageButton* close_button_ = nullptr;
views::Textfield* search_box_;
views::View* search_box_right_space_ = nullptr;
views::View* contents_view_ = nullptr;
app_list::AppListView* app_list_view_;
// Owned by |content_container_|. It is deleted when the view is deleted.
views::BoxLayout* box_layout_ = nullptr;
// Whether the search box is active.
bool is_search_box_active_ = false;
// Whether tablet mode is active.
bool is_tablet_mode_ = false;
// The current background color.
SkColor background_color_ = kSearchBoxBackgroundDefault;
// The current search box color.
SkColor search_box_color_ = kDefaultSearchboxColor;
// Whether the search box is selected.
bool selected_ = false;
} // namespace app_list