using System; using System.Windows.Forms; using System.Drawing; using System.ComponentModel; using System.Drawing.Drawing2D; using FastReport.Utils; using FastReport.Design.PageDesigners.Page; namespace FastReport { partial class BandBase { #region Fields internal static int HeaderSize { get { return 20; } } #endregion #region Properties /// [Browsable(false)] public override float Left { get { return base.Left; } set { base.Left = value; } } /// [Browsable(false)] public override float Top { get { return base.Top; } set { base.Top = value; } } /// [Browsable(false)] public override float Width { get { return base.Width; } set { base.Width = value; } } /// /// This property is not relevant to this class. /// [Browsable(false)] public override DockStyle Dock { get { return base.Dock; } set { base.Dock = value; } } /// /// This property is not relevant to this class. /// [Browsable(false)] public override AnchorStyles Anchor { get { return base.Anchor; } set { base.Anchor = value; } } /// /// This property is not relevant to this class. /// [Browsable(false)] public new bool GrowToBottom { get { return base.GrowToBottom; } set { base.GrowToBottom = value; } } /// /// This property is not relevant to this class. /// [Browsable(false)] public new ShiftMode ShiftMode { get { return base.ShiftMode; } set { base.ShiftMode = value; } } /// [DefaultValue(false)] public new bool CanBreak { get { return base.CanBreak; } set { base.CanBreak = value; } } /// /// This property is not relevant to this class. /// [Browsable(false)] public new BreakableComponent BreakTo { get { return base.BreakTo; } set { base.BreakTo = value; } } internal bool CanDelete { get { if (Page != null) { // do not delete the sole band on the page ObjectCollection pageObjects = Page.AllObjects; ObjectCollection bands = new ObjectCollection(); foreach (Base obj in pageObjects) { // fix: it was possible to delete the band if it has a child band if (obj is BandBase && (obj == this || !(obj is ChildBand))) bands.Add(obj); } return bands.Count > 1; } else return false; } } internal float DesignWidth { get { ReportPage page = Page as ReportPage; if (page != null && page.ExtraDesignWidth) { if (page.Columns.Count <= 1 || !IsColumnDependentBand) return Width * 5; } return Width; } } #endregion #region Public Methods /// public override void DrawSelection(FRPaintEventArgs e) { DrawSelectionPoint(e, Pens.Black, Brushes.White, Left + Width / 2, Top + Height + 2); DrawSelectionPoint(e, Pens.Black, Brushes.White, Left + Width / 2, Top + 2); } /// public override bool PointInObject(PointF point) { if (IsDesigning) { if (ReportWorkspace.ClassicView) return new RectangleF(Left, Top - (HeaderSize - 1), DesignWidth, Height + HeaderSize - 1).Contains(point); else return new RectangleF(Left, Top, DesignWidth, Height).Contains(point); } return AbsBounds.Contains(point); } /// public override void HandleMouseDown(FRMouseEventArgs e) { base.HandleMouseDown(e); if (e.handled) { if (e.modifierKeys != Keys.Shift) { e.mode = WorkspaceMode2.SelectionRect; e.activeObject = this; } } } /// public override void HandleMouseHover(FRMouseEventArgs e) { base.HandleMouseHover(e); if (e.handled) e.cursor = Cursors.Default; } /// public override void HandleMouseMove(FRMouseEventArgs e) { PointF point = new PointF(e.x, e.y); if (e.button == MouseButtons.None) { e.sizingPoint = SizingPoint.None; if (point.Y > Bounds.Bottom && point.Y < Bounds.Bottom + 4) { e.mode = WorkspaceMode2.Size; e.sizingPoint = SizingPoint.BottomCenter; e.cursor = Cursors.HSplit; e.handled = true; } if (point.Y > Bounds.Top && point.Y < Bounds.Top + 4 && point.X > (Bounds.Left + Bounds.Right) / 2 - 2 && point.X < (Bounds.Left + Bounds.Right) / 2 + 2) { e.mode = WorkspaceMode2.Size; e.sizingPoint = SizingPoint.TopCenter; e.cursor = Cursors.HSplit; e.handled = true; } } else { if (e.activeObject == this && e.mode == WorkspaceMode2.Size) { if (e.sizingPoint == SizingPoint.BottomCenter) { Height += e.delta.Y; FixHeight(); } if (e.sizingPoint == SizingPoint.TopCenter) { Height -= e.delta.Y; FixHeightWithComponentsShift(e.delta.Y); } e.handled = true; } } } /// public override void HandleMouseUp(FRMouseEventArgs e) { if (Report == null) return; if (e.mode == WorkspaceMode2.SelectionRect) { ObjectCollection selectedList = new ObjectCollection(); // find objects inside the selection rect for (int i = 0; i < Report.Designer.Objects.Count; i++) { Base c = Report.Designer.Objects[i]; if (c is ComponentBase && !(c is BandBase)) { e.handled = false; (c as ComponentBase).HandleMouseUp(e); // object is inside if (e.handled) selectedList.Add(c); } } if (selectedList.Count > 0) selectedList.CopyTo(Report.Designer.SelectedObjects); } FixHeight(); } /// public override SizeF GetPreferredSize() { SizeF result = new SizeF(0, 0); switch (ReportWorkspace.Grid.GridUnits) { case PageUnits.Millimeters: result = new SizeF(Units.Millimeters * 10, Units.Millimeters * 10); break; case PageUnits.Centimeters: result = new SizeF(Units.Centimeters * 1, Units.Centimeters * 1); break; case PageUnits.Inches: result = new SizeF(Units.Inches * 0.5f, Units.Inches * 0.5f); break; case PageUnits.HundrethsOfInch: result = new SizeF(Units.HundrethsOfInch * 50, Units.HundrethsOfInch * 50); break; } return result; } /// public override void Delete() { if (CanDelete) Dispose(); } internal virtual string GetInfoText() { return ""; } internal void DrawBandHeader(Graphics g, RectangleF rect, bool drawTopLine) { if (Report == null) return; Color color1 = Color.Empty; if (this is GroupHeaderBand || this is GroupFooterBand) color1 = Color.FromArgb(144, 228, 0); else if (this is DataBand) color1 = Color.FromArgb(255, 144, 0); else color1 = UIStyleUtils.GetGrayColor(Report.Designer.UIStyle); Color color2 = Color.FromArgb(100, color1); Color color3 = Color.FromArgb(180, Color.White); Color color4 = Color.Transparent; g.FillRectangle(Brushes.White, rect); using (LinearGradientBrush b = new LinearGradientBrush(rect, color1, color2, 90)) { g.FillRectangle(b, rect); } rect.Height /= 3; using (LinearGradientBrush b = new LinearGradientBrush(rect, color3, color4, 90)) { g.FillRectangle(b, rect); } if (drawTopLine) { using (Pen p = new Pen(color1)) { g.DrawLine(p, rect.Left, rect.Top, rect.Right, rect.Top); } } } /// public override ContextMenuBase GetContextMenu() { return new BandBaseMenu(Report.Designer); } /// public override void Draw(FRPaintEventArgs e) { if (Report == null) return; UpdateWidth(); if (IsDesigning) { IGraphics g = e.Graphics; RectangleF bounds = Bounds; bounds.X *= e.ScaleX; bounds.Y *= e.ScaleY; bounds.Width = DesignWidth * e.ScaleX; bounds.Height *= e.ScaleY; if (ReportWorkspace.ClassicView && Width != 0) { RectangleF fillRect = new RectangleF(bounds.Left, bounds.Top - (BandBase.HeaderSize - 1) * e.ScaleY, bounds.Width, (BandBase.HeaderSize - 1) * e.ScaleY); if (bounds.Top == BandBase.HeaderSize) { fillRect.Y = 0; fillRect.Height += e.ScaleY; } DrawBandHeader(g.Graphics, fillRect, true); ObjectInfo info = RegisteredObjects.FindObject(this); string text = Res.Get(info.Text); if (GetInfoText() != "") text += ": " + GetInfoText(); fillRect.X += 4; using (Font f = new Font(DrawUtils.DefaultFont.Name, DrawUtils.DefaultFont.Size * 96 / DrawUtils.ScreenDpi * Report.Designer.ZoomDpi)) TextRenderer.DrawText(g.Graphics, text, f, Rectangle.Round(fillRect), SystemColors.WindowText, TextFormatFlags.VerticalCenter | TextFormatFlags.PreserveGraphicsTranslateTransform); } g.FillRectangle(SystemBrushes.Window, bounds.Left, (int)Math.Round(bounds.Top), bounds.Width, bounds.Height + (ReportWorkspace.ClassicView ? 1 : 4)); DrawBackground(e); if (ReportWorkspace.ShowGrid) ReportWorkspace.Grid.Draw(g.Graphics, bounds, e.ScaleX); if (!ReportWorkspace.ClassicView) { Pen pen = e.Cache.GetPen(Color.Silver, 1, DashStyle.Dot); g.DrawLine(pen, bounds.Left, bounds.Bottom + 1, bounds.Right + 1, bounds.Bottom + 1); g.DrawLine(pen, bounds.Left + 1, bounds.Bottom + 2, bounds.Right + 1, bounds.Bottom + 2); g.DrawLine(pen, bounds.Left, bounds.Bottom + 3, bounds.Right + 1, bounds.Bottom + 3); } } else { DrawBackground(e); Border.Draw(e, new RectangleF(AbsLeft, AbsTop, Width, Height)); } } internal void FixHeight() { float maxHeight = Height; foreach (ReportComponentBase c in Objects) { if (c.Bottom > maxHeight) maxHeight = c.Bottom; } if (maxHeight < 0) maxHeight = 0; Height = maxHeight; } internal void FixHeightWithComponentsShift(float deltaY) { float minTop = Height; float maxBottom = 0; float minHeight = Height; // Calculate minimum top of all components on this band. foreach (ReportComponentBase component in Objects) { if (component.Top < minTop) { minTop = component.Top; } } // Calculate maximum bottom of all components on this band. foreach (ReportComponentBase component in Objects) { if (component.Bottom > maxBottom) { maxBottom = component.Bottom; } } // Calculate minimum height of band with components shift. minHeight = maxBottom - minTop; // Minimum height with compenents shift can't be negative. if (minHeight < 0) { minHeight = 0; } // Prevent incorrect movement of objects when mouse moves too fast. if (minTop < deltaY) { deltaY = minTop; } // Size of band should be decreased. if (deltaY > 0) { // There is enough place to move components up. if (minTop > 0) { // Move all components up. foreach (ReportComponentBase component in Objects) { component.Top -= deltaY; } } } else { // Move all components down. foreach (ReportComponentBase component in Objects) { component.Top -= deltaY; } } // Height can't be less then minHeight. if (Height < minHeight) { Height = minHeight; } } #endregion } }