<commit_before>// Copyright (c) 2009 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/views/panel_controller.h"

#include "app/resource_bundle.h"
#include "base/logging.h"
#include "base/singleton.h"
#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/views/tabs/tab_overview_types.h"
#include "chrome/common/x11_util.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "views/controls/button/image_button.h"
#include "views/controls/image_view.h"
#include "views/controls/label.h"
#include "views/event.h"
#include "views/view.h"
#include "views/widget/widget_gtk.h"

static int close_button_width;
static int close_button_height;
static SkBitmap* close_button_n;
static SkBitmap* close_button_m;
static SkBitmap* close_button_h;
static SkBitmap* close_button_p;
static gfx::Font* active_font = NULL;
static gfx::Font* inactive_font = NULL;

namespace {

const int kTitleWidth = 200;
const int kTitleHeight = 20;
const int kTitleIconSize = 16;
const int kTitleWidthPad = 2;
const int kTitleHeightPad = 1;
const int kButtonPad = 4;

const SkColor kActiveGradientStart = 0xffebeff9;
const SkColor kActiveGradientEnd = 0xffb3c4f6;
const SkColor kInactiveGradientStart = 0xfff2f2f2;
const SkColor kInactiveGradientEnd = 0xfff2f2f2;
const SkColor kActiveColor = SK_ColorBLACK;
const SkColor kInactiveColor = 0xff333333;
const SkColor kCloseButtonColor = SK_ColorBLACK;

static bool resources_initialized;
static void InitializeResources() {
  if (resources_initialized) {
    return;
  }

  resources_initialized = true;
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  inactive_font = new gfx::Font(rb.GetFont(ResourceBundle::BaseFont));
  active_font = new gfx::Font(inactive_font->DeriveFont(0, gfx::Font::BOLD));
  close_button_n = rb.GetBitmapNamed(IDR_TAB_CLOSE);
  close_button_m = rb.GetBitmapNamed(IDR_TAB_CLOSE_MASK);
  close_button_h = rb.GetBitmapNamed(IDR_TAB_CLOSE_H);
  close_button_p = rb.GetBitmapNamed(IDR_TAB_CLOSE_P);
  close_button_width = close_button_n->width();
  close_button_height = close_button_n->height();
}

}  // namespace

PanelController::PanelController(BrowserWindowGtk* browser_window)
    :  browser_window_(browser_window),
       panel_(browser_window->window()),
       panel_xid_(x11_util::GetX11WindowFromGtkWidget(GTK_WIDGET(panel_))),
       expanded_(true),
       mouse_down_(false),
       dragging_(false) {
  title_window_ = new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW);
  gfx::Rect title_bounds(
      0, 0, browser_window->bounds().width(), kTitleHeight);
  title_window_->Init(NULL, title_bounds);
  title_ = title_window_->GetNativeView();
  title_xid_ = x11_util::GetX11WindowFromGtkWidget(title_);

  TabOverviewTypes* tab_overview = TabOverviewTypes::instance();
  tab_overview->SetWindowType(
      title_,
      TabOverviewTypes::WINDOW_TYPE_CHROME_PANEL_TITLEBAR,
      NULL);
  std::vector<int> type_params;
  type_params.push_back(title_xid_);
  type_params.push_back(expanded_ ? 1 : 0);
  tab_overview->SetWindowType(
      GTK_WIDGET(panel_),
      TabOverviewTypes::WINDOW_TYPE_CHROME_PANEL,
      &type_params);

  g_signal_connect(
      panel_, "client-event", G_CALLBACK(OnPanelClientEvent), this);

  title_content_ = new TitleContentView(this);
  title_window_->SetContentsView(title_content_);
  title_window_->Show();
}

void PanelController::UpdateTitleBar() {
  Browser* browser = browser_window_->browser();
  title_content_->title_label()->SetText(
      UTF16ToWideHack(browser->GetWindowTitleForCurrentTab()));
  title_content_->title_icon()->SetImage(browser->GetCurrentPageIcon());
}

bool PanelController::TitleMousePressed(const views::MouseEvent& event) {
  if (!event.IsOnlyLeftMouseButton()) {
    return false;
  }
  gfx::Point abs_location = event.location();
  views::View::ConvertPointToScreen(title_content_, &abs_location);
  mouse_down_ = true;
  mouse_down_abs_x_ = abs_location.x();
  mouse_down_abs_y_ = abs_location.y();
  mouse_down_offset_x_ = event.x();
  mouse_down_offset_y_ = event.y();
  dragging_ = false;
  return true;
}

void PanelController::TitleMouseReleased(
    const views::MouseEvent& event, bool canceled) {
  if (!event.IsOnlyLeftMouseButton()) {
    return;
  }
  // Only handle clicks that started in our window.
  if (!mouse_down_) {
    return;
  }

  mouse_down_ = false;
  if (!dragging_) {
    TabOverviewTypes::Message msg(
        TabOverviewTypes::Message::WM_SET_PANEL_STATE);
    msg.set_param(0, panel_xid_);
    msg.set_param(1, expanded_ ? 0 : 1);
    TabOverviewTypes::instance()->SendMessage(msg);
  } else {
    TabOverviewTypes::Message msg(
        TabOverviewTypes::Message::WM_NOTIFY_PANEL_DRAG_COMPLETE);
    msg.set_param(0, panel_xid_);
    TabOverviewTypes::instance()->SendMessage(msg);
    dragging_ = false;
  }
}

bool PanelController::TitleMouseDragged(const views::MouseEvent& event) {
  if (!mouse_down_) {
    return false;
  }

  gfx::Point abs_location = event.location();
  views::View::ConvertPointToScreen(title_content_, &abs_location);
  if (!dragging_) {
    if (views::View::ExceededDragThreshold(
        abs_location.x() - mouse_down_abs_x_,
        abs_location.y() - mouse_down_abs_y_)) {
      dragging_ = true;
    }
  }
  if (dragging_) {
    TabOverviewTypes::Message msg(TabOverviewTypes::Message::WM_MOVE_PANEL);
    msg.set_param(0, panel_xid_);
    msg.set_param(1, abs_location.x() - mouse_down_offset_x_);
    msg.set_param(2, abs_location.y() - mouse_down_offset_y_);
    TabOverviewTypes::instance()->SendMessage(msg);
  }
  return true;
}

// static
bool PanelController::OnPanelClientEvent(
    GtkWidget* widget,
    GdkEventClient* event,
    PanelController* panel_controller) {
  return panel_controller->PanelClientEvent(event);<commit_msg>If a window is moving in response to a mouse motion event, you can't just convert the relative coords from the event to the screen because you don't know if your View's position relative to the screen may or may not have changed. You need the screen coordinates from the event itself. This change uses gdk_get_current_event() to get the event so we can get the screen coords from it Review URL: http://codereview.chromium.org/173213<commit_after>// Copyright (c) 2009 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/views/panel_controller.h"

#include "app/resource_bundle.h"
#include "base/logging.h"
#include "base/singleton.h"
#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/views/tabs/tab_overview_types.h"
#include "chrome/common/x11_util.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "views/controls/button/image_button.h"
#include "views/controls/image_view.h"
#include "views/controls/label.h"
#include "views/event.h"
#include "views/view.h"
#include "views/widget/widget_gtk.h"

static int close_button_width;
static int close_button_height;
static SkBitmap* close_button_n;
static SkBitmap* close_button_m;
static SkBitmap* close_button_h;
static SkBitmap* close_button_p;
static gfx::Font* active_font = NULL;
static gfx::Font* inactive_font = NULL;

namespace {

const int kTitleWidth = 200;
const int kTitleHeight = 20;
const int kTitleIconSize = 16;
const int kTitleWidthPad = 2;
const int kTitleHeightPad = 1;
const int kButtonPad = 4;

const SkColor kActiveGradientStart = 0xffebeff9;
const SkColor kActiveGradientEnd = 0xffb3c4f6;
const SkColor kInactiveGradientStart = 0xfff2f2f2;
const SkColor kInactiveGradientEnd = 0xfff2f2f2;
const SkColor kActiveColor = SK_ColorBLACK;
const SkColor kInactiveColor = 0xff333333;
const SkColor kCloseButtonColor = SK_ColorBLACK;

static bool resources_initialized;
static void InitializeResources() {
  if (resources_initialized) {
    return;
  }

  resources_initialized = true;
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  inactive_font = new gfx::Font(rb.GetFont(ResourceBundle::BaseFont));
  active_font = new gfx::Font(inactive_font->DeriveFont(0, gfx::Font::BOLD));
  close_button_n = rb.GetBitmapNamed(IDR_TAB_CLOSE);
  close_button_m = rb.GetBitmapNamed(IDR_TAB_CLOSE_MASK);
  close_button_h = rb.GetBitmapNamed(IDR_TAB_CLOSE_H);
  close_button_p = rb.GetBitmapNamed(IDR_TAB_CLOSE_P);
  close_button_width = close_button_n->width();
  close_button_height = close_button_n->height();
}

}  // namespace

PanelController::PanelController(BrowserWindowGtk* browser_window)
    :  browser_window_(browser_window),
       panel_(browser_window->window()),
       panel_xid_(x11_util::GetX11WindowFromGtkWidget(GTK_WIDGET(panel_))),
       expanded_(true),
       mouse_down_(false),
       dragging_(false) {
  title_window_ = new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW);
  gfx::Rect title_bounds(
      0, 0, browser_window->bounds().width(), kTitleHeight);
  title_window_->Init(NULL, title_bounds);
  title_ = title_window_->GetNativeView();
  title_xid_ = x11_util::GetX11WindowFromGtkWidget(title_);

  TabOverviewTypes* tab_overview = TabOverviewTypes::instance();
  tab_overview->SetWindowType(
      title_,
      TabOverviewTypes::WINDOW_TYPE_CHROME_PANEL_TITLEBAR,
      NULL);
  std::vector<int> type_params;
  type_params.push_back(title_xid_);
  type_params.push_back(expanded_ ? 1 : 0);
  tab_overview->SetWindowType(
      GTK_WIDGET(panel_),
      TabOverviewTypes::WINDOW_TYPE_CHROME_PANEL,
      &type_params);

  g_signal_connect(
      panel_, "client-event", G_CALLBACK(OnPanelClientEvent), this);

  title_content_ = new TitleContentView(this);
  title_window_->SetContentsView(title_content_);
  title_window_->Show();
}

void PanelController::UpdateTitleBar() {
  Browser* browser = browser_window_->browser();
  title_content_->title_label()->SetText(
      UTF16ToWideHack(browser->GetWindowTitleForCurrentTab()));
  title_content_->title_icon()->SetImage(browser->GetCurrentPageIcon());
}

bool PanelController::TitleMousePressed(const views::MouseEvent& event) {
  if (!event.IsOnlyLeftMouseButton()) {
    return false;
  }
  GdkEvent* gdk_event = gtk_get_current_event();
  if (gdk_event->type != GDK_BUTTON_PRESS) {
    gdk_event_free(gdk_event);
    NOTREACHED();
    return false;
  }
  GdkEventButton last_button_event = gdk_event->button;
  mouse_down_ = true;
  mouse_down_abs_x_ = last_button_event.x_root;
  mouse_down_abs_y_ = last_button_event.y_root;
  mouse_down_offset_x_ = event.x();
  mouse_down_offset_y_ = event.y();
  dragging_ = false;
  gdk_event_free(gdk_event);
  return true;
}

void PanelController::TitleMouseReleased(
    const views::MouseEvent& event, bool canceled) {
  if (!event.IsOnlyLeftMouseButton()) {
    return;
  }
  // Only handle clicks that started in our window.
  if (!mouse_down_) {
    return;
  }

  mouse_down_ = false;
  if (!dragging_) {
    TabOverviewTypes::Message msg(
        TabOverviewTypes::Message::WM_SET_PANEL_STATE);
    msg.set_param(0, panel_xid_);
    msg.set_param(1, expanded_ ? 0 : 1);
    TabOverviewTypes::instance()->SendMessage(msg);
  } else {
    TabOverviewTypes::Message msg(
        TabOverviewTypes::Message::WM_NOTIFY_PANEL_DRAG_COMPLETE);
    msg.set_param(0, panel_xid_);
    TabOverviewTypes::instance()->SendMessage(msg);
    dragging_ = false;
  }
}

bool PanelController::TitleMouseDragged(const views::MouseEvent& event) {
  if (!mouse_down_) {
    return false;
  }

  GdkEvent* gdk_event = gtk_get_current_event();
  if (gdk_event->type != GDK_MOTION_NOTIFY) {
    gdk_event_free(gdk_event);
    NOTREACHED();
    return false;
  }
  GdkEventMotion last_motion_event = gdk_event->motion;
  if (!dragging_) {
    if (views::View::ExceededDragThreshold(
        last_motion_event.x_root - mouse_down_abs_x_,
        last_motion_event.y_root - mouse_down_abs_y_)) {
      dragging_ = true;
    }
  }
  if (dragging_) {
    TabOverviewTypes::Message msg(TabOverviewTypes::Message::WM_MOVE_PANEL);
    msg.set_param(0, panel_xid_);
    msg.set_param(1, last_motion_event.x_root - mouse_down_offset_x_);
    msg.set_param(2, last_motion_event.y_root - mouse_down_offset_y_);
    TabOverviewTypes::instance()->SendMessage(msg);
  }
  gdk_event_free(gdk_event);
  return true;
}

// static
bool PanelController::OnPanelClientEvent(
    GtkWidget* widget,
    GdkEventClient* event,
    PanelController* panel_controller) {
  return panel_controller->PanelClientEvent(event);
{'fraction_non_alphanumeric': 0.11245324189526185, 'fraction_numerical': 0.00981920199501247, 'mean_word_length': 5.349826818406729, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '918857', 'n_tokens_mistral': 4469, 'n_tokens_neox': 4316, 'n_words': 804}