-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
237 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
org.mbari.vars.ui/src/main/java/org/mbari/vars/ui/commands/CreateAssociationsCmd.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 80 additions & 0 deletions
80
org.mbari.vars.ui/src/main/java/org/mbari/vars/ui/javafx/buttons/NewBoundingBoxBC.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package org.mbari.vars.ui.javafx.buttons; | ||
|
||
import javafx.collections.ListChangeListener; | ||
import javafx.scene.control.Button; | ||
import javafx.scene.text.Text; | ||
import org.mbari.vars.services.model.Annotation; | ||
import org.mbari.vars.services.model.Association; | ||
import org.mbari.vars.services.model.Media; | ||
import org.mbari.vars.ui.UIToolBox; | ||
import org.mbari.vars.ui.commands.CreateAssociationsCmd; | ||
import org.mbari.vars.ui.javafx.Icons; | ||
import org.mbari.vars.ui.mediaplayers.sharktopoda2.LocalizedAnnotation; | ||
import org.mbari.vcr4j.remote.control.commands.localization.Localization; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.UUID; | ||
|
||
public class NewBoundingBoxBC extends AbstractBC { | ||
|
||
public NewBoundingBoxBC(Button button, UIToolBox toolBox) { | ||
super(button, toolBox); | ||
} | ||
|
||
@Override | ||
protected void apply() { | ||
var selectedAnnotations = new ArrayList<>(toolBox.getData().getSelectedAnnotations()); | ||
if (selectedAnnotations.size() == 1) { | ||
var annotation = selectedAnnotations.get(0); | ||
var media = toolBox.getData().getMedia(); | ||
if (canLocalize(media, annotation)) { | ||
var association = toAssociation(annotation, media); | ||
association.resetUuid(); | ||
toolBox.getEventBus().send(new CreateAssociationsCmd(association, List.of(annotation))); | ||
} | ||
} | ||
} | ||
|
||
private boolean canLocalize(Media media, Annotation annotation) { | ||
return media != null | ||
&& media.getWidth() != null | ||
&& media.getHeight() != null | ||
&& annotation.getElapsedTime() != null | ||
&& annotation.getVideoReferenceUuid().equals(media.getVideoReferenceUuid()); | ||
} | ||
|
||
private Association toAssociation(Annotation annotation, Media media) { | ||
var w = media.getWidth(); | ||
var h = media.getHeight(); | ||
int width = (int) Math.round(w * 0.1); | ||
int height = (int) Math.round(h * 0.1); | ||
int x = (int) Math.round((w / 2.0) - (width / 2.0)); | ||
int y = (int) Math.round((h / 2.0) - (height / 2.0)); | ||
var duration = annotation.getDuration() == null ? null : annotation.getDuration().toMillis(); | ||
var localization = new Localization(UUID.randomUUID(), | ||
annotation.getConcept(), | ||
annotation.getElapsedTime().toMillis(), | ||
duration, | ||
x, y, width, height, null); | ||
return LocalizedAnnotation.toAssociation(localization); | ||
} | ||
|
||
@Override | ||
protected void init() { | ||
String tooltip = toolBox.getI18nBundle().getString("buttons.boundingbox"); | ||
Text icon = Icons.FORMAT_SHAPES.standardSize(); | ||
initializeButton(tooltip, icon); | ||
var selectedAnnotations = toolBox.getData().getSelectedAnnotations(); | ||
selectedAnnotations | ||
.addListener((ListChangeListener<Annotation>) c -> { | ||
var disable = true; | ||
if (selectedAnnotations.size() == 1) { | ||
var head = selectedAnnotations.get(0); | ||
var media = toolBox.getData().getMedia(); | ||
disable = !canLocalize(media, head); | ||
} | ||
button.setDisable(disable); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 25 additions & 1 deletion
26
...i.vars.ui/src/main/java/org/mbari/vars/ui/mediaplayers/sharktopoda2/LocalizationPair.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,37 @@ | ||
package org.mbari.vars.ui.mediaplayers.sharktopoda2; | ||
|
||
import org.mbari.vars.services.model.Annotation; | ||
import org.mbari.vars.ui.UIToolBox; | ||
import org.mbari.vcr4j.remote.control.commands.localization.Localization; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* When the remote video player sends a command to update, select, or delete a localization to VARS, | ||
* the localization's UUID corresponds to an existing Association. We then have to match the | ||
* localization to the assocation and it's parent annotations. This container holds all three of those. | ||
* @param localizedAnnotation The Annotation and association corresponding to a localization | ||
* @param localization The localization send from the video app to VARS | ||
*/ | ||
public record LocalizationPair(LocalizedAnnotation localizedAnnotation, Localization localization) { | ||
public record LocalizationPair(LocalizedAnnotation localizedAnnotation, | ||
Localization localization) implements Comparable<LocalizationPair> { | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (obj instanceof LocalizationPair that) { | ||
return this.localization.getUuid().equals(that.localization.getUuid()); | ||
} | ||
return false; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return localization.getUuid().hashCode(); | ||
} | ||
|
||
@Override | ||
public int compareTo(LocalizationPair that) { | ||
return this.localization.getUuid().compareTo(that.localization.getUuid()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 80 additions & 11 deletions
91
...i.vars.ui/src/main/java/org/mbari/vars/ui/mediaplayers/sharktopoda2/SharktopodaState.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,103 @@ | ||
package org.mbari.vars.ui.mediaplayers.sharktopoda2; | ||
|
||
import org.mbari.vars.services.model.Annotation; | ||
import org.mbari.vars.ui.UIToolBox; | ||
import org.mbari.vcr4j.remote.control.RVideoIO; | ||
import org.mbari.vcr4j.sharktopoda.client.localization.Localization; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.UUID; | ||
import java.util.*; | ||
import java.util.concurrent.CopyOnWriteArrayList; | ||
|
||
public class SharktopodaState { | ||
|
||
private final List<UUID> selectedLocalizations = new CopyOnWriteArrayList<>(); | ||
// private final List<UUID> selectedLocalizations = new CopyOnWriteArrayList<>(); | ||
|
||
public void setSelectedLocalizations(Collection<UUID> selectedLocalizations) { | ||
private final List<LocalizationPair> selectedLocalizations = new CopyOnWriteArrayList<>(); | ||
|
||
private final Map<UUID, LocalizationPair> localizations = new HashMap<>(); | ||
|
||
public void setSelectedLocalizations(Collection<LocalizationPair> selectedLocalizations) { | ||
synchronized (this.selectedLocalizations) { | ||
this.selectedLocalizations.clear(); | ||
this.selectedLocalizations.addAll(selectedLocalizations); | ||
} | ||
} | ||
|
||
public void clear() { | ||
selectedLocalizations.clear(); | ||
localizations.clear(); | ||
} | ||
|
||
public void addLocalizationPairs(Collection<LocalizationPair> pairs) { | ||
pairs.forEach(this::addLocalizationPair); | ||
} | ||
|
||
public void addLocalizationPair(LocalizationPair localizationPair) { | ||
localizations.put(localizationPair.localization().getUuid(), localizationPair); | ||
} | ||
|
||
public void removeLocalizationPairs(Collection<LocalizationPair> pairs) { | ||
pairs.forEach(p -> removeLocalizationPair(p.localization().getUuid())); | ||
} | ||
|
||
public void removeLocalizationPair(UUID localizationUuid) { | ||
localizations.remove(localizationUuid); | ||
} | ||
|
||
|
||
public boolean isDifferentThanSelected(Collection<UUID> localizations) { | ||
var isDiff = true; | ||
if (!localizations.isEmpty() && !selectedLocalizations.isEmpty()) { | ||
if (localizations.isEmpty() && selectedLocalizations.isEmpty()) { | ||
return false; | ||
} | ||
else if (!localizations.isEmpty() && !selectedLocalizations.isEmpty()) { | ||
var copy = new ArrayList<>(localizations); | ||
var copySelected = new ArrayList<>(selectedLocalizations); | ||
var copySelected = selectedLocalizations.stream().map(lp -> lp.localization().getUuid()).toList(); | ||
if (copy.size() == copySelected.size()) { | ||
copy.removeAll(copySelected); | ||
isDiff = copy.size() != 0; | ||
return copy.size() != 0; | ||
} | ||
} | ||
return isDiff; | ||
return true; | ||
} | ||
|
||
public static List<LocalizationPair> from(Annotation a, UIToolBox toolBox) { | ||
return LocalizedAnnotation.from(a) | ||
.stream() | ||
.flatMap(la -> la.toLocalization(toolBox).map(loc -> new LocalizationPair(la, loc)).stream()) | ||
.toList(); | ||
} | ||
|
||
public static List<LocalizationPair> from(Collection<Annotation> xs, UIToolBox toolBox) { | ||
return xs.stream() | ||
.flatMap(a -> SharktopodaState.from(a, toolBox).stream()) | ||
.toList(); | ||
} | ||
|
||
// TODO MOve this to static shared method for reuse | ||
// public static void addLocalization(Collection<Annotation> annotations, UIToolBox toolBox) { | ||
// var head = annotations.iterator().next(); | ||
// var ass = addedAssociations.iterator().next(); | ||
// var io = toolBox.getMediaPlayer().getVideoIO(); | ||
// if (io instanceof RVideoIO rio) { | ||
// var la = new LocalizedAnnotation(head, ass); | ||
// var opt = la.toLocalization(toolBox); | ||
// opt.ifPresent(loc -> { | ||
// rio.send(new AddLocalizationsCmd(rio.getUuid(), List.of(loc))); | ||
// }); | ||
// } | ||
// } | ||
// | ||
// // TODO MOve this to static shared method for reuse | ||
// public static void removeLocalization(Collection<Annotation> originalAnnotations, UIToolBox toolBox) { | ||
// var head = originalAnnotations.iterator().next(); | ||
// var ass = addedAssociations.iterator().next(); | ||
// var io = toolBox.getMediaPlayer().getVideoIO(); | ||
// if (io instanceof RVideoIO rio) { | ||
// var la = new LocalizedAnnotation(head, ass); | ||
// var opt = la.toLocalization(toolBox); | ||
// opt.ifPresent(loc -> { | ||
// rio.send(new RemoveLocalizationsCmd(rio.getUuid(), List.of(loc.getUuid()))); | ||
// }); | ||
// } | ||
// } | ||
} |
Oops, something went wrong.