diff options
Diffstat (limited to 'chrome/browser/ui/gtk/tabs/dragged_view_gtk.cc')
-rw-r--r-- | chrome/browser/ui/gtk/tabs/dragged_view_gtk.cc | 473 |
1 files changed, 0 insertions, 473 deletions
diff --git a/chrome/browser/ui/gtk/tabs/dragged_view_gtk.cc b/chrome/browser/ui/gtk/tabs/dragged_view_gtk.cc deleted file mode 100644 index 93811c5..0000000 --- a/chrome/browser/ui/gtk/tabs/dragged_view_gtk.cc +++ /dev/null @@ -1,473 +0,0 @@ -// Copyright (c) 2012 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. - -#include "chrome/browser/ui/gtk/tabs/dragged_view_gtk.h" - -#include <gdk/gdk.h> - -#include <algorithm> - -#include "base/debug/trace_event.h" -#include "base/i18n/rtl.h" -#include "base/stl_util.h" -#include "chrome/browser/extensions/tab_helper.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/themes/theme_service.h" -#include "chrome/browser/themes/theme_service_factory.h" -#include "chrome/browser/ui/gtk/gtk_theme_service.h" -#include "chrome/browser/ui/gtk/gtk_util.h" -#include "chrome/browser/ui/gtk/tabs/drag_data.h" -#include "chrome/browser/ui/gtk/tabs/tab_renderer_gtk.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/web_contents.h" -#include "third_party/skia/include/core/SkShader.h" -#include "ui/base/gtk/gtk_screen_util.h" -#include "ui/base/x/x11_util.h" -#include "ui/gfx/gtk_util.h" - -using content::WebContents; - -namespace { - -// The size of the dragged window frame. -const int kDragFrameBorderSize = 1; -const int kTwiceDragFrameBorderSize = 2 * kDragFrameBorderSize; - -// Used to scale the dragged window sizes. -const float kScalingFactor = 0.5; - -const int kAnimateToBoundsDurationMs = 150; - -const gdouble kTransparentAlpha = (200.0f / 255.0f); -const gdouble kOpaqueAlpha = 1.0f; -const double kDraggedTabBorderColor[] = { 103.0 / 0xff, - 129.0 / 0xff, - 162.0 / 0xff }; - -} // namespace - -//////////////////////////////////////////////////////////////////////////////// -// DraggedViewGtk, public: - -DraggedViewGtk::DraggedViewGtk(DragData* drag_data, - const gfx::Point& mouse_tab_offset, - const gfx::Size& contents_size) - : drag_data_(drag_data), - mini_width_(-1), - normal_width_(-1), - attached_(false), - parent_window_width_(-1), - mouse_tab_offset_(mouse_tab_offset), - attached_tab_size_(TabRendererGtk::GetMinimumSelectedSize()), - contents_size_(contents_size), - close_animation_(this) { - std::vector<WebContents*> data_sources(drag_data_->GetDraggedTabsContents()); - for (size_t i = 0; i < data_sources.size(); i++) { - renderers_.push_back(new TabRendererGtk(GtkThemeService::GetFrom( - Profile::FromBrowserContext(data_sources[i]->GetBrowserContext())))); - } - - for (size_t i = 0; i < drag_data_->size(); i++) { - WebContents* web_contents = drag_data_->get(i)->contents_; - renderers_[i]->UpdateData( - web_contents, - extensions::TabHelper::FromWebContents(web_contents)->is_app(), - false); // loading_only - renderers_[i]->set_is_active( - static_cast<int>(i) == drag_data_->source_tab_index()); - } - - container_ = gtk_window_new(GTK_WINDOW_POPUP); - SetContainerColorMap(); - gtk_widget_set_app_paintable(container_, TRUE); - g_signal_connect(container_, "expose-event", G_CALLBACK(OnExposeThunk), this); - gtk_widget_add_events(container_, GDK_STRUCTURE_MASK); - - // We contain the tab renderer in a GtkFixed in order to maintain the - // requested size. Otherwise, the widget will fill the entire window and - // cause a crash when rendering because the bounds don't match our images. - fixed_ = gtk_fixed_new(); - for (size_t i = 0; i < renderers_.size(); i++) - gtk_fixed_put(GTK_FIXED(fixed_), renderers_[i]->widget(), 0, 0); - - gtk_container_add(GTK_CONTAINER(container_), fixed_); - gtk_widget_show_all(container_); -} - -DraggedViewGtk::~DraggedViewGtk() { - gtk_widget_destroy(container_); - STLDeleteElements(&renderers_); -} - -void DraggedViewGtk::MoveDetachedTo(const gfx::Point& screen_point) { - DCHECK(!attached_); - gfx::Point distance_from_origin = - GetDistanceFromTabStripOriginToMousePointer(); - int y = screen_point.y() - ScaleValue(distance_from_origin.y()); - int x = screen_point.x() - ScaleValue(distance_from_origin.x()); - gtk_window_move(GTK_WINDOW(container_), x, y); -} - -void DraggedViewGtk::MoveAttachedTo(const gfx::Point& tabstrip_point) { - DCHECK(attached_); - int x = tabstrip_point.x() + GetWidthInTabStripUpToMousePointer() - - ScaleValue(GetWidthInTabStripUpToMousePointer()); - int y = tabstrip_point.y() + mouse_tab_offset_.y() - - ScaleValue(mouse_tab_offset_.y()); - gtk_window_move(GTK_WINDOW(container_), x, y); -} - -gfx::Point DraggedViewGtk::GetDistanceFromTabStripOriginToMousePointer() { - gfx::Point start_point(GetWidthInTabStripUpToMousePointer(), - mouse_tab_offset_.y()); - if (base::i18n::IsRTL()) - start_point.Offset(parent_window_width_ - GetTotalWidthInTabStrip(), 0); - return start_point; -} - -void DraggedViewGtk::Attach( - int normal_width, int mini_width, int window_width) { - attached_ = true; - parent_window_width_ = window_width; - normal_width_ = normal_width; - mini_width_ = mini_width; - - int dragged_tab_width = - drag_data_->GetSourceTabData()->mini_ ? mini_width : normal_width; - - Resize(dragged_tab_width); - - if (ui::IsScreenComposited()) { - GdkWindow* gdk_window = gtk_widget_get_window(container_); - gdk_window_set_opacity(gdk_window, kOpaqueAlpha); - } -} - -void DraggedViewGtk::Resize(int width) { - attached_tab_size_.set_width(width); - ResizeContainer(); -} - -void DraggedViewGtk::Detach() { - attached_ = false; - ResizeContainer(); - - if (ui::IsScreenComposited()) { - GdkWindow* gdk_window = gtk_widget_get_window(container_); - gdk_window_set_opacity(gdk_window, kTransparentAlpha); - } -} - -void DraggedViewGtk::Update() { - gtk_widget_queue_draw(container_); -} - -int DraggedViewGtk::GetWidthInTabStripFromTo(int from, int to) { - DCHECK(from <= static_cast<int>(drag_data_->size())); - DCHECK(to <= static_cast<int>(drag_data_->size())); - - // TODO(dpapad): Get 16 from TabStripGtk::kTabHOffset. - int mini_tab_count = 0, non_mini_tab_count = 0; - drag_data_->GetNumberOfMiniNonMiniTabs(from, to, - &mini_tab_count, &non_mini_tab_count); - int width = non_mini_tab_count * static_cast<int>(floor(normal_width_ + 0.5)) - + mini_tab_count * mini_width_ - std::max(to - from - 1, 0) * 16; - return width; -} - -int DraggedViewGtk::GetTotalWidthInTabStrip() { - return GetWidthInTabStripFromTo(0, drag_data_->size()); -} - -int DraggedViewGtk::GetWidthInTabStripUpToSourceTab() { - if (!base::i18n::IsRTL()) { - return GetWidthInTabStripFromTo(0, drag_data_->source_tab_index()); - } else { - return GetWidthInTabStripFromTo( - drag_data_->source_tab_index() + 1, drag_data_->size()); - } -} - -int DraggedViewGtk::GetWidthInTabStripUpToMousePointer() { - int width = GetWidthInTabStripUpToSourceTab() + mouse_tab_offset_.x(); - if (!base::i18n::IsRTL() && drag_data_->source_tab_index() > 0) { - width -= 16; - } else if (base::i18n::IsRTL() && - drag_data_->source_tab_index() < - static_cast<int>(drag_data_->size()) - 1) { - width -= 16; - } - return width; -} - -void DraggedViewGtk::AnimateToBounds(const gfx::Rect& bounds, - const base::Closure& callback) { - animation_callback_ = callback; - - gint x, y, width, height; - GdkWindow* gdk_window = gtk_widget_get_window(container_); - gdk_window_get_origin(gdk_window, &x, &y); - gdk_window_get_geometry(gdk_window, NULL, NULL, - &width, &height, NULL); - - animation_start_bounds_ = gfx::Rect(x, y, width, height); - animation_end_bounds_ = bounds; - - close_animation_.SetSlideDuration(kAnimateToBoundsDurationMs); - close_animation_.SetTweenType(gfx::Tween::EASE_OUT); - if (!close_animation_.IsShowing()) { - close_animation_.Reset(); - close_animation_.Show(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// DraggedViewGtk, gfx::AnimationDelegate implementation: - -void DraggedViewGtk::AnimationProgressed(const gfx::Animation* animation) { - int delta_x = (animation_end_bounds_.x() - animation_start_bounds_.x()); - int x = animation_start_bounds_.x() + - static_cast<int>(delta_x * animation->GetCurrentValue()); - int y = animation_end_bounds_.y(); - GdkWindow* gdk_window = gtk_widget_get_window(container_); - gdk_window_move(gdk_window, x, y); -} - -void DraggedViewGtk::AnimationEnded(const gfx::Animation* animation) { - animation_callback_.Run(); -} - -void DraggedViewGtk::AnimationCanceled(const gfx::Animation* animation) { - AnimationEnded(animation); -} - -//////////////////////////////////////////////////////////////////////////////// -// DraggedViewGtk, private: - -void DraggedViewGtk::Layout() { - if (attached_) { - for (size_t i = 0; i < renderers_.size(); i++) { - gfx::Rect rect(GetPreferredSize()); - rect.set_width(GetAttachedTabWidthAt(i)); - renderers_[i]->SetBounds(rect); - } - } else { - int left = 0; - if (base::i18n::IsRTL()) - left = GetPreferredSize().width() - attached_tab_size_.width(); - - // The renderer_'s width should be attached_tab_size_.width() in both LTR - // and RTL locales. Wrong width will cause the wrong positioning of the tab - // view in dragging. Please refer to http://crbug.com/6223 for details. - renderers_[drag_data_->source_tab_index()]->SetBounds( - gfx::Rect(left, 0, attached_tab_size_.width(), - attached_tab_size_.height())); - } -} - -gfx::Size DraggedViewGtk::GetPreferredSize() { - if (attached_) { - gfx::Size preferred_size(attached_tab_size_); - preferred_size.set_width(GetTotalWidthInTabStrip()); - return preferred_size; - } - - int width = std::max(attached_tab_size_.width(), contents_size_.width()) + - kTwiceDragFrameBorderSize; - int height = attached_tab_size_.height() + kDragFrameBorderSize + - contents_size_.height(); - return gfx::Size(width, height); -} - -void DraggedViewGtk::ResizeContainer() { - gfx::Size size = GetPreferredSize(); - gtk_window_resize(GTK_WINDOW(container_), - ScaleValue(size.width()), ScaleValue(size.height())); - Layout(); -} - -int DraggedViewGtk::ScaleValue(int value) { - return attached_ ? value : static_cast<int>(value * kScalingFactor); -} - -gfx::Rect DraggedViewGtk::bounds() const { - gint x, y, width, height; - gtk_window_get_position(GTK_WINDOW(container_), &x, &y); - gtk_window_get_size(GTK_WINDOW(container_), &width, &height); - return gfx::Rect(x, y, width, height); -} - -int DraggedViewGtk::GetAttachedTabWidthAt(int index) { - return drag_data_->get(index)->mini_? mini_width_ : normal_width_; -} - -void DraggedViewGtk::SetContainerColorMap() { - GdkScreen* screen = gtk_widget_get_screen(container_); - GdkColormap* colormap = gdk_screen_get_rgba_colormap(screen); - - // If rgba is not available, use rgb instead. - if (!colormap) - colormap = gdk_screen_get_rgb_colormap(screen); - - gtk_widget_set_colormap(container_, colormap); -} - -void DraggedViewGtk::SetContainerTransparency() { - cairo_t* cairo_context = gdk_cairo_create(gtk_widget_get_window(container_)); - if (!cairo_context) - return; - - // Make the background of the dragged tab window fully transparent. All of - // the content of the window (child widgets) will be completely opaque. - gfx::Size size = bounds().size(); - cairo_scale(cairo_context, static_cast<double>(size.width()), - static_cast<double>(size.height())); - cairo_set_source_rgba(cairo_context, 1.0f, 1.0f, 1.0f, 0.0f); - cairo_set_operator(cairo_context, CAIRO_OPERATOR_SOURCE); - cairo_paint(cairo_context); - cairo_destroy(cairo_context); -} - -void DraggedViewGtk::SetContainerShapeMask() { - // Create a 1bpp bitmap the size of |container_|. - gfx::Size size(GetPreferredSize()); - GdkPixmap* pixmap = gdk_pixmap_new(NULL, size.width(), size.height(), 1); - cairo_t* cairo_context = gdk_cairo_create(GDK_DRAWABLE(pixmap)); - - // Set the transparency. - cairo_set_source_rgba(cairo_context, 1.0f, 1.0f, 1.0f, 0.0f); - - // Blit the rendered bitmap into a pixmap. Any pixel set in the pixmap will - // be opaque in the container window. - if (!attached_) - cairo_scale(cairo_context, kScalingFactor, kScalingFactor); - for (size_t i = 0; i < renderers_.size(); i++) { - if (static_cast<int>(i) == 0) - cairo_set_operator(cairo_context, CAIRO_OPERATOR_SOURCE); - else - cairo_set_operator(cairo_context, CAIRO_OPERATOR_OVER); - - GtkAllocation allocation; - gtk_widget_get_allocation(container_, &allocation); - PaintTab(i, container_, cairo_context, allocation.width); - } - - if (!attached_) { - // Make the render area depiction opaque (leaving enough room for the - // border). - cairo_identity_matrix(cairo_context); - // On Lucid running VNC, the X server will reject RGBA (1,1,1,1) as an - // invalid value below in gdk_window_shape_combine_mask(). Using (0,0,0,1) - // instead. The value doesn't really matter, as long as the alpha is not 0. - cairo_set_source_rgba(cairo_context, 0.0f, 0.0f, 0.0f, 1.0f); - int tab_height = static_cast<int>( - kScalingFactor * renderers_[drag_data_->source_tab_index()]->height() - - kDragFrameBorderSize); - cairo_rectangle(cairo_context, - 0, tab_height, - size.width(), size.height() - tab_height); - cairo_fill(cairo_context); - } - - cairo_destroy(cairo_context); - - // Set the shape mask. - GdkWindow* gdk_window = gtk_widget_get_window(container_); - gdk_window_shape_combine_mask(gdk_window, pixmap, 0, 0); - g_object_unref(pixmap); -} - -gboolean DraggedViewGtk::OnExpose(GtkWidget* widget, GdkEventExpose* event) { - TRACE_EVENT0("ui::gtk", "DraggedViewGtk::OnExpose"); - - if (ui::IsScreenComposited()) - SetContainerTransparency(); - else - SetContainerShapeMask(); - - // Only used when not attached. - int tab_height = static_cast<int>( - kScalingFactor * renderers_[drag_data_->source_tab_index()]->height()); - - GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); - - // Draw the render area. - if (!attached_) { - content::RenderWidgetHost* render_widget_host = - drag_data_->GetSourceWebContents()->GetRenderViewHost(); - - // This leaves room for the border. - gfx::Rect dest_rect(kDragFrameBorderSize, tab_height, - allocation.width - kTwiceDragFrameBorderSize, - allocation.height - tab_height - - kDragFrameBorderSize); - render_widget_host->CopyFromBackingStoreToGtkWindow( - dest_rect, GDK_DRAWABLE(gtk_widget_get_window(widget))); - } - - cairo_t* cr = gdk_cairo_create(gtk_widget_get_window(widget)); - // Draw the border. - if (!attached_) { - cairo_set_line_width(cr, kDragFrameBorderSize); - cairo_set_source_rgb(cr, kDraggedTabBorderColor[0], - kDraggedTabBorderColor[1], - kDraggedTabBorderColor[2]); - // |offset| is the distance from the edge of the image to the middle of - // the border line. - double offset = kDragFrameBorderSize / 2.0 - 0.5; - double left_x = offset; - double top_y = tab_height - kDragFrameBorderSize + offset; - double right_x = allocation.width - offset; - double bottom_y = allocation.height - offset; - - cairo_move_to(cr, left_x, top_y); - cairo_line_to(cr, left_x, bottom_y); - cairo_line_to(cr, right_x, bottom_y); - cairo_line_to(cr, right_x, top_y); - cairo_line_to(cr, left_x, top_y); - cairo_stroke(cr); - } - - // Draw the tab. - if (!attached_) - cairo_scale(cr, kScalingFactor, kScalingFactor); - // Painting all but the active tab first, from last to first. - for (int i = renderers_.size() - 1; i >= 0; i--) { - if (i == drag_data_->source_tab_index()) - continue; - PaintTab(i, widget, cr, allocation.width); - } - // Painting the active tab last, so that it appears on top. - PaintTab(drag_data_->source_tab_index(), widget, cr, - allocation.width); - - cairo_destroy(cr); - - // We've already drawn the tab, so don't propagate the expose-event signal. - return TRUE; -} - -void DraggedViewGtk::PaintTab(int index, GtkWidget* widget, cairo_t* cr, - int widget_width) { - renderers_[index]->set_mini(drag_data_->get(index)->mini_); - cairo_surface_t* surface = renderers_[index]->PaintToSurface(widget, cr); - - int paint_at = 0; - if (!base::i18n::IsRTL()) { - paint_at = std::max(GetWidthInTabStripFromTo(0, index) - 16, 0); - } else { - paint_at = GetTotalWidthInTabStrip() - - GetWidthInTabStripFromTo(0, index + 1); - if (!attached_) { - paint_at = widget_width / kScalingFactor - - GetWidthInTabStripFromTo(0, index + 1); - } - } - - cairo_set_source_surface(cr, surface, paint_at, 0); - cairo_paint(cr); - cairo_surface_destroy(surface); -} |