ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/DC/UI.pm
Revision: 1.15
Committed: Fri Apr 7 23:05:21 2006 UTC (18 years, 2 months ago) by elmex
Branch: MAIN
Changes since 1.14: +176 -2 lines
Log Message:
added some new widgets

File Contents

# User Rev Content
1 elmex 1.6 package Crossfire::Client::Widget;
2 root 1.8
3 elmex 1.1 use strict;
4 elmex 1.11 use SDL::OpenGL;
5     use SDL::OpenGL::Constants;
6 elmex 1.1
7     our $FOCUS; # the widget with current focus
8 elmex 1.13 our @ACTIVE_WIDGETS;
9 elmex 1.1
10     # class methods for events
11     sub feed_sdl_key_down_event { $FOCUS->key_down ($_[0]) if $FOCUS }
12     sub feed_sdl_key_up_event { $FOCUS->key_up ($_[0]) if $FOCUS }
13     sub feed_sdl_button_down_event { $FOCUS->button_down ($_[0]) if $FOCUS }
14     sub feed_sdl_button_up_event { $FOCUS->button_up ($_[0]) if $FOCUS }
15    
16     sub new {
17     my $class = shift;
18 root 1.10
19     bless { @_ }, $class
20 elmex 1.1 }
21    
22 elmex 1.2 sub activate {
23 elmex 1.13 push @ACTIVE_WIDGETS, $_[0];
24 elmex 1.2 }
25 root 1.4
26 elmex 1.2 sub deactivate {
27 elmex 1.13 @ACTIVE_WIDGETS =
28     sort { $a->{z} <=> $b->{z} }
29     grep { $_ != $_[0] }
30     @ACTIVE_WIDGETS;
31 elmex 1.2 }
32    
33 root 1.14 sub size_request {
34     die "size_request is abtract";
35     }
36    
37 elmex 1.1 sub focus_in {
38     my ($widget) = @_;
39     $FOCUS = $widget;
40     }
41 root 1.4
42 elmex 1.1 sub focus_out {
43     my ($widget) = @_;
44     }
45 root 1.4
46 elmex 1.1 sub key_down {
47     my ($widget, $sdlev) = @_;
48     }
49 root 1.4
50 elmex 1.1 sub key_up {
51     my ($widget, $sdlev) = @_;
52     }
53 root 1.4
54 elmex 1.1 sub button_down {
55     my ($widget, $sdlev) = @_;
56     }
57 root 1.4
58 elmex 1.1 sub button_up {
59     my ($widget, $sdlev) = @_;
60     }
61 root 1.4
62 elmex 1.15 sub w { $_[0]->{w} }
63     sub h { $_[0]->{h} }
64 elmex 1.11 sub x { $_[0]->{x} = $_[1] if $_[1]; $_[0]->{x} }
65     sub y { $_[0]->{y} = $_[1] if $_[1]; $_[0]->{y} }
66 elmex 1.13 sub z { $_[0]->{z} = $_[1] if $_[1]; $_[0]->{z} }
67 elmex 1.11
68 elmex 1.1 sub draw {
69 elmex 1.11 my ($self) = @_;
70    
71     glPushMatrix;
72 root 1.12 glTranslate $self->{x}, $self->{y}, 0;
73 elmex 1.11 $self->_draw;
74     glPopMatrix;
75     }
76    
77     sub _draw {
78 elmex 1.1 my ($widget) = @_;
79     }
80 root 1.4
81 elmex 1.1 sub bbox {
82     my ($widget) = @_;
83     }
84 elmex 1.2
85 elmex 1.15 package Crossfire::Client::Widget::Container;
86    
87     our @ISA = Crossfire::Client::Widget::;
88    
89     use SDL::OpenGL;
90    
91     sub add { $_[0]->{child} = $_[1] }
92     sub get { $_[0]->{child} }
93    
94     sub size_request { $_[0]->{child}->size_request if $_[0]->{child} }
95    
96     sub _draw { die "Containers can't be drawn!" }
97    
98     package Crossfire::Client::Widget::Frame;
99    
100     our @ISA = Crossfire::Client::Widget::Container::;
101    
102     use SDL::OpenGL;
103    
104     sub size_request {
105     my ($self) = @_;
106     my $chld = $self->get
107     or return (0, 0);
108     map { $_ + 4 } $chld->size_request;
109     }
110    
111     sub _draw {
112     my ($self) = @_;
113    
114     my $chld = $self->get;
115    
116     my ($w, $h) = $chld->size_request;
117    
118     glColor 1, 0, 0;
119     glBegin GL_QUADS;
120     glTexCoord 0, 0; glVertex 0 , 0;
121     glTexCoord 0, 1; glVertex 0 , $h + 4;
122     glTexCoord 1, 1; glVertex $w + 4 , $h + 4;
123     glTexCoord 1, 0; glVertex $w + 4 , 0;
124     glEnd;
125    
126     glPushMatrix;
127     glTranslate (2, 2, 0);
128     $chld->_draw;
129     glPopMatrix;
130     }
131    
132     package Crossfire::Client::Widget::Table;
133    
134     our @ISA = Crossfire::Client::Widget::Container::;
135    
136     use SDL::OpenGL;
137    
138     sub add {
139     my ($self, $x, $y, $chld) = @_;
140     $self->{childs}[$y][$x] = $chld;
141     }
142    
143     sub max_row_height {
144     my ($self, $row) = @_;
145    
146     my $hs = 0;
147     for (my $xi = 0; $xi <= $#{$self->{childs}->[$row] || []}; $xi++) {
148     my $c = $self->{childs}->[$row]->[$xi];
149     my ($w, $h) = $c->size_request if $c;
150     if ($hs < $h) { $hs = $h }
151     }
152     return $hs;
153     }
154    
155     sub max_col_width {
156     my ($self, $col) = @_;
157    
158     my $ws = 0;
159     for (my $yi = 0; $yi <= $#{$self->{childs} || []}; $yi++) {
160     my $c = ($self->{childs}->[$yi] || [])->[$col];
161     my ($w, $h) = $c->size_request if $c;
162     if ($ws < $w) { $ws = $w }
163     }
164     return $ws;
165     }
166    
167     sub size_request {
168     my ($self) = @_;
169    
170     my ($hs, $ws) = (0, 0);
171    
172     for (my $yi = 0; $yi <= $#{$self->{childs}}; $yi++) {
173     $hs += $self->max_row_height ($yi);
174     }
175    
176     for (my $yi = 0; $yi <= $#{$self->{childs}}; $yi++) {
177     my $wm = 0;
178     for (my $xi = 0; $xi <= $#{$self->{childs}->[$yi]}; $xi++) {
179     $wm += $self->max_col_width ($xi)
180     }
181     if ($ws < $wm) { $ws = $wm }
182     }
183    
184     return ($ws, $hs);
185     }
186    
187     sub _draw {
188     my ($self) = @_;
189    
190     my $y = 0;
191     for (my $yi = 0; $yi <= $#{$self->{childs}}; $yi++) {
192     my $x = 0;
193    
194     for (my $xi = 0; $xi <= $#{$self->{childs}->[$yi]}; $xi++) {
195    
196     glPushMatrix;
197     glTranslate ($x, $y, 0);
198     my $c = $self->{childs}->[$yi]->[$xi];
199     $c->_draw if $c;
200     glPopMatrix;
201    
202     $x += $self->max_col_width ($xi);
203     }
204    
205     $y += $self->max_row_height ($yi);
206     }
207     }
208    
209     package Crossfire::Client::Widget::VBox;
210    
211     our @ISA = Crossfire::Client::Widget::Container::;
212    
213     use SDL::OpenGL;
214    
215     sub add {
216     my ($self, $chld) = @_;
217     push @{$self->{childs}}, $chld;
218     }
219    
220     sub size_request {
221     my ($self) = @_;
222    
223     my ($hs, $ws) = (0, 0);
224     for (@{$self->{childs} || []}) {
225     my ($w, $h) = $_->size_request;
226     $hs += $h;
227     if ($ws < $w) { $ws = $w }
228     }
229    
230     return ($ws, $hs);
231     }
232    
233     sub _draw {
234     my ($self) = @_;
235    
236     my ($x, $y);
237     for (@{$self->{childs} || []}) {
238     glPushMatrix;
239     glTranslate (0, $y, 0);
240     $_->_draw;
241     glPopMatrix;
242     my ($w, $h) = $_->size_request;
243     $y += $h;
244     }
245     }
246    
247 root 1.10 package Crossfire::Client::Widget::Label;
248    
249 root 1.12 our @ISA = Crossfire::Client::Widget::;
250    
251 root 1.10 use SDL::OpenGL;
252    
253     sub new {
254 root 1.12 my ($class, $x, $y, $z, $ttf, $text) = @_;
255 root 1.10
256 elmex 1.15 my $self = $class->SUPER::new (x => $x, y => $y, z => $z, ttf => $ttf);
257 root 1.10
258 elmex 1.15 $self->set_text ($text);
259 root 1.10
260     $self
261     }
262    
263 elmex 1.15 sub set_text {
264     my ($self, $text) = @_;
265     $self->{texture} = new_from_ttf Crossfire::Client::Texture $self->{ttf}, $self->{text} = $text;
266     }
267    
268     sub get_text {
269     my ($self, $text) = @_;
270     $self->{text}
271     }
272    
273 root 1.14 sub size_request {
274     my ($self) = @_;
275    
276     (
277     $self->{texture}{width},
278     $self->{texture}{height},
279     )
280     }
281    
282 elmex 1.11 sub _draw {
283 root 1.10 my ($self) = @_;
284    
285     my $tex = $self->{texture};
286    
287 root 1.12 $self->{x}--;
288    
289     glEnable GL_BLEND;
290 root 1.10 glEnable GL_TEXTURE_2D;
291 root 1.12 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE;
292 root 1.10 glBindTexture GL_TEXTURE_2D, $tex->{name};
293    
294 root 1.12 glColor 1, 1, 1;
295    
296 root 1.10 glBegin GL_QUADS;
297     glTexCoord 0, 0; glVertex 0 , 0;
298     glTexCoord 0, 1; glVertex 0 , $tex->{height};
299     glTexCoord 1, 1; glVertex $tex->{width}, $tex->{height};
300     glTexCoord 1, 0; glVertex $tex->{width}, 0;
301     glEnd;
302    
303 root 1.12 glDisable GL_BLEND;
304 root 1.10 glDisable GL_TEXTURE_2D;
305     }
306    
307 elmex 1.9 package Crossfire::Client::Widget::TextView;
308 root 1.4
309 elmex 1.3 use strict;
310 root 1.10
311 elmex 1.9 our @ISA = qw/Crossfire::Client::Widget/;
312 elmex 1.3
313     use SDL::OpenGL;
314     use SDL::OpenGL::Constants;
315    
316     sub add_line {
317     my ($self, $line) = @_;
318     push @{$self->{lines}}, $line;
319     }
320    
321 elmex 1.11 sub _draw {
322 elmex 1.3 my ($self) = @_;
323    
324     }
325    
326 elmex 1.9 package Crossfire::Client::Widget::MapWidget;
327 root 1.4
328 elmex 1.2 use strict;
329 elmex 1.7
330 elmex 1.9 our @ISA = qw/Crossfire::Client::Widget/;
331 elmex 1.2
332     use SDL::OpenGL;
333     use SDL::OpenGL::Constants;
334    
335     sub key_down {
336     print "MAPKEYDOWN\n";
337     }
338    
339     sub key_up {
340     }
341    
342 elmex 1.11 sub _draw {
343 elmex 1.2 glEnable GL_TEXTURE_2D;
344     glEnable GL_BLEND;
345 root 1.12 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE;
346 elmex 1.2
347     my $map = $::CONN->{map};
348    
349     for my $x (0 .. $::CONN->{mapw} - 1) {
350     for my $y (0 .. $::CONN->{maph} - 1) {
351    
352     my $cell = $map->[$x][$y]
353     or next;
354    
355     my $darkness = $cell->[3] * (1 / 255);
356     glColor $darkness, $darkness, $darkness;
357    
358     for my $num (grep $_, $cell->[0], $cell->[1], $cell->[2]) {
359 root 1.4 my $tex = $::CONN->{face}[$num]{texture} || next;
360 elmex 1.2
361 root 1.4 glBindTexture GL_TEXTURE_2D, $tex->{name};
362 elmex 1.2
363     glBegin GL_QUADS;
364 root 1.10 glTexCoord 0, 0; glVertex $x * 32 , $y * 32;
365     glTexCoord 0, 1; glVertex $x * 32 , $y * 32 + 32;
366     glTexCoord 1, 1; glVertex $x * 32 + 32, $y * 32 + 32;
367     glTexCoord 1, 0; glVertex $x * 32 + 32, $y * 32;
368 elmex 1.2 glEnd;
369     }
370     }
371     }
372    
373     glDisable GL_TEXTURE_2D;
374     glDisable GL_BLEND;
375     }
376    
377 elmex 1.1 1;
378 root 1.5