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 "ash/touch/touch_observer_hud.h"
6
7#include "ash/root_window_controller.h"
8#include "ash/root_window_settings.h"
9#include "ash/shell.h"
10#include "ash/shell_window_ids.h"
11#include "ui/aura/window_event_dispatcher.h"
12#include "ui/gfx/display.h"
13#include "ui/gfx/rect.h"
14#include "ui/gfx/screen.h"
15#include "ui/gfx/size.h"
16#include "ui/views/widget/widget.h"
17
18namespace ash {
19
20TouchObserverHUD::TouchObserverHUD(aura::Window* initial_root)
21    : display_id_(GetRootWindowSettings(initial_root)->display_id),
22      root_window_(initial_root),
23      widget_(NULL) {
24  const gfx::Display& display =
25      Shell::GetInstance()->display_manager()->GetDisplayForId(display_id_);
26
27  views::View* content = new views::View;
28
29  const gfx::Size& display_size = display.size();
30  content->SetSize(display_size);
31
32  widget_ = new views::Widget();
33  views::Widget::InitParams
34      params(views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
35  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
36  params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
37  params.accept_events = false;
38  params.bounds = display.bounds();
39  params.parent =
40      Shell::GetContainer(root_window_, kShellWindowId_OverlayContainer);
41  widget_->Init(params);
42  widget_->SetContentsView(content);
43  widget_->StackAtTop();
44  widget_->Show();
45
46  widget_->AddObserver(this);
47
48  // Observe changes in display size and mode to update touch HUD.
49  Shell::GetScreen()->AddObserver(this);
50#if defined(OS_CHROMEOS)
51  Shell::GetInstance()->display_configurator()->AddObserver(this);
52#endif  // defined(OS_CHROMEOS)
53
54  Shell::GetInstance()->display_controller()->AddObserver(this);
55  root_window_->AddPreTargetHandler(this);
56}
57
58TouchObserverHUD::~TouchObserverHUD() {
59  Shell::GetInstance()->display_controller()->RemoveObserver(this);
60
61#if defined(OS_CHROMEOS)
62  Shell::GetInstance()->display_configurator()->RemoveObserver(this);
63#endif  // defined(OS_CHROMEOS)
64  Shell::GetScreen()->RemoveObserver(this);
65
66  widget_->RemoveObserver(this);
67}
68
69void TouchObserverHUD::Clear() {
70}
71
72void TouchObserverHUD::Remove() {
73  root_window_->RemovePreTargetHandler(this);
74
75  RootWindowController* controller = GetRootWindowController(root_window_);
76  UnsetHudForRootWindowController(controller);
77
78  widget_->CloseNow();
79}
80
81void TouchObserverHUD::OnTouchEvent(ui::TouchEvent* /*event*/) {
82}
83
84void TouchObserverHUD::OnWidgetDestroying(views::Widget* widget) {
85  DCHECK_EQ(widget, widget_);
86  delete this;
87}
88
89void TouchObserverHUD::OnDisplayAdded(const gfx::Display& new_display) {}
90
91void TouchObserverHUD::OnDisplayRemoved(const gfx::Display& old_display) {
92  if (old_display.id() != display_id_)
93    return;
94  widget_->CloseNow();
95}
96
97void TouchObserverHUD::OnDisplayMetricsChanged(const gfx::Display& display,
98                                               uint32_t metrics) {
99  if (display.id() != display_id_ || !(metrics & DISPLAY_METRIC_BOUNDS))
100    return;
101
102  widget_->SetSize(display.size());
103}
104
105#if defined(OS_CHROMEOS)
106void TouchObserverHUD::OnDisplayModeChanged(
107    const ui::DisplayConfigurator::DisplayStateList& outputs) {
108  // Clear touch HUD for any change in display mode (single, dual extended, dual
109  // mirrored, ...).
110  Clear();
111}
112#endif  // defined(OS_CHROMEOS)
113
114void TouchObserverHUD::OnDisplaysInitialized() {
115  OnDisplayConfigurationChanged();
116}
117
118void TouchObserverHUD::OnDisplayConfigurationChanging() {
119  if (!root_window_)
120    return;
121
122  root_window_->RemovePreTargetHandler(this);
123
124  RootWindowController* controller = GetRootWindowController(root_window_);
125  UnsetHudForRootWindowController(controller);
126
127  views::Widget::ReparentNativeView(
128      widget_->GetNativeView(),
129      Shell::GetContainer(root_window_,
130                          kShellWindowId_UnparentedControlContainer));
131
132  root_window_ = NULL;
133}
134
135void TouchObserverHUD::OnDisplayConfigurationChanged() {
136  if (root_window_)
137    return;
138
139  root_window_ = Shell::GetInstance()->display_controller()->
140      GetRootWindowForDisplayId(display_id_);
141
142  views::Widget::ReparentNativeView(
143      widget_->GetNativeView(),
144      Shell::GetContainer(root_window_, kShellWindowId_OverlayContainer));
145
146  RootWindowController* controller = GetRootWindowController(root_window_);
147  SetHudForRootWindowController(controller);
148
149  root_window_->AddPreTargetHandler(this);
150}
151
152}  // namespace ash
153