home *** CD-ROM | disk | FTP | other *** search
/ ...taking it to the Macs! / ...taking it to the Macs!.iso / Extras / ActiveX Mac SDK / ActiveX SDK / Sample Controls / Button / CButtonControl.cpp < prev    next >
Encoding:
Text File  |  1996-12-22  |  26.8 KB  |  1,034 lines  |  [TEXT/CWIE]

  1. // =================================================================================
  2. //
  3. //    CButtonControl.cpp                ©1996 Microsoft Corporation All rights reserved.
  4. //
  5. // =================================================================================
  6.  
  7. #include "ocheaders.h"
  8. #include <math.h>
  9. #include <PlatformControlGuid.h>
  10. #include "CConnectionPoint.h"
  11. #include "CCPContainer.h"
  12. #include "CButtonControl.h"
  13.  
  14. static pascal void ScrollBarActionProc(ControlRef theControl, ControlPartCode partCode);
  15.  
  16. #pragma mark === CButtonControl::Constructors & Destructors ===
  17.  
  18. //=--------------------------------------------------------------------------=
  19. //    CButtonControl::CButtonControl    
  20. //=--------------------------------------------------------------------------=
  21.  
  22. CButtonControl::CButtonControl(void) : CBaseControl()
  23. {
  24. //    mBounds.top = mBounds.left = 0;
  25. //    mBounds.bottom = mBounds.right = 25;
  26.     *mID = 0;
  27.     *mTitle = 0;
  28.     mRefCon = (Int32) this;
  29.     mCurrentValue = 0;
  30.     mMinValue = 0;
  31.     mMaxValue = 1;
  32.     mControlType = PushButtonType;
  33.     mPageDistance = 2;
  34.     mActive = true;
  35.     mVisible = true;
  36.  
  37.     // Create the new connection point container object
  38.     CCPContainer*    containerObj = new CCPContainer(1);
  39.     
  40.     // Snag the interface pointer
  41.     if ( containerObj )
  42.         containerObj->QueryInterface(IID_IConnectionPointContainer, &mCPContainerP);
  43.     
  44.     // if we have a container object, allocate the connection points
  45.     if ( mCPContainerP )
  46.         // We support 1 connection point
  47.         containerObj->AddConnectionPoint(IID_IPlatformControlListener);
  48. }
  49.  
  50.  
  51. //=--------------------------------------------------------------------------=
  52. //    CButtonControl::~CButtonControl
  53. //=--------------------------------------------------------------------------=
  54.  
  55. CButtonControl::~CButtonControl()
  56. {
  57. }
  58.  
  59.  
  60. #pragma mark === CButtonControl::IUnknown methods ===
  61.  
  62. //=--------------------------------------------------------------------------=
  63. //    CButtonControl::IUnknown::QueryInterface::
  64. //=--------------------------------------------------------------------------=
  65.  
  66. STDMETHODIMP
  67. CButtonControl::QueryInterface(REFIID inRefID, void** outObj)
  68. {
  69.     if ( inRefID == IID_IPlatformControl )
  70.     {
  71.         *outObj = (void*) (IPlatformControl*) this;
  72.         AddRef();
  73.         
  74.         return S_OK;
  75.     }
  76.     else
  77.         return CBaseControl::QueryInterface(inRefID, outObj);
  78. }
  79.  
  80.  
  81. #pragma mark === CButtonControl::IControl methods ===
  82.  
  83. //=--------------------------------------------------------------------------=
  84. //    CButtonControl::IControl::GetID
  85. //=--------------------------------------------------------------------------=
  86.  
  87. STDMETHODIMP
  88. CButtonControl::GetID(Int32 inBufferSize, Char8* outID)
  89. {
  90.     if (*mID)
  91.     {
  92.         if (*mID < inBufferSize)
  93.             inBufferSize = *mID;
  94.         ::BlockMove(mID + 1, outID, inBufferSize);
  95.         *(outID + inBufferSize) = 0;
  96.     }
  97.     else
  98.         return CBaseControl::GetID(inBufferSize, outID);
  99.  
  100.     return S_OK;
  101. }
  102.  
  103.  
  104. //=--------------------------------------------------------------------------=
  105. //    CButtonControl::IControl::Draw
  106. //=--------------------------------------------------------------------------=
  107.  
  108. STDMETHODIMP
  109. CButtonControl::Draw( DrawContext* inContext)
  110. {
  111.     if (inContext->DrawAspect != DVASPECT_CONTENT)
  112.         return DV_E_DVASPECT;
  113.  
  114.     DrawMe((CButtonContextInfo*)GetContextInfoByID(inContext->ContextID), inContext);
  115.  
  116.     return S_OK;
  117. }
  118.  
  119.  
  120. //=--------------------------------------------------------------------------=
  121. //    CButtonControl::IControl::DoMouse    
  122. //=--------------------------------------------------------------------------=
  123.  
  124. STDMETHODIMP
  125. CButtonControl::DoMouse(MouseEventType inMouseET, PlatformEvent* inEvent)
  126. {
  127.     ErrorCode    theResult = S_FALSE;
  128.  
  129.     switch (inMouseET)
  130.     {
  131.         case MouseUp:
  132.             DrawAllContexts();
  133.             theResult = S_OK;
  134.             break;
  135.  
  136.         case MouseDown:
  137.             theResult = DoMouseDown(inEvent);
  138.             break;
  139.         default:
  140.             break;
  141.     }
  142.     
  143.     return theResult;
  144. }
  145.  
  146.  
  147. //=--------------------------------------------------------------------------=
  148. //    CButtonControl::IControl::DoActivate    
  149. //=--------------------------------------------------------------------------=
  150.  
  151. STDMETHODIMP
  152. CButtonControl::DoActivate(ActivateEventType inActiveET, UInt32 inContextID, PlatformEvent* inEvent)
  153. {
  154. #pragma unused (inEvent)
  155.     Boolean8            Redraw = false;
  156.     CButtonContextInfo*    ContextInfo = (CButtonContextInfo*)GetContextInfoByID(inContextID);
  157.     ControlRef            theControl = ContextInfo->GetControlRef();
  158.  
  159.     if (mActive && (inActiveET == WindowDeactivate || inActiveET == AppDeactivate))
  160.     {
  161.         ::HidePen();
  162.         ::HiliteControl(theControl, kControlInactivePart);
  163.         ::ShowPen();
  164.         Redraw = true;
  165.     }
  166.     else if (mActive && inActiveET == WindowActivate)
  167.     {
  168.         ::HidePen();
  169.         ::HiliteControl(theControl, kControlNoPart);
  170.         ::ShowPen();
  171.         Redraw = true;
  172.     }
  173.  
  174.     if (Redraw)
  175.     {
  176.         DrawContext    Context = { BeginPortType };
  177.         if (mContainerSiteP->AcquireContext(inContextID, &Context) == S_OK)
  178.         {
  179.             DrawMe(ContextInfo, &Context);
  180.             mContainerSiteP->ReleaseContext(&Context);
  181.         }
  182.     }
  183.  
  184.     return S_OK;
  185. }
  186.  
  187.  
  188. #pragma mark === CButtonControl::IPersistPropertyBag methods ===
  189.  
  190. //=--------------------------------------------------------------------------=
  191. //    CButtonControl::IPersistPropertyBag::Load
  192. //=--------------------------------------------------------------------------=
  193.  
  194. STDMETHODIMP
  195. CButtonControl::Load(IPropertyBag* PropertyBag, IErrorLog* ErrorLog)
  196. {
  197.     ControlPropertyType    SetProps = EmptyControlPropertyType;
  198.     ErrorCode            ECode = S_OK;
  199.     Int32                i;
  200.     PlatformPoint        PrevSize = mSize;
  201.     VARIANT                v;
  202.  
  203.     v.vt = VT_BSTR;
  204.     v.bstrVal = NULL;
  205.  
  206.     CBaseControl::Load(PropertyBag, ErrorLog);
  207.  
  208.     if (mSize.v != PrevSize.v || mSize.h != PrevSize.h)
  209.         SetProps = ControlPropertyType(SetProps | SizeControlProperty);
  210.  
  211.     if (PropertyBag->Read("ctype", &v, ErrorLog) == S_OK && v.bstrVal)
  212.     {
  213.         Char8        c = *(v.bstrVal + sizeof(Uint32));
  214.  
  215.         switch (c)
  216.         {
  217.             case 's':
  218.             case 'S':
  219.                 mControlType = ScrollBarType;
  220.                 mMaxValue = 32767;
  221.                 break;
  222.             case 'r':
  223.             case 'R':
  224.                 mControlType = RadioButtonType;
  225.                 break;
  226.             case 'c':
  227.             case 'C':
  228.                 mControlType = CheckBoxType;
  229.                 break;
  230.             case 'p':
  231.             case 'P':
  232.             default:
  233.                 //    the control defaults to a push button
  234.                 mControlType = PushButtonType;
  235.                 break;
  236.         }
  237.         CoTaskMemFree(v.bstrVal);
  238.         SetProps = ControlPropertyType(SetProps | TypeControlProperty);
  239.     }
  240.  
  241.     if (PropertyBag->Read("max", &v, ErrorLog) == S_OK && v.bstrVal)
  242.     {
  243.         ::StringToNum((Uchar8*)v.bstrVal + sizeof(Uint32) - 1, &i);
  244.         mMaxValue = i;
  245.         CoTaskMemFree(v.bstrVal);
  246.         SetProps = ControlPropertyType(SetProps | MaxValueControlProperty);
  247.     }
  248.  
  249.     if (PropertyBag->Read("min", &v, ErrorLog) == S_OK && v.bstrVal)
  250.     {
  251.         ::StringToNum((Uchar8*)v.bstrVal + sizeof(Uint32) - 1, &i);
  252.         mMinValue = i;
  253.         CoTaskMemFree(v.bstrVal);
  254.         SetProps = ControlPropertyType(SetProps | MinValueControlProperty);
  255.     }
  256.  
  257.     if (PropertyBag->Read("start", &v, ErrorLog) == S_OK && v.bstrVal)
  258.     {
  259.         ::StringToNum((Uchar8*)v.bstrVal + sizeof(Uint32) - 1, &i);
  260.         mCurrentValue = i;
  261.         CoTaskMemFree(v.bstrVal);
  262.         SetProps = ControlPropertyType(SetProps | ValueControlProperty);
  263.     }
  264.  
  265.     if (PropertyBag->Read("title", &v, ErrorLog) == S_OK && v.bstrVal)
  266.     {
  267.         Int16    NameLen = *((Uint32*) v.bstrVal);
  268.  
  269.         if (NameLen > 255)
  270.             NameLen = 255;
  271.         ::BlockMove(v.bstrVal + sizeof(Uint32), mTitle + 1, NameLen);
  272.         *mTitle = NameLen;
  273.         CoTaskMemFree(v.bstrVal);
  274.         SetProps = ControlPropertyType(SetProps | TitleControlProperty);
  275.     }
  276.  
  277.     if (PropertyBag->Read("visible", &v, ErrorLog) == S_OK && v.bstrVal)
  278.     {
  279.         Char8        c = *(v.bstrVal + sizeof(Uint32));
  280.  
  281.         if (c == 'F' || c == 'f')
  282.             mVisible = false;
  283.         else
  284.             mVisible = true;
  285.  
  286.         SetProps = ControlPropertyType(SetProps | VisibleControlProperty);
  287.     }
  288.  
  289.     TouchAllContexts(SetProps);
  290.  
  291.     return ECode;
  292. }
  293.  
  294.  
  295. #pragma mark === CButtonControl::CBaseControl methods ===
  296.  
  297. //=--------------------------------------------------------------------------=
  298. //    CButtonControl::CBaseControl::NewContext    
  299. //=--------------------------------------------------------------------------=
  300.  
  301. CBaseContextInfo*
  302. CButtonControl::NewContext(Uint32 inContextID)
  303. {
  304.     CButtonContextInfo*    NewContextInfo = new CButtonContextInfo(this, inContextID);
  305.  
  306.     return NewContextInfo;
  307. }
  308.  
  309.  
  310. #pragma mark === CButtonControl methods ===
  311.  
  312. //=--------------------------------------------------------------------------=
  313. //    CButtonControl::CBaseControl::NewContext    
  314. //=--------------------------------------------------------------------------=
  315.  
  316. void
  317. CButtonControl::TouchAllContexts(ControlPropertyType PropertyType)
  318. {
  319.     CButtonContextInfo*    ContextInfo;
  320.     Int16                Index = 1;
  321.  
  322.     while ((ContextInfo = (CButtonContextInfo*)GetContextInfoByIndex(Index++)) != NULL)
  323.     {
  324.         ControlRef    theControl = ContextInfo->GetControlRef();
  325.         DrawContext    Context = { BeginPortType };
  326.  
  327.         if (!theControl || PropertyType & TypeControlProperty)
  328.             ContextInfo->MakePlatformControl();
  329.         else if (mContainerSiteP->AcquireContext(ContextInfo->GetContextID(), &Context) == S_OK)
  330.         {
  331.             ::HidePen();    //    keep the changes from drawing until we are done
  332.  
  333.             if (PropertyType & SizeControlProperty)
  334.                 ::SizeControl(theControl, mSize.h, mSize.v);
  335.  
  336.             if (PropertyType & VisibleControlProperty)
  337.             {
  338.                 if (mVisible)
  339.                     ::ShowControl(theControl);
  340.                 else
  341.                     ::HideControl(theControl);
  342.             }
  343.  
  344.             if (PropertyType & TitleControlProperty)
  345.                 ::SetControlTitle(theControl, mTitle);
  346.  
  347.             if (PropertyType & MinValueControlProperty)
  348.                 ::SetControlMinimum(theControl, mMinValue);
  349.  
  350.             if (PropertyType & MaxValueControlProperty)
  351.                 ::SetControlMaximum(theControl, mMaxValue);
  352.  
  353.             if (PropertyType & ValueControlProperty)
  354.                 ::SetControlValue(theControl, mCurrentValue);
  355.  
  356.             ::ShowPen();    //    okay to draw now
  357.  
  358.             DrawMe(ContextInfo, &Context);
  359.             mContainerSiteP->ReleaseContext(&Context);
  360.         }
  361.     }
  362. }
  363.  
  364.  
  365. //=--------------------------------------------------------------------------=
  366. //    CButtonControl::DoMouseDown    
  367. //=--------------------------------------------------------------------------=
  368.  
  369. ErrorCode
  370. CButtonControl::DoMouseDown(PlatformEvent* inEvent)
  371. {
  372.     Boolean8    DoRelease = true;
  373.     DrawContext    Context = { BeginPortType };
  374.     Point        Origin, COrigin;
  375.  
  376.     if (mContainerSiteP->AcquireContext(mActiveContext->GetContextID(), &Context) == S_OK)
  377.     {
  378.         CButtonContextInfo*    ContextInfo = (CButtonContextInfo*)mActiveContext;
  379.         if (ContextInfo)
  380.         {
  381.             ControlRef        WhichControl;
  382.             ControlPartCode    PartCode;
  383.             Point            COrigin = ContextInfo->GetOrigin();
  384.             Point            LocalPoint = inEvent->where;
  385.  
  386.             Origin = *(Point*)(&Context.Port->portRect);
  387.             COrigin = ContextInfo->GetOrigin();
  388.             ::SetOrigin(Origin.h - COrigin.h, Origin.v - COrigin.v);
  389.             ::GlobalToLocal(&LocalPoint);
  390.             ::OffsetRgn(Context.Port->clipRgn, -COrigin.h,  -COrigin.v);
  391.  
  392.             if ((PartCode = ::FindControl(LocalPoint, Context.Port, &WhichControl)) != 0)
  393.             {
  394.                 Boolean8            Redraw = false;
  395.                 Boolean8            NotifyListeners;
  396.                 ControlActionUPP    ActionProc;
  397.                 Int16                OldValue = ::GetControlValue(ContextInfo->GetControlRef());
  398.                 Int16                NewValue;
  399.  
  400.                 switch (mControlType)
  401.                 {
  402.                     case ScrollBarType:
  403.                         switch (PartCode)
  404.                         {
  405.                             case kControlPageUpPart:
  406.                             case kControlPageDownPart:
  407.                                 //    at this point it would be good to ask the target what its page size is
  408.                                 //    and put that into mJumpDistance
  409.                                 //    intentional fall through
  410.                             case kControlUpButtonPart:
  411.                             case kControlDownButtonPart:
  412.                                 ActionProc = NewControlActionProc(ScrollBarActionProc);
  413.                                 break;
  414.                             case kControlIndicatorPart:
  415.                             default:
  416.                                 ActionProc = NULL;
  417.                                 break;
  418.                         }
  419.                         break;
  420.                     case PushButtonType:
  421.                     case CheckBoxType:
  422.                     case RadioButtonType:
  423.                     default:
  424.                         ActionProc = NULL;
  425.                         break;
  426.                 }
  427.  
  428.                 NotifyListeners = ::TrackControl(ContextInfo->GetControlRef(), LocalPoint, ActionProc);
  429.                 if (ActionProc)
  430.                     ::DisposeRoutineDescriptor(ActionProc);
  431.  
  432.                 switch (mControlType)
  433.                 {
  434.                     case CheckBoxType:
  435.                     case RadioButtonType:
  436.                         if (NotifyListeners)
  437.                         {
  438.                             NewValue = OldValue ? 0 : 1;
  439.                             Redraw = true;
  440.                         }
  441.                         break;
  442.                     case ScrollBarType:
  443.                         NewValue = ::GetControlValue(ContextInfo->GetControlRef());
  444.                         break;
  445.                     case PushButtonType:
  446.                     default:
  447.                         break;
  448.                 }
  449.  
  450.                 //    tell all sibling controls about the value change
  451.                 if (NewValue != OldValue)
  452.                 {
  453.                     DoRelease =  false;
  454.                     mCurrentValue = NewValue;
  455.                     NotifyListeners = true;
  456.                     ::OffsetRgn(Context.Port->clipRgn, COrigin.h,  COrigin.v);
  457.                     ::SetOrigin(Origin.h, Origin.v);
  458.                     mContainerSiteP->ReleaseContext(&Context);
  459.                     TouchAllContexts(ValueControlProperty);
  460.                 }
  461.  
  462.                 //    tell all the listeners that there was a click or value change
  463.                 if (NotifyListeners)
  464.                     TellListeners(NewValue);
  465.             }
  466.         }
  467. #if BE_STRICT
  468.         else
  469.             DebugStr("\pCButtonControl::DoMouse - Unrecognized context!");
  470. #endif    //    BE_STRICT
  471.         if (DoRelease)
  472.         {
  473.             ::OffsetRgn(Context.Port->clipRgn, COrigin.h,  COrigin.v);
  474.             ::SetOrigin(Origin.h, Origin.v);
  475.             mContainerSiteP->ReleaseContext(&Context);
  476.         }
  477.     }
  478. #if BE_STRICT
  479.     else
  480.         DebugStr("\pCButtonControl::DoMouse - Couldn't acquire default context");
  481. #endif    //    BE_STRICT
  482.     DrawAllContexts();
  483.     return S_OK;
  484. }
  485.  
  486.  
  487. //=--------------------------------------------------------------------------=
  488. //    CButtonControl::DrawAllContexts    
  489. //=--------------------------------------------------------------------------=
  490.  
  491. void
  492. CButtonControl::DrawAllContexts(void)
  493. {
  494.     DrawContext            Context = {BeginPortType};
  495.     Int32                Index = 1;
  496.     CButtonContextInfo*    ContextInfo;
  497.  
  498.     while((ContextInfo = (CButtonContextInfo*)GetContextInfoByIndex(Index++)) != NULL)
  499.         if (mContainerSiteP->AcquireContext(ContextInfo->GetContextID(), &Context) == S_OK)
  500.         {
  501.             DrawMe(ContextInfo, &Context);
  502.             mContainerSiteP->ReleaseContext(&Context);
  503.         }
  504. }
  505.  
  506.  
  507. //=--------------------------------------------------------------------------=
  508. //    CButtonControl::DrawMe    
  509. //=--------------------------------------------------------------------------=
  510.  
  511. void
  512. CButtonControl::DrawMe(CButtonContextInfo* inContextInfoP, DrawContext* inContextP)
  513. {
  514.     if (inContextInfoP->GetControlRef())    //    if the context has a real control then just draw it
  515.     {
  516.         Point        Origin = *(Point*)(&inContextP->Port->portRect);
  517.         Point        COrigin = inContextInfoP->GetOrigin();
  518.  
  519.         ::SetOrigin(Origin.h - COrigin.h, Origin.v - COrigin.v);
  520.         ::OffsetRgn(inContextP->Port->clipRgn, -COrigin.h,  -COrigin.v);
  521.  
  522.         ::DrawOneControl(inContextInfoP->GetControlRef());
  523.         ::OffsetRgn(inContextP->Port->clipRgn, COrigin.h,  COrigin.v);
  524.         ::SetOrigin(Origin.h, Origin.v);
  525.     }
  526.     else if (mVisible)    //    otherwise, it must not be able to handle a control, build a temp one - this doesn't work yet
  527.     {
  528.         PicHandle    TempPict = NULL;
  529.         WindowPtr    TempWin = ::NewCWindow(NULL, &inContextP->Location, "\p", false, documentProc, NULL, false, NULL);
  530.  
  531.         if (TempWin)
  532.         {
  533.             Rect        Bounds = { 0 };
  534.  
  535.             Bounds.right = mSize.h;
  536.             Bounds.bottom = mSize.v;
  537.             ::HidePen();
  538.             ControlRef    TempControl = ::NewControl(TempWin, &Bounds, mTitle, true,
  539.                 mCurrentValue, mMinValue, mMaxValue, mControlType, mRefCon);
  540.             if (TempControl)
  541.             {
  542.                 PicHandle    TempPict;
  543.  
  544.                 if ((TempPict = ::OpenPicture(&Bounds)) != NULL)
  545.                 {
  546.                     ::DrawOneControl(TempControl);
  547.                     ::ClosePicture();
  548.                 }
  549.                 ::DisposeControl(TempControl);
  550.             }
  551.             ::ShowPen();
  552.             ::DisposeWindow(TempWin);
  553.         }
  554.  
  555.         if (TempPict)
  556.         {
  557.             ::SetPort(inContextP->Port);
  558.             ::DrawPicture(TempPict, &inContextP->Location);
  559.             ::DisposeHandle(Handle(TempPict));
  560.         }
  561.     }
  562. }
  563.  
  564.  
  565. //=--------------------------------------------------------------------------=
  566. //    CButtonControl::TellListeners    
  567. //=--------------------------------------------------------------------------=
  568.  
  569. void
  570. CButtonControl::TellListeners(Int32 ControlValue)
  571. {
  572.     IEnumConnectionPoints*    enumCP;
  573.     
  574.     // Get an enumerator for the connection points
  575.     if ( SUCCEEDED(mCPContainerP->EnumConnectionPoints(&enumCP)) )
  576.     {
  577.         IConnectionPoint*    connectionPoint;
  578.         IUnknown*            Me;
  579.  
  580.         this->QueryInterface(IID_IUnknown, (void**) &Me);
  581.  
  582.         // Loop through all the connection points for this control
  583.         while ( enumCP->Next(1, &connectionPoint, nil) == NOERROR )
  584.         {
  585.             IEnumConnections*        enumC;
  586.  
  587.             // Get all the connections for this connection point
  588.             if ( SUCCEEDED( connectionPoint->EnumConnections(&enumC) ))
  589.             {
  590.                 CONNECTDATA            connectData;
  591.  
  592.                 // Loop through all the connections for this connection point    
  593.                 while ( enumC->Next(1, &connectData, nil) == NOERROR )
  594.                 {
  595.                     IPlatformControlListener*    Listener;
  596.                     // Get the interface implementation for this connection
  597.                     // if successful, fire the event
  598.                     if (connectData.pUnk->QueryInterface(IID_IPlatformControlListener, &Listener) == S_OK)
  599.                     {
  600.                         Listener->OnControlValueChange(Me, ControlValue);
  601.                         Listener->Release();
  602.                     }
  603.                 }
  604.                 
  605.                 // Release the enumerator
  606.                 enumC->Release();
  607.             }
  608.         }
  609.         
  610.         enumCP->Release();
  611.     }
  612. }
  613.  
  614.  
  615. #pragma mark === CButtonControl::IPlatformControl ===
  616.  
  617. //=--------------------------------------------------------------------------=
  618. //    CButtonControl::IPlatformControl::GetType    
  619. //=--------------------------------------------------------------------------=
  620.  
  621. STDMETHODIMP
  622. CButtonControl::GetType(IUnknown* inSource, ControlType* outCntrlType)
  623. {
  624. #pragma unused (inSource)
  625.  
  626.     *outCntrlType = mControlType;
  627.  
  628.     return S_OK;
  629. }
  630.  
  631.  
  632. //=--------------------------------------------------------------------------=
  633. //    CButtonControl::IPlatformControl::SetType    
  634. //=--------------------------------------------------------------------------=
  635.  
  636. STDMETHODIMP
  637. CButtonControl::SetType(IUnknown* inSource, ControlType inCntrlType)
  638. {
  639. #pragma unused (inSource)
  640.  
  641.     if (mControlType != inCntrlType)
  642.     {
  643.         mControlType = inCntrlType;
  644.         TouchAllContexts(VisibleControlProperty);
  645.     }
  646.  
  647.     return S_OK;
  648. }
  649.  
  650.  
  651. //=--------------------------------------------------------------------------=
  652. //    CButtonControl::IPlatformControl::GetSize    
  653. //=--------------------------------------------------------------------------=
  654.  
  655. STDMETHODIMP
  656. CButtonControl::GetSize(IUnknown* inSource, Int32* outWidth, Int32* outHeight)
  657. {
  658. #pragma unused (inSource)
  659.     *outWidth = mSize.h;
  660.     *outHeight = mSize.v;
  661.  
  662.     return S_OK;
  663. }
  664.  
  665.  
  666. //=--------------------------------------------------------------------------=
  667. //    CButtonControl::IPlatformControl::SetSize    
  668. //=--------------------------------------------------------------------------=
  669.  
  670. STDMETHODIMP
  671. CButtonControl::SetSize(IUnknown* inSource, Int32 inWidth, Int32 inHeight)
  672. {
  673. #pragma unused (inSource)
  674.     if (inWidth != mSize.h || inHeight != mSize.v)
  675.     {
  676.         mSize.h = inWidth;
  677.         mSize.v = inHeight;
  678.  
  679.         TouchAllContexts(SizeControlProperty);
  680.     }
  681.  
  682.     return S_OK;
  683. }
  684.  
  685.  
  686. //=--------------------------------------------------------------------------=
  687. //    CButtonControl::IPlatformControl::GetVisible    
  688. //=--------------------------------------------------------------------------=
  689.  
  690. STDMETHODIMP
  691. CButtonControl::GetVisible(IUnknown* inSource, Boolean8* outIsVisible)
  692. {
  693. #pragma unused (inSource)
  694.  
  695.     *outIsVisible = mVisible;
  696.  
  697.     return S_OK;
  698. }
  699.  
  700.  
  701. //=--------------------------------------------------------------------------=
  702. //    CButtonControl::IPlatformControl::SetVisible    
  703. //=--------------------------------------------------------------------------=
  704.  
  705. STDMETHODIMP
  706. CButtonControl::SetVisible(IUnknown* inSource, Boolean8 inShowIt)
  707. {
  708. #pragma unused (inSource)
  709.  
  710.     if (mVisible != inShowIt)
  711.     {
  712.         mVisible = inShowIt;
  713.         TouchAllContexts(VisibleControlProperty);
  714.     }
  715.  
  716.     return S_OK;
  717. }
  718.  
  719.  
  720. //=--------------------------------------------------------------------------=
  721. //    CButtonControl::IPlatformControl::GetHilite    
  722. //=--------------------------------------------------------------------------=
  723.  
  724. STDMETHODIMP
  725. CButtonControl::GetHilite(IUnknown* inSource, ControlHiliteType* outHiliteType)
  726. {
  727. #pragma unused (inSource)
  728.  
  729.     *outHiliteType = mHilite;
  730.  
  731.     return S_OK;
  732. }
  733.  
  734.  
  735. //=--------------------------------------------------------------------------=
  736. //    CButtonControl::IPlatformControl::SetHilite    
  737. //=--------------------------------------------------------------------------=
  738.  
  739. STDMETHODIMP
  740. CButtonControl::SetHilite(IUnknown* inSource, ControlHiliteType inHiliteType)
  741. {
  742. #pragma unused (inSource)
  743.  
  744.     if (mHilite != inHiliteType)
  745.     {
  746.         mHilite = inHiliteType;
  747.         TouchAllContexts(HiliteControlProperty);
  748.     }
  749.  
  750.     return S_OK;
  751. }
  752.  
  753.  
  754. //=--------------------------------------------------------------------------=
  755. //    CButtonControl::IPlatformControl::GetTitle    
  756. //=--------------------------------------------------------------------------=
  757.  
  758. STDMETHODIMP
  759. CButtonControl::GetTitle(IUnknown* inSource, Int32 inBufferSize, Char8* outControlTitle)
  760. {
  761. #pragma unused (inSource)
  762.  
  763.     Int16    NameLen = *mTitle;
  764.     if (NameLen > inBufferSize)
  765.         NameLen = inBufferSize;
  766.  
  767.     ::BlockMove(mTitle, outControlTitle, NameLen);
  768.     *(outControlTitle + NameLen) = '\0';
  769.  
  770.     return S_OK;
  771. }
  772.  
  773.  
  774. //=--------------------------------------------------------------------------=
  775. //    CButtonControl::IPlatformControl::SetTitle    
  776. //=--------------------------------------------------------------------------=
  777.  
  778. STDMETHODIMP
  779. CButtonControl::SetTitle(IUnknown* inSource, Char8* inControlTitle)
  780. {
  781. #pragma unused (inSource)
  782.  
  783.     Char8*    EndChar = inControlTitle;
  784.     Int16    NameLen;
  785.  
  786.     while (*EndChar++)
  787.         ;
  788.  
  789.     NameLen = EndChar - inControlTitle - 1;
  790.     if (NameLen > 255)
  791.         NameLen = 255;
  792.     ::BlockMove(inControlTitle, mTitle + 1, NameLen);
  793.     *mTitle = NameLen;
  794.     TouchAllContexts(TitleControlProperty);
  795.  
  796.     return S_OK;
  797. }
  798.  
  799.  
  800. //=--------------------------------------------------------------------------=
  801. //    CButtonControl::IPlatformControl::GetMinValue    
  802. //=--------------------------------------------------------------------------=
  803.  
  804. STDMETHODIMP
  805. CButtonControl::GetMinValue(IUnknown* inSource, Int32* outMinValue)
  806. {
  807. #pragma unused (inSource)
  808.  
  809.     *outMinValue = mMinValue;
  810.  
  811.     return S_OK;
  812. }
  813.  
  814.  
  815. //=--------------------------------------------------------------------------=
  816. //    CButtonControl::IPlatformControl::SetMinValue    
  817. //=--------------------------------------------------------------------------=
  818.  
  819. STDMETHODIMP
  820. CButtonControl::SetMinValue(IUnknown* inSource, Int32 inMinValue)
  821. {
  822. #pragma unused (inSource)
  823.  
  824.     if (inMinValue != mMinValue)
  825.     {
  826.         mMinValue = inMinValue;
  827.         TouchAllContexts(MinValueControlProperty);
  828.     }
  829.  
  830.     return S_OK;
  831. }
  832.  
  833.  
  834. //=--------------------------------------------------------------------------=
  835. //    CButtonControl::IPlatformControl::GetMaxValue    
  836. //=--------------------------------------------------------------------------=
  837.  
  838. STDMETHODIMP
  839. CButtonControl::GetMaxValue(IUnknown* inSource, Int32* outMaxValue)
  840. {
  841. #pragma unused (inSource)
  842.  
  843.     *outMaxValue = mMaxValue;
  844.  
  845.     return S_OK;
  846. }
  847.  
  848.  
  849. //=--------------------------------------------------------------------------=
  850. //    CButtonControl::IPlatformControl::SetMaxValue    
  851. //=--------------------------------------------------------------------------=
  852.  
  853. STDMETHODIMP
  854. CButtonControl::SetMaxValue(IUnknown* inSource, Int32 inMaxValue)
  855. {
  856. #pragma unused (inSource)
  857.  
  858.     if (inMaxValue != mMaxValue)
  859.     {
  860.         mMaxValue = inMaxValue;
  861.         TouchAllContexts(MaxValueControlProperty);
  862.     }
  863.  
  864.     return S_OK;
  865. }
  866.  
  867.  
  868. //=--------------------------------------------------------------------------=
  869. //    CButtonControl::IPlatformControl::GetValue    
  870. //=--------------------------------------------------------------------------=
  871.  
  872. STDMETHODIMP
  873. CButtonControl::GetValue(IUnknown* inSource, Int32* outValue)
  874. {
  875. #pragma unused (inSource)
  876.  
  877.     *outValue = mCurrentValue;
  878.  
  879.     return S_OK;
  880. }
  881.  
  882.  
  883. //=--------------------------------------------------------------------------=
  884. //    CButtonControl::IPlatformControl::SetValue    
  885. //=--------------------------------------------------------------------------=
  886.  
  887. STDMETHODIMP
  888. CButtonControl::SetValue(IUnknown* inSource, Int32 inValue)
  889. {
  890. #pragma unused (inSource)
  891.  
  892.     if (inValue != mCurrentValue)
  893.     {
  894.         mCurrentValue = inValue;
  895.         TouchAllContexts(ValueControlProperty);
  896.     }
  897.  
  898.     return S_OK;
  899. }
  900.  
  901.  
  902. //=--------------------------------------------------------------------------=
  903. //    CButtonControl::IPlatformControl::SetPageDistance    
  904. //=--------------------------------------------------------------------------=
  905.  
  906. STDMETHODIMP
  907. CButtonControl::SetPageDistance(IUnknown* inSource, Int32 inPageDistance)
  908. {
  909. #pragma unused (inSource)
  910.  
  911.     mPageDistance = inPageDistance;
  912.  
  913.     return S_OK;
  914. }
  915.  
  916.  
  917. #pragma mark === CButtonContextInfo Constructor & Destructor ===
  918.  
  919. //=--------------------------------------------------------------------------=
  920. //    CButtonContextInfo::CButtonContextInfo    
  921. //=--------------------------------------------------------------------------=
  922. CButtonContextInfo::CButtonContextInfo(CButtonControl* inControlP, Uint32 inContextID) :
  923.         CBaseContextInfo (inControlP, inContextID)
  924. {
  925.     DrawContext Context = { BeginPortType };
  926.  
  927.     mTBControlRef = NULL;
  928.  
  929.     MakePlatformControl();
  930. }
  931.  
  932.  
  933. //=--------------------------------------------------------------------------=
  934. //    CButtonContextInfo::MakePlatformControl    
  935. //=--------------------------------------------------------------------------=
  936.  
  937. void
  938. CButtonContextInfo::MakePlatformControl(void)
  939. {
  940.     DrawContext        Context = { BeginPortType };
  941.     CButtonControl*    ButtonControlP = (CButtonControl*)mControlP;
  942.     Rect            Bounds = { 0 };
  943.  
  944.     {
  945.         Int32            Width, Height;
  946.  
  947.         ((CButtonControl*)mControlP)->GetSize(NULL, &Width, &Height);
  948.         Bounds.right = Width;
  949.         Bounds.bottom = Height;
  950.     }
  951.  
  952.     if (mTBControlRef)
  953.     {
  954.         ::DisposeControl(mTBControlRef);
  955.         mTBControlRef = NULL;
  956.     }
  957.  
  958.     if (ButtonControlP->mContainerSiteP->AcquireContext(mContextID, &Context) == S_OK)
  959.     {
  960.         mOrigin = *(Point*)(&Context.Port->portRect);
  961.         if (Context.PortType == QDWindowPortType)
  962.         {
  963.             StringPtr    ControlTitle = ButtonControlP->mTitle;
  964.             Str255        TempName;
  965.  
  966.             if (!*ControlTitle)
  967.             {
  968.                 ControlTitle = TempName;
  969.                 ButtonControlP->GetID(254, (Char8*)(TempName+1));
  970.                 *TempName = strlen((Char8*)(TempName+1));
  971.             }
  972.  
  973.             ::SetOrigin(0, 0);
  974.             ::OffsetRect(&Bounds, -mOrigin.h, -mOrigin.v);
  975. ::ClipRect(&Bounds);
  976.             mTBControlRef = ::NewControl(Context.Port, &Bounds, ControlTitle, ButtonControlP->mVisible,
  977.                 ButtonControlP->mCurrentValue, ButtonControlP->mMinValue, ButtonControlP->mMaxValue,
  978.                 ButtonControlP->mControlType, ButtonControlP->mRefCon);
  979.             ::SetOrigin(mOrigin.h, mOrigin.v);
  980.         }
  981.         ButtonControlP->mContainerSiteP->ReleaseContext(&Context);
  982.     }
  983. }
  984.  
  985.  
  986. //=--------------------------------------------------------------------------=
  987. //    CButtonContextInfo::~CButtonContextInfo    
  988. //=--------------------------------------------------------------------------=
  989. CButtonContextInfo::~CButtonContextInfo(void)
  990. {
  991.     ::DisposeControl(mTBControlRef);
  992. }
  993.  
  994.  
  995. #pragma mark === Control Action Procs ===
  996.  
  997. //=--------------------------------------------------------------------------=
  998. //    ScrollBarActionProc [static]    
  999. //=--------------------------------------------------------------------------=
  1000. static pascal void
  1001. ScrollBarActionProc(ControlRef theControl, ControlPartCode partCode)
  1002. {
  1003.     Int16    OldValue, NewValue, MinValue, MaxValue;
  1004.     Int16    ScrollDistance = 0;
  1005.     
  1006.     switch (partCode)
  1007.     {
  1008.         case kControlUpButtonPart:
  1009.         case kControlDownButtonPart:
  1010.             ScrollDistance = 1;
  1011.             break;
  1012.         case kControlPageUpPart:
  1013.         case kControlPageDownPart:
  1014.             ScrollDistance = ((CButtonControl*)::GetControlReference(theControl))->GetPageDistance();
  1015.             break;
  1016.     }
  1017.  
  1018.     if (partCode == kControlUpButtonPart || partCode == kControlPageUpPart)
  1019.         ScrollDistance = -ScrollDistance;
  1020.  
  1021.     OldValue = ::GetControlValue(theControl);
  1022.     NewValue = OldValue + ScrollDistance;
  1023.     if (NewValue < (MinValue = ::GetControlMinimum(theControl)))
  1024.         NewValue = MinValue;
  1025.     else if (NewValue > (MaxValue = ::GetControlMaximum(theControl)))
  1026.         NewValue = MaxValue;
  1027.  
  1028.     if (OldValue != NewValue)
  1029.     {
  1030.         ::SetControlValue(theControl, NewValue);    //    this needs to be changed to move ALL sibling controls
  1031.         //    here is where we'd like to send out messages to listeners
  1032.     }
  1033. }
  1034.