| Index: chrome/browser/ui/gtk/tabs/tab_renderer_gtk.h
|
| diff --git a/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.h b/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..032353c6c5efc240e398401bed6dd963c57dc1d1
|
| --- /dev/null
|
| +++ b/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.h
|
| @@ -0,0 +1,456 @@
|
| +// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef CHROME_BROWSER_UI_GTK_TABS_TAB_RENDERER_GTK_H_
|
| +#define CHROME_BROWSER_UI_GTK_TABS_TAB_RENDERER_GTK_H_
|
| +#pragma once
|
| +
|
| +#include <gtk/gtk.h>
|
| +#include <map>
|
| +
|
| +#include "app/gtk_signal.h"
|
| +#include "base/basictypes.h"
|
| +#include "base/scoped_ptr.h"
|
| +#include "base/string16.h"
|
| +#include "chrome/browser/gtk/owned_widget_gtk.h"
|
| +#include "chrome/common/notification_observer.h"
|
| +#include "chrome/common/notification_registrar.h"
|
| +#include "gfx/canvas.h"
|
| +#include "gfx/font.h"
|
| +#include "gfx/rect.h"
|
| +#include "third_party/skia/include/core/SkBitmap.h"
|
| +#include "ui/base/animation/animation_delegate.h"
|
| +
|
| +namespace gfx {
|
| +class Size;
|
| +} // namespace gfx
|
| +
|
| +class CustomDrawButton;
|
| +class GtkThemeProvider;
|
| +class TabContents;
|
| +class ThemeProvider;
|
| +
|
| +namespace ui {
|
| +class SlideAnimation;
|
| +class ThrobAnimation;
|
| +}
|
| +
|
| +class TabRendererGtk : public ui::AnimationDelegate,
|
| + public NotificationObserver {
|
| + public:
|
| + // Possible animation states.
|
| + enum AnimationState {
|
| + ANIMATION_NONE,
|
| + ANIMATION_WAITING,
|
| + ANIMATION_LOADING
|
| + };
|
| +
|
| + class LoadingAnimation : public NotificationObserver {
|
| + public:
|
| + struct Data {
|
| + explicit Data(ThemeProvider* theme_provider);
|
| + Data(int loading, int waiting, int waiting_to_loading);
|
| +
|
| + SkBitmap* waiting_animation_frames;
|
| + SkBitmap* loading_animation_frames;
|
| + int loading_animation_frame_count;
|
| + int waiting_animation_frame_count;
|
| + int waiting_to_loading_frame_count_ratio;
|
| + };
|
| +
|
| + explicit LoadingAnimation(ThemeProvider* theme_provider);
|
| +
|
| + // Used in unit tests to inject specific data.
|
| + explicit LoadingAnimation(const LoadingAnimation::Data& data);
|
| +
|
| + virtual ~LoadingAnimation();
|
| +
|
| + // Advance the loading animation to the next frame, or hide the animation if
|
| + // the tab isn't loading. Returns |true| if the icon area needs to be
|
| + // repainted.
|
| + bool ValidateLoadingAnimation(AnimationState animation_state);
|
| +
|
| + AnimationState animation_state() const { return animation_state_; }
|
| + int animation_frame() const { return animation_frame_; }
|
| +
|
| + const SkBitmap* waiting_animation_frames() const {
|
| + return data_->waiting_animation_frames;
|
| + }
|
| + const SkBitmap* loading_animation_frames() const {
|
| + return data_->loading_animation_frames;
|
| + }
|
| +
|
| + // Provide NotificationObserver implementation.
|
| + virtual void Observe(NotificationType type,
|
| + const NotificationSource& source,
|
| + const NotificationDetails& details);
|
| +
|
| + private:
|
| + scoped_ptr<Data> data_;
|
| +
|
| + // Used to listen for theme change notifications.
|
| + NotificationRegistrar registrar_;
|
| +
|
| + // Gives us our throbber images.
|
| + ThemeProvider* theme_provider_;
|
| +
|
| + // Current state of the animation.
|
| + AnimationState animation_state_;
|
| +
|
| + // The current index into the Animation image strip.
|
| + int animation_frame_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(LoadingAnimation);
|
| + };
|
| +
|
| + explicit TabRendererGtk(ThemeProvider* theme_provider);
|
| + virtual ~TabRendererGtk();
|
| +
|
| + // TabContents. If only the loading state was updated, the loading_only flag
|
| + // should be specified. If other things change, set this flag to false to
|
| + // update everything.
|
| + virtual void UpdateData(TabContents* contents, bool app, bool loading_only);
|
| +
|
| + // Sets the blocked state of the tab.
|
| + void SetBlocked(bool pinned);
|
| + bool is_blocked() const;
|
| +
|
| + // Sets the mini-state of the tab.
|
| + void set_mini(bool mini) { data_.mini = mini; }
|
| + bool mini() const { return data_.mini; }
|
| +
|
| + // Sets the app state of the tab.
|
| + void set_app(bool app) { data_.app = app; }
|
| + bool app() const { return data_.app; }
|
| +
|
| + // Are we in the process of animating a mini tab state change on this tab?
|
| + void set_animating_mini_change(bool value) {
|
| + data_.animating_mini_change = value;
|
| + }
|
| +
|
| + // Updates the display to reflect the contents of this TabRenderer's model.
|
| + void UpdateFromModel();
|
| +
|
| + // Returns true if the Tab is selected, false otherwise.
|
| + virtual bool IsSelected() const;
|
| +
|
| + // Returns true if the Tab is visible, false otherwise.
|
| + virtual bool IsVisible() const;
|
| +
|
| + // Sets the visibility of the Tab.
|
| + virtual void SetVisible(bool visible) const;
|
| +
|
| + // Paints the tab into |canvas|.
|
| + virtual void Paint(gfx::Canvas* canvas);
|
| +
|
| + // Paints the tab into a SkBitmap.
|
| + virtual SkBitmap PaintBitmap();
|
| +
|
| + // Paints the tab, and keeps the result server-side. The returned surface must
|
| + // be freed with cairo_surface_destroy().
|
| + virtual cairo_surface_t* PaintToSurface();
|
| +
|
| + // There is no PaintNow available, so the fastest we can do is schedule a
|
| + // paint with the windowing system.
|
| + virtual void SchedulePaint();
|
| +
|
| + // Notifies the Tab that the close button has been clicked.
|
| + virtual void CloseButtonClicked();
|
| +
|
| + // Sets the bounds of the tab.
|
| + virtual void SetBounds(const gfx::Rect& bounds);
|
| +
|
| + // Provide NotificationObserver implementation.
|
| + virtual void Observe(NotificationType type,
|
| + const NotificationSource& source,
|
| + const NotificationDetails& details);
|
| +
|
| + // Advance the loading animation to the next frame, or hide the animation if
|
| + // the tab isn't loading. Returns |true| if the icon area needs to be
|
| + // repainted.
|
| + bool ValidateLoadingAnimation(AnimationState animation_state);
|
| +
|
| + // Repaint only the area of the tab that contains the favicon.
|
| + void PaintFavIconArea(GdkEventExpose* event);
|
| +
|
| + // Returns whether the Tab should display a favicon.
|
| + bool ShouldShowIcon() const;
|
| +
|
| + // Returns the minimum possible size of a single unselected Tab.
|
| + static gfx::Size GetMinimumUnselectedSize();
|
| + // Returns the minimum possible size of a selected Tab. Selected tabs must
|
| + // always show a close button and have a larger minimum size than unselected
|
| + // tabs.
|
| + static gfx::Size GetMinimumSelectedSize();
|
| + // Returns the preferred size of a single Tab, assuming space is
|
| + // available.
|
| + static gfx::Size GetStandardSize();
|
| +
|
| + // Returns the width for mini-tabs. Mini-tabs always have this width.
|
| + static int GetMiniWidth();
|
| +
|
| + // Loads the images to be used for the tab background.
|
| + static void LoadTabImages();
|
| +
|
| + // Sets the colors used for painting text on the tabs.
|
| + static void SetSelectedTitleColor(SkColor color);
|
| + static void SetUnselectedTitleColor(SkColor color);
|
| +
|
| + static gfx::Font* title_font() { return title_font_; }
|
| +
|
| + // Returns the bounds of the Tab.
|
| + int x() const { return bounds_.x(); }
|
| + int y() const { return bounds_.y(); }
|
| + int width() const { return bounds_.width(); }
|
| + int height() const { return bounds_.height(); }
|
| +
|
| + gfx::Rect bounds() const { return bounds_; }
|
| +
|
| + gfx::Rect favicon_bounds() const { return favicon_bounds_; }
|
| +
|
| + // Returns the non-mirrored (LTR) bounds of this tab.
|
| + gfx::Rect GetNonMirroredBounds(GtkWidget* parent) const;
|
| +
|
| + // Returns the requested bounds of the tab.
|
| + gfx::Rect GetRequisition() const;
|
| +
|
| + GtkWidget* widget() const { return tab_.get(); }
|
| +
|
| + // Start/stop the mini-tab title animation.
|
| + void StartMiniTabTitleAnimation();
|
| + void StopMiniTabTitleAnimation();
|
| +
|
| + void set_vertical_offset(int offset) { background_offset_y_ = offset; }
|
| +
|
| + protected:
|
| + const gfx::Rect& title_bounds() const { return title_bounds_; }
|
| + const gfx::Rect& close_button_bounds() const { return close_button_bounds_; }
|
| +
|
| + // Returns the title of the Tab.
|
| + string16 GetTitle() const;
|
| +
|
| + // enter-notify-event handler that signals when the mouse enters the tab.
|
| + CHROMEGTK_CALLBACK_1(TabRendererGtk, gboolean, OnEnterNotifyEvent,
|
| + GdkEventCrossing*);
|
| +
|
| + // leave-notify-event handler that signals when the mouse enters the tab.
|
| + CHROMEGTK_CALLBACK_1(TabRendererGtk, gboolean, OnLeaveNotifyEvent,
|
| + GdkEventCrossing*);
|
| +
|
| + private:
|
| + class FavIconCrashAnimation;
|
| +
|
| + // The data structure used to hold cached bitmaps. We need to manually free
|
| + // the bitmap in CachedBitmap when we remove it from |cached_bitmaps_|. We
|
| + // handle this when we replace images in the map and in the destructor.
|
| + struct CachedBitmap {
|
| + int bg_offset_x;
|
| + int bg_offset_y;
|
| + SkBitmap* bitmap;
|
| + };
|
| + typedef std::map<std::pair<const SkBitmap*, const SkBitmap*>, CachedBitmap>
|
| + BitmapCache;
|
| +
|
| + // Model data. We store this here so that we don't need to ask the underlying
|
| + // model, which is tricky since instances of this object can outlive the
|
| + // corresponding objects in the underlying model.
|
| + struct TabData {
|
| + TabData()
|
| + : is_default_favicon(false),
|
| + loading(false),
|
| + crashed(false),
|
| + off_the_record(false),
|
| + show_icon(true),
|
| + mini(false),
|
| + blocked(false),
|
| + animating_mini_change(false),
|
| + app(false) {
|
| + }
|
| +
|
| + SkBitmap favicon;
|
| + bool is_default_favicon;
|
| + string16 title;
|
| + bool loading;
|
| + bool crashed;
|
| + bool off_the_record;
|
| + bool show_icon;
|
| + bool mini;
|
| + bool blocked;
|
| + bool animating_mini_change;
|
| + bool app;
|
| + };
|
| +
|
| + // TODO(jhawkins): Move into TabResources class.
|
| + struct TabImage {
|
| + SkBitmap* image_l;
|
| + SkBitmap* image_c;
|
| + SkBitmap* image_r;
|
| + int l_width;
|
| + int r_width;
|
| + int y_offset;
|
| + };
|
| +
|
| + // Overridden from ui::AnimationDelegate:
|
| + virtual void AnimationProgressed(const ui::Animation* animation);
|
| + virtual void AnimationCanceled(const ui::Animation* animation);
|
| + virtual void AnimationEnded(const ui::Animation* animation);
|
| +
|
| + // Starts/Stops the crash animation.
|
| + void StartCrashAnimation();
|
| + void StopCrashAnimation();
|
| +
|
| + // Return true if the crash animation is currently running.
|
| + bool IsPerformingCrashAnimation() const;
|
| +
|
| + // Set the temporary offset for the favicon. This is used during animation.
|
| + void SetFavIconHidingOffset(int offset);
|
| +
|
| + void DisplayCrashedFavIcon();
|
| + void ResetCrashedFavIcon();
|
| +
|
| + // Generates the bounds for the interior items of the tab.
|
| + void Layout();
|
| +
|
| + // Returns the local bounds of the tab. This returns the rect
|
| + // {0, 0, width(), height()} for now, as we don't yet support borders.
|
| + gfx::Rect GetLocalBounds();
|
| +
|
| + // Moves the close button widget within the GtkFixed container.
|
| + void MoveCloseButtonWidget();
|
| +
|
| + // Returns the largest of the favicon, title text, and the close button.
|
| + static int GetContentHeight();
|
| +
|
| + // A helper method for generating the masked bitmaps used to draw the curved
|
| + // edges of tabs. We cache the generated bitmaps because they can take a
|
| + // long time to compute.
|
| + SkBitmap* GetMaskedBitmap(const SkBitmap* mask,
|
| + const SkBitmap* background,
|
| + int bg_offset_x,
|
| + int bg_offset_y);
|
| + BitmapCache cached_bitmaps_;
|
| +
|
| + // Paints the tab, minus the close button.
|
| + void PaintTab(GdkEventExpose* event);
|
| +
|
| + // Paint various portions of the Tab
|
| + void PaintTitle(gfx::Canvas* canvas);
|
| + void PaintIcon(gfx::Canvas* canvas);
|
| + void PaintTabBackground(gfx::Canvas* canvas);
|
| + void PaintInactiveTabBackground(gfx::Canvas* canvas);
|
| + void PaintActiveTabBackground(gfx::Canvas* canvas);
|
| + void PaintLoadingAnimation(gfx::Canvas* canvas);
|
| +
|
| + // Returns the number of favicon-size elements that can fit in the tab's
|
| + // current size.
|
| + int IconCapacity() const;
|
| +
|
| +
|
| + // Returns whether the Tab should display a close button.
|
| + bool ShouldShowCloseBox() const;
|
| +
|
| + CustomDrawButton* MakeCloseButton();
|
| +
|
| + // Gets the throb value for the tab. When a tab is not selected the
|
| + // active background is drawn at |GetThrobValue()|%. This is used for hover
|
| + // and mini-tab title change effects.
|
| + double GetThrobValue();
|
| +
|
| + // Handles the clicked signal for the close button.
|
| + CHROMEGTK_CALLBACK_0(TabRendererGtk, void, OnCloseButtonClicked);
|
| +
|
| + // Handles middle clicking the close button.
|
| + CHROMEGTK_CALLBACK_1(TabRendererGtk, gboolean, OnCloseButtonMouseRelease,
|
| + GdkEventButton*);
|
| +
|
| + // expose-event handler that redraws the tab.
|
| + CHROMEGTK_CALLBACK_1(TabRendererGtk, gboolean, OnExposeEvent,
|
| + GdkEventExpose*);
|
| +
|
| + // size-allocate handler used to update the current bounds of the tab.
|
| + CHROMEGTK_CALLBACK_1(TabRendererGtk, void, OnSizeAllocate, GtkAllocation*);
|
| +
|
| + // TODO(jhawkins): Move to TabResources.
|
| + static void InitResources();
|
| + static bool initialized_;
|
| +
|
| + // The bounds of various sections of the display.
|
| + gfx::Rect favicon_bounds_;
|
| + gfx::Rect title_bounds_;
|
| + gfx::Rect close_button_bounds_;
|
| +
|
| + TabData data_;
|
| +
|
| + static TabImage tab_active_;
|
| + static TabImage tab_inactive_;
|
| + static TabImage tab_alpha_;
|
| +
|
| + static gfx::Font* title_font_;
|
| + static int title_font_height_;
|
| +
|
| + static int close_button_width_;
|
| + static int close_button_height_;
|
| +
|
| + static SkColor selected_title_color_;
|
| + static SkColor unselected_title_color_;
|
| +
|
| + // The GtkDrawingArea we draw the tab on.
|
| + OwnedWidgetGtk tab_;
|
| +
|
| + // Whether we're showing the icon. It is cached so that we can detect when it
|
| + // changes and layout appropriately.
|
| + bool showing_icon_;
|
| +
|
| + // Whether we are showing the close button. It is cached so that we can
|
| + // detect when it changes and layout appropriately.
|
| + bool showing_close_button_;
|
| +
|
| + // The offset used to animate the favicon location.
|
| + int fav_icon_hiding_offset_;
|
| +
|
| + // The animation object used to swap the favicon with the sad tab icon.
|
| + scoped_ptr<FavIconCrashAnimation> crash_animation_;
|
| +
|
| + // Set when the crashed favicon should be displayed.
|
| + bool should_display_crashed_favicon_;
|
| +
|
| + // The bounds of this Tab.
|
| + gfx::Rect bounds_;
|
| +
|
| + // The requested bounds of this tab. These bounds are relative to the
|
| + // tabstrip.
|
| + gfx::Rect requisition_;
|
| +
|
| + // Hover animation.
|
| + scoped_ptr<ui::SlideAnimation> hover_animation_;
|
| +
|
| + // Animation used when the title of an inactive mini-tab changes.
|
| + scoped_ptr<ui::ThrobAnimation> mini_title_animation_;
|
| +
|
| + // Contains the loading animation state.
|
| + LoadingAnimation loading_animation_;
|
| +
|
| + // The offset used to paint the tab theme images.
|
| + int background_offset_x_;
|
| +
|
| + // The vertical offset used to paint the tab theme images. Controlled by the
|
| + // tabstrip and plumbed here to offset the theme image by the size of the
|
| + // alignment in the BrowserTitlebar.
|
| + int background_offset_y_;
|
| +
|
| + GtkThemeProvider* theme_provider_;
|
| +
|
| + // The close button.
|
| + scoped_ptr<CustomDrawButton> close_button_;
|
| +
|
| + // The current color of the close button.
|
| + SkColor close_button_color_;
|
| +
|
| + // Used to listen for theme change notifications.
|
| + NotificationRegistrar registrar_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TabRendererGtk);
|
| +};
|
| +
|
| +#endif // CHROME_BROWSER_UI_GTK_TABS_TAB_RENDERER_GTK_H_
|
|
|