mirror of
https://github.com/scratchfoundation/scratch-blocks.git
synced 2025-08-28 22:10:31 -04:00
Workspace comment render updates (to match block comments), and new minimize state and functionality.
This commit is contained in:
parent
e82796132b
commit
3a31481af9
3 changed files with 333 additions and 142 deletions
|
@ -40,12 +40,13 @@ goog.require('goog.math.Coordinate');
|
|||
* @param {string} content The content of this workspace comment.
|
||||
* @param {number} height Height of the comment.
|
||||
* @param {number} width Width of the comment.
|
||||
* @param {boolean} minimized Whether this comment is in the minimized state
|
||||
* @param {string=} opt_id Optional ID. Use this ID if provided, otherwise
|
||||
* create a new ID. If the ID conflicts with an in-use ID, a new one will
|
||||
* be generated.
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.WorkspaceComment = function(workspace, content, height, width, opt_id) {
|
||||
Blockly.WorkspaceComment = function(workspace, content, height, width, minimized, opt_id) {
|
||||
/** @type {string} */
|
||||
this.id = (opt_id && !workspace.getCommentById(opt_id)) ?
|
||||
opt_id : Blockly.utils.genUid();
|
||||
|
@ -74,6 +75,13 @@ Blockly.WorkspaceComment = function(workspace, content, height, width, opt_id) {
|
|||
*/
|
||||
this.width_ = width;
|
||||
|
||||
/**
|
||||
* The comment's minimized state.
|
||||
* @type{boolean}
|
||||
* @private
|
||||
*/
|
||||
this.isMinimized_ = minimized;
|
||||
|
||||
/**
|
||||
* @type {!Blockly.Workspace}
|
||||
*/
|
||||
|
@ -112,6 +120,13 @@ Blockly.WorkspaceComment = function(workspace, content, height, width, opt_id) {
|
|||
Blockly.WorkspaceComment.fireCreateEvent(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Maximum lable length (actual label length will include
|
||||
* one additional character, the ellipsis).
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceComment.MAX_LABEL_LENGTH = 16;
|
||||
|
||||
/**
|
||||
* Dispose of this comment.
|
||||
* @package
|
||||
|
@ -262,6 +277,15 @@ Blockly.WorkspaceComment.prototype.setText = function(text) {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether this comment is currently minimized.
|
||||
* @return {boolean} True if minimized
|
||||
* @package
|
||||
*/
|
||||
Blockly.WorkspaceComment.prototype.isMinimized = function() {
|
||||
return this.isMinimized_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encode a comment subtree as XML with XY coordinates.
|
||||
* @param {boolean=} opt_noId True if the encoder should skip the comment id.
|
||||
|
@ -277,6 +301,23 @@ Blockly.WorkspaceComment.prototype.toXmlWithXY = function(opt_noId) {
|
|||
return element;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the truncated text for this comment to display in the minimized
|
||||
* top bar.
|
||||
* @return {string} The truncated comment text
|
||||
* @package
|
||||
*/
|
||||
Blockly.WorkspaceComment.prototype.getLabelText = function() {
|
||||
if (this.content_.length > Blockly.WorkspaceComment.MAX_LABEL_LENGTH) {
|
||||
if (this.RTL) {
|
||||
return '\u2026' + this.content_.slice(0, Blockly.WorkspaceComment.MAX_LABEL_LENGTH);
|
||||
}
|
||||
return this.content_.slice(0, Blockly.WorkspaceComment.MAX_LABEL_LENGTH) + '\u2026';
|
||||
} else {
|
||||
return this.content_;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Encode a comment subtree as XML, but don't serialize the XY coordinates or
|
||||
* width and height. If you need that additional information use toXmlWithXY.
|
||||
|
@ -289,6 +330,9 @@ Blockly.WorkspaceComment.prototype.toXml = function(opt_noId) {
|
|||
if (!opt_noId) {
|
||||
commentElement.setAttribute('id', this.id);
|
||||
}
|
||||
if (this.isMinimized_) {
|
||||
commentElement.setAttribute('minimized', true);
|
||||
}
|
||||
commentElement.textContent = this.getText();
|
||||
return commentElement;
|
||||
};
|
||||
|
@ -325,7 +369,7 @@ Blockly.WorkspaceComment.fromXml = function(xmlComment, workspace) {
|
|||
var info = Blockly.WorkspaceComment.parseAttributes(xmlComment);
|
||||
|
||||
var comment = new Blockly.WorkspaceComment(
|
||||
workspace, info.content, info.h, info.w, info.id);
|
||||
workspace, info.content, info.h, info.w, info.minimized, info.id);
|
||||
|
||||
if (!isNaN(info.x) && !isNaN(info.y)) {
|
||||
comment.moveBy(info.x, info.y);
|
||||
|
@ -370,6 +414,12 @@ Blockly.WorkspaceComment.parseAttributes = function(xml) {
|
|||
* @type {number}
|
||||
*/
|
||||
y: parseInt(xml.getAttribute('y'), 10),
|
||||
/**
|
||||
* Whether this comment is minimized. Defaults to false if not specified in
|
||||
* the XML.
|
||||
* @type {boolean}
|
||||
*/
|
||||
minimized: xml.getAttribute('minimized') || false,
|
||||
/* @type {string} */
|
||||
content: xml.textContent
|
||||
};
|
||||
|
|
|
@ -35,7 +35,7 @@ goog.require('Blockly.WorkspaceCommentSvg');
|
|||
* @const
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.RESIZE_SIZE = 8;
|
||||
Blockly.WorkspaceCommentSvg.RESIZE_SIZE = 12 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH;
|
||||
|
||||
/**
|
||||
* Radius of the border around the comment.
|
||||
|
@ -43,7 +43,7 @@ Blockly.WorkspaceCommentSvg.RESIZE_SIZE = 8;
|
|||
* @const
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.BORDER_RADIUS = 3;
|
||||
Blockly.WorkspaceCommentSvg.BORDER_WIDTH = 1;
|
||||
|
||||
/**
|
||||
* Offset from the foreignobject edge to the textarea edge.
|
||||
|
@ -51,15 +51,37 @@ Blockly.WorkspaceCommentSvg.BORDER_RADIUS = 3;
|
|||
* @const
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.TEXTAREA_OFFSET = 2;
|
||||
Blockly.WorkspaceCommentSvg.TEXTAREA_OFFSET = 12;
|
||||
|
||||
/**
|
||||
* Offset from the top to make room for a top bar.
|
||||
* @type {number}
|
||||
* @const
|
||||
* The height of the comment top bar.
|
||||
* @package
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT = 32;
|
||||
|
||||
/**
|
||||
* The size of the minimize arrow icon in the comment top bar.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.TOP_OFFSET = 10;
|
||||
Blockly.WorkspaceCommentSvg.MINIMIZE_ICON_SIZE = 16;
|
||||
|
||||
/**
|
||||
* The size of the delete icon in the comment top bar.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.DELETE_ICON_SIZE = 12;
|
||||
|
||||
/**
|
||||
* The inset for the top bar icons.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.TOP_BAR_ICON_INSET = 6;
|
||||
|
||||
/**
|
||||
* Width that a minimized comment should have.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.MINIMIZE_WIDTH = 200;
|
||||
|
||||
/**
|
||||
* Returns a bounding box describing the dimensions of this comment.
|
||||
|
@ -83,31 +105,34 @@ Blockly.WorkspaceCommentSvg.prototype.render = function() {
|
|||
var size = this.getHeightWidth();
|
||||
|
||||
// Add text area
|
||||
this.createEditor_();
|
||||
this.svgGroup_.appendChild(this.foreignObject_);
|
||||
|
||||
this.svgHandleTarget_ = Blockly.utils.createSvgElement('rect',
|
||||
{
|
||||
'class': 'blocklyCommentHandleTarget',
|
||||
'x': 0,
|
||||
'y': 0
|
||||
});
|
||||
this.svgGroup_.appendChild(this.svgHandleTarget_);
|
||||
this.commentEditor_ = this.createEditor_();
|
||||
this.svgRectTarget_ = Blockly.utils.createSvgElement('rect',
|
||||
{
|
||||
'class': 'blocklyCommentTarget',
|
||||
'class': 'blocklyDraggable blocklyCommentTarget scratchCommentRect',
|
||||
'x': 0,
|
||||
'y': 0,
|
||||
'rx': Blockly.WorkspaceCommentSvg.BORDER_RADIUS,
|
||||
'ry': Blockly.WorkspaceCommentSvg.BORDER_RADIUS
|
||||
'rx': 4 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH,
|
||||
'ry': 4 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH
|
||||
});
|
||||
this.svgGroup_.appendChild(this.svgRectTarget_);
|
||||
|
||||
this.createCommentTopBar_();
|
||||
|
||||
this.svgGroup_.appendChild(this.commentEditor_);
|
||||
|
||||
// Add the resize icon
|
||||
this.addResizeDom_();
|
||||
if (this.isDeletable()) {
|
||||
// Add the delete icon
|
||||
this.addDeleteDom_();
|
||||
|
||||
// Show / hide relevant things based on minimized state
|
||||
if (this.isMinimized()) {
|
||||
this.minimizeArrow_.setAttributeNS('http://www.w3.org/1999/xlink',
|
||||
'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'comment-arrow-up.svg');
|
||||
this.commentEditor_.setAttribute('display', 'none');
|
||||
this.resizeGroup_.setAttribute('display', 'none');
|
||||
} else {
|
||||
this.minimizeArrow_.setAttributeNS('http://www.w3.org/1999/xlink',
|
||||
'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'comment-arrow-down.svg');
|
||||
this.topBarLabel_.setAttribute('display', 'none');
|
||||
}
|
||||
|
||||
this.setSize(size.width, size.height);
|
||||
|
@ -124,14 +149,14 @@ Blockly.WorkspaceCommentSvg.prototype.render = function() {
|
|||
this.resizeGroup_, 'mouseup', this, this.resizeMouseUp_);
|
||||
}
|
||||
|
||||
if (this.isDeletable()) {
|
||||
Blockly.bindEventWithChecks_(
|
||||
this.deleteGroup_, 'mousedown', this, this.deleteMouseDown_);
|
||||
Blockly.bindEventWithChecks_(
|
||||
this.deleteGroup_, 'mouseout', this, this.deleteMouseOut_);
|
||||
Blockly.bindEventWithChecks_(
|
||||
this.deleteGroup_, 'mouseup', this, this.deleteMouseUp_);
|
||||
}
|
||||
Blockly.bindEventWithChecks_(
|
||||
this.minimizeArrow_, 'mousedown', this, this.minimizeArrowMouseDown_);
|
||||
Blockly.bindEventWithChecks_(
|
||||
this.minimizeArrow_, 'mouseup', this, this.minimizeArrowMouseUp_);
|
||||
Blockly.bindEventWithChecks_(
|
||||
this.deleteIcon_, 'mousedown', this, this.deleteMouseDown_);
|
||||
Blockly.bindEventWithChecks_(
|
||||
this.deleteIcon_, 'mouseup', this, this.deleteMouseUp_);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -152,29 +177,35 @@ Blockly.WorkspaceCommentSvg.prototype.createEditor_ = function() {
|
|||
this.foreignObject_ = Blockly.utils.createSvgElement(
|
||||
'foreignObject',
|
||||
{
|
||||
'x': 0,
|
||||
'y': Blockly.WorkspaceCommentSvg.TOP_OFFSET,
|
||||
'x': Blockly.WorkspaceCommentSvg.BORDER_WIDTH,
|
||||
'y': Blockly.WorkspaceCommentSvg.BORDER_WIDTH + Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT,
|
||||
'class': 'blocklyCommentForeignObject'
|
||||
},
|
||||
null);
|
||||
var body = document.createElementNS(Blockly.HTML_NS, 'body');
|
||||
body.setAttribute('xmlns', Blockly.HTML_NS);
|
||||
body.className = 'blocklyMinimalBody';
|
||||
body.className = 'blocklyMinimalBody scratchCommentBody';
|
||||
var textarea = document.createElementNS(Blockly.HTML_NS, 'textarea');
|
||||
textarea.className = 'blocklyCommentTextarea';
|
||||
textarea.className = 'scratchCommentTextarea scratchCommentText';
|
||||
textarea.setAttribute('dir', this.RTL ? 'RTL' : 'LTR');
|
||||
body.appendChild(textarea);
|
||||
this.textarea_ = textarea;
|
||||
this.textarea_.style.margin = (Blockly.WorkspaceCommentSvg.TEXTAREA_OFFSET) + 'px';
|
||||
this.foreignObject_.appendChild(body);
|
||||
// Don't zoom with mousewheel.
|
||||
Blockly.bindEventWithChecks_(textarea, 'wheel', this, function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
Blockly.bindEventWithChecks_(textarea, 'change', this, function(
|
||||
/* eslint-disable no-unused-vars */ e
|
||||
/* eslint-enable no-unused-vars */) {
|
||||
this.setText(textarea.value);
|
||||
Blockly.bindEventWithChecks_(textarea, 'change', this, function(_e) {
|
||||
if (this.text_ != textarea.value) {
|
||||
Blockly.Events.fire(new Blockly.Events.CommentChange(
|
||||
this, this.text_, textarea.value));
|
||||
this.setText(textarea.value);
|
||||
}
|
||||
});
|
||||
|
||||
this.labelText_ = this.getLabelText();
|
||||
|
||||
return this.foreignObject_;
|
||||
};
|
||||
|
||||
|
@ -186,7 +217,7 @@ Blockly.WorkspaceCommentSvg.prototype.addResizeDom_ = function() {
|
|||
this.resizeGroup_ = Blockly.utils.createSvgElement(
|
||||
'g',
|
||||
{
|
||||
'class': this.RTL ? 'blocklyResizeSW' : 'blocklyResizeSE'
|
||||
'class': this.RTL ? 'scratchCommentResizeSW' : 'scratchCommentResizeSE'
|
||||
},
|
||||
this.svgGroup_);
|
||||
var resizeSize = Blockly.WorkspaceCommentSvg.RESIZE_SIZE;
|
||||
|
@ -211,43 +242,107 @@ Blockly.WorkspaceCommentSvg.prototype.addResizeDom_ = function() {
|
|||
};
|
||||
|
||||
/**
|
||||
* Add the delete icon to the DOM
|
||||
* Create the comment top bar and its contents.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.prototype.addDeleteDom_ = function() {
|
||||
this.deleteGroup_ = Blockly.utils.createSvgElement(
|
||||
'g',
|
||||
Blockly.WorkspaceCommentSvg.prototype.createCommentTopBar_ = function() {
|
||||
this.svgHandleTarget_ = Blockly.utils.createSvgElement('rect',
|
||||
{
|
||||
'class': 'blocklyCommentDeleteIcon'
|
||||
},
|
||||
this.svgGroup_);
|
||||
this.deleteIconBorder_ = Blockly.utils.createSvgElement('circle',
|
||||
'class': 'blocklyDraggable scratchCommentTopBar',
|
||||
'x': Blockly.WorkspaceCommentSvg.BORDER_WIDTH,
|
||||
'y': Blockly.WorkspaceCommentSvg.BORDER_WIDTH,
|
||||
'height': Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT
|
||||
}, this.svgGroup_);
|
||||
|
||||
this.createTopBarIcons_();
|
||||
this.createTopBarLabel_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the comment top bar label. This is the truncated comment text
|
||||
* that shows when comment is minimized.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.prototype.createTopBarLabel_ = function() {
|
||||
this.topBarLabel_ = Blockly.utils.createSvgElement('text',
|
||||
{
|
||||
'class': 'blocklyDeleteIconShape',
|
||||
'r': '7',
|
||||
'cx': '7.5',
|
||||
'cy': '7.5'
|
||||
},
|
||||
this.deleteGroup_);
|
||||
// x icon.
|
||||
Blockly.utils.createSvgElement(
|
||||
'line',
|
||||
'class': 'scratchCommentText',
|
||||
'x': this.width_ / 2,
|
||||
'y': (Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT / 2) + Blockly.WorkspaceCommentSvg.BORDER_WIDTH,
|
||||
'text-anchor': 'middle',
|
||||
'dominant-baseline': 'middle'
|
||||
}, this.svgGroup_);
|
||||
|
||||
this.labelTextNode_ = document.createTextNode(this.labelText_);
|
||||
this.topBarLabel_.appendChild(this.labelTextNode_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the minimize toggle and delete icons that in the comment top bar.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.prototype.createTopBarIcons_ = function() {
|
||||
var topBarMiddleY = (Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT / 2) +
|
||||
Blockly.WorkspaceCommentSvg.BORDER_WIDTH;
|
||||
|
||||
// Minimize Toggle Icon in Comment Top Bar
|
||||
var xInset = Blockly.WorkspaceCommentSvg.TOP_BAR_ICON_INSET;
|
||||
this.minimizeArrow_ = Blockly.utils.createSvgElement('image',
|
||||
{
|
||||
'x1': '5', 'y1': '10',
|
||||
'x2': '10', 'y2': '5',
|
||||
'stroke': '#fff',
|
||||
'stroke-width': '2'
|
||||
},
|
||||
this.deleteGroup_);
|
||||
Blockly.utils.createSvgElement(
|
||||
'line',
|
||||
'x': xInset,
|
||||
'y': topBarMiddleY - Blockly.WorkspaceCommentSvg.MINIMIZE_ICON_SIZE / 2,
|
||||
'width': Blockly.WorkspaceCommentSvg.MINIMIZE_ICON_SIZE,
|
||||
'height': Blockly.WorkspaceCommentSvg.MINIMIZE_ICON_SIZE
|
||||
}, this.svgGroup_);
|
||||
|
||||
// Delete Icon in Comment Top Bar
|
||||
this.deleteIcon_ = Blockly.utils.createSvgElement('image',
|
||||
{
|
||||
'x1': '5', 'y1': '5',
|
||||
'x2': '10', 'y2': '10',
|
||||
'stroke': '#fff',
|
||||
'stroke-width': '2'
|
||||
},
|
||||
this.deleteGroup_);
|
||||
'x': xInset,
|
||||
'y': topBarMiddleY - Blockly.WorkspaceCommentSvg.DELETE_ICON_SIZE / 2,
|
||||
'width': Blockly.WorkspaceCommentSvg.DELETE_ICON_SIZE,
|
||||
'height': Blockly.WorkspaceCommentSvg.DELETE_ICON_SIZE
|
||||
}, this.svgGroup_);
|
||||
this.deleteIcon_.setAttributeNS('http://www.w3.org/1999/xlink',
|
||||
'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'delete-x.svg');
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a mouse-down on bubble's minimize icon.
|
||||
* @param {!Event} e Mouse up event.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.prototype.minimizeArrowMouseDown_ = function(e) {
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a mouse-up on bubble's minimize icon.
|
||||
* @param {!Event} e Mouse up event.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.prototype.minimizeArrowMouseUp_ = function(e) {
|
||||
this.toggleMinimize_();
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a mouse-down on bubble's minimize icon.
|
||||
* @param {!Event} e Mouse up event.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.prototype.deleteMouseDown_ = function(e) {
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a mouse-up on bubble's delete icon.
|
||||
* @param {!Event} e Mouse up event.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.prototype.deleteMouseUp_ = function(e) {
|
||||
this.dispose();
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -276,40 +371,46 @@ Blockly.WorkspaceCommentSvg.prototype.resizeMouseDown_ = function(e) {
|
|||
e.stopPropagation();
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a mouse-down on comment's delete icon.
|
||||
* @param {!Event} e Mouse down event.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.prototype.deleteMouseDown_ = function(e) {
|
||||
// highlight the delete icon
|
||||
Blockly.utils.addClass(
|
||||
/** @type {!Element} */ (this.deleteIconBorder_), 'blocklyDeleteIconHighlighted');
|
||||
// This event has been handled. No need to bubble up to the document.
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a mouse-out on comment's delete icon.
|
||||
* @param {!Event} e Mouse out event.
|
||||
* Set the minimized state of the bubble.
|
||||
* @param {boolean} minimize Whether the bubble should be minimized
|
||||
* @param {?string} labelText Optional label text for the comment top bar
|
||||
* when it is minimized.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.prototype.deleteMouseOut_ = function(/*e*/) {
|
||||
// restore highlight on the delete icon
|
||||
Blockly.utils.removeClass(
|
||||
/** @type {!Element} */ (this.deleteIconBorder_), 'blocklyDeleteIconHighlighted');
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a mouse-up on comment's delete icon.
|
||||
* @param {!Event} e Mouse up event.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.prototype.deleteMouseUp_ = function(e) {
|
||||
// Delete this comment
|
||||
this.dispose(true, true);
|
||||
// This event has been handled. No need to bubble up to the document.
|
||||
e.stopPropagation();
|
||||
Blockly.WorkspaceCommentSvg.prototype.setRenderedMinimizeState_ = function(minimize, labelText) {
|
||||
if (minimize) {
|
||||
// Change minimize icon
|
||||
this.minimizeArrow_.setAttributeNS('http://www.w3.org/1999/xlink',
|
||||
'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'comment-arrow-up.svg');
|
||||
// Hide text area
|
||||
this.commentEditor_.setAttribute('display', 'none');
|
||||
// Hide resize handle if it exists
|
||||
if (this.resizeGroup_) {
|
||||
this.resizeGroup_.setAttribute('display', 'none');
|
||||
}
|
||||
if (labelText && this.labelText_ != labelText) {
|
||||
// Update label and display
|
||||
// TODO is there a better way to do this?
|
||||
this.topBarLabel_.removeChild(this.labelTextNode_);
|
||||
this.labelTextNode_ = document.createTextNode(labelText);
|
||||
this.topBarLabel_.appendChild(this.labelTextNode_);
|
||||
}
|
||||
Blockly.utils.removeAttribute(this.topBarLabel_, 'display');
|
||||
} else {
|
||||
// Change minimize icon
|
||||
this.minimizeArrow_.setAttributeNS('http://www.w3.org/1999/xlink',
|
||||
'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'comment-arrow-down.svg');
|
||||
// Hide label
|
||||
this.topBarLabel_.setAttribute('display', 'none');
|
||||
// Show text area
|
||||
Blockly.utils.removeAttribute(this.commentEditor_, 'display');
|
||||
// Display resize handle if it exists
|
||||
if (this.resizeGroup_) {
|
||||
Blockly.utils.removeAttribute(this.resizeGroup_, 'display');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -377,22 +478,22 @@ Blockly.WorkspaceCommentSvg.prototype.resizeMouseMove_ = function(e) {
|
|||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceCommentSvg.prototype.resizeComment_ = function() {
|
||||
var size = this.getHeightWidth();
|
||||
var topOffset = Blockly.WorkspaceCommentSvg.TOP_OFFSET;
|
||||
var doubleBorderWidth = 2 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH;
|
||||
var topOffset = Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT;
|
||||
var textOffset = Blockly.WorkspaceCommentSvg.TEXTAREA_OFFSET * 2;
|
||||
|
||||
this.foreignObject_.setAttribute('width',
|
||||
size.width);
|
||||
this.width_ - doubleBorderWidth);
|
||||
this.foreignObject_.setAttribute('height',
|
||||
size.height - topOffset);
|
||||
this.height_ - doubleBorderWidth - topOffset);
|
||||
if (this.RTL) {
|
||||
this.foreignObject_.setAttribute('x',
|
||||
-size.width);
|
||||
-this.width_);
|
||||
}
|
||||
this.textarea_.style.width =
|
||||
(size.width - textOffset) + 'px';
|
||||
(this.width_ - textOffset) + 'px';
|
||||
this.textarea_.style.height =
|
||||
(size.height - textOffset - topOffset) + 'px';
|
||||
(this.height_ - doubleBorderWidth - textOffset - topOffset) + 'px';
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -404,23 +505,40 @@ Blockly.WorkspaceCommentSvg.prototype.resizeComment_ = function() {
|
|||
Blockly.WorkspaceCommentSvg.prototype.setSize = function(width, height) {
|
||||
var oldWidth = this.width_;
|
||||
var oldHeight = this.height_;
|
||||
// Minimum size of a comment.
|
||||
width = Math.max(width, 45);
|
||||
height = Math.max(height, 20 + Blockly.WorkspaceCommentSvg.TOP_OFFSET);
|
||||
this.width_ = width;
|
||||
this.height_ = height;
|
||||
Blockly.Events.fire(new Blockly.Events.CommentChange(this,
|
||||
{width: oldWidth, height: oldHeight},
|
||||
{width: this.width_, height: this.height_}));
|
||||
this.svgRect_.setAttribute('width', width);
|
||||
this.svgRect_.setAttribute('height', height);
|
||||
|
||||
var doubleBorderWidth = 2 * Blockly.WorkspaceCommentSvg.BORDER_WIDTH;
|
||||
|
||||
if (this.isMinimized_) {
|
||||
width = Blockly.WorkspaceCommentSvg.MINIMIZE_WIDTH;
|
||||
height = Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT;
|
||||
} else {
|
||||
// Minimum size of a 'full size' (not minimized) comment.
|
||||
width = Math.max(width, doubleBorderWidth + 50);
|
||||
height = Math.max(height, doubleBorderWidth + 20 + Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT);
|
||||
|
||||
// Note we are only updating this.width_ or this.height_ here
|
||||
// and not in the case above, because when we're minimizing a comment,
|
||||
// we want to keep track of the width/height of the maximized comment
|
||||
this.width_ = width;
|
||||
this.height_ = height;
|
||||
Blockly.Events.fire(new Blockly.Events.CommentChange(this,
|
||||
{width: oldWidth, height: oldHeight},
|
||||
{width: this.width_, height: this.height_}));
|
||||
}
|
||||
|
||||
this.svgRectTarget_.setAttribute('width', width);
|
||||
this.svgRectTarget_.setAttribute('height', height);
|
||||
this.svgHandleTarget_.setAttribute('width', width);
|
||||
this.svgHandleTarget_.setAttribute('height', Blockly.WorkspaceCommentSvg.TOP_OFFSET);
|
||||
this.svgHandleTarget_.setAttribute('width', width - doubleBorderWidth);
|
||||
this.svgHandleTarget_.setAttribute('height', Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT);
|
||||
if (this.RTL) {
|
||||
this.svgRect_.setAttribute('transform', 'scale(-1 1)');
|
||||
this.minimizeArrow_.setAttribute('x', width -
|
||||
(Blockly.WorkspaceCommentSvg.MINIMIZE_ICON_SIZE) -
|
||||
Blockly.WorkspaceCommentSvg.TOP_BAR_ICON_INSET);
|
||||
this.svgRectTarget_.setAttribute('transform', 'scale(-1 1)');
|
||||
} else {
|
||||
this.deleteIcon_.setAttribute('x', width -
|
||||
Blockly.WorkspaceCommentSvg.DELETE_ICON_SIZE -
|
||||
Blockly.WorkspaceCommentSvg.TOP_BAR_ICON_INSET);
|
||||
}
|
||||
|
||||
var resizeSize = Blockly.WorkspaceCommentSvg.RESIZE_SIZE;
|
||||
|
@ -429,22 +547,55 @@ Blockly.WorkspaceCommentSvg.prototype.setSize = function(width, height) {
|
|||
// Mirror the resize group.
|
||||
this.resizeGroup_.setAttribute('transform', 'translate(' +
|
||||
(-width + resizeSize) + ',' + (height - resizeSize) + ') scale(-1 1)');
|
||||
this.deleteGroup_.setAttribute('transform', 'translate(' +
|
||||
(-width + resizeSize) + ',' + (-resizeSize) + ') scale(-1 1)');
|
||||
} else {
|
||||
this.resizeGroup_.setAttribute('transform', 'translate(' +
|
||||
(width - resizeSize) + ',' +
|
||||
(height - resizeSize) + ')');
|
||||
this.deleteGroup_.setAttribute('transform', 'translate(' +
|
||||
(width - resizeSize) + ',' +
|
||||
(-resizeSize) + ')');
|
||||
(width - doubleBorderWidth - resizeSize) + ',' +
|
||||
(height - doubleBorderWidth - resizeSize) + ')');
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isMinimized_) {
|
||||
this.topBarLabel_.setAttribute('x', width / 2);
|
||||
this.topBarLabel_.setAttribute('y', height / 2);
|
||||
}
|
||||
|
||||
// Allow the contents to resize.
|
||||
this.resizeComment_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggle the minimization state of this comment.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceComment.prototype.toggleMinimize_ = function() {
|
||||
this.setMinimized(!this.isMinimized_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the minimized state for this comment.
|
||||
* @param {boolean} minimize Whether the comment should be minimized
|
||||
* @package
|
||||
*/
|
||||
Blockly.WorkspaceComment.prototype.setMinimized = function(minimize) {
|
||||
if (this.isMinimized_ == minimize) return;
|
||||
Blockly.Events.fire(new Blockly.Events.CommentChange(this,
|
||||
{minimized: this.isMinimized_}, {minimized: minimize}));
|
||||
this.isMinimized_ = minimize;
|
||||
if (minimize) {
|
||||
if (this.rendered_) {
|
||||
this.setRenderedMinimizeState_(true, this.getLabelText());
|
||||
}
|
||||
this.setSize(Blockly.WorkspaceCommentSvg.MINIMIZE_WIDTH,
|
||||
Blockly.WorkspaceCommentSvg.TOP_BAR_HEIGHT);
|
||||
} else {
|
||||
if (this.rendered_) {
|
||||
this.setRenderedMinimizeState_(false);
|
||||
}
|
||||
this.setText(this.content_);
|
||||
this.setSize(this.width_, this.height_);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispose of any rendered comment components.
|
||||
* @private
|
||||
|
|
|
@ -51,19 +51,9 @@ Blockly.WorkspaceCommentSvg = function(workspace, content, height, width,
|
|||
* @private
|
||||
*/
|
||||
this.svgGroup_ = Blockly.utils.createSvgElement(
|
||||
'g', {'class': 'blocklyComment'}, null);
|
||||
'g', {}, null);
|
||||
this.svgGroup_.translate_ = '';
|
||||
|
||||
this.svgRect_ = Blockly.utils.createSvgElement(
|
||||
'rect',
|
||||
{
|
||||
'class': 'blocklyCommentRect',
|
||||
'x': 0,
|
||||
'y': 0,
|
||||
'rx': Blockly.WorkspaceCommentSvg.BORDER_RADIUS,
|
||||
'ry': Blockly.WorkspaceCommentSvg.BORDER_RADIUS
|
||||
});
|
||||
this.svgGroup_.appendChild(this.svgRect_);
|
||||
|
||||
/**
|
||||
* Whether the comment is rendered onscreen and is a part of the DOM.
|
||||
|
@ -543,7 +533,7 @@ Blockly.WorkspaceCommentSvg.fromXml = function(xmlComment, workspace,
|
|||
var info = Blockly.WorkspaceComment.parseAttributes(xmlComment);
|
||||
|
||||
var comment = new Blockly.WorkspaceCommentSvg(workspace,
|
||||
info.content, info.h, info.w, info.id);
|
||||
info.content, info.h, info.w, info.minimized, info.id);
|
||||
if (workspace.rendered) {
|
||||
comment.initSvg();
|
||||
comment.render(false);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue