Skip to content

Commit 57d876e

Browse files
committed
- Fixed hovering action to be more reliable
- Fixed fullscreen-related issue - Added tooltip about residue being hovered on structure viewere in Foldmason page - Minute style changes
1 parent e3c59d8 commit 57d876e

6 files changed

Lines changed: 90 additions & 49 deletions

File tree

frontend/MSA.vue

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
@removeHighlight="spliceActiveIndex"
6363
@changePreview="changePreview"
6464
ref="structViewer"
65+
id="structure-viewer"
6566
/>
6667
</div>
6768
<v-card-text v-if="structureViewerSelection.length == 0" style="position: absolute; top: calc(50% - 27px); left: 0; text-align: center;">
@@ -227,7 +228,7 @@
227228
justify-content: space-between;
228229
align-items: center;"
229230
>
230-
<div style="
231+
<!-- <div style="
231232
width: 36px;
232233
height: 36px;
233234
display: flex;
@@ -236,7 +237,8 @@
236237
<v-icon style="display: block;">
237238
{{ $MDI.CursorMove }}
238239
</v-icon>
239-
</div>
240+
</div> -->
241+
<div class="drag-handle" style="flex-grow: 1; align-self: stretch;"/>
240242
<!-- <v-card-title>Structure</v-card-title> -->
241243
<v-btn icon @click="toggleView" style="display: block;">
242244
<v-icon>
@@ -257,7 +259,7 @@
257259
@removeHighlight="spliceActiveIndex"
258260
ref="structViewer"
259261
/> -->
260-
<v-card-text v-if="structureViewerSelection.length == 0" style="position: absolute; top: calc(50% - 27px); left: 0; text-align: center;">
262+
<v-card-text v-if="structureViewerSelection.length == 0" style="position: absolute; top: calc(50% - 45px); left: 0; text-align: center; z-index: 1;">
261263
No structures loaded.
262264
</v-card-text>
263265
</div>
@@ -568,9 +570,11 @@ export default {
568570
this.blockIndex = Math.floor((scroll - top) / blockSize);
569571
}
570572
573+
if (!!document.fullscreenElement) return
574+
571575
this.showViewerCondition = this.showViewer
572576
&& scrollOffset >= rowHeight
573-
577+
574578
if (
575579
this.showViewerCondition
576580
) {
@@ -731,7 +735,7 @@ export default {
731735
this.selectedColumns.shift()
732736
}
733737
this.$emit('changedSelection', this.selectedColumns)
734-
this.$refs.msaView.addHighlightColumn(idx, move)
738+
this.$refs.msaView.addHighlightColumn(idx, move && this.showViewer)
735739
this.$refs.structViewer.updateAllHighlights()
736740
this.$refs.structViewer.moveView(idx)
737741
},
@@ -765,7 +769,7 @@ export default {
765769
this.previewColumn = Number(idx)
766770
767771
if (fromStruct) {
768-
this.$refs.msaView.activateColumn(idx, true)
772+
this.$refs.msaView.activateColumn(idx, true, true && this.showViewerCondition)
769773
this.$nextTick(() => {
770774
setTimeout(()=>{
771775
this.$refs.structViewer.updateAllPreview()

frontend/MSAView.vue

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ export default {
417417
arr?.forEach(e => e.classList.remove('preview-column'))
418418
this.$emit('changePreview', -1)
419419
},
420-
activateColumn(id, move=false) {
420+
activateColumn(id, fromUpward=false, move=false) {
421421
const wrapper = this.$refs.msaWrapper
422422
423423
const arr = wrapper?.querySelectorAll('.preview-column')
@@ -431,9 +431,8 @@ export default {
431431
top: el.getBoundingClientRect().top + window.scrollY - (180),
432432
left: 0,
433433
behavior: 'smooth'
434-
})
435-
}
436-
} else {
434+
})}
435+
} else if (!fromUpward) {
437436
this.$emit('changePreview', id)
438437
}
439438
},

frontend/NameField.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ small.ticket {
191191
bottom: -1px;
192192
left: 0;
193193
width: 100%;
194-
height: 1px;
194+
height: 2px;
195195
z-index: 3;
196196
background-color: var(--primary-color);
197197
transform: scaleX(0);

frontend/NavigationButton.vue

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
11
<template>
2-
<v-sheet color="transparent" style="position: fixed; width: 200px; right: 16px; bottom: 16px; z-index: 99998; align-items: center; justify-content: flex-end;"
3-
class="d-flex pa-2">
4-
<v-flex shrink style="flex-direction: row;">
5-
<v-tooltip top>
6-
<template v-slot:activator='{on,attrs}'>
7-
<v-fab-transition>
8-
<v-btn small v-bind="attrs" v-on="on" fab
9-
v-show="enableScrollPrev" @click="goTo(scrollPrevTarget)">
10-
<v-icon>{{ $MDI.ChevronUp }}</v-icon>
11-
</v-btn>
12-
</v-fab-transition>
13-
</template>
14-
<span>Scroll to prev. cluster</span>
15-
</v-tooltip>
16-
<v-tooltip top>
17-
<template v-slot:activator='{on,attrs}'>
18-
<v-fab-transition>
19-
<v-btn small v-bind="attrs" v-on="on" fab
20-
v-show="enableScrollNext" @click="goTo(scrollNextTarget)">
21-
<v-icon>{{ $MDI.ChevronDown }}</v-icon>
22-
</v-btn>
23-
</v-fab-transition>
24-
</template>
25-
<span>Scroll to next cluster</span>
26-
</v-tooltip>
2+
<v-sheet color="transparent" style="position: fixed; right: 16px; bottom: 16px; z-index: 99998; align-items: center; justify-content: flex-end;"
3+
class="d-flex pa-2">
4+
<v-flex class="mr-3" shrink style="flex-direction: row;" v-if="scrollOffsetArr.length > 0">
5+
<v-tooltip top>
6+
<template v-slot:activator='{on,attrs}'>
7+
<v-fab-transition>
8+
<v-btn small v-bind="attrs" v-on="on" fab
9+
v-show="enableScrollPrev" @click="goTo(scrollPrevTarget)">
10+
<v-icon>{{ $MDI.ChevronUp }}</v-icon>
11+
</v-btn>
12+
</v-fab-transition>
13+
</template>
14+
<span>Scroll to prev. cluster</span>
15+
</v-tooltip>
16+
<v-tooltip top>
17+
<template v-slot:activator='{on,attrs}'>
18+
<v-fab-transition>
19+
<v-btn small v-bind="attrs" v-on="on" fab
20+
v-show="enableScrollNext" @click="goTo(scrollNextTarget)">
21+
<v-icon>{{ $MDI.ChevronDown }}</v-icon>
22+
</v-btn>
23+
</v-fab-transition>
24+
</template>
25+
<span>Scroll to next cluster</span>
26+
</v-tooltip>
2727
</v-flex>
2828
<v-tooltip top color="primary">
2929
<template v-slot:activator='{on,attrs}'>
3030
<v-fab-transition>
31-
<v-btn class="ml-3" color="primary" fab v-show="enableScrollTop" @click="goTo(0)" v-bind="attrs" v-on="on">
31+
<v-btn color="primary" fab v-show="enableScrollTop" @click="goTo(0)" v-bind="attrs" v-on="on">
3232
<v-icon>{{ $MDI.DoubleChevronUp }}</v-icon>
33-
</v-btn>
33+
</v-btn>
3434
</v-fab-transition>
3535
</template>
3636
<span>Scroll to top</span>

frontend/SelectToSendPanelFoldMason.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<div>
33
<!-- For displaying number of selected entries and buttons to switch -->
44
<v-fade-transition>
5-
<v-sheet color="transparent" :style="{'position': 'fixed', 'width': $vuetify.breakpoint.smAndDown ? '80%' : '40%',
5+
<v-sheet color="transparent" :style="{'position': 'fixed', 'width': $vuetify.breakpoint.smAndDown ? 'fit-content' : '40%',
66
'left': $vuetify.breakpoint.smAndDown ? '16px' : '30%',
77
'bottom': '16px', 'z-index': 99998, 'align-items': 'center', 'justify-content': $vuetify.breakpoint.smAndDown ? 'flex-start' : 'space-between', 'opacity': loading ? 0.4 : 1}"
88
class="d-flex pa-2" v-if="targetIndex >= 0"

frontend/StructureViewerMSA.vue

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<div class="structure-panel">
33
<StructureViewerTooltip attach=".structure-panel" />
4-
<div class="structure-wrapper" ref="structurepanel">
4+
<div class="structure-wrapper" ref="structurepanel" @mouseleave="clearTimer" @mousedown="isMouseDown = true" @mouseup="isMouseDown = false">
55
<StructureViewerToolbar
66
:isFullscreen="isFullscreen"
77
:isSpinning="isSpinning"
@@ -16,6 +16,19 @@
1616
style="position: absolute; bottom: 8px;"
1717
/>
1818
<div class="structure-viewer" ref="viewport"></div>
19+
<div ref="previewTooltip"
20+
v-show="previewIndex >= 0"
21+
style="position: absolute;
22+
bottom: 48px;
23+
left: 8px;
24+
padding: 8px;
25+
font-size: 12px;
26+
background-color: rgba(0, 0, 0, 0.4);
27+
color: white
28+
"
29+
v-html="refRes"
30+
>
31+
</div>
1932
</div>
2033
</div>
2134
</template>
@@ -25,7 +38,7 @@ import StructureViewerTooltip from './StructureViewerTooltip.vue';
2538
import StructureViewerToolbar from './StructureViewerToolbar.vue';
2639
import StructureViewerMixin from './StructureViewerMixin.vue';
2740
import { tmalign, parse as parseTMOutput, parseMatrix as parseTMMatrix } from 'tmalign-wasm';
28-
import { mockPDB, makeSubPDB, makeMatrix4, getResidueIndices } from './Utilities.js';
41+
import { mockPDB, makeSubPDB, makeMatrix4, getResidueIndices, oneToThree } from './Utilities.js';
2942
import { download, PdbWriter, Matrix4, Quaternion, Vector3, concatStructures, ColormakerRegistry, Selection } from 'ngl';
3043
import { pulchra } from 'pulchra-wasm';
3144
@@ -142,6 +155,9 @@ export default {
142155
ticking: false,
143156
hoverTimer: null,
144157
pendingColumn: -1,
158+
registeredColumn: -1,
159+
isMouseDown: false,
160+
previewIndex: -1,
145161
}),
146162
props: {
147163
entries: { type: Array, required: true },
@@ -169,6 +185,7 @@ export default {
169185
this.stage.setParameters({
170186
hoverTimeout: 100,
171187
})
188+
172189
this.stage.signals.clicked.add((pickingProxy) => {
173190
if (!pickingProxy) {
174191
// this.selectedColumn = -1;
@@ -206,7 +223,7 @@ export default {
206223
});
207224
208225
this.stage.signals.hovered.add((pickingProxy) => {
209-
if (!pickingProxy || !pickingProxy.atom) {
226+
if (this.isMouseDown || !pickingProxy || !pickingProxy.atom) {
210227
this.clearTimer()
211228
return;
212229
}
@@ -222,7 +239,7 @@ export default {
222239
if (!this.ticking) {
223240
this.ticking = true
224241
window.requestAnimationFrame(() => {
225-
this.togglePreview()
242+
this.togglePreview(index)
226243
this.ticking = false
227244
})
228245
}
@@ -490,6 +507,7 @@ ENDMDL
490507
})
491508
);
492509
this.updateMask();
510+
this.clearTimer()
493511
},
494512
async updateMask() {
495513
this.stage.eachRepresentation((repr) => {
@@ -585,24 +603,29 @@ ENDMDL
585603
let sele = String(resIdx + 1 - range) + "-" + (resIdx - 1 + range)
586604
comp.autoView(sele, 200)
587605
},
588-
setTimer(idx) {
606+
setTimer(idx, structIdx) {
607+
this.registeredColumn = idx;
589608
this.hoverTimer = setTimeout(() => {
590-
console.log(idx, "fired")
609+
this.previewIndex = structIdx
591610
this.$emit('changePreview', idx, true)
592-
}, 1000)
611+
this.registeredColumn = -1
612+
}, 900)
593613
},
594614
clearTimer() {
595615
if (this.hoverTimer) {
596616
clearTimeout(this.hoverTimer)
597617
this.hoverTimer = null
598618
}
619+
this.previewIndex = -1
599620
this.$emit('changePreview', -1, true)
600621
},
601-
togglePreview() {
602-
if (this.previewColumn == this.pendingColumn) return
622+
togglePreview(index) {
623+
if (this.previewColumn == this.pendingColumn
624+
|| this.pendingColumn == this.registeredColumn
625+
) return
603626
604627
this.clearTimer()
605-
this.setTimer(this.pendingColumn)
628+
this.setTimer(this.pendingColumn, index)
606629
},
607630
},
608631
watch: {
@@ -640,6 +663,21 @@ ENDMDL
640663
highLightColor() {
641664
return 0xe31986
642665
},
666+
refRes() {
667+
if (this.previewColumn < 0
668+
|| this.previewIndex < 0) return ""
669+
670+
const targetObj = this.entries[this.previewIndex]
671+
const name = targetObj.name?.length > 12
672+
? targetObj.name.slice(0, 9) + '...'
673+
: targetObj.name
674+
const targetSeq = targetObj.aa
675+
const AA = oneToThree[targetSeq[this.previewColumn]]
676+
const formatted = AA.charAt(0) + AA.toLowerCase().slice(1, 3)
677+
const resNo = getResidueIndex(targetSeq, this.previewColumn) + 1
678+
return '<span>'+ name + ':&nbsp;</span><strong>'
679+
+ formatted + String(resNo) +'</strong>'
680+
},
643681
},
644682
}
645683
</script>

0 commit comments

Comments
 (0)