Welcome Dialog

Welcome to the Community!

We have a brand new look! Take a tour with us and explore the latest updates on Adobe Support Community.


Feature Request: Set Ruler Origin Location in Photoshop

Community Beginner ,
Jan 08, 2020 Jan 08, 2020

Copy link to clipboard

Copied

I'd love to see an option in preferences under Units and Rulers to set the Ruler Origin (0,0) to be in a different location than the top left corner of the artboard, either on a document by document basis, or as a default - maybe with a toggle. A 3x3 grid of radio button selections such as top left, middle left, bottom left; top center, middle center, bottom center; top right, middle right, bottom right would be ideal, but a drop down list would work also. This would save having to zoom waaaaayyy in to the appropriate location and dragging the corner box of the ruler to (hopefully) line up with the exact pixel you're aiming for on each new artboard/file.

If there's already a simple way to do this that I'm unaware of, I'd love to know what it is!

 

Thanks!

mscureman

TOPICS
macOS, Windows

Views

354

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 2 Correct answers

Adobe Community Professional , Jan 08, 2020 Jan 08, 2020
If you want to submit the radio button/dropdown idea (I'd +1) it you can submit it here: Adobe Feature Request Form 

Likes

Translate

Translate
Community Beginner , Jan 09, 2020 Jan 09, 2020
Thanks for the feedback, kstohlmeyer! I knew about dragging the upper left corner, but didn't know about the Shift key modifier.  Helpful! Also, I submitted this as an "Idea" on the feedback forum here:Set Ruler Origin Location in Preferences, New Document Dialog or Menu

Likes

Translate

Translate
Adobe Community Professional ,
Jan 08, 2020 Jan 08, 2020

Copy link to clipboard

Copied

Its super easy to reorientate the ruler:

Grab the upper left corner where the two rulers meet and drag a new orientation point.

If you hold the shift key while you move it will lock to ruler positions.

Kevin Stohlmeyer Adobe Community Professional/Adobe Certified Instructor

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jan 08, 2020 Jan 08, 2020

Copy link to clipboard

Copied

If you want to submit the radio button/dropdown idea (I'd +1) it you can submit it here:

Adobe Feature Request Form 

Kevin Stohlmeyer Adobe Community Professional/Adobe Certified Instructor

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 09, 2020 Jan 09, 2020

Copy link to clipboard

Copied

Thanks for the feedback, kstohlmeyer! I knew about dragging the upper left corner, but didn't know about the Shift key modifier.  Helpful!

 

Also, I submitted this as an "Idea" on the feedback forum here:

Set Ruler Origin Location in Preferences, New Document Dialog or Menu

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
May 16, 2021 May 16, 2021

Copy link to clipboard

Copied

A similar topic here: Feature Request: Set Origin Point

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 14, 2021 May 14, 2021

Copy link to clipboard

Copied

I'd love to have an option to set where the 0,0 point is for the X and Y axes. Top Left is fine for many projects, but it'd be nice to have, perhaps, a radio button-style interface, either in preferences or in the document properties (or both!), where you had a 3x3 grid of buttons so you could choose to set the reference origin point at the:

 

Top Left, Top Middle, Top Right

Middle Left, Center, Middle Right

Bottom Left, Bottom Middle, Bottom Right

 

See attached photo

 

jane-e_0-1621027172881.jpeg

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
May 14, 2021 May 14, 2021

Copy link to clipboard

Copied

If you not already aware you can change the point of origin if you have View>Rulers enabled.

 

Grid, Guides, and Ruler Shortcuts in Photoshop

 

 

You can make a feature requst over here:

 

Adobe Photoshop Family

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 14, 2021 May 14, 2021

Copy link to clipboard

Copied

Thanks, Jeff.  Yes, I'm aware of the feature to drag the origin point on the rulers, but that's the shortcut I'm looking for.  I want a way to set that simply either as a default preference, or as a one-click solution on a per document basis. One of the major drawbacks to clicking and dragging is the need to zoom in to a high level in order to precisely set 0,0 at the exact corner.

 

Also, I realized that I posted this request in the feedback forum you linked to about a year ago. I'd forgotten that I'd done that, but the need keeps cropping up for me, so I posted again.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
May 14, 2021 May 14, 2021

Copy link to clipboard

Copied

Hi @mscureman 

For the origin, Photoshop uses the same widget that InDesign and Illustrator use (plus other DTP applications going back 30+ years). Click the reference point to indicate the postion, then type the W and H in the options bar.

jane-e_0-1621027219821.png

 

 

To move the zero point, drag from the intersection of the rulers. Double-click the intersection to put it back.

jane-e_1-1621027661728.png

 

~ Jane

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 14, 2021 May 14, 2021

Copy link to clipboard

Copied

Thanks Jane, but I'm aware of the ability to drag the origin point.  I realized that I'd already posted this request a year ago in the feedback forum, but the issue remains a problem for me for the reasons I listed in that post.

 

Set Ruler Origin Location in Preferences, New Document Dialog or Menu

 

Also, I'm not seeing that widget when I use the Shape Tool (which is what I'm assuming you're using in your photo).

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
May 14, 2021 May 14, 2021

Copy link to clipboard

Copied

 

I have found some JavaScript code that I should be able to extend to do what you are requesting...

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
May 15, 2021 May 15, 2021

Copy link to clipboard

Copied

 

I wanted to do so much more, however, I have hit problems (variables, scriptUI etc).

 

The following script will offer a horizontal and vertical prompt, where you can input pixel values. The default is upper left, absolute: 0, 0 (the default ruler origin zero point)

 

In the short term, it is simple enough to make 9 separate scripts for the various fixed positions on the canvas (middle centre, lower right etc). These could be recorded into an action for a "quick n dirty GUI" selector.

 

I'm sure it would also be possible to make the origin offset relative to the upper left of a selection, however that would be last on my list considering the other challenges that I have hit.

 

 

/* 

https://community.adobe.com/t5/photoshop/feature-request-set-origin-point/td-p/12037399
Feature Request: Set Origin Point

Set Ruler Origin to User Input.jsx
Version 1.0, 15th May 2021
Stephen Marsh

*/

#target photoshop
    
    if (app.documents.length > 0) {

    (function () {

        // Save the current ruler units and set to pixels
        var savedRuler = app.preferences.rulerUnits;
        app.preferences.rulerUnits = Units.PIXELS;

        ////////////////////////////// tom_ruark @ adobe //////////////////////////////

        /* https://feedback.photoshop.com/conversations/photoshop/photoshop-ability-to-ruler-origin-by-script/5f5f45bb4b561a3d425c7b32 */

        // Version 2016.11.18
        // Show how to get and set the ruler origin point for the current document
        // Values are in pixels shifted 16 bits
        // some constants to make it more readable

        const classProperty = app.stringIDToTypeID("property");
        const krulerOriginHStr = app.stringIDToTypeID("rulerOriginH");
        const krulerOriginVStr = app.stringIDToTypeID("rulerOriginV");
        const classDocument = app.stringIDToTypeID("document");
        const typeOrdinal = app.stringIDToTypeID("ordinal");
        const enumTarget = app.stringIDToTypeID("targetEnum");
        const typeNULL = app.stringIDToTypeID("null");
        const keyTo = app.stringIDToTypeID("to");
        const eventSet = app.stringIDToTypeID("set");

        // get the current values
        GetRulerOrigin().toSource();

        function GetRulerOrigin() {
            var ro = {};

            ro.horizontal = GetInfo(classDocument, krulerOriginHStr) >> 16;
            ro.vertical = GetInfo(classDocument, krulerOriginVStr) >> 16;

            return ro;
        }

        function SetRulerOrigin_Horiz(horiz) {
            var desc = new ActionDescriptor();
            var ref = new ActionReference();
            ref.putProperty(classProperty, krulerOriginHStr);
            ref.putEnumerated(classDocument, typeOrdinal, enumTarget);
            desc.putReference(typeNULL, ref);
            desc.putInteger(keyTo, horiz << 16);
            executeAction(eventSet, desc, DialogModes.NO);
        }

        function SetRulerOrigin_Vert(vert) {
            var desc = new ActionDescriptor();
            var ref = new ActionReference();
            ref.putProperty(classProperty, krulerOriginVStr);
            ref.putEnumerated(classDocument, typeOrdinal, enumTarget);
            desc.putReference(typeNULL, ref);
            desc.putInteger(keyTo, vert << 16);
            executeAction(eventSet, desc, DialogModes.NO);
        }

        ///////////////////////////////////////////////////////////////////////////////
        // Function: GetInfo
        // Usage:    Get information from Photoshop
        // Input:    desiredClass, classApplication, classLayer, etc.
        //           desiredKey, optional specific key to get instead of everything
        //           this is recommended as all keys is an expensive call
        // Return:   ActionDescriptor or single value depending on what is asked for
        ///////////////////////////////////////////////////////////////////////////////
        function GetInfo(desiredClass, desiredKey) {
            var reference = new ActionReference();
            if (typeof desiredKey != "undefined") {
                reference.putProperty(stringIDToTypeID("property"), desiredKey);
            }
            reference.putEnumerated(desiredClass, stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
            var desc = executeActionGet(reference);
            if (typeof desiredKey != "undefined") {
                return GetItemFromDescriptor(desc, desiredKey);
            }
            return desc;
        }

        ///////////////////////////////////////////////////////////////////////////////
        // Function: GetItemFromDescriptor
        // Usage:    Get a specific key from an ActionDescriptor
        // Input:    desc (ActionDescriptor), valid ActionDescriptor to pull info from
        //           desiredKey (Number), key in question, use charIDToTypeID() or
        //           stringIDToTypeID()
        // Return:   ActionDescriptor or single value depending on what is asked for
        ///////////////////////////////////////////////////////////////////////////////
        function GetItemFromDescriptor(desc, desiredKey) {
            if (desc.hasKey(desiredKey)) {
                var typeID = desc.getType(desiredKey);
                switch (typeID) {
                    case DescValueType.BOOLEANTYPE:
                        return desc.getBoolean(desiredKey);
                        break;
                    case DescValueType.STRINGTYPE:
                        return desc.getString(desiredKey);
                        break;
                    case DescValueType.DOUBLETYPE:
                        return desc.getDouble(desiredKey);
                        break;
                    case DescValueType.INTEGERTYPE:
                        return desc.getInteger(desiredKey);
                        break;
                    case DescValueType.LARGEINTEGERTYPE:
                        return desc.getLargeInteger(desiredKey);
                        break;
                    case DescValueType.OBJECTTYPE:
                        return desc.getObjectValue(desiredKey);
                        break;
                    case DescValueType.UNITDOUBLE:
                        var newT = desc.getUnitDoubleType(desiredKey);
                        var newV = desc.getUnitDoubleValue(desiredKey);
                        return new UnitValue(newV, newT);
                        break;
                    case DescValueType.ENUMERATEDTYPE:
                        return desc.getEnumerationValue(desiredKey);
                        break;
                    case DescValueType.CLASSTYPE:
                        return desc.getClass(desiredKey);
                        break;
                    case DescValueType.ALIASTYPE:
                        return desc.getPath(desiredKey);
                        break;
                    case DescValueType.RAWTYPE:
                        var tempStr = desc.getData(desiredKey);
                        var rawData = new Array();
                        for (var tempi = 0; tempi < tempStr.length; tempi++) {
                            rawData[tempi] = tempStr.charCodeAt(tempi);
                        }
                        return rawData;
                        break;
                    case DescValueType.REFERENCETYPE:
                        return desc.getReference(desiredKey);
                        break;
                    case DescValueType.LISTTYPE:
                        return desc.getList(desiredKey);
                        break;
                    default:
                        return;
                }
            }
            return;
        }

        // Reset ruler origin to zero for a known start point
        SetRulerOrigin_Horiz(0);
        SetRulerOrigin_Vert(0);

        ////////////////////////////// tom_ruark @ adobe //////////////////////////////

        // Horizontal Input
        // Loop the input prompt until a number is entered
        var horizInput;
        while (isNaN(horizInput = prompt("Horizontal origin in pixels:", "0")));
        // Test if cancel returns null, then terminate the script
        if (horizInput === null) {
            alert('Script cancelled!');
            return
        }
        // Test if an empty string is returned, then terminate the script 
        if (horizInput === "") {
            alert('A value was not entered, script cancelled!');
            return
        }
        // Convert decimal input to integer
        var horizToInteger = parseInt(horizInput);


        // Vertical Input
        // Loop the input prompt until a number is entered
        var vertInput;
        while (isNaN(vertInput = prompt("Vertical origin in pixels:", "0")));
        // Test if cancel returns null, then terminate the script
        if (vertInput === null) {
            alert('Script cancelled!');
            return
        }
        // Test if an empty string is returned, then terminate the script 
        if (vertInput === "") {
            alert('A value was not entered, script cancelled!');
            return
        }
        // Convert decimal input to integer
        var vertToInteger = parseInt(vertInput);

        // Set the origin from the prompts
        SetRulerOrigin_Horiz(horizToInteger);
        SetRulerOrigin_Vert(vertToInteger);

        // Restore the ruler units
        app.preferences.rulerUnits = savedRuler;
    })
        ();
        }

else {
    alert('A document must be open to use this script!');
}

 

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
May 15, 2021 May 15, 2021

Copy link to clipboard

Copied

 

I believe that I have overcome the previous "basic" challenges with adding the GUI to the script code...

 

SetRulerOrigin-v1_1.png

 

/* 

https://community.adobe.com/t5/photoshop/feature-request-set-origin-point/td-p/12037399
Feature Request: Set Origin Point

Set Ruler Origin to User Input.jsx
Version 1.1, 16th May 2021
Stephen Marsh

*/

#target photoshop

if (app.documents.length > 0) {
    // Save the current ruler units and set to pixels
    var savedRuler = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;

    /////////////////////////////// joonas scriptUI ///////////////////////////////

    /*
    Code for Import https://scriptui.joonas.me — (Triple click to select): 
    {"activeId":0,"items":{"item-0":{"id":0,"type":"Dialog","parentId":false,"style":{"enabled":true,"varName":"dialogWindow","windowType":"Dialog","creationProps":{"su1PanelCoordinates":false,"maximizeButton":false,"minimizeButton":false,"independent":false,"closeButton":false,"borderless":false,"resizeable":false},"text":"Set Ruler Origin","preferredSize":[410,100],"margins":15,"orientation":"row","spacing":10,"alignChildren":["left","top"]}},"item-2":{"id":2,"type":"Button","parentId":4,"style":{"enabled":true,"varName":"okButton","text":"OK","justify":"center","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-3":{"id":3,"type":"Button","parentId":4,"style":{"enabled":true,"varName":"cancelButton","text":"Cancel","justify":"center","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-4":{"id":4,"type":"Group","parentId":0,"style":{"enabled":true,"varName":"okGroup","preferredSize":[0,0],"margins":[1,1,1,10],"orientation":"column","spacing":12,"alignChildren":["left","top"],"alignment":"top"}},"item-5":{"id":5,"type":"Group","parentId":0,"style":{"enabled":true,"varName":"upperGroup","preferredSize":[0,0],"margins":0,"orientation":"column","spacing":10,"alignChildren":["left","center"],"alignment":null}},"item-6":{"id":6,"type":"RadioButton","parentId":5,"style":{"enabled":true,"varName":"upperLeft","text":"Upper Left","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-7":{"id":7,"type":"RadioButton","parentId":5,"style":{"enabled":true,"varName":"middleLeft","text":"Middle Left","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-8":{"id":8,"type":"RadioButton","parentId":5,"style":{"enabled":true,"varName":"lowerLeft","text":"Lower Left","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-9":{"id":9,"type":"Group","parentId":0,"style":{"enabled":true,"varName":"middleGroup","preferredSize":[0,0],"margins":0,"orientation":"column","spacing":10,"alignChildren":["left","center"],"alignment":null}},"item-10":{"id":10,"type":"RadioButton","parentId":9,"style":{"enabled":true,"varName":"upperCenter","text":"Upper Center","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-11":{"id":11,"type":"RadioButton","parentId":9,"style":{"enabled":true,"varName":"middleCenter","text":"Middle Center","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-12":{"id":12,"type":"RadioButton","parentId":9,"style":{"enabled":true,"varName":"lowerCenter","text":"Lower Center","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-13":{"id":13,"type":"Group","parentId":0,"style":{"enabled":true,"varName":"lowerGroup","preferredSize":[0,0],"margins":0,"orientation":"column","spacing":10,"alignChildren":["left","center"],"alignment":null}},"item-14":{"id":14,"type":"RadioButton","parentId":13,"style":{"enabled":true,"varName":"upperRight","text":"Upper Right","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-15":{"id":15,"type":"RadioButton","parentId":13,"style":{"enabled":true,"varName":"middleRight","text":"Middle Right","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-16":{"id":16,"type":"RadioButton","parentId":13,"style":{"enabled":true,"varName":"lowerRight","text":"Lower Right","preferredSize":[0,0],"alignment":null,"helpTip":null}}},"order":[0,5,6,7,8,9,10,11,12,13,14,15,16,4,2,3],"settings":{"importJSON":true,"indentSize":false,"cepExport":false,"includeCSSJS":true,"showDialog":true,"functionWrapper":false,"afterEffectsDockable":false,"itemReferenceList":"None"}}
    */

    // DIALOGWINDOW
    // ============
    var dialogWindow = new Window("dialog", undefined, undefined, { closeButton: false });
    dialogWindow.text = "Set Ruler Origin - v1.1";
    dialogWindow.preferredSize.width = 410;
    dialogWindow.preferredSize.height = 100;
    dialogWindow.orientation = "row";
    dialogWindow.alignChildren = ["left", "top"];
    dialogWindow.spacing = 10;
    dialogWindow.margins = 15;

    // UPPERGROUP
    // ==========
    var upperGroup = dialogWindow.add("group", undefined, { name: "upperGroup" });
    upperGroup.orientation = "column";
    upperGroup.alignChildren = ["left", "center"];
    upperGroup.spacing = 10;
    upperGroup.margins = 0;

    var upperLeft = upperGroup.add("radiobutton", undefined, undefined, { name: "upperLeft" });
    upperLeft.text = "Upper Left";

    var middleLeft = upperGroup.add("radiobutton", undefined, undefined, { name: "middleLeft" });
    middleLeft.text = "Middle Left";

    var lowerLeft = upperGroup.add("radiobutton", undefined, undefined, { name: "lowerLeft" });
    lowerLeft.text = "Lower Left";

    ////////////////////// peter kahrel scriptUI for dummies //////////////////////
    // Preset the upper left  radiobutton as active
    upperGroup.children[0].value = true;
    ////////////////////// peter kahrel scriptUI for dummies //////////////////////

    // MIDDLEGROUP
    // ===========
    var middleGroup = dialogWindow.add("group", undefined, { name: "middleGroup" });
    middleGroup.orientation = "column";
    middleGroup.alignChildren = ["left", "center"];
    middleGroup.spacing = 10;
    middleGroup.margins = 0;

    var upperCenter = middleGroup.add("radiobutton", undefined, undefined, { name: "upperCenter" });
    upperCenter.text = "Upper Center";

    var middleCenter = middleGroup.add("radiobutton", undefined, undefined, { name: "middleCenter" });
    middleCenter.text = "Middle Center";

    var lowerCenter = middleGroup.add("radiobutton", undefined, undefined, { name: "lowerCenter" });
    lowerCenter.text = "Lower Center";

    // LOWERGROUP
    // ==========
    var lowerGroup = dialogWindow.add("group", undefined, { name: "lowerGroup" });
    lowerGroup.orientation = "column";
    lowerGroup.alignChildren = ["left", "center"];
    lowerGroup.spacing = 10;
    lowerGroup.margins = 0;

    var upperRight = lowerGroup.add("radiobutton", undefined, undefined, { name: "upperRight" });
    upperRight.text = "Upper Right";

    var middleRight = lowerGroup.add("radiobutton", undefined, undefined, { name: "middleRight" });
    middleRight.text = "Middle Right";

    var lowerRight = lowerGroup.add("radiobutton", undefined, undefined, { name: "lowerRight" });
    lowerRight.text = "Lower Right";

    // OKGROUP
    // =======
    var okGroup = dialogWindow.add("group", undefined, { name: "okGroup" });
    okGroup.orientation = "column";
    okGroup.alignChildren = ["left", "top"];
    okGroup.spacing = 12;
    okGroup.margins = [10, 1, 1, 1];
    okGroup.alignment = ["left", "top"];

    var okButton = okGroup.add("button", undefined, undefined, { name: "okButton" });
    okButton.text = "OK";

    var cancelButton = okGroup.add("button", undefined, undefined, { name: "cancelButton" });
    cancelButton.text = "Cancel";

    /////////////////////////////// joonas scriptUI ///////////////////////////////

    ////////////////////////////// tom_ruark @ adobe //////////////////////////////

    /* https://feedback.photoshop.com/conversations/photoshop/photoshop-ability-to-ruler-origin-by-script/5f5f45bb4b561a3d425c7b32 */

    // Version 2016.11.18
    // Show how to get and set the ruler origin point for the current document
    // Values are in pixels shifted 16 bits
    // some constants to make it more readable

    const classProperty = app.stringIDToTypeID("property");
    const krulerOriginHStr = app.stringIDToTypeID("rulerOriginH");
    const krulerOriginVStr = app.stringIDToTypeID("rulerOriginV");
    const classDocument = app.stringIDToTypeID("document");
    const typeOrdinal = app.stringIDToTypeID("ordinal");
    const enumTarget = app.stringIDToTypeID("targetEnum");
    const typeNULL = app.stringIDToTypeID("null");
    const keyTo = app.stringIDToTypeID("to");
    const eventSet = app.stringIDToTypeID("set");

    // get the current values
    GetRulerOrigin().toSource();

    function GetRulerOrigin() {
        var ro = {};

        ro.horizontal = GetInfo(classDocument, krulerOriginHStr) >> 16;
        ro.vertical = GetInfo(classDocument, krulerOriginVStr) >> 16;

        return ro;
    }

    function SetRulerOrigin_Horiz(horiz) {
        var desc = new ActionDescriptor();
        var ref = new ActionReference();
        ref.putProperty(classProperty, krulerOriginHStr);
        ref.putEnumerated(classDocument, typeOrdinal, enumTarget);
        desc.putReference(typeNULL, ref);
        desc.putInteger(keyTo, horiz << 16);
        executeAction(eventSet, desc, DialogModes.NO);
    }

    function SetRulerOrigin_Vert(vert) {
        var desc = new ActionDescriptor();
        var ref = new ActionReference();
        ref.putProperty(classProperty, krulerOriginVStr);
        ref.putEnumerated(classDocument, typeOrdinal, enumTarget);
        desc.putReference(typeNULL, ref);
        desc.putInteger(keyTo, vert << 16);
        executeAction(eventSet, desc, DialogModes.NO);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function: GetInfo
    // Usage:    Get information from Photoshop
    // Input:    desiredClass, classApplication, classLayer, etc.
    //   desiredKey, optional specific key to get instead of everything
    //   this is recommended as all keys is an expensive call
    // Return:   ActionDescriptor or single value depending on what is asked for
    ///////////////////////////////////////////////////////////////////////////////
    function GetInfo(desiredClass, desiredKey) {
        var reference = new ActionReference();
        if (typeof desiredKey != "undefined") {
            reference.putProperty(stringIDToTypeID("property"), desiredKey);
        }
        reference.putEnumerated(desiredClass, stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
        var desc = executeActionGet(reference);
        if (typeof desiredKey != "undefined") {
            return GetItemFromDescriptor(desc, desiredKey);
        }
        return desc;
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function: GetItemFromDescriptor
    // Usage:    Get a specific key from an ActionDescriptor
    // Input:    desc (ActionDescriptor), valid ActionDescriptor to pull info from
    //   desiredKey (Number), key in question, use charIDToTypeID() or
    //   stringIDToTypeID()
    // Return:   ActionDescriptor or single value depending on what is asked for
    ///////////////////////////////////////////////////////////////////////////////
    function GetItemFromDescriptor(desc, desiredKey) {
        if (desc.hasKey(desiredKey)) {
            var typeID = desc.getType(desiredKey);
            switch (typeID) {
                case DescValueType.BOOLEANTYPE:
                    return desc.getBoolean(desiredKey);
                    break;
                case DescValueType.STRINGTYPE:
                    return desc.getString(desiredKey);
                    break;
                case DescValueType.DOUBLETYPE:
                    return desc.getDouble(desiredKey);
                    break;
                case DescValueType.INTEGERTYPE:
                    return desc.getInteger(desiredKey);
                    break;
                case DescValueType.LARGEINTEGERTYPE:
                    return desc.getLargeInteger(desiredKey);
                    break;
                case DescValueType.OBJECTTYPE:
                    return desc.getObjectValue(desiredKey);
                    break;
                case DescValueType.UNITDOUBLE:
                    var newT = desc.getUnitDoubleType(desiredKey);
                    var newV = desc.getUnitDoubleValue(desiredKey);
                    return new UnitValue(newV, newT);
                    break;
                case DescValueType.ENUMERATEDTYPE:
                    return desc.getEnumerationValue(desiredKey);
                    break;
                case DescValueType.CLASSTYPE:
                    return desc.getClass(desiredKey);
                    break;
                case DescValueType.ALIASTYPE:
                    return desc.getPath(desiredKey);
                    break;
                case DescValueType.RAWTYPE:
                    var tempStr = desc.getData(desiredKey);
                    var rawData = new Array();
                    for (var tempi = 0; tempi < tempStr.length; tempi++) {
                        rawData[tempi] = tempStr.charCodeAt(tempi);
                    }
                    return rawData;
                    break;
                case DescValueType.REFERENCETYPE:
                    return desc.getReference(desiredKey);
                    break;
                case DescValueType.LISTTYPE:
                    return desc.getList(desiredKey);
                    break;
                default:
                    return;
            }
        }
        return;
    }
    ////////////////////////////// tom_ruark @ adobe //////////////////////////////

    /////////////////////////////// joonas scriptUI ///////////////////////////////

    okButton.onClick = function () {
        dialogWindow.close();

        // Canvas variables
        var rE = app.activeDocument.width; // rightEdge
        var hC = app.activeDocument.width / 2; // horizontalCenter
        var vC = app.activeDocument.height / 2; // verticalCenter
        var bE = app.activeDocument.height; // bottomEdge

        // Link function parameters to radio buttons

        if (upperLeft.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
        }

        if (upperCenter.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(hC);
            SetRulerOrigin_Vert(0);
        }

        if (upperRight.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(rE);
            SetRulerOrigin_Vert(0);
        }

        if (middleLeft.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(vC);
        }

        if (middleCenter.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(hC);
            SetRulerOrigin_Vert(vC);
        }

        if (middleRight.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(rE);
            SetRulerOrigin_Vert(vC);
        }

        if (lowerLeft.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(bE);
        }

        if (lowerCenter.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(hC);
            SetRulerOrigin_Vert(bE);
        }

        if (lowerRight.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(rE);
            SetRulerOrigin_Vert(bE);
        }
    }

    // Execute window
    dialogWindow.show();

    /////////////////////////////// joonas scriptUI ///////////////////////////////

    // Restore the ruler units
    app.preferences.rulerUnits = savedRuler;
}

else {
    alert('A document must be open to use this script!');
}

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
May 15, 2021 May 15, 2021

Copy link to clipboard

Copied

NOTE: I can't edit my previous post, it just comes up with a blank field (I have tried two different browsers on the Mac).  Strangely, I can edit this post, go figure!

 

A revised 1.2 version is below, which fixes the issues with the radio button groups in the 1.1 code!

 

/* 

https://community.adobe.com/t5/photoshop/feature-request-set-origin-point/td-p/12037399
Feature Request: Set Origin Point

Set Ruler Origin to User Input.jsx
Version 1.2, 16th May 2021
Stephen Marsh

*/

#target photoshop

if (app.documents.length > 0) {
    // Save the current ruler units and set to pixels
    var savedRuler = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;

    /////////////////////////////// joonas scriptUI ///////////////////////////////

    /*
    Code for Import https://scriptui.joonas.me — (Triple click to select): 
    {"activeId":0,"items":{"item-0":{"id":0,"type":"Dialog","parentId":false,"style":{"enabled":true,"varName":"dialogWindow","windowType":"Dialog","creationProps":{"su1PanelCoordinates":false,"maximizeButton":false,"minimizeButton":false,"independent":false,"closeButton":false,"borderless":false,"resizeable":false},"text":"Set Ruler Origin","preferredSize":[410,100],"margins":15,"orientation":"row","spacing":10,"alignChildren":["left","top"]}},"item-2":{"id":2,"type":"Button","parentId":4,"style":{"enabled":true,"varName":"okButton","text":"OK","justify":"center","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-3":{"id":3,"type":"Button","parentId":4,"style":{"enabled":true,"varName":"cancelButton","text":"Cancel","justify":"center","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-4":{"id":4,"type":"Group","parentId":0,"style":{"enabled":true,"varName":"okGroup","preferredSize":[0,0],"margins":[1,1,1,10],"orientation":"column","spacing":12,"alignChildren":["left","top"],"alignment":"top"}},"item-5":{"id":5,"type":"Group","parentId":0,"style":{"enabled":true,"varName":"upperGroup","preferredSize":[0,0],"margins":0,"orientation":"column","spacing":10,"alignChildren":["left","center"],"alignment":null}},"item-6":{"id":6,"type":"RadioButton","parentId":5,"style":{"enabled":true,"varName":"upperLeft","text":"Upper Left","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-7":{"id":7,"type":"RadioButton","parentId":5,"style":{"enabled":true,"varName":"middleLeft","text":"Middle Left","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-8":{"id":8,"type":"RadioButton","parentId":5,"style":{"enabled":true,"varName":"lowerLeft","text":"Lower Left","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-9":{"id":9,"type":"Group","parentId":0,"style":{"enabled":true,"varName":"middleGroup","preferredSize":[0,0],"margins":0,"orientation":"column","spacing":10,"alignChildren":["left","center"],"alignment":null}},"item-10":{"id":10,"type":"RadioButton","parentId":9,"style":{"enabled":true,"varName":"upperCenter","text":"Upper Center","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-11":{"id":11,"type":"RadioButton","parentId":9,"style":{"enabled":true,"varName":"middleCenter","text":"Middle Center","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-12":{"id":12,"type":"RadioButton","parentId":9,"style":{"enabled":true,"varName":"lowerCenter","text":"Lower Center","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-13":{"id":13,"type":"Group","parentId":0,"style":{"enabled":true,"varName":"lowerGroup","preferredSize":[0,0],"margins":0,"orientation":"column","spacing":10,"alignChildren":["left","center"],"alignment":null}},"item-14":{"id":14,"type":"RadioButton","parentId":13,"style":{"enabled":true,"varName":"upperRight","text":"Upper Right","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-15":{"id":15,"type":"RadioButton","parentId":13,"style":{"enabled":true,"varName":"middleRight","text":"Middle Right","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-16":{"id":16,"type":"RadioButton","parentId":13,"style":{"enabled":true,"varName":"lowerRight","text":"Lower Right","preferredSize":[0,0],"alignment":null,"helpTip":null}}},"order":[0,5,6,7,8,9,10,11,12,13,14,15,16,4,2,3],"settings":{"importJSON":true,"indentSize":false,"cepExport":false,"includeCSSJS":true,"showDialog":true,"functionWrapper":false,"afterEffectsDockable":false,"itemReferenceList":"None"}}
    */

    // DIALOGWINDOW
    // ============
    var dialogWindow = new Window("dialog", undefined, undefined, { closeButton: false });
    dialogWindow.text = "Set Ruler Origin - v1.1";
    dialogWindow.preferredSize.width = 410;
    dialogWindow.preferredSize.height = 100;
    dialogWindow.orientation = "row";
    dialogWindow.alignChildren = ["left", "top"];
    dialogWindow.spacing = 10;
    dialogWindow.margins = 15;

    // UPPERGROUP
    // ==========
    var upperGroup = dialogWindow.add("group", undefined, { name: "upperGroup" });
    upperGroup.orientation = "column";
    upperGroup.alignChildren = ["left", "center"];
    upperGroup.spacing = 10;
    upperGroup.margins = 0;

    var upperLeft = upperGroup.add("radiobutton", undefined, undefined, { name: "upperLeft" });
    upperLeft.text = "Upper Left";

    var middleLeft = upperGroup.add("radiobutton", undefined, undefined, { name: "middleLeft" });
    middleLeft.text = "Middle Left";

    var lowerLeft = upperGroup.add("radiobutton", undefined, undefined, { name: "lowerLeft" });
    lowerLeft.text = "Lower Left";

    ////////////////////// peter kahrel scriptUI for dummies //////////////////////
    // Preset the upper left  radiobutton as active
    upperGroup.children[0].value = true;
    ////////////////////// peter kahrel scriptUI for dummies //////////////////////

    // MIDDLEGROUP
    // ===========
    var middleGroup = dialogWindow.add("group", undefined, { name: "middleGroup" });
    middleGroup.orientation = "column";
    middleGroup.alignChildren = ["left", "center"];
    middleGroup.spacing = 10;
    middleGroup.margins = 0;

    var upperCenter = middleGroup.add("radiobutton", undefined, undefined, { name: "upperCenter" });
    upperCenter.text = "Upper Center";

    var middleCenter = middleGroup.add("radiobutton", undefined, undefined, { name: "middleCenter" });
    middleCenter.text = "Middle Center";

    var lowerCenter = middleGroup.add("radiobutton", undefined, undefined, { name: "lowerCenter" });
    lowerCenter.text = "Lower Center";

    // LOWERGROUP
    // ==========
    var lowerGroup = dialogWindow.add("group", undefined, { name: "lowerGroup" });
    lowerGroup.orientation = "column";
    lowerGroup.alignChildren = ["left", "center"];
    lowerGroup.spacing = 10;
    lowerGroup.margins = 0;

    var upperRight = lowerGroup.add("radiobutton", undefined, undefined, { name: "upperRight" });
    upperRight.text = "Upper Right";

    var middleRight = lowerGroup.add("radiobutton", undefined, undefined, { name: "middleRight" });
    middleRight.text = "Middle Right";

    var lowerRight = lowerGroup.add("radiobutton", undefined, undefined, { name: "lowerRight" });
    lowerRight.text = "Lower Right";

    ////////////////////// peter kahrel scriptUI for dummies //////////////////////
    upperGroup.addEventListener("click", function () {
        for (var i = 0; i < middleGroup.children.length; i++)
            middleGroup.children[i].value = false;
    }
    );
    upperGroup.addEventListener("click", function () {
        for (var i = 0; i < lowerGroup.children.length; i++)
            lowerGroup.children[i].value = false;
    }
    );

    middleGroup.addEventListener("click", function () {
        for (var i = 0; i < upperGroup.children.length; i++)
            upperGroup.children[i].value = false;
    }
    );
    middleGroup.addEventListener("click", function () {
        for (var i = 0; i < lowerGroup.children.length; i++)
            lowerGroup.children[i].value = false;
    }
    );

    lowerGroup.addEventListener("click", function () {
        for (var i = 0; i < middleGroup.children.length; i++)
            middleGroup.children[i].value = false;
    }
    );
    lowerGroup.addEventListener("click", function () {
        for (var i = 0; i < upperGroup.children.length; i++)
            upperGroup.children[i].value = false;
    }
    );
    ////////////////////// peter kahrel scriptUI for dummies //////////////////////

    /////////////////////////////// joonas scriptUI ///////////////////////////////

    // OKGROUP
    // =======
    var okGroup = dialogWindow.add("group", undefined, { name: "okGroup" });
    okGroup.orientation = "column";
    okGroup.alignChildren = ["left", "top"];
    okGroup.spacing = 12;
    okGroup.margins = [10, 1, 1, 1];
    okGroup.alignment = ["left", "top"];

    var okButton = okGroup.add("button", undefined, undefined, { name: "okButton" });
    okButton.text = "OK";

    var cancelButton = okGroup.add("button", undefined, undefined, { name: "cancelButton" });
    cancelButton.text = "Cancel";

    /////////////////////////////// joonas scriptUI ///////////////////////////////


    ////////////////////////////// tom_ruark @ adobe //////////////////////////////

    /* https://feedback.photoshop.com/conversations/photoshop/photoshop-ability-to-ruler-origin-by-script/5f5f45bb4b561a3d425c7b32 */

    // Version 2016.11.18
    // Show how to get and set the ruler origin point for the current document
    // Values are in pixels shifted 16 bits
    // some constants to make it more readable

    const classProperty = app.stringIDToTypeID("property");
    const krulerOriginHStr = app.stringIDToTypeID("rulerOriginH");
    const krulerOriginVStr = app.stringIDToTypeID("rulerOriginV");
    const classDocument = app.stringIDToTypeID("document");
    const typeOrdinal = app.stringIDToTypeID("ordinal");
    const enumTarget = app.stringIDToTypeID("targetEnum");
    const typeNULL = app.stringIDToTypeID("null");
    const keyTo = app.stringIDToTypeID("to");
    const eventSet = app.stringIDToTypeID("set");

    // get the current values
    GetRulerOrigin().toSource();

    function GetRulerOrigin() {
        var ro = {};

        ro.horizontal = GetInfo(classDocument, krulerOriginHStr) >> 16;
        ro.vertical = GetInfo(classDocument, krulerOriginVStr) >> 16;

        return ro;
    }

    function SetRulerOrigin_Horiz(horiz) {
        var desc = new ActionDescriptor();
        var ref = new ActionReference();
        ref.putProperty(classProperty, krulerOriginHStr);
        ref.putEnumerated(classDocument, typeOrdinal, enumTarget);
        desc.putReference(typeNULL, ref);
        desc.putInteger(keyTo, horiz << 16);
        executeAction(eventSet, desc, DialogModes.NO);
    }

    function SetRulerOrigin_Vert(vert) {
        var desc = new ActionDescriptor();
        var ref = new ActionReference();
        ref.putProperty(classProperty, krulerOriginVStr);
        ref.putEnumerated(classDocument, typeOrdinal, enumTarget);
        desc.putReference(typeNULL, ref);
        desc.putInteger(keyTo, vert << 16);
        executeAction(eventSet, desc, DialogModes.NO);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function: GetInfo
    // Usage:    Get information from Photoshop
    // Input:    desiredClass, classApplication, classLayer, etc.
    //   desiredKey, optional specific key to get instead of everything
    //   this is recommended as all keys is an expensive call
    // Return:   ActionDescriptor or single value depending on what is asked for
    ///////////////////////////////////////////////////////////////////////////////
    function GetInfo(desiredClass, desiredKey) {
        var reference = new ActionReference();
        if (typeof desiredKey != "undefined") {
            reference.putProperty(stringIDToTypeID("property"), desiredKey);
        }
        reference.putEnumerated(desiredClass, stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
        var desc = executeActionGet(reference);
        if (typeof desiredKey != "undefined") {
            return GetItemFromDescriptor(desc, desiredKey);
        }
        return desc;
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function: GetItemFromDescriptor
    // Usage:    Get a specific key from an ActionDescriptor
    // Input:    desc (ActionDescriptor), valid ActionDescriptor to pull info from
    //   desiredKey (Number), key in question, use charIDToTypeID() or
    //   stringIDToTypeID()
    // Return:   ActionDescriptor or single value depending on what is asked for
    ///////////////////////////////////////////////////////////////////////////////
    function GetItemFromDescriptor(desc, desiredKey) {
        if (desc.hasKey(desiredKey)) {
            var typeID = desc.getType(desiredKey);
            switch (typeID) {
                case DescValueType.BOOLEANTYPE:
                    return desc.getBoolean(desiredKey);
                    break;
                case DescValueType.STRINGTYPE:
                    return desc.getString(desiredKey);
                    break;
                case DescValueType.DOUBLETYPE:
                    return desc.getDouble(desiredKey);
                    break;
                case DescValueType.INTEGERTYPE:
                    return desc.getInteger(desiredKey);
                    break;
                case DescValueType.LARGEINTEGERTYPE:
                    return desc.getLargeInteger(desiredKey);
                    break;
                case DescValueType.OBJECTTYPE:
                    return desc.getObjectValue(desiredKey);
                    break;
                case DescValueType.UNITDOUBLE:
                    var newT = desc.getUnitDoubleType(desiredKey);
                    var newV = desc.getUnitDoubleValue(desiredKey);
                    return new UnitValue(newV, newT);
                    break;
                case DescValueType.ENUMERATEDTYPE:
                    return desc.getEnumerationValue(desiredKey);
                    break;
                case DescValueType.CLASSTYPE:
                    return desc.getClass(desiredKey);
                    break;
                case DescValueType.ALIASTYPE:
                    return desc.getPath(desiredKey);
                    break;
                case DescValueType.RAWTYPE:
                    var tempStr = desc.getData(desiredKey);
                    var rawData = new Array();
                    for (var tempi = 0; tempi < tempStr.length; tempi++) {
                        rawData[tempi] = tempStr.charCodeAt(tempi);
                    }
                    return rawData;
                    break;
                case DescValueType.REFERENCETYPE:
                    return desc.getReference(desiredKey);
                    break;
                case DescValueType.LISTTYPE:
                    return desc.getList(desiredKey);
                    break;
                default:
                    return;
            }
        }
        return;
    }
    ////////////////////////////// tom_ruark @ adobe //////////////////////////////

    /////////////////////////////// joonas scriptUI ///////////////////////////////

    okButton.onClick = function () {
        dialogWindow.close();

        // Canvas variables
        var rE = app.activeDocument.width; // rightEdge
        var hC = app.activeDocument.width / 2; // horizontalCenter
        var vC = app.activeDocument.height / 2; // verticalCenter
        var bE = app.activeDocument.height; // bottomEdge

        // Link function parameters to radio buttons

        if (upperLeft.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
        }

        if (upperCenter.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(hC);
            SetRulerOrigin_Vert(0);
        }

        if (upperRight.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(rE);
            SetRulerOrigin_Vert(0);
        }

        if (middleLeft.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(vC);
        }

        if (middleCenter.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(hC);
            SetRulerOrigin_Vert(vC);
        }

        if (middleRight.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(rE);
            SetRulerOrigin_Vert(vC);
        }

        if (lowerLeft.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(bE);
        }

        if (lowerCenter.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(hC);
            SetRulerOrigin_Vert(bE);
        }

        if (lowerRight.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(rE);
            SetRulerOrigin_Vert(bE);
        }
    }

    // Execute window
    dialogWindow.show();

    /////////////////////////////// joonas scriptUI ///////////////////////////////

    // Restore the ruler units
    app.preferences.rulerUnits = savedRuler;
}

else {
    alert('A document must be open to use this script!');
}

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
May 15, 2021 May 15, 2021

Copy link to clipboard

Copied

I worked out a wee workaround a few years ago after having problems with free transform step and repeat.  I was making a clock face, and because the origin point will not snap to a guide intersection, by the time you'd made your twelve FT rotations the build up of error was causing visible misalignment. 

 

I realsed that while the origin would not snap to a guide interesction, it would snap to a pixel location, so the answer was to place the guides and drag the grid zero to the guide intersection, (that does snap).  Then when using FT rotate, Alt drag the origin close to 0,0 and then correct it in the Options bar.  If you then use step and repeat 12 times, the last one will align perfectly with the first.

image.png

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
May 15, 2021 May 15, 2021

Copy link to clipboard

Copied

I've worded that wrong.  The origin does not snap to the grid zoro, zero, but the grid 0,0 will snap to the guide interection.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
May 19, 2021 May 19, 2021

Copy link to clipboard

Copied

If you hold down the Shift key while moving the Point of Orin it will snap to the ruler tick marks.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
May 15, 2021 May 15, 2021

Copy link to clipboard

Copied

NOTE: It appears that adding the joonas JSON code makes the previous scripts that I posted uneditable with this forum software, good to know!

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
May 18, 2021 May 18, 2021

Copy link to clipboard

Copied

Is there any interest in extending the previous script to offer X/Y co-ordinate entry fields, in addition to the 9 preset locations?

 

radiobuttons-plus-fields.png

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
May 19, 2021 May 19, 2021

Copy link to clipboard

Copied

LATEST

Here is a new 1.3 version, including X & Y entry fields in addition to the original 9 preset locations. The intention/expectation is that either the radio buttons are used, or the fields are used instead - not both at the same time.  There may be a way to make the use of one disable the other?

 

Set-Ruler-Origin-to-User-Input-GUI.jsx

Set-Ruler-Origin-to-User-Input-GUI.jsx

Set Ruler Origin to User Input v1-3.png

 

/* 
https://community.adobe.com/t5/photoshop/feature-request-set-origin-point/td-p/12037399
Feature Request: Set Origin Point

Set Ruler Origin to User Input.jsx
Version 1.3, 19th May 2021
Stephen Marsh
*/

#target photoshop

if (app.documents.length > 0) {

    // Save the current ruler units and set to pixels
    var savedRuler = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;

    /////////////////////////////// joonas scriptUI ///////////////////////////////

    // DIALOGWINDOW
    // ============
    var dialogWindow = new Window("dialog", undefined, undefined, {
        closeButton: false
    });
    dialogWindow.text = "Set Ruler Origin - v1.3"; // Remember to update this to match the header!
    dialogWindow.preferredSize.width = 410;
    dialogWindow.preferredSize.height = 100;
    dialogWindow.orientation = "row";
    dialogWindow.alignChildren = ["left", "center"];
    dialogWindow.spacing = 10;
    dialogWindow.margins = 15;

    // GROUP1
    // ======
    var group1 = dialogWindow.add("group", undefined, {
        name: "group1"
    });
    group1.orientation = "row";
    group1.alignChildren = ["left", "center"];
    group1.spacing = 10;
    group1.margins = 0;

    // UPPERGROUP
    // ==========
    var upperGroup = group1.add("group", undefined, {
        name: "upperGroup"
    });
    upperGroup.orientation = "column";
    upperGroup.alignChildren = ["left", "center"];
    upperGroup.spacing = 10;
    upperGroup.margins = 0;

    var upperLeft = upperGroup.add("radiobutton", undefined, undefined, {
        name: "upperLeft"
    });
    upperLeft.text = "Upper Left";
    upperLeft.helpTip = "Radio buttons override the X & Y fields";


    var middleLeft = upperGroup.add("radiobutton", undefined, undefined, {
        name: "middleLeft"
    });
    middleLeft.text = "Middle Left";
    middleLeft.helpTip = "Radio buttons override the X & Y fields";


    var lowerLeft = upperGroup.add("radiobutton", undefined, undefined, {
        name: "lowerLeft"
    });
    lowerLeft.text = "Lower Left";
    lowerLeft.helpTip = "Radio buttons override the X & Y fields";

    // MIDDLEGROUP
    // ===========
    var middleGroup = group1.add("group", undefined, {
        name: "middleGroup"
    });
    middleGroup.orientation = "column";
    middleGroup.alignChildren = ["left", "center"];
    middleGroup.spacing = 10;
    middleGroup.margins = 0;

    var upperCenter = middleGroup.add("radiobutton", undefined, undefined, {
        name: "upperCenter"
    });
    upperCenter.text = "Upper Center";
    upperCenter.helpTip = "Radio buttons override the X & Y fields";

    var middleCenter = middleGroup.add("radiobutton", undefined, undefined, {
        name: "middleCenter"
    });
    middleCenter.text = "Middle Center";
    middleCenter.helpTip = "Radio buttons override the X & Y fields";

    var lowerCenter = middleGroup.add("radiobutton", undefined, undefined, {
        name: "lowerCenter"
    });
    lowerCenter.text = "Lower Center";
    lowerCenter.helpTip = "Radio buttons override the X & Y fields";

    // LOWERGROUP
    // ==========
    var lowerGroup = group1.add("group", undefined, {
        name: "lowerGroup"
    });
    lowerGroup.orientation = "column";
    lowerGroup.alignChildren = ["left", "center"];
    lowerGroup.spacing = 10;
    lowerGroup.margins = 0;

    var upperRight = lowerGroup.add("radiobutton", undefined, undefined, {
        name: "upperRight"
    });
    upperRight.text = "Upper Right";
    upperRight.helpTip = "Radio buttons override the X & Y fields";

    var middleRight = lowerGroup.add("radiobutton", undefined, undefined, {
        name: "middleRight"
    });
    middleRight.text = "Middle Right";
    middleRight.helpTip = "Radio buttons override the X & Y fields";

    var lowerRight = lowerGroup.add("radiobutton", undefined, undefined, {
        name: "lowerRight"
    });
    lowerRight.text = "Lower Right";
    lowerRight.helpTip = "Radio buttons override the X & Y fields";

    // XYGROUP
    // =======
    var xyGroup = dialogWindow.add("group", undefined, {
        name: "xyGroup"
    });
    xyGroup.orientation = "row";
    xyGroup.alignChildren = ["left", "center"];
    xyGroup.spacing = 0;
    xyGroup.margins = [0, 0, 0, 0];
    xyGroup.alignment = ["left", "center"];

    // XYPANEL
    // =======
    var xyPanel = xyGroup.add("panel", undefined, undefined, {
        name: "xyPanel"
    });
    xyPanel.text = "X & Y Position";
    xyPanel.orientation = "column";
    xyPanel.alignChildren = ["left", "center"];
    xyPanel.spacing = 5;
    xyPanel.margins = [10, 10, 10, 10];
    xyPanel.alignment = ["left", "center"];

    var xValue = xyPanel.add('edittext {properties: {name: "xValue"}}');
    xValue.helpTip = "Enter the X value";
    xValue.preferredSize.width = 75;
    xValue.text = "";
    // Call the function to imit keyboard entry to digits
    xyPanel.xValue.addEventListener('keydown', NumericEditKeyboardHandler);

    ////////////////////// peter kahrel scriptUI for dummies //////////////////////
    // Preset the X field as active
    xValue.active = true;
    ////////////////////// peter kahrel scriptUI for dummies //////////////////////

    var yValue = xyPanel.add('edittext {properties: {name: "yValue"}}');
    yValue.helpTip = "Enter the Y value";
    yValue.preferredSize.width = 75;
    yValue.text = "";
    // Call the function to imit keyboard entry to digits
    xyPanel.yValue.addEventListener('keydown', NumericEditKeyboardHandler);

    ////////////////////// peter kahrel scriptUI for dummies //////////////////////
    // Make multiple groups act as one group
    upperGroup.addEventListener("click", function () {
        for (var i = 0; i < middleGroup.children.length; i++)
            middleGroup.children[i].value = false;
    });
    upperGroup.addEventListener("click", function () {
        for (var i = 0; i < lowerGroup.children.length; i++)
            lowerGroup.children[i].value = false;
    });

    middleGroup.addEventListener("click", function () {
        for (var i = 0; i < upperGroup.children.length; i++)
            upperGroup.children[i].value = false;
    });
    middleGroup.addEventListener("click", function () {
        for (var i = 0; i < lowerGroup.children.length; i++)
            lowerGroup.children[i].value = false;
    });

    lowerGroup.addEventListener("click", function () {
        for (var i = 0; i < middleGroup.children.length; i++)
            middleGroup.children[i].value = false;
    });
    lowerGroup.addEventListener("click", function () {
        for (var i = 0; i < upperGroup.children.length; i++)
            upperGroup.children[i].value = false;
    });
    ////////////////////// peter kahrel scriptUI for dummies //////////////////////

    /////////////////////////////// joonas scriptUI ///////////////////////////////
    // OKGROUP
    // =======
    var okGroup = dialogWindow.add("group", undefined, {
        name: "okGroup"
    });
    okGroup.orientation = "column";
    okGroup.alignChildren = ["left", "center"];
    okGroup.spacing = 12;
    okGroup.margins = [1, 1, 1, 1];
    okGroup.alignment = ["left", "center"];

    var okButton = okGroup.add("button", undefined, undefined, {
        name: "okButton"
    });
    okButton.text = "OK";

    var cancelButton = okGroup.add("button", undefined, undefined, {
        name: "cancelButton"
    });
    cancelButton.text = "Cancel";
    /////////////////////////////// joonas scriptUI ///////////////////////////////

    ////////////////////////////// tom_ruark @ adobe //////////////////////////////
    /* https://feedback.photoshop.com/conversations/photoshop/photoshop-ability-to-ruler-origin-by-script/5f5f45bb4b561a3d425c7b32 */
    // Version 2016.11.18
    // Show how to get and set the ruler origin point for the current document
    // Values are in pixels shifted 16 bits
    // some constants to make it more readable

    const classProperty = app.stringIDToTypeID("property");
    const krulerOriginHStr = app.stringIDToTypeID("rulerOriginH");
    const krulerOriginVStr = app.stringIDToTypeID("rulerOriginV");
    const classDocument = app.stringIDToTypeID("document");
    const typeOrdinal = app.stringIDToTypeID("ordinal");
    const enumTarget = app.stringIDToTypeID("targetEnum");
    const typeNULL = app.stringIDToTypeID("null");
    const keyTo = app.stringIDToTypeID("to");
    const eventSet = app.stringIDToTypeID("set");

    // get the current values
    GetRulerOrigin().toSource();

    function GetRulerOrigin() {
        var ro = {};
        ro.horizontal = GetInfo(classDocument, krulerOriginHStr) >> 16;
        ro.vertical = GetInfo(classDocument, krulerOriginVStr) >> 16;
        return ro;
    }

    function SetRulerOrigin_Horiz(horiz) {
        var desc = new ActionDescriptor();
        var ref = new ActionReference();
        ref.putProperty(classProperty, krulerOriginHStr);
        ref.putEnumerated(classDocument, typeOrdinal, enumTarget);
        desc.putReference(typeNULL, ref);
        desc.putInteger(keyTo, horiz << 16);
        executeAction(eventSet, desc, DialogModes.NO);
    }

    function SetRulerOrigin_Vert(vert) {
        var desc = new ActionDescriptor();
        var ref = new ActionReference();
        ref.putProperty(classProperty, krulerOriginVStr);
        ref.putEnumerated(classDocument, typeOrdinal, enumTarget);
        desc.putReference(typeNULL, ref);
        desc.putInteger(keyTo, vert << 16);
        executeAction(eventSet, desc, DialogModes.NO);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function: GetInfo
    // Usage:    Get information from Photoshop
    // Input:    desiredClass, classApplication, classLayer, etc.
    //           desiredKey, optional specific key to get instead of everything
    //           this is recommended as all keys is an expensive call
    // Return:   ActionDescriptor or single value depending on what is asked for
    ///////////////////////////////////////////////////////////////////////////////
    function GetInfo(desiredClass, desiredKey) {
        var reference = new ActionReference();
        if (typeof desiredKey != "undefined") {
            reference.putProperty(stringIDToTypeID("property"), desiredKey);
        }
        reference.putEnumerated(desiredClass, stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
        var desc = executeActionGet(reference);
        if (typeof desiredKey != "undefined") {
            return GetItemFromDescriptor(desc, desiredKey);
        }
        return desc;
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function: GetItemFromDescriptor
    // Usage:    Get a specific key from an ActionDescriptor
    // Input:    desc (ActionDescriptor), valid ActionDescriptor to pull info from
    //           desiredKey (Number), key in question, use charIDToTypeID() or
    //           stringIDToTypeID()
    // Return:   ActionDescriptor or single value depending on what is asked for
    ///////////////////////////////////////////////////////////////////////////////
    function GetItemFromDescriptor(desc, desiredKey) {
        if (desc.hasKey(desiredKey)) {
            var typeID = desc.getType(desiredKey);
            switch (typeID) {
                case DescValueType.BOOLEANTYPE:
                    return desc.getBoolean(desiredKey);
                    break;
                case DescValueType.STRINGTYPE:
                    return desc.getString(desiredKey);
                    break;
                case DescValueType.DOUBLETYPE:
                    return desc.getDouble(desiredKey);
                    break;
                case DescValueType.INTEGERTYPE:
                    return desc.getInteger(desiredKey);
                    break;
                case DescValueType.LARGEINTEGERTYPE:
                    return desc.getLargeInteger(desiredKey);
                    break;
                case DescValueType.OBJECTTYPE:
                    return desc.getObjectValue(desiredKey);
                    break;
                case DescValueType.UNITDOUBLE:
                    var newT = desc.getUnitDoubleType(desiredKey);
                    var newV = desc.getUnitDoubleValue(desiredKey);
                    return new UnitValue(newV, newT);
                    break;
                case DescValueType.ENUMERATEDTYPE:
                    return desc.getEnumerationValue(desiredKey);
                    break;
                case DescValueType.CLASSTYPE:
                    return desc.getClass(desiredKey);
                    break;
                case DescValueType.ALIASTYPE:
                    return desc.getPath(desiredKey);
                    break;
                case DescValueType.RAWTYPE:
                    var tempStr = desc.getData(desiredKey);
                    var rawData = new Array();
                    for (var tempi = 0; tempi < tempStr.length; tempi++) {
                        rawData[tempi] = tempStr.charCodeAt(tempi);
                    }
                    return rawData;
                    break;
                case DescValueType.REFERENCETYPE:
                    return desc.getReference(desiredKey);
                    break;
                case DescValueType.LISTTYPE:
                    return desc.getList(desiredKey);
                    break;
                default:
                    return;
            }
        }
        return;
    }
    ////////////////////////////// tom_ruark @ adobe //////////////////////////////

    /////////////////////////////// joonas scriptUI ///////////////////////////////
    okButton.onClick = function () {
        dialogWindow.close();
        /////////////////////////////// joonas scriptUI ///////////////////////////////

        // Link function parameters to X & Y field values
        if (xValue.text.length > 0) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(xValue.text);
        }

        if (yValue.text.length > 0) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Vert(yValue.text);
        }

        // Canvas variables
        var rE = app.activeDocument.width; // rightEdge
        var hC = app.activeDocument.width / 2; // horizontalCenter
        var vC = app.activeDocument.height / 2; // verticalCenter
        var bE = app.activeDocument.height; // bottomEdge

        // Link function parameters to radio buttons
        if (upperLeft.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
        }

        if (upperCenter.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(hC);
            SetRulerOrigin_Vert(0);
        }

        if (upperRight.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(rE);
            SetRulerOrigin_Vert(0);
        }

        if (middleLeft.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(vC);
        }

        if (middleCenter.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(hC);
            SetRulerOrigin_Vert(vC);
        }

        if (middleRight.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(rE);
            SetRulerOrigin_Vert(vC);
        }

        if (lowerLeft.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(bE);
        }

        if (lowerCenter.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(hC);
            SetRulerOrigin_Vert(bE);
        }

        if (lowerRight.value === true) {
            // Reset ruler origin to zero for a known start point
            SetRulerOrigin_Horiz(0);
            SetRulerOrigin_Vert(0);
            // Set ruler origin to variables
            SetRulerOrigin_Horiz(rE);
            SetRulerOrigin_Vert(bE);
        }
    }

    /////////////////////////////// joonas scriptUI ///////////////////////////////
    // Execute window
    dialogWindow.show();
    /////////////////////////////// joonas scriptUI ///////////////////////////////

    ////////////////////////////// tom_ruark @ adobe //////////////////////////////
    // Function to limit keyboard entry to digits
    function NumericEditKeyboardHandler(event) {
        try {
            var keyIsOK = KeyIsNumeric(event) ||
                KeyIsDelete(event) ||
                KeyIsLRArrow(event) ||
                KeyIsTabEnterEscape(event);

            if (!keyIsOK) {
                // Bad input: tell ScriptUI not to accept the keydown event
                event.preventDefault();
                /*
                Notify user of invalid input: make sure NOT
                to put up an alert dialog or do anything which
                requires user interaction, because that
                interferes with preventing the 'default'
                action for the keydown event */
                app.beep();
            }
        } catch (e) {
            // alert ("Ack! bug in NumericEditKeyboardHandler: " + e);
        }
    }

    function KeyHasModifier(event) {
        return event.shiftKey || event.ctrlKey || event.altKey || event.metaKey;
    }

    function KeyIsNumeric(event) {
        return (event.keyName >= '0') && (event.keyName <= '9') && !KeyHasModifier(event);
    }

    function KeyIsDelete(event) {
        return (event.keyName == 'Backspace') && !(event.ctrlKey);
    }

    function KeyIsLRArrow(event) {
        return ((event.keyName == 'Left') || (event.keyName == 'Right')) && !(event.altKey || event.metaKey);
    }

    function KeyIsTabEnterEscape(event) {
        return event.keyName == 'Tab' || event.keyName == 'Enter' || event.keyName == 'Escape';
    }
    ////////////////////////////// tom_ruark @ adobe //////////////////////////////

    // Restore the ruler units
    app.preferences.rulerUnits = savedRuler;

}

else {
    alert('A document must be open to use this script!');
}

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines