1##############################################################################
2#
3# Jarl - SXPM Tk Interface Code
4#
5#   Perl code to handle showing the Jarl SXPM GUI and interfacing with it.
6#
7##############################################################################
8
9##############################################################################
10#
11#  This program is free software; you can redistribute it and/or modify
12#  it under the terms of the GNU General Public License as published by
13#  the Free Software Foundation; either version 2 of the License, or
14#  (at your option) any later version.
15#
16#  This program is distributed in the hope that it will be useful,
17#  but WITHOUT ANY WARRANTY; without even the implied warranty of
18#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19#  GNU General Public License for more details.
20#
21#  You should have received a copy of the GNU General Public License
22#  along with this program; if not, write to the Free Software
23#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24#
25#  Jabber
26#  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
27#
28##############################################################################
29
30
31##############################################################################
32#
33# jarlSXPMIF_AddMessage - takes a <message/> and adds it to the proper
34#                           channel based on the from JID.
35#
36##############################################################################
37sub jarlSXPMIF_AddXPM {
38  my ($tag,$xpm) = @_;
39
40  $Debug->Log1("jarlSXPMIF_AddMessage: tag($tag) x($x) y($y) xpm($xpm)");
41
42#
43# erasing....
44#
45
46  my $priority = "low";
47
48  $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Canvas}->delete("xpm");
49
50  $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Canvas}->
51    createImage(0,0,
52		image=>$GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Canvas}->Pixmap(-data=>$xpm),
53		anchor=>"nw",
54	        tag=>[ "xpm" ]);
55
56  $TabBar->HighlightTab($tag,$priority);
57}
58
59
60##############################################################################
61#
62# jarlSXPMIF_SXPMExists - returns 1 if the GUI for the groupchat
63#                                   exists, 0 if not.
64#
65##############################################################################
66sub jarlSXPMIF_SXPMExists {
67  my ($tag) = @_;
68  return exists($GUI{Jabber}->{SXPM}->{$tag});
69}
70
71##############################################################################
72#
73# jarlSXPMIF_NewSXPM - function to do all GUI calls needed to create
74#                      a new groupchat.
75#
76##############################################################################
77sub jarlSXPMIF_NewSXPM {
78  my ($tag) = @_;
79
80  $Debug->Log3("jarlSXPMIF_NewSXPM: tag($tag)");
81
82  $GUI{Jabber}->{SXPM}->{$tag}->{top} =
83    $TabBar->AddTab(-type=>"docked",
84				 -tag=>$tag,
85				 -text=>"SXPM - ".&jarlSXPM_BoardName($tag));
86  &jarlSXPMIF_NewGUI($tag);
87  &jarlSXPMIF_RaiseSXPM($tag);
88}
89
90
91##############################################################################
92#
93# jarlSXPMIF_RaiseSXPM - function to bring the specified groupchat
94#                                  to the top of the window list.
95#
96##############################################################################
97sub jarlSXPMIF_RaiseSXPM {
98  my ($tag) = @_;
99  $TabBar->RaiseTab($tag);
100}
101
102
103##############################################################################
104#
105# jarlSXPMIF_NewGUI - populates the new tab with a groupchat GUI.
106#
107##############################################################################
108sub jarlSXPMIF_NewGUI {
109  my ($tag) = @_;
110
111  $Debug->Log3("jarlSXPMIF_NewGUI: tag($tag)");
112
113  #---------------------------------------------------------------------------
114  # Groupchat Window
115  #---------------------------------------------------------------------------
116  $GUI{Jabber}->{SXPM}->{$tag}->{Top}->{top}=
117    $GUI{Jabber}->{SXPM}->{$tag}->{top}->
118      Frame(-background=>$GUI{color}->{jarl}->{main}->{bg}->{normal},
119	    -foreground=>$GUI{color}->{jarl}->{main}->{fg}->{dark},
120	   )->pack(-side=>"top",
121		   -fill=>"x");
122  $GUI{Jabber}->{SXPM}->{$tag}->{Bottom}->{top}=
123    $GUI{Jabber}->{SXPM}->{$tag}->{top}->
124      Frame(-background=>$GUI{color}->{jarl}->{main}->{bg}->{normal},
125	    -foreground=>$GUI{color}->{jarl}->{main}->{fg}->{dark},
126	   )->pack(-side=>"bottom",
127		   -fill=>"x");
128  $GUI{Jabber}->{SXPM}->{$tag}->{Left}->{top}=
129    $GUI{Jabber}->{SXPM}->{$tag}->{top}->
130      Frame(-background=>$GUI{color}->{jarl}->{main}->{bg}->{normal},
131	    -foreground=>$GUI{color}->{jarl}->{main}->{fg}->{dark},
132	   )->pack(-side=>"left",
133		   -fill=>"both",
134		   -expand=>1);
135  $GUI{Jabber}->{SXPM}->{$tag}->{Right}->{top}=
136    $GUI{Jabber}->{SXPM}->{$tag}->{top}->
137      Frame(-background=>$GUI{color}->{jarl}->{main}->{bg}->{normal},
138	    -foreground=>$GUI{color}->{jarl}->{main}->{fg}->{dark},
139	   )->pack(-side=>"right",
140		   -fill=>"y");
141
142  $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{top}=
143    $GUI{Jabber}->{SXPM}->{$tag}->{Left}->{top}->
144      Frame(-background=>$GUI{color}->{jarl}->{main}->{bg}->{normal},
145	    -foreground=>$GUI{color}->{jarl}->{main}->{fg}->{dark},
146	    -relief=>"sunken",
147	    -borderwidth=>2
148	   )->pack(-side=>"top",
149		   -fill=>"both",
150		   -expand=>1,
151		   -padx=>5,
152		   -pady=>5);
153
154  $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Scrolled} =
155    $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{top}->
156      Scrolled("Canvas",
157	       -scrollbars=>"osoe",
158	       -background=>$GUI{color}->{jarl}->{main}->{bg}->{normal},
159	       -scrollregion=>[ 0,0,&jarlSXPM_BoardWidth($tag),&jarlSXPM_BoardHeight($tag)],
160	       -cursor=>"crosshair"
161	      )->pack(-side=>"left",
162		      -fill=>"both",
163		      -expand=>1,
164		      -padx=>0,
165		      -pady=>0);
166
167  $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{YScrollbar} =
168    $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Scrolled}->
169      Subwidget("yscrollbar");
170  $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{YScrollbar}->
171    configure(-width=>10,
172	      -borderwidth=>1,
173	      -highlightthickness=>0,
174	      -relief=>"flat",
175	     );
176  $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{XScrollbar} =
177    $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Scrolled}->
178      Subwidget("xscrollbar");
179  $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{XScrollbar}->
180    configure(-width=>10,
181	      -borderwidth=>1,
182	      -highlightthickness=>0,
183	      -relief=>"flat",
184	     );
185  $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Canvas} =
186    $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Scrolled}->
187      Subwidget("canvas");
188
189  $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Canvas}->
190    createRectangle(0,0,&jarlSXPM_BoardWidth($tag),&jarlSXPM_BoardHeight($tag),
191		    -outline=>undef,
192		    -fill=>$GUI{color}->{jarl}->{main}->{bg}->{light},
193		    -tag=>[ "board" ]);
194
195
196  $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Canvas}->
197    Tk::bind("<Button-4>",
198	     sub{
199	       $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Canvas}->
200		 yviewScroll(-1,"units");
201	     });
202  $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Canvas}->
203    Tk::bind("<Button-5>",
204	     sub{
205	       $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Canvas}->
206		 yviewScroll(1,"units");
207	     });
208
209  $GUI{Jabber}->{SXPM}->{$tag}->{ControlPanel}->{top}=
210    $GUI{Jabber}->{SXPM}->{$tag}->{Right}->{top}->
211      Frame(-background=>$GUI{color}->{jarl}->{main}->{bg}->{normal},
212	    -foreground=>$GUI{color}->{jarl}->{main}->{fg}->{dark},
213	   )->pack(-side=>"bottom",
214		   -fill=>"y",
215		   -expand=>1,
216		   -padx=>5,
217		   -pady=>5);
218
219  $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawitem} = "rect";
220
221  $GUI{Jabber}->{SXPM}->{$tag}->{ControlPanel}->{top}->
222    Radiobutton(-variable=>\$GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawitem},
223                -text=>"Rectangle",
224                -value=>"rect",
225                -command=>sub {
226		  &jarlSXPMIF_BindStart($tag);
227		}
228	       )->pack(-side=>"top",
229		       -anchor => 'w');
230
231  $GUI{Jabber}->{SXPM}->{$tag}->{ControlPanel}->{top}->
232    Radiobutton(-variable=>\$GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawitem},
233                -text=>"Oval",
234                -value=>"oval",
235                -command=>sub {
236		  &jarlSXPMIF_BindStart($tag);
237		}
238	       )->pack(-side=>"top",
239		       -anchor => 'w');
240
241  $GUI{Jabber}->{SXPM}->{$tag}->{ControlPanel}->{top}->
242    Radiobutton(-variable=>\$GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawitem},
243                -text=>"Line",
244                -value=>"line",
245                -command=>sub {
246		  &jarlSXPMIF_BindStart($tag);
247		}
248	       )->pack(-side=>"top",
249		       -anchor => 'w');
250
251  $GUI{Jabber}->{SXPM}->{$tag}->{ControlPanel}->{top}->
252    Label(-text => "Line Width:"
253	 )->pack(-side=>"top",
254		 -anchor => 'w');
255
256  $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{thickness} = 1;
257
258  $GUI{Jabber}->{SXPM}->{$tag}->{ControlPanel}->{top}->
259    Entry(-textvariable=>\$GUI{Jabber}->{SXPM}->{$tag}->{vars}->{thickness}
260	 )->pack(-side=>"top",
261		 -anchor=>'w');
262
263  &jarlSXPMIF_BindStart($tag);
264
265  $GUI{Jabber}->{SXPM}->{$tag}->{Say}->{Leave} =
266    $GUI{Jabber}->{SXPM}->{$tag}->{Bottom}->{top}->
267      Button(-image=>$GUI{Icons}->{Leave},
268	     -background=>$GUI{color}->{jarl}->{newmessage}->{bg}->{normal},
269	     -foreground=>$GUI{color}->{jarl}->{newmessage}->{fg}->{dark},
270	     -disabledforeground=>$GUI{color}->{jarl}->{newmessage}->{fg}->{light},
271	     -font=>$GUI{fonts}->{normal},
272	     -command=>sub{
273	       &jarlSXPM_Leave($tag);
274#	       &jarlGroupChat_Leave($tag);
275	       $TabBar->DeleteTab($tag);
276	       delete($GUI{Jabber}->{SXPM}->{$tag});
277	     }
278	    )->pack(-side=>"right");
279  &jarlMainIF_RegisterIcon($GUI{Jabber}->{SXPM}->{$tag}->{Say}->{Leave},
280			 "Leave");
281  $GUI{ToolBar}->{Balloon}->
282    attach($GUI{Jabber}->{SXPM}->{$tag}->{Say}->{Leave},
283	   -balloonmsg=>"Leave the Room ");
284}
285
286
287sub jarlSXPMIF_BindStart {
288  my $tag = shift;
289  # If there is a "Motion" binding, we need to allow the user
290  # to finish drawing the item before rebinding Button-1
291  # this fcn gets called when the finish drawing the item again
292
293  $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{bindings} =
294    $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Canvas}->Tk::bind("<Motion>");
295
296  return if ($#{$GUI{Jabber}->{SXPM}->{$tag}->{vars}->{bindings}} >= 0);
297
298  if ($GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawitem} eq "rect") {
299    $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Canvas}->
300      Tk::bind("<Button-1>", [\&jarlSXPMIF_StartDrawing, $tag, Ev('x'), Ev('y')]);
301  } elsif ($GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawitem} eq "oval") {
302    $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Canvas}->
303      Tk::bind("<Button-1>", [\&jarlSXPMIF_StartDrawing, $tag, Ev('x'), Ev('y')]);
304  } elsif ($GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawitem} eq "line") {
305    $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Canvas}->
306      Tk::bind("<Button-1>", [\&jarlSXPMIF_StartDrawing, $tag, Ev('x'), Ev('y')]);
307  }
308}
309
310
311
312sub jarlSXPMIF_StartDrawing {
313  my ($canvas, $tag, $x, $y) = @_;
314  $x = $canvas->canvasx($x);
315  $y = $canvas->canvasy($y);
316
317  # Do a little error checking
318
319  return if ($x >= &jarlSXPM_BoardWidth($tag));
320  return if ($y >= &jarlSXPM_BoardHeight($tag));
321
322  return if ($GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawing} ne "");
323
324  $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{thickness} = 1
325    if (($GUI{Jabber}->{SXPM}->{$tag}->{vars}->{thickness} !~ /[0-9]+/) ||
326	($GUI{Jabber}->{SXPM}->{$tag}->{vars}->{thickness} < 1));
327
328  $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawing} =
329    $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawitem};
330  $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawingthickness} =
331    $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{thickness};
332
333  if ($GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawitem} eq "rect") {
334    $canvas->createRectangle($x, $y, $x, $y,
335			     -width => $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{thickness},
336			     -tags => "drawmenow");
337  } elsif ($GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawitem} eq "oval") {
338    $canvas->createOval($x, $y, $x, $y,
339			-width => $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{thickness},
340			-tags => "drawmenow");
341  } elsif ($GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawitem} eq "line") {
342    $canvas->createLine($x, $y, $x, $y,
343			-width => $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{thickness},
344			-tags => "drawmenow");
345  }
346
347  $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{startx} = $x;
348  $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{starty} = $y;
349
350  # Map the Button-1 binding to &jarlSXPMIF_EndDrawing instead of start drawing
351
352  $canvas->Tk::bind("<Motion>", [\&jarlSXPMIF_SizeItem, $tag, Ev('x'), Ev('y')]);
353
354  $canvas->Tk::bind("<ButtonRelease-1>", [\&jarlSXPMIF_EndDrawing, $tag, Ev('x'), Ev('y')]);
355
356}
357
358
359
360sub jarlSXPMIF_SizeItem {
361  my ($canvas, $tag, $x, $y) = @_;
362  $x = $canvas->canvasx($x);
363  $y = $canvas->canvasy($y);
364
365  return if ($x >= &jarlSXPM_BoardWidth($tag));
366  return if ($y >= &jarlSXPM_BoardHeight($tag));
367
368  $canvas->coords("drawmenow",
369		  $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{startx},
370		  $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{starty},
371		  $x,
372		  $y);
373}
374
375
376
377sub jarlSXPMIF_EndDrawing {
378  my ($canvas, $tag, $x, $y) = @_;
379  $x = $canvas->canvasx($x);
380  $y = $canvas->canvasy($y);
381
382  return if ($x >= &jarlSXPM_BoardWidth($tag));
383  return if ($y >= &jarlSXPM_BoardHeight($tag));
384
385  # finalize the size of the item, and remove the tag from the item
386
387  $canvas->coords("drawmenow",
388		  $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{startx},
389		  $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{starty},
390		  $x,
391		  $y);
392
393  # remove motion binding.
394
395  $canvas->Tk::bind("<Motion>", "");
396
397  &jarlSXPMIF_BindStart($tag);
398
399  my $drawing = $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawing};
400  $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawing} = "";
401
402  $canvas->delete("drawmenow");
403
404  if (($x != $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{startx}) ||
405      ($y != $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{starty})) {
406
407    my ($offsetX,$offsetY,$dataWidth,$data);
408
409    ($offsetX,$offsetY,$dataWidth,$data) =
410      &jarlSXPM_Rect($GUI{Jabber}->{SXPM}->{$tag}->{vars}->{startx},
411		     $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{starty},
412		     $x,
413		     $y,
414		     $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawingthickness},
415		     " ",
416		     "a",
417		     " ")
418	if ($drawing eq "rect");
419
420    ($offsetX,$offsetY,$dataWidth,$data) =
421      &jarlSXPM_Oval($GUI{Jabber}->{SXPM}->{$tag}->{vars}->{startx},
422		     $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{starty},
423		     $x,
424		     $y,
425		     $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawingthickness},
426		     " ",
427		     "a",
428		     " ")
429	if ($drawing eq "oval");
430
431    ($offsetX,$offsetY,$dataWidth,$data) =
432      &jarlSXPM_Line($GUI{Jabber}->{SXPM}->{$tag}->{vars}->{startx},
433		     $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{starty},
434		     $x,
435		     $y,
436		     $GUI{Jabber}->{SXPM}->{$tag}->{vars}->{drawingthickness},
437		     " ",
438		     "a",
439		     " ")
440	if ($drawing eq "line");
441
442    my $message = $jabber{client}->SXPMSend(to=>&jarlSXPM_JID($tag),
443					    type=>&jarlSXPM_Type($tag),
444					    data=>$data,
445					    datawidth=>$dataWidth,
446					    datax=>$offsetX,
447					    datay=>$offsetY);
448
449    &jarlSXPM_AddMessage(&jarlSXPM_JID($tag),$message);
450  }
451}
452
453
454
455
456sub jarlSXPMIF_ResizeBoard {
457  my $tag = shift;
458
459  $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Canvas}->
460    delete("board");
461  $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Canvas}->
462    createRectangle(0,0,&jarlSXPM_BoardWidth($tag),&jarlSXPM_BoardHeight($tag),
463		    -outline=>undef,
464		    -fill=>$GUI{color}->{jarl}->{main}->{bg}->{light},
465		    -tag=>[ "board" ]);
466
467  $GUI{Jabber}->{SXPM}->{$tag}->{Board}->{Canvas}->
468    configure(-scrollregion=>[ 0,0,&jarlSXPM_BoardWidth($tag),&jarlSXPM_BoardHeight($tag)],
469	     );
470}
471
472
473
474##############################################################################
475#
476# jarlSXPMIF_CurrentSay - if $value is defined then the Entry contents
477#                              are set to $value, otherwise the contents of
478#                              the Entry are returned.
479#
480##############################################################################
481sub jarlSXPMIF_CurrentSay {
482  my ($tag,$value) =  @_;
483  $Debug->Log3("jarlSXPMIF_CurrentSay: tag($tag) value($value)");
484  if (defined($value)) {
485    $Debug->Log3("jarlSXPMIF_CurrentSay: set the entry to value($value)");
486    $GUI{Jabber}->{SXPM}->{$tag}->{Say}->{Entry}->delete(0,"end");
487    $GUI{Jabber}->{SXPM}->{$tag}->{Say}->{Entry}->insert(0,$value);
488    $GUI{Jabber}->{SXPM}->{$tag}->{Say}->{Entry}->icursor("end");
489    $GUI{Jabber}->{SXPM}->{$tag}->{Say}->{Entry}->xview(0);
490    return;
491  }
492  $Debug->Log3("jarlSXPMIF_CurrentSay: return(".$GUI{Jabber}->{SXPM}->{$tag}->{Say}->{Entry}->get().")");
493  return $GUI{Jabber}->{SXPM}->{$tag}->{Say}->{Entry}->get();
494}
495
496
4971;
498