616 строки
15 KiB
TypeScript
616 строки
15 KiB
TypeScript
///<reference path='refs.ts'/>
|
|
|
|
module TDev.RT {
|
|
//? Pictures and music...
|
|
//@ skill(2)
|
|
export module Media
|
|
{
|
|
export function rt_start(rt: Runtime): void
|
|
{}
|
|
|
|
export function rt_stop(rt: Runtime)
|
|
{
|
|
AudioContextManager.stop();
|
|
}
|
|
|
|
//? Plays a monotone sine wave
|
|
//@ [gain].defl(1) [frequency].defl(440)
|
|
export function tone(frequency: number, gain: number) {
|
|
if (Math_.is_nan(frequency) || Math_.is_nan(gain)) return;
|
|
AudioContextManager.tone(frequency, gain);
|
|
}
|
|
|
|
//? Plays a monotone note
|
|
//@ [gain].defl(1) [frequency].defl(440) [seconds].defl(1)
|
|
export function play_note(frequency: number, gain: number, seconds: number, r: ResumeCtx) {
|
|
if (Math_.is_nan(frequency) || Math_.is_nan(gain) || Math_.is_nan(seconds) || seconds <= 0) return;
|
|
|
|
AudioContextManager.tone(frequency, gain);
|
|
Util.setTimeout(seconds * 1000, () => {
|
|
AudioContextManager.tone(frequency, 0);
|
|
Util.setTimeout(40, () => {
|
|
r.resume();
|
|
})
|
|
})
|
|
}
|
|
|
|
//? Creates a new picture of the given size
|
|
//@ [result].writesMutable
|
|
//@ [width].defl(480) [height].defl(800)
|
|
export function create_picture(width:number, height:number) : Picture { return Picture.mk(width, height); }
|
|
|
|
//? Searches the Windows Phone Store (type in applications or music)
|
|
//@ stub flow(SinkSafe) obsolete
|
|
//@ [type].defl("music")
|
|
export function search_marketplace(terms:string, type:string) : void
|
|
{ }
|
|
|
|
export function askMusicAccessAsync(r : ResumeCtx): Promise { // boolean
|
|
return r.rt.host.askSourceAccessAsync("music", "your songs, song albums and playlists.", false);
|
|
}
|
|
export function askPictureAccessAsync(r : ResumeCtx): Promise { // boolean
|
|
return r.rt.host.askSourceAccessAsync("picture", "your pictures and picture albums.", false);
|
|
}
|
|
|
|
//? Gets the playlists on the phone
|
|
//@ cap(media) flow(SourceMusic) returns(Playlists)
|
|
//@ embedsLink("Playlists", "Playlist") async
|
|
export function playlists(r : ResumeCtx) // : Playlists
|
|
{
|
|
askMusicAccessAsync(r)
|
|
.then(allow => r.resumeVal(undefined))
|
|
.done();
|
|
}
|
|
|
|
export function pictureUriForMedia(uri: string, media: string) {
|
|
return uri;
|
|
}
|
|
|
|
export function pictureDataUriAsync(uri: string): Promise { // string
|
|
return Promise.as(undefined);
|
|
}
|
|
|
|
var _pictureUrls: string[] = undefined;
|
|
export function picturesAsync(uri : string) : Promise
|
|
{
|
|
if (!!_pictureUrls)
|
|
return Promise.as(Pictures.mk(_pictureUrls));
|
|
return BingServices.searchAsync("Images", "cat", null)
|
|
.then((results) => {
|
|
_pictureUrls = results.map((r) => r.url).slice(0, 4);
|
|
return Pictures.mk(_pictureUrls);
|
|
});
|
|
}
|
|
|
|
var _pictureAlbums: PictureAlbums = undefined;
|
|
export function pictureAlbumsAsync(uri : string) : Promise
|
|
{
|
|
if (_pictureAlbums) return Promise.as(_pictureAlbums);
|
|
|
|
return Media.picturesAsync(uri).then(pics => {
|
|
_pictureAlbums = PictureAlbums.mk([PictureAlbum.mk('cats', 'cats', pics)]);
|
|
return _pictureAlbums;
|
|
});
|
|
}
|
|
|
|
//? Gets the pictures on the phone
|
|
//@ async cap(media) flow(SourcePicture) returns(Pictures)
|
|
//@ embedsLink("Pictures", "Picture")
|
|
export function pictures(r: ResumeCtx) {
|
|
askPictureAccessAsync(r)
|
|
.then(allow => {
|
|
if (!allow) return Promise.as(Pictures.mk([]));
|
|
else return Media.picturesAsync('');
|
|
}).done(pics => r.resumeVal(pics));
|
|
}
|
|
|
|
|
|
//? Gets the saved pictures on the phone
|
|
//@ cap(media) flow(SourcePicture) returns(Pictures)
|
|
//@ embedsLink("Pictures", "Picture") async
|
|
export function saved_pictures(r: ResumeCtx) // : Pictures
|
|
{
|
|
pictures(r);
|
|
}
|
|
|
|
export function choosePictureAsync(title = 'choose a picture', description = ''): Promise {
|
|
var cam = (<any>navigator).camera;
|
|
if (cam) {
|
|
return new Promise((onSuccess, onError, onProgress) => {
|
|
cam.getPicture((url) => {
|
|
onSuccess(Picture.fromUrlSync(url, false, false));
|
|
}, (msg) => {
|
|
TDev.RT.App.logEvent(App.DEBUG, "senses", "choose picture failed: " + msg, undefined);
|
|
onSuccess(undefined);
|
|
}, {
|
|
quality: 85,
|
|
mediaType: (<any>window).Camera.MediaType.JPEG,
|
|
sourceType: (<any>window).Camera.PictureSourceType.PHOTOLIBRARY,
|
|
destinationType: (<any>window).Camera.DestinationType.FILE_URI
|
|
});
|
|
});
|
|
}
|
|
|
|
return new Promise(function (onSuccess, onError, onProgress) {
|
|
var m = new ModalDialog();
|
|
var file = HTML.mkImageInput(true, -1);
|
|
var pic : Picture = null;
|
|
m.add([div("wall-dialog-header", title),
|
|
div('wall-dialog-body', description),
|
|
div("wall-dialog-input", file.element),
|
|
div("wall-dialog-buttons", HTML.mkButtonOnce("ok", () => {
|
|
file.readAsync()
|
|
.then(dataUri => {
|
|
if (dataUri) return Picture.fromUrl(dataUri);
|
|
else return Promise.as(null);
|
|
})
|
|
.then(p => {
|
|
pic = p;
|
|
return p ? p.initAsync() : null;
|
|
})
|
|
.done(() => { m.dismiss(); });
|
|
})
|
|
)
|
|
]);
|
|
m.onDismiss = () => onSuccess(pic);
|
|
m.show();
|
|
});
|
|
}
|
|
|
|
//? Chooses a picture from the media library
|
|
//@ flow(SourcePicture) returns(Picture) uiAsync
|
|
//@ import("cordova", "org.apache.cordova.camera")
|
|
export function choose_picture(r: ResumeCtx)
|
|
{
|
|
return choosePictureAsync().done(pic => r.resumeVal(pic));
|
|
}
|
|
|
|
//? Gets the picture albums
|
|
//@ cap(media) flow(SourcePicture) returns(PictureAlbums)
|
|
//@ embedsLink("Picture Albums", "Picture Album") async
|
|
export function picture_albums(r: ResumeCtx) //: PictureAlbums
|
|
{
|
|
askPictureAccessAsync(r)
|
|
.then(allow => {
|
|
if (!allow) return Promise.as(PictureAlbums.mk([]));
|
|
else return Media.pictureAlbumsAsync('');
|
|
}).done(albums => r.resumeVal(albums));
|
|
}
|
|
|
|
export function initSongAlbumAsync(album: SongAlbum): Promise { // must call init
|
|
album.init('', 0, null);
|
|
return Promise.as(undefined);
|
|
}
|
|
|
|
export function loadSongAlbumArtAsync(albumName: string): Promise { // string
|
|
return Promise.as(undefined);
|
|
}
|
|
|
|
export function songsAsync(album : string) : Promise // Songs
|
|
{
|
|
return Promise.as(Songs.mk([]));
|
|
}
|
|
|
|
export function songAlbumsAsync() : Promise // SongAlbums
|
|
{
|
|
return Promise.as(SongAlbums.mk([]));
|
|
}
|
|
|
|
//? Gets the songs on the phone
|
|
//@ cap(media) flow(SourceMusic) returns(Songs)
|
|
//@ embedsLink("Songs", "Song") async
|
|
export function songs(r: ResumeCtx)
|
|
{
|
|
askMusicAccessAsync(r)
|
|
.then(allow => {
|
|
if (!allow) return Promise.as(Songs.mk([]));
|
|
else return Media.songsAsync("");
|
|
}).done(s => r.resumeVal(s));
|
|
}
|
|
|
|
//? Gets the song albums on the phone
|
|
//@ cap(media) flow(SourceMusic) returns(SongAlbums)
|
|
//@ embedsLink("Song Albums", "Song Album") async
|
|
export function song_albums(r : ResumeCtx) // : SongAlbums
|
|
{
|
|
askMusicAccessAsync(r)
|
|
.then(allow => {
|
|
if (!allow) return Promise.as(SongAlbums.mk([]));
|
|
else return Media.songAlbumsAsync();
|
|
}).done(s => r.resumeVal(s));
|
|
}
|
|
|
|
//? Creates a new game board
|
|
//@ timestamp
|
|
//@ [result].writesMutable
|
|
//@ [height].defl(640)
|
|
export function create_board(height:number, s:IStackFrame) : Board { return Board.mk(s.rt, false, 456, height, false); }
|
|
|
|
//? Creates a new game board in portrait mode. On rotatable devices it will take the entire screen when posted.
|
|
//@ obsolete
|
|
//@ timestamp
|
|
//@ [result].writesMutable
|
|
export function create_full_board(s:IStackFrame) : Board {
|
|
return Board.mk(s.rt, false, 480, 800, true);
|
|
}
|
|
|
|
//? Creates a new game board in portrait mode. On rotatable devices it will take the entire screen when posted.
|
|
//@ [result].writesMutable
|
|
//@ [width].defl(480) [height].defl(800)
|
|
export function create_portrait_board(width:number, height:number, s:IStackFrame) : Board {
|
|
return Board.mk(s.rt, false, width, height, true);
|
|
}
|
|
|
|
//? Creates a new game board in landscape mode. On rotatable devices it will take the entire screen when posted.
|
|
//@ [result].writesMutable
|
|
//@ [width].defl(800) [height].defl(480)
|
|
export function create_landscape_board(width:number, height:number, s:IStackFrame) : Board {
|
|
return Board.mk(s.rt, true, width, height, true);
|
|
}
|
|
|
|
var iconNames = [
|
|
'123',
|
|
'8ball',
|
|
'abc',
|
|
'acorn',
|
|
'add',
|
|
'addcircle',
|
|
'addfolder',
|
|
'addressbook',
|
|
'adduser',
|
|
'adminuser',
|
|
'airplane',
|
|
'aligncenter',
|
|
'alignleft',
|
|
'alignright',
|
|
'almostequal',
|
|
'alram',
|
|
'anchor',
|
|
'appointment',
|
|
'approvebutton',
|
|
'arrowbox',
|
|
'arrowcirclealt',
|
|
'arrow-circle-r',
|
|
'arrowcirclerounded',
|
|
'arrowdotted',
|
|
'arrowdownl',
|
|
'arrowdownr',
|
|
'arrowdownrounded',
|
|
'arrowhead',
|
|
'arrowlarge',
|
|
'arrowlr',
|
|
'arrowmoving',
|
|
'arrowr',
|
|
'arrowrlarge',
|
|
'arrowrounded',
|
|
'arrowstandard',
|
|
'arrowstandardcircle',
|
|
'award',
|
|
'barchart',
|
|
'beer',
|
|
'bell',
|
|
'binoculars',
|
|
'blankpage',
|
|
'bold',
|
|
'bolt',
|
|
'bomb',
|
|
'book',
|
|
'bookmark',
|
|
'briefcase',
|
|
'brush',
|
|
'bulletlist',
|
|
'bullseye',
|
|
'business',
|
|
'businesscard',
|
|
'businessperson',
|
|
'butterfly',
|
|
'cactus',
|
|
'calculator',
|
|
'callout',
|
|
'camera',
|
|
'capitalize',
|
|
'caution',
|
|
'chapback',
|
|
'chapbackcircle',
|
|
'chapforward',
|
|
'chargingbattery',
|
|
'check',
|
|
'checkalt',
|
|
'checkbox',
|
|
'checkcircle',
|
|
'checkcirclealt',
|
|
'cherry',
|
|
'clipboard',
|
|
'clock',
|
|
'clover',
|
|
'club',
|
|
'coffeecup',
|
|
'command',
|
|
'commandline',
|
|
'construction',
|
|
'contacts',
|
|
'controller',
|
|
'controls',
|
|
'copyright',
|
|
'creditcard',
|
|
'cube',
|
|
'cut',
|
|
'cycle',
|
|
'dashboard',
|
|
'delete',
|
|
'deleteuser',
|
|
'deliverytruck',
|
|
'directions',
|
|
'document',
|
|
'documents',
|
|
'documentsalt',
|
|
'dollar',
|
|
'downbox',
|
|
'download',
|
|
'downloadbutton',
|
|
'downloadbuttonalt',
|
|
'downloadpage',
|
|
'drawing',
|
|
'email',
|
|
'emaildoc',
|
|
'emailopen',
|
|
'emergency',
|
|
'emptybattery',
|
|
'erase',
|
|
'euro',
|
|
'exclamation',
|
|
'exclamationcircle',
|
|
'exclamationcirclealt',
|
|
'exit',
|
|
'expand',
|
|
'eye',
|
|
'farm',
|
|
'female',
|
|
'files',
|
|
'film',
|
|
'fire',
|
|
'fit',
|
|
'fithorizontal',
|
|
'flag',
|
|
'fleurdelis',
|
|
'flipchart',
|
|
'flowchart',
|
|
'folder',
|
|
'formattext',
|
|
'forward',
|
|
'forwardbutton',
|
|
'fourcolumn',
|
|
'fullbattery',
|
|
'funnel',
|
|
'gaspump',
|
|
'globe',
|
|
'globea',
|
|
'globeas',
|
|
'globeaus',
|
|
'globeeua',
|
|
'globesa',
|
|
'globeus',
|
|
'government',
|
|
'gps',
|
|
'grapes',
|
|
'graph',
|
|
'group',
|
|
'halfbattery',
|
|
'hammer',
|
|
'headphones',
|
|
'heart',
|
|
'heartalt',
|
|
'help',
|
|
'home',
|
|
'homealt',
|
|
'horn',
|
|
'horseshoe',
|
|
'hourglass',
|
|
'im',
|
|
'inbox',
|
|
'info',
|
|
'infocircle',
|
|
'infocirclealt',
|
|
'italic',
|
|
'journal',
|
|
'joystick',
|
|
'justified',
|
|
'key',
|
|
'lab',
|
|
'ladder',
|
|
'leaf',
|
|
'lightbulb',
|
|
'linechart',
|
|
'link',
|
|
'loading',
|
|
'loadingalt',
|
|
'location',
|
|
'lock',
|
|
'lockedfolder',
|
|
'male',
|
|
'map',
|
|
'martini',
|
|
'maximize',
|
|
'megaphone',
|
|
'mic',
|
|
'minusbox',
|
|
'minusboxalt',
|
|
'mobilephone',
|
|
'money',
|
|
'monitor',
|
|
'moon',
|
|
'mountains',
|
|
'movie',
|
|
'mp3player',
|
|
'multiply',
|
|
'multiplycircle',
|
|
'music',
|
|
'mute',
|
|
'needle',
|
|
'newpage',
|
|
'newpagealt',
|
|
'nextscenebutton',
|
|
'ninecolumn',
|
|
'notebook',
|
|
'numberedlist',
|
|
'omega',
|
|
'openfolder',
|
|
'package',
|
|
'pagecurl',
|
|
'paint',
|
|
'painting',
|
|
'paperclip',
|
|
'pause',
|
|
'pausecircle',
|
|
'pear',
|
|
'pen',
|
|
'penalt',
|
|
'pencil',
|
|
'person',
|
|
'phone',
|
|
'photo',
|
|
'photos',
|
|
'pie',
|
|
'piechart',
|
|
'play',
|
|
'playbutton',
|
|
'playcircle',
|
|
'plusbox',
|
|
'plusboxalt',
|
|
'pluscircle',
|
|
'pound',
|
|
'power',
|
|
'presentation',
|
|
'pricetag',
|
|
'printer',
|
|
'pushpin',
|
|
'question',
|
|
'questioncircle',
|
|
'questioncirclealt',
|
|
'quote',
|
|
'raindrop',
|
|
'reading',
|
|
'recycle',
|
|
'removebutton',
|
|
'removefolder',
|
|
'removepage',
|
|
'removeuser',
|
|
'restore',
|
|
'revert',
|
|
'rewind',
|
|
'rewindcircle',
|
|
'ribbon',
|
|
'runningman',
|
|
'save',
|
|
'savealt',
|
|
'screwdriver',
|
|
'search',
|
|
'setting',
|
|
'settings',
|
|
'share',
|
|
'sharethis',
|
|
'shield',
|
|
'shirt',
|
|
'shoppingbag',
|
|
'shoppingbasket',
|
|
'shoppingcart',
|
|
'shoppingcartalt',
|
|
'shrink',
|
|
'shuffle',
|
|
'signal',
|
|
'signalalt',
|
|
'sixcolumn',
|
|
'smartphone',
|
|
'smiliehappy',
|
|
'smiliehappyalt',
|
|
'smiliejustok',
|
|
'smiliejustokalt',
|
|
'smiliesad',
|
|
'smiliesadalt',
|
|
'sms',
|
|
'smsalt',
|
|
'snowflake',
|
|
'sort',
|
|
'sortaz',
|
|
'sound',
|
|
'soundhigh',
|
|
'soundlow',
|
|
'space',
|
|
'spade',
|
|
'split',
|
|
'stacks',
|
|
'star',
|
|
'staralt',
|
|
'strikeout',
|
|
'subtract',
|
|
'subtractcircle',
|
|
'suitcase',
|
|
'sun',
|
|
'switch',
|
|
'tableft',
|
|
'tabright',
|
|
'tanktop',
|
|
'target',
|
|
'terminal',
|
|
'text',
|
|
'threecolumn',
|
|
'thumbsdown',
|
|
'ticket',
|
|
'tools',
|
|
'touchpad',
|
|
'trash',
|
|
'tree',
|
|
'umbrella',
|
|
'underline',
|
|
'unlock',
|
|
'upbox',
|
|
'upload',
|
|
'video',
|
|
'videocam',
|
|
'wand',
|
|
'warning',
|
|
'warningalt',
|
|
'watch',
|
|
'weather',
|
|
'wheel',
|
|
'wifi',
|
|
'wine',
|
|
'workorder',
|
|
'wrench',
|
|
'writepage',
|
|
'yen',
|
|
'zoomin',
|
|
'zoomout'
|
|
];
|
|
|
|
//? Gets the list of built-in 48x48 icon names. You can see the icon list in the script settings.
|
|
//@ hidden cap(editoronly)
|
|
export function icon_names() : Collection<string>
|
|
{
|
|
return Collection.mkStrings(iconNames.slice(0));
|
|
}
|
|
|
|
function load_icon(name : string, size:number)
|
|
{
|
|
if (iconNames.indexOf(name.toLowerCase()) < 0)
|
|
return undefined;
|
|
|
|
return Picture.fromSVGIcon(name.toLowerCase(), size);
|
|
}
|
|
|
|
//? Gets a 48x48 icon picture. Use 'media->icon names' to retrieve the list of names available.
|
|
//@ hidden cap(editoronly)
|
|
export function icon(name:string):Picture
|
|
{
|
|
return load_icon(name, 48);
|
|
}
|
|
|
|
//? Gets a 96x96 icon picture. Use 'media->icon names' to retrieve the list of names available.
|
|
//@ hidden cap(editoronly)
|
|
export function large_icon(name:string):Picture
|
|
{
|
|
return load_icon(name, 96);
|
|
}
|
|
}
|
|
}
|