diff --git a/area.js b/area.js index c33de80..0dea931 100644 --- a/area.js +++ b/area.js @@ -31,9 +31,10 @@ const Lang = imports.lang; const Pango = imports.gi.Pango; const St = imports.gi.St; +const ExtensionUtils = imports.misc.extensionUtils; +const Main = imports.ui.main; const Screenshot = imports.ui.screenshot; -const ExtensionUtils = imports.misc.extensionUtils; const Me = ExtensionUtils.getCurrentExtension(); const Convenience = ExtensionUtils.getSettings ? ExtensionUtils : Me.imports.convenience; const Extension = Me.imports.extension; @@ -643,6 +644,7 @@ var DrawingArea = new Lang.Class({ }, _startWriting: function() { + let [x, y] = [this.currentElement.x, this.currentElement.y]; this.currentElement.text = ''; this.currentElement.cursorPosition = 0; this.emit('show-osd', null, _("Type your text and press %s") @@ -651,12 +653,19 @@ var DrawingArea = new Lang.Class({ this.textHasCursor = true; this._redisplay(); - this.textEntry = new St.Entry({ visible: false }); + this.textEntry = new St.Entry({ visible: false, x, y }); this.get_parent().add_child(this.textEntry); this.textEntry.grab_key_focus(); this.updateActionMode(); this.updatePointerCursor(); + let ibusCandidatePopup = Main.layoutManager.uiGroup.get_children().filter(child => + child.has_style_class_name && child.has_style_class_name('candidate-popup-boxpointer'))[0] || null; + if (ibusCandidatePopup) { + this.ibusHandler = ibusCandidatePopup.connect('notify::visible', popup => popup.visible && (this.textEntry.visible = true)); + this.textEntry.connect('destroy', () => ibusCandidatePopup.disconnect(this.ibusHandler)); + } + this.textEntry.clutterText.connect('activate', (clutterText) => { let startNewLine = true; this._stopWriting(startNewLine); @@ -703,13 +712,13 @@ var DrawingArea = new Lang.Class({ // copy object, the original keep existing in this.elements this.currentElement = Object.create(this.currentElement); this.currentElement.lineIndex ++; - let height = Math.abs(this.currentElement.points[1][1] - this.currentElement.points[0][1]); // define a new 'points' array, the original keep existing in this.elements this.currentElement.points = [ - [this.currentElement.points[0][0], this.currentElement.points[0][1] + height], - [this.currentElement.points[1][0], this.currentElement.points[1][1] + height] + [this.currentElement.points[0][0], this.currentElement.points[0][1] + this.currentElement.height], + [this.currentElement.points[1][0], this.currentElement.points[1][1] + this.currentElement.height] ]; this.currentElement.text = ""; + this.textEntry.set_y(this.currentElement.y); } else { this.currentElement = null; this._stopTextCursorTimeout(); diff --git a/elements.js b/elements.js index 6eb40ee..910e897 100644 --- a/elements.js +++ b/elements.js @@ -600,12 +600,28 @@ const TextElement = new Lang.Class({ }; }, + get x() { + // this.textWidth is computed during Cairo building. + return this.points[1][0] - (this.textRightAligned ? this.textWidth : 0); + }, + + get y() { + return Math.max(this.points[0][1], this.points[1][1]); + }, + + get height() { + return Math.abs(this.points[1][1] - this.points[0][1]); + }, + + // When rotating grouped lines, lineOffset is used to retrieve the rotation center of the first line. + get lineOffset() { + return (this.lineIndex || 0) * this.height; + }, + _drawCairo: function(cr, params) { - let points = this.points; - - if (points.length == 2) { + if (this.points.length == 2) { let layout = PangoCairo.create_layout(cr); - let fontSize = Math.abs(points[1][1] - points[0][1]) * Pango.SCALE; + let fontSize = this.height * Pango.SCALE; let fontDescription = new Pango.FontDescription(); fontDescription.set_absolute_size(fontSize); ['family', 'weight', 'style', 'stretch', 'variant'].forEach(attribute => { @@ -617,7 +633,7 @@ const TextElement = new Lang.Class({ layout.set_font_description(fontDescription); layout.set_text(this.text, -1); this.textWidth = layout.get_pixel_size()[0]; - cr.moveTo(points[1][0] - (this.textRightAligned ? this.textWidth : 0), Math.max(points[0][1],points[1][1]) - layout.get_baseline() / Pango.SCALE); + cr.moveTo(this.x, this.y - layout.get_baseline() / Pango.SCALE); layout.set_text(this.text, -1); PangoCairo.show_layout(cr, layout); @@ -625,19 +641,20 @@ const TextElement = new Lang.Class({ let cursorPosition = this.cursorPosition == -1 ? this.text.length : this.cursorPosition; layout.set_text(this.text.slice(0, cursorPosition), -1); let width = layout.get_pixel_size()[0]; - cr.rectangle(points[1][0] - (this.textRightAligned ? this.textWidth : 0) + width, Math.max(points[0][1],points[1][1]), - Math.abs(points[1][1] - points[0][1]) / 25, - Math.abs(points[1][1] - points[0][1])); + cr.rectangle(this.x + width, this.y, + this.height / 25, - this.height); cr.fill(); } - if (params.showTextRectangle || params.drawTextRectangle) { - cr.rectangle(points[1][0] - (this.textRightAligned ? this.textWidth : 0), Math.max(points[0][1], points[1][1]), - this.textWidth, - Math.abs(points[1][1] - points[0][1])); - if (params.showTextRectangle) - setDummyStroke(cr); - else - // Only draw the rectangle to find the element, not to show it. - cr.setLineWidth(0); + if (params.showTextRectangle) { + cr.rectangle(this.x, this.y - this.lineOffset, + this.textWidth, - this.height); + setDummyStroke(cr); + } else if (params.drawTextRectangle) { + cr.rectangle(this.x, this.y, + this.textWidth, - this.height); + // Only draw the rectangle to find the element, not to show it. + cr.setLineWidth(0); } } }, @@ -648,15 +665,15 @@ const TextElement = new Lang.Class({ _drawSvg: function(transAttribute) { let row = "\n "; - let points = this.points.map((point) => [Math.round(point[0]*100)/100, Math.round(point[1]*100)/100]); + let [x, y, height] = [Math.round(this.x*100)/100, Math.round(this.y*100)/100, Math.round(this.height*100)/100]; let color = this.eraser ? bgColor : this.color; let attributes = ''; - if (points.length == 2) { + if (this.points.length == 2) { attributes = `fill="${color}" ` + `stroke="transparent" ` + `stroke-opacity="0" ` + - `font-size="${Math.abs(points[1][1] - points[0][1])}"`; + `font-size="${height}"`; if (this.font.family) attributes += ` font-family="${this.font.family}"`; @@ -669,9 +686,8 @@ const TextElement = new Lang.Class({ if (this.font.variant && FontVariantNames[this.font.variant]) attributes += ` font-variant="${FontVariantNames[this.font.variant].toLowerCase()}"`; - // this.textWidth is computed during Cairo building. - row += `${this.text}`; + row += `${this.text}`; } return row; @@ -698,15 +714,10 @@ const TextElement = new Lang.Class({ } }, - // When rotating grouped lines, lineOffset is used to retrieve the rotation center of the first line. - _getLineOffset: function() { - return (this.lineIndex || 0) * Math.abs(this.points[1][1] - this.points[0][1]); - }, - _getOriginalCenter: function() { if (!this._originalCenter) { let points = this.points; - this._originalCenter = this.textWidth ? [points[1][0], Math.max(points[0][1], points[1][1]) - this._getLineOffset()] : + this._originalCenter = this.textWidth ? [points[1][0], Math.max(points[0][1], points[1][1]) - this.lineOffset] : points.length >= 3 ? getCentroid(points) : getNaiveCenter(points); }