Create new views and annotation sets

Signed-off-by: Justin Georgi <justin.georgi@gmail.com>
This commit is contained in:
2024-11-19 08:53:02 -07:00
parent 0dd9aba2b6
commit e92b319a85
3 changed files with 156 additions and 66 deletions

View File

@@ -147,4 +147,14 @@ releaseAnnotation = function(e) {
$('#wpTextbox1').val(newText) $('#wpTextbox1').val(newText)
} }
grabHotspot = null grabHotspot = null
}
/**
* Change the currently selected annotation set
*
* @param {string} newSet name of annotation set to select
*/
selectAnnotationSet = function(newSet) {
$('model-viewer').attr('currentSet',newSet)
readMvconfig()
} }

View File

@@ -1,5 +1,3 @@
let currentSet = 'default'
/** /**
* Convert text in the preview text editor to js object * Convert text in the preview text editor to js object
* *
@@ -27,9 +25,9 @@ extractMvconfig = function() {
/** /**
* Reads the json string in the edit panel * Reads the json string in the edit panel
* and updates hotspot elements * and updates hotspot elements and menu settings
* *
* @return {bool} true on successful read and update * @return {bool|object} arrays of view and set names on successful read and update false on failure
*/ */
readMvconfig = function() { readMvconfig = function() {
let hotspotsObj = [] let hotspotsObj = []
@@ -63,6 +61,7 @@ readMvconfig = function() {
console.warn('Failed to read model config:' + err.message) console.warn('Failed to read model config:' + err.message)
return false return false
} }
const currentSet = $('model-viewer').attr('currentSet') || 'default'
if (currentSet != 'default' && mvconfig.annotationSets[currentSet]) { if (currentSet != 'default' && mvconfig.annotationSets[currentSet]) {
mvconfig.annotationSets[currentSet].forEach(hs => { mvconfig.annotationSets[currentSet].forEach(hs => {
createHotspot(hs, slotNum) createHotspot(hs, slotNum)
@@ -84,7 +83,10 @@ readMvconfig = function() {
mView.appendChild(hs) mView.appendChild(hs)
}) })
return true return {
set: Object.keys(mvconfig.annotationSets),
view: Object.keys(mvconfig.viewerConfig)
}
} }
/** /**
@@ -160,6 +162,40 @@ toggleCameraControl = function(view) {
return newControl return newControl
} }
/**
* Add a new annoation set object to annotatsionSets array
*
* @param {string} newSet name of new view config
*/
addAnnotationSet = function(newSet) {
const mView = $('model-viewer')[0]
let [currentText, mvconfig] = extractMvconfig()
mvconfig.annotationSets[newSet] = []
const textUpdate = currentText.replace(/(?<=<mvconfig>)([\S\s]*?)(?=<\/mvconfig>)/gm,`\n${JSON.stringify(mvconfig, null, 2)}\n`)
$('#wpTextbox1').val(textUpdate)
selectAnnotationSet(newSet)
}
/**
* Add a new set of view configurations to viewerConfig
*
* @param {string} newView name of new view config
*/
addViewConfig = function(newView) {
const mView = $('model-viewer')[0]
let [currentText, mvconfig] = extractMvconfig()
mvconfig.viewerConfig[newView] = { "camera-controls": true }
const textUpdate = currentText.replace(/(?<=<mvconfig>)([\S\s]*?)(?=<\/mvconfig>)/gm,`\n${JSON.stringify(mvconfig, null, 2)}\n`)
$('#wpTextbox1').val(textUpdate)
selectViewConfig(newView)
}
/**
* Switch the current model-viewer attributes to a different
* set of configurations in the mvconfig data
*
* @param {string} view the view name (viewerConfig object key)
*/
selectViewConfig = function(view) { selectViewConfig = function(view) {
const mView = $('model-viewer')[0] const mView = $('model-viewer')[0]
let [_, mvconfig] = extractMvconfig() let [_, mvconfig] = extractMvconfig()
@@ -242,28 +278,4 @@ writeCameraLimit = function(axis, limit) {
mView.setAttribute(`${limit}-camera-orbit`, oldOrbitVals.join(' ')) mView.setAttribute(`${limit}-camera-orbit`, oldOrbitVals.join(' '))
const textUpdate = currentText.replace(/(?<=<mvconfig>)([\S\s]*?)(?=<\/mvconfig>)/gm,`\n${JSON.stringify(mvconfig, null, 2)}\n`) const textUpdate = currentText.replace(/(?<=<mvconfig>)([\S\s]*?)(?=<\/mvconfig>)/gm,`\n${JSON.stringify(mvconfig, null, 2)}\n`)
$('#wpTextbox1').val(textUpdate) $('#wpTextbox1').val(textUpdate)
} }
/**
* Change the currently selected annotation set
*
* @param {string} newSet name of annotation set to select
*/
selectAnnotationSet = function(newSet) {
currentSet = newSet
readMvconfig()
}
/*
export default {
extractMvconfig,
readMvconfig,
writeMvconfig,
orb2degree,
toggleCameraControl,
selectViewConfig,
writeCameraOrbit,
writeCameraLimit,
selectAnnotationSet
}
*/

View File

@@ -20,14 +20,6 @@ buildPreviewMenu = function() {
addHS.on('click', readyAddHotspot) addHS.on('click', readyAddHotspot)
addHS.setDisabled(true) 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({ const deleteHS = new OO.ui.ButtonWidget({
icon: 'cancel', icon: 'cancel',
label: 'Delete annotation', label: 'Delete annotation',
@@ -36,7 +28,7 @@ buildPreviewMenu = function() {
deleteHS.on('click', readyDelHotspot) deleteHS.on('click', readyDelHotspot)
deleteHS.setDisabled(true) deleteHS.setDisabled(true)
const setOptions = ['default', ...Object.keys(origMetadata.annotationSets)] const setOptions = ['default', ...Object.keys(origMetadata.annotationSets), 'Add new']
let setOptionItems = [] let setOptionItems = []
setOptions.forEach(opt => { setOptions.forEach(opt => {
setOptionItems.push(new OO.ui.MenuOptionWidget({data: opt, label: opt})) setOptionItems.push(new OO.ui.MenuOptionWidget({data: opt, label: opt}))
@@ -53,25 +45,15 @@ buildPreviewMenu = function() {
$overlay: $('#bodyContent') $overlay: $('#bodyContent')
}) })
setSelectHS.getMenu().on( 'choose', selSet => { setSelectHS.getMenu().on( 'choose', selSet => {
selectAnnotationSet(selSet.data) onSetMenu(selSet.data)
}) })
setSelectHS.setDisabled(true) setSelectHS.setDisabled(true)
const hotspotButtons = new OO.ui.ButtonGroupWidget({ const hotspotButtons = new OO.ui.ButtonGroupWidget({
items: [ addHS, updateHS, deleteHS, setSelectHS ] items: [ addHS, deleteHS, setSelectHS ]
}) })
//View Edit Controls //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({ const setView = new OO.ui.ButtonWidget({
icon: 'camera', icon: 'camera',
label: 'Set Initial View', label: 'Set Initial View',
@@ -162,7 +144,7 @@ buildPreviewMenu = function() {
}) })
setLims.setDisabled(true) setLims.setDisabled(true)
const setViewConfig = [...Object.keys(origMetadata.viewerConfig)] const setViewConfig = [...Object.keys(origMetadata.viewerConfig), 'Add new']
let setViewItems = [] let setViewItems = []
setViewConfig.forEach(opt => { setViewConfig.forEach(opt => {
setViewItems.push(new OO.ui.MenuOptionWidget({data: opt, label: opt})) setViewItems.push(new OO.ui.MenuOptionWidget({data: opt, label: opt}))
@@ -179,26 +161,50 @@ buildPreviewMenu = function() {
$overlay: $('#bodyContent') $overlay: $('#bodyContent')
}) })
selectVC.getMenu().on( 'choose', selSet => { selectVC.getMenu().on( 'choose', selSet => {
selectViewConfig(selSet.data) onViewMenu(selSet.data)
}) })
selectVC.setDisabled(true) selectVC.setDisabled(true)
const cameraButtons = new OO.ui.ButtonGroupWidget({ const cameraButtons = new OO.ui.ButtonGroupWidget({
items: [ downloadViewerImage, setControl, setView, setLims, selectVC ] items: [ setControl, setView, setLims, selectVC ]
})
//General 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 updateViewer = new OO.ui.ButtonWidget({
icon: 'reload',
label: 'Update from text',
invisibleLabel: true
})
updateViewer.on('click', refreshConfigs)
updateViewer.setDisabled(true)
const generalButtons = new OO.ui.ButtonGroupWidget({
items: [ downloadViewerImage, updateViewer ]
}) })
//Main Menu //Main Menu
const modelMenu = new OO.ui.HorizontalLayout({ const modelMenu = new OO.ui.HorizontalLayout({
items: [ items: [
hotspotButtons, hotspotButtons,
cameraButtons cameraButtons,
generalButtons
], ],
id: 'edit-model-menu' id: 'edit-model-menu'
}) })
$('#wikiPreview').after(modelMenu.$element) $('#wikiPreview').after(modelMenu.$element)
return [modelMenu, selectVC] return [modelMenu, selectVC, setSelectHS]
} }
/** /**
@@ -211,15 +217,6 @@ enableMenu = function() {
}); });
} }
/**
* 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 * Disable general interaction with model
* viewer for specific additional function * viewer for specific additional function
@@ -278,5 +275,76 @@ downloadImage = function(defName) {
}) })
} }
/**
* Process view selection menu select event
*
* @param {string} selectData data associated with the selected menu label
*/
onViewMenu = function(selectData) {
if (selectData == 'Add new') {
const newSelectIdx = viewSelector.menu.items.length
const newView = `View${newSelectIdx}`
viewSelector.menu.addItems([new OO.ui.MenuOptionWidget({data: newView, label: newView})], newSelectIdx - 1)
addViewConfig(newView)
} else {
selectViewConfig(selectData)
}
}
/**
* Process annotation set menu select event
*
* @param {string} selectData data associated with the selected menu label
*/
onSetMenu = function(selectData) {
if (selectData == 'Add new') {
const newSelectIdx = setSelector.menu.items.length
const newSet = `Set${newSelectIdx - 1}`
setSelector.menu.addItems([new OO.ui.MenuOptionWidget({data: newSet, label: newSet})], newSelectIdx - 1)
addAnnotationSet(newSet)
} else {
selectAnnotationSet(selectData)
}
}
/**
* Update the available menu options in the given menu
* from an array
*
* @param {string} menuTYpe 'set'|'view' to determine which menu to update
* @param {array} newOpts array of strings containing new menu options
*/
updateMenu = function(menuType, newOpts) {
let menuObj
switch (menuType) {
case 'set':
menuObj = setSelector
menuOpts = ['default', ...newOpts, 'Add new']
break
case 'view':
menuObj = viewSelector
menuOpts = [...newOpts, 'Add new']
break
}
menuObj.menu.clearItems()
menuOpts.forEach(opt => {
menuObj.menu.addItems([new OO.ui.MenuOptionWidget({data: opt, label: opt})])
})
}
/**
* Refresh all viewer settings and menus from the edit input text
*/
refreshConfigs = function() {
const newLists = readMvconfig()
if (newLists) {
for (let lst in newLists) {
updateMenu(lst, newLists[lst])
}
}
}
//Initialize the menu and get required global objects //Initialize the menu and get required global objects
const [modelMenu, viewSelector] = buildPreviewMenu() const [modelMenu,
viewSelector,
setSelector] = buildPreviewMenu()