mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Add in floating buttons for syncing between code and PDF
This commit is contained in:
parent
5f72f13528
commit
79cb8270e5
9 changed files with 122 additions and 8 deletions
|
@ -202,6 +202,11 @@
|
|||
#rawLogArea(style='display: none;')
|
||||
pre
|
||||
|
||||
script(type="text/template")#syncButtonsTemplate
|
||||
div.sync-buttons
|
||||
button.btn.sync-code-to-pdf →
|
||||
button.btn.sync-pdf-to-code ←
|
||||
|
||||
script(type="text/template")#outputFileLinkTemplate
|
||||
li
|
||||
a(href="/project/{{ project_id }}/output/{{ path }}", target="_blank") Download {{ name }}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
padding: 5px;
|
||||
font-size: 11px;
|
||||
.opacity(0);
|
||||
&.in { .opacity(80); }
|
||||
&.in { .opacity(100); }
|
||||
&.top { margin-top: -2px; }
|
||||
&.right { margin-left: 2px; }
|
||||
&.bottom { margin-top: 2px; }
|
||||
|
|
|
@ -50,7 +50,7 @@ define [
|
|||
@openDoc doc_id, options
|
||||
|
||||
initSplitView: () ->
|
||||
splitter = @editorPanel.find("#editorSplitter")
|
||||
@$splitter = splitter = @editorPanel.find("#editorSplitter")
|
||||
options =
|
||||
spacing_open: 8
|
||||
spacing_closed: 16
|
||||
|
@ -286,6 +286,7 @@ define [
|
|||
$.localStorage("doc.position.#{@current_doc_id}", docPosition)
|
||||
|
||||
onCursorChange: (event) ->
|
||||
@trigger "cursor:change", event
|
||||
if !@ignoreCursorPositionChanges
|
||||
docPosition = $.localStorage("doc.position.#{@current_doc_id}") || {}
|
||||
docPosition.cursorPosition = @getCursorPosition()
|
||||
|
@ -341,6 +342,9 @@ define [
|
|||
getContainerElement: () ->
|
||||
$(@aceEditor.renderer.getContainerElement())
|
||||
|
||||
getCursorElement: () ->
|
||||
@getContainerElement().find(".ace_cursor")
|
||||
|
||||
textToEditorCoordinates: (x, y) ->
|
||||
editorAreaOffset = @getContainerElement().offset()
|
||||
{pageX, pageY} = @aceEditor.renderer.textToScreenCoordinates(x, y)
|
||||
|
|
|
@ -218,4 +218,7 @@ define [
|
|||
highlightInPdf: (args...) ->
|
||||
@pdfView.highlightInPdf?(args...)
|
||||
|
||||
getPdfPosition: () ->
|
||||
@pdfView.getPdfPosition?()
|
||||
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ define [
|
|||
page: first.page
|
||||
offset:
|
||||
left: first.highlight.left
|
||||
top: first.highlight.top - 100
|
||||
top: first.highlight.top - 80
|
||||
}, true)
|
||||
|
||||
@pdfListView.clearHighlights()
|
||||
|
@ -154,6 +154,14 @@ define [
|
|||
@pdfListView.clearHighlights()
|
||||
, 1000
|
||||
|
||||
getPdfPosition: () ->
|
||||
position = @pdfListView.getPdfPosition(true)
|
||||
return if !position?
|
||||
return {
|
||||
page: position.page
|
||||
x: position.offset.left
|
||||
y: position.offset.top
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
define [
|
||||
"utils/Modal"
|
||||
"pdf/CompiledView"
|
||||
"pdf/SyncButtonsView"
|
||||
"libs/latex-log-parser"
|
||||
"libs/jquery.storage"
|
||||
"libs/underscore"
|
||||
"libs/backbone"
|
||||
], (Modal, CompiledView, LogParser) ->
|
||||
], (Modal, CompiledView, SyncButtonsView, LogParser) ->
|
||||
class PdfManager
|
||||
templates:
|
||||
pdfLink: $("#pdfSideBarLinkTemplate").html()
|
||||
|
||||
constructor: (@ide) ->
|
||||
_.extend @, Backbone.Events
|
||||
@createSyncButtons()
|
||||
@createPdfPanel()
|
||||
@ide.editor.aceEditor.commands.addCommand
|
||||
name: "compile",
|
||||
|
@ -35,6 +37,15 @@ define [
|
|||
else
|
||||
@switchToSplitView()
|
||||
|
||||
createSyncButtons: () ->
|
||||
unless @ide.userSettings.pdfViewer == "native"
|
||||
@syncButtonsView = new SyncButtonsView(ide: @ide)
|
||||
@syncButtonsView.on "click:sync-code-to-pdf", () =>
|
||||
@syncToPdf()
|
||||
@syncButtonsView.on "click:sync-pdf-to-code", () =>
|
||||
@syncToCode()
|
||||
@syncButtonsView.hide()
|
||||
|
||||
switchToFlatView: (options = {showPdf: false}) ->
|
||||
@teardownSplitView()
|
||||
@setupFlatView()
|
||||
|
@ -85,6 +96,11 @@ define [
|
|||
|
||||
@view.undelegateEvents()
|
||||
@view.delegateEvents()
|
||||
|
||||
@ide.editor.$splitter.append(
|
||||
@syncButtonsView?.$el
|
||||
)
|
||||
|
||||
setTimeout(@ide.layoutManager.resizeAllSplitters, 100)
|
||||
|
||||
teardownSplitView: () ->
|
||||
|
@ -112,7 +128,9 @@ define [
|
|||
doneCompiling = _.once =>
|
||||
@compiling = false
|
||||
@view.doneCompiling()
|
||||
@syncButtonsView?.show()
|
||||
setTimeout doneCompiling, 1000 * 60
|
||||
|
||||
if !@ide.project.get("rootDoc_id")?
|
||||
new Modal
|
||||
title: "No root document selected"
|
||||
|
@ -123,6 +141,7 @@ define [
|
|||
}]
|
||||
else if !@compiling
|
||||
@view.onCompiling()
|
||||
@syncButtonsView?.hide()
|
||||
@compiling = true
|
||||
@ide.socket.emit "pdfProject", opts, (err, pdfExists, outputFiles) =>
|
||||
@compiling = false
|
||||
|
@ -142,6 +161,7 @@ define [
|
|||
else
|
||||
@view.unsetPdf()
|
||||
@view.showLog()
|
||||
@syncButtonsView?.hide()
|
||||
|
||||
if outputFiles?
|
||||
@view.showOutputFileDownloadLinks(outputFiles)
|
||||
|
@ -213,6 +233,13 @@ define [
|
|||
}]
|
||||
|
||||
syncToCode: (e) ->
|
||||
if !e?
|
||||
e = @view.getPdfPosition()
|
||||
return if !e?
|
||||
# It's not clear exactly where we should sync to if it was directly
|
||||
# clicked on, but a little bit down from the very top seems best.
|
||||
e.y = e.y + 80
|
||||
|
||||
$.ajax {
|
||||
url: "/project/#{@ide.project_id}/sync/pdf"
|
||||
data:
|
||||
|
|
45
services/web/public/coffee/pdf/SyncButtonsView.coffee
Normal file
45
services/web/public/coffee/pdf/SyncButtonsView.coffee
Normal file
|
@ -0,0 +1,45 @@
|
|||
define [
|
||||
"libs/backbone"
|
||||
"libs/mustache"
|
||||
], () ->
|
||||
SyncButtonsView = Backbone.View.extend
|
||||
template: $("#syncButtonsTemplate").html()
|
||||
|
||||
events:
|
||||
"click .sync-code-to-pdf": () -> @trigger "click:sync-code-to-pdf"
|
||||
"click .sync-pdf-to-code": () -> @trigger "click:sync-pdf-to-code"
|
||||
|
||||
initialize: (options) ->
|
||||
@render()
|
||||
@ide = options.ide
|
||||
@ide.editor.on "resize", => @repositionLeft()
|
||||
@ide.editor.on "cursor:change", => @repositionTop()
|
||||
|
||||
render: () ->
|
||||
@setElement($(@template))
|
||||
return @
|
||||
|
||||
hide: () -> @$el.hide()
|
||||
|
||||
show: () -> @$el.show()
|
||||
|
||||
repositionLeft: () ->
|
||||
state = @ide.editor.$splitter.layout().readState()
|
||||
if state.east?
|
||||
@$el.css({right: state.east.size - 8})
|
||||
|
||||
repositionTop: () ->
|
||||
# The cursor hasn't actually moved yet.
|
||||
setTimeout () =>
|
||||
cursor = @ide.editor.getCursorElement()
|
||||
container = @ide.editor.getContainerElement()
|
||||
top = cursor.offset().top - container.offset().top
|
||||
top = top - 6
|
||||
|
||||
max = @ide.editor.getContainerElement().outerHeight() - @$el.outerHeight()
|
||||
top = 0 if top < 0
|
||||
top = max if top > max
|
||||
|
||||
@$el.css({top: top})
|
||||
, 10
|
||||
|
|
@ -369,12 +369,15 @@ ListView.prototype = {
|
|||
this.setPdfPosition(this.pdfPosition);
|
||||
},
|
||||
|
||||
getPdfPosition: function() {
|
||||
getPdfPosition: function(fromTop) {
|
||||
var pdfPosition = null;
|
||||
for (var i = 0; i < this.pageViews.length; i++) {
|
||||
var pageView = this.pageViews[i];
|
||||
var pdfOffset = pageView.getUppermostVisiblePdfOffset();
|
||||
if (pdfOffset !== null) {
|
||||
if (fromTop) {
|
||||
pdfOffset = pageView.normalHeight - pdfOffset;
|
||||
}
|
||||
pdfPosition = {
|
||||
page: i,
|
||||
offset: {
|
||||
|
@ -922,8 +925,8 @@ PDFListView.prototype = {
|
|||
this.renderController.onResize();
|
||||
},
|
||||
|
||||
getPdfPosition: function() {
|
||||
return this.listView.getPdfPosition();
|
||||
getPdfPosition: function(fromTop) {
|
||||
return this.listView.getPdfPosition(fromTop);
|
||||
},
|
||||
|
||||
setPdfPosition: function(pdfPosition, fromTop) {
|
||||
|
|
|
@ -204,6 +204,25 @@ body.editor {
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.sync-buttons {
|
||||
z-index: 3;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 2px;
|
||||
background-color: #eee;
|
||||
.border-radius(3px);
|
||||
border: 1px solid #aaa;
|
||||
button {
|
||||
display: block;
|
||||
padding: 3px;
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
}
|
||||
button:first-child {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undoConflictWarning {
|
||||
|
@ -223,7 +242,7 @@ body.editor {
|
|||
#pdfArea {
|
||||
background-color: #eee;
|
||||
#pdfToolBar{
|
||||
padding: 5px 5px 3px 5px;
|
||||
padding: 5px 10px 3px 10px;
|
||||
margin: 0;
|
||||
background-color: white;
|
||||
border-bottom: 1px solid #aaa;
|
||||
|
|
Loading…
Reference in a new issue