[gnome-documents/wip/gepub] preview: split out a common class for navigation controls
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-documents/wip/gepub] preview: split out a common class for navigation controls
- Date: Sun, 12 Jun 2016 23:06:07 +0000 (UTC)
commit 6d477f316f5f048d4a1500928cd3d529bc36396c
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Sun Jun 12 11:59:11 2016 -0700
preview: split out a common class for navigation controls
Let's share this code between all the preview backends.
src/epubview.js | 192 +++---------------------
src/evinceview.js | 230 +++++------------------------
src/lokview.js | 217 +++++-----------------------
src/org.gnome.Books.src.gresource.xml | 1 +
src/org.gnome.Documents.src.gresource.xml | 1 +
src/preview.js | 206 ++++++++++++++++++++++++++
6 files changed, 302 insertions(+), 545 deletions(-)
---
diff --git a/src/epubview.js b/src/epubview.js
index 94f6be3..f91a2cb 100644
--- a/src/epubview.js
+++ b/src/epubview.js
@@ -20,7 +20,6 @@
*/
const GLib = imports.gi.GLib;
-const Gdk = imports.gi.Gdk;
const Gepub = imports.gi.Gepub;
const Gio = imports.gi.Gio;
const Gtk = imports.gi.Gtk;
@@ -32,13 +31,12 @@ const Application = imports.application;
const Documents = imports.documents;
const ErrorBox = imports.errorBox;
const MainToolbar = imports.mainToolbar;
+const Preview = imports.preview;
const Searchbar = imports.searchbar;
const WindowMode = imports.windowMode;
const Lang = imports.lang;
-const Mainloop = imports.mainloop;
const Signals = imports.signals;
-const Tweener = imports.tweener.tweener;
function isEpub(mimeType) {
return (mimeType == 'application/epub+zip');
@@ -53,7 +51,7 @@ const EPUBView = new Lang.Class({
transition_type: Gtk.StackTransitionType.CROSSFADE });
this._overlay = overlay;
- this.page = 1;
+ this._page = 1;
this._errorBox = new ErrorBox.ErrorBox();
this.add_named(this._errorBox, 'error');
@@ -126,7 +124,7 @@ const EPUBView = new Lang.Class({
return;
this.set_visible_child_full('view', Gtk.StackTransitionType.NONE);
- this.page = 1;
+ this._page = 1;
this._navControls.show();
},
@@ -138,7 +136,7 @@ const EPUBView = new Lang.Class({
this.add_named(this.view, 'view');
this.view.show();
- this._navControls = new EPUBViewNavControls(this, this._overlay);
+ this._navControls = new Preview.PreviewNavControls(this, this._overlay);
this.set_visible_child_full('view', Gtk.StackTransitionType.NONE);
},
@@ -153,18 +151,30 @@ const EPUBView = new Lang.Class({
this.view.load_bytes(new GLib.Bytes(current), mime, 'UTF-8', null);
},
- goNext: function() {
- if (this._epubdoc.go_next()) {
- this.page++;
+ goPrev: function() {
+ if (this._epubdoc.go_prev()) {
+ this._page--;
this._loadCurrent();
}
},
- goPrev: function() {
- if (this._epubdoc.go_prev()) {
- this.page--;
+ goNext: function() {
+ if (this._epubdoc.go_next()) {
+ this._page++;
this._loadCurrent();
}
+ },
+
+ get hasPages() {
+ return true;
+ },
+
+ get page() {
+ return this._page;
+ },
+
+ get numPages() {
+ return this._epubSpine ? this._epubSpine.length : 0;
}
});
@@ -287,161 +297,3 @@ const EPUBViewToolbar = new Lang.Class({
this.toolbar.set_title(primary);
},
});
-
-const _PREVIEW_NAVBAR_MARGIN = 30;
-const _AUTO_HIDE_TIMEOUT = 2;
-
-const EPUBViewNavControls = new Lang.Class({
- Name: 'EPUBViewNavControls',
-
- _init: function(epubView, overlay) {
- this._epubView = epubView;
- this._overlay = overlay;
-
- this._visible = false;
- this._visibleInternal = false;
- this._pageChangedId = 0;
- this._autoHideId = 0;
- this._motionId = 0;
-
- this.prev_widget = new Gtk.Button({ image: new Gtk.Image ({ icon_name: 'go-previous-symbolic',
- pixel_size: 16 }),
- margin: _PREVIEW_NAVBAR_MARGIN,
- halign: Gtk.Align.START,
- valign: Gtk.Align.CENTER });
- this.prev_widget.get_style_context().add_class('osd');
- this._overlay.add_overlay(this.prev_widget);
- this.prev_widget.connect('clicked', Lang.bind(this, this._onPrevClicked));
- this.prev_widget.connect('enter-notify-event', Lang.bind(this, this._onEnterNotify));
- this.prev_widget.connect('leave-notify-event', Lang.bind(this, this._onLeaveNotify));
-
- this.next_widget = new Gtk.Button({ image: new Gtk.Image ({ icon_name: 'go-next-symbolic',
- pixel_size: 16 }),
- margin: _PREVIEW_NAVBAR_MARGIN,
- halign: Gtk.Align.END,
- valign: Gtk.Align.CENTER });
- this.next_widget.get_style_context().add_class('osd');
- this._overlay.add_overlay(this.next_widget);
- this.next_widget.connect('clicked', Lang.bind(this, this._onNextClicked));
- this.next_widget.connect('enter-notify-event', Lang.bind(this, this._onEnterNotify));
- this.next_widget.connect('leave-notify-event', Lang.bind(this, this._onLeaveNotify));
- this._overlay.connect('motion-notify-event', Lang.bind(this, this._onMotion));
- this._visible = true;
-
- },
-
- _onEnterNotify: function() {
- this._unqueueAutoHide();
- return false;
- },
-
- _onLeaveNotify: function() {
- this._queueAutoHide();
- return false;
- },
-
- _motionTimeout: function() {
- this._motionId = 0;
- this._visibleInternal = true;
- this._updateVisibility();
- this._queueAutoHide();
- return false;
- },
-
- _onMotion: function(widget, event) {
- if (this._motionId != 0)
- return false;
-
- let device = event.get_source_device();
- if (device.input_source == Gdk.InputSource.TOUCHSCREEN)
- return false;
-
- this._motionId = Mainloop.idle_add(Lang.bind(this, this._motionTimeout));
- return false;
- },
-
- _onPrevClicked: function() {
- this._epubView.goPrev();
- },
-
- _onNextClicked: function() {
- this._epubView.goNext();
- },
-
- _autoHide: function() {
- this._autoHideId = 0;
- this._visibleInternal = false;
- this._updateVisibility();
- return false;
- },
-
- _unqueueAutoHide: function() {
- if (this._autoHideId == 0)
- return;
-
- Mainloop.source_remove(this._autoHideId);
- this._autoHideId = 0;
- },
-
- _queueAutoHide: function() {
- this._unqueueAutoHide();
- this._autoHideId = Mainloop.timeout_add_seconds(_AUTO_HIDE_TIMEOUT, Lang.bind(this, this._autoHide));
- },
-
- _updateVisibility: function() {
- if (!this._epubView)
- return;
-
- if (!this._visible || !this._visibleInternal) {
- this._fadeOutButton(this.prev_widget);
- this._fadeOutButton(this.next_widget);
- return;
- }
-
- if (this._epubView.page == 1)
- this._fadeOutButton(this.prev_widget);
- else
- this._fadeInButton(this.prev_widget);
-
- var l = this._epubView._epubSpine.length;
- if (this._epubView.page >= l)
- this._fadeOutButton(this.next_widget);
- else
- this._fadeInButton(this.next_widget);
- },
-
- _fadeInButton: function(widget) {
- widget.show_all();
- Tweener.addTween(widget, { opacity: 1,
- time: 0.30,
- transition: 'easeOutQuad' });
- },
-
- _fadeOutButton: function(widget) {
- Tweener.addTween(widget, { opacity: 0,
- time: 0.30,
- transition: 'easeOutQuad',
- onComplete: function() {
- widget.hide();
- },
- onCompleteScope: this });
- },
-
- show: function() {
- this._visible = true;
- this._visibleInternal = true;
- this._updateVisibility();
- this._queueAutoHide();
- },
-
- hide: function() {
- this._visible = false;
- this._visibleInternal = false;
- this._updateVisibility();
- },
-
- destroy: function() {
- this.prev_widget.destroy();
- this.next_widget.destroy();
- }
-});
diff --git a/src/evinceview.js b/src/evinceview.js
index 07b4de8..6f3f4b2 100644
--- a/src/evinceview.js
+++ b/src/evinceview.js
@@ -22,7 +22,6 @@
const EvDocument = imports.gi.EvinceDocument;
const EvView = imports.gi.EvinceView;
const GdPrivate = imports.gi.GdPrivate;
-const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
@@ -30,12 +29,12 @@ const _ = imports.gettext.gettext;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
-const Tweener = imports.tweener.tweener;
const Application = imports.application;
const ErrorBox = imports.errorBox;
const MainToolbar = imports.mainToolbar;
const Places = imports.places;
+const Preview = imports.preview;
const Searchbar = imports.searchbar;
const Utils = imports.utils;
const WindowMode = imports.windowMode;
@@ -605,41 +604,50 @@ const EvinceView = new Lang.Class({
get lastSearch() {
return this._lastSearch;
+ },
+
+ goPrev: function() {
+ this.view.previous_page();
+ },
+
+ goNext: function() {
+ this.view.next_page();
+ },
+
+ get hasPages() {
+ return this._model ? (this._model.document.get_n_pages() > 0) : false;
+ },
+
+ get page() {
+ return this._model ? this._model.page : 0;
+ },
+
+ get numPages() {
+ return this._model ? this._model.document.get_n_pages() : 0;
}
});
Utils.addJSSignalMethods(EvinceView.prototype);
-const _PREVIEW_NAVBAR_MARGIN = 30;
-const _AUTO_HIDE_TIMEOUT = 2;
-
const EvinceViewNavControls = new Lang.Class({
Name: 'EvinceViewNavControls',
+ Extends: Preview.PreviewNavControls,
_init: function(previewView, overlay) {
+ this._pageChangedId = 0;
+
this._previewView = previewView;
this._model = previewView.getModel();
- this._overlay = overlay;
- this._visible = false;
- this._visibleInternal = false;
- this._pageChangedId = 0;
- this._autoHideId = 0;
- this._motionId = 0;
-
- this.bar_widget = new GdPrivate.NavBar({ document_model: this._model,
- margin: _PREVIEW_NAVBAR_MARGIN,
- valign: Gtk.Align.END,
- opacity: 0 });
- this.bar_widget.get_style_context().add_class('osd');
- this._overlay.add_overlay(this.bar_widget);
- this.bar_widget.connect('notify::hover', Lang.bind(this, function() {
- if (this.bar_widget.hover)
- this._onEnterNotify();
- else
- this._onLeaveNotify();
- }));
+ this.parent(previewView, overlay);
+ },
- let buttonArea = this.bar_widget.get_button_area();
+ createBarWidget: function() {
+ let barWidget = new GdPrivate.NavBar({ document_model: this._model,
+ margin: Preview.PREVIEW_NAVBAR_MARGIN,
+ valign: Gtk.Align.END,
+ opacity: 0 });
+
+ let buttonArea = barWidget.get_button_area();
let button = new Gtk.Button({ action_name: 'app.places',
image: new Gtk.Image({ icon_name: 'view-list-symbolic',
@@ -657,131 +665,7 @@ const EvinceViewNavControls = new Lang.Class({
});
buttonArea.pack_start(button, false, false, 0);
- this.prev_widget = new Gtk.Button({ image: new Gtk.Image ({ icon_name: 'go-previous-symbolic',
- pixel_size: 16 }),
- margin_start: _PREVIEW_NAVBAR_MARGIN,
- margin_end: _PREVIEW_NAVBAR_MARGIN,
- halign: Gtk.Align.START,
- valign: Gtk.Align.CENTER });
- this.prev_widget.get_style_context().add_class('osd');
- this._overlay.add_overlay(this.prev_widget);
- this.prev_widget.connect('clicked', Lang.bind(this, this._onPrevClicked));
- this.prev_widget.connect('enter-notify-event', Lang.bind(this, this._onEnterNotify));
- this.prev_widget.connect('leave-notify-event', Lang.bind(this, this._onLeaveNotify));
-
- this.next_widget = new Gtk.Button({ image: new Gtk.Image ({ icon_name: 'go-next-symbolic',
- pixel_size: 16 }),
- margin_start: _PREVIEW_NAVBAR_MARGIN,
- margin_end: _PREVIEW_NAVBAR_MARGIN,
- halign: Gtk.Align.END,
- valign: Gtk.Align.CENTER });
- this.next_widget.get_style_context().add_class('osd');
- this._overlay.add_overlay(this.next_widget);
- this.next_widget.connect('clicked', Lang.bind(this, this._onNextClicked));
- this.next_widget.connect('enter-notify-event', Lang.bind(this, this._onEnterNotify));
- this.next_widget.connect('leave-notify-event', Lang.bind(this, this._onLeaveNotify));
-
- this._overlay.connect('motion-notify-event', Lang.bind(this, this._onMotion));
-
- this._tapGesture = new Gtk.GestureMultiPress({ propagation_phase: Gtk.PropagationPhase.CAPTURE,
- touch_only: true,
- widget: this._previewView.view });
- this._tapGesture.connect('released', Lang.bind(this, this._onMultiPressReleased));
- this._tapGesture.connect('stopped', Lang.bind(this, this._onMultiPressStopped));
- },
-
- _onEnterNotify: function() {
- this._unqueueAutoHide();
- return false;
- },
-
- _onLeaveNotify: function() {
- this._queueAutoHide();
- return false;
- },
-
- _motionTimeout: function() {
- this._motionId = 0;
- this._visibleInternal = true;
- this._updateVisibility();
- if (!this.bar_widget.hover)
- this._queueAutoHide();
- return false;
- },
-
- _onMotion: function(widget, event) {
- if (this._motionId != 0) {
- return false;
- }
-
- let device = event.get_source_device();
- if (device.input_source == Gdk.InputSource.TOUCHSCREEN) {
- return false;
- }
-
- this._motionId = Mainloop.idle_add(Lang.bind(this, this._motionTimeout));
- return false;
- },
-
- _onMultiPressReleased: function() {
- this._tapGesture.set_state(Gtk.EventSequenceState.CLAIMED);
- this._visibleInternal = !this._visibleInternal;
- this._unqueueAutoHide();
- this._updateVisibility();
- },
-
- _onMultiPressStopped: function() {
- this._tapGesture.set_state(Gtk.EventSequenceState.DENIED);
- },
-
- _onPrevClicked: function() {
- this._previewView.view.previous_page();
- },
-
- _onNextClicked: function() {
- this._previewView.view.next_page();
- },
-
- _autoHide: function() {
- this._autoHideId = 0;
- this._visibleInternal = false;
- this._updateVisibility();
- return false;
- },
-
- _unqueueAutoHide: function() {
- if (this._autoHideId == 0)
- return;
-
- Mainloop.source_remove(this._autoHideId);
- this._autoHideId = 0;
- },
-
- _queueAutoHide: function() {
- this._unqueueAutoHide();
- this._autoHideId = Mainloop.timeout_add_seconds(_AUTO_HIDE_TIMEOUT, Lang.bind(this, this._autoHide));
- },
-
- _updateVisibility: function() {
- if (!this._model || !this._visible || !this._visibleInternal) {
- this._fadeOutButton(this.bar_widget);
- this._fadeOutButton(this.prev_widget);
- this._fadeOutButton(this.next_widget);
- return;
- }
-
- this._fadeInButton(this.bar_widget);
-
- if (this._model.page > 0)
- this._fadeInButton(this.prev_widget);
- else
- this._fadeOutButton(this.prev_widget);
-
- let doc = this._model.document;
- if (doc.get_n_pages() > this._model.page + 1)
- this._fadeInButton(this.next_widget);
- else
- this._fadeOutButton(this.next_widget);
+ return barWidget;
},
setModel: function(model) {
@@ -795,45 +679,6 @@ const EvinceViewNavControls = new Lang.Class({
if (this._model)
this._pageChangedId = this._model.connect('page-changed', Lang.bind(this,
this._updateVisibility));
- },
-
- _fadeInButton: function(widget) {
- if (!this._model)
- return;
- widget.show_all();
- Tweener.addTween(widget, { opacity: 1,
- time: 0.30,
- transition: 'easeOutQuad' });
- },
-
- _fadeOutButton: function(widget) {
- Tweener.addTween(widget, { opacity: 0,
- time: 0.30,
- transition: 'easeOutQuad',
- onComplete: function() {
- widget.hide();
- },
- onCompleteScope: this });
- },
-
- show: function() {
- this._visible = true;
- this._visibleInternal = true;
- this._updateVisibility();
- this._queueAutoHide();
- },
-
- hide: function() {
- this._visible = false;
- this._visibleInternal = false;
- this._updateVisibility();
- },
-
- destroy: function() {
- this.bar_widget.destroy();
- this.prev_widget.destroy();
- this.next_widget.destroy();
- this._tapGesture = null;
}
});
@@ -892,22 +737,21 @@ const EvinceViewToolbar = new Lang.Class({
if (!this._model)
return;
- let evDoc = this._model.get_document();
- let hasPages = (evDoc.get_n_pages() > 0);
let isFind = true;
try {
// This is a hack to find out if evDoc implements the
// EvDocument.DocumentFind interface or not. We don't expect
// the following invocation to work.
+ let evDoc = this._model.get_document();
evDoc.find_text();
} catch (e if e instanceof TypeError) {
isFind = false;
} catch (e) {
}
- this._handleEvent = (hasPages && isFind);
- this._searchAction.enabled = (hasPages && isFind);
+ this._handleEvent = (this.hasPages && isFind);
+ this._searchAction.enabled = (this.hasPages && isFind);
},
_getEvinceViewMenu: function() {
diff --git a/src/lokview.js b/src/lokview.js
index 2c97d4b..85a4119 100644
--- a/src/lokview.js
+++ b/src/lokview.js
@@ -31,13 +31,12 @@ const Gtk = imports.gi.Gtk;
const _ = imports.gettext.gettext;
const Lang = imports.lang;
-const Mainloop = imports.mainloop;
const Signals = imports.signals;
-const Tweener = imports.tweener.tweener;
const Application = imports.application;
const ErrorBox = imports.errorBox;
const MainToolbar = imports.mainToolbar;
+const Preview = imports.preview;
const Documents = imports.documents;
const ZOOM_IN_FACTOR = 1.2;
@@ -199,13 +198,6 @@ const LOKView = new Lang.Class({
open_document_cb: function(res, doc) {
// TODO: Call _finish and check failure
- if (isOpenDocumentPartDocument(this._doc.mimeType)) {
- this.hasParts = true;
- this.totalParts = this.view.get_parts();
- this.currentPart = this.view.get_part();
- } else
- this.hasParts = false;
-
this._progressBar.hide();
this.set_visible_child_name('view');
this.view.set_edit(false);
@@ -234,7 +226,7 @@ const LOKView = new Lang.Class({
this.view.connect('notify::can-zoom-out', Lang.bind(this, this._onCanZoomOutChanged));
}
- this._navControls = new LOKViewNavControls(this, this._overlay);
+ this._navControls = new Preview.PreviewNavControls(this, this._overlay);
this.set_visible_child_full('view', Gtk.StackTransitionType.NONE);
},
@@ -268,6 +260,39 @@ const LOKView = new Lang.Class({
this._errorBox.update(primary, secondary);
this.set_visible_child_name('error');
},
+
+ goPrev: function() {
+ let currentPart = this.view.get_part();
+ currentPart -= 1;
+ if (currentPart < 0)
+ return;
+ this.view.set_part(currentPart);
+ // FIXME: https://bugs.documentfoundation.org/show_bug.cgi?id=97236
+ this.view.reset_view();
+ },
+
+ goNext: function() {
+ let totalParts = this.view.get_parts();
+ let currentPart = this.view.get_part();
+ currentPart += 1;
+ if (currentPart > totalParts)
+ return;
+ this.view.set_part(currentPart);
+ // FIXME: https://bugs.documentfoundation.org/show_bug.cgi?id=97236
+ this.view.reset_view();
+ },
+
+ get hasPages() {
+ return isOpenDocumentPartDocument(this._doc.mimeType);
+ },
+
+ get page() {
+ return this.view.get_part();
+ },
+
+ get numPages() {
+ return this.view.get_parts();
+ }
});
Signals.addSignalMethods(LOKView.prototype);
@@ -353,175 +378,3 @@ const LOKViewToolbar = new Lang.Class({
this.toolbar.set_title(primary);
}
});
-
-const _LOKVIEW_NAVBAR_MARGIN = 30;
-const _AUTO_HIDE_TIMEOUT = 2;
-
-const LOKViewNavControls = new Lang.Class({
- Name: 'LOKViewNavControls',
-
- _init: function(lokView, overlay) {
- this._lokView = lokView;
- this._overlay = overlay;
-
- this._visible = false;
- this._visibleInternal = false;
- this._pageChangedId = 0;
- this._autoHideId = 0;
- this._motionId = 0;
-
- this.prev_widget = new Gtk.Button({ image: new Gtk.Image ({ icon_name: 'go-previous-symbolic',
- pixel_size: 16 }),
- margin_start: _LOKVIEW_NAVBAR_MARGIN,
- margin_end: _LOKVIEW_NAVBAR_MARGIN,
- halign: Gtk.Align.START,
- valign: Gtk.Align.CENTER });
- this.prev_widget.get_style_context().add_class('osd');
- this._overlay.add_overlay(this.prev_widget);
- this.prev_widget.connect('clicked', Lang.bind(this, this._onPrevClicked));
- this.prev_widget.connect('enter-notify-event', Lang.bind(this, this._onEnterNotify));
- this.prev_widget.connect('leave-notify-event', Lang.bind(this, this._onLeaveNotify));
-
- this.next_widget = new Gtk.Button({ image: new Gtk.Image ({ icon_name: 'go-next-symbolic',
- pixel_size: 16 }),
- margin_start: _LOKVIEW_NAVBAR_MARGIN,
- margin_end: _LOKVIEW_NAVBAR_MARGIN,
- halign: Gtk.Align.END,
- valign: Gtk.Align.CENTER });
- this.next_widget.get_style_context().add_class('osd');
- this._overlay.add_overlay(this.next_widget);
- this.next_widget.connect('clicked', Lang.bind(this, this._onNextClicked));
- this.next_widget.connect('enter-notify-event', Lang.bind(this, this._onEnterNotify));
- this.next_widget.connect('leave-notify-event', Lang.bind(this, this._onLeaveNotify));
- this._overlay.connect('motion-notify-event', Lang.bind(this, this._onMotion));
- },
-
- _onEnterNotify: function() {
- this._unqueueAutoHide();
- return false;
- },
-
- _onLeaveNotify: function() {
- this._queueAutoHide();
- return false;
- },
-
- _motionTimeout: function() {
- this._motionId = 0;
- this._visibleInternal = true;
- this._updateVisibility();
- this._queueAutoHide();
- return false;
- },
-
- _onMotion: function(widget, event) {
- if (this._motionId != 0) {
- return false;
- }
-
- let device = event.get_source_device();
- if (device.input_source == Gdk.InputSource.TOUCHSCREEN) {
- return false;
- }
-
- this._motionId = Mainloop.idle_add(Lang.bind(this, this._motionTimeout));
- return false;
- },
-
- _onPrevClicked: function() {
- let currentPart = this._lokView.view.get_part();
- currentPart -= 1;
- if (currentPart < 0)
- return;
- this._lokView.view.set_part(currentPart);
- // FIXME: https://bugs.documentfoundation.org/show_bug.cgi?id=97236
- this._lokView.view.reset_view();
- this._lokView.currentPart = currentPart;
- },
-
- _onNextClicked: function() {
- let totalParts = this._lokView.view.get_parts();
- let currentPart = this._lokView.view.get_part();
- currentPart += 1;
- if (currentPart > totalParts)
- return;
- this._lokView.view.set_part(currentPart);
- // FIXME: https://bugs.documentfoundation.org/show_bug.cgi?id=97236
- this._lokView.view.reset_view();
- this._lokView.currentPart = currentPart;
- },
-
- _autoHide: function() {
- this._autoHideId = 0;
- this._visibleInternal = false;
- this._updateVisibility();
- return false;
- },
-
- _unqueueAutoHide: function() {
- if (this._autoHideId == 0)
- return;
-
- Mainloop.source_remove(this._autoHideId);
- this._autoHideId = 0;
- },
-
- _queueAutoHide: function() {
- this._unqueueAutoHide();
- //FIXME: disable this temporarily till motion-notify-event works
- //this._autoHideId = Mainloop.timeout_add_seconds(_AUTO_HIDE_TIMEOUT, Lang.bind(this,
this._autoHide));
- },
-
- _updateVisibility: function() {
- if (!this._lokView.hasParts) {
- this._fadeOutButton(this.prev_widget);
- this._fadeOutButton(this.next_widget);
- return;
- }
-
- if (this._lokView.currentPart > 0)
- this._fadeInButton(this.prev_widget);
- else
- this._fadeOutButton(this.prev_widget);
-
- if (this._lokView.currentPart < this._lokView.totalParts)
- this._fadeInButton(this.next_widget);
- else
- this._fadeOutButton(this.next_widget);
- },
-
- _fadeInButton: function(widget) {
- widget.show_all();
- Tweener.addTween(widget, { opacity: 1,
- time: 0.30,
- transition: 'easeOutQuad' });
- },
-
- _fadeOutButton: function(widget) {
- Tweener.addTween(widget, { opacity: 0,
- time: 0.30,
- transition: 'easeOutQuad',
- onComplete: function() {
- widget.hide();
- },
- onCompleteScope: this });
- },
-
- show: function() {
- this._visible = true;
- this._visibleInternal = true;
- this._updateVisibility();
- this._queueAutoHide();
- },
-
- hide: function() {
- this._visible = false;
- this._visibleInternal = false;
- this._updateVisibility();
- },
-
- destroy: function() {
- this.prev_widget.destroy();
- this.next_widget.destroy();
- }
-});
diff --git a/src/org.gnome.Books.src.gresource.xml b/src/org.gnome.Books.src.gresource.xml
index ec04c5f..e76b30e 100644
--- a/src/org.gnome.Books.src.gresource.xml
+++ b/src/org.gnome.Books.src.gresource.xml
@@ -18,6 +18,7 @@
<file>password.js</file>
<file>places.js</file>
<file>presentation.js</file>
+ <file>preview.js</file>
<file>evinceview.js</file>
<file>properties.js</file>
<file>query.js</file>
diff --git a/src/org.gnome.Documents.src.gresource.xml b/src/org.gnome.Documents.src.gresource.xml
index ea5ff97..44c00e0 100644
--- a/src/org.gnome.Documents.src.gresource.xml
+++ b/src/org.gnome.Documents.src.gresource.xml
@@ -17,6 +17,7 @@
<file>notifications.js</file>
<file>password.js</file>
<file>places.js</file>
+ <file>preview.js</file>
<file>presentation.js</file>
<file>evinceview.js</file>
<file>properties.js</file>
diff --git a/src/preview.js b/src/preview.js
new file mode 100644
index 0000000..3fd5553
--- /dev/null
+++ b/src/preview.js
@@ -0,0 +1,206 @@
+const GdPrivate = imports.gi.GdPrivate;
+const Gdk = imports.gi.Gdk;
+const Gtk = imports.gi.Gtk;
+
+const Lang = imports.lang;
+const Mainloop = imports.mainloop;
+const Tweener = imports.tweener.tweener;
+
+const _AUTO_HIDE_TIMEOUT = 2;
+const PREVIEW_NAVBAR_MARGIN = 30;
+
+const PreviewNavControls = new Lang.Class({
+ Name: 'PreviewNavControls',
+
+ _init: function(preview, overlay) {
+ this._preview = preview;
+ this._overlay = overlay;
+
+ this._visible = false;
+ this._visibleInternal = false;
+ this._pageChangedId = 0;
+ this._autoHideId = 0;
+ this._motionId = 0;
+
+ this.bar_widget = this.createBarWidget();
+ if (this.bar_widget) {
+ this.bar_widget.get_style_context().add_class('osd');
+ this._overlay.add_overlay(this.bar_widget);
+ this.bar_widget.connect('notify::hover', Lang.bind(this, function() {
+ if (this.bar_widget.hover)
+ this._onEnterNotify();
+ else
+ this._onLeaveNotify();
+ }));
+ }
+
+ this.prev_widget = new Gtk.Button({ image: new Gtk.Image ({ icon_name: 'go-previous-symbolic',
+ pixel_size: 16 }),
+ margin_start: PREVIEW_NAVBAR_MARGIN,
+ margin_end: PREVIEW_NAVBAR_MARGIN,
+ halign: Gtk.Align.START,
+ valign: Gtk.Align.CENTER });
+ this.prev_widget.get_style_context().add_class('osd');
+ this._overlay.add_overlay(this.prev_widget);
+ this.prev_widget.connect('clicked', Lang.bind(this, this._onPrevClicked));
+ this.prev_widget.connect('enter-notify-event', Lang.bind(this, this._onEnterNotify));
+ this.prev_widget.connect('leave-notify-event', Lang.bind(this, this._onLeaveNotify));
+
+ this.next_widget = new Gtk.Button({ image: new Gtk.Image ({ icon_name: 'go-next-symbolic',
+ pixel_size: 16 }),
+ margin_start: PREVIEW_NAVBAR_MARGIN,
+ margin_end: PREVIEW_NAVBAR_MARGIN,
+ halign: Gtk.Align.END,
+ valign: Gtk.Align.CENTER });
+ this.next_widget.get_style_context().add_class('osd');
+ this._overlay.add_overlay(this.next_widget);
+ this.next_widget.connect('clicked', Lang.bind(this, this._onNextClicked));
+ this.next_widget.connect('enter-notify-event', Lang.bind(this, this._onEnterNotify));
+ this.next_widget.connect('leave-notify-event', Lang.bind(this, this._onLeaveNotify));
+
+ this._overlay.connect('motion-notify-event', Lang.bind(this, this._onMotion));
+
+ this._tapGesture = new Gtk.GestureMultiPress({ propagation_phase: Gtk.PropagationPhase.CAPTURE,
+ touch_only: true,
+ widget: this._preview.view });
+ this._tapGesture.connect('released', Lang.bind(this, this._onMultiPressReleased));
+ this._tapGesture.connect('stopped', Lang.bind(this, this._onMultiPressStopped));
+ },
+
+ createBarWidget: function() {
+ return null;
+ },
+
+ _onEnterNotify: function() {
+ this._unqueueAutoHide();
+ return false;
+ },
+
+ _onLeaveNotify: function() {
+ this._queueAutoHide();
+ return false;
+ },
+
+ _motionTimeout: function() {
+ this._motionId = 0;
+ this._visibleInternal = true;
+ this._updateVisibility();
+ if (this.bar_widget && !this.bar_widget.hover)
+ this._queueAutoHide();
+ return false;
+ },
+
+ _onMotion: function(widget, event) {
+ if (this._motionId != 0)
+ return false;
+
+ let device = event.get_source_device();
+ if (device.input_source == Gdk.InputSource.TOUCHSCREEN)
+ return false;
+
+ this._motionId = Mainloop.idle_add(Lang.bind(this, this._motionTimeout));
+ return false;
+ },
+
+ _onMultiPressReleased: function() {
+ this._tapGesture.set_state(Gtk.EventSequenceState.CLAIMED);
+ this._visibleInternal = !this._visibleInternal;
+ this._unqueueAutoHide();
+ this._updateVisibility();
+ },
+
+ _onMultiPressStopped: function() {
+ this._tapGesture.set_state(Gtk.EventSequenceState.DENIED);
+ },
+
+ _onPrevClicked: function() {
+ this._preview.goPrev();
+ },
+
+ _onNextClicked: function() {
+ this._preview.goNext();
+ },
+
+ _autoHide: function() {
+ this._autoHideId = 0;
+ this._visibleInternal = false;
+ this._updateVisibility();
+ return false;
+ },
+
+ _unqueueAutoHide: function() {
+ if (this._autoHideId == 0)
+ return;
+
+ Mainloop.source_remove(this._autoHideId);
+ this._autoHideId = 0;
+ },
+
+ _queueAutoHide: function() {
+ this._unqueueAutoHide();
+ this._autoHideId = Mainloop.timeout_add_seconds(_AUTO_HIDE_TIMEOUT, Lang.bind(this, this._autoHide));
+ },
+
+ _updateVisibility: function() {
+ let currentPage = this._preview.page;
+ let numPages = this._preview.numPages;
+
+ if (!this._visible || !this._visibleInternal || !this._preview.hasPages) {
+ if (this.bar_widget)
+ this._fadeOutButton(this.bar_widget);
+ this._fadeOutButton(this.prev_widget);
+ this._fadeOutButton(this.next_widget);
+ return;
+ }
+
+ if (this.bar_widget)
+ this._fadeInButton(this.bar_widget);
+
+ if (currentPage > 0)
+ this._fadeInButton(this.prev_widget);
+ else
+ this._fadeOutButton(this.prev_widget);
+
+ if (numPages > currentPage + 1)
+ this._fadeInButton(this.next_widget);
+ else
+ this._fadeOutButton(this.next_widget);
+ },
+
+ _fadeInButton: function(widget) {
+ widget.show_all();
+ Tweener.addTween(widget, { opacity: 1,
+ time: 0.30,
+ transition: 'easeOutQuad' });
+ },
+
+ _fadeOutButton: function(widget) {
+ Tweener.addTween(widget, { opacity: 0,
+ time: 0.30,
+ transition: 'easeOutQuad',
+ onComplete: function() {
+ widget.hide();
+ }});
+ },
+
+ show: function() {
+ this._visible = true;
+ this._visibleInternal = true;
+ this._updateVisibility();
+ this._queueAutoHide();
+ },
+
+ hide: function() {
+ this._visible = false;
+ this._visibleInternal = false;
+ this._updateVisibility();
+ },
+
+ destroy: function() {
+ if (this.bar_widget)
+ this.bar_widget.destroy();
+ this.prev_widget.destroy();
+ this.next_widget.destroy();
+ this._tapGesture = null;
+ }
+});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]