ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/kgsueme/kgsueme/chat.pl
Revision: 1.1
Committed: Fri Jul 25 03:50:33 2003 UTC (20 years, 10 months ago) by pcg
Content type: text/plain
Branch: MAIN
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 package chat;
2    
3     use Gtk2;
4    
5     use Glib::Object::Subclass
6     Gtk2::VBox,
7     signals => {
8     command => {
9     flags => [qw/run-first/],
10     return_type => undef, # void return
11     param_types => [Glib::Scalar, Glib::Scalar],
12     },
13     };
14    
15     my $tagtable = new Gtk2::TextTagTable;
16    
17     {
18     my %tags = (
19     default => { foreground => "black" },
20     node => { foreground => "#0000b0", event => 1 },
21     move => { foreground => "#0000b0", event => 1 },
22     user => { foreground => "#0000b0", event => 1 },
23     coord => { foreground => "#0000b0", event => 1 },
24     error => { foreground => "#ff0000", event => 1 },
25     header => { weight => 800, pixels_above_lines => 6 },
26     description => { weight => 800, foreground => "blue" },
27     infoblock => { weight => 700, foreground => "blue" },
28     );
29    
30     while (my ($k, $v) = each %tags) {
31     my $tag = new Gtk2::TextTag $k;
32     if (delete $v->{event}) {
33     ###
34     }
35     $tag->set (%$v);
36     $tagtable->add ($tag);
37     }
38     }
39    
40     sub INIT_INSTANCE {
41     my $self = shift;
42    
43     $self->{buffer} = new Gtk2::TextBuffer $tagtable;
44    
45     $self->{widget} = new Gtk2::ScrolledWindow;
46     $self->{widget}->set_policy("never", "always");
47     $self->pack_start ($self->{widget}, 1, 1, 0);
48    
49     $self->{widget}->add ($self->{view} = new_with_buffer Gtk2::TextView $self->{buffer});
50     $self->{view}->set_wrap_mode ("word");
51     $self->{view}->set_cursor_visible (0);
52    
53     $self->{view}->set_editable (0);
54    
55     #use PApp::Util; warn PApp::Util::dumpval ($self->{view}->get_events);
56     $self->{view}->signal_connect (motion_notify_event => sub {
57     my ($widget, $event) = @_;
58    
59     my $window = $widget->get_window ("text");
60     if ($event->window == $window) {
61     my ($win, $x, $y, $mask) = $window->get_pointer;
62     # warn "TAG EVENT @_ ($window, $win, $x, $y, $mask)\n";
63     #gtk_text_view_window_to_buffer_coords (text_view,
64     # GTK_TEXT_WINDOW_TEXT,
65     # text_view->drag_start_x,
66     # text_view->drag_start_y,
67     # &buffer_x,
68     # &buffer_y);
69     #
70     # gtk_text_layout_get_iter_at_pixel (text_view->layout,
71     # &iter,
72     # buffer_x, buffer_y);
73     #
74     # gtk_text_view_start_selection_dnd (text_view, &iter, event);
75     # return TRUE;
76     }
77     0;
78     });
79    
80     $self->pack_start (($self->{entry} = new Gtk2::Entry), 0, 1, 0);
81    
82     $self->{entry}->signal_connect(activate => sub {
83     my ($entry) = @_;
84     my $text = $entry->get_text;
85     $entry->set_text("");
86    
87     my ($cmd, $arg);
88    
89     if ($text =~ /^\/(\S+)\s*(.*)$/) {
90     ($cmd, $arg) = ($1, $2);
91     } else {
92     ($cmd, $arg) = ("msg", $text);
93     }
94    
95     $self->signal_emit (command => $cmd, $arg);
96     });
97    
98    
99     $self->set_end;
100    
101     $self;
102     }
103    
104     sub do_command {
105     my ($self, $cmd, $arg, %arg) = @_;
106     }
107    
108     sub set_end {
109     my ($self) = @_;
110    
111     # this is probably also a hack...
112     $self->{idle} ||= add Glib::Idle sub {
113     $self->{view}->scroll_to_iter ($self->{buffer}->get_end_iter, 0, 0, 0, 0)
114     if $self->{view};
115     delete $self->{idle};
116     };
117     }
118    
119     sub at_end {
120     my ($self) = @_;
121    
122     # this is, maybe, a bad hack :/
123     my $adj = $self->{widget}->get_vadjustment;
124     $adj->value + $adj->page_size >= $adj->upper - 0.5;
125     }
126    
127     sub append_text {
128     my ($self, $text) = @_;
129    
130     my $at_end = $self->at_end;
131    
132     my @tag;
133     $text = "<default>$text</default>";
134    
135     # pseudo-simplistic-xml-parser
136     for (;;) {
137     $text =~ /\G<([^>]+)>/gc or last;
138     my $tag = $1;
139     if ($tag =~ s/^\///) {
140     pop @tag;
141     } else {
142     push @tag, $tag;
143     }
144    
145     $text =~ /\G([^<]*)/gc or last;
146     $self->{buffer}->insert_with_tags_by_name ($self->{buffer}->get_end_iter, util::xmlto $1, $tag[-1])
147     if length $1;
148     }
149    
150     $self->set_end if $at_end;
151     }
152    
153     sub set_text {
154     my ($self, $text) = @_;
155    
156     my $at_end = $self->at_end;
157    
158     $self->{buffer}->set_text ("");
159     $self->append_text ($text);
160    
161     $self->set_end if $at_end;
162     }
163    
164     1;
165