### Accessing the Extensions API Source: https://context7.com/orama-interactive/pixelorama/llms.txt Demonstrates how to get a reference to the ExtensionsApi autoload and retrieve basic information like API and Pixelorama versions. ```APIDOC ## Accessing the Extensions API ### Description This section shows how to obtain the `ExtensionsApi` instance and retrieve the API version and Pixelorama version. ### Method `get_node_or_null("/root/ExtensionsApi")` to get the API instance. `api.get_api_version()` to get the API version. `api.general.get_pixelorama_version()` to get the Pixelorama version. ### Code Example ```gdscript var api = get_node_or_null("/root/ExtensionsApi") func _ready() -> void: if api == null: push_error("ExtensionsApi not found") return var version: int = api.get_api_version() print("Running Pixelorama ExtensionsApi version: ", version) var pix_version: String = api.general.get_pixelorama_version() print("Pixelorama version: ", pix_version) # e.g. "1.1.10" ``` ``` -------------------------------- ### Build Click Package Source: https://github.com/orama-interactive/pixelorama/blob/master/Misc/Clickable/README.md Navigate to the Clickable directory and run the build command to create the click package. ```bash $ cd Misc/Clickable $ clickable build ``` -------------------------------- ### Build for Multiple Architectures Source: https://github.com/orama-interactive/pixelorama/blob/master/Misc/Clickable/README.md Use the CLICKABLE_ARCH environment variable to specify target architectures for building. Recommended architectures include armhf and arm64. ```bash $ CLICKABLE_ARCH=armhf clickable build $ CLICKABLE_ARCH=arm64 clickable build ``` -------------------------------- ### GeneralAPI - Core Utilities Source: https://context7.com/orama-interactive/pixelorama/llms.txt Explains how to use the `general` sub-API to access core autoloads, the canvas node, and create UI elements like sliders. ```APIDOC ## GeneralAPI — Core Autoloads and Utility Nodes ### Description `ExtensionsApi.general` provides access to Pixelorama's primary autoloads (`Global`, `DrawingAlgos`), the canvas node, shader effect helpers, and UI slider factories. ### Methods - `api.general.get_global()`: Returns the Global autoload. - `api.general.get_drawing_algos()`: Returns the DrawingAlgos autoload. - `api.general.get_canvas()`: Returns the Canvas node. - `api.general.get_new_shader_image_effect()`: Creates a new ShaderImageEffect instance. - `api.general.create_value_slider()`: Creates a 1D float slider. - `api.general.create_value_slider_v2()`: Creates a 2D Vector2 slider. - `api.general.create_value_slider_v3()`: Creates a 3D Vector3 slider. ### Code Example ```gdscript var api = get_node_or_null("/root/ExtensionsApi") func apply_shader_to_current_cel() -> void: var global = api.general.get_global() # Global autoload var algos = api.general.get_drawing_algos() # DrawingAlgos autoload var canvas = api.general.get_canvas() # Canvas node # Apply a custom shader to the current cel's image var shader_effect: ShaderImageEffect = api.general.get_new_shader_image_effect() var my_shader: Shader = preload("res://my_extension/grayscale.gdshader") var project = global.current_project var cel = project.get_current_cel() # BaseCel if cel.get_class_name() == "PixelCel": var img: Image = cel.image var params := {"intensity": 1.0} shader_effect.generate_image(img, my_shader, params, project.size) await shader_effect.done cel.update_texture() # Create value sliders for custom tool UIs var slider = api.general.create_value_slider() # 1D float slider var slider_v2 = api.general.create_value_slider_v2() # 2D Vector2 slider var slider_v3 = api.general.create_value_slider_v3() # 3D Vector3 slider ``` ``` -------------------------------- ### Extension Entry Point - Main.gd Source: https://context7.com/orama-interactive/pixelorama/llms.txt The Main.gd script serves as the entry point for a Pixelorama extension. It interacts with the ExtensionsApi to add tools and manage signals. Ensure API version compatibility. ```gdscript # res://my_extension/Main.gd — the extension entry point extends Node var api = get_node_or_null("/root/ExtensionsApi") func _enter_tree() -> void: if not api or api.get_api_version() < 1: api.dialog.show_error("Incompatible API version!") return api.tools.add_tool("MyStamp", "Stamp", "res://my_extension/StampTool.tscn") api.signals.signal_project_created(_on_project_created) func _exit_tree() -> void: api.tools.remove_tool("MyStamp") api.signals.signal_project_created(_on_project_created, true) func _on_project_created(project) -> void: print("New project created: ", project.name) ``` -------------------------------- ### Create and Select Palettes with ExtensionsApi.palette Source: https://context7.com/orama-interactive/pixelorama/llms.txt The `ExtensionsApi.palette` API allows programmatic creation and activation of palettes. Palettes can be created as global (user-wide, persisted) or project-local. Access the `Palettes` autoload for deeper operations like selecting a palette. ```gdscript var api = get_node_or_null("/root/ExtensionsApi") func create_game_boy_palette() -> void: var palette_data := { "width": 4, "height": 1, "comment": "Classic Game Boy 4-color palette", "colors": [ {"index": 0, "color": "(0.608, 0.737, 0.059, 1)"}, {"index": 1, "color": "(0.427, 0.651, 0.204, 1)"}, {"index": 2, "color": "(0.188, 0.392, 0.188, 1)"}, {"index": 3, "color": "(0.063, 0.247, 0.063, 1)"} ] } # Create as a global palette (persisted to disk) api.palette.create_palette_from_data("Game Boy", palette_data, true) # Create as a project-local palette api.palette.create_palette_from_data("Game Boy Local", palette_data, false) # Access Palettes autoload for deeper operations var palettes_autoload = api.palette.autoload() palettes_autoload.select_palette("Game Boy") print("Active palette: ", palettes_autoload.current_palette.name) ``` -------------------------------- ### Command-Line Batch Export with Pixelorama CLI Source: https://context7.com/orama-interactive/pixelorama/llms.txt Pixelorama supports headless batch exporting of .pxo files from the command line for automated pipelines. Use --headless --quit flags for non-interactive execution. ```bash # Print help ./Pixelorama --headless --quit -- --help ``` ```bash # Export a project to PNG ./Pixelorama --headless --quit -- project.pxo --export -o output.png ``` ```bash # Export as spritesheet with 2x scale ./Pixelorama --headless --quit -- project.pxo --spritesheet -o sheet.png --scale 2 ``` ```bash # Export specific frame range (frames 1-5) as GIF ./Pixelorama --headless --quit -- project.pxo --export -o anim.gif --frames 1-5 ``` ```bash # Export with split layers and JSON metadata ./Pixelorama --headless --quit -- project.pxo --export -o frame.png --split-layers --json ``` ```bash # Export animation in ping-pong direction (0=forward, 1=backward, 2=ping-pong) ./Pixelorama --headless --quit -- project.pxo --export -o anim.apng --direction 2 ``` ```bash # Print project metadata ./Pixelorama --headless --quit -- project.pxo --size ``` ```bash ./Pixelorama --headless --quit -- project.pxo --framecount ``` ```bash ./Pixelorama --headless --quit -- --version ``` ```bash # Windows: use rel-dir to resolve relative paths Pixelorama.exe --headless --quit -- rel-dir="%CD%" project.pxo --export -o output.png ``` -------------------------------- ### PaletteAPI — Create and Select Palettes Source: https://context7.com/orama-interactive/pixelorama/llms.txt Provides the ability to programmatically create, populate, and activate palettes, both as global (user-wide) or project-local palettes. ```APIDOC ## PaletteAPI — Create and Select Palettes `ExtensionsApi.palette` provides the ability to programmatically create, populate, and activate palettes, both as global (user-wide) or project-local palettes. ```gdscript var api = get_node_or_null("/root/ExtensionsApi") func create_game_boy_palette() -> void: var palette_data := { "width": 4, "height": 1, "comment": "Classic Game Boy 4-color palette", "colors": [ {"index": 0, "color": "(0.608, 0.737, 0.059, 1)"}, {"index": 1, "color": "(0.427, 0.651, 0.204, 1)"}, {"index": 2, "color": "(0.188, 0.392, 0.188, 1)"}, {"index": 3, "color": "(0.063, 0.247, 0.063, 1)"} ] } # Create as a global palette (persisted to disk) api.palette.create_palette_from_data("Game Boy", palette_data, true) # Create as a project-local palette api.palette.create_palette_from_data("Game Boy Local", palette_data, false) # Access Palettes autoload for deeper operations var palettes_autoload = api.palette.autoload() palettes_autoload.select_palette("Game Boy") print("Active palette: ", palettes_autoload.current_palette.name) ``` ``` -------------------------------- ### ProjectAPI Source: https://context7.com/orama-interactive/pixelorama/llms.txt Create and manipulate projects, including creating new projects, adding frames and layers, reading cel data, and writing pixel images directly to cels. ```APIDOC ## ProjectAPI — Create and Manipulate Projects `ExtensionsApi.project` enables creating new projects, adding frames and layers, reading cel data, and writing pixel images directly to cels. ```gdscript var api = get_node_or_null("/root/ExtensionsApi") func create_animated_project() -> void: # Create a 64x64 project named "My Sprite" with transparent fill var proj: Project = api.project.new_project( [], # frames (empty = one frame created automatically) "My Sprite", # name Vector2(64, 64), # canvas size Color.TRANSPARENT ) # Add 3 more frames after frame 0 for i in range(3): api.project.add_new_frame(proj.frames.size() - 1) # Add a named pixel layer above layer 0 api.project.add_new_layer(0, "Outline", Global.LayerTypes.PIXEL) # Select specific cels (frame 1, layer 0) and (frame 1, layer 1) api.project.select_cels([[1, 0], [1, 1]]) # Write an image to frame 0, layer 0 var img := Image.create(64, 64, false, Image.FORMAT_RGBA8) img.fill(Color.RED) api.project.set_pixelcel_image(img, 0, 0) # Read a cel var cel: BaseCel = api.project.get_cel_at(proj, 0, 0) print("Cel type: ", cel.get_class_name()) # "PixelCel" # Get full project info as dictionary var info: Dictionary = api.project.get_project_info(proj) print("Project size: ", info["size"]) ``` ``` -------------------------------- ### GeneralAPI: Canvas, Autoloads, and Shader Effects Source: https://context7.com/orama-interactive/pixelorama/llms.txt Utilize the GeneralAPI to access core autoloads like Global and DrawingAlgos, the canvas node, and helpers for creating shader effects and UI sliders. ```gdscript var api = get_node_or_null("/root/ExtensionsApi") func apply_shader_to_current_cel() -> void: var global = api.general.get_global() # Global autoload var algos = api.general.get_drawing_algos() # DrawingAlgos autoload var canvas = api.general.get_canvas() # Canvas node # Apply a custom shader to the current cel's image var shader_effect: ShaderImageEffect = api.general.get_new_shader_image_effect() var my_shader: Shader = preload("res://my_extension/grayscale.gdshader") var project = global.current_project var cel = project.get_current_cel() # BaseCel if cel.get_class_name() == "PixelCel": var img: Image = cel.image var params := {"intensity": 1.0} shader_effect.generate_image(img, my_shader, params, project.size) await shader_effect.done cel.update_texture() # Create value sliders for custom tool UIs var slider = api.general.create_value_slider() # 1D float slider var slider_v2 = api.general.create_value_slider_v2() # 2D Vector2 slider var slider_v3 = api.general.create_value_slider_v3() # 3D Vector3 slider ``` -------------------------------- ### SelectionAPI Source: https://context7.com/orama-interactive/pixelorama/llms.txt Programmatically control selections, including selecting regions, moving, resizing, copying, pasting, and creating brushes from selections. ```APIDOC ## SelectionAPI — Programmatic Selection Control `ExtensionsApi.selection` exposes the selection system for scripted workflows: selecting regions, moving, resizing, copying, pasting, and creating brushes from selections. ```gdscript var api = get_node_or_null("/root/ExtensionsApi") func scripted_selection_example() -> void: # Select a 32x32 rectangle starting at (10, 10) api.selection.select_rect(Rect2i(10, 10, 32, 32), 0) # 0=add, 1=subtract, 2=intersect # Get the image data enclosed by the current selection var enclosed: Image = api.selection.get_enclosed_image() print("Selected region size: ", enclosed.get_size()) # Copy selection content api.selection.copy() # Move selection (with its content) to position (50, 50) api.selection.move_selection(Vector2i(50, 50), true, false) # Resize selection content to 64x64 api.selection.resize_selection(Vector2i(64, 64), true, false) # Make a project brush from selection api.selection.make_brush() # Invert then clear api.selection.invert() api.selection.clear_selection() ``` ``` -------------------------------- ### Create and Manipulate Projects with GDScript Source: https://context7.com/orama-interactive/pixelorama/llms.txt Utilize the ProjectAPI to create new projects, add frames and layers, and directly manipulate cel data. Ensure the API node is accessible. ```gdscript var api = get_node_or_null("/root/ExtensionsApi") func create_animated_project() -> void: # Create a 64x64 project named "My Sprite" with transparent fill var proj: Project = api.project.new_project( [], # frames (empty = one frame created automatically) "My Sprite", # name Vector2(64, 64), # canvas size Color.TRANSPARENT ) # Add 3 more frames after frame 0 for i in range(3): api.project.add_new_frame(proj.frames.size() - 1) # Add a named pixel layer above layer 0 api.project.add_new_layer(0, "Outline", Global.LayerTypes.PIXEL) # Select specific cels (frame 1, layer 0) and (frame 1, layer 1) api.project.select_cels([[1, 0], [1, 1]]) # Write an image to frame 0, layer 0 var img := Image.create(64, 64, false, Image.FORMAT_RGBA8) img.fill(Color.RED) api.project.set_pixelcel_image(img, 0, 0) # Read a cel var cel: BaseCel = api.project.get_cel_at(proj, 0, 0) print("Cel type: ", cel.get_class_name()) # "PixelCel" # Get full project info as dictionary var info: Dictionary = api.project.get_project_info(proj) print("Project size: ", info["size"]) ``` -------------------------------- ### MenuAPI - Adding Menu Items Source: https://context7.com/orama-interactive/pixelorama/llms.txt Details how to use the `menu` sub-API to add custom menu items to Pixelorama's top menu bar. ```APIDOC ## MenuAPI — Add Items to Top Menu Bar ### Description `ExtensionsApi.menu` lets extensions insert and remove entries in any top-bar menu (File, Edit, Select, Project, Effects, View, Window, Help). ### Methods - `api.menu.add_menu_item(menu_type, display_name, metadata, item_id)`: Adds a menu item. - `api.menu.remove_menu_item(menu_type, item_id)`: Removes a menu item. ### Parameters #### `add_menu_item` Parameters - **menu_type** (Constant): The type of menu to add the item to (e.g., `api.menu.EFFECTS`). - **display_name** (String): The text to display for the menu item. - **metadata** (Node): A node that will receive the `menu_item_clicked` signal. - **item_id** (int): An identifier for the menu item (-1 for auto-assign). #### `remove_menu_item` Parameters - **menu_type** (Constant): The type of menu the item belongs to. - **item_id** (int): The ID of the menu item to remove. ### Code Example ```gdscript var api = get_node_or_null("/root/ExtensionsApi") var menu_item_id := -1 var my_dialog: Window # your extension's dialog node func _ready() -> void: my_dialog = preload("res://my_extension/MyDialog.tscn").instantiate() api.general.get_extensions_node().add_child(my_dialog) # Add "My Tool" under the Effects menu menu_item_id = api.menu.add_menu_item( api.menu.EFFECTS, # menu type constant "My Tool", # display name my_dialog, # metadata: node with menu_item_clicked() -1 # item_id (-1 = auto-assign) ) # menu_item_id can be used to remove the entry later func _exit_tree() -> void: if menu_item_id != -1: api.menu.remove_menu_item(api.menu.EFFECTS, menu_item_id) ``` ``` -------------------------------- ### Extension Manifest - extension.json Source: https://context7.com/orama-interactive/pixelorama/llms.txt The extension.json manifest file defines metadata for a Pixelorama extension. The 'nodes' field lists scene paths to be instantiated when the extension loads. ```json { "name": "my_extension", "display_name": "My Extension", "description": "Adds a custom stamp tool and export format to Pixelorama.", "author": "Your Name", "version": "1.0.0", "license": "MIT", "nodes": [ "res://my_extension/Main.tscn" ] } ``` -------------------------------- ### Register Custom Import Options with ExtensionsApi.import Source: https://context7.com/orama-interactive/pixelorama/llms.txt Use `ExtensionsApi.import.add_import_option` to add new import handler types that will appear in Pixelorama's import dialogs. Remember to remove the option using `remove_import_option` when exiting the tree to prevent memory leaks. ```gdscript var api = get_node_or_null("/root/ExtensionsApi") var importer_id := -1 var import_scene := preload("res://my_extension/MyImportOptions.tscn") # MyImportOptions.gd must implement: # var import_preview_dialog (auto-assigned: reference to ImportPreviewDialog) # func initiate_import(path: String, image: Image) -> void func _ready() -> void: importer_id = api.import.add_import_option("My Format (.myfmt)", import_scene) func initiate_import(path: String, image: Image) -> void: # Custom parsing logic — modify `image` in place or create a new project var project := api.project.new_project([], path.get_file().get_basename()) api.project.set_pixelcel_image(image, 0, 0) func _exit_tree() -> void: api.import.remove_import_option(importer_id) ``` -------------------------------- ### Add Custom Tabs to Dockable UI with PanelAPI Source: https://context7.com/orama-interactive/pixelorama/llms.txt PanelAPI allows adding custom Control nodes as dockable tabs. Ensure to remove the node when exiting the tree to clean up resources. ```gdscript var api = get_node_or_null("/root/ExtensionsApi") var my_panel: Control func _ready() -> void: my_panel = preload("res://my_extension/MyPanel.tscn").instantiate() my_panel.name = "My Panel" # name shown in tab and Panels menu api.panel.add_node_as_tab(my_panel) # Check/toggle tab bar visibility print("Tabs visible: ", api.panel.tabs_visible) api.panel.tabs_visible = false # hide all tab labels func _exit_tree() -> void: api.panel.remove_node_from_tab(my_panel) # cleans up and frees the node ``` -------------------------------- ### ImportAPI — Register Custom Import Options Source: https://context7.com/orama-interactive/pixelorama/llms.txt Allows adding new import handler types that appear in Pixelorama's import dialogs by registering a custom import option. ```APIDOC ## ImportAPI — Register Custom Import Options `ExtensionsApi.import` allows adding new import handler types that appear in Pixelorama's import dialogs. ```gdscript var api = get_node_or_null("/root/ExtensionsApi") var importer_id := -1 var import_scene := preload("res://my_extension/MyImportOptions.tscn") # MyImportOptions.gd must implement: # var import_preview_dialog (auto-assigned: reference to ImportPreviewDialog) # func initiate_import(path: String, image: Image) -> void func _ready() -> void: importer_id = api.import.add_import_option("My Format (.myfmt)", import_scene) func initiate_import(path: String, image: Image) -> void: # Custom parsing logic — modify `image` in place or create a new project var project := api.project.new_project([], path.get_file().get_basename()) api.project.set_pixelcel_image(image, 0, 0) func _exit_tree() -> void: api.import.remove_import_option(importer_id) ``` ``` -------------------------------- ### Implement a Stamp Tool in GDScript Source: https://context7.com/orama-interactive/pixelorama/llms.txt This tool stamps an image onto the current cel. Ensure the stamp image is preloaded and the cel is a PixelCel before blending. ```gdscript extends BaseTool var stamp_image: Image = preload("res://my_extension/stamp.png") var _draw_pos := Vector2i.ZERO func get_config() -> Dictionary: return {"stamp_size": 16} func set_config(config: Dictionary) -> void: pass # restore UI controls from config func update_config() -> void: pass # update displayed control values func draw_start(pos: Vector2i) -> void: super(pos) # sets is_moving = true, initializes cache _draw_pos = pos _stamp(pos) func draw_move(pos: Vector2i) -> void: super(pos) if _draw_pos != pos: _stamp(pos) _draw_pos = pos func draw_end(pos: Vector2i) -> void: super(pos) # sets is_moving = false Global.current_project.can_undo = true func _stamp(pos: Vector2i) -> void: var project := Global.current_project var cel = project.get_current_cel() if cel.get_class_name() != "PixelCel": return var img: Image = cel.image img.blend_rect(stamp_image, Rect2i(Vector2i.ZERO, stamp_image.get_size()), pos) cel.update_texture() project.has_changed = true ```