Skip to content

Commit

Permalink
Merge pull request #575 from Tom-TBT/labelsort
Browse files Browse the repository at this point in the history
Label sorting with drag and drop
  • Loading branch information
will-moore authored Jul 11, 2024
2 parents 6456608 + 0496175 commit fefe87c
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 13 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"marked": "^4.2.12",
"mousetrap": "^1.6.5",
"raphael": "^2.3.0",
"sortablejs": "^1.15.2",
"underscore": "^1.13.4"
}
}
10 changes: 7 additions & 3 deletions src/css/figure.css
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
/* copied these from previous figure (Bootstrap 3.0.0) */
.btn-default {
/* only used for default buttons. Overridden for other buttons */
/* .btn-default class is still on lots of buttons (legacy from bootstrap 3.0.0)
/* .btn-default class is still on lots of buttons (legacy from bootstrap 3.0.0)
but now has no effect */
--bs-btn-border-color: #cccccc;;
}
Expand Down Expand Up @@ -84,7 +84,7 @@
}

.pixelated {
/* Try to show images in their original pixelated form Although 'pixelated' isn't
/* Try to show images in their original pixelated form Although 'pixelated' isn't
supported yet: https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering
Code from http://phrogz.net/tmp/canvas_image_zoom.html */
image-rendering:optimizeSpeed; /* Legal fallback */
Expand Down Expand Up @@ -767,7 +767,7 @@
/*Edge starts the margin from the thumb, not the track as other browsers do*/
}
}

#vp_z_slider input[type="range"], #vp_t_slider input[type="range"] {
background-color: #bbbbbb;
margin: 0;
Expand Down Expand Up @@ -1320,3 +1320,7 @@
#openFigureModal a {
text-decoration: none;
}

.form-inline{
cursor: move;
}
9 changes: 4 additions & 5 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>OMERO.figure</title>

<script>
// For dev, use this server to load/save figures (needs CORS enabled)
const dev_omeroweb_url = "http://localhost:4080/";
Expand Down Expand Up @@ -876,13 +875,13 @@ <h5 class="modal-title">Label Formatting</h5>
<h4>Markdown formatting</h4>
<p>
You can use "Markdown" syntax to add formatting to plain text. For
example, **this text will be bold** and this *word* will be italic.
example, **this text will be bold** and this *word* will be italic.
</p>
<p>
NB: Links are not supported for panel labels.
</p>
<p>
NB: You can escape a certain character to not be interpreted as Markdown by adding \ in front of the
NB: You can escape a certain character to not be interpreted as Markdown by adding \ in front of the
character. Ex: "my_string_" is interpreted as "my<i>string</i>" but "my\_string\_" is now interpreted as "my_string_"
</p>

Expand Down Expand Up @@ -1155,7 +1154,7 @@ <h5 class="modal-title">Labels from Key-Value Pairs</h5>
</div>
<form class="labelsFromMapAnnsForm" role="form">
<div class="modal-body">
<div>
<div>
<input type="radio" id="all-keys" name="kvpChoice" value="all-keys" />
<label for="all-keys">All Keys </label>

Expand Down Expand Up @@ -1823,7 +1822,7 @@ <h5>Example Label</h5>
<div class="row">
<div class="col-2 no-padding" id="channelToggle"></div>
<div class="col-10 no-padding" id="viewportContainer">

</div>
</div>
<div class="clearfix" style="padding-bottom: 13px"></div>
Expand Down
92 changes: 88 additions & 4 deletions src/js/views/right_panel_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import Backbone from "backbone";
import _ from "underscore";
import $ from "jquery";
import Sortable from 'sortablejs';

import {figureConfirmDialog, showModal, rotatePoint} from "./util";
import FigureColorPicker from "../views/colorpicker";
Expand Down Expand Up @@ -453,7 +454,7 @@
$("#selected_panels_labels").empty().append(this.sel_labels_panel.$el);
}
if (old) {
old.remove();
old.clear().remove();
}

// show scalebar form for selected panels
Expand Down Expand Up @@ -548,6 +549,90 @@
return false;
},

initialize_sortable: function() {
var self = this;
var containers = self.$el.find('.labels-container');

// Check if there are any elements
if (containers.length === 0) {
return;
}

// Destroy existing Sortable instances if any
if (self.sortables) {
self.sortables.forEach(function(sortable) {
sortable.destroy();
});
}
self.sortables = [];

// Initialize Sortable for each container
containers.each(function(index, el) {
var sortable = new Sortable(el, {
animation: 150,
fallbackOnBody: true,
onMove: function(evt) {
// Allow dragging outside the container
return evt.related === null || evt.related !== evt.from;
},
onEnd: function(evt) {
self.handle_sort(evt);
}
});

// Store the sortable instance
self.sortables.push(sortable);
});
},

clear: function() {
// clean up the sortable
if (this.sortables) {
this.sortables.forEach(function(sortable) {
sortable.destroy();
});
}
this.sortables = [];
return this;
},

handle_sort: function(evt) {
var container = evt.srcElement; // Get the object that triggered the event   

// Extract label keys in the new order of that position set
var forms = container.querySelectorAll('.edit-label-form');
var reordered_keys = Array.from(forms).map(form => form.getAttribute('data-key'));
var position = reordered_keys[0].split("_").pop();

// Update the order of labels in each panel
this.models.forEach(function(panelModel) {
var labels = panelModel.get('labels');
var labels_dict = {}; // Labels for the current position set
var leftover_labels = []; // The labels at other positions
for (let i = 0; i < labels.length; i++) {
// Generate a list of labels matching reordered_keys format
var l = labels[i];
if (l["position"] == position) {
var key = [l["text"], l["size"], l["color"], l["position"]].join("_");
labels_dict[key] = l;
} else {
leftover_labels.push(l);
}
}

var reordered_labels = [];
for (let i = 0; i < reordered_keys.length; i++) {
// For each key in result after sorting, check if exist for the panel
if(reordered_keys[i] in labels_dict) {
reordered_labels.push(labels_dict[reordered_keys[i]]);
delete labels_dict[reordered_keys[i]];
}
}
reordered_labels.push(...leftover_labels);
panelModel.set('labels', reordered_labels);
});
},

render: function() {

var self = this,
Expand Down Expand Up @@ -581,7 +666,7 @@
html += self.template(json);
});
self.$el.append(html);

this.initialize_sortable();
return this;
}
});
Expand Down Expand Up @@ -637,7 +722,6 @@
});

this.$vp_zoom_value = $("#vp_zoom_value");


// We nest the ZoomView so we can update it on update_img_css
this.zmView = new ZoomView({models: this.models,
Expand Down Expand Up @@ -701,7 +785,7 @@
return; // Ignore keyups except 'Enter'
}

// get the current entered value
// get the current entered value
var value = parseInt(event.target.value);
if (isNaN(value)) {
return;
Expand Down
2 changes: 1 addition & 1 deletion src/templates/labels_form.template.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

<div class="">
<div class="labels-container">

<% _.each(labels, function(l, i) { %>

Expand Down

0 comments on commit fefe87c

Please sign in to comment.