public __DataGridView() { //Console.WriteLine("enter DataGridView .ctor"); Console.WriteLine("event: enter new DataGridView()"); this.AutoGenerateColumns = true; // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201404/20140412 // tested by? // X:\jsc.svn\examples\javascript\forms\test\TestWebBrowserOneWayDataBinding\TestWebBrowserOneWayDataBinding\ApplicationControl.Designer.cs // this.dataGridView1.RowTemplate.Height = 24; this.RowTemplate = new DataGridViewRow(); this.InternalElement = new IHTMLDiv { // do this ahead of time // when can we have a special type for a classname string? className = typeof(DataGridView).Name }; // can jsc help us here and via [HTMLAttribute] redirect the data to html attribute? this.AllowUserToResizeColumnsAttribute = new XAttribute("AllowUserToResizeColumns", "").AttachTo(this.InternalElement); this.RowHeadersVisibleAttribute = new XAttribute("RowHeadersVisible", "true").AttachTo(this.InternalElement); // add the rule to current document. // what happens if we do popup? // wha about scoped style? this.css = this.InternalElement.css; // do we need this? this.InternalElement.style.overflow = DOM.IStyle.OverflowEnum.hidden; this.InternalColumns = new __DataGridViewColumnCollection(); this.Columns = (DataGridViewColumnCollection)(object)this.InternalColumns; #region InternalRows this.InternalRows = new __DataGridViewRowCollection { InternalContext = this }; this.Rows = (DataGridViewRowCollection)(object)this.InternalRows; this.InternalRows.InternalItems.Added += (s, i) => { s.InternalContext = this; }; #endregion #region SelectedCells this.InternalSelectedCells = new __DataGridViewSelectedCellCollection(); this.SelectedCells = (DataGridViewSelectedCellCollection)(object)this.InternalSelectedCells; this.InternalSelectedCells.InternalItems.ListChanged += (_s, _e) => { if (_e.ListChangedType == ListChangedType.ItemAdded) { var item = this.InternalSelectedCells.InternalItems[_e.NewIndex]; // when is this null? //if (this.DefaultCellStyle == null) //{ // item.InternalContentContainer.style.backgroundColor = JSColor.System.Highlight; //} //else //{ var SelectionBackColor = this.DefaultCellStyle.SelectionBackColor; var SelectionForeColor = this.DefaultCellStyle.SelectionForeColor; item.InternalTableColumn_div.style.backgroundColor = SelectionBackColor.ToString(); //} //item.InternalContentContainer.style.color = JSColor.System.HighlightText; // tested by // X:\jsc.svn\core\ScriptCoreLib.Windows.Forms\ScriptCoreLib.Windows.Forms\JavaScript\BCLImplementation\System\Windows\Forms\DataGridView.cs item.InternalTableColumn_div.style.color = SelectionForeColor.ToString(); } if (SelectionChanged != null) SelectionChanged(this, new EventArgs()); }; #endregion this.MultiSelect = true; this.InternalSetDefaultFont(); this.InternalScrollContainerElement = new IHTMLDiv { // pstyle className = "InternalScrollContainerElement" }.AttachTo(this.InternalElement); //this.InternalScrollContainerElement.style.backgroundColor = JSColor.Gray; this.BackgroundColor = global::System.Drawing.SystemColors.AppWorkspace; this.InternalScrollContainerElement.style.overflow = DOM.IStyle.OverflowEnum.auto; // tested by // X:\jsc.svn\examples\javascript\css\CSSPrintMediaExperiment\CSSPrintMediaExperiment\Application.cs // for printer we do not want to see the scollbar // if we change the document we will loose the style? // this wont work //IStyleSheet.Default // [CSSMediaTypes.print] // [this.InternalScrollContainerElement].style.overflow = // IStyle.OverflowEnum.hidden; new IStyle(this.InternalScrollContainerElement) { position = DOM.IStyle.PositionEnum.absolute, left = "0px", top = "0px", right = "0px", bottom = "0px" }; var __ContentTableContainer = new IHTMLDiv { className = "__ContentTableContainer" }.AttachTo(InternalScrollContainerElement); // 116ms css.style { selectorText = table.__ContentTable[style-id="2"] > tbody > tr > td } this.__ContentTable = new IHTMLTable { className = __ContentTable_className, cellPadding = 0, cellSpacing = 0 }.AttachTo(__ContentTableContainer); // X:\jsc.svn\examples\javascript\css\CSSOdd\CSSOdd\Application.cs //this.__ContentTable_css = css.descendants[className]; this.__ContentTable_css = css[this.__ContentTable]; //css.adjacentSibling[] //css.siblings //92ms css.style { selectorText = div.DataGridView[style-id="2"] table.__DataGridViewContentTable > tbody > tr > td } view-source:34816 // view-source:34816 //92ms css.style { selectorText = table.__DataGridViewColumnsTable[style-id="3"] > tbody > tr > td } // the hacky way: //this.__ContentTable_css = css[" table." + this.__ContentTable.className]; this.__ContentTable_css_td = this.__ContentTable_css + IHTMLElement.HTMLElementEnum.tbody + IHTMLElement.HTMLElementEnum.tr + IHTMLElement.HTMLElementEnum.td; this.__ContentTable_css_alt_td = this.__ContentTable_css [IHTMLElement.HTMLElementEnum.tbody][IHTMLElement.HTMLElementEnum.tr].even[IHTMLElement.HTMLElementEnum.td]; this.__ContentTable_css_odd_td = this.__ContentTable_css [IHTMLElement.HTMLElementEnum.tbody][IHTMLElement.HTMLElementEnum.tr].odd[IHTMLElement.HTMLElementEnum.td]; __ContentTable.style.paddingTop = "22px"; var __ColumnsTableContainer = new IHTMLDiv { className = "__ColumnsTableContainer" }.AttachTo(InternalScrollContainerElement); // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201312/20131213-forms-css this.__ColumnsTable = new IHTMLTable { className = __ColumnsTable_className, cellPadding = 0, cellSpacing = 0 }.AttachTo( __ColumnsTableContainer); this.__ColumnsTable_css = css[this.__ColumnsTable]; this.__ColumnsTable_css_td = this.__ColumnsTable_css + IHTMLElement.HTMLElementEnum.tbody + IHTMLElement.HTMLElementEnum.tr + IHTMLElement.HTMLElementEnum.td; IHTMLTableRow __ColumnsTableRow = null; //__ColumnsTableContainer.style.SetLocation(0, 0); __ColumnsTableContainer.style.position = IStyle.PositionEnum.absolute; __ColumnsTableContainer.style.left = "0px"; __ColumnsTableRow = __ColumnsTable.AddBody().AddRow(); __ColumnsTableRow.style.height = "22px"; var __RowsTableContainer = new IHTMLDiv { className = "__RowsTableContainer" }.AttachTo(InternalScrollContainerElement); //__RowsTableContainer.style.SetLocation(0, 0); __RowsTableContainer.style.position = IStyle.PositionEnum.absolute; __RowsTableContainer.style.top = "0px"; this.__RowsTable = new IHTMLTable { className = __RowsTable_className, cellPadding = 0, cellSpacing = 0 }.AttachTo(__RowsTableContainer); // should we make the monkier a bit lazier? this.__RowsTable_css = css[this.__RowsTable]; // 139ms { __RowsTable_css = { selectorText = div.DataGridView[style-id="2"] > div:nth-of-type(1) > div:nth-of-type(3) > table:nth-of-type(1), selectorElement = } } //Console.WriteLine(new { this.__RowsTable_css }); this.__RowsTable_css_td = this.__RowsTable_css + IHTMLElement.HTMLElementEnum.tbody + IHTMLElement.HTMLElementEnum.tr + IHTMLElement.HTMLElementEnum.td; this.__RowsTable_css_td.style.backgroundColor = "cyan"; __RowsTable.style.paddingTop = "22px"; this.__RowsTableBody = __RowsTable.AddBody(); Console.WriteLine("new DataGridView() before Corner"); #region Corner this.__Corner = new IHTMLDiv().AttachTo(InternalScrollContainerElement); __Corner.style.position = IStyle.PositionEnum.absolute; //__Corner.style.SetLocation(0, 0); __Corner.style.height = "22px"; #endregion // too slow for onscroll //var css_fixed_left = // __RowsTableContainer.css // | __Corner.css; //var css_fixed_top = // __ColumnsTableContainer.css // | __Corner.css; #region onscroll Action onscroll = delegate { // perhaps we should only use .css for static styles? // how much faster are we if we skip .css ? __Corner.style.top = this.InternalScrollContainerElement.scrollTop + "px"; __ColumnsTableContainer.style.top = this.InternalScrollContainerElement.scrollTop + "px"; __Corner.style.left = this.InternalScrollContainerElement.scrollLeft + "px"; __RowsTableContainer.style.left = this.InternalScrollContainerElement.scrollLeft + "px"; //css_fixed_left.style.left = this.InternalScrollContainerElement.scrollLeft + "px"; //css_fixed_top.style.top = this.InternalScrollContainerElement.scrollTop + "px"; }; #endregion this.__ContentTableBody = __ContentTable.AddBody(); this.InternalNewRow = new __DataGridViewRow(); this.InternalNewRow.InternalTableRow = __ContentTableBody.AddRow(); this.InternalNewRow.InternalTableRow.style.height = "22px"; this.InternalRows.InternalItems.Source.Add(InternalNewRow); // http://www.w3schools.com/cssref/sel_last-of-type.asp // dont we have lastOfType available yet? var InternalNewRow_content_css = // can we have LINQ style? .Last() (__ContentTable_css + IHTMLElement.HTMLElementEnum.tbody).last[IHTMLElement.HTMLElementEnum.tr]; var InternalNewRow_header_css = __RowsTable_css [IHTMLElement.HTMLElementEnum.tbody].last[IHTMLElement.HTMLElementEnum.tr]; var InternalNewRow_css = InternalNewRow_content_css | InternalNewRow_header_css; // move to conditional css! this.AllowUserToAddRowsChanged += delegate { if (this.AllowUserToAddRows) InternalNewRow_css.style.display = IStyle.DisplayEnum.empty; else InternalNewRow_css.style.display = IStyle.DisplayEnum.none; }; this.DefaultCellStyle = new DataGridViewCellStyle { BackColor = global::System.Drawing.SystemColors.Window }; this.ColumnHeadersDefaultCellStyle = new DataGridViewCellStyle { BackColor = global::System.Drawing.SystemColors.ButtonFace }; this.RowHeadersDefaultCellStyle = new DataGridViewCellStyle { BackColor = global::System.Drawing.SystemColors.ButtonFace }; Console.WriteLine("new DataGridView() before CreateVerticalResizer"); #region CreateVerticalResizer -- Func<IHTMLDiv> CreateVerticalResizer = () => { var r = new IHTMLDiv { className = "VerticalResizer" }; r.style.position = DOM.IStyle.PositionEnum.absolute; r.style.height = "9px"; r.style.left = "0px"; r.style.width = "200px"; //HorizontalResizer.style.backgroundColor = JSColor.Red; //r.style.cursor = DOM.IStyle.CursorEnum.move; var l = new IHTMLDiv().AttachTo(r); l.style.position = DOM.IStyle.PositionEnum.absolute; l.style.top = "4px"; l.style.height = "1px"; l.style.left = "0px"; l.style.right = "0px"; //l.style.backgroundColor = this.InternalBackgroundColor.ToString(); ////l.style.backgroundColor = "yellow"; //InternalBackgroundColorChanged += // delegate // { // l.style.backgroundColor = this.InternalBackgroundColor.ToString(); // }; l.setAttribute("data-resizer", "resizer"); //this.InternalGridColorTargets.Add( // l.css // ); this.ClientSizeChanged += delegate { r.style.width = "200x"; //r.Hide(); Native.window.requestAnimationFrame += //new ScriptCoreLib.JavaScript.Runtime.Timer( delegate { r.style.width = this.InternalScrollContainerElement.clientWidth + "px"; //l.style.backgroundColor = "red"; //r.Show(); } ; //).StartTimeout(200); }; return r; }; #endregion //css[(dynamic x) => x.AllowUserToResizeColumns == false][" .HorizontalResizer"].style.display = IStyle.DisplayEnum.none; //css[x => x.getAttribute("AllowUserToResizeColumns") == false][" .HorizontalResizer"].style.display = IStyle.DisplayEnum.none; var xAllowUserToResizeColumns_false = new XAttribute("AllowUserToResizeColumns", "false"); css[xAllowUserToResizeColumns_false][" .HorizontalResizer"].style.display = IStyle.DisplayEnum.none; // should jsc go and detect where the attribute is attached to? //css[" .HorizontalResizer"][xAllowUserToResizeColumns_false].style.display = IStyle.DisplayEnum.none; // before CreateHorizontalResizer var css_HorizontalResizer = css[" .HorizontalResizer"]; new IStyle(css_HorizontalResizer) { position = DOM.IStyle.PositionEnum.absolute, width = "9px", height = "22px" }; css_HorizontalResizer.hover.style.height = "100%"; css_HorizontalResizer.active.style.height = "100%"; css_HorizontalResizer.style.cursor = DOM.IStyle.CursorEnum.move; //var css_HorizontalResizerLine = css_HorizontalResizer[IHTMLElement.HTMLElementEnum.div]; new IStyle(css_HorizontalResizer.after) { // just to show up, we need to set this? content = "''", position = DOM.IStyle.PositionEnum.absolute, left = "4px", width = "1px", top = "0px", bottom = "0px" }; //_HorizontalResizer.css.active.first.style.color = "blue"; //_HorizontalResizer.css.style.backgroundColor = "yellow"; //_HorizontalResizer.css.active.style.backgroundColor = "cyan"; // debug //_HorizontalResizer.css.first.style.backgroundColor = "cyan"; // ?css.after.parent.hover... css_HorizontalResizer.hover.after.style.backgroundColor = "black"; css_HorizontalResizer.active.after.style.backgroundColor = "blue"; // save it so we can change the color this.InternalGridColor_css = css_HorizontalResizer.after; //var css = //var ZeroVerticalResizer = CreateVerticalResizer().AttachTo(InternalElement); //ZeroVerticalResizer.style.SetLocation(0, 22 - 5); Console.WriteLine("new DataGridView() before ZeroHorizontalResizer"); #region ZeroHorizontalResizer //var ZeroHorizontalResizer = CreateHorizontalResizer().AttachTo(InternalElement); var ZeroHorizontalResizer = new IHTMLDiv { className = "HorizontalResizer" }.AttachTo(InternalScrollContainerElement); var ZeroHorizontalResizerDrag = new DragHelper(ZeroHorizontalResizer) { // why cant I see it? Position = new Point(32, 0), Enabled = true }; //Action UpdateToVerticalResizerScroll = delegate //{ // //ZeroVerticalResizer.style.SetLocation( // // this.InternalScrollContainerElement.scrollLeft, // // this.InternalScrollContainerElement.scrollTop + (22 - 5) // //); //}; #region UpdateToHorizontalResizerScroll Action UpdateToHorizontalResizerScroll = delegate { ZeroHorizontalResizer.style.SetLocation( this.InternalScrollContainerElement.scrollLeft + ZeroHorizontalResizerDrag.Position.X - 1, this.InternalScrollContainerElement.scrollTop ); }; #endregion // what if the the value is changed in the inspector/ // will our control survive the change? as we dont get any events for that. // almost. the Fill will not be recalculate just yet tho // tested by // X:\jsc.svn\examples\javascript\forms\Test\TestFlowDataGridPadding\TestFlowDataGridPadding\Application.cs css[new XAttribute("RowHeadersVisible", "false")][__ColumnsTable, __ContentTable].style.paddingLeft = "1px"; var css_RowHeadersVisible_true = css[new XAttribute("RowHeadersVisible", "true")][__ColumnsTable, __ContentTable]; #endregion Console.WriteLine("new DataGridView() before UpdateToHorizontalResizerDrag"); #region UpdateToHorizontalResizerDrag Action UpdateToHorizontalResizerDrag = delegate { //var value = (ZeroHorizontalResizerDrag.Position.X + 4); var value = (ZeroHorizontalResizerDrag.Position.X + 4); // no we want it completly gone, not just at 4px if (this.RowHeadersVisible) { __Corner.style.width = (value - 2) + "px"; __RowsTable.style.width = value + "px"; __RowsTable.style.minWidth = value + "px"; // has 2 borders } css_RowHeadersVisible_true.style.paddingLeft = value + "px"; }; #endregion // when this.RowHeadersVisible == false css[new XAttribute("RowHeadersVisible", "false")] [ZeroHorizontalResizer, __Corner, __RowsTable] .style.display = IStyle.DisplayEnum.none; UpdateToHorizontalResizerScroll(); UpdateToHorizontalResizerDrag(); InternalRowHeadersVisibleChanged += delegate { // tested by // X:\jsc.svn\examples\javascript\Test\TestNoZeroColumnHeaderNoScrollbarDateDataGrid\TestNoZeroColumnHeaderNoScrollbarDateDataGrid\ApplicationControl.cs UpdateToHorizontalResizerDrag(); UpdateToHorizontalResizerScroll(); }; #region ZeroHorizontalResizerDrag Drag ZeroHorizontalResizerDrag.DragStart += delegate { Native.Document.body.style.cursor = DOM.IStyle.CursorEnum.move; //((IHTMLElement)ZeroHorizontalResizer.firstChild).style.backgroundColor = JSColor.Blue; }; ZeroHorizontalResizerDrag.DragStop += delegate { Native.Document.body.style.cursor = DOM.IStyle.CursorEnum.auto; //((IHTMLElement)ZeroHorizontalResizer.firstChild).style.backgroundColor = this.InternalBackgroundColor.ToString(); //((IHTMLElement)ZeroHorizontalResizer.firstChild).style.backgroundColor = ""; //((IHTMLElement)ZeroHorizontalResizer.firstChild).style.backgroundColor = "yellow"; UpdateToHorizontalResizerDrag(); InternalAutoSizeWhenFill(); }; ZeroHorizontalResizerDrag.DragMove += delegate { UpdateToHorizontalResizerScroll(); }; #endregion Console.WriteLine("new DataGridView() before onscroll"); onscroll(); #region onscroll this.InternalScrollContainerElement.onscroll += e => { // onscroll is high performance. // using .css will slow us down 10x? var s = Stopwatch.StartNew(); //UpdateToVerticalResizerScroll(); UpdateToHorizontalResizerScroll(); // 153209ms DataGridView onscroll { ElapsedMilliseconds = 13 } // should jsc inline for performance? onscroll(); // 35418ms DataGridView onscroll { ElapsedMilliseconds = 20 } // 234208ms DataGridView onscroll { ElapsedMilliseconds = 120 } // 10468ms DataGridView onscroll { ElapsedMilliseconds = 27 } if (s.ElapsedMilliseconds > 10) Console.WriteLine("DataGridView onscroll " + new { s.ElapsedMilliseconds }); }; #endregion Console.WriteLine("new DataGridView() after onscroll"); __DataGridViewCell MouseCaptureCell = null; InternalScrollContainerElement.onmouseup += delegate { MouseCaptureCell = null; }; // show data fast // API should do the casting here of the proxyies // this.Height = 22; // // set the default for all // are the borders getting in our way? //__ContentTable_css_td.style.height = "22px"; __ContentTable_css_td.style.height = "21px"; __ContentTable_css_td.style.lineHeight = "21px"; // this wont work for ff, ie //__ContentTable_css_td.style.position = IStyle.PositionEnum.relative; // IE, ff workaround. need a div to play relative var __ContentTable_css_td_relative = __ContentTable_css_td + IHTMLElement.HTMLElementEnum.div; new IStyle(__ContentTable_css_td_relative) { position = IStyle.PositionEnum.relative, width = "100%", height = "100%" }; // ready to be made interactive //__ContentTable_css_td_relative["[data]"].empty.first.letter.style.color = "red"; __ContentTable_css_td_relative["[data]"].empty.style.color = "red"; // ah a place holder? // X:\jsc.svn\examples\javascript\forms\Test\TestLargeDataTable\TestLargeDataTable\ApplicationControl.cs __ContentTable_css_td_relative[":not([data])"].empty.style.backgroundColor = "yellow"; var __ContentTable_css_td_empty_before = __ContentTable_css_td_relative.empty.before; __ContentTable_css_td_empty_before.contentXAttribute = new XAttribute("data", ""); new IStyle(__ContentTable_css_td_empty_before) { paddingLeft = "4px", paddingRight = "4px", whiteSpace = IStyle.WhiteSpaceEnum.pre, overflow = IStyle.OverflowEnum.hidden, position = IStyle.PositionEnum.absolute, left = "0", top = "0", bottom = "0", right = "0", }; // X:\jsc.svn\examples\javascript\CSS\Test\CSSNewIStyle\CSSNewIStyle\Application.cs // http://stackoverflow.com/questions/6601697/restore-webkits-css-outline-on-input-field new IStyle( __ContentTable_css_td + IHTMLElement.HTMLElementEnum.div + IHTMLElement.HTMLElementEnum.div) { outline = "none", whiteSpace = IStyle.WhiteSpaceEnum.pre, overflow = IStyle.OverflowEnum.hidden, position = IStyle.PositionEnum.absolute, left = "0", top = "0", bottom = "0", right = "0" }; new IStyle(__ContentTable_css_td + IHTMLElement.HTMLElementEnum.div + IHTMLElement.HTMLElementEnum.div + IHTMLElement.HTMLElementEnum.span) { marginLeft = "4px", marginRight = "4px", lineHeight = "21px", whiteSpace = IStyle.WhiteSpaceEnum.pre }; //Console.WriteLine("new DataGridView() before InitializeMissingCell"); #region InitializeCell Action<__DataGridViewCell, __DataGridViewRow> InitializeMissingCell = (SourceCell, SourceRow) => { // https://connect.microsoft.com/IE/feedback/details/687834/getcomputedstyle-doesnt-implement-2nd-argument-pseudoelt#details //Console.WriteLine("InitializeCell " + new { SourceCell.ColumnIndex }); // is cell index equal to column index? // what happens if we dont have enough columns? // https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle var SourceColumn = this.InternalColumns.InternalItems[SourceCell.ColumnIndex]; #region InternalTableColumn SourceCell.InternalTableColumn = SourceRow.InternalTableRow.AddColumn(); SourceRow.InternalCells.InternalItemsX.Removed += (XRemovedCell, XRemovedCellIndex) => { if (XRemovedCell == SourceCell) { SourceCell.InternalTableColumn.Orphanize(); } }; #endregion // 951ms event: dataGridView1 set DataSource { ColumnIndex = 6, SourceRowIndex = 98, ElapsedMilliseconds = 667, a = 6.737373737373737 } // this wont work if we have multiple datagrids // can we have a test for it? // this div is needed for UI activities? // like :before var InternalTableColumn_relative = new IHTMLDiv { }.AttachTo(SourceCell.InternalTableColumn); SourceCell.InternalTableColumn_div = new IHTMLDiv { tabIndex = (((SourceRow.Index + 1) << 16) + (SourceCell.ColumnIndex + 1)) }.AttachTo(InternalTableColumn_relative); SourceCell.InternalTableColumn_div_span = new IHTMLSpan { // unformatted //innerText = (string)SourceCell.Value }.AttachTo(SourceCell.InternalTableColumn_div); var SourceCellType = SourceCell.GetType(); //Console.WriteLine(new { SourceCellType }); // 25:204ms { SourceCellType = <Namespace>.DataGridViewTextBoxCell } // what about checkbox? tested by.? #region __DataGridViewButtonCell if (SourceColumn is __DataGridViewButtonColumn) { var InternalButton = new IHTMLButton().AttachTo(SourceCell.InternalTableColumn_div); InternalButton.style.font = this.Font.ToCssString(); InternalButton.style.position = IStyle.PositionEnum.absolute; InternalButton.style.left = "0px"; InternalButton.style.top = "0px"; InternalButton.style.width = "100%"; InternalButton.style.height = "100%"; SourceCell.InternalTableColumn_div_span.AttachTo(InternalButton); InternalButton.onclick += delegate { if (this.CellContentClick != null) this.CellContentClick(this, new DataGridViewCellEventArgs(SourceCell.ColumnIndex, SourceRow.Index) ); }; return; } #endregion #region __DataGridViewButtonCell if (SourceColumn is __DataGridViewCheckBoxColumn) { // do we already also support DataSource DataTable typeof(bool) var InternalButton = new IHTMLInput { type = Shared.HTMLInputTypeEnum.checkbox }.AttachTo(SourceCell.InternalTableColumn_div); SourceCell.InternalTableColumn_div.style.textAlign = IStyle.TextAlignEnum.center; SourceCell.InternalTableColumn_div.style.padding = "2px"; //SourceCell.InternalTableColumn_div.style.verticalAlign = "middle"; //InternalButton.style.font = this.Font.ToCssString(); //InternalButton.style.position = IStyle.PositionEnum.absolute; //InternalButton.style.left = "0px"; //InternalButton.style.top = "0px"; //InternalButton.style.width = "100%"; //InternalButton.style.height = "100%"; //InternalButton.style.margin = "auto"; SourceCell.InternalTableColumn_div_span.Orphanize(); InternalButton.onclick += delegate { if (this.CellContentClick != null) this.CellContentClick(this, new DataGridViewCellEventArgs(SourceCell.ColumnIndex, SourceRow.Index) ); }; return; } #endregion // with 9 , 12, 15, 12, 6 // without 16, 32, 27,25, 30 #if FCELLEVENTS #region AtInternalValueChanged Action AtInternalValueChanged = delegate { InternalRaiseCellFormatting(SourceCell); //var innerText = SourceCell.Value.ToString(); var innerText = SourceCell.FormattedValue.ToString(); //Console.WriteLine("AtInternalValueChanged " + new { innerText }); SourceCell.InternalTableColumn_div_span.innerText = innerText; // ? InternalRaiseCellValueChanged(SourceCell); // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/04-monese/2014/201401/20140104-deploy SourceCell.InternalTableColumn_div_span.title = SourceCell.InternalToolTipText; }; AtInternalValueChanged(); SourceCell.InternalValueChanged += AtInternalValueChanged; SourceCell.InternalToolTipTextChanged += AtInternalValueChanged; #endregion #region CellAtOffset Func<int, int, __DataGridViewCell> CellAtOffset = (x, y) => { var value = default(__DataGridViewCell); var Row = this.InternalRows.InternalItems.Source.ElementAtOrDefault( SourceRow.Index + y ); if (Row == null) if (SourceRow.Index + y == this.InternalRows.Count) Row = InternalNewRow; if (Row != null) { value = Row.InternalCells.InternalItems.ElementAtOrDefault( SourceCell.ColumnIndex + x ); } return value; }; #endregion bool ExitEditModeDone = true; #region EnterEditMode Action EnterEditMode = delegate { if (this.ReadOnly) return; if (SourceCell.ReadOnly) return; if (SourceColumn.ReadOnly) return; if (!ExitEditModeDone) return; SourceCell.IsInEditMode = true; ExitEditModeDone = false; SourceCell.InternalTableColumn_div.Orphanize(); var EditElement = new IHTMLInput(Shared.HTMLInputTypeEnum.text); EditElement.style.backgroundColor = "transparent"; EditElement.style.font = this.Font.ToCssString(); EditElement.style.borderWidth = "0"; EditElement.style.position = IStyle.PositionEnum.relative; EditElement.style.left = "4px"; EditElement.style.top = "0"; EditElement.style.outline = "0"; EditElement.style.padding = "0"; EditElement.style.width = (SourceColumn.Width - 4) + "px"; EditElement.style.height = (SourceRow.Height - 1) + "px"; //EditElement.AttachTo(SourceCell.InternalTableColumn); EditElement.AttachTo(InternalTableColumn_relative); SourceCell.InternalStyle.InternalForeColorChanged += delegate { EditElement.style.color = SourceCell.InternalStyle.InternalForeColor.ToString(); }; var OriginalValue = (string)SourceCell.Value; EditElement.value = OriginalValue; #region CheckChanges Action CheckChanges = delegate { //if (((string)SourceCell.Value) != EditElement.value) //{ var args = new __DataGridViewCellValidatingEventArgs( SourceCell.ColumnIndex, SourceRow.Index ) { FormattedValue = EditElement.value }; // tested by // X:\jsc.svn\examples\javascript\forms\FormsDataGridViewDeleteRow\FormsDataGridViewDeleteRow\ApplicationControl.cs if (this.CellValidating != null) this.CellValidating(this, (DataGridViewCellValidatingEventArgs)(object)args); //Console.WriteLine("CellValidating " + new { args.Cancel }); if (args.Cancel) { //Console.WriteLine("CellValidating Cancel " + new { OriginalValue }); SourceCell.Value = OriginalValue; return; } SourceCell.Value = EditElement.value; //} }; #endregion #region ExitEditMode Action ExitEditMode = delegate { if (ExitEditModeDone) return; ExitEditModeDone = true; SourceCell.IsInEditMode = false; EditElement.Orphanize(); SourceCell.InternalTableColumn_div.AttachTo(InternalTableColumn_relative); //SourceCell.InternalStyle.InternalForeColorChanged += // delegate // { // SourceCell.InternalContentContainer.style.color = SourceCell.InternalStyle.InternalForeColor.ToString(); // }; //SourceCell.InternalContentContainer.style.backgroundColor = SourceCell.InternalStyle.InternalBackColor.ToString(); InternalRaiseCellEndEdit(SourceCell); if (OriginalValue == (string)SourceCell.Value) return; this.AutoResizeColumn(SourceCell.ColumnIndex); //InternalRaiseCellFormatting(SourceCell); Console.WriteLine("ExitEditMode AtInternalValueChanged"); AtInternalValueChanged(); }; #endregion #region CellBeginEdit EditElement.onfocus += delegate { EditElement.select(); }; EditElement.focus(); InternalRaiseCellFormatting(SourceCell); InternalRaiseCellBeginEdit(SourceCell); #endregion #region onblur EditElement.onblur += delegate { //Console.WriteLine("EditElement.onblur"); if (CheckChanges != null) CheckChanges(); if (ExitEditMode != null) ExitEditMode(); }; #endregion var __selectionStart = -1; var __selectionEnd = -1; #region onkeyup EditElement.onkeyup += _ev => { #region Focus Action<__DataGridViewCell> Focus = Cell => { _ev.preventDefault(); _ev.stopPropagation(); if (Cell != null) { Cell.InternalTableColumn_div.focus(); } }; #endregion if (_ev.IsEscape) { CheckChanges = null; ExitEditMode(); Focus(SourceCell); return; } if (_ev.KeyCode == (int)Keys.Up) { Focus(CellAtOffset(0, -1)); return; } if (_ev.KeyCode == (int)Keys.Down) { Focus(CellAtOffset(0, 1)); return; } if (_ev.KeyCode == (int)Keys.Right) if (EditElement.selectionStart == __selectionStart) if (EditElement.selectionEnd == __selectionEnd) if (__selectionEnd == __selectionStart) if (__selectionStart == EditElement.value.Length) { Focus(CellAtOffset(1, 0)); return; } if (_ev.KeyCode == (int)Keys.Left) if (EditElement.selectionStart == __selectionStart) if (EditElement.selectionEnd == __selectionEnd) if (__selectionEnd == __selectionStart) if (__selectionStart == 0) { Focus(CellAtOffset(-1, 0)); return; } __selectionEnd = EditElement.selectionEnd; __selectionStart = EditElement.selectionStart; }; #endregion #region onkeypress EditElement.onkeypress += _ev => { if (_ev.IsReturn) { _ev.preventDefault(); _ev.stopPropagation(); if (CheckChanges != null) CheckChanges(); ExitEditMode(); SourceCell.InternalTableColumn_div.focus(); } }; #endregion }; #endregion #region InternalContentContainer ondblclick SourceCell.InternalTableColumn_div.ondblclick += ev => { ev.stopPropagation(); ev.preventDefault(); if (this.CellDoubleClick != null) this.CellDoubleClick( this, new DataGridViewCellEventArgs(SourceColumn.Index, SourceRow.Index) ); EnterEditMode(); }; #endregion #region InternalContentContainer android has long taps var TouchstartWatch = new Stopwatch(); SourceCell.InternalTableColumn_div.ontouchstart += delegate { Console.WriteLine("SourceCell.InternalContentContainer.ontouchstart"); TouchstartWatch.Restart(); }; SourceCell.InternalTableColumn_div.ontouchend += delegate { Console.WriteLine("SourceCell.InternalContentContainer.ontouchend"); if (TouchstartWatch.ElapsedMilliseconds > 300) { if (this.CellDoubleClick != null) this.CellDoubleClick( this, new DataGridViewCellEventArgs(SourceColumn.Index, SourceRow.Index) ); EnterEditMode(); } // script: error JSC1000: No implementation found for this native method, please implement [System.Diagnostics.Stopwatch.Reset()] //TouchstartWatch.Reset(); TouchstartWatch = new Stopwatch(); }; #endregion #region InternalContentContainer onmousedown SourceCell.InternalTableColumn_div.onmousedown += ev => { MouseCaptureCell = SourceCell; ev.preventDefault(); if (SourceCell.Selected) EnterEditMode(); else SourceCell.InternalTableColumn_div.focus(); }; #endregion #region InternalContentContainer onmousemove SourceCell.InternalTableColumn_div.onmousemove += ev => { if (MouseCaptureCell == null) return; if (!this.MultiSelect) { MouseCaptureCell = SourceCell; ev.preventDefault(); SourceCell.InternalTableColumn_div.focus(); return; } if (ev.MouseButton == IEvent.MouseButtonEnum.Left) { if (!this.InternalSelectedCells.Contains(SourceCell)) this.InternalSelectedCells.Add(SourceCell); ev.preventDefault(); } }; #endregion #region InternalContentContainer onmouseup SourceCell.InternalTableColumn_div.onmouseup += ev => { if (MouseCaptureCell == null) return; MouseCaptureCell = null; if (!ev.ctrlKey) if (ev.MouseButton == IEvent.MouseButtonEnum.Left) { ev.preventDefault(); if (this.CellClick != null) this.CellClick(this, new DataGridViewCellEventArgs(SourceCell.ColumnIndex, SourceRow.Index)); SourceCell.InternalTableColumn_div.focus(); } }; #endregion #region InternalContentContainer onkeydown SourceCell.InternalTableColumn_div.onkeydown += ev => { #region KeyNavigateTo Func<Keys, int, int, bool> KeyNavigateTo = (k, x, y) => { if (ev.KeyCode == (int)k) { // focus the cell on the right ev.preventDefault(); ev.stopPropagation(); var Cell = CellAtOffset(x, y); if (Cell != null) { Cell.InternalTableColumn_div.focus(); return true; } } return false; }; #endregion #region FullRowSelect Delete if (this.SelectionMode == DataGridViewSelectionMode.FullRowSelect) { if (ev.KeyCode == (int)Keys.Delete) { if (SourceRow == InternalNewRow) return; if (!this.InternalAllowUserToDeleteRows) return; // tested by // X:\jsc.svn\examples\javascript\forms\FormsDataGridViewDeleteRow\FormsDataGridViewDeleteRow\ApplicationControl.cs // script: error JSC1000: No implementation found for this native method, please implement [System.Windows.Forms.DataGridViewRowCollection.Remove(System.Windows.Forms.DataGridViewRow)] var Cell = CellAtOffset(0, 1); if (this.InternalBeforeUserDeletedRow != null) this.InternalBeforeUserDeletedRow( this, new DataGridViewRowEventArgs(SourceRow) ); this.Rows.Remove(SourceRow); if (this.UserDeletedRow != null) this.UserDeletedRow( this, new DataGridViewRowEventArgs(SourceRow) ); if (Cell != null) { Cell.InternalTableColumn_div.focus(); } return; } } #endregion if (KeyNavigateTo(Keys.Right, 1, 0)) return; if (KeyNavigateTo(Keys.Left, -1, 0)) return; if (KeyNavigateTo(Keys.Up, 0, -1)) return; if (KeyNavigateTo(Keys.Down, 0, 1)) return; if (ev.IsReturn) { ev.preventDefault(); ev.stopPropagation(); EnterEditMode(); return; } if (ev.KeyCode == (int)Keys.Space) { EnterEditMode(); return; } if (char.IsLetter((char)ev.KeyCode)) { EnterEditMode(); return; } if (char.IsNumber((char)ev.KeyCode)) { EnterEditMode(); return; } }; #endregion #region InternalContentContainer onblur SourceCell.InternalTableColumn_div.onblur += //SourceCell.InternalTableColumn.onblur += ev => { SourceCell.InternalSetSelected(false); if (!ev.ctrlKey) { // clear while (this.InternalSelectedCells.Count > 0) { var item = this.InternalSelectedCells.InternalItems[0]; //item.InternalContentContainer.style.backgroundColor = item.InternalStyle.InternalBackColor.ToString(); item.InternalTableColumn_div.style.backgroundColor = ""; item.InternalTableColumn_div.style.color = item.InternalStyle.InternalForeColor.ToString(); this.InternalSelectedCells.RemoveAt(0); } } if (this.CellLeave != null) this.CellLeave(this, new DataGridViewCellEventArgs(SourceCell.ColumnIndex, SourceRow.Index)); }; #endregion #region InternalContentContainer onfocus SourceCell.InternalTableColumn_div.onfocus += //SourceCell.InternalTableColumn.onfocus += ev => { SourceCell.InternalSetSelected(true); ev.preventDefault(); ev.stopPropagation(); if (this.CellEnter != null) this.CellEnter( this, new DataGridViewCellEventArgs(SourceCell.ColumnIndex, SourceRow.Index) ); { var NewSelectedCell = SourceCell; if (!this.InternalSelectedCells.Contains(NewSelectedCell)) this.InternalSelectedCells.Add(NewSelectedCell); } if (this.SelectionMode == DataGridViewSelectionMode.FullRowSelect) { // tested by // X:\jsc.svn\examples\javascript\forms\FormsDataGridRowSelect\FormsDataGridRowSelect\ApplicationControl.cs foreach (var NewSelectedCell in SourceRow.InternalCells.InternalItems) { if (!this.InternalSelectedCells.Contains(NewSelectedCell)) this.InternalSelectedCells.Add(NewSelectedCell); } } }; #endregion InternalBindCellMouseEnter(SourceCell); #region InternalContentContainer Font SourceCell.InternalTableColumn_div.style.font = SourceCell.InternalStyle.Font.ToCssString(); SourceCell.InternalStyle.InternalFontChanged += delegate { if (SourceCell.Selected) return; SourceCell.InternalTableColumn_div.style.font = SourceCell.InternalStyle.Font.ToCssString(); if (SourceCell.InternalStyle.InternalFont.Underline) SourceCell.InternalTableColumn_div.style.textDecoration = "underline"; else SourceCell.InternalTableColumn_div.style.textDecoration = ""; }; #endregion // need to move this to css //#region InternalContentContainer InternalForeColorChanged //SourceCell.InternalTableColumn_div.style.color = SourceCell.InternalStyle.InternalForeColor.ToString(); //SourceCell.InternalStyle.InternalForeColorChanged += // delegate // { // if (SourceCell.Selected) // return; // SourceCell.InternalTableColumn_div.style.color = SourceCell.InternalStyle.InternalForeColor.ToString(); // }; //#endregion if (SourceCell.InternalStyle.Alignment == DataGridViewContentAlignment.MiddleRight) SourceCell.InternalTableColumn_div.style.textAlign = IStyle.TextAlignEnum.right; #endif }; #endregion #region CreateMissingCells Action<__DataGridViewRow> CreateMissingCells = SourceRow => { //Console.WriteLine("CreateMissingCells " + new //{ // SourceRow.Index, // CellsCount = SourceRow.InternalCells.InternalItems.Count, // ColumnsCount = this.InternalColumns.InternalItems.Count //}); #region defaults while (SourceRow.InternalCells.InternalItems.Count < this.InternalColumns.InternalItems.Count) { var ColumnIndex = SourceRow.InternalCells.Count; //Console.WriteLine("CreateMissingCells " + new { SourceRow.Index, ColumnIndex }); var __c = this.InternalColumns.InternalItems[ColumnIndex]; __DataGridViewCell SourceCell = null; if (__c is __DataGridViewButtonColumn) { //Console.WriteLine("CreateMissingCells __DataGridViewButtonColumn " + new { SourceRow.Index, ColumnIndex }); SourceCell = new __DataGridViewButtonCell(); } else if (__c is __DataGridViewCheckBoxColumn) { //Console.WriteLine("CreateMissingCells ? " + new { SourceRow.Index, ColumnIndex }); // X:\jsc.svn\examples\javascript\forms\Test\TestButtonColumn\TestButtonColumn\ApplicationControl.cs SourceCell = new __DataGridViewCheckBoxCell(); } else { //Console.WriteLine("CreateMissingCells ? " + new { SourceRow.Index, ColumnIndex }); SourceCell = new __DataGridViewTextBoxCell(); } SourceRow.InternalCells.InternalItems.Add(SourceCell); } #endregion //29:295ms CreateMissingCells { Index = 0, CellsCount = 5, ColumnsCount = 1 } //29:296ms what if SourceRow has more columns than the table? { i = 0 } //29:298ms what if SourceRow has more columns than the table? { i = 1 } for (int i = 0; i < SourceRow.InternalCells.InternalItems.Count; i++) { //Console.WriteLine("what if SourceRow has more columns than the table? " + new { i }); // X:\jsc.svn\examples\javascript\forms\FormsHistoricBindingSourcePosition\FormsHistoricBindingSourcePosition\ApplicationControl.cs // SourceRow has more columns? bail? are we showing the correct columns? if (i == this.Columns.Count) break; var SourceColumn = this.InternalColumns.InternalItems[i]; var SourceCell = SourceRow.InternalCells.InternalItems[i]; if (SourceCell.InternalTableColumn == null) { InitializeMissingCell( SourceCell, SourceRow ); } SourceColumn.InternalDefaultCellStyleChanged += delegate { if (SourceColumn.DefaultCellStyle != null) { SourceCell.Style.ForeColor = SourceColumn.DefaultCellStyle.ForeColor; //SourceCell.Style.BackColor = SourceColumn.DefaultCellStyle.BackColor; } }; //((__DataGridViewCellStyle)SourceRow.DefaultCellStyle).InternalBackColorChanged += // delegate // { // // when row style is changed, who overriddes who? // //SourceCell.Style.BackColor = SourceRow.DefaultCellStyle.BackColor; // }; if (SourceColumn.DefaultCellStyle != null) { SourceCell.Style.ForeColor = SourceColumn.DefaultCellStyle.ForeColor; //SourceCell.Style.BackColor = SourceColumn.DefaultCellStyle.BackColor; } } }; #endregion (__ColumnsTableRow.css + IHTMLElement.HTMLElementEnum.div).style.position = IStyle.PositionEnum.relative; Console.WriteLine("new DataGridView() before InternalColumns"); #region InternalColumns this.InternalColumns.InternalItemsX.Removed += (SourceColumn, NewIndex) => { foreach (var SourceRow in this.InternalRows.InternalItems.Source) { SourceRow.Cells.RemoveAt(NewIndex); } SourceColumn.InternalTableColumn.Orphanize(); SourceColumn.ColumnHorizontalResizer.Orphanize(); }; this.InternalColumns.InternalItemsX.Added += (SourceColumn, NewIndex) => { // jsc why is this function slow? //var SourceColumn = this.InternalColumns.InternalItems[_e.NewIndex]; var SourceColumnStopwatch = Stopwatch.StartNew(); // 1250ms { Name = dataGridView1 } InternalColumns Added { Index = 29, SourceColumnStopwatch = 41 } SourceColumn.InternalContext = this; //Console.WriteLine( // new { this.Name } // + " InternalColumns Added " + new { SourceColumn.Index }); //if (c is __DataGridViewButtonColumn) // Console.WriteLine("InternalColumns __DataGridViewButtonColumn ItemAdded " + new { _e.NewIndex }); //else // Console.WriteLine("InternalColumns ? ItemAdded " + new { _e.NewIndex }); SourceColumn.InternalTableColumn = __ColumnsTableRow.AddColumn(); // move to .css //SourceColumn.InternalTableColumn.style.position = IStyle.PositionEnum.relative; if (this.InternalRows.Count > 0) foreach (var SourceRow in this.InternalRows.InternalItems.Source) { CreateMissingCells(SourceRow); } #region c1contentcrel, move to css + :before? var c1contentcrel = new IHTMLDiv { }.AttachTo(SourceColumn.InternalTableColumn); c1contentcrel.style.position = IStyle.PositionEnum.relative; c1contentcrel.style.left = "0"; c1contentcrel.style.top = "0"; c1contentcrel.style.right = "0"; c1contentcrel.style.height = "22px"; var c1contentc = new IHTMLDiv { }.AttachTo(c1contentcrel); c1contentc.style.overflow = IStyle.OverflowEnum.hidden; c1contentc.style.position = IStyle.PositionEnum.absolute; c1contentc.style.left = "0"; c1contentc.style.top = "0"; c1contentc.style.right = "0"; c1contentc.style.height = "22px"; var c1content = new IHTMLSpan { innerText = SourceColumn.HeaderText }.AttachTo(c1contentc); SourceColumn.InternalContent = c1content; c1content.style.marginLeft = "4px"; // tested by // X:\jsc.svn\examples\javascript\forms\TTFCurrencyExperment\TTFCurrencyExperment\ApplicationControl.cs #if FHR c1content.style.font = this.Font.ToCssString(); // ? we should use .css here this.FontChanged += delegate { c1content.style.font = this.Font.ToCssString(); }; #endif c1content.style.lineHeight = "22px"; #endregion SourceColumn.InternalHeaderTextChanged += delegate { // would we be better off using :after:content attr() c1content.innerText = SourceColumn.HeaderText; }; // setting the size for the headers on top //Console.WriteLine("before SourceColumnWidth_css"); var SourceColumnWidth_css = default(CSSStyleRuleMonkier); if (SourceColumn.Index == -1) { // scoped style? SourceColumnWidth_css = this.__RowsTable_css; } else { SourceColumnWidth_css = this.__ColumnsTable_css_td[SourceColumn.Index] | this.__ColumnsTable_css_td[SourceColumn.Index][IHTMLElement.HTMLElementEnum.div] | this.__ContentTable_css_td[SourceColumn.Index] | this.__ContentTable_css_td[SourceColumn.Index][IHTMLElement.HTMLElementEnum.div]; } #region AtInternalWidthChanged Action AtInternalWidthChanged = delegate { var SourceColumnWidthStopwatch = Stopwatch.StartNew(); var SourceColumnWidth = SourceColumn.Width; // tested by // X:\jsc.svn\examples\javascript\forms\Test\TestGrowingGrid\TestGrowingGrid\ApplicationControl.cs // X:\jsc.svn\examples\javascript\forms\Test\TestFlowDataGridPadding\TestFlowDataGridPadding\Application.cs // update the designer style SourceColumnWidth_css.style.width = SourceColumnWidth + "px"; //// table wants to squeeshe the columns, prevent it if (this.ColumnWidthChanged != null) this.ColumnWidthChanged(this, new DataGridViewColumnEventArgs(SourceColumn) ); // AtInternalWidthChanged { ElapsedMilliseconds = 0 } if (SourceColumnWidthStopwatch.ElapsedMilliseconds > 10) Console.WriteLine("AtInternalWidthChanged " + new { SourceColumnWidthStopwatch.ElapsedMilliseconds }); }; SourceColumn.InternalWidthChanged += AtInternalWidthChanged; AtInternalWidthChanged(); #endregion // should jsc record the last current method before entering console writeline? //Console.WriteLine( // new { this.Name } // + " InternalColumns Added step 2"); #if FHR #region InternalVisibleChanged //Console.WriteLine("before SourceColumnVisible__ColumnsTable_css"); var SourceColumnVisible__ColumnsTable_css = (__ColumnsTable_css + IHTMLElement.HTMLElementEnum.tbody + IHTMLElement.HTMLElementEnum.tr + IHTMLElement.HTMLElementEnum.td) [NewIndex]; //Console.WriteLine("after SourceColumnVisible__ColumnsTable_css"); //Console.WriteLine("before SourceColumnVisible__ContentTable_css"); var SourceColumnVisible__ContentTable_css = ( __ContentTable_css + IHTMLElement.HTMLElementEnum.tbody + IHTMLElement.HTMLElementEnum.tr + IHTMLElement.HTMLElementEnum.td ) [NewIndex]; //Console.WriteLine("after SourceColumnVisible__ContentTable_css"); // xattribute instead? var SourceColumnVisible_css = SourceColumnVisible__ColumnsTable_css | SourceColumnVisible__ContentTable_css; SourceColumn.InternalVisibleChanged += delegate { if (SourceColumn.Visible) SourceColumnVisible_css.style.display = IStyle.DisplayEnum.empty; else SourceColumnVisible_css.style.display = IStyle.DisplayEnum.none; }; #endregion #region ColumnHorizontalResizer CreateHorizontalResizer // should we delay this until resize is enabled? //Console.WriteLine("before CreateHorizontalResizer"); SourceColumn.ColumnHorizontalResizer = new IHTMLDiv { className = "HorizontalResizer" }; // what about older rules? // shall they stop existing once the new once is used? //Console.WriteLine("before CreateHorizontalResizer onscroll"); //onscroll(); //Console.WriteLine("after CreateHorizontalResizer"); SourceColumn.ColumnHorizontalResizer.AttachTo(InternalElement); //__ColumnsTableContainer.insertNextSibling(SourceColumn.ColumnHorizontalResizer); var ColumnHorizontalResizerDrag = new DragHelper(SourceColumn.ColumnHorizontalResizer) { Enabled = true }; SourceColumn.InternalHorizontalDrag = ColumnHorizontalResizerDrag; #endregion #region ColumnUpdateToHorizontalResizerScroll left Action ColumnUpdateToHorizontalResizerScroll = delegate { var x = ColumnHorizontalResizerDrag.Position.X; SourceColumn.ColumnHorizontalResizer.style.left = x + "px"; }; #endregion #region ColumnUpdateToHorizontalResizerScroll // do we need this? //this.InternalRows.InternalItems.Added += // delegate // { // this.HTMLTargetRef.requestAnimationFrame += // delegate // { // ColumnUpdateToHorizontalResizerScroll(); // }; // }; this.InternalAtAfterVisibleChanged += delegate { this.HTMLTargetRef.requestAnimationFrame += delegate { ColumnUpdateToHorizontalResizerScroll(); }; }; #endregion #region CompensateFor ZeroHorizontalResizerDrag DragStop Action<DragHelper> CompensateFor = Target => { var __X = 0; Target.DragStart += delegate { __X = Target.Position.X; }; Target.DragStop += delegate { ColumnHorizontalResizerDrag.Position.X += Target.Position.X - __X; ColumnUpdateToHorizontalResizerScroll(); }; }; CompensateFor(ZeroHorizontalResizerDrag); #endregion #region Reposition Action Reposition = delegate { var RepositionStopwatch = Stopwatch.StartNew(); var x = ZeroHorizontalResizerDrag.Position.X - 1; if (!this.RowHeadersVisible) { x = -4; } x -= this.InternalScrollContainerElement.scrollLeft; for (int i = 0; i <= NewIndex; i++) { //x += this.InternalColumns.InternalItems[i].Width; var CandidateColumn = this.InternalColumns.InternalItems[i]; // X:\jsc.svn\examples\javascript\forms\Test\TestDataGridPadding\TestDataGridPadding\ApplicationControl.cs if (CandidateColumn.Visible) x += CandidateColumn.Width + 1; } ColumnHorizontalResizerDrag.Position = new Point(x, 0); ColumnUpdateToHorizontalResizerScroll(); // what takes here half a sec? // 1737ms event: Reposition { Index = 0, ElapsedMilliseconds = 447 } // report slow. 60 is the new slow //if (RepositionStopwatch.ElapsedMilliseconds > 10) if (RepositionStopwatch.ElapsedMilliseconds > 60) Console.WriteLine("reposition " + new { SourceColumn.Index, RepositionStopwatch.ElapsedMilliseconds }); }; // are we adding columns in bulk? cant have reflow yet // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201402/20140205 if (!InternalDataSourceBusy) Reposition(); this.InternalScrollContainerElement.onscroll += e => { Reposition(); }; // tested by // X:\jsc.svn\examples\javascript\Test\TestNoZeroColumnHeaderNoScrollbarDateDataGrid\TestNoZeroColumnHeaderNoScrollbarDateDataGrid\ApplicationControl.cs InternalRowHeadersVisibleChanged += delegate { Reposition(); }; for (int i = 0; i <= NewIndex; i++) { var item = this.InternalColumns.InternalItems[i]; item.InternalWidthChanged += delegate { if (InternalDataSourceBusy) return; Reposition(); }; } #endregion #region ColumnHorizontalResizerDrag DragStart var __DragStartX = 0; ColumnHorizontalResizerDrag.DragStart += delegate { Native.Document.body.style.cursor = DOM.IStyle.CursorEnum.move; //((IHTMLElement)SourceColumn.ColumnHorizontalResizer.firstChild).style.backgroundColor = JSColor.Blue; __DragStartX = ColumnHorizontalResizerDrag.Position.X; }; ColumnHorizontalResizerDrag.DragStop += delegate { // { Width = 115, cwidth = 1045 } view-source:27892 // view-source:27892 //{ Width = 1045, cwidth = 1975 } Native.Document.body.style.cursor = DOM.IStyle.CursorEnum.auto; //((IHTMLElement)SourceColumn.ColumnHorizontalResizer.firstChild).style.backgroundColor = this.InternalBackgroundColor.ToString(); //((IHTMLElement)SourceColumn.ColumnHorizontalResizer.firstChild).style.backgroundColor = ""; //((IHTMLElement)SourceColumn.ColumnHorizontalResizer.firstChild).style.backgroundColor = "yellow"; //SourceColumn.ColumnHorizontalResizer.style.backgroundColor = "red"; var ColumnHorizontalResizerDragNewValue = SourceColumn.Width + ColumnHorizontalResizerDrag.Position.X - __DragStartX; Console.WriteLine(new { SourceColumn.Width, ColumnHorizontalResizerDragNewValue }); SourceColumn.Width = ColumnHorizontalResizerDragNewValue; InternalAutoSizeWhenFill(); }; ColumnHorizontalResizerDrag.DragMove += delegate { ColumnUpdateToHorizontalResizerScroll(); }; #endregion #region ColumnHorizontalResizer ondblclick AutoResizeColumn SourceColumn.ColumnHorizontalResizer.onmousedown += e => { if (e.MouseButton == IEvent.MouseButtonEnum.Middle) { e.preventDefault(); e.stopPropagation(); this.AutoResizeColumn(SourceColumn.Index, ObeyAutoSizeMode: false); InternalAutoSizeWhenFill(); } }; SourceColumn.ColumnHorizontalResizer.ondblclick += delegate { this.AutoResizeColumn(SourceColumn.Index, ObeyAutoSizeMode: false); InternalAutoSizeWhenFill(); }; #endregion #endif bool InternalAutoResizeColumnBuzy = false; #region InternalAutoResizeColumn //Console.WriteLine("add InternalAutoResizeColumn"); this.InternalAutoResizeColumn += (SourceColumnIndex, ObeyAutoSizeMode) => { //Console.WriteLine("at InternalAutoResizeColumn"); if (InternalAutoResizeColumnBuzy) return; if (SourceColumnIndex != SourceColumn.Index) return; var rows = this.InternalRows.InternalItems.Source; var InternalAutoResizeColumnStopwatch = Stopwatch.StartNew(); // InternalAutoSize { Count = 33, cindex = -1 } //Console.WriteLine( // new { this.Name } // + " InternalAutoResizeColumn " // + new // { // RowCount = rows.Count, // SourceColumnIndex, // // are we even supposed to do autoresize? // SourceColumn.AutoSizeMode // } //); #region Fill last column if (this.AutoSizeColumnsMode == DataGridViewAutoSizeColumnsMode.Fill) { var FillColumn = InternalGetVisibleColumns().LastOrDefault(); if (FillColumn != null) if (SourceColumnIndex == FillColumn.Index) { //Console.WriteLine("InternalAutoResizeColumn " + new { FillColumn.Index, FillColumn.Name }); //SourceColumn.le var SourceColumnLeft = InternalGetVisibleColumns() .Where(c => c.Index < FillColumn.Index) .Select(c => c.Width) .Sum(); var ZeroRight = (ZeroHorizontalResizerDrag.Position.X + 4); // X:\jsc.svn\examples\javascript\forms\FormsHistoricBindingSourcePosition\FormsHistoricBindingSourcePosition\ApplicationControl.cs // tested by? if (!this.RowHeadersVisible) { // we are missing the left border! SourceColumnLeft = 0; ZeroRight = -4; } // { cindex = 0, w = 0, all = 1600, WidthByFill = 1600 } var all = this.InternalScrollContainerElement.clientWidth; var WidthByFill = all - SourceColumnLeft - ZeroRight - 5; WidthByFill -= 1; //Console.WriteLine( // " InternalAutoResizeColumn Fill " // + new // { // SourceColumnIndex, // SourceColumnLeft, // value = ZeroRight, // all, // WidthByFill // } // ); //{ cindex = 0, w = 0, value = 99, all = 753, WidthByFill = 654 } #if FHR __DragStartX = ColumnHorizontalResizerDrag.Position.X + (WidthByFill - SourceColumn.Width); #endif InternalAutoResizeColumnBuzy = true; SourceColumn.Width = Math.Max(20, WidthByFill); InternalAutoResizeColumnBuzy = false; return; } } #endregion if (SourceColumnIndex < 0) return; if (SourceColumn.AutoSizeMode == DataGridViewAutoSizeColumnMode.None) { if (ObeyAutoSizeMode) return; } //Console.WriteLine("before max"); #region SetColumnWidth //1268ms before max view-source:35829 //1707ms after max // we should only look at currently visible rows? var WidthByRowsInThisColumn = rows.Take(16).Max( rr => { //1774ms at rr view-source:35829 //2273ms at rr //Console.WriteLine("enter rr"); // 33736ms before max view-source:35829 //33736ms enter rr view-source:35829 //34202ms exit rr { value = 228 } __DataGridViewCell cc = rr.Cells[SourceColumnIndex]; //Console.WriteLine("got cc"); //Console.WriteLine("InternalAutoSize " + new { rows.Count, cindex, cc.InternalContent.offsetWidth }); //2717ms got cc view-source:35829 //3165ms exit rr { value = 228 } var s = Stopwatch.StartNew(); // !!! accessing DOM is expensive! var value = cc.InternalTableColumn_div_span.offsetWidth; //2717ms got cc view-source:35829 //3165ms exit rr { value = 228 } if (s.ElapsedMilliseconds > 10) Console.WriteLine("got offsetWidth in " + new { s.ElapsedMilliseconds }); return value; } ); //Console.WriteLine("after max"); WidthByRowsInThisColumn = Math.Max(WidthByRowsInThisColumn, this.InternalColumns.InternalItems[SourceColumnIndex].InternalContent.offsetWidth); if (WidthByRowsInThisColumn == 0) { // no DOM? //Console.WriteLine("InternalAutoSize skipped"); return; } // extra padding? WidthByRowsInThisColumn += 8 + 24; //Console.WriteLine("InternalAutoSize" + new { SourceColumn.Width, cwidth = WidthByRowsInThisColumn }); #if FHR __DragStartX = ColumnHorizontalResizerDrag.Position.X + (WidthByRowsInThisColumn - SourceColumn.Width); #endif var NewWidth = Math.Max(20, WidthByRowsInThisColumn); // 15248ms { Name = dataGridView2 }InternalAutoResizeColumn { RowCount = 2, SourceColumnIndex = 0, NewWidth = 154, ElapsedMilliseconds = 2 } // 14818ms { Name = dataGridView2 } InternalAutoResizeColumn { RowCount = 2, SourceColumnIndex = 2, NewWidth = 120, ElapsedMilliseconds = 1 } // 1745ms event: { Name = dataGridView1 } InternalAutoResizeColumn { RowCount = 9, SourceColumnIndex = 1, NewWidth = 260, ElapsedMilliseconds = 447 } // report only slow https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201404/20140413 if (InternalAutoResizeColumnStopwatch.ElapsedMilliseconds > 20) Console.WriteLine( "event: " + new { this.Name } + " InternalAutoResizeColumn " + new { RowCount = rows.Count, SourceColumnIndex, NewWidth, InternalAutoResizeColumnStopwatch.ElapsedMilliseconds }); // why does this cost us 600ms? SourceColumn.Width = NewWidth; #endregion }; #endregion #if FHR if (ColumnAdded != null) ColumnAdded(this, new DataGridViewColumnEventArgs((DataGridViewColumn)(object)SourceColumn)); #endif // 1135ms { Name = dataGridView1 } InternalColumns Added { Index = 29, SourceColumnStopwatch = 7 } // 888 ?? // 244382ms event: dataGridView2 set DataSource columns { SourceDataTableColumnCount = 7, ElapsedMilliseconds = 869 } // 2135ms { Name = dataGridView2 } InternalColumns Added { Index = 0, Name = , SourceColumnStopwatch = 123 } //120:5572ms { Name = dataGridView2 } InternalColumns Added { Index = 1, SourceColumnStopwatch = 8 } // 112:371747ms { Name = dataGridView1 } InternalColumns Added { Index = 1, SourceColumnStopwatch = 31 } if (SourceColumnStopwatch.ElapsedMilliseconds > 40) Console.WriteLine( new { this.Name } + " InternalColumns Added " + new { SourceColumn.Index, SourceColumnStopwatch = SourceColumnStopwatch.ElapsedMilliseconds }); }; #endregion new IStyle(__RowsTable_css_td) { width = "100%", height = "21px", position = IStyle.PositionEnum.relative }; #region DataGridNewRow { var DataGridNewRow = new IHTMLImage("assets/ScriptCoreLib.Windows.Forms/DataGridNewRow.png"); var xDataGridViewCellIsInEditMode = new XAttribute("DataGridViewCellIsInEditMode", global::System.Convert.ToString(true)); var __RowsTable_css_td_after = __RowsTable_css [IHTMLElement.HTMLElementEnum.tbody] .last[IHTMLElement.HTMLElementEnum.tr] //[e => e.getAttribute("DataGridViewCellSelected") == true] [IHTMLElement.HTMLElementEnum.td] .after; __RowsTable_css_td_after.style.position = IStyle.PositionEnum.absolute; __RowsTable_css_td_after.style.left = "12px"; __RowsTable_css_td_after.style.top = "0px"; __RowsTable_css_td_after.style.right = "0"; __RowsTable_css_td_after.style.height = "21px"; __RowsTable_css_td_after.content = ""; __RowsTable_css_td_after.style.backgroundPosition = "left center"; DataGridNewRow.ToBackground(__RowsTable_css_td_after.style, false); } #endregion #region DataGridEditRow { var DataGridEditRow = new IHTMLImage("assets/ScriptCoreLib.Windows.Forms/DataGridEditRow.png"); var xDataGridViewCellIsInEditMode = new XAttribute("DataGridViewCellIsInEditMode", global::System.Convert.ToString(true)); var __RowsTable_css_td_after = __RowsTable_css [IHTMLElement.HTMLElementEnum.tbody] [IHTMLElement.HTMLElementEnum.tr] //[e => e.getAttribute("DataGridViewCellSelected") == true] [xDataGridViewCellIsInEditMode] [IHTMLElement.HTMLElementEnum.td] .after; __RowsTable_css_td_after.style.position = IStyle.PositionEnum.absolute; __RowsTable_css_td_after.style.left = "12px"; __RowsTable_css_td_after.style.top = "0px"; __RowsTable_css_td_after.style.right = "0"; __RowsTable_css_td_after.style.height = "21px"; __RowsTable_css_td_after.content = ""; __RowsTable_css_td_after.style.backgroundPosition = "left center"; DataGridEditRow.ToBackground(__RowsTable_css_td_after.style, false); } #endregion #region DataGridFocusRow { var xDataGridViewCellSelected = new XAttribute("DataGridViewCellSelected", global::System.Convert.ToString(true)); var DataGridFocusRow = new IHTMLImage("assets/ScriptCoreLib.Windows.Forms/DataGridFocusRow.png"); var __RowsTable_css_td_before = __RowsTable_css [IHTMLElement.HTMLElementEnum.tbody] [IHTMLElement.HTMLElementEnum.tr] //[e => e.getAttribute("DataGridViewCellSelected") == true] [xDataGridViewCellSelected] [IHTMLElement.HTMLElementEnum.td] .before; __RowsTable_css_td_before.style.position = IStyle.PositionEnum.absolute; __RowsTable_css_td_before.style.left = "4px"; __RowsTable_css_td_before.style.top = "0px"; __RowsTable_css_td_before.style.right = "0"; __RowsTable_css_td_before.style.height = "21px"; __RowsTable_css_td_before.content = ""; __RowsTable_css_td_before.style.backgroundPosition = "left center"; DataGridFocusRow.ToBackground(__RowsTable_css_td_before.style, false); } #endregion #region InitializeZeroColumnCell // we need to reduce this! Action<__DataGridViewRow> InitializeZeroColumnCell = SourceRow => { #region InternalTableColumn var __tr = default(IHTMLTableRow); if (InternalPrerenderZeroRows.Count > 0) { // datasource already prepped a row for us __tr = InternalPrerenderZeroRows.Dequeue(); __tr.Clear(); } else { __tr = new IHTMLTableRow { }; // Failed to execute 'insertBefore' on 'Node': The new child element is null. if (InternalNewRow != null) { __RowsTableBody.insertBefore(__tr, InternalNewRow.InternalZeroColumnTableRow); } else { __RowsTableBody.appendChild(__tr); } } SourceRow.InternalZeroColumnTableRow = __tr; //var __tr = __RowsTableBody.AddRow(); var InternalTableColumn = __tr.AddColumn(); #endregion // X:\jsc.svn\examples\javascript\forms\FormsGridCellStyle\FormsGridCellStyle\Application.cs InternalTableColumn.title = new { SourceRow.Index }.ToString(); //#region AtInternalHeightChanged //Action AtInternalHeightChanged = delegate //{ // //c1.style.height = (SourceRow.InternalHeight - 1) + "px"; // c1img.style.height = (SourceRow.InternalHeight - 1) + "px"; // c2img.style.height = (SourceRow.InternalHeight - 1) + "px"; // c1contentcrel.style.height = (SourceRow.InternalHeight - 1) + "px"; // __tr.style.height = SourceRow.InternalHeight + "px"; //}; //AtInternalHeightChanged(); //SourceRow.InternalHeightChanged += AtInternalHeightChanged; //#endregion }; #endregion InitializeZeroColumnCell(InternalNewRow); Console.WriteLine("new DataGridView() after InitializeZeroColumnCell"); #region InternalAutoResizeColumn var t = new global::System.Windows.Forms.Timer(); t.Interval = 100; t.Tick += delegate { t.Stop(); InternalAutoResizeAll(); }; #endregion this.InternalRowHeadersVisibleChanged += delegate { InternalAutoSizeWhenFill(); }; #region ClientSizeChanged // whatif we are in autosize mode? this.ClientSizeChanged += delegate { InternalAutoSizeWhenFill(); }; #endregion Console.WriteLine("new DataGridView() before InternalRows.Added"); #region InternalRows.Added this.InternalRows.InternalItems.Added += (SourceRow, CurrentRowIndex) => { if (SourceRow == InternalNewRow) { // do we have a test for readding rows? SourceRow.InternalTableRow.AttachTo(__ContentTableBody); SourceRow.InternalZeroColumnTableRow.AttachTo(__RowsTableBody); } if (SourceRow.InternalTableRow != null) return; //Console.WriteLine("InternalRows Added"); if (InternalNewRow == null) { // when is this happening? SourceRow.InternalTableRow = __ContentTableBody.AddRow(); } else { // how much time are we spending per row? // what about bulk entry? // could we adapt a preexisting table? // how much time do we spend on moving the new row thingy? if (InternalPrerenderRows.Count > 0) { // datasource already prepped a row for us SourceRow.InternalTableRow = InternalPrerenderRows.Dequeue(); SourceRow.InternalTableRow.Clear(); } else { SourceRow.InternalTableRow = new IHTMLTableRow(); // Uncaught NotFoundError: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node. if (InternalNewRow.InternalTableRow.parentNode == null) { // where is our new row? __ContentTableBody.appendChild(InternalNewRow.InternalTableRow); InternalNewRow.InternalZeroColumnTableRow.AttachTo(__RowsTableBody); } __ContentTableBody.insertBefore( // is it part of the rows still? SourceRow.InternalTableRow, InternalNewRow.InternalTableRow ); } //Console.WriteLine("InternalRows reposition InternalNewRow"); // make sure the RowIndex -1 is the last element this.InternalRows.InternalItems.Source.Remove(InternalNewRow); this.InternalRows.InternalItems.Source.Add(InternalNewRow); //Console.WriteLine("InternalRows reposition InternalNewRow done"); } // disabled for now, until we get a newer test //#region AtInternalHeightChanged //Action AtInternalHeightChanged = delegate //{ // SourceRow.InternalTableRow.style.height = SourceRow.InternalHeight + "px"; //}; //AtInternalHeightChanged(); //SourceRow.InternalHeightChanged += AtInternalHeightChanged; //#endregion CreateMissingCells(SourceRow); if (!InternalSkipAutoSize) if (!InternalDataSourceBusy) if (this.AutoSizeColumnsMode != DataGridViewAutoSizeColumnsMode.None) { //Console.WriteLine("a new row was added, auto resize?"); t.Stop(); t.Start(); } InitializeZeroColumnCell(SourceRow); }; #endregion #region InternalRows Removed this.InternalRows.InternalItems.Removed += (SourceRow, i) => { //Console.WriteLine("InternalRows Removed"); SourceRow.InternalTableRow.Orphanize(); SourceRow.InternalZeroColumnTableRow.Orphanize(); // raise any events }; #endregion __DataGridViewRow PendingNewRow = null; #region UserAddedRow this.InternalRaiseCellBeginEdit = (SourceCell) => { //Console.WriteLine("InternalRaiseCellBeginEdit " + new { SourceCell.ColumnIndex, SourceCell.OwningRow.Index }); var SourceRow = SourceCell.InternalOwningRow; if (SourceRow.IsNewRow) { var n = new __DataGridViewRow(); InternalNewRow = null; PendingNewRow = SourceRow; InternalSkipAutoSize = true; this.InternalRows.InternalItems.Source.Add(n); InternalSkipAutoSize = false; InternalNewRow = n; if (this.UserAddedRow != null) this.UserAddedRow(this, new DataGridViewRowEventArgs((DataGridViewRow)(object)SourceRow)); } if (this.CellBeginEdit != null) this.CellBeginEdit(this, new DataGridViewCellCancelEventArgs(SourceCell.ColumnIndex, SourceRow.Index) ); }; #endregion #region CellEndEdit this.InternalRaiseCellValueChanged = (SourceCell) => { var SourceRow = SourceCell.InternalOwningRow; if (SourceRow.IsNewRow) { // if there is now content on the new row then we need another new row downt we? return; } //Console.WriteLine("InternalRaiseCellValueChanged " + new { SourceCell.ColumnIndex, SourceCell.OwningRow.Index }); if (PendingNewRow == SourceRow) PendingNewRow = null; if (this.CellValueChanged != null) this.CellValueChanged(this, new DataGridViewCellEventArgs(SourceCell.ColumnIndex, SourceCell.OwningRow.Index) ); }; this.InternalRaiseCellEndEdit = (SourceCell) => { //Console.WriteLine("InternalRaiseCellEndEdit " + new { SourceCell.ColumnIndex, SourceCell.OwningRow.Index }); var SourceRow = SourceCell.InternalOwningRow; #region PendingNewRow if (PendingNewRow == SourceRow) { var ColumnIndex = SourceCell.ColumnIndex; var RowIndex = SourceRow.Index; this.InternalRows.InternalItems.Source.Remove(SourceRow); SourceRow.InternalTableRow.Orphanize(); SourceRow.InternalZeroColumnTableRow.Orphanize(); //if (this.UserDeletedRow != null) // this.UserDeletedRow(this, new DataGridViewRowEventArgs((DataGridViewRow)(object)SourceRow)); PendingNewRow = null; this.InternalRows.InternalItems.Source[RowIndex].InternalCells.InternalItems[ColumnIndex].InternalTableColumn_div.focus(); //this[SourceCell.ColumnIndex, SourceRow.Index].Selected = true; } #endregion if (this.CellEndEdit != null) this.CellEndEdit(this, new DataGridViewCellEventArgs(SourceCell.ColumnIndex, SourceRow.Index) ); }; #endregion this.GridColor = global::System.Drawing.Color.FromArgb(0xa0, 0xa0, 0xa0); this.Height = 400; // 2901ms exit DataGridView .ctor { ElapsedMilliseconds = 923 } // 25:584ms event: exit DataGridView .ctor { ElapsedMilliseconds = 525 } Console.WriteLine("event: new DataGridView() " + new { DataGridViewConstructorStopwatch.ElapsedMilliseconds }); }
private static void BuildStage(IHTMLImage bg, IHTMLElement info) { var stage = new IHTMLDiv { className = "stage" }; bg.ToBackground(Native.Document.body, false); Native.Document.body.style.color = Color.Red; info.style.backgroundColor =Color.Black; stage.AttachToDocument(); IStyleSheet.Default.AddRule(".stage", r => { r.style.backgroundColor = Color.White; r.style.position = IStyle.PositionEnum.absolute; r.style.left = "0px"; r.style.top = "0px"; r.style.right = "0px"; r.style.bottom = "0px"; r.style.Opacity = 0.0; } ); Action<Dude2, IEvent> WheelAction = (d, ev) => d.Zoom.StaticZoom += ev.WheelDirection * 0.2; var list = new List<Dude2>(); var Selection = default(Dude2); Action<Dude2> SelectDude = i => { if (Selection != null) Selection.IsSelected = false; Selection = i; if (Selection != null) Selection.IsSelected = true; }; Action<Dude2> BindSelectDude = i => i.Control.onclick += delegate { SelectDude(i); }; Func<FrameInfo[], int, int, Dude2> SpawnLookingDude = (f, x, y) => { var r = new Dude2 { Frames = f, }; //BindSelectDude(r); r.AnimationInfo.Frames_Stand = f; r.Zoom.DynamicZoomFunc = a => (a + 400) / (800); r.Zoom.StaticZoom = 1; r.SetSize(48, 72); r.TeleportTo(x, y); r.Control.className = "cursorred"; r.Control.AttachToDocument(); r.Direction = Math.PI.Random() * 2; r.Control.onmousewheel += (ev) => { WheelAction(r, ev); }; list.Add(r); return r; }; Func<int> r400 = () => 400.Random() + 100; //SpawnLookingDude(Frames.PigCop, r400(), r400()).LookAtMouse(stage); //SpawnLookingDude(Frames.Trooper, r400(), r400()).LookAtMouse(stage); #region wolf3d // say hello to wolf3d // video: http://www.youtube.com/watch?v=ohDAKEEKyP8 // http://verdammt.ionichost.com/ var w1 = SpawnLookingDude(Frames.WolfSoldier, r400(), r400()); w1.Zoom.StaticZoom = 1.75; //w1.LookAtMouse(stage); w1.AnimationInfo.Frames_Walk = Frames.WolfSoldier_Walk; //w1.RawWalkSpeed = 0.01; BindSelectDude(w1); var w2 = SpawnLookingDude(Frames.WolfSoldier, r400(), r400()); w2.Zoom.StaticZoom = 1.75; w2.AnimationInfo.Frames_Walk = Frames.WolfSoldier_Walk; w2.WalkTo(new Point(r400(), r400())); BindSelectDude(w2); // doom var imp = SpawnLookingDude(Frames.DoomImp, r400(), r400()); imp.Zoom.StaticZoom = 1.75; imp.AnimationInfo.Frames_Walk = Frames.DoomImp_Walk; imp.WalkTo(new Point(r400(), r400())); //imp.RawWalkSpeed /= 4; BindSelectDude(imp); #endregion var shrek1 = SpawnLookingDude(Frames.Shrek, r400(), r400()); shrek1.Zoom.StaticZoom = 1.2; shrek1.AnimationInfo.Frames_Walk = new[] { Frames.Shrek }; //shrek1.WalkTo(new Point(r400(), r400())); //imp.RawWalkSpeed /= 4; //shrek1.LookAtMouse(stage); BindSelectDude(shrek1); var dragon1 = SpawnLookingDude(Frames.Dragon, r400(), r400()); dragon1.AnimationInfo.Frames_Walk = new[] { Frames.Dragon }; dragon1.Zoom.StaticZoom = 0.3; BindSelectDude(dragon1); var whitedog1 = SpawnLookingDude(Frames.WhiteDog, r400(), r400()); whitedog1.AnimationInfo.Frames_Walk = Frames.WhiteDog_Walk; BindSelectDude(whitedog1); var dragon2 = SpawnLookingDude(Frames.BabyDragon, r400(), r400()); dragon2.AnimationInfo.Frames_Walk = Frames.BabyDragon_Walk; BindSelectDude(dragon2); /* var runner = SpawnLookingDude(Frames.Duke, r400(), r400()); runner.AnimationInfo.Frames_Walk = Frames.Duke_Walk; runner.WalkTo(new Point(r400(), r400())); BindSelectDude(runner); */ stage.onmousemove += ev => { try { if (Selection != null) if (!Selection.IsWalking) Selection.LookAt(ev.CursorPosition); } catch { } /* foreach (var v in list.Where(i => i.AnimationInfo.Frames_Stand == Frames.Duke)) v.WalkTo(ev.CursorPosition); */ }; stage.onclick += (ev) => { if (ev.ctrlKey) if (Selection != null) { var n = SpawnLookingDude(Selection.AnimationInfo.Frames_Stand, ev.CursorX, ev.CursorY); n.AnimationInfo.Frames_Walk = Selection.AnimationInfo.Frames_Walk; n.Zoom.StaticZoom = Selection.Zoom.StaticZoom; BindSelectDude(n); SelectDude(n); return; } if (Selection != null) Selection.WalkTo(ev.CursorPosition); //SelectDude(null); /* var n = SpawnLookingDude(Frames.Duke, ev.CursorX, ev.CursorY); n.AnimationInfo.Frames_Walk = Frames.Duke_Walk;*/ }; stage.onmousewheel += (ev) => { foreach (var v in list) { WheelAction(v, ev); } }; }