1 # Copyright (c) 2003-2009 Mikhael Goikhman
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 package FVWM
::Module
::Tk
;
22 use FVWM
::Module
::Toolkit
qw(base Tk Tk::Dialog Tk::ROText);
26 # support the old API with the first top-level argument
27 my $top = shift if @_ && UNIVERSAL
::isa
($_[0], "Tk::Toplevel");
30 $top = delete $params{TopWindow
} if exists $params{TopWindow
};
31 my $self = $class->SUPER::new
(%params);
33 $self->internal_die("TopWindow given in constructor is not Tk::Toplevel")
34 unless $top || UNIVERSAL
::isa
($top, "Tk::Toplevel");
36 $top = MainWindow
->new;
40 $self->{top_window
} = $top;
49 $self->event_loop_prepared(@params);
50 my $top = $self->{top_window
};
51 $top->fileevent($self->{istream
},
53 unless ($self->process_packet($self->read_packet)) {
54 if ($self->{disconnected
}) {
55 # Seems like something does not want to exit - force it.
56 # For example, a new Tk window is launched on ON_EXIT.
57 $top->destroy if defined $top && defined $top->{Configure
};
58 $self->debug("Forced to exit to escape event_loop, fix the module", 0);
61 $self->event_loop_finished(@params);
64 $self->event_loop_prepared(@params);
71 sub show_error
($$;$) {
74 my $title = shift || ($self->name . " Error");
76 my $top = $self->{top_window
};
78 my $dialog = $top->Dialog(
81 -default_button
=> 'Close',
83 -buttons
=> ['Close', 'Close All Errors', 'Exit Module'],
85 my $btn = $dialog->Show;
87 $self->terminate if $btn eq 'Exit Module';
88 $self->send("All ('$title') Close") if $btn eq 'Close All Errors';
91 sub show_message
($$;$) {
94 my $title = shift || ($self->name . " Message");
96 $self->{top_window
}->messageBox(
104 sub show_debug
($$;$) {
107 my $title = shift || ($self->name . " Debug");
109 my $dialog = $self->{tk_debug_dialog
};
111 my $top = $self->{top_window
};
112 unless (defined $top && defined $top->{Configure
}) {
113 # in the constructor (too early) or in destructor (too late)
114 $self->FVWM::Module
::Toolkit
::show_debug
($msg, $title);
119 # Tk's Dialog widgets are too damn inflexible.
120 # It's less hassle to build one from scratch.
121 $dialog = $top->Toplevel(-title
=> $title);
122 my $scroll = $dialog->Frame()->pack(-expand
=> 1, -fill
=> 'both');
123 my $bottom = $dialog->Frame()->pack(-expand
=> 0, -fill
=> 'x');
124 my $text = $scroll->Scrolled('ROText',
128 )->pack(-expand
=> 1, -fill
=> 'both');
130 $dialog->protocol('WM_DELETE_WINDOW', sub { $dialog->withdraw(); });
131 my @pack_opts = (-side
=> 'left', -expand
=> 1, -fill
=> 'both');
135 -command
=> sub { $dialog->withdraw(); },
139 -command
=> sub { $text->delete('0.0', 'end'); },
144 my $file = $dialog->getSaveFile(-title
=> "Save $title");
145 return unless defined $file;
146 if (!open(OUT
, ">$file")) {
147 $self->show_error("Couldn't save $file: $!", 'Save Error');
150 print OUT
$text->get('0.0', 'end');
155 $self->{tk_debug_dialog
} = $dialog;
156 $self->{tk_debug_text_wg
} = $text;
158 $dialog->deiconify() if $dialog->state() eq 'withdrawn';
160 my $text = $self->{tk_debug_text_wg
};
161 $text->insert('end', "$msg\n");
166 return shift->{top_window
};
175 FVWM::Module::Tk - FVWM::Module with the Tk widget library attached
179 Name this module TestModuleTk, make it executable and place in ModulePath:
183 use lib `fvwm-perllib dir`;
184 use FVWM::Module::Tk;
185 use Tk; # preferably in this order
187 my $top = new MainWindow(-name => "Simple Test");
188 my $id = $top->wrapper->[0];
190 my $module = new FVWM::Module::Tk(
192 Mask => M_ICONIFY | M_ERROR, # Mask may be omitted
196 -text => "Close", -command => sub { $top->destroy; }
199 $module->add_default_error_handler;
200 $module->add_handler(M_ICONIFY, sub {
201 my $id0 = $_[1]->_win_id;
202 $module->send("Iconify off", $id) if $id0 == $id;
204 $module->track('Scheduler')->schedule(60, sub {
205 $module->show_message("You run this module for 1 minute")
208 $module->send('Style "*imple Test" Sticky');
213 The B<FVWM::Module::Tk> class is a sub-class of B<FVWM::Module::Toolkit>
214 that overloads the methods B<new>, B<event_loop>, B<show_message>,
215 B<show_debug> and B<show_error> to manage Tk objects as well. It also adds new
216 method B<top_window>.
218 This manual page details only those differences. For details on the
219 API itself, see L<FVWM::Module>.
223 Only overloaded or new methods are covered here:
227 =item B<new> I<param-hash>
229 $module = new B<FVWM::Module::Tk> I<TopWindow> => $top, %params
231 Create and return an object of the B<FVWM::Module::Tk> class.
232 This B<new> method is identical to the (grand-)parent class method, with the
233 exception that a Tk top-level of some sort (MainWindow, TopLevel, Frame,
234 etc.) may be passed in the hash of options using the I<TopWindow> named value.
235 Other options in I<param-hash> are the same as described in L<FVWM::Module>.
237 If no top-level window is specified in the constructor, such dummy window
238 is created and immediately withdrawn. This top-level window is needed to
243 From outward appearances, this methods operates just as the parent
244 B<event_loop> does. It is worth mentioning, however, that this version
245 enters into the Tk B<MainLoop> subroutine, ostensibly not to return.
247 =item B<show_error> I<msg> [I<title>]
249 This method creates a dialog box using the Tk widgets. The dialog has
250 three buttons labeled "Close", "Close All Errors" and "Exit Module".
251 Selecting the "Close" button closes the dialog. "Close All Errors" closes
252 all error dialogs that may be open on the screen at that time.
253 "Exit Module" terminates your entire module.
255 Good for diagnostics of a Tk based module.
257 =item B<show_message> I<msg> [I<title>]
259 Creates a message window with one "Ok" button.
261 Useful for notices by a Tk based module.
263 =item B<show_debug> I<msg> [I<title>]
265 Creates a debug window with 3 buttons "Close", "Clear" and "Save".
266 All debug messages are added to the debug window.
268 "Close" withdraws the window until the next debug message arrives.
270 "Clear" erases the current contents of the debug window.
272 "Save" dumps the current contents of the debug window to the selected file.
274 Useful for debugging a Tk based module.
278 Returns the Tk toplevel that this object was created with.
284 Would not surprise me in the least.
288 Mikhael Goikhman <migo@homemail.com>.
292 Randy J. Ray <randy@byz.org>, author of the old classes
293 B<X11::Fvwm> and B<X11::Fvwm::Tk>.
295 Scott Smedley <ss@aao.gov.au>.
297 Nick Ing-Simmons <Nick.Ing-Simmons@tiuk.ti.com> for Tk Perl extension.
301 For more information, see L<fvwm>, L<FVWM::Module> and L<Tk>.