From 3e197eb310707ac12ed79554ee4c7b83d60c3d5f Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 13 Mar 2025 08:30:53 +0200 Subject: [PATCH] support capturing using additional webcam resolutions of fhd and uhd4k --- .../sparrowwallet/sparrow/AppController.java | 10 +- .../sparrowwallet/sparrow/SparrowDesktop.java | 4 - .../sparrow/control/QRScanDialog.java | 139 +++++++++++------- .../sparrow/control/WebcamResolution.java | 29 +++- .../sparrow/control/WebcamService.java | 65 +++++--- .../event/WebcamResolutionChangedEvent.java | 14 +- .../com/sparrowwallet/sparrow/io/Config.java | 15 +- 7 files changed, 173 insertions(+), 103 deletions(-) diff --git a/src/main/java/com/sparrowwallet/sparrow/AppController.java b/src/main/java/com/sparrowwallet/sparrow/AppController.java index 552a5b16..fa8a2ab5 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppController.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppController.java @@ -379,7 +379,7 @@ public class AppController implements Initializable { openWalletsInNewWindows.selectedProperty().bindBidirectional(openWalletsInNewWindowsProperty); hideEmptyUsedAddressesProperty.set(Config.get().isHideEmptyUsedAddresses()); hideEmptyUsedAddresses.selectedProperty().bindBidirectional(hideEmptyUsedAddressesProperty); - useHdCameraResolutionProperty.set(Config.get().isHdCapture()); + useHdCameraResolutionProperty.set(Config.get().getWebcamResolution() == null || Config.get().getWebcamResolution().isWidescreenAspect()); useHdCameraResolution.selectedProperty().bindBidirectional(useHdCameraResolutionProperty); mirrorCameraImageProperty.set(Config.get().isMirrorCapture()); mirrorCameraImage.selectedProperty().bindBidirectional(mirrorCameraImageProperty); @@ -944,7 +944,11 @@ public class AppController implements Initializable { public void useHdCameraResolution(ActionEvent event) { CheckMenuItem item = (CheckMenuItem)event.getSource(); - Config.get().setHdCapture(item.isSelected()); + if(Config.get().getWebcamResolution().isStandardAspect() && item.isSelected()) { + Config.get().setWebcamResolution(WebcamResolution.HD); + } else if(Config.get().getWebcamResolution().isWidescreenAspect() && !item.isSelected()) { + Config.get().setWebcamResolution(WebcamResolution.VGA); + } } public void mirrorCameraImage(ActionEvent event) { @@ -3150,7 +3154,7 @@ public class AppController implements Initializable { @Subscribe public void webcamResolutionChanged(WebcamResolutionChangedEvent event) { - useHdCameraResolutionProperty.set(event.isHdResolution()); + useHdCameraResolutionProperty.set(event.getResolution().isWidescreenAspect()); } @Subscribe diff --git a/src/main/java/com/sparrowwallet/sparrow/SparrowDesktop.java b/src/main/java/com/sparrowwallet/sparrow/SparrowDesktop.java index bb34bee5..fafba00c 100644 --- a/src/main/java/com/sparrowwallet/sparrow/SparrowDesktop.java +++ b/src/main/java/com/sparrowwallet/sparrow/SparrowDesktop.java @@ -72,10 +72,6 @@ public class SparrowDesktop extends Application { Config.get().setServerType(ServerType.ELECTRUM_SERVER); } - if(Config.get().getHdCapture() == null && OsType.getCurrent() == OsType.MACOS) { - Config.get().setHdCapture(Boolean.TRUE); - } - System.setProperty(Wallet.ALLOW_DERIVATIONS_MATCHING_OTHER_SCRIPT_TYPES_PROPERTY, Boolean.toString(!Config.get().isValidateDerivationPaths())); System.setProperty(Wallet.ALLOW_DERIVATIONS_MATCHING_OTHER_NETWORKS_PROPERTY, Boolean.toString(!Config.get().isValidateDerivationPaths())); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/QRScanDialog.java b/src/main/java/com/sparrowwallet/sparrow/control/QRScanDialog.java index 15d9a05b..a5b96f6d 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/QRScanDialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/QRScanDialog.java @@ -27,7 +27,6 @@ import com.sparrowwallet.hummingbird.registry.pathcomponent.PathComponent; import com.sparrowwallet.sparrow.AppServices; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.event.WebcamResolutionChangedEvent; -import com.sparrowwallet.sparrow.glyphfont.FontAwesome5; import com.sparrowwallet.sparrow.io.Config; import com.sparrowwallet.sparrow.io.bbqr.BBQRDecoder; import com.sparrowwallet.sparrow.io.bbqr.BBQRException; @@ -39,13 +38,14 @@ import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; import javafx.geometry.Insets; import javafx.scene.Node; import javafx.scene.control.*; import javafx.scene.layout.*; import javafx.util.Duration; import javafx.util.StringConverter; -import org.controlsfx.glyphfont.Glyph; import org.controlsfx.tools.Borders; import org.openpnp.capture.CaptureDevice; import org.slf4j.Logger; @@ -77,19 +77,22 @@ public class QRScanDialog extends Dialog { private static final Pattern PART_PATTERN = Pattern.compile("p(\\d+)of(\\d+) (.+)"); private static final int SCAN_PERIOD_MILLIS = 100; - private final ObjectProperty webcamResolutionProperty = new SimpleObjectProperty<>(WebcamResolution.VGA); + private final ObjectProperty webcamDeviceProperty = new SimpleObjectProperty<>(); + private final ObjectProperty webcamResolutionProperty = new SimpleObjectProperty<>(WebcamResolution.HD); private final DoubleProperty percentComplete = new SimpleDoubleProperty(0.0); - private final ObjectProperty webcamDeviceProperty = new SimpleObjectProperty<>(); + private final ObservableList foundDevices = FXCollections.observableList(new ArrayList<>()); + private final ObservableList availableResolutions = FXCollections.observableList(new ArrayList<>()); + private boolean postOpenUpdate; public QRScanDialog() { this.urDecoder = new URDecoder(); this.legacyUrDecoder = new LegacyURDecoder(); this.bbqrDecoder = new BBQRDecoder(); - if(Config.get().isHdCapture()) { - webcamResolutionProperty.set(WebcamResolution.HD); + if(Config.get().getWebcamResolution() != null) { + webcamResolutionProperty.set(Config.get().getWebcamResolution()); } this.webcamService = new WebcamService(webcamResolutionProperty.get(), null); @@ -110,19 +113,35 @@ public class QRScanDialog extends Dialog { progressBar.setPadding(new Insets(0, 10, 0, 10)); progressBar.setPrefWidth(Integer.MAX_VALUE); progressBar.progressProperty().bind(percentComplete); - webcamService.openingProperty().addListener((_, _, newValue) -> { + webcamService.openingProperty().addListener((_, _, opening) -> { if(percentComplete.get() <= 0.0) { - Platform.runLater(() -> percentComplete.set(newValue ? 0.0 : -1.0)); + Platform.runLater(() -> percentComplete.set(opening ? 0.0 : -1.0)); } - Platform.runLater(() -> { - if(Config.get().getWebcamDevice() != null && webcamDeviceProperty.get() == null) { - for(CaptureDevice device : webcamService.getFoundDevices()) { - if(device.getName().equals(Config.get().getWebcamDevice())) { - webcamDeviceProperty.set(device); + + if(opening) { + Platform.runLater(() -> { + try { + postOpenUpdate = true; + List newDevices = new ArrayList<>(webcamService.getDevices()); + newDevices.removeAll(foundDevices); + foundDevices.addAll(newDevices); + foundDevices.removeIf(device -> !webcamService.getDevices().contains(device)); + + if(Config.get().getWebcamDevice() != null && webcamDeviceProperty.get() == null) { + for(CaptureDevice device : foundDevices) { + if(device.getName().equals(Config.get().getWebcamDevice())) { + webcamDeviceProperty.set(device); + } + } } + + updateList(availableResolutions, webcamService.getResolutions()); + webcamResolutionProperty.set(webcamService.getResolution()); + } finally { + postOpenUpdate = false; } - } - }); + }); + } }); webcamService.closedProperty().addListener((_, _, closed) -> { if(closed && webcamResolutionProperty.get() != null) { @@ -148,12 +167,18 @@ public class QRScanDialog extends Dialog { Platform.runLater(() -> setResult(new Result(exception))); }); webcamService.start(); - webcamResolutionProperty.addListener((_, _, newResolution) -> { + webcamResolutionProperty.addListener((_, oldResolution, newResolution) -> { if(newResolution != null) { - setHeight(newResolution == WebcamResolution.HD ? (getHeight() - 100) : (getHeight() + 100)); - EventManager.get().post(new WebcamResolutionChangedEvent(newResolution == WebcamResolution.HD)); + if(newResolution.isStandardAspect() && oldResolution.isWidescreenAspect()) { + setHeight(getHeight() + 100); + } else if(newResolution.isWidescreenAspect() && oldResolution.isStandardAspect()) { + setHeight(getHeight() - 100); + } + EventManager.get().post(new WebcamResolutionChangedEvent(newResolution)); + } + if(newResolution == null || !postOpenUpdate) { + webcamService.cancel(); } - webcamService.cancel(); }); webcamDeviceProperty.addListener((_, _, newValue) -> { Config.get().setWebcamDevice(newValue.getName()); @@ -163,9 +188,8 @@ public class QRScanDialog extends Dialog { }); setOnCloseRequest(_ -> { - boolean isHdCapture = (webcamResolutionProperty.get() == WebcamResolution.HD); - if(Config.get().isHdCapture() != isHdCapture) { - Config.get().setHdCapture(isHdCapture); + if(webcamResolutionProperty.get() != null) { + Config.get().setWebcamResolution(webcamResolutionProperty.get()); } Platform.runLater(() -> { @@ -175,11 +199,11 @@ public class QRScanDialog extends Dialog { }); final ButtonType cancelButtonType = new javafx.scene.control.ButtonType("Close", ButtonBar.ButtonData.CANCEL_CLOSE); - final ButtonType hdButtonType = new javafx.scene.control.ButtonType("Use HD Capture", ButtonBar.ButtonData.LEFT); - final ButtonType camButtonType = new javafx.scene.control.ButtonType("Default Camera", ButtonBar.ButtonData.HELP_2); - dialogPane.getButtonTypes().addAll(hdButtonType, camButtonType, cancelButtonType); + final ButtonType deviceButtonType = new javafx.scene.control.ButtonType("Default Camera", ButtonBar.ButtonData.LEFT); + final ButtonType resolutionButtonType = new javafx.scene.control.ButtonType("Resolution", ButtonBar.ButtonData.HELP_2); + dialogPane.getButtonTypes().addAll(deviceButtonType, resolutionButtonType, cancelButtonType); dialogPane.setPrefWidth(646); - dialogPane.setPrefHeight(webcamResolutionProperty.get() == WebcamResolution.HD ? 490 : 590); + dialogPane.setPrefHeight(webcamResolutionProperty.get().isWidescreenAspect() ? 490 : 590); dialogPane.setMinHeight(dialogPane.getPrefHeight()); AppServices.moveToActiveWindowScreen(this); @@ -690,23 +714,9 @@ public class QRScanDialog extends Dialog { private class QRScanDialogPane extends DialogPane { @Override protected Node createButton(ButtonType buttonType) { - Node button = null; + Node button; if(buttonType.getButtonData() == ButtonBar.ButtonData.LEFT) { - ToggleButton hd = new ToggleButton(buttonType.getText()); - hd.setSelected(webcamResolutionProperty.get() == WebcamResolution.HD); - hd.setGraphicTextGap(5); - setHdGraphic(hd, hd.isSelected()); - - final ButtonBar.ButtonData buttonData = buttonType.getButtonData(); - ButtonBar.setButtonData(hd, buttonData); - hd.selectedProperty().addListener((observable, oldValue, newValue) -> { - webcamResolutionProperty.set(newValue ? WebcamResolution.HD : WebcamResolution.VGA); - setHdGraphic(hd, newValue); - }); - - button = hd; - } else if(buttonType.getButtonData() == ButtonBar.ButtonData.HELP_2) { - ComboBox devicesCombo = new ComboBox<>(webcamService.getFoundDevices()); + ComboBox devicesCombo = new ComboBox<>(foundDevices); devicesCombo.setConverter(new StringConverter<>() { @Override public String toString(CaptureDevice device) { @@ -719,9 +729,14 @@ public class QRScanDialog extends Dialog { } }); devicesCombo.valueProperty().bindBidirectional(webcamDeviceProperty); - ButtonBar.setButtonData(devicesCombo, ButtonBar.ButtonData.LEFT); - + final ButtonBar.ButtonData buttonData = buttonType.getButtonData(); + ButtonBar.setButtonData(devicesCombo, buttonData); button = devicesCombo; + } else if(buttonType.getButtonData() == ButtonBar.ButtonData.HELP_2) { + ComboBox resolutionsCombo = new ComboBox<>(availableResolutions); + resolutionsCombo.valueProperty().bindBidirectional(webcamResolutionProperty); + ButtonBar.setButtonData(resolutionsCombo, ButtonBar.ButtonData.LEFT); + button = resolutionsCombo; } else { button = super.createButton(buttonType); } @@ -734,19 +749,39 @@ public class QRScanDialog extends Dialog { button.disableProperty().bind(webcamService.openingProperty()); return button; } + } - private void setHdGraphic(ToggleButton hd, boolean isHd) { - if(isHd) { - hd.setGraphic(getGlyph(FontAwesome5.Glyph.CHECK_CIRCLE)); + public static > void updateList(List targetList, Collection sourceList) { + List sortedSource = new ArrayList<>(sourceList); + Collections.sort(sortedSource); + + ListIterator targetIter = targetList.listIterator(); + int sourceIndex = 0; + + while (sourceIndex < sortedSource.size() && targetIter.hasNext()) { + T sourceItem = sortedSource.get(sourceIndex); + T targetItem = targetIter.next(); + int comparison = sourceItem.compareTo(targetItem); + + if (comparison < 0) { + targetIter.previous(); // Back up to insert before + targetIter.add(sourceItem); + sourceIndex++; + } else if (comparison > 0) { + targetIter.remove(); } else { - hd.setGraphic(getGlyph(FontAwesome5.Glyph.BAN)); + sourceIndex++; } } - private Glyph getGlyph(FontAwesome5.Glyph glyphName) { - Glyph glyph = new Glyph(FontAwesome5.FONT_NAME, glyphName); - glyph.setFontSize(11); - return glyph; + while (sourceIndex < sortedSource.size()) { + targetIter.add(sortedSource.get(sourceIndex)); + sourceIndex++; + } + + while (targetIter.hasNext()) { + targetIter.next(); + targetIter.remove(); } } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/WebcamResolution.java b/src/main/java/com/sparrowwallet/sparrow/control/WebcamResolution.java index fa312305..396606e2 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/WebcamResolution.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/WebcamResolution.java @@ -2,14 +2,20 @@ package com.sparrowwallet.sparrow.control; import org.openpnp.capture.CaptureFormat; -public enum WebcamResolution { - VGA(640, 480), - HD(1280, 720); +import java.util.Arrays; +public enum WebcamResolution implements Comparable { + VGA("480p", 640, 480), + HD("720p", 1280, 720), + FHD("1080p", 1920, 1080), + UHD4K("4K", 3840, 2160); + + private final String name; private final int width; private final int height; - WebcamResolution(int width, int height) { + WebcamResolution(String name, int width, int height) { + this.name = name; this.width = width; this.height = height; } @@ -18,6 +24,14 @@ public enum WebcamResolution { return this.width * this.height; } + public boolean isStandardAspect() { + return Arrays.equals(getAspectRatio(), new int[]{4, 3}); + } + + public boolean isWidescreenAspect() { + return Arrays.equals(getAspectRatio(), new int[]{16, 9}); + } + public int[] getAspectRatio() { int factor = this.getCommonFactor(this.width, this.height); int wr = this.width / factor; @@ -29,6 +43,10 @@ public enum WebcamResolution { return height == 0 ? width : this.getCommonFactor(height, width % height); } + public String getName() { + return name; + } + public int getWidth() { return this.width; } @@ -38,8 +56,7 @@ public enum WebcamResolution { } public String toString() { - int[] ratio = this.getAspectRatio(); - return super.toString() + ' ' + this.width + 'x' + this.height + " (" + ratio[0] + ':' + ratio[1] + ')'; + return name; } public static WebcamResolution from(CaptureFormat captureFormat) { diff --git a/src/main/java/com/sparrowwallet/sparrow/control/WebcamService.java b/src/main/java/com/sparrowwallet/sparrow/control/WebcamService.java index 20c6afe8..423fa069 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/WebcamService.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/WebcamService.java @@ -10,8 +10,6 @@ import javafx.beans.property.BooleanProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; import javafx.concurrent.ScheduledService; import javafx.concurrent.Task; import javafx.embed.swing.SwingFXUtils; @@ -29,15 +27,18 @@ import java.awt.*; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.awt.image.WritableRaster; -import java.util.ArrayList; +import java.util.*; import java.util.List; -import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.Stream; public class WebcamService extends ScheduledService { private static final Logger log = LoggerFactory.getLogger(WebcamService.class); + private List devices; + private Set resolutions; + private WebcamResolution resolution; private CaptureDevice device; private final BooleanProperty opening = new SimpleBooleanProperty(false); @@ -50,7 +51,6 @@ public class WebcamService extends ScheduledService { private final OpenPnpCapture capture; private CaptureStream stream; private long lastQrSampleTime; - private final ObservableList foundDevices = FXCollections.observableList(new ArrayList<>()); private final Reader qrReader; private final Bokmakierie bokmakierie; @@ -94,27 +94,22 @@ public class WebcamService extends ScheduledService { protected Image call() throws Exception { try { if(stream == null) { - List devices = capture.getDevices(); + devices = capture.getDevices(); - List newDevices = new ArrayList<>(devices); - newDevices.removeAll(foundDevices); - foundDevices.addAll(newDevices); - foundDevices.removeIf(device -> !devices.contains(device)); - - if(foundDevices.isEmpty()) { + if(devices.isEmpty()) { throw new UnsupportedOperationException("No cameras available"); } - CaptureDevice selectedDevice = foundDevices.getFirst(); + CaptureDevice selectedDevice = devices.getFirst(); if(device != null) { - for(CaptureDevice webcam : foundDevices) { + for(CaptureDevice webcam : devices) { if(webcam.getName().equals(device.getName())) { selectedDevice = webcam; } } } else if(Config.get().getWebcamDevice() != null) { - for(CaptureDevice webcam : foundDevices) { + for(CaptureDevice webcam : devices) { if(webcam.getName().equals(Config.get().getWebcamDevice())) { selectedDevice = webcam; } @@ -129,17 +124,22 @@ public class WebcamService extends ScheduledService { Map supportedResolutions = device.getFormats().stream() .filter(f -> WebcamResolution.from(f) != null) - .collect(Collectors.toMap(WebcamResolution::from, Function.identity(), (u, v) -> u)); + .collect(Collectors.toMap(WebcamResolution::from, Function.identity(), (u, v) -> u, TreeMap::new)); + resolutions = supportedResolutions.keySet(); CaptureFormat format = supportedResolutions.get(resolution); if(format == null) { if(!supportedResolutions.isEmpty()) { - format = supportedResolutions.values().iterator().next(); + resolution = getNearestEnum(resolution, supportedResolutions.keySet().toArray(new WebcamResolution[0])); + format = supportedResolutions.get(resolution); } else { format = device.getFormats().getFirst(); + log.warn("Could not get standard capture resolution, using " + format.getFormatInfo().width + "x" + format.getFormatInfo().height); } + } - log.warn("Could not get requested capture resolution, using " + format.getFormatInfo().width + "x" + format.getFormatInfo().height); + if(log.isDebugEnabled()) { + log.debug("Opening capture stream with format " + format.getFormatInfo().width + "x" + format.getFormatInfo().height + " (" + fourCCToString(format.getFormatInfo().fourcc) + ")"); } opening.set(true); @@ -237,7 +237,7 @@ public class WebcamService extends ScheduledService { g2d.drawImage(image, 0, 0, null); float[] dash1 = {10.0f}; g2d.setColor(Color.BLACK); - g2d.setStroke(new BasicStroke(resolution == WebcamResolution.HD ? 3.0f : 1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f)); + g2d.setStroke(new BasicStroke(resolution.isWidescreenAspect() ? 3.0f : 1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f)); g2d.draw(new RoundRectangle2D.Double(cropped.x, cropped.y, cropped.length, cropped.length, 10, 10)); g2d.dispose(); return clone; @@ -274,6 +274,14 @@ public class WebcamService extends ScheduledService { } } + public List getDevices() { + return devices; + } + + public Set getResolutions() { + return resolutions; + } + public Result getResult() { return resultProperty.get(); } @@ -290,6 +298,10 @@ public class WebcamService extends ScheduledService { return resolution.getHeight(); } + public WebcamResolution getResolution() { + return resolution; + } + public void setResolution(WebcamResolution resolution) { this.resolution = resolution; } @@ -302,10 +314,6 @@ public class WebcamService extends ScheduledService { this.device = device; } - public ObservableList getFoundDevices() { - return foundDevices; - } - public BooleanProperty openingProperty() { return opening; } @@ -323,6 +331,17 @@ public class WebcamService extends ScheduledService { }); } + public static > T getNearestEnum(T target) { + return getNearestEnum(target, target.getDeclaringClass().getEnumConstants()); + } + + public static > T getNearestEnum(T target, T[] values) { + int ordinal = target.ordinal(); + return Stream.concat(ordinal > 0 ? Stream.of(values[ordinal - 1]) : Stream.empty(), ordinal < values.length - 1 ? Stream.of(values[ordinal + 1]) : Stream.empty()) + .findFirst() + .orElse(null); + } + private static class CroppedDimension { public int x; public int y; diff --git a/src/main/java/com/sparrowwallet/sparrow/event/WebcamResolutionChangedEvent.java b/src/main/java/com/sparrowwallet/sparrow/event/WebcamResolutionChangedEvent.java index 6d1f9c80..63099881 100644 --- a/src/main/java/com/sparrowwallet/sparrow/event/WebcamResolutionChangedEvent.java +++ b/src/main/java/com/sparrowwallet/sparrow/event/WebcamResolutionChangedEvent.java @@ -1,13 +1,15 @@ package com.sparrowwallet.sparrow.event; -public class WebcamResolutionChangedEvent { - private final boolean hdResolution; +import com.sparrowwallet.sparrow.control.WebcamResolution; - public WebcamResolutionChangedEvent(boolean hdResolution) { - this.hdResolution = hdResolution; +public class WebcamResolutionChangedEvent { + private final WebcamResolution resolution; + + public WebcamResolutionChangedEvent(WebcamResolution resolution) { + this.resolution = resolution; } - public boolean isHdResolution() { - return hdResolution; + public WebcamResolution getResolution() { + return resolution; } } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Config.java b/src/main/java/com/sparrowwallet/sparrow/io/Config.java index 3ae6dfb6..f93ad0f4 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Config.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Config.java @@ -6,6 +6,7 @@ import com.sparrowwallet.sparrow.UnitFormat; import com.sparrowwallet.sparrow.Mode; import com.sparrowwallet.sparrow.Theme; import com.sparrowwallet.sparrow.control.QRDensity; +import com.sparrowwallet.sparrow.control.WebcamResolution; import com.sparrowwallet.sparrow.net.*; import com.sparrowwallet.sparrow.wallet.FeeRatesSelection; import com.sparrowwallet.sparrow.wallet.OptimizationStrategy; @@ -56,7 +57,7 @@ public class Config { private long dustAttackThreshold = DUST_ATTACK_THRESHOLD_SATS; private int enumerateHwPeriod = ENUMERATE_HW_PERIOD_SECS; private QRDensity qrDensity; - private Boolean hdCapture; + private WebcamResolution webcamResolution; private boolean mirrorCapture = true; private boolean useZbar = true; private String webcamDevice; @@ -383,16 +384,12 @@ public class Config { flush(); } - public Boolean getHdCapture() { - return hdCapture; + public WebcamResolution getWebcamResolution() { + return webcamResolution; } - public Boolean isHdCapture() { - return hdCapture != null && hdCapture; - } - - public void setHdCapture(Boolean hdCapture) { - this.hdCapture = hdCapture; + public void setWebcamResolution(WebcamResolution webcamResolution) { + this.webcamResolution = webcamResolution; flush(); }