Skip to content

Commit d90f412

Browse files
committed
adding more detail to snap and touchchat for previews and metrics
1 parent 5be97e1 commit d90f412

2 files changed

Lines changed: 85 additions & 30 deletions

File tree

src/processors/snapProcessor.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ class SnapProcessor extends BaseProcessor {
163163
// Set toolbarId if there's a global toolbar
164164
if (hasGlobalToolbar) {
165165
tree.toolbarId = toolbarId || null;
166-
tree.rootId = toolbarId || defaultHomePageId || null;
166+
// Use defaultHomePageId as root (the content pageset), not the toolbar
167+
tree.rootId = defaultHomePageId || null;
167168
} else if (defaultHomePageId) {
168169
tree.rootId = defaultHomePageId;
169170
}
@@ -172,18 +173,11 @@ class SnapProcessor extends BaseProcessor {
172173
console.warn('[SnapProcessor] Failed to load PageSetProperties:', e);
173174
}
174175

175-
// If still no root, look for a page titled "Tool Bar" or similar
176-
if (!tree.rootId || tree.rootId === defaultHomePageId) {
177-
const toolbarPage = pages.find((p) => p.Title === 'Tool Bar' || p.Name === 'Tool Bar');
178-
if (toolbarPage) {
179-
tree.rootId = String(toolbarPage.UniqueId || toolbarPage.Id);
180-
}
181-
}
182-
183-
// If still no root, fallback to first page
176+
// If still no root, fallback to first page (but don't override a valid defaultHomePageId)
184177
if (!tree.rootId && pages.length > 0) {
185178
tree.rootId = String(pages[0].UniqueId || pages[0].Id);
186179
}
180+
187181
// Map from numeric Id -> UniqueId for later lookup
188182
const idToUniqueId: Record<string, string> = {};
189183
pages.forEach((pageRow: SnapPage) => {
@@ -205,6 +199,23 @@ class SnapProcessor extends BaseProcessor {
205199
tree.addPage(page);
206200
});
207201

202+
// Try to find toolbar page even if not set in PageSetProperties
203+
// Some SNAP files have a toolbar page but don't set ToolBarUniqueId
204+
// This must be done AFTER pages are added to the tree
205+
if (!tree.toolbarId || tree.toolbarId === '00000000-0000-0000-0000-000000000000') {
206+
const toolbarPage = Object.values(tree.pages).find((p) => {
207+
const name = (p.name || '').toLowerCase();
208+
return name === 'tool bar' || name === 'toolbar';
209+
});
210+
if (toolbarPage) {
211+
tree.toolbarId = toolbarPage.id;
212+
// Update metadata to reflect toolbar detection
213+
if (tree.metadata) {
214+
(tree.metadata as any).hasGlobalToolbar = true;
215+
}
216+
}
217+
}
218+
208219
// Load ScanGroups for TD Snap "Group Scan" feature
209220
// Maps PageLayoutId -> Array of ScanGroups with their scan block numbers
210221
interface SnapScanGroup {

src/processors/touchchatProcessor.ts

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)