Warning : session_start(): open(/var/lib/php/sessions/sess_nt445rcq13drc5812li8k82ut6, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning : session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
!7
need latest awtLater setMetaSrc assertSame.
// We're banning db_mainConcepts() again to allow multiple databases loaded at once
// !transpileMainSnippet #1033860
set flag NoVideoLibs.
!include once #1033998 // RSyntaxTextArea
!include once #1013490 // sarxos webcam
!include early #1033884 // Compact Module Include Gazelle V [dev version]
!include once #1034034 // Gazelle 22 Function Include for Scripts
rewrite Challenge to G22Challenge.
rewrite Label to G22Label.
module GazelleScreenCam {
!include early #1025212 // +Enabled without visualization
transient bool autoRunSelfTests = true;
int pixelRows = 128, colors = 8;
S script = "64p 8c gradientImage";
S newScript;
S screenCamScript;
S selectedTab;
S javaCode;
bool horizontalLayout; // flat layout
int fpsTarget = 20;
S webCamName;
bool webCamAccessEnabled = true;
WatchTarget watchTarget;
new G22_TestScreenPanel testScreen;
transient ImageSurface isPosterized;
transient new ScreenCamStream imageStream;
transient Gazelle22_ImageToRegions imageToRegions_finished;
transient new DoubleFPSCounter fpsCounter;
transient int fps;
transient WatchTargetSelector watchTargetSelector;
transient new RollingAverage remainingMSPerFrame;
transient int remainingMS;
transient new FunctionTimings functionTimings;
transient ReliableSingleThread rstRunScript = dm_rst(me(), r _runScript);
transient JGazelleVScriptRunner scriptRunner;
transient UIURLSystem uiURLs;
//transient L availableWebCams;
transient JComboBox cbWebCam;
transient SingleComponentPanel scpWebCamImage;
transient WebcamPanel webCamPanel;
transient JLeftArrowScriptIDE screenCamScriptIDE;
transient GazelleV_LeftArrowScript.Script runningScreenCamScript;
// set by host
transient Concepts concepts;
S uiURL = "Main Tabs";
transient FileWatchService fileWatcher;
transient SimpleCRUD_v2 labelCRUD;
transient SimpleCRUD_v2 imageCRUD;
transient JComponent imageCRUDVis;
transient SimpleCRUD_v2 entityCRUD;
transient JGallery /*gallery,*/ paintToolGallery;
//transient ImageSurface galleryImageSurface;
transient FlexibleRateTimer screenCamTimer;
transient SingleComponentPanel scpMain;
transient JTabbedPane mainTabs;
transient bool showRegionsAsOutline = true;
transient JComponent watchScreenPane;
transient S screenCamRecognitionOutput;
transient new G22Utils g22utils;
delegate stdImageSurface to g22utils.
delegate showUIURL to uiURLs.
delegate renderUIURL to uiURLs.
delegate setupScriptCRUD to g22utils.
transient BackgroundProcessesUI backgroundProcessesUI;
transient BackgroundProcessesUI.Entry bgScreenCam = new("Screen Cam")
.menuItem(jMenuItem("Screen Cam", r showScreenCam));
transient BackgroundProcessesUI.Entry bgWebCam = new("Web Cam")
.menuItem(jMenuItem("Web Cam", r showWebCam));
bool autoRunChallenge = true;
transient G22ChallengesPanel challengesPanel;
transient JComponent urlBar;
transient JVideoLibDownloader videoLibDownloader;
transient JFFMPEGVideoPlayer videoPlayer;
// it's now actually persistent
settableWithVar JPaintTool paintTool;
// also persistent
G22AnalysisPanel paintAnalysisPanel;
// to detect when the project is moved. not implemented yet
//settableWithVar File previousConceptsDir;
transient G22SelfTests selfTests;
settableWithVar bool paintToolGalleryExpanded;
transient StudyPanel studyPanel;
// add fields here
start {
testScreen.onChange(l0 change);
dm_onFieldChange horizontalLayout(
//r dm_revisualize // deh buggy
r dm_reload
);
/*if (concepts == null) {
// non-standalone mode (doesn't work yet)
printWithMS("Starting DB");
db();
concepts = db_mainConcepts();
} else
assertSame(concepts, db_mainConcepts());*/
concepts.quietSave = true;
// make indexes
indexConceptField(concepts, GalleryImage, "path");
indexConceptField(concepts, Example, "item");
indexConceptFieldCI(concepts, G22Label, "name");
g22utils.concepts(concepts);
concepts.miscMapPut(G22Utils.class, g22utils);
g22utils.onSettingUpParser(l1 modifyLeftArrowParser);
g22utils.basicParserTest();
// update count in tab when tab isn't selected
onConceptChangeByClass(concepts, Label, -> {
labelCRUD?.updateEnclosingTabTitle();
//imageCRUD?.updateEnclosingTabTitle();
});
uiURLs = new UIURLSystem(me(), dm_fieldLiveValue uiURL());
uiURLs.addPreferredUIURL("Main Tabs");
backgroundProcessesUI = new BackgroundProcessesUI;
dm_watchFieldAndNow enabled(-> backgroundProcessesUI.addOrRemove(enabled, bgScreenCam));
scriptRunner = new JGazelleVScriptRunner(dm_fieldLiveValue script(me()));
printWithMS("Making image stream");
imageStream.onNewElement(img -> {
fpsCounter.inc();
setField(fps := iround(fpsCounter!));
// perform analysis on screen cam image
// new G22_ImageAnalysis screenCamImageAnalysis;
assertTrue("meta", getMetaSrc(img) instanceof ScreenShotMeta);
Gazelle22_ImageToRegions itr = new(functionTimings, img, new SnPSettings(pixelRows, colors));
itr.run();
imageToRegions_finished = itr;
// run "linear" script on image if any
if (shouldRunScript()) rstRunScript.go();
// run left-arrow script
if (screenCamScriptIDE != null
&& screenCamScriptIDE.visible()) try {
g22_runPostAnalysisLeftArrowScript(itr, runningScreenCamScript);
} catch e {
printStackTrace(e);
screenCamScriptIDE.showRuntimeError(e);
}
// make textual result of analysis
S text = nRegions(itr.regions.regionCount());
setField(screenCamRecognitionOutput := text);
// display image after analysis so we can highlight a region
g22_renderPosterizedHighlightedImage(isPosterized, itr, showRegionsAsOutline);
});
watchTargetSelector = new WatchTargetSelector;
/*if (webCamAccessEnabled) {
printWithMS("Detecting web cams");
watchTargetSelector.updateCamCount();
printWithMS("Found " + n2(availableWebCams, "web cam"));
}*/
printWithMS("Starting screen cam");
ownResource(screenCamTimer = new FlexibleRateTimer(fpsTarget, rEnter {
if (!enabled) ret;
watchTargetSelector?.updateScreenCount();
Timestamp deadline = tsNowPlusMS(1000/fpsTarget);
watchTarget?.mainWindow(getWindow(urlBar));
watchTarget?.configureScreenCamStream(imageStream);
imageStream.step();
long remaining = deadline.minus(tsNow());
remainingMSPerFrame.add(remaining);
setField(remainingMS := iround(remainingMSPerFrame!));
}));
screenCamTimer.start();
dm_onFieldChange fpsTarget(-> screenCamTimer.setFrequencyImmediately(fpsTarget));
printWithMS("Gathering images from disk");
//addDirToGallery(galleryDir()));
addDirToGallery(conceptsDir(concepts));
printWithMS("Got dem images");
transpileRaw_makeTranslator = -> hotwire(#7);
// OSHI adds 4.5 MB to the jar...
//doAfter(5.0, r { print("Process size: ", toM_str(oshi_currentProcessResidentSize_noZGCFix())) });
tempGlobalPopupMenu((c, menu) -> {
O src = componentMetaSrc(c);
menu.add(commaCombine(
"Component class: " + getClassName(c),
src == null ?: "src class: " + getClassName(src)));
});
} // end of start method
void addDirToGallery(File dir) {
watchDirForGallery(dir);
for (f : allImageFiles(dir))
addToGallery(f);
}
void watchDirForGallery(File dir) {
fileWatcher if null = new FileWatchService;
fileWatcher.addRecursiveListener(dir, file -> {
if (isImageFile(file))
addToGallery(file);
});
}
visualize {
isPosterized = stdImageSurface();
labelCRUD = new SimpleCRUD_v2(concepts, Label);
labelCRUD.hideFields("globalID");
labelCRUD.addCountToEnclosingTab(true);
labelCRUD.itemToMap_inner2 = l
-> litorderedmap(
"Name" := l.name,
"# Examples" := n2(countConcepts(concepts, Example, label := l)));
imageCRUD = new SimpleCRUD_v2(concepts, GalleryImage);
imageCRUD.addCountToEnclosingTab(true);
imageCRUD.itemToMap_inner2 = img
-> litorderedmap(
"File" := fileName(img.path),
"Folder" := dirPath(img.path));
imageCRUD.defaultAction(img -> { thread { showImage(img.path) }});
imageCRUDVis = imageCRUD.visualize();
imageCRUD.addButton(jPopDownButton_noText(
"Forget missing images" := rThreadEnter forgetMissingImages
));
imageCRUD.addButton("Back to gallery", rThreadEnter { showUIURL("Gallery") });
imageCRUD.newConcept = -> {
new JFileChooser fc;
fc.setDialogTitle("Add image to gallery");
fc.setCurrentDirectory(conceptsDir(concepts));
fc.setFileFilter(new ImageFileFilter().allowDirectories(true));
addToGallery(execFileChooser(fc));
};
// main visual
studyPanel = new StudyPanel;
watchScreenPane = borderlessScrollPane(jHigherScrollPane(
jfullcenter(vstack(
withLeftAndRightMargin(hstack(
dm_rcheckBox enabled("Watch"),
watchTargetSelector.visualize(),
jlabel(" in "),
withLabelToTheRight("colors @ ", dm_spinner colors(2, 256)),
withLabelToTheRight("p", dm_powersOfTwoSpinner pixelRows(512)),
)),
verticalStrut(2),
withSideMargins(centerAndEastWithMargin(
dm_fieldLabel screenCamRecognitionOutput(),
dm_transientCalculatedToolTip speedInfo_long(rightAlignLabel(dm_transientCalculatedLabel speedInfo()))
)),
))));
initUIURLs();
mainTabs = scrollingTabs(jTopOrLeftTabs(horizontalLayout));
addUIURLToMainTabs("Screen Cam");
addUIURLToMainTabs("Paint");
addUIURLToMainTabs("Analyzers");
addUIURLToMainTabs("Scripts");
addUIURLToMainTabs("Left Arrow Script");
addUIURLToMainTabs("Entities");
addUIURLToMainTabs("Databases");
// add tabs here
// add main tabs to UI URLs (probably don't need this anymore)
for (S tab : tabNames(mainTabs)) {
reMutable tab = dropTrailingBracketedCount(tab);
uiURLs.put(tab, -> {
int i = indexOfTabNameWithoutTrailingCount(mainTabs, tab);
if (i < 0) ret jcenteredlabel("Hmm. Tab not found");
selectTab(mainTabs, i);
ret mainTabs;
});
}
// Fix UI URL after tab was changed manually
// Hopefully doesn't brake stuff (seems it doesn't)
onTabSelected(mainTabs, -> {
if (!isShowing(mainTabs)) ret;
S tabName = dropTrailingBracketedCount(selectedTabName(mainTabs));
if (!eqicOneOf(uiURL, "Main Tabs", tabName))
uiURLs.showUIURL("Main Tabs");
//uiURLs.showUIURL(tabName);
});
var cbEnabled = toolTip("Switch screen cam on or off", dm_checkBox enabled(""));
var lblScreenCam = setToolTip("Show scaled down and color-reduced screen image",
jlabel("Screen Cam"));
tabComponentClickFixer(lblScreenCam);
var screenCamTab = hstackWithSpacing(cbEnabled, lblScreenCam);
replaceTabTitleComponent(mainTabs, "Screen Cam", screenCamTab);
// for tab titles
challengesPanel?.updateCount();
labelCRUD?.update();
imageCRUD?.update();
analyzersPanel().recognizerCRUD.addCountToEnclosingTab(true);
analyzersPanel().recognizerCRUD.update();
scriptsPanel().scriptCRUD.addCountToEnclosingTab(true);
scriptsPanel().scriptCRUD.update();
persistSelectedTabAsLiveValue(mainTabs, dm_fieldLiveValue selectedTab());
urlBar = uiURLs.urlBar();
focusOnFirstShow(urlBar);
setToolTip(uiURLs.comboBox, "UI navigation system (partially populated)");
scpMain = singleComponentPanel();
uiURLs.scp(scpMain);
showUIURL(uiURL);
var lblDB = toolTip("Currently selected database (" + f2s(concepts.conceptsDir()) + ")",
jSimpleLabel(conceptsDirName()));
componentPopupMenuItems(lblDB,
"Manage or switch databases...",
rThread { showUIURL("Databases")});
var vis = northAndCenter(
withSideAndTopMargin(
westCenterAndEast(
//withLabelLeftAndRight("DB:", lblDB, "| "),
withLabelToTheRight(lblDB, "| "),
urlBar,
withLeftMargin(backgroundProcessesUI.shortLabel()))),
scpMain,
);
if (autoRunSelfTests)
onFirstShow(vis, l0 runSelfTests);
ret vis;
}
void runSelfTests {
thread "Self-Tests" {
selfTests = new G22SelfTests(g22utils);
selfTests.run();
selfTestsDone();
}
}
event selfTestsDone;
JComponent screenCamPanel() {
ret centerAndSouthOrEast(horizontalLayout,
withTools(isPosterized),
watchScreenPane);
}
JComponent screenCamPlusScriptPanel() enter {
print("screenCamPlusScriptPanel");
//ret watchScreenPane;
try {
var ide = screenCamScriptIDE = leftArrowScriptIDE();
ide.runButtonShouldBeEnabled = ->
eq(getText(ide.btnRun), "Stop")
|| ide.runButtonShouldBeEnabled_base();
ide.runScript = -> {
if (eq(getText(ide.btnRun), "Stop"))
runningScreenCamScript = null;
else {
runningScreenCamScript = screenCamScriptIDE.parsedScript();
ide.showStatus("Running");
}
setText(ide.btnRun,
runningScreenCamScript == null ? "Run" : "Stop");
};
ret centerAndSouthOrEast(horizontalLayout,
//withTools(
jhsplit(
jscroll_centered_borderless(isPosterized),
screenCamScriptIDE
.lvScript(dm_fieldLiveValue screenCamScript())
.visualize())
//, isPosterized)
, watchScreenPane);
} on fail e { print(e); }
}
S speedInfo() {
ret "FPS " + fps + " idle " + remainingMS + " ms";
}
S speedInfo_long() {
ret "Screen cam running at " + nFrames(fps) + "/second. " + n2(remainingMS) + " ms remaining per frame in first core"
+ " (of targeted " + fpsTarget + " FPS)";
}
bool useErrorHandling() { false; }
S renderFunctionTimings() {
ret lines(ciSorted(map(functionTimings!, (f, avg) ->
firstToUpper(f) + ": " + n2(iround(nsToMicroseconds(avg!))) + " " + microSymbol() + "s (" + n2(iround(avg.n())) + ")")));
}
transient long _runScript_idx;
void _runScript() {
scriptRunner.parseAndRunOn(imageToRegions_finished.ii);
}
bool shouldRunScript() {
ret isShowing(scriptRunner.scpScriptResult);
}
JComponent testScreenPanel() {
ret withSideAndTopMargin(testScreen.visualize());
}
L popDownItems() {
ret ll(jCheckBoxMenuItem_dyn("Horizontal Layout",
-> horizontalLayout,
b -> setField(horizontalLayout := b)));
}
void unvisualize {} // don't zero transient component fields
void resetTimings { functionTimings.reset(); }
// add tool side bar to image surface
JComponent withTools(
JComponent component default jscroll_centered_borderless(is),
ImageSurface is) {
ret centerAndEastWithMargin(component,
vstack(
verticalStrut(5),
jimageButtonScaledToWidth(16, #1103054, "Save screenshot in gallery", rThread saveScreenshotToGallery),
/*jPopDownButton_noText(
jCheckBoxMenuItem_dyn("Live scripting", -> liveScripting, b -> setLiveScripting(b)
),*/
)
);
}
class WatchTargetSelector {
JComboBox cb = jComboBox();
int screenCount, camCount;
visualize {
updateList();
//print("Selecting watchTarget: " + watchTarget);
selectItem(cb, watchTarget);
main onChange(cb, watchTarget -> {
setField(+watchTarget);
//print("Chose watchTarget: " + GazelleScreenCam.this.watchTarget);
});
ret cb;
}
void updateScreenCount() {
if (screenCount != screenCount())
updateList();
}
void updateList() swing {
setComboBoxItems(cb, makeWatchTargets());
}
L makeWatchTargets() {
ret flattenToList(
countIteratorAsList_incl(1, screenCount = screenCount(),
i -> WatchScreen(i)),
new WatchMouse,
new WatchScreenWithMouse,
new WatchOtherScreen,
);
}
}
class SnPSelector {
settable new SnPSettings settings;
event change;
visualize {
var colors = jspinner(settings.colors, 2, 256);
main onChange(colors, -> {
settings.colors = intFromSpinner(colors);
change();
});
var pixelRows = jPowersOfTwoSpinner(512, settings.pixelRows);
main onChange(pixelRows, -> {
settings.pixelRows = intFromSpinner(pixelRows);
change();
});
ret hstack(
colors,
jlabel(" colors @ "),
pixelRows,
jlabel(" p"));
}
}
JComponent wrapCRUD(S title, SimpleCRUD_v2 crud, JComponent vis default crud.visualize()) {
ret crud == null ?: withTopAndBottomMargin(jCenteredRaisedSection(title, withMargin(vis)));
}
File galleryDir() {
ret picturesDir(gazelle22_imagesSubDirName());
}
void saveScreenshotToGallery enter {
var img = imageStream!;
saveImageWithCounter(galleryDir(), "Screenshot", img);
}
GalleryImage addToGallery(File imgFile) {
if (!isImageFile(imgFile)) null;
var img = uniq(concepts, GalleryImage, path := imgFile);
//printVars("addToGallery", +imgFile, +img);
ret img;
}
class StudyPanel {
new SnPSelector snpSelector;
GalleryImage image;
BufferedImage originalImage;
//ImageSurface isOriginal = stdImageSurface();
ImageSurface isOriginalWithRegions = stdImageSurface();
ImageSurface isPosterized = stdImageSurface();
SingleComponentPanel scp = singleComponentPanel();
SingleComponentPanel analysisPanel = singleComponentPanel();
SingleComponentPanel scpExampleCRUD = singleComponentPanel();
ConceptsComboBox cbImage = swing(->
new ConceptsComboBox(concepts, GalleryImage));
Gazelle22_ImageToRegions itr;
int iSelectedRegion;
SimpleCRUD_v2 regionCRUD;
SimpleCRUD_v2 exampleCRUD;
*() {
print("Making StudyPanel " + this);
//cbImage.sortTheList = l -> sortConceptsByIDDesc(l);
cbImage.sortTheList = l -> sortedByComparator(l, (a, b)
-> cmpAlphanumIC(fileName(a.path), fileName(b.path)));
main onChangeAndNow(cbImage, img -> {
/*print("Image selected 1: " + img);
print("Me: " + me() + ", q thread: " + me().q().hasThread()
+ ", q jobs done: " + me().q().nJobsDone());
print("Module queue current job: " + me().q().currentJob());*/
dm_q(me(), r {
print("Image selected: " + img);
image = img;
scp.setComponent(studyImagePanel());
});
});
isPosterized.removeAllTools();
isPosterized.onMousePositionChanged(r_dm_q(me(), l0 regionUpdate));
imageSurfaceOnLeftMouseDown(isPosterized, pt -> dm_q(me(), r { chooseRegionAt(pt) }));
snpSelector.onChange(r_dm_q(me(), l0 runSnP));
}
void chooseRegionAt(Pt p) {
if (itr == null) ret;
iSelectedRegion = itr.regions.regionAt(p);
if (iSelectedRegion > 0) {
var savedRegion = uniq_returnIfNew(concepts, SavedRegion,
+image,
snpSettings := snpSelector.settings.cloneMe(),
regionIndex := iSelectedRegion);
// it's new, add values
if (savedRegion != null) {
print("Saved new region!");
var bitMatrix = toScanlineBitMatrix(itr.regions.regionBitMatrix(iSelectedRegion));
cset(savedRegion, +bitMatrix);
}
}
regionUpdate();
}
// load new image
JComponent studyImagePanel() {
if (image == null) null;
originalImage = loadImage2(image.path);
if (originalImage == null) ret jcenteredlabel("Image not found");
//isOriginal.setImage(originalImage);
isOriginalWithRegions.setImage(originalImage);
iSelectedRegion = 0;
itr = new Gazelle22_ImageToRegions(functionTimings, originalImage, snpSelector.settings);
runSnP();
regionCRUD = new SimpleCRUD_v2(concepts, SavedRegion);
regionCRUD.addFilter(+image);
regionCRUD
.showSearchBar(false)
.showAddButton(false)
.showEditButton(false)
.iconButtons(true);
regionCRUD.itemToMap_inner2 = region -> {
var examples = conceptsWhere(concepts, Example, item := region);
ret litorderedmap(
"Pixels" := region.bitMatrix == null ? "-" : n2(region.bitMatrix.pixelCount()),
//"Shape" := "TODO",
"Labels" := joinWithComma(map(examples, e -> e.label)),
// TODO: scale using snpsettings
"Position" := region.bitMatrix == null ? "-" : region.bitMatrix.boundingBoxOfTrueBits());
};
var regionCRUDComponent = regionCRUD.visualize();
regionCRUD.onSelectionChanged(l0 updateExampleCRUD);
ret hsplit(
jtabs(
//"Image" := jscroll_centered_borderless(isOriginal),
"Image + regions" := jscroll_centered_borderless(isOriginalWithRegions),
"Posterized" := jscroll_centered_borderless(isPosterized),
),
northAndCenterWithMargin(
analysisPanel,
hsplit(
jCenteredSection("Saved regions", regionCRUDComponent),
scpExampleCRUD)
));
}
void runSnP {
if (itr == null) ret;
itr.run();
regionUpdate();
}
void regionUpdate {
if (itr == null) ret;
var pixels = itr.posterized.getRGBPixels();
// hovering region marked green
g22_highlightRegion(pixels, isPosterized, itr, showRegionsAsOutline);
// selected region marked blue
itr.regions.markRegionInPixelArray(pixels, iSelectedRegion, 0xFFADD8E6);
var highlighted = bufferedImage(pixels, itr.posterized.getWidth(), itr.posterized.getHeight());
isPosterized.setImage(highlighted);
isPosterized.performAutoZoom(); // seems to be necessary for some reason
updateAnalysis();
}
void updateAnalysis {
/*new LS lines;
lines.add(nRegions(itr.regions.regionCount()));
lines.add("Selected region: " + iSelectedRegion);
S text = lines_rtrim(lines);
analysisPanel.setComponent(jLabel(text)));*/
}
void updateExampleCRUD {
var region = regionCRUD.selected();
if (region == null) ret with scpExampleCRUD.clear();
exampleCRUD = new SimpleCRUD_v2(concepts, Example);
exampleCRUD.entityName = -> "label for region";
exampleCRUD.addFilter(item := region);
exampleCRUD.showSearchBar(false);
exampleCRUD.iconButtons(true);
scpExampleCRUD.set(jCenteredSection("Labels for region",
exampleCRUD.visualize()));
}
void importImage {
new JFileChooser fc;
if (fc.showOpenDialog(cbImage) == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile().getAbsoluteFile();
if (!isImageFile(file)) ret with infoMessage("Not an image file");
var img = addToGallery(file);
waitUntil(250, 5.0, -> comboBoxContainsItem(cbImage, img));
setSelectedItem(cbImage, img);
}
}
visual
jRaisedSection(northAndCenterWithMargins(
centerAndEast(withLabel("Study", cbImage),
hstack(
jlabel(" in "),
snpSelector.visualize(),
horizontalStrut(10),
jPopDownButton_noText(
"Import image...", rThreadEnter importImage,
),
)),
scp));
} // end of StudyPanel
void initUIURLs {
uiURLs.put("Main Tabs", ->
horizontalLayout ? withMargin(mainTabs) : withSideMargin(mainTabs));
uiURLs.put("Screen Cam FPS", -> jFullCenter(
vstackWithSpacing(
jCenteredLabel("FPS target (frames per second) for screen cam:"),
jFullCenter(dm_spinner fpsTarget(1, 60)),
jCenteredLabel("(You can lower this value if you have a slower computer)"))));
uiURLs.put("Timings", -> {
JTextArea taTimings = jTextArea_noUndo();
awtEveryAndNow(taTimings, .5, r {
setText(taTimings, renderFunctionTimings())
});
ret withRightAlignedButtons(taTimings,
Reset := r resetTimings);
});
uiURLs.put("Test Screen" := -> testScreenPanel());
//uiURLs.put("Operators" := -> operatorsPanel());
uiURLs.put("Left Arrow Script" := -> leftArrowScriptPanel());
uiURLs.put("Settings" := -> settingsPanel());
uiURLs.put("System Info" := -> systemInfoPanel());
uiURLs.put("Web Cam" := -> webCamPanel());
uiURLs.put("Labels" := -> wrapCRUD("Labels", labelCRUD));
uiURLs.put(WithToolTip("Screen Cam + Linear Script", "Run a simple (linear) Gazelle V script")
:= -> withBottomMargin(scriptRunner.scriptAndResultPanel()));
uiURLs.put(WithToolTip("Left Arrow Script", "Run a \"left-arrow script\"")
:= -> withBottomMargin(leftArrowScriptPanel()));
uiURLs.put("Screen Cam + Script" := -> jOnDemand screenCamPlusScriptPanel());
uiURLs.put(WithToolTip("Gallery CRUD", "Gallery view with more functions (delete etc)")
:= -> wrapCRUD("Images", imageCRUD, imageCRUDVis));
uiURLs.put(WithToolTip("Paint", "Paint a picture for Gazelle with your mouse!")
:= -> withBottomMargin(paintPanel()));
uiURLs.put(WithToolTip("Video", "A little video player (Note: no sound and doesn't handle some videos)")
:= -> withBottomMargin(videoPanel()));
uiURLs.put(WithToolTip("Analyzers", "Manage image analyzers here")
:= -> withBottomMargin(analyzersPanel().visualize()));
uiURLs.put(WithToolTip("Scripts", "Manage all left-arrow scripts here")
:= -> withBottomMargin(scriptsPanel().visualize()));
uiURLs.put("Screen Cam" := -> jOnDemand screenCamPanel())
.put(WithToolTip("Study", "Here you can analyze gallery images")
:= -> withTopAndBottomMargin(studyPanel.visualize()))
.put(WithToolTip("Java", "Write & run actual Java code")
:= -> withBottomMargin(jOnDemand javaPanel()))
.put(WithToolTip("Gallery", "Gallery view with preview images")
:= -> galleryPanel().visualize())
.put(WithToolTip("Challenges", "Gazelle's self-tests")
:= -> challengesPanel())
.put(WithToolTip("Databases", "Choose the Gazelle database to use")
:= -> databasesPanel())
.put(WithToolTip("Entities", "Define entities (meta-level)")
:= -> entitiesPanel())
.put("Local Fonts" := -> localFontsPanel().visualize())
// add ui urls above this line
;
}
transient simplyCached G22LocalFontsPanel localFontsPanel() { ret new G22LocalFontsPanel(g22utils); }
JComponent settingsPanel() {
var cbMinimizeToTray = jCheckBox(isTrue(getOpt(dm_stem(), "minimizeToTray")));
onUpdate(cbMinimizeToTray, -> dm_callStem(me(), "setMinimizeToTray", isChecked(cbMinimizeToTray)));
ret jscroll(makeForm3(
"Minimize to tray", toolTip("Remove Gazelle from task bar when minimized (click Gazelle icon in system tray to reactivate)", cbMinimizeToTray),
"Access web cams", dm_checkBox webCamAccessEnabled(),
));
}
File gazelleJar() {
ret getBytecodePathForClass(this);
}
JComponent systemInfoPanel() {
var gazelleJar = gazelleJar();
var cbMinimizeToTray = jCheckBox(isTrue(getOpt(dm_stem(), "minimizeToTray")));
onUpdate(cbMinimizeToTray, -> dm_callStem(me(), "setMinimizeToTray", isChecked(cbMinimizeToTray)));
// Sadly, even jScrollVertical causes a bug in formLayouter1 that
// makes the form grow horizontally without bounds
ret /*jscrollVertical*/(makeForm3(
"Java Version", jlabel(javaVersion()),
"Gazelle Jar", JFilePathLabel(gazelleJar).visualize(),
"Gazelle Jar Size", str_toMB_oneDigit(fileSize(gazelleJar)),
"Using Custom Classloader", yesNoShort(usingStarter(mc())),
"Compilation Date", jlabel(or2(loadTextFileResource(classLoader(this), "compilation-date.txt"), "unknown")),
"Gazelle Count" := toolTip("How many Gazelles are running in the world",
jLiveValueLabel((LiveValue) dm_callOSOpt lvComputerCount())),
"Gazelle Database" := JFilePathLabel(concepts.conceptsFile()).visualize(),
"Gazelle Database Size" := str_toKB(fileSize(concepts.conceptsFile())),
"Self-Tests" := jlabel(selfTests == null ? "Not run" : selfTests.status()),
));
}
JComponent operatorsPanel() {
ret jcenteredlabel("TODO");
}
JLeftArrowScriptIDE leftArrowScriptIDE() {
var ide = g22utils.leftArrowIDE();
ide.withResultPanel();
ret ide;
}
void modifyLeftArrowParser(GazelleV_LeftArrowScriptParser parser) {
parser.allowTheWorld(me(), mc(), utils.class, g22utils);
}
JComponent leftArrowScriptPanel() {
var ide = leftArrowScriptIDE();
ide.lvScript(dm_fieldLiveValue newScript());
ret ide.visualize();
}
JComponent javaPanel() enter {
var scpResult = singleComponentPanel();
new JMiniJavaIDE ide;
ide.stringifier(g22utils.stringifier);
ide.extraClassMembers = script -> {
LS tok = javaTok(script);
if (contains(tok, "draw")) ret [[
import java.awt.*;
import java.awt.image.*;
interface SimpleRenderable {
void renderOn(Graphics2D g);
}
static BufferedImage draw(int w, int h, SimpleRenderable r) {
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = img.createGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, w, h);
g.setColor(Color.black);
r.renderOn(g);
return img;
}
]];
ret "";
};
ide.callCompiledObject = o -> {
O result = ide.callCompiledObject_base(o);
if (result cast BufferedImage)
scpResult.set(jscroll_centered_borderless(stdImageSurface(result)));
ret result;
};
ide.lvScript(dm_fieldLiveValue javaCode());
ret jhsplit(
jCenteredSection("Image will show here", scpResult),
ide.visualize());
}
JComponent webCamPanel() {
if (cbWebCam == null) {
var cams = listWebCams();
cbWebCam = jTypedComboBox(cams,
findWebCamByName(cams, webCamName));
}
if (scpWebCamImage == null) scpWebCamImage = singleComponentPanel();
ret northAndCenterWithMargins(
centerAndEastWithMargin(
withLabel("Cam", cbWebCam),
jline(
jbutton("Start", rThreadEnter startWebCam),
jbutton("Stop", rThreadEnter stopWebCam)
)),
scpWebCamImage);
}
void stopWebCam {
if (webCamPanel != null) {
webCamPanel.stop();
webCamPanel = null;
scpWebCamImage?.clear();
backgroundProcessesUI.remove(bgWebCam);
}
}
void startWebCam {
temp tempInfoBox("Starting Web Cam");
stopWebCam();
var cam = getSelectedItem_typed(cbWebCam);
setField(webCamName := cam?.getName());
if (cam != null) {
scpWebCamImage.set(webCamPanel = new WebcamPanel(cam, true));
backgroundProcessesUI.add(bgWebCam);
}
}
void forgetMissingImages {
int n = l(deleteConcepts(GalleryImage, img -> !img.imageExists()));
infoBox(n == 0 ? "Nothing to forget" : "Forgot " + nImages(n));
}
void addUIURLToMainTabs(S url) swing {
if (containsTabNameWithoutTrailingCount(mainTabs, url)) ret;
if (!uiURLs.hasURL(url)) ret with print("URL not found: " + url);
addTab(mainTabs, WithToolTip(uiURLs.toolTipForURL(url), url),
uiURLs.renderUIURL(url));
}
void showScreenCam() { showUIURL("Screen Cam"); }
void showWebCam() { showUIURL("Web Cam"); }
JComponent challengesPanel() {
if (challengesPanel == null)
challengesPanel = new G22ChallengesPanel().g22utils(g22utils);
ret challengesPanel.visualize();
}
class GalleryPanel is Swingable {
cachedVisualize {
var galleryImageSurface = stdImageSurface();
var gallery = new JGallery;
gallery.horizontal(false);
gallery.imageLoader().imageHeight(50);
new AWTOnConceptChangesByClass(concepts, GalleryImage, gallery.visualize(), -> {
var l = sortFilesAlphaNumIC(map(list(GalleryImage), i -> i.path));
gallery.setImageFiles(l);
updateEnclosingTabTitleWithCount(gallery.visualize(), l(l));
}).install();
var analysisPanel = new G22AnalysisPanel;
analysisPanel.editAnalyzer = l1 editAnalyzer;
analysisPanel.g22utils(g22utils).imageSurface(galleryImageSurface);
ownResource(analysisPanel);
main onChange(analysisPanel, me());
gallery.openImage = img -> {
galleryImageSurface.loadImage(img);
analysisPanel.setImage(img);
};
ret withBottomMargin(
jvsplit(0.75,
jhsplit(0.25,
jCenteredSection("All Images", gallery.visualize()),
jRaisedCenteredSection("Selected Image",
withRightAlignedButtons(galleryImageSurface.visualize(),
"Gallery CRUD" := r { showUIURL("Gallery CRUD") }
)
)
),
analysisPanel.visualize()
));
}
}
transient simplyCached GalleryPanel galleryPanel() { ret new GalleryPanel; }
JComponent entitiesPanel() {
if (entityCRUD == null)
entityCRUD = new SimpleCRUD_v2(concepts, Entity);
ret wrapCRUD("Entities", entityCRUD);
}
// for scripts
Gazelle22_ImageToRegions imageToRegions(BufferedImage inputImage, SnPSettings snpSettings) {
ret new Gazelle22_ImageToRegions(functionTimings, inputImage, snpSettings);
}
JComponent databasesPanel() {
ret new G22DatabasesPanel(g22utils, concepts).visualize();
}
transient simplyCached JComponent paintPanel() {
if (paintToolGallery == null) {
paintToolGallery = JGallery().horizontal(false);
paintToolGallery.openImage = img -> paintTool.loadImageProtected(img);
paintToolGallery.imageLoader().imageHeight(50);
new AWTOnConceptChangesByClass(concepts, GalleryImage, paintToolGallery.visualize(), -> {
var images = galleryImagesIn(conceptsDir(concepts));
print("Paint tool images: " + l(images));
paintToolGallery.setImageFiles(sortFilesAlphaNumIC(images));
}).install();
}
if (paintTool == null) paintTool(new JPaintTool);
ownResource(paintTool);
main onChange(paintTool, me());
paintTool.createAutoPersistFile =
-> makeFileNameUnique_beforeExtension_startWith1_noDot(conceptsDir("Painting.png"));
var paintToolVis = paintTool.visualize();
// migrating between directories - just make a new file
if (!isDeepContainedInDir_canonical(paintTool.autoPersistFile(), conceptsDir(concepts)))
paintTool.newImage();
new JG22Labels labelsView;
paintTool.bottomLeftControls = -> labelsView.visualize();
paintTool.varAutoPersistFile().onChangeAndNow(imageFile -> {
labelsView.setLabels(g22utils.labelsForFile(imageFile));
paintToolGallery.selectFile(imageFile);
});
labelsView.addLabel = text -> {
var imageFile = paintTool.autoPersistFile();
var labels = g22utils.labelsForFile(imageFile);
labels.add(g22utils.getLabel(text));
print(+labels);
g22utils.setLabelsForFile(imageFile, labels);
labelsView.setLabels(labels);
};
labelsView.removeLabel = label -> {
var imageFile = paintTool.autoPersistFile();
var labels = g22utils.labelsForFile(imageFile);
labels = listWithout(labels, label);
g22utils.setLabelsForFile(imageFile, labels);
labelsView.setLabels(labels);
};
paintAnalysisPanel if null = new G22AnalysisPanel;
paintAnalysisPanel.editAnalyzer = l1 editAnalyzer;
paintAnalysisPanel.g22utils(g22utils).imageSurface(paintTool.imageSurface());
ownResource(paintAnalysisPanel);
main onChange(paintAnalysisPanel, me());
paintTool.onImageChanged(img -> paintAnalysisPanel.setImage(img));
paintAnalysisPanel.setImage(paintTool.getImage());
var collapsiblePanel = CollapsibleLeftPanel(false, "Paintings",
paintToolGallery.visualize(), paintToolVis);
linkVars(varPaintToolGalleryExpanded(), collapsiblePanel.varExpanded());
paintToolGallery.varFiles().onChangeAndNow(files -> collapsiblePanel.sidePanelName(n2(files, "Painting")));
ret jvsplit(0.75,
collapsiblePanel.visualize(),
jRaisedCenteredSection("Image Analysis", paintAnalysisPanel.visualize()));
}
JComponent videoPanel() {
if (videoLibDownloader == null)
videoLibDownloader = new JVideoLibDownloader()
.forward(-> videoPlayer().visualize());
ret videoLibDownloader.visualize();
}
JFFMPEGVideoPlayer videoPlayer() {
if (videoPlayer == null)
videoPlayer = new JFFMPEGVideoPlayer;
ret videoPlayer;
}
transient simplyCached G22AnalyzersPanel analyzersPanel() {
ret new G22AnalyzersPanel(g22utils);
}
transient simplyCached G22ScriptsPanel scriptsPanel() {
ret new G22ScriptsPanel(g22utils);
}
Cl galleryImagesIn(File dir) {
ret mapNonNulls(list(GalleryImage),
i -> isDeepContainedInDir_absolute(i.path, dir) ? i.path : null);
}
void editAnalyzer(G22Recognizer analyzer) {
if (analyzer == null) ret;
analyzersPanel().edit(analyzer);
showUIURL("Analyzers");
}
O inlineScript(int scriptID, VarContext varContext) { ret inlineScript((long) scriptID, varContext); }
O inlineScript(long scriptID, VarContext varContext) {
var script = getConcept(G22LeftArrowScript, scriptID);
if (script == null) fail("Script ID " + scriptID + " not found");
GazelleV_LeftArrowScript.Script parsedScript = script.compileSaved().parsedScript;
ret parsedScript.get(varContext);
}
} // end of module
concept GalleryImage {
File path;
toString { ret /*"[" + id + "] " +*/ fileName(path); }
bool imageExists() { ret fileExists(path); }
}
concept SavedRegion {
new Ref image; // e.g. a GalleryImage
SnPSettings snpSettings;
int regionIndex; // region number relative to snpSettings
//Rect bounds; // get it from bitMatrix instead
ScanlineBitMatrix bitMatrix;
//new RefL labels;
}
concept Example {
new Ref label;
new Ref item; // e.g. a SavedRegion
double confidence = 1;
}
concept IfThenTheory {
new Ref if_;
new Ref then;
}
asclass WatchTarget {
void mainWindow(Window window) {}
abstract void configureScreenCamStream(ScreenCamStream stream);
}
// screenNr: 1 = screen 1 etc
srecord WatchScreen(int screenNr) > WatchTarget {
toString { ret "Screen " + screenNr; }
void configureScreenCamStream(ScreenCamStream stream) {
stream.useScreen(screenNr-1);
}
}
srecord WatchMouse(int width, int height) > WatchTarget {
WatchMouse() {
height = 256;
width = iround(height*16.0/9);
}
toString { ret "Mouse"; }
void configureScreenCamStream(ScreenCamStream stream) {
stream.area(mouseArea(width, height));
}
}
srecord WatchScreenWithMouse > WatchTarget {
toString { ret "Screen w/mouse"; }
void configureScreenCamStream(ScreenCamStream stream) {
stream.useScreen(screenNrContaining(mouseLocationPt()));
}
}
// Screen where Gazelle window is not
srecord WatchOtherScreen > WatchTarget {
toString { ret "Other Screen"; }
transient void settable Window mainWindow;
void configureScreenCamStream(ScreenCamStream stream) {
stream.useScreen(mod(screenNrOfWindow(mainWindow)+1, numberOfScreens()));
}
}
!include once #1034593 // Entity etc.