//**************************************************************** // icMap.js (_ic306.txt) // // Copyright (c) 2006 Clifford L. Collins // All rights are Reserved // // Collins Software // 7710 Janak Drive, Houston Texas // //---------------------------------------------------------------- // No distribution/publication/use of this code is permitted //**************************************************************** var clBlack = 0; var clTransparent = parseInt('0xf2f2f2'); var G; var SELECT_COLOR = '#FF8000'; var SELECT_WIDTH = '4'; var HANDLE_CENTER = -99; var HANDLE_ROTATE = -98; var HANDLE_RADIUS = -97; var RANGE_ID = -102; var Zgraphic = 150; var blinkLayer = null; var blinkSet = false; var blinkStatus = false; var blinkOn = true; //=================================================== // degree$ //=================================================== function degree$(angle) { var degree; var a,b; degree = (angle * 180.0) / Math.PI; return degree; } //======================================================================== // ic$userMap (Constructor) //======================================================================== function ic$userMap(name,view,height,width) { G = this; G.gid = 0; // Unique Graphic ID G.mode = 'select'; this.isSelect = false; this.isEdit = false; this.activeNode = null; G.modified = false; this.name = name; this.topFeature = null; this.freeGraphic = null; this.infoLink = ''; this.infoTag = ''; this.infoId = ''; this.modified = false; this.dbname = ''; // no Database Name Opened this.view = view; // mapping screen to real world this.height = height; this.width = width; this.cut = MAP$cut; this.copy = MAP$copy; this.selectAll = MAP$selectAll; this.paste = MAP$paste; this.drawSelected = MAP$drawSelected; this.startEdit = MAP$startEdit; this.undraw = MAP$undraw; this.isTable = false; this.clearLayer = MAP$clearLayer; this.curfea = null; this.promptSave = MAP$promptSave; this.hasAll = MAP$hasAll; this.hasSelected = MAP$hasSelected; this.previousRecord = MAP$previousRecord; this.nextRecord = MAP$nextRecord; this.firstRecord = MAP$firstRecord; this.lastRecord = MAP$lastRecord; this.autoRefresh = MAP$autoRefresh; this.autoToolbar = MAP$autoToolbar; this.autoCenter = MAP$autoCenter; this.toolbar = MAP$toolbar; this.refresh = MAP$refresh; this.centerSelected = MAP$centerSelected; this.previousFeature = MAP$previousFeature; this.nextFeature = MAP$nextFeature; this.addFeature = MAP$addFeature; this.newFeature = MAP$newFeature; this.clear = MAP$clear; this.deleteAll = MAP$deleteAll; this.del = MAP$del; this.setSize = MAP$setSize; this.setFixed = MAP$setFixed; this.selectFeature = MAP$selectFeature; this.htmlFeatures = MAP$htmlFeatures; this.findFeature = MAP$findFeature; this.findAddFeature = MAP$findAddFeature; this.activeFeature = MAP$activeFeature; this.listFeature = MAP$listFeature; this.setFeatureVisible = MAP$setFeatureVisible; this.setFeatureSnap = MAP$setFeatureSnap; this.featureExists = MAP$featureExists; this.clearSelected = MAP$clearSelected; this.deleteSelected = MAP$deleteSelected; this.deleteSelectedGraphics = MAP$deleteSelectedGraphics; this.renameTool = MAP$renameTool; // selected Feature this.deleteTool = MAP$deleteTool; // selected Feature this.addTool = MAP$addTool; // selected Feature this.renameFeature = MAP$renameFeature; // selected Feature this.deleteFeature = MAP$deleteFeature; // selected Feature this.eraseFeature = MAP$eraseFeature; // selected Feature this.moveFeatureUp = MAP$moveFeatureUp; // selected Feature this.moveFeatureDown = MAP$moveFeatureDown; // selected Feature this.eraseSelected = MAP$eraseSelected; // erase all selected features this.addGraphic = MAP$addGraphic; this.draw = MAP$draw; this.snap = MAP$snap; this.redraw = MAP$redraw; this.saveToFile = MAP$saveToFile; this.loadFromFile = MAP$loadFromFile; this.data = MAP$data; this.dataPaste = MAP$dataPaste; this.fdPaste = MAP$fdPaste; this.dataSelected = MAP$dataSelected; this.dataLayer = MAP$dataLayer; this.write = MAP$write; this.toObject = MAP$toObject; this.fromObject = MAP$fromObject; this.hotspot = MAP$hotspot; this.hotspot_csv = MAP$hotspot_csv; this.select = MAP$select; this.setZ = MAP$setZ; this.setBlink = MAP$setBlink; this.checkKeyEnter = MAP$checkKeyEnter; this.setNavigationButtons = MAP$setNavigationButtons; this.findById = MAP$findById; this.deleteById = MAP$deleteById; //------------------- Graphic Constructors ------------------ this.ic_Shape = ic$Shape; this.ic_Symbol = ic$Symbol; this.ic_Polygon = ic$Polygon; this.ic_Line = ic$Line; this.ic_Pline = ic$Pline; this.ic_Circle = ic$Circle; this.ic_Arc = ic$Arc; this.ic_Rectangle = ic$Rectangle; this.ic_Text = ic$Text; this.ic_Textbox = ic$Textbox; this.ic_Sketch = ic$Sketch; this.ic_Image = ic$Image; //-------------- Active Edit Feature (1 graphic element) -------- this.E = new ic$feature('activeEdit',this); this.E.isEdit = true; this.E.layer.style.zIndex = ZSelectPlane+1; //-------------- Delete Graphics (max 2000 units) -------- this.D = new ic$feature('DeletedElements',this); this.D.isDELETE = true; this.D.max = 2000; this.D.addDeleted = FEATURE$addDeleted; this.D.undelete = FEATURE$undelete; this.D.did = 0; this.undelete = MAP$undelete; //----------------- Selected Graphics List ----------------------- this.L = new ic$feature('selectList',this); this.L.isSelect = true; //----------------------------------------------------------- this.addFeature('Notes'); this.selectFeature('Notes'); this.editSetFeature = MAP$editSetFeature; this.forSelectedGraphics = MAP$forSelectedGraphics; this.edit = new ic$edit(this); blinkSet = false; blinkLayer = this.selectFeature('Notes'); } //======================================================================== // MAP$setZ //======================================================================== function MAP$setZ(layer,z) { var fea; fea = this.findAddFeature(layer); fea.layer.style.zIndex = parseInt(z); } //======================================================================== // MAP$setBlink //======================================================================== function MAP$setBlink(checked) { blinkOn = checked; } //======================================================================== // MAP$undelete //======================================================================== function MAP$undelete() { var xgra; xgra = this.D.botGraphicNode; if (!xgra) return; did = xgra.did; gra = this.D.undelete(did); while (gra) { fea = this.findFeature(gra.feature.name); if (! fea) fea = new ic$feature(gra.feature.name); fea.appendGraphic(gra); fea.drawGraphic(gra); gra = this.D.undelete(did); } this.selectFeature(xgra.feature.name); } //======================================================================== // MAP$startEdit //======================================================================== function MAP$startEdit() { this.isSelect = false; this.fromObject(this.activeNode); } //======================================================================== // MAP$checkKeyEnter //======================================================================== function MAP$checkKeyEnter(evt) { if (window.event.keyCode != 13) return; this.refresh(); } //======================================================================== // MAP$setFixed //======================================================================== function MAP$setFixed(checked) { this.forSelectedGraphics('gra.dc.fixed = ' + checked); } //======================================================================== // MAP$forSelectedGraphics //======================================================================== function MAP$forSelectedGraphics(cmd) { var gra; var gnode; if (this.L.graphicCount == 0) { gnode = this.activeNode; if (! gnode) return; gra = gnode.gra; eval(cmd); return; } gnode = this.L.topGraphicNode; while (gnode) { gra = gnode.gra; eval(cmd); gnode = gnode.next; } } //======================================================================== // MAP$undraw //======================================================================== function MAP$undraw(gra) { var obj; obj = getObject('$g$' + gra.gid); if (!obj) return; obj.innerHTML = ''; } //======================================================================== // MAP$eraseSelected //======================================================================== function MAP$eraseSelected() { var gnode; var nnode; var fea; this.D.did = this.D.did + 1; gnode = this.L.topGraphicNode; this.L.topGraphicNode = null; this.L.botGraphicNode = null; this.L.curnode = null; if (!gnode) { gnode = this.activeNode; if (!gnode) return; fea = gnode.gra.feature; this.undraw(gnode.gra); fea.deleteGraphic(gnode.gra); gnode = null; } while (gnode) { fea = gnode.gra.feature; this.undraw(gnode.gra); fea.deleteGraphic(gnode.gra); nnode = gnode.next; gnode.gra = null; gnode = nnode; } this.clearSelected() this.draw(); this.setNavigationButtons(); } //======================================================================== // MAP$promptSave //======================================================================== function MAP$promptSave() { if (!this.modified) return true; this.modified = false; fileSaveAs(); } //======================================================================== // MAP$copy //======================================================================== function MAP$copy(layer) { var data; data = this.dataLayer(layer); toClipboard(data); } //======================================================================== // MAP$cut //======================================================================== function MAP$cut(layer) { var data; data = this.dataLayer(layer); toClipboard(data); this.clearLayer(layer); } //======================================================================== // MAP$slelectAll //======================================================================== function MAP$selectAll() { var gnode; var fea; this.clearSelected(); fea = this.topFeature; while (fea) { gnode = fea.topGraphicNode; while (gnode) { this.L.addGraphic(gnode.gra); gnode = gnode.next; } fea = fea.next; } this.drawSelected(); return; } //======================================================================== // MAP$paste //======================================================================== function MAP$paste(layer) { var data; var fd; var test; data = clipboard(); this.dataPaste(layer,data); } //======================================================================== // MAP$dataPaste //======================================================================== function MAP$dataPaste(layer,data) { var data; var fd; var test; if (! data) return; if (data == '') return; test = data.substr(0,40).toLowerCase(); if (test.indexOf('*cg2') < 0) return; fd = new ic$memoryFile(data); this.fdPaste(fd,layer); } //======================================================================== // MAP$autoCenter //======================================================================== function MAP$autoCenter(gra) { var cx,cy,obj; setToolbarByName(gra.type); obj = getObject('autoCenter'); if (!obj) return; if (!obj.checked) return; cx = (gra.xmin + gra.xmax) / 2; cy = (gra.ymin + gra.ymax) / 2; goXY(cx,cy); draw(); } //======================================================================== // MAP$centerSelected //======================================================================== function MAP$centerSelected() { var cx,cy,obj; var gra; if (this.L.graphicCount > 0) gra = this.L.rng else { if (! this.activeNode) return; gra = this.activeNode.gra; } if (!gra) return; cx = (gra.xmin + gra.xmax) / 2; cy = (gra.ymin + gra.ymax) / 2; try { goXY(cx,cy); draw(); } catch (e) {return; } } //======================================================================== // MAP$hotspot //======================================================================== function MAP$hotspot(gra,text) { var lnk; var a; if (text == '') return text; if (this.isSelect) return text; if (this.isEdit) return text; try { lnk = gra.link; } catch (e) {lnk = '' } if (lnk == '') return text; a = ''; return (a + text + ''); } //======================================================================== // MAP$hotspot_csv //======================================================================== function MAP$hotspot_csv(gra,text) { var hint,href,target; var obj,z,a; try { if (text == '') return text; if (this.isSelect) return text; if (this.isEdit) return text; href = gra.href; //------------------- Set Z-Index --------- if (href == '') return text; href = editHref(href); a = ''; return (a + text + ''); } catch (e) { return text } } //======================================================================== // MAP$autoToolbar //======================================================================== function MAP$autoToolbar() { if (! autoToolbar.checked) return; this.toolbar(); } //======================================================================== // MAP$toolbar //======================================================================== function MAP$toolbar() { setEditTool(editMode); } //======================================================================== // MAP$autoRefresh //======================================================================== function MAP$autoRefresh() { if (! autoRefresh.checked) return; this.refresh(); } //======================================================================== // MAP$refresh //======================================================================== function MAP$refresh() { var gra; if (! this.activeNode) return; gra = this.activeNode.gra; editGetDC(gra.dc,gra.type); this.redraw(gra); } //======================================================================== // MAP$listFeature //======================================================================== function MAP$listFeature() { if (this.L.curnode) return this.L; else return this.curfea; } //======================================================================== // MAP$activeFeature //======================================================================== function MAP$activeFeature() { if (this.L.curnode) return this.L.curnode.gra.feature; else return this.curfea; } //======================================================================== // MAP$editSetFeature //======================================================================== function MAP$editSetFeature() { upTool.style.display = ''; // Feature Up/Down off downTool.style.display = ''; } //======================================================================== // MAP$findById //======================================================================== function MAP$findById(id) { var fea; var gra; fea = this.topFeature; while (fea) { gra = fea.findById(id); if (gra) return gra; fea = fea.next; } return null; } //======================================================================== // MAP$deleteById //======================================================================== function MAP$deleteById(layer,ID) { var fea; fea = this.findAddFeature(layer); if (fea.deleteById(ID)) return true; return false; } //======================================================================== // MAP$clearLayer //======================================================================== function MAP$clearLayer(layer) { var fea; fea = this.findAddFeature(layer); fea.clear(); } //======================================================================== // MAP$select //======================================================================== function MAP$select(x1,y1,x2,y2) { var dx,dy; var fea; var tx1,ty1; var rng; tol = 8; tx1 = this.view.screenToX(0); tx2 = this.view.screenToX(tol); stol = Math.abs(tx2 - tx1); if (this.L.graphicCount > 0) { this.toObject(); if (this.curfea) this.fromObject(this.curfea.curnode); else this.fromObject(null); } this.L.clear(); this.E.clear(); fea = this.topFeature; while (fea) { fea.select(x1,y1,x2,y2); fea = fea.next; } this.drawSelected(); } //======================================================================== // MAP$drawSelected //======================================================================== function MAP$drawSelected() { var fea; if (this.L.graphicCount == 1) // set 1 element as the active graphic { fea = this.L.topGraphicNode.gra.feature; fea.selectGraphic(this.L.topGraphicNode.gra); this.selectFeature(fea.name); this.L.clear(); } if (this.L.graphicCount == 0) { fea = this.activeFeature(); if (!fea) return; this.selectFeature(fea.name); return; // none selected; // reset to active; } this.L.rng = this.L.range(); this.draw(); this.E.drawGraphic(this.L.rng); } //======================================================================== // MAP$previousFeature //======================================================================== function MAP$previousFeature() { } //======================================================================== // MAP$nextFeature //======================================================================== function MAP$nextFeature() { } //======================================================================== // MAP$redraw //======================================================================== function MAP$redraw(gra) { var obj; obj = getObject('$g$' + gra.gid); // if (obj) obj.innerHTML = gra.vml(); // else gra.feature.drawGraphic(gra); gra.feature.drawGraphic(gra); if (!this.activeNode) return; if (gra != this.activeNode.gra) return; this.E.layer.innerHTML = ''; this.E.drawGraphic(gra); } //======================================================================== // MAP$clearSelected //======================================================================== function MAP$clearSelected() { try { this.E.clear(); this.L.clear(); } catch (e) { }; } //======================================================================== // ic$edit //======================================================================== function ic$edit(parent) { this.parent = parent; this.isDone = false; this.down = EDIT$down; this.move = EDIT$move; this.up = EDIT$up; this.moveEvent = EDIT$moveEvent; this.gra = null; } //======================================================================== // getPointRange //======================================================================== function getPointRange(gra,n) { var p; if (n >= 0) return null; if (n < -4) return null; p = null if (n == -1) { p = new Array(2); p[0] = gra.xmin; p[1] = gra.ymin; return p; } if (n == -2) { p = new Array(2); p[0] = gra.xmin; p[1] = gra.ymax; return p; } if (n == -3) { p = new Array(2); p[0] = gra.xmax; p[1] = gra.ymax; return p; } if (n == -4) { p = new Array(2); p[0] = gra.xmax; p[1] = gra.ymin; return p; } return null; } //======================================================================== // getPointLine //======================================================================== function getPointLine(gra,n) { var p; if (n < 0) return getPointRange(gra,n); if (n >= gra.x.length) return null; p = new Array(2); p[0] = gra.x[n]; p[1] = gra.y[n]; return p; } //======================================================================== // getPointArc //======================================================================== function getPointArc(gra,n) { var p; return null; if (n == HANDLE_CENTER) { p = new Array(2); p[0] = gra.cx; p[1] = gra.cy; return p; } switch (n) { case 1: // first p = new Array(2); p[0] = G.view.screenToX(this.ax1); p[1] = G.view.screenToX(this.ay1); break; case 2: // center p = new Array(2); p[0] = G.view.screenToX(this.ax2); p[1] = G.view.screenToX(this.ay2); break; case 3: // last p = new Array(2); p[0] = G.view.screenToX(this.ax3); p[1] = G.view.screenToX(this.ay3); break; } } //======================================================================== // getPointCircle //======================================================================== function getPointCircle(gra,n) { var p; if (n == HANDLE_CENTER) { p = new Array(2); p[0] = gra.cx; p[1] = gra.cy; return p; } if (n == HANDLE_RADIUS) { p = new Array(2); p[0] = gra.cx + gra.radius; p[1] = gra.cy; return p; } return null; } //======================================================================== // getPointSymbol //======================================================================== function getPointSymbol(gra,n) { var p; if (n < 0) return getPointRange(gra,n); if (n != 0) return null; p = new Array(2); p[0] = gra.x; p[1] = gra.y; return p; } //======================================================================== // getPointText //======================================================================== function getPointText(gra,n) { var p; if (n < 0) return getPointRange(gra,n); if (n != 0) return null; p = new Array(2); p[0] = gra.x; p[1] = gra.y; return p; } //======================================================================== // getPointTextbox //======================================================================== function getPointTextbox(gra,n) { var p; if (n < 0) return getPointRange(gra,n); if (n != 0) return null; p = new Array(2); p[0] = gra.x; p[1] = gra.y; return p; } //======================================================================== // getPointShape //======================================================================== function getPointShape(gra,n) { var p; if (n < 0) return getPointRange(gra,n); if (n != 0) return null; p = new Array(2); p[0] = gra.x; p[1] = gra.y; return p; } //======================================================================== // getPointImage //======================================================================== function getPointImage(gra,n) { var p; if (n < 0) return getPointRange(gra,n); if (n != 0) return null; p = new Array(2); p[0] = gra.x; p[1] = gra.y; return p; } //======================================================================== // EDIT$moveEvent //======================================================================== function EDIT$moveEvent(gid,n) { var gra; G.snapPoint = false; if (gid == RANGE_ID) return false; // ?? fea = this.parent.activeFeature(); if (! fea) return true; if (! fea.curnode) return true; if (fea.curnode.gra.gid != gid) return true; gra = fea.curnode.gra; p = null; if (gra.type == 'line') p = getPointLine(gra,n); if (gra.type == 'polygon') p = getPointLine(gra,n); if (gra.type == 'rectangle') p = getPointLine(gra,n); if (gra.type == 'arc') p = getPointArc(gra,n); if (gra.type == 'circle') p = getPointCircle(gra,n); if (gra.type == 'symbol') p = getPointSymbol(gra,n); if (gra.type == 'text') p = getPointText(gra,n); if (gra.type == 'textbox') p = getPointTextbox(gra,n); if (gra.type == 'shape') p = getPointShape(gra,n); if (gra.type == 'image') p = getPointImage(gra,n); if (!p) return; x = G.view.xToScreen(p[0]); y = G.view.yToScreen(p[1]); G.snapPoint = true; G.snapX = x; G.snapY = y; } //======================================================================== // EDIT$down //======================================================================== function EDIT$down(x,y,gid,n) { var fea; this.isDown = false; if (gid == RANGE_ID) { this.gra = this.parent.L.rng; } else { fea = this.parent.activeFeature(); if (! fea) return; if (! fea.curnode) return; if (fea.curnode.gra.gid != gid) return; this.gra = fea.curnode.gra; } this.parent.mode = 'edit'; this.x1 = x; this.y1 = y; this.x2 = x; this.y2 = y; this.x = x; // should be set by "findGra" this.y = y; this.n = n; this.edit = EDIT$fail; if (this.gra.type == 'line') this.edit = EDIT$line; if (this.gra.type == 'pline') this.edit = EDIT$line; if (this.gra.type == 'arc') this.edit = EDIT$arc; if (this.gra.type == 'circle') this.edit = EDIT$circle; if (this.gra.type == 'polygon') this.edit = EDIT$polygon; if (this.gra.type == 'rectangle') this.edit = EDIT$polygon; if (this.gra.type == 'symbol') this.edit = EDIT$symbol; if (this.gra.type == 'text') this.edit = EDIT$text; if (this.gra.type == 'textbox') this.edit = EDIT$textbox; if (this.gra.type == 'shape') this.edit = EDIT$shape; if (this.gra.type == 'image') this.edit = EDIT$image; if (this.gra.type == 'range') this.edit = EDIT$range; if (this.gra.type == 'arc') graToArc(this.gra,this); obj = getObject('$g$' + this.gra.gid); if (obj) obj.innerHTML = ''; this.isDown = true; this.move(x,y); } //======================================================================== // EDIT$fail //======================================================================== function EDIT$fail(gra) { } //======================================================================== // EDIT$move //======================================================================== function EDIT$move(x,y) { var dx,dy; var rx,ry; if (! this.isDown) return; rx = this.parent.view.screenToX(x-3); ry = this.parent.view.screenToY(y-3); this.x2 = x; this.y2 = y; this.edit(this.gra,rx,ry,this.n); this.parent.E.layer.innerHTML = ''; this.parent.E.drawGraphic(this.gra); } //======================================================================== // EDIT$up //======================================================================== function EDIT$up(x,y) { this.isDown = false; this.parent.mode = 'build'; if (! this.gra) return; obj = getObject('$g$' + this.gra.gid); if (this.gra.type == 'range') { this.parent.L.transform(this.gra); this.parent.draw(); this.parent.E.drawGraphic(this.parent.L.rng); } else if (obj) obj.innerHTML = this.gra.vml(); this.gra = null; } //======================================================================== // fit$line //======================================================================== function fit$line(gra) { var i; if (gra.x.length == 0) { gra.xmin = 0; gra.ymin = 0; gra.xmax = 0; gra.ymax = 0; return; } gra.xmin = gra.x[0]; gra.ymin = gra.y[0]; gra.xmax = gra.x[0]; gra.ymax = gra.y[0]; for (i = 1; i < gra.x.length; ++i) { gra.xmin = Math.min(gra.xmin,gra.x[i]); gra.ymin = Math.min(gra.ymin,gra.y[i]); gra.xmax = Math.max(gra.xmax,gra.x[i]); gra.ymax = Math.max(gra.ymax,gra.y[i]); } } //======================================================================== // EDIT$line //======================================================================== function EDIT$line(gra,x,y,n) { var cx,cy,dx,dy,i; if (n == HANDLE_CENTER) { cx = (gra.xmax + gra.xmin) / 2; cy = (gra.ymax + gra.ymin) / 2; dx = x - cx; dy = y - cy; for (i = 0; i < gra.x.length; ++i) { gra.x[i] = gra.x[i] + dx; gra.y[i] = gra.y[i] + dy; } gra.xmin = gra.xmin + dx; gra.ymin = gra.ymin + dy; gra.xmax = gra.xmax + dx; gra.ymax = gra.ymax + dy; return; } if (n < 0) return; gra.x[n] = x; gra.y[n] = y; fit$line(gra) G.setSize(gra); } //======================================================================== // EDIT$polygon //======================================================================== function EDIT$polygon(gra,x,y,n) { var i; var cx,cy; var dx,dy; if (n == HANDLE_CENTER) { cx = (gra.xmax + gra.xmin) / 2; cy = (gra.ymax + gra.ymin) / 2; dx = x - cx; dy = y - cy; for (i = 0; i < gra.x.length; ++i) { gra.x[i] = gra.x[i] + dx; gra.y[i] = gra.y[i] + dy; } gra.xmin = gra.xmin + dx; gra.ymin = gra.ymin + dy; gra.xmax = gra.xmax + dx; gra.ymax = gra.ymax + dy; return; } if (n < 0) return; if ((n == 0) || (n == (gra.x.length-1))) { i = gra.x.length-1; gra.x[0] = x; gra.y[0] = y; gra.x[i] = x; gra.y[i] = y; } else { gra.x[n] = x; gra.y[n] = y; } fit$line(gra); G.setSize(gra); } //======================================================================== // EDIT$rectangle //======================================================================== function EDIT$rectangle(gra,x,y,n) { var i; var cx,cy; var dx,dy; if (n == HANDLE_CENTER) { cx = (gra.xmax + gra.xmin) / 2; cy = (gra.ymax + gra.ymin) / 2; dx = x - cx; dy = y - cy; for (i = 0; i < gra.x.length; ++i) { gra.x[i] = gra.x[i] + dx; gra.y[i] = gra.y[i] + dy; } gra.xmin = gra.xmin + dx; gra.ymin = gra.ymin + dy; gra.xmax = gra.xmax + dx; gra.ymax = gra.ymax + dy; return; } if (n < 0) return; if ((n == 0) || (n == (gra.x.length-1))) { i = gra.x.length-1; gra.x[0] = x; gra.y[0] = y; gra.x[i] = x; gra.y[i] = y; } else { gra.x[n] = x; gra.y[n] = y; } fit$line(gra); G.setSize(gra); } //======================================================================== // EDIT$symbol //======================================================================== function EDIT$symbol(gra,x,y,n) { if (n == 0) { gra.x = x; gra.y = y; return; } if (n == HANDLE_ROTATE) { gra.angle = angle$(gra.x,gra.y,x,y); } } //======================================================================== // EDIT$text //======================================================================== function EDIT$text(gra,x,y,n) { if (n < 0) return; gra.x = x; gra.y = y; } //======================================================================== // EDIT$textbox //======================================================================== function EDIT$textbox(gra,x,y,n) { var dx,dy; var xmin,ymin,xmax,ymax; xmin = gra.xmin; ymin = gra.ymin; xmax = gra.xmax; ymax = gra.ymax; switch (n) { case -1: xmin = x; ymin = y; break; case -2: xmin = x; ymax = y; break; case -3: xmax = x; ymax = y; break; case -4: xmax = x; ymin = y; break; case HANDLE_CENTER: // (move) dx = (xmax - xmin) / 2; dy = (ymax - ymin) / 2; xmin = x - dx; ymin = y - dy; xmax = x + dx; ymax = y + dy; break; } gra.xmin = Math.min(xmin,xmax); gra.ymin = Math.min(ymin,ymax); gra.xmax = Math.max(xmin,xmax); gra.ymax = Math.max(ymin,ymax); G.setSize(gra); } //======================================================================== // EDIT$shape //======================================================================== function EDIT$shape(gra,x,y,n) { var dx,dy; var xmin,ymin,xmax,ymax; xmin = gra.xmin; ymin = gra.ymin; xmax = gra.xmax; ymax = gra.ymax; switch (n) { case -1: xmin = x; ymin = y; break; case -2: xmin = x; ymax = y; break; case -3: xmax = x; ymax = y; break; case -4: xmax = x; ymin = y; break; case HANDLE_CENTER: // (move) dx = (xmax - xmin) / 2; dy = (ymax - ymin) / 2; xmin = x - dx; ymin = y - dy; xmax = x + dx; ymax = y + dy; break; } gra.xmin = Math.min(xmin,xmax); gra.ymin = Math.min(ymin,ymax); gra.xmax = Math.max(xmin,xmax); gra.ymax = Math.max(ymin,ymax); G.setSize(gra); } //======================================================================== // EDIT$image //======================================================================== function EDIT$image(gra,x,y,n) { var dx,dy; var xmin,ymin,xmax,ymax; xmin = gra.xmin; ymin = gra.ymin; xmax = gra.xmax; ymax = gra.ymax; switch (n) { case -1: xmin = x; ymin = y; break; case -2: xmin = x; ymax = y; break; case -3: xmax = x; ymax = y; break; case -4: xmax = x; ymin = y; break; case HANDLE_CENTER: // (move) dx = (xmax - xmin) / 2; dy = (ymax - ymin) / 2; xmin = x - dx; ymin = y - dy; xmax = x + dx; ymax = y + dy; break; } gra.xmin = Math.min(xmin,xmax); gra.ymin = Math.min(ymin,ymax); gra.xmax = Math.max(xmin,xmax); gra.ymax = Math.max(ymin,ymax); G.setSize(gra); } //======================================================================== // fit$range //======================================================================== function fit$range(gra) { var xmin,ymin,xmax,ymax; xmin = gra.xmin; ymin = gra.xmin; xmax = gra.xmax; ymax = gra.xmax; gra.xmin = Math.min(xmin,xmax); gra.ymin = Math.min(ymin,ymax); gra.xmax = Math.max(xmin,xmax); gra.ymax = Math.max(ymin,ymax); G.setSize(gra); return; } //======================================================================== // EDIT$range //======================================================================== function EDIT$range(gra,x,y,n) { var dx,dy; var xmin,ymin,xmax,ymax; xmin = gra.xmin; ymin = gra.ymin; xmax = gra.xmax; ymax = gra.ymax; switch (n) { case -1: xmin = x; ymin = y; break; case -2: xmin = x; ymax = y; break; case -3: xmax = x; ymax = y; break; case -4: xmax = x; ymin = y; break; case HANDLE_CENTER: // (move) dx = (xmax - xmin) / 2; dy = (ymax - ymin) / 2; xmin = x - dx; ymin = y - dy; xmax = x + dx; ymax = y + dy; break; } gra.xmin = Math.min(xmin,xmax); gra.ymin = Math.min(ymin,ymax); gra.xmax = Math.max(xmin,xmax); gra.ymax = Math.max(ymin,ymax); G.setSize(gra); return; } //======================================================================== // EDIT$arc //======================================================================== function EDIT$arc(gra,x,y,n) { var sx,sy,arc; if (n == HANDLE_CENTER) { gra.cx = x; gra.cy = y; return; } if (n < 0) return; sx = G.view.xToScreen(x); sy = G.view.yToScreen(y); switch (n) { case 1: // first this.ax1 = sx; this.ay1 = sy; break; case 2: // center this.ax2 = sx; this.ay2 = sy; break; case 3: // last this.ax3 = sx; this.ay3 = sy; break; case HANDLE_CENTER: arc = makeArc$(this.ax1,this.ay1,this.ax2,this.ay2,this.ax3,this.ay3); dx = arc.cx - sx; dy = arc.cy - sy; this.ax1 = this.ax1 + dx; this.ay1 = this.ay1 + dy; this.ax2 = this.ax2 + dx; this.ay2 = this.ay2 + dy; this.ax3 = this.ax3 + dx; this.ay3 = this.ay3 + dy; break; } arc = makeArc$(this.ax1,this.ay1,this.ax2,this.ay2,this.ax3,this.ay3); if (arc.np = 0) return; gra.cx = G.view.screenToX(arc.cx); gra.cy = G.view.screenToY(arc.cy); gra.radius = Math.abs(G.view.screenToX(0) - G.view.screenToX(arc.radius)); gra.start = arc.start; // inverted Y axis gra.sweep = arc.sweep; fit$arc(gra); G.setSize(gra); return; } //======================================================================== // EDIT$circle //======================================================================== function EDIT$circle(gra,x,y,n) { switch (n) { case HANDLE_CENTER: // center gra.cx = x; gra.cy = y; break; case HANDLE_RADIUS: // radius gra.radius = length$(gra.cx,gra.cy,x,y); break; } fit$circle(gra); G.setSize(gra); } //======================================================================== // MAP$deleteSelected //======================================================================== function MAP$deleteSelected() { var gra; var gnode; var fea; this.D.did = this.D.did + 1; if (this.L.graphicCount > 0) { if (! confirm('delete ' + this.L.graphicCount + ' element' + S(this.L.graphicCount))) return; this.eraseSelected() return; } gnode = this.activeNode; if (! gnode) return; fea = gnode.gra.feature; this.undraw(gnode.gra); fea.deleteGraphic(gnode.gra); } //======================================================================== // MAP$deleteSelectedGraphics //======================================================================== function MAP$deleteSelectedGraphics() { var gnode; this.D.did = this.D.did + 1; gnode = this.L.topGraphicNode; while (gnode) { this.undraw(gnode.gra); gnode.gra.feature.deleteGraphic(gnode.gra); gnode = gnode.next; } this.L.clear(); } //======================================================================== // MAP$fromObject //======================================================================== function MAP$fromObject(node) { var gra; this.activeNode = node; if (! this.activeNode) { this.setNavigationButtons(); return; } fea = this.activeNode.gra.feature; gra = this.activeNode.gra; this.autoCenter(gra); try { activeName.innerText = fea.name + ' (' + gra.gid + ')'; } catch (e) {} editPutDC(gra.dc,gra.type); this.redraw(gra); this.setNavigationButtons(); } //======================================================================== // MAP$toObject //======================================================================== function MAP$toObject() { var gra; if (!this.activeNode) return; gra = this.activeNode.gra; try { editGetDC(gra.dc,gra.type); } catch (e) { alert('error toObject') }; } //======================================================================== // MAP$firstRecord //======================================================================== function MAP$firstRecord() { var fea; this.toObject(); fea = this.listFeature(); if (! fea) return; if (! fea.topGraphicNode) return; fea.selectNode(fea.topGraphicNode); } //======================================================================== // MAP$lastRecord //======================================================================== function MAP$lastRecord() { var fea; this.toObject(); fea = this.listFeature(); if (!fea) return; if (! fea.botGraphicNode) return; fea.selectNode(fea.botGraphicNode); } //======================================================================== // MAP$previousRecord //======================================================================== function MAP$previousRecord() { var fea; var list; fea = this.listFeature(); if (! fea) return; if (! fea.curnode) return; if (fea.curnode.prev) fea.selectNode(fea.curnode.prev); } //======================================================================== // MAP$nextRecord //======================================================================== function MAP$nextRecord() { var fea; fea = this.listFeature(); if (! fea) return; if (! fea.curnode) return; if (fea.curnode.next) fea.selectNode(fea.curnode.next); } //======================================================================== // MAP$write //======================================================================== function MAP$write(fd,has) { var names; var R; var fea; fd.write('*cg2;'); fd.write('*style,icMap;'); fd.writeCommentLine('!'); R = ',Range:(xmin:R8+ymin:R8+xmax:R8+ymax:R8)' + ',Fixed:(isSet:A5+PixelHeight:I4+PixelWidth:I4)'; if (has.line) { names = DCNames('line'); fd.write('*define:line, lin, ' + names + R + ',xy_list(32000):(x:R8+y:R8);'); } if (has.pline) { names = DCNames('pline'); fd.write('*define:pline, pln, ' + names + R + ',xy_list(32000):(x:R8+y:R8);'); } if (has.polygon) { names = DCNames('polygon'); fd.write('*define:polygon, pol, ' + names + R + ',xy_list(32000):(x:R8+y:R8);'); } if (has.rectangle) { names = DCNames('rectangle'); fd.write('*define:rectangle, rec, ' + names + R + ',xy_list(5):(x:R8+y:R8);'); } if (has.circle) { names = DCNames('circle'); fd.write('*define:circle, cir, ' + names + R + ',XY:(x:R8+y:R8),radius:R8;'); } if (has.arc) { names = DCNames('arc'); fd.write('*define:arc, arc, ' + names + R + ',XY:(x:R8+y:R8),radius:R8,start:R8,sweep:R8;'); } if (has.symbol) { names = DCNames('symbol'); fd.write('*define:symbol, sym, ' + names + R + ',XY:(x:R8+y:R8),angle:I4;'); } if (has.text) { names = DCNames('text'); fd.write('*define:text, txt, ' + names + R + ',XY:(X:r8:Y:R8),angle:I4;'); } if (has.textbox) { names = DCNames('textbox'); fd.write('*define:textbox, tbo, ' + names + R + ',XY:(X:R8+Y:R8);'); } if (has.shape) { names = DCNames('shape'); fd.write('*define:shape, shp, ' + names + R + ',style:i4,XY:(X:R8+Y:R8);'); } if (has.image) { names = DCNames('image'); fd.write('*define:image, img, ' + names + R + ',style:i4,XY:(X:R8+Y:R8);'); } } //======================================================================== // ic$has (constructor) //======================================================================== function ic$has() { this.line = false; this.pline = false; this.polyon = false; this.symbol = false; this.arc = false; this.circle = false; this.text = false; this.textbox = false; this.shape = false; this.image = false; this.lineCount = 0; this.plineCount = 0; this.polgonCount = 0; this.arcCount = 0; this.circleCount = 0; this.symbolCount = 0; this.textCount = 0; this.textboxCount = 0; this.shapeCount = 0; this.imageCount = 0; } //======================================================================== // MAP$hasAll //======================================================================== function MAP$hasAll() { has = new ic$has(); f = this.topFeature; while (f) { f.has(has); f = f.next; } return has; } //======================================================================== // MAP$hasSelected //======================================================================== function MAP$hasSelected() { has = new ic$has(); if (this.L.graphicCount > 0) this.L.has(has) else if (this.activeNode) this.activeNode.has(has); return has; } //======================================================================== // MAP$saveToFile //======================================================================== function MAP$saveToFile(filename) { var f,fd; var has; this.dbname = filename; fd = new ic$file(); if (! fd.create(filename)) return; has = this.hasAll(); this.write(fd,has); has = null; f = this.topFeature; while (f) { f.write(fd); f = f.next; } fd.write('!-------- End-of-File--------------;'); fd.close(); this.modified = false; } //======================================================================== // MAP$data //======================================================================== function MAP$data(fd,paste) { var f,fd; var xin; var has; var p; xin = false; if (MAP$data.arguments.length > 0) xin = true; //----------- read ------------ if (xin) { this.clearSelected(); p = new ic$parser(fd); while (p.nextSection()) { if (paste) fea = this.curfea; else fea = this.findCreateFeature(p.sectionName,p.findTable(p.sectionName)); gra = p.readGraphic(); while (gra) { gra.feature = fea; fea.appendGraphic(gra); // fea.drawGraphic(gra); if (paste) this.L.addGraphic(gra); gra = p.readGraphic(); } } this.clearSelected(); this.draw(); return; } //----------- write ------------- fd = new ic$memoryFile(); has = this.hasAll(); this.write(fd,has); f = this.topFeature; while (f) { f.write(fd); f = f.next; } fd.write('!-------- End-of-File--------------;'); return fd.close(); } //======================================================================== // MAP$fdPaste //======================================================================== function MAP$fdPaste(fd,layer) { var f,fd; var xin; var has; var p; var fea; fea = this.findAddFeature(layer); p = new ic$parser(fd); while (p.nextSection()) { gra = p.readGraphic(); while (gra) { gra.feature = fea; fea.appendGraphic(gra); gra = p.readGraphic(); } } this.draw(); } //======================================================================== // MAP$dataSelected //======================================================================== function MAP$dataSelected(data) { var f,fd; var xin; var fea,gra; var has; xin = false; if (MAP$dataSelected.arguments.length > 0) xin = true; //----------- Write ------------ if (xin) { // TODO return false; } //----------- Read ------------- fd = new ic$memoryFile(); has = this.hasSelected(); this.write(fd,has); has = null; if (this.L.graphicCount > 0) this.L.write(fd); // selected graphics else if (this.activeNode) // activeNode { gra = this.activeNode.gra; fea = gra.feature; fd.writeCommentLine('!'); fd.write('*section,' + fea.name + ';'); fd.write(fea.name + ', ' + gra.csv + ';'); gra.write(fd); } fd.write('!-------- End-of-File--------------;'); return fd.close(); } //======================================================================== // MAP$dataLayer //======================================================================== function MAP$dataLayer(layer) { var fd; var fea var has; fea = this.findFeature(layer); if (! fea) return ""; fd = new ic$memoryFile(); has = new ic$has(); fea.has(has); this.write(fd,has); has = null; fea.write(fd); fd.write('!-------- End-of-File--------------;'); return fd.close(); } //======================================================================== // MAP$loadFromFile //======================================================================== function MAP$loadFromFile(filename) { var f,fd; this.dbname = filename; fd = new ic$file(); if (! fd.openRead(filename)) return; this.data(fd,false); fd.close(); // this.centerSelected(); // this.draw; } //======================================================================== // MAP$draw //======================================================================== function MAP$draw() { var f; f = this.topFeature; while (f) { f.draw(); f = f.next; } // this.L.draw(); // selected // this.E.draw(); // active edit } //======================================================================== // MAP$snap //======================================================================== function MAP$snap(p,tol) { var f; var x1,x2,xtol; x1 = this.view.screenToX(0); x2 = this.view.screenToX(tol); xtol = Math.abs(x2 - x1); f = this.topFeature; while (f) { if (f.snap(p,xtol)) return true; f = f.next; } return false; } //======================================================================== // MAP$addGraphic //======================================================================== function MAP$addGraphic(layer,gra,isDraw) { var fea; this.modified = true; G.activeNode = null; fea = this.findAddFeature(layer); fea.addGraphic(gra,isDraw); // this.setNavigationButtons(); // this.curfea.draw(); } //======================================================================== // MAP$newFeature //======================================================================== function MAP$newFeature() { var name; name = ''; while (true) { name = window.prompt('New Feature name',name); if (! name) return; name = editName(name); if (! this.featureExists(name)) break; alert('feature /' + name + '/ already exists'); } this.addFeature(name); this.selectFeature(name); } //======================================================================== // MAP$moveFeatureUp (selected) //======================================================================== function MAP$moveFeatureUp() { var name; var f,prev,parent; prev = null; parent = null; f = this.topFeature; while (f) { if (f == this.curfea) { if (! prev) return; // already at top; if (parent) { parent.next = f; prev.next = f.next; f.next = prev; break; } else { this.topFeature = f; prev.next = f.next; f.next = prev; break; } } parent = prev; prev = f; f = f.next; } if (!f) return; this.selectFeature(f.name); } //======================================================================== // MAP$moveFeatureDown (selected) //======================================================================== function MAP$moveFeatureDown() { var name; var f,prev,n1,n2; if (! this.curfea) return; if (! this.curfea.next) return; // already at bottom; prev = null; f = this.topFeature; while (f) { if (f == this.curfea) { if (prev) { prev.next = f.next; } else { this.topFeature = f.next; } n1 = f.next; n2 = f.next.next; n1.next = f; f.next = n2; break; } prev = f; f = f.next; } if (!f) return; this.selectFeature(f.name); } //======================================================================== // MAP$del //======================================================================== function MAP$del(name) { var name; var f,prev,next; f = this.findFeature(name); if (!f) return; prev = null; next = null; this.curfea = null; f = this.topFeature; while (f != null) { next = f.next; if (name.toLowerCase() == f.name.toLowerCase()) if (prev == null) { this.topFeature = f.next; f.clear; f = null; break; } else { prev.next = f.next; f.clear; f = null; break; } prev = f; f = f.next; } if (prev) this.curfea = prev; if (next) this.curfea = next; } //======================================================================== // specialName //======================================================================== function specialName(name) { nam = name.toLowerCase(); if (nam == '[selected]') { alert('operation not allowed on feature /' + name + '/'); return true; } return false; } //======================================================================== // MAP$deleteFeature (selected) //======================================================================== function MAP$deleteFeature() { var name; if (! this.curfea) return; name = this.curfea.name; if (specialName(name)) return; if (! window.confirm('Delete Feature /' + name + '/')) return; this.del(name); name = ''; if (this.curfea) name = this.curfea.name; this.selectFeature(name); } //======================================================================== // MAP$addTool (selected) //======================================================================== function MAP$addTool() { if (icFeatureEdit.checked) this.newFeature(); } //======================================================================== // MAP$renameTool (selected) //======================================================================== function MAP$renameTool() { if (icFeatureEdit.checked) this.renameFeature(); } //======================================================================== // MAP$deleteTool (selected) //======================================================================== function MAP$deleteTool() { if (icFeatureEdit.checked) this.deleteFeature(); } //======================================================================== // MAP$eraseFeature (selected) //======================================================================== function MAP$eraseFeature() { var name; var cnt; if (! this.curfea) return; name = this.curfea.name; cnt = this.curfea.graphicCount; if (! window.confirm('delete ' + cnt + ' graphic element' + S(cnt) + ' from /' + name + '/')) return; this.clearSelected(); this.curfea.clear(); this.curfea.draw(); } //======================================================================== // MAP$renameFeature (selected) //======================================================================== function MAP$renameFeature() { var name; if (! this.curfea) return; name = this.curfea.name; if (specialName(name)) return; while (true) { name = window.prompt('Rename Feature',name); if (!name) return; name = editName(name); if ((name != '') && (! this.findFeature(name,true))) break; alert('duplicate feature /' + name + '/'); } this.curfea.name = name; this.selectFeature(name); } //======================================================================== // MAP$setFeatureVisible //======================================================================== function MAP$setFeatureVisible(checked) { var name; var f f = this.curfea; if (!f) return; f.visible = checked; f.draw(); if (!this.activeNode) return; if (f != this.activeNode.gra.feature) return; this.E.innerHTML = ''; if (!checked) return; this.E.drawGraphic(this.activeNode.gra); } //======================================================================== // MAP$setFeatureSnap //======================================================================== function MAP$setFeatureSnap(checked) { if (this.curfea) this.curfea.isSnap = checked; } //======================================================================== // MAP$clear //======================================================================== function MAP$clear() { var f,n; f = this.topFeature; this.topFeature = null; this.curfea = null; while (f) { n = f.next; f.clear; f = null; f = n; } f = this.freeGraphic this.freeGraphic = null; while (f) { n = f.next; f.clear; f = null; f = n; } } //======================================================================== // MAP$deleteAll //======================================================================== function MAP$deleteAll() { var f,n; this.L.clear(); this.E.clear(); this.D.clear(); f = this.topFeature; while (f) { n = f.next; f.clear(); f = n; } f = this.freeGraphic this.freeGraphic = null; while (f) { n = f.next; f.clear(); f = null; f = n; } } //======================================================================== // MAP$findAddFeature //======================================================================== function MAP$findAddFeature(name) { var fea; fea = this.findFeature(name); if (fea) return fea; fea = this.addFeature(name); return fea; } //======================================================================== // MAP$findFeature //======================================================================== function MAP$findFeature(name,excludeActive) { var f; f = this.topFeature; exclude = false; if (excludeActive != undefined) exclude = true; while (f != null) { if ((! exclude) || (f != this.curfea)) { if (name.toLowerCase() == f.name.toLowerCase()) return f; } f = f.next; } return null; } //======================================================================== // MAP$featureExists //======================================================================== function MAP$featureExists(name) { if (this.findFeature(name)) return true; return false; } //======================================================================== // MAP$addFeature //======================================================================== function MAP$addFeature(name) { var fea; this.curfea = new ic$feature(name,this); if (this.topFeature == null) { this.topFeature = this.curfea; } else { bot = this.topFeature; while (bot.next != null) bot = bot.next; bot.next = this.curfea; } this.selectFeature(name); return this.curfea; } //======================================================================== // MAP$selectFeature //======================================================================== function MAP$selectFeature(name) { this.toObject(); this.curfea = this.findFeature(name); try { icFeatureList.innerHTML = this.htmlFeatures(name); } catch (e) {}; if (! this.curfea) return; this.curfea.selectNode(this.curfea.curnode); return (this.curfea); } //======================================================================== // MAP$htmlFeatures //======================================================================== function MAP$htmlFeatures(name) { var text; var f; var rows, a; rows = 0; f = this.topFeature; while (f != null) { rows = rows + 1; f = f.next; } if (rows > 6) rows = 6; text = ''; return text; } //======================================================================== // ic$feature (Constructor) //======================================================================== function ic$feature(name,parent) { this.name = name; this.visible = true; this.isSnap = true; this.parent = parent; this.isEdit = false; this.isSelect = false; this.dcTable = null; this.next = null; this.graphicCount = 0; this.graphicID = 0; // Unique ID (do not reuse) this.topGraphicNode = null; this.botGraphicNode = null; this.selectGraphic = FEATURE$selectGraphic; this.selectNode = FEATURE$selectNode; this.draw = FEATURE$draw; this.drawGraphic = FEATURE$drawGraphic; this.snap = FEATURE$snap; this.write = FEATURE$write; this.select = FEATURE$select; this.deleteColumn = FEATURE$deleteColumn; this.has = FEATURE$has; this.range = FEATURE$range; this.transform = FEATURE$transform; this.findById = FEATURE$findById; this.deleteById = FEATURE$deleteById; this.addGraphic = FEATURE$addGraphic; this.appendGraphic = FEATURE$appendGraphic; this.deleteGraphic = FEATURE$deleteGraphic; this.deleteGraphicNode = FEATURE$deleteGraphicNode; this.clear = FEATURE$clear; this.next = null; this.layer = document.createElement('
'); this.layer.style.zIndex = Zgraphic; this.layer.style.borderWidth = 0; this.layer.style.border = ""; this.layer.style.position = "absolute"; this.layer.style.posTop = 0; this.layer.style.posLeft = 0; this.layer.style.pixelHeight = this.parent.height; this.layer.style.pixelWidth = this.parent.width; this.layer.oncontextmenu = null; document.body.appendChild(this.layer); } //======================================================================== // FEATURE$has //======================================================================== function FEATURE$has(has) { gnode = this.topGraphicNode; while (gnode) { gnode.has(has); gnode = gnode.next; } } //======================================================================== // FEATURE$undelete //======================================================================== function FEATURE$undelete(did) { var gra; gra = this.botGraphicNode; if (!gra) return null; if (gra.did != did) return null; this.graphicCount = this.graphicCount-1; if (!gra.prev) { this.topGraphicNode = null; this.botGraphicNode = null; gra.prev = null; gra.next = null; return gra; } this.botGraphicNode = gra.prev; gra.prev = null; gra.next = null; return gra; } //======================================================================== // FEATURE$addDeleted //======================================================================== function FEATURE$addDeleted(gra) { var xgra; gra.did = this.did; if (this.graphicCount >= this.max) { xgra = this.topGraphicNode; this.topGraphicNode = xgra.next; this.graphicCount = this.graphicCount-1; xgra = null; } this.graphicCount = this.graphicCount+1; if (this.topGraphicNode) { this.botGraphicNode.next = gra; gra.next = null; gra.prev = this.botGraphicNode; this.botGraphicNode = gra; return; } else { this.topGraphicNode = gra; this.botGraphicNode = gra; gra.next = null; gra.prev = null; } } //======================================================================== // FEATURE$selectNode //======================================================================== function FEATURE$selectNode(node) { G.toObject(); // update active node; this.curnode = node; G.fromObject(this.curnode); } //======================================================================== // FEATURE$findById //======================================================================== function FEATURE$findById(id) { var gnode; gnode = this.topGraphicNode; while (gnode) { if (gnode.gra.id == id) return gnode.gra; gnode = gnode.next; } return null; } //======================================================================== // FEATURE$deleteById //======================================================================== function FEATURE$deleteById(id) { var gnode; var pnode; var obj; gnode = this.topGraphicNode; pnode = null; while (gnode) { if (gnode.gra.id == id) { if (pnode == null) { this.topGraphicNode = gnode.next} else { pnode.next = gnode.next; } if (this.botGraphicNode == gnode) this.botGraphicNode = pnode; this.graphicCount = this.graphicCount - 1; obj = getObject('$g$' + gnode.gra.gid); if (obj) obj.innerHTML = ''; gnode.gra= null; gnode = null; return true; } pnode = gnode; gnode = gnode.next; } return false; } //======================================================================== // FEATURE$selectGraphic //======================================================================== function FEATURE$selectGraphic(gra) { var gnode; gnode = this.topGraphicNode; while (gnode) { if (gnode.gra == gra) { this.selectNode(gnode); // change active node; return; } gnode = gnode.next; } this.curnode = this.topGraphicNode; this.selectNode(this.topGraphicNode); } //======================================================================== // FEATURE$transform //======================================================================== function FEATURE$transform(gra) { var dx,dy; var w1,h1; var w2,h2; var xscl,yscl; var cx1,cy1,cx2,cy2; if (!gra) return; if (gra.type != 'range') return; if (!this.topGraphicNode) return; w1 = gra.xmax_old - gra.xmin_old; h1 = gra.ymax_old - gra.ymin_old; if (w1 < 0.0001) return; if (h1 < 0.0002) return; w2 = gra.xmax - gra.xmin; h2 = gra.ymax - gra.ymin; xscl = w2 / w1; yscl = h2 / h1; cx1 = (gra.xmax_old + gra.xmin_old) / 2; cy1 = (gra.ymax_old + gra.ymin_old) / 2; cx2 = (gra.xmax + gra.xmin) / 2; cy2 = (gra.ymax + gra.ymin) / 2; gnode = this.topGraphicNode; while (gnode) { gra$move(gnode.gra,-cx1,-cy1); gra$scale(gnode.gra,xscl,yscl); gra$move(gnode.gra,cx2,cy2); gra$fit(gnode.gra); gnode = gnode.next; } gra.xmin_old = gra.xmin; gra.ymin_old = gra.ymin; gra.xmax_old = gra.xmax; gra.ymax_old = gra.ymax; } //======================================================================== // gra$fit //======================================================================== function gra$fit(gra) { var i; if ((gra.type == 'line') || (gra.type == 'range') || (gra.type == 'polygon') || (gra.type == 'rectangle')) { fit$line(gra); return; } if (gra.type == 'symbol') fit$symobl(gra); if (gra.type == 'text') fit$text(gra); if (gra.type == 'textbox') fit$textbox(gra); if (gra.type == 'shape') fit$shape(gra); if (gra.type == 'circle') fit$circle(gra); if (gra.type == 'arc') fit$arc(gra); } //======================================================================== // gra$move //======================================================================== function gra$move(gra,xorg,yorg) { var i; if ((gra.type == 'line') || (gra.type == 'range') || (gra.type == 'polygon') || (gra.type == 'rectangle')) { for (i = 0; i < gra.x.length; ++i) { gra.x[i] = gra.x[i] + xorg; gra.y[i] = gra.y[i] + yorg; } return; } if ((gra.type == 'symbol') || (gra.type == 'text') || (gra.type == 'textbox') || (gra.type == 'shape')) { gra.x = gra.x + xorg; gra.y = gra.y + yorg; return; } if ((gra.type == 'circle') || (gra.type == 'arc')) { gra.cx = gra.cx + xorg; gra.cy = gra.cy + yorg; return; } } //======================================================================== // gra$scale //======================================================================== function gra$scale(gra,xscl,yscl) { var i; if ((Math.abs(xscl-1.0) < 0.0000001) && (Math.abs(yscl-1.0) < 0.0000001)) return; if ((gra.type == 'line') || (gra.type == 'range') || (gra.type == 'polygon') || (gra.type == 'rectangle')) { for (i = 0; i < gra.x.length; ++i) { gra.x[i] = gra.x[i] * xscl; gra.y[i] = gra.y[i] * yscl; } return; } if ((gra.type == 'symbol') || (gra.type == 'text') || (gra.type == 'textbox') || (gra.type == 'shape')) { gra.x = gra.x * xscl; gra.y = gra.y * yscl; return; } if ((gra.type == 'circle') || (gra.type == 'arc')) { gra.radius = gra.radius * xscl; return; } } //======================================================================== // FEATURE$range //======================================================================== function FEATURE$range() { var gnode; var gra; var xmin,ymin,xmax,ymax; xmin = 1.0e126; ymin = 1.0e126; xmax = -1.0e126; ymax = -1.0e126; gnode = this.topGraphicNode; if (!gnode) return; while (gnode) { xmin = Math.min(xmin,gnode.gra.xmin); ymin = Math.min(ymin,gnode.gra.ymin); xmax = Math.max(xmax,gnode.gra.xmax); ymax = Math.max(ymax,gnode.gra.ymax); gnode = gnode.next; } gra = new ic$Range(xmin,ymin,xmax,ymax); gra.gid = RANGE_ID; gra.feature = this; return gra; } //======================================================================== // RangeTouchesRange (A touches B) //======================================================================== function RangeTouchesRange(axmin,aymin,axmax,aymax,bxmin,bymin,bxmax,bymax) { if ((bxmin > axmax) && (bymin > aymax) && (axmin > bxmax) && (aymin > bymax)) return false; return true; } //======================================================================== // RangeInsideRange (A inside B) //======================================================================== function RangeInsideRange(axmin,aymin,axmax,aymax,bxmin,bymin,bxmax,bymax) { if (bxmin > axmax) return false; if (bymin > aymax) return false; if (axmin > bxmax) return false; if (aymin > bymax) return false; return true; } //======================================================================== // FEATURE$select //======================================================================== function FEATURE$select(x1,y1,x2,y2) { var gnode; gnode = this.topGraphicNode; while (gnode) { if (RangeInsideRange(gnode.gra.xmin,gnode.gra.ymin, gnode.gra.xmax,gnode.gra.ymax, x1,y1,x2,y2)) G.L.addGraphic(gnode.gra); gnode = gnode.next; } } //======================================================================== // ic$graphicNode (constructor) //======================================================================== function ic$graphicNode() { this.gra = null; this.next = null; this.prev = null; this.has = GRAPHICNODE$has; } //======================================================================== // GRAPHICNODE$has //======================================================================== function GRAPHICNODE$has(has) { switch (this.gra.type) { case 'line': has.line = true; has.lineCount = has.lineCount + 1; break; case 'pline': has.line = true; has.plineCount = has.plineCount + 1; break; case 'polygon': has.polygon = true; has.polygonCount = has.polygonCount + 1; break; case 'rectangle': has.rectangle = true; has.rectangleCount = has.rectangleCount + 1; break; case 'arc': has.arc = true; has.arcCount = has.arcCount + 1; break; case 'circle': has.circle = true; has.circleCount = has.circleCount + 1; break; case 'symbol': has.symbol = true; has.symbolCount = has.symbolCount + 1; break; case 'text': has.text = true; has.textCount = has.textCount + 1; break; case 'textbox': has.textbox = true; has.textboxCount = has.textboxCount + 1; break; case 'shape': has.shape = true; has.shapeCount = has.shapeCount + 1; break; case 'image': has.image = true; has.imageCount = has.imageCount + 1; break; } } //======================================================================== // FEATURE$write //======================================================================== function FEATURE$write(fd) { var text; fd.writeCommentLine('!'); fd.write('*section,' + this.name + ';'); gnode = this.topGraphicNode while (gnode) { gnode.gra.write(fd); gnode = gnode.next; } } //======================================================================== // FEATURE$draw //======================================================================== function FEATURE$draw() { var text; this.layer.innerHTML = ''; if (! this.visible) return; gnode = this.topGraphicNode; while (gnode) { this.drawGraphic(gnode.gra); gnode = gnode.next; } } //======================================================================== // FEATURE$deleteColumn //======================================================================== function FEATURE$deleteColumn(col) { var csv; var text; csv = new ic$csv(); gnode = this.topGraphicNode; while (gnode) { csv.data = gnode.gra.csv; csv.deleteColumn(col); gnode.gra.csv = csv.data; gnode = gnode.next; } csv = null; } //======================================================================== // FEATURE$snap //======================================================================== function FEATURE$snap(p,tol) { var text; if (! this.visible) return false; if (! this.isSnap) return false; gnode = this.topGraphicNode; while (gnode) { if (gnode.gra.snap(p,tol)) return true; gnode = gnode.next; } return false; } //======================================================================== // SymbolLibrary //======================================================================== function SymbolLibrary() { return "