📄 schematic.cpp
字号:
if(!Selected || Selected->selectedState == SELECTED_NONE) {
break;
}
if(Selected->selectedState != SELECTED_BELOW &&
SelectedWhich != ELEM_PLACEHOLDER)
{
SelectElement(-1, -1, SELECTED_BELOW);
break;
}
int i, j;
if(FindSelected(&i, &j)) {
j++;
while(j < DISPLAY_MATRIX_Y_SIZE &&
!VALID_LEAF(DisplayMatrix[i][j]))
{
j++;
}
if(j != DISPLAY_MATRIX_Y_SIZE) {
SelectElement(i, j, SELECTED_ABOVE);
} else if(ScrollYOffsetMax - ScrollYOffset < 3) {
// special case: scroll the end marker into view
ScrollYOffset = ScrollYOffsetMax;
RefreshScrollbars();
}
}
break;
}
}
}
//-----------------------------------------------------------------------------
// Edit the selected element. Pop up the appropriate modal dialog box to do
// this.
//-----------------------------------------------------------------------------
void EditSelectedElement(void)
{
if(!Selected || Selected->selectedState == SELECTED_NONE) return;
switch(SelectedWhich) {
case ELEM_COMMENT:
ShowCommentDialog(Selected->d.comment.str);
break;
case ELEM_CONTACTS:
ShowContactsDialog(&(Selected->d.contacts.negated),
Selected->d.contacts.name);
break;
case ELEM_COIL:
ShowCoilDialog(&(Selected->d.coil.negated),
&(Selected->d.coil.setOnly), &(Selected->d.coil.resetOnly),
Selected->d.coil.name);
break;
case ELEM_TON:
case ELEM_TOF:
case ELEM_RTO:
ShowTimerDialog(SelectedWhich, &(Selected->d.timer.delay),
Selected->d.timer.name);
break;
case ELEM_CTU:
case ELEM_CTD:
case ELEM_CTC:
ShowCounterDialog(SelectedWhich, &(Selected->d.counter.max),
Selected->d.counter.name);
break;
case ELEM_EQU:
case ELEM_NEQ:
case ELEM_GRT:
case ELEM_GEQ:
case ELEM_LES:
case ELEM_LEQ:
ShowCmpDialog(SelectedWhich, Selected->d.cmp.op1,
Selected->d.cmp.op2);
break;
case ELEM_ADD:
case ELEM_SUB:
case ELEM_MUL:
case ELEM_DIV:
ShowMathDialog(SelectedWhich, Selected->d.math.dest,
Selected->d.math.op1, Selected->d.math.op2);
break;
case ELEM_RES:
ShowResetDialog(Selected->d.reset.name);
break;
case ELEM_MOVE:
ShowMoveDialog(Selected->d.move.dest, Selected->d.move.src);
break;
case ELEM_SET_PWM:
ShowSetPwmDialog(Selected->d.setPwm.name,
&(Selected->d.setPwm.targetFreq));
break;
case ELEM_READ_ADC:
ShowReadAdcDialog(Selected->d.readAdc.name+1);
break;
case ELEM_UART_RECV:
case ELEM_UART_SEND:
ShowUartDialog(SelectedWhich, Selected->d.uart.name);
break;
case ELEM_PERSIST:
ShowPersistDialog(Selected->d.persist.var);
break;
case ELEM_SHIFT_REGISTER:
ShowShiftRegisterDialog(Selected->d.shiftRegister.name,
&(Selected->d.shiftRegister.stages));
break;
case ELEM_FORMATTED_STRING:
ShowFormattedStringDialog(Selected->d.fmtdStr.var,
Selected->d.fmtdStr.string);
break;
case ELEM_PIECEWISE_LINEAR:
ShowPiecewiseLinearDialog(Selected);
break;
case ELEM_LOOK_UP_TABLE:
ShowLookUpTableDialog(Selected);
break;
}
}
//-----------------------------------------------------------------------------
// Edit the element under the mouse cursor. This will typically be the
// selected element, since the first click would have selected it. If there
// is no element under the mouser cursor then do nothing; do not edit the
// selected element (which is elsewhere on screen), as that would be
// confusing.
//-----------------------------------------------------------------------------
void EditElementMouseDoubleclick(int x, int y)
{
x += ScrollXOffset;
y += FONT_HEIGHT/2;
int gx = (x - X_PADDING)/(POS_WIDTH*FONT_WIDTH);
int gy = (y - Y_PADDING)/(POS_HEIGHT*FONT_HEIGHT);
gy += ScrollYOffset;
if(InSimulationMode) {
ElemLeaf *l = DisplayMatrix[gx][gy];
if(l && DisplayMatrixWhich[gx][gy] == ELEM_CONTACTS) {
char *name = l->d.contacts.name;
if(name[0] == 'X') {
SimulationToggleContact(name);
}
} else if(l && DisplayMatrixWhich[gx][gy] == ELEM_READ_ADC) {
ShowAnalogSliderPopup(l->d.readAdc.name);
}
} else {
if(DisplayMatrix[gx][gy] == Selected) {
EditSelectedElement();
}
}
}
//-----------------------------------------------------------------------------
// Move the cursor in response to a mouse click. If they clicked in a leaf
// element box then figure out which edge they're closest too (with appropriate
// fudge factors to make all edges equally easy to click on) and put the
// cursor there.
//-----------------------------------------------------------------------------
void MoveCursorMouseClick(int x, int y)
{
x += ScrollXOffset;
y += FONT_HEIGHT/2;
int gx0 = (x - X_PADDING)/(POS_WIDTH*FONT_WIDTH);
int gy0 = (y - Y_PADDING)/(POS_HEIGHT*FONT_HEIGHT);
int gx = gx0;
int gy = gy0 + ScrollYOffset;
if(VALID_LEAF(DisplayMatrix[gx][gy])) {
int i, j;
for(i = 0; i < DISPLAY_MATRIX_X_SIZE; i++) {
for(j = 0; j < DISPLAY_MATRIX_Y_SIZE; j++) {
if(DisplayMatrix[i][j])
DisplayMatrix[i][j]->selectedState = SELECTED_NONE;
}
}
int dx = x - (gx0*POS_WIDTH*FONT_WIDTH + X_PADDING);
int dy = y - (gy0*POS_HEIGHT*FONT_HEIGHT + Y_PADDING);
int dtop = dy;
int dbottom = POS_HEIGHT*FONT_HEIGHT - dy;
int dleft = dx;
int dright = POS_WIDTH*FONT_WIDTH - dx;
int extra = 1;
if(DisplayMatrixWhich[gx][gy] == ELEM_COMMENT) {
dleft += gx*POS_WIDTH*FONT_WIDTH;
dright += (ColsAvailable - gx - 1)*POS_WIDTH*FONT_WIDTH;
extra = ColsAvailable;
} else {
if((gx > 0) && (DisplayMatrix[gx-1][gy] == DisplayMatrix[gx][gy])) {
dleft += POS_WIDTH*FONT_WIDTH;
extra = 2;
}
if((gx < (DISPLAY_MATRIX_X_SIZE-1)) &&
(DisplayMatrix[gx+1][gy] == DisplayMatrix[gx][gy]))
{
dright += POS_WIDTH*FONT_WIDTH;
extra = 2;
}
}
int decideX = (dright - dleft);
int decideY = (dtop - dbottom);
decideY = decideY*3*extra;
int state;
if(abs(decideY) > abs(decideX)) {
if(decideY > 0) {
state = SELECTED_BELOW;
} else {
state = SELECTED_ABOVE;
}
} else {
if(decideX > 0) {
state = SELECTED_LEFT;
} else {
state = SELECTED_RIGHT;
}
}
SelectElement(gx, gy, state);
}
}
//-----------------------------------------------------------------------------
// Place the cursor as near to the given point on the grid as possible. Used
// after deleting an element, for example.
//-----------------------------------------------------------------------------
void MoveCursorNear(int gx, int gy)
{
int out = 0;
for(out = 0; out < 8; out++) {
if(gx - out >= 0) {
if(VALID_LEAF(DisplayMatrix[gx-out][gy])) {
SelectElement(gx-out, gy, SELECTED_RIGHT);
return;
}
}
if(gx + out < DISPLAY_MATRIX_X_SIZE) {
if(VALID_LEAF(DisplayMatrix[gx+out][gy])) {
SelectElement(gx+out, gy, SELECTED_LEFT);
return;
}
}
if(gy - out >= 0) {
if(VALID_LEAF(DisplayMatrix[gx][gy-out])) {
SelectElement(gx, gy-out, SELECTED_BELOW);
return;
}
}
if(gy + out < DISPLAY_MATRIX_Y_SIZE) {
if(VALID_LEAF(DisplayMatrix[gx][gy+out])) {
SelectElement(gx, gy+out, SELECTED_ABOVE);
return;
}
}
if(out == 1) {
// Now see if we have a straight shot to the right; might be far
// if we have to go up to a coil or other end of line element.
int across;
for(across = 1; gx+across < DISPLAY_MATRIX_X_SIZE; across++) {
if(VALID_LEAF(DisplayMatrix[gx+across][gy])) {
SelectElement(gx+across, gy, SELECTED_LEFT);
return;
}
if(!DisplayMatrix[gx+across][gy]) break;
}
}
}
MoveCursorTopLeft();
}
//-----------------------------------------------------------------------------
// Negate the selected item, if this is meaningful.
//-----------------------------------------------------------------------------
void NegateSelected(void)
{
switch(SelectedWhich) {
case ELEM_CONTACTS:
Selected->d.contacts.negated = TRUE;
break;
case ELEM_COIL: {
ElemCoil *c = &Selected->d.coil;
c->negated = TRUE;
c->resetOnly = FALSE;
c->setOnly = FALSE;
break;
}
default:
break;
}
}
//-----------------------------------------------------------------------------
// Make the item selected normal: not negated, not set/reset only.
//-----------------------------------------------------------------------------
void MakeNormalSelected(void)
{
switch(SelectedWhich) {
case ELEM_CONTACTS:
Selected->d.contacts.negated = FALSE;
break;
case ELEM_COIL: {
ElemCoil *c = &Selected->d.coil;
c->negated = FALSE;
c->setOnly = FALSE;
c->resetOnly = FALSE;
break;
}
default:
break;
}
}
//-----------------------------------------------------------------------------
// Make the selected item set-only, if it is a coil.
//-----------------------------------------------------------------------------
void MakeSetOnlySelected(void)
{
if(SelectedWhich != ELEM_COIL) return;
ElemCoil *c = &Selected->d.coil;
c->setOnly = TRUE;
c->resetOnly = FALSE;
c->negated = FALSE;
}
//-----------------------------------------------------------------------------
// Make the selected item reset-only, if it is a coil.
//-----------------------------------------------------------------------------
void MakeResetOnlySelected(void)
{
if(SelectedWhich != ELEM_COIL) return;
ElemCoil *c = &Selected->d.coil;
c->resetOnly = TRUE;
c->setOnly = FALSE;
c->negated = FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -