Robert Carnecky před 10 roky
rodič
revize
654326f482

+ 3
- 0
.gitignore Zobrazit soubor

@@ -1,2 +1,5 @@
1 1
 /resources/game-icons.net
2 2
 /node_modules
3
+/generator/js/*.map
4
+/generator/js/*.d.ts
5
+/generator/js/*.js

+ 1
- 5
generator/generate.html Zobrazit soubor

@@ -14,12 +14,8 @@
14 14
     <!-- Library: Color picker -->
15 15
     <link href="lib/colorpicker/css/bootstrap-colorselector.css" rel="stylesheet" />
16 16
     <script type="text/javascript" src="lib/colorpicker/js/bootstrap-colorselector.js" charset="utf-8"></script>
17
-    <!-- Data -->
18
-    <script type="text/javascript" src="data/card_data_example.js"></script>
19 17
     <!-- Javascript -->
20
-    <script type="text/javascript" src="js/cards.js"></script>
21
-    <script type="text/javascript" src="js/colors.js"></script>
22
-    <script type="text/javascript" src="js/icons.js"></script>
18
+    <script type="text/javascript" src="js/card.js"></script>
23 19
     <script type="text/javascript" defer src="js/ui.js"></script>
24 20
     <!-- CSS -->
25 21
     <link href="css/ui.css" rel="stylesheet" />

+ 85
- 7
generator/js/card.ts Zobrazit soubor

@@ -1,4 +1,4 @@
1
-module rpgcards {
1
+module RpgCards {
2 2
 
3 3
     function normalizeTag(tag: string): string {
4 4
         return tag.trim().toLowerCase();
@@ -53,6 +53,8 @@ module rpgcards {
53 53
         contents: string[];
54 54
         tags: string[];
55 55
 
56
+        userData: any;
57
+
56 58
         constructor() {
57 59
             this.count = 1;
58 60
             this.title = "New card";
@@ -65,6 +67,7 @@ module rpgcards {
65 67
             this.icon_back = null;
66 68
             this.contents = [];
67 69
             this.tags = [];
70
+            this.userData = null;
68 71
         }
69 72
 
70 73
         static fromJSON(json: any): Card {
@@ -100,7 +103,9 @@ module rpgcards {
100 103
         }
101 104
 
102 105
         public duplicate(): Card {
103
-            return Card.fromJSON(this.toJSON());
106
+            var result = Card.fromJSON(this.toJSON());
107
+            result.title += " (Copy)";
108
+            return result;
104 109
         }
105 110
 
106 111
         public hasTag(tag: string): boolean {
@@ -141,6 +146,79 @@ module rpgcards {
141 146
         }
142 147
     };
143 148
 
149
+    interface CardAction {
150
+        fn: string;
151
+        card: Card;
152
+        ref: Card;
153
+    }
154
+
155
+    export class CardDeck {
156
+        cards: Card[];
157
+        private _actions: CardAction[];
158
+
159
+        constructor() {
160
+            this.cards = [];
161
+            this._actions = [];
162
+        }
163
+
164
+        public toJSON(): any {
165
+            return this.cards.map((card) => card.toJSON());
166
+        }
167
+
168
+        public static fromJSON(data: any): CardDeck {
169
+            if (Array.isArray(data)) {
170
+                var result = new CardDeck;
171
+                for (var i = 0; i < data.length; ++i) {
172
+                    result.cards.push(Card.fromJSON(data[i]));
173
+                }
174
+                return result;
175
+            } else {
176
+                throw new Error("Invalid data");
177
+            }
178
+        }
179
+
180
+        public addCards(cards: Card[]): void {
181
+            cards.forEach((card) => {
182
+                this._actions.push({fn:"add", card: card, ref: null});
183
+            });
184
+        }
185
+
186
+        public addNewCard(): Card {
187
+            var newCard = new Card();
188
+            this._actions.push({ fn: "add", card: newCard, ref: null });
189
+            return newCard;
190
+        }
191
+
192
+        public duplicateCard(card: Card): Card {
193
+            var newCard = card.duplicate();
194
+            this._actions.push({ fn: "add", card: new Card(), ref: card });
195
+            return newCard;
196
+        }
197
+
198
+        public deleteCard(card: Card): void {
199
+            this._actions.push({ fn: "del", card: card, ref: null });
200
+        }
201
+
202
+        public commit() {
203
+            for (var i = 0; i < this._actions.length; ++i) {
204
+                var action = this._actions[i];
205
+                if (action.fn === "add") {
206
+                    var index = this.cards.indexOf(action.ref);
207
+                    if (index > -1) {
208
+                        this.cards.splice(index + 1, 0, action.card);
209
+                    } else {
210
+                        this.cards.push(action.card);
211
+                    }
212
+                } else if (action.fn === "del") {
213
+                    var index = this.cards.indexOf(action.card);
214
+                    if (index > -1) {
215
+                        this.cards.splice(index, 1);
216
+                    }
217
+                }
218
+            }
219
+        }
220
+    }
221
+
144 222
     type ContentGeneratorFunction = (params: string[], card: Card, options: Options, ind: string, ind0: string) => string;
145 223
     type CardGeneratorFunction = (card: Card, options: Options, ind: string, ind0: string) => string;
146 224
 
@@ -238,7 +316,7 @@ module rpgcards {
238 316
         private  _contents(contents: string[], card: Card, options: Options, ind: string, ind0: string): string {
239 317
             var result = "";
240 318
             result += ind + '<card-contents>\n';
241
-            result += contents.map(function (value) {
319
+            result += contents.map((value) => {
242 320
                 var parts = splitParams(value);
243 321
                 var name = parts[0];
244 322
                 var params = parts.splice(1);
@@ -452,7 +530,7 @@ module rpgcards {
452 530
             Adds new pages if necessary.
453 531
         */
454 532
         public addCards(card: T, count: number): void {
455
-            for (let i = 0; i < count; ++i) {
533
+            for (var i = 0; i < count; ++i) {
456 534
                 this.addCard(card);
457 535
             }
458 536
         }
@@ -508,7 +586,7 @@ module rpgcards {
508 586
             var empty = generator.card_empty(options, this.indent);
509 587
 
510 588
             // Fill pages with cards
511
-            for (let i = 0; i < cards.length; ++i) {
589
+            for (var i = 0; i < cards.length; ++i) {
512 590
                 var card = cards[i];
513 591
                 var front = generator.card_front(card, options, this.indent);
514 592
                 var back = generator.card_back(card, options, this.indent);
@@ -532,7 +610,7 @@ module rpgcards {
532 610
             var empty = generator.card_empty(options, this.indent);
533 611
 
534 612
             // Fill pages with cards
535
-            for (let i = 0; i < cards.length; ++i) {
613
+            for (var i = 0; i < cards.length; ++i) {
536 614
                 var card = cards[i];
537 615
                 var front = generator.card_front(card, options, this.indent);
538 616
                 pages.addCards(front, card.count);
@@ -549,7 +627,7 @@ module rpgcards {
549 627
             var empty = generator.card_empty(options, this.indent);
550 628
 
551 629
             // Fill pages with cards (two at a time)
552
-            for (let i = 0; i < cards.length; ++i) {
630
+            for (var i = 0; i < cards.length; ++i) {
553 631
                 var card = cards[i];
554 632
                 var front = generator.card_front(card, options, this.indent);
555 633
                 var back = generator.card_back(card, options, this.indent);

+ 0
- 420
generator/js/cards.js Zobrazit soubor

@@ -1,420 +0,0 @@
1
-// ============================================================================
2
-// Card definition related functions
3
-// ============================================================================
4
-function card_default_options() {
5
-    return {
6
-        foreground_color: "white",
7
-        background_color: "white",
8
-        default_color: "black",
9
-        default_icon: "ace",
10
-        default_title_size: "13",
11
-        page_size: "A4",
12
-        page_rows: 3,
13
-        page_columns: 3,
14
-        card_arrangement: "doublesided",
15
-        card_size: "25x35",
16
-        card_count: null,
17
-        icon_inline: true
18
-    }
19
-}
20
-
21
-function card_default_data() {
22
-    return {
23
-        count: 1,
24
-        title: "New card",
25
-        contents: [],
26
-        tags: []
27
-    }
28
-}
29
-
30
-function card_init(card) {
31
-    card.title = card.title || "";
32
-    card.contents = card.contents || [];
33
-    card.tags = card.tags || [];
34
-}
35
-
36
-function card_has_tag(card, tag) {
37
-    tag = tag.trim().toLowerCase();
38
-    var index = card.tags.indexOf(tag);
39
-    return index > -1;
40
-}
41
-
42
-function card_add_tag(card, tag) {
43
-    tag = tag.trim().toLowerCase();
44
-    var index = card.tags.indexOf(tag);
45
-    if (index == -1) {
46
-        card.tags.push(tag);
47
-    }
48
-}
49
-
50
-function card_remove_tag(card, tag) {
51
-    tag = tag.trim().toLowerCase();
52
-    card.tags = card.tags.filter(function (t) {
53
-        return tag != t;
54
-    });
55
-}
56
-
57
-// ============================================================================
58
-// Card definition related functions
59
-// ============================================================================
60
-
61
-function card_data_color_front(card_data, options) {
62
-    return card_data.color_front || card_data.color || options.default_color || "black";
63
-}
64
-
65
-function card_data_color_back(card_data, options) {
66
-    return card_data.color_back || card_data.color || options.default_color || "black";
67
-}
68
-
69
-function card_data_icon_front(card_data, options) {
70
-    return card_data.icon_front || card_data.icon || options.default_icon || "ace";
71
-}
72
-
73
-function card_data_icon_back(card_data, options) {
74
-    return card_data.icon_back || card_data.icon || options.default_icon || "ace";
75
-}
76
-
77
-function card_data_split_params(value) {
78
-    return value.split("|").map(function (str) { return str.trim(); });
79
-}
80
-
81
-// ============================================================================
82
-// Card element generating functions
83
-// ============================================================================
84
-
85
-function card_element_title(card_data, options) {
86
-    var title = card_data.title || "";
87
-    var title_size = card_data.title_size || options.default_title_size || '13';
88
-    var icon = card_data_icon_front(card_data, options) + ".svg";
89
-
90
-    var result = "";
91
-    result += '<card-title size="' + title_size + '">';
92
-    result += '   <h1>' + title + '</h1>';
93
-    result += '   <h2>' + "" + '</h2>';
94
-    result += '   <card-icon src="/icons/' + icon + '"></card-icon>';
95
-    result += '</card-title>';
96
-    return result;
97
-
98
-    return '<div class="card-title card-title-' + title_size + '">' + title + '</div>';
99
-}
100
-
101
-function card_element_subtitle(params, card_data, options) {
102
-    var text = params[0] || "";
103
-    return '<card-subtitle>' + text + '</card-subtitle>';
104
-}
105
-
106
-function card_element_ruler(params, card_data, options) {
107
-    return '<card-rule></card-rule>';
108
-}
109
-
110
-function card_element_boxes(params, card_data, options) {
111
-    var count = params[0] || 1;
112
-    var size = params[1] || 3;
113
-    return '<card-boxes size="' + size + '" count="' + count + '"></card-boxes>';
114
-}
115
-
116
-function card_element_property(params, card_data, options) {
117
-    var header = params[0] || "";
118
-    var text = params[1] || "";
119
-    var result = "";
120
-    result += '<card-property>';
121
-    result += '   <h4>' + header + '</h4>';
122
-    result += '   <p>' + text + '</p>';
123
-    result += '</card-property>';
124
-    return result;
125
-}
126
-
127
-function card_element_description(params, card_data, options) {
128
-    var header = params[0] || "";
129
-    var text = params[1] || "";
130
-    var result = "";
131
-    result += '<card-description>';
132
-    result += '   <h4>' + header + '</h4>';
133
-    result += '   <p>' + text + '</p>';
134
-    result += '</card-description>';
135
-    return result;
136
-}
137
-
138
-function card_element_text(params, card_data, options) {
139
-    var text = params[0] || "";
140
-    var result = "";
141
-    result += '<card-description>';
142
-    result += '   <p>' + text + '</p>';
143
-    result += '</card-description>';
144
-    return result;
145
-}
146
-
147
-function card_element_dndstats(params, card_data, options) {
148
-    var result = "";
149
-    result += '<card-dndstats';
150
-    result += ' str="' + (parseInt(params[0], 10) || "") + '"';
151
-    result += ' dex="' + (parseInt(params[1], 10) || "") + '"';
152
-    result += ' con="' + (parseInt(params[2], 10) || "") + '"';
153
-    result += ' int="' + (parseInt(params[3], 10) || "") + '"';
154
-    result += ' wis="' + (parseInt(params[4], 10) || "") + '"';
155
-    result += ' cha="' + (parseInt(params[5], 10) || "") + '"';
156
-    result += '></card-dndstats>';
157
-    return result;
158
-}
159
-
160
-function card_element_bullet(params, card_data, options) {
161
-    var text = params[0] || "";
162
-    return '<card-bullet>' + text + '</card-bullet>';
163
-}
164
-
165
-function card_element_section(params, card_data, options) {
166
-    var text = params[0] || "";
167
-    return '<card-section>' + text + '</card-section>';
168
-}
169
-
170
-function card_element_fill(params, card_data, options) {
171
-    var size = params[0] || "1";
172
-    return '<card-fill size="' + size + '"></card-fill>';
173
-}
174
-
175
-function card_element_unknown(params, card_data, options) {
176
-    var text = params.join('|');
177
-    return '<card-description><p>' + text + '</p></card-description>';
178
-}
179
-
180
-function card_element_empty(params, card_data, options) {
181
-    return '';
182
-}
183
-
184
-var card_element_generators = {
185
-    subtitle: card_element_subtitle,
186
-    property: card_element_property,
187
-    rule: card_element_ruler,
188
-    ruler: card_element_ruler,
189
-    boxes: card_element_boxes,
190
-    description: card_element_description,
191
-    dndstats: card_element_dndstats,
192
-    text: card_element_text,
193
-    bullet: card_element_bullet,
194
-    fill: card_element_fill,
195
-    section: card_element_section,
196
-    disabled: card_element_empty
197
-};
198
-
199
-// ============================================================================
200
-// Card generating functions
201
-// ============================================================================
202
-
203
-function card_generate_contents(contents, card_data, options) {
204
-    var result = "";
205
-    result += '<card-contents>';
206
-    result += contents.map(function (value) {
207
-        var parts = card_data_split_params(value);
208
-        var element_name = parts[0];
209
-        var element_params = parts.splice(1);
210
-        var element_generator = card_element_generators[element_name];
211
-        if (element_generator) {
212
-            return element_generator(element_params, card_data, options);
213
-        } else if (element_name.length > 0) {
214
-            return card_element_unknown(element_params, card_data, options);
215
-        }
216
-    }).join("\n");
217
-    result += '</card-contents>';
218
-    return result;
219
-}
220
-
221
-function card_repeat(card, count) {
222
-    var result = [];
223
-    for (var i = 0; i < count; ++i) {
224
-        result.push(card);
225
-    }
226
-    return result;
227
-}
228
-
229
-function card_generate_front(data, options) {
230
-    var color = card_data_color_front(data, options);
231
-
232
-    var result = "";
233
-    result += '<rpg-card color="' + color + '" size="' + options.card_size + '">';
234
-    result += card_element_title(data, options);
235
-    result += card_generate_contents(data.contents, data, options);
236
-    result += '</rpg-card>';
237
-    return result;
238
-}
239
-
240
-function card_generate_back(data, options) {
241
-    var color = card_data_color_back(data, options)
242
-    var icon = card_data_icon_back(data, options) + ".svg";
243
-
244
-    var result = "";
245
-    result += '<rpg-card color="' + color + '" size="' + options.card_size + '">';
246
-    result += '   <card-back>';
247
-    result += '       <card-icon src="/icons/' + icon + '"></card-icon>';
248
-    result += '   </card-back>';
249
-    result += '</rpg-card>';
250
-    return result;
251
-}
252
-
253
-function card_generate_empty(count, options) {
254
-    var style_color = card_generate_color_style("white");
255
-
256
-    var result = "";
257
-    result += '<rpg-card color="' + color + '" size="' + options.card_size + '">';
258
-    result += '</rpg-card>';
259
-    return card_repeat(result, count);
260
-}
261
-
262
-// ============================================================================
263
-// Functions that generate pages of cards
264
-// ============================================================================
265
-
266
-function card_pages_split(data, rows, cols) {
267
-    var cards_per_page = rows * cols;
268
-    var result = [];
269
-    for (var i = 0; i < data.length; i += cards_per_page) {
270
-        var page = data.slice(i, i + cards_per_page);
271
-        result.push(page);
272
-    }
273
-    return result;
274
-}
275
-
276
-function card_pages_merge(front_pages, back_pages) {
277
-    var result = [];
278
-    for (var i = 0; i < front_pages.length; ++i) {
279
-        result.push(front_pages[i]);
280
-        result.push(back_pages[i]);
281
-    }
282
-    return result;
283
-}
284
-
285
-function cards_pages_flip_left_right(cards, rows, cols) {
286
-    var result = [];
287
-    for (var r = 0; r < rows; ++r) {
288
-        for (var c = 0; c < cols; ++c) {
289
-            var i = r*cols + (cols-1-c);
290
-            result.push(cards[i]);
291
-        }
292
-    }
293
-    return result;
294
-}
295
-
296
-function card_pages_add_padding(cards, options) {
297
-    var cards_per_page = options.page_rows * options.page_columns;
298
-    var last_page_cards = cards.length % cards_per_page;
299
-    if (last_page_cards !== 0) {
300
-        return cards.concat(card_generate_empty(cards_per_page - last_page_cards, options));
301
-    } else {
302
-        return cards;
303
-    }
304
-}
305
-
306
-function card_pages_interleave_cards(front_cards, back_cards, options) {
307
-    var result = [];
308
-    var i = 0;
309
-    while (i < front_cards.length) {
310
-        result.push(front_cards[i]);
311
-        result.push(back_cards[i]);
312
-        if (options.page_columns > 2) {
313
-            result.push(card_generate_empty(options.page_columns - 2, options));
314
-        }
315
-        ++i;
316
-    }
317
-    return result;
318
-}
319
-
320
-function card_pages_wrap(pages, options) {
321
-    var size = options.page_size || "A4";
322
-
323
-    var result = "";
324
-    for (var i = 0; i < pages.length; ++i) {
325
-        var style = "";
326
-        if ((options.card_arrangement == "doublesided") &&  (i % 2 == 1)) {
327
-            style += 'style="background-color:' + options.background_color + '"';
328
-        } else {
329
-            style += 'style="background-color:' + options.foreground_color + '"';
330
-        }
331
-        result += '<page class="page page-preview" size="' + size + '" ' + style + '>\n';
332
-        result += pages[i].join("\n");
333
-        result += '</page>\n';
334
-    }
335
-    return result;
336
-}
337
-
338
-function card_pages_generate_style(options) {
339
-    var size = "a4";
340
-    switch (options.page_size) {
341
-        case "A3": size = "A3 portrait"; break;
342
-        case "A4": size = "210mm 297mm"; break;
343
-        case "A5": size = "A5 portrait"; break;
344
-        case "Letter": size = "letter portrait"; break;
345
-        case "25x35": size = "2.5in 3.5in"; break;
346
-        default: size = "auto";
347
-    }
348
-
349
-    var result = "";
350
-    result += "<style>\n";
351
-    result += "@page {\n";
352
-    result += "    margin: 0;\n";
353
-    result += "    size:" + size + ";\n";
354
-    result += "    -webkit-print-color-adjust: exact;\n";
355
-    result += "}\n";
356
-    result += "</style>\n";
357
-    return result;
358
-}
359
-
360
-function card_pages_generate_html(card_data, options) {
361
-    options = options || card_default_options();
362
-    var rows = options.page_rows || 3;
363
-    var cols = options.page_columns || 3;
364
-
365
-    // Generate the HTML for each card
366
-    var front_cards = [];
367
-    var back_cards = [];
368
-    card_data.forEach(function (data) {
369
-        var count = options.card_count || data.count || 1;
370
-        var front = card_generate_front(data, options);
371
-        var back = card_generate_back(data, options);
372
-        front_cards = front_cards.concat(card_repeat(front, count));
373
-        back_cards = back_cards.concat(card_repeat(back, count));
374
-    });
375
-
376
-    var pages = [];
377
-    if (options.card_arrangement == "doublesided") {
378
-        // Add padding cards so that the last page is full of cards
379
-        front_cards = card_pages_add_padding(front_cards, options);
380
-        back_cards = card_pages_add_padding(back_cards, options);
381
-
382
-        // Split cards to pages
383
-        var front_pages = card_pages_split(front_cards, rows, cols);
384
-        var back_pages = card_pages_split(back_cards, rows, cols);
385
-
386
-        // Shuffle back cards so that they line up with their corresponding front cards
387
-        back_pages = back_pages.map(function (page) {
388
-            return cards_pages_flip_left_right(page, rows, cols);
389
-        });
390
-
391
-        // Interleave front and back pages so that we can print double-sided
392
-        pages = card_pages_merge(front_pages, back_pages);
393
-    } else if (options.card_arrangement == "front_only") {
394
-        var cards = card_pages_add_padding(front_cards, options);
395
-        pages = card_pages_split(cards, rows, cols);
396
-    } else if (options.card_arrangement == "side_by_side") {
397
-        var cards = card_pages_interleave_cards(front_cards, back_cards, options);
398
-        cards = card_pages_add_padding(cards, options);
399
-        pages = card_pages_split(cards, rows, cols);
400
-    }
401
-
402
-    // Wrap all pages in a <page> element and add CSS for the page size
403
-    var result = "";
404
-    result += card_pages_generate_style(options);
405
-    result += card_pages_wrap(pages, options);
406
-
407
-    return result;
408
-}
409
-
410
-function card_pages_insert_into(card_data, container) {
411
-
412
-    // Clear the previous content of the document
413
-    while (container.hasChildNodes()) {
414
-        container.removeChild(container.lastChild);
415
-    }
416
-
417
-    // Insert the HTML
418
-    var html = card_pages_generate_html(card_data);
419
-    container.innerHTML = html;
420
-}

+ 0
- 158
generator/js/colors.js Zobrazit soubor

@@ -1,158 +0,0 @@
1
-var css_color_names = [
2
-    "Black",
3
-    "Navy",
4
-    "DarkBlue",
5
-    "MediumBlue",
6
-    "Blue",
7
-    "DarkGreen",
8
-    "Green",
9
-    "Teal",
10
-    "DarkCyan",
11
-    "DeepSkyBlue",
12
-    "DarkTurquoise",
13
-    "MediumSpringGreen",
14
-    "Lime",
15
-    "SpringGreen",
16
-    "Aqua",
17
-    "Cyan",
18
-    "MidnightBlue",
19
-    "DodgerBlue",
20
-    "LightSeaGreen",
21
-    "ForestGreen",
22
-    "SeaGreen",
23
-    "DarkSlateGray",
24
-    "LimeGreen",
25
-    "MediumSeaGreen",
26
-    "Turquoise",
27
-    "RoyalBlue",
28
-    "SteelBlue",
29
-    "DarkSlateBlue",
30
-    "MediumTurquoise",
31
-    "Indigo",
32
-    "DarkOliveGreen",
33
-    "CadetBlue",
34
-    "CornflowerBlue",
35
-    "MediumAquaMarine",
36
-    "DimGray",
37
-    "SlateBlue",
38
-    "OliveDrab",
39
-    "SlateGray",
40
-    "LightSlateGray",
41
-    "MediumSlateBlue",
42
-    "LawnGreen",
43
-    "Chartreuse",
44
-    "Aquamarine",
45
-    "Maroon",
46
-    "Purple",
47
-    "Olive",
48
-    "Gray",
49
-    "SkyBlue",
50
-    "LightSkyBlue",
51
-    "BlueViolet",
52
-    "DarkRed",
53
-    "DarkMagenta",
54
-    "SaddleBrown",
55
-    "DarkSeaGreen",
56
-    "LightGreen",
57
-    "MediumPurple",
58
-    "DarkViolet",
59
-    "PaleGreen",
60
-    "DarkOrchid",
61
-    "YellowGreen",
62
-    "Sienna",
63
-    "Brown",
64
-    "DarkGray",
65
-    "LightBlue",
66
-    "GreenYellow",
67
-    "PaleTurquoise",
68
-    "LightSteelBlue",
69
-    "PowderBlue",
70
-    "FireBrick",
71
-    "DarkGoldenRod",
72
-    "MediumOrchid",
73
-    "RosyBrown",
74
-    "DarkKhaki",
75
-    "Silver",
76
-    "MediumVioletRed",
77
-    "IndianRed",
78
-    "Peru",
79
-    "Chocolate",
80
-    "Tan",
81
-    "LightGray",
82
-    "Thistle",
83
-    "Orchid",
84
-    "GoldenRod",
85
-    "PaleVioletRed",
86
-    "Crimson",
87
-    "Gainsboro",
88
-    "Plum",
89
-    "BurlyWood",
90
-    "LightCyan",
91
-    "Lavender",
92
-    "DarkSalmon",
93
-    "Violet",
94
-    "PaleGoldenRod",
95
-    "LightCoral",
96
-    "Khaki",
97
-    "AliceBlue",
98
-    "HoneyDew",
99
-    "Azure",
100
-    "SandyBrown",
101
-    "Wheat",
102
-    "Beige",
103
-    "WhiteSmoke",
104
-    "MintCream",
105
-    "GhostWhite",
106
-    "Salmon",
107
-    "AntiqueWhite",
108
-    "Linen",
109
-    "LightGoldenRodYellow",
110
-    "OldLace",
111
-    "Red",
112
-    "Fuchsia",
113
-    "Magenta",
114
-    "DeepPink",
115
-    "OrangeRed",
116
-    "Tomato",
117
-    "HotPink",
118
-    "Coral",
119
-    "DarkOrange",
120
-    "LightSalmon",
121
-    "Orange",
122
-    "LightPink",
123
-    "Pink",
124
-    "Gold",
125
-    "PeachPuff",
126
-    "NavajoWhite",
127
-    "Moccasin",
128
-    "Bisque",
129
-    "MistyRose",
130
-    "BlanchedAlmond",
131
-    "PapayaWhip",
132
-    "LavenderBlush",
133
-    "SeaShell",
134
-    "Cornsilk",
135
-    "LemonChiffon",
136
-    "FloralWhite",
137
-    "Snow",
138
-    "Yellow",
139
-    "LightYellow",
140
-    "Ivory",
141
-    "White"
142
-];
143
-
144
-
145
-var card_colors = {
146
-    "": "",
147
-    "dimgray": "dimgray",
148
-    "black": "black",
149
-    "darkgoldenrod": "darkgoldenrod",
150
-    "saddlebrown": "saddlebrown",
151
-    "indianred": "indianred",
152
-    "maroon": "maroon",
153
-    "indigo": "indigo",
154
-    "darkblue": "darkblue",
155
-    "royalblue": "royalblue",
156
-    "darkgreen": "darkgreen",
157
-    "#666633": "#666633"
158
-}

+ 163
- 0
generator/js/colors.ts Zobrazit soubor

@@ -0,0 +1,163 @@
1
+
2
+module RpgCardsUI {
3
+
4
+    export var css_color_names = [
5
+        "Black",
6
+        "Navy",
7
+        "DarkBlue",
8
+        "MediumBlue",
9
+        "Blue",
10
+        "DarkGreen",
11
+        "Green",
12
+        "Teal",
13
+        "DarkCyan",
14
+        "DeepSkyBlue",
15
+        "DarkTurquoise",
16
+        "MediumSpringGreen",
17
+        "Lime",
18
+        "SpringGreen",
19
+        "Aqua",
20
+        "Cyan",
21
+        "MidnightBlue",
22
+        "DodgerBlue",
23
+        "LightSeaGreen",
24
+        "ForestGreen",
25
+        "SeaGreen",
26
+        "DarkSlateGray",
27
+        "LimeGreen",
28
+        "MediumSeaGreen",
29
+        "Turquoise",
30
+        "RoyalBlue",
31
+        "SteelBlue",
32
+        "DarkSlateBlue",
33
+        "MediumTurquoise",
34
+        "Indigo",
35
+        "DarkOliveGreen",
36
+        "CadetBlue",
37
+        "CornflowerBlue",
38
+        "MediumAquaMarine",
39
+        "DimGray",
40
+        "SlateBlue",
41
+        "OliveDrab",
42
+        "SlateGray",
43
+        "LightSlateGray",
44
+        "MediumSlateBlue",
45
+        "LawnGreen",
46
+        "Chartreuse",
47
+        "Aquamarine",
48
+        "Maroon",
49
+        "Purple",
50
+        "Olive",
51
+        "Gray",
52
+        "SkyBlue",
53
+        "LightSkyBlue",
54
+        "BlueViolet",
55
+        "DarkRed",
56
+        "DarkMagenta",
57
+        "SaddleBrown",
58
+        "DarkSeaGreen",
59
+        "LightGreen",
60
+        "MediumPurple",
61
+        "DarkViolet",
62
+        "PaleGreen",
63
+        "DarkOrchid",
64
+        "YellowGreen",
65
+        "Sienna",
66
+        "Brown",
67
+        "DarkGray",
68
+        "LightBlue",
69
+        "GreenYellow",
70
+        "PaleTurquoise",
71
+        "LightSteelBlue",
72
+        "PowderBlue",
73
+        "FireBrick",
74
+        "DarkGoldenRod",
75
+        "MediumOrchid",
76
+        "RosyBrown",
77
+        "DarkKhaki",
78
+        "Silver",
79
+        "MediumVioletRed",
80
+        "IndianRed",
81
+        "Peru",
82
+        "Chocolate",
83
+        "Tan",
84
+        "LightGray",
85
+        "Thistle",
86
+        "Orchid",
87
+        "GoldenRod",
88
+        "PaleVioletRed",
89
+        "Crimson",
90
+        "Gainsboro",
91
+        "Plum",
92
+        "BurlyWood",
93
+        "LightCyan",
94
+        "Lavender",
95
+        "DarkSalmon",
96
+        "Violet",
97
+        "PaleGoldenRod",
98
+        "LightCoral",
99
+        "Khaki",
100
+        "AliceBlue",
101
+        "HoneyDew",
102
+        "Azure",
103
+        "SandyBrown",
104
+        "Wheat",
105
+        "Beige",
106
+        "WhiteSmoke",
107
+        "MintCream",
108
+        "GhostWhite",
109
+        "Salmon",
110
+        "AntiqueWhite",
111
+        "Linen",
112
+        "LightGoldenRodYellow",
113
+        "OldLace",
114
+        "Red",
115
+        "Fuchsia",
116
+        "Magenta",
117
+        "DeepPink",
118
+        "OrangeRed",
119
+        "Tomato",
120
+        "HotPink",
121
+        "Coral",
122
+        "DarkOrange",
123
+        "LightSalmon",
124
+        "Orange",
125
+        "LightPink",
126
+        "Pink",
127
+        "Gold",
128
+        "PeachPuff",
129
+        "NavajoWhite",
130
+        "Moccasin",
131
+        "Bisque",
132
+        "MistyRose",
133
+        "BlanchedAlmond",
134
+        "PapayaWhip",
135
+        "LavenderBlush",
136
+        "SeaShell",
137
+        "Cornsilk",
138
+        "LemonChiffon",
139
+        "FloralWhite",
140
+        "Snow",
141
+        "Yellow",
142
+        "LightYellow",
143
+        "Ivory",
144
+        "White"
145
+    ];
146
+
147
+
148
+    export var card_colors = {
149
+        "": "",
150
+        "dimgray": "dimgray",
151
+        "black": "black",
152
+        "darkgoldenrod": "darkgoldenrod",
153
+        "saddlebrown": "saddlebrown",
154
+        "indianred": "indianred",
155
+        "maroon": "maroon",
156
+        "indigo": "indigo",
157
+        "darkblue": "darkblue",
158
+        "royalblue": "royalblue",
159
+        "darkgreen": "darkgreen",
160
+        "#666633": "#666633"
161
+    }
162
+
163
+}

+ 166
- 0
generator/js/example_data.ts Zobrazit soubor

@@ -0,0 +1,166 @@
1
+module RpgCardsUI {
2
+
3
+    export var card_data_example = [
4
+        {
5
+            "count": 1,
6
+            "color": "maroon",
7
+            "title": "Burning Hands",
8
+            "icon": "book-cover",
9
+            "icon_back": "robe",
10
+            "contents": [
11
+                "subtitle | 1st level evocation",
12
+                "rule",
13
+                "property | Casting time | 1 action",
14
+                "property | Range | Self (15ft cone)",
15
+                "property | Components | V,S",
16
+                "rule",
17
+                "fill | 2",
18
+                "text | Each creature in a 15-foot cone must make a Dexterity saving throw. A creature takes <b>3d6 fire damage</b> on a failed save, or half as much damage on a successful one.",
19
+                "text | The fire ignites any flammable objects in the area that aren't being worn or carried.",
20
+                "fill | 3",
21
+                "section | At higher levels",
22
+                "text | +1d6 damage for each slot above 1st"
23
+            ],
24
+            "tags": ["spell", "mage"]
25
+        },
26
+        {
27
+            "count": 1,
28
+            "color": "indigo",
29
+            "title": "Cunning Action",
30
+            "icon": "white-book",
31
+            "icon_back": "cloak-dagger",
32
+            "contents": [
33
+                "subtitle | Rogue feature",
34
+                "rule",
35
+                "fill | 2",
36
+                "text | You can take a <b>bonus action on each of your turns</b> in combat. This action can be used only to take the <b>Dash, Disengage, or Hide</b> action.",
37
+                "fill | 2",
38
+                "section | Fast hands (Thief 3rd)",
39
+                "text | You can also use the bonus action to make a Dexterity (<b>Sleight of Hand</b>) check, use your thieves' tools to <b>disarm a trap</b> or <b>open a lock</b>, or take the <b>Use an Object</b> action."
40
+            ],
41
+            "tags": ["feature", "rogue"]
42
+        },
43
+        {
44
+            "count": 1,
45
+            "color": "dimgray",
46
+            "title": "Full Plate",
47
+            "icon": "breastplate",
48
+            "contents": [
49
+                "subtitle | Heavy armor (1500gp)",
50
+                "rule",
51
+                "property | AC | 18",
52
+                "property | Strength required | 15",
53
+                "property | Stealth | Disadvantage",
54
+                "rule",
55
+                "fill | 2",
56
+                "description | Heavy | Unless you have the required strength, your speed is reduced by 10 feet.",
57
+                "description | Stealth | You have disadvantage on Dexterity (Stealth) checks.",
58
+                "fill | 3"
59
+            ],
60
+            "tags": ["item", "armor"]
61
+        },
62
+        {
63
+            "count": 1,
64
+            "color": "dimgray",
65
+            "title": "Dagger",
66
+            "icon": "mixed-swords",
67
+            "contents": [
68
+                "subtitle | Simple melee weapon (2gp)",
69
+                "rule",
70
+                "property | Damage | 1d4 piercing",
71
+                "property | Modifier | Strength or Dexterity",
72
+                "property | Properties | Light, Finesse, Thrown (20/60)",
73
+                "rule",
74
+                "fill | 2",
75
+                "description | Finesse | Use your choice of Strength or Dexterity modifier for attack and damage.",
76
+                "description | Light | When you attack while dual wielding light weapons, you may use a bonus action to attack with your off hand.",
77
+                "description | Thrown | You can throw the weapon to make a ranged attack with the given range.",
78
+                "fill | 3"
79
+            ],
80
+            "tags": ["item", "weapon"]
81
+        },
82
+        {
83
+            "count": 1,
84
+            "color": "dimgray",
85
+            "title": "Shortsword of Very Long Names",
86
+            "title_size": "10",
87
+            "icon": "crossed-swords",
88
+            "contents": [
89
+                "subtitle | Simple melee weapon (10gp)",
90
+                "rule",
91
+                "property | Damage | 1d6 piercing",
92
+                "property | Modifier | Strength or Dexterity",
93
+                "property | Properties | Light, Finesse",
94
+                "rule",
95
+                "fill | 2",
96
+                "description | Finesse | Use your choice of Strength or Dexterity modifier for attack and damage.",
97
+                "description | Light | When you attack while dual wielding light weapons, you may use a bonus action to attack with your off hand.",
98
+                "fill | 3"
99
+            ],
100
+            "tags": ["item", "weapon", "magic"]
101
+        },
102
+        {
103
+            "count": 1,
104
+            "color": "dimgray",
105
+            "title": "Wand of Magic Missiles",
106
+            "icon": "crystal-wand",
107
+            "contents": [
108
+                "subtitle | Wondrous item",
109
+                "rule",
110
+                "property | Maximum charges | 7",
111
+                "property | Recharge | 1d6+1 each day",
112
+                "property | Depletion | If you expend the last charge, roll a d20. On a 1, the item is destroyed.",
113
+                "rule",
114
+                "fill | 2",
115
+                "description | Spells | You can use your action to cast the following spells:",
116
+                "bullet | magic missile, 1st level (1 charge)",
117
+                "bullet | magic missile, 2nd level (2 charges)",
118
+                "bullet | magic missile, 3rd level (3 charges)",
119
+                "fill | 3",
120
+                "boxes | 7 | 2.5"
121
+            ],
122
+            "tags": ["item", "wondrous-item", "magic"]
123
+        },
124
+        {
125
+            "count": 2,
126
+            "color": "dimgray",
127
+            "title": "Potion of Healing",
128
+            "icon": "drink-me",
129
+            "contents": [
130
+                "subtitle | Potion (50gp)",
131
+                "rule",
132
+                "property | Use time | 1 action",
133
+                "property | Hit points restored | 2d4+2",
134
+                "rule",
135
+                "fill | 2",
136
+                "text | When you drink this potion, you regain 2d4+2 hitpoints.",
137
+                "text | Drinking or administering a potion takes 1 action.",
138
+                "fill | 3"
139
+            ],
140
+            "tags": ["item", "consumable"]
141
+        },
142
+        {
143
+            "count": 1,
144
+            "color": "black",
145
+            "title": "Goblin",
146
+            "icon": "imp-laugh",
147
+            "contents": [
148
+                "subtitle | Small humanoid (goblinoid)",
149
+                "rule",
150
+                "property | Armor class | 15 (leather armor, shield)",
151
+                "property | Hit points | 7 (2d6)",
152
+                "rule",
153
+                "dndstats | 8 | 14 | 10 | 10 | 8 | 8",
154
+                "rule",
155
+                "property | Skills | Stealth +6",
156
+                "property | Challenge | 1/4 (50 XP)",
157
+                "rule",
158
+                "description | Nimble escape | Disengage or Hide as bonus action",
159
+                "fill | 2",
160
+                "section | Actions",
161
+                "description | Scimitar | Melee Weapon Attack: +4 to hit, reach 5 ft., one target. Hit: 5 (1d6 + 2) slashing damage"
162
+            ],
163
+            "tags": ["creature", "humanoid"]
164
+        }
165
+    ];
166
+}

+ 0
- 1336
generator/js/icons.js
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 1328
- 0
generator/js/icons.ts
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 0
- 22
generator/js/output.js Zobrazit soubor

@@ -1,22 +0,0 @@
1
-function receiveMessage(event) {
2
-    var html = event.data;
3
-    insertCards(html);
4
-}
5
-
6
-function insertCards(html) {
7
-    // Remove all previous content
8
-    while (document.body.hasChildNodes()) {
9
-        document.body.removeChild(document.body.lastChild);
10
-    }
11
-
12
-    // Create a div that holds all the received HTML
13
-    var div = document.createElement("div");
14
-    div.setAttribute("class", "output-container");
15
-    div.id = "output-container";
16
-    div.innerHTML = html;
17
-
18
-    // Add the new div to the document
19
-    document.body.appendChild(div);
20
-}
21
-
22
-window.addEventListener("message", receiveMessage, false);

+ 0
- 482
generator/js/ui.js Zobrazit soubor

@@ -1,482 +0,0 @@
1
-// Ugly global variable holding the current card deck
2
-var card_data = [];
3
-var card_options = card_default_options();
4
-
5
-function mergeSort(arr, compare) {
6
-    if (arr.length < 2)
7
-        return arr;
8
-
9
-    var middle = parseInt(arr.length / 2);
10
-    var left = arr.slice(0, middle);
11
-    var right = arr.slice(middle, arr.length);
12
-
13
-    return merge(mergeSort(left, compare), mergeSort(right, compare), compare);
14
-}
15
-
16
-function merge(left, right, compare) {
17
-    var result = [];
18
-
19
-    while (left.length && right.length) {
20
-        if (compare(left[0], right[0]) <= 0) {
21
-            result.push(left.shift());
22
-        } else {
23
-            result.push(right.shift());
24
-        }
25
-    }
26
-
27
-    while (left.length)
28
-        result.push(left.shift());
29
-
30
-    while (right.length)
31
-        result.push(right.shift());
32
-
33
-    return result;
34
-}
35
-
36
-var ui_generate_modal_shown = false;
37
-function ui_generate() {
38
-    if (card_data.length == 0) {
39
-        alert("Your deck is empty. Please define some cards first, or load the sample deck.");
40
-        return;
41
-    }
42
-
43
-    // Generate output HTML
44
-    var card_html = card_pages_generate_html(card_data, card_options);
45
-
46
-    // Open a new window for the output
47
-    // Use a separate window to avoid CSS conflicts
48
-    var tab = window.open("output.html", 'rpg-cards-output');
49
-
50
-    if (ui_generate_modal_shown == false) {
51
-        $("#print-modal").modal('show');
52
-        ui_generate_modal_shown = true;
53
-    }
54
-
55
-    // Send the generated HTML to the new window
56
-    // Use a delay to give the new window time to set up a message listener
57
-    setTimeout(function () { tab.postMessage(card_html, '*') }, 500);
58
-}
59
-
60
-function ui_load_sample() {
61
-    card_data = card_data_example;
62
-    ui_init_cards(card_data);
63
-    ui_update_card_list();
64
-}
65
-
66
-function ui_clear_all() {
67
-    card_data = [];
68
-    ui_update_card_list();
69
-}
70
-
71
-function ui_load_files(evt) {
72
-    // ui_clear_all();
73
-
74
-    var files = evt.target.files;
75
-
76
-    for (var i = 0, f; f = files[i]; i++) {
77
-        var reader = new FileReader();
78
-
79
-        reader.onload = function (reader) {
80
-            var data = JSON.parse(this.result);
81
-            ui_add_cards(data);
82
-        };
83
-
84
-        reader.readAsText(f);
85
-    }
86
-
87
-    // Reset file input
88
-    $("#file-load-form")[0].reset();
89
-}
90
-
91
-function ui_init_cards(data) {
92
-    data.forEach(function (card) {
93
-        card_init(card);
94
-    });
95
-}
96
-
97
-function ui_add_cards(data) {
98
-    ui_init_cards(data);
99
-    card_data = card_data.concat(data);
100
-    ui_update_card_list();
101
-}
102
-
103
-function ui_add_new_card() {
104
-    card_data.push(card_default_data());
105
-    ui_update_card_list();
106
-    ui_select_card_by_index(card_data.length - 1);
107
-}
108
-
109
-function ui_duplicate_card() {
110
-    if (card_data.length > 0) {
111
-        var old_card = ui_selected_card();
112
-        var new_card = $.extend({}, old_card);
113
-        card_data.push(new_card);
114
-        new_card.title = new_card.title + " (Copy)";
115
-    } else {
116
-        card_data.push(card_default_data());
117
-    }
118
-    ui_update_card_list();
119
-    ui_select_card_by_index(card_data.length - 1);
120
-}
121
-
122
-function ui_select_card_by_index(index) {
123
-    $("#selected-card").val(index);
124
-    ui_update_selected_card();
125
-}
126
-
127
-function ui_selected_card_index() {
128
-    return parseInt($("#selected-card").val(), 10);
129
-}
130
-
131
-function ui_selected_card() {
132
-    return card_data[ui_selected_card_index()];
133
-}
134
-
135
-function ui_delete_card() {
136
-    var index = ui_selected_card_index();
137
-    card_data.splice(index, 1);
138
-    ui_update_card_list();
139
-    ui_select_card_by_index(Math.min(index, card_data.length - 1));
140
-}
141
-
142
-function ui_update_card_list() {
143
-    $("#total_card_count").text("Deck contains " + card_data.length + " unique cards.");
144
-
145
-    $('#selected-card').empty();
146
-    for (var i = 0; i < card_data.length; ++i) {
147
-        var card = card_data[i];
148
-        $('#selected-card')
149
-            .append($("<option></option>")
150
-            .attr("value", i)
151
-            .text(card.title));
152
-    }
153
-
154
-    ui_update_selected_card();
155
-}
156
-
157
-function ui_save_file() {
158
-    var str = JSON.stringify(card_data, null, "  ");
159
-    var parts = [str];
160
-    var blob = new Blob(parts, { type: 'application/json' });
161
-    var url = URL.createObjectURL(blob);
162
-
163
-    var a = $("#file-save-link")[0];
164
-    a.href = url;
165
-    a.download = "rpg_cards.json";
166
-    a.click();
167
-
168
-    setTimeout(function () { URL.revokeObjectURL(url); }, 500);
169
-}
170
-
171
-function ui_update_selected_card() {
172
-    var card = ui_selected_card();
173
-    if (card) {
174
-        $("#card-title").val(card.title);
175
-        $("#card-title-size").val(card.title_size);
176
-        $("#card-count").val(card.count);
177
-        $("#card-icon").val(card.icon);
178
-        $("#card-icon-back").val(card.icon_back);
179
-        $("#card-contents").val(card.contents.join("\n"));
180
-        $("#card-tags").val(card.tags.join(", "));
181
-        $("#card-color").val(card.color).change();
182
-    } else {
183
-        $("#card-title").val("");
184
-        $("#card-title-size").val("");
185
-        $("#card-count").val(1);
186
-        $("#card-icon").val("");
187
-        $("#card-icon-back").val("");
188
-        $("#card-contents").val("");
189
-        $("#card-tags").val("");
190
-        $("#card-color").val("").change();
191
-    }
192
-
193
-    ui_render_selected_card();
194
-}
195
-
196
-function ui_render_selected_card() {
197
-    var card = ui_selected_card();
198
-    $('#preview-container').empty();
199
-    if (card) {
200
-        var front = card_generate_front(card, card_options);
201
-        var back = card_generate_back(card, card_options);
202
-        $('#preview-container').html(front + "\n" + back);
203
-    }
204
-}
205
-
206
-function ui_open_help() {
207
-    $("#help-modal").modal('show');
208
-}
209
-
210
-function ui_select_icon() {
211
-    window.open("http://game-icons.net/", "_blank");
212
-}
213
-
214
-function ui_setup_color_selector() {
215
-    // Insert colors
216
-    $.each(card_colors, function (name, val) {
217
-        $(".colorselector-data")
218
-            .append($("<option></option>")
219
-            .attr("value", name)
220
-            .attr("data-color", val)
221
-            .text(name));
222
-    });
223
-    
224
-    // Callbacks for when the user picks a color
225
-    $('#default_color_selector').colorselector({
226
-        callback: function (value, color, title) {
227
-            $("#default-color").val(title);
228
-            ui_set_default_color(title);
229
-        }
230
-    });
231
-    $('#card_color_selector').colorselector({
232
-        callback: function (value, color, title) {
233
-            $("#card-color").val(title);
234
-            ui_set_card_color(value);
235
-        }
236
-    });
237
-    $('#foreground_color_selector').colorselector({
238
-        callback: function (value, color, title) {
239
-            $("#foreground-color").val(title);
240
-            ui_set_foreground_color(value);
241
-        }
242
-    });
243
-    $('#background_color_selector').colorselector({
244
-        callback: function (value, color, title) {
245
-            $("#background-color").val(title);
246
-            ui_set_background_color(value);
247
-        }
248
-    });
249
-
250
-    // Styling
251
-    $(".dropdown-colorselector").addClass("input-group-addon color-input-addon");
252
-}
253
-
254
-function ui_set_default_color(color) {
255
-    card_options.default_color = color;
256
-    ui_render_selected_card();
257
-}
258
-
259
-function ui_set_foreground_color(color) {
260
-    card_options.foreground_color = color;
261
-}
262
-
263
-function ui_set_background_color(color) {
264
-    card_options.background_color = color;
265
-}
266
-
267
-function ui_change_option() {
268
-    var property = $(this).attr("data-option");
269
-    var value = $(this).val();
270
-    card_options[property] = value;
271
-    ui_render_selected_card();
272
-
273
-}
274
-
275
-function ui_change_card_title() {
276
-    var title = $("#card-title").val();
277
-    var card = ui_selected_card();
278
-    if (card) {
279
-        card.title = title;
280
-        $("#selected-card option:selected").text(title);
281
-        ui_render_selected_card();
282
-    }
283
-}
284
-
285
-function ui_change_card_property() {
286
-    var property = $(this).attr("data-property");
287
-    var value = $(this).val();
288
-    var card = ui_selected_card();
289
-    if (card) {
290
-        card[property] = value;
291
-        ui_render_selected_card();
292
-    }
293
-}
294
-
295
-function ui_set_card_color(value) {
296
-    var card = ui_selected_card();
297
-    if (card) {
298
-        card.color = value;
299
-        ui_render_selected_card();
300
-    }
301
-}
302
-
303
-function ui_update_card_color_selector(color, input, selector) {
304
-    if ($(selector + " option[value='" + color + "']").length > 0) {
305
-        // Update the color selector to the entered value
306
-        $(selector).colorselector("setValue", color);
307
-    } else {
308
-        // Unknown color - select a neutral color and reset the text value
309
-        $(selector).colorselector("setValue", "");
310
-        input.val(color);
311
-    }
312
-}
313
-
314
-function ui_change_card_color() {
315
-    var input = $(this);
316
-    var color = input.val();
317
-
318
-    ui_update_card_color_selector(color, input, "#card_color_selector");
319
-    ui_set_card_color(color);
320
-}
321
-
322
-function ui_change_default_color() {
323
-    var input = $(this);
324
-    var color = input.val();
325
-
326
-    ui_update_card_color_selector(color, input, "#default_color_selector");
327
-    ui_set_default_color(color);
328
-}
329
-
330
-function ui_change_default_icon() {
331
-    var value = $(this).val();
332
-    card_options.default_icon = value;
333
-    ui_render_selected_card();
334
-}
335
-
336
-function ui_change_card_contents() {
337
-    var value = $(this).val();
338
-
339
-    var card = ui_selected_card();
340
-    if (card) {
341
-        card.contents = value.split("\n");
342
-        ui_render_selected_card();
343
-    }
344
-}
345
-
346
-function ui_change_card_tags() {
347
-    var value = $(this).val();
348
-
349
-    var card = ui_selected_card();
350
-    if (card) {
351
-        if (value.trim().length == 0) {
352
-            card.tags = [];
353
-        } else {
354
-            card.tags = value.split(",").map(function (val) {
355
-                return val.trim().toLowerCase();
356
-            });
357
-        }
358
-        ui_render_selected_card();
359
-    }
360
-}
361
-
362
-function ui_change_default_title_size() {
363
-    card_options.default_title_size = $(this).val();
364
-    ui_render_selected_card();
365
-}
366
-
367
-function ui_change_default_icon_size() {
368
-    card_options.icon_inline = $(this).is(':checked');
369
-    ui_render_selected_card();
370
-}
371
-
372
-function ui_sort() {
373
-    $("#sort-modal").modal('show');
374
-}
375
-
376
-function ui_sort_execute() {
377
-    $("#sort-modal").modal('hide');
378
-
379
-    var fn_code = $("#sort-function").val();
380
-    var fn = new Function("card_a", "card_b", fn_code);
381
-
382
-    card_data = card_data.sort(function (card_a, card_b) {
383
-        var result = fn(card_a, card_b);
384
-        return result;
385
-    });
386
-
387
-    ui_update_card_list();
388
-}
389
-
390
-function ui_filter() {
391
-    $("#filter-modal").modal('show');
392
-}
393
-
394
-function ui_filter_execute() {
395
-    $("#filter-modal").modal('hide');
396
-
397
-    var fn_code = $("#filter-function").val();
398
-    var fn = new Function("card", fn_code);
399
-
400
-    card_data = card_data.filter(function (card) {
401
-        var result = fn(card);
402
-        if (result === undefined) return true;
403
-        else return result;
404
-    });
405
-
406
-    ui_update_card_list();
407
-}
408
-
409
-function ui_apply_default_color() {
410
-    for (var i = 0; i < card_data.length; ++i) {
411
-        card_data[i].color = card_options.default_color;
412
-    }
413
-    ui_render_selected_card();
414
-}
415
-
416
-function ui_apply_default_icon() {
417
-    for (var i = 0; i < card_data.length; ++i) {
418
-        card_data[i].icon = card_options.default_icon;
419
-    }
420
-    ui_render_selected_card();
421
-}
422
-
423
-function ui_apply_default_icon_back() {
424
-    for (var i = 0; i < card_data.length; ++i) {
425
-        card_data[i].icon_back = card_options.default_icon;
426
-    }
427
-    ui_render_selected_card();
428
-}
429
-
430
-$(document).ready(function () {
431
-    ui_setup_color_selector();
432
-    $('.icon-list').typeahead({source:icon_names});
433
-
434
-    $("#button-generate").click(ui_generate);
435
-    $("#button-load").click(function () { $("#file-load").click(); });
436
-    $("#file-load").change(ui_load_files);
437
-    $("#button-clear").click(ui_clear_all);
438
-    $("#button-load-sample").click(ui_load_sample);
439
-    //$("#button-save").click(ui_save_file);
440
-    $("#button-sort").click(ui_sort);
441
-    $("#button-filter").click(ui_filter);
442
-    $("#button-add-card").click(ui_add_new_card);
443
-    $("#button-duplicate-card").click(ui_duplicate_card);
444
-    $("#button-delete-card").click(ui_delete_card);
445
-    $("#button-help").click(ui_open_help);
446
-    $("#button-apply-color").click(ui_apply_default_color);
447
-    $("#button-apply-icon").click(ui_apply_default_icon);
448
-    $("#button-apply-icon-back").click(ui_apply_default_icon_back);
449
-
450
-    $("#selected-card").change(ui_update_selected_card);
451
-
452
-    $("#card-title").change(ui_change_card_title);
453
-    $("#card-title-size").change(ui_change_card_property);
454
-    $("#card-icon").change(ui_change_card_property);
455
-    $("#card-count").change(ui_change_card_property);
456
-    $("#card-icon-back").change(ui_change_card_property);
457
-    $("#card-color").change(ui_change_card_color);
458
-    $("#card-contents").change(ui_change_card_contents);
459
-    $("#card-tags").change(ui_change_card_tags);
460
-
461
-    $("#page-size").change(ui_change_option);
462
-    $("#page-rows").change(ui_change_option);
463
-    $("#page-columns").change(ui_change_option);
464
-    $("#card-arrangement").change(ui_change_option);
465
-    $("#card-size").change(ui_change_option);
466
-    $("#background-color").change(ui_change_option);
467
-
468
-    $("#default-color").change(ui_change_default_color);
469
-    $("#default-icon").change(ui_change_default_icon);
470
-    $("#default-title-size").change(ui_change_default_title_size);
471
-    $("#small-icons").change(ui_change_default_icon_size);
472
-
473
-    $(".icon-select-button").click(ui_select_icon);
474
-
475
-    $("#sort-execute").click(ui_sort_execute);
476
-    $("#filter-execute").click(ui_filter_execute);
477
-    
478
-    ui_update_card_list();
479
-});
480
-
481
-
482
-

+ 524
- 0
generator/js/ui.ts Zobrazit soubor

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

+ 7
- 0
make.bat Zobrazit soubor

@@ -0,0 +1,7 @@
1
+@ECHO building card.js
2
+@CALL node node_modules/typescript/bin/tsc generator/js/card.ts -t ES6 -sourcemap -d --out generator/js/card.js
3
+
4
+@ECHO building ui.js
5
+@CALL node node_modules/typescript/bin/tsc generator/js/ui.ts -t ES6 -sourcemap -d --out generator/js/ui.js
6
+
7
+@PAUSE

Loading…
Zrušit
Uložit