diff --git a/client/src/main/java/ctbrec/ui/controls/SearchPopoverTreeList.java b/client/src/main/java/ctbrec/ui/controls/SearchPopoverTreeList.java index a08cff65..01d421e7 100644 --- a/client/src/main/java/ctbrec/ui/controls/SearchPopoverTreeList.java +++ b/client/src/main/java/ctbrec/ui/controls/SearchPopoverTreeList.java @@ -44,6 +44,7 @@ import ctbrec.GlobalThreadPool; import ctbrec.Model; import ctbrec.recorder.Recorder; import ctbrec.ui.action.PlayAction; +import ctbrec.ui.action.SetThumbAsPortraitAction; import ctbrec.ui.menu.ModelMenuContributor; import javafx.application.Platform; import javafx.concurrent.Task; @@ -56,6 +57,7 @@ import javafx.scene.control.ContextMenu; import javafx.scene.control.Label; import javafx.scene.control.ListCell; import javafx.scene.control.ListView; +import javafx.scene.control.MenuItem; import javafx.scene.control.Skin; import javafx.scene.image.Image; import javafx.scene.image.ImageView; @@ -144,7 +146,7 @@ public class SearchPopoverTreeList extends PopoverTreeList implements Pop private Label title = new Label(); private Button follow; - private Button record; + private Button startRecording; private Model model; private ImageView thumb = new ImageView(); private int thumbSize = 64; @@ -156,17 +158,16 @@ public class SearchPopoverTreeList extends PopoverTreeList implements Pop setSkin(this); getStyleClass().setAll("search-tree-list-cell"); setOnMouseClicked(this); - setOnMouseEntered(evt -> { - getStyleClass().add(highlightClass); - }); - setOnMouseExited(evt -> { - getStyleClass().remove(highlightClass); - }); + setOnMouseEntered(evt -> getStyleClass().add(highlightClass)); + setOnMouseExited(evt -> getStyleClass().remove(highlightClass)); addEventHandler(ContextMenuEvent.CONTEXT_MENU_REQUESTED, event -> { popup = new CustomMouseBehaviorContextMenu(); ModelMenuContributor.newContributor(this, Config.getInstance(), recorder) // .withStartStopCallback(m -> setCursor(Cursor.DEFAULT)) // .contributeToMenu(List.of(model), popup); + var useImageAsPortrait = new MenuItem("Use As Portrait"); + useImageAsPortrait.setOnAction(e -> new SetThumbAsPortraitAction(this, model, thumb.getImage()).execute()); + popup.getItems().add(useImageAsPortrait); popup.show(this, event.getScreenX(), event.getScreenY()); event.consume(); }); @@ -198,6 +199,9 @@ public class SearchPopoverTreeList extends PopoverTreeList implements Pop protected void done() { try { get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + LOG.warn("Search failed: {}", e.getMessage()); } catch (Exception e) { LOG.warn("Search failed: {}", e.getMessage()); } @@ -205,8 +209,8 @@ public class SearchPopoverTreeList extends PopoverTreeList implements Pop } }); }); - record = new Button("Record"); - record.setOnAction(evt -> { + startRecording = new Button("Record"); + startRecording.setOnAction(evt -> { setCursor(Cursor.WAIT); GlobalThreadPool.submit(new Task() { @Override @@ -221,9 +225,9 @@ public class SearchPopoverTreeList extends PopoverTreeList implements Pop } }); }); - getChildren().addAll(thumb, title, follow, record); + getChildren().addAll(thumb, title, follow, startRecording); - record.visibleProperty().bind(title.visibleProperty()); + startRecording.visibleProperty().bind(title.visibleProperty()); thumb.visibleProperty().bind(title.visibleProperty()); } @@ -284,10 +288,10 @@ public class SearchPopoverTreeList extends PopoverTreeList implements Pop follow.setLayoutY((h - buttonH) / 2); follow.resize(buttonW, buttonH); - record.setStyle("-fx-font-size: 10px;"); - record.setLayoutX(w - 10); - record.setLayoutY((h - buttonH) / 2); - record.resize(buttonW, buttonH); + startRecording.setStyle("-fx-font-size: 10px;"); + startRecording.setLayoutX(w - 10); + startRecording.setLayoutY((h - buttonH) / 2); + startRecording.resize(buttonW, buttonH); } @Override diff --git a/client/src/main/java/ctbrec/ui/tabs/recorded/AbstractRecordedModelsTab.java b/client/src/main/java/ctbrec/ui/tabs/recorded/AbstractRecordedModelsTab.java index 129fb44f..4dc1977c 100644 --- a/client/src/main/java/ctbrec/ui/tabs/recorded/AbstractRecordedModelsTab.java +++ b/client/src/main/java/ctbrec/ui/tabs/recorded/AbstractRecordedModelsTab.java @@ -9,7 +9,6 @@ import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; @@ -23,6 +22,7 @@ import com.google.common.cache.LoadingCache; import com.google.common.eventbus.Subscribe; import ctbrec.Config; +import ctbrec.GlobalThreadPool; import ctbrec.Model; import ctbrec.StringUtil; import ctbrec.event.EventBusHolder; @@ -229,13 +229,13 @@ public abstract class AbstractRecordedModelsTab extends Tab implements TabSelect TableColumn portrait = addTableColumn("portrait", "Portrait", columnIdx, 80); portrait.setCellValueFactory(param -> { Model mdl = param.getValue().getDelegate(); - Image image = null; - try { - image = portraitCache.get(mdl); - } catch (ExecutionException e) { - LOG.error("Error while loading portrait from cache for {}", mdl, e); + SimpleObjectProperty imgProperty = new SimpleObjectProperty<>(); + Image image = portraitCache.getIfPresent(mdl); + if (image == null) { + GlobalThreadPool.submit(() -> portraitCache.put(mdl, loadModelPortrait(mdl))); } - return new SimpleObjectProperty(image); + imgProperty.set(image); + return imgProperty; }); portrait.setCellFactory(param -> new ImageTableCell()); portrait.setEditable(false);