Skip to content

Commit

Permalink
UIBlurView impl
Browse files Browse the repository at this point in the history
  • Loading branch information
XITRIX committed Dec 15, 2024
1 parent b7557f6 commit f138896
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 12 deletions.
2 changes: 2 additions & 0 deletions Submodules/UIKit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ add_definitions(
add_library(UIKit
lib/CABasicAnimation.cpp
lib/CABasicAnimationPrototype.cpp
lib/CABlurLayer.cpp
lib/CASpringAnimation.cpp
lib/CASpringAnimationPrototype.cpp
lib/CAMediaTimingFunction.cpp
Expand All @@ -24,6 +25,7 @@ add_library(UIKit
lib/UIApplication.cpp
lib/UIApplicationDelegateImpl.cpp
lib/UIApplicationMain.cpp
lib/UIBlurView.cpp
lib/UIColor.cpp
lib/UIImage.cpp
lib/UIImageView.cpp
Expand Down
27 changes: 27 additions & 0 deletions Submodules/UIKit/include/CABlurLayer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include <CALayer.h>

namespace NXKit {

class CABlurLayer: public CALayer {
public:
CABlurLayer();
CABlurLayer(CABlurLayer* layer);
virtual ~CABlurLayer() = default;

void draw(SkCanvas* context) override;
std::shared_ptr<CALayer> copy() override;

void setBlurValue(NXFloat blurValue);
[[nodiscard]] NXFloat blurValue() const { return _blurValue; }

std::optional<AnimatableProperty> value(std::string forKeyPath) override;
protected:
void update(std::shared_ptr<CALayer> presentation, std::shared_ptr<CABasicAnimation> animation, float progress) override;

private:
NXFloat _blurValue = 20;
};

}
19 changes: 19 additions & 0 deletions Submodules/UIKit/include/UIBlurView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include <UIView.h>
#include <CABlurLayer.h>

namespace NXKit {

class UIBlurView: public UIView {
public:
UIBlurView();

void setBlurValue(NXFloat blurValue) { _blurLayer()->setBlurValue(blurValue); }
[[nodiscard]] NXFloat blurValue() const { return _blurLayer()->blurValue(); }

private:
std::shared_ptr<CABlurLayer> _blurLayer() const;
};

}
5 changes: 3 additions & 2 deletions Submodules/UIKit/include/UIKit.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#pragma once

#include <UIViewController.h>
#include <UILabel.h>
#include <UIBlurView.h>
#include <UIImageView.h>
#include <UILabel.h>
#include <UIViewController.h>
2 changes: 0 additions & 2 deletions Submodules/UIKit/include/UILabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ class UILabel: public UIView {

private:
int _numberOfLines = 1;
std::string _text;

std::shared_ptr<CATextLayer> _textLayer() const;
};

Expand Down
68 changes: 68 additions & 0 deletions Submodules/UIKit/lib/CABlurLayer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include <CABlurLayer.h>
#include <tools/Tools.hpp>

#include "include/effects/SkImageFilters.h"

using namespace NXKit;

CABlurLayer::CABlurLayer(): CALayer() {
}

CABlurLayer::CABlurLayer(CABlurLayer* layer): CALayer(layer) {
_blurValue = layer->_blurValue;
}

std::shared_ptr<CALayer> CABlurLayer::copy() {
return new_shared<CABlurLayer>(this);
}

void CABlurLayer::draw(SkCanvas* context) {
SkPaint blurPaint;
blurPaint.setAntiAlias(true);

blurPaint.setStyle(SkPaint::kFill_Style);
// blurPaint.setStrokeWidth(10);

sk_sp<SkImageFilter> newBlurFilter = SkImageFilters::Blur(_blurValue, _blurValue, SkTileMode::kClamp, nullptr);
blurPaint.setImageFilter(std::move(newBlurFilter));
//
context->save();

SkRect rect = SkRect::MakeXYWH(0, 0, bounds().width(), bounds().height());
context->clipRect(rect, true);
// // Make a separate layer using the blur filter, clipped to the middle rectangle's bounds
SkCanvas::SaveLayerRec slr(&rect, &blurPaint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
context->saveLayer(slr);
context->restore();
context->restore();
}

void CABlurLayer::setBlurValue(NXFloat blurValue) {
if (_blurValue == blurValue) return;
onWillSet("blurValue");
_blurValue = blurValue;
}

std::optional<AnimatableProperty> CABlurLayer::value(std::string forKeyPath) {
if (forKeyPath == "blurValue") return _blurValue;
return CALayer::value(forKeyPath);
}

void CABlurLayer::update(std::shared_ptr<CALayer> presentation, std::shared_ptr<CABasicAnimation> animation, float progress) {
if (!animation->keyPath.has_value() || !animation->fromValue.has_value()) return;

auto keyPath = animation->keyPath.value();
auto fromValue = animation->fromValue.value();

if (keyPath == "blurValue") {
auto start = any_optional_cast<NXFloat>(fromValue);
if (!start.has_value()) { return; }

auto end = any_optional_cast<NXFloat>(animation->toValue);
if (!end.has_value()) end = this->_blurValue;

std::static_pointer_cast<CABlurLayer>(presentation)->setBlurValue(start.value() + (end.value() - start.value()) * progress);
}

CALayer::update(presentation, animation, progress);
}
9 changes: 9 additions & 0 deletions Submodules/UIKit/lib/UIBlurView.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <UIBlurView.h>

using namespace NXKit;

UIBlurView::UIBlurView(): UIView(NXRect(), new_shared<CABlurLayer>()) {}

std::shared_ptr<CABlurLayer> UIBlurView::_blurLayer() const {
return std::static_pointer_cast<CABlurLayer>(layer());
}
4 changes: 1 addition & 3 deletions Submodules/UIKit/lib/UILabel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

using namespace NXKit;

UILabel::UILabel(): UIView(NXRect(), new_shared<CATextLayer>()) {

}
UILabel::UILabel(): UIView(NXRect(), new_shared<CATextLayer>()) {}

std::shared_ptr<CATextLayer> UILabel::_textLayer() const {
return std::static_pointer_cast<CATextLayer>(layer());
Expand Down
49 changes: 44 additions & 5 deletions app/Screens/TestViewController/TestViewController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,32 @@

using namespace NXKit;

void animateCube(std::shared_ptr<UIView> view) {
UIView::animate(2.5, [view]() {
view->setTransform(NXAffineTransform::identity.rotationBy(45));
view->setBackgroundColor(UIColor::orange);
}, [view](bool res) {
UIView::animate(2.5, [view]() {
view->setTransform(NXAffineTransform::identity);
view->setBackgroundColor(UIColor::blue);
}, [view](bool res) {
animateCube(view);
});
});
}

void animateBlur(std::shared_ptr<UIBlurView> view) {
UIView::animate(2.5, [view]() {
view->setBlurValue(0);
}, [view](bool res) {
UIView::animate(2.5, [view]() {
view->setBlurValue(20);
}, [view](bool res) {
animateBlur(view);
});
});
}

void animateLabel(std::shared_ptr<UILabel> label) {
UIView::animate(5, [label]() {
label->setFrame({ 200, 100, 140, 88 });
Expand All @@ -19,6 +45,18 @@ void animateLabel(std::shared_ptr<UILabel> label) {
animateLabel(label);
});
});

// Looks like transform interpolation has issues
// UIView::animate(5, [label]() {
// label->layer()->setTransform(NXTransform3D::identity.rotationBy(180, 0, 0, 1));
// }, [label](bool res) {
// UIView::animate(5, [label]() {
// label->layer()->setTransform(NXTransform3D::identity.rotationBy(360, 0, 0, 1));
// }, [label](bool res) {
// label->layer()->setTransform(NXTransform3D::identity);
// animateLabel(label);
// });
// });
}

TestViewController::TestViewController() {
Expand Down Expand Up @@ -48,11 +86,7 @@ void TestViewController::loadView() {
imageView->setContentMode(UIViewContentMode::topLeft);

subview->addSubview(imageView);

UIView::animate(5, [imageView]() {
imageView->setTransform(NXAffineTransform::identity.rotationBy(45));
imageView->setBackgroundColor(UIColor::orange);
});
animateCube(imageView);

label = new_shared<UILabel>();
label->setFrame({ 200, 100, 240, 88 });
Expand All @@ -61,6 +95,11 @@ void TestViewController::loadView() {
label->setBackgroundColor(UIColor::red);
rootView->addSubview(label);

auto blur = new_shared<UIBlurView>();
blur->setFrame({ 80, 80, 240, 240 });
rootView->addSubview(blur);
animateBlur(blur);

setView(rootView);
}

Expand Down

0 comments on commit f138896

Please sign in to comment.