summaryrefslogtreecommitdiffstats
path: root/chrome/browser/accessibility/invert_bubble_views.cc
blob: 445f7704082a3f8d9f15320b1a4f74a2d2d72766 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// 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 "base/utf_string_conversions.h"
#include "chrome/browser/accessibility/invert_bubble_views.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/views/event_utils.h"
#include "chrome/browser/ui/views/window.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/page_navigator.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/sys_color_change_listener.h"
#include "ui/views/bubble/bubble_delegate.h"
#include "ui/views/controls/button/button.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"

namespace {
const char kLearnMoreUrl[] = "https://groups.google.com/a/googleproductforums.com/d/topic/chrome/Xrco2HsXS-8/discussion";
const int kBubbleWidth = 500;
}  // namespace

class InvertBubbleView : public views::BubbleDelegateView,
                         public views::LinkListener {
 public:
  InvertBubbleView(Profile* profile, views::View* anchor_view);
  virtual ~InvertBubbleView();

  // views::BubbleDelegateView overrides:
  virtual gfx::Rect GetAnchorRect() OVERRIDE;

 protected:
  // views::BubbleDelegateView overrides:
  virtual void Init() OVERRIDE;

  // views::LinkListener overrides:
  virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;

  Profile* profile_;

  DISALLOW_COPY_AND_ASSIGN(InvertBubbleView);
};

void InvertBubbleView::Init() {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  const gfx::Font& original_font = rb.GetFont(ResourceBundle::MediumFont);

  views::Label* title = new views::Label(
      l10n_util::GetStringUTF16(IDS_INVERT_NOTIFICATION));
  title->SetFont(original_font.DeriveFont(2, gfx::Font::BOLD));
  title->SetMultiLine(true);
  title->SizeToFit(kBubbleWidth);

  views::Link* learn_more =
    new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
  learn_more->SetFont(original_font);
  learn_more->set_listener(this);

  views::GridLayout* layout = views::GridLayout::CreatePanel(this);
  SetLayoutManager(layout);

  views::ColumnSet* columns = layout->AddColumnSet(0);
  columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::LEADING, 0,
                     views::GridLayout::USE_PREF, 0, 0);

  layout->StartRow(0, 0);
  layout->AddView(title);
  layout->StartRowWithPadding(0, 0, 0,
                              views::kRelatedControlSmallVerticalSpacing);
  layout->AddView(learn_more);

  // 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);
}

gfx::Rect InvertBubbleView::GetAnchorRect() {
  // Set the height to 0 so we display the bubble at the top of the
  // anchor rect.
  gfx::Rect rect(BubbleDelegateView::GetAnchorRect());
  rect.set_height(0);
  return rect;
}

InvertBubbleView::InvertBubbleView(Profile* profile, views::View* anchor_view)
    : views::BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT),
    profile_(profile) {
}

InvertBubbleView::~InvertBubbleView() {
}

void InvertBubbleView::LinkClicked(views::Link* source, int event_flags) {
  Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
  if (browser) {
    WindowOpenDisposition disposition =
        event_utils::DispositionFromEventFlags(event_flags);
    content::OpenURLParams params(
        GURL(kLearnMoreUrl), content::Referrer(),
        disposition == CURRENT_TAB ? NEW_FOREGROUND_TAB : disposition,
        content::PAGE_TRANSITION_LINK, false);
    browser->OpenURL(params);
  }
  GetWidget()->Close();
}

// static
void InvertBubble::RegisterUserPrefs(PrefService* prefs) {
  prefs->RegisterBooleanPref(prefs::kInvertNotificationShown,
                             false,
                             PrefService::UNSYNCABLE_PREF);
}

void InvertBubble::MaybeShowInvertBubble(Profile* profile,
                                         views::View* anchor_view) {
  PrefService* pref_service = profile->GetPrefs();
  if (gfx::IsInvertedColorScheme() &&
      !pref_service->GetBoolean(prefs::kInvertNotificationShown)) {
    pref_service->SetBoolean(prefs::kInvertNotificationShown, true);
    InvertBubbleView* delegate = new InvertBubbleView(profile, anchor_view);
    views::BubbleDelegateView::CreateBubble(delegate);
    delegate->StartFade(true);
  }
}