diff options
-rw-r--r-- | help/sample-gtk.cpp | 175 | ||||
-rw-r--r-- | ldmicro/coildialog.cpp | 169 | ||||
-rw-r--r-- | ldmicro/compilecommon.cpp | 2 | ||||
-rw-r--r-- | ldmicro/confdialog.cpp | 88 | ||||
-rw-r--r-- | ldmicro/contactsdialog.cpp | 271 | ||||
-rw-r--r-- | ldmicro/draw_outputdev.cpp | 205 | ||||
-rw-r--r-- | ldmicro/helpdialog.cpp | 2 | ||||
-rw-r--r-- | ldmicro/includes/ldmicro.h | 22 | ||||
-rw-r--r-- | ldmicro/iolist.cpp | 920 | ||||
-rw-r--r-- | ldmicro/ldmicro.cpp | 1214 | ||||
-rw-r--r-- | ldmicro/lib/freezeLD/freezeLD.cpp | 8 | ||||
-rw-r--r-- | ldmicro/lib/linuxUI/linuxLD.h | 53 | ||||
-rw-r--r-- | ldmicro/lib/linuxUI/linuxUI.cpp | 180 | ||||
-rw-r--r-- | ldmicro/lib/linuxUI/linuxUI.h | 61 | ||||
-rw-r--r-- | ldmicro/lutdialog.cpp | 911 | ||||
-rw-r--r-- | ldmicro/maincontrols.cpp | 312 | ||||
-rw-r--r-- | ldmicro/miscutil.cpp | 116 | ||||
-rw-r--r-- | ldmicro/pic16.cpp | 23 | ||||
-rw-r--r-- | ldmicro/resetdialog.cpp | 234 | ||||
-rw-r--r-- | ldmicro/schematic.cpp | 8 | ||||
-rw-r--r-- | ldmicro/simulate.cpp | 1420 | ||||
-rw-r--r-- | ldmicro/undoredo.cpp | 12 |
22 files changed, 3247 insertions, 3159 deletions
diff --git a/help/sample-gtk.cpp b/help/sample-gtk.cpp deleted file mode 100644 index 02238ed..0000000 --- a/help/sample-gtk.cpp +++ /dev/null @@ -1,175 +0,0 @@ -#include "GTK3Test.h" - -/// GTK Widgets -GtkWidget *window; -GtkWidget *windowGrid; -GtkWidget *radioButton1, *radioButton2; -GtkWidget *textLabel; -GtkWidget *textBox; -GtkWidget *buttonSubmit; -GtkWidget *buttonCancel; -GtkWidget *textViewWindow; -GtkWidget *scrolledwindow; - -/// GDK properties -GdkRGBA color; - -void textViewPrint(const char* format, ...) -{ - va_list arglist; - /// initialize valist for format arguments - va_start(arglist, format); - char* str; - // g_print("--in-print--\n"); - // vprintf(format, arglist); - vsprintf(str, format, arglist); - // g_print("text: "); - // g_print(str); - // g_print("\n"); - va_end(arglist); - // g_print("--text-gen-done--\n"); - - GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textViewWindow)); - // g_print("--buffer-created--\n"); - gtk_text_buffer_insert_at_cursor(GTK_TEXT_BUFFER(buffer), str, strlen(str)); - // g_print("--text-buffered--\n"); - gtk_text_view_set_buffer(GTK_TEXT_VIEW(textViewWindow), buffer); - // g_print("--text-printed--\n"); -} - - void setRGB(GdkRGBA* color, int r, int g, int b) -{ - color->red = r; - color->green = g; - color->blue = b; - color->alpha = 1; -} - -static void button1(GtkWidget *widget, gpointer data) -{ - textViewPrint ("Button1\n"); -} - -static void submitClicked(GtkWidget *widget, gpointer data) -{ - g_print("Submitted\n"); - textViewPrint("Submitted\n"); - - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radioButton1))) - { - g_print("Radio 1 selected\n"); - textViewPrint("Radio 1 selected\n"); - } - else - { - g_print("Radio 2 selected\n"); - textViewPrint("Radio 2 selected\n"); - } - - GtkEntryBuffer *entryBuffer; - entryBuffer = gtk_entry_get_buffer(GTK_ENTRY(textBox)); - - g_print("Text in textbox: %s\n", gtk_entry_buffer_get_text(GTK_ENTRY_BUFFER(entryBuffer))); - textViewPrint("Text in textbox: %s\n", gtk_entry_buffer_get_text(GTK_ENTRY_BUFFER(entryBuffer))); - - int w,h; - gtk_window_get_size(GTK_WINDOW(window), &w, &h); - - g_print("Width: %d, Height: %d\n", w, h); - textViewPrint("Width: %i, Height: %i\n", w, h); -} - -static void activate(GtkApplication* app, gpointer user_data) -{ - /// Make window - window = gtk_application_window_new(app); - gtk_window_set_title(GTK_WINDOW(window), "Window"); - gtk_window_set_default_size(GTK_WINDOW(window), 200, 200); - - /// grid to hold multiple witgets - windowGrid = gtk_grid_new(); - /// Attach grid to window - gtk_container_add(GTK_CONTAINER(window), windowGrid); - - /// Make button - GtkWidget *button; - button = gtk_button_new_with_label ("Button1"); - g_signal_connect (button, "clicked", G_CALLBACK (button1), NULL); - - /** Place the first button in the grid cell (0, 0), and make it fill - * just 1 cell horizontally and vertically (ie no spanning) - */ - gtk_grid_attach(GTK_GRID(windowGrid), button, 0, 0, 1, 1); - - /// Make box for 2 radio buttons - // GtkWidget *radioBox; - // radioBox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); // (orientation, number of rows) - //gtk_box_set_homogeneous (GTK_BOX(radioBox), TRUE); - - /// Make radio buttons - radioButton1 = gtk_radio_button_new_with_label(NULL, "radio1"); - radioButton2 = gtk_radio_button_new_with_label(NULL, "radio2"); - gtk_radio_button_set_group(GTK_RADIO_BUTTON(radioButton2), gtk_radio_button_get_group(GTK_RADIO_BUTTON(radioButton1))); - gtk_grid_attach(GTK_GRID(windowGrid), radioButton1, 0, 1, 1, 1); - gtk_grid_attach(GTK_GRID(windowGrid), radioButton2, 1, 1, 1, 1); - - /// Pack radio buttons in radio box - // gtk_box_pack_start(GTK_BOX (radioBox), radioButton1, FALSE, FALSE, 0); - // gtk_box_pack_start(GTK_BOX (radioBox), radioButton2, FALSE, FALSE, 0); - // gtk_box_pack_start (GTK_BOX(windowGrid), radioBox, FALSE, FALSE, 0); - - /// Make lable for text box - textLabel = gtk_label_new ("Enter something: "); - gtk_grid_attach(GTK_GRID(windowGrid), textLabel, 0, 2, 1, 1); - /// Spacing for widget - gtk_widget_set_margin_top(GTK_WIDGET(textLabel), 10); - gtk_widget_set_margin_bottom(GTK_WIDGET(textLabel), 10); - gtk_widget_set_margin_right(GTK_WIDGET(textLabel), 10); - gtk_widget_set_margin_left(GTK_WIDGET(textLabel), 10); - - /// Make text box - textBox = gtk_entry_new(); - gtk_entry_set_max_length(GTK_ENTRY(textBox), 0); - gtk_grid_attach(GTK_GRID(windowGrid), textBox, 1, 2, 1, 1); - - /// Make submit button - buttonSubmit = gtk_button_new_with_label ("Submit"); - g_signal_connect (buttonSubmit, "clicked", G_CALLBACK (submitClicked), NULL); - gtk_grid_attach(GTK_GRID(windowGrid), buttonSubmit, 0, 5, 1, 1); - setRGB(&color, 0, 1, 0); - gtk_widget_override_color(GTK_WIDGET(buttonSubmit), GTK_STATE_FLAG_NORMAL, &color); - - /// Make cancel button - buttonCancel = gtk_button_new_with_label ("Cancel"); - g_signal_connect_swapped (buttonCancel, "clicked", G_CALLBACK (gtk_widget_destroy), window); - gtk_grid_attach(GTK_GRID(windowGrid), buttonCancel, 1, 5, 1, 1); - setRGB(&color, 1, 0, 0); - gtk_widget_override_color(GTK_WIDGET(buttonCancel), GTK_STATE_FLAG_NORMAL, &color); - - /// Make text view widget - scrolledwindow = gtk_scrolled_window_new(NULL, NULL); - textViewWindow = gtk_text_view_new(); - gtk_container_add(GTK_CONTAINER(scrolledwindow), textViewWindow); - gtk_text_view_set_editable(GTK_TEXT_VIEW(textViewWindow), FALSE); - gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textViewWindow), TRUE); - gtk_text_view_set_overwrite(GTK_TEXT_VIEW(textViewWindow), FALSE); - //gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textViewWindow), GTK_WRAP_WORD); - gtk_widget_set_size_request(GTK_WIDGET(scrolledwindow), 2, 80); - gtk_grid_attach(GTK_GRID(windowGrid), scrolledwindow, 0, 6, 5, 5); - - gtk_widget_show_all (window); -} - -int main (int argc, char **argv) -{ - /// Make app - GtkApplication *app; - int status; - - app = gtk_application_new ("org.git.GTK", G_APPLICATION_FLAGS_NONE); - g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); - status = g_application_run (G_APPLICATION (app), argc, argv); - g_object_unref (app); - - return status; -} diff --git a/ldmicro/coildialog.cpp b/ldmicro/coildialog.cpp index 22fd10c..f04de10 100644 --- a/ldmicro/coildialog.cpp +++ b/ldmicro/coildialog.cpp @@ -27,108 +27,109 @@ #include "ldmicro.h" -static HWND CoilDialog; - -static HWND SourceInternalRelayRadio; -static HWND SourceMcuPinRadio; -static HWND NegatedRadio; -static HWND NormalRadio; -static HWND SetOnlyRadio; -static HWND ResetOnlyRadio; -static HWND NameTextbox; +static HWID CoilDialog; + +static HWID SourceInternalRelayRadio; +static HWID SourceMcuPinRadio; +static HWID NegatedRadio; +static HWID NormalRadio; +static HWID SetOnlyRadio; +static HWID ResetOnlyRadio; +static HWID NameTextbox; +static HWID OkButton; +static HWID CancelButton; static LONG_PTR PrevNameProc; -//----------------------------------------------------------------------------- -// Don't allow any characters other than A-Za-z0-9_ in the name. -//----------------------------------------------------------------------------- -// static LRESULT CALLBACK MyNameProc(HWND hwnd, UINT msg, WPARAM wParam, -// LPARAM lParam) -// { -// if(msg == WM_CHAR) { -// if(!(isalpha(wParam) || isdigit(wParam) || wParam == '_' || -// wParam == '\b')) -// { -// return 0; +HWID CoilGrid; +HWID CoilPackingBox; + +// //----------------------------------------------------------------------------- +// // Don't allow any characters other than A-Za-z0-9_ in the name. +// //----------------------------------------------------------------------------- +// // static LRESULT CALLBACK MyNameProc(HWND hwnd, UINT msg, WPARAM wParam, +// // LPARAM lParam) +// // { +// // if(msg == WM_CHAR) { +// // if(!(isalpha(wParam) || isdigit(wParam) || wParam == '_' || +// // wParam == '\b')) +// // { +// // return 0; +// // } +// // } + +// // return CallWindowProc((WNDPROC)PrevNameProc, hwnd, msg, wParam, lParam); +// // } + +// void CoilDialogMyNameProc (GtkEditable *editable, gchar *NewText, gint length, +// gint *position, gpointer data){ +// // gtk_widget_set_sensitive (MainWindow, TRUE); +// for (int i = 0; i < length; i++){ +// if (!(isalpha (NewText[i]) || NewText[i] == '_' || isdigit (NewText[i]) +// || NewText[i] == '\b' )){ +// g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text"); +// return; // } // } - -// return CallWindowProc((WNDPROC)PrevNameProc, hwnd, msg, wParam, lParam); // } + // static void MakeControls(void) // { -// HWND grouper = CreateWindowEx(0, WC_BUTTON, _("Type"), -// WS_CHILD | BS_GROUPBOX | WS_VISIBLE | WS_TABSTOP, -// 7, 3, 120, 105, CoilDialog, NULL, Instance, NULL); -// NiceFont(grouper); - // NormalRadio = CreateWindowEx(0, WC_BUTTON, _("( ) Normal"), // WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE | WS_GROUP, // 16, 21, 100, 20, CoilDialog, NULL, Instance, NULL); // NiceFont(NormalRadio); -// NegatedRadio = CreateWindowEx(0, WC_BUTTON, _("(/) Negated"), -// WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE, -// 16, 41, 100, 20, CoilDialog, NULL, Instance, NULL); -// NiceFont(NegatedRadio); - -// SetOnlyRadio = CreateWindowEx(0, WC_BUTTON, _("(S) Set-Only"), -// WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE, -// 16, 61, 100, 20, CoilDialog, NULL, Instance, NULL); -// NiceFont(SetOnlyRadio); - -// ResetOnlyRadio = CreateWindowEx(0, WC_BUTTON, _("(R) Reset-Only"), -// WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE, -// 16, 81, 105, 20, CoilDialog, NULL, Instance, NULL); -// NiceFont(ResetOnlyRadio); - -// HWND grouper2 = CreateWindowEx(0, WC_BUTTON, _("Source"), -// WS_CHILD | BS_GROUPBOX | WS_VISIBLE, -// 140, 3, 120, 65, CoilDialog, NULL, Instance, NULL); -// NiceFont(grouper2); - -// SourceInternalRelayRadio = CreateWindowEx(0, WC_BUTTON, _("Internal Relay"), -// WS_CHILD | BS_AUTORADIOBUTTON | WS_VISIBLE | WS_GROUP | WS_TABSTOP, -// 149, 21, 100, 20, CoilDialog, NULL, Instance, NULL); -// NiceFont(SourceInternalRelayRadio); - -// SourceMcuPinRadio = CreateWindowEx(0, WC_BUTTON, _("Pin on MCU"), -// WS_CHILD | BS_AUTORADIOBUTTON | WS_VISIBLE | WS_TABSTOP, -// 149, 41, 100, 20, CoilDialog, NULL, Instance, NULL); -// NiceFont(SourceMcuPinRadio); - -// HWND textLabel = CreateWindowEx(0, WC_STATIC, _("Name:"), -// WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, -// 135, 80, 50, 21, CoilDialog, NULL, Instance, NULL); -// NiceFont(textLabel); - -// NameTextbox = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, "", -// WS_CHILD | ES_AUTOHSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 190, 80, 155, 21, CoilDialog, NULL, Instance, NULL); -// FixedFont(NameTextbox); - -// OkButton = CreateWindowEx(0, WC_BUTTON, _("OK"), -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | BS_DEFPUSHBUTTON, -// 276, 10, 70, 23, CoilDialog, NULL, Instance, NULL); -// NiceFont(OkButton); - -// CancelButton = CreateWindowEx(0, WC_BUTTON, _("Cancel"), -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 276, 40, 70, 23, CoilDialog, NULL, Instance, NULL); -// NiceFont(CancelButton); - -// PrevNameProc = SetWindowLongPtr(NameTextbox, GWLP_WNDPROC, -// (LONG_PTR)MyNameProc); +// NormalRadio = gtk_radio_button_new_with_label (NULL, "( ) Normal"); +// NegatedRadio = gtk_radio_button_new_with_label_from_widget +// (GTK_RADIO_BUTTON (NormalRadio), "(/) Negated"); +// SetOnlyRadio = gtk_radio_button_new_with_label_from_widget +// (GTK_RADIO_BUTTON (NormalRadio), "(S) Set-Only"); +// ResetOnlyRadio = gtk_radio_button_new_with_label_from_widget +// (GTK_RADIO_BUTTON (NormalRadio), "(R) Reset-Only"); + +// SourceInternalRelayRadio = gtk_radio_button_new_with_label (NULL, "Internal Relay"); +// SourceMcuPinRadio = gtk_radio_button_new_with_label_from_widget +// (GTK_RADIO_BUTTON (SourceInternalRelayRadio), "Pin on MCU"); + +// HWID textLabel = gtk_label_new ("Name:"); + +// NameTextbox = gtk_entry_new(); +// gtk_entry_set_max_length (GTK_ENTRY (NameTextbox), 0); + +// OkButton = gtk_button_new_with_label ("OK"); +// CancelButton = gtk_button_new_with_label ("Cancel"); + +// gtk_grid_attach (GTK_GRID (CoilGrid), SourceInternalRelayRadio, 1, 2, 1, 1); +// gtk_grid_attach (GTK_GRID (CoilGrid), SourceInputPinRadio, 1, 3, 1, 1); +// gtk_grid_attach (GTK_GRID (CoilGrid), SourceOutputPinRadio, 1, 4, 1, 1); +// gtk_grid_attach (GTK_GRID (CoilGrid), textLabel, 2, 2, 1, 1); +// gtk_grid_attach (GTK_GRID (CoilGrid), NegatedCheckbox, 2, 3, 1, 1); +// gtk_grid_attach (GTK_GRID (CoilGrid), NameTextbox, 3, 2, 1, 1); +// gtk_grid_attach (GTK_GRID (CoilGrid), OkButton, 4, 2, 1, 1); +// gtk_grid_attach (GTK_GRID (CoilGrid), CancelButton, 4, 3, 1, 1); + +// gtk_grid_set_column_spacing (GTK_GRID (CoilGrid), 1); +// gtk_box_pack_start(GTK_BOX(CoilPackingBox), CoilGrid, TRUE, TRUE, 0); + + +// // PrevNameProc = SetWindowLongPtr(NameTextbox, GWLP_WNDPROC, +// // (LONG_PTR)MyNameProc); // } // void ShowCoilDialog(BOOL *negated, BOOL *setOnly, BOOL *resetOnly, char *name) // { -// CoilDialog = CreateWindowClient(0, "LDmicroDialog", -// _("Coil"), WS_OVERLAPPED | WS_SYSMENU, -// 100, 100, 359, 115, NULL, NULL, Instance, NULL); -// RECT r; -// GetClientRect(CoilDialog, &r); +// CoilGrid = gtk_grid_new(); +// CoilPackingBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + +// CoilDialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); +// gtk_window_set_title(GTK_WINDOW(CoilDialog), "Coil"); +// gtk_window_set_default_size(GTK_WINDOW(CoilDialog), 100, 50); +// gtk_window_set_resizable (GTK_WINDOW (CoilDialog), FALSE); +// gtk_container_add(GTK_CONTAINER(CoilDialog), CoilPackingBox); +// gtk_widget_add_events (CoilDialog, GDK_KEY_PRESS_MASK); +// gtk_widget_add_events (CoilDialog, GDK_BUTTON_PRESS_MASK); // MakeControls(); diff --git a/ldmicro/compilecommon.cpp b/ldmicro/compilecommon.cpp index a25d742..f66e7f9 100644 --- a/ldmicro/compilecommon.cpp +++ b/ldmicro/compilecommon.cpp @@ -118,8 +118,8 @@ static void MemForPin(char *name, DWORD *addr, int *bit, BOOL asInput) if(strcmp(Prog.io.assignment[i].name, name)==0) break; } - if(i >= Prog.io.count) oops(); + if(i >= Prog.io.count) oops(); if(asInput && Prog.io.assignment[i].type == IO_TYPE_DIG_OUTPUT) oops(); if(!asInput && Prog.io.assignment[i].type == IO_TYPE_DIG_INPUT) oops(); diff --git a/ldmicro/confdialog.cpp b/ldmicro/confdialog.cpp index cb61ce7..2fd8dd7 100644 --- a/ldmicro/confdialog.cpp +++ b/ldmicro/confdialog.cpp @@ -36,15 +36,15 @@ static HWID ConfDialog; static HWID CrystalTextbox; static HWID CycleTextbox; static HWID BaudTextbox; -static HWID ButtonOk; -static HWID ButtonCancel; +static HWID OkButton; +static HWID CancelButton; static LONG_PTR PrevCrystalProc; static LONG_PTR PrevCycleProc; static LONG_PTR PrevBaudProc; -HWID Grid; -HWID PackingBox; +HWID ConfGrid; +HWID ConfPackingBox; static void MakeControls(void) { @@ -74,8 +74,8 @@ static void MakeControls(void) gtk_widget_set_sensitive (textLabel2, FALSE); } - ButtonOk = gtk_button_new_with_label ("OK"); - ButtonCancel = gtk_button_new_with_label ("Cancel"); + OkButton = gtk_button_new_with_label ("OK"); + CancelButton = gtk_button_new_with_label ("Cancel"); char explanation[1024] = ""; @@ -111,22 +111,22 @@ static void MakeControls(void) HWID textLabel4 = gtk_label_new (explanation); // Creating required containers for packing - Grid = gtk_grid_new(); - PackingBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - - gtk_grid_attach (GTK_GRID (Grid), textLabel, 1, 2, 1, 1); - gtk_grid_attach (GTK_GRID (Grid), CycleTextbox, 3, 2, 1, 1); - gtk_grid_attach (GTK_GRID (Grid), ButtonOk, 6, 2, 2, 1); - gtk_grid_attach (GTK_GRID (Grid), textLabel2, 1, 4, 1, 1); - gtk_grid_attach (GTK_GRID (Grid), CrystalTextbox, 3, 4, 1, 1); - gtk_grid_attach (GTK_GRID (Grid), ButtonCancel, 6, 4, 2, 1); - gtk_grid_attach (GTK_GRID (Grid), textLabel3, 1, 6, 1, 1); - gtk_grid_attach (GTK_GRID (Grid), BaudTextbox, 3, 6, 1, 1); + ConfGrid = gtk_grid_new(); + ConfPackingBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + + gtk_grid_attach (GTK_GRID (ConfGrid), textLabel, 1, 2, 1, 1); + gtk_grid_attach (GTK_GRID (ConfGrid), CycleTextbox, 3, 2, 1, 1); + gtk_grid_attach (GTK_GRID (ConfGrid), OkButton, 6, 2, 2, 1); + gtk_grid_attach (GTK_GRID (ConfGrid), textLabel2, 1, 4, 1, 1); + gtk_grid_attach (GTK_GRID (ConfGrid), CrystalTextbox, 3, 4, 1, 1); + gtk_grid_attach (GTK_GRID (ConfGrid), CancelButton, 6, 4, 2, 1); + gtk_grid_attach (GTK_GRID (ConfGrid), textLabel3, 1, 6, 1, 1); + gtk_grid_attach (GTK_GRID (ConfGrid), BaudTextbox, 3, 6, 1, 1); - gtk_grid_set_column_spacing (GTK_GRID (Grid), 2); + gtk_grid_set_column_spacing (GTK_GRID (ConfGrid), 2); - gtk_box_pack_start(GTK_BOX(PackingBox), Grid, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(PackingBox), textLabel4, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(ConfPackingBox), ConfGrid, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(ConfPackingBox), textLabel4, TRUE, TRUE, 0); // PrevCycleProc = SetWindowLongPtr(CycleTextbox, GWLP_WNDPROC, // (LONG_PTR)MyNumberProc); @@ -138,17 +138,13 @@ static void MakeControls(void) // (LONG_PTR)MyNumberProc); } -void DestroyWindow (GtkWidget* widget, gpointer data){ - gtk_widget_destroy (ConfDialog); - gtk_widget_set_sensitive (MainWindow, TRUE); -} - //----------------------------------------------------------------------------- // Don't allow any characters other than 0-9. in the text boxes. //----------------------------------------------------------------------------- -void MyNumberProc (GtkEditable *editable, gchar *NewText, gint length, +void ConfDialogMyNumberProc (GtkEditable *editable, gchar *NewText, gint length, gint *position, gpointer data){ + gtk_widget_set_sensitive (MainWindow, TRUE); for (int i = 0; i < length; i++){ if (!(isdigit (NewText[i]) || NewText[i] == '.' || NewText[i] == '\b')){ g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text"); @@ -158,7 +154,7 @@ void MyNumberProc (GtkEditable *editable, gchar *NewText, gint length, } // Gets data from the text boxes -void GetData (GtkWidget* widget, gpointer data){ +void ConfDialogGetData (GtkWidget* widget, gpointer data){ char* buf; buf = const_cast <char*> (gtk_entry_get_text (GTK_ENTRY (CycleTextbox))); @@ -173,34 +169,40 @@ void GetData (GtkWidget* widget, gpointer data){ buf = const_cast <char*> (gtk_entry_get_text (GTK_ENTRY(BaudTextbox))); Prog.baudRate = atoi(buf); - DestroyWindow (ConfDialog, NULL); + DestroyWindow (ConfDialog); } // Checks for the required key press -gboolean KeyPress (GtkWidget* widget, GdkEventKey* event, gpointer data){ +gboolean ConfDialogKeyPress (GtkWidget* widget, GdkEventKey* event, gpointer data){ if (event -> keyval == GDK_KEY_Return){ - GetData(NULL, NULL); + ConfDialogGetData(NULL, NULL); } else if (event -> keyval == GDK_KEY_Escape){ - DestroyWindow (ConfDialog, NULL); + DestroyWindow (ConfDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); } return FALSE; } +void ConfCallDestroyWindow (HWID widget, gpointer data){ + DestroyWindow (ConfDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); +} + // Consists of all the signal calls -void SignalCall () { +void ConfDialogSignalCall () { g_signal_connect (G_OBJECT(CycleTextbox), "insert-text", - G_CALLBACK(MyNumberProc), NULL); + G_CALLBACK(ConfDialogMyNumberProc), NULL); g_signal_connect (G_OBJECT(CrystalTextbox), "insert-text", - G_CALLBACK(MyNumberProc), NULL); + G_CALLBACK(ConfDialogMyNumberProc), NULL); g_signal_connect (G_OBJECT(BaudTextbox), "insert-text", - G_CALLBACK(MyNumberProc), NULL); + G_CALLBACK(ConfDialogMyNumberProc), NULL); g_signal_connect (G_OBJECT (ConfDialog), "key-press-event", - G_CALLBACK(KeyPress), NULL); - g_signal_connect (G_OBJECT (ButtonOk), "clicked", - G_CALLBACK(GetData), NULL); - g_signal_connect (G_OBJECT (ButtonCancel), "clicked", - G_CALLBACK(DestroyWindow), NULL); + G_CALLBACK(ConfDialogKeyPress), NULL); + g_signal_connect (G_OBJECT (OkButton), "clicked", + G_CALLBACK(ConfDialogGetData), NULL); + g_signal_connect (G_OBJECT (CancelButton), "clicked", + G_CALLBACK(ConfCallDestroyWindow), NULL); } void ShowConfDialog(void) @@ -213,7 +215,7 @@ void ShowConfDialog(void) gtk_window_set_title(GTK_WINDOW(ConfDialog), "PLC Configuration"); gtk_window_set_default_size(GTK_WINDOW(ConfDialog), 200, 250); gtk_window_set_resizable (GTK_WINDOW (ConfDialog), FALSE); - gtk_container_add(GTK_CONTAINER(ConfDialog), PackingBox); + gtk_container_add(GTK_CONTAINER(ConfDialog), ConfPackingBox); gtk_widget_add_events (ConfDialog, GDK_KEY_PRESS_MASK); gtk_widget_add_events (ConfDialog, GDK_BUTTON_PRESS_MASK); @@ -228,12 +230,12 @@ void ShowConfDialog(void) gtk_entry_set_text (GTK_ENTRY (BaudTextbox), buf); gtk_widget_set_sensitive (MainWindow, FALSE); - gtk_widget_grab_focus (ButtonOk); + gtk_widget_grab_focus (OkButton); gtk_widget_set_state_flags (CycleTextbox, GTK_STATE_FLAG_FOCUSED, TRUE); gtk_widget_grab_focus (CycleTextbox); gtk_widget_show_all (ConfDialog); - SignalCall(); + ConfDialogSignalCall(); return; }
\ No newline at end of file diff --git a/ldmicro/contactsdialog.cpp b/ldmicro/contactsdialog.cpp index a845220..8d6e8d4 100644 --- a/ldmicro/contactsdialog.cpp +++ b/ldmicro/contactsdialog.cpp @@ -27,16 +27,21 @@ #include "ldmicro.h" -static HWND ContactsDialog; +static HWID ContactsDialog; -static HWND NegatedCheckbox; -static HWND SourceInternalRelayRadio; -static HWND SourceInputPinRadio; -static HWND SourceOutputPinRadio; -static HWND NameTextbox; +static HWID NegatedCheckbox; +static HWID SourceInternalRelayRadio; +static HWID SourceInputPinRadio; +static HWID SourceOutputPinRadio; +static HWID NameTextbox; +static HWID OkButton; +static HWID CancelButton; static LONG_PTR PrevNameProc; - +HWID ContactsGrid; +HWID ContactsPackingBox; +char* tmpname; +BOOL* tmpnegated; //----------------------------------------------------------------------------- // Don't allow any characters other than A-Za-z0-9_ in the name. //----------------------------------------------------------------------------- @@ -54,124 +59,142 @@ static LONG_PTR PrevNameProc; // return CallWindowProc((WNDPROC)PrevNameProc, hwnd, msg, wParam, lParam); // } -// static void MakeControls(void) -// { -// HWND grouper = CreateWindowEx(0, WC_BUTTON, _("Source"), -// WS_CHILD | BS_GROUPBOX | WS_VISIBLE, -// 7, 3, 120, 85, ContactsDialog, NULL, Instance, NULL); -// NiceFont(grouper); - -// SourceInternalRelayRadio = CreateWindowEx(0, WC_BUTTON, _("Internal Relay"), -// WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE, -// 16, 21, 100, 20, ContactsDialog, NULL, Instance, NULL); -// NiceFont(SourceInternalRelayRadio); - -// SourceInputPinRadio = CreateWindowEx(0, WC_BUTTON, _("Input pin"), -// WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE, -// 16, 41, 100, 20, ContactsDialog, NULL, Instance, NULL); -// NiceFont(SourceInputPinRadio); - -// SourceOutputPinRadio = CreateWindowEx(0, WC_BUTTON, _("Output pin"), -// WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE, -// 16, 61, 100, 20, ContactsDialog, NULL, Instance, NULL); -// NiceFont(SourceOutputPinRadio); - -// HWND textLabel = CreateWindowEx(0, WC_STATIC, _("Name:"), -// WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, -// 135, 16, 50, 21, ContactsDialog, NULL, Instance, NULL); -// NiceFont(textLabel); - -// NameTextbox = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, "", -// WS_CHILD | ES_AUTOHSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 190, 16, 115, 21, ContactsDialog, NULL, Instance, NULL); -// FixedFont(NameTextbox); - -// NegatedCheckbox = CreateWindowEx(0, WC_BUTTON, _("|/| Negated"), -// WS_CHILD | BS_AUTOCHECKBOX | WS_TABSTOP | WS_VISIBLE, -// 146, 44, 160, 20, ContactsDialog, NULL, Instance, NULL); -// NiceFont(NegatedCheckbox); - -// OkButton = CreateWindowEx(0, WC_BUTTON, _("OK"), -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | BS_DEFPUSHBUTTON, -// 321, 10, 70, 23, ContactsDialog, NULL, Instance, NULL); -// NiceFont(OkButton); - -// CancelButton = CreateWindowEx(0, WC_BUTTON, _("Cancel"), -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 321, 40, 70, 23, ContactsDialog, NULL, Instance, NULL); -// NiceFont(CancelButton); +void ContactsDialogMyNameProc (GtkEditable *editable, gchar *NewText, gint length, + gint *position, gpointer data){ + // gtk_widget_set_sensitive (MainWindow, TRUE); + for (int i = 0; i < length; i++){ + if (!(isalpha (NewText[i]) || NewText[i] == '_' || isdigit (NewText[i]) + || NewText[i] == '\b' )){ + g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text"); + return; + } + } +} + +static void MakeControls(void) +{ + SourceInternalRelayRadio = gtk_radio_button_new_with_label (NULL, "Internal Relay"); + + SourceInputPinRadio = gtk_radio_button_new_with_label_from_widget + (GTK_RADIO_BUTTON (SourceInternalRelayRadio), "Input pin"); + + SourceOutputPinRadio = gtk_radio_button_new_with_label_from_widget + (GTK_RADIO_BUTTON (SourceInternalRelayRadio), "Output pin"); + + HWID textLabel = gtk_label_new ("Name:"); + + NameTextbox = gtk_entry_new(); + gtk_entry_set_max_length (GTK_ENTRY (NameTextbox), 0); + + NegatedCheckbox = gtk_check_button_new_with_label ("|/| Negated"); + + OkButton = gtk_button_new_with_label ("OK"); + CancelButton = gtk_button_new_with_label ("Cancel"); + + gtk_grid_attach (GTK_GRID (ContactsGrid), SourceInternalRelayRadio, 1, 2, 1, 1); + gtk_grid_attach (GTK_GRID (ContactsGrid), SourceInputPinRadio, 1, 3, 1, 1); + gtk_grid_attach (GTK_GRID (ContactsGrid), SourceOutputPinRadio, 1, 4, 1, 1); + gtk_grid_attach (GTK_GRID (ContactsGrid), textLabel, 2, 2, 1, 1); + gtk_grid_attach (GTK_GRID (ContactsGrid), NegatedCheckbox, 2, 3, 1, 1); + gtk_grid_attach (GTK_GRID (ContactsGrid), NameTextbox, 3, 2, 1, 1); + gtk_grid_attach (GTK_GRID (ContactsGrid), OkButton, 4, 2, 1, 1); + gtk_grid_attach (GTK_GRID (ContactsGrid), CancelButton, 4, 3, 1, 1); + + gtk_grid_set_column_spacing (GTK_GRID (ContactsGrid), 1); + gtk_box_pack_start(GTK_BOX(ContactsPackingBox), ContactsGrid, TRUE, TRUE, 0); // PrevNameProc = SetWindowLongPtr(NameTextbox, GWLP_WNDPROC, // (LONG_PTR)MyNameProc); -// } - -// void ShowContactsDialog(BOOL *negated, char *name) -// { -// ContactsDialog = CreateWindowClient(0, "LDmicroDialog", -// _("Contacts"), WS_OVERLAPPED | WS_SYSMENU, -// 100, 100, 404, 95, NULL, NULL, Instance, NULL); - -// MakeControls(); +} + +void ContactsDialogGetData (BOOL* negated, char* name){ + if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (NegatedCheckbox))) { + *negated = TRUE; + } + else { + *negated = FALSE; + } + if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON + (SourceInternalRelayRadio))) { + name[0] = 'R'; + } + else if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON + (SourceInputPinRadio))) { + name[0] = 'X'; + } + else { + name[0] = 'Y'; + } + strcpy (name+1, gtk_entry_get_text (GTK_ENTRY (NameTextbox))); + + DestroyWindow (ContactsDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); +} + +// Mouse click callback +void ContactsDialogMouseClick(HWID widget, gpointer data){ + ContactsDialogGetData(tmpnegated, tmpname); +} + +// Checks for the required key press +gboolean ContactsDialogKeyPress (HWID widget, GdkEventKey* event, gpointer data){ + if (event -> keyval == GDK_KEY_Return){ + ContactsDialogGetData(tmpnegated, tmpname); + } + else if (event -> keyval == GDK_KEY_Escape){ + DestroyWindow (ContactsDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); + } + return FALSE; +} + +void ContactsCallDestroyWindow (HWID widget, gpointer data){ + DestroyWindow (ContactsDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); +} + +void ShowContactsDialog(BOOL *negated, char *name) +{ + ContactsGrid = gtk_grid_new(); + ContactsPackingBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + + ContactsDialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(ContactsDialog), "Contacts"); + gtk_window_set_default_size(GTK_WINDOW(ContactsDialog), 100, 50); + gtk_window_set_resizable (GTK_WINDOW (ContactsDialog), FALSE); + gtk_container_add(GTK_CONTAINER(ContactsDialog), ContactsPackingBox); + gtk_widget_add_events (ContactsDialog, GDK_KEY_PRESS_MASK); + gtk_widget_add_events (ContactsDialog, GDK_BUTTON_PRESS_MASK); + + MakeControls(); -// if(name[0] == 'R') { -// SendMessage(SourceInternalRelayRadio, BM_SETCHECK, BST_CHECKED, 0); -// } else if(name[0] == 'Y') { -// SendMessage(SourceOutputPinRadio, BM_SETCHECK, BST_CHECKED, 0); -// } else { -// SendMessage(SourceInputPinRadio, BM_SETCHECK, BST_CHECKED, 0); -// } -// if(*negated) { -// SendMessage(NegatedCheckbox, BM_SETCHECK, BST_CHECKED, 0); -// } -// SendMessage(NameTextbox, WM_SETTEXT, 0, (LPARAM)(name + 1)); - -// EnableWindow(MainWindow, FALSE); -// ShowWindow(ContactsDialog, TRUE); -// SetFocus(NameTextbox); -// SendMessage(NameTextbox, EM_SETSEL, 0, -1); - -// MSG msg; -// DWORD ret; -// DialogDone = FALSE; -// DialogCancel = FALSE; -// while((ret = GetMessage(&msg, NULL, 0, 0)) && !DialogDone) { -// if(msg.message == WM_KEYDOWN) { -// if(msg.wParam == VK_RETURN) { -// DialogDone = TRUE; -// break; -// } else if(msg.wParam == VK_ESCAPE) { -// DialogDone = TRUE; -// DialogCancel = TRUE; -// break; -// } -// } - -// if(IsDialogMessage(ContactsDialog, &msg)) continue; -// TranslateMessage(&msg); -// DispatchMessage(&msg); -// } - -// if(!DialogCancel) { -// if(SendMessage(NegatedCheckbox, BM_GETSTATE, 0, 0) & BST_CHECKED) { -// *negated = TRUE; -// } else { -// *negated = FALSE; -// } -// if(SendMessage(SourceInternalRelayRadio, BM_GETSTATE, 0, 0) -// & BST_CHECKED) -// { -// name[0] = 'R'; -// } else if(SendMessage(SourceInputPinRadio, BM_GETSTATE, 0, 0) -// & BST_CHECKED) -// { -// name[0] = 'X'; -// } else { -// name[0] = 'Y'; -// } -// SendMessage(NameTextbox, WM_GETTEXT, (WPARAM)16, (LPARAM)(name+1)); -// } - -// EnableWindow(MainWindow, TRUE); -// DestroyWindow(ContactsDialog); -// return; -// } + if(name[0] == 'R') { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (SourceInternalRelayRadio), TRUE); + } + else if(name[0] == 'Y') { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (SourceOutputPinRadio), TRUE); + } + else { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (SourceInputPinRadio), TRUE); + } + if(*negated) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (NegatedCheckbox), TRUE); + } + gtk_entry_set_text (GTK_ENTRY (NameTextbox), name + 1); + + gtk_widget_set_sensitive (MainWindow, FALSE); + gtk_widget_show_all (ContactsDialog); + gtk_widget_grab_focus (NameTextbox); + tmpname = name; + tmpnegated = negated; + + g_signal_connect (G_OBJECT(NameTextbox), "insert-text", + G_CALLBACK(ContactsDialogMyNameProc), NULL); + g_signal_connect (G_OBJECT (ContactsDialog), "key-press-event", + G_CALLBACK(ContactsDialogKeyPress), NULL); + g_signal_connect (G_OBJECT (OkButton), "clicked", + G_CALLBACK(ContactsDialogMouseClick), NULL); + g_signal_connect (G_OBJECT (CancelButton), "clicked", + G_CALLBACK(ContactsCallDestroyWindow), NULL); + +} diff --git a/ldmicro/draw_outputdev.cpp b/ldmicro/draw_outputdev.cpp index 69f08ca..cf2cae4 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; @@ -101,7 +102,7 @@ gboolean BlinkCursor(GtkWidget * window) //(HWND hwnd, UINT msg, UINT_PTR id, DW // if(!GDK_IS_DRAWING_CONTEXT(Hdc)) // return FALSE; - HCRDC Hcr = gdk_cairo_create(gtk_widget_get_window(DrawWindow));//gdk_drawing_context_get_cairo_context(Hdc);// + HCRDC Hcr = gdk_cairo_create(gtk_widget_get_window(DrawWindow)); static int PREV_x = c.left; static int PREV_y = c.top; @@ -126,11 +127,10 @@ gboolean BlinkCursor(GtkWidget * window) //(HWND hwnd, UINT msg, UINT_PTR id, DW else PatBlt(Hcr, c.left, c.top, c.width, c.height, PATINVERT, (HBRUSH)GetStockObject(BLACK_BRUSH)); InvalidateRect(DrawWindow, NULL, FALSE); - // g_print("BLINK\n"); cairo_destroy(Hcr); CursorDrawn = !CursorDrawn; - return TRUE; + return !kill; } //----------------------------------------------------------------------------- @@ -342,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(); } @@ -431,7 +429,7 @@ void InitForDrawing(void) // DrawChars function, for drawing to the export buffer instead of to the // screen. //----------------------------------------------------------------------------- -static void DrawCharsToExportBuffer(int cx, int cy, char *str) +static void DrawCharsToExportBuffer(HCRDC Hcr, int cx, int cy, const char *str) { while(*str) { if(*str >= 10) { @@ -447,105 +445,106 @@ static void DrawCharsToExportBuffer(int cx, int cy, char *str) //----------------------------------------------------------------------------- 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 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); - // ExportBuffer = NULL; - - // fprintf(f, _("\n\nI/O ASSIGNMENT:\n\n")); + 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(NULL, 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(NULL, 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); + ExportBuffer = NULL; + + 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)); + 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]; + PlcProgramSingleIo *io = &Prog.io.assignment[i]; + char *type = IoTypeToString(io->type); + char pin[MAX_NAME_LEN]; - // PinNumberForIo(pin, io); + PinNumberForIo(pin, io); - // sprintf(b, " | | %s\n", - // pin); + sprintf(b, " | | %s\n", + pin); - // memcpy(b+2, io->name, strlen(io->name)); - // memcpy(b+31, type, strlen(type)); - // fprintf(f, "%s", b); - // } + memcpy(b+2, io->name, strlen(io->name)); + memcpy(b+31, type, strlen(type)); + fprintf(f, "%s", b); + } - // fclose(f); + fclose(f); - // // we may have trashed the grid tables a bit; a repaint will fix that - // InvalidateRect(MainWindow, NULL, FALSE); + // we may have trashed the grid tables a bit; a repaint will fix that + InvalidateRect(MainWindow, NULL, FALSE); } //----------------------------------------------------------------------------- diff --git a/ldmicro/helpdialog.cpp b/ldmicro/helpdialog.cpp index fb1b6c3..71cbd1a 100644 --- a/ldmicro/helpdialog.cpp +++ b/ldmicro/helpdialog.cpp @@ -225,7 +225,7 @@ static void MakeControls(int a) } } gtk_widget_override_background_color (TextView, GTK_STATE_FLAG_NORMAL, - ((HBRUSH)GetStockObject(BLACK_BRUSH))->getThis()); + ((HBRUSH)GetStockObject(BLACK_BRUSH))); gtk_container_add (GTK_CONTAINER(RichEdit[a]), TextView); } diff --git a/ldmicro/includes/ldmicro.h b/ldmicro/includes/ldmicro.h index a1a1c75..8bf490f 100644 --- a/ldmicro/includes/ldmicro.h +++ b/ldmicro/includes/ldmicro.h @@ -589,7 +589,6 @@ void RefreshScrollbars(void); extern HINSTANCE Instance; extern HWID MainWindow; extern HWID DrawWindow; -// extern HCRDC Hcr; extern PlcProgram Prog; extern char CurrentSaveFile[MAX_PATH]; extern char CurrentCompileFile[MAX_PATH]; @@ -632,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); @@ -781,23 +780,22 @@ void WriteIhex(FILE *f, BYTE b); void FinishIhex(FILE *f); char *IoTypeToString(int ioType); void PinNumberForIo(char *dest, PlcProgramSingleIo *io); -HWND CreateWindowClient(DWORD exStyle, char *className, char *windowName, - DWORD style, int x, int y, int width, int height, HWND parent, - HMENU menu, HINSTANCE instance, void *param); +HWID CreateWindowClient(GtkWindowType wType, GdkWindowTypeHint wthint, char *windowName, + int x, int y, int width, int height, HWND parent); void MakeComponentListClass(void); void MakeNamingListClass(void); void MakeDialogBoxClass(void); -void NiceFont(HWND h); -void FixedFont(HWND h); +void NiceFont(HWID h); +void FixedFont(HWID h); void CompileSuccessfulMessage(char *str); extern BOOL RunningInBatchMode; extern HFONT MyNiceFont; extern HFONT MyFixedFont; -extern HWND OkButton; -extern HWND CancelButton; -extern BOOL DialogDone; -extern BOOL DialogCancel; +// extern HWID OkButton; +// extern HWID CancelButton; +// extern BOOL DialogDone; +// extern BOOL DialogCancel; // lang.cpp char *_(char *in); @@ -805,7 +803,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 e2fc032..f20b2f7 100644 --- a/ldmicro/iolist.cpp +++ b/ldmicro/iolist.cpp @@ -43,20 +43,20 @@ static struct { static int IoSeenPreviouslyCount; // // stuff for the dialog box that lets you choose pin assignments -// static BOOL DialogDone; -// static BOOL DialogCancel; +static BOOL DialogDone; +static BOOL DialogCancel; -// static HWND IoDialog; +static HWID IoDialog; -// static HWND PinList; -// static HWND OkButton; -// static HWND CancelButton; +static HWID PinList; +static HWID OkButton; +static HWID CancelButton; // // stuff for the popup that lets you set the simulated value of an analog in -// static HWND AnalogSliderMain; -// static HWND AnalogSliderTrackbar; -// static BOOL AnalogSliderDone; -// static BOOL AnalogSliderCancel; +static HWID AnalogSliderMain; +static HWID AnalogSliderTrackbar; +static BOOL AnalogSliderDone; +static BOOL AnalogSliderCancel; //----------------------------------------------------------------------------- @@ -394,159 +394,200 @@ void SaveIoListToFile(FILE *f) // Dialog proc for the popup that lets you set the value of an analog input for // simulation. //----------------------------------------------------------------------------- -// static LRESULT CALLBACK AnalogSliderDialogProc(HWND hwnd, UINT msg, -// WPARAM wParam, LPARAM lParam) -// { -// switch (msg) { -// case WM_CLOSE: -// case WM_DESTROY: -// AnalogSliderDone = TRUE; -// AnalogSliderCancel = TRUE; -// return 1; - -// default: -// return DefWindowProc(hwnd, msg, wParam, lParam); -// } -// } +static gboolean AnalogSliderDialogKeyboardProc(GtkWidget* widget, GdkEventKey* event, gpointer name) +{ + SWORD v = (SWORD)gtk_range_get_value(GTK_RANGE(AnalogSliderTrackbar)); + SetAdcShadow((char*)name, v); + if (AnalogSliderDone == TRUE || AnalogSliderCancel == TRUE) + { + DestroyWindow (AnalogSliderMain); + return FALSE; + } + + if (event->keyval == GDK_KEY_Return){ + DestroyWindow (AnalogSliderMain); + AnalogSliderDone = TRUE; + } + else if (event->keyval == GDK_KEY_Escape){ + DestroyWindow (AnalogSliderMain); + AnalogSliderDone = TRUE; + AnalogSliderCancel = TRUE; + } + + return FALSE; +} + +static gboolean AnalogSliderDialogMouseProc(GtkWidget *widget, GdkEventButton *event, gpointer name) +{ + SWORD v = (SWORD)gtk_range_get_value(GTK_RANGE(AnalogSliderTrackbar)); + SetAdcShadow((char*)name, v); + if (event->button == 1 && event->type == GDK_BUTTON_RELEASE){ + DestroyWindow (AnalogSliderMain); + AnalogSliderDone = TRUE; + } + + return FALSE; +} + +void AnalogSliderUpdateProc (GtkRange *range, GtkScrollType step, gpointer name) +{ + SWORD v = (SWORD)gtk_range_get_value(GTK_RANGE(AnalogSliderTrackbar)); + SetAdcShadow((char*)name, v); +} //----------------------------------------------------------------------------- // A little toolbar-style window that pops up to allow the user to set the // simulated value of an ADC pin. //----------------------------------------------------------------------------- -// 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); +void ShowAnalogSliderPopup(char *name) +{ + SWORD currentVal = GetAdcShadow(name); -// POINT pt; -// GetCursorPos(&pt); + 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; + } -// SWORD currentVal = GetAdcShadow(name); + int left = GLOBAL_mouse_last_clicked_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 = GLOBAL_mouse_last_clicked_y - (15 + (73*currentVal)/maxVal); -// 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 x, y; + gdk_window_get_origin (gtk_widget_get_window (view), &x, &y); -// 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); + if(top < 0) top = y + 10; + if(left < 0) left = x + 20; + + if (GTK_IS_WINDOW(AnalogSliderMain)) + return; + + AnalogSliderMain = gtk_window_new(GTK_WINDOW_POPUP); + gtk_window_set_title(GTK_WINDOW(AnalogSliderMain), _("I/O Pin")); + gtk_window_resize (GTK_WINDOW(AnalogSliderMain), 30, 100); + gtk_window_move(GTK_WINDOW(AnalogSliderMain), left, top); -// RECT r; -// SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); + AnalogSliderTrackbar = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL, + 0, + maxVal, + 1); -// if(top + 110 >= r.bottom) { -// top = r.bottom - 110; -// } -// if(top < 0) top = 0; + gtk_range_set_value (GTK_RANGE(AnalogSliderTrackbar), currentVal); -// 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); -// } + gtk_container_add(GTK_CONTAINER(AnalogSliderMain), AnalogSliderTrackbar); + + // SetFocus(AnalogSliderTrackbar); + gtk_window_set_focus_visible (GTK_WINDOW(AnalogSliderMain), TRUE); + gtk_window_set_keep_above (GTK_WINDOW(AnalogSliderMain), TRUE); + gtk_window_set_focus (GTK_WINDOW(AnalogSliderMain), AnalogSliderTrackbar); + + g_signal_connect (GTK_RANGE(AnalogSliderTrackbar), "key-press-event", + G_CALLBACK(AnalogSliderDialogKeyboardProc), (PVOID)name); + g_signal_connect (GTK_RANGE(AnalogSliderTrackbar), "button-release-event", + G_CALLBACK (AnalogSliderDialogMouseProc), (PVOID)name); + g_signal_connect (GTK_RANGE(AnalogSliderTrackbar), "value-changed", + G_CALLBACK (AnalogSliderUpdateProc), (PVOID)name); + + gtk_widget_show_all(AnalogSliderMain); + + AnalogSliderDone = FALSE; + AnalogSliderCancel = FALSE; + + // ListView_RedrawItems(IoList, 0, Prog.io.count - 1); +} //----------------------------------------------------------------------------- // Window proc for the contacts dialog box //----------------------------------------------------------------------------- -// static LRESULT CALLBACK IoDialogProc(HWND hwnd, UINT msg, WPARAM wParam, -// LPARAM lParam) -// { -// switch (msg) { -// case WM_COMMAND: { -// HWND h = (HWND)lParam; -// if(h == OkButton && wParam == BN_CLICKED) { -// DialogDone = TRUE; -// } else if(h == CancelButton && wParam == BN_CLICKED) { -// DialogDone = TRUE; -// DialogCancel = TRUE; -// } else if(h == PinList && HIWORD(wParam) == LBN_DBLCLK) { -// DialogDone = TRUE; -// } -// break; -// } - -// case WM_CLOSE: -// case WM_DESTROY: -// DialogDone = TRUE; -// DialogCancel = TRUE; -// return 1; - -// default: -// return DefWindowProc(hwnd, msg, wParam, lParam); -// } - -// return 1; -// } +static void IoDialogProc(BOOL DialogDone, int item) +{ + if(DialogDone) + { + char pin[16]; + ITLIST iter; + + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(PinList)); + gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); + + if(gtk_tree_selection_get_selected (selection, NULL, &iter)) + { + GValue valproc = G_VALUE_INIT; + + gtk_tree_model_get_value (gtk_tree_view_get_model (GTK_TREE_VIEW(PinList)), + &iter, 0, &valproc); + gchar* str = (char*)g_value_get_string(&valproc); + strcpy(pin, str); + g_free(str); + } + else + strcpy(pin, _("(no pin)")); + + if(strcmp(pin, _("(no pin)"))==0) + { + int i; + for(i = 0; i < IoSeenPreviouslyCount; i++) { + if(strcmp(IoSeenPreviously[i].name, + Prog.io.assignment[item].name)==0) + { + IoSeenPreviously[i].pin = NO_PIN_ASSIGNED; + } + } + Prog.io.assignment[item].pin = NO_PIN_ASSIGNED; + } + else + { + Prog.io.assignment[item].pin = atoi(pin); + // Only one name can be bound to each pin; make sure that there's + // not another entry for this pin in the IoSeenPreviously list, + // that might get used if the user creates a new pin with that + // name. + int i; + for(i = 0; i < IoSeenPreviouslyCount; i++) { + if(IoSeenPreviously[i].pin == atoi(pin)) { + IoSeenPreviously[i].pin = NO_PIN_ASSIGNED; + } + } + } + RefreshControlsToSettings(); + } + + DestroyWindow(IoDialog); +} + +void IoDialogRowActivateProc(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data) +{ + IoDialogProc(TRUE, GPOINTER_TO_INT(user_data)); +} + +void IoDialogCancelProc(HWID widget, gpointer data) +{ + IoDialogProc(FALSE, GPOINTER_TO_INT(data)); +} + +void IoDialogOkProc(HWID widget, gpointer data) +{ + IoDialogProc(TRUE, GPOINTER_TO_INT(data)); +} + +static gboolean IoDialogKeyPressProc(HWID widget, GdkEventKey* event, gpointer data) +{ + if (event -> keyval == GDK_KEY_Return) + { + IoDialogProc(TRUE, GPOINTER_TO_INT(data)); + } + else if (event -> keyval == GDK_KEY_Escape) + { + IoDialogProc(FALSE, GPOINTER_TO_INT(data)); + } + + return FALSE; +} //----------------------------------------------------------------------------- // Create our window class; nothing exciting. @@ -573,193 +614,165 @@ void SaveIoListToFile(FILE *f) // return RegisterClassEx(&wc); // } -// static void MakeControls(void) -// { -// HWND textLabel = CreateWindowEx(0, WC_STATIC, _("Assign:"), -// WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, -// 6, 1, 80, 17, IoDialog, NULL, Instance, NULL); -// NiceFont(textLabel); - -// PinList = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTBOX, "", -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | WS_VSCROLL | -// LBS_NOTIFY, 6, 18, 95, 320, IoDialog, NULL, Instance, NULL); -// FixedFont(PinList); - -// OkButton = CreateWindowEx(0, WC_BUTTON, _("OK"), -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | BS_DEFPUSHBUTTON, -// 6, 325, 95, 23, IoDialog, NULL, Instance, NULL); -// NiceFont(OkButton); - -// CancelButton = CreateWindowEx(0, WC_BUTTON, _("Cancel"), -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 6, 356, 95, 23, IoDialog, NULL, Instance, NULL); -// NiceFont(CancelButton); -// } +static void MakeControls(HWID Dialog) +{ + HLIST IoPinList = (GtkTreeModel*)gtk_list_store_new (1, G_TYPE_STRING); + + PinList = gtk_tree_view_new_with_model (GTK_TREE_MODEL(IoPinList)); + HTVC column = gtk_tree_view_column_new_with_attributes(_("Assign:"), + gtk_cell_renderer_text_new(), + "text", 0, + NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(PinList), column); + FixedFont(PinList); + + OkButton = gtk_button_new_with_label (_("OK")); + NiceFont(OkButton); + + CancelButton = gtk_button_new_with_label (_("Cancel")); + NiceFont(CancelButton); + + /// Add list to scrolled window to enable scrolling + HWID PinScroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (PinScroll), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_ALWAYS); + gtk_widget_set_hexpand(GTK_WIDGET(PinScroll), TRUE); + gtk_widget_set_vexpand(GTK_WIDGET(PinScroll), TRUE); + + gtk_container_add (GTK_CONTAINER(PinScroll), PinList); + + /// Pack all the widgets into main window + HWID PinBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_box_pack_start(GTK_BOX(PinBox), PinScroll, FALSE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(PinBox), OkButton, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(PinBox), CancelButton, FALSE, FALSE, 0); + gtk_container_add(GTK_CONTAINER(Dialog), PinBox); +} -// void ShowIoDialog(int item) -// { -// if(!Prog.mcu) { -// MessageBox(MainWindow, -// _("No microcontroller has been selected. You must select a " -// "microcontroller before you can assign I/O pins.\r\n\r\n" -// "Select a microcontroller under the Settings menu and try " -// "again."), _("I/O Pin Assignment"), MB_OK | MB_ICONWARNING); -// return; -// } - -// if(Prog.mcu->whichIsa == ISA_ANSIC) { -// Error(_("Can't specify I/O assignment for ANSI C target; compile and " -// "see comments in generated source code.")); -// return; -// } - -// if(Prog.mcu->whichIsa == ISA_INTERPRETED) { -// Error(_("Can't specify I/O assignment for interpretable target; see " -// "comments in reference implementation of interpreter.")); -// return; -// } - -// if(Prog.io.assignment[item].name[0] != 'X' && -// Prog.io.assignment[item].name[0] != 'Y' && -// Prog.io.assignment[item].name[0] != 'A') -// { -// Error(_("Can only assign pin number to input/output pins (Xname or " -// "Yname or Aname).")); -// return; -// } - -// if(Prog.io.assignment[item].name[0] == 'A' && Prog.mcu->adcCount == 0) { -// Error(_("No ADC or ADC not supported for this micro.")); -// return; -// } - -// if(strcmp(Prog.io.assignment[item].name+1, "new")==0) { -// Error(_("Rename I/O from default name ('%s') before assigning " -// "MCU pin."), Prog.io.assignment[item].name); -// return; -// } - -// MakeWindowClass(); - -// // We need the TOOLWINDOW style, or else the window will be forced to -// // a minimum width greater than our current width. And without the -// // APPWINDOW style, it becomes impossible to get the window back (by -// // Alt+Tab or taskbar). -// IoDialog = CreateWindowClient(WS_EX_TOOLWINDOW | WS_EX_APPWINDOW, -// "LDmicroIo", _("I/O Pin"), -// WS_OVERLAPPED | WS_SYSMENU, -// 100, 100, 107, 387, NULL, NULL, Instance, NULL); - -// MakeControls(); - -// SendMessage(PinList, LB_ADDSTRING, 0, (LPARAM)_("(no pin)")); -// int i; -// for(i = 0; i < Prog.mcu->pinCount; i++) { -// int j; -// for(j = 0; j < Prog.io.count; j++) { -// if(j == item) continue; -// if(Prog.io.assignment[j].pin == Prog.mcu->pinInfo[i].pin) { -// goto cant_use_this_io; -// } -// } - -// if(UartFunctionUsed() && Prog.mcu && -// ((Prog.mcu->pinInfo[i].pin == Prog.mcu->uartNeeds.rxPin) || -// (Prog.mcu->pinInfo[i].pin == Prog.mcu->uartNeeds.txPin))) -// { -// goto cant_use_this_io; -// } - -// if(PwmFunctionUsed() && -// Prog.mcu->pinInfo[i].pin == Prog.mcu->pwmNeedsPin) -// { -// goto cant_use_this_io; -// } - -// if(Prog.io.assignment[item].name[0] == 'A') { -// for(j = 0; j < Prog.mcu->adcCount; j++) { -// if(Prog.mcu->adcInfo[j].pin == Prog.mcu->pinInfo[i].pin) { -// // okay; we know how to connect it up to the ADC -// break; -// } -// } -// if(j == Prog.mcu->adcCount) { -// goto cant_use_this_io; -// } -// } - -// char buf[40]; -// if(Prog.mcu->pinCount <= 21) { -// sprintf(buf, "%3d %c%c%d", Prog.mcu->pinInfo[i].pin, -// Prog.mcu->portPrefix, Prog.mcu->pinInfo[i].port, -// Prog.mcu->pinInfo[i].bit); -// } else { -// sprintf(buf, "%3d %c%c%d", Prog.mcu->pinInfo[i].pin, -// Prog.mcu->portPrefix, Prog.mcu->pinInfo[i].port, -// Prog.mcu->pinInfo[i].bit); -// } -// SendMessage(PinList, LB_ADDSTRING, 0, (LPARAM)buf); -// cant_use_this_io:; -// } - -// EnableWindow(MainWindow, FALSE); -// ShowWindow(IoDialog, TRUE); -// SetFocus(PinList); - -// MSG msg; -// DWORD ret; -// DialogDone = FALSE; -// DialogCancel = FALSE; -// while((ret = GetMessage(&msg, NULL, 0, 0)) && !DialogDone) { -// if(msg.message == WM_KEYDOWN) { -// if(msg.wParam == VK_RETURN) { -// DialogDone = TRUE; -// break; -// } else if(msg.wParam == VK_ESCAPE) { -// DialogDone = TRUE; -// DialogCancel = TRUE; -// break; -// } -// } - -// if(IsDialogMessage(IoDialog, &msg)) continue; -// TranslateMessage(&msg); -// DispatchMessage(&msg); -// } - -// if(!DialogCancel) { -// int sel = SendMessage(PinList, LB_GETCURSEL, 0, 0); -// char pin[16]; -// SendMessage(PinList, LB_GETTEXT, (WPARAM)sel, (LPARAM)pin); -// if(strcmp(pin, _("(no pin)"))==0) { -// int i; -// for(i = 0; i < IoSeenPreviouslyCount; i++) { -// if(strcmp(IoSeenPreviously[i].name, -// Prog.io.assignment[item].name)==0) -// { -// IoSeenPreviously[i].pin = NO_PIN_ASSIGNED; -// } -// } -// Prog.io.assignment[item].pin = NO_PIN_ASSIGNED; -// } else { -// Prog.io.assignment[item].pin = atoi(pin); -// // Only one name can be bound to each pin; make sure that there's -// // not another entry for this pin in the IoSeenPreviously list, -// // that might get used if the user creates a new pin with that -// // name. -// int i; -// for(i = 0; i < IoSeenPreviouslyCount; i++) { -// if(IoSeenPreviously[i].pin == atoi(pin)) { -// IoSeenPreviously[i].pin = NO_PIN_ASSIGNED; -// } -// } -// } -// } - -// EnableWindow(MainWindow, TRUE); -// DestroyWindow(IoDialog); -// return; -// } +void ShowIoDialog(int item) +{ + if(!Prog.mcu) { + MessageBox(MainWindow, + _("No microcontroller has been selected. You must select a " + "microcontroller before you can assign I/O pins.\r\n\r\n" + "Select a microcontroller under the Settings menu and try " + "again."), _("I/O Pin Assignment"), MB_OK | MB_ICONWARNING); + return; + } + + if(Prog.mcu->whichIsa == ISA_ANSIC) { + Error(_("Can't specify I/O assignment for ANSI C target; compile and " + "see comments in generated source code.")); + return; + } + + if(Prog.mcu->whichIsa == ISA_INTERPRETED) { + Error(_("Can't specify I/O assignment for interpretable target; see " + "comments in reference implementation of interpreter.")); + return; + } + + if(Prog.io.assignment[item].name[0] != 'X' && + Prog.io.assignment[item].name[0] != 'Y' && + Prog.io.assignment[item].name[0] != 'A') + { + Error(_("Can only assign pin number to input/output pins (Xname or " + "Yname or Aname).")); + return; + } + + if(Prog.io.assignment[item].name[0] == 'A' && Prog.mcu->adcCount == 0) { + Error(_("No ADC or ADC not supported for this micro.")); + return; + } + + if(strcmp(Prog.io.assignment[item].name+1, "new")==0) { + Error(_("Rename I/O from default name ('%s') before assigning " + "MCU pin."), Prog.io.assignment[item].name); + return; + } + + // We need the TOOLWINDOW style, or else the window will be forced to + // a minimum width greater than our current width. And without the + // APPWINDOW style, it becomes impossible to get the window back (by + // Alt+Tab or taskbar). + IoDialog = CreateWindowClient(GTK_WINDOW_TOPLEVEL, GDK_WINDOW_TYPE_HINT_MENU, _("I/O Pin"), + 100, 100, 107, 387, NULL); + + MakeControls(IoDialog); + + ITLIST iter; + GValue val = G_VALUE_INIT; + g_value_init (&val, G_TYPE_STRING); + + HLIST model = gtk_tree_view_get_model (GTK_TREE_VIEW(PinList)); + + gtk_tree_model_get_iter_first (GTK_TREE_MODEL(model), &iter); + + gtk_list_store_append (GTK_LIST_STORE(model), &iter); + + g_value_set_string(&val, _("(no pin)")); + gtk_list_store_set_value (GTK_LIST_STORE(model), &iter, 0, &val); + + int i; + for(i = 0; i < Prog.mcu->pinCount; i++) { + int j; + for(j = 0; j < Prog.io.count; j++) { + if(j == item) continue; + if(Prog.io.assignment[j].pin == Prog.mcu->pinInfo[i].pin) { + goto cant_use_this_io; + } + } + + if(UartFunctionUsed() && Prog.mcu && + ((Prog.mcu->pinInfo[i].pin == Prog.mcu->uartNeeds.rxPin) || + (Prog.mcu->pinInfo[i].pin == Prog.mcu->uartNeeds.txPin))) + { + goto cant_use_this_io; + } + + if(PwmFunctionUsed() && + Prog.mcu->pinInfo[i].pin == Prog.mcu->pwmNeedsPin) + { + goto cant_use_this_io; + } + + if(Prog.io.assignment[item].name[0] == 'A') { + for(j = 0; j < Prog.mcu->adcCount; j++) { + if(Prog.mcu->adcInfo[j].pin == Prog.mcu->pinInfo[i].pin) { + // okay; we know how to connect it up to the ADC + break; + } + } + if(j == Prog.mcu->adcCount) { + goto cant_use_this_io; + } + } + + char buf[40]; + if(Prog.mcu->pinCount <= 21) { + sprintf(buf, "%3d %c%c%d", Prog.mcu->pinInfo[i].pin, + Prog.mcu->portPrefix, Prog.mcu->pinInfo[i].port, + Prog.mcu->pinInfo[i].bit); + } else { + sprintf(buf, "%3d %c%c%d", Prog.mcu->pinInfo[i].pin, + Prog.mcu->portPrefix, Prog.mcu->pinInfo[i].port, + Prog.mcu->pinInfo[i].bit); + } + gtk_list_store_append (GTK_LIST_STORE(model), &iter); + g_value_set_string(&val, buf); + gtk_list_store_set_value (GTK_LIST_STORE(model), &iter, 0, &val); +cant_use_this_io:; + } + + gtk_widget_show_all(IoDialog); + + g_signal_connect (PinList, "row_activated", G_CALLBACK (IoDialogRowActivateProc), GINT_TO_POINTER(item)); + g_signal_connect (IoDialog, "key_press_event", G_CALLBACK (IoDialogKeyPressProc), GINT_TO_POINTER(item)); + g_signal_connect (CancelButton, "clicked", G_CALLBACK (IoDialogCancelProc), GINT_TO_POINTER(item)); + g_signal_connect (OkButton, "clicked", G_CALLBACK (IoDialogOkProc), GINT_TO_POINTER(item)); +} //----------------------------------------------------------------------------- // Called in response to a notify for the listview. Handles click, text-edit @@ -767,119 +780,128 @@ void SaveIoListToFile(FILE *f) // where (LPSTR_TEXTCALLBACK); that way we don't have two parallel copies of // the I/O list to keep in sync. //----------------------------------------------------------------------------- -// void IoListProc(NMHDR *h) -// { -// switch(h->code) { -// case LVN_GETDISPINFO: { -// NMLVDISPINFO *i = (NMLVDISPINFO *)h; -// int item = i->item.iItem; -// switch(i->item.iSubItem) { -// case LV_IO_PIN: -// // Don't confuse people by displaying bogus pin assignments -// // for the C target. -// if(Prog.mcu && (Prog.mcu->whichIsa == ISA_ANSIC || -// Prog.mcu->whichIsa == ISA_INTERPRETED) ) -// { -// strcpy(i->item.pszText, ""); -// break; -// } - -// PinNumberForIo(i->item.pszText, -// &(Prog.io.assignment[item])); -// break; - -// case LV_IO_TYPE: { -// char *s = IoTypeToString(Prog.io.assignment[item].type); -// strcpy(i->item.pszText, s); -// break; -// } -// case LV_IO_NAME: -// strcpy(i->item.pszText, Prog.io.assignment[item].name); -// break; - -// case LV_IO_PORT: { -// // Don't confuse people by displaying bogus pin assignments -// // for the C target. -// if(Prog.mcu && Prog.mcu->whichIsa == ISA_ANSIC) { -// strcpy(i->item.pszText, ""); -// break; -// } - -// int type = Prog.io.assignment[item].type; -// if(type != IO_TYPE_DIG_INPUT && type != IO_TYPE_DIG_OUTPUT -// && type != IO_TYPE_READ_ADC) -// { -// strcpy(i->item.pszText, ""); -// break; -// } - -// int pin = Prog.io.assignment[item].pin; -// if(pin == NO_PIN_ASSIGNED || !Prog.mcu) { -// strcpy(i->item.pszText, ""); -// break; -// } - -// if(UartFunctionUsed() && Prog.mcu) { -// if((Prog.mcu->uartNeeds.rxPin == pin) || -// (Prog.mcu->uartNeeds.txPin == pin)) -// { -// strcpy(i->item.pszText, _("<UART needs!>")); -// break; -// } -// } - -// if(PwmFunctionUsed() && Prog.mcu) { -// if(Prog.mcu->pwmNeedsPin == pin) { -// strcpy(i->item.pszText, _("<PWM needs!>")); -// break; -// } -// } - -// int j; -// for(j = 0; j < Prog.mcu->pinCount; j++) { -// if(Prog.mcu->pinInfo[j].pin == pin) { -// sprintf(i->item.pszText, "%c%c%d", -// Prog.mcu->portPrefix, -// Prog.mcu->pinInfo[j].port, -// Prog.mcu->pinInfo[j].bit); -// break; -// } -// } -// if(j == Prog.mcu->pinCount) { -// sprintf(i->item.pszText, _("<not an I/O!>")); -// } -// break; -// } - -// case LV_IO_STATE: { -// if(InSimulationMode) { -// char *name = Prog.io.assignment[item].name; -// DescribeForIoList(name, i->item.pszText); -// } else { -// strcpy(i->item.pszText, ""); -// } -// break; -// } - -// } -// break; -// } -// case LVN_ITEMACTIVATE: { -// NMITEMACTIVATE *i = (NMITEMACTIVATE *)h; -// if(InSimulationMode) { -// char *name = Prog.io.assignment[i->iItem].name; -// if(name[0] == 'X') { -// SimulationToggleContact(name); -// } else if(name[0] == 'A') { -// ShowAnalogSliderPopup(name); -// } -// } else { -// UndoRemember(); -// ShowIoDialog(i->iItem); -// ProgramChanged(); -// InvalidateRect(MainWindow, NULL, FALSE); -// } -// break; -// } -// } -// } +void IoListProc(NMHDR *h) +{ + switch(h->code) { + case LVN_GETDISPINFO: { + + int item = h->item.iItem; + /// Don't confuse people by displaying bogus pin assignments + /// for the C target. + + char IO_value_holder[60]; + + GValue val = G_VALUE_INIT; + g_value_init (&val, G_TYPE_STRING); + + /// case LV_IO_PIN: + if(Prog.mcu && (Prog.mcu->whichIsa == ISA_ANSIC || + Prog.mcu->whichIsa == ISA_INTERPRETED) ) + { + strcpy(IO_value_holder, ""); + + g_value_set_string(&val, (const char*)&IO_value_holder); + gtk_list_store_set_value (GTK_LIST_STORE(h->hlistFrom), h->hlistIter, LV_IO_PIN, &val); + } + else + { + PinNumberForIo(IO_value_holder, &(Prog.io.assignment[item])); + g_value_set_string(&val, (const char*)&IO_value_holder); + gtk_list_store_set_value (GTK_LIST_STORE(h->hlistFrom), h->hlistIter, LV_IO_PIN, &val); + } + /// case LV_IO_TYPE: + char *s = IoTypeToString(Prog.io.assignment[item].type); + + g_value_set_string(&val, (const char*)s); + gtk_list_store_set_value (GTK_LIST_STORE(h->hlistFrom), h->hlistIter, LV_IO_TYPE, &val); + + /// case LV_IO_NAME: + g_value_set_string(&val, (const char*)Prog.io.assignment[item].name); + gtk_list_store_set_value (GTK_LIST_STORE(h->hlistFrom), h->hlistIter, LV_IO_NAME, &val); + + /// case LV_IO_PORT: + /// Don't confuse people by displaying bogus pin assignments + /// for the C target. + if(Prog.mcu && Prog.mcu->whichIsa == ISA_ANSIC) { + strcpy(IO_value_holder, ""); + break; + } + + int type = Prog.io.assignment[item].type; + if(type != IO_TYPE_DIG_INPUT && type != IO_TYPE_DIG_OUTPUT + && type != IO_TYPE_READ_ADC) + { + strcpy(IO_value_holder, ""); + break; + } + + int pin = Prog.io.assignment[item].pin; + if(pin == NO_PIN_ASSIGNED || !Prog.mcu) { + strcpy(IO_value_holder, ""); + break; + } + + if(UartFunctionUsed() && Prog.mcu) { + if((Prog.mcu->uartNeeds.rxPin == pin) || + (Prog.mcu->uartNeeds.txPin == pin)) + { + strcpy(IO_value_holder, _("<UART needs!>")); + break; + } + } + + if(PwmFunctionUsed() && Prog.mcu) { + if(Prog.mcu->pwmNeedsPin == pin) { + strcpy(IO_value_holder, _("<PWM needs!>")); + break; + } + } + + int j; + for(j = 0; j < Prog.mcu->pinCount; j++) { + if(Prog.mcu->pinInfo[j].pin == pin) { + sprintf(IO_value_holder, "%c%c%d", + Prog.mcu->portPrefix, + Prog.mcu->pinInfo[j].port, + Prog.mcu->pinInfo[j].bit); + break; + } + } + if(j == Prog.mcu->pinCount) { + sprintf(IO_value_holder, _("<not an I/O!>")); + } + + g_value_set_string(&val, (const char*)IO_value_holder); + gtk_list_store_set_value (GTK_LIST_STORE(h->hlistFrom), h->hlistIter, LV_IO_PORT, &val); + + /// case LV_IO_STATE: + if(InSimulationMode) { + char *name = Prog.io.assignment[item].name; + DescribeForIoList(name, IO_value_holder); + } else { + strcpy(IO_value_holder, ""); + } + + g_value_set_string(&val, (const char*)IO_value_holder); + gtk_list_store_set_value (GTK_LIST_STORE(h->hlistFrom), h->hlistIter, LV_IO_STATE, &val); + + 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); + } + break; + } + } +} diff --git a/ldmicro/ldmicro.cpp b/ldmicro/ldmicro.cpp index aac5ba7..d2b54b5 100644 --- a/ldmicro/ldmicro.cpp +++ b/ldmicro/ldmicro.cpp @@ -40,7 +40,6 @@ using namespace std; HINSTANCE Instance; HWID MainWindow; HWID DrawWindow; -// HCRDC Hcr; // parameters used to capture the mouse when implementing our totally non- // general splitter control @@ -66,79 +65,83 @@ char CurrentCompileFile[MAX_PATH]; // project file. PlcProgram Prog; +/// Function to safely quit program gtk main loop +void LD_WM_Close_call(GtkWidget *widget, GdkEvent *event, gpointer user_data); + //----------------------------------------------------------------------------- // Get a filename with a common dialog box and then save the program to that // file and then set our default filename to that. //----------------------------------------------------------------------------- -// static BOOL SaveAsDialog(void) -// { -// OPENFILENAME ofn; - -// memset(&ofn, 0, sizeof(ofn)); -// ofn.lStructSize = sizeof(ofn); -// ofn.hInstance = Instance; -// ofn.lpstrFilter = LDMICRO_PATTERN; -// ofn.lpstrDefExt = "ld"; -// ofn.lpstrFile = CurrentSaveFile; -// ofn.nMaxFile = sizeof(CurrentSaveFile); -// ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; - -// if(!GetSaveFileName(&ofn)) -// return FALSE; - -// if(!SaveProjectToFile(CurrentSaveFile)) { -// Error(_("Couldn't write to '%s'."), CurrentSaveFile); -// return FALSE; -// } else { -// ProgramChangedNotSaved = FALSE; -// return TRUE; -// } -// } +static BOOL SaveAsDialog(void) +{ + OPENFILENAME ofn; + + memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.parentWindow = MainWindow; + ofn.lpstrFilter = LDMICRO_PATTERN; + ofn.lpstrDefExt = "ld"; + ofn.lpstrFile = CurrentSaveFile; + ofn.nMaxFile = sizeof(CurrentSaveFile); + ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; + + if(!GetSaveFileName(&ofn)) + return FALSE; + + if(!SaveProjectToFile(CurrentSaveFile)) { + Error(_("Couldn't write to '%s'."), CurrentSaveFile); + return FALSE; + } else { + ProgramChangedNotSaved = FALSE; + return TRUE; + } +} //----------------------------------------------------------------------------- // Get a filename with a common dialog box and then export the program as // an ASCII art drawing. //----------------------------------------------------------------------------- -// static void ExportDialog(void) -// { -// char exportFile[MAX_PATH]; -// OPENFILENAME ofn; - -// exportFile[0] = '\0'; - -// memset(&ofn, 0, sizeof(ofn)); -// ofn.lStructSize = sizeof(ofn); -// ofn.hInstance = Instance; -// ofn.lpstrFilter = TXT_PATTERN; -// ofn.lpstrFile = exportFile; -// ofn.lpstrTitle = _("Export As Text"); -// ofn.nMaxFile = sizeof(exportFile); -// ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; - -// if(!GetSaveFileName(&ofn)) -// return; +static void ExportDialog(void) +{ + char exportFile[MAX_PATH]; + OPENFILENAME ofn; + + exportFile[0] = '\0'; + + memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.parentWindow = MainWindow; + ofn.lpstrFilter = TXT_PATTERN; + ofn.lpstrFile = exportFile; + ofn.lpstrDefExt = "txt"; + ofn.lpstrTitle = _("Export As Text"); + ofn.nMaxFile = sizeof(exportFile); + ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; + + if(!GetSaveFileName(&ofn)) + return; -// ExportDrawingAsText(exportFile); -// } + ExportDrawingAsText(exportFile); +} //----------------------------------------------------------------------------- // If we already have a filename, save the program to that. Otherwise same // as Save As. Returns TRUE if it worked, else returns FALSE. //----------------------------------------------------------------------------- -// static BOOL SaveProgram(void) -// { -// if(strlen(CurrentSaveFile)) { -// if(!SaveProjectToFile(CurrentSaveFile)) { -// Error(_("Couldn't write to '%s'."), CurrentSaveFile); -// return FALSE; -// } else { -// ProgramChangedNotSaved = FALSE; -// return TRUE; -// } -// } else { -// return SaveAsDialog(); -// } -// } +static BOOL SaveProgram(void) +{ + if(strlen(CurrentSaveFile)) { + if(!SaveProjectToFile(CurrentSaveFile)) { + Error(_("Couldn't write to '%s'."), CurrentSaveFile); + return FALSE; + } else { + ProgramChangedNotSaved = FALSE; + return TRUE; + } + } else { + return SaveAsDialog(); + } +} //----------------------------------------------------------------------------- // Compile the program to a hex file for the target micro. Get the output @@ -151,7 +154,7 @@ static void CompileProgram(BOOL compileAs) memset(&ofn, 0, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); - ofn.parentWindow = NULL; + ofn.parentWindow = MainWindow; ofn.lpstrTitle = _("Compile To"); if(Prog.mcu && Prog.mcu->whichIsa == ISA_ANSIC) { ofn.lpstrFilter = C_PATTERN; @@ -175,12 +178,12 @@ static void CompileProgram(BOOL compileAs) } if(!GenerateIntermediateCode()) return; - + if(Prog.mcu == NULL) { Error(_("Must choose a target microcontroller before compiling.")); return; } - + if(UartFunctionUsed() && Prog.mcu->uartNeeds.rxPin == 0) { Error(_("UART function used but not supported for this micro.")); return; @@ -190,7 +193,7 @@ static void CompileProgram(BOOL compileAs) Error(_("PWM function used but not supported for this micro.")); return; } - + switch(Prog.mcu->whichIsa) { case ISA_AVR: CompileAvr(CurrentCompileFile); break; case ISA_PIC16: CompilePic16(CurrentCompileFile); break; @@ -200,7 +203,8 @@ static void CompileProgram(BOOL compileAs) default: oops(); } - IntDumpListing("t.pl"); + + IntDumpListing("t.pl"); } //----------------------------------------------------------------------------- @@ -208,70 +212,71 @@ static void CompileProgram(BOOL compileAs) // or to cancel the operation they are performing. Return TRUE if they want // to cancel. //----------------------------------------------------------------------------- -// BOOL CheckSaveUserCancels(void) -// { -// if(!ProgramChangedNotSaved) { -// // no problem -// return FALSE; -// } +BOOL CheckSaveUserCancels(void) +{ + if(!ProgramChangedNotSaved) { + // no problem + return FALSE; + } -// int r = MessageBox(MainWindow, -// _("The program has changed since it was last saved.\r\n\r\n" -// "Do you want to save the changes?"), "LDmicro", -// MB_YESNOCANCEL | MB_ICONWARNING); -// switch(r) { -// case IDYES: -// if(SaveProgram()) -// return FALSE; -// else -// return TRUE; - -// case IDNO: -// return FALSE; - -// case IDCANCEL: -// return TRUE; - -// default: -// oops(); -// } -// } + int r = MessageBox(MainWindow, + _("The program has changed since it was last saved.\r\n\r\n" + "Do you want to save the changes?"), "LDmicro", + MB_YESNOCANCEL | MB_ICONWARNING); + switch(r) { + case IDYES: + if(SaveProgram()) + return FALSE; + else + return TRUE; + + case IDNO: + return FALSE; + + case IDCANCEL: + return TRUE; + + default: + oops(); + } + +} //----------------------------------------------------------------------------- // Load a new program from a file. If it succeeds then set our default filename // to that, else we end up with an empty file then. //----------------------------------------------------------------------------- -// static void OpenDialog(void) -// { -// OPENFILENAME ofn; - -// char tempSaveFile[MAX_PATH] = ""; - -// memset(&ofn, 0, sizeof(ofn)); -// ofn.lStructSize = sizeof(ofn); -// ofn.hInstance = Instance; -// ofn.lpstrFilter = LDMICRO_PATTERN; -// ofn.lpstrDefExt = "ld"; -// ofn.lpstrFile = tempSaveFile; -// ofn.nMaxFile = sizeof(tempSaveFile); -// ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; - -// if(!GetOpenFileName(&ofn)) -// return; - -// if(!LoadProjectFromFile(tempSaveFile)) { -// Error(_("Couldn't open '%s'."), tempSaveFile); -// CurrentSaveFile[0] = '\0'; -// } else { -// ProgramChangedNotSaved = FALSE; -// strcpy(CurrentSaveFile, tempSaveFile); -// UndoFlush(); -// } +static void OpenDialog(void) +{ + OPENFILENAME ofn; -// GenerateIoListDontLoseSelection(); -// RefreshScrollbars(); -// UpdateMainWindowTitleBar(); -// } + char tempSaveFile[MAX_PATH] = ""; + + memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.parentWindow = MainWindow; + ofn.lpstrFilter = LDMICRO_PATTERN; + ofn.lpstrDefExt = "ld"; + ofn.lpstrFile = tempSaveFile; + ofn.nMaxFile = sizeof(tempSaveFile); + ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY; + + if(!GetOpenFileName(&ofn)) + return; + + if(!LoadProjectFromFile(tempSaveFile)) { + Error(_("Couldn't open '%s'."), tempSaveFile); + CurrentSaveFile[0] = '\0'; + } else { + ProgramChangedNotSaved = FALSE; + strcpy(CurrentSaveFile, tempSaveFile); + UndoFlush(); + } + + GenerateIoListDontLoseSelection(); + RefreshScrollbars(); + UpdateMainWindowTitleBar(); +} //----------------------------------------------------------------------------- // Housekeeping required when the program changes: mark the program as @@ -282,7 +287,7 @@ void ProgramChanged(void) { ProgramChangedNotSaved = TRUE; GenerateIoListDontLoseSelection(); - // RefreshScrollbars(); + RefreshScrollbars(); } #define CHANGING_PROGRAM(x) { \ UndoRemember(); \ @@ -344,209 +349,210 @@ static void ProcessMenu(int code) switch(code) { case MNU_NEW: - // if(CheckSaveUserCancels()) break; - // NewProgram(); - // strcpy(CurrentSaveFile, ""); - // strcpy(CurrentCompileFile, ""); - // GenerateIoListDontLoseSelection(); - // RefreshScrollbars(); - // UpdateMainWindowTitleBar(); + if(CheckSaveUserCancels()) break; + NewProgram(); + strcpy(CurrentSaveFile, ""); + strcpy(CurrentCompileFile, ""); + GenerateIoListDontLoseSelection(); + RefreshScrollbars(); + UpdateMainWindowTitleBar(); break; case MNU_OPEN: - // if(CheckSaveUserCancels()) break; - // OpenDialog(); + if(CheckSaveUserCancels()) break; + OpenDialog(); break; case MNU_SAVE: - // SaveProgram(); - // UpdateMainWindowTitleBar(); + SaveProgram(); + UpdateMainWindowTitleBar(); break; case MNU_SAVE_AS: - // SaveAsDialog(); - // UpdateMainWindowTitleBar(); + SaveAsDialog(); + UpdateMainWindowTitleBar(); break; case MNU_EXPORT: - // ExportDialog(); + ExportDialog(); break; case MNU_EXIT: - // if(CheckSaveUserCancels()) break; + if(CheckSaveUserCancels()) break; + LD_WM_Close_call(NULL, NULL, NULL); // PostQuitMessage(0); break; case MNU_INSERT_COMMENT: - // CHANGING_PROGRAM(AddComment(_("--add comment here--"))); + CHANGING_PROGRAM(AddComment(_("--add comment here--"))); break; case MNU_INSERT_CONTACTS: - // CHANGING_PROGRAM(AddContact()); + CHANGING_PROGRAM(AddContact()); break; case MNU_INSERT_COIL: - // CHANGING_PROGRAM(AddCoil()); + CHANGING_PROGRAM(AddCoil()); break; case MNU_INSERT_TON: - // CHANGING_PROGRAM(AddTimer(ELEM_TON)); + CHANGING_PROGRAM(AddTimer(ELEM_TON)); break; case MNU_INSERT_TOF: - // CHANGING_PROGRAM(AddTimer(ELEM_TOF)); + CHANGING_PROGRAM(AddTimer(ELEM_TOF)); break; case MNU_INSERT_RTO: - // CHANGING_PROGRAM(AddTimer(ELEM_RTO)); + CHANGING_PROGRAM(AddTimer(ELEM_RTO)); break; case MNU_INSERT_CTU: - // CHANGING_PROGRAM(AddCounter(ELEM_CTU)); + CHANGING_PROGRAM(AddCounter(ELEM_CTU)); break; case MNU_INSERT_CTD: - // CHANGING_PROGRAM(AddCounter(ELEM_CTD)); + CHANGING_PROGRAM(AddCounter(ELEM_CTD)); break; case MNU_INSERT_CTC: - // CHANGING_PROGRAM(AddCounter(ELEM_CTC)); + CHANGING_PROGRAM(AddCounter(ELEM_CTC)); break; case MNU_INSERT_RES: - // CHANGING_PROGRAM(AddReset()); + CHANGING_PROGRAM(AddReset()); break; case MNU_INSERT_OPEN: - // CHANGING_PROGRAM(AddEmpty(ELEM_OPEN)); + CHANGING_PROGRAM(AddEmpty(ELEM_OPEN)); break; case MNU_INSERT_SHORT: - // CHANGING_PROGRAM(AddEmpty(ELEM_SHORT)); + CHANGING_PROGRAM(AddEmpty(ELEM_SHORT)); break; case MNU_INSERT_MASTER_RLY: - // CHANGING_PROGRAM(AddMasterRelay()); + CHANGING_PROGRAM(AddMasterRelay()); break; case MNU_INSERT_SHIFT_REG: - // CHANGING_PROGRAM(AddShiftRegister()); + CHANGING_PROGRAM(AddShiftRegister()); break; case MNU_INSERT_LUT: - // CHANGING_PROGRAM(AddLookUpTable()); + CHANGING_PROGRAM(AddLookUpTable()); break; case MNU_INSERT_PWL: - // CHANGING_PROGRAM(AddPiecewiseLinear()); + CHANGING_PROGRAM(AddPiecewiseLinear()); break; case MNU_INSERT_FMTD_STR: - // CHANGING_PROGRAM(AddFormattedString()); + CHANGING_PROGRAM(AddFormattedString()); break; case MNU_INSERT_OSR: - // CHANGING_PROGRAM(AddEmpty(ELEM_ONE_SHOT_RISING)); + CHANGING_PROGRAM(AddEmpty(ELEM_ONE_SHOT_RISING)); break; case MNU_INSERT_OSF: - // CHANGING_PROGRAM(AddEmpty(ELEM_ONE_SHOT_FALLING)); + CHANGING_PROGRAM(AddEmpty(ELEM_ONE_SHOT_FALLING)); break; case MNU_INSERT_MOV: - // CHANGING_PROGRAM(AddMove()); + CHANGING_PROGRAM(AddMove()); break; case MNU_INSERT_SET_PWM: - // CHANGING_PROGRAM(AddSetPwm()); + CHANGING_PROGRAM(AddSetPwm()); break; case MNU_INSERT_READ_ADC: - // CHANGING_PROGRAM(AddReadAdc()); + CHANGING_PROGRAM(AddReadAdc()); break; case MNU_INSERT_UART_SEND: - // CHANGING_PROGRAM(AddUart(ELEM_UART_SEND)); + CHANGING_PROGRAM(AddUart(ELEM_UART_SEND)); break; case MNU_INSERT_UART_RECV: - // CHANGING_PROGRAM(AddUart(ELEM_UART_RECV)); + CHANGING_PROGRAM(AddUart(ELEM_UART_RECV)); break; case MNU_INSERT_PERSIST: - // CHANGING_PROGRAM(AddPersist()); + CHANGING_PROGRAM(AddPersist()); break; -// { -// int elem; -// case MNU_INSERT_ADD: elem = ELEM_ADD; goto math; -// case MNU_INSERT_SUB: elem = ELEM_SUB; goto math; -// case MNU_INSERT_MUL: elem = ELEM_MUL; goto math; -// case MNU_INSERT_DIV: elem = ELEM_DIV; goto math; -// math: -// CHANGING_PROGRAM(AddMath(elem)); -// break; -// } + { + int elem; + case MNU_INSERT_ADD: elem = ELEM_ADD; goto math; + case MNU_INSERT_SUB: elem = ELEM_SUB; goto math; + case MNU_INSERT_MUL: elem = ELEM_MUL; goto math; + case MNU_INSERT_DIV: elem = ELEM_DIV; goto math; +math: + CHANGING_PROGRAM(AddMath(elem)); + break; + } -// { -// int elem; -// case MNU_INSERT_EQU: elem = ELEM_EQU; goto cmp; -// case MNU_INSERT_NEQ: elem = ELEM_NEQ; goto cmp; -// case MNU_INSERT_GRT: elem = ELEM_GRT; goto cmp; -// case MNU_INSERT_GEQ: elem = ELEM_GEQ; goto cmp; -// case MNU_INSERT_LES: elem = ELEM_LES; goto cmp; -// case MNU_INSERT_LEQ: elem = ELEM_LEQ; goto cmp; -// cmp: -// CHANGING_PROGRAM(AddCmp(elem)); -// break; -// } + { + int elem; + case MNU_INSERT_EQU: elem = ELEM_EQU; goto cmp; + case MNU_INSERT_NEQ: elem = ELEM_NEQ; goto cmp; + case MNU_INSERT_GRT: elem = ELEM_GRT; goto cmp; + case MNU_INSERT_GEQ: elem = ELEM_GEQ; goto cmp; + case MNU_INSERT_LES: elem = ELEM_LES; goto cmp; + case MNU_INSERT_LEQ: elem = ELEM_LEQ; goto cmp; +cmp: + CHANGING_PROGRAM(AddCmp(elem)); + break; + } case MNU_MAKE_NORMAL: - // CHANGING_PROGRAM(MakeNormalSelected()); + CHANGING_PROGRAM(MakeNormalSelected()); break; case MNU_NEGATE: - // CHANGING_PROGRAM(NegateSelected()); + CHANGING_PROGRAM(NegateSelected()); break; case MNU_MAKE_SET_ONLY: - // CHANGING_PROGRAM(MakeSetOnlySelected()); + CHANGING_PROGRAM(MakeSetOnlySelected()); break; case MNU_MAKE_RESET_ONLY: - // CHANGING_PROGRAM(MakeResetOnlySelected()); + CHANGING_PROGRAM(MakeResetOnlySelected()); break; case MNU_UNDO: - // UndoUndo(); + UndoUndo(); break; case MNU_REDO: - // UndoRedo(); + UndoRedo(); break; case MNU_INSERT_RUNG_BEFORE: - // CHANGING_PROGRAM(InsertRung(FALSE)); + CHANGING_PROGRAM(InsertRung(FALSE)); break; case MNU_INSERT_RUNG_AFTER: - // CHANGING_PROGRAM(InsertRung(TRUE)); + CHANGING_PROGRAM(InsertRung(TRUE)); break; case MNU_DELETE_RUNG: - // CHANGING_PROGRAM(DeleteSelectedRung()); + CHANGING_PROGRAM(DeleteSelectedRung()); break; case MNU_PUSH_RUNG_UP: - // CHANGING_PROGRAM(PushRungUp()); + CHANGING_PROGRAM(PushRungUp()); break; case MNU_PUSH_RUNG_DOWN: - // CHANGING_PROGRAM(PushRungDown()); + CHANGING_PROGRAM(PushRungDown()); break; case MNU_DELETE_ELEMENT: - // CHANGING_PROGRAM(DeleteSelectedFromProgram()); + CHANGING_PROGRAM(DeleteSelectedFromProgram()); break; case MNU_MCU_SETTINGS: @@ -554,27 +560,27 @@ static void ProcessMenu(int code) break; case MNU_SIMULATION_MODE: - // ToggleSimulationMode(); + ToggleSimulationMode(); 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: - // CompileProgram(FALSE); + CompileProgram(FALSE); break; case MNU_COMPILE_AS: - // CompileProgram(TRUE); + CompileProgram(TRUE); break; case MNU_MANUAL: @@ -585,415 +591,86 @@ static void ProcessMenu(int code) ShowHelpDialog(TRUE); break; } -} - -void WM_COMMAND (GtkMenuItem* men, gpointer gpcode){ - int tempcode = GPOINTER_TO_INT(gpcode); - ProcessMenu (tempcode); -} - -void MenuHandler (){ - g_signal_connect(G_OBJECT(McuSettingsMenu), "activate", - G_CALLBACK(WM_COMMAND), GINT_TO_POINTER(MNU_MCU_SETTINGS)); - g_signal_connect(G_OBJECT(ManualMenu), "activate", - G_CALLBACK(WM_COMMAND), GINT_TO_POINTER(MNU_MANUAL)); - g_signal_connect(G_OBJECT(AboutMenu), "activate", - G_CALLBACK(WM_COMMAND), GINT_TO_POINTER(MNU_ABOUT)); + gtk_widget_queue_draw(DrawWindow); } //----------------------------------------------------------------------------- // WndProc for MainWindow. //----------------------------------------------------------------------------- -LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - // switch (msg) { - // case WM_ERASEBKGND: - // break; +// LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +// { +// // switch (msg) { +// // case WM_ERASEBKGND: +// // break; - // case WM_SETFOCUS: +// // case WM_SETFOCUS: - // case WM_PAINT: { - // } +// // case WM_PAINT: { +// // } - // case WM_KEYDOWN: { - // } +// // case WM_KEYDOWN: { +// // } - // case WM_LBUTTONDBLCLK: { - // } +// // case WM_LBUTTONDBLCLK: { +// // } - // case WM_LBUTTONDOWN: { - // } - // case WM_MOUSEMOVE: { - // } - // case WM_MOUSEWHEEL: { - // } +// // case WM_LBUTTONDOWN: { +// // } +// // case WM_MOUSEMOVE: { +// // } +// // case WM_MOUSEWHEEL: { +// // } - // case WM_SIZE: +// // case WM_SIZE: - // case WM_NOTIFY: { - // NMHDR *h = (NMHDR *)lParam; - // if(h->hwndFrom == IoList) { - // IoListProc(h); - // } - // return 0; - // } - // case WM_VSCROLL: +// // case WM_NOTIFY: { - // case WM_HSCROLL: +// // case WM_VSCROLL: - // case WM_COMMAND: - // ProcessMenu(LOWORD(wParam)); - // InvalidateRect(MainWindow, NULL, FALSE); - // break; +// // case WM_HSCROLL: - // case WM_CLOSE: - // case WM_DESTROY: +// // case WM_COMMAND: - // default: - // return DefWindowProc(hwnd, msg, wParam, lParam); - // } +// // case WM_CLOSE: +// // case WM_DESTROY: - return 1; -} +// // default: +// // return DefWindowProc(hwnd, msg, wParam, lParam); +// // } + +// return 1; +// } -void LD_WM_Close_call(GtkWidget *widget, GdkEvent *event, gpointer user_data)//(HWND window) +void LD_WM_Close_call(GtkWidget *widget, GdkEvent *event, gpointer user_data) { /* Handles: * WM_CLOSE */ + + CheckSaveUserCancels(); - // if(Hdc != NULL) - // cairo_destroy(Hdc); FreezeWindowPos(MainWindow); FreezeDWORD(IoListHeight); gtk_main_quit(); } -gboolean LD_WM_KeyDown_call(GtkWidget *widget, GdkEvent *event, gpointer user_data) -{ - /* Handles: - * WM_KEYDOWN - */ - // g_print("ky call\n"); - switch(event->key.state) - { - case GDK_SHIFT_MASK: - g_print("SHIFT+"); - break; - case GDK_CONTROL_MASK: - g_print("CONTROL+"); - break; - } - - g_print("%c\n", (char)gdk_keyval_to_unicode(event->key.keyval)); - - // if(wParam == 'M') { - // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) { - // ToggleSimulationMode(); - // break; - // } - // } else if(wParam == VK_TAB) { - // SetFocus(IoList); - // BlinkCursor(0, 0, 0, 0); - // break; - // } else if(wParam == VK_F1) { - // ShowHelpDialog(FALSE); - // break; - // } - - // if(InSimulationMode) { - // switch(wParam) { - // case ' ': - // SimulateOneCycle(TRUE); - // break; - - // case 'R': - // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) - // StartSimulation(); - // break; - - // case 'H': - // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) - // StopSimulation(); - // break; - - // case VK_DOWN: - // if(ScrollYOffset < ScrollYOffsetMax) - // ScrollYOffset++; - // RefreshScrollbars(); - // InvalidateRect(MainWindow, NULL, FALSE); - // break; - - // case VK_UP: - // if(ScrollYOffset > 0) - // ScrollYOffset--; - // RefreshScrollbars(); - // InvalidateRect(MainWindow, NULL, FALSE); - // break; - - // case VK_LEFT: - // ScrollXOffset -= FONT_WIDTH; - // if(ScrollXOffset < 0) ScrollXOffset = 0; - // RefreshScrollbars(); - // InvalidateRect(MainWindow, NULL, FALSE); - // break; - - // case VK_RIGHT: - // ScrollXOffset += FONT_WIDTH; - // if(ScrollXOffset >= ScrollXOffsetMax) - // ScrollXOffset = ScrollXOffsetMax; - // RefreshScrollbars(); - // InvalidateRect(MainWindow, NULL, FALSE); - // break; - - // case VK_RETURN: - // case VK_ESCAPE: - // ToggleSimulationMode(); - // break; - // } - // break; - // } - - - // switch(wParam) { - // case VK_F5: - // CompileProgram(FALSE); - // break; - - // case VK_UP: - // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { - // CHANGING_PROGRAM(PushRungUp()); - // } else { - // MoveCursorKeyboard(wParam); - // } - // break; - - // case VK_DOWN: - // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { - // CHANGING_PROGRAM(PushRungDown()); - // } else { - // MoveCursorKeyboard(wParam); - // } - // break; - - // case VK_RIGHT: - // case VK_LEFT: - // MoveCursorKeyboard(wParam); - // break; - - // case VK_RETURN: - // CHANGING_PROGRAM(EditSelectedElement()); - // break; - - // case VK_DELETE: - // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { - // CHANGING_PROGRAM(DeleteSelectedRung()); - // } else { - // CHANGING_PROGRAM(DeleteSelectedFromProgram()); - // } - // break; - - // case VK_OEM_1: - // CHANGING_PROGRAM(AddComment(_("--add comment here--"))); - // break; - - // case 'C': - // CHANGING_PROGRAM(AddContact()); - // break; - - // // TODO: rather country-specific here - // case VK_OEM_2: - // CHANGING_PROGRAM(AddEmpty(ELEM_ONE_SHOT_RISING)); - // break; - - // case VK_OEM_5: - // CHANGING_PROGRAM(AddEmpty(ELEM_ONE_SHOT_FALLING)); - // break; - - // case 'L': - // CHANGING_PROGRAM(AddCoil()); - // break; - - // case 'R': - // CHANGING_PROGRAM(MakeResetOnlySelected()); - // break; - - // case 'E': - // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) { - // ExportDialog(); - // } else { - // CHANGING_PROGRAM(AddReset()); - // } - // break; - - // case 'S': - // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) { - // SaveProgram(); - // UpdateMainWindowTitleBar(); - // } else { - // CHANGING_PROGRAM(MakeSetOnlySelected()); - // } - // break; - - // case 'N': - // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) { - // if(CheckSaveUserCancels()) break; - // if(!ProgramChangedNotSaved) { - // int r = MessageBox(MainWindow, - // _("Start new program?"), - // "LDmicro", MB_YESNO | MB_DEFBUTTON2 | - // MB_ICONQUESTION); - // if(r == IDNO) break; - // } - // NewProgram(); - // strcpy(CurrentSaveFile, ""); - // strcpy(CurrentCompileFile, ""); - // GenerateIoListDontLoseSelection(); - // RefreshScrollbars(); - // UpdateMainWindowTitleBar(); - // } else { - // CHANGING_PROGRAM(NegateSelected()); - // } - // break; - - // case 'A': - // CHANGING_PROGRAM(MakeNormalSelected()); - // break; - - // case 'T': - // CHANGING_PROGRAM(AddTimer(ELEM_RTO)); - // break; - - // case 'O': - // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) { - // if(CheckSaveUserCancels()) break; - // OpenDialog(); - // } else { - // CHANGING_PROGRAM(AddTimer(ELEM_TON)); - // } - // break; - - // case 'F': - // CHANGING_PROGRAM(AddTimer(ELEM_TOF)); - // break; - - // case 'U': - // CHANGING_PROGRAM(AddCounter(ELEM_CTU)); - // break; - - // case 'I': - // CHANGING_PROGRAM(AddCounter(ELEM_CTD)); - // break; - - // case 'J': - // CHANGING_PROGRAM(AddCounter(ELEM_CTC)); - // break; - - // case 'M': - // CHANGING_PROGRAM(AddMove()); - // break; - - // case 'P': - // CHANGING_PROGRAM(AddReadAdc()); - // break; - - // case VK_OEM_PLUS: - // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { - // CHANGING_PROGRAM(AddMath(ELEM_ADD)); - // } else { - // CHANGING_PROGRAM(AddCmp(ELEM_EQU)); - // } - // break; - - // case VK_OEM_MINUS: - // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { - // } else { - // CHANGING_PROGRAM(AddMath(ELEM_SUB)); - // } - // break; - - // case '8': - // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { - // CHANGING_PROGRAM(AddMath(ELEM_MUL)); - // } - // break; - - // case 'D': - // CHANGING_PROGRAM(AddMath(ELEM_DIV)); - // break; - - // case VK_OEM_PERIOD: - // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { - // CHANGING_PROGRAM(AddCmp(ELEM_GRT)); - // } else { - // CHANGING_PROGRAM(AddCmp(ELEM_GEQ)); - // } - // break; - - // case VK_OEM_COMMA: - // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { - // CHANGING_PROGRAM(AddCmp(ELEM_LES)); - // } else { - // CHANGING_PROGRAM(AddCmp(ELEM_LEQ)); - // } - // break; - - // case 'V': - // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { - // CHANGING_PROGRAM(InsertRung(TRUE)); - // } - // break; - - // case '6': - // if(GetAsyncKeyState(VK_SHIFT) & 0x8000) { - // CHANGING_PROGRAM(InsertRung(FALSE)); - // } - // break; - - // case 'Z': - // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) { - // UndoUndo(); - // } - // break; - - // case 'Y': - // if(GetAsyncKeyState(VK_CONTROL) & 0x8000) { - // UndoRedo(); - // } - // break; - - // default: - // break; - // } - // if(wParam != VK_SHIFT && wParam != VK_CONTROL) { - // InvalidateRect(MainWindow, NULL, FALSE); - // } - // break; - // g_print("ky call end\n"); - return FALSE; -} - gboolean LD_GTK_mouse_click_hook(GtkWidget *widget, GdkEvent *event, gpointer user_data) { /* Handles: * WM_LBUTTONDBLCLK, WM_LBUTTONDOWN */ - // g_print("mo cl call\n"); GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(ScrollWindow)); - // g_print("---\nadj = %f\n", gtk_adjustment_get_value(adjustment)); - // g_print("upper = %f\n", gtk_adjustment_get_upper(adjustment) - gtk_widget_get_allocated_height (ScrollWindow)); - // g_print("lower = %f\n", gtk_adjustment_get_lower(adjustment)); - // g_print("inc = %f\n", gtk_adjustment_get_step_increment(adjustment)); - // g_print("w width = %i\n", gtk_widget_get_allocated_width (DrawWindow)); - // g_print("w height = %i\n---\n", gtk_widget_get_allocated_height (ScrollWindow)); switch(event->button.type) { case GDK_BUTTON_PRESS: if (event->button.button == 1) /// left click { + GLOBAL_mouse_last_clicked_x = event->button.x_root; + GLOBAL_mouse_last_clicked_y = event->button.y_root; + int x = event->button.x; int y = event->button.y - 30 + gtk_adjustment_get_value(adjustment); @@ -1008,13 +685,15 @@ gboolean LD_GTK_mouse_click_hook(GtkWidget *widget, GdkEvent *event, gpointer us if(!InSimulationMode) MoveCursorMouseClick(x, y); // SetFocus(MainWindow); - // InvalidateRect(DrawWindow, NULL, FALSE); gtk_widget_queue_draw(DrawWindow); } break; case GDK_2BUTTON_PRESS: if (event->button.button == 1) /// left click { + GLOBAL_mouse_last_clicked_x = event->button.x_root; + GLOBAL_mouse_last_clicked_y = event->button.y_root; + int x = event->button.x; int y = event->button.y - 30 + gtk_adjustment_get_value(adjustment); @@ -1023,13 +702,11 @@ gboolean LD_GTK_mouse_click_hook(GtkWidget *widget, GdkEvent *event, gpointer us } else { CHANGING_PROGRAM(EditElementMouseDoubleclick(x, y)); } - // InvalidateRect(DrawWindow, NULL, FALSE); gtk_widget_queue_draw(DrawWindow); } break; } - // g_print("mo cl call end\n"); return FALSE; } @@ -1038,14 +715,8 @@ gboolean LD_GTK_mouse_scroll_hook(GtkWidget *widget, GdkEvent *event, gpointer u /* Handles: * WM_VSCROLL, WM_HSCROLL, WM_MOUSEWHEEL */ - // g_print("mo sc call\n"); + GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(ScrollWindow)); - // g_print("adj = %f\n", gtk_adjustment_get_value(adjustment)); - // g_print("upper = %f\n", gtk_adjustment_get_upper(adjustment) - gtk_widget_get_allocated_height (ScrollWindow)); - // g_print("lower = %f\n", gtk_adjustment_get_lower(adjustment)); - // g_print("inc = %f\n", gtk_adjustment_get_step_increment(adjustment)); - // g_print("w width = %i\n", gtk_widget_get_allocated_width (DrawWindow)); - // g_print("w height = %i\n", gtk_widget_get_allocated_height (ScrollWindow)); switch(event->scroll.direction) { @@ -1080,7 +751,6 @@ gboolean LD_GTK_mouse_scroll_hook(GtkWidget *widget, GdkEvent *event, gpointer u } gtk_widget_queue_draw(DrawWindow); - // g_print("mo sc call end\n"); return FALSE; } @@ -1089,9 +759,6 @@ gboolean LD_WM_MouseMove_call(GtkWidget *widget, GdkEvent *event, gpointer user_ /* Handles: * WM_MOUSEMOVE */ - // g_print("mo mv call\n"); - // g_print("x = %f\n", event->button.x_root); - // g_print("y = %f\n", event->button.y_root); // int x = LOWORD(lParam); // int y = HIWORD(lParam); @@ -1106,92 +773,53 @@ gboolean LD_WM_MouseMove_call(GtkWidget *widget, GdkEvent *event, gpointer user_ return FALSE; } -gboolean LD_WM_Paint_call(HWID widget, HCRDC cr, gpointer data)//(HWID widget, GdkEventExpose *event)// +gboolean LD_WM_Paint_call(HWID widget, HCRDC cr, gpointer data) { /* Handles: * WM_PAINT */ - // g_print("draw called----------------------------------\n"); static BOOL Paint_call_first = TRUE; if (Paint_call_first) { gtk_widget_override_background_color(GTK_WIDGET(widget), GTK_STATE_FLAG_NORMAL, (HBRUSH)GetStockObject(BLACK_BRUSH)); + gint width = gtk_widget_get_allocated_width (widget); gint height = gtk_widget_get_allocated_height (widget); - COLORREF col; - GtkStyleContext *context; - context = gtk_widget_get_style_context (widget); - gtk_style_context_get_color (context, - gtk_style_context_get_state (context), - &col); - gdk_cairo_set_source_rgba (cr, &col); - gtk_render_background (context, cr, 0, 0, width, height); + gtk_widget_set_size_request(widget, width, height+1); + + gdk_cairo_set_source_rgba (cr, (HBRUSH)GetStockObject(BLACK_BRUSH)); + + cairo_rectangle(cr, 0, 0, width, height); + cairo_stroke_preserve(cr); + + cairo_fill (cr); + Paint_call_first = FALSE; } /// This draws the schematic. MainWindowResized(); PaintWindow(cr); - - /* Cairo test code - guint width, height; - GdkRGBA color; - GtkStyleContext *context; - context = gtk_widget_get_style_context (widget); - - width = gtk_widget_get_allocated_width (widget); - height = gtk_widget_get_allocated_height (widget); - g_print("w = %i\n", width); - g_print("h = %i\n", height); - - SetBkColor(widget, cr, HighlightColours.bg); - - gtk_render_background (context, cr, 0, 0, width, height); - - // cairo_arc (cr, - // width / 2.0, height / 2.0, - // MIN (width, height) / 3.0, - // 0, 2 * G_PI); - - cairo_rectangle(cr, 0, 0, width, height); - cairo_stroke_preserve(cr); - - gtk_style_context_get_color (context, - gtk_style_context_get_state (context), - &color); - gdk_cairo_set_source_rgba (cr, &color); - - cairo_fill (cr); - - SetBkColor(DrawWindow, cr, InSimulationMode ? HighlightColours.simBg : - HighlightColours.bg); - SetTextColor(cr, InSimulationMode ? HighlightColours.simRungNum : - HighlightColours.rungNum); - SelectObject(cr, FixedWidthFont); - for (int xp = 0; xp<= width; xp += 7) - for (int yp = 0; yp <= height; yp += 7) - TextOut(DrawWindow, cr, xp, yp, "H", 1); - */ return FALSE; } -gboolean LD_WM_Destroy_call(GtkWidget *widget, GdkEvent *event, gpointer user_data) +void LD_WM_Destroy_call(GtkWidget *widget, GdkEvent *event, gpointer user_data) { /* Handles: * WM_DESTROY */ - // g_print("dis call\n"); - // if(CheckSaveUserCancels()) break; - // PostQuitMessage(0); - // return 1; + CheckSaveUserCancels(); - return FALSE; + FreezeWindowPos(MainWindow); + FreezeDWORD(IoListHeight); + + gtk_main_quit(); } gboolean LD_WM_Size_call(GtkWidget *widget, GdkEvent *event, gpointer user_data) @@ -1199,9 +827,15 @@ gboolean LD_WM_Size_call(GtkWidget *widget, GdkEvent *event, gpointer user_data) /* Handles: * WM_SIZE */ - // g_print("size call\n"); MainWindowResized(); - // g_print("size call end\n"); + return FALSE; +} + +gboolean LD_WM_Command_call(GtkMenuItem* men, gpointer gpcode) +{ + int tempcode = GPOINTER_TO_INT(gpcode); + ProcessMenu (tempcode); + return FALSE; } @@ -1210,12 +844,251 @@ gboolean LD_WM_SetFocus_call(GtkWidget *widget, GdkEvent *event, gpointer user_d /* Handles: * WM_SETFOCUS */ - // g_print("focus call\n"); + InvalidateRect(DrawWindow, NULL, FALSE); - // g_print("focus call end\n"); + return FALSE; } +void LD_WM_Notify_Row_Activate_call(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data) +{ + /* Handles: + * WM_NOTIFY + */ + + // g_print("Row activated!\n"); + + int *ip = gtk_tree_path_get_indices ( path ); + + NMHDR h; + h.code = LVN_ITEMACTIVATE; + h.item.iItem = ip[0]; + h.hlistFrom = IoList; + + IoListProc(&h); +} + +void LD_WM_Notify_Cursor_Change_call(GtkTreeView *tree_view, gpointer user_data) +{ + /* Handles: + * WM_NOTIFY + */ + + ITLIST iter; + + // BOOL empty = !gtk_tree_model_get_iter_first (IoList, &iter); + // g_print("empty = %i\n", (empty == TRUE) ); + + HLIST pTreeModel; + int *ip; + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); + gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); + if(gtk_tree_selection_get_selected (selection, &pTreeModel, &iter)) + { + GtkTreePath *path = gtk_tree_model_get_path ( pTreeModel , &iter ) ; + ip = gtk_tree_path_get_indices ( path ); + } + else + if(!gtk_tree_model_get_iter_first (IoList, &iter)) + return; + + NMHDR h; + h.code = LVN_GETDISPINFO; + h.item.iItem = (ip == NULL) ? 0 : ip[0]; + h.hlistFrom = IoList; + h.hlistIter = &iter; + IoListProc(&h); +} + +inline void MenuHandler () +{ + g_signal_connect(G_OBJECT(NewMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_NEW)); + + g_signal_connect(G_OBJECT(OpenMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_OPEN)); + + g_signal_connect(G_OBJECT(SaveMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_SAVE)); + + g_signal_connect(G_OBJECT(SaveAsMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_SAVE_AS)); + + g_signal_connect(G_OBJECT(ExportMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_EXPORT)); + + g_signal_connect(G_OBJECT(ExitMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_EXIT)); + + g_signal_connect(G_OBJECT(InsertCommentMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_COMMENT)); + + g_signal_connect(G_OBJECT(InsertContactsMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_CONTACTS)); + + g_signal_connect(G_OBJECT(InsertCoilMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_COIL)); + + g_signal_connect(G_OBJECT(InsertTonMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_TON)); + + g_signal_connect(G_OBJECT(InsertTofMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_TOF)); + + g_signal_connect(G_OBJECT(InsertRtoMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_RTO)); + + g_signal_connect(G_OBJECT(InsertCtuMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_CTU)); + + g_signal_connect(G_OBJECT(InsertCtdMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_CTD)); + + g_signal_connect(G_OBJECT(InsertCtcMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_CTC)); + + g_signal_connect(G_OBJECT(InsertResMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_RES)); + + g_signal_connect(G_OBJECT(InsertOpenMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_OPEN)); + + g_signal_connect(G_OBJECT(InsertShortMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_SHORT)); + + g_signal_connect(G_OBJECT(InsertMasterRlyMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_MASTER_RLY)); + + g_signal_connect(G_OBJECT(InsertShiftRegMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_SHIFT_REG)); + + g_signal_connect(G_OBJECT(InsertLutMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_LUT)); + + g_signal_connect(G_OBJECT(InsertPwlMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_PWL)); + + g_signal_connect(G_OBJECT(InsertFmtdStrMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_FMTD_STR)); + + g_signal_connect(G_OBJECT(InsertOsrMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_OSR)); + + g_signal_connect(G_OBJECT(InsertOsfMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_OSF)); + + g_signal_connect(G_OBJECT(InsertMovMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_MOV)); + + g_signal_connect(G_OBJECT(InsertSetPwmMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_SET_PWM)); + + g_signal_connect(G_OBJECT(InsertReadAdcMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_READ_ADC)); + + g_signal_connect(G_OBJECT(InsertUartSendMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_UART_SEND)); + + g_signal_connect(G_OBJECT(InsertUartRecvMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_UART_RECV)); + + g_signal_connect(G_OBJECT(InsertPersistMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_PERSIST)); + + g_signal_connect(G_OBJECT(InsertAddMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_ADD)); + + g_signal_connect(G_OBJECT(InsertSubMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_SUB)); + + g_signal_connect(G_OBJECT(InsertMulMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_MUL)); + + g_signal_connect(G_OBJECT(InsertDivMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_DIV)); + + g_signal_connect(G_OBJECT(InsertEquMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_EQU)); + + g_signal_connect(G_OBJECT(InsertNeqMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_NEQ)); + + g_signal_connect(G_OBJECT(InsertGrtMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_GRT)); + + g_signal_connect(G_OBJECT(InsertGeqMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_GEQ)); + + g_signal_connect(G_OBJECT(InsertLesMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_LES)); + + g_signal_connect(G_OBJECT(InsertLeqMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_LEQ)); + + g_signal_connect(G_OBJECT(MakeNormalMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_MAKE_NORMAL)); + + g_signal_connect(G_OBJECT(NegateMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_NEGATE)); + + g_signal_connect(G_OBJECT(MakeSetOnlyMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_MAKE_SET_ONLY)); + + g_signal_connect(G_OBJECT(MakeResetOnlyMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_MAKE_RESET_ONLY)); + + g_signal_connect(G_OBJECT(UndoMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_UNDO)); + + g_signal_connect(G_OBJECT(RedoMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_REDO)); + + g_signal_connect(G_OBJECT(InsertRungBeforeMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_RUNG_BEFORE)); + + g_signal_connect(G_OBJECT(InsertRungAfterMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_INSERT_RUNG_AFTER)); + + g_signal_connect(G_OBJECT(DeleteRungMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_DELETE_RUNG)); + + g_signal_connect(G_OBJECT(PushRungUpMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_PUSH_RUNG_UP)); + + g_signal_connect(G_OBJECT(PushRungDownMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_PUSH_RUNG_DOWN)); + + g_signal_connect(G_OBJECT(DeleteElementMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_DELETE_ELEMENT)); + + g_signal_connect(G_OBJECT(McuSettingsMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_MCU_SETTINGS)); + + g_signal_connect(G_OBJECT(SimulationModeMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_SIMULATION_MODE)); + + g_signal_connect(G_OBJECT(StartSimulationMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_START_SIMULATION)); + + g_signal_connect(G_OBJECT(StopSimulationMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_STOP_SIMULATION)); + + g_signal_connect(G_OBJECT(SingleCycleMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_SINGLE_CYCLE)); + + g_signal_connect(G_OBJECT(CompileMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_COMPILE)); + + g_signal_connect(G_OBJECT(CompileAsMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_COMPILE_AS)); + + g_signal_connect(G_OBJECT(ManualMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_MANUAL)); + + g_signal_connect(G_OBJECT(AboutMenu), "activate", + G_CALLBACK(LD_WM_Command_call), GINT_TO_POINTER(MNU_ABOUT)); +} + //----------------------------------------------------------------------------- // Entry point into the program. //----------------------------------------------------------------------------- @@ -1230,12 +1103,6 @@ int main(int argc, char** argv) char *err = "Bad command line arguments: run 'ldmicro /c src.ld dest.hex'"; - // if (argc < 4) - // { - // Error(err); - // exit(-1); - // } - char *source = (char*)malloc(strlen(argv[2]) + strlen(argv[3]) + 2); sprintf(source, "%s %s", argv[2], argv[3]); @@ -1290,33 +1157,6 @@ int main(int argc, char** argv) gtk_init(&argc, &argv); Instance = NULL; - /* TEST - MainWindow=gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title(GTK_WINDOW(MainWindow), "LDMicro"); - g_signal_connect (MainWindow, "delete_event", G_CALLBACK (LDMicro_close), NULL); - gtk_window_set_default_size (GTK_WINDOW (MainWindow), 600, 400); - gtk_window_resize (GTK_WINDOW (MainWindow), 600, 400); - - ThawWindowPos(MainWindow); - ThawDWORD(IoListHeight); - - - // Title bar - UpdateMainWindowTitleBar(); - - // Splitting the window - MakeMainWindowControls(); - - // Calling the Simulation functions - - // StartSimulation(); // test - // SetMenusEnabled(true, true, false, - // true, false, false, false, - // true, true, true); // test - // ToggleSimulationMode(); //test - // GenerateIoListDontLoseSelection(); - StopSimulation(); //Test - */ MainHeap = HeapCreate(0, 1024*64, 0); @@ -1327,7 +1167,7 @@ int main(int argc, char** argv) gtk_window_resize (GTK_WINDOW(MainWindow), 800, 600); gtk_window_move(GTK_WINDOW(MainWindow), 10, 10); gtk_widget_override_background_color(GTK_WIDGET(MainWindow), - GTK_STATE_FLAG_NORMAL, ((HBRUSH)GetStockObject(GRAY_BRUSH))->getThis()); + GTK_STATE_FLAG_NORMAL, ((HBRUSH)GetStockObject(DKGRAY_BRUSH))); gtk_window_set_default_icon(LoadImage(Instance, LDMICRO_ICON, IMAGE_ICON, 32, 32, 0)); gtk_window_set_icon(GTK_WINDOW(MainWindow), LoadImage(Instance, LDMICRO_ICON, @@ -1335,6 +1175,7 @@ int main(int argc, char** argv) /// Make main window - end MakeMainWindowMenus(); + MakeDialogBoxClass(); InitForDrawing(); @@ -1344,19 +1185,19 @@ int main(int argc, char** argv) MakeMainWindowControls(); /// takes care of MakeMainWindowMenus() MainWindowResized(); - // CHANGING_PROGRAM(ShowConfDialog()); - MenuHandler(); /// Keyboard and mouse hooks equivalent to MainWndProc g_signal_connect (MainWindow, "delete_event", G_CALLBACK (LD_WM_Close_call), NULL); - // g_signal_connect (MainWindow, "key_press_event", G_CALLBACK (LD_WM_KeyDown_call), NULL); g_signal_connect (MainWindow, "button_press_event", G_CALLBACK (LD_GTK_mouse_click_hook), NULL); g_signal_connect (MainWindow, "scroll_event", G_CALLBACK (LD_GTK_mouse_scroll_hook), NULL); g_signal_connect (MainWindow, "motion_notify_event", G_CALLBACK (LD_WM_MouseMove_call), NULL); g_signal_connect (DrawWindow, "draw", G_CALLBACK (LD_WM_Paint_call), NULL); g_signal_connect (MainWindow, "destroy_event", G_CALLBACK (LD_WM_Destroy_call), NULL); g_signal_connect (MainWindow, "configure_event", G_CALLBACK (LD_WM_Size_call), NULL); - // g_signal_connect (MainWindow, "focus_in_event", G_CALLBACK (LD_WM_SetFocus_call), NULL); + g_signal_connect (MainWindow, "focus_in_event", G_CALLBACK (LD_WM_SetFocus_call), NULL); + g_signal_connect (view, "row_activated", G_CALLBACK (LD_WM_Notify_Row_Activate_call), NULL); + g_signal_connect (view, "cursor_changed", G_CALLBACK (LD_WM_Notify_Cursor_Change_call), NULL); + MenuHandler(); /// Keyboard and mouse hooks equivalent to MainWndProc - end NewProgram(); @@ -1369,10 +1210,10 @@ 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) { - // g_print("load prog: %s\n", argv[1]); char line[MAX_PATH]; if(*argv[1] == '"') { strcpy(line, argv[1]+1); @@ -1382,7 +1223,6 @@ int main(int argc, char** argv) if(strchr(line, '"')) *strchr(line, '"') = '\0'; realpath(line, CurrentSaveFile); - // g_print("resolved path: %s\n", CurrentSaveFile); if(!LoadProjectFromFile(CurrentSaveFile)) { NewProgram(); Error(_("Couldn't open '%s'."), CurrentSaveFile); @@ -1391,9 +1231,9 @@ int main(int argc, char** argv) UndoFlush(); } - GenerateIoListDontLoseSelection(); //~ - // RefreshScrollbars(); - UpdateMainWindowTitleBar(); //~ + GenerateIoListDontLoseSelection(); + RefreshScrollbars(); + UpdateMainWindowTitleBar(); // MSG msg; // DWORD ret; diff --git a/ldmicro/lib/freezeLD/freezeLD.cpp b/ldmicro/lib/freezeLD/freezeLD.cpp index b9cafb2..75bbb30 100644 --- a/ldmicro/lib/freezeLD/freezeLD.cpp +++ b/ldmicro/lib/freezeLD/freezeLD.cpp @@ -18,7 +18,6 @@ */ void FreezeWindowPosF(HWID hwid, char *subKey, char *name) { - //g_print("freezing"); char* Ld_CWD = (char *)malloc(MAX_PATH); getcwd(Ld_CWD, MAX_PATH); @@ -52,7 +51,7 @@ void FreezeWindowPosF(HWID hwid, char *subKey, char *name) Key newKey; int val; - //g_print("get width"); + sprintf(keyName, "%s_width", name); std::ofstream Register(keyName, std::ios::binary | std::ios::trunc); if (!Register.is_open()) @@ -67,7 +66,6 @@ void FreezeWindowPosF(HWID hwid, char *subKey, char *name) Register.write((char*) &newKey, sizeof(newKey)); Register.close(); - //g_print("get height"); sprintf(keyName, "%s_height", name); Register.open(keyName, std::ios::binary | std::ios::trunc); if (!Register.is_open()) @@ -82,7 +80,6 @@ void FreezeWindowPosF(HWID hwid, char *subKey, char *name) Register.write((char*) &newKey, sizeof(newKey)); Register.close(); - //g_print("get posX"); sprintf(keyName, "%s_posX", name); Register.open(keyName, std::ios::binary | std::ios::trunc); if (!Register.is_open()) @@ -97,7 +94,6 @@ void FreezeWindowPosF(HWID hwid, char *subKey, char *name) Register.write((char*) &newKey, sizeof(newKey)); Register.close(); - //g_print("get posY"); sprintf(keyName, "%s_posY", name); Register.open(keyName, std::ios::binary | std::ios::trunc); if (!Register.is_open()) @@ -112,7 +108,6 @@ void FreezeWindowPosF(HWID hwid, char *subKey, char *name) Register.write((char*) &newKey, sizeof(newKey)); Register.close(); - //g_print("get max"); sprintf(keyName, "%s_maximized", name); Register.open(keyName, std::ios::binary | std::ios::trunc); if (!Register.is_open()) @@ -129,7 +124,6 @@ void FreezeWindowPosF(HWID hwid, char *subKey, char *name) free(keyName); chdir(Ld_CWD); free(Ld_CWD); - //g_print("freezed"); } static void Clamp(LONG *v, LONG min, LONG max) diff --git a/ldmicro/lib/linuxUI/linuxLD.h b/ldmicro/lib/linuxUI/linuxLD.h index 80f4471..ce0b812 100644 --- a/ldmicro/lib/linuxUI/linuxLD.h +++ b/ldmicro/lib/linuxUI/linuxLD.h @@ -68,14 +68,16 @@ typedef HANDLE HGDIOBJ; typedef cairo_t *HCRDC; typedef GtkWidget *HWID; -typedef GtkWidget *HMENU; typedef GtkWindow *HWND; -typedef GtkListStore *HLIST; +typedef GtkTreeModel *HLIST; +typedef GtkTreeIter ITLIST; typedef GtkApplication *HAPP; typedef GtkTreeViewColumn *HTVC; typedef GdkPixbuf *HICON; typedef GdkRectangle GDRECT; -typedef GdkRectangle *PGDRECT; +typedef GDRECT *PGDRECT; +typedef HWID HMENU; +typedef ITLIST *HITLIST; /// Check if system is x64 or x86 #if defined(__UNIX64) @@ -122,10 +124,6 @@ typedef class tagColorReferance: public GdkRGBA{ return false; } - GdkRGBA* getThis() - { - return this; - } } COLORREF, *HBRUSH; /// Structures @@ -144,19 +142,38 @@ typedef struct HeapRecordTag{ } HEAPRECORD; typedef struct tagSCROLLINFO { - UINT cbSize; - UINT fMask; - int nMin; - int nMax; - UINT nPage; - int nPos; - int nTrackPos; + UINT cbSize; + UINT fMask; + int nMin; + int nMax; + UINT nPage; + int nPos; + int nTrackPos; } SCROLLINFO, *LPCSCROLLINFO; +typedef struct { + UINT mask; + int iItem; + int iSubItem; +// UINT state; +// UINT stateMask; + LPTSTR pszText; +// int cchTextMax; +// int iImage; +// LPARAM lParam; +// int iIndent; +// int iGroupId; +// UINT cColumns; +// PUINT puColumns; +// int *piColFmt; +// int iGroup; +} LVITEM, *LPLVITEM; + typedef struct tagNMHDR { - HWND hwndFrom; - UINT_PTR idFrom; - UINT code; + HLIST hlistFrom; + HITLIST hlistIter; + UINT code; + LVITEM item; } NMHDR; typedef struct FontTag { @@ -165,7 +182,7 @@ typedef struct FontTag { int nOrientation; int fnWeight; DWORD fdwItalic; - LPCTSTR lpszFace; + LPTSTR lpszFace; } *HFONT, FONT; typedef struct tagLOGBRUSH { diff --git a/ldmicro/lib/linuxUI/linuxUI.cpp b/ldmicro/lib/linuxUI/linuxUI.cpp index 52c4c36..d7248b7 100644 --- a/ldmicro/lib/linuxUI/linuxUI.cpp +++ b/ldmicro/lib/linuxUI/linuxUI.cpp @@ -1,5 +1,9 @@ #include "linuxUI.h" +/// Global variables to hole mouse click positions +int GLOBAL_mouse_last_clicked_x; +int GLOBAL_mouse_last_clicked_y; + /// Brushes const COLORREF BLACK_BR(0, 0, 0); const COLORREF WHITE_BR(255, 255, 255); @@ -10,6 +14,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; @@ -96,21 +103,87 @@ int MessageBox(HWID pWindow, char* message, char* title, UINT mFlags) BOOL GetSaveFileName(OPENFILENAME *ofn) { GtkWidget *dialog; - GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; + GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE; dialog = gtk_file_chooser_dialog_new (ofn->lpstrTitle, GTK_WINDOW(ofn->parentWindow), action, "_Cancel", GTK_RESPONSE_CANCEL, - "_Open", + "_Save", GTK_RESPONSE_ACCEPT, NULL); - //g_print("filter created\n"); + char filename[15] = "Untitled"; + + if (ofn->lpstrDefExt != NULL) + sprintf(filename, "Untitled.%s", ofn->lpstrDefExt); - if (ofn->Flags & OFN_OVERWRITEPROMPT == OFN_OVERWRITEPROMPT) + gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(dialog), filename); + + if (ofn->Flags & OFN_OVERWRITEPROMPT) gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); + + GtkFileFilter *filter = gtk_file_filter_new (); + char* strFilter = new char[strlen(ofn->lpstrFilter)]; + DWORD strFilterLen = 0; + BOOL filterResetFlag = FALSE; + + for (int i = 0; !(ofn->lpstrFilter[i] == '\0' && ofn->lpstrFilter[i-1] == '\0'); ++i) + { + memcpy (strFilter + strFilterLen, &ofn->lpstrFilter[i], 1 ); + ++strFilterLen; + if (ofn->lpstrFilter[i] == '\0') + if (filterResetFlag) + { + gtk_file_filter_add_pattern (GTK_FILE_FILTER(filter), strFilter); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter); + filter = gtk_file_filter_new (); + strFilterLen = 0; + filterResetFlag = FALSE; + } + else + { + gtk_file_filter_set_name (GTK_FILE_FILTER(filter), strFilter); + strFilterLen = 0; + filterResetFlag = TRUE; + } + } + + sprintf(strFilter, "*.%s", ofn->lpstrDefExt); + gtk_file_filter_add_pattern (GTK_FILE_FILTER(filter), strFilter); + gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(dialog), filter); + + delete strFilter; + + BOOL exitStatus = gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT; + if (exitStatus) + { + char* str; + str = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(dialog)); + + strcpy(ofn->lpstrFile, str); + g_free(str); + } + + gtk_widget_destroy (dialog); + + return exitStatus; +} +BOOL GetOpenFileName(OPENFILENAME *ofn) +{ + GtkWidget *dialog; + GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; + + dialog = gtk_file_chooser_dialog_new (ofn->lpstrTitle, + GTK_WINDOW(ofn->parentWindow), + action, + "_Cancel", + GTK_RESPONSE_CANCEL, + "_Open", + GTK_RESPONSE_ACCEPT, + NULL); + GtkFileFilter *filter = gtk_file_filter_new (); char* strFilter = new char[strlen(ofn->lpstrFilter)]; DWORD strFilterLen = 0; @@ -127,19 +200,15 @@ BOOL GetSaveFileName(OPENFILENAME *ofn) gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter); filter = gtk_file_filter_new (); strFilterLen = 0; - //g_print("filter pat: %s\n", strFilter); - //g_print("filter reset\n"); filterResetFlag = FALSE; } else { gtk_file_filter_set_name (GTK_FILE_FILTER(filter), strFilter); - //g_print("filter name: %s\n", strFilter); strFilterLen = 0; filterResetFlag = TRUE; } } - //g_print("filter rules added\n"); sprintf(strFilter, "*.%s", ofn->lpstrDefExt); gtk_file_filter_add_pattern (GTK_FILE_FILTER(filter), strFilter); @@ -148,8 +217,6 @@ BOOL GetSaveFileName(OPENFILENAME *ofn) delete strFilter; - //g_print("default filter set\n"); - BOOL exitStatus = gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT; if (exitStatus) { @@ -158,15 +225,13 @@ BOOL GetSaveFileName(OPENFILENAME *ofn) strcpy(ofn->lpstrFile, str); g_free(str); } - //g_print("file path saved: %s\n", ofn->lpstrFile); gtk_widget_destroy (dialog); - //g_print("exit\n"); - return exitStatus; } + void EnableMenuItem(HMENU MenuName, HMENU MenuItem, UINT CheckEnabledItem) { switch (CheckEnabledItem){ @@ -217,6 +282,9 @@ HANDLE GetStockObject(int fnObject) void SelectObject(HCRDC hcr, HFONT hfont) { + if (hcr ==NULL) + return; + cairo_select_font_face(hcr, hfont->lpszFace, hfont->fdwItalic ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_NORMAL, hfont->fnWeight == FW_BOLD ? CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL); @@ -231,8 +299,6 @@ void SelectObject(HCRDC hcr, HFONT hfont) // cairo_set_font_matrix (hcr, &matrix); - // g_print("wR = %f\nhR = %f\n", (double)hfont->nWidth / extents.width, (double)hfont->nHeight / extents.height); - // g_print("tW = %f tH = %f\n", extents.width, extents.width); cairo_set_font_size(hcr, 10); } @@ -250,24 +316,28 @@ HBRUSH CreateBrushIndirect(PLOGBRUSH plb) HFONT CreateFont(int nHeight, int nWidth, int nOrientation, int fnWeight, DWORD fdwItalic, LPCTSTR lpszFace) { - HFONT font = new FONT; + HFONT font = (HFONT)malloc(strlen(lpszFace) + 1 + sizeof(FONT)); font->nHeight = nHeight; font->nWidth = nWidth; font->nOrientation = nOrientation; font->fnWeight = fnWeight; font->fdwItalic = fdwItalic; - font->lpszFace = lpszFace; - + font->lpszFace = (char*)malloc(strlen(lpszFace)+1); + strcpy(font->lpszFace, lpszFace); + return font; } void SetBkColor(HWID widget, HCRDC hcr, COLORREF bkCol) { - // gtk_widget_override_background_color(GTK_WIDGET(widget), - // GTK_STATE_FLAG_NORMAL, &bkCol); + if (hcr == NULL) + return; + + gtk_widget_override_background_color(GTK_WIDGET(widget), + GTK_STATE_FLAG_NORMAL, &bkCol); - // gint width = gtk_widget_get_allocated_width (widget); - // gint height = gtk_widget_get_allocated_height (widget); + gint width = gtk_widget_get_allocated_width (widget); + gint height = gtk_widget_get_allocated_height (widget); // COLORREF col; // GtkStyleContext *context; @@ -277,20 +347,27 @@ void SetBkColor(HWID widget, HCRDC hcr, COLORREF bkCol) // gtk_style_context_get_color (context, // gtk_style_context_get_state (context), // &col); - - // gdk_cairo_set_source_rgba (hcr, &col); + gdk_cairo_set_source_rgba (hcr, &bkCol); + // cairo_rectangle(hcr, 0, 0, width, height); + // cairo_stroke_preserve(hcr); - // cairo_fill (hcr); + cairo_fill (hcr); } void SetTextColor(HCRDC hcr, COLORREF color) { + if (hcr == NULL) + return; + HdcCurrentTextColor = color; gdk_cairo_set_source_rgba (hcr, &color); } void TextOut(HWID hWid, HCRDC hcr, int nXStart, int nYStart, LPCTSTR lpString, int cchString) { + if (hcr == NULL) + return; + nYStart += 30; cairo_text_extents_t extents; @@ -298,24 +375,22 @@ void TextOut(HWID hWid, HCRDC hcr, int nXStart, int nYStart, LPCTSTR lpString, i int width = gtk_widget_get_allocated_width (hWid); int height= gtk_widget_get_allocated_height (hWid); BOOL resize_flag = FALSE; - // g_print("w = %f h = %f") if(nYStart+(extents.height/2.0) >= height) { - // g_print("Y extend\n"); height += extents.height + 50; resize_flag = TRUE; } if (nXStart+(extents.width/2.0) >= width) { - // g_print("X extend\n"); width += extents.width; resize_flag = TRUE; } if (resize_flag) gtk_widget_set_size_request(hWid, width, height); + char* text = (char*)malloc(cchString); strncpy(text, lpString, cchString); text[cchString] = '\0'; @@ -323,8 +398,6 @@ void TextOut(HWID hWid, HCRDC hcr, int nXStart, int nYStart, LPCTSTR lpString, i cairo_move_to(hcr, nXStart, nYStart); cairo_show_text(hcr, text); - // g_print("%s", text); - cairo_fill (hcr); } @@ -341,10 +414,7 @@ COLORREF GetTextColor(HCRDC Hdc) BOOL InvalidateRect(HWID hWid, const RECT *lpRect, BOOL bErase) { if(!GDK_IS_WINDOW(hWid)) - { - // g_print("not window\n"); return FALSE; - } if (lpRect == NULL) { @@ -362,6 +432,9 @@ BOOL InvalidateRect(HWID hWid, const RECT *lpRect, BOOL bErase) int FillRect(HCRDC hDC, const RECT *lprc, HBRUSH hbr) { + if (hDC == NULL) + return -1; + GDRECT gdrc; RECT_to_GDRECT(lprc, &gdrc); @@ -375,6 +448,9 @@ int FillRect(HCRDC hDC, const RECT *lprc, HBRUSH hbr) BOOL PatBlt(HCRDC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, DWORD dwRop, HBRUSH hbr) { + if (hdc == NULL) + return FALSE; + cairo_set_source_rgb(hdc, hbr->red, hbr->green, hbr->blue); cairo_rectangle(hdc, nXLeft, nYLeft + 20, nWidth, nHeight); cairo_stroke_preserve(hdc); @@ -420,4 +496,40 @@ BOOL GetWindowRect(HWID hWid, PRECT pRect) pRect->bottom = allocation.height; return TRUE; -}
\ No newline at end of file +} + + +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; +} + +void DestroyWindow (HWID widget) +{ + gtk_widget_destroy (widget); +} diff --git a/ldmicro/lib/linuxUI/linuxUI.h b/ldmicro/lib/linuxUI/linuxUI.h index bda2c5d..b1a3d48 100644 --- a/ldmicro/lib/linuxUI/linuxUI.h +++ b/ldmicro/lib/linuxUI/linuxUI.h @@ -34,24 +34,33 @@ #define MB_ICONINFORMATION 0x00000080L /// Scroll -#define SB_LINEUP 0x00000001 -#define SB_PAGEUP 0x00000002 -#define SB_LINEDOWN 0x00000004 -#define SB_PAGEDOWN 0x00000008 -#define SB_TOP 0x00000010 -#define SB_BOTTOM 0x00000020 -#define SB_THUMBTRACK 0x00000040 -#define SB_THUMBPOSITION 0x00000040 - -/// open/save file -#define OFN_PATHMUSTEXIST 0x00000100L -#define OFN_HIDEREADONLY 0x00000200L -#define OFN_OVERWRITEPROMPT 0x00000400L +#define SB_LINEUP 0x00000001 +#define SB_PAGEUP 0x00000002 +#define SB_LINEDOWN 0x00000004 +#define SB_PAGEDOWN 0x00000008 +#define SB_TOP 0x00000010 +#define SB_BOTTOM 0x00000020 +#define SB_THUMBTRACK 0x00000040 +#define SB_THUMBPOSITION 0x00000080 + +/// UART terminal flags +#define WM_GETTEXT 0x00000001 +#define WM_SETTEXT 0x00000002 +#define WM_SETTEXT_END 0x00000004 + +/// List view flags +#define LVN_ITEMACTIVATE 0x00000001 +#define LVN_GETDISPINFO 0x00000002 + +/// Open/save file +#define OFN_PATHMUSTEXIST 0x00000001L +#define OFN_HIDEREADONLY 0x00000002L +#define OFN_OVERWRITEPROMPT 0x00000004L /// PatBlt paint flags #define PATINVERT 0x00000100L -/// window brushes +/// Window brushes #define BS_SOLID 0x00000001L #define BS_HOLLOW 0x00000002L #define BLACK_BRUSH 0x00000004L @@ -96,9 +105,17 @@ 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; +extern int GLOBAL_mouse_last_clicked_x; +extern int GLOBAL_mouse_last_clicked_y; /// functions BOOL GetFocus(HWID window); @@ -115,6 +132,8 @@ int MessageBox( BOOL GetSaveFileName(OPENFILENAME *ofn); +BOOL GetOpenFileName(OPENFILENAME *ofn); + void EnableMenuItem( HMENU MenuName, HMENU MenuItem, @@ -195,4 +214,16 @@ BOOL GetWindowRect( HWID hWid, PRECT pRect); +UINT SetTimer( + HWID hWid, + UINT nIDEvent, + UINT uElapse, + BOOL (*lpTimerFunc)(BOOL)); + +BOOL KillTimer( + HWID hWid, + UINT uIDEvent); + +void DestroyWindow (HWID widget); + #endif
\ No newline at end of file diff --git a/ldmicro/lutdialog.cpp b/ldmicro/lutdialog.cpp index fde3156..188b1a8 100644 --- a/ldmicro/lutdialog.cpp +++ b/ldmicro/lutdialog.cpp @@ -26,95 +26,93 @@ #include "linuxUI.h" #include <stdio.h> #include <stdlib.h> +#include <iostream> //#include <commctrl.h> #include "ldmicro.h" -// static HWND LutDialog; +using namespace std; -// static HWND AsStringCheckbox; -// static HWND CountTextbox; -// static HWND DestTextbox; -// static HWND IndexTextbox; -// static HWND Labels[3]; +static HWID LutDialog; -// static HWND StringTextbox; +static HWID AsStringCheckbox; +static HWID CountTextbox; +static HWID DestTextbox; +static HWID IndexTextbox; +static HWID Labels[3]; + +static HWID StringTextbox; +static bool checkString; static BOOL WasAsString; static int WasCount; -//static HWND ValuesTextbox[MAX_LOOK_UP_TABLE_LEN]; +static HWID ValuesTextbox[MAX_LOOK_UP_TABLE_LEN]; static LONG_PTR PrevValuesProc[MAX_LOOK_UP_TABLE_LEN]; -//static HWND ValuesLabel[MAX_LOOK_UP_TABLE_LEN]; +static HWID ValuesLabel[MAX_LOOK_UP_TABLE_LEN]; static SWORD ValuesCache[MAX_LOOK_UP_TABLE_LEN]; static LONG_PTR PrevDestProc; static LONG_PTR PrevIndexProc; static LONG_PTR PrevCountProc; +static HWID OkButton; +static HWID CancelButton; + +HWID LutGrid; +HWID LutPackingBox; + +struct ShowLookUpTableDialogBuffer{ + int tmpcount; + bool tmpasString; + char PrevTableAsString[1024] = ""; +} temp; //----------------------------------------------------------------------------- // Don't allow any characters other than 0-9 and minus in the values. //----------------------------------------------------------------------------- -// static LRESULT CALLBACK MyNumberProc(HWND hwnd, UINT msg, WPARAM wParam, -// LPARAM lParam) -// { -// if(msg == WM_CHAR) { -// if(!(isdigit(wParam) || wParam == '\b' || wParam == '-')) { -// return 0; -// } -// } - -// WNDPROC w; -// int i; -// for(i = 0; i < MAX_LOOK_UP_TABLE_LEN; i++) { -// if(hwnd == ValuesTextbox[i]) { -// w = (WNDPROC)PrevValuesProc[i]; -// break; -// } -// } -// if(i == MAX_LOOK_UP_TABLE_LEN) oops(); -// return CallWindowProc(w, hwnd, msg, wParam, lParam); -// } +void LutDialogMyNumberProc (GtkEditable *editable, gchar *NewText, gint length, + gint *position, gpointer data){ + // gtk_widget_set_sensitive (MainWindow, TRUE); + for (int i = 0; i < length; i++){ + if (!(isdigit (NewText[i]) || NewText[i] == '\b' || NewText[i] == '-')){ + g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text"); + return; + } + } +} //----------------------------------------------------------------------------- // Don't allow any characters other than 0-9 in the count. //----------------------------------------------------------------------------- -// static LRESULT CALLBACK MyDigitsProc(HWND hwnd, UINT msg, WPARAM wParam, -// LPARAM lParam) -// { -// if(msg == WM_CHAR) { -// if(!(isdigit(wParam) || wParam == '\b')) { -// return 0; -// } -// } -// return CallWindowProc((WNDPROC)PrevCountProc, hwnd, msg, wParam, lParam); -// } +void LutDialogMyDigitsProc (GtkEditable *editable, gchar *NewText, gint length, + gint *position, gpointer data){ + // gtk_widget_set_sensitive (MainWindow, TRUE); + for (int i = 0; i < length; i++){ + if (!(isdigit (NewText[i]) || NewText[i] == '\b' )){ + g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text"); + return; + } + } +} //----------------------------------------------------------------------------- // Don't allow any characters other than A-Za-z0-9_ in the name. //----------------------------------------------------------------------------- -// static LRESULT CALLBACK MyNameProc(HWND hwnd, UINT msg, WPARAM wParam, -// LPARAM lParam) -// { -// if(msg == WM_CHAR) { -// if(!(isalpha(wParam) || isdigit(wParam) || wParam == '_' || -// wParam == '\b')) -// { -// return 0; -// } -// } -// WNDPROC w; -// if(hwnd == DestTextbox) { -// w = (WNDPROC)PrevDestProc; -// } else if(hwnd == IndexTextbox) { -// w = (WNDPROC)PrevIndexProc; -// } -// return CallWindowProc(w, hwnd, msg, wParam, lParam); -// } +void LutDialogMyNameProc (GtkEditable *editable, gchar *NewText, gint length, + gint *position, gpointer data){ + // gtk_widget_set_sensitive (MainWindow, TRUE); + for (int i = 0; i < length; i++){ + if (!(isalpha (NewText[i]) || NewText[i] == '_' || isdigit (NewText[i]) + || NewText[i] == '\b' )){ + g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text"); + return; + } + } +} //----------------------------------------------------------------------------- // Make the controls that are guaranteed not to move around as the count/ @@ -122,92 +120,87 @@ static LONG_PTR PrevCountProc; // because in that case we should not provide a checkbox to change whether // the table is edited as a string or table. //----------------------------------------------------------------------------- -// static void MakeFixedControls(BOOL forPwl) -// { -// Labels[0] = CreateWindowEx(0, WC_STATIC, _("Destination:"), -// WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, -// 0, 10, 78, 21, LutDialog, NULL, Instance, NULL); -// NiceFont(Labels[0]); - -// DestTextbox = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, "", -// WS_CHILD | ES_AUTOHSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 85, 10, 120, 21, LutDialog, NULL, Instance, NULL); -// FixedFont(DestTextbox); - -// Labels[1] = CreateWindowEx(0, WC_STATIC, _("Index:"), -// WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, -// 10, 40, 68, 21, LutDialog, NULL, Instance, NULL); -// NiceFont(Labels[1]); - -// IndexTextbox = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, "", -// WS_CHILD | ES_AUTOHSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 85, 40, 120, 21, LutDialog, NULL, Instance, NULL); -// FixedFont(IndexTextbox); - -// Labels[2] = CreateWindowEx(0,WC_STATIC, forPwl ? _("Points:") : _("Count:"), -// WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, -// 0, 70, 78, 21, LutDialog, NULL, Instance, NULL); -// NiceFont(Labels[2]); - -// CountTextbox = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, "", -// WS_CHILD | ES_AUTOHSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 85, 70, 120, 21, LutDialog, NULL, Instance, NULL); -// NiceFont(CountTextbox); - -// if(!forPwl) { -// AsStringCheckbox = CreateWindowEx(0, WC_BUTTON, -// _("Edit table of ASCII values like a string"), WS_CHILD | -// WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | BS_AUTOCHECKBOX, -// 10, 100, 300, 21, LutDialog, NULL, Instance, NULL); -// NiceFont(AsStringCheckbox); -// } - -// OkButton = CreateWindowEx(0, WC_BUTTON, _("OK"), -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | BS_DEFPUSHBUTTON, -// 231, 10, 70, 23, LutDialog, NULL, Instance, NULL); -// NiceFont(OkButton); - -// CancelButton = CreateWindowEx(0, WC_BUTTON, _("Cancel"), -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 231, 40, 70, 23, LutDialog, NULL, Instance, NULL); -// NiceFont(CancelButton); - -// PrevDestProc = SetWindowLongPtr(DestTextbox, GWLP_WNDPROC, -// (LONG_PTR)MyNameProc); -// PrevIndexProc = SetWindowLongPtr(IndexTextbox, GWLP_WNDPROC, -// (LONG_PTR)MyNameProc); -// PrevCountProc = SetWindowLongPtr(CountTextbox, GWLP_WNDPROC, -// (LONG_PTR)MyDigitsProc); -// } +static void MakeFixedControls(BOOL forPwl) +{ + // cout << "Inside MakeFixedControls ()" << "\n"; + Labels[0] = gtk_label_new ("Destination"); + Labels[1] = gtk_label_new ("Index:"); + Labels[2] = forPwl ? gtk_label_new ("Points:") : gtk_label_new ("Count:"); + + DestTextbox = gtk_entry_new (); + gtk_entry_set_max_length (GTK_ENTRY (DestTextbox), 0); + IndexTextbox = gtk_entry_new (); + gtk_entry_set_max_length (GTK_ENTRY (IndexTextbox), 0); + CountTextbox = gtk_entry_new (); + gtk_entry_set_max_length (GTK_ENTRY (CountTextbox), 0); + + // cout << "Created Labels, Dest, Index and Count text boxes" << "\n"; + + if(!forPwl) { + AsStringCheckbox = gtk_check_button_new_with_label + ("Edit table of ASCII values like a string"); + // cout << "Created CheckButton" << "\n"; + } + + + OkButton = gtk_button_new_with_label ("OK"); + CancelButton = gtk_button_new_with_label ("Cancel"); + + gtk_grid_attach (GTK_GRID (LutGrid), Labels[0], 0, 2, 1, 1); + gtk_grid_attach (GTK_GRID (LutGrid), DestTextbox, 1, 2, 1, 1); + gtk_grid_attach (GTK_GRID (LutGrid), OkButton, 3, 2, 1, 1); + gtk_grid_attach (GTK_GRID (LutGrid), Labels[1], 0, 4, 1, 1); + gtk_grid_attach (GTK_GRID (LutGrid), IndexTextbox, 1, 4, 1, 1); + gtk_grid_attach (GTK_GRID (LutGrid), CancelButton, 3, 4, 1, 1); + gtk_grid_attach (GTK_GRID (LutGrid), Labels[2], 0, 6, 1, 1); + gtk_grid_attach (GTK_GRID (LutGrid), CountTextbox, 1, 6, 1, 1); + gtk_grid_attach (GTK_GRID (LutGrid), AsStringCheckbox, 0, 8, 1, 1); + + g_signal_connect (G_OBJECT(DestTextbox), "insert-text", + G_CALLBACK(LutDialogMyNameProc), NULL); + g_signal_connect (G_OBJECT(IndexTextbox), "insert-text", + G_CALLBACK(LutDialogMyNameProc), NULL); + g_signal_connect (G_OBJECT(CountTextbox), "insert-text", + G_CALLBACK(LutDialogMyDigitsProc), NULL); +} //----------------------------------------------------------------------------- // Destroy all of the controls so that we can start anew. This is necessary // because if the size of the LUT changes, or if the user switches from // table entry to string entry, we must completely reconfigure the dialog. //----------------------------------------------------------------------------- -// static void DestroyLutControls(void) -// { -// if(WasAsString) { -// // Nothing to do; we constantly update the cache from the user- -// // specified string, because we might as well do that when we -// // calculate the length. -// } else { -// int i; -// for(i = 0; i < WasCount; i++) { -// char buf[20]; -// SendMessage(ValuesTextbox[i], WM_GETTEXT, (WPARAM)16, (LPARAM)buf); -// ValuesCache[i] = atoi(buf); -// } -// } - -// DestroyWindow(StringTextbox); - -// int i; -// for(i = 0; i < MAX_LOOK_UP_TABLE_LEN; i++) { -// DestroyWindow(ValuesTextbox[i]); -// DestroyWindow(ValuesLabel[i]); -// } -// } +static void DestroyLutControls(void) +{ + cout << "Inside DestroyLutControls ()" << "\n"; + if(WasAsString) { + // Nothing to do; we constantly update the cache from the user- + // specified string, because we might as well do that when we + // calculate the length. + } + else { + cout << "In DestroyLut WasCount : " << WasCount << "\n"; + int i; + for(i = 0; i < WasCount; i++) { + char buf[20]; + // SendMessage(ValuesTextbox[i], WM_GETTEXT, (WPARAM)16, (LPARAM)buf); + strcpy (buf, gtk_entry_get_text (GTK_ENTRY (ValuesTextbox[i]))); + ValuesCache[i] = atoi(buf); + } + cout << "Exiting else of WasAsString" << "\n"; + } + if (checkString){ + DestroyWindow(StringTextbox); + cout << "Destroyed StringTextbox" << "\n"; + } + int i; + // *** Changed from MAX_LOOK_UP_TABLE_LEN to count ***** // + for(i = 0; i < temp.tmpcount; i++) { + cout << "Destroy ValueTextbox i = " << i << "\n"; + DestroyWindow(ValuesTextbox[i]); + DestroyWindow(ValuesLabel[i]); + cout << "Called DestroyWindow() for ValuesTextbox and ValuesLabels" << "\n"; + } +} //----------------------------------------------------------------------------- // Make the controls that hold the LUT. The exact configuration of the dialog @@ -215,96 +208,109 @@ static LONG_PTR PrevCountProc; // and for table-type entry, on (b) the number of entries, and on (c) // whether we are editing a PWL table (list of points) or a straight LUT. //----------------------------------------------------------------------------- -// static void MakeLutControls(BOOL asString, int count, BOOL forPwl) -// { -// // Remember these, so that we know from where to cache stuff if we have -// // to destroy these textboxes and make something new later. -// WasAsString = asString; -// WasCount = count; - -// if(forPwl && asString) oops(); - -// if(asString) { -// char str[3*MAX_LOOK_UP_TABLE_LEN+1]; -// int i, j; -// j = 0; -// for(i = 0; i < count; i++) { -// int c = ValuesCache[i]; -// if(c >= 32 && c <= 127 && c != '\\') { -// str[j++] = c; -// } else if(c == '\\') { -// str[j++] = '\\'; -// str[j++] = '\\'; -// } else if(c == '\r') { -// str[j++] = '\\'; -// str[j++] = 'r'; -// } else if(c == '\b') { -// str[j++] = '\\'; -// str[j++] = 'b'; -// } else if(c == '\f') { -// str[j++] = '\\'; -// str[j++] = 'f'; -// } else if(c == '\n') { -// str[j++] = '\\'; -// str[j++] = 'n'; -// } else { -// str[j++] = 'X'; -// } -// } -// str[j++] = '\0'; -// StringTextbox = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, str, -// WS_CHILD | ES_AUTOHSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS | -// WS_VISIBLE, -// 10, 130, 294, 21, LutDialog, NULL, Instance, NULL); -// FixedFont(StringTextbox); -// SendMessage(CountTextbox, EM_SETREADONLY, (WPARAM)TRUE, 0); -// MoveWindow(LutDialog, 100, 30, 320, 185, TRUE); -// } else { -// int i; -// int base; -// if(forPwl) { -// base = 100; -// } else { -// base = 140; -// } -// for(i = 0; i < count; i++) { -// int x, y; - -// if(i < 16) { -// x = 10; -// y = base+30*i; -// } else { -// x = 160; -// y = base+30*(i-16); -// } - -// char buf[20]; -// sprintf(buf, "%d", ValuesCache[i]); -// ValuesTextbox[i] = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, buf, -// WS_CHILD | ES_AUTOHSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS | -// WS_VISIBLE, -// x+30, y, 80, 21, LutDialog, NULL, Instance, NULL); -// NiceFont(ValuesTextbox[i]); - -// if(forPwl) { -// sprintf(buf, "%c%d:", (i & 1) ? 'y' : 'x', i/2); -// } else { -// sprintf(buf, "%2d:", i); -// } -// ValuesLabel[i] = CreateWindowEx(0, WC_STATIC, buf, -// WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, -// x, y+3, 100, 21, LutDialog, NULL, Instance, NULL); -// FixedFont(ValuesLabel[i]); - -// PrevValuesProc[i] = SetWindowLongPtr(ValuesTextbox[i], -// GWLP_WNDPROC, (LONG_PTR)MyNumberProc); -// } -// if(count > 16) count = 16; -// SendMessage(CountTextbox, EM_SETREADONLY, (WPARAM)FALSE, 0); - -// MoveWindow(LutDialog, 100, 30, 320, base + 30 + count*30, TRUE); -// } -// } +static void MakeLutControls(BOOL asString, int count, BOOL forPwl) +{ + // Remember these, so that we know from where to cache stuff if we have + // to destroy these textboxes and make something new later. + WasAsString = asString; + cout << "asString in MakeLutControls : " << asString <<"\n"; + WasCount = count; + cout << "Count in MakeLutControls : " << count << "\n"; + if(forPwl && asString) oops(); + + if(asString) { + char str[3*MAX_LOOK_UP_TABLE_LEN+1]; + cout << "Inside if (asString) in MakeLutControls" << "\n"; + int i, j; + j = 0; + for(i = 0; i < count; i++) { + int c = ValuesCache[i]; + if(c >= 32 && c <= 127 && c != '\\') { + str[j++] = c; + } else if(c == '\\') { + str[j++] = '\\'; + str[j++] = '\\'; + } else if(c == '\r') { + str[j++] = '\\'; + str[j++] = 'r'; + } else if(c == '\b') { + str[j++] = '\\'; + str[j++] = 'b'; + } else if(c == '\f') { + str[j++] = '\\'; + str[j++] = 'f'; + } else if(c == '\n') { + str[j++] = '\\'; + str[j++] = 'n'; + } else { + str[j++] = 'X'; + } + } + str[j++] = '\0'; + StringTextbox = gtk_entry_new (); + gtk_grid_attach (GTK_GRID (LutGrid), StringTextbox, 1, 9, 1, 1); + checkString = TRUE; + gtk_widget_show_all (LutGrid); + gtk_editable_set_editable (GTK_EDITABLE (CountTextbox), FALSE); + // MoveWindow(StringTextbox, 100, 30, 320, 185, TRUE); // Changed LutDialog to StringTextbox + } + else { + int i; + int base; + if(forPwl) { + base = 100; + } + else { + base = 140; + } + for(i = 0; i < count; i++) { + int x, y; + + if(i < 16) { + x = 10; + y = base+30*i; + } + else { + x = 160; + y = base+30*(i-16); + } + + char buf[20]; + sprintf(buf, "%d", ValuesCache[i]); + ValuesTextbox[i] = gtk_entry_new (); + gtk_entry_set_max_length (GTK_ENTRY (ValuesTextbox[i]), 0); + // cout << "Made ValuesTextbox" << "\n"; + + if(forPwl) { + sprintf(buf, "%c%d:", (i & 1) ? 'y' : 'x', i/2); + } + else { + sprintf(buf, "%2d:", i); + } + + ValuesLabel[i] = gtk_label_new (buf); + if (i<10){ + gtk_grid_attach (GTK_GRID (LutGrid), ValuesLabel[i], 0, i+12, 1, 1); + gtk_grid_attach (GTK_GRID (LutGrid), ValuesTextbox[i], 1, i+12, 1, 1); + } + else if ((i>=10) && (i<20)){ + gtk_grid_attach (GTK_GRID (LutGrid), ValuesLabel[i], 2, i+2, 1, 1); + gtk_grid_attach (GTK_GRID (LutGrid), ValuesTextbox[i], 3, i+2, 1, 1); + } + else if ((i>=20) && (i<30)){ + gtk_grid_attach (GTK_GRID (LutGrid), ValuesLabel[i], 4, i-8, 1, 1); + gtk_grid_attach (GTK_GRID (LutGrid), ValuesTextbox[i], 5, i-8, 1, 1); + } + gtk_widget_show_all (LutDialog); + g_signal_connect (G_OBJECT(ValuesTextbox[i]), "insert-text", + G_CALLBACK(LutDialogMyNumberProc), NULL); + } + if(count > 16) count = 16; + gtk_editable_set_editable (GTK_EDITABLE (CountTextbox), TRUE); + + // MoveWindow(LutDialog, 100, 30, 320, base + 30 + count*30, TRUE); + } +} //----------------------------------------------------------------------------- // Decode a string into a look-up table; store the values in ValuesCache[], @@ -312,36 +318,136 @@ static LONG_PTR PrevCountProc; // reflect the new length. Returns FALSE if the new string is too long, else // TRUE. //----------------------------------------------------------------------------- -// BOOL StringToValuesCache(char *str, int *c) -// { -// int count = 0; -// while(*str) { -// if(*str == '\\') { -// str++; -// switch(*str) { -// case 'r': ValuesCache[count++] = '\r'; break; -// case 'n': ValuesCache[count++] = '\n'; break; -// case 'f': ValuesCache[count++] = '\f'; break; -// case 'b': ValuesCache[count++] = '\b'; break; -// default: ValuesCache[count++] = *str; break; -// } -// } else { -// ValuesCache[count++] = *str; -// } -// if(*str) { -// str++; -// } -// if(count >= 32) { -// return FALSE; -// } -// } - -// char buf[10]; -// sprintf(buf, "%d", count); -// SendMessage(CountTextbox, WM_SETTEXT, 0, (LPARAM)(buf)); -// *c = count; -// return TRUE; -// } +BOOL StringToValuesCache(char *str, int *c) +{ + // cout << "Inside StringToValuesCache" << "\n"; + int count = 0; + while(*str) { + if(*str == '\\') { + str++; + switch(*str) { + case 'r': ValuesCache[count++] = '\r'; break; + case 'n': ValuesCache[count++] = '\n'; break; + case 'f': ValuesCache[count++] = '\f'; break; + case 'b': ValuesCache[count++] = '\b'; break; + default: ValuesCache[count++] = *str; break; + } + } else { + ValuesCache[count++] = *str; + } + if(*str) { + str++; + } + if(count >= 32) { + return FALSE; + } + } + + char buf[10]; + sprintf(buf, "%d", count); + gtk_entry_set_text (GTK_ENTRY (CountTextbox), buf); + *c = count; + return TRUE; +} + +void LookUpTableGetData (HWID widget, gpointer data){ + ElemLeaf *l = (ElemLeaf *) data; + ElemLookUpTable *t = &(l->d.lookUpTable); + strcpy (t->dest, gtk_entry_get_text (GTK_ENTRY (DestTextbox))); + // t->index = const_cast <char*> (gtk_entry_get_text (GTK_ENTRY (IndexTextbox))); + strcpy (t->index, gtk_entry_get_text (GTK_ENTRY (IndexTextbox))); + // DestroyLutControls(); + + // The call to DestroyLutControls updated ValuesCache, so just read + // them out of there (whichever mode we were in before). + int i; + for(i = 0; i < temp.tmpcount; i++) { + t->vals[i] = ValuesCache[i]; + } + t->count = temp.tmpcount; + t->editAsString = temp.tmpasString; + gtk_widget_set_sensitive (MainWindow, TRUE); +} + +void LookUpTableCheckMode (void){ + int count = temp.tmpcount; + bool asString = temp.tmpasString; + + // Are we in table mode? In that case watch the (user-editable) count + // field, and use that to determine how many textboxes to show. + char buf[20]; + // buf = const_cast <char*> (gtk_entry_get_text (GTK_ENTRY (CountTextbox))); + strcpy (buf, gtk_entry_get_text (GTK_ENTRY (CountTextbox))); + if(atoi(buf) != count && !asString) { + count = atoi(buf); + if(count < 0 || count > 32) { + count = 0; + gtk_entry_set_text (GTK_ENTRY (CountTextbox), ""); + } + cout << "Count in LookUpTableCheckMode : " << count << "\n"; + DestroyLutControls(); + MakeLutControls(asString, count, FALSE); + } + + // Are we in string mode? In that case watch the string textbox, + // and use that to update the (read-only) count field. + if(asString) { + char scratch[1024]; + // scratch = const_cast <char*> (gtk_entry_get_text + // (GTK_ENTRY (StringTextbox))); + strcpy (scratch, gtk_entry_get_text (GTK_ENTRY (StringTextbox))); + if(strcmp(scratch, temp.PrevTableAsString)!=0) { + if(StringToValuesCache(scratch, &count)) { + strcpy(temp.PrevTableAsString, scratch); + } + else { + // Too long; put back the old one + gtk_entry_set_text (GTK_ENTRY (StringTextbox), + temp.PrevTableAsString); + } + } + } + // Did we just change modes? + BOOL x = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (AsStringCheckbox)); + if((x && !asString) || (!x && asString)) { + cout << "x is " << x << "\n"; + asString = x; + if (x == 1){ + MakeLutControls(asString, count, FALSE); + } + else { + DestroyLutControls(); + } + } + + temp.tmpcount = count; + temp.tmpasString = asString; +} + +// Checks for the required key press +gboolean LookUpTableKeyPress (HWID widget, GdkEventKey* event, gpointer data){ + LookUpTableCheckMode (); + if (event -> keyval == GDK_KEY_Return){ + LookUpTableGetData(NULL, (gpointer) data); + } + else if (event -> keyval == GDK_KEY_Escape){ + DestroyWindow (LutDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); + } + return FALSE; +} + +// Mouse click callback +void LutDialogMouseClick (HWID widget, gpointer data){ + LookUpTableCheckMode (); + LookUpTableGetData(NULL, (gpointer) data); +} + +// Calls DestroyWindow +void LutCallDestroyWindow (HWID widget, gpointer data){ + DestroyWindow (LutDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); +} //----------------------------------------------------------------------------- // Show the look-up table dialog. This one is nasty, mostly because there are @@ -349,132 +455,79 @@ static LONG_PTR PrevCountProc; // I should convert between those two representations on the fly, as the user // edit things, so I do. //----------------------------------------------------------------------------- -// void ShowLookUpTableDialog(ElemLeaf *l) -// { -// ElemLookUpTable *t = &(l->d.lookUpTable); - -// // First copy over all the stuff from the leaf structure; in particular, -// // we need our own local copy of the table entries, because it would be -// // bad to update those in the leaf before the user clicks okay (as he -// // might cancel). -// int count = t->count; -// BOOL asString = t->editAsString; -// memset(ValuesCache, 0, sizeof(ValuesCache)); -// int i; -// for(i = 0; i < count; i++) { -// ValuesCache[i] = t->vals[i]; -// } - -// // Now create the dialog's fixed controls, plus the changing (depending -// // on show style/entry count) controls for the initial configuration. -// LutDialog = CreateWindowClient(0, "LDmicroDialog", -// _("Look-Up Table"), WS_OVERLAPPED | WS_SYSMENU, -// 100, 100, 320, 375, NULL, NULL, Instance, NULL); -// MakeFixedControls(FALSE); -// MakeLutControls(asString, count, FALSE); +void ShowLookUpTableDialog(ElemLeaf *l) +{ + ElemLookUpTable *t = &(l->d.lookUpTable); + GdkEventKey* event; + + // First copy over all the stuff from the leaf structure; in particular, + // we need our own local copy of the table entries, because it would be + // bad to update those in the leaf before the user clicks okay (as he + // might cancel). + + int count = t->count; + cout << "Initially count is " << count << "\n"; + BOOL asString = t->editAsString; + cout << "Initially asString is " << asString << "\n"; + memset(ValuesCache, 0, sizeof(ValuesCache)); + int i; + for(i = 0; i < count; i++) { + ValuesCache[i] = t->vals[i]; + } + + // Now create the dialog's fixed controls, plus the changing (depending + // on show style/entry count) controls for the initial configuration. + + LutGrid = gtk_grid_new(); + // LutGrid[1] = gtk_grid_new(); + // gtk_grid_set_column_spacing (GTK_GRID (LutGrid), 1); + LutPackingBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + + LutDialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(LutDialog), "Look-Up Table"); + gtk_window_set_default_size(GTK_WINDOW(LutDialog), 100, 200); + gtk_window_set_resizable (GTK_WINDOW (LutDialog), FALSE); + gtk_box_pack_start(GTK_BOX(LutPackingBox), LutGrid, TRUE, TRUE, 0); + gtk_container_add(GTK_CONTAINER(LutDialog), LutPackingBox); + gtk_widget_add_events (LutDialog, GDK_KEY_PRESS_MASK); + gtk_widget_add_events (LutDialog, GDK_BUTTON_PRESS_MASK); + MakeFixedControls(FALSE); + MakeLutControls(asString, count, FALSE); -// // Set up the controls to reflect the initial configuration. -// SendMessage(DestTextbox, WM_SETTEXT, 0, (LPARAM)(t->dest)); -// SendMessage(IndexTextbox, WM_SETTEXT, 0, (LPARAM)(t->index)); -// char buf[30]; -// sprintf(buf, "%d", t->count); -// SendMessage(CountTextbox, WM_SETTEXT, 0, (LPARAM)buf); -// if(asString) { -// SendMessage(AsStringCheckbox, BM_SETCHECK, BST_CHECKED, 0); -// } - -// // And show the window -// EnableWindow(MainWindow, FALSE); -// ShowWindow(LutDialog, TRUE); -// SetFocus(DestTextbox); -// SendMessage(DestTextbox, EM_SETSEL, 0, -1); - -// char PrevTableAsString[1024] = ""; - -// MSG msg; -// DWORD ret; -// DialogDone = FALSE; -// DialogCancel = FALSE; -// while((ret = GetMessage(&msg, NULL, 0, 0)) && !DialogDone) { -// if(msg.message == WM_KEYDOWN) { -// if(msg.wParam == VK_RETURN) { -// DialogDone = TRUE; -// break; -// } else if(msg.wParam == VK_ESCAPE) { -// DialogDone = TRUE; -// DialogCancel = TRUE; -// break; -// } -// } - -// if(!IsDialogMessage(LutDialog, &msg)) { -// TranslateMessage(&msg); -// DispatchMessage(&msg); -// } - -// // Are we in table mode? In that case watch the (user-editable) count -// // field, and use that to determine how many textboxes to show. -// char buf[20]; -// SendMessage(CountTextbox, WM_GETTEXT, (WPARAM)16, (LPARAM)buf); -// if(atoi(buf) != count && !asString) { -// count = atoi(buf); -// if(count < 0 || count > 32) { -// count = 0; -// SendMessage(CountTextbox, WM_SETTEXT, 0, (LPARAM)""); -// } -// DestroyLutControls(); -// MakeLutControls(asString, count, FALSE); -// } - -// // Are we in string mode? In that case watch the string textbox, -// // and use that to update the (read-only) count field. -// if(asString) { -// char scratch[1024]; -// SendMessage(StringTextbox, WM_GETTEXT, (WPARAM)sizeof(scratch), -// (LPARAM)scratch); -// if(strcmp(scratch, PrevTableAsString)!=0) { -// if(StringToValuesCache(scratch, &count)) { -// strcpy(PrevTableAsString, scratch); -// } else { -// // Too long; put back the old one -// SendMessage(StringTextbox, WM_SETTEXT, 0, -// (LPARAM)PrevTableAsString); -// } -// } -// } - -// // Did we just change modes? -// BOOL x = SendMessage(AsStringCheckbox, BM_GETCHECK, 0, 0)==BST_CHECKED; -// if((x && !asString) || (!x && asString)) { -// asString = x; -// DestroyLutControls(); -// MakeLutControls(asString, count, FALSE); -// } - -// } - -// if(!DialogCancel) { -// SendMessage(DestTextbox, WM_GETTEXT, (WPARAM)16, (LPARAM)(t->dest)); -// SendMessage(IndexTextbox, WM_GETTEXT, (WPARAM)16, (LPARAM)(t->index)); -// DestroyLutControls(); -// // The call to DestroyLutControls updated ValuesCache, so just read -// // them out of there (whichever mode we were in before). -// int i; -// for(i = 0; i < count; i++) { -// t->vals[i] = ValuesCache[i]; -// } -// t->count = count; -// t->editAsString = asString; -// } - -// EnableWindow(MainWindow, TRUE); -// DestroyWindow(LutDialog); -// } + // Set up the controls to reflect the initial configuration. + gtk_entry_set_text (GTK_ENTRY (DestTextbox), t->dest); + gtk_entry_set_text (GTK_ENTRY (IndexTextbox), t->index); + + char buf[30]; + sprintf(buf, "%d", t->count); + gtk_entry_set_text (GTK_ENTRY (CountTextbox), buf); + if(asString) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (AsStringCheckbox), TRUE); + } + + // And show the window + gtk_widget_set_sensitive (MainWindow, FALSE); + gtk_widget_show_all (LutDialog); + gtk_widget_grab_focus(DestTextbox); + gtk_widget_grab_focus(OkButton); + + temp.tmpcount = count; + cout << "Count in ShowLookUp : " << count << "\n"; + temp.tmpasString = asString; + cout << "asString in ShowLookUp : " << asString << "\n"; + + g_signal_connect (G_OBJECT (LutDialog), "key-press-event", + G_CALLBACK(LookUpTableKeyPress), (gpointer)l); + g_signal_connect (G_OBJECT (OkButton), "clicked", + G_CALLBACK(LutDialogMouseClick), (gpointer)l); + g_signal_connect (G_OBJECT (CancelButton), "clicked", + G_CALLBACK(LutCallDestroyWindow), NULL); +} //----------------------------------------------------------------------------- // Show the piecewise linear table dialog. This one can only be edited in // only a single format, which makes things easier than before. -//----------------------------------------------------------------------------- +// //----------------------------------------------------------------------------- // void ShowPiecewiseLinearDialog(ElemLeaf *l) // { // ElemPiecewiseLinear *t = &(l->d.piecewiseLinear); @@ -492,74 +545,78 @@ static LONG_PTR PrevCountProc; // // Now create the dialog's fixed controls, plus the changing (depending // // on show style/entry count) controls for the initial configuration. -// LutDialog = CreateWindowClient(0, "LDmicroDialog", -// _("Piecewise Linear Table"), WS_OVERLAPPED | WS_SYSMENU, -// 100, 100, 320, 375, NULL, NULL, Instance, NULL); + +// LutDialog = gtk_dialog_new_with_buttons ("Piecewise Linear Table", GTK_WINDOW (MainWindow), +// GTK_DIALOG_MODAL, "Ok", GTK_RESPONSE_ACCEPT, +// "Cancel", GTK_RESPONSE_REJECT, NULL); +// gtk_widget_add_events (LutDialog, GDK_KEY_PRESS_MASK); +// gtk_widget_add_events (LutDialog, GDK_BUTTON_PRESS_MASK); // MakeFixedControls(TRUE); // MakeLutControls(FALSE, count*2, TRUE); // // Set up the controls to reflect the initial configuration. -// SendMessage(DestTextbox, WM_SETTEXT, 0, (LPARAM)(t->dest)); -// SendMessage(IndexTextbox, WM_SETTEXT, 0, (LPARAM)(t->index)); +// gtk_entry_set_text (GTK_ENTRY (DestTextbox), t->dest); +// gtk_entry_set_text (GTK_ENTRY (IndexTextbox), t->index); // char buf[30]; // sprintf(buf, "%d", t->count); -// SendMessage(CountTextbox, WM_SETTEXT, 0, (LPARAM)buf); +// gtk_entry_set_text (GTK_ENTRY (CountTextbox), buf); // // And show the window -// EnableWindow(MainWindow, FALSE); -// ShowWindow(LutDialog, TRUE); -// SetFocus(DestTextbox); -// SendMessage(DestTextbox, EM_SETSEL, 0, -1); - -// MSG msg; -// DWORD ret; -// DialogDone = FALSE; -// DialogCancel = FALSE; -// while((ret = GetMessage(&msg, NULL, 0, 0)) && !DialogDone) { -// if(msg.message == WM_KEYDOWN) { -// if(msg.wParam == VK_RETURN) { -// DialogDone = TRUE; -// break; -// } else if(msg.wParam == VK_ESCAPE) { -// DialogDone = TRUE; -// DialogCancel = TRUE; -// break; -// } -// } - -// if(!IsDialogMessage(LutDialog, &msg)) { -// TranslateMessage(&msg); -// DispatchMessage(&msg); -// } +// gtk_widget_set_sensitive (MainWindow, FALSE); +// gtk_widget_show_all (LutDialog); +// gtk_widget_grab_focus (DestTextbox); +// // SendMessage(DestTextbox, EM_SETSEL, 0, -1); + +// // MSG msg; +// // DWORD ret; +// // DialogDone = FALSE; +// // DialogCancel = FALSE; +// // while((ret = GetMessage(&msg, NULL, 0, 0)) && !DialogDone) { +// // if(msg.message == WM_KEYDOWN) { +// // if(msg.wParam == VK_RETURN) { +// // DialogDone = TRUE; +// // break; +// // } else if(msg.wParam == VK_ESCAPE) { +// // DialogDone = TRUE; +// // DialogCancel = TRUE; +// // break; +// // } +// // } + +// // if(!IsDialogMessage(LutDialog, &msg)) { +// // TranslateMessage(&msg); +// // DispatchMessage(&msg); +// // } // // Watch the (user-editable) count field, and use that to // // determine how many textboxes to show. -// char buf[20]; -// SendMessage(CountTextbox, WM_GETTEXT, (WPARAM)16, (LPARAM)buf); +// char* buf; +// buf = gtk_entry_get_text (GTK_ENTRY (CountTextbox)); +// // SendMessage(CountTextbox, WM_GETTEXT, (WPARAM)16, (LPARAM)buf); // if(atoi(buf) != count) { // count = atoi(buf); // if(count < 0 || count > 10) { // count = 0; -// SendMessage(CountTextbox, WM_SETTEXT, 0, (LPARAM)""); +// gtk_entry_set_text (GTK_ENTRY (CountTextbox), ""); // } // DestroyLutControls(); // MakeLutControls(FALSE, count*2, TRUE); // } // } -// if(!DialogCancel) { -// SendMessage(DestTextbox, WM_GETTEXT, (WPARAM)16, (LPARAM)(t->dest)); -// SendMessage(IndexTextbox, WM_GETTEXT, (WPARAM)16, (LPARAM)(t->index)); -// DestroyLutControls(); -// // The call to DestroyLutControls updated ValuesCache, so just read -// // them out of there. -// int i; -// for(i = 0; i < count*2; i++) { -// t->vals[i] = ValuesCache[i]; -// } -// t->count = count; -// } - -// EnableWindow(MainWindow, TRUE); -// DestroyWindow(LutDialog); +// // if(!DialogCancel) { +// // SendMessage(DestTextbox, WM_GETTEXT, (WPARAM)16, (LPARAM)(t->dest)); +// // SendMessage(IndexTextbox, WM_GETTEXT, (WPARAM)16, (LPARAM)(t->index)); +// // DestroyLutControls(); +// // // The call to DestroyLutControls updated ValuesCache, so just read +// // // them out of there. +// // int i; +// // for(i = 0; i < count*2; i++) { +// // t->vals[i] = ValuesCache[i]; +// // } +// // t->count = count; +// // } + +// // EnableWindow(MainWindow, TRUE); +// // DestroyWindow(LutDialog); // } diff --git a/ldmicro/maincontrols.cpp b/ldmicro/maincontrols.cpp index cd01ea9..0deaf73 100644 --- a/ldmicro/maincontrols.cpp +++ b/ldmicro/maincontrols.cpp @@ -34,7 +34,7 @@ HMENU NewMenu; HMENU OpenMenu; HMENU SaveMenu; -HMENU SaveAsMenu_AS; +HMENU SaveAsMenu; HMENU ExportMenu; HMENU ExitMenu; @@ -110,7 +110,7 @@ int ScrollHeight; BOOL NeedHoriz; // status bar at the bottom of the screen, to display settings -static HMENU StatusBar; +static HMENU StatusBar[3]; // have to get back to the menus to gray/ungray, check/uncheck things static HMENU FileMenu; @@ -131,8 +131,6 @@ static int IoListSelectionPoint; static BOOL IoListOutOfSync; int IoListHeight; int IoListTop; -GtkTreeIter* iter = new GtkTreeIter; -GtkTreeModel **IoListPtr = (GtkTreeModel**)GTK_TREE_MODEL (IoList); // whether the simulation is running in real time static BOOL RealTimeSimulationRunning; @@ -166,65 +164,65 @@ void AddMenuAccelerators (void){ gtk_widget_add_accelerator (PushRungDownMenu, "activate", AccelGroup, GDK_KEY_downarrow, GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (DeleteElementMenu, "activate", AccelGroup, GDK_KEY_Delete, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (DeleteRungMenu, "activate", AccelGroup, GDK_KEY_Delete, GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE); // Creating keyboard shortcuts for Instructions menu gtk_widget_add_accelerator (InsertCommentMenu, "activate", AccelGroup, GDK_KEY_semicolon, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertContactsMenu, "activate", AccelGroup, GDK_KEY_C, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertOsrMenu, "activate", AccelGroup, GDK_KEY_backslash, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertOsfMenu, "activate", AccelGroup, GDK_KEY_slash, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertTonMenu, "activate", AccelGroup, GDK_KEY_O, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertTofMenu, "activate", AccelGroup, GDK_KEY_F, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertRtoMenu, "activate", AccelGroup, GDK_KEY_T, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertCtuMenu, "activate", AccelGroup, GDK_KEY_U, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertCtdMenu, "activate", AccelGroup, GDK_KEY_I, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertCtcMenu, "activate", AccelGroup, GDK_KEY_J, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertEquMenu, "activate", AccelGroup, GDK_KEY_equal, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertGrtMenu, "activate", AccelGroup, GDK_KEY_greater, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertGeqMenu, "activate", AccelGroup, GDK_KEY_Stop, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertLesMenu, "activate", AccelGroup, GDK_KEY_less, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertLeqMenu, "activate", AccelGroup, GDK_KEY_comma, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertCoilMenu, "activate", AccelGroup, GDK_KEY_L, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertResMenu, "activate", AccelGroup, GDK_KEY_E, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertMovMenu, "activate", AccelGroup, GDK_KEY_M, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertAddMenu, "activate", AccelGroup, GDK_KEY_plus, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertSubMenu, "activate", AccelGroup, GDK_KEY_minus, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertMulMenu, "activate", AccelGroup, GDK_KEY_multiply, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertDivMenu, "activate", AccelGroup, GDK_KEY_D, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (InsertReadAdcMenu, "activate", AccelGroup, GDK_KEY_P, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (MakeNormalMenu, "activate", AccelGroup, GDK_KEY_A, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (NegateMenu, "activate", AccelGroup, GDK_KEY_N, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (MakeSetOnlyMenu, "activate", AccelGroup, GDK_KEY_S, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (MakeResetOnlyMenu, "activate", AccelGroup, GDK_KEY_R, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); // Creating keyboard shortcuts for Simulation menu gtk_widget_add_accelerator (SimulationModeMenu, "activate", AccelGroup, GDK_KEY_M, @@ -234,15 +232,15 @@ void AddMenuAccelerators (void){ gtk_widget_add_accelerator (StopSimulationMenu, "activate", AccelGroup, GDK_KEY_H, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator (SingleCycleMenu, "activate", AccelGroup, GDK_KEY_space, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); // Creating keyboard shortcuts for Compile menu gtk_widget_add_accelerator (CompileMenu, "activate", AccelGroup, GDK_KEY_F5, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); // Creating keyboard shortcuts for Help menu gtk_widget_add_accelerator (ManualMenu, "activate", AccelGroup, GDK_KEY_F1, - GDK_RELEASE_MASK, GTK_ACCEL_VISIBLE); + (GdkModifierType)0, GTK_ACCEL_VISIBLE); gtk_window_add_accel_group (GTK_WINDOW (MainWindow), AccelGroup); @@ -298,7 +296,7 @@ HMENU MakeMainWindowMenus(void) NewMenu = gtk_menu_item_new_with_mnemonic("_New"); OpenMenu = gtk_menu_item_new_with_mnemonic("_Open"); SaveMenu = gtk_menu_item_new_with_mnemonic("_Save"); - SaveAsMenu_AS = gtk_menu_item_new_with_mnemonic("_Save As"); + SaveAsMenu = gtk_menu_item_new_with_mnemonic("_Save As"); ExportMenu = gtk_menu_item_new_with_mnemonic("_Export As Text"); ExitMenu = gtk_menu_item_new_with_mnemonic("_Exit"); @@ -306,7 +304,7 @@ HMENU MakeMainWindowMenus(void) gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), NewMenu); // Appending menu items gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), OpenMenu); gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), SaveMenu); - gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), SaveAsMenu_AS); + gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), SaveAsMenu); FileMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), FileMenuSeparator); gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), ExportMenu); @@ -347,12 +345,15 @@ HMENU MakeMainWindowMenus(void) gtk_menu_shell_append (GTK_MENU_SHELL (Settings), MicroControllerMenu); // Appending the microcontroller names to "Microcontroller" item + GSList* mcuList = NULL; for (i = 0; i < NUM_SUPPORTED_MCUS; i++){ - ProcessorMenuItems[i] = gtk_check_menu_item_new_with_label (SupportedMcus[i].mcuName); + ProcessorMenuItems[i] = gtk_radio_menu_item_new_with_label (mcuList, SupportedMcus[i].mcuName); + mcuList = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (ProcessorMenuItems[i])); gtk_menu_shell_append (GTK_MENU_SHELL (ProcessorMenu), ProcessorMenuItems[i]); } - ProcessorMenuItems[NUM_SUPPORTED_MCUS] = gtk_check_menu_item_new_with_label ("(no microcontroller)"); + ProcessorMenuItems[NUM_SUPPORTED_MCUS] = gtk_radio_menu_item_new_with_label (mcuList, "(no microcontroller)"); + mcuList = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (ProcessorMenuItems[NUM_SUPPORTED_MCUS])); gtk_menu_shell_append (GTK_MENU_SHELL (ProcessorMenu), ProcessorMenuItems[NUM_SUPPORTED_MCUS]); gtk_menu_item_set_submenu(GTK_MENU_ITEM(MicroControllerMenu), ProcessorMenu); @@ -526,7 +527,7 @@ void MakeMainWindowControls(void) /// Pane to separate Scrolled Window and other widgets HWID pane = gtk_paned_new (GTK_ORIENTATION_VERTICAL); - IoList = gtk_list_store_new (5, + IoList = (GtkTreeModel*)gtk_list_store_new (5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, @@ -592,22 +593,62 @@ 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); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (ViewScroll), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_ALWAYS); + gtk_widget_set_hexpand(GTK_WIDGET(ViewScroll), TRUE); + gtk_widget_set_vexpand(GTK_WIDGET(ViewScroll), TRUE); + + gtk_container_add (GTK_CONTAINER(ViewScroll), view); /// Appending tree view to pane and pane to grid - gtk_paned_pack2 (GTK_PANED(pane), view, FALSE, FALSE); + gtk_paned_pack2 (GTK_PANED(pane), ViewScroll, FALSE, FALSE); gtk_paned_set_position (GTK_PANED (pane), 400); gtk_grid_attach (GTK_GRID (grid), pane, 0, 0, 1, 1); + + gtk_box_pack_start(GTK_BOX(PackBoxMenu), grid, FALSE, TRUE, 0); + + /// Grid for status bars + HWID StatusGrid = gtk_grid_new(); - /// Creating Status Bar and attaching to grid - StatusBar = gtk_statusbar_new(); - gtk_statusbar_push (GTK_STATUSBAR (StatusBar), - gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar), + /// Creating Status Bar 1 and attaching to grid + StatusBar[0] = gtk_statusbar_new(); + + gtk_statusbar_push (GTK_STATUSBAR (StatusBar[0]), + gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar[0]), "Introduction"), "LDMicro Started"); - /// Appneding Status Bar to box which is then added to Main Window - gtk_box_pack_start(GTK_BOX(PackBoxMenu), grid, FALSE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(PackBoxMenu), StatusBar, FALSE, FALSE, 0); + /// Appneding Status Bar 1 to the status grid + gtk_grid_attach (GTK_GRID (StatusGrid), StatusBar[0], 0, 0, 1, 1); + + /// Creating Status Bar 2 and attaching to grid + StatusBar[1] = gtk_statusbar_new(); + + gtk_statusbar_push (GTK_STATUSBAR (StatusBar[1]), + gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar[1]), + "Introduction"), "LDMicro Started"); + + /// Appneding Status Bar 2 to the status box + gtk_grid_attach (GTK_GRID (StatusGrid), StatusBar[1], 1, 0, 1, 1); + + /// Creating Status Bar 3 and attaching to grid + StatusBar[2] = gtk_statusbar_new(); + + gtk_statusbar_push (GTK_STATUSBAR (StatusBar[2]), + gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar[2]), + "Introduction"), "LDMicro Started"); + + /// Appneding Status Bar 3 to the status box + gtk_grid_attach (GTK_GRID (StatusGrid), StatusBar[2], 2, 0, 1, 1); + + /// Attach status grid to box + gtk_box_pack_start(GTK_BOX(PackBoxMenu), StatusGrid, FALSE, FALSE, 0); + + /// Adding box to Main Window gtk_container_add(GTK_CONTAINER(MainWindow), PackBoxMenu); } @@ -621,14 +662,6 @@ void RefreshScrollbars(void) SCROLLINFO vert, horiz; SetUpScrollbars(&NeedHoriz, &horiz, &vert); - GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(ScrollWindow)); - // g_print("adj = %f\n", gtk_adjustment_get_value(adjustment)); - // g_print("upper = %f\n", gtk_adjustment_get_upper(adjustment) - gtk_widget_get_allocated_height (ScrollWindow)); - // g_print("lower = %f\n", gtk_adjustment_get_lower(adjustment)); - // g_print("inc = %f\n", gtk_adjustment_get_step_increment(adjustment)); - // g_print("w width = %i\n", gtk_widget_get_allocated_width (DrawWindow)); - // g_print("w height = %i\n", gtk_widget_get_allocated_height (ScrollWindow)); - // SetScrollInfo(HorizScrollBar, SB_CTL, &horiz, TRUE); // SetScrollInfo(VertScrollBar, SB_CTL, &vert, TRUE); @@ -867,7 +900,7 @@ void ToggleSimulationMode(void) EnableMenuItem(FileMenu, OpenMenu, MF_GRAYED); EnableMenuItem(FileMenu, SaveMenu, MF_GRAYED); - EnableMenuItem(FileMenu, SaveAsMenu_AS, MF_GRAYED); + EnableMenuItem(FileMenu, SaveAsMenu, MF_GRAYED); EnableMenuItem(FileMenu, NewMenu, MF_GRAYED); EnableMenuItem(FileMenu, ExportMenu, MF_GRAYED); @@ -878,16 +911,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); @@ -895,7 +928,7 @@ void ToggleSimulationMode(void) EnableMenuItem(FileMenu, OpenMenu, MF_ENABLED); EnableMenuItem(FileMenu, SaveMenu, MF_ENABLED); - EnableMenuItem(FileMenu, SaveAsMenu_AS, MF_ENABLED); + EnableMenuItem(FileMenu, SaveAsMenu, MF_ENABLED); EnableMenuItem(FileMenu, NewMenu, MF_ENABLED); EnableMenuItem(FileMenu, ExportMenu, MF_ENABLED); @@ -906,9 +939,9 @@ void ToggleSimulationMode(void) CheckMenuItem(SimulateMenu, SimulationModeMenu, MF_UNCHECKED); - // if(UartFunctionUsed()) { - // DestroyUartSimulationWindow(); - // } + if(UartFunctionUsed()) { + DestroyUartSimulationWindow(); + } } UpdateMainWindowTitleBar(); @@ -922,36 +955,88 @@ void ToggleSimulationMode(void) //----------------------------------------------------------------------------- void RefreshControlsToSettings(void) { - int i; - gtk_tree_model_get_iter_first (GTK_TREE_MODEL(IoList), iter); - gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(view)), - GTK_SELECTION_SINGLE); + GtkTreeIter iter; + BOOL path_not_empty = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(IoList), &iter); + // g_print("path e = %i\n", path_not_empty); + + int * ip; + int i = 0; + + if(!IoListOutOfSync) { IoListSelectionPoint = -1; - for(i = 0; i < Prog.io.count; i++) { - gtk_tree_model_iter_next (GTK_TREE_MODEL(IoList), iter); - if(gtk_tree_selection_get_selected (gtk_tree_view_get_selection(GTK_TREE_VIEW(view)), - IoListPtr, iter)) { - IoListSelectionPoint = i; - break; - } + + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); + gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); + + GtkTreeModel *IoModelPtr; + if(gtk_tree_selection_get_selected (selection, &IoModelPtr, &iter)) + { + GtkTreePath *path = gtk_tree_model_get_path ( IoModelPtr, &iter ) ; + ip = gtk_tree_path_get_indices ( path ) ; + i = ip[0]; + IoListSelectionPoint = i; } } - gtk_list_store_clear (IoList); + + gtk_list_store_clear (GTK_LIST_STORE(IoList)); + + /// Fill IO List + NMHDR h; + h.code = LVN_GETDISPINFO; + h.hlistFrom = IoList; + + gtk_tree_model_get_iter_first (GTK_TREE_MODEL(IoList), &iter); + for(i = 0; i < Prog.io.count; i++) { + gtk_list_store_append (GTK_LIST_STORE(IoList), &iter); + h.item.iItem = i; + h.hlistIter = &iter; + IoListProc(&h); + } + + if(IoListSelectionPoint >= 0) { + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); + gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); + + gtk_tree_selection_unselect_all (selection); + GtkTreePath *path = gtk_tree_path_new_from_indices ( IoListSelectionPoint, -1); + gtk_tree_selection_select_path (selection, path); + + // ListView_EnsureVisible(IoList, IoListSelectionPoint, FALSE); + } + IoListOutOfSync = FALSE; if(Prog.mcu) { - gtk_statusbar_push (GTK_STATUSBAR (StatusBar), - gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar), "MCU Name"), + gtk_statusbar_push (GTK_STATUSBAR (StatusBar[0]), + gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar[0]), "MCU Name"), (gchar*)Prog.mcu->mcuName); - // SendMessage(StatusBar, SB_SETTEXT, 0, (LPARAM)Prog.mcu->mcuName); } else { - // SendMessage(StatusBar, SB_SETTEXT, 0, (LPARAM)_("no MCU selected")); - gtk_statusbar_push (GTK_STATUSBAR (StatusBar), - gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar), "MCU Name"), + gtk_statusbar_push (GTK_STATUSBAR (StatusBar[0]), + gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar[0]), "MCU Name"), "no MCU selected"); } + char buf[256]; + sprintf(buf, _("cycle time %.2f ms"), (double)Prog.cycleTime/1000.0); + + gtk_statusbar_push (GTK_STATUSBAR (StatusBar[1]), + gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar[1]), "Cycle time"), + buf); + + if(Prog.mcu && (Prog.mcu->whichIsa == ISA_ANSIC || + Prog.mcu->whichIsa == ISA_INTERPRETED)) + { + strcpy(buf, ""); + } else { + sprintf(buf, _("processor clock %.4f MHz"), + (double)Prog.mcuClock/1000000.0); + } + gtk_statusbar_push (GTK_STATUSBAR (StatusBar[2]), + gtk_statusbar_get_context_id (GTK_STATUSBAR (StatusBar[2]), "Processor time"), + buf); + + for(i = 0; i < NUM_SUPPORTED_MCUS; i++) { if(&SupportedMcus[i] == Prog.mcu) { CheckMenuItem(ProcessorMenu, ProcessorMenuItems[i], MF_CHECKED); @@ -975,24 +1060,41 @@ void RefreshControlsToSettings(void) //----------------------------------------------------------------------------- void GenerateIoListDontLoseSelection(void) { - int i; - gtk_tree_model_get_iter_first (GTK_TREE_MODEL(IoList), iter); - gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(view)), - GTK_SELECTION_SINGLE); + GtkTreeIter iter; + BOOL path_not_empty = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(IoList), &iter); + // g_print("path e = %i\n", path_not_empty); + + int * i ; IoListSelectionPoint = -1; - for(i = 0; i < Prog.io.count; i++) { - gtk_tree_model_iter_next (GTK_TREE_MODEL (IoList), iter); - if(gtk_tree_selection_get_selected (gtk_tree_view_get_selection(GTK_TREE_VIEW(view)), - IoListPtr, iter)) { - IoListSelectionPoint = i; - break; - } + + // GtkTreeSelection * tsel = gtk_tree_view_get_selection (tv); + // GtkTreeModel * tm ; + GtkTreePath * path ; + GtkTreeModel *IoModelPtr; + + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); + gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); + if(gtk_tree_selection_get_selected (selection, &IoModelPtr, &iter)) + { + path = gtk_tree_model_get_path ( IoModelPtr , &iter ) ; + i = gtk_tree_path_get_indices ( path ) ; + IoListSelectionPoint = i[0]; } - // IoListSelectionPoint = GenerateIoList(IoListSelectionPoint); + // gtk_tree_model_iter_next (GTK_TREE_MODEL(IoList), iter); + // BOOL iter_v = gtk_list_store_iter_is_valid(GTK_LIST_STORE(IoList), iter); + // g_print("iter = %i\n", iter_v); + + + // if ( gtk_tree_selection_get_selected ( tsel , &tm , &iter ) ) + // { + + // return i [ 0 ] ; + // } + + IoListSelectionPoint = GenerateIoList(IoListSelectionPoint); // can't just update the listview index; if I/O has been added then the // new selection point might be out of range till we refill it - IoListOutOfSync = TRUE; RefreshControlsToSettings(); } @@ -1007,8 +1109,8 @@ void MainWindowResized(void) GetClientRect(DrawWindow, &main); RECT status; - GetWindowRect(StatusBar, &status); - int statusHeight = status.bottom - status.top; + // GetWindowRect(StatusBar, &status); + // int statusHeight = status.bottom - status.top; // MoveWindow(StatusBar, 0, main.bottom - statusHeight, main.right, // statusHeight, TRUE); @@ -1022,8 +1124,8 @@ void MainWindowResized(void) // Make sure that we can't drag the top of the I/O list above the // bottom of the menu bar, because it then becomes inaccessible. if(IoListTop < 5) { - IoListHeight = main.bottom - statusHeight - 5; - IoListTop = main.bottom - IoListHeight - statusHeight; + IoListHeight = main.bottom - 5;//- statusHeight - 5; + IoListTop = main.bottom - IoListHeight;// - statusHeight; } // MoveWindow(IoList, 0, IoListTop, main.right, IoListHeight, TRUE); @@ -1041,7 +1143,7 @@ void StartSimulation(void) RealTimeSimulationRunning = TRUE; EnableMenuItem(SimulateMenu, StartSimulationMenu, MF_GRAYED); EnableMenuItem(SimulateMenu, StopSimulationMenu, MF_ENABLED); - // StartSimulationTimer(); + StartSimulationTimer(); UpdateMainWindowTitleBar(); } @@ -1055,7 +1157,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/miscutil.cpp b/ldmicro/miscutil.cpp index 777b721..f0f9aa8 100644 --- a/ldmicro/miscutil.cpp +++ b/ldmicro/miscutil.cpp @@ -40,8 +40,8 @@ static int IhexChecksum; // Try to common a bit of stuff between the dialog boxes, since only one // can be open at any time. -HWND OkButton; -HWND CancelButton; +HWID OkButton; +HWID CancelButton; BOOL DialogDone; BOOL DialogCancel; @@ -53,12 +53,12 @@ HFONT MyFixedFont; //----------------------------------------------------------------------------- void dbp(char *str, ...) { - va_list f; - char buf[1024]; - va_start(f, str); - vsprintf(buf, str, f); - OutputDebugString(buf); - OutputDebugString("\n"); + // va_list f; + // char buf[1024]; + // va_start(f, str); + // vsprintf(buf, str, f); + // OutputDebugString(buf); + // OutputDebugString("\n"); } //----------------------------------------------------------------------------- @@ -102,7 +102,7 @@ void Error(char *str, ...) printf("%s\n", buf); } else { //HWND h = GetForegroundWindow(); - //MessageBox(h, buf, _("LDmicro Error"), MB_OK | MB_ICONERROR); + MessageBox(MainWindow, buf, _("LDmicro Error"), MB_OK | MB_ICONERROR); } } @@ -132,26 +132,26 @@ void CompileSuccessfulMessage(char *str) //----------------------------------------------------------------------------- void CheckHeap(char *file, int line) { - static unsigned int SkippedCalls; - static SDWORD LastCallTime; - SDWORD now = GetTickCount(); - - // It slows us down too much to do the check every time we are called; - // but let's still do the check periodically; let's do it every 70 - // calls or every 20 ms, whichever is sooner. - if(SkippedCalls < 70 && (now - LastCallTime) < 20) { - SkippedCalls++; - return; - } + // static unsigned int SkippedCalls; + // static SDWORD LastCallTime; + // SDWORD now = GetTickCount(); + + // // It slows us down too much to do the check every time we are called; + // // but let's still do the check periodically; let's do it every 70 + // // calls or every 20 ms, whichever is sooner. + // if(SkippedCalls < 70 && (now - LastCallTime) < 20) { + // SkippedCalls++; + // return; + // } - SkippedCalls = 0; - LastCallTime = now; + // SkippedCalls = 0; + // LastCallTime = now; - // if(!HeapValidate(MainHeap, 0, NULL)) { - // dbp("file %s line %d", file, line); - // Error("Noticed memory corruption at file '%s' line %d.", file, line); - // oops(); - // } + // // if(!HeapValidate(MainHeap, 0, NULL)) { + // // dbp("file %s line %d", file, line); + // // Error("Noticed memory corruption at file '%s' line %d.", file, line); + // // oops(); + // // } } //----------------------------------------------------------------------------- @@ -204,10 +204,15 @@ void FinishIhex(FILE *f) //----------------------------------------------------------------------------- // Create a window with a given client area. //----------------------------------------------------------------------------- -HWND CreateWindowClient(DWORD exStyle, char *className, char *windowName, - DWORD style, int x, int y, int width, int height, HWND parent, - HMENU menu, HINSTANCE instance, void *param) +HWID CreateWindowClient(GtkWindowType wType, GdkWindowTypeHint wthint, char *windowName, + int x, int y, int width, int height, HWND parent) { + HWID h = gtk_window_new(wType); + gtk_window_set_title(GTK_WINDOW(h), windowName); + gtk_window_resize (GTK_WINDOW(h), width, height); + gtk_window_move(GTK_WINDOW(h), x, y); + gtk_window_set_type_hint (GTK_WINDOW(h), wthint); + // HWND h = CreateWindowEx(exStyle, className, windowName, style, x, y, // width, height, parent, menu, instance, param); @@ -218,16 +223,16 @@ HWND CreateWindowClient(DWORD exStyle, char *className, char *windowName, // SetWindowPos(h, HWND_TOP, x, y, width, height, 0); - return NULL; + return h; } //----------------------------------------------------------------------------- // Window proc for the dialog boxes. This Ok/Cancel stuff is common to a lot // of places, and there are no other callbacks from the children. //----------------------------------------------------------------------------- -static LRESULT CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wParam, - LPARAM lParam) -{ +// static LRESULT CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wParam, +// LPARAM lParam) +// { // switch (msg) { // case WM_NOTIFY: // break; @@ -253,8 +258,8 @@ static LRESULT CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wParam, // return DefWindowProc(hwnd, msg, wParam, lParam); // } - return 1; -} +// return 1; +// } @@ -263,7 +268,19 @@ static LRESULT CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wParam, //----------------------------------------------------------------------------- void NiceFont(HWID h) { - // gtk_widget_override_font(GTK_WIDGET(h), pango_font_description_from_string("Times New Roman")); + GtkCssProvider *provider = gtk_css_provider_new (); + + char *cssdata = new char[strlen(MyNiceFont->lpszFace) + 26]; + int fontSize = 10; + sprintf(cssdata, "textview { font: %ipx %s; }", fontSize, MyNiceFont->lpszFace); + + gtk_css_provider_load_from_data (provider, cssdata, -1, NULL); + + delete cssdata; + + gtk_style_context_add_provider (gtk_widget_get_style_context(h), + GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_USER); + // SendMessage(h, WM_SETFONT, (WPARAM)MyNiceFont, TRUE); } @@ -271,8 +288,21 @@ void NiceFont(HWID h) // Set the font of a control to a pretty fixed-width font (typ. Lucida // Console). //----------------------------------------------------------------------------- -void FixedFont(HWND h) +void FixedFont(HWID h) { + GtkCssProvider *provider = gtk_css_provider_new (); + + char *cssdata = new char[strlen(MyFixedFont->lpszFace) + 26]; + int fontSize = 10; + sprintf(cssdata, "textview { font: %ipx %s; }", fontSize, MyFixedFont->lpszFace); + + gtk_css_provider_load_from_data (provider, cssdata, -1, NULL); + + delete cssdata; + + gtk_style_context_add_provider (gtk_widget_get_style_context(h), + GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_USER); + // SendMessage(h, WM_SETFONT, (WPARAM)MyFixedFont, TRUE); } @@ -300,15 +330,13 @@ void MakeDialogBoxClass(void) // RegisterClassEx(&wc); - // MyNiceFont = CreateFont(16, 0, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE, - // ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, - // FF_DONTCARE, "Tahoma"); + MyNiceFont = CreateFont(16, 0, 0, FW_REGULAR, FALSE, "Tahoma"); + // if(!MyNiceFont) // MyNiceFont = (HFONT)GetStockObject(SYSTEM_FONT); - // MyFixedFont = CreateFont(14, 0, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE, - // ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, - // FF_DONTCARE, "Lucida Console"); + MyFixedFont = CreateFont(14, 0, 0, FW_REGULAR, FALSE, "Lucida Console"); + // if(!MyFixedFont) // MyFixedFont = (HFONT)GetStockObject(SYSTEM_FONT); } diff --git a/ldmicro/pic16.cpp b/ldmicro/pic16.cpp index a813420..d45eabb 100644 --- a/ldmicro/pic16.cpp +++ b/ldmicro/pic16.cpp @@ -508,7 +508,7 @@ static void CompileFromIntermediate(BOOL topLevel) // Keep track of which 2k section we are using. When it looks like we // are about to run out, fill with nops and move on to the next one. DWORD section = 0; - + for(; IntPc < IntCodeLen; IntPc++) { // Try for a margin of about 400 words, which is a little bit // wasteful but considering that the formatted output commands @@ -518,6 +518,7 @@ static void CompileFromIntermediate(BOOL topLevel) if(topLevel && (((PicProgWriteP + 400) >> 11) != section) && ((PicProgWriteP + 400) < Prog.mcu->flashWords)) { + // Jump to the beginning of the next section Instruction(OP_MOVLW, (PicProgWriteP >> 8) + (1<<3), 0); Instruction(OP_MOVWF, REG_PCLATH, 0); @@ -532,7 +533,7 @@ static void CompileFromIntermediate(BOOL topLevel) } IntOp *a = &IntCode[IntPc]; switch(a->op) { - case INT_SET_BIT: + case INT_SET_BIT: MemForSingleBit(a->name1, FALSE, &addr, &bit); SetBit(addr, bit); break; @@ -579,7 +580,7 @@ static void CompileFromIntermediate(BOOL topLevel) CompileIfBody(condFalse); break; } - case INT_IF_VARIABLE_LES_LITERAL: { + case INT_IF_VARIABLE_LES_LITERAL: { DWORD notTrue = AllocFwdAddr(); DWORD isTrue = AllocFwdAddr(); DWORD lsbDecides = AllocFwdAddr(); @@ -693,7 +694,7 @@ static void CompileFromIntermediate(BOOL topLevel) CompileIfBody(notTrue); break; } - case INT_SET_VARIABLE_TO_VARIABLE: + case INT_SET_VARIABLE_TO_VARIABLE: MemForVariable(a->name1, &addrl, &addrh); MemForVariable(a->name2, &addrl2, &addrh2); @@ -708,7 +709,7 @@ static void CompileFromIntermediate(BOOL topLevel) // results if the destination and one of the operands happen to // be the same registers (e.g. for B = A - B). - case INT_SET_VARIABLE_ADD: + case INT_SET_VARIABLE_ADD: MemForVariable(a->name1, &addrl, &addrh); MemForVariable(a->name2, &addrl2, &addrh2); MemForVariable(a->name3, &addrl3, &addrh3); @@ -746,7 +747,7 @@ static void CompileFromIntermediate(BOOL topLevel) Instruction(OP_DECF, addrh, DEST_F); break; - case INT_SET_VARIABLE_MULTIPLY: + case INT_SET_VARIABLE_MULTIPLY: MultiplyNeeded = TRUE; MemForVariable(a->name1, &addrl, &addrh); @@ -823,7 +824,7 @@ static void CompileFromIntermediate(BOOL topLevel) break; } - case INT_UART_RECV: { + case INT_UART_RECV: { MemForVariable(a->name1, &addrl, &addrh); MemForSingleBit(a->name2, TRUE, &addr, &bit); @@ -1171,7 +1172,7 @@ static void CompileFromIntermediate(BOOL topLevel) oops(); break; } - if(((PicProgWriteP >> 11) != section) && topLevel) { + if(((PicProgWriteP >> 11) != section) && topLevel) { // This is particularly prone to happening in the last section, // if the program doesn't fit (since we won't have attempted // to add padding). @@ -1415,6 +1416,7 @@ void CompilePic16(char *outFile) WipeMemory(); AllocStart(); + Scratch0 = AllocOctetRam(); Scratch1 = AllocOctetRam(); Scratch2 = AllocOctetRam(); @@ -1423,7 +1425,7 @@ void CompilePic16(char *outFile) Scratch5 = AllocOctetRam(); Scratch6 = AllocOctetRam(); Scratch7 = AllocOctetRam(); - + // Allocate the register used to hold the high byte of the EEPROM word // that's queued up to program, plus the bit to indicate that it is // valid. @@ -1435,6 +1437,7 @@ void CompilePic16(char *outFile) // bootloaders rewrite the beginning of the program to do their magic. // PCLATH is init to 0, but apparently some bootloaders want to see us // initialize it again. + Instruction(OP_BCF, REG_PCLATH, 3); Instruction(OP_BCF, REG_PCLATH, 4); Instruction(OP_GOTO, progStart, 0); @@ -1576,7 +1579,7 @@ void CompilePic16(char *outFile) ComplainAboutBaudRateError(divisor, actual, percentErr); } if(divisor > 255) ComplainAboutBaudRateOverflow(); - + WriteRegister(REG_SPBRG, divisor); WriteRegister(REG_TXSTA, 0x20); // only TXEN set WriteRegister(REG_RCSTA, 0x90); // only SPEN, CREN set diff --git a/ldmicro/resetdialog.cpp b/ldmicro/resetdialog.cpp index 70a5218..cbcfd30 100644 --- a/ldmicro/resetdialog.cpp +++ b/ldmicro/resetdialog.cpp @@ -24,125 +24,135 @@ #include "linuxUI.h" #include <stdio.h> //#include <commctrl.h> - +#include <iostream> #include "ldmicro.h" -static HWND ResetDialog; +using namespace std; + +static HWID ResetDialog; -static HWND TypeTimerRadio; -static HWND TypeCounterRadio; -static HWND NameTextbox; +static HWID TypeTimerRadio; +static HWID TypeCounterRadio; +static HWID NameTextbox; +static HWID OkButton; +static HWID CancelButton; static LONG_PTR PrevNameProc; +HWID ResetGrid; +HWID ResetPackingBox; //----------------------------------------------------------------------------- // Don't allow any characters other than A-Za-z0-9_ in the name. //----------------------------------------------------------------------------- -// static LRESULT CALLBACK MyNameProc(HWND hwnd, UINT msg, WPARAM wParam, -// LPARAM lParam) -// { -// if(msg == WM_CHAR) { -// if(!(isalpha(wParam) || isdigit(wParam) || wParam == '_' || -// wParam == '\b')) -// { -// return 0; -// } -// } - -// return CallWindowProc((WNDPROC)PrevNameProc, hwnd, msg, wParam, lParam); -// } - -// static void MakeControls(void) -// { -// HWND grouper = CreateWindowEx(0, WC_BUTTON, _("Type"), -// WS_CHILD | BS_GROUPBOX | WS_VISIBLE, -// 7, 3, 120, 65, ResetDialog, NULL, Instance, NULL); -// NiceFont(grouper); - -// TypeTimerRadio = CreateWindowEx(0, WC_BUTTON, _("Timer"), -// WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE, -// 16, 21, 100, 20, ResetDialog, NULL, Instance, NULL); -// NiceFont(TypeTimerRadio); - -// TypeCounterRadio = CreateWindowEx(0, WC_BUTTON, _("Counter"), -// WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE, -// 16, 41, 100, 20, ResetDialog, NULL, Instance, NULL); -// NiceFont(TypeCounterRadio); - -// HWND textLabel = CreateWindowEx(0, WC_STATIC, _("Name:"), -// WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, -// 135, 16, 50, 21, ResetDialog, NULL, Instance, NULL); -// NiceFont(textLabel); - -// NameTextbox = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, "", -// WS_CHILD | ES_AUTOHSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 190, 16, 115, 21, ResetDialog, NULL, Instance, NULL); -// FixedFont(NameTextbox); - -// OkButton = CreateWindowEx(0, WC_BUTTON, _("OK"), -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | BS_DEFPUSHBUTTON, -// 321, 10, 70, 23, ResetDialog, NULL, Instance, NULL); -// NiceFont(OkButton); - -// CancelButton = CreateWindowEx(0, WC_BUTTON, _("Cancel"), -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 321, 40, 70, 23, ResetDialog, NULL, Instance, NULL); -// NiceFont(CancelButton); - -// PrevNameProc = SetWindowLongPtr(NameTextbox, GWLP_WNDPROC, -// (LONG_PTR)MyNameProc); -// } - -// void ShowResetDialog(char *name) -// { -// ResetDialog = CreateWindowClient(0, "LDmicroDialog", -// _("Reset"), WS_OVERLAPPED | WS_SYSMENU, -// 100, 100, 404, 75, NULL, NULL, Instance, NULL); - -// MakeControls(); + +void ResetDialogMyNameProc (GtkEditable *editable, gchar *NewText, gint length, + gint *position, gpointer data){ + // gtk_widget_set_sensitive (MainWindow, TRUE); + for (int i = 0; i < length; i++){ + if (!(isalpha (NewText[i]) || NewText[i] == '_' || isdigit (NewText[i]) + || NewText[i] == '\b' )){ + g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text"); + return; + } + } +} + +static void MakeControls(void) +{ + TypeTimerRadio = gtk_radio_button_new_with_label (NULL, "Timer"); + + TypeCounterRadio = gtk_radio_button_new_with_label_from_widget + (GTK_RADIO_BUTTON (TypeTimerRadio), "Counter"); + + HWID textLabel = gtk_label_new ("Name"); + + NameTextbox = gtk_entry_new(); + gtk_entry_set_max_length (GTK_ENTRY (NameTextbox), 0); + + OkButton = gtk_button_new_with_label ("OK"); + CancelButton = gtk_button_new_with_label ("Cancel"); + + gtk_grid_attach (GTK_GRID (ResetGrid), TypeTimerRadio, 1, 2, 1, 1); + gtk_grid_attach (GTK_GRID (ResetGrid), TypeCounterRadio, 1, 3, 1, 1); + gtk_grid_attach (GTK_GRID (ResetGrid), textLabel, 2, 2, 1, 1); + gtk_grid_attach (GTK_GRID (ResetGrid), NameTextbox, 3, 2, 1, 1); + gtk_grid_attach (GTK_GRID (ResetGrid), OkButton, 4, 2, 1, 1); + gtk_grid_attach (GTK_GRID (ResetGrid), CancelButton, 4, 3, 1, 1); + + gtk_grid_set_column_spacing (GTK_GRID (ResetGrid), 1); + gtk_box_pack_start(GTK_BOX(ResetPackingBox), ResetGrid, TRUE, TRUE, 0); + + // PrevNameProc = SetWindowLongPtr(NameTextbox, GWLP_WNDPROC, + // (LONG_PTR)MyNameProc); +} + +void ResetDialogGetData (char* name){ + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (TypeTimerRadio))){ + name[0] = 'T'; + } + else { + name[0] = 'C'; + } + strcpy (name+1, gtk_entry_get_text (GTK_ENTRY (NameTextbox))); + gtk_widget_set_sensitive (MainWindow, TRUE); + DestroyWindow (ResetDialog); +} + +// Mouse click callback +void ResetDialogMouseClick (HWID widget, gpointer data){ + ResetDialogGetData((char*)data); +} + +// Checks for the required key press +gboolean ResetDialogKeyPress (HWID widget, GdkEventKey* event, gpointer data){ + if (event -> keyval == GDK_KEY_Return){ + ResetDialogGetData((char*)data); + } + else if (event -> keyval == GDK_KEY_Escape){ + DestroyWindow (ResetDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); + } + return FALSE; +} + +void ResetCallDestroyWindow (HWID widget, gpointer data){ + DestroyWindow (ResetDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); +} + +void ShowResetDialog(char *name) +{ + ResetGrid = gtk_grid_new(); + ResetPackingBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + + ResetDialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(ResetDialog), "Reset"); + gtk_window_set_default_size(GTK_WINDOW(ResetDialog), 100, 50); + gtk_window_set_resizable (GTK_WINDOW (ResetDialog), FALSE); + gtk_container_add(GTK_CONTAINER(ResetDialog), ResetPackingBox); + gtk_widget_add_events (ResetDialog, GDK_KEY_PRESS_MASK); + gtk_widget_add_events (ResetDialog, GDK_BUTTON_PRESS_MASK); + + MakeControls(); -// if(name[0] == 'T') { -// SendMessage(TypeTimerRadio, BM_SETCHECK, BST_CHECKED, 0); -// } else { -// SendMessage(TypeCounterRadio, BM_SETCHECK, BST_CHECKED, 0); -// } -// SendMessage(NameTextbox, WM_SETTEXT, 0, (LPARAM)(name + 1)); - -// EnableWindow(MainWindow, FALSE); -// ShowWindow(ResetDialog, TRUE); -// SetFocus(NameTextbox); -// SendMessage(NameTextbox, EM_SETSEL, 0, -1); - -// MSG msg; -// DWORD ret; -// DialogDone = FALSE; -// DialogCancel = FALSE; -// while((ret = GetMessage(&msg, NULL, 0, 0)) && !DialogDone) { -// if(msg.message == WM_KEYDOWN) { -// if(msg.wParam == VK_RETURN) { -// DialogDone = TRUE; -// break; -// } else if(msg.wParam == VK_ESCAPE) { -// DialogDone = TRUE; -// DialogCancel = TRUE; -// break; -// } -// } - -// if(IsDialogMessage(ResetDialog, &msg)) continue; -// TranslateMessage(&msg); -// DispatchMessage(&msg); -// } - -// if(!DialogCancel) { -// if(SendMessage(TypeTimerRadio, BM_GETSTATE, 0, 0) & BST_CHECKED) { -// name[0] = 'T'; -// } else { -// name[0] = 'C'; -// } -// SendMessage(NameTextbox, WM_GETTEXT, (WPARAM)16, (LPARAM)(name+1)); -// } - -// EnableWindow(MainWindow, TRUE); -// DestroyWindow(ResetDialog); -// } + if(name[0] == 'T') { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (TypeTimerRadio), TRUE); + } + else { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (TypeCounterRadio), TRUE); + } + gtk_entry_set_text (GTK_ENTRY (NameTextbox), name+1); + + gtk_widget_set_sensitive (MainWindow, FALSE); + gtk_widget_show_all (ResetDialog); + gtk_widget_grab_focus (NameTextbox); + + g_signal_connect (G_OBJECT(NameTextbox), "insert-text", + G_CALLBACK(ResetDialogMyNameProc), NULL); + g_signal_connect (G_OBJECT (ResetDialog), "key-press-event", + G_CALLBACK(ResetDialogKeyPress), (gpointer)name); + g_signal_connect (G_OBJECT (OkButton), "clicked", + G_CALLBACK(ResetDialogMouseClick), (gpointer)name); + g_signal_connect (G_OBJECT (CancelButton), "clicked", + G_CALLBACK(ResetCallDestroyWindow), NULL); +} diff --git a/ldmicro/schematic.cpp b/ldmicro/schematic.cpp index 5a91934..a53c9c2 100644 --- a/ldmicro/schematic.cpp +++ b/ldmicro/schematic.cpp @@ -24,9 +24,12 @@ #include "linuxUI.h" #include <stdio.h> #include <stdlib.h> +#include <iostream> #include "ldmicro.h" +using namespace std; + // Not all options all available e.g. can't delete the only relay coil in // a rung, can't insert two coils in series, etc. Keep track of what is // allowed so we don't corrupt our program. @@ -395,8 +398,12 @@ void MoveCursorKeyboard(int keyCode) // Edit the selected element. Pop up the appropriate modal dialog box to do // this. //----------------------------------------------------------------------------- + void EditSelectedElement(void) { + ShowLookUpTableDialog(Selected); + // ShowContactsDialog(&(Selected->d.contacts.negated),Selected->d.contacts.name); + // if(!Selected || Selected->selectedState == SELECTED_NONE) return; // switch(SelectedWhich) { @@ -526,6 +533,7 @@ void EditElementMouseDoubleclick(int x, int y) // EditSelectedElement(); // } // } + EditSelectedElement(); } //----------------------------------------------------------------------------- diff --git a/ldmicro/simulate.cpp b/ldmicro/simulate.cpp index ecb9b0e..0b3c206 100644 --- a/ldmicro/simulate.cpp +++ b/ldmicro/simulate.cpp @@ -89,8 +89,8 @@ static int IntPc; // A window to allow simulation with the UART stuff (insert keystrokes into // the program, view the output, like a terminal window). -static HWND UartSimulationWindow; -static HWND UartSimulationTextControl; +static HWID UartSimulationWindow; +static HWID UartSimulationTextControl; static LONG_PTR PrevTextProc; static int QueuedUartCharacter = -1; @@ -106,117 +106,117 @@ static char *MarkUsedVariable(char *name, DWORD flag); // Looks in the SingleBitItems list; if an item is not present then it is // FALSE by default. //----------------------------------------------------------------------------- -// static BOOL SingleBitOn(char *name) -// { -// int i; -// for(i = 0; i < SingleBitItemsCount; i++) { -// if(strcmp(SingleBitItems[i].name, name)==0) { -// return SingleBitItems[i].powered; -// } -// } -// return FALSE; -// } +static BOOL SingleBitOn(char *name) +{ + int i; + for(i = 0; i < SingleBitItemsCount; i++) { + if(strcmp(SingleBitItems[i].name, name)==0) { + return SingleBitItems[i].powered; + } + } + return FALSE; +} //----------------------------------------------------------------------------- // Set the state of a single-bit item. Adds it to the list if it is not there // already. //----------------------------------------------------------------------------- -// static void SetSingleBit(char *name, BOOL state) -// { -// int i; -// for(i = 0; i < SingleBitItemsCount; i++) { -// if(strcmp(SingleBitItems[i].name, name)==0) { -// SingleBitItems[i].powered = state; -// return; -// } -// } -// if(i < MAX_IO) { -// strcpy(SingleBitItems[i].name, name); -// SingleBitItems[i].powered = state; -// SingleBitItemsCount++; -// } -// } +static void SetSingleBit(char *name, BOOL state) +{ + int i; + for(i = 0; i < SingleBitItemsCount; i++) { + if(strcmp(SingleBitItems[i].name, name)==0) { + SingleBitItems[i].powered = state; + return; + } + } + if(i < MAX_IO) { + strcpy(SingleBitItems[i].name, name); + SingleBitItems[i].powered = state; + SingleBitItemsCount++; + } +} //----------------------------------------------------------------------------- // Count a timer up (i.e. increment its associated count by 1). Must already // exist in the table. //----------------------------------------------------------------------------- -// static void IncrementVariable(char *name) -// { -// int i; -// for(i = 0; i < VariablesCount; i++) { -// if(strcmp(Variables[i].name, name)==0) { -// (Variables[i].val)++; -// return; -// } -// } -// oops(); -// } +static void IncrementVariable(char *name) +{ + int i; + for(i = 0; i < VariablesCount; i++) { + if(strcmp(Variables[i].name, name)==0) { + (Variables[i].val)++; + return; + } + } + oops(); +} //----------------------------------------------------------------------------- // Set a variable to a value. //----------------------------------------------------------------------------- -// static void SetSimulationVariable(char *name, SWORD val) -// { -// int i; -// for(i = 0; i < VariablesCount; i++) { -// if(strcmp(Variables[i].name, name)==0) { -// Variables[i].val = val; -// return; -// } -// } -// MarkUsedVariable(name, VAR_FLAG_OTHERWISE_FORGOTTEN); -// SetSimulationVariable(name, val); -// } +static void SetSimulationVariable(char *name, SWORD val) +{ + int i; + for(i = 0; i < VariablesCount; i++) { + if(strcmp(Variables[i].name, name)==0) { + Variables[i].val = val; + return; + } + } + MarkUsedVariable(name, VAR_FLAG_OTHERWISE_FORGOTTEN); + SetSimulationVariable(name, val); +} //----------------------------------------------------------------------------- // Read a variable's value. //----------------------------------------------------------------------------- -// SWORD GetSimulationVariable(char *name) -// { -// int i; -// for(i = 0; i < VariablesCount; i++) { -// if(strcmp(Variables[i].name, name)==0) { -// return Variables[i].val; -// } -// } -// MarkUsedVariable(name, VAR_FLAG_OTHERWISE_FORGOTTEN); -// return GetSimulationVariable(name); -// } +SWORD GetSimulationVariable(char *name) +{ + int i; + for(i = 0; i < VariablesCount; i++) { + if(strcmp(Variables[i].name, name)==0) { + return Variables[i].val; + } + } + MarkUsedVariable(name, VAR_FLAG_OTHERWISE_FORGOTTEN); + return GetSimulationVariable(name); +} //----------------------------------------------------------------------------- // Set the shadow copy of a variable associated with a READ ADC operation. This // will get committed to the real copy when the rung-in condition to the // READ ADC is true. //----------------------------------------------------------------------------- -// void SetAdcShadow(char *name, SWORD val) -// { -// int i; -// for(i = 0; i < AdcShadowsCount; i++) { -// if(strcmp(AdcShadows[i].name, name)==0) { -// AdcShadows[i].val = val; -// return; -// } -// } -// strcpy(AdcShadows[i].name, name); -// AdcShadows[i].val = val; -// AdcShadowsCount++; -// } +void SetAdcShadow(char *name, SWORD val) +{ + int i; + for(i = 0; i < AdcShadowsCount; i++) { + if(strcmp(AdcShadows[i].name, name)==0) { + AdcShadows[i].val = val; + return; + } + } + strcpy(AdcShadows[i].name, name); + AdcShadows[i].val = val; + AdcShadowsCount++; +} //----------------------------------------------------------------------------- // Return the shadow value of a variable associated with a READ ADC. This is // what gets copied into the real variable when an ADC read is simulated. //----------------------------------------------------------------------------- -// SWORD GetAdcShadow(char *name) -// { -// int i; -// for(i = 0; i < AdcShadowsCount; i++) { -// if(strcmp(AdcShadows[i].name, name)==0) { -// return AdcShadows[i].val; -// } -// } -// return 0; -// } +SWORD GetAdcShadow(char *name) +{ + int i; + for(i = 0; i < AdcShadowsCount; i++) { + if(strcmp(AdcShadows[i].name, name)==0) { + return AdcShadows[i].val; + } + } + return 0; +} //----------------------------------------------------------------------------- // Mark how a variable is used; a series of flags that we can OR together, @@ -224,62 +224,62 @@ static char *MarkUsedVariable(char *name, DWORD flag); // (e.g. just a TON, an RTO with its reset, etc.). Returns NULL for success, // else an error string. //----------------------------------------------------------------------------- -// static char *MarkUsedVariable(char *name, DWORD flag) -// { -// int i; -// for(i = 0; i < VariablesCount; i++) { -// if(strcmp(Variables[i].name, name)==0) { -// break; -// } -// } -// if(i >= MAX_IO) return ""; - -// if(i == VariablesCount) { -// strcpy(Variables[i].name, name); -// Variables[i].usedFlags = 0; -// Variables[i].val = 0; -// VariablesCount++; -// } - -// switch(flag) { -// case VAR_FLAG_TOF: -// if(Variables[i].usedFlags != 0) -// return _("TOF: variable cannot be used elsewhere"); -// break; - -// case VAR_FLAG_TON: -// if(Variables[i].usedFlags != 0) -// return _("TON: variable cannot be used elsewhere"); -// break; +static char *MarkUsedVariable(char *name, DWORD flag) +{ + int i; + for(i = 0; i < VariablesCount; i++) { + if(strcmp(Variables[i].name, name)==0) { + break; + } + } + if(i >= MAX_IO) return ""; + + if(i == VariablesCount) { + strcpy(Variables[i].name, name); + Variables[i].usedFlags = 0; + Variables[i].val = 0; + VariablesCount++; + } + + switch(flag) { + case VAR_FLAG_TOF: + if(Variables[i].usedFlags != 0) + return _("TOF: variable cannot be used elsewhere"); + break; + + case VAR_FLAG_TON: + if(Variables[i].usedFlags != 0) + return _("TON: variable cannot be used elsewhere"); + break; -// case VAR_FLAG_RTO: -// if(Variables[i].usedFlags & ~VAR_FLAG_RES) -// return _("RTO: variable can only be used for RES elsewhere"); -// break; - -// case VAR_FLAG_CTU: -// case VAR_FLAG_CTD: -// case VAR_FLAG_CTC: -// case VAR_FLAG_RES: -// case VAR_FLAG_ANY: -// break; - -// case VAR_FLAG_OTHERWISE_FORGOTTEN: -// if(name[0] != '$') { -// Error(_("Variable '%s' not assigned to, e.g. with a " -// "MOV statement, an ADD statement, etc.\r\n\r\n" -// "This is probably a programming error; now it " -// "will always be zero."), name); -// } -// break; - -// default: -// oops(); -// } - -// Variables[i].usedFlags |= flag; -// return NULL; -// } + case VAR_FLAG_RTO: + if(Variables[i].usedFlags & ~VAR_FLAG_RES) + return _("RTO: variable can only be used for RES elsewhere"); + break; + + case VAR_FLAG_CTU: + case VAR_FLAG_CTD: + case VAR_FLAG_CTC: + case VAR_FLAG_RES: + case VAR_FLAG_ANY: + break; + + case VAR_FLAG_OTHERWISE_FORGOTTEN: + if(name[0] != '$') { + Error(_("Variable '%s' not assigned to, e.g. with a " + "MOV statement, an ADD statement, etc.\r\n\r\n" + "This is probably a programming error; now it " + "will always be zero."), name); + } + break; + + default: + oops(); + } + + Variables[i].usedFlags |= flag; + return NULL; +} //----------------------------------------------------------------------------- // Check for duplicate uses of a single variable. For example, there should @@ -287,207 +287,207 @@ static char *MarkUsedVariable(char *name, DWORD flag); // to have an RTO with the same name as its reset; in fact, verify that // there must be a reset for each RTO. //----------------------------------------------------------------------------- -// static void MarkWithCheck(char *name, int flag) -// { -// char *s = MarkUsedVariable(name, flag); -// if(s) { -// Error(_("Variable for '%s' incorrectly assigned: %s."), name, s); -// } -// } - -// static void CheckVariableNamesCircuit(int which, void *elem) -// { -// ElemLeaf *l = (ElemLeaf *)elem; -// char *name = NULL; -// DWORD flag; - -// switch(which) { -// case ELEM_SERIES_SUBCKT: { -// int i; -// ElemSubcktSeries *s = (ElemSubcktSeries *)elem; -// for(i = 0; i < s->count; i++) { -// CheckVariableNamesCircuit(s->contents[i].which, -// s->contents[i].d.any); -// } -// break; -// } - -// case ELEM_PARALLEL_SUBCKT: { -// int i; -// ElemSubcktParallel *p = (ElemSubcktParallel *)elem; -// for(i = 0; i < p->count; i++) { -// CheckVariableNamesCircuit(p->contents[i].which, -// p->contents[i].d.any); -// } -// break; -// } +static void MarkWithCheck(char *name, int flag) +{ + char *s = MarkUsedVariable(name, flag); + if(s) { + Error(_("Variable for '%s' incorrectly assigned: %s."), name, s); + } +} + +static void CheckVariableNamesCircuit(int which, void *elem) +{ + ElemLeaf *l = (ElemLeaf *)elem; + char *name = NULL; + DWORD flag; + + switch(which) { + case ELEM_SERIES_SUBCKT: { + int i; + ElemSubcktSeries *s = (ElemSubcktSeries *)elem; + for(i = 0; i < s->count; i++) { + CheckVariableNamesCircuit(s->contents[i].which, + s->contents[i].d.any); + } + break; + } + + case ELEM_PARALLEL_SUBCKT: { + int i; + ElemSubcktParallel *p = (ElemSubcktParallel *)elem; + for(i = 0; i < p->count; i++) { + CheckVariableNamesCircuit(p->contents[i].which, + p->contents[i].d.any); + } + break; + } -// case ELEM_RTO: -// case ELEM_TOF: -// case ELEM_TON: -// if(which == ELEM_RTO) -// flag = VAR_FLAG_RTO; -// else if(which == ELEM_TOF) -// flag = VAR_FLAG_TOF; -// else if(which == ELEM_TON) -// flag = VAR_FLAG_TON; -// else oops(); - -// MarkWithCheck(l->d.timer.name, flag); - -// break; - -// case ELEM_CTU: -// case ELEM_CTD: -// case ELEM_CTC: -// if(which == ELEM_CTU) -// flag = VAR_FLAG_CTU; -// else if(which == ELEM_CTD) -// flag = VAR_FLAG_CTD; -// else if(which == ELEM_CTC) -// flag = VAR_FLAG_CTC; -// else oops(); - -// MarkWithCheck(l->d.counter.name, flag); - -// break; - -// case ELEM_RES: -// MarkWithCheck(l->d.reset.name, VAR_FLAG_RES); -// break; - -// case ELEM_MOVE: -// MarkWithCheck(l->d.move.dest, VAR_FLAG_ANY); -// break; - -// case ELEM_LOOK_UP_TABLE: -// MarkWithCheck(l->d.lookUpTable.dest, VAR_FLAG_ANY); -// break; - -// case ELEM_PIECEWISE_LINEAR: -// MarkWithCheck(l->d.piecewiseLinear.dest, VAR_FLAG_ANY); -// break; - -// case ELEM_READ_ADC: -// MarkWithCheck(l->d.readAdc.name, VAR_FLAG_ANY); -// break; - -// case ELEM_ADD: -// case ELEM_SUB: -// case ELEM_MUL: -// case ELEM_DIV: -// MarkWithCheck(l->d.math.dest, VAR_FLAG_ANY); -// break; - -// case ELEM_UART_RECV: -// MarkWithCheck(l->d.uart.name, VAR_FLAG_ANY); -// break; - -// case ELEM_SHIFT_REGISTER: { -// int i; -// for(i = 1; i < l->d.shiftRegister.stages; i++) { -// char str[MAX_NAME_LEN+10]; -// sprintf(str, "%s%d", l->d.shiftRegister.name, i); -// MarkWithCheck(str, VAR_FLAG_ANY); -// } -// break; -// } - -// case ELEM_PERSIST: -// case ELEM_FORMATTED_STRING: -// case ELEM_SET_PWM: -// case ELEM_MASTER_RELAY: -// case ELEM_UART_SEND: -// case ELEM_PLACEHOLDER: -// case ELEM_COMMENT: -// case ELEM_OPEN: -// case ELEM_SHORT: -// case ELEM_COIL: -// case ELEM_CONTACTS: -// case ELEM_ONE_SHOT_RISING: -// case ELEM_ONE_SHOT_FALLING: -// case ELEM_EQU: -// case ELEM_NEQ: -// case ELEM_GRT: -// case ELEM_GEQ: -// case ELEM_LES: -// case ELEM_LEQ: -// break; - -// default: -// oops(); -// } -// } - -// static void CheckVariableNames(void) -// { -// int i; -// for(i = 0; i < Prog.numRungs; i++) { -// CheckVariableNamesCircuit(ELEM_SERIES_SUBCKT, Prog.rungs[i]); -// } -// } + case ELEM_RTO: + case ELEM_TOF: + case ELEM_TON: + if(which == ELEM_RTO) + flag = VAR_FLAG_RTO; + else if(which == ELEM_TOF) + flag = VAR_FLAG_TOF; + else if(which == ELEM_TON) + flag = VAR_FLAG_TON; + else oops(); + + MarkWithCheck(l->d.timer.name, flag); + + break; + + case ELEM_CTU: + case ELEM_CTD: + case ELEM_CTC: + if(which == ELEM_CTU) + flag = VAR_FLAG_CTU; + else if(which == ELEM_CTD) + flag = VAR_FLAG_CTD; + else if(which == ELEM_CTC) + flag = VAR_FLAG_CTC; + else oops(); + + MarkWithCheck(l->d.counter.name, flag); + + break; + + case ELEM_RES: + MarkWithCheck(l->d.reset.name, VAR_FLAG_RES); + break; + + case ELEM_MOVE: + MarkWithCheck(l->d.move.dest, VAR_FLAG_ANY); + break; + + case ELEM_LOOK_UP_TABLE: + MarkWithCheck(l->d.lookUpTable.dest, VAR_FLAG_ANY); + break; + + case ELEM_PIECEWISE_LINEAR: + MarkWithCheck(l->d.piecewiseLinear.dest, VAR_FLAG_ANY); + break; + + case ELEM_READ_ADC: + MarkWithCheck(l->d.readAdc.name, VAR_FLAG_ANY); + break; + + case ELEM_ADD: + case ELEM_SUB: + case ELEM_MUL: + case ELEM_DIV: + MarkWithCheck(l->d.math.dest, VAR_FLAG_ANY); + break; + + case ELEM_UART_RECV: + MarkWithCheck(l->d.uart.name, VAR_FLAG_ANY); + break; + + case ELEM_SHIFT_REGISTER: { + int i; + for(i = 1; i < l->d.shiftRegister.stages; i++) { + char str[MAX_NAME_LEN+10]; + sprintf(str, "%s%d", l->d.shiftRegister.name, i); + MarkWithCheck(str, VAR_FLAG_ANY); + } + break; + } + + case ELEM_PERSIST: + case ELEM_FORMATTED_STRING: + case ELEM_SET_PWM: + case ELEM_MASTER_RELAY: + case ELEM_UART_SEND: + case ELEM_PLACEHOLDER: + case ELEM_COMMENT: + case ELEM_OPEN: + case ELEM_SHORT: + case ELEM_COIL: + case ELEM_CONTACTS: + case ELEM_ONE_SHOT_RISING: + case ELEM_ONE_SHOT_FALLING: + case ELEM_EQU: + case ELEM_NEQ: + case ELEM_GRT: + case ELEM_GEQ: + case ELEM_LES: + case ELEM_LEQ: + break; + + default: + oops(); + } +} + +static void CheckVariableNames(void) +{ + int i; + for(i = 0; i < Prog.numRungs; i++) { + CheckVariableNamesCircuit(ELEM_SERIES_SUBCKT, Prog.rungs[i]); + } +} //----------------------------------------------------------------------------- // The IF condition is true. Execute the body, up until the ELSE or the // END IF, and then skip the ELSE if it is present. Called with PC on the // IF, returns with PC on the END IF. //----------------------------------------------------------------------------- -// static void IfConditionTrue(void) -// { -// IntPc++; -// // now PC is on the first statement of the IF body -// SimulateIntCode(); -// // now PC is on the ELSE or the END IF -// if(IntCode[IntPc].op == INT_ELSE) { -// int nesting = 1; -// for(; ; IntPc++) { -// if(IntPc >= IntCodeLen) oops(); - -// if(IntCode[IntPc].op == INT_END_IF) { -// nesting--; -// } else if(INT_IF_GROUP(IntCode[IntPc].op)) { -// nesting++; -// } -// if(nesting == 0) break; -// } -// } else if(IntCode[IntPc].op == INT_END_IF) { -// return; -// } else { -// oops(); -// } -// } +static void IfConditionTrue(void) +{ + IntPc++; + // now PC is on the first statement of the IF body + SimulateIntCode(); + // now PC is on the ELSE or the END IF + if(IntCode[IntPc].op == INT_ELSE) { + int nesting = 1; + for(; ; IntPc++) { + if(IntPc >= IntCodeLen) oops(); + + if(IntCode[IntPc].op == INT_END_IF) { + nesting--; + } else if(INT_IF_GROUP(IntCode[IntPc].op)) { + nesting++; + } + if(nesting == 0) break; + } + } else if(IntCode[IntPc].op == INT_END_IF) { + return; + } else { + oops(); + } +} //----------------------------------------------------------------------------- // The IF condition is false. Skip the body, up until the ELSE or the END // IF, and then execute the ELSE if it is present. Called with PC on the IF, // returns with PC on the END IF. //----------------------------------------------------------------------------- -// static void IfConditionFalse(void) -// { -// int nesting = 0; -// for(; ; IntPc++) { -// if(IntPc >= IntCodeLen) oops(); - -// if(IntCode[IntPc].op == INT_END_IF) { -// nesting--; -// } else if(INT_IF_GROUP(IntCode[IntPc].op)) { -// nesting++; -// } else if(IntCode[IntPc].op == INT_ELSE && nesting == 1) { -// break; -// } -// if(nesting == 0) break; -// } - -// // now PC is on the ELSE or the END IF -// if(IntCode[IntPc].op == INT_ELSE) { -// IntPc++; -// SimulateIntCode(); -// } else if(IntCode[IntPc].op == INT_END_IF) { -// return; -// } else { -// oops(); -// } -// } +static void IfConditionFalse(void) +{ + int nesting = 0; + for(; ; IntPc++) { + if(IntPc >= IntCodeLen) oops(); + + if(IntCode[IntPc].op == INT_END_IF) { + nesting--; + } else if(INT_IF_GROUP(IntCode[IntPc].op)) { + nesting++; + } else if(IntCode[IntPc].op == INT_ELSE && nesting == 1) { + break; + } + if(nesting == 0) break; + } + + // now PC is on the ELSE or the END IF + if(IntCode[IntPc].op == INT_ELSE) { + IntPc++; + SimulateIntCode(); + } else if(IntCode[IntPc].op == INT_END_IF) { + return; + } else { + oops(); + } +} //----------------------------------------------------------------------------- // Evaluate a circuit, calling ourselves recursively to evaluate if/else @@ -495,229 +495,231 @@ static char *MarkUsedVariable(char *name, DWORD flag); // internal tables. Returns when it reaches an end if or an else construct, // or at the end of the program. //----------------------------------------------------------------------------- -// static void SimulateIntCode(void) -// { -// for(; IntPc < IntCodeLen; IntPc++) { -// IntOp *a = &IntCode[IntPc]; -// switch(a->op) { -// case INT_SIMULATE_NODE_STATE: -// if(*(a->poweredAfter) != SingleBitOn(a->name1)) -// NeedRedraw = TRUE; -// *(a->poweredAfter) = SingleBitOn(a->name1); -// break; - -// case INT_SET_BIT: -// SetSingleBit(a->name1, TRUE); -// break; - -// case INT_CLEAR_BIT: -// SetSingleBit(a->name1, FALSE); -// break; - -// case INT_COPY_BIT_TO_BIT: -// SetSingleBit(a->name1, SingleBitOn(a->name2)); -// break; - -// case INT_SET_VARIABLE_TO_LITERAL: -// if(GetSimulationVariable(a->name1) != -// a->literal && a->name1[0] != '$') -// { -// NeedRedraw = TRUE; -// } -// SetSimulationVariable(a->name1, a->literal); -// break; - -// case INT_SET_VARIABLE_TO_VARIABLE: -// if(GetSimulationVariable(a->name1) != -// GetSimulationVariable(a->name2)) -// { -// NeedRedraw = TRUE; -// } -// SetSimulationVariable(a->name1, -// GetSimulationVariable(a->name2)); -// break; - -// case INT_INCREMENT_VARIABLE: -// IncrementVariable(a->name1); -// break; - -// { -// SWORD v; -// case INT_SET_VARIABLE_ADD: -// v = GetSimulationVariable(a->name2) + -// GetSimulationVariable(a->name3); -// goto math; -// case INT_SET_VARIABLE_SUBTRACT: -// v = GetSimulationVariable(a->name2) - -// GetSimulationVariable(a->name3); -// goto math; -// case INT_SET_VARIABLE_MULTIPLY: -// v = GetSimulationVariable(a->name2) * -// GetSimulationVariable(a->name3); -// goto math; -// case INT_SET_VARIABLE_DIVIDE: -// if(GetSimulationVariable(a->name3) != 0) { -// v = GetSimulationVariable(a->name2) / -// GetSimulationVariable(a->name3); -// } else { -// v = 0; -// Error(_("Division by zero; halting simulation")); -// StopSimulation(); -// } -// goto math; -// math: -// if(GetSimulationVariable(a->name1) != v) { -// NeedRedraw = TRUE; -// SetSimulationVariable(a->name1, v); -// } -// break; -// } - -// #define IF_BODY \ -// { \ -// IfConditionTrue(); \ -// } else { \ -// IfConditionFalse(); \ -// } -// case INT_IF_BIT_SET: -// if(SingleBitOn(a->name1)) -// IF_BODY -// break; - -// case INT_IF_BIT_CLEAR: -// if(!SingleBitOn(a->name1)) -// IF_BODY -// break; - -// case INT_IF_VARIABLE_LES_LITERAL: -// if(GetSimulationVariable(a->name1) < a->literal) -// IF_BODY -// break; - -// case INT_IF_VARIABLE_EQUALS_VARIABLE: -// if(GetSimulationVariable(a->name1) == -// GetSimulationVariable(a->name2)) -// IF_BODY -// break; - -// case INT_IF_VARIABLE_GRT_VARIABLE: -// if(GetSimulationVariable(a->name1) > -// GetSimulationVariable(a->name2)) -// IF_BODY -// break; - -// case INT_SET_PWM: -// // Dummy call will cause a warning if no one ever assigned -// // to that variable. -// (void)GetSimulationVariable(a->name1); -// break; - -// // Don't try to simulate the EEPROM stuff: just hold the EEPROM -// // busy all the time, so that the program never does anything -// // with it. -// case INT_EEPROM_BUSY_CHECK: -// SetSingleBit(a->name1, TRUE); -// break; - -// case INT_EEPROM_READ: -// case INT_EEPROM_WRITE: -// oops(); -// break; - -// case INT_READ_ADC: -// // Keep the shadow copies of the ADC variables because in -// // the real device they will not be updated until an actual -// // read is performed, which occurs only for a true rung-in -// // condition there. -// SetSimulationVariable(a->name1, GetAdcShadow(a->name1)); -// break; - -// case INT_UART_SEND: -// if(SingleBitOn(a->name2) && (SimulateUartTxCountdown == 0)) { -// SimulateUartTxCountdown = 2; -// AppendToUartSimulationTextControl( -// (BYTE)GetSimulationVariable(a->name1)); -// } -// if(SimulateUartTxCountdown == 0) { -// SetSingleBit(a->name2, FALSE); -// } else { -// SetSingleBit(a->name2, TRUE); -// } -// break; - -// case INT_UART_RECV: -// if(QueuedUartCharacter >= 0) { -// SetSingleBit(a->name2, TRUE); -// SetSimulationVariable(a->name1, (SWORD)QueuedUartCharacter); -// QueuedUartCharacter = -1; -// } else { -// SetSingleBit(a->name2, FALSE); -// } -// break; - -// case INT_END_IF: -// case INT_ELSE: -// return; - -// case INT_COMMENT: -// break; +static void SimulateIntCode(void) +{ + for(; IntPc < IntCodeLen; IntPc++) { + IntOp *a = &IntCode[IntPc]; + switch(a->op) { + case INT_SIMULATE_NODE_STATE: + if(*(a->poweredAfter) != SingleBitOn(a->name1)) + NeedRedraw = TRUE; + *(a->poweredAfter) = SingleBitOn(a->name1); + break; + + case INT_SET_BIT: + SetSingleBit(a->name1, TRUE); + break; + + case INT_CLEAR_BIT: + SetSingleBit(a->name1, FALSE); + break; + + case INT_COPY_BIT_TO_BIT: + SetSingleBit(a->name1, SingleBitOn(a->name2)); + break; + + case INT_SET_VARIABLE_TO_LITERAL: + if(GetSimulationVariable(a->name1) != + a->literal && a->name1[0] != '$') + { + NeedRedraw = TRUE; + } + SetSimulationVariable(a->name1, a->literal); + break; + + case INT_SET_VARIABLE_TO_VARIABLE: + if(GetSimulationVariable(a->name1) != + GetSimulationVariable(a->name2)) + { + NeedRedraw = TRUE; + } + SetSimulationVariable(a->name1, + GetSimulationVariable(a->name2)); + break; + + case INT_INCREMENT_VARIABLE: + IncrementVariable(a->name1); + break; + + { + SWORD v; + case INT_SET_VARIABLE_ADD: + v = GetSimulationVariable(a->name2) + + GetSimulationVariable(a->name3); + goto math; + case INT_SET_VARIABLE_SUBTRACT: + v = GetSimulationVariable(a->name2) - + GetSimulationVariable(a->name3); + goto math; + case INT_SET_VARIABLE_MULTIPLY: + v = GetSimulationVariable(a->name2) * + GetSimulationVariable(a->name3); + goto math; + case INT_SET_VARIABLE_DIVIDE: + if(GetSimulationVariable(a->name3) != 0) { + v = GetSimulationVariable(a->name2) / + GetSimulationVariable(a->name3); + } else { + v = 0; + Error(_("Division by zero; halting simulation")); + StopSimulation(); + } + goto math; +math: + if(GetSimulationVariable(a->name1) != v) { + NeedRedraw = TRUE; + SetSimulationVariable(a->name1, v); + } + break; + } + +#define IF_BODY \ + { \ + IfConditionTrue(); \ + } else { \ + IfConditionFalse(); \ + } + case INT_IF_BIT_SET: + if(SingleBitOn(a->name1)) + IF_BODY + break; + + case INT_IF_BIT_CLEAR: + if(!SingleBitOn(a->name1)) + IF_BODY + break; + + case INT_IF_VARIABLE_LES_LITERAL: + if(GetSimulationVariable(a->name1) < a->literal) + IF_BODY + break; + + case INT_IF_VARIABLE_EQUALS_VARIABLE: + if(GetSimulationVariable(a->name1) == + GetSimulationVariable(a->name2)) + IF_BODY + break; + + case INT_IF_VARIABLE_GRT_VARIABLE: + if(GetSimulationVariable(a->name1) > + GetSimulationVariable(a->name2)) + IF_BODY + break; + + case INT_SET_PWM: + // Dummy call will cause a warning if no one ever assigned + // to that variable. + (void)GetSimulationVariable(a->name1); + break; + + // Don't try to simulate the EEPROM stuff: just hold the EEPROM + // busy all the time, so that the program never does anything + // with it. + case INT_EEPROM_BUSY_CHECK: + SetSingleBit(a->name1, TRUE); + break; + + case INT_EEPROM_READ: + case INT_EEPROM_WRITE: + oops(); + break; + + case INT_READ_ADC: + // Keep the shadow copies of the ADC variables because in + // the real device they will not be updated until an actual + // read is performed, which occurs only for a true rung-in + // condition there. + SetSimulationVariable(a->name1, GetAdcShadow(a->name1)); + break; + + case INT_UART_SEND: + if(SingleBitOn(a->name2) && (SimulateUartTxCountdown == 0)) { + SimulateUartTxCountdown = 2; + AppendToUartSimulationTextControl( + (BYTE)GetSimulationVariable(a->name1)); + } + if(SimulateUartTxCountdown == 0) { + SetSingleBit(a->name2, FALSE); + } else { + SetSingleBit(a->name2, TRUE); + } + break; + + case INT_UART_RECV: + if(QueuedUartCharacter >= 0) { + SetSingleBit(a->name2, TRUE); + SetSimulationVariable(a->name1, (SWORD)QueuedUartCharacter); + QueuedUartCharacter = -1; + } else { + SetSingleBit(a->name2, FALSE); + } + break; + + case INT_END_IF: + case INT_ELSE: + return; + + case INT_COMMENT: + break; -// default: -// oops(); -// break; -// } -// } -// } + default: + oops(); + break; + } + } +} //----------------------------------------------------------------------------- // 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 // any outputs have changed. If so, force a screen refresh. If requested do // a screen refresh regardless. //----------------------------------------------------------------------------- -// void SimulateOneCycle(BOOL forceRefresh) -// { -// // When there is an error message up, the modal dialog makes its own -// // event loop, and there is risk that we would go recursive. So let -// // us fix that. (Note that there are no concurrency issues; we really -// // would get called recursively, not just reentrantly.) -// static BOOL Simulating = FALSE; +void SimulateOneCycle(BOOL forceRefresh) +{ + // When there is an error message up, the modal dialog makes its own + // event loop, and there is risk that we would go recursive. So let + // us fix that. (Note that there are no concurrency issues; we really + // would get called recursively, not just reentrantly.) + static BOOL Simulating = FALSE; -// if(Simulating) return; -// Simulating = TRUE; + if(Simulating) return; + Simulating = TRUE; -// NeedRedraw = FALSE; + NeedRedraw = FALSE; -// if(SimulateUartTxCountdown > 0) { -// SimulateUartTxCountdown--; -// } else { -// SimulateUartTxCountdown = 0; -// } + if(SimulateUartTxCountdown > 0) { + SimulateUartTxCountdown--; + } else { + SimulateUartTxCountdown = 0; + } -// IntPc = 0; -// SimulateIntCode(); + IntPc = 0; + SimulateIntCode(); -// if(NeedRedraw || SimulateRedrawAfterNextCycle || forceRefresh) { -// InvalidateRect(MainWindow, NULL, FALSE); -// ListView_RedrawItems(IoList, 0, Prog.io.count - 1); -// } + if(NeedRedraw || SimulateRedrawAfterNextCycle || forceRefresh) { + InvalidateRect(DrawWindow, NULL, FALSE); + gtk_widget_queue_draw(DrawWindow); + // ListView_RedrawItems(IoList, 0, Prog.io.count - 1); + } -// SimulateRedrawAfterNextCycle = FALSE; -// if(NeedRedraw) SimulateRedrawAfterNextCycle = TRUE; + SimulateRedrawAfterNextCycle = FALSE; + if(NeedRedraw) SimulateRedrawAfterNextCycle = TRUE; -// Simulating = FALSE; -// } + Simulating = FALSE; +} //----------------------------------------------------------------------------- // Start the timer that we use to trigger PLC cycles in approximately real @@ -725,81 +727,81 @@ static char *MarkUsedVariable(char *name, DWORD flag); // 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. //----------------------------------------------------------------------------- -// void ClearSimulationData(void) -// { -// VariablesCount = 0; -// SingleBitItemsCount = 0; -// AdcShadowsCount = 0; -// QueuedUartCharacter = -1; -// SimulateUartTxCountdown = 0; +void ClearSimulationData(void) +{ + VariablesCount = 0; + SingleBitItemsCount = 0; + AdcShadowsCount = 0; + QueuedUartCharacter = -1; + SimulateUartTxCountdown = 0; -// CheckVariableNames(); + CheckVariableNames(); -// SimulateRedrawAfterNextCycle = TRUE; + SimulateRedrawAfterNextCycle = TRUE; -// if(!GenerateIntermediateCode()) { -// ToggleSimulationMode(); -// return; -// } + if(!GenerateIntermediateCode()) { + ToggleSimulationMode(); + return; + } -// SimulateOneCycle(TRUE); -// } + SimulateOneCycle(TRUE); +} //----------------------------------------------------------------------------- // Provide a description for an item (Xcontacts, Ycoil, Rrelay, Ttimer, // or other) in the I/O list. //----------------------------------------------------------------------------- -// void DescribeForIoList(char *name, char *out) -// { -// switch(name[0]) { -// case 'R': -// case 'X': -// case 'Y': -// sprintf(out, "%d", SingleBitOn(name)); -// break; - -// case 'T': { -// double dtms = GetSimulationVariable(name) * -// (Prog.cycleTime / 1000.0); -// if(dtms < 1000) { -// sprintf(out, "%.2f ms", dtms); -// } else { -// sprintf(out, "%.3f s", dtms / 1000); -// } -// break; -// } -// default: { -// SWORD v = GetSimulationVariable(name); -// sprintf(out, "%hd (0x%04hx)", v, v); -// break; -// } -// } -// } +void DescribeForIoList(char *name, char *out) +{ + switch(name[0]) { + case 'R': + case 'X': + case 'Y': + sprintf(out, "%d", SingleBitOn(name)); + break; + + case 'T': { + double dtms = GetSimulationVariable(name) * + (Prog.cycleTime / 1000.0); + if(dtms < 1000) { + sprintf(out, "%.2f ms", dtms); + } else { + sprintf(out, "%.3f s", dtms / 1000); + } + break; + } + default: { + SWORD v = GetSimulationVariable(name); + sprintf(out, "%hd (0x%04hx)", v, v); + break; + } + } +} //----------------------------------------------------------------------------- // Toggle the state of a contact input; for simulation purposes, so that we // can set the input state of the program. //----------------------------------------------------------------------------- -// void SimulationToggleContact(char *name) -// { -// SetSingleBit(name, !SingleBitOn(name)); -// ListView_RedrawItems(IoList, 0, Prog.io.count - 1); -// } +void SimulationToggleContact(char *name) +{ + SetSingleBit(name, !SingleBitOn(name)); + // ListView_RedrawItems(IoList, 0, Prog.io.count - 1); +} //----------------------------------------------------------------------------- // Dialog proc for the popup that lets you interact with the UART stuff. @@ -835,140 +837,154 @@ static char *MarkUsedVariable(char *name, DWORD flag); //----------------------------------------------------------------------------- // Intercept WM_CHAR messages that to the terminal simulation window so that // we can redirect them to the PLC program. -//----------------------------------------------------------------------------- -// static LRESULT CALLBACK UartSimulationTextProc(HWND hwnd, UINT msg, -// WPARAM wParam, LPARAM lParam) -// { -// if(msg == WM_CHAR) { -// QueuedUartCharacter = (BYTE)wParam; -// return 0; -// } - -// return CallWindowProc((WNDPROC)PrevTextProc, hwnd, msg, wParam, lParam); -// } +// +// Ported: Read and write text fron the text view widget. +//----------------------------------------------------------------------------- +static void UartSimulationTextProc(HWID hwid, UINT umsg, char *text, UINT uszbuf) +{ + switch(umsg) + { + case WM_SETTEXT: + { + GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(hwid)); + gtk_text_buffer_set_text (buffer, text, -1); + gtk_text_view_set_buffer (GTK_TEXT_VIEW(hwid), buffer); + + GtkTextIter end; + gtk_text_buffer_get_end_iter (buffer, &end); + gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW(hwid), &end, 0.2, FALSE, 1, 1); + break; + } + case WM_SETTEXT_END: + { + GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(hwid)); + gtk_text_buffer_insert_at_cursor (buffer, text, -1); + gtk_text_view_set_buffer (GTK_TEXT_VIEW(hwid), buffer); + + GtkTextIter end; + gtk_text_buffer_get_end_iter (buffer, &end); + gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW(hwid), &end, 0.2, FALSE, 1, 1); + break; + } + case WM_GETTEXT: + { + GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(hwid)); + GtkTextIter start, end; + gtk_text_buffer_get_start_iter (buffer, &start); + gtk_text_buffer_get_end_iter (buffer, &end); + + char *txtBuf = gtk_text_buffer_get_text (buffer, &start, &end, FALSE); + + strcpy(text, txtBuf); + strcat(text, "\0"); + g_free(txtBuf); + break; + } + default: + break; + } +} //----------------------------------------------------------------------------- // Pop up the UART simulation window; like a terminal window where the // characters that you type go into UART RECV instruction and whatever // the program puts into UART SEND shows up as text. //----------------------------------------------------------------------------- -// void ShowUartSimulationWindow(void) -// { -// WNDCLASSEX wc; -// memset(&wc, 0, sizeof(wc)); -// wc.cbSize = sizeof(wc); - -// wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_OWNDC | -// CS_DBLCLKS; -// wc.lpfnWndProc = (WNDPROC)UartSimulationProc; -// wc.hInstance = Instance; -// wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW; -// wc.lpszClassName = "LDmicroUartSimulationWindow"; -// wc.lpszMenuName = NULL; -// wc.hCursor = LoadCursor(NULL, IDC_ARROW); - -// RegisterClassEx(&wc); - -// DWORD TerminalX = 200, TerminalY = 200, TerminalW = 300, TerminalH = 150; - -// ThawDWORD(TerminalX); -// ThawDWORD(TerminalY); -// ThawDWORD(TerminalW); -// ThawDWORD(TerminalH); - -// if(TerminalW > 800) TerminalW = 100; -// if(TerminalH > 800) TerminalH = 100; - -// RECT r; -// GetClientRect(GetDesktopWindow(), &r); -// if(TerminalX >= (DWORD)(r.right - 10)) TerminalX = 100; -// if(TerminalY >= (DWORD)(r.bottom - 10)) TerminalY = 100; - -// UartSimulationWindow = CreateWindowClient(WS_EX_TOOLWINDOW | -// WS_EX_APPWINDOW, "LDmicroUartSimulationWindow", -// "UART Simulation (Terminal)", WS_VISIBLE | WS_SIZEBOX, -// TerminalX, TerminalY, TerminalW, TerminalH, -// NULL, NULL, Instance, NULL); - -// UartSimulationTextControl = CreateWindowEx(0, WC_EDIT, "", WS_CHILD | -// WS_CLIPSIBLINGS | WS_VISIBLE | ES_AUTOVSCROLL | ES_MULTILINE | -// WS_VSCROLL, 0, 0, TerminalW, TerminalH, UartSimulationWindow, NULL, -// Instance, NULL); - -// HFONT fixedFont = CreateFont(14, 0, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE, -// ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, -// FF_DONTCARE, "Lucida Console"); -// if(!fixedFont) -// fixedFont = (HFONT)GetStockObject(SYSTEM_FONT); - -// SendMessage((HWND)UartSimulationTextControl, WM_SETFONT, (WPARAM)fixedFont, -// TRUE); - -// PrevTextProc = SetWindowLongPtr(UartSimulationTextControl, -// GWLP_WNDPROC, (LONG_PTR)UartSimulationTextProc); - -// ShowWindow(UartSimulationWindow, TRUE); -// SetFocus(MainWindow); -// } +void ShowUartSimulationWindow(void) +{ + DWORD TerminalX = 200, TerminalY = 200, TerminalW = 300, TerminalH = 150; + + ThawDWORD(TerminalX); + ThawDWORD(TerminalY); + ThawDWORD(TerminalW); + ThawDWORD(TerminalH); + + if(TerminalW > 800) TerminalW = 100; + if(TerminalH > 800) TerminalH = 100; + + UartSimulationWindow = CreateWindowClient(GTK_WINDOW_TOPLEVEL, GDK_WINDOW_TYPE_HINT_NORMAL, + "UART Simulation (Terminal)", TerminalX, TerminalY, TerminalW, TerminalH, NULL); + /// remove close button + gtk_window_set_deletable (GTK_WINDOW(UartSimulationWindow), FALSE); + + UartSimulationTextControl = gtk_text_view_new(); + + gtk_widget_override_font(GTK_WIDGET(UartSimulationTextControl), pango_font_description_from_string("Lucida Console")); + + /// Add text view into a scrolled window to enable scrolling functionality + HWID TextViewScroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (TextViewScroll), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_widget_set_hexpand(GTK_WIDGET(TextViewScroll), TRUE); + gtk_widget_set_vexpand(GTK_WIDGET(TextViewScroll), TRUE); + + gtk_container_add (GTK_CONTAINER(TextViewScroll), UartSimulationTextControl); + gtk_container_add (GTK_CONTAINER(UartSimulationWindow), TextViewScroll); + + gtk_widget_show_all(UartSimulationWindow); + + gtk_window_set_keep_above (GTK_WINDOW(MainWindow), TRUE); + gtk_window_set_focus_visible (GTK_WINDOW(MainWindow), TRUE); + gtk_window_set_keep_above (GTK_WINDOW(MainWindow), FALSE); +} //----------------------------------------------------------------------------- // Get rid of the UART simulation terminal-type window. //----------------------------------------------------------------------------- -// 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. -// if(UartSimulationWindow == NULL) return; +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. + if(UartSimulationWindow == NULL) return; -// DWORD TerminalX, TerminalY, TerminalW, TerminalH; -// RECT r; + DWORD TerminalX, TerminalY, TerminalW, TerminalH; + RECT r; -// GetClientRect(UartSimulationWindow, &r); -// TerminalW = r.right - r.left; -// TerminalH = r.bottom - r.top; + GetClientRect(UartSimulationWindow, &r); + TerminalW = r.right - r.left; + TerminalH = r.bottom - r.top; -// GetWindowRect(UartSimulationWindow, &r); -// TerminalX = r.left; -// TerminalY = r.top; + GetWindowRect(UartSimulationWindow, &r); + TerminalX = r.left; + TerminalY = r.top; -// FreezeDWORD(TerminalX); -// FreezeDWORD(TerminalY); -// FreezeDWORD(TerminalW); -// FreezeDWORD(TerminalH); + FreezeDWORD(TerminalX); + FreezeDWORD(TerminalY); + FreezeDWORD(TerminalW); + FreezeDWORD(TerminalH); -// DestroyWindow(UartSimulationWindow); -// UartSimulationWindow = NULL; -// } + DestroyWindow(UartSimulationWindow); + UartSimulationWindow = NULL; +} //----------------------------------------------------------------------------- // Append a received character to the terminal buffer. //----------------------------------------------------------------------------- -// static void AppendToUartSimulationTextControl(BYTE b) -// { -// char append[5]; - -// if((isalnum(b) || strchr("[]{};':\",.<>/?`~ !@#$%^&*()-=_+|", b) || -// b == '\r' || b == '\n') && b != '\0') -// { -// append[0] = b; -// append[1] = '\0'; -// } else { -// sprintf(append, "\\x%02x", b); -// } +static void AppendToUartSimulationTextControl(BYTE b) +{ + char append[5]; -// #define MAX_SCROLLBACK 256 -// char buf[MAX_SCROLLBACK]; + if((isalnum(b) || strchr("[]{};':\",.<>/?`~ !@#$%^&*()-=_+|", b) || + b == '\r' || b == '\n') && b != '\0') + { + append[0] = b; + append[1] = '\0'; + } else { + sprintf(append, "\\x%02x", b); + } -// SendMessage(UartSimulationTextControl, WM_GETTEXT, (WPARAM)sizeof(buf), -// (LPARAM)buf); +#define MAX_SCROLLBACK 256 + char buf[MAX_SCROLLBACK]; -// int overBy = (strlen(buf) + strlen(append) + 1) - sizeof(buf); -// if(overBy > 0) { -// memmove(buf, buf + overBy, strlen(buf)); -// } -// strcat(buf, append); + UartSimulationTextProc(UartSimulationTextControl, WM_GETTEXT, buf, strlen(buf)); -// SendMessage(UartSimulationTextControl, WM_SETTEXT, 0, (LPARAM)buf); -// SendMessage(UartSimulationTextControl, EM_LINESCROLL, 0, (LPARAM)INT_MAX); -// } + int overBy = (strlen(buf) + strlen(append) + 1) - sizeof(buf); + if(overBy > 0) { + memmove(buf, buf + overBy, strlen(buf)); + } + strcat(buf, append); + + UartSimulationTextProc(UartSimulationTextControl, WM_SETTEXT, buf, strlen(buf)); +} diff --git a/ldmicro/undoredo.cpp b/ldmicro/undoredo.cpp index 2a3c2fd..8bcfcc8 100644 --- a/ldmicro/undoredo.cpp +++ b/ldmicro/undoredo.cpp @@ -201,9 +201,9 @@ void UndoUndo(void) } else { SetUndoEnabled(FALSE, TRUE); } - // RefreshControlsToSettings(); - // RefreshScrollbars(); - // InvalidateRect(MainWindow, NULL, FALSE); + RefreshControlsToSettings(); + RefreshScrollbars(); + InvalidateRect(MainWindow, NULL, FALSE); } //----------------------------------------------------------------------------- @@ -224,9 +224,9 @@ void UndoRedo(void) } else { SetUndoEnabled(TRUE, FALSE); } - //RefreshControlsToSettings(); - //RefreshScrollbars(); - //InvalidateRect(MainWindow, NULL, FALSE); + RefreshControlsToSettings(); + RefreshScrollbars(); + InvalidateRect(MainWindow, NULL, FALSE); } //----------------------------------------------------------------------------- |