From 870d2822e069f1f6a88b678d0cc1c33e1ba13bfe Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Tue, 25 Apr 2023 20:52:53 -0500 Subject: [PATCH] Code Editor starting to work. Integration with raw data is screwball for some reason. --- embedded/gitattributes | 16 +++ embedded/gitignore | 6 ++ embedded/missing.h | 38 +++++++ embedded/recipe.c | 16 +++ embedded/recipe.h | 17 +--- include/editor.h | 2 +- include/utils.h | 1 + src/editor.c | 208 ++++++++++++++++++++++++++++++++++++++- src/joeydev.c | 2 +- src/main.c | 6 +- src/project.c | 90 ++++++++++++----- src/utils.c | 69 ++++++------- src/vector.c | 48 ++++++--- ui/Cook.glade | 49 +++++---- ui/Editor.glade | 63 ++++++++---- ui/joeydev.gresource.xml | 6 +- 16 files changed, 498 insertions(+), 139 deletions(-) create mode 100644 embedded/gitattributes create mode 100644 embedded/gitignore create mode 100644 embedded/missing.h create mode 100644 embedded/recipe.c diff --git a/embedded/gitattributes b/embedded/gitattributes new file mode 100644 index 0000000..c1cb8ae --- /dev/null +++ b/embedded/gitattributes @@ -0,0 +1,16 @@ +# +# GitAttributes for JoeyDev Projects +# + +# JoeyLib Formats +*.img filter=lfs diff=lfs merge=lfs -text +*.stn filter=lfs diff=lfs merge=lfs -text +*.vec filter=lfs diff=lfs merge=lfs -text +*.snd filter=lfs diff=lfs merge=lfs -text + +# Native Formats +*.png filter=lfs diff=lfs merge=lfs -text +*.jpg filter=lfs diff=lfs merge=lfs -text +*.gif filter=lfs diff=lfs merge=lfs -text +*.mod filter=lfs diff=lfs merge=lfs -text +*.wav filter=lfs diff=lfs merge=lfs -text diff --git a/embedded/gitignore b/embedded/gitignore new file mode 100644 index 0000000..4453e16 --- /dev/null +++ b/embedded/gitignore @@ -0,0 +1,6 @@ +# +# GitIgnore for JoeyDev Projects +# + +# No baked data. +*.dat diff --git a/embedded/missing.h b/embedded/missing.h new file mode 100644 index 0000000..871ea71 --- /dev/null +++ b/embedded/missing.h @@ -0,0 +1,38 @@ +/* + * JoeyDev + * Copyright (C) 2018-2023 Scott Duensing + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef MISSING_H +#define MISSING_H + + +// These are valid for 64 bit hosts. +typedef short int16_t; +typedef int int32_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; + + +// Things missing that are nice to have. +extern int fputc(int c, FILE *stream); +extern void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); + + +#endif // MISSING_H diff --git a/embedded/recipe.c b/embedded/recipe.c new file mode 100644 index 0000000..b288b7f --- /dev/null +++ b/embedded/recipe.c @@ -0,0 +1,16 @@ +/* + / + / JoeyDev Recipe + / +*/ + + +#include + + +int recipe(char *fileIn, char *outputPath) { + + // This program runs with the current working directory set to 'outputPath'. + + return 0; // Return a positive non-zero value on failure. +} diff --git a/embedded/recipe.h b/embedded/recipe.h index 2bd393e..87845fe 100644 --- a/embedded/recipe.h +++ b/embedded/recipe.h @@ -29,27 +29,16 @@ #include #include #include - - -// These are valid for 64 bit hosts. -typedef short int16_t; -typedef int int32_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; +#include // Our shared data. extern char **___recipeTargets; -// Things missing that are nice to have. -extern int fputc(int c, FILE *stream); -extern void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); - // Our API. -extern char *utilCreateString(char *format, ...); -extern void recipeAddTarget(char *target); -extern void recipeMessage(char *format, ...); +extern void recipeAddTarget(char *target); +extern void recipeMessage(char *format, ...); #endif // RECIPE_H diff --git a/include/editor.h b/include/editor.h index 74f7e77..bb6a7ba 100644 --- a/include/editor.h +++ b/include/editor.h @@ -24,7 +24,7 @@ #define EDITOR_H -void winEditorCreate(void); +void winEditorCreate(char *filename); #endif // EDITOR_H diff --git a/include/utils.h b/include/utils.h index a577773..8e8f8b3 100644 --- a/include/utils.h +++ b/include/utils.h @@ -44,6 +44,7 @@ void utilDequote(char *string); void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted); void utilExtractResource(char *path); char *utilFileBasename(char *path); +gboolean utilFileCopy(char *from, char *to); gboolean utilFileExists(char *filename); gboolean utilFileOpen(WindowDataT *self, char *extension, char *what); char *utilFileRemoveExtension(char *filename); diff --git a/src/editor.c b/src/editor.c index 6aed97a..7caca52 100644 --- a/src/editor.c +++ b/src/editor.c @@ -26,6 +26,10 @@ #include "scintillaHeaders.h" +#define MARKER_ERROR_ARROW 0 +#define MARKER_ERROR_HIGHLIGHT 1 + + typedef struct EditorDataS { WindowDataT windowData; GtkWidget *boxForEditor; @@ -41,13 +45,38 @@ typedef struct EditorDataS { static int _nextEditorId = 0; +static void clearEditor(EditorDataT *self); EVENT void editorEditorNotify(GtkWidget *sciWidget, gint ctrlID, struct SCNotification *notifyData, gpointer userData); +static void loadEditor(EditorDataT *self); static void loadEditorConfig(char *lexer, EditorDataT *self); +EVENT void menuEditorEditCopy(GtkWidget *object, gpointer userData); +EVENT void menuEditorEditCut(GtkWidget *object, gpointer userData); +EVENT void menuEditorEditDelete(GtkWidget *object, gpointer userData); +EVENT void menuEditorEditPaste(GtkWidget *object, gpointer userData); +EVENT void menuEditorFileClose(GtkWidget *object, gpointer userData); +EVENT void menuEditorFileNew(GtkWidget *object, gpointer userData); +EVENT void menuEditorFileOpen(GtkWidget *object, gpointer userData); +EVENT void menuEditorFileSave(GtkWidget *object, gpointer userData); +EVENT void menuEditorFileSaveAs(GtkWidget *object, gpointer userData); +EVENT void menuEditorHelpEditor(GtkWidget *object, gpointer userData); +static void status(EditorDataT *self, char *message); EVENT gboolean winEditorClose(GtkWidget *object, gpointer userData); static void winEditorDelete(gpointer userData); static void writeEditorConfig(char *lexer, EditorDataT *self); +static void clearEditor(EditorDataT *self) { + (void)self; + + // Clear editor. + SSM(SCI_CLEARALL, 0, 0); + + // Clear error markers. + SSM(SCI_MARKERDELETEALL, MARKER_ERROR_ARROW, 0); + SSM(SCI_MARKERDELETEALL, MARKER_ERROR_HIGHLIGHT, 0); +} + + EVENT void editorEditorNotify(GtkWidget *sciWidget, gint ctrlID, struct SCNotification *notifyData, gpointer userData) { EditorDataT *self = (EditorDataT *)userData; int lineNumber = (int)SSM(SCI_LINEFROMPOSITION, (uptr_t)notifyData->position, (sptr_t)0); @@ -75,6 +104,26 @@ EVENT void editorEditorNotify(GtkWidget *sciWidget, gint ctrlID, struct SCNotifi } +static void loadEditor(EditorDataT *self) { + FILE *in = NULL; + char *line = NULL; + size_t len = 0; + + in = fopen(self->windowData.filename, "rt"); + if (in != NULL) { + utilEnsureBufferSize((unsigned char **)&line, (int *)&len, 1024); // Not technically needed, but fixes a pointer warning from memmaker. + while (getline(&line, &len, in) != -1) { + SSM(SCI_ADDTEXT, strlen(line), (sptr_t)line); + } + fclose(in); + DEL(line); + } + + // Do again - loading text marks us dirty. + utilSetDirty((WindowDataT *)self, FALSE); +} + + static void loadEditorConfig(char *lexer, EditorDataT *self) { char *config = NULL; FILE *in = NULL; @@ -168,6 +217,152 @@ static void loadEditorConfig(char *lexer, EditorDataT *self) { } +EVENT void menuEditorEditCopy(GtkWidget *object, gpointer userData) { + EditorDataT *self = (EditorDataT *)userData; + + (void)object; + + SSM(SCI_COPY, 0, 0); +} + + +EVENT void menuEditorEditCut(GtkWidget *object, gpointer userData) { + EditorDataT *self = (EditorDataT *)userData; + + (void)object; + + SSM(SCI_CUT, 0, 0); +} + + +EVENT void menuEditorEditDelete(GtkWidget *object, gpointer userData) { + EditorDataT *self = (EditorDataT *)userData; + + (void)object; + + SSM(SCI_CLEAR, 0, 0); +} + + +EVENT void menuEditorEditPaste(GtkWidget *object, gpointer userData) { + EditorDataT *self = (EditorDataT *)userData; + + (void)object; + + SSM(SCI_PASTE, 0, 0); +} + + +EVENT void menuEditorFileClose(GtkWidget *object, gpointer userData) { + EditorDataT *self = (EditorDataT *)userData; + + (void)object; + + gtk_window_close(GTK_WINDOW(self->windowData.window)); +} + + +EVENT void menuEditorFileNew(GtkWidget *object, gpointer userData) { + EditorDataT *self = (EditorDataT *)userData; + + (void)object; + + if (self->windowData.isDirty == TRUE) { + if (!utilQuestionDialog(self->windowData.window, "New", "You have unsaved changes. Start new?")) { + return; + } + status(self, "New image."); + } + + clearEditor(self); + + // Clear any filename. + DEL(self->windowData.filename); + + // Mark clean. + utilSetDirty((WindowDataT *)self, FALSE); +} + + +EVENT void menuEditorFileOpen(GtkWidget *object, gpointer userData) { + EditorDataT *self = (EditorDataT *)userData; + + (void)object; + + if (utilFileOpen((WindowDataT *)userData, "*.*", "Code")) { + clearEditor(self); + loadEditor(self); + } +} + + +EVENT void menuEditorFileSave(GtkWidget *object, gpointer userData) { + EditorDataT *self = (EditorDataT *)userData; + int length = SSM(SCI_GETLENGTH, 0, 0); + FILE *out = NULL; + char *code = NULL; + + // Do we need to save? + if (self->windowData.isDirty == TRUE) { + + // Do we have a filename? If not, kick 'em to SaveAs. + if (self->windowData.filename == NULL) { + menuEditorFileSaveAs(object, userData); + return; + } + + // Allocate space to fetch code from editor. + code = (char *)malloc(length + 1); + if (!code) { + //***TODO*** Something bad happened. + return; + } + + // Fetch code. + SSM(SCI_GETTEXT, length, (sptr_t)code); + + out = fopen(self->windowData.filename, "wt"); + if (out != NULL) { + // Save! + fprintf(out, "%s\n", code); + fclose(out); + status(self, "Saved."); + // We're clean now. + utilSetDirty((WindowDataT *)self, FALSE); + } else { + //***TODO*** Something bad happened. + } + + // Release code. + DEL(code); + } +} + + +EVENT void menuEditorFileSaveAs(GtkWidget *object, gpointer userData) { + + (void)object; + + if (utilFileSaveAs((WindowDataT *)userData, "*.*", "Code")) { + menuEditorFileSave(object, (EditorDataT *)userData); + } +} + + +EVENT void menuEditorHelpEditor(GtkWidget *object, gpointer userData) { + (void)object; + (void)userData; + + gtk_show_uri_on_window(NULL, "https://skunkworks.kangaroopunch.com/skunkworks/joeydev/-/wikis/Code-Editor", GDK_CURRENT_TIME, NULL); +} + + +static void status(EditorDataT *self, char *message) { + gtk_statusbar_remove_all(GTK_STATUSBAR(self->statusBar), self->statusBarId); + gtk_statusbar_push(GTK_STATUSBAR(self->statusBar), self->statusBarId, message); +} + + EVENT gboolean winEditorClose(GtkWidget *object, gpointer userData) { // userData is not reliable due to menuVectorFileClose and util indirectly calling us. EditorDataT *self = (EditorDataT *)utilGetWindowData(object); @@ -187,7 +382,7 @@ EVENT gboolean winEditorClose(GtkWidget *object, gpointer userData) { } -void winEditorCreate(void) { +void winEditorCreate(char *filename) { EditorDataT *self; char *widgetNames[] = { "winEditor", @@ -262,6 +457,12 @@ void winEditorCreate(void) { SSM(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_TCORNER); SSM(SCI_SETFOLDFLAGS, SC_FOLDFLAG_LINEAFTER_CONTRACTED , 0); + // Margin markers. + SSM(SCI_MARKERDEFINE, MARKER_ERROR_ARROW, SC_MARK_SHORTARROW); // Error + SSM(SCI_MARKERSETBACK, MARKER_ERROR_ARROW, 255 | (0 << 8) | (0 << 16)); // RGB + SSM(SCI_MARKERDEFINE, MARKER_ERROR_HIGHLIGHT, SC_MARK_BACKGROUND); // Error + SSM(SCI_MARKERSETBACK, MARKER_ERROR_HIGHLIGHT, 127 | (0 << 8) | (0 << 16)); // RGB + // Add lexer for language support. self->pLexer = CreateLexer("cpp"); SSM(SCI_SETILEXER, 0, (sptr_t)self->pLexer); @@ -274,6 +475,11 @@ void winEditorCreate(void) { // Show window. gtk_widget_show_all(self->windowData.window); + + if (filename != NULL) { + self->windowData.filename = strdup(filename); + loadEditor(self); + } } diff --git a/src/joeydev.c b/src/joeydev.c index b3220f4..f821e02 100644 --- a/src/joeydev.c +++ b/src/joeydev.c @@ -70,7 +70,7 @@ EVENT void toolJoeyDevEditorClicked(GtkWidget *widget, gpointer userData) { (void)widget; (void)userData; - winEditorCreate(); + winEditorCreate(NULL); } diff --git a/src/main.c b/src/main.c index 30b6662..916bab4 100644 --- a/src/main.c +++ b/src/main.c @@ -59,9 +59,11 @@ int main(int argc, char **argv) { utilExtractResource("/com/kangaroopunch/joeydev/resources/stdnoreturn.h"); utilExtractResource("/com/kangaroopunch/joeydev/resources/tccdefs.h"); utilExtractResource("/com/kangaroopunch/joeydev/resources/tcclib.h"); - utilExtractResource("/com/kangaroopunch/joeydev/resources/tgmath.h"); // Not needed. - utilExtractResource("/com/kangaroopunch/joeydev/resources/varargs.h"); // Not needed. + utilExtractResource("/com/kangaroopunch/joeydev/resources/missing.h"); utilExtractResource("/com/kangaroopunch/joeydev/resources/recipe.h"); + utilExtractResource("/com/kangaroopunch/joeydev/resources/recipe.c"); + utilExtractResource("/com/kangaroopunch/joeydev/resources/gitignore"); + utilExtractResource("/com/kangaroopunch/joeydev/resources/gitattributes"); winJoeyDevCreate(); gtk_main(); diff --git a/src/project.c b/src/project.c index 877462c..df5e16a 100644 --- a/src/project.c +++ b/src/project.c @@ -33,6 +33,7 @@ #include "ssh.h" #include "messages.h" #include "compiler.h" +#include "editor.h" enum ProjectColumnsE { @@ -80,6 +81,7 @@ typedef struct ProjectDataS { char *buildPassword; TargetT **targets; GtkWidget *tempWidget; // Used to pass data around dialogs. + char *tempString; // Used to pass data around dialogs. } ProjectDataT; typedef struct SectionDataS { @@ -110,6 +112,7 @@ static ProjectDataT *_cookingProjectData = NULL; static void addToRecipeData(ProjectDataT *self, char *key, char *value); EVENT void buildTargetClicked(GtkButton *widget, gpointer userData); +EVENT void btnEditRawClicked(GtkButton *widget, gpointer userData); EVENT void btnEditRecipeClicked(GtkButton *widget, gpointer userData); EVENT void btnNewRecipeClicked(GtkButton *widget, gpointer userData); static void clearRecipeData(ProjectDataT *self); @@ -159,6 +162,26 @@ EVENT void buildTargetClicked(GtkButton *widget, gpointer userData) { } +EVENT void btnEditRawClicked(GtkButton *widget, gpointer userData) { + ProjectDataT *self = (ProjectDataT *)userData; + char *pathTemp = NULL; + char *filename = NULL; + int i; + + (void)widget; + + pathTemp = strdup(self->windowData.filename); + cwk_path_get_dirname(pathTemp, (size_t *)&i); //***TODO*** Self is getting clobbered here. WTF? + if (i > 0) pathTemp[i] = 0; + + //***TODO*** Be sure this is something we can edit as text. + + filename = utilCreateString("%s%s", pathTemp, self->tempString); + winEditorCreate(filename); + DEL(filename); +} + + EVENT void btnEditRecipeClicked(GtkButton *widget, gpointer userData) { ProjectDataT *self = (ProjectDataT *)userData; char *file = NULL; @@ -167,38 +190,46 @@ EVENT void btnEditRecipeClicked(GtkButton *widget, gpointer userData) { file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(self->tempWidget)); if (utilFileExists(file)) { - //***TODO*** Text Editor + winEditorCreate(file); } DEL(file); } EVENT void btnNewRecipeClicked(GtkButton *widget, gpointer userData) { - ProjectDataT *self = (ProjectDataT *)userData; - char *newFile = NULL; - FILE *out = NULL; + ProjectDataT *self = (ProjectDataT *)userData; + char *newFile = NULL; + char *fromTemp = NULL; + char *toTemp = NULL; + char *pathTemp = NULL; + int i; (void)widget; - //***TODO*** This should be an embedded file. - //***TODO*** We should also provide .gitignore and .gitattribute files. if (utilFileSaveOtherAs((WindowDataT *)userData, "*.c", "Recipe", &newFile)) { - out = fopen(newFile, "wt"); - fprintf(out, "" - "//\n" - "// JoeyBuild Recipe Program\n" - "//\n" - "\n" - "\n" - "#include \n" - "\n" - "\n" - "int recipe(char *fileIn, char *outputPath) {\n" - "\n" - "\treturn 0; // Return a positive non-zero value on failure.\n" - "}\n" - ); - fclose(out); + + pathTemp = strdup(self->windowData.filename); + cwk_path_get_dirname(pathTemp, (size_t *)&i); + if (i > 0) pathTemp[i] = 0; + + fromTemp = utilCreateString("%s%s", __resourcePath, "recipe.c"); + utilFileCopy(fromTemp, newFile); + DEL(fromTemp); + + fromTemp = utilCreateString("%s%s", __resourcePath, "gitignore"); + toTemp = utilCreateString("%s%s", pathTemp, ".gitignore"); + utilFileCopy(fromTemp, toTemp); + DEL(toTemp); + DEL(fromTemp); + + fromTemp = utilCreateString("%s%s", __resourcePath, "gitattributes"); + toTemp = utilCreateString("%s%s", pathTemp, ".gitattributes"); + utilFileCopy(fromTemp, toTemp); + DEL(toTemp); + DEL(fromTemp); + + DEL(pathTemp); + gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(self->tempWidget), newFile); } } @@ -252,6 +283,7 @@ static void dialogCookOptions(char *filename, ProjectDataT *self) { gtk_label_set_text(GTK_LABEL(lblRaw), raw); self->tempWidget = fileRecipe; + self->tempString = strdup(raw); // Find path of project file. path = strdup(self->windowData.filename); @@ -285,7 +317,9 @@ static void dialogCookOptions(char *filename, ProjectDataT *self) { DEL(path); DEL(raw); + self->tempWidget = NULL; + DEL(self->tempString); gtk_widget_destroy(dialogCookSettings); } @@ -1036,7 +1070,10 @@ EVENT void treeProjectRowActivated(GtkTreeView *treeView, GtkTreePath *path, Gtk GtkTreeIter iter; char *name = NULL; char *pathString = NULL; + char *pathTemp = NULL; + char *filename = NULL; int section; + int i; pathString = gtk_tree_path_to_string(path); if (strstr(pathString, ":") != NULL) { @@ -1047,8 +1084,15 @@ EVENT void treeProjectRowActivated(GtkTreeView *treeView, GtkTreePath *path, Gtk debug("Double click! [%d] [%s] [%s]\n", section, pathString, name); if (section == SECTION_CODE || section == SECTION_HEADER) { + //***TODO*** We find our path way too often. Do it once and keep it. + pathTemp = strdup(self->windowData.filename); + cwk_path_get_dirname(pathTemp, (size_t *)&i); + if (i > 0) pathTemp[i] = 0; + filename = utilCreateString("%s%s", pathTemp, name); // Launch code editor. - //***TODO*** + winEditorCreate(filename); + DEL(filename); + DEL(pathTemp); } if (section == SECTION_RAW_DATA) { diff --git a/src/utils.c b/src/utils.c index 3b6b97f..afc112c 100644 --- a/src/utils.c +++ b/src/utils.c @@ -183,6 +183,33 @@ char *utilFileBasename(char *path) { } +gboolean utilFileCopy(char *from, char *to) { + FILE *in = NULL; + FILE *out = NULL; + gboolean result = FALSE; + size_t bytes; + + in = fopen(from, "rb"); + if (in) { + out = fopen(to, "wb"); + if (out) { + while (!feof(in)) { + bytes = fread(__utilFilenameBuffer, 1, FILENAME_MAX, in); + if (bytes) { + fwrite(__utilFilenameBuffer, 1, bytes, out); + } + } + result = TRUE; + fclose(out); + } + fclose(in); + } + + return result; + +} + + gboolean utilFileExists(char *filename) { FILE *f = fopen(filename, "rb"); @@ -266,47 +293,7 @@ char *utilFileRemoveExtension(char *filename) { gboolean utilFileSaveAs(WindowDataT *self, char *extension, char *what) { - GtkWidget *dialog; - GtkFileFilter *filter; - gboolean result = FALSE; - char *files = utilCreateString("%s Files", what); - int x; - - //***TODO*** Make this use utilFileSaveOtherAS - - dialog = gtk_file_chooser_dialog_new("Save As", - GTK_WINDOW(self->window), - GTK_FILE_CHOOSER_ACTION_SAVE, - "_Cancel", GTK_RESPONSE_CANCEL, - "_Save", GTK_RESPONSE_ACCEPT, - NULL); - - if (self->filename != NULL) { - memcpy(__utilFilenameBuffer, self->filename, strlen(self->filename) + 1); - cwk_path_get_dirname(__utilFilenameBuffer, (size_t *)&x); - if (x > 0) __utilFilenameBuffer[x] = 0; - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),__utilFilenameBuffer); - } - - gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); - - filter = gtk_file_filter_new(); - gtk_file_filter_set_name(filter, files); - gtk_file_filter_add_pattern(filter, extension); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); - - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - DEL(self->filename); - self->filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - utilSetDirty(self, TRUE); - result = TRUE; - } - - DEL(files); - - gtk_widget_destroy(dialog); - - return result; + return utilFileSaveOtherAs(self, extension, what, &self->filename); } diff --git a/src/vector.c b/src/vector.c index 6afda50..7f2e645 100644 --- a/src/vector.c +++ b/src/vector.c @@ -40,6 +40,9 @@ #include "palette.h" +//***TODO*** Reuse editor.c instead of using our own text editor here. + + #define RENDER_TIMEOUT 5 // In seconds #define MARKER_ERROR_ARROW 0 @@ -99,6 +102,7 @@ static int _nextEditorId = 0; static int byte(VectorDataT *self, unsigned char byte); +static void clearVectorEditor(VectorDataT *self); EVENT void drawVectorImageClick(GtkWidget *object, GdkEventButton *event, gpointer userData); EVENT gboolean drawVectorImageDraw(GtkWidget *widget, cairo_t *cr, gpointer userData); EVENT gboolean drawVectorImageMotionEvent(GtkWidget *widget, GdkEventMotion *event, gpointer userData); @@ -153,6 +157,29 @@ static int byte(VectorDataT *self, unsigned char byte) { } +static void clearVectorEditor(VectorDataT *self) { + // Clear editor. + SSM(SCI_CLEARALL, 0, 0); + + // Clear error markers. + SSM(SCI_MARKERDELETEALL, MARKER_ERROR_ARROW, 0); + SSM(SCI_MARKERDELETEALL, MARKER_ERROR_HIGHLIGHT, 0); + + // Reset JoeyLib drawing state. + jlPaletteDefault(self->jlc); + jlDrawColorSet(self->jlc, 0); + jlDrawClear(self->jlc); + jlDrawColorSet(self->jlc, 15); + + // Destroy trace image, if any. + if (self->trace != NULL) { + cairo_surface_destroy(self->trace); + self->trace = NULL; + gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(self->fileVectorTraceImage)); + } +} + + EVENT void drawVectorImageClick(GtkWidget *object, GdkEventButton *event, gpointer userData) { VectorDataT *self = (VectorDataT *)userData; char temp[8]; @@ -704,26 +731,14 @@ EVENT void menuVectorFileNew(GtkWidget *object, gpointer userData) { status(self, "New image."); } - // Clear editor. - SSM(SCI_CLEARALL, 0, 0); - // Clear error markers. - SSM(SCI_MARKERDELETEALL, MARKER_ERROR_ARROW, 0); - SSM(SCI_MARKERDELETEALL, MARKER_ERROR_HIGHLIGHT, 0); - // Reset JoeyLib drawing state. - jlPaletteDefault(self->jlc); - jlDrawColorSet(self->jlc, 0); - jlDrawClear(self->jlc); - jlDrawColorSet(self->jlc, 15); - // Destroy trace image, if any. - if (self->trace != NULL) { - cairo_surface_destroy(self->trace); - self->trace = NULL; - gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(self->fileVectorTraceImage)); - } + clearVectorEditor(self); + // Clear any filename. DEL(self->windowData.filename); + // Refresh widget. gtk_widget_queue_draw(self->drawVectorImage); + // Mark clean. utilSetDirty((WindowDataT *)self, FALSE); } @@ -735,6 +750,7 @@ EVENT void menuVectorFileOpen(GtkWidget *object, gpointer userData) { (void)object; if (utilFileOpen((WindowDataT *)userData, "*.vic", "Image")) { + clearVectorEditor(self); loadVectorImage(self); } } diff --git a/ui/Cook.glade b/ui/Cook.glade index ab2fc01..d5b31a6 100644 --- a/ui/Cook.glade +++ b/ui/Cook.glade @@ -61,7 +61,7 @@ center vertical - + True False @@ -92,19 +92,7 @@ 1 1 - - - - - New - True - True - True - - - - 2 - 1 + 2 @@ -133,14 +121,41 @@ - - Edit + + Edit Recipe True True True - 15 + + 0 + 2 + 2 + + + + + Edit Raw Data + True + True + True + + + + 2 + 2 + 2 + + + + + New + True + True + True + + 3 1 diff --git a/ui/Editor.glade b/ui/Editor.glade index 8ffcb7c..e8de69b 100644 --- a/ui/Editor.glade +++ b/ui/Editor.glade @@ -19,7 +19,7 @@ True False - + True False _File @@ -29,31 +29,43 @@ True False - + True False + New True + + - + True False + Open... True + + - + True False + Save True + + - + True False + Save As... True + + @@ -63,10 +75,13 @@ - + True False + Close True + + @@ -74,7 +89,7 @@ - + True False _Edit @@ -84,31 +99,42 @@ True False - + True False + Cut True + + - + True False + Copy True + + - + True False + Paste True + + - + True False + Delete True + @@ -116,15 +142,7 @@ - - True - False - _View - True - - - - + True False _Help @@ -134,10 +152,13 @@ True False - + True False + Code Editor... True + + diff --git a/ui/joeydev.gresource.xml b/ui/joeydev.gresource.xml index bfb205c..0eb417d 100644 --- a/ui/joeydev.gresource.xml +++ b/ui/joeydev.gresource.xml @@ -33,8 +33,10 @@ ../thirdparty-installed/lib/tcc/include/stdnoreturn.h ../thirdparty-installed/lib/tcc/include/tccdefs.h ../thirdparty-installed/lib/tcc/include/tcclib.h - ../thirdparty-installed/lib/tcc/include/tgmath.h - ../thirdparty-installed/lib/tcc/include/varargs.h + ../embedded/missing.h ../embedded/recipe.h + ../embedded/recipe.c + ../embedded/gitignore + ../embedded/gitattributes