package hide.comp.cdb; import hxd.Key in K; class Cell extends Component { static var UID = 0; static var typeNames = [for( t in Type.getEnumConstructs(cdb.Data.ColumnType) ) t.substr(1).toLowerCase()]; var editor : Editor; var currentValue : Dynamic; public var line(default,null) : Line; public var column(default, null) : cdb.Data.Column; public var columnIndex(get, never) : Int; public var value(get, never) : Dynamic; public var table(get, never) : Table; public function new( root : Element, line : Line, column : cdb.Data.Column ) { super(null,root); this.line = line; this.editor = line.table.editor; this.column = column; @:privateAccess line.cells.push(this); root.addClass("t_" + typeNames[column.type.getIndex()]); if( column.kind == Script ) root.addClass("t_script"); refresh(); } function get_table() return line.table; function get_columnIndex() return table.sheet.columns.indexOf(column); inline function get_value() return currentValue; public function refresh() { currentValue = Reflect.field(line.obj, column.name); var html = valueHtml(column, value, line.table.sheet, line.obj); if( html == " " ) element.text(" ") else if( html.indexOf('<') < 0 && html.indexOf('&') < 0 ) element.text(html) else element.html(html); updateClasses(); } function updateClasses() { element.removeClass("edit"); element.removeClass("edit_long"); switch( column.type ) { case TBool: element.removeClass("true false").addClass( value==true ? "true" : "false" ); case TInt, TFloat: element.removeClass("zero"); if( value == 0 ) element.addClass("zero"); default: } } public function valueHtml( c : cdb.Data.Column, v : Dynamic, sheet : cdb.Sheet, obj : Dynamic ) : String { if( v == null ) { if( c.opt ) return " "; return '#NULL'; } return switch( c.type ) { case TInt, TFloat: switch( c.display ) { case Percent: (Math.round(v * 10000)/100) + "%"; default: v + ""; } case TId: v == "" ? '#MISSING' : (editor.base.getSheet(sheet.name).index.get(v).obj == obj ? v : '#DUP($v)'); case TString if( c.kind == Script ): v == "" ? " " : colorizeScript(v); case TString, TLayer(_): v == "" ? " " : StringTools.htmlEscape(v).split("\n").join("
"); case TRef(sname): if( v == "" ) '#MISSING'; else { var s = editor.base.getSheet(sname); var i = s.index.get(v); i == null ? '#REF($v)' : (i.ico == null ? "" : tileHtml(i.ico,true)+" ") + StringTools.htmlEscape(i.disp); } case TBool: v?"Y":"N"; case TEnum(values): values[v]; case TImage: '#DEPRECATED'; case TList: var a : Array = v; var ps = sheet.getSub(c); var out : Array = []; var size = 0; for( v in a ) { var vals = []; for( c in ps.columns ) switch( c.type ) { case TList, TProperties: continue; default: vals.push(valueHtml(c, Reflect.field(v, c.name), ps, v)); } var v = vals.length == 1 ? vals[0] : ""+vals; if( size > 200 ) { out.push("..."); break; } var vstr = v; if( v.indexOf("<") >= 0 ) { vstr = ~/]+>/g.replace(vstr, ""); vstr = ~//g.replace(vstr, "[I]"); vstr = ~/
"); case TCustom(name): var t = editor.base.getCustomType(name); var a : Array = v; var cas = t.cases[a[0]]; var str = cas.name; if( cas.args.length > 0 ) { str += "("; var out = []; var pos = 1; for( i in 1...a.length ) out.push(valueHtml(cas.args[i-1], a[i], sheet, this)); str += out.join(","); str += ")"; } str; case TFlags(values): var v : Int = v; var flags = []; for( i in 0...values.length ) if( v & (1 << i) != 0 ) flags.push(StringTools.htmlEscape(values[i])); flags.length == 0 ? String.fromCharCode(0x2205) : flags.join("|"); case TColor: '
'; case TFile: var path = ide.getPath(v); var url = "file://" + path; var ext = v.split(".").pop().toLowerCase(); var html = v == "" ? '#MISSING' : StringTools.htmlEscape(v); if( v != "" && !editor.quickExists(path) ) html = '' + html + ''; else if( ext == "png" || ext == "jpg" || ext == "jpeg" || ext == "gif" ) html = '$html
'; if( v != "" ) html += ' '; html; case TTilePos: return tileHtml(v); case TTileLayer: var v : cdb.Types.TileLayer = v; var path = ide.getPath(v.file); if( !editor.quickExists(path) ) '' + v.file + ''; else '#DATA'; case TDynamic: var str = Std.string(v).split("\n").join(" ").split("\t").join(""); if( str.length > 50 ) str = str.substr(0, 47) + "..."; str; } } static var KWDS = ["for","if","var","this","while","else","do","break","continue","switch","function","return","new","throw","try","catch","case","default"]; static var KWD_REG = new EReg([for( k in KWDS ) "(\\b"+k+"\\b)"].join("|"),"g"); function colorizeScript( ecode : String ) { var code = ecode; code = StringTools.htmlEscape(code); code = code.split("\n").join("
"); code = code.split("\t").join("    "); // typecheck var error = new ScriptEditor.ScriptChecker(editor.config, "cdb."+getDocumentName(), ["cdb."+table.sheet.name => line.obj]).check(ecode); if( error != null ) return ''+code+''; // strings code = ~/("[^"]*")/g.replace(code,'$1'); code = ~/('[^']*')/g.replace(code,'$1'); // keywords code = KWD_REG.map(code, function(r) return '${r.matched(0)}'); return code; } public function getGroup() : String { var gid : Null = Reflect.field(line.obj, "group"); if( gid == null ) return null; return table.sheet.props.separatorTitles[gid-1]; } public function getDocumentName() { var name = table.sheet.name; if( table.sheet.props.hasGroup ) { var g = getGroup(); if( g != null ) name += "[group="+g+"]"; } name += "."+column.name; return name; } function tileHtml( v : cdb.Types.TilePos, ?isInline ) { var path = ide.getPath(v.file); if( !editor.quickExists(path) ) { if( isInline ) return ""; return '' + v.file + ''; } var id = UID++; var width = v.size * (v.width == null?1:v.width); var height = v.size * (v.height == null?1:v.height); var max = width > height ? width : height; var zoom = max <= 32 ? 2 : 64 / max; var inl = isInline ? 'display:inline-block;' : ''; var url = "file://" + path; var html = '
'; html += ''; return html; } public function isTextInput() { return switch( column.type ) { case TString if( column.kind == Script ): return false; case TString, TInt, TFloat, TId, TCustom(_), TDynamic, TRef(_): return true; default: return false; } } public function focus() { editor.focus(); editor.cursor.set(table, this.columnIndex, this.line.index); } public function edit() { switch( column.type ) { case TString if( column.kind == Script ): open(); case TInt, TFloat, TString, TId, TCustom(_), TDynamic: var str = value == null ? "" : editor.base.valToString(column.type, value); var textSpan = element.wrapInner("").find("span"); var textHeight = textSpan.height(); var textWidth = textSpan.width(); var longText = textHeight > 25 || str.indexOf("\n") >= 0; element.empty(); element.addClass("edit"); var i = new Element(longText ? "