fix image preview and add option for automatically stop auto screenshoting when idle
This commit is contained in:
@@ -55,12 +55,19 @@ public final class ThumbnailCache implements AutoCloseable {
|
||||
this.textures = textures;
|
||||
this.loader = loader;
|
||||
this.size = size;
|
||||
this.capacity = Math.max(8, capacity);
|
||||
this.capacity = Math.max(1, capacity);
|
||||
}
|
||||
|
||||
/** Follows the player's setting without discarding what is already loaded. */
|
||||
/**
|
||||
* Follows the player's setting without discarding what is already loaded.
|
||||
*
|
||||
* <p>Only one is imposed here, because the caller is the one who knows what
|
||||
* it is caching: the grid's floor comes from its config setting, and the
|
||||
* detail view genuinely wants a capacity of two. Nothing thrashes at a small
|
||||
* capacity anyway -- {@link #endFrame()} refuses to evict what was drawn.
|
||||
*/
|
||||
public void capacity(int value) {
|
||||
this.capacity = Math.max(8, value);
|
||||
this.capacity = Math.max(1, value);
|
||||
}
|
||||
|
||||
/** Call once at the top of a frame, before any {@link #of} in that frame. */
|
||||
|
||||
@@ -215,6 +215,9 @@ public final class SettingsScreen extends PhotoSyncScreen {
|
||||
toggle("photosync.settings.skip_when_screen_open", "",
|
||||
() -> draft().autoCapture().skipWhenScreenOpen(),
|
||||
value -> autoCapture(settings -> settings.toBuilder().skipWhenScreenOpen(value).build()));
|
||||
toggle("photosync.settings.skip_when_still", "photosync.settings.skip_when_still.detail",
|
||||
() -> draft().autoCapture().skipWhenStill(),
|
||||
value -> autoCapture(settings -> settings.toBuilder().skipWhenStill(value).build()));
|
||||
}
|
||||
|
||||
private void buildNotifications() {
|
||||
|
||||
@@ -77,8 +77,10 @@ public final class TimelineScreen extends PhotoSyncScreen {
|
||||
BrowserSettings settings = ui.core().config().current().browser();
|
||||
this.tiles = new ThumbnailCache(ui.bridge().textures(), ui.core().thumbnails(),
|
||||
ThumbnailSize.GRID, settings.thumbnailCacheEntries());
|
||||
// Three is enough for the one open photo and the two either side of it.
|
||||
this.detail = new ThumbnailCache(ui.bridge().textures(), ui.core().thumbnails(), ThumbnailSize.DETAIL, 3);
|
||||
// Only one photo is ever open, and these are full-resolution textures --
|
||||
// a 4K screenshot is 33MB on the GPU. Two, so re-opening the last one is
|
||||
// instant, and no more than that.
|
||||
this.detail = new ThumbnailCache(ui.bridge().textures(), ui.core().thumbnails(), ThumbnailSize.DETAIL, 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -297,17 +299,40 @@ public final class TimelineScreen extends PhotoSyncScreen {
|
||||
half - uHalf, half - vHalf, half + uHalf, half + vHalf);
|
||||
}
|
||||
|
||||
/**
|
||||
* The opened photo, at whatever resolution has arrived so far.
|
||||
*
|
||||
* <p>What arrives first is the ThumbHash: a blurred 32x32 that is right for a
|
||||
* tile and nowhere near enough for a full-screen view. It is still worth
|
||||
* drawing, because it says which photo is opening, but it is dimmed and
|
||||
* labelled while it stands in -- an unannotated blur is indistinguishable
|
||||
* from a mod that fetched the wrong size.
|
||||
*/
|
||||
private void renderOpened(RenderBridge render, int mouseX, int mouseY) {
|
||||
detail.beginFrame();
|
||||
Rect area = body();
|
||||
render.fill(area.x(), area.y(), area.width(), area.height(), theme().overlay());
|
||||
Rect frame = area.inset(6);
|
||||
Optional<ThumbnailCache.Thumbnail> image = detail.of(opened);
|
||||
if (image.isPresent()) {
|
||||
drawContained(render, image.get().texture(), frame);
|
||||
} else {
|
||||
|
||||
if (detail.failed(opened.id())) {
|
||||
chrome.notice(render, frame, chrome.translate("photosync.browse.open_failed"),
|
||||
chrome.translate("photosync.browse.open_failed.hint"));
|
||||
} else if (image.isEmpty()) {
|
||||
chrome.notice(render, frame, chrome.translate("photosync.browse.opening"), "");
|
||||
} else {
|
||||
drawContained(render, image.get().texture(), frame);
|
||||
if (image.get().placeholder()) {
|
||||
render.fill(frame.x(), frame.y(), frame.width(), frame.height(),
|
||||
theme().fade(theme().overlay(), 0.6f));
|
||||
chrome.centered(render, chrome.translate("photosync.browse.opening"),
|
||||
new Rect(frame.x(), frame.centerY() - render.lineHeight(), frame.width(), render.lineHeight()),
|
||||
theme().text());
|
||||
chrome.busyBar(render, new Rect(frame.centerX() - 60, frame.centerY() + 6, 120, 3),
|
||||
System.currentTimeMillis(), theme().accent());
|
||||
}
|
||||
}
|
||||
|
||||
chrome.centered(render, chrome.translate("photosync.browse.close_hint"),
|
||||
area.bottom(render.lineHeight() + 2), theme().textFaint());
|
||||
detail.endFrame();
|
||||
@@ -367,7 +392,7 @@ public final class TimelineScreen extends PhotoSyncScreen {
|
||||
@Override
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||
if (opened != null) {
|
||||
opened = null;
|
||||
closeOpened();
|
||||
return true;
|
||||
}
|
||||
if (scroll.mouseClicked(mouseX, mouseY, button)) {
|
||||
@@ -401,7 +426,7 @@ public final class TimelineScreen extends PhotoSyncScreen {
|
||||
@Override
|
||||
public boolean keyPressed(int key, int scanCode, int modifiers) {
|
||||
if (opened != null && key == Keys.ESCAPE) {
|
||||
opened = null;
|
||||
closeOpened();
|
||||
return true;
|
||||
}
|
||||
return switch (key) {
|
||||
@@ -425,6 +450,19 @@ public final class TimelineScreen extends PhotoSyncScreen {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A cache entry that failed stays failed, which is right for a grid tile the
|
||||
* player is scrolling past and wrong for the one photo they chose to open. It
|
||||
* holds three entries, so dropping them all is the cheapest way to let a
|
||||
* second click try again.
|
||||
*/
|
||||
private void closeOpened() {
|
||||
if (detail.failed(opened.id())) {
|
||||
detail.clear();
|
||||
}
|
||||
opened = null;
|
||||
}
|
||||
|
||||
/** Escape dismisses the open photo before it dismisses the screen. */
|
||||
@Override
|
||||
public boolean closeOnEscape() {
|
||||
|
||||
Reference in New Issue
Block a user