Giter Site home page Giter Site logo

karta's Introduction

Karta

Demo gif

Disclaimer

This project is in its very early stages and is therefore highly experimental, barely usable and not really useful yet. Most of the mentioned features are planned but not yet implemented. Developed on Linux, not tested on Windows, tested but not certified on MacOS.

Introduction

Karta is a node-based file explorer and compositor. It creates a network out of a selected section of the file system and allows for files and folders to be arranged spatially and for arbitrary connections to be made between them. Attributes may be added to any node or connection. This network could then be queried for various purposes, though chiefly intended for structuring creative projects and making media art.

The project is free and open-sourced under a GPL license.

For a more detailed explanation of the project's purpose and goals, refer to docs/vision.md. For technical details refer to docs/architecture.md.

Key features:

  • Local first - the files and network database exist locally on your machine. No lock-in. The goal is to keep the storage format well documented and allow for syncing and exporting to plain text files.
  • Contextual - nodes don't have absolute spatial positions, but rather contextual ones. Since the network is always viewed from the point of view or "context" of some individual node, the positions of its connections are always relative to it. Two nodes can be positioned differently relative to each other depending on which context you look from.
  • Simulated - node arrangement may be force simulated. Currently not much more than a novelty, but the idea is to provide a varied selection of arrangement tools to free the user up to focus more on the content, especially when creating many nodes at once.
  • Virtual nodes - not all nodes have to physically exist in the file system. You can create "virtual" nodes of different types that get stored directly in the database.

Plans / wishlist

  • Operator nodes - a system for creating functional nodes with inputs and outputs that can manipulate data, like in other node-based programming tools. Useful for quick edits and experimentation right in the file explorer.
  • Rich previews - a system for adding custom preview generation support for any file type.
  • Composition - the ability to package a selection or sequence of nodes into a file, such as a series of images into a pdf or gif.
  • Presentation - support for displaying the previews of active nodes in the graph background or a separate window.
  • More dreamy ideas over in docs/vision.md

Getting Started

  • Make sure you have Rust installed. Karta uses the Bevy game engine so familiarity with it is recommended.
  • Clone the repo
  • Build and run

Usage

At first startup, you will be asked to choose a folder to create your vault in. Once set up, the contents of that folder will be spawned in as a force-directed graph. Middle-mouse click to pan the view and scroll to zoom. Dragging from the edge of a node to another will create a new connection between those nodes. Right-clicking on a node will bring up a menu where you can pin and unpin nodes (to be ignored by the force simulation) and move to another nodes' context.

Contributing

It's much too early for me to ask or hope for contributions. The most valuable thing you might contribute at this stage is sharing your thoughts about the project and discussing it with me, to help clarify the path forward. I am active in the Bevy discord, so you may find me there under the same username.

Use the develop branch for the most up-to-date version. Main is for stable-ish releases.

Development

Development within docker container

For those who don't want to install the development environment directly to their computers, it is possible to develop Karta within an isolated Docker container. You can build the image and run the container from the project root directory by typing:

docker compose up

This command will build the karta-rust-devenv docker image, if it does not already exist, and start the container. After that it is possible to run e.g. VSCode and connect to this running container by executing the "Dev Containers: Attach to running container" command, and chose the correct container. This will open a new VSCode instance which is now running within our rust development container. If you install rust- or any other plugin to VSCode, it will be valid only when running this container.

The project directory is to be found in /project directory. Use the terminal from VSCode to run any command within the context of docker container.

karta's People

Contributors

teodosin avatar isokissa avatar dependabot[bot] avatar

Stargazers

 avatar Mr.XY avatar charlotte avatar Miro Keimiöniemi avatar  avatar Mike avatar Tom Rindell avatar Shujaat Ali Khan avatar Toby avatar Mincho Paskalev avatar  avatar Andrey Lysenko avatar David Sanders avatar  avatar Peter avatar  avatar

Watchers

 avatar  avatar

Forkers

rustworks

karta's Issues

Crashes when trying to create vault (Mac)

On Mac, it crashes when I pressed the "Create vault" button. The following text is shown in the terminal:

Setting up Move actions
Config dir: "/Users/phz945/Library/Application Support/com.Teodosin.Karta"
Full path: "/Users/phz945/Library/Application Support/com.Teodosin.Karta/karta.vault"
Vaults file does not exist
Vault changed to: None
Saving vaults
No vault set
Config dir: "/Users/phz945/Library/Application Support/com.Teodosin.Karta"
Full path: "/Users/phz945/Library/Application Support/com.Teodosin.Karta/karta.vault"
No vault set
No vaults to save
Despawning context menus
Creating edge from drag
fatal runtime error: Rust cannot catch foreign exceptions

Guess: is it OK for path to contain whitespaces?

Double-click support

I don't know how this would be done in Bevy. The implementation I think I could complete would be very verbose and complicated, maybe prone to error. There should be an idiomatic way to do this, and I will wait for that for now.

Separate visual presentation of a node from the entity

For two reasons.

  • This will allow different types of nodes to look entirely different in the graph editor. There won't need to be for a universal minimum style, though there will be templates.
  • This isn't as immediate, but eventually there will be situations when we will want to evaluate a node without creating it in the graph. For example, for creating stand-alone executables from certain collections of nodes. Those wouldn't expose a node editor to the user, instead just show the content.

Warning before opening folder with a ton of files

When opening the context of a folder with a lot of files for the first time, there should be a popup dialog to choose whether to spawn all the files or not. This could be a good opportunity to split up the update_context function a bit.

Hovering toolbar for selected

A hovering menu with various actions floating above the current selection. The purpose of this is to increase visibility for some commonly used actions as opposed to tucking them away in the context menu.

Node sockets

Nodes will eventually need sockets. Here are some possible requirements.

A node could have a generic output socket hovering next to it at all times. Dragging from it to any node will create a generic connection between the two nodes. This would eliminate the need for a separate "Edges" mode, as long as it's straightforward to set the template for attributes.

There will also be nodes with specific inputs and outputs, such as operators. These sockets are in addition to the generic connection socket. Input are one-to-one, outputs one-to-many, as is tradition.

The positions of the sockets should be overridable by the node in question, but also with a global setting. Or there could be several configurations for the sockets which can be chosen by me or even the user. This is to allow for the unprecedented flexibility to choose the direction in which the node tree flows. Even if there ends up being a "best" direction, incorporating this flexibility could be useful in some situations and also increase the potential of Karta to become a generic graph editor library.

Make ui module reactive to graph changes

Currently the graph has to send events like "NodeSpawnedEvent" and "EdgeSpawnedEvent" that the ui module listens for and then inserts the appropriate components to those entities. This could instead be accomplished by a query for "Added" where T is a marker component for an entity that should have a graph representation.

Also, the ui nodes should become separate entities from the underlying data they are referencing. But that is a more complex task that requires systems to keep the two in sync, so it is a separate issue. #67.

These changes will also be necessary when the graph eventually becomes a standalone crate. Then users will just be able to add the marker component to the entities that they want to be displayed in the graph and it would work out of the box. And since they are separate entities they can have separate instances of components like Transform, which is obviously important for any entity that exists in 3D space.

Context history

Allow the user to return to previous contexts without having to locate the correct node. Important for usability.

This will have repercussions for the general undo/redo system, because those actions will have to be able to operate on pure data regardless of the currently spawned or visible entities. Otherwise contexts would have to have individual histories, and that could mess things up even further.

A simple solution for now would be to just reset the history every time the context changes. It's yucky but would avoid a lot of problems that might be worth deferring to the future.

Clickable, Hoverable Node Outline

An important UX feature. There should be a customizable outline around nodes. Square and circular variations. Should be able to smoothly expand or contract. Any color. Should be hoverable, clickable and selectable.

Fix force sim vibration

Sometimes when a node gets stuck between too many forces it begins vibrating violently. This should never happen.

Zoom in and out of contexts

Like TouchDesigner does it! Would be cool if this was smooth and seamless. An aesthetic experience.

Could be cool, but needs a polished implementation. Also somewhat conflicts with #7 . Also the positional interpolation of nodes that exist in both contexts would need to be disabled and they would all have to be despawned anew, with the camera position reset. This will need a couple iterations and some user testing.

Feature parity with Nemo file browser

Note: before a colossal task like this is undertaken, it should be determined if it's A: feasible and B: desirable. A professional and time-tested file browser like the ones shipping in these multi-billion$ operating systems is not easy to replicate. They are stable and reliable (I assume) so I don't want to bite off more than I can chew.

I think that desirability is largely determined by how light of a performance footprint Karta could have when it's not running its more intensive systems such as rendering, operators and so on. If it can be as light and simple to use as Nemo, then it stands a chance to be used as someone's main file browser.

Support for non-unicode characters in paths

File and context paths are currently serialized as strings. Context files also cause problems here. Because users might have files with the same name but different extensions in the same directory, we can't just replace the extension with .context for the context file, because we might cause a conflict. So we want to keep the original extension but add .context at the end. PathBuf doesn't support this directly for whatever reason, so the intermediate solution was to convert the path into string and add the extension manually.

UI Node base implementation

The foundation for implementing all UI panels and windows as nodes that can be moved around or locked in place. This will also be a test for using bevy_mod_picking for UI interaction.

Since there's currently only one UI element (the current context path bar), refactoring it to use this new system is also part of this issue.

The goal is to eventually merge the regular graph nodes and UI nodes and allow for moving a node from one environment to the other by way of a UI pin. This should wait however until Bevy UI is mature enough to be used in world-space (and until there's rounded corners).

Graph Editor Architecture

Tracking issue and summary for determining the proper architecture for the graph entity crate. The goal is to separate this into a standalone crate that can be used by any bevy project.


  • Make ui reactive to the underlying data entities #65

  • Group all relevant files and submodules under a single module #73

  • Move forces to bevy_overlay_graph

  • Separate data and view nodes into their own entities #67

  • Clarify and clean up dependencies (must not be dependent on Karta, Karta depending on BOG is ok)

  • Component property panel (blocked by #66)

  • ?

  • bevy_overlay_crate git submodule

  • bevy_overlay_crate public, usable through github

  • 0.1 on crates.io

Resources

Move graph_cam and simulation to ui module

graph_cam.rs and simulation.rs currently reside in the graph module, which should only deal with the underlying data structures of the graph. Move them to the ui module where they belong.

Fix selection jankiness

There are several issues with how selections currently are. They are broken, basically.

  • No visual indicator of what is selected
  • Shift modifier doesn't properly affect multi-select
  • Context menu doesn't appear if a node is selected / just moved

Node scaling?

An interesting potential feature. Superfluous? Maybe. Maybe it would make the node graph too complicated. On the other hand, it would unlock a whole lot of potential for it, things like semantic or dynamic zooming into contexts or whatever.

Initial saving and loading of contexts

Requirements:

  • Save nodes in a vec

  • Path of each node (file name is the name of the node. Virtual nodes also have file names, PathBuf doesn't apparently care whether a path is valid or not)

  • Type of each node (for now, maybe in the future it can be in the form of a file extension on virtual nodes?)

  • Optional: Node attributes (Don't exist yet, so make those as well)

  • Optional: Relative position of pinned nodes to context focal

  • Optional: Pins on node (position and presence)

  • Edges in a vec (directory parent edges are implicit, but have to be included because they may have attributes?)

  • Source and Target

  • Edge type

  • Directed (Is the connection one-way or two-way? No specific use-case in mind for this yet though )

  • Optional: Edge attributes

Contexts might have their own settings eventually, but not yet. Or maybe those will also be implemented as nodes.

My earlier implementation of Contexts as a bevy Asset might be completely unnecessary. The context files are just meant to be deserialized once into the relevant entities and don't need to hang around and be referred to. So simple saving and loading functions should suffice.

Handle duplicate paths

Handle duplicate node paths.

For now this mainly concerns virtual nodes, because they have default names upon creation. Since they are named after their node type, there will be a lot of duplicates if many of the same type are created. A number suffix should be added to each node:

Text Card
Text Card 1
Text Card 2
etc

Suffix will suffice for now.

Play mode

After all the work gone into designing a graph network, it would make sense to provide a curated way to interact with it.

The proposal is to implement a "play mode", where a selection of editor tools would be disabled and nodes could have actions assigned to them that are executed when they are clicked. The network author would choose the ways of interaction allowed in this mode.

The foundational idea here is that for any node, an action can be selected that is performed when the node is clicked in play mode. For example, a click on one node could change the context to that node. A click on another would play an animation in the scene layer. A click on a third would toggle some small area of the network to collapse or expand. A fourth would create a new node next to it.

A play mode could lead to:

  • Performance and presentation capabilities
  • Exporting networks as native executables or wasm apps
  • In-app tutorials for Karta

Expanding and collapsing node contexts

To accomplish this, the update_context system needs to be divided up.

Update_context should then only spawn the root node of a context and then send a "request context expansion" as an event. This way there can also be a pause when a new context is spawned, in the case of large folders where we might not want to spawn and simulate everything and instead give the user an option.

Request context expansion should handle both changing of contexts and the expansion of nodes within a context. There is not a meaningful difference between the two.

In-app tutorials

I would love it if all the features of Karta could be explained in some hand-crafted and protected contexts that ship with the app. That would be so elegant.

Force-direction MVP

Implement the basic algorithm for force-direction.

  • Spring forces between all edges (k-value should be changeable at some point, but not in this issue
  • Repulsive forces between all nodes

Something to experiment with: Doing the entire simulation in one timestep, and then interpolating the nodes to their new positions.

I want to try implementing this as a "Force" node, which, when placed in a context, performs the simulation continually. Or only when clicked.

There's also the "Arrange" mode, which should eventually support many different types of arrangement on selected nodes. Not part of this issue though.

File Browser features MVP

File Browser features needed for the mvp. All of them will also need to handle context files appropriately.

  • Renaming files
  • Moving files (from context menu AND from reconnecting directory edges)
  • Creating folders and files
  • Deleting folders and files (only to system trash, no permanent deletion!!)

SEARCH

Being able to search for any node in the vault to spawn is very important. This feature will need a lot of work though. Some initial thoughts:

  • Maybe ripgrep
  • Do I need some sort of indexing then? An embedded surrealDB database?
  • The pop-up text box and search dialog needs a well thought out implementation

Expand and collapse nodes

At first, expanded nodes shouldn't sync their positions with their parents context. They can be pinned or simulated, but their pinning will either not be saved or will be saved in the currently active grandparent or great grandparent context. You know what I mean?

Actions

To be a usable application, Karta needs undo and redo functionality.

The base solution is to wrap every possible user action into an Action struct and save their sequence to get a rewindable action history. This issue is about implementing this base.

The implementation should leave open the possibility for macros and for some day maybe even creating an action graph. In truth, it would be most elegant if Operators and Actions shared as much code as possible. Maybe Actions evolve to encompass Operators, instead of the other way around like I originally envisioned.

Something to think about is the storing of the data. Actions involving deleting OR changing data need to store that data in order for the action to be reversible. At first I was thinking that actions that create data don't need to store it, then I remembered redo. So yea, those too.

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.