172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/find_bar_gtk.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <gdk/gdkkeysyms.h> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector> 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/i18n/rtl.h" 143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 1721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h" 1921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/find_bar/find_bar_controller.h" 2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/find_bar/find_bar_state.h" 2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/find_bar/find_notification_details.h" 22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/find_bar/find_tab_helper.h" 2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/browser_window_gtk.h" 2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/cairo_cached_surface.h" 2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/custom_button.h" 2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/gtk_floating_container.h" 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/gtk/gtk_theme_service.h" 2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/gtk_util.h" 2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/nine_box.h" 3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/slide_animator_gtk.h" 3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/tab_contents_container_gtk.h" 3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/tabs/tab_strip_gtk.h" 3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/view_id_util.h" 3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h" 36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h" 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/native_web_keyboard_event.h" 38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/common/notification_service.h" 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h" 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h" 4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h" 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Used as the color of the text in the entry box and the text for the results 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// label for failure searches. 48513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst GdkColor kEntryTextColor = gtk_util::kGdkBlack; 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Used as the color of the background of the entry box and the background of 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the find label for successful searches. 52513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst GdkColor kEntryBackgroundColor = gtk_util::kGdkWhite; 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst GdkColor kFindFailureBackgroundColor = GDK_COLOR_RGB(255, 102, 102); 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst GdkColor kFindSuccessTextColor = GDK_COLOR_RGB(178, 178, 178); 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Padding around the container. 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kBarPaddingTopBottom = 4; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kEntryPaddingLeft = 6; 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kCloseButtonPaddingLeft = 3; 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kBarPaddingRight = 4; 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The height of the findbar dialog, as dictated by the size of the background 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// images. 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kFindBarHeight = 32; 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The width of the text entry field. 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kTextEntryWidth = 220; 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The size of the "rounded" corners. 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kCornerSize = 3; 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum FrameType { 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FRAME_MASK, 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FRAME_STROKE, 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns a list of points that either form the outline of the status bubble 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// (|type| == FRAME_MASK) or form the inner border around the inner edge 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// (|type| == FRAME_STROKE). 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::vector<GdkPoint> MakeFramePolygonPoints(int width, 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int height, 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FrameType type) { 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch using gtk_util::MakeBidiGdkPoint; 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<GdkPoint> points; 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool ltr = !base::i18n::IsRTL(); 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we have a stroke, we have to offset some of our points by 1 pixel. 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We have to inset by 1 pixel when we draw horizontal lines that are on the 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // bottom or when we draw vertical lines that are closer to the end (end is 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // right for ltr). 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int y_off = (type == FRAME_MASK) ? 0 : -1; 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We use this one for LTR. 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int x_off_l = ltr ? y_off : 0; 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We use this one for RTL. 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int x_off_r = !ltr ? -y_off : 0; 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Top left corner 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch points.push_back(MakeBidiGdkPoint(x_off_r, 0, width, ltr)); 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch points.push_back(MakeBidiGdkPoint( 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kCornerSize + x_off_r, kCornerSize, width, ltr)); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Bottom left corner 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch points.push_back(MakeBidiGdkPoint( 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kCornerSize + x_off_r, height - kCornerSize, width, ltr)); 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch points.push_back(MakeBidiGdkPoint( 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (2 * kCornerSize) + x_off_l, height + y_off, 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch width, ltr)); 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Bottom right corner 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch points.push_back(MakeBidiGdkPoint( 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch width - (2 * kCornerSize) + x_off_r, height + y_off, 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch width, ltr)); 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch points.push_back(MakeBidiGdkPoint( 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch width - kCornerSize + x_off_l, height - kCornerSize, width, ltr)); 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Top right corner 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch points.push_back(MakeBidiGdkPoint( 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch width - kCornerSize + x_off_l, kCornerSize, width, ltr)); 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch points.push_back(MakeBidiGdkPoint(width + x_off_l, 0, width, ltr)); 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return points; 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Give the findbar dialog its unique shape using images. 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SetDialogShape(GtkWidget* widget) { 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static NineBox* dialog_shape = NULL; 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!dialog_shape) { 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dialog_shape = new NineBox( 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_FIND_DLG_LEFT_BACKGROUND, 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_FIND_DLG_MIDDLE_BACKGROUND, 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_FIND_DLG_RIGHT_BACKGROUND, 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, 0, 0, 0, 0, 0); 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dialog_shape->ChangeWhiteToTransparent(); 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dialog_shape->ContourWidget(widget); 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Return a ninebox that will paint the border of the findbar dialog. This is 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// shared across all instances of the findbar. Do not free the returned pointer. 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst NineBox* GetDialogBorder() { 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static NineBox* dialog_border = NULL; 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!dialog_border) { 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dialog_border = new NineBox( 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_FIND_DIALOG_LEFT, 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_FIND_DIALOG_MIDDLE, 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_FIND_DIALOG_RIGHT, 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, 0, 0, 0, 0, 0); 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return dialog_border; 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Like gtk_util::CreateGtkBorderBin, but allows control over the alignment and 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// returns both the event box and the alignment so we can modify it during its 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// lifetime (i.e. during a theme change). 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BuildBorder(GtkWidget* child, 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool center, 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int padding_top, int padding_bottom, int padding_left, 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int padding_right, 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget** ebox, GtkWidget** alignment) { 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *ebox = gtk_event_box_new(); 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (center) 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *alignment = gtk_alignment_new(0.5, 0.5, 0.0, 0.0); 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_alignment_set_padding(GTK_ALIGNMENT(*alignment), 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch padding_top, padding_bottom, padding_left, 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch padding_right); 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_add(GTK_CONTAINER(*alignment), child); 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_add(GTK_CONTAINER(*ebox), *alignment); 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFindBarGtk::FindBarGtk(Browser* browser) 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : browser_(browser), 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch window_(static_cast<BrowserWindowGtk*>(browser->window())), 179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen theme_service_(GtkThemeService::GetFrom(browser->profile())), 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch container_width_(-1), 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch container_height_(-1), 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch match_label_failure_(false), 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ignore_changed_signal_(false) { 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InitWidgets(); 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ViewIDUtil::SetID(text_entry_, VIEW_ID_FIND_IN_PAGE_TEXT_FIELD); 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Insert the widget into the browser gtk hierarchy. 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch window_->AddFindBar(this); 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Hook up signals after the widget has been added to the hierarchy so the 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // widget will be realized. 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(text_entry_, "changed", 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnChanged), this); 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect_after(text_entry_, "key-press-event", 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnKeyPressEvent), this); 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect_after(text_entry_, "key-release-event", 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnKeyReleaseEvent), this); 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // When the user tabs to us or clicks on us, save where the focus used to 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // be. 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(text_entry_, "focus", 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnFocus), this); 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_add_events(text_entry_, GDK_BUTTON_PRESS_MASK); 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(text_entry_, "button-press-event", 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnButtonPress), this); 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(text_entry_, "move-cursor", G_CALLBACK(OnMoveCursor), this); 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(text_entry_, "activate", G_CALLBACK(OnActivate), this); 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(text_entry_, "direction-changed", 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnWidgetDirectionChanged), this); 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(text_entry_, "focus-in-event", 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnFocusIn), this); 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(text_entry_, "focus-out-event", 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnFocusOut), this); 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(container_, "expose-event", 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnExpose), this); 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFindBarGtk::~FindBarGtk() { 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::InitWidgets() { 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The find bar is basically an hbox with a gtkentry (text box) followed by 3 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // buttons (previous result, next result, close). We wrap the hbox in a gtk 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // alignment and a gtk event box to get the padding and light blue 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // background. We put that event box in a fixed in order to control its 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // lateral position. We put that fixed in a SlideAnimatorGtk in order to get 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the slide effect. 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* hbox = gtk_hbox_new(false, 0); 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch container_ = gtk_util::CreateGtkBorderBin(hbox, NULL, 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kBarPaddingTopBottom, kBarPaddingTopBottom, 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kEntryPaddingLeft, kBarPaddingRight); 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ViewIDUtil::SetID(container_, VIEW_ID_FIND_IN_PAGE); 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_app_paintable(container_, TRUE); 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch slide_widget_.reset(new SlideAnimatorGtk(container_, 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SlideAnimatorGtk::DOWN, 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, false, false, NULL)); 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen close_button_.reset(CustomDrawButton::CloseButton(theme_service_)); 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::CenterWidgetInHBox(hbox, close_button_->widget(), true, 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kCloseButtonPaddingLeft); 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(close_button_->widget(), "clicked", 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnClicked), this); 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_tooltip_text(close_button_->widget(), 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch l10n_util::GetStringUTF8(IDS_FIND_IN_PAGE_CLOSE_TOOLTIP).c_str()); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen find_next_button_.reset(new CustomDrawButton(theme_service_, 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_FINDINPAGE_NEXT, IDR_FINDINPAGE_NEXT_H, IDR_FINDINPAGE_NEXT_H, 2483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick IDR_FINDINPAGE_NEXT_P, GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_MENU)); 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(find_next_button_->widget(), "clicked", 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnClicked), this); 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_tooltip_text(find_next_button_->widget(), 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch l10n_util::GetStringUTF8(IDS_FIND_IN_PAGE_NEXT_TOOLTIP).c_str()); 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_end(GTK_BOX(hbox), find_next_button_->widget(), 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FALSE, FALSE, 0); 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen find_previous_button_.reset(new CustomDrawButton(theme_service_, 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_FINDINPAGE_PREV, IDR_FINDINPAGE_PREV_H, IDR_FINDINPAGE_PREV_H, 2583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick IDR_FINDINPAGE_PREV_P, GTK_STOCK_GO_UP, GTK_ICON_SIZE_MENU)); 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(find_previous_button_->widget(), "clicked", 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnClicked), this); 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_tooltip_text(find_previous_button_->widget(), 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch l10n_util::GetStringUTF8(IDS_FIND_IN_PAGE_PREVIOUS_TOOLTIP).c_str()); 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_end(GTK_BOX(hbox), find_previous_button_->widget(), 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FALSE, FALSE, 0); 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make a box for the edit and match count widgets. This is fixed size since 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // we want the widgets inside to resize themselves rather than making the 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // dialog bigger. 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* content_hbox = gtk_hbox_new(FALSE, 0); 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_size_request(content_hbox, kTextEntryWidth, -1); 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch text_entry_ = gtk_entry_new(); 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_entry_set_has_frame(GTK_ENTRY(text_entry_), FALSE); 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch match_count_label_ = gtk_label_new(NULL); 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This line adds padding on the sides so that the label has even padding on 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // all edges. 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_misc_set_padding(GTK_MISC(match_count_label_), 2, 0); 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch match_count_event_box_ = gtk_event_box_new(); 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* match_count_centerer = gtk_vbox_new(FALSE, 0); 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_start(GTK_BOX(match_count_centerer), match_count_event_box_, 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TRUE, TRUE, 0); 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_set_border_width(GTK_CONTAINER(match_count_centerer), 1); 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_add(GTK_CONTAINER(match_count_event_box_), match_count_label_); 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_end(GTK_BOX(content_hbox), match_count_centerer, 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FALSE, FALSE, 0); 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_end(GTK_BOX(content_hbox), text_entry_, TRUE, TRUE, 0); 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This event box is necessary to color in the area above and below the match 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // count label, and is where we draw the entry background onto in GTK mode. 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BuildBorder(content_hbox, true, 0, 0, 0, 0, 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &content_event_box_, &content_alignment_); 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_app_paintable(content_event_box_, TRUE); 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(content_event_box_, "expose-event", 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnContentEventBoxExpose), this); 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This alignment isn't centered and is used for spacing in chrome theme 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // mode. (It's also used in GTK mode for padding because left padding doesn't 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // equal bottom padding naturally.) 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BuildBorder(content_event_box_, false, 2, 2, 2, 0, 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &border_bin_, &border_bin_alignment_); 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::CenterWidgetInHBox(hbox, border_bin_, true, 0); 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen theme_service_->InitThemesFor(this); 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::AllSources()); 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(widget(), "parent-set", G_CALLBACK(OnParentSet), this); 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We take care to avoid showing the slide animator widget. 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show_all(container_); 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show(widget()); 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3163345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickFindBarController* FindBarGtk::GetFindBarController() const { 3173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return find_bar_controller_; 3183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 3193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid FindBarGtk::SetFindBarController(FindBarController* find_bar_controller) { 3213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick find_bar_controller_ = find_bar_controller; 3223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 3233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::Show(bool animate) { 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (animate) { 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch slide_widget_->Open(); 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch selection_rect_ = gfx::Rect(); 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Reposition(); 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (container_->window) 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_raise(container_->window); 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch slide_widget_->OpenWithoutAnimation(); 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::Hide(bool animate) { 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (animate) 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch slide_widget_->Close(); 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch slide_widget_->CloseWithoutAnimation(); 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::SetFocusAndSelection() { 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StoreOutsideFocus(); 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_grab_focus(text_entry_); 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Select all the text. 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_entry_select_region(GTK_ENTRY(text_entry_), 0, -1); 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::ClearResults(const FindNotificationDetails& results) { 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateUIForFindResult(results, string16()); 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::StopAnimation() { 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch slide_widget_->End(); 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::MoveWindowIfNecessary(const gfx::Rect& selection_rect, 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool no_redraw) { 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Not moving the window on demand, so do nothing. 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::SetFindText(const string16& find_text) { 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string find_text_utf8 = UTF16ToUTF8(find_text); 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Ignore the "changed" signal handler because programatically setting the 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // text should not fire a "changed" event. 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ignore_changed_signal_ = true; 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_entry_set_text(GTK_ENTRY(text_entry_), find_text_utf8.c_str()); 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ignore_changed_signal_ = false; 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::UpdateUIForFindResult(const FindNotificationDetails& result, 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const string16& find_text) { 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!result.selection_rect().IsEmpty()) { 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch selection_rect_ = result.selection_rect(); 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int xposition = GetDialogPosition(result.selection_rect()).x(); 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (xposition != widget()->allocation.x) 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Reposition(); 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Once we find a match we no longer want to keep track of what had 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // focus. EndFindSession will then set the focus to the page content. 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result.number_of_matches() > 0) 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch focus_store_.Store(NULL); 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string find_text_utf8 = UTF16ToUTF8(find_text); 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool have_valid_range = 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result.number_of_matches() != -1 && result.active_match_ordinal() != -1; 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string entry_text(gtk_entry_get_text(GTK_ENTRY(text_entry_))); 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (entry_text != find_text_utf8) { 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetFindText(find_text); 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_entry_select_region(GTK_ENTRY(text_entry_), 0, -1); 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!find_text.empty() && have_valid_range) { 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_label_set_text(GTK_LABEL(match_count_label_), 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch l10n_util::GetStringFUTF8(IDS_FIND_IN_PAGE_COUNT, 4003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::IntToString16(result.active_match_ordinal()), 4013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::IntToString16(result.number_of_matches())).c_str()); 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateMatchLabelAppearance(result.number_of_matches() == 0 && 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result.final_update()); 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If there was no text entered, we don't show anything in the result count 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // area. 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_label_set_text(GTK_LABEL(match_count_label_), ""); 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateMatchLabelAppearance(false); 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::AudibleAlert() { 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This call causes a lot of weird bugs, especially when using the custom 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // frame. TODO(estade): if people complain, re-enable it. See 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // http://crbug.com/27635 and others. 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // gtk_widget_error_bell(widget()); 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Rect FindBarGtk::GetDialogPosition(gfx::Rect avoid_overlapping_rect) { 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool ltr = !base::i18n::IsRTL(); 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 15 is the size of the scrollbar, copied from ScrollbarThemeChromium. 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The height is not used. 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // At very low browser widths we can wind up with a negative |dialog_bounds| 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // width, so clamp it to 0. 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Rect dialog_bounds = gfx::Rect(ltr ? 0 : 15, 0, 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::max(0, widget()->parent->allocation.width - (ltr ? 15 : 0)), 0); 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkRequisition req; 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_size_request(container_, &req); 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Size prefsize(req.width, req.height); 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Rect view_location( 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ltr ? dialog_bounds.width() - prefsize.width() : dialog_bounds.x(), 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dialog_bounds.y(), prefsize.width(), prefsize.height()); 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Rect new_pos = FindBarController::GetLocationForFindbarView( 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch view_location, dialog_bounds, avoid_overlapping_rect); 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new_pos; 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool FindBarGtk::IsFindBarVisible() { 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GTK_WIDGET_VISIBLE(widget()); 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::RestoreSavedFocus() { 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This function sometimes gets called when we don't have focus. We should do 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // nothing in this case. 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!gtk_widget_is_focus(text_entry_)) 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (focus_store_.widget()) 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_grab_focus(focus_store_.widget()); 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 45572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen find_bar_controller_->tab_contents()->tab_contents()->Focus(); 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFindBarTesting* FindBarGtk::GetFindBarTesting() { 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return this; 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::Observe(NotificationType type, 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationSource& source, 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationDetails& details) { 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(type.value, NotificationType::BROWSER_THEME_CHANGED); 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Force reshapings of the find bar window. 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch container_width_ = -1; 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch container_height_ = -1; 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (theme_service_->UseGtkTheme()) { 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_cursor(text_entry_, NULL, NULL); 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_base(text_entry_, GTK_STATE_NORMAL, NULL); 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_text(text_entry_, GTK_STATE_NORMAL, NULL); 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Prevent forced font sizes because it causes the jump up and down 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // character movement (http://crbug.com/22614), and because it will 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // prevent centering of the text entry. 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::UndoForceFontSize(text_entry_); 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::UndoForceFontSize(match_count_label_); 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_size_request(content_event_box_, -1, -1); 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_bg(content_event_box_, GTK_STATE_NORMAL, NULL); 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Replicate the normal GtkEntry behaviour by drawing the entry 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // background. We set the fake alignment to be the frame thickness. 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkStyle* style = gtk_rc_get_style(text_entry_); 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint xborder = style->xthickness; 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint yborder = style->ythickness; 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_alignment_set_padding(GTK_ALIGNMENT(content_alignment_), 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch yborder, yborder, xborder, xborder); 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We leave left padding on the left, even in GTK mode, as it's required 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // for the left margin to be equivalent to the bottom margin. 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_alignment_set_padding(GTK_ALIGNMENT(border_bin_alignment_), 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, 0, 1, 0); 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We need this event box to have its own window in GTK mode for doing the 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // hacky widget rendering. 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_event_box_set_visible_window(GTK_EVENT_BOX(border_bin_), TRUE); 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_app_paintable(border_bin_, TRUE); 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_misc_set_alignment(GTK_MISC(match_count_label_), 0.5, 0.5); 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 505513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch gtk_widget_modify_cursor( 506513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch text_entry_, >k_util::kGdkBlack, >k_util::kGdkGray); 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_base(text_entry_, GTK_STATE_NORMAL, 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &kEntryBackgroundColor); 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_text(text_entry_, GTK_STATE_NORMAL, 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &kEntryTextColor); 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Until we switch to vector graphics, force the font size. 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::ForceFontSizePixels(text_entry_, 13.4); // 13.4px == 10pt @ 96dpi 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::ForceFontSizePixels(match_count_label_, 13.4); 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Force the text widget height so it lines up with the buttons regardless 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // of font size. 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_size_request(content_event_box_, -1, 20); 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_bg(content_event_box_, GTK_STATE_NORMAL, 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &kEntryBackgroundColor); 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_alignment_set_padding(GTK_ALIGNMENT(content_alignment_), 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0.0, 0.0, 0.0, 0.0); 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_alignment_set_padding(GTK_ALIGNMENT(border_bin_alignment_), 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2, 2, 3, 0); 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We need this event box to be invisible because we're only going to draw 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // on the background (but we can't take it out of the heiarchy entirely 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // because we also need it to take up space). 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_event_box_set_visible_window(GTK_EVENT_BOX(border_bin_), FALSE); 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_app_paintable(border_bin_, FALSE); 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_misc_set_alignment(GTK_MISC(match_count_label_), 0.5, 1.0); 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch close_button_->SetBackground( 538ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen theme_service_->GetColor(ThemeService::COLOR_TAB_TEXT), 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rb.GetBitmapNamed(IDR_CLOSE_BAR), 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rb.GetBitmapNamed(IDR_CLOSE_BAR_MASK)); 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateMatchLabelAppearance(match_label_failure_); 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool FindBarGtk::GetFindBarWindowInfo(gfx::Point* position, 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool* fully_visible) { 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (position) 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *position = GetPosition(); 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (fully_visible) { 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *fully_visible = !slide_widget_->IsAnimating() && 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch slide_widget_->IsShowing(); 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstring16 FindBarGtk::GetFindText() { 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string contents(gtk_entry_get_text(GTK_ENTRY(text_entry_))); 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return UTF8ToUTF16(contents); 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstring16 FindBarGtk::GetFindSelectedText() { 56421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen gint cursor_pos; 56521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen gint selection_bound; 56621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen g_object_get(G_OBJECT(text_entry_), "cursor-position", &cursor_pos, 56721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NULL); 56821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen g_object_get(G_OBJECT(text_entry_), "selection-bound", &selection_bound, 56921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NULL); 57021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string contents(gtk_entry_get_text(GTK_ENTRY(text_entry_))); 57121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return UTF8ToUTF16(contents.substr(cursor_pos, selection_bound)); 57221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 57321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 57421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstring16 FindBarGtk::GetMatchCountText() { 57521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string contents(gtk_label_get_text(GTK_LABEL(match_count_label_))); 57621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return UTF8ToUTF16(contents); 57721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 57821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::FindEntryTextInContents(bool forward_search) { 58072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TabContentsWrapper* tab_contents = find_bar_controller_->tab_contents(); 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!tab_contents) 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 583dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen FindTabHelper* find_tab_helper = tab_contents->find_tab_helper(); 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string new_contents(gtk_entry_get_text(GTK_ENTRY(text_entry_))); 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (new_contents.length() > 0) { 588dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen find_tab_helper->StartFinding(UTF8ToUTF16(new_contents), forward_search, 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false); // Not case sensitive. 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The textbox is empty so we reset. 592dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen find_tab_helper->StopFinding(FindBarController::kClearSelection); 593dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UpdateUIForFindResult(find_tab_helper->find_result(), string16()); 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Clearing the text box should also clear the prepopulate state so that 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // when we close and reopen the Find box it doesn't show the search we 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // just deleted. 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FindBarState* find_bar_state = browser_->profile()->GetFindBarState(); 599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch find_bar_state->set_last_prepopulate_text(string16()); 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::UpdateMatchLabelAppearance(bool failure) { 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch match_label_failure_ = failure; 605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool use_gtk = theme_service_->UseGtkTheme(); 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (use_gtk) { 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkStyle* style = gtk_rc_get_style(text_entry_); 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkColor normal_bg = style->base[GTK_STATE_NORMAL]; 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkColor normal_text = gtk_util::AverageColors( 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style->text[GTK_STATE_NORMAL], style->base[GTK_STATE_NORMAL]); 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_bg(match_count_event_box_, GTK_STATE_NORMAL, 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch failure ? &kFindFailureBackgroundColor : 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &normal_bg); 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_fg(match_count_label_, GTK_STATE_NORMAL, 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch failure ? &kEntryTextColor : &normal_text); 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_bg(match_count_event_box_, GTK_STATE_NORMAL, 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch failure ? &kFindFailureBackgroundColor : 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &kEntryBackgroundColor); 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_fg(match_count_label_, GTK_STATE_NORMAL, 623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch failure ? &kEntryTextColor : &kFindSuccessTextColor); 624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::Reposition() { 628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!IsFindBarVisible()) 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This will trigger an allocate, which allows us to reposition. 632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (widget()->parent) 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_queue_resize(widget()->parent); 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::StoreOutsideFocus() { 637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |text_entry_| is the only widget in the find bar that can be focused, 638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // so it's the only one we have to check. 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(estade): when we make the find bar buttons focusable, we'll have 640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to change this (same above in RestoreSavedFocus). 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!gtk_widget_is_focus(text_entry_)) 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch focus_store_.Store(text_entry_); 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool FindBarGtk::MaybeForwardKeyEventToRenderer(GdkEventKey* event) { 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (event->keyval) { 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_Down: 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_Up: 649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_Page_Up: 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_Page_Down: 651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_Home: 653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_End: 654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((event->state & gtk_accelerator_get_default_mod_mask()) == 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GDK_CONTROL_MASK) { 656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Fall through. 659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 66372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TabContentsWrapper* contents = find_bar_controller_->tab_contents(); 664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!contents) 665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RenderViewHost* render_view_host = contents->render_view_host(); 668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure we don't have a text field element interfering with keyboard 670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // input. Otherwise Up and Down arrow key strokes get eaten. "Nom Nom Nom". 671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_host->ClearFocusedNode(); 672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NativeWebKeyboardEvent wke(event); 674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_host->ForwardKeyboardEvent(wke); 675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::AdjustTextAlignment() { 679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PangoDirection content_dir = 680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pango_find_base_dir(gtk_entry_get_text(GTK_ENTRY(text_entry_)), -1); 681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkTextDirection widget_dir = gtk_widget_get_direction(text_entry_); 683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Use keymap or widget direction if content does not have strong direction. 685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // It matches the behavior of GtkEntry. 686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (content_dir == PANGO_DIRECTION_NEUTRAL) { 687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (GTK_WIDGET_HAS_FOCUS(text_entry_)) { 688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch content_dir = gdk_keymap_get_direction( 689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_keymap_get_for_display(gtk_widget_get_display(text_entry_))); 690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (widget_dir == GTK_TEXT_DIR_RTL) 692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch content_dir = PANGO_DIRECTION_RTL; 693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch content_dir = PANGO_DIRECTION_LTR; 695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((widget_dir == GTK_TEXT_DIR_RTL && content_dir == PANGO_DIRECTION_LTR) || 699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (widget_dir == GTK_TEXT_DIR_LTR && content_dir == PANGO_DIRECTION_RTL)) { 700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_entry_set_alignment(GTK_ENTRY(text_entry_), 1.0); 701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_entry_set_alignment(GTK_ENTRY(text_entry_), 0.0); 703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Point FindBarGtk::GetPosition() { 707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Point point; 708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GValue value = { 0, }; 710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_value_init(&value, G_TYPE_INT); 711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_child_get_property(GTK_CONTAINER(widget()->parent), 712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget(), "x", &value); 713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch point.set_x(g_value_get_int(&value)); 714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_child_get_property(GTK_CONTAINER(widget()->parent), 716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget(), "y", &value); 717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch point.set_y(g_value_get_int(&value)); 718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_value_unset(&value); 720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return point; 722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::OnParentSet(GtkWidget* widget, GtkObject* old_parent, 726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FindBarGtk* find_bar) { 727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!widget->parent) 728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(widget->parent, "set-floating-position", 731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnSetFloatingPosition), find_bar); 732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::OnSetFloatingPosition( 736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkFloatingContainer* floating_container, 737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkAllocation* allocation, 738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FindBarGtk* find_bar) { 739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* findbar = find_bar->widget(); 740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int xposition = find_bar->GetDialogPosition(find_bar->selection_rect_).x(); 742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GValue value = { 0, }; 744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_value_init(&value, G_TYPE_INT); 745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_value_set_int(&value, xposition); 746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_child_set_property(GTK_CONTAINER(floating_container), 747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch findbar, "x", &value); 748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_value_set_int(&value, 0); 750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_child_set_property(GTK_CONTAINER(floating_container), 751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch findbar, "y", &value); 752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_value_unset(&value); 753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean FindBarGtk::OnChanged(GtkWindow* window, FindBarGtk* find_bar) { 757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch find_bar->AdjustTextAlignment(); 758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!find_bar->ignore_changed_signal_) 760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch find_bar->FindEntryTextInContents(true); 761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FALSE; 763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean FindBarGtk::OnKeyPressEvent(GtkWidget* widget, GdkEventKey* event, 767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FindBarGtk* find_bar) { 768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (find_bar->MaybeForwardKeyEventToRenderer(event)) { 769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (GDK_Escape == event->keyval) { 771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch find_bar->find_bar_controller_->EndFindSession( 772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FindBarController::kKeepSelection); 773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (GDK_Return == event->keyval || 775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GDK_KP_Enter == event->keyval) { 776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((event->state & gtk_accelerator_get_default_mod_mask()) == 777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GDK_CONTROL_MASK) { 778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch find_bar->find_bar_controller_->EndFindSession( 779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FindBarController::kActivateSelection); 780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool forward = (event->state & gtk_accelerator_get_default_mod_mask()) != 784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GDK_SHIFT_MASK; 785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch find_bar->FindEntryTextInContents(forward); 786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FALSE; 789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean FindBarGtk::OnKeyReleaseEvent(GtkWidget* widget, GdkEventKey* event, 793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FindBarGtk* find_bar) { 794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return find_bar->MaybeForwardKeyEventToRenderer(event); 795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::OnClicked(GtkWidget* button, FindBarGtk* find_bar) { 799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (button == find_bar->close_button_->widget()) { 800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch find_bar->find_bar_controller_->EndFindSession( 801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FindBarController::kKeepSelection); 802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (button == find_bar->find_previous_button_->widget() || 803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch button == find_bar->find_next_button_->widget()) { 804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch find_bar->FindEntryTextInContents( 805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch button == find_bar->find_next_button_->widget()); 806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean FindBarGtk::OnContentEventBoxExpose(GtkWidget* widget, 813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEventExpose* event, 814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FindBarGtk* bar) { 815ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (bar->theme_service_->UseGtkTheme()) { 816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Draw the text entry background around where we input stuff. Note the 817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // decrement to |width|. We do this because some theme engines 818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (*cough*Clearlooks*cough*) don't do any blending and use thickness to 819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // make sure that widgets never overlap. 820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int padding = gtk_widget_get_style(widget)->xthickness; 821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkRectangle rec = { 822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget->allocation.x, 823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget->allocation.y, 824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget->allocation.width - padding, 825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget->allocation.height 826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::DrawTextEntryBackground(bar->text_entry_, widget, 829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &event->area, &rec); 830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FALSE; 833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Used to handle custom painting of |container_|. 836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean FindBarGtk::OnExpose(GtkWidget* widget, GdkEventExpose* e, 837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FindBarGtk* bar) { 838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkRequisition req; 839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_size_request(widget, &req); 840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_size_request(bar->widget(), req.width, -1); 841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 842ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (bar->theme_service_->UseGtkTheme()) { 843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (bar->container_width_ != widget->allocation.width || 844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bar->container_height_ != widget->allocation.height) { 845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<GdkPoint> mask_points = MakeFramePolygonPoints( 846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget->allocation.width, widget->allocation.height, FRAME_MASK); 847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkRegion* mask_region = gdk_region_polygon(&mask_points[0], 848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mask_points.size(), 849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GDK_EVEN_ODD_RULE); 850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Reset the shape. 851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_shape_combine_region(widget->window, NULL, 0, 0); 852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_shape_combine_region(widget->window, mask_region, 0, 0); 853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_region_destroy(mask_region); 854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bar->container_width_ = widget->allocation.width; 856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bar->container_height_ = widget->allocation.height; 857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkDrawable* drawable = GDK_DRAWABLE(e->window); 860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkGC* gc = gdk_gc_new(drawable); 861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_gc_set_clip_rectangle(gc, &e->area); 862ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GdkColor color = bar->theme_service_->GetBorderColor(); 863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_gc_set_rgb_fg_color(gc, &color); 864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Stroke the frame border. 866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<GdkPoint> points = MakeFramePolygonPoints( 867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget->allocation.width, widget->allocation.height, FRAME_STROKE); 868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_draw_lines(drawable, gc, &points[0], points.size()); 869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_unref(gc); 871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (bar->container_width_ != widget->allocation.width || 873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bar->container_height_ != widget->allocation.height) { 874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Reset the shape. 875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_shape_combine_region(widget->window, NULL, 0, 0); 876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetDialogShape(bar->container_); 877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bar->container_width_ = widget->allocation.width; 879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bar->container_height_ = widget->allocation.height; 880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); 883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_cairo_rectangle(cr, &e->area); 884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_clip(cr); 885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Point tabstrip_origin = 887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bar->window_->tabstrip()->GetTabStripOriginForWidget(widget); 888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::DrawThemedToolbarBackground(widget, cr, e, tabstrip_origin, 890ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bar->theme_service_); 891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // During chrome theme mode, we need to draw the border around content_hbox 893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // now instead of when we render |border_bin_|. We don't use stacked event 894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // boxes to simulate the effect because we need to blend them with this 895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // background. 896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkAllocation border_allocation = bar->border_bin_->allocation; 897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Blit the left part of the background image once on the left. 8993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CairoCachedSurface* background_left = 900ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bar->theme_service_->GetRTLEnabledSurfaceNamed( 9013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick IDR_FIND_BOX_BACKGROUND_LEFT, widget); 902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch background_left->SetSource(cr, border_allocation.x, border_allocation.y); 903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); 904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_rectangle(cr, border_allocation.x, border_allocation.y, 905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch background_left->Width(), background_left->Height()); 906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_fill(cr); 907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Blit the center part of the background image in all the space between. 909ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CairoCachedSurface* background = bar->theme_service_->GetSurfaceNamed( 910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_FIND_BOX_BACKGROUND, widget); 911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch background->SetSource(cr, 912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch border_allocation.x + background_left->Width(), 913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch border_allocation.y); 914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); 915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_rectangle(cr, 916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch border_allocation.x + background_left->Width(), 917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch border_allocation.y, 918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch border_allocation.width - background_left->Width(), 919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch background->Height()); 920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_fill(cr); 921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_destroy(cr); 923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Draw the border. 925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetDialogBorder()->RenderToWidget(widget); 926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Propagate to the container's child. 929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* child = gtk_bin_get_child(GTK_BIN(widget)); 930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (child) 931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_propagate_expose(GTK_CONTAINER(widget), child, e); 932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean FindBarGtk::OnFocus(GtkWidget* text_entry, GtkDirectionType focus, 937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FindBarGtk* find_bar) { 938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch find_bar->StoreOutsideFocus(); 939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Continue propagating the event. 941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FALSE; 942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean FindBarGtk::OnButtonPress(GtkWidget* text_entry, GdkEventButton* e, 946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FindBarGtk* find_bar) { 947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch find_bar->StoreOutsideFocus(); 948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Continue propagating the event. 950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FALSE; 951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::OnMoveCursor(GtkEntry* entry, GtkMovementStep step, gint count, 955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gboolean selection, FindBarGtk* bar) { 956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static guint signal_id = g_signal_lookup("move-cursor", GTK_TYPE_ENTRY); 957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEvent* event = gtk_get_current_event(); 959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (event) { 960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((event->type == GDK_KEY_PRESS || event->type == GDK_KEY_RELEASE) && 961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bar->MaybeForwardKeyEventToRenderer(&(event->key))) { 962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_stop_emission(entry, signal_id, 0); 963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_event_free(event); 966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FindBarGtk::OnActivate(GtkEntry* entry, FindBarGtk* bar) { 971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bar->FindEntryTextInContents(true); 972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean FindBarGtk::OnFocusIn(GtkWidget* entry, GdkEventFocus* event, 976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FindBarGtk* find_bar) { 977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect( 978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_keymap_get_for_display(gtk_widget_get_display(entry)), 979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "direction-changed", 980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(&OnKeymapDirectionChanged), find_bar); 981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch find_bar->AdjustTextAlignment(); 983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FALSE; // Continue propagation. 985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean FindBarGtk::OnFocusOut(GtkWidget* entry, GdkEventFocus* event, 989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FindBarGtk* find_bar) { 990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_handlers_disconnect_by_func( 991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_keymap_get_for_display(gtk_widget_get_display(entry)), 992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reinterpret_cast<gpointer>(&OnKeymapDirectionChanged), find_bar); 993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FALSE; // Continue propagation. 995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 996