Line data Source code
1 : /* -*- coding: utf-8 -*- */
2 : /* Copyright (C) 2003-2012 by George Williams */
3 : /*
4 : * Redistribution and use in source and binary forms, with or without
5 : * modification, are permitted provided that the following conditions are met:
6 :
7 : * Redistributions of source code must retain the above copyright notice, this
8 : * list of conditions and the following disclaimer.
9 :
10 : * Redistributions in binary form must reproduce the above copyright notice,
11 : * this list of conditions and the following disclaimer in the documentation
12 : * and/or other materials provided with the distribution.
13 :
14 : * The name of the author may not be used to endorse or promote products
15 : * derived from this software without specific prior written permission.
16 :
17 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 : * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 : * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20 : * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 : * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 : * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 : * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 : */
28 : #include "cvundoes.h"
29 : #include "fontforgeui.h"
30 : #include "nonlineartrans.h"
31 : #include "splineutil.h"
32 : #include <utype.h>
33 : #include <ustring.h>
34 :
35 : struct nldlg {
36 : GWindow gw;
37 : int done, ok;
38 : };
39 :
40 0 : static int nld_e_h(GWindow gw, GEvent *event) {
41 0 : if ( event->type==et_close ) {
42 0 : struct nldlg *d = GDrawGetUserData(gw);
43 0 : d->done = true;
44 0 : } else if ( event->type == et_char ) {
45 0 : return( false );
46 0 : } else if ( event->type==et_controlevent && event->u.control.subtype==et_buttonactivate ) {
47 0 : struct nldlg *d = GDrawGetUserData(gw);
48 0 : d->done = true;
49 0 : d->ok = GGadgetGetCid(event->u.control.g);
50 : }
51 0 : return( true );
52 : }
53 :
54 0 : void NonLinearDlg(FontView *fv,CharView *cv) {
55 : static unichar_t *lastx, *lasty;
56 : struct nldlg d;
57 : GRect pos;
58 : GWindowAttrs wattrs;
59 : GGadgetCreateData gcd[8], boxes[4], *hvarray[3][3], *barray[9], *varray[3][2];
60 : GTextInfo label[8];
61 : struct expr_context c;
62 : char *expstr;
63 :
64 0 : memset(&d,'\0',sizeof(d));
65 0 : memset(&c,'\0',sizeof(c));
66 :
67 0 : memset(&wattrs,0,sizeof(wattrs));
68 0 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_restrict|wam_isdlg;
69 0 : wattrs.event_masks = ~(1<<et_charup);
70 0 : wattrs.restrict_input_to_me = 1;
71 0 : wattrs.is_dlg = 1;
72 0 : wattrs.undercursor = 1;
73 0 : wattrs.cursor = ct_pointer;
74 0 : wattrs.utf8_window_title = _("Non Linear Transform");
75 0 : pos.x = pos.y = 0;
76 0 : pos.width = GGadgetScale(GDrawPointsToPixels(NULL,200));
77 0 : pos.height = GDrawPointsToPixels(NULL,97);
78 0 : d.gw = GDrawCreateTopWindow(NULL,&pos,nld_e_h,&d,&wattrs);
79 :
80 0 : memset(gcd,0,sizeof(gcd));
81 0 : memset(boxes,0,sizeof(boxes));
82 0 : memset(label,0,sizeof(label));
83 :
84 : /* GT: an expression describing the transformation applied to the X coordinate */
85 0 : label[0].text = (unichar_t *) _("X Expr:");
86 0 : label[0].text_is_1byte = true;
87 0 : gcd[0].gd.label = &label[0];
88 0 : gcd[0].gd.pos.x = 10; gcd[0].gd.pos.y = 8;
89 0 : gcd[0].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
90 0 : gcd[0].gd.popup_msg = (unichar_t *) _("These expressions may contain the operators +,-,*,/,%,^ (which means raise to the power of here), and ?: It may also contain a few standard functions. Basic terms are real numbers, x and y.\nExamples:\n x^3+2.5*x^2+5\n (x-300)*(y-200)/100\n y+sin(100*x)");
91 0 : gcd[0].creator = GLabelCreate;
92 0 : hvarray[0][0] = &gcd[0];
93 :
94 0 : if ( lastx!=NULL )
95 0 : label[1].text = lastx;
96 : else {
97 0 : label[1].text = (unichar_t *) "x";
98 0 : label[1].text_is_1byte = true;
99 : }
100 0 : gcd[1].gd.label = &label[1];
101 0 : gcd[1].gd.pos.x = 55; gcd[1].gd.pos.y = 5; gcd[1].gd.pos.width = 135;
102 0 : gcd[1].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
103 0 : gcd[1].gd.popup_msg = (unichar_t *) _("These expressions may contain the operators +,-,*,/,%,^ (which means raise to the power of here), and ?: It may also contain a few standard functions. Basic terms are real numbers, x and y.\nExamples:\n x^3+2.5*x^2+5\n (x-300)*(y-200)/100\n y+sin(100*x)");
104 0 : gcd[1].creator = GTextFieldCreate;
105 0 : hvarray[0][1] = &gcd[1]; hvarray[0][2] = NULL;
106 :
107 : /* GT: an expression describing the transformation applied to the Y coordinate */
108 0 : label[2].text = (unichar_t *) _("Y Expr:");
109 0 : label[2].text_is_1byte = true;
110 0 : gcd[2].gd.label = &label[2];
111 0 : gcd[2].gd.pos.x = 10; gcd[2].gd.pos.y = gcd[0].gd.pos.y+26;
112 0 : gcd[2].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
113 0 : gcd[2].gd.popup_msg = (unichar_t *) _("These expressions may contain the operators +,-,*,/,%,^ (which means raise to the power of here), and ?: It may also contain a few standard functions. Basic terms are real numbers, x and y.\nExamples:\n x^3+2.5*x^2+5\n (x-300)*(y-200)/100\n y+sin(100*x)");
114 0 : gcd[2].creator = GLabelCreate;
115 0 : hvarray[1][0] = &gcd[2];
116 :
117 0 : if ( lasty!=NULL )
118 0 : label[3].text = lasty;
119 : else {
120 0 : label[3].text = (unichar_t *) "y";
121 0 : label[3].text_is_1byte = true;
122 : }
123 0 : gcd[3].gd.label = &label[3];
124 0 : gcd[3].gd.pos.x = gcd[1].gd.pos.x; gcd[3].gd.pos.y = gcd[1].gd.pos.y+26;
125 0 : gcd[3].gd.pos.width = gcd[1].gd.pos.width;
126 0 : gcd[3].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
127 0 : gcd[3].gd.popup_msg = (unichar_t *) _("These expressions may contain the operators +,-,*,/,%,^ (which means raise to the power of here), and ?: It may also contain a few standard functions. Basic terms are real numbers, x and y.\nExamples:\n x^3+2.5*x^2+5\n (x-300)*(y-200)/100\n y+sin(100*x)");
128 0 : gcd[3].creator = GTextFieldCreate;
129 0 : hvarray[1][1] = &gcd[3]; hvarray[1][2] = NULL; hvarray[2][0] = NULL;
130 :
131 0 : boxes[2].gd.flags = gg_enabled|gg_visible;
132 0 : boxes[2].gd.u.boxelements = hvarray[0];
133 0 : boxes[2].creator = GHVBoxCreate;
134 0 : varray[0][0] = &boxes[2]; varray[0][1] = NULL;
135 :
136 0 : gcd[4].gd.pos.x = 30-3; gcd[4].gd.pos.y = gcd[3].gd.pos.y+30;
137 0 : gcd[4].gd.pos.width = -1; gcd[4].gd.pos.height = 0;
138 0 : gcd[4].gd.flags = gg_visible | gg_enabled | gg_but_default;
139 0 : label[4].text = (unichar_t *) _("_OK");
140 0 : label[4].text_is_1byte = true;
141 0 : label[4].text_in_resource = true;
142 0 : gcd[4].gd.label = &label[4];
143 0 : gcd[4].gd.cid = true;
144 0 : gcd[4].creator = GButtonCreate;
145 0 : barray[0] = GCD_Glue; barray[1] = &gcd[4]; barray[2] = GCD_Glue;
146 :
147 0 : gcd[5].gd.pos.x = -30; gcd[5].gd.pos.y = gcd[4].gd.pos.y+3;
148 0 : gcd[5].gd.pos.width = -1; gcd[5].gd.pos.height = 0;
149 0 : gcd[5].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
150 0 : label[5].text = (unichar_t *) _("_Cancel");
151 0 : label[5].text_is_1byte = true;
152 0 : label[5].text_in_resource = true;
153 0 : gcd[5].gd.label = &label[5];
154 0 : gcd[5].gd.cid = false;
155 0 : gcd[5].creator = GButtonCreate;
156 0 : barray[3] = GCD_Glue; barray[4] = &gcd[5]; barray[5] = GCD_Glue; barray[6] = NULL;
157 :
158 0 : boxes[3].gd.flags = gg_enabled|gg_visible;
159 0 : boxes[3].gd.u.boxelements = barray;
160 0 : boxes[3].creator = GHBoxCreate;
161 0 : varray[1][0] = &boxes[3]; varray[1][1] = NULL;
162 0 : varray[2][0] = NULL;
163 :
164 0 : boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
165 0 : boxes[0].gd.flags = gg_enabled|gg_visible;
166 0 : boxes[0].gd.u.boxelements = varray[0];
167 0 : boxes[0].creator = GHVGroupCreate;
168 :
169 0 : GGadgetsCreate(d.gw,boxes);
170 0 : GHVBoxSetExpandableCol(boxes[2].ret,1);
171 0 : GHVBoxSetExpandableCol(boxes[3].ret,gb_expandgluesame);
172 0 : GHVBoxFitWindow(boxes[0].ret);
173 0 : GDrawSetVisible(d.gw,true);
174 0 : while ( !d.done ) {
175 0 : GDrawProcessOneEvent(NULL);
176 0 : if ( d.done && d.ok ) {
177 0 : expstr = cu_copy(_GGadgetGetTitle(gcd[1].ret));
178 0 : c.had_error = false;
179 0 : if ( (c.x_expr = nlt_parseexpr(&c,expstr))==NULL )
180 0 : d.done = d.ok = false;
181 : else {
182 0 : free(expstr);
183 0 : c.had_error = false;
184 0 : expstr = cu_copy(_GGadgetGetTitle(gcd[3].ret));
185 0 : if ( (c.y_expr = nlt_parseexpr(&c,expstr))==NULL ) {
186 0 : d.done = d.ok = false;
187 0 : nlt_exprfree(c.x_expr);
188 : } else {
189 0 : free(expstr);
190 0 : free(lasty); free(lastx);
191 0 : lastx = GGadgetGetTitle(gcd[1].ret);
192 0 : lasty = GGadgetGetTitle(gcd[3].ret);
193 : }
194 : }
195 : }
196 : }
197 0 : if ( d.ok ) {
198 0 : if ( fv!=NULL )
199 0 : _SFNLTrans((FontViewBase *) fv,&c);
200 : else
201 0 : CVNLTrans((CharViewBase *) cv,&c);
202 0 : nlt_exprfree(c.x_expr);
203 0 : nlt_exprfree(c.y_expr);
204 : }
205 0 : GDrawDestroyWindow(d.gw);
206 0 : }
207 :
208 : static GTextInfo originx[] = {
209 : { (unichar_t *) N_("Glyph Origin"), NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
210 : { (unichar_t *) N_("Center of Selection"), NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
211 : /* GT: The (x,y) position on the window where the user last pressed a mouse button */
212 : { (unichar_t *) N_("Last Press"), NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
213 : { (unichar_t *) N_("Value"), NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
214 : GTEXTINFO_EMPTY
215 : };
216 : static GTextInfo originy[] = {
217 : { (unichar_t *) N_("Glyph Origin"), NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
218 : { (unichar_t *) N_("Center of Selection"), NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
219 : /* GT: The (x,y) position on the window where the user last pressed a mouse button */
220 : { (unichar_t *) N_("Last Press"), NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
221 : { (unichar_t *) N_("Value"), NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
222 : GTEXTINFO_EMPTY
223 : };
224 : #define CID_XType 1001
225 : #define CID_YType 1002
226 : #define CID_XValue 1003
227 : #define CID_YValue 1004
228 : #define CID_ZValue 1005
229 : #define CID_DValue 1006
230 : #define CID_Tilt 1007
231 : #define CID_GazeDirection 1008
232 : #define CID_Vanish 1009
233 :
234 0 : static real GetQuietReal(GWindow gw,int cid,int *err) {
235 : const unichar_t *txt; unichar_t *end;
236 : real val;
237 :
238 0 : txt = _GGadgetGetTitle(GWidgetGetControl(gw,cid));
239 0 : val = u_strtod(txt,&end);
240 0 : if ( *end!='\0' )
241 0 : *err = true;
242 0 : return( val );
243 : }
244 :
245 0 : static void PoV_DoVanish(struct nldlg *d) {
246 : double x,y,dv,tilt,dir;
247 : double t;
248 0 : int err = false;
249 : double vp;
250 : char buf[80];
251 : unichar_t ubuf[80];
252 : extern char *coord_sep;
253 :
254 0 : x = GetQuietReal(d->gw,CID_XValue,&err);
255 0 : y = GetQuietReal(d->gw,CID_YValue,&err);
256 : /*z = GetQuietReal(d->gw,CID_ZValue,&err);*/
257 0 : dv = GetQuietReal(d->gw,CID_DValue,&err);
258 0 : tilt = GetQuietReal(d->gw,CID_Tilt,&err)*3.1415926535897932/180;
259 0 : dir = GetQuietReal(d->gw,CID_GazeDirection,&err)*3.1415926535897932/180;
260 0 : if ( err )
261 0 : return;
262 0 : if ( GGadgetGetFirstListSelectedItem( GWidgetGetControl(d->gw,CID_XType))!=3 )
263 0 : x = 0;
264 0 : if ( GGadgetGetFirstListSelectedItem( GWidgetGetControl(d->gw,CID_YType))!=3 )
265 0 : y = 0;
266 0 : t = tan(tilt);
267 0 : if ( t<.000001 && t>-.000001 )
268 0 : sprintf(buf,"inf%sinf", coord_sep);
269 : else {
270 0 : vp = dv/t;
271 0 : x -= sin(dir)*vp;
272 0 : y += cos(dir)*vp;
273 0 : sprintf(buf,"%g%s%g", x, coord_sep, y );
274 : }
275 0 : uc_strcpy(ubuf,buf);
276 0 : GGadgetSetTitle( GWidgetGetControl(d->gw,CID_Vanish), ubuf );
277 : }
278 :
279 0 : static int PoV_Vanish(GGadget *g, GEvent *e) {
280 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
281 0 : struct nldlg *d = GDrawGetUserData(GGadgetGetWindow(g));
282 0 : PoV_DoVanish(d);
283 : }
284 0 : return( true );
285 : }
286 :
287 0 : int PointOfViewDlg(struct pov_data *pov, SplineFont *sf, int flags) {
288 : static struct pov_data def = { or_center, or_value, 0, 0, .1,
289 : 0, 3.1415926535897932/16, .2, 0 };
290 0 : double emsize = (sf->ascent + sf->descent);
291 : struct nldlg d;
292 : GRect pos;
293 : GWindowAttrs wattrs;
294 : GGadgetCreateData gcd[24], boxes[7], *varray[10][3], *harray1[3], *harray2[3],
295 : *barray[9], *harray3[3], *harray4[3];
296 : GTextInfo label[24];
297 : int i,k,l;
298 : char xval[40], yval[40], zval[40], dval[40], tval[40], dirval[40];
299 : double x,y,z,dv,tilt,dir;
300 : int err;
301 : static int done = false;
302 :
303 0 : if ( !done ) {
304 0 : done = true;
305 0 : for ( i=0; originx[i].text!=NULL; ++i )
306 0 : originx[i].text = (unichar_t *) _((char *) originx[i].text);
307 0 : for ( i=0; originy[i].text!=NULL; ++i )
308 0 : originy[i].text = (unichar_t *) _((char *) originy[i].text);
309 : }
310 :
311 0 : *pov = def;
312 0 : pov->x *= emsize; pov->y *= emsize; pov->z *= emsize; pov->d *= emsize;
313 0 : if ( !(flags&1) ) {
314 0 : if ( pov->xorigin == or_lastpress ) pov->xorigin = or_center;
315 0 : if ( pov->yorigin == or_lastpress ) pov->yorigin = or_center;
316 : }
317 :
318 0 : memset(&d,'\0',sizeof(d));
319 :
320 0 : memset(&wattrs,0,sizeof(wattrs));
321 0 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_restrict|wam_isdlg;
322 0 : wattrs.event_masks = ~(1<<et_charup);
323 0 : wattrs.restrict_input_to_me = 1;
324 0 : wattrs.is_dlg = 1;
325 0 : wattrs.undercursor = 1;
326 0 : wattrs.cursor = ct_pointer;
327 0 : wattrs.utf8_window_title = _("Point of View Projection");
328 0 : pos.x = pos.y = 0;
329 0 : pos.width = GGadgetScale(GDrawPointsToPixels(NULL,240));
330 0 : pos.height = GDrawPointsToPixels(NULL,216);
331 0 : d.gw = GDrawCreateTopWindow(NULL,&pos,nld_e_h,&d,&wattrs);
332 :
333 0 : memset(gcd,0,sizeof(gcd));
334 0 : memset(boxes,0,sizeof(boxes));
335 0 : memset(label,0,sizeof(label));
336 :
337 0 : k=l=0;
338 0 : label[k].text = (unichar_t *) _("View Point");
339 0 : label[k].text_is_1byte = true;
340 0 : gcd[k].gd.label = &label[k];
341 0 : gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = 8;
342 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
343 0 : gcd[k++].creator = GLabelCreate;
344 0 : varray[l][0] = &gcd[k-1]; varray[l][1] = GCD_ColSpan; varray[l++][2] = NULL;
345 :
346 0 : label[k].text = (unichar_t *) _("_X");
347 0 : label[k].text_is_1byte = true;
348 0 : label[k].text_in_resource = true;
349 0 : gcd[k].gd.label = &label[k];
350 0 : gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y + 16;
351 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
352 0 : gcd[k++].creator = GLabelCreate;
353 0 : harray1[0] = &gcd[k-1];
354 :
355 0 : for ( i=or_zero; i<or_undefined; ++i ) originx[i].selected = false;
356 0 : originx[pov->xorigin].selected = true;
357 0 : originx[or_lastpress].disabled = !(flags&1);
358 0 : gcd[k].gd.pos.x = 23; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y-4;
359 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
360 0 : gcd[k].gd.label = &originx[pov->xorigin];
361 0 : gcd[k].gd.u.list = originx;
362 0 : gcd[k].gd.cid = CID_XType;
363 0 : gcd[k++].creator = GListButtonCreate;
364 0 : harray1[1] = &gcd[k-1]; harray1[2] = NULL;
365 :
366 0 : boxes[2].gd.flags = gg_enabled|gg_visible;
367 0 : boxes[2].gd.u.boxelements = harray1;
368 0 : boxes[2].creator = GHBoxCreate;
369 0 : varray[l][0] = &boxes[2];
370 :
371 0 : sprintf( xval, "%g", rint(pov->x));
372 0 : label[k].text = (unichar_t *) xval;
373 0 : label[k].text_is_1byte = true;
374 0 : gcd[k].gd.label = &label[k];
375 0 : gcd[k].gd.pos.x = 160; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y; gcd[k].gd.pos.width = 60;
376 0 : gcd[k].gd.flags = gg_enabled|gg_visible;
377 0 : gcd[k].gd.handle_controlevent = PoV_Vanish;
378 0 : gcd[k].gd.cid = CID_XValue;
379 0 : gcd[k++].creator = GTextFieldCreate;
380 0 : varray[l][1] = &gcd[k-1]; varray[l++][2] = NULL;
381 :
382 0 : label[k].text = (unichar_t *) _("_Y");
383 0 : label[k].text_is_1byte = true;
384 0 : label[k].text_in_resource = true;
385 0 : gcd[k].gd.label = &label[k];
386 0 : gcd[k].gd.pos.x = gcd[k-3].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y + 28;
387 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
388 0 : gcd[k++].creator = GLabelCreate;
389 0 : harray2[0] = &gcd[k-1];
390 :
391 0 : for ( i=or_zero; i<or_undefined; ++i ) originy[i].selected = false;
392 0 : originy[pov->yorigin].selected = true;
393 0 : originy[or_lastpress].disabled = !(flags&1);
394 0 : gcd[k].gd.pos.x = gcd[k-3].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y-4;
395 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
396 0 : gcd[k].gd.label = &originy[pov->yorigin];
397 0 : gcd[k].gd.u.list = originy;
398 0 : gcd[k].gd.cid = CID_YType;
399 0 : gcd[k++].creator = GListButtonCreate;
400 0 : harray2[1] = &gcd[k-1]; harray2[2] = NULL;
401 :
402 0 : boxes[3].gd.flags = gg_enabled|gg_visible;
403 0 : boxes[3].gd.u.boxelements = harray2;
404 0 : boxes[3].creator = GHBoxCreate;
405 0 : varray[l][0] = &boxes[3];
406 :
407 0 : sprintf( yval, "%g", rint(pov->y));
408 0 : label[k].text = (unichar_t *) yval;
409 0 : label[k].text_is_1byte = true;
410 0 : gcd[k].gd.label = &label[k];
411 0 : gcd[k].gd.pos.x = gcd[k-3].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y; gcd[k].gd.pos.width = gcd[k-3].gd.pos.width;
412 0 : gcd[k].gd.flags = gg_enabled|gg_visible;
413 0 : gcd[k].gd.cid = CID_YValue;
414 0 : gcd[k].gd.handle_controlevent = PoV_Vanish;
415 0 : gcd[k++].creator = GTextFieldCreate;
416 0 : varray[l][1] = &gcd[k-1]; varray[l++][2] = NULL;
417 :
418 0 : label[k].text = (unichar_t *) _("Distance to drawing plane:");
419 0 : label[k].text_is_1byte = true;
420 0 : gcd[k].gd.label = &label[k];
421 0 : gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y + 28;
422 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
423 0 : gcd[k++].creator = GLabelCreate;
424 0 : varray[l][0] = &gcd[k-1];
425 :
426 0 : sprintf( zval, "%g", rint(pov->z));
427 0 : label[k].text = (unichar_t *) zval;
428 0 : label[k].text_is_1byte = true;
429 0 : gcd[k].gd.label = &label[k];
430 0 : gcd[k].gd.pos.x = 160; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y-4; gcd[k].gd.pos.width = 60;
431 0 : gcd[k].gd.flags = gg_enabled|gg_visible;
432 0 : gcd[k].gd.handle_controlevent = PoV_Vanish;
433 0 : gcd[k].gd.cid = CID_ZValue;
434 0 : gcd[k++].creator = GTextFieldCreate;
435 0 : varray[l][1] = &gcd[k-1]; varray[l++][2] = NULL;
436 :
437 0 : label[k].text = (unichar_t *) _("Distance to projection plane:");
438 0 : label[k].text_is_1byte = true;
439 0 : gcd[k].gd.label = &label[k];
440 0 : gcd[k].gd.pos.x = gcd[k-2].gd.pos.x; gcd[k].gd.pos.y = gcd[k-2].gd.pos.y + 24;
441 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
442 0 : gcd[k++].creator = GLabelCreate;
443 0 : varray[l][0] = &gcd[k-1];
444 :
445 0 : sprintf( dval, "%g", rint(pov->d));
446 0 : label[k].text = (unichar_t *) dval;
447 0 : label[k].text_is_1byte = true;
448 0 : gcd[k].gd.label = &label[k];
449 0 : gcd[k].gd.pos.x = 160; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y-4; gcd[k].gd.pos.width = 60;
450 0 : gcd[k].gd.flags = gg_enabled|gg_visible;
451 0 : gcd[k].gd.handle_controlevent = PoV_Vanish;
452 0 : gcd[k].gd.cid = CID_DValue;
453 0 : gcd[k++].creator = GTextFieldCreate;
454 0 : varray[l][1] = &gcd[k-1]; varray[l++][2] = NULL;
455 :
456 0 : label[k].text = (unichar_t *) _("Drawing plane tilt:");
457 0 : label[k].text_is_1byte = true;
458 0 : gcd[k].gd.label = &label[k];
459 0 : gcd[k].gd.pos.x = gcd[k-2].gd.pos.x; gcd[k].gd.pos.y = gcd[k-2].gd.pos.y + 24;
460 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
461 0 : gcd[k++].creator = GLabelCreate;
462 0 : varray[l][0] = &gcd[k-1];
463 :
464 0 : sprintf( tval, "%g", rint(pov->tilt*180/3.1415926535897932));
465 0 : label[k].text = (unichar_t *) tval;
466 0 : label[k].text_is_1byte = true;
467 0 : gcd[k].gd.label = &label[k];
468 0 : gcd[k].gd.pos.x = 160; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y-4; gcd[k].gd.pos.width = 40;
469 0 : gcd[k].gd.flags = gg_enabled|gg_visible;
470 0 : gcd[k].gd.handle_controlevent = PoV_Vanish;
471 0 : gcd[k].gd.cid = CID_Tilt;
472 0 : gcd[k++].creator = GTextFieldCreate;
473 0 : harray3[0] = &gcd[k-1];
474 :
475 0 : label[k].text = (unichar_t *) U_("°");
476 0 : label[k].text_is_1byte = true;
477 0 : gcd[k].gd.label = &label[k];
478 0 : gcd[k].gd.pos.x = gcd[k-1].gd.pos.x+gcd[k-1].gd.pos.width+3; gcd[k].gd.pos.y = gcd[k-2].gd.pos.y;
479 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
480 0 : gcd[k++].creator = GLabelCreate;
481 0 : harray3[1] = &gcd[k-1]; harray3[2] = NULL;
482 :
483 0 : boxes[4].gd.flags = gg_enabled|gg_visible;
484 0 : boxes[4].gd.u.boxelements = harray3;
485 0 : boxes[4].creator = GHBoxCreate;
486 0 : varray[l][1] = &boxes[4]; varray[l++][2] = NULL;
487 :
488 0 : label[k].text = (unichar_t *) _("Direction of gaze:");
489 0 : label[k].text_is_1byte = true;
490 0 : gcd[k].gd.label = &label[k];
491 0 : gcd[k].gd.pos.x = gcd[k-3].gd.pos.x; gcd[k].gd.pos.y = gcd[k-3].gd.pos.y + 24;
492 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
493 0 : gcd[k++].creator = GLabelCreate;
494 0 : varray[l][0] = &gcd[k-1];
495 :
496 0 : sprintf( dirval, "%g", rint(pov->direction*180/3.1415926535897932));
497 0 : label[k].text = (unichar_t *) dirval;
498 0 : label[k].text_is_1byte = true;
499 0 : gcd[k].gd.label = &label[k];
500 0 : gcd[k].gd.pos.x = 160; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y-4; gcd[k].gd.pos.width = 40;
501 0 : gcd[k].gd.flags = gg_enabled|gg_visible;
502 0 : gcd[k].gd.handle_controlevent = PoV_Vanish;
503 0 : gcd[k].gd.cid = CID_GazeDirection;
504 0 : gcd[k++].creator = GTextFieldCreate;
505 0 : harray4[0] = &gcd[k-1];
506 :
507 0 : label[k].text = (unichar_t *) U_("°");
508 0 : label[k].text_is_1byte = true;
509 0 : gcd[k].gd.label = &label[k];
510 0 : gcd[k].gd.pos.x = gcd[k-1].gd.pos.x+gcd[k-1].gd.pos.width+3; gcd[k].gd.pos.y = gcd[k-2].gd.pos.y;
511 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
512 0 : gcd[k++].creator = GLabelCreate;
513 0 : harray4[1] = &gcd[k-1]; harray4[2] = NULL;
514 :
515 0 : boxes[5].gd.flags = gg_enabled|gg_visible;
516 0 : boxes[5].gd.u.boxelements = harray4;
517 0 : boxes[5].creator = GHBoxCreate;
518 0 : varray[l][1] = &boxes[5]; varray[l++][2] = NULL;
519 :
520 0 : label[k].text = (unichar_t *) _("Vanishing Point:");
521 0 : label[k].text_is_1byte = true;
522 0 : gcd[k].gd.label = &label[k];
523 0 : gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+18;
524 0 : gcd[k].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
525 0 : gcd[k].gd.popup_msg = (unichar_t *) _("This is the approximate location of the vanishing point.\nIt does not include the offset induced by \"Center of selection\"\nnor \"Last Press\".");
526 0 : gcd[k++].creator = GLabelCreate;
527 0 : varray[l][0] = &gcd[k-1];
528 :
529 0 : label[k].text = (unichar_t *) "123456.,123456.";
530 0 : label[k].text_is_1byte = true;
531 0 : gcd[k].gd.label = &label[k];
532 0 : gcd[k].gd.pos.x = 160; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y;
533 0 : gcd[k].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
534 0 : gcd[k].gd.popup_msg = (unichar_t *) _("This is the approximate location of the vanishing point.\nIt does not include the offset induced by \"Center of selection\"\nnor \"Last Press\".");
535 0 : gcd[k].gd.cid = CID_Vanish;
536 0 : gcd[k++].creator = GLabelCreate;
537 0 : varray[l][1] = &gcd[k-1]; varray[l++][2] = NULL;
538 :
539 0 : gcd[k].gd.pos.x = 30-3; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+18;
540 0 : gcd[k].gd.pos.width = -1; gcd[k].gd.pos.height = 0;
541 0 : gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_default;
542 0 : label[k].text = (unichar_t *) _("_OK");
543 0 : label[k].text_is_1byte = true;
544 0 : label[k].text_in_resource = true;
545 0 : gcd[k].gd.label = &label[k];
546 0 : gcd[k].gd.cid = true;
547 0 : gcd[k++].creator = GButtonCreate;
548 0 : barray[0] = GCD_Glue; barray[1] = &gcd[k-1]; barray[2] = GCD_Glue;
549 :
550 0 : gcd[k].gd.pos.x = -30; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+3;
551 0 : gcd[k].gd.pos.width = -1; gcd[k].gd.pos.height = 0;
552 0 : gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
553 0 : label[k].text = (unichar_t *) _("_Cancel");
554 0 : label[k].text_is_1byte = true;
555 0 : label[k].text_in_resource = true;
556 0 : gcd[k].gd.label = &label[k];
557 0 : gcd[k].gd.cid = false;
558 0 : gcd[k++].creator = GButtonCreate;
559 0 : barray[3] = GCD_Glue; barray[4] = &gcd[k-1]; barray[5] = GCD_Glue; barray[6] = NULL;
560 :
561 0 : boxes[6].gd.flags = gg_enabled|gg_visible;
562 0 : boxes[6].gd.u.boxelements = barray;
563 0 : boxes[6].creator = GHBoxCreate;
564 0 : varray[l][0] = &boxes[6]; varray[l][1] = GCD_ColSpan; varray[l++][2] = NULL;
565 0 : varray[l][0] = NULL;
566 :
567 0 : boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
568 0 : boxes[0].gd.flags = gg_enabled|gg_visible;
569 0 : boxes[0].gd.u.boxelements = varray[0];
570 0 : boxes[0].creator = GHVGroupCreate;
571 :
572 0 : GGadgetsCreate(d.gw,boxes);
573 0 : GHVBoxFitWindow(boxes[0].ret);
574 0 : PoV_DoVanish(&d);
575 0 : GDrawSetVisible(d.gw,true);
576 0 : while ( !d.done ) {
577 0 : GDrawProcessOneEvent(NULL);
578 0 : if ( d.done ) {
579 0 : if ( !d.ok ) {
580 0 : GDrawDestroyWindow(d.gw);
581 0 : return( -1 );
582 : }
583 0 : err = false;
584 0 : x = GetReal8(d.gw,CID_XValue,_("_X"),&err);
585 0 : y = GetReal8(d.gw,CID_YValue,_("_Y"),&err);
586 0 : z = GetReal8(d.gw,CID_ZValue,_("Distance to drawing plane:"),&err);
587 0 : dv = GetReal8(d.gw,CID_DValue,_("Distance to projection plane:"),&err);
588 0 : tilt = GetReal8(d.gw,CID_Tilt,_("Drawing plane tilt:"),&err);
589 0 : dir = GetReal8(d.gw,CID_GazeDirection,_("Direction of gaze:"),&err);
590 0 : if ( err ) {
591 0 : d.done = d.ok = false;
592 0 : continue;
593 : }
594 0 : pov->x = x; pov->y = y; pov->z = z; pov->d = dv;
595 0 : pov->tilt = tilt*3.1415926535897932/180;
596 0 : pov->direction = dir*3.1415926535897932/180;
597 0 : pov->xorigin = GGadgetGetFirstListSelectedItem( GWidgetGetControl(d.gw,CID_XType));
598 0 : pov->yorigin = GGadgetGetFirstListSelectedItem( GWidgetGetControl(d.gw,CID_YType));
599 : }
600 : }
601 :
602 0 : GDrawDestroyWindow(d.gw);
603 0 : def = *pov;
604 0 : def.x /= emsize; def.y /= emsize; def.z /= emsize; def.d /= emsize;
605 0 : return( 0 ); /* -1 => Canceled */
606 : }
607 :
608 0 : void CVPointOfView(CharView *cv,struct pov_data *pov) {
609 0 : int anysel = CVAnySel(cv,NULL,NULL,NULL,NULL);
610 : BasePoint origin;
611 :
612 0 : CVPreserveState((CharViewBase *) cv);
613 :
614 0 : origin.x = origin.y = 0;
615 0 : if ( pov->xorigin==or_center || pov->yorigin==or_center )
616 0 : CVFindCenter(cv,&origin,!anysel);
617 0 : if ( pov->xorigin==or_lastpress )
618 0 : origin.x = cv->p.cx;
619 0 : if ( pov->yorigin==or_lastpress )
620 0 : origin.y = cv->p.cy;
621 0 : if ( pov->xorigin!=or_value )
622 0 : pov->x = origin.x;
623 0 : if ( pov->yorigin!=or_value )
624 0 : pov->y = origin.y;
625 :
626 0 : MinimumDistancesFree(cv->b.sc->md); cv->b.sc->md = NULL;
627 0 : SPLPoV(cv->b.layerheads[cv->b.drawmode]->splines,pov,anysel);
628 0 : CVCharChangedUpdate(&cv->b);
629 0 : }
|