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.193 by root, Wed May 10 21:12:26 2006 UTC vs.
Revision 1.198 by root, Fri May 12 02:08:52 2006 UTC

1package CFClient::UI; 1package CFClient::UI;
2 2
3use utf8;
3use strict; 4use strict;
4 5
5use Scalar::Util (); 6use Scalar::Util ();
6use List::Util (); 7use List::Util ();
7 8
23 24
24 my $tip = $widget->{tooltip}; 25 my $tip = $widget->{tooltip};
25 26
26 $tip = $tip->($widget) if CODE:: eq ref $tip; 27 $tip = $tip->($widget) if CODE:: eq ref $tip;
27 28
28 $TOOLTIP->set_markup ($widget->{tooltip}); 29 $TOOLTIP->set_tooltip_from ($widget);
29
30 $TOOLTIP->show; 30 $TOOLTIP->show;
31 31
32 my ($x, $y) = $widget->coord2global ($widget->{w}, 0); 32 my ($x, $y) = $widget->coord2global ($widget->{w}, 0);
33 33
34 if ($x + $TOOLTIP->{w} > $::WIDTH) { 34 if ($x + $TOOLTIP->{w} > $::WIDTH) {
35 ($x, $y) = $widget->coord2global (-$TOOLTIP->{w}, 0); 35 ($x, $y) = $widget->coord2global (-$TOOLTIP->{w}, 0);
36 } 36 }
37 37
38 $TOOLTIP->move ($x, $y); 38 $TOOLTIP->move ($x, $y);
39 $TOOLTIP->check_size;
40 $TOOLTIP->update;
39 } 41 }
40 42
41 return; 43 return;
42 } 44 }
43 } 45 }
250 my ($self) = @_; 252 my ($self) = @_;
251 253
252 $_->reconfigure 254 $_->reconfigure
253 for $self->children; 255 for $self->children;
254 256
255 $self->check_size; 257 $self->check_size (1);
256 $CFClient::UI::ROOT->{size_alloc}{$self} = [$self, $self->{w}, $self->{h}];
257 $self->update; 258 $self->update;
258} 259}
259 260
260sub set_max_size { 261sub set_max_size {
261 my ($self, $w, $h) = @_; 262 my ($self, $w, $h) = @_;
382sub set_parent { 383sub set_parent {
383 my ($self, $parent) = @_; 384 my ($self, $parent) = @_;
384 385
385 Scalar::Util::weaken ($self->{parent} = $parent); 386 Scalar::Util::weaken ($self->{parent} = $parent);
386 387
388
389 # TODO: req_w _does_change after ->reconfigure
387 $self->check_size 390 $self->check_size
388 unless exists $self->{req_w}; 391 unless exists $self->{req_w};
389} 392}
390 393
391sub check_size { 394sub check_size {
392 my ($self) = @_; 395 my ($self, $forced) = @_;
393 396
397 $self->{force_alloc} = 1 if $forced;
394 $CFClient::UI::ROOT->{check_size}{$self} = $self; 398 $CFClient::UI::ROOT->{check_size}{$self} = $self;
395} 399}
396 400
397sub update { 401sub update {
398 my ($self) = @_; 402 my ($self) = @_;
508 $self->{children} = [ 512 $self->{children} = [
509 sort { $a->{z} <=> $b->{z} } 513 sort { $a->{z} <=> $b->{z} }
510 @{$self->{children}}, @widgets 514 @{$self->{children}}, @widgets
511 ]; 515 ];
512 516
513 $self->check_size; 517 $self->check_size (1);
514 $self->update; 518 $self->update;
515} 519}
516 520
517sub children { 521sub children {
518 @{ $_[0]{children} } 522 @{ $_[0]{children} }
625} 629}
626 630
627sub update { 631sub update {
628 my ($self) = @_; 632 my ($self) = @_;
629 633
630 $ROOT->on_refresh ($self => sub { $self->render_child }); 634 $ROOT->on_post_alloc ($self => sub { $self->render_child });
631 $self->SUPER::update; 635 $self->SUPER::update;
632} 636}
633 637
634sub size_allocate { 638sub size_allocate {
635 my ($self, $w, $h) = @_; 639 my ($self, $w, $h) = @_;
666 my ($w, $h) = ($self->w, $self->h); 670 my ($w, $h) = ($self->w, $self->h);
667 671
668 my $tex = $self->{texture} 672 my $tex = $self->{texture}
669 or return; 673 or return;
670 674
671 glEnable GL_BLEND;
672 glBlendFunc GL_ONE, GL_ONE_MINUS_SRC_ALPHA;
673 glEnable GL_TEXTURE_2D; 675 glEnable GL_TEXTURE_2D;
674 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; 676 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE;
675 glColor 0, 0, 0, 1; 677 glColor 0, 0, 0, 1;
676 678
677 $tex->draw_quad (0, 0, $w, $h); 679 $tex->draw_quad_alpha_premultiplied (0, 0, $w, $h);
678 680
679 glDisable GL_BLEND;
680 glDisable GL_TEXTURE_2D; 681 glDisable GL_TEXTURE_2D;
681} 682}
682 683
683############################################################################# 684#############################################################################
684 685
787 788
788our @ISA = CFClient::UI::Bin::; 789our @ISA = CFClient::UI::Bin::;
789 790
790use CFClient::OpenGL; 791use CFClient::OpenGL;
791 792
792sub new {
793 my $class = shift;
794
795 my $self = $class->SUPER::new (
796 bg => [1, 1, 1, 1],
797 border_bg => [1, 1, 1, 1],
798 border => 0.8,
799 @_
800 );
801
802 $self
803}
804
805sub _draw {
806 my ($self) = @_;
807
808 my ($w, $h) = ($self->{w}, $self->{h});
809
810 glEnable GL_BLEND;
811 glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA;
812 glEnable GL_TEXTURE_2D;
813 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE;
814
815# glBegin GL_QUADS;
816# glColor 0, 0, 0, 0;
817# glVertex 0 , 0;
818# glVertex 0 , $h;
819# glVertex $w, $h;
820# glVertex $w, 0;
821# glEnd;
822
823
824 $self->child->draw;
825 glDisable GL_BLEND;
826 glDisable GL_TEXTURE_2D;
827}
828
829############################################################################# 793#############################################################################
830 794
831package CFClient::UI::FancyFrame; 795package CFClient::UI::FancyFrame;
832 796
833our @ISA = CFClient::UI::Bin::; 797our @ISA = CFClient::UI::Bin::;
947 my ($self) = @_; 911 my ($self) = @_;
948 912
949 my ($w, $h ) = ($self->{w}, $self->{h}); 913 my ($w, $h ) = ($self->{w}, $self->{h});
950 my ($cw, $ch) = ($self->child->{w}, $self->child->{h}); 914 my ($cw, $ch) = ($self->child->{w}, $self->child->{h});
951 915
952 glEnable GL_BLEND;
953 glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA;
954 glEnable GL_TEXTURE_2D; 916 glEnable GL_TEXTURE_2D;
955 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE; 917 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE;
956 918
957 my $border = $self->border; 919 my $border = $self->border;
958 920
959 glColor @{ $self->{border_bg} }; 921 glColor @{ $self->{border_bg} };
960 $tex[1]->draw_quad (0, 0, $w, $border); 922 $tex[1]->draw_quad_alpha (0, 0, $w, $border);
961 $tex[3]->draw_quad (0, $border, $border, $ch); 923 $tex[3]->draw_quad_alpha (0, $border, $border, $ch);
962 $tex[2]->draw_quad ($w - $border, $border, $border, $ch); 924 $tex[2]->draw_quad_alpha ($w - $border, $border, $border, $ch);
963 $tex[4]->draw_quad (0, $h - $border, $w, $border); 925 $tex[4]->draw_quad_alpha (0, $h - $border, $w, $border);
964 926
965 if (@{$self->{bg}} < 4 || $self->{bg}[3]) { 927 if (@{$self->{bg}} < 4 || $self->{bg}[3]) {
966 my $bg = $tex[0]; 928 my $bg = $tex[0];
967 929
968 # TODO: repeat texture not scale 930 # TODO: repeat texture not scale
972 glColor @{ $self->{bg} }; 934 glColor @{ $self->{bg} };
973 935
974 $bg->{s} = $rep_x; 936 $bg->{s} = $rep_x;
975 $bg->{t} = $rep_y; 937 $bg->{t} = $rep_y;
976 $bg->{wrap_mode} = 1; 938 $bg->{wrap_mode} = 1;
977 $bg->draw_quad ($border, $border, $cw, $ch); 939 $bg->draw_quad_alpha ($border, $border, $cw, $ch);
940 }
978 941
979 glDisable GL_TEXTURE_2D; 942 glDisable GL_TEXTURE_2D;
980 glDisable GL_BLEND;
981 }
982 943
983 $self->{title}->draw if $self->{title}; 944 $self->{title}->draw if $self->{title};
984 945
985 $self->child->draw; 946 $self->child->draw;
986} 947}
1263 my ($class, %arg) = @_; 1224 my ($class, %arg) = @_;
1264 1225
1265 my $self = $class->SUPER::new ( 1226 my $self = $class->SUPER::new (
1266 fg => [1, 1, 1], 1227 fg => [1, 1, 1],
1267 #font => default_font 1228 #font => default_font
1229 #text => initial text
1230 #markup => initial narkup
1231 layout => (new CFClient::Layout),
1268 fontsize => 1, 1232 fontsize => 1,
1269 text => "",
1270 align => -1, 1233 align => -1,
1271 valign => -1, 1234 valign => -1,
1272 padding => 2, 1235 padding => 2,
1273 layout => new CFClient::Layout,
1274 can_events => 0, 1236 can_events => 0,
1275 %arg 1237 %arg
1276 ); 1238 );
1277 1239
1278 if (exists $self->{template}) { 1240 if (exists $self->{template}) {
1279 my $layout = new CFClient::Layout; 1241 my $layout = new CFClient::Layout;
1280 $layout->set_text (delete $self->{template}); 1242 $layout->set_text (delete $self->{template});
1281 $self->{template} = $layout; 1243 $self->{template} = $layout;
1282 } 1244 }
1283 1245
1284 $self->set_text (delete $self->{text}) if exists $self->{text}; 1246 if (exists $self->{markup}) {
1285 $self->set_markup (delete $self->{markup}) if exists $self->{markup}; 1247 $self->set_markup (delete $self->{markup});
1248 } else {
1249 $self->set_text (delete $self->{text});
1250 }
1286 1251
1287 $self 1252 $self
1288} 1253}
1289 1254
1290sub escape { 1255sub escape {
1308 my ($self, $text) = @_; 1273 my ($self, $text) = @_;
1309 1274
1310 return if $self->{text} eq "T$text"; 1275 return if $self->{text} eq "T$text";
1311 $self->{text} = "T$text"; 1276 $self->{text} = "T$text";
1312 1277
1278 $self->{layout} = new CFClient::Layout if $self->{layout}->is_rgba;
1313 $self->{layout}->set_text ($text); 1279 $self->{layout}->set_text ($text);
1314 1280
1315 $self->update; 1281 $self->update;
1316 $self->check_size; 1282 $self->check_size;
1317} 1283}
1320 my ($self, $markup) = @_; 1286 my ($self, $markup) = @_;
1321 1287
1322 return if $self->{text} eq "M$markup"; 1288 return if $self->{text} eq "M$markup";
1323 $self->{text} = "M$markup"; 1289 $self->{text} = "M$markup";
1324 1290
1291 my $rgba = $markup =~ /span.*(?:foreground|background)/;
1292
1293 $self->{layout} = new CFClient::Layout $rgba if $self->{layout}->is_rgba != $rgba;
1325 $self->{layout}->set_markup ($markup); 1294 $self->{layout}->set_markup ($markup);
1326 1295
1327 $self->update; 1296 $self->update;
1328 $self->check_size; 1297 $self->check_size;
1329} 1298}
1371 1340
1372sub _draw { 1341sub _draw {
1373 my ($self) = @_; 1342 my ($self) = @_;
1374 1343
1375 my $tex = $self->{texture} ||= do { 1344 my $tex = $self->{texture} ||= do {
1345 $self->{layout}->set_foreground (@{$self->{fg}});
1376 $self->{layout}->set_font ($self->{font}) if $self->{font}; 1346 $self->{layout}->set_font ($self->{font}) if $self->{font};
1377 $self->{layout}->set_width ($self->{w}); 1347 $self->{layout}->set_width ($self->{w});
1378 $self->{layout}->set_height (List::Util::min $self->{h}, $self->{fontsize} * $::FONTSIZE); 1348 $self->{layout}->set_height (List::Util::min $self->{h}, $self->{fontsize} * $::FONTSIZE);
1349
1379 new_from_layout CFClient::Texture $self->{layout} 1350 my $tex = new_from_layout CFClient::Texture $self->{layout};
1351
1352 $self->{ox} = int $self->{align} < 0 ? $self->{padding}
1353 : $self->{align} > 0 ? $self->{w} - $tex->{w} - $self->{padding}
1354 : ($self->{w} - $tex->{w}) * 0.5;
1355
1356 $self->{oy} = int $self->{valign} < 0 ? $self->{padding}
1357 : $self->{valign} > 0 ? $self->{h} - $tex->{h} - $self->{padding}
1358 : ($self->{h} - $tex->{h}) * 0.5;
1359
1360 $tex
1380 }; 1361 };
1381 1362
1382 glEnable GL_BLEND;
1383 glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA;
1384 glEnable GL_TEXTURE_2D; 1363 glEnable GL_TEXTURE_2D;
1385 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; 1364 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE;
1386 1365
1366 if ($tex->{format} == GL_ALPHA) {
1387 glColor @{$self->{fg}}; 1367 glColor @{$self->{fg}};
1388
1389 $self->{ox} = int (
1390 $self->{align} < 0 ? $self->{padding}
1391 : $self->{align} > 0 ? $self->{w} - $tex->{w} - $self->{padding}
1392 : ($self->{w} - $tex->{w}) * 0.5
1393 );
1394
1395 $self->{oy} = int (
1396 $self->{valign} < 0 ? $self->{padding}
1397 : $self->{valign} > 0 ? $self->{h} - $tex->{h} - $self->{padding}
1398 : ($self->{h} - $tex->{h}) * 0.5
1399 );
1400
1401 $tex->draw_quad ($self->{ox}, $self->{oy}); 1368 $tex->draw_quad_alpha ($self->{ox}, $self->{oy});
1369 } else {
1370 $tex->draw_quad_alpha_premultiplied ($self->{ox}, $self->{oy});
1371 }
1402 1372
1403 glDisable GL_TEXTURE_2D; 1373 glDisable GL_TEXTURE_2D;
1404 glDisable GL_BLEND;
1405} 1374}
1406 1375
1407############################################################################# 1376#############################################################################
1408 1377
1409package CFClient::UI::EntryBase; 1378package CFClient::UI::EntryBase;
1444 $self->{layout}->set_text ("$text "); 1413 $self->{layout}->set_text ("$text ");
1445 1414
1446 $self->emit (changed => $self->{text}); 1415 $self->emit (changed => $self->{text});
1447} 1416}
1448 1417
1418sub set_text {
1419 my ($self, $text) = @_;
1420
1421 $self->{cursor} = length $text;
1422 $self->_set_text ($text);
1423 $self->check_size;
1424 $self->update;
1425}
1426
1449sub get_text { 1427sub get_text {
1450 $_[0]{text} 1428 $_[0]{text}
1451} 1429}
1452 1430
1453sub size_request { 1431sub size_request {
1460 1438
1461sub size_allocate { 1439sub size_allocate {
1462 my ($self, $w, $h) = @_; 1440 my ($self, $w, $h) = @_;
1463 1441
1464 $self->_set_text (delete $self->{text});#d# don't check for == inside _set_text 1442 $self->_set_text (delete $self->{text});#d# don't check for == inside _set_text
1465}
1466
1467sub set_text {
1468 my ($self, $text) = @_;
1469
1470 $self->{cursor} = length $text;
1471 $self->_set_text ($text);
1472 $self->update;
1473} 1443}
1474 1444
1475sub key_down { 1445sub key_down {
1476 my ($self, $ev) = @_; 1446 my ($self, $ev) = @_;
1477 1447
1665 1635
1666 if ($GRAB == $self) { 1636 if ($GRAB == $self) {
1667 $self->{fg} = $self->{active_fg}; 1637 $self->{fg} = $self->{active_fg};
1668 } 1638 }
1669 1639
1670 glEnable GL_BLEND;
1671 glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA;
1672 glEnable GL_TEXTURE_2D; 1640 glEnable GL_TEXTURE_2D;
1673 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; 1641 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE;
1674 glColor 0, 0, 0, 1; 1642 glColor 0, 0, 0, 1;
1675 1643
1676 $tex[0]->draw_quad (0, 0, $self->{w}, $self->{h}); 1644 $tex[0]->draw_quad_alpha (0, 0, $self->{w}, $self->{h});
1677 1645
1678 glDisable GL_TEXTURE_2D; 1646 glDisable GL_TEXTURE_2D;
1679 glDisable GL_BLEND;
1680 1647
1681 $self->SUPER::_draw; 1648 $self->SUPER::_draw;
1682} 1649}
1683 1650
1684############################################################################# 1651#############################################################################
1731 1698
1732 my $s = (List::Util::min @$self{qw(w h)}) - $self->{padding} * 2; 1699 my $s = (List::Util::min @$self{qw(w h)}) - $self->{padding} * 2;
1733 1700
1734 glColor @{ $FOCUS == $self ? $self->{active_fg} : $self->{fg} }; 1701 glColor @{ $FOCUS == $self ? $self->{active_fg} : $self->{fg} };
1735 1702
1736 glEnable GL_BLEND; 1703 my $tex = $self->{state} ? $tex[1] : $tex[0];
1704
1737 glEnable GL_TEXTURE_2D; 1705 glEnable GL_TEXTURE_2D;
1738 glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA;
1739
1740 my $tex = $self->{state} ? $tex[1] : $tex[0];
1741
1742 $tex->draw_quad (0, 0, $s, $s); 1706 $tex->draw_quad_alpha (0, 0, $s, $s);
1743
1744 glDisable GL_TEXTURE_2D; 1707 glDisable GL_TEXTURE_2D;
1745 glDisable GL_BLEND;
1746} 1708}
1747 1709
1748############################################################################# 1710#############################################################################
1749 1711
1750package CFClient::UI::Image; 1712package CFClient::UI::Image;
1793 glTranslate 0, -$self->{w}, 0; 1755 glTranslate 0, -$self->{w}, 0;
1794 1756
1795 ($w, $h) = ($h, $w); 1757 ($w, $h) = ($h, $w);
1796 } 1758 }
1797 1759
1798 glEnable GL_BLEND;
1799 glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA;
1800 glEnable GL_TEXTURE_2D; 1760 glEnable GL_TEXTURE_2D;
1801 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; 1761 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE;
1802 1762
1803 $tex->draw_quad (0, 0, $w, $h); 1763 $tex->draw_quad_alpha (0, 0, $w, $h);
1804 1764
1805 glDisable GL_BLEND;
1806 glDisable GL_TEXTURE_2D; 1765 glDisable GL_TEXTURE_2D;
1807} 1766}
1808 1767
1809############################################################################# 1768#############################################################################
1810 1769
2102 $page ||= 2; 2061 $page ||= 2;
2103 2062
2104 my $knob_a = $inner_pad_px + ($value - $page * 0.5); 2063 my $knob_a = $inner_pad_px + ($value - $page * 0.5);
2105 my $knob_b = $inner_pad_px + ($value + $page * 0.5); 2064 my $knob_b = $inner_pad_px + ($value + $page * 0.5);
2106 2065
2107 glEnable GL_BLEND;
2108 glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA;
2109 glEnable GL_TEXTURE_2D; 2066 glEnable GL_TEXTURE_2D;
2110 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; 2067 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE;
2111 2068
2112 # draw background 2069 # draw background
2113 $tex[1]->draw_quad (0, 0, $w, $h); 2070 $tex[1]->draw_quad_alpha (0, 0, $w, $h);
2114 2071
2115 # draw handle 2072 # draw handle
2116 $tex[0]->draw_quad ($knob_a, 0, $knob_b - $knob_a, $h); 2073 $tex[0]->draw_quad_alpha ($knob_a, 0, $knob_b - $knob_a, $h);
2117 2074
2118 glDisable GL_BLEND;
2119 glDisable GL_TEXTURE_2D; 2075 glDisable GL_TEXTURE_2D;
2120} 2076}
2121 2077
2122############################################################################# 2078#############################################################################
2123 2079
2134 fontsize => 1, 2090 fontsize => 1,
2135 can_events => 0, 2091 can_events => 0,
2136 #font => default_font 2092 #font => default_font
2137 @_, 2093 @_,
2138 2094
2139 layout => (new CFClient::Layout), 2095 layout => (new CFClient::Layout 1),
2140 par => [], 2096 par => [],
2141 height => 0, 2097 height => 0,
2142 children => [ 2098 children => [
2143 (new CFClient::UI::Empty expand => 1), 2099 (new CFClient::UI::Empty expand => 1),
2144 (new CFClient::UI::Slider vertical => 1), 2100 (new CFClient::UI::Slider vertical => 1),
2162 2118
2163 my $layout = $self->{layout}; 2119 my $layout = $self->{layout};
2164 2120
2165 $layout->set_height ($self->{fontsize} * $::FONTSIZE); 2121 $layout->set_height ($self->{fontsize} * $::FONTSIZE);
2166 $layout->set_width ($self->{children}[0]{w}); 2122 $layout->set_width ($self->{children}[0]{w});
2167 $layout->set_text ($text); 2123 $layout->set_markup ($text);
2168 2124
2169 ($layout->size)[1] 2125 ($layout->size)[1]
2170} 2126}
2171 2127
2172sub reflow { 2128sub reflow {
2210 2166
2211 return unless $self->{h} > 0; 2167 return unless $self->{h} > 0;
2212 2168
2213 delete $self->{texture}; 2169 delete $self->{texture};
2214 2170
2215 $ROOT->on_refresh ($self, sub { 2171 $ROOT->on_post_alloc ($self, sub {
2216 if (delete $self->{need_reflow}) { 2172 if (delete $self->{need_reflow}) {
2217 my $height = 0; 2173 my $height = 0;
2218 2174
2219 $height += $_->[0] = $self->text_height ($_->[2]) 2175 $height += $_->[0] = $self->text_height ($_->[2])
2220 for @{$self->{par}}; 2176 for @{$self->{par}};
2228 2184
2229 $self->{texture} ||= new_from_opengl CFClient::Texture $self->{children}[0]{w}, $self->{children}[0]{h}, sub { 2185 $self->{texture} ||= new_from_opengl CFClient::Texture $self->{children}[0]{w}, $self->{children}[0]{h}, sub {
2230 glClearColor 0, 0, 0, 0; 2186 glClearColor 0, 0, 0, 0;
2231 glClear GL_COLOR_BUFFER_BIT; 2187 glClear GL_COLOR_BUFFER_BIT;
2232 2188
2233 glEnable GL_BLEND;
2234 glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA;
2235 glEnable GL_TEXTURE_2D; 2189 glEnable GL_TEXTURE_2D;
2236 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; 2190 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE;
2237 2191
2238 my $top = int $self->{children}[1]{range}[0]; 2192 my $top = int $self->{children}[1]{range}[0];
2239 2193
2248 2202
2249 for my $par (@{$self->{par}}) { 2203 for my $par (@{$self->{par}}) {
2250 my $h = $par->[0]; 2204 my $h = $par->[0];
2251 2205
2252 if ($y0 < $y + $h && $y < $y1) { 2206 if ($y0 < $y + $h && $y < $y1) {
2207 $layout->set_foreground (@{ $par->[1] });
2253 $layout->set_text ($par->[2]); 2208 $layout->set_markup ($par->[2]);
2254 2209
2255 glColor @{ $par->[1] };
2256 my ($W, $H) = $layout->size; 2210 my ($W, $H) = $layout->size;
2257 CFClient::Texture->new_from_layout ($layout)->draw_quad (0, $y - $y0); 2211 CFClient::Texture->new_from_layout ($layout)->draw_quad_alpha_premultiplied (0, $y - $y0);
2258 } 2212 }
2259 2213
2260 $y += $h; 2214 $y += $h;
2261 } 2215 }
2262 2216
2263 glDisable GL_TEXTURE_2D; 2217 glDisable GL_TEXTURE_2D;
2264 glDisable GL_BLEND;
2265 }; 2218 };
2266 }); 2219 });
2267} 2220}
2268 2221
2269sub _draw { 2222sub _draw {
2270 my ($self) = @_; 2223 my ($self) = @_;
2271 2224
2272 glEnable GL_BLEND;
2273 glBlendFunc GL_ONE, GL_ONE_MINUS_SRC_ALPHA;
2274 glEnable GL_TEXTURE_2D; 2225 glEnable GL_TEXTURE_2D;
2275 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; 2226 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE;
2276 glColor 1, 1, 1, 1; 2227 glColor 1, 1, 1, 1;
2277 $self->{texture}->draw_quad (0, 0, $self->{children}[0]{w}, $self->{children}[0]{h}); 2228 $self->{texture}->draw_quad_alpha_premultiplied (0, 0, $self->{children}[0]{w}, $self->{children}[0]{h});
2278 glDisable GL_TEXTURE_2D; 2229 glDisable GL_TEXTURE_2D;
2279 glDisable GL_BLEND;
2280 2230
2281 $self->{children}[1]->draw; 2231 $self->{children}[1]->draw;
2282 2232
2283} 2233}
2284 2234
2378 @_, 2328 @_,
2379 can_events => 0, 2329 can_events => 0,
2380 ) 2330 )
2381} 2331}
2382 2332
2383sub set_markup { 2333sub set_tooltip_from {
2384 my ($self, $text) = @_; 2334 my ($self, $widget) = @_;
2385 2335
2386 $self->{label} ||= new CFClient::UI::Label fontsize => 0.8, fg => [0, 0, 0]; 2336 $self->add (new CFClient::UI::Label
2387 $self->{label}->set_markup ($text); 2337 markup => $widget->{tooltip},
2388 $self->add ($self->{label}); 2338 max_w => ($widget->{tooltip_width} || 0.25) * $::WIDTH,
2339 fontsize => 0.8,
2340 fg => [0, 0, 0, 1],
2341 font => ($widget->{tooltip_font} || $::FONT_PROP),
2342 );
2389} 2343}
2390 2344
2391sub size_request { 2345sub size_request {
2392 my ($self) = @_; 2346 my ($self) = @_;
2393
2394 $self->child->set_max_size ($::WIDTH * 0.3);
2395 2347
2396 my ($w, $h) = @{$self->child}{qw(req_w req_h)}; 2348 my ($w, $h) = @{$self->child}{qw(req_w req_h)};
2397 2349
2398 ($w + 4, $h + 4) 2350 ($w + 4, $h + 4)
2399} 2351}
2405} 2357}
2406 2358
2407sub _draw { 2359sub _draw {
2408 my ($self) = @_; 2360 my ($self) = @_;
2409 2361
2410 glPushMatrix;
2411 glTranslate 0.375, 0.375; 2362 glTranslate 0.375, 0.375;
2412 2363
2413 my ($w, $h) = @$self{qw(w h)}; 2364 my ($w, $h) = @$self{qw(w h)};
2414 2365
2415 glColor 1, 0.8, 0.4; 2366 glColor 1, 0.8, 0.4;
2426 glVertex 0 , $h; 2377 glVertex 0 , $h;
2427 glVertex $w, $h; 2378 glVertex $w, $h;
2428 glVertex $w, 0; 2379 glVertex $w, 0;
2429 glEnd; 2380 glEnd;
2430 2381
2431 glPopMatrix; 2382 glTranslate 2 - 0.375, 2 - 0.375;
2432
2433 glTranslate 2, 2;
2434 $self->SUPER::_draw; 2383 $self->SUPER::_draw;
2435} 2384}
2436 2385
2437############################################################################# 2386#############################################################################
2438 2387
2461 return unless $::CONN;#d# manage and cache textures differently 2410 return unless $::CONN;#d# manage and cache textures differently
2462 my $tex = $::CONN->{texture}[$::CONN->{faceid}[$self->{face}]]; 2411 my $tex = $::CONN->{texture}[$::CONN->{faceid}[$self->{face}]];
2463 2412
2464 # TODO animation 2413 # TODO animation
2465 if ($tex) { 2414 if ($tex) {
2466 glEnable GL_BLEND;
2467 glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA;
2468 glEnable GL_TEXTURE_2D; 2415 glEnable GL_TEXTURE_2D;
2469 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE; 2416 glTexEnv GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE;
2470 glColor 1, 1, 1, 1; 2417 glColor 1, 1, 1, 1;
2471 $tex->draw_quad (0, 0, $self->{w}, $self->{h}); 2418 $tex->draw_quad_alpha (0, 0, $self->{w}, $self->{h});
2472 glDisable GL_TEXTURE_2D; 2419 glDisable GL_TEXTURE_2D;
2473 glDisable GL_BLEND;
2474 } 2420 }
2475} 2421}
2476 2422
2477############################################################################# 2423#############################################################################
2478 2424
2655 } 2601 }
2656} 2602}
2657 2603
2658############################################################################# 2604#############################################################################
2659 2605
2606package CFClient::UI::Statusbox;
2607
2608our @ISA = CFClient::UI::VBox::;
2609
2610sub reorder {
2611 my ($self) = @_;
2612 my $NOW = time;
2613
2614 while (my ($k, $v) = each %{ $self->{item} }) {
2615 delete $self->{item}{$k} if $v->{timeout} < $NOW;
2616 }
2617
2618 my @widgets;
2619
2620 my @items = sort {
2621 $a->{pri} <=> $b->{pri}
2622 or $b->{id} <=> $a->{id}
2623 } values %{ $self->{item} };
2624
2625 my $count = 10 + 1;
2626 for my $item (@items) {
2627 last unless --$count;
2628
2629 push @widgets, $item->{label} ||= do {
2630 # TODO: doesn't handle markup well (read as: at all)
2631 my $short = $item->{count} > 1
2632 ? "<b>$item->{count} ×</b> $item->{text}"
2633 : $item->{text};
2634
2635 for ($short) {
2636 s/^\s+//;
2637 s/\012.*/…/s;
2638 my $len = int 40 / $item->{fontsize};
2639 substr $_, $len, length, "…" if $len < length;
2640 }
2641
2642 new CFClient::UI::Label
2643 markup => $short,
2644 tooltip => $item->{tooltip},
2645 tooltip_font => $::FONT_PROP,
2646 tooltip_width => 0.67,
2647 fontsize => $item->{fontsize},
2648 color => $item->{color},
2649 can_events => 1,
2650 can_hover => 1
2651 };
2652 }
2653
2654 $self->clear;
2655 $self->SUPER::add (reverse @widgets);
2656}
2657
2658sub add {
2659 my ($self, $text, %arg) = @_;
2660
2661 $text =~ s/^\s+//;
2662 $text =~ s/\s+$//;
2663
2664 my $timeout = time + ((delete $arg{timeout}) || 60);
2665
2666 my $group = exists $arg{group} ? $arg{group} : ++$self->{id};
2667
2668 if (my $item = $self->{item}{$group}) {
2669 if ($item->{text} eq $text) {
2670 $item->{count}++;
2671 } else {
2672 $item->{count} = 1;
2673 $item->{text} = $item->{tooltip} = $text;
2674 }
2675 $item->{id} = ++$self->{id};
2676 $item->{timeout} = $timeout;
2677 delete $item->{label};
2678 } else {
2679 $self->{item}{$group} = {
2680 id => ++$self->{id},
2681 text => $text,
2682 timeout => $timeout,
2683 tooltip => $text,
2684 fontsize => 0.8,
2685 color => [0.8, 0.8, 0.8, 0.8],
2686 pri => 0,
2687 count => 1,
2688 %arg,
2689 };
2690 }
2691
2692 $self->reorder;
2693}
2694
2695#############################################################################
2696
2660package CFClient::UI::Root; 2697package CFClient::UI::Root;
2661 2698
2662our @ISA = CFClient::UI::Container::; 2699our @ISA = CFClient::UI::Container::;
2663 2700
2664use CFClient::OpenGL; 2701use CFClient::OpenGL;
2755 my ($self, $id, $cb) = @_; 2792 my ($self, $id, $cb) = @_;
2756 2793
2757 $self->{refresh_hook}{$id} = $cb; 2794 $self->{refresh_hook}{$id} = $cb;
2758} 2795}
2759 2796
2797sub on_post_alloc {
2798 my ($self, $id, $cb) = @_;
2799
2800 $self->{post_alloc_hook}{$id} = $cb;
2801}
2802
2760sub draw { 2803sub draw {
2761 my ($self) = @_; 2804 my ($self) = @_;
2805
2806 while ($self->{refresh_hook}) {
2807 $_->()
2808 for values %{delete $self->{refresh_hook}};
2809 }
2762 2810
2763 if ($self->{check_size}) { 2811 if ($self->{check_size}) {
2764 my @queue = ([], []); 2812 my @queue = ([], []);
2765 2813
2766 for (;;) { 2814 for (;;) {
2774 2822
2775 my ($w, $h) = $widget->{user_w} && $widget->{user_h} 2823 my ($w, $h) = $widget->{user_w} && $widget->{user_h}
2776 ? @$widget{qw(user_w user_h)} 2824 ? @$widget{qw(user_w user_h)}
2777 : $widget->size_request; 2825 : $widget->size_request;
2778 2826
2827 if (delete $widget->{force_alloc}
2779 if ($w != $widget->{req_w} || $h != $widget->{req_h}) { 2828 or $w != $widget->{req_w} or $h != $widget->{req_h}) {
2780 Carp::confess "$widget: size_request is negative" if $w < 0 || $h < 0;#d# 2829 Carp::confess "$widget: size_request is negative" if $w < 0 || $h < 0;#d#
2781 2830
2782 $widget->{req_w} = $w; 2831 $widget->{req_w} = $w;
2783 $widget->{req_h} = $h; 2832 $widget->{req_h} = $h;
2784 2833
2785 $self->{size_alloc}{$widget} = [$widget, $widget->{w}, $widget->{h}]; 2834 $self->{size_alloc}{$widget} = [$widget, $widget->{w} || $w, $widget->{h} || $h];
2786 2835
2787 $widget->{parent}->check_size 2836 $widget->{parent}->check_size
2788 if $widget->{parent}; 2837 if $widget->{parent};
2789 } 2838 }
2790 } 2839 }
2802 $widget->size_allocate ($w, $h); 2851 $widget->size_allocate ($w, $h);
2803 $widget->emit (size_allocate => $w, $h); 2852 $widget->emit (size_allocate => $w, $h);
2804 } 2853 }
2805 } 2854 }
2806 2855
2807 while ($self->{refresh_hook}) { 2856 while ($self->{post_alloc_hook}) {
2808 $_->() 2857 $_->()
2809 for values %{delete $self->{refresh_hook}}; 2858 for values %{delete $self->{post_alloc_hook}};
2810 } 2859 }
2811 2860
2812 glViewport 0, 0, $::WIDTH, $::HEIGHT; 2861 glViewport 0, 0, $::WIDTH, $::HEIGHT;
2813 glClearColor +($::CFG->{fow_intensity}) x 3, 1; 2862 glClearColor +($::CFG->{fow_intensity}) x 3, 1;
2814 glClear GL_COLOR_BUFFER_BIT; 2863 glClear GL_COLOR_BUFFER_BIT;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines