Add more model group relatedfunctionality
This commit is contained in:
parent
bcf4ab1d47
commit
bc72aca69e
|
@ -3,9 +3,12 @@ package ctbrec.ui;
|
|||
public enum Icon {
|
||||
|
||||
BLANK_16(Icon.class.getResource("/16/blank.png").toExternalForm()),
|
||||
GROUP_16(Icon.class.getResource("/16/users.png").toExternalForm()),
|
||||
BOOKMARK_16(Icon.class.getResource("/16/bookmark-new.png").toExternalForm()),
|
||||
CHECK_16(Icon.class.getResource("/16/check-small.png").toExternalForm()),
|
||||
CLOCK_16(Icon.class.getResource("/16/clock.png").toExternalForm());
|
||||
CLOCK_16(Icon.class.getResource("/16/clock.png").toExternalForm()),
|
||||
GROUP_16(Icon.class.getResource("/16/users.png").toExternalForm()),
|
||||
MEDIA_PLAYBACK_PAUSE_16(Icon.class.getResource("/16/media-playback-pause.png").toExternalForm()),
|
||||
MEDIA_RECORD_16(Icon.class.getResource("/16/media-record.png").toExternalForm());
|
||||
|
||||
private String url;
|
||||
|
||||
|
|
|
@ -85,7 +85,6 @@ public class AddToGroupAction {
|
|||
}
|
||||
|
||||
void requestFocus() {
|
||||
System.err.println("request focus");
|
||||
editor.requestFocus();
|
||||
editor.positionCaret(0);
|
||||
editor.selectAll();
|
||||
|
|
|
@ -103,8 +103,9 @@ public class EditGroupAction {
|
|||
groupName = new TextField(modelGroup.getName());
|
||||
var up = createUpButton();
|
||||
var down = createDownButton();
|
||||
var add = createAddButton();
|
||||
var remove = createRemoveButton();
|
||||
var buttons = new VBox(3, up, down, remove);
|
||||
var buttons = new VBox(3, up, down, add, remove);
|
||||
urlList = FXCollections.observableList(modelGroup.getModelUrls());
|
||||
urlList.addListener((ListChangeListener<String>) change -> urls = new ArrayList<>(urlList));
|
||||
urlListView = new ListView<>(urlList);
|
||||
|
@ -126,7 +127,7 @@ public class EditGroupAction {
|
|||
}
|
||||
|
||||
private Button createUpButton() {
|
||||
var button = createButton("\u25B4", "Move step up");
|
||||
var button = createButton("\u25B4", "Move up");
|
||||
button.setOnAction(evt -> {
|
||||
int idx = urlListView.getSelectionModel().getSelectedIndex();
|
||||
String selectedItem = urlListView.getSelectionModel().getSelectedItem();
|
||||
|
@ -138,7 +139,7 @@ public class EditGroupAction {
|
|||
}
|
||||
|
||||
private Button createDownButton() {
|
||||
var button = createButton("\u25BE", "Move step down");
|
||||
var button = createButton("\u25BE", "Move down");
|
||||
button.setOnAction(evt -> {
|
||||
int idx = urlListView.getSelectionModel().getSelectedIndex();
|
||||
String selectedItem = urlListView.getSelectionModel().getSelectedItem();
|
||||
|
@ -149,8 +150,15 @@ public class EditGroupAction {
|
|||
return button;
|
||||
}
|
||||
|
||||
private Button createAddButton() {
|
||||
var button = createButton("+", "Add selected URL");
|
||||
button.setDisable(false);
|
||||
button.setOnAction(evt -> Dialogs.showTextInput(getScene(), "Add URL", "Add new model URL", "").ifPresent(urlList::add));
|
||||
return button;
|
||||
}
|
||||
|
||||
private Button createRemoveButton() {
|
||||
var button = createButton("-", "Remove selected step");
|
||||
var button = createButton("-", "Remove selected URL");
|
||||
button.setOnAction(evt -> {
|
||||
String selectedItem = urlListView.getSelectionModel().getSelectedItem();
|
||||
if (selectedItem != null) {
|
||||
|
|
|
@ -50,13 +50,13 @@ public class ModelGroupMenuBuilder {
|
|||
var editGroup = new MenuItem("Edit group");
|
||||
editGroup.setOnAction(e -> new EditGroupAction(source, recorder, model).execute(callback));
|
||||
|
||||
var resumeAllOfGroup = new MenuItem("Resume all");
|
||||
var resumeAllOfGroup = new MenuItem("Resume all in group");
|
||||
resumeAllOfGroup.setOnAction(e -> new ResumeGroupAction(source, recorder, model).execute(callback));
|
||||
|
||||
var pauseAllOfGroup = new MenuItem("Pause all");
|
||||
var pauseAllOfGroup = new MenuItem("Pause all in group");
|
||||
pauseAllOfGroup.setOnAction(e -> new PauseGroupAction(source, recorder, model).execute(callback));
|
||||
|
||||
var stopAllOfGroup = new MenuItem("Remove all");
|
||||
var stopAllOfGroup = new MenuItem("Stop all in group");
|
||||
stopAllOfGroup.setOnAction(e -> new StopGroupAction(source, recorder, model).execute(callback));
|
||||
|
||||
menu.getItems().addAll(editGroup, resumeAllOfGroup, pauseAllOfGroup, stopAllOfGroup);
|
||||
|
|
|
@ -56,9 +56,9 @@ import ctbrec.ui.controls.CustomMouseBehaviorContextMenu;
|
|||
import ctbrec.ui.controls.DateTimeCellFactory;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import ctbrec.ui.controls.Toast;
|
||||
import ctbrec.ui.tabs.recorded.RecordedModelsTab.ModelName;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.concurrent.ScheduledService;
|
||||
|
@ -136,10 +136,13 @@ public class RecordingsTab extends Tab implements TabSelectionListener, Shutdown
|
|||
|
||||
table.setEditable(false);
|
||||
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
|
||||
TableColumn<JavaFxRecording, String> name = new TableColumn<>("Model");
|
||||
TableColumn<JavaFxRecording, ModelName> name = new TableColumn<>("Model");
|
||||
name.setId("name");
|
||||
name.setPrefWidth(200);
|
||||
name.setCellValueFactory(cdf -> new SimpleStringProperty(cdf.getValue().getModel().getName()));
|
||||
name.setCellValueFactory(param -> {
|
||||
var modelName = new ModelName(param.getValue().getModel(), recorder);
|
||||
return new SimpleObjectProperty<>(modelName);
|
||||
});
|
||||
TableColumn<JavaFxRecording, Instant> date = new TableColumn<>("Date");
|
||||
date.setId("date");
|
||||
date.setCellValueFactory(cdf -> {
|
||||
|
@ -663,23 +666,27 @@ public class RecordingsTab extends Tab implements TabSelectionListener, Shutdown
|
|||
}
|
||||
|
||||
private void download(Recording recording) {
|
||||
LOG.debug("Path {}", recording.getAbsoluteFile());
|
||||
String filename = proposeTargetFilename(recording);
|
||||
var chooser = new FileChooser();
|
||||
chooser.setInitialFileName(filename);
|
||||
if (config.getSettings().lastDownloadDir != null && !config.getSettings().lastDownloadDir.equals("")) {
|
||||
var dir = new File(config.getSettings().lastDownloadDir);
|
||||
while (!dir.exists()) {
|
||||
dir = dir.getParentFile();
|
||||
try {
|
||||
LOG.debug("Path {}", recording.getAbsoluteFile());
|
||||
String filename = proposeTargetFilename(recording);
|
||||
var chooser = new FileChooser();
|
||||
chooser.setInitialFileName(filename);
|
||||
if (config.getSettings().lastDownloadDir != null && !config.getSettings().lastDownloadDir.equals("")) {
|
||||
var dir = new File(config.getSettings().lastDownloadDir);
|
||||
while (!dir.exists()) {
|
||||
dir = dir.getParentFile();
|
||||
}
|
||||
chooser.setInitialDirectory(dir);
|
||||
}
|
||||
chooser.setInitialDirectory(dir);
|
||||
}
|
||||
File target = chooser.showSaveDialog(null);
|
||||
if (target != null) {
|
||||
config.getSettings().lastDownloadDir = target.getParent();
|
||||
startDownloadThread(target, recording);
|
||||
recording.setStatus(DOWNLOADING);
|
||||
recording.setProgress(0);
|
||||
File target = chooser.showSaveDialog(null);
|
||||
if (target != null) {
|
||||
config.getSettings().lastDownloadDir = target.getParent();
|
||||
startDownloadThread(target, recording);
|
||||
recording.setStatus(DOWNLOADING);
|
||||
recording.setProgress(0);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package ctbrec.ui.tabs;
|
|||
|
||||
import static ctbrec.Model.State.*;
|
||||
import static ctbrec.io.HttpConstants.*;
|
||||
import static ctbrec.ui.Icon.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
@ -10,6 +11,7 @@ import java.util.concurrent.CompletableFuture;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -21,13 +23,14 @@ import com.google.common.cache.LoadingCache;
|
|||
import ctbrec.Config;
|
||||
import ctbrec.GlobalThreadPool;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.Model.State;
|
||||
import ctbrec.io.HttpException;
|
||||
import ctbrec.recorder.Recorder;
|
||||
import ctbrec.ui.AutosizeAlert;
|
||||
import ctbrec.ui.CamrecApplication;
|
||||
import ctbrec.ui.Icon;
|
||||
import ctbrec.ui.SiteUiFactory;
|
||||
import ctbrec.ui.StreamSourceSelectionDialog;
|
||||
import ctbrec.ui.action.EditGroupAction;
|
||||
import ctbrec.ui.action.PlayAction;
|
||||
import ctbrec.ui.controls.Dialogs;
|
||||
import ctbrec.ui.controls.RecordingIndicator;
|
||||
|
@ -47,6 +50,7 @@ import javafx.scene.Cursor;
|
|||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
|
@ -72,9 +76,10 @@ public class ThumbCell extends StackPane {
|
|||
private static final Logger LOG = LoggerFactory.getLogger(ThumbCell.class);
|
||||
private static final Duration ANIMATION_DURATION = new Duration(250);
|
||||
|
||||
private static Image imgRecordIndicator = new Image(ThumbCell.class.getResource("/media-record-16.png").toExternalForm());
|
||||
private static Image imgPauseIndicator = new Image(ThumbCell.class.getResource("/media-playback-pause-16.png").toExternalForm());
|
||||
private static Image imgBookmarkIndicator = new Image(ThumbCell.class.getResource("/bookmark-new-16.png").toExternalForm());
|
||||
private static Image imgRecordIndicator = new Image(MEDIA_RECORD_16.url());
|
||||
private static Image imgPauseIndicator = new Image(MEDIA_PLAYBACK_PAUSE_16.url());
|
||||
private static Image imgBookmarkIndicator = new Image(BOOKMARK_16.url());
|
||||
private static Image imgGroupIndicator = new Image(Icon.GROUP_16.url());
|
||||
|
||||
private ModelRecordingState modelRecordingState = ModelRecordingState.NOT;
|
||||
private Model model;
|
||||
|
@ -93,6 +98,8 @@ public class ThumbCell extends StackPane {
|
|||
private RecordingIndicator recordingIndicator;
|
||||
private Tooltip recordingIndicatorTooltip;
|
||||
private StackPane previewTrigger;
|
||||
private Label groupIndicatorTooltipTrigger;
|
||||
private ImageView groupIndicator;
|
||||
private int index = 0;
|
||||
ContextMenu popup;
|
||||
private static final Color colorNormal = Color.BLACK;
|
||||
|
@ -170,7 +177,7 @@ public class ThumbCell extends StackPane {
|
|||
topic.setFont(new Font("Sansserif", 13));
|
||||
topic.setTextAlignment(TextAlignment.LEFT);
|
||||
topic.setOpacity(0);
|
||||
int margin = 4;
|
||||
var margin = 4;
|
||||
StackPane.setMargin(topic, new Insets(margin));
|
||||
StackPane.setAlignment(topic, Pos.TOP_CENTER);
|
||||
getChildren().add(topic);
|
||||
|
@ -191,6 +198,21 @@ public class ThumbCell extends StackPane {
|
|||
StackPane.setAlignment(recordingIndicator, Pos.TOP_LEFT);
|
||||
getChildren().add(recordingIndicator);
|
||||
|
||||
groupIndicator = new ImageView(imgGroupIndicator);
|
||||
groupIndicator.setVisible(false);
|
||||
groupIndicatorTooltipTrigger = new Label();
|
||||
groupIndicatorTooltipTrigger.setPrefSize(16, 16);
|
||||
groupIndicatorTooltipTrigger.setMinSize(16, 16);
|
||||
groupIndicatorTooltipTrigger.visibleProperty().bind(groupIndicator.visibleProperty());
|
||||
groupIndicatorTooltipTrigger.setCursor(Cursor.HAND);
|
||||
groupIndicatorTooltipTrigger.setOnMouseClicked(e -> new EditGroupAction(this, recorder, model).execute());
|
||||
StackPane.setMargin(groupIndicatorTooltipTrigger, new Insets(0, 3, 23, 0));
|
||||
StackPane.setAlignment(groupIndicatorTooltipTrigger, Pos.BOTTOM_RIGHT);
|
||||
StackPane.setMargin(groupIndicator, new Insets(0, 3, 23, 0));
|
||||
StackPane.setAlignment(groupIndicator, Pos.BOTTOM_RIGHT);
|
||||
getChildren().add(groupIndicator);
|
||||
getChildren().add(groupIndicatorTooltipTrigger);
|
||||
|
||||
if (Config.getInstance().getSettings().livePreviews) {
|
||||
getChildren().add(createPreviewTrigger());
|
||||
}
|
||||
|
@ -244,18 +266,18 @@ public class ThumbCell extends StackPane {
|
|||
}
|
||||
|
||||
private Node createPreviewTrigger() {
|
||||
int s = 32;
|
||||
var s = 32;
|
||||
previewTrigger = new StackPane();
|
||||
previewTrigger.setStyle("-fx-background-color: white;");
|
||||
previewTrigger.setOpacity(.8);
|
||||
previewTrigger.setMaxSize(s, s);
|
||||
|
||||
Polygon play = new Polygon(16, 8, 26, 15, 16, 22);
|
||||
var play = new Polygon(16, 8, 26, 15, 16, 22);
|
||||
StackPane.setMargin(play, new Insets(0, 0, 0, 3));
|
||||
play.setStyle("-fx-background-color: black;");
|
||||
previewTrigger.getChildren().add(play);
|
||||
|
||||
Circle clip = new Circle(s / 2.0);
|
||||
var clip = new Circle(s / 2.0);
|
||||
clip.setTranslateX(clip.getRadius());
|
||||
clip.setTranslateY(clip.getRadius());
|
||||
previewTrigger.setClip(clip);
|
||||
|
@ -336,7 +358,7 @@ public class ThumbCell extends StackPane {
|
|||
final int w = resolution[1];
|
||||
tagText = w != Integer.MAX_VALUE ? Integer.toString(w) : "HD";
|
||||
if (w == 0) {
|
||||
State state = model.getOnlineState(false);
|
||||
var state = model.getOnlineState(false);
|
||||
tagText = state.name();
|
||||
if (model.isOnline() && state == ONLINE) {
|
||||
resolutionCache.invalidate(model);
|
||||
|
@ -348,7 +370,7 @@ public class ThumbCell extends StackPane {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
State state = model.getOnlineState(true);
|
||||
var state = model.getOnlineState(true);
|
||||
if (state != ONLINE) {
|
||||
tagText = state.name();
|
||||
resolutionBackgroundColor = resolutionOfflineColor;
|
||||
|
@ -403,7 +425,7 @@ public class ThumbCell extends StackPane {
|
|||
if (resp.isSuccessful()) {
|
||||
double width = 480;
|
||||
double height = width * imgAspectRatio;
|
||||
Image img = new Image(resp.body().byteStream(), width, height, preserveAspectRatio.get(), true);
|
||||
var img = new Image(resp.body().byteStream(), width, height, preserveAspectRatio.get(), true);
|
||||
if (img.progressProperty().get() == 1.0) {
|
||||
Platform.runLater(() -> {
|
||||
iv.setImage(img);
|
||||
|
@ -431,13 +453,13 @@ public class ThumbCell extends StackPane {
|
|||
}
|
||||
|
||||
private Transition changeColor(Shape shape, Color from, Color to) {
|
||||
FillTransition transition = new FillTransition(ANIMATION_DURATION, from, to);
|
||||
var transition = new FillTransition(ANIMATION_DURATION, from, to);
|
||||
transition.setShape(shape);
|
||||
return transition;
|
||||
}
|
||||
|
||||
private Transition changeOpacity(Shape shape, double opacity) {
|
||||
FadeTransition transition = new FadeTransition(ANIMATION_DURATION, shape);
|
||||
var transition = new FadeTransition(ANIMATION_DURATION, shape);
|
||||
transition.setFromValue(shape.getOpacity());
|
||||
transition.setToValue(opacity);
|
||||
return transition;
|
||||
|
@ -623,6 +645,12 @@ public class ThumbCell extends StackPane {
|
|||
String txt = (modelRecordingState != ModelRecordingState.NOT) ? " " : "";
|
||||
txt += model.getDescription() != null ? model.getDescription() : "";
|
||||
topic.setText(txt);
|
||||
recorder.getModelGroup(model).ifPresentOrElse(group -> {
|
||||
var tooltip = group.getName() + ": " + group.getModelUrls().size() + " models:\n";
|
||||
tooltip += group.getModelUrls().stream().collect(Collectors.joining("\n"));
|
||||
groupIndicatorTooltipTrigger.setTooltip(new Tooltip(tooltip));
|
||||
groupIndicator.setVisible(true);
|
||||
}, () -> groupIndicator.setVisible(false));
|
||||
|
||||
if (Config.getInstance().getSettings().determineResolution) {
|
||||
updateResolutionTag();
|
||||
|
@ -630,13 +658,14 @@ public class ThumbCell extends StackPane {
|
|||
resolutionBackground.setVisible(false);
|
||||
resolutionTag.setVisible(false);
|
||||
}
|
||||
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
final var prime = 31;
|
||||
var result = 1;
|
||||
result = prime * result + ((model == null) ? 0 : model.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
@ -682,13 +711,13 @@ public class ThumbCell extends StackPane {
|
|||
topicBackground.setHeight(h - nameBackground.getHeight());
|
||||
topic.prefHeight(getHeight() - 25);
|
||||
topic.maxHeight(getHeight() - 25);
|
||||
int margin = 4;
|
||||
var margin = 4;
|
||||
topic.maxWidth(w - margin * 2.0);
|
||||
topic.setWrappingWidth(w - margin * 2.0);
|
||||
|
||||
streamPreview.resizeTo(w, h);
|
||||
|
||||
Rectangle clip = new Rectangle(w, h);
|
||||
var clip = new Rectangle(w, h);
|
||||
clip.setArcWidth(10);
|
||||
clip.arcHeightProperty().bind(clip.arcWidthProperty());
|
||||
this.setClip(clip);
|
||||
|
|
|
@ -38,7 +38,9 @@ import ctbrec.ui.controls.SearchBox;
|
|||
import ctbrec.ui.controls.autocomplete.AutoFillTextField;
|
||||
import ctbrec.ui.controls.autocomplete.ObservableListSuggester;
|
||||
import ctbrec.ui.tabs.TabSelectionListener;
|
||||
import ctbrec.ui.tabs.recorded.RecordedModelsTab.ModelName;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringPropertyBase;
|
||||
import javafx.collections.FXCollections;
|
||||
|
@ -136,10 +138,13 @@ public class RecordLaterTab extends Tab implements TabSelectionListener {
|
|||
if (!Config.getInstance().getSettings().livePreviews) {
|
||||
preview.setVisible(false);
|
||||
}
|
||||
TableColumn<JavaFxModel, String> name = new TableColumn<>("Model");
|
||||
TableColumn<JavaFxModel, ModelName> name = new TableColumn<>("Model");
|
||||
name.setPrefWidth(200);
|
||||
name.setCellValueFactory(new PropertyValueFactory<>("displayName"));
|
||||
name.setCellFactory(new ClickableCellFactory<>());
|
||||
name.setCellValueFactory(param -> {
|
||||
var modelName = new ModelName(param.getValue(), recorder);
|
||||
return new SimpleObjectProperty<>(modelName);
|
||||
});
|
||||
name.setCellFactory(param -> new ModelNameTableCell(recorder));
|
||||
name.setEditable(false);
|
||||
name.setId("name");
|
||||
TableColumn<JavaFxModel, String> url = new TableColumn<>("URL");
|
||||
|
|
|
@ -174,7 +174,7 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
|||
TableColumn<JavaFxModel, ModelName> name = new TableColumn<>("Model");
|
||||
name.setPrefWidth(200);
|
||||
name.setCellValueFactory(param -> {
|
||||
ModelName modelName = new ModelName(param.getValue(), recorder);
|
||||
var modelName = new ModelName(param.getValue(), recorder);
|
||||
return new SimpleObjectProperty<>(modelName);
|
||||
});
|
||||
name.setCellFactory(param -> new ModelNameTableCell(recorder));
|
||||
|
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
@ -27,7 +27,7 @@ public abstract class AbstractPlaceholderAwarePostProcessor extends AbstractPost
|
|||
public String fillInPlaceHolders(String input, PostProcessingContext ctx) {
|
||||
Recording rec = ctx.getRecording();
|
||||
Config config = ctx.getConfig();
|
||||
Optional<ModelGroup> modelGroup = ctx.getRecorder().getModelGroup(rec.getModel());
|
||||
Optional<ModelGroup> modelGroup = Optional.ofNullable(ctx.getRecorder()).flatMap(r -> r.getModelGroup(rec.getModel()));
|
||||
|
||||
Map<String, Function<String, Optional<String>>> placeholderValueSuppliers = new HashMap<>();
|
||||
placeholderValueSuppliers.put("modelName", r -> ofNullable(rec.getModel().getName()));
|
||||
|
|
Loading…
Reference in New Issue