home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c083 / 11.ddi / OWLSRC.PAK / SLIDER.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  9.5 KB  |  444 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1993 by Borland International
  3. //   source\owl\slider.cpp
  4. //----------------------------------------------------------------------------
  5. #pragma hdrignore SECTION
  6. #include <owl\owlpch.h>
  7. #include <owl\slider.h>
  8. #include <owl\dc.h>
  9.  
  10. #if !defined(SECTION) || SECTION == 1
  11.  
  12. DEFINE_RESPONSE_TABLE1(TSlider, TScrollBar)
  13.   EV_WM_SIZE,
  14.   EV_WM_GETDLGCODE,
  15.   EV_WM_ERASEBKGND,
  16.   EV_WM_PAINT,
  17.   EV_WM_LBUTTONDOWN,
  18.   EV_WM_MOUSEMOVE,
  19.   EV_WM_LBUTTONUP,
  20.   EV_WM_LBUTTONDBLCLK,
  21.   EV_WM_KEYDOWN,
  22.   EV_WM_SETFOCUS,
  23.   EV_WM_KILLFOCUS,
  24. END_RESPONSE_TABLE;
  25.  
  26. TSize  TSlider::MouseOffset;
  27. TDC*   TSlider::SlideDC = 0;
  28.  
  29. //
  30. // Constructor for a TSlider object
  31. //
  32. TSlider::TSlider(TWindow*        parent,
  33.                  int             id,
  34.                  int x, int y, int w, int h,
  35.                  TResId          thumbResId,
  36.                  TModule*        module)
  37.   : TScrollBar(parent, id, x, y, w, h, TRUE, module),
  38.     ThumbResId(thumbResId),
  39.     ThumbRect(0, 0, 9, 20),
  40.     CaretRect(3, 3, 3+3, 3+13)
  41. {
  42.   SetRange(0, 100);
  43.   Pos = 0;
  44.   ThumbRgn = 0;
  45.   TicGap = Range/10;
  46.   SlotThick = 17;
  47.   Snap = TRUE;
  48.  
  49.   Sliding = FALSE;
  50.   
  51.   // get slot size from Attr.H set by TScrollBar ?
  52.  
  53.   Attr.W = w;
  54.   Attr.H = h;
  55. }
  56.  
  57. //
  58. //
  59. //
  60. TSlider::~TSlider()
  61. {
  62.   delete ThumbRgn;
  63. }
  64.  
  65. //
  66. // Setup slider window
  67. //
  68. void
  69. TSlider::SetupWindow()
  70. {
  71.   TScrollBar::SetupWindow();
  72.   SetupThumbRgn();
  73. }
  74.  
  75. //
  76. // Check & set the slider range
  77. //
  78. void
  79. TSlider::SetRange(int min, int max) 
  80. {
  81.   Min = min;
  82.   Max = max;
  83.   if (Max > Min)
  84.     Range = Max - Min;
  85.   else if (Min > Max)
  86.     Range = Min - Max;
  87.   else
  88.     Range = 1;
  89. }
  90.  
  91. //
  92. // Set the position of the thumb
  93. //
  94. void
  95. TSlider::SetPosition(int pos)
  96. {
  97.   //
  98.   // constrain pos to be in the range "Min .. Max" & snap to tics if enabled
  99.   //
  100.   pos = SnapPos(pos);
  101.  
  102.   //
  103.   // Slide thumb to new position, converting pos to pixels
  104.   //
  105.   if (pos != Pos) {
  106.     if (HWindow) {
  107.       TDC* dc = SlideDC ? SlideDC : new TClientDC(HWindow);
  108.       SlideThumb(*dc, pos);
  109.       if (!SlideDC)
  110.         delete dc;
  111.     }
  112.     Pos = pos;
  113.   }
  114. }
  115.  
  116. //
  117. // setup region that defines the thumb shape for this slider class.
  118. // default region is a simple bounding rect, but could be any shape.
  119. //
  120. void
  121. TSlider::SetupThumbRgn()
  122. {
  123.   if (!ThumbRgn)
  124.     ThumbRgn = new TRegion(ThumbRect);
  125. }
  126.  
  127. //
  128. // Slide the thumb & perform necessary blitting & painting.
  129. // Assumes that Pos, Min & Max are up to date.
  130. //
  131. void
  132. TSlider::SlideThumb(TDC& dc, int pos)
  133. {
  134.   TPoint point = PosToPoint(pos);
  135.  
  136.   HideCaret();
  137.   GetBkColor(dc);
  138.   if (ThumbRgn) {
  139.     TRegion  oldRgn(ThumbRect);
  140.     TRect    newThumbRect(point, ThumbRect.Size());
  141.  
  142.     *ThumbRgn += point-ThumbRect.TopLeft();
  143.   
  144.     dc.SelectClipRgn(*ThumbRgn);
  145.     dc.BitBlt(newThumbRect, dc, ThumbRect.TopLeft());
  146.  
  147.     ThumbRect = newThumbRect;
  148.  
  149.     oldRgn -= *ThumbRgn;
  150.     dc.SelectClipRgn(oldRgn);
  151.     PaintSlot(dc);
  152.  
  153.   } else {
  154.     ThumbRect = TRect(point, ThumbRect.Size());
  155.     PaintSlot(dc);
  156.     PaintThumb(dc);
  157.   }
  158.   SetCaretPos(ThumbRect.left+CaretRect.left, ThumbRect.top+CaretRect.top);
  159.   ShowCaret();
  160. }
  161.  
  162. //
  163. // Paint the thumb itself using a resource DIB translated to the current system
  164. // button colors. Overlaps the slot.
  165. //
  166. void
  167. TSlider::PaintThumb(TDC& dc)
  168. {
  169.   TDib  thumbDib(*GetModule(), ThumbResId);
  170.   thumbDib.MapUIColors(
  171.     TDib::MapFace|TDib::MapText|TDib::MapShadow|TDib::MapHighlight,
  172.     &dc.GetBkColor()
  173.   );
  174.   int  dibX = (Sliding || !IsWindowEnabled()) ? thumbDib.Width()/2 : 0;
  175.   dc.SetDIBitsToDevice(ThumbRect, TPoint(dibX, 0), thumbDib);
  176. }
  177.  
  178. //
  179. // Constrain pos to be in the range "Min .. Max" &
  180. // perform 'Snap'ing if enabled by rounding pos to nearest TicGap
  181. //
  182. int
  183. TSlider::SnapPos(int pos)
  184. {
  185.   if (pos > Max)
  186.     pos = Max;
  187.  
  188.   else if (pos < Min)
  189.     pos = Min;
  190.  
  191.   return Snap ? (((pos-Min)+TicGap/2)/TicGap)*TicGap + Min : pos;
  192. }
  193.  
  194. //
  195. // Get & release a brush obtained from our parent window for use in painting 
  196. // background areas in this control.
  197. //
  198. void
  199. TSlider::GetBkColor(TDC& dc)
  200. {
  201.   Parent->HandleMessage(WM_CTLCOLOR, 
  202.                         (WPARAM)(HDC)dc,
  203.                         MAKELPARAM(HWindow, CTLCOLOR_STATIC));
  204.   BkColor = dc.GetBkColor();
  205. }
  206.  
  207. //
  208. // 
  209. //
  210. void
  211. TSlider::EvSize(UINT sizeType, TSize& size)
  212. {
  213.   TScrollBar::EvSize(sizeType, size);
  214. }
  215.  
  216. //
  217. // Make sure we get cursor movement keys to move the thumb
  218. //
  219. UINT
  220. TSlider::EvGetDlgCode(MSG far*)
  221. {
  222.   return DLGC_WANTARROWS;
  223. }
  224.  
  225. //
  226. // Paint the whole slider: ruler, slot & thumb
  227. //
  228. void
  229. TSlider::EvPaint()
  230. {
  231.   HideCaret();
  232.   if (ThumbRgn) {                   // use thumb region if avalable
  233.     TRegion updateRgn;
  234.     GetUpdateRgn(updateRgn);
  235.  
  236.     TPaintDC  dc(*this);
  237.  
  238.     GetBkColor(dc);
  239.  
  240.     TRegion thumbClip = *ThumbRgn;  // set clip to intersect of update & thumb
  241.     thumbClip &= updateRgn;
  242.     dc.SelectClipRgn(thumbClip);
  243.     PaintThumb(dc);
  244.  
  245.     updateRgn -= thumbClip;
  246.     dc.SelectClipRgn(updateRgn);    // set clip to update minus thumb
  247.     ValidateRgn(*ThumbRgn);
  248.     PaintSlot(dc);
  249.     PaintRuler(dc);
  250.  
  251.   } else {                          // no region, thumb will flicker a little
  252.     TPaintDC  dc(*this);
  253.  
  254.     GetBkColor(dc);
  255.     PaintSlot(dc);
  256.     PaintRuler(dc);
  257.     PaintThumb(dc);
  258.   }
  259.   ShowCaret();
  260. }
  261.  
  262. //
  263. // We'll always erase as we paint to avoid flicker
  264. //
  265. BOOL
  266. TSlider::EvEraseBkgnd(HDC)
  267. {
  268.   return TRUE;
  269. }
  270.  
  271. //
  272. // If a button down on the thumb, then enter sliding state.
  273. // If in the slot, pg up or down. If on the ruler, jump there.
  274. //
  275. void
  276. TSlider::EvLButtonDown(UINT /*modKeys*/, TPoint& point)
  277. {
  278.   if (GetFocus() != HWindow)
  279.     SetFocus();
  280.  
  281.   int scrollCode = HitTest(point);
  282.   switch (scrollCode) {
  283.     case SB_THUMBPOSITION:
  284.       NotifyParent(scrollCode, SnapPos(PointToPos(point)));
  285.       break;
  286.       
  287.     case SB_LINEUP:
  288.     case SB_LINEDOWN:
  289.     case SB_PAGEUP:
  290.     case SB_PAGEDOWN:
  291.       NotifyParent(scrollCode);
  292.       break;
  293.  
  294.     case SB_THUMBTRACK: {
  295.       Sliding = TRUE;
  296.       SetCapture();
  297.       HideCaret();
  298.       SlideDC = new TClientDC(HWindow);  // keep this dc around while sliding
  299.  
  300.       GetBkColor(*SlideDC);  // repaint thumb in pressed state
  301.       PaintThumb(*SlideDC);
  302.  
  303.       MouseOffset = point-ThumbRect.TopLeft();
  304.       point -= MouseOffset;
  305.       int pos = SnapPos(PointToPos(point));// keep thumb on track & on pos units
  306.       NotifyParent(9, pos);     // undocumented 'begin track' code
  307.       NotifyParent(SB_THUMBTRACK, pos);
  308.     }
  309.   }
  310. }
  311.  
  312. //
  313. // If sliding then either slide thumb, or detect a lost button up & simulate
  314. // it.
  315. //
  316. void
  317. TSlider::EvMouseMove(UINT modKeys, TPoint& point)
  318. {
  319.   if (Sliding && SlideDC) {
  320.     if (!(modKeys&MK_LBUTTON)) {
  321.       EvLButtonUp(modKeys, point);    // we missed a lbutton up somehow...
  322.       return;
  323.     }
  324.     // keep thumb on track & on pos units
  325.     NotifyParent(SB_THUMBTRACK, SnapPos(PointToPos(point - MouseOffset)));
  326.   }
  327. }
  328.  
  329. //
  330. // Handle button messages if we are sliding by releasing capture & ending
  331. // sliding state
  332. //
  333. void
  334. TSlider::EvLButtonUp(UINT /*modKeys*/, TPoint& point)
  335. {
  336.   int pos = SnapPos(PointToPos(point - MouseOffset));
  337.   if (Sliding) {
  338.     Sliding = FALSE;
  339.     NotifyParent(SB_THUMBPOSITION, pos);
  340.  
  341.     GetBkColor(*SlideDC);   // repaint thumb in released state
  342.     if (ThumbRgn)
  343.       SlideDC->SelectClipRgn(*ThumbRgn);
  344.     PaintThumb(*SlideDC);
  345.  
  346.     ReleaseCapture();
  347.     delete SlideDC;
  348.     SlideDC = 0;
  349.  
  350.     ShowCaret();
  351.   }
  352.   NotifyParent(SB_ENDSCROLL, pos);
  353. }
  354.  
  355. //
  356. // Catch double clicks and eat them
  357. //
  358. void
  359. TSlider::EvLButtonDblClk(UINT /*modKeys*/, TPoint&)
  360. {
  361. }
  362.  
  363. //
  364. // Translate key messages to scroll events w/ repeat.
  365. //
  366. void
  367. TSlider::EvKeyDown(UINT key, UINT repeatCount, UINT /*flags*/)
  368. {
  369.   static int KeyToCode[] = {
  370.     SB_PAGEUP,    // VK_PRIOR
  371.     SB_PAGEDOWN,  // VK_NEXT 
  372.     SB_BOTTOM,    // VK_END
  373.     SB_TOP,       // VK_HOME
  374.     SB_LINEUP,    // VK_LEFT(same as SB_LINELEFT)
  375.     SB_LINEUP,    // VK_UP
  376.     SB_LINEDOWN,  // VK_RIGHT(same as SB_LINERIGHT)
  377.     SB_LINEDOWN   // VK_DOWN
  378.   };
  379.  
  380.   if (key >= VK_PRIOR && key <= VK_DOWN) {
  381.     for (int i = 0; i < repeatCount; i++)
  382.       NotifyParent(KeyToCode[key-VK_PRIOR], Pos);
  383.     NotifyParent(SB_ENDSCROLL, Pos);
  384.   }
  385. }
  386.  
  387. //
  388. // Create, position & show a caret when we have focus. Remove it when we lose
  389. // focus
  390. //
  391. void
  392. TSlider::EvSetFocus(HWND /*hWndLostFocus*/)
  393. {
  394.   CreateCaret(TRUE, CaretRect.Width(), CaretRect.Height());
  395.   SetCaretPos(ThumbRect.left+CaretRect.left, ThumbRect.top+CaretRect.top);
  396.   ShowCaret();
  397. }
  398.  
  399. void
  400. TSlider::EvKillFocus(HWND /*hWndGetFocus*/)
  401. {
  402.   HideCaret();
  403.   DestroyCaret();
  404. }
  405.  
  406. #endif
  407. #if !defined(SECTION) || SECTION == 2
  408.  
  409. IMPLEMENT_ABSTRACT_STREAMABLE1(TSlider, TScrollBar);
  410.  
  411. void*
  412. TSlider::Streamer::Read(ipstream& is, uint32 /* version */) const
  413. {
  414.   TSlider* o = GetObject();
  415.   ReadBaseObject((TScrollBar*)o, is);
  416.   is >> o->Min
  417.      >> o->Max
  418.      >> o->Pos
  419.      >> o->ThumbResId
  420.      >> o->ThumbRect
  421.      >> o->TicGap
  422.      >> o->CaretRect
  423.      >> o->Snap;
  424.   o->SetRange(o->Min, o->Max);  // let it calculate Range
  425.   return o;
  426. }
  427.  
  428. void
  429. TSlider::Streamer::Write(opstream& os) const
  430. {
  431.   TSlider* o = GetObject();
  432.   WriteBaseObject((TScrollBar*)o, os);
  433.   os << o->Min
  434.      << o->Max
  435.      << o->Pos
  436.      << o->ThumbResId
  437.      << o->ThumbRect
  438.      << o->CaretRect
  439.      << o->TicGap
  440.      << o->Snap;
  441. }
  442.  
  443. #endif
  444.