blob: 5a060460d612c1eb48c8bb71a2a6adfc73dbce77 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:collection' show ListBase;
import 'package:quiver/core.dart';
/// Generic class for layout elements: provides the box coordinates of
/// viewport position and the element to place at that position.
abstract class LayoutElement<T> {
/// Box layout for this Element
final double x, y, w, h;
/// The element positioned at this location
final T element;
/// Constructor
LayoutElement({this.x, this.y, this.w, this.h, this.element});
/// Override comparator so LayoutElements with the same values evaluate to
/// equal.
@override
bool operator ==(dynamic other) =>
other is LayoutElement &&
x == other.x &&
y == other.y &&
w == other.w &&
h == other.h &&
element == other.element;
/// get hashCode
@override
int get hashCode {
return hash4(
(w - x).hashCode, (h - y).hashCode, (x * y).hashCode, element.hashCode);
}
}
/// Class for returning a layer of the Layout.
/// Each [Layer] contains all the [LayoutElement]s in that Layer.
/// LayoutElements are not required to fully tile the area.
class Layer<LayoutElement> extends ListBase<LayoutElement> {
final List<LayoutElement> _innerList = <LayoutElement>[];
/// Constructor for adding a single element to a Layer
Layer({LayoutElement element}) {
if (element != null) {
_innerList.add(element);
}
}
/// Constructor for adding a list of [LayoutElement]s to a layer
Layer.fromList({List<LayoutElement> elements}) {
_innerList.addAll(elements);
}
@override
int get length => _innerList.length;
@override
set length(int length) => _innerList.length = length;
@override
void operator []=(int index, LayoutElement value) {
_innerList[index] = value;
}
@override
LayoutElement operator [](int index) => _innerList[index];
@override
void add(LayoutElement value) => _innerList.add(value);
@override
void addAll(Iterable<LayoutElement> all) => _innerList.addAll(all);
}
/// Convenience class for placing a single Surface at a coordinate and size on
/// screen
class SurfaceLayout extends LayoutElement {
/// Constructor
SurfaceLayout({x, y, w, h, String surfaceId})
: super(x: x, y: y, w: w, h: h, element: surfaceId);
/// Export to JSON
Map<String, dynamic> toJson() => {
'x': x,
'y': y,
'w': w,
'h': h,
'surfaceId': element,
};
/// Decode from JSON
SurfaceLayout.fromJson(Map<String, dynamic> json)
: super(
x: json['x'],
y: json['y'],
w: json['w'],
h: json['h'],
element: json['surfaceId']);
@override
String toString() {
return toJson().toString();
}
}
/// Convenience class for placing a Stack of [Surface] elements at a coordinate
/// and size on screen. The box dimensions of the [StackLayout] apply to each of
/// the surfaces in the [StackLayout] - they are all intended to fit the stack
/// dimensions.
class StackLayout extends LayoutElement {
/// Constructor
StackLayout(
{double x, double y, double w, double h, List<String> surfaceStack})
: super(x: x, y: y, w: w, h: h, element: surfaceStack);
/// Export to JSON
Map<String, dynamic> toJson() => {
'x': x,
'y': y,
'w': w,
'h': h,
'surfaceStack': element,
};
/// Decode from JSON
StackLayout.fromJson(Map<String, dynamic> json)
: super(
x: json['x'],
y: json['y'],
w: json['w'],
h: json['h'],
element: json['surfaceStack']);
@override
String toString() {
return toJson().toString();
}
}