リンクをクリップボードにコピー
コピー完了
スクリプトのコードが書けないためチャットGPTを使って、以下の「テキストレイヤーを追加するスクリプト」を作ってもらったのですが、
・カーソルで範囲選択している場合は、その範囲内にある文字列のみをテキストレイヤーとして追加する
という機能が、Windowsならちゃんと機能するのに、Macだと範囲選択しても常にテキスト入力欄にあるすべての文字が追加されてしまいます。
WindowsとMacで範囲選択の定義か何かに違いがあるのでしょうか?Macでも選択範囲の文字列のみテキストレイヤーとして追加するには、どうすればよいのでしょうか?
※添付画像は、Windowsで起動してうまくできているパターンです。Macではこのようにできません。
おそらく、範囲選択した部分に限定するという機能の記述は、以下の「selectedText・・・」部分が該当すると思っていますが、この点をどう修正すれば良いのかわからない、という状況です。
<該当箇所>(後述スクリプトより抜粋)--------------------------------
// 「テキスト追加」ボタンの定義と追加
var addButton = buttonGroup.add("button", undefined, "追加");
addButton.onClick = function() {
var selectedText = inputField.textselection || inputField.text;
addTextLayer(selectedText);
};
------------------------------------------------------------------------------------
<スクリプト>------------------------------------
(function(parent) {
var mainScriptName = "test";
// 指定したテキストを保存する関数
function saveText(text) {
app.settings.saveSetting(mainScriptName, "tabText", File.encode(text));
}
// 保存されているテキストを取得する関数
function getSavedText() {
return app.settings.haveSetting(mainScriptName, "tabText") ?
File.decode(app.settings.getSetting(mainScriptName, "tabText")) :
"";
}
// メインパネルの作成
var mainPanel = (parent instanceof Panel) ? parent : new Window("palette", "メモパネル", undefined, {
resizeable: true,
});
// ボタン用のグループの作成
var buttonGroup = mainPanel.add("group");
// 「テキスト追加」ボタンの定義と追加
var addButton = buttonGroup.add("button", undefined, "追加");
addButton.onClick = function() {
var selectedText = inputField.textselection || inputField.text;
addTextLayer(selectedText);
};
// テキスト入力フィールドの追加
var inputField = mainPanel.add("edittext", undefined, getSavedText(), {
multiline: true,
});
inputField.alignment = ["fill", "fill"];
inputField.onChange = function() {
saveText(this.text);
};
// パネルのレイアウト調整
mainPanel.layout.layout();
mainPanel.onResize = function() {
mainPanel.layout.resize();
}
// パネルの表示
if (mainPanel instanceof Window) {
mainPanel.center();
mainPanel.show();
}
// テキストレイヤーを追加する関数
function addTextLayer(text) {
var comp = app.project.activeItem;
if (!(comp instanceof CompItem)) {
alert("コンポジションをアクティブにしてください");
return null;
}
var selectedLayer = comp.selectedLayers.length === 1 ? comp.selectedLayers[0] : null;
app.beginUndoGroup("Add Text Layer");
var textLayer = comp.layers.addText(text);
if (selectedLayer) {
textLayer.moveBefore(selectedLayer);
textLayer.inPoint = selectedLayer.inPoint;
textLayer.outPoint = selectedLayer.outPoint;
}
centerAnchorPoint(textLayer);
textLayer.position.setValue([comp.width / 2, comp.height / 2]);
app.endUndoGroup();
return textLayer;
}
// アンカーポイントを中心に設定する関数
function centerAnchorPoint(layer) {
var sourceRect = layer.sourceRectAtTime(0, false);
layer.property("ADBE Transform Group").property("ADBE Anchor Point").setValue([sourceRect.left + sourceRect.width / 2, sourceRect.top + sourceRect.height / 2]);
}
})(this);
どうやらmacだと他のパーツにフォーカスが移ってedittextのフォーカスが外れてしまうと
textselectionの選択部分を見失っている(もしくは選択が解除されている)みたいなので
edittextのフォーカスが外れたらどこかに格納するようにイベントリスナーを付けてあげるとよいかもです
// テキスト入力フィールドの追加
var inputField = mainPanel.add("edittext", undefined, getSavedText(), {
multiline: true,
selected_text: '', //仮にここに格納する
});
function store_selection(e) {
var inputField = e.target // e.targetでイベントリスナーをつけたやつを取得できる
var selected_text = inputField.textselection
// 選択部分があればその部分を、無ければテ
...
リンクをクリップボードにコピー
コピー完了
どうやらmacだと他のパーツにフォーカスが移ってedittextのフォーカスが外れてしまうと
textselectionの選択部分を見失っている(もしくは選択が解除されている)みたいなので
edittextのフォーカスが外れたらどこかに格納するようにイベントリスナーを付けてあげるとよいかもです
// テキスト入力フィールドの追加
var inputField = mainPanel.add("edittext", undefined, getSavedText(), {
multiline: true,
selected_text: '', //仮にここに格納する
});
function store_selection(e) {
var inputField = e.target // e.targetでイベントリスナーをつけたやつを取得できる
var selected_text = inputField.textselection
// 選択部分があればその部分を、無ければテキスト全体を格納する
inputField.properties.selected_text = (selected_text === '') ?
inputField.text :
selected_text;
}
inputField.addEventListener('blur', store_selection, false)
addButton.onClick = function() {
var selectedText = inputField.properties.selected_text; // 格納されたものを取得する
if (selectedText === '') return;
addTextLayer(selectedText);
};
リンクをクリップボードにコピー
コピー完了
tetsuoh様
さっそくのご回答ありがとうございます…!試してみたところ、私がやりたかったことができました。本当に大変助かりました。
後学のためにお伺いできれば幸いですが、私がそもそも知識がなく大変恐縮なのですが、tetsuoh様が仰る「どうやらmacだとフォーカスが外れてしまうと選択部分を見失っているみたい」というのは、どのような調べ方をするとわかるものなのでしょうか?もしくは、スクリプトを書ける方からすれば結構有名な?話だったりするのでしょうか。
私も色々とテストしたり散々調べたりもしたのですが、それでもよくわからず最終手段としてここで質問させていただいたので、もしよろしければ、こんな素人でもどのように調べればわかるのか、ヒントを頂戴できれば大変ありがたいです。
ただ、これ以上お手数おかけするのは本意ではないので、説明が大変でしたら回答不要で大丈夫です…!
リンクをクリップボードにコピー
コピー完了
問題の原因を探したテストの過程としては、まずはonClickの関数内でinputField.textselectionが取得できているかどうかを試してみて
ダメだったのでinputFieldのフォーカスが外れた際にinputField.textselectionが取得できるかというのを
addEventListenerを使って取得してみたところよさそうだったのでどこかに格納するようにしてみたといった流れです。
取得できたかどうかは今回は単純にalert()を使って値を表示させて確認しましたが
ブレークポイントを使ったほうが動作の流れを追えるのでそちらのほうが良いと思います。
クリック、フォーカスが外れる、内容が変更されるなどのイベントハンドラの扱いについてはマニュアルに
載っているのでそれを参考にしていますが、そもそもそういったイベントハンドラというものがあることを知っている
というのはスクリプトを過去たくさん書いてきただけでなく、はるか昔にhtml+javascriptで動的に変化するものを
作った経験や、現在でもExtendScriptより多様なことができる他言語のGUIプログラミング等をしていることも
そのような発想の一助となっているのではないかなーと思います。
その他諸々調べるにあたっては英語(といっても簡単な単語)で検索や、海外のスクリプト書いてる人のDiscordとかも参考にしてみたりしています。
リンクをクリップボードにコピー
コピー完了
お返事たいへん遅くなりまして申し訳ありません…!
とても丁寧に教えていただきましてありがとうございます!!
内容何度も読ませていただきましたが、まだまだスクリプト初心者の私には経験も知識も足りないなと思ったのと、それでも理解できるところもありましたので今回のことも良く理解して次に繋げられるようにがんばります。
また、海外でのサイトなども参考にするとよいというお話も大変参考になりました!
問題解決しただけでなくこれからの参考にもなり本当に大変助かりました。