/********************************************************************* * * DROPDOWN_InsertString */ void DROPDOWN_InsertString(DROPDOWN_Handle hObj, const char * s, unsigned int Index) { if (hObj && s) { DROPDOWN_Obj* pObj; unsigned int NumItems; WM_LOCK(); pObj = DROPDOWN_H2P(hObj); NumItems = DROPDOWN_GetNumItems(hObj); if (Index < NumItems) { WM_HMEM hItem; hItem = GUI_ARRAY_InsertItem(&pObj->Handles, Index, strlen(s) + 1); if (hItem) { char * pBuffer = (char *)GUI_ALLOC_h2p(hItem); strcpy(pBuffer, s); } WM_InvalidateWindow(hObj); if (pObj->hListWin) { LISTBOX_InsertString(pObj->hListWin, s, Index); } } else { DROPDOWN_AddString(hObj, s); if (pObj->hListWin) { LISTBOX_AddString(pObj->hListWin, s); } } WM_UNLOCK(); } }
/********************************************************************* * * _DROPDOWN_Callback */ static void _DROPDOWN_Callback (WM_MESSAGE*pMsg) { DROPDOWN_Handle hObj = pMsg->hWin; DROPDOWN_Obj* pObj = DROPDOWN_H2P(hObj); char IsExpandedBeforeMsg; IsExpandedBeforeMsg = pObj->hListWin ? 1 : 0; /* Let widget handle the standard messages */ if (WIDGET_HandleActive(hObj, pMsg) == 0) { return; } switch (pMsg->MsgId) { case WM_NOTIFY_PARENT: switch (pMsg->Data.v) { case WM_NOTIFICATION_SCROLL_CHANGED: WM_NotifyParent(hObj, WM_NOTIFICATION_SCROLL_CHANGED); break; case WM_NOTIFICATION_CLICKED: DROPDOWN_SetSel(hObj, LISTBOX_GetSel(pObj->hListWin)); WM_SetFocus(hObj); break; case LISTBOX_NOTIFICATION_LOST_FOCUS: DROPDOWN_Collapse(hObj); break; } break; case WM_PID_STATE_CHANGED: if (IsExpandedBeforeMsg == 0) { /* Make sure we do not react a second time */ const WM_PID_STATE_CHANGED_INFO * pInfo = (const WM_PID_STATE_CHANGED_INFO*)pMsg->Data.p; if (pInfo->State) { DROPDOWN_Expand(hObj); } } break; case WM_TOUCH: if (_OnTouch(hObj, pMsg) == 0) { return; } break; case WM_PAINT: _Paint(hObj); break; case WM_DELETE: _FreeAttached(pObj); break; /* No return here ... WM_DefaultProc needs to be called */ case WM_KEY: if ( ((const WM_KEY_INFO*)(pMsg->Data.p))->PressedCnt >0) { int Key = ((const WM_KEY_INFO*)(pMsg->Data.p))->Key; switch (Key) { case GUI_KEY_TAB: break; /* Send to parent by not doing anything */ default: DROPDOWN_AddKey(hObj, Key); return; } } break; } WM_DefaultProc(pMsg); }
/********************************************************************* * * DROPDOWN_AddString */ void DROPDOWN_AddString(DROPDOWN_Handle hObj, const char* s) { DROPDOWN_Obj* pObj; if (hObj && s) { WM_LOCK(); pObj = DROPDOWN_H2P(hObj); GUI_ARRAY_AddItem(&pObj->Handles, s, strlen(s) + 1); DROPDOWN_Invalidate(hObj); WM_UNLOCK(); } }
int DROPDOWN_GetSel (DROPDOWN_Handle hObj) { int r = 0; DROPDOWN_Obj* pObj; if (hObj) { WM_LOCK(); pObj = DROPDOWN_H2P(hObj); ASSERT_IS_VALID_PTR(pObj); r = pObj->Sel; WM_UNLOCK(); } return r; }
/********************************************************************* * * DROPDOWN_GetNumItems */ int DROPDOWN_GetNumItems(DROPDOWN_Handle hObj) { DROPDOWN_Obj* pObj; int r = 0; if (hObj) { WM_LOCK(); pObj = DROPDOWN_H2P(hObj); ASSERT_IS_VALID_PTR(pObj); r = _GetNumItems(pObj); WM_UNLOCK(); } return r; }
/********************************************************************* * * DROPDOWN_Collapse */ void DROPDOWN_Collapse(DROPDOWN_Handle hObj) { DROPDOWN_Obj* pObj; if (hObj) { WM_LOCK(); pObj = DROPDOWN_H2P(hObj); if (pObj->hListWin) { WM_DeleteWindow(pObj->hListWin); pObj->hListWin = 0; } WM_UNLOCK(); } }
/********************************************************************* * * _SelectByKey */ static void _SelectByKey(DROPDOWN_Handle hObj, int Key) { int i; DROPDOWN_Obj* pObj; pObj = DROPDOWN_H2P(hObj); Key = _Tolower(Key); for (i = 0; i < _GetNumItems(pObj); i++) { char c = _Tolower(*_GetpItem(pObj, i)); if (c == Key) { DROPDOWN_SetSel(hObj, i); break; } } }
/********************************************************************* * * DROPDOWN_Expand */ void DROPDOWN_Expand(DROPDOWN_Handle hObj) { int xSize, ySize, i, NumItems; WM_HWIN hLst; GUI_RECT r; WM_HWIN hParent; WM_Obj* pParent; DROPDOWN_Obj* pObj; if (hObj) { WM_LOCK(); pObj = DROPDOWN_H2P(hObj); if (pObj->hListWin == 0) { hParent = WM_GetParent(hObj); pParent = WM_H2P(hParent); xSize = WM__GetWindowSizeX(&pObj->Widget.Win); ySize = pObj->ySizeEx; NumItems = _GetNumItems(pObj); /* Get coordinates of window in client coordiantes of parent */ r = pObj->Widget.Win.Rect; GUI_MoveRect(&r, -pParent->Rect.x0, -pParent->Rect.y0); if (pObj->Flags & DROPDOWN_CF_UP) { r.y0 -= ySize; } else { r.y0 = r.y1; } hLst = LISTBOX_CreateAsChild(NULL, WM_GetParent(hObj), r.x0, r.y0 , xSize, ySize, WM_CF_SHOW); if (pObj->Flags & DROPDOWN_SF_AUTOSCROLLBAR) { LISTBOX_SetScrollbarWidth(hLst, pObj->ScrollbarWidth); LISTBOX_SetAutoScrollV(hLst, 1); } for (i = 0; i< NumItems; i++) { LISTBOX_AddString(hLst, _GetpItem(pObj, i)); } for (i = 0; i < GUI_COUNTOF(pObj->Props.aBackColor); i++) { LISTBOX_SetBkColor(hLst, i, pObj->Props.aBackColor[i]); } for (i = 0; i < GUI_COUNTOF(pObj->Props.aTextColor); i++) { LISTBOX_SetTextColor(hLst, i, pObj->Props.aTextColor[i]); } LISTBOX_SetItemSpacing(hLst, pObj->ItemSpacing); LISTBOX_SetFont(hLst, pObj->Props.pFont); WM_SetFocus(hLst); pObj->hListWin = hLst; LISTBOX_SetOwner(hLst, hObj); LISTBOX_SetSel(hLst, pObj->Sel); WM_NotifyParent(hObj, WM_NOTIFICATION_CLICKED); } WM_UNLOCK(); } }
/********************************************************************* * * DROPDOWN_SetColor */ void DROPDOWN_SetColor(DROPDOWN_Handle hObj, unsigned int Index, GUI_COLOR Color) { DROPDOWN_Obj * pObj; if (hObj) { if (Index < GUI_COUNTOF(pObj->Props.aColor)) { WM_LOCK(); pObj = DROPDOWN_H2P(hObj); if (pObj->Props.aColor[Index] != Color) { pObj->Props.aColor[Index] = Color; DROPDOWN_Invalidate(hObj); } WM_UNLOCK(); } } }
/********************************************************************* * * DROPDOWN_SetScrollbarWidth */ void DROPDOWN_SetScrollbarWidth(DROPDOWN_Handle hObj, unsigned Width) { DROPDOWN_Obj* pObj; if (hObj) { WM_LOCK(); pObj = DROPDOWN_H2P(hObj); if (Width != (unsigned)pObj->ScrollbarWidth) { pObj->ScrollbarWidth = Width; if (pObj->hListWin) { LISTBOX_SetScrollbarWidth(pObj->hListWin, Width); } } WM_UNLOCK(); } }
/********************************************************************* * * DROPDOWN_SetTextColor */ void DROPDOWN_SetTextColor(DROPDOWN_Handle hObj, unsigned int Index, GUI_COLOR color) { DROPDOWN_Obj* pObj; if (hObj) { if (Index < GUI_COUNTOF(pObj->Props.aBackColor)) { WM_LOCK(); pObj = DROPDOWN_H2P(hObj); ASSERT_IS_VALID_PTR(pObj); pObj->Props.aTextColor[Index] = color; DROPDOWN_Invalidate(hObj); if (pObj->hListWin) { LISTBOX_SetTextColor(pObj->hListWin, Index, color); } WM_UNLOCK(); } } }
/********************************************************************* * * DROPDOWN_DeleteItem */ void DROPDOWN_DeleteItem(DROPDOWN_Handle hObj, unsigned int Index) { if (hObj) { DROPDOWN_Obj * pObj; unsigned int NumItems; NumItems = DROPDOWN_GetNumItems(hObj); if (Index < NumItems) { WM_LOCK(); pObj = DROPDOWN_H2P(hObj); GUI_ARRAY_DeleteItem(&pObj->Handles, Index); WM_InvalidateWindow(hObj); if (pObj->hListWin) { LISTBOX_DeleteItem(pObj->hListWin, Index); } WM_UNLOCK(); } } }
/********************************************************************* * * DROPDOWN_SetAutoScroll */ void DROPDOWN_SetAutoScroll(DROPDOWN_Handle hObj, int OnOff) { if (hObj) { DROPDOWN_Obj* pObj; char Flags; WM_LOCK(); pObj = DROPDOWN_H2P(hObj); Flags = pObj->Flags & (~DROPDOWN_SF_AUTOSCROLLBAR); if (OnOff) { Flags |= DROPDOWN_SF_AUTOSCROLLBAR; } if (pObj->Flags != Flags) { pObj->Flags = Flags; if (pObj->hListWin) { LISTBOX_SetAutoScrollV(pObj->hListWin, (Flags & DROPDOWN_SF_AUTOSCROLLBAR) ? 1 : 0); } } WM_UNLOCK(); } }
/********************************************************************* * * DROPDOWN_SetSel */ void DROPDOWN_SetSel(DROPDOWN_Handle hObj, int Sel) { int NumItems, MaxSel; DROPDOWN_Obj* pObj; if (hObj) { WM_LOCK(); pObj = DROPDOWN_H2P(hObj); ASSERT_IS_VALID_PTR(pObj); NumItems = _GetNumItems(pObj); MaxSel = NumItems ? NumItems-1 : 0; if (Sel > MaxSel) { Sel = MaxSel; } if (Sel != pObj->Sel) { pObj->Sel = Sel; DROPDOWN_Invalidate(hObj); WM_NotifyParent(hObj, WM_NOTIFICATION_SEL_CHANGED); } WM_UNLOCK(); } }
/********************************************************************* * * DROPDOWN_SetFont */ void DROPDOWN_SetFont(DROPDOWN_Handle hObj, const GUI_FONT GUI_UNI_PTR * pfont) { int OldHeight; DROPDOWN_Obj* pObj; if (hObj) { WM_LOCK(); pObj = DROPDOWN_H2P(hObj); ASSERT_IS_VALID_PTR(pObj); OldHeight = GUI_GetYDistOfFont(pObj->Props.pFont); pObj->Props.pFont = pfont; DROPDOWN__AdjustHeight(hObj, pObj); DROPDOWN_Invalidate(hObj); if (pObj->hListWin) { if (OldHeight != GUI_GetYDistOfFont(pObj->Props.pFont)) { DROPDOWN_Collapse(hObj); DROPDOWN_Expand(hObj); } LISTBOX_SetFont(pObj->hListWin, pfont); } WM_UNLOCK(); } }
/********************************************************************* * * _Paint */ static void _Paint(DROPDOWN_Handle hObj) { int Border; GUI_RECT r; const char* s; int InnerSize, ColorIndex; DROPDOWN_Obj* pObj; int TextBorderSize; /* Do some initial calculations */ pObj = DROPDOWN_H2P(hObj); Border = pObj->Widget.pEffect->EffectSize; TextBorderSize = pObj->Props.TextBorderSize; GUI_SetFont(pObj->Props.pFont); ColorIndex = (pObj->Widget.State & WIDGET_STATE_FOCUS) ? 2 : 1; s = _GetpItem(pObj, pObj->Sel); WM_GetClientRect(&r); GUI__ReduceRect(&r, &r, Border); InnerSize = r.y1 - r.y0 + 1; /* Draw the 3D effect (if configured) */ WIDGET__EFFECT_DrawDown(&pObj->Widget); /* Draw the outer text frames */ r.x1 -= InnerSize; /* Spare square area to the right */ LCD_SetColor(pObj->Props.aBackColor[ColorIndex]); /* Draw the text */ LCD_SetBkColor(pObj->Props.aBackColor[ColorIndex]); GUI_FillRectEx(&r); r.x0 += TextBorderSize; r.x1 -= TextBorderSize; LCD_SetColor (pObj->Props.aTextColor[ColorIndex]); GUI_DispStringInRect(s, &r, pObj->Props.Align);/**/ /* Draw arrow */ WM_GetClientRect(&r); GUI__ReduceRect(&r, &r, Border); r.x0 = r.x1 + 1 - InnerSize; LCD_SetColor(0xc0c0c0); GUI_FillRectEx(&r); LCD_SetColor(GUI_BLACK); _DrawTriangleDown((r.x1 + r.x0) / 2, r.y0 + 5, (r.y1 - r.y0 - 8) / 2); WIDGET__EFFECT_DrawUpRect(&pObj->Widget, &r); }
/********************************************************************* * * DROPDOWN_CreateEx */ DROPDOWN_Handle DROPDOWN_CreateEx(int x0, int y0, int xsize, int ysize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id) { DROPDOWN_Handle hObj; hObj = WM_CreateWindowAsChild(x0, y0, xsize, -1, hParent, WinFlags, _DROPDOWN_Callback, sizeof(DROPDOWN_Obj) - sizeof(WM_Obj)); if (hObj) { DROPDOWN_Obj* pObj; WM_LOCK(); pObj = DROPDOWN_H2P(hObj); /* Init sub-classes */ GUI_ARRAY_CREATE(&pObj->Handles); /* init widget specific variables */ WIDGET__Init(&pObj->Widget, Id, WIDGET_STATE_FOCUSSABLE); pObj->Flags = ExFlags; pObj->Props = DROPDOWN__DefaultProps; pObj->ScrollbarWidth = 0; INIT_ID(pObj); pObj->ySizeEx = ysize; DROPDOWN__AdjustHeight(hObj, pObj); WM_UNLOCK(); } return hObj; }