<?xml version="1.0" encoding="windows-1252"?>
<node id="290475" title="WxPerl Login Dialog" created="2003-09-10 13:24:27" updated="2005-08-15 01:06:36">
<type id="1980">
snippet</type>
<author id="31503">
runrig</author>
<data>
<field name="doctext">
</field>
<field name="snippetdesc">
&lt;p&gt;I needed a simple login dialog from my main program, and decided to try WxPerl. Its mostly derived from [Jouke]'s [http://www.perl.com/pub/a/2001/09/12/wxtutorial1.html|Tutorial] examples, but I needed to figure out how to add a couple of other things to it. I [require] this module only if needed, since I know in advance some user/passwords, and the module portion of the code is installed somewhere in @INC as LoginDialog.pm.&lt;/p&gt;
&lt;p&gt;TBD: I gather from mailing archives that since I'm setting the focus on a text control before the window is opened, that it might be better to set it in an EVT_UPDATE_UI handler (though it works as-is for me), but I'm not quite sure how to go about that...help is appreciated :-)&lt;/p&gt;
&lt;p&gt;Updated w/[PodMaster]'s comments as I understand them. The change in SetFocus and use of EVT_UPDATE_UI became necesssary after the change from a Frame to a Dialog. Also, it's interesting that I don't even have to call Wx's MainLoop now...
&lt;p&gt;Update: Agghhh, EVT_UPDATE_UI broke it. I just don't understand how to use that event handler yet...&lt;/p&gt;
&lt;p&gt;Update: I think it works now...they only other thing I'd like to do is replace that $done flag in the code with something so that the handler uninstalls itself...watch this space...&lt;/p&gt;
&lt;p&gt;Changed EVT_UPDATE_UI to EVT_ACTIVATE. The former handler was being called over one hundred times, while the latter is only called ~3 times. Still it'd be nice if it were possible to have a handler uninstall itself...not sure if that's possible.&lt;/p&gt;
&lt;p&gt;Final update(!): Found out how to disconnect event handler, but had to change back to EVT_UPDATE_UI, as the
focus wouldn't get set in EVT_ACTIVATE if I disconnected it while executing the handler.&lt;/p&gt;</field>
<field name="snippetcode">
&lt;CODE&gt;
#!/usr/bin/perl
#
# For simple login dialog
# See example at bottom of file
# 

use strict;
use Wx;

###########################################################
#
# Extend the Frame class to our needs
#
package Wx::Perl::LoginDialog;

use Wx qw( wxTE_PASSWORD wxTE_PROCESS_ENTER );
use Wx::Event qw( EVT_BUTTON EVT_TEXT_ENTER EVT_UPDATE_UI );

use base qw/Wx::Dialog/;

sub new {
  my $class = shift;
  my $user = shift;
  my $passwd = shift;
 
  my $self = $class-&gt;SUPER::new(@_);
  $self-&gt;{user_out} = $user;
  $self-&gt;{passwd_out} = $passwd;

  $self-&gt;{UserLabel} = Wx::StaticText-&gt;new(
   $self,    # parent
   -1,        # id
   "User:",   # label
   [10, 30]   # position
  );
  $self-&gt;{PasswdLabel} = Wx::StaticText-&gt;new(
    $self,     # parent
    -1,         # id
    "Password:",# label
    [10, 50]    # position
  );
 
  $self-&gt;{User} = Wx::TextCtrl-&gt;new(
    $self,
    -1,
    ${$self-&gt;{user_out}} || "",
    [70,30],
    [70,20],
    wxTE_PROCESS_ENTER,
  );

  $self-&gt;{Passwd} = Wx::TextCtrl-&gt;new(
    $self,
    2,
    ${$self-&gt;{passwd_out}} || "",
    [70,50],
    [70,20],
    wxTE_PASSWORD | wxTE_PROCESS_ENTER,
  );

  $self-&gt;{Login} = Wx::Button-&gt;new(
    $self,
    1,
    "Login",
    [20,90],
  );

  $self-&gt;{Cancel} = Wx::Button-&gt;new(
    $self,
    2,
    "Cancel",
    [90,90],
  );

  EVT_UPDATE_UI(
    $self,
    -1,
    sub {
      $self-&gt;{Passwd}-&gt;SetFocus if $$user;
      EVT_UPDATE_UI($self, -1, undef);
    }
  );
 
  EVT_BUTTON(
    $self,     # Object to bind to
    1,         # ButtonID
    \&amp;Login
  );

  EVT_BUTTON(
    $self,     # Object to bind to
    2,         # ButtonID
    \&amp;CancelLogin # Subroutine to execute
  );

  EVT_TEXT_ENTER(
    $self,
    -1,
    \&amp;Login
  );

  $self-&gt;{Passwd}-&gt;SetFocus if $$user;
  return $self;
}

sub Login { 
  my $self = shift;
  ${$self-&gt;{user_out}} = $self-&gt;{User}-&gt;GetValue;
  ${$self-&gt;{passwd_out}} = $self-&gt;{Passwd}-&gt;GetValue;
  $self-&gt;EndModal(1);
}

sub CancelLogin { 
  my $self = shift;
  $self-&gt;EndModal(0);
}

###########################################################
#
package Wx::Perl::LoginWindow;

use base qw(Wx::App);   # Inherit from Wx::App
use Wx qw(wxCAPTION wxSYSTEM_MENU);
our ($user, $passwd, $ok);

sub BindVars {
  my $self = shift;
  ($user, $passwd, $ok) = @_;
  $self;
}

sub OnInit {
  my $self = shift;
  $$ok = Wx::Perl::LoginDialog-&gt;new(
    $user,
    $passwd,
    undef,         # Parent window
    -1,            # Window id
    'Login',       # Title
    [200,200],     # position X, Y
    [200,150],     # size X, Y
    wxCAPTION | wxSYSTEM_MENU
  )-&gt;ShowModal;
  0;
}

package LoginDialog;

sub get_login {
  shift;
  my $ok;
  my $app = eval { Wx::Perl::LoginWindow-&gt;BindVars(@_, \$ok)-&gt;new };
  die $@ unless $@ =~ "OnInit must return a true return value";
  $ok;
}

1;
###########################################################
#
# The main program
#
package main;
unless( caller ){

    if( @ARGV ) {
        LoginDialog-&gt;get_login(\my ($user, $passwd));
        die "USER $user\n\nPASS $passwd\n\n";
    } else { # Use defaults if available:

        my ($user, $passwd) = @ARGV;
        # Default either one if desired
        $user = 'username';

        unless ($user and $passwd) {
            # require LoginDialog;
            LoginDialog-&gt;get_login(\($user, $passwd));
        }
    }
}

&lt;/CODE&gt;</field>
</data>
</node>
