void _DrawItem(AuListControl.ZItemDrawArgs e) { //var p1 = APerf.Create(); var g = e.graphics; var ci = _VisibleItem(e.index); var r = e.bounds; int xText = _TextHorzOffset; var sym = ci.FirstSymbol; //draw images: kind, access, static/abstract var imageKind = ci.KindImage; if (imageKind != null) { int imgX = r.X + Au.Util.ADpi.ScaleInt(18); int imgY = (r.Y + r.Bottom + 1) / 2 - imageKind.Height / 2; int overlayX = r.X + Au.Util.ADpi.ScaleInt(4); int overlayY = imgY + Au.Util.ADpi.ScaleInt(4); g.DrawImage(imageKind, imgX, imgY, imageKind.Width, imageKind.Height); //note: would be very slow, but is very fast if DoubleBuffered = true (the control sets it in ctor). var imageAccess = ci.AccessImage; if (imageAccess != null) { g.DrawImage(imageAccess, overlayX, overlayY, imageAccess.Width, imageAccess.Height); } if (sym != null) { Bitmap b = null; if (sym.IsStatic && ci.kind != CiItemKind.Constant && ci.kind != CiItemKind.EnumMember && ci.kind != CiItemKind.Namespace) { b = _imgStatic; } else if (ci.kind == CiItemKind.Class && sym.IsAbstract) { b = _imgAbstract; } if (b != null) { g.DrawImage(b, overlayX, overlayY, b.Width, b.Height); } } } //p1.Next(); //draw selection r.Width -= xText; r.X += xText; if (e.isSelected) { g.FillRectangle(s_selectedBrush, r); } //draw text var s = ci.DisplayText; ADebug.PrintIf(!ci.ci.DisplayTextPrefix.NE(), s); //we don't support prefix; never seen. int xEndOfText = 0; using (var tr = new GdiTextRenderer(g)) { ColorInt color = ci.moveDown.HasAny(CiItemMoveDownBy.Name | CiItemMoveDownBy.FilterText) ? 0x808080 : 0; tr.MoveTo(r.X, r.Y); if (ci.hilite != 0) { ulong h = ci.hilite; for (int normalFrom = 0, boldFrom, boldTo, to = s.Length; normalFrom < to; normalFrom = boldTo) { for (boldFrom = normalFrom; boldFrom < to && 0 == (h & 1); boldFrom++) { h >>= 1; } tr.DrawText(s, color, normalFrom, boldFrom); if (boldFrom == to) { break; } for (boldTo = boldFrom; boldTo < to && 0 != (h & 1); boldTo++) { h >>= 1; } tr.FontBold(); tr.DrawText(s, color, boldFrom, boldTo); tr.FontNormal(); } } else { tr.DrawText(s, color); } if (ci.moveDown.Has(CiItemMoveDownBy.Obsolete)) { xEndOfText = tr.GetCurrentPosition().x; } string green = _GreenSuffix(e.index); if (green != null) { tr.DrawText(green, 0x40A000); } } //draw red line over obsolete items if (ci.moveDown.Has(CiItemMoveDownBy.Obsolete)) { int vCenter = r.Y + r.Height / 2; g.DrawLine(Pens.OrangeRed, r.X, vCenter, xEndOfText, vCenter); } //p1.NW('i'); //draw group separator if (e.index > 0) { var cip = _VisibleItem(e.index - 1); if (cip.moveDown != ci.moveDown || (_groupsEnabled && cip.group != ci.group)) { g.DrawLine(Pens.YellowGreen, 0, r.Y, r.Right, r.Y); } } }
//public bool DrawBackground() { //} //public bool DrawCheckbox() { //} //public bool DrawImage(System.Drawing.Bitmap image) { //} public bool DrawText() { var ci = _cd.item as CiComplItem; var s = _cd.item.DisplayText; Range black, green; if (ci.commentOffset == 0) { black = ..s.Length; green = default; } else { black = ..ci.commentOffset; green = ci.commentOffset..; } int xEndOfText = 0; int color = ci.moveDown.HasAny(CiComplItemMoveDownBy.Name | CiComplItemMoveDownBy.FilterText) ? 0x808080 : _textColor; _tr.MoveTo(_cd.xText, _cd.yText); if (ci.hilite != 0) { ulong h = ci.hilite; for (int normalFrom = 0, boldFrom, boldTo, to = black.End.Value; normalFrom < to; normalFrom = boldTo) { for (boldFrom = normalFrom; boldFrom < to && 0 == (h & 1); boldFrom++) { h >>= 1; } _tr.DrawText(s, color, normalFrom..boldFrom); if (boldFrom == to) { break; } for (boldTo = boldFrom; boldTo < to && 0 != (h & 1); boldTo++) { h >>= 1; } _tr.FontBold(); _tr.DrawText(s, color, boldFrom..boldTo); _tr.FontNormal(); } } else { _tr.DrawText(s, color, black); } if (ci.moveDown.Has(CiComplItemMoveDownBy.Obsolete)) { xEndOfText = _tr.GetCurrentPosition().x; } if (ci.commentOffset > 0) { _tr.DrawText(s, 0x00A040, green); } //draw red line over obsolete items if (ci.moveDown.Has(CiComplItemMoveDownBy.Obsolete)) { int vCenter = _cd.rect.top + _cd.rect.Height / 2; _cd.graphics.DrawLine(System.Drawing.Pens.OrangeRed, _cd.xText, vCenter, xEndOfText, vCenter); } return(true); }
//Called on resize, scroll, set visible items (replace, clear, expand/collapse, add/remove/move). void _Measure(bool onScroll = false) { if (_dontMeasure) { return; //this func is adding/removing scrollbars } EndEditLabel(); _labeltip?.Hide(); int sbV = More.Dpi.ScrollbarV_(_dpi), sbH = More.Dpi.ScrollbarH_(_dpi); var rw = _w.Rect; //never mind: minus border. Currently we don't use border. OK even if used, if just 1-pixel border and no caption. int width = rw.Width, height = rw.Height; if (width <= sbV || height <= sbH || _avi.NE_()) { NativeScrollbar_.ShowVH(_vscroll, false, _hscroll, false); return; } var range = _GetViewRange(onScroll ? _height : height); //print.it("_Measure", range.from, range.to); int maxWidth = _itemsWidth; GdiTextRenderer tr = null; for (int i = range.from; i < range.to; i++) { if (_avi[i].measured > 0) { continue; } tr ??= new GdiTextRenderer(_dpi); bool bold = _avi[i].item.IsBold; if (bold) { tr.FontBold(); } var z = tr.MeasureText(_avi[i].item.DisplayText); if (bold) { tr.FontNormal(); } int wid = ++z.width + _imageSize * (_avi[i].level + 1) + _imageMarginX * 2 + _marginLeft + _marginRight; if (HasCheckboxes) { wid += _itemHeight; } if (wid > maxWidth) { maxWidth = wid; } _avi[i].measured = (ushort)Math.Clamp(z.width, 1, ushort.MaxValue); } tr?.Dispose(); if (maxWidth > _itemsWidth) { _itemsWidth = maxWidth; } else if (onScroll) { return; } //set scrollbars int itemsHeight = _avi.Length * _itemHeight; bool needH = _itemsWidth > width && height >= _imageSize + sbH; if (needH) { height -= sbH; } bool needV = itemsHeight > height && _avi.Length > 1; if (needV) { width -= sbV; if (!needH) { needH = _itemsWidth > width && height >= _imageSize + sbH; } } //print.it(needH, needV); if (_scrollCorrection = (needH && onScroll && _inScrollbarScroll && !_hscroll.Visible)) { needH = false; } _dontMeasure = true; NativeScrollbar_.ShowVH(_vscroll, needV, _hscroll, needH); _dontMeasure = false; if (needV) { _vscroll.SetRange(_avi.Length); } else { _vscroll.NItems = _avi.Length; } if (needH) { _hscroll.SetRange(_itemsWidth / _imageSize); } else { _hscroll.NItems = 0; } }