App-PLab

 view release on metacpan or  search on metacpan

bin/PrLenS  view on Meta::CPAN

#!perl -w

use strict;
use warnings;
use Prima;
use Prima::Application name => "PrLenS";
use Prima::Edit;
use Prima::ExtLists;
use App::PLab;
use App::PLab::ImageApp;
use App::PLab::Calibrations;
use Prima::IPA qw/Local Misc Point Global Morphology Region/;
use Prima::VB::VBLoader;
use XML::Parser;

$::application-> icon( App::PLab::ImageAppGlyphs::icon( bga::processes));


package LenWindow;
use vars qw(@ISA);
@ISA = qw(App::PLab::Calibrations);

use constant MAXDATASET => 5;

sub win_inidefaults
{
   my $w = $_[0];
   return (
      $w-> SUPER::win_inidefaults,
      PointSize          => 4,
      nLines             => 6,
      autoCrispen        => 0,
      autoStretch        => 0,
      StatisticsWindowRect => '120 120 400 250',
      StatisticsWindowFont => 0,
      SpectrumMin        => 0,
      SpectrumMax        => 50,
      ShowExtras         => 0,
      ShowPrevExtras     => 0,
      C_minUF            => 1,
      C_maxUF            => 5,
      C_stepUF           => 10,
      C_min_area         => 200,
      C_min_rank         => 1,
      C_max_index        => 255,
      C_min_index        => 0,
      C_dilations        => 2,
      C_branch_radius    => 3,
      active_datasets    => 2,
      dataset_0_name     => 'cells',
      dataset_1_name     => 'processes',
      ( map { ( "dataset_${_}_name", "dataset" . ($_+1) ) } 2 .. MAXDATASET ),
      visible_datasets   => 0xffff,
   );
}


sub on_create
{
   my $self = $_[0];
   my $w    = $_[0];
   $self-> SUPER::on_create;
   $self-> {dataExt}            = 'pls';
   
   my $tb  = $self-> ToolBar;
   my $scale = $::application-> uiScaling;
   $scale = 1 if $scale < 1;

   my %btn_profile = (
     glyphs      => 1,
     text        => "",
     selectable  => 0,
     transparent => 1,
     flat        => 1,
     size        => [ map { $_ * $scale } 36, 36],
     borderWidth => 1,
     enabled     => 0,
   );

   $tb-> insert(
      [ SpeedButton =>
         name    => "MarkCells",
         origin  => [120 * $scale, 1],
         image   => App::PLab::ImageAppGlyphs::icon( bga::cells),
         onClick => sub { $w-> mark_cells },
         hint    => "Mark cells mode",
         %btn_profile,
      ],
      [ SpeedButton =>
         name    => "MarkProcesses",
         origin  => [160 * $scale, 1],
         image   => App::PLab::ImageAppGlyphs::icon( bga::processes),
         onClick => sub { $w-> mark_processes} , 
         hint    => "Mark processes mode",
         %btn_profile,
      ],
      [ SpeedButton =>
         name    => "DrawProcesses",
         origin  => [200 * $scale, 1],
         image   => App::PLab::ImageAppGlyphs::icon( bga::drawprocesses),
         onClick => sub { $w-> draw_processes} ,
         hint    => "Draw processes mode",
         %btn_profile,
      ],
      [ Label =>
         name => "CellsProcesses",
         font => { size => 10, pitch => fp::Fixed}, 
         color => cl::Red,
         origin => [ 249 * $scale, 8 * $scale],
	 size   => [ 80 * $scale, 20 * $scale],
         transparent => 1,
         text   => "???:???",
	 valignment => ta::Middle,
      ],
      [ Widget => 
          name => "MarkStateEx",
          transparent => 1,
          origin  => [ 336 * $scale, 8 * $scale],
          size    => [ 20 * $scale, 20 * $scale],
          color   => 0,
          onPaint => sub {
             my ( $self, $canvas) = @_;

bin/PrLenS  view on Meta::CPAN

         'Prima::Edit' =>
         name => 'StatText',
         readOnly => 1,
         hScroll => 1,
         vScroll => 1,
         font => \%font,
         origin => [ 0,0],
         size => [ $sd-> size],
         growMode => gm::Client,
         text => $w-> generate_statistics_text(),
         blockType => bt::Vertical,
      );

      $norepaint = 1;
   }

   $sd->StatText->text( $w-> generate_statistics_text()) unless $norepaint;
}

sub file_backup
{
   my $w = $_[0];
   my ( $cpm, $file) = ( $w-> {cypherMask}, $w-> win_extname( $w-> {file}));
   $file =~ s/\d{$cpm}(\.pls)$/$1/;
   return if Prima::MsgBox::message( "Copy $file to $file.bak?", mb::OKCancel) != mb::OK;
   return if -f "$file.bak" and Prima::MsgBox::message( "$file.bak exists. Overwrite?", mb::OKCancel) != mb::OK;
   require File::Copy;
   return if File::Copy::copy( $file, "$file.bak");
   Prima::MsgBox::message( "Error:$!", mb::OK|mb::Error);
}

sub draw_processes {
   my $w = $_[0];
   $w-> done_draw_mode;
   $w->{ binfo}->{ drawMode} = 0;
   undef $w->{ binfo}->{ nearestBranch};
   undef $w->{ binfo}->{ prevActiveRect};
   $w-> reset_mark_state(( defined( $w-> {markState}) && ( $w-> {markState} == 16) ? undef : 16))
      if defined $w-> {file};
   $w-> reset_mark_state( $w, undef) unless defined $w-> {file};
}

sub mark_cells
{
   my $w = $_[0]; 
   $w-> reset_mark_state( 1) if defined $w-> {file};
   $w-> reset_mark_state( undef) unless defined $w-> {file};
}

sub mark_processes
{
   my $w = $_[0];
   $w-> reset_mark_state( 0) if defined $w-> {file};
   $w-> reset_mark_state( undef) unless defined $w-> {file};
}


sub win_newframe
{
   my $w = $_[0];
   $w-> SUPER::win_newframe;
   for ( @{$w->{layers}}) {
      my $c = ucfirst $_;
      $w-> {$_} = [];
      $w-> {"ex$c"} = [];
      $w-> {"prevex$c"} = [];
      $w-> {"n$c"} = $w-> {"total$c"} = 0;
   }
   $w-> {branches} = [];
   $w-> modified(0);
   $w-> reset_mark_state; 
   $w-> {mirrorImage} = undef;
   $w-> {recWindow}-> RestoreBtn-> enabled( 0) if $w-> {recWindow};

   return unless defined $w-> {file};

   $w-> win_extwarn if defined $w-> {ini}-> {path} &&
      defined $w-> {oldPath} && $w-> {oldPath} ne $w-> {ini}-> {path};
   $w-> {oldPath} = $w-> {ini}-> {path};
   $w-> preprocess;
}

sub win_loadfile
{
   my ($w,$file) = @_;
   return 0 unless $w-> SUPER::win_loadfile( $file);
   $w-> update_state;
   return 1; 
}

sub win_newextras
{
   my $w = $_[0];
   $w-> SUPER::win_newextras;

   return unless defined $w-> {file};
   $w-> load_info();
}

sub win_saveframe
{
   my $w = $_[0];
   return $w-> save_info();
}

sub win_closeframe
{
   my $w = $_[0];
   $w-> SUPER::win_closeframe;
   $w-> reset_mark_state;
}


sub win_framechanged
{
   my $w = $_[0];
   $w-> SUPER::win_framechanged;

   my $tb = $w-> ToolBar;
   my $i = $w-> IV-> image;
   my $canApply = defined $i && $i-> type == im::Byte;

   $w-> menu-> FileStats-> enabled( $i);
   $w-> menu-> FileBackup-> enabled( $i);
   $w-> menu-> EditProcess-> enabled( $canApply);   
   $w-> menu-> EditProcessSeries-> enabled( $canApply);   
   $tb-> MarkCells-> enabled( $i);
   $tb-> MarkProcesses-> enabled( $i);
   $tb-> DrawProcesses-> enabled( $i);
   if ( $w-> {recWindow}) {
      my $r = $w-> {recWindow};
      $r-> ApplyBtn-> enabled( $canApply);
      $r-> RestoreBtn-> enabled( $canApply && defined $w-> {mirrorImage});
      $r-> PD1-> enabled( $canApply);
      $r-> PD2-> enabled( $canApply);
      $r-> PD3-> enabled( $canApply);
   }
   $w-> reset_mark_state;
   $w-> update_state;
}


sub reset_mark_state
{
   my ( $w, $state)  = @_;
   unless ( defined $state) {
      my $x = $w-> {markStateX} || 0;
      $state = defined($w-> {file}) ? $x : ( $x | 0x10000);
   } elsif ( $state =~ /^next|prev$/ && defined $w->{file}) {
      if ( defined $w-> {markStateX} && ($w-> {markStateX} & 0x10)) {
         $state = 0;
      } else {
         $state = ($w->{markState} || 0) + (( $state eq 'next') ? 1 : -1);
         $state = 0 if $state >= $w->{ini}->{active_datasets};
         $state = $w->{ini}->{active_datasets} - 1 if $state < 0;
      }
   } elsif ( $state eq 'draw' && defined $w->{file}) {
      $state = 0x10;
   }

   my $markState = $w-> ToolBar-> MarkState;
   my $markStateEx = $w-> ToolBar-> MarkStateEx;
   if ( $state & 0x10000) {
      $markState-> text( "Nothing to mark");
      $markStateEx-> color( 0);
      return;
   }
   if ( $state & 0x10) {
      $markState-> text( "Drawing processes" . ( $w->{ binfo}->{ drawMode} ? " (drawing)" : "")) ;
      $markStateEx-> color( 0);
   } else {
      my $layer = $w-> {layers}->[$state];
      $markState-> text( "Marking $layer");
      $markStateEx-> color( $w-> {ini}-> {"Color_" . (( $state < 2) ? ucfirst $layer : "Dataset$state")});
   }
   $w-> {markStateX} = $state;
   $w-> {markState} = ($state & 0x10000) ? undef : $state;

bin/PrLenS  view on Meta::CPAN

         
         # don't need'em for a while
         UF => { enabled => 0},
         
      )}-> {Form1}};
     if ( $@) { Prima::message("Error in setup resource: $@"); return };
     my ( $r, $i) = ( $w-> {recWindow}, $w-> {ini});
     $r-> UF-> From-> value ($i-> {C_minUF}   ); 
     $r-> UF-> To-> value   ($i-> {C_maxUF}  );
     $r-> UF-> Step-> value ($i-> {C_stepUF}  );
     $r-> FLT-> Min-> value ($i-> {C_min_index});
     $r-> FLT-> Max-> value ($i-> {C_max_index});
     $r-> Area-> value      ( $i-> {C_min_area});
     $r-> Dilations-> value ($i-> {C_dilations});
     $r-> Radius-> value  ( $i-> {C_branch_radius});
     $w-> win_framechanged;
  }
  $w-> {recWindow}-> bring_to_front;
  $w-> {recWindow}-> select;
}


sub IV_MouseDown
{
   my ( $w, $self, $btn, $mod, $x, $y) = @_;
   if ( ( ( $btn & mb::Left) == mb::Left)
           && ( defined $w->{ markState}) && ( $w->{ markState} == 16)
           && ( ( ! defined $w->{ binfo}) || ( ! $w->{ binfo}->{ drawMode}))) {
       $w-> initiate_draw_mode( $x, $y); 
       $self-> clear_event;
       return;
   }

   if ( $btn == mb::Right && !( $mod & km::Ctrl)) 
   {
      if ( ! defined( $w-> { markState}) || $w-> { markState} < 16)
      {
         $w-> reset_mark_state(( $mod & km::Shift) ? 'prev' : 'next');
      }
      else {
         if ( $w->{ binfo}->{ drawMode}) {
            $w-> done_draw_mode();
         }
         elsif ( defined( $w->{ binfo}->{ nearestBranch})) {
            $w->{ totalLength} -= $w-> calc_branch_length( $w->{ branches}->[ $w->{ binfo}->{ nearestBranch}]);
            $w->{ totalBranches}--;
            splice @{ $w->{ branches}}, $w->{ binfo}->{ nearestBranch}, 1;
            $w->{ binfo}->{ nearestBranch} = undef;
            $w-> modified( 1); 
            $self-> repaint;
         }
         $w-> show_stats( undef, 1);
      }
      $self-> clear_event;
      return;
   }
   
   if ( $btn == mb::Right && ($mod & km::Ctrl)) {
      $mod &= !km::Ctrl;
   }
   $w-> SUPER::IV_MouseDown( $self, $btn, $mod, $x, $y); 
}

sub IV_MouseMove
{
   my ( $w, $self, $mod, $x, $y) = @_;

   unless ( $self->{transaction}) {
      if (( $mod & km::Shift) && defined $self-> image) {
         my $i = $self-> image;
         my $pix = $i-> pixel( $self-> screen2point( $x, $y));
         $w-> sb_text((( $i-> type & im::BPP) > 8) ?
            sprintf("%02x %02x %02x", ($pix>>16)&0xFF, ($pix>>8)&0xFF, $pix&0xFF) :
            $pix
         ) if $pix != cl::Invalid;
      }
   }
   
   $w-> SUPER::IV_MouseMove( $self, $mod, $x, $y);

   return if !defined $w-> {binfo} || !defined $w-> {markState} || $w-> {markState} != 16;

   if ( $w->{ binfo}->{ drawMode} == 1) {
      my ( $bn) = $w->{ binfo}->{ branchNumber};
      my ( $ox, $oy) = @{ $w->{ branches}->[ $bn]->[ -1]};
      my ( $ax, $ay) = $self-> screen2point( $x, $y);
      my ( $ms) = $self->get_mouse_state;
      if ( ( scalar( @{ $w->{ branches}->[ $bn]}) == 1) || ( ( $ms & mb::Left) == mb::Left)) {
         push @{ $w->{ branches}->[ $bn]}, [ int($ax), int($ay)];
         $w->{ binfo}->{ removeLastPoint} = 0;
         $w-> {binfo}-> {firstDraw} = 1;
      }
      else {
         return unless $w-> {binfo}-> {firstDraw};
         @{ $w->{ branches}->[ $bn]->[ -1]} = ( $ax, $ay);
         $w->{ binfo}->{ removeLastPoint} = 1;
      }
      if ( scalar( @{ $w->{ branches}->[ $bn]}) > 1) {
         my ( $ex, $ey) = @{ $w->{ branches}->[ $bn]->[ -1]};
         my ( $bx, $by) = @{ $w->{ branches}->[ $bn]->[ -2]};
         my ( $left, $bottom, $right, $top) = ( $ox, $oy, $ox, $oy);
         $left = $ex if $left > $ex;
         $left = $bx if $left > $bx;
         $bottom = $ey if $bottom > $ey;
         $bottom = $by if $bottom > $by;
         $right = $ex if $right < $ex;
         $right = $bx if $right < $bx;
         $top = $ey if $top < $ey;
         $top = $by if $top < $by;
         $self-> invalidate_rect( $self-> point2screen( $left, $bottom, $right + 1, $top + 1));
      }
   }
   else{
      my ( $mindist, $bn, $i);
      my ( $rr);
      for ( $i = 0; $i <= $#{ $w->{ branches}}; $i++) {
         my ( $lmd, $j);
         my ( $left, $bottom, $right, $top) = ( @{ $w->{ branches}->[ $i]->[ 0]}, @{ $w->{ branches}->[ $i]->[ 0]});
         for ( $j = 0; $j < $#{ $w->{ branches}->[ $i]}; $j++) {
            my ( $x1, $y1, $x2, $y2) = ( @{ $w->{ branches}->[ $i]->[ $j]},
                                         @{ $w->{ branches}->[ $i]->[ $j + 1]});
            my ( $dist) = point_line_distance( $x1, $y1, $x2, $y2, $self-> screen2point($x, $y));
            $lmd = $dist unless defined $lmd;
            $lmd = $dist if $lmd > $dist;
            $left = $x1 if $left > $x1;
            $left = $x2 if $left > $x2;
            $bottom = $y1 if $bottom > $y1;
            $bottom = $y2 if $bottom > $y2;
            $right = $x1 if $right < $x1;
            $right = $x2 if $right < $x2;
            $top = $y1 if $top < $y1;
            $top = $y2 if $top < $y2;
         }
         if ( ( ! defined( $mindist)) || ( $mindist > $lmd)) {
            $mindist = $lmd;
            $bn = $i;
            $rr = [ $left, $bottom, $right + 1, $top + 1];
         }
      }

bin/PrLenS  view on Meta::CPAN

      next unless ( 1 << $_) & $w->{ini}->{visible_datasets};
      my $color = ( $_ < 2 ) ? ucfirst $layer : "Dataset$_";
      $canvas-> color( $w-> {ini}-> {"Color_$color"});
      foreach (@{$w-> {$layer}}) {
         my ($x, $y) = split;
         $canvas-> fill_ellipse( $x * $z, $y * $z, $zp, $zp);
      }
      if ( $w-> {ini}-> {ShowExtras}) {
         foreach (@{$w-> {"ex" . ucfirst $layer}}) {
            my ($x, $y) = split;
            $x *= $z; $y *= $z;
            $canvas-> line( $x - 3, $y - 3, $x + 3, $y + 3);
            $canvas-> line( $x - 3, $y + 3, $x + 3, $y - 3);
         }
      }
      if ( $w-> {ini}-> {ShowPrevExtras}) {
         foreach (@{$w-> {"prevex" . ucfirst $layer}}) {
            my ($x, $y) = split;
            $x *= $z; $y *= $z;
            $canvas-> line( $x - 3, $y - 3, $x + 3, $y + 3);
            $canvas-> line( $x - 3, $y + 3, $x + 3, $y - 3);
         }
      }
   }

   my $lw = $canvas->lineWidth;
   $canvas->lineWidth( 1);
   my ( $i) = 0;
   foreach ( @{ $w->{ branches}}) {
      if ( defined( $w->{ binfo}->{ nearestBranch}) && ( $i == $w->{ binfo}->{ nearestBranch})) {
         $canvas->color( $w->{ini}-> {Color_ActiveProcess});
      }
      else {
         $canvas->color( $w-> {ini}-> {Color_Branches});
      }
      my ( @br) = map { ( $_->[ 0] * $z, $_->[ 1] * $z)} @$_;
      $canvas->polyline( \@br);
      $i++;
   }
   $canvas->lineWidth( $lw);
}

# OPT

sub opt_colors
{
   my $i = $_[0]->{ini} ? $_[0]->{ini} : {$_[0]-> win_inidefaults};
   return {
      'Frame'         => [ cl::LightMagenta, 'Frame'],
      'Processes'     => [ cl::Blue,       'Process'],
      'Branches'      => [ cl::LightGreen, 'Branches'],
      'ActiveProcess' => [ 0x80FF80,       'Active process'],
      'Cells'         => [ cl::LightRed,   'Cells'],
      ( map { ( "Dataset$_", => [ cl::White / $_,   $i->{"dataset_${_}_name"}] ) } 2 .. MAXDATASET )
   };
}

sub opt_keys
{
   return {
      %{$_[0]-> SUPER::opt_keys()},
      EditAutoCrispening => [ kb::Space,           'Automatically crispen the image'],
      EditAutoStretching => [ km::Ctrl|kb::Space,  'Automatically stretch the image color spectrum'],
      EditProcess        => [ '^A',                'Markup processes automatically'],
      EditProcessSeries  => [ kb::NoKey,           'Markup series of processeses automatically'],
      EditRecSetup       => [ '@R',                'Display recognition setup dialog'],
      FileStats          => [ '@S',                'Invoke statistic data dialog'],
      FileBackup         => [ kb::NoKey,           'Backup current series data'],
      HelpAbout          => [ kb::NoKey,           'Standard about box'],
      HelpPlabApps       => [ kb::NoKey,           'Online PlabApps overview'],
      HelpContents       => [ kb::NoKey,           'Online PrLenS overview'],
   },
}

sub opt_propcreate
{
   my ( $w, $dlg, $nb, $nbpages) = @_;
   $w-> SUPER::opt_propcreate( $dlg, $nb, $nbpages);
   $nb-> tabs( @{$nb-> tabs}, 'Stretching');
   $nb-> insert_to_page( 1, [ SpinEdit =>
       origin => [ 10, 105],
       width  => 120,
       name   => 'nLines',
       min    => 2,
       max    => 20,
       hint   => 'Amount of lines in the grid',
   ] , [ Label =>
       origin => [ 10, 125],
       width  => 120,
       text   => 'Number of lines',
   ], [ CheckBox => 
       origin  => [ 10, 190],
       size    => [ 374, 36], 
       name    => 'ShowExtras',
       text    => '~Show first image markings',
       hint    => "If on, the markings on the first image in the series\nwill be displayed as crosses",
   ], [ CheckBox => 
       origin  => [ 10, 155],
       size    => [ 374, 36], 
       name    => 'ShowPrevExtras',
       text    => '~Show previous image markings',
       hint    => "If on, the markings on the previous image\nwill be displayed as crosses",
   ], [ Label => 
       origin  => [ 190, 130 ],
       autoWidth => 1,
       text      => 'Visible datasets',
   ], [ CheckList => 
       origin => [ 190, 55],
       size   => [ 120, 75],
       name   => 'Hyperset',
   ], [ SpinEdit => 
       origin => [ 190, 220],
       width  => 120,
       min    => 4,
       max    => 120,
       name   => 'PointSize',
       hint   => 'Size of point used for cell markings',
   ], [ Label => 
       origin => [ 190, 240],
       autoWidth => 1,
       text      => 'Point size',
   ], [ SpinEdit => 
       origin => [ 190, 160],
       width  => 120,
       min    => 2,
       max    => MAXDATASET,
       name   => 'Datasets',
       hint   => 'Number of visible types of data points sets. By default is 2, cells and processes', 
   ], [ Label => 
       origin => [ 190, 180],
       autoWidth => 1,
       text      => 'Number of datasets',
   ]);
   my $slider = $nb-> insert_to_page( 4, [ Widget => 
       origin  => [ 20, 70],
       size    => [ 262, 100],
       name    => 'StretchSlider',
       designScale => undef,

bin/PrLenS  view on Meta::CPAN

              $found = 'max';
              $self-> {maxLimit}  = 255;
              $self-> {minLimit}  = $self-> {min} + 1;
          } else {
             return;
          }
          $self-> {transaction} = $found;
          $self-> {last}   = $x;
          $self-> {anchor} = $x - $self-> {$found};
          $self-> capture(1);
       },
       onMouseMove => sub { 
          my ( $self, $mod, $x, $y) = @_; 
          return if !$self-> {transaction};
          $self-> clear_event;
          if ( $x - $self-> {anchor} < $self-> {minLimit}) {
             $x = $self-> {minLimit} + $self-> {anchor};
          } elsif ( $x - $self-> {anchor} > $self-> {maxLimit}) {
             $x = $self-> {maxLimit} + $self-> {anchor};
          }
          return if $self-> {last} == $x;
          $self-> {last} = $x;
          $self-> {$self-> {transaction}} = $x - $self-> {anchor};
          $self-> repaint;
       },
       onMouseUp => sub {
          my ( $self, $btn, $mod, $x, $y) = @_;
          $self-> clear_event;
          return unless $self-> {transaction};
          $self-> {transaction} = 0;
          $self-> capture(0);
       },
   ]);
   $nb-> insert_to_page( 4, [ Label => 
       origin  => [ 20, 170],
       designScale => undef,
       autoWidth => 1,
       text => 'Define spectrum range',
   ], [ Button => 
       origin  => [ 20, 20],
       designScale => undef,
       text => '~Preview',
       hint => 'Turn on auto-stretching before preview',
       name => 'StretchPreview',
       onClick => sub {
          unless ( $w-> {ini}->{autoStretch}) {
             return if Prima::MsgBox::message("Auto stretch feature is not turned on. Turn it on now?", mb::YesNo|mb::Information) != mb::Yes;
             $w-> stretching_state_changed;
          }
          $w-> {ini}-> {SpectrumMin} = $slider-> {min};
          $w-> {ini}-> {SpectrumMax} = $slider-> {max};
          $w-> preprocess;
          $w-> IV-> repaint;
       },
   ]);  
}

sub opt_proppush
{
   my ( $w, $dlg, $nb, $nbpages) = @_;
   $w-> SUPER::opt_proppush( $dlg, $nb, $nbpages);
   $nbpages-> nLines-> value( $w->{ini}->{nLines});
   $nbpages-> PointSize-> value( $w->{ini}->{PointSize});
   $nbpages-> Datasets-> value( $w->{ini}->{active_datasets});
   $nbpages-> ShowExtras-> checked( $w-> {ini}-> {ShowExtras});
   $nbpages-> ShowPrevExtras-> checked( $w-> {ini}-> {ShowPrevExtras});
   my $hs = $nbpages-> Hyperset;
   $hs-> items( [ map { ucfirst } @{$w->{layers}} ]);
   $hs-> vector( pack( 'I*', $w->{ini}-> {visible_datasets}));
   my $ssl = $nbpages-> StretchSlider;
   $ssl-> {saveMin} = $ssl-> {min} = $w->{ini}->{SpectrumMin};
   $ssl-> {saveMax} = $ssl-> {max} = $w->{ini}->{SpectrumMax};
   for ( qw( min max)) { 
      $ssl-> {$_}  = 0   if $ssl-> {$_} < 0;
      $ssl-> {$_}  = 255 if $ssl-> {$_} > 255;
   }
   my $pi = $nbpages-> pageIndex;
   $nbpages-> pageIndex( 4);
   $nbpages-> StretchPreview-> enabled( defined($w-> {file})); 
   $nbpages-> pageIndex( $pi);
}

sub opt_proppop
{
   my ( $w, $dlg, $nb, $nbpages, $mr) = @_;
   $w-> SUPER::opt_proppop( $dlg, $nb, $nbpages, $mr);
   my $ssl = $nbpages-> StretchSlider;
   if ( $mr) {
      $w->{ini}->{nLines} = $nbpages-> nLines-> value;
      $w->{ini}->{PointSize} = $nbpages-> PointSize-> value;
      my $ad = $w->{ini}->{active_datasets};
      $w->{ini}->{active_datasets} = $nbpages-> Datasets-> value;
      if ( $ad != $w->{ini}->{active_datasets}) {
         $w-> modified(1) if defined $w-> {file};
         $w-> reset_mark_state( 0) if defined $w-> {markState} && $w-> {markState} >= $w->{ini}->{active_datasets};
         $w-> {layers} = [ map { $w-> {ini}-> {"dataset_${_}_name"}} 0 .. $w->{ini}->{active_datasets} - 1];
         for ( @{$w-> {layers}}) {
            my $u = ucfirst $_;
            $w->{$_} ||= [];
            $w->{"ex$u"} ||= [];
            $w->{"prevex$u"} ||= [];
            $w->{"$_$u"} ||= 0 for qw(n total);
         }
      }
      $w-> {ini}-> {ShowExtras} = $nbpages-> ShowExtras-> checked;
      $w-> {ini}-> {ShowPrevExtras} = $nbpages-> ShowPrevExtras-> checked;
      my ( $a, $b) = ($ssl-> {min},$ssl-> {max});
      if ( ($w->{ini}->{SpectrumMin} != $a) ||
           ($w->{ini}->{SpectrumMax} != $b)) {
         $w->{ini}->{SpectrumMin} = $a;
         $w->{ini}->{SpectrumMax} = $b;
         $w-> preprocess;
      }
      $w-> {ini}-> {visible_datasets} = unpack('I*', $nbpages-> Hyperset-> vector);
      $w-> IV-> repaint;
   } else {
      if ( ($w->{ini}->{SpectrumMin} != $ssl-> {saveMin}) ||
           ($w->{ini}->{SpectrumMax} != $ssl-> {saveMax})) {
         $w->{ini}->{SpectrumMin} = $ssl-> {saveMin};
         $w->{ini}->{SpectrumMax} = $ssl-> {saveMax};
         $w-> preprocess;
         $w-> IV-> repaint;
      }
   }
}

# OPT_END

package Run;


my $wfil = App::PLab::ImageAppWindow::winmenu_file();
splice( @{$$wfil[1]}, -1, 0,
   [ '-FileStats'  => "~Statistics"   => q(show_stats)],
   [ '-FileBackup' => "~Backup results" => q(file_backup)],
   [],
   
);

my $wedt = App::PLab::ImageAppWindow::winmenu_edit();
splice( @{$$wedt[2]}, 0, 0,
   [ EditAutoCrispening => "~Auto crispening" => q(crispen_state_changed) ],
   [ EditAutoStretching => "Auto stretching"  => q(stretching_state_changed) ],
   [ EditRemoveAll => "Remove all frame data"  => q(remove_frame_data) ],
   [],
   [ EditRecSetup => "Recognition ~setup"  => q(win_showrec), ],   



( run in 0.979 second using v1.01-cache-2.11-cpan-5a3173703d6 )