summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/input_window.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/views/input_window.cc')
-rw-r--r--chrome/browser/views/input_window.cc194
1 files changed, 194 insertions, 0 deletions
diff --git a/chrome/browser/views/input_window.cc b/chrome/browser/views/input_window.cc
new file mode 100644
index 0000000..058e29d
--- /dev/null
+++ b/chrome/browser/views/input_window.cc
@@ -0,0 +1,194 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "chrome/browser/views/input_window.h"
+
+#include "chrome/browser/standard_layout.h"
+#include "chrome/common/l10n_util.h"
+#include "chrome/views/grid_layout.h"
+#include "chrome/views/label.h"
+#include "chrome/views/text_field.h"
+#include "chrome/views/window.h"
+#include "generated_resources.h"
+
+// Width to make the text field, in pixels.
+static const int kTextFieldWidth = 200;
+
+// ContentView ----------------------------------------------------------------
+
+// ContentView, as the name implies, is the content view for the InputWindow.
+// It registers accelerators that accept/cancel the input.
+
+class ContentView : public ChromeViews::View,
+ public ChromeViews::DialogDelegate,
+ public ChromeViews::TextField::Controller {
+ public:
+ explicit ContentView(InputWindowDelegate* delegate)
+ : delegate_(delegate),
+ window_(NULL),
+ focus_grabber_factory_(this) {
+ DCHECK(delegate_);
+ }
+
+ void set_window(ChromeViews::Window* window) { window_ = window; }
+
+ // ChromeViews::DialogDelegate overrides:
+ virtual bool IsDialogButtonEnabled(DialogButton button) const;
+ virtual bool Accept();
+ virtual bool Cancel();
+ virtual void WindowClosing();
+ virtual std::wstring GetWindowTitle() const;
+ virtual bool IsModal() const { return true; }
+
+ // ChromeViews::TextField::Controller overrides:
+ virtual void ContentsChanged(ChromeViews::TextField* sender,
+ const std::wstring& new_contents);
+ virtual void HandleKeystroke(ChromeViews::TextField*, UINT, TCHAR, UINT,
+ UINT) {}
+
+ protected:
+ // ChromeViews::View overrides:
+ virtual void ViewHierarchyChanged(bool is_add, ChromeViews::View* parent,
+ ChromeViews::View* child);
+
+ private:
+ // Set up dialog controls and layout.
+ void InitControlLayout();
+
+ // Sets focus to the first focusable element within the dialog.
+ void FocusFirstFocusableControl();
+
+ // The TextField that the user can type into.
+ ChromeViews::TextField* text_field_;
+
+ // The delegate that the ContentView uses to communicate changes to the
+ // caller.
+ InputWindowDelegate* delegate_;
+
+ // The Window that owns this view.
+ ChromeViews::Window* window_;
+
+ // Helps us set focus to the first TextField in the window.
+ ScopedRunnableMethodFactory<ContentView> focus_grabber_factory_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(ContentView);
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// ContentView, ChromeViews::DialogDelegate implementation:
+
+bool ContentView::IsDialogButtonEnabled(DialogButton button) const {
+ if (button == DIALOGBUTTON_OK && !delegate_->IsValid(text_field_->GetText()))
+ return false;
+ return true;
+}
+
+bool ContentView::Accept() {
+ delegate_->InputAccepted(text_field_->GetText());
+ return true;
+}
+
+bool ContentView::Cancel() {
+ delegate_->InputCanceled();
+ return true;
+}
+
+void ContentView::WindowClosing() {
+ delegate_->WindowClosing();
+}
+
+std::wstring ContentView::GetWindowTitle() const {
+ return delegate_->GetWindowTitle();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// ContentView, ChromeViews::TextField::Controller implementation:
+
+void ContentView::ContentsChanged(ChromeViews::TextField* sender,
+ const std::wstring& new_contents) {
+ window_->UpdateDialogButtons();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// ContentView, protected:
+
+void ContentView::ViewHierarchyChanged(bool is_add,
+ ChromeViews::View* parent,
+ ChromeViews::View* child) {
+ if (is_add && child == this)
+ InitControlLayout();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// ContentView, private:
+
+void ContentView::InitControlLayout() {
+ text_field_ = new ChromeViews::TextField;
+ text_field_->SetText(delegate_->GetTextFieldContents());
+ text_field_->SetController(this);
+
+ using ChromeViews::ColumnSet;
+ using ChromeViews::GridLayout;
+
+ // TODO(sky): Vertical alignment should be baseline.
+ GridLayout* layout = CreatePanelGridLayout(this);
+ SetLayoutManager(layout);
+
+ ColumnSet* c1 = layout->AddColumnSet(0);
+ c1->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
+ GridLayout::USE_PREF, 0, 0);
+ c1->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
+ c1->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
+ GridLayout::USE_PREF, kTextFieldWidth, kTextFieldWidth);
+
+ layout->StartRow(0, 0);
+ ChromeViews::Label* label =
+ new ChromeViews::Label(delegate_->GetTextFieldLabel());
+ layout->AddView(label);
+ layout->AddView(text_field_);
+
+ MessageLoop::current()->PostTask(FROM_HERE,
+ focus_grabber_factory_.NewRunnableMethod(
+ &ContentView::FocusFirstFocusableControl));
+}
+
+void ContentView::FocusFirstFocusableControl() {
+ text_field_->SelectAll();
+ text_field_->RequestFocus();
+}
+
+ChromeViews::Window* CreateInputWindow(HWND parent_hwnd,
+ InputWindowDelegate* delegate) {
+ ContentView* cv = new ContentView(delegate);
+ ChromeViews::Window* window = ChromeViews::Window::CreateChromeWindow(
+ parent_hwnd, gfx::Rect(), cv, cv);
+ cv->set_window(window);
+ window->UpdateDialogButtons();
+ return window;
+}