Articles 3D Audio Custom Controls General RB Graphics Hacks Mac OS X Menus Novelty Printing REALbasic 2005 REALbasic 2006 Registration Resources Reviews Serial Speech Sockets XML Video Resource Links News Current News February 2006 January 2006 December 2005 November 2005 October 2005 September 2005 August 2005 July 2005 June 2005 May 2005 April 2005 March 2005 ![]() REALbasic for Dummies by Erick Tejkowski ![]() Learning REALbasic through Applications REALbasic for Macintosh REALbasic Cross-Platform Application Development
Older files are in Stuffit 5 or greater format. Newer files are ".Zip". Download StuffIt Expander |
|
Today we're just going to take a brief look at drawing in Quartz thanks to the new Graphics.Handle feature in REALbasic 2006r1. What we'll do is setup a Quartz CGContextRef for a Canvas and clip it to the bounds and then draw a rectangle with a shadow in it.
A Bunch of Declares Let's first get the declares out of the way. You really don't need to know how to create these, if you do because you plan to make more, well, this isn't quite the place to learn since it requires a bunch of background knowledge anyway. Declare Function QDBeginCGContext Lib "Carbon" _
(CGrafPtr as Integer, ByRef CGContextRef as Integer) as Integer
Declare Function QDEndCGContext Lib "Carbon" _
(CGrafPtr as Integer, ByRef CGContextRef as Integer) as Integer
Declare Sub CGContextSaveGState Lib "Carbon" _
(CGContextRef as Integer)
Declare Sub CGContextRestoreGState Lib "Carbon" _
(CGContextRef as Integer)
Declare Sub CGContextClipToRect Lib "Carbon" _
(CGContextRef as Integer, rect as CGRect)
Declare Sub CGContextTranslateCTM Lib "Carbon" _
(CGContextRef as Integer, tx as Single, ty as Single)
Declare Sub CGContextFillRect Lib "Carbon" _
(CGContextRef as Integer, rect as CGRect )
Declare Sub CGContextSetRGBFillColor Lib "Carbon" _
(CGContextRef as Integer, Red as Single, Green as Single, Blue as Single, Alpha as Single)
Declare Sub CGContextSetShadow Lib "Carbon" _
(CGContextRef as Integer, offset as CGPoint, Blur as Single)
The Drawing Code Ok, now to the code to draw in the canvas. The first thing we do is just draw the white background and declare a few variables. Nothing fancy there. CGContextRef will hold the pointer to the CGContext variable which is synonymous to the "Graphics" class of Quartz. Sub Paint(g As Graphics)
*<the declares go here>*
// Background
g.ForeColor = &cFFFFFF
g.FillRect 0, 0, g.Width, g.Height
dim err, CGContextRef as Integer
dim rect as CGRect
const noErr = 0
// Open CGContext
err = QDBeginCGContext(g.Handle(Graphics.HandleTypeCGrafPtr), CGContextRef)
if err <> noErr then
break
return
end if
CGContextSaveGState(CGContextRef)
So what we need to do is first clip the bounds of the context (that is, limit the area we can draw into) and then translate the coordinate system so that it matches that of the canvas. One thing to note is that Quartz uses a bottom-left coordinate system. That means that it's like a normal Cartesian coordinate system. It's like making an "L" with your left hand - your thumb points to positive X and your first finger points to positive Y. This is really useful in some cases but in others its not. Unfortunately, I haven't been able to find a way to flip the coordinate system of a CGContext so for now we're just going to stick to the Quartz system and realize that when we're drawing with Quartz we're using its coordinate system.
// Clip to the Canvas's bounds
rect.origin.x = me.Left
rect.origin.y = self.Height - (me.Top + me.Height)
rect.dimens.width = me.Width
rect.dimens.height = me.Height
CGContextClipToRect(CGContextRef, rect)
CGContextTranslateCTM(CGContextRef, me.Left, self.Height - (me.Top + me.Height))
dim offset as CGPoint
offset.x = OffsetX
offset.y = -OffsetY 'negative because quartz and RB use two different coordinate systems
rect.origin.x = g.Width / 2 - 50.0
rect.origin.y = g.Height / 2 - 50.0
rect.dimens.width = 100.0
rect.dimens.height = 100.0
// Draw Rect
CGContextSetShadow(CGContextRef, offset, Blur)
CGContextSetRGBFillColor(CGContextRef, 1.0, 0, 0, 1.0)
CGContextFillRect(CGContextRef, rect)
// Close CGContext
CGContextRestoreGState(CGContextRef)
err = QDEndCGContext(g.Handle(Graphics.HandleTypeCGrafPtr), CGContextRef)
if err <> noErr then
break
return
end if
After restoring the state of our context (since we changed the clipping and origin we need to save the existing state before we do that, and then restore it after we're done) we close it (which then synchronizes the drawing to the window's buffer) and we're all done. After that we can go back to using REALbasic drawing code.
// REALbasic Drawing -- Unfortunately you can't draw using
// RB while the CGContext is open. If you could, you could set
// the shadow and then draw using RB and those objects could
// get shadows, but it doesn't work that way, despite RB using
// Quartz to draw
// Border
g.ForeColor = &c555555
g.DrawRect 0, 0, g.Width, g.Height
// Random Circle
g.ForeColor = &c0000FF
g.FillOval 30, 200, 40, 40
End Sub
Finished I wanted to have much more complex project, but I ran into some annoyingly serious problems as I was writing the project, so it will have to wait for a future release of REALbasic to have them fixed. In the mean time, you can download this project.
|
||||
|
||||||||||||||||||||||||||||||||
Maintained by the Staff of ResExcellence. This entire site ©1997-2006 ResExcellence
Privacy Statement? Sure we gotta Privacy Statement.
[an error occurred while processing this directive]