{
source "source/designer";
require "mspstrings";
+ require "mspgltk";
require "mspgbase";
build_info
{
+++ /dev/null
-//texture "dejavu-20.png";
-default_size 20;
-ascent 0.950;
-descent -0.250;
-glyph 32
-{
- texcoords 0.023438 0.925781 0.023438 0.925781;
- size 0.000 0.000;
- offset 0.000 0.000;
- advance 0.300;
-};
-glyph 33
-{
- texcoords 0.070312 0.925781 0.074219 0.984375;
- size 0.100 0.750;
- offset 0.150 0.000;
- advance 0.400;
-};
-glyph 34
-{
- texcoords 0.115234 0.964844 0.126953 0.984375;
- size 0.300 0.250;
- offset 0.100 0.500;
- advance 0.500;
-};
-glyph 35
-{
- texcoords 0.156250 0.925781 0.183594 0.984375;
- size 0.700 0.750;
- offset 0.100 0.000;
- advance 0.850;
-};
-glyph 36
-{
- texcoords 0.208984 0.914062 0.228516 0.984375;
- size 0.500 0.900;
- offset 0.100 -0.150;
- advance 0.650;
-};
-glyph 37
-{
- texcoords 0.251953 0.925781 0.285156 0.984375;
- size 0.850 0.750;
- offset 0.000 0.000;
- advance 0.950;
-};
-glyph 38
-{
- texcoords 0.302734 0.925781 0.330078 0.984375;
- size 0.700 0.750;
- offset 0.050 0.000;
- advance 0.750;
-};
-glyph 39
-{
- texcoords 0.363281 0.964844 0.367188 0.984375;
- size 0.100 0.250;
- offset 0.100 0.500;
- advance 0.300;
-};
-glyph 40
-{
- texcoords 0.410156 0.914062 0.417969 0.984375;
- size 0.200 0.900;
- offset 0.100 -0.150;
- advance 0.400;
-};
-glyph 41
-{
- texcoords 0.458984 0.914062 0.466797 0.984375;
- size 0.200 0.900;
- offset 0.100 -0.150;
- advance 0.400;
-};
-glyph 42
-{
- texcoords 0.503906 0.945312 0.521484 0.984375;
- size 0.450 0.500;
- offset 0.000 0.250;
- advance 0.500;
-};
-glyph 43
-{
- texcoords 0.548828 0.925781 0.572266 0.972656;
- size 0.600 0.600;
- offset 0.100 0.000;
- advance 0.850;
-};
-glyph 44
-{
- texcoords 0.607422 0.914062 0.613281 0.933594;
- size 0.150 0.250;
- offset 0.050 -0.150;
- advance 0.300;
-};
-glyph 45
-{
- texcoords 0.654297 0.945312 0.664062 0.953125;
- size 0.250 0.100;
- offset 0.050 0.250;
- advance 0.350;
-};
-glyph 46
-{
- texcoords 0.705078 0.925781 0.708984 0.933594;
- size 0.100 0.100;
- offset 0.100 0.000;
- advance 0.300;
-};
-glyph 47
-{
- texcoords 0.750000 0.921875 0.763672 0.984375;
- size 0.350 0.800;
- offset 0.000 -0.050;
- advance 0.350;
-};
-glyph 48
-{
- texcoords 0.794922 0.925781 0.814453 0.984375;
- size 0.500 0.750;
- offset 0.050 0.000;
- advance 0.650;
-};
-glyph 49
-{
- texcoords 0.845703 0.925781 0.863281 0.984375;
- size 0.450 0.750;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 50
-{
- texcoords 0.892578 0.925781 0.912109 0.984375;
- size 0.500 0.750;
- offset 0.050 0.000;
- advance 0.650;
-};
-glyph 51
-{
- texcoords 0.941406 0.925781 0.960938 0.984375;
- size 0.500 0.750;
- offset 0.050 0.000;
- advance 0.650;
-};
-glyph 52
-{
- texcoords 0.013672 0.828125 0.035156 0.886719;
- size 0.550 0.750;
- offset 0.050 0.000;
- advance 0.650;
-};
-glyph 53
-{
- texcoords 0.064453 0.828125 0.082031 0.886719;
- size 0.450 0.750;
- offset 0.050 0.000;
- advance 0.650;
-};
-glyph 54
-{
- texcoords 0.111328 0.828125 0.130859 0.886719;
- size 0.500 0.750;
- offset 0.050 0.000;
- advance 0.650;
-};
-glyph 55
-{
- texcoords 0.160156 0.828125 0.179688 0.886719;
- size 0.500 0.750;
- offset 0.050 0.000;
- advance 0.650;
-};
-glyph 56
-{
- texcoords 0.208984 0.828125 0.228516 0.886719;
- size 0.500 0.750;
- offset 0.050 0.000;
- advance 0.650;
-};
-glyph 57
-{
- texcoords 0.257812 0.828125 0.277344 0.886719;
- size 0.500 0.750;
- offset 0.050 0.000;
- advance 0.650;
-};
-glyph 58
-{
- texcoords 0.314453 0.828125 0.318359 0.867188;
- size 0.100 0.500;
- offset 0.100 0.000;
- advance 0.350;
-};
-glyph 59
-{
- texcoords 0.363281 0.816406 0.369141 0.867188;
- size 0.150 0.650;
- offset 0.050 -0.150;
- advance 0.350;
-};
-glyph 60
-{
- texcoords 0.402344 0.832031 0.427734 0.875000;
- size 0.650 0.550;
- offset 0.100 0.050;
- advance 0.850;
-};
-glyph 61
-{
- texcoords 0.451172 0.839844 0.476562 0.863281;
- size 0.650 0.300;
- offset 0.100 0.150;
- advance 0.850;
-};
-glyph 62
-{
- texcoords 0.500000 0.832031 0.525391 0.875000;
- size 0.650 0.550;
- offset 0.100 0.050;
- advance 0.850;
-};
-glyph 63
-{
- texcoords 0.552734 0.828125 0.568359 0.886719;
- size 0.400 0.750;
- offset 0.050 0.000;
- advance 0.550;
-};
-glyph 64
-{
- texcoords 0.591797 0.816406 0.626953 0.886719;
- size 0.900 0.900;
- offset 0.050 -0.150;
- advance 1.000;
-};
-glyph 65
-{
- texcoords 0.646484 0.828125 0.671875 0.886719;
- size 0.650 0.750;
- offset 0.000 0.000;
- advance 0.700;
-};
-glyph 66
-{
- texcoords 0.697266 0.828125 0.716797 0.886719;
- size 0.500 0.750;
- offset 0.100 0.000;
- advance 0.700;
-};
-glyph 67
-{
- texcoords 0.744141 0.828125 0.767578 0.886719;
- size 0.600 0.750;
- offset 0.050 0.000;
- advance 0.700;
-};
-glyph 68
-{
- texcoords 0.792969 0.828125 0.816406 0.886719;
- size 0.600 0.750;
- offset 0.100 0.000;
- advance 0.750;
-};
-glyph 69
-{
- texcoords 0.845703 0.828125 0.863281 0.886719;
- size 0.450 0.750;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 70
-{
- texcoords 0.894531 0.828125 0.910156 0.886719;
- size 0.400 0.750;
- offset 0.100 0.000;
- advance 0.600;
-};
-glyph 71
-{
- texcoords 0.939453 0.828125 0.964844 0.886719;
- size 0.650 0.750;
- offset 0.050 0.000;
- advance 0.800;
-};
-glyph 72
-{
- texcoords 0.013672 0.730469 0.035156 0.789062;
- size 0.550 0.750;
- offset 0.100 0.000;
- advance 0.750;
-};
-glyph 73
-{
- texcoords 0.070312 0.730469 0.074219 0.789062;
- size 0.100 0.750;
- offset 0.100 0.000;
- advance 0.300;
-};
-glyph 74
-{
- texcoords 0.117188 0.714844 0.126953 0.789062;
- size 0.250 0.950;
- offset -0.050 -0.200;
- advance 0.300;
-};
-glyph 75
-{
- texcoords 0.158203 0.730469 0.181641 0.789062;
- size 0.600 0.750;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 76
-{
- texcoords 0.210938 0.730469 0.228516 0.789062;
- size 0.450 0.750;
- offset 0.100 0.000;
- advance 0.550;
-};
-glyph 77
-{
- texcoords 0.255859 0.730469 0.281250 0.789062;
- size 0.650 0.750;
- offset 0.100 0.000;
- advance 0.850;
-};
-glyph 78
-{
- texcoords 0.306641 0.730469 0.328125 0.789062;
- size 0.550 0.750;
- offset 0.100 0.000;
- advance 0.750;
-};
-glyph 79
-{
- texcoords 0.351562 0.730469 0.378906 0.789062;
- size 0.700 0.750;
- offset 0.050 0.000;
- advance 0.800;
-};
-glyph 80
-{
- texcoords 0.406250 0.730469 0.423828 0.789062;
- size 0.450 0.750;
- offset 0.100 0.000;
- advance 0.600;
-};
-glyph 81
-{
- texcoords 0.449219 0.718750 0.476562 0.789062;
- size 0.700 0.900;
- offset 0.050 -0.150;
- advance 0.800;
-};
-glyph 82
-{
- texcoords 0.501953 0.730469 0.523438 0.789062;
- size 0.550 0.750;
- offset 0.100 0.000;
- advance 0.700;
-};
-glyph 83
-{
- texcoords 0.550781 0.730469 0.572266 0.789062;
- size 0.550 0.750;
- offset 0.050 0.000;
- advance 0.650;
-};
-glyph 84
-{
- texcoords 0.597656 0.730469 0.621094 0.789062;
- size 0.600 0.750;
- offset 0.000 0.000;
- advance 0.600;
-};
-glyph 85
-{
- texcoords 0.648438 0.730469 0.669922 0.789062;
- size 0.550 0.750;
- offset 0.100 0.000;
- advance 0.750;
-};
-glyph 86
-{
- texcoords 0.695312 0.730469 0.720703 0.789062;
- size 0.650 0.750;
- offset 0.000 0.000;
- advance 0.700;
-};
-glyph 87
-{
- texcoords 0.738281 0.730469 0.773438 0.789062;
- size 0.900 0.750;
- offset 0.050 0.000;
- advance 1.000;
-};
-glyph 88
-{
- texcoords 0.792969 0.730469 0.816406 0.789062;
- size 0.600 0.750;
- offset 0.050 0.000;
- advance 0.700;
-};
-glyph 89
-{
- texcoords 0.841797 0.730469 0.865234 0.789062;
- size 0.600 0.750;
- offset 0.000 0.000;
- advance 0.600;
-};
-glyph 90
-{
- texcoords 0.890625 0.730469 0.914062 0.789062;
- size 0.600 0.750;
- offset 0.050 0.000;
- advance 0.700;
-};
-glyph 91
-{
- texcoords 0.947266 0.718750 0.955078 0.789062;
- size 0.200 0.900;
- offset 0.100 -0.150;
- advance 0.400;
-};
-glyph 92
-{
- texcoords 0.017578 0.628906 0.031250 0.691406;
- size 0.350 0.800;
- offset 0.000 -0.050;
- advance 0.350;
-};
-glyph 93
-{
- texcoords 0.068359 0.621094 0.076172 0.691406;
- size 0.200 0.900;
- offset 0.100 -0.150;
- advance 0.400;
-};
-glyph 94
-{
- texcoords 0.109375 0.671875 0.134766 0.691406;
- size 0.650 0.250;
- offset 0.100 0.500;
- advance 0.850;
-};
-glyph 95
-{
- texcoords 0.160156 0.613281 0.179688 0.621094;
- size 0.500 0.100;
- offset 0.000 -0.250;
- advance 0.500;
-};
-glyph 96
-{
- texcoords 0.214844 0.679688 0.224609 0.695312;
- size 0.250 0.200;
- offset 0.050 0.600;
- advance 0.500;
-};
-glyph 97
-{
- texcoords 0.259766 0.632812 0.277344 0.675781;
- size 0.450 0.550;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 98
-{
- texcoords 0.306641 0.632812 0.326172 0.691406;
- size 0.500 0.750;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 99
-{
- texcoords 0.357422 0.632812 0.375000 0.675781;
- size 0.450 0.550;
- offset 0.050 0.000;
- advance 0.550;
-};
-glyph 100
-{
- texcoords 0.404297 0.632812 0.423828 0.691406;
- size 0.500 0.750;
- offset 0.050 0.000;
- advance 0.650;
-};
-glyph 101
-{
- texcoords 0.453125 0.632812 0.472656 0.675781;
- size 0.500 0.550;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 102
-{
- texcoords 0.505859 0.632812 0.519531 0.691406;
- size 0.350 0.750;
- offset 0.000 0.000;
- advance 0.350;
-};
-glyph 103
-{
- texcoords 0.550781 0.617188 0.570312 0.675781;
- size 0.500 0.750;
- offset 0.050 -0.200;
- advance 0.650;
-};
-glyph 104
-{
- texcoords 0.601562 0.632812 0.619141 0.691406;
- size 0.450 0.750;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 105
-{
- texcoords 0.656250 0.632812 0.660156 0.691406;
- size 0.100 0.750;
- offset 0.100 0.000;
- advance 0.300;
-};
-glyph 106
-{
- texcoords 0.703125 0.617188 0.710938 0.691406;
- size 0.200 0.950;
- offset 0.000 -0.200;
- advance 0.300;
-};
-glyph 107
-{
- texcoords 0.746094 0.632812 0.765625 0.691406;
- size 0.500 0.750;
- offset 0.100 0.000;
- advance 0.600;
-};
-glyph 108
-{
- texcoords 0.802734 0.632812 0.806641 0.691406;
- size 0.100 0.750;
- offset 0.100 0.000;
- advance 0.300;
-};
-glyph 109
-{
- texcoords 0.837891 0.632812 0.869141 0.675781;
- size 0.800 0.550;
- offset 0.100 0.000;
- advance 1.000;
-};
-glyph 110
-{
- texcoords 0.894531 0.632812 0.912109 0.675781;
- size 0.450 0.550;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 111
-{
- texcoords 0.941406 0.632812 0.960938 0.675781;
- size 0.500 0.550;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 112
-{
- texcoords 0.013672 0.519531 0.033203 0.578125;
- size 0.500 0.750;
- offset 0.100 -0.200;
- advance 0.650;
-};
-glyph 113
-{
- texcoords 0.062500 0.519531 0.082031 0.578125;
- size 0.500 0.750;
- offset 0.050 -0.200;
- advance 0.650;
-};
-glyph 114
-{
- texcoords 0.115234 0.535156 0.126953 0.578125;
- size 0.300 0.550;
- offset 0.100 0.000;
- advance 0.400;
-};
-glyph 115
-{
- texcoords 0.162109 0.535156 0.179688 0.578125;
- size 0.450 0.550;
- offset 0.050 0.000;
- advance 0.500;
-};
-glyph 116
-{
- texcoords 0.212891 0.535156 0.226562 0.589844;
- size 0.350 0.700;
- offset 0.050 0.000;
- advance 0.400;
-};
-glyph 117
-{
- texcoords 0.259766 0.535156 0.277344 0.578125;
- size 0.450 0.550;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 118
-{
- texcoords 0.306641 0.535156 0.328125 0.578125;
- size 0.550 0.550;
- offset 0.000 0.000;
- advance 0.550;
-};
-glyph 119
-{
- texcoords 0.351562 0.535156 0.380859 0.578125;
- size 0.750 0.550;
- offset 0.050 0.000;
- advance 0.850;
-};
-glyph 120
-{
- texcoords 0.404297 0.535156 0.425781 0.578125;
- size 0.550 0.550;
- offset 0.000 0.000;
- advance 0.550;
-};
-glyph 121
-{
- texcoords 0.453125 0.519531 0.474609 0.578125;
- size 0.550 0.750;
- offset 0.000 -0.200;
- advance 0.550;
-};
-glyph 122
-{
- texcoords 0.503906 0.535156 0.521484 0.578125;
- size 0.450 0.550;
- offset 0.050 0.000;
- advance 0.550;
-};
-glyph 123
-{
- texcoords 0.552734 0.523438 0.568359 0.593750;
- size 0.400 0.900;
- offset 0.150 -0.150;
- advance 0.650;
-};
-glyph 124
-{
- texcoords 0.607422 0.515625 0.611328 0.593750;
- size 0.100 1.000;
- offset 0.150 -0.250;
- advance 0.350;
-};
-glyph 125
-{
- texcoords 0.650391 0.523438 0.666016 0.593750;
- size 0.400 0.900;
- offset 0.100 -0.150;
- advance 0.650;
-};
-glyph 126
-{
- texcoords 0.695312 0.550781 0.720703 0.570312;
- size 0.650 0.250;
- offset 0.100 0.200;
- advance 0.850;
-};
-glyph 160
-{
- texcoords 0.755859 0.535156 0.755859 0.535156;
- size 0.000 0.000;
- offset 0.000 0.000;
- advance 0.300;
-};
-glyph 161
-{
- texcoords 0.802734 0.535156 0.806641 0.593750;
- size 0.100 0.750;
- offset 0.150 0.000;
- advance 0.400;
-};
-glyph 162
-{
- texcoords 0.845703 0.523438 0.863281 0.589844;
- size 0.450 0.850;
- offset 0.100 -0.150;
- advance 0.650;
-};
-glyph 163
-{
- texcoords 0.894531 0.535156 0.912109 0.593750;
- size 0.450 0.750;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 164
-{
- texcoords 0.941406 0.539062 0.962891 0.582031;
- size 0.550 0.550;
- offset 0.000 0.050;
- advance 0.650;
-};
-glyph 165
-{
- texcoords 0.011719 0.437500 0.035156 0.496094;
- size 0.600 0.750;
- offset 0.000 0.000;
- advance 0.650;
-};
-glyph 166
-{
- texcoords 0.070312 0.425781 0.074219 0.492188;
- size 0.100 0.850;
- offset 0.150 -0.150;
- advance 0.350;
-};
-glyph 167
-{
- texcoords 0.113281 0.429688 0.128906 0.496094;
- size 0.400 0.850;
- offset 0.050 -0.100;
- advance 0.500;
-};
-glyph 168
-{
- texcoords 0.164062 0.488281 0.175781 0.496094;
- size 0.300 0.100;
- offset 0.100 0.650;
- advance 0.500;
-};
-glyph 169
-{
- texcoords 0.205078 0.437500 0.232422 0.496094;
- size 0.700 0.750;
- offset 0.150 0.000;
- advance 1.000;
-};
-glyph 170
-{
- texcoords 0.259766 0.457031 0.277344 0.496094;
- size 0.450 0.500;
- offset 0.050 0.250;
- advance 0.450;
-};
-glyph 171
-{
- texcoords 0.306641 0.441406 0.326172 0.476562;
- size 0.500 0.450;
- offset 0.100 0.050;
- advance 0.600;
-};
-glyph 172
-{
- texcoords 0.353516 0.445312 0.378906 0.468750;
- size 0.650 0.300;
- offset 0.100 0.100;
- advance 0.850;
-};
-glyph 173
-{
- texcoords 0.410156 0.457031 0.419922 0.464844;
- size 0.250 0.100;
- offset 0.050 0.250;
- advance 0.350;
-};
-glyph 174
-{
- texcoords 0.449219 0.437500 0.478516 0.496094;
- size 0.750 0.750;
- offset 0.150 0.000;
- advance 1.000;
-};
-glyph 175
-{
- texcoords 0.505859 0.488281 0.517578 0.496094;
- size 0.300 0.100;
- offset 0.100 0.650;
- advance 0.500;
-};
-glyph 176
-{
- texcoords 0.554688 0.472656 0.566406 0.496094;
- size 0.300 0.300;
- offset 0.100 0.450;
- advance 0.500;
-};
-glyph 177
-{
- texcoords 0.597656 0.437500 0.621094 0.488281;
- size 0.600 0.650;
- offset 0.150 0.000;
- advance 0.850;
-};
-glyph 178
-{
- texcoords 0.652344 0.464844 0.664062 0.496094;
- size 0.300 0.400;
- offset 0.050 0.350;
- advance 0.400;
-};
-glyph 179
-{
- texcoords 0.701172 0.464844 0.712891 0.496094;
- size 0.300 0.400;
- offset 0.050 0.350;
- advance 0.400;
-};
-glyph 180
-{
- texcoords 0.751953 0.484375 0.761719 0.500000;
- size 0.250 0.200;
- offset 0.150 0.600;
- advance 0.500;
-};
-glyph 181
-{
- texcoords 0.794922 0.421875 0.814453 0.480469;
- size 0.500 0.750;
- offset 0.100 -0.200;
- advance 0.650;
-};
-glyph 182
-{
- texcoords 0.845703 0.429688 0.863281 0.496094;
- size 0.450 0.850;
- offset 0.100 -0.100;
- advance 0.650;
-};
-glyph 183
-{
- texcoords 0.900391 0.460938 0.904297 0.468750;
- size 0.100 0.100;
- offset 0.100 0.300;
- advance 0.300;
-};
-glyph 184
-{
- texcoords 0.947266 0.421875 0.955078 0.437500;
- size 0.200 0.200;
- offset 0.150 -0.200;
- advance 0.500;
-};
-glyph 185
-{
- texcoords 0.019531 0.367188 0.029297 0.398438;
- size 0.250 0.400;
- offset 0.100 0.350;
- advance 0.400;
-};
-glyph 186
-{
- texcoords 0.064453 0.359375 0.080078 0.398438;
- size 0.400 0.500;
- offset 0.050 0.250;
- advance 0.450;
-};
-glyph 187
-{
- texcoords 0.111328 0.343750 0.130859 0.378906;
- size 0.500 0.450;
- offset 0.100 0.050;
- advance 0.600;
-};
-glyph 188
-{
- texcoords 0.154297 0.339844 0.185547 0.398438;
- size 0.800 0.750;
- offset 0.100 0.000;
- advance 0.950;
-};
-glyph 189
-{
- texcoords 0.203125 0.339844 0.234375 0.398438;
- size 0.800 0.750;
- offset 0.100 0.000;
- advance 0.950;
-};
-glyph 190
-{
- texcoords 0.251953 0.339844 0.285156 0.398438;
- size 0.850 0.750;
- offset 0.050 0.000;
- advance 0.950;
-};
-glyph 191
-{
- texcoords 0.308594 0.339844 0.324219 0.398438;
- size 0.400 0.750;
- offset 0.050 0.000;
- advance 0.550;
-};
-glyph 192
-{
- texcoords 0.353516 0.339844 0.378906 0.414062;
- size 0.650 0.950;
- offset 0.000 0.000;
- advance 0.700;
-};
-glyph 193
-{
- texcoords 0.402344 0.339844 0.427734 0.414062;
- size 0.650 0.950;
- offset 0.000 0.000;
- advance 0.700;
-};
-glyph 194
-{
- texcoords 0.451172 0.339844 0.476562 0.414062;
- size 0.650 0.950;
- offset 0.000 0.000;
- advance 0.700;
-};
-glyph 195
-{
- texcoords 0.500000 0.339844 0.525391 0.410156;
- size 0.650 0.900;
- offset 0.000 0.000;
- advance 0.700;
-};
-glyph 196
-{
- texcoords 0.548828 0.339844 0.574219 0.414062;
- size 0.650 0.950;
- offset 0.000 0.000;
- advance 0.700;
-};
-glyph 197
-{
- texcoords 0.597656 0.339844 0.623047 0.414062;
- size 0.650 0.950;
- offset 0.000 0.000;
- advance 0.700;
-};
-glyph 198
-{
- texcoords 0.640625 0.339844 0.675781 0.398438;
- size 0.900 0.750;
- offset 0.000 0.000;
- advance 1.000;
-};
-glyph 199
-{
- texcoords 0.695312 0.324219 0.718750 0.398438;
- size 0.600 0.950;
- offset 0.050 -0.200;
- advance 0.700;
-};
-glyph 200
-{
- texcoords 0.748047 0.339844 0.765625 0.414062;
- size 0.450 0.950;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 201
-{
- texcoords 0.796875 0.339844 0.814453 0.414062;
- size 0.450 0.950;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 202
-{
- texcoords 0.845703 0.339844 0.863281 0.414062;
- size 0.450 0.950;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 203
-{
- texcoords 0.894531 0.339844 0.912109 0.414062;
- size 0.450 0.950;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 204
-{
- texcoords 0.947266 0.339844 0.955078 0.414062;
- size 0.200 0.950;
- offset 0.050 0.000;
- advance 0.300;
-};
-glyph 205
-{
- texcoords 0.019531 0.242188 0.027344 0.316406;
- size 0.200 0.950;
- offset 0.100 0.000;
- advance 0.300;
-};
-glyph 206
-{
- texcoords 0.066406 0.242188 0.078125 0.316406;
- size 0.300 0.950;
- offset 0.000 0.000;
- advance 0.300;
-};
-glyph 207
-{
- texcoords 0.115234 0.242188 0.126953 0.316406;
- size 0.300 0.950;
- offset 0.000 0.000;
- advance 0.300;
-};
-glyph 208
-{
- texcoords 0.156250 0.242188 0.183594 0.300781;
- size 0.700 0.750;
- offset 0.000 0.000;
- advance 0.750;
-};
-glyph 209
-{
- texcoords 0.208984 0.242188 0.230469 0.312500;
- size 0.550 0.900;
- offset 0.100 0.000;
- advance 0.750;
-};
-glyph 210
-{
- texcoords 0.253906 0.242188 0.281250 0.316406;
- size 0.700 0.950;
- offset 0.050 0.000;
- advance 0.800;
-};
-glyph 211
-{
- texcoords 0.302734 0.242188 0.330078 0.316406;
- size 0.700 0.950;
- offset 0.050 0.000;
- advance 0.800;
-};
-glyph 212
-{
- texcoords 0.351562 0.242188 0.378906 0.316406;
- size 0.700 0.950;
- offset 0.050 0.000;
- advance 0.800;
-};
-glyph 213
-{
- texcoords 0.400391 0.242188 0.427734 0.312500;
- size 0.700 0.900;
- offset 0.050 0.000;
- advance 0.800;
-};
-glyph 214
-{
- texcoords 0.449219 0.242188 0.476562 0.316406;
- size 0.700 0.950;
- offset 0.050 0.000;
- advance 0.800;
-};
-glyph 215
-{
- texcoords 0.501953 0.246094 0.523438 0.289062;
- size 0.550 0.550;
- offset 0.150 0.050;
- advance 0.850;
-};
-glyph 216
-{
- texcoords 0.544922 0.238281 0.576172 0.304688;
- size 0.800 0.850;
- offset 0.000 -0.050;
- advance 0.800;
-};
-glyph 217
-{
- texcoords 0.599609 0.242188 0.621094 0.316406;
- size 0.550 0.950;
- offset 0.100 0.000;
- advance 0.750;
-};
-glyph 218
-{
- texcoords 0.648438 0.242188 0.669922 0.316406;
- size 0.550 0.950;
- offset 0.100 0.000;
- advance 0.750;
-};
-glyph 219
-{
- texcoords 0.697266 0.242188 0.718750 0.316406;
- size 0.550 0.950;
- offset 0.100 0.000;
- advance 0.750;
-};
-glyph 220
-{
- texcoords 0.746094 0.242188 0.767578 0.316406;
- size 0.550 0.950;
- offset 0.100 0.000;
- advance 0.750;
-};
-glyph 221
-{
- texcoords 0.792969 0.242188 0.816406 0.316406;
- size 0.600 0.950;
- offset 0.000 0.000;
- advance 0.600;
-};
-glyph 222
-{
- texcoords 0.845703 0.242188 0.863281 0.300781;
- size 0.450 0.750;
- offset 0.100 0.000;
- advance 0.600;
-};
-glyph 223
-{
- texcoords 0.892578 0.242188 0.912109 0.300781;
- size 0.500 0.750;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 224
-{
- texcoords 0.943359 0.242188 0.960938 0.304688;
- size 0.450 0.800;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 225
-{
- texcoords 0.015625 0.144531 0.033203 0.207031;
- size 0.450 0.800;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 226
-{
- texcoords 0.064453 0.144531 0.082031 0.207031;
- size 0.450 0.800;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 227
-{
- texcoords 0.113281 0.144531 0.130859 0.207031;
- size 0.450 0.800;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 228
-{
- texcoords 0.162109 0.144531 0.179688 0.203125;
- size 0.450 0.750;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 229
-{
- texcoords 0.210938 0.144531 0.228516 0.210938;
- size 0.450 0.850;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 230
-{
- texcoords 0.251953 0.144531 0.285156 0.187500;
- size 0.850 0.550;
- offset 0.050 0.000;
- advance 0.950;
-};
-glyph 231
-{
- texcoords 0.308594 0.128906 0.326172 0.187500;
- size 0.450 0.750;
- offset 0.050 -0.200;
- advance 0.550;
-};
-glyph 232
-{
- texcoords 0.355469 0.144531 0.375000 0.207031;
- size 0.500 0.800;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 233
-{
- texcoords 0.404297 0.144531 0.423828 0.207031;
- size 0.500 0.800;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 234
-{
- texcoords 0.453125 0.144531 0.472656 0.207031;
- size 0.500 0.800;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 235
-{
- texcoords 0.501953 0.144531 0.521484 0.203125;
- size 0.500 0.750;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 236
-{
- texcoords 0.556641 0.144531 0.566406 0.207031;
- size 0.250 0.800;
- offset -0.050 0.000;
- advance 0.300;
-};
-glyph 237
-{
- texcoords 0.605469 0.144531 0.615234 0.207031;
- size 0.250 0.800;
- offset 0.050 0.000;
- advance 0.300;
-};
-glyph 238
-{
- texcoords 0.652344 0.144531 0.664062 0.207031;
- size 0.300 0.800;
- offset 0.000 0.000;
- advance 0.300;
-};
-glyph 239
-{
- texcoords 0.701172 0.144531 0.712891 0.203125;
- size 0.300 0.750;
- offset 0.000 0.000;
- advance 0.300;
-};
-glyph 240
-{
- texcoords 0.746094 0.144531 0.765625 0.203125;
- size 0.500 0.750;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 241
-{
- texcoords 0.796875 0.144531 0.814453 0.207031;
- size 0.450 0.800;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 242
-{
- texcoords 0.843750 0.144531 0.863281 0.207031;
- size 0.500 0.800;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 243
-{
- texcoords 0.892578 0.144531 0.912109 0.207031;
- size 0.500 0.800;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 244
-{
- texcoords 0.941406 0.144531 0.960938 0.207031;
- size 0.500 0.800;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 245
-{
- texcoords 0.013672 0.046875 0.033203 0.109375;
- size 0.500 0.800;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 246
-{
- texcoords 0.062500 0.046875 0.082031 0.105469;
- size 0.500 0.750;
- offset 0.050 0.000;
- advance 0.600;
-};
-glyph 247
-{
- texcoords 0.109375 0.050781 0.132812 0.089844;
- size 0.600 0.500;
- offset 0.100 0.050;
- advance 0.850;
-};
-glyph 248
-{
- texcoords 0.158203 0.042969 0.181641 0.093750;
- size 0.600 0.650;
- offset 0.000 -0.050;
- advance 0.600;
-};
-glyph 249
-{
- texcoords 0.210938 0.046875 0.228516 0.109375;
- size 0.450 0.800;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 250
-{
- texcoords 0.259766 0.046875 0.277344 0.109375;
- size 0.450 0.800;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 251
-{
- texcoords 0.308594 0.046875 0.326172 0.109375;
- size 0.450 0.800;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 252
-{
- texcoords 0.357422 0.046875 0.375000 0.105469;
- size 0.450 0.750;
- offset 0.100 0.000;
- advance 0.650;
-};
-glyph 253
-{
- texcoords 0.404297 0.031250 0.425781 0.109375;
- size 0.550 1.000;
- offset 0.000 -0.200;
- advance 0.550;
-};
-glyph 254
-{
- texcoords 0.453125 0.031250 0.472656 0.105469;
- size 0.500 0.950;
- offset 0.100 -0.200;
- advance 0.650;
-};
-glyph 255
-{
- texcoords 0.501953 0.031250 0.523438 0.105469;
- size 0.550 0.950;
- offset 0.000 -0.200;
- advance 0.550;
-};
border { top 5; right 5; bottom 5; left 5; };
};
+graphic "tooltip"
+{
+ texture "gui.png";
+ slice 72 90 20 16;
+ border { top 2; right 2; bottom 2; left 2; };
+};
+
graphic "hsliderslot"
{
texture "gui.png";
graphic "switchdown"
{
texture "gui.png";
- slice 46 43 20 21;
+ slice 47 43 20 21;
shadow { top 0; right 2; bottom 3; left 0; };
};
graphic "switchup"
{
texture "gui.png";
- slice 67 43 20 21;
+ slice 69 43 20 21;
shadow { top 0; right 2; bottom 3; left 0; };
};
};
};
+style "label-tooltip"
+{
+ font_color 0.0 0.0 0.0;
+
+ part
+ {
+ graphic NORMAL "tooltip";
+ };
+
+ special "text"
+ {
+ align 0.0 0.5;
+ fill 0.0 0.0;
+ margin { top 2; right 2; bottom 2; left 2; };
+ };
+};
+
style "hslider"
{
part
#include <cmath>
#include <iostream>
#include <GL/gl.h>
+#include <msp/gl/matrix.h>
+#include <msp/gl/misc.h>
+#include <msp/gl/projection.h>
#include <msp/gl/rendermode.h>
#include <msp/gl/select.h>
+#include <msp/gl/tests.h>
#include <msp/gl/texture2d.h>
#include <msp/input/keys.h>
+#include <msp/io/print.h>
#include <msp/strings/codec.h>
#include <msp/strings/lexicalcast.h>
#include <msp/strings/utf8.h>
#include "manipulator.h"
#include "measure.h"
#include "selection.h"
+#include "toolbar.h"
using namespace std;
using namespace Marklin;
screen_w(1280),
screen_h(960),
base_mesh(0),
+ cur_route(0),
mode(SELECT),
input(0),
cam_yaw(M_PI/2),
if(argc>1)
{
+ filename = argv[1];
DataFile::load(*layout, argv[1]);
const list<Track3D *> <racks = layout_3d->get_tracks();
for(list<Track3D *>::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
- {
- if((*i)->get_track().get_sensor_id())
- (*i)->set_color(GL::Color(1, 1, 0.5));
- else if((*i)->get_track().get_turnout_id())
- (*i)->set_color(GL::Color(0.5, 1, 1));
- else if((*i)->get_track().get_flex())
- (*i)->set_color(GL::Color(1, 0.5, 1));
- }
+ update_track_color(**i);
if(!layout->get_base().empty())
{
dpy = new Graphics::Display;
wnd = new Graphics::Window(*dpy, screen_w, screen_h);
glc = new Graphics::GLContext(*wnd);
+ wnd->set_title("Railway Designer");
wnd->signal_close.connect(sigc::bind(sigc::mem_fun(this, &Designer::exit), 0));
- wnd->signal_key_press.connect(sigc::mem_fun(this, &Designer::key_press));
- wnd->signal_key_release.connect(sigc::mem_fun(this, &Designer::key_release));
- wnd->signal_button_press.connect(sigc::mem_fun(this, &Designer::button_press));
- wnd->signal_pointer_motion.connect(sigc::mem_fun(this, &Designer::pointer_motion));
-
wnd->show();
glEnableClientState(GL_VERTEX_ARRAY);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_CULL_FACE);
- GL::Texture2D *font_tex = new GL::Texture2D;
- font_tex->set_min_filter(GL::LINEAR);
- font_tex->load_image("dejavu-20.png");
- font = new GL::Font();
- font->set_texture(*font_tex);
- DataFile::load(*font, "dejavu-20.font");
+ DataFile::load(ui_res, "marklin.res");
+ root = new GLtk::Root(ui_res, *wnd);
+
+ lbl_tooltip = new GLtk::Label(ui_res);
+ lbl_tooltip->set_style("tooltip");
+ root->add(*lbl_tooltip);
+ lbl_tooltip->set_visible(false);
+
+ toolbar = new Toolbar(*this);
+ root->add(*toolbar);
+ toolbar->set_position(0, screen_h-toolbar->get_geometry().h);
+ toolbar->set_visible(true);
+
+
+ wnd->signal_key_press.connect(sigc::mem_fun(this, &Designer::key_press));
+ wnd->signal_key_release.connect(sigc::mem_fun(this, &Designer::key_release));
+ wnd->signal_button_press.connect(sigc::mem_fun(this, &Designer::button_press));
+ wnd->signal_pointer_motion.connect(sigc::mem_fun(this, &Designer::pointer_motion));
mode = SELECT;
Application::main();
- delete font;
- delete font_tex;
- delete input;
+ delete root;
delete glc;
delete wnd;
return exit_code;
}
+void Designer::save()
+{
+ input = new ::Input(*this, "Save layout", filename);
+ input->signal_cancel.connect(sigc::mem_fun(this, &Designer::input_dismiss));
+ input->signal_accept.connect(sigc::mem_fun(this, &Designer::save_accept));
+ mode = INPUT;
+}
+
+void Designer::quit()
+{
+ exit(0);
+}
+
+void Designer::edit_route(Route &r)
+{
+ cur_route = &r;
+}
+
+void Designer::add_selection_to_route()
+{
+ if(!cur_route)
+ return;
+
+ try
+ {
+ const set<Track *> &stracks = selection->get_tracks();
+ set<const Track *> tracks(stracks.begin(), stracks.end());
+ cur_route->add_tracks(tracks);
+ }
+ catch(const Exception &e)
+ {
+ IO::print("%s\n", e.what());
+ }
+}
+
void Designer::map_pointer_coords(int x, int y, float &gx, float &gy)
{
float cos_pitch = cos(cam_pitch);
ss<<" (turnout "<<track.get_turnout_id()<<')';
else if(track.get_sensor_id())
ss<<" (sensor "<<track.get_sensor_id()<<')';
- tooltip = ss.str();
- move_tooltip(pointer_x, pointer_y);
+ set_tooltip(pointer_x, pointer_y, ss.str());
}
else
- tooltip.clear();
+ clear_tooltip();
tooltip_timeout = Msp::Time::TimeStamp();
}
glc->swap_buffers();
}
-/*** private ***/
-
-void Designer::key_press(unsigned code, unsigned mod, wchar_t ch)
+void Designer::key_press(unsigned code, unsigned mod, wchar_t)
{
unsigned key = Msp::Input::key_from_sys(code);
if(mode==INPUT)
- {
- input->key_press(key, mod, ch);
return;
- }
if(key==Msp::Input::KEY_SHIFT_L || key==Msp::Input::KEY_SHIFT_R)
shift = true;
mode = MANIPULATE;
}
else if(key==Msp::Input::KEY_W)
- {
- input = new ::Input(*this, "Filename");
- input->signal_cancel.connect(sigc::mem_fun(this, &Designer::input_dismiss));
- input->signal_accept.connect(sigc::mem_fun(this, &Designer::save_accept));
- mode = INPUT;
- }
+ save();
else if(key==Msp::Input::KEY_PLUS)
selection->select_more();
else if(key==Msp::Input::KEY_L && (mod&1))
if(*j!=*i)
(*i)->snap_to(**j, true);
- Track3D &t3d = layout_3d->get_track(**i);
- if((*i)->get_flex())
- t3d.set_color(GL::Color(1, 0.5, 1));
- else
- t3d.set_color(GL::Color(1, 1, 1));
+ update_track_color(layout_3d->get_track(**i));
}
}
else if(key==Msp::Input::KEY_F)
mode = INPUT;
}
}
+ else if(key==Msp::Input::KEY_A)
+ add_selection_to_route();
else if(key==Msp::Input::KEY_RIGHT)
rotate = -1;
else if(key==Msp::Input::KEY_LEFT)
{
y = screen_h-y-1;
- float gx, gy;
- map_pointer_coords(x, y, gx, gy);
+ pointer_x = x;
+ pointer_y = y;
if(mode==SELECT || mode==CATALOGUE)
- {
- pointer_x = x;
- pointer_y = y;
tooltip_timeout = Msp::Time::now()+100*Msp::Time::msec;
- }
+
+ clear_tooltip();
if(mode!=INPUT)
{
+ float gx, gy;
+ map_pointer_coords(x, y, gx, gy);
manipulator->pointer_motion(x, y, gx, gy);
measure->pointer_motion(x, y, gx, gy);
}
-
- if(mode==MEASURE || mode==MANIPULATE)
- move_tooltip(x, y);
}
void Designer::project_3d()
void Designer::render()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glEnable(GL_DEPTH_TEST);
+ GL::enable(GL::DEPTH_TEST);
project_3d();
apply_camera();
base_mesh->draw();
}
layout_3d->render(true);
+ if(cur_route)
+ {
+ glColor4f(0.5, 0.8, 1.0, 1.0);
+ const set<const Track *> &rtracks = cur_route->get_tracks();
+ const map<unsigned, int> &turnouts = cur_route->get_turnouts();
+ for(set<const Track *>::const_iterator i=rtracks.begin(); i!=rtracks.end(); ++i)
+ {
+ unsigned route = 0;
+ if(unsigned tid=(*i)->get_turnout_id())
+ {
+ map<unsigned, int>::const_iterator j = turnouts.find(tid);
+ if(j!=turnouts.end())
+ route = j->second;
+ }
+ layout_3d->get_track(**i).render_route(route);
+ }
+ }
manipulator->render();
if(mode==MEASURE)
measure->render();
}
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, screen_w, 0, screen_h, 0, 1);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
+ GL::matrix_mode(GL::PROJECTION);
+ GL::load_identity();
+ GL::ortho_bottomleft(screen_w, screen_h);
+ GL::matrix_mode(GL::MODELVIEW);
+ GL::load_identity();
- glDisable(GL_DEPTH_TEST);
+ GL::disable(GL::DEPTH_TEST);
- if(!tooltip.empty())
- {
- glTranslatef(tooltip_x, tooltip_y, 0);
- glScalef(20, 20, 20);
- float width = font->get_string_width(tooltip);
- glColor4f(0, 0, 0, 0.5);
- glBegin(GL_QUADS);
- glVertex2f(0, 0);
- glVertex2f(width, 0);
- glVertex2f(width, 1);
- glVertex2f(0, 1);
- glEnd();
- glColor4f(1, 1, 1, 1);
- font->draw_string(tooltip);
- }
-
- if(mode==INPUT)
- input->render();
+ root->render();
}
Track3D *Designer::pick_track(int x, int y)
return l->pick_track(xx, yy, size);
}
+void Designer::update_track_color(Track3D &track)
+{
+ if(track.get_track().get_sensor_id())
+ {
+ if(track.get_track().get_flex())
+ track.set_color(GL::Color(1, 0.6, 1));
+ else
+ track.set_color(GL::Color(0.7, 0.7, 1));
+ }
+ else if(track.get_track().get_turnout_id())
+ track.set_color(GL::Color(0.8, 1, 0.8));
+ else if(track.get_track().get_flex())
+ track.set_color(GL::Color(1, 0.8, 0.8));
+ else
+ track.set_color(GL::Color(1, 1, 1));
+}
+
void Designer::manipulation_status(const string &status)
{
- tooltip = status;
+ set_tooltip(pointer_x, pointer_y, status);
}
void Designer::manipulation_done(bool)
ostringstream ss;
ss.precision(3);
ss<<"Par "<<pard<<"mm - Perp "<<perpd<<"mm - Total "<<d<<"mm - Angle "<<adiff<<"°";
- tooltip = ss.str();
+ set_tooltip(pointer_x, pointer_y, ss.str());
}
void Designer::measure_done()
mode = SELECT;
}
-void Designer::move_tooltip(int x, int y)
+void Designer::set_tooltip(int x, int y, const std::string &text)
+{
+ int fontsize = ui_res.get_default_font().get_default_size();
+ int h = fontsize+6;
+ int w = static_cast<int>(ui_res.get_default_font().get_string_width(text)*fontsize)+6;
+ x = max(min(static_cast<int>(screen_w)-w, x), 0);
+ y = max(min(static_cast<int>(screen_h)-h, y), 0);
+ lbl_tooltip->set_text(text);
+ lbl_tooltip->set_geometry(GLtk::Geometry(x, y, w, h));
+ lbl_tooltip->set_visible(true);
+}
+
+void Designer::clear_tooltip()
{
- int w = static_cast<int>(font->get_string_width(tooltip)*20);
- tooltip_x = max(min(static_cast<int>(screen_w)-w, x), 0);
- tooltip_y = max(min(static_cast<int>(screen_h)-20, y), 0);
+ lbl_tooltip->set_visible(false);
}
void Designer::save_accept()
unsigned id = lexical_cast<unsigned>(input->get_text());
track->set_turnout_id(id);
- Track3D &t3d = layout_3d->get_track(*track);
- if(id)
- t3d.set_color(GL::Color(0.5, 1, 1));
- else
- t3d.set_color(GL::Color(1, 1, 1));
+ update_track_color(layout_3d->get_track(*track));
input_dismiss();
}
{
(*i)->set_sensor_id(id);
- Track3D &t3d = layout_3d->get_track(**i);
- if(id)
- t3d.set_color(GL::Color(1, 1, 0.5));
- else
- t3d.set_color(GL::Color(1, 1, 1));
+ update_track_color(layout_3d->get_track(**i));
}
input_dismiss();
#include <msp/gbase/glcontext.h>
#include <msp/gl/font.h>
#include <msp/gl/mesh.h>
+#include <msp/gltk/label.h>
+#include <msp/gltk/resources.h>
+#include <msp/gltk/root.h>
#include <msp/time/timestamp.h>
#include "libmarklin/catalogue.h"
#include "libmarklin/layout.h"
class Manipulator;
class Measure;
class Selection;
+class Toolbar;
class Designer: public Msp::Application
{
Msp::Graphics::GLContext *glc;
unsigned screen_w;
unsigned screen_h;
- Msp::GL::Font *font;
+ Msp::GLtk::Resources ui_res;
+ Msp::GLtk::Root *root;
+
+ Toolbar *toolbar;
+ Msp::GLtk::Label *lbl_tooltip;
+ Msp::Time::TimeStamp tooltip_timeout;
Marklin::Catalogue catalogue;
- Marklin::Layout *layout;
- Marklin::Layout3D *layout_3d;
Marklin::Layout *cat_layout;
Marklin::Layout3D *cat_layout_3d;
+ std::string filename;
+ Marklin::Layout *layout;
+ Marklin::Layout3D *layout_3d;
Msp::GL::Mesh *base_mesh;
+ Marklin::Route *cur_route;
Mode mode;
Selection *selection;
int pointer_x;
int pointer_y;
- int tooltip_x;
- int tooltip_y;
- std::string tooltip;
- Msp::Time::TimeStamp tooltip_timeout;
-
Msp::Time::TimeStamp last_tick;
static Msp::Application::RegApp<Designer> reg;
Designer(int, char **);
~Designer();
+ int main();
+ void save();
+ void quit();
+
Marklin::Layout *get_layout() { return layout; }
Marklin::Layout3D *get_layout_3d() { return layout_3d; }
- Msp::GL::Font &get_font() { return *font; }
- int main();
+ const Msp::GLtk::Resources &get_ui_resources() const { return ui_res; }
+ Msp::GLtk::Root &get_root() const { return *root; }
+ void edit_route(Marklin::Route &);
+ Marklin::Route *get_current_route() const { return cur_route; }
+ void add_selection_to_route();
+
void map_pointer_coords(int, int, float &, float &);
private:
void tick();
void apply_camera();
void render();
Marklin::Track3D *pick_track(int, int);
+ void update_track_color(Marklin::Track3D &);
void manipulation_status(const std::string &);
void manipulation_done(bool);
void measure_changed();
void measure_done();
- void move_tooltip(int, int);
+ void set_tooltip(int, int, const std::string &);
+ void clear_tooltip();
void save_accept();
void turnout_id_accept();
void sensor_id_accept();
#include <GL/gl.h>
#include <msp/gl/texture.h>
+#include <msp/gltk/button.h>
#include <msp/input/keys.h>
#include "designer.h"
#include "input.h"
using namespace std;
using namespace Msp;
-::Input::Input(Designer &d, const string &t, const string &e):
- designer(d),
- title(t),
- text(e),
- pos(text.size())
-{ }
-
-void ::Input::key_press(unsigned key, unsigned, wchar_t ch)
+::Input::Input(Designer &d, const string &title, const string &text):
+ Panel(d.get_ui_resources()),
+ designer(d)
{
- if(key==Msp::Input::KEY_ENTER)
- signal_accept.emit();
- else if(key==Msp::Input::KEY_ESC)
- signal_cancel.emit();
- else if(key==Msp::Input::KEY_BACKSPACE)
- {
- if(pos>0)
- {
- text.erase(pos-1, 1);
- --pos;
- }
- }
- else if(key==Msp::Input::KEY_DELETE)
- {
- if(pos<text.size())
- text.erase(pos, 1);
- }
- else if(key==Msp::Input::KEY_LEFT)
- {
- if(pos>0)
- --pos;
- }
- else if(key==Msp::Input::KEY_RIGHT)
- {
- if(pos<text.size())
- ++pos;
- }
- else if(ch>=0x20)
- {
- text.insert(pos, 1, ch);
- ++pos;
- }
-}
+ set_size(300, 100);
-void ::Input::render()
-{
- glLoadIdentity();
- glTranslatef(300, 450, 0);
+ GLtk::Label *lbl;
+ add(*(lbl=new GLtk::Label(res, title)));
+ lbl->set_geometry(GLtk::Geometry(10, geom.h-30, geom.w-20, 20));
- GL::Texture::unbind();
- glColor4f(0.7, 0.7, 0.7, 0.9);
- glBegin(GL_QUADS);
- glVertex2f(0, 0);
- glVertex2f(680, 0);
- glVertex2f(680, 60);
- glVertex2f(0, 60);
- glEnd();
+ add(*(entry=new GLtk::Entry(res, text)));
+ entry->set_geometry(GLtk::Geometry(10, geom.h-60, geom.w-20, 20));
- glColor4f(0, 0, 0, 1);
- glTranslatef(5, 35, 0);
+ GLtk::Button *btn;
- glPushMatrix();
- glScalef(20, 20, 20);
- designer.get_font().draw_string(title);
- glPopMatrix();
+ add(*(btn=new GLtk::Button(res, "Cncl")));
+ btn->set_geometry(GLtk::Geometry(geom.w-90, 10, 40, 24));
+ btn->set_style("red");
+ btn->signal_clicked.connect(signal_cancel);
- glTranslatef(0, -30, 0);
- glPushMatrix();
- glScalef(20, 20, 20);
- designer.get_font().draw_string(text);
+ add(*(btn=new GLtk::Button(res, "OK")));
+ btn->set_geometry(GLtk::Geometry(geom.w-50, 10, 40, 24));
+ btn->set_style("green");
+ btn->signal_clicked.connect(signal_accept);
+
+ designer.get_root().add(*this);
+ const GLtk::Geometry &rgeom=designer.get_root().get_geometry();
+ set_position((rgeom.w-geom.w)/2, (rgeom.h-geom.h)/2);
+ entry->set_focus();
+}
- glTranslatef(designer.get_font().get_string_width(text.substr(0, pos)), 0, 0);
- glDisable(GL_TEXTURE_2D);
- glBegin(GL_LINES);
- glVertex2f(0, 0);
- glVertex2f(0, 1);
- glEnd();
- glPopMatrix();
+const string &::Input::get_text() const
+{
+ return entry->get_text();
+}
+
+void ::Input::key_press(unsigned key, unsigned mod, wchar_t ch)
+{
+ if(key==Msp::Input::KEY_ENTER)
+ signal_accept.emit();
+ else if(key==Msp::Input::KEY_ESC)
+ signal_cancel.emit();
+ else
+ Panel::key_press(key, mod, ch);
}
#include <string>
#include <sigc++/sigc++.h>
+#include <msp/gltk/entry.h>
class Designer;
-class Input
+class Input: public Msp::GLtk::Panel
{
public:
sigc::signal<void> signal_accept;
private:
Designer &designer;
- std::string title;
- std::string text;
- unsigned pos;
+ Msp::GLtk::Entry *entry;
public:
Input(Designer &, const std::string &, const std::string & =std::string());
- const std::string &get_text() { return text; }
- void key_press(unsigned, unsigned, wchar_t);
- void render();
+ const std::string &get_text() const;
+private:
+ virtual void key_press(unsigned, unsigned, wchar_t);
};
#endif
--- /dev/null
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2009 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#include <msp/gltk/button.h>
+#include <msp/strings/formatter.h>
+#include "designer.h"
+#include "toolbar.h"
+
+using namespace std;
+using namespace Msp;
+using namespace Marklin;
+
+Toolbar::Toolbar(Designer &d):
+ GLtk::Panel(d.get_ui_resources()),
+ designer(d)
+{
+ set_size(370, 40);
+
+ GLtk::Button *btn;
+ GLtk::Label *lbl;
+
+ add(*(btn=new GLtk::Button(res, "Load")));
+ btn->set_geometry(GLtk::Geometry(5, 10, 40, 24));
+
+ add(*(btn=new GLtk::Button(res, "Save")));
+ btn->set_geometry(GLtk::Geometry(45, 10, 40, 24));
+ btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::save));
+
+ add(*(btn=new GLtk::Button(res, "Quit")));
+ btn->set_geometry(GLtk::Geometry(85, 10, 40, 24));
+ btn->set_style("red");
+ btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::quit));
+
+ add(*(btn=new GLtk::Button(res, "Trnt")));
+ btn->set_geometry(GLtk::Geometry(135, 10, 40, 24));
+
+ add(*(btn=new GLtk::Button(res, "Sens")));
+ btn->set_geometry(GLtk::Geometry(175, 10, 40, 24));
+
+ add(*(lbl=new GLtk::Label(res, "Routes:")));
+ lbl->set_geometry(GLtk::Geometry(225, 22, 40, 13));
+
+ add(*(drp_routes=new GLtk::Dropdown(res)));
+ drp_routes->set_geometry(GLtk::Geometry(225, 5, 100, 17));
+ drp_routes->append("(new route)");
+ drp_routes->signal_item_selected.connect(sigc::mem_fun(this, &Toolbar::route_selected));
+
+ add(*(btn=new GLtk::Button(res, "AddT")));
+ btn->set_geometry(GLtk::Geometry(325, 10, 40, 24));
+ btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::add_selection_to_route));
+
+ designer.get_layout()->signal_route_added.connect(sigc::hide(sigc::mem_fun(this, &Toolbar::update_routes)));
+ designer.get_layout()->signal_route_removed.connect(sigc::hide(sigc::mem_fun(this, &Toolbar::update_routes)));
+ update_routes();
+}
+
+void Toolbar::route_selected(unsigned index, const string &)
+{
+ if(index==drp_routes->get_n_items()-1)
+ {
+ Route *route = new Route(format("Route %d", designer.get_layout()->get_routes().size()+1));
+ designer.get_layout()->add_route(*route);
+ designer.edit_route(*route);
+
+ const set<Route *> &routes = designer.get_layout()->get_routes();
+ int selected = -1;
+ unsigned n = 0;
+ for(set<Route *>::const_iterator i=routes.begin(); (selected<0 && i!=routes.end()); ++i, ++n)
+ if(*i==route)
+ selected = n;
+ drp_routes->set_selected_index(selected);
+ }
+ else
+ {
+ const set<Route *> &routes = designer.get_layout()->get_routes();
+ set<Route *>::const_iterator i = routes.begin();
+ advance(i, index);
+ designer.edit_route(**i);
+ }
+}
+
+void Toolbar::update_routes()
+{
+ drp_routes->clear();
+ const set<Route *> &routes = designer.get_layout()->get_routes();
+ int selected = -1;
+ unsigned n = 0;
+ for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i, ++n)
+ {
+ drp_routes->append((*i)->get_name());
+ if(*i==designer.get_current_route())
+ selected = n;
+ }
+ drp_routes->append("(new route)");
+ drp_routes->set_selected_index(selected);
+}
--- /dev/null
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2009 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#ifndef TOOLBAR_H_
+#define TOOLBAR_H_
+
+#include <msp/gltk/dropdown.h>
+#include <msp/gltk/panel.h>
+
+class Designer;
+
+class Toolbar: public Msp::GLtk::Panel
+{
+private:
+ Designer &designer;
+ Msp::GLtk::Dropdown *drp_routes;
+
+public:
+ Toolbar(Designer &);
+private:
+ void route_selected(unsigned, const std::string &);
+ void update_routes();
+};
+
+#endif
void Layout::remove_track(Track &t)
{
- if(tracks.count(&t))
- {
- tracks.erase(&t);
+ if(tracks.erase(&t))
signal_track_removed.emit(t);
+}
+
+void Layout::add_route(Route &r)
+{
+ if(routes.insert(&r).second)
+ signal_route_added.emit(r);
+}
+
+void Layout::remove_route(Route &r)
+{
+ if(routes.erase(&r))
+ signal_route_removed.emit(r);
+}
+
+void Layout::save(const string &fn)
+{
+ IO::BufferedFile out(fn, IO::M_WRITE);
+ DataFile::Writer writer(out);
+
+ if(!base.empty())
+ writer.write((DataFile::Statement("base"), base));
+
+ for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+ {
+ DataFile::Statement st("track");
+ st.append((*i)->get_type().get_article_number());
+ (*i)->save(st.sub);
+ writer.write(st);
+ }
+
+ for(set<Route *>::iterator i=routes.begin(); i!=routes.end(); ++i)
+ {
+ DataFile::Statement st("route");
+ st.append((*i)->get_name());
+ (*i)->save(st.sub);
+ writer.write(st);
}
}
for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
(*i)->break_links();
- set<Track *> flext;
+ list<Track *> flext;
for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
{
if((*i)->get_flex())
- flext.insert(*i);
+ flext.push_back(*i);
else
{
for(set<Track *>::iterator j=i; j!=tracks.end(); ++j)
}
}
- for(set<Track *>::iterator i=flext.begin(); i!=flext.end(); ++i)
+ for(list<Track *>::iterator i=flext.begin(); i!=flext.end(); ++i)
for(set<Track *>::iterator j=tracks.begin(); j!=tracks.end(); ++j)
- if(j!=i)
+ if(*j!=*i)
(*i)->snap_to(**j, true);
}
-void Layout::save(const string &fn)
+void Layout::check_routes()
{
- IO::BufferedFile out(fn, IO::M_WRITE);
- DataFile::Writer writer(out);
- if(!base.empty())
- writer.write((DataFile::Statement("base"), base));
- for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+ for(set<Route *>::iterator i=routes.begin(); i!=routes.end(); ++i)
{
- DataFile::Statement st("track");
- st.append((*i)->get_type().get_article_number());
- (*i)->save(st.sub);
- writer.write(st);
+ // We must copy the turnout map, since adding tracks to the route will (temporarily) mess it up
+ const map<unsigned, int> turnouts = (*i)->get_turnouts();
+
+ Track *track = 0;
+ unsigned trk_route = 0;
+ for(set<Track *>::const_iterator j=tracks.begin(); j!=tracks.end(); ++j)
+ {
+ map<unsigned, int>::const_iterator k = turnouts.find((*j)->get_turnout_id());
+ if(k!=turnouts.end())
+ {
+ track = *j;
+ trk_route = k->second;
+ break;
+ }
+ }
+
+ (*i)->add_track(*track);
+
+ const vector<Endpoint> &eps = track->get_type().get_endpoints();
+ unsigned ep = 0;
+ for(unsigned j=0; j<eps.size(); ++i)
+ if(eps[j].routes&(1<<trk_route))
+ {
+ ep = j;
+ break;
+ }
+
+ Track *start = track;
+ while(1)
+ {
+ int out_ep = track->traverse(ep, trk_route);
+ if(out_ep<0)
+ break;
+ Track *next = track->get_links()[out_ep];
+ if(!next || next == start)
+ break;
+ ep = next->get_endpoint_by_link(*track);
+ if(next->get_type().get_n_routes()>1)
+ {
+ map<unsigned, int>::const_iterator j = turnouts.find(next->get_turnout_id());
+ if(j==turnouts.end())
+ break;
+ trk_route = j->second;
+ }
+ else
+ trk_route = 0;
+ (*i)->add_track(*next);
+ track = next;
+ }
}
}
DataFile::BasicLoader<Layout>(l)
{
add("base", &Layout::base);
+ add("route", &Loader::route);
add("track", &Loader::track);
}
void Layout::Loader::finish()
{
obj.check_links();
+ obj.check_routes();
for(set<Track *>::iterator i=obj.tracks.begin(); i!=obj.tracks.end(); ++i)
(*i)->check_slope();
}
+void Layout::Loader::route(const string &n)
+{
+ RefPtr<Route> rte = new Route(n);
+ load_sub(*rte);
+ obj.add_route(*rte.release());
+}
+
void Layout::Loader::track(unsigned art_nr)
{
TrackType &type = obj.catalogue.get_track(art_nr);
Loader(Layout &);
private:
virtual void finish();
+ void route(const std::string &);
void track(unsigned);
};
public:
sigc::signal<void, Track &> signal_track_added;
sigc::signal<void, Track &> signal_track_removed;
+ sigc::signal<void, Route &> signal_route_added;
+ sigc::signal<void, Route &> signal_route_removed;
private:
const Catalogue &catalogue;
std::string base;
std::set<Track *> tracks;
- //std::set<Route *> routes;
+ std::set<Route *> routes;
public:
Layout(const Catalogue &);
const std::set<Track *> &get_tracks() const { return tracks; }
void add_track(Track &);
void remove_track(Track &);
- void check_links();
+ void add_route(Route &);
+ const std::set<Route *> &get_routes() const { return routes; }
+ void remove_route(Route &);
void save(const std::string &);
+private:
+ void check_links();
+ void check_routes();
};
} // namespace Marklin
/* $Id$
This file is part of the MSP Märklin suite
-Copyright © 2006-2008 Mikkosoft Productions, Mikko Rasa
+Copyright © 2007-2009 Mikkosoft Productions, Mikko Rasa
Distributed under the GPL
*/
+#include "track.h"
+#include "tracktype.h"
#include "route.h"
+using namespace std;
+using namespace Msp;
+
namespace Marklin {
+Route::Route(const string &n):
+ name(n)
+{ }
+
+int Route::get_turnout(unsigned id) const
+{
+ map<unsigned, int>::const_iterator i = turnouts.find(id);
+ if(i!=turnouts.end())
+ return i->second;
+ return -1;
+}
+
+void Route::add_track(const Track &trk)
+{
+ if(tracks.count(&trk))
+ return;
+
+ if(!tracks.empty())
+ {
+ unsigned valid = check_validity(trk);
+ if(!(valid&1))
+ throw Exception("Not linked to existing tracks");
+ else if(!(valid&2))
+ throw Exception("Branching routes not allowed");
+ else if(!(valid&4))
+ throw Exception("Route must be smooth");
+ }
+
+ tracks.insert(&trk);
+ update_turnouts();
+}
+
+void Route::add_tracks(const set<const Track *> &trks)
+{
+ set<const Track *> pending;
+ for(set<const Track *>::const_iterator i=trks.begin(); i!=trks.end(); ++i)
+ if(!tracks.count(*i))
+ pending.insert(*i);
+
+ while(!pending.empty())
+ {
+ bool found = false;
+ for(set<const Track *>::const_iterator i=pending.begin(); i!=pending.end(); ++i)
+ if(tracks.empty() || check_validity(**i)==7)
+ {
+ tracks.insert(*i);
+ pending.erase(*i);
+ found = true;
+ break;
+ }
+
+ if(!found)
+ throw Exception("Could not add all tracks to route");
+ }
+
+ update_turnouts();
+}
+
+void Route::save(list<DataFile::Statement> &st) const
+{
+ for(map<unsigned, int>::const_iterator i=turnouts.begin(); i!=turnouts.end(); ++i)
+ st.push_back((DataFile::Statement("turnout"), i->first, i->second));
+}
+
+void Route::update_turnouts()
+{
+ set<unsigned> found;
+ for(set<const Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
+ if(unsigned tid=(*i)->get_turnout_id())
+ {
+ found.insert(tid);
+
+ const vector<Endpoint> &endpoints = (*i)->get_type().get_endpoints();
+ const vector<Track *> &links = (*i)->get_links();
+
+ unsigned mask = 15;
+ for(unsigned j=0; j<endpoints.size(); ++j)
+ {
+ if(!tracks.count(links[j]))
+ continue;
+ if(unsigned tid2=links[j]->get_turnout_id())
+ {
+ const Endpoint &ep = links[j]->get_type().get_endpoints()[links[j]->get_endpoint_by_link(**i)];
+ int r = get_turnout(tid2);
+ if(r>=0 && !(ep.routes&(1<<r)))
+ {
+ mask &= ~endpoints[j].routes;
+ continue;
+ }
+ }
+ mask &= endpoints[j].routes;
+ }
+
+ if(!(mask&(mask-1)))
+ {
+ unsigned route = 0;
+ for(; (mask && !(mask&1)); mask>>=1, ++route) ;
+ turnouts[tid] = route;
+ }
+ else
+ turnouts[tid] = -1;
+ }
+
+ for(map<unsigned, int>::iterator i=turnouts.begin(); i!=turnouts.end();)
+ {
+ if(!found.count(i->first))
+ turnouts.erase(i++);
+ else
+ ++i;
+ }
+}
+
+unsigned Route::check_validity(const Track &trk) const
+{
+ unsigned result = 4;
+ for(set<const Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
+ {
+ int epi=(*i)->get_endpoint_by_link(trk);
+ if(epi>=0)
+ {
+ result |= 1;
+ const vector<Endpoint> &endpoints = (*i)->get_type().get_endpoints();
+ if(unsigned tid=(*i)->get_turnout_id())
+ {
+ int r = get_turnout(tid);
+ if(r>=0)
+ {
+ if(endpoints[epi].routes&(1<<r))
+ result |= 2;
+ }
+ else
+ {
+ unsigned count = 0;
+ const vector<Track *> &links = (*i)->get_links();
+ int epj = -1;
+ for(unsigned k=0; k<endpoints.size(); ++k)
+ if(tracks.count(links[k]))
+ {
+ ++count;
+ epj = k;
+ }
+ if(count<=1)
+ {
+ result |= 2;
+ if(epj>=0 && !(endpoints[epi].routes&endpoints[epj].routes))
+ result &= 3;
+ }
+ }
+ }
+ else
+ result |= 2;
+ }
+ }
+
+ return result;
+}
+
+
+Route::Loader::Loader(Route &r):
+ DataFile::BasicLoader<Route>(r)
+{
+ add("turnout", &Loader::turnout);
+}
+void Route::Loader::turnout(unsigned id, unsigned route)
+{
+ obj.turnouts[id] = route;
+}
} // namespace Marklin
/* $Id$
This file is part of the MSP Märklin suite
-Copyright © 2007-2008 Mikkosoft Productions, Mikko Rasa
+Copyright © 2007-2009 Mikkosoft Productions, Mikko Rasa
Distributed under the GPL
*/
#include <map>
#include <set>
#include <string>
+#include <msp/datafile/loader.h>
namespace Marklin {
class Route
{
+public:
+ class Loader: public Msp::DataFile::BasicLoader<Route>
+ {
+ public:
+ Loader(Route &);
+ private:
+ void turnout(unsigned, unsigned);
+ };
+
private:
std::string name;
- std::set<Track *> tracks;
- std::map<unsigned, Turnout *> turnouts;
+ std::set<const Track *> tracks;
+ std::map<unsigned, int> turnouts;
public:
- Route();
- ~Route();
-
- const std::map<unsigned, Turnout *> &get_turnouts() const { return turnouts; }
- void add_track(Track *);
+ Route(const std::string &);
+
+ const std::string &get_name() const { return name; }
+ int get_turnout(unsigned) const;
+ const std::map<unsigned, int> &get_turnouts() const { return turnouts; }
+ void add_track(const Track &);
+ void add_tracks(const std::set<const Track *> &);
+ const std::set<const Track *> &get_tracks() const { return tracks; }
+ void save(std::list<Msp::DataFile::Statement> &) const;
+private:
+ void update_turnouts();
+ unsigned check_validity(const Track &) const;
};
} // namespace Marklin