diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-30 21:19:07 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-30 21:19:07 +0000 |
commit | a136016faff78780a4776c03e252e51d2f7cae37 (patch) | |
tree | ffbc1550c4275cd674f11410e15639f71daa67cf | |
parent | 9acc48601ea4aff4e5ec977c0dd089e887ba5ffd (diff) | |
download | chromium_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.grd | 5 | ||||
-rw-r--r-- | chrome/browser/defaults.cc | 2 | ||||
-rw-r--r-- | chrome/browser/defaults.h | 4 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_bar_instructions_view.cc | 106 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_bar_instructions_view.h | 63 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_bar_view.cc | 14 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_bar_view.h | 14 | ||||
-rw-r--r-- | chrome/browser/views/importer_view.cc | 20 | ||||
-rw-r--r-- | chrome/browser/views/importer_view.h | 7 | ||||
-rw-r--r-- | chrome/browser/views/options/content_page_view.cc | 2 | ||||
-rwxr-xr-x | chrome/chrome.gyp | 2 | ||||
-rwxr-xr-x | views/controls/label.cc | 6 | ||||
-rw-r--r-- | views/controls/label.h | 3 | ||||
-rw-r--r-- | views/grid_layout.cc | 67 | ||||
-rw-r--r-- | views/grid_layout.h | 12 | ||||
-rw-r--r-- | views/view.cc | 4 | ||||
-rw-r--r-- | views/view.h | 4 |
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(); |