diff options
author | Mike Crute <mcrute@gmail.com> | 2010-01-17 12:06:15 -0500 |
---|---|---|
committer | Mike Crute <mcrute@gmail.com> | 2010-01-17 12:06:15 -0500 |
commit | 55974d21a824378b287e563bce4c32597060cfca (patch) | |
tree | ff8426efe10ff98189fee26583f061fb08f19a50 /docroot/classes/card.class.js | |
download | designer_site-master.tar.bz2 designer_site-master.tar.xz designer_site-master.zip |
Diffstat (limited to 'docroot/classes/card.class.js')
-rwxr-xr-x | docroot/classes/card.class.js | 378 |
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 | |||
9 | var Card = Class.create(); | ||
10 | Object.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 | }); | ||