#ifndef ASH_GLANCEABLES_COMMON_GLANCEABLES_TIME_MANAGEMENT_BUBBLE_VIEW_H_
#define ASH_GLANCEABLES_COMMON_GLANCEABLES_TIME_MANAGEMENT_BUBBLE_VIEW_H_
#include <memory>
#include <string>
#include "ash/ash_export.h"
#include "ash/style/counter_expand_button.h"
#include "ash/style/error_message_toast.h"
#include "base/functional/callback_forward.h"
#include "ui/base/models/combobox_model.h"
#include "ui/compositor/compositor_metrics_tracker.h"
#include "ui/views/animation/animation_delegate_views.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/layout/flex_layout_view.h"
#include "ui/views/view.h"
namespace gfx {
struct VectorIcon;
}
namespace ash {
class Combobox;
class GlanceablesContentsScrollView;
class GlanceablesListFooterView;
class GlanceablesProgressBarView;
class ASH_EXPORT GlanceablesTimeManagementBubbleView
: public views::FlexLayoutView,
public views::AnimationDelegateViews {
METADATA_HEADER(GlanceablesTimeManagementBubbleView, views::FlexLayoutView)
public:
enum class Context { kTasks = 0, kClassroom = 1 };
class Observer : public base::CheckedObserver {
public:
virtual void OnExpandStateChanged(Context context,
bool is_expanded,
bool expand_by_overscroll) = 0;
};
struct InitParams {
InitParams();
InitParams(InitParams&& other);
~InitParams();
Context context;
std::unique_ptr<ui::ComboboxModel> combobox_model;
std::u16string combobox_tooltip;
int expand_button_tooltip_id = 0;
int collapse_button_tooltip_id = 0;
std::u16string footer_title;
std::u16string footer_tooltip;
raw_ptr<const gfx::VectorIcon> header_icon = nullptr;
int header_icon_tooltip_id = 0;
};
explicit GlanceablesTimeManagementBubbleView(InitParams params);
GlanceablesTimeManagementBubbleView(
const GlanceablesTimeManagementBubbleView&) = delete;
GlanceablesTimeManagementBubbleView& operator=(
const GlanceablesTimeManagementBubbleView&) = delete;
~GlanceablesTimeManagementBubbleView() override;
void ChildPreferredSizeChanged(View* child) override;
void Layout(PassKey) override;
gfx::Size GetMinimumSize() const override;
gfx::Size CalculatePreferredSize(
const views::SizeBounds& available_size) const override;
void AnimationEnded(const gfx::Animation* animation) override;
void AnimationProgressed(const gfx::Animation* animation) override;
void AnimationCanceled(const gfx::Animation* animation) override;
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
void CreateElevatedBackground();
void SetExpandState(bool is_expanded, bool expand_by_overscroll);
int GetCollapsedStatePreferredHeight() const;
bool IsExpanded() const { return is_expanded_; }
bool is_animating_resize() const {
return resize_animation_ && resize_animation_->is_animating();
}
void SetAnimationEndedClosureForTest(base::OnceClosure closure);
protected:
class GlanceablesExpandButton : public CounterExpandButton {
METADATA_HEADER(GlanceablesExpandButton, CounterExpandButton)
public:
GlanceablesExpandButton();
~GlanceablesExpandButton() override;
void SetExpandedStateTooltipStringId(int tooltip_text_id);
void SetCollapsedStateTooltipStringId(int tooltip_text_id);
std::u16string GetExpandedStateTooltipText() const override;
std::u16string GetCollapsedStateTooltipText() const override;
private:
int expand_tooltip_string_id_ = 0;
int collapse_tooltip_string_id_ = 0;
};
class ResizeAnimation : public gfx::LinearAnimation {
public:
enum class Type {
kContainerExpandStateChanged,
kChildResize,
};
ResizeAnimation(int start_height,
int end_height,
gfx::AnimationDelegate* delegate,
Type type);
int GetCurrentHeight() const;
private:
const Type type_;
const int start_height_;
const int end_height_;
};
virtual void OnHeaderIconPressed() = 0;
virtual void OnFooterButtonPressed() = 0;
virtual void SelectedListChanged() = 0;
virtual void AnimateResize(ResizeAnimation::Type resize_type) = 0;
void UpdateInteriorMargin();
void CreateComboBoxView();
size_t GetComboboxSelectedIndex() const;
void UpdateComboboxReplacementLabelText();
void SetUpResizeThroughputTracker(const std::string& histogram_name);
void MaybeDismissErrorMessage();
void ShowErrorMessage(const std::u16string& error_message,
views::Button::PressedCallback callback,
ErrorMessageToast::ButtonActionType type);
Combobox* combobox_view() { return combobox_view_; }
GlanceablesExpandButton* expand_button() { return expand_button_; }
GlanceablesProgressBarView* progress_bar() { return progress_bar_; }
GlanceablesContentsScrollView* content_scroll_view() {
return content_scroll_view_;
}
views::View* items_container_view() { return items_container_view_; }
GlanceablesListFooterView* list_footer_view() { return list_footer_view_; }
ui::ComboboxModel* combobox_model() { return combobox_model_.get(); }
std::unique_ptr<ResizeAnimation> resize_animation_;
base::ObserverList<Observer> observers_;
private:
void ToggleExpandState();
const Context context_;
bool is_expanded_ = true;
raw_ptr<views::FlexLayoutView> header_view_ = nullptr;
raw_ptr<Combobox> combobox_view_ = nullptr;
raw_ptr<views::Label> combobox_replacement_label_ = nullptr;
raw_ptr<GlanceablesExpandButton> expand_button_ = nullptr;
raw_ptr<GlanceablesProgressBarView> progress_bar_ = nullptr;
raw_ptr<GlanceablesContentsScrollView> content_scroll_view_ = nullptr;
raw_ptr<views::View> items_container_view_ = nullptr;
raw_ptr<GlanceablesListFooterView> list_footer_view_ = nullptr;
const std::unique_ptr<ui::ComboboxModel> combobox_model_;
std::optional<ui::ThroughputTracker> resize_throughput_tracker_;
base::OnceClosure resize_animation_ended_closure_;
raw_ptr<ErrorMessageToast> error_message_ = nullptr;
};
}
#endif