MODULE Browser; IMPORT OS, About, Desktop; VAR browserRunning: CHAR; browserWindow: ARRAY WINDOW_STRUCT_SIZE OF CHAR; browserIcons: ARRAY 12 OF Fox32OSButtonWidget; browserPage: INT; browserNumberOfPages: INT; browserNextPageButton: Fox32OSButtonWidget; browserPrevPageButton: Fox32OSButtonWidget; browserDiskId: INT; browserFileList: ARRAY 341 OF CHAR; browserHasIcons: CHAR; browserIconsResPtr: PTR; EXTERN browserMenuItemsRoot: POINTER TO CHAR; EXTERN browserFileListFriendly: ARRAY 12 OF POINTER TO CHAR; PROCEDURE BrowserMain(diskId, iconX, iconY: INT; desktopWin: PTR; hasIcons: CHAR; iconsResPtr: PTR;); VAR tempDskIconResPtr: PTR; BEGIN (* first, before we do anything, check to make sure the selected disk is available *) IF diskId >| 4 THEN new_messagebox(0, "Invalid disk ID!", 0, 128, 128, 144); end_current_task(); ELSIF diskId = 4 THEN IF IsRomDiskAvailable() = 0 THEN new_messagebox(0, "ROM disk not available!", 0, 128, 128, 200); end_current_task(); END; ELSE IF PortIn(080001000H OR diskId) = 0 THEN new_messagebox(0, "Disk not inserted!", 0, 128, 128, 160); end_current_task(); END; END; browserRunning := 1; browserPage := 0; browserDiskId := diskId; browserHasIcons := 0; browserIconsResPtr := iconsResPtr; (* if icons.res was loaded, then pull the `dsk` resource from it *) IF hasIcons THEN tempDskIconResPtr := get_resource(browserIconsResPtr, "dsk", 4096); IF tempDskIconResPtr THEN copy_memory_bytes(tempDskIconResPtr, PTROF(desktopDiskIcon), 4096); free_memory(tempDskIconResPtr); END; browserHasIcons := 1; END; (* create the window and draw its initial contents *) new_window(PTROF(browserWindow), "Fetcher", 384, 192, 64, 64, PTROF(browserMenuItemsRoot), PTROF(browserIcons)); DrawBrowserWindow(); WHILE browserRunning DO GetNextWindowEvent(PTROF(browserWindow)); (* mouse click event *) IF eventArgs[0] = PTROF(EVENT_TYPE_MOUSE_CLICK) THEN IF (eventArgs[1] <| 8) & (eventArgs[2] <| 16) THEN destroy_window(PTROF(browserWindow)); browserRunning := 0; QuitAnimation(iconX, iconY, desktopWin); ELSIF eventArgs[2] <| 16 THEN start_dragging_window(PTROF(browserWindow)); END; handle_widget_click(PTROF(browserWindow), eventArgs[1], eventArgs[2]); (* menu bar click event *) ELSIF eventArgs[0] = PTROF(EVENT_TYPE_MENU_BAR_CLICK) THEN menu_bar_click_event(PTROF(browserMenuItemsRoot)); (* menu update event *) ELSIF eventArgs[0] = PTROF(EVENT_TYPE_MENU_UPDATE) THEN menu_update_event(); (* menu click event *) ELSIF eventArgs[0] = PTROF(EVENT_TYPE_MENU_CLICK) THEN MenuClickEvent(eventArgs[2], eventArgs[3]); (* menu ack event *) ELSIF eventArgs[0] = PTROF(EVENT_TYPE_MENU_ACK) THEN close_menu(PTROF(browserMenuItemsRoot)); (* button click event *) ELSIF eventArgs[0] = PTROF(EVENT_TYPE_BUTTON_CLICK) THEN HandleIconClick(eventArgs[1]); END; save_state_and_yield_task(); END; END; PROCEDURE HandleIconClick(buttonId: INT;); BEGIN IF buttonId = 128 THEN (* next page button *) IncrementBrowserPage(); ELSIF buttonId = 129 THEN (* previous page button *) DecrementBrowserPage(); ELSE (* an icon was clicked! *) LaunchFromIcon(buttonId); END; END; PROCEDURE MenuClickEvent(rootIndex, itemIndex: INT;); BEGIN IF rootIndex = 0 THEN (* System menu *) IF itemIndex = 0 THEN (* About fox32os *) (* DIRTY HACK WARNING!!! *) close_menu(PTROF(browserMenuItemsRoot)); AboutMain(); END; END; END; PROCEDURE DrawBrowserWindow(); BEGIN fill_window(0FFFFFFFFH, PTROF(browserWindow)); SetupBrowserIconStructs(); draw_widgets_to_window(PTROF(browserWindow)); IF browserHasIcons THEN DrawBrowserIcons(); END; END; PROCEDURE DrawBrowserIcons(); VAR i: INT; icon: POINTER TO Fox32OSButtonWidget; tempFileIconResPtr: PTR; overlay: INT; BEGIN i := 0; overlay := get_window_overlay_number(PTROF(browserWindow)); WHILE i <| 12 DO icon := PTROF(browserIcons[i]); tempFileIconResPtr := get_resource(browserIconsResPtr, icon^.text + string_length(icon^.text) - 3, 4096); IF tempFileIconResPtr THEN set_tilemap(tempFileIconResPtr, 32, 32); draw_tile_to_overlay(0, icon^.x, icon^.y, overlay); free_memory(tempFileIconResPtr); END; i := i + 1; END; END; PROCEDURE SetupBrowserIconStructs(); VAR i, x, y, numberOfFiles: INT; icon: POINTER TO Fox32OSButtonWidget; BEGIN (* get a list of files *) numberOfFiles := ryfs_get_file_list(PTROF(browserFileList), browserDiskId); browserNumberOfPages := numberOfFiles / 12; ConvertFileNames(numberOfFiles); i := 0; WHILE i <| 12 DO x := ((i MOD 4) * 96) + 32; y := ((i / 4) * 64) + 24; icon := PTROF(browserIcons[i]); icon^.type := WIDGET_TYPE_BUTTON; IF i = 11 THEN icon^.next := PTROF(browserNextPageButton); ELSE icon^.next := PTROF(browserIcons[i + 1]); END; icon^.id := i; icon^.text := browserFileListFriendly[i]; icon^.fgColor := 0FF000000H; icon^.bgColor := 0FFDDDDDDH; icon^.width := 32; icon^.height := 32 + 16; icon^.x := x; icon^.y := y; i := i + 1; END; browserNextPageButton.type := WIDGET_TYPE_BUTTON; browserNextPageButton.next := PTROF(browserPrevPageButton); browserNextPageButton.id := 128; browserNextPageButton.text := ">"; browserNextPageButton.fgColor := 0FF000000H; browserNextPageButton.bgColor := 0FFDDDDDDH; browserNextPageButton.width := 16; browserNextPageButton.height := 16; browserNextPageButton.x := 368; browserNextPageButton.y := 16; browserPrevPageButton.type := WIDGET_TYPE_BUTTON; browserPrevPageButton.next := 0; browserPrevPageButton.id := 129; browserPrevPageButton.text := "<"; browserPrevPageButton.fgColor := 0FF000000H; browserPrevPageButton.bgColor := 0FFDDDDDDH; browserPrevPageButton.width := 16; browserPrevPageButton.height := 16; browserPrevPageButton.x := 0; browserPrevPageButton.y := 16; END; PROCEDURE IncrementBrowserPage(); BEGIN IF browserPage <| browserNumberOfPages THEN browserPage := browserPage + 1; END; DrawBrowserWindow(); END; PROCEDURE DecrementBrowserPage(); BEGIN IF browserPage >| 0 THEN browserPage := browserPage - 1; END; DrawBrowserWindow(); END; PROCEDURE LaunchFromIcon(buttonId: INT;); VAR icon: POINTER TO Fox32OSButtonWidget; BEGIN icon := PTROF(browserIcons[buttonId]); launch_fxf_from_disk(icon^.text, browserDiskId, 0, 0, 0, 0, 0); END; PROCEDURE ConvertFileNames(numberOfFiles: INT;); VAR i, j, numberOfFilesLeft: INT; BEGIN (* fill all filenames with "", 0, 0, 0, 0, 0 *) i := 12; WHILE i DO copy_memory_bytes("\0\0\0\0\0", browserFileListFriendly[i - 1], 12); i := i - 1; END; i := 0; numberOfFilesLeft := numberOfFiles - (browserPage * 12); IF numberOfFilesLeft >| 12 THEN numberOfFilesLeft := 12; END; WHILE i <| numberOfFilesLeft DO (* copy the first 8 characters (the actual name of the file) *) copy_memory_bytes(PTROF(browserFileList) + (browserPage * 11 * 12) + (i * 11), browserFileListFriendly[i], 8); (* find the first space in the name *) j := 7; WHILE j DO IF GETCHAR(PTROF(browserFileList) + (browserPage * 11 * 12) + (i * 11) + j) # 32 THEN BREAK(); END; j := j - 1; END; j := j + 1; (* j now equals the index of where the file name ends and the extension begins *) PUTCHAR(browserFileListFriendly[i] + j, 46); copy_memory_bytes(PTROF(browserFileList) + (browserPage * 11 * 12) + (i * 11) + 8, browserFileListFriendly[i] + j + 1, 3); PUTCHAR(browserFileListFriendly[i] + j + 4, 0); i := i + 1; END; END; PROCEDURE QuitAnimation(iconX, iconY: INT; desktopWin: PTR;); VAR i, x, y, w, h: INT; BEGIN IF desktopWin # 0 THEN (* draw the retracting box animation *) i := 0; WHILE i < 16 DO x := RSH(GETSHORT(PTROF(browserWindow) + 20) *| (16 - i) + iconX *| i, 4); y := RSH(GETSHORT(PTROF(browserWindow) + 22) *| (16 - i) + iconY *| i, 4); w := RSH(384 *| (16 - i) + 32 *| i, 4); h := RSH(192 *| (16 - i) + 32 *| i, 4); DrawWireframeBox(get_window_overlay_number(desktopWin), x, y, w, h, 020F0F0F0H); sleep_task(10); draw_filled_rectangle_to_overlay(x, y, w, h, 0, get_window_overlay_number(desktopWin)); i := i + 1; END; DrawDesktopIcons(desktopWin); END; END; END.