namespace pxt . editor { const fieldEditorId = "tilemap-editor" ; export class MonacoTilemapEditor extends MonacoReactFieldEditor < pxt . ProjectTilemap > { protected isTilemapLiteral : boolean ; protected tilemapLiteral : string ; protected textToValue ( text ) { const tm = this . readTilemap ( text ) ; const project = pxt . react . getTilemapProject ( ) ; pxt . sprite . addMissingTilemapTilesAndReferences ( project , tm ) ; return tm ; } protected readTilemap ( text ) { const project = pxt . react . getTilemapProject ( ) ; if ( /^\s*tiles\s*\./ . test ( text ) ) { this . isTilemapLiteral = false ; if ( text ) { try { const data = pxt . sprite . decodeTilemap ( text , "typescript" , project ) ; return createFakeAsset ( data ) ; } catch ( e ) { } return null ; } } this . isTilemapLiteral = true ; const match = /^\s*(tilemap(?:8|16|32)?)\s*(?:`([^`]*)`)|(?:\(\s*"""([^"]*)"""\s*\))\s*$/ . exec ( text ) ; const name = ( match [ 2 ] || match [ 3 ] || "" ) . trim ( ) ; this . tilemapLiteral = match [ 1 ] ; let proj ; let id ; if ( name ) { let id = ts . pxtc . escapeIdentifier ( name ) ; proj = project . getTilemap ( id ) ; } if ( ! proj ) { let tileWidth = 16 ; if ( this . tilemapLiteral === "tilemap8" ) { tileWidth = 8 ; } else if ( this . tilemapLiteral === "tilemap32" ) { tileWidth = 32 ; } const [ name ] = project . createNewTilemap ( id , tileWidth , 16 , 16 ) ; proj = project . getTilemap ( name ) ; id = name ; } return proj ; } protected resultToText ( asset ) { const project = pxt . react . getTilemapProject ( ) ; project . pushUndo ( ) ; pxt . sprite . updateTilemapReferencesFromResult ( project , asset ) ; if ( this . isTilemapLiteral ) { project . updateAsset ( asset ) ; return pxt . getTSReferenceForAsset ( asset , this . fileType === "python" ) ; } else { return pxt . sprite . encodeTilemap ( asset . data , this . fileType === "typescript" ? "typescript" : "python" ) ; } } protected getFieldEditorId ( ) { return "tilemap-editor" ; } protected getOptions ( ) { return { initWidth : 16 , initHeight : 16 , blocksInfo : this . host . blocksInfo ( ) } ; } protected getCreateTilemapRange ( ) { const start = this . editrange . getStartPosition ( ) ; let current = this . editrange . getEndPosition ( ) ; let range ; let openParen = 1 ; while ( true ) { range = new monaco . Range ( current . lineNumber , current . column , current . lineNumber + 1 , 0 ) ; const line = this . host . getText ( range ) ; for ( let i = 0 ; i < line . length ; i ++ ) { if ( line . charAt ( i ) === "(" ) { openParen ++ ; } else if ( line . charAt ( i ) === ")" ) { openParen -- ; if ( openParen === 0 ) { const end = new monaco . Position ( current . lineNumber , current . column + i + 2 ) ; return monaco . Range . fromPositions ( start , end ) ; } } } current = range . getEndPosition ( ) ; if ( current . lineNumber > start . lineNumber + 20 ) { return null ; } } } } function createFakeAsset ( data ) { return { type : pxt . AssetType . Tilemap , id : "" , internalID : 0 , meta : { } , data } ; } export const tilemapEditorDefinition = { id : fieldEditorId , foldMatches : true , alwaysBuildOnClose : true , glyphCssClass : "sprite-focus-hover ms-Icon ms-Icon--Nav2DMapView" , heightInPixels : 510 , weight : 5 , matcher : { searchString : "(?:tilemap(?:8|16|32)?\\s*(?:`|\\(\"\"\")(?:[ a-zA-Z0-9_]|\\n)*\\s*(?:`|\"\"\"\\)))|(?:tiles\\s*\\.\\s*createTilemap\\s*\\([^\\)]+\\))" , isRegex : true , matchCase : true , matchWholeWord : false } , proto : MonacoTilemapEditor } ; registerMonacoFieldEditor ( fieldEditorId , tilemapEditorDefinition ) ; }