Blockly Factory: Select Used Blocks for Export (#565)

* addAllUsedBlocks in exporter works when you hand set the instance variable.

added click handler for export button (which got lost in refactor).

saveStateFromWorkspace on tab switch

fixed bug in deselect block in exporter; added warning alert for add all used blocks

* nit line

* not warning for standard block types
This commit is contained in:
Tina Quach
2016-08-22 18:07:52 -07:00
committed by picklesrus
parent 66eff965c9
commit 7516866804
7 changed files with 103 additions and 10 deletions

View File

@@ -294,6 +294,14 @@ AppController.prototype.onTab = function() {
// Update toolbox to reflect current block library.
this.exporter.updateToolbox();
// Need accurate state in order to know which blocks are used in workspace
// factory.
this.workspaceFactoryController.saveStateFromWorkspace();
// Update exporter's list of the types of blocks used in workspace factory.
var usedBlockTypes = this.workspaceFactoryController.getAllUsedBlockTypes();
this.exporter.setUsedBlockTypes(usedBlockTypes);
// Show container of exporter.
FactoryUtils.show('blockLibraryExporter');
FactoryUtils.hide('workspaceFactoryContent');
@@ -336,7 +344,7 @@ AppController.prototype.styleTabs_ = function() {
*/
AppController.prototype.assignExporterClickHandlers = function() {
var self = this;
// Export blocks when the user submits the export settings.
document.getElementById('button_setBlocks').addEventListener('click',
function() {
document.getElementById('dropdownDiv_setBlocks').classList.toggle("show");
@@ -344,7 +352,7 @@ AppController.prototype.assignExporterClickHandlers = function() {
document.getElementById('dropdown_addAllUsed').addEventListener('click',
function() {
self.exporter.export();
self.exporter.addUsedBlocksToWorkspace();
document.getElementById('dropdownDiv_setBlocks').classList.remove("show");
});
@@ -359,6 +367,12 @@ AppController.prototype.assignExporterClickHandlers = function() {
self.exporter.addAllBlocksToWorkspace();
document.getElementById('dropdownDiv_setBlocks').classList.remove("show");
});
// Export blocks when the user submits the export settings.
document.getElementById('exporterSubmitButton').addEventListener('click',
function() {
self.exporter.export();
});
};
/**

View File

@@ -51,6 +51,8 @@ BlockExporterController = function(blockLibStorage) {
this.view = new BlockExporterView(
//Xml representation of the toolbox
this.tools.generateToolboxFromLibrary(this.blockLibStorage));
// Array to hold the block types used in workspace factory.
this.usedBlockTypes = [];
};
/**
@@ -283,7 +285,7 @@ BlockExporterController.prototype.onDeselectBlockForExport_ = function(event) {
var deletedBlockXml = event.oldXml;
var blockType = deletedBlockXml.getAttribute('type');
// Do not try to enable any blocks deleted from the block library.
if (this.blockLibStorage[blockType]) {
if (this.blockLibStorage.has(blockType)) {
// Enable the deselected block.
this.setBlockEnabled(blockType, true);
}
@@ -332,3 +334,60 @@ BlockExporterController.prototype.addAllBlocksToWorkspace = function() {
BlockExporterController.prototype.getBlockLibCategory = function() {
return this.tools.generateCategoryFromBlockLib(this.blockLibStorage);
};
/**
* Tied to the 'Add All Stored Blocks' button in the Block Exporter.
* Adds all blocks stored in block library to the selector workspace.
*/
BlockExporterController.prototype.addUsedBlocksToWorkspace = function() {
// Clear selector workspace.
this.view.clearSelectorWorkspace();
// Get list of block types that are in block library and used in workspace
// factory.
var storedBlockTypes = this.blockLibStorage.getBlockTypes();
var sharedBlockTypes = [];
// Keep list of custom block types used but not in library.
var unstoredCustomBlockTypes = [];
for (var i = 0, blockType; blockType = this.usedBlockTypes[i]; i++) {
if (storedBlockTypes.indexOf(blockType) != -1) {
sharedBlockTypes.push(blockType);
} else if (BlockFactory.standardBlockTypes.indexOf(blockType) == -1) {
unstoredCustomBlockTypes.push(blockType);
}
}
// Add and evaluate the shared blocks' definitions.
var blockXmlMap = this.blockLibStorage.getBlockXmlMap(sharedBlockTypes);
this.tools.addBlockDefinitions(blockXmlMap);
// For every block, render in selector workspace.
for (var i = 0, blockType; blockType = sharedBlockTypes[i]; i++) {
this.view.addBlock(blockType);
}
// Clean up workspace.
this.view.cleanUpSelectorWorkspace();
if (unstoredCustomBlockTypes.length > 0){
// Warn user to import block definitions and generator code for blocks
// not in their Block Library nor Blockly's standard library.
var blockTypesText = unstoredCustomBlockTypes.join(', ');
var customWarning = 'Custom blocks used in workspace factory but not ' +
'stored in block library:\n ' + blockTypesText +
'\n\nDon\'t forget to include block definitions and generator code ' +
'for these blocks.';
alert(customWarning);
}
};
/**
* Set the array that holds the block types used in workspace factory.
*
* @param {!Array.<!string>} usedBlockTypes - Block types used in
*/
BlockExporterController.prototype.setUsedBlockTypes =
function(usedBlockTypes) {
this.usedBlockTypes = usedBlockTypes;
};

View File

@@ -208,8 +208,7 @@ BlockLibraryController.prototype.setBlockLibStorage
* @return {!BlockLibraryStorage} blockLibStorage - Block Library Storage object
* that stores the blocks.
*/
BlockLibraryController.prototype.getBlockLibStorage =
function(blockLibStorage) {
BlockLibraryController.prototype.getBlockLibStorage = function() {
return this.blockLibStorage;
};

View File

@@ -165,3 +165,14 @@ BlockLibraryStorage.prototype.isEmpty = function() {
BlockLibraryStorage.prototype.getBlockXmlTextMap = function() {
return this.blocks;
};
/**
* Returns boolean of whether or not a given blockType is stored in block
* library.
*
* @param {string} blockType - Type of block.
* @return {boolean} Whether or not blockType is stored in block library.
*/
BlockLibraryStorage.prototype.has = function(blockType) {
return this.blocks[blockType] ? true : false;
};

View File

@@ -872,3 +872,4 @@ FactoryUtils.defineAndGetBlockTypes = function(blockDefsString, format) {
return blockTypes;
};

View File

@@ -1192,3 +1192,12 @@ WorkspaceFactoryController.prototype.setBlockLibCategory =
this.toolboxWorkspace.updateToolbox(this.toolbox);
};
/**
* Return the block types used in the custom toolbox and pre-loaded workspace.
*
* @return {!Array.<!string>} Block types used in the custom toolbox and
* pre-loaded workspace.
*/
WorkspaceFactoryController.prototype.getAllUsedBlockTypes = function() {
return this.model.getAllUsedBlockTypes();
};

View File

@@ -436,7 +436,7 @@ WorkspaceFactoryModel.prototype.getAllUsedBlockTypes = function() {
// Given XML for the workspace, adds all block types included in the XML
// to the list, not including duplicates.
var pushBlockTypesToList = function (xml, list) {
var pushBlockTypesToList = function(xml, list) {
// Get all block XML nodes.
var blocks = xml.getElementsByTagName('block');
@@ -451,22 +451,22 @@ WorkspaceFactoryModel.prototype.getAllUsedBlockTypes = function() {
if (this.flyout) {
// If has a single flyout, add block types for the single flyout.
this.pushBlockTypesToList(this.getSelectedXml(), blockTypeList);
pushBlockTypesToList(this.getSelectedXml(), blockTypeList);
} else {
// If has categories, add block types for each category.
for (var i = 0, category; category = this.toolboxList[i]; i++) {
if (category.type == ListElement.TYPE_CATEGORY) {
this.pushBlockTypesToList(category.xml, blockTypeList);
pushBlockTypesToList(category.xml, blockTypeList);
}
}
}
// Add the block types from any pre-loaded blocks.
this.pushBlockTypesToList(this.getPreloadXml(), blockTypeList);
pushBlockTypesToList(this.getPreloadXml(), blockTypeList);
return blockTypeList;
}
};
/**
* Class for a ListElement.