kekule
Version:
Open source JavaScript toolkit for chemoinformatics
706 lines (657 loc) • 33.4 kB
JavaScript
/**
* @fileoverview
* Configurations of base editors.
* @author Partridge Jiang
*/
/*
* requires /lan/classes.js
* requires /core/kekule.common.js
* requires /core/kekule.configs.js
* requires /utils/kekule.utils.js
* requires /widgets/kekule.widget.sys.js
* requires /widgets/chem/kekule.chemWidget.chemObjDisplayers.js
* requires /widgets/chem/editor/kekule.chemEditor.editorUtils.js
*/
(function(){
"use strict";
var PS = Class.PropertyScope;
/**
* Config class of base editor (class {@link Kekule.Editor.BaseEditor}).
* @class
* @augments Kekule.ChemWidget.ChemObjDisplayerConfigs
*
* @property {Kekule.EditorConfigs.UiMarkerConfigs} uiMarkerConfigs
* @property {Kekule.EditorConfigs.InteractionConfigs} interactionConfigs
* @property {Kekule.Editor.StructureConfigs} structureConfigs
*/
Kekule.Editor.BaseEditorConfigs = Class.create(Kekule.ChemWidget.ChemObjDisplayerConfigs,
/** @lends Kekule.Editor.BaseEditorConfigs# */
{
/** @private */
CLASS_NAME: 'Kekule.Editor.BaseEditorConfigs',
/** @private */
initProperties: function()
{
this.addConfigProp('uiMarkerConfigs', 'Kekule.EditorConfigs.UiMarkerConfigs');
this.addConfigProp('interactionConfigs', 'Kekule.EditorConfigs.InteractionConfigs');
this.addConfigProp('structureConfigs', 'Kekule.Editor.StructureConfigs');
this.addConfigProp('hotKeyConfigs', 'Kekule.Editor.HotKeyConfigs');
},
/** @private */
initPropValues: function(/*$super*/)
{
this.tryApplySuper('initPropValues') /* $super() */;
this.setPropStoreFieldValue('uiMarkerConfigs', new Kekule.Editor.UiMarkerConfigs());
this.setPropStoreFieldValue('interactionConfigs', new Kekule.Editor.InteractionConfigs());
this.setPropStoreFieldValue('structureConfigs', new Kekule.Editor.StructureConfigs());
this.setPropStoreFieldValue('hotKeyConfigs', new Kekule.Editor.HotKeyConfigs());
}
});
/**
* Config class of chem space editor (class {@link Kekule.Editor.ChemSpaceEditor}).
* @class
* @augments Kekule.Editor.BaseEditorConfigs
*
* @property {Kekule.Editor.ChemSpaceConfigs} chemSpaceConfigs
*/
Kekule.Editor.ChemSpaceEditorConfigs = Class.create(Kekule.Editor.BaseEditorConfigs,
/** @lends Kekule.Editor.ChemSpaceEditorConfigs# */
{
/** @private */
CLASS_NAME: 'Kekule.Editor.ChemSpaceEditorConfigs',
/** @private */
initProperties: function()
{
this.addConfigProp('chemSpaceConfigs', 'Kekule.Editor.ChemSpaceConfigs');
this.addConfigProp('styleSetterConfigs', 'Kekule.Editor.StyleSetterConfigs', undefined, {'scope': PS.PUBLIC});
this.addConfigProp('chemConditionSetterConfigs', 'Kekule.Editor.ChemConditionSetterConfigs', undefined, {'scope': PS.PUBLIC})
},
/** @private */
initPropValues: function(/*$super*/)
{
this.tryApplySuper('initPropValues') /* $super() */;
this.setPropStoreFieldValue('chemSpaceConfigs', new Kekule.Editor.ChemSpaceConfigs());
this.setPropStoreFieldValue('styleSetterConfigs', new Kekule.Editor.StyleSetterConfigs());
this.setPropStoreFieldValue('chemConditionSetterConfigs', new Kekule.Editor.ChemConditionSetterConfigs());
}
});
Kekule.ClassUtils.makeSingleton(Kekule.Editor.ChemSpaceEditorConfigs);
/**
* Configs of interaction between user and editor.
* @class
* @augments Kekule.AbstractConfigs
*
* @property {Float} editorInitialZoom Initial zoom level of chem editor.
* @property {Bool} scrollToObjAfterLoading Whether automatically scroll to the newly loaded chem object in editor.
* @property {Bool} autoExpandClientSizeAfterLoading Whether automatically enlarge the editor size to display all chem objects after loading.
* @property {Bool} autoExpandClientSizeAfterManipulation Whether automatically enlarge the editor size to display all chem objects after manipulating.
* @property {Bool} enableTrackOnNearest If true, hot track or selection will focus on object nearest to coord,
* otherwise, focus on topmost object around coord.
* @property {Bool} enableHotTrack Whether highlighting objects under mouse when mouse moves over editor.
* @property {Bool} autoSelectNewlyInsertedObjects Whether select objects newly inserted by mouse or pen into editor by IA controllers automatically.
* @property {Bool} autoSelectNewlyInsertedObjectsOnTouch Whether select objects newly inserted by touch into editor by IA controllers automatically.
* @property {Int} objBoundTrackMinInflation The bound of object will usually be inflated to make it easier to select. This value controls the minimal inflating degree.
* @property {Int} selectionMarkerInflation Inflation of selection marker, makes it easier to see the containing objects.
* @property {Int} selectionMarkerEdgeInflation Inflation when judging if a coord is on selection marker edge.
* @property {Int} selectionMarkerDefPulseDuration
* @property {Int} selectionMarkerDefPulseCount
* @property {Int} selectionCurveSimplificationDistanceThreshold Distance threshold to simplify the selecting curve.
* @property {Int} rotationRegionInflation A circle with this ratio outside selection area marker will be regarded as rotation region.
* @property {Float} constrainedRotateStep In constrained rotate mode, rotation angle will only be times of this value.
* @property {Int} rotationLocationPointDistanceThreshold Rotate will occur only when mouse point distance (from rotation center) larger than this value
* (too small distance will cause very sharp rotation).
* @property {Int} directedMoveDistanceThreshold Directed moving will only be done if moved distance large than this value.
* @property {Bool} enablePartialAreaSelecting If this value is true, when drag a selecting rubber band, object partial in the band will also be selected.
* @property {Bool} enableMergePreview When set to true, a preview of merge (instead of actual merge) will be displayed during manipulation of chem objects.
* Set this value to true will improve the performance of chem editor.
* @property {Bool} enableMagneticMerge Whether nearing node will be merged when moving their position.
* @property {Bool} enableNodeMerge Whether node merging is allowed.
* @property {Bool} enableNeighborNodeMerge Whether neighboring node merging is allowed.
* @property {Bool} enableConnectorMerge Whether connector merging is allowed.
* @property {Bool} enableStructFragmentMerge Whether node or connector merging between different molecule is allowed.
* @property {Bool} enableCascadeRemoveOrphanNeighborChemNode When deleting a chem node (and its linked connectors) in editor, whether its neighbor with no linked connector after deleting will also be removed.
* @property {Bool} enablePreserveLastOrphanNeighborChemNode When deleting a chem node (and its linked connectors), if its neighbor is the last node in molecule, whether this last node should be preserved.
* If this property is true, it is much easier to input single main atom molecule (e.g., CH4, OH2) in editor.
*
* @property {Bool} followPointerCoordOnDirectManipulatingSingleObj If true, the new coord of manipulating object will be set directly by the position of pointer (rather than the delta coord to the original position).
* @property {Bool} enableOffSelectionManipulation If true, holding pointer down outside selection region for a while
* will enter the manipulation state to move the selected objects.
* @property {Int} OffSelectionManipulationActivatingTimeThreshold Holding pointer down longer then this time (in ms) may
* invoker off selection manipulation.
* @property {Bool} enableGestureManipulation Whether using pinch/rotate gesture to manipulate selected objects is allowed.
* @property {Bool} enableGestureZoomOnEditor Whether using pinch gesture change the zoom level of editor is allowed.
* @property {Bool} enableHotKey Whether using hot key in editor is allowed.
* @property {Float} unmovePointerDistanceThreshold When moving less than this distance, pointer will be regarded as still.
* @property {Int} atomSetterFontSize Font size of atom setter widget.
* @property {Bool} allowUnknownAtomSymbol If true, input unknown text in atom setter will add new pseudo atom.
* @property {Bool} enableBondKekulizeHucklize Whether Kekulize and Hucklize buttons are shown in bond modifier of editor.
* @property {Int} clonedObjectScreenOffset The pixel distance between cloned objects and origin objects when doing clone selection action in editor.
* @property {Int} selectingCurveSimplificationDistanceThreshold Distance threshold to simplify curves in selecting marker.
* @property {Float} selectingBrushWidth The selecting brush width.
* //@property {Int} selectingBrushMinWidth Min width of selecting brush.
* @property {Int} trackSimplifierDistanceThreshold Distance threshold to simplify curves in track structure input.
* @property {Float} trackTouchRefLength In touch track input, the editor may be zoomed in to ensure the default bond screen level is this value (in inch).
*/
Kekule.Editor.InteractionConfigs = Class.create(Kekule.AbstractConfigs,
/** @lends Kekule.Editor.InteractionConfigs# */
{
/** @private */
CLASS_NAME: 'Kekule.Editor.InteractionConfigs',
/** @private */
initProperties: function()
{
var degreeStep = Math.PI / 180;
this.addBoolConfigProp('enableTrackOnNearest', true);
this.addBoolConfigProp('enableHotTrack', true);
this.addBoolConfigProp('scrollToObjAfterLoading', true);
this.addBoolConfigProp('autoExpandClientSizeAfterLoading', true);
this.addBoolConfigProp('autoExpandClientSizeAfterManipulation', false);
this.addBoolConfigProp('autoSelectNewlyInsertedObjects', !true);
this.addBoolConfigProp('autoSelectNewlyInsertedObjectsOnTouch', true);
this.addIntConfigProp('objBoundTrackMinInflation', 5);
this.addIntConfigProp('objBoundTrackMinInflationMouse', null);
this.addIntConfigProp('objBoundTrackMinInflationPen', null);
this.addIntConfigProp('objBoundTrackMinInflationTouch', 10);
this.addFloatConfigProp('objBoundTrackInflationRatio', 0.2);
this.addFloatConfigProp('objBoundTrackInflationRatioMouse', null);
this.addFloatConfigProp('objBoundTrackInflationRatioPen', null);
this.addFloatConfigProp('objBoundTrackInflationRatioTouch', 0.33);
this.addBoolConfigProp('enablePartialAreaSelecting', false);
this.addFloatConfigProp('selectingBrushWidth', 12);
this.addBoolConfigProp('enableOffSelectionManipulation', true);
this.addIntConfigProp('offSelectionManipulationActivatingTimeThreshold', 800);
this.addFloatConfigProp('unmovePointerDistanceThreshold', 5, {'scope': PS.PUBLIC}); // hidden to object inspector
//this.addFloatConfigProp('selectingBrushMinWidth', 5);
this.addIntConfigProp('selectingCurveSimplificationDistanceThreshold', 2, {'scope': PS.PUBLIC}); // hidden to object inspector
this.addIntConfigProp('selectionMarkerInflation', 5);
this.addIntConfigProp('selectionMarkerEdgeInflation', 5);
this.addIntConfigProp('selectionMarkerDefPulseDuration', 500);
this.addIntConfigProp('selectionMarkerDefPulseCount', 2);
this.addBoolConfigProp('followPointerCoordOnDirectManipulatingSingleObj', true);
this.addIntConfigProp('followPointerCoordOnDirectManipulatingSingleObjDistanceThreshold', 2);
//this.addConfigProp('constrainedResizeLevels', DataType.ARRAY, undefined);
this.addFloatConfigProp('constrainedResizeStep', 0.125/*0.25*/);
this.addIntConfigProp('rotationRegionInflation', 10);
this.addFloatConfigProp('constrainedRotateStep', degreeStep * 7.5); // 7.5 degree
this.addIntConfigProp('rotationLocationPointDistanceThreshold', 10);
this.addIntConfigProp('directedMoveDistanceThreshold', 10);
this.addBoolConfigProp('enableMergePreview', true);
this.addBoolConfigProp('enableMagneticMerge', true);
this.addBoolConfigProp('enableNodeMerge', true);
this.addBoolConfigProp('enableNeighborNodeMerge', true);
this.addBoolConfigProp('enableConnectorMerge', true);
this.addBoolConfigProp('enableStructFragmentMerge', true);
this.addBoolConfigProp('enableCascadeRemoveOrphanNeighborChemNode', true);
this.addBoolConfigProp('enablePreserveLastOrphanNeighborChemNode', true);
this.addBoolConfigProp('enableGestureManipulation', true);
this.addBoolConfigProp('enableGestureZoomOnEditor', true);
this.addBoolConfigProp('enableHotKey', true);
this.addIntConfigProp('clonedObjectScreenOffset', 10);
this.addIntConfigProp('atomSetterFontSize', 14);
this.addBoolConfigProp('allowUnknownAtomSymbol', true);
this.addBoolConfigProp('enableBondKekulizeHucklize', true);
this.addIntConfigProp('trackSimplifierDistanceThreshold', 8);
this.addIntConfigProp('trackSimplifierIgnoreSegmentThreshold', 10);
this.addIntConfigProp('trackMergeDistanceThreshold', 20);
this.addFloatConfigProp('trackOptimizationAngleConstraint', degreeStep * 30); // 30 degree
this.addConfigProp('trackOptimizationDistanceConstraints', DataType.ARRAY, undefined, {'scope': PS.PUBLIC});
this.addIntConfigProp('trackOptimizationPrimaryDistanceConstraint', 1);
this.addFloatConfigProp('trackTouchRefLength', 0.5, {'scope': PS.PUBLIC}); // 0.5 inchi
this.addBoolConfigProp('autoAdjustZoomLevelOnTrackTouching', !true, {'scope': PS.PUBLIC}); // currently has some problems, disable it
this.addFloatConfigProp('editorInitialZoom', 1.5);
},
/** @ignore */
initPropValues: function(/*$super*/)
{
this.tryApplySuper('initPropValues') /* $super() */;
this.setTrackOptimizationDistanceConstraints([0.5, 1, 3, 4, 5]);
}
});
/**
* Configs of UI marker styles.
* @class
* @augments Kekule.AbstractConfigs
*
* @property {String} hotTrackerColor Color of hot track marker.
* @property {Float} hotTrackerOpacity Opacity of hot track marker.
* @property {String} selectionMarkerStrokeColor Stroke color of selection marker.
* @property {Float} selectionMarkerStrokeWidth Width of selection marker stroke.
* @property {String} selectionMarkerFillColor Fill color of selection marker. Usually this value should be set to null (not filled).
* @property {Float} selectionMarkerOpacity Opacity of selection marker.
* @property {Float} selectionMarkerEmphasisOpacity Opacity of a highlighted selection marker.
* @property {Number} selectionTransformMarkerSize Width/height of selection transform handler box, in px.
* @property {Float} selectionTransformMarkerOpacity Opacity of selection transform marker.
* @property {String} selectingMarkerStrokeColor Stroke color of selecting marker.
* @property {Float} selectingMarkerStrokeWidth Width of selecting marker stroke.
* @property {String} selectingMarkerStrokeDash Dash style of selecting marker.
* @property {String} selectingMarkerFillColor Fill color of selecting marker. Usually this value should be set to null (not filled).
* @property {Float} selectingMarkerOpacity Opacity of selecting marker.
* @property {String} selectingBrushMarkerStrokeColor Stroke color of selecting brush marker.
* @property {String} selectingBrushMarkerStrokeDash Dash style of selecting brush marker.
* @property {Float} selectingBrushMarkerOpacity Opacity of selecting brush marker.
* @property {String} selectingBrushMarkerStrokeLineCap
* @property {String} selectingBrushMarkerStrokeLineJoin
* @property {String} flexStructureAssocMarkerColor Color of marker displaying atom count in flex ring/chain controller.
* @property {Float} flexStructureAssocMarkerOpacity Opacity of marker displaying atom count in flex ring/chain controller.
* @property {Int} flexStructureAssocMarkerFontSize Font size of marker displaying atom count in flex ring/chain controller.
*
*/
Kekule.Editor.UiMarkerConfigs = Class.create(Kekule.AbstractConfigs,
/** @lends Kekule.Editor.UiMarkerConfigs# */
{
/** @private */
CLASS_NAME: 'Kekule.Editor.UiMarkerConfigs',
/** @private */
initProperties: function()
{
this.addStrConfigProp('hotTrackerColor', '#0000FF');
this.addFloatConfigProp('hotTrackerOpacity', 0.5);
this.addStrConfigProp('selectionMarkerStrokeColor', '#0000FF');
this.addFloatConfigProp('selectionMarkerStrokeWidth', 2);
this.addStrConfigProp('selectionMarkerFillColor', '#0000FF');
this.addFloatConfigProp('selectionMarkerOpacity', 0.2);
this.addFloatConfigProp('selectionMarkerEmphasisOpacity', 0.4);
this.addFloatConfigProp('selectionTransformMarkerSize', 8, {'scope': PS.PUBLIC}); // currently not used?
this.addFloatConfigProp('selectionTransformMarkerOpacity', 0.4, {'scope': PS.PUBLIC}); // currently not used?
this.addStrConfigProp('selectingMarkerStrokeColor', '#000000');
this.addFloatConfigProp('selectingMarkerStrokeWidth', 1);
this.addStrConfigProp('selectingMarkerStrokeDash', true);
this.addStrConfigProp('selectingMarkerFillColor', null);
this.addFloatConfigProp('selectingMarkerOpacity', 0.7);
this.addStrConfigProp('selectingBrushMarkerStrokeColor', '#0000FF');
this.addStrConfigProp('selectingBrushMarkerStrokeDash', false);
this.addFloatConfigProp('selectingBrushMarkerStrokeLineCap', 'round');
this.addFloatConfigProp('selectingBrushMarkerStrokeLineJoin', 'round');
this.addFloatConfigProp('selectingBrushMarkerOpacity', 0.3);
this.addStrConfigProp('trackMarkerStrokeColor', '#0000AA');
this.addFloatConfigProp('trackMarkerStrokeWidth', 2);
this.addStrConfigProp('trackMarkerStrokeDash', false);
this.addFloatConfigProp('trackMarkerOpacity', 0.5);
this.addHashConfigProp('issueCheckMarkerColors', {
'error': {
'strokeColor': '#FF0000',
'fillColor': null,
'activeStrokeColor': '#FF0000',
'activeFillColor': '#FF6666'
},
'warning': {
'strokeColor': '#f1a200',
'fillColor': null,
'activeStrokeColor': '#f1a200',
'activeFillColor': '#ffdb15'
},
'note': {
'strokeColor': '#00b0f0',
'fillColor': null,
'activeStrokeColor': '#007ca8',
'activeFillColor': '#00b0f0'
},
'log': {
'strokeColor': '#00b0f0',
'fillColor': null,
'activeStrokeColor': '#007ca8',
'activeFillColor': '#00b0f0'
}
});
this.addFloatConfigProp('issueCheckMarkerStrokeWidth', 2);
this.addFloatConfigProp('issueCheckActiveMarkerStrokeWidth', 2);
this.addStrConfigProp('issueCheckMarkerOpacity', 0.3);
this.addStrConfigProp('issueCheckActiveMarkerOpacity', 0.6);
this.addStrConfigProp('flexStructureAssocMarkerColor', '#0000AA');
this.addFloatConfigProp('flexStructureAssocMarkerOpacity', 0.5);
this.addIntConfigProp('flexStructureAssocMarkerFontSize', 14);
this.addStrConfigProp('flexStructureAssocMarkerFontFamily', "Arial, Helvetica, sans-serif");
}
});
/**
* Configs of molecule structure settings.
* @class
* @augments Kekule.AbstractConfigs
*
* @property {String} defBondType Default type of bond.
* @property {Int} defBondOrder Default order of bond.
* @property {Int} defBondLength Default bond length.
* @property {Array} defBondAngles A mapping of default 2D bond angles to different bond types, in arc.
* The mapping is a series of values like the following:
* angles[bondOrder1][0] = [defaultAngle];
* angles[bondOrder1][bondOrder2] = [angle of two bonds];
* @property {Float} bondConstrainedDirectionDelta When moving bond, the bond angle will be changed in n*delta in constrained mode.
* @property {Array} bondConstrainedDirectionAngles When moving bond, besides bondConstrainedDirectionDelta, bond angle can also be "docked" to these values.
* @property {Float} bondConstrainedDirectionAngleThreshold
* @property {Float} initialBondDirection When create a brand new bond (without any existed bond connected), which direction should the bond be.
* @property {String} defIsotopeId Default isotope of atom.
* @property {Array} primaryOrgChemAtoms Atom symbols of most often seen in organic chemistry.
* @property {Bool} enableChargeAndRadicalMarker If true, marker objects will be used in editor to represent charge and radical.
* @property {Int} maxFlexChainAtomCount The max atom count when creating carbon chain using flex chain tool. 0 means no restricts.
* @property {Int} minFlexRingAtomCount The min atom count when creating carbon ring using flex ring tool.
* @property {Int} maxFlexRingAtomCount The max atom count when creating carbon ring using flex ring tool. 0 means no restricts.
* //@property {Int} initialFlexRingAtomCount The initial atom count when creating carbon ring using flex ring tool.
*
* @property {Hash} nonAtomNodeInputSetting Settings to restrict the input types of non-atom node.
*/
Kekule.Editor.StructureConfigs = Class.create(Kekule.AbstractConfigs,
/** @lends Kekule.Editor.StructureConfigs# */
{
/** @private */
CLASS_NAME: 'Kekule.Editor.StructureConfigs',
/** @private */
initProperties: function()
{
/*
this.addFloatConfigProp('defBondAngle', Math.PI * 2 / 3);
this.defineProp('defBondAngleDegree', {'dataType': DataType.FLOAT,
'getter': function() { return this.getDefBondAngle() * 180 / Math.PI; },
'setter': function(value) { this.setDefBondAngle(value * Math.PI / 180); }
});
*/
this.addStrConfigProp('defBondType', Kekule.BondType.DEFAULT, {'enumSource': Kekule.BondType});
this.addIntConfigProp('defBondOrder', Kekule.BondOrder.SINGLE, {'enumSource': Kekule.BondOrder});
this.addFloatConfigProp('defBondLength', Kekule.globalOptions.structure.defaultBondLength2D || 0.8);
this.addConfigProp('defBondAngles', DataType.ARRAY, undefined, {'scope': PS.PUBLIC});
this.addFloatConfigProp('bondConstrainedDirectionDelta', undefined, {'scope': PS.PUBLIC});
this.addConfigProp('bondConstrainedDirectionAngles', DataType.ARRAY, undefined, {'scope': PS.PUBLIC});
this.addFloatConfigProp('bondConstrainedDirectionAngleThreshold', undefined, {'scope': PS.PUBLIC});
this.addFloatConfigProp('initialBondDirection', undefined, {'scope': PS.PUBLIC});
this.addStrConfigProp('defIsotopeId', 'C');
this.addConfigProp('primaryOrgChemAtoms', DataType.ARRAY, undefined, {'scope': PS.PUBLIC});
this.addIntConfigProp('maxFlexChainAtomCount', 0); // no limits on flex chain
this.addIntConfigProp('minFlexRingAtomCount', 3);
this.addIntConfigProp('maxFlexRingAtomCount', 18); // too large ring cause performance problem
//this.addIntConfigProp('initialFlexRingAtomCount', 3);
//this.addBoolConfigProp('enableChargeAndRadicalMarker', true);
this.addHashConfigProp('enabledNonAtomNodeTypes', {
'RGroup': true,
'pseudoatomDummy': true,
'pseudoatomHetero': true,
'pseudoatomAny': true,
'variableAtomList': true,
'variableAtomNotList': true
});
this.addHashConfigProp('enabledBondForms', {
// covalent bond types
'single': true,
'double': true,
'triple': true,
'quad': true,
'explicitAromatic': true,
// stereo bond types
'up': true,
'upInverted': true,
'down': true,
'downInverted': true,
'upOrDown': true,
'eOrZ': true,
'closer': true,
// other types
'ionic': false,
'coordinate': false,
'metallic': false,
'hydrogen': true,
'transition': true
});
},
/** @private */
initPropValues: function(/*$super*/)
{
this.tryApplySuper('initPropValues') /* $super() */;
var degreeStep = Math.PI / 180;
// init defBondAngles array
var angles = [];
var BO = Kekule.BondOrder;
var angle120 = Math.PI * 2 / 3;
angles[0] = angle120; // default value for unset bonds
angles[BO.EXPLICIT_AROMATIC] = [angle120];
angles[BO.TRIPLE] = [Math.PI];
angles[BO.DOUBLE] = [angle120];
angles[BO.DOUBLE][BO.DOUBLE] = Math.PI;
angles[BO.SINGLE] = [angle120];
this.setDefBondAngles(angles);
this.setBondConstrainedDirectionDelta(10 * Math.PI / 180);
this.setBondConstrainedDirectionAngles([0, 90 * degreeStep, 180 * degreeStep, 270 * degreeStep]);
this.setBondConstrainedDirectionAngleThreshold(degreeStep * 3);
this.setInitialBondDirection(30 * degreeStep);
this.setPrimaryOrgChemAtoms(['C', 'H', 'O', 'N', 'P', 'S', 'F', 'Cl', 'Br', 'I', 'Si', 'D', 'C13']);
},
/**
* Get the default bond angle of two valence bonds.
* @param {Int} bondOrder1
* @param {Int} bondOrder2
* @returns {Float}
*/
getDefAngleOfBonds: function(bondOrder1, bondOrder2)
{
var b1 = bondOrder1 || 0;
var b2 = bondOrder2 || 0;
if (b1 > b2)
{
b1 = bondOrder2 || 0;
b2 = bondOrder1 || 0;
}
var angles = this.getDefBondAngles();
var map = angles[b2];
if (!map)
return angles[0]; // default value for unset bonds
else
{
var value = map[b1];
return value || map[0];
}
},
/**
* Returns default angle when added new bond to startObj.
* @param {Kekule.ChemObject} startObj
* @param {Int} newBondOrder
* @return {Float}
*/
getNewBondDefAngle: function(startObj, newBondOrder)
{
if (Kekule.ObjUtils.isUnset(newBondOrder))
newBondOrder = this.getDefBondOrder();
var result;
var surroundingObjs = Kekule.Editor.StructureUtils.getSurroundingObjs(startObj);
if (surroundingObjs.length === 1) // one existing bond, defAngle is decided by new bond order and existing bond order
{
var existingConnector = startObj.getLinkedConnectorAt(0);
if (existingConnector && (existingConnector.getConnectedObjs().indexOf(surroundingObjs[0]) >= 0))
{
var existingBondOrder = existingConnector.getBondOrder? existingConnector.getBondOrder(): null;
if (Kekule.ObjUtils.notUnset(existingBondOrder))
result = this.getDefAngleOfBonds(newBondOrder, existingBondOrder);
}
}
else if (surroundingObjs.length === 0) // no connected bond, use initialDirection
result = this.getInitialBondDirection();
else
result = this.getDefAngleOfBonds(newBondOrder, 0);
return result;
}
});
/**
* Configs of chem space default settings.
* @class
* @augments Kekule.AbstractConfigs
*
* @property {Hash} defScreenSize2D Default 2D screen size of space, based on px.
* @property {Hash} defScreenSize3D Default 3D size of space.
* @property {Hash} autoExpandScreenSize2D The 2D delta used when auto expanding the space size.
* @property {Hash} autoExpandScreenSize3D The 3D delta used when auto expanding the space size.
* @property {Num} defPadding Padding on top when adding an unpositioned object to container chem space.
*/
Kekule.Editor.ChemSpaceConfigs = Class.create(Kekule.AbstractConfigs,
/** @lends Kekule.Editor.ChemSpaceConfigs# */
{
/** @private */
CLASS_NAME: 'Kekule.Editor.ChemSpaceConfigs',
/** @private */
initProperties: function()
{
this.addHashConfigProp('defScreenSize2D');
this.addHashConfigProp('defScreenSize3D');
this.addHashConfigProp('autoExpandScreenSize2D');
this.addHashConfigProp('autoExpandScreenSize3D');
this.addNumConfigProp('defPadding', 50);
},
/** @private */
initPropValues: function(/*$super*/)
{
this.tryApplySuper('initPropValues') /* $super() */;
this.setDefScreenSize2D({'x': 900, 'y': 1500});
this.setDefScreenSize3D({'x': 600, 'y': 600, 'z': 600});
this.setAutoExpandScreenSize2D({'x': 200, 'y': 200});
this.setAutoExpandScreenSize3D({'x': 100, 'y': 100, 'z': 100});
}
});
/**
* Configs of chem composer style toolbar settings.
* @class
* @augments Kekule.AbstractConfigs
*
* @property {Array} listedFontSizes Predefined font size displayed in font size combo box, in px.
* @property {Array} listedFontNames Predefined font names displayed in font size combo box.
*/
Kekule.Editor.StyleSetterConfigs = Class.create(Kekule.AbstractConfigs,
/** @lends Kekule.Editor.StyleSetterConfigs# */
{
/** @private */
CLASS_NAME: 'Kekule.Editor.StyleSetterConfigs',
/** @private */
initProperties: function()
{
this.defineProp('listedFontSizes', {'dataType': DataType.ARRAY});
this.defineProp('listedFontNames', {'dataType': DataType.ARRAY});
},
/** @private */
initPropValues: function(/*$super*/)
{
this.tryApplySuper('initPropValues') /* $super() */;
this.setListedFontSizes([8,9,10,11,12,14,16,18,20,24,28,32,36,40,44,48,54,60,66,72,80,88,96]);
/*
this.setListedFontNames([
'Arial, Helvetica, sans-serif',
'Georgia, Times New Roman, Times, serif',
'Courier New, Courier, monospace',
'Tahoma, Geneva, sans-serif',
'Trebuchet MS, Arial, Helvetica, sans-serif',
'Arial Black, Gadget, sans-serif',
'Palatino Linotype, Book Antiqua, Palatino, serif',
'Lucida Sans Unicode, Lucida Grande, sans-serif',
'MS Serif, New York, serif',
'Lucida Console, Monaco, monospace',
'Comic Sans MS, cursive'
]);
*/
this.setListedFontNames(Kekule.Widget.FontEnumerator.getAvailableFontFamilies());
}
});
/**
* Configs of chem composer chem condition modifier settings.
* @class
* @augments Kekule.AbstractConfigs
*
* @property {Array} listedChemConditions Predefined reaction conditions (value and display text) displayed in selector.
* Each item is an object of {text, value}
*/
Kekule.Editor.ChemConditionSetterConfigs = Class.create(Kekule.AbstractConfigs,
/** @lends Kekule.Editor.ChemConditionSetterConfigs# */
{
/** @private */
CLASS_NAME: 'Kekule.Editor.ChemConditionSetterConfigs',
/** @private */
initProperties: function()
{
this.defineProp('listedChemConditions', {'dataType': DataType.ARRAY});
this.addNumConfigProp('conditionGlyphFontSizeMin', 4);
this.addNumConfigProp('conditionGlyphFontSizeMax', 32);
this.addNumConfigProp('conditionGlyphFontSizeStep', 1);
},
/** @private */
initPropValues: function(/*$super*/)
{
this.tryApplySuper('initPropValues');
var items = [
{'text': Kekule.$L('ChemWidgetTexts.LABEL_REACTION_CONDITION_HEAT'), 'value': Kekule.ReactionQualitativeCondition.HEAT},
{'text': Kekule.$L('ChemWidgetTexts.LABEL_REACTION_CONDITION_LIGHT'), 'value': Kekule.ReactionQualitativeCondition.LIGHT},
{'text': Kekule.$L('ChemWidgetTexts.LABEL_REACTION_CONDITION_PRESSURE'), 'value': Kekule.ReactionQualitativeCondition.PRESSURE},
{'text': Kekule.$L('ChemWidgetTexts.LABEL_REACTION_CONDITION_HIGH_TEMP'), 'value': Kekule.ReactionQualitativeCondition.HIGH_TEMP},
{'text': Kekule.$L('ChemWidgetTexts.LABEL_REACTION_CONDITION_LOW_TEMP'), 'value': Kekule.ReactionQualitativeCondition.LOW_TEMP},
{'text': Kekule.$L('ChemWidgetTexts.LABEL_REACTION_CONDITION_MICROWAVE'), 'value': Kekule.ReactionQualitativeCondition.MICROWAVE}
// {'text': Kekule.$L('ChemWidgetTexts.LABEL_REACTION_CONDITION_CUSTOM'), 'value': ''} // empty value means custom reaction condition
];
this.setListedChemConditions(items);
}
});
/**
* Configs of hot key settings of editor.
* @class
* @augments Kekule.AbstractConfigs
*
* @property {Array} hotKeys Hot keys to do quick action.
* Each item in array is a hash {key: string, action: string},
*/
Kekule.Editor.HotKeyConfigs = Class.create(Kekule.AbstractConfigs,
/** @lends Kekule.Editor.HotKeyConfigs# */
{
/** @private */
CLASS_NAME: 'Kekule.Editor.HotKeyConfigs',
/** @private */
initProperties: function()
{
this.defineProp('hotKeys', {'dataType': DataType.ARRAY});
},
/** @private */
initPropValues: function(/*$super*/)
{
var CWN = Kekule.ChemWidget.ComponentWidgetNames;
// debug, fetch default ones
this.tryApplySuper('initPropValues');
this.setHotKeys([
// node modification
{'key': 'c', 'action': 'atom_C'},
{'key': 'h', 'action': 'atom_H'},
{'key': 'o', 'action': 'atom_O'},
{'key': 'n', 'action': 'atom_N'},
{'key': 'p', 'action': 'atom_P'},
{'key': 's', 'action': 'atom_S'},
{'key': 'f', 'action': 'atom_F'},
{'key': 'Shift+C', 'action': 'atom_Cl'},
{'key': 'b', 'action': 'atom_Br'},
{'key': 'i', 'action': 'atom_I'},
{'key': 'Shift+B', 'action': 'atom_B'},
{'key': 'k', 'action': 'atom_K'},
{'key': 'Shift+N', 'action': 'atom_Na'},
{'key': 'd', 'action': 'atom_D'},
{'key': 'm', 'action': 'subgroup_methyl'},
{'key': 'e', 'action': 'subgroup_ethyl'},
{'key': 't', 'action': 'subgroup_TMS'},
{'key': 'Shift+P', 'action': 'subgroup_phenyl'},
{'key': 'Shift+T', 'action': 'subgroup_OTs'},
{'key': 'Shift+E', 'action': 'subgroup_COOCH3'},
{'key': 'a', 'action': 'atom_any'},
{'key': 'q', 'action': 'atom_hetero'},
{'key': 'l', 'action': 'atom_variable'},
{'key': 'r', 'action': 'subgroup_R'},
// connector modification
{'key': '1', 'action': 'bond_single'},
{'key': '2', 'action': 'bond_double'},
{'key': '3', 'action': 'bond_triple'},
{'key': '4', 'action': 'bond_quad'},
{'key': 'b', 'action': 'bond_closer'},
{'key': 'w', 'action': 'bond_up'},
{'key': 'h', 'action': 'bond_down'},
{'key': 'Shift+W', 'action': 'bond_down'},
{'key': 'y', 'action': 'bond_upOrDown'},
// general
{'key': 'Ctrl+A', 'action': CWN.selectAll},
{'key': 'Ctrl+C', 'action': CWN.copy},
{'key': 'Ctrl+X', 'action': CWN.cut},
{'key': 'Ctrl+V', 'action': CWN.paste},
{'key': 'Ctrl+Z', 'action': CWN.undo},
{'key': 'Ctrl+Shift+Z', 'action': CWN.redo},
{'key': '+', 'action': CWN.zoomIn},
{'key': '-', 'action': CWN.zoomOut},
{'key': 'Delete', 'action': CWN.eraseSelection},
{'key': 'Backspace', 'action': CWN.eraseSelection}
]);
}
});
})();