// vismap.js - layer/scene visibility map // copyright 2009, Martin Rinehart var model; // filled in with JSON from Ruby var layer_cbs = []; // checkboxes outside the layer names var rc_cbs = []; // main (row/col) checkboxes var scene_cbs = []; // checkboxes above the scene numbers // function TOC // support functions, in alpha order // click handlers, also alpha // createXxxx(), also alpha // Note: The associated "vismap.html" has an empty . // SUPPORT FUNCTIONS function add_checkbox( cell, i, id_suffix, handler ) { var cb = document.createElement( 'input' ); cb.id = i + '_' + id_suffix; cb.type = 'checkbox'; cell.appendChild( cb ); cb.onclick = handler; } function get_layer_cbs() { for ( var i = 0; i < model.layers.length; i++ ) { layer_cbs[i] = document.getElementById( i + '_layers_cb' ); } } function error() { return model.vis.substring(0,1) == 'E'; } function get_rc_cbs() { for ( var i = 0; i < model.layers.length; i++ ) { for ( j = 0; j < model.scenes.length; j++ ) { var k = i*model.scenes.length + j; var id = num_given_rc(i, j) + '_rc_cb' rc_cbs[ k ] = document.getElementById( id ); rc_cbs[ k ].checked = ( model.vis.substr(k,1) == 'V' ) } } } function get_scene_cbs() { for ( var i = 0; i < model.scenes.length; i++ ) { scene_cbs[i] = document.getElementById( i + '_scenes_cb' ); } } function getVis() { // assembles new string of 'V's and 'I's var nlayers = model.layers.length; var nscenes = model.scenes.length; var vis = ''; for ( var i = 0; i < (nlayers*nscenes); i++ ) { vis += rc_cbs[ i ].checked ? 'V' : 'I'; } return vis; } function nospace( txt ) { return txt.replace( new RegExp(' ','g'), ' ' ); } function num_given_rc( r, c ) { return r * model.scenes.length + c; } function rc_given_num( num ) { var len = model.scenes.length; return [ Math.round(( num / len ) - 0.5), num % len ]; } // called by and by "Refresh" button function rubyCalled( callback_name, message ) { if ( (typeof message) == 'undefined' ) message = ''; url = 'skp:' + callback_name + '@' + message; // window.location.href = url; rubyReturned( "{ layers:[ 'Layer0', 'basement', 'ground_floor', 'garage', 'second_floor', 'stairs', 'roof' ], scenes:[ 'outside, aerial', 'outside, front door', 'livingroom', 'diningroom', 'bedroom', 'garage' ], vis:'VVVVVVVVIIIVVVVVIVVVVVVVVVIVVVIIVVVIVVIIIV' }" ); } // called from Ruby function rubyReturned( json ) { eval( 'model = ' + json ); // whats_in_model(); createUI(); if ( !error() ) { createUIrefs(); } } whats_in_model = function() { alert( 'layers = ' + model.layers + '\n' + 'scenes = ' + model.scenes + '\n' + 'vis = ' + model.vis ); } function write_checkbox( r, c ) { var n = num_given_rc( r, c ); ret = ' '; return ret; } function write_layer_checkbox( r ) { ret = ' '; return ret; } function write_scene_checkbox( c ) { ret = ' '; return ret; } // CLICK HANDLERS var btn_download = function() { var vis = getVis(); rubyCalled( 'newVis', vis ); } var btn_refresh = function() { rubyCalled( 'refresh' ); } // on unchecking an individual box, uncheck its scene/layer boxes var handle_click = function() { var n = parseInt( this.id ); if ( rc_cbs[n].checked ) return; var where = rc_given_num( n ); var row = where[0]; var col = where[1]; scene_cbs[ col ].checked = false; layer_cbs[ row ].checked = false; } // end of handle_click() var handle_layer_click = function( ) { var r = parseInt( this.id ); var base = r * model.scenes.length; var stop = base + model.scenes.length; for ( i = base; i < stop; i++ ) { rc_cbs[ i ].checked = layer_cbs[ r ].checked; if ( ! rc_cbs[i].checked ) { scene_cbs[ rc_given_num(i)[1] ].checked = false; } } } // end of handle_layer_click() var handle_scene_click = function() { var col = parseInt( this.id ); for ( i = 0; i < model.layers.length; i++ ) { j = col + i*model.scenes.length; rc_cbs[ j ].checked = scene_cbs[ col ].checked; if ( ! rc_cbs[j].checked ) { layer_cbs[ rc_given_num(j)[0] ].checked = false; } } } // WRITE THE SECTION function createButton( id, txt ) { var btn = document.createElement( 'button' ); btn.id = id; btn.innerHTML = txt; btn.style.background = '#e0ffe0'; return btn; } function createButtonSpacer() { var span = document.createElement( 'span' ); span.innerHTML = ' ' return span; } function createInnerTable() { var cell, // a cell being created/populated cl, // column (in rw/cl loops) i, // loop counter itbl, // the inner table row, // a row being created/populated rw // row (in rw/cl loops) itbl = document.createElement( 'table' ); itbl.align = 'center'; itbl.style.backgroundColor = '#f0f0ff'; itbl.border=0; itbl.cellPadding=3; itbl.style.height='100%'; itbl.style.width='100%'; row = itbl.insertRow(0); // top row: scenes' checkboxes row.insertCell(0); row.insertCell(1); // first two are empty for ( i = 0; i < model.scenes.length; i++ ) { cell = row.insertCell(i+2); add_checkbox( cell, i, 'scenes_cb', handle_scene_click ); } row = itbl.insertRow(1); // 2nd row, scene numbers row.insertCell(0); row.insertCell(1); for ( i = 0; i < model.scenes.length; i++ ) { cell = row.insertCell(i+2); cell.align='center'; cell.innerHTML = '' + (i+1) + ''; } for ( rw = 0; rw < model.layers.length; rw++ ) { row = itbl.insertRow(rw+2); cell = row.insertCell(0); // layer checkbox add_checkbox( cell, rw, 'layers_cb', handle_layer_click ); cell = row.insertCell(1); // layer name cell.align = 'left'; cell.innerHTML = model.layers[rw]; for ( cl = 0; cl < model.scenes.length; cl++ ) { cell = row.insertCell(cl+2); add_checkbox( cell, rw*model.scenes.length + cl, 'rc_cb', handle_click ); } } // end of loop over layers return itbl; } // end of createInnerTable() function createSceneList() { var span = document.createElement( 'span' ); var list = ''; for ( i = 0; i < model.scenes.length; i++ ) { list += '' + (i+1) + ' ' + nospace( model.scenes[i] )+ '
'; } span.innerHTML = list; return span; } function createTop() { var top = document.createElement( 'div' ); top.innerHTML = '
' + 'SketchUp Rubies icon' + ' ' + 'Layer/Scene Visibility Map
' return top; } function createUI() { var cell, // a cell being created/populated outer_table, // the light green surrounding table row, // a row being created/populated size // [width, height] for outer table // CLEAR ALL document.body.innerHTML = ''; if ( error() ) { document.body.innerHTML = '

Error Analyzing Model

' + '

Reported ' + model.vis + '

Try Window/Model Info/Statistics Purge Unused' + '
and then try Vismap again.' return; } // MAKE TABLE outer_table = document.createElement( 'table' ); outer_table.align='center'; outer_table.style.backgroundColor='#f0fff8'; outer_table.border=0; // size = compute_size(); // self: you can't do this until you've got a model to compute from size = [600, 450]; outer_table.style.height=size[1]+'px'; outer_table.style.width=size[0]+'px'; document.body.appendChild( outer_table ); // ROW 1, icon and title row = outer_table.insertRow(0); cell = row.insertCell(0); cell.colSpan = 2; cell.appendChild( createTop() ); // ROW 2, inner table and scene list row = outer_table.insertRow(1); cell = row.insertCell(0); // start with inner table // cell.width = '60%'; cell.align = 'center'; cell.appendChild( createInnerTable() ); cell = row.insertCell(1); // scene list // cell.width = '40%'; cell.appendChild( createSceneList() ); // ROW 3, buttons row = outer_table.insertRow(2); cell = row.insertCell(0); cell.colSpan = 2; cell.align='center'; var btn = createButton( 'from_model', 'Get Data from Model' ); cell.appendChild( btn ); btn.onclick = btn_refresh; cell.appendChild( createButtonSpacer() ); btn = createButton( 'to_model', 'Send Data to Model' ); cell.appendChild( btn ); btn.onclick = btn_download; } // end of createUI() function createUIrefs() { get_layer_cbs(); get_rc_cbs(); get_scene_cbs(); } // end of vismap.js