Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Side by Side Diff: chrome/browser/ui/gtk/tabs/tab_renderer_gtk.h

Issue 231733005: Delete the GTK+ port of Chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remerge to ToT Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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_TABS_TAB_RENDERER_GTK_H_
6 #define CHROME_BROWSER_UI_GTK_TABS_TAB_RENDERER_GTK_H_
7
8 #include <gtk/gtk.h>
9 #include <map>
10
11 #include "base/basictypes.h"
12 #include "base/compiler_specific.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/strings/string16.h"
15 #include "chrome/browser/ui/tabs/tab_utils.h"
16 #include "content/public/browser/notification_observer.h"
17 #include "content/public/browser/notification_registrar.h"
18 #include "third_party/skia/include/core/SkBitmap.h"
19 #include "ui/base/gtk/gtk_signal.h"
20 #include "ui/base/gtk/owned_widget_gtk.h"
21 #include "ui/gfx/animation/animation_delegate.h"
22 #include "ui/gfx/canvas.h"
23 #include "ui/gfx/font.h"
24 #include "ui/gfx/image/cairo_cached_surface.h"
25 #include "ui/gfx/rect.h"
26
27 namespace gfx {
28 class CairoCachedSurface;
29 class Image;
30 class Size;
31 class SlideAnimation;
32 class ThrobAnimation;
33 } // namespace gfx
34
35 class CustomDrawButton;
36 class GtkThemeService;
37
38 namespace content {
39 class WebContents;
40 }
41
42 class TabRendererGtk : public gfx::AnimationDelegate,
43 public content::NotificationObserver {
44 public:
45 // Possible animation states.
46 enum AnimationState {
47 ANIMATION_NONE,
48 ANIMATION_WAITING,
49 ANIMATION_LOADING
50 };
51
52 class LoadingAnimation : public content::NotificationObserver {
53 public:
54 struct Data {
55 explicit Data(GtkThemeService* theme_service);
56 Data(int loading, int waiting, int waiting_to_loading);
57
58 int loading_animation_frame_count;
59 int waiting_animation_frame_count;
60 int waiting_to_loading_frame_count_ratio;
61 };
62
63 explicit LoadingAnimation(GtkThemeService* theme_service);
64
65 // Used in unit tests to inject specific data.
66 explicit LoadingAnimation(const LoadingAnimation::Data& data);
67
68 virtual ~LoadingAnimation();
69
70 // Advance the loading animation to the next frame, or hide the animation if
71 // the tab isn't loading. Returns |true| if the icon area needs to be
72 // repainted.
73 bool ValidateLoadingAnimation(AnimationState animation_state);
74
75 AnimationState animation_state() const { return animation_state_; }
76 int animation_frame() const { return animation_frame_; }
77
78 // Provide content::NotificationObserver implementation.
79 virtual void Observe(int type,
80 const content::NotificationSource& source,
81 const content::NotificationDetails& details) OVERRIDE;
82
83 private:
84 scoped_ptr<Data> data_;
85
86 // Used to listen for theme change notifications.
87 content::NotificationRegistrar registrar_;
88
89 // Gives us our throbber images.
90 GtkThemeService* theme_service_;
91
92 // Current state of the animation.
93 AnimationState animation_state_;
94
95 // The current index into the Animation image strip.
96 int animation_frame_;
97
98 DISALLOW_COPY_AND_ASSIGN(LoadingAnimation);
99 };
100
101 explicit TabRendererGtk(GtkThemeService* theme_service);
102 virtual ~TabRendererGtk();
103
104 // Provide content::NotificationObserver implementation.
105 virtual void Observe(int type,
106 const content::NotificationSource& source,
107 const content::NotificationDetails& details) OVERRIDE;
108
109 // WebContents. If only the loading state was updated, the loading_only flag
110 // should be specified. If other things change, set this flag to false to
111 // update everything.
112 virtual void UpdateData(content::WebContents* contents,
113 bool app,
114 bool loading_only);
115
116 // Sets the blocked state of the tab.
117 void SetBlocked(bool pinned);
118 bool is_blocked() const;
119
120 // Sets the mini-state of the tab.
121 void set_mini(bool mini) { data_.mini = mini; }
122 bool mini() const { return data_.mini; }
123
124 // Sets the app state of the tab.
125 void set_app(bool app) { data_.app = app; }
126 bool app() const { return data_.app; }
127
128 // Are we in the process of animating a mini tab state change on this tab?
129 void set_animating_mini_change(bool value) {
130 data_.animating_mini_change = value;
131 }
132
133 // Updates the display to reflect the contents of this TabRenderer's model.
134 void UpdateFromModel();
135
136 // Returns true if the Tab is active, false otherwise.
137 virtual bool IsActive() const;
138
139 // Set |is_active_| property of this tab.
140 void set_is_active(bool is_active) { is_active_ = is_active; }
141
142 // Returns true if the Tab is selected, false otherwise.
143 virtual bool IsSelected() const;
144
145 // Returns true if the Tab is visible, false otherwise.
146 virtual bool IsVisible() const;
147
148 // Sets the visibility of the Tab.
149 virtual void SetVisible(bool visible) const;
150
151 // Paints the tab using resources from the display that |widget| is on,
152 // drawing into |cr|.
153 void Paint(GtkWidget* widget, cairo_t* cr);
154
155 // Paints the tab, and keeps the result server-side. The returned surface must
156 // be freed with cairo_surface_destroy().
157 cairo_surface_t* PaintToSurface(GtkWidget* widget, cairo_t* cr);
158
159 // There is no PaintNow available, so the fastest we can do is schedule a
160 // paint with the windowing system.
161 void SchedulePaint();
162
163 // Notifies the Tab that the close button has been clicked.
164 virtual void CloseButtonClicked();
165
166 // Sets the bounds of the tab.
167 virtual void SetBounds(const gfx::Rect& bounds);
168
169 // Advance the loading animation to the next frame, or hide the animation if
170 // the tab isn't loading. Returns |true| if the icon area needs to be
171 // repainted.
172 bool ValidateLoadingAnimation(AnimationState animation_state);
173
174 // Repaint only the area of the tab that contains the favicon.
175 void PaintFaviconArea(GtkWidget* widget, cairo_t* cr);
176
177 // Returns whether the Tab should display a favicon.
178 bool ShouldShowIcon() const;
179
180 // Invoked from Layout() to adjust the position of the favicon or media
181 // indicator for mini tabs.
182 void MaybeAdjustLeftForMiniTab(gfx::Rect* bounds) const;
183
184 // Returns the minimum possible size of a single unselected Tab.
185 static gfx::Size GetMinimumUnselectedSize();
186 // Returns the minimum possible size of a selected Tab. Selected tabs must
187 // always show a close button and have a larger minimum size than unselected
188 // tabs.
189 static gfx::Size GetMinimumSelectedSize();
190 // Returns the preferred size of a single Tab, assuming space is
191 // available.
192 static gfx::Size GetStandardSize();
193
194 // Returns the width for mini-tabs. Mini-tabs always have this width.
195 static int GetMiniWidth();
196
197 static gfx::Font* title_font() { return title_font_; }
198
199 // Returns the bounds of the Tab.
200 int x() const { return bounds_.x(); }
201 int y() const { return bounds_.y(); }
202 int width() const { return bounds_.width(); }
203 int height() const { return bounds_.height(); }
204
205 gfx::Rect bounds() const { return bounds_; }
206
207 gfx::Rect favicon_bounds() const { return favicon_bounds_; }
208
209 // Returns the non-mirrored (LTR) bounds of this tab.
210 gfx::Rect GetNonMirroredBounds(GtkWidget* parent) const;
211
212 // Returns the requested bounds of the tab.
213 gfx::Rect GetRequisition() const;
214
215 GtkWidget* widget() const { return tab_.get(); }
216
217 // Start/stop the mini-tab title animation.
218 void StartMiniTabTitleAnimation();
219 void StopMiniTabTitleAnimation();
220
221 void set_vertical_offset(int offset) { background_offset_y_ = offset; }
222
223 protected:
224 const gfx::Rect& title_bounds() const { return title_bounds_; }
225 const gfx::Rect& close_button_bounds() const { return close_button_bounds_; }
226
227 // Raise button to top of Z-order.
228 void Raise() const;
229
230 // Returns the title of the Tab.
231 base::string16 GetTitle() const;
232
233 // enter-notify-event handler that signals when the mouse enters the tab.
234 CHROMEGTK_CALLBACK_1(TabRendererGtk, gboolean, OnEnterNotifyEvent,
235 GdkEventCrossing*);
236
237 // leave-notify-event handler that signals when the mouse enters the tab.
238 CHROMEGTK_CALLBACK_1(TabRendererGtk, gboolean, OnLeaveNotifyEvent,
239 GdkEventCrossing*);
240
241 private:
242 class FaviconCrashAnimation;
243
244 // Model data. We store this here so that we don't need to ask the underlying
245 // model, which is tricky since instances of this object can outlive the
246 // corresponding objects in the underlying model.
247 struct TabData {
248 TabData();
249 ~TabData();
250
251 SkBitmap favicon;
252 gfx::CairoCachedSurface cairo_favicon;
253 bool is_default_favicon;
254 base::string16 title;
255 bool loading;
256 bool crashed;
257 bool incognito;
258 bool show_icon;
259 bool mini;
260 bool blocked;
261 bool animating_mini_change;
262 bool app;
263 TabMediaState media_state;
264 TabMediaState previous_media_state;
265 };
266
267 // Overridden from gfx::AnimationDelegate:
268 virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
269 virtual void AnimationCanceled(const gfx::Animation* animation) OVERRIDE;
270 virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE;
271
272 // Starts/Stops the crash animation.
273 void StartCrashAnimation();
274 void StopCrashAnimation();
275
276 // Return true if the crash animation is currently running.
277 bool IsPerformingCrashAnimation() const;
278
279 // Starts the media indicator fade-in/out animation. There's no stop method
280 // because this is not a continuous animation.
281 void StartMediaIndicatorAnimation();
282
283 // Set the temporary offset for the favicon. This is used during animation.
284 void SetFaviconHidingOffset(int offset);
285
286 void DisplayCrashedFavicon();
287 void ResetCrashedFavicon();
288
289 // Generates the bounds for the interior items of the tab.
290 void Layout();
291
292 // Returns the local bounds of the tab. This returns the rect
293 // {0, 0, width(), height()} for now, as we don't yet support borders.
294 gfx::Rect GetLocalBounds();
295
296 // Moves the close button widget within the GtkFixed container.
297 void MoveCloseButtonWidget();
298
299 // Returns the largest of the favicon, title text, and the close button.
300 static int GetContentHeight();
301
302 void PaintTab(GtkWidget* widget, GdkEventExpose* event);
303
304 // Paint various portions of the Tab
305 void PaintTitle(GtkWidget* widget, cairo_t* cr);
306 void PaintIcon(GtkWidget* widget, cairo_t* cr);
307 void PaintMediaIndicator(GtkWidget* widget, cairo_t* cr);
308 void PaintTabBackground(GtkWidget* widget, cairo_t* cr);
309 void PaintInactiveTabBackground(GtkWidget* widget, cairo_t* cr);
310 void PaintActiveTabBackground(GtkWidget* widget, cairo_t* cr);
311 void PaintLoadingAnimation(GtkWidget* widget, cairo_t* cairo);
312
313 // Draws the given |tab_bg| onto |cr| using the tab shape masks along the
314 // sides for the rounded tab shape.
315 void DrawTabBackground(cairo_t* cr,
316 GtkWidget* widget,
317 const gfx::Image& tab_bg,
318 int offset_x,
319 int offset_y);
320
321 // Draws the tab shadow using the given idr resources onto |cr|.
322 void DrawTabShadow(cairo_t* cr,
323 GtkWidget* widget,
324 int left_idr,
325 int center_idr,
326 int right_idr);
327
328 // Returns the number of favicon-size elements that can fit in the tab's
329 // current size.
330 int IconCapacity() const;
331
332 // Returns whether the Tab should display the media indicator.
333 bool ShouldShowMediaIndicator() const;
334
335 // Returns whether the Tab should display a close button.
336 bool ShouldShowCloseBox() const;
337
338 CustomDrawButton* MakeCloseButton();
339
340 // Gets the throb value for the tab. When a tab is not selected the
341 // active background is drawn at |GetThrobValue()|%. This is used for hover
342 // and mini-tab title change effects.
343 double GetThrobValue();
344
345 // Handles the clicked signal for the close button.
346 CHROMEGTK_CALLBACK_0(TabRendererGtk, void, OnCloseButtonClicked);
347
348 // Handles middle clicking the close button.
349 CHROMEGTK_CALLBACK_1(TabRendererGtk, gboolean, OnCloseButtonMouseRelease,
350 GdkEventButton*);
351
352 // expose-event handler that redraws the tab.
353 CHROMEGTK_CALLBACK_1(TabRendererGtk, gboolean, OnExposeEvent,
354 GdkEventExpose*);
355
356 // size-allocate handler used to update the current bounds of the tab.
357 CHROMEGTK_CALLBACK_1(TabRendererGtk, void, OnSizeAllocate, GtkAllocation*);
358
359 // TODO(jhawkins): Move to TabResources.
360 static void InitResources();
361 static bool initialized_;
362
363 // The bounds of various sections of the display.
364 gfx::Rect favicon_bounds_;
365 gfx::Rect title_bounds_;
366 gfx::Rect media_indicator_bounds_;
367 gfx::Rect close_button_bounds_;
368
369 TabData data_;
370
371 static int tab_active_l_width_;
372 static int tab_active_l_height_;
373 static int tab_inactive_l_width_;
374 static int tab_inactive_l_height_;
375
376 static gfx::Font* title_font_;
377 static int title_font_height_;
378
379 static int close_button_width_;
380 static int close_button_height_;
381
382 content::NotificationRegistrar registrar_;
383
384 // The GtkDrawingArea we draw the tab on.
385 ui::OwnedWidgetGtk tab_;
386
387 // Whether we're showing the icon. It is cached so that we can detect when it
388 // changes and layout appropriately.
389 bool showing_icon_;
390
391 // Whether we're showing the media indicator. It is cached so that we can
392 // detect when it changes and layout appropriately.
393 bool showing_media_indicator_;
394
395 // Whether we are showing the close button. It is cached so that we can
396 // detect when it changes and layout appropriately.
397 bool showing_close_button_;
398
399 // The offset used to animate the favicon location.
400 int favicon_hiding_offset_;
401
402 // The animation object used to swap the favicon with the sad tab icon.
403 scoped_ptr<FaviconCrashAnimation> crash_animation_;
404
405 // Set when the crashed favicon should be displayed.
406 bool should_display_crashed_favicon_;
407
408 // The bounds of this Tab.
409 gfx::Rect bounds_;
410
411 // The requested bounds of this tab. These bounds are relative to the
412 // tabstrip.
413 gfx::Rect requisition_;
414
415 // Hover animation.
416 scoped_ptr<gfx::SlideAnimation> hover_animation_;
417
418 // Animation used when the title of an inactive mini-tab changes.
419 scoped_ptr<gfx::ThrobAnimation> mini_title_animation_;
420
421 // Media indicator fade-in/out animation (i.e., only on show/hide, not a
422 // continuous animation).
423 scoped_ptr<gfx::Animation> media_indicator_animation_;
424 TabMediaState animating_media_state_;
425
426 // Contains the loading animation state.
427 LoadingAnimation loading_animation_;
428
429 // The offset used to paint the tab theme images.
430 int background_offset_x_;
431
432 // The vertical offset used to paint the tab theme images. Controlled by the
433 // tabstrip and plumbed here to offset the theme image by the size of the
434 // alignment in the BrowserTitlebar.
435 int background_offset_y_;
436
437 GtkThemeService* theme_service_;
438
439 // The close button.
440 scoped_ptr<CustomDrawButton> close_button_;
441
442 // The current color of the close button.
443 SkColor close_button_color_;
444
445 // Indicates whether this tab is the active one.
446 bool is_active_;
447
448 // Color of the title text on the selected tab.
449 SkColor selected_title_color_;
450
451 // Color of the title text on an unselected tab.
452 SkColor unselected_title_color_;
453
454 DISALLOW_COPY_AND_ASSIGN(TabRendererGtk);
455 };
456
457 #endif // CHROME_BROWSER_UI_GTK_TABS_TAB_RENDERER_GTK_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698