/********************************************************************* * * LISTVIEW_DeleteColumn */ void LISTVIEW_DeleteColumn(LISTVIEW_Handle hObj, unsigned Index) { if (hObj) { LISTVIEW_Obj* pObj; WM_LOCK(); pObj = LISTVIEW_H2P(hObj); if (Index < GUI_ARRAY_GetNumItems(&pObj->AlignArray)) { unsigned NumRows, i; GUI_ARRAY* pRow; HEADER_DeleteItem(pObj->hHeader, Index); GUI_ARRAY_DeleteItem(&pObj->AlignArray, Index); NumRows = GUI_ARRAY_GetNumItems(&pObj->RowArray); for (i = 0; i < NumRows; i++) { LISTVIEW_ITEM * pItem; pRow = (GUI_ARRAY*)GUI_ARRAY_GetpItem(&pObj->RowArray, i); /* Delete attached info items */ pItem = (LISTVIEW_ITEM *)GUI_ARRAY_GetpItem(pRow, Index); if (pItem->hItemInfo) { GUI_ALLOC_Free(pItem->hItemInfo); } /* Delete cell */ GUI_ARRAY_DeleteItem(pRow, Index); } LISTVIEW__UpdateScrollParas(hObj, pObj); LISTVIEW__InvalidateInsideArea(hObj, pObj); } WM_UNLOCK(); } }
/********************************************************************* * * LISTVIEW_AddColumn */ int LISTVIEW_AddColumn(LISTVIEW_Handle hObj, int Width, const char * s, int Align) { int r = 0; if (hObj) { LISTVIEW_Obj* pObj; LISTVIEW_COLUMN Column = {0}; unsigned NumRows; WM_LOCK(); pObj = LISTVIEW_H2P(hObj); HEADER_AddItem(pObj->hHeader, Width, s, Align); Column.Align = Align; GUI_ARRAY_AddItem(&pObj->ColumnArray, &Column, sizeof(LISTVIEW_COLUMN)); pObj = LISTVIEW_H2P(hObj); /* Restore after allocating memory */ NumRows = LISTVIEW__GetNumRows(pObj); if (NumRows) { LISTVIEW_ROW* pRow; unsigned i; for (i = 0; i < NumRows; i++) { pRow = (LISTVIEW_ROW*) GUI_ARRAY_GetpItem(&pObj->RowArray, i); if (GUI_ARRAY_AddItem(&pRow->CellArray, NULL, sizeof(LISTVIEW_CELL))) { r = 1; break; } pObj = LISTVIEW_H2P(hObj); /* Restore after allocating memory */ } } LISTVIEW__UpdateScrollParas(hObj, pObj); LISTVIEW__InvalidateInsideArea(hObj, pObj); WM_UNLOCK(); } return r; }
/********************************************************************* * * LISTVIEW_SetFont */ void LISTVIEW_SetFont(LISTVIEW_Handle hObj, const GUI_FONT GUI_UNI_PTR * pFont) { if (hObj) { LISTVIEW_Obj* pObj; WM_LOCK(); pObj = LISTVIEW_H2P(hObj); if (pFont != pObj->Props.pFont) { pObj->Props.pFont = pFont; LISTVIEW__UpdateScrollParas(hObj, pObj); LISTVIEW__InvalidateInsideArea(hObj, pObj); } WM_UNLOCK(); } }
/********************************************************************* * * LISTVIEW_AddRow */ int LISTVIEW_AddRow(LISTVIEW_Handle hObj, const GUI_ConstString* ppText) { int r = 0; if (hObj) { LISTVIEW_Obj* pObj; WM_LOCK(); pObj = LISTVIEW_H2P(hObj); /* Add row item to the GUI_ARRAY */ if (GUI_ARRAY_AddItem(&pObj->RowArray, NULL, sizeof(LISTVIEW_ROW)) == 0) { LISTVIEW_ROW* pRow; int i, RowIndex, NumColumns, NumBytes; const char* s; pObj = LISTVIEW_H2P(hObj); /* Restore after allocating memory */ RowIndex = LISTVIEW__GetNumRows(pObj) - 1; NumColumns = LISTVIEW__GetNumColumns(pObj); pRow = (LISTVIEW_ROW*) GUI_ARRAY_GetpItem(&pObj->RowArray, RowIndex); GUI_ARRAY_CREATE(&pRow->CellArray); /* Add columns for the new row */ for (i = 0; i < NumColumns; i++) { LISTVIEW_CELL* pCell; s = (ppText) ? *ppText++ : 0; if (s == 0) { ppText = 0; } NumBytes = GUI__strlen(s) + 1; /* 0 if no string is specified (s == NULL) */ if (GUI_ARRAY_AddItem(&pRow->CellArray, NULL, sizeof(LISTVIEW_CELL) + NumBytes)) { r = 1; break; } pObj = LISTVIEW_H2P(hObj); /* Restore after allocating memory */ pRow = (LISTVIEW_ROW*) GUI_ARRAY_GetpItem(&pObj->RowArray, RowIndex); /* Restore after allocating memory */ pCell = (LISTVIEW_CELL*) GUI_ARRAY_GetpItem(&pRow->CellArray, i); if (NumBytes > 1) { strcpy(pCell->acText, s); } } pObj->IsSorted = 0; LISTVIEW__UpdateScrollParas(hObj, pObj); if (pObj->hSort && (pObj->SortIndex >= 0)) { LISTVIEW__InvalidateInsideArea(hObj, pObj); } else { LISTVIEW__InvalidateRow(hObj, pObj, RowIndex); } } else { r = 1; } WM_UNLOCK(); } return r; }
/********************************************************************* * * LISTVIEW_SetRowHeight */ unsigned LISTVIEW_SetRowHeight(LISTVIEW_Handle hObj, unsigned RowHeight) { unsigned r = 0; if (hObj) { LISTVIEW_Obj* pObj; WM_LOCK(); pObj = LISTVIEW_H2P(hObj); r = pObj->RowDistY; if (RowHeight != r) { pObj->RowDistY = RowHeight; LISTVIEW__UpdateScrollParas(hObj, pObj); LISTVIEW__InvalidateInsideArea(hObj, pObj); } WM_UNLOCK(); } return r; }
/********************************************************************* * * LISTVIEW_SetAutoScrollV */ void LISTVIEW_SetAutoScrollV(LISTVIEW_Handle hObj, int State) { if (hObj) { LISTVIEW_Obj* pObj; char Flags; WM_LOCK(); pObj = LISTVIEW_H2P(hObj); Flags = pObj->Flags & (~LISTVIEW_SF_AUTOSCROLLBAR_V); if (State) { Flags |= LISTVIEW_SF_AUTOSCROLLBAR_V; } if (pObj->Flags != Flags) { pObj->Flags = Flags; LISTVIEW__UpdateScrollParas(hObj, pObj); } WM_UNLOCK(); } }
/********************************************************************* * * LISTVIEW_DeleteRow */ void LISTVIEW_DeleteRow(LISTVIEW_Handle hObj, unsigned Index) { if (hObj) { LISTVIEW_Obj* pObj; unsigned NumRows; WM_LOCK(); pObj = LISTVIEW_H2P(hObj); NumRows = GUI_ARRAY_GetNumItems(&pObj->RowArray); if (Index < NumRows) { unsigned NumColumns, i; GUI_ARRAY* pRow; pRow = (GUI_ARRAY*)GUI_ARRAY_GetpItem(&pObj->RowArray, Index); /* Delete attached info items */ NumColumns = GUI_ARRAY_GetNumItems(pRow); for (i = 0; i < NumColumns; i++) { LISTVIEW_ITEM * pItem; pItem = (LISTVIEW_ITEM *)GUI_ARRAY_GetpItem(pRow, i); if (pItem->hItemInfo) { GUI_ALLOC_Free(pItem->hItemInfo); } } /* Delete row */ GUI_ARRAY_Delete(pRow); GUI_ARRAY_DeleteItem(&pObj->RowArray, Index); /* Adjust properties */ if (pObj->Sel == (signed int)Index) { pObj->Sel = -1; } if (pObj->Sel > (signed int)Index) { pObj->Sel--; } if (LISTVIEW__UpdateScrollParas(hObj, pObj)) { LISTVIEW__InvalidateInsideArea(hObj, pObj); } else { _InvalidateRowAndBelow(hObj, pObj, Index); } } WM_UNLOCK(); } }
/********************************************************************* * * LISTVIEW_AddColumn */ void LISTVIEW_AddColumn(LISTVIEW_Handle hObj, int Width, const char * s, int Align) { if (hObj) { LISTVIEW_Obj* pObj; unsigned NumRows; WM_LOCK(); pObj = LISTVIEW_H2P(hObj); HEADER_AddItem(pObj->hHeader, Width, s, Align); /* Modify header */ GUI_ARRAY_AddItem(&pObj->AlignArray, &Align, sizeof(int)); NumRows = LISTVIEW_GetNumRows(hObj); if (NumRows) { GUI_ARRAY* pRow; unsigned i; for (i = 0; i < NumRows; i++) { pRow = (GUI_ARRAY*) GUI_ARRAY_GetpItem(&pObj->RowArray, i); GUI_ARRAY_AddItem(pRow, NULL, sizeof(LISTVIEW_ITEM) + 1); } } LISTVIEW__UpdateScrollParas(hObj, pObj); LISTVIEW__InvalidateInsideArea(hObj, pObj); WM_UNLOCK(); } }
/********************************************************************* * * LISTVIEW_CreateEx */ LISTVIEW_Handle LISTVIEW_CreateEx(int x0, int y0, int xsize, int ysize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id) { LISTVIEW_Handle hObj; GUI_USE_PARA(ExFlags); /* Create the window */ if ((xsize == 0) && (ysize == 0) && (x0 == 0) && (y0 == 0)) { GUI_RECT Rect; WM_GetClientRectEx(hParent, &Rect); xsize = Rect.x1 - Rect.x0 + 1; ysize = Rect.y1 - Rect.y0 + 1; } hObj = WM_CreateWindowAsChild(x0, y0, xsize, ysize, hParent, WinFlags, &_LISTVIEW_Callback, sizeof(LISTVIEW_Obj) - sizeof(WM_Obj)); if (hObj) { LISTVIEW_Obj* pObj; WM_LOCK(); pObj = LISTVIEW_H2P(hObj); /* Init sub-classes */ GUI_ARRAY_CREATE(&pObj->RowArray); GUI_ARRAY_CREATE(&pObj->AlignArray); /* Init widget specific variables */ WIDGET__Init(&pObj->Widget, Id, WIDGET_STATE_FOCUSSABLE); /* Init member variables */ LISTVIEW_INIT_ID(pObj); pObj->Props = LISTVIEW_DefaultProps; pObj->ShowGrid = 0; pObj->RowDistY = 0; pObj->Sel = -1; pObj->LBorder = 1; pObj->RBorder = 1; pObj->hHeader = HEADER_CreateEx(0, 0, 0, 0, hObj, WM_CF_SHOW, 0, 0); LISTVIEW__UpdateScrollParas(hObj, pObj); WM_UNLOCK(); } else { GUI_DEBUG_ERROROUT_IF(hObj==0, "LISTVIEW_Create failed") } return hObj; }
/********************************************************************* * * LISTVIEW_AddRow */ void LISTVIEW_AddRow(LISTVIEW_Handle hObj, const GUI_ConstString* ppText) { if (hObj) { LISTVIEW_Obj* pObj; int NumRows; WM_LOCK(); pObj = LISTVIEW_H2P(hObj); NumRows = GUI_ARRAY_GetNumItems(&pObj->RowArray); /* Create GUI_ARRAY for the new row */ if (GUI_ARRAY_AddItem(&pObj->RowArray, NULL, sizeof(GUI_ARRAY)) == 0) { int i, NumColumns, NumBytes; GUI_ARRAY* pRow; const char* s; GUI_ARRAY_CREATE((GUI_ARRAY *)GUI_ARRAY_GetpItem(&pObj->RowArray, NumRows)); /* For higher debug levels only */ /* Add columns for the new row */ NumColumns = HEADER_GetNumItems(pObj->hHeader); for (i = 0; i < NumColumns; i++) { LISTVIEW_ITEM * pItem; pRow = (GUI_ARRAY *)GUI_ARRAY_GetpItem(&pObj->RowArray, NumRows); s = (ppText) ? *ppText++ : 0; if (s == 0) { ppText = 0; } NumBytes = GUI__strlen(s) + 1; /* 0 if no string is specified (s == NULL) */ GUI_ARRAY_AddItem(pRow, NULL, sizeof(LISTVIEW_ITEM) + NumBytes); pItem = (LISTVIEW_ITEM *)GUI_ARRAY_GetpItem(pRow, i); if (NumBytes > 1) { strcpy(pItem->acText, s); } } LISTVIEW__UpdateScrollParas(hObj, pObj); LISTVIEW__InvalidateRow(hObj, pObj, NumRows); } WM_UNLOCK(); } }
/********************************************************************* * * _LISTVIEW_Callback */ static void _LISTVIEW_Callback (WM_MESSAGE *pMsg) { LISTVIEW_Handle hObj; LISTVIEW_Obj* pObj; WM_SCROLL_STATE ScrollState; hObj = pMsg->hWin; /* Let widget handle the standard messages */ if (WIDGET_HandleActive(hObj, pMsg) == 0) { return; } pObj = LISTVIEW_H2P(hObj); switch (pMsg->MsgId) { case WM_NOTIFY_CLIENTCHANGE: case WM_SIZE: LISTVIEW__UpdateScrollParas(hObj, pObj); return; case WM_NOTIFY_PARENT: switch (pMsg->Data.v) { case WM_NOTIFICATION_CHILD_DELETED: /* make sure we do not send any messages to the header child once it has been deleted */ if (pMsg->hWinSrc == pObj->hHeader) { pObj->hHeader = 0; } break; case WM_NOTIFICATION_VALUE_CHANGED: if (pMsg->hWinSrc == WM_GetScrollbarV(hObj)) { WM_GetScrollState(pMsg->hWinSrc, &ScrollState); pObj->ScrollStateV.v = ScrollState.v; LISTVIEW__InvalidateInsideArea(hObj, pObj); _NotifyOwner(hObj, WM_NOTIFICATION_SCROLL_CHANGED); } else if (pMsg->hWinSrc == WM_GetScrollbarH(hObj)) { WM_GetScrollState(pMsg->hWinSrc, &ScrollState); pObj->ScrollStateH.v = ScrollState.v; LISTVIEW__UpdateScrollParas(hObj, pObj); HEADER_SetScrollPos(pObj->hHeader, pObj->ScrollStateH.v); _NotifyOwner(hObj, WM_NOTIFICATION_SCROLL_CHANGED); } break; case WM_NOTIFICATION_SCROLLBAR_ADDED: LISTVIEW__UpdateScrollParas(hObj, pObj); break; } return; case WM_PAINT: _Paint(hObj, pObj, pMsg); return; case WM_TOUCH: _OnTouch(hObj, pObj, pMsg); return; /* Important: message handled ! */ case WM_KEY: if (((const WM_KEY_INFO*)(pMsg->Data.p))->PressedCnt > 0) { int Key; Key = ((const WM_KEY_INFO*)(pMsg->Data.p))->Key; if (_AddKey(hObj, Key)) { return; } } break; /* No return here ... WM_DefaultProc needs to be called */ case WM_DELETE: _FreeAttached(pObj); break; /* No return here ... WM_DefaultProc needs to be called */ } WM_DefaultProc(pMsg); }
/********************************************************************* * * LISTVIEW_Callback */ void LISTVIEW_Callback (WM_MESSAGE *pMsg) { LISTVIEW_Handle hObj; LISTVIEW_Obj* pObj; WM_SCROLL_STATE ScrollState; hObj = pMsg->hWin; /* Let widget handle the standard messages */ if (WIDGET_HandleActive(hObj, pMsg) == 0) { return; } pObj = (LISTVIEW_Obj *)GUI_ALLOC_h2p(hObj); /* Don't use use WIDGET_H2P because WIDGET_INIT_ID() has not be called at this point */ switch (pMsg->MsgId) { case WM_NOTIFY_CLIENTCHANGE: case WM_SIZE: if (pMsg->hWinSrc && (pMsg->hWinSrc == pObj->hHeader)) { LISTVIEW__UpdateScrollParas(hObj, pObj); } return; case WM_NOTIFY_PARENT: switch (pMsg->Data.v) { case WM_NOTIFICATION_CHILD_DELETED: /* make sure we do not send any messages to the header child once it has been deleted */ if (pMsg->hWinSrc == pObj->hHeader) { pObj->hHeader = 0; } break; case WM_NOTIFICATION_VALUE_CHANGED: if (pMsg->hWinSrc == WM_GetScrollbarV(hObj)) { WM_GetScrollState(pMsg->hWinSrc, &ScrollState); pObj->ScrollStateV.v = ScrollState.v; LISTVIEW__InvalidateInsideArea(hObj, pObj); _NotifyOwner(hObj, WM_NOTIFICATION_SCROLL_CHANGED); } else if (pMsg->hWinSrc == WM_GetScrollbarH(hObj)) { WM_GetScrollState(pMsg->hWinSrc, &ScrollState); pObj->ScrollStateH.v = ScrollState.v; LISTVIEW__UpdateScrollParas(hObj, pObj); HEADER_SetScrollPos(pObj->hHeader, pObj->ScrollStateH.v); _NotifyOwner(hObj, WM_NOTIFICATION_SCROLL_CHANGED); } break; case WM_NOTIFICATION_SCROLLBAR_ADDED: #if WIDGET_USE_PARENT_EFFECT WIDGET_SetEffect(pMsg->hWinSrc, pObj->Widget.pEffect); #endif LISTVIEW__UpdateScrollParas(hObj, pObj); break; case WM_NOTIFICATION_RELEASED: if ((pMsg->hWinSrc == pObj->hHeader) && (pObj->hSort)) { int Column; LISTVIEW_SORT * pSort; LISTVIEW_COLUMN * pColumn; WM_SetFocus(hObj); Column = HEADER_GetSel(pObj->hHeader); if (Column >= 0) { pColumn = (LISTVIEW_COLUMN *)GUI_ARRAY_GetpItem(&pObj->ColumnArray, Column); if (pColumn->fpCompare) { pSort = (LISTVIEW_SORT *)GUI_ALLOC_h2p(pObj->hSort); if (pSort) { // ReverseSort if (pObj->SortIndex == Column) { pSort->Reverse ^= 1; pObj->ReverseSort = 1; pObj->IsSorted = 0; } else { pSort->Reverse = 0; pObj->SortIndex = Column; pObj->IsPresorted = 0; } /* if (pObj->SortIndex == Column) { pSort->Reverse ^= 1; } else { pSort->Reverse = 0; pObj->SortIndex = Column; } pObj->IsPresorted = 0; */ LISTVIEW__InvalidateInsideArea(hObj, pObj); } } } } break; } return; case WM_PAINT: _Paint(hObj, pObj, pMsg); return; case WM_TOUCH: _OnTouch(hObj, pObj, pMsg); return; /* Important: message handled ! */ case WM_KEY: if (((const WM_KEY_INFO*)(pMsg->Data.p))->PressedCnt > 0) { int Key; Key = ((const WM_KEY_INFO*)(pMsg->Data.p))->Key; if (_AddKey(hObj, pObj, Key)) { return; } } break; /* No return here ... WM_DefaultProc needs to be called */ case WM_DELETE: _FreeAttached(pObj); break; /* No return here ... WM_DefaultProc needs to be called */ } WM_DefaultProc(pMsg); }