Wednesday, February 17, 2010

Dialogs, fields, and magic variables

So I've obviously been spending too much time with this, but I added magic variables to Class::Declarative today, and used them for text controls in Wx.

A magic variable is one for which a handler is registered with the context. When we read or write that variable in the context, our handler is called. That means that code can get or write field contents just by referring to the field as the variable it's tied to - and you tie a field to a variable just by naming it.

So the wxPerl dialogs.pl sample is this code:

#!/usr/bin/perl
#############################################################################
## Name: samples/dialog/dialog.pl
## Purpose: Dialog wxPerl sample
## Author: Mattia Barbon
## Modified by:
## Created: 12/11/2000
## RCS-ID: $Id: dialog.pl,v 1.4 2004/10/19 20:28:13 mbarbon Exp $
## Copyright: (c) 2000 Mattia Barbon
## Licence: This program is free software; you can redistribute it and/or
## modify it under the same terms as Perl itself
#############################################################################

use Wx;

package MyApp;

use strict;
use vars qw(@ISA);

@ISA=qw(Wx::App);

use Wx qw(wxDefaultSize wxDefaultPosition);

sub OnInit {
my( $this ) = @_;

my( $dialog ) = MyDialog->new( "wxPerl dialog sample",
wxDefaultPosition,
);

$this->SetTopWindow( $dialog );

$dialog->Show( 1 );

1;
}

package MyDialog;

use strict;
use vars qw(@ISA);

@ISA=qw(Wx::Dialog);

use Wx::Event qw(EVT_CLOSE EVT_BUTTON);
use Wx qw(wxDefaultSize wxDefaultValidator);

sub new {
my( $class ) = shift;
my( $this ) = $class->SUPER::new( undef, -1, $_[0], $_[1], [250, 110] );

# $this->SetIcon( Wx::GetWxPerlIcon() );

my( $ct ) = $this->{CELSIUS} =
Wx::TextCtrl->new( $this, -1, '0', [20, 20], [100, -1] );
my( $cb ) = Wx::Button->new( $this, -1, 'Celsius', [130, 20] );
my( $ft ) = $this->{FAHRENHEIT} =
Wx::TextCtrl->new( $this, -1, '32', [20, 50], [100, -1] );
my( $fb ) = Wx::Button->new( $this, -1, 'Fahrenheit', [130, 50] );

EVT_BUTTON( $this, $cb, \&CelsiusToFahrenheit );
EVT_BUTTON( $this, $fb, \&FahrenheitToCelsius );

EVT_CLOSE( $this, \&OnClose );

$this;
}

sub CelsiusToFahrenheit {
my( $this, $event ) = @_;

$this->{FAHRENHEIT}->SetValue( ( $this->{CELSIUS}->GetValue() /
100.0 ) * 180 + 32 );
}

sub FahrenheitToCelsius {
my( $this, $event ) = @_;

$this->{CELSIUS}->SetValue( ( ( $this->{FAHRENHEIT}->GetValue()-32 ) /
180.0 ) * 100 );
}

sub OnClose {
my( $this, $event ) = @_;

$this->Destroy();
}

package main;

my( $app ) = MyApp->new();

$app->MainLoop();

# Local variables: #
# mode: cperl #
# End: #


In the Wx::Declarative framework, that becomes this:

use Class::Declarative qw(Wx::Declarative);

dialog (xsize=250, ysize=110) "Wx::Declarative dialog sample"
field celsius (size=100, x=20, y=20) "0"
button celsius (x=130, y=20) "Celsius" { $^fahrenheit = ($^celsius / 100.0) * 180 + 32; }
field fahrenheit (size=100, x=20, y=50) "32"
button fahrenheit (x=130, y=50) "Fahrenheit" { $^celsius = (($^fahrenheit - 32) / 180.0) * 100; }


And it works, as of right now.

No comments:

Post a Comment