CURA-4182
The canvas approach has a drawback on the UI update: when a printcore
or a material is changed, calling requestPaint() to the canvas doesn't
trigger an immediate update. The solution is to have a built-in Timer in
the Canvas and to use that to update. Somehow this just works. The
problem with this approach is that the Timer constantly updates the
canvas which eats a lot of CPU power. To solve this, I changed the timer
to be a one-time timer and it will be started when there is a
material/print core update.