home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-06-30 | 10.2 KB | 329 lines | [TEXT/CWIE] |
- // ===========================================================================
- // LAGAIconButton.cp
- // ===========================================================================
- // “Apple Grayscale Appearance” compliant (almost) icon button
- // Copyright © 1996 Chrisoft (Christophe ANDRES) All rights reserved.
- //
- // You may use this source code in any application (commercial, shareware, freeware,
- // postcardware, etc), but not remove this notice (no need to acknowledge the use of
- // this class in the about box)
- // You may not sell this source code in any form. This source code may be placed on
- // publicly accessable archive sites and source code disks. It may not be placed on
- // profit archive sites and source code disks without the permission of the author,
- // Christophe ANDRES.
- //
- // This source code is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- //
- // If you make any change or improvement on this class, please send the improved/changed
- // version to : chrisoft@calva.net or Christophe ANDRES
- // 20, rue Prosper Mérimée
- // 67100 STRASBOURG
- // FRANCE
- //
- // ===========================================================================
- // LAGAIconButton.h <- double-click + Command-D to see class declaration
- //
- // LAGAIconButton is my implementation of the “Apple Grayscale Appearance for System 7.5”
- // Icon Buttons with the exception of the pressed state. The pressed state is my own kind,
- // because I (and my customers) found it nicer than Apple's ;-)
- //
- // The button supports icon families or cicn (use 'ICN#' and 'cicn' in constructor. To
- // get the best result, the size of the button should be 5 pixels more than the icon (so for
- // a 32X32 icon, the minimum size should be 37X37)
- //
- // if mRadioBehavior is set, the Icon Button acts as a RadioButton and can be used with
- // a radio group
- //
- // This class requires AGAColors.cp to be present in your project
- //
- // Version : 1.2
- //
- // Change History (most recent first, date in US form : mm/dd/yy):
- //
- // 06/30/96 ca Public release of version 1.2
- // 06/27/96 ca Changed checks for disabled state (check on triState_On instead of triState_Off)
- // in order that triState_Latent state is drawn as disabled
- // 06/04/96 ca Added static RegisterClass for easier class registration
- // Increased version to 1.2
- // 06/01/96 ms Changes brought by Marco Sandri <msandri@mbox.vol.it>
- // Changes made to avoid icon "flicker" during pressing
- // 05/15/96 ca Replaced HasAGAColors by PaneInColor (see note in AGAColors.h)
- // 05/11/96 ca Increased version to 1.1
- // Added copy constructor
- // Added "on the fly" constructor
- // Replaced UEnvironment::HasFeature(env_SupportsColor) with HasAGAColors
- // Added change history
- // 04/22/96 ca class made available by Christophe ANDRES <chrisoft@calva.net>
- // (version 1.0)
- //
- // To Do:
- //
-
- #include "LAGAIconButton.h"
- #include "AGAColors.h"
- #include <UDrawingState.h>
- #include <PP_Messages.h>
- #include <PP_Resources.h>
-
- // begin <06/04/96 ca>
- void LAGAIconButton::RegisterClass ()
-
- {
- URegistrar::RegisterClass(LAGAIconButton::class_ID, (ClassCreatorFunc)LAGAIconButton::CreateAGAIconButtonStream);
- }
- // end <06/04/96 ca>
-
- LAGAIconButton* LAGAIconButton::CreateAGAIconButtonStream (LStream *inStream)
-
- {
- return(new LAGAIconButton(inStream));
- }
-
- //-------Constructors-------------------------------------------------------------------------------------------------
-
- LAGAIconButton::LAGAIconButton ()
-
- {
- mIconType = 'ICN#';
- mIconID = resID_Undefined;
- mIcon = nil;
- mRadioBehavior = false;
- }
-
- LAGAIconButton::LAGAIconButton (LStream *inStream) : LControl(inStream)
-
- {
- unsigned char radioBehavior;
-
- mIcon = nil;
- inStream->ReadData(&mIconType, sizeof(OSType));
- inStream->ReadData(&mIconID, sizeof(ResIDT));
- inStream->ReadData(&radioBehavior, sizeof(unsigned char));
- mRadioBehavior = (radioBehavior != 0);
- if (mRadioBehavior)
- mMaxValue = 1;
- if (mIconType != 'cicn' && mIconType != 'ICN#')
- delete this;
- }
-
- // begin <05/11/96 ca>
- LAGAIconButton::LAGAIconButton (const LAGAIconButton &inOriginal) : LControl(inOriginal)
-
- {
- mIcon = nil;
- mIconType = inOriginal.mIconType;
- mIconID = inOriginal.mIconID;
- mRadioBehavior = inOriginal.mRadioBehavior;
- if (mRadioBehavior)
- mMaxValue = 1;
- if (mIconType != 'cicn' && mIconType != 'ICN#')
- delete this;
- }
-
- LAGAIconButton::LAGAIconButton (const SPaneInfo &inPaneInfo, MessageT inClickedMessage, OSType inIconType,
- ResIDT inIconID, Boolean inRadioButtonBehavior)
- : LControl(inPaneInfo, inClickedMessage, 0, 0, 1)
- {
- mIcon = nil;
- mIconType = inIconType;
- mIconID = inIconID;
- mRadioBehavior = inRadioButtonBehavior;
- if (mRadioBehavior)
- mMaxValue = 1;
- if (mIconType != 'cicn' && mIconType != 'ICN#')
- delete this;
- }
- // end <05/11/96 ca>
-
- LAGAIconButton::~LAGAIconButton ()
-
- {
- if (mIcon != nil)
- DisposeCIcon(mIcon);
- }
-
- //-------Utilities--------------------------------------------------------------------------------------------------
-
- void LAGAIconButton::HotSpotResult (Int16 inHotSpot)
-
- {
- // Undo Button hilighting
- if (!mRadioBehavior)
- {
- HotSpotAction(inHotSpot, false, true);
- BroadcastValueMessage(); // Although value doesn't change,
- // send message to inform Listeners
- // that button was clicked
- }
- else
- {
- // In the Mac interface, clicking on a RadioButton always
- // turns it on (or leaves it on). The standard way to turn
- // off a RadioButton is to turn on another one in the
- // same Radio Group. A Radio Group will normally be a
- // Listener of a RadioButton.
-
- if (mValue != Button_On) // <06/01/96 ms>
- SetValue(Button_On);
- }
- }
-
- void LAGAIconButton::HotSpotAction (Int16 inHotSpot, Boolean inCurrInside, Boolean inPrevInside)
-
- {
- // Draw if cursor moved from IN to OUT
- // or from OUT to IN
- if (inCurrInside != inPrevInside && (!mRadioBehavior || mValue != Button_On)) // <06/01/96 ms>
- {
- FocusDraw();
- DrawGraphic(inCurrInside);
- }
- }
-
- void LAGAIconButton::SetValue (Int32 inValue)
-
- {
-
- if (!mRadioBehavior)
- {
- LControl::SetValue(inValue);
- }
- else
- {
- if (inValue < mMinValue)
- inValue = mMinValue;
- else
- if (inValue > mMaxValue)
- inValue = mMaxValue;
- mValue = inValue;
- // If turning RadioButton on, broadcast message so that the
- // RadioGroup (if present) will turn off the other RadioButtons
- // in the group.
-
- if (inValue == Button_On)
- {
- BroadcastValueMessage();
- BroadcastMessage(msg_ControlClicked, (void*) this);
- }
- Draw(nil); // <06/01/96 ms>
- }
- }
-
- //-------Drawers----------------------------------------------------------------------------------------------------
-
- void LAGAIconButton::DrawSelf ()
-
- {
- DrawGraphic(false);
- }
-
- void LAGAIconButton::DrawGraphic (Boolean inPushed)
-
- {
- StColorPenState theState;
- Rect frame;
- long theValue = (mRadioBehavior ? mValue : 0);
- Boolean down = inPushed || (theValue != 0);
- Boolean hasColor = ::PaneInColor(this); // <05/15/96 ca>
-
- theState.Normalize();
- CalcLocalFrameRect(frame);
-
- // Draw the black frame;
- ::MoveTo(frame.left + 1, frame.top);
- ::LineTo(frame.right - 2, frame.top);
- ::MoveTo(frame.right - 1, frame.top + 1);
- ::LineTo(frame.right - 1, frame.bottom - 2);
- ::MoveTo(frame.right - 2, frame.bottom - 1);
- ::LineTo(frame.left + 1, frame.bottom - 1);
- ::MoveTo(frame.left, frame.bottom - 2);
- ::LineTo(frame.left, frame.top + 1);
-
- // Draw the inside (w/o the Icon)
- ::InsetRect(&frame, 1, 1);
- if (hasColor)
- {
- ApplyForeAndBackColors();
- if (down)
- ::RGBBackColor(&gAGAColorArray[4]);
- }
- ::EraseRect(&frame);
-
- // Draw the shadows
- if (hasColor)
- {
- ::RGBForeColor(&gAGAColorArray[7]);
- if (down)
- {
- ::MoveTo(frame.left, frame.bottom - 1);
- ::LineTo(frame.left, frame.top);
- ::LineTo(frame.right - 1, frame.top);
- }
- else
- {
- ::MoveTo(frame.right - 1, frame.top);
- ::LineTo(frame.right - 1, frame.bottom - 1);
- ::LineTo(frame.left, frame.bottom - 1);
- ::MoveTo(frame.right - 2, frame.top + 1);
- ::LineTo(frame.right - 2, frame.bottom - 2);
- ::LineTo(frame.left + 1, frame.bottom - 2);
- ::ForeColor(whiteColor);
- ::MoveTo(frame.left, frame.bottom - 2);
- ::LineTo(frame.left, frame.top);
- ::LineTo(frame.right - 2, frame.top);
- }
- }
-
- // Draw the Icon
- SDimension16 theSize;
- Rect drawFrame;
-
- CalcLocalFrameRect(frame);
- GetFrameSize(theSize);
- if (GetIconID() != resID_Undefined)
- if (mIconType == 'cicn')
- {
- if (mIcon == nil)
- mIcon = ::GetCIcon(GetIconID());
- if (mIcon != nil)
- {
- drawFrame = (*mIcon)->iconBMap.bounds;
- if (theSize.width < (drawFrame.right + 5))
- drawFrame.right = theSize.width - 5;
- if (theSize.height < (drawFrame.bottom + 5))
- drawFrame.bottom = theSize.height - 5;
- short hPos = (((theSize.width - drawFrame.right) / 2) + frame.left) + ((down && hasColor) ? 1 : 0);
- short vPos = (((theSize.height - drawFrame.bottom) / 2) + frame.top) + ((down && hasColor) ? 1 : 0);
- drawFrame.left += hPos;
- drawFrame.right += hPos;
- drawFrame.top += vPos;
- drawFrame.bottom += vPos;
-
- ::PlotCIconHandle(&drawFrame, atNone, (mEnabled == triState_On) ? ttNone : ttDisabled, mIcon); // <06/27/96 ca>
- }
- }
- else
- {
- if ((theSize.width < 37) || (theSize.height < 37))
- ::SetRect(&drawFrame, 0, 0, 16, 16);
- else
- ::SetRect(&drawFrame, 0, 0, 32, 32);
- short hPos = (((theSize.width - drawFrame.right) / 2) + frame.left) + ((down && hasColor) ? 1 : 0);
- short vPos = (((theSize.height - drawFrame.bottom) / 2) + frame.top) + ((down && hasColor) ? 1 : 0);
- drawFrame.left += hPos;
- drawFrame.right += hPos;
- drawFrame.top += vPos;
- drawFrame.bottom += vPos;
-
- ::PlotIconID(&drawFrame, atNone, (mEnabled == triState_On) ? ttNone : ttDisabled, GetIconID()); // <06/27/96 ca>
- }
- if (!hasColor && down)
- {
- ::InsetRect(&frame, 1, 1);
- ::InvertRect(&frame);
- }
- }
-
-