lib 1400521 // FlatLAF set flag PingV3. set flag NotifyingPrintLog. set flag SymbolAsString. // Do the JavaX init svoid standaloneInit { __javax = x30.class; x30.__javax = x30.class; // for hotwire x30_pkg.x30_util.__setJavaX(x30.class); x30.cleanKillMsg = ""; callOnLoadMethods(mc()); } concept Stem { DynModule module; Rect frameRect; bool alwaysOnTop, autoUpdate; transient JFrame window; Rect getFrameRect() { ret toRect(getBounds(window)); } void saveFrameRect { setField(frameRect := getFrameRect()); } void setAlwaysOnTop(bool alwaysOnTop) { this.alwaysOnTop = alwaysOnTop; change(); alwaysOnTop(window, alwaysOnTop); } void setWindow(JFrame window) { this.window = window; if (frameRect != null) setBounds(window, frameRect); onWindowClosing(window, r cleanExit); onBoundsChange(window, r saveFrameRect); alwaysOnTop(window, alwaysOnTop); } } transient sclass GazelleHost { Stem stem; DynModule gazelle; transient S windowTitle = "November Gazelle v1"; transient S downloadURL = "https://botcompany.de/jar/" + psI(programID()) + "?withLibs=1&noCompiler=1"; transient S trayIconImageID = #1103047; transient int borderSize = 5; transient Color color1 = awtColor("ADD8E6"); transient Color color2 = awtColor("EEEEEE"); transient Color color3 = awtColor("A3C0AA"); transient IF0 moduleMaker; transient ThreadPool threadPool; transient TrayIcon trayIcon; transient JFrame mainWindow; transient Set argsSet; transient Concepts concepts; *(ThreadPool *threadPool, IF0 *moduleMaker) {} void trayIconLeftClick { activateFrame_v3(mainWindow); } void makeTrayIcon { pcall-short { trayIcon_imageAutoSize = false; trayIcon = installTrayIcon(trayIconImageID, windowTitle, r trayIconLeftClick, "Show Gazelle", r { activateFrame(mainWindow) }, "Exit Gazelle", r cleanExit ); } } void run(S[] args) { argsSet = asSet(args); if (!argsSet.contains("noflatlaf")) com.formdev.flatlaf.FlatLightLaf.setup(); if (contains(args, "profile")) profileToConsole(() -> actualMain(args)); else actualMain(args); if (argsSet.contains("brexit")) System.exit(0); } void actualMain(S... args) { vm_generalMap_put(stefansOS := this); System.out.println(hmsWithColonsAndMS() + ": Init"); //x30.coreInit(); // Ready to roll if (containsOneOf(argsSet, "upgrade", "update")) ret with upgradeGazelle(); makeTrayIcon(); initAutoUpdate(); // Test classFinder sanity set flag defaultDefaultClassFinder_debug. assertEquals(callF(_defaultClassFinder(), "main$Stem"), Stem.class); // Start DB concepts = newConceptsWithClassFinder(programID); concepts.fileLock().lockOrFail(); concepts.fileLock().deleteOnExit(); concepts.persist(); print("Concepts loaded: " + map className(allConcepts(concepts)); var stems = findConcepts(concepts, Stem); print("Stems in DB: " + l(stems)); stem = first(stems); if (stem == null) { print("Starting new module"); stem = registerConcept(concepts, new Stem); makeModule(); cset(stem, module := gazelle); } else { gazelle = stem.module; print("Depersisted module " + gazelle); } gazelle._host = stem; setOpt_raw(gazelle, +threadPool); // only if the field exists copyLocalLog(gazelle, mc()); JComponent vis; { temp gazelle.enter(); gazelle.start(); printWithMS("Visualize"); vis = swing(-> { temp gazelle.enter(); ret gazelle.visualize(); }); } vis = makeWindowBorderAndTitle(vis, windowTitle); printWithMS("Show frame"); //stem.window = showMainFrame("Gazella", vis); JFrame frame = makeUndecoratedFrame(windowTitle, vis); setFrameIcon(frame, trayIconImageID); stem.setWindow(mainWindow = frame); showWindow(stem.window); printWithMS("Dudadoneski"); } void minimize { if (trayIcon == null) minimizeWindow(mainWindow); else hideWindow(mainWindow); } JComponent makeWindowBorderAndTitle(JComponent contents, S title) { //ret jCenteredSection_fontSizePlus(10, title, vis); var icons = jline(); icons.add(jbutton("Minimize", r minimize)); icons.add(jbutton("Close", r cleanExit /*{ disposeWindow(icons) }*/)); icons.add(jPopDownButton_noText( "Update Gazelle", rThread upgradeGazelle, "Restart Gazelle", rThread restart, jCheckBoxMenuItem_dyn("Auto-Update", -> stem.autoUpdate, b -> cset(stem, autoUpdate := b)), "Dump threads", rThread { showText("User threads", renderUserThreadsWithStackTraces()); }, jCheckBoxMenuItem_dyn("Always on top", -> stem.alwaysOnTop, alwaysOnTop -> stem.setAlwaysOnTop(alwaysOnTop)) )); var actualTitle = fontSizePlus(7, jCenteredLabel(title)); var spacer = gazelle_wavySpacer(); var titleBarMain = setOpaqueBackground(color1, westCenterAndEastWithMargin( jImage_scaledToHeight(24, trayIconImageID), actualTitle, setOpaqueBackground(color2, spacer)); installWindowDragger(actualTitle); installWindowDragger(spacer); var titleBar = setBackground(color2, centerAndEast( titleBarMain, icons)); var border = // createBevelBorder(); BorderFactory.createLineBorder(color1, borderSize); var outerPanel = withBorder(border, northAndCenter(titleBar, contents)); installWindowResizeDraggerOnBorder(outerPanel); ret outerPanel; } O dm_getStem(O moduleOrID) { ret stem; } O resolveModule(O moduleOrID) { ret moduleOrID == stem ? gazelle : moduleOrID; } void cleanExit { thread { print("Saving DB for exit"); dispose concepts; System.exit(0); } } File myJar() { ret getBytecodePathForClass(this); } void upgradeGazelle { File myJar = myJar(); print(+myJar); S date = ymdMinusHMS(); File f = javaxCodeDir("Downloaded Updates/" + "gazelle-" + date + ".jar"); infoBox("Downloading Update..."); loadBinaryPageToFile(downloadURL, f); printFileInfo(f); if (!isNonEmptySingleZip_byMagicHeader(f)) ret with infoBox("Bad file downloaded... :("); bool replaced; if (isFile(myJar)) { print("Loaded " + nClasses(loadAllClassesInByteCodePath(myJar))); print("Replacing with new version: " + myJar); renameFile(myJar, appendToBaseName(myJar, ".bak." + date)); copyFile(f, myJar); printFileInfo(myJar); set replaced; } infoBox(replaced ? "Installed update, replaced " + f2s(myJar) + " - now starting" : "Starting update, but could not replace originally downloaded jar"); restart(replaced ? myJar : f); } void restart(File jar default myJar()) { S javaCmd = or2(currentProcessCommand(), "java"); S cmd = pqO(javaCmd) + " -jar " + pqO(jar); print(cmd); nohup(cmd); cleanExit(); } void makeModule() { if (gazelle == null) gazelle = callF(moduleMaker); } void reloadModuleInBackground(Stem mod) { restart(); } void initAutoUpdate { print("Making SnippetUpdateConnector."); snippetUpdateConnector(verbose := true); vmBus_onMessage snippetUpdate(voidfunc(L l) { S uri = getString(l, 1); new Matches m; if (swic(uri, "/transpileOK/", m)) if (sameSnippetID(programID(), firstIntAsString(m.rest()))) { if (stem.autoUpdate) upgradeGazelle(); //infoBox("Gazelle can be updated!"); } }); } }