summaryrefslogtreecommitdiff
path: root/docroot/classes/card.class.js
diff options
context:
space:
mode:
Diffstat (limited to 'docroot/classes/card.class.js')
-rwxr-xr-xdocroot/classes/card.class.js378
1 files changed, 378 insertions, 0 deletions
diff --git a/docroot/classes/card.class.js b/docroot/classes/card.class.js
new file mode 100755
index 0000000..e135259
--- /dev/null
+++ b/docroot/classes/card.class.js
@@ -0,0 +1,378 @@
1/*
2 * Material Experience - Card Class
3 *
4 * EYEMG - Interactive Media Group
5 * Created by Mike Crute (mcrute@eyemg.com)
6 * Updated by Mike Crute (mcrute@eyemg.com) on 9/26/07
7 */
8
9var Card = Class.create();
10Object.extend(Card.prototype,
11{
12 /*
13 * Creates the card and appends it to the document. This does
14 * not set the content.
15 */
16 initialize: function()
17 {
18 this.options = Object.extend(
19 {
20 title: 'New Card', // Card Title
21 id: 'mycard', // Card ID
22 preview: false, // This is a preview card
23 addExtraButtons: true, // Add the extra buttons to non-system cards
24 contID: null, // Content ID of the card's contents
25 color: SME.colors.blue, // Card Color
26 width: SME.sizes.card.width, // Card Width
27 height: SME.sizes.card.height, // Card Height
28 onClose: Prototype.emptyFunction, // Card Close Callback
29 onFadeComplete: Prototype.emptyFunction, // Card Fade Completion Callback
30 onFadeOutFinish: Prototype.emptyFunction // Card Fade Out Completion Callback
31 }, arguments[0] || {});
32
33 // Keep track of our card chip
34 this.chip = this.options.chip;
35
36 // Buttons on the card frame
37 this.buttons = [];
38
39 // Create the document overlay but don't yet show it
40 this.overlay = new Overlay(
41 {
42 onClick: function()
43 {
44 this.hide();
45 }.bind(this)
46 });
47
48 this._createCard();
49
50 if (this.options.addExtraButtons)
51 {
52 this._addExtraButtons();
53 }
54
55 // Always add a close button
56 this.addCommandButton(Strings.closeCard,'images/close.gif', function()
57 {
58 this.hide();
59 }.bind(this));
60
61 this.setTitle(this.options.title);
62 },
63
64 /*
65 * Create the card DOM nodes.
66 */
67 _createCard: function()
68 {
69 // Get the rounded corner generator and the coordinates of the page center
70 var Rounder = new RoundedCorners(this.options.color);
71 var cardPos = window.calcCordsToCenter(this.options.height, this.options.width);
72 var slicebox = Rounder.get(Rounder.directions.top);
73
74 // Intro card will flash across the screen while card builds but
75 // before fading up if display is not set to none
76 this.card = Builder.node('div',
77 {
78 id: this.options.id,
79 style: 'display: none;',
80 className: 'card'
81 });
82
83 // Create the card header with title and button box
84 slicebox.appendChild(this.title = Builder.node('span', { className: 'cardTitle' }));
85 slicebox.appendChild(this.buttonbox = Builder.node('div', { className: 'buttonbox' },
86 this.buttonLabel = Builder.node('span', { className: 'commandlabel' })
87 ));
88
89 // Append the header and the card content area
90 this.card.appendChild(slicebox);
91 this.card.appendChild(Builder.node('div', { style: 'background: white; opacity: 100%;' },
92 this.cframe = Builder.node('div')
93 ));
94
95 // Append the bottom of the card frame and add the card to the document
96 this.card.appendChild(Rounder.get(Rounder.directions.bottom));
97 document.body.appendChild(this.card);
98
99 // Card frame styles
100 Element.extend(this.cframe).setStyle(
101 {
102 width: this.options.width - 11 + 'px',
103 height: this.options.height - 40 + 'px',
104 borderLeft: '5px solid ' + this.options.color,
105 borderRight: '5px solid ' + this.options.color,
106 borderTop: '10px solid ' + this.options.color,
107 position: 'relative',
108 overflow: 'hidden'
109 });
110
111 // Card styles
112 Element.extend(this.card).setStyle(
113 {
114 height: this.options.height + 'px',
115 width: this.options.width + 'px',
116 top: cardPos.top + 'px',
117 left: cardPos.left + 'px',
118 zIndex: 9001,
119 opacity: '100%',
120 display: 'none',
121 position: 'absolute'
122 });
123
124 // Make the card draggable
125 this.drag = new Draggable(this.card,
126 {
127 handle: 'round',
128 zindex: 9001,
129 starteffect: null,
130 endeffect: null
131 });
132 },
133
134 /*
135 * Add a command button to the top right of the card.
136 */
137 addCommandButton: function(title, icon, action)
138 {
139 var newButton = Builder.node('img', { className: 'commandbtn', src: icon });
140
141 // Show the label on mouseover
142 Event.observe(newButton, 'mouseover', function()
143 {
144 this.buttonLabel.innerHTML = title;
145 }.bindAsEventListener(this));
146
147 // Hide the label on mouse out
148 Event.observe(newButton, 'mouseout', function()
149 {
150 this.buttonLabel.innerHTML = '';
151 }.bindAsEventListener(this));
152
153 // Take the action specified when the button is clicked
154 Event.observe(newButton, 'click', function(event)
155 {
156 action(event);
157 });
158
159 // Add the button to the button box and cache it.
160 this.buttons[title] = this.buttonbox.appendChild(newButton);
161 },
162
163 /*
164 * Removes a command button from the card.
165 */
166 removeCommandButton: function(button)
167 {
168 this.buttonLabel.innerHTML = '';
169 this.buttonbox.removeChild(this.buttons[button]);
170 },
171
172 /*
173 * Sets the title of the card.
174 */
175 setTitle: function(title)
176 {
177 this.options.title = title;
178 this.title.innerHTML = title;
179 },
180
181 /*
182 * Disables the drag on the card and removes the card
183 * from the DOM.
184 */
185 destroy: function()
186 {
187 // Kill the drag to prevent probable memory leaks in IE
188 this.drag.destroy();
189
190 // Remove the card from the DOM
191 document.body.removeChild(this.card);
192
193 // Destroy the overlay
194 this.overlay.destroy();
195 },
196
197 /*
198 * Display the card.
199 */
200 show: function()
201 {
202 // Track the currently active card for the history manager
203 // FLAWED LOGIC: We can have multiple cards visible at the same
204 // time.
205 SME.currentCard = this;
206
207 // Get card positioning data
208 var cardPos = window.calcCordsToCenter(this.options.height, this.options.width);
209 var windSize = window.getDimensions();
210
211 // Position the card
212 this.card.setStyle(
213 {
214 top: cardPos.top + 'px',
215 left: cardPos.left + 'px'
216 });
217
218 this._autoSetLayout();
219
220 // Show the overlay first so it will fade in with the card
221 this.overlay.show();
222
223 // Fade the card in and run its fadeComplete function.
224 new Effect.Appear(this.card,
225 {
226 afterFinish: function()
227 {
228 this.options.onFadeComplete();
229 }.bind(this)
230 });
231 },
232
233 /*
234 * Automatically set the layout based on the content of a JSON feed
235 * if it is supplied.
236 */
237 _autoSetLayout: function()
238 {
239 // Fetch data only if this is not an intro card and a content
240 // id has been specified.
241 if (!this.options.contID)
242 {
243 return;
244 }
245
246 // Pull the correct data if this is a preview or a real
247 // card.
248 if (this.options.preview)
249 {
250 var theUrl = SME.url.cardPreview.evaluate({card: this.options.contID})
251 }
252 else
253 {
254 var theUrl = SME.url.cards.evaluate({card: this.options.contID});
255 }
256
257 new Ajax.Request(theUrl,
258 {
259 method: 'get',
260
261 onSuccess: function(transport)
262 {
263 try
264 {
265 var data = transport.responseText.cleanJSON().evalJSON();
266 this.setLayout(SME.engineMapping[data.template], data);
267 }
268 catch (exception)
269 {
270 if (SME.debug)
271 {
272 console.error(exception);
273 }
274
275 this.setLayout(Card.Layout.Errors, '');
276 }
277 }.bind(this)
278 });
279 },
280
281 /*
282 * Add extra buttons to a card. I moved this to its own private
283 * function because some cards, like system cards, don't need all
284 * those extra buttons.
285 */
286 _addExtraButtons: function()
287 {
288 this.addCommandButton(Strings.addToSketchbook,'images/plus.gif', function()
289 {
290 SME.sketchbook.addChip(this.options.contID);
291 }.bind(this));
292
293 this.addCommandButton(Strings.sendToFriend,'images/email.gif', function()
294 {
295 if ($('cardFlash'))
296 {
297 this.flashP = $('cardFlash').up();
298 this.flash = $('cardFlash').remove();
299 }
300
301 var card = new Card(
302 {
303 color: SME.colors.grey,
304 title: Strings.sendToFriend,
305 addExtraButtons: false,
306
307 onFadeComplete: function()
308 {
309 if (this.flash)
310 {
311 this.flashP.appendChild(this.flash);
312 this.flash = null;
313 }
314 }.bind(this)
315 });
316
317 card.setLayout(Card.Layout.Special,
318 {
319 url: SME.url.sendToFriend.evaluate(
320 {
321 durl: 'card' + encodeURI(this.options.contID),
322 title: encodeURI(this.options.title)
323 })
324 });
325
326 card.show();
327 }.bind(this));
328
329 this.addCommandButton(Strings.printCard, 'images/print.gif', function()
330 {
331 this.layoutEngine.print();
332 }.bind(this));
333
334 // Card history ON the card was poorly designed and implemented
335 // (yeah, I know) so I'm just removing it for now till I get
336 // some time to re-write it.
337 //
338 // TODO: Re-write this
339 this.addCommandButton(Strings.myHistory,'images/history.gif', function()
340 {
341 var center = window.calcCordsToCenter(SME.sizes.card.height, SME.sizes.card.width);
342 SME.history.getDropDown(center.left + 30, center.top + 13);
343 });
344 },
345
346 /*
347 * Hides the current card but does not remove it from the DOM.
348 */
349 hide: function()
350 {
351 // There is no current card so unset it
352 // FLAWED LOGIC: We can have multiple cards.
353 SME.currentCard = null;
354
355 // Fade out and subsequently destroy the card
356 new Effect.Fade(this.card,
357 {
358 afterFinish: function()
359 {
360 this.options.onFadeOutFinish();
361 this.destroy();
362 }.bind(this)
363 });
364
365 // FLAWED LOGIC: Multiple cards, see above.
366 SME.history.clearHash();
367 this.overlay.hide();
368 this.options.onClose();
369 },
370
371 /*
372 * Sets the layout of the card using a layout engine.
373 */
374 setLayout: function(layoutE, data)
375 {
376 this.layoutEngine = new layoutE(this.cframe, data, this).layout();
377 }
378});