Subversion Repositories filter_foundry

Rev

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

  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 "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
  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);
  299. #endif
  300.  
  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)
  304.   //HideDialogItem(dp,MAKEITEM);
  305. #endif
  306.  
  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
  350.       PLstrcat(fname,(StringPtr)"\p.8bf");
  351. #endif
  352. #ifdef MACMACHO
  353.       PLstrcat(fname,(StringPtr)"\p.plugin");
  354. #endif
  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. }
  435.