Пример #1
0
        private void OnIMCommit(object o, CommitArgs args)
        {
            try {
                var str = new StringBuilder();

                for (int i = 0; i < args.Str.Length; i++)
                {
                    char utf32Char;
                    if (char.IsHighSurrogate(args.Str, i))
                    {
                        utf32Char = (char)char.ConvertToUtf32(args.Str, i);
                        i++;
                    }
                    else
                    {
                        utf32Char = args.Str[i];
                    }

                    str.Append(utf32Char.ToString());
                }

                CurrentTextEngine.InsertText(str.ToString());
            } finally {
                imContext.Reset();
            }
        }
Пример #2
0
 protected override bool OnHandleCopy(Document document, Clipboard cb)
 {
     if (!is_editing)
     {
         return(false);
     }
     CurrentTextEngine.PerformCopy(cb);
     return(true);
 }
Пример #3
0
 public override bool TryHandleCopy(Clipboard cb)
 {
     if (CurrentTextEngine.EditMode == EditingMode.NotEditing)
     {
         return(false);
     }
     CurrentTextEngine.PerformCopy(cb);
     return(true);
 }
Пример #4
0
 public override bool TryHandleCopy(Clipboard cb)
 {
     if (!is_editing)
     {
         return(false);
     }
     CurrentTextEngine.PerformCopy(cb);
     return(true);
 }
Пример #5
0
        private bool TryHandleChar(EventKey eventKey)
        {
            // Try to handle it as a character
            if (CurrentTextEngine.HandleKeyPress(eventKey))
            {
                return(true);
            }

            // We didn't handle the key
            return(false);
        }
Пример #6
0
        /// <summary>
        /// Finalize re-editable text (if applicable).
        /// </summary>
        public void FinalizeText()
        {
            //If this is true, don't finalize any text - this is used to prevent the code from looping recursively.
            if (!ignoreCloneFinalizations)
            {
                //Only bother finalizing text if editing.
                if (CurrentTextEngine.EditMode == EditingMode.Editing)
                {
                    //Start ignoring any Surface.Clone calls from this point on (so that it doesn't start to loop).
                    ignoreCloneFinalizations = true;



                    Document doc = PintaCore.Workspace.ActiveDocument;

                    //Create a backup of everything before redrawing the text and etc.
                    Cairo.ImageSurface oldTextSurface = doc.CurrentUserLayer.TextLayer.Surface.Clone();
                    Cairo.ImageSurface oldUserSurface = doc.CurrentUserLayer.Surface.Clone();
                    TextEngine         oldTextEngine  = CurrentTextEngine.Clone();



                    //Draw the text onto the UserLayer (without the cursor) rather than the TextLayer.
                    RedrawText(false, false);

                    //Clear the TextLayer.
                    doc.CurrentUserLayer.TextLayer.Clear();

                    //Clear the text and its boundaries.
                    CurrentTextEngine.Clear();
                    CurrentTextBounds = Gdk.Rectangle.Zero;



                    //Create a new TextHistoryItem so that the finalization of the text can be undone. Construct
                    //it on the spot so that it is more memory efficient if the changes are small.
                    TextHistoryItem hist = new TextHistoryItem(Icon, FinalizeName, oldTextSurface, oldUserSurface, oldTextEngine, doc.CurrentUserLayer);

                    //Add the new TextHistoryItem.
                    doc.History.PushNewItem(hist);



                    //Stop ignoring any Surface.Clone calls from this point on.
                    ignoreCloneFinalizations = false;



                    //Now that the text has been finalized, change its state.
                    CurrentTextEngine.textMode = TextMode.Unchanged;
                }
            }
        }
Пример #7
0
        private void UpdateFont()
        {
            if (CurrentTextEngine != null)
            {
                CurrentTextEngine.Alignment = Alignment;
                CurrentTextEngine.SetFont(Font, FontSize, bold_btn.Active, italic_btn.Active, underscore_btn.Active);
            }

            if (is_editing)
            {
                RedrawText(true, true);
            }
        }
Пример #8
0
        protected override bool OnHandlePaste(Document document, Clipboard cb)
        {
            if (!is_editing)
            {
                return(false);
            }

            if (!CurrentTextEngine.PerformPaste(cb))
            {
                return(false);
            }
            RedrawText(true, true);
            return(true);
        }
Пример #9
0
        public override bool TryHandlePaste(Clipboard cb)
        {
            if (!is_editing)
            {
                return(false);
            }

            if (!CurrentTextEngine.PerformPaste(cb))
            {
                return(false);
            }
            RedrawText(true, true);
            return(true);
        }
Пример #10
0
        private void StartEditing()
        {
            is_editing = true;

            //Start ignoring any Surface.Clone calls from this point on (so that it doesn't start to loop).
            ignoreCloneFinalizations = true;

            //Store the previous state of the current UserLayer's and TextLayer's ImageSurfaces.
            user_undo_surface = PintaCore.Workspace.ActiveDocument.CurrentUserLayer.Surface.Clone();
            text_undo_surface = PintaCore.Workspace.ActiveDocument.CurrentUserLayer.TextLayer.Surface.Clone();
            undo_engine       = CurrentTextEngine.Clone();

            //Stop ignoring any Surface.Clone calls from this point on.
            ignoreCloneFinalizations = false;
        }
Пример #11
0
        private void UpdateFont()
        {
            if (PintaCore.Workspace.HasOpenDocuments)
            {
                var font = font_button.Widget.FontDesc.Copy();
                font.Weight = bold_btn.Active ? Pango.Weight.Bold : Pango.Weight.Normal;
                font.Style  = italic_btn.Active ? Pango.Style.Italic : Pango.Style.Normal;

                CurrentTextEngine.SetFont(font, Alignment, underscore_btn.Active);
            }

            if (is_editing)
            {
                RedrawText(true, true);
            }
        }
Пример #12
0
        protected override bool OnKeyDown(Document document, ToolKeyEventArgs e)
        {
            if (!PintaCore.Workspace.HasOpenDocuments)
            {
                return(false);
            }

            // If we are dragging the text, we
            // aren't going to handle key presses
            if (tracking)
            {
                return(false);
            }

            // Ignore anything with Alt pressed
            if (e.IsAltPressed)
            {
                return(false);
            }

            ctrlKey = e.Key.IsControlKey();
            UpdateMouseCursor(document);

            // Assume that we are going to handle the key
            bool keyHandled = true;

            if (is_editing)
            {
                switch (e.Key)
                {
                case Gdk.Key.BackSpace:
                    CurrentTextEngine.PerformBackspace();
                    break;

                case Gdk.Key.Delete:
                    CurrentTextEngine.PerformDelete();
                    break;

                case Gdk.Key.KP_Enter:
                case Gdk.Key.Return:
                    CurrentTextEngine.PerformEnter();
                    break;

                case Gdk.Key.Left:
                    CurrentTextEngine.PerformLeft(e.IsControlPressed, e.IsShiftPressed);
                    break;

                case Gdk.Key.Right:
                    CurrentTextEngine.PerformRight(e.IsControlPressed, e.IsShiftPressed);
                    break;

                case Gdk.Key.Up:
                    CurrentTextEngine.PerformUp(e.IsShiftPressed);
                    break;

                case Gdk.Key.Down:
                    CurrentTextEngine.PerformDown(e.IsShiftPressed);
                    break;

                case Gdk.Key.Home:
                    CurrentTextEngine.PerformHome(e.IsControlPressed, e.IsShiftPressed);
                    break;

                case Gdk.Key.End:
                    CurrentTextEngine.PerformEnd(e.IsControlPressed, e.IsShiftPressed);
                    break;

                case Gdk.Key.Next:
                case Gdk.Key.Prior:
                    break;

                case Gdk.Key.Escape:
                    StopEditing(false);
                    return(true);

                case Gdk.Key.Insert:
                    if (e.IsShiftPressed)
                    {
                        Gtk.Clipboard cb = Gtk.Clipboard.Get(Gdk.Atom.Intern("CLIPBOARD", false));
                        CurrentTextEngine.PerformPaste(cb);
                    }
                    else if (e.IsControlPressed)
                    {
                        Gtk.Clipboard cb = Gtk.Clipboard.Get(Gdk.Atom.Intern("CLIPBOARD", false));
                        CurrentTextEngine.PerformCopy(cb);
                    }
                    break;

                default:
                    if (e.IsControlPressed)
                    {
                        if (e.Key == Gdk.Key.z)
                        {
                            //Ctrl + Z for undo while editing.
                            OnHandleUndo(document);

                            if (PintaCore.Workspace.ActiveDocument.History.CanUndo)
                            {
                                PintaCore.Workspace.ActiveDocument.History.Undo();
                            }

                            return(true);
                        }
                        else if (e.Key == Gdk.Key.i)
                        {
                            italic_btn.Toggle();
                            UpdateFont();
                        }
                        else if (e.Key == Gdk.Key.b)
                        {
                            bold_btn.Toggle();
                            UpdateFont();
                        }
                        else if (e.Key == Gdk.Key.u)
                        {
                            underscore_btn.Toggle();
                            UpdateFont();
                        }
                        else if (e.Key == Gdk.Key.a)
                        {
                            // Select all of the text.
                            CurrentTextEngine.PerformHome(false, false);
                            CurrentTextEngine.PerformEnd(true, true);
                        }
                        else
                        {
                            //Ignore command shortcut.
                            return(false);
                        }
                    }
                    else
                    {
                        if (e.Event is not null)
                        {
                            keyHandled = TryHandleChar(e.Event);
                        }
                    }

                    break;
                }
                if (keyHandled)
                {
                    imContext.FocusOut();
                    RedrawText(true, true);
                    imContext.FocusIn();
                }
            }
            else
            {
                // If we're not editing, allow the key press to be handled elsewhere (e.g. for selecting another tool).
                keyHandled = false;
            }

            return(keyHandled);
        }
Пример #13
0
        protected override void OnMouseDown(Document document, ToolMouseEventArgs e)
        {
            ctrlKey = e.IsControlPressed;

            //Store the mouse position.
            Point pt = e.PointDouble.ToGdkPoint();

            // Grab focus so we can get keystrokes
            imContext.FocusIn();

            if (selection != null)
            {
                selection.Dispose();
            }
            selection = document.Selection.Clone();

            // A right click allows you to move the text around
            if (e.MouseButton == MouseButton.Right)
            {
                //The user is dragging text with the right mouse button held down, so track the mouse as it moves.
                tracking = true;

                //Remember the position of the mouse before the text is dragged.
                startMouseXY    = e.PointDouble;
                startClickPoint = clickPoint;

                //Change the cursor to indicate that the text is being dragged.
                SetCursor(cursor_hand);

                return;
            }

            // The user clicked the left mouse button
            if (e.MouseButton == MouseButton.Left)
            {
                // If the user is [editing or holding down Ctrl] and clicked
                //within the text, move the cursor to the click location
                if ((is_editing || ctrlKey) && CurrentTextBounds.ContainsCorrect(pt))
                {
                    StartEditing();

                    //Change the position of the cursor to where the mouse clicked.
                    TextPosition p = CurrentTextLayout.PointToTextPosition(pt);
                    CurrentTextEngine.SetCursorPosition(p, true);

                    //Redraw the text with the new cursor position.
                    RedrawText(true, true);

                    return;
                }

                // We're already editing and the user clicked outside the text,
                // commit the user's work, and start a new edit
                switch (CurrentTextEngine.State)
                {
                // We were editing, save and stop
                case TextMode.Uncommitted:
                    StopEditing(true);
                    break;

                // We were editing, but nothing had been
                // keyed. Stop editing.
                case TextMode.Unchanged:
                    StopEditing(false);
                    break;
                }

                if (ctrlKey)
                {
                    //Go through every UserLayer.
                    foreach (UserLayer ul in document.Layers.UserLayers)
                    {
                        //Check each UserLayer's editable text boundaries to see if they contain the mouse position.
                        if (ul.textBounds.ContainsCorrect(pt))
                        {
                            //The mouse clicked on editable text.

                            //Change the current UserLayer to the Layer that contains the text that was clicked on.
                            document.Layers.SetCurrentUserLayer(ul);

                            //The user is editing text now.
                            is_editing = true;

                            //Set the cursor in the editable text where the mouse was clicked.
                            TextPosition p = CurrentTextLayout.PointToTextPosition(pt);
                            CurrentTextEngine.SetCursorPosition(p, true);

                            //Redraw the editable text with the cursor.
                            RedrawText(true, true);

                            //Don't check any more UserLayers - stop at the first UserLayer that has editable text containing the mouse position.
                            return;
                        }
                    }
                }
                else
                {
                    if (CurrentTextEngine.State == TextMode.NotFinalized)
                    {
                        //The user is making a new text and the old text hasn't been finalized yet.
                        FinalizeText();
                    }

                    if (!is_editing)
                    {
                        // Start editing at the cursor location
                        clickPoint = pt;
                        CurrentTextEngine.Clear();
                        UpdateFont();
                        clickPoint.Offset(0, -CurrentTextLayout.FontHeight / 2);
                        CurrentTextEngine.Origin = clickPoint;
                        StartEditing();
                        RedrawText(true, true);
                    }
                }
            }
        }
Пример #14
0
        /// <summary>
        /// Draws the text.
        /// </summary>
        /// <param name="showCursor">Whether or not to show the mouse cursor in the drawing.</param>
        /// <param name="useTextLayer">Whether or not to use the TextLayer (as opposed to the Userlayer).</param>
        private void RedrawText(bool showCursor, bool useTextLayer)
        {
            Rectangle r = CurrentTextLayout.GetLayoutBounds();

            r.Inflate(10 + OutlineWidth, 10 + OutlineWidth);
            InflateAndInvalidate(r);
            CurrentTextBounds = r;

            Rectangle cursorBounds = Rectangle.Zero;

            Cairo.ImageSurface surf;

            if (!useTextLayer)
            {
                //Draw text on the current UserLayer's surface as finalized text.
                surf = PintaCore.Workspace.ActiveDocument.Layers.CurrentUserLayer.Surface;
            }
            else
            {
                //Draw text on the current UserLayer's TextLayer's surface as re-editable text.
                surf = PintaCore.Workspace.ActiveDocument.Layers.CurrentUserLayer.TextLayer.Layer.Surface;

                ClearTextLayer();
            }

            using (var g = new Cairo.Context(surf)) {
                g.Save();

                // Show selection if on text layer
                if (useTextLayer)
                {
                    // Selected Text
                    Cairo.Color c = new Cairo.Color(0.7, 0.8, 0.9, 0.5);
                    foreach (Rectangle rect in CurrentTextLayout.SelectionRectangles)
                    {
                        g.FillRectangle(rect.ToCairoRectangle(), c);
                    }
                }

                if (selection != null)
                {
                    selection.Clip(g);
                }

                g.MoveTo(new Cairo.PointD(CurrentTextEngine.Origin.X, CurrentTextEngine.Origin.Y));

                g.SetSourceColor(PintaCore.Palette.PrimaryColor);

                //Fill in background
                if (BackgroundFill)
                {
                    using (var g2 = new Cairo.Context(surf)) {
                        if (selection != null)
                        {
                            selection.Clip(g2);
                        }

                        g2.FillRectangle(CurrentTextLayout.GetLayoutBounds().ToCairoRectangle(), PintaCore.Palette.SecondaryColor);
                    }
                }

                // Draw the text
                if (FillText)
                {
                    Pango.CairoHelper.ShowLayout(g, CurrentTextLayout.Layout);
                }

                if (FillText && StrokeText)
                {
                    g.SetSourceColor(PintaCore.Palette.SecondaryColor);
                    g.LineWidth = OutlineWidth;

                    Pango.CairoHelper.LayoutPath(g, CurrentTextLayout.Layout);
                    g.Stroke();
                }
                else if (StrokeText)
                {
                    g.SetSourceColor(PintaCore.Palette.PrimaryColor);
                    g.LineWidth = OutlineWidth;

                    Pango.CairoHelper.LayoutPath(g, CurrentTextLayout.Layout);
                    g.Stroke();
                }

                if (showCursor)
                {
                    var loc   = CurrentTextLayout.GetCursorLocation();
                    var color = PintaCore.Palette.PrimaryColor;

                    g.Antialias = Cairo.Antialias.None;
                    g.DrawLine(new Cairo.PointD(loc.X, loc.Y),
                               new Cairo.PointD(loc.X, loc.Y + loc.Height),
                               color, 1);

                    cursorBounds = Rectangle.Inflate(loc, 2, 10);
                }

                g.Restore();


                if (useTextLayer && (is_editing || ctrlKey) && !CurrentTextEngine.IsEmpty())
                {
                    //Draw the text edit rectangle.

                    g.Save();

                    g.Translate(.5, .5);

                    using (Cairo.Path p = g.CreateRectanglePath(CurrentTextBounds.ToCairoRectangle())) {
                        g.AppendPath(p);
                    }

                    g.LineWidth = 1;

                    g.SetSourceColor(new Cairo.Color(1, 1, 1));
                    g.StrokePreserve();

                    g.SetDash(new double[] { 2, 4 }, 0);
                    g.SetSourceColor(new Cairo.Color(1, .1, .2));

                    g.Stroke();

                    g.Restore();
                }
            }

            InflateAndInvalidate(PintaCore.Workspace.ActiveDocument.Layers.CurrentUserLayer.previousTextBounds);
            PintaCore.Workspace.Invalidate(old_cursor_bounds);
            InflateAndInvalidate(r);
            PintaCore.Workspace.Invalidate(cursorBounds);

            old_cursor_bounds = cursorBounds;
        }
Пример #15
0
        protected override void OnKeyDown(DrawingArea canvas, KeyPressEventArgs args)
        {
            if (!PintaCore.Workspace.HasOpenDocuments)
            {
                args.RetVal = false;
                return;
            }

            Gdk.ModifierType modifier = args.Event.State;

            // If we are dragging the text, we
            // aren't going to handle key presses
            if (tracking)
            {
                return;
            }

            // Ignore anything with Alt pressed
            if ((modifier & Gdk.ModifierType.Mod1Mask) != 0)
            {
                return;
            }

            ctrlKey = (args.Event.Key == Gdk.Key.Control_L || args.Event.Key == Gdk.Key.Control_R);
            UpdateMouseCursor();

            // Assume that we are going to handle the key
            bool keyHandled = true;

            if (is_editing)
            {
                switch (args.Event.Key)
                {
                case Gdk.Key.BackSpace:
                    CurrentTextEngine.PerformBackspace();
                    break;

                case Gdk.Key.Delete:
                    CurrentTextEngine.PerformDelete();
                    break;

                case Gdk.Key.KP_Enter:
                case Gdk.Key.Return:
                    CurrentTextEngine.PerformEnter();
                    break;

                case Gdk.Key.Left:
                    CurrentTextEngine.PerformLeft((modifier & Gdk.ModifierType.ControlMask) != 0, (modifier & Gdk.ModifierType.ShiftMask) != 0);
                    break;

                case Gdk.Key.Right:
                    CurrentTextEngine.PerformRight((modifier & Gdk.ModifierType.ControlMask) != 0, (modifier & Gdk.ModifierType.ShiftMask) != 0);
                    break;

                case Gdk.Key.Up:
                    CurrentTextEngine.PerformUp((modifier & Gdk.ModifierType.ShiftMask) != 0);
                    break;

                case Gdk.Key.Down:
                    CurrentTextEngine.PerformDown((modifier & Gdk.ModifierType.ShiftMask) != 0);
                    break;

                case Gdk.Key.Home:
                    CurrentTextEngine.PerformHome((modifier & Gdk.ModifierType.ControlMask) != 0, (modifier & Gdk.ModifierType.ShiftMask) != 0);
                    break;

                case Gdk.Key.End:
                    CurrentTextEngine.PerformEnd((modifier & Gdk.ModifierType.ControlMask) != 0, (modifier & Gdk.ModifierType.ShiftMask) != 0);
                    break;

                case Gdk.Key.Next:
                case Gdk.Key.Prior:
                    break;

                case Gdk.Key.Escape:
                    StopEditing(false);
                    return;

                case Gdk.Key.Insert:
                    if (modifier.IsShiftPressed())
                    {
                        Gtk.Clipboard cb = Gtk.Clipboard.Get(Gdk.Atom.Intern("CLIPBOARD", false));
                        CurrentTextEngine.PerformPaste(cb);
                    }
                    else if (modifier.IsControlPressed())
                    {
                        Gtk.Clipboard cb = Gtk.Clipboard.Get(Gdk.Atom.Intern("CLIPBOARD", false));
                        CurrentTextEngine.PerformCopy(cb);
                    }
                    break;

                default:
                    if (modifier.IsControlPressed())
                    {
                        if (args.Event.Key == Gdk.Key.z)
                        {
                            //Ctrl + Z for undo while editing.
                            TryHandleUndo();

                            if (PintaCore.Workspace.ActiveDocument.History.CanUndo)
                            {
                                PintaCore.Workspace.ActiveDocument.History.Undo();
                            }

                            return;
                        }
                        else if (args.Event.Key == Gdk.Key.i)
                        {
                            italic_btn.Toggle();
                            UpdateFont();
                        }
                        else if (args.Event.Key == Gdk.Key.b)
                        {
                            bold_btn.Toggle();
                            UpdateFont();
                        }
                        else if (args.Event.Key == Gdk.Key.u)
                        {
                            underscore_btn.Toggle();
                            UpdateFont();
                        }
                        else if (args.Event.Key == Gdk.Key.a)
                        {
                            // Select all of the text.
                            CurrentTextEngine.PerformHome(false, false);
                            CurrentTextEngine.PerformEnd(true, true);
                        }
                        else
                        {
                            //Ignore command shortcut.
                            return;
                        }
                    }
                    else
                    {
                        keyHandled = TryHandleChar(args.Event);
                    }

                    break;
                }

                // If we processed a key, update the display
                if (keyHandled)
                {
                    RedrawText(true, true);
                }
            }
            else
            {
                // If we're not editing, allow the key press to be handled elsewhere (e.g. for selecting another tool).
                keyHandled = false;
            }

            args.RetVal = keyHandled;
        }
Пример #16
0
        protected override void OnMouseDown(DrawingArea canvas, ButtonPressEventArgs args, Cairo.PointD point)
        {
            ctrlKey = (args.Event.State & ModifierType.ControlMask) != 0;

            //Store the mouse position.
            Point pt = point.ToGdkPoint();

            // Grab focus so we can get keystrokes
            PintaCore.Chrome.Canvas.GrabFocus();

            if (selection != null)
            {
                selection.DisposeSelection();
            }
            selection = PintaCore.Workspace.ActiveDocument.Selection.Clone();

            // A right click allows you to move the text around
            if (args.Event.Button == 3)
            {
                //The user is dragging text with the right mouse button held down, so track the mouse as it moves.
                tracking = true;

                //Remember the position of the mouse before the text is dragged.
                startMouseXY    = point;
                startClickPoint = clickPoint;

                //Change the cursor to indicate that the text is being dragged.
                SetCursor(cursor_hand);

                return;
            }

            // The user clicked the left mouse button
            if (args.Event.Button == 1)
            {
                // If the user is [editing or holding down Ctrl] and clicked
                //within the text, move the cursor to the click location
                if ((is_editing || ctrlKey) && CurrentTextBounds.ContainsCorrect(pt))
                {
                    StartEditing();

                    //Change the position of the cursor to where the mouse clicked.
                    Position p = CurrentTextEngine.PointToTextPosition(pt);
                    CurrentTextEngine.SetCursorPosition(p, true);

                    //Redraw the text with the new cursor position.
                    RedrawText(true, true);

                    return;
                }

                // We're already editing and the user clicked outside the text,
                // commit the user's work, and start a new edit
                switch (CurrentTextEngine.EditMode)
                {
                // We were editing, save and stop
                case EditingMode.Editing:
                    StopEditing(true);
                    break;

                // We were editing, but nothing had been
                // keyed. Stop editing.
                case EditingMode.EmptyEdit:
                    StopEditing(false);
                    break;
                }

                if (ctrlKey)
                {
                    //Go through every UserLayer.
                    foreach (UserLayer ul in PintaCore.Workspace.ActiveDocument.UserLayers)
                    {
                        //Check each UserLayer's editable text boundaries to see if they contain the mouse position.
                        if (ul.textBounds.ContainsCorrect(pt))
                        {
                            //The mouse clicked on editable text.

                            //Change the current UserLayer to the Layer that contains the text that was clicked on.
                            PintaCore.Workspace.ActiveDocument.SetCurrentUserLayer(ul);

                            //The user is editing text now.
                            is_editing = true;

                            //Set the cursor in the editable text where the mouse was clicked.
                            Position p = CurrentTextEngine.PointToTextPosition(pt);
                            CurrentTextEngine.SetCursorPosition(p, true);

                            //Redraw the editable text with the cursor.
                            RedrawText(true, true);

                            //Don't check any more UserLayers - stop at the first UserLayer that has editable text containing the mouse position.
                            return;
                        }
                    }
                }
                else
                {
                    if (CurrentTextEngine.textMode == TextMode.NotFinalized)
                    {
                        //The user is making a new text and the old text hasn't been finalized yet.
                        FinalizeText();
                    }

                    if (!is_editing)
                    {
                        // Start editing at the cursor location
                        clickPoint = pt;
                        CurrentTextEngine.Clear();
                        clickPoint.Offset(0, -CurrentTextEngine.FontHeight / 2);
                        CurrentTextEngine.Origin = clickPoint;
                        StartEditing();
                        RedrawText(true, true);
                    }
                }
            }
        }