home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / mac / UserInterface / CButton.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  15.9 KB  |  604 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #ifdef PowerPlant_PCH
  20. #include PowerPlant_PCH
  21. #endif
  22.  
  23. #include <UGWorld.h>
  24. #include <UDrawingState.h>
  25. #include <UDrawingUtils.h>
  26. #include <UMemoryMgr.h>
  27. #include <UTextTraits.h>
  28. #include <LStream.h>
  29.  
  30. #if defined(QAP_BUILD)
  31. #include <QAP_Assist.h>
  32. #endif
  33.  
  34. #include "UGraphicGizmos.h"
  35. #include "CButton.h"
  36. #include "StSetBroadcasting.h"
  37. #include "CTargetedUpdateMenuRegistry.h"
  38.  
  39. #ifndef __ICONS__
  40. #include <Icons.h>
  41. #endif
  42.  
  43. #ifndef __PALETTES__
  44. #include <Palettes.h>
  45. #endif
  46.  
  47. #ifndef __TOOLUTILS__
  48. #include <ToolUtils.h>
  49. #endif
  50.  
  51. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  52. //    ÑÑÑ
  53. //    Ñ    Class CButton
  54. //    ÑÑÑ    
  55. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  56. /*
  57. #if defined(QAP_BUILD)
  58. void
  59. CButton::QapGetContents (PWCINFO pwc, short *pCount, short max)
  60. {
  61.     QapAddViewItem (pwc, pCount, WT_ASSIST_ITEM, WC_PUSH_BUTTON);
  62. }
  63.  
  64. void
  65. CButton::QapGetCDescriptorMax (char * cp_buf, short s_max)
  66. {
  67.     Str255    controlTitle;
  68.     short    sMinLen;
  69.     
  70.     GetDescriptor(controlTitle);
  71.     
  72.     memset (cp_buf, 0, s_max);
  73.     sMinLen = ((short)controlTitle[0] < s_max ? (short)controlTitle[0] : s_max);
  74.     strncpy (cp_buf, (const char *)&controlTitle[1], sMinLen);
  75. }
  76. #endif
  77. */
  78. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  79. //    Ñ    CButton
  80. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  81.  
  82. CButton::CButton(LStream *inStream)
  83.     :    LControl(inStream)
  84. {
  85.     mButtonMask = NULL;
  86.     mGraphicHandle = NULL;
  87.     SetTrackInside(false);
  88.     
  89.     *inStream >> mTrackBehaviour;
  90.     *inStream >> mOvalWidth;
  91.     *inStream >> mOvalHeight;
  92.         
  93.     inStream->ReadPString(mTitle);
  94.     *inStream >> mTitleTraitsID;    
  95.     *inStream >> mTitleAlignment;
  96.     *inStream >> mTitlePadPixels;
  97.         
  98.     *inStream >> mGraphicType;
  99.     *inStream >> mGraphicID;
  100.     *inStream >> mGraphicAlignment;
  101.     *inStream >> mGraphicPadPixels;
  102.  
  103.     if ((mGraphicID != 0) && (mGraphicType == 'cicn'))
  104.         {
  105.         mGraphicHandle = ::GetCIcon(mGraphicID);
  106.         ThrowIfNULL_(mGraphicHandle);
  107.         }
  108. }
  109.  
  110. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  111. //    Ñ    ~CButton
  112. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  113.  
  114. CButton::~CButton()
  115. {
  116.     if (mButtonMask != NULL)
  117.         ::DisposeRgn(mButtonMask);
  118.         
  119.     if (mGraphicHandle != NULL)
  120.         ::DisposeCIcon(mGraphicHandle);
  121. }
  122.  
  123. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  124. //    Ñ    InitBevelButton
  125. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  126.  
  127. void CButton::FinishCreateSelf(void)
  128. {
  129.     LControl::FinishCreateSelf();
  130.     
  131.     Rect theButtonRect;
  132.     CalcLocalFrameRect(theButtonRect);
  133.     
  134.     mButtonMask = ::NewRgn();
  135.     ThrowIfNULL_(mButtonMask);
  136.     
  137.     ::OpenRgn();
  138.     ::FrameRoundRect(&theButtonRect, mOvalWidth, mOvalHeight);
  139.     ::CloseRgn(mButtonMask);
  140. }
  141.  
  142. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  143. //    Ñ    Draw
  144. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  145.  
  146. void CButton::Draw(RgnHandle inSuperDrawRgnH)
  147. {
  148.     Rect theFrame;
  149.     if ((mVisible == triState_On) && CalcPortFrameRect(theFrame) &&
  150.             ((inSuperDrawRgnH == nil) || RectInRgn(&theFrame, inSuperDrawRgnH)) && FocusDraw())
  151.         {
  152.         PortToLocalPoint(topLeft(theFrame));    // Get Frame in Local coords
  153.         PortToLocalPoint(botRight(theFrame));
  154.  
  155.         if (ExecuteAttachments(msg_DrawOrPrint, &theFrame))
  156.             {
  157.             Boolean bDidDraw = false;
  158.  
  159.             StColorPenState thePenSaver;
  160.             StColorPenState::Normalize();
  161.             
  162.             // Fail safe offscreen drawing
  163.             StValueChanger<EDebugAction> okayToFail(gDebugThrow, debugAction_Nothing);
  164.             try
  165.                 {            
  166.                 LGWorld theOffWorld(theFrame, 0, useTempMem);
  167.  
  168.                 if (!theOffWorld.BeginDrawing())
  169.                     throw memFullErr;
  170.                     
  171.                 DrawSelf();
  172.                     
  173.                 theOffWorld.EndDrawing();
  174.                 theOffWorld.CopyImage(GetMacPort(), theFrame, srcCopy, mButtonMask);
  175.                 bDidDraw = true;
  176.                 }
  177.             catch (...)
  178.                 {
  179.                 //     & draw onscreen
  180.                 }
  181.  
  182.             if (!bDidDraw)
  183.                 {
  184. // FIX ME!!! the mask is not calculated yet!!!!!
  185.                 ::SetClip(mButtonMask);
  186.                 DrawSelf();
  187.                 }
  188.             }
  189.         }
  190. }
  191.  
  192. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  193. //    Ñ    PrepareDrawButton
  194. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  195.  
  196. void CButton::PrepareDrawButton(void)
  197. {
  198.     CalcLocalFrameRect(mCachedButtonFrame);
  199.  
  200.     // Calculate the drawing mask region.
  201.     ::OpenRgn();
  202.     ::FrameRoundRect(&mCachedButtonFrame, mOvalWidth, mOvalHeight);
  203.     ::CloseRgn(mButtonMask);
  204.     
  205.     CalcTitleFrame();
  206.     if ( mGraphicID != 0 )
  207.         CalcGraphicFrame();
  208. }
  209.  
  210. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  211. //    Ñ    CalcTitleFrame
  212. //
  213. //    This calculates the bounding box of the title (if any).  This is useful
  214. //    for both the string placement, as well as position the button graphic
  215. //    (again, if any).
  216. //
  217. //    Note that this routine sets the text traits for the ensuing draw.  If
  218. //    you override this method, make sure that you're doing the same.
  219. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  220.  
  221. void CButton::CalcTitleFrame(void)
  222. {
  223.     if (mTitle.Length() == 0)
  224.         return;
  225.  
  226.     UTextTraits::SetPortTextTraits(mTitleTraitsID);
  227.  
  228.     FontInfo theInfo;
  229.     ::GetFontInfo(&theInfo);
  230.     mCachedTitleFrame.top = mCachedButtonFrame.top;
  231.     mCachedTitleFrame.left = mCachedButtonFrame.left;        
  232.     mCachedTitleFrame.right = mCachedTitleFrame.left + ::StringWidth(mTitle);;
  233.     mCachedTitleFrame.bottom = mCachedTitleFrame.top + theInfo.ascent + theInfo.descent + theInfo.leading;;
  234.  
  235.     UGraphicGizmos::AlignRectOnRect(mCachedTitleFrame, mCachedButtonFrame, mTitleAlignment);
  236.     UGraphicGizmos::PadAlignedRect(mCachedTitleFrame, mTitlePadPixels, mTitleAlignment);
  237. }
  238.  
  239. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  240. //    Ñ    CalcGraphicFrame
  241. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  242.  
  243. void CButton::CalcGraphicFrame(void)
  244. {
  245.     if ( mGraphicID == 0 )
  246.         return;
  247.     
  248.     // The container for the graphic starts out as the whole
  249.     // button area.
  250.     Rect theContainerFrame = mCachedButtonFrame;
  251.  
  252.     Rect theImageFrame;
  253.     if (mGraphicType == 'cicn' && mGraphicHandle != NULL)
  254.         theImageFrame = (**mGraphicHandle).iconPMap.bounds;
  255.     else if (mGraphicType == 'ICN#')
  256.         {
  257.         CIconFamily theFamily(GetGraphicID());
  258.         theFamily.CalcBestSize(theContainerFrame);
  259.         theImageFrame = theFamily;
  260.         }
  261.     else
  262.         theImageFrame = theContainerFrame;
  263.     
  264.     UGraphicGizmos::AlignRectOnRect(theImageFrame, theContainerFrame, mGraphicAlignment);
  265.     UGraphicGizmos::PadAlignedRect(theImageFrame, mGraphicPadPixels, mGraphicAlignment);
  266.     mCachedGraphicFrame = theImageFrame;
  267. }
  268.  
  269. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  270. //    Ñ    FinalizeDrawButton
  271. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  272.  
  273. void CButton::FinalizeDrawButton(void)
  274. {
  275. }
  276.  
  277. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  278. //    Ñ    DrawSelf
  279. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  280.  
  281. void CButton::DrawSelf(void)
  282. {
  283.     PrepareDrawButton();
  284.  
  285.     DrawButtonContent();
  286.  
  287.     if (mTitle.Length() > 0)
  288.         DrawButtonTitle();
  289.  
  290.     if (GetGraphicID() != 0)
  291.         DrawButtonGraphic();
  292.             
  293.     if (!IsEnabled() || !IsActive())
  294.         DrawSelfDisabled();
  295.             
  296.     FinalizeDrawButton();
  297. }
  298.  
  299. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  300. //    Ñ    DrawSelfDisabled
  301. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  302.  
  303. void CButton::DrawSelfDisabled(void)
  304. {
  305. }
  306.  
  307. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  308. //    Ñ    DrawButtonContent
  309. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  310.  
  311. void CButton::DrawButtonContent(void)
  312. {
  313. }
  314.  
  315. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  316. //    Ñ    
  317. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  318.  
  319. void CButton::DrawButtonTitle(void)
  320. {
  321.     StColorPenState::Normalize();
  322.     
  323.     if (IsTrackInside() || GetValue() == Button_On)
  324.         ::OffsetRect(&mCachedTitleFrame, 1, 1);
  325.  
  326.     UGraphicGizmos::PlaceStringInRect(mTitle, mCachedTitleFrame, teCenter, teCenter);
  327. }
  328.  
  329. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  330. //    Ñ    
  331. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  332.  
  333. void CButton::DrawButtonGraphic(void)
  334. {
  335.     if (IsTrackInside() || (GetValue() == Button_On))
  336.         ::OffsetRect(&mCachedGraphicFrame, 1, 1);
  337.  
  338.     if (mGraphicType == 'cicn' && mGraphicHandle != NULL)
  339.         {
  340.         ::PlotCIcon(&mCachedGraphicFrame, mGraphicHandle);
  341.         }
  342.     else if (mGraphicType == 'ICN#')
  343.         {
  344.         CIconFamily theFamily(GetGraphicID());
  345.         theFamily.Plot(mCachedGraphicFrame, mGraphicAlignment);
  346.         }
  347.     else
  348.         {
  349.         ::FillRect(&mCachedGraphicFrame, &UQDGlobals::GetQDGlobals()->ltGray);
  350.         ::FrameRect(&mCachedGraphicFrame);
  351.         }
  352. }
  353.  
  354.  
  355. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  356. //    Ñ
  357. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  358.  
  359. void CButton::ActivateSelf(void)
  360. {
  361.     if (FocusExposed())
  362.         {
  363.         FocusDraw();
  364.         Draw(NULL);
  365.         
  366.         Rect theFrame;
  367.         CalcLocalFrameRect(theFrame);
  368.         ::ValidRgn(mButtonMask);
  369.         }
  370. }
  371.  
  372. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  373. //    Ñ
  374. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  375.  
  376. void CButton::DeactivateSelf(void)
  377. {
  378.     if (FocusExposed())
  379.         {
  380.         FocusDraw();
  381.         Draw(NULL);
  382.         
  383.         Rect theFrame;
  384.         CalcLocalFrameRect(theFrame);
  385.         ::ValidRgn(mButtonMask);
  386.         }
  387. }
  388.  
  389. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  390. //    Ñ
  391. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  392.  
  393. void CButton::EnableSelf(void)
  394. {
  395.     if (FocusExposed())
  396.         {
  397.         FocusDraw();
  398.         Draw(NULL);
  399.         }
  400. }
  401.  
  402. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  403. //    Ñ
  404. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  405.  
  406. void CButton::DisableSelf(void)
  407. {
  408.     if (FocusExposed())
  409.         {
  410.         FocusDraw();
  411.         Draw(NULL);
  412.         }
  413. }
  414.  
  415. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  416. //    Ñ    HotSpotAction
  417. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  418.  
  419. void CButton::HotSpotAction(short /* inHotSpot */, Boolean inCurrInside, Boolean inPrevInside)
  420. {
  421.     if (inCurrInside != inPrevInside)
  422.         {
  423.         SetTrackInside(inCurrInside);
  424.         Draw(NULL);
  425.         }
  426. }
  427.  
  428. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  429. //    Ñ    HotSpotResult
  430. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  431.  
  432. void CButton::HotSpotResult(Int16 inHotSpot)
  433. {
  434.     switch (GetBehaviour())
  435.         {
  436.         case eBehaviour_Button:
  437.             {
  438.             // Undo Button hilighting
  439.             HotSpotAction(inHotSpot, false, true);
  440.             // Although value doesn't change, send message to inform Listeners
  441.             // that button was clicked
  442.             BroadcastValueMessage();
  443.             }
  444.             break;
  445.             
  446.         case eBehaviour_Radio:
  447.             {
  448.             // Leave the button down, and force the value on
  449.             SetTrackInside(false);
  450.             SetValue(Button_On);
  451.             }
  452.             break;
  453.                 
  454.         case eBehaviour_Toggle:
  455.             {
  456.             // Leave the button down, and toggle the value
  457.             SetTrackInside(false);
  458.             SetValue(Button_On - mValue);
  459.             }
  460.             break;
  461.             
  462.         default:
  463.             Assert_(false);
  464.             break;
  465.         }    
  466. }
  467.  
  468. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  469. //    Ñ    SetValue
  470. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  471.  
  472. void CButton::SetValue(Int32 inValue)
  473. {
  474.     if (inValue < mMinValue)        // Enforce min/max range
  475.         inValue = mMinValue;
  476.     else if (inValue > mMaxValue)
  477.         inValue = mMaxValue;
  478.  
  479.     if (mValue != inValue)
  480.         {                            //    If value is not the current value
  481.         mValue = inValue;            //  Store new value
  482.         FocusDraw();
  483.         Draw(NULL);
  484.         BroadcastValueMessage();    //  Inform Listeners of value change
  485.         
  486.         if (IsBehaviourRadio())
  487.             BroadcastMessage(msg_ControlClicked, (void*)this);
  488.         }
  489.  
  490. }
  491.  
  492. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  493. //    Ñ    GetDescriptor
  494. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  495.  
  496. StringPtr CButton::GetDescriptor(Str255 outDescriptor) const
  497. {
  498.     ::BlockMoveData(&mTitle[0], &outDescriptor[0], mTitle.Length() + 1);
  499.     return (StringPtr)&mTitle[0];
  500. }
  501.  
  502. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  503. //    Ñ    SetDescriptor
  504. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  505.  
  506. void CButton::SetDescriptor(ConstStr255Param inDescriptor)
  507. {
  508.     mTitle = inDescriptor;
  509. }
  510.  
  511. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  512. //    Ñ    SetGraphicID
  513. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  514.  
  515. void CButton::SetGraphicID(ResIDT inResID)
  516. {
  517.     // This no longer throws an exception if a requested cicn does not
  518.     // exist, to support CPatternButtons without multiple graphics.
  519.     if (inResID != mGraphicID)
  520.         {
  521.         CIconHandle graphicHandle = NULL;
  522.         
  523.         if (mGraphicType == 'cicn')
  524.             {        
  525.             graphicHandle = ::GetCIcon(inResID);
  526.             if (graphicHandle == NULL)
  527.                 return;
  528.             }
  529.         
  530.         if (mGraphicHandle != NULL)
  531.             ::DisposeCIcon(mGraphicHandle);
  532.         
  533.         mGraphicHandle = graphicHandle;
  534.         
  535.         }
  536.  
  537.     mGraphicID = inResID;
  538. }
  539.  
  540. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  541. //    Ñ    GetGraphicID
  542. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  543.  
  544. ResIDT CButton::GetGraphicID(void) const
  545. {
  546.     return mGraphicID;
  547. }
  548.  
  549. #pragma mark -
  550.  
  551. // ---------------------------------------------------------------------------
  552. //        Ñ HandleEnablingPolicy
  553. // ---------------------------------------------------------------------------
  554.  
  555. void
  556. CButton::HandleEnablingPolicy()
  557. {
  558.     LCommander* theTarget        = LCommander::GetTarget();
  559.     MessageT    command            = GetValueMessage();
  560.     Boolean     enabled            = false;
  561.     Boolean        usesMark        = false;
  562.     Str255        outName;
  563.     Char16        outMark;
  564.         
  565.     if (!CTargetedUpdateMenuRegistry::UseRegistryToUpdateMenus() ||
  566.             CTargetedUpdateMenuRegistry::CommandInRegistry(command))
  567.     {
  568.         if (!IsActive() || !IsVisible())
  569.             return;
  570.             
  571.         if (!theTarget)
  572.             return;
  573.         
  574.         theTarget->ProcessCommandStatus(command, enabled, usesMark, outMark, outName);
  575.         
  576.         if (enabled)
  577.         {
  578.             Enable();
  579.         }
  580.         else
  581.         {
  582.             Disable();
  583.         }
  584.         
  585.         // This code not only enables and disables toolbar buttons (above)
  586.         // but also (if a toggle button) to set the correct state (pushed or not).
  587.         // The code below was added for use in the editor; other areas may
  588.         // want this functionality.  This could also be done in a subclass... 
  589.         
  590.         if (usesMark)
  591.         {
  592.             if (IsBehaviourToggle())
  593.             {
  594.                 StSetBroadcasting setBroadcasting(this, false);    // Stop broadcasting while we change the value
  595.  
  596.                 // Why the cast here - why? If we really want to execute LControl's SetValue
  597.                 // and not a derived class, then explain it in the code!
  598.                 
  599.                 ((LControl *) this)->SetValue (outMark == checkMark ? Button_On : Button_Off);    
  600.                                         // hilite == true if there's a ├
  601.             }
  602.         }
  603.     }
  604. }