@@ -249,29 +249,43 @@ class TouchChatProcessor extends BaseProcessor {
249249
250250 // Load button boxes and their cells
251251 const buttonBoxQuery = `
252- SELECT bbc.*, b.*, bb.id as box_id
252+ SELECT bbc.*, b.*, bb.id as box_id, bb.layout_x, bb.layout_y
253253 FROM button_box_cells bbc
254254 JOIN buttons b ON b.resource_id = bbc.resource_id
255255 JOIN button_boxes bb ON bb.id = bbc.button_box_id
256256 ` ;
257257 try {
258258 const buttonBoxCells = db . prepare ( buttonBoxQuery ) . all ( ) as ( TouchChatButton & {
259259 box_id : number ;
260+ layout_x : number ;
261+ layout_y : number ;
260262 } ) [ ] ;
261263 const buttonBoxes = new Map <
262264 number ,
263- Array < {
264- button : AACButton ;
265- location : number ;
266- spanX : number ;
267- spanY : number ;
268- } >
265+ {
266+ layoutX : number ;
267+ layoutY : number ;
268+ buttons : Array < {
269+ button : AACButton ;
270+ location : number ;
271+ spanX : number ;
272+ spanY : number ;
273+ } > ;
274+ }
269275 > ( ) ;
270276
271277 buttonBoxCells . forEach ( ( cell ) => {
272- if ( ! buttonBoxes . has ( cell . box_id ) ) {
273- buttonBoxes . set ( cell . box_id , [ ] ) ;
278+ let boxData = buttonBoxes . get ( cell . box_id ) ;
279+
280+ if ( ! boxData ) {
281+ boxData = {
282+ layoutX : cell . layout_x || 10 ,
283+ layoutY : cell . layout_y || 6 ,
284+ buttons : [ ] ,
285+ } ;
286+ buttonBoxes . set ( cell . box_id , boxData ) ;
274287 }
288+
275289 const style = buttonStyles . get ( cell . button_style_id ) ;
276290 // Create semantic action for TouchChat button
277291 const semanticAction : AACSemanticAction = {
@@ -320,7 +334,7 @@ class TouchChatProcessor extends BaseProcessor {
320334 labelOnTop : toBooleanOrUndefined ( style ?. label_on_top ) ,
321335 } ,
322336 } ) ;
323- buttonBoxes . get ( cell . box_id ) ? .push ( {
337+ boxData . buttons . push ( {
324338 button,
325339 location : ( ( cell as any ) . location as number ) || 0 ,
326340 spanX : ( ( cell as any ) . span_x as number ) || 1 ,
@@ -346,8 +360,8 @@ class TouchChatProcessor extends BaseProcessor {
346360 // Use mapped string ID if available, otherwise use numeric ID as string
347361 const pageId = numericToRid . get ( instance . page_id ) || String ( instance . page_id ) ;
348362 const page = tree . getPage ( pageId ) ;
349- const buttons = buttonBoxes . get ( instance . button_box_id ) ;
350- if ( page && buttons ) {
363+ const boxData = buttonBoxes . get ( instance . button_box_id ) ;
364+ if ( page && boxData ) {
351365 // Initialize page grid if not exists (assume max 10x10 grid)
352366 if ( ! pageGrids . has ( pageId ) ) {
353367 const grid : Array < Array < AACButton | null > > = [ ] ;
@@ -361,16 +375,14 @@ class TouchChatProcessor extends BaseProcessor {
361375 if ( ! pageGrid ) return ;
362376 const boxX = Number ( instance . position_x ) || 0 ;
363377 const boxY = Number ( instance . position_y ) || 0 ;
364- const boxWidth = Number ( instance . size_x ) || 1 ;
378+ const boxWidth = boxData . layoutX ; // Use layout_x from button_boxes, not size_x from instance
365379 // boxHeight not currently used but kept for future span calculations
366- // const boxHeight = Number(instance.size_y) || 1 ;
380+ // const boxHeight = boxData.layoutY ;
367381
368- buttons . forEach ( ( { button, location, spanX, spanY } ) => {
382+ boxData . buttons . forEach ( ( { button, location, spanX, spanY } ) => {
369383 const safeLocation = Number ( location ) || 0 ;
370384 const safeSpanX = Number ( spanX ) || 1 ;
371385 const safeSpanY = Number ( spanY ) || 1 ;
372- // Add button to page
373- page . addButton ( button ) ;
374386
375387 // Calculate button position within the button box
376388 // location is a linear index, convert to grid coordinates
@@ -381,6 +393,13 @@ class TouchChatProcessor extends BaseProcessor {
381393 const absoluteX = boxX + buttonX ;
382394 const absoluteY = boxY + buttonY ;
383395
396+ // Set button's x and y coordinates
397+ button . x = absoluteX ;
398+ button . y = absoluteY ;
399+
400+ // Add button to page
401+ page . addButton ( button ) ;
402+
384403 // Place button in grid (handle span)
385404 for ( let r = absoluteY ; r < absoluteY + safeSpanY && r < 10 ; r ++ ) {
386405 for ( let c = absoluteX ; c < absoluteX + safeSpanX && c < 10 ; c ++ ) {
@@ -704,7 +723,14 @@ class TouchChatProcessor extends BaseProcessor {
704723 );
705724
706725 CREATE TABLE IF NOT EXISTS button_boxes (
707- id INTEGER PRIMARY KEY
726+ id INTEGER PRIMARY KEY,
727+ resource_id INTEGER,
728+ layout_x INTEGER DEFAULT 10,
729+ layout_y INTEGER DEFAULT 6,
730+ init_size_x INTEGER DEFAULT 10000,
731+ init_size_y INTEGER DEFAULT 10000,
732+ scan_pattern_id INTEGER DEFAULT 0,
733+ FOREIGN KEY (resource_id) REFERENCES resources (id)
708734 );
709735
710736 CREATE TABLE IF NOT EXISTS button_box_cells (
@@ -886,8 +912,26 @@ class TouchChatProcessor extends BaseProcessor {
886912
887913 // Create a button box for this page's buttons
888914 const buttonBoxId = buttonBoxIdCounter ++ ;
889- const insertButtonBox = db . prepare ( 'INSERT INTO button_boxes (id) VALUES (?)' ) ;
890- insertButtonBox . run ( buttonBoxId ) ;
915+
916+ // Create a resource for the button box
917+ const buttonBoxResourceId = resourceIdCounter ++ ;
918+ const insertButtonBoxResource = db . prepare (
919+ 'INSERT INTO resources (id, name, type) VALUES (?, ?, ?)'
920+ ) ;
921+ insertButtonBoxResource . run ( buttonBoxResourceId , page . name || 'ButtonBox' , 0 ) ;
922+
923+ // Insert button box with layout dimensions
924+ const insertButtonBox = db . prepare (
925+ 'INSERT INTO button_boxes (id, resource_id, layout_x, layout_y, init_size_x, init_size_y) VALUES (?, ?, ?, ?, ?, ?)'
926+ ) ;
927+ insertButtonBox . run (
928+ buttonBoxId ,
929+ buttonBoxResourceId ,
930+ gridWidth ,
931+ gridHeight ,
932+ 10000 , // init_size_x in internal units
933+ 10000 // init_size_y in internal units
934+ ) ;
891935
892936 // Create button box instance with calculated dimensions
893937 const insertButtonBoxInstance = db . prepare (
0 commit comments