Skip to content

Commit

Permalink
[chromecast] Add rounded corner decoration utility.
Browse files Browse the repository at this point in the history
Upstreams a utility which draws roundy corners on aura windows.

Bug: internal b/141369549
Test: manual
Change-Id: Ibbc57c6e15529ebc69fb294fc391cf349e9bb305
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1841573
Reviewed-by: Daniel Nicoara <dnicoara@chromium.org>
Commit-Queue: Ryan Daum <rdaum@chromium.org>
Cr-Commit-Position: refs/heads/master@{#702905}
  • Loading branch information
Ryan Daum authored and Commit Bot committed Oct 4, 2019
1 parent 5f77c23 commit 242c714
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 0 deletions.
4 changes: 4 additions & 0 deletions chromecast/graphics/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ cast_source_set("graphics") {
"cast_window_manager.h",
"gestures/cast_gesture_handler.cc",
"gestures/cast_gesture_handler.h",
"rounded_window_corners.cc",
"rounded_window_corners.h",
]

deps = [
Expand Down Expand Up @@ -63,6 +65,7 @@ cast_source_set("graphics") {
"gestures/multiple_tap_detector.h",
"gestures/side_swipe_detector.cc",
"gestures/side_swipe_detector.h",
"rounded_window_corners_aura.cc",
]

deps += [
Expand All @@ -77,6 +80,7 @@ cast_source_set("graphics") {
sources += [
"cast_window_manager_default.cc",
"cast_window_manager_default.h",
"rounded_window_corners.h",
]
}

Expand Down
13 changes: 13 additions & 0 deletions chromecast/graphics/rounded_window_corners.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2019 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 "chromecast/graphics/rounded_window_corners.h"

namespace chromecast {

RoundedWindowCorners::RoundedWindowCorners() {}

RoundedWindowCorners::~RoundedWindowCorners() {}

} // namespace chromecast
28 changes: 28 additions & 0 deletions chromecast/graphics/rounded_window_corners.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2019 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.

#ifndef CHROMECAST_GRAPHICS_ROUNDED_WINDOW_CORNERS_H_
#define CHROMECAST_GRAPHICS_ROUNDED_WINDOW_CORNERS_H_

#include <memory>

namespace chromecast {

class CastWindowManager;

// A class that draws rounded borders on the corners of the screen.
class RoundedWindowCorners {
public:
static std::unique_ptr<RoundedWindowCorners> Create(
CastWindowManager* window_manager);

RoundedWindowCorners();
virtual ~RoundedWindowCorners();

virtual void SetColorInversion(bool enable) = 0;
};

} // namespace chromecast

#endif // CHROMECAST_GRAPHICS_ROUNDED_WINDOW_CORNERS_H_
130 changes: 130 additions & 0 deletions chromecast/graphics/rounded_window_corners_aura.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// Copyright 2019 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 "chromecast/graphics/rounded_window_corners.h"

#include <vector>

#include "base/threading/thread_checker.h"
#include "chromecast/graphics/cast_window_manager.h"
#include "ui/aura/window.h"
#include "ui/gfx/canvas.h"
#include "ui/views/layout/layout_provider.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"

namespace chromecast {
namespace {

const int kCornerRadius = 10;

// A view that draws a black rounded corner. One should be used for each corner
// of the main view.
class BlackCornerView : public views::View {
public:
BlackCornerView(int radius, bool on_right, bool on_top)
: radius_(radius), on_right_(on_right), on_top_(on_top) {}

~BlackCornerView() override {}

void SetColorInversion(bool enable) {
// In order to show as black we need to paint white when inversion is on.
color_ = enable ? SK_ColorWHITE : SK_ColorBLACK;
SchedulePaint();
}

private:
void OnPaint(gfx::Canvas* canvas) override {
// Draw a black rectangle over everything.
canvas->DrawColor(color_);
// Then clear out the inner corner.
cc::PaintFlags flags;
flags.setStrokeWidth(0);
flags.setColor(color_);
flags.setStyle(cc::PaintFlags::kFill_Style);
flags.setAntiAlias(true);
flags.setBlendMode(SkBlendMode::kClear);
gfx::PointF center_point(on_right_ ? radius_ : 0, on_top_ ? radius_ : 0);
canvas->DrawCircle(center_point, radius_, flags);
}

void Layout() override {
int x = on_right_ ? 0 : parent()->width() - radius_;
int y = on_top_ ? 0 : parent()->height() - radius_;
SetBounds(x, y, radius_, radius_);
}

SkColor color_ = SK_ColorBLACK;
int radius_;
bool on_right_;
bool on_top_;
};

// Aura based implementation of RoundedWindowCorners.
class RoundedWindowCornersAura : public RoundedWindowCorners {
public:
explicit RoundedWindowCornersAura(CastWindowManager* window_manager);
~RoundedWindowCornersAura() override;

void SetColorInversion(bool enable) override;

private:
std::unique_ptr<views::Widget> widget_;
views::LayoutProvider layout_provider_;

std::vector<BlackCornerView*> corners_;

THREAD_CHECKER(thread_checker_);

DISALLOW_COPY_AND_ASSIGN(RoundedWindowCornersAura);
};

RoundedWindowCornersAura::RoundedWindowCornersAura(
CastWindowManager* window_manager) {
auto main_view = std::make_unique<views::View>();
auto add_view = [this, &main_view](int radius, bool on_right, bool on_top) {
BlackCornerView* view = new BlackCornerView(radius, on_right, on_top);
main_view->AddChildView(view);
corners_.push_back(view);
};
add_view(kCornerRadius, false, false);
add_view(kCornerRadius, true, false);
add_view(kCornerRadius, false, true);
add_view(kCornerRadius, true, true);

widget_.reset(new views::Widget);
views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.context = window_manager->GetRootWindow();
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
params.bounds = window_manager->GetRootWindow()->GetBoundsInRootWindow();
params.accept_events = false;
widget_->Init(std::move(params));
widget_->SetContentsView(main_view.release());
widget_->GetNativeWindow()->SetName("RoundCorners");

window_manager->SetWindowId(widget_->GetNativeView(),
CastWindowManager::CORNERS_OVERLAY);

widget_->Show();
}

RoundedWindowCornersAura::~RoundedWindowCornersAura() {
DCHECK(thread_checker_.CalledOnValidThread());
}

void RoundedWindowCornersAura::SetColorInversion(bool enable) {
for (auto* view : corners_)
view->SetColorInversion(enable);
}

} // namespace

// static
std::unique_ptr<RoundedWindowCorners> RoundedWindowCorners::Create(
CastWindowManager* window_manager) {
return std::make_unique<RoundedWindowCornersAura>(window_manager);
}

} // namespace chromecast
33 changes: 33 additions & 0 deletions chromecast/graphics/rounded_window_corners_default.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2019 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 "chromecast/graphics/rounded_window_corners.h"

#include "base/macros.h"

namespace chromecast {

namespace {

// A no-op default implementation of RoundedWindowCorners.
class RoundedWindowCornersDefault : public RoundedWindowCorners {
public:
RoundedWindowCornersDefault() {}
~RoundedWindowCornersDefault() override {}

void SetColorInversion(bool enable) override {}

private:
DISALLOW_COPY_AND_ASSIGN(RoundedWindowCornersDefault);
};

} // namespace

// static
std::unique_ptr<RoundedWindowCorners> RoundedWindowCorners::Create(
CastWindowManager* window_manager) {
return std::make_unique<RoundedWindowCornersDefault>();
}

} // namespace chromecast

0 comments on commit 242c714

Please sign in to comment.