-
Notifications
You must be signed in to change notification settings - Fork 110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Roadmap #345
Comments
Just to note that with bindings to C++ (or technically Objective-C, though would limit to iOS/macOS), it would become possible to create bindings for JSI (JavaScript Interface; a library originally designed by Meta and Microsoft for React Native). JSI is a common interface for performing simple operations that make use of native data (e.g. calling functions, exposing HostObjects) on any JS engine. The idea is that instead of calling (for example) V8 APIs directly, you'd call the engine-agnostic JSI APIs and a corresponding V8 call would be made by the engine-specific implementation of the JSI. As engine-specific implementations are already available for V8, JSC, and Hermes, it would allow exposing Taffy to each of them with reduced maintenance burden. The advantage over WASM is that it would work on JS engines not supporting WASM (even if only due to JIT being disabled, e.g. the App Store). It's something I'd have an interest in helping with once C++ bindings were made! Spare time willing, of course. |
I think, that pure C public interface (for FFI) is a key for making bindings for various other languages. It is common solution/strategy implemented in many projects, even in Yoga (written internally in C++, with C public interface, which used in Java/C#/JavaScript(WASM)/ObjC bindings) |
Agreed that a C interface ought to be priority as it can serve as the foundation for the others (and more easily allow 3rd parties to bind to Taffy in lieu of 1st party bindings.) @shirakaba Presumably C bindings would work for you? |
Could the JSI bindings used by https://github.com/triniwiz/nativescript-mason be reused @shirakaba? |
@shirakaba in the mason lib the iOS side is pretty much the c bindings you're looking for, wish I had a little more time to port it. |
@triniwiz How come you're using cxx and jsi for Android and cbindgen and swift for iOS? They seem like completely different approaches... |
It's due to how the JSI is setup in NativeScript for iOS but I'm thinking I could move things around to give me an ease up |
Oh, I hadn't realised that was @triniwiz's approach! Yeah, something exactly like that 😂🙇♂️ |
Presumably! Although I defer to Osei at this point as he seems to have got it bridged all the way to iOS/Android already. |
Commenting here since I haven't seen it shared anywhere: I assume there should also be tools to navigate the layouts, rather than simply… lay them out? To make any one of these layouts navigable via keyboard or controller, you need the ability to, at minimum:
To me, these kinds of inclusion make the most sense in this library, rather than any library that uses these trees, since they're fundamental properties of the tree itself. You can't simply lay out a second navigation tree, since you need to depend on the layout of the original tree; one simple example of this is flexbox, since that can affect whether an element is below or to the right of something, for example. Sure, you can manually compute this data yourself by navigating the tree and checking the positions of the layouts, but that's super inefficient and I would expect anything consuming the layout data to be able to build a navigation tree at the same time as the layout tree. Would be more than willing to help draft out the API for what this looks like and develop these features, but wanted to comment on the roadmap here first since these are pretty fundamental things that look missing to me. |
@nicopap has done more investigation into this on the Bevy side, but I don't think taffy is the right place for this abstraction: that should be handled on the UI crate's side. |
Okay, you think that taffy isn't the right place for this abstraction, but do you have any particular ideas how a UI crate would actually perform these operations by itself after using Taffy to generate a layout? Like I mention, the goal isn't to be live-navigating the Taffy tree directly, but for Taffy to offer data in the generated layout on where nodes are laid out relative to each other that makes it easier for any potential UI library to generate their own navigation trees. The only way you could do this currently, unless I'm missing something major from the API, is manually sorting the position information from the nodes yourself, which seems way less efficient than just having Taffy add in a bit of extra metadata on each node that includes that information as it's generating the layout. Since the positions of things can depend on flow, this also affects the resulting navigation tree (example I gave was buttons being vertically or horizontally stacked based upon a flex layout) and so that needs to be taken into account. |
Hmm.... are you saying you want Taffy to output absolute positions rather than parent-relative positions? That is something that Taffy could feasibly do. Although we would likely do it as a pass over the data after existing computation had be completed (so it wouldn't be any more efficient than you doing it yourself). Regarding actually having a "node above", "node to left" reference on each ndoe. I think the only way to do this in Taffy would also to manually sort the positions of the nodes. As things like absolute position can mean that a node's position isn't necessarily in any particular order. And I don't see how Taffy would compute relative positions between nested nodes. In fact, it doesn't seem obvious to me how to order such nodes at all. The bigger problem from my perspective is that I don't think there is a single best way to do this. For example, I don't think it's usual to determine the next/previous focusable node by visual position in the document. I think it's usually done by tabindex, falling back to source order. Taffy 0.4 (upcoming) does allow for either:
Which might make it a bit easier for you to implement any custom functionality you want on top of Taffy's tree. |
Yep, that's it. Though strictly speaking, that's tab navigation rather than orthogonal navigation, which is still unsolved.
For sure. I've seen loads of attempts at implementing Spatial Navigation (previously having worked in Smart TV) and there are loads of ways to go about it, each with different strengths and weaknesses. Norigin Spatial Navigation to name one, the WICG's Spatial Navigation (implemented by Opera) to name another, and also Mozilla's Spatial Navigation. Then there are frameworks from the BBC and no end of in-house frameworks from other manufacturers (like Netflix). Some take the approach of measuring and hit-testing, while others (I assume BBC's TAL) probably take an explicit numbered grid. There are lots of problems to solve like Given the amount of application-level context needed to handle the more complex cases, I do think it would be better handled by a framework that sits on top of Taffy, that has that full context. These days, I'd probably base upon the WICG implementation myself, though it does of course assume a DOM-capable JS environment (which of course is not necessarily what Taffy will be targeting). |
But wouldn't orthogonal navigation not really need the absolute positions, since relationships with parents are mostly preserved in children? While CSS supports much more complicated layout structure via weird operations like the
And sure, there are other cases where you're right that you'd just have to sort things by hand, but I was under the impression that, at least part of generating the flow, you'd still be able to add at least some metadata to help out any potential UI library looking to leverage this information, even if it's only at the same nesting level and they'd have to manually compute beyond that level themself. That said, the ability to add your own metadata to the tree does provide a good starting point for implementing this as something external to taffy that's still attached to the same tree, and it would be a good way to evaluate whether adding this into taffy itself would really make sense.
It would still be nice to, for example, have the ability to navigate nodes in a linear fashion without having to navigate the tree yourself. Of course, this could easily be done with a plugin, I think it would be nice to add some sort of helper on top of the tree structure that lets you navigate leaves with an iterator that stores its own stack. Also just want to say thank you @shirakaba for the links on the different ways other folks have tackled this problem. It's certainly not an easy one to solve, and the main reason why I wanted to bring it up here rather than just filing specific issues is that I think there may be some way Taffy could help out with this, even though obviously a bulk of the work would still be on any UI engine that used the resulting layouts. |
I am actually working on this in #705, hope it helps :) |
I thought it might be useful to track possible future feature work in a more structured way (grouped into categories).
See also: the Taffy Project Board
Future
CSS / Web layout features
box-sizing: content-box
#289align-content
in Block layout #709position: static
(absolute position relative a non-parent ancestor) #212Overflow::Auto
#560Calc
val #225min-content
/max-content
/fit-content
forwidth
/height
grid-template
,grid-template-areas
andgrid-area
Display::Block
) #405Display::Contents
#533Display::Table
) #467Display::Subgrid
) #468Non-CSS layout features
stretch
forwidth
/height
and possiblymargin
/inset
API Enhancements
Style
struct #568Style
from (and serialize to?) CSS syntax #440FFI / Bindings for other languages
The text was updated successfully, but these errors were encountered: