diff --git a/e2e/test-data/PerformanceDisplayLayout.json b/e2e/test-data/PerformanceDisplayLayout.json index eebc7635ad..de81d7b4ca 100644 --- a/e2e/test-data/PerformanceDisplayLayout.json +++ b/e2e/test-data/PerformanceDisplayLayout.json @@ -1 +1 @@ -{"openmct":{"21338566-d472-4377-aed1-21b79272c8de":{"identifier":{"key":"21338566-d472-4377-aed1-21b79272c8de","namespace":""},"name":"Performance Display Layout","type":"layout","composition":[{"key":"644c2e47-2903-475f-8a4a-6be1588ee02f","namespace":""}],"configuration":{"items":[{"width":32,"height":18,"x":1,"y":1,"identifier":{"key":"644c2e47-2903-475f-8a4a-6be1588ee02f","namespace":""},"hasFrame":true,"fontSize":"default","font":"default","type":"subobject-view","id":"5aeb5a71-3149-41ed-9d8a-d34b0a18b053"}],"layoutGrid":[10,10]},"modified":1652228997384,"location":"mine","persisted":1652228997384},"644c2e47-2903-475f-8a4a-6be1588ee02f":{"identifier":{"key":"644c2e47-2903-475f-8a4a-6be1588ee02f","namespace":""},"name":"Performance Example Imagery","type":"example.imagery","configuration":{"imageLocation":"","imageLoadDelayInMilliSeconds":20000,"imageSamples":[]},"telemetry":{"values":[{"name":"Name","key":"name"},{"name":"Time","key":"utc","format":"utc","hints":{"domain":2}},{"name":"Local Time","key":"local","format":"local-format","hints":{"domain":1}},{"name":"Image","key":"url","format":"image","hints":{"image":1}},{"name":"Image Download Name","key":"imageDownloadName","format":"imageDownloadName","hints":{"imageDownloadName":1}}]},"modified":1652228997375,"location":"21338566-d472-4377-aed1-21b79272c8de","persisted":1652228997375}},"rootId":"21338566-d472-4377-aed1-21b79272c8de"} \ No newline at end of file +{"openmct":{"b3cee102-86dd-4c0a-8eec-4d5d276f8691":{"identifier":{"key":"b3cee102-86dd-4c0a-8eec-4d5d276f8691","namespace":""},"name":"Performance Display Layout","type":"layout","composition":[{"key":"9666e7b4-be0c-47a5-94b8-99accad7155e","namespace":""}],"configuration":{"items":[{"width":32,"height":18,"x":12,"y":9,"identifier":{"key":"9666e7b4-be0c-47a5-94b8-99accad7155e","namespace":""},"hasFrame":true,"fontSize":"default","font":"default","type":"subobject-view","id":"23ca351d-a67d-46aa-a762-290eb742d2f1"}],"layoutGrid":[10,10]},"modified":1654299875432,"location":"mine","persisted":1654299878751},"9666e7b4-be0c-47a5-94b8-99accad7155e":{"identifier":{"key":"9666e7b4-be0c-47a5-94b8-99accad7155e","namespace":""},"name":"Performance Example Imagery","type":"example.imagery","configuration":{"imageLocation":"","imageLoadDelayInMilliSeconds":20000,"imageSamples":[],"layers":[{"source":"dist/imagery/example-imagery-layer-16x9.png","name":"16:9","visible":false},{"source":"dist/imagery/example-imagery-layer-safe.png","name":"Safe","visible":false},{"source":"dist/imagery/example-imagery-layer-scale.png","name":"Scale","visible":false}]},"telemetry":{"values":[{"name":"Name","key":"name"},{"name":"Time","key":"utc","format":"utc","hints":{"domain":2}},{"name":"Local Time","key":"local","format":"local-format","hints":{"domain":1}},{"name":"Image","key":"url","format":"image","hints":{"image":1},"layers":[{"source":"dist/imagery/example-imagery-layer-16x9.png","name":"16:9"},{"source":"dist/imagery/example-imagery-layer-safe.png","name":"Safe"},{"source":"dist/imagery/example-imagery-layer-scale.png","name":"Scale"}]},{"name":"Image Download Name","key":"imageDownloadName","format":"imageDownloadName","hints":{"imageDownloadName":1}}]},"modified":1654299840077,"location":"b3cee102-86dd-4c0a-8eec-4d5d276f8691","persisted":1654299840078}},"rootId":"b3cee102-86dd-4c0a-8eec-4d5d276f8691"} \ No newline at end of file diff --git a/e2e/tests/performance/imagery.perf.spec.js b/e2e/tests/performance/imagery.perf.spec.js index e7033ef10d..433bc1699d 100644 --- a/e2e/tests/performance/imagery.perf.spec.js +++ b/e2e/tests/performance/imagery.perf.spec.js @@ -164,7 +164,7 @@ test.describe('Performance tests', () => { console.log('jpgResourceTiming ' + JSON.stringify(jpgResourceTiming)); // Click Close Icon - await page.locator('.c-click-icon').click(); + await page.locator('[aria-label="Close"]').click(); await page.evaluate(() => window.performance.mark("view-large-close-button")); //await client.send('HeapProfiler.enable'); diff --git a/e2e/tests/plugins/imagery/exampleImagery.e2e.spec.js b/e2e/tests/plugins/imagery/exampleImagery.e2e.spec.js index d5c204cdb2..0a570e5c2a 100644 --- a/e2e/tests/plugins/imagery/exampleImagery.e2e.spec.js +++ b/e2e/tests/plugins/imagery/exampleImagery.e2e.spec.js @@ -32,7 +32,6 @@ const { expect } = require('@playwright/test'); test.describe('Example Imagery', () => { test.beforeEach(async ({ page }) => { - page.on('console', msg => console.log(msg.text())); //Go to baseURL await page.goto('/', { waitUntil: 'networkidle' }); @@ -61,19 +60,19 @@ test.describe('Example Imagery', () => { test('Can use Mouse Wheel to zoom in and out of latest image', async ({ page }) => { const bgImageLocator = page.locator(backgroundImageSelector); const deltaYStep = 100; //equivalent to 1x zoom - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); const originalImageDimensions = await page.locator(backgroundImageSelector).boundingBox(); // zoom in - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); await page.mouse.wheel(0, deltaYStep * 2); // wait for zoom animation to finish - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); const imageMouseZoomedIn = await page.locator(backgroundImageSelector).boundingBox(); // zoom out - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); await page.mouse.wheel(0, -deltaYStep); // wait for zoom animation to finish - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); const imageMouseZoomedOut = await page.locator(backgroundImageSelector).boundingBox(); expect(imageMouseZoomedIn.height).toBeGreaterThan(originalImageDimensions.height); @@ -88,11 +87,11 @@ test.describe('Example Imagery', () => { const panHotkey = process.platform === 'linux' ? ['Control', 'Alt'] : ['Alt']; const bgImageLocator = page.locator(backgroundImageSelector); - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); // zoom in await page.mouse.wheel(0, deltaYStep * 2); - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); const zoomedBoundingBox = await bgImageLocator.boundingBox(); const imageCenterX = zoomedBoundingBox.x + zoomedBoundingBox.width / 2; const imageCenterY = zoomedBoundingBox.y + zoomedBoundingBox.height / 2; @@ -151,22 +150,22 @@ test.describe('Example Imagery', () => { test('Can use + - buttons to zoom on the image', async ({ page }) => { const bgImageLocator = page.locator(backgroundImageSelector); - await bgImageLocator.hover(); - const zoomInBtn = page.locator('.t-btn-zoom-in'); - const zoomOutBtn = page.locator('.t-btn-zoom-out'); + await bgImageLocator.hover({trial: true}); + const zoomInBtn = page.locator('.t-btn-zoom-in').nth(0); + const zoomOutBtn = page.locator('.t-btn-zoom-out').nth(0); const initialBoundingBox = await bgImageLocator.boundingBox(); await zoomInBtn.click(); await zoomInBtn.click(); // wait for zoom animation to finish - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); const zoomedInBoundingBox = await bgImageLocator.boundingBox(); expect(zoomedInBoundingBox.height).toBeGreaterThan(initialBoundingBox.height); expect(zoomedInBoundingBox.width).toBeGreaterThan(initialBoundingBox.width); await zoomOutBtn.click(); // wait for zoom animation to finish - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); const zoomedOutBoundingBox = await bgImageLocator.boundingBox(); expect(zoomedOutBoundingBox.height).toBeLessThan(zoomedInBoundingBox.height); expect(zoomedOutBoundingBox.width).toBeLessThan(zoomedInBoundingBox.width); @@ -176,18 +175,18 @@ test.describe('Example Imagery', () => { test('Can use the reset button to reset the image', async ({ page }) => { const bgImageLocator = page.locator(backgroundImageSelector); // wait for zoom animation to finish - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); - const zoomInBtn = page.locator('.t-btn-zoom-in'); - const zoomResetBtn = page.locator('.t-btn-zoom-reset'); + const zoomInBtn = page.locator('.t-btn-zoom-in').nth(0); + const zoomResetBtn = page.locator('.t-btn-zoom-reset').nth(0); const initialBoundingBox = await bgImageLocator.boundingBox(); await zoomInBtn.click(); // wait for zoom animation to finish - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); await zoomInBtn.click(); // wait for zoom animation to finish - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); const zoomedInBoundingBox = await bgImageLocator.boundingBox(); expect.soft(zoomedInBoundingBox.height).toBeGreaterThan(initialBoundingBox.height); @@ -195,7 +194,7 @@ test.describe('Example Imagery', () => { await zoomResetBtn.click(); // wait for zoom animation to finish - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); const resetBoundingBox = await bgImageLocator.boundingBox(); expect.soft(resetBoundingBox.height).toBeLessThan(zoomedInBoundingBox.height); @@ -209,18 +208,18 @@ test.describe('Example Imagery', () => { const bgImageLocator = page.locator(backgroundImageSelector); const pausePlayButton = page.locator('.c-button.pause-play'); // wait for zoom animation to finish - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); // open the time conductor drop down - await page.locator('.c-conductor__controls button.c-mode-button').click(); + await page.locator('button:has-text("Fixed Timespan")').click(); // Click local clock - await page.locator('.icon-clock >> text=Local Clock').click(); + await page.locator('[data-testid="conductor-modeOption-realtime"]').click(); await expect.soft(pausePlayButton).not.toHaveClass(/is-paused/); - const zoomInBtn = page.locator('.t-btn-zoom-in'); + const zoomInBtn = page.locator('.t-btn-zoom-in').nth(0); await zoomInBtn.click(); // wait for zoom animation to finish - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); return expect(pausePlayButton).not.toHaveClass(/is-paused/); }); @@ -267,7 +266,7 @@ test('Example Imagery in Display layout', async ({ page }) => { await page.waitForSelector('.c-message-banner__message', { state: 'detached'}); await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Example Imagery'); const bgImageLocator = page.locator(backgroundImageSelector); - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); // Click previous image button const previousImageButton = page.locator('.c-nav--prev'); @@ -279,7 +278,7 @@ test('Example Imagery in Display layout', async ({ page }) => { // Zoom in const originalImageDimensions = await page.locator(backgroundImageSelector).boundingBox(); - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); const deltaYStep = 100; // equivalent to 1x zoom await page.mouse.wheel(0, deltaYStep * 2); const zoomedBoundingBox = await bgImageLocator.boundingBox(); @@ -287,7 +286,7 @@ test('Example Imagery in Display layout', async ({ page }) => { const imageCenterY = zoomedBoundingBox.y + zoomedBoundingBox.height / 2; // Wait for zoom animation to finish - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); const imageMouseZoomedIn = await page.locator(backgroundImageSelector).boundingBox(); expect(imageMouseZoomedIn.height).toBeGreaterThan(originalImageDimensions.height); expect(imageMouseZoomedIn.width).toBeGreaterThan(originalImageDimensions.width); @@ -311,11 +310,11 @@ test('Example Imagery in Display layout', async ({ page }) => { await page.locator('[data-testid=conductor-modeOption-realtime]').click(); // Zoom in on next image - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); await page.mouse.wheel(0, deltaYStep * 2); // Wait for zoom animation to finish - await bgImageLocator.hover(); + await bgImageLocator.hover({trial: true}); const imageNextMouseZoomedIn = await page.locator(backgroundImageSelector).boundingBox(); expect(imageNextMouseZoomedIn.height).toBeGreaterThan(originalImageDimensions.height); expect(imageNextMouseZoomedIn.width).toBeGreaterThan(originalImageDimensions.width); diff --git a/example/imagery/plugin.js b/example/imagery/plugin.js index 6823ede509..47d6f4ef70 100644 --- a/example/imagery/plugin.js +++ b/example/imagery/plugin.js @@ -59,7 +59,8 @@ export default function () { object.configuration = { imageLocation: '', imageLoadDelayInMilliSeconds: DEFAULT_IMAGE_LOAD_DELAY_IN_MILISECONDS, - imageSamples: [] + imageSamples: [], + layers: [] }; object.telemetry = { @@ -90,7 +91,21 @@ export default function () { format: 'image', hints: { image: 1 - } + }, + layers: [ + { + source: 'dist/imagery/example-imagery-layer-16x9.png', + name: '16:9' + }, + { + source: 'dist/imagery/example-imagery-layer-safe.png', + name: 'Safe' + }, + { + source: 'dist/imagery/example-imagery-layer-scale.png', + name: 'Scale' + } + ] }, { name: 'Image Download Name', diff --git a/src/api/overlays/components/OverlayComponent.vue b/src/api/overlays/components/OverlayComponent.vue index f8a66f7597..9742fd7367 100644 --- a/src/api/overlays/components/OverlayComponent.vue +++ b/src/api/overlays/components/OverlayComponent.vue @@ -7,6 +7,7 @@
diff --git a/src/plugins/displayLayout/components/LayoutFrame.vue b/src/plugins/displayLayout/components/LayoutFrame.vue index 052fa63a3c..c81fb80f71 100644 --- a/src/plugins/displayLayout/components/LayoutFrame.vue +++ b/src/plugins/displayLayout/components/LayoutFrame.vue @@ -25,8 +25,7 @@ class="l-layout__frame c-frame" :class="{ 'no-frame': !item.hasFrame, - 'u-inspectable': inspectable, - 'is-in-small-container': size.width < 600 || size.height < 600 + 'u-inspectable': inspectable }" :style="style" > diff --git a/src/plugins/displayLayout/components/layout-frame.scss b/src/plugins/displayLayout/components/layout-frame.scss index 63f2299ecb..d036814021 100644 --- a/src/plugins/displayLayout/components/layout-frame.scss +++ b/src/plugins/displayLayout/components/layout-frame.scss @@ -9,10 +9,6 @@ > *:first-child { flex: 1 1 auto; } - - &.is-in-small-container { - //background: rgba(blue, 0.1); - } } .c-frame__move-bar { diff --git a/src/plugins/imagery/components/FilterSettings.vue b/src/plugins/imagery/components/FilterSettings.vue new file mode 100644 index 0000000000..c88d215d55 --- /dev/null +++ b/src/plugins/imagery/components/FilterSettings.vue @@ -0,0 +1,74 @@ + + + diff --git a/src/plugins/imagery/components/ImageControls.vue b/src/plugins/imagery/components/ImageControls.vue index a14a402df5..b14c13f8b2 100644 --- a/src/plugins/imagery/components/ImageControls.vue +++ b/src/plugins/imagery/components/ImageControls.vue @@ -21,75 +21,62 @@ *****************************************************************************/ diff --git a/src/plugins/imagery/components/LayerSettings.vue b/src/plugins/imagery/components/LayerSettings.vue new file mode 100644 index 0000000000..1e99a0aee6 --- /dev/null +++ b/src/plugins/imagery/components/LayerSettings.vue @@ -0,0 +1,59 @@ + + + diff --git a/src/plugins/imagery/components/ZoomSettings.vue b/src/plugins/imagery/components/ZoomSettings.vue new file mode 100644 index 0000000000..e53d6289ed --- /dev/null +++ b/src/plugins/imagery/components/ZoomSettings.vue @@ -0,0 +1,89 @@ + + + diff --git a/src/plugins/imagery/components/imagery-view.scss b/src/plugins/imagery/components/imagery-view.scss index 8cdae861db..e781fdce9a 100644 --- a/src/plugins/imagery/components/imagery-view.scss +++ b/src/plugins/imagery/components/imagery-view.scss @@ -28,6 +28,27 @@ display: flex; flex-direction: column; flex: 1 1 auto; + + &.unnsynced{ + @include sUnsynced(); + } + + &.cursor-zoom-in { + cursor: zoom-in; + } + + &.cursor-zoom-out { + cursor: zoom-out; + } + + &.pannable { + @include cursorGrab(); + } + } + + .image-wrapper { + overflow: visible clip; + background-image: repeating-linear-gradient(45deg, transparent, transparent 4px, rgba(125, 125, 125, 0.2) 4px, rgba(125, 125, 125, 0.2) 8px); } .image-wrapper { @@ -45,19 +66,6 @@ flex: 1 1 auto; height: 0; overflow: hidden; - &.unnsynced{ - @include sUnsynced(); - } - &.cursor-zoom-in { - cursor: zoom-in; - } - &.cursor-zoom-out { - cursor: zoom-out; - } - &.pannable { - @include cursorGrab(); - - } } &__background-image { background-position: center; @@ -77,6 +85,7 @@ background: rgba(black, 0.2); border-radius: $smallCr; padding: 2px $interiorMargin; + pointer-events: none; position: absolute; right: $m; top: $m; @@ -146,6 +155,11 @@ } + &__layer-image { + pointer-events: none; + z-index: 1; + } + &__thumbs-wrapper { display: flex; // Uses row layout justify-content: flex-end; @@ -179,6 +193,50 @@ font-size: 0.8em; margin: $interiorMarginSm; } + + .c-control-menu { + // Controls on left of flex column layout, close btn on right + @include menuOuter(); + + border-radius: $controlCr; + display: flex; + align-items: flex-start; + justify-content: space-between; + padding: $interiorMargin; + width: min-content; + + > * + * { + margin-left: $interiorMargin; + } + } + + .c-switcher-menu { + display: contents; + + &__content { + // Menu panel + top: 28px; + position: absolute; + + .c-so-view & { + top: 25px; + } + } + } +} + +.--width-less-than-220 .--show-if-less-than-220.c-switcher-menu { + display: contents !important; +} + +.s-image-layer { + position: absolute; + height: 100%; + width: 100%; + opacity: 0.5; + background-size: contain; + background-repeat: no-repeat; + background-position: center; } /*************************************** THUMBS */ @@ -229,70 +287,36 @@ /*************************************** IMAGERY LOCAL CONTROLS*/ .c-imagery { .h-local-controls--overlay-content { + display: flex; + flex-direction: row; position: absolute; left: $interiorMargin; top: $interiorMargin; z-index: 70; background: $colorLocalControlOvrBg; border-radius: $basicCr; - max-width: 250px; - min-width: 170px; - width: 35%; align-items: center; - padding: $interiorMargin $interiorMarginLg; - - input[type="range"] { - display: block; - width: 100%; - &:not(:first-child) { - margin-top: $interiorMarginLg; - } - - &:before { - margin-right: $interiorMarginSm; - } - } + padding: $interiorMargin $interiorMargin; .s-status-taking-snapshot & { display: none; } } - - &__lc { - &__reset-btn { - // Span that holds bracket graphics and button - $bc: $scrollbarTrackColorBg; - - &:before, - &:after { - border-right: 1px solid $bc; - content:''; - display: block; - width: 5px; - height: 4px; - } - - &:before { - border-top: 1px solid $bc; - margin-bottom: 2px; - } - - &:after { - border-bottom: 1px solid $bc; - margin-top: 2px; - } - - .c-icon-link { - color: $colorBtnFg; - } + [class*='--menus-aligned'] { + > * + * { + button { margin-left: $interiorMarginSm; } } } } .c-image-controls { + &__controls-wrapper { + // Wraps __controls and __close-btn + display: flex; + } + &__controls { display: flex; align-items: stretch; - flex-direction: column; > * + * { margin-top: $interiorMargin; @@ -314,31 +338,67 @@ } - &__input { - // A wrapper is needed to add the type icon to left of each control - - input[type='range'] { - //width: 100%; // Do we need this? - } - } - &__zoom { - > * + * { margin-left: $interiorMargin; } + > * + * { margin-left: $interiorMargin; } // Is this used? } - &__sliders { - display: flex; - flex: 1 1 auto; - flex-direction: column; + &--filters { + // Styles specific to the brightness and contrast controls - > * + * { - margin-top: 11px; + .c-image-controls { + &__sliders { + display: flex; + flex: 1 1 auto; + flex-direction: column; + min-width: 80px; + + > * + * { + margin-top: 11px; + } + + input[type="range"] { + display: block; + width: 100%; + } + } + + &__slider-wrapper { + display: flex; + align-items: center; + + &:before { margin-right: $interiorMargin; } + } + + &__reset-btn { + // Span that holds bracket graphics and button + $bc: $scrollbarTrackColorBg; + flex: 0 0 auto; + + &:before, + &:after { + border-right: 1px solid $bc; + content:''; + display: block; + width: 5px; + height: 4px; + } + + &:before { + border-top: 1px solid $bc; + margin-bottom: 2px; + } + + &:after { + border-bottom: 1px solid $bc; + margin-top: 2px; + } + + .c-icon-link { + color: $colorBtnFg; + } + } } } - - &__btn-reset { - flex: 0 0 auto; - } } /*************************************** BUTTONS */ @@ -383,7 +443,7 @@ @include cArrowButtonSizing($dimOuter: 48px); border-radius: $controlCr; - .is-in-small-container & { + .--width-less-than-600 & { @include cArrowButtonSizing($dimOuter: 32px); } } @@ -409,10 +469,6 @@ background-color: $colorBodyFg; } - //[class*='__image-placeholder'] { - // display: none; - //} - img { display: block !important; } diff --git a/src/plugins/imagery/layers/example-imagery-layer-16x9.png b/src/plugins/imagery/layers/example-imagery-layer-16x9.png new file mode 100644 index 0000000000..877a0e6038 Binary files /dev/null and b/src/plugins/imagery/layers/example-imagery-layer-16x9.png differ diff --git a/src/plugins/imagery/layers/example-imagery-layer-safe.png b/src/plugins/imagery/layers/example-imagery-layer-safe.png new file mode 100644 index 0000000000..f99907f299 Binary files /dev/null and b/src/plugins/imagery/layers/example-imagery-layer-safe.png differ diff --git a/src/plugins/imagery/layers/example-imagery-layer-scale.png b/src/plugins/imagery/layers/example-imagery-layer-scale.png new file mode 100644 index 0000000000..7f5f41211b Binary files /dev/null and b/src/plugins/imagery/layers/example-imagery-layer-scale.png differ diff --git a/src/plugins/imagery/pluginSpec.js b/src/plugins/imagery/pluginSpec.js index 8ba66a24c2..aa2a284d43 100644 --- a/src/plugins/imagery/pluginSpec.js +++ b/src/plugins/imagery/pluginSpec.js @@ -100,12 +100,24 @@ describe("The Imagery View Layouts", () => { location: "parentId", modified: 0, persisted: 0, + configuration: { + layers: [{ + name: '16:9', + visible: true + }] + }, telemetry: { values: [ { "name": "Image", "key": "url", "format": "image", + "layers": [ + { + source: location.host + '/images/bg-splash.jpg', + name: '16:9' + } + ], "hints": { "image": 1, "priority": 3 @@ -366,6 +378,18 @@ describe("The Imagery View Layouts", () => { }); }); + it("on mount should show the any image layers", (done) => { + //Looks like we need Vue.nextTick here so that computed properties settle down + Vue.nextTick().then(() => { + Vue.nextTick(() => { + const layerEls = parent.querySelectorAll('.js-layer-image'); + console.log(layerEls); + expect(layerEls.length).toEqual(1); + done(); + }); + }); + }); + it("should show the clicked thumbnail as the main image", (done) => { //Looks like we need Vue.nextTick here so that computed properties settle down Vue.nextTick(() => { diff --git a/src/plugins/telemetryTable/components/table.scss b/src/plugins/telemetryTable/components/table.scss index 512af8c3a1..03d54c0f72 100644 --- a/src/plugins/telemetryTable/components/table.scss +++ b/src/plugins/telemetryTable/components/table.scss @@ -63,8 +63,9 @@ padding-top: 0; padding-bottom: 0; } - .is-in-small-container & { - display: none; + + .--width-less-than-600 & { + display: none !important; } } } diff --git a/src/styles/_controls.scss b/src/styles/_controls.scss index ac11686977..3e356036d6 100644 --- a/src/styles/_controls.scss +++ b/src/styles/_controls.scss @@ -42,6 +42,17 @@ } } +@mixin menuPositioning() { + display: flex; + flex-direction: column; + position: absolute; + z-index: 100; + + > * { + flex: 0 0 auto; + } +} + @mixin menuInner() { li { @include cControl(); @@ -479,6 +490,10 @@ select { &__row { > * + * { margin-left: $interiorMargin; } } + + li { + white-space: nowrap; + } } /******************************************************** TABS */ @@ -567,6 +582,7 @@ select { /******************************************************** MENUS */ .c-menu { @include menuOuter(); + @include menuPositioning(); @include menuInner(); &__section-hint { @@ -590,6 +606,7 @@ select { .c-super-menu { // Two column layout, menu items on left with detail of hover element on right @include menuOuter(); + @include menuPositioning(); display: flex; padding: $interiorMarginLg; flex-direction: row; @@ -1035,6 +1052,14 @@ input[type="range"] { display: inline-flex; align-items: center; } + + [class*='--menus-aligned'] { + // Contains top level elements that hold dropdown menus + // Top level elements use display: contents to allow their menus to compactly align + // 03-18-22: used in ImageControls.vue + display: flex; + flex-direction: row; + } } .c-local-controls { diff --git a/src/styles/_global.scss b/src/styles/_global.scss index 5b2efb8efd..46ab0ad66b 100644 --- a/src/styles/_global.scss +++ b/src/styles/_global.scss @@ -349,3 +349,22 @@ body.desktop .has-local-controls { pointer-events: none !important; cursor: default !important; } + +/******************************************************** RESPONSIVE CONTAINERS */ +@mixin responsiveContainerWidths($dimension) { + // 3/21/22: `--width-less-than*` classes set in ObjectView.vue + .--show-if-less-than-#{$dimension} { + // Hide anything that displays within a given width by default. + // `display` property must be set within a more specific class + // for the particular item to be displayed. + display: none !important + } + + .--width-less-than-#{$dimension} { + .--hide-if-less-than-#{$dimension} { display: none; } + } +} + +//.--hide-by-default { display: none !important; } +@include responsiveContainerWidths('220'); +@include responsiveContainerWidths('600'); diff --git a/src/styles/_legacy-plots.scss b/src/styles/_legacy-plots.scss index 4ec0529e0f..b9ae1b6d9b 100644 --- a/src/styles/_legacy-plots.scss +++ b/src/styles/_legacy-plots.scss @@ -118,7 +118,7 @@ mct-plot { } } - .is-in-small-container & { + .--width-less-than-600 & { .c-control-bar { display: none; } @@ -498,7 +498,7 @@ mct-plot { margin-bottom: $interiorMarginSm; } - .is-in-small-container & { + .--width-less-than-600 & { &.is-legend-hidden { display: none; } diff --git a/src/styles/_table.scss b/src/styles/_table.scss index 12540ae933..d6c85206d0 100644 --- a/src/styles/_table.scss +++ b/src/styles/_table.scss @@ -90,7 +90,7 @@ div.c-table { flex: 1 1 auto; } - .is-in-small-container & { + .--width-less-than-600 & { &:not(.is-paused) { .c-table-control-bar { display: none; diff --git a/src/ui/components/ObjectFrame.vue b/src/ui/components/ObjectFrame.vue index cef8931873..1254cc3cbb 100644 --- a/src/ui/components/ObjectFrame.vue +++ b/src/ui/components/ObjectFrame.vue @@ -21,9 +21,11 @@ *****************************************************************************/