Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / display / overscan_calibrator.cc
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/chromeos/display/overscan_calibrator.h"
6
7 #include "ash/display/display_controller.h"
8 #include "ash/display/display_info.h"
9 #include "ash/display/display_manager.h"
10 #include "ash/shell.h"
11 #include "ash/shell_window_ids.h"
12 #include "base/callback.h"
13 #include "ui/aura/window.h"
14 #include "ui/compositor/layer.h"
15 #include "ui/gfx/canvas.h"
16
17 namespace chromeos {
18 namespace {
19
20 // The opacity for the arrows of the overscan calibration.
21 const float kArrowOpacity = 0.8;
22
23 // The height in pixel for the arrows to show the overscan calibration.
24 const int kCalibrationArrowHeight = 50;
25
26 // The gap between the boundary and calibration arrows.
27 const int kArrowGapWidth = 20;
28
29 // Draw the arrow for the overscan calibration to |canvas|.
30 void DrawTriangle(int x_offset,
31                   int y_offset,
32                   double rotation_degree,
33                   gfx::Canvas* canvas) {
34   // Draw triangular arrows.
35   SkPaint content_paint;
36   content_paint.setStyle(SkPaint::kFill_Style);
37   content_paint.setColor(SkColorSetA(SK_ColorBLACK, kuint8max * kArrowOpacity));
38   SkPaint border_paint;
39   border_paint.setStyle(SkPaint::kStroke_Style);
40   border_paint.setColor(SkColorSetA(SK_ColorWHITE, kuint8max * kArrowOpacity));
41
42   SkPath base_path;
43   base_path.moveTo(0, SkIntToScalar(-kCalibrationArrowHeight));
44   base_path.lineTo(SkIntToScalar(-kCalibrationArrowHeight), 0);
45   base_path.lineTo(SkIntToScalar(kCalibrationArrowHeight), 0);
46   base_path.close();
47
48   SkPath path;
49   gfx::Transform rotate_transform;
50   rotate_transform.Rotate(rotation_degree);
51   gfx::Transform move_transform;
52   move_transform.Translate(x_offset, y_offset);
53   rotate_transform.ConcatTransform(move_transform);
54   base_path.transform(rotate_transform.matrix(), &path);
55
56   canvas->DrawPath(path, content_paint);
57   canvas->DrawPath(path, border_paint);
58 }
59
60 }  // namespace
61
62 OverscanCalibrator::OverscanCalibrator(
63     const gfx::Display& target_display, const gfx::Insets& initial_insets)
64     : display_(target_display),
65       insets_(initial_insets),
66       initial_insets_(initial_insets),
67       committed_(false) {
68   // Undo the overscan calibration temporarily so that the user can see
69   // dark boundary and current overscan region.
70   ash::Shell::GetInstance()->display_controller()->SetOverscanInsets(
71       display_.id(), gfx::Insets());
72
73   ash::DisplayInfo info =
74       ash::Shell::GetInstance()->display_manager()->GetDisplayInfo(
75           display_.id());
76
77   aura::Window* root = ash::Shell::GetInstance()->display_controller()->
78       GetRootWindowForDisplayId(display_.id());
79   ui::Layer* parent_layer =
80       ash::Shell::GetContainer(root, ash::kShellWindowId_OverlayContainer)
81           ->layer();
82
83   calibration_layer_.reset(new ui::Layer());
84   calibration_layer_->SetOpacity(0.5f);
85   calibration_layer_->SetBounds(parent_layer->bounds());
86   calibration_layer_->set_delegate(this);
87   parent_layer->Add(calibration_layer_.get());
88 }
89
90 OverscanCalibrator::~OverscanCalibrator() {
91   // Overscan calibration has finished without commit, so the display has to
92   // be the original offset.
93   if (!committed_) {
94     ash::Shell::GetInstance()->display_controller()->SetOverscanInsets(
95         display_.id(), initial_insets_);
96   }
97 }
98
99 void OverscanCalibrator::Commit() {
100   ash::Shell::GetInstance()->display_controller()->SetOverscanInsets(
101       display_.id(), insets_);
102   committed_ = true;
103 }
104
105 void OverscanCalibrator::Reset() {
106   insets_ = initial_insets_;
107   calibration_layer_->SchedulePaint(calibration_layer_->bounds());
108 }
109
110 void OverscanCalibrator::UpdateInsets(const gfx::Insets& insets) {
111   insets_.Set(std::max(insets.top(), 0),
112               std::max(insets.left(), 0),
113               std::max(insets.bottom(), 0),
114               std::max(insets.right(), 0));
115   calibration_layer_->SchedulePaint(calibration_layer_->bounds());
116 }
117
118 void OverscanCalibrator::OnPaintLayer(gfx::Canvas* canvas) {
119   static const SkColor kTransparent = SkColorSetARGB(0, 0, 0, 0);
120   gfx::Rect full_bounds = calibration_layer_->bounds();
121   gfx::Rect inner_bounds = full_bounds;
122   inner_bounds.Inset(insets_);
123   canvas->FillRect(full_bounds, SK_ColorBLACK);
124   canvas->FillRect(inner_bounds, kTransparent, SkXfermode::kClear_Mode);
125
126   gfx::Point center = inner_bounds.CenterPoint();
127   int vertical_offset = inner_bounds.height() / 2 - kArrowGapWidth;
128   int horizontal_offset = inner_bounds.width() / 2 - kArrowGapWidth;
129
130   DrawTriangle(center.x(), center.y() + vertical_offset, 0, canvas);
131   DrawTriangle(center.x(), center.y() - vertical_offset, 180, canvas);
132   DrawTriangle(center.x() - horizontal_offset, center.y(), 90, canvas);
133   DrawTriangle(center.x() + horizontal_offset, center.y(), -90, canvas);
134 }
135
136 void OverscanCalibrator::OnDelegatedFrameDamage(
137     const gfx::Rect& damage_rect_in_dip) {
138 }
139
140 void OverscanCalibrator::OnDeviceScaleFactorChanged(
141     float device_scale_factor) {
142   // TODO(mukai): Cancel the overscan calibration when the device
143   // configuration has changed.
144 }
145
146 base::Closure OverscanCalibrator::PrepareForLayerBoundsChange() {
147   return base::Closure();
148 }
149
150 }  // namespace chromeos