void RefreshDisplay() { OutputState os = PrepareCalculators(); if (os != null) { // Refresh result label immediately string resultText = null; try { foreach (var c in os.Calcs) { resultText = resultText == null ? "" : resultText + ", "; resultText += CalculatorCore.Eval(c.Expr, c.Vars); } txtResult.Enabled = true; } catch (Exception e) { if (resultText == null) { resultText = e.Message; } txtResult.Enabled = false; } txtResult.Text = resultText; if (_bw.IsBusy) { _refreshRequested = true; return; } os.Bitmap = new DirectBitmap(graphPanel.ClientSize); _bw.RunWorkerAsync(os); } }
DirectBitmap _prevBitmap; // bitmap used in most recent frame (often same as current) public CalcForm() { InitializeComponent(); // Prepare to calculate and draw on a background thread _bw.DoWork += (s, e) => { var state = (OutputState)(e.Result = e.Argument); try { foreach (var c in state.Calcs) { c.Run(); // do calculations } state.RenderAll(); } catch { if (state.Bitmap != _outState?.Bitmap) { state.Bitmap.Dispose(); // the new bitmap won't be used } throw; } }; _bw.RunWorkerCompleted += (s, e) => { if (panelError.Visible = (e.Error != null)) { txtError.Text = e.Error.Message; } else { _outState = (OutputState)e.Result; if (_prevBitmap != _outState.Bitmap) { using (_prevBitmap) _prevBitmap = _outState.Bitmap; } graphPanel.Image = _prevBitmap.Bitmap; } if (_refreshRequested) { _refreshRequested = false; RefreshDisplay(); } }; }
public static GraphRange New(string rangeName, LNode range, int numPixels, Dictionary <Symbol, LNode> varDict) { if (range == null) { return new GraphRange(-1, 1, numPixels, Pens.MidnightBlue, null) { AutoRange = true } } ; if (range.Calls(CodeSymbols.Colon, 2) && range[0].IsId && string.Compare(range[0].Name.Name, rangeName, true) == 0) { range = range[1]; // ignore axis prefix like "x:" or "y:" } if (range.Calls(CodeSymbols.Sub, 2) || range.Calls(CodeSymbols.DotDot, 2)) { double lo = CalculatorCore.Eval(range[0], varDict); double hi = CalculatorCore.Eval(range[1], varDict); Pen pen = OutputState.MakePen(range); string label = range.Attrs.Select(a => a.Value as string).FirstOrDefault(s => s != null); var result = new GraphRange(lo, hi, numPixels, pen, label) { RangeExpr = range }; foreach (var attr in range.Attrs) { if (attr.Value is int) { result.RoughLineCount = (int)attr.Value; } } return(result); } throw new FormatException("Invalid range for {axis}: {range}".Localized("axis", rangeName, "range", range)); } }