UNPKG

ovuse

Version:

WPF-inspired Web UI framework

181 lines (180 loc) 7.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const _1 = require("."); const __1 = require(".."); class ItemsControl extends _1.FrameworkElement { constructor() { super(...arguments); //list of items created //note that in general this list is not 1:1 with itemssource collection //for example the case when some sort of virtualization of items is applied this._elements = null; this._divElement = null; //Templates collection this._templates = new __1.ObservableCollection(); } static initProperties() { _1.FrameworkElement.overflowYProperty.overrideDefaultValue(ItemsControl, "auto"); } attachVisualOverride(elementContainer) { this._visual = this._divElement = document.createElement("div"); let itemsPanel = this.itemsPanel; if (itemsPanel == null) this.itemsPanel = itemsPanel = new _1.Stack(); itemsPanel.attachVisual(this._visual); super.attachVisualOverride(elementContainer); } measureOverride(constraint) { if (this.itemsPanel != null) { this.itemsPanel.measure(constraint); if (this.itemsPanel.desiredSize != null) return this.itemsPanel.desiredSize; } return new _1.Size(); } arrangeOverride(finalSize) { if (this.itemsPanel != null) this.itemsPanel.arrange(finalSize.toRect()); return finalSize; } layoutOverride() { super.layoutOverride(); if (this.itemsPanel != null) this.itemsPanel.layout(); } get templates() { return this._templates; } set templates(value) { if (value == this._templates) return; if (this._templates != null) { //remove handler so that resource can be disposed this._templates.offChangeNotify(this); } this._templates = value; if (this._templates != null) { this._templates.forEach(el => { //to do: re-apply templates to children }); this._templates.onChangeNotify(this); } } onCollectionChanged(collection, added, removed, startRemoveIndex) { if (collection == this._templates) { //templates collection is changed this.setupItems(); } else if (collection == this.itemsSource) { //some items were added/removed from itemssouurce if (this.itemsPanel == null) return; added.forEach(item => { if (item == null) throw new Error("Unable to render null items"); var templateForItem = _1.DataTemplate.getTemplateForItem(this._templates.toArray(), item); if (templateForItem == null) { throw new Error("Unable to find a valid template for item"); } var newElement = templateForItem.createElement(); if (newElement != null) { newElement.setValue(_1.FrameworkElement.dataContextProperty, item); this.itemsPanel.children.add(newElement); } }); removed.forEach(item => { this.itemsPanel.children.remove(this.itemsPanel.children.at(startRemoveIndex++)); }); } this.invalidateMeasure(); } get itemsSource() { return this.getValue(ItemsControl.itemsSourceProperty); } set itemsSource(value) { this.setValue(ItemsControl.itemsSourceProperty, value); } get itemsPanel() { return this.getValue(ItemsControl.itemsPanelProperty); } set itemsPanel(value) { this.setValue(ItemsControl.itemsPanelProperty, value); } onDependencyPropertyChanged(property, value, oldValue) { if (property == ItemsControl.itemsSourceProperty) { if (oldValue != null && oldValue["offChangeNotify"] != null) { var oldItmesSource = oldValue; oldItmesSource.offChangeNotify(this); } this.setupItems(); if (value != null && value["onChangeNotify"] != null) { var newItemsSource = value; newItemsSource.onChangeNotify(this); } } else if (property == ItemsControl.itemsPanelProperty) { var oldPanel = oldValue; if (oldPanel != null && oldPanel.parent == this) { oldPanel.children.clear(); oldPanel.parent = null; oldPanel.attachVisual(null); } var newPanel = value; if (newPanel != null) { newPanel.parent = this; if (this._visual != null) newPanel.attachVisual(this._visual); } } else if (property == ItemsControl.itemsPanelProperty) this.setupItems(); super.onDependencyPropertyChanged(property, value, oldValue); } setupItems() { if (this._elements != null) { this.itemsPanel.children.clear(); this._elements = null; } if (this._templates == null || this._templates.count == 0) return; var itemsSource = this.itemsSource; if (itemsSource != null) { var elements = null; if (Object.prototype.toString.call(itemsSource) == '[object Array]') elements = itemsSource; else elements = itemsSource["elements"]; if (elements == null) throw new Error("Unable to get list of elements from itemsSource"); elements = elements.map(item => { var templateForItem = _1.DataTemplate.getTemplateForItem(this._templates.toArray(), item); if (templateForItem == null) { throw new Error("Unable to find a valid template for item"); } var newElement = templateForItem.createElement(); if (newElement != null) newElement.setValue(_1.FrameworkElement.dataContextProperty, item); return newElement; }); this._elements = elements.filter(item => item != null); } if (this._elements != null) { if (this.itemsPanel == null) { this.itemsPanel = new _1.Stack(); this.itemsPanel.parent = this; if (this._visual != null) this.itemsPanel.attachVisual(this._visual); } this.itemsPanel.children = new __1.ObservableCollection(this._elements); } this.invalidateMeasure(); } } ItemsControl._init = ItemsControl.initProperties(); //itemsSource property ItemsControl.itemsSourceProperty = __1.DependencyObject.registerProperty(ItemsControl, "ItemsSource", null, _1.FrameworkPropertyMetadataOptions.AffectsMeasure | _1.FrameworkPropertyMetadataOptions.AffectsRender); //itemsPanel property ItemsControl.itemsPanelProperty = __1.DependencyObject.registerProperty(ItemsControl, "ItemsPanel", null, _1.FrameworkPropertyMetadataOptions.AffectsMeasure | _1.FrameworkPropertyMetadataOptions.AffectsRender); exports.ItemsControl = ItemsControl;