home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / gbtn02.zip / Buttons.CPP next >
C/C++ Source or Header  |  1997-04-22  |  12KB  |  302 lines

  1. #define INCL_WIN
  2. #define INCL_GPI
  3. #include <OS2.H>
  4. #include <stdlib.H>
  5. #include <string.H>
  6. #include <math.H>
  7. #include "Buttons.H"
  8.  
  9. #define HAVECAPTURE 1
  10. #define HAVEFOCUS   2
  11. #define INSIDERECT  4
  12. #define SPACEDOWN   8
  13.  
  14. typedef union {
  15.     ULONG Index;
  16.     struct {
  17.         UCHAR blue,green,red;
  18.         UCHAR dummy;
  19.     } rgb;
  20. } CLR;
  21.  
  22. typedef struct {
  23.   BYTE      Flags;
  24.   HPOINTER  Bitmap;
  25.     CLR       Colour;
  26.     CLR       BackgroundColour;
  27. //CLR         ForegroundColour;
  28. //CLR         DisabledColour;
  29.   PSZ       pszText;
  30. } GBTN;
  31.  
  32. typedef GBTN *PGBTN;
  33.  
  34. MRESULT EXPENTRY ButtonClassProc(HWND, ULONG, MPARAM, MPARAM);
  35.  
  36. BOOL EXPENTRY RegisterShadedButtonClass() {
  37.   return WinRegisterClass ((HAB) 0, SHADEDBTNCLASS, ButtonClassProc, CS_SIZEREDRAW, sizeof (PGBTN));
  38. }
  39.  
  40. MRESULT EXPENTRY ButtonClassProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) {
  41.   POINTL        ptl;
  42.   GBTN          *pGradBtn;
  43.   WNDPARAMS     *pwprm;
  44.   RECTL         rcl;
  45.  
  46.   pGradBtn = (PGBTN) WinQueryWindowPtr (hwnd, 0);
  47.  
  48.   switch(msg) {
  49.   case WM_CREATE: {
  50.       CREATESTRUCT  *pcrst;
  51.       pGradBtn = (PGBTN) malloc (sizeof (GBTN));
  52.       pGradBtn->Flags = 0;
  53.       pcrst = (PCREATESTRUCT) PVOIDFROMMP(mp2);
  54.       pGradBtn->pszText = (PSZ) malloc(1+strlen(pcrst->pszText));
  55.       strcpy(pGradBtn->pszText, pcrst->pszText);
  56.             if (WinQueryWindowULong(hwnd, QWL_STYLE) & GBT_GRAPHIC)
  57.                 pGradBtn->Bitmap = WinLoadPointer(HWND_DESKTOP, 0UL, atoi(pGradBtn->pszText));
  58.         }
  59.     WinSetWindowPtr(hwnd, 0, pGradBtn);
  60.  
  61.         ULONG ulID;
  62.         if (!WinQueryPresParam(hwnd, PP_BACKGROUNDCOLOR, PP_BACKGROUNDCOLORINDEX, NULL, 4UL, (PVOID)&(pGradBtn->Colour.Index), QPF_ID2COLORINDEX))
  63.             pGradBtn->BackgroundColour.Index = 0x00CCCCCC;
  64.         if (!WinQueryPresParam(hwnd, GBPP_BUTTONCOLOR, GBPP_BUTTONCOLORINDEX, NULL, 4UL, (PVOID)&(pGradBtn->Colour.Index), QPF_ID2COLORINDEX))
  65.             pGradBtn->Colour.Index = WinQuerySysColor(HWND_DESKTOP, SYSCLR_BUTTONMIDDLE, 0L);
  66.     return 0;
  67.     case GBM_SETCOLOR:
  68.         pGradBtn->Colour.Index = LONGFROMMP (mp1);
  69.     WinInvalidateRect(hwnd, NULL, FALSE);
  70.         return MRFROMSHORT(1);
  71.   case WM_SETWINDOWPARAMS:
  72.     pwprm = (PWNDPARAMS) PVOIDFROMMP (mp1);
  73.     if(pwprm->fsStatus & WPM_TEXT) {
  74.       free(pGradBtn->pszText);
  75.       pGradBtn->pszText = (PSZ) malloc(1+pwprm->cchText);
  76.       strcpy(pGradBtn->pszText, pwprm->pszText);
  77.     } else break;
  78.         WinInvalidateRect(hwnd, NULL, FALSE);
  79.     return MRFROMSHORT(1);
  80.   case WM_QUERYWINDOWPARAMS:
  81.     pwprm = (PWNDPARAMS) PVOIDFROMMP (mp1);
  82.     if(pwprm->fsStatus & WPM_CCHTEXT)
  83.       pwprm->cchText = strlen (pGradBtn->pszText);
  84.     if(pwprm->fsStatus & WPM_TEXT)
  85.       strcpy (pwprm->pszText, pGradBtn->pszText);
  86.     if(pwprm->fsStatus & WPM_CBCTLDATA)
  87.       pwprm->cbCtlData = 0;
  88.     if(pwprm->fsStatus & WPM_CTLDATA)
  89.       pwprm->pCtlData = 0;
  90.         if(pwprm->fsStatus & (WPM_CCHTEXT | WPM_TEXT | WPM_CBCTLDATA | WPM_CTLDATA))
  91.         return MRFROMSHORT(1);
  92.         break;
  93.     case WM_PRESPARAMCHANGED:
  94.         switch (LONGFROMMP(mp1)) {
  95.             case 0:
  96.                 if (!WinQueryPresParam(hwnd, PP_BACKGROUNDCOLOR, PP_BACKGROUNDCOLORINDEX, NULL, 4UL, (PVOID)&(pGradBtn->Colour.Index), QPF_ID2COLORINDEX))
  97.                     pGradBtn->BackgroundColour.Index = 0x00CCCCCC;
  98.                 if (!WinQueryPresParam(hwnd, GBPP_BUTTONCOLOR, GBPP_BUTTONCOLORINDEX, NULL, 4UL, (PVOID)&(pGradBtn->Colour.Index), QPF_ID2COLORINDEX))
  99.                     pGradBtn->Colour.Index = WinQuerySysColor(HWND_DESKTOP, SYSCLR_BUTTONMIDDLE, 0L);
  100.                 return MRFROMSHORT(1);
  101.             case PP_BACKGROUNDCOLOR:
  102.             case PP_BACKGROUNDCOLORINDEX:
  103.                 if (!WinQueryPresParam(hwnd, PP_BACKGROUNDCOLOR, PP_BACKGROUNDCOLORINDEX, NULL, 4UL, (PVOID)&(pGradBtn->Colour.Index), QPF_ID2COLORINDEX))
  104.                     pGradBtn->BackgroundColour.Index = 0x00CCCCCC;
  105.                 return MRFROMSHORT(1);
  106.             case GBPP_BUTTONCOLOR:
  107.             case GBPP_BUTTONCOLORINDEX:
  108.                 if (!WinQueryPresParam(hwnd, GBPP_BUTTONCOLOR, GBPP_BUTTONCOLORINDEX, NULL, 4UL, (PVOID)&(pGradBtn->Colour.Index), QPF_ID2COLORINDEX))
  109.                     pGradBtn->Colour.Index = WinQuerySysColor(HWND_DESKTOP, SYSCLR_BUTTONMIDDLE, 0L);
  110.                 return MRFROMSHORT(1);
  111.         }
  112.         break;
  113.     case WM_SYSCOLORCHANGE:
  114.         if (WinQueryPresParam(hwnd, PP_BACKGROUNDCOLOR, PP_BACKGROUNDCOLORINDEX, NULL, 4UL, (PVOID)&(pGradBtn->Colour.Index), QPF_ID2COLORINDEX))
  115.             pGradBtn->Colour.Index = WinQuerySysColor(HWND_DESKTOP, SYSCLR_BUTTONMIDDLE, 0L);
  116.         break;
  117.   case WM_BUTTON1DOWN:
  118.     if(WinQueryWindowULong(hwnd, QWL_STYLE) & GBT_NOPUSH)
  119.       break;
  120.     WinSetFocus(HWND_DESKTOP, hwnd);
  121.     WinSetCapture(HWND_DESKTOP, hwnd);
  122.     pGradBtn->Flags |= HAVECAPTURE | INSIDERECT;
  123.     WinInvalidateRect(hwnd, NULL, FALSE);
  124.     return 0;
  125.   case WM_MOUSEMOVE: {
  126.       BOOL fTestInsideRect;
  127.       if((pGradBtn->Flags & HAVECAPTURE) == 0)
  128.         break;
  129.       WinQueryWindowRect(hwnd, &rcl);
  130.       ptl.x = MOUSEMSG(&msg)->x;
  131.       ptl.y = MOUSEMSG(&msg)->y;
  132.       fTestInsideRect = WinPtInRect (WinQueryAnchorBlock(hwnd), &rcl, &ptl);
  133.       if(((pGradBtn->Flags & INSIDERECT) != 0) != fTestInsideRect) {
  134.         pGradBtn->Flags ^= INSIDERECT;
  135.         WinInvalidateRect(hwnd, NULL, FALSE);
  136.       }
  137.     }
  138.     break;
  139.   case WM_BUTTON1UP:
  140.     if ((pGradBtn->Flags & HAVECAPTURE == 0) || !WinIsWindowEnabled(hwnd))
  141.       break;
  142.     WinSetCapture(HWND_DESKTOP, NULLHANDLE);
  143.     pGradBtn->Flags &= !(HAVECAPTURE | INSIDERECT);
  144.     WinQueryWindowRect(hwnd, &rcl);
  145.     ptl.x = MOUSEMSG(&msg)->x;
  146.     ptl.y = MOUSEMSG(&msg)->y;
  147.     if(WinPtInRect(WinQueryAnchorBlock(hwnd), &rcl, &ptl))
  148.       WinPostMsg(WinQueryWindow(hwnd, QW_OWNER), WM_COMMAND,
  149.           MPFROMSHORT(WinQueryWindowUShort(hwnd, QWS_ID)),
  150.           MPFROM2SHORT(CMDSRC_PUSHBUTTON, TRUE));
  151.     WinInvalidateRect(hwnd, NULL, FALSE);
  152.     return 0;
  153.   case WM_ENABLE:
  154.     WinInvalidateRect(hwnd, NULL, FALSE);
  155.     return 0;
  156.   case WM_SETFOCUS:
  157.     pGradBtn->Flags |= SHORT1FROMMP(mp2) & HAVEFOCUS;
  158.     WinInvalidateRect(hwnd, NULL, FALSE);
  159.     return 0;
  160.   case WM_CHAR:
  161.     if(!(CHARMSG(&msg)->fs & KC_VIRTUALKEY) ||
  162.          CHARMSG(&msg)->vkey != VK_SPACE    ||
  163.          CHARMSG(&msg)->fs & KC_PREVDOWN    ||
  164.          !WinIsWindowEnabled(hwnd))
  165.       break;
  166.     if(!(CHARMSG(&msg)->fs & KC_KEYUP))
  167.       pGradBtn->Flags |= SPACEDOWN;
  168.     else {
  169.       pGradBtn->Flags &= !SPACEDOWN;
  170.       WinPostMsg(WinQueryWindow(hwnd, QW_OWNER), WM_COMMAND,
  171.           MPFROMSHORT(WinQueryWindowUShort(hwnd, QWS_ID)),
  172.           MPFROM2SHORT(CMDSRC_PUSHBUTTON, FALSE));
  173.     }
  174.     WinInvalidateRect(hwnd, NULL, FALSE);
  175.     return 0;
  176.     case WM_PAINT: {
  177.             HPS hps;
  178.             long height;
  179.             CLR colr;
  180.             POINTL aptl[TXTBOX_COUNT];
  181.             POINTL left,right;
  182.             ULONG WindowStyle;
  183. // Initialize
  184.             WinQueryWindowRect(hwnd, &rcl);
  185.             WindowStyle = WinQueryWindowULong(hwnd,QWL_STYLE);
  186.             height = rcl.yTop;
  187.             hps = WinBeginPaint(hwnd, NULLHANDLE, NULL);
  188.             WinFillRect(hps, &rcl, CLR_PALEGRAY);
  189.             GpiCreateLogColorTable(hps, LCOL_RESET, LCOLF_RGB, 0L, 0L, NULL);
  190. // Draw gradient pattern
  191.             colr.Index = 0UL;
  192.             left.x = rcl.xLeft;
  193.             right.x = rcl.xRight;
  194.             for(left.y = right.y = 1; right.y < height; right.y++, left.y++) {
  195.                 if (pGradBtn->Flags & (INSIDERECT | SPACEDOWN)) {
  196.                     colr.rgb.red = pGradBtn->Colour.rgb.red * (2 * right.y + 3 * height) / 6 / height;
  197.                     colr.rgb.green = pGradBtn->Colour.rgb.green * (2 * right.y + 3 * height) / 6 / height;
  198.                     colr.rgb.blue = pGradBtn->Colour.rgb.blue * (2 * right.y + 3 * height) / 6 / height;
  199.                 } else {
  200.                     colr.rgb.red = pGradBtn->Colour.rgb.red * ( height + right.y) / 2 / height;
  201.                     colr.rgb.green = pGradBtn->Colour.rgb.green * (height + right.y) / 2 / height;
  202.                     colr.rgb.blue = pGradBtn->Colour.rgb.blue * (height + right.y) / 2 / height;
  203.                 }
  204.                 if(WindowStyle & GBT_RIGHTROUND)
  205.                     right.x = rcl.xRight - height / 2 + (LONG) sqrt((float) (right.y * (height - right.y)));
  206.                 if(WindowStyle & GBT_LEFTROUND)
  207.                     left.x = height / 2 - (LONG) sqrt((float) (left.y * (height - left.y)));
  208.                 GpiSetColor(hps, colr.Index);
  209.                 GpiMove(hps, &left);
  210.                 GpiLine(hps, &right);
  211.             }
  212. // Draw border
  213.             rcl.xRight--;
  214.             rcl.yTop--;
  215.             ptl.y = rcl.yBottom;
  216.             ptl.x = (WindowStyle & GBT_LEFTROUND) ? rcl.xLeft + height / 2 : rcl.xLeft;
  217.             GpiMove(hps, &ptl);
  218.             ptl.y = rcl.yBottom;
  219.             ptl.x = (WindowStyle & GBT_RIGHTROUND) ? rcl.xRight - height / 2 : rcl.xRight;
  220.             GpiSetColor(hps, 0x00888888);
  221.             GpiLine(hps, &ptl);
  222.             ptl.y = rcl.yTop;
  223.             if (WindowStyle & GBT_RIGHTROUND) {
  224.                 ARCPARAMS arcparams;
  225.                 arcparams.lP = arcparams.lQ = height / 2;
  226.                 arcparams.lR = arcparams.lS = 0L;
  227.                 GpiSetArcParams(hps, &arcparams);
  228.                 right.x = rcl.xRight - height / 2;
  229.                 right.y = height / 2;
  230.                 GpiPartialArc(hps, &right, MAKEFIXED(1,0), MAKEFIXED(270,0), MAKEFIXED(90,0));
  231.                 if (!(height % 2))
  232.                     right.y--;
  233.                 GpiPartialArc(hps, &right, MAKEFIXED(1,0), MAKEFIXED(0,0), MAKEFIXED(45,0));
  234.                 GpiSetColor(hps, (pGradBtn->Flags & (INSIDERECT | SPACEDOWN) ? 0x00888888 : 0x00FFFFFF));
  235.                 GpiPartialArc(hps, &right, MAKEFIXED(1,0), MAKEFIXED(45,0), MAKEFIXED(45,0));
  236.                 GpiMove(hps, &ptl);
  237.             } else { if (WindowStyle & GBT_NORIGHTLINE)
  238.                     GpiMove(hps, (PPOINTL) &rcl.xRight);
  239.                 else
  240.                     GpiLine(hps, (PPOINTL) &rcl.xRight);
  241.                 GpiSetColor(hps, (pGradBtn->Flags & (INSIDERECT | SPACEDOWN) ? 0x00888888 : 0x00FFFFFF));
  242.             }
  243.             ptl.y = rcl.yTop;
  244.             ptl.x = (WindowStyle & GBT_LEFTROUND) ? rcl.xLeft + height / 2 : rcl.xLeft;
  245.             GpiLine(hps, &ptl);
  246.             rcl.yBottom = 1;
  247.             if (WindowStyle & GBT_LEFTROUND) {
  248.                 ARCPARAMS arcparams;
  249.                 arcparams.lP = arcparams.lQ = height / 2;
  250.                 arcparams.lR = arcparams.lS = 0L;
  251.                 GpiSetArcParams(hps, &arcparams);
  252.                 ptl.y = ptl.x = height / 2;
  253.                 if (!(height % 2))
  254.                     ptl.y--;
  255.                 GpiPartialArc(hps, &ptl, MAKEFIXED(1,0), MAKEFIXED(90,0), MAKEFIXED(90,0));
  256.                 if (!(height % 2))
  257.                     ptl.y++;
  258.                 GpiPartialArc(hps, &ptl, MAKEFIXED(1,0), MAKEFIXED(180,0), MAKEFIXED(45,0));
  259.                 GpiSetColor(hps, 0x00888888);
  260.                 GpiPartialArc(hps, &ptl, MAKEFIXED(1,0), MAKEFIXED(215,0), MAKEFIXED(45,0));
  261.             } else if (!(WindowStyle & GBT_NOLEFTLINE))
  262.                     GpiLine(hps, (PPOINTL) &rcl.xLeft);
  263.             rcl.yBottom = 0;
  264. // Draw text
  265. //            GpiCreateLogColorTable(hps, LCOL_RESET, LCOLF_DEFAULT, 0L, 0L, NULL);
  266.             ptl.x = rcl.xRight >> 1;
  267.             ptl.y = rcl.yTop >> 1;
  268.             if (WindowStyle & GBT_RIGHTROUND)
  269.                 ptl.x -= rcl.yTop >> 1;
  270.             if (WindowStyle & GBT_LEFTROUND)
  271.                 ptl.x += rcl.yTop >> 1;
  272.             if (pGradBtn->Flags & (INSIDERECT | SPACEDOWN)) {
  273.                 ptl.x++;
  274.                 ptl.y--;
  275.             }
  276.             if (WindowStyle & GBT_GRAPHIC) {
  277.                 LONG PointerWidth, PointerHeight;
  278.                 PointerWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXPOINTER);
  279.                 PointerHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYPOINTER);
  280.                 ptl.x -= PointerWidth >> 1;
  281.                 ptl.y -= PointerHeight >> 1;
  282.                 WinDrawPointer(hps, ptl.x, ptl.y, pGradBtn->Bitmap, WinIsWindowEnabled(hwnd) ? DP_NORMAL : DP_HALFTONED);
  283.             } else {
  284.                 GpiQueryTextBox(hps, strlen(pGradBtn->pszText), pGradBtn->pszText, TXTBOX_COUNT, aptl);
  285.                 ptl.x -= aptl[TXTBOX_CONCAT].x >> 1;
  286.                 ptl.y -= (aptl[TXTBOX_TOPLEFT].y + aptl[TXTBOX_BOTTOMLEFT].y) >> 1;
  287.                 GpiSetColor(hps, (WinIsWindowEnabled(hwnd) ? 0x00000000 : 0x00888888));
  288.                 GpiCharStringAt (hps, &ptl, strlen(pGradBtn->pszText), pGradBtn->pszText);
  289.             }
  290.             WinEndPaint(hps);
  291.             return 0;
  292.         }
  293.   case WM_DESTROY:
  294.                 if (WinQueryWindowULong(hwnd, QWL_STYLE) & GBT_GRAPHIC)
  295.                         WinDestroyPointer(pGradBtn->Bitmap);
  296.     free(pGradBtn->pszText);
  297.     free(pGradBtn);
  298.     return 0;
  299.   }
  300.   return WinDefWindowProc(hwnd, msg, mp1, mp2);
  301. }
  302.