getHandleOffsets method
Returns pixel positions of all interactive handles for this drawing.
Implementation
List<Offset> getHandleOffsets(
Rect bounds,
PriceRange priceRange,
CoordinateConverter converter,
) {
if (points.isEmpty) return const [];
switch (tool) {
case DrawingTool.pointer:
return const [];
case DrawingTool.trendline:
case DrawingTool.extendedTrendline:
case DrawingTool.arrow:
case DrawingTool.ruler:
if (points.length < 2) {
final x = converter.indexToX(points[0].candleIndex);
final y = CoordinateConverter.priceToY(
points[0].price,
bounds,
priceRange,
);
return [Offset(x, y)];
}
final x1 = converter.indexToX(points[0].candleIndex);
final y1 = CoordinateConverter.priceToY(
points[0].price,
bounds,
priceRange,
);
final x2 = converter.indexToX(points[1].candleIndex);
final y2 = CoordinateConverter.priceToY(
points[1].price,
bounds,
priceRange,
);
return [Offset(x1, y1), Offset(x2, y2)];
case DrawingTool.horizontalLine:
final y = CoordinateConverter.priceToY(
points[0].price,
bounds,
priceRange,
);
return [
Offset(bounds.left + 50.0, y),
Offset(bounds.center.dx, y),
Offset(bounds.right - 50.0, y),
];
case DrawingTool.horizontalRay:
final x = converter.indexToX(points[0].candleIndex);
final y = CoordinateConverter.priceToY(
points[0].price,
bounds,
priceRange,
);
return [
Offset(x, y),
Offset(((x + bounds.right) / 2).clamp(x + 20.0, bounds.right), y),
];
case DrawingTool.verticalLine:
final x = converter.indexToX(points[0].candleIndex);
return [
Offset(x, bounds.top + 40.0),
Offset(x, bounds.center.dy),
Offset(x, bounds.bottom - 40.0),
];
case DrawingTool.rectangle:
if (points.length < 2) {
final x = converter.indexToX(points[0].candleIndex);
final y = CoordinateConverter.priceToY(
points[0].price,
bounds,
priceRange,
);
return [Offset(x, y)];
}
final x1 = converter.indexToX(points[0].candleIndex);
final y1 = CoordinateConverter.priceToY(
points[0].price,
bounds,
priceRange,
);
final x2 = converter.indexToX(points[1].candleIndex);
final y2 = CoordinateConverter.priceToY(
points[1].price,
bounds,
priceRange,
);
final left = math.min(x1, x2);
final right = math.max(x1, x2);
final top = math.min(y1, y2);
final bottom = math.max(y1, y2);
final midX = (left + right) / 2;
final midY = (top + bottom) / 2;
return [
Offset(left, top), // 0: Top-Left corner
Offset(right, top), // 1: Top-Right corner
Offset(right, bottom), // 2: Bottom-Right corner
Offset(left, bottom), // 3: Bottom-Left corner
Offset(midX, top), // 4: Top Edge
Offset(right, midY), // 5: Right Edge
Offset(midX, bottom), // 6: Bottom Edge
Offset(left, midY), // 7: Left Edge
];
case DrawingTool.fibonacci:
if (points.length < 2) return const [];
final x1 = converter.indexToX(points[0].candleIndex);
final y1 = CoordinateConverter.priceToY(
points[0].price,
bounds,
priceRange,
);
final x2 = converter.indexToX(points[1].candleIndex);
final y2 = CoordinateConverter.priceToY(
points[1].price,
bounds,
priceRange,
);
return [Offset(x1, y1), Offset(x2, y2)];
case DrawingTool.longPosition:
case DrawingTool.shortPosition:
final isLong = tool == DrawingTool.longPosition;
final entry = points.first;
final entryX = converter.indexToX(entry.candleIndex);
final entryY = CoordinateConverter.priceToY(
entry.price,
bounds,
priceRange,
);
final widthSpan = (properties['widthSpan'] as double?) ?? (40 * 11.0);
final rightX = (entryX + widthSpan).clamp(entryX + 50.0, bounds.right);
final targetPrice = properties['targetPrice'] as double? ??
(isLong ? entry.price * 1.015 : entry.price * 0.985);
final stopPrice = properties['stopPrice'] as double? ??
(isLong ? entry.price * 0.9925 : entry.price * 1.0075);
final targetY = CoordinateConverter.priceToY(
targetPrice,
bounds,
priceRange,
);
final stopY = CoordinateConverter.priceToY(
stopPrice,
bounds,
priceRange,
);
return [
Offset((entryX + rightX) / 2, targetY),
Offset((entryX + rightX) / 2, stopY),
Offset(entryX, entryY),
Offset(rightX, entryY),
];
case DrawingTool.parallelChannel:
if (points.length < 2) return const [];
final px1 = converter.indexToX(points[0].candleIndex);
final py1 = CoordinateConverter.priceToY(points[0].price, bounds, priceRange);
final px2 = converter.indexToX(points[1].candleIndex);
final py2 = CoordinateConverter.priceToY(points[1].price, bounds, priceRange);
if (points.length >= 3) {
final py3 = CoordinateConverter.priceToY(points[2].price, bounds, priceRange);
return [Offset(px1, py1), Offset(px2, py2), Offset(px1, py3)];
}
return [Offset(px1, py1), Offset(px2, py2)];
case DrawingTool.textLabel:
if (points.isEmpty) return const [];
final lx = converter.indexToX(points[0].candleIndex);
final ly = CoordinateConverter.priceToY(points[0].price, bounds, priceRange);
return [Offset(lx, ly)];
}
}