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(); } }
protected override bool OnHandleCopy(Document document, Clipboard cb) { if (!is_editing) { return(false); } CurrentTextEngine.PerformCopy(cb); return(true); }
public override bool TryHandleCopy(Clipboard cb) { if (CurrentTextEngine.EditMode == EditingMode.NotEditing) { return(false); } CurrentTextEngine.PerformCopy(cb); return(true); }
public override bool TryHandleCopy(Clipboard cb) { if (!is_editing) { return(false); } CurrentTextEngine.PerformCopy(cb); return(true); }
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); }
/// <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; } } }
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); } }
protected override bool OnHandlePaste(Document document, Clipboard cb) { if (!is_editing) { return(false); } if (!CurrentTextEngine.PerformPaste(cb)) { return(false); } RedrawText(true, true); return(true); }
public override bool TryHandlePaste(Clipboard cb) { if (!is_editing) { return(false); } if (!CurrentTextEngine.PerformPaste(cb)) { return(false); } RedrawText(true, true); return(true); }
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; }
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); } }
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); }
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); } } } }
/// <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; }
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; }
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); } } } }