forked from j62/ctbrec
Implement pause/resume in ThumbCell
Add pause/resume item to the thumbnail overview context menu. Change the recording indicator to a paused indicator, if the recording is paused
This commit is contained in:
parent
c884c3b248
commit
9e40d44128
|
@ -169,6 +169,22 @@ public class LocalRecorder implements Recorder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSuspended(Model model) {
|
||||||
|
lock.lock();
|
||||||
|
try {
|
||||||
|
int index = models.indexOf(model);
|
||||||
|
if(index >= 0) {
|
||||||
|
Model m = models.get(index);
|
||||||
|
return m.isSuspended();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Model> getModelsRecording() {
|
public List<Model> getModelsRecording() {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
|
|
|
@ -31,4 +31,6 @@ public interface Recorder {
|
||||||
|
|
||||||
public void suspendRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException;
|
public void suspendRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException;
|
||||||
public void resumeRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException;
|
public void resumeRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException;
|
||||||
|
|
||||||
|
public boolean isSuspended(Model model);
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,6 +109,17 @@ public class RemoteRecorder implements Recorder {
|
||||||
return models != null && models.contains(model);
|
return models != null && models.contains(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSuspended(Model model) {
|
||||||
|
int index = models.indexOf(model);
|
||||||
|
if(index >= 0) {
|
||||||
|
Model m = models.get(index);
|
||||||
|
return m.isSuspended();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Model> getModelsRecording() {
|
public List<Model> getModelsRecording() {
|
||||||
if(lastSync.isBefore(Instant.now().minusSeconds(60))) {
|
if(lastSync.isBefore(Instant.now().minusSeconds(60))) {
|
||||||
|
@ -280,10 +291,24 @@ public class RemoteRecorder implements Recorder {
|
||||||
@Override
|
@Override
|
||||||
public void suspendRecording(Model model) throws InvalidKeyException, NoSuchAlgorithmException, IllegalStateException, IOException {
|
public void suspendRecording(Model model) throws InvalidKeyException, NoSuchAlgorithmException, IllegalStateException, IOException {
|
||||||
sendRequest("suspend", model);
|
sendRequest("suspend", model);
|
||||||
|
model.setSuspended(true);
|
||||||
|
// update cached model
|
||||||
|
int index = models.indexOf(model);
|
||||||
|
if(index >= 0) {
|
||||||
|
Model m = models.get(index);
|
||||||
|
m.setSuspended(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resumeRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException {
|
public void resumeRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException {
|
||||||
sendRequest("resume", model);
|
sendRequest("resume", model);
|
||||||
|
model.setSuspended(false);
|
||||||
|
// update cached model
|
||||||
|
int index = models.indexOf(model);
|
||||||
|
if(index >= 0) {
|
||||||
|
Model m = models.get(index);
|
||||||
|
m.setSuspended(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package ctbrec.ui;
|
||||||
|
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
|
import javafx.scene.shape.Rectangle;
|
||||||
|
|
||||||
|
public class PauseIndicator extends HBox {
|
||||||
|
|
||||||
|
public PauseIndicator(Color c, int size) {
|
||||||
|
spacingProperty().setValue(size*1/5);
|
||||||
|
Rectangle left = new Rectangle(size*2/5, size);
|
||||||
|
left.setFill(c);
|
||||||
|
Rectangle right = new Rectangle(size*2/5, size);
|
||||||
|
right.setFill(c);
|
||||||
|
getChildren().add(left);
|
||||||
|
getChildren().add(right);
|
||||||
|
}
|
||||||
|
}
|
|
@ -64,6 +64,7 @@ public class ThumbCell extends StackPane {
|
||||||
private Text resolutionTag;
|
private Text resolutionTag;
|
||||||
private Recorder recorder;
|
private Recorder recorder;
|
||||||
private Circle recordingIndicator;
|
private Circle recordingIndicator;
|
||||||
|
private PauseIndicator pausedIndicator;
|
||||||
private int index = 0;
|
private int index = 0;
|
||||||
ContextMenu popup;
|
ContextMenu popup;
|
||||||
private final Color colorNormal = Color.BLACK;
|
private final Color colorNormal = Color.BLACK;
|
||||||
|
@ -81,6 +82,7 @@ public class ThumbCell extends StackPane {
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.recorder = recorder;
|
this.recorder = recorder;
|
||||||
recording = recorder.isRecording(model);
|
recording = recorder.isRecording(model);
|
||||||
|
model.setSuspended(recorder.isSuspended(model));
|
||||||
this.setStyle("-fx-background-color: lightgray");
|
this.setStyle("-fx-background-color: lightgray");
|
||||||
|
|
||||||
iv = new ImageView();
|
iv = new ImageView();
|
||||||
|
@ -145,6 +147,12 @@ public class ThumbCell extends StackPane {
|
||||||
StackPane.setAlignment(recordingIndicator, Pos.TOP_LEFT);
|
StackPane.setAlignment(recordingIndicator, Pos.TOP_LEFT);
|
||||||
getChildren().add(recordingIndicator);
|
getChildren().add(recordingIndicator);
|
||||||
|
|
||||||
|
pausedIndicator = new PauseIndicator(colorRecording, 16);
|
||||||
|
pausedIndicator.setVisible(false);
|
||||||
|
StackPane.setMargin(pausedIndicator, new Insets(3));
|
||||||
|
StackPane.setAlignment(pausedIndicator, Pos.TOP_LEFT);
|
||||||
|
getChildren().add(pausedIndicator);
|
||||||
|
|
||||||
selectionOverlay = new Rectangle();
|
selectionOverlay = new Rectangle();
|
||||||
selectionOverlay.setOpacity(0);
|
selectionOverlay.setOpacity(0);
|
||||||
StackPane.setAlignment(selectionOverlay, Pos.TOP_LEFT);
|
StackPane.setAlignment(selectionOverlay, Pos.TOP_LEFT);
|
||||||
|
@ -324,7 +332,14 @@ public class ThumbCell extends StackPane {
|
||||||
Color c = mouseHovering ? colorHighlight : colorNormal;
|
Color c = mouseHovering ? colorHighlight : colorNormal;
|
||||||
nameBackground.setFill(c);
|
nameBackground.setFill(c);
|
||||||
}
|
}
|
||||||
recordingIndicator.setVisible(recording);
|
|
||||||
|
if(recording) {
|
||||||
|
recordingIndicator.setVisible(!model.isSuspended());
|
||||||
|
pausedIndicator.setVisible(model.isSuspended());
|
||||||
|
} else {
|
||||||
|
recordingIndicator.setVisible(false);
|
||||||
|
pausedIndicator.setVisible(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void startStopAction(boolean start) {
|
void startStopAction(boolean start) {
|
||||||
|
@ -350,6 +365,31 @@ public class ThumbCell extends StackPane {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pauseResumeAction(boolean pause) {
|
||||||
|
setCursor(Cursor.WAIT);
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
if(pause) {
|
||||||
|
recorder.suspendRecording(model);
|
||||||
|
} else {
|
||||||
|
recorder.resumeRecording(model);
|
||||||
|
}
|
||||||
|
setRecording(recording);
|
||||||
|
} catch (Exception e1) {
|
||||||
|
LOG.error("Couldn't pause/resume recording", e1);
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
Alert alert = new AutosizeAlert(Alert.AlertType.ERROR);
|
||||||
|
alert.setTitle("Error");
|
||||||
|
alert.setHeaderText("Couldn't pause/resume recording");
|
||||||
|
alert.setContentText("I/O error while pausing/resuming the recording: " + e1.getLocalizedMessage());
|
||||||
|
alert.showAndWait();
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setCursor(Cursor.DEFAULT);
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
private void _startStopAction(Model model, boolean start) {
|
private void _startStopAction(Model model, boolean start) {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
|
@ -429,6 +469,7 @@ public class ThumbCell extends StackPane {
|
||||||
this.model.setPreview(model.getPreview());
|
this.model.setPreview(model.getPreview());
|
||||||
this.model.setTags(model.getTags());
|
this.model.setTags(model.getTags());
|
||||||
this.model.setUrl(model.getUrl());
|
this.model.setUrl(model.getUrl());
|
||||||
|
this.model.setSuspended(model.isSuspended());
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,6 +482,7 @@ public class ThumbCell extends StackPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void update() {
|
private void update() {
|
||||||
|
model.setSuspended(recorder.isSuspended(model));
|
||||||
setRecording(recorder.isRecording(model));
|
setRecording(recorder.isRecording(model));
|
||||||
setImage(model.getPreview());
|
setImage(model.getPreview());
|
||||||
String txt = recording ? " " : "";
|
String txt = recording ? " " : "";
|
||||||
|
|
|
@ -324,6 +324,12 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
||||||
stop.setOnAction((e) -> startStopAction(getSelectedThumbCells(cell), false));
|
stop.setOnAction((e) -> startStopAction(getSelectedThumbCells(cell), false));
|
||||||
MenuItem startStop = recorder.isRecording(cell.getModel()) ? stop : start;
|
MenuItem startStop = recorder.isRecording(cell.getModel()) ? stop : start;
|
||||||
|
|
||||||
|
MenuItem pause = new MenuItem("Pause Recording");
|
||||||
|
pause.setOnAction((e) -> pauseResumeAction(getSelectedThumbCells(cell), true));
|
||||||
|
MenuItem resume = new MenuItem("Resume Recording");
|
||||||
|
resume.setOnAction((e) -> pauseResumeAction(getSelectedThumbCells(cell), false));
|
||||||
|
MenuItem pauseResume = recorder.isSuspended(cell.getModel()) ? resume : pause;
|
||||||
|
|
||||||
MenuItem follow = new MenuItem("Follow");
|
MenuItem follow = new MenuItem("Follow");
|
||||||
follow.setOnAction((e) -> follow(getSelectedThumbCells(cell), true));
|
follow.setOnAction((e) -> follow(getSelectedThumbCells(cell), true));
|
||||||
MenuItem unfollow = new MenuItem("Unfollow");
|
MenuItem unfollow = new MenuItem("Unfollow");
|
||||||
|
@ -388,7 +394,7 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
||||||
contextMenu.setAutoHide(true);
|
contextMenu.setAutoHide(true);
|
||||||
contextMenu.setHideOnEscape(true);
|
contextMenu.setHideOnEscape(true);
|
||||||
contextMenu.setAutoFix(true);
|
contextMenu.setAutoFix(true);
|
||||||
contextMenu.getItems().addAll(openInPlayer, startStop);
|
contextMenu.getItems().addAll(openInPlayer, startStop, pauseResume);
|
||||||
if(site.supportsFollow()) {
|
if(site.supportsFollow()) {
|
||||||
MenuItem followOrUnFollow = (this instanceof FollowedTab) ? unfollow : follow;
|
MenuItem followOrUnFollow = (this instanceof FollowedTab) ? unfollow : follow;
|
||||||
followOrUnFollow.setDisable(!site.credentialsAvailable());
|
followOrUnFollow.setDisable(!site.credentialsAvailable());
|
||||||
|
@ -431,6 +437,12 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void pauseResumeAction(List<ThumbCell> selection, boolean pause) {
|
||||||
|
for (ThumbCell thumbCell : selection) {
|
||||||
|
thumbCell.pauseResumeAction(pause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void startPlayer(List<ThumbCell> selection) {
|
private void startPlayer(List<ThumbCell> selection) {
|
||||||
for (ThumbCell thumbCell : selection) {
|
for (ThumbCell thumbCell : selection) {
|
||||||
thumbCell.startPlayer();
|
thumbCell.startPlayer();
|
||||||
|
|
Loading…
Reference in New Issue