Draw randomly colored dots in DrawingArea - how?
Posted
#1
(In Topic #1230)
Trainee
How do I make is to that I get to see randomly colored dots across the entire DrawingArea?
To make the dots standout, I'm using an expanded a 128x128 canvas.
This is my first foray into the DrawingArea object and there's very little documentation (that I could find) to help me trundle along so here I am.
Code (gambas)
- ' Gambas class file
- With Paint
- .Brush = .Color(Color.RGB(red, green, blue, 0))
- .LineWidth = 3.0
- .MoveTo(xpos, ypos)
- .LineTo(xpos + factor - 1, ypos)
- .LineTo(xpos + factor - 1, ypos + factor - 1)
- .Lineto(xpos, ypos + factor - 1)
- .LineTo(xpos, ypos)
- .Stroke
- .End
- xpos = x * factor
- ypos = y * factor
- red = Rand(100, 255)
- green = Rand(100, 255)
- blue = Rand(100, 255)
- DrawingArea1.Refresh
- DrawingArea1.Refresh
- DrawingArea1.Refresh
Posted
Guru

Calling .Refresh triggers the draw event to clear the area and draw anew. (not just part of it)
So what you have there is an animation rapidly showing random single dots.
you should put the loop in the Draw event and call the paint function and not DrawingArea1.Refresh so many times.
Code (gambas)
- DrawingArea1.Refresh ' trigger Draw event
- With Paint
- .Brush = .Color(Color.RGB(red, green, blue, 0))
- .LineWidth = 3.0
- .MoveTo(xpos, ypos)
- .LineTo(xpos + factor - 1, ypos)
- .LineTo(xpos + factor - 1, ypos + factor - 1)
- .Lineto(xpos, ypos + factor - 1)
- .LineTo(xpos, ypos)
- .Stroke
- xpos = x * factor
- ypos = y * factor
- red = Rand(100, 255)
- green = Rand(100, 255)
- blue = Rand(100, 255)
- PaintDot()
Posted
Guru

Like I say it depends on the application, sometimes a DrawingArea is prefered , sometimes a Picture
A PictureBox can be easily manipulated and things added to it,
or then there's the DrawingArea that has to paint its contents via code with each refresh..
Another option is to paint the Picture and then use Paint.DrawPicture() in the DrawingArea1_Draw() event to paint it as a background that you then paint on top of.
PS. i noticed in your code you used Paint.End in the Draw event.
you should not really do that, you should only use Paint.End if you have used Paint.Begin() on an object.
The Draw event is inside the controls Paint.Begin/Paint.End instructions so you do not need to use Paint.End. the control may possibly have more drawing to do and will expect the Paint device to be active.
Posted
Trainee
BruceSteers said
Depending on the application it can be better to use a simple PictureBox and use paint functions to paint the picture.
Like I say it depends on the application, sometimes a DrawingArea is prefered , sometimes a Picture
A PictureBox can be easily manipulated and things added to it,The benefits of a Picture over a drawing area is it can be added to bit by bit and the picture just displayed as it is,
or the drawingarea that has to paint its contents via code each refresh..
PS. i noticed in your code you used Paint.End in the Draw event.
you should not do that, you should only use Paint.End if you have used Paint.Begin() on an object.
The Draw event is inside the controls Paint.Begin/Paint.End instructions you you do not need to End it. the control may possibly have more drawing to do and will expect the Paint device to be active.
Thanks muchly, Bruce.
I'll experiment with the PictureBox too as I'm still in the early stage of my project so no lock-in yet - brain or code -
PS: The code in DrawingArea1_Draw() was a copy and paste from an example I spotted somewhere in the forum - copied and pasted without any understanding as I experimented.
Let the awakening begin…
Cheers,
ak.
Posted
Trainee
I've modified my code as you had it above and noticed that the DrawingArea refresh several times when loses or gains focus and on form resize. Is this something that can be overcome?
As it currently stands, it's not ideal for what I'm planning to do with it. The PictureBox is already gaining favor.
ak.
Posted
Guru

ak2766 said
Hey Bruce,
I've modified my code as you had it above and noticed that the DrawingArea refresh several times when loses or gains focus and on form resize. Is this something that can be overcome?
As it currently stands, it's not ideal for what I'm planning to do with it. The PictureBox is already gaining favor.
ak.
Sorry i just adapted your code to work but didn't really think about it, yes a Refresh can happen all by itself.
This is what i meant about using a Picture or DrawingArea depending on purpose.
options are to paint a picture and just show that in the Draw event.
or make your dots an array that the Draw event paints the same array each time.
Posted
Trainee
BruceSteers said
…
or make your dots an array that the Draw event paints the same array each time.
Ouch! That was like a wake up slap - duh - :mrgreen: !
Posted
Guru

ak2766 said
BruceSteers said
…
or make your dots an array that the Draw event paints the same array each time.
Ouch! That was like a wake up slap - duh - :mrgreen: !
Haha.
I think your main problem was thinking the Draw() event and refresh do little bits.
But no , the refresh triggers the Draw event for a complete draw.
knowing that you should get thing rolling now
PS. never use Refresh in a Draw event as it will recursively crash.
also a good tip. try not to use anything that causes a Refresh in a draw event. like changing size or setting certain other properties. use the BeforeArrange() event for things like that.
Posted
Trainee
BruceSteers said
Haha.
I think your main problem was thinking the Draw() event and refresh do little bits.
But no , the refresh triggers the Draw event for a complete draw.
Exactly! I initially only had the redraw in the inner loop but thought maybe I needed more -
Thanks for your help. Really appreciated.
Cheers,
ak.
Posted
Trainee
If I wanted to clear the DrawingArea, what's the process?
Some reading [1] led me to believe that the .Clear method would be the answer but it doesn't do what I expected:
I even tried setting the .Cached to True but that caused dots to not be drawn at all.
Help!
[1]: /comp/gb.qt4/drawingarea/clear - Gambas Documentation
EDIT: Nevermind. I figured out how to do it by iterating through all dots and deleting them one by one and then calling PaintDot. I was hoping there was a way to clear them all at once but this has the added benefit of allowing me to delete selectively - which is something I need later anyway.
1 guest and 0 members have just viewed this.



