Skip to content

Writing a Custom Brush

Cameron White edited this page Jun 16, 2013 · 8 revisions

This guide assumes that you have set up a basic add-in as described in [Writing an Add-in] (https://github.com/PintaProject/Pinta/wiki/Getting-Started:-Writing-an-Addin).

This guide will demonstrate how to write a custom brush that can be used by the Paintbrush tool. The source code for this example is available at https://github.com/PintaProject/BlockBrush, and the brush can be installed from Pinta's add-in repository.

The Basics

Ensure that the add-in description file (.addin.xml) has the category set to Brushes. This will make it easier for users to find your brush in the Add-in Gallery. The add-in description file should now look like:

<?xml version="1.0" encoding="UTF-8"?>
<Addin id="BlockBrush" version="0.1" category="Brushes">
    <Header>
        <Name>Block Brush</Name>
        <Description>A brush similar to the block brush in GIMP.</Description>
        <Author>Cameron White</Author>
        <Url>https://github.com/PintaProject/BlockBrush</Url>
    </Header>
    <Dependencies>
        <Addin id="Pinta" version="1.5" />
    </Dependencies>
</Addin>

All brushes inherit from Pinta.Core.BasePaintBrush. There are two required methods that you must implement:

  • You must provide the Name of the brush. This should be a user-friendly (and translatable) name, as it will be displayed to users in the toolbar of the Paintbrush tool.
  • You must implement the OnMouseMove method. This is called whenever the user moves the mouse, and is where we will be drawing onto the canvas. The method must return a rectangle containing the area of the canvas that should be redrawn.

Let's add these - for now, we won't do anything in the OnMouseMove method, so we'll just return the empty rectangle:

using System;
using Mono.Addins;
using Pinta.Core;

namespace BlockBrush
{
    public class BlockBrush : BasePaintBrush
    {
        public override string Name {
            get { return AddinManager.CurrentLocalizer.GetString ("Block"); }
        }

        protected override Gdk.Rectangle OnMouseMove (Cairo.Context g, Cairo.Color strokeColor,
                                                      Cairo.ImageSurface surface,int x, int y,
                                                      int lastX, int lastY)
        {
            return Gdk.Rectangle.Zero;
        }
    }
}

Implementing the Brush

Registering the Brush

We've now written a brush, but we haven't told Pinta about it yet. In the IExtension subclass, we need to call PintaCore.PaintBrushes.AddPaintBrush to register the brush, and PintaCore.PaintBrushes.RemoveInstanceOfPaintBrush to unregister the brush:

using System;
using Pinta.Core;

namespace BlockBrush
{
    [Mono.Addins.Extension]
    public class BlockBrushExtension : IExtension
    {
        public void Initialize ()
        {
            PintaCore.PaintBrushes.AddPaintBrush (new BlockBrush ());
        }

        public void Uninitialize ()
        {
            PintaCore.PaintBrushes.RemoveInstanceOfPaintBrush (typeof (BlockBrush));
        }
    }
}