using FastReport.Utils; using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace FastReport.Controls { internal class ToolStripZoomControl : ToolStripItem { private bool hlButton1; private bool hlButton2; private bool hlButton3; private bool hlMinus; private bool hlPlus; private bool movingSlider; private int Minimum { get; set; } private int Maximum { get; set; } private int _value; private int Value { get => _value; set { if (value < Minimum) value = Minimum; if (value > Maximum) value = Maximum; _value = value; ValueChanged?.Invoke(this, EventArgs.Empty); Invalidate(); } } public float ZoomValue { get { float val = Value; if (val < 100) val = val * 0.75f + 25; else val = (val - 100) * 4 + 100; return val / 100f; } set { if (value < 1) value = (value - 0.25f) / 0.75f; else if (value > 1) value = (value - 1) / 4 + 1; Value = (int)Math.Round(value * 100); } } private int Step { get; set; } private UIStyle style; public UIStyle UIStyle { get => style; set { style = value; Invalidate(); } } public event EventHandler ValueChanged; public event EventHandler ZoomPageWidthClick; public event EventHandler ZoomWholePageClick; public event EventHandler Zoom100Click; private void PaintBackground(Graphics g) { Rectangle rect = new Rectangle(0, 0, Width, Height); var colorTable = UIStyleUtils.GetColorTable(UIStyle); using (var brush = new LinearGradientBrush(rect, colorTable.Workspace.ZoomControl.GradientBegin, colorTable.Workspace.ZoomControl.GradientEnd, 90)) g.FillRectangle(brush, rect); using (var pen = new Pen(colorTable.GripDark)) g.DrawLine(pen, 0, 0, 0, Height); using (var pen = new Pen(colorTable.GripLight)) g.DrawLine(pen, 1, 0, 1, Height); } private void PaintHighlight(Graphics g, Rectangle rect) { int _22 = Owner.LogicalToDevice(22); var colorTable = UIStyleUtils.GetColorTable(UIStyle); using (var brush = new LinearGradientBrush(rect, colorTable.ButtonSelectedGradientBegin, colorTable.ButtonSelectedGradientEnd, 90)) g.FillRectangle(brush, rect); using (var pen = new Pen(colorTable.ButtonSelectedHighlightBorder, (int)Math.Round(Owner.LogicalToDevice(1f)))) g.DrawRectangle(pen, rect); } private void PaintButton(Graphics g, int imageIndex, int x, int baseLine, bool highlight) { var bmp = Owner.GetImage(imageIndex); if (highlight) { int _22 = Owner.LogicalToDevice(22); PaintHighlight(g, new Rectangle(x, baseLine - _22 / 2, _22, _22)); } int _3 = Owner.LogicalToDevice(3); int _16 = Owner.LogicalToDevice(16); g.DrawImage(bmp, new Rectangle(x + _3, baseLine - _16 / 2, _16, _16)); } private void PaintText(Graphics g, int x) { Color foreColor = UIStyleUtils.GetColorTable(UIStyle).Workspace.ZoomControl.Foreground; TextRenderer.DrawText(g, ((int)(Math.Round(ZoomValue * 100))).ToString() + "%", Font, new Rectangle(x, 0, Owner.LogicalToDevice(40), Height), foreColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter); } private void PaintSlider(Graphics g, int x, int baseLine) { int btnSize = Owner.LogicalToDevice(11); int thumb = Owner.LogicalToDevice(5); int gap = Owner.LogicalToDevice(20); int padRight = Owner.LogicalToDevice(8); int _1 = (int)Math.Round(Owner.LogicalToDevice(1f)); int _2 = _1 + _1; int _3 = Owner.LogicalToDevice(3) + 1; int _6 = Owner.LogicalToDevice(6) + 1; int y = baseLine; var colorTable = UIStyleUtils.GetColorTable(UIStyle); Color foreColor = colorTable.Workspace.ZoomControl.Foreground; Color altColor = Color.Black; Pen p = new Pen(foreColor, _1); Pen p1 = new Pen(altColor, _1); Brush b = new SolidBrush(foreColor); Brush b1 = new SolidBrush(altColor); // minus if (hlMinus) PaintHighlight(g, new Rectangle(x - _3, y - btnSize / 2 - _3, btnSize + _6, btnSize + _6)); g.DrawLine(hlMinus ? p1 : p, x, y, x + btnSize - 1, y); // line x += gap; g.DrawLine(p, x, y, Width - gap - padRight, y); // thumb int lineWidth = Width - gap - padRight - x; int pos = lineWidth * (Value - Minimum) / (Maximum - Minimum) + x; g.FillRectangle(b, pos - thumb / 2, y - btnSize / 2, thumb, btnSize); g.FillRectangle(b1, pos - thumb / 2 + _1, y - btnSize / 2 + _1, thumb - _2, btnSize - _2); // plus x = Width - padRight - btnSize; if (hlPlus) PaintHighlight(g, new Rectangle(x - _3, y - btnSize / 2 - _3, btnSize + _6, btnSize + _6)); g.DrawLine(hlPlus? p1 : p, x, y, x + btnSize - 1, y); g.DrawLine(hlPlus ? p1 : p, x + btnSize / 2, y - btnSize / 2, x + btnSize / 2, y + btnSize / 2); p.Dispose(); p1.Dispose(); b.Dispose(); b1.Dispose(); } private void ResetHighlight() { hlButton1 = false; hlButton2 = false; hlButton3 = false; hlMinus = false; hlPlus = false; } protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; PaintBackground(g); int gap = Owner.LogicalToDevice(6); int btnSize = Owner.LogicalToDevice(22); int textSize = Owner.LogicalToDevice(40); int x = gap; int baseLine = Height / 2; PaintButton(g, 235, x, baseLine, hlButton1); x += btnSize; PaintButton(g, 236, x, baseLine, hlButton2); x += btnSize; PaintButton(g, 237, x, baseLine, hlButton3); x += btnSize + gap; PaintText(g, x); x += textSize + gap; PaintSlider(g, x, baseLine); } protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); int padRight = Owner.LogicalToDevice(8); int gap = Owner.LogicalToDevice(6); int btnSize = Owner.LogicalToDevice(22); int textSize = Owner.LogicalToDevice(40); int lineGap = Owner.LogicalToDevice(20); int mouseX = e.X; if (Config.IsRunningOnMono) { mouseX -= this.Bounds.Left; } movingSlider = false; if (e.Button == MouseButtons.Left) { // slider area int lineStart = gap * 3 + btnSize * 3 + textSize + lineGap; int lineWidth = Width - padRight - lineGap - lineStart; if (mouseX >= lineStart && mouseX <= lineStart + lineWidth) { Value = (mouseX - lineStart) * (Maximum - Minimum) / lineWidth + Minimum; movingSlider = true; } } } protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); int padRight = Owner.LogicalToDevice(8); int gap = Owner.LogicalToDevice(6); int btnSize = Owner.LogicalToDevice(22); int textSize = Owner.LogicalToDevice(40); int sz = Owner.LogicalToDevice(11); int lineGap = Owner.LogicalToDevice(20); int baseLine = Height / 2; int _3 = Owner.LogicalToDevice(3); int mouseX = e.X; int mouseY = e.Y; if (Config.IsRunningOnMono) { mouseX -= this.Bounds.Left; } ResetHighlight(); if (movingSlider) { // slider area int lineStart = gap * 3 + btnSize * 3 + textSize + lineGap; int lineWidth = Width - padRight - lineGap - lineStart; if (mouseX >= lineStart && mouseX <= lineStart + lineWidth) { Value = (mouseX - lineStart) * (Maximum - Minimum) / lineWidth + Minimum; } } else { int x = gap; if (mouseY > baseLine - btnSize / 2 && mouseY < baseLine + btnSize / 2) { // hit test buttons hlButton1 = mouseX > x && mouseX < x + btnSize; x += btnSize; hlButton2 = mouseX > x && mouseX < x + btnSize; x += btnSize; hlButton3 = mouseX > x && mouseX < x + btnSize; // hit text + - x = gap * 3 + btnSize * 3 + textSize; hlMinus = mouseX > x - _3 && mouseX < x + sz + _3; x = Width - padRight - sz; hlPlus = mouseX > x - _3 && mouseX < x + sz + _3; } } Invalidate(); } protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); if (e.Button == MouseButtons.Left) { if (hlButton1) ZoomPageWidthClick?.Invoke(this, EventArgs.Empty); else if (hlButton2) ZoomWholePageClick?.Invoke(this, EventArgs.Empty); else if (hlButton3) Zoom100Click?.Invoke(this, EventArgs.Empty); else if (hlMinus) Value -= Step; else if (hlPlus) Value += Step; } movingSlider = false; ResetHighlight(); Invalidate(); } protected override void OnMouseLeave(EventArgs e) { base.OnMouseLeave(e); ResetHighlight(); Invalidate(); } public ToolStripZoomControl() { Maximum = 200; Value = 100; Step = 5; AutoSize = false; } } }