Ustawianie galerii inline.
[redakcja.git] / platforma / static / js / views / gallery.js
1 /*global View render_template panels */
2 var ImageGalleryView = View.extend({
3   _className: 'ImageGalleryView',
4   element: null,
5   model: null,
6   currentPage: -1,
7   pageZoom: 1.0,
8   template: 'image-gallery-view-template',
9   
10   init: function(element, model, parent, template) 
11   {    
12     console.log("init for gallery");
13     this._super(element, model, template);
14     this.parent = parent;
15
16     console.log("gallery model", this.model);
17        
18     this.model
19       .addObserver(this, 'data', this.modelDataChanged.bind(this))
20       .addObserver(this, 'state', this.modelStateChanged.bind(this));
21    
22     //$('.image-gallery-view', this.element).html(this.model.get('data'));
23     this.modelStateChanged('state', this.model.get('state'));
24     this.model.load();    
25   },
26   
27   modelDataChanged: function(property, value) 
28   {   
29     console.log(this.model.get('state'), value, value.length);
30     if ((this.model.get('state') == 'synced') && (value.length == 0)) {
31       console.log('tutaj');
32       this.render('image-gallery-empty-template');
33     } else {
34       this.render();
35       this.gotoPage(this.currentPage);
36     }
37   },
38
39   gotoPage: function(index) 
40   {
41      if (index < 0) 
42          index = 0;
43     
44      var n = this.$pages.length;
45      if (index >= n) index = n-1;
46
47      if( (this.currentPage == index) )
48          return;
49
50      var cpage = this.$currentPage();
51
52      if(cpage) {
53          var offset = this.pageViewOffset(cpage);
54          this.cleanPage(cpage);
55      }
56      
57      this.currentPage = index;
58
59      cpage = this.$currentPage()
60      this.renderImage(cpage);
61
62      if(offset) {
63          cpage.css({top: offset.y, left: offset.x});
64      }
65
66      var self = this;
67      $('img', cpage).bind('load', function() {
68         if(offset)
69              self.setPageViewOffset(cpage, offset);
70      });
71      
72      cpage.show();
73
74      if(this.currentPage == n-1)
75           this.$nextButton.attr('disabled', 'disabled');
76      else
77           this.$nextButton.removeAttr('disabled');
78
79       if(this.currentPage == 0)
80           this.$prevButton.attr('disabled', 'disabled');
81       else
82           this.$prevButton.removeAttr('disabled');
83
84       this.$pageInput.val( (this.currentPage+1) );
85   },
86   
87   reload: function() {},
88   
89   modelStateChanged: function(property, value) {   
90     if (value == 'loading') {
91       this.freeze('Ɓadowanie...');
92     } else {
93       if ((value == 'synced') && (this.model.get('data').length == 0)) {
94         this.render('image-gallery-empty-template');
95       }
96       this.unfreeze();
97     }
98   },
99
100   $currentPage: function() {
101       if(this.currentPage >= 0 && this.currentPage < this.$pages.length)
102           return $(this.$pages[this.currentPage]);
103       else
104           return undefined;
105   },    
106
107   cleanPage: function($page) {
108     $page.hide();
109     $('img', $page).unbind();
110     
111     $page.empty();    
112     this.setPageViewOffset($page, {x:0, y:0});
113   },
114
115   pageDragStart: function(event)
116   {      
117       this.dragStart = {x: event.clientX, y: event.clientY};
118       $(window).bind('mousemove.imagedrag', this.pageDrag.bind(this));
119       $(window).bind('mouseup.imagedrag', this.pageDragStop.bind(this));
120       
121       this.$currentPage().css('cursor', 'move');
122
123       return false;
124   },
125
126   pageDrag: function(event)
127   {
128       if(!this.dragStart) return;
129
130       var delta = {
131            x: this.dragStart.x - event.clientX,
132            y: this.dragStart.y - event.clientY };     
133
134       var offset = this.pageViewOffset( $(this.$pages[this.currentPage]) );
135       offset.x -= delta.x;
136       offset.y -= delta.y;
137       this.setPageViewOffset( $(this.$pages[this.currentPage]), offset);
138       
139       this.dragStart = {x: event.clientX, y: event.clientY };     
140       return false;
141   },
142
143   pageDragStop: function(event) {
144       this.$currentPage().css('cursor', 'auto');
145
146       this.dragStart = undefined;
147       $(window).unbind('mousemove.imagedrag');
148       $(window).unbind('mouseup.imagedrag');
149
150       return false;
151   },
152
153   pageViewOffset: function($page) {
154       var left = parseInt($page.css('left'));
155       var top = parseInt($page.css('top'));
156
157       return {x: left, y: top};
158   },
159
160   setPageViewOffset: function($page, offset) {
161       // check if the image will be actually visible
162       // and correct
163       var MARGIN = 30;
164
165
166       var vp_width = this.$pageListRoot.width();
167       var vp_height = this.$pageListRoot.height();
168       
169       var width = $page.outerWidth();
170       var height = $page.outerHeight();
171
172       // console.log(offset, vp_width, vp_height, width, height);
173       if( offset.x+width-MARGIN < 0 ) {
174         // console.log('too much on the left', offset.x, -width)
175         offset.x = -width+MARGIN;
176       }
177       
178       // too much on the right
179       if( offset.x > vp_width-MARGIN) {
180           offset.x = vp_width-MARGIN;
181           // console.log('too much on the right', offset.x, vp_width, width)
182       }
183       
184       if( offset.y+height-MARGIN < 0)
185         offset.y = -height+MARGIN;      
186
187       if( offset.y > vp_height-MARGIN)
188           offset.y = vp_height-MARGIN;               
189       
190       $page.css({left: offset.x, top: offset.y});           
191   },
192
193   reload: function() {
194     this.model.load(true);
195   },
196   
197   renderImage: function(target) 
198   {
199       var source = target.attr('ui:model');
200       var orig_width = parseInt(target.attr('ui:width'));
201       var orig_height = parseInt(target.attr('ui:height'));
202
203       target.html('<img src="' + source
204            + '" width="' + Math.floor(orig_width * this.pageZoom)
205            + '" height="' + Math.floor(orig_height * this.pageZoom)
206            + '" />');
207        
208       $('img', target).
209         css({
210             'user-select': 'none',
211             '-webkit-user-select': 'none',
212             '-khtml-user-select': 'none',
213             '-moz-user-select': 'none'
214         }).
215         attr('unselectable', 'on').
216         mousedown(this.pageDragStart.bind(this));    
217   },
218
219   render: function(template) 
220   {
221     if(!this.model) return;            
222     
223     $('.choose-gallery-button', this.element).unbind();
224     
225     /* first unbind all */    
226     if(this.$nextButton) this.$nextButton.unbind();
227     if(this.$prevButton) this.$prevButton.unbind();
228     if(this.$jumpButton) this.$jumpButton.unbind();
229     if(this.$pageInput) this.$pageInput.unbind();
230
231     if(this.$zoomInButton) this.$zoomInButton.unbind();
232     if(this.$zoomOutButton) this.$zoomOutButton.unbind();
233     if(this.$zoomResetButton) this.$zoomResetButton.unbind();
234     
235     if (!template) {
236       /* render */
237       this._super();
238       
239       /* fetch important parts */
240       this.$pageListRoot = $('.image-gallery-page-list', this.element);
241       this.$pages = $('.image-gallery-page-container', this.$pageListRoot);
242
243       this.$nextButton = $('.image-gallery-next-button', this.element);
244       this.$prevButton = $('.image-gallery-prev-button', this.element);
245       this.$pageInput = $('.image-gallery-current-page', this.element);
246
247       // this.$zoomSelect = $('.image-gallery-current-zoom', this.element);
248       this.$zoomInButton = $('.image-gallery-zoom-in', this.element);
249       this.$zoomOutButton = $('.image-gallery-zoom-out', this.element);
250       this.$zoomResetButton = $('.image-gallery-zoom-reset', this.element);
251
252       /* re-bind events */
253       this.$nextButton.click( this.nextPage.bind(this) );
254       this.$prevButton.click( this.prevPage.bind(this) );
255       this.$pageInput.change( this.jumpToPage.bind(this) );
256
257       // this.$zoomSelect.change( this.zoomChanged.bind(this) );
258       this.$zoomInButton.click( this.zoomInOneStep.bind(this) );
259       this.$zoomOutButton.click( this.zoomOutOneStep.bind(this) );
260       this.$zoomResetButton.click( this.zoomReset.bind(this) );
261
262       this.gotoPage(this.currentPage);
263       this.changePageZoom(this.pageZoom);
264     } else {
265       this._super(template);
266       
267       var self = this;
268       $('.choose-gallery-button', self.element).click(function() {
269         console.log('CLICK CLICK')
270         self.model.setGallery($('#id_subpath', self.element).val());
271       });
272     }
273   },
274
275   jumpToPage: function() {     
276         this.gotoPage(parseInt(this.$pageInput.val())-1);
277   },
278   
279   nextPage: function() {
280       this.gotoPage(this.currentPage + 1);    
281   },
282
283   prevPage: function() {
284       this.gotoPage(this.currentPage - 1);
285   },
286
287   zoomReset: function() {
288       this.changePageZoom(1.0);
289   },
290
291   zoomInOneStep: function() {
292       var zoom = this.pageZoom + 0.1;
293       if(zoom > 3.0) zoom = 3.0;
294       this.changePageZoom(zoom);
295   },
296
297   zoomOutOneStep: function() {
298       var zoom = this.pageZoom - 0.1;
299       if(zoom < 0.3) zoom = 0.3;
300       this.changePageZoom(zoom);
301   },
302
303   changePageZoom: function(value) {
304       var current = this.$currentPage();
305
306       if(!current) return;
307
308       var alpha = value/this.pageZoom;
309       this.pageZoom = value;
310
311       var nwidth = current.attr('ui:width') * this.pageZoom;
312       var nheight = current.attr('ui:height') * this.pageZoom;
313       var off_top = parseInt(current.css('top'));
314       var off_left = parseInt(current.css('left'));
315       
316       var vpx = this.$pageListRoot.width() * 0.5;
317       var vpy = this.$pageListRoot.height() * 0.5;
318       
319       var new_off_left = vpx - alpha*(vpx-off_left);
320       var new_off_top = vpy - alpha*(vpy-off_top);
321                  
322       $('img', current).attr('width', nwidth);
323       $('img', current).attr('height', nheight);
324       
325       this.setPageViewOffset(current, {
326           y: new_off_top, x: new_off_left
327       });
328
329       // this.$zoomSelect.val(this.pageZoom);
330       // console.log('Zoom is now', this.pageZoom);
331   },
332   
333   dispose: function()
334   {
335       console.log("Disposing gallery.");
336       this.model.removeObserver(this);
337       this._super();
338   }
339 });
340
341 // Register view
342 panels['gallery'] = ImageGalleryView;