/* * Copyright (c) 2020-2021 joshua stein * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include "amend.h" #include "browser.h" #include "committer.h" #include "focusable.h" #include "repo.h" #include "settings.h" #include "util.h" MenuHandle apple_menu, file_menu, edit_menu, repo_menu, amendment_menu; bool quitting = false; bool handle_menu(long menu_id); int main(void) { Handle mbar; EventRecord event; WindowPtr event_win; GrafPtr old_port; AppFile finder_file; struct repo *repo; struct focusable *focusable; short event_in, n, finder_action, finder_count; bool did_initial_open = false; char key; InitGraf(&thePort); InitFonts(); FlushEvents(everyEvent, 0); InitWindows(); InitMenus(); TEInit(); InitDialogs(0); InitCursor(); MaxApplZone(); util_init(); settings_load(); mbar = GetNewMBar(MBAR_ID); SetMenuBar(mbar); apple_menu = GetMHandle(APPLE_MENU_ID); AddResMenu(apple_menu, 'DRVR'); file_menu = GetMHandle(FILE_MENU_ID); edit_menu = GetMHandle(EDIT_MENU_ID); repo_menu = GetMHandle(REPO_MENU_ID); amendment_menu = GetMHandle(AMENDMENT_MENU_ID); menu_defaults(); DrawMenuBar(); /* see if we were started by double-clicking a .repo file */ CountAppFiles(&finder_action, &finder_count); while (!quitting) { WaitNextEvent(everyEvent, &event, 5L, 0L); switch (event.what) { case nullEvent: for (n = 0; n < nfocusables; n++) { if (focusables[n]->idle) focusables[n]->idle(focusables[n], &event); } if (!did_initial_open) { if (finder_count) { GetAppFiles(1, &finder_file); ClrAppFiles(1); finder_count = 0; repo = repo_open(&finder_file); } else repo = repo_open(NULL); if (repo) browser_init(repo); did_initial_open = true; } break; case keyDown: case autoKey: key = event.message & charCodeMask; if ((event.modifiers & cmdKey) != 0) { if (handle_menu(MenuKey(key))) break; } if ((focusable = focusable_focused()) && focusable->key_down) focusable->key_down(focusable, &event); break; case mouseDown: event_in = FindWindow(event.where, &event_win); switch (event_in) { case inMenuBar: handle_menu(MenuSelect(event.where)); break; case inSysWindow: SystemClick(&event, event_win); break; case inDrag: if ((focusable = focusable_find(event_win)) != NULL) { if (!focusable_show(focusable)) break; DragWindow(event_win, event.where, &screenBits.bounds); } break; case inGoAway: if (TrackGoAway(event_win, event.where)) { if ((focusable = focusable_find(event_win)) != NULL) focusable_close(focusable); } break; case inContent: if ((focusable = focusable_find(event_win)) != NULL) { if (!focusable_show(focusable)) break; if (focusable->mouse_down) focusable->mouse_down(focusable, &event); } break; } break; case updateEvt: event_win = (WindowPtr)event.message; focusable = focusable_find(event_win); if (focusable && focusable->update) { GetPort(&old_port); SetPort(event_win); BeginUpdate(event_win); focusable->update(focusable, &event); EndUpdate(event_win); SetPort(old_port); } break; case activateEvt: break; case app4Evt: if (HiWord(event.message) & (1 << 8)) { /* multifinder suspend/resume */ switch (event.message & (1 << 0)) { case 0: /* suspend */ for (n = 0; n < nfocusables; n++) { if (focusables[n]->suspend) focusables[n]->suspend(focusables[n], &event); } break; case 1: /* resume */ for (n = 0; n < nfocusables; n++) { if (focusables[n]->resume) focusables[n]->resume(focusables[n], &event); } break; } } break; } } return 0; } bool handle_menu(long menu_id) { struct focusable *focused; short menu, item; bool ret = true; menu = HiWord(menu_id); item = LoWord(menu_id); if (menu && item && (focused = focusable_focused()) && focused->menu && focused->menu(focused, menu, item)) goto handled; switch (menu) { case APPLE_MENU_ID: switch (item) { case APPLE_MENU_ABOUT_ID: about(PROGRAM_NAME); break; default: { Str255 da; GrafPtr save_port; GetItem(apple_menu, LoWord(menu_id), &da); GetPort(&save_port); OpenDeskAcc(da); SetPort(save_port); break; } } break; case FILE_MENU_ID: switch (item) { case FILE_MENU_NEW_ID: { struct repo *repo; if ((repo = repo_create())) browser_init(repo); break; } case FILE_MENU_OPEN_ID: { struct repo *repo; if ((repo = repo_open(NULL))) browser_init(repo); break; } case FILE_MENU_SETTINGS_ID: settings_edit(); break; case FILE_MENU_QUIT_ID: if (focusables_quit()) quitting = true; break; } break; default: ret = false; } handled: HiliteMenu(0); return ret; } void menu_defaults(void) { DisableItem(edit_menu, EDIT_MENU_CUT_ID); DisableItem(edit_menu, EDIT_MENU_COPY_ID); DisableItem(edit_menu, EDIT_MENU_PASTE_ID); DisableItem(edit_menu, EDIT_MENU_SELECT_ALL_ID); DisableItem(repo_menu, REPO_MENU_ADD_FILE_ID); DisableItem(repo_menu, REPO_MENU_DISCARD_CHANGES_ID); DisableItem(repo_menu, REPO_MENU_APPLY_DIFF_ID); DisableItem(amendment_menu, AMENDMENT_MENU_EDIT_ID); DisableItem(amendment_menu, AMENDMENT_MENU_EXPORT_ID); }