12 Replies Latest reply: Dec 7, 2011 1:46 AM by c.pfaffenbichler RSS

    multiple guide sets

    c.pfaffenbichler Community Member

      In another thread a poster asked about multiple guide sets:

      http://forums.adobe.com/message/4062904#4062904

       

      It would seem that this should be fairly simple to achieve with writing guides’ properties into the metadata (possibly a dedidcated layer’s xmpMetaData) in sets and subsequently loading them from there.

      One could even do just one dialog with an entry field for entering a name when saving a guide set and a dropDownList to load or remove such sets.

       

      So I wonder if anybody either has already done something like this or has a (better) idea on the issue?

      Thanks for any feedback.

        • 1. Re: multiple guide sets
          Michael L Hale Community Member

          I was working on a guide panel that had just about every guide related feature Jeff Tranberry and I could think of. I was saving the sets( we called them presets ) in the user's presets folder as XML. The javascript end works just fine but I gave up on making the panel because of all the panel issues with Windows 7 and the newer Mac OSs

           

          Maybe I should create something that uses ScriptUI for the interface.

          • 2. Re: multiple guide sets
            c.pfaffenbichler Community Member

            Thanks for your answer.

             

            I suspect a Panel would probably be preferable for most users, a modal dialog might scare some of them off.

             

            If the presets were saved separately then they would not for example transfer with the documents?

            • 3. Re: multiple guide sets
              Michael L Hale Community Member

              I guess I didn't think of every feature after all. I had the guide preset set up like all the other presets in Photoshop. i.e. stored on the system and not with the document. I can see where having a guide preset travel with the document could have it's advantages. But if they are stored in the document how would one apply that set to a different document? Along those lines, do you think that being able to store other presets with a document would be useful?

               

              I agree that a panel would be ideal. But after all the issues that came up with my smart object linking panel I decided I would not make another until Adobe sorts out the issues with them.

              • 4. Re: multiple guide sets
                c.pfaffenbichler Community Member

                But if they are stored in the document how would one apply that set to a different document?

                I suppose one would need an export-function for that after all.

                Or, and this is a pretty dirty option I guess, if one uses a layer to hold the xmpMetaData one could transfer that – of course that would clash with a possible existing one in th ereceiving document. (I just wanted to use layer metadata to avoid meddling in the file’s metadata.)

                But I have to admit that I was thinking only of document-specific guides and not of guide presets for documents in general.

                Did you intend to offer options for units or percentages?

                 

                I once installed the Flash Builder trial and let it expire before getting anywhere, so I’m respectful for proper Panel-building …

                • 5. Re: multiple guide sets
                  Paul Riggott Community Member

                  As Mike has said a panel would be the best, Extension Builder, Flash Builder and Configurator all have the same problem with Windows 7 and render panels out of bounds until Adobe fix the problem.

                  I don't know if this will be of any use but I have a script here that creates new documents along with user selected guides, maybe it could be expanded to cope with preset guides?

                  http://www.scriptsrus.talktalk.net/CreateNewCanvas.htm

                  • 6. Re: multiple guide sets
                    Michael L Hale Community Member

                    c.pfaffenbichler wrote:

                     

                    Did you intend to offer options for units or percentages

                    As I remember I set it up so it could work with any distance unit, pixels or percent. I also had a flag in the preset so the guide set could either be fixed or relative so ( within limits ) it could work with any size document at any resolution.

                     

                    I think that if the preset is saved with the document it would be better to save it in a custom namespace in the document's metadata instead of a layer's metadata. To me the problem with using layer metadata to store a document wide setting is that it limts what can be done with the document, i.e. the layer can not be deleted, merged, etc.

                     

                    As I understand it both Windows 7 and Mac OSX have problems with custom panels. They range from simple panel refresh issues to more serious fucus issues. With Windows 7 sometimes a application restart is needed.

                    • 7. Re: multiple guide sets
                      c.pfaffenbichler Community Member

                      I think that if the preset is saved with the document it would be better to save it in a custom namespace in the document's metadata

                      You are right; but (please pardon my ignorance) I have no idea how to add a custom namespace to the xmpMetaData or how to retrieve that namespace’s information …

                      Would I have to use BridgeTalk for that?

                      • 8. Re: multiple guide sets
                        Michael L Hale Community Member

                        With newer versions of Photoshop you can use AdobeXMPScript to work with metadata. It is simple really, You just need to make up a namespace URL string, use new Namespace to convert that string into a namespace, then use registerNamespace() to add the namespace to the XMP. From there you can use it like any other namespace.

                         

                        But now that you have me thinking about this in more detail I am not sure any longer that the document's metadata has a clear advantage. I will have to do some test when I have time.

                        • 9. Re: multiple guide sets
                          Paul Riggott Community Member

                          Here is an example I've put together...

                           

                           

                          #target photoshop
                          app.bringToFront();
                          function main(){
                          var startRulerUnits = app.preferences.rulerUnits;
                          app.preferences.rulerUnits = Units.PIXELS;
                          // Set up metadata namespace
                          if (ExternalObject.AdobeXMPScript == undefined)  ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
                          var psNamespace = "http://ns.ps-scripts.com/1.0/";
                          var psPrefix = "psscripts:";
                          XMPMeta.registerNamespace(psNamespace, psPrefix);
                          existingGuidePresets = [];
                          existingGuidePresets = getGuideArray();
                          var guides = app.activeDocument.guides;
                          var gH = '';
                          var gV = '';
                          for( var g = 0; g < guides.length; g++ ){
                              if(guides[g].direction.toString() == 'Direction.HORIZONTAL'){
                                  gH+=(parseInt(guides[g].coordinate.value));
                                  gH+=',';
                                  }else{
                                      gV+=(parseInt(guides[g].coordinate.value));
                                      gV+=','
                                      }
                          }
                          gH=gH.replace(/,$/,'');
                          gV=gV.replace(/,$/,'');
                          app.preferences.rulerUnits = startRulerUnits;
                          var win = new Window( 'dialog', 'Custom Guides' ); 
                          g = win.graphics;
                          var myBrush = g.newBrush(g.BrushType.SOLID_COLOR, [0.99, 0.99, 0.99, 1]);
                          g.backgroundColor = myBrush;
                          win.p1= win.add("panel", undefined, undefined, {borderStyle:"black"}); 
                          win.g1 = win.p1.add('group');
                          win.g1.orientation = "row";
                          win.title = win.g1.add('statictext',undefined,'Custom Guides');
                          win.title.alignment="fill";
                          var g = win.title.graphics;
                          g.font = ScriptUI.newFont("Georgia","BOLDITALIC",22);
                          win.g5 =win.p1.add('group');
                          win.g5.orientation = "row";
                          win.g5.alignment='fill';
                          win.g5.spacing=10;
                          win.g5.st1 = win.g5.add('statictext',undefined,'Existing Presets');
                          win.g5.dd1 = win.g5.add('dropdownlist');
                          win.g5.dd1.preferredSize=[300,20];
                          for(var w in existingGuidePresets){
                              win.g5.dd1.add('item',existingGuidePresets[w].toString().match(/^[A-Za-z0-9 ]+/));
                              }
                          win.g5.dd1.selection=0;
                          win.g10 =win.p1.add('group');
                          win.g10.orientation = "row";
                          win.g10.alignment='fill';
                          win.g10.spacing=10;
                          win.g10.bu1 = win.g10.add('button',undefined,'Remove Preset');
                          win.g10.bu2 = win.g10.add('button',undefined,'Use and Append Guides');
                          win.g10.bu3 = win.g10.add('button',undefined,'Use and Remove Guides');
                          win.g15 =win.p1.add('group');
                          win.g15.orientation = "row";
                          win.g15.alignment='fill';
                          win.g15.st1 = win.g15.add('statictext',undefined,'New Preset Name');
                          win.g20 =win.p1.add('group');
                          win.g20.orientation = "row";
                          win.g20.alignment='fill';
                          win.g20.spacing=10;
                          win.g20.et1 = win.g20.add('edittext');
                          win.g20.et1.preferredSize=[300,20];
                          win.g20.bu1 = win.g20.add('button',undefined,'Add New Preset');
                          win.g200 =win.p1.add('group');
                          win.g200.orientation = "row";
                          win.g200.bu1 = win.g200.add('button',undefined,'Cancel');
                          win.g200.bu1.preferredSize=[350,30];
                          win.g10.bu1.onClick=function(){//Remove preset
                          if(existingGuidePresets.length == 0) return;
                          existingGuidePresets.splice(win.g5.dd1.selection.index,1);
                          win.g5.dd1.removeAll();
                          for(var w in existingGuidePresets){
                              win.g5.dd1.add('item',existingGuidePresets[w].toString().match(/^[A-Za-z0-9 ]+/));
                              }
                          win.g5.dd1.selection=0;
                          putGuideArray(existingGuidePresets);
                              }
                          win.g10.bu2.onClick=function(){//Use and append guides
                          if(existingGuidePresets.length == 0) return;
                          win.close(0);
                          var ar1 = existingGuidePresets[win.g5.dd1.selection.index].toString().split('#');
                          var Hor = ar1[1].toString().split(',');
                          var Ver = ar1[2].toString().split(',');
                          for(var H in Hor){
                              activeDocument.guides.add(Direction.HORIZONTAL,new UnitValue(Number(Hor[H]),'px'));
                              }
                          for(var V in Ver){
                              activeDocument.guides.add(Direction.VERTICAL,new UnitValue(Number(Ver[V]),'px'));
                              }
                              }
                          win.g10.bu3.onClick=function(){//Use and remove existing guides
                          if(existingGuidePresets.length == 0) return;
                          win.close(0);
                          clearGuides();
                          var ar1 = existingGuidePresets[win.g5.dd1.selection.index].toString().split('#');
                          var Hor = ar1[1].toString().split(',');
                          var Ver = ar1[2].toString().split(',');
                          for(var H in Hor){
                              activeDocument.guides.add(Direction.HORIZONTAL,new UnitValue(Number(Hor[H]),'px'));
                              }
                          for(var V in Ver){
                              activeDocument.guides.add(Direction.VERTICAL,new UnitValue(Number(Ver[V]),'px'));
                              }
                              }
                          win.g20.bu1.onClick=function(){//New preset
                          if(win.g20.et1.text == ''){
                              alert("You need to enter a name for the new preset");
                              return;
                              }
                          win.close(0);
                          currentGuides = win.g20.et1.text + "#" + gH + "#" + gV;
                          existingGuidePresets.push(currentGuides);
                          putGuideArray(existingGuidePresets);
                              }
                          win.center();
                          win.show();
                          function getGuideArray(){
                          var xmp; 
                          var newGuideArray=[];
                          xmp = new XMPMeta( app.activeDocument.xmpMetadata.rawData );
                          var Count = xmp.countArrayItems(psNamespace, "GuideArray");
                          for(var i = 1;i <= Count;i++){
                           newGuideArray.push(xmp.getArrayItem(psNamespace, "GuideArray", i).toString());
                          }
                          return newGuideArray;
                           }
                          function putGuideArray(gArray){
                          var xmp; 
                          xmp = new XMPMeta( app.activeDocument.xmpMetadata.rawData ); 
                          xmp.deleteProperty(psNamespace, "GuideArray");  
                           for(var g in gArray){
                           xmp.appendArrayItem(psNamespace, "GuideArray", gArray[g].toString(), 0, XMPConst.ARRAY_IS_UNORDERED);
                           }
                          app.activeDocument.xmpMetadata.rawData = xmp.serialize();
                          }
                          function clearGuides() { 
                             var id556 = charIDToTypeID( "Dlt " ); 
                                 var desc102 = new ActionDescriptor(); 
                                 var id557 = charIDToTypeID( "null" ); 
                                     var ref70 = new ActionReference(); 
                                     var id558 = charIDToTypeID( "Gd  " ); 
                                     var id559 = charIDToTypeID( "Ordn" ); 
                                     var id560 = charIDToTypeID( "Al  " ); 
                                     ref70.putEnumerated( id558, id559, id560 ); 
                                 desc102.putReference( id557, ref70 ); 
                             executeAction( id556, desc102, DialogModes.NO ); 
                          };
                          }
                          main();
                          
                          
                          • 10. Re: multiple guide sets
                            c.pfaffenbichler Community Member

                            Thanks a lot!

                            I’ll try to check it out tomorrow morning.

                            • 11. Re: multiple guide sets
                              Paul Riggott Community Member

                              Just a couple of amendments to it...

                               

                               

                              #target photoshop
                              app.bringToFront();
                              ///////////////////////////////////
                              // Photoshop CS5 or better
                              ///////////////////////////////////
                              function main(){
                              if(!documents.length) return;
                              var startRulerUnits = app.preferences.rulerUnits;
                              app.preferences.rulerUnits = Units.PIXELS;
                              // Set up metadata namespace
                              if (ExternalObject.AdobeXMPScript == undefined)  ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
                              var psNamespace = "http://ns.ps-scripts.com/1.0/";
                              var psPrefix = "psscripts:";
                              XMPMeta.registerNamespace(psNamespace, psPrefix);
                              existingGuidePresets = [];
                              existingGuidePresets = getGuideArray();
                              var guides = app.activeDocument.guides;
                              var gH = '';
                              var gV = '';
                              for( var g = 0; g < guides.length; g++ ){
                                  if(guides[g].direction.toString() == 'Direction.HORIZONTAL'){
                                      gH+=(parseInt(guides[g].coordinate.value));
                                      gH+=',';
                                      }else{
                                          gV+=(parseInt(guides[g].coordinate.value));
                                          gV+=','
                                          }
                              }
                              gH=gH.replace(/,$/,'');
                              gV=gV.replace(/,$/,'');
                              app.preferences.rulerUnits = startRulerUnits;
                              var win = new Window( 'dialog', 'Custom Guides' ); 
                              g = win.graphics;
                              var myBrush = g.newBrush(g.BrushType.SOLID_COLOR, [0.99, 0.99, 0.99, 1]);
                              g.backgroundColor = myBrush;
                              win.p1= win.add("panel", undefined, undefined, {borderStyle:"black"}); 
                              win.g1 = win.p1.add('group');
                              win.g1.orientation = "row";
                              win.title = win.g1.add('statictext',undefined,'Custom Guides');
                              win.title.alignment="fill";
                              var g = win.title.graphics;
                              g.font = ScriptUI.newFont("Georgia","BOLDITALIC",22);
                              win.g5 =win.p1.add('group');
                              win.g5.orientation = "row";
                              win.g5.alignment='fill';
                              win.g5.spacing=10;
                              win.g5.st1 = win.g5.add('statictext',undefined,'Existing Presets');
                              win.g5.dd1 = win.g5.add('dropdownlist');
                              win.g5.dd1.preferredSize=[300,20];
                              for(var w in existingGuidePresets){
                                  win.g5.dd1.add('item',existingGuidePresets[w].toString().match(/[^#]*/));
                                  }
                              win.g5.dd1.selection=0;
                              win.g10 =win.p1.add('group');
                              win.g10.orientation = "row";
                              win.g10.alignment='fill';
                              win.g10.spacing=10;
                              win.g10.bu1 = win.g10.add('button',undefined,'Remove Preset');
                              win.g10.bu2 = win.g10.add('button',undefined,'Use and Append Guides');
                              win.g10.bu3 = win.g10.add('button',undefined,'Use and Remove Guides');
                              win.g15 =win.p1.add('group');
                              win.g15.orientation = "row";
                              win.g15.alignment='fill';
                              win.g15.st1 = win.g15.add('statictext',undefined,'New Preset Name');
                              win.g20 =win.p1.add('group');
                              win.g20.orientation = "row";
                              win.g20.alignment='fill';
                              win.g20.spacing=10;
                              win.g20.et1 = win.g20.add('edittext');
                              win.g20.et1.preferredSize=[300,20];
                              win.g20.bu1 = win.g20.add('button',undefined,'Add New Preset');
                              win.g200 =win.p1.add('group');
                              win.g200.orientation = "row";
                              win.g200.bu1 = win.g200.add('button',undefined,'Cancel');
                              win.g200.bu1.preferredSize=[350,30];
                              win.g10.bu1.onClick=function(){//Remove preset
                              if(existingGuidePresets.length == 0) return;
                              existingGuidePresets.splice(win.g5.dd1.selection.index,1);
                              win.g5.dd1.removeAll();
                              for(var w in existingGuidePresets){
                                  win.g5.dd1.add('item',existingGuidePresets[w].toString().match(/[^#]*/));
                                  }
                              win.g5.dd1.selection=0;
                              putGuideArray(existingGuidePresets);
                                  }
                              win.g10.bu2.onClick=function(){//Use and append guides
                              if(existingGuidePresets.length == 0) return;
                              win.close(0);
                              var ar1 = existingGuidePresets[win.g5.dd1.selection.index].toString().split('#');
                              var Hor = ar1[1].toString().split(',');
                              var Ver = ar1[2].toString().split(',');
                              for(var H in Hor){
                                  activeDocument.guides.add(Direction.HORIZONTAL,new UnitValue(Number(Hor[H]),'px'));
                                  }
                              for(var V in Ver){
                                  activeDocument.guides.add(Direction.VERTICAL,new UnitValue(Number(Ver[V]),'px'));
                                  }
                                  }
                              win.g10.bu3.onClick=function(){//Use and remove existing guides
                              if(existingGuidePresets.length == 0) return;
                              win.close(0);
                              clearGuides();
                              var ar1 = existingGuidePresets[win.g5.dd1.selection.index].toString().split('#');
                              var Hor = ar1[1].toString().split(',');
                              var Ver = ar1[2].toString().split(',');
                              for(var H in Hor){
                                  activeDocument.guides.add(Direction.HORIZONTAL,new UnitValue(Number(Hor[H]),'px'));
                                  }
                              for(var V in Ver){
                                  activeDocument.guides.add(Direction.VERTICAL,new UnitValue(Number(Ver[V]),'px'));
                                  }
                                  }
                              win.g20.bu1.onClick=function(){//New preset
                              if(app.activeDocument.guides.length == 0){
                                  alert("No guides exist");
                                  return;
                                  }
                              if(win.g20.et1.text == ''){
                                  alert("You need to enter a name for the new preset");
                                  return;
                                  }
                              win.close(0);
                              currentGuides = win.g20.et1.text + "#" + gH + "#" + gV;
                              existingGuidePresets.push(currentGuides);
                              putGuideArray(existingGuidePresets);
                                  }
                              win.center();
                              win.show();
                              function getGuideArray(){
                              var xmp; 
                              var newGuideArray=[];
                              xmp = new XMPMeta( app.activeDocument.xmpMetadata.rawData );
                              var Count = xmp.countArrayItems(psNamespace, "GuideArray");
                              for(var i = 1;i <= Count;i++){
                               newGuideArray.push(xmp.getArrayItem(psNamespace, "GuideArray", i).toString());
                              }
                              return newGuideArray;
                               }
                              function putGuideArray(gArray){
                              var xmp; 
                              xmp = new XMPMeta( app.activeDocument.xmpMetadata.rawData ); 
                              xmp.deleteProperty(psNamespace, "GuideArray");  
                               for(var g in gArray){
                               xmp.appendArrayItem(psNamespace, "GuideArray", gArray[g].toString(), 0, XMPConst.ARRAY_IS_UNORDERED);
                               }
                              app.activeDocument.xmpMetadata.rawData = xmp.serialize();
                              }
                              function clearGuides() { 
                                 var id556 = charIDToTypeID( "Dlt " ); 
                                     var desc102 = new ActionDescriptor(); 
                                     var id557 = charIDToTypeID( "null" ); 
                                         var ref70 = new ActionReference(); 
                                         var id558 = charIDToTypeID( "Gd  " ); 
                                         var id559 = charIDToTypeID( "Ordn" ); 
                                         var id560 = charIDToTypeID( "Al  " ); 
                                         ref70.putEnumerated( id558, id559, id560 ); 
                                     desc102.putReference( id557, ref70 ); 
                                 executeAction( id556, desc102, DialogModes.NO ); 
                              };
                              }
                              main();
                              
                              
                              • 12. Re: multiple guide sets
                                c.pfaffenbichler Community Member

                                Thank you both, as usual your input has been remarkable.

                                 

                                Paul, maybe you want to point the original poster in the thread I linked to in my original post to your Script.

                                That thread had some unfortunate impoliteness, but your effort might be appreciated there, too.

                                 

                                Edit: I still don’t quite get the namespace-thing, but I hope I’ll have time to take a closer look at the Script soon.

                                Thanks again.