#!/usr/bin/perl use strict; use warnings; use Wx; use Smart::Comments '###'; package WxPMEdit; use base 'Wx::App'; use Wx qw( wxDEFAULT_FRAME_STYLE ); sub OnInit { my $self = shift; my($frame) = WxPMFrame->new( undef, # parent -1, # ID (-1 = don't care) "wxPMTest", # title [-1,-1], # position (don't care) [500,300], # size wxDEFAULT_FRAME_STYLE, # window name? not really sure what this is ); $frame->Show(1); return 1; # success } package WxPMText; use base 'Wx::TextCtrl'; use Wx qw( wxTE_MULTILINE ); sub new { my $class = shift; ### assert: @_ >= 3 $_[3] ||= [-1,-1]; $_[4] ||= [-1,-1]; $_[5] |= wxTE_MULTILINE; my $self = $class->SUPER::new(@_); # this doesn't work... so have to hack the parameters (see above) # $self->SetStyle(Wx::TextCtrl::wxTE_MULTILINE); $self; } package WxPMFrame; use base 'Wx::Frame'; use Wx::Event; use Wx qw( wxID_EXIT wxID_CUT wxID_COPY wxID_PASTE wxID_UNDO wxID_REDO ); my @menu = ( [ '&File', [ -1, "&Open\tCtrl-O", 'Open' ], '-', [ wxID_EXIT, "E&xit\tCtrl-Q", 'Exit' ], ], [ '&Edit', [ wxID_UNDO, "&Undo\tAlt", 'Undo' ], #{ menuitem => [ wxID_UNDO, "&Undo\tAlt", 'Undo' ], object => '_text', method => 'Undo' }, [ wxID_REDO, "&Redo\tCtrl-Alt", 'Redo' ], '-', #[ wxID_CUT, "Cu&t\tCtrl-X", 'Cut' ], #[ wxID_COPY, "&Copy\tCtrl-C", 'Copy' ], { menuitem => [ wxID_PASTE, "&Paste\tCtrl-V", 'Paste' ], object => '_text' }, #[ wxID_PASTE, "&Paste\tCtrl-V", 'Paste' ], [ -1, "Select &All\tCtrl-A", 'Select All' ] ], ); sub _SetupMenu { my $self = shift; my $menubar = Wx::MenuBar->new(); for my $top_menu (@menu) { my $menu = Wx::Menu->new(); $menubar->Append($menu, shift @$top_menu); for (@$top_menu) { if (ref $_) { # we may have an array ref, or a hash ref (with the array ref # inside) my $data = ref $_ eq 'ARRAY' ? { menuitem => $_ } : $_; my $item = $data->{menuitem}; my $id = #$self->{_menu}{$item->[2]} = $menu->Append(@$item)->GetId(); # look for the handler - with fallback my $func = $data->{method} || $item->[2]; # who will handle? my $object = $data->{object} || $self; $object = $self->{$object} if not ref $object; # how do we do this? my $code = $func; if (ref $code or $code = $object->can($func) or $code = $object->can(do { ($func = 'OnMenu' . $func) =~ s/\s+//g; $func }) ) { $Data::Dumper::Deparse = 1; ### setup menu: $object ### id: $id ### code: $code ### func: $func Wx::Event::EVT_MENU($object, $id, $code); } else { warn "$item->[2] not implemented\n"; } } elsif ($_ eq '-') { $menu->AppendSeparator(); } else { die "bad data in \@menu"; } } } $self->SetMenuBar($menubar); } sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self->{_text} = WxPMText->new($self, -1, ''); $self->{_text}->SetFocus; $self->_SetupMenu; $self } sub OnMenuOpen { my $self = shift; print "OnMenuOpen stub"; } sub OnMenuUndo { my $self = shift; $self->{_text}->Undo(); } sub OnMenuRedo { my $self = shift; $self->{_text}->Redo(); } sub OnMenuPaste { my $self = shift; ### pasting $self->{_text}->Paste(); ### paste code: $self->{_text}->can('Paste') } sub OnMenuExit { my $self = shift; $self->Close(1); } sub OnMenuSelectAll { my $self = shift; $self->{_text}->SetSelection(-1,-1); } package main; my $app = WxPMEdit->new(); $app->MainLoop(); 0;