Skip to content

Commit

Permalink
Layout drawable
Browse files Browse the repository at this point in the history
- [x] Changes LayoutComponent to extend Drawable (implements ShapePaintContainer)
- [x] Fixes some API naming conflicts
- [x] Adds DrawableProxy to allow inserting custom draw commands into draw order (allows LayoutComponent fills to be drawn below children and strokes to be drawn above
- [x] Works with Fill/Stroke inspectors
- [x] Adds corner radius core props
- [x] Clipping
- [x] CPP Updates
- [x] Clipping in CPP
- [x] Deal with conflicting x/y properties in Node & Artboard (CPP)

https://github.com/rive-app/rive/assets/186340/5aec1cd5-6b00-4627-bfce-9cdeec8e3e96

Showing clipping and blend modes / opacity

https://github.com/user-attachments/assets/843b6c74-cec0-4333-8ef1-6fee9b910a59

Diffs=
114da4e39 Layout drawable (#7544)

Co-authored-by: Philip Chung <[email protected]>
  • Loading branch information
philter and philter committed Jul 23, 2024
1 parent 2b9cfe1 commit 93014af
Show file tree
Hide file tree
Showing 29 changed files with 538 additions and 141 deletions.
2 changes: 1 addition & 1 deletion .rive_head
Original file line number Diff line number Diff line change
@@ -1 +1 @@
b5f342002be71c61608ad6c37835349eb4e7c719
114da4e39ba61dd337e8f6f47c1c7b2fb2223915
23 changes: 23 additions & 0 deletions dev/core_generator/lib/src/definition.dart
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ class Definition {
for (final property in properties) {
code.writeln('static const uint16_t ${property.name}PropertyKey = '
'${property.key!.intValue};');
for (final altKey in property.key!.alternates) {
code.writeln(
'static const uint16_t ${altKey.stringValue}PropertyKey = '
'${altKey.intValue};');
}
}
if (storedProperties.any((prop) => !prop.isEncoded)) {
code.writeln('private:');
Expand Down Expand Up @@ -486,6 +491,12 @@ class Definition {
for (final property in properties) {
ctxCode.writeln('case ${property.definition.name}Base'
'::${property.name}PropertyKey:');
if (property.key != null) {
for (final altKey in property.key!.alternates) {
ctxCode.writeln('case ${property.definition.name}Base'
'::${altKey.stringValue}PropertyKey:');
}
}
ctxCode.writeln('object->as<${property.definition.name}Base>()->'
'${property.name}(value);');
ctxCode.writeln('break;');
Expand All @@ -506,6 +517,10 @@ class Definition {
for (final property in properties) {
ctxCode.writeln('case ${property.definition.name}Base'
'::${property.name}PropertyKey:');
for (final altKey in property.key!.alternates) {
ctxCode.writeln('case ${property.definition.name}Base'
'::${altKey.stringValue}PropertyKey:');
}
ctxCode
.writeln('return object->as<${property.definition.name}Base>()->'
'${property.name}();');
Expand All @@ -528,6 +543,10 @@ class Definition {
for (final property in properties) {
ctxCode.writeln('case ${property.definition.name}Base'
'::${property.name}PropertyKey:');
for (final altKey in property.key!.alternates) {
ctxCode.writeln('case ${property.definition.name}Base'
'::${altKey.stringValue}PropertyKey:');
}
}
}
ctxCode.writeln('return Core${fieldType.capitalizedName}Type::id;');
Expand Down Expand Up @@ -567,6 +586,10 @@ class Definition {
for (final property in properties) {
ctxCode.writeln('case ${property.definition.name}Base'
'::${property.name}PropertyKey:');
for (final altKey in property.key!.alternates) {
ctxCode.writeln('case ${property.definition.name}Base'
'::${altKey.stringValue}PropertyKey:');
}
ctxCode
.writeln('return object->is<${property.definition.name}Base>();');
}
Expand Down
31 changes: 28 additions & 3 deletions dev/core_generator/lib/src/key.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'property.dart';
class Key {
final String? stringValue;
final int? intValue;
final List<Key> alternates = [];

bool get isMissing => intValue == null;

Expand All @@ -23,12 +24,36 @@ class Key {
}
dynamic iv = data['int'];
dynamic sv = data['string'];
dynamic av = data['alternates'];
if (iv is int && sv is String) {
return Key(sv, iv);
final key = Key(sv, iv);
if (av is List) {
for (final a in av) {
if (a is Map<String, dynamic>) {
dynamic altiv = a['int'];
dynamic altsv = a['string'];
key.alternates.add(Key(altsv, altiv));
}
}
}
return key;
}
return null;
}

Map<String, dynamic> serialize() =>
<String, dynamic>{'int': intValue, 'string': stringValue};
Map<String, dynamic> serialize() {
final json = <String, dynamic>{'int': intValue, 'string': stringValue};
final altsJson = [];
for (final alt in alternates) {
final altJson = <String, dynamic>{
'int': alt.intValue,
'string': alt.stringValue
};
altsJson.add(altJson);
}
if (altsJson.isNotEmpty) {
json['alternates'] = altsJson;
}
return json;
}
}
18 changes: 0 additions & 18 deletions dev/defs/artboard.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,6 @@
},
"extends": "layout_component.json",
"properties": {
"x": {
"type": "double",
"initialValue": "0",
"key": {
"int": 9,
"string": "x"
},
"description": "X coordinate in editor world space."
},
"y": {
"type": "double",
"initialValue": "0",
"key": {
"int": 10,
"string": "y"
},
"description": "Y coordinate in editor world space."
},
"originX": {
"type": "double",
"initialValue": "0",
Expand Down
49 changes: 49 additions & 0 deletions dev/defs/layout/layout_component_style.json
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,55 @@
"string": "maxheightunitsvalue"
},
"description": ""
},
"linkCornerRadius": {
"type": "bool",
"initialValue": "true",
"key": {
"int": 639,
"string": "linkcornerradius"
},
"description": "Whether the TL corner radius defines all the radiuses"
},
"cornerRadiusTL": {
"type": "double",
"initialValue": "0",
"animates": true,
"key": {
"int": 640,
"string": "cornerradiustl"
},
"description": "Top left radius of the corners of this layout"
},
"cornerRadiusTR": {
"type": "double",
"initialValue": "0",
"animates": true,
"key": {
"int": 641,
"string": "cornerradiustr"
},
"description": "Top right radius of the corners of this layout"
},
"cornerRadiusBL": {
"type": "double",
"initialValue": "0",
"animates": true,
"key": {
"int": 642,
"string": "cornerradiusbl"
},
"description": "Bottom left radius of the corners of this layout"
},
"cornerRadiusBR": {
"type": "double",
"initialValue": "0",
"animates": true,
"key": {
"int": 643,
"string": "cornerradiusbr"
},
"description": "Bottom right radius of the corners of this layout"
}
}
}
2 changes: 1 addition & 1 deletion dev/defs/layout_component.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"int": 409,
"string": "layoutcomponent"
},
"extends": "world_transform_component.json",
"extends": "drawable.json",
"properties": {
"clip": {
"type": "bool",
Expand Down
16 changes: 14 additions & 2 deletions dev/defs/node.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@
"group": "position",
"key": {
"int": 13,
"string": "x"
"string": "x",
"alternates": [
{
"int": 9,
"string": "xArtboard"
}
]
}
},
"y": {
Expand All @@ -25,7 +31,13 @@
"group": "position",
"key": {
"int": 14,
"string": "y"
"string": "y",
"alternates": [
{
"int": 10,
"string": "yArtboard"
}
]
}
},
"styleValue": {
Expand Down
24 changes: 13 additions & 11 deletions include/rive/artboard.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "rive/hit_info.hpp"
#include "rive/math/aabb.hpp"
#include "rive/renderer.hpp"
#include "rive/shapes/shape_paint_container.hpp"
#include "rive/text/text_value_run.hpp"
#include "rive/event.hpp"
#include "rive/audio/audio_engine.hpp"
Expand Down Expand Up @@ -48,7 +47,7 @@ class SMITrigger;
typedef void (*ArtboardCallback)(Artboard*);
#endif

class Artboard : public ArtboardBase, public CoreContext, public ShapePaintContainer
class Artboard : public ArtboardBase, public CoreContext
{
friend class File;
friend class ArtboardImporter;
Expand All @@ -71,8 +70,6 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta

unsigned int m_DirtDepth = 0;
RawPath m_backgroundRawPath;
rcp<RenderPath> m_BackgroundPath;
rcp<RenderPath> m_ClipPath;
Factory* m_Factory = nullptr;
Drawable* m_FirstDrawable = nullptr;
bool m_IsInstance = false;
Expand All @@ -88,8 +85,7 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta
void sortDependencies();
void sortDrawOrder();
void updateDataBinds();

Artboard* getArtboard() override { return this; }
void performUpdate(ComponentDirt value) override;

#ifdef TESTING
public:
Expand All @@ -114,15 +110,20 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta

// EXPERIMENTAL -- for internal testing only for now.
// DO NOT RELY ON THIS as it may change/disappear in the future.
Core* hitTest(HitInfo*, const Mat2D* = nullptr);
Core* hitTest(HitInfo*, const Mat2D&) override;

void onComponentDirty(Component* component);

/// Update components that depend on each other in DAG order.
bool updateComponents();
void update(ComponentDirt value) override;
void onDirty(ComponentDirt dirt) override;

// Artboards don't update their world transforms in the same way
// as other TransformComponents so we override this.
// This is because LayoutComponent extends Drawable, but
// Artboard is a special type of LayoutComponent
void updateWorldTransform() override {}

void markLayoutDirty(LayoutComponent* layoutComponent)
{
m_dirtyLayout.insert(layoutComponent);
Expand Down Expand Up @@ -150,12 +151,13 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta
kHideBG,
kHideFG,
};
void draw(Renderer* renderer, DrawOption = DrawOption::kNormal);
void draw(Renderer* renderer, DrawOption option);
void draw(Renderer* renderer) override;
void addToRenderPath(RenderPath* path, const Mat2D& transform);

#ifdef TESTING
RenderPath* clipPath() const { return m_ClipPath.get(); }
RenderPath* backgroundPath() const { return m_BackgroundPath.get(); }
RenderPath* clipPath() const { return m_clipPath.get(); }
RenderPath* backgroundPath() const { return m_backgroundPath.get(); }
#endif

const std::vector<Core*>& objects() const { return m_Objects; }
Expand Down
21 changes: 20 additions & 1 deletion include/rive/drawable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class Drawable : public DrawableBase

public:
BlendMode blendMode() const { return (BlendMode)blendModeValue(); }
ClipResult clip(Renderer* renderer) const;
ClipResult applyClip(Renderer* renderer) const;
virtual void draw(Renderer* renderer) = 0;
virtual Core* hitTest(HitInfo*, const Mat2D&) = 0;
void addClippingShape(ClippingShape* shape);
Expand All @@ -49,6 +49,25 @@ class Drawable : public DrawableBase

StatusCode onAddedDirty(CoreContext* context) override;
};

class ProxyDrawing
{
public:
virtual void drawProxy(Renderer* renderer) = 0;
};

class DrawableProxy : public Drawable
{
private:
ProxyDrawing* m_proxyDrawing;

public:
DrawableProxy(ProxyDrawing* proxy) : m_proxyDrawing(proxy) {}

void draw(Renderer* renderer) override { m_proxyDrawing->drawProxy(renderer); }

Core* hitTest(HitInfo*, const Mat2D&) override { return nullptr; }
};
} // namespace rive

#endif
Loading

0 comments on commit 93014af

Please sign in to comment.