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:
0xboobface 2018-11-07 18:08:04 +01:00
parent c884c3b248
commit 9e40d44128
6 changed files with 117 additions and 2 deletions

View File

@ -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
public List<Model> getModelsRecording() {
lock.lock();

View File

@ -31,4 +31,6 @@ public interface Recorder {
public void suspendRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException;
public void resumeRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException;
public boolean isSuspended(Model model);
}

View File

@ -109,6 +109,17 @@ public class RemoteRecorder implements Recorder {
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
public List<Model> getModelsRecording() {
if(lastSync.isBefore(Instant.now().minusSeconds(60))) {
@ -280,10 +291,24 @@ public class RemoteRecorder implements Recorder {
@Override
public void suspendRecording(Model model) throws InvalidKeyException, NoSuchAlgorithmException, IllegalStateException, IOException {
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
public void resumeRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException {
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);
}
}
}

View File

@ -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);
}
}

View File

@ -64,6 +64,7 @@ public class ThumbCell extends StackPane {
private Text resolutionTag;
private Recorder recorder;
private Circle recordingIndicator;
private PauseIndicator pausedIndicator;
private int index = 0;
ContextMenu popup;
private final Color colorNormal = Color.BLACK;
@ -81,6 +82,7 @@ public class ThumbCell extends StackPane {
this.model = model;
this.recorder = recorder;
recording = recorder.isRecording(model);
model.setSuspended(recorder.isSuspended(model));
this.setStyle("-fx-background-color: lightgray");
iv = new ImageView();
@ -145,6 +147,12 @@ public class ThumbCell extends StackPane {
StackPane.setAlignment(recordingIndicator, Pos.TOP_LEFT);
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.setOpacity(0);
StackPane.setAlignment(selectionOverlay, Pos.TOP_LEFT);
@ -324,7 +332,14 @@ public class ThumbCell extends StackPane {
Color c = mouseHovering ? colorHighlight : colorNormal;
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) {
@ -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) {
new Thread(() -> {
try {
@ -429,6 +469,7 @@ public class ThumbCell extends StackPane {
this.model.setPreview(model.getPreview());
this.model.setTags(model.getTags());
this.model.setUrl(model.getUrl());
this.model.setSuspended(model.isSuspended());
update();
}
@ -441,6 +482,7 @@ public class ThumbCell extends StackPane {
}
private void update() {
model.setSuspended(recorder.isSuspended(model));
setRecording(recorder.isRecording(model));
setImage(model.getPreview());
String txt = recording ? " " : "";

View File

@ -324,6 +324,12 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
stop.setOnAction((e) -> startStopAction(getSelectedThumbCells(cell), false));
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");
follow.setOnAction((e) -> follow(getSelectedThumbCells(cell), true));
MenuItem unfollow = new MenuItem("Unfollow");
@ -388,7 +394,7 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
contextMenu.setAutoHide(true);
contextMenu.setHideOnEscape(true);
contextMenu.setAutoFix(true);
contextMenu.getItems().addAll(openInPlayer, startStop);
contextMenu.getItems().addAll(openInPlayer, startStop, pauseResume);
if(site.supportsFollow()) {
MenuItem followOrUnFollow = (this instanceof FollowedTab) ? unfollow : follow;
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) {
for (ThumbCell thumbCell : selection) {
thumbCell.startPlayer();