Home | History | Annotate | Download | only in gtk
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_UI_GTK_STATUS_BUBBLE_GTK_H_
      6 #define CHROME_BROWSER_UI_GTK_STATUS_BUBBLE_GTK_H_
      7 #pragma once
      8 
      9 #include <gtk/gtk.h>
     10 
     11 #include <string>
     12 
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/timer.h"
     15 #include "chrome/browser/ui/gtk/owned_widget_gtk.h"
     16 #include "chrome/browser/ui/status_bubble.h"
     17 #include "content/common/notification_observer.h"
     18 #include "content/common/notification_registrar.h"
     19 #include "googleurl/src/gurl.h"
     20 #include "ui/base/animation/animation_delegate.h"
     21 #include "ui/base/gtk/gtk_signal.h"
     22 #include "ui/gfx/point.h"
     23 
     24 class GtkThemeService;
     25 class Profile;
     26 
     27 namespace ui {
     28 class SlideAnimation;
     29 }
     30 
     31 // GTK implementation of StatusBubble. Unlike Windows, our status bubble
     32 // doesn't have the nice leave-the-window effect since we can't rely on the
     33 // window manager to not try to be "helpful" and center our popups, etc.
     34 // We therefore position it absolutely in a GtkFixed, that we don't own.
     35 class StatusBubbleGtk : public StatusBubble,
     36                         public NotificationObserver,
     37                         public ui::AnimationDelegate {
     38  public:
     39   explicit StatusBubbleGtk(Profile* profile);
     40   virtual ~StatusBubbleGtk();
     41 
     42   bool flip_horizontally() const { return flip_horizontally_; }
     43   int y_offset() const { return y_offset_; }
     44 
     45   // StatusBubble implementation.
     46   virtual void SetStatus(const string16& status);
     47   virtual void SetURL(const GURL& url, const string16& languages);
     48   virtual void Hide();
     49   virtual void MouseMoved(const gfx::Point& location, bool left_content);
     50 
     51   // ui::AnimationDelegate implementation.
     52   virtual void AnimationEnded(const ui::Animation* animation);
     53   virtual void AnimationProgressed(const ui::Animation* animation);
     54 
     55   // Called when the download shelf becomes visible or invisible.
     56   // This is used by to ensure that the status bubble does not obscure
     57   // the download shelf, when it is visible.
     58   virtual void UpdateDownloadShelfVisibility(bool visible);
     59 
     60   // Overridden from NotificationObserver:
     61   virtual void Observe(NotificationType type,
     62                        const NotificationSource& source,
     63                        const NotificationDetails& details);
     64 
     65   // Top of the widget hierarchy for a StatusBubble. This top level widget is
     66   // guarenteed to have its gtk_widget_name set to "status-bubble" for
     67   // identification.
     68   GtkWidget* widget() { return container_.get(); }
     69 
     70  private:
     71   // Sets the text of the label widget and controls visibility. (As contrasted
     72   // with setting the current status or URL text, which may be ignored for now).
     73   void SetStatusTextTo(const std::string& status_utf8);
     74 
     75   // Sets the status text to the current value of |url_|, eliding it as
     76   // necessary.
     77   void SetStatusTextToURL();
     78 
     79   // Sets the status bubble's location in the parent GtkFixed, shows the widget
     80   // and makes sure that the status bubble has the highest z-order.
     81   void Show();
     82 
     83   // Builds the widgets, containers, etc.
     84   void InitWidgets();
     85 
     86   // Notification from the window that we should retheme ourself.
     87   void UserChangedTheme();
     88 
     89   // Sets whether the bubble should be flipped horizontally and displayed on the
     90   // opposite side of the tab contents.  Reshapes the container and queues a
     91   // redraw if necessary.
     92   void SetFlipHorizontally(bool flip_horizontally);
     93 
     94   // Expand the bubble up to the full width of the browser, so that the entire
     95   // URL may be seen. Called after the user hovers over a link for sufficient
     96   // time.
     97   void ExpandURL();
     98 
     99   // Adjust the actual size of the bubble by changing the label's size request.
    100   void UpdateLabelSizeRequest();
    101 
    102   // Returns true if the status bubble is in the expand-state (i.e., is
    103   // currently expanded or in the process of expanding).
    104   bool expanded() {
    105     return expand_animation_.get();
    106   }
    107 
    108   CHROMEGTK_CALLBACK_1(StatusBubbleGtk, gboolean, HandleMotionNotify,
    109                        GdkEventMotion*);
    110 
    111   CHROMEGTK_CALLBACK_1(StatusBubbleGtk, gboolean, HandleEnterNotify,
    112                        GdkEventCrossing*);
    113 
    114   NotificationRegistrar registrar_;
    115 
    116   // Provides colors.
    117   GtkThemeService* theme_service_;
    118 
    119   // The toplevel event box.
    120   OwnedWidgetGtk container_;
    121 
    122   // The GtkAlignment holding |label_|.
    123   GtkWidget* padding_;
    124 
    125   // The GtkLabel holding the text.
    126   OwnedWidgetGtk label_;
    127 
    128   // The status text we want to display when there are no URLs to display.
    129   std::string status_text_;
    130 
    131   // The URL we are displaying for.
    132   GURL url_;
    133 
    134   // The possibly elided url text we want to display.
    135   std::string url_text_;
    136 
    137   // Used to determine the character set that the user can read (for eliding
    138   // the url text).
    139   string16 languages_;
    140 
    141   // A timer that hides our window after a delay.
    142   base::OneShotTimer<StatusBubbleGtk> hide_timer_;
    143 
    144   // A timer that expands our window after a delay.
    145   base::OneShotTimer<StatusBubbleGtk> expand_timer_;
    146 
    147   // The animation for resizing the status bubble on long hovers.
    148   scoped_ptr<ui::SlideAnimation> expand_animation_;
    149 
    150   // The start and end width of the current resize animation.
    151   int start_width_;
    152   int desired_width_;
    153 
    154   // Should the bubble be flipped horizontally (e.g. displayed on the right for
    155   // an LTR language)?  We move the bubble to the other side of the tab contents
    156   // rather than sliding it down when the download shelf is visible.
    157   bool flip_horizontally_;
    158 
    159   // Vertical offset used to hide the status bubble as the pointer nears it.
    160   int y_offset_;
    161 
    162   // If the download shelf is visible, do not obscure it.
    163   bool download_shelf_is_visible_;
    164 
    165   // 'location' and 'left_content' values from the last invocation of
    166   // MouseMoved().  We hang onto these so we can move the bubble if necessary
    167   // when its text changes, triggering a size change.
    168   gfx::Point last_mouse_location_;
    169   bool last_mouse_left_content_;
    170 
    171   // Shortly after the cursor enters the status bubble, we'll get a message
    172   // that the cursor left the content area. This lets us ignore that.
    173   bool ignore_next_left_content_;
    174 };
    175 
    176 #endif  // CHROME_BROWSER_UI_GTK_STATUS_BUBBLE_GTK_H_
    177