mirror of
https://github.com/cds-astro/aladin-lite.git
synced 2026-06-12 11:01:37 -07:00
toolbar functional
This commit is contained in:
committed by
Matthieu Baumann
parent
45129708db
commit
8b645824c7
@@ -12,6 +12,14 @@
|
||||
* [fix] layer opacity restored when switching from not visible to visible <https://github.com/cds-astro/aladin-lite/issues/332>
|
||||
* [feat] dark/light mode for the interface
|
||||
* [fix] polylines shapes size not consistent w.r.t to div size <https://github.com/cds-astro/aladin-lite/issues/331>
|
||||
* [feat] 'stackChanged' new event informing when a layer has been added, removed or swapped.
|
||||
* [ui] a new HiPS browser window to search and find HiPS among the HiPS worldwide network.
|
||||
* [ui] new settings panel for Catalog overlays to change the size, color or shapes of sources
|
||||
* [ui] possibility to swap 2 layers. Functional but not definitive, it would be better to allow drag and drop amond the layers.
|
||||
* [fix] fix local HiPS loading.
|
||||
* [ui] WIP. A toolbar object
|
||||
* [fix] fix selection of footprints. In the future allow a skew selection mode and a additive selection shortkey.
|
||||
* [fix] inertia bug when zooming in/out
|
||||
|
||||
### 3.7.0-beta
|
||||
|
||||
|
||||
@@ -4,15 +4,16 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="aladin-lite-div" style="width: 512px; height: 512px"></div>
|
||||
<div id="toolbar"></div>
|
||||
<div id="aladin-lite-div" style="width: 512px; height: 512px">
|
||||
<div id="toolbar"></div>
|
||||
</div>
|
||||
|
||||
<script type="module">
|
||||
import showUrl from './../assets/icons/show.svg';
|
||||
import A from '../src/js/A.js';
|
||||
let aladin;
|
||||
A.init.then(() => {
|
||||
aladin = A.aladin('#aladin-lite-div', {toolbar: {divSelector: '#toolbar', vertical: false}, samp: true, survey: "data/hips/PanSTARRS_DR1_color-z-zg-g", fov:2.0, target: "22 35 58.39 +33 57 57.8", showSettingsControl: true, log: false});
|
||||
aladin = A.aladin('#aladin-lite-div', {toolbar: {divSelector: '#toolbar'}, samp: true, survey: "data/hips/PanSTARRS_DR1_color-z-zg-g", fov:2.0, target: "22 35 58.39 +33 57 57.8", showSettingsControl: true, log: false});
|
||||
aladin.setProjection('AIT');
|
||||
let cfht = aladin.createImageSurvey("CFHT", "CFHT MegaCam u+g+r", "./data/hips/CFHT", "equatorial", 10, {imgFormat: 'png'});
|
||||
let jwst1 = aladin.createImageSurvey("CDS/P/JWST/Stephans-Quintet/NIRCam+MIRI", "JWST NIRCam+MIRI", "data/hips/JWST_NIRCam_MIRI", null, null, {imgFormat: 'png'});
|
||||
|
||||
@@ -68,8 +68,8 @@
|
||||
console.log(pos)
|
||||
});
|
||||
|
||||
aladin.on('layerChanged', function(imageLayer, layer, state){
|
||||
console.log(imageLayer, layer, state)
|
||||
aladin.on('stackChanged', function(state) {
|
||||
console.log(state)
|
||||
});
|
||||
|
||||
cat.sources[0].actionClicked();
|
||||
|
||||
+4353
-4353
File diff suppressed because it is too large
Load Diff
+56
-6
@@ -284,11 +284,22 @@
|
||||
|
||||
.aladin-anchor-top{top:0}
|
||||
.aladin-anchor-middle{top:50%; transform: translate(0, -50%);/*half of the .box height*/}
|
||||
.aladin-anchor-bottom{bottom:0}
|
||||
.aladin-anchor-bottom{
|
||||
bottom:0;
|
||||
|
||||
.aladin-anchor-left{left:0;}
|
||||
.aladin-anchor-center{left:50%; transform: translate(-50%, 0%);/*half of the .box width*/}
|
||||
.aladin-anchor-right{right:0;}
|
||||
}
|
||||
|
||||
.aladin-anchor-left {
|
||||
left: 0;
|
||||
|
||||
}
|
||||
.aladin-anchor-center{
|
||||
left:50%;
|
||||
transform: translate(-50%, 0%);/*half of the .box width*/
|
||||
}
|
||||
.aladin-anchor-right{
|
||||
right:0;
|
||||
}
|
||||
|
||||
.aladin-anchor-middle.aladin-anchor-center {
|
||||
transform: translate(-50%, -50%);
|
||||
@@ -861,6 +872,22 @@
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.aladin-context-menu.left {
|
||||
left: 0;
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
.aladin-context-menu.top{
|
||||
top: 0;
|
||||
left: 0;
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
.aladin-context-menu.bottom {
|
||||
top: 100%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.aladin-context-menu .aladin-context-sub-menu.left {
|
||||
left: 0;
|
||||
transform: translateX(-100%);
|
||||
@@ -885,6 +912,29 @@
|
||||
transform: translate(-100%, -100%);
|
||||
}
|
||||
|
||||
.aladin-box.left {
|
||||
left: 0;
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
.aladin-box.right {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.aladin-box.bottom {
|
||||
top: 100%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.aladin-box.top {
|
||||
top: 0;
|
||||
left: 0;
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
.aladin-box.left.top {
|
||||
transform: translate(-100%, -100%);
|
||||
}
|
||||
|
||||
.aladin-reticle {
|
||||
position: absolute;
|
||||
@@ -1297,8 +1347,8 @@ otherwise it fits its content options. If those are too big the select can go ou
|
||||
|
||||
.aladin-widgets-toolbar {
|
||||
position: absolute;
|
||||
top: 3rem;
|
||||
left: .2rem;
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 5rem;
|
||||
}
|
||||
|
||||
.aladin-widgets-toolbar > * {
|
||||
|
||||
+48
-15
@@ -155,6 +155,10 @@ import { Polyline } from "./shapes/Polyline";
|
||||
* @property {Object} [selector] - More options for the the selector.
|
||||
* @property {string} [selector.color] - Color of the selector, defaults to the color of the reticle. Can be a hex color or a function returning a hex color.
|
||||
* @property {number} [selector.lineWidth=2] - Width of the selector line.
|
||||
* @property {Object} [toolbar] - Toolbar object
|
||||
* @property {string} [toolbar.divSelector="null"] - A selector to put the toolbar in. By default the toolbar will be inserted in the Aladin Lite view.
|
||||
* @property {string} [toolbar.position="topleft"] - Can be 'topleft', 'topright', 'bottomleft', 'bottomright'. Default to 'topleft'
|
||||
* @property {boolean} [toolbar.vertical=true] - Is the toolbar horizontal or not. Default to vertical
|
||||
*
|
||||
* @example
|
||||
* let aladin = A.aladin({
|
||||
@@ -253,7 +257,7 @@ import { Polyline } from "./shapes/Polyline";
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {('select'|'objectsSelected'|'objectClicked'|'objectHovered'|'objectHoveredStop'|'footprintClicked'|'footprintHovered'|'positionChanged'|'zoomChanged'|'rotationChanged'|'click'|'rightClickMove'|'mouseMove'|'wheelTriggered'|'fullScreenToggled'|'cooFrameChanged'|'resizeChanged'|'projectionChanged'|'layerChanged')} EventListener
|
||||
* @typedef {('select'|'objectsSelected'|'objectClicked'|'objectHovered'|'objectHoveredStop'|'footprintClicked'|'footprintHovered'|'positionChanged'|'zoomChanged'|'rotationChanged'|'click'|'rightClickMove'|'mouseMove'|'wheelTriggered'|'fullScreenToggled'|'cooFrameChanged'|'resizeChanged'|'projectionChanged'|'stackChanged')} EventListener
|
||||
*
|
||||
* <ul>
|
||||
* <li>'positionChanged' is triggered when the view position has been changed. It gives the user the new center position of the view in ICRS frame. See {@link positionChangedParam}</li>
|
||||
@@ -261,6 +265,7 @@ import { Polyline } from "./shapes/Polyline";
|
||||
* <li>'mouseMove' is triggered when the mouse move over the view. It gives the the user the new position of the cursor in the current frame. See {@link mouseMoveParam}</li>
|
||||
* <li>'wheelTriggered' allows to redefine the zooming. Listening for it will disable the default zooming heuristic.</li>
|
||||
* <li>'objectsSelected', 'objectClicked', 'objectHovered', 'objectHoveredStop', 'footprintClicked', 'footprintHovered' are triggered when a catalog source/footprint has been clicked, hovered, ...
|
||||
* <li>'stackChanged' is triggered when a layer has been added, removed or swapped. The callback passed is an object having fields. The layer object that has been added/removed (or the swapped layers) and a flag that tells you if it has been 'added', 'removed' or 'swapped'.
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
@@ -300,14 +305,32 @@ export let Aladin = (function () {
|
||||
|
||||
const self = this;
|
||||
|
||||
ALEvent.HIPS_LAYER_ADDED.listenedBy(aladinDiv, (imageLayer) => {
|
||||
this.callbacksByEventName["layerChanged"] &&
|
||||
this.callbacksByEventName["layerChanged"](imageLayer.detail.layer, imageLayer.detail.layer.layer, "ADDED");
|
||||
ALEvent.LAYER_ADDED.listenedBy(aladinDiv, (e) => {
|
||||
const {layer} = e.detail;
|
||||
let callback = this.callbacksByEventName["stackChanged"];
|
||||
callback && callback({
|
||||
change: 'added',
|
||||
layer,
|
||||
});
|
||||
});
|
||||
|
||||
ALEvent.HIPS_LAYER_REMOVED.listenedBy(aladinDiv, (imageLayer) => {
|
||||
this.callbacksByEventName["layerChanged"] &&
|
||||
this.callbacksByEventName["layerChanged"](imageLayer.detail.layer, imageLayer.detail.layer.layer, "REMOVED");
|
||||
ALEvent.LAYER_REMOVED.listenedBy(aladinDiv, (e) => {
|
||||
const {layer} = e.detail;
|
||||
let callback = this.callbacksByEventName["stackChanged"];
|
||||
callback && callback({
|
||||
change: 'removed',
|
||||
layer
|
||||
});
|
||||
});
|
||||
|
||||
ALEvent.LAYER_SWAPPED.listenedBy(aladinDiv, (e) => {
|
||||
const {layer1, layer2} = e.detail;
|
||||
let callback = this.callbacksByEventName["stackChanged"];
|
||||
callback && callback({
|
||||
change: 'swapped',
|
||||
layer1,
|
||||
layer2
|
||||
});
|
||||
});
|
||||
|
||||
// if not options was set, try to retrieve them from the query string
|
||||
@@ -576,9 +599,9 @@ export let Aladin = (function () {
|
||||
if (!(toolbarDivSelector instanceof HTMLElement)) {
|
||||
toolbarDivSelector = document.querySelector(toolbarDivSelector);
|
||||
}
|
||||
this.toolbar = new Toolbar([], {
|
||||
this.toolbar = new Toolbar({
|
||||
classList: ["aladin-widgets-toolbar"],
|
||||
vertical: options && options.toolbar.vertical
|
||||
...options.toolbar
|
||||
}, toolbarDivSelector)
|
||||
|
||||
// Status bar
|
||||
@@ -773,8 +796,9 @@ export let Aladin = (function () {
|
||||
pixelateCanvas: true,
|
||||
manualSelection: false,
|
||||
toolbar: {
|
||||
vertical: true,
|
||||
divSelector: null,
|
||||
vertical: true,
|
||||
position: 'topleft'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1122,7 +1146,6 @@ export let Aladin = (function () {
|
||||
|
||||
return projName;
|
||||
};
|
||||
``;
|
||||
|
||||
/**
|
||||
* Returns the current coordinate system: possible values are 'ICRS', 'ICRSd', and 'Galactic' .
|
||||
@@ -1139,6 +1162,16 @@ export let Aladin = (function () {
|
||||
return this.view.cooFrame.label;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a reference to the Aladin Lite toolbar object. User can append, remove DOMElement/widgets to it
|
||||
*
|
||||
* @memberof Aladin
|
||||
* @returns {Toolbar}
|
||||
*/
|
||||
Aladin.prototype.getToolbar = function () {
|
||||
return this.toolbar;
|
||||
};
|
||||
|
||||
/**
|
||||
* Moves the Aladin instance to the specified astronomical object.
|
||||
*
|
||||
@@ -2248,7 +2281,7 @@ export let Aladin = (function () {
|
||||
"cooFrameChanged",
|
||||
"resizeChanged",
|
||||
"projectionChanged",
|
||||
"layerChanged"
|
||||
"stackChanged"
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -2306,9 +2339,9 @@ export let Aladin = (function () {
|
||||
console.log("positionChanged", ra, dec)
|
||||
})
|
||||
|
||||
aladin.on("layerChanged", (layer, layerName, state) => {
|
||||
console.log("layerChanged", layer, layerName, state)
|
||||
})
|
||||
aladin.on('stackChanged', function(state) {
|
||||
console.log(state)
|
||||
});
|
||||
*/
|
||||
Aladin.prototype.on = function (what, myFunction) {
|
||||
if (Aladin.AVAILABLE_CALLBACKS.indexOf(what) < 0) {
|
||||
|
||||
+1
-1
@@ -869,7 +869,7 @@ export let HiPS = (function () {
|
||||
imgFormat: this.imgFormat,
|
||||
});
|
||||
// once the meta have been well parsed, we can set the meta
|
||||
ALEvent.HIPS_LAYER_CHANGED.dispatchedTo(this.view.aladinDiv, {
|
||||
ALEvent.LAYER_CHANGED.dispatchedTo(this.view.aladinDiv, {
|
||||
layer: this,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -557,64 +557,6 @@ export class SpectraDisplayer extends DOMElement {
|
||||
|
||||
this.view.catalogCanvas.dispatchEvent(wheelEvent);
|
||||
});
|
||||
|
||||
/*
|
||||
const updateSelectorList = () => {
|
||||
let options = [];
|
||||
for (const hipsName of this.hips3DList.keys()) {
|
||||
options.push(hipsName)
|
||||
}
|
||||
|
||||
this.selector.update({options})
|
||||
};
|
||||
|
||||
ALEvent.HIPS_LAYER_ADDED.listenedBy(
|
||||
this.view.aladin.aladinDiv,
|
||||
function (e) {
|
||||
let hips = e.detail.layer;
|
||||
|
||||
if (hips.dataproductType === "spectral-cube") {
|
||||
self.hips3DList.set(hips.name, hips);
|
||||
|
||||
updateSelectorList()
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
ALEvent.HIPS_LAYER_SWAP.listenedBy(
|
||||
this.view.aladin.aladinDiv,
|
||||
function (e) {
|
||||
let firstHiPS = e.detail.firstLayer;
|
||||
let secondHiPS = e.detail.secondLayer;
|
||||
|
||||
self.hips3DList.delete(firstHiPS.name);
|
||||
|
||||
if (secondHiPS.dataproductType === "spectral-cube") {
|
||||
self.hips3DList.set(secondHiPS.name, secondHiPS);
|
||||
}
|
||||
|
||||
updateSelectorList()
|
||||
}
|
||||
);
|
||||
|
||||
ALEvent.HIPS_LAYER_REMOVED.listenedBy(
|
||||
this.view.aladin.aladinDiv,
|
||||
function (e) {
|
||||
let hips = e.detail.layer;
|
||||
self.hips3DList.delete(hips.name);
|
||||
|
||||
if (hips === this.hips) {
|
||||
// the hips pointed by the tool has been removed
|
||||
self.attachHiPS3D(null);
|
||||
}
|
||||
|
||||
if (self.hips3DList.size === 0) {
|
||||
self.hide()
|
||||
}
|
||||
|
||||
updateSelectorList()
|
||||
}
|
||||
);*/
|
||||
}
|
||||
|
||||
_hide() {
|
||||
|
||||
+17
-19
@@ -1786,7 +1786,7 @@ export let View = (function () {
|
||||
|
||||
if (alreadyPresentImageLayer) {
|
||||
if (alreadyPresentImageLayer.added === true) {
|
||||
ALEvent.HIPS_LAYER_REMOVED.dispatchedTo(this.aladinDiv, { layer: alreadyPresentImageLayer });
|
||||
ALEvent.LAYER_REMOVED.dispatchedTo(this.aladinDiv, { layer: alreadyPresentImageLayer });
|
||||
}
|
||||
|
||||
alreadyPresentImageLayer.added = false;
|
||||
@@ -1811,7 +1811,7 @@ export let View = (function () {
|
||||
// select the layer if he is on top
|
||||
this.selectLayer(layer);
|
||||
|
||||
ALEvent.HIPS_LAYER_ADDED.dispatchedTo(this.aladinDiv, { layer: imageLayer });
|
||||
ALEvent.LAYER_ADDED.dispatchedTo(this.aladinDiv, { layer: imageLayer });
|
||||
}
|
||||
|
||||
View.prototype.addImageLayer = function (imageLayer, layer) {
|
||||
@@ -1869,20 +1869,26 @@ export let View = (function () {
|
||||
})
|
||||
}
|
||||
|
||||
View.prototype.swapLayers = function(firstLayer, secondLayer) {
|
||||
View.prototype.swapLayers = function(layer1, layer2) {
|
||||
// Throw an exception if either the first or the second layers are not in the stack
|
||||
this.wasm.swapLayers(firstLayer, secondLayer);
|
||||
this.wasm.swapLayers(layer1, layer2);
|
||||
|
||||
// Swap in overlaylayers
|
||||
const idxFirstLayer = this.overlayLayers.indexOf(firstLayer);
|
||||
const idxSecondLayer = this.overlayLayers.indexOf(secondLayer);
|
||||
const i = this.overlayLayers.indexOf(layer1);
|
||||
const j = this.overlayLayers.indexOf(layer2);
|
||||
|
||||
const tmp = this.overlayLayers[idxFirstLayer];
|
||||
this.overlayLayers[idxFirstLayer] = this.overlayLayers[idxSecondLayer];
|
||||
this.overlayLayers[idxSecondLayer] = tmp;
|
||||
const tmp = this.overlayLayers[i];
|
||||
this.overlayLayers[i] = this.overlayLayers[j];
|
||||
this.overlayLayers[j] = tmp;
|
||||
|
||||
// Tell the layer hierarchy has changed
|
||||
ALEvent.HIPS_LAYER_SWAP.dispatchedTo(this.aladinDiv, { firstLayer: firstLayer, secondLayer: secondLayer });
|
||||
ALEvent.LAYER_SWAPPED.dispatchedTo(
|
||||
this.aladinDiv,
|
||||
{
|
||||
layer1: this.imageLayers.get(layer1),
|
||||
layer2: this.imageLayers.get(layer2)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
View.prototype.removeImageLayer = function (layer) {
|
||||
@@ -1918,15 +1924,7 @@ export let View = (function () {
|
||||
this.selectLayer(this.overlayLayers[this.overlayLayers.length - 1]);
|
||||
}
|
||||
|
||||
ALEvent.HIPS_LAYER_REMOVED.dispatchedTo(this.aladinDiv, { layer: imageLayer });
|
||||
|
||||
// check if there are no more surveys
|
||||
/*const noMoreLayersToWaitFor = this.promises.length === 0;
|
||||
if (noMoreLayersToWaitFor && this.empty) {
|
||||
// no promises to launch!
|
||||
const dssId = Aladin.DEFAULT_OPTIONS.survey;
|
||||
this.aladin.setBaseImageLayer(dssId);
|
||||
}*/
|
||||
ALEvent.LAYER_REMOVED.dispatchedTo(this.aladinDiv, { layer: imageLayer });
|
||||
};
|
||||
|
||||
View.prototype.contains = function(survey) {
|
||||
|
||||
@@ -51,17 +51,14 @@ export class ALEvent {
|
||||
static POSITION_CHANGED = new ALEvent("AL:position.changed");
|
||||
static ZOOM_CHANGED = new ALEvent("AL:zoom.changed");
|
||||
|
||||
static HIPS_LAYER_ADDED = new ALEvent("AL:HiPSLayer.added");
|
||||
static HIPS_LAYER_REMOVED = new ALEvent("AL:HiPSLayer.removed");
|
||||
static HIPS_LAYER_RENAMED = new ALEvent("AL:HiPSLayer.renamed");
|
||||
static HIPS_LAYER_SWAP = new ALEvent("AL:HiPSLayer.swap");
|
||||
static HIPS_LAYER_CHANGED = new ALEvent("AL:HiPSLayer.changed");
|
||||
static LAYER_ADDED = new ALEvent("AL:Layer.added");
|
||||
static LAYER_REMOVED = new ALEvent("AL:Layer.removed");
|
||||
static LAYER_SWAPPED = new ALEvent("AL:Layer.swapped");
|
||||
static LAYER_CHANGED = new ALEvent("AL:Layer.changed");
|
||||
|
||||
static HIPS_CACHE_UPDATED = new ALEvent("AL:HiPSCache.updated");
|
||||
|
||||
static FAVORITE_HIPS_LIST_UPDATED = new ALEvent("AL:HiPSFavorites.updated");
|
||||
|
||||
|
||||
static GRAPHIC_OVERLAY_LAYER_ADDED = new ALEvent("AL:GraphicOverlayLayer.added");
|
||||
static GRAPHIC_OVERLAY_LAYER_REMOVED = new ALEvent("AL:GraphicOverlayLayer.removed");
|
||||
|
||||
|
||||
@@ -278,12 +278,8 @@ export class HiPSBrowserBox extends Box {
|
||||
position: { direction: "top" },
|
||||
},
|
||||
toggled: false,
|
||||
widget: {
|
||||
position: {
|
||||
anchor: 'right center'
|
||||
},
|
||||
obj: filterBox,
|
||||
}
|
||||
openPosition: 'right center',
|
||||
widget: filterBox,
|
||||
});
|
||||
|
||||
let filterNumberElt = document.createElement("div");
|
||||
|
||||
@@ -331,9 +331,7 @@ import { WidgetTogglerButton } from "../Button/Toggler.js";
|
||||
enable: (o) => {
|
||||
spectraDisplayer.attachHiPS3D(options.layer)
|
||||
},
|
||||
widget: {
|
||||
obj: spectraDisplayer
|
||||
}
|
||||
widget: spectraDisplayer
|
||||
});
|
||||
|
||||
self.update({content: Layout.vertical([[self.selector, self.spectraBtn], self.opacitySettingsContent])})
|
||||
@@ -346,9 +344,7 @@ import { WidgetTogglerButton } from "../Button/Toggler.js";
|
||||
}
|
||||
|
||||
_addListeners() {
|
||||
let self = this;
|
||||
|
||||
ALEvent.HIPS_LAYER_CHANGED.listenedBy(this.aladin.aladinDiv, (e) => {
|
||||
ALEvent.LAYER_CHANGED.listenedBy(this.aladin.aladinDiv, (e) => {
|
||||
const hips = e.detail.layer;
|
||||
let selectedLayer = this.options.layer;
|
||||
|
||||
|
||||
+23
-16
@@ -155,6 +155,7 @@ export class OverlayStackBox extends Box {
|
||||
size: "small",
|
||||
monochrome: true,
|
||||
},
|
||||
openDirection: 'right',
|
||||
tooltip: {
|
||||
content: "A catalog, MOC or footprint",
|
||||
position: { direction: "top" },
|
||||
@@ -485,6 +486,7 @@ export class OverlayStackBox extends Box {
|
||||
size: "small",
|
||||
monochrome: true,
|
||||
},
|
||||
openDirection: 'right',
|
||||
ctxMenu: [
|
||||
{
|
||||
label: {
|
||||
@@ -669,25 +671,25 @@ export class OverlayStackBox extends Box {
|
||||
}
|
||||
);
|
||||
|
||||
ALEvent.HIPS_LAYER_ADDED.listenedBy(
|
||||
ALEvent.LAYER_ADDED.listenedBy(
|
||||
this.aladin.aladinDiv,
|
||||
function (e) {
|
||||
updateOverlayList();
|
||||
}
|
||||
);
|
||||
|
||||
ALEvent.HIPS_LAYER_SWAP.listenedBy(this.aladin.aladinDiv, function (e) {
|
||||
ALEvent.LAYER_SWAPPED.listenedBy(this.aladin.aladinDiv, function (e) {
|
||||
updateOverlayList();
|
||||
});
|
||||
|
||||
ALEvent.HIPS_LAYER_REMOVED.listenedBy(
|
||||
ALEvent.LAYER_REMOVED.listenedBy(
|
||||
this.aladin.aladinDiv,
|
||||
function (e) {
|
||||
updateOverlayList();
|
||||
}
|
||||
);
|
||||
|
||||
ALEvent.HIPS_LAYER_CHANGED.listenedBy(
|
||||
ALEvent.LAYER_CHANGED.listenedBy(
|
||||
this.aladin.aladinDiv,
|
||||
function (e) {
|
||||
const hips = e.detail.layer;
|
||||
@@ -736,7 +738,20 @@ export class OverlayStackBox extends Box {
|
||||
super._hide();
|
||||
}
|
||||
|
||||
delete() {
|
||||
if (!this.ui) {
|
||||
return
|
||||
}
|
||||
|
||||
for (let component of Object.values(this.ui)) {
|
||||
for (let elt of Object.values(component)) {
|
||||
elt.remove && elt.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
createLayout() {
|
||||
this.delete()
|
||||
this.ui = {};
|
||||
|
||||
let layout = [[this.addOverlayBtn, " Overlays"]];
|
||||
@@ -898,12 +913,8 @@ export class OverlayStackBox extends Box {
|
||||
if (spectraDisplayer)
|
||||
spectraDisplayer.attachHiPS3D(options.layer)
|
||||
},
|
||||
widget: {
|
||||
obj: catSettingsBox,
|
||||
position: {
|
||||
direction: "right",
|
||||
}
|
||||
}
|
||||
widget: catSettingsBox,
|
||||
openDirection: "right"
|
||||
});
|
||||
|
||||
optBtn.push(catSettingsBtn);
|
||||
@@ -1057,12 +1068,8 @@ export class OverlayStackBox extends Box {
|
||||
|
||||
settingsBox.update({ layer: hips });
|
||||
},
|
||||
widget: {
|
||||
obj: settingsBox,
|
||||
position: {
|
||||
direction: "right",
|
||||
}
|
||||
}
|
||||
widget: settingsBox,
|
||||
openDirection: "right",
|
||||
});
|
||||
|
||||
let loadMOCBtn = ActionButton.BUTTONS(self.aladin)
|
||||
|
||||
@@ -122,10 +122,7 @@ export class CtxMenuActionButtonOpener extends WidgetTogglerButton {
|
||||
})
|
||||
};
|
||||
super({
|
||||
widget: {
|
||||
obj: aladin.contextMenu,
|
||||
position: {direction: (options && options.openDirection) || 'right'}
|
||||
},
|
||||
widget: aladin.contextMenu,
|
||||
enable(e) {
|
||||
enableTooltips()
|
||||
// If it was hidden then reopen it
|
||||
@@ -153,9 +150,8 @@ export class CtxMenuActionButtonOpener extends WidgetTogglerButton {
|
||||
|
||||
update(options) {
|
||||
if (options && options.ctxMenu) {
|
||||
console.log(this.ctxMenu, "attach", options.ctxMenu)
|
||||
this.layout = options.ctxMenu;
|
||||
this.ctxMenu.attach(this.layout, this)
|
||||
//this.ctxMenu.attach(this.layout, this)
|
||||
}
|
||||
|
||||
super.update(options)
|
||||
|
||||
@@ -55,11 +55,11 @@ import { ALEvent } from "../../events/ALEvent";
|
||||
size: 'medium',
|
||||
url: projectionIconUrl,
|
||||
},
|
||||
openDirection: 'left',
|
||||
classList: ['aladin-projection-control'],
|
||||
content: projectionName,
|
||||
tooltip: {content: 'Change the view projection', position: {direction: 'bottom left'}},
|
||||
ctxMenu,
|
||||
openDirection: 'left',
|
||||
...options
|
||||
}, aladin);
|
||||
|
||||
|
||||
@@ -40,14 +40,10 @@ import stackOverlayIconUrl from "./../../../../assets/icons/stack.svg";
|
||||
* UI responsible for displaying the viewport infos
|
||||
* @param {Aladin} aladin - The aladin instance.
|
||||
*/
|
||||
constructor(aladin) {
|
||||
constructor(aladin, options) {
|
||||
super({
|
||||
widget: {
|
||||
obj: new OverlayStackBox(aladin),
|
||||
position: {
|
||||
direction: "right"
|
||||
}
|
||||
},
|
||||
openDirection: (options && options.openDirection) || 'right',
|
||||
widget: new OverlayStackBox(aladin),
|
||||
icon: {
|
||||
size: 'medium',
|
||||
monochrome: true,
|
||||
@@ -57,7 +53,7 @@ import stackOverlayIconUrl from "./../../../../assets/icons/stack.svg";
|
||||
tooltip: {
|
||||
content: 'Open the overlays menu',
|
||||
position: {
|
||||
direction: 'top right'
|
||||
direction: (options && options.openDirection) || 'left'
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -42,7 +42,7 @@ export class TogglerActionButton extends ActionButton {
|
||||
super({
|
||||
...options,
|
||||
toggled,
|
||||
action(o) {
|
||||
action: (o) => {
|
||||
self.toggle(o)
|
||||
}
|
||||
})
|
||||
@@ -102,32 +102,30 @@ export class TogglerActionButton extends ActionButton {
|
||||
constructor(options) {
|
||||
let self;
|
||||
|
||||
let {position, obj} = options && options.widget;
|
||||
|
||||
let widget = obj;
|
||||
let widget = options && options.widget;
|
||||
let enable = options && options.enable;
|
||||
|
||||
super({
|
||||
toggled: false,
|
||||
on(o) {
|
||||
on: (o) => {
|
||||
if (enable)
|
||||
enable(o)
|
||||
|
||||
widget._show({position})
|
||||
widget._show({
|
||||
position: self.position
|
||||
})
|
||||
},
|
||||
off(_) {
|
||||
off: (_) => {
|
||||
self.close();
|
||||
},
|
||||
...options
|
||||
});
|
||||
self = this;
|
||||
|
||||
this.update(options)
|
||||
|
||||
widget.setToggler(this);
|
||||
this.widget = widget;
|
||||
|
||||
if (position && position.direction) {
|
||||
position['nextTo'] = this;
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
@@ -135,4 +133,22 @@ export class TogglerActionButton extends ActionButton {
|
||||
|
||||
super.close()
|
||||
}
|
||||
|
||||
update(options) {
|
||||
this.openDirection = (options && options.openDirection) || this.openDirection;
|
||||
this.openPosition = (options && options.openPosition) || this.openPosition;
|
||||
|
||||
if (this.openPosition) {
|
||||
this.position = {
|
||||
anchor: this.openPosition,
|
||||
}
|
||||
} else {
|
||||
this.position = {
|
||||
direction: this.openDirection,
|
||||
nextTo: this
|
||||
}
|
||||
}
|
||||
|
||||
super.update(options)
|
||||
}
|
||||
}
|
||||
|
||||
+41
-9
@@ -34,26 +34,29 @@ import { DOMElement } from "./Widgets/Widget";
|
||||
export class Toolbar extends Layout {
|
||||
/**
|
||||
* Create a layout
|
||||
* @param {layout: Array.<DOMElement | String>} layout - Represents the structure of the Tabs
|
||||
* @param {Object[]} widgets - A list of predefined widgets
|
||||
* @param {Object} options - Options object
|
||||
* @param {DOMElement} target - The parent element.
|
||||
* @param {String} position - The position of the tabs layout relative to the target.
|
||||
* For the list of possibilities, see https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML
|
||||
* For the list of possibilities, see https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML
|
||||
*/
|
||||
constructor(widgets, options, target, position = "beforeend") {
|
||||
constructor(options, target) {
|
||||
let position = (options && options.position) || 'topleft';
|
||||
delete options.position;
|
||||
|
||||
super(
|
||||
[],
|
||||
options,
|
||||
target,
|
||||
position
|
||||
)
|
||||
|
||||
|
||||
console.log("options toolbar", options)
|
||||
|
||||
this.position = position;
|
||||
this.vertical = options && options.vertical === true;
|
||||
|
||||
this.toggled = null;
|
||||
this.widgets = {};
|
||||
|
||||
for (let [name, widget] of Object.entries(widgets)) {
|
||||
this.add(name, widget)
|
||||
}
|
||||
}
|
||||
|
||||
// Close the toggled widget if the user clicks on another one
|
||||
@@ -104,6 +107,35 @@ export class Toolbar extends Layout {
|
||||
widget = new ActionButton(widget)
|
||||
}
|
||||
|
||||
switch (this.position) {
|
||||
case 'topleft':
|
||||
widget.update({openDirection: 'right'})
|
||||
this.update({position: {
|
||||
anchor: 'left top'
|
||||
}})
|
||||
break;
|
||||
case 'topright':
|
||||
widget.update({openDirection: 'left'})
|
||||
this.update({position: {
|
||||
anchor: 'right top'
|
||||
}})
|
||||
break;
|
||||
case 'bottomleft':
|
||||
widget.update({openDirection: 'top'})
|
||||
this.update({position: {
|
||||
anchor: 'left bottom'
|
||||
}})
|
||||
break;
|
||||
case 'bottomright':
|
||||
widget.update({openDirection: 'top right'})
|
||||
this.update({position: {
|
||||
anchor: 'right bottom'
|
||||
}})
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const action = widget.options.action;
|
||||
widget.update({
|
||||
action: (o) => {
|
||||
|
||||
@@ -57,8 +57,6 @@ export class Box extends DOMElement {
|
||||
|
||||
this.el.innerHTML = "";
|
||||
|
||||
let self = this;
|
||||
|
||||
let close = this.options.close === false ? false : true;
|
||||
let draggable = false;
|
||||
if (close) {
|
||||
|
||||
@@ -213,9 +213,11 @@ export class DOMElement {
|
||||
let aDivRect = aladinDiv.getBoundingClientRect();
|
||||
const offViewX = aDivRect.x;
|
||||
const offViewY = aDivRect.y;
|
||||
|
||||
if (!dir) {
|
||||
// determine the direction with respect to the element given
|
||||
let elX = options.nextTo.el.getBoundingClientRect().left + options.nextTo.el.getBoundingClientRect().width * 0.5 - offViewX;
|
||||
const nextElementRect = nextTo.el.getBoundingClientRect();
|
||||
let elX = nextElementRect.left + nextElementRect.width * 0.5 - offViewX;
|
||||
dir = (elX < innerWidth / 2) ? 'right' : 'left';
|
||||
}
|
||||
|
||||
@@ -224,23 +226,28 @@ export class DOMElement {
|
||||
}
|
||||
|
||||
let rect = nextTo.getBoundingClientRect();
|
||||
this.el.classList.remove('left', 'right', 'top', 'bottom');
|
||||
|
||||
switch (dir) {
|
||||
case 'left':
|
||||
left = rect.x - offsetWidth - offViewX;
|
||||
left = rect.x - offViewX;
|
||||
top = rect.y - offViewY;
|
||||
this.el.classList.add('left');
|
||||
break;
|
||||
case 'right':
|
||||
left = rect.x + rect.width - offViewX;
|
||||
top = rect.y - offViewY;
|
||||
this.el.classList.add('right');
|
||||
break;
|
||||
case 'top':
|
||||
left = rect.x - offViewX;
|
||||
top = rect.y - offsetHeight - offViewY;
|
||||
top = rect.y - offViewY;
|
||||
this.el.classList.add('top');
|
||||
break;
|
||||
case 'bottom':
|
||||
left = rect.x - offViewX;
|
||||
top = rect.y + rect.height - offViewY;
|
||||
this.el.classList.add('bottom');
|
||||
break;
|
||||
default:
|
||||
left = 0;
|
||||
@@ -250,11 +257,11 @@ export class DOMElement {
|
||||
|
||||
// Translate if the div in
|
||||
if (typeof top === 'number') {
|
||||
if (top + offsetHeight >= innerHeight) {
|
||||
/*if (top + offsetHeight >= innerHeight) {
|
||||
y = '-' + (top + offsetHeight - innerHeight) + 'px';
|
||||
} else if (top < 0) {
|
||||
y = Math.abs(top) + 'px';
|
||||
}
|
||||
}*/
|
||||
|
||||
top = top + 'px';
|
||||
}
|
||||
@@ -262,11 +269,11 @@ export class DOMElement {
|
||||
bottom = bottom + 'px';
|
||||
}
|
||||
if (typeof left === 'number') {
|
||||
if (left + offsetWidth > innerWidth) {
|
||||
/*if (left + offsetWidth > innerWidth) {
|
||||
x = '-' + (left + offsetWidth - innerWidth) + 'px';
|
||||
} else if (left < 0) {
|
||||
x = Math.abs(left) + 'px';
|
||||
}
|
||||
}*/
|
||||
|
||||
left = left + 'px';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user