CorelDRAW Community
CorelDRAW Community
  • Site
  • User
  • Site
  • Search
  • User
Developer Area
Developer Area
Docs & Tutorials Creating Custom Tools in CorelDRAW and Corel DESIGNER
  • Forums
  • Wikis
  • API References
  • Tags
  • More
  • Cancel
  • New
Developer Area requires membership for participation - click to join
  • -Addons: Extending Application Functionality with VBA and VSTA
    • Creating Custom Tools in CorelDRAW and Corel DESIGNER
    • Creating Ruler Tool for CorelDRAW or Corel DESIGNER
    • Custom Add-ons in CorelDRAW, Corel DESIGNER and Corel PHOTO-PAINT
    • Custom Dockers in CorelDRAW, Corel DESIGNER and Corel PHOTO-PAINT
    • Making a Zig Zag Tool for CorelDRAW and Corel DESIGNER
  • +General Articles

Creating Custom Tools in CorelDRAW and Corel DESIGNER

New to CorelDRAW X7 Update 1 and Corel DESIGNER X7 is the ability to create your own tools in VBA, C# or C++. This is done using the new tool interface called ToolState and a set of many new functions and classes that are specifically geared towards creating tools.

While new tools can be implemented in any language that supports COM, this article will focus on C#.

Prerequisites

  • Microsoft Visual Studio 2012 or higher is required. Visual Studio Community (free version) is available from Microsoft here.
  • The "CorelDRAW and Corel DESIGNER Tool Addon" extension for Visual Studio is demonstrated in this article.  To install the extension run Visual Studio, select the Tools->Extensions and Updates menu item, expand the Online tab and search for "CorelDRAW".  Select "CorelDRAW  and Corel DESIGNER Tool Addon" extension and install it.

Creating a New Project

Once the "CorelDRAW and Corel DESIGNER Tool Addon" extension is installed in Visual Studio, it will be available through the File->New Project list.  Go to File->New Project and navigate to Installed->Templates->Other Languages->C#, and select "CorelDRAW and Corel DESIGNER Tool Addon" from the list. Choose a name for the tool (e.g. "MyTool") and press OK to create the project.

Next the Addon Settings dialog is displayed from which the startup application can be selected.  This choice can be changed later through the project's properties dialog  (Start external program). Note: The application choices are only enabled if the template detects that the application is installed on the computer.

Compile and Run

To compile the addon, select Build->Build Solution (or press F7).  Press F5 and it will launch the application (CorelDRAW or Corel DESIGNER) that was selected earlier and the new tool will be added to the toolbox.

This sample tool allows the user to create 2-point lines and demonstrates how easy it is to create a custom tool.  It has on screen preview UI, snapping, constraints, a property bar, and everything else one would expect for a tool.

The Code

The project has two .cs files. Addon.cs contains the entry point. This class will be instantiated by the host application (CorelDRAW or Corel DESIGNER) when the application is started.  This is where the new tool is registered, any other data sources or other tasks that need to be performed on application startup.

///<summary>
/// Constructor for the Addon.  This is called by CorelDRAW or Corel DESIGNER when it is discovered.
///</summary>
public Addon(Application Application)
{
	// Create and register our tool
	ToolState toolState = new CGS.MyTool(Application);
	Application.RegisterToolState("b17f7ca0-0062-4dd8-adf6-1ea2192a3d35", "MyTool", toolState);
}

The function RegisterToolState tells that application that the GUID (Globally Unique IDentifier) "b17f7ca0-0062-4dd8-adf6-1ea2192a3d35" identifies the MyTool addon. This GUID must be different for every tool  and the Visual Studio extension will generates a new one for every project. Multiple tools can be created within the project and all registered at this place. Each tool will need a unique GUID.  This can be created using Tools->Create GUID in Visual Studio or an equivalent GUID generator that are available on the web.

The MyTool.cs file contains the code for the tool. This sample tool is less than 200 lines long, but could be extended to do whatever custom logic is required. The MyTool class inherits from the ToolState interface.  The host application, when using the tool, will call into the various functions that are implemented. For example, when the tool starts, the OnStartState() function will be called, allowing the tool to be set for use. When you move the mouse across the view, the OnMouseMove() function will be called.  This function can be used to update the UI or collect mouse positions for curve creation.

The code for the sample tool is documented well, please take a few moments to read through the code and the comments to gain a basic understanding of the functions. The pseudo code for the line tool is as follows:

OnLButtonDownLeaveGrace
   save the left mouse button down position

OnMouseMove
  if the left mouse is down
    update the xor'd on screen UI with a line from the saved location to the current position

OnLButtonUp
  Create a line from the saved position to the current position

 The UI

In the project there are two XSLT files: AppUI.xslt and UserUI.xslt.  XSLT is an XML transformation file.  It's purpose is to update the user's workspace to include the new tool.  This sample will just add the new tool button to the end of the Toolbox.  More complex changes to the workspace are possible using other XSLT transformations.  If you're attempting to create any complicated UI, you may want to read up on XSLT to better understand it.

The AppUI.xslt file is responsible for defining new items (e.g. buttons) and adding new dockers or dialogs.  Anything that isn't customizable can be defined here.  In the sample line tool, it adds one new item.

<!-- C# Test Line Tool -->
<itemData guid="b17f7ca0-0062-4dd8-adf6-1ea2192a3d35"
          type="groupedRadioButton"
          currentActiveOfGroup="*Bind(DataSource=WAppDataSource;Path=ActiveTool;BindType=TwoWay)"
          enable="*Bind(DataSource=WAppDataSource;Path=ToolboxEnable)"
          identifier="b17f7ca0-0062-4dd8-adf6-1ea2192a3d35"/>

A GUID is used to identify the tool button ("b17f7ca0-0062-4dd8-adf6-1ea2192a3d35"). This GUID is set for both the item and the grouped radio identifier.  This is also the same GUID that was registered as MyTool with the application.  This is important as it causes MyTool activate when the button is clicked.

UserUI.xslt is for modifying any UI that is customizable, for example, adding buttons to existing toolbars or menus, or creating new toolbars for the tools, etc.

  <!-- Add tool item to the Toolbox -->
  <xsl:template match="//commandBarData[@guid='7c905e2a-cb64-4ba1-aff0-c306f392680c']/toolbar">
    <xsl:apply-templates mode="insert-item" select=".">
      <xsl:with-param name="content">
        <xsl:if test="not(./item[@guidRef='6b5b83bb-e7b8-4f9d-8dfd-36f59bf545cf'])">
          <!-- Only insert if its not already there -->
          <item guidRef="6b5b83bb-e7b8-4f9d-8dfd-36f59bf545cf"/>
        </xsl:if>
      </xsl:with-param>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="uiConfig/commandBars/commandBarData[@guid='74e03d83-404c-49f5-824a-fe0fd02ab29a']/toolbar">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    <modeData guid="fd9a53f7-05cc-4cdc-b2ad-0fd6a7ea3480" captionRef="01965a34-ae38-01a0-4271-cd903b48e518">
      <item guidRef="3148e122-4f73-6e8a-4dfb-b2f6a84090d5"/>
      <item guidRef="a41164ff-c9e9-4b2c-954a-095f4204538e"/>
      <item guidRef="266435b4-6e53-460f-9fa7-f45be187d400"/>
      <item guidRef="325d7c86-da3a-4610-bd25-5cf98cf66a41"/>
      <item guidRef="42bef211-16e5-4b4f-b9ee-52b7b5476232"/>
      <item guidRef="d289f32b-3808-4510-b892-fd2cb0820209"/>
      <item guidRef="266435b4-6e53-460f-9fa7-f45be187d400"/>
      <item guidRef="8723ad52-3e31-473c-8756-7ae85abcc483"/>
      <item guidRef="266435b4-6e53-460f-9fa7-f45be187d400"/>
      <item guidRef="e6644135-9dab-4935-8ab9-fc85527810ca"/>
      <item guidRef="6ae897fd-2eab-4dad-b172-f4fb768c273e"/>
      <item guidRef="266435b4-6e53-460f-9fa7-f45be187d400"/>
      <item guidRef="97e5c8b9-f7e2-453c-92a2-af7fb61e67b2"/>
      <item guidRef="266435b4-6e53-460f-9fa7-f45be187d400"/>
      <item guidRef="76dd9e0c-e9c2-42b6-b8bb-f7717482164e"/>
      <item guidRef="6bd00383-d132-4686-8a21-8d7052b6a81b"/>
      <item guidRef="40cc3adc-498a-4256-a98a-d1210a4019f7"/>
    </modeData>
    </xsl:copy>
  </xsl:template>

The first section adds the new tool button to the end of the Toolbox.  It makes use of template the helper insert-item also defined in the XSLT.   The second section defines a new property bar mode for the tool.  The guid "fd9a53f7-05cc-4cdc-b2ad-0fd6a7ea3480" is unique for this tool as well, and in MyTool::StartAtState(), you'll find the following line:

currentAttribs.PropertyBarGuid = "fd9a53f7-05cc-4cdc-b2ad-0fd6a7ea3480";

This tells the host application that we want to use this property bar when the tool is selected. The items on this sample property bar mode come from the application, mostly from the real line tool.  Custom items can be created and included here as well.

The Resources

The three types of resources that can be defined are icons, cursors and strings.  The config.xml ties a GUID for an item to a particular resource.  In this case we tie "b17f7ca0-0062-4dd8-adf6-1ea2192a3d35" to string "10223" and icon "104.  These resources can be found in the project by double-clicking on resources.rct. 

Note: It may be easier to create icons using an external editor instead of using the built-in editor and then use "Add Resource", "Icon", Import.

The APIs 

Below is a list of all of the new functions added to the CorelDRAW X7.1 and Corel DESIGNER X7 object model:

ClassAPI(s)Description
Application ActiveToolStateGuid [get,set]

This is a replacement for ActiveTool.  It uses a GUID to identify the tool.  Unlike ActiveTool, it can be used to get or set any state.

RegisterToolState, UnregisterToolState

This allows third parties to register or unregister custom tools with CorelDRAW.  UnregisterToolState does not need to be called before shutdown.  RegisterToolState can be called multiple times with the same tool (e.g. if the code has been updated)

CreateOnScreenCurve, CreateOnScreenHandle, CreateOnScreenText Helper function to create an on screen curve, handle or text that is xor'd onto the view
Math Object that provides math utility functions
RegisterUserApplicationPreference This allows third parties to register custom application preferences.  Application preferences persist after shutdown and are stored with the workspace.  They can be access via the AppPrefMgr datasource.  They can also be bound to UI within the application.  They support most basic types (int, string, double, bool) and Color
GetApplicationPreferenceValue, SetApplicationPreferenceValue Get or set any application preference
Document CreateCurveFitToPoints, CreateCurveFitToPointsAndCusps This function creates a Curve that is fit to a Points array.
SampleColorAtPoint, SampleColorInArea This function retrieves a color at a given point (or area) in the document
Curve AppendSubpathFitToPoints, AppendSubpathFitToPointsAndCusps This appends a new curve subpath that is fit to a Points array
ApplyTransformMatrix This method transforms the curve by a TransformMatrix
AppendSubpathFromPoints Creates line segments from the points array
CreateCurveMappedToStroke Creates a curve that is this curve mapped to a stroke, similar to artistic media
CreateCurveMappedToStrokeAndReferenceLine Creates a curve that is this curve mapped to a stroke and reference line, similar to artistic media
AutoReduceNodes Reduces the number of nodes in a curve based on a tolerance value
JoinTouchingSubpaths Connects any subpaths that touch
AppendSubpathCircle Creates a circle subpath
AppendSubpathRectangle Creates a rectangle subpath
AppendSubpathThreePointArc Creates a 3-point arc subpath
SelfWeldClosedSubpaths Self welds any closed subpaths
Window ScreenDistanceToDocumentDistance Converts a screen distance in pixels to document unit distance.  This used to be in Math.
DocumentDistanceToScreenDistance Converts document unit distance to a screen distance in pixels
Node GetPoint, SetPoint Get or set a position of a node using a Point
Segment GetPerpendicularVectorAt Get a perpendicular vector at a position on the segment
GetTangentVectorAt Get a tangent vector at a position on the segment
GetPointAt Get a point from a position on the segment
Subpath EqualDivide Divide the subpath into equal length subpaths
GetEvenlySpacedPoints Get a PointRange of points evenly spaced along the subpath
GetPerpendicularVectorAt Get a perpendicular vector at a position on the subpath
GetTangentVectorAt Get a tangent vector at a position on the subpath
GetPointAt Get a point from a position on the subpath
Shape TransformationMatrix [get, set] Gets or sets the transformation applied to the shape.  This is a replacement for GetMatrix, SetMatrix which do not package up the matrix in an object.
ApplyTransformMatrix This method transforms the shape by a TransformMatrix
Color IsColorStyle Determines if the color is a color style.
ColorStyleName Returns the name of the color style if the color is a color style, otherwise empty.
ModifyColorStyleColor If this color is a color style, this function modifies the underlying color style (i.e. all colors in the document referencing the color style will change).  If changeWholeHarmony is true, all colors in the same harmony will change similar to the wheel in the color styles docker.  If the color is a rule-based harmony, the whole harmony always changes, but the saturation only changes if changeWholeHarmony is true.
StyleSheet AllColorStyles Gets an array of all color styles in the document
CreateColorStyle Creates a new color style
DeleteAllColorStyles Deletes all color styles in the document
DeleteColorStyle Deletes a specific color style in the document
RenameColorStyle Renames a color style in the document
OnScreenCurve - This object represents an xor'd curve that is drawn within the view Show, Hide Show/Hide the curve. 
SetPen, SetNoPen Set the width and color of the curve
SetBrush, SetNoBrush Set the fill of the curve
SetCurve, SetLine, SetRectangle, SetCircle, SetPoints Set the curve
OnScreenHandle - This object represents an xor'd handle glyph that is drawn within the view Show, Hide Show/Hide the handle. 
SetHandleColor Sets the color of the handle
SetPosition Sets the position of the handle
UpdateHotTracking The handle can be draw larger when the mouse is over it, this function allows for this.
IsHotTracked Determines if the handle is hottracking
IsOnHandle Determines is a given point is over the handle
OnScreenText - This object represents an xor'd text that is drawn within the view Show, Hide Show/Hide the text.
SetTextColor Set the text color
SetTextAndPosition Set the text and position of the text
SetText Set only the text
SetPixelOffset Set the the amount in pixels to offset the text by
UpdatePosition Update only the position of the text
ToolStateAttributes - This object provides several attributes and helper functions for custom tools PropertyBarGuid Get/Set the guid for the tool's property bar
ContextMenuGuid [get, set] Get/Set the guid for the tool's context menu
UseTabletPressure [get, set] Determines if the tools should be collecting pressure data
AllowTempPickState [get, set] Determines if the tool can resize objects using the resize handles
AllowAutopan [get, set] Determines if the tool allows autopan while dragging
AllowContextMenu [get, set] Determines if the tool should pop up a context menu with the right mouse click
CanUpdateSelectionOnMouseClick [get, set] Determines if the tool can select different objects when a click happens
DeselectOnLButtonDown [get, set] Determines if the tool should de-select the current shape when the left mouse is clicked
EnterGraceStateOnLButtonDown [get, set] Determines if the tool should enter a grace state when the left mouse button is clicked. This is useful to determine if a click or click+drag is happening.
StatusInfo Sets the status bar tool string
SetCursor Sets the current cursor
SetCursorGuid Sets the current cursor using a resource GUID (which can be exposed via the config.xml file of an addon)
StartTimer Starts a timer that calls into the tool
StopTimer Stops a timer
SnapMouse Snaps a mouse position using current snapping settings
AnchoredSnapMouse Snaps a mouse position using current snapping settings, and allows for more advanced snapping (such as snapping a line to a perpendicular)
ConstrainMouse Uses the current constrain settings to constrain to an angle
IsKeyDown Determines if a given key is held
CurrentPressure Returns the current pen pressure between 0 and 1.
ToolState - This is an object that must be implemented and registered to create custom tools OnStartState Callback when the tool is activated
OnExitState Callback when the tool is deactivated
OnMouseMove Callback when the mouse is moved
OnLButtonDown Callback when the left mouse button is pressed
OnLButtonDownLeaveGrace Callback when the left mouse button is pressed and a small amount of time has passed or the mouse has been moved a short distance
OnLButtonUp Callback when the left mouse button is released
OnLButtonDblClick Callback when the left mouse button is double clicked
OnClick Callback when the mouse has been clicked. New parameter, no longer returns boolean.
OnRButtonDown Callback when the right mouse button has been pressed
OnRButtonUp Callback when the right mouse button has been released
OnKeyDown Callback when a key is pressed
OnKeyUp Callback when a key is released
OnDelete Callback when the Delete key is pressed and released
OnAbort Callback when the ESC key is pressed and released
OnCommit Callback when IsDrawing is true and the user presses enter or space
OnSnapMouse Callback to handle snapping
OnTimer Callback when a registered timer event is invoked
IsDrawing Callback to tell the tool that we're drawing. Several small behaviour changes happen when we are drawing, for example, autopan will activate when the user moves the mouse close to the edge of the view.
Point - object to wrap a simple x and y position x, y [get, set] The coordinate
Add, Subtract Shift the x and y by a vector offset
DistanceTo Get the distance to another point
GetCopy Get a copy of the point
PointRange - object that hold multiple points Item [get, set] Get or set a point within the array
First, Last Get the first or last point within the array
Count Get the number of points within the array
AddPoint, AddPointXY Add a point to the end of the array
InsertPoint, AddPoints, InsertPoints Add and insert points into the array
Remove Remove a point from the array
RemoveRange Remove several points in the array
RemoveAll Clear the array
RemoveAdjacentDuplicates Removes a point where the next point is the same
Reverse Reverses the order of the points
Smoothen Run a smoothing operation of the points. Renamed
GetCopy Get a copy of the PointRange
Vector - object to wrap a simple x and y vector x, y [get, set] The vector's x and y offset
Length [get, set] Get or set the length of the vector
Angle [get, set] Get or set the angle of the vector
GetOffsettedPoint Given a point and a distance, creates a new point which is offsetted perpendicualr to the vector
Add, Subtract Add or subtract vectors
MultiplyBy Scale the vector
Negate Negate the vector
Normalize Set the vector's length to 1.0
AngleBetween Gets the angle in degrees between the vector and another in counter clockwise direction
SmallAngleBetween Gets the small angle in degrees between the vector and another
DotProduct Computes the dot product between this vector and another
CrossProduct Computes the cross product between this vector and another
SetFromPoints Creates a vector from point A to B
ProjectOnto Projects this vector onto another
GetCopy Get a copy of the vector
TransformMatrix - object that stores a linear transformation matrix d11, d12, d21, d22 [get, set] The raw data that stores the transmations - please prefer not to use these
TranslationX, TranslationY [get, set] Gets or sets the translation of the matrix
BasisXAxis, BasisYAxis [get, set] Gets or sets the basis vectors for the matrix
Translation [get, set] Gets or sets the translation for the matrix
SetToIdentity Set the matrix to the identity
Invert Inverts the matrix
TranslateBy, TranslateByVector, SetTranslation Translates the matrix
Rotate Rotates the matrix around (0, 0)
RotateAround Rotates the matrix around a given point
Scale Scales a matrix around (0, 0)
ScaleAround Scales a matrix around a given point
Transform Transforms a matrix by another
TransformAround Transforms a matrix by another around a given point
TransformPoint, UntransformPoint Transforms a point
TransformPoints, UntransformPoints Transforms an array of points
TransformVector, UntransformVector Transforms a vector
IsIdentity Determine if the matrix is the identity matrix
IsSkewedOrRotatedOrMirrored Determine if the matrix is the skewed or rotated or mirrored
ContainsOnlyTranslation Determines if the matrix is only translations
IsSkewedOrRotated Determines if the matrix is skewed or rotated
IsScaledOrSkewedOrRotated Determines if the matrix is scaled or skewed or rotated
IsOrthogonal Determines if the matrix is orthagonal
IsOrthonormalAxisAligned Determines if the matrix is ortho normal axis aligned
IsOrthonormal Determines if the matrix is orthonormal
IsMirrored Determines if the matrix is mirrored
IsScaled Determines if the matrix is scaled
IsTranslated Determines if the matrix is translated
GetCopy Get a copy of the TransformMatrix
MathUtils - object provided by the application that provides several utility math functions Interpolate Creates a point that interpolates two given points
IntersectLineSegments Gets the intersection point of two line segments - returns false if the lines don't intersect
DistanceToLineSegment Gets the distance of a point to a line segment
ClosestPointToLineSegment Gets the closest point to a line segment
IntersectInfiniteLines Gets the intersection point of two lines - returns false if the lines are parallel
DistanceToInfiniteLine Gets the distance of a point to a line
ClosestPointToInfiniteLine Gets the closest point to a line
GetRandomReal Gets a random double precision number
GetRandomInteger Gets a random integer
FitLineToPoints Fits a line to an array of points
MidPoint Creates a point that bisects two given points
CreatePoint Creates a point
CreateVector Creates a vector
CreatePointRange Creates a PointRange
CreateIdentityTransformMatrix Creates an identity TransformMatrix
CreateRotationTransformMatrix Creates a rotation TransformMatrix
CreateTranslationTransformMatrix Creates a translation TransformMatrix
CreateScaleTransformMatrix Creates a scale TransformMatrix
CreateLineSegmentTransformMatrix Creates a TransformMatrix which when applied to the line (FromStart, FromEnd) will result in the line (ToStart, ToEnd)

Notes:

  • VBA tools will require delay load to be off, for this reason alone, it is recommended to use C# or C++. You can also write your tool as a VB dll if that's the language you're most comfortable in.
  • The UserUI.xslt is only loaded once to update the workspace.  If while developing the tool, this file needs to be changed, you will need to reset the workspace by holding F8. It is therefore recommended to work in a temporary workspace while you develop your tool. 
  • The AppUI.xslt file is loaded every time so any changes made will be seen immediately.
  • Users of CorelDRAW X7.1 or higher must be signed in with a valid CorelDRAW Standard or Premium membership to use a custom addon tool.  Standard membership is free for all customers who have purchased the CorelDRAW Graphics Suite X7.
  • If both 32 and 64-bit versions of CorelDRAW installed, the Visual Studio project template will select the 64-bit version.

  • Share
  • History
  • More
  • Cancel
Related
Recommended

© Corel Corporation. All rights reserved. The content herein is in the form of a personal web log ("Blog") or forum posting. As such, the views expressed in this site are those of the participants and do not necessarily reflect the views of Corel Corporation, or its affiliates and their respective officers, directors, employees and agents. Terms of Use / Privacy​ ​/ ​Cookies / Terms and Conditions / User Guidelines.