diff --git a/src/components/BitmapEditor/components/ExportDialog/index.tsx b/src/components/BitmapEditor/components/ExportDialog/index.tsx index 63a0df6..e5c8dbf 100644 --- a/src/components/BitmapEditor/components/ExportDialog/index.tsx +++ b/src/components/BitmapEditor/components/ExportDialog/index.tsx @@ -1,6 +1,6 @@ import { useBitmapsStore } from '@/stores/bitmaps'; import { DataFormat, Platform, SizeFormat, exportBitmap } from './utils'; -import { useMemo } from 'react'; +import { useEffect, useMemo, useRef } from 'react'; import { FormProvider, useForm } from 'react-hook-form'; import { CheckBox } from '@/components/CheckBox'; import { Input } from '@/components/Input'; @@ -46,9 +46,19 @@ export const ExportDialog = ({ bitmapId, area, onClose }: ExportDialogProps): JS defaultValues: { ...defaultValues, name: bitmapEntity?.name ?? '' }, }); - const { register, handleSubmit, watch } = methods; + const { register, handleSubmit, watch, setValue } = methods; const formValues = watch(); + const prevPlatformRef = useRef(formValues.platform); + + // Auto-select Pico-friendly bit order only when switching into RP Pico platform. + useEffect(() => { + if (prevPlatformRef.current !== Platform.Pico && formValues.platform === Platform.Pico) { + setValue('bitOrder', BitOrder.LSB); + } + prevPlatformRef.current = formValues.platform; + }, [formValues.platform, setValue]); + const exportCode = useMemo( () => (bitmapEntity ? exportBitmap({ bitmapEntity, area, ...formValues }) : ''), [area, bitmapEntity, formValues], diff --git a/src/components/BitmapEditor/components/ExportDialog/utils.test.ts b/src/components/BitmapEditor/components/ExportDialog/utils.test.ts index 74dbfdb..95aa1fb 100644 --- a/src/components/BitmapEditor/components/ExportDialog/utils.test.ts +++ b/src/components/BitmapEditor/components/ExportDialog/utils.test.ts @@ -109,15 +109,13 @@ describe('BitmapEditor/ExportDialog/utils', () => { }); expect(result).toContain('// testbitmap.h'); - expect(result).toContain('#ifndef TESTBITMAP_H'); - expect(result).toContain('#define TESTBITMAP_H'); + expect(result).toContain('#pragma once'); expect(result).toContain('#include '); expect(result).toContain('#include "bitmap.h"'); expect(result).toContain('const bitmap_t testbitmap = {'); expect(result).toContain('.width = 8,'); expect(result).toContain('.height = 8,'); expect(result).toContain(`.data = (uint8_t[]){${expectedDataHex}}`); - expect(result).toContain('#endif // TESTBITMAP_H'); }); }); diff --git a/src/components/BitmapEditor/components/ExportDialog/utils.ts b/src/components/BitmapEditor/components/ExportDialog/utils.ts index 8bf3ce5..6341a34 100644 --- a/src/components/BitmapEditor/components/ExportDialog/utils.ts +++ b/src/components/BitmapEditor/components/ExportDialog/utils.ts @@ -123,13 +123,12 @@ ${varType}${progMem} ${nameLower}[] = { ${dataArray} }; .replace(/\n$/, ''); }; -const exportForPico = ({ nameLower, nameUpper, width, height, dataArray }: PlatformExportParams): string => { - const headerName = `${nameUpper}_H`; +const exportForPico = ({ nameLower, width, height, dataArray }: PlatformExportParams): string => { const includesBlock = ['#include ', '#include "bitmap.h"'].filter(Boolean).join('\n'); return ` // ${nameLower}.h -#ifndef ${headerName} -#define ${headerName} +#pragma once + ${includesBlock} const bitmap_t ${nameLower} = { @@ -137,8 +136,6 @@ const bitmap_t ${nameLower} = { .height = ${height}, .data = (uint8_t[]){${dataArray}} }; - -#endif // ${headerName} ` .replace(/^\n/, '') .replace(/\n$/, ''); diff --git a/src/pages/EditBitmap/index.test.tsx b/src/pages/EditBitmap/index.test.tsx index eb96bc8..bf383d7 100644 --- a/src/pages/EditBitmap/index.test.tsx +++ b/src/pages/EditBitmap/index.test.tsx @@ -93,6 +93,28 @@ test('export bitmap', async () => { expect(spy).toHaveBeenCalledWith(exportCode); }); +test('select pico sets LSB bit order automatically', async () => { + const { userEvent } = await setupTest(); + const exportButton = screen.getByText('Export to C'); + expect(exportButton).toBeEnabled(); + await userEvent.click(exportButton); + + const msbRadio = screen.getByLabelText('MSB-first (Adafruit)'); + const lsbRadio = screen.getByLabelText('LSB-first (U8g2, Pico)'); + const picoRadio = screen.getByLabelText('RP Pico'); + + await userEvent.click(msbRadio); + expect((msbRadio as HTMLInputElement).checked).toBeTruthy(); + expect((lsbRadio as HTMLInputElement).checked).toBeFalsy(); + + await userEvent.click(picoRadio); + expect((lsbRadio as HTMLInputElement).checked).toBeTruthy(); + + await userEvent.click(msbRadio); + expect((msbRadio as HTMLInputElement).checked).toBeTruthy(); + expect((lsbRadio as HTMLInputElement).checked).toBeFalsy(); +}); + test('grid settings', async () => { const { userEvent, stores } = await setupTest(); const gridButton = screen.getByText('Grid');