#ifndef UI_MESSAGE_CENTER_VIEWS_MESSAGE_VIEW_H_
#define UI_MESSAGE_CENTER_VIEWS_MESSAGE_VIEW_H_
#include <memory>
#include <string>
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "build/chromeos_buildflags.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/message_center/message_center_export.h"
#include "ui/message_center/notification_list.h"
#include "ui/message_center/public/cpp/notification.h"
#include "ui/message_center/public/cpp/notification_delegate.h"
#include "ui/message_center/public/cpp/notifier_id.h"
#include "ui/views/animation/slide_out_controller.h"
#include "ui/views/animation/slide_out_controller_delegate.h"
#include "ui/views/controls/focus_ring.h"
#include "ui/views/controls/highlight_path_generator.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/view.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "base/time/time.h"
#endif
namespace views {
class ScrollView;
}
namespace message_center {
namespace test {
class MessagePopupCollectionTest;
}
class Notification;
class NotificationControlButtonsView;
class MESSAGE_CENTER_EXPORT MessageView
: public views::View,
public views::SlideOutControllerDelegate,
public views::FocusChangeListener {
public:
static const char kViewClassName[];
class Observer : public base::CheckedObserver {
public:
virtual void OnSlideStarted(const std::string& notification_id) {}
virtual void OnSlideChanged(const std::string& notification_id) {}
virtual void OnSlideEnded(const std::string& notification_id) {}
virtual void OnPreSlideOut(const std::string& notification_id) {}
virtual void OnSlideOut(const std::string& notification_id) {}
virtual void OnCloseButtonPressed(const std::string& notification_id) {}
virtual void OnSettingsButtonPressed(const std::string& notification_id) {}
virtual void OnSnoozeButtonPressed(const std::string& notification_id) {}
};
enum class Mode {
NORMAL = 0,
PINNED = 1,
SETTING = 2,
};
explicit MessageView(const Notification& notification);
MessageView(const MessageView&) = delete;
MessageView& operator=(const MessageView&) = delete;
~MessageView() override;
virtual void AddGroupNotification(const Notification& notification) {}
virtual views::View* FindGroupNotificationView(
const std::string& notification_id);
virtual void PopulateGroupNotifications(
const std::vector<const Notification*>& notifications) {}
virtual void RemoveGroupNotification(const std::string& notification_id) {}
std::u16string CreateAccessibleName(const Notification& notification);
virtual void UpdateWithNotification(const Notification& notification);
void SetIsNested();
virtual NotificationControlButtonsView* GetControlButtonsView() const = 0;
virtual void SetExpanded(bool expanded);
virtual bool IsExpanded() const;
virtual bool IsAutoExpandingAllowed() const;
virtual bool IsManuallyExpandedOrCollapsed() const;
virtual void SetManuallyExpandedOrCollapsed(ExpandState state);
virtual void CloseSwipeControl();
virtual void SlideOutAndClose(int direction);
virtual void UpdateCornerRadius(int top_radius, int bottom_radius);
virtual void OnContainerAnimationStarted();
virtual void OnContainerAnimationEnded();
void OnCloseButtonPressed();
virtual void OnSettingsButtonPressed(const ui::Event& event);
virtual void OnSnoozeButtonPressed(const ui::Event& event);
#if BUILDFLAG(IS_CHROMEOS_ASH)
virtual base::TimeDelta GetBoundsAnimationDuration(
const Notification& notification) const;
#endif
void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
bool OnMousePressed(const ui::MouseEvent& event) override;
bool OnMouseDragged(const ui::MouseEvent& event) override;
void OnMouseReleased(const ui::MouseEvent& event) override;
void OnMouseEntered(const ui::MouseEvent& event) override;
bool OnKeyPressed(const ui::KeyEvent& event) override;
bool OnKeyReleased(const ui::KeyEvent& event) override;
void OnPaint(gfx::Canvas* canvas) override;
void OnBlur() override;
void OnGestureEvent(ui::GestureEvent* event) override;
void RemovedFromWidget() override;
void AddedToWidget() override;
const char* GetClassName() const override;
void OnThemeChanged() override;
ui::Layer* GetSlideOutLayer() override;
void OnSlideStarted() override;
void OnSlideChanged(bool in_progress) override;
void OnSlideOut() override;
void OnWillChangeFocus(views::View* before, views::View* now) override;
void OnDidChangeFocus(views::View* before, views::View* now) override;
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
Mode GetMode() const;
virtual float GetSlideAmount() const;
void SetSettingMode(bool setting_mode);
void DisableSlideForcibly(bool disable);
void SetSlideButtonWidth(int coutrol_button_width);
void set_notification_id(const std::string& notification_id) {
notification_id_ = notification_id;
}
std::string notification_id() const { return notification_id_; }
NotifierId notifier_id() const { return notifier_id_; }
base::Time timestamp() const { return timestamp_; }
bool pinned() const { return pinned_; }
bool is_active() const { return is_active_; }
void set_parent_message_view(MessageView* parent_message_view) {
parent_message_view_ = parent_message_view;
}
MessageView* parent_message_view() { return parent_message_view_; }
void set_scroller(views::ScrollView* scroller) { scroller_ = scroller; }
protected:
class HighlightPathGenerator : public views::HighlightPathGenerator {
public:
HighlightPathGenerator();
HighlightPathGenerator(const HighlightPathGenerator&) = delete;
HighlightPathGenerator& operator=(const HighlightPathGenerator&) = delete;
SkPath GetHighlightPath(const views::View* view) override;
};
virtual void UpdateControlButtonsVisibility();
virtual void SetDrawBackgroundAsActive(bool active);
virtual void UpdateBackgroundPainter();
void UpdateControlButtonsVisibilityWithNotification(
const Notification& notification);
void SetCornerRadius(int top_radius, int bottom_radius);
views::ScrollView* scroller() { return scroller_; }
base::ObserverList<Observer>* observers() { return &observers_; }
bool is_nested() const { return is_nested_; }
int bottom_radius() const { return bottom_radius_; }
views::SlideOutController* slide_out_controller_for_test() {
return &slide_out_controller_;
}
private:
friend class test::MessagePopupCollectionTest;
SkPath GetHighlightPath() const;
views::SlideOutController::SlideMode CalculateSlideMode() const;
bool ShouldShowControlButtons() const;
bool ShouldParentHandleSlide() const;
void UpdateNestedBorder();
std::string notification_id_;
const NotifierId notifier_id_;
base::Time timestamp_;
bool is_active_ = false;
bool pinned_ = false;
bool setting_mode_ = false;
bool is_nested_ = false;
bool disable_slide_ = false;
bool is_sliding_ = false;
raw_ptr<MessageView> parent_message_view_ = nullptr;
raw_ptr<views::FocusManager> focus_manager_ = nullptr;
raw_ptr<views::ScrollView> scroller_ = nullptr;
views::SlideOutController slide_out_controller_;
base::ObserverList<Observer> observers_;
int top_radius_ = 0;
int bottom_radius_ = 0;
};
}
#endif