Project loading mostly implemented.
This commit is contained in:
parent
f31c292336
commit
02103f36ef
9 changed files with 295 additions and 144 deletions
|
@ -51,6 +51,8 @@ typedef struct WindowDataS {
|
||||||
GtkWidget *window;
|
GtkWidget *window;
|
||||||
gboolean (*closeWindow)(GtkWidget* widget, gpointer data);
|
gboolean (*closeWindow)(GtkWidget* widget, gpointer data);
|
||||||
gboolean isDirty;
|
gboolean isDirty;
|
||||||
|
char *title;
|
||||||
|
char *filename;
|
||||||
} WindowDataT;
|
} WindowDataT;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,11 @@ char *utilCreateString(char *format, ...);
|
||||||
char *utilCreateStringVArgs(char *format, va_list args);
|
char *utilCreateStringVArgs(char *format, va_list args);
|
||||||
void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted);
|
void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted);
|
||||||
gboolean utilFileExists(char *filename);
|
gboolean utilFileExists(char *filename);
|
||||||
|
gboolean utilFileOpen(WindowDataT *self, char *extension, char *what);
|
||||||
WindowDataT *utilGetWindowData(GtkWidget *window);
|
WindowDataT *utilGetWindowData(GtkWidget *window);
|
||||||
gboolean utilGetWidgetsFromMemory(char *resource, char *name[], GtkWidget **widgets[], gpointer userData);
|
gboolean utilGetWidgetsFromMemory(char *resource, char *name[], GtkWidget **widgets[], gpointer userData);
|
||||||
gboolean utilQuestionDialog(GtkWidget *parent, char *title, char *question);
|
gboolean utilQuestionDialog(GtkWidget *parent, char *title, char *question);
|
||||||
|
void utilSetDirty(WindowDataT *self, gboolean dirty);
|
||||||
void utilWindowRegister(gpointer windowData);
|
void utilWindowRegister(gpointer windowData);
|
||||||
int utilWindowsCloseAll(void);
|
int utilWindowsCloseAll(void);
|
||||||
int utilWindowsOpen(void);
|
int utilWindowsOpen(void);
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#define VECTOR_H
|
#define VECTOR_H
|
||||||
|
|
||||||
|
|
||||||
void winVectorCreate(void);
|
void winVectorCreate(char *filename);
|
||||||
|
|
||||||
|
|
||||||
#endif // VECTOR_H
|
#endif // VECTOR_H
|
||||||
|
|
|
@ -28,11 +28,6 @@
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
|
|
||||||
|
|
||||||
//***TODO*** This entire thing should render to a 4 bit buffer and only
|
|
||||||
// convert to truecolor when needed. That way we can implement palette
|
|
||||||
// side effects.
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
jint16 StartX;
|
jint16 StartX;
|
||||||
jint16 EndX;
|
jint16 EndX;
|
||||||
|
|
|
@ -81,7 +81,7 @@ EVENT void toolJoeyDevVectorClicked(GtkWidget *widget, gpointer userData) {
|
||||||
(void)widget;
|
(void)widget;
|
||||||
(void)userData;
|
(void)userData;
|
||||||
|
|
||||||
winVectorCreate();
|
winVectorCreate(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -104,15 +104,15 @@ GtkWidget *palette_dialog_new(GtkWidget *parent, char *title, unsigned char r, u
|
||||||
self = NEW(PaletteDialogDataT);
|
self = NEW(PaletteDialogDataT);
|
||||||
|
|
||||||
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
||||||
gtk_box_set_spacing(vbox, 10);
|
gtk_box_set_spacing(GTK_BOX(vbox), 10);
|
||||||
|
|
||||||
self->drawingArea = gtk_drawing_area_new();
|
self->drawingArea = gtk_drawing_area_new();
|
||||||
gtk_widget_set_size_request(self->drawingArea, 128, 64);
|
gtk_widget_set_size_request(self->drawingArea, 128, 64);
|
||||||
g_signal_connect(G_OBJECT(self->drawingArea), "draw", G_CALLBACK(paletteDialogDraw), self);
|
g_signal_connect(G_OBJECT(self->drawingArea), "draw", G_CALLBACK(paletteDialogDraw), self);
|
||||||
|
|
||||||
grid = gtk_grid_new();
|
grid = gtk_grid_new();
|
||||||
gtk_grid_set_column_spacing(grid, 10);
|
gtk_grid_set_column_spacing(GTK_GRID(grid), 10);
|
||||||
gtk_grid_set_row_spacing(grid, 10);
|
gtk_grid_set_row_spacing(GTK_GRID(grid), 10);
|
||||||
|
|
||||||
labelRed = gtk_label_new("Red:");
|
labelRed = gtk_label_new("Red:");
|
||||||
labelGreen = gtk_label_new("Green:");
|
labelGreen = gtk_label_new("Green:");
|
||||||
|
|
175
src/project.c
175
src/project.c
|
@ -20,27 +20,54 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma ide diagnostic ignored "cppcoreguidelines-narrowing-conversions"
|
||||||
|
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
enum ProjectSectionTypeE {
|
||||||
|
SECTION_HEADER = 0,
|
||||||
|
SECTION_CODE,
|
||||||
|
SECTION_BITMAP,
|
||||||
|
SECTION_STENCIL,
|
||||||
|
SECTION_VECTOR,
|
||||||
|
SECTION_SOUND,
|
||||||
|
SECTION_MUSIC,
|
||||||
|
SECTION_RAW_DATA,
|
||||||
|
SECTION_COOKED_DATA,
|
||||||
|
SECTION_COUNT
|
||||||
|
};
|
||||||
|
typedef enum ProjectSectionTypeE ProjectSectionTypeT;
|
||||||
|
|
||||||
|
|
||||||
typedef struct ProjectDataS {
|
typedef struct ProjectDataS {
|
||||||
WindowDataT windowData;
|
WindowDataT windowData;
|
||||||
GtkWidget *treeProject;
|
GtkWidget *treeProject;
|
||||||
GtkTreeStore *storeProject;
|
GtkTreeStore *storeProject;
|
||||||
GtkTreeIter iterTop;
|
char *title;
|
||||||
GtkTreeIter iterHeaders;
|
char *filename;
|
||||||
GtkTreeIter iterCode;
|
|
||||||
GtkTreeIter iterBitmaps;
|
|
||||||
GtkTreeIter iterVectors;
|
|
||||||
GtkTreeIter iterSounds;
|
|
||||||
GtkTreeIter iterMusic;
|
|
||||||
GtkTreeIter iterData;
|
|
||||||
char *title;
|
|
||||||
} ProjectDataT;
|
} ProjectDataT;
|
||||||
|
|
||||||
|
|
||||||
|
static char *_SectionName[] = {
|
||||||
|
"Header",
|
||||||
|
"Code",
|
||||||
|
"Bitmap",
|
||||||
|
"Stencil",
|
||||||
|
"Vector",
|
||||||
|
"Sound",
|
||||||
|
"Music",
|
||||||
|
"Raw Data",
|
||||||
|
"Cooked Data",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void loadProject(ProjectDataT *self);
|
||||||
EVENT void menuProjectFileNew(GtkWidget *object, gpointer userData);
|
EVENT void menuProjectFileNew(GtkWidget *object, gpointer userData);
|
||||||
EVENT void menuProjectFileOpen(GtkWidget *object, gpointer userData);
|
EVENT void menuProjectFileOpen(GtkWidget *object, gpointer userData);
|
||||||
EVENT void menuProjectFileSave(GtkWidget *object, gpointer userData);
|
EVENT void menuProjectFileSave(GtkWidget *object, gpointer userData);
|
||||||
|
@ -56,13 +83,104 @@ EVENT gboolean winProjectClose(GtkWidget *object, gpointer userData);
|
||||||
static void winProjectDelete(gpointer userData);
|
static void winProjectDelete(gpointer userData);
|
||||||
|
|
||||||
|
|
||||||
|
static void loadProject(ProjectDataT *self) {
|
||||||
|
FILE *in = NULL;
|
||||||
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
size_t count = 0;
|
||||||
|
int16_t extension;
|
||||||
|
int end;
|
||||||
|
char temp[4];
|
||||||
|
GtkTreeIter iterParent;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
ProjectSectionTypeT section;
|
||||||
|
|
||||||
|
in = fopen(self->windowData.filename, "rt");
|
||||||
|
if (in != NULL) {
|
||||||
|
while (getline(&line, &len, in) != -1) {
|
||||||
|
if (strlen(line) > 0) line[strlen(line) - 1] = 0;
|
||||||
|
switch (count) {
|
||||||
|
case 0: // Version Number
|
||||||
|
case 1: // Separator line
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: // Project Data
|
||||||
|
// Are we reading single filenames?
|
||||||
|
// Is it long enough?
|
||||||
|
if (strlen(line) > 5) {
|
||||||
|
// Put last three bytes - the extension - into a short int so we can use it with switch.
|
||||||
|
end = (int)strlen(line) - 1;
|
||||||
|
extension = (line[end - 2] << 16) + (line[end - 1] << 8) + line[end];
|
||||||
|
//debug("%s - %d\n", line, extension);
|
||||||
|
switch (extension) {
|
||||||
|
case 11880: // h
|
||||||
|
section = SECTION_HEADER;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 11875: // c
|
||||||
|
section = SECTION_CODE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 28007: // img
|
||||||
|
section = SECTION_BITMAP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 29806: // stn
|
||||||
|
section = SECTION_STENCIL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 26979: // vic
|
||||||
|
section = SECTION_VECTOR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 28260: // snd
|
||||||
|
section = SECTION_SOUND;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 28516: // mod
|
||||||
|
section = SECTION_MUSIC;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 24951: // raw
|
||||||
|
section = SECTION_RAW_DATA;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
section = SECTION_COUNT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (section < SECTION_COUNT) {
|
||||||
|
snprintf(temp, 4, "%d", section);
|
||||||
|
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(self->storeProject), &iterParent, temp);
|
||||||
|
gtk_tree_store_append(self->storeProject, &iter, &iterParent);
|
||||||
|
gtk_tree_store_set(self->storeProject, &iter, 0, line, -1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
fclose(in);
|
||||||
|
DEL(line);
|
||||||
|
gtk_tree_view_expand_all(GTK_TREE_VIEW(self->treeProject));
|
||||||
|
utilSetDirty((WindowDataT *)self, FALSE); // Do again - loading text marks us dirty.
|
||||||
|
} else {
|
||||||
|
//***TODO*** Something bad happened.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EVENT void menuProjectFileNew(GtkWidget *object, gpointer userData) {
|
EVENT void menuProjectFileNew(GtkWidget *object, gpointer userData) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EVENT void menuProjectFileOpen(GtkWidget *object, gpointer userData) {
|
EVENT void menuProjectFileOpen(GtkWidget *object, gpointer userData) {
|
||||||
|
ProjectDataT *self = (ProjectDataT *)userData;
|
||||||
|
|
||||||
|
if (utilFileOpen((WindowDataT *)userData, "*.joe", "Project")) {
|
||||||
|
loadProject(self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,8 +267,10 @@ void winProjectCreate(void) {
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
GtkTreeViewColumn *col;
|
GtkTreeViewColumn *col;
|
||||||
GtkCellRenderer *renderer;
|
GtkCellRenderer *renderer;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
ProjectSectionTypeT i;
|
||||||
|
|
||||||
// Set up instance data.
|
// Set up instance data.
|
||||||
self = NEW(ProjectDataT);
|
self = NEW(ProjectDataT);
|
||||||
|
@ -168,20 +288,12 @@ void winProjectCreate(void) {
|
||||||
gtk_tree_view_column_pack_start(col, renderer, TRUE);
|
gtk_tree_view_column_pack_start(col, renderer, TRUE);
|
||||||
gtk_tree_view_column_add_attribute(col, renderer, "text", 0);
|
gtk_tree_view_column_add_attribute(col, renderer, "text", 0);
|
||||||
self->storeProject = gtk_tree_store_new(1, G_TYPE_STRING);
|
self->storeProject = gtk_tree_store_new(1, G_TYPE_STRING);
|
||||||
gtk_tree_store_append(self->storeProject, &self->iterTop, NULL);
|
|
||||||
gtk_tree_store_set(self->storeProject, &self->iterTop, 0, "Headers", -1);
|
for (i=0; i<SECTION_COUNT; i++) {
|
||||||
gtk_tree_store_append(self->storeProject, &self->iterTop, NULL);
|
gtk_tree_store_append(self->storeProject, &iter, NULL);
|
||||||
gtk_tree_store_set(self->storeProject, &self->iterTop, 0, "Code", -1);
|
gtk_tree_store_set(self->storeProject, &iter, 0, _SectionName[i], -1);
|
||||||
gtk_tree_store_append(self->storeProject, &self->iterTop, NULL);
|
}
|
||||||
gtk_tree_store_set(self->storeProject, &self->iterTop, 0, "Bitmaps", -1);
|
|
||||||
gtk_tree_store_append(self->storeProject, &self->iterTop, NULL);
|
|
||||||
gtk_tree_store_set(self->storeProject, &self->iterTop, 0, "Vectors", -1);
|
|
||||||
gtk_tree_store_append(self->storeProject, &self->iterTop, NULL);
|
|
||||||
gtk_tree_store_set(self->storeProject, &self->iterTop, 0, "Sounds", -1);
|
|
||||||
gtk_tree_store_append(self->storeProject, &self->iterTop, NULL);
|
|
||||||
gtk_tree_store_set(self->storeProject, &self->iterTop, 0, "Music", -1);
|
|
||||||
gtk_tree_store_append(self->storeProject, &self->iterTop, NULL);
|
|
||||||
gtk_tree_store_set(self->storeProject, &self->iterTop, 0, "Data", -1);
|
|
||||||
gtk_tree_view_set_model(GTK_TREE_VIEW(self->treeProject), GTK_TREE_MODEL(self->storeProject));
|
gtk_tree_view_set_model(GTK_TREE_VIEW(self->treeProject), GTK_TREE_MODEL(self->storeProject));
|
||||||
g_object_unref(self->storeProject);
|
g_object_unref(self->storeProject);
|
||||||
|
|
||||||
|
@ -191,6 +303,10 @@ void winProjectCreate(void) {
|
||||||
// Register window & show it.
|
// Register window & show it.
|
||||||
utilWindowRegister(self);
|
utilWindowRegister(self);
|
||||||
gtk_widget_show_all(self->windowData.window);
|
gtk_widget_show_all(self->windowData.window);
|
||||||
|
|
||||||
|
//***DEBUG***
|
||||||
|
self->windowData.filename = strdup("/home/scott/code/joeydev/cmake-build-debug/test.joe");
|
||||||
|
loadProject(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -201,3 +317,6 @@ static void winProjectDelete(gpointer userData) {
|
||||||
|
|
||||||
DEL(self);
|
DEL(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
|
75
src/utils.c
75
src/utils.c
|
@ -89,6 +89,52 @@ gboolean utilFileExists(char *filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gboolean utilFileOpen(WindowDataT *self, char *extension, char *what) {
|
||||||
|
GtkWidget *dialog;
|
||||||
|
GtkFileFilter *filter;
|
||||||
|
char *title = utilCreateString("Open %s", what);
|
||||||
|
char *warning = utilCreateString("You have unsaved changes. Open different %s?", what);
|
||||||
|
char *files = utilCreateString("%s Files", what);
|
||||||
|
gboolean result = TRUE;
|
||||||
|
|
||||||
|
if (self->isDirty) {
|
||||||
|
if (!utilQuestionDialog(self->window, title, warning)) {
|
||||||
|
result = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == TRUE) {
|
||||||
|
dialog = gtk_file_chooser_dialog_new(title,
|
||||||
|
GTK_WINDOW(self->window),
|
||||||
|
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||||
|
"_Cancel", GTK_RESPONSE_CANCEL,
|
||||||
|
"_Open", GTK_RESPONSE_ACCEPT,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
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) {
|
||||||
|
utilSetDirty((WindowDataT *)self, FALSE);
|
||||||
|
DEL(self->filename);
|
||||||
|
self->filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||||
|
} else {
|
||||||
|
result = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEL(files);
|
||||||
|
DEL(warning);
|
||||||
|
DEL(title);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WindowDataT *utilGetWindowData(GtkWidget *window) {
|
WindowDataT *utilGetWindowData(GtkWidget *window) {
|
||||||
return hmget(_windowList, window);
|
return hmget(_windowList, window);
|
||||||
}
|
}
|
||||||
|
@ -135,8 +181,34 @@ gboolean utilQuestionDialog(GtkWidget *parent, char *title, char *question) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void utilSetDirty(WindowDataT *self, gboolean dirty) {
|
||||||
|
char *title;
|
||||||
|
|
||||||
|
self->isDirty = dirty;
|
||||||
|
if (dirty) {
|
||||||
|
if (self->filename) {
|
||||||
|
title = utilCreateString("%s - %s *", self->title, self->filename);
|
||||||
|
} else {
|
||||||
|
title = utilCreateString("%s - (no name) *", self->title);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (self->filename) {
|
||||||
|
title = utilCreateString("%s - %s", self->title, self->filename);
|
||||||
|
} else {
|
||||||
|
title = utilCreateString("%s", self->title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gtk_window_set_title(GTK_WINDOW(self->window), title);
|
||||||
|
DEL(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void utilWindowRegister(gpointer windowData) {
|
void utilWindowRegister(gpointer windowData) {
|
||||||
WindowDataT *w = (WindowDataT *)windowData;
|
WindowDataT *w = (WindowDataT *)windowData;
|
||||||
|
|
||||||
|
// Grab title.
|
||||||
|
w->title = strdup(gtk_window_get_title(GTK_WINDOW(w->window)));
|
||||||
|
|
||||||
hmput(_windowList, w->window, windowData);
|
hmput(_windowList, w->window, windowData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,5 +242,8 @@ gboolean utilWindowUnRegister(gpointer windowData) {
|
||||||
WindowDataT *w = (WindowDataT *)windowData;
|
WindowDataT *w = (WindowDataT *)windowData;
|
||||||
result = hmdel(_windowList, w->window);
|
result = hmdel(_windowList, w->window);
|
||||||
|
|
||||||
|
DEL(w->filename);
|
||||||
|
DEL(w->title);
|
||||||
|
|
||||||
return (result == 1) ? TRUE : FALSE;
|
return (result == 1) ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
|
|
170
src/vector.c
170
src/vector.c
|
@ -87,8 +87,6 @@ typedef struct VectorDataS {
|
||||||
jlContextT *jlc;
|
jlContextT *jlc;
|
||||||
double traceImagePercent;
|
double traceImagePercent;
|
||||||
float *variables;
|
float *variables;
|
||||||
char *filename;
|
|
||||||
char *title;
|
|
||||||
char *tracename;
|
char *tracename;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
int bufferLength;
|
int bufferLength;
|
||||||
|
@ -113,6 +111,7 @@ static int getWord(VecByteCodeT *bytecode, int *index);
|
||||||
static void insertCommand(VectorDataT *self, char *command);
|
static void insertCommand(VectorDataT *self, char *command);
|
||||||
static void insertText(VectorDataT *self, char *text);
|
static void insertText(VectorDataT *self, char *text);
|
||||||
static void loadTraceImage(VectorDataT *self, char *filename);
|
static void loadTraceImage(VectorDataT *self, char *filename);
|
||||||
|
static void loadVectorImage(VectorDataT *self);
|
||||||
EVENT void menuVectorEditCopy(GtkWidget *object, gpointer userData);
|
EVENT void menuVectorEditCopy(GtkWidget *object, gpointer userData);
|
||||||
EVENT void menuVectorEditCut(GtkWidget *object, gpointer userData);
|
EVENT void menuVectorEditCut(GtkWidget *object, gpointer userData);
|
||||||
EVENT void menuVectorEditDelete(GtkWidget *object, gpointer userData);
|
EVENT void menuVectorEditDelete(GtkWidget *object, gpointer userData);
|
||||||
|
@ -126,7 +125,6 @@ EVENT void menuVectorHelpVector(GtkWidget *object, gpointer userData);
|
||||||
static void releasePointList(VectorDataT *self);
|
static void releasePointList(VectorDataT *self);
|
||||||
static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self);
|
static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self);
|
||||||
EVENT void scaleVectorTraceImageValueChanged(GtkWidget *object, gpointer userData);
|
EVENT void scaleVectorTraceImageValueChanged(GtkWidget *object, gpointer userData);
|
||||||
static void setDirty(VectorDataT *self, gboolean dirty);
|
|
||||||
static void sortCoordinates(int *x1, int *y1, int *x2, int *y2);
|
static void sortCoordinates(int *x1, int *y1, int *x2, int *y2);
|
||||||
static void status(VectorDataT *self, char *message);
|
static void status(VectorDataT *self, char *message);
|
||||||
EVENT void toolBoxClicked(GtkToolButton *object, gpointer userData);
|
EVENT void toolBoxClicked(GtkToolButton *object, gpointer userData);
|
||||||
|
@ -425,7 +423,7 @@ EVENT void editorVectorNotify(GtkWidget *sciWidget, gint ctrlID, struct SCNotifi
|
||||||
// Release bytecode.
|
// Release bytecode.
|
||||||
DEL(byteCode.bytes);
|
DEL(byteCode.bytes);
|
||||||
// Mark text dirty. SCN_SAVEPOINTLEFT isn't being reliable.
|
// Mark text dirty. SCN_SAVEPOINTLEFT isn't being reliable.
|
||||||
setDirty(self, TRUE);
|
utilSetDirty((WindowDataT *)self, TRUE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -450,7 +448,7 @@ EVENT void fileVectorTraceImageFileSet(GtkWidget *object, gpointer userData) {
|
||||||
|
|
||||||
status(self, "Trace image loaded.");
|
status(self, "Trace image loaded.");
|
||||||
|
|
||||||
setDirty(self, TRUE);
|
utilSetDirty((WindowDataT *)self, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -606,6 +604,50 @@ static void loadTraceImage(VectorDataT *self, char *filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void loadVectorImage(VectorDataT *self) {
|
||||||
|
FILE *in = NULL;
|
||||||
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
size_t count = 0;
|
||||||
|
|
||||||
|
in = fopen(self->windowData.filename, "rt");
|
||||||
|
if (in != NULL) {
|
||||||
|
self->buffer[0] = 0;
|
||||||
|
while (getline(&line, &len, in) != -1) {
|
||||||
|
switch (count) {
|
||||||
|
case 0: // Version Number
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: // Trace image name
|
||||||
|
line[strlen(line) - 1] = 0;
|
||||||
|
if (utilFileExists(line)) {
|
||||||
|
loadTraceImage(self, line);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // Separator line
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: // Code for editor
|
||||||
|
utilEnsureBufferSize((unsigned char **)&self->buffer, &self->bufferLength, strlen(self->buffer) + strlen(line));
|
||||||
|
strcat(self->buffer, line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
fclose(in);
|
||||||
|
DEL(line);
|
||||||
|
SSM(SCI_ADDTEXT, strlen(self->buffer), (sptr_t)self->buffer);
|
||||||
|
//SSM(SCI_CONVERTEOLS, SC_EOL_CR, 0);
|
||||||
|
status(self, "Image loaded.");
|
||||||
|
utilSetDirty((WindowDataT *)self, FALSE); // Do again - loading text marks us dirty.
|
||||||
|
} else {
|
||||||
|
//***TODO*** Something bad happened.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EVENT void menuVectorEditCopy(GtkWidget *object, gpointer userData) {
|
EVENT void menuVectorEditCopy(GtkWidget *object, gpointer userData) {
|
||||||
VectorDataT *self = (VectorDataT *)userData;
|
VectorDataT *self = (VectorDataT *)userData;
|
||||||
|
|
||||||
|
@ -680,84 +722,22 @@ EVENT void menuVectorFileNew(GtkWidget *object, gpointer userData) {
|
||||||
gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(self->fileVectorTraceImage));
|
gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(self->fileVectorTraceImage));
|
||||||
}
|
}
|
||||||
// Clear any filename.
|
// Clear any filename.
|
||||||
DEL(self->filename);
|
DEL(self->windowData.filename);
|
||||||
// Refresh widget.
|
// Refresh widget.
|
||||||
gtk_widget_queue_draw(self->drawVectorImage);
|
gtk_widget_queue_draw(self->drawVectorImage);
|
||||||
// Mark clean.
|
// Mark clean.
|
||||||
setDirty(self, FALSE);
|
utilSetDirty((WindowDataT *)self, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EVENT void menuVectorFileOpen(GtkWidget *object, gpointer userData) {
|
EVENT void menuVectorFileOpen(GtkWidget *object, gpointer userData) {
|
||||||
VectorDataT *self = (VectorDataT *)userData;
|
VectorDataT *self = (VectorDataT *)userData;
|
||||||
GtkWidget *dialog;
|
|
||||||
GtkFileFilter *filter;
|
|
||||||
FILE *in;
|
|
||||||
char *line = NULL;
|
|
||||||
size_t len = 0;
|
|
||||||
size_t count = 0;
|
|
||||||
|
|
||||||
if (self->windowData.isDirty) {
|
(void)object;
|
||||||
if (!utilQuestionDialog(self->windowData.window, "Open", "You have unsaved changes. Open different file?")) {
|
|
||||||
return;
|
if (utilFileOpen((WindowDataT *)userData, "*.vic", "Image")) {
|
||||||
}
|
loadVectorImage(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog = gtk_file_chooser_dialog_new("Open",
|
|
||||||
GTK_WINDOW(self->windowData.window),
|
|
||||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
|
||||||
"_Cancel", GTK_RESPONSE_CANCEL,
|
|
||||||
"_Open", GTK_RESPONSE_ACCEPT,
|
|
||||||
NULL);
|
|
||||||
filter = gtk_file_filter_new();
|
|
||||||
gtk_file_filter_add_pattern(filter, "*.vic");
|
|
||||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
|
|
||||||
|
|
||||||
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
|
||||||
// Use our New code to reset the editor state before we load.
|
|
||||||
setDirty(self, FALSE);
|
|
||||||
menuVectorFileNew(object, userData);
|
|
||||||
|
|
||||||
DEL(self->filename);
|
|
||||||
self->filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
|
||||||
|
|
||||||
in = fopen(self->filename, "rt");
|
|
||||||
if (in != NULL) {
|
|
||||||
self->buffer[0] = 0;
|
|
||||||
while (getline(&line, &len, in) != -1) {
|
|
||||||
switch (count) {
|
|
||||||
case 0: // Version Number
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: // Trace image name
|
|
||||||
line[strlen(line) - 1] = 0;
|
|
||||||
if (utilFileExists(line)) {
|
|
||||||
loadTraceImage(self, line);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2: // Separator line
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: // Code for editor
|
|
||||||
utilEnsureBufferSize((unsigned char **)&self->buffer, &self->bufferLength, strlen(self->buffer) + strlen(line));
|
|
||||||
strcat(self->buffer, line);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
fclose(in);
|
|
||||||
DEL(line);
|
|
||||||
SSM(SCI_ADDTEXT, strlen(self->buffer), (sptr_t)self->buffer);
|
|
||||||
//SSM(SCI_CONVERTEOLS, SC_EOL_CR, 0);
|
|
||||||
status(self, "Image loaded.");
|
|
||||||
setDirty(self, FALSE); // Do again - loading text marks us dirty.
|
|
||||||
} else {
|
|
||||||
//***TODO*** Something bad happened.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_widget_destroy(dialog);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -771,7 +751,7 @@ EVENT void menuVectorFileSave(GtkWidget *object, gpointer userData) {
|
||||||
if (self->windowData.isDirty == TRUE) {
|
if (self->windowData.isDirty == TRUE) {
|
||||||
|
|
||||||
// Do we have a filename? If not, kick 'em to SaveAs.
|
// Do we have a filename? If not, kick 'em to SaveAs.
|
||||||
if (self->filename == NULL) {
|
if (self->windowData.filename == NULL) {
|
||||||
menuVectorFileSaveAs(object, userData);
|
menuVectorFileSaveAs(object, userData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -786,7 +766,7 @@ EVENT void menuVectorFileSave(GtkWidget *object, gpointer userData) {
|
||||||
// Fetch code.
|
// Fetch code.
|
||||||
SSM(SCI_GETTEXT, length, (sptr_t)code);
|
SSM(SCI_GETTEXT, length, (sptr_t)code);
|
||||||
|
|
||||||
out = fopen(self->filename, "wt");
|
out = fopen(self->windowData.filename, "wt");
|
||||||
if (out != NULL) {
|
if (out != NULL) {
|
||||||
// Save!
|
// Save!
|
||||||
fprintf(out, "%s\n", VICTOR_VERSION);
|
fprintf(out, "%s\n", VICTOR_VERSION);
|
||||||
|
@ -796,7 +776,7 @@ EVENT void menuVectorFileSave(GtkWidget *object, gpointer userData) {
|
||||||
fclose(out);
|
fclose(out);
|
||||||
status(self, "Saved.");
|
status(self, "Saved.");
|
||||||
// We're clean now.
|
// We're clean now.
|
||||||
setDirty(self, FALSE);
|
utilSetDirty((WindowDataT *)self, FALSE);
|
||||||
} else {
|
} else {
|
||||||
//***TODO*** Something bad happened.
|
//***TODO*** Something bad happened.
|
||||||
}
|
}
|
||||||
|
@ -821,8 +801,8 @@ EVENT void menuVectorFileSaveAs(GtkWidget *object, gpointer userData) {
|
||||||
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
|
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
|
||||||
|
|
||||||
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||||
DEL(self->filename);
|
DEL(self->windowData.filename);
|
||||||
self->filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
self->windowData.filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||||
menuVectorFileSave(object, self);
|
menuVectorFileSave(object, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1200,28 +1180,6 @@ EVENT void scaleVectorTraceImageValueChanged(GtkWidget *object, gpointer userDat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void setDirty(VectorDataT *self, gboolean dirty) {
|
|
||||||
char *title;
|
|
||||||
|
|
||||||
self->windowData.isDirty = dirty;
|
|
||||||
if (dirty) {
|
|
||||||
if (self->filename) {
|
|
||||||
title = utilCreateString("%s - %s *", self->title, self->filename);
|
|
||||||
} else {
|
|
||||||
title = utilCreateString("%s - (no name) *", self->title);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (self->filename) {
|
|
||||||
title = utilCreateString("%s - %s", self->title, self->filename);
|
|
||||||
} else {
|
|
||||||
title = utilCreateString("%s", self->title);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gtk_window_set_title(GTK_WINDOW(self->windowData.window), title);
|
|
||||||
DEL(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void sortCoordinates(int *x1, int *y1, int *x2, int *y2) {
|
static void sortCoordinates(int *x1, int *y1, int *x2, int *y2) {
|
||||||
int temp;
|
int temp;
|
||||||
|
|
||||||
|
@ -1430,7 +1388,7 @@ EVENT gboolean winVectorClose(GtkWidget *object, gpointer userData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void winVectorCreate(void) {
|
void winVectorCreate(char *filename) {
|
||||||
VectorDataT *self;
|
VectorDataT *self;
|
||||||
char *widgetNames[] = {
|
char *widgetNames[] = {
|
||||||
"winVector",
|
"winVector",
|
||||||
|
@ -1464,9 +1422,6 @@ void winVectorCreate(void) {
|
||||||
widgets[4] = &self->statusBar;
|
widgets[4] = &self->statusBar;
|
||||||
utilGetWidgetsFromMemory("/com/kangaroopunch/joeydev/Vector.glade", widgetNames, widgets, self);
|
utilGetWidgetsFromMemory("/com/kangaroopunch/joeydev/Vector.glade", widgetNames, widgets, self);
|
||||||
|
|
||||||
// Grab title.
|
|
||||||
self->title = strdup(gtk_window_get_title(GTK_WINDOW(self->windowData.window)));
|
|
||||||
|
|
||||||
// Get status bar context ID.
|
// Get status bar context ID.
|
||||||
self->statusBarId = gtk_statusbar_get_context_id(GTK_STATUSBAR(self->statusBar), "JoeyDev");
|
self->statusBarId = gtk_statusbar_get_context_id(GTK_STATUSBAR(self->statusBar), "JoeyDev");
|
||||||
|
|
||||||
|
@ -1569,6 +1524,11 @@ void winVectorCreate(void) {
|
||||||
gtk_widget_show_all(self->windowData.window);
|
gtk_widget_show_all(self->windowData.window);
|
||||||
|
|
||||||
status(self, "Welcome to the Victor Vector Editor!");
|
status(self, "Welcome to the Victor Vector Editor!");
|
||||||
|
|
||||||
|
if (filename != NULL) {
|
||||||
|
self->windowData.filename = strdup(filename);
|
||||||
|
loadVectorImage(self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1586,8 +1546,6 @@ static void winVectorDelete(gpointer userData) {
|
||||||
cairo_surface_destroy(self->target);
|
cairo_surface_destroy(self->target);
|
||||||
if (self->trace != NULL) cairo_surface_destroy(self->trace);
|
if (self->trace != NULL) cairo_surface_destroy(self->trace);
|
||||||
releasePointList(self);
|
releasePointList(self);
|
||||||
DEL(self->filename);
|
|
||||||
DEL(self->title);
|
|
||||||
DEL(self->tracename);
|
DEL(self->tracename);
|
||||||
DEL(self->buffer);
|
DEL(self->buffer);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue