📄 edit.c
字号:
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 + -