Author Topic: JS: event triggered programatically  (Read 4993 times)

Offline David Serrano

  • PTeam Member
  • PixInsight Guru
  • ****
  • Posts: 503
JS: event triggered programatically
« on: 2007 September 05 11:18:36 »
As per our conversation on the KSIntegration thread, I've edited the code leaving only the relevant part. This is it:

Code: [Select]
// didn't bother to clean these up
#include <pjsr/Sizer.jsh>
#include <pjsr/FrameStyle.jsh>
#include <pjsr/NumericControl.jsh>
#include <pjsr/TextAlign.jsh>
#include <pjsr/StdButton.jsh>
#include <pjsr/StdIcon.jsh>
#include <pjsr/ColorSpace.jsh>
#include <pjsr/SampleType.jsh>
#include <pjsr/UndoFlag.jsh>

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

   // sequence of spaces to be prepended to debug stmts, to visually show the
   // increasing "depth" of the code flow
   this.strpad = "";

   this.target_List = new TreeBox (this);
   this.target_List.setMinSize (400, 200);
   this.target_List.font = new Font ("monospace", 10); // best to show tabulated data
   this.target_List.numberOfColumns = 2;
   this.target_List.headerVisible = true;
   this.target_List.headerSorting = true;
   this.target_List.setHeaderText (0, "Views");
   this.target_List.setHeaderText (1, "Dimensions");
   this.target_List.setHeaderAlignment (0, Align_Left);
   this.target_List.setHeaderAlignment (1, Align_Left);
   this.target_List.onNodeUpdated = function() {
      var node = this.dialog.target_List.currentNode;
      var foo=0;
      this.dialog.strpad += "  ";         // add padding before entering loop
      for (bar in node) if (!foo++) {     // beware of the dog!
         // walk the list and set the similar images to the state of the just-clicked one
         console.writeln (format ("%snode (%s) updated", this.dialog.strpad, node.text (0)));
         for (i = 0; i < this.dialog.target_List.numberOfChildren; i++) {
            console.writeln (format ("%sin loop, iteration (%d)", this.dialog.strpad, i));
            if (this.dialog.target_List.child (i).text (1) == node.text (1)) {
               // If onNodeUpdated is called now, we will enter this function again without
               // trimming strpad, so the following debug stmts will appear more padded.
               //
               // If not, we will exit this loop and some padding will be removed.
               console.writeln (format ("%sabout to tick a box", this.dialog.strpad));
               this.dialog.target_List.child (i).checked = node.checked;
               console.writeln (format ("%sticked and still alive!", this.dialog.strpad));
            }
         }
      }
      // remove padding after loop
      this.dialog.strpad = this.dialog.strpad.substr (0, this.dialog.strpad.length - 2);
   }

   // Node creation helper
   function addViewNode (parent, view) {
      var node = new TreeBoxNode (parent);
      node.checkable = true;
      node.checked = false;

      node.setText (0, view.fullId);

      var image = view.image;
      var metadata = format ("%5d x %5d x %d", image.width, image.height, image.numberOfChannels);
      node.setText (1, metadata);

      return node;
   }

   // Build the view tree structure
   var windows = ImageWindow.windows;
   for (var i = 0; i < windows.length; ++i) {
      var node = addViewNode (this.target_List, windows[i].mainView);
      node.expanded = false; // or true to initially expand all preview lists

      var previews = windows[i].previews;
      for (var j = 0; j < previews.length; ++j)
         addViewNode (this.target_List, previews[j]);
   }
   this.target_List.sort();

   // Ensure that all columns are initially visible
   this.target_List.adjustColumnWidthToContents (0);
   this.target_List.adjustColumnWidthToContents (1);

   this.adjustToContents();
}

kappa_sigma_dialog.prototype = new Dialog;
var dialog = new kappa_sigma_dialog();

dialog.execute();


(This code actually reveals two bugs. I'll talk about the "dog" :P in another report).

The output I get from this script with two images open, when selecting the first of them in the script interface is the following. I've manually labeled some of the lines for reference after pasting them here.

Code: [Select]
 node (Image01) updated
  in loop, iteration (0)
  about to tick a box
  ticked and still alive!           [1]
  in loop, iteration (1)
  about to tick a box               [2]
    node (Image01) updated          [3]
    in loop, iteration (0)
    about to tick a box
    ticked and still alive!         [4]
    in loop, iteration (1)
    about to tick a box
    ticked and still alive!         [5]
  ticked and still alive!


I think we get to [1] without recursion because the engine knows we are working with that image, so it shouldn't call onNodeUpdated again. In [2] we're in the second iteration of the loop, about to enable the second box. Then we find ourselves in [3], i.e. onNodeUpdated was called. Note that the image name is still Image01 and the indentation of the output (called "padding" in the code) is bigger. Again, in [4] the engine knows that this object is in some way related to our current situation, so doesn't enter the function again. Same in [5].

If I click the second image instead of the first, this is the output:

Code: [Select]
 node (Image02) updated
  in loop, iteration (0)
  about to tick a box
    node (Image02) updated
    in loop, iteration (0)
    about to tick a box
    ticked and still alive!
    in loop, iteration (1)
    about to tick a box
    ticked and still alive!
  ticked and still alive!


The indentation grows in the first pass of the loop because the first image has not been "seen" yet. From then on, everything should be self-explanatory by now.

Of course, trying this with more than two images makes the output much longer, but completely predictable otherwise.
--
 David Serrano

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
JS: event triggered programatically
« Reply #1 on: 2007 September 06 09:44:35 »
Ok, this IS a bug  :lol:

I'm fixing it now. By the way, this bug manifests nicely in the Dogs & Cats dialog, see the other thread where I've just answered your post.

Well, the onNodeUpdated is complex because it gets called whenever you change a single property of TreeBoxNode (text, icon, checked state, etc) programmatically. Fortunately, no infinite recursion is happening, or there are a lot of things that could go really wrong in the platform. Shhhh, dont tell anyone... :lol:
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline David Serrano

  • PTeam Member
  • PixInsight Guru
  • ****
  • Posts: 503
JS: event triggered programatically
« Reply #2 on: 2007 October 12 09:25:08 »
Just checked that this is gone :).
--
 David Serrano