Skip to content

Writing Drawing Code for Android, Desktop, iOS and Web

When writing code it’s always a good idea to be thinking about the future. Today you are creating a desktop project but tomorrow you might need to create an Android or iOS project. That code you’re writing might be code you could use for another project for another platform.

For the most part, writing drawing code will just work because you use Xojo’s Graphics class for Android, Desktop and iOS projects. Web projects, however, don’t use the Graphics class. The WebCanvas control’s Paint event is passed a WebGraphics object. While the Graphics and WebGraphics classes have a lot in common, sharing many of the same methods with the same parameters, they are two distinctly different classes from the perspective of the Xojo compiler. That means that while the code you write will look almost identical, you still have to use a Graphics object for Android, Desktop and iOS projects and a WebGraphics object for Web projects.

Your instinct might be to simply write the code for one and then copy it to the other projects, changing Graphics to WebGraphics for Web projects. This will of course work, but then you have to remember to do this copy/paste/change operation every time you update your code. That’s not ideal.

Graphics vs. WebGraphics

With Xojo, the code can be written in such a way as to automatically handle the difference between Graphics/WebGraphics. Most often your graphics methods will be called from something that provides a Graphics or WebGraphics object for you to draw into such as a Canvas control’s Paint event. From there your code will call your methods that do the drawing. The problem is that your methods can’t use a Graphics or a WebGraphics type as a parameter because Graphics is not going to work for your Web projects and WebGraphics doesn’t exist in any framework except the Web framework. Thus using it anywhere else will result in a compiler error.

Using a Variant

Getting around this limitation is, fortunately, quite easy. Instead of using Graphics or WebGraphics as a parameter type, you use Variant. A Variant can hold any type of data from Strings to Integers, to Graphics to WebGraphics and more.

Once your drawing method gets the Variant though, it can’t use it to draw. It can only use a Graphics or WebGraphics objects. The trick is to then copy it into a Graphics or WebGraphics class variable:

Var g As Graphics = context

or

Var g As WebGraphics = context

The problem you now face, as mentioned earlier, is that WebGraphics only exists in Web projects. That means you have to write your code in such a way that you will declare the variable g as a Graphics object in Android, Desktop and iOS projects and as a WebGraphics object in Web projects. This can be achieved via conditional compilation. This is a simple technique that tells the Xojo compiler to only compile code into your app if conditions you specify are met. In this case, if you’re targeting Desktop or Mobile, it should compile in the line that uses the Graphics type, and if you are targeting a Web app, the line that uses WebGraphics. To conditionally compile, you just need to add that conditional code around these two lines:

#If TargetDesktop Or TargetMobile Then
   Var g As Graphics = context
#EndIf

#If TargetWeb Then
   Var g As WebGraphics = context
#EndIf

Since a project must be only one of the above types, when you run or build your project, the appropriate line of code will be compiled in. From there, you now have a variable (g) of the right type can use this to draw whatever you like. For example, there are four identical example projects (one for each project type) that show off this technique. They can be found in the Xojo IDE by choosing File > New Project, clicking on Examples, choosing the Graphics folder in the list and then the Cross-Platform Drawing folder. The examples all draw a checkerboard that looks like this:

They all contain the an identical Checkerboard class that handles the drawing. This class has DrawBorder and DrawCheckers methods that both take a Variant as a parameter. In each project is a Canvas control whose Paint event calls these methods:

Var cb As New Checkerboard
cb.DrawBoard(g)
cb.DrawCheckers(g)

The full DrawBoard method looks like this:

#If TargetDesktop Or TargetMobile Then
  Var g As Graphics = context
#EndIf

#If TargetWeb Then
  Var g As WebGraphics = context
#EndIf 

Var boxSize As Integer = Min(g.Width/8, g.Height/8) 'The size of the box
'Draw the rows
For y As Integer = 0 To 7
  For x As Integer = 0 To 7
    'Switch colors for each box in the row
    If g.DrawingColor = Color.Black Then
      g.DrawingColor = Color.White
    Else
      g.DrawingColor = Color.Black
    End If
    'Draw a box
    g.FillRectangle(x * boxSize, y * boxSize, boxSize, boxSize)
  Next
  'Switch colors again for the beginning of the next row
  If g.DrawingColor = Color.Black Then
    g.DrawingColor = Color.White
  Else
    g.DrawingColor = Color.Black
  End If
Next

In the example projects, check out the DrawCheckers method as well. It uses the same technique. What is great about this is that this class can be copied into any Android, Desktop, iOS or Web project and it will indeed just work.

Checking Out the Examples

There are four example projects (one for each project type – Android, Desktop, iOS and Web) that demonstrate the technique explained here. You can find them in the Xojo IDE by choosing File > New Project, clicking on Examples, choosing the Graphics folder in the list and then the Cross-Platform Drawing folder.

Geoff Perlman is the Founder and CEO of Xojo. When he’s not leading the Xojo team he can be found playing drums in Austin, Texas and spending time with his family.