Nifty. How far along is the code?
I've done some planning for my textbox implementation so far. I haven't written any
actual textbox code- I've been implementing a "pgstring" object that will handle the
text buffers and provide better Unicode support. My code so far is in the
"textbox_branch" branch in CVS.
I'll describe my design so far...
There are several things I am concerned about with this textbox widget:
- Fast and memory efficient
- Flexible object oriented architecture (Paragraph, textbox, and string are all
separate objects)
- Editable with efficient drawing even when there's a background behind the text
- Support for any fonts/colors
- Ability to embed arbitrary divnodes in the text, to support embedded widgets, and
embedding other paragraphs, for supporting tables
- Ability for paragraphs to be embedded in other structures, like tables or frames
- Multilingual support, including Unicode, right-to-left text, etc.
My design contains these objects:
- pgstring
This object would manage inserting, deleting, encoding, decoding, and other text
operations, managing the string encoding internally. It would support:
- UTF-8
- normal ASCII
- 8-bit character plus 8-bit formatting (used by terminal widget)
- 24-bit character plus 8-bit formatting (also for terminal)
- Textbox buffer with gaps for fast insert/delete, and embedded pointers to
formatting data or divnodes
- All strings would be sized, either ignoring nulls or using them for some
other purpose (like unused space in the textbox buffer)
- formatting
This formatting data would be a structure including a font handle, color, and
other attributes. These structures would be used in multiple places in the text if
necessary, and reference counted.
- paragraph
The paragraph object would be implemented as a gropnode type that renders one
paragraph, and a set of functions for inserting/deleting/etc. Normally the textbox
widget would manage creating and destroying paragraphs, and passing on input events to
the proper paragraph. The paragraph would be mostly responsible for wrapping. The
paragraph object would have a pgstring with the text buffer, plus a list of addresses
within the pgstring where the text is wrapped. The paragraph would store the width it
is wrapped to, and re-wrap itself if the width changes.
When text is typed into any place in the paragraph, an incremental version of the
paragraph gropnode is rendered that handles drawing the new character(s) and wrapping
if necessary. Every paragraph has one pointer to a background divnode. When text needs
to be cleared and redrawn, the clipping rectangle is set to the region to be erased
and this background divnode is rendered. On a simple text editing box, most paragraphs
will have the same background divnode, and the background will be determined by the
theme. In formatted text, each cel in a table (for example) could have a different
background.
- textbox
The textbox widget itself would be responsible for creating/destroying paragraphs,
dispatching events to the paragraphs, and manage higher-level formatting. (like tables)
--
I'd like to see what you have so far. Could you create a "chuck_textbox_branch" or
something in CVS, to import your code into? It seems like your code would work well as
an implementation for the paragraph object.
Let me know if my design seems too complicated or inefficient. I don't think it adds
much overhead relative to a pure single-style editing widget, and it has enough
flexibility that eventually we should be able to get reasonable HTML rendering or word
processing with it.
On Tue, Jul 09, 2002 at 12:12:08PM -0700, Chuck Groom wrote:
> To confound and doubly surprise everyone, I started working a textbox a
> while ago, had to drop in for a while, and when I picked it up again it
> turned out that Micah was busy on the same. So as to not step on toes or
> duplicate effort, I'd like to share the general design I was working with.
>
> Like Micah, we realized that this widget would be easier to implement if
> pgui operated on sized strings, not null-terminated strings.
>
> I also found that adding a small generic linked list API, similar
> to glib's, was very helpful for this.
>
> The text editor's core features are:
> - Efficient memory use (O(n) or O(n log n))
> - Very fast char insert, delete
> - Handles two common worst-cases situations (speed and memory usage)
> a. Many newlines (lots of paragraphs)
> b. A single huge paragraph
> - Widget can be read-only or editable
> - Scrollable
> - Client may get text, set text, insert string, set cursor position,
> set scroll, get virtual height of text area.
> - Events were still TBD, but probably add hooks for text insert, delete,
> scrolling, and cases where the cursor moves off the top or bottom
> of the widget.
>
> Other features (for a later version of the widget) include setting the
> font characteristics of a region of text.
>
> This is currently intended only for ASCII text, left-to-right top-to-bottom.
>
> I decided to not implement this widget within the typical grop
> context because that seemed to add too much overhead, especially when you
> considered cases like editing a 1Mb text file. This is, of course, freely
> debateable. From my experience working with a number of GUIs, I've seen that
> text widgets tend to simply manage their own drawing in a virtual pane.
>
> After a lot of thought, I adopted a the following data structure. Text
> is stored in buffer-gapped blocks. Blocks are organized in a linked list.
> Each block contains one or more paragraphs. Paragraphs never span blocks.
> All blocks are the same fixed size. If a paragraph grows and cannot fit into
> a block, we shed the last paragraph into a new block. If a block contains
> just one paragraph and it grows too much to fit in the block, only in this
> case do we grow the block's data size.
>
> Buffer-gapping allows for very fast text insert and delete.
>
> Blocks contain paragraphs. Paragraphs contain a linked list of atoms.
> Each atom is part of a line of text; atoms may not span lines.
> For now, atoms only describe text, though in the future they will also
> describe text attributes. Text atoms record the length of text, rendered
> width, rendered height, and flags including whether the atom starts on the
> left side, ends on the right side, and needs to be drawn. Paragraphs
> store the length of the paragraph, rendered height, and whether the paragraph
> contains atoms that need to be redraw or rewrapped.
>
> These flags and meta information allow us to quickly render a paragraph. The
> nice thing about paragraphs, of course, is that you're gaurenteed that
> a paragraph starts at the left side of a text widget. If a paragraph doesn't
> need to be re-wrapped, then we know how large it is and can easily render
> any part of it.
>
> As you type and edit, paragraphs may be shed to new blocks to free up
> space in the buffer gap. There is a periodic idle loop that compacts
> blocks with sparse data. Each iteration of the compaction just checks
> one more block, so it won't gobble up too much pgui attention.
>
> I hope our ideas can complement one another, and we get a text widget
> soon!
>
> -Chuck
>
>
> -------------------------------------------------------
> This sf.net email is sponsored by:ThinkGeek
> Stuff, things, and much much more.
> http://thinkgeek.com/sf
> _______________________________________________
> Pgui-devel mailing list
> [EMAIL PROTECTED]
> https://lists.sourceforge.net/lists/listinfo/pgui-devel
--
Only you can prevent creeping featurism!
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Stuff, things, and much much more.
http://thinkgeek.com/sf
_______________________________________________
Pgui-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/pgui-devel