Simple Drawing Application

By Sergey Malenkov, November 5, 2008

This example is an easy-to-write application that enables the user to draw with the mouse. The color and thickness of the pen can also be customized.

Understanding the Code

The Draw class creates a canvas that enables the user to draw with the mouse.

The drawing code is very compact, as shown in Figure 1. The canvas variable is an empty Group object. Each time a mouse button is pressed, a new Path object is created and added to the canvas. The path starts at the point where the button press has occurred. When the mouse is dragged past the starting point, new segments are created and added to the path. These segments are immediately visible onscreen because the path is added to the Scene.

Source Code
Rectangle {
  fill: BG
  width: bind canvas.scene.width - Rect_Padding
  height: bind canvas.scene.height - Rect_Padding
  var path: Path;
  onMousePressed: function(mouse) {
    path = Path {
      stroke: COLOR
      strokeWidth: SIZE
      strokeLineCap: StrokeLineCap.ROUND
      strokeLineJoin: StrokeLineJoin.ROUND
      elements: MoveTo { x: mouse.x   y: mouse.y }
    }
    insert path into canvas.content
  }
  onMouseDragged: function(mouse) {
    insert LineTo { x: mouse.x   y: mouse.y } into path.elements
  }
  onKeyPressed: function(key) {
    if (key.controlDown and key.code == KeyCode.VK_Z) {
      undo()
    }
  }
}
  

Figure 1: Drawing Code

The rest of the application deals with controls that provide for choosing color and line width.

The color chooser is a simple collection of Rectangle objects in VBox and HBox that represent colors from the COLORS variable which is shown in Figure 2. The selected color is marked with the stroke of the rectangle. The selected color is replaced with the current color when the mouse is pressed.

Source Code
                     HBox {
                       spacing: CONTENT_PADDING
                       content: for (color in COLORS) Rectangle {
                           fill: color
                           width: D
                           height: D
                           blocksMouse: true
                           cursor: Cursor.HAND
                           onMousePressed: function(e) {
                               COLOR = color
                           }
                       }
                  }
  

Figure 2: Creating the Color Chooser

The line width selector is more complicated, as shown in Figure 3. The Line object represents line width and the selected color. The Circle object provides all functionality. The selected line width is marked with the stroke of the circle. The selected line width is replaced with the current line width when the mouse is pressed.

Source Code
                    HBox {
                      spacing: CONTENT_PADDING
                      content: for (size in [1..5]) Group {
                          content: [
                              Circle {
                                  strokeWidth: circle_widthstroke
                                  stroke: bind if (SIZE == size)  then FG  else null
                                  fill: BG
                                  radius: D / Padding
                                  blocksMouse: true
                                  cursor: Cursor.HAND
                                  onMousePressed: function(e) {
                                      SIZE = size
                                  }
                             }
                             Line {
                                 def o = (D - size) / Padding - Line_Padding;
                                 strokeWidth: size
                                 stroke: bind COLOR
                                 strokeLineCap: StrokeLineCap.ROUND
                                 startX: -o
                                 endX: o
                             }
                         ]
                     }
                 }
  

Figure 3: Creating the Line Width Selector

Customizing the Code

To further customize, change the following variables.

D
the width and height of the buttons in color chooser and line width selector
BG
the background color of the canvas
FG
the color of the strokes that are used to mark selected color and line width

Source Code
def D = 22;
def BG = Color.WHITE;
def FG = Color.BLACK;
def COLORS = [
  Color.RED,
  Color.ORANGE,
  Color.YELLOW,
  Color.GREEN,
  Color.LIGHTBLUE,
  Color.BLUE,
  Color.MAGENTA,
  Color.BLACK
];
  

Figure 4: Customizing the Variables