| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 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/gtk/slide_animator_gtk.h" | |
| 6 | |
| 7 #include "chrome/browser/gtk/gtk_expanded_container.h" | |
| 8 #include "ui/base/animation/animation.h" | |
| 9 #include "ui/base/animation/slide_animation.h" | |
| 10 | |
| 11 namespace { | |
| 12 | |
| 13 void OnChildSizeRequest(GtkWidget* expanded, | |
| 14 GtkWidget* child, | |
| 15 GtkRequisition* requisition, | |
| 16 gpointer control_child_size) { | |
| 17 // If |control_child_size| is true, then we want |child_| to match the width | |
| 18 // of the |widget_|, but the height of |child_| should not change. | |
| 19 if (!GPOINTER_TO_INT(control_child_size)) { | |
| 20 requisition->width = -1; | |
| 21 } | |
| 22 requisition->height = -1; | |
| 23 } | |
| 24 | |
| 25 } // namespace | |
| 26 | |
| 27 bool SlideAnimatorGtk::animations_enabled_ = true; | |
| 28 | |
| 29 SlideAnimatorGtk::SlideAnimatorGtk(GtkWidget* child, | |
| 30 Direction direction, | |
| 31 int duration, | |
| 32 bool linear, | |
| 33 bool control_child_size, | |
| 34 Delegate* delegate) | |
| 35 : child_(child), | |
| 36 direction_(direction), | |
| 37 delegate_(delegate) { | |
| 38 widget_.Own(gtk_expanded_container_new()); | |
| 39 gtk_container_add(GTK_CONTAINER(widget_.get()), child); | |
| 40 gtk_widget_set_size_request(widget_.get(), -1, 0); | |
| 41 | |
| 42 // If the child requests it, we will manually set the size request for | |
| 43 // |child_| every time the |widget_| changes sizes. This is mainly useful | |
| 44 // for bars, where we want the child to expand to fill all available space. | |
| 45 g_signal_connect(widget_.get(), "child-size-request", | |
| 46 G_CALLBACK(OnChildSizeRequest), | |
| 47 GINT_TO_POINTER(control_child_size)); | |
| 48 | |
| 49 // We connect to this signal to set an initial position for our child widget. | |
| 50 // The reason we connect to this signal rather than setting the initial | |
| 51 // position here is that the widget is currently unallocated and may not | |
| 52 // even have a size request. | |
| 53 g_signal_connect(child, "size-allocate", | |
| 54 G_CALLBACK(OnChildSizeAllocate), this); | |
| 55 | |
| 56 child_needs_move_ = (direction == DOWN); | |
| 57 | |
| 58 animation_.reset(new ui::SlideAnimation(this)); | |
| 59 // Default tween type is EASE_OUT. | |
| 60 if (linear) | |
| 61 animation_->SetTweenType(ui::Tween::LINEAR); | |
| 62 if (duration != 0) | |
| 63 animation_->SetSlideDuration(duration); | |
| 64 } | |
| 65 | |
| 66 SlideAnimatorGtk::~SlideAnimatorGtk() { | |
| 67 widget_.Destroy(); | |
| 68 } | |
| 69 | |
| 70 void SlideAnimatorGtk::Open() { | |
| 71 if (!animations_enabled_) | |
| 72 return OpenWithoutAnimation(); | |
| 73 | |
| 74 gtk_widget_show(widget_.get()); | |
| 75 animation_->Show(); | |
| 76 } | |
| 77 | |
| 78 void SlideAnimatorGtk::OpenWithoutAnimation() { | |
| 79 gtk_widget_show(widget_.get()); | |
| 80 animation_->Reset(1.0); | |
| 81 animation_->Show(); | |
| 82 AnimationProgressed(animation_.get()); | |
| 83 } | |
| 84 | |
| 85 void SlideAnimatorGtk::Close() { | |
| 86 if (!animations_enabled_) | |
| 87 return CloseWithoutAnimation(); | |
| 88 | |
| 89 animation_->Hide(); | |
| 90 } | |
| 91 | |
| 92 void SlideAnimatorGtk::End() { | |
| 93 animation_->End(); | |
| 94 } | |
| 95 | |
| 96 void SlideAnimatorGtk::CloseWithoutAnimation() { | |
| 97 animation_->Reset(0.0); | |
| 98 animation_->Hide(); | |
| 99 AnimationProgressed(animation_.get()); | |
| 100 gtk_widget_hide(widget_.get()); | |
| 101 } | |
| 102 | |
| 103 bool SlideAnimatorGtk::IsShowing() { | |
| 104 return animation_->IsShowing(); | |
| 105 } | |
| 106 | |
| 107 bool SlideAnimatorGtk::IsClosing() { | |
| 108 return animation_->IsClosing(); | |
| 109 } | |
| 110 | |
| 111 bool SlideAnimatorGtk::IsAnimating() { | |
| 112 return animation_->is_animating(); | |
| 113 } | |
| 114 | |
| 115 void SlideAnimatorGtk::AnimationProgressed(const ui::Animation* animation) { | |
| 116 GtkRequisition req; | |
| 117 gtk_widget_size_request(child_, &req); | |
| 118 | |
| 119 int showing_height = static_cast<int>(req.height * | |
| 120 animation_->GetCurrentValue()); | |
| 121 if (direction_ == DOWN) { | |
| 122 gtk_expanded_container_move(GTK_EXPANDED_CONTAINER(widget_.get()), | |
| 123 child_, 0, showing_height - req.height); | |
| 124 child_needs_move_ = false; | |
| 125 } | |
| 126 gtk_widget_set_size_request(widget_.get(), -1, showing_height); | |
| 127 } | |
| 128 | |
| 129 void SlideAnimatorGtk::AnimationEnded(const ui::Animation* animation) { | |
| 130 if (!animation_->IsShowing()) { | |
| 131 gtk_widget_hide(widget_.get()); | |
| 132 if (delegate_) | |
| 133 delegate_->Closed(); | |
| 134 } | |
| 135 } | |
| 136 | |
| 137 // static | |
| 138 void SlideAnimatorGtk::SetAnimationsForTesting(bool enable) { | |
| 139 animations_enabled_ = enable; | |
| 140 } | |
| 141 | |
| 142 // static | |
| 143 void SlideAnimatorGtk::OnChildSizeAllocate(GtkWidget* child, | |
| 144 GtkAllocation* allocation, | |
| 145 SlideAnimatorGtk* slider) { | |
| 146 if (slider->child_needs_move_) { | |
| 147 gtk_expanded_container_move(GTK_EXPANDED_CONTAINER(slider->widget()), | |
| 148 child, 0, -allocation->height); | |
| 149 slider->child_needs_move_ = false; | |
| 150 } | |
| 151 } | |
| OLD | NEW |