diff --git a/SenseHatDriverDemo/build.gradle b/SenseHatDriverDemo/build.gradle index 692471c..1c9b77e 100644 --- a/SenseHatDriverDemo/build.gradle +++ b/SenseHatDriverDemo/build.gradle @@ -1,14 +1,14 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 26 + compileSdkVersion 28 defaultConfig { applicationId "com.eon.androidthings.sensehat" - minSdkVersion 26 - targetSdkVersion 26 + minSdkVersion 27 + targetSdkVersion 28 versionCode 1 versionName "1.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { @@ -20,14 +20,14 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.android.support.constraint:constraint-layout:1.0.2' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.1' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' - implementation 'com.android.support:support-annotations:25.4.0' + implementation 'androidx.annotation:annotation:1.0.1' - compileOnly 'com.google.android.things:androidthings:+' + compileOnly 'com.google.android.things:androidthings:1.0' implementation project(path: ':SenseHatDriverLibrary') implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.0.2' diff --git a/SenseHatDriverDemo/src/main/java/com/eon/androidthings/sensehat/HomeActivity.java b/SenseHatDriverDemo/src/main/java/com/eon/androidthings/sensehat/HomeActivity.java index 6a9735f..e3efdb7 100644 --- a/SenseHatDriverDemo/src/main/java/com/eon/androidthings/sensehat/HomeActivity.java +++ b/SenseHatDriverDemo/src/main/java/com/eon/androidthings/sensehat/HomeActivity.java @@ -14,7 +14,7 @@ import com.eon.androidthings.sensehatdriverlibrary.SenseHat; import com.eon.androidthings.sensehatdriverlibrary.devices.LedMatrix; import com.eon.androidthings.sensehat.demos.JoystickDemo; -import com.eon.androidthings.sensehat.demos.TextScrollDemo; +import com.eon.androidthings.sensehat.demos.LedDrawingDemo; import com.eon.androidthings.sensehat.uitils.NetworkUtils; import org.apache.commons.lang3.exception.ExceptionUtils; @@ -41,7 +41,7 @@ public class HomeActivity extends Activity { private JoystickDemo joystickDemo; - private TextScrollDemo textScrollDemo; + private LedDrawingDemo ledDrawingDemo; private TextView cursorCoordTextView; private TextView cursorColorTextView; @@ -82,7 +82,7 @@ protected void onCreate(Bundle savedInstanceState) { /** Text-Scrolling */ - this.textScrollDemo = new TextScrollDemo(sensorManager, this.getAssets()); + this.ledDrawingDemo = new LedDrawingDemo(this); /** * Humidity and temperature demo... @@ -118,7 +118,7 @@ public void onAccuracyChanged(Sensor sensor, int accuracy) { senseHat.addHumidityTempatureSensorListener(humidityListener, temperatureListener); /** Simple Joystick demo*/ - this.joystickDemo = new JoystickDemo(sensorManager, new IGui() { + this.joystickDemo = new JoystickDemo(new IGui() { @Override public void setCursorInformations(final String xCoord, final String yCoord, final String color) diff --git a/SenseHatDriverDemo/src/main/java/com/eon/androidthings/sensehat/demos/JoystickDemo.java b/SenseHatDriverDemo/src/main/java/com/eon/androidthings/sensehat/demos/JoystickDemo.java index 71a2af2..b465fea 100644 --- a/SenseHatDriverDemo/src/main/java/com/eon/androidthings/sensehat/demos/JoystickDemo.java +++ b/SenseHatDriverDemo/src/main/java/com/eon/androidthings/sensehat/demos/JoystickDemo.java @@ -2,13 +2,12 @@ import android.graphics.Bitmap; import android.graphics.Color; -import android.hardware.SensorManager; +import com.eon.androidthings.sensehat.gui.IGui; import com.eon.androidthings.sensehatdriverlibrary.SenseHat; import com.eon.androidthings.sensehatdriverlibrary.devices.JoystickDirectionEnum; import com.eon.androidthings.sensehatdriverlibrary.devices.JoystickListener; import com.eon.androidthings.sensehatdriverlibrary.devices.LedMatrix; -import com.eon.androidthings.sensehat.gui.IGui; import java.io.IOException; @@ -29,7 +28,7 @@ public class JoystickDemo { private IGui gui; - public JoystickDemo(SensorManager sensorManager, IGui gui) throws IOException { + public JoystickDemo(IGui gui) throws IOException { this.gui = gui; SenseHat senseHat = SenseHat.getInstance(); diff --git a/SenseHatDriverDemo/src/main/java/com/eon/androidthings/sensehat/demos/LedDrawingDemo.java b/SenseHatDriverDemo/src/main/java/com/eon/androidthings/sensehat/demos/LedDrawingDemo.java new file mode 100644 index 0000000..cfe0744 --- /dev/null +++ b/SenseHatDriverDemo/src/main/java/com/eon/androidthings/sensehat/demos/LedDrawingDemo.java @@ -0,0 +1,89 @@ +package com.eon.androidthings.sensehat.demos; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; +import android.graphics.Rect; + +import com.eon.androidthings.sensehat.R; +import com.eon.androidthings.sensehatdriverlibrary.SenseHat; +import com.eon.androidthings.sensehatdriverlibrary.devices.LedMatrix; +import com.eon.androidthings.sensehatdriverlibrary.devices.fonts.BlackWhiteFont; +import com.eon.androidthings.sensehatdriverlibrary.devices.fonts.LEDFont; + +import java.io.IOException; + +/** + * LED Drawing Demo + */ + +public class LedDrawingDemo { + + public LedDrawingDemo(final Context context) throws IOException { + + //SenseHat.init(sensorManager); + // final LEDFont font = new MultiColorFont(assetmanager); + final LEDFont font = new BlackWhiteFont(context.getAssets()); + + // Draw one letter on the LED Matrix + // Bitmap letterBitmap = font.getBitmapForLetter('a'); + // SenseHat.getInstance().getLedMatrix().draw(letterBitmap); + + // infinity text scrolling + new Thread(new Runnable() { + @Override + public void run() { + try { + final LedMatrix ledMatrix = SenseHat.getInstance().getLedMatrix(); + // Render icon and text once and re-use. + final Bitmap iconBitmap = createIconBitmap(context.getResources()); + // TODO At the moment only uppercase letters are working + final Bitmap sentenceBitmap = font.getBitmapForSentence(" HELLO RASPI "); + do { + // Rotate iconBitmap a few times + for (int rotation = 0; rotation < 12; rotation++) { + ledMatrix.draw(iconBitmap, rotation); + Thread.sleep(500); + } + // Scroll the text on screen. + for (int currentX = 0; currentX < sentenceBitmap.getWidth() - LedMatrix.WIDTH; currentX++) { + // Using the currentX value, draw a specific segment of the sentenceBitmap. + ledMatrix.draw( + sentenceBitmap, currentX, 0, LedMatrix.WIDTH, LedMatrix.HEIGHT); + Thread.sleep(100); + } + } while (true); + } catch (Exception e) { + // TODO ExceptionHandling + e.printStackTrace(); + } + } + }).start(); + } + + Bitmap createIconBitmap(final Resources resources) { + // Setting up result canvas + final Bitmap result = Bitmap.createBitmap( + LedMatrix.WIDTH, LedMatrix.HEIGHT, Bitmap.Config.ARGB_8888, true); + final Canvas canvas = new Canvas(result); + // Background color and canvas Paint + canvas.drawColor(Color.BLUE); + final Paint paint = new Paint(); + paint.setColorFilter(new PorterDuffColorFilter(Color.GREEN, PorterDuff.Mode.SRC_IN)); + // Icon bitmap read + final Bitmap icon = BitmapFactory.decodeResource(resources, R.drawable.led_icon_android); + final Rect srcRect = new Rect(0, 0, icon.getWidth(), icon.getHeight()); + final Rect dstRect = new Rect(0, 0, canvas.getWidth(), canvas.getHeight()); + // Draw icon and recycle source bitmap + canvas.drawBitmap(icon, srcRect, dstRect, paint); + icon.recycle(); + return result; + } + +} diff --git a/SenseHatDriverDemo/src/main/java/com/eon/androidthings/sensehat/demos/TextScrollDemo.java b/SenseHatDriverDemo/src/main/java/com/eon/androidthings/sensehat/demos/TextScrollDemo.java deleted file mode 100644 index 70aa5d5..0000000 --- a/SenseHatDriverDemo/src/main/java/com/eon/androidthings/sensehat/demos/TextScrollDemo.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.eon.androidthings.sensehat.demos; - -import android.content.res.AssetManager; -import android.graphics.Bitmap; -import android.hardware.SensorManager; - -import com.eon.androidthings.sensehatdriverlibrary.SenseHat; -import com.eon.androidthings.sensehatdriverlibrary.devices.LedMatrix; -import com.eon.androidthings.sensehatdriverlibrary.devices.fonts.BlackWhiteFont; -import com.eon.androidthings.sensehatdriverlibrary.devices.fonts.LEDFont; - -import java.io.IOException; - -/** - * TextScroll-Demo - */ - -public class TextScrollDemo { - - - public TextScrollDemo(final SensorManager sensorManager, final AssetManager assetmanager) throws IOException { - - //SenseHat.init(sensorManager); - // final LEDFont font = new MultiColorFont(assetmanager); - final LEDFont font = new BlackWhiteFont(assetmanager); - - // Draw one letter on the LED Matrix - // Bitmap letterBitmap = font.getBitmapForLetter('a'); - // SenseHat.getInstance().getLedMatrix().draw(letterBitmap); - - // infinity text scrolling - new Thread(new Runnable() { - @Override - public void run() { - try { - do { - // TODO At the moment only uppercase letters are working - Bitmap sentenceBitmap = font.getBitmapForSentence(" HELLO RASPI "); - Bitmap targetBitmap = Bitmap.createBitmap(// - LedMatrix.WIDTH,// - LedMatrix.HEIGHT, // - Bitmap.Config.ARGB_8888); - - for (int currentX = 0; currentX < sentenceBitmap.getWidth() - LedMatrix.WIDTH; currentX++) { - // copy sentenceBitmap to targetBitmap - for (int y = 0; y < LedMatrix.HEIGHT; y++) { - - for (int x = 0; x < LedMatrix.WIDTH; x++) { - int color = sentenceBitmap.getPixel(currentX + x, y); - targetBitmap.setPixel(x, y, color); - } - } - SenseHat.getInstance().getLedMatrix().draw(targetBitmap); - Thread.sleep(100); - } - } while (true); - } catch (Exception e) { - // TODO ExceptionHandling - e.printStackTrace(); - } - } - }).start(); - } -} diff --git a/SenseHatDriverDemo/src/main/res/drawable/led_icon_android.png b/SenseHatDriverDemo/src/main/res/drawable/led_icon_android.png new file mode 100644 index 0000000..2e65fed Binary files /dev/null and b/SenseHatDriverDemo/src/main/res/drawable/led_icon_android.png differ diff --git a/SenseHatDriverLibrary/build.gradle b/SenseHatDriverLibrary/build.gradle index 3877478..0d7a08f 100644 --- a/SenseHatDriverLibrary/build.gradle +++ b/SenseHatDriverLibrary/build.gradle @@ -1,15 +1,15 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 26 + compileSdkVersion 28 defaultConfig { - minSdkVersion 26 - targetSdkVersion 26 + minSdkVersion 27 + targetSdkVersion 28 versionCode 1 versionName "1.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -25,10 +25,10 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.android.support:appcompat-v7:26.1.0' + implementation 'androidx.appcompat:appcompat:1.0.2' testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.1' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' - compileOnly 'com.google.android.things:androidthings:+' + compileOnly 'com.google.android.things:androidthings:1.0' } diff --git a/SenseHatDriverLibrary/src/main/java/com/eon/androidthings/sensehatdriverlibrary/devices/HumidityTemperatureSensor.java b/SenseHatDriverLibrary/src/main/java/com/eon/androidthings/sensehatdriverlibrary/devices/HumidityTemperatureSensor.java index 7c1d9ae..524eef9 100644 --- a/SenseHatDriverLibrary/src/main/java/com/eon/androidthings/sensehatdriverlibrary/devices/HumidityTemperatureSensor.java +++ b/SenseHatDriverLibrary/src/main/java/com/eon/androidthings/sensehatdriverlibrary/devices/HumidityTemperatureSensor.java @@ -1,13 +1,14 @@ package com.eon.androidthings.sensehatdriverlibrary.devices; -import android.support.annotation.IntDef; -import android.support.annotation.VisibleForTesting; import com.eon.androidthings.sensehatdriverlibrary.utils.I2CDeviceRegistry; import com.google.android.things.pio.I2cDevice; import java.io.IOException; +import androidx.annotation.IntDef; +import androidx.annotation.VisibleForTesting; + /** * I2C Address 0x5f: HTS221 Humidity/Temperature */ diff --git a/SenseHatDriverLibrary/src/main/java/com/eon/androidthings/sensehatdriverlibrary/devices/LedMatrix.java b/SenseHatDriverLibrary/src/main/java/com/eon/androidthings/sensehatdriverlibrary/devices/LedMatrix.java index e64b9c2..e38a4a6 100644 --- a/SenseHatDriverLibrary/src/main/java/com/eon/androidthings/sensehatdriverlibrary/devices/LedMatrix.java +++ b/SenseHatDriverLibrary/src/main/java/com/eon/androidthings/sensehatdriverlibrary/devices/LedMatrix.java @@ -8,6 +8,12 @@ import com.google.android.things.pio.I2cDevice; import java.io.IOException; +import java.util.Iterator; + +import androidx.annotation.ColorInt; +import androidx.annotation.IntRange; +import androidx.annotation.NonNull; +import androidx.annotation.Size; /** * Driver for the SenseHat LED matrix. @@ -22,10 +28,19 @@ public class LedMatrix implements AutoCloseable { public static final int WIDTH = 8; public static final int HEIGHT = 8; + public static final int ROTATE_NONE = 0; + public static final int ROTATE_CW1 = 1; + public static final int ROTATE_CW2 = 2; + public static final int ROTATE_CW3 = 3; + public static final int ROTATE_CCW1 = -1; + public static final int ROTATE_CCW2 = -2; + public static final int ROTATE_CCW3 = -3; // ----------------------------------------------------- Instance Variables private static final int BUFFER_SIZE = WIDTH * HEIGHT * 3 + 1; // pixel and RGB - private byte[] mBuffer = new byte[BUFFER_SIZE]; + + private final byte[] mBuffer = new byte[BUFFER_SIZE]; + private final Positioner mPositioner = new Positioner(); // Defaults to ROTATE_NONE private I2cDevice i2cDevice; @@ -33,15 +48,24 @@ public class LedMatrix implements AutoCloseable { /** * Create a new LED matrix driver connected on the given I2C bus. - * - * @throws IOException */ - public LedMatrix(I2cDevice i2cDevice) throws IOException { + public LedMatrix(final I2cDevice i2cDevice) { this.i2cDevice = i2cDevice; } // --------------------------------------------------------- Public Methods + /** + * Change the orientation of draws to the LED matrix. + * + * This is the global rotations value for standard draws to the LED matrix. + * + * @param rotations The number of 90 degree rotations to apply to the matrix. + */ + public void setRotation(@IntRange(from = -3,to = 3) final int rotations) { + this.mPositioner.setRotations(rotations); + } + /** * Close the driver and the underlying device. * @@ -64,7 +88,7 @@ public void close() throws IOException { * @param color Color to draw * @throws IOException */ - public void draw(int color) throws IOException { + public void draw(@ColorInt final int color) throws IOException { this.mBuffer[0] = 0; float a = Color.alpha(color) / 255.f; byte r = (byte) ((int) (Color.red(color) * a) >> 3); @@ -81,29 +105,132 @@ public void draw(int color) throws IOException { } /** - * Draw the given drawable to the LED matrix. + * Draw the given drawable to the LED matrix. Uses the global rotations value. * * @param drawable Drawable to draw * @throws IOException */ - public void draw(Drawable drawable) throws IOException { - Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, - Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); + public void draw(@NonNull final Drawable drawable) throws IOException { + final Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888); + final Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, WIDTH, HEIGHT); drawable.draw(canvas); this.draw(bitmap); } /** - * Draw the given bitmap to the LED matrix. + * Draw the given drawable to the LED matrix with a specified rotations value. + * + * @param drawable Drawable to draw + * @param rotations An integer representing the amount of 90 degree rotations. + * @throws IOException + */ + public void draw(@NonNull final Drawable drawable, final int rotations) throws IOException { + final Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888); + final Canvas canvas = new Canvas(bitmap); + drawable.setBounds(0, 0, WIDTH, HEIGHT); + drawable.draw(canvas); + this.draw(bitmap, rotations); + } + + /** + * Draw the given bitmap to the LED matrix. Uses the global rotations value. * * @param bitmap Bitmap to draw * @throws IOException */ - public void draw(Bitmap bitmap) throws IOException { - Bitmap dest = Bitmap.createScaledBitmap(bitmap, 8, 8, true); - this.mBuffer[0] = 0; + public void draw(@NonNull final Bitmap bitmap) throws IOException { + if (this.mPositioner.rotations != ROTATE_NONE) { + final Iterator iterator = mPositioner.iterator(); + this.drawBitmapPositioned(bitmap, iterator); + return; + } + this.drawBitmap(bitmap); + } + + /** + * Draw the given bitmap to the LED matrix with a specified rotations value. + * + * @param bitmap Bitmap to draw + * @param rotations An integer representing the amount of 90 degree rotations. + * @throws IOException + */ + public void draw(@NonNull final Bitmap bitmap, final int rotations) throws IOException { + if (rotations == ROTATE_NONE) { + this.drawBitmap(bitmap); + } else { + final Iterator iterator = mPositioner.iterator(rotations); + this.drawBitmapPositioned(bitmap, iterator); + } + } + + /** + * Draw a range of the given bitmap to the LED matrix. Uses the global rotations value. + * + * @param bitmap Bitmap to draw + * @param startX Starting X position of the bitmap + * @param startY Starting Y position of the bitmap + * @param width Width in pixels from the starting X position + * @param height Height in pixels from the starting Y position + * @throws IOException + * @throws IllegalArgumentException + */ + public void draw(@NonNull final Bitmap bitmap, + final int startX, + final int startY, + final int width, + final int height) throws IOException { + + if (width > WIDTH || height > HEIGHT) { + throw new IllegalArgumentException("Invalid bounds; too large for LED Matrix."); + } else if (startX < 0 || startY < 0 + || (startX + width) > bitmap.getWidth() + || (startY + height) > bitmap.getHeight()) { + + throw new IllegalArgumentException( + "Invalid bounds; boundary out of bitmap dimension range."); + } + final Iterator iterator = + mPositioner.withBounds(startX, startY, width, height).iterator(); + this.drawBitmapPositioned(bitmap, iterator); + } + + /** + * Draw a range of the given bitmap to the LED matrix with a specified rotations value. + * + * @param bitmap Bitmap to draw + * @param startX Starting X position of the bitmap + * @param startY Starting Y position of the bitmap + * @param width Width in pixels from the starting X position + * @param height Height in pixels from the starting Y position + * @param rotations An integer representing the amount of 90 degree rotations. + * @throws IOException + * @throws IllegalArgumentException + */ + public void draw(@NonNull final Bitmap bitmap, + final int startX, + final int startY, + final int width, + final int height, + final int rotations) throws IOException { + + if (width > WIDTH || height > HEIGHT) { + throw new IllegalArgumentException("Invalid bounds; too large for LED Matrix."); + } else if (startX < 0 || startY < 0 + || (startX + width) > bitmap.getWidth() + || (startY + height) > bitmap.getHeight()) { + + throw new IllegalArgumentException( + "Invalid bounds; boundary out of bitmap dimension range."); + } + final Iterator iterator = + mPositioner.withBounds(startX, startY, width, height).iterator(rotations); + this.drawBitmapPositioned(bitmap, iterator); + } + + // -------------------------------------------------------- Private Methods + + private void drawBitmap(@NonNull final Bitmap bitmap) throws IOException { for (int y = 0; y < HEIGHT; y++) { for (int x = 0; x < WIDTH; x++) { int p = bitmap.getPixel(x, y); @@ -116,5 +243,272 @@ public void draw(Bitmap bitmap) throws IOException { this.i2cDevice.write(this.mBuffer, this.mBuffer.length); } - // -------------------------------------------------------- Private Methods + private void drawBitmapPositioned(@NonNull final Bitmap bitmap, + final Iterator positionIterator) throws IOException { + + while (positionIterator.hasNext()) { + final Position position = positionIterator.next(); + final int p = bitmap.getPixel(position.fromX, position.fromY); + float a = Color.alpha(p) / 255.f; + this.mBuffer[1 + position.toX + WIDTH * 0 + 3 * WIDTH * position.toY] = + (byte) ((int) (Color.red(p) * a) >> 3); + this.mBuffer[1 + position.toX + WIDTH * 1 + 3 * WIDTH * position.toY] = + (byte) ((int) (Color.green(p) * a) >> 3); + this.mBuffer[1 + position.toX + WIDTH * 2 + 3 * WIDTH * position.toY] = + (byte) ((int) (Color.blue(p) * a) >> 3); + } + this.i2cDevice.write(this.mBuffer, this.mBuffer.length); + } + + /** + * Iterable class for managing bitmap positioning and rotation during draws to the LED matrix. + */ + private static class Positioner implements Iterable { + + private int rotations = 0; + private int startX = -1; + private int startY = -1; + private int width = WIDTH; + private int height = HEIGHT; + + /** + * Normalize the given rotations value to the range of -3 to +3 + * + * @param rotations An integer representing the amount of 90 degree rotations. + * @return The normalized rotations value. + */ + int normalizeRotations(final int rotations) { + if (rotations < 0) { + return ((rotations < -3) ? rotations % 4 : rotations) + 4; + } else { + return (rotations > 3) ? rotations % 4 : rotations; + } + } + + /** + * Set the default rotations value for this positioner. + * + * @param rotations An integer representing the amount of 90 degree rotations. + */ + void setRotations(@IntRange(from = -3, to = 3) final int rotations) { + this.rotations = normalizeRotations(rotations); + } + + /** + * Creates a new OnPositionListener for managing coordinate logic in the Positioner's iterator. + * + * @param rotations An integer representing the amount of 90 degree rotations. + * @return The requested OnPositionListener for the given rotations. + */ + OnPositionListener createListener(final int rotations) { + switch (rotations) { + case 1: // ROTATE_CW1, ROTATE_CCW3 + return new OnPositionListener() { + @Override + public int[] initPositionedCoords() { + return new int[]{WIDTH - 1, 0}; + } + + @Override + public void updatePositionedCoords(int[] coords) { + coords[1]++; + if (coords[1] == HEIGHT) { + coords[1] = 0; + coords[0]--; + } + } + }; + case 2: // ROTATE_CW2, ROTATE_CCW2 + return new OnPositionListener() { + @Override + public int[] initPositionedCoords() { + return new int[]{WIDTH - 1, HEIGHT - 1}; + } + + @Override + public void updatePositionedCoords(int[] coords) { + coords[0]--; + if (coords[0] == -1) { + coords[0] = WIDTH - 1; + coords[1]--; + } + } + }; + case 3: // ROTATE_CW3, ROTATE_CCW1 + return new OnPositionListener() { + @Override + public int[] initPositionedCoords() { + return new int[]{0, HEIGHT - 1}; + } + + @Override + public void updatePositionedCoords(int[] coords) { + coords[1]--; + if (coords[1] == -1) { + coords[1] = HEIGHT - 1; + coords[0]++; + } + } + }; + case 0: // ROTATE_NONE + case 4: + default: + return new OnPositionListener() { + @Override + public int[] initPositionedCoords() { + return new int[]{0, 0}; + } + + @Override + public void updatePositionedCoords(int[] coords) { + coords[0]++; + if (coords[0] == WIDTH) { + coords[0] = 0; + coords[1]++; + } + } + }; + } + } + + /** + * Set the bounds of the next PositionIterator created. + * + * @param startX Starting X position + * @param startY Starting Y position + * @param width Width in pixels from the starting X position + * @param height Height in pixels from the starting Y position + * @return This positioner. + */ + Positioner withBounds(final int startX, final int startY, final int width, final int height) { + this.startX = startX; + this.startY = startY; + this.width = width; + this.height = height; + return this; + } + + /** + * Create a new PositionIterator using a specified rotations value. + * + * @param rotations An integer representing the amount of 90 degree rotations. + * @return The requested PositionIterator. + */ + Iterator createIterator(final int rotations) { + final PositionIterator iterator; + if (startX > -1 || startY > -1) { + iterator = new PositionIterator(createListener(rotations), startX, startY, width, height); + startX = -1; + startY = -1; + } else { + iterator = new PositionIterator(createListener(rotations)); + } + return iterator; + } + + /** + * Create a new PositionIterator. Uses the global rotations value. + * + * @return The requested PositionIterator. + */ + @Override + public Iterator iterator() { + return createIterator(this.rotations); + } + + /** + * Create a new PositionIterator using a specified rotations value. + * + * @param rotations An integer representing the amount of 90 degree rotations. + * @return The requested PositionIterator. + */ + public Iterator iterator(final int rotations) { + return createIterator(normalizeRotations(rotations)); + } + + } + + private interface OnPositionListener { + /** + * Initialize the starting coordinates for the positioning action. + * @return an integer array with the initial values for the positioned X and Y. + */ + @NonNull + @Size(value = 2) + int[] initPositionedCoords(); + + /** + * Update the given rotated X and Y values. Runs when PositionIterator.next() is called. + * @param coords An array containing the X and Y values to be updated. + */ + void updatePositionedCoords(@NonNull @Size(value = 2) final int[] coords); + } + + private static class PositionIterator implements Iterator { + + private final OnPositionListener onRotationListener; + @Size(value = 2) + private final int[] positionedCoords; + + private final int startX; + private final int endX, endY; + + private int x, y; + + public PositionIterator(@NonNull final OnPositionListener onRotationListener) { + this(onRotationListener, 0, 0, WIDTH, HEIGHT); + } + + public PositionIterator(@NonNull final OnPositionListener onRotationListener, + final int startX, + final int startY, + final int width, + final int height) { + + if (null == onRotationListener) { + throw new IllegalArgumentException("onRotationListener must not be null."); + } + this.onRotationListener = onRotationListener; + positionedCoords = onRotationListener.initPositionedCoords(); + + // Bitmap looping values + this.startX = startX; + x = startX; + y = startY; + endX = x + width; + endY = y + height; + } + + @Override + public boolean hasNext() { + return y < endY; + } + + @Override + public Position next() { + final Position result = new Position(x++, y, positionedCoords[0], positionedCoords[1]); + if (x == endX) { + x = startX; + y++; + } + onRotationListener.updatePositionedCoords(positionedCoords); + return result; + } + + } + + private static class Position { + + private final int fromX, fromY; + private final int toX, toY; + + public Position(int fromX, int fromY, int toX, int toY) { + this.fromX = fromX; + this.fromY = fromY; + this.toX = toX; + this.toY = toY; + } + + } + } \ No newline at end of file diff --git a/build.gradle b/build.gradle index bc08de4..e00d775 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.0.1' + classpath 'com.android.tools.build:gradle:3.3.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3327252..749f530 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Jan 24 15:25:15 CET 2018 +#Sat Feb 09 11:29:50 CST 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip diff --git a/sensehatdriverdemo/.gitignore b/sensehatdriverdemo/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/sensehatdriverdemo/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/sensehatdriverdemo/gradle/wrapper/gradle-wrapper.jar b/sensehatdriverdemo/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 13372ae..0000000 Binary files a/sensehatdriverdemo/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/sensehatdriverdemo/gradle/wrapper/gradle-wrapper.properties b/sensehatdriverdemo/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 9ba40f1..0000000 --- a/sensehatdriverdemo/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Feb 09 10:17:50 CET 2018 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip diff --git a/sensehatdriverdemo/src/main/java/com/eon/androidthinks/sensehat/demos/HumidityTemperatureDemo.java b/sensehatdriverdemo/src/main/java/com/eon/androidthinks/sensehat/demos/HumidityTemperatureDemo.java deleted file mode 100644 index e3c9265..0000000 --- a/sensehatdriverdemo/src/main/java/com/eon/androidthinks/sensehat/demos/HumidityTemperatureDemo.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.eon.androidthinks.sensehat.demos; - -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; - -import com.eon.androidthings.sensehatdriverlibrary.SenseHat; - -import java.io.IOException; - -/** - * Created by o0632 on 31.01.2018. - */ - -public class HumidityTemperatureDemo { - - - private final SensorManager sensorManager; - - public HumidityTemperatureDemo(SensorManager sensorManager) throws IOException { - - this.sensorManager = sensorManager; - - - SenseHat senseHat = SenseHat.init(sensorManager); - - SensorEventListener humidityListener = new SensorEventListener() { - @Override - public void onSensorChanged(SensorEvent event) { - System.out.println("HUM-Value:" + event.values[0]); - } - - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) { - System.out.println("HUM-ACUU:" + sensor + " acc:''" + accuracy); - } - }; - - SensorEventListener temperatureListener = new SensorEventListener() { - @Override - public void onSensorChanged(SensorEvent event) { - System.out.println("TEMP-Value:" + event.values[0]); - } - - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) { - System.out.println("TEMP-ACUU:" + sensor + " acc:''" + accuracy); - } - }; - - - senseHat.addHumidityTempatureSensorListener(humidityListener, temperatureListener); - - } - -} diff --git a/sensehatdriverdemo/src/main/res/values/styles.xml b/sensehatdriverdemo/src/main/res/values/styles.xml deleted file mode 100644 index b6b9204..0000000 --- a/sensehatdriverdemo/src/main/res/values/styles.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - -