From cf2edb5145da6ce06c7154b55a7262e3d8eb4268 Mon Sep 17 00:00:00 2001 From: Daniel Collin Date: Mon, 31 Dec 2012 01:03:39 +0100 Subject: [PATCH] WIP on Bookmark support --- ogl_editor/src/Commands.c | 60 +++++++++++++++--- ogl_editor/src/Commands.h | 2 +- ogl_editor/src/Editor.c | 25 +++++--- ogl_editor/src/TrackData.c | 121 +++++++++++++++++++++++++++++++++++++ ogl_editor/src/TrackData.h | 10 +++ ogl_editor/src/TrackView.c | 37 ++++++++++-- ogl_editor/src/macosx/RocketView.m | 2 +- 7 files changed, 231 insertions(+), 26 deletions(-) diff --git a/ogl_editor/src/Commands.c b/ogl_editor/src/Commands.c index cb2c000..23cf3b1 100644 --- a/ogl_editor/src/Commands.c +++ b/ogl_editor/src/Commands.c @@ -3,6 +3,8 @@ #include "Types.h" #include "../../sync/sync.h" #include "../../sync/track.h" +#include +#include /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -46,7 +48,7 @@ struct MultiCommandData CommandList list; }; -static struct MultiCommandData* s_multiCommand; +static struct MultiCommandData* s_multiCommand = 0; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -60,31 +62,38 @@ void Commands_init(struct sync_track** syncTracks, struct TrackData* trackData) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static int countEntriesInList(CommandList* list) +{ + Command* command; + int count = 0; + + for (command = list->first; command; command = command->next) + count++; + + return count; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + static void execCommand(Command* command) { // set if we have multi command recording enabled) if (s_multiCommand) { + printf("cmd add to multicommand %p\n", command); CommandList_addEntry(&s_multiCommand->list, command); } else { + printf("cmd add to undoStack %p\n", command); CommandList_addEntry(&s_undoStack, command); + printf("undo stack size %d\n", countEntriesInList(&s_undoStack)); command->exec(command->userData); } CommandList_clear(&s_redoStack); } - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void Commands_beginMulti() -{ - s_multiCommand = malloc(sizeof(struct MultiCommandData)); - memset(s_multiCommand, 0, sizeof(struct MultiCommandData)); -} - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static void execMultiCommand(void* userData) @@ -109,19 +118,32 @@ static void undoMultiCommand(void* userData) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Commands_beginMulti(const char* name) +{ + s_multiCommand = malloc(sizeof(struct MultiCommandData)); + memset(s_multiCommand, 0, sizeof(struct MultiCommandData)); + printf("multi_cmd: %s start %p\n", name, s_multiCommand); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Commands_endMulti() { Command* command; + // Check if any command was added during multi command if (CommandList_isEmpty(&s_multiCommand->list)) { + printf("multi_cmd: end (nothing to add)\n"); free(s_multiCommand); s_multiCommand = 0; return; } + printf("multi_cmd: end %p\n", s_multiCommand); + command = malloc(sizeof(Command)); memset(command, 0, sizeof(Command)); @@ -154,6 +176,8 @@ static void execDeleteKey(void* userData) data->oldKey = t->keys[idx]; sync_del_key(t, data->row); + printf("del_cmd exec: %d %d\n", data->track, data->row); + RemoteConnection_sendDeleteKeyCommand(t->name, data->row); } @@ -165,6 +189,8 @@ static void undoDeleteKey(void* userData) struct sync_track* t = s_syncTracks[data->track]; sync_set_key(t, &data->oldKey); + printf("del_cmd undo: %d %d\n", data->track, data->oldKey.row); + RemoteConnection_sendSetKeyCommand(t->name, &data->oldKey); } @@ -188,6 +214,8 @@ void Commands_deleteKey(int track, int row) data->track = track; data->row = row; + printf("del_cmd add: %p %d %d\n", command, track, row); + execCommand(command); } @@ -306,12 +334,21 @@ void Commands_undo() { Command* command; + printf("calling undo\n"); + if (CommandList_isEmpty(&s_undoStack)) + { + printf("Thinks undo stack is empty.\n"); return; + } + + printf("undo stack size before pop %d\n", countEntriesInList(&s_undoStack)); command = s_undoStack.last; CommandList_pop(&s_undoStack); + printf("undo stack size after pop %d\n", countEntriesInList(&s_undoStack)); + command->prev = 0; command->next = 0; @@ -332,6 +369,9 @@ void Commands_redo() command = s_redoStack.last; CommandList_pop(&s_redoStack); + command->prev = 0; + command->next = 0; + CommandList_addEntry(&s_undoStack, command); command->exec(command->userData); diff --git a/ogl_editor/src/Commands.h b/ogl_editor/src/Commands.h index 23e1d5e..1973e64 100644 --- a/ogl_editor/src/Commands.h +++ b/ogl_editor/src/Commands.h @@ -22,7 +22,7 @@ void Commands_deleteKey(int track, int row); void Commands_addOrUpdateKey(int track, struct track_key* key); void Commands_toogleBookmark(int track, int row); void Commands_updateKey(int track, struct track_key* key); -void Commands_beginMulti(); // Used (for example) when changing many value at the same time +void Commands_beginMulti(const char* name); // Used (for example) when changing many value at the same time void Commands_endMulti(); #endif diff --git a/ogl_editor/src/Editor.c b/ogl_editor/src/Editor.c index eb65422..a646b3d 100644 --- a/ogl_editor/src/Editor.c +++ b/ogl_editor/src/Editor.c @@ -491,7 +491,7 @@ static void deleteArea(int rowPos, int track, int bufferWidth, int bufferHeight) const int track_count = getTrackCount(); struct sync_track** tracks = getTracks(); - Commands_beginMulti(); + Commands_beginMulti("deleteArea"); for (i = 0; i < bufferWidth; ++i) { @@ -522,7 +522,7 @@ static void biasSelection(float value, int selectLeft, int selectRight, int sele int track, row; struct sync_track** tracks = getTracks(); - Commands_beginMulti(); + Commands_beginMulti("biasSelection"); for (track = selectLeft; track <= selectRight; ++track) { @@ -671,7 +671,7 @@ bool Editor_keyDown(int key, int keyCode, int modifiers) row += modifiers & EMGUI_KEY_ALT ? 8 : 1; if ((modifiers & EMGUI_KEY_COMMAND) || row > trackData->endRow) - row = trackData->endRow; + row = TrackData_getNextBookmark(trackData, row); viewInfo->rowPos = row; @@ -720,7 +720,7 @@ bool Editor_keyDown(int key, int keyCode, int modifiers) row -= modifiers & EMGUI_KEY_ALT ? 8 : 1; if ((modifiers & EMGUI_KEY_COMMAND) || row < trackData->startRow) - row = trackData->startRow; + row = TrackData_getPrevBookmark(trackData, row); viewInfo->rowPos = row; @@ -912,7 +912,16 @@ bool Editor_keyDown(int key, int keyCode, int modifiers) else Commands_undo(); - handled_key = true; + Editor_update(); + + return true; + } + + if (key == 'b' || key == 'B') + { + TrackData_toogleBookmark(trackData, row_pos); + Editor_update(); + return true; } // Handle paste of data @@ -932,7 +941,7 @@ bool Editor_keyDown(int key, int keyCode, int modifiers) deleteArea(row_pos, active_track, buffer_width, buffer_height); - Commands_beginMulti(); + Commands_beginMulti("pasteArea"); for (i = 0; i < buffer_size; ++i) { @@ -1035,9 +1044,7 @@ bool Editor_keyDown(int key, int keyCode, int modifiers) key.value = sync_get_val(t, row_pos); key.type = t->keys[emaxi(idx - 1, 0)].type; - sync_set_key(t, &key); - - RemoteConnection_sendSetKeyCommand(t->name, &key); + Commands_addOrUpdateKey(active_track, &key); } handled_key = true; diff --git a/ogl_editor/src/TrackData.c b/ogl_editor/src/TrackData.c index 27a9e88..e33ed19 100644 --- a/ogl_editor/src/TrackData.c +++ b/ogl_editor/src/TrackData.c @@ -155,3 +155,124 @@ void TrackData_setActiveTrack(TrackData* trackData, int track) trackData->activeTrack = track; } +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +bool TrackData_hasBookmark(TrackData* trackData, int row) +{ + int i, count = trackData->bookmarkCount; + int* bookmarks = trackData->bookmarks; + + if (!bookmarks) + return false; + + for (i = 0; i < count; ++i) + { + if (bookmarks[i] == row) + return true; + } + + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +int compare(const void* a, const void* b) +{ + return *(int*)a - *(int*)b; +} + +static void sortArray(int* bookmarks, int count) +{ + qsort(bookmarks, count, sizeof(int), compare); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void TrackData_toogleBookmark(TrackData* trackData, int row) +{ + int i, count = trackData->bookmarkCount; + int* bookmarks = trackData->bookmarks; + + if (!bookmarks) + { + bookmarks = trackData->bookmarks = malloc(sizeof(int)); + *bookmarks = row; + trackData->bookmarkCount++; + return; + } + + for (i = 0; i < count; ++i) + { + if (bookmarks[i] == row) + { + bookmarks[i] = 0; + sortArray(bookmarks, count); + return; + } + } + + // look for empty slot + + for (i = 0; i < count; ++i) + { + if (bookmarks[i] == 0) + { + bookmarks[i] = row; + sortArray(bookmarks, count); + return; + } + } + + // no slot found so we will resize the array and add the bookmark at the end + + bookmarks = trackData->bookmarks = realloc(bookmarks, sizeof(int) * (count + 1)); + bookmarks[count] = row; + sortArray(bookmarks, count + 1); + + trackData->bookmarkCount = count + 1; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +int TrackData_getNextBookmark(TrackData* trackData, int row) +{ + int i, count = trackData->bookmarkCount; + int* bookmarks = trackData->bookmarks; + + if (!bookmarks) + return trackData->endRow; + + for (i = 0; i < count - 1; ++i) + { + const int v0 = bookmarks[i + 0]; + const int v1 = bookmarks[i + 1]; + + if (row >= v0 && row < v1) + return v1; + } + + return trackData->endRow; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +int TrackData_getPrevBookmark(TrackData* trackData, int row) +{ + int i, count = trackData->bookmarkCount - 1; + int* bookmarks = trackData->bookmarks; + + if (!bookmarks) + return trackData->startRow; + + for (i = count; i > 0; --i) + { + const int v0 = bookmarks[i]; + + if (v0 < row) + return v0; + } + + return trackData->startRow; +} + + diff --git a/ogl_editor/src/TrackData.h b/ogl_editor/src/TrackData.h index 405c293..3e3c193 100644 --- a/ogl_editor/src/TrackData.h +++ b/ogl_editor/src/TrackData.h @@ -8,6 +8,7 @@ enum { EDITOR_MAX_TRACKS = 16 * 1024, + EDITOR_MAX_BOOKMARKS = 32 * 1024, }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -64,6 +65,8 @@ typedef struct TrackData struct sync_data syncData; Track tracks[EDITOR_MAX_TRACKS]; Group groups[EDITOR_MAX_TRACKS]; + int* bookmarks; + int bookmarkCount; int groupCount; int activeTrack; int lastColor; @@ -74,6 +77,13 @@ typedef struct TrackData } TrackData; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +bool TrackData_hasBookmark(TrackData* trackData, int row); +void TrackData_toogleBookmark(TrackData* trackData, int row); +int TrackData_getNextBookmark(TrackData* trackData, int row); +int TrackData_getPrevBookmark(TrackData* trackData, int row); + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Will get the get the track if it exists else create it int TrackData_createGetTrack(TrackData* trackData, const char* name); diff --git a/ogl_editor/src/TrackView.c b/ogl_editor/src/TrackView.c index 5befe29..6d69bb7 100644 --- a/ogl_editor/src/TrackView.c +++ b/ogl_editor/src/TrackView.c @@ -35,6 +35,7 @@ const uint32_t active_text_color = EMGUI_COLOR32(0xff, 0xff, 0xff, 0xff); const uint32_t inactive_text_color = EMGUI_COLOR32(0x5f, 0x5f, 0x5f, 0xff); const uint32_t border_color = EMGUI_COLOR32(40, 40, 40, 255); const uint32_t selection_color = EMGUI_COLOR32(0x5f, 0x5f, 0x5f, 0x4f); +const uint32_t bookmark_color = EMGUI_COLOR32(0x3f, 0x2f, 0xaf, 0x7f); static bool s_needsUpdate = false; @@ -75,7 +76,7 @@ static void printRowNumbers(int x, int y, int rowCount, int rowOffset, int rowSp if (rowOffset < 0) { y += rowSpacing * -rowOffset; - rowOffset = 0; + rowOffset = 0; } for (i = 0; i < rowCount; ++i) @@ -99,6 +100,33 @@ static void printRowNumbers(int x, int y, int rowCount, int rowOffset, int rowSp /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static void drawBookmarks(TrackData* trackData, int x, int y, int rowCount, int rowOffset, int width, int endY) +{ + int i; + + if (rowOffset < 0) + { + y += 8 * -rowOffset; + rowOffset = 0; + } + + for (i = 0; i < rowCount; ++i) + { + if (rowOffset != 0) + { + if (TrackData_hasBookmark(trackData, rowOffset)) + Emgui_fill(bookmark_color, x, y, width, 8); + } + + y += 8; rowOffset++; + + if (y > endY) + break; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + static bool drawColorButton(uint32_t color, int x, int y, int size) { const uint32_t colorFade = Emgui_color32(32, 32, 32, 255); @@ -410,10 +438,6 @@ static int renderGroup(Group* group, Track* startTrack, int posX, int* trackOffs size = getGroupSize(info.viewInfo, group, startTrackIndex); - printf("size %d\n", size); - - // TODO: Draw the group name and such here - renderGroupHeader(group, posX, oldY, size, info.viewInfo->windowSizeX); info.startPos += 5; @@ -600,6 +624,9 @@ bool TrackView_render(TrackViewInfo* viewInfo, TrackData* trackData) Emgui_fill(Emgui_color32(127, 127, 127, 56), 0, mid_screen_y + adjust_top_size, viewInfo->windowSizeX, font_size + 1); + Emgui_setLayer(1); + drawBookmarks(trackData, 2, adjust_top_size, end_row, y_pos_row, viewInfo->windowSizeX, y_end_border); + Emgui_setLayer(0); return s_needsUpdate; diff --git a/ogl_editor/src/macosx/RocketView.m b/ogl_editor/src/macosx/RocketView.m index 28416e5..6649cf9 100644 --- a/ogl_editor/src/macosx/RocketView.m +++ b/ogl_editor/src/macosx/RocketView.m @@ -179,7 +179,7 @@ static int getModifierFlags(int flags) float y = (float)[theEvent deltaY]; int flags = getModifierFlags([theEvent modifierFlags]); - printf("%f %f %d\n", x, y, flags); + //printf("%f %f %d\n", x, y, flags); Editor_scroll(-x, -y, flags); }