1 // Copyright (c) 2012 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.
5 #ifndef CHROME_BROWSER_UI_GTK_STATUS_BUBBLE_GTK_H_
6 #define CHROME_BROWSER_UI_GTK_STATUS_BUBBLE_GTK_H_
12 #include "base/compiler_specific.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/timer/timer.h"
15 #include "chrome/browser/ui/status_bubble.h"
16 #include "content/public/browser/notification_observer.h"
17 #include "content/public/browser/notification_registrar.h"
18 #include "ui/base/gtk/gtk_signal.h"
19 #include "ui/base/gtk/owned_widget_gtk.h"
20 #include "ui/gfx/animation/animation_delegate.h"
21 #include "ui/gfx/point.h"
24 class GtkThemeService
;
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 content::NotificationObserver
,
37 public gfx::AnimationDelegate
{
39 explicit StatusBubbleGtk(Profile
* profile
);
40 virtual ~StatusBubbleGtk();
42 bool flip_horizontally() const { return flip_horizontally_
; }
43 int y_offset() const { return y_offset_
; }
45 // StatusBubble implementation.
46 virtual void SetStatus(const base::string16
& status
) OVERRIDE
;
47 virtual void SetURL(const GURL
& url
, const std::string
& languages
) OVERRIDE
;
48 virtual void Hide() OVERRIDE
;
49 virtual void MouseMoved(const gfx::Point
& location
,
50 bool left_content
) OVERRIDE
;
52 // gfx::AnimationDelegate implementation.
53 virtual void AnimationEnded(const gfx::Animation
* animation
) OVERRIDE
;
54 virtual void AnimationProgressed(const gfx::Animation
* animation
) OVERRIDE
;
56 // Called when the download shelf becomes visible or invisible.
57 // This is used by to ensure that the status bubble does not obscure
58 // the download shelf, when it is visible.
59 virtual void UpdateDownloadShelfVisibility(bool visible
) OVERRIDE
;
61 // Overridden from content::NotificationObserver:
62 virtual void Observe(int type
,
63 const content::NotificationSource
& source
,
64 const content::NotificationDetails
& details
) OVERRIDE
;
66 // Top of the widget hierarchy for a StatusBubble. This top level widget is
67 // guarenteed to have its gtk_widget_name set to "status-bubble" for
69 GtkWidget
* widget() { return container_
.get(); }
72 // Sets the text of the label widget and controls visibility. (As contrasted
73 // with setting the current status or URL text, which may be ignored for now).
74 void SetStatusTextTo(const std::string
& status_utf8
);
76 // Sets the status text to the current value of |url_|, eliding it as
78 void SetStatusTextToURL();
80 // Sets the status bubble's location in the parent GtkFixed, shows the widget
81 // and makes sure that the status bubble has the highest z-order.
84 // Builds the widgets, containers, etc.
87 // Notification from the window that we should retheme ourself.
88 void UserChangedTheme();
90 // Sets whether the bubble should be flipped horizontally and displayed on the
91 // opposite side of the tab contents. Reshapes the container and queues a
92 // redraw if necessary.
93 void SetFlipHorizontally(bool flip_horizontally
);
95 // Expand the bubble up to the full width of the browser, so that the entire
96 // URL may be seen. Called after the user hovers over a link for sufficient
100 // Adjust the actual size of the bubble by changing the label's size request.
101 void UpdateLabelSizeRequest();
103 // Returns true if the status bubble is in the expand-state (i.e., is
104 // currently expanded or in the process of expanding).
106 return expand_animation_
.get();
109 CHROMEGTK_CALLBACK_1(StatusBubbleGtk
, gboolean
, HandleMotionNotify
,
112 CHROMEGTK_CALLBACK_1(StatusBubbleGtk
, gboolean
, HandleEnterNotify
,
115 content::NotificationRegistrar registrar_
;
118 GtkThemeService
* theme_service_
;
120 // The toplevel event box.
121 ui::OwnedWidgetGtk container_
;
123 // The GtkAlignment holding |label_|.
126 // The GtkLabel holding the text.
127 ui::OwnedWidgetGtk label_
;
129 // The status text we want to display when there are no URLs to display.
130 std::string status_text_
;
132 // The URL we are displaying for.
135 // The possibly elided url text we want to display.
136 std::string url_text_
;
138 // Used to determine the character set that the user can read (for eliding
140 std::string languages_
;
142 // A timer that hides our window after a delay.
143 base::OneShotTimer
<StatusBubbleGtk
> hide_timer_
;
145 // A timer that expands our window after a delay.
146 base::OneShotTimer
<StatusBubbleGtk
> expand_timer_
;
148 // The animation for resizing the status bubble on long hovers.
149 scoped_ptr
<gfx::SlideAnimation
> expand_animation_
;
151 // The start and end width of the current resize animation.
155 // Should the bubble be flipped horizontally (e.g. displayed on the right for
156 // an LTR language)? We move the bubble to the other side of the tab contents
157 // rather than sliding it down when the download shelf is visible.
158 bool flip_horizontally_
;
160 // Vertical offset used to hide the status bubble as the pointer nears it.
163 // If the download shelf is visible, do not obscure it.
164 bool download_shelf_is_visible_
;
166 // 'location' and 'left_content' values from the last invocation of
167 // MouseMoved(). We hang onto these so we can move the bubble if necessary
168 // when its text changes, triggering a size change.
169 gfx::Point last_mouse_location_
;
170 bool last_mouse_left_content_
;
172 // Shortly after the cursor enters the status bubble, we'll get a message
173 // that the cursor left the content area. This lets us ignore that.
174 bool ignore_next_left_content_
;
177 #endif // CHROME_BROWSER_UI_GTK_STATUS_BUBBLE_GTK_H_