⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 edit.c

📁 Source code for an Numeric Cmputer
💻 C
📖 第 1 页 / 共 2 页
字号:
void ApplyNewArithmExpr(){    int NumExpr;    for (NumExpr = 0; NumExpr < NBR_ARITHM_EXPR; NumExpr++)	strcpy(ArithmExpr[NumExpr].Expr, EditArithmExpr[NumExpr].Expr);}void CheckForFreeingArithmExpr(int PosiX, int PosiY){    int TypeElement = EditDatas.Rung.Element[PosiX][PosiY].Type;    if ((TypeElement == ELE_COMPAR) || (TypeElement == ELE_OUTPUT_OPERATE)) {	/* Freeing Expr */	EditArithmExpr[EditDatas.Rung.Element[PosiX][PosiY].VarNum].Expr[0] =	    '\0';    }}void CheckForAllocatingArithmExpr(int PosiX, int PosiY){    int TypeElement = EditDatas.Rung.Element[PosiX][PosiY].Type;    int NumExpr = 0;    int Found = FALSE;    if ((TypeElement == ELE_COMPAR) || (TypeElement == ELE_OUTPUT_OPERATE)) {	do {	    /* Expr free ? */	    if (EditArithmExpr[NumExpr].Expr[0] == '\0') {		Found = TRUE;		/* Allocate this expr for the operate/compar block ! */		EditDatas.Rung.Element[PosiX][PosiY].VarNum = NumExpr;	    }	    NumExpr++;	}	while ((NumExpr < NBR_ARITHM_EXPR) && (!Found));    }}void InitBufferRungEdited(StrRung * pRung){    int x, y;    for (y = 0; y < RUNG_HEIGHT; y++) {	for (x = 0; x < RUNG_WIDTH; x++) {	    pRung->Element[x][y].Type = ELE_FREE;	    pRung->Element[x][y].ConnectedWithTop = 0;	    pRung->Element[x][y].VarType = 0;	    pRung->Element[x][y].VarNum = 0;	    pRung->Element[x][y].DynamicState = 0;	}    }    pRung->Used = TRUE;    pRung->PrevRung = -1;    pRung->NextRung = -1;}int GetNbrRungsDefined(void){    int NbrRungsUsed = 0;    int ScanRung;    for (ScanRung = 0; ScanRung < NBR_RUNGS; ScanRung++) {	if (RungArray[ScanRung].Used)	    NbrRungsUsed++;    }    return NbrRungsUsed;}int FindFreeRung(){    int NumFree = -1;    int ScanRung = 0;    do {	if (!RungArray[ScanRung].Used)	    NumFree = ScanRung;	ScanRung++;    }    while ((NumFree == -1) && (ScanRung < NBR_RUNGS));    return NumFree;}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);}/* 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;	}	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)	    CheckForBlocksOfBigElement(&RungX, &RungY);	if (EditDatas.NumElementSelectedInToolBar < ELE_UNUSABLE) {	    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 = ELE_FREE;	    }	    /* apply the new element */	    if (NumElement == ELE_FREE) {		/* 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;		EditDatas.Rung.Element[RungX][RungY].Type = NumElement;	    } 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}void CopyRungToRung(StrRung * RungSrc, StrRung * RungDest){    memcpy(RungDest, RungSrc, sizeof(StrRung));}

⌨️ 快捷键说明

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