Chromium Code Reviews| 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/gtk/browser_titlebar.h" | 5 #include "chrome/browser/ui/gtk/browser_titlebar.h" |
| 6 | 6 |
| 7 #include <gdk/gdkkeysyms.h> | 7 #include <gdk/gdkkeysyms.h> |
| 8 #include <gtk/gtk.h> | 8 #include <gtk/gtk.h> |
| 9 | 9 |
| 10 #include <string> | 10 #include <string> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/i18n/rtl.h" | 14 #include "base/i18n/rtl.h" |
| 15 #include "base/memory/singleton.h" | 15 #include "base/memory/singleton.h" |
| 16 #include "base/string_piece.h" | 16 #include "base/string_piece.h" |
| 17 #include "base/string_tokenizer.h" | 17 #include "base/string_tokenizer.h" |
| 18 #include "base/utf_string_conversions.h" | 18 #include "base/utf_string_conversions.h" |
| 19 #include "chrome/app/chrome_command_ids.h" | 19 #include "chrome/app/chrome_command_ids.h" |
| 20 #include "chrome/browser/browser_process.h" | 20 #include "chrome/browser/browser_process.h" |
| 21 #include "chrome/browser/managed_mode.h" | |
| 21 #include "chrome/browser/prefs/pref_service.h" | 22 #include "chrome/browser/prefs/pref_service.h" |
| 23 #include "chrome/browser/profiles/avatar_menu_model.h" | |
| 22 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" |
| 23 #include "chrome/browser/profiles/profile_info_cache.h" | 25 #include "chrome/browser/profiles/profile_info_cache.h" |
| 24 #include "chrome/browser/profiles/profile_manager.h" | 26 #include "chrome/browser/profiles/profile_manager.h" |
| 25 #include "chrome/browser/ui/browser.h" | 27 #include "chrome/browser/ui/browser.h" |
| 26 #include "chrome/browser/ui/gtk/accelerators_gtk.h" | 28 #include "chrome/browser/ui/gtk/accelerators_gtk.h" |
| 27 #include "chrome/browser/ui/gtk/avatar_menu_button_gtk.h" | 29 #include "chrome/browser/ui/gtk/avatar_menu_button_gtk.h" |
| 28 #include "chrome/browser/ui/gtk/browser_window_gtk.h" | 30 #include "chrome/browser/ui/gtk/browser_window_gtk.h" |
| 29 #include "chrome/browser/ui/gtk/custom_button.h" | 31 #include "chrome/browser/ui/gtk/custom_button.h" |
| 30 #if defined(USE_GCONF) | 32 #if defined(USE_GCONF) |
| 31 #include "chrome/browser/ui/gtk/gconf_titlebar_listener.h" | 33 #include "chrome/browser/ui/gtk/gconf_titlebar_listener.h" |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 // maximized). | 107 // maximized). |
| 106 const int kMaximizedTabstripPadding = 16; | 108 const int kMaximizedTabstripPadding = 16; |
| 107 | 109 |
| 108 gboolean OnMouseMoveEvent(GtkWidget* widget, GdkEventMotion* event, | 110 gboolean OnMouseMoveEvent(GtkWidget* widget, GdkEventMotion* event, |
| 109 BrowserWindowGtk* browser_window) { | 111 BrowserWindowGtk* browser_window) { |
| 110 // Reset to the default mouse cursor. | 112 // Reset to the default mouse cursor. |
| 111 browser_window->ResetCustomFrameCursor(); | 113 browser_window->ResetCustomFrameCursor(); |
| 112 return TRUE; | 114 return TRUE; |
| 113 } | 115 } |
| 114 | 116 |
| 115 GdkPixbuf* GetOTRAvatar() { | |
| 116 static GdkPixbuf* otr_avatar = NULL; | |
| 117 if (!otr_avatar) { | |
| 118 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
| 119 otr_avatar = rb.GetNativeImageNamed( | |
| 120 IDR_OTR_ICON, ui::ResourceBundle::RTL_ENABLED).ToGdkPixbuf(); | |
| 121 } | |
| 122 return otr_avatar; | |
| 123 } | |
| 124 | |
| 125 // Converts a GdkColor to a color_utils::HSL. | 117 // Converts a GdkColor to a color_utils::HSL. |
| 126 color_utils::HSL GdkColorToHSL(const GdkColor* color) { | 118 color_utils::HSL GdkColorToHSL(const GdkColor* color) { |
| 127 color_utils::HSL hsl; | 119 color_utils::HSL hsl; |
| 128 color_utils::SkColorToHSL(SkColorSetRGB(color->red >> 8, | 120 color_utils::SkColorToHSL(SkColorSetRGB(color->red >> 8, |
| 129 color->green >> 8, | 121 color->green >> 8, |
| 130 color->blue >> 8), &hsl); | 122 color->blue >> 8), &hsl); |
| 131 return hsl; | 123 return hsl; |
| 132 } | 124 } |
| 133 | 125 |
| 134 // Returns either |one| or |two| based on which has a greater difference in | 126 // Returns either |one| or |two| based on which has a greater difference in |
| 135 // luminosity. | 127 // luminosity. |
| 136 GdkColor PickLuminosityContrastingColor(const GdkColor* base, | 128 GdkColor PickLuminosityContrastingColor(const GdkColor* base, |
| 137 const GdkColor* one, | 129 const GdkColor* one, |
| 138 const GdkColor* two) { | 130 const GdkColor* two) { |
| 139 // Convert all GdkColors to color_utils::HSLs. | 131 // Convert all GdkColors to color_utils::HSLs. |
| 140 color_utils::HSL baseHSL = GdkColorToHSL(base); | 132 color_utils::HSL baseHSL = GdkColorToHSL(base); |
| 141 color_utils::HSL oneHSL = GdkColorToHSL(one); | 133 color_utils::HSL oneHSL = GdkColorToHSL(one); |
| 142 color_utils::HSL twoHSL = GdkColorToHSL(two); | 134 color_utils::HSL twoHSL = GdkColorToHSL(two); |
| 143 double one_difference = fabs(baseHSL.l - oneHSL.l); | 135 double one_difference = fabs(baseHSL.l - oneHSL.l); |
| 144 double two_difference = fabs(baseHSL.l - twoHSL.l); | 136 double two_difference = fabs(baseHSL.l - twoHSL.l); |
| 145 | 137 |
| 146 // Be biased towards the first color presented. | 138 // Be biased towards the first color presented. |
| 147 if (two_difference > one_difference + 0.1) | 139 if (two_difference > one_difference + 0.1) |
| 148 return *two; | 140 return *two; |
| 149 else | 141 else |
| 150 return *one; | 142 return *one; |
| 151 } | 143 } |
| 152 | 144 |
| 153 // Returns true if there are multiple profiles created. This is used to | |
| 154 // determine whether to display the avatar image. | |
| 155 bool HasMultipleProfiles() { | |
| 156 ProfileInfoCache& cache = | |
| 157 g_browser_process->profile_manager()->GetProfileInfoCache(); | |
| 158 return ProfileManager::IsMultipleProfilesEnabled() && | |
| 159 cache.GetNumberOfProfiles() > 1; | |
| 160 } | |
| 161 | |
| 162 } // namespace | 145 } // namespace |
| 163 | 146 |
| 164 //////////////////////////////////////////////////////////////////////////////// | 147 //////////////////////////////////////////////////////////////////////////////// |
| 165 // PopupPageMenuModel | 148 // PopupPageMenuModel |
| 166 | 149 |
| 167 // A menu model that builds the contents of the menu shown for popups (when the | 150 // A menu model that builds the contents of the menu shown for popups (when the |
| 168 // user clicks on the favicon) and all of its submenus. | 151 // user clicks on the favicon) and all of its submenus. |
| 169 class PopupPageMenuModel : public ui::SimpleMenuModel { | 152 class PopupPageMenuModel : public ui::SimpleMenuModel { |
| 170 public: | 153 public: |
| 171 PopupPageMenuModel(ui::SimpleMenuModel::Delegate* delegate, Browser* browser); | 154 PopupPageMenuModel(ui::SimpleMenuModel::Delegate* delegate, Browser* browser); |
| (...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 796 void BrowserTitlebar::UpdateAvatar() { | 779 void BrowserTitlebar::UpdateAvatar() { |
| 797 // Remove previous state. | 780 // Remove previous state. |
| 798 gtk_util::RemoveAllChildren(titlebar_left_avatar_frame_); | 781 gtk_util::RemoveAllChildren(titlebar_left_avatar_frame_); |
| 799 gtk_util::RemoveAllChildren(titlebar_right_avatar_frame_); | 782 gtk_util::RemoveAllChildren(titlebar_right_avatar_frame_); |
| 800 | 783 |
| 801 if (!ShouldDisplayAvatar()) | 784 if (!ShouldDisplayAvatar()) |
| 802 return; | 785 return; |
| 803 | 786 |
| 804 if (!avatar_) { | 787 if (!avatar_) { |
| 805 if (IsOffTheRecord()) { | 788 if (IsOffTheRecord()) { |
| 806 avatar_ = gtk_image_new_from_pixbuf(GetOTRAvatar()); | 789 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 790 gfx::Image avatar_image = | |
| 791 rb.GetNativeImageNamed(IDR_OTR_ICON, ui::ResourceBundle::RTL_ENABLED); | |
| 792 avatar_ = gtk_image_new_from_pixbuf(avatar_image.ToGdkPixbuf()); | |
| 807 gtk_misc_set_alignment(GTK_MISC(avatar_), 0.0, 1.0); | 793 gtk_misc_set_alignment(GTK_MISC(avatar_), 0.0, 1.0); |
| 808 gtk_widget_set_size_request(avatar_, -1, 0); | 794 gtk_widget_set_size_request(avatar_, -1, 0); |
| 809 } else { | 795 } else { |
| 810 // Is using multi-profile avatar. | 796 // Use a clickable avatar. |
| 811 avatar_ = avatar_button_->widget(); | 797 avatar_ = avatar_button_->widget(); |
| 812 } | 798 } |
| 813 } | 799 } |
| 814 | 800 |
| 815 gtk_widget_show_all(avatar_); | 801 gtk_widget_show_all(avatar_); |
| 816 | 802 |
| 817 if (display_avatar_on_left_) { | 803 if (display_avatar_on_left_) { |
| 818 gtk_container_add(GTK_CONTAINER(titlebar_left_avatar_frame_), avatar_); | 804 gtk_container_add(GTK_CONTAINER(titlebar_left_avatar_frame_), avatar_); |
| 819 gtk_widget_show(titlebar_left_avatar_frame_); | 805 gtk_widget_show(titlebar_left_avatar_frame_); |
| 820 gtk_widget_hide(titlebar_right_avatar_frame_); | 806 gtk_widget_hide(titlebar_right_avatar_frame_); |
| 821 } else { | 807 } else { |
| 822 gtk_container_add(GTK_CONTAINER(titlebar_right_avatar_frame_), avatar_); | 808 gtk_container_add(GTK_CONTAINER(titlebar_right_avatar_frame_), avatar_); |
| 823 gtk_widget_show(titlebar_right_avatar_frame_); | 809 gtk_widget_show(titlebar_right_avatar_frame_); |
| 824 gtk_widget_hide(titlebar_left_avatar_frame_); | 810 gtk_widget_hide(titlebar_left_avatar_frame_); |
| 825 } | 811 } |
| 826 | 812 |
| 827 if (IsOffTheRecord()) | 813 if (IsOffTheRecord()) |
| 828 return; | 814 return; |
| 829 | 815 |
| 830 ProfileInfoCache& cache = | 816 bool is_gaia_picture = false; |
| 831 g_browser_process->profile_manager()->GetProfileInfoCache(); | 817 gfx::Image avatar; |
| 832 Profile* profile = browser_window_->browser()->profile(); | 818 if (ManagedMode::IsInManagedMode()) { |
| 833 size_t index = cache.GetIndexOfProfileWithPath(profile->GetPath()); | 819 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 834 if (index != std::string::npos) { | 820 avatar = rb.GetNativeImageNamed(IDR_MANAGED_MODE_AVATAR, |
| 835 bool is_gaia_picture = | 821 ui::ResourceBundle::RTL_ENABLED); |
| 822 } else { | |
| 823 ProfileInfoCache& cache = | |
| 824 g_browser_process->profile_manager()->GetProfileInfoCache(); | |
| 825 Profile* profile = browser_window_->browser()->profile(); | |
| 826 size_t index = cache.GetIndexOfProfileWithPath(profile->GetPath()); | |
| 827 if (index == std::string::npos) | |
| 828 return; | |
|
Evan Stade
2012/04/26 18:27:51
nit: \n
Bernhard Bauer
2012/04/27 08:59:23
Done.
| |
| 829 is_gaia_picture = | |
| 836 cache.IsUsingGAIAPictureOfProfileAtIndex(index) && | 830 cache.IsUsingGAIAPictureOfProfileAtIndex(index) && |
| 837 cache.GetGAIAPictureOfProfileAtIndex(index); | 831 cache.GetGAIAPictureOfProfileAtIndex(index); |
| 838 avatar_button_->SetIcon( | 832 avatar = cache.GetAvatarIconOfProfileAtIndex(index); |
| 839 cache.GetAvatarIconOfProfileAtIndex(index), is_gaia_picture); | 833 } |
| 834 avatar_button_->SetIcon(avatar, is_gaia_picture); | |
| 840 | 835 |
| 841 BubbleGtk::ArrowLocationGtk arrow_location = | 836 BubbleGtk::ArrowLocationGtk arrow_location = |
| 842 display_avatar_on_left_ ^ base::i18n::IsRTL() ? | 837 display_avatar_on_left_ ^ base::i18n::IsRTL() ? |
| 843 BubbleGtk::ARROW_LOCATION_TOP_LEFT : | 838 BubbleGtk::ARROW_LOCATION_TOP_LEFT : |
| 844 BubbleGtk::ARROW_LOCATION_TOP_RIGHT; | 839 BubbleGtk::ARROW_LOCATION_TOP_RIGHT; |
| 845 avatar_button_->set_menu_arrow_location(arrow_location); | 840 avatar_button_->set_menu_arrow_location(arrow_location); |
| 846 } | |
| 847 } | 841 } |
| 848 | 842 |
| 849 void BrowserTitlebar::ShowFaviconMenu(GdkEventButton* event) { | 843 void BrowserTitlebar::ShowFaviconMenu(GdkEventButton* event) { |
| 850 if (!favicon_menu_model_.get()) { | 844 if (!favicon_menu_model_.get()) { |
| 851 favicon_menu_model_.reset( | 845 favicon_menu_model_.reset( |
| 852 new PopupPageMenuModel(this, browser_window_->browser())); | 846 new PopupPageMenuModel(this, browser_window_->browser())); |
| 853 | 847 |
| 854 favicon_menu_.reset(new MenuGtk(NULL, favicon_menu_model_.get())); | 848 favicon_menu_.reset(new MenuGtk(NULL, favicon_menu_model_.get())); |
| 855 } | 849 } |
| 856 | 850 |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1086 // to NULL during that time. | 1080 // to NULL during that time. |
| 1087 if (!window_) | 1081 if (!window_) |
| 1088 return; | 1082 return; |
| 1089 | 1083 |
| 1090 window_has_focus_ = | 1084 window_has_focus_ = |
| 1091 gtk_widget_get_window(GTK_WIDGET(window_)) == active_window; | 1085 gtk_widget_get_window(GTK_WIDGET(window_)) == active_window; |
| 1092 UpdateTextColor(); | 1086 UpdateTextColor(); |
| 1093 } | 1087 } |
| 1094 | 1088 |
| 1095 bool BrowserTitlebar::ShouldDisplayAvatar() { | 1089 bool BrowserTitlebar::ShouldDisplayAvatar() { |
| 1096 return (IsOffTheRecord() || HasMultipleProfiles()) && | 1090 if (IsOffTheRecord() || ManagedMode::IsInManagedMode()) |
| 1097 browser_window_->browser()->is_type_tabbed(); | 1091 return true; |
| 1092 if (!browser_window_->browser()->is_type_tabbed()) | |
| 1093 return false; | |
|
Evan Stade
2012/04/26 18:27:51
nit: need vertical space in this function
Bernhard Bauer
2012/04/27 08:59:23
Done.
| |
| 1094 return AvatarMenuModel::ShouldShowAvatarMenu(); | |
| 1098 } | 1095 } |
| 1099 | 1096 |
| 1100 bool BrowserTitlebar::IsOffTheRecord() { | 1097 bool BrowserTitlebar::IsOffTheRecord() { |
| 1101 return browser_window_->browser()->profile()->IsOffTheRecord(); | 1098 return browser_window_->browser()->profile()->IsOffTheRecord(); |
| 1102 } | 1099 } |
| 1103 | 1100 |
| 1104 /////////////////////////////////////////////////////////////////////////////// | 1101 /////////////////////////////////////////////////////////////////////////////// |
| 1105 // BrowserTitlebar::Throbber implementation | 1102 // BrowserTitlebar::Throbber implementation |
| 1106 // TODO(tc): Handle anti-clockwise spinning when waiting for a connection. | 1103 // TODO(tc): Handle anti-clockwise spinning when waiting for a connection. |
| 1107 | 1104 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1161 ui::SimpleMenuModel::Delegate* delegate) | 1158 ui::SimpleMenuModel::Delegate* delegate) |
| 1162 : SimpleMenuModel(delegate) { | 1159 : SimpleMenuModel(delegate) { |
| 1163 AddItemWithStringId(IDC_NEW_TAB, IDS_TAB_CXMENU_NEWTAB); | 1160 AddItemWithStringId(IDC_NEW_TAB, IDS_TAB_CXMENU_NEWTAB); |
| 1164 AddItemWithStringId(IDC_RESTORE_TAB, IDS_RESTORE_TAB); | 1161 AddItemWithStringId(IDC_RESTORE_TAB, IDS_RESTORE_TAB); |
| 1165 AddSeparator(); | 1162 AddSeparator(); |
| 1166 AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER); | 1163 AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER); |
| 1167 AddSeparator(); | 1164 AddSeparator(); |
| 1168 AddCheckItemWithStringId(kShowWindowDecorationsCommand, | 1165 AddCheckItemWithStringId(kShowWindowDecorationsCommand, |
| 1169 IDS_SHOW_WINDOW_DECORATIONS_MENU); | 1166 IDS_SHOW_WINDOW_DECORATIONS_MENU); |
| 1170 } | 1167 } |
| OLD | NEW |