Here is the Go board. How do you like it? I think it's pretty much what I want, with the exception of the cursor for selecting your position. I'll have to work on the design of that a bit.
Porting GNU Go is pretty much my first GUI application coding in S60 or Symbian. Mostly I have been doing at lower level code. What GUI experience I have is all in Win32 and the X Window System.
To begin with I started out doing the board as part of the main view, and while this worked, I knew that would be better to create a new widget to handle specialized tasks like drawing the Go board. It simplifies the drawing calculations & key event handling if nothing else.
This is pretty easy in Symbian as it turns out, just create your class like this:
class CBoardControl : public CCoeControl
{
public:
static CBoardControl* NewL(const CCoeControl &aContainer, const TRect &aRect);
static CBoardControl* NewLC(const CCoeControl &aContainer, const TRect &aRect);
// Handle drawing of the control
void Draw(const TRect& aRect) const;
~CBoardControl();
protected:
// Handle changing the size of the control.
// Particularly needed to handle redrawing after the screen mode changes.
virtual void SizeChanged();
private:
void ConstructL(const CCoeControl &aContainer, const TRect &aRect);
CBoardControl();
};
The
SizeChanged is needed for recalculating things when the layout changes. Everything else is standard Symbian boilerplate, and the only interesting stuff is done in the
Draw function.
One thing I found is that your drawing coordinates are not re-origined for your control, and also not limited to the size that was specified for it. They are all still relative to the parent control. This makes calculations difficult, and makes it easy to inadvertently draw outside your control's area (as i was found I was doing in the first few revisions of my the control code). There is an easy solution to this however. I added the following to the start of the
Draw function, and things are as I want it:
void CBoardControl::Draw(const TRect& /* aRect */) const
{
// Get the standard graphics context
CWindowGc& gc = SystemGc();
// make sure we don't draw outside of control's own area
gc.SetClippingRect (Rect ());
// put the origin at the top left of the control's area
gc.SetOrigin (Rect().iTl);
// TODO: your drawing code here
// ...
}
Another annoying thing about drawing in Symbian is the way that it doesn't draw the last pixel of what you specify. Is there a way around that? It sure makes life difficult having to add one pixel to sometimes X coordinate, sometimes Y coordinate, and sometimes both.
There are a lot of things that I need to change in the control though. At the moment those handicap spots are just hardcoded in place, and so is the 19x19 layout. I need to make it accept the range of board sizes that GNU Go supports, and to read the positions of the handicap spots from the engine. At the moment the GUI is not even linked against the GNU Go codebase, so I'm some way away from getting that in place.
One thing I discovered when I read the
Wikipedia entry on Go was that the board is not square, but in 15:14 aspect ratio. Don't know if I'll implement that ever. It's debatable if it would be noticeable on the larger S60 screens, never mind the smaller (previously standard) ones.
Anyway, I am quite happy with the board control now. It is coming along nicely. I think it ought to be more or less reusable if I ever decide to port GNU Chess :)
Well, still lots to do for GNU Go first...