SE3-TTSDeck/resources/ttsdeck/plugin.js

208 lines
5.7 KiB
JavaScript

/*
* TTSDeck.js
*
* Creates a deck image and corresponding "Saved Object" JSON for use
* in Tabletop Simulator
*/
useLibrary("project");
useLibrary("imageutils");
useLibrary("threads");
useLibrary("uilayout");
useLibrary("uicontrols");
importClass(arkham.project.CopiesList);
const Card = require("ttsdeck/Card.js");
const { TTSDeck } = require("ttsdeck/TTSDeck.js");
const TTSJson = require("ttsdeck/TTSJson.js");
const getName = () => "TTSDeck";
const getDescription = () => "Generates a TTS deck image and JSON file";
const getVersion = () => 1.0;
const getPluginType = () => arkham.plugins.Plugin.INJECTED;
function unload() {
unregisterAll();
}
// Creates a test button during development that calls unload() to clean up.
testProjectScript();
function settingsDialog(deck_task) {
const task_settings = deck_task.getSettings();
const image_format_field = comboBox([
ImageUtils.FORMAT_JPEG,
ImageUtils.FORMAT_PNG,
]);
image_format_field.setSelectedItem(
task_settings.get("tts_image_format", "jpg")
);
const resolution_field = textField(
task_settings.get("tts_image_resolution", "200"),
15
);
const clear_cache_button = button("Clear Cache", undefined, function (e) {
const cache_dir = new File(deck_task.file, ".ttsdeck_cache");
cache_dir.listFiles().forEach((file) => file.delete());
});
const panel = new Grid();
// prettier-ignore
panel.place(
"Image Format", "",
image_format_field, "grow,span",
"Resolution", "",
resolution_field, "grow,span",
clear_cache_button, "grow,span"
);
const close_button = panel.createDialog("TTS Export").showDialog();
return [
close_button,
image_format_field.getSelectedItem(),
Number(resolution_field.text),
];
}
function run() {
const ttsDeckAction = JavaAdapter(TaskAction, {
getLabel: () => "Generate TTS Deck",
getActionName: () => "ttsdeck",
// Applies to Deck Tasks
appliesTo: function appliesTo(project, task, member) {
if (member != null || task == null) {
return false;
}
const type = task.settings.get(Task.KEY_TYPE);
if (NewTaskType.DECK_TYPE.equals(type)) {
return true;
}
return false;
},
perform: function perform(project, task, member) {
let deck_task = ProjectUtilities.simplify(project, task, member);
const [close_button, image_format, image_resolution] =
settingsDialog(deck_task);
// User canceled the dialog or closed it without pressing ok
if (close_button != 1) {
return;
}
// persist settings
const task_settings = deck_task.getSettings();
task_settings.set("tts_image_format", image_format);
task_settings.set("tts_image_resolution", image_resolution);
deck_task.writeTaskSettings();
// If used with arkhamdb, get cycle prefix from settings
const arkhamdb_cycle_prefix = task_settings.get("arkhamdb_cycle_prefix");
Eons.setWaitCursor(true);
try {
Thread.busyWindow(
(busy_props) =>
this.performImpl(
busy_props,
image_format,
image_resolution,
arkhamdb_cycle_prefix,
deck_task
),
"Setting up...",
true
);
} catch (ex) {
Error.handleUncaught(ex);
} finally {
Eons.setWaitCursor(false);
}
},
performImpl: function performImpl(
busy_props,
image_format,
image_resolution,
arkhamdb_cycle_prefix,
member
) {
let copies_list;
try {
copies_list = new CopiesList(member);
} catch (ex) {
copies_list = new CopiesList();
alert(
"unable to read copies list, using card count of 2 for all files",
true
);
}
const children = member.getChildren();
const cards = children
.map((child) => {
if (ProjectUtilities.matchExtension(child, "eon")) {
let card = new Card(child, arkhamdb_cycle_prefix, copies_list);
if (card.component.isDeckLayoutSupported()) {
return card;
}
}
return undefined;
})
.filter((card) => card !== undefined);
const deck = new TTSDeck(
image_format,
image_resolution,
cards,
copies_list
).build(busy_props);
if (busy_props.cancelled) return;
const saved_object = TTSJson.makeSavedObjectJSON(
[deck.makeJSON()],
member.getName()
);
busy_props.status = "";
busy_props.maximumProgress = -1;
busy_props.title = "Writing JSON";
const json_file = new File(member.file, member.getName() + ".json");
ProjectUtilities.writeTextFile(
json_file,
JSON.stringify(saved_object, null, 4)
);
const deck_images = deck.getImages();
busy_props.title = "Writing Images";
busy_props.maximumProgress = deck_images.length;
deck_images.forEach((deck_image, index) => {
busy_props.currentProgress = index;
const image_file = Card.getImageFile(member, image_format, index + 1);
ImageUtils.write(
deck_image,
image_file,
image_format,
-1,
false,
image_resolution
);
});
let back_image = cards[0].makeImageUncached(image_resolution, true);
const back_image_file = Card.getImageFile(member, image_format, "back");
ImageUtils.write(
back_image,
back_image_file,
image_format,
-1,
false,
image_resolution
);
member.synchronize();
},
});
ActionRegistry.register(ttsDeckAction, Actions.PRIORITY_IMPORT_EXPORT);
}