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 "ui/aura/test/test_screen.h"
6
7#include "base/logging.h"
8#include "ui/aura/env.h"
9#include "ui/aura/window.h"
10#include "ui/aura/window_event_dispatcher.h"
11#include "ui/aura/window_tree_host.h"
12#include "ui/gfx/geometry/size_conversions.h"
13#include "ui/gfx/native_widget_types.h"
14#include "ui/gfx/rect_conversions.h"
15#include "ui/gfx/screen.h"
16
17namespace aura {
18
19namespace {
20
21bool IsRotationPortrait(gfx::Display::Rotation rotation) {
22  return rotation == gfx::Display::ROTATE_90 ||
23         rotation == gfx::Display::ROTATE_270;
24}
25
26}  // namespace
27
28// static
29TestScreen* TestScreen::Create(const gfx::Size& size) {
30  const gfx::Size kDefaultSize(800, 600);
31  // Use (0,0) because the desktop aura tests are executed in
32  // native environment where the display's origin is (0,0).
33  return new TestScreen(gfx::Rect(size.IsEmpty() ? kDefaultSize : size));
34}
35
36// static
37TestScreen* TestScreen::CreateFullscreen() {
38  return new TestScreen(gfx::Rect(WindowTreeHost::GetNativeScreenSize()));
39}
40
41TestScreen::~TestScreen() {
42}
43
44WindowTreeHost* TestScreen::CreateHostForPrimaryDisplay() {
45  DCHECK(!host_);
46  host_ = WindowTreeHost::Create(gfx::Rect(display_.GetSizeInPixel()));
47  host_->window()->AddObserver(this);
48  host_->InitHost();
49  return host_;
50}
51
52void TestScreen::SetDeviceScaleFactor(float device_scale_factor) {
53  gfx::Rect bounds_in_pixel(display_.GetSizeInPixel());
54  display_.SetScaleAndBounds(device_scale_factor, bounds_in_pixel);
55  host_->OnHostResized(bounds_in_pixel.size());
56}
57
58void TestScreen::SetDisplayRotation(gfx::Display::Rotation rotation) {
59  gfx::Rect bounds_in_pixel(display_.GetSizeInPixel());
60  gfx::Rect new_bounds(bounds_in_pixel);
61  if (IsRotationPortrait(rotation) != IsRotationPortrait(display_.rotation())) {
62    new_bounds.set_width(bounds_in_pixel.height());
63    new_bounds.set_height(bounds_in_pixel.width());
64  }
65  display_.set_rotation(rotation);
66  display_.SetScaleAndBounds(display_.device_scale_factor(), new_bounds);
67  host_->SetRootTransform(GetRotationTransform() * GetUIScaleTransform());
68}
69
70void TestScreen::SetUIScale(float ui_scale) {
71  ui_scale_ = ui_scale;
72  gfx::Rect bounds_in_pixel(display_.GetSizeInPixel());
73  gfx::Rect new_bounds = gfx::ToNearestRect(
74      gfx::ScaleRect(bounds_in_pixel, 1.0f / ui_scale));
75  display_.SetScaleAndBounds(display_.device_scale_factor(), new_bounds);
76  host_->SetRootTransform(GetRotationTransform() * GetUIScaleTransform());
77}
78
79void TestScreen::SetWorkAreaInsets(const gfx::Insets& insets) {
80  display_.UpdateWorkAreaFromInsets(insets);
81}
82
83gfx::Transform TestScreen::GetRotationTransform() const {
84  gfx::Transform rotate;
85  switch (display_.rotation()) {
86    case gfx::Display::ROTATE_0:
87      break;
88    case gfx::Display::ROTATE_90:
89      rotate.Translate(display_.bounds().height(), 0);
90      rotate.Rotate(90);
91      break;
92    case gfx::Display::ROTATE_270:
93      rotate.Translate(0, display_.bounds().width());
94      rotate.Rotate(270);
95      break;
96    case gfx::Display::ROTATE_180:
97      rotate.Translate(display_.bounds().width(),
98                       display_.bounds().height());
99      rotate.Rotate(180);
100      break;
101  }
102
103  return rotate;
104}
105
106gfx::Transform TestScreen::GetUIScaleTransform() const {
107  gfx::Transform ui_scale;
108  ui_scale.Scale(1.0f / ui_scale_, 1.0f / ui_scale_);
109  return ui_scale;
110}
111
112bool TestScreen::IsDIPEnabled() {
113  return true;
114}
115
116void TestScreen::OnWindowBoundsChanged(
117    Window* window, const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) {
118  DCHECK_EQ(host_->window(), window);
119  display_.SetSize(gfx::ToFlooredSize(
120      gfx::ScaleSize(new_bounds.size(), display_.device_scale_factor())));
121}
122
123void TestScreen::OnWindowDestroying(Window* window) {
124  if (host_->window() == window)
125    host_ = NULL;
126}
127
128gfx::Point TestScreen::GetCursorScreenPoint() {
129  return Env::GetInstance()->last_mouse_location();
130}
131
132gfx::NativeWindow TestScreen::GetWindowUnderCursor() {
133  return GetWindowAtScreenPoint(GetCursorScreenPoint());
134}
135
136gfx::NativeWindow TestScreen::GetWindowAtScreenPoint(const gfx::Point& point) {
137  return host_->window()->GetTopWindowContainingPoint(point);
138}
139
140int TestScreen::GetNumDisplays() const {
141  return 1;
142}
143
144std::vector<gfx::Display> TestScreen::GetAllDisplays() const {
145  return std::vector<gfx::Display>(1, display_);
146}
147
148gfx::Display TestScreen::GetDisplayNearestWindow(
149    gfx::NativeWindow window) const {
150  return display_;
151}
152
153gfx::Display TestScreen::GetDisplayNearestPoint(const gfx::Point& point) const {
154  return display_;
155}
156
157gfx::Display TestScreen::GetDisplayMatching(const gfx::Rect& match_rect) const {
158  return display_;
159}
160
161gfx::Display TestScreen::GetPrimaryDisplay() const {
162  return display_;
163}
164
165void TestScreen::AddObserver(gfx::DisplayObserver* observer) {
166}
167
168void TestScreen::RemoveObserver(gfx::DisplayObserver* observer) {
169}
170
171TestScreen::TestScreen(const gfx::Rect& screen_bounds)
172    : host_(NULL),
173      ui_scale_(1.0f) {
174  static int64 synthesized_display_id = 2000;
175  display_.set_id(synthesized_display_id++);
176  display_.SetScaleAndBounds(1.0f, screen_bounds);
177}
178
179}  // namespace aura
180