Programming:  Touch areas

The program adds two "buttons", one increments a counter, the other decrements the same counter. If you hold the pen down on the button, it will perform its action repeatedly.

The code shows that you don't need to include a bitmap for every button. You can define your touch sesitive areas the way you want. You can also define an area as large as the whole screen and manage your buttons according to the point clicked (tsts.x, tsts.y).

If you have no particular reason to do otherwise (PollEvent), i suggest that you use TCHSTS and LibTchWait. They provide a sort of object oriented management of the items your app is made of.

#include	<stdrom.h>
#include	"define.h"
#include	"libc.h"

Let's define the touch sensitive areas

#define RECT_PLUS_X1  10
#define RECT_PLUS_Y1  10
#define RECT_PLUS_X2  50
#define RECT_PLUS_Y2  50

#define RECT_MINUS_X1  110
#define RECT_MINUS_Y1  10
#define RECT_MINUS_X2  150
#define RECT_MINUS_Y2  50

#define OBJ_PLUS 0xc012
#define OBJ_MINUS 0xc013

Program management stuff

#define DELAY_MAX 80

void UpdateDisplay();
void DoPlus();
void DoMinus();
void CheckButtons(TCHSTS *);

int Count;
int Delay;

Here's the touch table. We're interested in two actions for both buttons: ACT_MAKE (pen down), and ACT_DOWN (continuosly fired as long as the pen is held down).

TCHTBL TchList[3] = 
{
	/* Plus button */
		RECT_PLUS_X1, RECT_PLUS_Y1, 
		RECT_PLUS_X2, RECT_PLUS_Y2,
		ACT_MAKE | ACT_DOWN,
		OBJ_PLUS,
		0x0000,

	/* Minus button */
		RECT_MINUS_X1, RECT_MINUS_Y1, 
		RECT_MINUS_X2, RECT_MINUS_Y2,
		ACT_MAKE | ACT_DOWN,
		OBJ_MINUS,
		0x0000,

	/* End */
		0, 0, 0, 0,
		ACT_NONE,
		OBJ_END,
		0x0000
};

Code to repaint the screen, boring...

void UpdateDisplay()
{
	char digit[16];
	int sz;

	LibClrDisp();

	LibGdsBox(RECT_PLUS_X1, RECT_PLUS_Y1, RECT_PLUS_X2, RECT_PLUS_Y2); 
	sz = LibGetProStrSize(IB_PFONT3, "+");
	LibPutProStr(IB_PFONT3, 
		RECT_PLUS_X1 + (RECT_PLUS_X2 - RECT_PLUS_X1 - sz) / 2, 
		RECT_PLUS_Y1 + (RECT_PLUS_Y2 - RECT_PLUS_Y1 - sz) / 2, 
		"+", sz);
	

	LibGdsBox(RECT_MINUS_X1, RECT_MINUS_Y1, RECT_MINUS_X2, RECT_MINUS_Y2); 
	sz = LibGetProStrSize(IB_PFONT3, "-");
	LibPutProStr(IB_PFONT3, 
		RECT_MINUS_X1 + (RECT_MINUS_X2 - RECT_MINUS_X1 - sz) / 2, 
		RECT_MINUS_Y1 + (RECT_MINUS_Y2 - RECT_MINUS_Y1 - sz) / 2, 
		"-", sz);


	sprintf(digit, "%d", Count);
	sz = LibGetProStrSize(IB_PFONT3, digit);
	LibPutProStr(IB_PFONT3, 80, 80, digit, sz);
	LibPutDisp();
}

Callback functions for the buttons.

void DoPlus()
{
	if (Count == 9) return;
	Count++;
	UpdateDisplay();
}

void DoMinus()
{
	if (Count == 0) return;
	Count--;
	UpdateDisplay();
}

Let's see what happened. We only expect two events ACT_MAKE and ACT_DOWN. If ACT_MAKE we execute the callbacks immediately. If ACT_DOWN we wait until we receive "DELAY" ACT_DOWN events, in order to respond slowly. This shows that ACT_MAKE is fired only once.

void CheckButtons(TCHSTS *tsts)
{
	if (tsts->act == ACT_MAKE)
	{
		Delay = 0;

		if (tsts->obj == OBJ_PLUS)
			DoPlus();

		if (tsts->obj == OBJ_MINUS)
			DoMinus();
	}

	if (tsts->act == ACT_DOWN)
	{
		Delay++;
		if (Delay < DELAY_MAX) return;

		if (tsts->obj == OBJ_PLUS)
			DoPlus();

		if (tsts->obj == OBJ_MINUS)
			DoMinus();

		Delay = 0;
	}

}

This is old stuff, by now.

void main()
{
	TCHSTS tsts;
	bool bExit = FALSE;

	LibTchStackClr();
	LibTchStackPush(NULL);

	LibTchStackPush(TchHardIcon);
	LibTchStackPush(&TchList[0]);

	Count = Delay = 0;
	UpdateDisplay();

	LibTchInit();

	for (;bExit == FALSE;)
	{
		LibTchWait(&tsts);           

		if (tsts.obj == OBJ_HIC_ESC)        
			bExit = TRUE;

		CheckButtons(&tsts);
	}

	LibTchStackClr();
	LibJumpMenu();
}