PElement abstract class
abstract class PElement extends AttachableObject { final List<AffineTransform> _transforms = new List<AffineTransform>(); final bool cacheEnabled; final EventHandle<EventArgs> _invalidatedEventHandle = new EventHandle<EventArgs>(); CanvasElement _cacheCanvas; num _width, _height, _alpha; Size _lastDrawSize; bool clip = false; ElementParent _parent; PElement(this._width, this._height, [this.cacheEnabled = false]); num get width => _width; void set width(num value) { assert(isValidNumber(value)); _width = value; invalidateDraw(); } num get height => _height; void set height(num value) { assert(isValidNumber(value)); _height = value; invalidateDraw(); } Size get size => new Size(_width, _height); void set size(Size value) { assert(value.isValid); _width = value.width; _height = value.height; invalidateDraw(); } ElementParent get parent => _parent; EventRoot<EventArgs> get invalidated => _invalidatedEventHandle; AffineTransform getTransform() { var tx = new AffineTransform(); _transforms.forEach(tx.concatenate); return tx; } AffineTransform getTransformToRoot(){ var tx = new AffineTransform(); if(_parent != null){ tx.concatenate(_parent.getTransformToRoot()); } tx.concatenate(getTransform()); return tx; } void update(){ } void drawCore(CanvasRenderingContext2D ctx){ if(cacheEnabled) { _drawCached(ctx); } else { _drawNormal(ctx); } } AffineTransform addTransform(){ validateNotDisposed(); var tx = new AffineTransform(); _transforms.add(tx); return tx; } abstract void drawOverride(CanvasRenderingContext2D ctx); void invalidateDraw(){ validateNotDisposed(); if(_lastDrawSize != null){ _lastDrawSize = null; _invalidateParent(); } } void registerParent(ElementParent parent) { assert(_parent == null); assert(parent != null); _parent = parent; } void disposeInternal(){ super.disposeInternal(); _invalidatedEventHandle.dispose(); } // // Privates // bool _stageDraw(CanvasRenderingContext2D ctx){ update(); var dirty = (_lastDrawSize == null); drawCore(ctx); return dirty; } void _drawCached(CanvasRenderingContext2D ctx) { if (this._cacheCanvas == null) { this._cacheCanvas = new CanvasElement(); } final intLastDrawSize = (_lastDrawSize == null) ? null : new Size(_lastDrawSize.width.toInt(), _lastDrawSize.height.toInt()); if (CanvasUtil.getCanvasSize(this._cacheCanvas) != intLastDrawSize) { // DARTBUG: 5172 - width and height don't work on CanvasElement this._cacheCanvas.attributes["width"] = this.width; this._cacheCanvas.attributes["height"] = this.height; var cacheCtx = _cacheCanvas.context2d; _drawInternal(cacheCtx); } ctx.save(); var tx = this.getTransform(); CanvasUtil.transform(ctx, tx); ctx.drawImage(this._cacheCanvas, 0, 0); ctx.restore(); } void _drawNormal(CanvasRenderingContext2D ctx){ var tx = this.getTransform(); if (this._isClipped(tx, ctx)) { return; } ctx.save(); // Translate to the starting position CanvasUtil.transform(ctx, tx); // clip to the bounds of the object if (this.clip) { ctx.beginPath(); ctx.rect(0, 0, width, height); ctx.clip(); } _drawInternal(ctx); ctx.restore(); } void _drawInternal(CanvasRenderingContext2D ctx){ if (_alpha != null) { ctx.globalAlpha = _alpha; } // call the abstract draw method drawOverride(ctx); _lastDrawSize = this.size; } bool _isClipped(AffineTransform tx, CanvasRenderingContext2D ctx){ if(clip){ // a lot more impl to do here... } return false; } void _invalidateParent(){ assert(this._parent != null); _invalidatedEventHandle.fireEvent(EventArgs.empty); _parent.childInvalidated(this); } }
Extends
DisposableImpl > AttachableObject > PElement
Subclasses
ImgElement, ParentElement, Shape, TextureAnimationElement
Constructors
new PElement(num _width, num _height, [bool cacheEnabled = false]) #
PElement(this._width, this._height, [this.cacheEnabled = false]);
Properties
final bool cacheEnabled #
final bool cacheEnabled;
bool clip #
bool clip = false;
num height #
num get height => _height;
void set height(num value) { assert(isValidNumber(value)); _height = value; invalidateDraw(); }
final EventRoot<EventArgs> invalidated #
EventRoot<EventArgs> get invalidated => _invalidatedEventHandle;
final ElementParent parent #
ElementParent get parent => _parent;
final Type runtimeType #
A representation of the runtime type of the object.
external Type get runtimeType;
Size size #
Size get size => new Size(_width, _height);
void set size(Size value) { assert(value.isValid); _width = value.width; _height = value.height; invalidateDraw(); }
num width #
num get width => _width;
void set width(num value) { assert(isValidNumber(value)); _width = value; invalidateDraw(); }
Operators
bool operator ==(other) #
The equality operator.
The default behavior for all Object
s is to return true if and
only if this
and
other are the same object.
If a subclass overrides the equality operator it should override
the hashCode
method as well to maintain consistency.
bool operator ==(other) => identical(this, other);
Methods
AffineTransform addTransform() #
AffineTransform addTransform(){ validateNotDisposed(); var tx = new AffineTransform(); _transforms.add(tx); return tx; }
void dispose() #
void dispose(){ if (!_disposed) { // Set disposed_ to true first, in case during the chain of disposal this // gets disposed recursively. this._disposed = true; this.disposeInternal(); } }
void disposeInternal() #
Do not call this method directly. Call dispose
instead.
Subclasses should override this method to implement Disposable
behavior.
void disposeInternal(){ super.disposeInternal(); _invalidatedEventHandle.dispose(); }
void drawCore(CanvasRenderingContext2D ctx) #
void drawCore(CanvasRenderingContext2D ctx){ if(cacheEnabled) { _drawCached(ctx); } else { _drawNormal(ctx); } }
abstract void drawOverride(CanvasRenderingContext2D ctx) #
AffineTransform getTransform() #
AffineTransform getTransform() { var tx = new AffineTransform(); _transforms.forEach(tx.concatenate); return tx; }
AffineTransform getTransformToRoot() #
AffineTransform getTransformToRoot(){ var tx = new AffineTransform(); if(_parent != null){ tx.concatenate(_parent.getTransformToRoot()); } tx.concatenate(getTransform()); return tx; }
int hashCode() #
Get a hash code for this object.
All objects have hash codes. Hash codes are guaranteed to be the
same for objects that are equal when compared using the equality
operator ==
. Other than that there are no guarantees about
the hash codes. They will not be consistent between runs and
there are no distribution guarantees.
If a subclass overrides hashCode
it should override the
equality operator as well to maintain consistency.
external int hashCode();
void invalidateDraw() #
void invalidateDraw(){ validateNotDisposed(); if(_lastDrawSize != null){ _lastDrawSize = null; _invalidateParent(); } }
noSuchMethod(String name, List args) #
noSuchMethod
is invoked when users invoke a non-existant method
on an object. The name of the method and the arguments of the
invocation are passed to noSuchMethod
. If noSuchMethod
returns a value, that value becomes the result of the original
invocation.
The default behavior of noSuchMethod
is to throw a
noSuchMethodError
.
external Dynamic noSuchMethod(String name, List args);
const Object() #
Creates a new Object
instance.
Object
instances have no meaningful state, and are only useful
through their identity. An Object
instance is equal to itself
only.
const Object();
new PElement(num _width, num _height, [bool cacheEnabled = false]) #
PElement(this._width, this._height, [this.cacheEnabled = false]);
void registerParent(ElementParent parent) #
void registerParent(ElementParent parent) { assert(_parent == null); assert(parent != null); _parent = parent; }
String toString() #
Returns a string representation of this object.
external String toString();
void update() #
void update(){ }
void validateNotDisposed() #
void validateNotDisposed() { assert(!_disposed); }