summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authortc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-12 17:03:37 +0000
committertc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-12 17:03:37 +0000
commit92e175a8152b4a7226cf8715aed8501ed7d83187 (patch)
tree67ca4faf8de98eef08cbc592f4b16b8d08d739be /chrome
parent7985f9159ec6ba70fcdc4c76b6bc8787c074cb50 (diff)
downloadchromium_src-92e175a8152b4a7226cf8715aed8501ed7d83187.zip
chromium_src-92e175a8152b4a7226cf8715aed8501ed7d83187.tar.gz
chromium_src-92e175a8152b4a7226cf8715aed8501ed7d83187.tar.bz2
Some work in refactoring FindBarWin/FindBarView so
we can share code across platforms. See http://code.google.com/p/chromium/wiki/FindBarRefactoring for more information about the design. Review URL: http://codereview.chromium.org/42057 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11544 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browser.scons3
-rw-r--r--chrome/browser/browser.vcproj12
-rw-r--r--chrome/browser/find_bar.h72
-rw-r--r--chrome/browser/find_bar_controller.cc136
-rw-r--r--chrome/browser/find_bar_controller.h51
-rw-r--r--chrome/browser/gtk/browser_window_gtk.cc22
-rw-r--r--chrome/browser/gtk/browser_window_gtk.h4
-rw-r--r--chrome/browser/gtk/find_bar_gtk.cc52
-rw-r--r--chrome/browser/gtk/find_bar_gtk.h41
-rw-r--r--chrome/browser/views/find_bar_view.cc25
-rw-r--r--chrome/browser/views/find_bar_win.cc151
-rw-r--r--chrome/browser/views/find_bar_win.h78
-rw-r--r--chrome/browser/views/frame/browser_view.cc32
-rw-r--r--chrome/browser/views/frame/browser_view.h4
-rw-r--r--chrome/chrome.gyp3
15 files changed, 470 insertions, 216 deletions
diff --git a/chrome/browser/browser.scons b/chrome/browser/browser.scons
index fd164282..a572a0b 100644
--- a/chrome/browser/browser.scons
+++ b/chrome/browser/browser.scons
@@ -189,6 +189,9 @@ input_files = ChromeFileList([
'controller.h',
'dock_info.cc',
'dock_info.h',
+ 'find_bar.h',
+ 'find_bar_controller.cc',
+ 'find_bar_controller.h',
'find_notification_details.h',
'js_before_unload_handler.h',
'js_before_unload_handler_win.cc',
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index c7827fa..da8341a 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -702,6 +702,18 @@
>
</File>
<File
+ RelativePath=".\find_bar_controller.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\find_bar_controller.h"
+ >
+ </File>
+ <File
+ RelativePath=".\find_bar.h"
+ >
+ </File>
+ <File
RelativePath=".\find_notification_details.h"
>
</File>
diff --git a/chrome/browser/find_bar.h b/chrome/browser/find_bar.h
new file mode 100644
index 0000000..5ebb188
--- /dev/null
+++ b/chrome/browser/find_bar.h
@@ -0,0 +1,72 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// This is an interface for the platform specific FindBar. It is responsible
+// for drawing the FindBar bar on the platform and is owned by the
+// FindBarController.
+
+#ifndef CHROME_BROWSER_FIND_BAR_H_
+#define CHROME_BROWSER_FIND_BAR_H_
+
+#include "base/gfx/rect.h"
+
+class FindNotificationDetails;
+class WebContents;
+
+class FindBar {
+ public:
+ virtual ~FindBar() { }
+
+ // Shows the find bar. Any previous search string will again be visible.
+ virtual void Show() = 0;
+
+ // Hide the find bar. If |animate| is true, we try to slide the find bar
+ // away.
+ virtual void Hide(bool animate) = 0;
+
+ // Restore the selected text in the find box and focus it.
+ virtual void SetFocusAndSelection() = 0;
+
+ // Clear the text in the find box.
+ virtual void ClearResults(const FindNotificationDetails& results) = 0;
+
+ // Stop the animation.
+ virtual void StopAnimation() = 0;
+
+ // Set the text in the find box.
+ virtual void SetFindText(const std::wstring& find_text) = 0;
+
+ // Updates the FindBar with the find result details contained within the
+ // specified |result|.
+ virtual void UpdateUIForFindResult(const FindNotificationDetails& result,
+ const std::wstring& find_text) = 0;
+
+ // Returns the rectangle representing where to position the find bar. It uses
+ // GetDialogBounds and positions itself within that, either to the left (if an
+ // InfoBar is present) or to the right (no InfoBar). If
+ // |avoid_overlapping_rect| is specified, the return value will be a rectangle
+ // located immediately to the left of |avoid_overlapping_rect|, as long as
+ // there is enough room for the dialog to draw within the bounds. If not, the
+ // dialog position returned will overlap |avoid_overlapping_rect|.
+ // Note: |avoid_overlapping_rect| is expected to use coordinates relative to
+ // the top of the page area, (it will be converted to coordinates relative to
+ // the top of the browser window, when comparing against the dialog
+ // coordinates). The returned value is relative to the browser window.
+ virtual gfx::Rect GetDialogPosition(gfx::Rect avoid_overlapping_rect) = 0;
+
+ // Moves the dialog window to the provided location, moves it to top in the
+ // z-order (HWND_TOP, not HWND_TOPMOST) and shows the window (if hidden).
+ // It then calls UpdateWindowEdges to make sure we don't overwrite the Chrome
+ // window border. If |no_redraw| is set, the window is getting moved but not
+ // sized, and should not be redrawn to reduce update flicker.
+ virtual void SetDialogPosition(const gfx::Rect& new_pos, bool no_redraw) = 0;
+
+ virtual bool IsFindBarVisible() = 0;
+
+ // Upon dismissing the window, restore focus to the last focused view which is
+ // not FindBarView or any of its children.
+ virtual void RestoreSavedFocus() = 0;
+};
+
+#endif // CHROME_BROWSER_FIND_BAR_H_
diff --git a/chrome/browser/find_bar_controller.cc b/chrome/browser/find_bar_controller.cc
new file mode 100644
index 0000000..81e759b
--- /dev/null
+++ b/chrome/browser/find_bar_controller.cc
@@ -0,0 +1,136 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/find_bar_controller.h"
+
+#include "build/build_config.h"
+#include "chrome/browser/find_bar.h"
+#include "chrome/browser/tab_contents/navigation_entry.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/browser/tab_contents/web_contents.h"
+
+FindBarController::FindBarController(FindBar* find_bar)
+ : find_bar_(find_bar), web_contents_(NULL) {
+}
+
+FindBarController::~FindBarController() {
+ // Web contents should have been NULLed out. If not, then we're leaking
+ // notification observers.
+ DCHECK(!web_contents_);
+}
+
+void FindBarController::Show() {
+ // Only show the animation if we're not already showing a find bar for the
+ // selected WebContents.
+ if (!web_contents_->find_ui_active()) {
+ web_contents_->set_find_ui_active(true);
+ find_bar_->Show();
+ }
+ find_bar_->SetFocusAndSelection();
+}
+
+void FindBarController::EndFindSession() {
+ find_bar_->Hide(true);
+
+ // |web_contents_| can be NULL for a number of reasons, for example when the
+ // tab is closing. We must guard against that case. See issue 8030.
+ if (web_contents_) {
+ // When we hide the window, we need to notify the renderer that we are done
+ // for now, so that we can abort the scoping effort and clear all the
+ // tickmarks and highlighting.
+ web_contents_->StopFinding(false); // false = don't clear selection on
+ // page.
+ find_bar_->ClearResults(web_contents_->find_result());
+
+ // When we get dismissed we restore the focus to where it belongs.
+ find_bar_->RestoreSavedFocus();
+ }
+}
+
+void FindBarController::ChangeWebContents(WebContents* contents) {
+ if (web_contents_) {
+ NotificationService::current()->RemoveObserver(
+ this, NotificationType::FIND_RESULT_AVAILABLE,
+ Source<TabContents>(web_contents_));
+ NotificationService::current()->RemoveObserver(
+ this, NotificationType::NAV_ENTRY_COMMITTED,
+ Source<NavigationController>(web_contents_->controller()));
+ find_bar_->StopAnimation();
+ }
+
+ web_contents_ = contents;
+
+ // Hide any visible find window from the previous tab if NULL |web_contents|
+ // is passed in or if the find UI is not active in the new tab.
+ if (find_bar_->IsFindBarVisible() &&
+ (!web_contents_ || !web_contents_->find_ui_active())) {
+ find_bar_->Hide(false);
+ }
+
+ if (web_contents_) {
+ NotificationService::current()->AddObserver(
+ this, NotificationType::FIND_RESULT_AVAILABLE,
+ Source<TabContents>(web_contents_));
+ NotificationService::current()->AddObserver(
+ this, NotificationType::NAV_ENTRY_COMMITTED,
+ Source<NavigationController>(web_contents_->controller()));
+
+ // Update the find bar with existing results and search text, regardless of
+ // whether or not the find bar is visible, so that if it's subsequently
+ // shown it is showing the right state for this tab. We update the find text
+ // _first_ since the FindBarView checks its emptiness to see if it should
+ // clear the result count display when there's nothing in the box.
+ find_bar_->SetFindText(web_contents_->find_text());
+
+ if (web_contents_->find_ui_active()) {
+ // A tab with a visible find bar just got selected and we need to show the
+ // find bar but without animation since it was already animated into its
+ // visible state. We also want to reset the window location so that
+ // we don't surprise the user by popping up to the left for no apparent
+ // reason.
+ gfx::Rect new_pos = find_bar_->GetDialogPosition(gfx::Rect());
+ find_bar_->SetDialogPosition(new_pos, false);
+
+ // Only modify focus and selection if Find is active, otherwise the Find
+ // Bar will interfere with user input.
+ find_bar_->SetFocusAndSelection();
+ }
+
+ find_bar_->UpdateUIForFindResult(web_contents_->find_result(),
+ web_contents_->find_text());
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// FindBarWin, NotificationObserver implementation:
+
+void FindBarController::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::FIND_RESULT_AVAILABLE) {
+ // Don't update for notifications from TabContentses other than the one we
+ // are actively tracking.
+ if (Source<TabContents>(source).ptr() == web_contents_) {
+ find_bar_->UpdateUIForFindResult(web_contents_->find_result(),
+ web_contents_->find_text());
+ FindNotificationDetails details = web_contents_->find_result();
+ }
+ } else if (type == NotificationType::NAV_ENTRY_COMMITTED) {
+ NavigationController* source_controller =
+ Source<NavigationController>(source).ptr();
+ if (source_controller == web_contents_->controller()) {
+ NavigationController::LoadCommittedDetails* commit_details =
+ Details<NavigationController::LoadCommittedDetails>(details).ptr();
+ PageTransition::Type transition_type =
+ commit_details->entry->transition_type();
+ // We hide the FindInPage window when the user navigates away, except on
+ // reload.
+ if (find_bar_->IsFindBarVisible() &&
+ PageTransition::StripQualifier(transition_type) !=
+ PageTransition::RELOAD) {
+ EndFindSession();
+ }
+ }
+ }
+}
diff --git a/chrome/browser/find_bar_controller.h b/chrome/browser/find_bar_controller.h
new file mode 100644
index 0000000..7551239
--- /dev/null
+++ b/chrome/browser/find_bar_controller.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_FIND_BAR_CONTROLLER_H_
+#define CHROME_BROWSER_FIND_BAR_CONTROLLER_H_
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "chrome/common/notification_observer.h"
+
+class FindBar;
+class WebContents;
+
+class FindBarController : public NotificationObserver {
+ public:
+ // FindBar takes ownership of |find_bar_view|.
+ FindBarController(FindBar* find_bar);
+
+ virtual ~FindBarController();
+
+ // Shows the find bar. Any previous search string will again be visible.
+ void Show();
+
+ // Ends the current session.
+ void EndFindSession();
+
+ // Accessor for the attached WebContents.
+ WebContents* web_contents() const { return web_contents_; }
+
+ // Changes the WebContents that this FindBar is attached to. This occurs when
+ // the user switches tabs in the Browser window. |contents| can be NULL.
+ void ChangeWebContents(WebContents* contents);
+
+ // Overridden from NotificationObserver:
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ FindBar* get_find_bar() const { return find_bar_.get(); }
+
+ private:
+ scoped_ptr<FindBar> find_bar_;
+
+ // The WebContents we are currently associated with. Can be NULL.
+ WebContents* web_contents_;
+
+ DISALLOW_COPY_AND_ASSIGN(FindBarController);
+};
+
+#endif // CHROME_BROWSER_FIND_BAR_CONTROLLER_H_
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index 484b5ff..6a58b4b 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -8,6 +8,7 @@
#include "base/base_paths_linux.h"
#include "base/path_service.h"
#include "chrome/browser/browser.h"
+#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/gtk/browser_toolbar_gtk.h"
#include "chrome/browser/gtk/find_bar_gtk.h"
#include "chrome/browser/gtk/nine_box.h"
@@ -169,10 +170,12 @@ void BrowserWindowGtk::Init() {
toolbar_->Init(browser_->profile(), accel_group);
toolbar_->AddToolbarToBox(vbox_);
- find_bar_.reset(new FindBarGtk());
+ FindBarGtk* find_bar_gtk = new FindBarGtk();
+ find_bar_controller_.reset(new FindBarController(find_bar_gtk));
+ find_bar_gtk->set_find_bar_controller(find_bar_controller_.get());
contents_container_.reset(new TabContentsContainerGtk(
- find_bar_->gtk_widget()));
+ find_bar_gtk->gtk_widget()));
contents_container_->AddContainerToBox(vbox_);
@@ -205,6 +208,11 @@ void BrowserWindowGtk::Close() {
if (!window_)
return;
+ // TODO(tc): Once the tab strip model is hooked up, this call can be removed.
+ // It should get called by TabDetachedAt when the window is being closed, but
+ // we don't have a TabStripModel yet.
+ find_bar_controller_->ChangeWebContents(NULL);
+
gtk_widget_destroy(GTK_WIDGET(window_));
window_ = NULL;
}
@@ -311,7 +319,7 @@ void BrowserWindowGtk::ToggleBookmarkBar() {
}
void BrowserWindowGtk::ShowFindBar() {
- find_bar_->Show();
+ find_bar_controller_->Show();
}
void BrowserWindowGtk::ShowAboutChromeDialog() {
@@ -368,6 +376,11 @@ void BrowserWindowGtk::TabDetachedAt(TabContents* contents, int index) {
// TODO(port): Uncoment this line when we get infobars.
// infobar_container_->ChangeTabContents(NULL);
contents_container_->SetTabContents(NULL);
+
+ // When dragging the last TabContents out of a window there is no selection
+ // notification that causes the find bar for that window to be un-registered
+ // for notifications from this TabContents.
+ find_bar_controller_->ChangeWebContents(NULL);
}
}
@@ -390,7 +403,8 @@ void BrowserWindowGtk::TabSelectedAt(TabContents* old_contents,
toolbar_->SetProfile(new_contents->profile());
UpdateToolbar(new_contents, true);
- find_bar_->ChangeWebContents(new_contents->AsWebContents());
+ if (find_bar_controller_.get())
+ find_bar_controller_->ChangeWebContents(new_contents->AsWebContents());
}
void BrowserWindowGtk::TabStripEmpty() {
diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h
index df1fbdd..7d86175 100644
--- a/chrome/browser/gtk/browser_window_gtk.h
+++ b/chrome/browser/gtk/browser_window_gtk.h
@@ -13,7 +13,7 @@
#include "chrome/browser/tabs/tab_strip_model.h"
class BrowserToolbarGtk;
-class FindBarGtk;
+class FindBarController;
class LocationBar;
class NineBox;
class StatusBubbleGtk;
@@ -124,7 +124,7 @@ class BrowserWindowGtk : public BrowserWindow,
// The Find Bar. This may be NULL if there is no Find Bar, and if it is
// non-NULL, it may or may not be visible. It is possible for the Find Bar
// to move among windows as tabs are dragged around.
- scoped_ptr<FindBarGtk> find_bar_;
+ scoped_ptr<FindBarController> find_bar_controller_;
};
#endif // CHROME_BROWSER_GTK_BROWSER_WINDOW_GTK_H_
diff --git a/chrome/browser/gtk/find_bar_gtk.cc b/chrome/browser/gtk/find_bar_gtk.cc
index 5bfe1c6..2398770 100644
--- a/chrome/browser/gtk/find_bar_gtk.cc
+++ b/chrome/browser/gtk/find_bar_gtk.cc
@@ -7,6 +7,7 @@
#include <gdk/gdkkeysyms.h>
#include "base/string_util.h"
+#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/gtk/tab_contents_container_gtk.h"
#include "chrome/browser/tab_contents/web_contents.h"
@@ -20,13 +21,13 @@ gboolean EntryContentsChanged(GtkWindow* window, FindBarGtk* find_bar) {
gboolean KeyPressEvent(GtkWindow* window, GdkEventKey* event,
FindBarGtk* find_bar) {
if (GDK_Escape == event->keyval)
- find_bar->Hide();
+ find_bar->EscapePressed();
return FALSE;
}
}
-FindBarGtk::FindBarGtk() : web_contents_(NULL) {
+FindBarGtk::FindBarGtk() {
find_text_ = gtk_entry_new();
gtk_widget_show(find_text_);
@@ -45,26 +46,57 @@ void FindBarGtk::Show() {
gtk_widget_grab_focus(find_text_);
}
-void FindBarGtk::Hide() {
+void FindBarGtk::Hide(bool animate) {
+ // TODO(tc): Animated slide away.
gtk_widget_hide(container_);
- if (web_contents_)
- web_contents_->StopFinding(true);
+}
+
+void FindBarGtk::SetFocusAndSelection() {
+}
+
+void FindBarGtk::ClearResults(const FindNotificationDetails& results) {
+}
+
+void FindBarGtk::StopAnimation() {
+ // No animation yet, so do nothing.
+}
+
+void FindBarGtk::SetFindText(const std::wstring& find_text) {
+}
+
+void FindBarGtk::UpdateUIForFindResult(const FindNotificationDetails& result,
+ const std::wstring& find_text) {
+}
+
+gfx::Rect FindBarGtk::GetDialogPosition(gfx::Rect avoid_overlapping_rect) {
+ return gfx::Rect();
+}
+
+void FindBarGtk::SetDialogPosition(const gfx::Rect& new_pos, bool no_redraw) {
+}
+
+bool FindBarGtk::IsFindBarVisible() {
+ return true;
+}
+
+void FindBarGtk::RestoreSavedFocus() {
}
void FindBarGtk::ContentsChanged() {
- if (!web_contents_)
+ WebContents* web_contents = find_bar_controller_->web_contents();
+ if (!web_contents)
return;
std::string new_contents(gtk_entry_get_text(GTK_ENTRY(find_text_)));
if (new_contents.length() > 0) {
- web_contents_->StartFinding(UTF8ToWide(new_contents), true);
+ web_contents->StartFinding(UTF8ToWide(new_contents), true);
} else {
// The textbox is empty so we reset.
- web_contents_->StopFinding(true); // true = clear selection on page.
+ web_contents->StopFinding(true); // true = clear selection on page.
}
}
-void FindBarGtk::ChangeWebContents(WebContents* contents) {
- web_contents_ = contents;
+void FindBarGtk::EscapePressed() {
+ find_bar_controller_->EndFindSession();
}
diff --git a/chrome/browser/gtk/find_bar_gtk.h b/chrome/browser/gtk/find_bar_gtk.h
index 9a38ce9..6ac3c41 100644
--- a/chrome/browser/gtk/find_bar_gtk.h
+++ b/chrome/browser/gtk/find_bar_gtk.h
@@ -5,33 +5,49 @@
#ifndef CHROME_BROWSER_GTK_FIND_BAR_GTK_H_
#define CHROME_BROWSER_GTK_FIND_BAR_GTK_H_
-#include <string>
+#include "chrome/browser/find_bar.h"
#include <gtk/gtk.h>
+#include <string>
+
+class FindBarController;
class TabContentsContainerGtk;
class WebContents;
// Currently this class contains both a model and a view. We may want to
// eventually pull out the model specific bits and share with Windows.
-class FindBarGtk {
+class FindBarGtk : public FindBar {
public:
FindBarGtk();
- ~FindBarGtk() { }
+ virtual ~FindBarGtk() { }
- // Show the find dialog if it's not already showing. The Find dialog is
- // positioned above the web contents area (TabContentsContainerGtk).
- void Show();
- void Hide();
+ void set_find_bar_controller(FindBarController* find_bar_controller) {
+ find_bar_controller_ = find_bar_controller;
+ }
// Callback when the text in the find box changes.
void ContentsChanged();
- // Callback from BrowserWindowGtk when the web contents changes.
- void ChangeWebContents(WebContents* contents);
+ // Callback when Escape is pressed.
+ void EscapePressed();
GtkWidget* gtk_widget() const { return container_; }
+ // Methods from FindBar.
+ virtual void Show();
+ virtual void Hide(bool animate);
+ virtual void SetFocusAndSelection();
+ virtual void ClearResults(const FindNotificationDetails& results);
+ virtual void StopAnimation();
+ virtual void SetFindText(const std::wstring& find_text);
+ virtual void UpdateUIForFindResult(const FindNotificationDetails& result,
+ const std::wstring& find_text);
+ virtual gfx::Rect GetDialogPosition(gfx::Rect avoid_overlapping_rect);
+ virtual void SetDialogPosition(const gfx::Rect& new_pos, bool no_redraw);
+ virtual bool IsFindBarVisible();
+ virtual void RestoreSavedFocus();
+
private:
// GtkHBox containing the find bar widgets.
GtkWidget* container_;
@@ -39,9 +55,10 @@ class FindBarGtk {
// The widget where text is entered.
GtkWidget* find_text_;
- // A non-owning pointer to the web contents associated with the find bar.
- // This can be NULL.
- WebContents* web_contents_;
+ // Pointer back to the owning controller.
+ FindBarController* find_bar_controller_;
+
+ DISALLOW_COPY_AND_ASSIGN(FindBarGtk);
};
#endif // CHROME_BROWSER_GTK_FIND_BAR_GTK_H_
diff --git a/chrome/browser/views/find_bar_view.cc b/chrome/browser/views/find_bar_view.cc
index 45616b1..1cb9481 100644
--- a/chrome/browser/views/find_bar_view.cc
+++ b/chrome/browser/views/find_bar_view.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include "base/string_util.h"
+#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/browser/views/find_bar_win.h"
#include "chrome/browser/view_ids.h"
@@ -398,9 +399,7 @@ void FindBarView::Layout() {
find_previous_button_->height());
}
-void FindBarView::ViewHierarchyChanged(bool is_add,
- View *parent,
- View *child) {
+void FindBarView::ViewHierarchyChanged(bool is_add, View *parent, View *child) {
if (is_add && child == this) {
find_text_->SetHorizontalMargins(3, 3); // Left and Right margins.
find_text_->RemoveBorder(); // We draw our own border (a background image).
@@ -429,13 +428,13 @@ void FindBarView::ButtonPressed(views::BaseButton* sender) {
case FIND_PREVIOUS_TAG:
case FIND_NEXT_TAG:
if (find_text_->GetText().length() > 0) {
- container_->web_contents()->StartFinding(
+ container_->find_bar_controller()->web_contents()->StartFinding(
find_text_->GetText(),
sender->GetTag() == FIND_NEXT_TAG);
}
break;
case CLOSE_TAG:
- container_->EndFindSession();
+ container_->find_bar_controller()->EndFindSession();
break;
default:
NOTREACHED() << L"Unknown button";
@@ -448,23 +447,23 @@ void FindBarView::ButtonPressed(views::BaseButton* sender) {
void FindBarView::ContentsChanged(views::TextField* sender,
const std::wstring& new_contents) {
+ FindBarController* controller = container_->find_bar_controller();
+ DCHECK(controller);
// We must guard against a NULL web_contents, which can happen if the text
// in the Find box is changed right after the tab is destroyed. Otherwise, it
// can lead to crashes, as exposed by automation testing in issue 8048.
- if (!container_->web_contents())
+ if (!controller->web_contents())
return;
// When the user changes something in the text box we check the contents and
// if the textbox contains something we set it as the new search string and
// initiate search (even though old searches might be in progress).
if (new_contents.length() > 0) {
- container_->web_contents()->StartFinding(new_contents, true);
+ controller->web_contents()->StartFinding(new_contents, true);
} else {
- // The textbox is empty so we reset.
- container_->web_contents()->StopFinding(true); // true = clear selection on
- // page.
- UpdateForResult(container_->web_contents()->find_result(),
- std::wstring());
+ // The textbox is empty so we reset. true = clear selection on page.
+ controller->web_contents()->StopFinding(true);
+ UpdateForResult(controller->web_contents()->find_result(), std::wstring());
}
}
@@ -480,7 +479,7 @@ void FindBarView::HandleKeystroke(views::TextField* sender, UINT message,
std::wstring find_string = find_text_->GetText();
if (find_string.length() > 0) {
// Search forwards for enter, backwards for shift-enter.
- container_->web_contents()->StartFinding(
+ container_->find_bar_controller()->web_contents()->StartFinding(
find_string,
GetKeyState(VK_SHIFT) >= 0);
}
diff --git a/chrome/browser/views/find_bar_win.cc b/chrome/browser/views/find_bar_win.cc
index dd9056c..5eae72d 100644
--- a/chrome/browser/views/find_bar_win.cc
+++ b/chrome/browser/views/find_bar_win.cc
@@ -6,15 +6,14 @@
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/bookmark_bar_view.h"
#include "chrome/browser/views/find_bar_view.h"
#include "chrome/browser/views/frame/browser_view.h"
-#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/browser/tab_contents/web_contents_view.h"
-#include "chrome/common/notification_service.h"
#include "chrome/views/external_focus_tracker.h"
#include "chrome/views/native_scroll_bar.h"
#include "chrome/views/root_view.h"
@@ -28,11 +27,11 @@ static const int kMinFindWndDistanceFromSelection = 5;
// FindBarWin, public:
FindBarWin::FindBarWin(BrowserView* browser_view)
- : web_contents_(NULL),
- browser_view_(browser_view),
+ : browser_view_(browser_view),
find_dialog_animation_offset_(0),
focus_manager_(NULL),
- old_accel_target_for_esc_(NULL) {
+ old_accel_target_for_esc_(NULL),
+ find_bar_controller_(NULL) {
HWND parent_hwnd = browser_view->GetWidget()->GetHWND();
// Start listening to focus changes, so we can register and unregister our
@@ -178,13 +177,11 @@ void FindBarWin::UpdateWindowEdges(const gfx::Rect& new_pos) {
}
void FindBarWin::Show() {
- // Only show the animation if we're not already showing a find bar for the
- // selected WebContents.
- if (!web_contents_->find_ui_active()) {
- web_contents_->set_find_ui_active(true);
- animation_->Reset();
- animation_->Show();
- }
+ animation_->Reset();
+ animation_->Show();
+}
+
+void FindBarWin::SetFocusAndSelection() {
view_->SetFocusAndSelection();
}
@@ -192,76 +189,30 @@ bool FindBarWin::IsAnimating() {
return animation_->IsAnimating();
}
-void FindBarWin::EndFindSession() {
- animation_->Reset(1.0);
- animation_->Hide();
-
- // |web_contents_| can be NULL for a number of reasons, for example when the
- // tab is closing. We must guard against that case. See issue 8030.
- if (web_contents_) {
- // When we hide the window, we need to notify the renderer that we are done
- // for now, so that we can abort the scoping effort and clear all the
- // tickmarks and highlighting.
- web_contents_->StopFinding(false); // false = don't clear selection on
- // page.
- view_->UpdateForResult(web_contents_->find_result(), std::wstring());
-
- // When we get dismissed we restore the focus to where it belongs.
- RestoreSavedFocus();
+void FindBarWin::Hide(bool animate) {
+ if (animate) {
+ animation_->Reset(1.0);
+ animation_->Hide();
+ } else {
+ ShowWindow(SW_HIDE);
}
}
-void FindBarWin::ChangeWebContents(WebContents* contents) {
- if (web_contents_) {
- NotificationService::current()->RemoveObserver(
- this, NotificationType::FIND_RESULT_AVAILABLE,
- Source<TabContents>(web_contents_));
- NotificationService::current()->RemoveObserver(
- this, NotificationType::NAV_ENTRY_COMMITTED,
- Source<NavigationController>(web_contents_->controller()));
- if (animation_->IsAnimating())
- animation_->End();
- }
-
- web_contents_ = contents;
+void FindBarWin::ClearResults(const FindNotificationDetails& results) {
+ view_->UpdateForResult(results, std::wstring());
+}
- // Hide any visible find window from the previous tab if NULL |web_contents|
- // is passed in or if the find UI is not active in the new tab.
- if (IsVisible() && (!web_contents_ || !web_contents_->find_ui_active()))
- ShowWindow(SW_HIDE);
+void FindBarWin::StopAnimation() {
+ if (animation_->IsAnimating())
+ animation_->End();
+}
- if (web_contents_) {
- NotificationService::current()->AddObserver(
- this, NotificationType::FIND_RESULT_AVAILABLE,
- Source<TabContents>(web_contents_));
- NotificationService::current()->AddObserver(
- this, NotificationType::NAV_ENTRY_COMMITTED,
- Source<NavigationController>(web_contents_->controller()));
-
- // Update the find bar with existing results and search text, regardless of
- // whether or not the find bar is visible, so that if it's subsequently
- // shown it is showing the right state for this tab. We update the find text
- // _first_ since the FindBarView checks its emptiness to see if it should
- // clear the result count display when there's nothing in the box.
- view_->SetFindText(web_contents_->find_text());
-
- if (web_contents_->find_ui_active()) {
- // A tab with a visible find bar just got selected and we need to show the
- // find bar but without animation since it was already animated into its
- // visible state. We also want to reset the window location so that
- // we don't surprise the user by popping up to the left for no apparent
- // reason.
- gfx::Rect new_pos = GetDialogPosition(gfx::Rect());
- SetDialogPosition(new_pos, false);
-
- // Only modify focus and selection if Find is active, otherwise the Find
- // Bar will interfere with user input.
- view_->SetFocusAndSelection();
- }
+void FindBarWin::SetFindText(const std::wstring& find_text) {
+ view_->SetFindText(find_text);
+}
- UpdateUIForFindResult(web_contents_->find_result(),
- web_contents_->find_text());
- }
+bool FindBarWin::IsFindBarVisible() {
+ return IsVisible();
}
void FindBarWin::MoveWindowIfNecessary(const gfx::Rect& selection_rect,
@@ -269,8 +220,10 @@ void FindBarWin::MoveWindowIfNecessary(const gfx::Rect& selection_rect,
// We only move the window if one is active for the current WebContents. If we
// don't check this, then SetDialogPosition below will end up making the Find
// Bar visible.
- if (!web_contents_ || !web_contents_->find_ui_active())
+ if (!find_bar_controller()->web_contents() ||
+ !find_bar_controller()->web_contents()->find_ui_active()) {
return;
+ }
gfx::Rect new_pos = GetDialogPosition(selection_rect);
SetDialogPosition(new_pos, no_redraw);
@@ -280,38 +233,6 @@ void FindBarWin::MoveWindowIfNecessary(const gfx::Rect& selection_rect,
}
////////////////////////////////////////////////////////////////////////////////
-// FindBarWin, NotificationObserver implementation:
-
-void FindBarWin::Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- if (type == NotificationType::FIND_RESULT_AVAILABLE) {
- // Don't update for notifications from TabContentses other than the one we
- // are actively tracking.
- if (Source<TabContents>(source).ptr() == web_contents_) {
- UpdateUIForFindResult(web_contents_->find_result(),
- web_contents_->find_text());
- FindNotificationDetails details = web_contents_->find_result();
- }
- } else if (type == NotificationType::NAV_ENTRY_COMMITTED) {
- NavigationController* source_controller =
- Source<NavigationController>(source).ptr();
- if (source_controller == web_contents_->controller()) {
- NavigationController::LoadCommittedDetails* commit_details =
- Details<NavigationController::LoadCommittedDetails>(details).ptr();
- PageTransition::Type transition_type =
- commit_details->entry->transition_type();
- // We hide the FindInPage window when the user navigates away, except on
- // reload.
- if (IsVisible() && PageTransition::StripQualifier(transition_type) !=
- PageTransition::RELOAD) {
- EndFindSession();
- }
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
// FindBarWin, views::WidgetWin implementation:
void FindBarWin::OnFinalMessage(HWND window) {
@@ -362,7 +283,7 @@ bool FindBarWin::AcceleratorPressed(const views::Accelerator& accelerator) {
// This will end the Find session and hide the window, causing it to loose
// focus and in the process unregister us as the handler for the Escape
// accelerator through the FocusWillChange event.
- EndFindSession();
+ find_bar_controller_->EndFindSession();
return true;
}
@@ -389,9 +310,11 @@ void FindBarWin::AnimationProgressed(const Animation* animation) {
}
void FindBarWin::AnimationEnded(const Animation* animation) {
+ // Place the find bar in its fully opened state.
+ find_dialog_animation_offset_ = 0;
+
if (!animation_->IsShowing()) {
// Animation has finished closing.
- find_dialog_animation_offset_ = 0;
ShowWindow(SW_HIDE);
} else {
// Animation has finished opening.
@@ -445,7 +368,9 @@ gfx::Rect FindBarWin::GetDialogPosition(gfx::Rect avoid_overlapping_rect) {
// whereas the selection rect is relative to the page.
RECT frame_rect = {0}, webcontents_rect = {0};
::GetWindowRect(GetParent(), &frame_rect);
- ::GetWindowRect(web_contents_->view()->GetNativeView(), &webcontents_rect);
+ ::GetWindowRect(
+ find_bar_controller()->web_contents()->view()->GetNativeView(),
+ &webcontents_rect);
avoid_overlapping_rect.Offset(0, webcontents_rect.top - frame_rect.top);
}
@@ -522,7 +447,7 @@ void FindBarWin::SetFocusChangeListener(HWND parent_hwnd) {
void FindBarWin::RestoreSavedFocus() {
if (focus_tracker_.get() == NULL) {
// TODO(brettw) Focus() should be on WebContentsView.
- web_contents_->Focus();
+ find_bar_controller()->web_contents()->Focus();
} else {
focus_tracker_->FocusLastFocusedExternalView();
}
diff --git a/chrome/browser/views/find_bar_win.h b/chrome/browser/views/find_bar_win.h
index c226ea9..b06a033 100644
--- a/chrome/browser/views/find_bar_win.h
+++ b/chrome/browser/views/find_bar_win.h
@@ -6,14 +6,15 @@
#define CHROME_BROWSER_VIEWS_FIND_BAR_WIN_H_
#include "base/gfx/rect.h"
-#include "chrome/browser/find_notification_details.h"
+#include "chrome/browser/find_bar.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
#include "chrome/common/animation.h"
-#include "chrome/common/notification_service.h"
#include "chrome/views/widget_win.h"
class BrowserView;
+class FindBarController;
class FindBarView;
+class FindNotificationDetails;
class RenderViewHost;
class SlideAnimation;
@@ -39,23 +40,19 @@ class View;
class FindBarWin : public views::FocusChangeListener,
public views::WidgetWin,
public AnimationDelegate,
- public NotificationObserver {
+ public FindBar {
public:
explicit FindBarWin(BrowserView* browser_view);
virtual ~FindBarWin();
- // Accessor for the attached WebContents.
- WebContents* web_contents() const { return web_contents_; }
-
- // Shows the find bar. Any previous search string will again be visible.
- void Show();
-
- // Ends the current session.
- void EndFindSession();
-
- // Changes the WebContents that this FindBar is attached to. This occurs when
- // the user switches tabs in the Browser window. |contents| can be NULL.
- void ChangeWebContents(WebContents* contents);
+ // Accessor for find_bar_controller so FindBarView can get back to
+ // FindBarController.
+ FindBarController* find_bar_controller() const {
+ return find_bar_controller_;
+ }
+ void set_find_bar_controller(FindBarController* find_bar_controller) {
+ find_bar_controller_ = find_bar_controller;
+ }
// If the find bar obscures the search results we need to move the window. To
// do that we need to know what is selected on the page. We simply calculate
@@ -79,10 +76,19 @@ class FindBarWin : public views::FocusChangeListener,
// new |parent_hwnd|.
void SetFocusChangeListener(HWND parent_hwnd);
- // Overridden from NotificationObserver:
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details);
+ // FindBar implementation:
+ virtual void Show();
+ virtual void Hide(bool animate);
+ virtual void SetFocusAndSelection();
+ virtual void ClearResults(const FindNotificationDetails& results);
+ virtual void StopAnimation();
+ virtual void SetFindText(const std::wstring& find_text);
+ virtual void UpdateUIForFindResult(const FindNotificationDetails& result,
+ const std::wstring& find_text);
+ virtual gfx::Rect GetDialogPosition(gfx::Rect avoid_overlapping_rect);
+ virtual void SetDialogPosition(const gfx::Rect& new_pos, bool no_redraw);
+ virtual bool IsFindBarVisible();
+ virtual void RestoreSavedFocus();
// Overridden from views::WidgetWin:
virtual void OnFinalMessage(HWND window);
@@ -111,26 +117,6 @@ class FindBarWin : public views::FocusChangeListener,
// be an empty rectangle.
void GetDialogBounds(gfx::Rect* bounds);
- // Returns the rectangle representing where to position the find bar. It uses
- // GetDialogBounds and positions itself within that, either to the left (if an
- // InfoBar is present) or to the right (no InfoBar). If
- // |avoid_overlapping_rect| is specified, the return value will be a rectangle
- // located immediately to the left of |avoid_overlapping_rect|, as long as
- // there is enough room for the dialog to draw within the bounds. If not, the
- // dialog position returned will overlap |avoid_overlapping_rect|.
- // Note: |avoid_overlapping_rect| is expected to use coordinates relative to
- // the top of the page area, (it will be converted to coordinates relative to
- // the top of the browser window, when comparing against the dialog
- // coordinates). The returned value is relative to the browser window.
- gfx::Rect GetDialogPosition(gfx::Rect avoid_overlapping_rect);
-
- // Moves the dialog window to the provided location, moves it to top in the
- // z-order (HWND_TOP, not HWND_TOPMOST) and shows the window (if hidden).
- // It then calls UpdateWindowEdges to make sure we don't overwrite the Chrome
- // window border. If |no_redraw| is set, the window is getting moved but not
- // sized, and should not be redrawn to reduce update flicker.
- void SetDialogPosition(const gfx::Rect& new_pos, bool no_redraw);
-
// The dialog needs rounded edges, so we create a polygon that corresponds to
// the background images for this window (and make the polygon only contain
// the pixels that we want to draw). The polygon is then given to SetWindowRgn
@@ -139,9 +125,6 @@ class FindBarWin : public views::FocusChangeListener,
// to prevent from drawing onto Chrome's window border.
void UpdateWindowEdges(const gfx::Rect& new_pos);
- // Upon dismissing the window, restore focus to the last focused view which is
- // not FindBarView or any of its children.
- void RestoreSavedFocus();
// Registers this class as the handler for when Escape is pressed. We will
// unregister once we loose focus. See also: SetFocusChangeListener().
@@ -151,14 +134,6 @@ class FindBarWin : public views::FocusChangeListener,
// also: SetFocusChangeListener().
void UnregisterEscAccelerator();
- // Updates the FindBarView with the find result details contained within the
- // specified |result|.
- void UpdateUIForFindResult(const FindNotificationDetails& result,
- const std::wstring& find_text);
-
- // The WebContents we are currently associated with.
- WebContents* web_contents_;
-
// The BrowserView that created us.
BrowserView* browser_view_;
@@ -183,6 +158,9 @@ class FindBarWin : public views::FocusChangeListener,
// closed.
scoped_ptr<views::ExternalFocusTracker> focus_tracker_;
+ // A pointer back to the owning controller.
+ FindBarController* find_bar_controller_;
+
DISALLOW_COPY_AND_ASSIGN(FindBarWin);
};
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index e8c2a54..27ddcac 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -12,6 +12,7 @@
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/encoding_menu_controller_delegate.h"
+#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/about_chrome_view.h"
#include "chrome/browser/views/bookmark_bar_view.h"
@@ -462,7 +463,10 @@ void BrowserView::Init() {
infobar_container_ = new InfoBarContainer(this);
AddChildView(infobar_container_);
- find_bar_.reset(new FindBarWin(this));
+ FindBarWin* find_bar_win = new FindBarWin(this);
+
+ find_bar_controller_.reset(new FindBarController(find_bar_win));
+ find_bar_win->set_find_bar_controller(find_bar_controller_.get());
contents_container_ = new TabContentsContainerView;
set_contents_view(contents_container_);
@@ -754,7 +758,7 @@ void BrowserView::ToggleBookmarkBar() {
}
void BrowserView::ShowFindBar() {
- find_bar_->Show();
+ find_bar_controller_->Show();
}
void BrowserView::ShowAboutChromeDialog() {
@@ -865,17 +869,24 @@ LocationBarView* BrowserView::GetLocationBarView() const {
bool BrowserView::GetFindBarWindowInfo(gfx::Point* position,
bool* fully_visible) const {
+ FindBarWin* find_bar_win = NULL;
+ if (find_bar_controller_.get()) {
+ find_bar_win = static_cast<FindBarWin*>(
+ find_bar_controller_->get_find_bar());
+ DCHECK(find_bar_win);
+ }
+
CRect window_rect;
- if (!find_bar_.get() ||
- !::IsWindow(find_bar_->GetHWND()) ||
- !::GetWindowRect(find_bar_->GetHWND(), &window_rect)) {
+ if (!find_bar_controller_.get() ||
+ !::IsWindow(find_bar_win->GetHWND()) ||
+ !::GetWindowRect(find_bar_win->GetHWND(), &window_rect)) {
*position = gfx::Point(0, 0);
*fully_visible = false;
return false;
}
*position = gfx::Point(window_rect.TopLeft().x, window_rect.TopLeft().y);
- *fully_visible = find_bar_->IsVisible() && !find_bar_->IsAnimating();
+ *fully_visible = find_bar_win->IsVisible() && !find_bar_win->IsAnimating();
return true;
}
@@ -910,7 +921,7 @@ void BrowserView::TabDetachedAt(TabContents* contents, int index) {
// When dragging the last TabContents out of a window there is no selection
// notification that causes the find bar for that window to be un-registered
// for notifications from this TabContents.
- find_bar_->ChangeWebContents(NULL);
+ find_bar_controller_->ChangeWebContents(NULL);
}
}
@@ -948,8 +959,8 @@ void BrowserView::TabSelectedAt(TabContents* old_contents,
UpdateToolbar(new_contents, true);
UpdateUIForContents(new_contents);
- if (find_bar_.get())
- find_bar_->ChangeWebContents(new_contents->AsWebContents());
+ if (find_bar_controller_.get())
+ find_bar_controller_->ChangeWebContents(new_contents->AsWebContents());
}
void BrowserView::TabStripEmpty() {
@@ -1210,7 +1221,8 @@ void BrowserView::Layout() {
// back into us to find the bounding box the find bar must be laid out within,
// and that code depends on the TabContentsContainer's bounds being up to
// date.
- find_bar_->MoveWindowIfNecessary(gfx::Rect(), true);
+ static_cast<FindBarWin*>(find_bar_controller_->get_find_bar())->
+ MoveWindowIfNecessary(gfx::Rect(), true);
LayoutStatusBubble(bottom);
#ifdef CHROME_PERSONALIZATION
if (IsPersonalizationEnabled()) {
diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h
index 8b9173c..a222819 100644
--- a/chrome/browser/views/frame/browser_view.h
+++ b/chrome/browser/views/frame/browser_view.h
@@ -24,7 +24,7 @@ class BookmarkBarView;
class Browser;
class BrowserToolbarView;
class EncodingMenuControllerDelegate;
-class FindBarWin;
+class FindBarController;
class FullscreenExitBubble;
class InfoBarContainer;
class Menu;
@@ -395,7 +395,7 @@ class BrowserView : public BrowserWindow,
// The Find Bar. This may be NULL if there is no Find Bar, and if it is
// non-NULL, it may or may not be visible.
- scoped_ptr<FindBarWin> find_bar_;
+ scoped_ptr<FindBarController> find_bar_controller_;
// The distance the FindBar is from the top of the window, in pixels.
int find_bar_y_;
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 83772a1..afdc600 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -606,6 +606,9 @@
'browser/external_tab_container.h',
'browser/fav_icon_helper.cc',
'browser/fav_icon_helper.h',
+ 'browser/find_bar.h",
+ 'browser/find_bar_controller.cc",
+ 'browser/find_bar_controller.h",
'browser/find_notification_details.h',
'browser/first_run.cc',
'browser/first_run.h',