ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/DC/UI.pm
(Generate patch)

Comparing deliantra/Deliantra-Client/DC/UI.pm (file contents):
Revision 1.148 by elmex, Sat Apr 22 12:14:45 2006 UTC vs.
Revision 1.155 by root, Sun Apr 23 02:22:54 2006 UTC

8use CFClient; 8use CFClient;
9 9
10our ($FOCUS, $HOVER, $GRAB); # various widgets 10our ($FOCUS, $HOVER, $GRAB); # various widgets
11 11
12our $ROOT; 12our $ROOT;
13our $TOOLTIP;
13our $BUTTON_STATE; 14our $BUTTON_STATE;
15
16sub check_tooltip {
17 if (!$GRAB) {
18 for (my $widget = $HOVER; $widget; $widget = $widget->{parent}) {
19 if (exists $widget->{tooltip}) {
20
21 if ($TOOLTIP->{owner} != $widget) {
22 $TOOLTIP->{owner} = $widget;
23
24 my $tip = $widget->{tooltip};
25
26 $tip = $tip->($widget) if CODE:: eq ref $tip;
27
28 $TOOLTIP->set_text ($widget->{tooltip});
29 $TOOLTIP->move ($widget->coord2global ($widget->{w}, 0));
30 $TOOLTIP->show;
31 }
32
33 return;
34 }
35 }
36 }
37
38 $TOOLTIP->hide;
39 delete $TOOLTIP->{owner};
40}
14 41
15# class methods for events 42# class methods for events
16sub feed_sdl_key_down_event { 43sub feed_sdl_key_down_event {
17 $FOCUS->key_down ($_[0]) if $FOCUS; 44 $FOCUS->key_down ($_[0]) if $FOCUS;
18} 45}
28 if (!$BUTTON_STATE) { 55 if (!$BUTTON_STATE) {
29 my $widget = $ROOT->find_widget ($x, $y); 56 my $widget = $ROOT->find_widget ($x, $y);
30 57
31 $GRAB = $widget; 58 $GRAB = $widget;
32 $GRAB->update if $GRAB; 59 $GRAB->update if $GRAB;
60
61 check_tooltip;
33 } 62 }
34 63
35 $BUTTON_STATE |= 1 << ($ev->{button} - 1); 64 $BUTTON_STATE |= 1 << ($ev->{button} - 1);
36 65
37 $GRAB->button_down ($ev, $GRAB->coord2local ($x, $y)) if $GRAB; 66 $GRAB->button_down ($ev, $GRAB->coord2local ($x, $y)) if $GRAB;
49 78
50 if (!$BUTTON_STATE) { 79 if (!$BUTTON_STATE) {
51 my $grab = $GRAB; undef $GRAB; 80 my $grab = $GRAB; undef $GRAB;
52 $grab->update if $grab; 81 $grab->update if $grab;
53 $GRAB->update if $GRAB; 82 $GRAB->update if $GRAB;
83
84 check_tooltip;
54 } 85 }
55} 86}
56 87
57sub feed_sdl_motion_event { 88sub feed_sdl_motion_event {
58 my ($ev) = @_; 89 my ($ev) = @_;
63 if ($widget != $HOVER) { 94 if ($widget != $HOVER) {
64 my $hover = $HOVER; $HOVER = $widget; 95 my $hover = $HOVER; $HOVER = $widget;
65 96
66 $hover->update if $hover && $hover->{can_hover}; 97 $hover->update if $hover && $hover->{can_hover};
67 $HOVER->update if $HOVER && $HOVER->{can_hover}; 98 $HOVER->update if $HOVER && $HOVER->{can_hover};
99
100 check_tooltip;
68 } 101 }
69 102
70 $HOVER->mouse_motion ($ev, $HOVER->coord2local ($x, $y)) if $HOVER; 103 $HOVER->mouse_motion ($ev, $HOVER->coord2local ($x, $y)) if $HOVER;
71} 104}
72 105
96 129
97 my $self = bless { 130 my $self = bless {
98 x => 0, 131 x => 0,
99 y => 0, 132 y => 0,
100 z => 0, 133 z => 0,
134 can_events => 1,
101 @_ 135 @_
102 }, $class; 136 }, $class;
103 137
104 for (keys %$self) { 138 for (keys %$self) {
105 if (/^connect_(.*)$/) { 139 if (/^connect_(.*)$/) {
278} 312}
279 313
280sub find_widget { 314sub find_widget {
281 my ($self, $x, $y) = @_; 315 my ($self, $x, $y) = @_;
282 316
317 return () unless $self->{can_events};
318
283 return $self 319 return $self
284 if $x >= $self->{x} && $x < $self->{x} + $self->{w} 320 if $x >= $self->{x} && $x < $self->{x} + $self->{w}
285 && $y >= $self->{y} && $y < $self->{y} + $self->{h}; 321 && $y >= $self->{y} && $y < $self->{y} + $self->{h};
286 322
287 () 323 ()
294} 330}
295 331
296sub check_size { 332sub check_size {
297 my ($self) = @_; 333 my ($self) = @_;
298 334
335 return unless $self->{parent};
336
299 my ($w, $h) = $self->size_request; 337 my ($w, $h) = $self->size_request;
300 338
301 if ($w != $self->{req_w} || $h != $self->{req_h}) { 339 if ($w != $self->{req_w} || $h != $self->{req_h}) {
302 $self->{req_w} = $w; 340 $self->{req_w} = $w;
303 $self->{req_h} = $h; 341 $self->{req_h} = $h;
304 342
305 $self->{parent}->check_size 343 $self->{parent}->check_size;
306 if $self->{parent};
307 } 344 }
308} 345}
309 346
310sub update { 347sub update {
311 my ($self) = @_; 348 my ($self) = @_;
378 415
379package CFClient::UI::Empty; 416package CFClient::UI::Empty;
380 417
381our @ISA = CFClient::UI::Base::; 418our @ISA = CFClient::UI::Base::;
382 419
420sub new {
421 my ($class, %arg) = @_;
422 $class->SUPER::new (can_events => 0, %arg);
423}
424
383sub size_request { 425sub size_request {
384 (0, 0) 426 (0, 0)
385} 427}
386 428
387sub draw { } 429sub draw { }
395sub new { 437sub new {
396 my ($class, %arg) = @_; 438 my ($class, %arg) = @_;
397 439
398 my $children = delete $arg{children} || []; 440 my $children = delete $arg{children} || [];
399 441
400 my $self = $class->SUPER::new (children => [], %arg); 442 my $self = $class->SUPER::new (children => [], can_events => 0, %arg);
401 $self->add ($_) for @$children; 443 $self->add ($_) for @$children;
402 444
403 $self 445 $self
404} 446}
405 447
424 delete $child->{parent}; 466 delete $child->{parent};
425 467
426 $self->{children} = [ grep $_ != $child, @{ $self->{children} } ]; 468 $self->{children} = [ grep $_ != $child, @{ $self->{children} } ];
427 469
428 $self->check_size; 470 $self->check_size;
471 $self->update;
429} 472}
430 473
431sub find_widget { 474sub find_widget {
432 my ($self, $x, $y) = @_; 475 my ($self, $x, $y) = @_;
433 476
561sub new { die } 604sub new { die }
562 605
563sub size_request { 606sub size_request {
564 my ($self) = @_; 607 my ($self) = @_;
565 608
566 @$self{qw(child_w child_h)} = $self->child->size_request; 609 @$self{qw(child_w child_h)} = @{$self->child}{qw(req_w req_h)};
567 $self->child->size_allocate (0, 0, @$self{qw(child_w child_h)}); 610 $self->child->size_allocate (0, 0, @$self{qw(child_w child_h)});
568 611
569 @$self{qw(child_w child_h)} 612 @$self{qw(child_w child_h)}
570} 613}
571 614
659 702
660 my $self = $class->SUPER::new ( 703 my $self = $class->SUPER::new (
661 bg => [1, 1, 1, 1], 704 bg => [1, 1, 1, 1],
662 border_bg => [1, 1, 1, 1], 705 border_bg => [1, 1, 1, 1],
663 border => 0.8, 706 border => 0.8,
707 can_events => 1,
664 @_ 708 @_
665 ); 709 );
666 710
667 $self->{title} &&= new CFClient::UI::Label 711 $self->{title} &&= new CFClient::UI::Label
668 align => 0, 712 align => 0,
837 or next; 881 or next;
838 882
839 for my $x (0 .. $#$row) { 883 for my $x (0 .. $#$row) {
840 my $widget = $row->[$x] 884 my $widget = $row->[$x]
841 or next; 885 or next;
842 my ($w, $h) = $widget->size_request; 886 my ($w, $h) = @$widget{qw(req_w req_h)};
843 887
844 $w[$x] = max $w[$x], $w; 888 $w[$x] = max $w[$x], $w;
845 $h[$y] = max $h[$y], $h; 889 $h[$y] = max $h[$y], $h;
846 } 890 }
847 } 891 }
952 996
953 ($h, $w) = ($w, $h); 997 ($h, $w) = ($w, $h);
954 998
955 my $children = $self->{children}; 999 my $children = $self->{children};
956 1000
957 my @h = map +($_->size_request)[0], @$children; 1001 my @h = map $_->{req_w}, @$children;
958 1002
959 my $req_h = List::Util::sum @h; 1003 my $req_h = List::Util::sum @h;
960 1004
961 if ($req_h > $h) { 1005 if ($req_h > $h) {
962 # ah well, not enough space 1006 # ah well, not enough space
1010sub size_allocate { 1054sub size_allocate {
1011 my ($self, $w, $h) = @_; 1055 my ($self, $w, $h) = @_;
1012 1056
1013 my $children = $self->{children}; 1057 my $children = $self->{children};
1014 1058
1015 my @h = map +($_->size_request)[1], @$children; 1059 my @h = map $_->{req_h}, @$children;
1016 1060
1017 my $req_h = List::Util::sum @h; 1061 my $req_h = List::Util::sum @h;
1018 1062
1019 if ($req_h > $h) { 1063 if ($req_h > $h) {
1020 # ah well, not enough space 1064 # ah well, not enough space
1061 text => "", 1105 text => "",
1062 align => -1, 1106 align => -1,
1063 valign => -1, 1107 valign => -1,
1064 padding => 2, 1108 padding => 2,
1065 layout => new CFClient::Layout, 1109 layout => new CFClient::Layout,
1110 can_events => 0,
1066 %arg 1111 %arg
1067 ); 1112 );
1068 1113
1069 if (exists $self->{template}) { 1114 if (exists $self->{template}) {
1070 my $layout = new CFClient::Layout; 1115 my $layout = new CFClient::Layout;
1092 my ($self, $text) = @_; 1137 my ($self, $text) = @_;
1093 1138
1094 $self->{layout}->set_text ($text); 1139 $self->{layout}->set_text ($text);
1095 1140
1096 delete $self->{texture}; 1141 delete $self->{texture};
1142 $self->check_size;
1097 $self->update; 1143 $self->update;
1098} 1144}
1099 1145
1100sub set_markup { 1146sub set_markup {
1101 my ($self, $markup) = @_; 1147 my ($self, $markup) = @_;
1102 1148
1103 $self->{layout}->set_markup ($markup); 1149 $self->{layout}->set_markup ($markup);
1104 1150
1105 delete $self->{texture}; 1151 delete $self->{texture};
1152 $self->check_size;
1106 $self->update; 1153 $self->update;
1107} 1154}
1108 1155
1109sub size_request { 1156sub size_request {
1110 my ($self) = @_; 1157 my ($self) = @_;
1137 1184
1138sub set_fontsize { 1185sub set_fontsize {
1139 my ($self, $fontsize) = @_; 1186 my ($self, $fontsize) = @_;
1140 1187
1141 $self->{fontsize} = $fontsize; 1188 $self->{fontsize} = $fontsize;
1189 delete $self->{texture};
1142 $self->check_size; 1190 $self->check_size;
1191 $self->update;
1143} 1192}
1144 1193
1145sub _draw { 1194sub _draw {
1146 my ($self) = @_; 1195 my ($self) = @_;
1147 1196
1193 active_bg => [1, 1, 1, 0.5], 1242 active_bg => [1, 1, 1, 0.5],
1194 active_fg => [0, 0, 0], 1243 active_fg => [0, 0, 0],
1195 can_hover => 1, 1244 can_hover => 1,
1196 can_focus => 1, 1245 can_focus => 1,
1197 valign => 0, 1246 valign => 0,
1247 can_events => 1,
1198 @_ 1248 @_
1199 ) 1249 )
1200} 1250}
1201 1251
1202sub _set_text { 1252sub _set_text {
1230} 1280}
1231 1281
1232sub size_allocate { 1282sub size_allocate {
1233 my ($self, $w, $h) = @_; 1283 my ($self, $w, $h) = @_;
1234 1284
1235 $self->_set_text ($self->{text}); 1285 $self->_set_text (delete $self->{text});#d# don't check for == inside _set_text
1236} 1286}
1237 1287
1238sub set_text { 1288sub set_text {
1239 my ($self, $text) = @_; 1289 my ($self, $text) = @_;
1240 1290
1387 bg => [1, 1, 1, 0.2], 1437 bg => [1, 1, 1, 0.2],
1388 active_fg => [0, 0, 1], 1438 active_fg => [0, 0, 1],
1389 can_hover => 1, 1439 can_hover => 1,
1390 align => 0, 1440 align => 0,
1391 valign => 0, 1441 valign => 0,
1442 can_events => 1,
1392 @_ 1443 @_
1393 ) 1444 )
1394} 1445}
1395 1446
1396sub button_up { 1447sub button_up {
1501our %loaded_images; 1552our %loaded_images;
1502 1553
1503sub new { 1554sub new {
1504 my $class = shift; 1555 my $class = shift;
1505 1556
1506 my $self = $class->SUPER::new (@_); 1557 my $self = $class->SUPER::new (can_events => 0, @_);
1507 1558
1508 $self->{image} or confess "Image has 'image' not set. This is a fatal error!"; 1559 $self->{image} or confess "Image has 'image' not set. This is a fatal error!";
1509 1560
1510 $loaded_images{$self->{image}} ||= 1561 $loaded_images{$self->{image}} ||=
1511 new_from_file CFClient::Texture CFClient::find_rcfile $self->{image}, mipmap => 1; 1562 new_from_file CFClient::Texture CFClient::find_rcfile $self->{image}, mipmap => 1;
1670package CFClient::UI::Gauge; 1721package CFClient::UI::Gauge;
1671 1722
1672our @ISA = CFClient::UI::VBox::; 1723our @ISA = CFClient::UI::VBox::;
1673 1724
1674sub new { 1725sub new {
1675 my ($class, %arg) = shift; 1726 my ($class, %arg) = @_;
1676 1727
1677 my $self = $class->SUPER::new ( 1728 my $self = $class->SUPER::new (
1678 @_, 1729 tooltip => $arg{type},
1730 %arg,
1679 ); 1731 );
1680 1732
1681 $self->add ($self->{value} = new CFClient::UI::Label valign => 1, align => 0, template => "999"); 1733 $self->add ($self->{value} = new CFClient::UI::Label valign => +1, align => 0, template => "999");
1682 $self->add ($self->{gauge} = new CFClient::UI::VGauge type => $self->{type}, expand => 1); 1734 $self->add ($self->{gauge} = new CFClient::UI::VGauge type => $self->{type}, expand => 1);
1683 $self->add ($self->{max} = new CFClient::UI::Label valign => 1, align => 0, template => "999"); 1735 $self->add ($self->{max} = new CFClient::UI::Label valign => -1, align => 0, template => "999");
1684 1736
1685 $self 1737 $self
1686} 1738}
1687 1739
1688sub set_fontsize { 1740sub set_fontsize {
2054 my $class = shift; 2106 my $class = shift;
2055 2107
2056 my $self = $class->SUPER::new ( 2108 my $self = $class->SUPER::new (
2057 state => 0, 2109 state => 0,
2058 connect_activate => \&toggle_flopper, 2110 connect_activate => \&toggle_flopper,
2111 can_events => 1,
2059 @_ 2112 @_
2060 ); 2113 );
2061 2114
2062 if ($self->{state}) { 2115 if ($self->{state}) {
2063 $self->{state} = 0; 2116 $self->{state} = 0;
2083 $self->emit (changed => $self->{state}); 2136 $self->emit (changed => $self->{state});
2084} 2137}
2085 2138
2086############################################################################# 2139#############################################################################
2087 2140
2141package CFClient::UI::Tooltip;
2142
2143our @ISA = CFClient::UI::Bin::;
2144
2145use CFClient::OpenGL;
2146
2147sub new {
2148 my $class = shift;
2149
2150 $class->SUPER::new (
2151 @_,
2152 can_events => 0,
2153 )
2154}
2155
2156sub set_text {
2157 my ($self, $text) = @_;
2158
2159 $self->{label} ||= new CFClient::UI::Label fontsize => 0.8, fg => [0, 0, 0];
2160 $self->{label}->set_text ($text);
2161 $self->add ($self->{label});
2162}
2163
2164sub size_request {
2165 my ($self) = @_;
2166
2167 my ($w, $h) = @{$self->child}{qw(req_w req_h)};
2168
2169 $w = List::Util::min $::WIDTH * 0.2, $w;
2170 $h = List::Util::max $::HEIGHT * 0.2, $h;
2171
2172 ($w + 4, $h + 4)
2173}
2174
2175sub _draw {
2176 my ($self) = @_;
2177
2178 glPushMatrix;
2179 glTranslate 0.375, 0.375;
2180
2181 my ($w, $h) = @$self{qw(w h)};
2182
2183 glColor 1, 0.8, 0.4;
2184 glBegin GL_QUADS;
2185 glVertex 0 , 0;
2186 glVertex 0 , $h;
2187 glVertex $w, $h;
2188 glVertex $w, 0;
2189 glEnd;
2190
2191 glColor 0, 0, 0;
2192 glBegin GL_LINE_LOOP;
2193 glVertex 0 , 0;
2194 glVertex 0 , $h;
2195 glVertex $w, $h;
2196 glVertex $w, 0;
2197 glEnd;
2198
2199 glPopMatrix;
2200
2201 glTranslate 2, 2;
2202 $self->SUPER::_draw;
2203}
2204
2205#############################################################################
2206
2088package CFClient::UI::Root; 2207package CFClient::UI::Root;
2089 2208
2090our @ISA = CFClient::UI::Container::; 2209our @ISA = CFClient::UI::Container::;
2091 2210
2092use CFClient::OpenGL; 2211use CFClient::OpenGL;
2093 2212
2094sub check_size { 2213sub check_size {
2095 my ($self) = @_; 2214 my ($self) = @_;
2096 2215
2097 $self->configure (0, 0, $::WITH, $::HEIGHT); 2216 $self->configure (0, 0, $::WIDTH, $::HEIGHT);
2098} 2217}
2099 2218
2100sub size_request { 2219sub size_request {
2101 ($::WIDTH, $::HEIGHT) 2220 ($::WIDTH, $::HEIGHT)
2102} 2221}
2104sub configure { 2223sub configure {
2105 my ($self, $x, $y, $w, $h) = @_; 2224 my ($self, $x, $y, $w, $h) = @_;
2106 2225
2107 $self->SUPER::configure ($x, $y, $w, $h); 2226 $self->SUPER::configure ($x, $y, $w, $h);
2108 2227
2109 $_->configure ($_->{x}, $_->{y}, $_->size_request)
2110 for @{$self->{children}}; 2228 for my $child (@{$self->{children}}) {
2229 my ($X, $Y, $W, $H) = @$child{qw(x y req_w req_h)};
2230
2231 $X = List::Util::max 0, List::Util::min $w - $W, $X;
2232 $Y = List::Util::max 0, List::Util::min $h - $H, $Y;
2233 $child->configure ($X, $Y, $W,$H);
2234 }
2111} 2235}
2112 2236
2113sub _topleft { 2237sub _topleft {
2114 my ($self, $x, $y) = @_; 2238 my ($self, $x, $y) = @_;
2115 2239
2162############################################################################# 2286#############################################################################
2163 2287
2164package CFClient::UI; 2288package CFClient::UI;
2165 2289
2166$ROOT = new CFClient::UI::Root; 2290$ROOT = new CFClient::UI::Root;
2291$TOOLTIP = new CFClient::UI::Tooltip;
2167 2292
21681 22931
2169 2294

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines