using System;
using System.Collections;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
using FastReport.Utils;
using FastReport.Editor;
using System.Collections.Generic;
using FastReport.TypeConverters;
namespace FastReport.Design.PageDesigners.Page
{
#if !DEBUG
[DesignTimeVisible(false)]
#endif
internal class RulerBase : Control
{
public bool allowPaint = true;
protected ToolTip toolTip;
private ReportPageDesigner pageDesigner;
private float offset;
public float Offset
{
get { return offset; }
set { offset = value; }
}
public ReportWorkspace Workspace
{
get { return pageDesigner.Workspace; }
}
public ReportPageDesigner PageDesigner
{
get { return pageDesigner; }
}
public Designer Designer
{
get { return pageDesigner.Designer; }
}
protected bool CheckGridStep(ref float kx, ref float ky)
{
bool al = ReportWorkspace.SnapToGrid;
if (ModifierKeys == Keys.Alt)
al = !al;
bool result = true;
float grid = ReportWorkspace.Grid.SnapSize;
if (al)
{
result = kx >= grid || kx <= -grid || ky >= grid || ky <= -grid;
if (result)
{
kx = (int)(kx / grid) * grid;
ky = (int)(ky / grid) * grid;
}
}
return result;
}
#if !MONO
private const int WM_PAINT = 0x000F;
protected override void WndProc(ref Message m)
{
if ((m.Msg != WM_PAINT) || (allowPaint && m.Msg == WM_PAINT))
{
base.WndProc(ref m);
}
}
#endif
public RulerBase(ReportPageDesigner pd) : base()
{
pageDesigner = pd;
toolTip = new ToolTip();
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
}
}
#if !DEBUG
[DesignTimeVisible(false)]
#endif
internal class HorzRuler : RulerBase
{
private PointF lastMousePoint;
private bool mouseDown;
private bool mouseMoved;
private int activeGuide;
private bool saveAutoGuides;
private void DrawRuler(Graphics g, float start, float size)
{
Font font = new Font("Tahoma", 6f * this.FontDpiMultiplier());
Brush brush = SystemBrushes.WindowText;
Pen pen = SystemPens.WindowText;
int w5 = 5;
int w10 = 10;
float dx = (ReportWorkspace.Grid.GridUnits == PageUnits.Millimeters || ReportWorkspace.Grid.GridUnits == PageUnits.Centimeters ?
Units.Millimeters : Units.TenthsOfInch) * Designer.ZoomDpi;
string s = (((int)Math.Round(size / dx)) / 10).ToString();
float maxw = g.MeasureString(s, font).Width;
float i = start;
int i1 = 0;
while (i < start + size)
{
int h = 0;
if (i1 == 0)
h = 0;
else if (i1 % w10 == 0)
h = 6;
else if (i1 % w5 == 0)
h = 4;
else
h = 2;
if (h == 2 && dx * w10 < this.LogicalToDevice(41))
h = 0;
if (h == 4 && dx * w10 < this.LogicalToDevice(21))
h = 0;
int w = 0;
if (h == 6)
{
if (maxw > dx * w10 * 1.5f)
w = w10 * 4;
else if (maxw > dx * w10 * 0.7f)
w = w10 * 2;
else
w = w10;
}
if (w != 0 && i1 % w == 0)
{
if (ReportWorkspace.Grid.GridUnits == PageUnits.Millimeters)
s = (i1).ToString();
else if (ReportWorkspace.Grid.GridUnits == PageUnits.HundrethsOfInch)
s = (i1 * 10).ToString();
else
s = (i1 / 10).ToString();
SizeF sz = g.MeasureString(s, font);
g.DrawString(s, font, brush, new PointF(Offset + i - sz.Width / 2 + 1, this.LogicalToDevice(7)));
}
else if (h != 0)
{
g.DrawLine(pen,
Offset + i, this.LogicalToDevice(6 + (13 - h) / 2),
Offset + i, this.LogicalToDevice(6 + (13 - h) / 2 + h - 1));
}
i += dx;
i1++;
}
}
private void DrawRulerRtl(Graphics g, float start, float size)
{
Font font = new Font("Tahoma", 6f * this.FontDpiMultiplier());
Brush brush = SystemBrushes.WindowText;
Pen pen = SystemPens.WindowText;
int w5 = 5;
int w10 = 10;
float dx = (ReportWorkspace.Grid.GridUnits == PageUnits.Millimeters || ReportWorkspace.Grid.GridUnits == PageUnits.Centimeters ?
Units.Millimeters : Units.TenthsOfInch) * Designer.ZoomDpi;
string s = (((int)Math.Round(size / dx)) / 10).ToString();
float maxw = g.MeasureString(s, font).Width;
float i = start + size;
int i1 = 0;
while (i > start)
{
int h = 0;
if (i1 == 0)
h = 0;
else if (i1 % w10 == 0)
h = 6;
else if (i1 % w5 == 0)
h = 4;
else
h = 2;
if (h == 2 && dx * w10 < this.LogicalToDevice(41))
h = 0;
if (h == 4 && dx * w10 < this.LogicalToDevice(21))
h = 0;
int w = 0;
if (h == 6)
{
if (maxw > dx * w10 * 1.5f)
w = w10 * 4;
else if (maxw > dx * w10 * 0.7f)
w = w10 * 2;
else
w = w10;
}
if (w != 0 && i1 % w == 0)
{
if (ReportWorkspace.Grid.GridUnits == PageUnits.Millimeters)
s = (i1).ToString();
else if (ReportWorkspace.Grid.GridUnits == PageUnits.HundrethsOfInch)
s = (i1 * 10).ToString();
else
s = (i1 / 10).ToString();
SizeF sz = g.MeasureString(s, font);
g.DrawString(s, font, brush, new PointF(Offset + i - sz.Width / 2 + 1, this.LogicalToDevice(7)));
}
else if (h != 0)
{
g.DrawLine(pen,
Offset + i, this.LogicalToDevice(6 + (13 - h) / 2),
Offset + i, this.LogicalToDevice(6 + (13 - h) / 2 + h - 1));
}
i -= dx;
i1++;
}
}
private void DrawGuides(Graphics g)
{
FloatCollection guides = Workspace.Page.Guides;
if (guides == null)
return;
if (guides.Count > activeGuide && activeGuide != -1)
{
toolTip.Show(Converter.ToString((Workspace.Page.LeftMargin * Units.Millimeters + guides[activeGuide]) / ReportWorkspace.Grid.SnapSize * 10 / 4, typeof(PaperConverter))
+ " | " +
Converter.ToString((Workspace.Page.PaperWidth * Units.Millimeters - Workspace.Page.LeftMargin * Units.Millimeters - guides[activeGuide]) / ReportWorkspace.Grid.SnapSize * 10 / 4, typeof(PaperConverter)),
this, (int)Math.Round(Offset + guides[activeGuide] * Designer.ZoomDpi - 4), 32
);
}
if (activeGuide == -1)
toolTip.Hide(this);
for (int i = 0; i < guides.Count; i++)
{
Image b = this.GetImage(i == activeGuide ? 174 : 74);
g.DrawImage(b, (int)Math.Round(Offset + guides[i] * Designer.ZoomDpi - 4), 16);
}
}
private void MoveGuide(float kx)
{
Workspace.Guides.MoveVGuide(activeGuide, kx);
float f = Workspace.Page.Guides[activeGuide];
f += kx;
Workspace.Page.Guides[activeGuide] = Converter.DecreasePrecision(f, 2);
Workspace.Refresh();
Refresh();
}
private void FixGuide(bool remove)
{
float f = Workspace.Page.Guides[activeGuide];
if (remove || f < 0 || f > Workspace.Width / Designer.ZoomDpi)
Workspace.Page.Guides.RemoveAt(activeGuide);
activeGuide = -1;
Refresh();
}
protected override void OnPaint(PaintEventArgs e)
{
if (Workspace.Locked)
return;
Graphics g = e.Graphics;
g.SetClip(new RectangleF(Height, 0, Width - Height, Height));
g.FillRectangle(SystemBrushes.Window, new RectangleF(
Offset, this.LogicalToDevice(5),
Workspace.Width, Height - this.LogicalToDevice(10)));
if (Config.RightToLeft)
{
DrawRulerRtl(g, 0, Workspace.Width);
}
else
{
DrawRuler(g, 0, Workspace.Width);
}
DrawGuides(g);
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (Workspace.Locked)
return;
float scale = Designer.ZoomDpi;
lastMousePoint = new PointF(e.X / scale, e.Y / scale);
mouseDown = true;
mouseMoved = false;
if (activeGuide != -1)
Workspace.Guides.BeforeMoveVGuide(activeGuide);
saveAutoGuides = ReportWorkspace.AutoGuides;
ReportWorkspace.AutoGuides = false;
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (Workspace.Locked)
return;
float scale = Designer.ZoomDpi;
if (e.Button == MouseButtons.None)
{
// find guide
FloatCollection guides = Workspace.Page.Guides;
if (guides == null)
return;
float x = (e.X - Offset) / scale;
activeGuide = -1;
for (int i = 0; i < guides.Count; i++)
{
if (x > guides[i] - 5 && x < guides[i] + 5)
{
activeGuide = i;
break;
}
}
Refresh();
}
else if (e.Button == MouseButtons.Left)
{
if (activeGuide == -1)
return;
float kx = e.X / scale - lastMousePoint.X;
float ky = e.Y / scale - lastMousePoint.Y;
if (!CheckGridStep(ref kx, ref ky))
return;
mouseMoved = true;
MoveGuide(kx);
lastMousePoint.X += kx;
lastMousePoint.Y += ky;
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (Workspace.Locked || !mouseDown)
return;
ReportWorkspace.AutoGuides = saveAutoGuides;
mouseDown = false;
if (mouseMoved)
{
FixGuide(e.Y < -5 || e.Y > Height + 5);
Workspace.Designer.SetModified(null, "MoveGuide");
}
else
{
// create new guide
float x = (e.X - Offset) / Designer.ZoomDpi;
if (x < Workspace.Width && e.Y > 5 && e.Y < 20)
{
if (ReportWorkspace.SnapToGrid)
x = (int)(x / ReportWorkspace.Grid.SnapSize) * ReportWorkspace.Grid.SnapSize;
if (Workspace.Page.Guides == null)
Workspace.Page.Guides = new FloatCollection();
Workspace.Page.Guides.Add(x);
Workspace.Designer.SetModified(null, "AddGuide");
}
}
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
if (Workspace.Locked)
return;
if (!mouseDown && activeGuide != -1)
{
activeGuide = -1;
Refresh();
}
}
public HorzRuler(ReportPageDesigner pd) : base(pd)
{
activeGuide = -1;
}
}
#if !DEBUG
[DesignTimeVisible(false)]
#endif
internal class VertRuler : RulerBase
{
private PointF lastMousePoint;
private bool mouseDown;
private bool mouseMoved;
private int activeGuide;
private BandBase activeBand;
private bool resizing;
private bool saveAutoGuides;
private void DrawRuler(Graphics g, float start, float size)
{
Font font = new Font("Tahoma", 6f * this.FontDpiMultiplier());
Brush brush = SystemBrushes.WindowText;
Pen pen = SystemPens.WindowText;
int w5 = 5;
int w10 = 10;
float dx = (ReportWorkspace.Grid.GridUnits == PageUnits.Millimeters || ReportWorkspace.Grid.GridUnits == PageUnits.Centimeters ?
Units.Millimeters : Units.TenthsOfInch) * Designer.ZoomDpi;
string s = (((int)Math.Round(size / dx)) / 10).ToString();
float maxw = g.MeasureString(s, font).Width;
float i = start;
int i1 = 0;
while (i < start + size)
{
int h = 0;
if (i1 == 0)
h = 0;
else if (i1 % w10 == 0)
h = 6;
else if (i1 % w5 == 0)
h = 4;
else
h = 2;
if (h == 2 && dx * w10 < this.LogicalToDevice(41))
h = 0;
if (h == 4 && dx * w10 < this.LogicalToDevice(21))
h = 0;
int w = 0;
if (h == 6)
{
if (maxw > dx * w10 * 1.5f)
w = w10 * 4;
else if (maxw > dx * w10 * 0.7f)
w = w10 * 2;
else
w = w10;
}
if (w != 0 && i1 % w == 0)
{
if (ReportWorkspace.Grid.GridUnits == PageUnits.Millimeters)
s = (i1).ToString();
else if (ReportWorkspace.Grid.GridUnits == PageUnits.HundrethsOfInch)
s = (i1 * 10).ToString();
else
s = (i1 / 10).ToString();
SizeF sz = g.MeasureString(s, font);
PointF p = new PointF(Width - sz.Height - this.LogicalToDevice(7), Offset + i + sz.Width / 2);
GraphicsState state = g.Save();
g.TranslateTransform(p.X + sz.Height / 2, p.Y + sz.Width / 2);
g.RotateTransform(-90);
p.X /= 2;
p.Y = -sz.Height / 2;
g.DrawString(s, font, brush, p);
g.Restore(state);
}
else if (h != 0)
{
g.DrawLine(pen,
this.LogicalToDevice(6 + (13 - h) / 2), Offset + i,
this.LogicalToDevice(6 + (13 - h) / 2 + h - 1), Offset + i);
}
i += dx;
i1++;
}
}
private void DrawGuides(Graphics g, BandBase band)
{
FloatCollection guides = band.Guides;
if (guides == null)
return;
if (band == activeBand && guides.Count > activeGuide && activeGuide != -1)
{
toolTip.Show(Converter.ToString((Workspace.Page.TopMargin * Units.Millimeters + (band.Top + guides[activeGuide])) / ReportWorkspace.Grid.SnapSize * 10 / 4, typeof(PaperConverter))
+ " | "
+ Converter.ToString((Workspace.Page.PaperHeight * Units.Millimeters - Workspace.Page.TopMargin * Units.Millimeters - (band.Top + guides[activeGuide])) / ReportWorkspace.Grid.SnapSize * 10 / 4, typeof(PaperConverter)),
this, 32, (int)Math.Round(Offset + (band.Top + guides[activeGuide]) * Designer.ZoomDpi + 10)
);
}
if (activeGuide == -1)
toolTip.Hide(this);
for (int i = 0; i < guides.Count; i++)
{
Image b = this.GetImage(band == activeBand && i == activeGuide ? 173 : 73);
g.DrawImage(b, 16, (int)Math.Round(Offset + (band.Top + guides[i]) * Designer.ZoomDpi - 4));
}
}
private BandCollection GetBands()
{
BandCollection bands = new BandCollection();
ObjectCollection objects = PageDesigner.Page.AllObjects;
foreach (Base c in objects)
{
if (c is BandBase)
bands.Add(c as BandBase);
}
return bands;
}
private BandBase BandAt(float y)
{
BandCollection bands = GetBands();
foreach (BandBase b in bands)
{
if (y >= b.Top && y <= b.Bottom + (ReportWorkspace.ClassicView ? BandBase.HeaderSize : 4))
return b;
}
return null;
}
private void MoveGuide(float ky)
{
Workspace.Guides.MoveHGuide(activeBand, activeGuide, ky);
float f = activeBand.Guides[activeGuide];
f += ky;
activeBand.Guides[activeGuide] = Converter.DecreasePrecision(f, 2);
Workspace.Refresh();
Refresh();
}
private void ResizeBand(float ky)
{
activeBand.Height += ky;
activeBand.FixHeight();
Workspace.UpdateBands();
}
private void FixGuide(bool remove)
{
float f = activeBand.Guides[activeGuide];
if (remove || f < 0 || f > activeBand.Height)
activeBand.Guides.RemoveAt(activeGuide);
activeGuide = -1;
Refresh();
}
protected override void OnPaint(PaintEventArgs e)
{
if (Workspace.Locked)
return;
Graphics g = e.Graphics;
// highlight bands list
Hashtable bandsToHighlight = new Hashtable();
if (ReportWorkspace.EnableBacklight)
{
foreach (Base obj in Designer.SelectedObjects)
{
BandBase band = null;
if (obj is BandBase)
band = obj as BandBase;
else if (obj is ReportComponentBase)
band = (obj as ReportComponentBase).Band;
if (band != null)
bandsToHighlight[band] = 1;
}
}
float scale = Designer.ZoomDpi;
BandCollection bands = GetBands();
foreach (BandBase b in bands)
{
Brush brush = bandsToHighlight.ContainsKey(b) ? Brushes.Gainsboro : SystemBrushes.Window;
g.FillRectangle(brush, new RectangleF(
this.LogicalToDevice(5), Offset + b.Top * scale,
Width - this.LogicalToDevice(10), b.Height * scale + 1));
DrawRuler(g, b.Top * scale, b.Height * scale);
DrawGuides(g, b);
if (ReportWorkspace.ClassicView)
{
RectangleF fillRect = new RectangleF(
this.LogicalToDevice(5), Offset + (b.Top - (BandBase.HeaderSize - 1)) * scale,
Width - this.LogicalToDevice(10), (BandBase.HeaderSize - 1) * scale);
if (b.Top == BandBase.HeaderSize)
{
fillRect.Y = 0;
fillRect.Height += scale;
}
b.DrawBandHeader(g, fillRect, true);
if (b.Top > BandBase.HeaderSize)
{
// draw splitter lines
float lineY = fillRect.Top + fillRect.Height / 2 - this.LogicalToDevice(2);
for (int i = 0; i < 6; i += 2)
{
g.DrawLine(SystemPens.ControlDarkDark,
this.LogicalToDevice(9), lineY + this.LogicalToDevice(i),
Width - this.LogicalToDevice(10), lineY + this.LogicalToDevice(i));
}
}
}
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (Workspace.Locked)
return;
float scale = Designer.ZoomDpi;
lastMousePoint = new PointF(e.X / scale, e.Y / scale);
mouseDown = true;
mouseMoved = false;
if (activeBand != null && activeGuide != -1)
Workspace.Guides.BeforeMoveHGuide(activeBand, activeGuide);
saveAutoGuides = ReportWorkspace.AutoGuides;
ReportWorkspace.AutoGuides = false;
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (Workspace.Locked)
return;
float scale = Designer.ZoomDpi;
if (e.Button == MouseButtons.None)
{
// find band
float y = (e.Y - Offset) / scale;
Cursor = Cursors.Default;
resizing = false;
activeGuide = -1;
activeBand = BandAt(y);
if (activeBand != null)
{
// check band resize
if (y > activeBand.Bottom - 1 &&
y < activeBand.Bottom + (ReportWorkspace.ClassicView ? BandBase.HeaderSize : 4))
{
resizing = true;
Cursor = Cursors.HSplit;
}
else
{
// check guides
FloatCollection guides = activeBand.Guides;
if (guides != null)
{
for (int i = 0; i < guides.Count; i++)
{
if (y > activeBand.Top + guides[i] - 5 &&
y < activeBand.Top + guides[i] + 5)
{
activeGuide = i;
break;
}
}
}
}
}
Refresh();
}
else if (e.Button == MouseButtons.Left)
{
float kx = e.X / scale - lastMousePoint.X;
float ky = e.Y / scale - lastMousePoint.Y;
if (!CheckGridStep(ref kx, ref ky))
return;
if (activeBand != null)
{
if (resizing)
{
mouseMoved = true;
ResizeBand(ky);
}
else if (activeGuide != -1)
{
mouseMoved = true;
MoveGuide(ky);
}
}
lastMousePoint.X += kx;
lastMousePoint.Y += ky;
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (Workspace.Locked)
return;
ReportWorkspace.AutoGuides = saveAutoGuides;
mouseDown = false;
if (mouseMoved)
{
if (resizing)
activeBand.FixHeight();
else
FixGuide(e.X < -this.LogicalToDevice(5) || e.X > Width + this.LogicalToDevice(5));
Workspace.Designer.SetModified(null, resizing ? "ResizeBand" : "MoveGuide");
}
else
{
// create new guide
if (e.X > this.LogicalToDevice(5) && e.X < this.LogicalToDevice(20))
{
float y = (e.Y - Offset) / Designer.ZoomDpi;
BandBase band = BandAt(y);
if (band != null)
{
y = y - band.Top;
if (ReportWorkspace.SnapToGrid)
y = (int)(y / ReportWorkspace.Grid.SnapSize) * ReportWorkspace.Grid.SnapSize;
if (band.Guides == null)
band.Guides = new FloatCollection();
band.Guides.Add(y);
Workspace.Designer.SetModified(null, "AddGuide");
}
}
}
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
if (Workspace.Locked)
return;
if (!mouseDown && activeGuide != -1)
{
activeGuide = -1;
Refresh();
}
}
public VertRuler(ReportPageDesigner pd) : base(pd)
{
activeGuide = -1;
}
}
#if !MONO
///
/// Represent ruler with guides for forms of editors
///
public class RulerWithGuides : EditRuler
{
private bool mouseDown = false;
private Pen pen;
private List rulerElements;
private RulerElement activElement;
private int countTabPos;
private bool leftIndentIsActive = false;
private bool rightIndentIsActive = false;
#region Properties
///
/// Get or set left indent position
///
public int LeftIndent
{
get
{
return leftIndent.Indent;
}
set
{
leftIndent.Indent = value;
Invalidate();
}
}
///
/// Get or set right indent position
///
public int RightIndent
{
get
{
return rightIndent.Indent;
}
set
{
rightIndent.Indent = value;
Invalidate();
}
}
///
/// Gets or sets tab positiions
///
public int[] TabPositions
{
get
{
List result = new List();
foreach (var elem in rulerElements)
{
if(elem is TabPosition)
{
result.Add(elem.Bounds.X + 4);
}
}
result.Sort();
return result.ToArray();
}
set
{
for (int i = 0; i < rulerElements.Count; i++)
{
if (rulerElements[i] is TabPosition)
{
rulerElements.Remove(rulerElements[i]);
i--;
}
}
for (int i = 0; i < value.Length; i++)
{
rulerElements.Add(new TabPosition(value[i]));
}
Invalidate();
}
}
#endregion
#region Protected method
///
protected override void OnDoubleClick(EventArgs e)
{
base.OnDoubleClick(e);
MouseEventArgs me = e as MouseEventArgs;
if (me.X > RulerStart && me.X < RulerWidth && me.Button == MouseButtons.Left && !TabPosExist(me.X) &&
countTabPos + 1 <= 32 && !leftIndentIsActive && !rightIndentIsActive && activElement == null)
{
rulerElements.Add(new TabPosition(me.X));
countTabPos++;
OnChange(this);
}
}
///
protected override Rectangle GetIndentHitRect(RulerIndent Indent)
{
Rectangle result = Rectangle.Empty;
if (Vertical)
{
//if (Indent.Orientation == IndentOrientation.Near)
// result = new Rectangle(cRulerTop, RulerStart + Indent.Indent - EditConsts.DefaultRulerHitWidth, cRulerHeight, EditConsts.DefaultRulerHitWidth * 2);
//else
// result = new Rectangle(cRulerTop, PageStart + PageWidth - EditConsts.DefaultRulerHitWidth, cRulerHeight, EditConsts.DefaultRulerHitWidth * 2);
}
else
{
if (Indent.Orientation == IndentOrientation.Near)
result = new Rectangle(RulerStart + Indent.Indent - EditConsts.DefaultRulerHitWidth, cRulerTop, EditConsts.DefaultRulerHitWidth * 2, cRulerHeight);
else
result = new Rectangle(RulerStart + RulerWidth - EditConsts.DefaultRulerHitWidth - Indent.Indent, cRulerTop, EditConsts.DefaultRulerHitWidth * 2, cRulerHeight);
}
return result;
}
///
protected override Rectangle GetIndentRect(RulerIndent indent)
{
Rectangle result = Rectangle.Empty;
if (Vertical)
{
//if (indent.Orientation == IndentOrientation.Near)
// result = new Rectangle(cRulerTop, RulerStart, cRulerHeight, indent.Indent);
//else
// result = new Rectangle(cRulerTop, PageWidth + PageStart, cRulerHeight, indent.Indent);
}
else
{
if (indent.Orientation == IndentOrientation.Near)
result = new Rectangle(RulerStart, cRulerTop, indent.Indent, cRulerHeight);
else
result = new Rectangle(RulerWidth + RulerStart - indent.Indent, cRulerTop, indent.Indent, cRulerHeight);
}
return result;
}
///
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
foreach(var elem in rulerElements)
{
elem.Draw(pe.Graphics);
}
}
///
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
mouseDown = true;
if (RulerWidth - RightIndent + RulerStart + 2 >= e.X && RulerWidth - RightIndent + RulerStart - 4 <= e.X && e.Button != MouseButtons.Right)
rightIndentIsActive = true;
else if (LeftIndent + RulerStart - 4 <= e.X && LeftIndent + RulerStart + 2 >= e.X && e.Button != MouseButtons.Right)
leftIndentIsActive = true;
else
foreach (var elem in rulerElements)
{
if (elem.Bounds.Contains(e.Location))
{
if (e.Button == MouseButtons.Right && elem is TabPosition)
{
rulerElements.Remove(elem);
countTabPos--;
}
else
{
activElement = elem;
activElement.IsActive = true;
if (e.X > RulerWidth + RulerStart - RightIndent)
activElement.Move(new Point(RulerWidth + RulerStart - RightIndent, 0));
else if(e.X < RulerStart + LeftIndent)
activElement.Move(new Point(RulerStart + LeftIndent, 0));
}
break;
}
}
OnChange(this);
}
///
protected override void OnMouseMove(MouseEventArgs e)
{
int oldLeftIndent = LeftIndent;
base.OnMouseMove(e);
if (mouseDown && activElement != null && e.X < RulerWidth + RulerStart - RightIndent && e.X > RulerStart + LeftIndent)
{
activElement.Move(e.Location);
OnChange(this);
}
else if(mouseDown && leftIndentIsActive)
{
int dx = LeftIndent - oldLeftIndent;
//if (dx != 0)
dx += 4;
foreach (var elem in rulerElements)
{
elem.Move(new Point(elem.Bounds.X + dx, 0));
}
}
}
///
protected override void OnChange(object sender)
{
base.OnChange(sender);
Invalidate();
}
///
protected override void OnMouseCaptureChanged(EventArgs e)
{
base.OnMouseCaptureChanged(e);
mouseDown = false;
if (activElement != null)
activElement.IsActive = false;
activElement = null;
leftIndentIsActive = false;
rightIndentIsActive = false;
OnChange(this);
}
///
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
mouseDown = false;
if(activElement != null)
activElement.IsActive = false;
activElement = null;
leftIndentIsActive = false;
rightIndentIsActive = false;
OnChange(this);
}
///
protected override void InitLayout()
{
base.InitLayout();
pen = new Pen(Color.Black, 1);
pen.DashStyle = DashStyle.Dash;
pen.DashPattern = new float[] { 4, 4 };
rulerElements = new List();
}
///
protected override void OnHandleDestroyed(EventArgs e)
{
pen.Dispose();
base.OnHandleDestroyed(e);
}
#endregion
private bool TabPosExist(int x)
{
foreach (var elem in rulerElements)
{
if (elem.Bounds.Contains(x, elem.Bounds.Y) && elem is TabPosition)
{
return true;
}
}
return false;
}
///
/// Method for drawing guides on element of form.
///
///
///
public void DrawGuides(object sender, PaintEventArgs e)
{
if (mouseDown)
{
if(activElement != null)
e.Graphics.DrawLine(pen, new Point(activElement.Bounds.X + 4, e.ClipRectangle.Top), new Point(activElement.Bounds.X + 4, e.ClipRectangle.Bottom));
else if(leftIndentIsActive)
e.Graphics.DrawLine(pen, new Point(LeftIndent + RulerStart, e.ClipRectangle.Top), new Point(LeftIndent + RulerStart, e.ClipRectangle.Bottom));
else if (rightIndentIsActive)
e.Graphics.DrawLine(pen, new Point(RulerWidth - RightIndent + RulerStart + 2, e.ClipRectangle.Top), new Point(RulerWidth - RightIndent + RulerStart + 2, e.ClipRectangle.Bottom));
}
}
///
/// Base class for elements of RulerWithGuides
///
public class RulerElement
{
private bool isActive;
private Rectangle bounds;
///
/// Get or set bounds of object
///
public Rectangle Bounds
{
get { return bounds; }
set { bounds = value; }
}
///
/// Get or set state of object
///
public bool IsActive
{
get { return isActive; }
set { isActive = value; }
}
///
/// Draw element on graphics
///
///
public virtual void Draw(Graphics g) { }
///
/// Method for moving object by means of chenging bounds
///
///
public virtual void Move(Point location) { }
}
///
/// Element of RulerWithGuides presenting position of tabs
///
public class TabPosition : RulerElement
{
///
/// Constructor of class TabPosition
///
///
public TabPosition(int x)
{
IsActive = false;
Bounds = new Rectangle(x - 4, 16, 14, 14);
}
///
public override void Draw(Graphics g)
{
base.Draw(g);
if(IsActive)
g.DrawImage(Res.GetImage(174, 96), Bounds);
else
g.DrawImage(Res.GetImage(74, 96), Bounds);
}
///
public override void Move(Point location)
{
base.Move(location);
Bounds = new Rectangle(location.X - 4, 16, 14, 14);
}
}
}
#endif
}