- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / gtk / status_bubble_gtk.h
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.
4
5 #ifndef CHROME_BROWSER_UI_GTK_STATUS_BUBBLE_GTK_H_
6 #define CHROME_BROWSER_UI_GTK_STATUS_BUBBLE_GTK_H_
7
8 #include <gtk/gtk.h>
9
10 #include <string>
11
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"
22 #include "url/gurl.h"
23
24 class GtkThemeService;
25 class Profile;
26
27 namespace gfx {
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 content::NotificationObserver,
37                         public gfx::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) 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;
51
52   // gfx::AnimationDelegate implementation.
53   virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE;
54   virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
55
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;
60
61   // Overridden from content::NotificationObserver:
62   virtual void Observe(int type,
63                        const content::NotificationSource& source,
64                        const content::NotificationDetails& details) OVERRIDE;
65
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
68   // identification.
69   GtkWidget* widget() { return container_.get(); }
70
71  private:
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);
75
76   // Sets the status text to the current value of |url_|, eliding it as
77   // necessary.
78   void SetStatusTextToURL();
79
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.
82   void Show();
83
84   // Builds the widgets, containers, etc.
85   void InitWidgets();
86
87   // Notification from the window that we should retheme ourself.
88   void UserChangedTheme();
89
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);
94
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
97   // time.
98   void ExpandURL();
99
100   // Adjust the actual size of the bubble by changing the label's size request.
101   void UpdateLabelSizeRequest();
102
103   // Returns true if the status bubble is in the expand-state (i.e., is
104   // currently expanded or in the process of expanding).
105   bool expanded() {
106     return expand_animation_.get();
107   }
108
109   CHROMEGTK_CALLBACK_1(StatusBubbleGtk, gboolean, HandleMotionNotify,
110                        GdkEventMotion*);
111
112   CHROMEGTK_CALLBACK_1(StatusBubbleGtk, gboolean, HandleEnterNotify,
113                        GdkEventCrossing*);
114
115   content::NotificationRegistrar registrar_;
116
117   // Provides colors.
118   GtkThemeService* theme_service_;
119
120   // The toplevel event box.
121   ui::OwnedWidgetGtk container_;
122
123   // The GtkAlignment holding |label_|.
124   GtkWidget* padding_;
125
126   // The GtkLabel holding the text.
127   ui::OwnedWidgetGtk label_;
128
129   // The status text we want to display when there are no URLs to display.
130   std::string status_text_;
131
132   // The URL we are displaying for.
133   GURL url_;
134
135   // The possibly elided url text we want to display.
136   std::string url_text_;
137
138   // Used to determine the character set that the user can read (for eliding
139   // the url text).
140   std::string languages_;
141
142   // A timer that hides our window after a delay.
143   base::OneShotTimer<StatusBubbleGtk> hide_timer_;
144
145   // A timer that expands our window after a delay.
146   base::OneShotTimer<StatusBubbleGtk> expand_timer_;
147
148   // The animation for resizing the status bubble on long hovers.
149   scoped_ptr<gfx::SlideAnimation> expand_animation_;
150
151   // The start and end width of the current resize animation.
152   int start_width_;
153   int desired_width_;
154
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_;
159
160   // Vertical offset used to hide the status bubble as the pointer nears it.
161   int y_offset_;
162
163   // If the download shelf is visible, do not obscure it.
164   bool download_shelf_is_visible_;
165
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_;
171
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_;
175 };
176
177 #endif  // CHROME_BROWSER_UI_GTK_STATUS_BUBBLE_GTK_H_