Subversion Repositories filter_foundry

Rev

Rev 8 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 toby 1
/*
2
        This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
3
    Copyright (C) 2003-5 Toby Thain, toby@telegraphics.com.au
4
 
5
    This program is free software; you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by  
7
    the Free Software Foundation; either version 2 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
15
    You should have received a copy of the GNU General Public License  
16
    along with this program; if not, write to the Free Software
17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
*/
19
 
20
/* This is PLATFORM INDEPENDENT user interface code - mainly dialog logic */
21
 
22
#include "ff.h"
23
 
24
#include "node.h"
25
#include "parser.h"
26
#include "funcs.h"
27
#include "y.tab.h"
28
#include "choosefile.h"
29
#include "sprintf_tiny.h"
30
 
31
#ifdef MAC_ENV
32
        #include <files.h>
33
        #include <plstringfuncs.h>
34
 
35
        #define GETSLIDERVALUE GetDlgControlValue
36
        #define SETSLIDERVALUE SetDlgControlValue
37
        #define GETCTLTEXT getctltext
38
        #define SETCTLTEXT setctltext
39
        #define GETCTLTEXTINT getctltextint
40
        #define SETCTLTEXTINT setctltextint
41
        #define SELECTCTLTEXT selectctltext
42
#else
43
        #include <commctrl.h>
44
        #include "compat_string.h"
45
 
46
        #define GETSLIDERVALUE(d,i) SendDlgItemMessage(d,i,TBM_GETPOS,0,0)
47
        #define SETSLIDERVALUE(d,i,v) SendDlgItemMessage(d,i,TBM_SETPOS,TRUE,v)
48
        #define GETCTLTEXT GetDlgItemText
49
        #define SETCTLTEXT SetDlgItemText
50
        #define SELECTCTLTEXT SELECTDLGITEMTEXT
51
        #define GETCTLTEXTINT GetDlgItemInt
52
        #define SETCTLTEXTINT SetDlgItemInt
53
#endif
54
 
55
Boolean doupdates = true;
56
double zoomfactor,fitzoom;
57
 
58
void updateglobals(DIALOGREF dp);
59
struct node *updateexpr(DIALOGREF dp,int i);
60
void updatedialog(DIALOGREF dp);
61
void slidertextchanged(DIALOGREF dp,int item);
62
void updatezoom(DIALOGREF dp);
63
 
64
void updatedialog(DIALOGREF dp){
65
        int i;
66
 
67
        doupdates = false;
68
 
69
        for( i=0 ; i<8 ; ++i ){
70
                SETSLIDERVALUE(dp,FIRSTCTLITEM+i,slider[i]);
71
                SETCTLTEXTINT(dp,FIRSTCTLTEXTITEM+i,slider[i],false);
72
        }
73
 
74
        for( i=0 ; i<4 ; ++i ){
75
                if(!gdata->standalone) SETCTLTEXT(dp,FIRSTEXPRITEM+i,expr[i] ? expr[i] : "oups! expr[i] is nil!");
76
                if(i<nplanes)
77
                        updateexpr(dp,FIRSTEXPRITEM+i);
78
        }
79
 
80
        if(!gdata->standalone) SELECTCTLTEXT(dp,FIRSTEXPRITEM,0,-1);
81
 
82
        doupdates = true;
83
}
84
 
85
/* copy dialog settings to global variables (sliders, expressions) */
86
 
87
void updateglobals(DIALOGREF dp){
88
        int i;
89
        char s[MAXEXPR+1];
90
 
91
        for( i=0 ; i<8 ; ++i )
92
                slider[i] = GETSLIDERVALUE(dp,FIRSTCTLITEM+i);
93
 
94
        if(!gdata->standalone)
95
                for( i=0 ; i<4 ; ++i ){
96
                        /* stash expression strings */
97
                        if(GETCTLTEXT(dp,FIRSTEXPRITEM+i,s,MAXEXPR)){
98
                                if(expr[i])
99
                                        free(expr[i]);
100
                                if(!(expr[i] = my_strdup(s)))
101
                                        dbg("updateglobals: my_strdup returned zero??");
102
                        }else
103
                                dbg("updateglobals: GETCTLTEXT returned zero??");
104
                }
105
}
106
 
107
struct node *updateexpr(DIALOGREF dp,int item){
108
        char s[MAXEXPR+1];
109
        int i;
110
 
111
//dbg("updateexpr");
112
 
113
        i = item - FIRSTEXPRITEM;
114
 
115
        freetree(tree[i]);
116
 
117
        if(!gdata->standalone){
118
                GETCTLTEXT(dp,item,s,MAXEXPR);
119
 
120
                if(expr[i])
121
                        free(expr[i]);
122
                expr[i] = my_strdup(s);
123
        }
124
 
125
        tree[i] = parseexpr(expr[i]);
126
 
127
        if(!gdata->standalone){
128
                if(tree[i])
129
                        HideDialogItem(dp,FIRSTICONITEM+i);
130
                else{
131
                        err[i] = errstr;
132
                        errstart[i] = tokstart;
133
                        errpos[i] = tokpos;
134
                        ShowDialogItem(dp,FIRSTICONITEM+i);
135
                }
136
        }
137
        return tree[i];
138
}
139
 
140
void updatezoom(DIALOGREF dp){
141
        char s[10],*q = int_str(s,(int)(100./zoomfactor),10);
142
        *q++ = '%';
143
        *q = 0;
144
        SETCTLTEXT(dp,ZOOMLEVELITEM,s);
145
        zoomfactor > 1. ? ShowDialogItem(dp,ZOOMINITEM) : HideDialogItem(dp,ZOOMINITEM);
146
        zoomfactor < fitzoom ? ShowDialogItem(dp,ZOOMOUTITEM) : HideDialogItem(dp,ZOOMOUTITEM);
147
}
148
 
149
/* traverse expression tree, looking for constant references to sliders */
150
 
151
int checksl(struct node*p,int ctlflags[],int mapflags[]);
152
int checksl(struct node*p,int ctlflags[],int mapflags[]){
153
        if(p){
154
                int s;
155
                if( (p->kind==TOK_FN1 && p->v.sym->fn == (pfunc_type)ff_ctl)
156
                 || (p->kind==TOK_FN3 && p->v.sym->fn == (pfunc_type)ff_val) ){
157
                        if(p->child[0]->kind == TOK_NUM){
158
                                s = p->child[0]->v.value;
159
                                if(s>=0 && s<=7)
160
                                        ctlflags[s] = 1;
161
                        }else
162
                                return true; /* can't determine which ctl() */
163
                }else if( p->kind==TOK_FN2 && p->v.sym->fn == (pfunc_type)ff_map )
164
                        if(p->child[0]->kind == TOK_NUM){
165
                                s = p->child[0]->v.value;
166
                                if(s>=0 && s<=3){
167
                                        mapflags[s] = 1;
168
                                        ctlflags[s*2] = ctlflags[s*2+1] = 1;
169
                                }
170
                        }else
171
                                return true; /* can't determine which map() */
172
 
173
                return checksl(p->child[0],ctlflags,mapflags)
174
                        || checksl(p->child[1],ctlflags,mapflags)
175
                        || checksl(p->child[2],ctlflags,mapflags)
176
                        || checksl(p->child[3],ctlflags,mapflags)
177
                        || checksl(p->child[4],ctlflags,mapflags);     
178
        }else return false;
179
}
180
 
181
Boolean checksliders(int exprs,int ctlflags[],int mapflags[]){
182
        int i,f = false;
183
 
184
        for(i=4;i--;)
185
                mapflags[i] = 0;
186
        for(i=8;i--;)
187
                ctlflags[i] = 0;
188
 
189
        for(i=0;i<exprs;i++)
190
                if(checksl(tree[i],ctlflags,mapflags))
191
                        f = true;
192
 
193
        return f;
194
}
195
 
196
void slidermoved(DIALOGREF dp,int i){
197
        int v = GETSLIDERVALUE(dp,i);
198
        i -= FIRSTCTLITEM;
199
        slider[i] = v;
200
        SETCTLTEXTINT(dp,i+FIRSTCTLTEXTITEM,v,false);
201
}
202
 
203
void slidertextchanged(DIALOGREF dp,int i){
204
        int v = GETCTLTEXTINT(dp,i,NULL,false);
205
        i -= FIRSTCTLTEXTITEM;
206
        SETSLIDERVALUE(dp,i+FIRSTCTLITEM,v);
207
        slider[i] = v;
208
}
209
 
210
void maindlgupdate(DIALOGREF dp){
211
        int i,unknown,ctls[8],maps[4];
212
 
213
        unknown = checksliders(nplanes,ctls,maps);
214
 
215
        for(i=0;i<8;i++)
216
                if(unknown || ctls[i]){
217
                        ENABLEDLGITEM(dp,FIRSTCTLITEM+i);
218
                        ShowDialogItem(dp,FIRSTCTLTEXTITEM+i); /* FIXME: this changes keyboard focus */
219
                }else{
220
                        DISABLEDLGITEM(dp,FIRSTCTLITEM+i);
221
                        HideDialogItem(dp,FIRSTCTLTEXTITEM+i); /* FIXME: this changes keyboard focus */
222
                }
223
 
224
        for( i=0 ; i<nplanes ; i++ )
225
                if(!tree[i]){
226
                        /* uh oh, couldn't parse one of the saved expressions...this is fatal */
227
                        DISABLEDLGITEM(dp,IDOK);
228
                        if(gdata->standalone){
229
                                alertuser("Can't run this filter (there is a problem with the saved expressions).","");
230
                        }else{
231
                                DISABLEDLGITEM(dp,SAVEITEM);
232
                                DISABLEDLGITEM(dp,MAKEITEM);
233
                        }
234
                        return;
235
                }
236
 
237
        /* we have valid expression trees in all slots...proceed! */
238
        updateglobals(dp);
239
        if(setup(gpb))
240
                recalc_preview(gpb,dp);
241
 
242
        ENABLEDLGITEM(dp,IDOK);
243
        if(!gdata->standalone){
244
                ENABLEDLGITEM(dp,SAVEITEM);
245
                ENABLEDLGITEM(dp,MAKEITEM);
246
        }
247
}
248
 
249
/* one-time initialisation of dialog box */
250
 
251
void maindlginit(DIALOGREF dp){
252
        char s[0x100];
253
        extern char *defaultexpr[];
254
        int i;
255
 
256
        /* hide unused expression items */
257
        if(gdata->standalone){
258
                myp2cstrcpy(s,gdata->parm.author); SetDlgItemText(dp,PARAMAUTHORITEM,s);
259
                myp2cstrcpy(s,gdata->parm.copyright); SetDlgItemText(dp,PARAMCOPYITEM,s);
260
                for(i=0;i<8;++i){
261
                        if(gdata->parm.ctl_used[i]){
262
                                myp2cstrcpy(s,gdata->parm.ctl[i]); SetDlgItemText(dp,FIRSTCTLLABELITEM+i,s);
263
                        }else if(gdata->parm.map_used[i/2]){
264
                                if(i&1)
265
                                        HideDialogItem(dp,FIRSTCTLLABELITEM+i);
266
                                else{
267
                                        myp2cstrcpy(s,gdata->parm.map[i/2]); SetDlgItemText(dp,FIRSTCTLLABELITEM+i,s);
268
                                }
269
                        }else{
270
                                HideDialogItem(dp,FIRSTCTLITEM+i);
271
                                HideDialogItem(dp,FIRSTCTLTEXTITEM+i);
272
                                HideDialogItem(dp,FIRSTCTLLABELITEM+i);
273
                        }
274
                }
275
        }else
276
                for(i=nplanes;i<4;++i){
277
                        HideDialogItem(dp,FIRSTICONITEM+i);
278
                        HideDialogItem(dp,FIRSTEXPRITEM+i);
279
                        HideDialogItem(dp,FIRSTLABELITEM+i);
280
                }
281
 
282
        if(setup_preview(gpb)){
283
                extern int preview_w,preview_h;
284
                double zh = (gpb->filterRect.right-gpb->filterRect.left)/(double)preview_w,
285
                           zv = (gpb->filterRect.bottom-gpb->filterRect.top)/(double)preview_h;
286
                fitzoom = zh > zv ? zh : zv;
287
                zoomfactor = fitzoom;
288
                updatezoom(dp);
289
        }else{
290
                HideDialogItem(dp,ZOOMINITEM);
291
                HideDialogItem(dp,ZOOMOUTITEM);
292
                HideDialogItem(dp,ZOOMLEVELITEM);
293
        }
294
 
295
#ifdef WIN_ENV
296
        // can't build standalone filter on less than NT platform :-(
297
        // due to absence of resource editing API (UpdateResource etc)
298
        if(!isWin32NT())
299
                HideDialogItem(dp,MAKEITEM);
300
#endif
301
 
302
        updatedialog(dp);
303
        maindlgupdate(dp);
304
}
305
 
306
 
307
/* process an item hit. return false if the dialog is finished; otherwise return true. */
308
 
309
Boolean maindlgitem(DIALOGREF dp,int item){
310
        StandardFileReply sfr;
311
        NavReplyRecord reply;
312
        static char filefilters[] =
313
                "All supported files (.AFS, .8BF, .TXT)\0*.AFS;*.8BF;*.TXT\0All files (*.*)\0*.*\0\0";
314
        static OSType types[] = {TEXT_FILETYPE,PS_FILTER_FILETYPE};
315
        Boolean readok = false;
316
        char *reason;
317
        Str255 fname;
318
 
319
        switch(item){
320
        case IDOK:     
321
//              updateglobals(dp);
322
        case IDCANCEL:
323
                dispose_preview();
324
                return false; // end dialog
325
        case OPENITEM:
326
                if(!gdata->standalone && choosefiletypes("\pChoose filter settings",&sfr,&reply,types,2,filefilters)){
327
                        if(loadfile(&sfr,&reason)){
328
                                updatedialog(dp);
329
                                maindlgupdate(dp);
330
                        }else alertuser("Cannot load settings.",reason);
331
                }
332
                break;
333
        case SAVEITEM:
334
                if(!gdata->standalone && putfile("\pSave filter settings","\p",
335
                                                                                 TEXT_FILETYPE,SIG_SIMPLETEXT,&reply,&sfr)){
336
//                      updateglobals(dp);
337
                        if(savefile(&sfr))
338
                                completesave(&reply);
339
                }
340
                break;
341
        case MAKEITEM:
342
                if( !gdata->standalone && builddialog(gpb) ){
343
                        PLstrcpy(fname,gdata->parm.title);
344
#ifdef WIN_ENV
345
                        PLstrcat(fname,(StringPtr)"\p.8bf");
346
#endif
347
                        if( putfile("\pMake standalone filter",fname,
348
                                                PS_FILTER_FILETYPE,kPhotoshopSignature,&reply,&sfr ) )
349
                                make_standalone(&sfr);
350
                }
351
                break;
352
        case ZOOMINITEM:
353
//              zoomfactor = zoomfactor/2.;
354
                zoomfactor = zoomfactor>2. ? zoomfactor/2. : 1.;
355
                updatezoom(dp);
356
                recalc_preview(gpb,dp);
357
                break;
358
        case ZOOMOUTITEM:
359
                zoomfactor *= 2.;
360
                if(zoomfactor > fitzoom)
361
                        zoomfactor = fitzoom;
362
                updatezoom(dp);
363
                recalc_preview(gpb,dp);
364
                break;
365
        case ZOOMLEVELITEM:
366
                zoomfactor = (zoomfactor == fitzoom) ? 1. : fitzoom;
367
                updatezoom(dp);
368
                recalc_preview(gpb,dp);
369
                break;
370
        case FIRSTCTLITEM:
371
        case FIRSTCTLITEM+1:
372
        case FIRSTCTLITEM+2:
373
        case FIRSTCTLITEM+3:
374
        case FIRSTCTLITEM+4:
375
        case FIRSTCTLITEM+5:
376
        case FIRSTCTLITEM+6:
377
        case FIRSTCTLITEM+7:
378
                slidermoved(dp,item);
379
                recalc_preview(gpb,dp);
380
                break;
381
        case FIRSTCTLTEXTITEM:
382
        case FIRSTCTLTEXTITEM+1:
383
        case FIRSTCTLTEXTITEM+2:
384
        case FIRSTCTLTEXTITEM+3:
385
        case FIRSTCTLTEXTITEM+4:
386
        case FIRSTCTLTEXTITEM+5:
387
        case FIRSTCTLTEXTITEM+6:
388
        case FIRSTCTLTEXTITEM+7:
389
                slidertextchanged(dp,item);
390
                recalc_preview(gpb,dp);
391
                break;
392
        case FIRSTICONITEM:
393
        case FIRSTICONITEM+1:
394
        case FIRSTICONITEM+2:
395
        case FIRSTICONITEM+3:
396
                item -= FIRSTICONITEM;
397
                alertuser(err[item],"");
398
                SELECTCTLTEXT(dp,FIRSTEXPRITEM+item,errstart[item],errpos[item]);
399
                break;
400
        case FIRSTEXPRITEM:
401
        case FIRSTEXPRITEM+1:
402
        case FIRSTEXPRITEM+2:
403
        case FIRSTEXPRITEM+3:
404
//              dbg("expritem hit");
405
                if( (item-FIRSTEXPRITEM)<nplanes ){
406
                        updateexpr(dp,item);
407
                        maindlgupdate(dp);
408
                }
409
                break;
410
        }
411
 
412
        return true; // keep going
413
}
414
 
415
Boolean alertuser(char *err,char *more){
416
        char *s = malloc(strlen(err)+strlen(more)+2),*q;
417
        Boolean res;
418
 
419
        q = cat(s,err);
420
        *q++ = '\n';
421
        q = cat(q,more);
422
        *q = 0;
423
        res = simplealert(s);
424
        free(s);
425
        return res;
426
}