-
Notifications
You must be signed in to change notification settings - Fork 480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Widgets/text area #4995
Widgets/text area #4995
Conversation
509a0c1
to
83a9a19
Compare
I really appreciate your work on all of this stuff! You really went all out with this widget and the result is fantastic. Journal is sooo good and it's awesome that every other script will have such a great textarea to work with. I have been looking forward to this PR 😄 |
This PR looks good to me. My understanding is that this type of stuff (especially lua, ui) is primarily myk's area of responsibility to sign-off on, so it may take some time to be merged. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
first pass review done (docs only)
docs/dev/Lua API.rst
Outdated
* ``on_text_change``: Callback function called whenever the text changes. | ||
The function signature should be ``on_text_change(new_text)``. | ||
|
||
* ``on_cursor_change``: Callback function called whenever the cursor | ||
position changes. The function signature should be ``on_cursor_change(new_cursor_pos)``. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest also passing the old text/old cursor position so callbacks that care don't have to keep that state themselves. Callbacks that don't care don't even have to include the parameter in their function signatures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will do it for the cursor, but I have doubts for it as default behaviour of on_text_change
.
The text can be potentially long and storing and passing a copy of it on every keypress can be bad for performance and memory, especially that I assume most of the tools will not need it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done for on_text_change
, also tests add.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lua strings are immutable (a change to a string causes a new string to be allocated). If you take a reference to the string before modification and pass it to the callback along with the current (modified) string, there is no additional memory being used. There was already a string copy operation as a result of modifying the string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, as such - I am going to implement the old_text
param.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done and tests added.
docs/dev/Lua API.rst
Outdated
position changes. The function signature should be ``on_cursor_change(new_cursor_pos)``. | ||
|
||
* ``one_line_mode``: Boolean attribute that, when set to ``true``, | ||
disables multi-line text features and restricts the text area to a single line. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should document whether string.char(10) will be interpreted as the cp437 glyph. It would be nice if it did, but that can be implemented later if it's not already true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added.
\n
will be removed from the text, not rendered as glyph.
Its not so obvious for me that they should be rendered as glyph, what do u think that?
maybe precise what do u mean by glyph, so I am sure we are think about the same thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
\n is ◙ in cp437 - It has a graphical representation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, in CP437, single-string multiline text isn't a thing. We're creating a funky hybrid here that needs careful documentation around the handling of string.char(10)
. You can use ◙ in a name, for example. Currently you cannot use that character at all in this widget (which is a perfectly fine compromise, I think), but if we are to use one_line_mode
TextArea widgets to replace EditField, we'd probably want to support the whole CP437 character set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its not something I feel comfortable to do here, but I am open to do it in a follow up PR. Is it fine?
docs/dev/Lua API.rst
Outdated
|
||
Scrolls the text area view to ensure that the current cursor position is visible. | ||
This is useful for automatically scrolling when the user moves the cursor | ||
beyond the visible region of the text area. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Scrolling on cursor movement doesn't happen automatically? I'd expect this to be the default so the parent isn't required to implement on_cursor_change for a good default behavior. What are the use cases for on_cursor_change callback other than to call this function? If we had that "keep cursor visible when moving cursor" default functionality, are there any other use cases for this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we had that "keep cursor visible when moving cursor" default functionality, are there any other use cases for this function?
It is default functionality for all default manipulation of TextArea by the user.
But there is :setCursor
API where we allow the API consumer to manipulate the cursor.
This function do not automatically scroll to the cursor, to allow API consumer to better control.
e.g. imagine someone want to paste a text to end of the textarea for some reason, but do not change user cursor and scroll position.
I had a similar case with gui/journal
Table of Contents feature, but I do not remember now what it was exactly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I think I understand. How about this?
Scrolls the text area view to ensure that the current cursor position is visible.
- This is useful for automatically scrolling when the user moves the cursor
- beyond the visible region of the text area.
+ This happens automatically when the user interactively moves the cursor or
+ pastes text into the widget, but may need to be called when ``setCursor`` is
+ called programmatically.
docs/dev/Lua API.rst
Outdated
- Text Selection: Select text with the mouse, with support for replacing or | ||
removing selected text. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be moved above Ctrl-U so mouse users know they can skip paying attention to the deletion keyboard shortcuts. Actually, on second thought, I'd split this list into two sections:
1st section: baseline functionality (features that players would expect from any text editor: text wrapping, mouse selection, copy/paste, undo/redo). We can probably reduce the amount of documentation dedicated to well-understood features, like Home and End. You can just mention that "the usual keyboard keys are supported, like Home, End, Backspace, Delete, etc. In addition, common mouse gestures are supported, like double click to highlight a word or triple click to highlight a line."
2nd section: keyboard power user shortcuts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not convinced, IMO we should keep all option described.
its quite think line what is "baseline" features and what now, it can be different for every user.
may proposition is to include and intro, like u proposed, but below it, in dedicated section, keep all shortcuts like now.
what do u think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
at least Text Selection in particular should be moved adjacent to the Mouse Control line so similar concepts are grouped. This list is long and feels unorganized
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improved, what do u think about current version?
docs/dev/Lua API.rst
Outdated
- Jump to Beginning/End: Quickly move the cursor to the beginning or end of the | ||
text using :kbd:`Ctrl` + :kbd:`Home` and :kbd:`Ctrl` + :kbd:`End`. | ||
- Select Word/Line: Use double click to select current word, or triple click to | ||
select current line |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing final period (also true for sentences below)
Also add tests for TextArea `on_cursor_change` callback
625c02a
to
57e5e57
Compare
57e5e57
to
a307308
Compare
795d2be
to
b9422dc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a line to the Lua section of the changelog.
To allow me to see the diff between reviews, could you keep the commits without force pushes? Force pushing causes GitHub to lose the review context.
docs/dev/Lua API.rst
Outdated
The cursor in the ``TextArea`` class is index-based, starting from 1, | ||
consistent with Lua's text indexing conventions. | ||
|
||
Each character, including new lines (``string.char(10)``), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each character, including new lines (``string.char(10)``), | |
Each character, including newlines (``string.char(10)``), |
docs/dev/Lua API.rst
Outdated
* ``init_text``: The initial text content for the text area. | ||
|
||
* ``init_cursor``: The initial cursor position within the text content. | ||
If not specified, defaults to end of the text (length of ``init_text``). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
length of init_text
plus one, right? (according to the Cursor Behavior text above)
docs/dev/Lua API.rst
Outdated
* ``text_pen``: Optional pen used to draw the text. | ||
|
||
* ``select_pen``: Optional pen used for text selection. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please document default pens
docs/dev/Lua API.rst
Outdated
If any "\n" (``string.char(10)``) are available in the text, | ||
they will be removed from the text |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find this phrasing a unclear for the semantics I expect. This is the behavior I'd like to see described:
- If multiline text is pasted into the widget, newlines are removed (that is, the non-multiline SDL clipboard functions are used)
- The Enter key is not handled by the widget as if it were included in
ignore_keys
docs/dev/Lua API.rst
Outdated
|
||
Scrolls the text area view to ensure that the current cursor position is visible. | ||
This is useful for automatically scrolling when the user moves the cursor | ||
beyond the visible region of the text area. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I think I understand. How about this?
Scrolls the text area view to ensure that the current cursor position is visible.
- This is useful for automatically scrolling when the user moves the cursor
- beyond the visible region of the text area.
+ This happens automatically when the user interactively moves the cursor or
+ pastes text into the widget, but may need to be called when ``setCursor`` is
+ called programmatically.
TextAreaContent.ATTRS{ | ||
text = '', | ||
text_pen = COLOR_LIGHTCYAN, | ||
ignore_keys = {'STRING_A096'}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment as above -- I think we can change the default to an empty list due to INTERCEPT_HANDLED_HOTKEYS
enable_cursor_blink = true, | ||
debug = false, | ||
one_line_mode = false, | ||
history_size = 10, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the internet does not seem to have a good consensus of what a 'good' default history size is, but 10 seems low to me. How about 20 (or leave the attribute as DEFAULT_NIL
and use the HistoryStore default of 25)?
function TextAreaContent:getPreferredFocusState() | ||
return true | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it doesn't make sense for both TextArea and TextAreaContent to want focus since TextAreaContent is a child of TextArea. This function should be removed since it is TextArea that really needs the focus.
|
||
function WrappedText:update(text, wrap_width) | ||
self.lines = text:wrap( | ||
wrap_width, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if wrap_width
is nil
, then the text will be wrapped at 72 characters. Is this appropriate? Should wrap_width
instead default to math.huge
?
|
||
config.target = 'core' | ||
|
||
local df_major_version = tonumber(dfhack.getCompiledDFVersion():match('%d+')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now that 50.14 has been released (which supports the new cursor navigation keybindings), you can take this out and run the tests unconditionally
7e7a33d
to
1f75f37
Compare
You force pushed him again. lol. |
I should clarify that force pushing is ok to amend a just-committed commit. The review complications happen when force pushing such that already-reviewed commits get a new hash. |
docs/dev/Lua API.rst
Outdated
they will be removed from the text | ||
* ``one_line_mode``: If set to ``true``, disables multi-line text features. | ||
In this mode the :kbd:`Enter` key is not handled by the widget | ||
as if it were included in ``ignore_keys``. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as if it were included in ``ignore_keys``. | |
as if it were included in ``ignore_keys``. |
docs/dev/Lua API.rst
Outdated
|
||
Functionality: | ||
Functionality | ||
------------- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
welcome to the wonderful world of restructured text header underline rules. Currently, this section is interpreted like this:
that is, Functionality
is a peer of TextArea class
and Cursor Behavior
is a higher level header than TextArea class
.
You need to scan through the existing headers and discover what underline style is used for what level of header. It's different for every file, and is determined by whatever the file uses first for that particular header depth.
The indentation for list continuation lines is also apparently different from what sphinx expects:
You can see how this PR's text is currently rendered here: https://dfhack--4995.org.readthedocs.build/en/4995/docs/dev/Lua%20API.html#textarea-class
You can get to that link by clicking on "details" for the ReadTheDocs build action:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank for the tip, I did not know that I can preview docs in build results!
I corrected the docs now.
docs/dev/Lua API.rst
Outdated
- New Lines: Easily insert new lines using the :kbd:`Enter` key, supporting | ||
multiline text input. | ||
- Text Wrapping: Text automatically wraps within the editor, ensuring lines fit | ||
within the display without manual adjustments. | ||
- Scrolling behaviour for long text build-in. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Scrolling behaviour for long text build-in. | |
- Scrolling for long text entries. |
end | ||
end | ||
|
||
function TextArea:getPreferredFocusState() | ||
return self.parent_view.focus | ||
return self.parent_view and self.parent_view.focus or true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not just true
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I read the docs, but I was always confused by this "preferred focus" feature.
Changed to true
This MR introduce
TextArea
widget.This widgets is already in use in
gui/journal
and cominggui/notes
tools.Its provide much better support for text manipultation than TextField do.
Scripts journal has been migrated here:
DFHack/scripts#1327