ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/kgsueme/kgsueme/superchat.pl
Revision: 1.1
Committed: Thu May 20 23:09:53 2004 UTC (20 years ago) by pcg
Content type: text/plain
Branch: MAIN
Log Message:
*** empty log message ***

File Contents

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