toolbar functional

This commit is contained in:
Matthieu Baumann
2026-01-31 16:01:51 +01:00
committed by Matthieu Baumann
parent 45129708db
commit 8b645824c7
20 changed files with 4609 additions and 4536 deletions
+8
View File
@@ -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 -3
View File
@@ -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'});
+2 -2
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+56 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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,
});
}
-58
View File
@@ -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
View File
@@ -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) {
+4 -7
View File
@@ -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");
+2 -6
View File
@@ -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");
+2 -6
View File
@@ -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
View File
@@ -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, "&nbsp;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)
+2 -6
View File
@@ -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)
+1 -1
View File
@@ -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);
+4 -8
View File
@@ -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'
}
},
});
+27 -11
View File
@@ -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
View File
@@ -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) => {
-2
View File
@@ -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) {
+14 -7
View File
@@ -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';
}