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#include "chrome/browser/ui/gtk/titlebar_throb_animation.h"
6#include "grit/theme_resources.h"
7#include "third_party/skia/include/core/SkBitmap.h"
8#include "ui/base/resource/resource_bundle.h"
9#include "ui/gfx/skbitmap_operations.h"
10
11namespace {
12
13// We don't bother to clean up these or the pixbufs they contain when we exit.
14std::vector<GdkPixbuf*>* g_throbber_frames = NULL;
15std::vector<GdkPixbuf*>* g_throbber_waiting_frames = NULL;
16
17// Load |resource_id| from the ResourceBundle and split it into a series of
18// square GdkPixbufs that get stored in |frames|.
19void MakeThrobberFrames(int resource_id, std::vector<GdkPixbuf*>* frames) {
20  ui::ResourceBundle &rb = ui::ResourceBundle::GetSharedInstance();
21  SkBitmap frame_strip = rb.GetImageNamed(resource_id).AsBitmap();
22
23  // Each frame of the animation is a square, so we use the height as the
24  // frame size.
25  int frame_size = frame_strip.height();
26  size_t num_frames = frame_strip.width() / frame_size;
27
28  // Make a separate GdkPixbuf for each frame of the animation.
29  for (size_t i = 0; i < num_frames; ++i) {
30    SkBitmap frame = SkBitmapOperations::CreateTiledBitmap(frame_strip,
31        i * frame_size, 0, frame_size, frame_size);
32    frames->push_back(gfx::GdkPixbufFromSkBitmap(frame));
33  }
34}
35
36}  // namespace
37
38// TODO(tc): Handle anti-clockwise spinning when waiting for a connection.
39
40TitlebarThrobAnimation::TitlebarThrobAnimation()
41    : current_frame_(0),
42      current_waiting_frame_(0) {
43}
44
45GdkPixbuf* TitlebarThrobAnimation::GetNextFrame(bool is_waiting) {
46  InitFrames();
47  if (is_waiting) {
48    return (*g_throbber_waiting_frames)[current_waiting_frame_++ %
49        g_throbber_waiting_frames->size()];
50  } else {
51    return (*g_throbber_frames)[current_frame_++ % g_throbber_frames->size()];
52  }
53}
54
55void TitlebarThrobAnimation::Reset() {
56  current_frame_ = 0;
57  current_waiting_frame_ = 0;
58}
59
60// static
61void TitlebarThrobAnimation::InitFrames() {
62  if (g_throbber_frames)
63    return;
64
65  // We load the light version of the throbber since it'll be in the titlebar.
66  g_throbber_frames = new std::vector<GdkPixbuf*>;
67  MakeThrobberFrames(IDR_THROBBER_LIGHT, g_throbber_frames);
68
69  g_throbber_waiting_frames = new std::vector<GdkPixbuf*>;
70  MakeThrobberFrames(IDR_THROBBER_WAITING_LIGHT, g_throbber_waiting_frames);
71}
72