[Gtk-sharp-list] Custom Widget Animation Degrades Over Time

Aaron Radich aaron at radich.com
Thu Jul 29 13:40:33 EDT 2010




I've created a custom marquee widget that displays scrolling text and
images similar.  The widget works great when first ran, but over time
slows down eventually grinding down to a halt/freeze.  I'm assuming that
there is some sort of resource issue that I am not managing wisely.  Most
of the magic for the display happens in the DrawingArea's ExposeEvent,
which I am forcing to fire with the DrawingArea.QueueDraw() method call
(looping triggered from a GLib.Timeout).  Does anyone see anything that
might be contributing to my performance
issue?
Aaron
===========================================
     
protected virtual void OnObjDrawingAreaExposeEvent(object o,
Gtk.ExposeEventArgs args)
      {
         //base.OnExposeEvent
(args);
        
         // Insert custom drawing code here.
         try
         {
            iYTrans =
GetTranslatedCoordinate(MarqueeDirection.Up, "y", y);
            iXTrans = GetTranslatedCoordinate(MarqueeDirection.Left,
"x", x);
            iXTransAdjusted = iYTransAdjusted =
0;

            // create bmpTmp, a snapshot of a portion of the
main bitmap
            if (BmpMain != null)

               lock (this) 
               {
                 
int iSmallerWidth = objDrawingArea.Allocation.Width > BmpMain.Width ?
BmpMain.Width : objDrawingArea.Allocation.Width;

                  int iSmallerHeight = objDrawingArea.Allocation.Height
> BmpMain.Height ? BmpMain.Height :
objDrawingArea.Allocation.Height;

                  switch
(FScrollingDirection)
                  {
                    
case MarqueeDirection.Up:
                        // build full and
partial bitmaps for up and down scrolling
                        if
(iYTrans >= 0 && iYTrans < BmpMain.Height -
objDrawingArea.Allocation.Height)
                        {  // build
full bitmap
                           BmpTmp = BmpMain.Clone(
                              new RectangleF(
                              new PointF(0, iYTrans),
                              new SizeF(iSmallerWidth,
iSmallerHeight)),
                             
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                        }
                        else if (iYTrans
< 0)
                        {  // build partial bitmap at top
(beginning)
                           // set iYTransAdjusted
                           if (objDrawingArea.Allocation.Height +
iYTrans > BmpMain.Height)
                             
iYTransAdjusted = BmpMain.Height;
                           else if
(objDrawingArea.Allocation.Height + iYTrans <= 0)
                              iYTransAdjusted = 1;
                           else
                             
iYTransAdjusted = objDrawingArea.Allocation.Height + iYTrans;

                           BmpTmp = BmpMain.Clone(
                              new RectangleF(
                              new PointF(0, 0),
                              new SizeF(iSmallerWidth,
iYTransAdjusted)),
                             
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                        }

                        else if
((iYTrans >= BmpMain.Height - objDrawingArea.Allocation.Height)
&& iYTrans < BmpMain.Height)
                        {  //
build partial bitmap at bottom (end)
                          
BmpTmp = BmpMain.Clone(
                              new
RectangleF(
                              new PointF(0, iYTrans),
                              new SizeF(iSmallerWidth, BmpMain.Height -
iYTrans)),
                             
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                        }
                        break;
                     case MarqueeDirection.Left:
                        if (iXTrans > 0 && iXTrans <
BmpMain.Width - objDrawingArea.Allocation.Width)
                        {  // build full bitmap
                           BmpTmp = BmpMain.Clone(
                              new RectangleF(
                              new PointF(iXTrans, 0),
                              new SizeF(iSmallerWidth,
iSmallerHeight)),
                             
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                        }
                        else if (iXTrans
< 0)
                        {  // build partial bitmap at left
(beginning)
                           // iXTransAdjusted
                           if (objDrawingArea.Allocation.Width + iXTrans
> BmpMain.Width)
                              iXTransAdjusted =
BmpMain.Width;
                           else if
(objDrawingArea.Allocation.Width + iXTrans <= 0)
                              iXTransAdjusted = 1;
                           else
                             
iXTransAdjusted = objDrawingArea.Allocation.Width + iXTrans;

                           BmpTmp = BmpMain.Clone(
                              new RectangleF(
                              new PointF(0, 0),
                              new SizeF(iXTransAdjusted,
iSmallerHeight)),
                             
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                        }
                        else if ((iXTrans
>= BmpMain.Width - objDrawingArea.Allocation.Width) && iXTrans
< BmpMain.Width)
                        {  // build partial
bitmap at right (end)
                           BmpTmp =
BmpMain.Clone(
                              new RectangleF(
                              new PointF(iXTrans, 0),
                              new SizeF(BmpMain.Width - iXTrans,
iSmallerHeight)),
                             
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                        }
                        break;
                  } // switch(_direction)
               } //
lock(this)

            // draw bmpTmp on the screen
            if (BmpTmp != null)
            {
              
BmpTmp.MakeTransparent(BGColor);

               using (Graphics
g = Gtk.DotNet.Graphics.FromDrawable(args.Event.Window))
               {
                  if (FScrollingDirection ==
MarqueeDirection.Up)
                  {
                     if
(iYTrans < 0)   // draw partial at top
                       
//e.Graphics.DrawImageUnscaled(bmpTmp, 0, -iYTrans);
                        g.DrawImageUnscaled(BmpTmp, 0, -iYTrans);
                     else              // draw a full / bottom bmp
starting at the top of the screen
                       
//e.Graphics.DrawImageUnscaled(bmpTmp, 0, 0);
                       
g.DrawImageUnscaled(BmpTmp, 0, 0);
                  }
                  else if (FScrollingDirection ==
MarqueeDirection.Left)
                  {
                    
if (iXTrans < 0)   // draw partial at left
                       
//e.Graphics.DrawImageUnscaled(bmpTmp, -iXTrans, 0);
                        g.DrawImageUnscaled(BmpTmp, -iXTrans, 0);
                     else              // draw full at left
                        //e.Graphics.DrawImageUnscaled(bmpTmp, 0, 0);
                        g.DrawImageUnscaled(BmpTmp, 0, 0);
                  }
                  bGotExposedPaint = true;
               }
            }

            // free up
the temporary bitmap
            //BmpTmp.Dispose();
           
//BmpTmp = null;
         }
         catch //(Exception ex)
         {
            //string s = ex.ToString();
           
//int i    = 5;
            //this.Stop();
           
//using(Font f = new Font("verdana", 18))
           
//{
            //   this.DisplayItems.Clear();
            //  
this.DisplayItems.Add(new DisplayObject(ex.ToString(), f, Brushes.Red),
(int)CreateGraphics().MeasureString(ex.Message, f, Size).Width,
iLineSpacing, _direction);
            //   this.Start();
            //}
         }
        
         //return
true;
      }




More information about the Gtk-sharp-list mailing list