Files
enviPy-bayer/static/js/ketcher2/script/render/restruct/rergroup.js
2025-06-23 20:13:54 +02:00

199 lines
6.9 KiB
JavaScript

/****************************************************************************
* Copyright 2017 EPAM Systems
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
***************************************************************************/
var Box2Abs = require('../../util/box2abs');
var Vec2 = require('../../util/vec2');
var util = require('../util');
var draw = require('../draw');
var scale = require('../../util/scale');
var ReObject = require('./reobject');
var BORDER_EXT = new Vec2(0.05 * 3, 0.05 * 3);
function ReRGroup(/* Struct.RGroup*/rgroup) {
this.init('rgroup');
this.labelBox = null;
this.item = rgroup;
}
ReRGroup.prototype = new ReObject();
ReRGroup.isSelectable = function () {
return false;
};
ReRGroup.prototype.getAtoms = function (render) {
var ret = [];
this.item.frags.each(function (fnum, fid) {
ret = ret.concat(render.ctab.frags.get(fid).fragGetAtoms(render, fid));
});
return ret;
};
ReRGroup.prototype.getBonds = function (render) {
var ret = [];
this.item.frags.each(function (fnum, fid) {
ret = ret.concat(render.ctab.frags.get(fid).fragGetBonds(render, fid));
});
return ret;
};
ReRGroup.prototype.calcBBox = function (render) {
var ret;
this.item.frags.each(function (fnum, fid) {
var bbf = render.ctab.frags.get(fid).calcBBox(render.ctab, fid, render);
if (bbf)
ret = (ret ? Box2Abs.union(ret, bbf) : bbf);
});
ret = ret.extend(BORDER_EXT, BORDER_EXT); // eslint-disable-line no-underscore-dangle
return ret;
};
function rGroupdrawBrackets(set, render, bb, d) {
d = scale.obj2scaled(d || new Vec2(1, 0), render.options);
var bracketWidth = Math.min(0.25, bb.sz().x * 0.3);
var bracketHeight = bb.p1.y - bb.p0.y;
var cy = 0.5 * (bb.p1.y + bb.p0.y);
var leftBracket = draw.bracket(render.paper, d.negated(),
d.negated().rotateSC(1, 0),
scale.obj2scaled(new Vec2(bb.p0.x, cy), render.options),
bracketWidth, bracketHeight, render.options);
var rightBracket = draw.bracket(render.paper, d, d.rotateSC(1, 0),
scale.obj2scaled(new Vec2(bb.p1.x, cy), render.options),
bracketWidth, bracketHeight, render.options);
return set.push(leftBracket, rightBracket);
}
// TODO need to review parameter list
ReRGroup.prototype.draw = function (render, options) { // eslint-disable-line max-statements
var bb = this.calcBBox(render);
if (bb) {
var ret = { data: [] };
var p0 = scale.obj2scaled(bb.p0, options);
var p1 = scale.obj2scaled(bb.p1, options);
var brackets = render.paper.set();
rGroupdrawBrackets(brackets, render, bb); // eslint-disable-line new-cap
ret.data.push(brackets);
var key = render.ctab.rgroups.keyOf(this);
var labelSet = render.paper.set();
var label = render.paper.text(p0.x, (p0.y + p1.y) / 2, 'R' + key + '=')
.attr({
'font': options.font,
'font-size': options.fontRLabel,
'fill': 'black'
});
var labelBox = util.relBox(label.getBBox());
/* eslint-disable no-mixed-operators*/
label.translateAbs(-labelBox.width / 2 - options.lineWidth, 0);
/* eslint-enable no-mixed-operators*/
labelSet.push(label);
var logicStyle = {
'font': options.font,
'font-size': options.fontRLogic,
'fill': 'black'
};
var logic = [];
// TODO [RB] temporary solution, need to review
// BEGIN
/*
if (this.item.range.length > 0)
logic.push(this.item.range);
if (this.item.resth)
logic.push("RestH");
if (this.item.ifthen > 0)
logic.push("IF R" + key.toString() + " THEN R" + this.item.ifthen.toString());
*/
logic.push(
(this.item.ifthen > 0 ? 'IF ' : '') +
'R' + key.toString() +
/* eslint-disable no-nested-ternary */
(this.item.range.length > 0 ?
this.item.range.startsWith('>') || this.item.range.startsWith('<') || this.item.range.startsWith('=') ?
this.item.range : '=' + this.item.range : '>0') +
(this.item.resth ? ' (RestH)' : '') +
(this.item.ifthen > 0 ? '\nTHEN R' + this.item.ifthen.toString() : '')
/* eslint-enable no-nested-ternary */
);
// END
/* eslint-disable no-mixed-operators*/
var shift = labelBox.height / 2 + options.lineWidth / 2;
/* eslint-enable no-mixed-operators*/
for (var i = 0; i < logic.length; ++i) {
var logicPath = render.paper.text(p0.x, (p0.y + p1.y) / 2, logic[i]).attr(logicStyle);
var logicBox = util.relBox(logicPath.getBBox());
shift += logicBox.height / 2;
/* eslint-disable no-mixed-operators*/
logicPath.translateAbs(-logicBox.width / 2 - 6 * options.lineWidth, shift);
shift += logicBox.height / 2 + options.lineWidth / 2;
/* eslint-enable no-mixed-operators*/
ret.data.push(logicPath);
labelSet.push(logicPath);
}
ret.data.push(label);
this.labelBox = Box2Abs.fromRelBox(labelSet.getBBox()).transform(scale.scaled2obj, render.options);
return ret;
} else { // eslint-disable-line no-else-return
// TODO abnormal situation, empty fragments must be destroyed by tools
return {};
}
};
// TODO need to review parameter list
ReRGroup.prototype._draw = function (render, rgid, attrs) { // eslint-disable-line no-underscore-dangle
var bb = this.getVBoxObj(render).extend(BORDER_EXT, BORDER_EXT); // eslint-disable-line no-underscore-dangle
if (bb) {
var p0 = scale.obj2scaled(bb.p0, render.options);
var p1 = scale.obj2scaled(bb.p1, render.options);
return render.paper.rect(p0.x, p0.y, p1.x - p0.x, p1.y - p0.y, 0).attr(attrs);
}
};
ReRGroup.prototype.drawHighlight = function (render) {
var rgid = render.ctab.rgroups.keyOf(this);
if (!(typeof rgid === 'undefined')) {
var ret = this._draw(render, rgid, render.options.highlightStyle/* { 'fill' : 'red' }*/); // eslint-disable-line no-underscore-dangle
render.ctab.addReObjectPath('highlighting', this.visel, ret);
/*
this.getAtoms(render).each(function(aid) {
render.ctab.atoms.get(aid).drawHighlight(render);
}, this);
*/
this.item.frags.each(function (fnum, fid) {
render.ctab.frags.get(fid).drawHighlight(render);
}, this);
return ret;
} else { // eslint-disable-line no-else-return
// TODO abnormal situation, fragment does not belong to the render
}
};
ReRGroup.prototype.show = function (restruct, id, options) {
var drawing = this.draw(restruct.render, options);
for (var group in drawing) {
if (drawing.hasOwnProperty(group)) {
while (drawing[group].length > 0)
restruct.addReObjectPath(group, this.visel, drawing[group].shift(), null, true);
}
}
// TODO rgroup selection & highlighting
};
module.exports = ReRGroup;