Code Editor starting to work. Integration with raw data is screwball for some reason.
This commit is contained in:
parent
917eedb95b
commit
870d2822e0
16 changed files with 498 additions and 139 deletions
16
embedded/gitattributes
Normal file
16
embedded/gitattributes
Normal file
|
@ -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
|
6
embedded/gitignore
Normal file
6
embedded/gitignore
Normal file
|
@ -0,0 +1,6 @@
|
|||
#
|
||||
# GitIgnore for JoeyDev Projects
|
||||
#
|
||||
|
||||
# No baked data.
|
||||
*.dat
|
38
embedded/missing.h
Normal file
38
embedded/missing.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* JoeyDev
|
||||
* Copyright (C) 2018-2023 Scott Duensing <scott@kangaroopunch.com>
|
||||
*
|
||||
* 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
|
16
embedded/recipe.c
Normal file
16
embedded/recipe.c
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
/
|
||||
/ JoeyDev Recipe
|
||||
/
|
||||
*/
|
||||
|
||||
|
||||
#include <recipe.h>
|
||||
|
||||
|
||||
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.
|
||||
}
|
|
@ -29,25 +29,14 @@
|
|||
#include <stdatomic.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdnoreturn.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;
|
||||
#include <missing.h>
|
||||
|
||||
|
||||
// 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, ...);
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#define EDITOR_H
|
||||
|
||||
|
||||
void winEditorCreate(void);
|
||||
void winEditorCreate(char *filename);
|
||||
|
||||
|
||||
#endif // EDITOR_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);
|
||||
|
|
208
src/editor.c
208
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ EVENT void toolJoeyDevEditorClicked(GtkWidget *widget, gpointer userData) {
|
|||
(void)widget;
|
||||
(void)userData;
|
||||
|
||||
winEditorCreate();
|
||||
winEditorCreate(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,7 +190,7 @@ 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);
|
||||
}
|
||||
|
@ -176,29 +199,37 @@ EVENT void btnEditRecipeClicked(GtkButton *widget, gpointer userData) {
|
|||
EVENT void btnNewRecipeClicked(GtkButton *widget, gpointer userData) {
|
||||
ProjectDataT *self = (ProjectDataT *)userData;
|
||||
char *newFile = NULL;
|
||||
FILE *out = 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 <recipe.h>\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) {
|
||||
|
|
69
src/utils.c
69
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
48
src/vector.c
48
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
<property name="valign">center</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<!-- n-columns=4 n-rows=2 -->
|
||||
<!-- n-columns=4 n-rows=3 -->
|
||||
<object class="GtkGrid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
|
@ -92,19 +92,7 @@
|
|||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="btnNewRecipe">
|
||||
<property name="label" translatable="yes">New</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<signal name="clicked" handler="btnNewRecipeClicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">1</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -133,14 +121,41 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="btnEdit">
|
||||
<property name="label" translatable="yes">Edit</property>
|
||||
<object class="GtkButton" id="btnEditRecipe">
|
||||
<property name="label" translatable="yes">Edit Recipe</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="margin-start">15</property>
|
||||
<signal name="clicked" handler="btnEditRecipeClicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="btnEditRaw">
|
||||
<property name="label" translatable="yes">Edit Raw Data</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<signal name="clicked" handler="btnEditRawClicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="btnNewRecipe">
|
||||
<property name="label" translatable="yes">New</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<signal name="clicked" handler="btnNewRecipeClicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">3</property>
|
||||
<property name="top-attach">1</property>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<object class="GtkMenuItem" id="menuEditorFile">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">_File</property>
|
||||
|
@ -29,31 +29,43 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<object class="GtkMenuItem" id="menuEditorFileNew">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">New</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuEditorFileNew" swapped="no"/>
|
||||
<accelerator key="n" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<object class="GtkMenuItem" id="menuEditorFileOpen">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Open...</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuEditorFileOpen" swapped="no"/>
|
||||
<accelerator key="o" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<object class="GtkMenuItem" id="menuEditorFileSave">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Save</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuEditorFileSave" swapped="no"/>
|
||||
<accelerator key="s" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<object class="GtkMenuItem" id="menuEditorFileSaveAs">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Save As...</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuEditorFileSaveAs" swapped="no"/>
|
||||
<accelerator key="s" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -63,10 +75,13 @@
|
|||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<object class="GtkMenuItem" id="menuEditorFileClose">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Close</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuEditorFileClose" swapped="no"/>
|
||||
<accelerator key="F4" signal="activate" modifiers="GDK_MOD1_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -74,7 +89,7 @@
|
|||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<object class="GtkMenuItem" id="menuEditorEdit">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">_Edit</property>
|
||||
|
@ -84,31 +99,42 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<object class="GtkMenuItem" id="menuEditorEditCut">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Cut</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuEditorEditCut" swapped="no"/>
|
||||
<accelerator key="x" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<object class="GtkMenuItem" id="menuEditorEditCopy">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Copy</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuEditorEditCopy" swapped="no"/>
|
||||
<accelerator key="c" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<object class="GtkMenuItem" id="menuEditorEditPaste">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Paste</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuEditorEditPaste" swapped="no"/>
|
||||
<accelerator key="v" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<object class="GtkMenuItem" id="menuEditorEditDelete">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Delete</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuEditorEditDelete" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -116,15 +142,7 @@
|
|||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">_View</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<object class="GtkMenuItem" id="menuEditorHelp">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">_Help</property>
|
||||
|
@ -134,10 +152,13 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<object class="GtkMenuItem" id="menuEditorHelpEditor">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Code Editor...</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuEditorHelpEditor" swapped="no"/>
|
||||
<accelerator key="F1" signal="activate"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -33,8 +33,10 @@
|
|||
<file compressed="true" alias="stdnoreturn.h">../thirdparty-installed/lib/tcc/include/stdnoreturn.h</file>
|
||||
<file compressed="true" alias="tccdefs.h">../thirdparty-installed/lib/tcc/include/tccdefs.h</file>
|
||||
<file compressed="true" alias="tcclib.h">../thirdparty-installed/lib/tcc/include/tcclib.h</file>
|
||||
<file compressed="true" alias="tgmath.h">../thirdparty-installed/lib/tcc/include/tgmath.h</file>
|
||||
<file compressed="true" alias="varargs.h">../thirdparty-installed/lib/tcc/include/varargs.h</file>
|
||||
<file compressed="true" alias="missing.h">../embedded/missing.h</file>
|
||||
<file compressed="true" alias="recipe.h">../embedded/recipe.h</file>
|
||||
<file compressed="true" alias="recipe.c">../embedded/recipe.c</file>
|
||||
<file compressed="true" alias="gitignore">../embedded/gitignore</file>
|
||||
<file compressed="true" alias="gitattributes">../embedded/gitattributes</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
|
Loading…
Add table
Reference in a new issue