{"id":13619724,"url":"https://github.com/aluntzer/gtknodes","last_synced_at":"2025-04-14T16:32:38.524Z","repository":{"id":51276978,"uuid":"205883304","full_name":"aluntzer/gtknodes","owner":"aluntzer","description":"A GTK-based library to create functional flow graphs with the ability to pass arbitrary data between connected elements.","archived":false,"fork":false,"pushed_at":"2024-01-01T21:22:57.000Z","size":6871,"stargazers_count":89,"open_issues_count":7,"forks_count":10,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-08-01T21:41:49.731Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aluntzer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2019-09-02T15:14:39.000Z","updated_at":"2024-07-21T18:54:19.000Z","dependencies_parsed_at":"2023-02-18T04:31:12.488Z","dependency_job_id":"2108bb08-a342-44a5-8444-05344cac06c4","html_url":"https://github.com/aluntzer/gtknodes","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aluntzer%2Fgtknodes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aluntzer%2Fgtknodes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aluntzer%2Fgtknodes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aluntzer%2Fgtknodes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aluntzer","download_url":"https://codeload.github.com/aluntzer/gtknodes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223638170,"owners_count":17177753,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T21:00:47.562Z","updated_at":"2024-11-08T05:31:56.387Z","avatar_url":"https://github.com/aluntzer.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"# GtkNodes\n\nThis library provides a (hopefully) easy-to-use interface for the creation\nof functional flow graphs with the ablility to pass arbitrary data\nbetween connected elements.\n\nThe flow graph is managed in NodeView, which is a graphical connection manager\nfor the graph's functional element (Nodes). Nodes are custom GtkWidget\ncontainers (derived from GtkBox), which hold one or more items (i.e. other\nwidgets). When a widget is added to a node, it will be assigned a NodeSocket,\nwhich represents (and manages) the actual connectivity between nodes.\n\nA NodeSocket can be configured in one of 3 modes: SINK, SOURCE and DISABLE.\nSINKs accept a single input and are connected to a SOURCE by a drag-and-drop\noperation from a source socket to a sink socket. SOURCEs can have an arbitrary\nnumber of connected outputs.\nA socket in SINK mode will be displayed vertically centered to its associated\nwidget and on the left edge of the node, while sockets in SOURCE mode are\ndrawn on the right edge of the node. Sockets in mode DISABLE are simply not\ndrawn.\n\nExisting connections can be modified in the NodeView by drag and drop.\nIf a connected sink receives a new connection from a source, it will disconnect\nfrom its previous source and connect to the new input.\nIf a drag operation is started on top of a connected sink, its source will be\ndisconnected and the drag event will be redirected to the source, just as if\nthe user had initiated the drag event on the source.\nThis method is also how the user would drop an existing connection between\nnodes: by starting the drag on the sink and then simply aborting the drag.\n\nIn order to ensure (data format) compatbility between nodes, a numerical\nkey can be configured. If the key changes, or a connection to a socket with an\nincompatible key is attempted, the connection will be either dropped or rejected.\nA key value of 0 for sinks is special, in that they will accept any input.\n\nIn order to visualize compatible sockets, an RGBA value can be set.\n\n\n## Nodes\n\nThe Node widget is a widget container drived from #GtkBox.\nWidgets added to the node are assigned a NodeSocket. The user must\nconfigure the type of socket and connect to the *socket-incoming* signal\nin order to be able to receive the data passed through a connection.\n\nThe Node can be collapsed by clicking the #GtkExpander which will hide the\nnode items, and show a compact representation of the node with just the\nGtkExpander and the sockets visible.\n\n\u003e **_NOTE:_** When adding a node to the NodeView, make sure to call\n\u003e gtk_widget_show_all() on the Node widget to show the widget along with the\n\u003e content. This was changed from the previous behaviour where\n\u003e gtk_nodes_node_view_add() called show_all() on the NodeView, leading to\n\u003e undesirable effects when adding new nodes.\n\n\n## Data Exchange\n\nTo receive data on a socket, connect to the \"socket-incoming\" signal\njust as you would for any other Gtk/Glib signal.\n\nAll data are passed encapsulated in a GByteArray in order to accomodate arbitrary formats\nand also so that Nodes can be introspected and used with other languages.\n\nTo write data on a socket, a function is provided which requires the\nsocket reference (can be retrieved when adding an item to a Node) and a\nGByteArray as input.\n\n\n## Ability to save and restore graphs\n\nAll reconstruction of graphs is handled by GtkBuilder. This means that\nall individual nodes must be implemented as subclasses of the Node widget,\nso GtkBuilder can locate, create and add them to a node view.\n\nThe NodeView widget provides load/store functions for this purpose.\n\n### Internal states\n\nCustom GtkNodesNode widgets can save and restore their internal child\nwidget states and other properties and special tags by implementing\nthe proper GtkBuildable interfaces. To export the configuration,\nnode_export_properties() must be implemented and is expected to return\nvalid xml output which is integrated into the xml output produced\nby #GtkNodesNodeView.\n\nFor example, to restore the value of an internal spin button widget,\nthe function would return an allocated string containing:\n\n```xml\n\u003cchild internal-child=\"spinbutton\"\u003e\n     \u003cobject class=\"GtkSpinButton\"\u003e\n     \t\u003cproperty name=\"value\"\u003e5\u003c/property\u003e\n     \u003c/object\u003e\n\u003c/child\u003e\n```\n\nThe weird thing is that GtkBuilder apparently wants to add the internal\nchildren to the GtkNode widget, even though the \"internal-child\" property is\nset. This obviously fails, resulting in a warning message,\nhowever the restoration of the child's property succeeds. I have not\nyet figured out, why this is the case, maybe this requires another builder\nclass function to be implemented, or I may have misunderstood the intention\nof \"internal-child\".\n\nExample nodes demonstrating this functionality are found in examples/nodes/node_step.c for\nthe C demonstrator and in class NumberNode for the Python demo (examples/img.py).\n\n\n# API\n\nYou can find a gtkdoc rendering of the API [here](https://uviespace.univie.ac.at/gtknodes/index.html).\n\n\n# Screenshots\n\nFrom the C demo: an 8-bit binary adder with 9 bits of output\n\n![BinAdder](./screenshots/binary_adder.gif)\n\n\nThe Python example: applying image filters using NumPy, SciPy and Matplotlib\nplus a random calculator node controlling plot parameters\n\n![ImgFilter](./screenshots/img_filter.gif)\n\n\nAn actual use case: freely programmable observations for my radio telescope\ncontrol software. The nodes integration is only preliminary, but what\ncan already be constructed very easily in this example is a grid observation\nprogram in a celestial coordinate system (Horizon, Equatorial or Galactic)\nand the application of a filter to the spectral data received by the telescope.\n\nIf you want to try it for yourself, see [radtel](https://github.com/aluntzer/radtel).\nThe nodes support is still incomplete, you can find it on the *gtknodes* branch.\n\n![RadTel](./screenshots/radtel.gif)\n\n# Building\n\nIf you want to use this library from python or any other language using\ngobject introspection bindings, make sure the build tools (g-ir-scanner,\ng-ir-compiler). If bindings are still not generated, enable introspection\nexplicitly:\n\n\n```\n./configure --enable-introspection=yes\n\n```\n\nIf you want to try the python example without installing the library system-wide,\nmake sure to export the proper paths, i.e. from the examples/ subdirectory\nrun the demo like this:\n\n```\nGI_TYPELIB_PATH=../introspection/ LD_LIBRARY_PATH=../src/.libs python img.py\n```\n\n\n# Build dependencies \n\nUbuntu:\n\n```\nsudo apt install \\\n  gobject-introspection \\\n  gtk-doc-tools \\\n  libtool \\\n  autoconf \\\n  automake \\\n  libgladeui-dev \\\n  libgirepository1.0-dev\n\n```\n\n# Packages\n\nArch Linux:\n\nAvailable in AUR as [gtknodes-git](https://aur.archlinux.org/packages/gtknodes-git/)\n\n\n# Notes\n\n- I realise that this description is be a bit brief at this time, but you may\n  want to check the examples subdirectory for implementations of a NodeView\n  and Nodes in both C and Python. These examples cover pretty much every\n  aspect of this library.\n\n- While possible, using a GtkNodesNode outside of a GtkNodesNodeView does \n  not make much sense.\n\n- The placement of sockets is currently only properly supported for the\n  GTK_ORIENTATION_VERTICAL orientation\n\n- If the nodes and node viewer seem familiar to you, note that they were\n  heavily inspired by how nodes work in Blender.\n\n- I realize that there are lot of features you might want to see right now,\n  such as snap-to-grid, auto-layout, zoomability, or one thing I'd like to\n  have in the near future: collapsible node groups (essentially a Node with a\n  NodeView inside). All of this will have to wait bit, unfortunately, I'll be\n  short on time for a while. I accept patches though :)\n\n\n\n# Licensing\n\nGtkNodes is released under the terms of the GNU Lesser General Public License,\nversion 2.1 or, at your option, any later version, as published by the Free\nSoftware Foundation.\n\nPlease, see the [`COPYING`](./COPYING) file for further information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faluntzer%2Fgtknodes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faluntzer%2Fgtknodes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faluntzer%2Fgtknodes/lists"}