Statistics
| Branch: | Tag: | Revision:

root / ui / static / snf / js / views.js @ 96d725ac

History | View | Annotate | Download (9.4 kB)

1
;(function(root){
2
    
3
    // root
4
    var root = root;
5
    
6
    // setup namepsaces
7
    var snf = root.synnefo = root.synnefo || {};
8
    var models = snf.models = snf.models || {}
9
    var storage = snf.storage = snf.storage || {};
10
    var views = snf.views = snf.views || {}
11
    var util = snf.util = snf.util || {}
12

    
13
    // shortcuts
14
    var bb = root.Backbone;
15
    
16
    // logging
17
    var logger = new snf.logging.logger("SNF-VIEWS");
18
    var debug = _.bind(logger.debug, logger);
19
    
20
    // Base view object
21
    views.View = bb.View.extend({
22
        // the main element of the view
23
        // view delegates show, visible, hide etc to this element
24
        view_id: false,
25

    
26
        el: '#app',
27
        data_from: false,
28
        selectors: {},
29
        
30
        initialize: function() {
31
            this.log = new snf.logging.logger("SNF-VIEWS:" + this.view_id);
32
        },
33
    
34
        // is the view visible ?
35
        visible: function(){
36
            return $(this.el).is(":visible");
37
        },
38
        
39
        // hide view
40
        hide: function() {
41
            if (!this.visible()) { return this };
42
            return $(this.el).hide();
43
        },
44
        
45
        // show view
46
        show: function() {
47
            if (this.visible()) { return this };
48
            $(this.el).show();
49
            if (this.show_view) { this.show_view.apply(this, arguments)};
50
        },
51

    
52
        sel: function(id) {
53
            return this.$(this.selectors[id]);
54
        },
55

    
56
        // animations
57
        fadeIn: function(time, callback) {
58
            $(this.el).fadeIn(time, callback);
59
            return this.show();
60
        },
61

    
62
        fadeOut: function(time, callback) {
63
            $(this.el).fadeOut(time, callback);
64
            return this.hide();
65
        }
66
    });
67
    
68
    
69
    // overlays registry
70
    views._overlay_index = [];
71

    
72
    // overlay view helper
73
    views.Overlay = views.View.extend({
74
        view_id: 'overlay',
75
        tpl_selector: '#generic-overlay-tpl',
76
        css_class: 'overlay',
77
        oneInstance: true,
78
        fixed: false,
79

    
80
        
81
        initialize: function(options, selector) {
82
            this.defaults = {
83
                load: false,
84
                closeOnClick: false,
85
                mask: {
86
                    color: "#444",
87
                    loadSpeed: 200,
88
                    opacity: 0.7
89
                }
90
            }
91
            
92
            this.tpl_selector = selector || this.tpl_selector;
93
            views.Overlay.__super__.initialize.apply(this);
94
            views._overlay_index.push(this);
95

    
96
            this.options = _.extend(this.defaults, options);
97
            this.options.clone = this.options.clone == undefined ? true : this.options.clonde;
98
            this.options.fixed = this.fixed;
99

    
100
            this.options.onOpen = this.options.onOpen || function() {};
101
            this.options.onClose = this.options.onClose || function() {};
102
            this.options.beforeOpen = this.options.beforeOpen || function() {};
103
            this.options.beforeClose = this.options.beforeClose || function() {};
104
            this.el = this.create_element();
105
            this.el.hide();
106
        
107
            var ajax_params = _.clone(this.options);
108

    
109
            ajax_params.onBeforeLoad = _.bind(this._beforeOpen, this);
110
            ajax_params.onLoad = _.bind(this._onOpen, this);
111
            ajax_params.onBeforeClose = _.bind(this._beforeClose, this);
112
            ajax_params.onClose = _.bind(this._onClose, this);
113
            ajax_params.oneInstance = this.oneInstance;
114
            // create overlay
115
            // TODO: does this return overlay object ?? (to avoid the next code line)
116
            $(this.el).overlay(ajax_params);
117

    
118
            this.overlay = $(this.el).overlay();
119
            this.append_css = this.options ? this.options.css_class ? this.options.css_class : "" : "";
120
            return this;
121
        },
122

    
123
        create_element: function() {
124
            var el = undefined;
125
            if (this.options.clone) {
126
                el = $(this.tpl_selector).clone();
127
            } else {
128
                el = $(this.tpl_selector);
129
            }
130
            
131
            // append content
132
            if (this.content_selector) {
133
                var content = $(this.content_selector).clone();
134
                content.addClass("content");
135
                
136
                if ($(el).find(".content").length) {
137
                    $(el).find(".content").replaceWith(content);
138
                }
139
                content.removeClass("hidden");
140
            }
141

    
142
            if (this.overlay_id) {
143
            }
144

    
145
            $(el).addClass("overlay");
146
            if (this.css_class) {
147
                $(el).addClass(this.css_class);
148
            }
149
            
150
            if (this.options.clone) {
151
                $("body").append(el);
152
            }
153

    
154
            return el;
155
        },
156

    
157
        set_title: function(title) {
158
            if (title || this.title) {
159
                $(this.el).find(".header .title").html(title || this.title)
160
            }
161
        },
162

    
163
        set_subtitle: function(subtitle) {
164
            if (subtitle || this.subtitle) {
165
                $(this.el).find(".header .subtitle").html(subtitle || this.subtitle)
166
            }
167
        },
168

    
169
        _beforeOpen: function() {
170
            if (this.append_css) {
171
                $(this.el).addClass(this.append_css);
172
            }
173

    
174
            this.set_title();
175
            this.set_subtitle();
176
            
177
            this.beforeOpen.apply(this, arguments);
178
            this.options.beforeOpen.apply(this, arguments);
179
        },
180

    
181
        _onOpen: function() {
182
            if ($(this.el).find(".closeme").length) {
183
                $(this.el).find(".closeme").click(_.bind(function(){
184
                    this.hide();
185
                }, this))
186
            }
187
            this.onOpen.apply(this, arguments);
188
            this.options.onOpen.apply(this, arguments);
189
        },
190

    
191
        _beforeClose: function() {
192
            this.beforeClose.apply(this, arguments);
193
            this.options.beforeClose.apply(this, arguments);
194
        },
195

    
196
        _onClose: function() {
197
            if (this.append_css) {
198
                $(this.el).removeClass(this.append_css);
199
            }
200
            this.onClose.apply(this, arguments);
201
            this.options.onClose.apply(this, arguments);
202
        },
203

    
204
        beforeOpen: function () {},
205
        onOpen: function () {},
206
        beforeClose: function () {},
207
        onClose: function () {},
208

    
209
        show: function() {
210
            // close opened overlays
211
            var hidden = false;
212
            _.each(views._overlay_index, function(ovr){
213
                if (ovr == this) { return };
214
                if (ovr.visible()) {
215
                    hidden = true;
216
                    ovr.hide();
217
                }
218
            })
219

    
220
            // do we need to wait for other overlays to close ???
221
            if (hidden) { delay = 300; } else { delay = 0; }
222
            window.setTimeout(_.bind(function(){ this.overlay.load() }, this), delay)
223
            return this;
224
        },
225

    
226
        hide: function() {
227
            if (!this.overlay.isOpened()) {
228
                // if its not opened events wont trigger
229
                this._onClose()
230
            } else {
231
                this.overlay.close();
232
            }
233
            return this;
234
        }
235
    });
236

    
237
    
238
    // overlay view helper
239
    views.VMOverlay = views.Overlay.extend({
240

    
241
        initialize: function() {
242
            views.VMOverlay.__super__.initialize.apply(this);
243
            this.vm = undefined;
244
            this.view_id_tpl = this.view_id;
245

    
246
            _.bindAll(this, "_handle_vm_change", "_handle_vm_remove");
247
        },
248

    
249
        set_vm: function(vm) {
250
            if (this.vm) { this.unbind_vm_handlers };
251
            this.vm = vm;
252
            this.view_id = this.view_id + "_" + vm.id;
253
            this.bind_vm_handlers();
254
        },
255

    
256
        bind_vm_handlers: function() {
257
            this.log.debug("binding handlers");
258
            this.vm.bind("change", this._handle_vm_change);
259
            storage.vms.bind("remove", this._handle_vm_remove);
260
        },
261
        
262
        unbind_vm_handlers: function() {
263
            this.log.debug("unbinding handlers", this.vm);
264
            if (!this.vm) { return };
265
            this.vm.unbind("change", this._handle_vm_change);
266
            storage.vms.unbind("remove", this._handle_vm_remove);
267
        },
268
        
269
        _update_vm_details: function() { 
270
            if (!this.vm) { console.error("invalid view state"); return }
271
            this.set_subtitle(this.vm.get("name") + snf.ui.helpers.vm_icon_tag(this.vm, "small"));
272

    
273
            var ico_path = snf.ui.helpers.os_icon_path(this.vm.get("OS"), "oslarge");
274
            this.$(".content").css({"background-image":"url(" + ico_path +")"})
275
            this.update_vm_details() 
276
        },
277

    
278
        update_vm_details: function() {},
279
        handle_vm_remove: function() {},
280
        handle_vm_change: function () {},
281
        
282
        _handle_vm_remove: function(vm, collection) {
283
            if (this.vm && vm.id == this.vm.id) {
284
                this.hide();
285
            }
286
            this.handle_vm_remove();
287
        },
288
        
289
        _handle_vm_change: function(vm) {
290
            this._update_vm_details();
291
            this.handle_vm_change(vm);
292
        },
293
        
294
        beforeClose: function() {
295
            this.unbind_vm_handlers();
296
            this.vm = undefined;
297
        },
298

    
299
        show: function(vm) {
300
            this.set_vm(vm);
301
            views.VMOverlay.__super__.show.apply(this, arguments);
302
            this._update_vm_details();
303
        }
304

    
305
    });
306

    
307
})(this);