// ForearmRough.c #include "ForearmRough.h" #include #include "utils.h" // CP# means Control Point or Handle // // * // * // * CP0 // ********************************* // * // * // *CP1 // * // * // //************************************************************************************** // // Functions for ForearmRough // //************************************************************************************* L_VOID ForearmRough_AddHandle(HANNOBJECT hObject, ANNPOINT aptLine[], pHANDLEDEF pHandleDef) { L_UINT uFlags = ANNHANDLE_LOCATION | ANNHANDLE_CONTAINER_COORDINATES | ANNHANDLE_ID | ANNHANDLE_PEN_COLOR | ANNHANDLE_FILL_COLOR | ANNHANDLE_SHAPE; ANNHANDLE AnnHandle; AnnHandle.uStructSize = sizeof(ANNHANDLE); AnnHandle.nShape = pHandleDef->nShape; AnnHandle.crPen = RGB(0,0,0); AnnHandle.hCursor= NULL; AnnHandle.aptContainer.x = (aptLine[0].x + aptLine[1].x) / 2; AnnHandle.aptContainer.y = (aptLine[0].y + aptLine[1].y) / 2; AnnHandle.nID = pHandleDef->nID; AnnHandle.crFill = pHandleDef->crFill; AnnHandle.uFlags = uFlags; L_AnnAddUserHandle(hObject, &AnnHandle); } #define FOREARMROUGH_NUMPOINTS 2 HANDLEDEF ForearmRough_HandleDef[FOREARMROUGH_NUMPOINTS] = { HANDLE_ID_CP0, ANNHANDLE_SHAPE_CIRCLE, RGB(0,0,0), HANDLE_ID_CP1, ANNHANDLE_SHAPE_CIRCLE, RGB(255,0,128), }; L_VOID ForearmRough_AddUserHandles(HANNOBJECT hObject) { L_INT nCount; ANNPOINT aptLine[2]; HANNOBJECT AnnObjectNeighbors[2]; // this object is made of two lines AnnGetNeighborObjects(hObject, AnnObjectNeighbors, &nCount); AnnSortNeighborObjects(hObject, AnnObjectNeighbors, nCount); // Horizontal line -- swap so that aptLine[0] is to the left aptLine[1] L_AnnGetPoints(AnnObjectNeighbors[0], aptLine); if (aptLine[0].x > aptLine[1].x) SwapAnnPoints(aptLine + 0, aptLine + 1); ForearmRough_AddHandle(AnnObjectNeighbors[0], aptLine, ForearmRough_HandleDef + 0); // Vertical line -- swap so that aptLine[0] is above aptLine[1] L_AnnGetPoints(AnnObjectNeighbors[1], aptLine); if (aptLine[0].y > aptLine[1].y) SwapAnnPoints(aptLine + 0, aptLine + 1); ForearmRough_AddHandle(AnnObjectNeighbors[1], aptLine, ForearmRough_HandleDef + 1); } //*************** ForearmRough Create functions HANNOBJECT ForearmRough_CreateLine(HANNOBJECT hContainer, POINT pt0, POINT pt1, L_UINT uTool, L_INT nID) { HANNOBJECT hLine; L_AnnCreateItem(hContainer, ANNOBJECT_LINE, FALSE, &hLine); L_AnnDefine(hLine, &pt0, ANNDEFINE_BEGINSET); L_AnnDefine(hLine, &pt1, ANNDEFINE_END); AnnSetID(hLine, uTool, nID); //Set tag to identify line 0,1,2 L_AnnSetVisible(hLine, TRUE, 0, NULL); L_AnnSetSelected(hLine, TRUE, 0); HideDefaultHandles(hLine); return hLine; } L_VOID ForearmRough_LButtonDown(HWND hWnd, LPCHILDDATA pData) { L_AnnAddUndoNode(pData->hAutomation); L_AnnCreateItem(pData->hContainer, ANNOBJECT_RECT, FALSE, &pData->ObjectForearmRough.hLineH); L_AnnDefine(pData->ObjectForearmRough.hLineH, &pData->ptStart, ANNDEFINE_BEGINSET); pData->fCapture = TRUE; L_AnnRestrictCursor(pData->hContainer, NULL, NULL, &pData->rcOldClip, TRUE); } L_VOID ForearmRough_MouseMove(LPCHILDDATA pData) { L_AnnDefine(pData->ObjectForearmRough.hLineH, &pData->ptMove, ANNDEFINE_UPDATE); } L_VOID ForearmRough_LButtonUp(LPCHILDDATA pData, L_UINT uTool) { HANNOBJECT hLineH, hLineV; POINT pt0, pt1; LONG xMin, xMax, yMin, yMax; L_AnnDefine(pData->ObjectForearmRough.hLineH, &pData->ptEnd, ANNDEFINE_END); // The object that we just created is a square // Remove from the container and delete L_AnnRemove(pData->ObjectForearmRough.hLineH); L_AnnDestroy(pData->ObjectForearmRough.hLineH, 0); // Get min, max values of x,y xMin = min(pData->ptStart.x, pData->ptEnd.x); xMax = max(pData->ptStart.x, pData->ptEnd.x); yMin = min(pData->ptStart.y, pData->ptEnd.y); yMax = max(pData->ptStart.y, pData->ptEnd.y); // Create horizontal line pt0.x = xMin; pt0.y = (3*yMin + yMax) / 4; pt1.x = xMax; pt1.y = pt0.y; hLineH = ForearmRough_CreateLine(pData->hContainer, pt0, pt1, uTool, 0); // Create vertical line pt0.x = (xMin + 3*xMax) / 4; pt0.y = yMin; pt1.x = pt0.x; pt1.y = yMax; hLineV = ForearmRough_CreateLine(pData->hContainer, pt0, pt1, uTool, 1); // set the default settings from the automation object, and group the objects L_AnnSetAutoDefaults(pData->hAutomation, pData->hContainer, ANNFLAG_SELECTED|ANNFLAG_RECURSE); L_AnnGroup(pData->hContainer, ANNFLAG_SELECTED|ANNFLAG_RECURSE, NULL); // Add user handles ForearmRough_AddUserHandles(hLineH); } //*************** ForearmRough Update functions L_VOID ForearmRough_RestrictPoint(LPCHILDDATA pData, HANNOBJECT hLineH, HANNOBJECT hLineV, POINT ptHandle) { ANNPOINT aptLine[2]; POINT ptLineH[2], ptLineV[2]; RECT rcClip; ANNRECT arcContainer; RECT rcContainer; GetClipCursor(&pData->rcOldClip); rcClip = pData->rcOldClip; // Get min, max X for horizontal line L_AnnGetPoints(hLineH, aptLine); if (aptLine[0].x > aptLine[1].x) SwapAnnPoints(aptLine + 0, aptLine + 1); L_AnnConvert(pData->hContainer, ptLineH, aptLine, 2, ANNCONVERT_TO_CLIENT); // Get min, max Y for vertical line L_AnnGetPoints(hLineV, aptLine); if (aptLine[0].y > aptLine[1].y) SwapAnnPoints(aptLine + 0, aptLine + 1); L_AnnConvert(pData->hContainer, ptLineV, aptLine, 2, ANNCONVERT_TO_CLIENT); L_AnnGetRect(pData->hContainer, &arcContainer, NULL); L_AnnConvert(pData->hContainer, (LPPOINT)&rcContainer, (pANNPOINT)&arcContainer, 2, ANNCONVERT_TO_CLIENT); if (pData->nUserHandleID == HANDLE_ID_CP0) { // Horizontal line rcClip.top = ptLineV[0].y; rcClip.bottom = ptLineV[1].y; rcClip.left = ptHandle.x - (ptLineH[1].x - ptLineV[0].x); rcClip.right = ptHandle.x + (ptLineV[0].x - ptLineH[0].x); // restrict moving line outside container rcContainer.left += ptHandle.x - ptLineH[0].x; rcContainer.right -= ptLineH[1].x - ptHandle.x; } else { // Vertical line rcClip.left = ptLineH[0].x; rcClip.right = ptLineH[1].x; rcClip.top = ptHandle.y - (ptLineV[1].y - ptLineH[0].y); rcClip.bottom = ptHandle.y + (ptLineH[0].y - ptLineV[0].y); // restrict moving line outside container rcContainer.top += ptHandle.y - ptLineV[0].y; rcContainer.bottom -= ptLineV[1].y - ptHandle.y; } IntersectRect(&rcClip, &rcClip, &rcContainer); L_AnnRestrictCursor(pData->hContainer, &rcClip, NULL, NULL, FALSE); } L_VOID ForearmRough_Handle_LButtonDown(LPCHILDDATA pData, pANNMOUSEPOS pMousePos) { L_INT32 nCount; AnnGetNeighborObjects( pData->hObjectChange, pData->AnnObjectNeighbors, &nCount); AnnSortNeighborObjects(pData->hObjectChange, pData->AnnObjectNeighbors, nCount); ForearmRough_RestrictPoint(pData, pData->AnnObjectNeighbors[0], pData->AnnObjectNeighbors[1], pMousePos->pt); switch (pData->nUserHandleID) { case HANDLE_ID_CP0: L_AnnDefine(pData->AnnObjectNeighbors[0], &pMousePos->pt, ANNDEFINE_BEGINMOVE); break; case HANDLE_ID_CP1: L_AnnDefine(pData->AnnObjectNeighbors[1], &pMousePos->pt, ANNDEFINE_BEGINMOVE); break; } } L_VOID ForearmRough_Handle_MouseMove(LPCHILDDATA pData, pANNMOUSEPOS pMousePos) { switch (pData->nUserHandleID) { case HANDLE_ID_CP0: L_AnnDefine(pData->AnnObjectNeighbors[0], &pMousePos->pt, ANNDEFINE_APPEND); break; case HANDLE_ID_CP1: L_AnnDefine(pData->AnnObjectNeighbors[1], &pMousePos->pt, ANNDEFINE_APPEND); break; } } L_VOID ForearmRough_Handle_LButtonUp(LPCHILDDATA pData, pANNMOUSEPOS pMousePos) { switch (pData->nUserHandleID) { case HANDLE_ID_CP0: L_AnnDefine(pData->AnnObjectNeighbors[0], &pMousePos->pt, ANNDEFINE_END); MoveHandle(pData->AnnObjectNeighbors[0], pData->nUserHandleID, pMousePos->pt); break; case HANDLE_ID_CP1: L_AnnDefine(pData->AnnObjectNeighbors[1], &pMousePos->pt, ANNDEFINE_END); MoveHandle(pData->AnnObjectNeighbors[1], pData->nUserHandleID, pMousePos->pt); break; } ClipCursor(&pData->rcOldClip); } //*************** ForearmRough Misc functions L_VOID ForearmRough_ClipCursor(LPCHILDDATA pData, HANNOBJECT hObject, POINT ptStart, L_BOOL bRestore) { L_INT32 nCount; ANNRECT arcBounds; RECT rcBounds; AnnGetNeighborObjects( hObject, pData->AnnObjectNeighbors, &nCount); AnnSortNeighborObjects(hObject, pData->AnnObjectNeighbors, nCount); // Restrict only the box--the line is unrestricted GetBoundingBox(pData->AnnObjectNeighbors, 1, &arcBounds); L_AnnConvert(pData->hContainer, (LPPOINT)&rcBounds, (pANNPOINT)&arcBounds, 2, ANNCONVERT_TO_CLIENT); L_AnnRestrictCursor(pData->hContainer, &rcBounds, &ptStart, &pData->rcOldClip, FALSE); }