GithubHelp home page GithubHelp logo

graphiteeditor / graphite Goto Github PK

View Code? Open in Web Editor NEW
6.9K 57.0 371.0 29.31 MB

2D raster & vector editor that melds traditional layers & tools with a modern node-based, non-destructive, procedural workflow.

Home Page: https://graphite.rs

License: Apache License 2.0

Rust 79.40% JavaScript 0.98% HTML 0.51% TypeScript 6.66% Shell 0.02% Handlebars 0.03% SCSS 1.32% CSS 0.12% Svelte 10.87% WGSL 0.03% Nix 0.06%
graphics-editor vector-editor photo-editing photo-editor compositor 2d-graphics art design node-editor procedural-art

graphite's People

Contributors

0hypercube avatar akshay1992kalbhor avatar alexandruica avatar androxium avatar cauthmann avatar chase-percy avatar chrismend19 avatar dependabot[bot] avatar dhruv-ahuja avatar elbertronnie avatar ezbaze avatar gabrielmajeri avatar haikalvidya avatar hannahli2010 avatar henryksloan avatar isiko avatar keavon avatar linda-zheng avatar mfish33 avatar milan-sedivy avatar moosama76 avatar orlp avatar otdavies avatar pkupper avatar protheory8 avatar robnadal avatar rustynixietube avatar t0mstone avatar truedoctor avatar zhiyuang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

graphite's Issues

Layer panel does not update after undo

When pressing Z to undo, the most recently added layer does not immediately disappear from the layer panel. Only when adding a new layer does the old one disappear.

Implement scrolling with hidden overflow

This deals with the situation when the children of a component have expanded past the dimensions of their container. In such a case, the container may be given a scroll layout engine attribute which defaults to 0% (fully top/left). Absolute pixel values may be useful in addition to percentages because that would allow the user to drag an overflowed menu by the pixel increments of their mouse movement. Percentages (and absolute pixels) outside the 0–100% range would be clamped.

Because the layout system is built upon the premise that all elements are hierarchically enclosed within the dimensions of their ancestors, it is probably expected that each element is drawn fully without being cropped off. So the requirement that an overflowed layout must be cropped by their container may require some thought. Probably the layout engine will have to calculate values that extend past its parent, and then the shader simply won't render those cropped parts because the generated quads will be clamped to those bounds (thus, nothing is sent to the fragment shader outside those bounds).

It may also be worth considering if a mode like CSS's overflow: visible may be possible, whereby the overflowed children cover up what is behind them. However this may result in many edge cases related to rendering and redrawing only damaged areas. Unless this is trivial to implement or ends up being needed in the UI, it's probably unnecessary.

Standardize icon folders

Icon SVGs should just be 12x12, 16x16, tool (24x24), and node (24x24) type icons. Organize them into the respective folders and change the viewBox and Vue component padding as necessary to crop to the simple dimensions.

OutOfMemory

Hi. I tried running this on Windows

cargo build
RUST_BACKTRACE=1 ./target/debug/Graphite.exe 

But it fails

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: OutOfMemory(Host)', C:\Users\jamen\.cargo\registry\src\github.com-1ecc6299db9ec823\wgpu-core-0.5.6\src\device\mod.rs:1822:17
stack backtrace:
   0: backtrace::backtrace::trace_unsynchronized
             at C:\Users\VssAdministrator\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.46\src\backtrace\mod.rs:66
   1: std::sys_common::backtrace::_print_fmt
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\sys_common\backtrace.rs:78
   2: std::sys_common::backtrace::_print::{{impl}}::fmt
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\sys_common\backtrace.rs:59
   3: core::fmt::write
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libcore\fmt\mod.rs:1069
   4: std::io::Write::write_fmt<std::sys::windows::stdio::Stderr>
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\io\mod.rs:1504
   5: std::sys_common::backtrace::_print
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\sys_common\backtrace.rs:62
   6: std::sys_common::backtrace::print
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\sys_common\backtrace.rs:49
   7: std::panicking::default_hook::{{closure}}
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\panicking.rs:198
   8: std::panicking::default_hook
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\panicking.rs:218
   9: std::panicking::rust_panic_with_hook
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\panicking.rs:511
  10: std::panicking::begin_panic_handler
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\panicking.rs:419
  11: core::panicking::panic_fmt
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libcore\panicking.rs:111
  12: core::option::expect_none_failed
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libcore\option.rs:1268
  13: core::result::Result<gfx_backend_vulkan::native::GraphicsPipeline, gfx_hal::pso::CreationError>::unwrap<gfx_backend_vulkan::native::GraphicsPipeline,gfx_hal::pso::CreationError>
             at C:\Users\jamen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\result.rs:1005
  14: wgpu_core::hub::Global<wgpu_core::hub::IdentityManagerFactory>::device_create_render_pipeline<wgpu_core::hub::IdentityManagerFactory,gfx_backend_vulkan::Backend>
             at C:\Users\jamen\.cargo\registry\src\github.com-1ecc6299db9ec823\wgpu-core-0.5.6\src\device\mod.rs:1822
  15: wgpu_native::device::wgpu_device_create_render_pipeline
             at C:\Users\jamen\.cargo\registry\src\github.com-1ecc6299db9ec823\wgpu-native-0.5.1\src\device.rs:339
  16: wgpu::Device::create_render_pipeline
             at C:\Users\jamen\.cargo\registry\src\github.com-1ecc6299db9ec823\wgpu-0.5.2\src\lib.rs:867
  17: graphite::pipeline::Pipeline::build_pipeline
             at .\src\pipeline.rs:111
  18: graphite::pipeline::Pipeline::new
             at .\src\pipeline.rs:30
  19: graphite::application::Application::new
             at .\src\application.rs:72
  20: graphite::main
             at .\src\main.rs:30
  21: std::rt::lang_start::{{closure}}<()>
             at C:\Users\jamen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libstd\rt.rs:67
  22: std::rt::lang_start_internal::{{closure}}
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\rt.rs:52
  23: std::panicking::try::do_call
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\panicking.rs:331
  24: std::panicking::try
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\panicking.rs:274
  25: std::panic::catch_unwind
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\panic.rs:394
  26: std::rt::lang_start_internal
             at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\rt.rs:51
  27: std::rt::lang_start<()>
             at C:\Users\jamen\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libstd\rt.rs:67
  28: main
  29: invoke_main
             at d:\A01\_work\6\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
  30: __scrt_common_main_seh
             at d:\A01\_work\6\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
  31: BaseThreadInitThunk
  32: RtlUserThreadStart

Is this a bug or am I missing something?

Same thing in release mode.

Seems like it points to this line in graphite's code. But I have a similar pipeline in my project without this issue.

Edit: I tried compiling and loading the shaders manually with glslc from shaderc but its the same error.

Active Tool Router and stub for Tool State Machine

Inputs events (let's start with mouse inputs and modifier keys for now) should be directed from the Dispatcher to the Active Tool Router, then from there to the corresponding tool's state machine definition run by the Tool State Machine system.

The Active Tool Router is basically just a switch. It redirects events it receives to the FSM corresponding to the active_tool.

This issue should not add any functionality for the user to run, but it should extend the stubbed out tool Response to a click on the canvas into the Active Tool Router and to a stub for the FSM. This is followed up with #54 for the actual FSM implementation.

Code review existing GUI language parsing/AST/component generation code and architecture

I'd love to sit down and talk through the codebase and find what should be redesigned or refactored before proceeding with building the DOM tree (#4). Having a second opinion on the usage of terminology throughout the code would be excellent as well. See this documentation for a primer on the GUI system. There's also a more detailed specification in a Google Doc that I need to convert to a Markdown file and add to the repo.

This code review pertains to the following files:

  • gui_attributes.rs
  • gui_node.rs
  • layout_abstract_syntax.rs
  • layout_abstract_types.rs
  • layout_attribute_parser.rs
  • layout_system.rs
  • window_dom.rs
  • window_events.rs

Entry point in application.rs:

let mut main_window_layout = LayoutSystem::new();
main_window_layout.add_window(("window", "main"));

Use `log` instead of `println`

There are a few temporary printlns throughout the code, which are very useful now, in the early stages of the project, to make sure everything gets loaded and runs correctly.

We could instead switch to the log crate, and use appropriate (trace, debug, info) levels.

Upgrade wgpu to 0.7.0

It is currently using 0.5.0. Please keep the comments approximately consistent where things changed.

Add caching for rendered svg shapes

Currently the whole svg code is generated from scratch for each frame. This might get quite expensive with tools such as the pen tool consisting of multiple svg shapes.
We should implement either a tool local caching of the svg string, or ideally some sort of global cache management system, but we might not need that for 0.1.

Tools interrupted in their drag phase break when returning to the tool

Description

When drawing with the 'Pen' tool and switching the tool prematurely (before you have clicked enter) and then going back to the Pen tool and moving the mouse cursor around a bit, this happens

screen-capture

Reproduction steps

  1. Start drawing with the pen tool
  2. Don't press enter and have the line still following the cursor
  3. Click on any other tool and draw with it
  4. Click back onto the pen tool and move your mouse around

To be honest I think that it looked nice but probably wasn't intended to happen.

Refactor input system

There are currently some issues with handling user input:

  • Modifier keys should be handled globally to avoid issues with letting go of them while not focusing the canvas
  • Mod keys should persist across tools for the same reason
  • This applies to currently pressed mouse buttons as well, but in that case we at least have access to the currently pressed buttons
  • On the neo layout with the chrome browser, shift is recognized as CapsLock, we could think about making these equivalent

Initialize window layout by composing components within one another from the root window component

Now that all the component files are individually parsed into their own abstract syntax trees containing their subcomponents and attribute variable values, we have to put these all together into an actual GUI tree representing the whole window, essentially HTML's DOM. This needs to take into consideration the way in which data is passed down to children as props, and how that data will be reactively updated whenever the parent changes that data.

As of mid-February 2021, this is currently the GUI system's main blocking issue that requires some architectural design planning before approaching this further.

The Pen Tool adds a layer when it is completed after only creating the starting point

Currently this creates a 0x0 shape. Now that we are going to be creating layers each time you draw a shape, this will pollute the layer panel and be more obvious. (Eventually we might want to open a popup dialog asking for numerical specifications on the shape you clicked to create, for example the radius or width and height and rotation of an ellipse.)

Unite web build systems (WebPack for WASM bindings and Vue CLI for frontend)

See the readme on how we currently have two separate build systems:

The Vue.js frontend builds with Vue CLI using the commands npm run build, npm run serve, and npm run lint.

The wasm-bindgen infrastructure builds with WebPack using the commands npm run webpack-build and npm run webpack-start.

(See package.json)

We should probably move both over to WebPack in some way that allows the built WASM modules to work in the Vue app. I am positively abysmal at wrangling build systems so I need help from somebody who has knowledge of this.

It would also be great if we can upgrade to WebPack 5, but I had to downgrade because of an incompatibility that I ran into (but perhaps I was just doing something wrong).

Bonus: help improve the reliability of the development environment in VS Code (and perhaps other editors, if that's of interest to people). It's currently very un-robust. Configurations for linters, auto-formatting, code completion in Vue files, tidying up build environment related things all around the project, etc.

Implement the Tool State Machine

This is a finite state machine with various states and transitions, see the diagram below for an example. Each transition also represents a "hint" that shows up in the status bar footer.

It is important to think of the tool menu as, conceptually, a mode selector for the behavior of editing within the viewport. You perform operations on the viewport using your mouse and keyboard, and those operations change the node graph for you. Depending on which mode you're in, different operations are applied. That mode is chosen by selecting the active tool in the toolbar, or you could think of it as the "tool mode" in the "tool mode selector bar".

Each of these "modes" will be given its own FSM definition designed to model the exact behavior for the user experience of the tool.

The state machines will probably be pretty gnarly, it is way easier to work with them in a format resembling the Nomnoml diagram code (see below) than it is to figure out all that in Rust code. So the FSM for each tool will be defined as a text file. This probably makes extensions easier to support in the future also. We will need to design a format grammar and write a parser to construct the internal FSM data structure, which is implemented as:

  • Each tool has a HashMap to store all the ToolStates (orange and gold states in the graph).
  • A ToolState stores: name: String; isIntermediate: boolean; transitions: Vec<Transition>; action: a closure or a string name to look up the closure in a HashMap;
  • A Transition stores: condition: TransitionCondition; destination: string (each Transition is owned by its outgoing state within the Vec)
  • The "destination" string is the name of another ToolState. A TransitionCondition is an enum with all the possible input events and stateful details about the tool options, editor, and document (examples: mouse move event, mouse button down and up event for each mouse button, key down and up events for every key), plus ε (an instant, automatic transition). Perhaps we need a concept of event (which gets triggered) and a persistent condition (like a tool setting or some stateful characteristic about the document or editor). Or instead, perhaps transitions are only inputs or ε, but they can be gated by persistent conditions. The array of TransitionConditions will probably set the precedence.
  • The state machine is hard coded to begin with the Ready state. There is no end state, the machine never halts.

Example subset of the FSM for the Select tool:

Nomnoml diagram link

Orange is a main state that shows up in the footer of the Graphite editor as an input hint. Yellow/gold is a "intermediate" state that doesn't show up in the footer, but instead the result of the state it leads to shows up. (You can get to Transform Selected through a LMB Down combined with a MouseMove, for example.)

Footer

Question: Collaboration

Are there any plans to introduce live collaboration between multiple clients?

I was just listening to the presentation in game dev and considering that there is an API "endpoint", I thought it might be possible to have multiple end clients connect to a Graphite Server to collaborate on the same document together.

I very much realize that this is quiet a crazy idea 😄

Implement layout algorithm

Once the layout is parsed into memory, we have to compute the offsets and sizes (width/height) of the objects to be rendered.

Layout algorithm

To calculate dimensions (width/height):

  • elements with fixed sizes (e.g. 123px) are laid out, in the order they are encountered.
  • then we handle elements with inner, which indicates that the size of the component depends on the size of the child.
  • then percentages (such as 10%) are computed, based on the total size of the parent container.
  • then @ rules (e.g. 100@) are applied, which divide up the remaining free space.

When the width/height attributes are not specified, they each default to inner.

To calculate positions (x/y):

  • this only makes sense when there is some free space left (otherwise, all the elements fit tightly together and are positioned one after another).
  • x-align/y-align take a percentage, which indicates where it should be along the respective axis.
    0% would mean completely to the left/to the top, 100% would mean completely to the right/to the bottom, and 50% would be halfway between.

If there's not enough space in the parent container to lay out all children, we need to handle the overflow (for instance, through scrolling).

Change Ellipse Tool to work like a standard ellipse tool (not just circles)

This should be relatively easy for a newcomer or someone who has a few extra minutes. The Ellipse Tool currently only draws circles from the center. Instead, it should draw ellipses from the corner by default. If you want to constrain it to a 1:1 aspect ratio (a circle), you hold the Shift modifier key. If you want to have the circle originate from the center instead of the corner, you hold the Alt modifier key.

These modifier keys can also be extended to the other shape drawing tools.

Rename core lib crates to have 'graphite' prefix

Someone might want to make a third-party GUI implementation for Graphite. To do that they would need to link to core libs that we have in packages directory, so I think we should consider publishing them to https://crates.io at some point in the future. However before we can do that we need to rename crates to have a unique name.

I suggest we name crates cli and render-engine to graphite-cli and graphite-render-engine respectively. To do that we only need to change the name field in Cargo.toml, no need to rename directories.

SVG export

Save the current document as an svg when pressing Ctrl + Z.

This involves adding a new Message to the document message handler SaveDocument.
Advertise the action.
Add the keybind in the input mapper.
And a message to the frontend message handler.
Add a function to download the svg sent by the rust code, to the javascript code.

Document scaling

We need a system of document units within our (currently) infinite viewport. Then you can use the scale input area or zoom buttons to adjust that zoom.

Tool actions need to be projected from viewport space to canvas space. We actually probably will want some standard functions specifically for projecting between coording spaces that can be used by lots of code. In the future, you'll also be able to rotate the viewport's display of the canvas.

And then the canvas space needs to be shown at the correct pan and zoom (and rotation) in the viewport.

Build the document journal (history chain)

Generate inverse operation for a given operation and store both in the document.
This will be used to implement the history feature

Store a chain of history events and add the ability to navigate in it.

Should be done after: #134

Complexity: 5
Involves: Document (Rust)

Eliminate wasm-pack from build system

We are using wasm-pack and wasm-pack-plugin as dev dependencies. But we really should only need wasm-bindgen. The fewer dependencies, the better— especially because wasm-pack is apparently unmaintained and has a high-severity security vulnerability from a sub-dependency and upgrading to the patched dependency version has gone unfixed for nearly half a year. We do not need all the features of wasm-pack, it simply rolls together the separate parts of our Vue (through webpack) and wasm-bindgen build process. Let's fix the security problem and work towards removing non-vital dependencies.

Better GUI code error reporting

One important UX improvement for GUI component authors is providing clear and understandable error messages.

For now, we can just panic if the XML is invalid in any way.

The best solution is to use a crate like codespan, which would allow us to emit nicely formatted errors, just like the Rust compiler.

Implement the Path Tool for Bezier curve editing

  • Create a system for dealing with points.
  • The visualization part eventually involves the Viewport Overlays system (#99), but we can temporarily use the already-implemented system for "working layers" (shapes drawn to the canvas in a preview state before they get committed to the document).
  • De-conflicting clicks when multiple points are very close together (using Blender's method of picking the one based on distance from the mouse to the edge connected to that point, so you move your mouse closer to one side or the other of the path edge to prioritize one point or the other)
  • Points are extracted from all layers but not occluded by the fill of other layers (that's a complexity of behavior we can address later.)

Goes hand-in-hand with #185, the Pen Tool, which creates the Bezier paths similarly to how the Path Tool edits them.

Complexity: 3
Involves: Editor (Rust), Document (Rust)

Enforce standard Rust code formatting

Running the repository through cargo fmt ends up reformatting almost all of the files.

Since this can end up being quite messy once the project gets larger, we should do a commit formatting the code now, and keep on using rustfmt consistently to keep the code formatted.

Add an opacity attribute for elements to be drawn translucently

While individual <box> and <text> primitive components have the ability to specify colors with an alpha value, it will often be necessary to make an entire widget translucent. Because of the way compositing multiple layers with opacity works, setting all descendant elements to semitransparent will not produce the required result. Instead, they must all be rendered with their full opacity and then the resulting component (with its children inside) can be composited into the rest of the UI render with the percent value specified in a new opacity layout engine attribute (which defaults to opacity="100%").

Extract layout attributes into a separate structure

Right now, the layout attributes (such as width or padding) are stored together with other, user-defined attributes in the attributes vector:
https://github.com/Keavon/Graphite/blob/c41710ab7696799d6d81974eee3768d01c58c60c/src/layout_abstract_syntax.rs#L23
To store these more efficiently, and to simplify the downstream code, the parser should extract these attributes and store them into a Rust structure. Something similar to this:
https://github.com/Keavon/Graphite/blob/c41710ab7696799d6d81974eee3768d01c58c60c/src/layout_dom_node.rs#L8-L12
But instead of f32s, width and height would store a Dimension.

If the parser notices a node has a value given for a layout attribute, for example width = "10px", it will store it as is (Dimension::AbsolutePx(10.0)). Otherwise it will use the default value (in this example, Dimension::Inner for unspecified width).

How to contribute?

Hi, the project's vision described in the readme is really cool. However, there aren't a lot of open issues.

Since the readme says

The project is seeking collaborators to help design and develop the software.

would it be possible to get an idea in which stage the project is, and how we can help?

Node graph-based viewport overlays system

Tools need a way of supplying overlays to be drawn on top of the canvas. These can be globally or selectively disabled with the Overlays button:

(Overlays are globally disabled by clicking the checkbox area, selectively disabled by clicking the popover dropdown arrow and clicking on various types of specific overlays to disable)

Various types of overlays will come from:

  • The bounding box around the selected objects when using the Select Tool:
  • Similar to above, subtle bounding boxes indicating which which layers are being hovered over (which clicking at that moment would then select) when using the Select Tool
  • The points used to connect and control the flow of gradients in the Gradient Tool (example in Illustrator:)
  • All the vector shape points and handles when using the Path Tool and Pen Tool
  • Spline points when using the Spline Tool

There is similar concept related to overlays which always appear and don't get affected by the Overlays toggle. These are fundamental visualizations provided by the tools for their own interactivity, such as:

  • A box selection with the Select Tool
  • The window, rule-of-thirds, handles, and peripheral darkening of the Crop Tool
  • Floating interactive mouse-centric UI widgets like color sample preview from the Eyedropper Tool
  • In the Brush Tool, some sort of brush preview showing the angles of the bristles or the size and shape of the textured brush pattern
  • In the Clone Tool, it would show the corresponding area of the canvas being actively sampled from while drawing

These would be drawn on a layer above the overlays you can enable/disable with the setting described earlier. However they will probably use the same overlay system code.

Overlays will be rendered as an SVG string over the top of the document viewport.

Complexity: 5
Involves: Frontend (JS), Editor (Rust), Document (Rust)

Change how Vue sends input to the backend

We are currently binding keys in Vue. This was set up as a temporary measure. We'll want to properly send input events to the WASM code without involving Vue. Some considerations:

  • All keyboard input should be sent to the WASM
  • Only mouse inputs targeting the viewport should be sent, not those involving clicks on GUI elements
  • Mouse that has dragged outside the viewport should continue to be sent until (and including) release
  • Properly handle (to the best of its abilities) events when the application has been removed from focus in the OS
  • Use input to outside-the-viewport items to help reconstruct the status of inputs that may have been interrupted while mouse button was down in a viewport interaction and then focus lost
  • Support multiple panels at once
  • Generic approach so it can be used in other panel types, like the Layer Graph
  • Consideration should be put into pen inputs, and other types of input devices

Design the render engine architecture

Let's kick off this module with a meeting on Discord next weekend (Feb 27 or 28).

Before then, I am going to write up documentation on how the node system in Graphite behaves (so it isn't all just living in my mind) so we can glean the necessary technical requirements.

Then we can discuss what Rust/WGPU architecture will make this work.

Pick times you are available to meet: http://whenisgood.net/qkgaq4k

Make the show/hide layer button work

Start with core\editor\src\dispatcher\mod.rs:40 and plumb the state updates through the document layer system's visibility state. It needs to end up in the state encoded in a LayerPanelEntry in core\document\src\response.rs:9 which gets sent through the WASM back to the frontend.

Scripting Language: What about WASM instead?

Discussion

I know this might be early but I just stumbled on to this project (great work by the way) and noticed that you plan to support scripting via javascript. That probably makes sense, but I wanted to at least throw out a thought I've been having about scripting for my projects and that's using WASM instead of Lua/javascript. This would allow any language that compiles to WASM to be used for scripting...

Just a thought for the owner(s). Sorry if this is too early or too late, just trying to share an idea!

Resources

Rust, WebAssembly, and the future of Serverless by Steve Klabnik

Layer system for SVG elements in the document

We need to eventually draw a layer panel with a layer stack (with folders, so it's a tree structure). Each layer is used to keep track of a Kurbo shape in memory, and to allow the user to select the shapes and modify them (instead of just adding new shapes like we do right now). Then we will need each modified Kurbo shape to request a rerender (into SVG element syntax) and an update to the attributes of the existing SVG element (or addition or removal of elements in the SVG tag when a shape is added or deleted).

GUI overlay layer(s)

The root component in the base layer is drawn on the window with the window's dimensions, and it does not allow anything to be drawn outside of its parent container component. Tooltips, dropdown menus, popovers, modal popups, and tabs in the process of being dragged around are examples of overlays that will be needed in Graphite. These will be rendered in a layer above the base UI.

Many overlay menus will be drawn with 90% opacity, which should probably get specified using the regular system for that which works for components in the regular window base layer.

For flexibility, it probably makes sense to build a layer system instead of hardcoding one base layer and one overlay layer. Each component drawn with the layer system would be given an "outwards-pushing" (px or inner) width and height, as well as x and y coordinates. The base layer for a window (such as the one instantiating windows/main.xml or others in the windows folder) would have a width and height equal to the window and x="0px" and y="0px" (% of the window width/height may be convenient also, like for easily centering modals or a welcome splash screen). Layers above it, for tooltips and such, would be probably from an overlays folder (by convention) and they would have a smaller width and height as well as x and y values to align the overlay with the appropriate placement in the base layer (for example, the selection portion of a dropdown menu would be aligned underneath the collapsed button portion and set to a width equal to that width).

To accommodate the unknown height of dropdown menus or width of tooltip text, would need to allow inner in addition to absolute px dimensions. This should work just fine, but % and @ would not be allowed for the outermost (root) container called by the layer system.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.