public void zSetMarginWidth(int margin, int value, bool dpiScale = true, bool chars = false) { if (dpiScale && value > 0) { var a = _marginDpi ??= new int[Call(SCI_GETMARGINS)]; if (chars) { value *= zStyleMeasureStringWidth(STYLE_LINENUMBER, "8"); a[margin] = Dpi.Unscale(value, _dpi).ToInt(); } else { a[margin] = value; value = Dpi.Scale(value, _dpi); } } else { var a = _marginDpi; if (a != null) { a[margin] = 0; } } Call(SCI_SETMARGINWIDTHN, margin, value); }
public void Show(SciCode doc, int position, List <CiComplItem> a, List <string> groups) { if (a.NE_()) { Hide(); return; } _a = a; _groups = groups; _groupsEnabled = _groups != null && _groupButton.IsChecked == true; _doc = doc; foreach (var v in _kindButtons) { v.IsChecked = false; } _groupButton.Visibility = _groups != null ? Visibility.Visible : Visibility.Collapsed; UpdateVisibleItems(); var r = CiUtil.GetCaretRectFromPos(_doc, position, inScreen: true); r.left -= Dpi.Scale(50, _doc); _popup.ShowByRect(_doc, Dock.Bottom, r); }
/// <summary> /// Raised when the form is painted /// </summary> /// <param name="e"></param> protected override void OnPaint(PaintEventArgs e) { using (var buffer = new Bitmap(Bounds.Width, Bounds.Height)) { using (var g = GraphicsEx.FromImage(buffer)) { g.GradientFill( Bounds, Color.DarkBlue, Color.LightBlue, GradientFillDirection.Vertical); using (var font = FontFactory.CreateRotatedFont(Font.Name, 50)) { var size = g.Surface.MeasureString(Text, font); var x = (Bounds.Width - size.Width) / 2f; using (var brush = new SolidBrush(ForeColor)) g.Surface.DrawString(Text, font, brush, x, Dpi.Scale(5)); } } e.Graphics.DrawImage(buffer, 0, 0); } }
/// <summary> /// Creates an instance of <see cref="Sidebar"/> /// </summary> public Sidebar() { base.Location = new Point(0, 0); base.Size = new Size(Dpi.Scale(25), Screen.PrimaryScreen.WorkingArea.Height); base.Dock = DockStyle.Left; base.ForeColor = Color.White; }
Size _Measure() { _dpi = Dpi.OfWindow(_w); int i = _cellSize = Dpi.Scale(10, _dpi); var z = new SIZE(i, i); z.width *= c_nHue; z.width++; z.height *= c_nLum + 1; z.height++; z.height += _cellSize / 4; return(Dpi.Unscale(z, _dpi)); }
//public void zSetMarginWidth(int margin, string textToMeasureWidth) { // int n = zStyleMeasureStringWidth(STYLE_LINENUMBER, textToMeasureWidth); // Call(SCI_SETMARGINWIDTHN, margin, n + 4); //} //not used //public int zGetMarginWidth(int margin, bool dpiUnscale) { // int R = Call(SCI_GETMARGINWIDTHN, margin); // if (dpiUnscale && R > 0) { // var a = _marginDpi; // var v = a?[margin] ?? 0; // if (v > 0) R = v; // } // return R; //} internal void zMarginWidthsDpiChanged_() { var a = _marginDpi; if (a == null) { return; } for (int i = a.Length; --i >= 0;) { if (a[i] > 0) { Call(SCI_SETMARGINWIDTHN, i, Dpi.Scale(a[i], _dpi)); } } }
protected override void ZOnHandleCreated() { base.ZOnHandleCreated(); zStyleBackColor(Sci.STYLE_DEFAULT, 0xf8fff0); if (ZInitUseSystemFont) { zStyleFont(Sci.STYLE_DEFAULT); //Segoe UI 9 is narrower but taller than the default Verdana 8. Also tested Calibri 9, but Verdana looks better. } zStyleClearAll(); zSetMarginWidth(1, 0); SIZE z = ZInitBlankMargins; z = Dpi.Scale(z, this.Hwnd); Call(Sci.SCI_SETMARGINLEFT, 0, z.width); Call(Sci.SCI_SETMARGINRIGHT, 0, z.height); }
/// <summary> /// Takes screenshot of specified rectangle in screen, quantizes colors to make smaller, compresses, Base64 encodes and returns comment string like <c>" /*image:...*/"</c>. /// If fails, prints warning and returns null. /// </summary> public static string MakeScreenshotComment(RECT r, DpiOf dpi = default) { if (dpi != default) { int i = dpi.Dpi; if (i != 96) { r.Inflate((Dpi.Scale(r.Width, i) - r.Width) / 2, (Dpi.Scale(r.Height, i) - r.Height) / 2); } } try { var b = uiimage.capture(r); var a = Quantize(b, 16); var z = Convert2.BrotliCompress(a); return("/*image:" //+ "\r\n" //rejected + "WkJN" + Convert.ToBase64String(z) + "*/"); } catch (Exception e1) { print.warning("MakeScreenshotComment() failed. " + e1.ToStringWithoutStack()); return(null); } }
private void DrawImage(GraphicsEx gxOff) { if (image == null) { return; } var imageAttr = new ImageAttributes(); using (var bmp = new Bitmap(image)) { var transparentKey = bmp.GetPixel(1, 1); imageAttr.SetColorKey(transparentKey, transparentKey); } //var imgRect = Dpi.ScaleRectangle((Width - image.Width) / 2, 5, image.Width, image.Height); int width = Dpi.Scale(image.Width); int height = Dpi.Scale(image.Height); var imgRect = new Rectangle((Width - width) / 2, Dpi.Scale(5), width, height); gxOff.Surface.DrawImage(image, imgRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imageAttr); }
void _WmMousemove(POINT pc) { if (!_paintedOnce) { return; } //format text to draw below magnifier string text; using (new StringBuilder_(out var s)) { var ic = _flags & (ICFlags.Image | ICFlags.Color | ICFlags.Rectangle); if (ic == 0) { ic = ICFlags.Image | ICFlags.Color; } bool canColor = ic.Has(ICFlags.Color); if (canColor) { var color = _img.GetPixel(pc.x, pc.y).ToArgb() & 0xffffff; s.Append("Color #").Append(color.ToString("X6")).Append('\n'); } if (ic == ICFlags.Color) { s.Append("Click to capture color.\n"); } else if (ic == ICFlags.Rectangle) { s.Append("Mouse-drag to capture rectangle.\n"); } else if (!canColor) { s.Append("Mouse-drag to capture image.\n"); } else { s.Append("Mouse-drag to capture image,\nor Ctrl+click to capture color.\n"); } s.Append("More: right-click"); //" cancel: key Esc\n retry: key F3 ... F3" text = s.ToString(); } var font = NativeFont_.RegularCached(_dpi); int magnWH = Dpi.Scale(200, _dpi) / 10 * 10; //width and height of the magnified image without borders etc if (_textSize == default) { using (var tr = new FontDC_(font)) _textSize = tr.MeasureDT(text, TFFlags.NOPREFIX); } int width = Math.Max(magnWH, _textSize.width) + 2, height = magnWH + 4 + _textSize.height; using var mb = new MemoryBitmap(width, height); var dc = mb.Hdc; using var wdc = new WindowDC_(_w); //draw frames and color background. Also erase magnifier, need when near screen edges. Api.FillRect(dc, (0, 0, width, height), Api.GetStockObject(4)); //BLACK_BRUSH //copy from captured screen image to magnifier image. Magnify 5 times. int k = magnWH / 10; Api.StretchBlt(dc, 1, 1, magnWH, magnWH, wdc, pc.x - k, pc.y - k, k * 2, k * 2, Api.SRCCOPY); //draw red crosshair k = magnWH / 2; using (var pen = new Pen_(0xff)) { pen.DrawLine(dc, (k, 1), (k, magnWH + 1)); pen.DrawLine(dc, (1, k), (magnWH + 1, k)); } //draw text below magnifier var rc = new RECT(1, magnWH + 2, _textSize.width, _textSize.height); Api.SetTextColor(dc, 0x32CD9A); //Color.YellowGreen Api.SetBkMode(dc, 1); var oldFont = Api.SelectObject(dc, font); Api.DrawText(dc, text, ref rc, TFFlags.NOPREFIX); Api.SelectObject(dc, oldFont); //set magninifier position far from cursor var pm = new POINT(4, 4); _w.MapScreenToClient(ref pm); int xMove = magnWH * 3; if (_magnMoved) { pm.Offset(xMove, 0); } var rm = new RECT(pm.x, pm.y, width, height); rm.Inflate(magnWH / 2, magnWH / 2); if (rm.Contains(pc)) { Api.InvalidateRect(_w, (pm.x, pm.y, width, height)); _magnMoved ^= true; pm.Offset(_magnMoved ? xMove : -xMove, 0); } Api.BitBlt(wdc, pm.x, pm.y, width, height, dc, 0, 0, Api.SRCCOPY); }
/// <summary> /// Draws the control in normal or pushed states /// </summary> /// <param name="e">Paitn event</param> protected override void OnPaint(PaintEventArgs e) { var attributes = new ImageAttributes(); using (var g = Graphics.FromImage(MemoryBitmap)) { if (Pushed) { using (var pen = new Pen(Theme.ThemeBase)) GraphicsExtensions.DrawThemedGradientRectangle(g, pen, ClientRectangle, Dpi.ScaleSize(new Size(8, 8))); } else { g.Clear(Parent.BackColor); } var textSize = g.MeasureString(Text, Font); var textArea = new RectangleF((ClientSize.Width - textSize.Width) / 2, (ClientSize.Height - textSize.Height), textSize.Width, textSize.Height); if (Image != null) { var imageWidth = Dpi.Scale(Image.Width); var imageHeight = Dpi.Scale(Image.Height); var imageArea = new Rectangle((ClientSize.Width - imageWidth) / 2, (ClientSize.Height - imageHeight) / 2, imageWidth, imageHeight); var key = Image.GetPixel(0, 0); attributes.SetColorKey(key, key); g.DrawImage(Image, StretchImage ? ClientRectangle : imageArea, 0, 0, Image.Width, Image.Height, GraphicsUnit.Pixel, attributes); } using (var brush = new SolidBrush(ForeColor)) g.DrawString(Text, Font, brush, textArea); if (Pushed) { var key = MemoryBitmap.GetPixel(0, 0); attributes.SetColorKey(key, key); } else { attributes.ClearColorKey(); } e.Graphics.DrawImage(MemoryBitmap, ClientRectangle, 0, 0, MemoryBitmap.Width, MemoryBitmap.Height, GraphicsUnit.Pixel, attributes); } }
SIZE _Scale(System.Windows.Size z) => _NeedScaling(false) ? Dpi.Scale(z, _dpi) : SIZE.From(z, true);
public _Metrics(popupMenu m) { foreach (var b in m._a) { if (b.IsSeparator) { hasSeparators = true; } else { if (b.HasImage_) { hasImages = true; } if (b.checkType > 0) { hasCheck = true; } if (b.IsSubmenu) { hasSubmenus = true; } if (b.Hotkey != null) { hasHotkeys = true; } } } int dpi = m._dpi; bBorder = dpi / 96; textPaddingX = Dpi.Scale(8, dpi); textPaddingY = Dpi.Scale(1, dpi); if (hasImages) { image = Dpi.Scale(16, dpi); } if (hasCheck) { check = Dpi.Scale(18, dpi); } if (hasSubmenus) { submenu = Dpi.Scale(16, dpi); } separator = Dpi.Scale(8, dpi); sepLine = 2; theme = Api.OpenThemeData(m._w, "Menu"); if (theme != default) { using var dc = new ScreenDC_(); if (hasSubmenus) { Api.GetThemePartSize(theme, dc, 16, 1, null, Api.THEMESIZE.TS_TRUE, out zSubmenu); submenu = Math.Max(submenu, zSubmenu.width + submenu / 4); } if (hasCheck) { Api.GetThemePartSize(theme, dc, 11, 1, null, Api.THEMESIZE.TS_TRUE, out zCheck); check = Math.Max(check, zCheck.width + 2); } if (hasSeparators && 0 == Api.GetThemePartSize(theme, dc, 15, 0, null, Api.THEMESIZE.TS_TRUE, out var k)) { sepLine = k.height; } } submenuMargin = hasHotkeys ? 0 : submenu; }
async void _ShowSignature(SciCode doc, char ch, bool methodCompletion = false) { //using var p1 = perf.local(); if (!CodeInfo.GetContextAndDocument(out var cd, -2) || cd.pos < 2) { return; //returns false if position is in meta comments } _cancelTS?.Cancel(); _cancelTS = new CancellationTokenSource(); var cancelTS = _cancelTS; var cancelToken = cancelTS.Token; #if DEBUG if (Debugger.IsAttached) { cancelToken = default; _cancelTS = null; } #endif SyntaxNode root = null; //ISignatureHelpProvider provider = null; SignatureHelpItems r = null; try { //could be sync, quite fast, but then sometimes reenters (GetItemsAsync waits/dispatches) and sometimes hangs r = await Task.Run(async() => { //p1.Next(); root = cd.syntaxRoot; //p1.Next('r'); var providers = _SignatureHelpProviders; //print.it(providers); SignatureHelpItems r = null; var trigger = new SignatureHelpTriggerInfo(ch == default ? SignatureHelpTriggerReason.InvokeSignatureHelpCommand : SignatureHelpTriggerReason.TypeCharCommand, ch); foreach (var p in providers) { //print.it(p); var r2 = await p.GetItemsAsync(cd.document, cd.pos, trigger, SignatureHelpOptions.Default, cancelToken).ConfigureAwait(false); if (cancelToken.IsCancellationRequested) /*print.it("IsCancellationRequested");*/ return { (null); } //often if (r2 == null) { continue; } if (r == null || r2.ApplicableSpan.Start > r.ApplicableSpan.Start) { r = r2; //provider = p; } //Example: 'print.it(new Something())'. // The first provider probably is for Write (invocation). // Then the second is for Something (object creation). // We need the innermost, in this case Something. } return(r); }); } catch (OperationCanceledException) { /*Debug_.Print("canceled");*/ return; } //never noticed //catch (AggregateException e1) when (e1.InnerException is TaskCanceledException) { return; } finally { cancelTS.Dispose(); if (cancelTS == _cancelTS) { _cancelTS = null; } } //print.it(r, cancelToken.IsCancellationRequested); if (cancelToken.IsCancellationRequested) { return; } if (r == null) { _CancelUI(); return; } Debug.Assert(doc == Panels.Editor.ZActiveDoc); //when active doc changed, cancellation must be requested if (cd.pos != doc.zCurrentPos16 || (object)cd.code != doc.zText) { return; //changed while awaiting } //p1.Next('s'); //print.it($"<><c orange>pos={cd.pos}, span={r.ApplicableSpan}, nItems={r.Items.Count}, argCount={r.ArgumentCount}, argIndex={r.ArgumentIndex}, argName={r.ArgumentName}, sel={r.SelectedItemIndex}, provider={provider}<>"); //get span of the arglist. r.ApplicableSpan.Start is of the statement, not of the arglist. In chained methods it is the chain start. var fullSpan = r.ApplicableSpan; //CiUtil.HiliteRange(fullSpan); wait.doEvents(500); var start = fullSpan.Start; var tok = root.FindToken(cd.pos); if (tok.Kind() is SyntaxKind.OpenParenToken or SyntaxKind.OpenBracketToken or SyntaxKind.LessThanToken) { tok = tok.GetPreviousToken(); } var argNode = tok.Parent; while (argNode != null) { int i = argNode.SpanStart; if (i <= start) { break; } if (argNode is BaseArgumentListSyntax or AttributeArgumentListSyntax or TypeArgumentListSyntax) { start = i + 1; break; } //CiUtil.PrintNode(argNode); argNode = argNode.Parent; } var argSpan = new TextSpan(start, fullSpan.End - start); //CiUtil.PrintNode(argNode); CiUtil.HiliteRange(argSpan); //print.it(argSpan); var span = new _Span(argSpan, cd.code); int iSel = 0, iSel2 = 0; if (r.Items.Count > 1) { iSel2 = r.SelectedItemIndex ?? -1; if (_data?.IsSameArglist(span, r) ?? false) { iSel = _data.iUserSelected; //preserve user selection in same session if (iSel2 < 0) { iSel2 = _data.iRoslynSelected; //on error use last good Roslyn selection in same session, like in VS } } else { iSel = -1; } } _data = new _Data { r = r, span = span, iUserSelected = iSel, iRoslynSelected = iSel2, sci = doc, }; if (iSel < 0) { iSel = iSel2; } if (iSel < 0) { //r.SelectedItemIndex is null when cannot resolve overloads, eg when arglist is partially typed. Example: wnd.find(1, ); iSel = r.SelectedItemIndex ?? (r.ArgumentCount == 0 ? 0 : -1); if (iSel < 0) { for (int i = 0; i < r.Items.Count; i++) { if (r.Items[i].Parameters.Length >= r.ArgumentCount) { iSel = i; break; } } if (iSel < 0) { for (int i = 0; i < r.Items.Count; i++) { if (r.Items[i].IsVariadic) { iSel = i; break; } } if (iSel < 0) { iSel = 0; } } } } doc.ZTempRanges_Add(this, argSpan.Start, argSpan.End, onLeave: () => { if (doc.ZTempRanges_Enum(doc.zCurrentPos8, this, utf8: true).Any()) { return; } _CancelUI(); }, SciCode.ZTempRangeFlags.NoDuplicate); var rect = RECT.Union(CiUtil.GetCaretRectFromPos(doc, fullSpan.Start), CiUtil.GetCaretRectFromPos(doc, cd.pos)); doc.Hwnd.MapClientToScreen(ref rect); rect.Width += Dpi.Scale(200, doc.Hwnd); rect.left -= 6; _textPopup ??= new CiPopupText(CiPopupText.UsedBy.Signature, onHiddenOrDestroyed: (_, _) => _data = null) { OnLinkClick = (ph, e) => ph.Text = _FormatText(e.ToInt(1), userSelected: true) }; _textPopup.Text = _FormatText(iSel, userSelected: false); if (!_textPopup.IsVisible) { CodeInfo.HideTextPopupAndTempWindows(); if (CodeInfo._compl.IsVisibleUI) //without this does not show completions with selected enum when typed Function( when first parameter is enum { CodeInfo._compl.Cancel(); } if (methodCompletion) { CodeInfo._compl.ShowList(ch); //when autocompletion added (); may need to show enum list } } _textPopup.Show(Panels.Editor.ZActiveDoc, rect, System.Windows.Controls.Dock.Bottom); //also show Keys/Regex tool? //CiUtil.PrintNode(node); if (argNode is ArgumentListSyntax or BracketedArgumentListSyntax && cd.code.Eq(cd.pos - 1, "\"\"")) { //print.it("string"); var semo = cd.semanticModel; var token = root.FindToken(cd.pos); if (true == token.IsInString(cd.pos, cd.code, out var stringInfo)) { var stringFormat = CiUtil.GetParameterStringFormat(stringInfo.stringNode, semo, true); if (stringFormat != 0) { CodeInfo._tools.ShowForStringParameter(stringFormat, cd, stringInfo, _textPopup.PopupWindow.Hwnd); } } } }