Merge pull request #971 from cycomachead/resource-loading

Refactor Loading Resources (Sounds, Libraries, etc)
dev
Jens Mönig 2015-11-16 12:34:51 +01:00
commit 2642708780
7 zmienionych plików z 173 dodań i 150 usunięć

Wyświetl plik

@ -0,0 +1,12 @@
atom-playground.jpg Atom Playground
bedroom1.gif Bedroom 1
bedroom2.gif Bedroom 2
berkeley-mural.jpg Berkeley Mural
brick-wall-and-stairs.jpg Brick Wall and Stairs
brick-wall1.jpg Brick Wall 1
brick-wall2.jpg Brick Wall 2
desert.gif Desert
night-city-with-street.gif Night City with Street
party-room.jpg Party Room
pathway.jpg Pathway
xy-grid.gif XY Grid

32
Costumes/COSTUMES 100644
Wyświetl plik

@ -0,0 +1,32 @@
alonzo.png Alonzo
bat1-a.png Bat 1a
bat1-b.png Bat 1b
bat2-a.png Bat 2a
bat2-b.png Bat 2b
boy1-standing.gif Boy 1 Standing
boy1-walking.gif Boy 1 Walking
boy2.gif Boy 2
boy3.gif Boy 3
cat2.gif Cat 2
cat3.png Cat 3
cat4.png Cat 4
cat5.gif Cat 5
dog1-a.png Dog 1a
dog1-b.png Dog 1b
dog2-a.png Dog 2a
dog2-b.png Dog 2b
dog2-c.png Dog 2c
dragon1-a.png Dragon 1a
dragon1-b.png Dragon 1b
dragon2.gif Dragon 2
girl1-standing.gif Girl 1 Standing
girl1-walking.gif Girl 1 Walking
girl2-shouting.gif Girl 2 Shouting
girl2-standing.gif Girl 2 Standing
girl3-basketball.gif Girl 3 Basketball
girl3-running.gif Girl 3 Running
girl3-standing.gif Girl 3 Standing
marissa-crouching.gif Marissa Crouching
marissa-sitting.gif Marissa Sitting
marissa.gif Marissa
unicorn1.png Unicorn

10
Examples/EXAMPLES 100644
Wyświetl plik

@ -0,0 +1,10 @@
animal-game.xml Animal Game
Codification.xml Codification
copter.xml Copter
count-change.xml Count Change
icecream-visual.xml Icecream Visual
JSfunctions.xml JSfunctions
live-tree.xml Live Tree
swimmer.xml Swimmer
tree.xml Tree
vee.xml Vee

12
Sounds/SOUNDS 100644
Wyświetl plik

@ -0,0 +1,12 @@
Cat.mp3 Cat
Chord.wav Chord
Dog1.wav Dog 1
Dog2.wav Dog 2
FingerSnap.wav Finger Snap
Kitten.wav Kitten
Laugh-female.wav Laugh Female
Laugh-male1.wav Laugh Male 1
Laugh-male2.wav Laugh Male 2
Laugh-male3.mp3 Laugh Male 3
Meow.wav Meow
Pop.wav Pop

Wyświetl plik

@ -2570,6 +2570,7 @@ BlockMorph.prototype.restoreInputs = function (oldInputs) {
BlockMorph.prototype.showHelp = function () {
var myself = this,
ide = this.parentThatIsA(IDE_Morph),
pic = new Image(),
help,
comment,
@ -2607,7 +2608,7 @@ BlockMorph.prototype.showHelp = function () {
block.fullImage()
);
} else {
pic.src = 'help/' + spec + '.png';
pic.src = ide.resourceURL('help', spec + '.png');
}
};

240
gui.js
Wyświetl plik

@ -85,16 +85,6 @@ var SoundIconMorph;
var JukeboxMorph;
var StageHandleMorph;
// Get the full url without "snap.html"
var baseURL = (function getPath(location) {
var origin, path, slash;
path = location.pathname; // starts with a /
origin = location.origin; // has no trailing /
slash = path.lastIndexOf('/');
path = path.slice(0, slash + 1); // keep a trailing /
return origin + path;
}(window.location));
// IDE_Morph ///////////////////////////////////////////////////////////
@ -2012,6 +2002,7 @@ IDE_Morph.prototype.userMenu = function () {
IDE_Morph.prototype.snapMenu = function () {
var menu,
myself = this,
world = this.world();
menu = new MenuMorph(this);
@ -2020,7 +2011,8 @@ IDE_Morph.prototype.snapMenu = function () {
menu.addItem(
'Reference manual',
function () {
window.open('help/SnapManual.pdf', 'SnapReferenceManual');
var url = myself.resourceURL('help', 'SnapManual.pdf');
window.open(url, 'SnapReferenceManual');
}
);
menu.addItem(
@ -2478,6 +2470,27 @@ IDE_Morph.prototype.projectMenu = function () {
'Costumes' : 'Backgrounds',
shiftClicked = (world.currentKey === 16);
// Utility for creating Costumes, etc menus.
// loadFunction takes in two parameters: a file URL, and a canonical name
function createMediaMenu (mediaType, loadFunction) {
return function () {
var names = this.getMediaList(mediaType),
mediaMenu = new MenuMorph(
myself,
localize('Import') + ' ' + localize(mediaType)
);
names.forEach(function (item) {
mediaMenu.addItem(
item.name,
function () {loadFunction(item.file, item.name); },
item.help
);
});
mediaMenu.popup(world, pos);
}
}
menu = new MenuMorph(this);
menu.addItem('Project notes...', 'editProjectNotes');
menu.addLine();
@ -2589,9 +2602,7 @@ IDE_Morph.prototype.projectMenu = function () {
'Import tools',
function () {
myself.droppedText(
myself.getURLsbeOrRelative(
'tools.xml'
),
myself.getURL('tools.xml'),
'tools'
);
},
@ -2599,46 +2610,22 @@ IDE_Morph.prototype.projectMenu = function () {
);
menu.addItem(
'Libraries...',
function () {
// read a list of libraries from an external file,
var libMenu = new MenuMorph(this, 'Import library'),
libUrl = baseURL + 'libraries/' + 'LIBRARIES';
function loadLib(name) {
var url = baseURL + 'libraries/' + name + '.xml';
createMediaMenu(
'libraries',
function loadLib(file, name) {
var url = myself.resourceURL('libraries', file);
myself.droppedText(myself.getURL(url), name);
}
myself.getURL(libUrl).split('\n').forEach(function (line) {
if (line.length > 0) {
libMenu.addItem(
line.substring(line.indexOf('\t') + 1),
function () {
loadLib(
line.substring(0, line.indexOf('\t'))
);
}
);
}
});
libMenu.popup(world, pos);
},
),
'Select categories of additional blocks to add to this project.'
);
menu.addItem(
localize(graphicsName) + '...',
function () {
var dir = graphicsName,
names = myself.getCostumesList(dir),
libMenu = new MenuMorph(
myself,
localize('Import') + ' ' + localize(dir)
);
function loadCostume(name) {
var url = dir + '/' + name,
createMediaMenu(
graphicsName,
function loadCostume(file, name) {
var url = myself.resourceURL(graphicsName, file),
img = new Image();
img.onload = function () {
var canvas = newCanvas(new Point(img.width, img.height));
@ -2647,74 +2634,84 @@ IDE_Morph.prototype.projectMenu = function () {
};
img.src = url;
}
names.forEach(function (line) {
if (line.length > 0) {
libMenu.addItem(
line,
function () {loadCostume(line); }
);
}
});
libMenu.popup(world, pos);
},
),
'Select a costume from the media library'
);
menu.addItem(
localize('Sounds') + '...',
function () {
var names = this.getCostumesList('Sounds'),
libMenu = new MenuMorph(this, 'Import sound');
function loadSound(name) {
var url = 'Sounds/' + name,
createMediaMenu(
'Sounds',
function loadSound(file, name) {
var url = myself.resourceURL('Sounds', file),
audio = new Audio();
audio.src = url;
audio.load();
myself.droppedAudio(audio, name);
}
names.forEach(function (line) {
if (line.length > 0) {
libMenu.addItem(
line,
function () {loadSound(line); }
);
}
});
libMenu.popup(world, pos);
},
),
'Select a sound from the media library'
);
menu.popup(world, pos);
};
IDE_Morph.prototype.getCostumesList = function (dirname) {
var dir,
costumes = [];
// Give a path a file in subfolders.
// Method can be easily overridden if running in a custom location.
IDE_Morph.prototype.resourceURL = function (folder, file) {
return folder + '/' + file;
}
dir = this.getURL(dirname);
dir.split('\n').forEach(
function (line) {
var startIdx = line.search(new RegExp('href="[^./?].*"')),
endIdx,
name;
// Return a list of files in a directory based on the contents file
IDE_Morph.prototype.getMediaList = function (dirname) {
var url, data;
if (startIdx > 0) {
name = line.substring(startIdx + 6);
endIdx = name.search(new RegExp('"'));
name = name.substring(0, endIdx);
costumes.push(name);
}
}
);
costumes.sort(function (x, y) {
return x < y ? -1 : 1;
url = this.resourceURL(dirname, dirname.toUpperCase());
data = this.parseResourceFile(this.getURL(url));
data.sort(function (x, y) {
return x.name.toLowerCase() < y.name.toLowerCase() ? -1 : 1;
});
return costumes;
return data;
};
// A Resource File lists all the files that could be loaded in a submenu
// Examples are libraries/LIBRARIES, Costumes/COSTUMES, etc
// A File is very simple:
// A "//" starts a comment line, that is ignored.
// All lines have 3 fields: file-name, Display Name, Help Text
// These fields are delimited by tabs.
IDE_Morph.prototype.parseResourceFile = function (text) {
var parts,
items = [],
comment = '//',
delimter = '\t';
text = text.split(/\n|\r\n/);
text.map(function (line) {
return line.trim();
}).filter(function (line) {
return line.length > 0 && line[0] !== comment;
}).forEach(function (line) {
parts = line.split(delimter);
parts = parts.map(function (str) { return str.trim() });
if (parts.length < 2) {
return;
}
items.push({
file: parts[0],
name: parts[1],
help: parts.length > 2 ? parts[2] : ''
});
});
return items;
};
// IDE_Morph menu actions
IDE_Morph.prototype.aboutSnap = function () {
@ -4651,7 +4648,7 @@ IDE_Morph.prototype.setCloudURL = function () {
);
};
// IDE_Morph synchronous Http data fetching
// IDE_Morph synchronous HTTP data fetching
IDE_Morph.prototype.getURL = function (url) {
var request = new XMLHttpRequest(),
@ -4669,22 +4666,6 @@ IDE_Morph.prototype.getURL = function (url) {
}
};
IDE_Morph.prototype.getURLsbeOrRelative = function (url) {
var request = new XMLHttpRequest(),
myself = this;
try {
request.open('GET', baseURL + url, false);
request.send();
if (request.status === 200) {
return request.responseText;
}
return myself.getURL(url);
} catch (err) {
myself.showMessage(err);
return;
}
};
// IDE_Morph user dialog shortcuts
IDE_Morph.prototype.showMessage = function (message, secs) {
@ -5106,7 +5087,7 @@ ProjectDialogMorph.prototype.setSource = function (source) {
}
myself.edit();
};
} else { // 'examples', 'cloud' is initialized elsewhere
} else { // 'examples'; 'cloud' is initialized elsewhere
this.listField.action = function (item) {
var src, xml;
if (item === undefined) {return; }
@ -5114,7 +5095,7 @@ ProjectDialogMorph.prototype.setSource = function (source) {
myself.nameField.setContents(item.name || '');
}
src = myself.ide.getURL(
baseURL + 'Examples/' + item.name + '.xml'
myself.ide.resourceURL('Examples', item.file)
);
xml = myself.ide.serializer.parse(src);
@ -5166,33 +5147,7 @@ ProjectDialogMorph.prototype.getLocalProjectList = function () {
};
ProjectDialogMorph.prototype.getExamplesProjectList = function () {
var dir,
projects = [];
//alert(baseURL);
dir = this.ide.getURL(baseURL + 'Examples/');
dir.split('\n').forEach(
function (line) {
var startIdx = line.search(new RegExp('href=".*xml"')),
endIdx,
name,
dta;
if (startIdx > 0) {
endIdx = line.search(new RegExp('.xml'));
name = line.substring(startIdx + 6, endIdx);
dta = {
name: name,
thumb: null,
notes: null
};
projects.push(dta);
}
}
);
projects = projects.sort(function (x, y) {
return x.name.toLowerCase() < y.name.toLowerCase() ? -1 : 1;
});
return projects;
return this.ide.getMediaList('Examples');
};
ProjectDialogMorph.prototype.installCloudProjectList = function (pl) {
@ -5289,7 +5244,8 @@ ProjectDialogMorph.prototype.openProject = function () {
if (this.source === 'cloud') {
this.openCloudProject(proj);
} else if (this.source === 'examples') {
src = this.ide.getURL(baseURL + 'Examples/' + proj.name + '.xml');
// Note "file" is a property of the parseResourceFile function.
src = this.ide.getURL(this.ide.resourceURL('Examples', proj.file));
this.ide.openProjectString(src);
this.destroy();
} else { // 'local'

Wyświetl plik

@ -1,7 +1,7 @@
iteration-composition Iteration, composition
list-utilities List utilities
stream-tools Streams (lazy lists)
variadic-reporters Variadic reporters
word-sentence Words, sentences
cases Multi-branched conditional (switch)
leap-library LEAP Motion controller
iteration-composition.xml Iteration, composition
list-utilities.xml List utilities
stream-tools.xml Streams (lazy lists)
variadic-reporters.xml Variadic reporters
word-sentence.xml Words, sentences
cases.xml Multi-branched conditional (switch)
leap-library.xml LEAP Motion controller