Getting started
Let's cover shortly the basics of tables. Usual working flow is as follows:
- type of column in table's row
- a value to integer or pointer data of the cell if needed
- desired columns usable
- set custom procedures for loading, saving and drawing if needed
- set ID and Data values for row (each one is of two bytes length) if needed
FormPtr frmP = FrmGetActiveForm();
TablePtr tableP = FrmGetObjectPtr( frmP,
FrmGetObjectIndex(frmP,TestTableTable));
UInt nNumRows = TblGetNumberOfRows(tableP);
UInt i = 0;
for (i = 0; i < i =" 0;" nvalue =" TblGetItemInt(tableP,row,column);" nvalue ="="" bitmaph =" DmGetResource('Tbmp'," bitmaph =" DmGetResource('Tbmp'," bitmapp =" (BitmapPtr)">topLeft.x, bounds->topLeft.y);
MemHandleUnlock (bitmapH);
}
All this function does is load the appropriate bitmap resource according to stored value and then draw it inside the cell bounds. You may freely apply your imagination here and implement almost any behavior. Just avoid time consuming operations when the cell is being drawn, otherwise users will not understand you!
Responding to events
The Table API provides more opportunities to display data than to edit data. One more point where you may customize your control is in handling some events. Applying to tables, it will be tblEnterEvent and tblSelectEvent. You may process them in HandleEvent function. As an example we'll implement in-place edit. The main idea is simple. We need to create field in cell's bounds and then redirect events to this control. For example, in case of in-place edit you may write something like following code sample. This is just a very simple and schematical implementation of what was presented above:
*********************************************************************
Global variables
*********************************************************************/
FieldPtr g_InPlaceField;
UInt16 g_wCurrRow, g_wCurrCol;
MemHandle g_hText;
Boolean g_bSelected;
static void SaveValue(TablePtr table);
static void HandleTapInCell(EventType* eventP,
TablePtr tableP,
UInt16 wCol,
UInt16 wRow,
Boolean& bHandled);
..................................
static void MainFormInit(FormType *frmP)
{
.......................
g_wCurrRow = g_wCurrCol = -1;
g_bSelected = false;
g_InPlaceField =
(FieldPtr)FrmGetObjectPtr(frmP,FrmGetObjectIndex(frmP,MainInPlaceEdit));
.......................
}
static Boolean MainFormHandleEvent(EventType * eventP)
{
Boolean handled = false;
FormType * frmP;
switch (eventP->eType)
{
// other events
......................
case tblEnterEvent:
{
frmP = FrmGetActiveForm();
TablePtr tableP = eventP->data.tblEnter.pTable;
UInt16 wRow = eventP->data.tblEnter.row;
UInt16 wCol = eventP->data.tblEnter.column;
HandleTapInCell(eventP, tableP, wCol, wRow, handled);
g_wCurrRow = wRow;
g_wCurrCol = wCol;
}
break;
}
return handled;
}
/*********************************************************************
* Internal Functions
*********************************************************************/
static void SaveValue(TablePtr table)
{
Boolean dirty;
if (!g_InPlaceField)
return;
dirty = FldDirty(g_InPlaceField);
if (dirty)
{
CharPtr textP = FldGetTextPtr(g_InPlaceField);
Int nInt;
if (textP)
nInt = StrAToI(textP);
else
nInt = 0;
TblSetItemInt(table,g_wCurrRow,0,nInt);
}
FldReleaseFocus(g_InPlaceField);
FldSetSelection(g_InPlaceField, 0, 0);
}
static void HandleTapInCell( EventType* eventP,
TablePtr tableP,
UInt16 wCol,
UInt16 wRow,
Boolean& bHandled)
{
FormPtr frmP = FrmGetActiveForm();
// if user tapped on new row then deselect current one
if ( g_bSelected &&
(wCol != g_wCurrCol || wRow != g_wCurrRow) )
{
SaveValue(tableP);
FrmHideObject(frmP,FrmGetObjectIndex(frmP,MainInPlaceEdit));
TblMarkRowInvalid(tableP,g_wCurrRow);
g_bSelected = false;
}
TblRedrawTable(tableP);
if ( wCol > 0 )
{
g_bSelected = false;
bHandled = false;
return;
}
// show field at new position if needed
RectangleType r;
TblGetItemBounds(tableP,wRow,wCol,&r);
if ( (wCol == 0 && wCol != g_wCurrCol) || (wRow != g_wCurrRow) )
{
TblGetItemBounds(tableP,wRow,wCol,&r);
Int16 nInt = TblGetItemInt(tableP,wRow,wCol);
FrmSetObjectBounds(frmP,FrmGetObjectIndex(frmP,MainInPlaceEdit),&r);
FrmShowObject(frmP,FrmGetObjectIndex(frmP,MainInPlaceEdit));
char szBuffer[10];
StrPrintF(szBuffer,"%d",nInt);
char* pText = (char*)MemHandleLock(g_hText);
StrCopy(pText,szBuffer);
MemHandleUnlock(g_hText);
FldSetTextHandle(g_InPlaceField,g_hText);
FrmSetFocus(frmP,FrmGetObjectIndex(frmP,MainTestTable));
{
// Convert tblEnter event to fldEnter event
EventType newEvent;
EvtCopyEvent(eventP,&newEvent);
newEvent.eType = fldEnterEvent;
newEvent.data.fldEnter.fieldID = 1971;
newEvent.data.fldEnter.pField = g_InPlaceField;
FldHandleEvent(g_InPlaceField, &newEvent);
}
FldDrawField(g_InPlaceField);
g_bSelected = true;
bHandled = true;
}
FrmDrawForm(frmP);
}
Where to go
As we have seen, Table API manager gives us several opportunities to customize our tables. For most of relatively simple cases it's more than enough. But if you're requested to implement more complex behavior, next possible area of thinking is Gadget control. We will discuss it in next article.
Article Source: Developer.Com
To inquire more about Palm applications, mobile application development services please visit www.palmphone.com or Call 888-284-0858



No comments:
Post a Comment