// ACCELA Mac toolbox C++ wrapper library // Copyright (C) 2002 David Catmull #pragma once #include "ACarbonEvent.h" #include "XValueType.h" #include #include FW(Carbon,Scrap.h) // --------------------------------------------------------------------------- #pragma mark ReadWritePolicy namespace APrivate { class DoRead { protected: template static bool ReadParam( const ACarbonEvent &inEvent, EventParamName inName, EventParamType inType, T &outParameter) { OSStatus err = inEvent.GetParameter(inName,inType,outParameter); bool exists = true; if (err == eventParameterNotFoundErr) exists = false; else if (err != noErr) throw err; return exists; } }; class DontRead { protected: template static bool ReadParam( const ACarbonEvent &, EventParamName, EventParamType, T &) { return false; } }; class DoWrite { protected: bool mDirty; DoWrite() : mDirty(false) {} void SetDirty() { mDirty = true; } template void WriteParam( ACarbonEvent &inEvent, EventParamName inName, EventParamType inType, const T &inParameter) { if (mDirty) inEvent.SetParameter(inName,inType,inParameter); } }; class DontWrite { protected: void SetDirty() { // How do I make this a compile-time error? throw std::runtime_error("assignment to read-only parameter"); } template void WriteParam( ACarbonEvent &, EventParamName, EventParamType, const T &) {} }; } class AReadOnly : public APrivate::DoRead, public APrivate::DontWrite {}; class AReadWrite : public APrivate::DoRead, public APrivate::DoWrite {}; class AWriteOnly : public APrivate::DontRead,public APrivate::DoWrite {}; // --------------------------------------------------------------------------- #pragma mark AEventParameter template class AEventParameter : public ReadWritePolicy { public: AEventParameter( EventRef inEvent, EventParamName inParamName, EventParamType inParamType = XValueType::GetType()) : mEvent(inEvent),mParamName(inParamName),mParamType(inParamType) { mExists = ReadParam(mEvent,inParamName,inParamType,mParam); } virtual ~AEventParameter() { WriteParam(mEvent,mParamName,mParamType,mParam); } // Maybe change to: // operator typename Loki::TypeTraits::ParameterType() const operator const T&() const { if (!mExists) throw std::runtime_error("parameter doesn't exist yet"); return mParam; } AEventParameter& operator=( const T &inNewValue) { SetDirty(); mParam = inNewValue; mExists = true; return *this; } bool Exists() const { return mExists; } protected: ACarbonEvent mEvent; T mParam; const EventParamName mParamName; const EventParamType mParamType; bool mExists; }; // --------------------------------------------------------------------------- #pragma mark ASpecificParameter template < class T, EventParamName tParamName, EventParamType tParamType, class ReadWritePolicy = AReadOnly> class ASpecificParameter : public AEventParameter { public: explicit ASpecificParameter( EventRef inEvent) : AEventParameter(inEvent,tParamName,tParamType) {} ASpecificParameter& operator=( const T &inNewValue) { AEventParameter::operator=(inNewValue); return *this; } }; template class AParam { public: // General typedef ASpecificParameter Mouse; typedef ASpecificParameter Modifiers; typedef ASpecificParameter ClickActivation; typedef ASpecificParameter Attributes; typedef ASpecificParameter Dimensions; typedef ASpecificParameter Event; // Graphics typedef ASpecificParameter Port; typedef ASpecificParameter Context; // Command typedef ASpecificParameter Command; // Controls typedef ASpecificParameter Control; typedef ASpecificParameter ControlPart; typedef ASpecificParameter SubControl; // Menus typedef ASpecificParameter Menu; typedef ASpecificParameter MenuItem; typedef ASpecificParameter MenuContext; // Windows typedef ASpecificParameter Window; typedef ASpecificParameter WindowPart; typedef ASpecificParameter WindowRegion; // Scrap typedef ASpecificParameter Scrap; typedef ASpecificParameter Drag; }; // --------------------------------------------------------------------------- #pragma mark AGenericParameter template < class T, EventParamType tParamType, class ReadWritePolicy = AReadOnly> class AGenericParameter : public AEventParameter { public: AGenericParameter( EventRef inEvent, EventParamName inParamName) : AEventParameter(inEvent,inParamName,tParamType) {} AGenericParameter& operator=( const T &inNewValue) { AEventParameter::operator=(inNewValue); return *this; } }; template class ATypeParam { public: typedef AGenericParameter< ::Rect,typeQDRectangle,ReadWritePolicy> Rect; typedef AGenericParameter< ::Point,typeQDPoint,ReadWritePolicy> Point; typedef AGenericParameter< ::Boolean,typeBoolean,ReadWritePolicy> Boolean; typedef AGenericParameter< ::Ptr,typePtr,ReadWritePolicy> Ptr; typedef AGenericParameter< ::WindowRef,typeWindowRef,ReadWritePolicy> WindowRef; typedef AGenericParameter< ::MenuRef,typeMenuRef,ReadWritePolicy> MenuRef; typedef AGenericParameter< ::MenuItemIndex,typeMenuItemIndex,ReadWritePolicy> MenuItemIndex; typedef AGenericParameter< ::RgnHandle,typeQDRgnHandle,ReadWritePolicy> RgnHandle; typedef AGenericParameter Enumeration; typedef AGenericParameter< ::ControlPartCode,typeControlPartCode,ReadWritePolicy> ControlPartCode; typedef AGenericParameter< ::GWorldPtr,typeGWorldPtr,ReadWritePolicy> GWorldPtr; typedef AGenericParameter< ::UInt32,typeUInt32,ReadWritePolicy> UInt32; typedef AGenericParameter< ::SInt32,typeSInt32,ReadWritePolicy> SInt32; typedef AGenericParameter< ::SInt16,typeSInt16,ReadWritePolicy> SInt16; };