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

Add dropdown to enable drawing shapes with fixed aspect ratios/sizes #197

Merged
merged 4 commits into from
Jul 22, 2022
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
85 changes: 64 additions & 21 deletions histomicsui/web_client/panels/DrawWidget.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,10 @@ var DrawWidget = Panel.extend({
'click .h-draw': 'drawElement',
'change .h-style-group': '_setToSelectedStyleGroup',
'change .h-brush-shape,.h-brush-size,.h-brush-screen': '_changeBrush',
'change .h-fixed-shape,.h-fixed-height,.h-fixed-width': '_changeShapeConstraint',
'click .h-configure-style-group': '_styleGroupEditor',
'mouseenter .h-element': '_highlightElement',
'mouseleave .h-element': '_unhighlightElement',
'show.bs.collapse': 'expand',
'hide.bs.collapse': 'collapse',
'click .h-dropdown-title': '_dropdownControlClick'
}),

Expand Down Expand Up @@ -143,6 +142,7 @@ var DrawWidget = Panel.extend({
}
});
}
this._updateConstraintValueInputs();
return this;
},

Expand Down Expand Up @@ -593,7 +593,15 @@ var DrawWidget = Panel.extend({
// always show the active annotation when drawing a new element
this.annotation.set('displayed', true);
this._drawingType = type;
this.viewer.startDrawMode(type)

const options = { modeOptions: {} };
if (this._editOptions.size_mode === 'fixed_aspect_ratio') {
options.modeOptions.constraint = this._editOptions.fixed_width / this._editOptions.fixed_height;
} else if (this._editOptions.size_mode === 'fixed_size') {
options.modeOptions.constraint = { width: this._editOptions.fixed_width, height: this._editOptions.fixed_height };
}

this.viewer.startDrawMode(type, options)
.then((element, annotations, opts) => this._addDrawnElements(element, annotations, opts));
}
this.$('button.h-draw[data-type]').removeClass('active');
Expand Down Expand Up @@ -685,6 +693,9 @@ var DrawWidget = Panel.extend({
if (!opts.brush_size || !(parseFloat(opts.brush_size) > 0)) {
opts.brush_size = 50;
}
if (!opts.size_mode) {
opts.size_mode = 'unconstrained';
}
},

/**
Expand Down Expand Up @@ -716,28 +727,26 @@ var DrawWidget = Panel.extend({
/**
* For a dropdown control widget, handle expanding and collapsing.
*
* TODO: When we have multiple such widgets, we should close all but the
* current widget.
*
* @param {jquery.Event} e The event that triggered this toggle.
*/
_dropdownControlClick(e) {
e.stopImmediatePropagation();
$(e.target).parent().find('.h-dropdown-content').collapse('toggle');
},

/**
* Update the icon when a dropdown control group expands.
*/
expand() {
this.$('.icon-down-open').attr('class', 'icon-up-open');
},

/**
* Update the icon when a dropdown control group closes.
*/
collapse() {
this.$('.icon-up-open').attr('class', 'icon-down-open');
const content = $(e.target).parent().find('.h-dropdown-content');
const isCollapsed = !content.hasClass('in');
const buttons = $(e.target).closest('.h-draw-tools').find('.btn-group');
buttons.find('.h-dropdown-content').each((idx, dropdown) => {
dropdown = $(dropdown);
if (!dropdown.is(content) && dropdown.hasClass('in')) {
dropdown.collapse('toggle');
dropdown.parent().find('.icon-up-open').removeClass('icon-up-open').addClass('icon-down-open');
}
});
content.collapse('toggle');
$(e.target).find('.icon-down-open,.icon-up-open').removeClass(
isCollapsed ? 'icon-down-open' : 'icon-up-open').addClass(
isCollapsed ? 'icon-up-open' : 'icon-down-open');
// Select the corresponding radio button for the current size_mode
$(`input[mode="${this._editOptions.size_mode || 'unconstrained'}"]`, $(e.target.parentNode)).trigger('click');
},

/**
Expand All @@ -756,6 +765,40 @@ var DrawWidget = Panel.extend({
}
},

/**
* Show or hide width/height input depending on the currently selected drawing mode.
*/
_updateConstraintValueInputs() {
if (['fixed_aspect_ratio', 'fixed_size'].includes(this.$('.h-fixed-shape:checked').attr('mode'))) {
this.$('.h-fixed-values').show();
} else {
this.$('.h-fixed-values').hide();
}
},

/**
* Update the width/height constraint for a shape being drawn with a fixed
* aspect ratio or fixed size.
*/
_changeShapeConstraint(evt) {
const opts = {
size_mode: this.$('.h-fixed-shape:checked').attr('mode'),
fixed_width: parseFloat(this.$('.h-fixed-width').val()),
fixed_height: parseFloat(this.$('.h-fixed-height').val())
};
this._saveEditOptions(opts);

this._updateConstraintValueInputs();

if (opts.size_mode === 'fixed_aspect_ratio') {
this.viewer.startDrawMode(this._drawingType, { modeOptions: { constraint: opts.fixed_width / opts.fixed_height } });
} else if (opts.size_mode === 'fixed_size') {
this.viewer.startDrawMode(this._drawingType, { modeOptions: { constraint: { width: opts.fixed_width, height: opts.fixed_height } } });
} else {
this.viewer.startDrawMode(this._drawingType);
}
},

/**
* Cycle through available brush shapes.
*/
Expand Down
10 changes: 10 additions & 0 deletions histomicsui/web_client/stylesheets/panels/drawWidget.styl
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,16 @@
width 165px
.h-brush-size
width 60px
.h-fixed-shape-controls
@extend .h-brush-controls
z-index 10
padding 0 25%
.h-fixed-shape-form-group
height 100%
.h-fixed-width
width 50%
.h-fixed-height
width 50%

.flattenicon:before
transform: scale(1, 0.67)
40 changes: 40 additions & 0 deletions histomicsui/web_client/templates/panels/drawWidget.pug
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,50 @@ block content
button.h-draw.btn.btn-default(
type='button', data-type='rectangle', title='Draw a new rectangle (keyboard shortcut: r)', class=drawingType === 'rectangle' ? 'active' : null)
| #[span.icon-check-empty]Rectangle
button.btn.btn-default.h-dropdown-title.h-brush-dropdown(type='button', data-target='#h-fixed-shape-controls')
i.icon-down-open
.h-fixed-shape-controls.h-dropdown-content.collapse
.form-group.h-fixed-shape-form-group.input-sm
label.radio
input.h-fixed-shape(type="radio", name="h-fixed-shape", mode="unconstrained")
| Unconstrained
label.radio
input.h-fixed-shape(type="radio", name="h-fixed-shape", mode="fixed_aspect_ratio")
| Fixed Aspect Ratio
label.radio
input.h-fixed-shape(type="radio", name="h-fixed-shape", mode="fixed_size")
| Fixed Size
.form-group.h-fixed-shape-form-group.h-fixed-values.input-sm
label
| Width
input.h-fixed-width(type="number", min="1", value=opts.fixed_width)
label
| Height
input.h-fixed-height(type="number", min="1", value=opts.fixed_height)
.btn-group.btn-group-sm
button.h-draw.btn.btn-default(
type='button', data-type='ellipse', title='Draw a new ellipse (keyboard shortcut: i)', class=drawingType === 'ellipse' ? 'active' : null)
| #[span.icon-circle-empty.flattenicon]Ellipse
button.btn.btn-default.h-dropdown-title.h-brush-dropdown(type='button', data-target='#h-fixed-shape-controls')
i.icon-down-open
.h-fixed-shape-controls.h-dropdown-content.collapse
.form-group.h-fixed-shape-form-group.input-sm
label.radio
input.h-fixed-shape(type="radio", name="h-fixed-shape", mode="unconstrained")
| Unconstrained
label.radio
input.h-fixed-shape(type="radio", name="h-fixed-shape", mode="fixed_aspect_ratio")
| Fixed Aspect Ratio
label.radio
input.h-fixed-shape(type="radio", name="h-fixed-shape", mode="fixed_size")
| Fixed Size
.form-group.h-fixed-shape-form-group.h-fixed-values.input-sm
label
| Width
input.h-fixed-width(type="number", min="1", value=opts.fixed_width)
label
| Height
input.h-fixed-height(type="number", min="1", value=opts.fixed_height)
.btn-group.btn-group-sm
button.h-draw.btn.btn-default(
type='button', data-type='circle', title='Draw a new circle (keyboard shortcut: c)', class=drawingType === 'circle' ? 'active' : null)
Expand Down