summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-30 21:19:07 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-30 21:19:07 +0000
commita136016faff78780a4776c03e252e51d2f7cae37 (patch)
treeffbc1550c4275cd674f11410e15639f71daa67cf
parent9acc48601ea4aff4e5ec977c0dd089e887ba5ffd (diff)
downloadchromium_src-a136016faff78780a4776c03e252e51d2f7cae37.zip
chromium_src-a136016faff78780a4776c03e252e51d2f7cae37.tar.gz
chromium_src-a136016faff78780a4776c03e252e51d2f7cae37.tar.bz2
Adds link to bookmark bar that when clicked imports bookmarks. I also
added support for baselines to GridLayout. BUG=4374 TEST=On a new profile make sure the bookmark bar has a link to import bookmarks, click the link and make sure you can import your bookmarks. Review URL: http://codereview.chromium.org/440029 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@33336 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd5
-rw-r--r--chrome/browser/defaults.cc2
-rw-r--r--chrome/browser/defaults.h4
-rw-r--r--chrome/browser/views/bookmark_bar_instructions_view.cc106
-rw-r--r--chrome/browser/views/bookmark_bar_instructions_view.h63
-rw-r--r--chrome/browser/views/bookmark_bar_view.cc14
-rw-r--r--chrome/browser/views/bookmark_bar_view.h14
-rw-r--r--chrome/browser/views/importer_view.cc20
-rw-r--r--chrome/browser/views/importer_view.h7
-rw-r--r--chrome/browser/views/options/content_page_view.cc2
-rwxr-xr-xchrome/chrome.gyp2
-rwxr-xr-xviews/controls/label.cc6
-rw-r--r--views/controls/label.h3
-rw-r--r--views/grid_layout.cc67
-rw-r--r--views/grid_layout.h12
-rw-r--r--views/view.cc4
-rw-r--r--views/view.h4
17 files changed, 299 insertions, 36 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index e2cec7d..7715048 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -3487,7 +3487,7 @@ Keep your key file in a safe place. You will need it to create new versions of y
/
</message>
<message name="IDS_BOOKMARKS_NO_ITEMS" desc="Text shown when the user has no bookmarks">
- For quick access, place your bookmarks here in the bookmarks bar.
+ For quick access, place your bookmarks here on the bookmarks bar.
</message>
<!-- The location for special bookmark groups -->
@@ -6168,6 +6168,9 @@ Keep your key file in a safe place. You will need it to create new versions of y
Toggle Compact Navigation Bar
</message>
</if>
+ <message name="IDS_BOOKMARK_BAR_IMPORT_LINK" desc="text shown for importing ">
+ Import bookmarks now...
+ </message>
</messages>
</release>
</grit>
diff --git a/chrome/browser/defaults.cc b/chrome/browser/defaults.cc
index 2586bc2..e0f9142 100644
--- a/chrome/browser/defaults.cc
+++ b/chrome/browser/defaults.cc
@@ -17,6 +17,7 @@ const SessionStartupPref::Type kDefaultSessionStartupType =
const int kPinnedTabWidth = 64;
const bool kCanToggleSystemTitleBar = false;
const bool kRestorePopups = true;
+const bool kShowImportOnBookmarkBar = false;
const bool kShowExitMenuItem = false;
const bool kOSSupportsOtherBrowsers = false;
@@ -46,6 +47,7 @@ const SessionStartupPref::Type kDefaultSessionStartupType =
SessionStartupPref::DEFAULT;
const int kPinnedTabWidth = 56;
const bool kRestorePopups = false;
+const bool kShowImportOnBookmarkBar = true;
const bool kShowExitMenuItem = true;
const bool kOSSupportsOtherBrowsers = true;
diff --git a/chrome/browser/defaults.h b/chrome/browser/defaults.h
index 3ba67d5..4df86b6 100644
--- a/chrome/browser/defaults.h
+++ b/chrome/browser/defaults.h
@@ -40,6 +40,10 @@ extern const bool kRestorePopups;
// Can the browser be alive without any browser windows?
extern const bool kBrowserAliveWithNoWindows;
+// Should a link be shown on the bookmark bar allowing the user to import
+// bookmarks.
+extern const bool kShowImportOnBookmarkBar;
+
// Should the exit menu be shown?
extern const bool kShowExitMenuItem;
diff --git a/chrome/browser/views/bookmark_bar_instructions_view.cc b/chrome/browser/views/bookmark_bar_instructions_view.cc
new file mode 100644
index 0000000..3b38001
--- /dev/null
+++ b/chrome/browser/views/bookmark_bar_instructions_view.cc
@@ -0,0 +1,106 @@
+// 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/views/bookmark_bar_instructions_view.h"
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "chrome/browser/browser_theme_provider.h"
+#include "chrome/browser/defaults.h"
+#include "grit/generated_resources.h"
+#include "views/controls/label.h"
+
+using views::View;
+
+// Horizontal padding, in pixels, between the link and label.
+static const int kViewPadding = 6;
+
+BookmarkBarInstructionsView::BookmarkBarInstructionsView(Delegate* delegate)
+ : delegate_(delegate),
+ instructions_(NULL),
+ import_link_(NULL),
+ baseline_(-1),
+ updated_colors_(false) {
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+
+ instructions_ = new views::Label(
+ l10n_util::GetString(IDS_BOOKMARKS_NO_ITEMS));
+ AddChildView(instructions_);
+
+ if (browser_defaults::kShowImportOnBookmarkBar) {
+ import_link_ = new views::Link(
+ l10n_util::GetString(IDS_BOOKMARK_BAR_IMPORT_LINK));
+ // We don't want the link to alter tab navigation.
+ import_link_->SetFocusable(false);
+ import_link_->SetController(this);
+ AddChildView(import_link_);
+ }
+}
+
+gfx::Size BookmarkBarInstructionsView::GetPreferredSize() {
+ int ascent = 0, descent = 0, height = 0, width = 0;
+ for (int i = 0; i < GetChildViewCount(); ++i) {
+ View* view = GetChildViewAt(i);
+ gfx::Size pref = view->GetPreferredSize();
+ int baseline = view->GetBaseline();
+ if (baseline != -1) {
+ ascent = std::max(ascent, baseline);
+ descent = std::max(descent, pref.height() - baseline);
+ } else {
+ height = std::max(pref.height(), height);
+ }
+ width += pref.width();
+ }
+ width += (GetChildViewCount() - 1) * kViewPadding;
+ if (ascent != 0)
+ height = std::max(ascent + descent, height);
+ return gfx::Size(width, height);
+}
+
+void BookmarkBarInstructionsView::Layout() {
+ int remaining_width = width();
+ int x = 0;
+ for (int i = 0; i < GetChildViewCount(); ++i) {
+ View* view = GetChildViewAt(i);
+ gfx::Size pref = view->GetPreferredSize();
+ int baseline = view->GetBaseline();
+ int y;
+ if (baseline != -1 && baseline_ != -1)
+ y = baseline_ - baseline;
+ else
+ y = (height() - pref.height()) / 2;
+ int view_width = std::min(remaining_width, pref.width());
+ view->SetBounds(x, y, view_width, pref.height());
+ x += view_width + kViewPadding;
+ remaining_width = std::max(0, width() - x);
+ }
+}
+
+void BookmarkBarInstructionsView::ThemeChanged() {
+ UpdateColors();
+}
+
+void BookmarkBarInstructionsView::ViewHierarchyChanged(bool is_add,
+ View* parent,
+ View* child) {
+ if (!updated_colors_ && is_add && GetWidget())
+ UpdateColors();
+}
+
+void BookmarkBarInstructionsView::LinkActivated(views::Link* source,
+ int event_flags) {
+ delegate_->ShowImportDialog();
+}
+
+void BookmarkBarInstructionsView::UpdateColors() {
+ // We don't always have a theme provider (ui tests, for example).
+ const ThemeProvider* theme_provider = GetThemeProvider();
+ if (!theme_provider)
+ return;
+ updated_colors_ = true;
+ SkColor text_color =
+ theme_provider->GetColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT);
+ instructions_->SetColor(text_color);
+ import_link_->SetColor(text_color);
+}
diff --git a/chrome/browser/views/bookmark_bar_instructions_view.h b/chrome/browser/views/bookmark_bar_instructions_view.h
new file mode 100644
index 0000000..4f148d5
--- /dev/null
+++ b/chrome/browser/views/bookmark_bar_instructions_view.h
@@ -0,0 +1,63 @@
+// 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_VIEWS_BOOKMARK_BAR_INSTRUCTIONS_VIEW_H_
+#define CHROME_BROWSER_VIEWS_BOOKMARK_BAR_INSTRUCTIONS_VIEW_H_
+
+#include "views/view.h"
+#include "views/controls/link.h"
+
+namespace views {
+class Label;
+class Link;
+}
+
+// BookmarkBarInstructionsView is a child of the bookmark bar that is visible
+// when the user has no bookmarks on the bookmark bar.
+// BookmarkBarInstructionsView shows a description of the bookmarks bar along
+// with a link to import bookmarks. Clicking the link results in notifying the
+// delegate.
+class BookmarkBarInstructionsView : public views::View,
+ public views::LinkController {
+ public:
+ // The delegate is notified once the user clicks on the link to import
+ // bookmarks.
+ class Delegate {
+ public:
+ virtual void ShowImportDialog() = 0;
+ };
+
+ explicit BookmarkBarInstructionsView(Delegate* delegate);
+
+ // View overrides.
+ virtual gfx::Size GetPreferredSize();
+ virtual void Layout();
+ virtual void ThemeChanged();
+ virtual void ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child);
+
+ // LinkController.
+ virtual void LinkActivated(views::Link* source, int event_flags);
+
+ private:
+ void UpdateColors();
+
+ Delegate* delegate_;
+
+ views::Label* instructions_;
+ views::Link* import_link_;
+
+ // The baseline of the child views. This is -1 if none of the views support a
+ // baseline.
+ int baseline_;
+
+ // Have the colors of the child views been updated? This is initially false
+ // and set to true once we have a valid ThemeProvider.
+ bool updated_colors_;
+
+ DISALLOW_COPY_AND_ASSIGN(BookmarkBarInstructionsView);
+};
+
+#endif // CHROME_BROWSER_VIEWS_BOOKMARK_BAR_INSTRUCTIONS_VIEW_H_
diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc
index 3b95041..6f57092d 100644
--- a/chrome/browser/views/bookmark_bar_view.cc
+++ b/chrome/browser/views/bookmark_bar_view.cc
@@ -29,6 +29,7 @@
#include "chrome/browser/views/bookmark_context_menu.h"
#include "chrome/browser/views/event_utils.h"
#include "chrome/browser/views/frame/browser_view.h"
+#include "chrome/browser/views/importer_view.h"
#include "chrome/browser/views/location_bar_view.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/page_transition_types.h"
@@ -860,6 +861,13 @@ void BookmarkBarView::GetAnchorPositionAndStartIndexForButton(
*start_index = 0;
}
+void BookmarkBarView::ShowImportDialog() {
+ views::Window::CreateChromeWindow(
+ GetWindow()->GetNativeWindow(),
+ gfx::Rect(),
+ new ImporterView(profile_, FAVORITES))->Show();
+}
+
void BookmarkBarView::Init() {
// Note that at this point we're not in a hierarchy so GetThemeProvider() will
// return NULL. When we're inserted into a hierarchy, we'll call
@@ -885,10 +893,7 @@ void BookmarkBarView::Init() {
l10n_util::GetString(IDS_ACCNAME_SEPARATOR));
AddChildView(bookmarks_separator_view_);
- instructions_ = new views::Label(
- l10n_util::GetString(IDS_BOOKMARKS_NO_ITEMS),
- rb.GetFont(ResourceBundle::BaseFont));
-
+ instructions_ = new BookmarkBarInstructionsView(this);
AddChildView(instructions_);
SetContextMenuController(this);
@@ -1536,7 +1541,6 @@ void BookmarkBarView::UpdateColors() {
return;
SkColor text_color =
theme_provider->GetColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT);
- instructions_->SetColor(text_color);
for (int i = 0; i < GetBookmarkButtonCount(); ++i)
GetBookmarkButton(i)->SetEnabledColor(text_color);
other_bookmarked_button()->SetEnabledColor(text_color);
diff --git a/chrome/browser/views/bookmark_bar_view.h b/chrome/browser/views/bookmark_bar_view.h
index 49ac37f..92efeb8 100644
--- a/chrome/browser/views/bookmark_bar_view.h
+++ b/chrome/browser/views/bookmark_bar_view.h
@@ -8,8 +8,8 @@
#include "app/slide_animation.h"
#include "chrome/browser/bookmarks/bookmark_drag_data.h"
#include "chrome/browser/bookmarks/bookmark_model_observer.h"
-#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/sync/profile_sync_service.h"
+#include "chrome/browser/views/bookmark_bar_instructions_view.h"
#include "chrome/browser/views/bookmark_menu_controller_views.h"
#include "chrome/browser/views/detachable_toolbar_view.h"
#include "chrome/common/notification_registrar.h"
@@ -22,7 +22,6 @@ class PrefService;
namespace views {
class CustomButton;
-class Label;
class MenuButton;
class MenuItemView;
class TextButton;
@@ -44,7 +43,8 @@ class BookmarkBarView : public DetachableToolbarView,
public views::ContextMenuController,
public views::DragController,
public AnimationDelegate,
- public BookmarkMenuController::Observer {
+ public BookmarkMenuController::Observer,
+ public BookmarkBarInstructionsView::Delegate {
friend class ShowFolderMenuTask;
public:
@@ -204,6 +204,9 @@ class BookmarkBarView : public DetachableToolbarView,
views::MenuItemView::AnchorPosition* anchor,
int* start_index);
+ // BookmarkBarInstructionsView::Delegate.
+ virtual void ShowImportDialog();
+
// Maximum size of buttons on the bookmark bar.
static const int kMaxButtonWidth;
@@ -463,8 +466,9 @@ class BookmarkBarView : public DetachableToolbarView,
// Visible if not all the bookmark buttons fit.
views::MenuButton* overflow_button_;
- // If no bookmarks are visible, we show some text explaining the bar.
- views::Label* instructions_;
+ // BookmarkBarInstructionsView that is visible if there are no bookmarks on
+ // the bookmark bar.
+ views::View* instructions_;
ButtonSeparatorView* bookmarks_separator_view_;
diff --git a/chrome/browser/views/importer_view.cc b/chrome/browser/views/importer_view.cc
index 5df68ef..12636c8 100644
--- a/chrome/browser/views/importer_view.cc
+++ b/chrome/browser/views/importer_view.cc
@@ -25,12 +25,12 @@ namespace browser {
void ShowImporterView(views::Widget* parent,
Profile* profile) {
views::Window::CreateChromeWindow(parent->GetNativeView(), gfx::Rect(),
- new ImporterView(profile))->Show();
+ new ImporterView(profile, ALL))->Show();
}
} // namespace browser
-ImporterView::ImporterView(Profile* profile)
+ImporterView::ImporterView(Profile* profile, int initial_state)
: import_from_label_(NULL),
profile_combobox_(NULL),
import_items_label_(NULL),
@@ -39,7 +39,8 @@ ImporterView::ImporterView(Profile* profile)
passwords_checkbox_(NULL),
search_engines_checkbox_(NULL),
profile_(profile),
- importer_host_(new ImporterHost()) {
+ importer_host_(new ImporterHost()),
+ initial_state_(initial_state) {
DCHECK(profile);
SetupControl();
}
@@ -59,14 +60,17 @@ void ImporterView::SetupControl() {
new views::Label(l10n_util::GetString(IDS_IMPORT_ITEMS_LABEL));
history_checkbox_ =
- InitCheckbox(l10n_util::GetString(IDS_IMPORT_HISTORY_CHKBOX), true);
+ InitCheckbox(l10n_util::GetString(IDS_IMPORT_HISTORY_CHKBOX),
+ (initial_state_ & HISTORY) != 0);
favorites_checkbox_ =
- InitCheckbox(l10n_util::GetString(IDS_IMPORT_FAVORITES_CHKBOX), true);
+ InitCheckbox(l10n_util::GetString(IDS_IMPORT_FAVORITES_CHKBOX),
+ (initial_state_ & FAVORITES) != 0);
passwords_checkbox_ =
- InitCheckbox(l10n_util::GetString(IDS_IMPORT_PASSWORDS_CHKBOX), true);
+ InitCheckbox(l10n_util::GetString(IDS_IMPORT_PASSWORDS_CHKBOX),
+ (initial_state_ & PASSWORDS) != 0);
search_engines_checkbox_ =
InitCheckbox(l10n_util::GetString(IDS_IMPORT_SEARCH_ENGINES_CHKBOX),
- true);
+ (initial_state_ & SEARCH_ENGINES) != 0);
// Arranges controls by using GridLayout.
const int column_set_id = 0;
@@ -154,7 +158,7 @@ int ImporterView::GetItemCount() {
DCHECK(importer_host_.get());
int item_count = importer_host_->GetAvailableProfileCount();
if (checkbox_items_.size() < static_cast<size_t>(item_count))
- checkbox_items_.resize(item_count, ALL);
+ checkbox_items_.resize(item_count, initial_state_);
return item_count;
}
diff --git a/chrome/browser/views/importer_view.h b/chrome/browser/views/importer_view.h
index 88a07cb..ac1bc20 100644
--- a/chrome/browser/views/importer_view.h
+++ b/chrome/browser/views/importer_view.h
@@ -30,7 +30,9 @@ class ImporterView : public views::View,
public views::Combobox::Listener,
public ImportObserver {
public:
- explicit ImporterView(Profile* profile);
+ // Creates a new ImporterView. |initial_state| is a bitmask of ImportItems.
+ // Each checkbox for the bits in |initial_state| is checked.
+ ImporterView(Profile* profile, int initial_state);
virtual ~ImporterView();
// Overridden from views::View.
@@ -88,6 +90,9 @@ class ImporterView : public views::View,
// selected item in the combo-box.
std::vector<uint16> checkbox_items_;
+ // Initial state of the checkbox_items_.
+ uint16 initial_state_;
+
Profile* profile_;
DISALLOW_EVIL_CONSTRUCTORS(ImporterView);
diff --git a/chrome/browser/views/options/content_page_view.cc b/chrome/browser/views/options/content_page_view.cc
index 3189919..686d6498 100644
--- a/chrome/browser/views/options/content_page_view.cc
+++ b/chrome/browser/views/options/content_page_view.cc
@@ -113,7 +113,7 @@ void ContentPageView::ButtonPressed(
views::Window::CreateChromeWindow(
GetWindow()->GetNativeWindow(),
gfx::Rect(),
- new ImporterView(profile()))->Show();
+ new ImporterView(profile(), ALL))->Show();
} else if (sender == clear_data_button_) {
views::Window::CreateChromeWindow(
GetWindow()->GetNativeWindow(),
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 3fec795..9b44c7d 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -2255,6 +2255,8 @@
'browser/views/autocomplete/autocomplete_popup_gtk.h',
'browser/views/blocked_popup_container_view_views.cc',
'browser/views/blocked_popup_container_view_views.h',
+ 'browser/views/bookmark_bar_instructions_view.cc',
+ 'browser/views/bookmark_bar_instructions_view.h',
'browser/views/bookmark_bar_view.cc',
'browser/views/bookmark_bar_view.h',
'browser/views/bookmark_bubble_view.cc',
diff --git a/views/controls/label.cc b/views/controls/label.cc
index ae98543..dff4165 100755
--- a/views/controls/label.cc
+++ b/views/controls/label.cc
@@ -99,6 +99,10 @@ gfx::Size Label::GetPreferredSize() {
return prefsize;
}
+int Label::GetBaseline() {
+ return GetInsets().top() + font_.baseline();
+}
+
int Label::ComputeMultiLineFlags() {
int flags = gfx::Canvas::MULTI_LINE;
#if !defined(OS_WIN)
@@ -439,7 +443,7 @@ gfx::Rect Label::GetTextBounds() {
gfx::Insets insets = GetInsets();
int avail_width = width() - insets.width();
// Respect the size set by the owner view
- text_size.set_width(std::min(avail_width, text_size.width()));
+ text_size.set_width(std::max(0, std::min(avail_width, text_size.width())));
int text_y = insets.top() +
(height() - text_size.height() - insets.height()) / 2;
diff --git a/views/controls/label.h b/views/controls/label.h
index 19d921d..76df4db 100644
--- a/views/controls/label.h
+++ b/views/controls/label.h
@@ -58,6 +58,9 @@ class Label : public View {
// Overridden to compute the size required to display this label
virtual gfx::Size GetPreferredSize();
+ // Overriden to return the baseline of the label.
+ virtual int GetBaseline();
+
// Return the height necessary to display this label with the provided width.
// This method is used to layout multi-line labels. It is equivalent to
// GetPreferredSize().height() if the receiver is not multi-line
diff --git a/views/grid_layout.cc b/views/grid_layout.cc
index 5b991fc..d35f42f 100644
--- a/views/grid_layout.cc
+++ b/views/grid_layout.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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.
@@ -143,7 +143,7 @@ class LayoutElement {
int location_;
int size_;
- DISALLOW_EVIL_CONSTRUCTORS(LayoutElement);
+ DISALLOW_COPY_AND_ASSIGN(LayoutElement);
};
// Column -------------------------------------------------------------
@@ -213,7 +213,7 @@ class Column : public LayoutElement {
std::vector<Column*> same_size_columns_;
Column* master_column_;
- DISALLOW_EVIL_CONSTRUCTORS(Column);
+ DISALLOW_COPY_AND_ASSIGN(Column);
};
void Column::ResetSize() {
@@ -265,12 +265,15 @@ class Row : public LayoutElement {
: LayoutElement(resize_percent),
fixed_height_(fixed_height),
height_(height),
- column_set_(column_set) {
+ column_set_(column_set),
+ max_ascent_(0),
+ max_descent_(0) {
}
virtual ~Row() {}
virtual void ResetSize() {
+ max_ascent_ = max_descent_ = 0;
SetSize(height_);
}
@@ -278,13 +281,31 @@ class Row : public LayoutElement {
return column_set_;
}
+ // Adjusts the size to accomodate the specified ascent/descent.
+ void AdjustSizeForBaseline(int ascent, int descent) {
+ max_ascent_ = std::max(ascent, max_ascent_);
+ max_descent_ = std::max(descent, max_descent_);
+ AdjustSize(max_ascent_ + max_descent_);
+ }
+
+ int max_ascent() const {
+ return max_ascent_;
+ }
+
+ int max_descent() const {
+ return max_descent_;
+ }
+
private:
const bool fixed_height_;
const int height_;
// The column set used for this row; null for padding rows.
ColumnSet* column_set_;
- DISALLOW_EVIL_CONSTRUCTORS(Row);
+ int max_ascent_;
+ int max_descent_;
+
+ DISALLOW_COPY_AND_ASSIGN(Row);
};
// ViewState -------------------------------------------------------------
@@ -308,7 +329,8 @@ struct ViewState {
pref_width(pref_width),
pref_height(pref_height),
remaining_width(0),
- remaining_height(0) {
+ remaining_height(0),
+ baseline(-1) {
DCHECK(view && start_col >= 0 && start_row >= 0 && col_span > 0 &&
row_span > 0 && start_col < column_set->num_columns() &&
(start_col + col_span) <= column_set->num_columns());
@@ -336,6 +358,10 @@ struct ViewState {
// distributed to the columns/rows the view is in.
int remaining_width;
int remaining_height;
+
+ // The baseline. Only used if the view is vertically aligned along the
+ // baseline.
+ int baseline;
};
static bool CompareByColumnSpan(const ViewState* v1, const ViewState* v2) {
@@ -716,6 +742,9 @@ void GridLayout::AddView(View* view, int col_span, int row_span,
int pref_width, int pref_height) {
DCHECK(current_row_col_set_ && col_span > 0 && row_span > 0 &&
(next_column_ + col_span) <= current_row_col_set_->num_columns());
+ // We don't support baseline alignment of views spanning rows. Please add if
+ // you need it.
+ DCHECK(v_align != BASELINE || row_span == 1);
ViewState* state =
new ViewState(current_row_col_set_, view, next_column_, current_row_,
col_span, row_span, h_align, v_align, pref_width,
@@ -732,6 +761,9 @@ static void CalculateSize(int pref_size, GridLayout::Alignment alignment,
case GridLayout::LEADING:
// Nothing to do, location already points to start.
break;
+ case GridLayout::BASELINE: // If we were asked to align on baseline, but
+ // the view doesn't have a baseline, fall back
+ // to center.
case GridLayout::CENTER:
*location += (available_size - *size) / 2;
break;
@@ -783,8 +815,12 @@ void GridLayout::Layout(View* host) {
int y = rows_[view_state->start_row]->Location() + top_inset_;
int height = LayoutElement::TotalSize(view_state->start_row,
view_state->row_span, &rows_);
- CalculateSize(view_state->pref_height, view_state->v_align,
- &y, &height);
+ if (view_state->v_align == BASELINE && view_state->baseline != -1) {
+ y += rows_[view_state->start_row]->max_ascent() - view_state->baseline;
+ height = view_state->pref_height;
+ } else {
+ CalculateSize(view_state->pref_height, view_state->v_align, &y, &height);
+ }
view->SetBounds(x, y, width, height);
}
}
@@ -830,7 +866,9 @@ void GridLayout::SizeRowsAndColumns(bool layout, int width, int height,
// Reset the height of each row.
LayoutElement::ResetSizes(&rows_);
- // Do two things:
+ // Do the following:
+ // . If the view is aligned along it's baseline, obtain the baseline from the
+ // view and update the rows ascent/descent.
// . Reset the remaining_height of each view state.
// . If the width the view will be given is different than it's pref, ask
// for the height given a particularly width.
@@ -838,6 +876,10 @@ void GridLayout::SizeRowsAndColumns(bool layout, int width, int height,
i != view_states_.end() ; ++i) {
ViewState* view_state = *i;
view_state->remaining_height = view_state->pref_height;
+
+ if (view_state->v_align == BASELINE)
+ view_state->baseline = view_state->view->GetBaseline();
+
if (view_state->h_align == FILL) {
// The view is resizable. As the pref height may vary with the width,
// ask for the pref again.
@@ -855,13 +897,18 @@ void GridLayout::SizeRowsAndColumns(bool layout, int width, int height,
}
}
- // Update the height of each row from the views.
+ // Update the height/ascent/descent of each row from the views.
std::vector<ViewState*>::iterator view_states_iterator = view_states_.begin();
for (; view_states_iterator != view_states_.end() &&
(*view_states_iterator)->row_span == 1; ++view_states_iterator) {
ViewState* view_state = *view_states_iterator;
Row* row = rows_[view_state->start_row];
row->AdjustSize(view_state->remaining_height);
+ if (view_state->baseline != -1 &&
+ view_state->baseline <= view_state->pref_height) {
+ row->AdjustSizeForBaseline(view_state->baseline,
+ view_state->pref_height - view_state->baseline);
+ }
view_state->remaining_height = 0;
}
diff --git a/views/grid_layout.h b/views/grid_layout.h
index e3e7a62..9f07242 100644
--- a/views/grid_layout.h
+++ b/views/grid_layout.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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.
@@ -81,7 +81,11 @@ class GridLayout : public LayoutManager {
TRAILING,
// The view is resized to fill the space.
- FILL
+ FILL,
+
+ // The view is aligned along the baseline. This is only valid for the
+ // vertical axis.
+ BASELINE
};
// An enumeration of the possible ways the size of a column may be obtained.
@@ -244,7 +248,7 @@ class GridLayout : public LayoutManager {
// Rows.
std::vector<Row*> rows_;
- DISALLOW_EVIL_CONSTRUCTORS(GridLayout);
+ DISALLOW_COPY_AND_ASSIGN(GridLayout);
};
// ColumnSet is used to define a set of columns. GridLayout may have any
@@ -346,7 +350,7 @@ class ColumnSet {
// for a description of what the master column is.
std::vector<Column*> master_columns_;
- DISALLOW_EVIL_CONSTRUCTORS(ColumnSet);
+ DISALLOW_COPY_AND_ASSIGN(ColumnSet);
};
} // namespace views
diff --git a/views/view.cc b/views/view.cc
index 3450e9a..f4869ec 100644
--- a/views/view.cc
+++ b/views/view.cc
@@ -143,6 +143,10 @@ gfx::Size View::GetPreferredSize() {
return gfx::Size();
}
+int View::GetBaseline() {
+ return -1;
+}
+
void View::SizeToPreferredSize() {
gfx::Size prefsize = GetPreferredSize();
if ((prefsize.width() != width()) || (prefsize.height() != height()))
diff --git a/views/view.h b/views/view.h
index 48d7b58..ae9a637 100644
--- a/views/view.h
+++ b/views/view.h
@@ -203,6 +203,10 @@ class View : public AcceleratorTarget {
// Get the size the View would like to be, if enough space were available.
virtual gfx::Size GetPreferredSize();
+ // Returns the baseline of this view, or -1 if this view has no baseline. The
+ // return value is relative to the preferred height.
+ virtual int GetBaseline();
+
// Convenience method that sizes this view to its preferred size.
void SizeToPreferredSize();