From 6c7ac5e74933c873f63e2637f2b68b4812cd043d Mon Sep 17 00:00:00 2001 From: nakst <> Date: Mon, 20 Sep 2021 17:08:54 +0100 Subject: [PATCH] EsButtonSetIconFromBits; icons for 2048 game --- apps/2048.ini | 5 ++- apps/test.cpp | 2 +- desktop/api.cpp | 45 +++++++++++++++---- desktop/desktop.cpp | 34 +++++++++++++- desktop/gui.cpp | 105 ++++++++++++++++++++++++++++++-------------- desktop/os.header | 6 ++- desktop/syscall.cpp | 6 +-- desktop/text.cpp | 4 +- desktop/theme.cpp | 2 +- res/2048_icon16.png | Bin 0 -> 1019 bytes res/2048_icon32.png | Bin 0 -> 1724 bytes shared/strings.cpp | 2 +- util/api_table.ini | 4 +- util/build_core.c | 2 +- 14 files changed, 163 insertions(+), 54 deletions(-) create mode 100644 res/2048_icon16.png create mode 100644 res/2048_icon32.png diff --git a/apps/2048.ini b/apps/2048.ini index f06f8e5..d4f3e0d 100644 --- a/apps/2048.ini +++ b/apps/2048.ini @@ -1,7 +1,10 @@ [general] name=2048 -icon=icon_applications_other use_single_instance=1 [build] source=apps/2048.cpp + +[embed] +$Icons/16=res/2048_icon16.png +$Icons/32=res/2048_icon32.png diff --git a/apps/test.cpp b/apps/test.cpp index 99d9820..f3fee21 100644 --- a/apps/test.cpp +++ b/apps/test.cpp @@ -130,7 +130,7 @@ const EsStyle stylePanel = { int TestCanvasMessage(EsElement *, EsMessage *message) { if (message->type == ES_MSG_PAINT) { size_t dataBytes; - const void *data = EsEmbeddedFileGet("test", -1, &dataBytes); + const void *data = EsBundleFind(nullptr, "test", -1, &dataBytes); if (data) EsDrawVectorFile(message->painter, EsPainterBoundsClient(message->painter), data, dataBytes); uint32_t cornerRadii[4] = { 10, 20, 30, 40 }; diff --git a/desktop/api.cpp b/desktop/api.cpp index d24e4f9..2793b76 100644 --- a/desktop/api.cpp +++ b/desktop/api.cpp @@ -76,6 +76,7 @@ struct EsFileStore { EsHandle handle; struct { + const EsBundle *bundle; char *path; size_t pathBytes; }; @@ -115,6 +116,21 @@ struct Work { EsGeneric context; }; +struct EsBundle { + const BundleHeader *base; + ptrdiff_t bytes; +}; + +const EsBundle bundleDefault = { + .base = (const BundleHeader *) BUNDLE_FILE_MAP_ADDRESS, + .bytes = -1, +}; + +const EsBundle bundleDesktop = { + .base = (const BundleHeader *) BUNDLE_FILE_DESKTOP_MAP_ADDRESS, + .bytes = -1, +}; + struct { Array<EsSystemConfigurationGroup> systemConfigurationGroups; EsMutex systemConfigurationMutex; @@ -161,7 +177,7 @@ void UndoManagerDestroy(EsUndoManager *manager); int TextGetStringWidth(EsElement *element, const EsTextStyle *style, const char *string, size_t stringBytes); struct APIInstance *InstanceSetup(EsInstance *instance); EsTextStyle TextPlanGetPrimaryStyle(EsTextPlan *plan); -EsFileStore *FileStoreCreateFromEmbeddedFile(const char *path, size_t pathBytes); +EsFileStore *FileStoreCreateFromEmbeddedFile(const EsBundle *bundle, const char *path, size_t pathBytes); EsFileStore *FileStoreCreateFromPath(const char *path, size_t pathBytes); EsFileStore *FileStoreCreateFromHandle(EsHandle handle); void FileStoreCloseHandle(EsFileStore *fileStore); @@ -678,7 +694,7 @@ EsFileStore *FileStoreCreateFromHandle(EsHandle handle) { return fileStore; } -EsFileStore *FileStoreCreateFromEmbeddedFile(const char *name, size_t nameBytes) { +EsFileStore *FileStoreCreateFromEmbeddedFile(const EsBundle *bundle, const char *name, size_t nameBytes) { EsFileStore *fileStore = (EsFileStore *) EsHeapAllocate(sizeof(EsFileStore) + nameBytes, false); if (!fileStore) return nullptr; EsMemoryZero(fileStore, sizeof(EsFileStore)); @@ -687,6 +703,7 @@ EsFileStore *FileStoreCreateFromEmbeddedFile(const char *name, size_t nameBytes) fileStore->error = ES_SUCCESS; fileStore->path = (char *) (fileStore + 1); fileStore->pathBytes = nameBytes; + fileStore->bundle = bundle; EsMemoryCopy(fileStore->path, name, nameBytes); return fileStore; } @@ -1732,18 +1749,24 @@ void EsInstanceSetActiveUndoManager(EsInstance *_instance, EsUndoManager *manage EsCommandSetDisabled(EsCommandByID(manager->instance, ES_COMMAND_REDO), !manager->redoStack.Length()); } -const void *EsEmbeddedFileGet(const char *_name, ptrdiff_t nameBytes, size_t *byteCount) { +const void *EsBundleFind(const EsBundle *bundle, const char *_name, ptrdiff_t nameBytes, size_t *byteCount) { + if (!bundle) { + bundle = &bundleDefault; + } + if (nameBytes == -1) { nameBytes = EsCStringLength(_name); } - const BundleHeader *header = (const BundleHeader *) BUNDLE_FILE_MAP_ADDRESS; - - if (nameBytes > 9 && 0 == EsMemoryCompare(_name, "$Desktop/", 9)) { - header = (const BundleHeader *) BUNDLE_FILE_DESKTOP_MAP_ADDRESS; - _name += 9, nameBytes -= 9; + if (bundle->bytes != -1) { + if ((size_t) bundle->bytes < sizeof(BundleHeader) + || (size_t) (bundle->bytes - sizeof(BundleHeader)) / sizeof(BundleFile) < bundle->base->fileCount + || bundle->base->signature != BUNDLE_SIGNATURE || bundle->base->version != 1) { + return nullptr; + } } + const BundleHeader *header = bundle->base; const BundleFile *files = (const BundleFile *) (header + 1); uint64_t name = CalculateCRC64(_name, nameBytes); @@ -1753,6 +1776,12 @@ const void *EsEmbeddedFileGet(const char *_name, ptrdiff_t nameBytes, size_t *by *byteCount = files[i].bytes; } + if (bundle->bytes != -1) { + if (files[i].offset >= (size_t) bundle->bytes || files[i].bytes > (size_t) (bundle->bytes - files[i].offset)) { + return nullptr; + } + } + return (const uint8_t *) header + files[i].offset; } } diff --git a/desktop/desktop.cpp b/desktop/desktop.cpp index 6d1956d..5d7f7d2 100644 --- a/desktop/desktop.cpp +++ b/desktop/desktop.cpp @@ -1261,9 +1261,41 @@ void InstanceBlankTabCreate(EsMessage *message) { if (application->hidden) continue; EsButton *button = EsButtonCreate(buttonGroup, ES_CELL_H_FILL | ES_ELEMENT_NO_FOCUS_ON_CLICK, ES_STYLE_BUTTON_GROUP_ITEM, application->cName); - EsButtonSetIcon(button, (EsStandardIcon) application->iconID ?: ES_ICON_APPLICATION_DEFAULT_ICON); button->userData = application; + if (application->iconID) { + EsButtonSetIcon(button, (EsStandardIcon) application->iconID); + } else { + EsButtonSetIcon(button, ES_ICON_APPLICATION_DEFAULT_ICON); + + // TODO Load the icon asynchronously. + // TODO Load the correct icon size. + // TODO Reload the icon if the UI scale factor changes. + // TODO Cache the icon bits. + // TODO Generic icon and thumbnail cache in the API, based off the one from File Manager? + + size_t fileBytes; + void *file = EsFileMap(application->cExecutable, -1, &fileBytes, ES_MAP_OBJECT_READ_ONLY); + EsBundle bundle = { .base = (const BundleHeader *) file, .bytes = (ptrdiff_t) fileBytes }; + + if (file) { + size_t icon32Bytes; + const void *icon32 = EsBundleFind(&bundle, EsLiteral("$Icons/32"), &icon32Bytes); + + if (icon32) { + uint32_t width, height; + uint32_t *bits = (uint32_t *) EsImageLoad(icon32, icon32Bytes, &width, &height, 4); + + if (bits) { + EsButtonSetIconFromBits(button, bits, width, height, width * 4); + EsHeapFree(bits); + } + } + + EsObjectUnmap(file); + } + } + EsButtonOnCommand(button, [] (EsInstance *, EsElement *element, EsCommand *) { ApplicationInstance *instance = ApplicationInstanceFindByWindowID(element->window->id); diff --git a/desktop/gui.cpp b/desktop/gui.cpp index 384ee25..c2aae2b 100644 --- a/desktop/gui.cpp +++ b/desktop/gui.cpp @@ -295,6 +295,15 @@ struct EsButton : EsElement { EsCommand *command; EsCommandCallback onCommand; EsElement *checkBuddy; + EsImageDisplay *imageDisplay; +}; + +struct EsImageDisplay : EsElement { + void *source; + size_t sourceBytes; + + uint32_t *bits; + size_t width, height, stride; }; struct ScrollPane { @@ -3729,6 +3738,14 @@ int ProcessButtonMessage(EsElement *element, EsMessage *message) { ES_RECT_2S(message->painter->width, message->painter->height), button->label, button->labelBytes, button->iconID, (button->flags & ES_BUTTON_DROPDOWN) ? ES_DRAW_CONTENT_MARKER_DOWN_ARROW : ES_FLAGS_DEFAULT); + } else if (message->type == ES_MSG_PAINT_ICON) { + if (button->imageDisplay) { + EsRectangle imageSize = ES_RECT_2S(button->imageDisplay->width, button->imageDisplay->height); + EsRectangle bounds = EsRectangleFit(EsPainterBoundsClient(message->painter), imageSize, true); + EsImageDisplayPaint(button->imageDisplay, message->painter, bounds); + } else { + return 0; + } } else if (message->type == ES_MSG_GET_WIDTH) { if (!button->measurementCache.Get(message, &button->state)) { EsTextStyle textStyle; @@ -3760,6 +3777,11 @@ int ProcessButtonMessage(EsElement *element, EsMessage *message) { elements.FindAndDeleteSwap(button, true); button->command->elements = elements.array; } + + if (button->imageDisplay) { + EsElementDestroy(button->imageDisplay); + button->imageDisplay = nullptr; + } } else if (message->type == ES_MSG_MOUSE_LEFT_DOWN) { } else if (message->type == ES_MSG_MOUSE_LEFT_CLICK) { if (button->flags & ES_BUTTON_CHECKBOX) { @@ -3885,10 +3907,28 @@ EsButton *EsButtonCreate(EsElement *parent, uint64_t flags, const EsStyle *style void EsButtonSetIcon(EsButton *button, uint32_t iconID) { EsMessageMutexCheck(); + if (button->imageDisplay) { + EsElementDestroy(button->imageDisplay); + button->imageDisplay = nullptr; + } + button->iconID = iconID; button->Repaint(true); } +void EsButtonSetIconFromBits(EsButton *button, const uint32_t *bits, size_t width, size_t height, size_t stride) { + EsMessageMutexCheck(); + + if (!button->imageDisplay) { + button->imageDisplay = EsImageDisplayCreate(button); + } + + if (button->imageDisplay) { + EsImageDisplayLoadBits(button->imageDisplay, bits, width, height, stride); + button->Repaint(true); + } +} + void EsButtonOnCommand(EsButton *button, EsCommandCallback onCommand, EsCommand *command) { EsMessageMutexCheck(); @@ -4991,44 +5031,43 @@ EsSplitter *EsSplitterCreate(EsElement *parent, uint64_t flags, const EsStyle *s // clipboard // zoom/pan -struct EsImageDisplay : EsElement { - void *source; - size_t sourceBytes; +void EsImageDisplayPaint(EsImageDisplay *display, EsPainter *painter, EsRectangle bounds) { + if (!display->bits && !display->source) { + return; + } - uint32_t *bits; - size_t width, height, stride; -}; + if (!display->bits && display->source) { + uint32_t width, height; + uint8_t *bits = EsImageLoad((uint8_t *) display->source, display->sourceBytes, &width, &height, 4); + + if (bits) { + display->bits = (uint32_t *) bits; + display->width = width; + display->height = height; + display->stride = width * 4; + } + + if (~display->flags & UI_STATE_CHECK_VISIBLE) { + if (display->window->checkVisible.Add(display)) { + display->state |= UI_STATE_CHECK_VISIBLE; + } + } + } + + EsPaintTarget source = {}; + source.bits = display->bits; + source.width = display->width; + source.height = display->height; + source.stride = display->stride; + source.fullAlpha = ~display->flags & ES_IMAGE_DISPLAY_FULLY_OPAQUE; + EsDrawPaintTarget(painter, &source, bounds, ES_RECT_4(0, display->width, 0, display->height), 0xFF); +} int ProcessImageDisplayMessage(EsElement *element, EsMessage *message) { EsImageDisplay *display = (EsImageDisplay *) element; - if (message->type == ES_MSG_PAINT && (display->bits || display->source)) { - if (!display->bits && display->source) { - uint32_t width, height; - uint8_t *bits = EsImageLoad((uint8_t *) display->source, display->sourceBytes, &width, &height, 4); - - if (bits) { - display->bits = (uint32_t *) bits; - display->width = width; - display->height = height; - display->stride = width * 4; - } - - if (~display->flags & UI_STATE_CHECK_VISIBLE) { - if (display->window->checkVisible.Add(display)) { - display->state |= UI_STATE_CHECK_VISIBLE; - } - } - } - - EsPaintTarget source = {}; - source.bits = display->bits; - source.width = display->width; - source.height = display->height; - source.stride = display->stride; - EsDrawPaintTarget(message->painter, &source, - EsPainterBoundsInset(message->painter), - ES_RECT_4(0, display->width, 0, display->height), 0xFF); + if (message->type == ES_MSG_PAINT) { + EsImageDisplayPaint(display, message->painter, EsPainterBoundsInset(message->painter)); } else if (message->type == ES_MSG_GET_WIDTH) { message->measure.width = display->width; } else if (message->type == ES_MSG_GET_HEIGHT) { diff --git a/desktop/os.header b/desktop/os.header index ae2dd4e..8740abf 100644 --- a/desktop/os.header +++ b/desktop/os.header @@ -20,6 +20,7 @@ opaque_type EsUndoManager none; opaque_type EsHeap none; opaque_type EsFileStore none; opaque_type EsUserTask none; +opaque_type EsBundle none; type_name uint8_t EsNodeType; type_name intptr_t EsError; @@ -570,6 +571,7 @@ define ES_LIST_DISPLAY_MARKER_TYPE_MASK (0xFF << 0) define ES_IMAGE_DISPLAY_DECODE_WHEN_NEEDED (1 << 0) // The image is only kept in its decoded state when the display is on-screen. define ES_IMAGE_DISPLAY_MANUAL_SIZE (1 << 1) // The display will be manually sized; its size does not depend on the loaded image. +define ES_IMAGE_DISPLAY_FULLY_OPAQUE (1 << 2) // The loaded image will always be fully opaque. define ES_COMMAND_SYSTEM_START (0xF0000000) define ES_COMMAND_DELETE (0xF0000001) @@ -1947,7 +1949,7 @@ function void EsINIZeroTerminate(EsINIState *s); // File systems. -function const void *EsEmbeddedFileGet(STRING name, size_t *byteCount = ES_NULL); +function const void *EsBundleFind(const EsBundle *bundle, STRING name, size_t *byteCount = ES_NULL); // Pass null as the bundle to use the current application's bundle. function ptrdiff_t EsDirectoryEnumerateChildren(STRING path, EsDirectoryChild **buffer); // Free buffer with EsHeapFree. Returns number of children. @@ -2390,6 +2392,7 @@ private function void _EsUISetFont(EsFontFamily id); function EsButton *EsButtonCreate(EsElement *parent, uint64_t flags = ES_FLAGS_DEFAULT, const EsStyle *style = ES_NULL, STRING label = BLANK_STRING); function void EsButtonSetIcon(EsButton *button, uint32_t iconID); +function void EsButtonSetIconFromBits(EsButton *button, const uint32_t *bits, size_t width, size_t height, size_t stride); function void EsButtonSetCheck(EsButton *button, EsCheckState checkState = ES_CHECK_CHECKED, bool sendUpdatedMessage = true); function EsCheckState EsButtonGetCheck(EsButton *button); function void EsButtonOnCommand(EsButton *button, EsCommandCallback callback, EsCommand *command = ES_NULL); // TODO Public property? @@ -2450,6 +2453,7 @@ function void EsIconDisplaySetIcon(EsIconDisplay *display, uint32_t iconID); function EsImageDisplay *EsImageDisplayCreate(EsElement *parent, uint64_t flags = ES_FLAGS_DEFAULT, const EsStyle *style = ES_NULL); function void EsImageDisplayLoadBits(EsImageDisplay *display, const uint32_t *bits, size_t width, size_t height, size_t stride); function void EsImageDisplayLoadFromMemory(EsImageDisplay *display, const void *buffer, size_t bufferBytes); +function void EsImageDisplayPaint(EsImageDisplay *display, EsPainter *painter, EsRectangle bounds); function EsTextDisplay *EsTextDisplayCreate(EsElement *parent, uint64_t flags = ES_FLAGS_DEFAULT, const EsStyle *style = ES_NULL, STRING label = BLANK_STRING); function void EsTextDisplaySetContents(EsTextDisplay *display, STRING contents = BLANK_STRING); diff --git a/desktop/syscall.cpp b/desktop/syscall.cpp index 61ff817..667795c 100644 --- a/desktop/syscall.cpp +++ b/desktop/syscall.cpp @@ -352,7 +352,7 @@ void *EsFileStoreReadAll(EsFileStore *file, size_t *fileSize) { return EsFileReadAll(file->path, file->pathBytes, fileSize, &file->error); } else if (file->type == FILE_STORE_EMBEDDED_FILE) { size_t _fileSize; - const void *data = EsEmbeddedFileGet(file->path, file->pathBytes, &_fileSize); + const void *data = EsBundleFind(file->bundle, file->path, file->pathBytes, &_fileSize); void *copy = EsHeapAllocate(_fileSize, false); if (!copy) return nullptr; if (fileSize) *fileSize = _fileSize; @@ -404,7 +404,7 @@ EsFileOffsetDifference EsFileStoreGetSize(EsFileStore *file) { } } else if (file->type == FILE_STORE_EMBEDDED_FILE) { size_t size; - EsEmbeddedFileGet(file->path, file->pathBytes, &size); + EsBundleFind(file->bundle, file->path, file->pathBytes, &size); return size; } else { EsAssert(false); @@ -421,7 +421,7 @@ void *EsFileStoreMap(EsFileStore *file, size_t *fileSize, uint32_t flags) { } else if (file->type == FILE_STORE_PATH) { return EsFileMap(file->path, file->pathBytes, fileSize, flags); } else if (file->type == FILE_STORE_EMBEDDED_FILE) { - return (void *) EsEmbeddedFileGet(file->path, file->pathBytes, fileSize); + return (void *) EsBundleFind(file->bundle, file->path, file->pathBytes, fileSize); } else { EsAssert(false); return nullptr; diff --git a/desktop/text.cpp b/desktop/text.cpp index c74a153..419d98f 100644 --- a/desktop/text.cpp +++ b/desktop/text.cpp @@ -512,7 +512,7 @@ void FontInitialise() { size_t fileIndex = weight - 1 + italic * 9; if (item->valueBytes && item->value[0] == ':') { - entry.files[fileIndex] = FileStoreCreateFromEmbeddedFile(item->value + 1, item->valueBytes - 1); + entry.files[fileIndex] = FileStoreCreateFromEmbeddedFile(&bundleDesktop, item->value + 1, item->valueBytes - 1); } else { entry.files[fileIndex] = FileStoreCreateFromPath(item->value, item->valueBytes); } @@ -1373,7 +1373,7 @@ bool EsDrawStandardIcon(EsPainter *painter, uint32_t id, int size, EsRectangle r if (!cacheEntry->data) { if (!iconManagement.standardPack) { - iconManagement.standardPack = (const uint8_t *) EsEmbeddedFileGet(EsLiteral("$Desktop/Icons.dat"), &iconManagement.standardPackSize); + iconManagement.standardPack = (const uint8_t *) EsBundleFind(&bundleDesktop, EsLiteral("Icons.dat"), &iconManagement.standardPackSize); } iconManagement.buffer = (char *) EsHeapAllocate((iconManagement.bufferAllocated = 131072), false); diff --git a/desktop/theme.cpp b/desktop/theme.cpp index 62b393f..0d79c1d 100644 --- a/desktop/theme.cpp +++ b/desktop/theme.cpp @@ -1318,7 +1318,7 @@ const char *GetConstantString(const char *cKey) { bool ThemeInitialise() { EsBuffer data = {}; - data.in = (const uint8_t *) EsEmbeddedFileGet(EsLiteral("$Desktop/Theme.dat"), &data.bytes); + data.in = (const uint8_t *) EsBundleFind(&bundleDesktop, EsLiteral("Theme.dat"), &data.bytes); const ThemeHeader *header = (const ThemeHeader *) EsBufferRead(&data, sizeof(ThemeHeader)); diff --git a/res/2048_icon16.png b/res/2048_icon16.png new file mode 100644 index 0000000000000000000000000000000000000000..1898486ade55950131e397805e9c9b6b6fc9f4bd GIT binary patch literal 1019 zcmV<X0|fkuP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0004mX+uL$Nkc;* zaB^>EX>4Tx04R}tkv&MmKpe$iTeT_`2Q!E`WT;LS#ELj-6^c+H)C#RSm|XfHG-*gu zTpR`0f`cE6RR<SmT^(EnLGS~_&CN;CMN0f%QfLw5!Ery{-Fw`<1A_H3)2xnhK+|nA zolJ<?+=>`}MGpi-5J#8HEMr!ZQt%yL_XzOyF2=L`&;2?2)V#%jfJi*U4AUlFC!X50 z4bJ<-0xQWX@j3CBNf#u3<htVV8|R|SL7pj?ne-g7Kr9y9SZQNcGBx5!;;5?WlpoA` zta9Gstd*;*c~AbrNM2uF;yTS?B(Z=+ND!f*iVc)uBSx!EiiI@oCw%-vu3sXTLaq%k za?GOw4YKP8|AXJ%T7~$8mlR0=oiC2_F#?2lfkw@7zK<QJaRP*%fh)b`uhfC*Ptt2G zEqVm>Zvz+CElt@2E_Z;zCqp)6R|?S#77D=o8GTa@7`O#`SH0ev`#607GSpS-1~@nb zMvIia=JW3E_TK(I)9mjDVb*e>s|sF}00006VoOIv0RI600RN!9r;`8x010qNS#tmY z79{`x79{~mQY7#I000McNliru<p~rH00YaR{+Iv&0r*KoK~y-)rIRsC6hRn;zkyvj z*mL#v?h0!YO$14_Kw2APVXSPdG*B2zVnJnNXerc23u$faEljM8!C06m6cjc#<W7!+ z<3!k<nP)L~>|&|gOg1zBH}C!bJowMg0Bml3e^pq!U}V66P}r3Lqi{&!cT^Nb(c1LI z^NR-H)0YihnZ7_2#ek4T=&)!A*clW&|Ih*8_PIWDS7%HFaCDS2HXh;S%bSNPR1qtQ z{ayeZHpc-7fV{waf5O;KKSzT0=@?-!h%AX&zBL2D=Em0&aG2+WdJT&UUabEF;K6*0 zc0EQWsLARP;nKVWSnKfkAYH=CA4`>*IE~oH?WHK(Nq}>LgDzlbBrTS1UIHT;Q!$<0 zJ_y=b{kW;t+Y;ctLxV2k-&O(emmkqc+5mKR`>eeA48Y?%bF>=?0-W<F6-Z)xX8=G; zpy4dN#IL;`08SpSV8hyqg~B<CT8p!@4*_9o8NIz6V<1bXcyjLsLS$)z+wWoo&Q}yT z=g2$TxR)yc^cPoo{Udby?rcgkoeI|WJ0x3A0kFmOzoy_tXYd<<312=K=j#;CV-S%q zZCY2If^!@sDea|aV1$}Y?x$x!hIC>q$Q9UA8I#wR$qR@5xKRS)I9_}E?)}0rNsQ7{ pi9{t8VV$hi)~M{y|6`ih{{Sj032>#Vz1IK$002ovPDHLkV1kQa$glta literal 0 HcmV?d00001 diff --git a/res/2048_icon32.png b/res/2048_icon32.png new file mode 100644 index 0000000000000000000000000000000000000000..170676832300834d405e80bbc7d5ef3e8900aec5 GIT binary patch literal 1724 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 S7mnrt0000<MNUMnLSTX*`x++z literal 0 HcmV?d00001 diff --git a/shared/strings.cpp b/shared/strings.cpp index a445f4c..b4e74e8 100644 --- a/shared/strings.cpp +++ b/shared/strings.cpp @@ -33,7 +33,7 @@ DEFINE_INTERFACE_STRING(CommonFileMakeCopy, "Make a copy"); DEFINE_INTERFACE_STRING(CommonFileVersionHistory, "Version history" ELLIPSIS); DEFINE_INTERFACE_STRING(CommonFileShowInFileManager, "Show in File Manager" ELLIPSIS); DEFINE_INTERFACE_STRING(CommonFileMenuFileSize, "Size:"); -DEFINE_INTERFACE_STRING(CommonFileMenuFileLocation, "Location:"); +DEFINE_INTERFACE_STRING(CommonFileMenuFileLocation, "Where:"); DEFINE_INTERFACE_STRING(CommonFileUnchanged, "(All changes saved.)"); DEFINE_INTERFACE_STRING(CommonSearchOpen, "Search"); diff --git a/util/api_table.ini b/util/api_table.ini index 9f7f741..501df37 100644 --- a/util/api_table.ini +++ b/util/api_table.ini @@ -366,7 +366,7 @@ EsElementStartTransition=364 EsToolbarAddFileMenu=365 EsFileWriteAllFromHandle=366 EsFileWriteAllGatherFromHandle=367 -EsEmbeddedFileGet=368 +EsButtonSetIconFromBits=368 EsFileStoreWriteAll=369 EsInstanceOpenComplete=370 EsInstanceSaveComplete=371 @@ -378,6 +378,7 @@ EsMountPointEnumerate=376 EsMountPointGetVolumeInformation=377 EsListViewInvalidateAll=378 EsListViewGetFocusedItem=379 +EsBundleFind=380 EsPathQueryInformation=381 EsListViewCreateInlineTextbox=382 EsTextboxStartEdit=383 @@ -458,3 +459,4 @@ EsPanelRadioGroupGetChecked=457 EsTextboxEnableSmartQuotes=458 EsBufferWriteInt8=459 EsInstanceGetStartupRequest=460 +EsImageDisplayPaint=461 diff --git a/util/build_core.c b/util/build_core.c index 8947e49..39e05b4 100644 --- a/util/build_core.c +++ b/util/build_core.c @@ -858,7 +858,7 @@ void OutputSystemConfiguration() { FilePrintFormat(file, "%s=|Fonts:/%.*s.dat\n", fontLines[i].key, (int) fontLines[i].valueBytes - 4, fontLines[i].value); #endif } else { - FilePrintFormat(file, "%s=:$Desktop/%s\n", fontLines[i].key, fontLines[i].value); + FilePrintFormat(file, "%s=:%s\n", fontLines[i].key, fontLines[i].value); } } else { size_t bytes = EsINIFormat(fontLines + i, buffer, sizeof(buffer));