123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
"use strict";
modulum('LayoutEngineBase', ['EventListener', 'LayoutInvalidationService'],
function(context, cls) {
cls.LayoutEngineBase = context.oo.Class(cls.EventListener, function($super) {
return {
__name: "LayoutEngineBase",
_widget: null,
_charMeasured: false,
_styleRules: null,
_statuses: null,
_invalidatedMeasure: context.LayoutInvalidationService.getInitialInvalidation(),
_invalidatedAllocatedSpace: context.LayoutInvalidationService.getInitialInvalidation(),
_forceParentInvalidateMeasure: false,
_needMeasure: true,
constructor: function(widget) {
$super.constructor.call(this);
this._widget = widget;
this._styleRules = {};
this._statuses = {
measured: false,
adjusted: false,
layouted: false
};
},
destroy: function() {
this._destroyStyle();
this._widget = null;
this._styleRules = null;
this._statuses = null;
$super.destroy.call(this);
},
_destroyStyle: function() {
if (this._styleSheetId) {
var stylingContext = this._widget.getStylingContext();
if (stylingContext === "widget") {
context.styler.removeStyleSheet(this._styleSheetId);
} else {
var sheetId = this._widget.getStyleSheetId();
context.styler.appendStyleSheet({}, this._styleSheetId, true, sheetId);
}
}
},
reset: function(recursive) {
this._statuses.layouted = false;
this._statuses.measured = false;
this._statuses.adjusted = false;
this._invalidatedMeasure = context.LayoutInvalidationService.getInitialInvalidation();
this._invalidatedAllocatedSpace = context.LayoutInvalidationService.getInitialInvalidation();
this._forceParentInvalidateMeasure = false;
this._needMeasure = true;
this._charMeasured = false;
this._getLayoutInfo().reset(true);
if (recursive) {
var children = this._widget && this._widget.getChildren && this._widget.getChildren(),
i = 0,
len = children && children.length || 0;
for (; i < len; i++) {
var engine = children[i].getLayoutEngine();
if (engine) {
engine.reset(recursive);
}
}
}
},
_getLayoutInfo: function(widget) {
var w = widget || this._widget;
if (!w) {
return null;
}
return w.getLayoutInformation();
},
registerChild: function(widget) {},
unregisterChild: function(widget) {},
resetSizes: function() {
var layoutInfo = this._widget.getLayoutInformation();
layoutInfo.getMinimal().reset();
layoutInfo.getMaximal().reset();
layoutInfo.getMeasured().reset();
layoutInfo.getAllocated().reset();
layoutInfo.getAvailable().reset();
},
beforeLayout: function() {},
prepareMeasure: function() {},
measureChar: function() {
if (!this._ignoreLayout && !this._charMeasured) {
var MMMlen = this._widget.__charMeasurer1.getBoundingClientRect(),
_000len = this._widget.__charMeasurer2.getBoundingClientRect();
this._getLayoutInfo().setCharSize(MMMlen.width / 10, _000len.width / 10, MMMlen.height / 10);
if (_000len.width > 0 && MMMlen.height > 0) {
this._charMeasured = true;
}
}
},
DOMMeasure: function() {
var layoutInfo = this._widget.getLayoutInformation(),
element = this._widget.getElement(),
elemRects = element.getBoundingClientRect();
layoutInfo.setRawMeasure(elemRects.width, elemRects.height);
},
measure: function() {},
measureDecoration: function() {
},
afterMeasure: function() {
this._statuses.measured = true;
},
prepareAdjustments: function() {},
adjustMeasure: function() {},
afterAdjustMeasure: function() {
this._statuses.adjusted = true;
},
adjustStretchability: function() {},
prepareApplyLayout: function(layoutApplicationService) {},
applyLayout: function() {},
notifyLayoutApplied: function() {
this.emit(context.constants.widgetEvents.layoutApplied);
},
onLayoutApplied: function(hook) {
return this.when(context.constants.widgetEvents.layoutApplied, hook);
},
needMeasure: function() {
return this._needMeasure;
},
ignoreMeasureInvalidation: function() {
return false;
},
forceMeasurement: function() {
this._needMeasure = true;
},
invalidateMeasure: function(invalidation) {
if (this._widget && this._widget.getElement() && !this._widget.getElement().isInDOM()) {
this._invalidatedMeasure = context.LayoutInvalidationService.getInitialInvalidation();
}
this._invalidatedMeasure = this._prepareInvalidation(invalidation, this._invalidatedMeasure);
if (this._widget && (this._forceParentInvalidateMeasure || !this._widget.isHidden())) {
var parentWidget = this._widget && this._widget.getParentWidget(),
parentEngine = parentWidget && parentWidget.getLayoutEngine();
if (parentEngine) {
parentEngine.invalidateMeasure(this._invalidatedMeasure, this);
}
this._forceParentInvalidateMeasure = false;
}
},
invalidateAllocatedSpace: function(invalidation) {
this._invalidatedAllocatedSpace = this._prepareInvalidation(invalidation, this._invalidatedAllocatedSpace);
if (this._widget && !this._widget.isHidden()) {
var children = this.getRenderableChildren(),
len = children.length;
for (var i = 0; i < len; i++) {
if (children[i]) {
var layoutEngine = children[i].getLayoutEngine();
if (layoutEngine) {
layoutEngine.invalidateAllocatedSpace(this._invalidatedAllocatedSpace);
}
}
}
}
},
_prepareInvalidation: function(invalidation, current) {
if (current !== context.LayoutInvalidationService.getInitialInvalidation() && (!invalidation || current < invalidation)) {
return invalidation || context.LayoutInvalidationService.nextInvalidation();
}
return current;
},
needMeasureSwitching: function() {
return true;
},
isInvalidatedMeasure: function(timestamp) {
return this.needMeasure() && Boolean(this._widget) &&
!this._widget.isHidden() && (this._invalidatedMeasure >= timestamp);
},
isInvalidatedAllocatedSpace: function(timestamp) {
return Boolean(this._widget) && !this._widget.isHidden() &&
(this._invalidatedAllocatedSpace >= timestamp);
},
isInvalidated: function(timestamp) {
var result = this.isInvalidatedMeasure(timestamp) || this.isInvalidatedAllocatedSpace(timestamp),
windowWidget = this._widget && this._widget.getWindowWidget();
return result && (!windowWidget || !windowWidget._disabled || windowWidget._forceVisible);
},
isXStretched: function() {
var info = this._getLayoutInfo();
return info && info.isXStretched() || info.isChildrenXStretched();
},
isYStretched: function() {
var info = this._getLayoutInfo();
return info && info.isYStretched() || info.isChildrenYStretched();
},
getRenderableChildren: function() {
return this._widget && this._widget.getChildren && this._widget.getChildren() || [];
},
updateInvalidated: function(invalidation) {
if (this._widget && this._widget.isLayoutMeasureable(true)) {
this._invalidatedMeasure = this._getUpdatedInvalidation(invalidation, this._invalidatedMeasure);
this._invalidatedAllocatedSpace = this._getUpdatedInvalidation(invalidation, this._invalidatedAllocatedSpace);
if (this._getLayoutInfo().getSizePolicyConfig().isInitial()) {
this._needMeasure = false;
}
this._statuses.layouted = true;
}
},
_getUpdatedInvalidation: function(invalidation, current) {
return Math.max(invalidation, current === context.LayoutInvalidationService.getInitialInvalidation() ? 1 : current);
},
changeHidden: function() {
this._forceParentInvalidateMeasure = true;
if (this._widget && this._widget.getParentWidget() && this._widget.getParentWidget().getLayoutEngine()) {
this._widget.getParentWidget().getLayoutEngine().invalidateMeasure();
this._widget.getParentWidget().getLayoutEngine().invalidateAllocatedSpace();
}
this.invalidateMeasure();
},
getLayoutSheetId: function() {
return this._widget && this._widget.getStyleSheetId() || "_";
}
};
});
});