Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Horizontal layer buttons #2566

Merged
merged 33 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
bf22850
Layers now represented as horizontal buttons
javerbukh Nov 3, 2023
2de03cf
Fix codestyle
javerbukh Nov 14, 2023
6483a01
Fix codestlye and remove comments
javerbukh Nov 14, 2023
3c31e18
Viewer multiselect mixed state working
javerbukh Nov 14, 2023
9ab3162
Working on handling edge cases of mixed state
javerbukh Nov 15, 2023
f34e42b
Use messages in LayerSelect to call parts of _on_layers_changed
javerbukh Nov 16, 2023
1fd124f
Remove unused elements
javerbukh Nov 16, 2023
1ef9bdb
Fix button colors not updating after unmix state
javerbukh Nov 16, 2023
93ce319
Fix codestyle
javerbukh Nov 16, 2023
fdf0703
Attempt 2 at fixing code style
javerbukh Nov 16, 2023
85c1a3b
Fix CI, put buttons in icon order
javerbukh Nov 16, 2023
7b2ef3d
Code style again
javerbukh Nov 16, 2023
10aaa91
Fix more tests
javerbukh Nov 16, 2023
60ad145
Everything handled by _on_layers_changed
javerbukh Nov 17, 2023
639eb87
button styling/tooltip based on (mixed)-color/visibility
kecnry Nov 17, 2023
17f4e33
improve tab styling
kecnry Nov 17, 2023
e4650ff
avoid second loop when applying RGB presets
kecnry Nov 17, 2023
f9640e0
improved handling of colormap and mixed colormode
kecnry Nov 17, 2023
9a3c30e
remove elevation
kecnry Nov 17, 2023
d3baec2
use all_color_to_label in tab styling
kecnry Nov 17, 2023
939d3be
Mixed visibility and color represented in button
javerbukh Nov 17, 2023
611ea92
improved handling of subset color when in colormap
kecnry Nov 17, 2023
1f56e99
improved dark-theme support
kecnry Nov 17, 2023
fb64d0f
tooltip and RGB preset support for mixed visibility
kecnry Nov 17, 2023
fd4353d
Visible is set to layer visible and bitmap visible
javerbukh Nov 17, 2023
5d50565
avoid displacement when no tabs selected
kecnry Nov 17, 2023
f0a7966
Fix CI tests
javerbukh Nov 17, 2023
37c9605
RGB presets: handle unmixing state
kecnry Nov 17, 2023
10d1f20
Address review comments
javerbukh Nov 17, 2023
02661cc
Forgot one change
javerbukh Nov 17, 2023
a0e8ee2
for styling, always check if item in list, not as substring
kecnry Nov 20, 2023
bea110d
Update changelog
javerbukh Nov 20, 2023
32a75df
Add tests
javerbukh Nov 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ New Features

- Add button in Plot Options to apply preset RBG options to visible layers when in Monochromatic mode. [#2558]

- 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 @@ -626,13 +626,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
Comment on lines +629 to +630
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rosteen - does this change make sense to you? Now that we have this info already parsed, we can avoid the double-loop and can explicitly handle the mixed case - this means that if a layer is visible in one selected viewer, but not all, it will still be included in the logic. The alternative would be to only act all layers visible in all selected viewers, but I think you said you intended for this behavior, right?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine to me, and yeah I preferred updating all visible layers in any selected viewer.


# 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
Loading