Files
GlModelViewer/modules/glmv-prev.js
Justin Georgi 0dd9aba2b6 Refactor js files (#48)
This pr is a significant reorg of the js files.

1) All non-basic functions have been moved out of the main glmv.js
2) 'Metadata' has been universally changed to mvconfig to avoid conflict with actual file metadata
3) Configuration changing functions have been split off into glmv-mvconfig.js
4) Hotspot modification functions have been split off into glmv-hs.js

Reviewed-on: #48
2024-11-18 03:54:29 +00:00

282 lines
7.4 KiB
JavaScript

//Initialize globals
require('./glmv-mvconfig.js')
require('./glmv-hs.js')
/**
* Use the OOui js library to create wikis-style menu
* options on the preview edits page for interaction
* with the model
*/
buildPreviewMenu = function() {
let [_, origMetadata] = extractMvconfig()
//Annotation Edit Controls
const addHS = new OO.ui.ButtonWidget({
icon: 'mapPinAdd',
label: 'Add annotation',
invisibleLabel: true,
class: 'edit-button'
})
addHS.on('click', readyAddHotspot)
addHS.setDisabled(true)
const updateHS = new OO.ui.ButtonWidget({
icon: 'reload',
label: 'Update annotations',
invisibleLabel: true
})
updateHS.on('click', readMvconfig)
updateHS.setDisabled(true)
const deleteHS = new OO.ui.ButtonWidget({
icon: 'cancel',
label: 'Delete annotation',
invisibleLabel: true
})
deleteHS.on('click', readyDelHotspot)
deleteHS.setDisabled(true)
const setOptions = ['default', ...Object.keys(origMetadata.annotationSets)]
let setOptionItems = []
setOptions.forEach(opt => {
setOptionItems.push(new OO.ui.MenuOptionWidget({data: opt, label: opt}))
})
const setSelectHS = new OO.ui.ButtonMenuSelectWidget({
icon: 'mapTrail',
label: 'Select annotation set',
invisibleLabel: true,
menu: {
items: setOptionItems,
width: 'min-content'
},
$overlay: $('#bodyContent')
})
setSelectHS.getMenu().on( 'choose', selSet => {
selectAnnotationSet(selSet.data)
})
setSelectHS.setDisabled(true)
const hotspotButtons = new OO.ui.ButtonGroupWidget({
items: [ addHS, updateHS, deleteHS, setSelectHS ]
})
//View Edit Controls
const downloadViewerImage = new OO.ui.ButtonWidget({
icon: 'imageAdd',
label: 'Download current image',
invisibleLabel: true
})
downloadViewerImage.on('click', () => {
downloadImage(mw.config.values.wgTitle)
})
downloadViewerImage.setDisabled(true)
const setView = new OO.ui.ButtonWidget({
icon: 'camera',
label: 'Set Initial View',
invisibleLabel: true
})
setView.on('click', writeCameraOrbit)
setView.setDisabled(true)
const setControl = new OO.ui.ButtonWidget({
icon: 'hand',
label: 'Toggle camera control',
invisibleLabel: true
})
setControl.on('click', () => $('model-viewer')[0].toggleAttribute('camera-controls', toggleCameraControl()))
setControl.setDisabled(true)
//View Limit Controls
const setMinYaw = new OO.ui.ButtonWidget({
label: 'Min'
})
setMinYaw.on('click', () => {
writeCameraLimit('yaw','min')
})
const setMaxYaw = new OO.ui.ButtonWidget({
label: 'Max'
})
setMaxYaw.on('click', () => {
writeCameraLimit('yaw','max')
})
const yawLimitButtons = new OO.ui.ButtonGroupWidget({
items: [ setMinYaw, setMaxYaw ]
})
const labelYaw = new OO.ui.LabelWidget({
label: "Yaw:"
})
const yawButtons = new OO.ui.HorizontalLayout({
items: [
labelYaw,
yawLimitButtons
],
id: 'yaw-limits'
})
const setMinPitch = new OO.ui.ButtonWidget({
label: 'Min'
})
setMinPitch.on('click', () => {
writeCameraLimit('pitch','min')
})
const setMaxPitch = new OO.ui.ButtonWidget({
label: 'Max'
})
setMaxPitch.on('click', () => {
writeCameraLimit('pitch','max')
})
const pitchLimitButtons = new OO.ui.ButtonGroupWidget({
items: [ setMinPitch, setMaxPitch ]
})
const labelPitch = new OO.ui.LabelWidget({
label: "Pitch:"
})
const pitchButtons = new OO.ui.HorizontalLayout({
items: [
labelPitch,
pitchLimitButtons
],
id: 'pitch-limits'
})
const setLims = new OO.ui.PopupButtonWidget({
label: 'Set View Limits',
invisibleLabel: true,
icon: 'tableMergeCells',
popup: {
$content: yawButtons.$element.add(pitchButtons.$element),
padded: true,
position: 'above'
},
$overlay: $('#bodyContent')
})
setLims.setDisabled(true)
const setViewConfig = [...Object.keys(origMetadata.viewerConfig)]
let setViewItems = []
setViewConfig.forEach(opt => {
setViewItems.push(new OO.ui.MenuOptionWidget({data: opt, label: opt}))
})
const selectVC = new OO.ui.ButtonMenuSelectWidget({
icon: 'eye',
label: 'Select view configuration',
invisibleLabel: true,
menu: {
items: setViewItems,
width: 'min-content'
},
$overlay: $('#bodyContent')
})
selectVC.getMenu().on( 'choose', selSet => {
selectViewConfig(selSet.data)
})
selectVC.setDisabled(true)
const cameraButtons = new OO.ui.ButtonGroupWidget({
items: [ downloadViewerImage, setControl, setView, setLims, selectVC ]
})
//Main Menu
const modelMenu = new OO.ui.HorizontalLayout({
items: [
hotspotButtons,
cameraButtons
],
id: 'edit-model-menu'
})
$('#wikiPreview').after(modelMenu.$element)
return [modelMenu, selectVC]
}
/**
* Enable all the preview menu widgets (called by
* model load event)
*/
enableMenu = function() {
modelMenu.items.forEach(group => {
group.items.forEach(el => el.setDisabled(false))
});
}
/**
* Add a selection option to a ButtonMenuSelectWidget
*
* @param {ButtonMenuSelectWidget} menuWidget
*/
addMenuOption = function(menuWidget) {
menuWidget.menu.addItems([new OO.ui.MenuOptionWidget({data: 'New option', label: 'New option'})])
}
/**
* Disable general interaction with model
* viewer for specific additional function
*
* @param {string} fnClass class to add to model-viewer
* @param {callback} viewCall callback function to add to model-viewer
* @return {Element} model-viewer element
*/
disableViewer = function(fnClass, viewCall) {
const previewMv = $('model-viewer')
if (viewCall) previewMv.one('click', viewCall)
if (fnClass) previewMv.addClass(fnClass)
previewMv[0].disableTap = true
previewMv[0].toggleAttribute('camera-controls', false)
return previewMv[0]
}
/**
* Enable general interaction with model
* viewer
*
* @return {Element} model-viewer element
*/
enableViewer = function() {
const previewMv = $('model-viewer')
previewMv.off('click', clickAddHotspot)
previewMv.off('click', cancelDeleteHotspot)
previewMv.removeClass('AddingHotspot DeletingHotspot')
previewMv[0].disableTap = false
previewMv[0].toggleAttribute('camera-controls', true)
return previewMv[0]
}
/**
* Use the model viewer methods to get image
* of current view and download
*
* @param {string} defName wiki page name to use as base file name
*/
downloadImage = function(defName) {
const imgName = defName.split('.')[0]
const mView = $('model-viewer')[0]
const dlA = document.createElement('a')
dlA.setAttribute('download',imgName + '.png')
const reader = new FileReader()
reader.addEventListener("load", () => {
dlA.setAttribute('href',reader.result)
dlA.click()
},{once: true})
mView.toBlob(null, null, true)
.then(imgBlob => {
reader.readAsDataURL(imgBlob)
})
}
//Initialize the menu and get required global objects
const [modelMenu, viewSelector] = buildPreviewMenu()