CMP EMBEDDED.COM

Login | Register     Welcome Guest  
HOME DESIGN PRODUCTS COLUMNS E-LEARNING CONFERENCES CODE FORUMS/BLOGS NEWSLETTERS CONTACT FEATURES RSS RSS

Listing 3 : Functions for drawing and erasing objects and refreshing the display
void displayRefresh(void)
{
Drawable *drawablePtr; /* for iterating through lists */
int offsetX;
int offsetY;
/* 
First erase the old images of the dirty objects
*/
for (drawablePtr = GS_dirtyList;
drawablePtr != NULL;
drawablePtr = drawablePtr->nextDirtyDrawablePtr)
{
/*
We only erase the image if there was an old
parent and it 
is not dirty. Strictly speaking we should check the parentýs 
parent and so on, but the extra work would probably not pay 
off in terms of avoiding extra redraws.
*/
if ( (drawablePtr->oldParentPtr != NULL) &&
(drawablePtr->oldParentPtr->visible) &&
(!drawablePtr->oldParentPtr->drawable.dirty) )
{
offsetX = drawablePtr->oldParentPtr->absoluteLeft;
offsetY = drawablePtr->oldParentPtr->absoluteTop;
drawableErase(drawablePtr, offsetX,
offsetY);
} 
} /* end for */
/*
The next step is to draw all of the dirty objects 
*/
for (drawablePtr = GS_dirtyList;
drawablePtr != NULL;
drawablePtr = drawablePtr->nextDirtyDrawablePtr)
{
/*
We only draw the image if there is a parent and it is not 
dirty. Strictly speaking we should check the parentýs parent 
and so on, but the extra work would probably not pay off.
*/
if ( (drawablePtr->parentPtr != NULL) &&
(drawablePtr->parentPtr->visible) &&
(!drawablePtr->parentPtr->drawable.dirty) )
{
offsetX = drawablePtr->parentPtr->absoluteLeft;
offsetY = drawablePtr->parentPtr->absoluteTop;
drawableDraw(drawablePtr, offsetX, offsetY);
} /* end if */
} /* end for */
/* 
Now that the objects have been updated the dirty flag can be 
cleared. These flags should not be cleared in one of the earlier 
loops because they are used for optimizations in the drawableDraw 
function. Note that the links of the chain are not set to NULL.
This does not matter because they will get overwritten if it is put
on the chain again.
*/
drawablePtr = GS_dirtyList;
for (drawablePtr = GS_dirtyList;
drawablePtr != NULL;
drawablePtr = drawablePtr->nextDirtyDrawablePtr)
{
drawablePtr->dirty = FALSE;
}
GS_dirtyList = NULL; 
}
void drawableDraw(Drawable *drawablePtr, int offsetX, int offsetY)
{
/* draw should never be called for an orphan */
assert(drawablePtr->parentPtr != NULL);
switch (drawablePtr->type)
{
case
CONTAINER:
containerDraw((Container *)drawablePtr, offsetX, offsetY);
break;
case BOX: 
boxDraw((Box *)drawablePtr, offsetX, offsetY);
break;
case CIRCLE:
circleDraw((Circle *)drawablePtr, offsetX, offsetY);
break;
case LINE:
lineDraw((Line *)drawablePtr, offsetX, offsetY);
break;
case TEXT:
textDraw((Text *)drawablePtr, offsetX, offsetY);
break;
default:
assert(FALSE);
}
/* 
Update the oldParent for the time when we will want to 
erase this
drawable
*/
drawablePtr->oldParentPtr = drawablePtr->parentPtr;
}
/*
This function decides what kind of shape we have and chooses an
erase routine based on the type field of the Drawable structure.
{
if (drawablePtr->oldParentPtr == NULL)
{
/*
If there is no old parent then there is nowhere to 
erase from.
*/
return;
}
switch (drawablePtr->type)
{
case CONTAINER:
containerErase((Container *)drawablePtr, offsetX, offsetY);
break;
case BOX:
boxErase((Box
*)drawablePtr, offsetX, offsetY);
break;
case CIRCLE:
circleErase((Circle *)drawablePtr, offsetX, offsetY);
break;
case LINE:
lineErase((Line *)drawablePtr, offsetX, offsetY);
break;
case TEXT:
textErase((Text *)drawablePtr, offsetX, offsetY);
break;
default:
assert(FALSE);
}
}
void boxDraw(Box * boxPtr, int offsetX, int offsetY)
{
int top;
int left;
int right;
int bottom;
assert(boxPtr->drawable.parentPtr != NULL);
left = offsetX + boxPtr->drawable.area.left;
top = offsetY + boxPtr->drawable.area.top;
right = offsetX + boxPtr->drawable.area.right;
bottom = offsetY + boxPtr->drawable.area.bottom;
#ifdef USING_BGI
setcolor(boxPtr->drawable.color);
if (boxPtr->filled)
{
setfillstyle(SOLID_FILL, boxPtr->fillColor);
fillRectangle(left, top, right, bottom);
}
else
{
setfillstyle(EMPTY_FILL, boxPtr->fillColor);
rectangle(left, top, right, bottom);
}
#endif
/* 
We have to record all of the old stuff now, so it can be used on
the
next erase
*/
boxPtr->drawable.oldArea = boxPtr->drawable.area;
boxPtr->oldFilled = boxPtr->filled;
}
/*
This function will draw over a box in the background color of 
the parent, and therefore erase the box. The background color
of the old parent is used because the current parent may be 
different, and the image that we are trying to remove is in the 
old parent.
If the old parent has moved or changed color, then this routine 
would not work. This is not a problem, because if the old parent
had
moved then it would be marked dirty and this routine would
never be called. The redraw of the old parent would clean any
image of the box that remained.
*/
void boxErase(Box *boxPtr, int offsetX, int offsetY)
{
int backgroundColor;
int absoluteLeft = offsetX + boxPtr->drawable.oldArea.left;
int absoluteTop = offsetY + boxPtr->drawable.oldArea.top;
int absoluteRight = offsetX + boxPtr->drawable.oldArea.right;
int absoluteBottom = offsetY + boxPtr->drawable.oldArea.bottom;
backgroundColor =
boxPtr->drawable.oldParentPtr->drawable.color; 
#ifdef USING_BGI
setcolor(backgroundColor);
if (boxPtr->oldFilled)
{
setfillstyle(SOLID_FILL, backgroundColor);
fillRectangle(absoluteLeft, absoluteTop, 
absoluteRight, absoluteBottom);
}
else
{
setfillstyle(EMPTY_FILL, backgroundColor);
rectangle(absoluteLeft, absoluteTop, 
absoluteRight, absoluteBottom);
}
#endif
}
/* 

Back

Embedded.com Career Center
Looking for a new job?
SEARCH JOBS

Browse all jobs

SPONSOR
RECENT JOB POSTINGS





 :