Game Accessibility Library logo SourceForge.net Logo
Game Accessibility Suite: CATGUI/CATSlider.cpp Source File

CATSlider.cpp

Go to the documentation of this file.
00001 //---------------------------------------------------------------------------
00002 /// \file CATSlider.cpp
00003 /// \brief Slider control for GUI
00004 /// \ingroup CATGUI
00005 ///
00006 /// Copyright (c) 2003-2008 by Michael Ellison.
00007 /// See COPYING.txt for the \ref gaslicense License (MIT License).
00008 ///
00009 // $Author: mikeellison $
00010 // $Date: 2008-01-23 01:43:25 -0600 (Wed, 23 Jan 2008) $
00011 // $Revision:   $
00012 // $NoKeywords: $
00013 //
00014 //
00015 //---------------------------------------------------------------------------
00016 #include <math.h>
00017 
00018 #include "CATSlider.h"
00019 #include "CATWindow.h"
00020 #include "CATFilterEWMA.h"
00021 #include "CATCursor.h"
00022 #include "CATApp.h"
00023 #include "CATUtil.h"
00024 
00025 // base resolution of Slider
00026 const CATFloat32 kSLIDERSTEP = 0.001f;
00027 
00028 //---------------------------------------------------------------------------
00029 // CATSlider constructor (inherited from CATControl->CATXMLObject)
00030 // \param element - Type name ("Button")
00031 // \param attribs - attribute information for the window
00032 // \param parent - parent XML object (should be a "Window" element)
00033 // \param rootDir - root directory of skin
00034 //---------------------------------------------------------------------------
00035 CATSlider::CATSlider(      const CATString&             element, 
00036                      const CATString&             rootDir)
00037                      : CATControl(element,  rootDir)
00038 {   
00039     fSliderStyle        = CATSLIDER_VERTICAL;
00040     fValueType          = CATVALUE_LINEAR;
00041     // Defaults
00042     fLastTarget             = fValue;
00043     fImageSlide          = 0;
00044     fImageSlideDisabled  = 0;
00045     fImageSlideFocus     = 0;
00046     fImageOn             = 0;
00047     fSlideOffset         = 0;
00048     fCommandTrack        = false;
00049     fCursor.SetType(CATCURSOR_TOPBOTTOM);
00050 }
00051 
00052 //---------------------------------------------------------------------------
00053 /// CATSlider destructor
00054 //---------------------------------------------------------------------------
00055 CATSlider::~CATSlider()
00056 {
00057     if (fImageSlide)
00058     {
00059         CATImage::ReleaseImage(fImageSlide);
00060     }
00061     if (fImageSlideDisabled)
00062     {
00063         CATImage::ReleaseImage(fImageSlideDisabled);
00064     }
00065     if (fImageSlideFocus)
00066     {
00067         CATImage::ReleaseImage(fImageSlideFocus);
00068     }
00069 }
00070 
00071 void CATSlider::TrackMouseDown(const CATPOINT& point, CATMODKEY modKey)
00072 {   
00073     CATControl::TrackMouseDown(point,modKey);      
00074     TrackMouseMove(point,true, modKey);
00075 }
00076 
00077 void CATSlider::TrackMouseRelease(const CATPOINT& point, CATMODKEY modKey)
00078 {   
00079     this->fPressed = false;
00080     this->fActive = true;
00081     fLastTarget = fValue;
00082     this->MarkDirty();
00083     this->OnMouseClick();
00084 }
00085 
00086 void CATSlider::TrackMouseMove(const CATPOINT& point, bool left, CATMODKEY modKey)
00087 {   
00088     CATFloat32 newVal = fValue;
00089     if (left)
00090     {      
00091         switch (fSliderStyle)
00092         {
00093         case CATSLIDER_HORIZONTAL:
00094             {
00095                 newVal = ((CATFloat32)(point.x - fRect.left))/(CATFloat32)(fRect.Width() - fImageSlide->Width()) * GetValRange() + fMinValue;
00096             }
00097             break;
00098 
00099         case CATSLIDER_VERTICAL:
00100         default:
00101             {
00102                 newVal = ((CATFloat32)(fRect.Height() - fImageSlide->Height()) - 
00103                     (point.y - fRect.top)) / 
00104                     (CATFloat32)(fRect.Height() - fImageSlide->Height()) * GetValRange() + fMinValue;
00105             }
00106             break;
00107         }
00108 
00109         if (modKey & CATMODKEY_SHIFT)
00110         {
00111             fLastTarget = newVal;
00112             if (newVal < fValue)
00113             {
00114                 fValue -= GetValRange() / 1000.0f;
00115             }
00116             else
00117             {
00118                 fValue += GetValRange() / 1000.0f;              
00119             }
00120         }
00121         else
00122         {
00123             fValue = newVal;
00124             fLastTarget = fValue;
00125         }
00126 
00127         this->BoundsCheckValue();      
00128 
00129         // fLastPoint = point;
00130 
00131         this->MarkDirty();
00132         if (this->fCommandTrack)
00133         {
00134             this->OnMouseClick();
00135             // Maintain pressed state...
00136             fPressed = true;
00137         }
00138     }
00139 }
00140 
00141 void CATSlider::TrackMouseTimer(CATMODKEY modKey)
00142 {
00143     if ((modKey & CATMODKEY_SHIFT) && (fLastTarget != fValue))
00144     {
00145         if (fLastTarget < fValue)
00146         {
00147             fValue -= GetValRange() / 1000.0f;
00148         }
00149         else
00150         {
00151             fValue += GetValRange() / 1000.0f;
00152         }
00153         this->BoundsCheckValue();
00154 
00155         this->MarkDirty();
00156 
00157         if (this->fCommandTrack)
00158         {
00159             this->OnMouseClick();           
00160             // Maintain pressed state...
00161             fPressed = true;
00162         }
00163     }
00164 }
00165 
00166 
00167 
00168 void CATSlider::OnMouseWheel(    const CATPOINT& point,
00169                              CATFloat32        wheelMove,
00170                              CATMODKEY          modKey)
00171 {
00172 
00173     CATFloat32 keyStep = (modKey & CATMODKEY_SHIFT)?10.0f:100.0f;
00174     CATFloat32 delta = (wheelMove * kSLIDERSTEP * GetValRange()) * keyStep;
00175     this->fValue += delta;
00176     fLastTarget = fValue;
00177 
00178     this->BoundsCheckValue();
00179 
00180     this->MarkDirty();      
00181     this->OnMouseClick();
00182 }
00183 //---------------------------------------------------------------------------
00184 void CATSlider::OnKeyPress(const CATKeystroke& keystroke)
00185 {
00186     CATControl::OnKeyPress(keystroke);
00187 }
00188 
00189 void CATSlider::OnKeyDown(const CATKeystroke& keystroke)
00190 {   
00191     if (keystroke.IsSpecial())
00192     {
00193         CATFloat32 delta = 0;
00194 
00195         switch (keystroke.GetSpecialKey())
00196         {
00197         case CATKEY_LEFT:
00198             delta = -kSLIDERSTEP * GetValRange();
00199             break;      
00200         case CATKEY_RIGHT:
00201             delta = kSLIDERSTEP * GetValRange();
00202             break;
00203         case CATKEY_UP:
00204             delta = kSLIDERSTEP * 10 * GetValRange();
00205             break;
00206         case CATKEY_DOWN:
00207             delta = -kSLIDERSTEP * 10 * GetValRange();
00208             break;
00209         case CATKEY_NEXT:
00210             delta = -kSLIDERSTEP * 100 * GetValRange();
00211             break;
00212         case CATKEY_PRIOR:
00213             delta = kSLIDERSTEP * 100 * GetValRange();
00214             break;
00215 
00216         case CATKEY_HOME:
00217             fValue = fMinValue;
00218             fLastTarget = fValue;
00219             this->MarkDirty();
00220             this->OnMouseClick();
00221             return;
00222             break;
00223 
00224         case CATKEY_END:
00225             fValue = fMaxValue;
00226             fLastTarget = fValue;
00227             this->MarkDirty();
00228             this->OnMouseClick();
00229             return;
00230             break;
00231         }      
00232 
00233         if (delta != 0)
00234         {
00235             fValue += delta;
00236             fLastTarget = fValue;
00237 
00238             this->BoundsCheckValue();
00239 
00240             this->MarkDirty();      
00241             this->OnMouseClick();
00242         }
00243     }
00244 
00245     // Allow default handling on stuff we don't do.
00246     CATControl::OnKeyDown(keystroke);
00247 }
00248 
00249 
00250 //---------------------------------------------------------------------------
00251 // Draw() draws the control into the parent window
00252 // \param dirtyRect - portion of control (in window coordinates)
00253 //        that requires redrawing.
00254 //---------------------------------------------------------------------------
00255 void CATSlider::Draw(CATImage* image, const CATRect& dirtyRect)
00256 {
00257     if (this->IsVisible() == false)
00258     {
00259         return;
00260     }
00261 
00262     // Draw background for slider
00263     CATControl::Draw(image,dirtyRect);
00264 
00265 
00266     // Draw "On" image if applicable
00267     if (fImageOn && this->IsEnabled())
00268     {
00269         CATRect onRect = fRect;
00270 
00271         if (this->fSliderStyle == CATSLIDER_HORIZONTAL)
00272         {
00273             CATInt32 width = CATMin(onRect.Width(), fImageOn->Width());
00274             if (width > fSlideOffset)
00275             {
00276                 width -= fSlideOffset;
00277             }
00278 
00279             onRect.right = (CATInt32)(onRect.left + width*this->GetValPercent());                                
00280 
00281         }
00282         else
00283         {
00284             CATInt32 height = fImageOn->Height();
00285             CATInt32 onHeight = height;
00286 
00287             if (height > fSlideOffset)
00288             {
00289                 onHeight -= fSlideOffset;
00290             }
00291 
00292             onRect.top += (CATInt32)(height - (onHeight * this->GetValPercent()));
00293         }  
00294 
00295         CATRect layerRect;
00296         if (onRect.Intersect(dirtyRect, &layerRect))
00297         {  
00298             image->Overlay(   this->fImageOn,
00299                 layerRect.left,
00300                 layerRect.top,
00301                 layerRect.left - fRect.left,
00302                 layerRect.top - fRect.top,
00303                 layerRect.Width(),
00304                 layerRect.Height());
00305         }
00306     }
00307     // Now draw slider knob
00308     CATInt32 xPos, yPos;
00309     xPos = 0;
00310     yPos = 0;
00311 
00312     switch (fSliderStyle)
00313     {
00314     case CATSLIDER_HORIZONTAL:
00315         {
00316             xPos = (CATInt32)(GetValPercent() * (fRect.Width() - this->fImageSlide->Width())) + fRect.left;
00317             yPos = fRect.top;
00318         }
00319         break;
00320 
00321     case CATSLIDER_VERTICAL:
00322     default:
00323         {
00324             xPos = fRect.left;
00325             yPos = (fRect.bottom - fImageSlide->Height()) - (CATInt32)(GetValPercent() * (fRect.Height() - this->fImageSlide->Height()));
00326         }
00327         break;
00328     }
00329 
00330     CATRect slideRect(xPos,yPos, this->fImageSlide->Width() + xPos, this->fImageSlide->Height() + yPos);
00331     CATRect drawRect;
00332     bool drawn = false;
00333     if (slideRect.Intersect(dirtyRect,&drawRect))
00334     {
00335         if ( (this->IsEnabled() == false) && (this->fImageSlideDisabled))
00336         {
00337             image->Overlay(   this->fImageSlideDisabled,
00338                 drawRect.left, 
00339                 drawRect.top, 
00340                 drawRect.left - xPos,
00341                 drawRect.top - yPos,
00342                 drawRect.Width(),
00343                 drawRect.Height());
00344             drawn = true;
00345         }
00346         else 
00347         {         
00348             if ((!drawn) && (IsFocused() || IsActive() || IsPressed()) && (this->fImageSlideFocus))
00349             {
00350                 image->Overlay(   this->fImageSlideFocus,
00351                     drawRect.left, 
00352                     drawRect.top, 
00353                     drawRect.left - xPos,
00354                     drawRect.top - yPos,
00355                     drawRect.Width(),
00356                     drawRect.Height());
00357                 drawn = true;
00358             }
00359         }
00360 
00361         if ((!drawn) && (this->fImageSlide != 0))
00362         {
00363             image->Overlay(   this->fImageSlide,
00364                 drawRect.left, 
00365                 drawRect.top, 
00366                 drawRect.left - xPos,
00367                 drawRect.top - yPos,
00368                 drawRect.Width(),
00369                 drawRect.Height());
00370             drawn = true;
00371         }
00372 
00373         if (!drawn)
00374         {
00375             CATTRACE("4");
00376 
00377             // Right now, just make a big red rectangle where we should go.
00378             image->FillRect(drawRect, fBackgroundColor);
00379         }      
00380     }
00381 }
00382 
00383 /// ParseAttributes() parses the known attributes for an object.
00384 CATResult CATSlider::ParseAttributes()
00385 {
00386     CATResult result = CATControl::ParseAttributes();
00387     CATString attrib;
00388 
00389     fCommandTrack = GetAttribute(L"CommandTrack",fCommandTrack);
00390     fSlideOffset  = GetAttribute(L"SlideOffset",fSlideOffset);
00391     attrib = GetAttribute(L"SliderStyle");
00392     if (!attrib.IsEmpty())
00393     {
00394         if ((attrib.GetWChar(0) | (char)0x20) == 'v')
00395         {
00396             fSliderStyle = CATSLIDER_VERTICAL;
00397         }
00398         else
00399         {
00400             fSliderStyle = CATSLIDER_HORIZONTAL;
00401         }
00402     }
00403 
00404     CATResult tmpResult;
00405     attrib = GetAttribute(L"ImageSlide");
00406     if (!attrib.IsEmpty())
00407     {
00408         tmpResult = LoadSkinImage(attrib,fImageSlide);
00409         if (CATFAILED(tmpResult))
00410             result = tmpResult;
00411     }
00412 
00413     attrib = GetAttribute(L"ImageOn");
00414     if (!attrib.IsEmpty())
00415     {
00416         tmpResult = LoadSkinImage(attrib,fImageOn);
00417         if (CATFAILED(tmpResult))
00418             result = tmpResult;
00419     }
00420 
00421     attrib = GetAttribute(L"ImageSlideDisabled");
00422     if (!attrib.IsEmpty())  
00423     {
00424         tmpResult = LoadSkinImage(attrib,fImageSlideDisabled);
00425         if (CATFAILED(tmpResult))
00426             result = tmpResult;
00427     }
00428 
00429     attrib = GetAttribute(L"ImageSlideFocus");
00430     if (!attrib.IsEmpty())  
00431     {
00432         tmpResult = LoadSkinImage(attrib,fImageSlideFocus);
00433         if (CATFAILED(tmpResult))
00434             result = tmpResult;
00435     }
00436 
00437     attrib = GetAttribute(L"ValueType");
00438     if (!attrib.IsEmpty())
00439     {
00440         if (attrib.Compare("dB") == 0)
00441         {
00442             fValueType = CATVALUE_DB;
00443         }
00444         else
00445         {
00446             fValueType = CATVALUE_LINEAR;
00447         }
00448     }
00449 
00450     return result;
00451 
00452 }
00453 
00454 CATSLIDER_STYLE CATSlider::GetSliderStyle()
00455 {
00456     return fSliderStyle;
00457 }
00458 
00459 void CATSlider::SetSliderStyle(CATSLIDER_STYLE style)
00460 {
00461     fSliderStyle = style;
00462     // IF manually set, override cursor 
00463     switch (fSliderStyle)
00464     {
00465     case CATSLIDER_HORIZONTAL:
00466         fCursor.SetType(CATCURSOR_LEFTRIGHT);
00467         break;
00468     case CATSLIDER_VERTICAL:         
00469     default:
00470         fCursor.SetType(CATCURSOR_TOPBOTTOM);
00471         break;
00472     }
00473 }
00474 
00475 CATResult CATSlider::Load(CATPROGRESSCB             progressCB ,
00476                           void*                         progressParam,
00477                           CATFloat32                        progMin,
00478                           CATFloat32                        progMax)
00479 {
00480     CATResult result = CATControl::Load(progressCB, progressParam, progMin, progMax);
00481 
00482     if (CATFAILED(result))
00483     {
00484         return result;
00485     }
00486 
00487     // Sanity check images
00488     if (fImageSlide != 0)
00489     {
00490         CATResult testResult = CAT_SUCCESS;
00491 
00492         if (fImageSlideDisabled)
00493         {
00494             testResult = CheckImageSize(fImageSlideDisabled, fImageSlide);
00495             if (testResult != CAT_SUCCESS)
00496                 result = testResult;
00497         }
00498 
00499         if (fImageSlideFocus)
00500         {
00501             testResult = CheckImageSize(fImageSlideFocus, fImageSlide);
00502             if (testResult != CAT_SUCCESS)
00503                 result = testResult;
00504         }
00505     }
00506 
00507     return result;
00508 }
00509 
00510 CATString CATSlider::GetHint() const
00511 {
00512     CATString retString = CATControl::GetHint();
00513 
00514     if (fShowHintValue)
00515     {
00516         CATString hintVal;
00517         if (fValueType == CATVALUE_DB)
00518         {
00519             if (fValue == 0.0f)
00520             {
00521                 hintVal.Format(" ( Off )");
00522             }
00523             else
00524             {
00525                 CATFloat32 dbValue = CATLinearToDBValue(fValue);
00526                 hintVal.Format(" ( %c%.2fdB - %.2f)",(dbValue > 0)?'+':'-', fabs(dbValue), CATLinearToDBGain(fValue) );
00527             }
00528         }
00529         else
00530         {
00531             hintVal.Format(" ( %.2f )",this->GetValue());
00532         }
00533         retString << hintVal;
00534     }
00535 
00536     return retString;
00537 }
00538 
00539 
00540 // OnMouseDoubleClick() is called the mouse is double clicked.
00541 //
00542 // \param modKey - Key state modifiers for ctrl/shift/alt/etc.
00543 void CATSlider::OnMouseDoubleClick(CATMODKEY modKey)
00544 {
00545     this->SetValue(fDefValue);
00546     fLastTarget = fValue;
00547     this->MarkDirty();
00548 }

Generated on Mon Feb 11 04:09:56 2008 for Game Accessibility Suite by doxygen 1.5.4