I came across a problem when I was trying to create logical screens on the Presto that I could swap with a button press. The essence of the problem was that I could blank the current screen, but to redraw the new screen I had to draw all the ‘widgets’ relating to the new screen twice for them to be displayed.
The minimal example code that illustrates this is shown below. The code puts a white rectangle on the screen for 2 seconds, the screen is cleared and an orange rectangle should then be displayed for 5 seconds. However, unless the orange rectangle is created twice (in the example by uncommenting the second “rect.rectangle(10,35,100,40)” statement I do not get the orange rectangle displayed on the screen.
from presto import Presto
from picovector import PicoVector, Polygon, Transform, ANTIALIAS_X16
import time
presto = Presto(full_res=True)
display = presto.display
vector = PicoVector(display)
t = Transform()
vector.set_transform(t)
vector.set_antialiasing(ANTIALIAS_X16)
vector.set_font("Roboto-Medium.af", 14)
vector.set_font_letter_spacing(100)
vector.set_font_word_spacing(100)
vector.set_font_size(40)
rect = Polygon()
BLACK = display.create_pen(0, 0, 0)
WHITE = display.create_pen(255, 255, 255)
ORANGE = display.create_pen(200,100,100)
print('clear screen and show a rectangle')
display.set_pen(BLACK)
display.clear()
display.set_pen(WHITE)
rect.rectangle(10,35,100,40)
vector.draw(rect)
presto.update()
time.sleep(2)
print('clear screen and show another rectangle')
display.set_pen(BLACK)
display.clear()
display.set_pen(ORANGE)
rect.rectangle(10,35,100,40)
#rect.rectangle(10,35,100,40) # uncomment this to get a rectangle
vector.draw(rect)
presto.update()
time.sleep(5)
So the screen clears the first rectangle and displays the new rectangle only if I put 2 rect.rectangle(10,35,100,40) statements, but this would seem to indicate something is amiss.
If I understand correctly how Pico vector works, a Polygon can consist of multiple different shapes. E.g. if you call rectangle multiple times on the same polygon with different coordinates, the final shape will include all those boxes. Now you are adding multiple boxes with same coordinates, so they go on top of each other. Don’t really know how it’s meant to behave in that case, but seems like now they somehow cancel each other out.
But in your case the fix is simple, move rect.rectangle(10,35,100,40) statement right after rect = Polygon() and remove all other rect.rectangle calls, you only need the first one since you want only one box.
You can see how the “cancelling each other out” works if you shift the coordinates of the second rectangle call a little in your original example, so that they overlap a little bit but not completely.
Looked into PicoVector docs and it works as it’s supposed to. Drawing shapes on top of each other is meant to “erase” the overlapping part, that’s how you can draw more complicated things.
Check here in the “Drawing something” part of the README and see the example (with three overlapping circles):
@cvuorinen Thanks for your comments, but I do actually want two shapes in the same place after a screen clear. Probably the minimal example of two identical rectangles was not an optimal choice for the example. The idea is that a screen_1 will have items, like a rectangle, then all the items are cleared and other items are are drawn on the screen_2, without the items, like the first rectangle interfering with whats is now to be placed on screen_2.
I suppose its my assumption as to what display.clear() does it the issue. It seems that a display.clear() still keeps the items previously drawn lurking in the background and I have to first draw all the items that were on the screen in a background colour and then draw the new shapes. I give an example of this with a rectangle and a circle shape in the same spot. After a screen clear, if the circle is then drawn without first drawing the original rectangle in the background colour it shows up again and interferes with the newly drawn circle.
from presto import Presto
from picovector import PicoVector, Polygon, Transform, ANTIALIAS_X16
import time
presto = Presto(full_res=True)
display = presto.display
vector = PicoVector(display)
t = Transform()
vector.set_transform(t)
vector.set_antialiasing(ANTIALIAS_X16)
vector.set_font("Roboto-Medium.af", 14)
vector.set_font_letter_spacing(100)
vector.set_font_word_spacing(100)
vector.set_font_size(40)
p = Polygon()
BLACK = display.create_pen(0, 0, 0)
WHITE = display.create_pen(255, 255, 255)
ORANGE = display.create_pen(200,100,100)
print('clear screen and show a rectangle')
display.set_pen(BLACK)
display.clear()
display.set_pen(WHITE)
p.rectangle(10,35,100,40)
vector.draw(p)
presto.update()
time.sleep(2)
print('clear screen and draw a circle')
display.set_pen(BLACK)
display.clear()
#p.rectangle(10,35,100,40) # uncomment to clear the rectangle shape.
# put in an extra update and pause to show the screen is cleared
presto.update()
time.sleep(2)
# now display a circle
display.set_pen(ORANGE)
p.circle(40,45,40)
vector.draw(p)
presto.update()
time.sleep(5)
Should a display.clear() be enough to erase all the items drawn on the screen without needing to individually draw all the shapes in the background colour individually. I hoped so, but it does not do so. :)
@cvuorinen Your second post came whilst I was writing my last post. Thanks again for the info on PicoGraphics. This is the first time I’m having a play with all this. I shall have to see what I can find. I’ve not found a good doc, but rather small snippet docs, and it seems one’s familiarisation is garnered by ploughing through example code. I remember in the days of VB6 one could buy a whole book on a VB6 ‘bible’ to get all the info, but that era is long gone I suppose. But I rather think that a display.clear() could be made to remove all the shapes without further ado. Well it gets my vote anyway :)
@cvuorinen Thanks, thats got the snippet working. Now I must see how to incorporate that into my widget classes, of dials and text boxes etc. but you’ve set me off on the right path. Lots of different polygons here we come :)