PiRSquared17 / piccolo2d

Automatically exported from code.google.com/p/piccolo2d
0 stars 0 forks source link

Problems using Piccolo 1.2.1.NET PScrollableContol with MS Visual Studio 2008 #78

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
From piccolo2d-dev:

from    pz0151 <steffen.ploetz at cityweb.de>
to  Piccolo2D Developers <piccolo2d-dev at googlegroups.com>
date    Wed, Mar 25, 2009 at 1:58 PM

I wanted to use PScrollableContol with PCanvas and had some problems
to get this combination run.
Here are the rurn aronds i found:

Step 1
======
Placing a PScrollableContol onto a Panel causes an "object reference
not set to an instance of an object" error in PScrollableContol.cs in
line 624

               public virtual Size GetViewSize(RectangleF bounds) {
                       return scrollDirector.GetViewSize(bounds);
               }

My suggestion:

               public virtual Size GetViewSize(RectangleF bounds) {
           if (scrollDirector != null)
               return scrollDirector.GetViewSize(bounds);
           else
               return new Size();
               }

Step 2
======
After this repair placing a PScrollableContol onto a Panel causes an
"object reference not set to an instance of an object" error in
PScrollableContol.cs in line 515

               protected override void OnLayout(LayoutEventArgs levent) {
                       ...
                       if (vsbNeeded) {
                               vScrollBar.Height = availRect.Height;
                               vScrollBar.Visible = true;
                       }
                       else {
                               vScrollBar.Visible = false;
                       }

                       if (hsbNeeded) {
                               hScrollBar.Width = availRect.Width;
                               hScrollBar.Visible = true;
                       }
                       else {
                               hScrollBar.Visible = false;
                       }

                       view.Size = availRect.Size;
               }

My suggestion:

               protected override void OnLayout(LayoutEventArgs levent) {
                       ...
                       if (vsbNeeded && vScrollBar != null) {
                               vScrollBar.Height = availRect.Height;
                               vScrollBar.Visible = true;
                       }
                       else if (vScrollBar != null) {
                               vScrollBar.Visible = false;
                       }

                       if (hsbNeeded && hScrollBar != null) {
                               hScrollBar.Width = availRect.Width;
                               hScrollBar.Visible = true;
                       }
                       else if (hScrollBar != null) {
                               hScrollBar.Visible = false;
                       }

                       view.Size = availRect.Size;
               }

Step 3
======
After this repair placing a PScrollableContol onto a Panel causes an
"object reference not set to an instance of an object" error in
PScrollableContol.cs in line 526

               protected override void OnLayout(LayoutEventArgs levent) {
                       ...

                       view.Size = availRect.Size;
               }

My suggestion:

               protected override void OnLayout(LayoutEventArgs levent) {
                       ...
           if (view != null) {
                       view.Size = availRect.Size;
           }
               }

Step 4
======
Now we can error-free place a PScrollableContol onto a Panel and
assign the Canvas property to a PCanvas.
But starting the application causes a "object reference not set to an
instance of an object" error in PScrollableContol.cs in line 594

               public virtual Size Extent {
                       get {
                               int offset = 0;
                               if (vScrollBar.Visible) {
                                       offset = DEFAULT_SCROLL_WIDTH;
                               }
                               int width = Math.Max(0,
ClientRectangle.Width - offset);

                               offset = 0;
                               if (hScrollBar.Visible) {
                                       offset = DEFAULT_SCROLL_WIDTH;
                               }
                               int height = Math.Max(0,
ClientRectangle.Height - offset);

                               return new Size(width, height);

                       }
               }

Cause is the property initialization sequence, MS Visual Studio
generates for our PScrollableContol:

                       ...
           this.pScrollableControl1.AutoLargeChange = true;
           this.pScrollableControl1.AutoLargeChangeFactor = 0.9F;
           this.pScrollableControl1.Canvas = this.Panel_Content;
                       ...

AutoLargeChange is set before Canvas, but without canvas the
vScrollBar and hScrollBar attributes of our PScrollableContol are not
initialized.
My suggestion:

               public virtual Size Extent {
                       get {
                               int offset = 0;
                               if (vScrollBar != null && vScrollBar.Visible) {
                                       offset = DEFAULT_SCROLL_WIDTH;
                               }
                               int width = Math.Max(0,
ClientRectangle.Width - offset);

                               offset = 0;
                               if (hScrollBar != null && hScrollBar.Visible) {
                                       offset = DEFAULT_SCROLL_WIDTH;
                               }
                               int height = Math.Max(0,
ClientRectangle.Height - offset);

                               return new Size(width, height);

                       }
               }

Step 5
======
Another "object reference not set to an instance of an object" error
in conjunction with this problem occurs in PScrollableContol.cs occurs
in line 617, 644 and 543

               public virtual Size ViewSize {
                       get {
                               return scrollDirector.GetViewSize(new
RectangleF(0, 0,
Extent.Width, Extent.Height));
                       }
               }

               public virtual Point ViewPosition {
                       get {
                               return scrollDirector.GetViewPosition(new
RectangleF(0, 0,
Extent.Width, Extent.Height));
                       }
                       set {
                               SetViewPosition(value, false);
                       }
               }

               public virtual void UpdateScrollbars() {
                       if (scrollable) {
                               // update values
                               Size s = ViewSize;
                               Point p = ViewPosition;

                               vScrollBar.Maximum = s.Height-(Extent.Height-
VLargeChangePixels)-1;
                               vScrollBar.Value = p.Y;

                               hScrollBar.Maximum =
s.Width-(Extent.Width-HLargeChangePixels)-1;
                               hScrollBar.Value = p.X;

                               // layout controls
                               PerformLayout();

                               vScrollBar.SmallChange = VSmallChangePixels;
                               vScrollBar.LargeChange = VLargeChangePixels;
                               hScrollBar.SmallChange = HSmallChangePixels;
                               hScrollBar.LargeChange = HLargeChangePixels;
                       }
               }

My suggestion:

               public virtual Size ViewSize {
                       get {
               if (scrollDirector != null) {
                   return scrollDirector.GetViewSize(new RectangleF
(0, 0, Extent.Width, Extent.Height));
               }
               else {
                   return new Size();
               }
                       }
               }

               public virtual Point ViewPosition {
                       get {
                               if (scrollDirector != null) {
                   return scrollDirector.GetViewPosition(new
RectangleF(0, 0, Extent.Width, Extent.Height));
               }
               else {
                   return new Point();
               }
                       }
                       set {
                               SetViewPosition(value, false);
                       }
               }

               public virtual void UpdateScrollbars() {
                       if (scrollable) {
                               // update values
                               Size s = ViewSize;
                               Point p = ViewPosition;

                               if (vScrollBar != null) {
                   vScrollBar.Maximum = s.Height-(Extent.Height-
VLargeChangePixels)-1;
                                   vScrollBar.Value = p.Y;
               }
               if (hScrollBar != null) {
                               hScrollBar.Maximum = s.Width-(Extent.Width-
HLargeChangePixels)-1;
                               hScrollBar.Value = p.X;
                           }
                               // layout controls
                               PerformLayout();

                               if (vScrollBar != null) {
                   vScrollBar.SmallChange = VSmallChangePixels;
                                   vScrollBar.LargeChange = VLargeChangePixels;
               }
                               if (hScrollBar != null) {
                               hScrollBar.SmallChange = HSmallChangePixels;
                               hScrollBar.LargeChange = HLargeChangePixels;
               }
                       }
               }

Step 6
======
Now the application can be started without runtime error, but the
scroll bars are not placed at the right and bottom boundary of our
PScrollableContol.
My suggestion is to add a new method UpdateScrollbarLocations() for
PScrollableContol after UpdateScrollbars().

       /// <summary>
       /// Updates the locations of the scrollbars.
       /// </summary>
       public virtual void UpdateScrollbarLocations() {
           vScrollBar.Bounds = new Rectangle(ClientRectangle.Width -
DEFAULT_SCROLL_WIDTH, ClientRectangle.Y, DEFAULT_SCROLL_WIDTH,
ClientRectangle.Height - DEFAULT_SCROLL_WIDTH);
           hScrollBar.Bounds = new Rectangle(ClientRectangle.X,
ClientRectangle.Height - DEFAULT_SCROLL_WIDTH, ClientRectangle.Width -
DEFAULT_SCROLL_WIDTH, DEFAULT_SCROLL_WIDTH);
       }

And to call it in the application constructor after InitializeComponent
():

           InitializeComponent();
                       pScrollableControl1.UpdateScrollbarLocations();

Advice
======
To get use of the scroll capability, set PCanca's Layer size grater
than PScrollableContol size.
To adjust event argument positions to scroll positions use the
Camera.ViewMatrix property.

Original issue reported on code.google.com by heue...@gmail.com on 25 Mar 2009 at 8:15

GoogleCodeExporter commented 9 years ago
I have the same problems. Thanks for useful pointers. I'll check these solution.

Original comment by langxangvn on 7 Jul 2009 at 8:16