📄 draw_outputdev.cpp
字号:
if(SelectedGxAfterNextPaint >= 0) {
MoveCursorNear(SelectedGxAfterNextPaint, SelectedGyAfterNextPaint);
InvalidateRect(MainWindow, NULL, FALSE);
SelectedGxAfterNextPaint = -1;
SelectedGyAfterNextPaint = -1;
} else if(ScrollSelectedIntoViewAfterNextPaint && Selected) {
SelectElement(-1, -1, Selected->selectedState);
ScrollSelectedIntoViewAfterNextPaint = FALSE;
InvalidateRect(MainWindow, NULL, FALSE);
} else {
if(!SelectionActive) {
if(Prog.numRungs > 0) {
if(MoveCursorTopLeft()) {
InvalidateRect(MainWindow, NULL, FALSE);
}
}
}
}
// draw the `buses' at either side of the screen
r.left = X_PADDING - FONT_WIDTH;
r.top = 0;
r.right = r.left + 4;
r.bottom = IoListTop;
FillRect(Hdc, &r, InSimulationMode ? BusLeftBrush : BusBrush);
r.left += POS_WIDTH*FONT_WIDTH*ColsAvailable + 2;
r.right += POS_WIDTH*FONT_WIDTH*ColsAvailable + 2;
FillRect(Hdc, &r, InSimulationMode ? BusRightBus : BusBrush);
CursorDrawn = FALSE;
BitBlt(paintDc, 0, 0, bw, bh, BackDc, ScrollXOffset, 0, SRCCOPY);
if(InSimulationMode) {
KillTimer(MainWindow, TIMER_BLINK_CURSOR);
} else {
KillTimer(MainWindow, TIMER_BLINK_CURSOR);
BlinkCursor(NULL, 0, NULL, 0);
SetTimer(MainWindow, TIMER_BLINK_CURSOR, 800, BlinkCursor);
}
Hdc = paintDc;
ok();
}
//-----------------------------------------------------------------------------
// Set up the syntax highlighting colours, according to the currently selected
// scheme.
//-----------------------------------------------------------------------------
static void SetSyntaxHighlightingColours(void)
{
static const SyntaxHighlightingColours Schemes[] = {
{
RGB(0, 0, 0), // bg
RGB(255, 255, 225), // def
RGB(255, 110, 90), // selected
RGB(255, 150, 90), // op
RGB(255, 255, 100), // punct
RGB(255, 160, 160), // lit
RGB(120, 255, 130), // name
RGB(130, 130, 130), // rungNum
RGB(130, 130, 245), // comment
RGB(255, 255, 255), // bus
RGB(0, 0, 0), // simBg
RGB(130, 130, 130), // simRungNum
RGB(100, 130, 130), // simOff
RGB(255, 150, 150), // simOn
RGB(255, 150, 150), // simBusLeft
RGB(150, 150, 255), // simBusRight
},
};
memcpy(&HighlightColours, &Schemes[0], sizeof(Schemes[0]));
}
//-----------------------------------------------------------------------------
// Set up the stuff we'll need to draw our schematic diagram. Fonts, brushes,
// pens, etc.
//-----------------------------------------------------------------------------
void InitForDrawing(void)
{
SetSyntaxHighlightingColours();
FixedWidthFont = CreateFont(
FONT_HEIGHT, FONT_WIDTH,
0, 0,
FW_REGULAR,
FALSE,
FALSE,
FALSE,
ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
FF_DONTCARE,
"Lucida Console");
FixedWidthFontBold = CreateFont(
FONT_HEIGHT, FONT_WIDTH-1,
0, 0,
FW_BLACK,
FALSE,
FALSE,
FALSE,
ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
FF_DONTCARE,
"Lucida Console");
LOGBRUSH lb;
lb.lbStyle = BS_SOLID;
lb.lbColor = HighlightColours.simBusRight;
BusRightBus = CreateBrushIndirect(&lb);
lb.lbColor = HighlightColours.simBusLeft;
BusLeftBrush = CreateBrushIndirect(&lb);
lb.lbColor = HighlightColours.bus;
BusBrush = CreateBrushIndirect(&lb);
lb.lbColor = HighlightColours.bg;
BgBrush = CreateBrushIndirect(&lb);
lb.lbColor = HighlightColours.simBg;
SimBgBrush = CreateBrushIndirect(&lb);
}
//-----------------------------------------------------------------------------
// DrawChars function, for drawing to the export buffer instead of to the
// screen.
//-----------------------------------------------------------------------------
static void DrawCharsToExportBuffer(int cx, int cy, char *str)
{
while(*str) {
if(*str >= 10) {
ExportBuffer[cy][cx] = *str;
cx++;
}
str++;
}
}
//-----------------------------------------------------------------------------
// Export a text drawing of the ladder logic program to a file.
//-----------------------------------------------------------------------------
void ExportDrawingAsText(char *file)
{
int maxWidth = ProgCountWidestRow();
ColsAvailable = maxWidth;
int totalHeight = 0;
int i;
for(i = 0; i < Prog.numRungs; i++) {
totalHeight += CountHeightOfElement(ELEM_SERIES_SUBCKT, Prog.rungs[i]);
totalHeight += 1;
}
totalHeight *= POS_HEIGHT;
totalHeight += 3;
ExportBuffer = (char **)CheckMalloc(totalHeight * sizeof(char *));
int l = maxWidth*POS_WIDTH + 8;
for(i = 0; i < totalHeight; i++) {
ExportBuffer[i] = (char *)CheckMalloc(l);
memset(ExportBuffer[i], ' ', l-1);
ExportBuffer[i][4] = '|';
ExportBuffer[i][3] = '|';
ExportBuffer[i][l-3] = '|';
ExportBuffer[i][l-2] = '|';
ExportBuffer[i][l-1] = '\0';
}
DrawChars = DrawCharsToExportBuffer;
int cy = 1;
for(i = 0; i < Prog.numRungs; i++) {
int cx = 5;
DrawElement(ELEM_SERIES_SUBCKT, Prog.rungs[i], &cx, &cy,
Prog.rungPowered[i]);
if((i + 1) < 10) {
ExportBuffer[cy+1][1] = '0' + (i + 1);
} else {
ExportBuffer[cy+1][1] = '0' + ((i + 1) % 10);
ExportBuffer[cy+1][0] = '0' + ((i + 1) / 10);
}
cy += POS_HEIGHT*CountHeightOfElement(ELEM_SERIES_SUBCKT,
Prog.rungs[i]);
cy += POS_HEIGHT;
}
cy -= 2;
DrawEndRung(5, cy);
FILE *f = fopen(file, "w");
if(!f) {
Error(_("Couldn't open '%s'\n"), f);
return;
}
fprintf(f, "LDmicro export text\n");
if(Prog.mcu) {
fprintf(f, "for '%s', %.6f MHz crystal, %.1f ms cycle time\n\n",
Prog.mcu->mcuName, Prog.mcuClock/1e6, Prog.cycleTime/1e3);
} else {
fprintf(f, "no MCU assigned, %.6f MHz crystal, %.1f ms cycle time\n\n",
Prog.mcuClock/1e6, Prog.cycleTime/1e3);
}
fprintf(f, "\nLADDER DIAGRAM:\n\n");
for(i = 0; i < totalHeight; i++) {
ExportBuffer[i][4] = '|';
fprintf(f, "%s\n", ExportBuffer[i]);
CheckFree(ExportBuffer[i]);
}
CheckFree(ExportBuffer[i]);
fprintf(f, _("\n\nI/O ASSIGNMENT:\n\n"));
fprintf(f, _(" Name | Type | Pin\n"));
fprintf(f, " ----------------------------+--------------------+------\n");
for(i = 0; i < Prog.io.count; i++) {
char b[1024];
memset(b, '\0', sizeof(b));
PlcProgramSingleIo *io = &Prog.io.assignment[i];
char *type = IoTypeToString(io->type);
char pin[MAX_NAME_LEN];
PinNumberForIo(pin, io);
sprintf(b, " | | %s\n",
pin);
memcpy(b+2, io->name, strlen(io->name));
memcpy(b+31, type, strlen(type));
fprintf(f, "%s", b);
}
fclose(f);
// we may have trashed the grid tables a bit; a repaint will fix that
InvalidateRect(MainWindow, NULL, FALSE);
}
//-----------------------------------------------------------------------------
// Determine the settings of the vertical and (if needed) horizontal
// scrollbars used to scroll our view of the program.
//-----------------------------------------------------------------------------
void SetUpScrollbars(BOOL *horizShown, SCROLLINFO *horiz, SCROLLINFO *vert)
{
int totalHeight = 0;
int i;
for(i = 0; i < Prog.numRungs; i++) {
totalHeight += CountHeightOfElement(ELEM_SERIES_SUBCKT, Prog.rungs[i]);
totalHeight++;
}
totalHeight += 1; // for the end rung
int totalWidth = ProgCountWidestRow();
if(totalWidth <= ScreenColsAvailable()) {
*horizShown = FALSE;
ScrollXOffset = 0;
ScrollXOffsetMax = 0;
} else {
*horizShown = TRUE;
memset(horiz, 0, sizeof(*horiz));
horiz->cbSize = sizeof(*horiz);
horiz->fMask = SIF_DISABLENOSCROLL | SIF_ALL;
horiz->nMin = 0;
horiz->nMax = X_PADDING + totalWidth*POS_WIDTH*FONT_WIDTH;
RECT r;
GetClientRect(MainWindow, &r);
horiz->nPage = r.right - X_PADDING;
horiz->nPos = ScrollXOffset;
ScrollXOffsetMax = horiz->nMax - horiz->nPage + 1;
if(ScrollXOffset > ScrollXOffsetMax) ScrollXOffset = ScrollXOffsetMax;
if(ScrollXOffset < 0) ScrollXOffset = 0;
}
vert->cbSize = sizeof(*vert);
vert->fMask = SIF_DISABLENOSCROLL | SIF_ALL;
vert->nMin = 0;
vert->nMax = totalHeight - 1;
vert->nPos = ScrollYOffset;
vert->nPage = ScreenRowsAvailable();
ScrollYOffsetMax = vert->nMax - vert->nPage + 1;
if(ScrollYOffset > ScrollYOffsetMax) ScrollYOffset = ScrollYOffsetMax;
if(ScrollYOffset < 0) ScrollYOffset = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -