blob: 556192a59d46e582844746148faeee3b63896cbd [file] [log] [blame]
// Copyright (c) 2012 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/ui/views/accessibility/invert_bubble_view.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "content/public/browser/page_navigator.h"
#include "grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/window_open_disposition.h"
#include "ui/gfx/sys_color_change_listener.h"
#include "ui/views/bubble/bubble_delegate.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/link.h"
#include "ui/views/controls/link_listener.h"
#include "ui/views/layout/grid_layout.h"
#include "ui/views/layout/layout_constants.h"
#include "ui/views/widget/widget.h"
namespace {
const char kHighContrastExtensionUrl[] =
"https://chrome.google.com/webstore/detail/djcfdncoelnlbldjfhinnjlhdjlikmph";
const char kDarkThemeSearchUrl[] =
"https://chrome.google.com/webstore/search-themes/dark";
const char kLearnMoreUrl[] =
"https://groups.google.com/a/googleproductforums.com/d/topic/chrome/Xrco2HsXS-8/discussion";
class InvertBubbleView : public views::BubbleDelegateView,
public views::LinkListener {
public:
InvertBubbleView(Browser* browser, views::View* anchor_view);
virtual ~InvertBubbleView();
private:
// Overridden from views::BubbleDelegateView:
virtual void Init() override;
// Overridden from views::LinkListener:
virtual void LinkClicked(views::Link* source, int event_flags) override;
void OpenLink(const std::string& url, int event_flags);
Browser* browser_;
views::Link* high_contrast_;
views::Link* dark_theme_;
views::Link* learn_more_;
views::Link* close_;
DISALLOW_COPY_AND_ASSIGN(InvertBubbleView);
};
InvertBubbleView::InvertBubbleView(Browser* browser, views::View* anchor_view)
: views::BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT),
browser_(browser),
high_contrast_(NULL),
dark_theme_(NULL),
learn_more_(NULL),
close_(NULL) {
}
InvertBubbleView::~InvertBubbleView() {
}
void InvertBubbleView::Init() {
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
const gfx::FontList& original_font_list =
rb.GetFontList(ui::ResourceBundle::MediumFont);
views::Label* title = new views::Label(
base::string16(), original_font_list.Derive(2, gfx::Font::BOLD));
title->SetMultiLine(true);
learn_more_ = new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
learn_more_->SetFontList(original_font_list);
learn_more_->set_listener(this);
high_contrast_ =
new views::Link(l10n_util::GetStringUTF16(IDS_HIGH_CONTRAST_EXT));
high_contrast_->SetFontList(original_font_list);
high_contrast_->set_listener(this);
dark_theme_ = new views::Link(l10n_util::GetStringUTF16(IDS_DARK_THEME));
dark_theme_->SetFontList(original_font_list);
dark_theme_->set_listener(this);
close_ = new views::Link(l10n_util::GetStringUTF16(IDS_CLOSE));
close_->SetFontList(original_font_list);
close_->set_listener(this);
views::GridLayout* layout = views::GridLayout::CreatePanel(this);
SetLayoutManager(layout);
views::ColumnSet* columns = layout->AddColumnSet(0);
for (int i = 0; i < 4; i++) {
columns->AddColumn(views::GridLayout::LEADING,
views::GridLayout::LEADING, 0,
views::GridLayout::USE_PREF, 0, 0);
}
layout->StartRow(0, 0);
layout->AddView(title, 4, 1);
layout->StartRowWithPadding(0, 0, 0,
views::kRelatedControlSmallVerticalSpacing);
layout->AddView(high_contrast_);
layout->AddView(dark_theme_);
layout->AddView(learn_more_);
layout->AddView(close_);
// Fit the message to the width of the links in the bubble.
const gfx::Size size(GetPreferredSize());
title->SetText(l10n_util::GetStringUTF16(IDS_HIGH_CONTRAST_NOTIFICATION));
title->SizeToFit(size.width());
// Switching to high-contrast mode has a nasty habit of causing Chrome
// top-level windows to lose focus, so closing the bubble on deactivate
// makes it disappear before the user has even seen it. This forces the
// user to close it explicitly, which should be okay because it affects
// a small minority of users, and only once.
set_close_on_deactivate(false);
}
void InvertBubbleView::LinkClicked(views::Link* source, int event_flags) {
if (source == high_contrast_)
OpenLink(kHighContrastExtensionUrl, event_flags);
else if (source == dark_theme_)
OpenLink(kDarkThemeSearchUrl, event_flags);
else if (source == learn_more_)
OpenLink(kLearnMoreUrl, event_flags);
else if (source == close_)
GetWidget()->Close();
else
NOTREACHED();
}
void InvertBubbleView::OpenLink(const std::string& url, int event_flags) {
WindowOpenDisposition disposition =
ui::DispositionFromEventFlags(event_flags);
content::OpenURLParams params(
GURL(url), content::Referrer(),
disposition == CURRENT_TAB ? NEW_FOREGROUND_TAB : disposition,
ui::PAGE_TRANSITION_LINK, false);
browser_->OpenURL(params);
}
} // namespace
namespace chrome {
void MaybeShowInvertBubbleView(BrowserView* browser_view) {
Browser* browser = browser_view->browser();
PrefService* pref_service = browser->profile()->GetPrefs();
views::View* anchor = browser_view->toolbar()->app_menu();
if (gfx::IsInvertedColorScheme() && anchor && anchor->GetWidget() &&
!pref_service->GetBoolean(prefs::kInvertNotificationShown)) {
pref_service->SetBoolean(prefs::kInvertNotificationShown, true);
InvertBubbleView* delegate = new InvertBubbleView(browser, anchor);
views::BubbleDelegateView::CreateBubble(delegate)->Show();
}
}
} // namespace chrome