OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" | 5 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/i18n/rtl.h" | 11 #include "base/i18n/rtl.h" |
12 #include "base/memory/scoped_vector.h" | |
12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
13 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
14 #include "chrome/app/chrome_command_ids.h" | 15 #include "chrome/app/chrome_command_ids.h" |
15 #include "chrome/browser/alternate_nav_url_fetcher.h" | 16 #include "chrome/browser/alternate_nav_url_fetcher.h" |
16 #include "chrome/browser/command_updater.h" | 17 #include "chrome/browser/command_updater.h" |
17 #include "chrome/browser/defaults.h" | 18 #include "chrome/browser/defaults.h" |
18 #include "chrome/browser/extensions/api/omnibox/omnibox_api.h" | 19 #include "chrome/browser/extensions/api/omnibox/omnibox_api.h" |
19 #include "chrome/browser/extensions/location_bar_controller.h" | 20 #include "chrome/browser/extensions/location_bar_controller.h" |
20 #include "chrome/browser/extensions/script_bubble_controller.h" | 21 #include "chrome/browser/extensions/script_bubble_controller.h" |
21 #include "chrome/browser/extensions/tab_helper.h" | 22 #include "chrome/browser/extensions/tab_helper.h" |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
113 const int kBorderCornerRadius = 2; | 114 const int kBorderCornerRadius = 2; |
114 | 115 |
115 const int kDesktopItemPadding = 3; | 116 const int kDesktopItemPadding = 3; |
116 const int kDesktopEdgeItemPadding = kDesktopItemPadding; | 117 const int kDesktopEdgeItemPadding = kDesktopItemPadding; |
117 const int kDesktopScriptBadgeItemPadding = 9; | 118 const int kDesktopScriptBadgeItemPadding = 9; |
118 const int kDesktopScriptBadgeEdgeItemPadding = kDesktopScriptBadgeItemPadding; | 119 const int kDesktopScriptBadgeEdgeItemPadding = kDesktopScriptBadgeItemPadding; |
119 | 120 |
120 const int kTouchItemPadding = 8; | 121 const int kTouchItemPadding = 8; |
121 const int kTouchEdgeItemPadding = kTouchItemPadding; | 122 const int kTouchEdgeItemPadding = kTouchItemPadding; |
122 | 123 |
124 // Description of a decoration to be added inside the location bar, either to | |
125 // the left or to the right. | |
126 struct LocationBarDecoration { | |
Peter Kasting
2012/12/21 19:17:01
Consider defining all this code in a separate .h/.
beaudoin
2013/01/03 03:30:45
Done. (Although it's still a local struct, but now
| |
127 LocationBarDecoration(int y, | |
128 int height, | |
129 bool auto_collapse, | |
130 double max_fraction, | |
131 int edge_item_padding, | |
132 int item_padding, | |
133 int builtin_padding, | |
134 views::View* view) | |
135 : y(y), | |
136 height(height), | |
137 auto_collapse(auto_collapse), | |
138 max_fraction(max_fraction), | |
139 edge_item_padding(edge_item_padding), | |
140 item_padding(item_padding), | |
141 builtin_padding(builtin_padding), | |
142 view(view), | |
143 computed_width(0) { | |
144 DCHECK(!auto_collapse || max_fraction == 0.0); | |
145 DCHECK(max_fraction >= 0.0); | |
146 } | |
147 | |
148 // Simpler constructor for regular decorations. | |
149 LocationBarDecoration(int height, int builtin_padding, views::View* view) | |
150 : y(LocationBarView::kVerticalEdgeThickness), | |
151 height(height), | |
152 auto_collapse(false), | |
153 max_fraction(0), | |
154 edge_item_padding(LocationBarView::GetEdgeItemPadding()), | |
155 item_padding(LocationBarView::GetItemPadding()), | |
156 builtin_padding(builtin_padding), | |
157 view(view), | |
158 computed_width(0) { | |
159 DCHECK(!auto_collapse || max_fraction == 0.0); | |
160 DCHECK(max_fraction >= 0.0); | |
161 } | |
162 | |
163 // The y position of the view inside its parent. | |
164 int y; | |
165 | |
166 // If 0, will use the preferred height of the view. | |
167 int height; | |
168 | |
169 // True means that, if there is not enough available space in the location | |
170 // bar, the view will reduce its width either to its minimal width or to zero | |
171 // (making it invisible), whichever fits. If true, |max_faction| must be 0. | |
172 bool auto_collapse; | |
173 | |
174 // Used for resizeable decorations, indicates the maximum fraction of the | |
175 // location bar that can be taken by this decoration, 0 for non-resizable | |
176 // decorations. If non-zero, |auto_collapse| must be false. | |
177 double max_fraction; | |
178 | |
179 // Padding to use if the decoration is the first element next to the edge. | |
180 int edge_item_padding; | |
181 | |
182 // Padding to use if the decoration follows another decoration. | |
183 int item_padding; | |
184 | |
185 // Padding built into the decoration and that should be removed, on | |
186 // both sides, during layout. | |
187 int builtin_padding; | |
188 | |
189 views::View* view; | |
190 | |
191 // The width computed by the layout process. | |
192 double computed_width; | |
193 }; | |
194 | |
195 // First pass of decoration layout process. Pass the full width of the location | |
196 // bar in |entry_width|. This pass will adjust it to account for | |
197 // non-collapsible and non-resizable decorations. |decorations| must always be | |
198 // ordered from the edge of the location bar towards the middle. | |
199 void LayoutDecorationsPass1( | |
200 ScopedVector<LocationBarDecoration>& decorations, | |
Peter Kasting
2012/12/21 19:17:01
Instead of some non-scoped functions that each tak
beaudoin
2013/01/03 03:30:45
New LocationBarLayout class: Done.
However I did
| |
201 int item_edit_padding, | |
202 int edge_edit_padding, | |
203 int* entry_width) { | |
204 | |
205 bool first_item = true; | |
206 bool at_least_one_visible = false; | |
207 for (ScopedVector<LocationBarDecoration>::iterator it(decorations.begin()); | |
208 it != decorations.end(); ++it) { | |
209 // Autocollapsing decorations are ignored in this pass. | |
210 if (!(*it)->auto_collapse) { | |
211 at_least_one_visible = true; | |
212 *entry_width -= -2 * (*it)->builtin_padding + | |
213 (first_item ? (*it)->edge_item_padding : (*it)->item_padding); | |
214 } | |
215 first_item = false; | |
216 // Resizing decorations are ignored in this pass. | |
217 if (!(*it)->auto_collapse && (*it)->max_fraction == 0.0) { | |
218 (*it)->computed_width = (*it)->view->GetPreferredSize().width(); | |
219 *entry_width -= (*it)->computed_width; | |
220 } | |
221 } | |
222 *entry_width -= at_least_one_visible ? item_edit_padding : edge_edit_padding; | |
223 } | |
224 | |
225 // Second pass of decoration layout process. Pass the |entry_width| computed | |
226 // by the first pass. This pass will adjust it to account for resizable | |
227 // decorations. |decorations| must always be ordered from the edge of the | |
228 // location bar towards the middle. | |
229 void LayoutDecorationsPass2( | |
230 ScopedVector<LocationBarDecoration>& decorations, | |
231 int *entry_width) { | |
232 | |
233 for (ScopedVector<LocationBarDecoration>::iterator it(decorations.begin()); | |
234 it != decorations.end(); ++it) { | |
235 if ((*it)->max_fraction > 0.0) { | |
236 int max_width = static_cast<int>(*entry_width * (*it)->max_fraction); | |
237 (*it)->computed_width = std::min((*it)->view->GetPreferredSize().width(), | |
238 std::max((*it)->view->GetMinimumSize().width(), max_width)); | |
239 *entry_width -= (*it)->computed_width; | |
240 } | |
241 } | |
242 } | |
243 | |
244 // Third and final pass of decoration layout process. Pass the |bounds| | |
245 // corresponding to the entire space available in the location bar. This pass | |
246 // will update it as decorations are laid out. |available_width| measures the | |
247 // empty space within the location bar, taking the decorations and text into | |
248 // account. |decorations| must always be ordered from the edge of the location | |
249 // bar towards the middle. | |
250 void LayoutDecorationsPass3( | |
251 ScopedVector<LocationBarDecoration>& decorations, | |
252 int item_edit_padding, | |
253 int edge_edit_padding, | |
254 bool left, | |
255 gfx::Rect* bounds, | |
256 int* available_width) { | |
257 bool first_visible = true; | |
258 for (ScopedVector<LocationBarDecoration>::iterator it(decorations.begin()); | |
259 it != decorations.end(); ++it) { | |
260 // Collapse decorations if needed. | |
261 if ((*it)->auto_collapse) { | |
262 int padding = -2 * (*it)->builtin_padding + | |
263 (first_visible ? (*it)->edge_item_padding : (*it)->item_padding); | |
264 // Try preferred size, if it fails try minimum size, if it fails collapse. | |
265 (*it)->computed_width = (*it)->view->GetPreferredSize().width(); | |
266 if ((*it)->computed_width + padding > *available_width) | |
267 (*it)->computed_width = (*it)->view->GetMinimumSize().width(); | |
268 if ((*it)->computed_width + padding > *available_width) { | |
269 (*it)->computed_width = 0; | |
270 (*it)->view->SetVisible(false); | |
271 } else { | |
272 (*it)->view->SetVisible(true); | |
273 (*available_width) -= (*it)->computed_width + padding; | |
274 } | |
275 } else { | |
276 (*it)->view->SetVisible(true); | |
277 } | |
278 // Layout visible decorations. | |
279 if ((*it)->view->visible()) { | |
280 int padding = -(*it)->builtin_padding + | |
281 (first_visible ? (*it)->edge_item_padding : (*it)->item_padding); | |
282 first_visible = false; | |
283 int x; | |
284 if (left) | |
285 x = bounds->x() + padding; | |
286 else | |
287 x = bounds->x() + bounds->width() - padding - (*it)->computed_width; | |
288 int height = (*it)->height == 0 ? | |
289 (*it)->view->GetPreferredSize().height() : (*it)->height; | |
290 (*it)->view->SetBounds(x, (*it)->y, (*it)->computed_width, height); | |
291 bounds->set_width(bounds->width() - padding - (*it)->computed_width + | |
292 (*it)->builtin_padding); | |
293 if (left) { | |
294 bounds->set_x(bounds->x() + padding + (*it)->computed_width - | |
295 (*it)->builtin_padding); | |
296 } | |
297 } | |
298 } | |
299 int final_padding = first_visible ? edge_edit_padding : item_edit_padding; | |
300 bounds->set_width(bounds->width() - final_padding); | |
301 if (left) | |
302 bounds->set_x(bounds->x() + final_padding); | |
303 } | |
304 | |
123 } // namespace | 305 } // namespace |
124 | 306 |
125 // static | 307 // static |
126 const int LocationBarView::kNormalHorizontalEdgeThickness = 2; | 308 const int LocationBarView::kNormalHorizontalEdgeThickness = 2; |
127 const int LocationBarView::kVerticalEdgeThickness = 3; | 309 const int LocationBarView::kVerticalEdgeThickness = 3; |
128 const int LocationBarView::kIconInternalPadding = 2; | 310 const int LocationBarView::kIconInternalPadding = 2; |
129 const int LocationBarView::kBubbleHorizontalPadding = 1; | 311 const int LocationBarView::kBubbleHorizontalPadding = 1; |
130 const char LocationBarView::kViewClassName[] = | 312 const char LocationBarView::kViewClassName[] = |
131 "browser/ui/views/location_bar/LocationBarView"; | 313 "browser/ui/views/location_bar/LocationBarView"; |
132 | 314 |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
633 0, GetThemeProvider()->GetImageSkiaNamed(sizing_image_id)->height()); | 815 0, GetThemeProvider()->GetImageSkiaNamed(sizing_image_id)->height()); |
634 } | 816 } |
635 | 817 |
636 void LocationBarView::Layout() { | 818 void LocationBarView::Layout() { |
637 if (!location_entry_.get()) | 819 if (!location_entry_.get()) |
638 return; | 820 return; |
639 | 821 |
640 // TODO(jhawkins): Remove once crbug.com/101994 is fixed. | 822 // TODO(jhawkins): Remove once crbug.com/101994 is fixed. |
641 CHECK(location_icon_view_); | 823 CHECK(location_icon_view_); |
642 | 824 |
643 // TODO(sky): baseline layout. | |
644 int location_y = kVerticalEdgeThickness; | |
645 // In some cases (e.g. fullscreen mode) we may have 0 height. We still want | 825 // In some cases (e.g. fullscreen mode) we may have 0 height. We still want |
646 // to position our child views in this case, because other things may be | 826 // to position our child views in this case, because other things may be |
647 // positioned relative to them (e.g. the "bookmark added" bubble if the user | 827 // positioned relative to them (e.g. the "bookmark added" bubble if the user |
648 // hits ctrl-d). | 828 // hits ctrl-d). |
649 int location_height = GetInternalHeight(false); | 829 int location_height = GetInternalHeight(false); |
650 | 830 |
651 // The edge stroke is 1 px thick. In popup mode, the edges are drawn by the | 831 // The edge stroke is 1 px thick. In popup mode, the edges are drawn by the |
652 // omnibox' parent, so there isn't any edge to account for at all. | 832 // omnibox' parent, so there isn't any edge to account for at all. |
653 const int kEdgeThickness = (mode_ == NORMAL) ? | 833 const int kEdgeThickness = (mode_ == NORMAL) ? |
654 kNormalHorizontalEdgeThickness : 0; | 834 kNormalHorizontalEdgeThickness : 0; |
655 // The edit has 1 px of horizontal whitespace inside it before the text. | 835 // The edit has 1 px of horizontal whitespace inside it before the text. |
656 const int kEditInternalSpace = 1; | 836 const int kEditInternalSpace = 1; |
657 // The space between an item and the edit is the normal item space, minus the | 837 // The space between an item and the edit is the normal item space, minus the |
658 // edit's built-in space (so the apparent space will be the same). | 838 // edit's built-in space (so the apparent space will be the same). |
659 const int kItemEditPadding = GetItemPadding() - kEditInternalSpace; | 839 const int kItemEditPadding = GetItemPadding() - kEditInternalSpace; |
660 const int kEdgeEditPadding = GetEdgeItemPadding() - kEditInternalSpace; | 840 const int kEdgeEditPadding = GetEdgeItemPadding() - kEditInternalSpace; |
661 const int kBubbleVerticalPadding = (mode_ == POPUP) ? | 841 const int kBubbleVerticalPadding = (mode_ == POPUP) ? |
662 -1 : kBubbleHorizontalPadding; | 842 -1 : kBubbleHorizontalPadding; |
843 const double kMaxBubbleFraction = 0.5; | |
Peter Kasting
2012/12/21 19:17:01
Nit: Add comment about this
beaudoin
2013/01/03 03:30:45
Done.
| |
844 const int kBubbleLocationY = kVerticalEdgeThickness + kBubbleVerticalPadding; | |
663 | 845 |
664 // Start by reserving the padding at the right edge. | 846 ScopedVector<LocationBarDecoration> left_decorations; |
665 int entry_width = width() - kEdgeThickness; | 847 ScopedVector<LocationBarDecoration> right_decorations; |
666 // No need for edge item padding with action box as it fills | |
667 // all the area on the right. | |
668 if (!action_box_button_view_) | |
669 entry_width -= GetEdgeItemPadding(); | |
670 | 848 |
671 // |location_icon_view_| is visible except when |ev_bubble_view_| or | 849 selected_keyword_view_->SetVisible(false); |
672 // |selected_keyword_view_| are visible. | |
673 int location_icon_width = 0; | |
674 int ev_bubble_width = 0; | |
675 location_icon_view_->SetVisible(false); | 850 location_icon_view_->SetVisible(false); |
676 ev_bubble_view_->SetVisible(false); | 851 ev_bubble_view_->SetVisible(false); |
852 keyword_hint_view_->SetVisible(false); | |
677 | 853 |
678 const string16 keyword(location_entry_->model()->keyword()); | 854 const string16 keyword(location_entry_->model()->keyword()); |
679 const bool is_keyword_hint(location_entry_->model()->is_keyword_hint()); | 855 const bool is_keyword_hint(location_entry_->model()->is_keyword_hint()); |
680 const bool show_selected_keyword = !keyword.empty() && !is_keyword_hint; | 856 const bool show_selected_keyword = !keyword.empty() && !is_keyword_hint; |
857 const bool show_keyword_hint = !keyword.empty() && is_keyword_hint; | |
681 if (show_selected_keyword) { | 858 if (show_selected_keyword) { |
682 // Assume the keyword might be hidden. | 859 // Autocollapsible bubble decoration. |
683 entry_width -= (kEdgeThickness + kEdgeEditPadding); | 860 left_decorations.push_back(new LocationBarDecoration( |
684 } else if (model_->GetSecurityLevel() == ToolbarModel::EV_SECURE) { | 861 kBubbleLocationY, 0, true, 0, kBubbleHorizontalPadding, |
685 ev_bubble_view_->SetVisible(true); | 862 GetItemPadding(), 0, selected_keyword_view_)); |
686 ev_bubble_view_->SetLabel(model_->GetEVCertName()); | |
687 ev_bubble_width = ev_bubble_view_->GetPreferredSize().width(); | |
688 // We'll adjust this width and take it out of |entry_width| below. | |
689 } else { | |
690 location_icon_view_->SetVisible(true); | |
691 location_icon_width = location_icon_view_->GetPreferredSize().width(); | |
692 entry_width -= (kEdgeThickness + GetEdgeItemPadding() + | |
693 location_icon_width + kItemEditPadding); | |
694 } | |
695 | |
696 if (action_box_button_view_) { | |
697 action_box_button_view_->SetVisible(true); | |
698 entry_width -= action_box_button_view_->width() + GetItemPadding(); | |
699 } | |
700 if (star_view_ && star_view_->visible()) | |
701 entry_width -= star_view_->GetPreferredSize().width() + GetItemPadding(); | |
702 | |
703 if (script_bubble_icon_view_ && script_bubble_icon_view_->visible()) { | |
704 entry_width -= script_bubble_icon_view_->GetPreferredSize().width() + | |
705 GetItemPadding(); | |
706 } | |
707 | |
708 if (open_pdf_in_reader_view_ && open_pdf_in_reader_view_->visible()) { | |
709 entry_width -= open_pdf_in_reader_view_->GetPreferredSize().width() + | |
710 GetItemPadding(); | |
711 } | |
712 for (PageActionViews::const_iterator i(page_action_views_.begin()); | |
713 i != page_action_views_.end(); ++i) { | |
714 if ((*i)->visible()) | |
715 entry_width -= ((*i)->GetPreferredSize().width() + GetItemPadding()); | |
716 } | |
717 if (zoom_view_->visible()) | |
718 entry_width -= zoom_view_->GetPreferredSize().width() + GetItemPadding(); | |
719 for (ContentSettingViews::const_iterator i(content_setting_views_.begin()); | |
720 i != content_setting_views_.end(); ++i) { | |
721 if ((*i)->visible()) | |
722 entry_width -= ((*i)->GetPreferredSize().width() + GetItemPadding()); | |
723 } | |
724 if (web_intents_button_view_->visible()) { | |
725 entry_width -= web_intents_button_view_->GetPreferredSize().width() + | |
726 GetItemPadding(); | |
727 } | |
728 // The gap between the edit and whatever is to its right is shortened. | |
729 entry_width += kEditInternalSpace; | |
730 | |
731 // Size the EV bubble after taking star/page actions/content settings out of | |
732 // |entry_width| so we won't take too much space. | |
733 if (ev_bubble_width) { | |
734 // Try to elide the bubble to be no larger than half the total available | |
735 // space, but never elide it any smaller than 150 px. | |
736 static const int kMinElidedBubbleWidth = 150; | |
737 static const double kMaxBubbleFraction = 0.5; | |
738 const int total_padding = | |
739 kEdgeThickness + kBubbleHorizontalPadding + kItemEditPadding; | |
740 ev_bubble_width = std::min(ev_bubble_width, std::max(kMinElidedBubbleWidth, | |
741 static_cast<int>((entry_width - total_padding) * kMaxBubbleFraction))); | |
742 entry_width -= (total_padding + ev_bubble_width); | |
743 } | |
744 | |
745 const int max_edit_width = location_entry_->GetMaxEditWidth(entry_width); | |
746 if (max_edit_width < 0) | |
747 return; | |
748 | |
749 const bool show_keyword_hint = !keyword.empty() && is_keyword_hint; | |
750 selected_keyword_view_->SetVisible(show_selected_keyword); | |
751 keyword_hint_view_->SetVisible(show_keyword_hint); | |
752 if (show_selected_keyword) { | |
753 if (selected_keyword_view_->keyword() != keyword) { | 863 if (selected_keyword_view_->keyword() != keyword) { |
754 selected_keyword_view_->SetKeyword(keyword); | 864 selected_keyword_view_->SetKeyword(keyword); |
755 const TemplateURL* template_url = | 865 const TemplateURL* template_url = |
756 TemplateURLServiceFactory::GetForProfile(profile_)-> | 866 TemplateURLServiceFactory::GetForProfile(profile_)-> |
757 GetTemplateURLForKeyword(keyword); | 867 GetTemplateURLForKeyword(keyword); |
758 if (template_url && template_url->IsExtensionKeyword()) { | 868 if (template_url && template_url->IsExtensionKeyword()) { |
759 gfx::Image image = extensions::OmniboxAPI::Get(profile_)-> | 869 gfx::Image image = extensions::OmniboxAPI::Get(profile_)-> |
760 GetOmniboxIcon(template_url->GetExtensionId()); | 870 GetOmniboxIcon(template_url->GetExtensionId()); |
761 selected_keyword_view_->SetImage(image.AsImageSkia()); | 871 selected_keyword_view_->SetImage(image.AsImageSkia()); |
762 selected_keyword_view_->set_is_extension_icon(true); | 872 selected_keyword_view_->set_is_extension_icon(true); |
763 } else { | 873 } else { |
764 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 874 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
765 selected_keyword_view_->SetImage( | 875 selected_keyword_view_->SetImage( |
766 *rb.GetImageSkiaNamed(IDR_OMNIBOX_SEARCH)); | 876 *rb.GetImageSkiaNamed(IDR_OMNIBOX_SEARCH)); |
767 selected_keyword_view_->set_is_extension_icon(false); | 877 selected_keyword_view_->set_is_extension_icon(false); |
768 } | 878 } |
769 } | 879 } |
770 } else if (show_keyword_hint) { | 880 } else if (model_->GetSecurityLevel() == ToolbarModel::EV_SECURE) { |
881 ev_bubble_view_->SetLabel(model_->GetEVCertName()); | |
882 // Bubble decoration that can use a maximum fraction of the width. | |
883 left_decorations.push_back(new LocationBarDecoration( | |
884 kBubbleLocationY, 0, false, kMaxBubbleFraction, | |
885 kBubbleHorizontalPadding, GetItemPadding(), 0, ev_bubble_view_)); | |
886 } else { | |
887 left_decorations.push_back(new LocationBarDecoration( | |
888 location_height, location_icon_view_->GetBuiltInHorizontalPadding(), | |
889 location_icon_view_)); | |
890 } | |
891 | |
892 if (action_box_button_view_) { | |
893 right_decorations.push_back(new LocationBarDecoration( | |
894 kVerticalEdgeThickness - ActionBoxButtonView::kBorderOverlap, 0, false, | |
895 0, 0, 0, 0, action_box_button_view_)); | |
896 } | |
897 if (star_view_ && star_view_->visible()) { | |
898 right_decorations.push_back(new LocationBarDecoration( | |
899 location_height, star_view_->GetBuiltInHorizontalPadding(), | |
900 star_view_)); | |
901 } | |
902 if (script_bubble_icon_view_ && script_bubble_icon_view_->visible()) { | |
903 right_decorations.push_back(new LocationBarDecoration( | |
904 location_height, | |
905 script_bubble_icon_view_->GetBuiltInHorizontalPadding(), | |
906 script_bubble_icon_view_)); | |
907 } | |
908 if (open_pdf_in_reader_view_ && open_pdf_in_reader_view_->visible()) { | |
909 right_decorations.push_back(new LocationBarDecoration( | |
910 location_height, | |
911 open_pdf_in_reader_view_->GetBuiltInHorizontalPadding(), | |
912 open_pdf_in_reader_view_)); | |
913 } | |
914 for (PageActionViews::const_iterator i(page_action_views_.begin()); | |
915 i != page_action_views_.end(); ++i) { | |
916 if ((*i)->visible()) { | |
917 right_decorations.push_back(new LocationBarDecoration( | |
918 location_height, (*i)->GetBuiltInHorizontalPadding(), (*i))); | |
919 } | |
920 } | |
921 if (zoom_view_->visible()) | |
922 right_decorations.push_back(new LocationBarDecoration(location_height, 0, | |
923 zoom_view_)); | |
924 for (ContentSettingViews::const_reverse_iterator | |
925 i(content_setting_views_.rbegin()); i != content_setting_views_.rend(); | |
926 ++i) { | |
927 if ((*i)->visible()) { | |
928 // Bubble decoration. | |
Peter Kasting
2012/12/21 19:17:01
Comment is too brief. Why are these "bubble decor
beaudoin
2013/01/03 03:30:45
Actually, comment is not really needed, dropped it
| |
929 right_decorations.push_back(new LocationBarDecoration( | |
930 kBubbleLocationY, 0, false, 0, GetEdgeItemPadding(), GetItemPadding(), | |
931 (*i)->GetBuiltInHorizontalPadding(), (*i))); | |
932 } | |
933 } | |
934 if (web_intents_button_view_->visible()) { | |
935 right_decorations.push_back(new LocationBarDecoration( | |
936 kBubbleLocationY, 0, false, 0, GetEdgeItemPadding(), GetItemPadding(), | |
937 web_intents_button_view_->GetBuiltInHorizontalPadding(), | |
938 web_intents_button_view_)); | |
939 } | |
940 if (show_keyword_hint) { | |
941 // Collapsible regular decoration | |
Peter Kasting
2012/12/21 19:17:01
Nit: Trailing period. Comment is also pretty brie
beaudoin
2013/01/03 03:30:45
Comment dropped.
| |
942 right_decorations.push_back(new LocationBarDecoration( | |
943 kVerticalEdgeThickness, 0, true, 0, GetEdgeItemPadding(), | |
944 GetItemPadding(), 0, keyword_hint_view_)); | |
771 if (keyword_hint_view_->keyword() != keyword) | 945 if (keyword_hint_view_->keyword() != keyword) |
772 keyword_hint_view_->SetKeyword(keyword); | 946 keyword_hint_view_->SetKeyword(keyword); |
773 } | 947 } |
774 | 948 |
775 // Lay out items to the right of the edit field. | 949 // Perform layout. |
776 int offset = width() - kEdgeThickness; | 950 int full_width = width() - 2 * kEdgeThickness; |
777 if (action_box_button_view_) { | 951 int entry_width = full_width; // Starts with full width and update it. |
Peter Kasting
2012/12/21 19:17:01
Nit: Grammar. Comment doesn't add much anyway.
beaudoin
2013/01/03 03:30:45
Comment dropped.
| |
778 offset -= action_box_button_view_->width(); | 952 LayoutDecorationsPass1(left_decorations, kItemEditPadding, kEdgeEditPadding, |
779 action_box_button_view_->SetPosition( | 953 &entry_width); |
780 gfx::Point(offset, | 954 LayoutDecorationsPass1(right_decorations, kItemEditPadding, kEdgeEditPadding, |
781 kVerticalEdgeThickness - | 955 &entry_width); |
782 ActionBoxButtonView::kBorderOverlap)); | 956 LayoutDecorationsPass2(left_decorations, &entry_width); |
783 offset -= GetItemPadding(); | 957 LayoutDecorationsPass2(right_decorations, &entry_width); |
784 } else { | |
785 offset -= GetEdgeItemPadding(); | |
786 } | |
787 | 958 |
788 if (star_view_ && star_view_->visible()) { | 959 int available_width = entry_width - location_entry_->TextWidth(); |
789 offset += star_view_->GetBuiltInHorizontalPadding(); | 960 // The bounds must be wide enough for all the decorations to fit. |
790 int star_width = star_view_->GetPreferredSize().width(); | 961 gfx::Rect location_bounds(kEdgeThickness, kVerticalEdgeThickness, |
791 offset -= star_width; | 962 std::max(full_width, full_width - entry_width), |
792 star_view_->SetBounds(offset, location_y, star_width, location_height); | 963 location_height); |
793 offset -= GetItemPadding() - star_view_->GetBuiltInHorizontalPadding(); | 964 LayoutDecorationsPass3(left_decorations, kItemEditPadding, kEdgeEditPadding, |
794 } | 965 true, &location_bounds, &available_width); |
795 | 966 LayoutDecorationsPass3(right_decorations, kItemEditPadding, kEdgeEditPadding, |
796 if (script_bubble_icon_view_ && script_bubble_icon_view_->visible()) { | 967 false, &location_bounds, &available_width); |
797 offset += script_bubble_icon_view_->GetBuiltInHorizontalPadding(); | |
798 int width = script_bubble_icon_view_->GetPreferredSize().width(); | |
799 offset -= width; | |
800 script_bubble_icon_view_->SetBounds( | |
801 offset, location_y, width, location_height); | |
802 offset -= GetItemPadding() - | |
803 script_bubble_icon_view_->GetBuiltInHorizontalPadding(); | |
804 } | |
805 | |
806 if (open_pdf_in_reader_view_ && open_pdf_in_reader_view_->visible()) { | |
807 offset += open_pdf_in_reader_view_->GetBuiltInHorizontalPadding(); | |
808 int icon_width = open_pdf_in_reader_view_->GetPreferredSize().width(); | |
809 offset -= icon_width; | |
810 open_pdf_in_reader_view_->SetBounds(offset, location_y, | |
811 icon_width, location_height); | |
812 offset -= GetItemPadding() - | |
813 open_pdf_in_reader_view_->GetBuiltInHorizontalPadding(); | |
814 } | |
815 | |
816 for (PageActionViews::const_iterator i(page_action_views_.begin()); | |
817 i != page_action_views_.end(); ++i) { | |
818 if ((*i)->visible()) { | |
819 offset += (*i)->GetBuiltInHorizontalPadding(); | |
820 int page_action_width = (*i)->GetPreferredSize().width(); | |
821 offset -= page_action_width; | |
822 (*i)->SetBounds(offset, location_y, page_action_width, location_height); | |
823 offset -= GetItemPadding() - (*i)->GetBuiltInHorizontalPadding(); | |
824 } | |
825 } | |
826 | |
827 if (zoom_view_->visible()) { | |
828 int zoom_width = zoom_view_->GetPreferredSize().width(); | |
829 offset -= zoom_width; | |
830 zoom_view_->SetBounds(offset, location_y, zoom_width, location_height); | |
831 offset -= GetItemPadding(); | |
832 } | |
833 | |
834 // We use a reverse_iterator here because we're laying out the views from | |
835 // right to left but in the vector they're ordered left to right. | |
836 for (ContentSettingViews::const_reverse_iterator | |
837 i(content_setting_views_.rbegin()); i != content_setting_views_.rend(); | |
838 ++i) { | |
839 if ((*i)->visible()) { | |
840 offset += (*i)->GetBuiltInHorizontalPadding(); | |
841 int content_blocked_width = (*i)->GetPreferredSize().width(); | |
842 offset -= content_blocked_width; | |
843 (*i)->SetBounds(offset, location_y + kBubbleVerticalPadding, | |
844 content_blocked_width, (*i)->GetPreferredSize().height()); | |
845 offset -= GetItemPadding() - (*i)->GetBuiltInHorizontalPadding(); | |
846 } | |
847 } | |
848 | |
849 // Now the web intents button. | |
850 if (web_intents_button_view_->visible()) { | |
851 offset += web_intents_button_view_->GetBuiltInHorizontalPadding(); | |
852 int width = web_intents_button_view_->GetPreferredSize().width(); | |
853 offset -= width; | |
854 web_intents_button_view_->SetBounds( | |
855 offset, location_y + kBubbleVerticalPadding, width, | |
856 web_intents_button_view_->GetPreferredSize().height()); | |
857 offset -= GetItemPadding() - | |
858 web_intents_button_view_->GetBuiltInHorizontalPadding(); | |
859 } | |
860 | |
861 // Now lay out items to the left of the edit field. | |
862 if (location_icon_view_->visible()) { | |
863 location_icon_view_->SetBounds( | |
864 kEdgeThickness + GetEdgeItemPadding() - | |
865 location_icon_view_->GetBuiltInHorizontalPadding(), | |
866 location_y, location_icon_width, location_height); | |
867 offset = location_icon_view_->bounds().right() + kItemEditPadding - | |
868 location_icon_view_->GetBuiltInHorizontalPadding(); | |
869 } else if (ev_bubble_view_->visible()) { | |
870 ev_bubble_view_->SetBounds(kEdgeThickness + kBubbleHorizontalPadding, | |
871 location_y + kBubbleVerticalPadding, ev_bubble_width, | |
872 ev_bubble_view_->GetPreferredSize().height()); | |
873 offset = ev_bubble_view_->bounds().right() + kItemEditPadding; | |
874 } else { | |
875 offset = kEdgeThickness + | |
876 (show_selected_keyword ? kBubbleHorizontalPadding : kEdgeEditPadding); | |
877 } | |
878 | |
879 // Now lay out the edit field and views that autocollapse to give it more | |
880 // room. | |
881 gfx::Rect location_bounds(offset, location_y, entry_width, location_height); | |
882 if (show_selected_keyword) { | |
883 selected_keyword_view_->SetBounds(0, location_y + kBubbleVerticalPadding, | |
884 0, selected_keyword_view_->GetPreferredSize().height()); | |
885 LayoutView(selected_keyword_view_, kItemEditPadding, | |
886 AvailableWidth(max_edit_width), true, &location_bounds); | |
887 location_bounds.set_x(selected_keyword_view_->visible() ? | |
888 (offset + selected_keyword_view_->width() + kItemEditPadding) : | |
889 (kEdgeThickness + kEdgeEditPadding)); | |
890 } else if (show_keyword_hint) { | |
891 keyword_hint_view_->SetBounds(0, location_y, 0, location_height); | |
892 // Tricky: |entry_width| has already been enlarged by |kEditInternalSpace|. | |
893 // But if we add a trailing view, it needs to have that enlargement be to | |
894 // its left. So we undo the enlargement, then include it in the padding for | |
895 // the added view. | |
896 location_bounds.Inset(0, 0, kEditInternalSpace, 0); | |
897 LayoutView(keyword_hint_view_, kItemEditPadding, | |
898 AvailableWidth(max_edit_width), false, &location_bounds); | |
899 if (!keyword_hint_view_->visible()) { | |
900 // Put back the enlargement that we undid above. | |
901 location_bounds.Inset(0, 0, -kEditInternalSpace, 0); | |
902 } | |
903 } | |
904 | 968 |
905 // Layout out the suggested text view right aligned to the location | 969 // Layout out the suggested text view right aligned to the location |
906 // entry. Only show the suggested text if we can fit the text from one | 970 // entry. Only show the suggested text if we can fit the text from one |
907 // character before the end of the selection to the end of the text and the | 971 // character before the end of the selection to the end of the text and the |
908 // suggested text. If we can't it means either the suggested text is too big, | 972 // suggested text. If we can't it means either the suggested text is too big, |
909 // or the user has scrolled. | 973 // or the user has scrolled. |
910 | 974 |
911 // TODO(sky): We could potentially combine this with the previous step to | 975 // TODO(sky): We could potentially adjust this to take into account suggested |
912 // force using minimum size if necessary, but currently the chance of showing | 976 // text to force using minimum size if necessary, but currently the chance of |
913 // keyword hints and suggested text is minimal and we're not confident this | 977 // showing keyword hints and suggested text is minimal and we're not confident |
914 // is the right approach for suggested text. | 978 // this is the right approach for suggested text. |
915 if (suggested_text_view_) { | 979 if (suggested_text_view_) { |
916 // TODO(sky): need to layout when the user changes caret position. | 980 // TODO(sky): need to layout when the user changes caret position. |
917 int suggested_text_width = | 981 int suggested_text_width = |
918 suggested_text_view_->GetPreferredSize().width(); | 982 suggested_text_view_->GetPreferredSize().width(); |
919 int vis_text_width = location_entry_->WidthOfTextAfterCursor(); | 983 int vis_text_width = location_entry_->WidthOfTextAfterCursor(); |
920 if (vis_text_width + suggested_text_width > entry_width) { | 984 if (suggested_text_width > available_width) { |
921 // Hide the suggested text if the user has scrolled or we can't fit all | 985 // Hide the suggested text if the user has scrolled or we can't fit all |
922 // the suggested text. | 986 // the suggested text. |
923 suggested_text_view_->SetBounds(0, 0, 0, 0); | 987 suggested_text_view_->SetBounds(0, 0, 0, 0); |
924 } else { | 988 } else { |
925 int location_needed_width = location_entry_->TextWidth(); | 989 int location_needed_width = location_entry_->TextWidth(); |
926 #if defined(USE_AURA) | 990 #if defined(USE_AURA) |
927 // TODO(sky): fix this. The +1 comes from the width of the cursor, without | 991 // TODO(sky): fix this. The +1 comes from the width of the cursor, without |
928 // the text ends up shifting to the left. | 992 // the text ends up shifting to the left. |
929 location_needed_width++; | 993 location_needed_width++; |
930 #endif | 994 #endif |
931 location_bounds.set_width(std::min(location_needed_width, | 995 location_bounds.set_width(std::min(location_needed_width, |
Peter Kasting
2012/12/21 19:17:01
Nit: Put this on next line so the args line up
beaudoin
2013/01/03 03:30:45
Done.
| |
932 entry_width - suggested_text_width)); | 996 location_bounds.width() - suggested_text_width)); |
933 // TODO(sky): figure out why this needs the -1. | 997 // TODO(sky): figure out why this needs the -1. |
934 suggested_text_view_->SetBounds(location_bounds.right() - 1, | 998 suggested_text_view_->SetBounds(location_bounds.right() - 1, |
935 location_bounds.y(), | 999 location_bounds.y(), |
936 suggested_text_width, | 1000 suggested_text_width, |
937 location_bounds.height()); | 1001 location_bounds.height()); |
938 } | 1002 } |
939 } | 1003 } |
940 | 1004 |
941 location_entry_view_->SetBoundsRect(location_bounds); | 1005 location_entry_view_->SetBoundsRect(location_bounds); |
942 } | 1006 } |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1123 } | 1187 } |
1124 | 1188 |
1125 InstantController* LocationBarView::GetInstant() { | 1189 InstantController* LocationBarView::GetInstant() { |
1126 return delegate_->GetInstant(); | 1190 return delegate_->GetInstant(); |
1127 } | 1191 } |
1128 | 1192 |
1129 WebContents* LocationBarView::GetWebContents() const { | 1193 WebContents* LocationBarView::GetWebContents() const { |
1130 return delegate_->GetWebContents(); | 1194 return delegate_->GetWebContents(); |
1131 } | 1195 } |
1132 | 1196 |
1133 int LocationBarView::AvailableWidth(int location_bar_width) { | |
1134 return location_bar_width - location_entry_->TextWidth(); | |
1135 } | |
1136 | |
1137 void LocationBarView::LayoutView(views::View* view, | |
1138 int padding, | |
1139 int available_width, | |
1140 bool leading, | |
1141 gfx::Rect* bounds) { | |
1142 DCHECK(view && bounds); | |
1143 gfx::Size view_size = view->GetPreferredSize(); | |
1144 if ((view_size.width() + padding) > available_width) | |
1145 view_size = view->GetMinimumSize(); | |
1146 int desired_width = view_size.width() + padding; | |
1147 view->SetVisible(desired_width < bounds->width()); | |
1148 if (view->visible()) { | |
1149 view->SetBounds( | |
1150 leading ? bounds->x() : (bounds->right() - view_size.width()), | |
1151 view->y(), view_size.width(), view->height()); | |
1152 bounds->set_width(bounds->width() - desired_width); | |
1153 } | |
1154 } | |
1155 | |
1156 void LocationBarView::RefreshContentSettingViews() { | 1197 void LocationBarView::RefreshContentSettingViews() { |
1157 for (ContentSettingViews::const_iterator i(content_setting_views_.begin()); | 1198 for (ContentSettingViews::const_iterator i(content_setting_views_.begin()); |
1158 i != content_setting_views_.end(); ++i) { | 1199 i != content_setting_views_.end(); ++i) { |
1159 (*i)->Update(model_->GetInputInProgress() ? NULL : GetWebContents()); | 1200 (*i)->Update(model_->GetInputInProgress() ? NULL : GetWebContents()); |
1160 } | 1201 } |
1161 } | 1202 } |
1162 | 1203 |
1163 void LocationBarView::DeletePageActionViews() { | 1204 void LocationBarView::DeletePageActionViews() { |
1164 for (PageActionViews::const_iterator i(page_action_views_.begin()); | 1205 for (PageActionViews::const_iterator i(page_action_views_.begin()); |
1165 i != page_action_views_.end(); ++i) | 1206 i != page_action_views_.end(); ++i) |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1575 int LocationBarView::GetInternalHeight(bool use_preferred_size) { | 1616 int LocationBarView::GetInternalHeight(bool use_preferred_size) { |
1576 int total_height = | 1617 int total_height = |
1577 use_preferred_size ? GetPreferredSize().height() : height(); | 1618 use_preferred_size ? GetPreferredSize().height() : height(); |
1578 return std::max(total_height - (kVerticalEdgeThickness * 2), 0); | 1619 return std::max(total_height - (kVerticalEdgeThickness * 2), 0); |
1579 } | 1620 } |
1580 | 1621 |
1581 bool LocationBarView::HasValidSuggestText() const { | 1622 bool LocationBarView::HasValidSuggestText() const { |
1582 return suggested_text_view_ && !suggested_text_view_->size().IsEmpty() && | 1623 return suggested_text_view_ && !suggested_text_view_->size().IsEmpty() && |
1583 !suggested_text_view_->text().empty(); | 1624 !suggested_text_view_->text().empty(); |
1584 } | 1625 } |
OLD | NEW |