!7 static double interval = 1.0; static new LatestAppearance latest; sS tooltip; static RectAndMD5 mouse; static Rect rectShown; static int maxClipWidth = min(300, screenWidth()/2); static int maxClipHeight = min(100, screenHeight()/2); static ImageSurface lastIS; p-subst { autoRestart(); startBotHere("Screen Segmenter.", #1015121); consoleIcon(#1101243); onGlobalMousePress(voidfunc(NativeMouseEvent e) { lock defaultLock(); int x = e.getX(), y = e.getY(); makeToolTip(Pt(x, y)); S text; if (mouse == null) text = "User clicked at " + x + "/" + y + " (" + screenWidth() + "x" + screenHeight() + ")"; else text = "User clicked on " + (empty(tooltip) ? "uncommented object of size " + mouse.r.w + "x" + mouse.r.h : multiLineQuote(tooltip)) + " at " + x + "/" + y + " (screen: " + screenWidth() + "x" + screenHeight() + ", rect: " + mouse.r + ", md5: " + mouse.md5 + ")"; mechAppend_noUniq_inQ("Mouse log", text); }); S tooltip = ""; // mouse repeat with sleep interval { time2 { L list = latest.recordAndSort(thingsOnScreen2()); makeToolTip(mousePt()); } print(localDateWithSeconds() + ": Found: " + list); consoleTitle(l(list) + " " + joinWithComma(list)); } } svoid makeToolTip(Pt mousePt) { lock defaultLock(); L rects = segmentedScreenFromCacheFile_last; mouse = smallestRectAndMD5Containing(rects, mousePt); S name = ""; if (mouse != null) print("Mouse: " + sfu(mouse)); if (mouse != null) name = unnull(thingsOnScreenDefinitions().get(mouse.md5)); /*if (neq(name, tooltip)) flatInfoBox_topRightCorner(name, 1.0);*/ tooltip = name; Rect r = mouse == null ? null : mouse.r; if (r != null /*&& empty(name)*/ && neq(r, rectShown) && r.w <= maxClipWidth && r.h <= maxClipHeight && !mouseInWindow(lastIS)) { disposeWindow(lastIS); double zoom = 1; int x = max(r.w, r.h); if (x < 30) zoom = 3.0; else if (x < 100) zoom = 2.0; BufferedImage2 clip = shootScreenArea_possiblyBroken(mouse.r); final ImageSurface is = zoomedImageSurface(clip, zoom); lastIS = is; hideWindowOnComponentMouseOver(is); showWindowInTopRightCorner(withLineBorder(Color.green, withMargin(10, vstackWithSpacing( jcenteredlabel("Symbol at mouse cursor:"), is, jcenteredlabel("Interpretation:"), jcenteredboldlabel(or2(name, "?")), jbutton("Teach this symbol...", r-thread { teach(clip, name, r) ))))); disposeWindowAfter_unlessMouseInIt(3.0, is); } rectShown = r; } svoid teach(BufferedImage2 clip, S _name, RectAndMD5 r) { S md5 = md5OfBufferedImage(clip); bool imageChanged = neq(md5, r.md5); S name = unnull(or2(thingsOnScreenDefinitions().get(md5), _name)); final JTextField tf = jtextfield(name); showFormTitled("Teach symbol", "MD5", md5 + (imageChanged ? " (warning: changed)" : ""), "Symbol", new ImageChooser(clip), "Meaning", tf, r { S text = getTextTrim(tf); addThingOnScreenDefinition(md5, text); comments.put(md5, nullIfEmpty(text)); ((DefaultTableModel) table.getModel()).setValueAt(text, row, 1); }); }