03.01.2013 Views

Chapter 1

Chapter 1

Chapter 1

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

}<br />

The cursor is simply a black line around the outside of the tile and a white line around the<br />

inside of that. The cursor had to look good whatever the color of the square underneath and<br />

around, whatever the contrast capabilities of the display and at whatever zoom level. And yet<br />

the cursor should not altogether hide the square underneath.<br />

It took me quite a few iterations to get a scheme that was acceptable. Unusually, the scheme<br />

I finally chose – for good aesthetic and functional reasons – was also very simple to execute<br />

in C++ code.<br />

Redrawing the view<br />

Draw() is called by the control framework when the windowing system (the Window server)<br />

determines that the control needs redrawing, for example, when a window on-top moves<br />

away and exposes the control. The other circumstance in which a program draws to a view<br />

is to update it to reflect a change in the program's data: for example, in the case of Solo<br />

Ships, to show that a square has been hit. This is called application-initiated redrawing.<br />

Sometimes the data will have changed so much that an application will need to redraw the<br />

entire view. Often, however, only a small amount of data will have changed, and only part of<br />

the view needs changing. This approach, called incremental redrawing, is a good idea, as,<br />

for views of any complexity, redrawing the entire view is likely to be slow enough to be<br />

noticeable to the user. The downside of incremental redrawing is that it can be complex to<br />

program. For each view that you write, you will need to determine the appropriate trade off<br />

between performance/appearance (requiring more incremental redrawing), and program<br />

complexity (requiring less incremental redrawing).<br />

For Solo Ships, some experimentation found that redrawing the whole view produced<br />

noticeable display flicker and so was not satisfactory.<br />

Using incremental redrawing to update just the tiles, however, produced an acceptable<br />

effect. This meant I didn't have to go to the next level of complexity of incrementally<br />

redrawing individual tiles.<br />

The function to update all tiles on the board is DrawTilesNow(). It's called whenever a<br />

fleet gets a hit, or the cursor moves from one square to another.<br />

void CFleetView::DrawTilesNow() const<br />

{<br />

Window().Invalidate(iBoardRect);<br />

ActivateGc();<br />

Window().BeginRedraw(iBoardRect);<br />

DrawTiles();<br />

Window().EndRedraw();<br />

DeactivateGc();<br />

}<br />

DrawTiles() actually draws the tiles, as we've already seen. But now it's sandwiched<br />

between some unfamiliar functions. These are discussed in detail in <strong>Chapter</strong> 11, but for now<br />

I'll just say a little about this standard pattern used for incremental redraws. The calls<br />

through Window() are required because the Window server needs to know when and<br />

where applications are drawing in order to coordinate all their display activities. Similarly, the

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!