view release on metacpan or search on metacpan
$gui->MainLoop;
This produces something like
https://github.com/saiftynet/GUIDeFATE/blob/master/calculator%20screenshot.png
Of course this is at a very early stage, and I have only implemented
buttons, static text and text control widgets. More will come.
Suggestions welcome.
EDIT> have implemented Menu and image subpanels at version 0.0.2
EDIT> have implemented Multiline text ctrl subpanels at version 0.0.3
EDIT> have implemented Message Boxes and file selector at Version 0.04
EDIT> have implemented an potential modification to allow other backends
EDIT> Have implemented a Tk backend
Copyright (C) 2018 Saif Ahmed
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.6 or,
lib/GFgtk.pm view on Meta::CPAN
our $winHeight;
our $winTitle="title";
our $winScale=6.5;
# these arrays will contain the widgets each as an arrayref of the parameters
my @widgets=();
my %iVars=(); #vars for interface operation (e.g.
my %oVars=(); #vars for interface creation (e.g. list of options)
my %styles;
my $lastMenuLabel; #bug workaround in menu generator may be needed for submenus
sub new
{
my $class = shift;
my $self={};
bless( $self, $class );
$self->{window}= Gtk3::Window->new;
$self->{window}->signal_connect(destroy => sub { Gtk3::main_quit; });
$self->{window}->resize($winWidth,$winHeight);
$self->{window} -> set_title($winTitle);
lib/GFgtk.pm view on Meta::CPAN
};
sub MainLoop{
Gtk3->main;
}
# setupContent sets up the initial content before Mainloop can be run.
sub setupContent{
my ($self, $canvas)=@_;
$self ->{"menubar"}=undef;
my $currentMenu;
foreach my $widget (@widgets){
my @params=@$widget;
my $wtype=shift @params;
if ($wtype eq "btn") {aBt($self, $canvas, @params);}
elsif ($wtype eq "textctrl") {aTC($self, $canvas, @params);}
elsif ($wtype eq "stattext") {aST($self, $canvas, @params);}
elsif ($wtype eq "sp") {aSP($self, $canvas, @params);}
elsif ($wtype eq "combo") {aCB($self, $canvas, @params);}
elsif ($wtype eq "sp") {aSP($self, $canvas, @params);}
elsif ($wtype eq "mb")
{
if (! $self->{"menubar"}){
$self ->{"menubar"} = Gtk3::MenuBar->new;
$canvas->put($self ->{"menubar"},0,0);
}
$currentMenu=aMB($self,$canvas,$currentMenu,@params)
}
}
sub aBt{
my ($self,$canvas, $id, $label, $location, $size, $action)=@_;
$canvas->{"btn$id"}=Gtk3::Button->new($label);
$canvas->{"btn$id"}->set_property("width-request", ${$size}[0]);
$canvas->{"btn$id"}->signal_connect( clicked => $action );
$canvas->put($canvas->{"btn$id"},${$location}[0] ,${$location}[1]);
}
lib/GFgtk.pm view on Meta::CPAN
$canvas->{"combo$id"}->set_active (0);
$canvas->{"combo$id"}->signal_connect(changed => sub{
$iVars{"combo$id"}=$canvas->{"combo$id"}->get_active_text;
&$action});
$canvas->put($canvas->{"combo$id"},${$location}[0] ,${$location}[1]);
}
else {print "Combo options not defined for 'combo$id' with label $label\n"}
}
sub aMB{
my ($self,$canvas,$currentMenu, $id, $label, $type, $action)=@_;
if (($lastMenuLabel) &&($label eq $lastMenuLabel)){return $currentMenu} # bug workaround
else {$lastMenuLabel=$label}; # in menu generator
if ($type eq "menuhead"){
$currentMenu="menu".$id;
$self ->{$currentMenu} = Gtk3::MenuItem->new_with_label($label);
$self ->{"sm$currentMenu"}=Gtk3::Menu->new();
$self ->{$currentMenu}->set_submenu( $self ->{"sm$currentMenu"} );
$self ->{"menubar"}->append($self ->{$currentMenu});
}
elsif ($type eq "radio"){
$self ->{"sm$currentMenu"}->append(Gtk3::RadioMenuItem->new($label));
}
elsif ($type eq "check"){
$self ->{"sm$currentMenu"}->append(Gtk3::CheckMenuItem->new($label));
}
elsif ($type eq "separator"){
$self ->{"sm$currentMenu"}->append(Gtk3::SeparatorMenuItem->new());
}
else{
if($currentMenu!~m/$label/){
$self ->{"mi$id"}=Gtk3::MenuItem->new($label);
$self ->{"sm$currentMenu"}->append($self ->{"mi$id"});
$self ->{"mi$id"}->signal_connect('activate' => $action);
}
}
# logging menu generator print "$currentMenu---$id----$label---$type\n";
return $currentMenu;
}
sub aSP{
my ($self,$canvas, $id, $panelType, $content, $location, $size)=@_;
if ($panelType eq "I"){ # Image panels start with I
if (! -e $content){ return; }
my $pixbuf = Gtk3::Gdk::Pixbuf->new_from_file($content);
my $scaled = $pixbuf->scale_simple(${$size}[0],${$size}[1], 'GDK_INTERP_HYPER');
$canvas->{"Image".$id} = Gtk3::Image->new();
$canvas->{"Image".$id}->set_from_pixbuf($scaled);
lib/GFqt.pm view on Meta::CPAN
our $winHeight;
our $winTitle;
our $winScale=6.5;
# these arrays will contain the widgets each as an arrayref of the parameters
my @widgets=();
my %iVars=(); #vars for interface operation (e.g.
my %oVars=(); #vars for interface creation (e.g. list of options)
my %styles;
# my @menus;
my $lastMenuLabel; #bug workaround in menu generator may be needed for submenus
sub new
{
my $class = shift;
$app = Qt::Application(\@ARGV);
my $self = $class->SUPER::new(); # call the superclass' constructor
$self->{canvas}=Qt::Widget;
$frame= $self->{canvas};
$self->setWindowTitle ( $winTitle );
$self->{canvas}->setGeometry(0, 0, $winWidth, $winHeight);
lib/GFqt.pm view on Meta::CPAN
if ($widgetIndex !=-1){
if ($wType eq "mb") { &{$widget[3]};}
elsif ($wType eq "btn") { &{$widget[4]};}
elsif ($wType eq "combo") { &{$widget[4]};}
}
}
# setupContent sets up the initial content before Mainloop can be run.
sub setupContent{
my ($self, $canvas)=@_;
my $currentMenu;
foreach my $widget (@widgets){
my @params=@$widget; my $menuStarted=0;
my $wtype=shift @params;
if ($wtype eq "btn") {aBt($self, $canvas, @params);}
elsif ($wtype eq "textctrl") {aTC($self, $canvas, @params);}
elsif ($wtype eq "stattext") {aST($self, $canvas, @params);}
elsif ($wtype eq "sp") {aSP($self, $canvas, @params);}
elsif ($wtype eq "combo") {aCB($self, $canvas, @params);}
elsif ($wtype eq "sp") {aSP($self, $canvas, @params);}
elsif ($wtype eq "mb") {$currentMenu=aMB($self,$canvas,$currentMenu,@params) }
}
sub aBt{
my ($self,$canvas, $id, $label, $location, $size, $action)=@_;
$canvas->{"btn$id"}=Qt::PushButton($label);
$canvas->{"btn$id"}->setParent($canvas);
$canvas->{"btn$id"}->setGeometry(${$location}[0],${$location}[1],${$size}[0],${$size}[1]);
$self->connect($canvas->{"btn".$id}, SIGNAL 'clicked()', $self->{SigMan}, SLOT 'map()');
$self->{SigMan}->setMapping($canvas->{"btn".$id}, "btn".$id);
}
lib/GFqt.pm view on Meta::CPAN
$canvas->{"combo$id"}->setGeometry(${$location}[0],${$location}[1], 80,32);
$self->connect($canvas->{"combo".$id}, SIGNAL 'currentIndexChanged(int)', $self->{SigMan}, SLOT 'map()');
$self->{SigMan}->setMapping($canvas->{"combo".$id}, "combo".$id);
}
else {print "Combo options not defined for 'combo$id' with label $label\n"}
}
sub aMB{
my ($self,$canvas,$currentMenu, $id, $label, $type, $action)=@_;
if (($lastMenuLabel) &&($label eq $lastMenuLabel)){return $currentMenu} # bug workaround
else {$lastMenuLabel=$label}; # in menu generator
if ($type eq "menuhead"){
$currentMenu="menu".$id;
$self->{$currentMenu} = Qt::Menu($self->tr($label),$self);
$self->menuBar()->addMenu($self->{$currentMenu})
# push (@menus, $currentMenu)
}
elsif ($type eq "radio"){
}
elsif ($type eq "check"){
}
elsif ($type eq "separator"){
$canvas->{$currentMenu}->addSeparator();
}
else{
$self->{"menu".$id."Act"}=Qt::Action($self->tr($label), $self);
$self->connect($self->{"menu".$id."Act"}, SIGNAL 'triggered()', $self->{SigMan}, SLOT 'map()');
$self->{SigMan}->setMapping($self->{"menu".$id."Act"}, "menu".$id);
$self->{$currentMenu}->addAction($self->{"menu".$id."Act"});
}
# logging menu generator print "$currentMenu---$id----$label---$type\n";
return $currentMenu;
}
sub aSP{
my ($self,$canvas, $id, $panelType, $content, $location, $size)=@_;
if ($panelType eq "I"){ # Image panels start with I
if (! -e $content){ return; }
$canvas->{"Image$id"}=Qt::Label();
my $image = Qt::Image(Qt::String($content));
$canvas->{"Image$id"}->setPixmap(Qt::Pixmap::fromImage( $image )->scaled(${$size}[0],${$size}[1]) );
$canvas->{"Image$id"}->setParent($canvas);
lib/GFtemplate.pm view on Meta::CPAN
use strict;
use warnings;
our $VERSION = '0.081';
use parent qw(Backend::MainWindow); ##
use Image::Magick; ##other modules that need to be loaded
use Exporter 'import'; ##somefunctions are always passed back to GUIDeFATE.pm
our @EXPORT_OK = qw<addButton addStatText addTextCtrl addMenuBits addPanel setScale $frame $winScale $winWidth $winHeight $winTitle>;
our $frame; # The frame which is the parent of all the widgets
# ever widget is referenced by an id and is accessible by $frame -> {id}
our $winX=30; # These are the window dimensions and are modified by GUIDeFATE
our $winY=30;
our $winWidth;
our $winHeight;
our $winTitle;
our $winScale=6.5; # This allows the window to be scaled
lib/GFtemplate.pm view on Meta::CPAN
foreach my $button (@buttons){
aBt($self, $frame, @$button)
}
foreach my $textctrl (@textctrls){
aTC($self,$frame,@$textctrl)
}
foreach my $stattxt (@stattexts){
aST($self,$frame,@$stattxt)
}
if (scalar @menu){ #menu exists
$self->configure(-menu => my $self ->{"menubar"} = $self->Menu);
my $currentMenu;
foreach my $menuBits (@menu){
$currentMenu=aMB($self,$frame,$currentMenu,@$menuBits)
}
}
foreach my $sp (@subpanels){
aSP($self,$frame,@$sp);
}
# these functions convert the parameters of the widget into actual widgets
sub aBt{ # creates buttons
my ($self,$frame, $id, $label, $location, $size, $action)=@_;
lib/GFtemplate.pm view on Meta::CPAN
my ($self,$frame, $id, $text, $location, $size, $action)=@_;
# id are "textctrl".$id, if action specified, return triggers $action (not all backend support this)
# referenced by $frame->{"textctrl".$id}
}
sub aST{ #static texts
my ($self,$frame, $id, $text, $location)=@_;
# id are "stattext".$id,
# referenced by $frame->{"stattext".$id}
}
sub aMB{ #parses the menu items into a menu. menus may need to be a child of main window
my ($self,$canvas,$currentMenu, $id, $label, $type, $action)=@_;
if (($lastMenuLabel) &&($label eq $lastMenuLabel)){return $currentMenu} # bug workaround
else {$lastMenuLabel=$label}; # in menu generator
if ($type eq "menuhead"){ #the label of the menu
}
elsif ($type eq "radio"){ #menu items which are radio buttons in tk there is no function called
}
elsif ($type eq "check"){ #menu items which are check boxes in tk there is no function called
}
elsif ($type eq "separator"){ #separators
}
else{
if($currentMenu!~m/$label/){ #simple menu items
$self ->{$currentMenu}->command(-label => $label, -command =>$action);
}
}
return $currentMenu;
}
sub aSP{
my ($self,$canvas, $id, $panelType, $content, $location, $size)=@_; ##image Id must endup $id+1
if ($panelType eq "I"){ # Image panels start with I
$content=~s/^\s+|\s+$//g;
if (! -e $content){ return; }
no warnings; # sorry about that...suppresses a "Useless string used in void context"
my $image = Image::Magick->new;
my $r = $image->Read("$content");
lib/GFtemplate.pm view on Meta::CPAN
#functions for GUIDeFATE to load the widgets into the backend...leave alone
sub addButton{
push (@buttons,shift );
}
sub addTextCtrl{
push (@textctrls,shift );
}
sub addStatText{
push (@stattexts,shift );
}
sub addMenuBits{
push (@menu, shift);
}
sub addPanel{
push (@subpanels, shift);
}
sub addStyle{
my ($name,$style)=@_;
$styles{$name}=$style;
}
lib/GFtk.pm view on Meta::CPAN
our $winHeight;
our $winTitle;
our $winScale=6.5;
# these arrays will contain the widgets each as an arrayref of the parameters
my @widgets=();
my %iVars=(); #vars for interface operation (e.g.
my %oVars=(); #vars for interface creation (e.g. list of options)
my %styles;
my $lastMenuLabel; #bug workaround in menu generator may be needed for submenus
sub new
{
my $class = shift;
my $self = $class->SUPER::new(@_); # call the superclass' constructor
$self -> title($winTitle);
$self -> geometry($winWidth."x".$winHeight);
$frame = $self->Canvas(
-bg => 'lavender',
-relief => 'sunken',
lib/GFtk.pm view on Meta::CPAN
-weight=>'normal',
-size=>int(-18*18/14));
setupContent($self,$frame); #then add content
return $self;
};
# setupContent sets up the initial content before Mainloop can be run.
sub setupContent{
my ($self, $canvas)=@_;
$self ->{"menubar"}=undef;
my $currentMenu;
foreach my $widget (@widgets){
my @params=@$widget;
my $wtype=shift @params;
if ($wtype eq "btn") {aBt($self, $canvas, @params);}
elsif ($wtype eq "textctrl") {aTC($self, $canvas, @params);}
elsif ($wtype eq "stattext") {aST($self, $canvas, @params);}
elsif ($wtype eq "sp") {aSP($self, $canvas, @params);}
elsif ($wtype eq "combo") {aCB($self, $canvas, @params);}
elsif ($wtype eq "sp") {aSP($self, $canvas, @params);}
elsif ($wtype eq "mb")
{
if (! $self->{"menubar"}){
$self->configure(-menu => $self ->{"menubar"} = $self->Menu);
}
$currentMenu=aMB($self,$canvas,$currentMenu,@params)
}
}
sub aBt{
my ($self,$canvas, $id, $label, $location, $size, $action)=@_;
$canvas->{"btn$id"}=$canvas->Button(-text => $label,
-width => ${$size}[0]/6.68-4,
-height => ${$size}[1]/16,
-pady => 1,
-command => $action);
lib/GFtk.pm view on Meta::CPAN
-width => (${$size}[0]-20)*1.5,
-height => ${$size}[1],
-anchor => "nw",
-window =>$canvas->{"combo$id"});
}
else {print "Combo options not defined for 'combo$id' with label $label\n"}
}
sub aMB{
my ($self,$canvas,$currentMenu, $id, $label, $type, $action)=@_;
if (($lastMenuLabel) &&($label eq $lastMenuLabel)){return $currentMenu} # bug workaround
else {$lastMenuLabel=$label}; # in menu generator
if ($type eq "menuhead"){
$currentMenu="menu".$id;
$self ->{$currentMenu} = $self ->{"menubar"}->cascade(-label => "~$label")
}
elsif ($type eq "radio"){
$self ->{$currentMenu}->radiobutton(-label => $label);
}
elsif ($type eq "check"){
$self ->{$currentMenu}->checkbutton(-label => $label);
}
elsif ($type eq "separator"){
$self ->{$currentMenu}->separator;
}
else{
if($currentMenu!~m/$label/){
$self ->{$currentMenu}->command(-label => $label, -command =>$action);
}
}
# logging menu generator print "$currentMenu---$id----$label---$type\n";
return $currentMenu;
}
sub aSP{
my ($self,$canvas, $id, $panelType, $content, $location, $size)=@_;
if ($panelType eq "I"){ # Image panels start with I
if (! -e $content){ return; }
no warnings; # sorry about that...suppresses a "Useless string used in void context"
my $image = Image::Magick->new;
my $r = $image->Read("$content");
if ($image){
lib/GFwxFrame.pm view on Meta::CPAN
use Wx::Perl::Imagick; #for image panels
use base qw(Wx::Frame); # Inherit from Wx::Frame
# these arrays will contain the widgets each as an arrayref of the parameters
my @widgets=();
my %iVars=(); #vars for interface operation (e.g.
my %oVars=(); #vars for interface
my %styles;
my $lastMenuLabel; #bug workaround in menu generator
my $winScale=6.5;
my $font = Wx::Font->new( 3*$winScale,
wxDEFAULT,
wxNORMAL,
wxNORMAL,
0,
"",
wxFONTENCODING_DEFAULT);
lib/GFwxFrame.pm view on Meta::CPAN
my $panel = Wx::Panel->new( $self,-1); # parent, id
setupContent($self,$panel); #then add content
return $self;
}
# setupContent sets up the initial content before Mainloop can be run.
sub setupContent{
my ($self,$canvas)=@_;
$self ->{"menubar"}=undef;
my $currentMenu;
foreach my $widget (@widgets){
my @params=@$widget;
my $wtype=shift @params;
if ($wtype eq "btn") {aBt($self, $canvas, @params);}
elsif ($wtype eq "textctrl") {aTC($self, $canvas, @params);}
elsif ($wtype eq "stattext") {aST($self, $canvas, @params);}
elsif ($wtype eq "sp") {aSP($self, $canvas, @params);}
elsif ($wtype eq "combo") {aCB($self, $canvas, @params);}
elsif ($wtype eq "sp") {aSP($self, $canvas, @params);}
elsif ($wtype eq "mb")
{
if (! $self->{"menubar"}){
$self ->{"menubar"} = Wx::MenuBar->new();
$self->SetMenuBar($self ->{"menubar"});
}
$currentMenu=aMB($self,$canvas,$currentMenu,@params)
}
}
sub aCB{
my ($self,$panel, $id, $label, $location, $size, $action)=@_;
if (defined $oVars{$label}){
my @strings2 = split(",",$oVars{$label});
$self->{"combo".$id}= Wx::ComboBox->new($panel, $id, $strings2[0],$location, Wx::Size->new($$size[0], $$size[1]),\@strings2,wxCB_DROPDOWN);
EVT_COMBOBOX( $self, $id, $action);
}
else {print "Combo options not defined for 'combo$id' with label $label\n"}
}
sub aMB{
my ($self,$panel,$currentMenu, $id, $label, $type, $action)=@_;
if (($lastMenuLabel) &&($label eq $lastMenuLabel)){return $currentMenu} # bug workaround
else {$lastMenuLabel=$label}; # in menu generator
if ($type eq "menuhead"){
$currentMenu="menu".$id;
$self ->{$currentMenu} = Wx::Menu->new();
$self ->{"menubar"}->Append($self ->{$currentMenu}, $label);
}
elsif ($type eq "radio"){
$self ->{$currentMenu}->AppendRadioItem($id, $label);
EVT_MENU( $self, $id, $action )
}
elsif ($type eq "check"){
$self ->{$currentMenu}->AppendCheckItem($id, $label);
EVT_MENU( $self, $id, $action )
}
elsif ($type eq "separator"){
$self ->{$currentMenu}->AppendSeparator();
}
else{
if($currentMenu!~m/$label/){
$self ->{$currentMenu}->Append($id, $label);
EVT_MENU( $self, $id, $action )
}
}
# logging menu generator print "$currentMenu---$id----$label---$type\n";
return $currentMenu;
}
sub aBt{
my ($self,$panel, $id, $label, $location, $size, $action)=@_;
$self->{"btn".$id} = Wx::Button->new( $panel, # parent
$id, # ButtonID
$label, # label
$location, # position
$size # size
);
lib/GUIDeFATE.pm view on Meta::CPAN
}
if(!$winHeight) {$winHeight=$winScale*4*($l-1)};
my $mode="";
while ($l++<=scalar(@lines)){
my $line=$lines[$l];
if ((!$line) || ($line eq "")||($line=~/^#/)){
$mode="";next;
}
elsif ($line=~/menu/i){
$log="Menu found\n"; ##
if ($verbose){ print $log; }
if ($auto){ $autoGen.="#".$log; }
$mode="menu";
next;}
elsif($line=~/^([A-z]+=)/){
chomp $line;
my ($varName,$value)=split(/=/,$line,2);
$log="var ' $varName ' has value ' $value '\n"; ##
addVar($varName,$value);
}
if($mode eq "menu"){
if ($line=~/^\-([A-z0-9].*)/i){
$log= "Menuhead $1 found\n"; ##
if ($verbose){ print $log; }
if ($auto){ $autoGen.="#".$log; }
addWidget(["mb",$bid++, $1, "menuhead", undef]);
}
elsif($line=~/^\-{2}([A-z0-9].*)\;radio/i){
$log= "Menu $1 as radio found, calls function &menu$bid \n";##
if ($verbose){ print $log; }
if ($auto){ $autoGen.="#".$log.makeSub("menu$bid","Menu with label $1"); }
addWidget(["mb",$bid, $1, "radio", \&{"main::menu".$bid++}]);
}
elsif($line=~/^\-{2}([A-z0-9].*)\;check/i){
$log= "Menu $1 as check found, calls function &menu$bid \n";##
if ($verbose){ print $log; }
if ($auto){ $autoGen.="#".$log.makeSub("menu$bid","Menu with label $1"); }
addWidget(["mb",$bid, $1, "check", \&{"main::menu".$bid++}]);
}
elsif($lines[$l]=~/^\-{6}/){
$log= "Separator found,\n"; ##
if ($verbose){ print $log; }
if ($auto){ $autoGen.="#".$log.makeSub("menu$bid","Menu with label $1"); }
addWidget(["mb",$bid++, "", "separator",""]);
}
elsif($line=~/^\-{2}([A-z0-9].*)/i){
$log= "Menu $1 found, calls function &menu$bid \n";##
if ($verbose){ print $log; }
if ($auto){ $autoGen.="#".$log.makeSub("menu$bid","Menu with label $1"); }
}
addWidget(["mb",$bid, $1, "normal", \&{"main::menu".$bid++}]);
}
elsif($line=~/^\-{3}([A-z0-9].*)/i){
$log= "SubMenu $1 found\n";##
}
}
if ($auto){
open(my $fh, '>', 'autogen.txt');
print $fh $autoGen;
close $fh;
}
sub makeSub{