From: Łukasz Rekucki Date: Wed, 30 Sep 2009 14:17:10 +0000 (+0200) Subject: Galeria skanów z przewijaniem, bez zoom'a. X-Git-Url: https://git.mdrn.pl/redakcja.git/commitdiff_plain/861a08cdc38728e9f988a0a321e62693e26e947f?ds=sidebyside;hp=-c Galeria skanów z przewijaniem, bez zoom'a. --- 861a08cdc38728e9f988a0a321e62693e26e947f diff --git a/apps/api/handlers/library_handlers.py b/apps/api/handlers/library_handlers.py index b2ff94b4..b9e6314b 100644 --- a/apps/api/handlers/library_handlers.py +++ b/apps/api/handlers/library_handlers.py @@ -80,10 +80,7 @@ class LibraryHandler(BaseHandler): # not top-level anymore document_tree.pop(part) parent['parts'].append(child) - - # sort the right way - for doc in documents.itervalues(): doc['parts'].sort(key=natural_order(lambda d: d['name'])) diff --git a/apps/api/utils.py b/apps/api/utils.py index 9b45a320..c072d356 100644 --- a/apps/api/utils.py +++ b/apps/api/utils.py @@ -58,10 +58,12 @@ def hglibrary(func): import re +import locale + NAT_EXPR = re.compile(r'(\d+)', re.LOCALE | re.UNICODE) def natural_order(get_key=lambda x: x): def getter(key): - key = [int(x) if n%2 else x for (n,x) in enumerate(NAT_EXPR.split(get_key(key))) ] + key = [int(x) if n%2 else locale.strxfrm(x.encode('utf-8')) for (n,x) in enumerate(NAT_EXPR.split(get_key(key))) ] return key return getter diff --git a/apps/explorer/models.py b/apps/explorer/models.py index a8a8c3b2..7ab6b095 100644 --- a/apps/explorer/models.py +++ b/apps/explorer/models.py @@ -102,4 +102,4 @@ class GalleryForDocument(models.Model): document = models.CharField(max_length=255) def __unicode__(self): - return u"%s:%s" % self.subpath, self.document \ No newline at end of file + return u"%s:%s" % (self.subpath, self.document) \ No newline at end of file diff --git a/project/settings.py b/project/settings.py index 05518193..7d2ed64e 100644 --- a/project/settings.py +++ b/project/settings.py @@ -30,6 +30,9 @@ TIME_ZONE = 'Europe/Warsaw Poland' # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = 'pl' +import locale +locale.setlocale(locale.LC_ALL, '') + SITE_ID = 1 # If you set this to False, Django will make some optimizations so as not diff --git a/project/static/css/master.css b/project/static/css/master.css index a3857e6e..32ed073f 100644 --- a/project/static/css/master.css +++ b/project/static/css/master.css @@ -224,16 +224,62 @@ label { background-color: #DDD; } - - - /* ================= */ /* = Gallery panel = */ /* ================= */ -.images-wrap { - overflow-x: hidden; - overflow-y: scroll; +.image-gallery-view-template { + position: absolute; + top: 0px; left: 0px; right: 0px; bottom: 0px; + overflow: hidden; +} + +.image-gallery-header { + position: absolute; + bottom: 0px; + left: 0px; + right: 0px; + height: 30px; + + background: blue; + border: 1px solid green; +} + +.image-gallery-header p { + margin: 0px; + padding: 3px 1em; + height: 30px; + line-height: 24px; + text-align: center; +} + +.image-gallery-page-list { + position: absolute; + top: 0px; + left: 0px; + right: 0px; + bottom: 30px; + border: 1px solid red; + background: black; + z-index: 0; + + overflow: hidden; } +.image-gallery-page-container { + display: none; + border: none; + + position: absolute; + top: 0px; left: 0px; + + text-align: center; + padding: 0px; +} + +.image-gallery-page-container img { + /* border: 2px solid green; */ + margin: 0px; +} + /* =========================== */ /* = DublinCore Editor panel = */ diff --git a/project/static/js/views/gallery.js b/project/static/js/views/gallery.js index 390aaadb..95736565 100644 --- a/project/static/js/views/gallery.js +++ b/project/static/js/views/gallery.js @@ -7,7 +7,7 @@ var ImageGalleryView = View.extend({ init: function(element, model, parent, template) { - this.currentPage = 0; + this.currentPage = -1; this._super(element, model, template); this.parent = parent; @@ -22,23 +22,60 @@ var ImageGalleryView = View.extend({ }, modelDataChanged: function(property, value) - { - $.log('updating pages', property, value); + { if( property == 'data') - { - this.gotoPage(this.currentPage); - this.element.html(render_template(this.template, this)); + { + this.render(); + this.gotoPage(this.currentPage); } }, - gotoPage: function(index) { + gotoPage: function(index) + { if (index < 0) index = 0; - - var n = this.model.get('pages').length; + + var n = this.$pages.length; if (index >= n) index = n-1; + if( (this.currentPage == index) ) + return; + + var cpage = this.$currentPage(); + + if(cpage) { + var offset = this.pageViewOffset(cpage); + this.cleanPage(cpage); + } + this.currentPage = index; + + cpage = this.$currentPage() + this.renderImage(cpage, cpage.attr('ui:model')); + + if(offset) { + cpage.css({top: offset.y, left: offset.x}); + } + + var self = this; + $('img', cpage).bind('load', function() { + if(offset) + self.setPageViewOffset(cpage, offset); + }); + + cpage.show(); + + if(this.currentPage == n-1) + this.$nextButton.attr('disabled', 'disabled'); + else + this.$nextButton.removeAttr('disabled'); + + if(this.currentPage == 0) + this.$prevButton.attr('disabled', 'disabled'); + else + this.$prevButton.removeAttr('disabled'); + + this.$pageInput.val( (this.currentPage+1) ); }, modelStateChanged: function(property, value) { @@ -52,6 +89,150 @@ var ImageGalleryView = View.extend({ this.parent.freeze('Zapisywanie...'); } }, + + $currentPage: function() { + if(this.currentPage >= 0 && this.currentPage < this.$pages.length) + return $(this.$pages[this.currentPage]); + else + return undefined; + }, + + cleanPage: function($page) { + $page.hide(); + $('img', $page).unbind(); + + $page.empty(); + + this.setPageViewOffset($page, {x:0, y:0}); + }, + + pageDragStart: function(event) + { + this.dragStart = {x: event.clientX, y: event.clientY}; + $(window).bind('mousemove.imagedrag', this.pageDrag.bind(this)); + $(window).bind('mouseup.imagedrag', this.pageDragStop.bind(this)); + + this.$currentPage().css('cursor', 'move'); + + return false; + }, + + pageDrag: function(event) + { + if(!this.dragStart) return; + + var delta = { + x: this.dragStart.x - event.clientX, + y: this.dragStart.y - event.clientY }; + + var offset = this.pageViewOffset( $(this.$pages[this.currentPage]) ); + offset.x -= delta.x; + offset.y -= delta.y; + this.setPageViewOffset( $(this.$pages[this.currentPage]), offset); + + this.dragStart = {x: event.clientX, y: event.clientY }; + return false; + }, + + pageDragStop: function(event) { + this.$currentPage().css('cursor', 'auto'); + + this.dragStart = undefined; + $(window).unbind('mousemove.imagedrag'); + $(window).unbind('mouseup.imagedrag'); + + return false; + }, + + pageViewOffset: function($page) { + var left = parseInt($page.css('left')); + var top = parseInt($page.css('top')); + + return {x: left, y: top}; + }, + + setPageViewOffset: function($page, offset) { + // check if the image will be actually visible + // and correct + var MARGIN = 30; + + var vp_width = this.$pageListRoot.width(); + var vp_height = this.$pageListRoot.height(); + + var width = $page.outerWidth(); + var height = $page.outerHeight(); + + if( offset.x+width-MARGIN < 0 ) { + // console.log('too much on the left', offset.x, -width) + offset.x = -width+MARGIN; + } + + // too much on the right + if( offset.x > vp_width-MARGIN) { + offset.x = vp_width-MARGIN; + // console.log('too much on the right', offset.x, vp_width, width) + } + + + if( offset.y+height-MARGIN < 0) + offset.y = -height+MARGIN; + + if( offset.y > vp_height-MARGIN) + offset.y = vp_height-MARGIN; + + $page.css({left: offset.x, top: offset.y}); + }, + + renderImage: function(target, source) { + target.html(''); + $('img', target). + css({ + 'user-select': 'none', + '-webkit-user-select': 'none', + '-khtml-user-select': 'none', + '-moz-user-select': 'none', + }). + attr('unselectable', 'on'). + mousedown(this.pageDragStart.bind(this)); + }, + + render: function() { + /* first unbind all */ + + // this.pageListElement + if(this.$nextButton) this.$nextButton.unbind(); + if(this.$prevButton) this.$prevButton.unbind(); + if(this.$jumpButton) this.$jumpButton.unbind(); + + /* render */ + this.element.html(render_template(this.template, this)); + + /* fetch important parts */ + this.$pageListRoot = $('.image-gallery-page-list', this.element); + this.$pages = $('.image-gallery-page-container', this.$pageListRoot); + + this.$nextButton = $('.image-gallery-next-button', this.element); + this.$prevButton = $('.image-gallery-prev-button', this.element); + this.$pageInput = $('.image-gallery-current-page', this.element); + + /* re-bind events */ + this.$nextButton.click( this.nextPage.bind(this) ); + this.$prevButton.click( this.prevPage.bind(this) ); + + this.$pageInput.change( this.jumpToPage.bind(this) ); + }, + + jumpToPage: function() { + this.gotoPage(parseInt(this.$pageInput.val())-1); + }, + + nextPage: function() { + this.gotoPage(this.currentPage + 1); + }, + + prevPage: function() { + this.gotoPage(this.currentPage - 1); + }, dispose: function() { this.model.removeObserver(this); diff --git a/project/templates/explorer/editor.html b/project/templates/explorer/editor.html index c38dfc4f..b51af173 100644 --- a/project/templates/explorer/editor.html +++ b/project/templates/explorer/editor.html @@ -55,14 +55,27 @@ -
+