UI: expose gamma slider. Fix #190

This commit is contained in:
Matthieu Baumann
2024-11-04 11:21:38 +01:00
committed by Matthieu Baumann
parent 5562d74c0b
commit a6f2f1ed76
11 changed files with 99 additions and 50 deletions

View File

@@ -25,9 +25,9 @@
aladin.setImageLayer(survey2);
/*setTimeout(() => {
setTimeout(() => {
aladin.removeHiPSFromFavorites(survey3)
}, 10000);*/
}, 5000);
aladin.addColormap('mycmap', ["lightblue", "red", "violet", "lightgreen"])

View File

@@ -326,6 +326,7 @@ impl Layers {
.ok_or(err_layer_not_found)?;
self.layers.remove(id_layer);
al_core::log(&format!("remove layer {:?}", id_layer));
// Loop over all the meta for its longitude reversed property
// and set the camera to it if there is at least one
let longitude_reversed = self.meta.values().any(|meta| meta.longitude_reversed);
@@ -335,9 +336,13 @@ impl Layers {
// Check if the url is still used
let id_still_used = self.ids.values().any(|rem_id| rem_id == &id);
if id_still_used {
al_core::log("still used");
// Keep the resource whether it is a HiPS or a FITS
Ok(id_layer)
} else {
al_core::log("not needed");
// Resource not needed anymore
if let Some(hips) = self.hipses.remove(&id) {
// A HiPS has been found and removed

View File

@@ -424,12 +424,11 @@ export let Aladin = (function () {
}
// at least id or url is defined
let key = id || url;
let key = name || id || url;
// Merge what is already in the cache for that HiPS with new properties
// coming from the MOCServer
let hips = new HiPS(key, key, cachedSurvey)
self.hipsCache.append(key, hips);
self.hipsCache.append(key, cachedSurvey);
}
};
this._setupUI(options);
@@ -1443,9 +1442,11 @@ export let Aladin = (function () {
};
Aladin.prototype.removeUIByName = function(name) {
let elt = this.ui.find((elm) => elm.name === name)
if (elt) {
elt.remove()
let index = this.ui.findIndex((elm) => elm.name === name)
if (index >= 0) {
this.ui[index].remove();
this.ui.splice(index, 1);
}
};
@@ -1540,11 +1541,12 @@ export let Aladin = (function () {
maxOrder,
options
) {
let hips = new HiPS(id, url || id, { name, maxOrder, url, cooFrame, ...options })
let hipsOptions = { id, name, maxOrder, url, cooFrame, ...options };
let hips = new HiPS(id, url || id, hipsOptions)
if (this instanceof Aladin && !this.hipsCache.contains(id)) {
if (this instanceof Aladin && !this.hipsCache.contains(hips.name)) {
// Add it to the cache as soon as possible if we have a reference to the aladin object
this.hipsCache.append(hips.id, hips)
this.hipsCache.append(hips.name, hipsOptions)
}
return hips;
@@ -1591,11 +1593,14 @@ export let Aladin = (function () {
console.warn(survey + ' is among the list of HiPS currently in the view.');
}
let id;
if (typeof survey !== "string") {
survey = survey.id;
id = survey.name
} else {
id = survey
}
this.hipsCache.delete(survey);
this.hipsCache.delete(id);
}
/**
@@ -1847,9 +1852,9 @@ export let Aladin = (function () {
const idOrUrl = urlOrHiPSOrFITS;
// many cases here
// 1/ It has been already added to the cache
let cachedLayer = hipsCache.get(idOrUrl)
if (cachedLayer) {
imageLayer = cachedLayer
let cachedOptions = hipsCache.get(idOrUrl)
if (cachedOptions) {
imageLayer = A.HiPS(idOrUrl, cachedOptions);
} else {
// 2/ Not in the cache, then we create the hips from this url/id and
// go to the case 3
@@ -1860,18 +1865,20 @@ export let Aladin = (function () {
// 3/ It is an image survey.
imageLayer = urlOrHiPSOrFITS;
let cachedLayer = hipsCache.get(imageLayer.id)
if (!cachedLayer) {
hipsCache.append(imageLayer.id, imageLayer)
let cachedLayerOptions = hipsCache.get(imageLayer.name)
if (!cachedLayerOptions) {
hipsCache.append(imageLayer.name, imageLayer.options)
} else {
// first set the options of the cached layer to the one of the user
cachedLayer.setOptions(imageLayer.options)
// if it is in the cache we get it from the cache
imageLayer = cachedLayer
imageLayer = A.HiPS(imageLayer.id, cachedLayerOptions)
}
}
let imageLayerCopied = Object.assign(Object.create(Object.getPrototypeOf(imageLayer)), imageLayer)
imageLayerCopied.layer = layer;
return this.view.setOverlayImageLayer(imageLayer, layer);
return this.view.setOverlayImageLayer(imageLayerCopied, layer);
};
/**

View File

@@ -153,7 +153,7 @@ export let HiPSList = (function () {
{
creatorDid: "ivo://CDS/P/allWISE/color",
id: "P/allWISE/color",
name: "AllWISE color",
name: "AllWISE color Red (W4) , Green (W2) , Blue (W1) from raw Atlas Images",
maxOrder: 8,
tileSize: 512,
imgFormat: "jpeg",

View File

@@ -194,7 +194,7 @@ export let HiPS = (function () {
this.id = id;
this.options = options;
this.name = (options && options.name) || undefined;
this.name = (options && options.name) || id;
this.startUrl = options.startUrl;
this.slice = 0;
@@ -949,8 +949,8 @@ export let HiPS = (function () {
let self = this;
let hipsCache = this.view.aladin.hipsCache;
if (hipsCache.contains(self.id)) {
hipsCache.append(self.id, this)
if (hipsCache.contains(self.name)) {
hipsCache.append(self.name, this.options)
}
};

View File

@@ -36,8 +36,8 @@ export let HiPSCache = (function () {
/*
* key can be a CDS ID or an url. TODO could be an options.name too.
*/
HiPSCache.prototype.append = function (key, image) {
this.cache[key] = image;
HiPSCache.prototype.append = function (key, options) {
this.cache[key] = options;
ALEvent.HIPS_CACHE_UPDATED.dispatchedTo(document.body);
};

View File

@@ -1830,6 +1830,7 @@ export let View = (function () {
View.prototype.removeImageLayer = function (layer) {
// Get the survey to remove to dissociate it from the view
let imageLayer = this.imageLayers.get(layer);
if (imageLayer === undefined) {
// there is nothing to remove
return;

View File

@@ -63,26 +63,31 @@ export class HiPSBrowserBox extends Box {
self._filterHiPSList({})
});
const _parseHiPS = (e) => {
const value = e.target.value;
let image;
let image, name;
// A user can put an url
try {
image = new URL(value).href;
name = image;
} catch (e) {
// Or he can select a HiPS from the list given
const hips = HiPSBrowserBox.HiPSList[value];
if (hips) {
image = hips.ID || hips.hips_service_url;
name = hips.obs_title || hips.ID;
} else {
// Finally if not found, interpret the input text value as the HiPS (e.g. ID)
image = value;
name = value;
}
}
if (image) {
self._addHiPS(image)
self._addHiPS(image, name)
self.searchDropdown.update({title: value});
}
};
@@ -116,6 +121,11 @@ export class HiPSBrowserBox extends Box {
searchDropdown.removeClass('aladin-valid')
searchDropdown.removeClass('aladin-not-valid')
},
change(e) {
e.stopPropagation();
e.preventDefault()
_parseHiPS(e)
}
},
});
@@ -273,10 +283,11 @@ export class HiPSBrowserBox extends Box {
};
}
_addHiPS(id) {
console.log("add hips", id)
_addHiPS(id, name) {
let self = this;
let hips = A.imageHiPS(id, {
name,
successCallback: (hips) => {
self.searchDropdown.removeClass('aladin-not-valid');
self.searchDropdown.addClass('aladin-valid');
@@ -288,6 +299,8 @@ export class HiPSBrowserBox extends Box {
}
})
self.aladin.removeUIByName("cube_displayer" + hips.layer)
if (!hips.cubeDepth)
return;
@@ -321,10 +334,10 @@ export class HiPSBrowserBox extends Box {
hips.setSliceNumber(idxSlice)
cubeDisplayer.update({position: cubeDisplayer.position, content: Layout.horizontal([prevBtn, nextBtn, slicer, toStr(idxSlice + 1, true) + '/' + toStr(numSlices, false)])})
};
let slicer = Input.slider({
label: "Slice",
name: "cube slicer",
name: "cube_slicer" + hips.layer,
ticks: [idxSlice],
tooltip: {content: (idxSlice + 1) + '/' + numSlices, position: {direction: 'bottom'}},
min: 0,
@@ -370,7 +383,7 @@ export class HiPSBrowserBox extends Box {
let cubeDisplayer = A.box({
close: true,
name: 'player' + hips.name,
name: "cube_displayer" + hips.layer,
header: {
title: 'Player for: ' + hips.name,
draggable: true,
@@ -378,6 +391,7 @@ export class HiPSBrowserBox extends Box {
content: Layout.horizontal([prevBtn, nextBtn, slicer, toStr(idxSlice + 1, true) + '/' + toStr(numSlices, false)]),
position: {anchor: 'center top'},
});
self.aladin.addUI(cubeDisplayer)
},
errorCallback: (e) => {

View File

@@ -28,7 +28,6 @@
*
*****************************************************************************/
import { Form } from "../Widgets/Form.js";
import { ColorCfg } from "../../ColorCfg.js";
import { Box } from "../Widgets/Box.js";
import { ALEvent } from "../../events/ALEvent.js";
import opacityIconUrl from '../../../../assets/icons/opacity.svg';
@@ -165,6 +164,21 @@ import { ColorCfg } from "../../ColorCfg.js";
slider.update({value: contrast, tooltip: {content: `${contrast.toFixed(3)}`, position: {direction: 'right'}}})
}
},
{
label: 'gamma:',
tooltip: {content: 'gamma', position: {direction: 'right'}},
name: 'gamma',
type: 'range',
min: 0.1,
max: 10.0,
ticks: [1.0],
value: 1.0,
change: (e, slider) => {
const gamma = +e.target.value
self.options.layer.setGamma(gamma)
slider.update({value: gamma, tooltip: {content: `${gamma.toFixed(3)}`, position: {direction: 'right'}}})
}
},
]
});
let pixelSettingsContent = new Form({
@@ -274,6 +288,7 @@ import { ColorCfg } from "../../ColorCfg.js";
this.opacitySettingsContent.set('opacity', hips.getOpacity());
this.luminositySettingsContent.set('brightness', colorCfg.getBrightness());
this.luminositySettingsContent.set('contrast', colorCfg.getContrast());
this.luminositySettingsContent.set('gamma', colorCfg.getGamma());
this.luminositySettingsContent.set('saturation', colorCfg.getSaturation());
}
@@ -305,6 +320,7 @@ import { ColorCfg } from "../../ColorCfg.js";
this.opacitySettingsContent.set('opacity', hips.getOpacity());
this.luminositySettingsContent.set('brightness', colorCfg.getBrightness());
this.luminositySettingsContent.set('contrast', colorCfg.getContrast());
this.luminositySettingsContent.set('gamma', colorCfg.getGamma());
this.luminositySettingsContent.set('saturation', colorCfg.getSaturation());
}
});

View File

@@ -721,11 +721,14 @@ export class OverlayStackBox extends Box {
self.cachedHiPS = {};
for (var key in hipsCache.cache) {
let HiPS = hipsCache.cache[key];
let HiPSOptions = hipsCache.cache[key];
if (HiPS.name) {
self.cachedHiPS[HiPS.name.toString()] = HiPS;
}
/*if (HiPSOptions.name) {
self.cachedHiPS[HiPSOptions.name.toString()] = HiPSOptions;
} else {
self.cachedHiPS[key] = HiPSOptions;
}*/
self.cachedHiPS[key] = HiPSOptions;
}
// Update the options of the selector
@@ -739,7 +742,10 @@ export class OverlayStackBox extends Box {
let currentHiPS = hips.HiPSSelector.options.value
let favoritesCopy = [...favorites];
if (!(currentHiPS in favoritesCopy)) {
// add the current hips to the selector as well, even if it has been manually
// removed from the HiPSList
if (favoritesCopy.indexOf(currentHiPS) < 0) {
favoritesCopy.push(currentHiPS)
}
@@ -935,25 +941,25 @@ export class OverlayStackBox extends Box {
hipsOptions.sort()
for (const layer of layers) {
let HiPSSelector = Input.select({
value: layer.name,
value: layer.name || layer.id,
options: hipsOptions,
title: layer.name,
change: (e) => {
let name = e.target.value;
// search for the
let HiPS = self.cachedHiPS[name];
let HiPSOptions = self.cachedHiPS[name];
let image;
/*let image;
if (HiPS instanceof Image) {
image = HiPS;
} else {
// HiPS
image = HiPS.id || HiPS.url || undefined;
}
}*/
let hips = A.HiPS(HiPSOptions.id || HiPSOptions.url, HiPSOptions);
self.aladin.setOverlayImageLayer(image, layer.layer);
self.aladin.setOverlayImageLayer(hips, layer.layer);
}
});
@@ -963,9 +969,10 @@ export class OverlayStackBox extends Box {
disable: layer.layer === "base",
tooltip: { content: "Remove", position: { direction: "top" } },
action(e) {
console.log(layer)
self.aladin.removeImageLayer(layer.layer);
// remove HiPS cube player if any
self.aladin.removeUIByName("player" + layer.name)
self.aladin.removeUIByName("cube_displayer" + layer.layer)
},
});
@@ -1000,11 +1007,9 @@ export class OverlayStackBox extends Box {
});
let settingsBox = new HiPSSettingsBox(self.aladin);
settingsBox.update({ layer });
settingsBox._hide();
let settingsBtn = new TogglerActionButton({
icon: { url: settingsIconUrl, monochrome: true },
size: "small",

View File

@@ -74,6 +74,7 @@ export class DOMElement {
if (target && target.children) {
index = Array.prototype.indexOf.call(target.children, el);
}
console.log("remove", el)
el.remove()
return {target, position: index};