Prior to this change an editor with no content and a zero minimum
constraint would return itself has having width zero. This
prevented users from being able to see the editor when they
moved focus to it, as it could not display its caret. This
simple change ensures that, at minimum, the editor returns
its dimensions to include the width of a caret.
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
This commit switches gofont.Collection from returning
a collection of fonts using the old text shaper to
using the new harfbuzz-based shaper. The underlying type
of gofont.Collection() has changed, which may break users
who dug into the font data.
References: https://todo.sr.ht/~eliasnaur/gio/146
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
These fields are no longer needed with the new text shaper.
Advances is redundant to the glyph information, and Text
should never be used during layout, as you should
traverse the cluster list instead. This commit also removed
the now-unused string field from the path LRU cache key.
References: https://todo.sr.ht/~eliasnaur/gio/146
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
This commit replaces the previous opentype.Font with
an implementation that uses the new text shaper. In
order to keep the implementation simple, support for
opentype font collections was dropped. It should be
possible to re-add this support after some changes
to the text shaper's line wrapping algorithm.
To expand on the above, doing proper font fallback with
harfbuzz will require splitting the input text on font
glyph support boundaries, changing the input from a
simple shaping.Input to []shaping.Input with each input
matched against the font that supports its language.
The line wrapping then needs to be able to properly
consume that slice. Since the line wrapping algorithm is
really complex, I'm hoping to defer that modification
until this simple version is accepted.
References: https://todo.sr.ht/~eliasnaur/gio/146
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
This commit updates material.Editor and material.Label to support the
new text shaper. This requires breaking their assumption that glyphs
of font data map 1:1 to runes of text data.
References: https://todo.sr.ht/~eliasnaur/gio/146
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
This commit adds a check that caret coordinates never exceed
the max constraints of the editor.
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
We'd like to re-use the Editor.closestPosition seeking for
segmentIterator.Next; this change extracts the state-less logic
into functions.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit adds a testcase to catch unexpected panics in the
editor's scroll offset logic introduced by using different
setting combinations that affect editor layout. It also fixes
a panic for single-line editors with alignments other than
text.Start.
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
This commit ensures that the edit buffer used by widget.Editor
does not get EOF when trying to read zero bytes from the
underlying buffer, which eliminates a panic when calling
Editor.SelectedText().
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
This change uncovered and fixes a bug in nullLayout.
This is an API change; the methods operated in bytes before.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Needed for efficient implementation of the upcoming IME interface.
Also introduce Editor.replace, seek methods for easier caret navigation
and editing.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
When there were non ASCII characters (for exemple éèàçîï) in a deleted
selection or word, more characters were deleted because there was a
mismatch between runes and bytes in Delete and deleteWord
Fixes: https://todo.sr.ht/~eliasnaur/gio/330
Signed-off-by: Fabien Jansem <fabien@jansem.eu.org>
To make the semantic relation between the editor and its content clear,
the editor clip operation must cover the content. This change adds an
explicit widget argument to editor, and lays it out inside the clip
rect.
This is an API change. Users of Editor.Layout must provide a content
widget.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
For example, ButtonLeft may be the right-most button for a left-handed user.
Rename the button names to match their intended use.
This is an API change. Use the following commands to update your
projects:
$ gofmt -r 'pointer.ButtonLeft -> pointer.ButtonPrimary' -w .
$ gofmt -r 'pointer.ButtonRight -> pointer.ButtonSecondary' -w .
$ gofmt -r 'pointer.ButtonMiddle -> pointer.ButtonTertiary' -w .
Signed-off-by: Elias Naur <mail@eliasnaur.com>
If you created an Editor and immediately SetCaret, it panicked because
e.lines was nil and it looked at e.lines[0].
- Add e.makeValid at the top of SetCaret.
- Add a test case for this situation.
Signed-off-by: Larry Clapp <larry@theclapp.org>
- Allow dragging to be on both horizontal and vertical axes at once.
- Split Editor.caret.pos into caret.start and caret.stop. caret.start is
the old caret.pos, and is both the position of the caret, and also the
start of selected text. caret.end is the end of the selected text.
Start can be after end, e.g. after after Shift-DownArrow.
- Update caret.end after a mouse drag, and various shifted keys
(Shift-UpArrow, Shift-DownArrow, etc).
- Change Shortcut-C to copy only the selected text, not the whole editor
text.
- Add Shortcut-X to copy and delete selected text, and Shortcut-A to
select all text.
- The various Insert/Delete/etc functions now overwrite or delete the
selection, as appropriate.
- Change MoveCaret to accept a distance for selection end, as well.
Change SetCaret to accept a selection end offset.
- Add SelectionLen to get the selection length, Selection to get
selection offsets, SelectedText to get the selected text, and
ClearSelection to clear the selection.
- Add a rudimentary selection unit test, and extend the deleteWord unit
test with some text selection cases.
- Add SelectionColor to material.EditorStyle, which defaults to
Theme.Palette.ContrastBg.
Signed-off-by: Larry Clapp <larry@theclapp.org>
- Move caret from editBuffer.caret to Editor.caret.pos.ofs and related
refactoring. Move other fields in Editor.caret into Editor.caret.pos.
- Refactor several functions to change a position passed into them,
rather than changing e.rr.caret directly.
- Add editBuffer.Seek().
- Remove editBuffer.dump().
- Change Editor.Move to MoveCaret.
- Add Editor.SetCaret.
- Updated tests.
Signed-off-by: Larry Clapp <larry@theclapp.org>
Commit https://gioui.org/commit/b331407e81456 added text layout and shaping
based on io.Reader and changed Editor to use it. Unfortunately, as ~inkeliz
discovered, caching of shapes were also lost.
~inkeliz suggested fix,
https://lists.sr.ht/~eliasnaur/gio-patches/patches/15059
adds caching of shapes to Editor to regain lost performance.
This change repairs the cache to work on io.Reader API, in hope that the
already complicated Editor won't need additional caching.
Before this change, text layouts were represented as a slice of (rune, advance)
pairs. Unfortunately, this representation doesn't lend itself to caching of
shaping results, so change the representation of a line of text to be a pair
of text and advances:
package text
type Layout {
Text string
Advances []fixed.Int26_6
}
The Text field can then be used in a cache key, assuming Advances is
consistent with it.
The end result is that the two shaper variants of text.Shaper is reduced to
just one, and the Len field field of text.Line is no longer needed.
The changed representation adds a bit of extra work to package opentype.
Cleaning that up is left as a future TODO.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This change adds optional password masking to the Editor. To enable
this feature, set the new Mask field to a non-zero rune. Every rune
in the Editor's contents will be replaced by the mask rune in the
visual display, except for newlines. The actual contents of the
editor can still be accessed with Len, Text, and SetText.
Fixes gio#80
Signed-off-by: tainted-bit <sourcehut@taintedbit.com>