diff options
29 files changed, 6353 insertions, 5350 deletions
@@ -1,7 +1,36 @@ +# About LDMicro +LDmicro is a ladder logic editor, simulator and compiler for 8-bit microcontrollers. It can generate native code for Atmel AVR and Microchip PIC16 CPUs from a ladder diagram. + # LDMicro for Linux -This is a linux compatible version of the original LDMicro program. +This is a Linux compatible version of the original LDMicro program for windows created by Jonathan Westhues, and proted to Linux under [FOSSEE](https://github.com/FOSSEE) fellowship program 2018 by [Ramana R](https://github.com/Rr42) and [Rohit I](https://github.com/NatsuDrag9), under the mentorship of [Akshay C](https://github.com/akshay-c). + +GitHub repository of LDMicro for windows can be found [here](https://github.com/akshay-c/LDmicro). + +# Instructions +Before modifying contents of this git account, kindly make sure that you do not add unnecessary files that are created during the make process. In order to do so ensure that you add appropriate command to the makefile and execute "make clean" script before uploading your changes to git. + +# Building LDMicro for Linux +LDmicro for Linux is built using MinGW C++ compiler. + +### Building the Makefile +In order to generate the Makefile that can be used to compile the project, simply run the following commands from a terminal in the project directory: +``` +cd /LDmicro/ +mkdir build +cd build/ +cmake .. +``` -GitHub repository of LDMicro for windows can be found [here](https://github.com/akshay-c/LDmicro) +### Building LDMicro for Linux +Simply run `make` in the build directory of the project to compile. + +_Note_: In order to compile the Makefile must first be generated (see [Building the Makefile](#building-the-makefile)). + +Multiple Perl Scripts are executed during the build phase. In order to execute these scripts, you need perl. This project uses ActivePerl Community Edition, which can be obtained from the following website: + +http://www.activestate.com/activeperl + +or install the perl packages from the terminal (see [External package dependencies](#external-package-dependencies)). ## External package dependencies The install commands for all the packages required to compile LDMicro for Linux are given below: @@ -17,19 +46,9 @@ _Note_: Be sure to run `sudo apt-get update` and `sudo apt-get upgrade` before r ``` * Perl: `sudo apt-get install perl` -## LDMicro for Linux can be compiled and run using the following commands -### To cmpile using cmake use the following commands -``` -cd /LDmicro/ -mkdir build -cd build/ -cmake .. -make -``` -### To run program in linux use the following command - -# To run program in shell mode use the below command +## Running and testing LDMicro for Linux +### To run program in shell mode use the below command `./LDmicro /c <.ld file to compile> <.hex destination file>` -# To run program in GUI mode use the below command +### To run program in GUI mode use the below command `sudo ./LDMicro` 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/circuit.cpp b/ldmicro/circuit.cpp index ad9c791..5f4bad9 100644 --- a/ldmicro/circuit.cpp +++ b/ldmicro/circuit.cpp @@ -24,9 +24,11 @@ #include <linuxUI.h> #include <stdio.h> #include <stdlib.h> +#include <iostream> #include "ldmicro.h" +using namespace std; static ElemSubcktSeries *LoadSeriesFromFile(FILE *f); @@ -638,7 +640,7 @@ void FreeCircuit(int which, void *any) //----------------------------------------------------------------------------- void FreeEntireProgram(void) { - ForgetEverything(); + // ForgetEverything(); int i; for(i = 0; i < Prog.numRungs; i++) { diff --git a/ldmicro/coildialog.cpp b/ldmicro/coildialog.cpp index 22fd10c..1d36f98 100644 --- a/ldmicro/coildialog.cpp +++ b/ldmicro/coildialog.cpp @@ -27,184 +27,197 @@ #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; +static HWID CoilGrid; +static HWID CoilPackingBox; +static bool* tmpnegated; +static bool* tmpsetOnly ; +static bool* tmpresetOnly; + //----------------------------------------------------------------------------- // 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 | 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); -// } - -// 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); - -// MakeControls(); + +void CoilDialogMyNameProc (GtkEditable *editable, gchar *NewText, gint length, + gint *position, gpointer data){ + 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) +{ + 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), NormalRadio, 0, 1, 1, 1); + gtk_grid_attach (GTK_GRID (CoilGrid), NegatedRadio, 0, 2, 1, 1); + gtk_grid_attach (GTK_GRID (CoilGrid), SetOnlyRadio, 0, 3, 1, 1); + gtk_grid_attach (GTK_GRID (CoilGrid), ResetOnlyRadio, 0, 4, 1, 1); + gtk_grid_attach (GTK_GRID (CoilGrid), SourceInternalRelayRadio, 1, 1, 1, 1); + gtk_grid_attach (GTK_GRID (CoilGrid), SourceMcuPinRadio, 1, 2, 1, 1); + gtk_grid_attach (GTK_GRID (CoilGrid), textLabel, 1, 4, 1, 1); + gtk_grid_attach (GTK_GRID (CoilGrid), NameTextbox, 2, 4, 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); + + g_signal_connect (G_OBJECT (NameTextbox), "insert-text", + G_CALLBACK (CoilDialogMyNameProc), NULL); +} + +void CoilDialogGetData (char* name){ + + bool* negated = tmpnegated; + bool* resetOnly = tmpresetOnly; + bool* setOnly = tmpsetOnly; + + if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON + (SourceInternalRelayRadio))) { + name[0] = 'R'; + } + else { + name[0] = 'Y'; + } + strcpy (name+1, gtk_entry_get_text (GTK_ENTRY (NameTextbox))); + + if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON + (NormalRadio))) { + *negated = FALSE; + *setOnly = FALSE; + *resetOnly = FALSE; + } + else if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON + (NegatedRadio))) { + *negated = TRUE; + *setOnly = FALSE; + *resetOnly = FALSE; + } + else if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON + (SetOnlyRadio))) { + *negated = FALSE; + *setOnly = TRUE; + *resetOnly = FALSE; + } + else if(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON + (ResetOnlyRadio))){ + *negated = FALSE; + *setOnly = FALSE; + *resetOnly = TRUE; + } + + gtk_widget_set_sensitive (MainWindow, TRUE); + DestroyWindow (CoilDialog); +} + +// Mouse click callback +void CoilDialogMouseClick (HWID widget, gpointer data){ + CoilDialogGetData((char*)data); +} + +// Checks for the required key press +gboolean CoilDialogKeyPress (HWID widget, GdkEventKey* event, gpointer data){ + if (event -> keyval == GDK_KEY_Return){ + CoilDialogGetData((char*)data); + } + else if (event -> keyval == GDK_KEY_Escape){ + DestroyWindow (CoilDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); + } + return FALSE; +} + +// Calls DestroyWindow +void CoilCallDestroyWindow (HWID widget, gpointer data){ + DestroyWindow (CoilDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); +} + +void ShowCoilDialog(BOOL *negated, BOOL *setOnly, BOOL *resetOnly, char *name) +{ + 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(); -// if(name[0] == 'R') { -// SendMessage(SourceInternalRelayRadio, BM_SETCHECK, BST_CHECKED, 0); -// } else { -// SendMessage(SourceMcuPinRadio, BM_SETCHECK, BST_CHECKED, 0); -// } -// SendMessage(NameTextbox, WM_SETTEXT, 0, (LPARAM)(name + 1)); -// if(*negated) { -// SendMessage(NegatedRadio, BM_SETCHECK, BST_CHECKED, 0); -// } else if(*setOnly) { -// SendMessage(SetOnlyRadio, BM_SETCHECK, BST_CHECKED, 0); -// } else if(*resetOnly) { -// SendMessage(ResetOnlyRadio, BM_SETCHECK, BST_CHECKED, 0); -// } else { -// SendMessage(NormalRadio, BM_SETCHECK, BST_CHECKED, 0); -// } - -// EnableWindow(MainWindow, FALSE); -// ShowWindow(CoilDialog, 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(CoilDialog, &msg)) continue; -// TranslateMessage(&msg); -// DispatchMessage(&msg); -// } - -// if(!DialogCancel) { -// if(SendMessage(SourceInternalRelayRadio, BM_GETSTATE, 0, 0) -// & BST_CHECKED) -// { -// name[0] = 'R'; -// } else { -// name[0] = 'Y'; -// } -// SendMessage(NameTextbox, WM_GETTEXT, (WPARAM)16, (LPARAM)(name+1)); - -// if(SendMessage(NormalRadio, BM_GETSTATE, 0, 0) & BST_CHECKED) { -// *negated = FALSE; -// *setOnly = FALSE; -// *resetOnly = FALSE; -// } else if(SendMessage(NegatedRadio, BM_GETSTATE, 0, 0) & BST_CHECKED) { -// *negated = TRUE; -// *setOnly = FALSE; -// *resetOnly = FALSE; -// } else if(SendMessage(SetOnlyRadio, BM_GETSTATE, 0, 0) & BST_CHECKED) { -// *negated = FALSE; -// *setOnly = TRUE; -// *resetOnly = FALSE; -// } else if(SendMessage(ResetOnlyRadio, BM_GETSTATE, 0, 0) & BST_CHECKED) -// { -// *negated = FALSE; -// *setOnly = FALSE; -// *resetOnly = TRUE; -// } -// } - -// EnableWindow(MainWindow, TRUE); -// DestroyWindow(CoilDialog); -// return; -// } + if(name[0] == 'R') { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (SourceInternalRelayRadio), TRUE); + } + else { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (SourceMcuPinRadio), TRUE); + } + gtk_entry_set_text (GTK_ENTRY (NameTextbox), name+1); + if(*negated) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (NegatedRadio), TRUE); + } + else if(*setOnly) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (SetOnlyRadio), TRUE); + } + else if(*resetOnly) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ResetOnlyRadio), TRUE); + } + else { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (NormalRadio), TRUE); + } + + gtk_widget_set_sensitive (MainWindow, FALSE); + gtk_widget_show_all (CoilDialog); + gtk_widget_grab_focus (NameTextbox); + + tmpnegated = negated; + tmpresetOnly = resetOnly; + tmpsetOnly = setOnly; + + g_signal_connect (G_OBJECT (CoilDialog), "key-press-event", + G_CALLBACK(CoilDialogKeyPress), (gpointer)name); + g_signal_connect (G_OBJECT (OkButton), "clicked", + G_CALLBACK(CoilDialogMouseClick), (gpointer)name); + g_signal_connect (G_OBJECT (CancelButton), "clicked", + G_CALLBACK(CoilCallDestroyWindow), NULL); + + return; +} diff --git a/ldmicro/commentdialog.cpp b/ldmicro/commentdialog.cpp index 9bea08d..e6743b4 100644 --- a/ldmicro/commentdialog.cpp +++ b/ldmicro/commentdialog.cpp @@ -27,71 +27,87 @@ #include "ldmicro.h" -static HWND CommentDialog; - -static HWND CommentTextbox; - -// static void MakeControls(void) -// { -// CommentTextbox = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, "", -// WS_CHILD | ES_AUTOHSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | -// ES_MULTILINE | ES_WANTRETURN, -// 7, 10, 600, 38, CommentDialog, NULL, Instance, NULL); -// FixedFont(CommentTextbox); - -// OkButton = CreateWindowEx(0, WC_BUTTON, _("OK"), -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | BS_DEFPUSHBUTTON, -// 620, 6, 70, 23, CommentDialog, NULL, Instance, NULL); -// NiceFont(OkButton); - -// CancelButton = CreateWindowEx(0, WC_BUTTON, _("Cancel"), -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 620, 36, 70, 23, CommentDialog, NULL, Instance, NULL); -// NiceFont(CancelButton); -// } - -// void ShowCommentDialog(char *comment) -// { -// CommentDialog = CreateWindowClient(0, "LDmicroDialog", -// _("Comment"), WS_OVERLAPPED | WS_SYSMENU, -// 100, 100, 700, 65, NULL, NULL, Instance, NULL); - -// MakeControls(); - -// SendMessage(CommentTextbox, WM_SETTEXT, 0, (LPARAM)comment); - -// EnableWindow(MainWindow, FALSE); -// ShowWindow(CommentDialog, TRUE); -// SetFocus(CommentTextbox); -// SendMessage(CommentTextbox, 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_TAB && GetFocus() == CommentTextbox) { -// SetFocus(OkButton); -// continue; -// } else if(msg.wParam == VK_ESCAPE) { -// DialogDone = TRUE; -// DialogCancel = TRUE; -// break; -// } -// } - -// if(IsDialogMessage(CommentDialog, &msg)) continue; -// TranslateMessage(&msg); -// DispatchMessage(&msg); -// } - -// if(!DialogCancel) { -// SendMessage(CommentTextbox, WM_GETTEXT, (WPARAM)(MAX_COMMENT_LEN-1), -// (LPARAM)comment); -// } - -// EnableWindow(MainWindow, TRUE); -// DestroyWindow(CommentDialog); -// return; -// } +static HWID CommentDialog; + +static HWID CommentTextbox; + +static HWID CommentGrid; +static HWID CommentPackingBox; +static HWID OkButton; +static HWID CancelButton; + +static void MakeControls(void) +{ + CommentTextbox = gtk_entry_new(); + gtk_entry_set_max_length (GTK_ENTRY (CommentTextbox), 0); + gtk_widget_set_hexpand (CommentTextbox, TRUE); + gtk_widget_set_vexpand (CommentTextbox, TRUE); + + OkButton = gtk_button_new_with_label ("OK"); + CancelButton = gtk_button_new_with_label ("Cancel"); + + gtk_grid_attach (GTK_GRID (CommentGrid), CommentTextbox, 1, 2, 1, 1); + gtk_grid_attach (GTK_GRID (CommentGrid), OkButton, 5, 2, 1, 1); + gtk_grid_attach (GTK_GRID (CommentGrid), CancelButton, 5, 3, 1, 1); + + gtk_grid_set_column_spacing (GTK_GRID (CommentGrid), 1); + gtk_box_pack_start(GTK_BOX(CommentPackingBox), CommentGrid, TRUE, TRUE, 0); +} + +void CommentDialogGetData (char* comment){ + strncpy (comment, gtk_entry_get_text (GTK_ENTRY (CommentTextbox)), + MAX_COMMENT_LEN-1); + gtk_widget_set_sensitive (MainWindow, TRUE); + DestroyWindow (CommentDialog); +} + +// Mouse click callback +void CommentDialogMouseClick (HWID widget, gpointer data){ + CommentDialogGetData((char*)data); +} + +// Checks for the required key press +gboolean CommentDialogKeyPress (HWID widget, GdkEventKey* event, gpointer data){ + if (event -> keyval == GDK_KEY_Return){ + CommentDialogGetData((char*)data); + } + else if (event -> keyval == GDK_KEY_Escape){ + DestroyWindow (CommentDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); + } + return FALSE; +} + +void CommentCallDestroyWindow (HWID widget, gpointer data){ + DestroyWindow (CommentDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); +} + +void ShowCommentDialog(char *comment) +{ + CommentGrid = gtk_grid_new(); + CommentPackingBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + + CommentDialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(CommentDialog), "Comment"); + gtk_window_set_default_size(GTK_WINDOW(CommentDialog), 700, 50); + gtk_window_set_resizable (GTK_WINDOW (CommentDialog), FALSE); + gtk_widget_add_events (CommentDialog, GDK_KEY_PRESS_MASK); + gtk_widget_add_events (CommentDialog, GDK_BUTTON_PRESS_MASK); + + MakeControls(); + gtk_entry_set_text (GTK_ENTRY (CommentTextbox), comment); + gtk_container_add(GTK_CONTAINER(CommentDialog), CommentPackingBox); + gtk_widget_set_sensitive (MainWindow, FALSE); + gtk_widget_show_all (CommentDialog); + gtk_widget_grab_focus (CommentTextbox); + + g_signal_connect (G_OBJECT (CommentDialog), "key-press-event", + G_CALLBACK(CommentDialogKeyPress), (gpointer)comment); + g_signal_connect (G_OBJECT (OkButton), "clicked", + G_CALLBACK(CommentDialogMouseClick), (gpointer)comment); + g_signal_connect (G_OBJECT (CancelButton), "clicked", + G_CALLBACK(CommentCallDestroyWindow), NULL); + + return; +} 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 f908893..2fd8dd7 100644 --- a/ldmicro/confdialog.cpp +++ b/ldmicro/confdialog.cpp @@ -25,150 +25,108 @@ #include <linuxUI.h> #include <stdio.h> #include <stdlib.h> +#include <iostream> //#include <commctrl.h> - #include "ldmicro.h" -// static HWND ConfDialog; +using namespace std; + +static HWID ConfDialog; -// static HWND CrystalTextbox; -// static HWND CycleTextbox; -// static HWND BaudTextbox; +static HWID CrystalTextbox; +static HWID CycleTextbox; +static HWID BaudTextbox; +static HWID OkButton; +static HWID CancelButton; static LONG_PTR PrevCrystalProc; static LONG_PTR PrevCycleProc; static LONG_PTR PrevBaudProc; -//----------------------------------------------------------------------------- -// Don't allow any characters other than 0-9. in the text boxes. -//----------------------------------------------------------------------------- -// static LRESULT CALLBACK MyNumberProc(HWND hwnd, UINT msg, WPARAM wParam, -// LPARAM lParam) -// { -// if(msg == WM_CHAR) { -// if(!(isdigit(wParam) || wParam == '.' || wParam == '\b')) { -// return 0; -// } -// } - -// LONG_PTR t; -// if(hwnd == CrystalTextbox) -// t = PrevCrystalProc; -// else if(hwnd == CycleTextbox) -// t = PrevCycleProc; -// else if(hwnd == BaudTextbox) -// t = PrevBaudProc; -// else -// oops(); - -// return CallWindowProc((WNDPROC)t, hwnd, msg, wParam, lParam); -// } +HWID ConfGrid; +HWID ConfPackingBox; static void MakeControls(void) -{ -// HWND textLabel = CreateWindowEx(0, WC_STATIC, _("Cycle Time (ms):"), -// WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, -// 5, 13, 145, 21, ConfDialog, NULL, Instance, NULL); -// NiceFont(textLabel); - -// CycleTextbox = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, "", -// WS_CHILD | ES_AUTOHSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 155, 12, 85, 21, ConfDialog, NULL, Instance, NULL); -// NiceFont(CycleTextbox); - -// HWND textLabel2 = CreateWindowEx(0, WC_STATIC, -// _("Crystal Frequency (MHz):"), -// WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, -// 0, 43, 150, 21, ConfDialog, NULL, Instance, NULL); -// NiceFont(textLabel2); - -// CrystalTextbox = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, "", -// WS_CHILD | ES_AUTOHSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 155, 42, 85, 21, ConfDialog, NULL, Instance, NULL); -// NiceFont(CrystalTextbox); - -// HWND textLabel3 = CreateWindowEx(0, WC_STATIC, _("UART Baud Rate (bps):"), -// WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, -// 5, 73, 145, 21, ConfDialog, NULL, Instance, NULL); -// NiceFont(textLabel3); - -// BaudTextbox = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, "", -// WS_CHILD | ES_AUTOHSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 155, 72, 85, 21, ConfDialog, NULL, Instance, NULL); -// NiceFont(BaudTextbox); - -// if(!UartFunctionUsed()) { -// EnableWindow(BaudTextbox, FALSE); -// EnableWindow(textLabel3, FALSE); -// } - -// if(Prog.mcu && (Prog.mcu->whichIsa == ISA_ANSIC || -// Prog.mcu->whichIsa == ISA_INTERPRETED)) -// { -// EnableWindow(CrystalTextbox, FALSE); -// EnableWindow(textLabel2, FALSE); -// } - -// OkButton = CreateWindowEx(0, WC_BUTTON, _("OK"), -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | BS_DEFPUSHBUTTON, -// 258, 11, 70, 23, ConfDialog, NULL, Instance, NULL); -// NiceFont(OkButton); - -// CancelButton = CreateWindowEx(0, WC_BUTTON, _("Cancel"), -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 258, 41, 70, 23, ConfDialog, NULL, Instance, NULL); -// NiceFont(CancelButton); - -// char explanation[1024] = ""; - -// if(UartFunctionUsed()) { -// if(Prog.mcu && Prog.mcu->uartNeeds.rxPin != 0) { -// sprintf(explanation, -// _("Serial (UART) will use pins %d and %d.\r\n\r\n"), -// Prog.mcu->uartNeeds.rxPin, Prog.mcu->uartNeeds.txPin); -// } else { -// strcpy(explanation, -// _("Please select a micro with a UART.\r\n\r\n")); -// } -// } else { -// strcpy(explanation, _("No serial instructions (UART Send/UART Receive) " -// "are in use; add one to program before setting baud rate.\r\n\r\n") -// ); -// } - -// strcat(explanation, -// _("The cycle time for the 'PLC' runtime generated by LDmicro is user-" -// "configurable. Very short cycle times may not be achievable due " -// "to processor speed constraints, and very long cycle times may not " -// "be achievable due to hardware overflows. Cycle times between 10 ms " -// "and 100 ms will usually be practical.\r\n\r\n" -// "The compiler must know what speed crystal you are using with the " -// "micro to convert between timing in clock cycles and timing in " -// "seconds. A 4 MHz to 20 MHz crystal is typical; check the speed " -// "grade of the part you are using to determine the maximum allowable " -// "clock speed before choosing a crystal.")); - -// HWND textLabel4 = CreateWindowEx(0, WC_STATIC, explanation, -// WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, -// 11, 104, 310, 400, ConfDialog, NULL, Instance, NULL); -// NiceFont(textLabel4); - -// // Measure the explanation string, so that we know how to size our window -// RECT tr, cr; -// HDC hdc = CreateCompatibleDC(NULL); -// SelectObject(hdc, MyNiceFont); -// SetRect(&tr, 0, 0, 310, 400); -// DrawText(hdc, explanation, -1, &tr, DT_CALCRECT | -// DT_LEFT | DT_TOP | DT_WORDBREAK); -// DeleteDC(hdc); -// int h = 104 + tr.bottom + 10; -// SetWindowPos(ConfDialog, NULL, 0, 0, 344, h, SWP_NOMOVE); -// // h is the desired client height, but SetWindowPos includes title bar; -// // so fix it up by hand -// GetClientRect(ConfDialog, &cr); -// int nh = h + (h - (cr.bottom - cr.top)); -// SetWindowPos(ConfDialog, NULL, 0, 0, 344, nh, SWP_NOMOVE); - +{ + // Creating text labels + HWID textLabel = gtk_label_new ("Cycle Time (ms):"); + HWID textLabel2 = gtk_label_new ("Crystal Frequency (MHz):"); + HWID textLabel3 = gtk_label_new ("UART Baud Rate (bps):"); + + // Creating text boxes + CycleTextbox = gtk_entry_new (); + gtk_entry_set_max_length (GTK_ENTRY (CycleTextbox), 0); + // gtk_entry_set_input_purpose (GTK_ENTRY (CycleTextbox), GTK_INPUT_PURPOSE_DIGITS); + CrystalTextbox = gtk_entry_new (); + gtk_entry_set_max_length (GTK_ENTRY (CrystalTextbox), 0); + BaudTextbox = gtk_entry_new (); + gtk_entry_set_max_length (GTK_ENTRY (BaudTextbox), 0); + + if(!UartFunctionUsed()) { + gtk_widget_set_sensitive (BaudTextbox, FALSE); + gtk_widget_set_sensitive (textLabel3, FALSE); + } + + if(Prog.mcu && (Prog.mcu->whichIsa == ISA_ANSIC || + Prog.mcu->whichIsa == ISA_INTERPRETED)) + { + gtk_widget_set_sensitive (CrystalTextbox, FALSE); + gtk_widget_set_sensitive (textLabel2, FALSE); + } + + OkButton = gtk_button_new_with_label ("OK"); + CancelButton = gtk_button_new_with_label ("Cancel"); + + char explanation[1024] = ""; + + if(UartFunctionUsed()) { + if(Prog.mcu && Prog.mcu->uartNeeds.rxPin != 0) { + sprintf(explanation, + _("Serial (UART) will use pins %d and %d.\r\n\r\n"), + Prog.mcu->uartNeeds.rxPin, Prog.mcu->uartNeeds.txPin); + } + else { + strcpy(explanation, + _("Please select a micro with a UART.\r\n\r\n")); + } + } + else { + strcpy(explanation, _("\n No serial instructions (UART Send/UART Receive) \n" + "are in use; add one to program before \n" + "setting baud rate.\r\n\r\n") ); + } + + strcat(explanation, + _("The cycle time for the 'PLC' runtime generated by \n" "LDmicro is user-" + "configurable. Very short cycle \n" "times may not be achievable due " + "to processor \n" "speed constraints, and very long cycle times may \n" + "not be achievable due to hardware overflows. Cycle \n" "times between 10 ms \n" + "and 100 ms will usually be practical.\r\n\r\n" + "The compiler must know what speed crystal you \n" "are using with the " + "micro to convert between timing \n" "in clock cycles and timing in" + "seconds. A 4 MHz to \n" "20 MHz crystal is typical; check the speed " + "grade of \n" "the part you are using to determine the maximum \n" "allowable" + "clock speed before choosing a crystal.\n")); + + HWID textLabel4 = gtk_label_new (explanation); + + // Creating required containers for packing + 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 (ConfGrid), 2); + + 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); @@ -180,70 +138,104 @@ static void MakeControls(void) // (LONG_PTR)MyNumberProc); } +//----------------------------------------------------------------------------- +// Don't allow any characters other than 0-9. in the text boxes. +//----------------------------------------------------------------------------- + +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"); + return; + } + } +} + +// Gets data from the text boxes +void ConfDialogGetData (GtkWidget* widget, gpointer data){ + char* buf; + + buf = const_cast <char*> (gtk_entry_get_text (GTK_ENTRY (CycleTextbox))); + Prog.cycleTime = (int)(1000*atof(buf) + 0.5); + if(Prog.cycleTime == 0) { + Error(_("Zero cycle time not valid; resetting to 10 ms.")); + Prog.cycleTime = 10000; + } + + buf = const_cast <char*> (gtk_entry_get_text (GTK_ENTRY(CrystalTextbox))); + Prog.mcuClock = (int)(1e6*atof(buf) + 0.5); + + buf = const_cast <char*> (gtk_entry_get_text (GTK_ENTRY(BaudTextbox))); + Prog.baudRate = atoi(buf); + DestroyWindow (ConfDialog); +} + +// Checks for the required key press +gboolean ConfDialogKeyPress (GtkWidget* widget, GdkEventKey* event, gpointer data){ + if (event -> keyval == GDK_KEY_Return){ + ConfDialogGetData(NULL, NULL); + } + else if (event -> keyval == GDK_KEY_Escape){ + 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 ConfDialogSignalCall () { + g_signal_connect (G_OBJECT(CycleTextbox), "insert-text", + G_CALLBACK(ConfDialogMyNumberProc), NULL); + g_signal_connect (G_OBJECT(CrystalTextbox), "insert-text", + G_CALLBACK(ConfDialogMyNumberProc), NULL); + g_signal_connect (G_OBJECT(BaudTextbox), "insert-text", + G_CALLBACK(ConfDialogMyNumberProc), NULL); + g_signal_connect (G_OBJECT (ConfDialog), "key-press-event", + 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) { -// // The window's height will be resized later, to fit the explanation text. -// ConfDialog = CreateWindowClient(0, "LDmicroDialog", _("PLC Configuration"), -// WS_OVERLAPPED | WS_SYSMENU, -// 100, 100, 0, 0, NULL, NULL, Instance, NULL); - -// MakeControls(); - -// char buf[16]; -// sprintf(buf, "%.1f", (Prog.cycleTime / 1000.0)); -// SendMessage(CycleTextbox, WM_SETTEXT, 0, (LPARAM)buf); - -// sprintf(buf, "%.6f", Prog.mcuClock / 1e6); -// SendMessage(CrystalTextbox, WM_SETTEXT, 0, (LPARAM)buf); - -// sprintf(buf, "%d", Prog.baudRate); -// SendMessage(BaudTextbox, WM_SETTEXT, 0, (LPARAM)buf); - -// EnableWindow(MainWindow, FALSE); -// ShowWindow(ConfDialog, TRUE); -// SetFocus(CycleTextbox); - -// 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(ConfDialog, &msg)) continue; -// TranslateMessage(&msg); -// DispatchMessage(&msg); -// } - -// if(!DialogCancel) { -// char buf[16]; -// SendMessage(CycleTextbox, WM_GETTEXT, (WPARAM)sizeof(buf), -// (LPARAM)(buf)); -// Prog.cycleTime = (int)(1000*atof(buf) + 0.5); -// if(Prog.cycleTime == 0) { -// Error(_("Zero cycle time not valid; resetting to 10 ms.")); -// Prog.cycleTime = 10000; -// } - -// SendMessage(CrystalTextbox, WM_GETTEXT, (WPARAM)sizeof(buf), -// (LPARAM)(buf)); -// Prog.mcuClock = (int)(1e6*atof(buf) + 0.5); - -// SendMessage(BaudTextbox, WM_GETTEXT, (WPARAM)sizeof(buf), -// (LPARAM)(buf)); -// Prog.baudRate = atoi(buf); -// } - -// EnableWindow(MainWindow, TRUE); -// DestroyWindow(ConfDialog); -// return; -} + // The window's height will be resized later, to fit the explanation text. + MakeControls(); + GdkEventKey* event; + + ConfDialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); + 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), ConfPackingBox); + gtk_widget_add_events (ConfDialog, GDK_KEY_PRESS_MASK); + gtk_widget_add_events (ConfDialog, GDK_BUTTON_PRESS_MASK); + + char buf[16]; + sprintf(buf, "%.1f", (Prog.cycleTime / 1000.0)); + gtk_entry_set_text (GTK_ENTRY (CycleTextbox), buf); + + sprintf(buf, "%.6f", Prog.mcuClock / 1e6); + gtk_entry_set_text (GTK_ENTRY (CrystalTextbox), buf); + + sprintf(buf, "%d", Prog.baudRate); + gtk_entry_set_text (GTK_ENTRY (BaudTextbox), buf); + + gtk_widget_set_sensitive (MainWindow, FALSE); + 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); + + ConfDialogSignalCall(); + + return; +}
\ No newline at end of file diff --git a/ldmicro/contactsdialog.cpp b/ldmicro/contactsdialog.cpp index a845220..bf896fa 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; - +static HWID ContactsGrid; +static 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.cpp b/ldmicro/draw.cpp index ad8259d..7c58154 100644 --- a/ldmicro/draw.cpp +++ b/ldmicro/draw.cpp @@ -250,54 +250,54 @@ int ProgCountWidestRow(void) // Draw a vertical wire one leaf element unit high up from (cx, cy), where cx // and cy are in charcter units. //----------------------------------------------------------------------------- -static void VerticalWire(int cx, int cy) +static void VerticalWire(HCRDC Hcr, int cx, int cy) { int j; for(j = 1; j < POS_HEIGHT; j++) { - DrawChars(cx, cy + (POS_HEIGHT/2 - j), "|"); + DrawChars(Hcr, cx, cy + (POS_HEIGHT/2 - j), "|"); } - DrawChars(cx, cy + (POS_HEIGHT/2), "+"); - DrawChars(cx, cy + (POS_HEIGHT/2 - POS_HEIGHT), "+"); + DrawChars(Hcr, cx, cy + (POS_HEIGHT/2), "+"); + DrawChars(Hcr, cx, cy + (POS_HEIGHT/2 - POS_HEIGHT), "+"); } //----------------------------------------------------------------------------- // Convenience functions for making the text colors pretty, for DrawElement. //----------------------------------------------------------------------------- -static void NormText(void) +static void NormText(HCRDC Hcr) { - SetTextColor(Hdc, InSimulationMode ? HighlightColours.simOff : + SetTextColor(Hcr, InSimulationMode ? HighlightColours.simOff : HighlightColours.def); - SelectObject(Hdc, FixedWidthFont); + SelectObject(Hcr, FixedWidthFont); } -static void EmphText(void) +static void EmphText(HCRDC Hcr) { - SetTextColor(Hdc, InSimulationMode ? HighlightColours.simOn : + SetTextColor(Hcr, InSimulationMode ? HighlightColours.simOn : HighlightColours.selected); - SelectObject(Hdc, FixedWidthFontBold); + SelectObject(Hcr, FixedWidthFontBold); } -static void NameText(void) +static void NameText(HCRDC Hcr) { if(!InSimulationMode && !ThisHighlighted) { - SetTextColor(Hdc, HighlightColours.name); + SetTextColor(Hcr, HighlightColours.name); } } -static void BodyText(void) +static void BodyText(HCRDC Hcr) { if(!InSimulationMode && !ThisHighlighted) { - SetTextColor(Hdc, HighlightColours.def); + SetTextColor(Hcr, HighlightColours.def); } } -static void PoweredText(BOOL powered) +static void PoweredText(HCRDC Hcr, BOOL powered) { if(InSimulationMode) { if(powered) - EmphText(); + EmphText(Hcr); else - NormText(); + NormText(Hcr); } } @@ -322,36 +322,36 @@ static int FormattedStrlen(const char *str) // Draw a string, centred in the space of a single position, with spaces on // the left and right. Draws on the upper line of the position. //----------------------------------------------------------------------------- -static void CenterWithSpaces(int cx, int cy, char *str, BOOL powered, +static void CenterWithSpaces(HCRDC Hcr, int cx, int cy, char *str, BOOL powered, BOOL isName) { int extra = POS_WIDTH - FormattedStrlen(str); - PoweredText(powered); - if(isName) NameText(); - DrawChars(cx + (extra/2), cy + (POS_HEIGHT/2) - 1, str); - if(isName) BodyText(); + PoweredText(Hcr, powered); + if(isName) NameText(Hcr); + DrawChars(Hcr, cx + (extra/2), cy + (POS_HEIGHT/2) - 1, str); + if(isName) BodyText(Hcr); } //----------------------------------------------------------------------------- // Like CenterWithWires, but for an arbitrary width position (e.g. for ADD // and SUB, which are double-width). //----------------------------------------------------------------------------- -static void CenterWithWiresWidth(int cx, int cy,const char *str, BOOL before, +static void CenterWithWiresWidth(HCRDC Hcr, int cx, int cy,const char *str, BOOL before, BOOL after, int totalWidth) { int extra = totalWidth - FormattedStrlen(str); - PoweredText(after); - DrawChars(cx + (extra/2), cy + (POS_HEIGHT/2), str); + PoweredText(Hcr, after); + DrawChars(Hcr, cx + (extra/2), cy + (POS_HEIGHT/2), str); - PoweredText(before); + PoweredText(Hcr, before); int i; for(i = 0; i < (extra/2); i++) { - DrawChars(cx + i, cy + (POS_HEIGHT/2), "-"); + DrawChars(Hcr, cx + i, cy + (POS_HEIGHT/2), "-"); } - PoweredText(after); + PoweredText(Hcr, after); for(i = FormattedStrlen(str)+(extra/2); i < totalWidth; i++) { - DrawChars(cx + i, cy + (POS_HEIGHT/2), "-"); + DrawChars(Hcr, cx + i, cy + (POS_HEIGHT/2), "-"); } } @@ -360,16 +360,16 @@ static void CenterWithWiresWidth(int cx, int cy,const char *str, BOOL before, // the left and right coloured according to the powered state. Draws on the // middle line. //----------------------------------------------------------------------------- -static void CenterWithWires(int cx, int cy, const char *str, BOOL before, BOOL after) +static void CenterWithWires(HCRDC Hcr, int cx, int cy, const char *str, BOOL before, BOOL after) { - CenterWithWiresWidth(cx, cy, str, before, after, POS_WIDTH); + CenterWithWiresWidth(Hcr, cx, cy, str, before, after, POS_WIDTH); } //----------------------------------------------------------------------------- // Draw an end of line element (coil, RES, MOV, etc.). Special things about // an end of line element: we must right-justify it. //----------------------------------------------------------------------------- -static BOOL DrawEndOfLine(int which, ElemLeaf *leaf, int *cx, int *cy, +static BOOL DrawEndOfLine(HCRDC Hcr, int which, ElemLeaf *leaf, int *cx, int *cy, BOOL poweredBefore) { int cx0 = *cx, cy0 = *cy; @@ -390,8 +390,8 @@ static BOOL DrawEndOfLine(int which, ElemLeaf *leaf, int *cx, int *cy, break; } - NormText(); - PoweredText(poweredBefore); + NormText(Hcr); + PoweredText(Hcr, poweredBefore); while(*cx < (ColsAvailable-thisWidth)*POS_WIDTH) { int gx = *cx/POS_WIDTH; int gy = *cy/POS_HEIGHT; @@ -405,14 +405,14 @@ static BOOL DrawEndOfLine(int which, ElemLeaf *leaf, int *cx, int *cy, int i; for(i = 0; i < POS_WIDTH; i++) { - DrawChars(*cx + i, *cy + (POS_HEIGHT/2), "-"); + DrawChars(Hcr, *cx + i, *cy + (POS_HEIGHT/2), "-"); } *cx += POS_WIDTH; cx0 += POS_WIDTH; } if(leaf == Selected && !InSimulationMode) { - EmphText(); + EmphText(Hcr); ThisHighlighted = TRUE; } else { ThisHighlighted = FALSE; @@ -424,26 +424,26 @@ static BOOL DrawEndOfLine(int which, ElemLeaf *leaf, int *cx, int *cy, ElemCounter *c = &leaf->d.counter; sprintf(buf, "{\x01""CTC\x02 0:%d}", c->max); - CenterWithSpaces(*cx, *cy, c->name, poweredAfter, TRUE); - CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter); + CenterWithSpaces(Hcr, *cx, *cy, c->name, poweredAfter, TRUE); + CenterWithWires(Hcr, *cx, *cy, buf, poweredBefore, poweredAfter); break; } case ELEM_RES: { ElemReset *r = &leaf->d.reset; - CenterWithSpaces(*cx, *cy, r->name, poweredAfter, TRUE); - CenterWithWires(*cx, *cy, "{RES}", poweredBefore, poweredAfter); + CenterWithSpaces(Hcr, *cx, *cy, r->name, poweredAfter, TRUE); + CenterWithWires(Hcr, *cx, *cy, "{RES}", poweredBefore, poweredAfter); break; } case ELEM_READ_ADC: { ElemReadAdc *r = &leaf->d.readAdc; - CenterWithSpaces(*cx, *cy, r->name, poweredAfter, TRUE); - CenterWithWires(*cx, *cy, "{READ ADC}", poweredBefore, + CenterWithSpaces(Hcr, *cx, *cy, r->name, poweredAfter, TRUE); + CenterWithWires(Hcr, *cx, *cy, "{READ ADC}", poweredBefore, poweredAfter); break; } case ELEM_SET_PWM: { ElemSetPwm *s = &leaf->d.setPwm; - CenterWithSpaces(*cx, *cy, s->name, poweredAfter, TRUE); + CenterWithSpaces(Hcr, *cx, *cy, s->name, poweredAfter, TRUE); char l[50]; if(s->targetFreq >= 100000) { sprintf(l, "{PWM %d kHz}", (s->targetFreq+500)/1000); @@ -454,13 +454,13 @@ static BOOL DrawEndOfLine(int which, ElemLeaf *leaf, int *cx, int *cy, } else { sprintf(l, "{PWM %d Hz}", s->targetFreq); } - CenterWithWires(*cx, *cy, l, poweredBefore, + CenterWithWires(Hcr, *cx, *cy, l, poweredBefore, poweredAfter); break; } case ELEM_PERSIST: - CenterWithSpaces(*cx, *cy, leaf->d.persist.var, poweredAfter, TRUE); - CenterWithWires(*cx, *cy, "{PERSIST}", poweredBefore, poweredAfter); + CenterWithSpaces(Hcr, *cx, *cy, leaf->d.persist.var, poweredAfter, TRUE); + CenterWithWires(Hcr, *cx, *cy, "{PERSIST}", poweredBefore, poweredAfter); break; case ELEM_MOVE: { @@ -471,7 +471,7 @@ static BOOL DrawEndOfLine(int which, ElemLeaf *leaf, int *cx, int *cy, if((strlen(m->dest) > (POS_WIDTH - 9)) || (strlen(m->src) > (POS_WIDTH - 9))) { - CenterWithWires(*cx, *cy, TOO_LONG, poweredBefore, + CenterWithWires(Hcr, *cx, *cy, TOO_LONG, poweredBefore, poweredAfter); break; } @@ -484,12 +484,12 @@ static BOOL DrawEndOfLine(int which, ElemLeaf *leaf, int *cx, int *cy, strcpy(bot, "{ \x01MOV\x02}"); memcpy(bot+2, m->src, strlen(m->src)); - CenterWithSpaces(*cx, *cy, top, poweredAfter, FALSE); - CenterWithWires(*cx, *cy, bot, poweredBefore, poweredAfter); + CenterWithSpaces(Hcr, *cx, *cy, top, poweredAfter, FALSE); + CenterWithWires(Hcr, *cx, *cy, bot, poweredBefore, poweredAfter); break; } case ELEM_MASTER_RELAY: - CenterWithWires(*cx, *cy, "{MASTER RLY}", poweredBefore, + CenterWithWires(Hcr, *cx, *cy, "{MASTER RLY}", poweredBefore, poweredAfter); break; @@ -502,9 +502,9 @@ static BOOL DrawEndOfLine(int which, ElemLeaf *leaf, int *cx, int *cy, bot[strlen(bot)] = ' '; bot[13] = '}'; bot[14] = '\0'; - CenterWithSpaces(*cx, *cy, "{\x01SHIFT REG\x02 }", + CenterWithSpaces(Hcr, *cx, *cy, "{\x01SHIFT REG\x02 }", poweredAfter, FALSE); - CenterWithWires(*cx, *cy, bot, poweredBefore, poweredAfter); + CenterWithWires(Hcr, *cx, *cy, bot, poweredBefore, poweredAfter); break; } case ELEM_PIECEWISE_LINEAR: @@ -526,14 +526,14 @@ static BOOL DrawEndOfLine(int which, ElemLeaf *leaf, int *cx, int *cy, top[strlen(top)] = ' '; top[13] = '}'; top[14] = '\0'; - CenterWithSpaces(*cx, *cy, top, poweredAfter, FALSE); + CenterWithSpaces(Hcr, *cx, *cy, top, poweredAfter, FALSE); memset(bot, ' ', sizeof(bot)); bot[0] = '{'; sprintf(bot+2, " %s[%s]", str, index); bot[strlen(bot)] = ' '; bot[13] = '}'; bot[14] = '\0'; - CenterWithWires(*cx, *cy, bot, poweredBefore, poweredAfter); + CenterWithWires(Hcr, *cx, *cy, bot, poweredBefore, poweredAfter); break; } case ELEM_COIL: { @@ -553,8 +553,8 @@ static BOOL DrawEndOfLine(int which, ElemLeaf *leaf, int *cx, int *cy, buf[2] = ')'; buf[3] = '\0'; - CenterWithSpaces(*cx, *cy, c->name, poweredAfter, TRUE); - CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter); + CenterWithSpaces(Hcr, *cx, *cy, c->name, poweredAfter, TRUE); + CenterWithWires(Hcr, *cx, *cy, buf, poweredBefore, poweredAfter); break; } case ELEM_DIV: @@ -608,9 +608,9 @@ static BOOL DrawEndOfLine(int which, ElemLeaf *leaf, int *cx, int *cy, bot[l] = '}'; bot[l+1] = '\0'; int extra = 2*POS_WIDTH - FormattedStrlen(top); - PoweredText(poweredAfter); - DrawChars(*cx + (extra/2), *cy + (POS_HEIGHT/2) - 1, top); - CenterWithWiresWidth(*cx, *cy, bot, poweredBefore, poweredAfter, + PoweredText(Hcr, poweredAfter); + DrawChars(Hcr, *cx + (extra/2), *cy + (POS_HEIGHT/2) - 1, top); + CenterWithWiresWidth(Hcr, *cx, *cy, bot, poweredBefore, poweredAfter, 2*POS_WIDTH); *cx += POS_WIDTH; @@ -631,7 +631,7 @@ static BOOL DrawEndOfLine(int which, ElemLeaf *leaf, int *cx, int *cy, // Draw a leaf element. Special things about a leaf: no need to recurse // further, and we must put it into the display matrix. //----------------------------------------------------------------------------- -static BOOL DrawLeaf(int which, ElemLeaf *leaf, int *cx, int *cy, +static BOOL DrawLeaf(HCRDC Hcr, int which, ElemLeaf *leaf, int *cx, int *cy, BOOL poweredBefore) { int cx0 = *cx, cy0 = *cy; @@ -649,20 +649,20 @@ static BOOL DrawLeaf(int which, ElemLeaf *leaf, int *cx, int *cy, if(b[-1] == '\r') b[-1] = '\0'; *b = '\0'; sprintf(tlbuf, "\x03 ; %s\x02", tbuf); - DrawChars(*cx, *cy + (POS_HEIGHT/2) - 1, tlbuf); + DrawChars(Hcr, *cx, *cy + (POS_HEIGHT/2) - 1, tlbuf); sprintf(tlbuf, "\x03 ; %s\x02", b+1); - DrawChars(*cx, *cy + (POS_HEIGHT/2), tlbuf); + DrawChars(Hcr, *cx, *cy + (POS_HEIGHT/2), tlbuf); } else { sprintf(tlbuf, "\x03 ; %s\x02", tbuf); - DrawChars(*cx, *cy + (POS_HEIGHT/2) - 1, tlbuf); + DrawChars(Hcr, *cx, *cy + (POS_HEIGHT/2) - 1, tlbuf); } *cx += ColsAvailable*POS_WIDTH; break; } case ELEM_PLACEHOLDER: { - NormText(); - CenterWithWiresWidth(*cx, *cy, "--", FALSE, FALSE, 2); + NormText(Hcr); + CenterWithWiresWidth(Hcr, *cx, *cy, "--", FALSE, FALSE, 2); *cx += POS_WIDTH; break; } @@ -675,8 +675,8 @@ static BOOL DrawLeaf(int which, ElemLeaf *leaf, int *cx, int *cy, buf[2] = '['; buf[3] = '\0'; - CenterWithSpaces(*cx, *cy, c->name, poweredAfter, TRUE); - CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter); + CenterWithSpaces(Hcr, *cx, *cy, c->name, poweredAfter, TRUE); + CenterWithWires(Hcr, *cx, *cy, buf, poweredBefore, poweredAfter); *cx += POS_WIDTH; break; @@ -717,19 +717,19 @@ cmp: strcpy(s2, TOO_LONG); } - CenterWithSpaces(*cx, *cy, s1, poweredAfter, FALSE); - CenterWithWires(*cx, *cy, s2, poweredBefore, poweredAfter); + CenterWithSpaces(Hcr, *cx, *cy, s1, poweredAfter, FALSE); + CenterWithWires(Hcr, *cx, *cy, s2, poweredBefore, poweredAfter); *cx += POS_WIDTH; break; } case ELEM_OPEN: - CenterWithWires(*cx, *cy, "+ +", poweredBefore, poweredAfter); + CenterWithWires(Hcr, *cx, *cy, "+ +", poweredBefore, poweredAfter); *cx += POS_WIDTH; break; case ELEM_SHORT: - CenterWithWires(*cx, *cy, "+------+", poweredBefore, poweredAfter); + CenterWithWires(Hcr, *cx, *cy, "+------+", poweredBefore, poweredAfter); *cx += POS_WIDTH; break; @@ -744,8 +744,8 @@ cmp: s2 = "[\x01OSF\x02 \\_]"; } else oops(); - CenterWithSpaces(*cx, *cy, s1, poweredAfter, FALSE); - CenterWithWires(*cx, *cy, s2, poweredBefore, poweredAfter); + CenterWithSpaces(Hcr, *cx, *cy, s1, poweredAfter, FALSE); + CenterWithWires(Hcr, *cx, *cy, s2, poweredBefore, poweredAfter); *cx += POS_WIDTH; break; @@ -763,8 +763,8 @@ cmp: ElemCounter *c = &leaf->d.counter; sprintf(buf, "[%s >=%d]", s, c->max); - CenterWithSpaces(*cx, *cy, c->name, poweredAfter, TRUE); - CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter); + CenterWithSpaces(Hcr, *cx, *cy, c->name, poweredAfter, TRUE); + CenterWithWires(Hcr, *cx, *cy, buf, poweredBefore, poweredAfter); *cx += POS_WIDTH; break; @@ -791,8 +791,8 @@ cmp: sprintf(buf, "[%s %.2f ms]", s, t->delay/1000.0); } - CenterWithSpaces(*cx, *cy, t->name, poweredAfter, TRUE); - CenterWithWires(*cx, *cy, buf, poweredBefore, poweredAfter); + CenterWithSpaces(Hcr, *cx, *cy, t->name, poweredAfter, TRUE); + CenterWithWires(Hcr, *cx, *cy, buf, poweredBefore, poweredAfter); *cx += POS_WIDTH; break; @@ -808,28 +808,28 @@ cmp: sprintf(bot, "{\"%s\"}", str); int extra = 2*POS_WIDTH - strlen(leaf->d.fmtdStr.var); - PoweredText(poweredAfter); - NameText(); - DrawChars(*cx + (extra/2), *cy + (POS_HEIGHT/2) - 1, + PoweredText(Hcr, poweredAfter); + NameText(Hcr); + DrawChars(Hcr, *cx + (extra/2), *cy + (POS_HEIGHT/2) - 1, leaf->d.fmtdStr.var); - BodyText(); + BodyText(Hcr); - CenterWithWiresWidth(*cx, *cy, bot, poweredBefore, poweredAfter, + CenterWithWiresWidth(Hcr, *cx, *cy, bot, poweredBefore, poweredAfter, 2*POS_WIDTH); *cx += 2*POS_WIDTH; break; } case ELEM_UART_RECV: case ELEM_UART_SEND: - CenterWithWires(*cx, *cy, + CenterWithWires(Hcr, *cx, *cy, (which == ELEM_UART_RECV) ? "{UART RECV}" : "{UART SEND}", poweredBefore, poweredAfter); - CenterWithSpaces(*cx, *cy, leaf->d.uart.name, poweredAfter, TRUE); + CenterWithSpaces(Hcr, *cx, *cy, leaf->d.uart.name, poweredAfter, TRUE); *cx += POS_WIDTH; break; default: - poweredAfter = DrawEndOfLine(which, leaf, cx, cy, poweredBefore); + poweredAfter = DrawEndOfLine(Hcr, which, leaf, cx, cy, poweredBefore); break; } @@ -926,19 +926,18 @@ cmp: // element, else FALSE. This is needed to colour all the wires correctly, // since the colouring indicates whether a wire is energized. //----------------------------------------------------------------------------- -BOOL DrawElement(int which, void *elem, int *cx, int *cy, BOOL poweredBefore) +BOOL DrawElement(HCRDC Hcr, int which, void *elem, int *cx, int *cy, BOOL poweredBefore) { BOOL poweredAfter; int cx0 = *cx, cy0 = *cy; ElemLeaf *leaf = (ElemLeaf *)elem; - - SetBkColor(DrawWindow,Hdc, InSimulationMode ? HighlightColours.simBg : + SetBkColor(DrawWindow,Hcr, InSimulationMode ? HighlightColours.simBg : HighlightColours.bg); - NormText(); + NormText(Hcr); if(elem == Selected && !InSimulationMode) { - EmphText(); + EmphText(Hcr); ThisHighlighted = TRUE; } else { ThisHighlighted = FALSE; @@ -950,7 +949,7 @@ BOOL DrawElement(int which, void *elem, int *cx, int *cy, BOOL poweredBefore) ElemSubcktSeries *s = (ElemSubcktSeries *)elem; poweredAfter = poweredBefore; for(i = 0; i < s->count; i++) { - poweredAfter = DrawElement(s->contents[i].which, + poweredAfter = DrawElement(Hcr, s->contents[i].which, s->contents[i].d.any, cx, cy, poweredAfter); } break; @@ -968,12 +967,12 @@ BOOL DrawElement(int which, void *elem, int *cx, int *cy, BOOL poweredBefore) for(i = 0; i < p->count; i++) { BOOL poweredThis; - poweredThis = DrawElement(p->contents[i].which, + poweredThis = DrawElement(Hcr, p->contents[i].which, p->contents[i].d.any, cx, cy, poweredBefore); if(InSimulationMode) { if(poweredThis) poweredAfter = TRUE; - PoweredText(poweredThis); + PoweredText(Hcr, poweredThis); } while((*cx - cx0) < widthMax*POS_WIDTH) { @@ -992,7 +991,7 @@ BOOL DrawElement(int which, void *elem, int *cx, int *cy, BOOL poweredBefore) buf[j] = '-'; } buf[j] = '\0'; - DrawChars(*cx, *cy + (POS_HEIGHT/2), buf); + DrawChars(Hcr, *cx, *cy + (POS_HEIGHT/2), buf); *cx += POS_WIDTH; } @@ -1015,37 +1014,37 @@ BOOL DrawElement(int which, void *elem, int *cx, int *cy, BOOL poweredBefore) if(*cx/POS_WIDTH != ColsAvailable) { needWire = FALSE; for(j = heightMax - 1; j >= 1; j--) { - if(j <= lowestPowered) PoweredText(poweredAfter); + if(j <= lowestPowered) PoweredText(Hcr, poweredAfter); if(DisplayMatrix[*cx/POS_WIDTH - 1][*cy/POS_HEIGHT + j]) { needWire = TRUE; } - if(needWire) VerticalWire(*cx - 1, *cy + j*POS_HEIGHT); + if(needWire) VerticalWire(Hcr, *cx - 1, *cy + j*POS_HEIGHT); } // stupid special case if(lowestPowered == 0 && InSimulationMode) { - EmphText(); - DrawChars(*cx - 1, *cy + (POS_HEIGHT/2), "+"); + EmphText(Hcr); + DrawChars(Hcr, *cx - 1, *cy + (POS_HEIGHT/2), "+"); } } - PoweredText(poweredBefore); + PoweredText(Hcr, poweredBefore); needWire = FALSE; for(j = heightMax - 1; j >= 1; j--) { if(DisplayMatrix[cx0/POS_WIDTH][*cy/POS_HEIGHT + j]) { needWire = TRUE; } - if(needWire) VerticalWire(cx0 - 1, *cy + j*POS_HEIGHT); + if(needWire) VerticalWire(Hcr, cx0 - 1, *cy + j*POS_HEIGHT); } break; } default: - poweredAfter = DrawLeaf(which, leaf, cx, cy, poweredBefore); + poweredAfter = DrawLeaf(Hcr, which, leaf, cx, cy, poweredBefore); break; } - NormText(); + NormText(Hcr); return poweredAfter; } @@ -1053,18 +1052,18 @@ BOOL DrawElement(int which, void *elem, int *cx, int *cy, BOOL poweredBefore) // Draw the rung that signals the end of the program. Kind of useless but // do it anyways, for convention. //----------------------------------------------------------------------------- -void DrawEndRung(int cx, int cy) +void DrawEndRung(HCRDC Hcr, int cx, int cy) { int i; char *str = "[END]"; int lead = (POS_WIDTH - strlen(str))/2; ThisHighlighted = TRUE; for(i = 0; i < lead; i++) { - DrawChars(cx + i, cy + (POS_HEIGHT/2), "-"); + DrawChars(Hcr, cx + i, cy + (POS_HEIGHT/2), "-"); } - DrawChars(cx + i, cy + (POS_HEIGHT/2), str); + DrawChars(Hcr, cx + i, cy + (POS_HEIGHT/2), str); i += strlen(str); for(; i < ColsAvailable*POS_WIDTH; i++) { - DrawChars(cx + i, cy + (POS_HEIGHT/2), "-"); + DrawChars(Hcr, cx + i, cy + (POS_HEIGHT/2), "-"); } } diff --git a/ldmicro/draw_outputdev.cpp b/ldmicro/draw_outputdev.cpp index d0b39bb..cf2cae4 100644 --- a/ldmicro/draw_outputdev.cpp +++ b/ldmicro/draw_outputdev.cpp @@ -31,7 +31,7 @@ #include "ldmicro.h" -void (*DrawChars)(int, int, const char *); +void (*DrawChars)(HCRDC Hcr, int, int, const char *); // After an undo all the memory addresses change but make an effort to put // the cursor roughly where it should be. @@ -81,35 +81,63 @@ 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. //----------------------------------------------------------------------------- -void CALLBACK BlinkCursor(HWND hwnd, UINT msg, UINT_PTR id, DWORD time) +BOOL BlinkCursor(BOOL kill = FALSE) { - // if(!isFocus(MainWindow) && !CursorDrawn) return; - // if(Cursor.left == 0) return; + // if(GetFocus(MainWindow) != !CursorDrawn) return TRUE; + + if(Cursor.left == 0) return TRUE; + + PlcCursor c; + memcpy(&c, &Cursor, sizeof(c)); + + c.top -= ScrollYOffset*POS_HEIGHT*FONT_HEIGHT; + c.left -= ScrollXOffset; + + if(c.top >= IoListTop) return TRUE; + + if(c.top + c.height >= IoListTop) { + c.height = IoListTop - c.top - 3; + } + + // if(!GDK_IS_DRAWING_CONTEXT(Hdc)) + // return FALSE; + + HCRDC Hcr = gdk_cairo_create(gtk_widget_get_window(DrawWindow)); - // PlcCursor c; - // memcpy(&c, &Cursor, sizeof(c)); + static int PREV_x = c.left; + static int PREV_y = c.top; + static int PREV_w = c.width; + static int PREV_h = c.height; - // c.top -= ScrollYOffset*POS_HEIGHT*FONT_HEIGHT; - // c.left -= ScrollXOffset; + if (PREV_x != c.left || PREV_y != c.top || PREV_w != c.width || PREV_h != c.height) + { + PatBlt(Hcr, PREV_x, PREV_y, PREV_w, PREV_h, PATINVERT, (HBRUSH)GetStockObject(BLACK_BRUSH)); + PREV_x = c.left; + PREV_y = c.top; + PREV_w = c.width; + PREV_h = c.height; - // if(c.top >= IoListTop) return; + // MainWindowResized(); + // PaintWindow(Hcr); + gtk_widget_queue_draw(DrawWindow); + } - // if(c.top + c.height >= IoListTop) { - // c.height = IoListTop - c.top - 3; - // } + if (CursorDrawn) + PatBlt(Hcr, c.left, c.top, c.width, c.height, PATINVERT, (HBRUSH)GetStockObject(WHITE_BRUSH)); + else + PatBlt(Hcr, c.left, c.top, c.width, c.height, PATINVERT, (HBRUSH)GetStockObject(BLACK_BRUSH)); + InvalidateRect(DrawWindow, NULL, FALSE); + cairo_destroy(Hcr); + CursorDrawn = !CursorDrawn; - // Hdc = GetDC(MainWindow); - // SelectObject(Hdc, GetStockObject(WHITE_BRUSH)); - // PatBlt(Hdc, c.left, c.top, c.width, c.height, PATINVERT); - // CursorDrawn = !CursorDrawn; - // ReleaseDC(MainWindow, Hdc); + return !kill; } //----------------------------------------------------------------------------- // Output a string to the screen at a particular location, in character- // sized units. //----------------------------------------------------------------------------- -static void DrawCharsToScreen(int cx, int cy, const char *str) +static void DrawCharsToScreen(HCRDC Hcr, int cx, int cy, const char *str) { cy -= ScrollYOffset*POS_HEIGHT; if(cy < -2) return; @@ -129,12 +157,12 @@ static void DrawCharsToScreen(int cx, int cy, const char *str) if(strchr("{}[]", *str) && hiOk && !inComment) { if(*str == '{' || *str == '[') inBrace++; if(inBrace == 1) { - prev = GetTextColor(Hdc); - SetTextColor(Hdc, HighlightColours.punct); - TextOut(Hdc, x, y, str, 1); - SetTextColor(Hdc, prev); + prev = GetTextColor(Hcr); + SetTextColor(Hcr, HighlightColours.punct); + TextOut(DrawWindow, Hcr, x, y, str, 1); + SetTextColor(Hcr, prev); } else { - TextOut(Hdc, x, y, str, 1); + TextOut(DrawWindow, Hcr, x, y, str, 1); } if(*str == ']' || *str == '}') inBrace--; } else if(( @@ -142,42 +170,42 @@ static void DrawCharsToScreen(int cx, int cy, const char *str) || str[-1] == ':' || str[-1] == '[')) || (*str == '-' && isdigit(str[1]))) && hiOk && !inComment) { - prev = GetTextColor(Hdc); - SetTextColor(Hdc, HighlightColours.lit); - TextOut(Hdc, x, y, str, 1); - SetTextColor(Hdc, prev); + prev = GetTextColor(Hcr); + SetTextColor(Hcr, HighlightColours.lit); + TextOut(DrawWindow, Hcr, x, y, str, 1); + SetTextColor(Hcr, prev); inNumber = TRUE; } else if(*str == '\x01') { cx--; if(hiOk) { - prev = GetTextColor(Hdc); - SetTextColor(Hdc, HighlightColours.op); + prev = GetTextColor(Hcr); + SetTextColor(Hcr, HighlightColours.op); } } else if(*str == '\x02') { cx--; if(hiOk) { - SetTextColor(Hdc, prev); + SetTextColor(Hcr, prev); inComment = FALSE; } } else if(*str == '\x03') { cx--; if(hiOk) { - prev = GetTextColor(Hdc); - SetTextColor(Hdc, HighlightColours.comment); + prev = GetTextColor(Hcr); + SetTextColor(Hcr, HighlightColours.comment); inComment = TRUE; } } else if(inNumber) { if(isdigit(*str) || *str == '.') { - prev = GetTextColor(Hdc); - SetTextColor(Hdc, HighlightColours.lit); - TextOut(Hdc, x, y, str, 1); - SetTextColor(Hdc, prev); + prev = GetTextColor(Hcr); + SetTextColor(Hcr, HighlightColours.lit); + TextOut(DrawWindow, Hcr, x, y, str, 1); + SetTextColor(Hcr, prev); } else { - TextOut(Hdc, x, y, str, 1); + TextOut(DrawWindow, Hcr, x, y, str, 1); inNumber = FALSE; } } else { - TextOut(Hdc, x, y, str, 1); + TextOut(DrawWindow, Hcr, x, y, str, 1); } firstTime = FALSE; @@ -218,63 +246,12 @@ int ScreenRowsAvailable(void) // cursor should go and fill in coordinates for BlinkCursor. Not allowed to // draw deeper than IoListTop, as we would run in to the I/O listbox. //----------------------------------------------------------------------------- -void PaintWindow() +void PaintWindow(HCRDC Hcr) { - /* - cairo_set_source_rgb(cr, Cairo_R, Cairo_G, Cairo_G); - - cairo_select_font_face(cr, "Purisa", - CAIRO_FONT_SLANT_NORMAL, - CAIRO_FONT_WEIGHT_BOLD); - - cairo_set_font_size(cr, 20); - - cairo_move_to(cr, 20, height / 2.0); - cairo_show_text(cr, "-----------THIS IS A TEST DRAW----------"); - - cairo_fill (cr); - */ - - // SetBkColor(DrawWindow, hcr, InSimulationMode ? HighlightColours.simBg : - // HighlightColours.bg); - - // SetTextColor(hcr, InSimulationMode ? HighlightColours.simRungNum : - // HighlightColours.rungNum); - - // SelectObject(hcr, FixedWidthFont); - - // TextOut(hcr, 5, 100, "-------] [-------------------------------------------------------------------------------------------------------------------------------------------------{RES}-------", 14); - - // static HBITMAP BackBitmap; - // static HDC BackDc; - // static int BitmapWidth; - ok(); - - // RECT r; - // GetClientRect(MainWindow, &r); - + int bw = gtk_widget_get_allocated_width (DrawWindow);// = r.right; int bh = IoListTop; - - // HDC paintDc; - // if(!BackDc) { - // HWND desktop = GetDesktopWindow(); - // RECT dk; - // GetClientRect(desktop, &dk); - - // BitmapWidth = max(2000, dk.right + 300); - // BackBitmap = CreateCompatibleBitmap(Hdc, BitmapWidth, dk.bottom + 300); - // BackDc = CreateCompatibleDC(Hdc); - // SelectObject(BackDc, BackBitmap); - // } - // paintDc = Hdc; - // Hdc = BackDc; - - // RECT fi; - // fi.left = 0; fi.top = 0; - // fi.right = BitmapWidth; fi.bottom = bh; - // FillRect(Hdc, &fi, InSimulationMode ? SimBgBrush : BgBrush); /// now figure out how we should draw the ladder logic ColsAvailable = ProgCountWidestRow(); @@ -301,26 +278,26 @@ void PaintWindow() if(((cy + thisHeight) >= (ScrollYOffset - 8)*POS_HEIGHT) && (cy < (ScrollYOffset + rowsAvailable + 8)*POS_HEIGHT)) { - SetBkColor(DrawWindow, Hdc, InSimulationMode ? HighlightColours.simBg : + SetBkColor(DrawWindow, Hcr, InSimulationMode ? HighlightColours.simBg : HighlightColours.bg); - SetTextColor(Hdc, InSimulationMode ? HighlightColours.simRungNum : + SetTextColor(Hcr, InSimulationMode ? HighlightColours.simRungNum : HighlightColours.rungNum); - SelectObject(Hdc, FixedWidthFont); + SelectObject(Hcr, FixedWidthFont); int rung = i + 1; int y = Y_PADDING + FONT_HEIGHT*cy; int yp = y + FONT_HEIGHT*(POS_HEIGHT/2) - POS_HEIGHT*FONT_HEIGHT*ScrollYOffset; - + if(rung < 10) { char r[1] = { rung + '0' }; - TextOut(Hdc, 8 + FONT_WIDTH, yp, r, 1); + TextOut(DrawWindow, Hcr, 8 + FONT_WIDTH, yp, r, 1); } else { char r[2] = { (rung / 10) + '0', (rung % 10) + '0' }; - TextOut(Hdc, 8, yp, r, 2); + TextOut(DrawWindow, Hcr, 8, yp, r, 2); } int cx = 0; - DrawElement(ELEM_SERIES_SUBCKT, Prog.rungs[i], &cx, &cy, + DrawElement(Hcr, ELEM_SERIES_SUBCKT, Prog.rungs[i], &cx, &cy, Prog.rungPowered[i]); } @@ -328,7 +305,8 @@ void PaintWindow() cy += POS_HEIGHT; } cy -= 2; - DrawEndRung(0, cy); + DrawEndRung(Hcr, 0, cy); + if(SelectedGxAfterNextPaint >= 0) { MoveCursorNear(SelectedGxAfterNextPaint, SelectedGyAfterNextPaint); InvalidateRect(DrawWindow, NULL, FALSE); @@ -354,24 +332,22 @@ void PaintWindow() r.top = 0; r.right = r.left + 4; r.bottom = IoListTop; - FillRect(Hdc, &r, InSimulationMode ? BusLeftBrush : BusBrush); + FillRect(Hcr, &r, InSimulationMode ? BusLeftBrush : BusBrush); r.left += POS_WIDTH*FONT_WIDTH*ColsAvailable + 2; r.right += POS_WIDTH*FONT_WIDTH*ColsAvailable + 2; - FillRect(Hdc, &r, InSimulationMode ? BusRightBus : BusBrush); + FillRect(Hcr, &r, InSimulationMode ? BusRightBus : BusBrush); + InvalidateRect(DrawWindow, NULL, FALSE); CursorDrawn = FALSE; // BitBlt(paintDc, 0, 0, bw, bh, BackDc, ScrollXOffset, 0, SRCCOPY); - // if(InSimulationMode) { - // KillTimer(MainWindow, TIMER_BLINK_CURSOR); - // } else { - // KillTimer(MainWindow, TIMER_BLINK_CURSOR); - // BlinkCursor(NULL, 0, NULL, 0); - // SetTimer(MainWindow, TIMER_BLINK_CURSOR, 800, BlinkCursor); - // } + if(InSimulationMode) { + KillTimer(DrawWindow, TIMER_BLINK_CURSOR); + } else { + SetTimer(DrawWindow, TIMER_BLINK_CURSOR, 200, BlinkCursor); + } - // Hdc = paintDc; ok(); } @@ -453,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) { @@ -469,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); } //----------------------------------------------------------------------------- @@ -576,46 +553,46 @@ void ExportDrawingAsText(char *file) //----------------------------------------------------------------------------- void SetUpScrollbars(BOOL *horizShown, SCROLLINFO *horiz, SCROLLINFO *vert) { - // int totalHeight = 0; - // int i; - // for(i = 0; i < Prog.numRungs; i++) { - // totalHeight += CountHeightOfElement(ELEM_SERIES_SUBCKT, Prog.rungs[i]); - // totalHeight++; - // } - // totalHeight += 1; // for the end rung - - // int totalWidth = ProgCountWidestRow(); - - // if(totalWidth <= ScreenColsAvailable()) { - // *horizShown = FALSE; - // ScrollXOffset = 0; - // ScrollXOffsetMax = 0; - // } else { - // *horizShown = TRUE; - // memset(horiz, 0, sizeof(*horiz)); - // horiz->cbSize = sizeof(*horiz); - // horiz->fMask = SIF_DISABLENOSCROLL | SIF_ALL; - // horiz->nMin = 0; - // horiz->nMax = X_PADDING + totalWidth*POS_WIDTH*FONT_WIDTH; - // RECT r; - // GetClientRect(MainWindow, &r); - // horiz->nPage = r.right - X_PADDING; - // horiz->nPos = ScrollXOffset; - - // ScrollXOffsetMax = horiz->nMax - horiz->nPage + 1; - // if(ScrollXOffset > ScrollXOffsetMax) ScrollXOffset = ScrollXOffsetMax; - // if(ScrollXOffset < 0) ScrollXOffset = 0; - // } - - // vert->cbSize = sizeof(*vert); + int totalHeight = 0; + int i; + for(i = 0; i < Prog.numRungs; i++) { + totalHeight += CountHeightOfElement(ELEM_SERIES_SUBCKT, Prog.rungs[i]); + totalHeight++; + } + totalHeight += 1; // for the end rung + + int totalWidth = ProgCountWidestRow(); + + if(totalWidth <= ScreenColsAvailable()) { + *horizShown = FALSE; + ScrollXOffset = 0; + ScrollXOffsetMax = 0; + } else { + *horizShown = TRUE; + memset(horiz, 0, sizeof(*horiz)); + horiz->cbSize = sizeof(*horiz); + // horiz->fMask = SIF_DISABLENOSCROLL | SIF_ALL; + horiz->nMin = 0; + horiz->nMax = X_PADDING + totalWidth*POS_WIDTH*FONT_WIDTH; + RECT r; + GetClientRect(DrawWindow, &r); + horiz->nPage = r.right - X_PADDING; + horiz->nPos = ScrollXOffset; + + ScrollXOffsetMax = horiz->nMax - horiz->nPage + 1; + if(ScrollXOffset > ScrollXOffsetMax) ScrollXOffset = ScrollXOffsetMax; + if(ScrollXOffset < 0) ScrollXOffset = 0; + } + + vert->cbSize = sizeof(*vert); // vert->fMask = SIF_DISABLENOSCROLL | SIF_ALL; - // vert->nMin = 0; - // vert->nMax = totalHeight - 1; - // vert->nPos = ScrollYOffset; - // vert->nPage = ScreenRowsAvailable(); + vert->nMin = 0; + vert->nMax = totalHeight - 1; + vert->nPos = ScrollYOffset; + vert->nPage = ScreenRowsAvailable(); - // ScrollYOffsetMax = vert->nMax - vert->nPage + 1; + ScrollYOffsetMax = vert->nMax - vert->nPage + 1; - // if(ScrollYOffset > ScrollYOffsetMax) ScrollYOffset = ScrollYOffsetMax; - // if(ScrollYOffset < 0) ScrollYOffset = 0; + if(ScrollYOffset > ScrollYOffsetMax) ScrollYOffset = ScrollYOffsetMax; + if(ScrollYOffset < 0) ScrollYOffset = 0; } diff --git a/ldmicro/helpdialog.cpp b/ldmicro/helpdialog.cpp index a800f61..71cbd1a 100644 --- a/ldmicro/helpdialog.cpp +++ b/ldmicro/helpdialog.cpp @@ -26,11 +26,14 @@ #include "linuxUI.h" #include <stdio.h> #include <stdlib.h> +#include <iostream> //#include <commctrl.h> //#include <richedit.h> #include "ldmicro.h" +using namespace std; + extern char *HelpText[]; extern char *HelpTextDe[]; extern char *HelpTextFr[]; @@ -90,24 +93,29 @@ static char **Text[] = { AboutText }; -static HWND HelpDialog[2]; -static HWND RichEdit[2]; +static HWID HelpDialog[2]; +static HWID RichEdit[2]; static BOOL HelpWindowOpen[2]; static int TitleHeight; +HWID PackBoxHelp; +HWID TextView; +GtkTextBuffer* TextBuffer; +GtkTextIter* TextIter = new GtkTextIter; + #define RICH_EDIT_HEIGHT(h) \ ((((h) - 3 + (FONT_HEIGHT/2)) / FONT_HEIGHT) * FONT_HEIGHT) -// static void SizeRichEdit(int a) -// { -// RECT r; -// GetClientRect(HelpDialog[a], &r); - -// SetWindowPos(RichEdit[a], HWND_TOP, 6, 3, r.right - 6, -// RICH_EDIT_HEIGHT(r.bottom), 0); -// } +static void SizeRichEdit(int a) +{ + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (RichEdit[a]), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_ALWAYS); + gtk_widget_set_hexpand(GTK_WIDGET(RichEdit[a]), TRUE); + gtk_widget_set_vexpand(GTK_WIDGET(RichEdit[a]), TRUE); +} // static BOOL Resizing(RECT *r, int wParam) // { @@ -142,80 +150,85 @@ static int TitleHeight; // return !touched; // } -// static void MakeControls(int a) -// { -// HMODULE re = LoadLibrary("RichEd20.dll"); -// if(!re) oops(); - -// RichEdit[a] = CreateWindowEx(0, RICHEDIT_CLASS, -// "", WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | ES_READONLY | -// ES_MULTILINE | WS_VSCROLL, -// 0, 0, 100, 100, HelpDialog[a], NULL, Instance, NULL); - -// SendMessage(RichEdit[a], WM_SETFONT, (WPARAM)FixedWidthFont, TRUE); -// SendMessage(RichEdit[a], EM_SETBKGNDCOLOR, (WPARAM)0, RGB(0, 0, 0)); - -// SizeRichEdit(a); - -// int i; -// BOOL nextSubHead = FALSE; -// for(i = 0; Text[a][i]; i++) { -// char *s = Text[a][i]; - -// CHARFORMAT cf; -// cf.cbSize = sizeof(cf); -// cf.dwMask = CFM_BOLD | CFM_COLOR; -// cf.dwEffects = 0; -// if((s[0] == '=') || -// (Text[a][i+1] && Text[a][i+1][0] == '=')) -// { -// cf.crTextColor = RGB(255, 255, 110); -// } else if(s[3] == '|' && s[4] == '|') { -// cf.crTextColor = RGB(255, 110, 255); -// } else if(s[0] == '>' || nextSubHead) { -// // Need to make a copy because the strings we are passed aren't -// // mutable. -// char copy[1024]; -// if(strlen(s) >= sizeof(copy)) oops(); -// strcpy(copy, s); - -// int j; -// for(j = 1; copy[j]; j++) { -// if(copy[j] == ' ' && copy[j-1] == ' ') -// break; -// } -// BOOL justHeading = (copy[j] == '\0'); -// copy[j] = '\0'; -// cf.crTextColor = RGB(110, 255, 110); -// SendMessage(RichEdit[a], EM_SETCHARFORMAT, SCF_SELECTION, -// (LPARAM)&cf); -// SendMessage(RichEdit[a], EM_REPLACESEL, (WPARAM)FALSE, -// (LPARAM)copy); -// SendMessage(RichEdit[a], EM_SETSEL, (WPARAM)-1, (LPARAM)-1); +static void MakeControls(int a) +{ + // HMODULE re = LoadLibrary("RichEd20.dll"); + // if(!re) oops(); + + RichEdit[a] = gtk_scrolled_window_new (NULL, NULL); + TextView = gtk_text_view_new (); + TextBuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (TextView)); + gtk_text_view_set_editable (GTK_TEXT_VIEW (TextView), FALSE); + SizeRichEdit(a); + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (TextView), GTK_WRAP_WORD); + gtk_text_buffer_get_start_iter (TextBuffer, TextIter); + // COLORREF color; + // gtk_text_buffer_create_tag (TextBuffer, "ForegroundColor1", + // "foreground", "blue"); + + int i; + BOOL nextSubHead = FALSE; + for(i = 0; Text[a][i]; i++) { + char *s = Text[a][i]; + gtk_text_buffer_get_iter_at_offset (TextBuffer, TextIter, -1); + + if((s[0] == '=') || + (Text[a][i+1] && Text[a][i+1][0] == '=')) + { + COLORREF color = RGB(255, 255, 110); + // gtk_widget_override_color (TextView, GTK_STATE_FLAG_NORMAL, &color); -// // Special case if there's nothing except title on the line -// if(!justHeading) { -// copy[j] = ' '; -// } -// s += j; -// cf.crTextColor = RGB(255, 110, 255); -// nextSubHead = !nextSubHead; -// } else { -// cf.crTextColor = RGB(255, 255, 255); -// } - -// SendMessage(RichEdit[a], EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); -// SendMessage(RichEdit[a], EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)s); -// SendMessage(RichEdit[a], EM_SETSEL, (WPARAM)-1, (LPARAM)-1); - -// if(Text[a][i+1]) { -// SendMessage(RichEdit[a], EM_REPLACESEL, FALSE, (LPARAM)"\r\n"); -// SendMessage(RichEdit[a], EM_SETSEL, (WPARAM)-1, (LPARAM)-1); -// } -// } - -// SendMessage(RichEdit[a], EM_SETSEL, (WPARAM)0, (LPARAM)0); -// } + } + else if(s[3] == '|' && s[4] == '|') { + // COLORREF color = RGB(255, 110, 255); + // gtk_widget_override_color (TextView, GTK_STATE_FLAG_NORMAL, &color); + } + else if(s[0] == '>' || nextSubHead) { + // Need to make a copy because the strings we are passed aren't + // mutable. + char copy[1024]; + if(strlen(s) >= sizeof(copy)) oops(); + strcpy(copy, s); + + int j; + for(j = 1; copy[j]; j++) { + if(copy[j] == ' ' && copy[j-1] == ' ') + break; + } + BOOL justHeading = (copy[j] == '\0'); + copy[j] = '\0'; + COLORREF color = RGB(110, 255, 110); + // gtk_widget_override_color (TextView, GTK_STATE_FLAG_NORMAL, &color); + gtk_text_buffer_insert (TextBuffer, TextIter, copy, -1); + gtk_text_buffer_get_iter_at_offset (TextBuffer, TextIter, -1); + + // Special case if there's nothing except title on the line + if(!justHeading) { + copy[j] = ' '; + } + s += j; + // color = RGB(255, 110, 255); + // gtk_widget_override_color (TextView, GTK_STATE_FLAG_NORMAL, &color); + nextSubHead = !nextSubHead; + } + else { + COLORREF color = RGB(255, 255, 255); + gtk_widget_override_color (TextView, GTK_STATE_FLAG_NORMAL, &color); + } + + // gtk_text_buffer_insert_with_tags_by_name (TextBuffer, TextIter, + // s, -1, "ForegroundColor1", NULL); + gtk_text_buffer_insert (TextBuffer, TextIter, s, -1); + + if(Text[a][i+1]) { + gtk_text_buffer_insert (TextBuffer, TextIter, "\n", -1); + } + } + gtk_widget_override_background_color (TextView, GTK_STATE_FLAG_NORMAL, + ((HBRUSH)GetStockObject(BLACK_BRUSH))); + gtk_container_add (GTK_CONTAINER(RichEdit[a]), TextView); + +} //----------------------------------------------------------------------------- // Window proc for the help dialog. @@ -253,8 +266,8 @@ static int TitleHeight; //----------------------------------------------------------------------------- // Create the class for the help window. //----------------------------------------------------------------------------- -// static void MakeClass(void) -// { +static void MakeClass(void) +{ // WNDCLASSEX wc; // memset(&wc, 0, sizeof(wc)); // wc.cbSize = sizeof(wc); @@ -263,7 +276,6 @@ static int TitleHeight; // CS_DBLCLKS; // wc.lpfnWndProc = (WNDPROC)HelpProc; // wc.hInstance = Instance; -// wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // wc.lpszClassName = "LDmicroHelp"; // wc.lpszMenuName = NULL; // wc.hCursor = LoadCursor(NULL, IDC_ARROW); @@ -272,37 +284,34 @@ static int TitleHeight; // wc.hIconSm = (HICON)LoadImage(Instance, MAKEINTRESOURCE(4000), // IMAGE_ICON, 16, 16, 0); -// RegisterClassEx(&wc); -// } -// void ShowHelpDialog(BOOL about) -// { -// int a = about ? 1 : 0; -// if(HelpWindowOpen[a]) { -// SetForegroundWindow(HelpDialog[a]); -// return; -// } +// RegisterClassEx(&wc); +} -// MakeClass(); +void ShowHelpDialog(BOOL about) +{ + int a = about ? 1 : 0; + + MakeClass(); -// char *s = about ? "About LDmicro" : "LDmicro Help"; -// HelpDialog[a] = CreateWindowEx(0, "LDmicroHelp", s, -// WS_OVERLAPPED | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | -// WS_SIZEBOX, -// 100, 100, 650, 300+10*FONT_HEIGHT, NULL, NULL, Instance, NULL); -// MakeControls(a); - -// ShowWindow(HelpDialog[a], TRUE); -// SetFocus(RichEdit[a]); + const char *s = about ? "About LDmicro" : "LDmicro Help"; -// HelpWindowOpen[a] = TRUE; + MakeControls(a); -// RECT r; -// GetClientRect(HelpDialog[a], &r); -// TitleHeight = 300 - r.bottom; + PackBoxHelp = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_box_pack_start(GTK_BOX(PackBoxHelp), RichEdit[a], FALSE, TRUE, 0); -// GetWindowRect(HelpDialog[a], &r); -// Resizing(&r, WMSZ_TOP); -// SetWindowPos(HelpDialog[a], HWND_TOP, r.left, r.top, r.right - r.left, -// r.bottom - r.top, 0); -// } + HelpDialog[a] = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_default_size(GTK_WINDOW(HelpDialog[a]), 650, 300+10*FONT_HEIGHT); + gtk_window_set_title(GTK_WINDOW(HelpDialog[a]), s); + gtk_container_add(GTK_CONTAINER(HelpDialog[a]), PackBoxHelp); + + gtk_widget_show_all (HelpDialog[a]); + gtk_widget_grab_focus (RichEdit[a]); + + if(HelpWindowOpen[a]) { + gtk_widget_grab_focus (HelpDialog[a]); + return; + } + HelpWindowOpen[a] = TRUE; +} diff --git a/ldmicro/includes/ldmicro.h b/ldmicro/includes/ldmicro.h index e69adb4..8bf490f 100644 --- a/ldmicro/includes/ldmicro.h +++ b/ldmicro/includes/ldmicro.h @@ -51,79 +51,151 @@ typedef signed long SDWORD; #define NUM_SUPPORTED_MCUS 16 // Menu IDs -extern HMENU MNU_NEW; -extern HMENU MNU_OPEN; -extern HMENU MNU_SAVE; -extern HMENU MNU_SAVE_AS; -extern HMENU MNU_EXPORT; -extern HMENU MNU_EXIT; - -extern HMENU MNU_UNDO; -extern HMENU MNU_REDO; -extern HMENU MNU_PUSH_RUNG_UP; -extern HMENU MNU_PUSH_RUNG_DOWN; -extern HMENU MNU_INSERT_RUNG_BEFORE; -extern HMENU MNU_INSERT_RUNG_AFTER; -extern HMENU MNU_DELETE_ELEMENT; -extern HMENU MNU_DELETE_RUNG; - -extern HMENU MNU_INSERT_COMMENT; -extern HMENU MNU_INSERT_CONTACTS; -extern HMENU MNU_INSERT_COIL; -extern HMENU MNU_INSERT_TON; -extern HMENU MNU_INSERT_TOF; -extern HMENU MNU_INSERT_RTO; -extern HMENU MNU_INSERT_RES; -extern HMENU MNU_INSERT_OSR; -extern HMENU MNU_INSERT_OSF; -extern HMENU MNU_INSERT_CTU; -extern HMENU MNU_INSERT_CTD; -extern HMENU MNU_INSERT_CTC; -extern HMENU MNU_INSERT_ADD; -extern HMENU MNU_INSERT_SUB; -extern HMENU MNU_INSERT_MUL; -extern HMENU MNU_INSERT_DIV; -extern HMENU MNU_INSERT_MOV; -extern HMENU MNU_INSERT_READ_ADC; -extern HMENU MNU_INSERT_SET_PWM; -extern HMENU MNU_INSERT_UART_SEND; -extern HMENU MNU_INSERT_UART_RECV; -extern HMENU MNU_INSERT_EQU; -extern HMENU MNU_INSERT_NEQ; -extern HMENU MNU_INSERT_GRT; -extern HMENU MNU_INSERT_GEQ; -extern HMENU MNU_INSERT_LES; -extern HMENU MNU_INSERT_LEQ; -extern HMENU MNU_INSERT_OPEN; -extern HMENU MNU_INSERT_SHORT; -extern HMENU MNU_INSERT_MASTER_RLY; -extern HMENU MNU_INSERT_SHIFT_REG; -extern HMENU MNU_INSERT_LUT; -extern HMENU MNU_INSERT_FMTD_STR; -extern HMENU MNU_INSERT_PERSIST; -extern HMENU MNU_MAKE_NORMAL; -extern HMENU MNU_NEGATE; -extern HMENU MNU_MAKE_SET_ONLY; -extern HMENU MNU_MAKE_RESET_ONLY; -extern HMENU MNU_INSERT_PWL; - -extern HMENU MNU_MCU_SETTINGS; -extern HMENU MNU_PROCESSOR[NUM_SUPPORTED_MCUS+1]; -extern HMENU MNU_MICRO_CONTROLLER; - -extern HMENU MNU_SIMULATION_MODE; -extern HMENU MNU_START_SIMULATION; -extern HMENU MNU_STOP_SIMULATION; -extern HMENU MNU_SINGLE_CYCLE; - -extern HMENU MNU_COMPILE; -extern HMENU MNU_COMPILE_AS; - -extern HMENU MNU_MANUAL; -extern HMENU MNU_ABOUT; - -extern HMENU MNU_ADV_SIMULATION; - +#define MNU_NEW 0x01 +#define MNU_OPEN 0x02 +#define MNU_SAVE 0x03 +#define MNU_SAVE_AS 0x04 +#define MNU_EXPORT 0x05 +#define MNU_EXIT 0x06 + +#define MNU_UNDO 0x10 +#define MNU_REDO 0x11 +#define MNU_PUSH_RUNG_UP 0x12 +#define MNU_PUSH_RUNG_DOWN 0x13 +#define MNU_INSERT_RUNG_BEFORE 0x14 +#define MNU_INSERT_RUNG_AFTER 0x15 +#define MNU_DELETE_ELEMENT 0x16 +#define MNU_DELETE_RUNG 0x17 + +#define MNU_INSERT_COMMENT 0x20 +#define MNU_INSERT_CONTACTS 0x21 +#define MNU_INSERT_COIL 0x22 +#define MNU_INSERT_TON 0x23 +#define MNU_INSERT_TOF 0x24 +#define MNU_INSERT_RTO 0x25 +#define MNU_INSERT_RES 0x26 +#define MNU_INSERT_OSR 0x27 +#define MNU_INSERT_OSF 0x28 +#define MNU_INSERT_CTU 0x29 +#define MNU_INSERT_CTD 0x2a +#define MNU_INSERT_CTC 0x2b +#define MNU_INSERT_ADD 0x2c +#define MNU_INSERT_SUB 0x2d +#define MNU_INSERT_MUL 0x2e +#define MNU_INSERT_DIV 0x2f +#define MNU_INSERT_MOV 0x30 +#define MNU_INSERT_READ_ADC 0x31 +#define MNU_INSERT_SET_PWM 0x32 +#define MNU_INSERT_UART_SEND 0x33 +#define MNU_INSERT_UART_RECV 0x34 +#define MNU_INSERT_EQU 0x35 +#define MNU_INSERT_NEQ 0x36 +#define MNU_INSERT_GRT 0x37 +#define MNU_INSERT_GEQ 0x38 +#define MNU_INSERT_LES 0x39 +#define MNU_INSERT_LEQ 0x3a +#define MNU_INSERT_OPEN 0x3b +#define MNU_INSERT_SHORT 0x3c +#define MNU_INSERT_MASTER_RLY 0x3d +#define MNU_INSERT_SHIFT_REG 0x3e +#define MNU_INSERT_LUT 0x3f +#define MNU_INSERT_FMTD_STR 0x40 +#define MNU_INSERT_PERSIST 0x41 +#define MNU_MAKE_NORMAL 0x42 +#define MNU_NEGATE 0x43 +#define MNU_MAKE_SET_ONLY 0x44 +#define MNU_MAKE_RESET_ONLY 0x45 +#define MNU_INSERT_PWL 0x46 + +#define MNU_MCU_SETTINGS 0x50 +#define MNU_PROCESSOR_0 0xa0 + +#define MNU_SIMULATION_MODE 0x60 +#define MNU_START_SIMULATION 0x61 +#define MNU_STOP_SIMULATION 0x62 +#define MNU_SINGLE_CYCLE 0x63 + +#define MNU_COMPILE 0x70 +#define MNU_COMPILE_AS 0x71 + +#define MNU_MANUAL 0x80 +#define MNU_ABOUT 0x81 + +// #define MNU_ADV_SIMULATION + +// New menu items here +extern HMENU NewMenu; +extern HMENU OpenMenu; +extern HMENU SaveMenu; +extern HMENU SaveAsMenu; +extern HMENU ExportMenu; +extern HMENU ExitMenu; + +extern HMENU UndoMenu; +extern HMENU RedoMenu; +extern HMENU PushRungUpMenu; +extern HMENU PushRungDownMenu; +extern HMENU InsertRungBeforeMenu; +extern HMENU InsertRungAfterMenu; +extern HMENU DeleteElementMenu; +extern HMENU DeleteRungMenu; + +extern HMENU InsertCommentMenu; +extern HMENU InsertContactsMenu; +extern HMENU InsertCoilMenu; +extern HMENU InsertTonMenu; +extern HMENU InsertTofMenu; +extern HMENU InsertRtoMenu; +extern HMENU InsertResMenu; +extern HMENU InsertOsrMenu; +extern HMENU InsertOsfMenu; +extern HMENU InsertCtuMenu; +extern HMENU InsertCtdMenu; +extern HMENU InsertCtcMenu; +extern HMENU InsertAddMenu; +extern HMENU InsertSubMenu; +extern HMENU InsertMulMenu; +extern HMENU InsertDivMenu; +extern HMENU InsertMovMenu; +extern HMENU InsertReadAdcMenu; +extern HMENU InsertSetPwmMenu; +extern HMENU InsertUartSendMenu; +extern HMENU InsertUartRecvMenu; +extern HMENU InsertEquMenu; +extern HMENU InsertNeqMenu; +extern HMENU InsertGrtMenu; +extern HMENU InsertGeqMenu; +extern HMENU InsertLesMenu; +extern HMENU InsertLeqMenu; +extern HMENU InsertOpenMenu; +extern HMENU InsertShortMenu; +extern HMENU InsertMasterRlyMenu; +extern HMENU InsertShiftRegMenu; +extern HMENU InsertLutMenu; +extern HMENU InsertFmtdStrMenu; +extern HMENU InsertPersistMenu; +extern HMENU MakeNormalMenu; +extern HMENU NegateMenu; +extern HMENU MakeSetOnlyMenu; +extern HMENU MakeResetOnlyMenu; +extern HMENU InsertPwlMenu; + +extern HMENU McuSettingsMenu; +extern HMENU ProcessorMenuItems[NUM_SUPPORTED_MCUS+1]; +extern HMENU MicroControllerMenu; + +extern HMENU SimulationModeMenu; +extern HMENU StartSimulationMenu; +extern HMENU StopSimulationMenu; +extern HMENU SingleCycleMenu; + +extern HMENU CompileMenu; +extern HMENU CompileAsMenu; + +extern HMENU ManualMenu; +extern HMENU AboutMenu; + +// extern HMENU MNU_ADV_SIMULATION; // Columns within the I/O etc. listview. #define LV_IO_NAME 0x00 @@ -517,7 +589,6 @@ void RefreshScrollbars(void); extern HINSTANCE Instance; extern HWID MainWindow; extern HWID DrawWindow; -extern HCRDC Hdc; extern PlcProgram Prog; extern char CurrentSaveFile[MAX_PATH]; extern char CurrentCompileFile[MAX_PATH]; @@ -532,8 +603,8 @@ void CheckHeap(char *file, int line); // maincontrols.cpp void MakeMainWindowControls(void); HMENU MakeMainWindowMenus(void); -void VscrollProc(WPARAM wParam); -void HscrollProc(WPARAM wParam); +void VscrollProc(int wParam); +void HscrollProc(int wParam); void GenerateIoListDontLoseSelection(void); void RefreshControlsToSettings(void); void MainWindowResized(void); @@ -547,20 +618,21 @@ extern BOOL NeedHoriz; extern HLIST IoList; extern int IoListTop; extern int IoListHeight; +extern HMENU ScrollWindow; // draw.cpp int ProgCountWidestRow(void); int CountHeightOfElement(int which, void *elem); -BOOL DrawElement(int which, void *elem, int *cx, int *cy, BOOL poweredBefore); -void DrawEndRung(int cx, int cy); +BOOL DrawElement(HCRDC Hcr, int which, void *elem, int *cx, int *cy, BOOL poweredBefore); +void DrawEndRung(HCRDC Hcr, int cx, int cy); extern int ColsAvailable; extern BOOL SelectionActive; extern BOOL ThisHighlighted; // draw_outputdev.cpp -extern void (*DrawChars)(int, int, const char *); -void CALLBACK BlinkCursor(HWND hwnd, UINT msg, UINT_PTR id, DWORD time); -void PaintWindow(); +extern void (*DrawChars)(HCRDC Hcr, int, int, const char *); +BOOL BlinkCursor(BOOL kill); +void PaintWindow(HCRDC Hcr); void ExportDrawingAsText(char *file); void InitForDrawing(void); void SetUpScrollbars(BOOL *horizShown, SCROLLINFO *horiz, SCROLLINFO *vert); @@ -708,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); @@ -732,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 e878eae..be02fd5 100644 --- a/ldmicro/ldmicro.cpp +++ b/ldmicro/ldmicro.cpp @@ -31,12 +31,15 @@ #include "ldmicro.h" #include "freezeLD.h" #include "mcutable.h" +#include <iomanip> +#include <iostream> + +using namespace std; HINSTANCE Instance; HWID MainWindow; HWID DrawWindow; -HCRDC Hdc; // parameters used to capture the mouse when implementing our totally non- // general splitter control @@ -62,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 @@ -147,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; @@ -171,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; @@ -186,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; @@ -196,7 +203,8 @@ static void CompileProgram(BOOL compileAs) default: oops(); } - IntDumpListing("t.pl"); + + IntDumpListing("t.pl"); } //----------------------------------------------------------------------------- @@ -204,87 +212,88 @@ 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 // changed so that we ask if user wants to save before exiting, and update // the I/O list. //----------------------------------------------------------------------------- -// void ProgramChanged(void) -// { -// ProgramChangedNotSaved = TRUE; -// GenerateIoListDontLoseSelection(); -// RefreshScrollbars(); -// } -// #define CHANGING_PROGRAM(x) { \ -// UndoRemember(); \ -// x; \ -// ProgramChanged(); \ -// } +void ProgramChanged(void) +{ + ProgramChangedNotSaved = TRUE; + GenerateIoListDontLoseSelection(); + RefreshScrollbars(); +} +#define CHANGING_PROGRAM(x) { \ + UndoRemember(); \ + x; \ + ProgramChanged();\ + } //----------------------------------------------------------------------------- // Hook that we install when the user starts dragging the `splitter,' in case @@ -323,326 +332,380 @@ static void CompileProgram(BOOL compileAs) //----------------------------------------------------------------------------- // Handle a selection from the menu bar of the main window. //----------------------------------------------------------------------------- -// static void ProcessMenu(int code) -// { -// if(code >= MNU_PROCESSOR_0 && code < MNU_PROCESSOR_0+NUM_SUPPORTED_MCUS) { -// strcpy(CurrentCompileFile, ""); -// Prog.mcu = &SupportedMcus[code - MNU_PROCESSOR_0]; -// RefreshControlsToSettings(); -// return; -// } -// if(code == MNU_PROCESSOR_0+NUM_SUPPORTED_MCUS) { -// Prog.mcu = NULL; -// strcpy(CurrentCompileFile, ""); -// RefreshControlsToSettings(); -// return; -// } +static void ProcessMenu(int code) +{ + if(code >= MNU_PROCESSOR_0 && code < MNU_PROCESSOR_0+NUM_SUPPORTED_MCUS) { + strcpy(CurrentCompileFile, ""); + Prog.mcu = &SupportedMcus[code - MNU_PROCESSOR_0]; + RefreshControlsToSettings(); + return; + } + if(code == MNU_PROCESSOR_0+NUM_SUPPORTED_MCUS) { + Prog.mcu = NULL; + strcpy(CurrentCompileFile, ""); + RefreshControlsToSettings(); + return; + } -// switch(code) { -// case MNU_NEW: -// if(CheckSaveUserCancels()) break; -// NewProgram(); -// strcpy(CurrentSaveFile, ""); -// strcpy(CurrentCompileFile, ""); -// GenerateIoListDontLoseSelection(); -// RefreshScrollbars(); -// UpdateMainWindowTitleBar(); -// break; + switch(code) { + case MNU_NEW: + if(CheckSaveUserCancels()) break; + NewProgram(); + strcpy(CurrentSaveFile, ""); + strcpy(CurrentCompileFile, ""); + GenerateIoListDontLoseSelection(); + RefreshScrollbars(); + UpdateMainWindowTitleBar(); + break; -// case MNU_OPEN: -// if(CheckSaveUserCancels()) break; -// OpenDialog(); -// break; + case MNU_OPEN: + if(CheckSaveUserCancels()) break; + OpenDialog(); + break; -// case MNU_SAVE: -// SaveProgram(); -// UpdateMainWindowTitleBar(); -// break; + case MNU_SAVE: + SaveProgram(); + UpdateMainWindowTitleBar(); + break; -// case MNU_SAVE_AS: -// SaveAsDialog(); -// UpdateMainWindowTitleBar(); -// break; + case MNU_SAVE_AS: + SaveAsDialog(); + UpdateMainWindowTitleBar(); + break; -// case MNU_EXPORT: -// ExportDialog(); -// break; + case MNU_EXPORT: + ExportDialog(); + break; -// case MNU_EXIT: -// if(CheckSaveUserCancels()) break; -// PostQuitMessage(0); -// break; + case MNU_EXIT: + if(CheckSaveUserCancels()) break; + LD_WM_Close_call(NULL, NULL, NULL); + // PostQuitMessage(0); + break; -// case MNU_INSERT_COMMENT: -// CHANGING_PROGRAM(AddComment(_("--add comment here--"))); -// break; + case MNU_INSERT_COMMENT: + CHANGING_PROGRAM(AddComment(_("--add comment here--"))); + break; -// case MNU_INSERT_CONTACTS: -// CHANGING_PROGRAM(AddContact()); -// break; + case MNU_INSERT_CONTACTS: + CHANGING_PROGRAM(AddContact()); + break; -// case MNU_INSERT_COIL: -// CHANGING_PROGRAM(AddCoil()); -// break; + case MNU_INSERT_COIL: + CHANGING_PROGRAM(AddCoil()); + break; -// case MNU_INSERT_TON: -// CHANGING_PROGRAM(AddTimer(ELEM_TON)); -// break; + case MNU_INSERT_TON: + CHANGING_PROGRAM(AddTimer(ELEM_TON)); + break; -// case MNU_INSERT_TOF: -// CHANGING_PROGRAM(AddTimer(ELEM_TOF)); -// break; + case MNU_INSERT_TOF: + CHANGING_PROGRAM(AddTimer(ELEM_TOF)); + break; -// case MNU_INSERT_RTO: -// CHANGING_PROGRAM(AddTimer(ELEM_RTO)); -// break; + case MNU_INSERT_RTO: + CHANGING_PROGRAM(AddTimer(ELEM_RTO)); + break; -// case MNU_INSERT_CTU: -// CHANGING_PROGRAM(AddCounter(ELEM_CTU)); -// break; + case MNU_INSERT_CTU: + CHANGING_PROGRAM(AddCounter(ELEM_CTU)); + break; -// case MNU_INSERT_CTD: -// CHANGING_PROGRAM(AddCounter(ELEM_CTD)); -// break; + case MNU_INSERT_CTD: + CHANGING_PROGRAM(AddCounter(ELEM_CTD)); + break; -// case MNU_INSERT_CTC: -// CHANGING_PROGRAM(AddCounter(ELEM_CTC)); -// break; + case MNU_INSERT_CTC: + CHANGING_PROGRAM(AddCounter(ELEM_CTC)); + break; -// case MNU_INSERT_RES: -// CHANGING_PROGRAM(AddReset()); -// break; + case MNU_INSERT_RES: + CHANGING_PROGRAM(AddReset()); + break; -// case MNU_INSERT_OPEN: -// CHANGING_PROGRAM(AddEmpty(ELEM_OPEN)); -// break; + case MNU_INSERT_OPEN: + CHANGING_PROGRAM(AddEmpty(ELEM_OPEN)); + break; -// case MNU_INSERT_SHORT: -// CHANGING_PROGRAM(AddEmpty(ELEM_SHORT)); -// break; + case MNU_INSERT_SHORT: + CHANGING_PROGRAM(AddEmpty(ELEM_SHORT)); + break; -// case MNU_INSERT_MASTER_RLY: -// CHANGING_PROGRAM(AddMasterRelay()); -// break; + case MNU_INSERT_MASTER_RLY: + CHANGING_PROGRAM(AddMasterRelay()); + break; -// case MNU_INSERT_SHIFT_REG: -// CHANGING_PROGRAM(AddShiftRegister()); -// break; + case MNU_INSERT_SHIFT_REG: + CHANGING_PROGRAM(AddShiftRegister()); + break; -// case MNU_INSERT_LUT: -// CHANGING_PROGRAM(AddLookUpTable()); -// break; + case MNU_INSERT_LUT: + CHANGING_PROGRAM(AddLookUpTable()); + break; -// case MNU_INSERT_PWL: -// CHANGING_PROGRAM(AddPiecewiseLinear()); -// break; + case MNU_INSERT_PWL: + CHANGING_PROGRAM(AddPiecewiseLinear()); + break; -// case MNU_INSERT_FMTD_STR: -// CHANGING_PROGRAM(AddFormattedString()); -// break; + case MNU_INSERT_FMTD_STR: + CHANGING_PROGRAM(AddFormattedString()); + break; -// case MNU_INSERT_OSR: -// CHANGING_PROGRAM(AddEmpty(ELEM_ONE_SHOT_RISING)); -// break; + case MNU_INSERT_OSR: + CHANGING_PROGRAM(AddEmpty(ELEM_ONE_SHOT_RISING)); + break; -// case MNU_INSERT_OSF: -// CHANGING_PROGRAM(AddEmpty(ELEM_ONE_SHOT_FALLING)); -// break; + case MNU_INSERT_OSF: + CHANGING_PROGRAM(AddEmpty(ELEM_ONE_SHOT_FALLING)); + break; -// case MNU_INSERT_MOV: -// CHANGING_PROGRAM(AddMove()); -// break; + case MNU_INSERT_MOV: + CHANGING_PROGRAM(AddMove()); + break; -// case MNU_INSERT_SET_PWM: -// CHANGING_PROGRAM(AddSetPwm()); -// break; + case MNU_INSERT_SET_PWM: + CHANGING_PROGRAM(AddSetPwm()); + break; -// case MNU_INSERT_READ_ADC: -// CHANGING_PROGRAM(AddReadAdc()); -// break; + case MNU_INSERT_READ_ADC: + CHANGING_PROGRAM(AddReadAdc()); + break; -// case MNU_INSERT_UART_SEND: -// CHANGING_PROGRAM(AddUart(ELEM_UART_SEND)); -// break; + case MNU_INSERT_UART_SEND: + CHANGING_PROGRAM(AddUart(ELEM_UART_SEND)); + break; -// case MNU_INSERT_UART_RECV: -// CHANGING_PROGRAM(AddUart(ELEM_UART_RECV)); -// break; + case MNU_INSERT_UART_RECV: + CHANGING_PROGRAM(AddUart(ELEM_UART_RECV)); + break; -// case MNU_INSERT_PERSIST: -// CHANGING_PROGRAM(AddPersist()); -// break; + case MNU_INSERT_PERSIST: + 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; -// } - -// case MNU_MAKE_NORMAL: -// CHANGING_PROGRAM(MakeNormalSelected()); -// 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()); + break; -// case MNU_NEGATE: -// CHANGING_PROGRAM(NegateSelected()); -// break; + case MNU_NEGATE: + CHANGING_PROGRAM(NegateSelected()); + break; -// case MNU_MAKE_SET_ONLY: -// CHANGING_PROGRAM(MakeSetOnlySelected()); -// break; + case MNU_MAKE_SET_ONLY: + CHANGING_PROGRAM(MakeSetOnlySelected()); + break; -// case MNU_MAKE_RESET_ONLY: -// CHANGING_PROGRAM(MakeResetOnlySelected()); -// break; + case MNU_MAKE_RESET_ONLY: + CHANGING_PROGRAM(MakeResetOnlySelected()); + break; -// case MNU_UNDO: -// UndoUndo(); -// break; + case MNU_UNDO: + UndoUndo(); + break; -// case MNU_REDO: -// UndoRedo(); -// break; + case MNU_REDO: + UndoRedo(); + break; -// case MNU_INSERT_RUNG_BEFORE: -// CHANGING_PROGRAM(InsertRung(FALSE)); -// break; + case MNU_INSERT_RUNG_BEFORE: + CHANGING_PROGRAM(InsertRung(FALSE)); + break; -// case MNU_INSERT_RUNG_AFTER: -// CHANGING_PROGRAM(InsertRung(TRUE)); -// break; + case MNU_INSERT_RUNG_AFTER: + CHANGING_PROGRAM(InsertRung(TRUE)); + break; -// case MNU_DELETE_RUNG: -// CHANGING_PROGRAM(DeleteSelectedRung()); -// break; + case MNU_DELETE_RUNG: + CHANGING_PROGRAM(DeleteSelectedRung()); + break; -// case MNU_PUSH_RUNG_UP: -// CHANGING_PROGRAM(PushRungUp()); -// break; + case MNU_PUSH_RUNG_UP: + CHANGING_PROGRAM(PushRungUp()); + break; -// case MNU_PUSH_RUNG_DOWN: -// CHANGING_PROGRAM(PushRungDown()); -// break; + case MNU_PUSH_RUNG_DOWN: + CHANGING_PROGRAM(PushRungDown()); + break; -// case MNU_DELETE_ELEMENT: -// CHANGING_PROGRAM(DeleteSelectedFromProgram()); -// break; + case MNU_DELETE_ELEMENT: + CHANGING_PROGRAM(DeleteSelectedFromProgram()); + break; -// case MNU_MCU_SETTINGS: -// CHANGING_PROGRAM(ShowConfDialog()); -// break; + case MNU_MCU_SETTINGS: + CHANGING_PROGRAM(ShowConfDialog()); + break; -// case MNU_SIMULATION_MODE: -// ToggleSimulationMode(); -// break; + case MNU_SIMULATION_MODE: + ToggleSimulationMode(); + break; -// case MNU_START_SIMULATION: -// StartSimulation(); -// break; + case MNU_START_SIMULATION: + StartSimulation(); + break; -// case MNU_STOP_SIMULATION: -// StopSimulation(); -// break; + case MNU_STOP_SIMULATION: + StopSimulation(); + break; -// case MNU_SINGLE_CYCLE: -// SimulateOneCycle(TRUE); -// break; + case MNU_SINGLE_CYCLE: + SimulateOneCycle(TRUE); + break; -// case MNU_COMPILE: -// CompileProgram(FALSE); -// break; + case MNU_COMPILE: + CompileProgram(FALSE); + break; -// case MNU_COMPILE_AS: -// CompileProgram(TRUE); -// break; + case MNU_COMPILE_AS: + CompileProgram(TRUE); + break; -// case MNU_MANUAL: -// ShowHelpDialog(FALSE); -// break; + case MNU_MANUAL: + ShowHelpDialog(FALSE); + break; -// case MNU_ABOUT: -// ShowHelpDialog(TRUE); -// break; -// } -// } + case MNU_ABOUT: + ShowHelpDialog(TRUE); + break; + } + gtk_widget_queue_draw(DrawWindow); +} //----------------------------------------------------------------------------- -// WndProc for MainWindow. +// WndProc functions for MainWindow. //----------------------------------------------------------------------------- -LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - // switch (msg) { - // case WM_ERASEBKGND: - // break; - - // case WM_SETFOCUS: - - // case WM_PAINT: { - // } - - // case WM_KEYDOWN: { - // } +gboolean LD_WM_KeyDown_call(GtkWidget *widget, GdkEventKey *event, gpointer user_data) +{ + /* Handles: + * WM_KEYDOWN + */ - // case WM_LBUTTONDBLCLK: { - // } + UINT wParam = event->keyval; - // case WM_LBUTTONDOWN: { - // } - // case WM_MOUSEMOVE: { - // } - // case WM_MOUSEWHEEL: { - // } + if(wParam == VK_TAB) { + // SetFocus(IoList); + gtk_window_set_focus (GTK_WINDOW(MainWindow), view); + // BlinkCursor(0, 0, 0, 0); + + } - // case WM_SIZE: + if(InSimulationMode) + { + switch(wParam) + { + case VK_DOWN: + if(ScrollYOffset < ScrollYOffsetMax) + ScrollYOffset++; + RefreshScrollbars(); + gtk_widget_queue_draw(DrawWindow); + break; + + case VK_UP: + if(ScrollYOffset > 0) + ScrollYOffset--; + RefreshScrollbars(); + gtk_widget_queue_draw(DrawWindow); + break; + + case VK_LEFT: + ScrollXOffset -= FONT_WIDTH; + if(ScrollXOffset < 0) + ScrollXOffset = 0; + RefreshScrollbars(); + gtk_widget_queue_draw(DrawWindow); + break; + + case VK_RIGHT: + ScrollXOffset += FONT_WIDTH; + if(ScrollXOffset >= ScrollXOffsetMax) + ScrollXOffset = ScrollXOffsetMax; + RefreshScrollbars(); + gtk_widget_queue_draw(DrawWindow); + break; + + case VK_RETURN: + case VK_ESCAPE: + ToggleSimulationMode(); + break; + } + } - // case WM_NOTIFY: { - // NMHDR *h = (NMHDR *)lParam; - // if(h->hwndFrom == IoList) { - // IoListProc(h); - // } - // return 0; - // } - // case WM_VSCROLL: + switch(wParam) + { + case VK_UP: + if(event->state & GDK_SHIFT_MASK) + { + CHANGING_PROGRAM(PushRungUp()); + } + else + { + MoveCursorKeyboard(wParam); + } + + gtk_widget_queue_draw(DrawWindow); + break; - // case WM_HSCROLL: + case VK_DOWN: + if(event->state & GDK_SHIFT_MASK) + { + CHANGING_PROGRAM(PushRungDown()); + } + else + { + MoveCursorKeyboard(wParam); + } + + gtk_widget_queue_draw(DrawWindow); + break; - // case WM_COMMAND: - // ProcessMenu(LOWORD(wParam)); - // InvalidateRect(MainWindow, NULL, FALSE); - // break; + case VK_RIGHT: + case VK_LEFT: + MoveCursorKeyboard(wParam); + gtk_widget_queue_draw(DrawWindow); + break; - // case WM_CLOSE: - // case WM_DESTROY: + case VK_RETURN: + CHANGING_PROGRAM(EditSelectedElement()); + gtk_widget_queue_draw(DrawWindow); + break; - // default: - // return DefWindowProc(hwnd, msg, wParam, lParam); - // } + default: + break; + } - return 1; + return FALSE; } -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(); FreezeWindowPos(MainWindow); FreezeDWORD(IoListHeight); @@ -650,344 +713,46 @@ void LD_WM_Close_call(GtkWidget *widget, GdkEvent *event, gpointer user_data)//( gtk_main_quit(); } -gboolean LD_WM_KeyDown_call(GtkWidget *widget, GdkEvent *event, gpointer user_data) -{ - /* Handles: - * WM_KEYDOWN - */ - - 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; - return FALSE; -} - gboolean LD_GTK_mouse_click_hook(GtkWidget *widget, GdkEvent *event, gpointer user_data) { /* Handles: * WM_LBUTTONDBLCLK, WM_LBUTTONDOWN */ - g_print("x = %f\n", event->button.x_root); - g_print("y = %f\n", event->button.y_root); + GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(ScrollWindow)); + switch(event->button.type) { - case GDK_BUTTON_PRESS:// To Do: run only for left click - // int x = LOWORD(lParam); - // int y = HIWORD(lParam); - // if((y > (IoListTop - 9)) && (y < (IoListTop + 3))) { - // POINT pt; - // pt.x = x; pt.y = y; - // ClientToScreen(MainWindow, &pt); - // MouseY = pt.y; - // MouseHookHandle = SetWindowsHookEx(WH_MOUSE_LL, - // (HOOKPROC)MouseHook, Instance, 0); - // } - // if(!InSimulationMode) MoveCursorMouseClick(x, y); - - // SetFocus(MainWindow); - // InvalidateRect(MainWindow, NULL, FALSE); + 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); + + if(!InSimulationMode) MoveCursorMouseClick(x, y); + + gtk_widget_queue_draw(DrawWindow); + } break; case GDK_2BUTTON_PRESS: - // int x = LOWORD(lParam); - // int y = HIWORD(lParam); - // if(InSimulationMode) { - // EditElementMouseDoubleclick(x, y); - // } else { - // CHANGING_PROGRAM(EditElementMouseDoubleclick(x, y)); - // } - // InvalidateRect(MainWindow, NULL, FALSE); + 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); + + if(InSimulationMode) { + EditElementMouseDoubleclick(x, y); + } else { + CHANGING_PROGRAM(EditElementMouseDoubleclick(x, y)); + } + gtk_widget_queue_draw(DrawWindow); + } break; } @@ -1000,26 +765,41 @@ gboolean LD_GTK_mouse_scroll_hook(GtkWidget *widget, GdkEvent *event, gpointer u * WM_VSCROLL, WM_HSCROLL, WM_MOUSEWHEEL */ + GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(ScrollWindow)); + switch(event->scroll.direction) { case GDK_SCROLL_UP: + if (gtk_adjustment_get_value(adjustment) == gtk_adjustment_get_lower(adjustment)) + VscrollProc(SB_TOP); + else + VscrollProc(SB_LINEUP); + break; case GDK_SCROLL_DOWN: - // VscrollProc(wParam); + if (gtk_adjustment_get_value(adjustment) == gtk_adjustment_get_upper(adjustment) - gtk_widget_get_allocated_height (ScrollWindow)) + VscrollProc(SB_BOTTOM); + else + VscrollProc(SB_LINEDOWN); break; case GDK_SCROLL_LEFT: + HscrollProc(SB_LINEUP); + break; case GDK_SCROLL_RIGHT: - // HscrollProc(wParam); + HscrollProc(SB_LINEDOWN); break; case GDK_SCROLL_SMOOTH: - // if((GET_WHEEL_DELTA_WPARAM(wParam)) > 0) { - // VscrollProc(SB_LINEUP); - // } else { - // VscrollProc(SB_LINEDOWN); - // } - // gdk_event_get_scroll_deltas (const GdkEvent *event, gdouble *delta_x, gdouble *delta_y); + double d_x, d_y; + gdk_event_get_scroll_deltas (event, &d_x, &d_y); + if(d_y > 0) { + VscrollProc(SB_LINEUP); + } else { + VscrollProc(SB_LINEDOWN); + } break; } + + gtk_widget_queue_draw(DrawWindow); return FALSE; } @@ -1029,9 +809,6 @@ gboolean LD_WM_MouseMove_call(GtkWidget *widget, GdkEvent *event, gpointer user_ * WM_MOUSEMOVE */ - // 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); @@ -1041,7 +818,15 @@ gboolean LD_WM_MouseMove_call(GtkWidget *widget, GdkEvent *event, gpointer user_ // SetCursor(LoadCursor(NULL, IDC_ARROW)); // } - // break; + // int dy = MouseY - mhs->pt.y; + + // int dy = MouseY - mhs->pt.y; + + // IoListHeight += dy; + // if(IoListHeight < 50) IoListHeight = 50; + // MouseY = mhs->pt.y; + // MainWindowResized(); + return FALSE; } @@ -1051,103 +836,47 @@ gboolean LD_WM_Paint_call(HWID widget, HCRDC cr, gpointer data) * WM_PAINT */ - g_print("draw called\n"); + static BOOL Paint_call_first = TRUE; - // guint width, height; - // GdkRGBA color; - // GtkStyleContext *context; + if (Paint_call_first) + { + gtk_widget_override_background_color(GTK_WIDGET(widget), + GTK_STATE_FLAG_NORMAL, (HBRUSH)GetStockObject(BLACK_BRUSH)); - // context = gtk_widget_get_style_context (widget); + gint width = gtk_widget_get_allocated_width (widget); + gint height = gtk_widget_get_allocated_height (widget); - // width = gtk_widget_get_allocated_width (widget); - // height = gtk_widget_get_allocated_height (widget); + gtk_widget_set_size_request(widget, width, height+1); - // gtk_render_background (context, cr, 0, 0, width, height); + gdk_cairo_set_source_rgba (cr, (HBRUSH)GetStockObject(BLACK_BRUSH)); - // 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); - // cairo_fill (cr); - // static double Cairo_R = 0.0, Cairo_G = 0.0, Cairo_B = 0.0; - // cairo_set_source_rgb(cr, Cairo_R, Cairo_G, Cairo_G); - // Cairo_R = (Cairo_R+0.2 > 0.4) ? 0 : Cairo_R+0.2; - // Cairo_G = (Cairo_G+0.4 > 1.0) ? 0.4 : Cairo_G+0.4; - // Cairo_B = (Cairo_B+0.1 > 0.5) ? 0 : Cairo_B+0.1; - - // cairo_select_font_face(cr, "Purisa", - // CAIRO_FONT_SLANT_NORMAL, - // CAIRO_FONT_WEIGHT_BOLD); - - // cairo_set_font_size(cr, 20); - - // cairo_move_to(cr, 20, height / 2.0); - // cairo_show_text(cr, "-----------THIS IS A TEST DRAW----------"); - - // cairo_fill (cr); - - - // PAINTSTRUCT ps; - Hdc = cr;//BeginPaint(hwnd, &ps); + Paint_call_first = FALSE; + } /// This draws the schematic. - PaintWindow(); - - // cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); - // cairo_set_line_width(cr, 1); - - // cairo_rectangle(cr, 20, 20, 120, 80); - // cairo_rectangle(cr, 180, 20, 80, 80); - // cairo_stroke_preserve(cr); - // cairo_fill(cr); - - RECT r; - // Fill around the scroll bars - // if(NeedHoriz) { - ScrollHeight = 10; - r.top = IoListTop - ScrollHeight - 2; - r.bottom = IoListTop - 2; - r.right = 5; - FillRect(Hdc, &r, (HBRUSH)GetStockObject(LTGRAY_BRUSH)); - // } - GetClientRect(DrawWindow, &r); - ScrollWidth = 10; - r.left = r.right - ScrollWidth - 2; - FillRect(Hdc, &r, (HBRUSH)GetStockObject(LTGRAY_BRUSH)); - // Draw the splitter thing to grab to resize the I/O listview. - GetClientRect(DrawWindow, &r); - r.top = IoListTop - 2; - r.bottom = IoListTop; - FillRect(Hdc, &r, (HBRUSH)GetStockObject(LTGRAY_BRUSH)); - r.top = IoListTop - 2; - r.bottom = IoListTop - 1; - FillRect(Hdc, &r, (HBRUSH)GetStockObject(WHITE_BRUSH)); - r.top = IoListTop; - r.bottom = IoListTop + 1; - FillRect(Hdc, &r, (HBRUSH)GetStockObject(DKGRAY_BRUSH)); - // EndPaint(hwnd, &ps); + MainWindowResized(); + PaintWindow(cr); 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 */ - // if(CheckSaveUserCancels()) break; + CheckSaveUserCancels(); - // PostQuitMessage(0); - // return 1; + FreezeWindowPos(MainWindow); + FreezeDWORD(IoListHeight); - return FALSE; + gtk_main_quit(); } gboolean LD_WM_Size_call(GtkWidget *widget, GdkEvent *event, gpointer user_data) @@ -1155,9 +884,14 @@ gboolean LD_WM_Size_call(GtkWidget *widget, GdkEvent *event, gpointer user_data) /* Handles: * WM_SIZE */ + MainWindowResized(); + return FALSE; +} - // MainWindowResized(); - // break; +gboolean LD_WM_Command_call(GtkMenuItem* men, gpointer gpcode) +{ + int tempcode = GPOINTER_TO_INT(gpcode); + ProcessMenu (tempcode); return FALSE; } @@ -1168,12 +902,250 @@ gboolean LD_WM_SetFocus_call(GtkWidget *widget, GdkEvent *event, gpointer user_d * WM_SETFOCUS */ - // InvalidateRect(MainWindow, NULL, FALSE); - // break; + InvalidateRect(DrawWindow, NULL, FALSE); 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. //----------------------------------------------------------------------------- @@ -1188,12 +1160,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]); @@ -1240,44 +1206,17 @@ int main(int argc, char** argv) exit(0); } + //we need to initialize all these functions so that gtk knows + //to be thread-aware + if (!g_thread_supported ()){ g_thread_init(NULL); } + gdk_threads_init(); + gdk_threads_enter(); + 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); - // MakeDialogBoxClass(); - // MakeComponentListClass(); - // MakeSmplDialogClass(); - // MakeNamingListClass(); - HMENU top = MakeMainWindowMenus(); - /// Make main window MainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(MainWindow), "LDmicro"); @@ -1285,13 +1224,16 @@ 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, IMAGE_ICON, 32, 32, 0)); /// Make main window - end + MakeMainWindowMenus(); + MakeDialogBoxClass(); + InitForDrawing(); ThawWindowPos(MainWindow); @@ -1311,20 +1253,25 @@ int main(int argc, char** argv) 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 (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(); strcpy(CurrentSaveFile, ""); - // We are running interactively, or we would already have exited. We - // can therefore show the window now, and otherwise set up the GUI. + /// We are running interactively, or we would already have exited. We + /// can therefore show the window now, and otherwise set up the GUI. - // Displaying the window + /// Displaying the window gtk_widget_show_all(MainWindow); + + /// Blink cursor + 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); @@ -1334,7 +1281,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); @@ -1343,9 +1289,9 @@ int main(int argc, char** argv) UndoFlush(); } - GenerateIoListDontLoseSelection(); //~ - // RefreshScrollbars(); - UpdateMainWindowTitleBar(); //~ + GenerateIoListDontLoseSelection(); + RefreshScrollbars(); + UpdateMainWindowTitleBar(); // MSG msg; // DWORD ret; @@ -1370,5 +1316,6 @@ int main(int argc, char** argv) // } gtk_main(); + gdk_threads_leave(); return EXIT_SUCCESS; }
\ No newline at end of file diff --git a/ldmicro/lib/freezeLD/freezeLD.cpp b/ldmicro/lib/freezeLD/freezeLD.cpp index ea3fae2..75bbb30 100644 --- a/ldmicro/lib/freezeLD/freezeLD.cpp +++ b/ldmicro/lib/freezeLD/freezeLD.cpp @@ -18,21 +18,21 @@ */ void FreezeWindowPosF(HWID hwid, char *subKey, char *name) { - //g_print("freezing"); char* Ld_CWD = (char *)malloc(MAX_PATH); - getcwd(Ld_CWD, sizeof(Ld_CWD)); - + getcwd(Ld_CWD, MAX_PATH); + if (!Ld_CWD) return; - char* moveToKeyLocatin = (char *)malloc(strlen(name) + 30); + char* moveToKeyLocatin = (char *)malloc(strlen(name) + MAX_PATH); if(!moveToKeyLocatin) { free(Ld_CWD); return; } - sprintf(moveToKeyLocatin, "mkdir -p %s/%s", FREEZE_REGISTER, subKey); + + sprintf(moveToKeyLocatin, "mkdir -p %s/%s/%s", getenv("HOME"), FREEZE_REGISTER, subKey); system(moveToKeyLocatin); - sprintf(moveToKeyLocatin, "%s/%s", FREEZE_REGISTER, subKey); + sprintf(moveToKeyLocatin, "%s/%s/%s", getenv("HOME"), FREEZE_REGISTER, subKey); if (-1 == chdir(moveToKeyLocatin)) { free(Ld_CWD); @@ -51,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()) @@ -66,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()) @@ -81,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()) @@ -96,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()) @@ -111,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()) @@ -128,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) @@ -143,18 +138,19 @@ static void Clamp(LONG *v, LONG min, LONG max) void ThawWindowPosF(HWID hwid, char *subKey, char *name) { char* Ld_CWD = (char *)malloc(MAX_PATH); - getcwd(Ld_CWD, sizeof(Ld_CWD)); - + getcwd(Ld_CWD, MAX_PATH); + if (!Ld_CWD) return; - char* moveToKeyLocatin = (char *)malloc(strlen(name) + 30); + char* moveToKeyLocatin = (char *)malloc(strlen(name) + MAX_PATH); if(!moveToKeyLocatin) { free(Ld_CWD); return; } - sprintf(moveToKeyLocatin, "%s/%s", FREEZE_REGISTER, subKey); + + sprintf(moveToKeyLocatin, "%s/%s/%s", getenv("HOME"), FREEZE_REGISTER, subKey); if (-1 == chdir(moveToKeyLocatin)) { free(Ld_CWD); @@ -162,8 +158,8 @@ void ThawWindowPosF(HWID hwid, char *subKey, char *name) return; } free(moveToKeyLocatin); - - char *keyName = (char *)malloc(strlen(name) + 30); + + char *keyName = (char *)malloc(strlen(name) + MAX_PATH); if(!keyName) { free(Ld_CWD); @@ -252,20 +248,21 @@ void ThawWindowPosF(HWID hwid, char *subKey, char *name) void FreezeDWORDF(DWORD val, char *subKey, char *name) { char* Ld_CWD = (char *)malloc(MAX_PATH); - getcwd(Ld_CWD, sizeof(Ld_CWD)); + getcwd(Ld_CWD, MAX_PATH); if (!Ld_CWD) return; - char* moveToKeyLocatin = (char *)malloc(strlen(name) + 30); + char* moveToKeyLocatin = (char *)malloc(strlen(name) + MAX_PATH); if(!moveToKeyLocatin) { free(Ld_CWD); return; } - sprintf(moveToKeyLocatin, "mkdir -p %s/%s", FREEZE_REGISTER, subKey); + + sprintf(moveToKeyLocatin, "mkdir -p %s/%s/%s", getenv("HOME"), FREEZE_REGISTER, subKey); system(moveToKeyLocatin); - sprintf(moveToKeyLocatin, "%s/%s", FREEZE_REGISTER, subKey); + sprintf(moveToKeyLocatin, "%s/%s/%s", getenv("HOME"), FREEZE_REGISTER, subKey); if (-1 == chdir(moveToKeyLocatin)) { free(Ld_CWD); @@ -291,18 +288,19 @@ void FreezeDWORDF(DWORD val, char *subKey, char *name) DWORD ThawDWORDF(DWORD val, char *subKey, char *name) { char* Ld_CWD = (char *)malloc(MAX_PATH); - getcwd(Ld_CWD, sizeof(Ld_CWD)); + getcwd(Ld_CWD, MAX_PATH); if (!Ld_CWD) return val; - char* moveToKeyLocatin = (char *)malloc(strlen(name) + 30); + char* moveToKeyLocatin = (char *)malloc(strlen(name) + MAX_PATH); if(!moveToKeyLocatin) { free(Ld_CWD); return val; } - sprintf(moveToKeyLocatin, "%s/%s", FREEZE_REGISTER, subKey); + + sprintf(moveToKeyLocatin, "%s/%s/%s", getenv("HOME"), FREEZE_REGISTER, subKey); if (-1 == chdir(moveToKeyLocatin)) { free(Ld_CWD); @@ -335,20 +333,21 @@ DWORD ThawDWORDF(DWORD val, char *subKey, char *name) void FreezeStringF(char *val, char *subKey, char *name) { char* Ld_CWD = (char *)malloc(MAX_PATH); - getcwd(Ld_CWD, sizeof(Ld_CWD)); + getcwd(Ld_CWD, MAX_PATH); if (!Ld_CWD) return; - char* moveToKeyLocatin = (char *)malloc(strlen(name) + 30); + char* moveToKeyLocatin = (char *)malloc(strlen(name) + MAX_PATH); if(!moveToKeyLocatin) { free(Ld_CWD); return; } - sprintf(moveToKeyLocatin, "mkdir -p %s/%s", FREEZE_REGISTER, subKey); + + sprintf(moveToKeyLocatin, "mkdir -p %s/%s/%s", getenv("HOME"), FREEZE_REGISTER, subKey); system(moveToKeyLocatin); - sprintf(moveToKeyLocatin, "%s/%s", FREEZE_REGISTER, subKey); + sprintf(moveToKeyLocatin, "%s/%s/%s", getenv("HOME"), FREEZE_REGISTER, subKey); if (-1 == chdir(moveToKeyLocatin)) { free(Ld_CWD); @@ -356,7 +355,7 @@ void FreezeStringF(char *val, char *subKey, char *name) return; } free(moveToKeyLocatin); - + std::ofstream Register(name, std::ios::trunc); Register << strlen(val)+1 << "\n"; Register << val; @@ -372,18 +371,19 @@ void FreezeStringF(char *val, char *subKey, char *name) void ThawStringF(char *val, int max, char *subKey, char *name) { char* Ld_CWD = (char *)malloc(MAX_PATH); - getcwd(Ld_CWD, sizeof(Ld_CWD)); + getcwd(Ld_CWD, MAX_PATH); if (!Ld_CWD) return; - char* moveToKeyLocatin = (char *)malloc(strlen(name) + 30); + char* moveToKeyLocatin = (char *)malloc(strlen(name) + MAX_PATH); if(!moveToKeyLocatin) { free(Ld_CWD); return; } - sprintf(moveToKeyLocatin, "%s/%s", FREEZE_REGISTER, subKey); + + sprintf(moveToKeyLocatin, "%s/%s/%s", getenv("HOME"), FREEZE_REGISTER, subKey); if (-1 == chdir(moveToKeyLocatin)) { free(Ld_CWD); diff --git a/ldmicro/lib/freezeLD/freezeLD.h b/ldmicro/lib/freezeLD/freezeLD.h index 3e1c0b7..581466d 100644 --- a/ldmicro/lib/freezeLD/freezeLD.h +++ b/ldmicro/lib/freezeLD/freezeLD.h @@ -10,7 +10,7 @@ #ifndef __FREEZE_H #define __FREEZE_H -#define FREEZE_REGISTER "~/.ldmicro" +#define FREEZE_REGISTER ".ldmicro" #define FREEZE_SUBKEY "LDMicro" diff --git a/ldmicro/lib/linuxUI/linuxLD.cpp b/ldmicro/lib/linuxUI/linuxLD.cpp index 95f1221..a83d15e 100644 --- a/ldmicro/lib/linuxUI/linuxLD.cpp +++ b/ldmicro/lib/linuxUI/linuxLD.cpp @@ -1,4 +1,7 @@ #include "linuxUI.h" +#include <iostream> + +using namespace std; std::vector<HEAPRECORD> HeapRecords; @@ -116,8 +119,8 @@ HICON LoadImage(HINSTANCE hinst, LPCTSTR lpszName, UINT uType, int cxDesired, void RECT_to_GDRECT(const RECT *rc, GDRECT *gdrc) { - gdrc->x = rc->top; - gdrc->y = rc->left; + gdrc->x = rc->left; + gdrc->y = rc->top; gdrc->width = rc->right - rc->left; gdrc->height = rc->bottom - rc->top; } diff --git a/ldmicro/lib/linuxUI/linuxLD.h b/ldmicro/lib/linuxUI/linuxLD.h index 8a3e3a2..c9379c2 100644 --- a/ldmicro/lib/linuxUI/linuxLD.h +++ b/ldmicro/lib/linuxUI/linuxLD.h @@ -16,6 +16,7 @@ #define CALLBACK #define CONST const +/// Meamory flags #define HEAP_ZERO_MEMORY 0x00000008 /// Image loading flags @@ -24,7 +25,6 @@ /// Macro functions #define max(_A, _B) std::max(_A, _B) -// #define min(_A, _B) std::min(_A, _B) /// Typedefs //typedef int64_t __int64; @@ -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) @@ -114,10 +116,14 @@ typedef class tagColorReferance: public GdkRGBA{ this->alpha = 1.0; } - GdkRGBA* getThis() + bool operator== (tagColorReferance& arg1) { - return this; + if( ((int)arg1.red == (int)this->red) && ((int)arg1.green == (int)this->green) && ((int)arg1.blue == (int)this->blue) ) + return true; + else + return false; } + } COLORREF, *HBRUSH; /// Structures @@ -136,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 { @@ -157,7 +182,7 @@ typedef struct FontTag { int nOrientation; int fnWeight; DWORD fdwItalic; - LPCTSTR lpszFace; + LPTSTR lpszFace; } *HFONT, FONT; typedef struct tagLOGBRUSH { @@ -173,6 +198,17 @@ typedef struct _RECT { LONG bottom; } RECT, *PRECT; +typedef struct SimpleDialogDataTag { + UINT uflag; + int boxes; + char **dests; + char *str1; + char *str2; + char *str3; + int *num1; + int *num2; +} SimpleDialogData; + /// Variables extern std::vector<HEAPRECORD> HeapRecord; diff --git a/ldmicro/lib/linuxUI/linuxUI.cpp b/ldmicro/lib/linuxUI/linuxUI.cpp index d5a9ad6..64f7690 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,18 +14,25 @@ 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; const UINT MF_CHECKED = 2; const UINT MF_UNCHECKED = 3; +/// Accelerators (keyboard shortcuts) +GtkAccelGroup* AccelGroup; +GClosure* closure; + /// ListStore HWID view; HTVC column; /// Wraper function for gtk_window_has_toplevel_focus -BOOL isFocus(HWID window) +BOOL GetFocus(HWID window) { return (BOOL) gtk_window_has_toplevel_focus(GTK_WINDOW(window)); } @@ -92,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; @@ -123,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); @@ -144,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) { @@ -154,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){ @@ -213,24 +282,24 @@ 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); cairo_rotate(hcr, hfont->nOrientation); - - cairo_text_extents_t extents; - cairo_text_extents (hcr, "H", &extents); - - cairo_matrix_t matrix; - cairo_matrix_init_scale (&matrix, - (double)hfont->nWidth * 1.6, - (double)hfont->nHeight * 1.4); + // cairo_text_extents_t extents; + // cairo_text_extents (hcr, "Z", &extents); + // cairo_matrix_t matrix; + // cairo_matrix_init_scale (&matrix, + // (double)hfont->nWidth, + // (double)hfont->nHeight); - 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\ntH = %f\n", extents.width, extents.width); - // cairo_set_font_size(hcr, 15); + // cairo_set_font_matrix (hcr, &matrix); + + cairo_set_font_size(hcr, 10); } HBRUSH CreateBrushIndirect(PLOGBRUSH plb) @@ -247,48 +316,87 @@ 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) { + if (hcr == NULL) + return; + gtk_widget_override_background_color(GTK_WIDGET(widget), GTK_STATE_FLAG_NORMAL, &bkCol); - GtkStyleContext *context; - COLORREF col; - - context = gtk_widget_get_style_context (widget); gint width = gtk_widget_get_allocated_width (widget); gint height = gtk_widget_get_allocated_height (widget); - gtk_style_context_get_color (context, - gtk_style_context_get_state (context), - &col); - - gdk_cairo_set_source_rgba (hcr, &col); + // COLORREF col; + // GtkStyleContext *context; - gtk_render_background (context, hcr, 0, 0, width, height); + // 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 (hcr, &bkCol); + // cairo_rectangle(hcr, 0, 0, width, height); + // cairo_stroke_preserve(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(HCRDC hcr, int nXStart, int nYStart, LPCTSTR lpString, int cchString) +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; + cairo_text_extents (hcr, lpString, &extents); + int width = gtk_widget_get_allocated_width (hWid); + int height= gtk_widget_get_allocated_height (hWid); + BOOL resize_flag = FALSE; + + if(nYStart+(extents.height/2.0) >= height) + { + height += extents.height + 50; + resize_flag = TRUE; + } + + if (nXStart+(extents.width/2.0) >= width) + { + 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'; + cairo_move_to(hcr, nXStart, nYStart); - cairo_show_text(hcr, lpString); + cairo_show_text(hcr, text); cairo_fill (hcr); } @@ -305,14 +413,28 @@ COLORREF GetTextColor(HCRDC Hdc) BOOL InvalidateRect(HWID hWid, const RECT *lpRect, BOOL bErase) { + if(!GDK_IS_WINDOW(hWid)) + return FALSE; + + if (lpRect == NULL) + { + gdk_window_invalidate_rect (gtk_widget_get_window (hWid), NULL, FALSE); + return TRUE; + } + GDRECT Gdrect; RECT_to_GDRECT(lpRect, &Gdrect); // gtk_widget_queue_draw(hWid); - gdk_window_invalidate_rect (gtk_widget_get_window (hWid), &Gdrect, bErase); + gdk_window_invalidate_rect (gtk_widget_get_window (hWid), &Gdrect, FALSE); + + return TRUE; } int FillRect(HCRDC hDC, const RECT *lprc, HBRUSH hbr) { + if (hDC == NULL) + return -1; + GDRECT gdrc; RECT_to_GDRECT(lprc, &gdrc); @@ -324,12 +446,93 @@ int FillRect(HCRDC hDC, const RECT *lprc, HBRUSH hbr) return 0; } +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); + + cairo_fill(hdc); + + return TRUE; +} + BOOL GetClientRect(HWID hWid, PRECT pRect) +{ + GtkAllocation allocation; + gtk_widget_get_allocation (hWid, &allocation); + + pRect->top = allocation.x; + pRect->left = allocation.y; + pRect->right = allocation.width; + pRect->bottom = allocation.height; + + return TRUE; +} + +BOOL MoveWindow(HWID hWid, int X, int Y, int nWidth, int nHeight, BOOL bRepaint) +{ + gtk_window_move(GTK_WINDOW(hWid), X, Y); + gtk_window_resize(GTK_WINDOW(hWid), nWidth, nHeight); + + if (bRepaint) + gdk_window_invalidate_rect (gtk_widget_get_window (hWid), NULL, FALSE); + + return TRUE; +} + + +BOOL GetWindowRect(HWID hWid, PRECT pRect) { - pRect->top = 0; - pRect->left = 0; - pRect->right = gtk_widget_get_allocated_width (hWid); - pRect->bottom = gtk_widget_get_allocated_height (hWid); + GtkAllocation allocation; + gtk_widget_get_allocation (hWid, &allocation); + + pRect->top = allocation.x; + pRect->left = allocation.y; + pRect->right = allocation.width; + pRect->bottom = allocation.height; return TRUE; } + + +UINT SetTimer(HWID hWid, UINT nIDEvent, UINT uElapse, BOOL (*lpTimerFunc)(BOOL) ) +{ + auto record_it = std::find_if(timerRecords.begin(), timerRecords.end(), [&nIDEvent](TimerRecord &Record) { return Record.ufID == nIDEvent; }); + + if (record_it != timerRecords.end()) + return 0; + + TimerRecord tr; + tr.pfun = lpTimerFunc; + tr.ufID = nIDEvent; + tr.utID = g_timeout_add(uElapse, (GSourceFunc)lpTimerFunc, FALSE); + + timerRecords.push_back(tr); + return tr.utID; +} + +BOOL KillTimer(HWID hWid, UINT uIDEvent) +{ + auto record_it = std::find_if(timerRecords.begin(), timerRecords.end(), [&uIDEvent](TimerRecord &Record) { return Record.ufID == uIDEvent; }); + + if (record_it == timerRecords.end()) + return FALSE; + + record_it->pfun(TRUE); + g_source_remove (record_it->utID); + timerRecords.erase(record_it); + + return TRUE; +} + +void DestroyWindow (HWID widget) +{ + if (GTK_IS_WIDGET(widget)) + { + gtk_widget_destroy (widget); + } +} diff --git a/ldmicro/lib/linuxUI/linuxUI.h b/ldmicro/lib/linuxUI/linuxUI.h index e7b1d90..53040ec 100644 --- a/ldmicro/lib/linuxUI/linuxUI.h +++ b/ldmicro/lib/linuxUI/linuxUI.h @@ -33,12 +33,64 @@ #define MB_ICONWARNING 0x00000040L #define MB_ICONINFORMATION 0x00000080L -/// open/save file -#define OFN_PATHMUSTEXIST 0x00000100L -#define OFN_HIDEREADONLY 0x00000200L -#define OFN_OVERWRITEPROMPT 0x00000400L - -/// window brushes +/// 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 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 + +/// Key masks +#define VK_TAB GDK_KEY_Tab + +#define VK_DOWN 65364 +#define VK_UP 65362 +#define VK_LEFT 65361 +#define VK_RIGHT 65363 + +#define VK_NP_DOWN 65433 +#define VK_NP_UP 65431 +#define VK_NP_LEFT 65430 +#define VK_NP_RIGHT 65432 + +#define VK_RETURN GDK_KEY_Return +#define VK_ESCAPE GDK_KEY_Escape +#define VK_F5 GDK_KEY_F5 +#define VK_F1 GDK_KEY_F1 + +#define VK_OEM_PLUS GDK_KEY_plus +#define VK_OEM_MINUS GDK_KEY_minus +#define VK_OEM_PERIOD GDK_KEY_period +#define VK_OEM_COMMA GDK_KEY_comma + +#define VK_DELETE GDK_KEY_Delete +#define VK_NP_DELETE GDK_KEY_KP_Delete + +// #define VK_OEM_1 GDK_KEY_colon // GDK_KEY_semicolon +// #define VK_OEM_2 GDK_KEY_question // GDK_KEY_slash +// #define VK_OEM_5 GDK_KEY_backslash // GDK_KEY_bar + +/// Window brushes #define BS_SOLID 0x00000001L #define BS_HOLLOW 0x00000002L #define BLACK_BRUSH 0x00000004L @@ -63,9 +115,13 @@ extern const UINT MF_GRAYED; extern const UINT MF_CHECKED; extern const UINT MF_UNCHECKED; +/// Accelerators (keyboard shortcuts) +extern GtkAccelGroup* AccelGroup; +extern GClosure* closure; + /// ListStore -extern GtkWidget *view; -extern GtkTreeViewColumn *column; +extern HWID view; +extern HTVC column; /// Structures typedef struct OpenFileInfoData { @@ -79,57 +135,77 @@ 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 isFocus(HWID window); +BOOL GetFocus(HWID window); -COLORREF RGB(int red, - int green, - int blue); +COLORREF RGB( + int red, + int green, + int blue); -int MessageBox(HWID pWindow, +int MessageBox( + HWID pWindow, char* message, char* title, UINT mFlags); BOOL GetSaveFileName(OPENFILENAME *ofn); -void EnableMenuItem(HMENU MenuName, +BOOL GetOpenFileName(OPENFILENAME *ofn); + +void EnableMenuItem( + HMENU MenuName, HMENU MenuItem, UINT CheckEnabledItem); -void CheckMenuItem(HMENU MenuName, +void CheckMenuItem( + HMENU MenuName, HMENU MenuItem, UINT Check); HANDLE GetStockObject(int fnObject); -void SelectObject(HCRDC hcr, +void SelectObject( + HCRDC hcr, HFONT hfont); HBRUSH CreateBrushIndirect(PLOGBRUSH plb); -HFONT CreateFont(int nHeight, +HFONT CreateFont( + int nHeight, int nWidth, int nOrientation, int fnWeight, DWORD fdwItalic, LPCTSTR lpszFace); -void SetBkColor(HWID widget, +void SetBkColor( + HWID widget, HCRDC hcr, COLORREF bkCol); -void SetTextColor(HCRDC hcr, +void SetTextColor( + HCRDC hcr, COLORREF color); -void TextOut(HCRDC hcr, - int nXStart, - int nYStart, - LPCTSTR lpString, - int cchString); +void TextOut( + HWID hWid, + HCRDC hcr, + int nXStart, + int nYStart, + LPCTSTR lpString, + int cchString); COLORREF GetTextColor(HCRDC Hdc); @@ -143,8 +219,41 @@ int FillRect( const RECT *lprc, HBRUSH hbr); +BOOL PatBlt( + HCRDC hdc, + int nXLeft, + int nYLeft, + int nWidth, + int nHeight, + DWORD dwRop, + HBRUSH hbr); + BOOL GetClientRect( HWID hWid, PRECT lpRect); +BOOL MoveWindow( + HWID hWid, + int X, + int Y, + int nWidth, + int nHeight, + BOOL bRepaint); + +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..e106e31 100644 --- a/ldmicro/lutdialog.cpp +++ b/ldmicro/lutdialog.cpp @@ -26,95 +26,94 @@ #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; +static UINT LUT_DIALOG_REFRESH_TIMER_ID_1 = 0; +static UINT LUT_DIALOG_REFRESH_TIMER_ID_2 = 0; + +HWID LutGrid; +HWID LutPackingBox; + +struct LookUpTableDialogBuffer{ + int tmpcount; + bool tmpasString; + char PrevTableAsString[1024] = ""; +} temp; + +static int piecewiseTmpCount; //----------------------------------------------------------------------------- // 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){ + 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){ + 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){ + 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 +121,109 @@ 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) +{ + bool madeCheckbox = FALSE; + 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); + + if(!forPwl) { + AsStringCheckbox = gtk_check_button_new_with_label + ("Edit table of ASCII values like a string"); + madeCheckbox = TRUE; + } + + 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); + if (madeCheckbox){ + 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(BOOL destroyFlag = TRUE) +{ + 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]; + char *tmpB = (char*)gtk_entry_get_text (GTK_ENTRY (ValuesTextbox[i])); + strcpy (buf, tmpB); + ValuesCache[i] = atoi(buf); + } + } + + if (destroyFlag){ + for(int i = 0; i < temp.tmpcount; i++) + { + if (GTK_IS_ENTRY(ValuesTextbox[i])) + { + DestroyWindow(ValuesTextbox[i]); + DestroyWindow(ValuesLabel[i]); + } + } + } +} + +static void DestroyLutControlsPiecewise(BOOL destroyFlag = TRUE) +{ + 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]; + char *tmpB = (char*)gtk_entry_get_text (GTK_ENTRY (ValuesTextbox[i])); + strcpy (buf, tmpB); + ValuesCache[i] = atoi(buf); + } + } + + if (destroyFlag) + { + int i; + for(i = 0; i < WasCount; i++) { + DestroyWindow(ValuesTextbox[i]); + DestroyWindow(ValuesLabel[i]); + } + } +} //----------------------------------------------------------------------------- // Make the controls that hold the LUT. The exact configuration of the dialog @@ -215,96 +231,103 @@ 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; + 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 = gtk_entry_new (); + gtk_grid_attach (GTK_GRID (LutGrid), StringTextbox, 0, 9, 1, 1); + checkString = TRUE; + gtk_widget_show_all (LutGrid); + gtk_editable_set_editable (GTK_EDITABLE (CountTextbox), FALSE); + } + 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); + gtk_entry_set_text (GTK_ENTRY (ValuesTextbox[i]), buf); + + 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); + } +} //----------------------------------------------------------------------------- // Decode a string into a look-up table; store the values in ValuesCache[], @@ -312,36 +335,167 @@ 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) +{ + 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 (gpointer data){ + ElemLeaf *l = (ElemLeaf *) data; + ElemLookUpTable *t = &(l->d.lookUpTable); + strcpy (t->dest, gtk_entry_get_text (GTK_ENTRY (DestTextbox))); + strcpy (t->index, gtk_entry_get_text (GTK_ENTRY (IndexTextbox))); + DestroyLutControls(FALSE); + + // 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), ""); + } + 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]; + 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)); + checkString = x; + if((x && !asString) || (!x && asString)) { + asString = x; + if (x == 1){ + MakeLutControls(asString, count, FALSE); + + for(int i = 0; i < temp.tmpcount; i++) { + if (GTK_IS_ENTRY(ValuesTextbox[i])) + { + DestroyWindow(ValuesTextbox[i]); + DestroyWindow(ValuesLabel[i]); + } + } + } + else { + DestroyLutControls(); + if (!x && GTK_IS_ENTRY(StringTextbox)) + { + DestroyWindow(StringTextbox); + gtk_editable_set_editable (GTK_EDITABLE (CountTextbox), TRUE); + } + } + } + + temp.tmpcount = count; + temp.tmpasString = asString; +} + +// Checks for the required key press +gboolean LookUpTableKeyPress (HWID widget, GdkEventKey* event, gpointer data){ + + if (event -> keyval == GDK_KEY_Return){ + LookUpTableCheckMode (); + LookUpTableGetData((gpointer) data); + DestroyWindow (LutDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); + g_source_remove (LUT_DIALOG_REFRESH_TIMER_ID_1); + LUT_DIALOG_REFRESH_TIMER_ID_1 = 0; + } + else if (event -> keyval == GDK_KEY_Escape){ + DestroyWindow (LutDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); + g_source_remove (LUT_DIALOG_REFRESH_TIMER_ID_1); + LUT_DIALOG_REFRESH_TIMER_ID_1 = 0; + } + return FALSE; +} + +/// Dialog refresh function +BOOL LutDialogRefresh(gpointer data) +{ + LookUpTableCheckMode (); + LookUpTableGetData((gpointer) data); + return TRUE; +} +// Ok button call +void LutDialogOk (HWID widget, gpointer data) +{ + LookUpTableCheckMode (); + LookUpTableGetData((gpointer) data); + + DestroyWindow (LutDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); + g_source_remove (LUT_DIALOG_REFRESH_TIMER_ID_1); + LUT_DIALOG_REFRESH_TIMER_ID_1 = 0; +} + +// Cancel button call +void LutCallCancel (HWID widget, gpointer data) +{ + DestroyWindow (LutDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); + g_source_remove (LUT_DIALOG_REFRESH_TIMER_ID_1); + LUT_DIALOG_REFRESH_TIMER_ID_1 = 0; +} //----------------------------------------------------------------------------- // Show the look-up table dialog. This one is nasty, mostly because there are @@ -349,217 +503,216 @@ 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); - -// // 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); -// } +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. + + LutGrid = gtk_grid_new(); + 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. + 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; + temp.tmpasString = asString; + + g_signal_connect (G_OBJECT (LutDialog), "key-press-event", + G_CALLBACK(LookUpTableKeyPress), (gpointer)l); + g_signal_connect (G_OBJECT (OkButton), "clicked", + G_CALLBACK(LutDialogOk), (gpointer)l); + g_signal_connect (G_OBJECT (CancelButton), "clicked", + G_CALLBACK(LutCallCancel), NULL); + + if (LUT_DIALOG_REFRESH_TIMER_ID_1 == 0) + LUT_DIALOG_REFRESH_TIMER_ID_1 = g_timeout_add(100, (GSourceFunc)LutDialogRefresh, (gpointer)l); +} + +// Piecewise Dialog + +void PiecewiseDialogGetData(gpointer data){ + + ElemLeaf *l = (ElemLeaf *) data; + ElemPiecewiseLinear *t = &(l->d.piecewiseLinear); + int count = piecewiseTmpCount; + strcpy (t->dest, gtk_entry_get_text (GTK_ENTRY (DestTextbox))); + strcpy (t->index, gtk_entry_get_text (GTK_ENTRY (IndexTextbox))); + DestroyLutControlsPiecewise(FALSE); + // MakeLutControls(FALSE, count*2, TRUE); + + // The call to DestroyLutControlsPiecewise 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; +} + +void PiecewiseDialogPointTextbox (int count){ + char* buf; + char *tmpBuf = (char*)gtk_entry_get_text (GTK_ENTRY (CountTextbox)); + buf = (char*)malloc(strlen(tmpBuf)); + strcpy (buf, tmpBuf); + if(atoi(buf) != count) { + count = atoi(buf); + if(count < 0 || count > 10) { + count = 0; + gtk_entry_set_text (GTK_ENTRY (CountTextbox), ""); + } + DestroyLutControlsPiecewise(); + MakeLutControls(FALSE, count*2, TRUE); + } + piecewiseTmpCount = count; +} + +/// Dialog refresh function +BOOL PiecewiseDialogRefresh(gpointer data) +{ + PiecewiseDialogPointTextbox (piecewiseTmpCount); + PiecewiseDialogGetData((gpointer) data); + return TRUE; +} + +// Ok button call +void PiecewiseDialogOk (HWID widget, gpointer data) +{ + PiecewiseDialogPointTextbox (piecewiseTmpCount); + PiecewiseDialogGetData((gpointer) data); + + DestroyWindow (LutDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); + g_source_remove (LUT_DIALOG_REFRESH_TIMER_ID_2); + LUT_DIALOG_REFRESH_TIMER_ID_2 = 0; +} + +// Checks for the required key press +gboolean PiecewiseDialogKeyPress (HWID widget, GdkEventKey* event, gpointer data){ + + if (event -> keyval == GDK_KEY_Return){ + PiecewiseDialogPointTextbox (piecewiseTmpCount); + PiecewiseDialogGetData((gpointer) data); + DestroyWindow (LutDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); + g_source_remove (LUT_DIALOG_REFRESH_TIMER_ID_2); + LUT_DIALOG_REFRESH_TIMER_ID_2 = 0; + } + else if (event -> keyval == GDK_KEY_Escape){ + DestroyWindow (LutDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); + g_source_remove (LUT_DIALOG_REFRESH_TIMER_ID_2); + LUT_DIALOG_REFRESH_TIMER_ID_2 = 0; + } + return FALSE; +} + +// Cancel button call +void PiecewiseCallCancel (HWID widget, gpointer data) +{ + DestroyWindow (LutDialog); + gtk_widget_set_sensitive (MainWindow, TRUE); + g_source_remove (LUT_DIALOG_REFRESH_TIMER_ID_2); + LUT_DIALOG_REFRESH_TIMER_ID_2 = 0; +} //----------------------------------------------------------------------------- // 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); - -// // 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; -// memset(ValuesCache, 0, sizeof(ValuesCache)); -// int i; -// for(i = 0; i < count*2; 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", -// _("Piecewise Linear Table"), WS_OVERLAPPED | WS_SYSMENU, -// 100, 100, 320, 375, NULL, NULL, Instance, NULL); -// MakeFixedControls(TRUE); -// MakeLutControls(FALSE, count*2, TRUE); +// //----------------------------------------------------------------------------- +void ShowPiecewiseLinearDialog(ElemLeaf *l) +{ + ElemPiecewiseLinear *t = &(l->d.piecewiseLinear); + + // 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; + memset(ValuesCache, 0, sizeof(ValuesCache)); + int i; + for(i = 0; i < count*2; 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(); + LutPackingBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + + LutDialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(LutDialog), "Piecewise Linear 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(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)); -// char buf[30]; -// sprintf(buf, "%d", t->count); -// SendMessage(CountTextbox, WM_SETTEXT, 0, (LPARAM)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); -// } - -// // 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) { -// count = atoi(buf); -// if(count < 0 || count > 10) { -// count = 0; -// SendMessage(CountTextbox, WM_SETTEXT, 0, (LPARAM)""); -// } -// 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); -// } + // 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); + + // And show the window + gtk_widget_set_sensitive (MainWindow, FALSE); + gtk_widget_show_all (LutDialog); + // gtk_widget_grab_focus (DestTextbox); + + piecewiseTmpCount = count; + + g_signal_connect (G_OBJECT (LutDialog), "key-press-event", + G_CALLBACK(PiecewiseDialogKeyPress), (gpointer)l); + g_signal_connect (G_OBJECT (OkButton), "clicked", + G_CALLBACK(PiecewiseDialogOk), (gpointer)l); + g_signal_connect (G_OBJECT (CancelButton), "clicked", + G_CALLBACK(PiecewiseCallCancel), NULL); + + if (LUT_DIALOG_REFRESH_TIMER_ID_2 == 0) + LUT_DIALOG_REFRESH_TIMER_ID_2 = g_timeout_add(100, (GSourceFunc)PiecewiseDialogRefresh, (gpointer)l); +} diff --git a/ldmicro/maincontrols.cpp b/ldmicro/maincontrols.cpp index a08696f..14aa308 100644 --- a/ldmicro/maincontrols.cpp +++ b/ldmicro/maincontrols.cpp @@ -31,76 +31,76 @@ #include "ldmicro.h" // Menu IDs -HMENU MNU_NEW; -HMENU MNU_OPEN; -HMENU MNU_SAVE; -HMENU MNU_SAVE_AS; -HMENU MNU_EXPORT; -HMENU MNU_EXIT; - -HMENU MNU_UNDO; -HMENU MNU_REDO; -HMENU MNU_PUSH_RUNG_UP; -HMENU MNU_PUSH_RUNG_DOWN; -HMENU MNU_INSERT_RUNG_BEFORE; -HMENU MNU_INSERT_RUNG_AFTER; -HMENU MNU_DELETE_ELEMENT; -HMENU MNU_DELETE_RUNG; - -HMENU MNU_INSERT_COMMENT; -HMENU MNU_INSERT_CONTACTS; -HMENU MNU_INSERT_COIL; -HMENU MNU_INSERT_TON; -HMENU MNU_INSERT_TOF; -HMENU MNU_INSERT_RTO; -HMENU MNU_INSERT_RES; -HMENU MNU_INSERT_OSR; -HMENU MNU_INSERT_OSF; -HMENU MNU_INSERT_CTU; -HMENU MNU_INSERT_CTD; -HMENU MNU_INSERT_CTC; -HMENU MNU_INSERT_ADD; -HMENU MNU_INSERT_SUB; -HMENU MNU_INSERT_MUL; -HMENU MNU_INSERT_DIV; -HMENU MNU_INSERT_MOV; -HMENU MNU_INSERT_READ_ADC; -HMENU MNU_INSERT_SET_PWM; -HMENU MNU_INSERT_UART_SEND; -HMENU MNU_INSERT_UART_RECV; -HMENU MNU_INSERT_EQU; -HMENU MNU_INSERT_NEQ; -HMENU MNU_INSERT_GRT; -HMENU MNU_INSERT_GEQ; -HMENU MNU_INSERT_LES; -HMENU MNU_INSERT_LEQ; -HMENU MNU_INSERT_OPEN; -HMENU MNU_INSERT_SHORT; -HMENU MNU_INSERT_MASTER_RLY; -HMENU MNU_INSERT_SHIFT_REG; -HMENU MNU_INSERT_LUT; -HMENU MNU_INSERT_FMTD_STR; -HMENU MNU_INSERT_PERSIST; -HMENU MNU_MAKE_NORMAL; -HMENU MNU_NEGATE; -HMENU MNU_MAKE_SET_ONLY; -HMENU MNU_MAKE_RESET_ONLY; -HMENU MNU_INSERT_PWL; - -HMENU MNU_MCU_SETTINGS; -HMENU MNU_PROCESSOR[NUM_SUPPORTED_MCUS+1]; -HMENU MNU_MICRO_CONTROLLER; // Item for Microcontroller - -HMENU MNU_SIMULATION_MODE; -HMENU MNU_START_SIMULATION; -HMENU MNU_STOP_SIMULATION; -HMENU MNU_SINGLE_CYCLE; - -HMENU MNU_COMPILE; -HMENU MNU_COMPILE_AS; - -HMENU MNU_MANUAL; -HMENU MNU_ABOUT; +HMENU NewMenu; +HMENU OpenMenu; +HMENU SaveMenu; +HMENU SaveAsMenu; +HMENU ExportMenu; +HMENU ExitMenu; + +HMENU UndoMenu; +HMENU RedoMenu; +HMENU PushRungUpMenu; +HMENU PushRungDownMenu; +HMENU InsertRungBeforeMenu; +HMENU InsertRungAfterMenu; +HMENU DeleteElementMenu; +HMENU DeleteRungMenu; + +HMENU InsertCommentMenu; +HMENU InsertContactsMenu; +HMENU InsertCoilMenu; +HMENU InsertTonMenu; +HMENU InsertTofMenu; +HMENU InsertRtoMenu; +HMENU InsertResMenu; +HMENU InsertOsrMenu; +HMENU InsertOsfMenu; +HMENU InsertCtuMenu; +HMENU InsertCtdMenu; +HMENU InsertCtcMenu; +HMENU InsertAddMenu; +HMENU InsertSubMenu; +HMENU InsertMulMenu; +HMENU InsertDivMenu; +HMENU InsertMovMenu; +HMENU InsertReadAdcMenu; +HMENU InsertSetPwmMenu; +HMENU InsertUartSendMenu; +HMENU InsertUartRecvMenu; +HMENU InsertEquMenu; +HMENU InsertNeqMenu; +HMENU InsertGrtMenu; +HMENU InsertGeqMenu; +HMENU InsertLesMenu; +HMENU InsertLeqMenu; +HMENU InsertOpenMenu; +HMENU InsertShortMenu; +HMENU InsertMasterRlyMenu; +HMENU InsertShiftRegMenu; +HMENU InsertLutMenu; +HMENU InsertFmtdStrMenu; +HMENU InsertPersistMenu; +HMENU MakeNormalMenu; +HMENU NegateMenu; +HMENU MakeSetOnlyMenu; +HMENU MakeResetOnlyMenu; +HMENU InsertPwlMenu; + +HMENU McuSettingsMenu; +HMENU ProcessorMenuItems[NUM_SUPPORTED_MCUS+1]; +HMENU MicroControllerMenu; // Item for Microcontroller + +HMENU SimulationModeMenu; +HMENU StartSimulationMenu; +HMENU StopSimulationMenu; +HMENU SingleCycleMenu; + +HMENU CompileMenu; +HMENU CompileAsMenu; + +HMENU ManualMenu; +HMENU AboutMenu; // scrollbars for the ladder logic area // static HWND HorizScrollBar; @@ -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; @@ -119,10 +119,10 @@ static HMENU InstructionMenu; static HMENU ProcessorMenu; static HMENU SimulateMenu; static HMENU TopMenu; // Menu Bar -static HMENU settings; -static HMENU compile; -static HMENU help; -static HMENU ScrollWindow; +static HMENU Settings; +static HMENU Compile; +static HMENU Help; +HMENU ScrollWindow; // listview used to maintain the list of I/O pins with symbolic names, plus // the internal relay too @@ -131,21 +131,129 @@ 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; +// Displaying keyboard shortcuts for each menu item +void AddMenuAccelerators (void){ + // Declaring the accelerator group for keyboard shortcuts + AccelGroup = gtk_accel_group_new (); + + // Creating keyboard shortcuts for File menu + gtk_widget_add_accelerator (NewMenu, "activate", AccelGroup, GDK_KEY_N, + GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (OpenMenu, "activate", AccelGroup, GDK_KEY_O, + GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (SaveMenu, "activate", AccelGroup, GDK_KEY_S, + GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (ExportMenu, "activate", AccelGroup, GDK_KEY_E, + GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + + // Creating keyboard shortcuts for Edit menu + gtk_widget_add_accelerator (UndoMenu, "activate", AccelGroup, GDK_KEY_Z, + GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (RedoMenu, "activate", AccelGroup, GDK_KEY_Y, + GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertRungBeforeMenu, "activate", AccelGroup, GDK_KEY_F6, + GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertRungAfterMenu, "activate", AccelGroup, GDK_KEY_V, + GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (PushRungUpMenu, "activate", AccelGroup, GDK_KEY_uparrow, + GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE); + 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, + (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, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertContactsMenu, "activate", AccelGroup, GDK_KEY_C, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertOsrMenu, "activate", AccelGroup, GDK_KEY_backslash, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertOsfMenu, "activate", AccelGroup, GDK_KEY_slash, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertTonMenu, "activate", AccelGroup, GDK_KEY_O, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertTofMenu, "activate", AccelGroup, GDK_KEY_F, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertRtoMenu, "activate", AccelGroup, GDK_KEY_T, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertCtuMenu, "activate", AccelGroup, GDK_KEY_U, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertCtdMenu, "activate", AccelGroup, GDK_KEY_I, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertCtcMenu, "activate", AccelGroup, GDK_KEY_J, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertEquMenu, "activate", AccelGroup, GDK_KEY_equal, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertGrtMenu, "activate", AccelGroup, GDK_KEY_greater, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertGeqMenu, "activate", AccelGroup, GDK_KEY_Stop, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertLesMenu, "activate", AccelGroup, GDK_KEY_less, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertLeqMenu, "activate", AccelGroup, GDK_KEY_comma, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertCoilMenu, "activate", AccelGroup, GDK_KEY_L, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertResMenu, "activate", AccelGroup, GDK_KEY_E, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertMovMenu, "activate", AccelGroup, GDK_KEY_M, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertAddMenu, "activate", AccelGroup, GDK_KEY_plus, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertSubMenu, "activate", AccelGroup, GDK_KEY_minus, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertMulMenu, "activate", AccelGroup, GDK_KEY_multiply, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertDivMenu, "activate", AccelGroup, GDK_KEY_D, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (InsertReadAdcMenu, "activate", AccelGroup, GDK_KEY_P, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (MakeNormalMenu, "activate", AccelGroup, GDK_KEY_A, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (NegateMenu, "activate", AccelGroup, GDK_KEY_N, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (MakeSetOnlyMenu, "activate", AccelGroup, GDK_KEY_S, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (MakeResetOnlyMenu, "activate", AccelGroup, GDK_KEY_R, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + + // Creating keyboard shortcuts for Simulation menu + gtk_widget_add_accelerator (SimulationModeMenu, "activate", AccelGroup, GDK_KEY_M, + GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + gtk_widget_add_accelerator (StartSimulationMenu, "activate", AccelGroup, GDK_KEY_R, + GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + 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, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + + // Creating keyboard shortcuts for Compile menu + gtk_widget_add_accelerator (CompileMenu, "activate", AccelGroup, GDK_KEY_F5, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + + // Creating keyboard shortcuts for Help menu + gtk_widget_add_accelerator (ManualMenu, "activate", AccelGroup, GDK_KEY_F1, + (GdkModifierType)0, GTK_ACCEL_VISIBLE); + + gtk_window_add_accel_group (GTK_WINDOW (MainWindow), AccelGroup); + +} + //----------------------------------------------------------------------------- // Create the top-level menu bar for the main window. Mostly static, but we // create the "select processor" menu from the list in mcutable.h dynamically. //----------------------------------------------------------------------------- HMENU MakeMainWindowMenus(void) { - HMENU MenuBox; // Box for alignment - HMENU PackedMenuBox; // Stores the packed box - HMENU TopMenu; // Menu Bar + HMENU MenuBox; // Box for packing and alignment + // HMENU TopMenu; // Menu Bar HWID FileLabel; // File menu label HWID EditLabel; // Edit menu label HWID InstructionLabel; // Instruction menu label @@ -153,7 +261,6 @@ HMENU MakeMainWindowMenus(void) HWID CompileLabel; // Compile menu label HWID HelpLabel; // Help menu label HWID SimulateLabel; // Simulate menu label - HMENU ProcessorMenuItems; // Processor menu items HMENU FileMenuSeparator; // File menu separator HMENU EditMenuSeparator; // Edit menu separator HMENU InstructionMenuSeparator; // Instruction menu separator @@ -169,226 +276,229 @@ HMENU MakeMainWindowMenus(void) // Creating various menus FileMenu = gtk_menu_new(); EditMenu = gtk_menu_new(); - settings = gtk_menu_new(); + Settings = gtk_menu_new(); ProcessorMenu = gtk_menu_new(); InstructionMenu = gtk_menu_new(); SimulateMenu = gtk_menu_new(); - compile = gtk_menu_new(); - help = gtk_menu_new(); + Compile = gtk_menu_new(); + Help = gtk_menu_new(); // Creating labels for each menu - FileLabel = gtk_menu_item_new_with_label("File"); - EditLabel = gtk_menu_item_new_with_label("Edit"); - SettingsLabel = gtk_menu_item_new_with_label("Settings"); - InstructionLabel = gtk_menu_item_new_with_label("Instructions"); - SimulateLabel = gtk_menu_item_new_with_label("Simulate"); - CompileLabel = gtk_menu_item_new_with_label("Compile"); - HelpLabel = gtk_menu_item_new_with_label("Help"); + FileLabel = gtk_menu_item_new_with_mnemonic("_File"); + EditLabel = gtk_menu_item_new_with_mnemonic("_Edit"); + SettingsLabel = gtk_menu_item_new_with_mnemonic("_Settings"); + InstructionLabel = gtk_menu_item_new_with_mnemonic("_Instructions"); + SimulateLabel = gtk_menu_item_new_with_mnemonic("_Simulate"); + CompileLabel = gtk_menu_item_new_with_mnemonic("_Compile"); + HelpLabel = gtk_menu_item_new_with_mnemonic("_Help"); // Creating labels for File Menu - MNU_NEW = gtk_menu_item_new_with_label("New"); - MNU_OPEN = gtk_menu_item_new_with_label("Open"); - MNU_SAVE = gtk_menu_item_new_with_label("Save"); - MNU_SAVE_AS = gtk_menu_item_new_with_label("Save As"); - MNU_EXPORT = gtk_menu_item_new_with_label("Export As Text"); - MNU_EXIT = gtk_menu_item_new_with_label("Exit"); - + 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 = 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"); + // Appending menu items (labels) to File menu and adding separators - gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), MNU_NEW); // Appending menu items - gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), MNU_OPEN); - gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), MNU_SAVE); - gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), MNU_SAVE_AS); + 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); FileMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), FileMenuSeparator); - gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), MNU_EXPORT); + gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), ExportMenu); FileMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), FileMenuSeparator); - gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), MNU_EXIT); + gtk_menu_shell_append(GTK_MENU_SHELL (FileMenu), ExitMenu); // Creating labels for Edit Menu - MNU_UNDO = gtk_menu_item_new_with_label("Undo"); - MNU_REDO = gtk_menu_item_new_with_label("Redo"); - MNU_INSERT_RUNG_BEFORE = gtk_menu_item_new_with_label("Insert rung Before"); - MNU_INSERT_RUNG_AFTER = gtk_menu_item_new_with_label("Insert Rung After"); - MNU_PUSH_RUNG_UP = gtk_menu_item_new_with_label("Move Selected Rung Up"); - MNU_PUSH_RUNG_DOWN = gtk_menu_item_new_with_label("Move Selected Rung Down"); - MNU_DELETE_ELEMENT = gtk_menu_item_new_with_label("Delete Selected Element"); - MNU_DELETE_RUNG = gtk_menu_item_new_with_label("Delete Rung"); + UndoMenu = gtk_menu_item_new_with_mnemonic("_Undo"); + RedoMenu = gtk_menu_item_new_with_mnemonic("_Redo"); + InsertRungBeforeMenu = gtk_menu_item_new_with_mnemonic("_Insert rung Before"); + InsertRungAfterMenu = gtk_menu_item_new_with_mnemonic("_Insert Rung After"); + PushRungUpMenu = gtk_menu_item_new_with_mnemonic("_Move Selected Rung Up"); + PushRungDownMenu = gtk_menu_item_new_with_mnemonic("_Move Selected Rung Down"); + DeleteElementMenu = gtk_menu_item_new_with_mnemonic("_Delete Selected Element"); + DeleteRungMenu = gtk_menu_item_new_with_mnemonic("_Delete Rung"); // Appending menu items to Edit menu and adding separators - gtk_menu_shell_append(GTK_MENU_SHELL (EditMenu), MNU_UNDO); - gtk_menu_shell_append(GTK_MENU_SHELL (EditMenu), MNU_REDO); + gtk_menu_shell_append(GTK_MENU_SHELL (EditMenu), UndoMenu); + gtk_menu_shell_append(GTK_MENU_SHELL (EditMenu), RedoMenu); EditMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(EditMenu), EditMenuSeparator); - gtk_menu_shell_append(GTK_MENU_SHELL (EditMenu), MNU_INSERT_RUNG_BEFORE); - gtk_menu_shell_append(GTK_MENU_SHELL (EditMenu), MNU_INSERT_RUNG_AFTER); - gtk_menu_shell_append(GTK_MENU_SHELL (EditMenu), MNU_PUSH_RUNG_UP); - gtk_menu_shell_append(GTK_MENU_SHELL (EditMenu), MNU_PUSH_RUNG_DOWN); + gtk_menu_shell_append(GTK_MENU_SHELL (EditMenu), InsertRungBeforeMenu); + gtk_menu_shell_append(GTK_MENU_SHELL (EditMenu), InsertRungAfterMenu); + gtk_menu_shell_append(GTK_MENU_SHELL (EditMenu), PushRungUpMenu); + gtk_menu_shell_append(GTK_MENU_SHELL (EditMenu), PushRungDownMenu); EditMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(EditMenu), EditMenuSeparator); - gtk_menu_shell_append(GTK_MENU_SHELL (EditMenu), MNU_DELETE_ELEMENT); - gtk_menu_shell_append(GTK_MENU_SHELL (EditMenu), MNU_DELETE_RUNG); + gtk_menu_shell_append(GTK_MENU_SHELL (EditMenu), DeleteElementMenu); + gtk_menu_shell_append(GTK_MENU_SHELL (EditMenu), DeleteRungMenu); // Creating labels for Settings Menu - MNU_MCU_SETTINGS = gtk_menu_item_new_with_label ("MCU Parameters..."); - MNU_MICRO_CONTROLLER = gtk_menu_item_new_with_label ("Microcontroller"); + McuSettingsMenu = gtk_menu_item_new_with_mnemonic ("_MCU Parameters..."); + MicroControllerMenu = gtk_menu_item_new_with_mnemonic ("_Microcontroller"); // Appending menu items to Settings menu - gtk_menu_shell_append (GTK_MENU_SHELL (settings), MNU_MCU_SETTINGS); - gtk_menu_shell_append (GTK_MENU_SHELL (settings), MNU_MICRO_CONTROLLER); + gtk_menu_shell_append (GTK_MENU_SHELL (Settings), McuSettingsMenu); + 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++){ - MNU_PROCESSOR[i] = gtk_check_menu_item_new_with_label (SupportedMcus[i].mcuName); - gtk_menu_shell_append (GTK_MENU_SHELL (ProcessorMenu), MNU_PROCESSOR[i]); + 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]); } - MNU_PROCESSOR[NUM_SUPPORTED_MCUS] = gtk_check_menu_item_new_with_label ("(no microcontroller)"); - gtk_menu_shell_append (GTK_MENU_SHELL (ProcessorMenu), MNU_PROCESSOR[NUM_SUPPORTED_MCUS]); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(MNU_MICRO_CONTROLLER), ProcessorMenu); + 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); // Creating labels for Instruction Menu and adding separators - MNU_INSERT_COMMENT = gtk_menu_item_new_with_label("Insert Comment"); - MNU_INSERT_CONTACTS = gtk_menu_item_new_with_label("Insert Contacts"); - MNU_INSERT_OSR = gtk_menu_item_new_with_label("Insert OSR (One Shot Rising)"); - MNU_INSERT_OSF = gtk_menu_item_new_with_label("Insert OSF (One Shot Falling)"); - MNU_INSERT_TON = gtk_menu_item_new_with_label("Insert TON (Delayed Turn On)"); - MNU_INSERT_TOF = gtk_menu_item_new_with_label("Insert TOF (Delayed Turn Off)"); - MNU_INSERT_RTO = gtk_menu_item_new_with_label("Insert RTO (Retentive Delayed Turn On)"); - MNU_INSERT_CTU = gtk_menu_item_new_with_label("Insert CTU (Count Up)"); - MNU_INSERT_CTD = gtk_menu_item_new_with_label("Insert CTD (Count Down)"); - MNU_INSERT_CTC = gtk_menu_item_new_with_label("Insert CTC (Count Circular)"); - MNU_INSERT_EQU = gtk_menu_item_new_with_label("Insert EQU (Compare for Equals)"); - MNU_INSERT_NEQ = gtk_menu_item_new_with_label("Insert NEQ (Compare for Not Equals)"); - MNU_INSERT_GRT = gtk_menu_item_new_with_label("Insert GRT (Compare for Greater Than)"); - MNU_INSERT_GEQ = gtk_menu_item_new_with_label("Insert GEQ (Compare for Greater Than or Equal)"); - MNU_INSERT_LES = gtk_menu_item_new_with_label("Insert LES (Compare for Less Than)"); - MNU_INSERT_LEQ = gtk_menu_item_new_with_label("Insert LEQ (Compare for Less Than or Equal)"); - MNU_INSERT_OPEN = gtk_menu_item_new_with_label("Insert Open Circuit"); - MNU_INSERT_SHORT = gtk_menu_item_new_with_label("Insert Short Circuit"); - MNU_INSERT_MASTER_RLY = gtk_menu_item_new_with_label("Insert Master Control Relay"); - MNU_INSERT_COIL = gtk_menu_item_new_with_label("Insert Coil"); - MNU_INSERT_RES = gtk_menu_item_new_with_label("Insert RES (Counter/RTO Reset)"); - MNU_INSERT_MOV = gtk_menu_item_new_with_label("Insert MOV (Move)"); - MNU_INSERT_ADD = gtk_menu_item_new_with_label("Insert ADD (16-bit Integer Ad)"); - MNU_INSERT_SUB = gtk_menu_item_new_with_label("Insert SUB (16-bit Integer Subtract)"); - MNU_INSERT_MUL = gtk_menu_item_new_with_label("Insert MUL (16-bit Integer Multiply)"); - MNU_INSERT_DIV = gtk_menu_item_new_with_label("Insert DIV (16-bit Integer Division)"); - MNU_INSERT_SHIFT_REG = gtk_menu_item_new_with_label("Insert Shift Register"); - MNU_INSERT_LUT = gtk_menu_item_new_with_label("Insert Look-Up Table"); - MNU_INSERT_PWL = gtk_menu_item_new_with_label("Insert Piecewise Linear"); - MNU_INSERT_FMTD_STR = gtk_menu_item_new_with_label("Insert Formatted String Over UART"); - MNU_INSERT_UART_SEND = gtk_menu_item_new_with_label("Insert UART Send"); - MNU_INSERT_UART_RECV = gtk_menu_item_new_with_label("Insert UART Receive"); - MNU_INSERT_SET_PWM = gtk_menu_item_new_with_label("Insert Set PWM Output"); - MNU_INSERT_READ_ADC = gtk_menu_item_new_with_label("Insert A/D Converter Read"); - MNU_INSERT_PERSIST = gtk_menu_item_new_with_label("Insert Make Persistent"); - MNU_MAKE_NORMAL = gtk_menu_item_new_with_label("Make Normal"); - MNU_NEGATE = gtk_menu_item_new_with_label("Make Negated"); - MNU_MAKE_SET_ONLY = gtk_menu_item_new_with_label("Make Set-Only"); - MNU_MAKE_RESET_ONLY = gtk_menu_item_new_with_label("Make Reset-Only"); + InsertCommentMenu = gtk_menu_item_new_with_mnemonic("_Insert Comment"); + InsertContactsMenu = gtk_menu_item_new_with_mnemonic("_Insert Contacts"); + InsertOsrMenu = gtk_menu_item_new_with_mnemonic("_Insert OSR (One Shot Rising)"); + InsertOsfMenu = gtk_menu_item_new_with_mnemonic("_Insert OSF (One Shot Falling)"); + InsertTonMenu = gtk_menu_item_new_with_mnemonic("_Insert TON (Delayed Turn On)"); + InsertTofMenu = gtk_menu_item_new_with_mnemonic("_Insert TOF (Delayed Turn Off)"); + InsertRtoMenu = gtk_menu_item_new_with_mnemonic("_Insert RTO (Retentive Delayed Turn On)"); + InsertCtuMenu = gtk_menu_item_new_with_mnemonic("_Insert CTU (Count Up)"); + InsertCtdMenu = gtk_menu_item_new_with_mnemonic("_Insert CTD (Count Down)"); + InsertCtcMenu = gtk_menu_item_new_with_mnemonic("_Insert CTC (Count Circular)"); + InsertEquMenu = gtk_menu_item_new_with_mnemonic("_Insert EQU (Compare for Equals)"); + InsertNeqMenu = gtk_menu_item_new_with_mnemonic("_Insert NEQ (Compare for Not Equals)"); + InsertGrtMenu = gtk_menu_item_new_with_mnemonic("_Insert GRT (Compare for Greater Than)"); + InsertGeqMenu = gtk_menu_item_new_with_mnemonic("_Insert GEQ (Compare for Greater Than or Equal)"); + InsertLesMenu = gtk_menu_item_new_with_mnemonic("_Insert LES (Compare for Less Than)"); + InsertLeqMenu = gtk_menu_item_new_with_mnemonic("_Insert LEQ (Compare for Less Than or Equal)"); + InsertOpenMenu = gtk_menu_item_new_with_mnemonic("_Insert Open Circuit"); + InsertShortMenu = gtk_menu_item_new_with_mnemonic("_Insert Short Circuit"); + InsertMasterRlyMenu = gtk_menu_item_new_with_mnemonic("_Insert Master Control Relay"); + InsertCoilMenu = gtk_menu_item_new_with_mnemonic("_Insert Coil"); + InsertResMenu = gtk_menu_item_new_with_mnemonic("_Insert RES (Counter/RTO Reset)"); + InsertMovMenu = gtk_menu_item_new_with_mnemonic("_Insert MOV (Move)"); + InsertAddMenu = gtk_menu_item_new_with_mnemonic("_Insert ADD (16-bit Integer Ad)"); + InsertSubMenu = gtk_menu_item_new_with_mnemonic("_Insert SUB (16-bit Integer Subtract)"); + InsertMulMenu = gtk_menu_item_new_with_mnemonic("_Insert MUL (16-bit Integer Multiply)"); + InsertDivMenu = gtk_menu_item_new_with_mnemonic("_Insert DIV (16-bit Integer Division)"); + InsertShiftRegMenu = gtk_menu_item_new_with_mnemonic("_Insert Shift Register"); + InsertLutMenu = gtk_menu_item_new_with_mnemonic("_Insert Look-Up Table"); + InsertPwlMenu = gtk_menu_item_new_with_mnemonic("_Insert Piecewise Linear"); + InsertFmtdStrMenu = gtk_menu_item_new_with_mnemonic("_Insert Formatted String Over UART"); + InsertUartSendMenu = gtk_menu_item_new_with_mnemonic("_Insert UART Send"); + InsertUartRecvMenu = gtk_menu_item_new_with_mnemonic("_Insert UART Receive"); + InsertSetPwmMenu = gtk_menu_item_new_with_mnemonic("_Insert Set PWM Output"); + InsertReadAdcMenu = gtk_menu_item_new_with_mnemonic("_Insert A/D Converter Read"); + InsertPersistMenu = gtk_menu_item_new_with_mnemonic("_Insert Make Persistent"); + MakeNormalMenu = gtk_menu_item_new_with_mnemonic("_Make Normal"); + NegateMenu = gtk_menu_item_new_with_mnemonic("_Make Negated"); + MakeSetOnlyMenu = gtk_menu_item_new_with_mnemonic("_Make Set-Only"); + MakeResetOnlyMenu = gtk_menu_item_new_with_mnemonic("_Make Reset-Only"); // Appending menu items to Instruction menu and adding separators - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_COMMENT); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertCommentMenu); InstructionMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append (GTK_MENU_SHELL(InstructionMenu), InstructionMenuSeparator); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_CONTACTS); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertContactsMenu); InstructionMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append (GTK_MENU_SHELL(InstructionMenu), InstructionMenuSeparator); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_OSR); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertOsrMenu); InstructionMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append (GTK_MENU_SHELL(InstructionMenu), InstructionMenuSeparator); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_OSF); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_TON); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_TOF); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_RTO); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertOsfMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertTonMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertTofMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertRtoMenu); InstructionMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append (GTK_MENU_SHELL(InstructionMenu), InstructionMenuSeparator); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_CTU); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_CTD); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_CTC); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertCtuMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertCtdMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertCtcMenu); InstructionMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append (GTK_MENU_SHELL(InstructionMenu), InstructionMenuSeparator); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_EQU); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_NEQ); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_GRT); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_GEQ); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_LES); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_LEQ); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertEquMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertNeqMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertGrtMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertGeqMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertLesMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertLeqMenu); InstructionMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append (GTK_MENU_SHELL(InstructionMenu), InstructionMenuSeparator); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_OPEN); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_SHORT); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_MASTER_RLY); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertOpenMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertShortMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertMasterRlyMenu); InstructionMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append (GTK_MENU_SHELL(InstructionMenu), InstructionMenuSeparator); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_COIL); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_RES); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertCoilMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertResMenu); InstructionMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append (GTK_MENU_SHELL(InstructionMenu), InstructionMenuSeparator); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_MOV); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_ADD); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_SUB); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_MUL); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_DIV); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertMovMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertAddMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertSubMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertMulMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertDivMenu); InstructionMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append (GTK_MENU_SHELL(InstructionMenu), InstructionMenuSeparator); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_SHIFT_REG); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_LUT); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_PWL); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_FMTD_STR); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertShiftRegMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertLutMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertPwlMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertFmtdStrMenu); InstructionMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InstructionMenuSeparator); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_UART_SEND); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_UART_RECV); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_SET_PWM); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_READ_ADC); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_INSERT_PERSIST); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertUartSendMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertUartRecvMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertSetPwmMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertReadAdcMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InsertPersistMenu); InstructionMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), InstructionMenuSeparator); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_MAKE_NORMAL); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_NEGATE); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_MAKE_SET_ONLY); - gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MNU_MAKE_RESET_ONLY); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MakeNormalMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), NegateMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MakeSetOnlyMenu); + gtk_menu_shell_append (GTK_MENU_SHELL (InstructionMenu), MakeResetOnlyMenu); - // Creating labels for Simulation Menu - MNU_COMPILE = gtk_menu_item_new_with_label("Compile"); - MNU_COMPILE_AS = gtk_menu_item_new_with_label("Compile As..."); + // Creating labels for Compile Menu + CompileMenu = gtk_menu_item_new_with_mnemonic("_Compile"); + CompileAsMenu = gtk_menu_item_new_with_mnemonic("_Compile As..."); // Appending menu items to Compile menu - gtk_menu_shell_append(GTK_MENU_SHELL (compile), MNU_COMPILE); - gtk_menu_shell_append(GTK_MENU_SHELL (compile), MNU_COMPILE_AS); + gtk_menu_shell_append(GTK_MENU_SHELL (Compile), CompileMenu); + gtk_menu_shell_append(GTK_MENU_SHELL (Compile), CompileAsMenu); - // Creating labels for Simulation Menu - MNU_MANUAL = gtk_menu_item_new_with_label("Manual..."); - MNU_ABOUT = gtk_menu_item_new_with_label("About..."); + // Creating labels for Help Menu + ManualMenu = gtk_menu_item_new_with_mnemonic("_Manual..."); + AboutMenu = gtk_menu_item_new_with_mnemonic("_About..."); // Appending menu items to Help menu - gtk_menu_shell_append(GTK_MENU_SHELL (help), MNU_MANUAL); - gtk_menu_shell_append(GTK_MENU_SHELL (help), MNU_ABOUT); + gtk_menu_shell_append(GTK_MENU_SHELL (Help), ManualMenu); + gtk_menu_shell_append(GTK_MENU_SHELL (Help), AboutMenu); // Creating labels for Simulation Menu - MNU_SIMULATION_MODE = gtk_check_menu_item_new_with_label("Simulation Mode"); - MNU_START_SIMULATION = gtk_menu_item_new_with_label("Start Real-Time Simulation"); - MNU_STOP_SIMULATION = gtk_menu_item_new_with_label("Halt Simulation"); - MNU_SINGLE_CYCLE = gtk_menu_item_new_with_label("Single Cycle"); + SimulationModeMenu = gtk_check_menu_item_new_with_mnemonic("_Simulation Mode"); + StartSimulationMenu = gtk_menu_item_new_with_mnemonic("_Start Real-Time Simulation"); + StopSimulationMenu = gtk_menu_item_new_with_mnemonic("_Halt Simulation"); + SingleCycleMenu = gtk_menu_item_new_with_mnemonic("_Single Cycle"); // Appending menu items to Simulate menu and adding separators - gtk_menu_shell_append(GTK_MENU_SHELL (SimulateMenu), MNU_SIMULATION_MODE); - gtk_menu_shell_append(GTK_MENU_SHELL (SimulateMenu), MNU_START_SIMULATION); - gtk_menu_shell_append(GTK_MENU_SHELL (SimulateMenu), MNU_STOP_SIMULATION); - gtk_menu_shell_append(GTK_MENU_SHELL (SimulateMenu), MNU_SINGLE_CYCLE); + gtk_menu_shell_append(GTK_MENU_SHELL (SimulateMenu), SimulationModeMenu); + gtk_menu_shell_append(GTK_MENU_SHELL (SimulateMenu), StartSimulationMenu); + gtk_menu_shell_append(GTK_MENU_SHELL (SimulateMenu), StopSimulationMenu); + gtk_menu_shell_append(GTK_MENU_SHELL (SimulateMenu), SingleCycleMenu); SimulateMenuSeparator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(SimulateMenu), SimulateMenuSeparator); // Creating submenus for each menu gtk_menu_item_set_submenu(GTK_MENU_ITEM(FileLabel), FileMenu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(EditLabel), EditMenu); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(SettingsLabel), settings); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(SettingsLabel), Settings); gtk_menu_item_set_submenu(GTK_MENU_ITEM(InstructionLabel), InstructionMenu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(SimulateLabel), SimulateMenu); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(CompileLabel), compile); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(HelpLabel), help); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(CompileLabel), Compile); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(HelpLabel), Help); // Appending the menu item to the menu bar gtk_menu_shell_append(GTK_MENU_SHELL(TopMenu), FileLabel); @@ -401,7 +511,8 @@ HMENU MakeMainWindowMenus(void) // Packing the menu bar into the box for alignment gtk_box_pack_start(GTK_BOX(MenuBox), TopMenu, FALSE, FALSE, 0); - + AddMenuAccelerators (); + return MenuBox; } @@ -411,12 +522,12 @@ HMENU MakeMainWindowMenus(void) //----------------------------------------------------------------------------- void MakeMainWindowControls(void) { - HWID PackBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + HWID PackBoxMenu = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); HWID grid = gtk_grid_new(); /// 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, @@ -430,6 +541,7 @@ void MakeMainWindowControls(void) /// Creating a list view = gtk_tree_view_new_with_model (GTK_TREE_MODEL(IoList)); gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (IoList)); + gtk_tree_view_set_enable_search (GTK_TREE_VIEW (view), FALSE); column = gtk_tree_view_column_new_with_attributes("Name", gtk_cell_renderer_text_new(), @@ -471,7 +583,7 @@ void MakeMainWindowControls(void) /// Creating Scrolled Window ScrollWindow = gtk_scrolled_window_new (NULL, NULL); - HWID viewport = gtk_viewport_new (NULL,NULL); + HWID ViewPortMenu = gtk_viewport_new (NULL,NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (ScrollWindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); @@ -479,27 +591,66 @@ void MakeMainWindowControls(void) gtk_widget_set_vexpand(GTK_WIDGET(ScrollWindow), TRUE); /// Adding DrawWindow to pane - gtk_container_add (GTK_CONTAINER(viewport), DrawWindow); - gtk_container_add (GTK_CONTAINER(ScrollWindow), viewport); - gtk_paned_add1 (GTK_PANED (pane), ScrollWindow); + 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); - + + /// 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_set_position (GTK_PANED (pane), 250); + 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 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 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); - /// 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), "Introduction"), - "LDMicro Started"); + /// Attach status grid to box + gtk_box_pack_start(GTK_BOX(PackBoxMenu), StatusGrid, FALSE, FALSE, 0); - /// Appneding Status Bar to box which is then added to Main Window - gtk_box_pack_start(GTK_BOX(PackBox), grid, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(PackBox), StatusBar, FALSE, FALSE, 0); - gtk_container_add(GTK_CONTAINER(MainWindow), PackBox); + /// Adding box to Main Window + gtk_container_add(GTK_CONTAINER(MainWindow), PackBoxMenu); } //----------------------------------------------------------------------------- @@ -509,8 +660,9 @@ void MakeMainWindowControls(void) //----------------------------------------------------------------------------- void RefreshScrollbars(void) { - // SCROLLINFO vert, horiz; - // SetUpScrollbars(&NeedHoriz, &horiz, &vert); + SCROLLINFO vert, horiz; + SetUpScrollbars(&NeedHoriz, &horiz, &vert); + // SetScrollInfo(HorizScrollBar, SB_CTL, &horiz, TRUE); // SetScrollInfo(VertScrollBar, SB_CTL, &vert, TRUE); @@ -531,44 +683,44 @@ void RefreshScrollbars(void) // MoveWindow(VertScrollBar, main.right - ScrollWidth - 2, 1, ScrollWidth, // NeedHoriz ? (IoListTop - ScrollHeight - 4) : (IoListTop - 3), TRUE); - // InvalidateRect(MainWindow, NULL, FALSE); + InvalidateRect(DrawWindow, NULL, FALSE); } //----------------------------------------------------------------------------- // Respond to a WM_VSCROLL sent to the main window, presumably by the one and // only vertical scrollbar that it has as a child. //----------------------------------------------------------------------------- -void VscrollProc(WPARAM wParam) +void VscrollProc(int wParam) { - // int prevY = ScrollYOffset; - // switch(LOWORD(wParam)) { - // case SB_LINEUP: - // case SB_PAGEUP: - // if(ScrollYOffset > 0) { - // ScrollYOffset--; - // } - // break; - - // case SB_LINEDOWN: - // case SB_PAGEDOWN: - // if(ScrollYOffset < ScrollYOffsetMax) { - // ScrollYOffset++; - // } - // break; - - // case SB_TOP: - // ScrollYOffset = 0; - // break; - - // case SB_BOTTOM: - // ScrollYOffset = ScrollYOffsetMax; - // break; - - // case SB_THUMBTRACK: - // case SB_THUMBPOSITION: - // ScrollYOffset = HIWORD(wParam); - // break; - // } + int prevY = ScrollYOffset; + switch(wParam) { + case SB_LINEUP: + case SB_PAGEUP: + if(ScrollYOffset > 0) { + ScrollYOffset--; + } + break; + + case SB_LINEDOWN: + case SB_PAGEDOWN: + if(ScrollYOffset < ScrollYOffsetMax) { + ScrollYOffset++; + } + break; + + case SB_TOP: + ScrollYOffset = 0; + break; + + case SB_BOTTOM: + ScrollYOffset = ScrollYOffsetMax; + break; + + // case SB_THUMBTRACK: + // case SB_THUMBPOSITION: + // ScrollYOffset = HIWORD(wParam); + // break; + } // if(prevY != ScrollYOffset) { // SCROLLINFO si; // si.cbSize = sizeof(si); @@ -584,42 +736,42 @@ void VscrollProc(WPARAM wParam) // Respond to a WM_HSCROLL sent to the main window, presumably by the one and // only horizontal scrollbar that it has as a child. //----------------------------------------------------------------------------- -void HscrollProc(WPARAM wParam) +void HscrollProc(int wParam) { - // int prevX = ScrollXOffset; - // switch(LOWORD(wParam)) { - // case SB_LINEUP: - // ScrollXOffset -= FONT_WIDTH; - // break; - - // case SB_PAGEUP: - // ScrollXOffset -= POS_WIDTH*FONT_WIDTH; - // break; - - // case SB_LINEDOWN: - // ScrollXOffset += FONT_WIDTH; - // break; - - // case SB_PAGEDOWN: - // ScrollXOffset += POS_WIDTH*FONT_WIDTH; - // break; - - // case SB_TOP: - // ScrollXOffset = 0; - // break; - - // case SB_BOTTOM: - // ScrollXOffset = ScrollXOffsetMax; - // break; - - // case SB_THUMBTRACK: - // case SB_THUMBPOSITION: - // ScrollXOffset = HIWORD(wParam); - // break; - // } + int prevX = ScrollXOffset; + switch(wParam) { + case SB_LINEUP: + ScrollXOffset -= FONT_WIDTH; + break; + + case SB_PAGEUP: + ScrollXOffset -= POS_WIDTH*FONT_WIDTH; + break; + + case SB_LINEDOWN: + ScrollXOffset += FONT_WIDTH; + break; + + case SB_PAGEDOWN: + ScrollXOffset += POS_WIDTH*FONT_WIDTH; + break; + + case SB_TOP: + ScrollXOffset = 0; + break; + + case SB_BOTTOM: + ScrollXOffset = ScrollXOffsetMax; + break; - // if(ScrollXOffset > ScrollXOffsetMax) ScrollXOffset = ScrollXOffsetMax; - // if(ScrollXOffset < 0) ScrollXOffset = 0; + // case SB_THUMBTRACK: + // case SB_THUMBPOSITION: + // ScrollXOffset = HIWORD(wParam); + // break; + } + + if(ScrollXOffset > ScrollXOffsetMax) ScrollXOffset = ScrollXOffsetMax; + if(ScrollXOffset < 0) ScrollXOffset = 0; // if(prevX != ScrollXOffset) { // SCROLLINFO si; @@ -665,66 +817,66 @@ void SetMenusEnabled(BOOL canNegate, BOOL canNormal, BOOL canResetOnly, BOOL canSetOnly, BOOL canDelete, BOOL canInsertEnd, BOOL canInsertOther, BOOL canPushDown, BOOL canPushUp, BOOL canInsertComment) { - EnableMenuItem(EditMenu, MNU_PUSH_RUNG_UP, + EnableMenuItem(EditMenu, PushRungUpMenu, canPushUp ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(EditMenu, MNU_PUSH_RUNG_DOWN, + EnableMenuItem(EditMenu, PushRungDownMenu, canPushDown ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(EditMenu, MNU_DELETE_RUNG, + EnableMenuItem(EditMenu, DeleteRungMenu, (Prog.numRungs > 1) ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(InstructionMenu, MNU_NEGATE, + EnableMenuItem(InstructionMenu, NegateMenu, canNegate ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(InstructionMenu, MNU_MAKE_NORMAL, + EnableMenuItem(InstructionMenu, MakeNormalMenu, canNormal ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(InstructionMenu, MNU_MAKE_RESET_ONLY, + EnableMenuItem(InstructionMenu, MakeResetOnlyMenu, canResetOnly ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(InstructionMenu, MNU_MAKE_SET_ONLY, + EnableMenuItem(InstructionMenu, MakeSetOnlyMenu, canSetOnly ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(InstructionMenu, MNU_INSERT_COMMENT, + EnableMenuItem(InstructionMenu, InsertCommentMenu, canInsertComment ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(EditMenu, MNU_DELETE_ELEMENT, + EnableMenuItem(EditMenu, DeleteElementMenu, canDelete ? MF_ENABLED : MF_GRAYED); int t; t = canInsertEnd ? MF_ENABLED : MF_GRAYED; - EnableMenuItem(InstructionMenu, MNU_INSERT_COIL, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_RES, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_MOV, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_ADD, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_SUB, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_MUL, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_DIV, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_CTC, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_PERSIST, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_READ_ADC, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_SET_PWM, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_MASTER_RLY, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_SHIFT_REG, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_LUT, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_PWL, t); + EnableMenuItem(InstructionMenu, InsertCoilMenu, t); + EnableMenuItem(InstructionMenu, InsertResMenu, t); + EnableMenuItem(InstructionMenu, InsertMovMenu, t); + EnableMenuItem(InstructionMenu, InsertAddMenu, t); + EnableMenuItem(InstructionMenu, InsertSubMenu, t); + EnableMenuItem(InstructionMenu, InsertMulMenu, t); + EnableMenuItem(InstructionMenu, InsertDivMenu, t); + EnableMenuItem(InstructionMenu, InsertCtcMenu, t); + EnableMenuItem(InstructionMenu, InsertPersistMenu, t); + EnableMenuItem(InstructionMenu, InsertReadAdcMenu, t); + EnableMenuItem(InstructionMenu, InsertSetPwmMenu, t); + EnableMenuItem(InstructionMenu, InsertMasterRlyMenu, t); + EnableMenuItem(InstructionMenu, InsertShiftRegMenu, t); + EnableMenuItem(InstructionMenu, InsertLutMenu, t); + EnableMenuItem(InstructionMenu, InsertPwlMenu, t); t = canInsertOther ? MF_ENABLED : MF_GRAYED; - EnableMenuItem(InstructionMenu, MNU_INSERT_TON, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_TOF, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_OSR, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_OSF, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_RTO, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_CONTACTS, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_CTU, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_CTD, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_EQU, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_NEQ, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_GRT, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_GEQ, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_LES, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_LEQ, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_SHORT, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_OPEN, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_UART_SEND, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_UART_RECV, t); - EnableMenuItem(InstructionMenu, MNU_INSERT_FMTD_STR, t); + EnableMenuItem(InstructionMenu, InsertTonMenu, t); + EnableMenuItem(InstructionMenu, InsertTofMenu, t); + EnableMenuItem(InstructionMenu, InsertOsrMenu, t); + EnableMenuItem(InstructionMenu, InsertOsfMenu, t); + EnableMenuItem(InstructionMenu, InsertRtoMenu, t); + EnableMenuItem(InstructionMenu, InsertContactsMenu, t); + EnableMenuItem(InstructionMenu, InsertCtuMenu, t); + EnableMenuItem(InstructionMenu, InsertCtdMenu, t); + EnableMenuItem(InstructionMenu, InsertEquMenu, t); + EnableMenuItem(InstructionMenu, InsertNeqMenu, t); + EnableMenuItem(InstructionMenu, InsertGrtMenu, t); + EnableMenuItem(InstructionMenu, InsertGeqMenu, t); + EnableMenuItem(InstructionMenu, InsertLesMenu, t); + EnableMenuItem(InstructionMenu, InsertLeqMenu, t); + EnableMenuItem(InstructionMenu, InsertShortMenu, t); + EnableMenuItem(InstructionMenu, InsertOpenMenu, t); + EnableMenuItem(InstructionMenu, InsertUartSendMenu, t); + EnableMenuItem(InstructionMenu, InsertUartRecvMenu, t); + EnableMenuItem(InstructionMenu, InsertFmtdStrMenu, t); } //----------------------------------------------------------------------------- @@ -732,8 +884,8 @@ void SetMenusEnabled(BOOL canNegate, BOOL canNormal, BOOL canResetOnly, //----------------------------------------------------------------------------- void SetUndoEnabled(BOOL undoEnabled, BOOL redoEnabled) { - // EnableMenuItem(EditMenu, MNU_UNDO, undoEnabled ? MF_ENABLED : MF_GRAYED); - // EnableMenuItem(EditMenu, MNU_REDO, redoEnabled ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(EditMenu, UndoMenu, undoEnabled ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(EditMenu, RedoMenu, redoEnabled ? MF_ENABLED : MF_GRAYED); } //----------------------------------------------------------------------------- @@ -744,53 +896,53 @@ void ToggleSimulationMode(void) { InSimulationMode = !InSimulationMode; if(InSimulationMode) { - EnableMenuItem(SimulateMenu, MNU_START_SIMULATION, MF_ENABLED); - EnableMenuItem(SimulateMenu, MNU_SINGLE_CYCLE, MF_ENABLED); + EnableMenuItem(SimulateMenu, StartSimulationMenu, MF_ENABLED); + EnableMenuItem(SimulateMenu, SingleCycleMenu, MF_ENABLED); - EnableMenuItem(FileMenu, MNU_OPEN, MF_GRAYED); - EnableMenuItem(FileMenu, MNU_SAVE, MF_GRAYED); - EnableMenuItem(FileMenu, MNU_SAVE_AS, MF_GRAYED); - EnableMenuItem(FileMenu, MNU_NEW, MF_GRAYED); - EnableMenuItem(FileMenu, MNU_EXPORT, MF_GRAYED); + EnableMenuItem(FileMenu, OpenMenu, MF_GRAYED); + EnableMenuItem(FileMenu, SaveMenu, MF_GRAYED); + EnableMenuItem(FileMenu, SaveAsMenu, MF_GRAYED); + EnableMenuItem(FileMenu, NewMenu, MF_GRAYED); + EnableMenuItem(FileMenu, ExportMenu, MF_GRAYED); EnableMenuItem(TopMenu, EditMenu, MF_GRAYED); - EnableMenuItem(TopMenu, settings, MF_GRAYED); + EnableMenuItem(TopMenu, Settings, MF_GRAYED); EnableMenuItem(TopMenu, InstructionMenu, MF_GRAYED); - EnableMenuItem(TopMenu, compile, MF_GRAYED); - - CheckMenuItem(SimulateMenu, MNU_SIMULATION_MODE, MF_CHECKED); + EnableMenuItem(TopMenu, Compile, MF_GRAYED); + + CheckMenuItem(SimulateMenu, SimulationModeMenu, MF_CHECKED); - // ClearSimulationData(); // simulation.cpp, ldmicro.h - // Recheck InSimulationMode, because there could have been a compile + 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, MNU_START_SIMULATION, MF_GRAYED); - EnableMenuItem(SimulateMenu, MNU_STOP_SIMULATION, MF_GRAYED); - EnableMenuItem(SimulateMenu, MNU_SINGLE_CYCLE, MF_GRAYED); + EnableMenuItem(SimulateMenu, StartSimulationMenu, MF_GRAYED); + EnableMenuItem(SimulateMenu, StopSimulationMenu, MF_GRAYED); + EnableMenuItem(SimulateMenu, SingleCycleMenu, MF_GRAYED); - EnableMenuItem(FileMenu, MNU_OPEN, MF_ENABLED); - EnableMenuItem(FileMenu, MNU_SAVE, MF_ENABLED); - EnableMenuItem(FileMenu, MNU_SAVE_AS, MF_ENABLED); - EnableMenuItem(FileMenu, MNU_NEW, MF_ENABLED); - EnableMenuItem(FileMenu, MNU_EXPORT, MF_ENABLED); + EnableMenuItem(FileMenu, OpenMenu, MF_ENABLED); + EnableMenuItem(FileMenu, SaveMenu, MF_ENABLED); + EnableMenuItem(FileMenu, SaveAsMenu, MF_ENABLED); + EnableMenuItem(FileMenu, NewMenu, MF_ENABLED); + EnableMenuItem(FileMenu, ExportMenu, MF_ENABLED); EnableMenuItem(TopMenu, EditMenu, MF_ENABLED); - EnableMenuItem(TopMenu, settings, MF_ENABLED); + EnableMenuItem(TopMenu, Settings, MF_ENABLED); EnableMenuItem(TopMenu, InstructionMenu, MF_ENABLED); - EnableMenuItem(TopMenu, compile, MF_ENABLED); + EnableMenuItem(TopMenu, Compile, MF_ENABLED); - CheckMenuItem(SimulateMenu, MNU_SIMULATION_MODE, MF_UNCHECKED); + CheckMenuItem(SimulateMenu, SimulationModeMenu, MF_UNCHECKED); - // if(UartFunctionUsed()) { - // DestroyUartSimulationWindow(); - // } + if(UartFunctionUsed()) { + DestroyUartSimulationWindow(); + } } UpdateMainWindowTitleBar(); @@ -804,50 +956,102 @@ 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, MNU_PROCESSOR[i], MF_CHECKED); + CheckMenuItem(ProcessorMenu, ProcessorMenuItems[i], MF_CHECKED); } else { - CheckMenuItem(ProcessorMenu, MNU_PROCESSOR[i], MF_UNCHECKED); + CheckMenuItem(ProcessorMenu, ProcessorMenuItems[i], MF_UNCHECKED); } } // `(no microcontroller)' setting if (!Prog.mcu){ - CheckMenuItem(ProcessorMenu, MNU_PROCESSOR[NUM_SUPPORTED_MCUS], MF_CHECKED); + CheckMenuItem(ProcessorMenu, ProcessorMenuItems[NUM_SUPPORTED_MCUS], MF_CHECKED); } else { - CheckMenuItem(ProcessorMenu, MNU_PROCESSOR[NUM_SUPPORTED_MCUS], MF_UNCHECKED); + CheckMenuItem(ProcessorMenu, ProcessorMenuItems[NUM_SUPPORTED_MCUS], MF_UNCHECKED); } } @@ -857,24 +1061,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(); } @@ -885,10 +1106,33 @@ void GenerateIoListDontLoseSelection(void) //----------------------------------------------------------------------------- void MainWindowResized(void) { + RECT main; + GetClientRect(DrawWindow, &main); + + RECT status; + // GetWindowRect(StatusBar, &status); + // int statusHeight = status.bottom - status.top; + + // MoveWindow(StatusBar, 0, main.bottom - statusHeight, main.right, + // statusHeight, TRUE); + // Make sure that the I/O list can't disappear entirely. if(IoListHeight < 30) { IoListHeight = 30; } + IoListTop = main.bottom ;//- IoListHeight - statusHeight; + + // 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 - 5;//- statusHeight - 5; + IoListTop = main.bottom - IoListHeight;// - statusHeight; + } + // MoveWindow(IoList, 0, IoListTop, main.right, IoListHeight, TRUE); + + RefreshScrollbars(); + + InvalidateRect(DrawWindow, NULL, FALSE); } //----------------------------------------------------------------------------- @@ -898,9 +1142,9 @@ void MainWindowResized(void) void StartSimulation(void) { RealTimeSimulationRunning = TRUE; - EnableMenuItem(SimulateMenu, MNU_START_SIMULATION, MF_GRAYED); - EnableMenuItem(SimulateMenu, MNU_STOP_SIMULATION, MF_ENABLED); - // StartSimulationTimer(); + EnableMenuItem(SimulateMenu, StartSimulationMenu, MF_GRAYED); + EnableMenuItem(SimulateMenu, StopSimulationMenu, MF_ENABLED); + StartSimulationTimer(); UpdateMainWindowTitleBar(); } @@ -912,9 +1156,9 @@ void StopSimulation(void) { RealTimeSimulationRunning = FALSE; - EnableMenuItem(SimulateMenu, MNU_START_SIMULATION, MF_ENABLED); - EnableMenuItem(SimulateMenu, MNU_STOP_SIMULATION, MF_GRAYED); - // KillTimer(MainWindow, TIMER_SIMULATE); - + EnableMenuItem(SimulateMenu, StartSimulationMenu, MF_ENABLED); + EnableMenuItem(SimulateMenu, StopSimulationMenu, MF_GRAYED); + KillTimer(MainWindow, TIMER_SIMULATE); + UpdateMainWindowTitleBar(); }
\ No newline at end of file diff --git a/ldmicro/miscutil.cpp b/ldmicro/miscutil.cpp index 092f606..f0f9aa8 100644 --- a/ldmicro/miscutil.cpp +++ b/ldmicro/miscutil.cpp @@ -23,9 +23,11 @@ #include "linuxUI.h" #include <stdio.h> #include <stdlib.h> - +#include <iostream> #include "ldmicro.h" +using namespace std; + // We should display messages to the user differently if we are running // interactively vs. in batch (command-line) mode. BOOL RunningInBatchMode = FALSE; @@ -38,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; @@ -51,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"); } //----------------------------------------------------------------------------- @@ -100,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); } } @@ -130,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(); + // // } } //----------------------------------------------------------------------------- @@ -202,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); @@ -216,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; @@ -251,8 +258,8 @@ static LRESULT CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wParam, // return DefWindowProc(hwnd, msg, wParam, lParam); // } - return 1; -} +// return 1; +// } @@ -261,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); } @@ -269,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); } @@ -298,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..238814a 100644 --- a/ldmicro/resetdialog.cpp +++ b/ldmicro/resetdialog.cpp @@ -24,125 +24,133 @@ #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; +static HWID ResetGrid; +static 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); + + g_signal_connect (G_OBJECT(NameTextbox), "insert-text", + G_CALLBACK(ResetDialogMyNameProc), NULL); +} + +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 (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 28d5eac..661f841 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. @@ -83,43 +86,43 @@ BOOL FindSelected(int *gx, int *gy) //----------------------------------------------------------------------------- void SelectElement(int gx, int gy, int state) { -// if(gx < 0 || gy < 0) { -// if(!FindSelected(&gx, &gy)) { -// return; -// } -// } - -// if(Selected) Selected->selectedState = SELECTED_NONE; - -// Selected = DisplayMatrix[gx][gy]; -// SelectedWhich = DisplayMatrixWhich[gx][gy]; - -// if(SelectedWhich == ELEM_PLACEHOLDER) { -// state = SELECTED_LEFT; -// } - -// if((gy - ScrollYOffset) >= ScreenRowsAvailable()) { -// ScrollYOffset = gy - ScreenRowsAvailable() + 1; -// RefreshScrollbars(); -// } -// if((gy - ScrollYOffset) < 0) { -// ScrollYOffset = gy; -// RefreshScrollbars(); -// } -// if((gx - ScrollXOffset*POS_WIDTH*FONT_WIDTH) >= ScreenColsAvailable()) { -// ScrollXOffset = gx*POS_WIDTH*FONT_WIDTH - ScreenColsAvailable(); -// RefreshScrollbars(); -// } -// if((gx - ScrollXOffset*POS_WIDTH*FONT_WIDTH) < 0) { -// ScrollXOffset = gx*POS_WIDTH*FONT_WIDTH; -// RefreshScrollbars(); -// } - -// ok(); -// Selected->selectedState = state; -// ok(); - -// WhatCanWeDoFromCursorAndTopology(); + if(gx < 0 || gy < 0) { + if(!FindSelected(&gx, &gy)) { + return; + } + } + + if(Selected) Selected->selectedState = SELECTED_NONE; + + Selected = DisplayMatrix[gx][gy]; + SelectedWhich = DisplayMatrixWhich[gx][gy]; + + if(SelectedWhich == ELEM_PLACEHOLDER) { + state = SELECTED_LEFT; + } + + if((gy - ScrollYOffset) >= ScreenRowsAvailable()) { + ScrollYOffset = gy - ScreenRowsAvailable() + 1; + RefreshScrollbars(); + } + if((gy - ScrollYOffset) < 0) { + ScrollYOffset = gy; + RefreshScrollbars(); + } + if((gx - ScrollXOffset*POS_WIDTH*FONT_WIDTH) >= ScreenColsAvailable()) { + ScrollXOffset = gx*POS_WIDTH*FONT_WIDTH - ScreenColsAvailable(); + RefreshScrollbars(); + } + if((gx - ScrollXOffset*POS_WIDTH*FONT_WIDTH) < 0) { + ScrollXOffset = gx*POS_WIDTH*FONT_WIDTH; + RefreshScrollbars(); + } + + ok(); + Selected->selectedState = state; + ok(); + + WhatCanWeDoFromCursorAndTopology(); } //----------------------------------------------------------------------------- @@ -129,86 +132,86 @@ void SelectElement(int gx, int gy, int state) //----------------------------------------------------------------------------- void WhatCanWeDoFromCursorAndTopology(void) { -// BOOL canNegate = FALSE, canNormal = FALSE; -// BOOL canResetOnly = FALSE, canSetOnly = FALSE; -// BOOL canPushUp = TRUE, canPushDown = TRUE; - -// BOOL canDelete = TRUE; - -// int i = RungContainingSelected(); -// if(i >= 0) { -// if(i == 0) canPushUp = FALSE; -// if(i == (Prog.numRungs-1)) canPushDown = FALSE; - -// if(Prog.rungs[i]->count == 1 && -// Prog.rungs[i]->contents[0].which == ELEM_PLACEHOLDER) -// { -// canDelete = FALSE; -// } -// } - -// CanInsertEnd = FALSE; -// CanInsertOther = TRUE; - -// if(Selected && -// (SelectedWhich == ELEM_COIL || -// SelectedWhich == ELEM_RES || -// SelectedWhich == ELEM_ADD || -// SelectedWhich == ELEM_SUB || -// SelectedWhich == ELEM_MUL || -// SelectedWhich == ELEM_DIV || -// SelectedWhich == ELEM_CTC || -// SelectedWhich == ELEM_READ_ADC || -// SelectedWhich == ELEM_SET_PWM || -// SelectedWhich == ELEM_MASTER_RELAY || -// SelectedWhich == ELEM_SHIFT_REGISTER || -// SelectedWhich == ELEM_LOOK_UP_TABLE || -// SelectedWhich == ELEM_PIECEWISE_LINEAR || -// SelectedWhich == ELEM_PERSIST || -// SelectedWhich == ELEM_MOVE)) -// { -// if(SelectedWhich == ELEM_COIL) { -// canNegate = TRUE; -// canNormal = TRUE; -// canResetOnly = TRUE; -// canSetOnly = TRUE; -// } - -// if(Selected->selectedState == SELECTED_ABOVE || -// Selected->selectedState == SELECTED_BELOW) -// { -// CanInsertEnd = TRUE; -// CanInsertOther = FALSE; -// } else if(Selected->selectedState == SELECTED_RIGHT) { -// CanInsertEnd = FALSE; -// CanInsertOther = FALSE; -// } -// } else if(Selected) { -// if(Selected->selectedState == SELECTED_RIGHT || -// SelectedWhich == ELEM_PLACEHOLDER) -// { -// CanInsertEnd = ItemIsLastInCircuit(Selected); -// } -// } -// if(SelectedWhich == ELEM_CONTACTS) { -// canNegate = TRUE; -// canNormal = TRUE; -// } -// if(SelectedWhich == ELEM_PLACEHOLDER) { -// // a comment must be the only element in its rung, and it will fill -// // the rung entirely -// CanInsertComment = TRUE; -// } else { -// CanInsertComment = FALSE; -// } -// if(SelectedWhich == ELEM_COMMENT) { -// // if there's a comment there already then don't let anything else -// // into the rung -// CanInsertEnd = FALSE; -// CanInsertOther = FALSE; -// } -// SetMenusEnabled(canNegate, canNormal, canResetOnly, canSetOnly, canDelete, -// CanInsertEnd, CanInsertOther, canPushDown, canPushUp, CanInsertComment); + BOOL canNegate = FALSE, canNormal = FALSE; + BOOL canResetOnly = FALSE, canSetOnly = FALSE; + BOOL canPushUp = TRUE, canPushDown = TRUE; + + BOOL canDelete = TRUE; + + int i = RungContainingSelected(); + if(i >= 0) { + if(i == 0) canPushUp = FALSE; + if(i == (Prog.numRungs-1)) canPushDown = FALSE; + + if(Prog.rungs[i]->count == 1 && + Prog.rungs[i]->contents[0].which == ELEM_PLACEHOLDER) + { + canDelete = FALSE; + } + } + + CanInsertEnd = FALSE; + CanInsertOther = TRUE; + + if(Selected && + (SelectedWhich == ELEM_COIL || + SelectedWhich == ELEM_RES || + SelectedWhich == ELEM_ADD || + SelectedWhich == ELEM_SUB || + SelectedWhich == ELEM_MUL || + SelectedWhich == ELEM_DIV || + SelectedWhich == ELEM_CTC || + SelectedWhich == ELEM_READ_ADC || + SelectedWhich == ELEM_SET_PWM || + SelectedWhich == ELEM_MASTER_RELAY || + SelectedWhich == ELEM_SHIFT_REGISTER || + SelectedWhich == ELEM_LOOK_UP_TABLE || + SelectedWhich == ELEM_PIECEWISE_LINEAR || + SelectedWhich == ELEM_PERSIST || + SelectedWhich == ELEM_MOVE)) + { + if(SelectedWhich == ELEM_COIL) { + canNegate = TRUE; + canNormal = TRUE; + canResetOnly = TRUE; + canSetOnly = TRUE; + } + + if(Selected->selectedState == SELECTED_ABOVE || + Selected->selectedState == SELECTED_BELOW) + { + CanInsertEnd = TRUE; + CanInsertOther = FALSE; + } else if(Selected->selectedState == SELECTED_RIGHT) { + CanInsertEnd = FALSE; + CanInsertOther = FALSE; + } + } else if(Selected) { + if(Selected->selectedState == SELECTED_RIGHT || + SelectedWhich == ELEM_PLACEHOLDER) + { + CanInsertEnd = ItemIsLastInCircuit(Selected); + } + } + if(SelectedWhich == ELEM_CONTACTS) { + canNegate = TRUE; + canNormal = TRUE; + } + if(SelectedWhich == ELEM_PLACEHOLDER) { + // a comment must be the only element in its rung, and it will fill + // the rung entirely + CanInsertComment = TRUE; + } else { + CanInsertComment = FALSE; + } + if(SelectedWhich == ELEM_COMMENT) { + // if there's a comment there already then don't let anything else + // into the rung + CanInsertEnd = FALSE; + CanInsertOther = FALSE; + } + SetMenusEnabled(canNegate, canNormal, canResetOnly, canSetOnly, canDelete, + CanInsertEnd, CanInsertOther, canPushDown, canPushUp, CanInsertComment); } //----------------------------------------------------------------------------- @@ -250,32 +253,32 @@ void ForgetEverything(void) //----------------------------------------------------------------------------- BOOL MoveCursorTopLeft(void) { -// int i, j; -// // Let us first try to place it somewhere on-screen, so start at the -// // vertical scroll offset, not the very top (to avoid placing the -// // cursor in a position that would force us to scroll to put it in to -// // view.) -// for(i = 0; i < DISPLAY_MATRIX_X_SIZE; i++) { -// for(j = ScrollYOffset; -// j < DISPLAY_MATRIX_Y_SIZE && j < (ScrollYOffset+16); j++) -// { -// if(VALID_LEAF(DisplayMatrix[i][j])) { -// SelectElement(i, j, SELECTED_LEFT); -// return TRUE; -// } -// } -// } - -// // If that didn't work, then try anywhere on the diagram before giving -// // up entirely. -// for(i = 0; i < DISPLAY_MATRIX_X_SIZE; i++) { -// for(j = 0; j < 16; j++) { -// if(VALID_LEAF(DisplayMatrix[i][j])) { -// SelectElement(i, j, SELECTED_LEFT); -// return TRUE; -// } -// } -// } + int i, j; + // Let us first try to place it somewhere on-screen, so start at the + // vertical scroll offset, not the very top (to avoid placing the + // cursor in a position that would force us to scroll to put it in to + // view.) + for(i = 0; i < DISPLAY_MATRIX_X_SIZE; i++) { + for(j = ScrollYOffset; + j < DISPLAY_MATRIX_Y_SIZE && j < (ScrollYOffset+16); j++) + { + if(VALID_LEAF(DisplayMatrix[i][j])) { + SelectElement(i, j, SELECTED_LEFT); + return TRUE; + } + } + } + + // If that didn't work, then try anywhere on the diagram before giving + // up entirely. + for(i = 0; i < DISPLAY_MATRIX_X_SIZE; i++) { + for(j = 0; j < 16; j++) { + if(VALID_LEAF(DisplayMatrix[i][j])) { + SelectElement(i, j, SELECTED_LEFT); + return TRUE; + } + } + } return FALSE; } @@ -287,210 +290,211 @@ BOOL MoveCursorTopLeft(void) //----------------------------------------------------------------------------- void MoveCursorKeyboard(int keyCode) { -// if(!Selected || Selected->selectedState == SELECTED_NONE) { -// MoveCursorTopLeft(); -// return; -// } - -// switch(keyCode) { -// case VK_LEFT: { -// if(!Selected || Selected->selectedState == SELECTED_NONE) { -// break; -// } -// if(Selected->selectedState != SELECTED_LEFT) { -// SelectElement(-1, -1, SELECTED_LEFT); -// break; -// } -// if(SelectedWhich == ELEM_COMMENT) break; -// int i, j; -// if(FindSelected(&i, &j)) { -// i--; -// while(i >= 0 && (!VALID_LEAF(DisplayMatrix[i][j]) || -// (DisplayMatrix[i][j] == Selected))) -// { -// i--; -// } -// if(i >= 0) { -// SelectElement(i, j, SELECTED_RIGHT); -// } -// } -// break; -// } -// case VK_RIGHT: { -// if(!Selected || Selected->selectedState == SELECTED_NONE) { -// break; -// } -// if(Selected->selectedState != SELECTED_RIGHT) { -// SelectElement(-1, -1, SELECTED_RIGHT); -// break; -// } -// if(SelectedWhich == ELEM_COMMENT) break; -// int i, j; -// if(FindSelected(&i, &j)) { -// i++; -// while(i < DISPLAY_MATRIX_X_SIZE && -// !VALID_LEAF(DisplayMatrix[i][j])) -// { -// i++; -// } -// if(i != DISPLAY_MATRIX_X_SIZE) { -// SelectElement(i, j, SELECTED_LEFT); -// } -// } -// break; -// } -// case VK_UP: { -// if(!Selected || Selected->selectedState == SELECTED_NONE) { -// break; -// } -// if(Selected->selectedState != SELECTED_ABOVE && -// SelectedWhich != ELEM_PLACEHOLDER) -// { -// SelectElement(-1, -1, SELECTED_ABOVE); -// break; -// } -// int i, j; -// if(FindSelected(&i, &j)) { -// j--; -// while(j >= 0 && !VALID_LEAF(DisplayMatrix[i][j])) -// j--; -// if(j >= 0) { -// SelectElement(i, j, SELECTED_BELOW); -// } -// } -// break; -// } -// case VK_DOWN: { -// if(!Selected || Selected->selectedState == SELECTED_NONE) { -// break; -// } -// if(Selected->selectedState != SELECTED_BELOW && -// SelectedWhich != ELEM_PLACEHOLDER) -// { -// SelectElement(-1, -1, SELECTED_BELOW); -// break; -// } -// int i, j; -// if(FindSelected(&i, &j)) { -// j++; -// while(j < DISPLAY_MATRIX_Y_SIZE && -// !VALID_LEAF(DisplayMatrix[i][j])) -// { -// j++; -// } -// if(j != DISPLAY_MATRIX_Y_SIZE) { -// SelectElement(i, j, SELECTED_ABOVE); -// } else if(ScrollYOffsetMax - ScrollYOffset < 3) { -// // special case: scroll the end marker into view -// ScrollYOffset = ScrollYOffsetMax; -// RefreshScrollbars(); -// } -// } -// break; -// } -// } + if(!Selected || Selected->selectedState == SELECTED_NONE) { + MoveCursorTopLeft(); + return; + } + + switch(keyCode) { + case VK_LEFT: { + if(!Selected || Selected->selectedState == SELECTED_NONE) { + break; + } + if(Selected->selectedState != SELECTED_LEFT) { + SelectElement(-1, -1, SELECTED_LEFT); + break; + } + if(SelectedWhich == ELEM_COMMENT) break; + int i, j; + if(FindSelected(&i, &j)) { + i--; + while(i >= 0 && (!VALID_LEAF(DisplayMatrix[i][j]) || + (DisplayMatrix[i][j] == Selected))) + { + i--; + } + if(i >= 0) { + SelectElement(i, j, SELECTED_RIGHT); + } + } + break; + } + case VK_RIGHT: { + if(!Selected || Selected->selectedState == SELECTED_NONE) { + break; + } + if(Selected->selectedState != SELECTED_RIGHT) { + SelectElement(-1, -1, SELECTED_RIGHT); + break; + } + if(SelectedWhich == ELEM_COMMENT) break; + int i, j; + if(FindSelected(&i, &j)) { + i++; + while(i < DISPLAY_MATRIX_X_SIZE && + !VALID_LEAF(DisplayMatrix[i][j])) + { + i++; + } + if(i != DISPLAY_MATRIX_X_SIZE) { + SelectElement(i, j, SELECTED_LEFT); + } + } + break; + } + case VK_UP: { + if(!Selected || Selected->selectedState == SELECTED_NONE) { + break; + } + if(Selected->selectedState != SELECTED_ABOVE && + SelectedWhich != ELEM_PLACEHOLDER) + { + SelectElement(-1, -1, SELECTED_ABOVE); + break; + } + int i, j; + if(FindSelected(&i, &j)) { + j--; + while(j >= 0 && !VALID_LEAF(DisplayMatrix[i][j])) + j--; + if(j >= 0) { + SelectElement(i, j, SELECTED_BELOW); + } + } + break; + } + case VK_DOWN: { + if(!Selected || Selected->selectedState == SELECTED_NONE) { + break; + } + if(Selected->selectedState != SELECTED_BELOW && + SelectedWhich != ELEM_PLACEHOLDER) + { + SelectElement(-1, -1, SELECTED_BELOW); + break; + } + int i, j; + if(FindSelected(&i, &j)) { + j++; + while(j < DISPLAY_MATRIX_Y_SIZE && + !VALID_LEAF(DisplayMatrix[i][j])) + { + j++; + } + if(j != DISPLAY_MATRIX_Y_SIZE) { + SelectElement(i, j, SELECTED_ABOVE); + } else if(ScrollYOffsetMax - ScrollYOffset < 3) { + // special case: scroll the end marker into view + ScrollYOffset = ScrollYOffsetMax; + RefreshScrollbars(); + } + } + break; + } + } } //----------------------------------------------------------------------------- // Edit the selected element. Pop up the appropriate modal dialog box to do // this. //----------------------------------------------------------------------------- + void EditSelectedElement(void) { -// if(!Selected || Selected->selectedState == SELECTED_NONE) return; - -// switch(SelectedWhich) { -// case ELEM_COMMENT: -// ShowCommentDialog(Selected->d.comment.str); -// break; - -// case ELEM_CONTACTS: -// ShowContactsDialog(&(Selected->d.contacts.negated), -// Selected->d.contacts.name); -// break; - -// case ELEM_COIL: -// ShowCoilDialog(&(Selected->d.coil.negated), -// &(Selected->d.coil.setOnly), &(Selected->d.coil.resetOnly), -// Selected->d.coil.name); -// break; - -// case ELEM_TON: -// case ELEM_TOF: -// case ELEM_RTO: -// ShowTimerDialog(SelectedWhich, &(Selected->d.timer.delay), -// Selected->d.timer.name); -// break; - -// case ELEM_CTU: -// case ELEM_CTD: -// case ELEM_CTC: -// ShowCounterDialog(SelectedWhich, &(Selected->d.counter.max), -// Selected->d.counter.name); -// break; - -// case ELEM_EQU: -// case ELEM_NEQ: -// case ELEM_GRT: -// case ELEM_GEQ: -// case ELEM_LES: -// case ELEM_LEQ: -// ShowCmpDialog(SelectedWhich, Selected->d.cmp.op1, -// Selected->d.cmp.op2); -// break; - -// case ELEM_ADD: -// case ELEM_SUB: -// case ELEM_MUL: -// case ELEM_DIV: -// ShowMathDialog(SelectedWhich, Selected->d.math.dest, -// Selected->d.math.op1, Selected->d.math.op2); -// break; - -// case ELEM_RES: -// ShowResetDialog(Selected->d.reset.name); -// break; - -// case ELEM_MOVE: -// ShowMoveDialog(Selected->d.move.dest, Selected->d.move.src); -// break; - -// case ELEM_SET_PWM: -// ShowSetPwmDialog(Selected->d.setPwm.name, -// &(Selected->d.setPwm.targetFreq)); -// break; - -// case ELEM_READ_ADC: -// ShowReadAdcDialog(Selected->d.readAdc.name+1); -// break; - -// case ELEM_UART_RECV: -// case ELEM_UART_SEND: -// ShowUartDialog(SelectedWhich, Selected->d.uart.name); -// break; - -// case ELEM_PERSIST: -// ShowPersistDialog(Selected->d.persist.var); -// break; - -// case ELEM_SHIFT_REGISTER: -// ShowShiftRegisterDialog(Selected->d.shiftRegister.name, -// &(Selected->d.shiftRegister.stages)); -// break; - -// case ELEM_FORMATTED_STRING: -// ShowFormattedStringDialog(Selected->d.fmtdStr.var, -// Selected->d.fmtdStr.string); -// break; - -// case ELEM_PIECEWISE_LINEAR: -// ShowPiecewiseLinearDialog(Selected); -// break; - -// case ELEM_LOOK_UP_TABLE: -// ShowLookUpTableDialog(Selected); -// break; -// } + if(!Selected || Selected->selectedState == SELECTED_NONE) return; + + switch(SelectedWhich) { + case ELEM_COMMENT: + ShowCommentDialog(Selected->d.comment.str); + break; + + case ELEM_CONTACTS: + ShowContactsDialog(&(Selected->d.contacts.negated), + Selected->d.contacts.name); + break; + + case ELEM_COIL: + ShowCoilDialog(&(Selected->d.coil.negated), + &(Selected->d.coil.setOnly), &(Selected->d.coil.resetOnly), + Selected->d.coil.name); + break; + + case ELEM_TON: + case ELEM_TOF: + case ELEM_RTO: + ShowTimerDialog(SelectedWhich, &(Selected->d.timer.delay), + Selected->d.timer.name); + break; + + case ELEM_CTU: + case ELEM_CTD: + case ELEM_CTC: + ShowCounterDialog(SelectedWhich, &(Selected->d.counter.max), + Selected->d.counter.name); + break; + + case ELEM_EQU: + case ELEM_NEQ: + case ELEM_GRT: + case ELEM_GEQ: + case ELEM_LES: + case ELEM_LEQ: + ShowCmpDialog(SelectedWhich, Selected->d.cmp.op1, + Selected->d.cmp.op2); + break; + + case ELEM_ADD: + case ELEM_SUB: + case ELEM_MUL: + case ELEM_DIV: + ShowMathDialog(SelectedWhich, Selected->d.math.dest, + Selected->d.math.op1, Selected->d.math.op2); + break; + + case ELEM_RES: + ShowResetDialog(Selected->d.reset.name); + break; + + case ELEM_MOVE: + ShowMoveDialog(Selected->d.move.dest, Selected->d.move.src); + break; + + case ELEM_SET_PWM: + ShowSetPwmDialog(Selected->d.setPwm.name, + &(Selected->d.setPwm.targetFreq)); + break; + + case ELEM_READ_ADC: + ShowReadAdcDialog(Selected->d.readAdc.name+1); + break; + + case ELEM_UART_RECV: + case ELEM_UART_SEND: + ShowUartDialog(SelectedWhich, Selected->d.uart.name); + break; + + case ELEM_PERSIST: + ShowPersistDialog(Selected->d.persist.var); + break; + + case ELEM_SHIFT_REGISTER: + ShowShiftRegisterDialog(Selected->d.shiftRegister.name, + &(Selected->d.shiftRegister.stages)); + break; + + case ELEM_FORMATTED_STRING: + ShowFormattedStringDialog(Selected->d.fmtdStr.var, + Selected->d.fmtdStr.string); + break; + + case ELEM_PIECEWISE_LINEAR: + ShowPiecewiseLinearDialog(Selected); + break; + + case ELEM_LOOK_UP_TABLE: + ShowLookUpTableDialog(Selected); + break; + } } //----------------------------------------------------------------------------- @@ -502,30 +506,30 @@ void EditSelectedElement(void) //----------------------------------------------------------------------------- void EditElementMouseDoubleclick(int x, int y) { -// x += ScrollXOffset; - -// y += FONT_HEIGHT/2; - -// int gx = (x - X_PADDING)/(POS_WIDTH*FONT_WIDTH); -// int gy = (y - Y_PADDING)/(POS_HEIGHT*FONT_HEIGHT); - -// gy += ScrollYOffset; - -// if(InSimulationMode) { -// ElemLeaf *l = DisplayMatrix[gx][gy]; -// if(l && DisplayMatrixWhich[gx][gy] == ELEM_CONTACTS) { -// char *name = l->d.contacts.name; -// if(name[0] == 'X') { -// SimulationToggleContact(name); -// } -// } else if(l && DisplayMatrixWhich[gx][gy] == ELEM_READ_ADC) { -// ShowAnalogSliderPopup(l->d.readAdc.name); -// } -// } else { -// if(DisplayMatrix[gx][gy] == Selected) { -// EditSelectedElement(); -// } -// } + x += ScrollXOffset; + + y += FONT_HEIGHT/2; + + int gx = (x - X_PADDING)/(POS_WIDTH*FONT_WIDTH); + int gy = (y - Y_PADDING)/(POS_HEIGHT*FONT_HEIGHT); + + gy += ScrollYOffset; + + if(InSimulationMode) { + ElemLeaf *l = DisplayMatrix[gx][gy]; + if(l && DisplayMatrixWhich[gx][gy] == ELEM_CONTACTS) { + char *name = l->d.contacts.name; + if(name[0] == 'X') { + SimulationToggleContact(name); + } + } else if(l && DisplayMatrixWhich[gx][gy] == ELEM_READ_ADC) { + ShowAnalogSliderPopup(l->d.readAdc.name); + } + } else { + if(DisplayMatrix[gx][gy] == Selected) { + EditSelectedElement(); + } + } } //----------------------------------------------------------------------------- @@ -536,71 +540,71 @@ void EditElementMouseDoubleclick(int x, int y) //----------------------------------------------------------------------------- void MoveCursorMouseClick(int x, int y) { -// x += ScrollXOffset; - -// y += FONT_HEIGHT/2; - -// int gx0 = (x - X_PADDING)/(POS_WIDTH*FONT_WIDTH); -// int gy0 = (y - Y_PADDING)/(POS_HEIGHT*FONT_HEIGHT); - -// int gx = gx0; -// int gy = gy0 + ScrollYOffset; - -// if(VALID_LEAF(DisplayMatrix[gx][gy])) { -// int i, j; -// for(i = 0; i < DISPLAY_MATRIX_X_SIZE; i++) { -// for(j = 0; j < DISPLAY_MATRIX_Y_SIZE; j++) { -// if(DisplayMatrix[i][j]) -// DisplayMatrix[i][j]->selectedState = SELECTED_NONE; -// } -// } -// int dx = x - (gx0*POS_WIDTH*FONT_WIDTH + X_PADDING); -// int dy = y - (gy0*POS_HEIGHT*FONT_HEIGHT + Y_PADDING); - -// int dtop = dy; -// int dbottom = POS_HEIGHT*FONT_HEIGHT - dy; -// int dleft = dx; -// int dright = POS_WIDTH*FONT_WIDTH - dx; - -// int extra = 1; -// if(DisplayMatrixWhich[gx][gy] == ELEM_COMMENT) { -// dleft += gx*POS_WIDTH*FONT_WIDTH; -// dright += (ColsAvailable - gx - 1)*POS_WIDTH*FONT_WIDTH; -// extra = ColsAvailable; -// } else { -// if((gx > 0) && (DisplayMatrix[gx-1][gy] == DisplayMatrix[gx][gy])) { -// dleft += POS_WIDTH*FONT_WIDTH; -// extra = 2; -// } -// if((gx < (DISPLAY_MATRIX_X_SIZE-1)) && -// (DisplayMatrix[gx+1][gy] == DisplayMatrix[gx][gy])) -// { -// dright += POS_WIDTH*FONT_WIDTH; -// extra = 2; -// } -// } - -// int decideX = (dright - dleft); -// int decideY = (dtop - dbottom); - -// decideY = decideY*3*extra; - -// int state; -// if(abs(decideY) > abs(decideX)) { -// if(decideY > 0) { -// state = SELECTED_BELOW; -// } else { -// state = SELECTED_ABOVE; -// } -// } else { -// if(decideX > 0) { -// state = SELECTED_LEFT; -// } else { -// state = SELECTED_RIGHT; -// } -// } -// SelectElement(gx, gy, state); -// } + x += ScrollXOffset; + + y += FONT_HEIGHT/2; + + int gx0 = (x - X_PADDING)/(POS_WIDTH*FONT_WIDTH); + int gy0 = (y - Y_PADDING)/(POS_HEIGHT*FONT_HEIGHT); + + int gx = gx0; + int gy = gy0 + ScrollYOffset; + + if(VALID_LEAF(DisplayMatrix[gx][gy])) { + int i, j; + for(i = 0; i < DISPLAY_MATRIX_X_SIZE; i++) { + for(j = 0; j < DISPLAY_MATRIX_Y_SIZE; j++) { + if(DisplayMatrix[i][j]) + DisplayMatrix[i][j]->selectedState = SELECTED_NONE; + } + } + int dx = x - (gx0*POS_WIDTH*FONT_WIDTH + X_PADDING); + int dy = y - (gy0*POS_HEIGHT*FONT_HEIGHT + Y_PADDING); + + int dtop = dy; + int dbottom = POS_HEIGHT*FONT_HEIGHT - dy; + int dleft = dx; + int dright = POS_WIDTH*FONT_WIDTH - dx; + + int extra = 1; + if(DisplayMatrixWhich[gx][gy] == ELEM_COMMENT) { + dleft += gx*POS_WIDTH*FONT_WIDTH; + dright += (ColsAvailable - gx - 1)*POS_WIDTH*FONT_WIDTH; + extra = ColsAvailable; + } else { + if((gx > 0) && (DisplayMatrix[gx-1][gy] == DisplayMatrix[gx][gy])) { + dleft += POS_WIDTH*FONT_WIDTH; + extra = 2; + } + if((gx < (DISPLAY_MATRIX_X_SIZE-1)) && + (DisplayMatrix[gx+1][gy] == DisplayMatrix[gx][gy])) + { + dright += POS_WIDTH*FONT_WIDTH; + extra = 2; + } + } + + int decideX = (dright - dleft); + int decideY = (dtop - dbottom); + + decideY = decideY*3*extra; + + int state; + if(abs(decideY) > abs(decideX)) { + if(decideY > 0) { + state = SELECTED_BELOW; + } else { + state = SELECTED_ABOVE; + } + } else { + if(decideX > 0) { + state = SELECTED_LEFT; + } else { + state = SELECTED_RIGHT; + } + } + SelectElement(gx, gy, state); + } } //----------------------------------------------------------------------------- @@ -609,49 +613,49 @@ void MoveCursorMouseClick(int x, int y) //----------------------------------------------------------------------------- void MoveCursorNear(int gx, int gy) { -// int out = 0; - -// for(out = 0; out < 8; out++) { -// if(gx - out >= 0) { -// if(VALID_LEAF(DisplayMatrix[gx-out][gy])) { -// SelectElement(gx-out, gy, SELECTED_RIGHT); -// return; -// } -// } -// if(gx + out < DISPLAY_MATRIX_X_SIZE) { -// if(VALID_LEAF(DisplayMatrix[gx+out][gy])) { -// SelectElement(gx+out, gy, SELECTED_LEFT); -// return; -// } -// } -// if(gy - out >= 0) { -// if(VALID_LEAF(DisplayMatrix[gx][gy-out])) { -// SelectElement(gx, gy-out, SELECTED_BELOW); -// return; -// } -// } -// if(gy + out < DISPLAY_MATRIX_Y_SIZE) { -// if(VALID_LEAF(DisplayMatrix[gx][gy+out])) { -// SelectElement(gx, gy+out, SELECTED_ABOVE); -// return; -// } -// } - -// if(out == 1) { -// // Now see if we have a straight shot to the right; might be far -// // if we have to go up to a coil or other end of line element. -// int across; -// for(across = 1; gx+across < DISPLAY_MATRIX_X_SIZE; across++) { -// if(VALID_LEAF(DisplayMatrix[gx+across][gy])) { -// SelectElement(gx+across, gy, SELECTED_LEFT); -// return; -// } -// if(!DisplayMatrix[gx+across][gy]) break; -// } -// } -// } - -// MoveCursorTopLeft(); + int out = 0; + + for(out = 0; out < 8; out++) { + if(gx - out >= 0) { + if(VALID_LEAF(DisplayMatrix[gx-out][gy])) { + SelectElement(gx-out, gy, SELECTED_RIGHT); + return; + } + } + if(gx + out < DISPLAY_MATRIX_X_SIZE) { + if(VALID_LEAF(DisplayMatrix[gx+out][gy])) { + SelectElement(gx+out, gy, SELECTED_LEFT); + return; + } + } + if(gy - out >= 0) { + if(VALID_LEAF(DisplayMatrix[gx][gy-out])) { + SelectElement(gx, gy-out, SELECTED_BELOW); + return; + } + } + if(gy + out < DISPLAY_MATRIX_Y_SIZE) { + if(VALID_LEAF(DisplayMatrix[gx][gy+out])) { + SelectElement(gx, gy+out, SELECTED_ABOVE); + return; + } + } + + if(out == 1) { + // Now see if we have a straight shot to the right; might be far + // if we have to go up to a coil or other end of line element. + int across; + for(across = 1; gx+across < DISPLAY_MATRIX_X_SIZE; across++) { + if(VALID_LEAF(DisplayMatrix[gx+across][gy])) { + SelectElement(gx+across, gy, SELECTED_LEFT); + return; + } + if(!DisplayMatrix[gx+across][gy]) break; + } + } + } + + MoveCursorTopLeft(); } //----------------------------------------------------------------------------- diff --git a/ldmicro/simpledialog.cpp b/ldmicro/simpledialog.cpp index 14aab25..0d63a22 100644 --- a/ldmicro/simpledialog.cpp +++ b/ldmicro/simpledialog.cpp @@ -29,394 +29,670 @@ #include "ldmicro.h" -static HWND SimpleDialog; +static HWID SimpleDialog; +static HWID OkButton; +static HWID CancelButton; #define MAX_BOXES 5 -static HWND Textboxes[MAX_BOXES]; -static HWND Labels[MAX_BOXES]; +static HWID Textboxes[MAX_BOXES]; +static HWID Labels[MAX_BOXES]; static LONG_PTR PrevAlnumOnlyProc[MAX_BOXES]; static LONG_PTR PrevNumOnlyProc[MAX_BOXES]; static BOOL NoCheckingOnBox[MAX_BOXES]; +static BOOL SIMPLE_DIALOG_ACTIVE = FALSE; + +static SimpleDialogData SDdata; + +/// Simple dialog data flags +#define SD_TIMER 0x0000001 +#define SD_COUNTER 0x0000002 +#define SD_CMP 0x0000003 +#define SD_MOVE 0x0000004 +#define SD_READ_ADC 0x0000005 +#define SD_SET_PWM 0x0000006 +#define SD_UART 0x0000007 +#define SD_MATH 0x0000008 +#define SD_SHIFT_REGISTER 0x0000009 +#define SD_FORMATTED_STRING 0x0000010 +#define SD_PERSIST 0x0000011 + //----------------------------------------------------------------------------- // Don't allow any characters other than -A-Za-z0-9_ in the box. //----------------------------------------------------------------------------- -// static LRESULT CALLBACK MyAlnumOnlyProc(HWND hwnd, UINT msg, WPARAM wParam, -// LPARAM lParam) -// { -// if(msg == WM_CHAR) { -// if(!(isalpha(wParam) || isdigit(wParam) || wParam == '_' || -// wParam == '\b' || wParam == '-' || wParam == '\'')) -// { -// return 0; -// } -// } - -// int i; -// for(i = 0; i < MAX_BOXES; i++) { -// if(hwnd == Textboxes[i]) { -// return CallWindowProc((WNDPROC)PrevAlnumOnlyProc[i], hwnd, msg, -// wParam, lParam); -// } -// } -// oops(); -// } +static void MyAlnumOnlyProc (GtkEditable *editable, gchar *NewText, gint length, + gint *position, gpointer data) +{ + for (int i = 0; i < length; i++) + { + if (!(isalpha (NewText[i]) || NewText[i] == '_' || isdigit (NewText[i]) || + NewText[i] == '\b' || NewText[i] == '\'' || NewText[i] == '-')) + { + g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text"); + return; + } + } + // if(msg == WM_CHAR) { + // if(!(isalpha(wParam) || isdigit(wParam) || wParam == '_' || + // wParam == '\b' || wParam == '-' || wParam == '\'')) + // { + // return 0; + // } + // } + + // int i; + // for(i = 0; i < MAX_BOXES; i++) { + // if(hwnd == Textboxes[i]) { + // return CallWindowProc((WNDPROC)PrevAlnumOnlyProc[i], hwnd, msg, + // wParam, lParam); + // } + // } + // oops(); +} //----------------------------------------------------------------------------- // Don't allow any characters other than -0-9. in the box. //----------------------------------------------------------------------------- -// static LRESULT CALLBACK MyNumOnlyProc(HWND hwnd, UINT msg, WPARAM wParam, -// LPARAM lParam) -// { -// if(msg == WM_CHAR) { -// if(!(isdigit(wParam) || wParam == '.' || wParam == '\b' -// || wParam == '-')) -// { -// return 0; -// } -// } - -// int i; -// for(i = 0; i < MAX_BOXES; i++) { -// if(hwnd == Textboxes[i]) { -// return CallWindowProc((WNDPROC)PrevNumOnlyProc[i], hwnd, msg, -// wParam, lParam); -// } -// } -// oops(); -// } - -// static void MakeControls(int boxes, char **labels, DWORD fixedFontMask) -// { -// int i; -// HDC hdc = GetDC(SimpleDialog); -// SelectObject(hdc, MyNiceFont); - -// SIZE si; - -// int maxLen = 0; -// for(i = 0; i < boxes; i++) { -// GetTextExtentPoint32(hdc, labels[i], strlen(labels[i]), &si); -// if(si.cx > maxLen) maxLen = si.cx; -// } - -// int adj; -// if(maxLen > 70) { -// adj = maxLen - 70; -// } else { -// adj = 0; -// } - -// for(i = 0; i < boxes; i++) { -// GetTextExtentPoint32(hdc, labels[i], strlen(labels[i]), &si); - -// Labels[i] = CreateWindowEx(0, WC_STATIC, labels[i], -// WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, -// (80 + adj) - si.cx - 4, 13 + i*30, si.cx, 21, -// SimpleDialog, NULL, Instance, NULL); -// NiceFont(Labels[i]); - -// Textboxes[i] = CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, "", -// WS_CHILD | ES_AUTOHSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS | -// WS_VISIBLE, -// 80 + adj, 12 + 30*i, 120 - adj, 21, -// SimpleDialog, NULL, Instance, NULL); - -// if(fixedFontMask & (1 << i)) { -// FixedFont(Textboxes[i]); -// } else { -// NiceFont(Textboxes[i]); -// } -// } -// ReleaseDC(SimpleDialog, hdc); - -// OkButton = CreateWindowEx(0, WC_BUTTON, _("OK"), -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | BS_DEFPUSHBUTTON, -// 218, 11, 70, 23, SimpleDialog, NULL, Instance, NULL); -// NiceFont(OkButton); - -// CancelButton = CreateWindowEx(0, WC_BUTTON, _("Cancel"), -// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, -// 218, 41, 70, 23, SimpleDialog, NULL, Instance, NULL); -// NiceFont(CancelButton); -// } - -// BOOL ShowSimpleDialog(char *title, int boxes, char **labels, DWORD numOnlyMask, -// DWORD alnumOnlyMask, DWORD fixedFontMask, char **dests) -// { -// BOOL didCancel; - -// if(boxes > MAX_BOXES) oops(); - -// SimpleDialog = CreateWindowClient(0, "LDmicroDialog", title, -// WS_OVERLAPPED | WS_SYSMENU, -// 100, 100, 304, 15 + 30*(boxes < 2 ? 2 : boxes), NULL, NULL, -// Instance, NULL); - -// MakeControls(boxes, labels, fixedFontMask); +static void MyNumOnlyProc (GtkEditable *editable, gchar *NewText, gint length, + gint *position, gpointer data) +{ + for (int i = 0; i < length; i++) + { + if (!(isdigit (NewText[i]) || NewText[i] == '\b' || + NewText[i] == '.' || NewText[i] == '-')) + { + g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text"); + return; + } + } + // if(msg == WM_CHAR) { + // if(!(isdigit(wParam) || wParam == '.' || wParam == '\b' + // || wParam == '-')) + // { + // return 0; + // } + // } + + // int i; + // for(i = 0; i < MAX_BOXES; i++) { + // if(hwnd == Textboxes[i]) { + // return CallWindowProc((WNDPROC)PrevNumOnlyProc[i], hwnd, msg, + // wParam, lParam); + // } + // } + // oops(); +} + +static void MakeControls(int boxes, char **labels, DWORD fixedFontMask) +{ + int i; + // HDC hdc = GetDC(SimpleDialog); + // SelectObject(hdc, MyNiceFont); + + // SIZE si; + + // int maxLen = 0; + // for(i = 0; i < boxes; i++) { + // GetTextExtentPoint32(hdc, labels[i], strlen(labels[i]), &si); + // if(si.cx > maxLen) maxLen = si.cx; + // } + + // int adj; + // if(maxLen > 70) { + // adj = maxLen - 70; + // } else { + // adj = 0; + // } + HWID grid = gtk_grid_new(); + + for(i = 0; i < boxes; i++) { + // GetTextExtentPoint32(hdc, labels[i], strlen(labels[i]), &si); + + Labels[i] = gtk_label_new (labels[i]); + // CreateWindowEx(0, WC_STATIC, labels[i], + // WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, + // (80 + adj) - si.cx - 4, 13 + i*30, si.cx, 21, + // SimpleDialog, NULL, Instance, NULL); + NiceFont(Labels[i]); + gtk_grid_attach (GTK_GRID (grid), Labels[i], 0, i, 1, 1); + + Textboxes[i] = gtk_entry_new (); + // CreateWindowEx(WS_EX_CLIENTEDGE, WC_EDIT, "", + // WS_CHILD | ES_AUTOHSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS | + // WS_VISIBLE, + // 80 + adj, 12 + 30*i, 120 - adj, 21, + // SimpleDialog, NULL, Instance, NULL); + + if(fixedFontMask & (1 << i)) { + FixedFont(Textboxes[i]); + } else { + NiceFont(Textboxes[i]); + } + gtk_grid_attach (GTK_GRID (grid), Textboxes[i], 1, i, 1, 1); + } + // ReleaseDC(SimpleDialog, hdc); + + OkButton = gtk_button_new_with_label (_("OK")); + // CreateWindowEx(0, WC_BUTTON, _("OK"), + // WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | BS_DEFPUSHBUTTON, + // 218, 11, 70, 23, SimpleDialog, NULL, Instance, NULL); + NiceFont(OkButton); + gtk_grid_attach (GTK_GRID (grid), OkButton, 2, 0, 1, 1); + + CancelButton = gtk_button_new_with_label(_("Cancel")); + // CreateWindowEx(0, WC_BUTTON, _("Cancel"), + // WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, + // 218, 41, 70, 23, SimpleDialog, NULL, Instance, NULL); + NiceFont(CancelButton); + gtk_grid_attach (GTK_GRID (grid), CancelButton, 2, 1, 1, 1); + gtk_container_add(GTK_CONTAINER(SimpleDialog), grid); +} + +void SimpleDialogWrapUp() +{ + // if(!didCancel) + for(int i = 0; i < SDdata.boxes; i++) { + if(NoCheckingOnBox[i]) { + // char get[64]; + // SendMessage(Textboxes[i], WM_GETTEXT, 60, (LPARAM)get); + char *get = (char*)gtk_entry_get_text (GTK_ENTRY(Textboxes[i])); + strcpy(SDdata.dests[i], get); + if (strlen(get) < 60) + strcpy(SDdata.dests[i], get); + else + { + strncpy(SDdata.dests[i], get, 60); + SDdata.dests[i][60] = '\0'; + } + } else { + char get[20]; + // SendMessage(Textboxes[i], WM_GETTEXT, 15, (LPARAM)get); + char *str = (char*)gtk_entry_get_text (GTK_ENTRY(Textboxes[i])); + strcpy(get, str); + if (strlen(str) < 15) + strcpy(get, str); + else + { + strncpy(get, str, 15); + get[15] = '\0'; + } + + if( (!strchr(get, '\'')) || + (get[0] == '\'' && get[2] == '\'' && strlen(get)==3) ) + { + if(strlen(get) == 0) { + Error(_("Empty textbox; not permitted.")); + } else { + strcpy(SDdata.dests[i], get); + } + } else { + Error(_("Bad use of quotes: <%s>"), get); + } + } + } + + switch(SDdata.uflag) + { + case SD_TIMER: + { + SDdata.str1[0] = 'T'; + strcpy(SDdata.str1+1, SDdata.dests[0]); + g_print("%s, %s\n", SDdata.str1, SDdata.dests[0]); + double del = atof(SDdata.dests[1]); + if(del > 2140000) { // 2**31/1000, don't overflow signed int + Error(_("Delay too long; maximum is 2**31 us.")); + } else if(del <= 0) { + Error(_("Delay cannot be zero or negative.")); + } else { + *SDdata.num1 = (int)(1000*del + 0.5); + } + break; + } + case SD_COUNTER: + { + *SDdata.num1 = atoi(SDdata.dests[1]); + break; + } + case SD_CMP: + { + break; + } + case SD_MOVE: + { + break; + } + case SD_READ_ADC: + { + break; + } + case SD_SET_PWM: + { + *SDdata.num1 = atoi(SDdata.dests[1]); + break; + } + case SD_UART: + { + break; + } + case SD_MATH: + { + break; + } + case SD_SHIFT_REGISTER: + { + *SDdata.num1 = atoi(SDdata.dests[1]); + + if(*SDdata.num1 <= 0 || *SDdata.num1 >= 200) + { + Error(_("Not a reasonable size for a shift register.")); + *SDdata.num1 = 1; + } + break; + } + case SD_FORMATTED_STRING: + { + break; + } + case SD_PERSIST: + { + break; + } + } + + DestroyWindow(SimpleDialog); + SIMPLE_DIALOG_ACTIVE = FALSE; +} + +void SimpleDialogCancelProc() +{ + DestroyWindow(SimpleDialog); + SIMPLE_DIALOG_ACTIVE = FALSE; +} + +static gboolean SimpleDialogKeyPressProc(HWID widget, GdkEventKey* event, gpointer data) +{ + if(event -> keyval == GDK_KEY_Return) + { + // DialogDone = TRUE; + SimpleDialogWrapUp(); + } else if(event -> keyval == GDK_KEY_Escape) + { + // DialogDone = TRUE; + // DialogCancel = TRUE; + SimpleDialogCancelProc(); + } + + return FALSE; +} + +void ShowSimpleDialog(char *title, int boxes, char **labels, DWORD numOnlyMask, + DWORD alnumOnlyMask, DWORD fixedFontMask, char **dests) +{ + if(SIMPLE_DIALOG_ACTIVE) + return; + + SIMPLE_DIALOG_ACTIVE = TRUE; + + BOOL didCancel = FALSE; + + if(boxes > MAX_BOXES) oops(); + + SimpleDialog = CreateWindowClient(GTK_WINDOW_TOPLEVEL, GDK_WINDOW_TYPE_HINT_NORMAL, + title, 100, 100, 304, 15 + 30*(boxes < 2 ? 2 : boxes), GTK_WINDOW(MainWindow) ); + // CreateWindowClient(0, "LDmicroDialog", title, + // WS_OVERLAPPED | WS_SYSMENU, + // 100, 100, 304, 15 + 30*(boxes < 2 ? 2 : boxes), NULL, NULL, + // Instance, NULL); + + MakeControls(boxes, labels, fixedFontMask); -// int i; -// for(i = 0; i < boxes; i++) { -// SendMessage(Textboxes[i], WM_SETTEXT, 0, (LPARAM)dests[i]); - -// if(numOnlyMask & (1 << i)) { -// PrevNumOnlyProc[i] = SetWindowLongPtr(Textboxes[i], GWLP_WNDPROC, -// (LONG_PTR)MyNumOnlyProc); -// } -// if(alnumOnlyMask & (1 << i)) { -// PrevAlnumOnlyProc[i] = SetWindowLongPtr(Textboxes[i], GWLP_WNDPROC, -// (LONG_PTR)MyAlnumOnlyProc); -// } -// } - -// EnableWindow(MainWindow, FALSE); -// ShowWindow(SimpleDialog, TRUE); -// SetFocus(Textboxes[0]); -// SendMessage(Textboxes[0], 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(SimpleDialog, &msg)) continue; -// TranslateMessage(&msg); -// DispatchMessage(&msg); -// } - -// didCancel = DialogCancel; - -// if(!didCancel) { -// for(i = 0; i < boxes; i++) { -// if(NoCheckingOnBox[i]) { -// char get[64]; -// SendMessage(Textboxes[i], WM_GETTEXT, 60, (LPARAM)get); -// strcpy(dests[i], get); -// } else { -// char get[20]; -// SendMessage(Textboxes[i], WM_GETTEXT, 15, (LPARAM)get); - -// if( (!strchr(get, '\'')) || -// (get[0] == '\'' && get[2] == '\'' && strlen(get)==3) ) -// { -// if(strlen(get) == 0) { -// Error(_("Empty textbox; not permitted.")); -// } else { -// strcpy(dests[i], get); -// } -// } else { -// Error(_("Bad use of quotes: <%s>"), get); -// } -// } -// } -// } - -// EnableWindow(MainWindow, TRUE); -// DestroyWindow(SimpleDialog); - -// return !didCancel; -// } - -// void ShowTimerDialog(int which, int *delay, char *name) -// { -// char *s; -// switch(which) { -// case ELEM_TON: s = _("Turn-On Delay"); break; -// case ELEM_TOF: s = _("Turn-Off Delay"); break; -// case ELEM_RTO: s = _("Retentive Turn-On Delay"); break; -// default: oops(); break; -// } + int i; + for(i = 0; i < boxes; i++) + { + // SendMessage(Textboxes[i], WM_SETTEXT, 0, (LPARAM)dests[i]); + gtk_entry_set_text (GTK_ENTRY(Textboxes[i]), dests[i]); + + if(numOnlyMask & (1 << i)) + { + g_signal_connect (G_OBJECT(Textboxes[i]), "insert-text", + G_CALLBACK(MyNumOnlyProc), NULL); + // PrevNumOnlyProc[i] = SetWindowLongPtr(Textboxes[i], GWLP_WNDPROC, + // (LONG_PTR)MyNumOnlyProc); + } else if(alnumOnlyMask & (1 << i)) + { + g_signal_connect (G_OBJECT(Textboxes[i]), "insert-text", + G_CALLBACK(MyAlnumOnlyProc), NULL); + // PrevAlnumOnlyProc[i] = SetWindowLongPtr(Textboxes[i], GWLP_WNDPROC, + // (LONG_PTR)MyAlnumOnlyProc); + } + } + + g_signal_connect (CancelButton, "clicked", G_CALLBACK (SimpleDialogCancelProc), NULL); + g_signal_connect (OkButton, "clicked", G_CALLBACK (SimpleDialogWrapUp), NULL); + g_signal_connect (SimpleDialog, "key_press_event", G_CALLBACK (SimpleDialogKeyPressProc), NULL); + + // EnableWindow(MainWindow, FALSE); + // ShowWindow(SimpleDialog, TRUE); + gtk_widget_show_all(SimpleDialog); + // SetFocus(Textboxes[0]); + // SendMessage(Textboxes[0], 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(SimpleDialog, &msg)) continue; + // TranslateMessage(&msg); + // DispatchMessage(&msg); + // } + + // didCancel = DialogCancel; + + + + // EnableWindow(MainWindow, TRUE); + // DestroyWindow(SimpleDialog); + + // return !didCancel; +} + +void ShowTimerDialog(int which, int *delay, char *name) +{ + char *s; + switch(which) { + case ELEM_TON: s = _("Turn-On Delay"); break; + case ELEM_TOF: s = _("Turn-Off Delay"); break; + case ELEM_RTO: s = _("Retentive Turn-On Delay"); break; + default: oops(); break; + } -// char *labels[] = { _("Name:"), _("Delay (ms):") }; - -// char delBuf[16]; -// char nameBuf[16]; -// sprintf(delBuf, "%.3f", (*delay / 1000.0)); -// strcpy(nameBuf, name+1); -// char *dests[] = { nameBuf, delBuf }; - -// if(ShowSimpleDialog(s, 2, labels, (1 << 1), (1 << 0), (1 << 0), dests)) { -// name[0] = 'T'; -// strcpy(name+1, nameBuf); -// double del = atof(delBuf); -// if(del > 2140000) { // 2**31/1000, don't overflow signed int -// Error(_("Delay too long; maximum is 2**31 us.")); -// } else if(del <= 0) { -// Error(_("Delay cannot be zero or negative.")); -// } else { -// *delay = (int)(1000*del + 0.5); -// } -// } -// } - -// void ShowCounterDialog(int which, int *maxV, char *name) -// { -// char *title; - -// switch(which) { -// case ELEM_CTU: title = _("Count Up"); break; -// case ELEM_CTD: title = _("Count Down"); break; -// case ELEM_CTC: title = _("Circular Counter"); break; - -// default: oops(); -// } - -// char *labels[] = { _("Name:"), (which == ELEM_CTC ? _("Max value:") : -// _("True if >= :")) }; -// char maxS[128]; -// sprintf(maxS, "%d", *maxV); -// char *dests[] = { name+1, maxS }; -// ShowSimpleDialog(title, 2, labels, 0x2, 0x1, 0x1, dests); -// *maxV = atoi(maxS); -// } - -// void ShowCmpDialog(int which, char *op1, char *op2) -// { -// char *title; -// char *l2; -// switch(which) { -// case ELEM_EQU: -// title = _("If Equals"); -// l2 = "= :"; -// break; - -// case ELEM_NEQ: -// title = _("If Not Equals"); -// l2 = "/= :"; -// break; - -// case ELEM_GRT: -// title = _("If Greater Than"); -// l2 = "> :"; -// break; - -// case ELEM_GEQ: -// title = _("If Greater Than or Equal To"); -// l2 = ">= :"; -// break; - -// case ELEM_LES: -// title = _("If Less Than"); -// l2 = "< :"; -// break; - -// case ELEM_LEQ: -// title = _("If Less Than or Equal To"); -// l2 = "<= :"; -// break; - -// default: -// oops(); -// } -// char *labels[] = { _("'Closed' if:"), l2 }; -// char *dests[] = { op1, op2 }; -// ShowSimpleDialog(title, 2, labels, 0, 0x3, 0x3, dests); -// } - -// void ShowMoveDialog(char *dest, char *src) -// { -// char *labels[] = { _("Destination:"), _("Source:") }; -// char *dests[] = { dest, src }; -// ShowSimpleDialog(_("Move"), 2, labels, 0, 0x3, 0x3, dests); -// } - -// void ShowReadAdcDialog(char *name) -// { -// char *labels[] = { _("Destination:") }; -// char *dests[] = { name }; -// ShowSimpleDialog(_("Read A/D Converter"), 1, labels, 0, 0x1, 0x1, dests); -// } - -// void ShowSetPwmDialog(char *name, int *targetFreq) -// { -// char freq[100]; -// sprintf(freq, "%d", *targetFreq); - -// char *labels[] = { _("Duty cycle var:"), _("Frequency (Hz):") }; -// char *dests[] = { name, freq }; -// ShowSimpleDialog(_("Set PWM Duty Cycle"), 2, labels, 0x2, 0x1, 0x1, dests); - -// *targetFreq = atoi(freq); -// } - -// void ShowUartDialog(int which, char *name) -// { -// char *labels[] = { (which == ELEM_UART_RECV) ? _("Destination:") : -// _("Source:") }; -// char *dests[] = { name }; - -// ShowSimpleDialog((which == ELEM_UART_RECV) ? _("Receive from UART") : -// _("Send to UART"), 1, labels, 0, 0x1, 0x1, dests); -// } - -// void ShowMathDialog(int which, char *dest, char *op1, char *op2) -// { -// char *l2, *title; -// if(which == ELEM_ADD) { -// l2 = "+ :"; -// title = _("Add"); -// } else if(which == ELEM_SUB) { -// l2 = "- :"; -// title = _("Subtract"); -// } else if(which == ELEM_MUL) { -// l2 = "* :"; -// title = _("Multiply"); -// } else if(which == ELEM_DIV) { -// l2 = "/ :"; -// title = _("Divide"); -// } else oops(); - -// char *labels[] = { _("Destination:"), _("is set := :"), l2 }; -// char *dests[] = { dest, op1, op2 }; -// ShowSimpleDialog(title, 3, labels, 0, 0x7, 0x7, dests); -// } - -// void ShowShiftRegisterDialog(char *name, int *stages) -// { -// char stagesStr[20]; -// sprintf(stagesStr, "%d", *stages); - -// char *labels[] = { _("Name:"), _("Stages:") }; -// char *dests[] = { name, stagesStr }; -// ShowSimpleDialog(_("Shift Register"), 2, labels, 0x2, 0x1, 0x1, dests); - -// *stages = atoi(stagesStr); - -// if(*stages <= 0 || *stages >= 200) { -// Error(_("Not a reasonable size for a shift register.")); -// *stages = 1; -// } -// } - -// void ShowFormattedStringDialog(char *var, char *string) -// { -// char *labels[] = { _("Variable:"), _("String:") }; -// char *dests[] = { var, string }; -// NoCheckingOnBox[0] = TRUE; -// NoCheckingOnBox[1] = TRUE; -// ShowSimpleDialog(_("Formatted String Over UART"), 2, labels, 0x0, -// 0x1, 0x3, dests); -// NoCheckingOnBox[0] = FALSE; -// NoCheckingOnBox[1] = FALSE; -// } - -// void ShowPersistDialog(char *var) -// { -// char *labels[] = { _("Variable:") }; -// char *dests[] = { var }; -// ShowSimpleDialog(_("Make Persistent"), 1, labels, 0, 1, 1, dests); -// } + char *labels[] = { _("Name:"), _("Delay (ms):") }; + + char delBuf[16]; + char nameBuf[16]; + sprintf(delBuf, "%.3f", (*delay / 1000.0)); + strcpy(nameBuf, name+1); + char *dests[] = { nameBuf, delBuf }; + + if (SIMPLE_DIALOG_ACTIVE) + return; + + SDdata.uflag = SD_TIMER; + SDdata.boxes = 2; + SDdata.str1 = name; + SDdata.num1 = delay; + SDdata.dests = new char*[2]; + SDdata.dests[0] = new char[16]; + SDdata.dests[1] = new char[16]; + sprintf(SDdata.dests[1], "%.3f", (*delay / 1000.0)); + strcpy(SDdata.dests[0], name+1); + + ShowSimpleDialog(s, 2, labels, (1 << 1), (1 << 0), (1 << 0), dests); +} + +void ShowCounterDialog(int which, int *maxV, char *name) +{ + char *title; + + switch(which) { + case ELEM_CTU: title = _("Count Up"); break; + case ELEM_CTD: title = _("Count Down"); break; + case ELEM_CTC: title = _("Circular Counter"); break; + + default: oops(); + } + + char *labels[] = { _("Name:"), (which == ELEM_CTC ? _("Max value:") : + _("True if >= :")) }; + char maxS[128]; + sprintf(maxS, "%d", *maxV); + char *dests[] = { name+1, maxS }; + + if (SIMPLE_DIALOG_ACTIVE) + return; + + SDdata.uflag = SD_COUNTER; + SDdata.boxes = 2; + SDdata.str1 = name; + SDdata.num1 = maxV; + SDdata.dests = new char*[2]; + SDdata.dests[0] = name+1; + SDdata.dests[1] = new char[128]; + sprintf(SDdata.dests[1], "%d", *maxV); + + ShowSimpleDialog(title, 2, labels, 0x2, 0x1, 0x1, dests); +} + +void ShowCmpDialog(int which, char *op1, char *op2) +{ + char *title; + char *l2; + switch(which) { + case ELEM_EQU: + title = _("If Equals"); + l2 = "= :"; + break; + + case ELEM_NEQ: + title = _("If Not Equals"); + l2 = "/= :"; + break; + + case ELEM_GRT: + title = _("If Greater Than"); + l2 = "> :"; + break; + + case ELEM_GEQ: + title = _("If Greater Than or Equal To"); + l2 = ">= :"; + break; + + case ELEM_LES: + title = _("If Less Than"); + l2 = "< :"; + break; + + case ELEM_LEQ: + title = _("If Less Than or Equal To"); + l2 = "<= :"; + break; + + default: + oops(); + } + char *labels[] = { _("'Closed' if:"), l2 }; + char *dests[] = { op1, op2 }; + + if (SIMPLE_DIALOG_ACTIVE) + return; + + SDdata.uflag = SD_CMP; + SDdata.boxes = 2; + SDdata.dests = new char*[2]; + SDdata.dests[0] = op1; + SDdata.dests[1] = op2; + + ShowSimpleDialog(title, 2, labels, 0, 0x3, 0x3, dests); +} + +void ShowMoveDialog(char *dest, char *src) +{ + char *labels[] = { _("Destination:"), _("Source:") }; + char *dests[] = { dest, src }; + + if (SIMPLE_DIALOG_ACTIVE) + return; + + SDdata.uflag = SD_MOVE; + SDdata.boxes = 2; + SDdata.dests = new char*[2]; + SDdata.dests[0] = dest; + SDdata.dests[1] = src; + + ShowSimpleDialog(_("Move"), 2, labels, 0, 0x3, 0x3, dests); +} + +void ShowReadAdcDialog(char *name) +{ + char *labels[] = { _("Destination:") }; + char *dests[] = { name }; + + if (SIMPLE_DIALOG_ACTIVE) + return; + + SDdata.uflag = SD_READ_ADC; + SDdata.boxes = 1; + SDdata.dests = new char*[1]; + SDdata.dests[0] = name; + + ShowSimpleDialog(_("Read A/D Converter"), 1, labels, 0, 0x1, 0x1, dests); +} + +void ShowSetPwmDialog(char *name, int *targetFreq) +{ + char freq[100]; + sprintf(freq, "%d", *targetFreq); + + char *labels[] = { _("Duty cycle var:"), _("Frequency (Hz):") }; + char *dests[] = { name, freq }; + + if (SIMPLE_DIALOG_ACTIVE) + return; + + SDdata.uflag = SD_SET_PWM; + SDdata.boxes = 2; + SDdata.num1 = targetFreq; + SDdata.dests = new char*[2]; + SDdata.dests[0] = name; + SDdata.dests[1] = new char[100]; + sprintf(SDdata.dests[1], "%d", *targetFreq); + + ShowSimpleDialog(_("Set PWM Duty Cycle"), 2, labels, 0x2, 0x1, 0x1, dests); +} + +void ShowUartDialog(int which, char *name) +{ + char *labels[] = { (which == ELEM_UART_RECV) ? _("Destination:") : + _("Source:") }; + char *dests[] = { name }; + + if (SIMPLE_DIALOG_ACTIVE) + return; + + SDdata.uflag = SD_UART; + SDdata.boxes = 1; + SDdata.dests = new char*[2]; + SDdata.dests[0] = name; + + ShowSimpleDialog((which == ELEM_UART_RECV) ? _("Receive from UART") : + _("Send to UART"), 1, labels, 0, 0x1, 0x1, dests); +} + +void ShowMathDialog(int which, char *dest, char *op1, char *op2) +{ + char *l2, *title; + if(which == ELEM_ADD) { + l2 = "+ :"; + title = _("Add"); + } else if(which == ELEM_SUB) { + l2 = "- :"; + title = _("Subtract"); + } else if(which == ELEM_MUL) { + l2 = "* :"; + title = _("Multiply"); + } else if(which == ELEM_DIV) { + l2 = "/ :"; + title = _("Divide"); + } else oops(); + + char *labels[] = { _("Destination:"), _("is set := :"), l2 }; + char *dests[] = { dest, op1, op2 }; + + if (SIMPLE_DIALOG_ACTIVE) + return; + + SDdata.uflag = SD_MATH; + SDdata.boxes = 3; + SDdata.dests = new char*[3]; + SDdata.dests[0] = dest; + SDdata.dests[1] = op1; + SDdata.dests[2] = op2; + + ShowSimpleDialog(title, 3, labels, 0, 0x7, 0x7, dests); +} + +void ShowShiftRegisterDialog(char *name, int *stages) +{ + char stagesStr[20]; + sprintf(stagesStr, "%d", *stages); + + char *labels[] = { _("Name:"), _("Stages:") }; + char *dests[] = { name, stagesStr }; + + if (SIMPLE_DIALOG_ACTIVE) + return; + + SDdata.uflag = SD_SHIFT_REGISTER; + SDdata.boxes = 2; + SDdata.num1 = stages; + SDdata.dests = new char*[2]; + SDdata.dests[0] = name; + SDdata.dests[1] = new char[20]; + sprintf(SDdata.dests[1], "%d", *stages); + + ShowSimpleDialog(_("Shift Register"), 2, labels, 0x2, 0x1, 0x1, dests); +} + +void ShowFormattedStringDialog(char *var, char *string) +{ + char *labels[] = { _("Variable:"), _("String:") }; + char *dests[] = { var, string }; + + if (SIMPLE_DIALOG_ACTIVE) + return; + + SDdata.uflag = SD_FORMATTED_STRING; + SDdata.boxes = 2; + SDdata.dests = new char*[2]; + SDdata.dests[0] = var; + SDdata.dests[1] = string; + + NoCheckingOnBox[0] = TRUE; + NoCheckingOnBox[1] = TRUE; + ShowSimpleDialog(_("Formatted String Over UART"), 2, labels, 0x0, + 0x1, 0x3, dests); + NoCheckingOnBox[0] = FALSE; + NoCheckingOnBox[1] = FALSE; +} + +void ShowPersistDialog(char *var) +{ + char *labels[] = { _("Variable:") }; + char *dests[] = { var }; + + if (SIMPLE_DIALOG_ACTIVE) + return; + + SDdata.uflag = SD_PERSIST; + SDdata.boxes = 1; + SDdata.dests = new char*[1]; + SDdata.dests[0] = var; + + ShowSimpleDialog(_("Make Persistent"), 1, labels, 0, 1, 1, dests); +} 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 69831d8..8bcfcc8 100644 --- a/ldmicro/undoredo.cpp +++ b/ldmicro/undoredo.cpp @@ -25,9 +25,12 @@ #include "linuxUI.h" #include <stdio.h> #include <stdlib.h> +#include <iostream> #include "ldmicro.h" +using namespace std; + // Store a `deep copy' of the entire program before every change, in a // circular buffer so that the first one scrolls out as soon as the buffer // is full and we try to push another one. @@ -198,9 +201,9 @@ void UndoUndo(void) } else { SetUndoEnabled(FALSE, TRUE); } - // RefreshControlsToSettings(); - // RefreshScrollbars(); - // InvalidateRect(MainWindow, NULL, FALSE); + RefreshControlsToSettings(); + RefreshScrollbars(); + InvalidateRect(MainWindow, NULL, FALSE); } //----------------------------------------------------------------------------- @@ -221,9 +224,9 @@ void UndoRedo(void) } else { SetUndoEnabled(TRUE, FALSE); } - //RefreshControlsToSettings(); - //RefreshScrollbars(); - //InvalidateRect(MainWindow, NULL, FALSE); + RefreshControlsToSettings(); + RefreshScrollbars(); + InvalidateRect(MainWindow, NULL, FALSE); } //----------------------------------------------------------------------------- |