diff options
Diffstat (limited to 'ldmicro')
-rw-r--r-- | ldmicro/draw_outputdev.cpp | 17 | ||||
-rw-r--r-- | ldmicro/includes/ldmicro.h | 4 | ||||
-rw-r--r-- | ldmicro/iolist.cpp | 225 | ||||
-rw-r--r-- | ldmicro/ldmicro.cpp | 9 | ||||
-rw-r--r-- | ldmicro/lib/linuxUI/linuxUI.cpp | 33 | ||||
-rw-r--r-- | ldmicro/lib/linuxUI/linuxUI.h | 17 | ||||
-rw-r--r-- | ldmicro/maincontrols.cpp | 16 | ||||
-rw-r--r-- | ldmicro/simulate.cpp | 52 |
8 files changed, 215 insertions, 158 deletions
diff --git a/ldmicro/draw_outputdev.cpp b/ldmicro/draw_outputdev.cpp index 4979dbc..eab7324 100644 --- a/ldmicro/draw_outputdev.cpp +++ b/ldmicro/draw_outputdev.cpp @@ -81,9 +81,10 @@ SyntaxHighlightingColours HighlightColours; // bottom, left, right) but we don't care; just go from the coordinates // computed when we drew the schematic in the paint procedure. //----------------------------------------------------------------------------- -gboolean BlinkCursor(GtkWidget * window) //(HWND hwnd, UINT msg, UINT_PTR id, DWORD time) +BOOL BlinkCursor(BOOL kill = FALSE) { // if(GetFocus(MainWindow) != !CursorDrawn) return TRUE; + if(Cursor.left == 0) return TRUE; PlcCursor c; @@ -129,7 +130,7 @@ gboolean BlinkCursor(GtkWidget * window) //(HWND hwnd, UINT msg, UINT_PTR id, DW cairo_destroy(Hcr); CursorDrawn = !CursorDrawn; - return TRUE; + return !kill; } //----------------------------------------------------------------------------- @@ -341,13 +342,11 @@ void PaintWindow(HCRDC Hcr) // 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); - // } + if(InSimulationMode) { + KillTimer(DrawWindow, TIMER_BLINK_CURSOR); + } else { + SetTimer(DrawWindow, TIMER_BLINK_CURSOR, 200, BlinkCursor); + } ok(); } diff --git a/ldmicro/includes/ldmicro.h b/ldmicro/includes/ldmicro.h index dd76e4c..8f01181 100644 --- a/ldmicro/includes/ldmicro.h +++ b/ldmicro/includes/ldmicro.h @@ -631,7 +631,7 @@ extern BOOL ThisHighlighted; // draw_outputdev.cpp extern void (*DrawChars)(HCRDC Hcr, int, int, const char *); -gboolean BlinkCursor(GtkWidget * window); +BOOL BlinkCursor(BOOL kill); void PaintWindow(HCRDC Hcr); void ExportDrawingAsText(char *file); void InitForDrawing(void); @@ -804,7 +804,7 @@ char *_(char *in); // simulate.cpp void SimulateOneCycle(BOOL forceRefresh); -void CALLBACK PlcCycleTimer(HWND hwnd, UINT msg, UINT_PTR id, DWORD time); +BOOL PlcCycleTimer(BOOL kill); void StartSimulationTimer(void); void ClearSimulationData(void); void DescribeForIoList(char *name, char *out); diff --git a/ldmicro/iolist.cpp b/ldmicro/iolist.cpp index d06b7a6..e314fae 100644 --- a/ldmicro/iolist.cpp +++ b/ldmicro/iolist.cpp @@ -415,104 +415,109 @@ void SaveIoListToFile(FILE *f) //----------------------------------------------------------------------------- void ShowAnalogSliderPopup(char *name) { -// WNDCLASSEX wc; -// memset(&wc, 0, sizeof(wc)); -// wc.cbSize = sizeof(wc); - -// wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_OWNDC | -// CS_DBLCLKS; -// wc.lpfnWndProc = (WNDPROC)AnalogSliderDialogProc; -// wc.hInstance = Instance; -// wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW; -// wc.lpszClassName = "LDmicroAnalogSlider"; -// wc.lpszMenuName = NULL; -// wc.hCursor = LoadCursor(NULL, IDC_ARROW); - -// RegisterClassEx(&wc); - -// POINT pt; -// GetCursorPos(&pt); - -// SWORD currentVal = GetAdcShadow(name); - -// SWORD maxVal; -// if(Prog.mcu) { -// maxVal = Prog.mcu->adcMax; -// } else { -// maxVal = 1023; -// } -// if(maxVal == 0) { -// Error(_("No ADC or ADC not supported for selected micro.")); -// return; -// } - -// int left = pt.x - 10; -// // try to put the slider directly under the cursor (though later we might -// // realize that that would put the popup off the screen) -// int top = pt.y - (15 + (73*currentVal)/maxVal); - -// RECT r; -// SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); - -// if(top + 110 >= r.bottom) { -// top = r.bottom - 110; -// } -// if(top < 0) top = 0; + HWID scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, + 0, + 1024, + 1); -// AnalogSliderMain = CreateWindowClient(0, "LDmicroAnalogSlider", "I/O Pin", -// WS_VISIBLE | WS_POPUP | WS_DLGFRAME, -// left, top, 30, 100, NULL, NULL, Instance, NULL); - -// AnalogSliderTrackbar = CreateWindowEx(0, TRACKBAR_CLASS, "", WS_CHILD | -// TBS_AUTOTICKS | TBS_VERT | TBS_TOOLTIPS | WS_CLIPSIBLINGS | WS_VISIBLE, -// 0, 0, 30, 100, AnalogSliderMain, NULL, Instance, NULL); -// SendMessage(AnalogSliderTrackbar, TBM_SETRANGE, FALSE, -// MAKELONG(0, maxVal)); -// SendMessage(AnalogSliderTrackbar, TBM_SETTICFREQ, (maxVal + 1)/8, 0); -// SendMessage(AnalogSliderTrackbar, TBM_SETPOS, TRUE, currentVal); - -// EnableWindow(MainWindow, FALSE); -// ShowWindow(AnalogSliderMain, TRUE); -// SetFocus(AnalogSliderTrackbar); - -// DWORD ret; -// MSG msg; -// AnalogSliderDone = FALSE; -// AnalogSliderCancel = FALSE; - -// SWORD orig = GetAdcShadow(name); - -// while(!AnalogSliderDone && (ret = GetMessage(&msg, NULL, 0, 0))) { -// SWORD v = (SWORD)SendMessage(AnalogSliderTrackbar, TBM_GETPOS, 0, 0); - -// if(msg.message == WM_KEYDOWN) { -// if(msg.wParam == VK_RETURN) { -// AnalogSliderDone = TRUE; -// break; -// } else if(msg.wParam == VK_ESCAPE) { -// AnalogSliderDone = TRUE; -// AnalogSliderCancel = TRUE; -// break; -// } -// } else if(msg.message == WM_LBUTTONUP) { -// if(v != orig) { -// AnalogSliderDone = TRUE; -// } -// } -// SetAdcShadow(name, v); - -// TranslateMessage(&msg); -// DispatchMessage(&msg); -// } - -// if(!AnalogSliderCancel) { -// SWORD v = (SWORD)SendMessage(AnalogSliderTrackbar, TBM_GETPOS, 0, 0); -// SetAdcShadow(name, v); -// } - -// EnableWindow(MainWindow, TRUE); -// DestroyWindow(AnalogSliderMain); -// ListView_RedrawItems(IoList, 0, Prog.io.count - 1); + // WNDCLASSEX wc; + // memset(&wc, 0, sizeof(wc)); + // wc.cbSize = sizeof(wc); + + // wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_OWNDC | + // CS_DBLCLKS; + // wc.lpfnWndProc = (WNDPROC)AnalogSliderDialogProc; + // wc.hInstance = Instance; + // wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW; + // wc.lpszClassName = "LDmicroAnalogSlider"; + // wc.lpszMenuName = NULL; + // wc.hCursor = LoadCursor(NULL, IDC_ARROW); + + // RegisterClassEx(&wc); + + // POINT pt; + // GetCursorPos(&pt); + + // SWORD currentVal = GetAdcShadow(name); + + // SWORD maxVal; + // if(Prog.mcu) { + // maxVal = Prog.mcu->adcMax; + // } else { + // maxVal = 1023; + // } + // if(maxVal == 0) { + // Error(_("No ADC or ADC not supported for selected micro.")); + // return; + // } + + // int left = pt.x - 10; + // // try to put the slider directly under the cursor (though later we might + // // realize that that would put the popup off the screen) + // int top = pt.y - (15 + (73*currentVal)/maxVal); + + // RECT r; + // SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); + + // if(top + 110 >= r.bottom) { + // top = r.bottom - 110; + // } + // if(top < 0) top = 0; + + // AnalogSliderMain = CreateWindowClient(0, "LDmicroAnalogSlider", "I/O Pin", + // WS_VISIBLE | WS_POPUP | WS_DLGFRAME, + // left, top, 30, 100, NULL, NULL, Instance, NULL); + + // AnalogSliderTrackbar = CreateWindowEx(0, TRACKBAR_CLASS, "", WS_CHILD | + // TBS_AUTOTICKS | TBS_VERT | TBS_TOOLTIPS | WS_CLIPSIBLINGS | WS_VISIBLE, + // 0, 0, 30, 100, AnalogSliderMain, NULL, Instance, NULL); + // SendMessage(AnalogSliderTrackbar, TBM_SETRANGE, FALSE, + // MAKELONG(0, maxVal)); + // SendMessage(AnalogSliderTrackbar, TBM_SETTICFREQ, (maxVal + 1)/8, 0); + // SendMessage(AnalogSliderTrackbar, TBM_SETPOS, TRUE, currentVal); + + // EnableWindow(MainWindow, FALSE); + // ShowWindow(AnalogSliderMain, TRUE); + // SetFocus(AnalogSliderTrackbar); + + // DWORD ret; + // MSG msg; + // AnalogSliderDone = FALSE; + // AnalogSliderCancel = FALSE; + + // SWORD orig = GetAdcShadow(name); + + // while(!AnalogSliderDone && (ret = GetMessage(&msg, NULL, 0, 0))) { + // SWORD v = (SWORD)SendMessage(AnalogSliderTrackbar, TBM_GETPOS, 0, 0); + + // if(msg.message == WM_KEYDOWN) { + // if(msg.wParam == VK_RETURN) { + // AnalogSliderDone = TRUE; + // break; + // } else if(msg.wParam == VK_ESCAPE) { + // AnalogSliderDone = TRUE; + // AnalogSliderCancel = TRUE; + // break; + // } + // } else if(msg.message == WM_LBUTTONUP) { + // if(v != orig) { + // AnalogSliderDone = TRUE; + // } + // } + // SetAdcShadow(name, v); + + // TranslateMessage(&msg); + // DispatchMessage(&msg); + // } + + // if(!AnalogSliderCancel) { + // SWORD v = (SWORD)SendMessage(AnalogSliderTrackbar, TBM_GETPOS, 0, 0); + // SetAdcShadow(name, v); + // } + + // EnableWindow(MainWindow, TRUE); + // DestroyWindow(AnalogSliderMain); + // ListView_RedrawItems(IoList, 0, Prog.io.count - 1); } //----------------------------------------------------------------------------- @@ -876,19 +881,19 @@ void IoListProc(NMHDR *h) break; } case LVN_ITEMACTIVATE: { - // if(InSimulationMode) { - // char *name = Prog.io.assignment[h->item.iItem].name; - // if(name[0] == 'X') { - // SimulationToggleContact(name); - // } else if(name[0] == 'A') { - // ShowAnalogSliderPopup(name); - // } - // } else { - // UndoRemember(); - // ShowIoDialog(h->item.iItem); - // ProgramChanged(); - // InvalidateRect(MainWindow, NULL, FALSE); - // } + if(InSimulationMode) { + char *name = Prog.io.assignment[h->item.iItem].name; + if(name[0] == 'X') { + SimulationToggleContact(name); + } else if(name[0] == 'A') { + ShowAnalogSliderPopup(name); + } + } else { + // UndoRemember(); + // ShowIoDialog(h->item.iItem); + // ProgramChanged(); + // InvalidateRect(MainWindow, NULL, FALSE); + } break; } } diff --git a/ldmicro/ldmicro.cpp b/ldmicro/ldmicro.cpp index e0c2141..07ae855 100644 --- a/ldmicro/ldmicro.cpp +++ b/ldmicro/ldmicro.cpp @@ -564,15 +564,15 @@ cmp: break; case MNU_START_SIMULATION: - // StartSimulation(); + StartSimulation(); break; case MNU_STOP_SIMULATION: - // StopSimulation(); + StopSimulation(); break; case MNU_SINGLE_CYCLE: - // SimulateOneCycle(TRUE); + SimulateOneCycle(TRUE); break; case MNU_COMPILE: @@ -1202,7 +1202,8 @@ int main(int argc, char** argv) gtk_widget_show_all(MainWindow); /// Blink cursor - g_timeout_add(200, (GSourceFunc)BlinkCursor, DrawWindow); + SetTimer(DrawWindow, TIMER_BLINK_CURSOR, 200, BlinkCursor); + // SetTimer(MainWindow, TIMER_BLINK_CURSOR, 800, BlinkCursor); if(argc >= 2) { char line[MAX_PATH]; diff --git a/ldmicro/lib/linuxUI/linuxUI.cpp b/ldmicro/lib/linuxUI/linuxUI.cpp index c3c7c0d..5a7b799 100644 --- a/ldmicro/lib/linuxUI/linuxUI.cpp +++ b/ldmicro/lib/linuxUI/linuxUI.cpp @@ -10,6 +10,9 @@ const COLORREF DKGRAY_BR(169, 169, 169); /// Variable to current text color COLORREF HdcCurrentTextColor; +/// Variable to hold timers +std::vector<TimerRecord> timerRecords; + /// EnableMenuItem Variables const UINT MF_ENABLED = 0; const UINT MF_GRAYED = 1; @@ -470,4 +473,34 @@ BOOL GetWindowRect(HWID hWid, PRECT pRect) pRect->bottom = allocation.height; return TRUE; +} + +UINT SetTimer(HWID hWid, UINT nIDEvent, UINT uElapse, BOOL (*lpTimerFunc)(BOOL) ) +{ + auto record_it = std::find_if(timerRecords.begin(), timerRecords.end(), [&nIDEvent](TimerRecord &Record) { return Record.ufID == nIDEvent; }); + + if (record_it != timerRecords.end()) + return 0; + + TimerRecord tr; + tr.pfun = lpTimerFunc; + tr.ufID = nIDEvent; + tr.utID = g_timeout_add(uElapse, (GSourceFunc)lpTimerFunc, FALSE); + + timerRecords.push_back(tr); + return tr.utID; +} + +BOOL KillTimer(HWID hWid, UINT uIDEvent) +{ + auto record_it = std::find_if(timerRecords.begin(), timerRecords.end(), [&uIDEvent](TimerRecord &Record) { return Record.ufID == uIDEvent; }); + + if (record_it == timerRecords.end()) + return FALSE; + + record_it->pfun(TRUE); + g_source_remove (record_it->utID); + timerRecords.erase(record_it); + + return TRUE; }
\ No newline at end of file diff --git a/ldmicro/lib/linuxUI/linuxUI.h b/ldmicro/lib/linuxUI/linuxUI.h index e970e42..09fb488 100644 --- a/ldmicro/lib/linuxUI/linuxUI.h +++ b/ldmicro/lib/linuxUI/linuxUI.h @@ -100,8 +100,15 @@ typedef struct OpenFileInfoData { LPCTSTR lpstrDefExt; } OPENFILENAME; +typedef struct TimerRecordTag { + BOOL (*pfun)(BOOL); + UINT ufID; + UINT utID; +} TimerRecord; + /// Variables extern COLORREF HdcCurrentTextColor; +extern std::vector<TimerRecord> timerRecords; /// functions BOOL GetFocus(HWID window); @@ -201,4 +208,14 @@ BOOL GetWindowRect( HWID hWid, PRECT pRect); +UINT SetTimer( + HWID hWid, + UINT nIDEvent, + UINT uElapse, + BOOL (*lpTimerFunc)(BOOL)); + +BOOL KillTimer( + HWID hWid, + UINT uIDEvent); + #endif
\ No newline at end of file diff --git a/ldmicro/maincontrols.cpp b/ldmicro/maincontrols.cpp index f532a01..9e3770d 100644 --- a/ldmicro/maincontrols.cpp +++ b/ldmicro/maincontrols.cpp @@ -594,7 +594,7 @@ void MakeMainWindowControls(void) gtk_container_add (GTK_CONTAINER(ViewPortMenu), DrawWindow); gtk_container_add (GTK_CONTAINER(ScrollWindow), ViewPortMenu); gtk_paned_pack1 (GTK_PANED (pane), ScrollWindow, TRUE, TRUE); - gtk_paned_set_position (GTK_PANED (pane), 0); + gtk_paned_set_position (GTK_PANED (pane), 0); /// Appending tree view to scrolled window HWID ViewScroll = gtk_scrolled_window_new (NULL, NULL); @@ -912,16 +912,16 @@ void ToggleSimulationMode(void) CheckMenuItem(SimulateMenu, SimulationModeMenu, MF_CHECKED); - // ClearSimulationData(); // simulation.cpp, ldmicro.h + ClearSimulationData(); // simulation.cpp, ldmicro.h // Recheck InSimulationMode, because there could have been a Compile // error, which would have kicked us out of simulation mode. - // if(UartFunctionUsed() && InSimulationMode) { - // ShowUartSimulationWindow(); // simulate.cpp - // } + if(UartFunctionUsed() && InSimulationMode) { + ShowUartSimulationWindow(); // simulate.cpp + } } else { RealTimeSimulationRunning = FALSE; - // KillTimer(MainWindow, TIMER_SIMULATE); + KillTimer(MainWindow, TIMER_SIMULATE); EnableMenuItem(SimulateMenu, StartSimulationMenu, MF_GRAYED); EnableMenuItem(SimulateMenu, StopSimulationMenu, MF_GRAYED); @@ -1144,7 +1144,7 @@ void StartSimulation(void) RealTimeSimulationRunning = TRUE; EnableMenuItem(SimulateMenu, StartSimulationMenu, MF_GRAYED); EnableMenuItem(SimulateMenu, StopSimulationMenu, MF_ENABLED); - // StartSimulationTimer(); + StartSimulationTimer(); UpdateMainWindowTitleBar(); } @@ -1158,7 +1158,7 @@ void StopSimulation(void) EnableMenuItem(SimulateMenu, StartSimulationMenu, MF_ENABLED); EnableMenuItem(SimulateMenu, StopSimulationMenu, MF_GRAYED); - // KillTimer(MainWindow, TIMER_SIMULATE); + KillTimer(MainWindow, TIMER_SIMULATE); UpdateMainWindowTitleBar(); }
\ No newline at end of file diff --git a/ldmicro/simulate.cpp b/ldmicro/simulate.cpp index 1ed0167..6b38896 100644 --- a/ldmicro/simulate.cpp +++ b/ldmicro/simulate.cpp @@ -673,13 +673,14 @@ math: // Called by the Windows timer that triggers cycles when we are running // in real time. //----------------------------------------------------------------------------- -// void CALLBACK PlcCycleTimer(HWND hwnd, UINT msg, UINT_PTR id, DWORD time) -// { -// int i; -// for(i = 0; i < CyclesPerTimerTick; i++) { -// SimulateOneCycle(FALSE); -// } -// } +BOOL PlcCycleTimer(BOOL kill = FALSE) +{ + for(int i = 0; i < CyclesPerTimerTick; i++) { + SimulateOneCycle(FALSE); + } + + return !kill; +} //----------------------------------------------------------------------------- // Simulate one cycle of the PLC. Update everything, and keep track of whether @@ -709,7 +710,8 @@ void SimulateOneCycle(BOOL forceRefresh) SimulateIntCode(); if(NeedRedraw || SimulateRedrawAfterNextCycle || forceRefresh) { - InvalidateRect(MainWindow, NULL, FALSE); + InvalidateRect(DrawWindow, NULL, FALSE); + gtk_widget_queue_draw(DrawWindow); // ListView_RedrawItems(IoList, 0, Prog.io.count - 1); } @@ -725,17 +727,17 @@ void SimulateOneCycle(BOOL forceRefresh) // is about as fast as anyone could follow by eye. Faster timers will just // go instantly. //----------------------------------------------------------------------------- -// void StartSimulationTimer(void) -// { -// int p = Prog.cycleTime/1000; -// if(p < 5) { -// SetTimer(MainWindow, TIMER_SIMULATE, 10, PlcCycleTimer); -// CyclesPerTimerTick = 10000 / Prog.cycleTime; -// } else { -// SetTimer(MainWindow, TIMER_SIMULATE, p, PlcCycleTimer); -// CyclesPerTimerTick = 1; -// } -// } +void StartSimulationTimer(void) +{ + int p = Prog.cycleTime/1000; + if(p < 5) { + SetTimer(MainWindow, TIMER_SIMULATE, 10, PlcCycleTimer); + CyclesPerTimerTick = 10000 / Prog.cycleTime; + } else { + SetTimer(MainWindow, TIMER_SIMULATE, p, PlcCycleTimer); + CyclesPerTimerTick = 1; + } +} //----------------------------------------------------------------------------- // Clear out all the parameters relating to the previous simulation. @@ -852,8 +854,8 @@ void SimulationToggleContact(char *name) // characters that you type go into UART RECV instruction and whatever // the program puts into UART SEND shows up as text. //----------------------------------------------------------------------------- -// void ShowUartSimulationWindow(void) -// { +void ShowUartSimulationWindow(void) +{ // WNDCLASSEX wc; // memset(&wc, 0, sizeof(wc)); // wc.cbSize = sizeof(wc); @@ -909,13 +911,13 @@ void SimulationToggleContact(char *name) // ShowWindow(UartSimulationWindow, TRUE); // SetFocus(MainWindow); -// } +} //----------------------------------------------------------------------------- // Get rid of the UART simulation terminal-type window. //----------------------------------------------------------------------------- -// void DestroyUartSimulationWindow(void) -// { +void DestroyUartSimulationWindow(void) +{ // // Try not to destroy the window if it is already destroyed; that is // // not for the sake of the window, but so that we don't trash the // // stored position. @@ -939,7 +941,7 @@ void SimulationToggleContact(char *name) // DestroyWindow(UartSimulationWindow); // UartSimulationWindow = NULL; -// } +} //----------------------------------------------------------------------------- // Append a received character to the terminal buffer. |