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

📄 draw.cpp

📁 plc软件的源代码 支持PIC ATMEGA单片机
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                    memcpy(s1+strlen(leaf->d.cmp.op1)+2, s, strlen(s));
                    memcpy(s2+2, leaf->d.cmp.op2, strlen(leaf->d.cmp.op2));
                } else {
                    strcpy(s1, "");
                    strcpy(s2, TOO_LONG);
                }

                CenterWithSpaces(*cx, *cy, s1, poweredAfter, FALSE);
                CenterWithWires(*cx, *cy, s2, poweredBefore, poweredAfter);

                *cx += POS_WIDTH;
                break;
        }
        case ELEM_OPEN:
            CenterWithWires(*cx, *cy, "+      +", poweredBefore, poweredAfter);
            *cx += POS_WIDTH;
            break;

        case ELEM_SHORT:
            CenterWithWires(*cx, *cy, "+------+", poweredBefore, poweredAfter);
            *cx += POS_WIDTH;
            break;

        case ELEM_ONE_SHOT_RISING:
        case ELEM_ONE_SHOT_FALLING: {
            char *s1, *s2;
            if(which == ELEM_ONE_SHOT_RISING) {
                s1 = "      _ ";
                s2 = "[\x01OSR\x02_/ ]";
            } else if(which == ELEM_ONE_SHOT_FALLING) {
                s1 = "    _   ";
                s2 = "[\x01OSF\x02 \\_]";
            } else oops();

            CenterWithSpaces(*cx, *cy, s1, poweredAfter, FALSE);
            CenterWithWires(*cx, *cy, s2, poweredBefore, poweredAfter);

            *cx += POS_WIDTH;
            break;
        }
        case ELEM_CTU:
        case ELEM_CTD: {
            char *s;
            if(which == ELEM_CTU)
                s = "\x01""CTU\x02";
            else if(which == ELEM_CTD)
                s = "\x01""CTD\x02";
            else oops();

            char buf[256];
            ElemCounter *c = &leaf->d.counter;
            sprintf(buf, "[%s >=%d]", s, c->max);

            CenterWithSpaces(*cx, *cy, c->name, poweredAfter, TRUE);
            CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter);

            *cx += POS_WIDTH;
            break;
        }
        case ELEM_RTO:
        case ELEM_TON:
        case ELEM_TOF: {
            char *s;
            if(which == ELEM_TON)
                s = "\x01TON\x02";
            else if(which == ELEM_TOF)
                s = "\x01TOF\x02";
            else if(which == ELEM_RTO)
                s = "\x01RTO\x02";
            else oops();

            char buf[256];
            ElemTimer *t = &leaf->d.timer;
            if(t->delay >= 1000*1000) {
                sprintf(buf, "[%s %.3f s]", s, t->delay/1000000.0);
            } else if(t->delay >= 100*1000) {
                sprintf(buf, "[%s %.1f ms]", s, t->delay/1000.0);
            } else {
                sprintf(buf, "[%s %.2f ms]", s, t->delay/1000.0);
            }

            CenterWithSpaces(*cx, *cy, t->name, poweredAfter, TRUE);
            CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter);

            *cx += POS_WIDTH;
            break;
        }
        case ELEM_FORMATTED_STRING: {
            char bot[100];
            sprintf(bot, "{\"%s\"}", leaf->d.fmtdStr.string);

            int extra = 2*POS_WIDTH - strlen(leaf->d.fmtdStr.var);
            PoweredText(poweredAfter);
            NameText();
            DrawChars(*cx + (extra/2), *cy + (POS_HEIGHT/2) - 1,
                leaf->d.fmtdStr.var);
            BodyText();

            CenterWithWiresWidth(*cx, *cy, bot, poweredBefore, poweredAfter,
                2*POS_WIDTH);
            *cx += 2*POS_WIDTH;
            break;
        }
        case ELEM_UART_RECV:
        case ELEM_UART_SEND:
            CenterWithWires(*cx, *cy,
                (which == ELEM_UART_RECV) ? "{UART RECV}" : "{UART SEND}",
                poweredBefore, poweredAfter);
            CenterWithSpaces(*cx, *cy, leaf->d.uart.name, poweredAfter, TRUE);
            *cx += POS_WIDTH;
            break;

        default:
            poweredAfter = DrawEndOfLine(which, leaf, cx, cy, poweredBefore);
            break;
    }

    // And now we can enter the element into the display matrix so that the
    // UI routines know what element is at position (gx, gy) when the user
    // clicks there, and so that we know where to put the cursor if this
    // element is selected.

    // Don't use original cx0, as an end of line element might be further
    // along than that.
    cx0 = *cx - POS_WIDTH;

    int gx = cx0/POS_WIDTH;
    int gy = cy0/POS_HEIGHT;
    if(CheckBoundsUndoIfFails(gx, gy)) return FALSE;
    DM_BOUNDS(gx, gy);

    DisplayMatrix[gx][gy] = leaf;
    DisplayMatrixWhich[gx][gy] = which;

    int xadj = 0;
    switch(which) {
        case ELEM_ADD:
        case ELEM_SUB:
        case ELEM_MUL:
        case ELEM_DIV:
        case ELEM_FORMATTED_STRING:
            DM_BOUNDS(gx-1, gy);
            DisplayMatrix[gx-1][gy] = leaf;
            DisplayMatrixWhich[gx-1][gy] = which;
            xadj = POS_WIDTH*FONT_WIDTH;
            break;
    }

    if(which == ELEM_COMMENT) {
        int i;
        for(i = 0; i < ColsAvailable; i++) {
            DisplayMatrix[i][gy] = leaf;
            DisplayMatrixWhich[i][gy] = ELEM_COMMENT;
        }
        xadj = (ColsAvailable-1)*POS_WIDTH*FONT_WIDTH;
    }

    int x0 = X_PADDING + cx0*FONT_WIDTH;
    int y0 = Y_PADDING + cy0*FONT_HEIGHT;

    if(leaf->selectedState != SELECTED_NONE && leaf == Selected) {
        SelectionActive = TRUE;
    }
    switch(leaf->selectedState) {
        case SELECTED_LEFT:
            Cursor.left = x0 + FONT_WIDTH - 4 - xadj;
            Cursor.top = y0 - FONT_HEIGHT/2;
            Cursor.width = 2;
            Cursor.height = POS_HEIGHT*FONT_HEIGHT;
            break;

        case SELECTED_RIGHT:
            Cursor.left = x0 + (POS_WIDTH-1)*FONT_WIDTH - 5;
            Cursor.top = y0 - FONT_HEIGHT/2;
            Cursor.width = 2;
            Cursor.height = POS_HEIGHT*FONT_HEIGHT;
            break;

        case SELECTED_ABOVE:
            Cursor.left = x0 + FONT_WIDTH/2 - xadj;
            Cursor.top = y0 - 2;
            Cursor.width = (POS_WIDTH-2)*FONT_WIDTH + xadj;
            Cursor.height = 2;
            break;

        case SELECTED_BELOW:
            Cursor.left = x0 + FONT_WIDTH/2 - xadj;
            Cursor.top = y0 + (POS_HEIGHT-1)*FONT_HEIGHT +
                FONT_HEIGHT/2 - 2;
            Cursor.width = (POS_WIDTH-2)*(FONT_WIDTH) + xadj;
            Cursor.height = 2;
            break;

        default:
            break;
    }

    return poweredAfter;
}

//-----------------------------------------------------------------------------
// Draw a particular subcircuit with its top left corner at *cx and *cy (in
// characters). If it is a leaf element then just print it and return; else
// loop over the elements of the subcircuit and call ourselves recursively.
// At the end updates *cx and *cy.
//
// In simulation mode, returns TRUE the circuit is energized after the given
// element, else FALSE. This is needed to colour all the wires correctly,
// since the colouring indicates whether a wire is energized.
//-----------------------------------------------------------------------------
BOOL DrawElement(int which, void *elem, int *cx, int *cy, BOOL poweredBefore)
{
    BOOL poweredAfter;

    int cx0 = *cx, cy0 = *cy;
    ElemLeaf *leaf = (ElemLeaf *)elem;

    SetBkColor(Hdc, InSimulationMode ? HighlightColours.simBg :
        HighlightColours.bg);
    NormText();

    if(elem == Selected && !InSimulationMode) {
        EmphText();
        ThisHighlighted = TRUE;
    } else {
        ThisHighlighted = FALSE;
    }

    switch(which) {
        case ELEM_SERIES_SUBCKT: {
            int i;
            ElemSubcktSeries *s = (ElemSubcktSeries *)elem;
            poweredAfter = poweredBefore;
            for(i = 0; i < s->count; i++) {
                poweredAfter = DrawElement(s->contents[i].which,
                    s->contents[i].d.any, cx, cy, poweredAfter);
            }
            break;
        }
        case ELEM_PARALLEL_SUBCKT: {
            int i;
            ElemSubcktParallel *p = (ElemSubcktParallel *)elem;
            int widthMax = CountWidthOfElement(which, elem, (*cx)/POS_WIDTH);
            int heightMax = CountHeightOfElement(which, elem);

            poweredAfter = FALSE;

            int lowestPowered = -1;
            int downBy = 0;
            for(i = 0; i < p->count; i++) {
                BOOL poweredThis;

                poweredThis = DrawElement(p->contents[i].which,
                    p->contents[i].d.any, cx, cy, poweredBefore);

                if(InSimulationMode) {
                    if(poweredThis) poweredAfter = TRUE;
                    PoweredText(poweredThis);
                }

                while((*cx - cx0) < widthMax*POS_WIDTH) {
                    int gx = *cx/POS_WIDTH;
                    int gy = *cy/POS_HEIGHT;

                    if(CheckBoundsUndoIfFails(gx, gy)) return FALSE;

                    DM_BOUNDS(gx, gy);
                    DisplayMatrix[gx][gy] = PADDING_IN_DISPLAY_MATRIX;
                    DisplayMatrixWhich[gx][gy] = ELEM_PADDING;

                    char buf[256];
                    int j;
                    for(j = 0; j < POS_WIDTH; j++) {
                        buf[j] = '-';
                    }
                    buf[j] = '\0';
                    DrawChars(*cx, *cy + (POS_HEIGHT/2), buf);
                    *cx += POS_WIDTH;
                }

                *cx = cx0;
                int justDrewHeight = CountHeightOfElement(p->contents[i].which,
                    p->contents[i].d.any);
                *cy += POS_HEIGHT*justDrewHeight;

                downBy += justDrewHeight;
                if(poweredThis) {
                    lowestPowered = downBy - 1;
                }
            }
            *cx = cx0 + POS_WIDTH*widthMax;
            *cy = cy0;

            int j;
            BOOL needWire;

            if(*cx/POS_WIDTH != ColsAvailable) {
                needWire = FALSE;
                for(j = heightMax - 1; j >= 1; j--) {
                    if(j <= lowestPowered) PoweredText(poweredAfter);
                    if(DisplayMatrix[*cx/POS_WIDTH - 1][*cy/POS_HEIGHT + j]) {
                        needWire = TRUE;
                    }
                    if(needWire) VerticalWire(*cx - 1, *cy + j*POS_HEIGHT);
                }
                // stupid special case
                if(lowestPowered == 0 && InSimulationMode) {
                    EmphText();
                    DrawChars(*cx - 1, *cy + (POS_HEIGHT/2), "+");
                }
            }

            PoweredText(poweredBefore);
            needWire = FALSE;
            for(j = heightMax - 1; j >= 1; j--) {
                if(DisplayMatrix[cx0/POS_WIDTH][*cy/POS_HEIGHT + j]) {
                    needWire = TRUE;
                }
                if(needWire) VerticalWire(cx0 - 1, *cy + j*POS_HEIGHT);
            }

            break;
        }
        default:
            poweredAfter = DrawLeaf(which, leaf, cx, cy, poweredBefore);
            break;
    }


    NormText();
    return poweredAfter;
}

//-----------------------------------------------------------------------------
// Draw the rung that signals the end of the program. Kind of useless but
// do it anyways, for convention.
//-----------------------------------------------------------------------------
void DrawEndRung(int cx, int cy)
{
    int i;
    char *str = "[END]";
    int lead = (POS_WIDTH - strlen(str))/2;
    ThisHighlighted = TRUE;
    for(i = 0; i < lead; i++) {
        DrawChars(cx + i, cy + (POS_HEIGHT/2), "-");
    }
    DrawChars(cx + i, cy + (POS_HEIGHT/2), str);
    i += strlen(str);
    for(; i < ColsAvailable*POS_WIDTH; i++) {
        DrawChars(cx + i, cy + (POS_HEIGHT/2), "-");
    }
}

⌨️ 快捷键说明

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