Subversion Repositories filter_foundry

Rev

Rev 11 | Rev 23 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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