浏览代码

NotificationServer: Expand the notification when hovered

Now, instead of showing a tooltip, the entire notification will be
shown when the user hovers over a notification. In the future, limiting
the amount of lines shown within the notification and moving extra lines
to the tooltip again might be a good idea.
sin-ack 4 年之前
父节点
当前提交
48d4062b47

+ 40 - 11
Userland/Services/NotificationServer/NotificationWindow.cpp

@@ -66,8 +66,8 @@ NotificationWindow::NotificationWindow(i32 client_id, const String& text, const
     m_original_rect = rect;
 
     auto& widget = set_main_widget<GUI::Widget>();
-    widget.set_fill_with_background_color(true);
 
+    widget.set_fill_with_background_color(true);
     widget.set_layout<GUI::HorizontalBoxLayout>();
     widget.layout()->set_margins({ 8, 8, 8, 8 });
     widget.layout()->set_spacing(6);
@@ -87,13 +87,10 @@ NotificationWindow::NotificationWindow(i32 client_id, const String& text, const
     m_text_label = &left_container.add<GUI::Label>(text);
     m_text_label->set_text_alignment(Gfx::TextAlignment::CenterLeft);
 
-    widget.set_tooltip(text);
-    m_title_label->set_tooltip(text);
-    m_text_label->set_tooltip(text);
-
-    auto& right_container = widget.add<GUI::Widget>();
-    right_container.set_fixed_width(36);
-    right_container.set_layout<GUI::HorizontalBoxLayout>();
+    // FIXME: There used to be code for setting the tooltip here, but since we
+    // expand the notification now we no longer set the tooltip. Should there be
+    // a limit to the lines shown in an expanded notification, at which point a
+    // tooltip should be set?
 
     on_close = [this] {
         s_windows.remove(m_id);
@@ -111,17 +108,42 @@ RefPtr<NotificationWindow> NotificationWindow::get_window_by_id(i32 id)
     return window.value_or(nullptr);
 }
 
-void NotificationWindow::set_text(const String& value)
+void NotificationWindow::resize_to_fit_text()
+{
+    auto line_height = m_text_label->font().glyph_height();
+    auto total_height = m_text_label->preferred_height();
+
+    m_text_label->set_fixed_height(total_height);
+    set_height(40 - line_height + total_height);
+}
+
+void NotificationWindow::enter_event(Core::Event&)
+{
+    m_hovering = true;
+    resize_to_fit_text();
+    move_to_front();
+}
+
+void NotificationWindow::leave_event(Core::Event&)
+{
+    m_hovering = false;
+    m_text_label->set_fixed_height(-1);
+    set_height(40);
+}
+
+void NotificationWindow::set_text(String const& value)
 {
     m_text_label->set_text(value);
+    if (m_hovering)
+        resize_to_fit_text();
 }
 
-void NotificationWindow::set_title(const String& value)
+void NotificationWindow::set_title(String const& value)
 {
     m_title_label->set_text(value);
 }
 
-void NotificationWindow::set_image(const Gfx::ShareableBitmap& image)
+void NotificationWindow::set_image(Gfx::ShareableBitmap const& image)
 {
     m_image->set_visible(image.is_valid());
     if (image.is_valid()) {
@@ -129,6 +151,13 @@ void NotificationWindow::set_image(const Gfx::ShareableBitmap& image)
     }
 }
 
+void NotificationWindow::set_height(int height)
+{
+    auto rect = this->rect();
+    rect.set_height(height);
+    set_rect(rect);
+}
+
 void NotificationWindow::screen_rects_change_event(GUI::ScreenRectsChangeEvent& event)
 {
     update_notification_window_locations(event.rects()[event.main_screen_index()]);

+ 8 - 0
Userland/Services/NotificationServer/NotificationWindow.h

@@ -24,17 +24,25 @@ public:
 
     static RefPtr<NotificationWindow> get_window_by_id(i32 id);
 
+protected:
+    virtual void enter_event(Core::Event&) override;
+    virtual void leave_event(Core::Event&) override;
+
 private:
     NotificationWindow(i32 client_id, const String& text, const String& title, const Gfx::ShareableBitmap&);
 
     virtual void screen_rects_change_event(GUI::ScreenRectsChangeEvent&) override;
 
+    void resize_to_fit_text();
+    void set_height(int);
+
     Gfx::IntRect m_original_rect;
     i32 m_id;
 
     GUI::Label* m_text_label;
     GUI::Label* m_title_label;
     GUI::ImageWidget* m_image;
+    bool m_hovering { false };
 };
 
 }