暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. /// <reference path="./card.ts" />
  2. /// <reference path="./colors.ts" />
  3. /// <reference path="./icons.ts" />
  4. /// <reference path="./example_data.ts" />
  5. /// <reference path="./jquery.d.ts" />
  6. module RpgCardsUI {
  7. var deck: RpgCards.CardDeck = null;
  8. var options: RpgCards.Options = null;
  9. var cardGenerator: RpgCards.CardHtmlGenerator = null;
  10. var pageGenerator: RpgCards.PageHtmlGenerator = null;
  11. // ============================================================================
  12. // Seleted card
  13. // ============================================================================
  14. function selected_card_index(): number {
  15. return parseInt($("#selected-card").val(), 10);
  16. }
  17. function selected_card(): RpgCards.Card {
  18. var index = selected_card_index();
  19. if (deck.cards.length > index) {
  20. return deck.cards[index];
  21. } else {
  22. return null;
  23. }
  24. }
  25. function select_card_by_index(index: number) {
  26. if (index > -1) {
  27. $("#selected-card").val("" + index);
  28. } else {
  29. $("#selected-card").val("" + (deck.cards.length - 1));
  30. }
  31. update_selected_card();
  32. }
  33. function select_card_by_card(card: RpgCards.Card) {
  34. var index = deck.cards.indexOf(card);
  35. select_card_by_index(index);
  36. }
  37. // ============================================================================
  38. // Rendering
  39. // ============================================================================
  40. function render_selected_card() {
  41. var card = selected_card();
  42. $('#preview-container').empty();
  43. if (card) {
  44. var front = cardGenerator.card_front(card, options, " ");
  45. var back = cardGenerator.card_back(card, options, " ");
  46. $('#preview-container').html(front + "\n" + back);
  47. }
  48. }
  49. function update_selected_card() {
  50. var card = selected_card();
  51. if (card) {
  52. $("#card-title").val(card.title);
  53. $("#card-title-size").val(card.title_size);
  54. $("#card-count").val(""+card.count);
  55. $("#card-icon").val(card.icon);
  56. $("#card-icon-back").val(card.icon_back);
  57. $("#card-contents").val(card.contents.join("\n"));
  58. $("#card-tags").val(card.tags.join(", "));
  59. $("#card-color").val(card.color).change();
  60. } else {
  61. $("#card-title").val("");
  62. $("#card-title-size").val("");
  63. $("#card-count").val("1");
  64. $("#card-icon").val("");
  65. $("#card-icon-back").val("");
  66. $("#card-contents").val("");
  67. $("#card-tags").val("");
  68. $("#card-color").val("").change();
  69. }
  70. render_selected_card();
  71. }
  72. function update_card_list() {
  73. deck.commit();
  74. $("#total_card_count").text("Deck contains " + deck.cards.length + " unique cards.");
  75. $('#selected-card').empty();
  76. for (var i = 0; i < deck.cards.length; ++i) {
  77. var card = deck.cards[i];
  78. $('#selected-card')
  79. .append($("<option></option>")
  80. .attr("value", i)
  81. .text(card.title));
  82. }
  83. update_selected_card();
  84. }
  85. // ============================================================================
  86. // Color picker
  87. // ============================================================================
  88. function setup_color_selector() {
  89. // Insert colors
  90. $.each(card_colors, function (name, val) {
  91. $(".colorselector-data")
  92. .append($("<option></option>")
  93. .attr("value", name)
  94. .attr("data-color", val)
  95. .text(name));
  96. });
  97. // Callbacks for when the user picks a color
  98. (<any>$('#default_color_selector')).colorselector({
  99. callback: function (value, color, title) {
  100. $("#default-color").val(title);
  101. set_default_color(title);
  102. }
  103. });
  104. (<any>$('#card_color_selector')).colorselector({
  105. callback: function (value, color, title) {
  106. $("#card-color").val(title);
  107. set_card_color(value);
  108. }
  109. });
  110. (<any>$('#foreground_color_selector')).colorselector({
  111. callback: function (value, color, title) {
  112. $("#foreground-color").val(title);
  113. set_foreground_color(value);
  114. }
  115. });
  116. (<any>$('#background_color_selector')).colorselector({
  117. callback: function (value, color, title) {
  118. $("#background-color").val(title);
  119. set_background_color(value);
  120. }
  121. });
  122. // Styling
  123. $(".dropdown-colorselector").addClass("input-group-addon color-input-addon");
  124. }
  125. function set_card_color(value) {
  126. var card = selected_card();
  127. if (card) {
  128. card.color = value;
  129. render_selected_card();
  130. }
  131. }
  132. function set_default_color(color) {
  133. options.default_color = color;
  134. render_selected_card();
  135. }
  136. function set_foreground_color(color) {
  137. options.foreground_color = color;
  138. }
  139. function set_background_color(color) {
  140. options.background_color = color;
  141. }
  142. function update_card_color_selector(color, input, selector) {
  143. if ($(selector + " option[value='" + color + "']").length > 0) {
  144. // Update the color selector to the entered value
  145. (<any>$(selector)).colorselector("setValue", color);
  146. } else {
  147. // Unknown color - select a neutral color and reset the text value
  148. (<any>$(selector)).colorselector("setValue", "");
  149. input.val(color);
  150. }
  151. }
  152. // ============================================================================
  153. // Card values
  154. // ============================================================================
  155. function on_change_card_title() {
  156. var title = $("#card-title").val();
  157. var card = selected_card();
  158. if (card) {
  159. card.title = title;
  160. $("#selected-card option:selected").text(title);
  161. render_selected_card();
  162. }
  163. }
  164. function on_change_card_color() {
  165. var input = $(this);
  166. var color = input.val();
  167. update_card_color_selector(color, input, "#card_color_selector");
  168. set_card_color(color);
  169. }
  170. function on_change_card_property() {
  171. var property = $(this).attr("data-property");
  172. var value = $(this).val();
  173. var card = selected_card();
  174. if (card) {
  175. card[property] = value;
  176. render_selected_card();
  177. }
  178. }
  179. function on_change_card_contents() {
  180. var value = $(this).val();
  181. var card = selected_card();
  182. if (card) {
  183. card.contents = value.split("\n");
  184. render_selected_card();
  185. }
  186. }
  187. function on_change_card_tags() {
  188. var value = $(this).val();
  189. var card = selected_card();
  190. if (card) {
  191. if (value.trim().length == 0) {
  192. card.tags = [];
  193. } else {
  194. card.tags = value.split(",").map(function (val) {
  195. return val.trim().toLowerCase();
  196. });
  197. }
  198. render_selected_card();
  199. }
  200. }
  201. // ============================================================================
  202. // Global default values
  203. // ============================================================================
  204. function on_change_option() {
  205. var property = $(this).attr("data-option");
  206. var value = $(this).val();
  207. options[property] = value;
  208. render_selected_card();
  209. }
  210. function on_change_default_color() {
  211. var input = $(this);
  212. var color = input.val();
  213. update_card_color_selector(color, input, "#default_color_selector");
  214. set_default_color(color);
  215. }
  216. function on_change_default_icon() {
  217. var value = $(this).val();
  218. options.default_icon = value;
  219. render_selected_card();
  220. }
  221. function on_change_default_title_size() {
  222. options.default_title_size = $(this).val();
  223. render_selected_card();
  224. }
  225. function on_change_default_icon_size() {
  226. options.icon_inline = $(this).is(':checked');
  227. render_selected_card();
  228. }
  229. // ============================================================================
  230. // Map/Filter
  231. // ============================================================================
  232. function apply_default_color() {
  233. deck.cards.forEach((card) => {
  234. card.color = options.default_color;
  235. });
  236. render_selected_card();
  237. }
  238. function apply_default_icon() {
  239. deck.cards.forEach((card) => {
  240. card.icon = options.default_icon;
  241. });
  242. render_selected_card();
  243. }
  244. function apply_default_icon_back() {
  245. deck.cards.forEach((card) => {
  246. card.icon_back = options.default_icon;
  247. });
  248. render_selected_card();
  249. }
  250. function sort() {
  251. showModal("#sort-modal");
  252. }
  253. function sort_execute() {
  254. hideModal("#sort-modal");
  255. var fn_code = $("#sort-function").val();
  256. var fn = new Function("card_a", "card_b", fn_code);
  257. deck.cards = deck.cards.sort(function (card_a, card_b) {
  258. var result = fn(card_a, card_b);
  259. return result;
  260. });
  261. update_card_list();
  262. }
  263. function filter() {
  264. showModal("#filter-modal");
  265. }
  266. function filter_execute() {
  267. hideModal("#filter-modal");
  268. var fn_code = $("#filter-function").val();
  269. var fn = new Function("card", fn_code);
  270. deck.cards = deck.cards.filter(function (card) {
  271. var result = fn(card);
  272. if (result === undefined) return true;
  273. else return result;
  274. });
  275. update_card_list();
  276. }
  277. // ============================================================================
  278. // Modals
  279. // ============================================================================
  280. function showModal(id: string) {
  281. (<any>$(id)).modal('show');
  282. }
  283. function hideModal(id: string) {
  284. (<any>$(id)).modal('hide');
  285. }
  286. // ============================================================================
  287. // I/O
  288. // ============================================================================
  289. function save_file() {
  290. var str = JSON.stringify(deck.toJSON(), null, " ");
  291. var parts = [str];
  292. var blob = new Blob(parts, { type: 'application/json' });
  293. var url = URL.createObjectURL(blob);
  294. var a = <HTMLLinkElement>$("#file-save-link")[0];
  295. a.href = url;
  296. (<any>a).download = "rpg_cards.json";
  297. a.click();
  298. setTimeout(function () { URL.revokeObjectURL(url); }, 1000);
  299. }
  300. function load_sample() {
  301. deck = RpgCards.CardDeck.fromJSON(card_data_example);
  302. update_card_list();
  303. }
  304. function clear_all() {
  305. deck = new RpgCards.CardDeck();
  306. update_card_list();
  307. }
  308. function ui_load_files(evt) {
  309. // ui_clear_all();
  310. var files = evt.target.files;
  311. for (var i = 0, f; f = files[i]; i++) {
  312. var reader = new FileReader();
  313. reader.onload = function (reader) {
  314. var data = JSON.parse(this.result);
  315. var deck = RpgCards.CardDeck.fromJSON(data);
  316. add_cards(deck.cards);
  317. };
  318. reader.readAsText(f);
  319. }
  320. // Reset file input
  321. (<any>$("#file-load-form")[0]).reset();
  322. }
  323. function add_cards(cards: RpgCards.Card[]) {
  324. deck.addCards(cards);
  325. update_card_list();
  326. }
  327. function add_new_card() {
  328. deck.addNewCard();
  329. update_card_list();
  330. select_card_by_index(deck.cards.length - 1);
  331. }
  332. function duplicate_card() {
  333. var newCard = null;
  334. if (deck.cards.length > 0) {
  335. var old_card = selected_card();
  336. newCard = deck.duplicateCard(old_card);
  337. } else {
  338. newCard = deck.addNewCard();
  339. }
  340. update_card_list();
  341. select_card_by_card(newCard);
  342. }
  343. function delete_card() {
  344. var index = selected_card_index();
  345. var card = selected_card();
  346. deck.deleteCard(card);
  347. update_card_list();
  348. select_card_by_index(Math.min(index, deck.cards.length - 1));
  349. }
  350. // ============================================================================
  351. // Menu
  352. // ============================================================================
  353. function open_help() {
  354. showModal("#help-modal");
  355. }
  356. function select_icon() {
  357. window.open("http://game-icons.net/", "_blank");
  358. }
  359. var generate_modal_shown = false;
  360. function generate() {
  361. if (deck.cards.length === 0) {
  362. alert("Your deck is empty. Please define some cards first, or load the sample deck.");
  363. return;
  364. }
  365. // Generate output HTML
  366. var card_html = pageGenerator.generateHtml(deck.cards, options);
  367. // Open a new window for the output
  368. // Use a separate window to avoid CSS conflicts
  369. var tab = window.open("output.html", 'rpg-cards-output');
  370. if (generate_modal_shown == false) {
  371. showModal("#print-modal");
  372. generate_modal_shown = true;
  373. }
  374. // Send the generated HTML to the new window
  375. // Use a delay to give the new window time to set up a message listener
  376. setTimeout(function () { tab.postMessage(card_html, '*') }, 500);
  377. }
  378. // ============================================================================
  379. // Initialization
  380. // ============================================================================
  381. function init() {
  382. deck = new RpgCards.CardDeck();
  383. options = new RpgCards.Options();
  384. cardGenerator = new RpgCards.CardHtmlGenerator;
  385. pageGenerator = new RpgCards.PageHtmlGenerator;
  386. setup_color_selector();
  387. (<any>$('.icon-list')).typeahead({ source: icon_names });
  388. // Menu
  389. $("#sort-execute").click(sort_execute);
  390. $("#filter-execute").click(filter_execute);
  391. $("#button-generate").click(generate);
  392. $("#button-load").click(function () { $("#file-load").click(); });
  393. $("#file-load").change(ui_load_files);
  394. $("#button-clear").click(clear_all);
  395. $("#button-load-sample").click(load_sample);
  396. $("#button-save").click(save_file);
  397. $("#button-sort").click(sort);
  398. $("#button-filter").click(filter);
  399. $("#button-add-card").click(add_new_card);
  400. $("#button-duplicate-card").click(duplicate_card);
  401. $("#button-delete-card").click(delete_card);
  402. $("#button-help").click(open_help);
  403. $("#button-apply-color").click(apply_default_color);
  404. $("#button-apply-icon").click(apply_default_icon);
  405. $("#button-apply-icon-back").click(apply_default_icon_back);
  406. $("#selected-card").change(update_selected_card);
  407. $("#card-title").change(on_change_card_title);
  408. $("#card-title-size").change(on_change_card_property);
  409. $("#card-title-icon-text").change(on_change_card_property);
  410. $("#card-icon").change(on_change_card_property);
  411. $("#card-count").change(on_change_card_property);
  412. $("#card-icon-back").change(on_change_card_property);
  413. $("#card-color").change(on_change_card_color);
  414. $("#card-contents").change(on_change_card_contents);
  415. $("#card-tags").change(on_change_card_tags);
  416. // Global options
  417. $("#page-size").change(on_change_option);
  418. $("#page-rows").change(on_change_option);
  419. $("#page-columns").change(on_change_option);
  420. $("#card-arrangement").change(on_change_option);
  421. $("#card-size").change(on_change_option);
  422. $("#background-color").change(on_change_option);
  423. $("#default-color").change(on_change_default_color);
  424. $("#default-icon").change(on_change_default_icon);
  425. $("#default-title-size").change(on_change_default_title_size);
  426. $("#small-icons").change(on_change_default_icon_size);
  427. $(".icon-select-button").click(select_icon);
  428. update_card_list();
  429. }
  430. $(document).ready(function () {
  431. init();
  432. });
  433. }