package lib.ui; import util.Vec.Vec2; import kernel.ui.TermBuffer.Pixel; abstract Canvas(Array>) to Array> { inline public function new() { this = [[]]; } public inline function set(i:Vec2, pixel:Pixel) { if (this[i.y] == null) { this[i.y] = []; } this[i.y][i.x] = pixel; } public inline function get(i:Vec2):Pixel { return this[i.y][i.x]; } public function keyValueIterator():KeyValueIterator, Pixel> { return new CanvasKeyValueIterator(this); } public function combine(other:Canvas, offset:Vec2) { for (key => value in other) { if (value == null) { continue; } var y = offset.y + key.y; var x = offset.x + key.x; if (this[y] == null) { this[y] = []; } this[y][x] = value; } } public function hight():Int { return this.length; } public function maxWidth() { var max = 0; for (i in 0...this.length) { if (this[i].length > max) { max = this[i].length; } } return max; } } class CanvasKeyValueIterator { private final canvas:Array>; private var index:Vec2 = {x: 0, y: 0}; @:allow(lib.ui.Canvas) private function new(canvas:Array>) { this.canvas = canvas; } public function hasNext():Bool { return index.y < canvas.length && index.x <= canvas[index.y].length; } public function next():{key:Vec2, value:Pixel} { var oldIndex:Vec2 = this.index; if (index.x >= canvas[index.y].length) { // Goto next line index = {x: 0, y: index.y + 1}; } else { // Goto next pixel in line index = {x: index.x + 1, y: index.y}; } return { key: oldIndex, value: this.canvas[oldIndex.y][oldIndex.x] }; } }