invert_bubble_view.cc revision 010d83a9304c5a91596085d917d248abff47903a
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 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/views/accessibility/invert_bubble_view.h" 6 7#include "base/prefs/pref_service.h" 8#include "chrome/browser/profiles/profile.h" 9#include "chrome/browser/ui/browser.h" 10#include "chrome/browser/ui/views/frame/browser_view.h" 11#include "chrome/browser/ui/views/toolbar/toolbar_view.h" 12#include "chrome/common/pref_names.h" 13#include "content/public/browser/page_navigator.h" 14#include "grit/generated_resources.h" 15#include "ui/base/l10n/l10n_util.h" 16#include "ui/base/resource/resource_bundle.h" 17#include "ui/base/window_open_disposition.h" 18#include "ui/gfx/sys_color_change_listener.h" 19#include "ui/views/bubble/bubble_delegate.h" 20#include "ui/views/controls/label.h" 21#include "ui/views/controls/link.h" 22#include "ui/views/controls/link_listener.h" 23#include "ui/views/layout/grid_layout.h" 24#include "ui/views/layout/layout_constants.h" 25#include "ui/views/widget/widget.h" 26 27namespace { 28 29const char kHighContrastExtensionUrl[] = 30 "https://chrome.google.com/webstore/detail/djcfdncoelnlbldjfhinnjlhdjlikmph"; 31const char kDarkThemeSearchUrl[] = 32 "https://chrome.google.com/webstore/search-themes/dark"; 33const char kLearnMoreUrl[] = 34 "https://groups.google.com/a/googleproductforums.com/d/topic/chrome/Xrco2HsXS-8/discussion"; 35 36class InvertBubbleView : public views::BubbleDelegateView, 37 public views::LinkListener { 38 public: 39 InvertBubbleView(Browser* browser, views::View* anchor_view); 40 virtual ~InvertBubbleView(); 41 42 private: 43 // Overridden from views::BubbleDelegateView: 44 virtual void Init() OVERRIDE; 45 46 // Overridden from views::LinkListener: 47 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; 48 49 void OpenLink(const std::string& url, int event_flags); 50 51 Browser* browser_; 52 views::Link* high_contrast_; 53 views::Link* dark_theme_; 54 views::Link* learn_more_; 55 views::Link* close_; 56 57 DISALLOW_COPY_AND_ASSIGN(InvertBubbleView); 58}; 59 60InvertBubbleView::InvertBubbleView(Browser* browser, views::View* anchor_view) 61 : views::BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT), 62 browser_(browser), 63 high_contrast_(NULL), 64 dark_theme_(NULL), 65 learn_more_(NULL), 66 close_(NULL) { 67} 68 69InvertBubbleView::~InvertBubbleView() { 70} 71 72void InvertBubbleView::Init() { 73 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 74 const gfx::FontList& original_font_list = 75 rb.GetFontList(ui::ResourceBundle::MediumFont); 76 77 views::Label* title = new views::Label( 78 base::string16(), original_font_list.Derive(2, gfx::Font::BOLD)); 79 title->SetMultiLine(true); 80 81 learn_more_ = new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE)); 82 learn_more_->SetFontList(original_font_list); 83 learn_more_->set_listener(this); 84 85 high_contrast_ = 86 new views::Link(l10n_util::GetStringUTF16(IDS_HIGH_CONTRAST_EXT)); 87 high_contrast_->SetFontList(original_font_list); 88 high_contrast_->set_listener(this); 89 90 dark_theme_ = new views::Link(l10n_util::GetStringUTF16(IDS_DARK_THEME)); 91 dark_theme_->SetFontList(original_font_list); 92 dark_theme_->set_listener(this); 93 94 close_ = new views::Link(l10n_util::GetStringUTF16(IDS_CLOSE)); 95 close_->SetFontList(original_font_list); 96 close_->set_listener(this); 97 98 views::GridLayout* layout = views::GridLayout::CreatePanel(this); 99 SetLayoutManager(layout); 100 101 views::ColumnSet* columns = layout->AddColumnSet(0); 102 for (int i = 0; i < 4; i++) { 103 columns->AddColumn(views::GridLayout::LEADING, 104 views::GridLayout::LEADING, 0, 105 views::GridLayout::USE_PREF, 0, 0); 106 } 107 108 layout->StartRow(0, 0); 109 layout->AddView(title, 4, 1); 110 layout->StartRowWithPadding(0, 0, 0, 111 views::kRelatedControlSmallVerticalSpacing); 112 layout->AddView(high_contrast_); 113 layout->AddView(dark_theme_); 114 layout->AddView(learn_more_); 115 layout->AddView(close_); 116 117 // Fit the message to the width of the links in the bubble. 118 const gfx::Size size(GetPreferredSize()); 119 title->SetText(l10n_util::GetStringUTF16(IDS_HIGH_CONTRAST_NOTIFICATION)); 120 title->SizeToFit(size.width()); 121 122 // Switching to high-contrast mode has a nasty habit of causing Chrome 123 // top-level windows to lose focus, so closing the bubble on deactivate 124 // makes it disappear before the user has even seen it. This forces the 125 // user to close it explicitly, which should be okay because it affects 126 // a small minority of users, and only once. 127 set_close_on_deactivate(false); 128} 129 130void InvertBubbleView::LinkClicked(views::Link* source, int event_flags) { 131 if (source == high_contrast_) 132 OpenLink(kHighContrastExtensionUrl, event_flags); 133 else if (source == dark_theme_) 134 OpenLink(kDarkThemeSearchUrl, event_flags); 135 else if (source == learn_more_) 136 OpenLink(kLearnMoreUrl, event_flags); 137 else if (source == close_) 138 GetWidget()->Close(); 139 else 140 NOTREACHED(); 141} 142 143void InvertBubbleView::OpenLink(const std::string& url, int event_flags) { 144 WindowOpenDisposition disposition = 145 ui::DispositionFromEventFlags(event_flags); 146 content::OpenURLParams params( 147 GURL(url), content::Referrer(), 148 disposition == CURRENT_TAB ? NEW_FOREGROUND_TAB : disposition, 149 content::PAGE_TRANSITION_LINK, false); 150 browser_->OpenURL(params); 151} 152 153} // namespace 154 155namespace chrome { 156 157void MaybeShowInvertBubbleView(BrowserView* browser_view) { 158 Browser* browser = browser_view->browser(); 159 PrefService* pref_service = browser->profile()->GetPrefs(); 160 views::View* anchor = browser_view->toolbar()->app_menu(); 161 if (gfx::IsInvertedColorScheme() && anchor && anchor->GetWidget() && 162 !pref_service->GetBoolean(prefs::kInvertNotificationShown)) { 163 pref_service->SetBoolean(prefs::kInvertNotificationShown, true); 164 InvertBubbleView* delegate = new InvertBubbleView(browser, anchor); 165 views::BubbleDelegateView::CreateBubble(delegate)->Show(); 166 } 167} 168 169} // namespace chrome 170