edit.c

来自「CNC 的开放码,EMC2 V2.2.8版」· C语言 代码 · 共 1,270 行 · 第 1/3 页

C
1,270
字号
void AddRung(){	InitBufferRungEdited( &EditDatas.Rung );	EditDatas.DoBeforeFinalCopy = MODE_ADD;	EditDatas.NumRung = FindFreeRung();	/* we have found a free rung ? */	if (EditDatas.NumRung>=0)	{		EditDatas.ModeEdit = TRUE;		EditDatas.ElementUnderEdit = NULL;		autorize_prevnext_buttons(FALSE);		clear_label_comment();		CopyCurrentArithmExpr();	}}void InsertRung(){	/* not really different than adding a rung... */	AddRung();	EditDatas.DoBeforeFinalCopy = MODE_INSERT;}void ModifyCurrentRung(){	CopyRungToRung(&RungArray[InfosGene->CurrentRung],&EditDatas.Rung);	EditDatas.DoBeforeFinalCopy = MODE_MODIFY;	EditDatas.NumRung = InfosGene->CurrentRung;	EditDatas.ModeEdit = TRUE;	EditDatas.ElementUnderEdit = NULL;	autorize_prevnext_buttons(FALSE);	CopyCurrentArithmExpr();}void DeleteCurrentRung(){	int NextDeleted;	int PrevDeleted;	int NewCurrent;	int OldCurrent;	int x,y;	/* do not destroy the last one ! */	if ( !((InfosGene->CurrentRung==InfosGene->FirstRung) && (InfosGene->CurrentRung==InfosGene->LastRung)) )	{		PrevDeleted = RungArray[InfosGene->CurrentRung].PrevRung;		NextDeleted = RungArray[InfosGene->CurrentRung].NextRung;		NewCurrent = NextDeleted;		/* deleting first rung ?*/		if (InfosGene->CurrentRung==InfosGene->FirstRung)		{			InfosGene->FirstRung = NextDeleted;		}		else		{			RungArray[PrevDeleted].NextRung = NextDeleted;		}		/* deleting last rung ? */		if (InfosGene->CurrentRung==InfosGene->LastRung)		{			InfosGene->LastRung = PrevDeleted;			NewCurrent = InfosGene->LastRung;		}		else		{			RungArray[NextDeleted].PrevRung = PrevDeleted;		}		/* the rung is now free ! */		OldCurrent = InfosGene->CurrentRung;		RungArray[InfosGene->CurrentRung].Used = FALSE;		InfosGene->CurrentRung = NewCurrent;		DrawRungs();		UpdateVScrollBar();		refresh_label_comment( );		/* save infos for the current section */		SectionArray[ InfosGene->CurrentSection ].FirstRung = InfosGene->FirstRung;		SectionArray[ InfosGene->CurrentSection ].LastRung = InfosGene->LastRung;		/* kill the expressions used on the rung deleted */		for (y=0;y<RUNG_HEIGHT;y++)		{			for(x=0;x<RUNG_WIDTH;x++)			{				if ( (RungArray[OldCurrent].Element[x][y].Type == ELE_COMPAR)				|| (RungArray[OldCurrent].Element[x][y].Type == ELE_OUTPUT_OPERATE) )				{					strcpy(ArithmExpr[ RungArray[OldCurrent].Element[x][y].VarNum ].Expr,"");				}			}		}	}}void CancelRungEdited(){	EditDatas.ModeEdit = FALSE;	EditDatas.ElementUnderEdit = NULL;	EditDatas.NumElementSelectedInToolBar = -1;	LoadElementProperties(NULL);	DrawRungs();	refresh_label_comment( );	autorize_prevnext_buttons(TRUE);}void ApplyRungEdited(){	int PrevNew;	int NextNew;	save_label_comment_edited();	CopyRungToRung(&EditDatas.Rung,&RungArray[EditDatas.NumRung]);	ApplyNewArithmExpr();	/* if we have added or inserted, we will have to */	/* modify the links between rungs */	/* order is important when setting all this, if multi-tasking : */	/* calc.c is using only .NextRung to updates all the rungs. */	/* and also global FirstRung & LastRung to start and end */	switch(EditDatas.DoBeforeFinalCopy)	{		/* Add rung edited after current rung */		case MODE_ADD:			PrevNew = InfosGene->CurrentRung;			NextNew = RungArray[InfosGene->CurrentRung].NextRung;			RungArray[EditDatas.NumRung].PrevRung = PrevNew;			/* new added is not the last now ? */			if (InfosGene->CurrentRung!=InfosGene->LastRung)			{				RungArray[EditDatas.NumRung].NextRung = NextNew;				RungArray[NextNew].PrevRung = EditDatas.NumRung;			}			RungArray[PrevNew].NextRung = EditDatas.NumRung;			/* we can now update LastRung */			if (InfosGene->CurrentRung==InfosGene->LastRung)			{				InfosGene->LastRung = EditDatas.NumRung;			}			/* Here is the new current ! */			InfosGene->CurrentRung = EditDatas.NumRung;			UpdateVScrollBar();			break;		/* Insert rung edited before current rung */		case MODE_INSERT:			PrevNew = RungArray[InfosGene->CurrentRung].PrevRung;			NextNew = InfosGene->CurrentRung;			RungArray[EditDatas.NumRung].NextRung = NextNew;			/* new added is not the first now ? */			if (InfosGene->CurrentRung!=InfosGene->FirstRung)			{				RungArray[EditDatas.NumRung].PrevRung = PrevNew;				RungArray[PrevNew].NextRung = EditDatas.NumRung;			}			else			{				InfosGene->FirstRung = EditDatas.NumRung;			}			RungArray[NextNew].PrevRung = EditDatas.NumRung;			/* Here is the new current ! */			InfosGene->CurrentRung = EditDatas.NumRung;			UpdateVScrollBar();			break;	}	/* save infos for the current section */	SectionArray[ InfosGene->CurrentSection ].FirstRung = InfosGene->FirstRung;	SectionArray[ InfosGene->CurrentSection ].LastRung = InfosGene->LastRung;	EditDatas.ModeEdit = FALSE;	EditDatas.ElementUnderEdit = NULL;	EditDatas.NumElementSelectedInToolBar = -1;	LoadElementProperties(NULL);	DrawRungs();	autorize_prevnext_buttons(TRUE);	InfosGene->AskConfirmationToQuit = TRUE;}/* When we fall on an "unusable" element of a big one,we return new posix and posiy of the "alive" block */void CheckForBlocksOfBigElement(int * PosiX,int * PosiY){	int ScanX,ScanY;	int ScanForRule;	/* on an "unusable" ? */	if (EditDatas.Rung.Element[*PosiX][*PosiY].Type==ELE_UNUSABLE)	{		/* we now will have to check for all the "alive" block of		bigs elements */		for (ScanY=0;ScanY<RUNG_HEIGHT;ScanY++)		{			for(ScanX=0;ScanX<RUNG_WIDTH;ScanX++)			{				ScanForRule = 0;				do				{					/* Is is an element with a rule ? */					if (EditDatas.Rung.Element[ScanX][ScanY].Type == RulesForSpecialElements[ScanForRule][TYPEELERULE])					{						/* Have we clicked in it ? */						if ( (*PosiX>=ScanX-RulesForSpecialElements[ScanForRule][XSIZEELERULE]-1)							&& (*PosiX<=ScanX)							&& (*PosiY>=ScanY)							&& (*PosiY<=ScanY+RulesForSpecialElements[ScanForRule][YSIZEELERULE]-1) )						{							/* We've got it ! */							/* We make as we have clicked on the "alive" block ! */							*PosiX = ScanX;							*PosiY = ScanY;							return;						}					}					ScanForRule++;				}				while(RulesForSpecialElements[ScanForRule][0]!=-1);			}		}	}}int VerifyRulesForElement(short int NumEle,int PosiX,int PosiY){	int RulePass;	int ItIsOk = TRUE;	int ItIsAnOutputEle = FALSE;	if ( (NumEle==ELE_OUTPUT) || (NumEle==ELE_OUTPUT_NOT)			|| (NumEle==ELE_OUTPUT_SET) || (NumEle==ELE_OUTPUT_RESET)			|| (NumEle==ELE_OUTPUT_JUMP) || (NumEle==ELE_OUTPUT_CALL)			|| (NumEle==ELE_OUTPUT_OPERATE) )		ItIsAnOutputEle = TRUE;	/* verify for outputs if we are under output zone (right column) */	if ( (PosiX==RUNG_WIDTH-1) && !ItIsAnOutputEle )	{			ItIsOk = FALSE;	}	/* verify for inputs if we are under input zone (not right column) */	if ( (PosiX<RUNG_WIDTH-1) && ItIsAnOutputEle )	{			ItIsOk = FALSE;	}	/* verify if for elements bigger than one block it will fit */	RulePass = 0;	do	{		if ( RulesForSpecialElements[RulePass][TYPEELERULE] == NumEle )		{			if ( (PosiX-RulesForSpecialElements[RulePass][XSIZEELERULE]+1 < 0)				|| (PosiY+RulesForSpecialElements[RulePass][YSIZEELERULE]-1 >= RUNG_HEIGHT) )				ItIsOk = FALSE;		}		RulePass++;	}	while(RulesForSpecialElements[RulePass][0]!=-1);	/* verify if we are not on another part of a big element ! */	if (EditDatas.Rung.Element[PosiX][PosiY].Type==ELE_UNUSABLE)		ItIsOk = FALSE;	return ItIsOk;}/* used for destroying or adding a big element *//* when destroying : filling all the blocks with ELE_FREE *//* when adding : filling all the blocks with ELE_UNUSABLE *//* the block "alive" is written elsewhere */void CleanForBigElement(short int NumEle,int PosiX,int PosiY,short int FillWithThis){	int RulePass;	int PassX,PassY;	RulePass = 0;	do	{		if (RulesForSpecialElements[RulePass][TYPEELERULE] == NumEle )		{			for (PassX = PosiX - RulesForSpecialElements[RulePass][XSIZEELERULE] +1 ; PassX<=PosiX ; PassX++)			{				for (PassY = PosiY ; PassY<=PosiY + RulesForSpecialElements[RulePass][YSIZEELERULE] -1 ; PassY++)				{					CheckForFreeingArithmExpr(PassX,PassY);					EditDatas.Rung.Element[PassX][PassY].Type = FillWithThis;					EditDatas.Rung.Element[PassX][PassY].ConnectedWithTop = 0;					EditDatas.Rung.Element[PassX][PassY].DynamicOutput = 0;				}			}		}		RulePass++;	}	while(RulesForSpecialElements[RulePass][0]!=-1);}void CheckBigElementTopLeft(short int NumEle,int * PosiX){	int RulePass;	RulePass = 0;	do	{		if (RulesForSpecialElements[RulePass][TYPEELERULE] == NumEle )		{			*PosiX = *PosiX + RulesForSpecialElements[RulePass][XSIZEELERULE] - 1;			if ( *PosiX>=RUNG_WIDTH )			{				*PosiX = RUNG_WIDTH-1;			}		}		RulePass++;	}	while(RulesForSpecialElements[RulePass][0]!=-1);}/* return TRUE if contact or coil element */int IsASimpleElement(int Element){	int Res = FALSE;	if ( (Element==ELE_INPUT) || (Element==ELE_INPUT_NOT)		|| (Element==ELE_RISING_INPUT) || (Element==ELE_FALLING_INPUT)		|| (Element==ELE_OUTPUT) || (Element==ELE_OUTPUT_NOT)		|| (Element==ELE_OUTPUT_SET) || (Element==ELE_OUTPUT_RESET)		|| (Element==ELE_OUTPUT_JUMP) || (Element==ELE_OUTPUT_CALL) )		Res = TRUE;	return Res;}/* click with the mouse in x and y pixels of the rung */void EditElementInRung(double x,double y){	int RungX,RungY;	short int NumElement;	/* correspond to which block ? */	RungX = x/InfosGene->BlockWidth;	RungY = y/InfosGene->BlockHeight;	if ( (RungX<RUNG_WIDTH) && (RungY<RUNG_HEIGHT)		&& (EditDatas.NumElementSelectedInToolBar!=-1) )	{		/* check for "unusable" blocks */		if (EditDatas.NumElementSelectedInToolBar==EDIT_POINTER || EditDatas.NumElementSelectedInToolBar==EDIT_ERASER )			CheckForBlocksOfBigElement(&RungX,&RungY);		if (EditDatas.NumElementSelectedInToolBar!=EDIT_CNX_WITH_TOP				&& EditDatas.NumElementSelectedInToolBar!=EDIT_POINTER				&& EditDatas.NumElementSelectedInToolBar!=EDIT_LONG_CONNECTION )		{			NumElement = EditDatas.NumElementSelectedInToolBar;			/* For big element, click insert top-left of the element */			CheckBigElementTopLeft(NumElement,&RungX);			/* already the same element ? => if yes kill it! */			if (NumElement==EditDatas.Rung.Element[RungX][RungY].Type)			{				NumElement = EDIT_ERASER;			}			/* apply the new element */			if (NumElement==EDIT_ERASER)			{                                /* the blocks other than the "alive" are now free... */				CleanForBigElement(EditDatas.Rung.Element[RungX][RungY].Type,RungX,RungY,ELE_FREE);			        EditDatas.Rung.Element[RungX][RungY].DynamicOutput = 0;                                if (((x-RungX*InfosGene->BlockWidth)>=0) && ((x-RungX*InfosGene->BlockWidth)<=15)                                    && (EditDatas.Rung.Element[RungX][RungY].ConnectedWithTop))				      {			                   				            EditDatas.Rung.Element[RungX][RungY].ConnectedWithTop = 0;			              }else{				           EditDatas.Rung.Element[RungX][RungY].Type = ELE_FREE;			                   }							}			else			{				if (VerifyRulesForElement(NumElement,RungX,RungY))				{					/* the blocks other than the "alive" are now free... */					CleanForBigElement(EditDatas.Rung.Element[RungX][RungY].Type,RungX,RungY,ELE_FREE);					/* for big element with only one block "alive" we must mark the others */					/* blocks as unusable */					CleanForBigElement(NumElement,RungX,RungY,ELE_UNUSABLE);					// if not a simple element (contact/coil) replaced by a simple element, clean VarNum					if ( !(IsASimpleElement(NumElement) && IsASimpleElement(EditDatas.Rung.Element[RungX][RungY].Type)) )					{						EditDatas.Rung.Element[RungX][RungY].VarNum = 0;					}					EditDatas.Rung.Element[RungX][RungY].Type = NumElement;					CheckForAllocatingArithmExpr(RungX,RungY);				}			}		}		if (EditDatas.NumElementSelectedInToolBar==EDIT_CNX_WITH_TOP)		{			if (EditDatas.Rung.Element[RungX][RungY].ConnectedWithTop)			{				EditDatas.Rung.Element[RungX][RungY].ConnectedWithTop = 0;			}			else			{				if (RungY>0)					EditDatas.Rung.Element[RungX][RungY].ConnectedWithTop = 1;			}		}		if (EditDatas.NumElementSelectedInToolBar==EDIT_LONG_CONNECTION)		{			int ScanX = RungX;			while(EditDatas.Rung.Element[ScanX][RungY].Type==ELE_FREE && ScanX<RUNG_WIDTH-1 )			{				EditDatas.Rung.Element[ScanX++][RungY].Type = ELE_CONNECTION;			}		}		LoadElementProperties(&EditDatas.Rung.Element[RungX][RungY]);		EditDatas.ElementUnderEdit = &EditDatas.Rung.Element[RungX][RungY];	}}/* click with the mouse in x and y pixels of the section display */void EditElementInThePage(double x,double y){	int iCurrentLanguage = SectionArray[ InfosGene->CurrentSection ].Language;	if ( iCurrentLanguage==SECTION_IN_LADDER )	{		if ( ( y >= InfosGene->OffsetCurrentRungDisplayed ) && ( y < InfosGene->OffsetCurrentRungDisplayed+InfosGene->BlockHeight*RUNG_HEIGHT ) )			EditElementInRung( x, y - InfosGene->OffsetCurrentRungDisplayed );	}#ifdef SEQUENTIAL_SUPPORT	if ( iCurrentLanguage==SECTION_IN_SEQUENTIAL )		EditElementInSeqPage( x+InfosGene->HScrollValue, y+InfosGene->VScrollValue );#endif}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?