home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c083 / 13.ddi / NOTEBOOK.PAK / HSCROLL.CPP next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  16.4 KB  |  566 lines

  1. //----------------------------------------------------------------------------
  2. //    hscroll.cpp - class for hscroll bar gadget (non-window based) 
  3. //----------------------------------------------------------------------------
  4. //    Copyright (c) 1993 Borland International
  5. //----------------------------------------------------------------------------
  6. #include <owl\owlpch.h>
  7. #include <owl\dc.h>
  8.  
  9. #include "utils.h"        // for debugging support
  10. #include "hscroll.h"
  11. //---------------------------------------------------------------------------- 
  12. THScroll::THScroll(TWindow *Parent, int x, int y, int width, int height, 
  13.     int idnum, int Lowval, int Highval, int initval, BOOL Frame3d, 
  14.     BOOL Arrowline, BOOL Thumbmove, int Repeatdelay)
  15. {
  16.   parent = Parent;
  17.   frame3d = Frame3d;
  18.   lastfocusxoff = -1;
  19.   arrowline = Arrowline;
  20.   thumbmove = Thumbmove;
  21.   repeatdelay = Repeatdelay;
  22.   showit = TRUE;
  23.   if (arrowline)
  24.       barsize = 1;
  25.   else
  26.       barsize = 2;
  27.  
  28.   BuildBrushes();
  29.   SetScrollRange(Lowval, Highval, FALSE);
  30.   SetScrollPos(initval, FALSE);
  31.  
  32.   mousedown = HSB_NOTDOWN;
  33.   displaystate = HSB_NOTDOWN;
  34.   mylongid = MAKELONG(0, idnum);
  35.   if (! idnum)
  36.       scrollmsg = WM_HSCROLL;
  37.   else
  38.       scrollmsg = NW_HSCROLL;
  39.  
  40.   ChangeRect(TRect(x, y, x+width, y+height), FALSE);
  41. }
  42. //----------------------------------------------------------------------------
  43. THScroll::~THScroll()
  44. {
  45.   DeleteBrushes();
  46. }
  47. //----------------------------------------------------------------------------
  48. void THScroll::ShowScrollBar(BOOL show)
  49. {
  50.   showit = show;
  51. }
  52. //----------------------------------------------------------------------------
  53. void THScroll::DeleteBrushes()
  54. {
  55.   delete framebrush;
  56.   delete trackbrush;
  57.   delete hilitebrush;
  58.   delete shadowbrush;
  59.   delete facebrush;
  60. }
  61. //----------------------------------------------------------------------------
  62. void THScroll::BuildBrushes()
  63. {
  64.   framebrush = new TBrush(GetSysColor(COLOR_WINDOWFRAME));
  65.   trackbrush = new TBrush(GetSysColor(COLOR_SCROLLBAR));
  66.   hilitebrush = new TBrush(GetSysColor(COLOR_BTNHIGHLIGHT));
  67.   shadowbrush = new TBrush(GetSysColor(COLOR_BTNSHADOW));
  68.   facebrush = new TBrush(GetSysColor(COLOR_BTNFACE));
  69. }
  70. //----------------------------------------------------------------------------
  71. void THScroll::SysColorChange()
  72. {
  73.   DeleteBrushes();
  74.   BuildBrushes();
  75. }
  76. //----------------------------------------------------------------------------
  77. void THScroll::ChangeRect(TRect &newrect, BOOL repaint)
  78. {
  79.   int height = newrect.Height();
  80.   int width = newrect.Width();
  81.  
  82.   // set minimum sizes
  83.   if (height < 4)
  84.       height = 4;
  85.  
  86.   if (width < 14)
  87.       width = 14;
  88.     
  89.   framerect = TRect(newrect.left, newrect.top, newrect.left+width, 
  90.     newrect.top+height);
  91.  
  92.   if (frame3d)        // will add 3d frame on outside
  93.     sbrect = framerect.InflatedBy(-1, -1);
  94.   else
  95.     sbrect = framerect;
  96.  
  97.   // compute a few measurements here to make our life easier 
  98.   sbheight = sbrect.bottom - sbrect.top;
  99.   sbwidth = sbrect.right - sbrect.left;
  100.   sqsize = sbheight - 2;
  101.   trackwidth = sbwidth - 2*(sqsize + barsize);    // overlaps arrow lines
  102.   trange = trackwidth - (sqsize+2);
  103.   trackxoff = sbrect.left + sqsize + barsize;    // start on outer left arrow bar
  104.  
  105.   SetScrollPos(curval, SV_NOREPAINT);
  106.  
  107.   if (repaint)
  108.     MyPaint(HSB_FORCEALL);
  109. }
  110. //----------------------------------------------------------------------------
  111. void THScroll::ForcePaint()
  112. {
  113.   MyPaint(HSB_FORCEALL);
  114. }
  115. //----------------------------------------------------------------------------
  116. void THScroll::DrawFrames(TDC &mydc)
  117. {
  118.   if (frame3d)            // outer 3d frame
  119.       DrawShadeFrame(mydc, framerect, FALSE);
  120.  
  121.   // draw inner frame (avoid flicker by not painting interrior)
  122.   mydc.FrameRect(sbrect, *framebrush);
  123.  
  124.   // draw double black lines for left and right buttons
  125.   mydc.SelectObject(*framebrush);
  126.   FASTRECT(mydc, sbrect.left+sqsize+1, sbrect.top, barsize, sbheight);
  127.   FASTRECT(mydc, sbrect.right-(sqsize+1+barsize), sbrect.top, barsize, 
  128.       sbheight);
  129. }
  130.  
  131. //----------------------------------------------------------------------------
  132. void THScroll::DrawLeftArrow(TDC &mydc, BOOL isdown)
  133. {
  134.   TRect myrect(sbrect.left+1, sbrect.top+1, sbrect.left+sqsize+1,
  135.       sbrect.bottom-1);
  136.   DrawArrowButton(mydc, myrect, isdown, TRUE);
  137. }
  138.  
  139. //----------------------------------------------------------------------------
  140. void THScroll::DrawRightArrow(TDC &mydc, BOOL isdown)
  141. {
  142.   TRect myrect(sbrect.right-(sqsize+1), sbrect.top+1, sbrect.right-1,
  143.       sbrect.bottom-1);
  144.   DrawArrowButton(mydc, myrect, isdown, FALSE);
  145. }
  146.  
  147. //----------------------------------------------------------------------------
  148. void THScroll::DrawLeftTrack(TDC &mydc, BOOL isdown)
  149. {
  150.   if (isdown)
  151.     mydc.SelectObject(*shadowbrush);
  152.   else
  153.     mydc.SelectObject(*trackbrush);
  154.   FASTRECT(mydc, trackxoff, sbrect.top+barsize, thumbxoff-trackxoff, 
  155.       sbheight-2);
  156. }
  157.  
  158. //----------------------------------------------------------------------------
  159. void THScroll::DrawRightTrack(TDC &mydc, BOOL isdown)
  160. {
  161.   int xoff = thumbxoff+sqsize+2;
  162.   int lastx = trackxoff + trackwidth - 1;
  163.  
  164.   if (isdown)
  165.     mydc.SelectObject(*shadowbrush);
  166.   else
  167.     mydc.SelectObject(*trackbrush);
  168.  
  169.   FASTRECT(mydc, xoff, sbrect.top+1, lastx-xoff+1, sbheight-2);
  170. }
  171. //----------------------------------------------------------------------------
  172. void THScroll::DrawThumb(TDC &mydc, BOOL drawfocus, BOOL erasefocus)
  173. {
  174.   if ((erasefocus) && (lastfocusxoff >= 0)){
  175.     mydc.DrawFocusRect(lastfocusxoff, sbrect.top, lastfocusxoff+sqsize+2, 
  176.         sbrect.top+sbheight);
  177.   }
  178.  
  179.   if (drawfocus){
  180.     mydc.DrawFocusRect(thumbxoff, sbrect.top, thumbxoff+sqsize+2, 
  181.         sbrect.top+sbheight);
  182.     lastfocusxoff = thumbxoff;
  183.     return;
  184.   }
  185.  
  186.   // draw thumb track (but don't cover two outside black lines)
  187.   mydc.SelectObject(*trackbrush);
  188.   FASTRECT(mydc, trackxoff+1, sbrect.top+1, trackwidth-2, sbheight-2);
  189.  
  190.   // draw black lines on each side of solid thumb
  191.   mydc.SelectObject(*framebrush);
  192.   FASTVLINE(mydc, thumbxoff, sbrect.top, sbheight);
  193.   FASTVLINE(mydc, thumbxoff+sqsize+1, sbrect.top, sbheight);
  194.  
  195.   // draw solid thumb
  196.   mydc.SelectObject(*facebrush);
  197.   FASTRECT(mydc, thumbxoff+1, sbrect.top+1, sqsize, sqsize);
  198.  
  199.   // draw shaded frame and extra "_|" design for solid thumb
  200.   TRect myrect(thumbxoff+1, sbrect.top+1, thumbxoff+sqsize+1, 
  201.     sbrect.bottom-1);
  202.  
  203.   DrawShadeFrame(mydc, myrect, TRUE);
  204.  
  205.   lastfocusxoff = -1;
  206. }
  207.  
  208. //----------------------------------------------------------------------------
  209. void THScroll::DrawDownFrame(TDC &mydc, TRect &myrect)
  210. {
  211.   // always a single width shadow line
  212.   mydc.SelectObject(*shadowbrush);
  213.   FASTHLINE(mydc, myrect.left, myrect.top, myrect.right-myrect.left);
  214.   FASTVLINE(mydc, myrect.left, myrect.top, myrect.bottom-myrect.top);
  215. }
  216. //----------------------------------------------------------------------------
  217. void THScroll::DrawShadeFrame(TDC &mydc, TRect &myrect, BOOL forthumb)
  218. {
  219.   int width = myrect.right - myrect.left;
  220.   int height = myrect.bottom - myrect.top;
  221.  
  222.   mydc.SelectObject(*hilitebrush);
  223.   FASTHLINE(mydc, myrect.left, myrect.top, width);
  224.   FASTVLINE(mydc, myrect.left, myrect.top, height);
  225.   if (sqsize > 15) {        // double highlight
  226.     FASTHLINE(mydc, myrect.left, myrect.top+1, width);
  227.     FASTVLINE(mydc, myrect.left+1, myrect.top, height);
  228.   }
  229.  
  230.   mydc.SelectObject(*shadowbrush);
  231.   FASTHLINE(mydc, myrect.left, myrect.bottom-1, width);
  232.   FASTVLINE(mydc, myrect.right-1, myrect.top, height);
  233.   if ((forthumb) || (sqsize >= 15)) {        // double shadow 
  234.     FASTHLINE(mydc, myrect.left+1, myrect.bottom-2, width-1);
  235.     FASTVLINE(mydc, myrect.right-2, myrect.top+1, height-1);
  236.   }
  237. }
  238. //---------------------------------------------------------------------------
  239. void THScroll::DrawArrowButton(TDC &mydc, TRect brect, BOOL isdown, BOOL left)
  240. {
  241.   int xoff, yoff, width, height, downoff, aheight, awidth;
  242.   int lheight, lwidth, mywidth, delta;
  243.  
  244.   // draw button background 
  245.   mydc.FillRect(brect, *facebrush);
  246.  
  247.   // draw frame around button
  248.   if (isdown)
  249.     DrawDownFrame(mydc, brect);
  250.   else
  251.     DrawShadeFrame(mydc, brect, FALSE);
  252.  
  253.   // calculations for drawing arrow line and head
  254.   width = brect.right - brect.left;
  255.   height = brect.bottom - brect.top;
  256.  
  257.   if (isdown)
  258.     downoff = 1;
  259.   else
  260.     downoff = 0;
  261.  
  262.   mydc.SelectObject(*framebrush);    // for drawing arrows
  263.  
  264.   aheight = 2 + (height+1)/3;
  265.   if (! (aheight%2))        // need an odd numbered arrow height
  266.     aheight--;
  267.  
  268.   awidth = (aheight+1)/2;
  269.   if (arrowline)
  270.     lwidth = awidth-1;
  271.   else
  272.     lwidth = 0;
  273.  
  274.   mywidth = awidth + lwidth;
  275.   delta = width - mywidth;
  276.   xoff = brect.left + delta/2;    // where whole object should start
  277.   if (delta%2)    // odd number - put extra space on left
  278.     xoff++;
  279.  
  280.   if (arrowline) {        // draw arrow line
  281.     if (left)
  282.         xoff += awidth;        // xoff is now where line starts
  283.     lheight = (aheight+2)/3;
  284.     yoff = brect.top + (height/2 - lheight/2);
  285.     FASTRECT(mydc, xoff+downoff, yoff+downoff, lwidth, lheight);
  286.     if (left)
  287.         xoff--;
  288.     else
  289.         xoff += lwidth;
  290.   }else if (left)
  291.     xoff += (awidth-1);
  292.  
  293.   // xoff is now where back line of arrow should be drawn
  294.   yoff = brect.top + (height/2 - aheight/2);
  295.  
  296.   // draw arrow head
  297.   while (aheight > 0) {
  298.     FASTVLINE(mydc, xoff+downoff, yoff+downoff, aheight);
  299.     aheight -= 2;
  300.     if (left)
  301.       xoff--;
  302.     else
  303.         xoff++;
  304.     yoff++;
  305.   }
  306. }
  307. //---------------------------------------------------------------------------
  308. void THScroll::MyPaint(int newstate)
  309. {
  310.   if ((! parent->HWindow) || (parent->IsIconic()) || (! showit))
  311.     return;
  312.  
  313.   BOOL forceall = (newstate == HSB_FORCEALL);
  314.  
  315.   if ((! forceall) && (newstate == displaystate) && 
  316.     (newstate <= HSB_RIGHTTHUMB))
  317.     return;            // already drawn
  318.  
  319.   BOOL doleft = (displaystate==HSB_LEFTARROW) || (newstate==HSB_LEFTARROW);
  320.   BOOL doright = (displaystate==HSB_RIGHTARROW) || (newstate==HSB_RIGHTARROW);
  321.   BOOL dothumb = (displaystate>=HSB_LEFTTHUMB) || (newstate>=HSB_LEFTTHUMB);
  322.  
  323.   if (newstate <= HSB_RIGHTTHUMB)
  324.     displaystate = newstate;
  325.  
  326.   TWindowDC mydc(*parent);
  327.  
  328.   if (forceall)
  329.     DrawFrames(mydc);
  330.  
  331.   if ((forceall) || (doleft))
  332.     DrawLeftArrow(mydc, (displaystate==HSB_LEFTARROW));
  333.   
  334.   if ((forceall) || (doright))
  335.     DrawRightArrow(mydc, (displaystate==HSB_RIGHTARROW));
  336.   
  337.   if ((forceall) || (dothumb)) {
  338.     DrawThumb(mydc, (displaystate==HSB_THUMBFOCUS), 
  339.         (displaystate==HSB_THUMBFOCUS));
  340.     if (displaystate == HSB_LEFTTHUMB)        // gray to left of thumb
  341.         DrawLeftTrack(mydc, TRUE);
  342.     else if (displaystate == HSB_RIGHTTHUMB)    // gray to right of thumb
  343.         DrawRightTrack(mydc, TRUE);
  344.   }
  345. }
  346. //----------------------------------------------------------------------------
  347. int THScroll::GetScrollPos()
  348. {
  349.   return(curval);
  350. }
  351. //----------------------------------------------------------------------------
  352. void THScroll::GetScrollRange(int &low, int &high)
  353. {
  354.   low = lowval;
  355.   high = highval;
  356. }
  357. //----------------------------------------------------------------------------
  358. int THScroll::SetScrollPos(int newval, int repaint)
  359. {
  360.   int oldval = curval;
  361.   curval = min(max(newval, lowval), highval);
  362.  
  363.   // reposition thumb to match new value
  364.   thumbxoff = (int)(trackxoff + ((LONG)trange*(curval-lowval))/vrange);
  365.  
  366.   if (repaint == SV_REPAINT)
  367.     MyPaint(HSB_THUMB);
  368.   else if (repaint == SV_THUMBTRACK)
  369.     MyPaint(thumbmove ? HSB_THUMB : HSB_THUMBFOCUS);
  370.  
  371.   return(oldval);
  372. }
  373. //----------------------------------------------------------------------------
  374. void THScroll::SetScrollRange(int Lowval, int Highval, BOOL redraw)
  375. {
  376.   lowval = Lowval;
  377.   highval = Highval;
  378.   if (highval <= lowval)
  379.     highval = lowval + 1;
  380.  
  381.   vrange = highval - lowval;
  382.  
  383.   if (redraw)
  384.     MyPaint(HSB_FORCEALL);
  385. }
  386. //----------------------------------------------------------------------------
  387. int THScroll::GetMouseLoc(TPoint &winpt)
  388. {
  389.   if ((parent->IsIconic()) || (! sbrect.Contains(winpt)) || (! showit)) 
  390.     return(HSB_NOTDOWN);
  391.  
  392.   int myx = winpt.x;
  393.   int left = sbrect.left;
  394.  
  395.   if (myx < left+sqsize+2)
  396.     return(HSB_LEFTARROW);
  397.   if (myx > (left+sqsize+2+trackwidth))
  398.     return(HSB_RIGHTARROW);
  399.   if (myx < thumbxoff)
  400.     return(HSB_LEFTTHUMB);
  401.   if (myx > thumbxoff+sqsize+2)
  402.     return(HSB_RIGHTTHUMB);
  403.   return(HSB_THUMB);
  404. }
  405. //----------------------------------------------------------------------------
  406. BOOL THScroll::MyLButtonDown(UINT /*hitTest*/, TPoint& winpt)
  407. {
  408.   mousedown = GetMouseLoc(winpt);
  409.   if (mousedown == HSB_NOTDOWN)    // mousedown not in scrollbar
  410.     return(FALSE);
  411.  
  412.   origval = curval;
  413.   newloc = mousedown;
  414.  
  415.   switch (mousedown) {
  416.     case HSB_LEFTARROW:
  417.     case HSB_RIGHTARROW:
  418.         MyPaint(mousedown);
  419.         break;
  420.  
  421.     case HSB_LEFTTHUMB:
  422.          MyPaint(mousedown);
  423.         parent->SendMessage(scrollmsg, SB_PAGELEFT, mylongid);
  424.         break;
  425.  
  426.     case HSB_RIGHTTHUMB:
  427.         MyPaint(mousedown);
  428.         parent->SendMessage(scrollmsg, SB_PAGERIGHT, mylongid);
  429.         break;
  430.  
  431.     case HSB_THUMB:
  432.         thumbgrabxoff = winpt.x - thumbxoff;
  433.         SetScrollPos(curval, SV_THUMBTRACK);
  434.   }
  435.  
  436.   AutoScrollMouse();
  437.  
  438.   return(TRUE);
  439. }
  440. //----------------------------------------------------------------------------
  441. BOOL THScroll::MyMouseMove(UINT /*hitTest*/, TPoint& winpt)
  442. {
  443.   if (mousedown == HSB_NOTDOWN)    // mousedown was not in our scrollbar
  444.     return(FALSE);
  445.  
  446.   newloc = GetMouseLoc(winpt);
  447.  
  448.   switch (mousedown) {
  449.     case HSB_LEFTARROW:
  450.     case HSB_RIGHTARROW:
  451.     case HSB_LEFTTHUMB:
  452.     case HSB_RIGHTTHUMB:
  453.       if (newloc == mousedown)
  454.           MyPaint(mousedown);
  455.         else
  456.           MyPaint(HSB_NOTDOWN);
  457.         break;
  458.  
  459.     case HSB_THUMB:
  460.         if (newloc != HSB_NOTDOWN){        // anywhere inside sb
  461.           int newpos = (winpt.x - thumbgrabxoff) - trackxoff;
  462.           if (newpos < 0)
  463.               newpos = 0;
  464.           else if (newpos > trange)
  465.               newpos = trange;
  466.           int newval = (int)(lowval + ((LONG)vrange*newpos)/trange);
  467.           SetScrollPos(newval, SV_THUMBTRACK);
  468.           parent->SendMessage(scrollmsg, SB_THUMBTRACK, 
  469.               mylongid | newval);
  470.         } else {
  471.           SetScrollPos(origval, SV_THUMBTRACK);
  472.           parent->SendMessage(scrollmsg, SB_THUMBTRACK, 
  473.               mylongid | origval);
  474.         }
  475.       break;
  476.   }
  477.   return(TRUE);
  478. }
  479. //----------------------------------------------------------------------------
  480. BOOL THScroll::MyLButtonUp(UINT /*hitTest*/, TPoint& winpt)
  481. {
  482.   int sendval;
  483.  
  484.   if (mousedown == HSB_NOTDOWN)    // mousedown was not in our scrollbar
  485.     return(FALSE);
  486.  
  487.   newloc = GetMouseLoc(winpt);
  488.  
  489.   switch (mousedown){
  490.     case HSB_LEFTARROW:
  491.         MyPaint(HSB_NOTDOWN);
  492.         if (newloc == mousedown)
  493.           parent->SendMessage(scrollmsg, SB_LINELEFT, mylongid);
  494.         break;
  495.  
  496.     case HSB_RIGHTARROW:
  497.       MyPaint(HSB_NOTDOWN);
  498.         if (newloc == mousedown)
  499.           parent->SendMessage(scrollmsg, SB_LINERIGHT, mylongid);
  500.         break;
  501.  
  502.     case HSB_THUMB:
  503.         sendval = curval;        // save off before overwritting
  504.         SetScrollPos(origval, SV_REPAINT);
  505.         parent->SendMessage(scrollmsg, SB_THUMBPOSITION, 
  506.           mylongid | sendval);
  507.         break;
  508.     
  509.     default:
  510.         MyPaint(HSB_NOTDOWN);
  511.         break;
  512.   }
  513.  
  514.   parent->SendMessage(scrollmsg, SB_ENDSCROLL, mylongid);
  515.   mousedown = HSB_NOTDOWN;
  516.   return(TRUE);
  517. }
  518. //----------------------------------------------------------------------------
  519. void THScroll::AutoScrollMouse()
  520. {
  521.   MSG  loopMsg;
  522.   DWORD delayticks;
  523.  
  524.   loopMsg.message = 0;
  525.   parent->SetCapture();
  526.   
  527.   delayticks = repeatdelay + GetTickCount();    
  528.  
  529.   while (loopMsg.message != WM_LBUTTONUP && 
  530.     (loopMsg.message != WM_MOUSEMOVE ||(loopMsg.wParam&MK_LBUTTON))) {
  531.     if (::PeekMessage(&loopMsg, 0, 0, 0, PM_REMOVE)) {
  532.       ::TranslateMessage(&loopMsg);
  533.       ::DispatchMessage(&loopMsg);
  534.     }
  535.   if (GetTickCount() > delayticks)
  536.       AutoScrollAction();
  537.   }
  538.  
  539.   parent->ReleaseCapture();
  540. }
  541. //----------------------------------------------------------------------------
  542. void THScroll::AutoScrollAction()
  543. {
  544.   if (newloc != mousedown)
  545.     return;
  546.  
  547.   switch (mousedown) {
  548.     case HSB_LEFTARROW:
  549.         parent->SendMessage(scrollmsg, SB_LINELEFT, mylongid);
  550.         break;
  551.  
  552.     case HSB_RIGHTARROW:
  553.         parent->SendMessage(scrollmsg, SB_LINERIGHT, mylongid);
  554.         break;
  555.  
  556.     case HSB_LEFTTHUMB:
  557.         parent->SendMessage(scrollmsg, SB_PAGELEFT, mylongid);
  558.         break;
  559.  
  560.     case HSB_RIGHTTHUMB:
  561.         parent->SendMessage(scrollmsg, SB_PAGERIGHT, mylongid);
  562.         break;
  563.   }
  564. }
  565. //----------------------------------------------------------------------------
  566.