UNPKG

ares-ide

Version:

A browser-based code editor and UI designer for Enyo 2 projects

365 lines (339 loc) 11.1 kB
/* global ares */ enyo.kind({ name: "CategoryItem", components: [ {classes: "palette-category", components: [ {ontap: "toggleDrawer", classes: "palette-category-name", components: [ {name: "indicator", classes: "indicator turned"}, {name: "name", tag: "span"} ]}, {kind: "onyx.Drawer", name: "drawer", open: true, components: [ {name: "list", kind: "Repeater", count: 0, onSetupItem: "setupItem", components: [ {kind: "PaletteItem"} ]} ]} ]} ], events: { onToggledDrawer: "" }, toggleDrawer: function(inSender, inEvent) { if (this.$.list.count !== 0) { var open = this.$.drawer.getOpen(); this.$.drawer.setOpen(!open); this.$.indicator.addRemoveClass("turned", !open); this.doToggledDrawer(); } return true; }, setModel: function(inModel) { this.model = inModel; this.$.name.setContent(this.model.name); this.$.list.count = this.model.items.length; if (this.$.list.count === 0 && this.$.drawer.getOpen()) { this.closeDrawer(); } this.$.list.build(); if (this.$.name.content === "ignore") { this.hide(); } }, setupItem: function(inSender, inEvent) { inEvent.item.$.paletteItem.setModel(this.model.items[inEvent.index]); // <---- TODO - sibling reference, should be fixed up return true; }, /** @public */ openDrawer: function() { this.$.drawer.setOpen(true); this.$.indicator.addRemoveClass("turned", true); }, /** @public */ closeDrawer: function() { this.$.drawer.setOpen(false); this.$.indicator.addRemoveClass("turned", false); }, /** @public */ drawerStatus: function() { return this.$.drawer.getOpen(); } }); enyo.kind({ name: "PaletteItem", components: [ {kind: "Control", classes: "palette-item", attributes: {draggable: true}, components: [ {name: "icon", kind: "Image", showing: false}, {name: "name"}, {classes: "row-fluid", name: "client"} ]} ], handlers: { ondragstart: "decorateDragEvent" }, //* On dragstart, add _this.config_ data to drag event decorateDragEvent: function(inSender, inEvent) { if (!inEvent.dataTransfer) { return true; } inEvent.config = this.config; inEvent.options = this.options; }, setModel: function(inModel) { if (inModel) { for (var n in inModel) { var c = this.$[n]; if (c) { var v = inModel[n]; if (c.kind == "Image") { c.setSrc("$deimos/images/" + v); c.setShowing(true); } else { c.setContent(v); } } } this.attributes.title = inModel.description; this.config = inModel.config; this.options = inModel.options; } } }); enyo.kind({ name: "Palette", style: "position: relative", published: { projectIndexer: "" }, debug: false, components: [ {kind: "FittableRows", classes: "enyo-fit", components: [ {kind: "onyx.MoreToolbar", classes: "deimos-toolbar deimos-toolbar-margined-buttons", components: [ {kind: "onyx.Button", name: "expandAllCategoriesButton", content: "Expand all", ontap: "expandAllCategories"}, {kind: "onyx.Button", name: "collapseAllCategoriesButton", content: "Collapse all", ontap: "collapseAllCategories"} ]}, {kind: "Scroller", fit: true, components: [ {name: "list", kind: "Repeater", count: 0, onSetupItem: "setupItem", components: [ {kind: "CategoryItem"} ]} ]}, {kind: "onyx.InputDecorator", style: "width:100%; margin-top:10px;", layoutKind: "FittableColumnsLayout", components: [ {kind: "onyx.Input", name: "filterPalette", fit:true, placeholder: "filter", oninput: "paletteFiltering"}, {kind: "onyx.Icon", name: "filterPaletteIcon", src: "$deimos/images/search-input-search.png", style: "height:20px;", ontap: "resetFilter"} ]} ]} ], handlers: { ondragstart: "dragstart", onToggledDrawer: "toggledDrawer" }, create: function () { ares.setupTraceLogger(this); this.inherited(arguments); this.$.expandAllCategoriesButton.setDisabled(true); }, setupItem: function(inSender, inEvent) { var index = inEvent.index; var item = inEvent.item; item.$.categoryItem.setModel(this.palette[index]); return true; }, dragstart: function(inSender, inEvent) { if (!inEvent.dataTransfer) { return true; } var dragData = { type: "ares/createitem", item: { config: inEvent.config, options: inEvent.options } }; inEvent.dataTransfer.setData("text", enyo.json.codify.to(dragData)); }, /** * The current project analyzer output has changed * Re-build the palette * @param value the new analyzer output * @protected */ projectIndexerChanged: function() { this.trace("projectIndexerChanged: rebuilt the palette "); var catchAllPalette = this.buildCatchAllPalette(); var allPalette = ares.clone(catchAllPalette.concat(this.projectIndexer.design.palette || [])); var filterString = this.$.filterPalette.getValue().toLowerCase(); if (filterString !== "") { var k; enyo.forEach(allPalette, function(category) { for (k = 0; k < category.items.length; k++) { if (category.items[k].name.toLowerCase().indexOf(filterString) === -1) { category.items.splice(k, 1); k--; } } }, this); } var i = 0; enyo.forEach(allPalette, function(category) { if (category.items.length === 0) { i--; } else { i++; } }, this); if (i === this.$.list.count) { this.$.expandAllCategoriesButton.setDisabled(true); this.$.collapseAllCategoriesButton.setDisabled(false); } else if (i === -(this.$.list.count)) { this.$.expandAllCategoriesButton.setDisabled(true); this.$.collapseAllCategoriesButton.setDisabled(true); } this.palette = allPalette; this.palette.sort(function(a,b) { return (a.name || "").localeCompare(b.name || "") + (a.order || 0) - (b.order || 0); }); // count reset must be forced this.$.list.set("count", 0); this.$.list.set("count", this.palette.length); }, /** * Builds "catch-all palette" entries. The standard palette comes from the projectIndexer's * palette, which is built from palette categories and items specified in .design files included * in package.js files included in the app's libs. This function builds palette entries * for any kinds that do not have palette enteries specified by .design files, allowing any * kind to be usable in the designer. We create a palette category for each kind namespace * that contains a kind not assigned to a palette, and a catch-all category for non-namespaced kinds. * @returns Array containing catch-all palette categories * @protected */ buildCatchAllPalette: function() { // Start custom palette with catch-all category for non-namespaced kinds var catchAllCategories = { "" : { order: 11000, name: "Custom Kinds", items: [] } }; // Get all kinds from .design files if .design exist var catchKindListInPalette = []; if (this.projectIndexer.design.hasOwnProperty("palette")) { var keys = Object.keys(this.projectIndexer.design.palette); enyo.forEach(keys, function(o) { if (this.projectIndexer.design.palette[o]) { var keys = Object.keys(this.projectIndexer.design.palette[o].items); enyo.forEach(keys, function(item) { var kindName = this.projectIndexer.design.palette[o].items[item].config.kind || ""; catchKindListInPalette.push(kindName); }, this); } }, this); } // Get list of all public Components from indexer without palette meta-data, sorted by name var catchAllKinds = enyo.filter(this.projectIndexer.objects, function(o) { return (o.type == "kind") && (enyo.indexOf("enyo.Component", o.superkinds) >= 0) && (o.group == "public") && (catchKindListInPalette.indexOf(o.name) == -1); }).sort(function(a,b) { return a.name.localeCompare(b.name); }); // Add components to catch-all categories per namespace enyo.forEach(catchAllKinds, function(kind) { // Create palette item for kind var item = { name: kind.name, description: kind.comment, config: {kind: kind.name} }; // Check for package namespace var dot = kind.name.lastIndexOf("."); if (dot > 0) { var pkg = kind.name.substring(0, dot); var cat = catchAllCategories[pkg]; if (!cat) { // Generate a new custom palette for this package if it doesn't exist cat = { order: 10000, name: pkg + " (other)", items: [] }; catchAllCategories[pkg] = cat; } // avoid HTML description coming from the API viewer item.description = ""; cat.items.push(item); } else { // No package, so add to catch-all category catchAllCategories[""].items.push(item); } }); // Create the final custom palette array var catchAllPalette = []; for (var p in catchAllCategories) { if (catchAllCategories.hasOwnProperty(p)) { catchAllPalette.push(catchAllCategories[p]); } } return catchAllPalette; }, /** @private */ paletteFiltering: function(inSender, inEvent) { this.trace(inSender, "=>", inEvent); if (this.$.filterPalette.getValue() === "") { this.$.filterPaletteIcon.set("src", "$deimos/images/search-input-search.png"); } else { this.$.filterPaletteIcon.set("src", "$deimos/images/search-input-cancel.png"); } this.$.expandAllCategoriesButton.setDisabled(true); this.$.collapseAllCategoriesButton.setDisabled(false); this.projectIndexerChanged(); return true; }, /** @private */ resetFilter: function(inSender, inEvent) { this.trace(inSender, "=>", inEvent); if (this.$.filterPalette.getValue() !== "") { this.$.filterPalette.setValue(""); this.paletteFiltering(); } return true; }, /** @private */ expandAllCategories: function(inSender, inEvent) { this.trace(inSender, "=>", inEvent); this.paletteFiltering(inSender, inEvent); this.$.expandAllCategoriesButton.setDisabled(true); this.$.collapseAllCategoriesButton.setDisabled(false); return true; }, /** @private */ collapseAllCategories: function(inSender, inEvent) { this.trace(inSender, "=>", inEvent); this.$.collapseAllCategoriesButton.setDisabled(true); this.$.expandAllCategoriesButton.setDisabled(false); for (var i = 0; i < this.$.list.count; i ++) { this.$.list.getControls()[i].$.categoryItem.closeDrawer(); } return true; }, /** @private */ toggledDrawer: function(inSender, inEvent) { this.trace(inSender, "=>", inEvent); var openedCategories = 0, closedCategories = 0; for (var i = 0; i < this.$.list.count; i ++) { if (this.$.list.getControls()[i].$.categoryItem.drawerStatus()) { openedCategories++; } else { closedCategories--; } } if (openedCategories === this.$.list.count) { this.$.expandAllCategoriesButton.setDisabled(true); this.$.collapseAllCategoriesButton.setDisabled(false); } else if (closedCategories === -(this.$.list.count)) { this.$.expandAllCategoriesButton.setDisabled(false); this.$.collapseAllCategoriesButton.setDisabled(true); } else { this.$.expandAllCategoriesButton.setDisabled(false); this.$.collapseAllCategoriesButton.setDisabled(false); } } });