OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 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/views/panel_controller.h" |
| 6 |
| 7 #include <gdk/gdkx.h> |
| 8 extern "C" { |
| 9 #include <X11/Xlib.h> |
| 10 } |
| 11 |
| 12 #include "app/resource_bundle.h" |
| 13 #include "base/logging.h" |
| 14 #include "base/singleton.h" |
| 15 #include "base/scoped_ptr.h" |
| 16 #include "chrome/browser/browser.h" |
| 17 #include "chrome/browser/gtk/browser_window_gtk.h" |
| 18 #include "chrome/browser/views/tabs/tab_overview_types.h" |
| 19 #include "chrome/common/x11_util.h" |
| 20 #include "grit/app_resources.h" |
| 21 #include "grit/generated_resources.h" |
| 22 #include "grit/theme_resources.h" |
| 23 #include "views/controls/button/image_button.h" |
| 24 #include "views/controls/label.h" |
| 25 #include "views/event.h" |
| 26 #include "views/view.h" |
| 27 #include "views/widget/widget_gtk.h" |
| 28 |
| 29 static int close_button_width; |
| 30 static int close_button_height; |
| 31 static SkBitmap* close_button_n; |
| 32 static SkBitmap* close_button_h; |
| 33 static SkBitmap* close_button_p; |
| 34 static gfx::Font* title_font = NULL; |
| 35 |
| 36 namespace { |
| 37 |
| 38 const int kTitleWidth = 200; |
| 39 const int kTitleHeight = 24; |
| 40 const int kTitlePad = 8; |
| 41 const int kButtonPad = 8; |
| 42 |
| 43 static bool resources_initialized; |
| 44 static void InitializeResources() { |
| 45 if (resources_initialized) { |
| 46 return; |
| 47 } |
| 48 |
| 49 resources_initialized = true; |
| 50 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 51 title_font = new gfx::Font(rb.GetFont(ResourceBundle::BaseFont)); |
| 52 close_button_n = rb.GetBitmapNamed(IDR_TAB_CLOSE); |
| 53 close_button_h = rb.GetBitmapNamed(IDR_TAB_CLOSE_H); |
| 54 close_button_p = rb.GetBitmapNamed(IDR_TAB_CLOSE_P); |
| 55 close_button_width = close_button_n->width(); |
| 56 close_button_height = close_button_n->height(); |
| 57 } |
| 58 |
| 59 } // namespace |
| 60 |
| 61 PanelController::PanelController(BrowserWindowGtk* browser_window) |
| 62 : browser_window_(browser_window), |
| 63 panel_(browser_window->window()), |
| 64 panel_xid_(x11_util::GetX11WindowFromGtkWidget(GTK_WIDGET(panel_))), |
| 65 expanded_(true), |
| 66 mouse_down_(false), |
| 67 dragging_(false) { |
| 68 title_window_ = new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW); |
| 69 gfx::Rect title_bounds( |
| 70 0, 0, browser_window->GetNormalBounds().width(), kTitleHeight); |
| 71 title_window_->Init(NULL, title_bounds); |
| 72 title_ = title_window_->GetNativeView(); |
| 73 title_xid_ = x11_util::GetX11WindowFromGtkWidget(title_); |
| 74 |
| 75 TabOverviewTypes* tab_overview = TabOverviewTypes::instance(); |
| 76 tab_overview->SetWindowType( |
| 77 title_, |
| 78 TabOverviewTypes::WINDOW_TYPE_CHROME_PANEL_TITLEBAR, |
| 79 NULL); |
| 80 std::vector<int> type_params; |
| 81 type_params.push_back(title_xid_); |
| 82 type_params.push_back(expanded_ ? 1 : 0); |
| 83 tab_overview->SetWindowType( |
| 84 GTK_WIDGET(panel_), |
| 85 TabOverviewTypes::WINDOW_TYPE_CHROME_PANEL, |
| 86 &type_params); |
| 87 |
| 88 g_signal_connect( |
| 89 panel_, "client-event", G_CALLBACK(OnPanelClientEvent), this); |
| 90 |
| 91 title_content_ = new TitleContentView(this); |
| 92 title_window_->SetContentsView(title_content_); |
| 93 title_window_->Show(); |
| 94 } |
| 95 |
| 96 void PanelController::UpdateTitleBar() { |
| 97 title_content_->title_label()->SetText( |
| 98 browser_window_->browser()->GetCurrentPageTitle()); |
| 99 } |
| 100 |
| 101 bool PanelController::TitleMousePressed(const views::MouseEvent& event) { |
| 102 if (!event.IsOnlyLeftMouseButton()) { |
| 103 return false; |
| 104 } |
| 105 gfx::Point abs_location = event.location(); |
| 106 views::View::ConvertPointToScreen(title_content_, &abs_location); |
| 107 mouse_down_ = true; |
| 108 mouse_down_abs_x_ = abs_location.x(); |
| 109 mouse_down_abs_y_ = abs_location.y(); |
| 110 mouse_down_offset_x_ = event.x(); |
| 111 mouse_down_offset_y_ = event.y(); |
| 112 dragging_ = false; |
| 113 return true; |
| 114 } |
| 115 |
| 116 void PanelController::TitleMouseReleased( |
| 117 const views::MouseEvent& event, bool canceled) { |
| 118 if (!event.IsOnlyLeftMouseButton()) { |
| 119 return; |
| 120 } |
| 121 // Only handle clicks that started in our window. |
| 122 if (!mouse_down_) { |
| 123 return; |
| 124 } |
| 125 |
| 126 mouse_down_ = false; |
| 127 if (!dragging_) { |
| 128 TabOverviewTypes::Message msg( |
| 129 TabOverviewTypes::Message::WM_SET_PANEL_STATE); |
| 130 msg.set_param(0, panel_xid_); |
| 131 msg.set_param(1, expanded_ ? 0 : 1); |
| 132 TabOverviewTypes::instance()->SendMessage(msg); |
| 133 } else { |
| 134 TabOverviewTypes::Message msg( |
| 135 TabOverviewTypes::Message::WM_NOTIFY_PANEL_DRAG_COMPLETE); |
| 136 msg.set_param(0, panel_xid_); |
| 137 TabOverviewTypes::instance()->SendMessage(msg); |
| 138 dragging_ = false; |
| 139 } |
| 140 } |
| 141 |
| 142 bool PanelController::TitleMouseDragged(const views::MouseEvent& event) { |
| 143 if (!mouse_down_) { |
| 144 return false; |
| 145 } |
| 146 |
| 147 gfx::Point abs_location = event.location(); |
| 148 views::View::ConvertPointToScreen(title_content_, &abs_location); |
| 149 if (!dragging_) { |
| 150 if (views::View::ExceededDragThreshold( |
| 151 abs_location.x() - mouse_down_abs_x_, |
| 152 abs_location.y() - mouse_down_abs_y_)) { |
| 153 dragging_ = true; |
| 154 } |
| 155 } |
| 156 if (dragging_) { |
| 157 TabOverviewTypes::Message msg(TabOverviewTypes::Message::WM_MOVE_PANEL); |
| 158 msg.set_param(0, panel_xid_); |
| 159 msg.set_param(1, abs_location.x() - mouse_down_offset_x_); |
| 160 msg.set_param(2, abs_location.y() - mouse_down_offset_y_); |
| 161 TabOverviewTypes::instance()->SendMessage(msg); |
| 162 } |
| 163 return true; |
| 164 } |
| 165 |
| 166 // static |
| 167 bool PanelController::OnPanelClientEvent( |
| 168 GtkWidget* widget, |
| 169 GdkEventClient* event, |
| 170 PanelController* panel_controller) { |
| 171 return panel_controller->PanelClientEvent(event); |
| 172 } |
| 173 |
| 174 bool PanelController::PanelClientEvent(GdkEventClient* event) { |
| 175 TabOverviewTypes::Message msg; |
| 176 TabOverviewTypes::instance()->DecodeMessage(*event, &msg); |
| 177 if (msg.type() == TabOverviewTypes::Message::CHROME_NOTIFY_PANEL_STATE) { |
| 178 expanded_ = msg.param(0); |
| 179 } |
| 180 return true; |
| 181 } |
| 182 |
| 183 void PanelController::Close() { |
| 184 title_window_->Close(); |
| 185 } |
| 186 |
| 187 void PanelController::ButtonPressed(views::Button* sender) { |
| 188 if (sender == title_content_->close_button()) { |
| 189 browser_window_->Close(); |
| 190 } |
| 191 } |
| 192 |
| 193 PanelController::TitleContentView::TitleContentView( |
| 194 PanelController* panel_controller) |
| 195 : panel_controller_(panel_controller) { |
| 196 InitializeResources(); |
| 197 close_button_ = new views::ImageButton(panel_controller_); |
| 198 close_button_->SetImage(views::CustomButton::BS_NORMAL, close_button_n); |
| 199 close_button_->SetImage(views::CustomButton::BS_HOT, close_button_h); |
| 200 close_button_->SetImage(views::CustomButton::BS_PUSHED, close_button_p); |
| 201 AddChildView(close_button_); |
| 202 |
| 203 title_label_ = new views::Label(std::wstring(), *title_font); |
| 204 title_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
| 205 AddChildView(title_label_); |
| 206 |
| 207 set_background(views::Background::CreateSolidBackground(0xdd, 0xdd, 0xdd, 1)); |
| 208 } |
| 209 |
| 210 void PanelController::TitleContentView::Layout() { |
| 211 close_button_->SetBounds( |
| 212 bounds().width() - (close_button_width + kButtonPad), |
| 213 (bounds().height() - close_button_height) / 2, |
| 214 close_button_width, |
| 215 close_button_height); |
| 216 title_label_->SetBounds( |
| 217 kTitlePad, |
| 218 0, |
| 219 bounds().width() - (kTitlePad + close_button_width + 2 * kButtonPad), |
| 220 bounds().height()); |
| 221 } |
| 222 |
| 223 bool PanelController::TitleContentView::OnMousePressed( |
| 224 const views::MouseEvent& event) { |
| 225 return panel_controller_->TitleMousePressed(event); |
| 226 } |
| 227 |
| 228 void PanelController::TitleContentView::OnMouseReleased( |
| 229 const views::MouseEvent& event, bool canceled) { |
| 230 return panel_controller_->TitleMouseReleased(event, canceled); |
| 231 } |
| 232 |
| 233 bool PanelController::TitleContentView::OnMouseDragged( |
| 234 const views::MouseEvent& event) { |
| 235 return panel_controller_->TitleMouseDragged(event); |
| 236 } |
| 237 |
OLD | NEW |