xwords/common/draw.h
ehouse 89edef9c18 change API for drawing divider so it can be focussed as well as
selected.  Being using that information in palm and wince.  For GTK,
use color rather than ugly black rects to indicate focus.
2008-07-17 05:03:01 +00:00

305 lines
14 KiB
C

/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
/*
* Copyright 1997 - 2007 by Eric House (xwords@eehouse.org). All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _DRAW_H_
#define _DRAW_H_
#include "comtypes.h"
#include "xptypes.h"
#include "model.h"
/* typedef struct DrawCtx DrawCtx; */
typedef XP_Bool (*LastScoreCallback)( void* closure, XP_S16 player,
XP_UCHAR* expl, XP_U16* explLen );
typedef enum {
CELL_NONE = 0x00
, CELL_ISBLANK = 0x01
, CELL_HIGHLIGHT = 0x02
, CELL_ISSTAR = 0x04
, CELL_ISCURSOR = 0x08
, CELL_ISEMPTY = 0x10 /* of a tray tile slot */
, CELL_DRAGSRC = 0x20 /* where drag originated */
, CELL_DRAGCUR = 0x40 /* where drag is now */
, CELL_ALL = 0xFF
} CellFlags;
typedef struct DrawScoreInfo {
LastScoreCallback lsc;
void* lscClosure;
XP_UCHAR* name;
XP_U16 playerNum;
XP_S16 totalScore;
XP_S16 nTilesLeft; /* < 0 means don't use */
CellFlags flags;
XP_Bool isTurn;
XP_Bool selected;
XP_Bool isRemote;
XP_Bool isRobot;
} DrawScoreInfo;
enum HINT_ATTS { HINT_BORDER_NONE = 0,
HINT_BORDER_LEFT = 1,
HINT_BORDER_RIGHT = 2,
HINT_BORDER_TOP = 4,
HINT_BORDER_BOTTOM = 8,
HINT_BORDER_CENTER = 0x10
};
typedef XP_UCHAR HintAtts;
#define HINT_BORDER_EDGE \
(HINT_BORDER_LEFT|HINT_BORDER_RIGHT|HINT_BORDER_TOP|HINT_BORDER_BOTTOM)
/* Platform-supplied draw functions are either staticly linked, or called via
* a vtable. If you want static linking, define DRAW_LINK_DIRECT via a -D
* option to your compiler, and use the DRAW_FUNC_NAME macro to make your
* names match what's declared here. Otherwise, if DRAW_LINK_DIRECT is not
* defined, you need to create and populate a vtable. See any of the existing
* platforms' draw implementations for examples.
*
* As to how to choose, static linking makes the binary a tiny bit smaller,
* but vtables give more flexibilty. For example, Palm uses them to support
* both black-and-white and color screens, while linux on linux separate
* vtable are created to allow a runtime choice between gtk and ncurses
* drawing.
*/
#ifdef DRAW_LINK_DIRECT
# define DRAW_FUNC_NAME(name) linked##_draw_##name
# define DRAW_VTABLE_NAME DRAW_FUNC_NAME
#else
# define DRAW_VTABLE_NAME(name) (*m_draw_ ## name)
#endif
#ifdef DRAW_LINK_DIRECT
typedef void DrawCtxVTable;
#else
typedef struct DrawCtxVTable {
#endif
#ifdef DRAW_WITH_PRIMITIVES
void DRAW_VTABLE_NAME(setClip)( DrawCtx* dctx, const XP_Rect* newClip,
const XP_Rect* oldClip );
void DRAW_VTABLE_NAME(frameRect)( DrawCtx* dctx, const XP_Rect* rect );
void DRAW_VTABLE_NAME(invertRect)( DrawCtx* dctx, const XP_Rect* rect );
void DRAW_VTABLE_NAME(drawString)( DrawCtx* dctx, const XP_UCHAR* str,
XP_U16 x, XP_U16 y );
void DRAW_VTABLE_NAME(drawBitmap)( DrawCtx* dctx, const XP_Bitmap bm,
XP_U16 x, XP_U16 y );
void DRAW_VTABLE_NAME(measureText)( DrawCtx* dctx, const XP_UCHAR* buf,
XP_U16* widthP, XP_U16* heightP );
#endif
void DRAW_VTABLE_NAME(destroyCtxt) ( DrawCtx* dctx );
XP_Bool DRAW_VTABLE_NAME(boardBegin) ( DrawCtx* dctx,
const DictionaryCtxt* dict,
const XP_Rect* rect,
DrawFocusState dfs );
void DRAW_VTABLE_NAME(objFinished)( DrawCtx* dctx, BoardObjectType typ,
const XP_Rect* rect,
DrawFocusState dfs );
/* rect is not const: set by callee */
XP_Bool DRAW_VTABLE_NAME(vertScrollBoard) (DrawCtx* dctx, XP_Rect* rect,
XP_S16 dist, DrawFocusState dfs );
XP_Bool DRAW_VTABLE_NAME(trayBegin) ( DrawCtx* dctx, const XP_Rect* rect,
XP_U16 owner,
DrawFocusState dfs );
void DRAW_VTABLE_NAME(measureRemText) ( DrawCtx* dctx, const XP_Rect* r,
XP_S16 nTilesLeft,
XP_U16* width, XP_U16* height );
void DRAW_VTABLE_NAME(drawRemText) (DrawCtx* dctx, const XP_Rect* rInner,
const XP_Rect* rOuter,
XP_S16 nTilesLeft);
void DRAW_VTABLE_NAME(scoreBegin) ( DrawCtx* dctx, const XP_Rect* rect,
XP_U16 numPlayers, DrawFocusState dfs );
void DRAW_VTABLE_NAME(measureScoreText) ( DrawCtx* dctx,
const XP_Rect* r,
const DrawScoreInfo* dsi,
XP_U16* width, XP_U16* height );
void DRAW_VTABLE_NAME(score_drawPlayer) ( DrawCtx* dctx,
const XP_Rect* rInner,
const XP_Rect* rOuter,
const DrawScoreInfo* dsi );
void DRAW_VTABLE_NAME(score_pendingScore) ( DrawCtx* dctx,
const XP_Rect* rect,
XP_S16 score,
XP_U16 playerNum,
CellFlags flags );
void DRAW_VTABLE_NAME(drawTimer) ( DrawCtx* dctx, const XP_Rect* rInner,
const XP_Rect* rOuter,
XP_U16 player, XP_S16 secondsLeft );
XP_Bool DRAW_VTABLE_NAME(drawCell) ( DrawCtx* dctx, const XP_Rect* rect,
/* at least one of these two will be
null */
const XP_UCHAR* text,
const XP_Bitmap bitmap,
Tile tile,
XP_S16 owner, /* -1 means don't use */
XWBonusType bonus, HintAtts hintAtts,
CellFlags flags );
void DRAW_VTABLE_NAME(invertCell) ( DrawCtx* dctx, const XP_Rect* rect );
void DRAW_VTABLE_NAME(drawTile) ( DrawCtx* dctx, const XP_Rect* rect,
/* at least 1 of these two will be null*/
const XP_UCHAR* text,
const XP_Bitmap bitmap,
XP_S16 val, CellFlags flags );
#ifdef POINTER_SUPPORT
void DRAW_VTABLE_NAME(drawTileMidDrag) ( DrawCtx* dctx, const XP_Rect* rect,
/* at least 1 of these two will be null*/
const XP_UCHAR* text,
const XP_Bitmap bitmap,
XP_S16 val, XP_U16 owner,
CellFlags flags );
#endif
void DRAW_VTABLE_NAME(drawTileBack) ( DrawCtx* dctx, const XP_Rect* rect,
CellFlags flags );
void DRAW_VTABLE_NAME(drawTrayDivider) ( DrawCtx* dctx, const XP_Rect* rect,
CellFlags flags );
void DRAW_VTABLE_NAME(clearRect) ( DrawCtx* dctx, const XP_Rect* rect );
void DRAW_VTABLE_NAME(drawBoardArrow) ( DrawCtx* dctx,
const XP_Rect* rect,
XWBonusType bonus, XP_Bool vert,
HintAtts hintAtts,
CellFlags flags);
const XP_UCHAR* DRAW_VTABLE_NAME(getMiniWText) ( DrawCtx* dctx,
XWMiniTextType textHint );
void DRAW_VTABLE_NAME(measureMiniWText) ( DrawCtx* dctx, const XP_UCHAR* textP,
XP_U16* width, XP_U16* height );
void DRAW_VTABLE_NAME(drawMiniWindow)( DrawCtx* dctx, const XP_UCHAR* text,
const XP_Rect* rect, void** closure );
#ifndef DRAW_LINK_DIRECT
} DrawCtxVTable; /* */
#endif
struct DrawCtx {
DrawCtxVTable* vtable;
};
/* Franklin's compiler is too old to support __VA_ARGS__... */
#ifdef DRAW_LINK_DIRECT
# define CALL_DRAW_NAME0(name,dc) linked##_draw_##name(dc)
# define CALL_DRAW_NAME1(name,dc,p1) linked##_draw_##name(dc,(p1))
# define CALL_DRAW_NAME2(name,dc,p1,p2) \
linked##_draw_##name(dc,(p1),(p2))
# define CALL_DRAW_NAME3(name,dc,p1,p2,p3) \
linked##_draw_##name(dc,(p1),(p2),(p3))
# define CALL_DRAW_NAME4(name,dc,p1,p2,p3,p4) \
linked##_draw_##name(dc,(p1),(p2),(p3),(p4))
# define CALL_DRAW_NAME5(name,dc,p1,p2,p3,p4,p5) \
linked##_draw_##name(dc,(p1),(p2),(p3),(p4),(p5))
# define CALL_DRAW_NAME6(name,dc,p1,p2,p3,p4,p5,p6) \
linked##_draw_##name(dc,(p1),(p2),(p3),(p4),(p5),(p6))
# define CALL_DRAW_NAME8(name,dc,p1,p2,p3,p4,p5,p6,p7,p8) \
linked##_draw_##name(dc,(p1),(p2),(p3),(p4),(p5),(p6),(p7),(p8))
# define CALL_DRAW_NAME10(name,dc,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) \
linked##_draw_##name(dc,(p1),(p2),(p3),(p4),(p5),(p6),(p7),\
(p8),(p9),(p10))
#else
# define CALL_DRAW_NAME0(name,dc) ((dc)->vtable->m_draw_##name)(dc)
# define CALL_DRAW_NAME1(name,dc,p1) ((dc)->vtable->m_draw_##name)(dc,(p1))
# define CALL_DRAW_NAME2(name,dc,p1,p2) \
((dc)->vtable->m_draw_##name)(dc,(p1),(p2))
# define CALL_DRAW_NAME3(name,dc,p1,p2,p3) \
((dc)->vtable->m_draw_##name)(dc,(p1),(p2),(p3))
# define CALL_DRAW_NAME4(name,dc,p1,p2,p3,p4) \
((dc)->vtable->m_draw_##name)(dc,(p1),(p2),(p3),(p4))
# define CALL_DRAW_NAME5(name,dc,p1,p2,p3,p4,p5) \
((dc)->vtable->m_draw_##name)(dc,(p1),(p2),(p3),(p4),(p5))
# define CALL_DRAW_NAME6(name,dc,p1,p2,p3,p4,p5,p6) \
((dc)->vtable->m_draw_##name)(dc,(p1),(p2),(p3),(p4),(p5),(p6))
# define CALL_DRAW_NAME8(name,dc,p1,p2,p3,p4,p5,p6,p7,p8) \
((dc)->vtable->m_draw_##name)(dc,(p1),(p2),(p3),(p4),(p5),(p6),(p7),\
(p8))
# define CALL_DRAW_NAME10(name,dc,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) \
((dc)->vtable->m_draw_##name)(dc,(p1),(p2),(p3),(p4),(p5),(p6),(p7),\
(p8),(p9),(p10))
#endif
#define draw_destroyCtxt(dc) CALL_DRAW_NAME0(destroyCtxt, dc)
#define draw_boardBegin( dc,d,r,f ) CALL_DRAW_NAME3(boardBegin, dc, d,r,f)
#define draw_objFinished( dc, t, r, d ) CALL_DRAW_NAME3(objFinished, (dc), (t), (r), (d))
#define draw_trayBegin( dc, r, o, f ) CALL_DRAW_NAME3(trayBegin,dc, r, o, f)
#define draw_vertScrollBoard( dc, r, d, f ) \
CALL_DRAW_NAME3(vertScrollBoard, (dc),(r),(d),(f))
#define draw_scoreBegin( dc, r, t, f ) \
CALL_DRAW_NAME3( scoreBegin,(dc), (r), (t), (f))
#define draw_measureRemText( dc, r, n, wp, hp ) \
CALL_DRAW_NAME4(measureRemText, (dc), (r), (n), (wp), (hp) )
#define draw_drawRemText( dc, ri, ro, n ) \
CALL_DRAW_NAME3(drawRemText, (dc), (ri), (ro), (n) )
#define draw_measureScoreText(dc,r,dsi,wp,hp) \
CALL_DRAW_NAME4(measureScoreText,(dc),(r),(dsi),(wp),(hp))
#define draw_score_drawPlayer(dc, ri, ro, dsi) \
CALL_DRAW_NAME3(score_drawPlayer,(dc),(ri),(ro),(dsi))
#define draw_score_pendingScore(dc, r, s, p, f ) \
CALL_DRAW_NAME4(score_pendingScore,(dc), (r), (s), (p), (f))
#define draw_drawTimer( dc, ri, ro, plyr, sec ) \
CALL_DRAW_NAME4(drawTimer,(dc),(ri),(ro),(plyr),(sec))
#define draw_drawCell( dc, rect, txt, bmap, t, o, bon, hi, f ) \
CALL_DRAW_NAME8(drawCell,(dc),(rect),(txt),(bmap),(t),(o),(bon),(hi),\
(f))
#define draw_invertCell( dc, rect ) CALL_DRAW_NAME1(invertCell,(dc),(rect))
#define draw_drawTile( dc, rect, text, bmp, val, hil ) \
CALL_DRAW_NAME5(drawTile,(dc),(rect),(text),(bmp),(val),(hil))
#ifdef POINTER_SUPPORT
#define draw_drawTileMidDrag( dc, rect, text, bmp, val, ownr, hil ) \
CALL_DRAW_NAME6(drawTileMidDrag,(dc),(rect),(text),(bmp),(val),(ownr),(hil))
#endif /* POINTER_SUPPORT */
#define draw_drawTileBack( dc, rect, f ) \
CALL_DRAW_NAME2(drawTileBack, (dc), (rect), (f) )
#define draw_drawTrayDivider( dc, rect, s ) \
CALL_DRAW_NAME2(drawTrayDivider,(dc),(rect), (s))
#define draw_clearRect( dc, rect ) CALL_DRAW_NAME1(clearRect,(dc),(rect))
#define draw_drawBoardArrow( dc, r, b, v, h, f ) \
CALL_DRAW_NAME5(drawBoardArrow,(dc),(r),(b), (v), (h), (f))
#define draw_getMiniWText( dc, b ) CALL_DRAW_NAME1(getMiniWText, (dc),(b) )
#define draw_measureMiniWText( dc, t, wp, hp) \
CALL_DRAW_NAME3(measureMiniWText, (dc),(t), (wp), (hp) )
#define draw_drawMiniWindow( dc, t, r, c ) \
CALL_DRAW_NAME3(drawMiniWindow, (dc), (t), (r), (c) )
#ifdef DRAW_WITH_PRIMITIVES
# define draw_setClip( dc, rn, ro ) CALL_DRAW_NAME2(setClip, (dc), (rn), (ro))
# define draw_frameRect( dc, r ) CALL_DRAW_NAME1(frameRect, (dc), (r) )
# define draw_invertRect( dc, r ) CALL_DRAW_NAME1(invertCell, (dc), (r) )
# define draw_drawString( dc, s, x, y) \
CALL_DRAW_NAME3(drawString, (dc), (s), (x), (y) )
# define draw_drawBitmap( dc, bm, x, y ) \
CALL_DRAW_NAME3(drawBitmap, (dc), (bm), (x), (y) )
# define draw_measureText( dc, t, wp, hp ) \
CALL_DRAW_NAME3(measureText, (dc), (t), (wp), (hp) )
void InitDrawDefaults( DrawCtxVTable* vtable );
#endif /* DRAW_WITH_PRIMITIVES */
#endif