private void RenderMaqueeWave() { int blockWidth = foregroundLeadingSize + marqueeWidth + foregroundTrailingSize; float t = (((float)(value - minimum)) / ((float)(maximum - minimum))) * (float)(2.0 * Math.PI); int travelDistance = (this.Width - blockWidth) / 2; int position = ((this.Width - blockWidth) / 2) + (int)(Math.Sin(t) * (double)travelDistance); CustomProgressBar.DrawImage( offscreen, foregroundImage, new Rectangle(position, 0, foregroundLeadingSize, this.Height), new Rectangle(0, 0, foregroundLeadingSize, foregroundImage.Height)); CustomProgressBar.DrawImage( offscreen, foregroundImage, new Rectangle(position + foregroundLeadingSize + marqueeWidth, 0, foregroundTrailingSize, this.Height), new Rectangle(foregroundImage.Width - foregroundTrailingSize, 0, foregroundTrailingSize, foregroundImage.Height)); CustomProgressBar.DrawImage( offscreen, foregroundImage, new Rectangle(position + foregroundLeadingSize, 0, marqueeWidth, this.Height), new Rectangle(foregroundLeadingSize, 0, foregroundImage.Width - (foregroundLeadingSize + foregroundTrailingSize), foregroundImage.Height + 1)); }
private void RenderMarqueeTileWrap() { Region clipRegion = offscreen.Clip; int tileLeft = 0; int blockWidth = foregroundImage.Width - (foregroundLeadingSize + foregroundTrailingSize); int distance = (int)(((float)this.Width + blockWidth) * ((float)(value - minimum)) / ((float)(maximum - minimum))); // By setting clip we don't have to change the size of either the source rectangle or the destination rectangle, // the clip will make sure the overflow is cropped away. offscreen.Clip = new Region(new Rectangle(distance - blockWidth, 0, blockWidth, this.Height)); int step = 0; while (tileLeft <= this.Width) { CustomProgressBar.DrawImage( offscreen, foregroundImage, new Rectangle(blockWidth * step, 0, blockWidth, this.Height), new Rectangle(foregroundLeadingSize, 0, blockWidth, foregroundImage.Height)); tileLeft += blockWidth; ++step; } offscreen.Clip = clipRegion; }
protected void RenderCacheImages() { CustomProgressBar.DisposeToNull(backgroundCacheImage); CustomProgressBar.DisposeToNull(overlayCacheImage); backgroundCacheImage = new Bitmap(Width, Height); using (Graphics backgroundCacheGraphics = Graphics.FromImage(backgroundCacheImage)) { // Render the background, here we pass the entire width of the progressbar as the distance value because we // always want the entire background to be drawn. Render(backgroundCacheGraphics, backgroundImage, backgroundDrawMethod, backgroundLeadingSize, backgroundTrailingSize, this.Width); } overlayCacheImage = new Bitmap(Width, Height); using (Graphics overlayCacheGraphics = Graphics.FromImage(overlayCacheImage)) { // Make sure that we retain our chroma key value by starting with a fully transparent overlay cache image #if PocketPC overlayCacheGraphics.FillRectangle(new SolidBrush(Color.Magenta), ClientRectangle); #else overlayCacheGraphics.FillRectangle(new SolidBrush(Color.Transparent), ClientRectangle); #endif // Render the overlay, this way we can get neat border on our progress bar (for example) Render(overlayCacheGraphics, overlayImage, overlayDrawMethod, overlayLeadingSize, overlayTrailingSize, this.Width); } }
private void ProgressBar_Resize(object sender, EventArgs e) { // // If the progressbar is resized we dump out current offscreen and set it to null, a new one // will then be created as the OnPaint method will request this if it is null. // CustomProgressBar.DisposeToNull(offscreenImage); CustomProgressBar.DisposeToNull(offscreen); DoLayout(); RenderCacheImages(); }
protected override void OnPaint(PaintEventArgs e) { // // An offscreen is a must have so we make sure one is always created if it does not exists, // a resize of the progressbar sets offscreenImage to null and this will then automatically // create a new one with the correct dimensions. // if (offscreenImage == null) { CreateOffscreen(); } // Render the background first using the cached image CustomProgressBar.DrawImage(offscreen, backgroundCacheImage, ClientRectangle, ClientRectangle); switch (barType) { case BarType.Progress: // We only need to render the foreground if the current value is above the minimum if (value > minimum) { // Calculate the amount of pixels (the distance) to draw. int distance = (int)(((float)this.Width) * ((float)(value - minimum)) / ((float)(maximum - minimum))); Render(offscreen, foregroundImage, foregroundDrawMethod, foregroundLeadingSize, foregroundTrailingSize, distance); } break; case BarType.Marquee: // There are a couple of ways to render the marquee foreground so this is delegated to a method RenderMarqueeForeground(); break; } // Render the overlay using the cached image CustomProgressBar.DrawImage(offscreen, overlayCacheImage, ClientRectangle, ClientRectangle); // Finally, draw we our offscreen onto the Graphics in the event. e.Graphics.DrawImage(offscreenImage, 0, 0); }
protected void Render(Graphics graphics, Image sourceImage, DrawMethod drawMethod, int leadingSize, int trailingSize, int distance) { // If we don't have an image to render just bug out, this allows us to call Render without checking sourceImage first. if (sourceImage == null) { return; } // // Draw the first segment of the image as defined by leadingSize, this is always drawn at (0, 0). // CustomProgressBar.DrawImage( graphics, sourceImage, new Rectangle(0, 0, leadingSize, this.Height), new Rectangle(0, 0, leadingSize, sourceImage.Height + 1)); // // Figure out where the last segment of the image should be drawn, this is always to the right of the first segment // and then at the given distance minus the width of the last segment. // int trailerLeftPosition = Math.Max(leadingSize, distance - trailingSize); CustomProgressBar.DrawImage( graphics, sourceImage, new Rectangle(trailerLeftPosition, 0, trailingSize, this.Height), new Rectangle(sourceImage.Width - trailingSize, 0, trailingSize, sourceImage.Height + 1)); // // We only draw the middle segment if the width of the first and last are less than what we need to display. // if (distance > leadingSize + trailingSize) { RenderCenterSegment(graphics, sourceImage, drawMethod, leadingSize, trailingSize, distance, trailerLeftPosition); } }
private void RenderMarqueeBlockWrap() { int blockWidth = foregroundLeadingSize + marqueeWidth + foregroundTrailingSize; float distance = (((float)(value - minimum)) / ((float)(maximum - minimum))) * (this.Width + blockWidth); int position = (int)(distance - blockWidth); CustomProgressBar.DrawImage( offscreen, foregroundImage, new Rectangle(position, 0, foregroundLeadingSize, this.Height), new Rectangle(0, 0, foregroundLeadingSize, foregroundImage.Height)); CustomProgressBar.DrawImage( offscreen, foregroundImage, new Rectangle(position + foregroundLeadingSize + marqueeWidth, 0, foregroundTrailingSize, this.Height), new Rectangle(foregroundImage.Width - foregroundTrailingSize, 0, foregroundTrailingSize, foregroundImage.Height)); CustomProgressBar.DrawImage( offscreen, foregroundImage, new Rectangle(position + foregroundLeadingSize, 0, marqueeWidth, this.Height), new Rectangle(foregroundLeadingSize, 0, foregroundImage.Width - (foregroundLeadingSize + foregroundTrailingSize), foregroundImage.Height + 1)); }
private void RenderCenterSegment(Graphics graphics, Image sourceImage, DrawMethod drawMethod, int leadingSize, int trailingSize, int distance, int trailerLeftPosition) { switch (drawMethod) { case DrawMethod.Stretch: // This draws the middle segment stretched to fill the area between the first and last segment. CustomProgressBar.DrawImage( graphics, sourceImage, new Rectangle(leadingSize, 0, distance - (leadingSize + trailingSize), this.Height), new Rectangle(leadingSize, 0, sourceImage.Width - (leadingSize + trailingSize), sourceImage.Height + 1)); break; case DrawMethod.Tile: // This draws the middle segment un-stretched as many times as required to fill the area between the first and last segment. { Region clipRegion = graphics.Clip; int tileLeft = leadingSize; int tileWidth = sourceImage.Width - (leadingSize + trailingSize); // By setting clip we don't have to change the size of either the source rectangle or the destination rectangle, // the clip will make sure the overflow is cropped away. graphics.Clip = new Region(new Rectangle(tileLeft, 0, trailerLeftPosition - tileLeft, this.Height)); while (tileLeft < trailerLeftPosition) { CustomProgressBar.DrawImage( graphics, sourceImage, new Rectangle(tileLeft, 0, tileWidth, this.Height), new Rectangle(leadingSize, 0, tileWidth, sourceImage.Height)); tileLeft += tileWidth; } graphics.Clip = clipRegion; } break; } }