question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TextView: Additional Move method proposals

See original GitHub issue

With the update merged that added two public methods to the TextView for MoveHome and MoveEnd I would like to propose the following:

  1. The existing MoveUp() and MoveDown() methods be changed from private to public.
  2. Add MoveRight() and MoveLeft() public methods that allow programmatic moving of the cursor to the right and left (with an overload for each that will specify whether the cursor should go the next or previous lines if at EOL or BOL respectively or stop at the line barrier).

With the 2nd item the code in ProcessKey() that handles Key.CursorRight and Key.CursorLeft can then call MoveRight() and MoveLeft() with the option to move lines when at EOL or BOL.

The only thing I waffled on was whether MoveRight() and MoveLeft() should move the cursor to a different line or not by default without specifying. I don’t really have a strong opinion either way.

I went ahead and coded this so you see what I’m proposing.

https://github.com/blakepell/gui.cs/commit/90497f72a33e60bceeb2dac6b6f7e6cd87ec92b7#diff-d62dd6237dd225328a492cfce16930be

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:1
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
tigcommented, Nov 4, 2022

I think this issue was addressed with the KeyBinding stuff added in and around #1566 and #1548.

void Initialize ()
		{
			CanFocus = true;
			Used = true;

			model.LinesLoaded += Model_LinesLoaded;
			historyText.ChangeText += HistoryText_ChangeText;

			Initialized += TextView_Initialized;

			// Things this view knows how to do
			AddCommand (Command.PageDown, () => { ProcessPageDown (); return true; });
			AddCommand (Command.PageDownExtend, () => { ProcessPageDownExtend (); return true; });
			AddCommand (Command.PageUp, () => { ProcessPageUp (); return true; });
			AddCommand (Command.PageUpExtend, () => { ProcessPageUpExtend (); return true; });
			AddCommand (Command.LineDown, () => { ProcessMoveDown (); return true; });
			AddCommand (Command.LineDownExtend, () => { ProcessMoveDownExtend (); return true; });
			AddCommand (Command.LineUp, () => { ProcessMoveUp (); return true; });
			AddCommand (Command.LineUpExtend, () => { ProcessMoveUpExtend (); return true; });
			AddCommand (Command.Right, () => ProcessMoveRight ());
			AddCommand (Command.RightExtend, () => { ProcessMoveRightExtend (); return true; });
			AddCommand (Command.Left, () => ProcessMoveLeft ());
			AddCommand (Command.LeftExtend, () => { ProcessMoveLeftExtend (); return true; });
			AddCommand (Command.DeleteCharLeft, () => { ProcessDeleteCharLeft (); return true; });
			AddCommand (Command.StartOfLine, () => { ProcessMoveStartOfLine (); return true; });
			AddCommand (Command.StartOfLineExtend, () => { ProcessMoveStartOfLineExtend (); return true; });
			AddCommand (Command.DeleteCharRight, () => { ProcessDeleteCharRight (); return true; });
			AddCommand (Command.EndOfLine, () => { ProcessMoveEndOfLine (); return true; });
			AddCommand (Command.EndOfLineExtend, () => { ProcessMoveEndOfLineExtend (); return true; });
			AddCommand (Command.CutToEndLine, () => { KillToEndOfLine (); return true; });
			AddCommand (Command.CutToStartLine, () => { KillToStartOfLine (); return true; });
			AddCommand (Command.Paste, () => { ProcessPaste (); return true; });
			AddCommand (Command.ToggleExtend, () => { ToggleSelecting (); return true; });
			AddCommand (Command.Copy, () => { ProcessCopy (); return true; });
			AddCommand (Command.Cut, () => { ProcessCut (); return true; });
			AddCommand (Command.WordLeft, () => { ProcessMoveWordBackward (); return true; });
			AddCommand (Command.WordLeftExtend, () => { ProcessMoveWordBackwardExtend (); return true; });
			AddCommand (Command.WordRight, () => { ProcessMoveWordForward (); return true; });
			AddCommand (Command.WordRightExtend, () => { ProcessMoveWordForwardExtend (); return true; });
			AddCommand (Command.KillWordForwards, () => { ProcessKillWordForward (); return true; });
			AddCommand (Command.KillWordBackwards, () => { ProcessKillWordBackward (); return true; });
			AddCommand (Command.NewLine, () => ProcessReturn ());
			AddCommand (Command.BottomEnd, () => { MoveBottomEnd (); return true; });
			AddCommand (Command.BottomEndExtend, () => { MoveBottomEndExtend (); return true; });
			AddCommand (Command.TopHome, () => { MoveTopHome (); return true; });
			AddCommand (Command.TopHomeExtend, () => { MoveTopHomeExtend (); return true; });
			AddCommand (Command.SelectAll, () => { ProcessSelectAll (); return true; });
			AddCommand (Command.ToggleOverwrite, () => { ProcessSetOverwrite (); return true; });
			AddCommand (Command.EnableOverwrite, () => { SetOverwrite (true); return true; });
			AddCommand (Command.DisableOverwrite, () => { SetOverwrite (false); return true; });
			AddCommand (Command.Tab, () => ProcessTab ());
			AddCommand (Command.BackTab, () => ProcessBackTab ());
			AddCommand (Command.NextView, () => ProcessMoveNextView ());
			AddCommand (Command.PreviousView, () => ProcessMovePreviousView ());
			AddCommand (Command.Undo, () => { UndoChanges (); return true; });
			AddCommand (Command.Redo, () => { RedoChanges (); return true; });
			AddCommand (Command.DeleteAll, () => { DeleteAll (); return true; });
			AddCommand (Command.Accept, () => {
				ContextMenu.Position = new Point (CursorPosition.X - leftColumn + 2, CursorPosition.Y - topRow + 2);
				ShowContextMenu ();
				return true;
			});

			// Default keybindings for this view
			AddKeyBinding (Key.PageDown, Command.PageDown);
			AddKeyBinding (Key.V | Key.CtrlMask, Command.PageDown);

			AddKeyBinding (Key.PageDown | Key.ShiftMask, Command.PageDownExtend);

			AddKeyBinding (Key.PageUp, Command.PageUp);
			AddKeyBinding (((int)'V' + Key.AltMask), Command.PageUp);

			AddKeyBinding (Key.PageUp | Key.ShiftMask, Command.PageUpExtend);

			AddKeyBinding (Key.N | Key.CtrlMask, Command.LineDown);
			AddKeyBinding (Key.CursorDown, Command.LineDown);

			AddKeyBinding (Key.CursorDown | Key.ShiftMask, Command.LineDownExtend);

			AddKeyBinding (Key.P | Key.CtrlMask, Command.LineUp);
			AddKeyBinding (Key.CursorUp, Command.LineUp);

			AddKeyBinding (Key.CursorUp | Key.ShiftMask, Command.LineUpExtend);

			AddKeyBinding (Key.F | Key.CtrlMask, Command.Right);
			AddKeyBinding (Key.CursorRight, Command.Right);

			AddKeyBinding (Key.CursorRight | Key.ShiftMask, Command.RightExtend);

			AddKeyBinding (Key.B | Key.CtrlMask, Command.Left);
			AddKeyBinding (Key.CursorLeft, Command.Left);

			AddKeyBinding (Key.CursorLeft | Key.ShiftMask, Command.LeftExtend);

			AddKeyBinding (Key.Delete, Command.DeleteCharLeft);
			AddKeyBinding (Key.Backspace, Command.DeleteCharLeft);

			AddKeyBinding (Key.Home, Command.StartOfLine);
			AddKeyBinding (Key.A | Key.CtrlMask, Command.StartOfLine);

			AddKeyBinding (Key.Home | Key.ShiftMask, Command.StartOfLineExtend);

			AddKeyBinding (Key.DeleteChar, Command.DeleteCharRight);
			AddKeyBinding (Key.D | Key.CtrlMask, Command.DeleteCharRight);

			AddKeyBinding (Key.End, Command.EndOfLine);
			AddKeyBinding (Key.E | Key.CtrlMask, Command.EndOfLine);

			AddKeyBinding (Key.End | Key.ShiftMask, Command.EndOfLineExtend);

			AddKeyBinding (Key.K | Key.CtrlMask, Command.CutToEndLine); // kill-to-end
			AddKeyBinding (Key.DeleteChar | Key.CtrlMask | Key.ShiftMask, Command.CutToEndLine); // kill-to-end

			AddKeyBinding (Key.K | Key.AltMask, Command.CutToStartLine); // kill-to-start
			AddKeyBinding (Key.Backspace | Key.CtrlMask | Key.ShiftMask, Command.CutToStartLine); // kill-to-start

			AddKeyBinding (Key.Y | Key.CtrlMask, Command.Paste); // Control-y, yank
			AddKeyBinding (Key.Space | Key.CtrlMask, Command.ToggleExtend);

			AddKeyBinding (((int)'C' + Key.AltMask), Command.Copy);
			AddKeyBinding (Key.C | Key.CtrlMask, Command.Copy);

			AddKeyBinding (((int)'W' + Key.AltMask), Command.Cut);
			AddKeyBinding (Key.W | Key.CtrlMask, Command.Cut);
			AddKeyBinding (Key.X | Key.CtrlMask, Command.Cut);

			AddKeyBinding (Key.CursorLeft | Key.CtrlMask, Command.WordLeft);
			AddKeyBinding ((Key)((int)'B' + Key.AltMask), Command.WordLeft);

			AddKeyBinding (Key.CursorLeft | Key.CtrlMask | Key.ShiftMask, Command.WordLeftExtend);

			AddKeyBinding (Key.CursorRight | Key.CtrlMask, Command.WordRight);
			AddKeyBinding ((Key)((int)'F' + Key.AltMask), Command.WordRight);

			AddKeyBinding (Key.CursorRight | Key.CtrlMask | Key.ShiftMask, Command.WordRightExtend);
			AddKeyBinding (Key.DeleteChar | Key.CtrlMask, Command.KillWordForwards); // kill-word-forwards
			AddKeyBinding (Key.Backspace | Key.CtrlMask, Command.KillWordBackwards); // kill-word-backwards

			AddKeyBinding (Key.Enter, Command.NewLine);
			AddKeyBinding (Key.End | Key.CtrlMask, Command.BottomEnd);
			AddKeyBinding (Key.End | Key.CtrlMask | Key.ShiftMask, Command.BottomEndExtend);
			AddKeyBinding (Key.Home | Key.CtrlMask, Command.TopHome);
			AddKeyBinding (Key.Home | Key.CtrlMask | Key.ShiftMask, Command.TopHomeExtend);
			AddKeyBinding (Key.T | Key.CtrlMask, Command.SelectAll);
			AddKeyBinding (Key.InsertChar, Command.ToggleOverwrite);
			AddKeyBinding (Key.Tab, Command.Tab);
			AddKeyBinding (Key.BackTab | Key.ShiftMask, Command.BackTab);

			AddKeyBinding (Key.Tab | Key.CtrlMask, Command.NextView);
			AddKeyBinding (Application.AlternateForwardKey, Command.NextView);

			AddKeyBinding (Key.Tab | Key.CtrlMask | Key.ShiftMask, Command.PreviousView);
			AddKeyBinding (Application.AlternateBackwardKey, Command.PreviousView);

			AddKeyBinding (Key.Z | Key.CtrlMask, Command.Undo);
			AddKeyBinding (Key.R | Key.CtrlMask, Command.Redo);

			AddKeyBinding (Key.G | Key.CtrlMask, Command.DeleteAll);
			AddKeyBinding (Key.D | Key.CtrlMask | Key.ShiftMask, Command.DeleteAll);

			currentCulture = Thread.CurrentThread.CurrentUICulture;

			ContextMenu = new ContextMenu () { MenuItems = BuildContextMenuBarItem () };
			ContextMenu.KeyChanged += ContextMenu_KeyChanged;

			AddKeyBinding (ContextMenu.Key, Command.Accept);
		}

@blakepell can you confirm?

1reaction
blakepellcommented, Sep 18, 2020

Thank you for the feedback. After thinking about it more I totally agree with you, I’ll update my example.

Read more comments on GitHub >

github_iconTop Results From Across the Web

android: move a view on touch move (ACTION_MOVE)
I've found an easy approach to do that with the ViewPropertyAnimator: float dX, dY; @Override public boolean onTouch(View view, ...
Read more >
Layouts and binding expressions
The expression language allows you to write expressions that handle events dispatched by the views. The Data Binding Library automatically ...
Read more >
NSTextView | Apple Developer Documentation
A set of optional methods that text view delegates can use to manage selection, set text attributes, work with the spell checker, and...
Read more >
When I add the textView to the LinearLayout, it jumps ...
When I add the textView to the LinearLayout, it jumps automatically to the top of the screen and I can't move it. Help?...
Read more >
TextView.MovementMethod Property (Android.Widget)
Gets the android.text.method.MovementMethod being used for this TextView, which provides positioning, scrolling, and text selection functionality.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found