Skip to content
This repository has been archived by the owner on Feb 2, 2021. It is now read-only.

Commit

Permalink
Merge pull request #13 from rebuy-de/available_events
Browse files Browse the repository at this point in the history
Add move events!
  • Loading branch information
omares committed Mar 20, 2015
2 parents 336f274 + 9c8ded5 commit 28458a4
Show file tree
Hide file tree
Showing 10 changed files with 282 additions and 35 deletions.
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,16 @@ You can enable or disable the scanner and preview using the `BarcodeScanner.IsEn

What | Type | Description
---- | ---- | -----------
`BarcodeScanner.BarcodeFound` | EventHandler | The event gets raised when a barcode was found and decoded. Use this to start of your custom logic.
`BarcodeScanner.IsEnabled` | Property | If `true` opens the camera and starts the preview. If `false` stops the preview and releases the camera.
`BarcodeScanner.Barcode` | Property | A bindable property that holds the value of the last found barcode.
`BarcodeScanner.BarcodeChanged` | EventHandler | Raised only when the barcode text changes.
`BarcodeScanner.BarcodeDecoded` | EventHandler | Raised every time when a barcode is decoded from the preview, even if the value is the same as the previews one.
`BarcodeScanner.PreviewActivated` | EventHandler | Raised after the preview image gets active.
`BarcodeScanner.PreviewDeactivated` | EventHandler | Raised after the preview image gets deactivated.
`BarcodeScanner.CameraOpened` | EventHandler | Raised after the camera was obtained.
`BarcodeScanner.CameraReleased` | EventHandler | Raised after the camera was released.
`BarcodeScanner.Barcode` | Property | Holds the value of the last found barcode.
`BarcodeScanner.IsEnabled` | Property | If `true` opens the camera and activates the preview. `false` deactivates the preview and releases the camera.
`BarcodeScanner.PreviewActive` | Property | If `true` the preview image gets updated. `false` no preview for you!
`BarcodeScanner.BarcodeDecoder` | Property | If `true` the decoder is active and tries to decode barcodes out of the image. `false` turns the decoder off, the preview is still active but barcodes will not be decoded.

### Debugging

Expand Down
46 changes: 46 additions & 0 deletions Rb.Forms.Barcode.Droid/BarcodeScannerRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@

using Rb.Forms.Barcode.Pcl;
using Rb.Forms.Barcode.Pcl.Logger;
using Rb.Forms.Barcode.Pcl.Extensions;
using Rb.Forms.Barcode.Droid;
using Rb.Forms.Barcode.Droid.Camera;
using Rb.Forms.Barcode.Droid.Decoder;
using Rb.Forms.Barcode.Droid.Logger;

using Android.Views;
using System.Threading.Tasks;

[assembly: ExportRenderer(typeof(BarcodeScanner), typeof(BarcodeScannerRenderer))]
namespace Rb.Forms.Barcode.Droid
Expand All @@ -31,6 +33,10 @@ public static void Init()

public void SurfaceCreated(ISurfaceHolder holder)
{
if (!Element.IsEnabled) {
return;
}

this.Debug("SurfaceCreated");

if (cameraControl.CameraOpen) {
Expand All @@ -43,6 +49,10 @@ public void SurfaceCreated(ISurfaceHolder holder)

public void SurfaceChanged(ISurfaceHolder holder, global::Android.Graphics.Format format, int width, int height)
{
if (!Element.IsEnabled) {
return;
}

this.Debug("SurfaceChanged");

try {
Expand Down Expand Up @@ -101,6 +111,32 @@ protected override void OnElementPropertyChanged(object sender, PropertyChangedE
releaseCamera();
}
}

if (e.PropertyName == BarcodeScanner.PreviewActiveProperty.PropertyName)
{
this.Debug("ScannerActive [{0}]", Element.PreviewActive);

if (Element.PreviewActive) {
startPreview();
}

if (!Element.PreviewActive) {
haltPreview();
}
}

if (e.PropertyName == BarcodeScanner.BarcodeDecoderProperty.PropertyName)
{
this.Debug("Decoder state [{0}]", Element.BarcodeDecoder);

if (Element.BarcodeDecoder) {
barcodeDecoder.RefreshToken();
}

if (!Element.BarcodeDecoder) {
barcodeDecoder.CancelDecoding();
}
}
}

protected override void OnVisibilityChanged(global::Android.Views.View view, ViewStates visibility)
Expand Down Expand Up @@ -145,10 +181,13 @@ private void openCamera()
}

barcodeDecoder.RefreshToken();
Element.BarcodeDecoder = true;

try {
cameraControl.OpenCamera();
cameraControl.AssignPreview(Control.Holder);

Element.OnCameraOpened();
} catch (Exception ex) {
this.Debug("Unable to open camera");
this.Debug(ex.ToString());
Expand All @@ -159,10 +198,13 @@ private void releaseCamera()
{
try {
barcodeDecoder.CancelDecoding();
Element.BarcodeDecoder = false;

cameraControl.ReleaseCamera();
autoFocus.Enabled = false;

BarcodeScannerRenderer.reuseCamera = false;
Element.OnCameraReleased();
} catch (Exception ex) {
this.Debug("Unable to release camera");
this.Debug(ex.ToString());
Expand All @@ -184,12 +226,16 @@ private void startPreview()
if (cameraControl.AutoFocusMode) {
cameraControl.AutoFocus(autoFocus);
}

Element.PreviewActive = true;
}

private void haltPreview()
{
autoFocus.Enabled = false;
cameraControl.HaltPreview();

Element.PreviewActive = false;
}
}
}
43 changes: 30 additions & 13 deletions Rb.Forms.Barcode.Droid/Camera/CameraConfigurator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,36 @@ public AndroidCamera Configure(AndroidCamera camera)
this.Debug("Focus Mode [{0}]", focusMode);
parameters.FocusMode = focusMode;

var sceneMode = determineSceneMode(camera);
this.Debug("Scene Mode [{0}]", sceneMode);
parameters.SceneMode = sceneMode;

this.Debug("Metering area [{0}]", (parameters.MaxNumMeteringAreas > 0).ToString());
if (parameters.MaxNumMeteringAreas > 0) {
parameters.MeteringAreas = createAreas();
if (isPickyDevice()) {
this.Debug("Used device is marked as picky. Skipping detailed configuration to ensure function compatibility.");
}

this.Debug("Video stabilization [{0}]", parameters.IsVideoStabilizationSupported.ToString());
if (parameters.IsVideoStabilizationSupported) {
parameters.VideoStabilization = true;
if (!isPickyDevice()) {
var sceneMode = determineSceneMode(camera);
this.Debug("Scene Mode [{0}]", sceneMode);
parameters.SceneMode = sceneMode;

this.Debug("Metering area [{0}]", (parameters.MaxNumMeteringAreas > 0).ToString());
if (parameters.MaxNumMeteringAreas > 0) {
parameters.MeteringAreas = createAreas();
}

this.Debug("Focusing area [{0}]", (parameters.MaxNumFocusAreas > 0).ToString());
if (parameters.MaxNumFocusAreas > 0) {
parameters.FocusAreas = createAreas();
}

this.Debug("Video stabilization [{0}]", parameters.IsVideoStabilizationSupported.ToString());
if (parameters.IsVideoStabilizationSupported) {
parameters.VideoStabilization = true;
}

var whiteBalance = determineWhiteBalance(camera);
this.Debug("White balance [{0}]", whiteBalance);
parameters.WhiteBalance = whiteBalance;
}

var whiteBalance = determineWhiteBalance(camera);
this.Debug("White balance [{0}]", whiteBalance);
parameters.WhiteBalance = whiteBalance;

camera.SetParameters(parameters);

return camera;
Expand Down Expand Up @@ -92,6 +104,11 @@ private string determineWhiteBalance(AndroidCamera camera)
area
};
}

private bool isPickyDevice()
{
return Android.OS.Build.Manufacturer.Contains("samsung");
}
}
}
#pragma warning restore 618
2 changes: 1 addition & 1 deletion Rb.Forms.Barcode.Droid/Camera/PreviewFrameCallback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ async public void OnPreviewFrame(byte[] bytes, AndroidCamera camera)
var barcode = await decoder;

if (!string.IsNullOrWhiteSpace(barcode)) {
scanner.RaiseBarcodeFoundEvent(barcode);
scanner.Barcode = barcode;
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions Rb.Forms.Barcode.Droid/Decoder/BarcodeDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ public Task<String> DecodeAsync(byte[] bytes, int width, int height)
return null;
}

if (cancellationTokenSource.IsCancellationRequested) {
return null;
}

lastPreviewScanAnalysis = DateTime.UtcNow;

currentTask = Task.Run(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

namespace Rb.Forms.Barcode.Pcl
{
public sealed class BarcodeFoundEventArgs : EventArgs
public class BarcodeEventArgs : EventArgs
{
public string Barcode { get; private set; }

public BarcodeFoundEventArgs(string barcode)
public BarcodeEventArgs(string barcode)
{
Barcode = barcode;
}
Expand Down
124 changes: 115 additions & 9 deletions Rb.Forms.Barcode.Pcl/BarcodeScanner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,139 @@

using Xamarin.Forms;
using System.Diagnostics;
using Rb.Forms.Barcode.Pcl.Extensions;

namespace Rb.Forms.Barcode.Pcl
{
public class BarcodeScanner : View
{
/// <summary>
/// OneWay source to target binding for the current barcode.
/// </summary>
public static readonly BindableProperty BarcodeProperty =
BindableProperty.Create<BarcodeScanner, String>(
p => p.Barcode, default(string), BindingMode.OneWayToSource);
p => p.Barcode, default(string), propertyChanged: OnBarcodeChanged
);

/// <summary>
/// Gets or sets the current barcode.
/// </summary>
/// <value>The barcode.</value>
public String Barcode
{
get { return (String) GetValue(BarcodeProperty); }
set { SetValue(BarcodeProperty, value); }
set {
SetValue(BarcodeProperty, value);
OnBarcodeDecoded(value);
}
}

/// <summary>
/// TwoWay binding to control the scanner preview and decoder state.
/// If set to true the preview is active, false deactivates the preview image.
/// </summary>
public static readonly BindableProperty PreviewActiveProperty =
BindableProperty.Create<BarcodeScanner, bool>(
p => p.PreviewActive, default(bool), BindingMode.TwoWay, propertyChanged: OnPreviewActiveChanged
);

/// <summary>
/// Gets or controlls the current preview state.
/// </summary>
/// <value>The barcode.</value>
public bool PreviewActive
{
get { return (bool) GetValue(PreviewActiveProperty); }
set { SetValue(PreviewActiveProperty, value); }
}

/// <summary>
/// TwoWay binding for barcode decoder control.
/// If set to true the decoder tries to read the barcode from the surface image, false deactivates the decoder.
/// </summary>
public static readonly BindableProperty BarcodeDecoderProperty =
BindableProperty.Create<BarcodeScanner, bool>(
p => p.BarcodeDecoder, default(bool), BindingMode.TwoWay
);

/// <summary>
/// Gets or controlls the decoder state.
/// </summary>
/// <value>The barcode.</value>
public bool BarcodeDecoder
{
get { return (bool) GetValue(BarcodeDecoderProperty); }
set { SetValue(BarcodeDecoderProperty, value); }
}

/// <summary>
/// Occurs only when the barcode text changes.
/// </summary>
public event EventHandler<BarcodeEventArgs> BarcodeChanged;

/// <summary>
/// Occurs every time when a barcode is decoded from the preview, even if the value is the same as the previews one.
/// </summary>
public event EventHandler<BarcodeEventArgs> BarcodeDecoded;

/// <summary>
/// Occurs as soon as the surfaces starts previewing.
/// </summary>
public event EventHandler<EventArgs> PreviewActivated;

/// <summary>
/// Occurs when the surfaces stops previewing.
/// </summary>
public event EventHandler<EventArgs> PreviewDeactivated;

/// <summary>
/// Occurs after the camera was opened.
/// </summary>
public event EventHandler<EventArgs> CameraOpened;

/// <summary>
/// Occurs after the camera was released.
/// </summary>
public event EventHandler<EventArgs> CameraReleased;

public void OnCameraOpened()
{
CameraOpened.Raise(this, EventArgs.Empty);
}

public event EventHandler<BarcodeFoundEventArgs> BarcodeFound;
public void OnCameraReleased()
{
CameraReleased.Raise(this, EventArgs.Empty);
}

public void RaiseBarcodeFoundEvent(String barcode)
private static void OnBarcodeChanged(BindableObject bindable, String oldValue, String newBarcode)
{
Barcode = barcode;
Debug.WriteLine("[ScannerView] OnBarcodeChanged [{0}]", newBarcode, null);
var b = (BarcodeScanner) bindable;

b.BarcodeChanged.Raise(b, new BarcodeEventArgs(newBarcode));
}

Debug.WriteLine("[ScannerView] RaiseBarcodeFoundEvent [{0}]", barcode, null);
if (null == this.BarcodeFound) {
return;
private void OnBarcodeDecoded(String barcode)
{
Debug.WriteLine("[ScannerView] OnBarcodeDecoded [{0}]", barcode, null);

BarcodeDecoded.Raise(this, new BarcodeEventArgs(barcode));
}

private static void OnPreviewActiveChanged(BindableObject bindable, bool oldState, bool newState)
{
var b = (BarcodeScanner) bindable;

Debug.WriteLine("[ScannerView] OnPreviewActiveChanged to [{0}]", newState);

if (newState) {
b.PreviewActivated.Raise(b, new EventArgs());
}

this.BarcodeFound(this, new BarcodeFoundEventArgs(barcode));
if (!newState) {
b.PreviewDeactivated.Raise(b, new EventArgs());
}
}
}
}
Loading

0 comments on commit 28458a4

Please sign in to comment.