Difference between revisions of "Manual/Plugins/Scripting"
(9 intermediate revisions by the same user not shown) | |||
Line 74: | Line 74: | ||
− | ==Color== | + | ==Misc== |
+ | ===global functions=== | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|print(...)|void|Writes all arguments to standard output and the {{bl|Manual/Dialogs/Script_Console}}.}} | ||
+ | {{object list item|run_script(filename)|void|executes the given script file in the current context.}} | ||
+ | {{object list end}} | ||
+ | |||
+ | ===Color=== | ||
{{object list begin}} | {{object list begin}} | ||
{{object list section|Constructors}} | {{object list section|Constructors}} | ||
Line 102: | Line 110: | ||
{{object list item|cmyk(c,m,y,k,a{{=}}255)|Color|Creates a color from its CMYK components}} | {{object list item|cmyk(c,m,y,k,a{{=}}255)|Color|Creates a color from its CMYK components}} | ||
{{object list end}} | {{object list end}} | ||
+ | |||
+ | ===Path=== | ||
+ | Object used in cusp plugins to draw the knot line, wrapper to the Knotter internal '''Path_Builder''' class. | ||
+ | Cannot be constructed by the user. | ||
+ | {{object list begin}} | ||
+ | {{object list section|Methods}} | ||
+ | {{object list header}} | ||
+ | {{object list item|add_line( Point p1, Point p2 )|void|Draw a straight line from {{js|p1}} to {{js|p2}} }} | ||
+ | {{object list item|add_quad( Point p1, Point control, Point p2|void | ||
+ | |Draw a quadratic curve from {{js|p1}} to {{js|p2}} with control point {{js|control}} }} | ||
+ | {{object list item|add_cubic( Point p1, Point control1, Point control2, Point p2 )|void | ||
+ | |Draw a cubic curve from {{js|p1}} to {{js|p2}} with control points {{js|control1}} and {{js|control2}} }} | ||
+ | {{object list end}} | ||
+ | |||
+ | ==Graph== | ||
+ | |||
+ | ===Graph=== | ||
+ | The graph for a given knot. | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|new graph()|Graph|Creates an empty graph}} | ||
+ | {{object list item|nodes|Array[Node]|Nodes in the graph}} | ||
+ | {{object list item|edges|Array[Edge]|Edges in the graph}} | ||
+ | {{object list item|style|Graph.Style|Graph Style}} | ||
+ | {{object list item|selected_nodes|Array[node]|List of the selected nodes}} | ||
+ | {{object list item|add_node(point)|Node|Creates a new node}} | ||
+ | {{object list item|add_node(x,y)|Node|Creates a new node}} | ||
+ | {{object list item|remove_node(node)|void|Remove node from the graph}} | ||
+ | {{object list item|remove_edge(edge)|void|Remove edge from the graph}} | ||
+ | {{object list item|connect(node1,node2)|Edge|Creates a new edge}} | ||
+ | {{object list item|node_at(point)|Node|Get the node at the given location}} | ||
+ | {{object list item|node_at(x,y)|Node|Get the node at the given location}} | ||
+ | {{object list item|node_at(point,radius)|Array[Node]|Get the nodes within given distance from location}} | ||
+ | {{object list item|node_at(x,y,radius)|Array[Node]|Get the nodes within given distance from location}} | ||
+ | {{object list item|append( file_name, keep_style{{=}}false, offset{{=}}Point() )|Boolean|Add nodes and edges from a file. '''keep_style''' controls whether the nodes should have their custom style set to override the graph style in order to follow the style from the file.}} | ||
+ | {{object list item|append(Graph other)|void|The contents of the other graph are copied to this graph.}} | ||
+ | {{object list item|clear()|void|Remove all edges and nodes}} | ||
+ | {{object list end}} | ||
+ | |||
+ | |||
+ | ===Node=== | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|pos|Point|Position of the node.}} | ||
+ | {{object list item|x|Number|{{js|pos.x}}.}} | ||
+ | {{object list item|y|Number|{{js|pos.y}}.}} | ||
+ | {{object list item|selected|Boolean|Whether the node is selected.}} | ||
+ | {{object list item|edges|Array[Edge]|(Read-Only) Edges with this node as vertex.}} | ||
+ | {{object list item|style|Node.Style|Contains the style features that this node overrides from the graph}} | ||
+ | {{object list item|has_edge_too(Node other)|Boolean|Whether there is an edge from {{js|this}} to {{js|other}}.}} | ||
+ | {{object list item|edge_to(Node other)|Edge|Edge connecting {{js|this}} and {{js|other}}.}} | ||
+ | {{object list end}} | ||
+ | |||
+ | ===Edge=== | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|vertex1|Node|One of the vertices of the edge}} | ||
+ | {{object list item|vertex2|Node|One of the vertices of the edge}} | ||
+ | {{object list item|line|Line|Line from {{js|vertex1.pos}} to {{js|vertex2.pos}}}} | ||
+ | {{object list item|midpoint|Point|Point at the middle of the edge}} | ||
+ | {{object list item|style|Edge.Style|Contains the style features that this edge overrides from the graph}} | ||
+ | {{object list item|is_vertex(node)|Boolean|Whether the node is a vertex of the edge}} | ||
+ | {{object list item|other(node)|Node|If the given node is one of its vertices, return the other vertex}} | ||
+ | {{object list end}} | ||
+ | |||
+ | |||
+ | ===Graph.Style=== | ||
+ | Default style for nodes and edges and graph appearance | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|crossing|Edge.Style|Default edge style}} | ||
+ | {{object list item|cusp|Node.Style|Default node style}} | ||
+ | {{object list item|colors|Array[Color]|(Read-Only) Colors}} | ||
+ | {{object list end}} | ||
+ | |||
+ | ===Node.Style=== | ||
+ | For nodes, a single style feature can be removed by setting it to {{js|undefined}} | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|angle|Number|Minimum angle required to trigger a cusp}} | ||
+ | {{object list item|curve|Number|Size of the curve control handles}} | ||
+ | {{object list item|distance|Number|Distance of the tip of the cusp from the node}} | ||
+ | {{object list item|shape|String|Name of the cusp shape. Possible values are the elements of {{js|knotter.cusp_shapes}}}} | ||
+ | {{object list item|clear()|void|Reset all features}} | ||
+ | {{object list end}} | ||
+ | |||
+ | ===Edge.Style=== | ||
+ | For nodes, a single style feature can be removed by setting it to {{js|undefined}} | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|curve|Number|Size of the curve control handles}} | ||
+ | {{object list item|gap|Number|Size of the gap for a rope passing under a crossing}} | ||
+ | {{object list item|slide|Number|Slide the crossing position [0-1]}} | ||
+ | {{object list item|type|String|The name of the edge type. Possible values are the elements of {{js|knotter.edge_types}} }} | ||
+ | {{object list item|clear()|void|Reset all features}} | ||
+ | {{object list end}} | ||
+ | |||
+ | |||
+ | ==Interaction with Knotter== | ||
+ | |||
+ | ===system=== | ||
+ | Object that allows interactions with the system. | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|read_file(file_name)|ByteArray|Read file contents}} | ||
+ | {{object list item|write_file(file_name,data)|Boolean|Write data to file.{{js|data}} can be either a string or a ByteArray. Returns true if the output was successful.}} | ||
+ | {{object list item|temp_path()|String|Returns the system temporary directory path.}} | ||
+ | {{object list item|unique_temp_file(base_name,extension)|String|Returns a safe absolute file name to create a unique temporary file with the given extension.}} | ||
+ | {{object list item|file_exists(file_name,readable{{=}}false,writable{{=}}false)|Boolean|Check if a file with the given permissions exists in the file system.}} | ||
+ | |||
+ | {{object list end}} | ||
+ | |||
+ | ===knotter=== | ||
+ | Object with information on Knotter. | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|version|String|Knotter version}} | ||
+ | {{object list item|has_version(Number major,Number minor)|Boolean|Whether the current version is greater than major.minor.0}} | ||
+ | {{object list item|cusp_shapes|Array[String]|Array of names of the available cusp shapes}} | ||
+ | {{object list item|edge_types|Array[String]|Array of names of the available edge types}} | ||
+ | {{object list end}} | ||
+ | |||
+ | ===window=== | ||
+ | Perform some basic operations to Knotter main window. | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|current_file|String|(Read only) File name of the knot in the active tab}} | ||
+ | {{object list item|current_tab|Number|Index of the active tab}} | ||
+ | {{object list item|open_tabs|Number|Number of open tabs}} | ||
+ | {{object list item|document|Document|Document corresponding to the current tab.}} | ||
+ | {{object list item|open( String file )|Boolean|Open file, returns true if successful}} | ||
+ | {{object list item|open()|Boolean|Create an new tab}} | ||
+ | {{object list item|screenshot(String file, String widget_name{{=}}"")|void|Take a screenshot of the given widget (or the main window if '''widget_name''' is empty).}} | ||
+ | {{object list end}} | ||
+ | |||
+ | ===window.dialog=== | ||
+ | An object that contains several functions to display simple dialogs to the user. | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|information(message,title{{=}}"")|void|Display an information dialog}} | ||
+ | {{object list item|warning(message,title{{=}}"")|void|Display a warning dialog}} | ||
+ | {{object list item|critical(message,title{{=}}"")|void|Display an error dialog}} | ||
+ | {{object list item|question(message, title{{=}}"", button_0{{=}}"OK", button_1{{=}}"", button_2{{=}}"")|Number|Display a dialog asking a question. For every non-empty button text a button is shown. Returns the index of the button that the user pressed.}} | ||
+ | {{object list item|get_open_file(title{{=}}"",filters{{=}}"")|String|Show a dialog to open a file. Filters is in the form ''"Text (.txt);;Image (.svg .png)"'', Returns the selected file name or an empty string if the user canceled the dialog.}} | ||
+ | {{object list item|get_number(message, title{{=}}"", default_value{{=}}0, min{{=}}MIN, max{{=}}MAX)|Number|Asks a dialog for a number. Returns NaN if the user canceled.}} | ||
+ | {{object list item|get_integer(message, title{{=}}"", default_value{{=}}0, min{{=}}MIN, max{{=}}MAX)|Number|Just like '''get_number''' but only integers values are allowed}} | ||
+ | {{object list item|get_text(message,title{{=}}"",default_value{{=}})|String|Ask the user for a line of text.}} | ||
+ | {{object list item|information(get_item,title{{=}}"",items{{=}}[])|String|Ask the user to select an item from the list. Returns the string representing the value or an empty string if the user canceled the dialog.}} | ||
+ | {{object list item|load_widget(file_name)|QWidget|Load a widget from a Ui file}} | ||
+ | {{object list item|progress_dialog(message, maximum{{=}}0, cancel_button{{=}}"Cancel" )|QProgressDialog|Creates a [http://qt-project.org/doc/qt-5.0/qtwidgets/qprogressdialog.html progress dialog].}} | ||
+ | {{object list end}} | ||
+ | |||
+ | ===gui=== | ||
+ | Utility object that creates wrappers to Qt widgets in order to access some of their functionality that is not usually available to scripts. | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|table_widget(QTableWidget)|gui.table_widget|Creates a wrapper to a QTableWidget.}} | ||
+ | {{object list end}} | ||
+ | ====gui.table_widget==== | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|table|QObject|The wrapped QTableWidget.}} | ||
+ | {{object list item|set_value(row, column, value)|void|Change the value in the given cell.}} | ||
+ | {{object list item|get_value (row,column)|String|Get the value in the given cell.}} | ||
+ | {{object list item|append_row([values])|void|Append a row with the given values.}} | ||
+ | {{object list item|current_row()|Number|The currently selected row or -1.}} | ||
+ | {{object list item|current_column()|Number|The currently selected column or -1.}} | ||
+ | {{object list item|value_changed(row,column,value)|(Signal)|Emitted when the user changes the content of a cell.}} | ||
+ | {{object list end}} | ||
+ | |||
+ | ===Document=== | ||
+ | The document from which the script was called. While '''window.document''' may change, the global '''document''' object will be the same during the entire script. | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|filename|String|The name of the file for this document.}} | ||
+ | {{object list item|graph|Graph|The graph contained by the document.}} | ||
+ | {{object list item|grid|Grid|The grid used by the document.}} | ||
+ | {{object list item|insert(graph,message{{=}}"ScriptInsert")|Boolean|Insert graph in the document. The inserted graph will have to be placed by the user in the desired location. Returns whether insertion has been successful.}} | ||
+ | {{object list item|render|Document.render|Document renderer}} | ||
+ | {{object list item|begin_macro(message)|void|Wrap following edits to the document in a macro, the message will be the text displayed in the action history. Macros can be nested.}} | ||
+ | {{object list item|end_macro()|void|End current macro. For each call to {{js|begin_macro}} there should be a call to {{js|end_macro}}.}} | ||
+ | {{object list end}} | ||
+ | |||
+ | ===Document.render=== | ||
+ | Renders the document in several formats. | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|draw_graph {{=}} false|Boolean|Whether the graph should be rendered as well.}} | ||
+ | {{object list item|knot()|String|Knot file XML.}} | ||
+ | {{object list item|svg()|String|SVG XML.}} | ||
+ | {{object list item|raster( width{{=}}0, height{{=}}0, format{{=}}"PNG", quality{{=}}0, background{{=}}new Color() )|ByteArray|Raster.<br/> | ||
+ | If {{js|width}} or {{js|height}} aren't positive, their value is deduced by the graph size.<br/> | ||
+ | {{js|format}} is a string identifying the image format.<br/> | ||
+ | {{js|quality}} in [0,100] is the opposite of the compression. For JPEG it may be a good idea to set to a high value for other formats low values mean more compression.<br/> | ||
+ | {{js|background}} Background color, transparent will look black in formats that don't have an aplpha channel.}} | ||
+ | {{object list end}} | ||
+ | |||
+ | ===Grid=== | ||
+ | The grid displayed by a document object. | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|size|Number|Size of a grid cell.}} | ||
+ | {{object list item|origin|Point|Position of the grid origin}} | ||
+ | {{object list item|enabled|Boolean|Whether the grid is displayed or not.}} | ||
+ | {{object list item|shape|String|One of ''SQUARE'', ''TRIANGLE1'' or ''TRIANGLE2''.}} | ||
+ | {{object list item|enable()|void|Shorthand for {{js|grid.enabled {{=}} true;}}.}} | ||
+ | {{object list item|disable()|void|Shorthand for {{js|grid.enabled {{=}} false;}}.}} | ||
+ | {{object list end}} | ||
+ | |||
+ | ==Plugin-specific objects== | ||
+ | |||
+ | ===All Plugins=== | ||
+ | All plugins can access the object {{js|plugin}} that contains the information from the [[Manual/Plugins#Plugin_Data|plugin data]]. | ||
+ | |||
+ | ===Cusp Plugins=== | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|angle|Number|The angle between input and output edge}} | ||
+ | {{object list item|cusp_angle|Number|Style setting, if {{js|angle > cusp_angle}} , draw a cusp}} | ||
+ | {{object list item|handle_length|Number|Style setting, "curve" style parameter in the UI}} | ||
+ | {{object list item|start_handle|Line|Starting point for lines, start_handle.p1 will be connected to the path forming the crossing}} | ||
+ | {{object list item|finish_handle|Line|Ending point for lines, finish_handle.p1 will be connected to the path forming the crossing}} | ||
+ | {{object list item|cusp_point|Point|Pre-computed cusp point location}} | ||
+ | {{object list item|node_point|Point|Position of the node between the two edges}} | ||
+ | {{object list item|input_edge|Line|Line corresponding to the input edge}} | ||
+ | {{object list item|output_edge|Line|Line corresponding to the output edge}} | ||
+ | {{object list item|path|Path|Object used to build the path}} | ||
+ | {{object list item|direction|Number| -1 or +1 depending on the direction of the angle (clockwise or counter)}} | ||
+ | {{object list end}} | ||
+ | |||
+ | ====Guidelines==== | ||
+ | A cusp is expected to render a path from {{js|start_handle.p1}} to {{js|finish_handle.p1}}. | ||
+ | |||
+ | {{js|start_handle.p2}} and {{js|finish_handle.p2}} may be used as control points. | ||
+ | |||
+ | If {{js|angle > cusp_angle}} the line should pass through {{js|cusp_point}} | ||
+ | |||
+ | ====Example==== | ||
+ | Follows the code to replicate the built-in rounded cusp. | ||
+ | {{script| | ||
+ | // When angle is large enough, draw the cusp | ||
+ | if ( angle > cusp_angle ) | ||
+ | { | ||
+ | // Create a "handle" that on cusp_point with size handle_length to determine the control points | ||
+ | var handle {{=}} new Line(start_handle.p1,finish_handle.p1); | ||
+ | handle.translate(cusp_point); | ||
+ | handle.translate(opposite(start_handle.p1)); | ||
+ | handle.length {{=}} handle_length; | ||
+ | var h2 {{=}} handle.p2; | ||
+ | handle.length {{=}} -handle_length; | ||
+ | var h1 {{=}} handle.p2; | ||
+ | // Use the control points to render the cusp | ||
+ | path.add_cubic ( start_handle.p1, start_handle.p2, h1, cusp_point ); | ||
+ | path.add_cubic ( finish_handle.p1, finish_handle.p2, h2, cusp_point ); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | // Don't draw a cusp, just a curve from start_handle to finish_handle | ||
+ | |||
+ | if ( distance(start_handle.p1,finish_handle.p1) < start_handle.length + finish_handle.length ) | ||
+ | { | ||
+ | // The two edges are very close together, avoid artifacts with a simpler curve | ||
+ | var midpoint {{=}} Point( (start_handle.p2.x+finish_handle.p2.x)/2, | ||
+ | (start_handle.p2.y+finish_handle.p2.y)/2 ); | ||
+ | path.add_quad(start_handle.p1,midpoint,finish_handle.p1); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | // There's enough room to draw a cubic curve | ||
+ | path.add_cubic(start_handle.p1,start_handle.p2,finish_handle.p2,finish_handle.p1); | ||
+ | } | ||
+ | } | ||
+ | }} | ||
+ | |||
+ | ===Edge Plugins=== | ||
+ | {{object list begin}} | ||
+ | {{object list header}} | ||
+ | {{object list item|TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, TOP_LEFT|Number|Constant values to identify the input/output handle.}} | ||
+ | {{object list item|edge|Edge|The edge that is requesting the script.}} | ||
+ | {{object list item|style|Edge.Style|The edge style containing default values from the graph.}} | ||
+ | {{object list item|handle|Number|The input handle (See above for values that may identify it).}} | ||
+ | {{object list item|path|Path|Object used to build the path. (Only available to the {{js|traverse}} script)}} | ||
+ | {{object list item|result|Number|The output handle id. The script must write a value to this variable. (Only available to the {{js|traverse}} script)}} | ||
+ | {{object list item|result|Line|The output handle. The script must write a value to this variable. (Only available to the {{js|handle}} script)}} | ||
+ | {{object list end}} | ||
+ | |||
+ | ====Guidelines==== | ||
+ | A custom crossing requires two scripts: | ||
+ | ;traverse | ||
+ | :that will draw to the {{js|path}} (if needed) and return the direction the thread should move once passed the current edge | ||
+ | ;handle | ||
+ | :that will return a line corresponding to the given handle id. | ||
+ | |||
+ | These snippets will be executed after the execution of the main script file. It's recommended that the scrip file provides useful functions that will be called by these snippets. | ||
+ | |||
+ | ====Example==== | ||
+ | The following example replicates the default crossing: | ||
+ | {{script| | ||
+ | { | ||
+ | "author" : "Mattia Basaglia", | ||
+ | "description" : "An implementation of the built-in normal edge type as a plugin, disabled by default.\n\nThis plugin serves as an example on how to create crossing plugins.", | ||
+ | "license" : "GPLv3+", | ||
+ | "name" : "Example Edge", | ||
+ | "requires" : "0.9.6", | ||
+ | "script" : "example_edge.js", | ||
+ | "type" : "crossing", | ||
+ | "version" : "1", | ||
+ | "traverse" : "var result {{=}} traverse(edge,handle,style);", | ||
+ | "handle" : "var result {{=}} handle_line(edge,handle,style);", | ||
+ | "auto_enable" : false, | ||
+ | "category" : "Example" | ||
+ | } | ||
+ | }} | ||
+ | |||
+ | {{script| | ||
+ | function traverse(edge,handle,style) | ||
+ | { | ||
+ | var next {{=}} 0; | ||
+ | if ( handle {{==}} TOP_RIGHT ) | ||
+ | next {{=}} BOTTOM_LEFT; | ||
+ | else if ( handle {{==}} BOTTOM_RIGHT ) | ||
+ | next {{=}} TOP_LEFT; | ||
+ | else if ( handle {{==}} BOTTOM_LEFT ) | ||
+ | next {{=}} TOP_RIGHT; | ||
+ | else if ( handle {{==}} TOP_LEFT ) | ||
+ | next {{=}} BOTTOM_RIGHT; | ||
+ | |||
+ | if ( handle {{==}} TOP_LEFT {{!!}} next {{==}} TOP_LEFT ) | ||
+ | path.add_line(handle_line(edge,handle,style).p1, | ||
+ | handle_line(edge,next,style).p1 | ||
+ | ); | ||
+ | return next; | ||
+ | } | ||
+ | |||
+ | function deg2rad(deg) | ||
+ | { | ||
+ | return deg / 180 * Math.PI; | ||
+ | } | ||
+ | |||
+ | function handle_line(edge,handle,style) | ||
+ | { | ||
+ | |||
+ | var handle_angle {{=}} 0; | ||
+ | if ( handle {{==}} TOP_RIGHT ) | ||
+ | handle_angle {{=}} Math.PI/4.0; | ||
+ | else if ( handle {{==}} TOP_LEFT ) | ||
+ | handle_angle {{=}} Math.PI*3.0/4.0; | ||
+ | else if ( handle {{==}} BOTTOM_LEFT ) | ||
+ | handle_angle {{=}} Math.PI*5.0/4.0; | ||
+ | else if ( handle {{==}} BOTTOM_RIGHT ) | ||
+ | handle_angle {{=}} Math.PI*7.0/4.0; | ||
+ | |||
+ | handle_angle +{{=}} deg2rad(edge.line.angle); | ||
+ | var p1 {{=}} edge.line.pointAt(style.slide); | ||
+ | p1.x {{=}} p1.x+style.gap/2*Math.cos(handle_angle); | ||
+ | p1.y {{=}} p1.y-style.gap/2*Math.sin(handle_angle); | ||
+ | |||
+ | var p2 {{=}} new Point( | ||
+ | p1.x+style.curve*Math.cos(handle_angle), | ||
+ | p1.y-style.curve*Math.sin(handle_angle) | ||
+ | ); | ||
+ | |||
+ | return new Line(p1,p2); | ||
+ | } | ||
+ | }} |
Latest revision as of 10:55, 11 November 2013
This page is updated to Knotter version 0.9.6 |
Scripts are in QtScript aka ECMAScript aka JavaScript.
The details of the language are specified in the Qt ECMAScript reference. This page focuses on functions and objects specific to Knotter.
Geometry
Point
A wrapper to QPointF.
Constructors | ||
---|---|---|
Name | Type | Description |
new Point()
|
Point
|
new Point(0,0)
|
new Point( Point other )
|
Point
|
Copy point other
|
new Point( Number x, Number y )
|
Point
|
Create point with given coordinates |
External functions | ||
Name | Type | Description |
opposite( Point p )
|
Point
|
new Point(-p.x,-p.y)
|
distance(Point a, Point b)
|
Number
|
Distance from a and b |
Line
A wrapper to QLineF most of the functionality of QLineF is also present in line
.
Constructors | ||
---|---|---|
Name | Type | Description |
new Line()
|
Line
|
Empty line |
new Line( Line other )
|
Line
|
Copy line other_line
|
new Line( point1, point2 )
|
Line
|
Line from point point1 to point2
|
Properties | ||
Name | Type | Description |
p1
|
Point
|
Starting point of the line |
p2
|
Point
|
End point of the line |
x1
|
Number
|
p1.x
|
x2
|
Number
|
p2.x
|
y1
|
Number
|
p1.y
|
y2
|
Number
|
p2.y
|
angle
|
Number
|
Angle of the line in degrees. An angle of 0° is a horizontal line pointing to the right. |
length
|
Number
|
Length of the line (distance between p1 and p2
|
dx
|
Number
|
p1.x-p2.x
|
dy
|
Number
|
p1.y-p2.y
|
Methods | ||
Name | Type | Description |
intersect ( Line other )
|
Point
|
Return the intersection point between the current line and other |
normalVector()
|
Line
|
Returns a line that is perpendicular to this line with the same starting point and length. |
unitVector()
|
Line
|
Returns the unit vector for this line, i.e a line starting at the same point as this line with a length of 1.0. |
pointAt(Number t)
|
Point
|
Returns the point at the parameterized position specified by t. The function returns the line's start point if t = 0, and its end point if t = 1. |
translate(Point offset)
|
void
|
Translate the line by offset
|
translate(Number x,Number y)
|
void
|
translate(point(x,y))
|
Polygon
Name | Type | Description |
---|---|---|
new Polygon()
|
Polygon
|
Create an empty polygon. |
new Polygon(vertices)
|
Polygon
|
Create a polygon with given vertices. |
vertices
|
Array[Point]
|
Vertices of the polygon. |
contains(point)
|
Boolean
|
Whether the point is inside the polygon. |
contains(x,y)
|
Boolean
|
contains(new Point(x,y)) .
|
add_vertex(point)
|
void
|
Appends a vertex to vertices .
|
Misc
global functions
Name | Type | Description |
---|---|---|
print(...)
|
void
|
Writes all arguments to standard output and the Script_Console. |
run_script(filename)
|
void
|
executes the given script file in the current context. |
Color
Constructors | ||
---|---|---|
Name | Type | Description |
new Color()
|
Color
|
Creates a transparent black color |
new Color(string)
|
Color
|
Create a color from a color name eg: #ff00ff, red |
new Color(r,g,b,a=255)
|
Color
|
Create a color from rgb components [0-255] |
new Color(color)
|
Color
|
Copy color |
Properties | ||
Name | Type | Description |
alpha
|
Number
|
Transparency [0-255] |
red
|
Number
|
RGB red channel [0-255] |
green
|
Number
|
RGB green channel [0-255] |
blue
|
Number
|
RGB blue channel [0-255] |
hue
|
Number
|
HSV hue channel [0-360] |
saturation
|
Number
|
HSV saturation channel [0-255] |
value
|
Number
|
HSV value channel [0-255] |
cyan
|
Number
|
CMYK cyan channel [0-255] |
magenta
|
Number
|
CMYK magenta channel [0-255] |
yellow
|
Number
|
CMYK yellow channel [0-255] |
black
|
Number
|
CMYK black channel [0-255] |
Number | ||
Name | Type | Description |
rgb(r,g,b,a=255)
|
Color
|
Same as new Color(r,g,b,a)
|
hsv(h,s,v,a=255)
|
Color
|
Creates a color from its HSV components |
hsl(h,s,l,a=255)
|
Color
|
Creates a color from its HSL components |
cmyk(c,m,y,k,a=255)
|
Color
|
Creates a color from its CMYK components |
Path
Object used in cusp plugins to draw the knot line, wrapper to the Knotter internal Path_Builder class. Cannot be constructed by the user.
Methods | ||
---|---|---|
Name | Type | Description |
add_line( Point p1, Point p2 )
|
void
|
Draw a straight line from p1 to p2
|
add_quad( Point p1, Point control, Point p2
|
void
|
Draw a quadratic curve from p1 to p2 with control point control
|
add_cubic( Point p1, Point control1, Point control2, Point p2 )
|
void
|
Draw a cubic curve from p1 to p2 with control points control1 and control2
|
Graph
Graph
The graph for a given knot.
Name | Type | Description |
---|---|---|
new graph()
|
Graph
|
Creates an empty graph |
nodes
|
Array[Node]
|
Nodes in the graph |
edges
|
Array[Edge]
|
Edges in the graph |
style
|
Graph.Style
|
Graph Style |
selected_nodes
|
Array[node]
|
List of the selected nodes |
add_node(point)
|
Node
|
Creates a new node |
add_node(x,y)
|
Node
|
Creates a new node |
remove_node(node)
|
void
|
Remove node from the graph |
remove_edge(edge)
|
void
|
Remove edge from the graph |
connect(node1,node2)
|
Edge
|
Creates a new edge |
node_at(point)
|
Node
|
Get the node at the given location |
node_at(x,y)
|
Node
|
Get the node at the given location |
node_at(point,radius)
|
Array[Node]
|
Get the nodes within given distance from location |
node_at(x,y,radius)
|
Array[Node]
|
Get the nodes within given distance from location |
append( file_name, keep_style=false, offset=Point() )
|
Boolean
|
Add nodes and edges from a file. keep_style controls whether the nodes should have their custom style set to override the graph style in order to follow the style from the file. |
append(Graph other)
|
void
|
The contents of the other graph are copied to this graph. |
clear()
|
void
|
Remove all edges and nodes |
Node
Name | Type | Description |
---|---|---|
pos
|
Point
|
Position of the node. |
x
|
Number
|
pos.x .
|
y
|
Number
|
pos.y .
|
selected
|
Boolean
|
Whether the node is selected. |
edges
|
Array[Edge]
|
(Read-Only) Edges with this node as vertex. |
style
|
Node.Style
|
Contains the style features that this node overrides from the graph |
has_edge_too(Node other)
|
Boolean
|
Whether there is an edge from this to other .
|
edge_to(Node other)
|
Edge
|
Edge connecting this and other .
|
Edge
Name | Type | Description |
---|---|---|
vertex1
|
Node
|
One of the vertices of the edge |
vertex2
|
Node
|
One of the vertices of the edge |
line
|
Line
|
Line from vertex1.pos to vertex2.pos
|
midpoint
|
Point
|
Point at the middle of the edge |
style
|
Edge.Style
|
Contains the style features that this edge overrides from the graph |
is_vertex(node)
|
Boolean
|
Whether the node is a vertex of the edge |
other(node)
|
Node
|
If the given node is one of its vertices, return the other vertex |
Graph.Style
Default style for nodes and edges and graph appearance
Name | Type | Description |
---|---|---|
crossing
|
Edge.Style
|
Default edge style |
cusp
|
Node.Style
|
Default node style |
colors
|
Array[Color]
|
(Read-Only) Colors |
Node.Style
For nodes, a single style feature can be removed by setting it to undefined
Name | Type | Description |
---|---|---|
angle
|
Number
|
Minimum angle required to trigger a cusp |
curve
|
Number
|
Size of the curve control handles |
distance
|
Number
|
Distance of the tip of the cusp from the node |
shape
|
String
|
Name of the cusp shape. Possible values are the elements of knotter.cusp_shapes
|
clear()
|
void
|
Reset all features |
Edge.Style
For nodes, a single style feature can be removed by setting it to undefined
Name | Type | Description |
---|---|---|
curve
|
Number
|
Size of the curve control handles |
gap
|
Number
|
Size of the gap for a rope passing under a crossing |
slide
|
Number
|
Slide the crossing position [0-1] |
type
|
String
|
The name of the edge type. Possible values are the elements of knotter.edge_types
|
clear()
|
void
|
Reset all features |
Interaction with Knotter
system
Object that allows interactions with the system.
Name | Type | Description |
---|---|---|
read_file(file_name)
|
ByteArray
|
Read file contents |
write_file(file_name,data)
|
Boolean
|
Write data to file.data can be either a string or a ByteArray. Returns true if the output was successful.
|
temp_path()
|
String
|
Returns the system temporary directory path. |
unique_temp_file(base_name,extension)
|
String
|
Returns a safe absolute file name to create a unique temporary file with the given extension. |
file_exists(file_name,readable=false,writable=false)
|
Boolean
|
Check if a file with the given permissions exists in the file system. |
knotter
Object with information on Knotter.
Name | Type | Description |
---|---|---|
version
|
String
|
Knotter version |
has_version(Number major,Number minor)
|
Boolean
|
Whether the current version is greater than major.minor.0 |
cusp_shapes
|
Array[String]
|
Array of names of the available cusp shapes |
edge_types
|
Array[String]
|
Array of names of the available edge types |
window
Perform some basic operations to Knotter main window.
Name | Type | Description |
---|---|---|
current_file
|
String
|
(Read only) File name of the knot in the active tab |
current_tab
|
Number
|
Index of the active tab |
open_tabs
|
Number
|
Number of open tabs |
document
|
Document
|
Document corresponding to the current tab. |
open( String file )
|
Boolean
|
Open file, returns true if successful |
open()
|
Boolean
|
Create an new tab |
screenshot(String file, String widget_name="")
|
void
|
Take a screenshot of the given widget (or the main window if widget_name is empty). |
window.dialog
An object that contains several functions to display simple dialogs to the user.
Name | Type | Description |
---|---|---|
information(message,title="")
|
void
|
Display an information dialog |
warning(message,title="")
|
void
|
Display a warning dialog |
critical(message,title="")
|
void
|
Display an error dialog |
question(message, title="", button_0="OK", button_1="", button_2="")
|
Number
|
Display a dialog asking a question. For every non-empty button text a button is shown. Returns the index of the button that the user pressed. |
get_open_file(title="",filters="")
|
String
|
Show a dialog to open a file. Filters is in the form "Text (.txt);;Image (.svg .png)", Returns the selected file name or an empty string if the user canceled the dialog. |
get_number(message, title="", default_value=0, min=MIN, max=MAX)
|
Number
|
Asks a dialog for a number. Returns NaN if the user canceled. |
get_integer(message, title="", default_value=0, min=MIN, max=MAX)
|
Number
|
Just like get_number but only integers values are allowed |
get_text(message,title="",default_value=)
|
String
|
Ask the user for a line of text. |
information(get_item,title="",items=[])
|
String
|
Ask the user to select an item from the list. Returns the string representing the value or an empty string if the user canceled the dialog. |
load_widget(file_name)
|
QWidget
|
Load a widget from a Ui file |
progress_dialog(message, maximum=0, cancel_button="Cancel" )
|
QProgressDialog
|
Creates a progress dialog. |
gui
Utility object that creates wrappers to Qt widgets in order to access some of their functionality that is not usually available to scripts.
Name | Type | Description |
---|---|---|
table_widget(QTableWidget)
|
gui.table_widget
|
Creates a wrapper to a QTableWidget. |
gui.table_widget
Name | Type | Description |
---|---|---|
table
|
QObject
|
The wrapped QTableWidget. |
set_value(row, column, value)
|
void
|
Change the value in the given cell. |
get_value (row,column)
|
String
|
Get the value in the given cell. |
append_row([values])
|
void
|
Append a row with the given values. |
current_row()
|
Number
|
The currently selected row or -1. |
current_column()
|
Number
|
The currently selected column or -1. |
value_changed(row,column,value)
|
(Signal)
|
Emitted when the user changes the content of a cell. |
Document
The document from which the script was called. While window.document may change, the global document object will be the same during the entire script.
Name | Type | Description |
---|---|---|
filename
|
String
|
The name of the file for this document. |
graph
|
Graph
|
The graph contained by the document. |
grid
|
Grid
|
The grid used by the document. |
insert(graph,message="ScriptInsert")
|
Boolean
|
Insert graph in the document. The inserted graph will have to be placed by the user in the desired location. Returns whether insertion has been successful. |
render
|
Document.render
|
Document renderer |
begin_macro(message)
|
void
|
Wrap following edits to the document in a macro, the message will be the text displayed in the action history. Macros can be nested. |
end_macro()
|
void
|
End current macro. For each call to begin_macro there should be a call to end_macro .
|
Document.render
Renders the document in several formats.
Name | Type | Description |
---|---|---|
draw_graph = false
|
Boolean
|
Whether the graph should be rendered as well. |
knot()
|
String
|
Knot file XML. |
svg()
|
String
|
SVG XML. |
raster( width=0, height=0, format="PNG", quality=0, background=new Color() )
|
ByteArray
|
Raster. If |
Grid
The grid displayed by a document object.
Name | Type | Description |
---|---|---|
size
|
Number
|
Size of a grid cell. |
origin
|
Point
|
Position of the grid origin |
enabled
|
Boolean
|
Whether the grid is displayed or not. |
shape
|
String
|
One of SQUARE, TRIANGLE1 or TRIANGLE2. |
enable()
|
void
|
Shorthand for grid.enabled = true; .
|
disable()
|
void
|
Shorthand for grid.enabled = false; .
|
Plugin-specific objects
All Plugins
All plugins can access the object plugin
that contains the information from the plugin data.
Cusp Plugins
Name | Type | Description |
---|---|---|
angle
|
Number
|
The angle between input and output edge |
cusp_angle
|
Number
|
Style setting, if angle > cusp_angle , draw a cusp
|
handle_length
|
Number
|
Style setting, "curve" style parameter in the UI |
start_handle
|
Line
|
Starting point for lines, start_handle.p1 will be connected to the path forming the crossing |
finish_handle
|
Line
|
Ending point for lines, finish_handle.p1 will be connected to the path forming the crossing |
cusp_point
|
Point
|
Pre-computed cusp point location |
node_point
|
Point
|
Position of the node between the two edges |
input_edge
|
Line
|
Line corresponding to the input edge |
output_edge
|
Line
|
Line corresponding to the output edge |
path
|
Path
|
Object used to build the path |
direction
|
Number
|
-1 or +1 depending on the direction of the angle (clockwise or counter) |
Guidelines
A cusp is expected to render a path from start_handle.p1
to finish_handle.p1
.
start_handle.p2
and finish_handle.p2
may be used as control points.
If angle > cusp_angle
the line should pass through cusp_point
Example
Follows the code to replicate the built-in rounded cusp.
// When angle is large enough, draw the cusp
if ( angle > cusp_angle )
{
// Create a "handle" that on cusp_point with size handle_length to determine the control points
var handle = new Line(start_handle.p1,finish_handle.p1);
handle.translate(cusp_point);
handle.translate(opposite(start_handle.p1));
handle.length = handle_length;
var h2 = handle.p2;
handle.length = -handle_length;
var h1 = handle.p2;
// Use the control points to render the cusp
path.add_cubic ( start_handle.p1, start_handle.p2, h1, cusp_point );
path.add_cubic ( finish_handle.p1, finish_handle.p2, h2, cusp_point );
}
else
{
// Don't draw a cusp, just a curve from start_handle to finish_handle
if ( distance(start_handle.p1,finish_handle.p1) < start_handle.length + finish_handle.length )
{
// The two edges are very close together, avoid artifacts with a simpler curve
var midpoint = Point( (start_handle.p2.x+finish_handle.p2.x)/2,
(start_handle.p2.y+finish_handle.p2.y)/2 );
path.add_quad(start_handle.p1,midpoint,finish_handle.p1);
}
else
{
// There's enough room to draw a cubic curve
path.add_cubic(start_handle.p1,start_handle.p2,finish_handle.p2,finish_handle.p1);
}
}
Edge Plugins
Name | Type | Description |
---|---|---|
TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, TOP_LEFT
|
Number
|
Constant values to identify the input/output handle. |
edge
|
Edge
|
The edge that is requesting the script. |
style
|
Edge.Style
|
The edge style containing default values from the graph. |
handle
|
Number
|
The input handle (See above for values that may identify it). |
path
|
Path
|
Object used to build the path. (Only available to the traverse script)
|
result
|
Number
|
The output handle id. The script must write a value to this variable. (Only available to the traverse script)
|
result
|
Line
|
The output handle. The script must write a value to this variable. (Only available to the handle script)
|
Guidelines
A custom crossing requires two scripts:
- traverse
- that will draw to the
path
(if needed) and return the direction the thread should move once passed the current edge - handle
- that will return a line corresponding to the given handle id.
These snippets will be executed after the execution of the main script file. It's recommended that the scrip file provides useful functions that will be called by these snippets.
Example
The following example replicates the default crossing:
{
"author" : "Mattia Basaglia",
"description" : "An implementation of the built-in normal edge type as a plugin, disabled by default.\n\nThis plugin serves as an example on how to create crossing plugins.",
"license" : "GPLv3+",
"name" : "Example Edge",
"requires" : "0.9.6",
"script" : "example_edge.js",
"type" : "crossing",
"version" : "1",
"traverse" : "var result = traverse(edge,handle,style);",
"handle" : "var result = handle_line(edge,handle,style);",
"auto_enable" : false,
"category" : "Example"
}
function traverse(edge,handle,style)
{
var next = 0;
if ( handle == TOP_RIGHT )
next = BOTTOM_LEFT;
else if ( handle == BOTTOM_RIGHT )
next = TOP_LEFT;
else if ( handle == BOTTOM_LEFT )
next = TOP_RIGHT;
else if ( handle == TOP_LEFT )
next = BOTTOM_RIGHT;
if ( handle == TOP_LEFT || next == TOP_LEFT )
path.add_line(handle_line(edge,handle,style).p1,
handle_line(edge,next,style).p1
);
return next;
}
function deg2rad(deg)
{
return deg / 180 * Math.PI;
}
function handle_line(edge,handle,style)
{
var handle_angle = 0;
if ( handle == TOP_RIGHT )
handle_angle = Math.PI/4.0;
else if ( handle == TOP_LEFT )
handle_angle = Math.PI*3.0/4.0;
else if ( handle == BOTTOM_LEFT )
handle_angle = Math.PI*5.0/4.0;
else if ( handle == BOTTOM_RIGHT )
handle_angle = Math.PI*7.0/4.0;
handle_angle += deg2rad(edge.line.angle);
var p1 = edge.line.pointAt(style.slide);
p1.x = p1.x+style.gap/2*Math.cos(handle_angle);
p1.y = p1.y-style.gap/2*Math.sin(handle_angle);
var p2 = new Point(
p1.x+style.curve*Math.cos(handle_angle),
p1.y-style.curve*Math.sin(handle_angle)
);
return new Line(p1,p2);
}