Skip to content
Snippets Groups Projects
Commit 6bc08095 authored by brettw@chromium.org's avatar brettw@chromium.org
Browse files

Make the views bookmark bubble work on GTK.

The combobox still isn't implemented, but this makes TextBox work, and also
does some changes around the info_bubble to make sure it get created properly.

TEST=none
BUG=none.
Review URL: http://codereview.chromium.org/177026

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@24821 0039d316-1c4b-4281-b951-d872f2087c98
parent 005afbdc
No related merge requests found
......@@ -7,6 +7,7 @@
#include "app/gfx/canvas.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/keyboard_codes.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/bookmarks/bookmark_editor.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
......@@ -20,6 +21,7 @@
#include "views/standard_layout.h"
#include "views/controls/button/native_button.h"
#include "views/controls/textfield/textfield.h"
#include "views/focus/focus_manager.h"
using views::Combobox;
using views::ColumnSet;
......@@ -111,7 +113,7 @@ int BookmarkBubbleView::RecentlyUsedFoldersModel::GetItemCount() {
std::wstring BookmarkBubbleView::RecentlyUsedFoldersModel::GetItemAt(
int index) {
if (index == nodes_.size())
if (index == static_cast<int>(nodes_.size()))
return l10n_util::GetString(IDS_BOOMARK_BUBBLE_CHOOSER_ANOTHER_FOLDER);
return nodes_[index]->GetTitle();
}
......@@ -182,7 +184,7 @@ void BookmarkBubbleView::DidChangeBounds(const gfx::Rect& previous,
void BookmarkBubbleView::BubbleShown() {
DCHECK(GetWidget());
GetFocusManager()->RegisterAccelerator(
views::Accelerator(VK_RETURN, false, false, false), this);
views::Accelerator(base::VKEY_RETURN, false, false, false), this);
title_tf_->RequestFocus();
title_tf_->SelectAll();
......@@ -190,7 +192,7 @@ void BookmarkBubbleView::BubbleShown() {
bool BookmarkBubbleView::AcceleratorPressed(
const views::Accelerator& accelerator) {
if (accelerator.GetKeyCode() != VK_RETURN)
if (accelerator.GetKeyCode() != base::VKEY_RETURN)
return false;
if (edit_button_->HasFocus())
ButtonPressed(edit_button_);
......@@ -199,6 +201,12 @@ bool BookmarkBubbleView::AcceleratorPressed(
return true;
}
void BookmarkBubbleView::ViewHierarchyChanged(bool is_add, View* parent,
View* child) {
if (is_add && child == this)
Init();
}
BookmarkBubbleView::BookmarkBubbleView(InfoBubbleDelegate* delegate,
Profile* profile,
const GURL& url,
......@@ -212,7 +220,6 @@ BookmarkBubbleView::BookmarkBubbleView(InfoBubbleDelegate* delegate,
profile_->GetBookmarkModel()->GetMostRecentlyAddedNodeForURL(url)),
remove_bookmark_(false),
apply_edits_(true) {
Init();
}
void BookmarkBubbleView::Init() {
......@@ -378,6 +385,7 @@ void BookmarkBubbleView::ShowEditor() {
// Commit any edits now.
ApplyEdits();
#if defined(OS_WIN)
// Parent the editor to our root ancestor (not the root we're in, as that
// is the info bubble and will close shortly).
HWND parent = GetAncestor(GetWidget()->GetNativeView(), GA_ROOTOWNER);
......@@ -390,6 +398,10 @@ void BookmarkBubbleView::ShowEditor() {
// status changes. That way, when the editor closes, activation is properly
// restored to the browser.
ShowWindow(GetWidget()->GetNativeView(), SW_HIDE);
#else
NOTIMPLEMENTED(); // TODO(brettw) find the parent.
gfx::NativeView parent = NULL;
#endif
// Even though we just hid the window, we need to invoke Close to schedule
// the delete and all that.
......
......@@ -57,6 +57,8 @@ class BookmarkBubbleView : public views::View,
// Override to close on return.
virtual bool AcceleratorPressed(const views::Accelerator& accelerator);
virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
private:
// Model for the combobox showing the list of folders to choose from. The
// list always contains the bookmark bar, other node and parent. The list
......
......@@ -32,24 +32,6 @@ void ShowImporterView(views::Widget* parent,
NOTIMPLEMENTED();
}
void ShowBookmarkBubbleView(views::Window* parent,
const gfx::Rect& bounds,
InfoBubbleDelegate* delegate,
Profile* profile,
const GURL& url,
bool newly_bookmarked) {
NOTIMPLEMENTED();
}
void HideBookmarkBubbleView() {
NOTIMPLEMENTED();
}
bool IsBookmarkBubbleViewShowing() {
NOTIMPLEMENTED();
return false;
}
void ShowBookmarkManagerView(Profile* profile) {
NOTIMPLEMENTED();
}
......
......@@ -129,29 +129,29 @@ void InfoBubble::Init(views::Window* parent,
0 : CS_DROPSHADOW);
#endif
content_view_ = CreateContentView(content);
gfx::Rect bounds =
content_view_->CalculateWindowBoundsAndAjust(position_relative_to);
#if defined(OS_WIN)
WidgetWin::Init(parent->GetNativeWindow(), bounds);
WidgetWin::Init(parent->GetNativeWindow(), gfx::Rect());
#else
WidgetGtk::Init(GTK_WIDGET(parent->GetNativeWindow()), bounds);
WidgetGtk::Init(GTK_WIDGET(parent->GetNativeWindow()), gfx::Rect());
#endif
SetContentsView(content_view_);
// The preferred size may differ when parented. Ask for the bounds again
// and if they differ reset the bounds.
gfx::Rect parented_bounds =
content_view_->CalculateWindowBoundsAndAjust(position_relative_to);
if (bounds != parented_bounds) {
// TODO(beng): This should be done in a cleaner and cross-platform way.
#if defined(OS_WIN)
SetWindowPos(NULL, parented_bounds.x(), parented_bounds.y(),
parented_bounds.width(), parented_bounds.height(),
SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOZORDER);
// Invoke ChangeSize, otherwise layered window isn't updated correctly.
ChangeSize(0, CSize(parented_bounds.width(), parented_bounds.height()));
SetWindowPos(NULL, parented_bounds.x(), parented_bounds.y(),
parented_bounds.width(), parented_bounds.height(),
SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOZORDER);
// Invoke ChangeSize, otherwise layered window isn't updated correctly.
ChangeSize(0, CSize(parented_bounds.width(), parented_bounds.height()));
#else
SetBounds(parented_bounds);
#endif
}
#if defined(OS_WIN)
// Register the Escape accelerator for closing.
......@@ -213,6 +213,7 @@ void InfoBubble::OnActivate(UINT action, BOOL minimized, HWND window) {
}
void InfoBubble::OnSize(UINT param, const CSize& size) {
// See OnSizeAllocate for the Linux version.
gfx::Path path;
content_view_->GetMask(gfx::Size(size.cx, size.cy), &path);
SetWindowRgn(path.CreateHRGN(), TRUE);
......@@ -239,16 +240,26 @@ void InfoBubble::Close(bool closed_by_escape) {
#endif
}
#if defined(OS_LINUX)
void InfoBubble::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) {
gfx::Path path;
content_view_->GetMask(gfx::Size(allocation->width, allocation->height),
&path);
SetShape(path);
WidgetGtk::OnSizeAllocate(widget, allocation);
}
#endif
// ContentView ----------------------------------------------------------------
InfoBubble::ContentView::ContentView(views::View* content, InfoBubble* host)
: host_(host) {
: content_(content),
host_(host) {
if (UILayoutIsRightToLeft()) {
arrow_edge_ = TOP_RIGHT;
} else {
arrow_edge_ = TOP_LEFT;
}
AddChildView(content);
}
gfx::Rect InfoBubble::ContentView::CalculateWindowBoundsAndAjust(
......@@ -439,6 +450,13 @@ void InfoBubble::ContentView::Paint(gfx::Canvas* canvas) {
}
}
void InfoBubble::ContentView::ViewHierarchyChanged(bool is_add,
View* parent,
View* child) {
if (is_add && child == this)
AddChildView(content_);
}
gfx::Rect InfoBubble::ContentView::CalculateWindowBounds(
const gfx::Rect& position_relative_to) {
gfx::Size pref = GetPreferredSize();
......
......@@ -147,12 +147,15 @@ class InfoBubble : public views::WidgetGtk, public AnimationDelegate {
// view. If this returns false the arrow is positioned along the right edge.
bool IsLeft() { return (arrow_edge_ & 1) == 0; }
private:
virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
private:
// Returns the bounds for the window containing us based on the current
// arrow edge.
gfx::Rect CalculateWindowBounds(const gfx::Rect& position_relative_to);
views::View* content_;
// Edge to draw the arrow at.
ArrowEdge arrow_edge_;
......@@ -170,6 +173,11 @@ class InfoBubble : public views::WidgetGtk, public AnimationDelegate {
// the close is the result of pressing escape.
void Close(bool closed_by_escape);
#if defined(OS_LINUX)
// Overridden from WidgetGtk.
virtual void OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation);
#endif
// The delegate notified when the InfoBubble is closed.
InfoBubbleDelegate* delegate_;
......
......@@ -2361,6 +2361,8 @@
['include', '^browser/views/autocomplete/autocomplete_popup_gtk.h'],
['include', '^browser/views/bookmark_bar_view.cc'],
['include', '^browser/views/bookmark_bar_view.h'],
['include', '^browser/views/bookmark_bubble_view.cc'],
['include', '^browser/views/bookmark_bubble_view.h'],
['include', '^browser/views/bookmark_context_menu.cc'],
['include', '^browser/views/bookmark_context_menu.h'],
['include', '^browser/views/bookmark_menu_button.cc'],
......
......@@ -101,8 +101,9 @@ int Label::ComputeMultiLineFlags() {
return flags;
}
void Label::CalculateDrawStringParams(
std::wstring* paint_text, gfx::Rect* text_bounds, int* flags) {
void Label::CalculateDrawStringParams(std::wstring* paint_text,
gfx::Rect* text_bounds,
int* flags) {
DCHECK(paint_text && text_bounds && flags);
if (url_set_) {
......
// #ifndef CHROME_VIEWS_NATIVE_CONTROL_WIN_H_// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
// 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.
......
......@@ -4,13 +4,19 @@
#include "views/controls/textfield/native_textfield_gtk.h"
#include "base/string_util.h"
#include "views/controls/textfield/textfield.h"
namespace views {
////////////////////////////////////////////////////////////////////////////////
// NativeTextfieldGtk, public:
NativeTextfieldGtk::NativeTextfieldGtk(Textfield* textfield)
: NativeControlGtk() {
: NativeControlGtk(),
textfield_(textfield) {
if (textfield_->style() & Textfield::STYLE_MULTILINE)
NOTIMPLEMENTED(); // We don't support multiline yet.
}
NativeTextfieldGtk::~NativeTextfieldGtk() {
......@@ -20,44 +26,91 @@ NativeTextfieldGtk::~NativeTextfieldGtk() {
// NativeTextfieldGtk, NativeTextfieldWrapper implementation:
std::wstring NativeTextfieldGtk::GetText() const {
return std::wstring();
if (!native_view())
return std::wstring();
return UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(native_view())));
}
void NativeTextfieldGtk::UpdateText() {
if (!native_view())
return;
gtk_entry_set_text(GTK_ENTRY(native_view()),
WideToUTF8(textfield_->text()).c_str());
}
void NativeTextfieldGtk::AppendText(const std::wstring& text) {
if (!native_view())
return;
gtk_entry_append_text(GTK_ENTRY(native_view()), WideToUTF8(text).c_str());
}
std::wstring NativeTextfieldGtk::GetSelectedText() const {
return std::wstring();
if (!native_view())
return std::wstring();
int begin, end;
if (!gtk_editable_get_selection_bounds(GTK_EDITABLE(native_view()),
&begin, &end))
return std::wstring(); // Nothing selected.
return UTF8ToWide(std::string(
&gtk_entry_get_text(GTK_ENTRY(native_view()))[begin],
end - begin));
}
void NativeTextfieldGtk::SelectAll() {
if (!native_view())
return;
// -1 as the end position selects to the end of the text.
gtk_editable_select_region(GTK_EDITABLE(native_view()),
0, -1);
}
void NativeTextfieldGtk::ClearSelection() {
if (!native_view())
return;
gtk_editable_select_region(GTK_EDITABLE(native_view()), 0, 0);
}
void NativeTextfieldGtk::UpdateBorder() {
if (!native_view())
return;
NOTIMPLEMENTED();
}
void NativeTextfieldGtk::UpdateBackgroundColor() {
if (!native_view())
return;
NOTIMPLEMENTED();
}
void NativeTextfieldGtk::UpdateReadOnly() {
if (!native_view())
return;
gtk_editable_set_editable(GTK_EDITABLE(native_view()),
textfield_->IsEnabled());
}
void NativeTextfieldGtk::UpdateFont() {
if (!native_view())
return;
NOTIMPLEMENTED();
}
void NativeTextfieldGtk::UpdateEnabled() {
if (!native_view())
return;
NOTIMPLEMENTED();
}
void NativeTextfieldGtk::SetHorizontalMargins(int left, int right) {
if (!native_view())
return;
NOTIMPLEMENTED();
}
void NativeTextfieldGtk::SetFocus() {
Focus();
}
View* NativeTextfieldGtk::GetView() {
......@@ -72,7 +125,10 @@ gfx::NativeView NativeTextfieldGtk::GetTestingHandle() const {
// NativeTextfieldGtk, NativeControlGtk overrides:
void NativeTextfieldGtk::CreateNativeControl() {
// TODO(port): create gtk text field
GtkWidget* widget = gtk_entry_new();
// TODO(brettw) hook in an observer to get text change events so we can call
// the controller.
NativeControlCreated(widget);
}
void NativeTextfieldGtk::NativeControlCreated(GtkWidget* widget) {
......@@ -80,4 +136,13 @@ void NativeTextfieldGtk::NativeControlCreated(GtkWidget* widget) {
// TODO(port): post-creation init
}
////////////////////////////////////////////////////////////////////////////////
// NativeTextfieldWrapper, public:
// static
NativeTextfieldWrapper* NativeTextfieldWrapper::CreateWrapper(
Textfield* field) {
return new NativeTextfieldGtk(field);
}
} // namespace views
......@@ -38,6 +38,8 @@ class NativeTextfieldGtk : public NativeControlGtk,
virtual void NativeControlCreated(GtkWidget* widget);
private:
Textfield* textfield_;
DISALLOW_COPY_AND_ASSIGN(NativeTextfieldGtk);
};
......
......@@ -720,7 +720,7 @@ void WidgetGtk::OnWindowPaint(GtkWidget* widget, GdkEventExpose* event) {
// view here as that is done by OnPaint.
DCHECK(transparent_);
int width, height;
gtk_window_get_size (GTK_WINDOW (widget), &width, &height);
gtk_window_get_size(GTK_WINDOW (widget), &width, &height);
cairo_t* cr = gdk_cairo_create(widget->window);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source_rgba(cr, 0, 0, 0, 0);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment