15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/find_bar_view.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/themes/theme_properties.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/find_bar/find_bar_controller.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/find_bar/find_bar_state.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/find_bar/find_bar_state_factory.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/find_bar/find_notification_details.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/find_bar/find_tab_helper.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/view_ids.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/find_bar_host.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_view.h" 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/generated_resources.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h" 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/skia/include/core/SkPaint.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/theme_provider.h" 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "ui/resources/grit/ui_resources.h" 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/views/border.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/image_button.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h" 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/ime/input_method.h" 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/views/painter.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The margins around the UI controls, derived from assets and design specs. 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kMarginLeftOfCloseButton = 3; 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kMarginRightOfCloseButton = 7; 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kMarginLeftOfMatchCountLabel = 3; 440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst int kMarginRightOfMatchCountLabel = 1; 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kMarginLeftOfFindTextfield = 12; 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kMarginVerticalFindTextfield = 6; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The margins around the match count label (We add extra space so that the 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// background highlight extends beyond just the text). 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kMatchCountExtraWidth = 9; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Minimum width for the match count label. 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kMatchCountMinWidth = 30; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The text color for the match count label. 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const SkColor kTextColorMatchCount = SkColorSetRGB(178, 178, 178); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The text color for the match count label when no matches are found. 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const SkColor kTextColorNoMatch = SK_ColorBLACK; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The background color of the match count label when results are found. 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const SkColor kBackgroundColorMatch = SkColorSetARGB(0, 255, 255, 255); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The background color of the match count label when no results are found. 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const SkColor kBackgroundColorNoMatch = SkColorSetRGB(255, 102, 102); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The default number of average characters that the text box will be. This 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// number brings the width on a "regular fonts" system to about 300px. 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kDefaultCharWidth = 43; 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FindBarView, public: 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FindBarView::FindBarView(FindBarHost* host) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : DropdownBarView(host), 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_text_(NULL), 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_count_text_(NULL), 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) focus_forwarder_view_(NULL), 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_previous_button_(NULL), 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_next_button_(NULL), 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) close_button_(NULL) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) find_text_ = new views::Textfield; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_text_->set_id(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_text_->set_default_width_in_chars(kDefaultCharWidth); 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) find_text_->set_controller(this); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_text_->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_FIND)); 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The find bar textfield has a background image instead of a border. 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) find_text_->SetBorder(views::Border::NullBorder()); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(find_text_); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_count_text_ = new views::Label(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(match_count_text_); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a focus forwarder view which sends focus to find_text_. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) focus_forwarder_view_ = new FocusForwarderView(find_text_); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(focus_forwarder_view_); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_previous_button_ = new views::ImageButton(this); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_previous_button_->set_tag(FIND_PREVIOUS_TAG); 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) find_previous_button_->SetFocusable(true); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) find_previous_button_->SetImage(views::CustomButton::STATE_NORMAL, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rb.GetImageSkiaNamed(IDR_FINDINPAGE_PREV)); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) find_previous_button_->SetImage(views::CustomButton::STATE_HOVERED, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rb.GetImageSkiaNamed(IDR_FINDINPAGE_PREV_H)); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) find_previous_button_->SetImage(views::CustomButton::STATE_PRESSED, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rb.GetImageSkiaNamed(IDR_FINDINPAGE_PREV_P)); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) find_previous_button_->SetImage(views::CustomButton::STATE_DISABLED, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rb.GetImageSkiaNamed(IDR_FINDINPAGE_PREV_D)); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_previous_button_->SetTooltipText( 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_FIND_IN_PAGE_PREVIOUS_TOOLTIP)); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_previous_button_->SetAccessibleName( 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_ACCNAME_PREVIOUS)); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(find_previous_button_); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_next_button_ = new views::ImageButton(this); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_next_button_->set_tag(FIND_NEXT_TAG); 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) find_next_button_->SetFocusable(true); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) find_next_button_->SetImage(views::CustomButton::STATE_NORMAL, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rb.GetImageSkiaNamed(IDR_FINDINPAGE_NEXT)); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) find_next_button_->SetImage(views::CustomButton::STATE_HOVERED, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rb.GetImageSkiaNamed(IDR_FINDINPAGE_NEXT_H)); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) find_next_button_->SetImage(views::CustomButton::STATE_PRESSED, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rb.GetImageSkiaNamed(IDR_FINDINPAGE_NEXT_P)); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) find_next_button_->SetImage(views::CustomButton::STATE_DISABLED, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rb.GetImageSkiaNamed(IDR_FINDINPAGE_NEXT_D)); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_next_button_->SetTooltipText( 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_FIND_IN_PAGE_NEXT_TOOLTIP)); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_next_button_->SetAccessibleName( 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_ACCNAME_NEXT)); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(find_next_button_); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_button_ = new views::ImageButton(this); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_button_->set_tag(CLOSE_TAG); 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) close_button_->SetFocusable(true); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close_button_->SetImage(views::CustomButton::STATE_NORMAL, 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rb.GetImageSkiaNamed(IDR_CLOSE_1)); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close_button_->SetImage(views::CustomButton::STATE_HOVERED, 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rb.GetImageSkiaNamed(IDR_CLOSE_1_H)); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close_button_->SetImage(views::CustomButton::STATE_PRESSED, 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rb.GetImageSkiaNamed(IDR_CLOSE_1_P)); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_button_->SetTooltipText( 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_FIND_IN_PAGE_CLOSE_TOOLTIP)); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_button_->SetAccessibleName( 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE)); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close_button_->SetAnimationDuration(0); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildView(close_button_); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetBackground(rb.GetImageSkiaNamed(IDR_FIND_DLG_LEFT_BACKGROUND), 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rb.GetImageSkiaNamed(IDR_FIND_DLG_RIGHT_BACKGROUND)); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetBorderFromIds( 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IDR_FIND_DIALOG_LEFT, IDR_FIND_DIALOG_MIDDLE, IDR_FIND_DIALOG_RIGHT); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preferred_height_ = rb.GetImageSkiaNamed(IDR_FIND_DIALOG_MIDDLE)->height(); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static const int kImages[] = IMAGE_GRID(IDR_TEXTFIELD); 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) find_text_border_.reset(views::Painter::CreateImageGridPainter(kImages)); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnableCanvasFlippingForRTLUI(true); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FindBarView::~FindBarView() { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void FindBarView::SetFindTextAndSelectedRange( 170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& find_text, 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const gfx::Range& selected_range) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_text_->SetText(find_text); 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) find_text_->SelectRange(selected_range); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 FindBarView::GetFindText() const { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return find_text_->text(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)gfx::Range FindBarView::GetSelectedRange() const { 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return find_text_->GetSelectedRange(); 1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 FindBarView::GetFindSelectedText() const { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return find_text_->GetSelectedText(); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 FindBarView::GetMatchCountText() const { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return match_count_text_->text(); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindBarView::UpdateForResult(const FindNotificationDetails& result, 193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& find_text) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool have_valid_range = 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.number_of_matches() != -1 && result.active_match_ordinal() != -1; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/34970: some IMEs get confused if we change the text 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // composed by them. To avoid this problem, we should check the IME status and 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // update the text only when the IME is not composing text. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (find_text_->text() != find_text && !find_text_->IsIMEComposing()) { 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) find_text_->SetText(find_text); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_text_->SelectAll(true); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (find_text.empty() || !have_valid_range) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there was no text entered, we don't show anything in the result count 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // area. 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearMatchCount(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_count_text_->SetText(l10n_util::GetStringFUTF16(IDS_FIND_IN_PAGE_COUNT, 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::IntToString16(result.active_match_ordinal()), 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::IntToString16(result.number_of_matches()))); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateMatchCountAppearance(result.number_of_matches() == 0 && 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.final_update()); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The match_count label may have increased/decreased in size so we need to 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // do a layout and repaint the dialog so that the find text field doesn't 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // partially overlap the match-count label when it increases on no matches. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindBarView::ClearMatchCount() { 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match_count_text_->SetText(base::string16()); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateMatchCountAppearance(false); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindBarView::SetFocusAndSelection(bool select_all) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_text_->RequestFocus(); 235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetInputMethod()->ShowImeIfNeeded(); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (select_all && !find_text_->text().empty()) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_text_->SelectAll(true); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FindBarView, views::View overrides: 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindBarView::OnPaint(gfx::Canvas* canvas) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Paint drop down bar border and background. 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DropdownBarView::OnPaint(canvas); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Paint the background and border for the textfield. 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const int find_text_x = kMarginLeftOfFindTextfield / 2; 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect text_bounds(find_text_x, find_next_button_->y(), 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) find_next_button_->bounds().right() - find_text_x, 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) find_next_button_->height()); 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const int kBorderCornerRadius = 2; 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect background_bounds = text_bounds; 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_bounds.Inset(kBorderCornerRadius, kBorderCornerRadius); 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SkPaint paint; 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) paint.setStyle(SkPaint::kFill_Style); 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) paint.setColor(find_text_->GetBackgroundColor()); 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) canvas->DrawRoundRect(background_bounds, kBorderCornerRadius, paint); 259e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch canvas->Save(); 260e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch canvas->ClipRect(gfx::Rect(0, 0, find_previous_button_->x(), height())); 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) views::Painter::PaintPainterAt(canvas, find_text_border_.get(), text_bounds); 262e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch canvas->Restore(); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Draw the background of the match text. We want to make sure the red 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // "no-match" background almost completely fills up the amount of vertical 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // space within the text box. We therefore fix the size relative to the button 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // heights. We use the FindPrev button, which has a 1px outer whitespace 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // margin, 1px border and we want to appear 1px below the border line so we 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // subtract 3 for top and 3 for bottom. 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect match_count_background_bounds(match_count_text_->bounds()); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) match_count_background_bounds.set_height( 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) find_previous_button_->height() - 6); // Subtract 3px x 2. 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) match_count_background_bounds.set_y( 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (height() - match_count_background_bounds.height()) / 2); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->FillRect(match_count_background_bounds, 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) match_count_text_->background_color()); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindBarView::Layout() { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int panel_width = GetPreferredSize().width(); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stay within view bounds. 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int view_width = width(); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view_width && view_width < panel_width) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) panel_width = view_width; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First we draw the close button on the far right. 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size sz = close_button_->GetPreferredSize(); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_button_->SetBounds(panel_width - sz.width() - 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMarginRightOfCloseButton, 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (height() - sz.height()) / 2, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sz.width(), 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sz.height()); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the color. 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnThemeChanged(); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Next, the FindNext button to the left the close button. 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sz = find_next_button_->GetPreferredSize(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_next_button_->SetBounds(close_button_->x() - 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_next_button_->width() - 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMarginLeftOfCloseButton, 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (height() - sz.height()) / 2, 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sz.width(), 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sz.height()); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then, the FindPrevious button to the left the FindNext button. 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sz = find_previous_button_->GetPreferredSize(); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_previous_button_->SetBounds(find_next_button_->x() - 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_previous_button_->width(), 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (height() - sz.height()) / 2, 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sz.width(), 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sz.height()); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then the label showing the match count number. 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sz = match_count_text_->GetPreferredSize(); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We extend the label bounds a bit to give the background highlighting a bit 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of breathing room (margins around the text). 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sz.Enlarge(kMatchCountExtraWidth, 0); 319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sz.SetToMax(gfx::Size(kMatchCountMinWidth, 0)); 3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const int match_count_x = 3210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch find_previous_button_->x() - kMarginRightOfMatchCountLabel - sz.width(); 3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const int find_text_y = kMarginVerticalFindTextfield; 3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const gfx::Insets find_text_insets(find_text_->GetInsets()); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_count_text_->SetBounds(match_count_x, 3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci find_text_y - find_text_insets.top() + 3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci find_text_->GetBaseline() - 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) match_count_text_->GetBaseline(), 32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) sz.width(), sz.height()); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Fill the remaining width and available height with the textfield. 3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const int left_margin = kMarginLeftOfFindTextfield - find_text_insets.left(); 3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const int find_text_width = std::max(0, match_count_x - left_margin - 3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kMarginLeftOfMatchCountLabel + find_text_insets.right()); 3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci find_text_->SetBounds(left_margin, find_text_y, find_text_width, 3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci height() - 2 * kMarginVerticalFindTextfield); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The focus forwarder view is a hidden view that should cover the area 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // between the find text box and the find button so that when the user clicks 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in that area we focus on the find text box. 3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const int find_text_edge = find_text_->x() + find_text_->width(); 34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) focus_forwarder_view_->SetBounds( 34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) find_text_edge, find_previous_button_->y(), 34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) find_previous_button_->x() - find_text_edge, 34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) find_previous_button_->height()); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size FindBarView::GetPreferredSize() const { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size prefsize = find_text_->GetPreferredSize(); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.set_height(preferred_height_); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add up all the preferred sizes and margins of the rest of the controls. 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.Enlarge(kMarginLeftOfCloseButton + kMarginRightOfCloseButton + 3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kMarginLeftOfFindTextfield - 3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci find_text_->GetInsets().width(), 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.Enlarge(find_previous_button_->GetPreferredSize().width(), 0); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.Enlarge(find_next_button_->GetPreferredSize().width(), 0); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefsize.Enlarge(close_button_->GetPreferredSize().width(), 0); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return prefsize; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FindBarView, views::ButtonListener implementation: 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindBarView::ButtonPressed( 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Button* sender, const ui::Event& event) { 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (sender->tag()) { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FIND_PREVIOUS_TAG: 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FIND_NEXT_TAG: 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!find_text_->text().empty()) { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindTabHelper* find_tab_helper = FindTabHelper::FromWebContents( 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_bar_host()->GetFindBarController()->web_contents()); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_tab_helper->StartFinding(find_text_->text(), 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sender->tag() == FIND_NEXT_TAG, 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false); // Not case sensitive. 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.IsMouseEvent()) { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If mouse event, we move the focus back to the text-field, so that the 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // user doesn't have to click on the text field to change the search. We 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // don't want to do this for keyboard clicks on the button, since the 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // user is more likely to press FindNext again than change the search 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // query. 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_text_->RequestFocus(); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CLOSE_TAG: 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_bar_host()->GetFindBarController()->EndFindSession( 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindBarController::kKeepSelectionOnPage, 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindBarController::kKeepResultsInFindBox); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << L"Unknown button"; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FindBarView, views::TextfieldController implementation: 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FindBarView::HandleKeyEvent(views::Textfield* sender, 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::KeyEvent& key_event) { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the dialog is not visible, there is no reason to process keyboard input. 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!host()->IsVisible()) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (find_bar_host()->MaybeForwardKeyEventToWebpage(key_event)) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; // Handled, we are done! 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (key_event.key_code() == ui::VKEY_RETURN) { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pressing Return/Enter starts the search (unless text box is empty). 411a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 find_string = find_text_->text(); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!find_string.empty()) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindBarController* controller = find_bar_host()->GetFindBarController(); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindTabHelper* find_tab_helper = 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindTabHelper::FromWebContents(controller->web_contents()); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Search forwards for enter, backwards for shift-enter. 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find_tab_helper->StartFinding(find_string, 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !key_event.IsShiftDown(), 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false); // Not case sensitive. 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void FindBarView::OnAfterUserAction(views::Textfield* sender) { 428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The composition text wouldn't be what the user is really looking for. 429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // We delay the search until the user commits the composition text. 430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!sender->IsIMEComposing() && sender->text() != last_searched_text_) 431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Find(sender->text()); 432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void FindBarView::OnAfterPaste() { 435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Clear the last search text so we always search for the user input after 436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // a paste operation, even if the pasted text is the same as before. 437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // See http://crbug.com/79002 438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) last_searched_text_.clear(); 439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void FindBarView::Find(const base::string16& search_text) { 442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FindBarController* controller = find_bar_host()->GetFindBarController(); 443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(controller); 444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::WebContents* web_contents = controller->web_contents(); 445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // We must guard against a NULL web_contents, which can happen if the text 446868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // in the Find box is changed right after the tab is destroyed. Otherwise, it 447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // can lead to crashes, as exposed by automation testing in issue 8048. 448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!web_contents) 449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FindTabHelper* find_tab_helper = FindTabHelper::FromWebContents(web_contents); 451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) last_searched_text_ = search_text; 453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // When the user changes something in the text box we check the contents and 455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // if the textbox contains something we set it as the new search string and 456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // initiate search (even though old searches might be in progress). 457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!search_text.empty()) { 458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The last two params here are forward (true) and case sensitive (false). 459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) find_tab_helper->StartFinding(search_text, true, false); 460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) find_tab_helper->StopFinding(FindBarController::kClearSelectionOnPage); 462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UpdateForResult(find_tab_helper->find_result(), base::string16()); 463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) find_bar_host()->MoveWindowIfNecessary(gfx::Rect(), false); 464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Clearing the text box should clear the prepopulate state so that when 466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // we close and reopen the Find box it doesn't show the search we just 467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // deleted. We can't do this on ChromeOS yet because we get ContentsChanged 468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // sent for a lot more things than just the user nulling out the search 469868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // terms. See http://crbug.com/45372. 470868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Profile* profile = 471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Profile::FromBrowserContext(web_contents->GetBrowserContext()); 472868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FindBarState* find_bar_state = FindBarStateFactory::GetForProfile(profile); 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) find_bar_state->set_last_prepopulate_text(base::string16()); 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindBarView::UpdateMatchCountAppearance(bool no_match) { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (no_match) { 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) match_count_text_->SetBackgroundColor(kBackgroundColorNoMatch); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_count_text_->SetEnabledColor(kTextColorNoMatch); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) match_count_text_->SetBackgroundColor(kBackgroundColorMatch); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_count_text_->SetEnabledColor(kTextColorMatchCount); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FindBarView::FocusForwarderView::OnMousePressed( 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::MouseEvent& event) { 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (view_to_focus_on_mousedown_) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_to_focus_on_mousedown_->RequestFocus(); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FindBarHost* FindBarView::find_bar_host() const { 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<FindBarHost*>(host()); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindBarView::OnThemeChanged() { 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetThemeProvider()) { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_button_->SetBackground( 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetThemeProvider()->GetColor(ThemeProperties::COLOR_TAB_TEXT), 503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rb.GetImageSkiaNamed(IDR_CLOSE_1), 504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rb.GetImageSkiaNamed(IDR_CLOSE_1_MASK)); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 507