2006-04-17

Mu Torere, the Legend

The sole reason for the InfoDisplay class is to show to the user which colour belongs to which player. In this program, the class is draw directly on the window, over-lapping the playing field. If I ever figure out a way to allow a program to close a child modeless window, I'll post it but for now this is it.

A Singleton class, CInfoDisplay contains the following as variables;
variableinital valuecomment
static CString *labelsNULL 
static COLORREF *coloursNULL 
static CPoint topLeftCPoint(0,0)for positioning
static int counter0for the iterator
static int numLabel0 

There are some named constants used for spacing included as well as a limit to the number of array elements.

The functions that will be used are static CInfoDisplay* getInstance(const int& count) and static void Release(void) for the pattern (Note that getInstance requires a parameter), void Draw(CDC* pDC), CSize getLabelSize(CDC* pDC) const, static void First(void) (to reset counter to 0), bool setInfo(const CString& sLabel, const COLORREF& rgbColour), and bool setRGB(const int& index, const COLORREF& rgb). Also note that the setRGB() function requires a index. I would have been better not to depend on such things for synchronization.

Since the labels and the colours are in dynamic arrays, the destructor can be used for the clean-up.
destructor
CInfoDisplay::~CInfoDisplay(void)
If labels is not-NULL, delete it.
If colours is not-NULL, delete it.


The additional code in this class's getInstance involves creating the labels and colours arrays;
CInfoDisplay* CInfoDisplay::getInstance(const int& count)
Pre-condition;
That count is greater than 0.
If instance is NULL and count greater than 0
{
Create new CInfoDisplay and assign to instance.
(Strictly speaking if this fails, the function should return NULL.)

If count is greater than CInfoDisplay::MAX_LABELS, use CInfoDisplay::MAX_LABELS instead.

Try allocating CString[count] memory and assigning it to labels.

Try allocating COLORREF[count] memory and assigning it to colours.

If labels is not-NULL, assign _T(" ") to each element.
If colours is not_NULL, assign RGB(255,0,0), i.e. red, to each element.

Assign (0,0) to topLeft.
}

Return instance.

Note the use of _T() for the CString elements. This Microsoft macro handles the difference between UNICODE and ANSCII at compile-time.

For the iterator function;
bool CInfoDisplay::setInfo(const CString& sLabel, const COLORREF& rgbColour)
Pre-condition;
That instance is not-NULL.
That counter is greater or equal to 0 and less than numLabel.
That labels is not_NULL.
That colours is not-NULL.
If counter equals numLabel, then return false. // no more can be entered

Assign sLabel to labels[counter].
Assign rgbColour to colours[counter].

Increment counter.

Return true.


The index-based colour-setting function works as follows;
bool CInfoDisplay::setRGB(const int& index, const COLORREF& rgb)
Pre-condition;
That instance is not-NULL.
That colours is not-NULL.
That index is greater than or equal to 0 and less than numLabel.
Assign rgb to colours[index].

Return true.


The following function helps the program determine the size of all the text that will be drawn. For now mostly redundant, but if positioning the CInfoDisplay instance is being done it will allow the programmer to compensate for weirdness.
CSize CInfoDisplay::getLabelSize(CDC* pDC) const
Pre-condition;
That instance is not-NULL.
That numLabel is greater or equal to 0 and less than numLabel.
That labels is not_NULL.
That pDC is not-NULL.
Initialize the x and y values to return.

For each label,
{
Get the size of the text of the label. (via GetTextExtent())

If the label's x-extent is greater, assign the value to x.

If the label's y-extent is smaller than the rectangle used to display the colour (CInfoDisplay::CELL_SIZE)
{
Increment y by CInfoDisplay::CELL_SIZE.
}
else
{
Increment y by the label's y-extent.
}

If not at the last label
{
Increment y by CInfoDisplay::SPACING.
}

Return CSize(x,y).


Finally, for drawing the instance;
void CInfoDisplay::Draw(CDC* pDC)
Pre-condition;
That instance is not-NULL.
That labels is not_NULL.
That pDC is not-NULL.
Get the size of the text from getLabelSize().

Create a solid pen with the colour of the menu text.

Initialize dy with the BORDER value + PADDING value + topLeft.y.
For each label,
{
Draw the label.

Get the size of the label.
Adjust like the gatLabelSize() function.

Set up a square CELL_SIZE-by-CELL_SIZE separated from the label by SPACING.
Create a solid brush with the appropriate colour.
Draw the square.

Increment dv by the label height and by the SPACING.
}

Now draw the enclosing box. Remember that the box is reduced by the BORDER value, that topLeft positions the box, and that the box's width is expanded by SPACING and the colour display.

No comments: