_BUILDING A SOM OPENDOC PART_ by Robert Orfali and Dan Harkey Listing One /*-------- Smiley.IDL for Smiley OpenDoc part (Excerpted) -------------*/ #ifndef _SMILEYPRT_ #define _SMILEYPRT_ #ifndef _SIMPLPRT_ #include #endif #ifdef __PRIVATE__ // Implementation Types typedef long HPS; typedef long Rect; #endif interface SmileyPart : SimplePart { #ifdef __PRIVATE__ void CommonInit(in ODStorageUnit storageUnit); void DrawSmileyFace(in HPS hpsDraw, in Rect frameRect); void SetOrigin(in ODFacet facet); #endif #ifdef __SOMIDL__ implementation { functionprefix = SmileyPart; majorversion = 1; minorversion = 0; #ifdef __PRIVATE__ releaseorder: CommonInit,DrawSmileyFace,SetOrigin; #endif override: InitPart, InitPartFromStorage, Draw, Externalize, HandleEvent, RemoveDisplayFrame; #ifdef __PRIVATE__ ODSession session; ODStorageUnit storageUnit; ODFocusSet focusSet; ODTypeToken selectionFocus; ODTypeToken menuFocus; ODTypeToken keyFocus; ODBoolean smile; #endif }; #endif }; #endif // _SMILEYPRT_ Listing Two /*---- Smiley example implemented in OpenDoc for OS/2. (Excerpted code.) --- */ #include "os2.h" #include "smiley.xih" //---- InitPart (OD Method): Called when part first created ---- SOM_Scope void SOMLINK SmileyPartInitPart(SmileyPart *somSelf, Environment *ev,ODStorageUnit* storageUnit) { SmileyPartData *somThis = SmileyPartGetData(somSelf); SmileyPartMethodDebug("SmileyPart","SmileyPartInitPart"); if (somSelf->IsInitialized(ev)) return; SmileyPart_parent_SimplePart_InitPart(somSelf, ev, storageUnit); somSelf->CommonInit(ev, storageUnit); _smile = TRUE; storageUnit->AddProperty(ev, kODPropSmile)->AddValue(ev, kODBoolean); } //---- InitPartFromStorage (OD Method): Called during part internalization ---- SOM_Scope void SOMLINK SmileyPartInitPartFromStorage(SmileyPart *somSelf, Environment *ev,ODStorageUnit* storageUnit) { SmileyPartData *somThis = SmileyPartGetData(somSelf); SmileyPartMethodDebug("SmileyPart","SmileyPartInitPartFromStorage"); if (somSelf->IsInitialized(ev)) return; somSelf->InitPersistentObjectFromStorage(ev, storageUnit); somSelf->CommonInit(ev, storageUnit); storageUnit->Focus(ev, kODPropSmile,kODPosUndefined, kODBoolean,0,kODPosUndefined); storageUnit->GetValue(ev, sizeof(_smile), &_smile); } //-SmileyPartCommonInit (Private Method) Called by InitPart/InitPartFromStorage SOM_Scope void SOMLINK SmileyPartCommonInit(SmileyPart *somSelf, Environment *ev,ODStorageUnit* storageUnit) { SmileyPartData *somThis = SmileyPartGetData(somSelf); SmileyPartMethodDebug("SmileyPart","SmileyPartCommonInit"); _session = storageUnit->GetSession(ev); // Record session and _storageUnit = storageUnit; // storage unit for later // create and initialize the focus set _focusSet = new ODFocusSet(); _focusSet->InitFocusSet(ev); _selectionFocus = _session->Tokenize(ev, kODSelectionFocus); _menuFocus = _session->Tokenize(ev, kODMenuFocus); _keyFocus = _session->Tokenize(ev, kODKeyFocus); _focusSet->Add(ev, _selectionFocus); _focusSet->Add(ev, _menuFocus); _focusSet->Add(ev, _keyFocus); } //---- Draw (OD Method): Called to Render Part ----- SOM_Scope void SOMLINK SmileyPartDraw(SmileyPart *somSelf, Environment *ev, ODFacet* facet, ODShape* invalidShape) { SmileyPartData *somThis = SmileyPartGetData(somSelf); SmileyPartMethodDebug("SmileyPart","SmileyPartDraw"); // get presentation space HPS hpsDraw = facet->GetCanvas(ev)->GetPlatformCanvas(ev); GpiSavePS(hpsDraw); GpiResetPS(hpsDraw, GRES_ATTRS); // get frame and determine part rectangle ODFrame* displayFrame = facet->GetFrame(ev); HRGN frameRgn = displayFrame->GetFrameShape(ev)->GetRegion(ev); Rect frameRect; GpiQueryRegionBox(hpsDraw, frameRgn, &frameRect); // set up clipping HRGN saveClip; ODShape* clipShape = new ODShape; clipShape->CopyFrom(ev, facet->GetAggregateClipShape(ev)); clipShape->Transform(ev, facet->GetContentTransform(ev)); HRGN clip = clipShape->GetRegion(ev); GpiSetClipRegion(hpsDraw, clip, &saveClip); // set part origin somSelf->SetOrigin(ev, facet); // Draw the Smiley Face somSelf->DrawSmileyFace(ev, hpsDraw, frameRect); // Cleanup and return GpiRestorePS(hpsDraw, -1); GpiSetClipRegion(hpsDraw, 0, &saveClip); delete clipShape; } //--- DrawSmileyFace (Private Method): Called by Draw to render SmileyFace --- SOM_Scope void SOMLINK SmileyPartDrawSmileyFace(SmileyPart *somSelf, Environment *ev,HPS hpsDraw,Rect frameRect) { SmileyPartData *somThis = SmileyPartGetData(somSelf); SmileyPartMethodDebug("SmileyPart","SmileyPartDrawSmileyFace"); // determine part center and smiley radius POINTL ptlCenter = {frameRect.xRight/2, frameRect.yTop/2}; LONG radius = min(frameRect.xRight/2, frameRect.yTop/2)*.97; // paint white background for smiley face part GpiSetColor ( hpsDraw, CLR_WHITE ); POINTL ptlBox = {frameRect.xRight, frameRect.yTop}; GpiBox(hpsDraw, DRO_FILL, &ptlBox, 0, 0); // Draw Smiley Face Background GpiSetColor ( hpsDraw, CLR_YELLOW ); GpiSetCurrentPosition(hpsDraw , &ptlCenter); GpiFullArc(hpsDraw , DRO_OUTLINEFILL , MAKEFIXED (radius , 0 ) ) ; // Initialize Line Characteristics GpiSetColor ( hpsDraw, CLR_BLACK); GpiSetPattern(hpsDraw, PATSYM_SOLID); GpiSetLineWidthGeom(hpsDraw, radius*.07); GpiSetLineEnd(hpsDraw, LINEEND_ROUND); // Draw Smiley Face Outline GpiBeginPath(hpsDraw, 1); GpiFullArc(hpsDraw , DRO_OUTLINE, MAKEFIXED (radius , 0 ) ) ; if (_smile) // Draw a Smiling Mouth { POINTL ptlSmileY" = {ptlCenter.x-(radius*.6), ptlCenter.y-(radius*.3), ptlCenter.x, ptlCenter.y-(radius*.7), ptlCenter.x+(radius*.6), ptlCenter.y-(radius*.3)}; GpiSetCurrentPosition(hpsDraw , &ptlSmile[0]); GpiPointArc(hpsDraw, &ptlSmile[1]); } else // Draw a Sad Mouth { POINTL ptlSad[] = {ptlCenter.x-(radius*.6), ptlCenter.y-(radius*.6), ptlCenter.x, ptlCenter.y-(radius*.5), ptlCenter.x+(radius*.6), ptlCenter.y-(radius*.6)}; GpiSetCurrentPosition(hpsDraw , &ptlSad[0]); GpiPointArc(hpsDraw, &ptlSad[1]); } GpiEndPath(hpsDraw); GpiStrokePath(hpsDraw, 1, 0); // Draw Left Eye POINTL ptlLEye = {ptlCenter.x-radius*.3, ptlCenter.y+radius*.3}; GpiSetCurrentPosition(hpsDraw , &ptlLEye); GpiFullArc(hpsDraw , DRO_OUTLINEFILL , MAKEFIXED (radius*.07, 0 ) ) ; // Draw Right Eye POINTL ptlREye = {ptlCenter.x+radius*.3, ptlCenter.y+radius*.3}; GpiSetCurrentPosition(hpsDraw , &ptlREye); GpiFullArc(hpsDraw , DRO_OUTLINEFILL , MAKEFIXED (radius*.07, 0 ) ) ; // Draw Nose POINTL ptlNose = {ptlCenter.x, ptlCenter.y-radius*.2}; GpiSetCurrentPosition(hpsDraw , &ptlNose); GpiFullArc(hpsDraw , DRO_OUTLINEFILL , MAKEFIXED (radius*.07, 0 ) ) ; } //---- SetOrigin (Private Method): Called by Draw to position Smiley Face ---- SOM_Scope void SOMLINK SmileyPartSetOrigin(SmileyPart *somSelf, Environment *ev,ODFacet* facet) { SmileyPartData *somThis = SmileyPartGetData(somSelf); SmileyPartMethodDebug("SmileyPart","SmileyPartSetOrigin"); ODTransform* localToGlobal = facet->GetContentTransform(ev); HPS hps = facet->GetCanvas(ev)->GetPlatformCanvas(ev); MATRIXLF mtx; facet->GetContentTransform(ev)->GetMATRIXLF(ev, &mtx); GpiSetModelTransformMatrix(hps, 9, &mtx, TRANSFORM_REPLACE); facet->GetCanvas(ev)->ReleasePlatformCanvas(ev); } //--- HandleEvent (OD Method): Called when the part receives a UI event ---- SOM_Scope ODBoolean SOMLINK SmileyPartHandleEvent(SmileyPart *somSelf, Environment *ev,ODEventData* event,ODFrame* frame,ODFacet* facet) { SmileyPartData *somThis = SmileyPartGetData(somSelf); SmileyPartMethodDebug("SmileyPart","SmileyPartHandleEvent"); switch (event->msg) { case WM_BUTTON1DOWN: // Activate the Part if (_session->GetArbitrator(ev)-> RequestFocusSet(ev, _focusSet,frame)) somSelf->FocusAcquired(ev, _selectionFocus, frame); return kODTrue; case WM_BUTTON2DOWN: // Toggle Smile/Sad Face _smile = !_smile; frame->Invalidate(ev, kODNULL); return kODTrue; default: return kODFalse; } }