home *** CD-ROM | disk | FTP | other *** search
- //----------------------------------------------------------------------------
- // ObjectWindows - (C) Copyright 1993 by Borland International
- // source\owl\slider.cpp
- //----------------------------------------------------------------------------
- #pragma hdrignore SECTION
- #include <owl\owlpch.h>
- #include <owl\slider.h>
- #include <owl\dc.h>
-
- #if !defined(SECTION) || SECTION == 1
-
- DEFINE_RESPONSE_TABLE1(TSlider, TScrollBar)
- EV_WM_SIZE,
- EV_WM_GETDLGCODE,
- EV_WM_ERASEBKGND,
- EV_WM_PAINT,
- EV_WM_LBUTTONDOWN,
- EV_WM_MOUSEMOVE,
- EV_WM_LBUTTONUP,
- EV_WM_LBUTTONDBLCLK,
- EV_WM_KEYDOWN,
- EV_WM_SETFOCUS,
- EV_WM_KILLFOCUS,
- END_RESPONSE_TABLE;
-
- TSize TSlider::MouseOffset;
- TDC* TSlider::SlideDC = 0;
-
- //
- // Constructor for a TSlider object
- //
- TSlider::TSlider(TWindow* parent,
- int id,
- int x, int y, int w, int h,
- TResId thumbResId,
- TModule* module)
- : TScrollBar(parent, id, x, y, w, h, TRUE, module),
- ThumbResId(thumbResId),
- ThumbRect(0, 0, 9, 20),
- CaretRect(3, 3, 3+3, 3+13)
- {
- SetRange(0, 100);
- Pos = 0;
- ThumbRgn = 0;
- TicGap = Range/10;
- SlotThick = 17;
- Snap = TRUE;
-
- Sliding = FALSE;
-
- // get slot size from Attr.H set by TScrollBar ?
-
- Attr.W = w;
- Attr.H = h;
- }
-
- //
- //
- //
- TSlider::~TSlider()
- {
- delete ThumbRgn;
- }
-
- //
- // Setup slider window
- //
- void
- TSlider::SetupWindow()
- {
- TScrollBar::SetupWindow();
- SetupThumbRgn();
- }
-
- //
- // Check & set the slider range
- //
- void
- TSlider::SetRange(int min, int max)
- {
- Min = min;
- Max = max;
- if (Max > Min)
- Range = Max - Min;
- else if (Min > Max)
- Range = Min - Max;
- else
- Range = 1;
- }
-
- //
- // Set the position of the thumb
- //
- void
- TSlider::SetPosition(int pos)
- {
- //
- // constrain pos to be in the range "Min .. Max" & snap to tics if enabled
- //
- pos = SnapPos(pos);
-
- //
- // Slide thumb to new position, converting pos to pixels
- //
- if (pos != Pos) {
- if (HWindow) {
- TDC* dc = SlideDC ? SlideDC : new TClientDC(HWindow);
- SlideThumb(*dc, pos);
- if (!SlideDC)
- delete dc;
- }
- Pos = pos;
- }
- }
-
- //
- // setup region that defines the thumb shape for this slider class.
- // default region is a simple bounding rect, but could be any shape.
- //
- void
- TSlider::SetupThumbRgn()
- {
- if (!ThumbRgn)
- ThumbRgn = new TRegion(ThumbRect);
- }
-
- //
- // Slide the thumb & perform necessary blitting & painting.
- // Assumes that Pos, Min & Max are up to date.
- //
- void
- TSlider::SlideThumb(TDC& dc, int pos)
- {
- TPoint point = PosToPoint(pos);
-
- HideCaret();
- GetBkColor(dc);
- if (ThumbRgn) {
- TRegion oldRgn(ThumbRect);
- TRect newThumbRect(point, ThumbRect.Size());
-
- *ThumbRgn += point-ThumbRect.TopLeft();
-
- dc.SelectClipRgn(*ThumbRgn);
- dc.BitBlt(newThumbRect, dc, ThumbRect.TopLeft());
-
- ThumbRect = newThumbRect;
-
- oldRgn -= *ThumbRgn;
- dc.SelectClipRgn(oldRgn);
- PaintSlot(dc);
-
- } else {
- ThumbRect = TRect(point, ThumbRect.Size());
- PaintSlot(dc);
- PaintThumb(dc);
- }
- SetCaretPos(ThumbRect.left+CaretRect.left, ThumbRect.top+CaretRect.top);
- ShowCaret();
- }
-
- //
- // Paint the thumb itself using a resource DIB translated to the current system
- // button colors. Overlaps the slot.
- //
- void
- TSlider::PaintThumb(TDC& dc)
- {
- TDib thumbDib(*GetModule(), ThumbResId);
- thumbDib.MapUIColors(
- TDib::MapFace|TDib::MapText|TDib::MapShadow|TDib::MapHighlight,
- &dc.GetBkColor()
- );
- int dibX = (Sliding || !IsWindowEnabled()) ? thumbDib.Width()/2 : 0;
- dc.SetDIBitsToDevice(ThumbRect, TPoint(dibX, 0), thumbDib);
- }
-
- //
- // Constrain pos to be in the range "Min .. Max" &
- // perform 'Snap'ing if enabled by rounding pos to nearest TicGap
- //
- int
- TSlider::SnapPos(int pos)
- {
- if (pos > Max)
- pos = Max;
-
- else if (pos < Min)
- pos = Min;
-
- return Snap ? (((pos-Min)+TicGap/2)/TicGap)*TicGap + Min : pos;
- }
-
- //
- // Get & release a brush obtained from our parent window for use in painting
- // background areas in this control.
- //
- void
- TSlider::GetBkColor(TDC& dc)
- {
- Parent->HandleMessage(WM_CTLCOLOR,
- (WPARAM)(HDC)dc,
- MAKELPARAM(HWindow, CTLCOLOR_STATIC));
- BkColor = dc.GetBkColor();
- }
-
- //
- //
- //
- void
- TSlider::EvSize(UINT sizeType, TSize& size)
- {
- TScrollBar::EvSize(sizeType, size);
- }
-
- //
- // Make sure we get cursor movement keys to move the thumb
- //
- UINT
- TSlider::EvGetDlgCode(MSG far*)
- {
- return DLGC_WANTARROWS;
- }
-
- //
- // Paint the whole slider: ruler, slot & thumb
- //
- void
- TSlider::EvPaint()
- {
- HideCaret();
- if (ThumbRgn) { // use thumb region if avalable
- TRegion updateRgn;
- GetUpdateRgn(updateRgn);
-
- TPaintDC dc(*this);
-
- GetBkColor(dc);
-
- TRegion thumbClip = *ThumbRgn; // set clip to intersect of update & thumb
- thumbClip &= updateRgn;
- dc.SelectClipRgn(thumbClip);
- PaintThumb(dc);
-
- updateRgn -= thumbClip;
- dc.SelectClipRgn(updateRgn); // set clip to update minus thumb
- ValidateRgn(*ThumbRgn);
- PaintSlot(dc);
- PaintRuler(dc);
-
- } else { // no region, thumb will flicker a little
- TPaintDC dc(*this);
-
- GetBkColor(dc);
- PaintSlot(dc);
- PaintRuler(dc);
- PaintThumb(dc);
- }
- ShowCaret();
- }
-
- //
- // We'll always erase as we paint to avoid flicker
- //
- BOOL
- TSlider::EvEraseBkgnd(HDC)
- {
- return TRUE;
- }
-
- //
- // If a button down on the thumb, then enter sliding state.
- // If in the slot, pg up or down. If on the ruler, jump there.
- //
- void
- TSlider::EvLButtonDown(UINT /*modKeys*/, TPoint& point)
- {
- if (GetFocus() != HWindow)
- SetFocus();
-
- int scrollCode = HitTest(point);
- switch (scrollCode) {
- case SB_THUMBPOSITION:
- NotifyParent(scrollCode, SnapPos(PointToPos(point)));
- break;
-
- case SB_LINEUP:
- case SB_LINEDOWN:
- case SB_PAGEUP:
- case SB_PAGEDOWN:
- NotifyParent(scrollCode);
- break;
-
- case SB_THUMBTRACK: {
- Sliding = TRUE;
- SetCapture();
- HideCaret();
- SlideDC = new TClientDC(HWindow); // keep this dc around while sliding
-
- GetBkColor(*SlideDC); // repaint thumb in pressed state
- PaintThumb(*SlideDC);
-
- MouseOffset = point-ThumbRect.TopLeft();
- point -= MouseOffset;
- int pos = SnapPos(PointToPos(point));// keep thumb on track & on pos units
- NotifyParent(9, pos); // undocumented 'begin track' code
- NotifyParent(SB_THUMBTRACK, pos);
- }
- }
- }
-
- //
- // If sliding then either slide thumb, or detect a lost button up & simulate
- // it.
- //
- void
- TSlider::EvMouseMove(UINT modKeys, TPoint& point)
- {
- if (Sliding && SlideDC) {
- if (!(modKeys&MK_LBUTTON)) {
- EvLButtonUp(modKeys, point); // we missed a lbutton up somehow...
- return;
- }
- // keep thumb on track & on pos units
- NotifyParent(SB_THUMBTRACK, SnapPos(PointToPos(point - MouseOffset)));
- }
- }
-
- //
- // Handle button messages if we are sliding by releasing capture & ending
- // sliding state
- //
- void
- TSlider::EvLButtonUp(UINT /*modKeys*/, TPoint& point)
- {
- int pos = SnapPos(PointToPos(point - MouseOffset));
- if (Sliding) {
- Sliding = FALSE;
- NotifyParent(SB_THUMBPOSITION, pos);
-
- GetBkColor(*SlideDC); // repaint thumb in released state
- if (ThumbRgn)
- SlideDC->SelectClipRgn(*ThumbRgn);
- PaintThumb(*SlideDC);
-
- ReleaseCapture();
- delete SlideDC;
- SlideDC = 0;
-
- ShowCaret();
- }
- NotifyParent(SB_ENDSCROLL, pos);
- }
-
- //
- // Catch double clicks and eat them
- //
- void
- TSlider::EvLButtonDblClk(UINT /*modKeys*/, TPoint&)
- {
- }
-
- //
- // Translate key messages to scroll events w/ repeat.
- //
- void
- TSlider::EvKeyDown(UINT key, UINT repeatCount, UINT /*flags*/)
- {
- static int KeyToCode[] = {
- SB_PAGEUP, // VK_PRIOR
- SB_PAGEDOWN, // VK_NEXT
- SB_BOTTOM, // VK_END
- SB_TOP, // VK_HOME
- SB_LINEUP, // VK_LEFT(same as SB_LINELEFT)
- SB_LINEUP, // VK_UP
- SB_LINEDOWN, // VK_RIGHT(same as SB_LINERIGHT)
- SB_LINEDOWN // VK_DOWN
- };
-
- if (key >= VK_PRIOR && key <= VK_DOWN) {
- for (int i = 0; i < repeatCount; i++)
- NotifyParent(KeyToCode[key-VK_PRIOR], Pos);
- NotifyParent(SB_ENDSCROLL, Pos);
- }
- }
-
- //
- // Create, position & show a caret when we have focus. Remove it when we lose
- // focus
- //
- void
- TSlider::EvSetFocus(HWND /*hWndLostFocus*/)
- {
- CreateCaret(TRUE, CaretRect.Width(), CaretRect.Height());
- SetCaretPos(ThumbRect.left+CaretRect.left, ThumbRect.top+CaretRect.top);
- ShowCaret();
- }
-
- void
- TSlider::EvKillFocus(HWND /*hWndGetFocus*/)
- {
- HideCaret();
- DestroyCaret();
- }
-
- #endif
- #if !defined(SECTION) || SECTION == 2
-
- IMPLEMENT_ABSTRACT_STREAMABLE1(TSlider, TScrollBar);
-
- void*
- TSlider::Streamer::Read(ipstream& is, uint32 /* version */) const
- {
- TSlider* o = GetObject();
- ReadBaseObject((TScrollBar*)o, is);
- is >> o->Min
- >> o->Max
- >> o->Pos
- >> o->ThumbResId
- >> o->ThumbRect
- >> o->TicGap
- >> o->CaretRect
- >> o->Snap;
- o->SetRange(o->Min, o->Max); // let it calculate Range
- return o;
- }
-
- void
- TSlider::Streamer::Write(opstream& os) const
- {
- TSlider* o = GetObject();
- WriteBaseObject((TScrollBar*)o, os);
- os << o->Min
- << o->Max
- << o->Pos
- << o->ThumbResId
- << o->ThumbRect
- << o->CaretRect
- << o->TicGap
- << o->Snap;
- }
-
- #endif
-