• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
flip_horizontally()42   bool flip_horizontally() const { return flip_horizontally_; }
y_offset()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.
widget()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).
expanded()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