/* ARGSUSED */ static void _pgmvcp_groupDropEh ( Widget w, XtPointer clnt, XEvent *event, Boolean *ctdr ) /************************************************************************ * _pgmvcp_groupDropEh * * * * This function is the callback for a drop on a group. * * * * static void _pgmvcp_groupDropEh (w, clnt, event, ctdr) * * * * Input parameters: * * w Widget Parent widget * * clnt XtPointer State information record * * *event XEvent Button press event record * * * ** * * Log: * * E. Safford/GSC 06/97 Modified to handle Special Text * * E. Wehner/EAi 07/97 Remove offsets when replacing text. * * E. Safford/GSC 07/97 Fixed drag with special text problem * * E. Wehner/EAi 08/97 Remove watch box slide * * C. Lin/EAI 8/97 Add offsets for 'S' coord(roam) * * D.W.Plummer/NCEP 9/97 Combine into NxmDraw for new vgstruct.h * * E. Wehner/EAi 9/97 Remove graphics info record * * C. Lin/EAi 10/97 rename from NxmDrSlDropCb, cleanup * * C. Lin/EAi 10/97 add WBOX_ELEM related functions * * C. Lin/EAi 11/97 further cleanup * * E. Safford/GSC 02/98 add _storedEl for undo function * * S. Law/GSC 04/98 added copy function * * E. Safford/GSC 04/98 added FUNC_SELECT to FUNC_MOVE ops * * S. Law/GSC 05/98 cleaned up drag, added group box * * E. Safford/GSC 05/98 mod for new undo routines * * E. Safford/GSC 05/98 move to nmap_pgmvcp.c * * E. Safford/GSC 06/98 split from mvcpDrop.c * * E. Safford/GSC 06/98 added call to cgr_grfrsh.c * * G. Krueger/EAI 06/98 Uniform status hints * * C. Lin/EAI 08/98 fix ghosting problem & reset _dragCount * * G. Krueger/EAI 09/98 Added ghost veiling * * G. Krueger/EAI 10/98 Using table for hints * * E. Safford/GSC 12/98 modify refresh to limit area affected * * D.W.Plummer/NCEP 4/99 remove call to pgwlst_update * * E. Safford/GSC 10/99 update for new xwcmn.h * * S. Law/GSC 06/00 changed to use xgtoff * * H. Zeng/EAI 11/00 changed for the new undo design * * H. Zeng/EAI 11/00 changed cvg_rdrec() parameters * * A. Hardy/GSC 11/00 renamed coordinate system declarations * * H. Zeng/EAI 12/00 modified for multiple undo steps * * J. Wu/SAIC 12/01 add layer in crg_set() call * * T. Lee/SAIC 11/03 added user directory to work_file * * T. Lee/SAIC 11/03 used cvg_getworkfile * * J. Wu/SAIC 11/03 adjust jet barb/hash position * * J. Wu/SAIC 02/04 adjust gfa attribute box position * * J. Wu/SAIC 10/04 free GFA block memory * * S. Danz/AWC 07/06 Added new cvg_delet placement argument * * S. Danz/AWC 08/06 New flag to pgvgf_saveNewElm to place el* * S. Danz/AWC 08/06 Updated to use cvg_checkplace to find * * area impacted and call crg_rebuild() * ***********************************************************************/ { int location, ier, nelm, ii, jj, *inxarry, layer, update_crg; int currfunc, newnum, old_location, xoff, yoff, found; float llx, lly, urx, ury, delx, dely; float o_llx, o_lly, o_urx, o_ury, inf_bbox[4]; char newtyp; VG_DBStruct el, del_el; /*---------------------------------------------------------------------*/ _dragCount = 0; mcanvw_disarmDrag(); mcanvw_disarmDrop(); pggst_clearGhost(TRUE); if (!_midDrag) return; _midDrag = FALSE; update_crg = 0; currfunc = pgpalw_getCurOperId(); old_location = pgactv_getElmLoc(); cvg_rdrec(cvg_getworkfile(), old_location, &el, &ier); crg_ggnel(el.hdr.grptyp, el.hdr.grpnum, &nelm, &ier); if (nelm <= 0) return; inxarry = (int *)malloc(nelm*sizeof(int)); crg_gginx (el.hdr.grptyp, el.hdr.grpnum, nelm, inxarry, &nelm, &ier); newtyp = el.hdr.grptyp; newnum = el.hdr.grpnum; crg_ggbnd (newtyp, newnum, &o_llx, &o_urx, &o_ury, &o_lly, &ier); if (currfunc == FUNC_COPY) crg_ggnxt (el.hdr.grptyp, &newnum, &ier); /* * set "delta" amounts... */ xgtoff (&xoff, &yoff, &ier); delx = (float)event->xbutton.x + (float)xoff - _dragX; dely = (float)event->xbutton.y + (float)yoff - _dragY; _dragX += delx; _dragY += dely; delx = _dragX - _origX - _goffX; dely = _dragY - _origY - _goffY; pghdlb_deselectEl (old_location, FALSE); /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } pgundo_newStep(); layer = pglayer_getCurLayer( ); for (ii = 0; ii < nelm; ii++) { crg_goffset(inxarry[ii], &location, &ier); cvg_rdrec(cvg_getworkfile(), location, &el, &ier); pgactv_setActvElm ( &el, location); pgactv_getDevPts (&_dcN, &_dcX, &_dcY); for (jj = 0; jj < _dcN; jj++) { pgactv_modPt (jj, *(_dcX + jj) + delx, *(_dcY + jj) + dely); } if ((currfunc == FUNC_MOVE) || (currfunc == FUNC_SELECT)) { /* * Mark elements in placement that are effected by * the delete, and get the area of influence back */ cvg_rdrec(cvg_getworkfile(), location, &del_el, &ier); cvg_checkplace(&del_el, 1, location, &found, inf_bbox, &ier); if (found > 0) { /* * Update the refresh extent if the area impacted by * placement was bigger than the area passed in */ o_llx = G_MIN(o_llx, inf_bbox[0]); o_lly = G_MIN(o_lly, inf_bbox[2]); o_urx = G_MAX(o_urx, inf_bbox[1]); o_ury = G_MAX(o_ury, inf_bbox[3]); update_crg = 1; } /* * Free TCA/GFA memory */ if ( del_el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &del_el ); } else if ( del_el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &del_el ); } /* * delete old element */ cvg_delet (cvg_getworkfile(), location, TRUE, &ier); crg_clear (inxarry[ii], &ier); pgundo_storeThisLoc(location, UNDO_DEL, &ier); } /* * adjust jet barb/hash position accordingly */ if ( el.hdr.vg_type == JET_ELM ) { _pgmvcp_jetCalc ( &el, delx, dely, True ); } /* * adjust GFA attribute box position accordingly */ if ( el.hdr.vg_type == GFA_ELM ) { _pgmvcp_gfaCalc ( &el, delx, dely, True ); } /* * save new element */ el.hdr.grptyp = newtyp; el.hdr.grpnum = newnum; pgvgf_saveNewElm(NULL, sys_D, &el, _dcN, _dcX, _dcY, FALSE, &location, &ier); pgundo_storeThisLoc (location, UNDO_ADD, &ier); /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } cvg_rdrec(cvg_getworkfile(), location, &el, &ier); crg_set (&el, location, layer, &ier); /* * Mark elements in placement that are effected by * the new element, and get the area of influence back */ cvg_checkplace(&el, 0, location, &found, inf_bbox, &ier); if (found > 0) { /* * Update the refresh extent if the area impacted by * placement was bigger than the area passed in */ o_llx = G_MIN(o_llx, inf_bbox[0]); o_lly = G_MIN(o_lly, inf_bbox[2]); o_urx = G_MAX(o_urx, inf_bbox[1]); o_ury = G_MAX(o_ury, inf_bbox[3]); update_crg = 1; } /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } } /* for */ pgundo_endStep(); pgactv_setActvElm (&el, location); crg_ggbnd (newtyp, newnum, &llx, &urx, &ury, &lly, &ier); free (inxarry); o_llx -= EXTRA; o_lly -= EXTRA; o_urx += EXTRA; o_ury += EXTRA; if (o_llx < llx) llx = o_llx; if (o_lly < lly) lly = o_lly; if (o_urx > urx) urx = o_urx; if (o_ury > ury) ury = o_ury; xpgpaste (llx, lly, urx, ury, &ier); cvg_rfrsh (NULL, llx, lly, urx, ury, &ier); /* * If we may have impacted other elements with placement * we will need to rebuild the range records */ if (update_crg) { crg_rebuild(); } pghdlb_select (&el, location); mbotw_mouseSet(LMHINT_DRAG, MMHINT_DONE); }
static void pgfilterw_updateFilter ( void ) /************************************************************************ * pgfilterw_updateFilter * * * * Updates the current filter string and then refreshes the display. * * * * static void pgfilterw_updateFilter ( void ) * * * * Input parameters: * * Output parameters: * * none * * * ** * * Log: * * J. Wu/SAIC 07/04 initial coding * * J. Wu/SAIC 08/04 link filter change with GFA window * * J. Wu/SAIC 09/04 Restart GFA for any filter changes * * J. Wu/SAIC 10/04 Access GFA attr with cvg_getFld() * * E. Safford/SAIC 07/05 rm sequence # from cvg_scangfa() call * * M. Li/SAIC 03/07 Not reset fcst hour if change from GFA * * E. Safford/SAIC 05/07 fix gfa' connection * * E. Safford/SAIC 06/07 fix bug in preFilterOn determination * * B. Yin/SAIC 12/07 set GFA hr to last selected filter time * ***********************************************************************/ { int ii, filternum, ier, cur_obj, cur_loc, newel_loc, num; int subtyp, areatyp, len; char lastTime[8], value[32], tag[32], timeCmp[10]; Boolean gfaIsUp = False, gfaInAdd = False, preFilterOn = False; Boolean gfaPrimeIsUp = False; VG_DBStruct cur_el, newel; /*---------------------------------------------------------------------*/ cur_el.elem.gfa.info.nblocks = 0; _curFilter[0] = '\0'; filternum = 0; for ( ii = 0; ii < _nFilTime[TIME_FILTER]; ii++ ) { if ( _filterStatus[ii] ) { filternum++; strcat ( _curFilter, _filTime[TIME_FILTER][ii] ); if ( ii < (_nFilTime[TIME_FILTER] - 1) ) { strcat ( _curFilter, ";" ); } } } /* * If no filter is provided but the filter window is up - none * of the elements with time stamp will be displayed. If the * filter window is down, all elements should be displayed. */ if ( filternum == 0 ) { if ( pgfilterw_isUp() ) { strcpy ( _curFilter, ACTV_FILTER ); } else { strcpy ( _curFilter, CANCEL_FILTER ); } } /* * Check if gfaw is up and its mode. */ gfaIsUp = pggfaw_isUp(); gfaPrimeIsUp = pggfawp_isUp(); if( gfaIsUp ) { gfaInAdd = pggfaw_isAddMode(); } else if( gfaPrimeIsUp ) { gfaInAdd = pggfawp_isAddMode(); } cur_obj = pgpalw_getCurObjId (); /* * If gfaw is up, retrieve the current GFA attributes and check * if the previous forecast hour is still "ON" in filter window. * * If it is still on, then take no action. If it is not, and there * is another time selected, set the GFA/GFA' window forecast hour to * the first selected time. * * Note that the GFA/GFA' will ignore the Airmet and Outlook filter * settings. */ cur_loc = -1; preFilterOn = False; if ( gfaIsUp || gfaPrimeIsUp ) { if ( gfaInAdd ) { if( gfaIsUp ) { pggfaw_getAttr ( &cur_el ); ier = 0; } else { pggfawp_getAttr ( &cur_el ); ier = 0; } } else { cur_loc = pgactv_getElmLoc (); cvg_rdrec ( cvg_getworkfile(), cur_loc, &cur_el, &ier ); } cvg_getFld ( &cur_el, TAG_GFA_FCSTHR, value, &ier ); if ( filternum > 0 && ier == 0 ) { for ( ii = 0; ii < _nFilTime[TIME_FILTER]; ii++ ) { if ( _filterStatus[ii] ) { strcpy( timeCmp, _filTime[TIME_FILTER][ii] ); len = strlen( timeCmp ); if( timeCmp[ len-1 ] == '+' ) { timeCmp[ len-1 ] = '\0'; } if ( strcmp ( value, timeCmp ) == 0 ) { preFilterOn = True; break; } } } } } /* * Update filter setting in CVG library. */ cvg_setfilter ( _curFilter, &ier ); /* * Refresh the display. */ pgfilterw_refresh (); /* * Adjust GFA window, if necessary. */ if ( gfaIsUp || gfaPrimeIsUp ) { /* * If previously in "Add" mode, keep drawing. */ if ( gfaInAdd ) { /* * Set the GFA hour to the last selected filter time. * */ pgfilterw_getLastTime ( lastTime ); if ( strlen ( lastTime ) > (size_t)0 ) { if (!_fromGfa) { if( gfaIsUp ) { pggfaw_setHour ( lastTime ); } else { pggfawp_setHour ( lastTime ); } } } } else { /* Previously in "Edit" mode */ /* * The filter matching the active element's forecast hour * is still ON, keep editing it. */ if ( preFilterOn ) { cvg_freeElPtr( &cur_el ); pghdlb_select ( &cur_el, cur_loc ); } else { /* * The filter matching the active element's forecast * hour is OFF, terminate all pending actions. * However, if it is turned off by pressing hotkeys, * and a GFA element matching the same subtype, * and area type number could be found, * set to edit that element. */ if ( _offByHotkey ) { cvg_getFld ( &cur_el, TAG_GFA_SUBTYPE, value, &ier ); subtyp = atoi ( value ); cvg_getFld ( &cur_el, TAG_GFA_AREATYPE, value, &ier ); areatyp = atoi ( value ); cvg_getFld ( &cur_el, TAG_GFA_TAG, tag, &ier ); cvg_scangfa ( NULL, pglayer_getCurLayer(), subtyp, areatyp, tag, &newel, &newel_loc, &ier ); if ( ier == 0 ) { crg_getinx ( cur_loc, &num, &ier); pghdlb_deselectEl ( num, TRUE ); pgactv_setActvElm ( &newel, newel_loc ); pghdlb_select ( &newel, newel_loc ); if( gfaIsUp ) { pggfaw_setAttr ( &newel ); } else { pggfawp_setAttr ( &newel ); } } else { pgevt_unsetOper ( TRUE ); } } else { pgevt_unsetOper ( TRUE ); } _offByHotkey = False; } } /* End "if" in edit mode */ } cvg_freeElPtr( &cur_el ); _fromGfa = False; }
void pgmvcp_start ( char grptyp, int grpnum, char closed, float xx, float yy, int smooth ) /************************************************************************ * pgmvcp_start * * * * Function for starting MOVE/COPY drag mode called by pgevt_mvcpHdl. * * * * void pgmvcp_start ( grptyp, grpnum, closed, xx, yy, smooth ) * * * * Input parameters: * * grptyp char group type of selected element * * grpnum int group number of selected element * * closed char figure close flag * * xx float x coordinate of cursor * * yy float y coordinate of cursor * * smooth int smoothing level * * * * Output parameters: * * none * * * ** * * Log: * * E. Wehner/Eai Initial coding * * C. Lin/EAi 10/97 rename from NxmDrawSlide2Cb, cleanup * * C. Lin/EAi 11/97 reset the hot point when necessary * * E. Safford/GSC 03/98 add pgsymb_popdown * * E. Safford/GSC 04/98 remove check on class * * S. Law/GSC 04/98 added copy function * * S. Law/GSC 05/98 cleaned up drag, added group box * * S. Law/GSC 05/98 replaced pgpalw_mvcp with _setupOper * * S. Law/GSC 05/98 added call to pgevt_unsetOper * * E. Safford/GSC 05/98 move to nmap_pgmvcp.c * * G. Krueger/EAI 06/98 Uniform status hints * * E. Safford/GSC 07/98 modify ghost of closed figures * * E. Safford/GSC 07/98 modify ghost of smoothed figures * * C. Lin/EAi 08/98 add _dragCount to improve jiggle effect * * G. Krueger/EAI 09/98 Added ghost veiling * * E. Safford/GSC 09/98 modify to handle mode (GRP/OBJ) * * G. Krueger/EAI 10/98 Using table for hints * * W. Li/EAI 01/99 NxmTxtA_XXX --> pgtxt_XXX * * G. Krueger/EAI 05/99 Added circle draw function * * G. Krueger/EAI 06/99 Simplified circle move * * S. Law/GSC 09/99 added parameter to mcanvw_set* functions* * H. Zeng/EAI 04/00 changed cursor name * * E. Safford/GSC 02/01 add check on cvg_rdsel return code * * E. Safford/GSC 02/01 add param to cvg_rdsel * * J. Wu/SAIC 10/04 free GFA block memory * ***********************************************************************/ { int selected, nearest, ier; float llx, lly, urx, ury, dummy; VG_DBStruct el; /*---------------------------------------------------------------------*/ _midDrag = FALSE; _nearPt = pgactv_getNearPt(); pggst_veilGhost (FALSE); if (grptyp && grpnum && (grptyp == GRPTYP_COMSYM || pgpalw_getMode() == TYPE_GRP)) { crg_ggbnd(grptyp, grpnum, &llx, &urx, &ury, &lly, &ier); _dragX = _origX = llx; _dragY = _origY = lly; _goffX = xx - llx; _goffY = yy - lly; _gpcX[0] = llx - _goffX; _gpcY[0] = lly - _goffY; _gpcX[1] = urx - _goffX; _gpcY[1] = lly - _goffY; _gpcX[2] = urx - _goffX; _gpcY[2] = ury - _goffY; _gpcX[3] = llx - _goffX; _gpcY[3] = ury - _goffY; _gpcX[4] = llx - _goffX; _gpcY[4] = lly - _goffY; mcanvw_setDragFunc((XtEventHandler)&_pgmvcp_groupDragEh, CURS_DEFAULT); mcanvw_setDropFunc((XtEventHandler)&_pgmvcp_groupDropEh, CURS_DEFAULT); } else { _closedFig = (closed)? TRUE : FALSE; pgactv_getDevPts (&_dcN, &_dcX, &_dcY); selected = pgactv_getElmLoc(); if (selected != -1) { cvg_rdsel(NULL, selected, xx, yy, &nearest, &dummy, &el, &ier); /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } if ( ier != 0 ) { return; } if ( el.hdr.vg_type == CIRCLE_ELM ) _nearPt = 0; _wboxElm = ( el.hdr.vg_type == WBOX_ELM ); } _dragX = _origX = *(_dcX + _nearPt); _dragY = _origY = *(_dcY + _nearPt); _goffX = 0.0F; _goffY = 0.0F; mcanvw_setDragFunc((XtEventHandler)&_pgmvcp_elDragEh, CURS_DEFAULT); mcanvw_setDropFunc((XtEventHandler)&_pgmvcp_elDropEh, CURS_DEFAULT); } _dragCount = 0; _smoothLvl = smooth; pgtxt_setGhostFlag (FALSE, NULL); mbotw_mouseSet(LMHINT_DRAG, MMHINT_DONE); }
/* ARGSUSED */ static void _pgmvcp_elDropEh ( Widget w, XtPointer clnt, XEvent *event, Boolean *ctdr ) /************************************************************************ * _pgmvcp_elDropEh * * * * This function is the callback for a drop on a selected element. * * * * static void _pgmvcp_elDropEh (w, clnt, event, ctdr) * * * * Input parameters: * * w Widget Parent widget * * clnt XtPointer State information record * * *event XEvent Button press event record * * * ** * * Log: * * E. Safford/GSC 06/97 Modified to handle Special Text * * E. Wehner/EAi 07/97 Remove offsets when replacing text. * * E. Safford/GSC 07/97 Fixed drag with special text problem * * E. Wehner/EAi 08/97 Remove watch box slide * * C. Lin/EAI 8/97 Add offsets for 'S' coord(roam) * * D.W.Plummer/NCEP 9/97 Combine into NxmDraw for new vgstruct.h * * E. Wehner/EAi 9/97 Remove graphics info record * * C. Lin/EAi 10/97 rename from NxmDrSlDropCb, cleanup * * C. Lin/EAi 10/97 add WBOX_ELEM related functions * * C. Lin/EAi 11/97 further cleanup * * E. Safford/GSC 02/98 add _storedEl for undo function * * S. Law/GSC 04/98 added copy function * * E. Safford/GSC 04/98 added FUNC_SELECT to FUNC_MOVE ops * * S. Law/GSC 05/98 cleaned up drag, added group box * * E. Safford/GSC 05/98 mod for new undo routines * * E. Safford/GSC 05/98 move to nmap_pgmvcp.c * * E. Safford/GSC 06/98 split from mvcpDrop.c * * G. Krueger/EAI 06/98 Uniform status hints * * E. Safford/GSC 07/98 reset _dcN for closed figures * * C. Lin/EAI 08/98 fix ghosting problem & reset _dragCount * * G. Krueger/EAI 09/98 Added ghost veiling * * G. Krueger/EAI 10/98 Using table for hints * * E. Safford/GSC 12/98 modify refresh to limit area affected * * D.W.Plummer/NCEP 4/99 remove call to pgwlst_update * * E. Safford/GSC 11/00 wipe the county list for watches * * H. Zeng/EAI 11/00 changed for the new undo design * * H. Zeng/EAI 11/00 changed cvg_rdrec() parameters * * A. Hardy/GSC 11/00 renamed coordinate system declaration * * H. Zeng/EAI 12/00 modified for multiple undo steps * * J. Wu/SAIC 12/01 add layer in crg_set() call * * J. Wu/SAIC 01/02 add layer in crg_get() call * * T. Lee/SAIC 11/03 added user directory to work_file * * T. Lee/SAIC 11/03 used cvg_getworkfile * * J. Wu/SAIC 11/03 adjust jet barb/hash position * * J. Wu/SAIC 02/04 adjust gfa attribute box position * * J. Wu/SAIC 07/04 add filter param. to crg_get() * * J. Wu/SAIC 07/04 free GFA block memory * * B. Yin/SAIC 02/05 add a call to snap for GFA * * E. Safford/SAIC 06/05 allow smear to get smaller on edit * * S. Danz/AWC 07/06 Added new cvg_delet placement argument * * S. Danz/AWC 08/06 New flag to pgvgf_saveNewElm to place el* * S. Danz/AWC 08/06 Updated to use cvg_checkplace to find * * area impacted and call crg_rebuild() * * S. Danz/AWC 02/07 Add logic to update GFA centroid * * L. Hinson/AWC 07/09 Add code to update CCF centroid * ***********************************************************************/ { int location, ier, currfunc, new_location, num, layer, el_layer; int found, update_crg, one = 1; float llx, lly, urx, ury; float x_cntr, y_cntr, c_lat, c_lon, area; float o_llx, o_lly, o_urx, o_ury, inf_bbox[4]; char value[32]; VG_DBStruct el, del_el; filter_t filter; /*---------------------------------------------------------------------*/ _dragCount = 0; mcanvw_disarmDrag(); mcanvw_disarmDrop(); if ( _wboxElm ) { pgwpts_setSnap (TRUE); _pgmvcp_wboxCalc ( ); } pggst_clearGhost(TRUE); if (!_midDrag) return; _midDrag = FALSE; update_crg = 0; currfunc = pgpalw_getCurOperId(); pgundo_newStep(); location = pgactv_getElmLoc(); cvg_rdrec(cvg_getworkfile(), location, &el, &ier); crg_getinx (location, &num, &ier); crg_get (num, &el_layer, filter, &o_llx, &o_lly, &o_urx, &o_ury, &ier); pghdlb_deselectEl (location, FALSE); if ((currfunc == FUNC_MOVE) || (currfunc == FUNC_SELECT)) { /* * Mark elements in placement that are effected by * the delete, and get the area of influence back */ cvg_rdrec(cvg_getworkfile(), location, &del_el, &ier); cvg_checkplace(&del_el, 1, location, &found, inf_bbox, &ier); if (found > 0) { /* * Update the refresh extent if the area impacted by * placement was bigger than the area passed in */ o_llx = G_MIN(o_llx, inf_bbox[0]); o_lly = G_MIN(o_lly, inf_bbox[2]); o_urx = G_MAX(o_urx, inf_bbox[1]); o_ury = G_MAX(o_ury, inf_bbox[3]); update_crg = 1; } /* * Free TCA/GFA memory */ if ( del_el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &del_el ); } else if ( del_el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &del_el ); } /* * delete old element */ cvg_delet (cvg_getworkfile(), location, TRUE, &ier); crg_clear (num, &ier); pgundo_storeThisLoc(location, UNDO_DEL, &ier); } if ( el.hdr.vg_type == WBOX_ELM ) { pgwbxw_getAnchor ( 0, el.elem.wbx.info.w_a0id, &el.elem.wbx.info.w_a0lt, &el.elem.wbx.info.w_a0ln, &el.elem.wbx.info.w_a0dis, el.elem.wbx.info.w_a0dir, &ier ); pgwbxw_getAnchor ( 1, el.elem.wbx.info.w_a1id, &el.elem.wbx.info.w_a1lt, &el.elem.wbx.info.w_a1ln, &el.elem.wbx.info.w_a1dis, el.elem.wbx.info.w_a1dir, &ier ); /* * Wipe the county list */ el.elem.wbx.info.numcnty = 0; } /* * adjust jet barb/hash position accordingly */ if ( el.hdr.vg_type == JET_ELM ) { _pgmvcp_jetCalc ( &el, 0, 0, False ); } if ( el.hdr.vg_type == SIGCCF_ELM ) { _pgmvcp_ccfCalc ( &el, 0, 0, False ); gtrans ( sys_D, sys_M, &_dcN, _dcX, _dcY, &(el.elem.ccf.latlon[0]), &(el.elem.ccf.latlon[_dcN]), &ier, strlen(sys_D), strlen(sys_M) ); _dcN = el.elem.ccf.info.npts; cvg_todev ( &el, &_dcN, _dcX, _dcY, &ier ); if ( el.hdr.closed ) { cgr_centroid ( _dcX, _dcY, &_dcN, &x_cntr, &y_cntr, &area, &ier ); } else { x_cntr = _dcX[0] ; y_cntr = _dcY[0] ; } gtrans( sys_D, sys_M, &one, &x_cntr, &y_cntr, &c_lat, &c_lon, &ier, strlen(sys_D), strlen(sys_M) ); el.elem.ccf.info.arrowlat = c_lat; el.elem.ccf.info.arrowlon = c_lon; } /* * adjust GFA attribute box position accordingly */ if ( el.hdr.vg_type == GFA_ELM ) { _pgmvcp_gfaCalc ( &el, 0, 0, False ); gtrans ( sys_D, sys_M, &_dcN, _dcX, _dcY, &(el.elem.gfa.latlon[0]), &(el.elem.gfa.latlon[_dcN]), &ier, strlen(sys_D), strlen(sys_M) ); pgsmear_snapEl ( FALSE, &el, &ier ); _dcN = el.elem.gfa.info.npts; cvg_todev( &el, &_dcN, _dcX, _dcY, &ier ); if ( pggfaw_isClosed() ) { cgr_centroid( _dcX, _dcY, &_dcN, &x_cntr, &y_cntr, &area, &ier ); } else { x_cntr = _dcX[ 0 ]; y_cntr = _dcY[ 0 ]; } gtrans( sys_D, sys_M, &one, &x_cntr, &y_cntr, &c_lat, &c_lon, &ier, strlen(sys_D), strlen(sys_M) ); sprintf ( value, "%7.2f", c_lat ); cvg_setFld ( &el, TAG_GFA_ARROW_LAT, value, &ier ); sprintf ( value, "%7.2f", c_lon ); cvg_setFld ( &el, TAG_GFA_ARROW_LON, value, &ier ); } /* * save new element */ pgvgf_saveNewElm(NULL, sys_D, &el, _dcN, _dcX, _dcY, FALSE, &new_location, &ier); pgundo_storeThisLoc (new_location, UNDO_ADD, &ier); pgundo_endStep(); /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } cvg_rdrec(cvg_getworkfile(), new_location, &el, &ier); layer = pglayer_getCurLayer( ); crg_set (&el, new_location, layer, &ier); pgactv_setActvElm (&el, new_location); crg_getinx (new_location, &num, &ier); crg_get(num, &el_layer, filter, &llx, &lly, &urx, &ury, &ier); if (o_llx < llx) llx = o_llx; if (o_lly < lly) lly = o_lly; if (o_urx > urx) urx = o_urx; if (o_ury > ury) ury = o_ury; /* * Mark elements in placement that are effected by * the new element, and get the area of influence back */ cvg_checkplace(&el, 0, new_location, &found, inf_bbox, &ier); if (found > 0) { /* * Update the refresh extent if the area impacted by * placement was bigger than the area passed in */ llx = G_MIN(llx, inf_bbox[0]); lly = G_MIN(lly, inf_bbox[2]); urx = G_MAX(urx, inf_bbox[1]); ury = G_MAX(ury, inf_bbox[3]); update_crg = 1; } xpgpaste (llx, lly, urx, ury, &ier); cvg_rfrsh (NULL, llx, lly, urx, ury, &ier); /* * If we may have impacted other elements with placement * we will need to rebuild the range records */ if (update_crg) { crg_rebuild(); } pghdlb_select (&el, new_location); /* * Free TCA/GFA memory */ if ( el.hdr.vg_type == TCA_ELM ) { cvg_freeBkpts ( &el ); } else if ( el.hdr.vg_type == GFA_ELM ) { cvg_freeElPtr ( &el ); } mbotw_mouseSet(LMHINT_DRAG, MMHINT_DONE); }
/* ARGSUSED */ void pgdel_deletEh ( Widget wid, XtPointer clnt, XEvent *event, Boolean *ctdr ) /************************************************************************ * pgdel_deletEh * * * * Delete the selected element. * * * * void pgdel_deletEh (wid, clnt, event, ctdr ) * * * * Input parameters: * * wid Widget callback widget * * clnt XtPointer client data * * *event XEvent * * * ** * * Log: * * E. Wehner Initial coding * * E. Safford 9/97 Replaced grP->cmd with cmd_ routines * * D.W.Plummer/NCEP 9/97 Changes for new vgstruct header file * * E. Wehner/EAi 9/97 Remove graphics info record * * C. Lin/EAi 10/97 rename from NxmDrawErase, cleanup * * E. Safford/GSC 02/98 added undo capability * * F. Yen/NCEP 1/98 Updated calls for crg library cleanup * * S. Law/GSC 04/98 added pghdlb_deselectEl * * E. Safford/GSC 04/98 mod to handle groups * * S. Law/GSC 05/98 replaced pgpalw_delete with _setupOper * * E. Safford/GSC 05/98 updated for new undo functions * * S. Law/GSC 05/98 added check for pghot_getElmLoc * * E. Safford/GSC 06/98 moved to nmap_pgdel.c * * E. Safford/GSC 06/98 updated pghdlb_deselectEl call * * E. Safford/GSC 06/98 added call to crg_grfrsh * * E. Safford/GSC 09/98 modify to handle mode (OBJ/GRP) * * W. Li/EAI 10/98 renamed pgdel_eraseXX -> pgdel_deletXX * * E. Safford/GSC 10/98 modify for param change to cvg_rdrec * * E. Safford/GSC 12/98 limit area of refresh * * S. Law/GSC 03/00 changed to use pgutls_prepNew * * E. Safford/GSC 03/00 fixed group delete crash * * S. Law/GSC 03/00 added GRPTYP_CCF check * * H. Zeng/EAI 11/00 changed for the new undo design * * H. Zeng/EAI 12/00 modified for multiple undo steps * * J. Wu/GSC 03/01 added "EXIT" hint to bottom panel * * J. Wu/SAIC 02/02 set changes_made to TRUE on curr. layer * * T. Lee/SAIC 11/03 added user directory to work_file * * T. Lee/SAIC 11/03 used cvg_getworkfile * * E. Safford/SAIC 04/04 moved most code to pgdel_deleteElms() * ***********************************************************************/ { int location = -1; /*---------------------------------------------------------------------*/ location = pgactv_getElmLoc(); if( location < 0 ) return; if (event->xbutton.button == Button1) { pgdel_deleteElms( ); } mcanvw_disarmPress(); pgpalw_setupOper(); mbotw_mouseSet(LMHINT_SELECT, MMHINT_EXIT); }
void pgconn_start ( VG_DBStruct *el, float currx, float curry ) /************************************************************************ * pgconn_start * * * * Initial setup and original selection * * * * void pgconn_start (el, currx, curry) * * * * Input parameters: * * *el VG_DBStruct selected element * * currx float current x coordinate * * curry float current y coordinate * * * * Output parameters: * * NONE * * * ** * * Log: * * S. Law/GSC 09/98 Initial coding * * G. Krueger/EAI 09/98 Added ghost veiling * * G. Krueger/EAI 10/98 Using table for mouse hints * * S. Law/GSC 09/99 added parameter to mcanvw_set* functions* * H. Zeng/EAI 04/00 changed cursor name * * H. Zeng/EAI 11/00 added _primaryLoc * * J. Wu/GSC 02/01 Modified 'unused1' in VG to 'smooth' * * J. Wu/SAIC 06/07 connect GFAs with same hazard type & * * forecast hour * ***********************************************************************/ { float *dcx, *dcy; int dcn, near, ii, jj, ier; char hazard[32]; /*---------------------------------------------------------------------*/ _primaryEl = *el; _primaryLoc = pgactv_getElmLoc(); /* * Check the type of first selected element - GFAs (except open * FZLVL) are handle differently than other types of VG elements. */ _isGFA = (_primaryEl.hdr.vg_type == GFA_ELM) ? True:False; _isOpenFzlvl = False; if ( _isGFA ) { _primaryEl.elem.gfa.info.nblocks = el->elem.gfa.info.nblocks; G_MALLOC ( _primaryEl.elem.gfa.info.blockPtr[ 0 ], gfaBlock_t, el->elem.gfa.info.nblocks, "pgconn_start: _primaryEl.blockPtr" ); memcpy ( _primaryEl.elem.gfa.info.blockPtr[ 0 ], el->elem.gfa.info.blockPtr[ 0 ], el->elem.gfa.info.nblocks * STD_STRLEN * sizeof ( char ) ); cvg_getFld ( el, TAG_GFA_AREATYPE, hazard, &ier ); if ( strcasecmp( hazard, "FZLVL" ) == 0 ) { if ( _primaryEl.hdr.closed == 0 ) { _isOpenFzlvl = True; } } } _drawGhost = True; if ( _isGFA && !_isOpenFzlvl ) { _drawGhost = False; } /* * Start another mouse click. */ pggst_veilGhost ( FALSE ); mcanvw_setPressFunc((XtEventHandler)&pgconn_select, CURS_DEFAULT); /* * No drag function for closed GFAs - except open FZLVLs. */ if ( _drawGhost ) { mcanvw_setDragFunc((XtEventHandler)&pgconn_ghost, CURS_DEFAULT); } pgactv_getDevPts (&dcn, &dcx, &dcy); /* * Ghost only for non-GFAs and open FZLVLs. */ if ( _drawGhost ) { near = pgactv_getNearPt (); _ghostN = (dcn < 3) ? dcn : 3; if (FindNearEnd (0, near, (dcn - 1))) { /* ghost last 2 or 3 points */ jj = 0; for (ii = (dcn - _ghostN); ii < dcn; ii++) { _ghostX[jj] = *(dcx + ii); _ghostY[jj] = *(dcy + ii); jj++; } } else { /* ghost first 2 or 3 points */ jj = 0; for (ii = (_ghostN - 1); ii > -1; ii--) { _ghostX[jj] = *(dcx + ii); _ghostY[jj] = *(dcy + ii); jj++; } } _ghostX[jj] = currx; _ghostY[jj] = curry; pggst_clearGhost (TRUE); pggst_setLineAttr (_primaryEl.hdr.smooth, (Boolean) _primaryEl.hdr.closed); pggst_addGhostPts ( (_ghostN+1), _ghostX, _ghostY, &ier ); pggst_drawGhost (GST_NORMAL); } mbotw_mouseSet(LMHINT_NEXT, MMHINT_DONE); }
/* ARGSUSED */ static void pgconn_select ( Widget wid, XtPointer clnt, XEvent *event, Boolean *ctdr ) /************************************************************************ * pgconn_select * * * * This function handles the selection callbacks * * * * static void pgconn_select (wid, clnt, event, ctdr ) * * * * Input parameters: * * wid Widget calling widget * * clnt XtPointer * * *event XEvent * * * * Output parameters: * * NONE * * * ** * * Log: * * S. Law/GSC 09/98 Initial coding * * S. Law/GSC 09/98 Removed unnecessary refreshes * * E. Safford/GSC 09/98 fix ghost problem conn to 2 pt lines * * G. Krueger/EAI 10/98 Using table for mouse hints * * S. Law/GSC 09/98 added CLASS_SIGMETS * * S. Law/GSC 09/99 added parameter to mcanvw_set* functions* * E. Safford/GSC 10/99 update for new xwcmn.h * * S. Law/GSC 02/00 added CCF * * S. Law/GSC 03/00 added parameter to pgutls_prepNew * * H. Zeng/EAI 04/00 changed cursor name * * S. Law/GSC 06/00 changed to use xgtoff * * H. Zeng/EAI 11/00 modified for the new undo design * * A. Hardy/GSC 11/00 renamed coordinate system declaration * * H. Zeng/EAI 12/00 modified for multiple undo steps * * J. Wu/GSC 03/01 added "EXIT" hint to bottom panel * * J. Wu/SAIC 01/02 scan the current PGEN layer only * * E. Safford/SAIC 03/02 rename from _pgconn_select, add * * pgutls_regroup(), clean up * * E. Safford/SAIC 04/02 check ier from cvg_scan to avoid UMR * * T. Lee/SAIC 11/03 added user directory to work_file * * T. Lee/SAIC 11/03 used cvg_getworkfile * * S. Danz/AWC 08/06 New flag to pgvgf_saveNewElm to place el* * J. Wu/SAIC 06/07 connect GFAs * ***********************************************************************/ { float xx, yy, llx, lly, urx, ury; float *primary_x, *primary_y; float secondary_x[MAXPTS], secondary_y[MAXPTS]; int primary_n, primary_loc, secondary_n; int ier, near, test, xoff, yoff, cur_layer; int start, grp_num1, grp_num2; char grp_typ1, grp_typ2, warnMsg[256], value[10]; char mesg[] = {"Maximum vertices exceeded."}; Boolean primary_grouped = FALSE; Boolean secondary_grouped = FALSE; static int secondary_elnum; static int secondary_loc; static Boolean reverse_flag = FALSE; static VG_DBStruct secondary_el; static VG_DBStruct GFA_el; int GFA_pts, GFA_newloc; float GFA_x[MAXPTS], GFA_y[MAXPTS]; /*---------------------------------------------------------------------*/ xgtoff (&xoff, &yoff, &ier); cur_layer = pglayer_getCurLayer (); if (event->xbutton.button == Button1) { if (_selectFlag) { /* confirming secondary element */ grp_typ1 = _primaryEl.hdr.grptyp; grp_num1 = _primaryEl.hdr.grpnum; if ( grp_typ1 > 0 && grp_num1 > 0 ) { primary_grouped = TRUE; } cvg_todev (&secondary_el, &secondary_n, secondary_x, secondary_y, &ier); grp_typ2 = secondary_el.hdr.grptyp; grp_num2 = secondary_el.hdr.grpnum; if ( grp_typ2 > 0 && grp_num2 > 0 ) { secondary_grouped = TRUE; } if ( _drawGhost ) { near = pgactv_getNearPt (); pgactv_getDevPts (&primary_n, &primary_x, &primary_y); start = (FindNearEnd (0, near, (primary_n - 1)) == 0) ? 0 : primary_n; if (reverse_flag) { pgutls_fReverseArray (secondary_n, secondary_x, secondary_y); } pgactv_addPts (secondary_x, secondary_y, secondary_n, start, &ier); } if (ier == 0) { if ( _drawGhost ) { pgactv_getDevPts (&primary_n, &primary_x, &primary_y); } /* * Grouping the new element: * * If the primary element was grouped, the new element stays in * that group. If the primary element was not grouped, but the * secondary element was, then put the new element in the * secondary element's group. */ if ( !primary_grouped && secondary_grouped ) { _primaryEl.hdr.grptyp = grp_typ2; _primaryEl.hdr.grpnum = grp_num2; } /* * Save the new element: * * For non-GFAs or open FZLVLs, use points of both the primary * and secondary elements. * * For closed GFAs, use points resulting from smearing the primary * and secondary elements. * * Note: The new GFA element will use the the primary element's * forecast hour, color, and line attributes. */ if ( _drawGhost ) { pgundo_newStep(); pgundo_storeThisLoc ( _primaryLoc, UNDO_DEL, &ier ); pgundo_storeThisLoc ( secondary_loc, UNDO_DEL, &ier ); pgutls_prepNew ( -1, &_primaryEl, &llx, &lly, &urx, &ury, &ier); pgvgf_saveNewElm ( cvg_getworkfile(), sys_D, &_primaryEl, primary_n, primary_x, primary_y, TRUE, &primary_loc, &ier ); pgutls_redraw ( primary_loc, &_primaryEl, &ier ); pgundo_storeThisLoc ( primary_loc, UNDO_ADD, &ier); } else { pgvgf_saveNewElm ( cvg_getworkfile(), sys_M, &GFA_el, 0, GFA_x, GFA_y, TRUE, &GFA_newloc, &ier ); if ( ier >= 0 ) { pgundo_newStep(); pgundo_storeThisLoc ( _primaryLoc, UNDO_DEL, &ier ); pgundo_storeThisLoc ( secondary_loc, UNDO_DEL, &ier ); pgactv_setActvElm ( &_primaryEl, _primaryLoc ); pgutls_prepNew ( _primaryLoc, &_primaryEl, &llx, &lly, &urx, &ury, &ier); pgutls_redraw ( GFA_newloc, &GFA_el, &ier ); pgundo_storeThisLoc ( GFA_newloc, UNDO_ADD, &ier ); } else if ( ier == -28 ) { /* too few points in resulting smear */ cvg_getFld ( &GFA_el, TAG_GFA_TAG, value, &ier ); sprintf( warnMsg, "Unable to connect tag %s.\n It has too few points after smearing and/or snapping.\n", value ); NxmWarn_show( mcanvw_getDrawingW(), warnMsg ); } cvg_freeElPtr ( &GFA_el ); } /* * set the secondary element as the active * one, so that prepNew can remove it */ pgactv_setActvElm (&secondary_el, secondary_loc); pgutls_prepNew (secondary_loc, &secondary_el, &llx, &lly, &urx, &ury, &ier); /* * If both elements were grouped, then move all elements * grouped with the secondary element into the primary * element's group. */ if ( primary_grouped && secondary_grouped ) { pgutls_regroup ( grp_typ2, grp_num2, grp_typ1, grp_num1, &ier ); } pgundo_endStep(); /* * Clean up for next connection. */ if ( _isGFA ) { cvg_freeElPtr ( &secondary_el ); cvg_freeElPtr ( &_primaryEl ); } pghdlb_deselectAll (); pgactv_clearActv (); pggst_clearGhost ( FALSE ); } else { NxmWarn_show (wid, mesg); } mcanvw_setPressFunc ((XtEventHandler)&pgevt_locateElmCb, CURS_DEFAULT); if ( _drawGhost ) mcanvw_disarmDrag (); _selectFlag = FALSE; mbotw_mouseSet(LMHINT_SELECT, MMHINT_EXIT); } else { /* selecting secondary element */ xx = (float) (event->xbutton.x + xoff); yy = (float) (event->xbutton.y + yoff); test = False; cvg_scan (NULL, cur_layer, (char)_primaryEl.hdr.vg_class, xx, yy, 0, &secondary_el, &secondary_loc, &near, &ier); /* * Verify elements only if no error returned from cvg_scan. */ if ( ier >= 0 ) { test = pgconn_verifyType ( &_primaryEl, &secondary_el); } /* * Verify there are actually 2 elements, not the same element. */ if (test) { if (secondary_loc == pgactv_getElmLoc () || secondary_loc == 0) { test = FALSE; } } if ( test ) { crg_getinx ( secondary_loc, &secondary_elnum, &ier ); /* * Get the points for the potential connect/join and use it * to draw the ghost line so the user can have a feel of the * result before making the confirmation. * * For non-GFAs or open FZLVLs, connect points of both the primary * and secondary elements. * * For closed GFAs, get points by smearing the primary and * secondary elements. * */ if ( !_drawGhost ) { /* * Select the second GFA. */ pghdlb_select ( &secondary_el, secondary_loc ); /* * Smear two GFA polygons. */ GFA_pts = 0; GFA_el.elem.gfa.info.nblocks = 0; pgconn_smear ( _primaryLoc, secondary_loc, &GFA_el, &GFA_pts, GFA_x, GFA_y ); /* * Ghost the resulting polygon. */ pggst_clearGhost (TRUE); pggst_setLineAttr ( _primaryEl.hdr.smooth, (Boolean)_primaryEl.hdr.closed ); pggst_addGhostPts ( GFA_pts, GFA_x, GFA_y, &ier ); pggst_drawGhost ( GST_NORMAL ); } else { pggst_drawGhost (GST_NORMAL); mcanvw_disarmDrag (); cvg_todev (&secondary_el, &secondary_n, secondary_x, secondary_y, &ier); if (FindNearEnd (0, near, (secondary_n - 1))) { reverse_flag = TRUE; pgutls_fReverseArray (secondary_n, secondary_x, secondary_y); } else { reverse_flag = FALSE; } pggst_replaceGhostPts (1, &secondary_x[0], &secondary_y[0], &ier); pggst_addGhostPts ((secondary_n - 1), &secondary_x[1], &secondary_y[1], &ier); pggst_drawGhost (GST_NORMAL); } _selectFlag = TRUE; mbotw_mouseSet(LMHINT_CONFIRM, MMHINT_CANCEL); } } } else { if (_selectFlag) { /* unselecting secondary element */ pghdlb_deselectEl ( secondary_elnum, TRUE ); pghdlb_displayAllSel (); if ( _drawGhost ) { xx = (float) (event->xbutton.x + xoff); yy = (float) (event->xbutton.y + yoff); _ghostX[_ghostN] = xx; _ghostY[_ghostN] = yy; pggst_clearGhost (FALSE); pggst_addGhostPts ((_ghostN + 1), _ghostX, _ghostY, &ier); pggst_drawGhost (GST_NORMAL); } _selectFlag = FALSE; mbotw_mouseSet(LMHINT_NEXT, MMHINT_DONE); if ( _drawGhost ) { mcanvw_setDragFunc((XtEventHandler)&pgconn_ghost, CURS_DEFAULT); } if ( _isGFA ) { cvg_freeElPtr ( &secondary_el ); if ( !_drawGhost ) cvg_freeElPtr ( &GFA_el ); } } else { /* unselecting primary element */ if ( _isGFA ) { cvg_freeElPtr ( &_primaryEl ); } mcanvw_disarmDynamic (); _selectFlag = FALSE; pghdlb_deselectAll(); mcanvw_setPressFunc ((XtEventHandler)&pgevt_locateElmCb, CURS_DEFAULT); _selectFlag = FALSE; mbotw_mouseSet(LMHINT_SELECT, MMHINT_EXIT); } } }