diff --git a/src/css/builder.css b/src/css/builder.css index fc3e8a96..43fbd122 100644 --- a/src/css/builder.css +++ b/src/css/builder.css @@ -866,6 +866,17 @@ body.ui-tabs.ui-widget { overflow-x: hidden; overflow-y: auto; } +.propertyView .datalist .upload-button { + text-align: center; + border: 1px solid #a1a1a1; + line-height: 12px; + background-color: #fbfbfb; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + margin-top: 2px; + margin-bottom: 2px; +} .propertyView .datalist li { clear:both; cursor: pointer; diff --git a/src/js/adm.js b/src/js/adm.js index aeecbe9f..32c7c120 100644 --- a/src/js/adm.js +++ b/src/js/adm.js @@ -253,6 +253,24 @@ ADM.addEventType("activePageChanged"); */ ADM.addEventType("selectionChanged"); +/** + * Event sent by the ADM object when the usage status of images change. + * When the active page changes, the selected widget is set to null + * automatically. + * + * @name ADM#imagesUpdated + * @event + * @param {Object} event Object including standard "id" and "name" + * properties, as well as a + * "usageStatus" is an object contains + * current usage status of + * all existing images + * @param {Any} data The data you supplied to the bind() call. + * @see ADMEventSource.bind + * @see ADMEventSource.unbind + */ +ADM.addEventType("imagesUpdated"); + /** * Gets the singleton design root. * diff --git a/src/js/projects.js b/src/js/projects.js index fbb8a852..8aaa32ac 100644 --- a/src/js/projects.js +++ b/src/js/projects.js @@ -433,6 +433,8 @@ $(function () { pmUtils._projectsInfo[newPid] = {}; pmUtils.setProperties(newPid, properties); pmUtils.setProperty(newPid, "accessDate", new Date()); + // init resource usage status + $.rib.pmUtils.resourceRef = {}; if (design && (design instanceof ADMNode)) { ADM.setDesignRoot(design); @@ -534,7 +536,7 @@ $(function () { * @return {None}. */ pmUtils.openProject = function (pid, success, error) { - var designPath, successHandler; + var designPath, successHandler, imagePath; if (!pmUtils._projectsInfo[pid]) { console.error("Error: Invalid pid for project when opening project"); @@ -546,6 +548,7 @@ $(function () { return; } designPath = pmUtils.getDesignPath(pid); + imagePath = pmUtils.getProjectDir(pid) + 'images/'; successHandler = function (result) { var design, project; @@ -556,6 +559,15 @@ $(function () { pmUtils._activeProject = pid; // update access time pmUtils.setProperty(pid, "accessDate", new Date()); + // init pmUtils.resourceRef, reset usage status of resources + $.rib.pmUtils.resourceRef = {}; + $.rib.fsUtils.ls(imagePath, function (entries) { + $.each(entries, function (i, e) { + $.rib.pmUtils.resourceRef['images/'+e.name] = 0; + }); + }, function (e) { + dumplog('There is no image in this project.'); + }); // set the new design as design root ADM.setDesignRoot(design); success && success(); @@ -961,6 +973,7 @@ $(function () { } else { pmUtils.resourceRef[refPath]++; } + ADM.fireEvent('imagesUpdated', {usageStatus: pmUtils.resourceRef}); return; }; @@ -983,8 +996,10 @@ $(function () { $.rib.confirm('Unused resource: "' + entry.name + '". \nWould you like to delete it from the project?', function () { $.rib.fsUtils.rm(entry.fullPath); + ADM.fireEvent('imagesUpdated', {usageStatus: pmUtils.resourceRef}); }, function () { pmUtils.resourceRef[refPath] = 0; + ADM.fireEvent('imagesUpdated', {usageStatus: pmUtils.resourceRef}); }); }); } @@ -1013,12 +1028,6 @@ $(function () { if (!(node instanceof ADMNode)) { return false; } - // if the design is Design root - if (node.getType() === "Design") { - // reset pmUtils.resourceRef - pmUtils.resourceRef = {}; - upFlag = true; - } // Find all used sandbox resource nodes and the matched properties matched = node.findNodesByProperty($.rib.pmUtils.relativeFilter); for (i = 0; i < matched.length; i++) { diff --git a/src/js/views/base.js b/src/js/views/base.js index ef493c62..1afe3515 100644 --- a/src/js/views/base.js +++ b/src/js/views/base.js @@ -27,6 +27,7 @@ o.selectionChanged = this._selectionChangedHandler; o.activePageChanged = this._activePageChangedHandler; o.modelUpdated = this._modelUpdatedHandler; + o.imagesUpdated = this._imagesUpdatedHandler; // FIXME: This should work, but $.extend of options seems to be // creating a copy of the ADM, which will not containt the @@ -94,6 +95,9 @@ if (o.activePageChanged) { a.bind("activePageChanged", o.activePageChanged, this); } + if (o.imagesUpdated) { + a.bind("imagesUpdated", o.imagesUpdated, this); + } // Since model changed, need to call our designReset hander // to sync up the ADMDesign modelUpdated event handler diff --git a/src/js/views/property.js b/src/js/views/property.js index 5e7baf96..afcfb63a 100644 --- a/src/js/views/property.js +++ b/src/js/views/property.js @@ -89,6 +89,16 @@ widget.refresh(event,widget); } }, + _imagesUpdatedHandler: function(event, widget) { + widget = widget || this; + var optionsList, options; + if (widget.options.imagesDatalist) { + options = event.usageStatus || $.rib.pmUtils.resourceRef; + optionsList = widget.options.imagesDatalist.find('ul'); + updateOptions(optionsList, Object.keys(options)); + } + return; + }, _showProperties: function(node) { var labelId, labelVal, valueId, valueVal, count, @@ -113,6 +123,8 @@ .addClass('title') .text(BWidget.getDisplayLabel(type)+' Properties'); content.empty(); + // git rib of old datalist element + this.options.imagesDatalist = null; propertyItems = $('
').addClass("propertyItems") .appendTo(content); props = node.getProperties(); @@ -165,27 +177,39 @@ } break; case "url-uploadable": - $('') + var array, datalist, uploadClick; + uploadClick = function (e) { + var optionsWrapper, textInput, saveDir; + optionsWrapper = $(this).parents('.datalist:first'); + optionsWrapper.hide(); + textInput = optionsWrapper.prev('input'); + + saveDir = $.rib.pmUtils.ProjectDir + "/" + $.rib.pmUtils.getActive() + "/images/"; + $.rib.fsUtils.upload("image", $(this).parent(), function(file) { + // Write uploaded file to sandbox + $.rib.fsUtils.write(saveDir + file.name, file, function (newFile) { + textInput.val("images/" + newFile.name).change(); + }); + }); + }; + // merge all image files + array = [{ + value: "upload", + clickCallback: uploadClick, + cssClass: 'upload-button', + stable: true + }].concat(Object.keys($.rib.pmUtils.resourceRef)); + datalist = createDatalist(array); + if (!datalist) break; + datalist.addClass('title').appendTo(value); + datalist.find('input[type="text"]') .attr('id', valueId) .addClass('title labelInput') - .appendTo(value); - //set default value - value.find('#' + valueId).val(valueVal); - $('') - .addClass('buttonStyle') - .click(function (e) { - var target, saveDir; - target = $(this).prev("input:text"); - saveDir = $.rib.pmUtils.ProjectDir + "/" + $.rib.pmUtils.getActive() + "/images/"; - $.rib.fsUtils.upload("image", $(this).parent(), function(file) { - // Write uploaded file to sandbox - $.rib.fsUtils.write(saveDir + file.name, file, function (newFile) { - target.val("images/" + newFile.name); - target.trigger('change'); - }); - }); - }).appendTo(value); + .val(valueVal); + // save the datalist for update + this.options.imagesDatalist = $(this.options.imagesDatalist).add(datalist); break; + case "record-array": $('