//BoxCorner.c #include "BoxCorner.h" #include "annotate.h" #include "utils.h" #include "limits.h" // CP# means Control Point or Handle // // // CP0 ********************************* CP1 // * * // * * // * * // * * // * * // CP3 ********************************* CP2 //************************************************************************************** // // Functions for BoxCorner // //************************************************************************************* L_VOID BoxCorner_AddHandle(HANNOBJECT hObject, ANNPOINT apt, pHANDLEDEF pHandleDef) { ANNHANDLE AnnHandle; L_UINT uFlags = ANNHANDLE_LOCATION | ANNHANDLE_CONTAINER_COORDINATES | ANNHANDLE_ID | ANNHANDLE_PEN_COLOR | ANNHANDLE_FILL_COLOR | ANNHANDLE_SHAPE; AnnHandle.uStructSize = sizeof(ANNHANDLE); AnnHandle.nShape = pHandleDef->nShape; AnnHandle.crPen = RGB(0,0,0); AnnHandle.hCursor= NULL; AnnHandle.aptContainer = apt; AnnHandle.nID = pHandleDef->nID; AnnHandle.crFill = pHandleDef->crFill; AnnHandle.uFlags = uFlags; L_AnnAddUserHandle(hObject, &AnnHandle); } #define BOXCORNER_NUMPOINTS 4 HANDLEDEF BoxCorner_HandleDef[BOXCORNER_NUMPOINTS] = { HANDLE_ID_CP0, ANNHANDLE_SHAPE_CIRCLE, RGB(0,0,0), HANDLE_ID_CP1, ANNHANDLE_SHAPE_CIRCLE, RGB(128,128,128), HANDLE_ID_CP2, ANNHANDLE_SHAPE_CIRCLE, RGB(255,0,0), HANDLE_ID_CP3, ANNHANDLE_SHAPE_CIRCLE, RGB(0,255,0), }; // BoxCorner_AddUserHandles L_VOID BoxCorner_AddUserHandles(HANNOBJECT hPoly) { ANNPOINT aptPoly[4]; L_DOUBLE dMinX, dMinY, dMaxX, dMaxY; L_INT i; ANNPOINT apt; L_AnnGetPoints(hPoly, aptPoly); dMinX = dMaxX = aptPoly[0].x; dMinY = dMaxY = aptPoly[0].y; for(i=1; i<4; i++) { if (dMinX > aptPoly[i].x) dMinX = aptPoly[i].x; if (dMaxX < aptPoly[i].x) dMaxX = aptPoly[i].x; if (dMinY > aptPoly[i].y) dMinY = aptPoly[i].y; if (dMaxY < aptPoly[i].y) dMaxY = aptPoly[i].y; } apt.x = dMinX; apt.y = dMinY; BoxCorner_AddHandle(hPoly, apt, BoxCorner_HandleDef + 0); apt.x = dMaxX; apt.y = dMinY; BoxCorner_AddHandle(hPoly, apt, BoxCorner_HandleDef + 1); apt.x = dMaxX; apt.y = dMaxY; BoxCorner_AddHandle(hPoly, apt, BoxCorner_HandleDef + 2); apt.x = dMinX; apt.y = dMaxY; BoxCorner_AddHandle(hPoly, apt, BoxCorner_HandleDef + 3); } #define BOXCORNER_DIST 5; L_VOID BoxCorner_RestrictPoint(LPCHILDDATA pData, HANNOBJECT hRect) { RECT rcClip; ANNRECT arcContainer; ANNRECT arcRect; RECT rcRect; POINT pt0, pt1, pt2, pt3; // client coordinates of handles CP0 ... CP3 GetClipCursor(&pData->rcOldClip); rcClip = pData->rcOldClip; // L_AnnGetRect(hRect, &arcRect, NULL); L_AnnConvert(pData->hContainer, (LPPOINT)&rcRect, (pANNPOINT)&arcRect, 2, ANNCONVERT_TO_CLIENT); L_AnnGetRect(pData->hContainer, &arcContainer, NULL); L_AnnConvert(pData->hContainer, (LPPOINT)&rcClip, (pANNPOINT)&arcContainer, 2, ANNCONVERT_TO_CLIENT); switch(pData->nUserHandleID) { case HANDLE_ID_CP0: GetHandleInfo(hRect, HANDLE_ID_CP1, &pt1, NULL, NULL); GetHandleInfo(hRect, HANDLE_ID_CP3, &pt3, NULL, NULL); rcClip.right = pt1.x - BOXCORNER_DIST; rcClip.bottom = pt3.y - BOXCORNER_DIST; break; case HANDLE_ID_CP1: GetHandleInfo(hRect, HANDLE_ID_CP0, &pt0, NULL, NULL); GetHandleInfo(hRect, HANDLE_ID_CP2, &pt2, NULL, NULL); rcClip.left = pt0.x + BOXCORNER_DIST; rcClip.bottom = pt2.y - BOXCORNER_DIST; break; case HANDLE_ID_CP2: GetHandleInfo(hRect, HANDLE_ID_CP1, &pt1, NULL, NULL); GetHandleInfo(hRect, HANDLE_ID_CP3, &pt3, NULL, NULL); rcClip.left = pt3.x + BOXCORNER_DIST; rcClip.top = pt1.y + BOXCORNER_DIST; break; case HANDLE_ID_CP3: GetHandleInfo(hRect, HANDLE_ID_CP0, &pt0, NULL, NULL); GetHandleInfo(hRect, HANDLE_ID_CP2, &pt2, NULL, NULL); rcClip.top = pt0.y + BOXCORNER_DIST; rcClip.right = pt2.x - BOXCORNER_DIST; break; } rcClip.right++; rcClip.bottom++; L_AnnRestrictCursor(pData->hContainer, &rcClip, NULL, NULL, FALSE); } // L_VOID BoxCorner_Handle_LButtonDown(LPCHILDDATA pData, pANNMOUSEPOS pMousePos) { pData->ptStart = pMousePos->pt; switch (pData->nUserHandleID) { case HANDLE_ID_CP0: case HANDLE_ID_CP1: case HANDLE_ID_CP2: case HANDLE_ID_CP3: pData->ptStart = pMousePos->pt; L_AnnDefine(pData->hObjectChange, &pMousePos->pt, ANNDEFINE_BEGINMOVEPOINT); BoxCorner_RestrictPoint( pData, pData->hObjectChange); break; } } L_VOID BoxCorner_Handle_MouseMove(LPCHILDDATA pData, pANNMOUSEPOS pMousePos) { POINT ptMove = pMousePos->pt; switch (pData->nUserHandleID) { case HANDLE_ID_CP0: case HANDLE_ID_CP1: //ptMove.y = pData->ptStart.y; break; case HANDLE_ID_CP2: case HANDLE_ID_CP3: //ptMove.x = pData->ptStart.x; break; } L_AnnDefine(pData->hObjectChange, &ptMove, ANNDEFINE_APPEND); pMousePos->fUpdatePos = FALSE; } L_VOID BoxCorner_Handle_LButtonUp(LPCHILDDATA pData, pANNMOUSEPOS pMousePos) { POINT ptMove; ptMove = pMousePos->pt; switch (pData->nUserHandleID) { case HANDLE_ID_CP0: case HANDLE_ID_CP1: //ptMove.y = pData->ptStart.y; break; case HANDLE_ID_CP2: case HANDLE_ID_CP3: //ptMove.x = pData->ptStart.x; break; } L_AnnDefine(pData->hObjectChange, &ptMove, ANNDEFINE_END); MoveHandle(pData->hObjectChange, pData->nUserHandleID, pMousePos->pt); } //*************** BoxCorner Create functions L_VOID BoxCorner_LButtonDown(HWND hWnd, LPCHILDDATA pData) { L_AnnAddUndoNode(pData->hAutomation); L_AnnCreateItem(pData->hContainer, ANNOBJECT_RECT, TRUE, &pData->hRect); L_AnnDefine(pData->hRect, &pData->ptStart, ANNDEFINE_BEGINSET); pData->fCapture = TRUE; L_AnnRestrictCursor(pData->hContainer, NULL, NULL, &pData->rcOldClip,TRUE); } L_VOID BoxCorner_MouseMove(LPCHILDDATA pData) { L_AnnDefine(pData->hRect, &pData->ptMove, ANNDEFINE_UPDATE); } L_VOID BoxCorner_LButtonUp(LPCHILDDATA pData, L_UINT uTool) { HANNOBJECT hPoly; POINT pt; // Finish creating the rectangle L_AnnDefine(pData->hRect, &pData->ptEnd, ANNDEFINE_END); // Delete the rectangle and create a polygon L_AnnRemove(pData->hRect); L_AnnDestroy(pData->hRect, 0); // Create the polygon by defining the four vertices L_AnnCreateItem(pData->hContainer, ANNOBJECT_POLYGON, FALSE, &hPoly); pt = pData->ptStart; L_AnnDefine(hPoly, &pt, ANNDEFINE_BEGINSET); pt.x = pData->ptEnd.x; pt.y = pData->ptStart.y; L_AnnDefine(hPoly, &pt, ANNDEFINE_APPEND); pt.x = pData->ptEnd.x; pt.y = pData->ptEnd.y; L_AnnDefine(hPoly, &pt, ANNDEFINE_APPEND); pt.x = pData->ptStart.x; pt.y = pData->ptEnd.y; L_AnnDefine(hPoly, &pt, ANNDEFINE_APPEND); L_AnnDefine(hPoly, &pt, ANNDEFINE_END); L_AnnSetVisible(hPoly, TRUE, 0, NULL); HideDefaultHandles(hPoly); BoxCorner_AddUserHandles(hPoly); L_AnnSetSelected(hPoly, TRUE, 0); // set the default settings from the automation object, and group the objects L_AnnSetAutoDefaults(pData->hAutomation, pData->hContainer, ANNFLAG_SELECTED|ANNFLAG_RECURSE); AnnSetID(hPoly, uTool, 0); }