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

Reverse intensity #219

Merged
merged 13 commits into from
Jun 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion omero_figure/scripts/omero/figure_scripts/Figure_To_Pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,7 @@ def apply_rdefs(self, image, channels):
c_idxs = []
windows = []
colors = []
reverses = []

# OMERO.figure doesn't support greyscale rendering
image.setColorRenderingModel()
Expand All @@ -764,8 +765,9 @@ def apply_rdefs(self, image, channels):
c_idxs.append(i+1)
windows.append([c['window']['start'], c['window']['end']])
colors.append(c['color'])
reverses.append(c['reverseIntensity'])

image.setActiveChannels(c_idxs, windows, colors)
image.setActiveChannels(c_idxs, windows, colors, reverses)

def get_crop_region(self, panel):
"""
Expand Down
40 changes: 27 additions & 13 deletions omero_figure/static/figure/css/figure.css
Original file line number Diff line number Diff line change
Expand Up @@ -351,10 +351,10 @@
width:100%;
}

.glyphicon-ok {
.previewIdChange .glyphicon-ok {
color: #0f0;
}
.glyphicon-flag {
.previewIdChange .glyphicon-flag {
color: #f00;
}
/* Classes here are generated in templates from 'top' etc See labelicon classes below */
Expand Down Expand Up @@ -524,6 +524,7 @@
height: 150px;
margin-left: 15px;
margin-top: 35px;
background: #666;
}
.show-rotation {
padding: 5px 2px;
Expand All @@ -549,10 +550,11 @@
position: relative;
}
.ch_slider {
height: 11px !important;
width: 225px !important;
top: -6px;
left: 50px;
height: 12px !important;
width: 170px !important;
top: -2px;
left: 104px;
position: absolute !important;
}
.ch_start, .ch_end {
position: absolute;
Expand All @@ -563,7 +565,9 @@
top: 0px;
}
.ch_start input, .ch_end input {
width: 40px;
width: 45px;
height: 33px;
text-align: center;
}
/* Hide spinner added to 'number' inputs */
input[type='number'] {
Expand All @@ -575,14 +579,12 @@
margin: 0;
}
.ch_start {
left: 4px;
left: 54px;
text-align: right;
width: 30px;
}
.ch_end {
right: 12px;
text-align: left;
width: 30px;
right: 0;
}
.ui-slider-disabled a {
display: none;
Expand Down Expand Up @@ -733,6 +735,11 @@
border: solid 1px #bbb;
}

/* remove border from above */
.colorpicker .reverseIntensity span {
border-width: 0;
}

.lutOption {
text-align: left;
}
Expand All @@ -742,10 +749,17 @@
display: inline-block;
}

.lutBg, .ch_slider .ui-slider-range {
.ch_slider .ui-slider-range {
background-image: url('../images/gradient.png');
background-size: 100% 50px;
background-position: 0 0;
background-repeat: no-repeat;
}

.lutBg, .ch_slider .lutBg {
/* NB: when updating png, consider using different name to avoid cache */
background-image: url('../images/luts_10.png'); /* each lut is 10px high */
background-size: 100% 1850px; /* height is stretched 5x (50px per LUT) */
background-size: 100% 1950px; /* height is stretched 5x (50px per LUT) */
background-repeat: no-repeat;
}

Expand Down
Binary file added omero_figure/static/figure/images/gradient.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified omero_figure/static/figure/images/luts_10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions omero_figure/templates/figure/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -743,22 +743,22 @@ <h4 class="modal-title">Open</h4>
<!-- NB: data-export-option attr used to label export button & handled by js on click -->
<li><a href="#" data-export-option="PDF"
title="Export figure as PDF">
<span class="glyphicon glyphicon-ok" style="color:#333"></span>
<span class="glyphicon glyphicon-ok"></span>
PDF</a>
</li>
<li><a href="#" data-export-option="PDF & images"
title="Export as PDF, in zip with panel images">
<span class="glyphicon glyphicon-ok" style="color:#333; visibility:hidden"></span>
<span class="glyphicon glyphicon-ok" style="visibility:hidden"></span>
PDF with images</a>
</li>
<li><a href="#" data-export-option="TIFF"
title="Export figure as a TIFF image per page">
<span class="glyphicon glyphicon-ok" style="color:#333; visibility:hidden"></span>
<span class="glyphicon glyphicon-ok" style="visibility:hidden"></span>
TIFF (300 dpi)</a>
</li>
<li><a href="#" data-export-option="TIFF & images"
title="Export as TIFF, in zip with panel images">
<span class="glyphicon glyphicon-ok" style="color:#333; visibility:hidden"></span>
<span class="glyphicon glyphicon-ok" style="visibility:hidden"></span>
TIFF with images</a>
</li>
<li><a href="#" data-export-option="to OMERO"
Expand Down
15 changes: 9 additions & 6 deletions src/js/models/panel_model.js
Original file line number Diff line number Diff line change
Expand Up @@ -529,25 +529,28 @@
},

get_img_src: function() {
var cStrings = [];
_.each(this.get('channels'), function(c, i){
if (c.active) {
cStrings.push(1+i + "|" + c.window.start + ":" + c.window.end + "$" + c.color);
}
var chs = this.get('channels');
var cStrings = chs.map(function(c, i){
return (c.active ? '' : '-') + (1+i) + "|" + c.window.start + ":" + c.window.end + "$" + c.color;
});
var maps_json = chs.map(function(c){
return {'reverse': {'enabled': !!c.reverseIntensity}};
});
var renderString = cStrings.join(","),
imageId = this.get('imageId'),
theZ = this.get('theZ'),
theT = this.get('theT'),
baseUrl = this.get('baseUrl'),
// stringify json and remove spaces
maps = '&maps=' + JSON.stringify(maps_json).replace(/ /g, ""),
proj = "";
if (this.get('z_projection')) {
proj = "&p=intmax|" + this.get('z_start') + ":" + this.get('z_end');
}
baseUrl = baseUrl || WEBGATEWAYINDEX.slice(0, -1); // remove last /

return baseUrl + '/render_image/' + imageId + "/" + theZ + "/" + theT
+ '/?c=' + renderString + proj + "&m=c";
+ '/?c=' + renderString + proj + maps +"&m=c";
},

// used by the PanelView and ImageViewerView to get the size and
Expand Down
105 changes: 100 additions & 5 deletions src/js/views/channel_slider_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,69 @@ var ChannelSliderView = Backbone.View.extend({
events: {
"keyup .ch_start": "handle_channel_input",
"keyup .ch_end": "handle_channel_input",
"click .channel-btn": "toggle_channel",
"click .dropdown-menu a": "pick_color",
},

pick_color: function(e) {
var color = e.currentTarget.getAttribute('data-color'),
$colorbtn = $(e.currentTarget).parent().parent(),
oldcolor = $(e.currentTarget).attr('data-oldcolor'),
idx = $colorbtn.attr('data-index'),
self = this;

if (color == 'colorpicker') {
FigureColorPicker.show({
'color': oldcolor,
'success': function(newColor){
// remove # from E.g. #ff00ff
newColor = newColor.replace("#", "");
self.set_color(idx, newColor);
}
});
} else if (color == 'lutpicker') {
FigureLutPicker.show({
success: function(lutName){
// LUT names are handled same as color strings
self.set_color(idx, lutName);
}
});
} else if (color == 'reverse') {
var reverse = $('span', e.currentTarget).hasClass('glyphicon-check');
self.models.forEach(function(m){
m.save_channel(idx, 'reverseIntensity', !reverse);
});
} else {
this.set_color(idx, color);
}
return false;
},

set_color: function(idx, color) {
if (this.models) {
this.models.forEach(function(m){
m.save_channel(idx, 'color', color);
});
}
},

toggle_channel: function(e) {
var idx = e.currentTarget.getAttribute('data-index');

if (this.model) {
this.model.toggle_channel(idx);
} else if (this.models) {
// 'flat' means that some panels have this channel on, some off
var flat = $('div', e.currentTarget).hasClass('ch-btn-flat');
this.models.forEach(function(m){
if(flat) {
m.toggle_channel(idx, true);
} else {
m.toggle_channel(idx);
}
});
}
return false;
},

handle_channel_input: function(event) {
Expand Down Expand Up @@ -61,13 +124,24 @@ var ChannelSliderView = Backbone.View.extend({
return ch[idx].color;
}
}
var getReverse = function(idx) {
return function(ch) {
// For older figures (created pre 5.3.0) might be undefined
return ch[idx].reverseIntensity === true;
}
}
var getActive = function(idx) {
return function(ch) {
return ch[idx].active === true;
}
}
var windowFn = function (idx, attr) {
return function (ch) {
return ch[idx].window[attr];
}
};
var allEqualFn = function(prev, value) {
return value === prev ? prev : false;
return value === prev ? prev : undefined;
};
var reduceFn = function(fn) {
return function(prev, curr) {
Expand Down Expand Up @@ -99,16 +173,32 @@ var ChannelSliderView = Backbone.View.extend({
var mins = chData.map(windowFn(chIdx, 'min'));
var maxs = chData.map(windowFn(chIdx, 'max'));
var colors = chData.map(getColor(chIdx));
var reverses = chData.map(getReverse(chIdx));
var actives = chData.map(getActive(chIdx));
// Reduce lists into summary for this channel
var startAvg = parseInt(starts.reduce(addFn, 0) / starts.length, 10);
var endAvg = parseInt(ends.reduce(addFn, 0) / ends.length, 10);
var startsNotEqual = starts.reduce(allEqualFn, starts[0]) === false;
var endsNotEqual = ends.reduce(allEqualFn, ends[0]) === false;
var startsNotEqual = starts.reduce(allEqualFn, starts[0]) === undefined;
var endsNotEqual = ends.reduce(allEqualFn, ends[0]) === undefined;
var min = mins.reduce(reduceFn(Math.min));
var max = maxs.reduce(reduceFn(Math.max));
var color = colors.reduce(allEqualFn, colors[0]) ? colors[0] : 'ccc';
// allEqualFn for booleans will return undefined if not or equal
var reverse = reverses.reduce(allEqualFn, reverses[0]) ? true : false;
var active = actives.reduce(allEqualFn, actives[0]);
var style = {'background-position': '0 0'}
var sliderClass = '';
var lutBgPos = FigureLutPicker.getLutBackgroundPosition(color);
if (color.toUpperCase() === "FFFFFF") color = "ccc"; // white slider would be invisible
if (color.endsWith('.lut')) {
style['background-position'] = lutBgPos;
sliderClass = 'lutBg';
} else if (color.toUpperCase() === "FFFFFF") {
color = "ccc"; // white slider would be invisible
}
if (reverse) {
style.transform = 'scaleX(-1)';
}
if (color == "FFFFFF") color = "ccc"; // white slider would be invisible

// Make sure slider range is increased if needed to include current values
min = Math.min(min, startAvg);
Expand All @@ -119,6 +209,9 @@ var ChannelSliderView = Backbone.View.extend({
'startsNotEqual': startsNotEqual,
'endAvg': endAvg,
'endsNotEqual': endsNotEqual,
'active': active,
'lutBgPos': lutBgPos,
'reverse': reverse,
'color': color});
var $div = $(sliderHtml).appendTo(this.$el);

Expand All @@ -138,7 +231,9 @@ var ChannelSliderView = Backbone.View.extend({
}
})
// Need to add background style to newly created div.ui-slider-range
.children('.ui-slider-range').css('background-position', lutBgPos)
.children('.ui-slider-range').css(style)
.addClass(sliderClass);

}.bind(this));
return this;
}
Expand Down
2 changes: 2 additions & 0 deletions src/js/views/lutpicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ var LutPickerView = Backbone.View.extend({
"orange_hot.lut",
"phase.lut",
"physics.lut",
"pup_br.lut",
"pup_nr.lut",
"rainbow_rgb.lut",
"red-green.lut",
"red_hot.lut",
Expand Down
Loading