Skip to content

Commit

Permalink
WIP: UILabel textColor animation
Browse files Browse the repository at this point in the history
  • Loading branch information
XITRIX committed Dec 15, 2024
1 parent 36554a5 commit 96fefe0
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 23 deletions.
9 changes: 7 additions & 2 deletions Submodules/UIKit/include/CALayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,17 @@ class CALayer: public enable_shared_from_this<CALayer> {
void removeAllAnimations();
void onWillSet(std::string keyPath);
void onDidSetAnimations(bool wasEmpty);
std::optional<AnimatableProperty> value(std::string forKeyPath);

// Override to add new animatable
virtual std::optional<AnimatableProperty> value(std::string forKeyPath);

void animateAt(Timer currentTime);

void skiaRender(SkCanvas* canvas);
protected:
// Override to add new animatable
virtual void update(std::shared_ptr<CALayer> presentation, std::shared_ptr<CABasicAnimation> animation, float progress);

private:
friend class UIView;

Expand Down Expand Up @@ -164,7 +170,6 @@ class CALayer: public enable_shared_from_this<CALayer> {
/// This is both a performance optimization (avoids lots of animations at the start)
/// as well as a correctness fix (matches iOS behaviour). Maybe there's a better way though?
bool hasBeenRenderedInThisPartOfOverallLayerHierarchy = false;
void update(std::shared_ptr<CALayer> presentation, std::shared_ptr<CABasicAnimation> animation, float progress);
};

}
14 changes: 11 additions & 3 deletions Submodules/UIKit/include/CATextLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,26 @@ class CATextLayer: public CALayer {
void setText(std::string text);
[[nodiscard]] std::string text() const { return _text; }

void setFontSize(NXFloat fontSize);
[[nodiscard]] NXFloat fontSize() const { return _fontSize; }

void setTextColor(UIColor textColor);
[[nodiscard]] UIColor textColor() const { return _textColor; }

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 _fontSize = 17;
std::string _text = "Furthermore, العربية نص جميل. द क्विक ब्राउन फ़ॉक्स jumps over the lazy 🐕.";
UIColor _textColor = UIColor::black;

// Skia
sk_sp<SkTypeface> typeface;
skia::textlayout::ParagraphStyle paraStyle;
sk_sp<skia::textlayout::FontCollection> fontCollection;
// skia::textlayout::ParagraphStyle paraStyle;
// sk_sp<skia::textlayout::FontCollection> fontCollection;
sk_sp<SkUnicode> unicode;
std::unique_ptr<skia::textlayout::ParagraphBuilder> paragraphBuilder;
std::unique_ptr<skia::textlayout::Paragraph> paragraph;

void updateParagraph();
Expand Down
8 changes: 7 additions & 1 deletion Submodules/UIKit/include/UILabel.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
#pragma once

#include <UIView.h>
#include <CATextLayer.h>
#include <include/core/SkTypeface.h>

namespace NXKit {

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

void setTextColor(UIColor textColor);
[[nodiscard]] UIColor textColor();

private:
int _numberOfLines = 1;
std::string _text;
UIColor _textColor = UIColor::black;

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

}
3 changes: 1 addition & 2 deletions Submodules/UIKit/lib/CALayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,7 @@ void CALayer::onWillSet(std::string keyPath) {

auto animation = std::static_pointer_cast<CABasicAnimation>(actionForKey(animationKey));
if (animation &&
(this->hasBeenRenderedInThisPartOfOverallLayerHierarchy
|| animation->wasCreatedInUIAnimateBlock()) &&
(this->hasBeenRenderedInThisPartOfOverallLayerHierarchy || animation->wasCreatedInUIAnimateBlock()) &&
!this->isPresentationForAnotherLayer &&
!CATransaction::disableActions())
{
Expand Down
57 changes: 43 additions & 14 deletions Submodules/UIKit/lib/CATextLayer.cpp
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
#include <CATextLayer.h>
#include <modules/skunicode/include/SkUnicode_icu.h>
#include <tools/Tools.hpp>

using namespace NXKit;
using namespace skia::textlayout;

CATextLayer::CATextLayer(): CALayer() {
auto fontMgr = SkiaCtx::main()->getFontMgr();

SkFontStyle fontStyle;
typeface = SkiaCtx::main()->getFontMgr()->matchFamilyStyle(nullptr, fontStyle);

fontCollection = sk_make_sp<FontCollection>();
fontCollection->setDefaultFontManager(SkiaCtx::main()->getFontMgr());

unicode = SkUnicodes::ICU::Make();

paragraphBuilder = ParagraphBuilder::make(paraStyle, fontCollection, unicode);
updateParagraph();
}

CATextLayer::CATextLayer(CATextLayer* layer): CALayer(layer) {
_fontSize = layer->_fontSize;
_textColor = layer->_textColor;
_text = layer->_text;

typeface = layer->typeface;
paraStyle = layer->paraStyle;
fontCollection = layer->fontCollection;
unicode = layer->unicode;

paragraphBuilder = ParagraphBuilder::make(paraStyle, fontCollection, unicode);
updateParagraph();
}

Expand All @@ -46,12 +40,20 @@ void CATextLayer::setText(std::string text) {

void CATextLayer::setTextColor(UIColor textColor) {
if (_textColor == textColor) return;
onWillSet("textColor");
_textColor = textColor;
updateParagraph();
}

void CATextLayer::setFontSize(NXFloat fontSize) {
if (_fontSize == fontSize) return;
_fontSize = fontSize;
updateParagraph();
}

void CATextLayer::updateParagraph() {
paragraphBuilder->Reset();
auto fontCollection = sk_make_sp<FontCollection>();
fontCollection->setDefaultFontManager(SkiaCtx::main()->getFontMgr());

SkPaint paint;
paint.setAntiAlias(true);
Expand All @@ -60,12 +62,39 @@ void CATextLayer::updateParagraph() {
skia::textlayout::TextStyle style;
style.setForegroundColor(paint);
style.setTypeface(typeface);
style.setFontSize(17);
style.setFontSize(_fontSize);

ParagraphStyle paraStyle;
paraStyle.setTextStyle(style);
paraStyle.setTextAlign(TextAlign::kRight);

paragraphBuilder->addText(_text.c_str());
auto paragraphBuilder = ParagraphBuilder::make(paraStyle, fontCollection, unicode);

paragraphBuilder->addText(_text.c_str());
paragraph = paragraphBuilder->Build();
}

std::optional<AnimatableProperty> CATextLayer::value(std::string forKeyPath) {
if (forKeyPath == "textColor") return _textColor;
return CALayer::value(forKeyPath);
}

void CATextLayer::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 == "textColor") {
auto start = any_optional_cast<UIColor>(fromValue);
if (!start.has_value()) { return; }

auto end = any_optional_cast<UIColor>(animation->toValue);
if (!end.has_value()) end = this->_textColor;
if (!end.has_value()) end = UIColor::clear;

std::static_pointer_cast<CATextLayer>(presentation)->setTextColor(start->interpolationTo(end.value(), progress));
}

CALayer::update(presentation, animation, progress);
}
13 changes: 12 additions & 1 deletion Submodules/UIKit/lib/UILabel.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
#include <UILabel.h>
#include <CATextLayer.h>

using namespace NXKit;

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

}

std::shared_ptr<CATextLayer> UILabel::_textLayer() {
return std::static_pointer_cast<CATextLayer>(layer());
}

void UILabel::setTextColor(UIColor textColor) {
_textLayer()->setTextColor(textColor);
}

UIColor UILabel::textColor() {
return _textLayer()->textColor();
}
3 changes: 3 additions & 0 deletions app/AppDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ namespace NXKit {
void animateLabel(std::shared_ptr<UILabel> label) {
UIView::animate(5, [label]() {
label->setFrame({ 200, 100, 140, 88 });
label->setTextColor(UIColor::cyan);
}, [label](bool res) {
UIView::animate(5, [label]() {
label->setFrame({ 200, 100, 240, 88 });
label->setTextColor(UIColor::black);
}, [label](bool res) {
animateLabel(label);
});
Expand Down Expand Up @@ -56,6 +58,7 @@ bool UIApplicationDelegate::applicationDidFinishLaunchingWithOptions(UIApplicati

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

auto label = new_shared<UILabel>();
Expand Down

0 comments on commit 96fefe0

Please sign in to comment.