[Nanoleaf] Support lines (#13881)
Lines is a Nanoleaf shape we haven't been able to test earlier. Now we have tested them, and added support for painting them as well. They do unfortunately not support touch gestures. Signed-off-by: Jørgen Austvik <jaustvik@acm.org>
This commit is contained in:
parent
0e68936663
commit
02398b14a3
|
@ -33,8 +33,8 @@ You can set the **color** for each panel and in the case of a Nanoleaf Canvas or
|
|||
| Shapes Mini Triangles | NL48 | Mini Triangles | X | X |
|
||||
| Elements Hexagon | NL52 | Elements Hexagons | X | X |
|
||||
| Smart Bulb | NL45 | Smart Bulb | - | |
|
||||
| Lightstrip | NL55 | Lightstrip | - | |
|
||||
| Lines | NL59 | Lines | - | |
|
||||
| Lightstrip | NL55 | Lightstrip | - | - |
|
||||
| Lines | NL59 | Lines | X | |
|
||||
| Canvas | NL29 | Squares | X | X |
|
||||
|
||||
x = Supported (-) = unknown (no device available to test)
|
||||
|
|
|
@ -35,9 +35,9 @@ public enum ShapeType {
|
|||
SHAPES_CONTROLLER("Controller (Shapes)", 12, 0, 0, 1, DrawingAlgorithm.NONE),
|
||||
ELEMENTS_HEXAGON("Elements Hexagon", 14, 134, 6, 1, DrawingAlgorithm.HEXAGON),
|
||||
ELEMENTS_HEXAGON_CORNER("Elements Hexagon - Corner", 15, 58, 6, 6, DrawingAlgorithm.CORNER),
|
||||
LINES_CONNECTOR("Lines Connector", 16, 11, 1, 1, DrawingAlgorithm.LINE),
|
||||
LINES_CONNECTOR("Lines Connector", 16, 11, 1, 1, DrawingAlgorithm.NONE),
|
||||
LIGHT_LINES("Light Lines", 17, 154, 1, 1, DrawingAlgorithm.LINE),
|
||||
LINES_LINES_SINGLE("Light Lines - Single Sone", 18, 77, 1, 1, DrawingAlgorithm.LINE),
|
||||
LINES_LINES_SINGLE("Light Lines - Single Sone", 18, 77, 2, 2, DrawingAlgorithm.LINE),
|
||||
CONTROLLER_CAP("Controller Cap", 19, 11, 0, 1, DrawingAlgorithm.NONE),
|
||||
POWER_CONNECTOR("Power Connector", 20, 11, 0, 1, DrawingAlgorithm.NONE);
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* Copyright (c) 2010-2022 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.nanoleaf.internal.layout.shape;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.nanoleaf.internal.layout.DrawingSettings;
|
||||
import org.openhab.binding.nanoleaf.internal.layout.PanelState;
|
||||
import org.openhab.binding.nanoleaf.internal.layout.Point2D;
|
||||
import org.openhab.binding.nanoleaf.internal.layout.ShapeType;
|
||||
|
||||
/**
|
||||
* A panel that shouldn't be drawn (power connector, controller, ...).
|
||||
*
|
||||
* Especially lines can have controllers and power connectors etc on top of each other.
|
||||
*
|
||||
* @author Jørgen Austvik - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class NoDraw extends Panel {
|
||||
|
||||
private final Point2D position;
|
||||
|
||||
public NoDraw(ShapeType shapeType, int panelId, Point2D position) {
|
||||
super(shapeType);
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Point2D> generateOutline() {
|
||||
return Arrays.asList(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D graphics, DrawingSettings settings, PanelState state) {
|
||||
}
|
||||
}
|
|
@ -81,13 +81,21 @@ public class PanelFactory {
|
|||
Point2D pos3 = new Point2D(hexShape.getPosX(), hexShape.getPosY());
|
||||
return new Hexagon(shapeType, hexShape.getPanelId(), pos3, hexShape.getOrientation());
|
||||
|
||||
case LINE:
|
||||
return new SingleLine(shapeType, positionDatum);
|
||||
|
||||
case CORNER:
|
||||
return new HexagonCorners(shapeType, positionDatum);
|
||||
|
||||
case NONE:
|
||||
PositionDatum noShape = positionDatum.get(0);
|
||||
Point2D pos4 = new Point2D(noShape.getPosX(), noShape.getPosY());
|
||||
return new NoDraw(shapeType, noShape.getPanelId(), pos4);
|
||||
|
||||
default:
|
||||
PositionDatum shape = positionDatum.get(0);
|
||||
Point2D pos4 = new Point2D(shape.getPosX(), shape.getPosY());
|
||||
return new Point(shapeType, shape.getPanelId(), pos4);
|
||||
Point2D pos5 = new Point2D(shape.getPosX(), shape.getPosY());
|
||||
return new Point(shapeType, shape.getPanelId(), pos5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/**
|
||||
* Copyright (c) 2010-2022 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.nanoleaf.internal.layout.shape;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Stroke;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.nanoleaf.internal.layout.DrawingSettings;
|
||||
import org.openhab.binding.nanoleaf.internal.layout.ImagePoint2D;
|
||||
import org.openhab.binding.nanoleaf.internal.layout.PanelState;
|
||||
import org.openhab.binding.nanoleaf.internal.layout.Point2D;
|
||||
import org.openhab.binding.nanoleaf.internal.layout.ShapeType;
|
||||
import org.openhab.binding.nanoleaf.internal.model.PositionDatum;
|
||||
import org.openhab.core.library.types.HSBType;
|
||||
|
||||
/**
|
||||
* A single line.
|
||||
*
|
||||
* @author Jørgen Austvik - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SingleLine extends Panel {
|
||||
|
||||
private static final int CORNER_DIAMETER = 4;
|
||||
private static final int LINE_WIDTH = 6;
|
||||
|
||||
private final List<PositionDatum> corners;
|
||||
|
||||
public SingleLine(ShapeType shapeType, List<PositionDatum> corners) {
|
||||
super(shapeType);
|
||||
|
||||
this.corners = Collections.unmodifiableList(new ArrayList<>(corners));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Point2D> generateOutline() {
|
||||
List<Point2D> result = new ArrayList<>(corners.size());
|
||||
for (PositionDatum corner : corners) {
|
||||
result.add(new Point2D(corner.getPosX(), corner.getPosY()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D graphics, DrawingSettings settings, PanelState state) {
|
||||
List<ImagePoint2D> outline = settings.generateImagePoints(generateOutline());
|
||||
Polygon p = new Polygon();
|
||||
for (int i = 0; i < outline.size(); i++) {
|
||||
ImagePoint2D pos = outline.get(i);
|
||||
p.addPoint(pos.getX(), pos.getY());
|
||||
}
|
||||
|
||||
if (settings.shouldFillWithColor()) {
|
||||
Color corner1Color = getColor(corners.get(0).getPanelId(), state);
|
||||
Color corner2Color = getColor(corners.get(0).getPanelId(), state);
|
||||
|
||||
ImagePoint2D center = findCenter(outline);
|
||||
|
||||
Stroke oldStroke = graphics.getStroke();
|
||||
Stroke lineStroke = new BasicStroke(LINE_WIDTH, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
|
||||
graphics.setStroke(lineStroke);
|
||||
graphics.setColor(corner1Color);
|
||||
graphics.drawLine(outline.get(0).getX(), outline.get(0).getY(), center.getX(), center.getY());
|
||||
graphics.setColor(corner2Color);
|
||||
graphics.drawLine(outline.get(1).getX(), outline.get(1).getY(), center.getX(), center.getY());
|
||||
graphics.setStroke(oldStroke);
|
||||
}
|
||||
|
||||
if (settings.shouldDrawOutline()) {
|
||||
graphics.setColor(settings.getOutlineColor());
|
||||
graphics.drawPolygon(p);
|
||||
}
|
||||
|
||||
if (settings.shouldDrawCorners()) {
|
||||
for (PositionDatum corner : corners) {
|
||||
ImagePoint2D position = settings.generateImagePoint(new Point2D(corner.getPosX(), corner.getPosY()));
|
||||
graphics.setColor(getColor(corner.getPanelId(), state));
|
||||
graphics.fillOval(position.getX() - CORNER_DIAMETER / 2, position.getY() - CORNER_DIAMETER / 2,
|
||||
CORNER_DIAMETER, CORNER_DIAMETER);
|
||||
|
||||
if (settings.shouldDrawOutline()) {
|
||||
graphics.setColor(settings.getOutlineColor());
|
||||
graphics.drawOval(position.getX() - CORNER_DIAMETER / 2, position.getY() - CORNER_DIAMETER / 2,
|
||||
CORNER_DIAMETER, CORNER_DIAMETER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.shouldDrawLabels()) {
|
||||
graphics.setColor(settings.getLabelColor());
|
||||
|
||||
for (PositionDatum corner : corners) {
|
||||
ImagePoint2D position = settings.generateImagePoint(new Point2D(corner.getPosX(), corner.getPosY()));
|
||||
graphics.drawString(Integer.toString(corner.getPanelId()), position.getX(), position.getY());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ImagePoint2D findCenter(List<ImagePoint2D> outline) {
|
||||
Point2D[] bounds = findBounds(outline);
|
||||
int midX = bounds[0].getX() + (bounds[1].getX() - bounds[0].getX()) / 2;
|
||||
int midY = bounds[0].getY() + (bounds[1].getY() - bounds[0].getY()) / 2;
|
||||
return new ImagePoint2D(midX, midY);
|
||||
}
|
||||
|
||||
private static Color getColor(int panelId, PanelState state) {
|
||||
HSBType color = state.getHSBForPanel(panelId);
|
||||
return new Color(color.getRGB());
|
||||
}
|
||||
}
|
|
@ -47,7 +47,8 @@ public class NanoleafLayoutTest {
|
|||
static @Nullable Path temporaryDirectory;
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "lasvegas.json", "theduck.json", "squares.json", "wings.json", "spaceinvader.json" })
|
||||
@ValueSource(strings = { "lasvegas.json", "theduck.json", "squares.json", "wings.json", "spaceinvader.json",
|
||||
"lines.json" })
|
||||
public void testFile(String fileName) throws Exception {
|
||||
Path file = Path.of("src/test/resources/", fileName);
|
||||
assertTrue(Files.exists(file), "File should exist: " + file);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{"name":"Lines","serialNo":"S1234567","manufacturer":"Nanoleaf","firmwareVersion":"7.1.0","hardwareVersion":"0.0.4-0","model":"NL59","discovery":null,"effects":{"effectsList":["Beat Drop","Cotton Candy","Cozy Blaze","Fiesta","Good Vibes","Hip Hop","Jalapeno Heat","Kaleidoscope","Mountain Air","Mystic Night","Neon Dreams","Northern Lights","Pop Rocks","Prism","Radioactive","Raspberry Lemonade","Sakura Blossom","Starry Sky","Tuscany Sunset","Waterfall"],"select":"Raspberry Lemonade"},"firmwareUpgrade":null,"panelLayout":{"globalOrientation":{"value":88,"max":360,"min":0},"layout":{"numPanels":13,"sideLength":154,"positionData":[{"panelId":15376,"x":227,"y":337,"o":0,"shapeType":20},{"panelId":12105,"x":227,"y":212,"o":0,"shapeType":18},{"panelId":56841,"x":227,"y":289,"o":0,"shapeType":18},{"panelId":24127,"x":227,"y":164,"o":120,"shapeType":16},{"panelId":55776,"x":119,"y":274,"o":300,"shapeType":18},{"panelId":10400,"x":185,"y":313,"o":300,"shapeType":18},{"panelId":54069,"x":77,"y":250,"o":180,"shapeType":16},{"panelId":6876,"x":119,"y":226,"o":240,"shapeType":18},{"panelId":35357,"x":185,"y":188,"o":240,"shapeType":18},{"panelId":45376,"x":77,"y":125,"o":0,"shapeType":18},{"panelId":16384,"x":77,"y":202,"o":0,"shapeType":18},{"panelId":49828,"x":77,"y":77,"o":300,"shapeType":16},{"panelId":5591,"x":227,"y":337,"o":0,"shapeType":19}]}},"qkihnokomhartlnp":{},"schedules":{},"state":{"brightness":{"value":63,"max":100,"min":0},"colorMode":"effect","ct":{"value":4000,"max":6500,"min":1200},"hue":{"value":0,"max":360,"min":0},"on":{"value":true},"sat":{"value":0,"max":100,"min":0}}}
|
Loading…
Reference in New Issue