Copy link to clipboard
Copied
Hello, I need to write a script that switches 2 working media. For example: if the active working environment has the name "photo", then switch to the working environment "Drawing". Tell me, please, how to determine the name of the active work environment?
#target photoshop
s2t = stringIDToTypeID;
var r = new ActionReference();
r.putProperty(s2t('property'), s2t('menuBarInfo'));
r.putEnumerated(s2t('application'), s2t('ordinal'), s2t('targetEnum'));
var mainMenu = executeActionGet(r).getObjectValue(s2t('menuBarInfo')).getList(s2t('submenu'))
var windowMenu = new ActionDescriptor()
for (var i = 0; i < mainMenu.count; i++) {
if (mainMenu.getObjectValue(i).getString(s2t('title')) == localize('$$$/Menu/Window')) {
var windowMenu = main
...
Если вам нужно срабатывание на строку, которой нет в файле локализации, то уберите в условии функцию localize и сравнивайте непосредственно с нужным вам названием
if (currentWorkspaceTitle == 'Монитор')
в случае проблем посмотрите, что пишется в переменную currentWorkspaceTitle в процессе работы скрипта
Copy link to clipboard
Copied
#target photoshop
s2t = stringIDToTypeID;
var r = new ActionReference();
r.putProperty(s2t('property'), s2t('menuBarInfo'));
r.putEnumerated(s2t('application'), s2t('ordinal'), s2t('targetEnum'));
var mainMenu = executeActionGet(r).getObjectValue(s2t('menuBarInfo')).getList(s2t('submenu'))
var windowMenu = new ActionDescriptor()
for (var i = 0; i < mainMenu.count; i++) {
if (mainMenu.getObjectValue(i).getString(s2t('title')) == localize('$$$/Menu/Window')) {
var windowMenu = mainMenu.getObjectValue(i).getList(s2t('submenu'))
break;
}
}
var workspaceMenu = new ActionDescriptor()
for (var i = 0; i < windowMenu.count; i++) {
if (windowMenu.getObjectValue(i).getString(s2t('title')) == localize('$$$/Menu/Window/ProjectWorkSpace')) {
workspaceMenu = windowMenu.getObjectValue(i).getList(s2t('submenu'))
break;
}
}
for (var i = 0; i < workspaceMenu.count; i++) {
if (workspaceMenu.getObjectValue(i).getBoolean(s2t('checked'))) {
alert('current workpace: ' + workspaceMenu.getObjectValue(i).getString(s2t('title')))
}
}
* if you switch the workspace and immediately run the script, it will show that the workspace has not changed (although it is not). Apparently Photoshop does not update the menuBarInfo descriptor until the user re-selects any menu item.
you can also use event notifications to track when the workspace is switched and save its name for future use (before first run the code, you need save it to a file, since the event listener will start it every time the workspace is changed)
#target photoshop
var s2t = stringIDToTypeID,
t2s = typeIDToStringID,
UUID = 'bf7064f7-eee2-4ac2-a639-5c3832469b43';
try {
var target = t2s(arguments[0].getReference(s2t('null')).getDesiredClass())
if (target == 'workspace') {
var d = new ActionDescriptor();
d.putString(s2t('workspace'), arguments[0].getReference(s2t('null')).getName())
app.putCustomOptions(UUID, d)
}
} catch (e) {
app.notifiersEnabled = true
var f = File($.fileName),
deleted;
for (var i = 0; i < app.notifiers.length; i++) {
var ntf = app.notifiers[i]
if (ntf.eventFile.name == f.name) { ntf.remove(); i--; deleted = true }
}
if (deleted) {
alert('event listening disabled!')
} else {
alert('event listening enabled!')
app.notifiers.add('slct', f)
var r = new ActionReference();
r.putProperty(s2t('property'), s2t('menuBarInfo'));
r.putEnumerated(s2t('application'), s2t('ordinal'), s2t('targetEnum'));
var mainMenu = executeActionGet(r).getObjectValue(s2t('menuBarInfo')).getList(s2t('submenu'))
var windowMenu = new ActionDescriptor()
for (var i = 0; i < mainMenu.count; i++) {
if (mainMenu.getObjectValue(i).getString(s2t('title')) == localize('$$$/Menu/Window')) {
var windowMenu = mainMenu.getObjectValue(i).getList(s2t('submenu'))
break;
}
}
var workspaceMenu = new ActionDescriptor()
for (var i = 0; i < windowMenu.count; i++) {
if (windowMenu.getObjectValue(i).getString(s2t('title')) == localize('$$$/Menu/Window/ProjectWorkSpace')) {
workspaceMenu = windowMenu.getObjectValue(i).getList(s2t('submenu'))
break;
}
}
for (var i = 0; i < workspaceMenu.count; i++) {
if (workspaceMenu.getObjectValue(i).getBoolean(s2t('checked'))) {
var d = new ActionDescriptor();
d.putString(s2t('workspace'), workspaceMenu.getObjectValue(i).getString(s2t('title')))
app.putCustomOptions(UUID, d)
break;
}
}
}
}
In this case, you can get the name of the current workspace at any time (while event listener enabled) using the code:
var s2t = stringIDToTypeID,
UUID = 'bf7064f7-eee2-4ac2-a639-5c3832469b43';
try {var d = app.getCustomOptions (UUID)} catch (e) {}
if (d) alert ('current workspace: ' + d.getString (s2t('workspace')))
Copy link to clipboard
Copied
Hello, thanks, I did not understand how to organize it a little. In turning on the script listener, it then issues
a notification that the listener is not available.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Thank you, it works, was inattentive and did not start once again the first script to activate the listener
Подскажите,пожалуйста ,необходимо вместо вывода диалогового окна с инфо о рабочей среде,сделать переменную -если рабочая среда "фото" ,то использовать такую то функцию,если "рисунок" ...и т.д.
Copy link to clipboard
Copied
var s2t = stringIDToTypeID,
UUID = 'bf7064f7-eee2-4ac2-a639-5c3832469b43';
try { var d = app.getCustomOptions(UUID) } catch (e) { }
if (d) var w = d.getString(s2t('workspace'))
if (w == localize('$$$/FileName/Presets/WorkSpaces/Photography')) {
// call function for photography workspace here
} else if (w == localize('$$$/FileName/Presets/WorkSpaces/Painting')) {
// call function for painting workspace here
}
Copy link to clipboard
Copied
Thank you!
Copy link to clipboard
Copied
Да не за что!
Возможность получить расширенную информацию о пунктах меню (самое первое сообщение и аналогичный кусок кода во втором) появились только в последних версиях Фотошопа. В старых версиях этот код работать не будет, то есть информация о выбранном рабочем пространстве на момент первого запуска скрипта будет недоступна. По сути единственный способ, который обеспечивает хоть какую-то совместимость - это работа с уведомлениями. Т.е. для совместимости код можно укоротить до:
#target photoshop
var s2t = stringIDToTypeID,
t2s = typeIDToStringID,
UUID = 'bf7064f7-eee2-4ac2-a639-5c3832469b43';
try {
var target = t2s(arguments[0].getReference(s2t('null')).getDesiredClass())
if (target == 'workspace') {
var d = new ActionDescriptor();
d.putString(s2t('workspace'), arguments[0].getReference(s2t('null')).getName())
app.putCustomOptions(UUID, d)
}
} catch (e) {
app.notifiersEnabled = true
var f = File($.fileName),
deleted;
for (var i = 0; i < app.notifiers.length; i++) {
var ntf = app.notifiers[i]
if (ntf.eventFile.name == f.name) { ntf.remove(); i--; deleted = true }
}
if (deleted) {
alert('event listening disabled!')
} else {
alert('event listening enabled!')
app.notifiers.add('slct', f)
}
}
(т.е. мы не получаем информацию о выбранном рабочем пространстве на момент запуска скрипта, но при дальнейших переключениях он получает ее через уведомления)
Copy link to clipboard
Copied
Через "&Reset" работает гарантированно, начиная с CC2018, как минимум.
CC2019 - Get name of current workspace function not working
Только нужно более умно̀ подкрутить под последние версии (не использовать фиксированные индексы).
З.Ы. Использование нотификаторов на постоянной основе крайне не желательно. Во-первых, это может тормозить работу. Во-вторых и далее, не во всех случаях может сработать перехват. Любой тупой сторонний скрипт, использующий нотификаторы, запросто может нарушить всю работу уже установленных "постоянных" нотификаторов.
.
Copy link to clipboard
Copied
Я б не сбрасывал рабочее пространство просто так. Фиг знает, что там у пользователя на момент запуска скрипта настроено (может какие панельки или еще что).
У меня есть скрипт, который трекает выбор слоев (отслеживает около 10 событий (6 для слоев, 4 для каналов)) - больше года с ним работаю, тормозов не замечал (включен 24/7). Хотя, конечно, я там все функции по таймеру гонял.
Пробовал вешать несколько скриптов на одно событие - случаев перехвата не встречал (шоп отрабатывает все нотификаторы). А вот кривую реакцию самого шопа на определенные нотификаторы встречал - например, если повесить на toolModalStateChanged, то скрипт перехыватывает событие трансформации и не отдает его фотошопу (не работает запись в экшены). Возвращать полученный в качестве аргумента дескриптор не пробывал (по идее должно сработать через app.playbackParameters, надо будет посмотреть).
Copy link to clipboard
Copied
Наверное не так поняли. Там ничего не сбрасывается. То же, что и у вас. Просто ищется меню не с "checked", а с именем начинающимся с "&Reset".
Copy link to clipboard
Copied
А, блин. Иногда нужно открывать тему по ссылке перед тем как писать 🙂
То есть примерно так:
#target photoshop
s2t = stringIDToTypeID;
var r = new ActionReference();
r.putProperty(s2t('property'), s2t('menuBarInfo'));
r.putEnumerated(s2t('application'), s2t('ordinal'), s2t('targetEnum'));
var mainMenu = executeActionGet(r).getObjectValue(s2t('menuBarInfo')).getList(s2t('submenu'))
var windowMenu = new ActionDescriptor(),
windowTitle = localize('$$$/Menu/Window').replace(/\&/, '');
for (var i = 0; i < mainMenu.count; i++) {
if (mainMenu.getObjectValue(i).getString(s2t('title')).replace(/\&/, '') == windowTitle) {
var windowMenu = mainMenu.getObjectValue(i).getList(s2t('submenu'))
break;
}
}
var workspaceMenu = new ActionDescriptor(),
workspaceTitle = localize('$$$/Menu/Window/ProjectWorkSpace').replace(/\&/, '');
for (var i = 0; i < windowMenu.count; i++) {
if (windowMenu.getObjectValue(i).getString(s2t('title')).replace(/\&/, '') == workspaceTitle) {
workspaceMenu = windowMenu.getObjectValue(i).getList(s2t('submenu'))
break;
}
}
var reset = localize("$$$/Menu/WorkSpace/Reset=&Reset ^0").replace(/[(\&)( \^0$)]/g, '');
for (var i = 0; i < workspaceMenu.count; i++) {
if (workspaceMenu.getObjectValue(i).getString(s2t('title')).replace(/\&/, '').indexOf(reset) != -1) {
var currentWorkspaceTitle = workspaceMenu.getObjectValue(i).getString(s2t('title')).replace(/\&/, '').replace(RegExp(reset + ' '), '')
break;
}
}
alert('current workpace: ' + currentWorkspaceTitle)
К слову, похоже что на маке игнорируются амперсанды из локализации: верхняя строка алерта title, нижняя то что вернула функция localize, пришлось регэкспов напихать...
Copy link to clipboard
Copied
Ну вот! Это, думаю, самый правильный ответ. : )
Copy link to clipboard
Copied
Спасибо!Работает отлично!Подскажите только,пожалуйста,как сюда прикрутить действия ,вместо уведомления?И еще вопрос,в предыдущей связке скрипт действий работал только с теми раб.средами,что находились в папке C:\Program Files\Adobe\Adobe Photoshop 2021\Required\Workspaces и были с англ.названием,можно ли это как- то поправить?Название рабочих сред в скрипте с уведомлением он так же определял и на кириллице и на латинице,а вот с действиями не хотел.
Copy link to clipboard
Copied
А расскажите ,пожалуйста,подробнее про ваши отслеживания действий на слои.Например,если активен слой кривые или создается такой слой,то к ,примеру ,надо запустить какую-то рабочую среду.Или где можно посмотреть списки имен событий,чтобы их правильно вписать ?
Copy link to clipboard
Copied
В варианте с уведмлениями я не учел, что уведомление выдает name меню, а не title (они отличаются наличием амперсанда), поэтому и не работало.
#target photoshop
s2t = stringIDToTypeID;
var r = new ActionReference();
r.putProperty(s2t('property'), s2t('menuBarInfo'));
r.putEnumerated(s2t('application'), s2t('ordinal'), s2t('targetEnum'));
var mainMenu = executeActionGet(r).getObjectValue(s2t('menuBarInfo')).getList(s2t('submenu'))
var windowMenu = new ActionDescriptor(),
windowTitle = localize('$$$/Menu/Window').replace(/\&/, '');
for (var i = 0; i < mainMenu.count; i++) {
if (mainMenu.getObjectValue(i).getString(s2t('title')).replace(/\&/, '') == windowTitle) {
var windowMenu = mainMenu.getObjectValue(i).getList(s2t('submenu'))
break;
}
}
var workspaceMenu = new ActionDescriptor(),
workspaceTitle = localize('$$$/Menu/Window/ProjectWorkSpace').replace(/\&/, '');
for (var i = 0; i < windowMenu.count; i++) {
if (windowMenu.getObjectValue(i).getString(s2t('title')).replace(/\&/, '') == workspaceTitle) {
workspaceMenu = windowMenu.getObjectValue(i).getList(s2t('submenu'))
break;
}
}
var reset = localize("$$$/Menu/WorkSpace/Reset=&Reset ^0").replace(/[(\&)( \^0$)]/g, '');
for (var i = 0; i < workspaceMenu.count; i++) {
if (workspaceMenu.getObjectValue(i).getString(s2t('title')).replace(/\&/, '').indexOf(reset) != -1) {
var currentWorkspaceTitle = workspaceMenu.getObjectValue(i).getString(s2t('title')).replace(/\&/, '').replace(RegExp(reset + ' '), '')
if (currentWorkspaceTitle == localize('$$$/FileName/Presets/WorkSpaces/Photography').replace(/\&/, '')){
// call function for photography workspace here
}else if (currentWorkspaceTitle == localize('$$$/FileName/Presets/WorkSpaces/Painting').replace(/\&/, '')) {
// call function for painting workspace here
}
break;
}
}
Свой скрипт скину вам в личку, напишу как с его помощью выполнить такой сценарий (он предназначен только для выбора инструментов, но позволяет задейстовать экшены для любых других действий).
Информацию о событии можно получить множеством способов - либо установив script listener и разбирать код который он выводит, либо вручную установив нотификатор на 'All ' (т.е. app.notifiers.add('All ', путь ко скрипту) и разбирать полученный дескриптор в самом скрипте (можете посмотреть тему Script Events Listener), также можно изучить код Script Events Manager.jsx, который есть в стандартных скриптах фотошопа, либо скачать SDK - там есть файл PITerminology.h, котором отдельно выделены имена событий.
Copy link to clipboard
Copied
Благодарю,работает,но так же не хочет работать с кириллицей(
Copy link to clipboard
Copied
Не знаю, что у вас там за проблемы с кириллицей и амперсандами, но если речь о скрипте котрый ищет в menuBarInfo, то можно искать не по title, а по command ==5117.
Естественно Drawing и Photo там в title не будет.
... но может просто не понял о чём это вы : )
P.S. иринас52980346, не стоит новичку заморачиваться с нотификаторами.
А зачем вам нужен на практике данный скрипт?
Лично я работаю только в CS6. Там эта штука с menuBarInfo вообще не работает. Для изменения поведения скриптов я использую линейку. Например, при процентах одно поведение, при других единицах другое, при третьих третье. Или же смотрю состояние волшебной палки или лассо. При добавлении одно поведение, при режиме вычитания другое. А рабочая среда всегда одна и та же.
Copy link to clipboard
Copied
Ну я не совсем новичок,плаваю потихоньку)У меня в задачах разные действия и работа на разных мониторах,например на граф планшете экран 13 дюймов,и если я постоянно буду разворачивать то ,что мне нужно ,у меня не останется места.А так на одну кнопку поставил гор.клавишу с переключением и все.Ну и плюс разные настройки панелей и инструментов для обработки и для рисования.Имя рабочих сред скрип видит великолепно и англ.и русских,а вот сделать запрограммированное, исходя из названия рабочей среды на русском он не хочет.На англ.же прекрасно.Видимо тут как и с названием инструментов,на англ.фотошоп берет их,а на русском нет)
Copy link to clipboard
Copied
возможно проблема в версии фотошопа. пробуйте отладкой поймать где ошибка.
пробовал на винде и на маке (20 и 22 версии) - всё работает, от языка не зависит.
Copy link to clipboard
Copied
Это стандартные рабочие среды,они в папке всеравно на латинице,у меня проблема с созданной рабочей средой с названием на кириллице.Т.е и в папке рабочих сред она на кириллице.Но стоит ей дать имя на латинице все работает.
Copy link to clipboard
Copied
Если вам нужно срабатывание на строку, которой нет в файле локализации, то уберите в условии функцию localize и сравнивайте непосредственно с нужным вам названием
if (currentWorkspaceTitle == 'Монитор')
в случае проблем посмотрите, что пишется в переменную currentWorkspaceTitle в процессе работы скрипта
Copy link to clipboard
Copied
Вот теперь отлично работает.И стандартные берет ,и кириллицу ,и даже те,которые не в стандартной папке лежат.
Copy link to clipboard
Copied
Покажите ваш скрипт (код) и имя созданной рабочей среды на кириллице.
Специфичные функции сократите до alert()
Copy link to clipboard
Copied
del
...