Problems with inconsistent script results.

seanhoughton

Active member
I'm having a really difficult time getting the HorizontalSizer to work.  My brute force approach to the problem was to keep deleting things until my script looked exactly like the HelloWorld example.  I did this and it was still broken.  The only difference was one variable name.  I renamed this and all of a sudden the sizer started working.  I renamed it back to the original name and it still worked, which is pretty weird.  I started from scratch again and I've included the script below.  How do I make the controls stack?

Code:
#include <pjsr/Sizer.jsh>
#include <pjsr/FrameStyle.jsh>
#include <pjsr/TextAlign.jsh>
#include <pjsr/StdButton.jsh>
#include <pjsr/StdIcon.jsh>
#include <pjsr/NumericControl.jsh>

#define TITLE Demonstration
#define VERSION 0.1

function DemonstrationDialog()
{
   this.__base__ = Dialog;
   this.__base__();

   this.helpLabel = new Label( this );
   with ( this.helpLabel )
   {
      frameStyle = FrameStyle_Box;
      margin = 4;
      wordWrapping = true;
      useRichText = true;
      text = "This is a helpful label";
   }

   this.findExposureButton = new PushButton( this );
   this.findExposureButton.text = "Press me";

   this.contentSizer = new VerticalSizer;
   this.contentSizer.add(this.helpLabel);
   this.contentSizer.add(this.findExposureButton);


   this.windowTitle = #TITLE + " Script";
   this.adjustToContents();
}


DemonstrationDialog.prototype = new Dialog;

var dialog = new DemonstrationDialog;
dialog.execute();
 
Hi Sean,

Welcome to PixInsight development.

The problem is here:

Code:
   this.contentSizer = new VerticalSizer;
   this.contentSizer.add(this.helpLabel);
   this.contentSizer.add(this.findExposureButton);

With these sentences you are defining a
Code:
contentSizer
property of your dialog. That's fine syntactically but it doesn't work as you expect.

What you need to define is the
Code:
Control.sizer
property, which has been inherited by the
Code:
Dialog
object, which in turn your
Code:
DemonstrationDialog
inherits from because you execute Dialog's constructor at the beginning of your dialog's constructor:

Code:
   this.__base__ = Dialog;
   this.__base__();

So the correct code is:

Code:
   this.sizer = new VerticalSizer;
   this.sizer.add(this.helpLabel);
   this.sizer.add(this.findExposureButton);

Now, the Sizer object (the HorizontalSizer and VerticalSizer objects are just wrappers to Sizer defined in pjsr/Sizer.jsh) doesn't provide automatic separation between items and a margin between the dialog and its contents by default (this is common to both PJSR and PCL). For a sizer object defining the entire layout of a dialog, you must set these properties explicitly with reasonable values:

Code:
   this.sizer = new VerticalSizer;
   this.sizer.margin = 8;
   this.sizer.spacing = 6;
   this.sizer.add(this.helpLabel);
   this.sizer.add(this.findExposureButton);

Next, you usually want to ensure reasonable minimum dimensions for your dialog so that the user cannot reduce it down to a few pixels. This is best done by calling the inherited
Code:
Control.setMinSize()
method. For example:

Code:
   this.setMinSize( 300, 200 );

Finally, you normally don't want the console to remain visible during normal operation of your script. For scripts that provide a graphical user interface, it is customary hiding the console by invoking:

Code:
   console.hide();

With all of these modifications your script works fine and looks like this:

Code:
#include <pjsr/Sizer.jsh>
#include <pjsr/FrameStyle.jsh>
#include <pjsr/TextAlign.jsh>
#include <pjsr/StdButton.jsh>
#include <pjsr/StdIcon.jsh>
#include <pjsr/NumericControl.jsh>

#define TITLE Demonstration
#define VERSION 0.1

function DemonstrationDialog()
{
   this.__base__ = Dialog;
   this.__base__();

   this.helpLabel = new Label( this );
   with ( this.helpLabel )
   {
      frameStyle = FrameStyle_Box;
      margin = 4;
      wordWrapping = true;
      useRichText = true;
      text = "This is a helpful label";
   }

   this.findExposureButton = new PushButton( this );
   this.findExposureButton.text = "Press me";

   this.sizer = new VerticalSizer;
   this.sizer.margin = 8;
   this.sizer.spacing = 6;
   this.sizer.add( this.helpLabel );
   this.sizer.add( this.findExposureButton );

   this.setMinSize( 300, 200 );

   this.windowTitle = #TITLE + " Script";
  
   this.adjustToContents();
}

DemonstrationDialog.prototype = new Dialog;

console.hide();

var dialog = new DemonstrationDialog;
dialog.execute();

Hope this helps.
 
Aha!  Javascript's automatic member variable creation on assignment is ripe for these kinds of mistakes  :'(  The JS API was pretty easy to work with (other than the sizer snafu) but at some point I'll give the c++ interface a try too.

I'll post my new script tonight.
 
Back
Top