Scrollbar.c
上传用户:zbk8730
上传日期:2017-08-10
资源大小:12168k
文件大小:15k
源码类别:

uCOS

开发平台:

C/C++

  1. /*
  2. *********************************************************************************************************
  3. *                                                uC/GUI
  4. *                        Universal graphic software for embedded applications
  5. *
  6. *                       (c) Copyright 2002, Micrium Inc., Weston, FL
  7. *                       (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
  8. *
  9. *              礐/GUI is protected by international copyright laws. Knowledge of the
  10. *              source code may not be used to write a similar product. This file may
  11. *              only be used in accordance with a license and should not be redistributed
  12. *              in any way. We appreciate your understanding and fairness.
  13. *
  14. ----------------------------------------------------------------------
  15. File        : SCROLLBAR.c
  16. Purpose     : SCROLLBAR for new emWin GSC widgets
  17. ---------------------------END-OF-HEADER------------------------------
  18. */
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include "GUI_Private.H"
  22. #include "SCROLLBAR.h"
  23. #include "Widget.h"
  24. #if GUI_WINSUPPORT
  25. /*********************************************************************
  26. *
  27. *       Private config defaults
  28. *
  29. **********************************************************************
  30. */
  31. /* Support for 3D effects */
  32. #ifndef SCROLLBAR_USE_3D
  33.   #define SCROLLBAR_USE_3D 1
  34. #endif
  35. /* Define colors */
  36. #ifndef SCROLLBAR_BKCOLOR0_DEFAULT
  37.   #define SCROLLBAR_BKCOLOR0_DEFAULT 0x808080
  38. #endif
  39. #ifndef SCROLLBAR_BKCOLOR1_DEFAULT
  40.   #define SCROLLBAR_BKCOLOR1_DEFAULT GUI_BLACK
  41. #endif
  42. #ifndef SCROLLBAR_COLOR0_DEFAULT
  43.   #define SCROLLBAR_COLOR0_DEFAULT 0xc0c0c0
  44. #endif
  45. #ifndef SCROLLBAR_COLOR1_DEFAULT
  46.   #define SCROLLBAR_COLOR1_DEFAULT GUI_BLACK
  47. #endif
  48. /*********************************************************************
  49. *
  50. *       Object definition
  51. *
  52. **********************************************************************
  53. */
  54. typedef struct {
  55.   WIDGET Widget;
  56.   GUI_COLOR aBkColor[2];
  57.   GUI_COLOR aColor[2];
  58.   int NumItems, v, PageSize;
  59.   #if GUI_DEBUG_LEVEL >1
  60.     int DebugId;
  61.   #endif  
  62. } SCROLLBAR_Obj;
  63. typedef struct {
  64.   int x1_LeftArrow;
  65.   int x0_Thumb;
  66.   int x1_Thumb;
  67.   int x0_RightArrow;
  68.   int xSizeMoveable;
  69.   int ThumbSize;
  70. } POSITIONS;
  71. /*********************************************************************
  72. *
  73. *       Static data
  74. *
  75. **********************************************************************
  76. */
  77. I16 _DefaultWidth = 11;
  78. /*********************************************************************
  79. *
  80. *       Macros for internal use
  81. *
  82. **********************************************************************
  83. */
  84. #define SCROLLBAR_ID 0x4544   /* Magic numer, should be unique if possible */
  85. #define SCROLLBAR_H2P(h) (SCROLLBAR_Obj*) WM_H2P(h)
  86. #ifdef _DEBUG
  87.   #define SCROLLBAR_ASSERT_IS_VALID_PTR(p) DEBUG_ERROROUT_IF(p->DebugId != SCROLLBAR_ID, "xxx.c: Wrong handle type or Object not init'ed")
  88.   #define SCROLLBAR_INIT_ID(p)   p->DebugId = SCROLLBAR_ID
  89.   #define SCROLLBAR_DEINIT_ID(p) p->DebugId = SCROLLBAR_ID+1
  90. #else
  91.   #define SCROLLBAR_ASSERT_IS_VALID_PTR(p)
  92.   #define SCROLLBAR_INIT_ID(p)
  93.   #define SCROLLBAR_DEINIT_ID(p)
  94. #endif
  95. /*********************************************************************
  96. *
  97. *       Static routines
  98. *
  99. **********************************************************************
  100. */
  101. static int _GetArrowSize(SCROLLBAR_Obj* pObj) {
  102.   unsigned int r;
  103.   unsigned int xSize = WIDGET__GetXSize(&pObj->Widget);
  104.   unsigned int ySize = WIDGET__GetYSize(&pObj->Widget);
  105.   r = ySize/2 + 5;
  106.   if (r > xSize-5)
  107.     r = xSize-5;
  108.   return r;
  109. }
  110. /*********************************************************************
  111. *
  112. *       _GetPositions
  113.   Calculates all positions required for drawing or for mouse / touch
  114.   evaluation.
  115. */
  116. static void _GetPositions(SCROLLBAR_Obj* pObj, POSITIONS* pPos) {
  117.   int xSizeArrow, xSize, xSizeMoveable, ThumbSize, NumItems, xSizeThumbArea;
  118.   NumItems      = pObj->NumItems;
  119.   xSize         = WIDGET__GetXSize(&pObj->Widget);
  120.   xSizeArrow    = _GetArrowSize(pObj);
  121.   xSizeThumbArea= xSize - 2*xSizeArrow;     /* Number of pixels available for thumb and movement */
  122.   ThumbSize     = GUI__DivideRound(xSizeThumbArea * pObj->PageSize, NumItems);
  123.   if (ThumbSize < 4)
  124.     ThumbSize = 4;
  125.   xSizeMoveable = xSizeThumbArea - ThumbSize;
  126.   pPos->x1_LeftArrow  = xSizeArrow-1;
  127.   pPos->x0_RightArrow = xSize - xSizeArrow;
  128.   pPos->x0_Thumb      = pPos->x1_LeftArrow + 1+ GUI__DivideRound(xSizeMoveable * pObj->v, NumItems - pObj->PageSize);
  129.   pPos->x1_Thumb      = pPos->x0_Thumb + ThumbSize - 1;
  130.   pPos->xSizeMoveable = xSizeMoveable;
  131.   pPos->ThumbSize     = ThumbSize;
  132. }
  133. /*********************************************************************
  134. *
  135. *       _DrawTriangle
  136. */
  137. static void _DrawTriangle(WIDGET* pWidget, int x, int y, int Size, int Inc) {
  138.   if (pWidget->State & WIDGET_STATE_VERTICAL) {
  139.     for (; Size >= 0; Size--, x += Inc) {
  140.       GUI_DrawHLine(x, y - Size, y + Size);
  141.     }
  142.   } else {
  143.     for (; Size >= 0; Size--, x += Inc) {
  144.       GUI_DrawVLine(x, y - Size, y + Size);
  145.     }
  146.   }
  147. }
  148. /*********************************************************************
  149. *
  150. *       _Paint
  151. */
  152. static void _Paint(SCROLLBAR_Obj* pObj) {
  153.   int xArrow, ArrowSize, ArrowOff;
  154.   POSITIONS Pos;
  155.   GUI_RECT r, rClient;
  156.   /*
  157.     Get / calc position info
  158.   */
  159.   _GetPositions(pObj, &Pos);
  160.   xArrow = _GetArrowSize(pObj);
  161.   WIDGET__GetClientRect(&pObj->Widget, &rClient);
  162.   r = rClient;
  163.   ArrowSize = ((r.y1 - r.y0) /3) - 1;
  164.   /*
  165.     Draw the thumb area ( optimized ... We could also fill using GUI_Clear())
  166.   */
  167.   GUI_SetColor(pObj->aBkColor[0]);
  168.   r = rClient;
  169.   r.x0 = Pos.x1_LeftArrow + 1;
  170.   r.x1 = Pos.x0_Thumb - 1;
  171.   WIDGET__FillRectEx(&pObj->Widget, &r);
  172.   r.x0 = Pos.x1_Thumb + 1;
  173.   r.x1 = Pos.x0_RightArrow - 1;
  174.   WIDGET__FillRectEx(&pObj->Widget, &r);
  175.   /*
  176.     Draw left Arrow
  177.   */
  178.   ArrowOff = 3 + ArrowSize+ ArrowSize/3;
  179.   GUI_SetColor(pObj->aColor[0]);
  180.   r = rClient;
  181.   r.x1 = xArrow-1;
  182.   WIDGET__FillRectEx(&pObj->Widget, &r);
  183.   GUI_SetColor(pObj->aBkColor[1]);
  184.   _DrawTriangle(&pObj->Widget, r.x0 + ArrowOff, (r.y1 - r.y0) >> 1, ArrowSize, -1);
  185.   WIDGET__EFFECT_DrawUpRect(&pObj->Widget, &r);
  186.   /*
  187.     Draw right Arrow
  188.   */
  189.   GUI_SetColor(pObj->aColor[0]);
  190.   r = rClient;
  191.   r.x0 = r.x1 - (xArrow - 1);
  192.   WIDGET__FillRectEx(&pObj->Widget, &r);
  193.   GUI_SetColor(pObj->aBkColor[1]);
  194.   _DrawTriangle(&pObj->Widget, r.x1 - ArrowOff, (r.y1 - r.y0) >> 1, ArrowSize, 1);
  195.   WIDGET__EFFECT_DrawUpRect(&pObj->Widget, &r);
  196.   /*
  197.     Draw Thumb
  198.   */
  199.   r = rClient;
  200.   r.x0 = Pos.x0_Thumb;
  201.   r.x1 = Pos.x1_Thumb;
  202.   GUI_SetColor(pObj->aColor[0]);
  203.   WIDGET__FillRectEx(&pObj->Widget, &r);
  204.   WIDGET__EFFECT_DrawUpRect(&pObj->Widget, &r);
  205. }
  206. /*********************************************************************
  207. *
  208. *       _OnTouch
  209. */
  210. static void _OnTouch(SCROLLBAR_Handle hObj, SCROLLBAR_Obj* pObj, WM_MESSAGE*pMsg) {
  211.   POSITIONS Pos;
  212.   GUI_TOUCH_tState* pState = (GUI_TOUCH_tState*)pMsg->Data.p;
  213.   if (pMsg->Data.p) {  /* Something happened in our area (pressed or released) */
  214.     if (pState->Pressed) {
  215.       int Sel;
  216.       int Range;
  217.       int x;
  218.       Sel = pObj->v;
  219.       _GetPositions(pObj, &Pos);
  220.       Range = pObj->NumItems - pObj->PageSize;
  221.       /* Swap mouse coordinates if necessary */
  222.       if (pObj->Widget.State & WIDGET_STATE_VERTICAL) {
  223.         int t = pState->x;
  224.         pState->x = pState->y;
  225.         pState->y = t;
  226.       }
  227.       x = pState->x;
  228.       if (x <= Pos.x1_LeftArrow) {         /* left arrow (line left) */
  229.         Sel--;
  230.       } else if (x < Pos.x0_Thumb) {       /* left area  (page left) */
  231.         Sel -= pObj->PageSize;
  232.       } else if (x <= Pos.x1_Thumb) {      /* Thumb area */
  233.         if (Pos.xSizeMoveable > 0) {
  234.           x = x - Pos.ThumbSize/2 - Pos.x1_LeftArrow-1;
  235.           Sel = GUI__DivideRound(Range * x, Pos.xSizeMoveable);
  236.         }
  237.       } else if (x < Pos.x0_RightArrow) {  /* right area (page right) */
  238.         Sel += pObj->PageSize;
  239.       } else {
  240.         Sel++;
  241.       }
  242.       /* WM_SetFocus(hObj); */
  243.       WM_SetCapture(hObj, 1);
  244.       SCROLLBAR_SetValue(hObj, Sel);
  245.     }
  246.   }
  247. }
  248. /*********************************************************************
  249. *
  250. *       _OnKey
  251. */
  252. static void  _OnKey(SCROLLBAR_Handle hObj, WM_MESSAGE*pMsg) {
  253.   WM_KEY_INFO* pKeyInfo;
  254.   int Key;
  255.   pKeyInfo = (WM_KEY_INFO*)(pMsg->Data.p);
  256.   Key = pKeyInfo->Key;
  257.   if (pKeyInfo->PressedCnt > 0) {
  258.     switch (Key) {
  259.       case GUI_KEY_RIGHT:
  260.       case GUI_KEY_DOWN:
  261.         SCROLLBAR_Inc(hObj);
  262.         break;                    /* Send to parent by not doing anything */
  263.       case GUI_KEY_LEFT:
  264.       case GUI_KEY_UP:
  265.         SCROLLBAR_Dec(hObj);
  266.         break;                    /* Send to parent by not doing anything */
  267.       default:
  268.         return;
  269.     }
  270.   }
  271. }
  272. /*********************************************************************
  273. *
  274. *       _OnSetScrollState 
  275. */
  276. static void _OnSetScrollState(SCROLLBAR_Handle hObj, SCROLLBAR_Obj* pObj, const WM_SCROLL_STATE* pState) {
  277.   pObj->NumItems = pState->NumItems;
  278.   pObj->PageSize = pState->PageSize;
  279.   pObj->v        = pState->v;
  280.   WM_InvalidateWindow(hObj);
  281. }
  282. /*********************************************************************
  283. *
  284. *       _SCROLLBAR_Callback
  285. */
  286. static void _SCROLLBAR_Callback (WM_MESSAGE *pMsg) {
  287.   SCROLLBAR_Handle hObj;
  288.   SCROLLBAR_Obj* pObj;
  289.   hObj = pMsg->hWin;
  290.   pObj = SCROLLBAR_H2P(hObj);
  291.   /* Let widget handle the standard messages */
  292.   if (WIDGET_HandleActive(hObj, pMsg) == 0) {
  293.     return;
  294.   }
  295.   switch (pMsg->MsgId) {
  296.   case WM_PAINT:
  297.     GUI_DEBUG_LOG("SCROLLBAR: _Callback(WM_PAINT)n");
  298.     _Paint(pObj);
  299.     return;
  300.   case WM_TOUCH:
  301.     _OnTouch(hObj, pObj, pMsg);
  302.     break;
  303.   case WM_KEY:
  304.     _OnKey(hObj, pMsg);
  305.     break;
  306.   case WM_SET_SCROLL_STATE:
  307.     _OnSetScrollState(hObj, pObj, (const WM_SCROLL_STATE*)pMsg->Data.p);
  308.     break;
  309.   case WM_GET_SCROLL_STATE:
  310.     ((WM_SCROLL_STATE*)pMsg->Data.p)->NumItems = pObj->NumItems;
  311.     ((WM_SCROLL_STATE*)pMsg->Data.p)->PageSize = pObj->PageSize;
  312.     ((WM_SCROLL_STATE*)pMsg->Data.p)->v        = pObj->v;
  313.     break;
  314.   }
  315.   WM_DefaultProc(pMsg);
  316. }
  317. /*********************************************************************
  318. *
  319. *       Exported routines:  Create
  320. *
  321. **********************************************************************
  322. */
  323. /* Note: the parameters to a create function may vary.
  324.          Some widgets may have multiple create functions */
  325. SCROLLBAR_Handle SCROLLBAR_Create (int x0, int y0, int xsize, int ysize, WM_HWIN hParent, int Id, int WinFlags, int SpecialFlags) {
  326.   SCROLLBAR_Handle hObj;
  327.   WM_LOCK();
  328.   /* Set defaults if necessary */
  329.   if ((xsize == 0) && (ysize == 0)) {
  330.     GUI_RECT Rect;
  331.     WM_GetInsideRect(hParent, &Rect);
  332.     if (SpecialFlags & SCROLLBAR_CF_VERTICAL) {
  333.       xsize = _DefaultWidth;
  334.       x0 = Rect.x1 +1 - xsize;
  335.       y0 = Rect.y0;
  336.       ysize = Rect.y1 - Rect.y0 +1;
  337.     } else {
  338.       ysize = _DefaultWidth;
  339.     }
  340.   }
  341.   /* Create the window */
  342.   hObj = WM_CreateWindowAsChild(x0, y0, xsize, ysize, hParent,
  343.                        WinFlags, _SCROLLBAR_Callback, sizeof(SCROLLBAR_Obj)-sizeof(WM_Obj));
  344.   if (hObj) {
  345.     SCROLLBAR_Obj* pObj = SCROLLBAR_H2P(hObj);
  346.     U16 InitState;
  347.     /* Handle SpecialFlags */
  348.     InitState = WIDGET_STATE_ENABLED;
  349.     if (SpecialFlags & SCROLLBAR_CF_VERTICAL) {
  350.       InitState |= WIDGET_CF_VERTICAL;
  351.     }
  352.     if ((SpecialFlags & SCROLLBAR_CF_FOCUSSABLE) == 0) {
  353.       InitState |= WIDGET_STATE_FOCUSSABLE;
  354.     }
  355.     /* init widget specific variables */
  356.     WIDGET__Init(&pObj->Widget, InitState);
  357.     /* init member variables */
  358.     SCROLLBAR_INIT_ID(pObj);
  359.     pObj->Widget.Id       = Id;
  360.     pObj->aBkColor[0]   = SCROLLBAR_BKCOLOR0_DEFAULT;
  361.     pObj->aBkColor[1]   = SCROLLBAR_BKCOLOR1_DEFAULT;
  362.     pObj->aColor[0]     = SCROLLBAR_COLOR0_DEFAULT;
  363.     pObj->aColor[1]     = SCROLLBAR_COLOR1_DEFAULT;
  364.     pObj->NumItems      = 100;
  365.     pObj->PageSize      =  10;
  366.   } else {
  367.     GUI_DEBUG_ERROROUT_IF(hObj==0, "SCROLLBAR_Create failed")
  368.   }
  369.   WM_UNLOCK();
  370.   return hObj;
  371. }
  372. SCROLLBAR_Handle SCROLLBAR_CreateAttached(WM_HWIN hParent, int SpecialFlags) {
  373.   SCROLLBAR_Handle  hThis;
  374.   int Id;
  375.   Id = (SpecialFlags & SCROLLBAR_CF_VERTICAL) ? GUI_ID_VSCROLL : GUI_ID_HSCROLL;
  376.   hThis = SCROLLBAR_Create(0,0,0,0, hParent, Id, WM_CF_SHOW,         /* WinFlags */
  377.                            SpecialFlags);
  378.   if (hThis) {
  379.     WM_MESSAGE Msg;
  380.     Msg.MsgId = WM_ADD_SCROLLBAR;
  381.     WM_SendMessage(hParent, &Msg);
  382.   }
  383.   return hThis;
  384. }
  385. SCROLLBAR_Handle SCROLLBAR_CreateIndirect(const GUI_WIDGET_CREATE_INFO* pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK* cb) {
  386.   SCROLLBAR_Handle  hThis;
  387.   GUI_USE_PARA(cb);
  388.   hThis = SCROLLBAR_Create(pCreateInfo->x0 + x0, pCreateInfo->y0 + y0, pCreateInfo->xSize, pCreateInfo->ySize,
  389.                         hWinParent, pCreateInfo->Id, 0, pCreateInfo->Flags);
  390.   return hThis;
  391. }
  392. /*********************************************************************
  393. *
  394. *       Exported routines:  Various methods
  395. *
  396. **********************************************************************
  397. */
  398. void SCROLLBAR_Dec(SCROLLBAR_Handle hObj) { SCROLLBAR_AddValue(hObj, -1); }
  399. void SCROLLBAR_Inc(SCROLLBAR_Handle hObj) { SCROLLBAR_AddValue(hObj,  1); }
  400. void SCROLLBAR_AddValue(SCROLLBAR_Handle hObj, int Add) {
  401.   SCROLLBAR_Obj* pObj;
  402.   if (hObj) {
  403.     WM_LOCK();
  404.     pObj = SCROLLBAR_H2P(hObj);
  405.     SCROLLBAR_SetValue(hObj, pObj->v + Add);
  406.     WM_UNLOCK();
  407.   }
  408. }
  409. void SCROLLBAR_SetValue(SCROLLBAR_Handle hObj, int v) {
  410.   SCROLLBAR_Obj* pObj;
  411.   int Max;
  412.   if (hObj) {
  413.     WM_LOCK();
  414.     pObj = SCROLLBAR_H2P(hObj);
  415.     Max = pObj->NumItems - pObj->PageSize;
  416.     if (Max < 0)
  417.       Max =0;
  418.     /* Put in min/max range */
  419.     if (v < 0) {
  420.       v = 0;
  421.     }
  422.     if (v > Max) {
  423.       v = Max;
  424.     }
  425.     if (pObj->v != v) {
  426.       pObj->v = v;
  427.       WM_InvalidateWindow(hObj);
  428.       WM_NotifyParent(hObj, WM_NOTIFICATION_VALUE_CHANGED);
  429.     }
  430.     WM_UNLOCK();
  431.   }
  432. }
  433. void SCROLLBAR_SetNumItems(SCROLLBAR_Handle hObj, int NumItems) {
  434.   SCROLLBAR_Obj* pObj;
  435.   if (hObj) {
  436.     WM_LOCK();
  437.     pObj = SCROLLBAR_H2P(hObj);
  438.     if (pObj->NumItems != NumItems) {
  439.       pObj->NumItems = NumItems;
  440.       WM_InvalidateWindow(hObj);
  441.     }
  442.     WM_UNLOCK();
  443.   }
  444. }
  445. void SCROLLBAR_SetPageSize(SCROLLBAR_Handle hObj, int PageSize) {
  446.   SCROLLBAR_Obj* pObj;
  447.   if (hObj) {
  448.     WM_LOCK();
  449.     pObj = SCROLLBAR_H2P(hObj);
  450.     if (pObj->PageSize != PageSize) {
  451.       pObj->PageSize = PageSize;
  452.       WM_InvalidateWindow(hObj);
  453.     }
  454.     WM_UNLOCK();
  455.   }
  456. }
  457. void  SCROLLBAR_SetState   (SCROLLBAR_Handle hObj, const WM_SCROLL_STATE* pState) {
  458.   if (hObj) {
  459.     SCROLLBAR_SetPageSize(hObj, pState->PageSize);
  460.     SCROLLBAR_SetNumItems(hObj, pState->NumItems);
  461.     SCROLLBAR_SetValue   (hObj, pState->v);
  462.   }
  463. }
  464. /*********************************************************************
  465. *
  466. *       Query state
  467. *
  468. **********************************************************************
  469. */
  470. int SCROLLBAR_GetValue(SCROLLBAR_Handle hObj) {
  471.   int r = 0;
  472.   SCROLLBAR_Obj* pObj;
  473.   if (hObj) {
  474.     WM_LOCK();
  475.     pObj = SCROLLBAR_H2P(hObj);
  476.     r = pObj->v;
  477.     WM_UNLOCK();
  478.   }
  479.   return r;
  480. }
  481. #endif  /* #if GUI_WINSUPPORT */