Skip to content

Commit

Permalink
Horizontal layer buttons (spacetelescope#2566)
Browse files Browse the repository at this point in the history
* Layers now represented as horizontal buttons

Color change and multiselect working

Move logic to LayerSelect

* Fix codestyle

* Fix codestlye and remove comments

* Viewer multiselect mixed state working

* Working on handling edge cases of mixed state

* Use messages in LayerSelect to call parts of _on_layers_changed

* Remove unused elements

* Fix button colors not updating after unmix state

* Fix codestyle

* Attempt 2 at fixing code style

* Fix CI, put buttons in icon order

* Code style again

* Fix more tests

* Everything handled by _on_layers_changed

* button styling/tooltip based on (mixed)-color/visibility

* improve tab styling

* avoid second loop when applying RGB presets

* improved handling of colormap and mixed colormode

* remove elevation

* redundant and conflicting with tab backgrounds

* use all_color_to_label in tab styling

* Mixed visibility and color represented in button

* improved handling of subset color when in colormap

* improved dark-theme support

* tooltip and RGB preset support for mixed visibility

* Visible is set to layer visible and bitmap visible

* avoid displacement when no tabs selected

* Fix CI tests

* RGB presets: handle unmixing state

* Address review comments

* Forgot one change

* for styling, always check if item in list, not as substring

* Update changelog

* Add tests

---------

Co-authored-by: Kyle Conroy <kyleconroy@gmail.com>
  • Loading branch information
2 people authored and rosteen committed Nov 29, 2023
1 parent fbff70a commit 2a09293
Show file tree
Hide file tree
Showing 9 changed files with 778 additions and 466 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ New Features

- Plugin APIs now include a ``close_in_tray()`` method. [#2562]

- Convert the layer select dropdown in Plot Options into a horizontal panel of buttons. [#2566]

Cubeviz
^^^^^^^

Expand Down
1 change: 1 addition & 0 deletions jdaviz/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ def to_unit(self, data, cid, values, original_units, target_units):
'plugin-subset-select': 'components/plugin_subset_select.vue',
'plugin-viewer-select': 'components/plugin_viewer_select.vue',
'plugin-layer-select': 'components/plugin_layer_select.vue',
'plugin-layer-select-tabs': 'components/plugin_layer_select_tabs.vue',
'plugin-editable-select': 'components/plugin_editable_select.vue',
'plugin-add-results': 'components/plugin_add_results.vue',
'plugin-auto-label': 'components/plugin_auto_label.vue',
Expand Down
18 changes: 18 additions & 0 deletions jdaviz/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -451,4 +451,22 @@ a:active {
font-weight: 500 !important;
}
.suppress-scrollbar {
overflow-y: scroll;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* Internet Explorer 10+ */
}
.suppress-scrollbar::-webkit-scrollbar { /* WebKit */
width: 0;
height: 0;
}
.layer-tab-selected {
background-color: rgba(0,0,0,0.1);
}
.theme--dark .layer-tab-selected {
background-color: rgba(255,255,255,0.1);
}
</style>
87 changes: 87 additions & 0 deletions jdaviz/components/plugin_layer_select_tabs.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<template>
<div>
<span class="suppress-scrollbar" style="display: inline-block; white-space: nowrap; margin-left: -24px; width: calc(100% + 48px); overflow-x: scroll; overflow-y: hidden">
<span v-for="(item, index) in items" :class="selectedAsList.includes(item.label) ? 'layer-tab-selected' : ''" :style="'display: inline-block; padding: 12px; '+(selectedAsList.includes(item.label) ? 'border-top: 2px solid #c75109' : 'border-top: 2px solid transparent')">
<j-tooltip :tooltipcontent="tooltipContent(item)">
<v-btn
:rounded="item.is_subset"
@click="() => {if (!multiselect){$emit('update:selected', item.label)} else if(!selectedAsList.includes(item.label)) {$emit('update:selected', selected.concat(item.label))} else {$emit('update:selected', selected.filter(select => select != item.label))} }"
:style="'padding: 0px; margin-bottom: 4px; background: '+visibilityStyle(item)+', '+colorStyle(item)"
width="30px"
min-width="30px"
height="30px"
>
<span style="color: white; text-shadow: 0px 0px 3px black">
{{ item.icon }}
</span>
</v-btn>
</j-tooltip>
</span>
</span>
</div>
</template>

<script>
module.exports = {
props: ['items', 'selected', 'multiselect', 'colormode'],
computed: {
selectedAsList() {
if (this.$props.multiselect) {
return this.$props.selected
}
return [this.$props.selected]
}
},
methods: {
tooltipContent(item) {
var tooltip = item.label
if (item.mixed_visibility) {
tooltip += '<br/>Visible: mixed'
} else if (!item.visible) {
tooltip += '<br/>Visible: false'
}
if (this.$props.colormode === 'Colormaps' && !item.is_subset) {
tooltip += '<br/>Color mode: colormap'
} else if (this.$props.colormode === 'mixed' && !item.is_subset) {
tooltip += '<br/>Color mode: mixed'
}
if (item.mixed_color && (this.$props.colormode !== 'Colormaps' || item.is_subset)) {
tooltip += '<br/>Color: mixed'
}
return tooltip
},
visibilityStyle(item) {
if (item.mixed_visibility){
return 'repeating-linear-gradient(30deg, rgba(0,0,0,0.3), rgba(0,0,0,0.3) 3px, transparent 3px, transparent 3px, transparent 10px)'
}
else if (item.visible) {
return 'repeating-linear-gradient(30deg, transparent, transparent 10px)'
} else {
return 'repeating-linear-gradient(30deg, rgba(0,0,0,0.8), rgba(0,0,0,0.8) 7px, transparent 7px, transparent 7px, transparent 10px)'
}
},
colorStyle(item) {
if (this.$props.colormode == 'Colormaps' && !item.is_subset) {
return 'repeating-linear-gradient( -45deg, gray, gray 20px)'
}
if (item.mixed_color) {
colors = item.all_colors_to_label
const strip_width = 42 / colors.length
var style = 'repeating-linear-gradient( -45deg, '
for ([ind, color] of colors.entries()) {
style += color + ' '+ind*strip_width+'px, ' + color + ' '+(ind+1)*strip_width+'px'
if (ind !== colors.length-1) {
style += ', '
}
}
style += ')'
return style
}
return 'repeating-linear-gradient( -45deg, '+item.color+', '+item.color+' 20px)'
}
}
};
</script>
2 changes: 1 addition & 1 deletion jdaviz/components/plugin_section_header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
white-space: nowrap;
margin-left: -12px;
margin-right: -12px;
margin-top: 40px;
margin-top: 36px;
margin-bottom: 8px;
}
Expand Down
17 changes: 6 additions & 11 deletions jdaviz/configs/default/plugins/plot_options/plot_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,13 +627,8 @@ def apply_RGB_presets(self):
# Switch back to this at the end
initial_layer = self.layer_selected

# Filter out subset layers
image_layers = [layer for layer in self.layer.choices if "Subset" not in layer]
visible_layers = []
for layer in image_layers:
self.layer_selected = layer
if self.image_visible.value:
visible_layers.append(layer)
# Determine layers visible in selected viewer(s) - consider mixed to be visible
visible_layers = [layer['label'] for layer in self.layer.items if not layer['is_subset'] and (layer['visible'] or layer['mixed_visibility'])] # noqa

# Set opacity to something that seems sensible
n_visible = len(visible_layers)
Expand All @@ -651,10 +646,10 @@ def apply_RGB_presets(self):

for i in range(n_visible):
self.layer_selected = visible_layers[i]
self.image_opacity_value = default_opacity
self.image_color_value = preset_colors[i]
self.stretch_function_value = "arcsinh"
self.stretch_preset_value = 99
self.image_opacity.unmix_state(default_opacity)
self.image_color.unmix_state(preset_colors[i])
self.stretch_function.unmix_state("arcsinh")
self.stretch_preset.unmix_state(99)

self.layer_selected = initial_layer

Expand Down
Loading

0 comments on commit 2a09293

Please sign in to comment.