home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-12-17 | 7.9 KB | 321 lines | [TEXT/CWIE] |
- // =================================================================================
- //
- // CShapesControl.cpp ©1996 Microsoft Corporation All rights reserved.
- //
- // =================================================================================
-
- #include "ocheaders.h"
- #include <math.h>
- #include "CShapesControl.h"
-
- const Int32 DefaultIdleTicks = 60;
- const Uint32 DefaultIdleRefCon = 0;
-
-
- #pragma mark === CShapesControl::Construction & Destruction ===
-
-
- //=--------------------------------------------------------------------------=
- // CShapesControl::CShapesControl
- //=--------------------------------------------------------------------------=
-
- CShapesControl::CShapesControl(void)
- {
- mCurrentShape = ShapeType(BeginShapeType + 1);
- mIsIdling = false;
- mIsPressed = false;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CShapesControl::~CShapesControl
- //=--------------------------------------------------------------------------=
-
- CShapesControl::~CShapesControl()
- {
- }
-
- #pragma mark === CShapesControl::IControl Interface ===
-
-
- //=--------------------------------------------------------------------------=
- // CShapesControl::IControl::Draw
- //=--------------------------------------------------------------------------=
-
- STDMETHODIMP
- CShapesControl::Draw(DrawContext* inContext)
- {
- if (inContext->DrawAspect != DVASPECT_CONTENT)
- return DV_E_DVASPECT;
-
- // we are in a context aspect, be sure we are idling
- StartIdling();
- DrawMe(&inContext->Location);
-
- return S_OK;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CShapesControl::IControl::GetUsedArea
- //=--------------------------------------------------------------------------=
-
- STDMETHODIMP
- CShapesControl::GetUsedArea(PlatformRegion* outUsedArea)
- {
- if (!outUsedArea->Region)
- return E_FAIL;
-
- Rect Bounds;
-
- Bounds.top = Bounds.left = 0;
- Bounds.bottom = mSize.v;
- Bounds.right = mSize.h;
-
- ::OpenRgn();
- switch (mCurrentShape)
- {
- case OvalShapeType:
- ::FrameOval(&Bounds);
- break;
- case TriangleShapeType:
- ::MoveTo(mSize.h/3, 0);
- ::LineTo(0, mSize.v/2);
- ::LineTo(2*mSize.h/3, mSize.v);
- ::LineTo(mSize.h/3, 0);
- break;
- case PentagonShapeType:
- ::MoveTo(mSize.h/2, 0);
- ::LineTo(0, mSize.v/3);
- ::LineTo(mSize.h/3, mSize.v);
- ::LineTo(2*mSize.h/3, mSize.v);
- ::LineTo(mSize.h, mSize.v/3);
- ::LineTo(mSize.h/2, 0);
- break;
- case HexagonShapeType:
- ::MoveTo(mSize.h/2, 0);
- ::LineTo(0, mSize.v/3);
- ::LineTo(0, 2*mSize.v/3);
- ::LineTo(mSize.h/2, mSize.v);
- ::LineTo(mSize.h, 2*mSize.v/3);
- ::LineTo(mSize.h, mSize.v/3);
- ::LineTo(mSize.h/2, 0);
- break;
- case RectangleShapeType:
- default:
- ::FrameRect(&Bounds);
- break;
- }
-
- ::CloseRgn(outUsedArea->Region);
- return S_OK;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CShapesControl::IControl::DoMouse
- //=--------------------------------------------------------------------------=
-
- STDMETHODIMP
- CShapesControl::DoMouse(MouseEventType inMouseET, PlatformEvent* inEvent)
- {
- #pragma unused (inEvent)
- ErrorCode theResult = S_FALSE;
-
- switch (inMouseET)
- {
- case MouseUp:
- mIsPressed = false;
- DrawAllContexts();
- theResult = S_OK;
- break;
-
- case MouseDown:
- mIsPressed = true;
- DrawAllContexts();
- theResult = S_OK;
- break;
- }
-
- return theResult;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CShapesControl::IControl::DoIdle
- //=--------------------------------------------------------------------------=
-
- STDMETHODIMP
- CShapesControl::DoIdle(Uint32 IdleRefCon)
- {
- #pragma unused(IdleRefCon)
- ShapeType PrevShape = mCurrentShape;
-
- mCurrentShape = ShapeType(mCurrentShape + 1);
- if (mCurrentShape >= EndShapeType)
- mCurrentShape = ShapeType(BeginShapeType + 1);
-
- if (PrevShape != mCurrentShape)
- mContainerSiteP->OnChange(UsedAreaChange);
-
- DrawAllContexts();
-
- return S_OK;
- }
-
-
- #pragma mark === CShapesControl::IPersist ===
-
- //=--------------------------------------------------------------------------=
- // CShapesControl::IPersistPropertyBag::IPersistPropertyBag::Load
- //=--------------------------------------------------------------------------=
-
- STDMETHODIMP
- CShapesControl::Load(IPropertyBag* PropertyBag, IErrorLog* ErrorLog)
- {
- ErrorCode ErrCode = S_OK;
-
- LoadTextState(PropertyBag, ErrorLog);
-
- return ErrCode;
- }
-
- //=--------------------------------------------------------------------------=
- // CShapesControl::IPersistPropertyBag::LoadTextState
- //=--------------------------------------------------------------------------=
- // load in our text state for this control.
- //
- // Parameters:
- // IPropertyBag * - [in] property bag to read from
- // IErrorLog * - [in] errorlog object to use with proeprty bag
- //
- // Output:
- // ErrorCode
- //
- STDMETHODIMP
- CShapesControl::LoadTextState(IPropertyBag *PropertyBag,IErrorLog *ErrorLog)
- {
- ErrorCode ECode = S_OK;
- Int32 i;
- VARIANT v;
-
- v.vt = VT_BSTR;
- v.bstrVal = NULL;
-
- // get the starting size
- if (PropertyBag->Read("width", &v, ErrorLog) == S_OK && v.bstrVal)
- {
- ::StringToNum((Uchar8*)v.bstrVal + sizeof(Uint32) - 1, &i);
- mSize.h = i;
- CoTaskMemFree(v.bstrVal);
- }
-
- if (PropertyBag->Read("height", &v, ErrorLog) == S_OK && v.bstrVal)
- {
- ::StringToNum((Uchar8*)v.bstrVal + sizeof(Uint32) - 1, &i);
- mSize.v = i;
- CoTaskMemFree(v.bstrVal);
- }
-
- return ECode;
- }
-
-
- #pragma mark === CShapesControl::protected methods ===
-
- //=--------------------------------------------------------------------------=
- // CShapesControl::StartIdling
- //=--------------------------------------------------------------------------=
-
- Boolean8
- CShapesControl::StartIdling(void)
- {
- if (!mIsIdling)
- mIsIdling = mContainerSiteP->SetIdleTime(DefaultIdleTicks, DefaultIdleRefCon) == S_OK;
-
- return mIsIdling;
- }
-
-
- //=--------------------------------------------------------------------------=
- // CShapesControl::StopIdling
- //=--------------------------------------------------------------------------=
-
- Boolean8
- CShapesControl::StopIdling(void)
- {
- if (mIsIdling && mContainerSiteP->SetIdleTime(RemoveAllIdlers, NULL) == S_OK)
- mIsIdling = false;
-
- return !mIsIdling;
- }
-
-
- #pragma mark === CShapesControl::private methods ===
-
- //=--------------------------------------------------------------------------=
- // CShapesControl::DrawAllContexts
- //=--------------------------------------------------------------------------=
-
- void
- CShapesControl::DrawAllContexts()
- {
- Boolean8 ShouldBeIdling = false;
- Int32 Index = 1;
- DrawContext Context = {BeginPortType};
- UInt32 ContextID;
-
- while ( GetContextID(Index, &ContextID) )
- {
- if (mContainerSiteP->AcquireContext(ContextID, &Context) == S_OK)
- {
- // we could do this by watching context changes, but this is a simple
- // control which ignores such things - so instead we'll just watch this way
- if (Context.DrawAspect == DVASPECT_CONTENT)
- ShouldBeIdling = true;
- DrawMe(&Context.Location);
- mContainerSiteP->ReleaseContext(&Context);
- }
- ++Index;
- }
-
- if (ShouldBeIdling != mIsIdling)
- {
- if (ShouldBeIdling)
- StartIdling();
- else
- StopIdling();
- }
- }
-
-
- //=--------------------------------------------------------------------------=
- // CShapesControl::DrawMe
- //=--------------------------------------------------------------------------=
-
- void
- CShapesControl::DrawMe(Rect *BoundsRect)
- {
- Pattern DrawPattern;
- Rect StartRect;
- RGBColor DrawColor;
- PlatformRegion DrawShape = { NULL };
- DrawShape.Region = ::NewRgn();
-
- GetUsedArea(&DrawShape);
- StartRect.top = StartRect.left = 0;
- StartRect.bottom = mSize.v;
- StartRect.right = mSize.h;
- ::MapRgn(DrawShape.Region, &StartRect, BoundsRect);
-
- if (mIsPressed)
- DrawColor.red = DrawColor.green = DrawColor.blue = 0x0010;
- else
- DrawColor.red = DrawColor.green = DrawColor.blue = 0x8000;
-
- ::RGBForeColor(&DrawColor);
- ::StuffHex(&DrawPattern, "\pffffffffffffffff");
- ::FillRgn(DrawShape.Region, &DrawPattern);
- ::DisposeRgn(DrawShape.Region);
- }
-