remove README.Protocol and add a README that refers to the "real"
[fg:toms-fgdata.git] / Nasal / material.nas
1 # material dialog
2 # ===============
3 #
4 # Usage:  material.showDialog(<path>, [<title>], [<x>], [<y>]);
5 #
6 # the path should point to a property "directory" (usually set in
7 # the aircraft's *-set.xml file) that contains any of
8 # (shininess|transparency|texture) and (diffuse|ambient|specular|emission),
9 # whereby the latter four are directories containing any of
10 # (red|green|blue|factor|offset).
11 #
12 # If <title> is omitted or nil, then the last path component is used as title.
13 # If <x> and <y> are undefined, then the dialog is centered.
14 #
15 #
16 # Example:
17 #   <foo>
18 #       <diffuse>
19 #           <red>1.0</red>
20 #           <green>0.5</green>
21 #           <blue>0.5</blue>
22 #       </diffuse>
23 #       <transparency>0.5</transparency>
24 #       <texture>bar.rgb</texture>
25 #   </foo>
26 #
27 #
28 #   material.showDialog("/sim/model/foo/", "FOO");
29 #
30 #
31 #
32 # Of course, these properties are only used if a "material" animation
33 # references them via <*-prop> definition.
34 #
35 # Example:
36 #
37 #  <animation>
38 #      <type>material</type>
39 #      <object-name>foo</object-name>
40 #      <property-base>/sim/model/foo</property-base>
41 #      <diffuse>
42 #          <red-prop>diffuse/red</red-prop>
43 #          <green-prop>diffuse/green</green-prop>
44 #          <blue-prop>diffuse/blue</blue-prop>
45 #      </diffuse>
46 #      <transparency-prop>transparency</transparency-prop>
47 #      <texture-prop>texture</texture-prop>
48 #  </animation>
49 #
50
51 dialog = nil;
52
53 colorgroup = func {
54         parent = arg[0];  # pui parent
55         name = arg[1];    # "diffuse"
56         base = arg[2];
57         undef = func { props.globals.getNode(base ~ name ~ "/" ~ arg[0]) == nil };
58
59         if (undef("red") and undef("green") and undef("blue")) {
60                 return 0;
61         }
62
63         if (arg[3] != nil) {
64                 parent.addChild("hrule").setColor(1, 1, 1, 0.5);
65         }
66
67         grp = parent.addChild("group");
68         grp.set("layout", "vbox");
69         grp.addChild("text").set("label", name);
70
71         foreach (color; ["red", "green", "blue", "factor"]) {
72                 mat(parent, color, base ~ name ~ "/" ~ color, "%.3f");
73         }
74         mat(parent, "offset", base ~ name ~ "/" ~ "offset", "%.3f", -1.0, 1.0);
75         return 1;
76 }
77
78
79 mat = func {
80         parent = arg[0];
81         name = arg[1];
82         path = arg[2];
83         format = arg[3];
84         if (props.globals.getNode(path) != nil) {
85                 grp = parent.addChild("group");
86                 grp.set("layout", "hbox");
87
88                 grp.addChild("empty").set("stretch", 1);
89                 grp.addChild("text").set("label", name);
90
91                 slider = grp.addChild("slider");
92                 slider.set("property", path);
93                 slider.set("live", 1);
94                 if (size(arg) == 6) {
95                         slider.set("min", arg[4]);
96                         slider.set("max", arg[5]);
97                 }
98                 slider.setBinding("dialog-apply");
99
100                 number = grp.addChild("text");
101                 number.set("label", "-0.123");
102                 number.set("format", format);
103                 number.set("property", path);
104                 number.set("live", 1);
105                 number.setColor(1, 0, 0);
106         }
107 }
108
109
110 showDialog = func {
111         base = arg[0];
112         while (size(base) and substr(base, size(base) - 1, 1) == "/") {
113                 base = substr(base, 0, size(base) - 1);
114         }
115         parentdir = "";
116         b = base;
117         while (size(b)) {
118                 c = substr(b, size(b) - 1, 1);
119                 if (c == "/") { break }
120                 b = substr(b, 0, size(b) - 1);
121                 parentdir = c ~ parentdir;
122         }
123
124         title = if (size(arg) > 1 and arg[1] != nil) { arg[1] } else { parentdir };
125         name = "material-" ~ parentdir;
126         base = base ~ "/";
127
128         dialog = gui.Widget.new();
129         dialog.set("name", name);
130         if (size(arg) > 2 and arg[2] != nil) { dialog.set("x", arg[2]) }
131         if (size(arg) > 3 and arg[3] != nil) { dialog.set("y", arg[3]) }
132         dialog.set("layout", "vbox");
133
134         titlebar = dialog.addChild("group");
135         titlebar.set("layout", "hbox");
136         w = titlebar.addChild("text");
137         w.set("label", "object \"" ~ title ~ "\"");
138         titlebar.addChild("empty").set("stretch", 1);
139
140         w = titlebar.addChild("button");
141         w.set("pref-width", 16);
142         w.set("pref-height", 16);
143         w.set("legend", "");
144         w.set("default", 1);
145         w.set("keynum", 27);
146         w.set("border", 1);
147         w.setBinding("dialog-close");
148
149         h = 0;
150         h += colorgroup(dialog, "diffuse", base, h);
151         h += colorgroup(dialog, "ambient", base, h);
152         h += colorgroup(dialog, "emission", base, h);
153         h += colorgroup(dialog, "specular", base, h);
154
155         undef = func { props.globals.getNode(base ~ arg[0]) == nil };
156         if (!(undef("shininess") and undef("transparency/alpha") and undef("threshold"))) {
157                 if (h) {
158                         dialog.addChild("hrule").setColor(1, 1, 1, 0.5);
159                 }
160
161                 w = dialog.addChild("group");
162                 w.set("layout", "hbox");
163                 w.addChild("text").set("label", "misc");
164
165                 mat(dialog, "shi", base ~ "shininess", "%.0f", 0.0, 128.0);
166                 mat(dialog, "alpha", base ~ "transparency/alpha", "%.3f");
167                 mat(dialog, "thresh", base ~ "threshold", "%.3f");
168                 h += 1;
169         }
170
171         if (!undef("texture")) {
172                 if (h) {
173                         dialog.addChild("hrule").setColor(1, 1, 1, 0.5);
174                 }
175
176                 w = dialog.addChild("group");
177                 w.set("layout", "hbox");
178                 w.addChild("text").set("label", "texture");
179
180                 w = dialog.addChild("input");
181                 w.set("live", 1);
182                 w.set("pref-width", 200);
183                 w.set("property", base ~ "texture");
184                 w.setBinding("dialog-apply");
185         }
186         dialog.addChild("empty").set("pref-height", "3");
187
188         dialog.setColor(0.6, 0.6, 0.6, 0.6);
189
190         fgcommand("dialog-new", dialog.prop());
191         gui.showDialog(name);
192 }
193
194