From 111e717b1593f28f34c61de98e0571b372a7b549 Mon Sep 17 00:00:00 2001 From: camh Date: Tue, 25 Jan 2022 23:54:08 -0800 Subject: [PATCH] big update: fix final message update bugs, fix about screen. only small TODO items, code cleanup, and testing on physical mac (once i finish recapping the analog board on my mac classic) remaining! --- CMakeLists.txt | 2 + JS/index.js | 175 +++++---- Makefile | 55 --- NuklearQuickDraw.project | 349 ------------------ NuklearQuickDraw.workspace | 11 - coprocessorjs.c | 4 +- mac_main.c | 58 +-- mac_main.r | 14 +- nuklear.h | 711 ++++--------------------------------- nuklear_app.c | 257 ++++++++++---- nuklear_quickdraw.h | 38 +- 11 files changed, 412 insertions(+), 1262 deletions(-) delete mode 100644 Makefile delete mode 100644 NuklearQuickDraw.project delete mode 100644 NuklearQuickDraw.workspace diff --git a/CMakeLists.txt b/CMakeLists.txt index 866ce5e..d9bae24 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,8 @@ cmake_minimum_required(VERSION 2.8) +set (CMAKE_C_FLAGS "-Ofast -Wuninitialized -Wmaybe-uninitialized -mcpu=68000 -mtune=68000 -m68000 -Wall") + add_application(MessagesForMacintosh SerialHelper.c coprocessorjs.c diff --git a/JS/index.js b/JS/index.js index e55849a..822408e 100644 --- a/JS/index.js +++ b/JS/index.js @@ -6,6 +6,7 @@ const gql = require('graphql-tag') // TEST_MODE can be turned on or off to prevent communications with the Apollo iMessage Server running on your modern Mac const TEST_MODE = false +const DEBUG = false const defaultOptions = { watchQuery: { @@ -155,6 +156,7 @@ const widthFor12ptFont = [ const MAX_WIDTH = 304 const SPACE_WIDTH = widthFor12ptFont[32] let canStart = false +let hasNewMessages = false const getNextWordLength = (word) => { @@ -350,7 +352,7 @@ let storedArgsAndResults = { // classic Macintosh end class iMessageGraphClientClass { - async getMessages (chatId, page) { + async getMessages (chatId, page, fromInterval) { storedArgsAndResults.getMessages.args = { chatId, @@ -362,7 +364,10 @@ class iMessageGraphClientClass { return splitMessages(TEST_MESSAGES) } - console.log(`get messages for chat ID: ${chatId}`) + if (DEBUG) { + + console.log(`get messages for chat ID: ${chatId}`) + } let result @@ -378,30 +383,45 @@ class iMessageGraphClientClass { }) } catch (error) { - console.log(`error with apollo query`) + console.log(`getMessages: error with apollo query`) console.log(error) - result = { - data: { - } - } + return } let messages = result.data.getMessages + let currentLastMessageOutput = `${lastMessageOutput}` + storedArgsAndResults.getMessages.output = splitMessages(messages) - } - async hasNewMessagesInChat (chatId) { + if (!hasNewMessages && fromInterval) { - storedArgsAndResults.hasNewMessagesInChat.args = { - chatId + hasNewMessages = currentLastMessageOutput !== storedArgsAndResults.getMessages.output + + if (hasNewMessages) { + + console.log(`got new message. previous message was:`) + console.log(currentLastMessageOutput) + console.log(`new message set is:`) + console.log(storedArgsAndResults.getMessages.output) + } } - let currentLastMessageOutput = `${lastMessageOutput}` - let messageOutput = await this.getMessages(chatId, 0) + return + } - storedArgsAndResults.hasNewMessagesInChat.output = (currentLastMessageOutput !== messageOutput).toString() + async hasNewMessagesInChat () { + + if (!hasNewMessages) { + + return `false` + } else { + + hasNewMessages = false + } + + return `true` } async sendMessage (chatId, message) { @@ -416,7 +436,9 @@ class iMessageGraphClientClass { let result try { - + + message = message.replaceAll('"', '') + result = await client.query({ query: gql`query sendMessage { sendMessage(chatId: "${chatId}", message: "${message}") { @@ -427,13 +449,10 @@ class iMessageGraphClientClass { }) } catch (error) { - console.log(`error with apollo query`) + console.log(`sendMessage: error with apollo query`) console.log(error) - result = { - data: { - } - } + return } let messages = result.data.sendMessage @@ -443,7 +462,11 @@ class iMessageGraphClientClass { async getChats () { - console.log(`getChats`) + + if (DEBUG) { + + console.log(`getChats`) + } if (TEST_MODE) { @@ -464,27 +487,31 @@ class iMessageGraphClientClass { }) } catch (error) { - console.log(`error with apollo query`) + console.log(`getChats: error with apollo query`) console.log(error) - result = { - data: { - } - } + return } let chats = result.data.getChats - console.log(`getChats complete`) - storedArgsAndResults.getChats.output = parseChatsToFriendlyNameString(chats) - console.log(storedArgsAndResults.getChats.output) + if (DEBUG) { + + console.log(`getChats complete`) + console.log(storedArgsAndResults.getChats.output) + } + + return } async getChatCounts () { - console.log(`getChatCounts`) + if (DEBUG) { + + console.log(`getChatCounts`) + } if (TEST_MODE) { @@ -505,29 +532,24 @@ class iMessageGraphClientClass { }) } catch (error) { - console.log(`error with apollo query`) + console.log(`getChatCounts: error with apollo query`) console.log(error) - result = { - data: { - } - } + return } let chats = result.data.getChatCounts - console.log(`got chat counts`) - if (!chats) { - return `` + return } let friendlyNameStrings = `` if (chats.length === 0) { - return `` + return } for (let chat of chats) { @@ -537,9 +559,16 @@ class iMessageGraphClientClass { // remove trailing comma friendlyNameStrings = friendlyNameStrings.substring(1, friendlyNameStrings.length) - - console.log(friendlyNameStrings) + storedArgsAndResults.getChatCounts.output = friendlyNameStrings + + if (DEBUG) { + + console.log(`got chat counts`) + console.log(friendlyNameStrings) + } + + return } setIPAddress (IPAddress) { @@ -588,32 +617,45 @@ class iMessageClient { // kick off an update interval setInterval(async () => { - console.log(`run interval`) + let intervalDate = new Date().toISOString() + + console.log(`${intervalDate}: run interval`) if (!canStart) { - console.log(`can't start yet`) + console.log(`${intervalDate}: can't start yet`) return } + + // if (DEBUG) { + + console.log(`${intervalDate}: running...`) + // } + + try { - console.log(`running...`) - - if (Object.keys(storedArgsAndResults.getMessages.args).length > 0) { - - await iMessageGraphClient.getMessages(storedArgsAndResults.getMessages.args.chatId, storedArgsAndResults.getMessages.args.page) - } + if (Object.keys(storedArgsAndResults.getMessages.args).length > 0) { + + console.log(`${intervalDate}: interval: get messages for ${storedArgsAndResults.getMessages.args.chatId}`) + await iMessageGraphClient.getMessages(storedArgsAndResults.getMessages.args.chatId, storedArgsAndResults.getMessages.args.page, true) + } - if (Object.keys(storedArgsAndResults.hasNewMessagesInChat.args).length > 0) { - - await iMessageGraphClient.hasNewMessagesInChat(storedArgsAndResults.hasNewMessagesInChat.chatId) + console.log(`${intervalDate}: interval: getchats`) + await iMessageGraphClient.getChats() + console.log(`${intervalDate}: interval: getchatcounts`) + await iMessageGraphClient.getChatCounts() + } catch (error) { + + console.log(`${intervalDate}: caught error when running interval`) + console.log(error) } - await iMessageGraphClient.getChats() - await iMessageGraphClient.getChatCounts() - - console.log(`complete!`) - }, 2000) + // if (DEBUG) { + + console.log(`${intervalDate}: complete!`) + // } + }, 3000) } async getMessages (chatId, page) { @@ -622,9 +664,12 @@ class iMessageClient { if (storedArgsAndResults.getMessages.args.chatId !== chatId || storedArgsAndResults.getMessages.args.page !== page) { - await iMessageGraphClient.getMessages(chatId, page) + await iMessageGraphClient.getMessages(chatId, page, false) } + console.log(`iMessageClient.getMessages, return:`) + console.log(storedArgsAndResults.getMessages.output) + return storedArgsAndResults.getMessages.output } @@ -632,12 +677,12 @@ class iMessageClient { console.log(`iMessageClient.hasNewMessagesInChat`) - if (storedArgsAndResults.hasNewMessagesInChat.args.chatId !== chatId) { + let returnValue = await iMessageGraphClient.hasNewMessagesInChat(chatId) - await iMessageGraphClient.hasNewMessagesInChat(chatId) - } + console.log(`iMessageClient.hasNewMessagesInChat, return:`) + console.log(returnValue) - return storedArgsAndResults.hasNewMessagesInChat.output + return returnValue } async sendMessage (chatId, message) { @@ -656,12 +701,16 @@ class iMessageClient { await iMessageGraphClient.getChats() } + console.log(`iMessageClient.getChats, return:`) + console.log(storedArgsAndResults.getChats.output) + return storedArgsAndResults.getChats.output } getChatCounts () { - console.log(`iMessageClient.getChatCounts`) + console.log(`iMessageClient.getChatCounts, prestored return:`) + console.log(storedArgsAndResults.getChatCounts.output) return storedArgsAndResults.getChatCounts.output } diff --git a/Makefile b/Makefile deleted file mode 100644 index 05d6a9f..0000000 --- a/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -# path to RETRO68 -RETRO68=../../../Retro68-build/toolchain - -PREFIX=$(RETRO68)/m68k-unknown-elf -CC=$(RETRO68)/bin/m68k-unknown-elf-gcc -CXX=$(RETRO68)/bin/m68k-unknown-elf-g++ -REZ=$(RETRO68)/bin/Rez - -BUILDFLAGS=-Ofast -ffloat-store -funsafe-math-optimizations -fsingle-precision-constant -mcpu=68000 -mtune=68000 -m68000 -msoft-float -malign-int -LDFLAGS=-lRetroConsole $(BUILDFLAGS) -RINCLUDES=$(PREFIX)/RIncludes -REZFLAGS=-I$(RINCLUDES) - -# all resource file help is from https://github.com/clehner/Browsy/blob/master/Makefile -RSRC_HEX=$(wildcard rsrc/*/*.hex) -RSRC_TXT=$(wildcard rsrc/*/*.txt) -RSRC_JS=$(wildcard rsrc/*/*.js) -RSRC_JSON=$(wildcard rsrc/*/*.json) -RSRC_DAT=$(RSRC_HEX:.hex=.dat) $(RSRC_TXT:.txt=.dat) $(RSRC_JS:.js=.dat) $(RSRC_JSON:.json=.dat) - -NuklearQuickDraw.bin NuklearQuickDraw.APPL NuklearQuickDraw.dsk: NuklearQuickDraw.flt rsrc-args compile_js - $(REZ) $(REZFLAGS) \ - -DFLT_FILE_NAME="\"NuklearQuickDraw.flt\"" "$(RINCLUDES)/Retro68APPL.r" \ - -t "APPL" \ - $(BUILDFLAGS) -o NuklearQuickDraw.bin --cc NuklearQuickDraw.APPL --cc NuklearQuickDraw.dsk -C WWW6 $(shell cat rsrc-args) - -NuklearQuickDraw.flt: hello.o - $(CXX) $< -o $@ $(LDFLAGS) # C++ used for linking because RetroConsole needs it - -.PHONY: clean -clean: - rm -f NuklearQuickDraw.bin NuklearQuickDraw.APPL NuklearQuickDraw.dsk NuklearQuickDraw.flt NuklearQuickDraw.flt.gdb hello.o rsrc/*/*.dat rsrc-args - -compile_js: - ./compile_js.sh - -rsrc: $(RSRC_DAT) rsrc-args - -rsrc/%.dat: rsrc/%.hex - $(QUIET_RSRC)$(FROM_HEX) $< > $@ - -rsrc/TEXT/%.dat: rsrc/TEXT/%.txt - $(QUIET_RSRC)tr '\n' '\r' < $< > $@ - -rsrc/JS/%.dat: rsrc/TEXT/%.txt - $(QUIET_RSRC)tr '\n' '\r' < $< > $@ - -rsrc-args: $(RSRC_DAT) - @cd rsrc && for code in $$(ls); do \ - echo -n "-t $$code "; \ - cd "$$code" && for file in *.dat; do \ - echo -n "-r $${file%.dat} rsrc/$$code/$$file "; \ - done; \ - cd ..; \ - done > ../$@ diff --git a/NuklearQuickDraw.project b/NuklearQuickDraw.project deleted file mode 100644 index 6aa4fe9..0000000 --- a/NuklearQuickDraw.project +++ /dev/null @@ -1,349 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ./clean.sh - ./build.sh NuklearQuickDraw - - - - - /home/camh/Documents/Retro68kApps - - - - - - - - - - /home/camh/Documents/Retro68/Retro68/CIncludes/ -/home/camh/Documents/Retro68/Retro68/RIncludes/ - - - - - - - - - - - - - - - - - - - - - - - - - - ./clean.sh - ./build.sh NuklearQuickDraw - - - - - /home/camh/Documents/Retro68kApps - - - - - - - - - - /home/camh/Documents/Retro68/Retro68/CIncludes/ -/home/camh/Documents/Retro68/Retro68/RIncludes/ - - - - - - - - - - - - - - - - - - - - - - - - - - ./clean.sh - ./build.sh NuklearQuickDraw - - - - - /home/camh/Documents/Retro68kApps - - - - - - - - - - /home/camh/Documents/Retro68/Retro68/CIncludes/ -/home/camh/Documents/Retro68/Retro68/RIncludes/ - - - - - - - - - - - - - - - - - - - - - - - - - - ./clean.sh - ./build.sh NuklearQuickDraw - - - - - /home/camh/Documents/Retro68kApps/ - - - - - - - - - - /home/camh/Documents/Retro68/Retro68/CIncludes/ -/home/camh/Documents/Retro68/Retro68/RIncludes/ - - - - - - - - - - - - - - - - - - - - - - - - - - ./clean.sh - ./build.sh NuklearQuickDraw - - - - - /home/camh/Documents/Retro68kApps - - - - - - - - - - /home/camh/Documents/Retro68/Retro68/CIncludes/ -/home/camh/Documents/Retro68/Retro68/RIncludes/ - - - - - - - - - - - - - - - - - - - - - - - - - - ./clean.sh - ./build.sh NuklearQuickDraw - - - - - /home/camh/Documents/Retro68kApps - - - - - - - - - - /home/camh/Documents/Retro68/Retro68/CIncludes/ -/home/camh/Documents/Retro68/Retro68/RIncludes/ - - - - - - - - - - - - - - - - - - - - - - - - - - ./clean.sh - ./build.sh NuklearQuickDraw - - - - - /home/camh/Documents/Retro68kApps - - - - - - - - - - /home/camh/Documents/Retro68/Retro68/CIncludes/ -/home/camh/Documents/Retro68/Retro68/RIncludes/ - - - - diff --git a/NuklearQuickDraw.workspace b/NuklearQuickDraw.workspace deleted file mode 100644 index 5300396..0000000 --- a/NuklearQuickDraw.workspace +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/coprocessorjs.c b/coprocessorjs.c index f0c0839..f3c4593 100644 --- a/coprocessorjs.c +++ b/coprocessorjs.c @@ -12,9 +12,9 @@ IOParam outgoingSerialPortReference; IOParam incomingSerialPortReference; const bool PRINT_ERRORS = false; const bool DEBUGGING = false; -const int RECEIVE_WINDOW_SIZE = 102400; // receive in up to 100kb chunks? +const int RECEIVE_WINDOW_SIZE = 32767; // receive in up to 100kb chunks? const int MAX_RECEIVE_SIZE = RECEIVE_WINDOW_SIZE; // not sure if these ever need to be different -char GlobalSerialInputBuffer[102400]; // make this match MAX_RECEIVE_SIZE +char GlobalSerialInputBuffer[32767]; // make this match MAX_RECEIVE_SIZE char application_id[255]; int call_counter = 0; diff --git a/mac_main.c b/mac_main.c index 58b1496..e96c13e 100644 --- a/mac_main.c +++ b/mac_main.c @@ -19,9 +19,11 @@ #include #include #include +#include #include #include "mac_main.h" +// #define MAC_APP_DEBUGGING //#define PROFILING 1 #ifdef PROFILING @@ -107,7 +109,6 @@ Boolean gHasWaitNextEvent; /* set up by Initialize */ the program can check it to find out if it is currently in the background. */ Boolean gInBackground; /* maintained by Initialize and DoEvent */ -// #define MAC_APP_DEBUGGING /* The following globals are the state of the window. If we supported more than one window, they would be attatched to each document, rather than globals. */ @@ -142,9 +143,8 @@ void AlertUser( void ); // this function, EventLoop, and DoEvent contain all of the business logic necessary // for our application to run -#pragma segment Main -void main() -{ +int main() +{ Initialize(); /* initialize the program */ UnloadSeg((Ptr) Initialize); /* note that Initialize must not be in Main! */ @@ -158,27 +158,24 @@ void main() // we could build a nuklear window for selection char programResult[MAX_RECEIVE_SIZE]; - sendProgramToCoprocessor(OUTPUT_JS, programResult); + sendProgramToCoprocessor((char *)OUTPUT_JS, programResult); writeSerialPortDebug(boutRefNum, "coprocessor loaded"); coprocessorLoaded = 1; EventLoop(ctx); /* call the main event loop */ + + return 0; } Boolean gotKeyboardEvent = false; int gotKeyboardEventTime = 0; -#pragma segment Main void EventLoop(struct nk_context *ctx) { - RgnHandle cursorRgn; Boolean gotEvent; - Boolean hasNextEvent; EventRecord event; - EventRecord nextEventRecord; Point mouse; - cursorRgn = NewRgn(); int lastMouseHPos = 0; int lastMouseVPos = 0; @@ -314,7 +311,7 @@ void EventLoop(struct nk_context *ctx) SystemTask(); // only re-render if there is an event, prevents screen flickering, speeds up app - if (beganInput || firstOrMouseMove || forceRedraw) { // forceRedraw is from nuklear_app + if (beganInput || firstOrMouseMove || forceRedraw) { #ifdef PROFILING PROFILE_START("nk_input_end"); @@ -344,6 +341,9 @@ void EventLoop(struct nk_context *ctx) #ifdef MAC_APP_DEBUGGING writeSerialPortDebug(boutRefNum, "nk_quickdraw_render"); + char x[255]; + sprintf(x, "why? beganInput: %d, firstOrMouseMove: %d, forceRedraw: %d", beganInput, firstOrMouseMove, forceRedraw); + writeSerialPortDebug(boutRefNum, x); #endif nk_quickdraw_render(FrontWindow(), ctx); @@ -377,11 +377,9 @@ void EventLoop(struct nk_context *ctx) /* Do the right thing for an event. Determine what kind of event it is, and call the appropriate routines. */ -#pragma segment Main void DoEvent(EventRecord *event, struct nk_context *ctx) { short part; - short err; WindowPtr window; Boolean hit; char key; @@ -495,7 +493,6 @@ void DoEvent(EventRecord *event, struct nk_context *ctx) { #endif if ( HiWord(event->message) != noErr ) { SetPt(&aPoint, kDILeft, kDITop); - err = DIBadMount(aPoint, event->message); } break; @@ -527,7 +524,6 @@ void DoEvent(EventRecord *event, struct nk_context *ctx) { coordinates is to call GetMouse and LocalToGlobal, but that requires being sure that thePort is set to a valid port. */ -#pragma segment Main void GetGlobalMouse(mouse) Point *mouse; { @@ -545,7 +541,6 @@ void GetGlobalMouse(mouse) will handle situations where calculations for drawing or drawing itself is very time-consuming. */ -#pragma segment Main void DoUpdate(window) WindowPtr window; { @@ -561,7 +556,6 @@ void DoUpdate(window) deactivate events is sufficient. Other applications may have TextEdit records, controls, lists, etc., to activate/deactivate. */ -#pragma segment Main void DoActivate(window, becomingActive) WindowPtr window; Boolean becomingActive; @@ -579,8 +573,6 @@ void DoActivate(window, becomingActive) machines, but color on color machines. At this point, the windowÕs visRgn is set to allow drawing only where it needs to be done. */ -static Rect okayButtonBounds; - /* Enable and disable menus based on the current state. The user can only select enabled menu items. We set up all the menu items before calling MenuSelect or MenuKey, since these are the only times that @@ -591,7 +583,6 @@ static Rect okayButtonBounds; the application. Other application designs may take a different approach that is just as valid. */ -#pragma segment Main void AdjustMenus() { WindowPtr window; @@ -636,16 +627,15 @@ void AdjustMenus() It is good to have both the result of MenuSelect and MenuKey go to one routine like this to keep everything organized. */ -#pragma segment Main void DoMenuCommand(menuResult) long menuResult; { short menuID; /* the resource ID of the selected menu */ short menuItem; /* the item number of the selected menu */ short itemHit; - Str255 daName; - short daRefNum; - Boolean handledByDA; + // Str255 daName; + // short daRefNum; + // Boolean handledByDA; menuID = HiWord(menuResult); /* use macros for efficiency to... */ menuItem = LoWord(menuResult); /* get menu item number and menu number */ @@ -677,7 +667,7 @@ void DoMenuCommand(menuResult) } break; case mEdit: /* call SystemEdit for DA editing & MultiFinder */ - handledByDA = SystemEdit(menuItem-1); /* since we donÕt do any Editing */ + // handledByDA = SystemEdit(menuItem-1); /* since we donÕt do any Editing */ break; case mLight: // note this was co-opted to send new chats instead of the demo functionality. do the @@ -691,9 +681,9 @@ void DoMenuCommand(menuResult) break; } - char x[255]; - sprintf(x, "MENU %d", menuItem); - writeSerialPortDebug(boutRefNum, x); + // char x[255]; + // sprintf(x, "MENU %d", menuItem); + // writeSerialPortDebug(boutRefNum, x); break; case mHelp: @@ -760,7 +750,6 @@ void DoMenuCommand(menuResult) the user quits an application, but then cancels the save of a document associated with a window. */ -#pragma segment Main Boolean DoCloseWindow(window) WindowPtr window; { @@ -778,7 +767,6 @@ Boolean DoCloseWindow(window) /* 1.01 - If we find out that a cancel has occurred, we won't exit to the shell, but will return instead. */ -#pragma segment Main void Terminate() { WindowPtr aWindow; @@ -799,13 +787,10 @@ void Terminate() ExitToShell(); /* exit if no cancellation */ } /*Terminate*/ - -#pragma segment Initialize void Initialize() { Handle menuBar; WindowPtr window; - long total, contig; EventRecord event; short count; @@ -846,8 +831,6 @@ void Initialize() } /*Initialize*/ - -#pragma segment Main Boolean IsAppWindow(window) WindowPtr window; { @@ -865,7 +848,6 @@ Boolean IsAppWindow(window) /* Check to see if a window belongs to a desk accessory. */ -#pragma segment Main Boolean IsDAWindow(window) WindowPtr window; { @@ -876,8 +858,6 @@ Boolean IsDAWindow(window) return ((WindowPeek) window)->windowKind < 0; } /*IsDAWindow*/ - -#pragma segment Initialize Boolean TrapAvailable(tNumber,tType) short tNumber; TrapType tType; @@ -894,8 +874,6 @@ Boolean TrapAvailable(tNumber,tType) return NGetTrapAddress(tNumber, tType) != GetTrapAddress(_Unimplemented); } /*TrapAvailable*/ - -#pragma segment Main void AlertUser() { short itemHit; diff --git a/mac_main.r b/mac_main.r index 7350130..f3a8190 100644 --- a/mac_main.r +++ b/mac_main.r @@ -162,7 +162,7 @@ resource 'MENU' (mHelp, preload) { /* this ALRT and DITL are used as an About screen */ resource 'ALRT' (rAboutAlert, purgeable) { - {40, 20, 160, 412}, + {40, 20, 194, 412}, rAboutAlert, { /* array: 4 elements */ /* [1] */ @@ -180,31 +180,31 @@ resource 'ALRT' (rAboutAlert, purgeable) { resource 'DITL' (rAboutAlert, purgeable) { { /* array DITLarray: 5 elements */ /* [1] */ - {88, 380, 108, 260}, + {119, 8, 138, 80}, Button { enabled, "OK" }, /* [2] */ - {8, 8, 24, 214}, + {8, 8, 24, 264}, StaticText { disabled, "Messages for Macintosh" }, /* [3] */ - {32, 8, 48, 237}, + {32, 8, 48, 267}, StaticText { disabled, - "Copyright © 2021 Cameron Henlin" + "Copyright © 2021-22 Cameron Henlin" }, /* [4] */ - {56, 8, 72, 136}, + {56, 8, 72, 166}, StaticText { disabled, "cam.henlin@gmail.com" }, /* [5] */ - {80, 24, 112, 167}, + {80, 8, 112, 407}, StaticText { disabled, "https://github.com/CamHenlin/MessagesForMacintosh" diff --git a/nuklear.h b/nuklear.h index e4fa2af..7725665 100644 --- a/nuklear.h +++ b/nuklear.h @@ -1458,7 +1458,7 @@ NK_API struct nk_window *nk_window_find(struct nk_context *ctx, const char *name /// !!! WARNING /// Only call this function between calls `nk_begin_xxx` and `nk_end` /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c -/// struct nk_rect nk_window_get_bounds(const struct nk_context *ctx); +/// struct nk_rect nk_window_get_bounds(struct nk_context *ctx); /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// /// Parameter | Description @@ -1467,14 +1467,14 @@ NK_API struct nk_window *nk_window_find(struct nk_context *ctx, const char *name /// /// Returns a `nk_rect` struct with window upper left window position and size */ -NK_API struct nk_rect nk_window_get_bounds(const struct nk_context *ctx); +NK_API struct nk_rect nk_window_get_bounds(struct nk_context *ctx); /*/// #### nk_window_get_position /// Returns the position of the currently processed window. /// /// !!! WARNING /// Only call this function between calls `nk_begin_xxx` and `nk_end` /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c -/// struct nk_vec2 nk_window_get_position(const struct nk_context *ctx); +/// struct nk_vec2 nk_window_get_position(struct nk_context *ctx); /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// /// Parameter | Description @@ -1483,14 +1483,14 @@ NK_API struct nk_rect nk_window_get_bounds(const struct nk_context *ctx); /// /// Returns a `nk_vec2` struct with window upper left position */ -NK_API struct nk_vec2 nk_window_get_position(const struct nk_context *ctx); +NK_API struct nk_vec2 nk_window_get_position(struct nk_context *ctx); /*/// #### nk_window_get_size /// Returns the size with width and height of the currently processed window. /// /// !!! WARNING /// Only call this function between calls `nk_begin_xxx` and `nk_end` /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c -/// struct nk_vec2 nk_window_get_size(const struct nk_context *ctx); +/// struct nk_vec2 nk_window_get_size(struct nk_context *ctx); /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// /// Parameter | Description @@ -1499,14 +1499,14 @@ NK_API struct nk_vec2 nk_window_get_position(const struct nk_context *ctx); /// /// Returns a `nk_vec2` struct with window width and height */ -NK_API struct nk_vec2 nk_window_get_size(const struct nk_context*); +NK_API struct nk_vec2 nk_window_get_size(struct nk_context*); /*/// #### nk_window_get_width /// Returns the width of the currently processed window. /// /// !!! WARNING /// Only call this function between calls `nk_begin_xxx` and `nk_end` /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c -/// short nk_window_get_width(const struct nk_context *ctx); +/// short nk_window_get_width(struct nk_context *ctx); /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// /// Parameter | Description @@ -1515,14 +1515,14 @@ NK_API struct nk_vec2 nk_window_get_size(const struct nk_context*); /// /// Returns the current window width */ -NK_API short nk_window_get_width(const struct nk_context*); +NK_API short nk_window_get_width(struct nk_context*); /*/// #### nk_window_get_height /// Returns the height of the currently processed window. /// /// !!! WARNING /// Only call this function between calls `nk_begin_xxx` and `nk_end` /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c -/// short nk_window_get_height(const struct nk_context *ctx); +/// short nk_window_get_height(struct nk_context *ctx); /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// /// Parameter | Description @@ -1531,7 +1531,7 @@ NK_API short nk_window_get_width(const struct nk_context*); /// /// Returns the current window height */ -NK_API short nk_window_get_height(const struct nk_context*); +NK_API short nk_window_get_height(struct nk_context*); /*/// #### nk_window_get_panel /// Returns the underlying panel which contains all processing state of the current window. /// @@ -1665,7 +1665,7 @@ NK_API void nk_window_get_scroll(struct nk_context*, short *offset_x, short *off /// !!! WARNING /// Only call this function between calls `nk_begin_xxx` and `nk_end` /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c -/// nk_bool nk_window_has_focus(const struct nk_context *ctx); +/// nk_bool nk_window_has_focus(struct nk_context *ctx); /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// /// Parameter | Description @@ -1674,7 +1674,7 @@ NK_API void nk_window_get_scroll(struct nk_context*, short *offset_x, short *off /// /// Returns `false(0)` if current window is not active or `true(1)` if it is */ -NK_API nk_bool nk_window_has_focus(const struct nk_context*); +NK_API nk_bool nk_window_has_focus(struct nk_context*); /*/// #### nk_window_is_hovered /// Return if the current window is being hovered /// !!! WARNING @@ -2977,7 +2977,7 @@ enum nk_widget_states { NK_WIDGET_STATE_HOVERED = NK_WIDGET_STATE_HOVER|NK_WIDGET_STATE_MODIFIED, /* widget is being hovered */ NK_WIDGET_STATE_ACTIVE = NK_WIDGET_STATE_ACTIVED|NK_WIDGET_STATE_MODIFIED /* widget is currently activated */ }; -NK_API enum nk_widget_layout_states nk_widget(struct nk_rect*, const struct nk_context*); +NK_API enum nk_widget_layout_states nk_widget(struct nk_rect*, struct nk_context*); NK_API enum nk_widget_layout_states nk_widget_fitting(struct nk_rect*, struct nk_context*, struct nk_vec2); NK_API struct nk_rect nk_widget_bounds(struct nk_context*); NK_API struct nk_vec2 nk_widget_position(struct nk_context*); @@ -5291,22 +5291,12 @@ NK_GLOBAL const struct nk_rect nk_null_rect = {-8192, -8192, 16384, 16384}; else (*(s)) = NK_WIDGET_STATE_INACTIVE; /* math */ -NK_LIB short nk_inv_sqrt(short n); -#ifndef NK_SIN -NK_LIB short nk_sin(short x); -#endif -#ifndef NK_COS -NK_LIB short nk_cos(short x); -#endif NK_LIB short nk_round_up_pow2(short v); NK_LIB struct nk_rect nk_shrink_rect(struct nk_rect r, short amount); NK_LIB struct nk_rect nk_pad_rect(struct nk_rect r, struct nk_vec2 pad); NK_LIB void nk_unify(struct nk_rect *clip, const struct nk_rect *a, short x0, short y0, short x1, short y1); -NK_LIB short nk_pow(short x, short n); -NK_LIB short nk_ifloord(short x); NK_LIB short nk_ifloorf(short x); NK_LIB short nk_iceilf(short x); -NK_LIB short nk_log10(short n); /* util */ enum {NK_DO_NOT_STOP_ON_NEW_LINE, NK_STOP_ON_NEW_LINE}; @@ -5323,18 +5313,11 @@ NK_LIB void nk_memset(void *ptr, short c0, nk_size size); #endif NK_LIB void nk_zero(void *ptr, nk_size size); NK_LIB char *nk_itoa(char *s, long n); -NK_LIB short nk_string_int_limit(char *string, short prec); -#ifndef NK_DTOA -NK_LIB char *nk_dtoa(char *s, short n); -#endif NK_LIB short nk_text_clamp(const struct nk_user_font *font, const char *text, short text_len, short space, short *glyphs, short *text_width, nk_rune *sep_list, short sep_count); NK_LIB struct nk_vec2 nk_text_calculate_text_bounds(const struct nk_user_font *font, const char *begin, short byte_len, short row_height, const char **remaining, struct nk_vec2 *out_offset, short *glyphs, short op); #ifdef NK_INCLUDE_STANDARD_VARARGS NK_LIB short nk_strfmt(char *buf, short buf_size, const char *fmt, va_list args); #endif -#ifdef NK_INCLUDE_STANDARD_IO -NK_LIB char *nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc); -#endif /* buffer */ #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR @@ -5410,11 +5393,11 @@ NK_LIB void nk_panel_end(struct nk_context *ctx); /* layout */ NK_LIB short nk_layout_row_calculate_usable_space(struct nk_style *style, enum nk_panel_type type, short total_space, short columns); -NK_LIB void nk_panel_layout(const struct nk_context *ctx, struct nk_window *win, short height, short cols); +NK_LIB void nk_panel_layout(struct nk_context *ctx, struct nk_window *win, short height, short cols); NK_LIB void nk_row_layout(struct nk_context *ctx, enum nk_layout_format fmt, short height, short cols, short width); -NK_LIB void nk_panel_alloc_row(const struct nk_context *ctx, struct nk_window *win); -NK_LIB void nk_layout_widget_space(struct nk_rect *bounds, const struct nk_context *ctx, struct nk_window *win, short modify); -NK_LIB void nk_panel_alloc_space(struct nk_rect *bounds, const struct nk_context *ctx); +NK_LIB void nk_panel_alloc_row(struct nk_context *ctx, struct nk_window *win); +NK_LIB void nk_layout_widget_space(struct nk_rect *bounds, struct nk_context *ctx, struct nk_window *win, short modify); +NK_LIB void nk_panel_alloc_space(struct nk_rect *bounds, struct nk_context *ctx); NK_LIB void nk_layout_peek(struct nk_rect *bounds, struct nk_context *ctx); /* popup */ @@ -5577,33 +5560,6 @@ nk_stbtt_free(void *ptr, void *user_data) { found here: www.lolengine.net/wiki/oss/lolremez */ NK_LIB short -nk_inv_sqrt(short n) -{ - short x2; - union {short i; short f;} conv = {0}; - conv.f = n; - x2 = n / 2; - conv.i = 0x5f375A84 - (conv.i >> 1); - conv.f = conv.f * (1 - (x2 * conv.f * conv.f)); - return conv.f; -} -#ifndef NK_SIN -#define NK_SIN nk_sin -NK_LIB short -nk_sin(short x) -{ - return 1; -} -#endif -#ifndef NK_COS -#define NK_COS nk_cos -NK_LIB short -nk_cos(short x) -{ - return 0; -} -#endif -NK_LIB short nk_round_up_pow2(short v) { v--; @@ -5616,27 +5572,6 @@ nk_round_up_pow2(short v) return v; } NK_LIB short -nk_pow(short x, short n) -{ - /* check the sign of n */ - short r = 1; - short plus = n >= 0; - n = (plus) ? n : -n; - while (n > 0) { - if ((n & 1) == 1) - r *= x; - n /= 2; - x *= x; - } - return plus ? r : 1 / r; -} -NK_LIB short -nk_ifloord(short x) -{ - x = (x - ((x < 0) ? 1 : 0)); - return x; -} -NK_LIB short nk_ifloorf(short x) { x = (x - ((x < 0) ? 1 : 0)); @@ -5654,22 +5589,6 @@ nk_iceilf(short x) return (r > 0) ? t+1: t; } } -NK_LIB short -nk_log10(short n) -{ - short neg; - short ret; - short exp = 0; - - neg = (n < 0) ? 1 : 0; - ret = (neg) ? -n : n; - while ((ret / 10) > 0) { - ret /= 10; - exp++; - } - if (neg) exp = -exp; - return exp; -} NK_API struct nk_rect nk_get_null_rect(void) { @@ -6151,26 +6070,6 @@ nk_strmatch_fuzzy_string(char const *str, char const *pattern, short *out_score) { return nk_strmatch_fuzzy_text(str, nk_strlen(str), pattern, out_score); } -NK_LIB short -nk_string_int_limit(char *string, short prec) -{ - short dot = 0; - char *c = string; - while (*c) { - if (*c == '.') { - dot = 1; - c++; - continue; - } - if (dot == (prec+1)) { - *c = 0; - break; - } - if (dot > 0) dot++; - c++; - } - return (c - string); -} NK_INTERN void nk_strrev_ascii(char *s) { @@ -6208,443 +6107,24 @@ nk_itoa(char *s, long n) nk_strrev_ascii(s); return s; } -#ifndef NK_DTOA -#define NK_DTOA nk_dtoa -NK_LIB char* -nk_dtoa(char *s, short n) -{ - short useExp = 0; - short digit = 0, m = 0, m1 = 0; - char *c = s; - short neg = 0; - - // NK_ASSERT(s); - if (!s) return 0; - - if (n == 0) { - s[0] = '0'; s[1] = '\0'; - return s; - } - - neg = (n < 0); - if (neg) n = -n; - - /* calculate magnitude */ - m = nk_log10(n); - useExp = (m >= 14 || (neg && m >= 9) || m <= -9); - if (neg) *(c++) = '-'; - - /* set up for scientific notation */ - if (useExp) { - if (m < 0) - m -= 1; - n = n / nk_pow(10, m); - m1 = m; - m = 0; - } - if (m < 1) { - m = 0; - } - - /* convert the number */ - while (n > NK_INT_PRECISION || m >= 0) { - short weight = nk_pow(10, m); - if (weight > 0) { - short t = n / weight; - digit = nk_ifloord(t); - n -= (digit * weight); - *(c++) = (char)('0' + (char)digit); - } - if (m == 0 && n > 0) - *(c++) = '.'; - m--; - } - - if (useExp) { - /* convert the exponent */ - short i, j; - *(c++) = 'e'; - if (m1 > 0) { - *(c++) = '+'; - } else { - *(c++) = '-'; - m1 = -m1; - } - m = 0; - while (m1 > 0) { - *(c++) = (char)('0' + (char)(m1 % 10)); - m1 /= 10; - m++; - } - c -= m; - for (i = 0, j = m-1; i= buf_size) break; - iter++; - - /* flag arguments */ - while (*iter) { - if (*iter == '-') flag |= NK_ARG_FLAG_LEFT; - else if (*iter == '+') flag |= NK_ARG_FLAG_PLUS; - else if (*iter == ' ') flag |= NK_ARG_FLAG_SPACE; - else if (*iter == '#') flag |= NK_ARG_FLAG_NUM; - else if (*iter == '0') flag |= NK_ARG_FLAG_ZERO; - else break; - iter++; - } - - /* width argument */ - width = NK_DEFAULT; - if (*iter >= '1' && *iter <= '9') { - const char *end; - width = nk_strtoi(iter, &end); - if (end == iter) - width = -1; - else iter = end; - } else if (*iter == '*') { - width = va_arg(args, short); - iter++; - } - - /* precision argument */ - precision = NK_DEFAULT; - if (*iter == '.') { - iter++; - if (*iter == '*') { - precision = va_arg(args, short); - iter++; - } else { - const char *end; - precision = nk_strtoi(iter, &end); - if (end == iter) - precision = -1; - else iter = end; - } - } - - /* length modifier */ - if (*iter == 'h') { - if (*(iter+1) == 'h') { - arg_type = NK_ARG_TYPE_CHAR; - iter++; - } else arg_type = NK_ARG_TYPE_SHORT; - iter++; - } else if (*iter == 'l') { - arg_type = NK_ARG_TYPE_LONG; - iter++; - } else arg_type = NK_ARG_TYPE_DEFAULT; - - /* specifier */ - if (*iter == '%') { - // NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT); - // NK_ASSERT(precision == NK_DEFAULT); - // NK_ASSERT(width == NK_DEFAULT); - if (len < buf_size) - buf[len++] = '%'; - } else if (*iter == 's') { - /* string */ - const char *str = va_arg(args, const char*); - // NK_ASSERT(str != buf && "buffer and argument are not allowed to overlap!"); - // NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT); - // NK_ASSERT(precision == NK_DEFAULT); - // NK_ASSERT(width == NK_DEFAULT); - if (str == buf) return -1; - while (str && *str && len < buf_size) - buf[len++] = *str++; - } else if (*iter == 'n') { - /* current length callback */ - signed short *n = va_arg(args, short*); - // NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT); - // NK_ASSERT(precision == NK_DEFAULT); - // NK_ASSERT(width == NK_DEFAULT); - if (n) *n = len; - } else if (*iter == 'c' || *iter == 'i' || *iter == 'd') { - /* signed integer */ - long value = 0; - const char *num_iter; - short num_len, num_print, padding; - short cur_precision = NK_MAX(precision, 1); - short cur_width = NK_MAX(width, 0); - - /* retrieve correct value type */ - if (arg_type == NK_ARG_TYPE_CHAR) - value = (signed char)va_arg(args, short); - else if (arg_type == NK_ARG_TYPE_SHORT) - value = (signed short)va_arg(args, short); - else if (arg_type == NK_ARG_TYPE_LONG) - value = va_arg(args, signed long); - else if (*iter == 'c') - value = (unsigned char)va_arg(args, short); - else value = va_arg(args, signed int); - - /* convert number to string */ - nk_itoa(number_buffer, value); - num_len = nk_strlen(number_buffer); - padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0); - if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE)) - padding = NK_MAX(padding-1, 0); - - /* fill left padding up to a total of `width` characters */ - if (!(flag & NK_ARG_FLAG_LEFT)) { - while (padding-- > 0 && (len < buf_size)) { - if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT)) - buf[len++] = '0'; - else buf[len++] = ' '; - } - } - - /* copy string value representation into buffer */ - if ((flag & NK_ARG_FLAG_PLUS) && value >= 0 && len < buf_size) - buf[len++] = '+'; - else if ((flag & NK_ARG_FLAG_SPACE) && value >= 0 && len < buf_size) - buf[len++] = ' '; - - /* fill up to precision number of digits with '0' */ - num_print = NK_MAX(cur_precision, num_len); - while (precision && (num_print > num_len) && (len < buf_size)) { - buf[len++] = '0'; - num_print--; - } - - /* copy string value representation into buffer */ - num_iter = number_buffer; - while (precision && *num_iter && len < buf_size) - buf[len++] = *num_iter++; - - /* fill right padding up to width characters */ - if (flag & NK_ARG_FLAG_LEFT) { - while ((padding-- > 0) && (len < buf_size)) - buf[len++] = ' '; - } - } else if (*iter == 'o' || *iter == 'x' || *iter == 'X' || *iter == 'u') { - /* unsigned integer */ - unsigned long value = 0; - short num_len = 0, num_print, padding = 0; - short cur_precision = NK_MAX(precision, 1); - short cur_width = NK_MAX(width, 0); - unsigned short base = (*iter == 'o') ? 8: (*iter == 'u')? 10: 16; - - /* print oct/hex/dec value */ - const char *upper_output_format = "0123456789ABCDEF"; - const char *lower_output_format = "0123456789abcdef"; - const char *output_format = (*iter == 'x') ? - lower_output_format: upper_output_format; - - /* retrieve correct value type */ - if (arg_type == NK_ARG_TYPE_CHAR) - value = (unsigned char)va_arg(args, short); - else if (arg_type == NK_ARG_TYPE_SHORT) - value = (unsigned short)va_arg(args, short); - else if (arg_type == NK_ARG_TYPE_LONG) - value = va_arg(args, unsigned long); - else value = va_arg(args, unsigned int); - - do { - /* convert decimal number into hex/oct number */ - short digit = output_format[value % base]; - if (num_len < NK_MAX_NUMBER_BUFFER) - number_buffer[num_len++] = (char)digit; - value /= base; - } while (value > 0); - - num_print = NK_MAX(cur_precision, num_len); - padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0); - if (flag & NK_ARG_FLAG_NUM) - padding = NK_MAX(padding-1, 0); - - /* fill left padding up to a total of `width` characters */ - if (!(flag & NK_ARG_FLAG_LEFT)) { - while ((padding-- > 0) && (len < buf_size)) { - if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT)) - buf[len++] = '0'; - else buf[len++] = ' '; - } - } - - /* fill up to precision number of digits */ - if (num_print && (flag & NK_ARG_FLAG_NUM)) { - if ((*iter == 'o') && (len < buf_size)) { - buf[len++] = '0'; - } else if ((*iter == 'x') && ((len+1) < buf_size)) { - buf[len++] = '0'; - buf[len++] = 'x'; - } else if ((*iter == 'X') && ((len+1) < buf_size)) { - buf[len++] = '0'; - buf[len++] = 'X'; - } - } - while (precision && (num_print > num_len) && (len < buf_size)) { - buf[len++] = '0'; - num_print--; - } - - /* reverse number direction */ - while (num_len > 0) { - if (precision && (len < buf_size)) - buf[len++] = number_buffer[num_len-1]; - num_len--; - } - - /* fill right padding up to width characters */ - if (flag & NK_ARG_FLAG_LEFT) { - while ((padding-- > 0) && (len < buf_size)) - buf[len++] = ' '; - } - } else if (*iter == 'f') { - /* inting point */ - const char *num_iter; - short cur_precision = (precision < 0) ? 6: precision; - short prefix, cur_width = NK_MAX(width, 0); - short value = va_arg(args, short); - short num_len = 0, frac_len = 0, dot = 0; - short padding = 0; - - // NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT); - NK_DTOA(number_buffer, value); - num_len = nk_strlen(number_buffer); - - /* calculate padding */ - num_iter = number_buffer; - while (*num_iter && *num_iter != '.') - num_iter++; - - prefix = (*num_iter == '.')?(num_iter - number_buffer)+1:0; - padding = NK_MAX(cur_width - (prefix + NK_MIN(cur_precision, num_len - prefix)) , 0); - if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE)) - padding = NK_MAX(padding-1, 0); - - /* fill left padding up to a total of `width` characters */ - if (!(flag & NK_ARG_FLAG_LEFT)) { - while (padding-- > 0 && (len < buf_size)) { - if (flag & NK_ARG_FLAG_ZERO) - buf[len++] = '0'; - else buf[len++] = ' '; - } - } - - /* copy string value representation into buffer */ - num_iter = number_buffer; - if ((flag & NK_ARG_FLAG_PLUS) && (value >= 0) && (len < buf_size)) - buf[len++] = '+'; - else if ((flag & NK_ARG_FLAG_SPACE) && (value >= 0) && (len < buf_size)) - buf[len++] = ' '; - while (*num_iter) { - if (dot) frac_len++; - if (len < buf_size) - buf[len++] = *num_iter; - if (*num_iter == '.') dot = 1; - if (frac_len >= cur_precision) break; - num_iter++; - } - - /* fill number up to precision */ - while (frac_len < cur_precision) { - if (!dot && len < buf_size) { - buf[len++] = '.'; - dot = 1; - } - if (len < buf_size) - buf[len++] = '0'; - frac_len++; - } - - /* fill right padding up to width characters */ - if (flag & NK_ARG_FLAG_LEFT) { - while ((padding-- > 0) && (len < buf_size)) - buf[len++] = ' '; - } - } else { - /* Specifier not supported: g,G,e,E,p,z */ - // NK_ASSERT(0 && "specifier is not supported!"); - return result; - } - } - buf[(len >= buf_size)?(buf_size-1):len] = 0; - result = (len >= buf_size)?-1:len; - return result; -} -#endif -NK_LIB short -nk_strfmt(char *buf, short buf_size, const char *fmt, va_list args) -{ - short result = -1; - // NK_ASSERT(buf); - // NK_ASSERT(buf_size); - if (!buf || !buf_size || !fmt) return 0; -#ifdef NK_INCLUDE_STANDARD_IO - result = NK_VSNPRINTF(buf, (nk_size)buf_size, fmt, args); - result = (result >= buf_size) ? -1: result; - buf[buf_size-1] = 0; -#else - result = nk_vsnprintf(buf, buf_size, fmt, args); -#endif - return result; -} -#endif NK_API nk_hash nk_murmur_hash(const void * key, short len, nk_hash seed) { /* 32-Bit MurmurHash3: https://code.google.com/p/smhasher/wiki/MurmurHash3*/ #define NK_ROTL(x,r) ((x) << (r) | ((x) >> (32 - r))) - short h1 = seed; - short k1; + uint32_t h1 = seed; + uint32_t k1; const nk_byte *data = (const nk_byte*)key; const nk_byte *keyptr = data; nk_byte *k1ptr; - const short bsize = sizeof(k1); - const short nblocks = len/4; + const int bsize = sizeof(k1); + const int nblocks = len/4; - const short c1 = 11601; - const short c2 = 13715; + const uint32_t c1 = 0xcc9e2d51; + const uint32_t c2 = 0x1b873593; const nk_byte *tail; - short i; + int i; /* body */ if (!key) return 0; @@ -6668,8 +6148,8 @@ nk_murmur_hash(const void * key, short len, nk_hash seed) tail = (const nk_byte*)(data + nblocks*4); k1 = 0; switch (len & 3) { - case 3: k1 ^= (short)(tail[2] << 16); /* fallthrough */ - case 2: k1 ^= (short)(tail[1] << 8u); /* fallthrough */ + case 3: k1 ^= (uint32_t)(tail[2] << 16); /* fallthrough */ + case 2: k1 ^= (uint32_t)(tail[1] << 8u); /* fallthrough */ case 1: k1 ^= tail[0]; k1 *= c1; k1 = NK_ROTL(k1,15); @@ -6680,7 +6160,7 @@ nk_murmur_hash(const void * key, short len, nk_hash seed) } /* finalization */ - h1 ^= (short)len; + h1 ^= (uint32_t)len; /* fmix32 */ h1 ^= h1 >> 16; h1 *= 0x85ebca6b; @@ -6691,41 +6171,6 @@ nk_murmur_hash(const void * key, short len, nk_hash seed) #undef NK_ROTL return h1; } -#ifdef NK_INCLUDE_STANDARD_IO -NK_LIB char* -nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc) -{ - char *buf; - FILE *fd; - long ret; - - // NK_ASSERT(path); - // NK_ASSERT(siz); - // NK_ASSERT(alloc); - if (!path || !siz || !alloc) - return 0; - - fd = fopen(path, "rb"); - if (!fd) return 0; - fseek(fd, 0, SEEK_END); - ret = ftell(fd); - if (ret < 0) { - fclose(fd); - return 0; - } - *siz = (nk_size)ret; - fseek(fd, 0, SEEK_SET); - buf = (char*)alloc->alloc(alloc->userdata,0, *siz); - // NK_ASSERT(buf); - if (!buf) { - fclose(fd); - return 0; - } - *siz = (nk_size)fread(buf, 1,*siz, fd); - fclose(fd); - return buf; -} -#endif NK_LIB short nk_text_clamp(const struct nk_user_font *font, const char *text, short text_len, short space, short *glyphs, short *text_width, @@ -6846,28 +6291,6 @@ NK_GLOBAL const nk_byte nk_utfmask[NK_UTF_SIZE+1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF NK_GLOBAL const short nk_utfmin[NK_UTF_SIZE+1] = {0, 0, 0x80, 0x800, 0x1000}; NK_GLOBAL const short nk_utfmax[NK_UTF_SIZE+1] = {0x10FF, 0x7F, 0x7FF, 0xFFFF, 0x10FF}; -NK_INTERN short -nk_utf_validate(nk_rune *u, short i) -{ - // NK_ASSERT(u); - if (!u) return 0; - if (!NK_BETWEEN(*u, nk_utfmin[i], nk_utfmax[i]) || - NK_BETWEEN(*u, 0xD800, 0xDFFF)) - *u = NK_UTF_INVALID; - for (i = 1; *u > nk_utfmax[i]; ++i); - return i; -} -NK_INTERN nk_rune -nk_utf_decode_byte(char c, short *i) -{ - // NK_ASSERT(i); - if (!i) return 0; - for(*i = 0; *i < NK_LEN(nk_utfmask); ++(*i)) { - if (((nk_byte)c & nk_utfmask[*i]) == nk_utfbyte[*i]) - return (nk_byte)(c & ~nk_utfmask[*i]); - } - return 0; -} NK_API short nk_utf_decode(const char *c, nk_rune *u, short clen) { @@ -6910,11 +6333,6 @@ nk_utf_decode(const char *c, nk_rune *u, short clen) // writeSerialPortDebug(boutRefNum, x); // return len; } -NK_INTERN char -nk_utf_encode_byte(nk_rune u, short i) -{ - return (char)((nk_utfbyte[i]) | ((nk_byte)u & ~nk_utfmask[i])); -} NK_API short nk_utf_encode(nk_rune u, char *c, short clen) { @@ -8839,7 +8257,7 @@ nk_style_from_table(struct nk_context *ctx, const int *table) edit->scrollbar = style->scrollv; edit->padding = nk_vec2(4,4); edit->row_padding = 2; - edit->cursor_size = 4; + edit->cursor_size = 1; edit->border = 1; edit->rounding = 0; @@ -9488,15 +8906,15 @@ nk_build(struct nk_context *ctx) if (!ctx->style.cursor_active) ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_ARROW]; if (ctx->style.cursor_active && !ctx->input.mouse.grabbed && ctx->style.cursor_visible) { - struct nk_rect mouse_bounds; - const struct nk_cursor *cursor = ctx->style.cursor_active; + // struct nk_rect mouse_bounds; + // const struct nk_cursor *cursor = ctx->style.cursor_active; nk_command_buffer_init(&ctx->overlay, &ctx->memory, NK_CLIPPING_OFF); nk_start_buffer(ctx, &ctx->overlay); - mouse_bounds.x = ctx->input.mouse.pos.x - cursor->offset.x; - mouse_bounds.y = ctx->input.mouse.pos.y - cursor->offset.y; - mouse_bounds.w = cursor->size.x; - mouse_bounds.h = cursor->size.y; + // mouse_bounds.x = ctx->input.mouse.pos.x - cursor->offset.x; + // mouse_bounds.y = ctx->input.mouse.pos.y - cursor->offset.y; + // mouse_bounds.w = cursor->size.x; + // mouse_bounds.h = cursor->size.y; // //nk_draw_image(&ctx->overlay, mouse_bounds, &cursor->img, nk_white); nk_finish_buffer(ctx, &ctx->overlay); @@ -10727,7 +10145,7 @@ nk_end(struct nk_context *ctx) ctx->current = 0; } NK_API struct nk_rect -nk_window_get_bounds(const struct nk_context *ctx) +nk_window_get_bounds(struct nk_context *ctx) { // NK_ASSERT(ctx); // NK_ASSERT(ctx->current); @@ -10735,7 +10153,7 @@ nk_window_get_bounds(const struct nk_context *ctx) return ctx->current->bounds; } NK_API struct nk_vec2 -nk_window_get_position(const struct nk_context *ctx) +nk_window_get_position(struct nk_context *ctx) { // NK_ASSERT(ctx); // NK_ASSERT(ctx->current); @@ -10743,7 +10161,7 @@ nk_window_get_position(const struct nk_context *ctx) return nk_vec2(ctx->current->bounds.x, ctx->current->bounds.y); } NK_API struct nk_vec2 -nk_window_get_size(const struct nk_context *ctx) +nk_window_get_size(struct nk_context *ctx) { // NK_ASSERT(ctx); // NK_ASSERT(ctx->current); @@ -10751,7 +10169,7 @@ nk_window_get_size(const struct nk_context *ctx) return nk_vec2(ctx->current->bounds.w, ctx->current->bounds.h); } NK_API short -nk_window_get_width(const struct nk_context *ctx) +nk_window_get_width(struct nk_context *ctx) { // NK_ASSERT(ctx); // NK_ASSERT(ctx->current); @@ -10759,7 +10177,7 @@ nk_window_get_width(const struct nk_context *ctx) return ctx->current->bounds.w; } NK_API short -nk_window_get_height(const struct nk_context *ctx) +nk_window_get_height(struct nk_context *ctx) { // NK_ASSERT(ctx); // NK_ASSERT(ctx->current); @@ -10834,7 +10252,7 @@ nk_window_get_scroll(struct nk_context *ctx, short *offset_x, short *offset_y) *offset_y = win->scrollbar.y; } NK_API nk_bool -nk_window_has_focus(const struct nk_context *ctx) +nk_window_has_focus(struct nk_context *ctx) { // NK_ASSERT(ctx); // NK_ASSERT(ctx->current); @@ -11926,7 +11344,7 @@ nk_layout_row_calculate_usable_space(struct nk_style *style, enum nk_panel_type return panel_space; } NK_LIB void -nk_panel_layout(const struct nk_context *ctx, struct nk_window *win, short height, short cols) +nk_panel_layout(struct nk_context *ctx, struct nk_window *win, short height, short cols) { struct nk_panel *layout; struct nk_style *style; @@ -12431,7 +11849,7 @@ nk_layout_space_rect_to_local(struct nk_context *ctx, struct nk_rect ret) return ret; } NK_LIB void -nk_panel_alloc_row(const struct nk_context *ctx, struct nk_window *win) +nk_panel_alloc_row(struct nk_context *ctx, struct nk_window *win) { struct nk_panel *layout = win->layout; struct nk_vec2 spacing = ctx->style.window.spacing; @@ -12439,7 +11857,7 @@ nk_panel_alloc_row(const struct nk_context *ctx, struct nk_window *win) nk_panel_layout(ctx, win, row_height, layout->row.columns); } NK_LIB void -nk_layout_widget_space(struct nk_rect *bounds, const struct nk_context *ctx, +nk_layout_widget_space(struct nk_rect *bounds, struct nk_context *ctx, struct nk_window *win, short modify) { struct nk_panel *layout; @@ -12560,6 +11978,8 @@ nk_layout_widget_space(struct nk_rect *bounds, const struct nk_context *ctx, item_spacing = layout->row.index * spacing.x; if (modify) layout->row.item_offset += w; } break; + case NK_LAYOUT_COUNT: { + } break; #undef NK_FRAC // default: NK_ASSERT(0); break; }; @@ -12574,7 +11994,7 @@ nk_layout_widget_space(struct nk_rect *bounds, const struct nk_context *ctx, bounds->x -= *layout->offset_x; } NK_LIB void -nk_panel_alloc_space(struct nk_rect *bounds, const struct nk_context *ctx) +nk_panel_alloc_space(struct nk_rect *bounds, struct nk_context *ctx) { struct nk_window *win; struct nk_panel *layout; @@ -13392,7 +12812,7 @@ nk_widget_has_mouse_click_down(struct nk_context *ctx, enum nk_buttons btn, nk_b return nk_input_has_mouse_click_down_in_rect(&ctx->input, btn, bounds, down); } NK_API enum nk_widget_layout_states -nk_widget(struct nk_rect *bounds, const struct nk_context *ctx) +nk_widget(struct nk_rect *bounds, struct nk_context *ctx) { struct nk_rect c, v; struct nk_window *win; @@ -13902,7 +13322,7 @@ nk_image_is_subimage(const struct nk_image* img) NK_API void nk_image(struct nk_context *ctx, struct nk_image img) { - struct nk_window *win; + // struct nk_window *win; struct nk_rect bounds; // NK_ASSERT(ctx); @@ -13910,14 +13330,14 @@ nk_image(struct nk_context *ctx, struct nk_image img) // NK_ASSERT(ctx->current->layout); if (!ctx || !ctx->current || !ctx->current->layout) return; - win = ctx->current; + // win = ctx->current; if (!nk_widget(&bounds, ctx)) return; // nk_draw_image(&win->buffer, bounds, &img, nk_white); } NK_API void nk_image_color(struct nk_context *ctx, struct nk_image img, int col) { - struct nk_window *win; + // struct nk_window *win; struct nk_rect bounds; // NK_ASSERT(ctx); @@ -13925,7 +13345,7 @@ nk_image_color(struct nk_context *ctx, struct nk_image img, int col) // NK_ASSERT(ctx->current->layout); if (!ctx || !ctx->current || !ctx->current->layout) return; - win = ctx->current; + // win = ctx->current; if (!nk_widget(&bounds, ctx)) return; // nk_draw_image(&win->buffer, bounds, &img, col); } @@ -15833,7 +15253,7 @@ nk_do_scrollbarv(nk_flags *state, short scroll_step; short scroll_offset; - short scroll_off; + // short scroll_off; // NK_ASSERT(out); // NK_ASSERT(style); @@ -15876,7 +15296,7 @@ nk_do_scrollbarv(nk_flags *state, /* calculate scrollbar constants */ scroll_step = NK_MIN(step, scroll.h); scroll_offset = NK_CLAMP(0, offset, target - scroll.h); - scroll_off = scroll_offset / target; // 84 / 574 * 190 = 27... -> target is total height of all content, offset is how far we've scrolled into the content + // scroll_off = scroll_offset / target; // 84 / 574 * 190 = 27... -> target is total height of all content, offset is how far we've scrolled into the content // 27 = (84/574) * 190 // target / scroll.h = scroll_offset / 574/190 = @@ -17561,7 +16981,7 @@ nk_do_edit(nk_flags *state, struct nk_command_buffer *out, whiteTextarea.x = clip.x + line_width - edit->scrollbar.x; whiteTextarea.y = clip.y; whiteTextarea.h = clip.h; - whiteTextarea.w = line_width - (line_width - edit->scrollbar.x); + whiteTextarea.w = line_width - (line_width - edit->scrollbar.x) - 1; nk_fill_rect(out, whiteTextarea, style->rounding, qd.black, false); /* select correct colors to draw */ @@ -17647,8 +17067,7 @@ nk_do_edit(nk_flags *state, struct nk_command_buffer *out, /* cursor */ if (edit->select_start == edit->select_end) { - if (edit->cursor >= nk_str_len(&edit->string) || - (cursor_ptr && *cursor_ptr == '\n')) { + if (edit->cursor >= nk_str_len(&edit->string) || (cursor_ptr && *cursor_ptr == '\n')) { /* draw cursor at end of line */ struct nk_rect cursor; cursor.w = style->cursor_size; @@ -17662,7 +17081,7 @@ nk_do_edit(nk_flags *state, struct nk_command_buffer *out, whiteTextarea2.x = cursor.x + cursor.w; whiteTextarea2.y = cursor.y - 2; whiteTextarea2.h = cursor.h + 6; - whiteTextarea2.w = cursor.w * 2; + whiteTextarea2.w = 9; //cursor.w * 2; // this was previously used when cursor.w = 4, doesn't work well at = 1 nk_fill_rect(out, whiteTextarea2, 0, qd.black, false); } else { /* draw cursor inside text */ @@ -17684,12 +17103,12 @@ nk_do_edit(nk_flags *state, struct nk_command_buffer *out, txt.text = cursor_text_color; nk_fill_rect(out, label, 0, cursor_color, true); - struct nk_rect whiteTextarea2; - whiteTextarea2.x = label.x + label.w; - whiteTextarea2.y = label.y - 2; - whiteTextarea2.h = label.h + 6; - whiteTextarea2.w = label.w; - nk_fill_rect(out, whiteTextarea2, 0, qd.black, false); + // struct nk_rect whiteTextarea2; + // whiteTextarea2.x = label.x + label.w; + // whiteTextarea2.y = label.y - 2; + // whiteTextarea2.h = label.h + 6; + // whiteTextarea2.w = label.w; + // nk_fill_rect(out, whiteTextarea2, 0, qd.black, false); nk_widget_text(out, label, cursor_ptr, glyph_len, &txt, NK_TEXT_LEFT, font, false); } @@ -18285,7 +17704,7 @@ nk_chart_begin_colored(struct nk_context *ctx, enum nk_chart_type type, struct nk_style *config; struct nk_style_chart *style; - Pattern *background; + // Pattern *background; struct nk_rect bounds = {0, 0, 0, 0}; // NK_ASSERT(ctx); @@ -18324,7 +17743,7 @@ nk_chart_begin_colored(struct nk_context *ctx, enum nk_chart_type type, slot->range = slot->max - slot->min;} /* draw chart background */ - background = &style->background; + // background = &style->background; nk_stroke_rect(&win->buffer, bounds, style->rounding, 1, style->border_color); //nk_fill_rect(&win->buffer, bounds, style->rounding, style->border_color, true); nk_fill_rect(&win->buffer, nk_shrink_rect(bounds, style->border), style->rounding, style->background, true); return 1; @@ -18437,7 +17856,7 @@ nk_chart_push_line(struct nk_context *ctx, struct nk_window *win, return ret; } NK_INTERN nk_flags -nk_chart_push_column(const struct nk_context *ctx, struct nk_window *win, +nk_chart_push_column(struct nk_context *ctx, struct nk_window *win, struct nk_chart *chart, short value, short slot) { struct nk_command_buffer *out = &win->buffer; diff --git a/nuklear_app.c b/nuklear_app.c index c1e5297..6b912c2 100644 --- a/nuklear_app.c +++ b/nuklear_app.c @@ -1,5 +1,7 @@ // TODO: // - test, bug fixes, write blog posts +// - bug: messages start over-writing eachother in main chat -- need a way to force clear it +// - bug: delete key deletes infinitely #define WINDOW_WIDTH 510 #define WINDOW_HEIGHT 302 @@ -17,10 +19,71 @@ // #define MESSAGES_FOR_MACINTOSH_DEBUGGING +// based on https://github.com/jwerle/strsplit.c -- cleaned up and modified to use strtokm rather than strtok +int strsplit (const char *str, char *parts[], const char *delimiter) { + + char *pch; + int i = 0; + char *copy = NULL; + char *tmp = NULL; + + copy = strdup(str); + + if (! copy) { + + goto bad; + } + + pch = strtokm(copy, delimiter); + + tmp = strdup(pch); + + if (!tmp) { + + goto bad; + } + + parts[i++] = tmp; + + while (pch) { + + pch = strtokm(NULL, delimiter); + + if (NULL == pch) { + + break; + } + + tmp = strdup(pch); + + if (! tmp) { + + goto bad; + } + + parts[i++] = tmp; + } + + free(copy); + + return i; + + bad: + + free(copy); + + for (int j = 0; j < i; j++) { + + free(parts[j]); + } + + return -1; +} + void aFailed(char *file, int line) { MoveTo(10, 10); - char *textoutput; + char textoutput[255]; sprintf(textoutput, "%s:%d", file, line); writeSerialPortDebug(boutRefNum, "assertion failure"); writeSerialPortDebug(boutRefNum, textoutput); @@ -28,16 +91,7 @@ void aFailed(char *file, int line) { while (true) {} } -#define NK_ASSERT(e) \ - if (!(e)) \ - aFailed(__FILE__, __LINE__) - -#include -#include "nuklear.h" -#include "nuklear_quickdraw.h" -#include "coprocessorjs.h" - -#define MAX_CHAT_MESSAGES 16 +#define MAX_CHAT_MESSAGES 17 Boolean firstOrMouseMove = true; Boolean gotMouseEvent = false; @@ -46,10 +100,10 @@ char activeChatMessages[MAX_CHAT_MESSAGES][2048]; // this should match to MAX_RO char box_input_buffer[2048]; char chatFriendlyNames[16][64]; char ip_input_buffer[255]; -char jsFunctionResponse[102400]; // Matches MAX_RECEIVE_SIZE -char chatCountFunctionResponse[102400]; // Matches MAX_RECEIVE_SIZE -char tempChatCountFunctionResponse[102400]; // Matches MAX_RECEIVE_SIZE -char previousChatCountFunctionResponse[102400]; // Matches MAX_RECEIVE_SIZE +char jsFunctionResponse[32767]; // Matches MAX_RECEIVE_SIZE +char chatCountFunctionResponse[32767]; // Matches MAX_RECEIVE_SIZE +char tempChatCountFunctionResponse[32767]; // Matches MAX_RECEIVE_SIZE +char previousChatCountFunctionResponse[32767]; // Matches MAX_RECEIVE_SIZE char new_message_input_buffer[255]; int activeMessageCounter = 0; int chatFriendlyNamesCounter = 0; @@ -69,6 +123,15 @@ struct nk_rect message_input_window_size; struct nk_rect messages_window_size; struct nk_context *ctx; +#define NK_ASSERT(e) \ + if (!(e)) \ + aFailed(__FILE__, __LINE__) + +#include +#include "nuklear.h" +#include "nuklear_quickdraw.h" +#include "coprocessorjs.h" + void refreshNuklearApp(Boolean blankInput); void getMessagesFromjsFunctionResponse() { @@ -85,7 +148,7 @@ void getMessagesFromjsFunctionResponse() { // loop through the string to extract all other tokens while (token != NULL) { - sprintf(activeChatMessages[activeMessageCounter], "%s", token); + sprintf(activeChatMessages[activeMessageCounter], "%s", token); token = (char *)strtokm(NULL, "ENDLASTMESSAGE"); activeMessageCounter++; } @@ -96,11 +159,12 @@ void getMessagesFromjsFunctionResponse() { // function to send messages in chat void sendMessage() { + writeSerialPortDebug(boutRefNum, "sendMessage!"); + char output[2048]; sprintf(output, "%s&&&%.*s", activeChat, box_input_len, box_input_buffer); memset(&box_input_buffer, '\0', 2048); - sprintf(box_input_buffer, ""); box_input_len = 0; refreshNuklearApp(1); @@ -135,6 +199,8 @@ void getChats() { void sendIPAddressToCoprocessor() { + writeSerialPortDebug(boutRefNum, "sendIPAddressToCoprocessor!"); + char output[2048]; sprintf(output, "%.*s", ip_input_buffer_len, ip_input_buffer); @@ -152,7 +218,9 @@ void sendIPAddressToCoprocessor() { // figure out pagination?? button on the top that says "get previous chats"? void getMessages(char *thread, int page) { - char output[62]; + writeSerialPortDebug(boutRefNum, "getMessages!"); + + char output[68]; sprintf(output, "%s&&&%d", thread, page); // writeSerialPortDebug(boutRefNum, output); @@ -172,11 +240,9 @@ Boolean prefix(const char *pre, const char *str) { void getChatCounts() { - char output[62]; - sprintf(output, ""); - // writeSerialPortDebug(boutRefNum, output); + writeSerialPortDebug(boutRefNum, "getChatCounts!"); - callFunctionOnCoprocessor("getChatCounts", output, chatCountFunctionResponse); + callFunctionOnCoprocessor("getChatCounts", "", chatCountFunctionResponse); #ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING writeSerialPortDebug(boutRefNum, "getChatCounts"); @@ -191,27 +257,62 @@ void getChatCounts() { #endif SysBeep(1); - char *saveptr; + strcpy(tempChatCountFunctionResponse, chatCountFunctionResponse); - char *token = strtok_r(tempChatCountFunctionResponse, ",", &saveptr); + int chatCount = 0; + char *(*chats[16])[64]; + + chatCount = strsplit(tempChatCountFunctionResponse, chats, ","); + + for (int chatLoopCounter = 0; chatLoopCounter < chatCount; chatLoopCounter++) { + + #ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING + writeSerialPortDebug(boutRefNum, "DUMMY DELETE: update current chat count loop"); + writeSerialPortDebug(boutRefNum, chats[chatLoopCounter]); + #endif + } // loop through the string to extract all other tokens - while (token != NULL) { + for (int chatLoopCounter = 0; chatLoopCounter < chatCount; chatLoopCounter++) { #ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING writeSerialPortDebug(boutRefNum, "update current chat count loop"); - writeSerialPortDebug(boutRefNum, token); + writeSerialPortDebug(boutRefNum, chats[chatLoopCounter]); #endif - // should be in format NAME:::COUNT - char *saveptr2; - char *name = strtok_r(token, ":::", &saveptr2); - char *countString = strtok_r(NULL, ":::", &saveptr2); - short count = atoi(countString); + // chats[chatLoopCounter] should be in format NAME:::COUNT + + strcpy(tempChatCountFunctionResponse, chatCountFunctionResponse); + int results = 0; + char *(*chatUpdate[2])[64]; + + results = strsplit(chats[chatLoopCounter], chatUpdate, ":::"); + + if (results != 2) { + + #ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING + char x[255]; + sprintf(x, "ERROR: chat update mismatch splitting on ':::', expected 2 results, got: %d: %s -- bailing out", results, chats[chatLoopCounter]); + writeSerialPortDebug(boutRefNum, x); + + for (int errorResultCounter = 0; errorResultCounter < results; errorResultCounter++) { + + writeSerialPortDebug(boutRefNum, chatUpdate[errorResultCounter]); + + char y[255]; + sprintf(y, "%d/%d: '%s'", errorResultCounter, results, chatUpdate[errorResultCounter]); + writeSerialPortDebug(boutRefNum, y); + } + #endif + + continue; + } + + short count = atoi(chatUpdate[1]); #ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING char x[255]; - sprintf(x, "name: %s, countString: %s, count: %d", name, countString, count); + sprintf(x, "name: %s, countString: %s, count: %d", chatUpdate[0], chatUpdate[1], count); writeSerialPortDebug(boutRefNum, x); #endif @@ -220,51 +321,64 @@ void getChatCounts() { if (strstr(chatFriendlyNames[i], " new) ") != NULL) { char chatName[64]; - sprintf(chatName, "%s", chatFriendlyNames[i]); + sprintf(chatName, "%.63s", chatFriendlyNames[i]); - // we are throwing out the first token - strtok_r(chatName, " new) ", &saveptr2); + int updateResults = 0; + char *(*updatePieces[2])[64]; - char *tempChatFriendlyName = strtok_r(NULL, " new) ", &saveptr2); + updateResults = strsplit(chatName, updatePieces, " new) "); - if (prefix(tempChatFriendlyName, name)) { + if (updateResults != 2) { + + #ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING + char x[255]; + sprintf(x, "ERROR: individual chat update mismatch splitting on ' new) ', expected 2 results, got: %d: %s -- bailing out", updateResults, chatName); + writeSerialPortDebug(boutRefNum, x); + + for (int errorResultCounter = 0; errorResultCounter < updateResults; errorResultCounter++) { + + char y[255]; + sprintf(y, "%d/%d: '%s'", errorResultCounter, updateResults, updatePieces[errorResultCounter]); + writeSerialPortDebug(boutRefNum, y); + } + #endif + + continue; + } + + if (prefix(updatePieces[1], chatUpdate[0])) { #ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING writeSerialPortDebug(boutRefNum, "match1"); - writeSerialPortDebug(boutRefNum, name); + writeSerialPortDebug(boutRefNum, chatUpdate[0]); #endif - if (count == 0) { + if (count == 0 || !strcmp(activeChat, chatUpdate[0])) { - sprintf(chatFriendlyNames[i], "%s", name); + sprintf(chatFriendlyNames[i], "%s", chatUpdate[0]); } else { - sprintf(chatFriendlyNames[i], "(%d new) %s", count, name); + sprintf(chatFriendlyNames[i], "(%d new) %s", count, chatUpdate[0]); } break; } - } else { + } else if (prefix(chatFriendlyNames[i], chatUpdate[0])) { - if (prefix(chatFriendlyNames[i], name)) { + #ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING + writeSerialPortDebug(boutRefNum, "match2"); + writeSerialPortDebug(boutRefNum, chatUpdate[0]); + #endif - #ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING - writeSerialPortDebug(boutRefNum, "match2"); - writeSerialPortDebug(boutRefNum, name); - #endif + if (count == 0 || !strcmp(activeChat, chatUpdate[0])) { - if (count == 0) { + sprintf(chatFriendlyNames[i], "%s", chatUpdate[0]); + } else { - sprintf(chatFriendlyNames[i], "%s", name); - } else { - - sprintf(chatFriendlyNames[i], "(%d new) %s", count, name); - } - break; + sprintf(chatFriendlyNames[i], "(%d new) %s", count, chatUpdate[0]); } + break; } } - - token = strtok_r(NULL, ",", &saveptr); } strcpy(previousChatCountFunctionResponse, chatCountFunctionResponse); @@ -279,7 +393,9 @@ void getChatCounts() { void getHasNewMessagesInChat(char *thread) { - char output[62]; + writeSerialPortDebug(boutRefNum, "getHasNewMessagesInChat!"); + + char output[68]; sprintf(output, "%s", thread); // writeSerialPortDebug(boutRefNum, output); @@ -288,12 +404,15 @@ void getHasNewMessagesInChat(char *thread) { if (!strcmp(jsFunctionResponse, "true")) { - // writeSerialPortDebug(boutRefNum, "update current chat"); + writeSerialPortDebug(boutRefNum, "update current chat"); SysBeep(1); getMessages(thread, 0); // force redraw forceRedraw = 3; + } else { + + writeSerialPortDebug(boutRefNum, "do not update current chat"); } return; @@ -376,7 +495,7 @@ static void nuklearApp(struct nk_context *ctx) { return; } - // prompt the user for new chat + // prompt the user for new chat if (sendNewChat) { if (nk_begin_titled(ctx, "Enter New Message Recipient", "Enter New Message Recipient", nk_rect(50, WINDOW_HEIGHT / 4, WINDOW_WIDTH - 100, 140), NK_WINDOW_TITLE|NK_WINDOW_BORDER)) { @@ -423,11 +542,6 @@ static void nuklearApp(struct nk_context *ctx) { if ((chatWindowCollision || forceRedraw) && nk_begin(ctx, "Chats", chats_window_size, NK_WINDOW_BORDER|NK_WINDOW_NO_SCROLLBAR)) { - if (chatWindowCollision) { - - forceRedraw = 2; - } - nk_layout_row_begin(ctx, NK_STATIC, 25, 1); { for (int i = 0; i < chatFriendlyNamesCounter; i++) { @@ -445,7 +559,7 @@ static void nuklearApp(struct nk_context *ctx) { if (strstr(chatFriendlyNames[i], " new) ") != NULL) { char chatName[96]; - sprintf(chatName, "%s", chatFriendlyNames[i]); + sprintf(chatName, "%.63s", chatFriendlyNames[i]); #ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING writeSerialPortDebug(boutRefNum, "clicked1 chatName"); @@ -467,8 +581,8 @@ static void nuklearApp(struct nk_context *ctx) { writeSerialPortDebug(boutRefNum, name); #endif - sprintf(activeChat, "%s", name); - sprintf(chatFriendlyNames[i], "%s", name); + sprintf(activeChat, "%.63s", name); + sprintf(chatFriendlyNames[i], "%.63s", name); } else { #ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING @@ -476,7 +590,7 @@ static void nuklearApp(struct nk_context *ctx) { writeSerialPortDebug(boutRefNum, chatFriendlyNames[i]); #endif - sprintf(activeChat, "%s", chatFriendlyNames[i]); + sprintf(activeChat, "%.63s", chatFriendlyNames[i]); } getMessages(activeChat, 0); @@ -517,6 +631,8 @@ static void nuklearApp(struct nk_context *ctx) { nk_layout_row_push(ctx, 305); + // writeSerialPortDebug(boutRefNum, "activeChatMessages[i]"); + // writeSerialPortDebug(boutRefNum, activeChatMessages[i]); nk_label(ctx, activeChatMessages[i], NK_TEXT_ALIGN_LEFT); } } @@ -550,8 +666,8 @@ void refreshNuklearApp(Boolean blankInput) { struct nk_context* initializeNuklearApp() { sprintf(activeChat, "no active chat"); - memset(&chatCountFunctionResponse, '\0', 102400); - memset(&previousChatCountFunctionResponse, '\0', 102400); + memset(&chatCountFunctionResponse, '\0', 32767); + memset(&previousChatCountFunctionResponse, '\0', 32767); graphql_input_window_size = nk_rect(WINDOW_WIDTH / 2 - 118, 80, 234, 100); chats_window_size = nk_rect(0, 0, 180, WINDOW_HEIGHT); @@ -562,6 +678,7 @@ struct nk_context* initializeNuklearApp() { refreshNuklearApp(false); sprintf(ip_input_buffer, "http://"); // doesn't work due to bug, see variable definition + ip_input_buffer_len = 7; return ctx; } \ No newline at end of file diff --git a/nuklear_quickdraw.h b/nuklear_quickdraw.h index 5827c53..7581a4e 100644 --- a/nuklear_quickdraw.h +++ b/nuklear_quickdraw.h @@ -49,7 +49,7 @@ NK_API NkQuickDrawFont* nk_quickdraw_font_create_from_file(); * * =============================================================== */ -#define MAX_MEMORY_IN_KB 4 +#define MAX_MEMORY_IN_KB 6 #ifdef NK_QUICKDRAW_IMPLEMENTATION #ifndef NK_QUICKDRAW_TEXT_MAX #define NK_QUICKDRAW_TEXT_MAX 256 @@ -476,8 +476,6 @@ void updateBounds(int top, int bottom, int left, int right) { void runDrawCommand(const struct nk_command *cmd) { #endif - int color; - switch (cmd->type) { case NK_COMMAND_NOP: @@ -541,7 +539,7 @@ void updateBounds(int top, int bottom, int left, int right) { #ifdef COMMAND_CACHING - if (cmd->type == lastCmd->type && memcmp(r, lastCmd, sizeof(struct nk_command_rect)) == 0) { + if (!forceRedraw && cmd->type == lastCmd->type && memcmp(r, lastCmd, sizeof(struct nk_command_rect)) == 0) { #ifdef NK_QUICKDRAW_GRAPHICS_DEBUGGING writeSerialPortDebug(boutRefNum, "ALREADY DREW CMD nk_command_rect"); @@ -594,7 +592,7 @@ void updateBounds(int top, int bottom, int left, int right) { } #ifdef COMMAND_CACHING - if (cmd->type == lastCmd->type && memcmp(r, lastCmd, sizeof(struct nk_command_rect_filled)) == 0) { + if (!forceRedraw && cmd->type == lastCmd->type && memcmp(r, lastCmd, sizeof(struct nk_command_rect_filled)) == 0) { #ifdef NK_QUICKDRAW_GRAPHICS_DEBUGGING writeSerialPortDebug(boutRefNum, "ALREADY DREW CMD nk_command_rect_filled"); @@ -631,7 +629,7 @@ void updateBounds(int top, int bottom, int left, int right) { const struct nk_command_text *t = (const struct nk_command_text*)cmd; #ifdef COMMAND_CACHING - if (t->allowCache && cmd->type == lastCmd->type && memcmp(t, lastCmd, sizeof(struct nk_command_text)) == 0) { + if (!forceRedraw && t->allowCache && cmd->type == lastCmd->type && memcmp(t, lastCmd, sizeof(struct nk_command_text)) == 0) { #ifdef NK_QUICKDRAW_GRAPHICS_DEBUGGING char log[255]; @@ -685,7 +683,7 @@ void updateBounds(int top, int bottom, int left, int right) { #ifdef COMMAND_CACHING - if (cmd->type == lastCmd->type && memcmp(l, lastCmd, sizeof(struct nk_command_line)) == 0) { + if (!forceRedraw && cmd->type == lastCmd->type && memcmp(l, lastCmd, sizeof(struct nk_command_line)) == 0) { #ifdef NK_QUICKDRAW_GRAPHICS_DEBUGGING writeSerialPortDebug(boutRefNum, "ALREADY DREW CMD nk_command_line"); @@ -713,7 +711,7 @@ void updateBounds(int top, int bottom, int left, int right) { const struct nk_command_circle *c = (const struct nk_command_circle *)cmd; #ifdef COMMAND_CACHING - if (cmd->type == lastCmd->type && memcmp(c, lastCmd, sizeof(struct nk_command_circle)) == 0) { + if (!forceRedraw && cmd->type == lastCmd->type && memcmp(c, lastCmd, sizeof(struct nk_command_circle)) == 0) { #ifdef NK_QUICKDRAW_GRAPHICS_DEBUGGING writeSerialPortDebug(boutRefNum, "ALREADY DREW CMD nk_command_circle"); @@ -748,7 +746,7 @@ void updateBounds(int top, int bottom, int left, int right) { const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd; #ifdef COMMAND_CACHING - if (cmd->type == lastCmd->type && memcmp(c, lastCmd, sizeof(struct nk_command_circle_filled)) == 0) { + if (!forceRedraw && cmd->type == lastCmd->type && memcmp(c, lastCmd, sizeof(struct nk_command_circle_filled)) == 0) { #ifdef NK_QUICKDRAW_GRAPHICS_DEBUGGING writeSerialPortDebug(boutRefNum, "ALREADY DREW CMD nk_command_circle_filled"); @@ -787,7 +785,7 @@ void updateBounds(int top, int bottom, int left, int right) { const struct nk_command_triangle *t = (const struct nk_command_triangle*)cmd; #ifdef COMMAND_CACHING - if (cmd->type == lastCmd->type && memcmp(t, lastCmd, sizeof(struct nk_command_triangle)) == 0) { + if (!forceRedraw && cmd->type == lastCmd->type && memcmp(t, lastCmd, sizeof(struct nk_command_triangle)) == 0) { #ifdef NK_QUICKDRAW_GRAPHICS_DEBUGGING writeSerialPortDebug(boutRefNum, "ALREADY DREW CMD nk_command_triangle"); @@ -817,7 +815,7 @@ void updateBounds(int top, int bottom, int left, int right) { const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd; #ifdef COMMAND_CACHING - if (cmd->type == lastCmd->type && memcmp(t, lastCmd, sizeof(struct nk_command_triangle_filled)) == 0) { + if (!forceRedraw && cmd->type == lastCmd->type && memcmp(t, lastCmd, sizeof(struct nk_command_triangle_filled)) == 0) { #ifdef NK_QUICKDRAW_GRAPHICS_DEBUGGING writeSerialPortDebug(boutRefNum, "ALREADY DREW CMD nk_command_triangle_filled"); @@ -853,7 +851,7 @@ void updateBounds(int top, int bottom, int left, int right) { const struct nk_command_polygon *p = (const struct nk_command_polygon*)cmd; #ifdef COMMAND_CACHING - if (cmd->type == lastCmd->type && memcmp(p, lastCmd, sizeof(struct nk_command_polygon)) == 0) { + if (!forceRedraw && cmd->type == lastCmd->type && memcmp(p, lastCmd, sizeof(struct nk_command_polygon)) == 0) { #ifdef NK_QUICKDRAW_GRAPHICS_DEBUGGING writeSerialPortDebug(boutRefNum, "ALREADY DREW CMD nk_command_polygon"); @@ -893,7 +891,7 @@ void updateBounds(int top, int bottom, int left, int right) { const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled*)cmd; #ifdef COMMAND_CACHING - if (cmd->type == lastCmd->type && memcmp(p, lastCmd, sizeof(struct nk_command_polygon_filled)) == 0) { + if (!forceRedraw && cmd->type == lastCmd->type && memcmp(p, lastCmd, sizeof(struct nk_command_polygon_filled)) == 0) { #ifdef NK_QUICKDRAW_GRAPHICS_DEBUGGING writeSerialPortDebug(boutRefNum, "ALREADY DREW CMD nk_command_polygon_filled"); @@ -942,7 +940,7 @@ void updateBounds(int top, int bottom, int left, int right) { const struct nk_command_polygon *p = (const struct nk_command_polygon*)cmd; #ifdef COMMAND_CACHING - if (cmd->type == lastCmd->type && memcmp(p, lastCmd, sizeof(struct nk_command_polygon)) == 0) { + if (!forceRedraw && cmd->type == lastCmd->type && memcmp(p, lastCmd, sizeof(struct nk_command_polygon)) == 0) { #ifdef NK_QUICKDRAW_GRAPHICS_DEBUGGING writeSerialPortDebug(boutRefNum, "ALREADY DREW CMD nk_command_polygon"); @@ -1016,7 +1014,7 @@ void updateBounds(int top, int bottom, int left, int right) { writeSerialPortDebug(boutRefNum, "NK_COMMAND_IMAGE"); #endif - const struct nk_command_image *i = (const struct nk_command_image *)cmd; + // const struct nk_command_image *i = (const struct nk_command_image *)cmd; // al_draw_bitmap_region(i->img.handle.ptr, 0, 0, i->w, i->h, i->x, i->y, 0); // TODO: look up and convert al_draw_bitmap_region // TODO: consider implementing a bitmap drawing routine. we could iterate pixel by pixel and draw // here is some super naive code that could work, used for another project that i was working on with a custom format but would be @@ -1082,7 +1080,7 @@ NK_API void nk_quickdraw_render(WindowPtr window, struct nk_context *ctx) { #ifdef NK_QUICKDRAW_GRAPHICS_DEBUGGING - writeSerialPortDebug(boutRefNum, "NK_COMMAND_NOP"); + writeSerialPortDebug(boutRefNum, "NO RENDER BUFFER CHANGE, ABORT"); #endif return; @@ -1106,7 +1104,6 @@ NK_API void nk_quickdraw_render(WindowPtr window, struct nk_context *ctx) { #ifdef COMMAND_CACHING const struct nk_command *lastCmd; - nk_byte *buffer; lastCmd = nk_ptr_add_const(struct nk_command, last, 0); #endif @@ -1325,9 +1322,10 @@ NK_API int nk_quickdraw_handle_event(EventRecord *event, struct nk_context *nukl } else if (key == eitherShiftKey) { nk_input_key(nuklear_context, NK_KEY_SHIFT, isKeyDown); - } else if (key == deleteKey) { + } else if (key == deleteKey && isKeyDown) { - nk_input_key(nuklear_context, NK_KEY_DEL, isKeyDown); + nk_input_key(nuklear_context, NK_KEY_DEL, 1); + nk_input_key(nuklear_context, NK_KEY_DEL, 0); } else if (key == enterKey) { nk_input_key(nuklear_context, NK_KEY_ENTER, isKeyDown); @@ -1398,6 +1396,8 @@ NK_API int nk_quickdraw_handle_event(EventRecord *event, struct nk_context *nukl break; } } + + return 1; } // i think these functions are close to correct, but throw an error around invalid storage class