Drawing shapes is extremely straightforward, as a graphics context provides a series of functions that draw particular shapes. Examples include DrawRect() and DrawEllipse() for drawing rectangular shapes and ellipses, respectively.
While the role of the function is quite obvious from its name , it is often the parameters required by these functions that can determine the appearance of the desired shape. Whether or not the shape is filled or outlined depends on the current pen and brush settings. These are determined by the TPenStyle and TBrushStyle enumerations.
In order to draw an outline shape, the brush style would be set to null and the pen style to a value other than null. Conversely, in order to draw a filled shape without an outline, you would set the pen style to null and the brush style to any value but null. Recalling that pens and brushes also have a color property, it is possible to have separate colors for the outline and filled regions of shapes.
// filled shape no outline gc.SetPenStyle(CGraphicsContext::ENullPen); gc.SetBrushStyle(CGraphicsContext::ESolidBrush); // draw // outline shape no fill gc.SetPenStyle(CGraphicsContext::ESolidPen); gc.SetBrushStyle(CGraphicsContext::ENullBrush); // draw // outline shape with fill gc.SetPenStyle(CGraphicsContext::ESolidPen); gc.SetBrushStyle(CGraphicsContext::ESolidBrush); // draw
The Shapes example converts a data set, provided by the user , into simple graphical charts and covers drawing many of these shapes.
Drawing rectangles is achieved through calling the DrawRect() function of a graphics context. This takes a single trect parameter, which is the area the drawn rectangle will occupy.
gc.DrawRect(rectOfCurrentBar);
Rounded rectangles can also be drawn ”this function takes a second parameter, of type TSize , for the elliptical shape that generates the roundedness of the edges, as demonstrated in Figure 11-10.
gc.DrawRoundRect(rect, roundEdgeSize);
In the Shapes example, the DrawRect() function is used to draw the bars of the bar chart view.
Ellipses are drawn using the DrawEllipse() method and require a single parameter of type TRect . This is the rectangular area within which the ellipse will be centered.
gc.DrawEllipse(ellipseRect);
Arcs and pie slices are drawn in fundamentally the same way. The first parameter is the rectangular area within which resides the elliptical region, of which the arc or pie is a fraction. The other two parameters are two points through which radials can be drawn from the center of the ellipse. The arc or pie is drawn between the points where these radials intercept the edges of the ellipse. The pie area includes the radials to the intersection; the arc produces a chord when filled.
gc.DrawPie(KPieRect, pieStartPoint, pieEndPoint);
This is illustrated in Figure 11-11.
DrawPie() would result in filling the area bounded by the radials and the arc.
When drawing pies, arcs, or any other shapes, you must remember that the Cartesian coordinate system differs from the coordinate system of a computer screen, or a Series 60 device ”the origin is at the top left-hand corner, and the y axis increases downward. |
There are two separate functions for drawing polygons: DrawPolyLine() and DrawPolygon() . DrawPolyLine() will draw an outline shape, while DrawPolygon() will be filled. Polygons comprise of an array of points, and these are provided to either function in order to render the desired shape.
// Create Array of points (1 is added to // allow for origin point) CArrayFix<TPoint>* polyLineArray = new (ELeave) CArrayFixFlat<TPoint>(numElements + 1); CleanupStack::PushL(polyLineArray); polyLineArray->AppendL(origin); // Iterate value model. Calculate points based on // values and append to points array. for (TInt i = 0; i < numElements; i++) { // Calculated height of line based on input data heightOfCurrentLine = (iShapesModel.ElementAt(i) * aAxisRect.Height()) / maxValue; xOfCurrentLine = origin.iX + ((i + 1) * widthOfLineSpacer); yOfCurrentLine = origin.iY - heightOfCurrentLine; polyLineArray->AppendL(TPoint(xOfCurrentLine, yOfCurrentLine)); } gc.DrawPolyLine(polyLineArray);
The code snippet above is taken from the Shapes application and is used to generate a line graph based on the data provided by the application's data model.
A special parameter that can be passed to the DrawPolygon() function determines how the shape will be filled if lines of the polygon should cross over each other. The TFillRule enumeration has two values, EAlternate and EWinding , with EAlternate filling only odd-numbered bounded regions, as illustrated in Figure 11-12.