flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Text editor from scratch

Author
Thread Post new topic Reply to topic
MrFox



Joined: 17 Aug 2016
Posts: 52
Location: Russia
MrFox 15 Nov 2016, 05:54
Hi, I'm writing a UEFI-32 library that can manage text user interface with forms and controls (create, change states, process events from controls and keyboard). By now, I have it almost done (multiple modal windows, labels, push buttons, radio buttons, check boxes and list boxes), the only thing yet to do is text edit fields.

They are actually micro-text editors of two sorts: single line and miltiline. I want to implement both and I see no problem implementing the single-line ones. As for multiline, I want to give them full-feature functionality to use as an engine for my future text edition app (a minimalistic IDE for fasm under UEFI, actually).

I have many ideas on how to implement all the features (basic editing, selection, cut-copy-paste, undo-redo, etc) but I'm sure there are existing working algorythms.

The question is: where can I find code examples (at least for consulting them, at most to use them 'as is' or with minimal amendments)? Is there someone who could explain how the internals are working? Could you recommend a good book?
Post 15 Nov 2016, 05:54
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 15 Nov 2016, 08:51
The flat editor 3.x is a portable editor core that was written to serve as the base for fasm's IDEs for various operating systems (though only the interfaces for DOS and Windows have been created). The original flat editor (version 1) was written alongside fasm and they were both easily ported to my own operating system at the time*, the fedit 3 is the continuation of that idea. The editor functions were inspired by the built-in editor of DOS Navigator (which was the editor I used to write fasm originally), and fedit uses a similar segmented architecture that allows a good performance even on a very large files**.

The entire source of flat editor core resides in the SOURCE\IDE directory of fasm's DOS/Windows packages. The documentation of core functions is available in the thread I linked above.

There are no simple examples, but if you read the fedit_core documentation in detail, you should be able to set it up in any 32-bit environment. You can refer to the sources of FASMD, for example its function "update_screen" demonstrates how you can read the editor data to generate the representation on the screen (but this one includes the addition of syntax highlighting, so it is not as simple example as it could be).

____
* Unfortunately no source codes of that version of TitanOS survived.
** I know of people that have been using FASMW to edit things like large SQL dumps, myself included. For this reason I have also implemented Boyer–Moore text search into flat editor.
Post 15 Nov 2016, 08:51
View user's profile Send private message Visit poster's website Reply with quote
MrFox



Joined: 17 Aug 2016
Posts: 52
Location: Russia
MrFox 15 Nov 2016, 18:52
Thank you so much Tomasz!
I'll definitly give it a very careful and dedicated look.
With all my respect, at first glance, your code lacks comments very much. I'm not looking for simple examples only; I'm able to understand more complex and sophisticated things but understanding them from pure code will take as much time as I would need to write my own. I can't figure out what flowers come from what seeds (even though I clearly see both the flowers and the seeds).

In my opinion, some general explanation on how this all works definitely wouldn't hurt, e.g. "the source file is loaded into memory and gets split into blocks of 100h bytes size (delimiter? other criteria?). Then the blocks are presented to the user in the following way... When the user presses a key, the key code is being passed to __ procedure... etc." A survey like this would help people make out the algorythm from behind the code.

Nonetheless, I'll definitely give it a serious go. Thanks!
Post 15 Nov 2016, 18:52
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 15 Nov 2016, 19:09
MrFox wrote:
In my opinion, some general explanation on how this all works definitely wouldn't hurt, e.g. "the source file is loaded into memory and gets split into blocks of 100h bytes size (delimiter? other criteria?). Then the blocks are presented to the user in the following way... When the user presses a key, the key code is being passed to __ procedure... etc." A survey like this would help people make out the algorythm from behind the code.
The fedit_core.txt contains such information, although quite scattered, because everything is contained in the descriptions of API functions and some of the variables. What it lacks is a kind of tutorial that would show how to combine all these function calls into an actual working editor. Surely I need to write it one day.
Post 15 Nov 2016, 19:09
View user's profile Send private message Visit poster's website Reply with quote
redsock



Joined: 09 Oct 2009
Posts: 435
Location: Australia
redsock 15 Nov 2016, 20:13
For a contrasting approach, I spent some time for a text editor/display component for my library's TUI goods: https://2ton.com.au/library_as_html/tui_text.inc.html ... that component is used to provide both the single-line text input field, as well as the multiline text display (where it just sets the edit flag to false) for my sshtalk program if you wanted to see it in action: https://2ton.com.au/sshtalk.

There are many ways to approach text editor functionality. My own deals with many-to-1 view versus text output (think wordwrap, linewrap, etc) as well as justification, etc given an input text.

These can be messy problems, hahah. The VIM code to deal with same is also messy (as are most text editors that are feature-rich).

_________________
2 Ton Digital - https://2ton.com.au/
Post 15 Nov 2016, 20:13
View user's profile Send private message Reply with quote
pabloreda



Joined: 24 Jan 2007
Posts: 116
Location: Argentina
pabloreda 16 Nov 2016, 01:53
I make some editor, but not in asm.

1 line edit in https://github.com/phreda4/reda4/blob/master/r4/Lib/input.txt
line 5 to 36 the basic rutines for 1 line edit, this is a immediate gui input text component.

full text editor with syntax coloring and more in https://github.com/phreda4/reda4/blob/master/r4/IDE/edit-code.txt
Post 16 Nov 2016, 01:53
View user's profile Send private message Visit poster's website Reply with quote
MrFox



Joined: 17 Aug 2016
Posts: 52
Location: Russia
MrFox 16 Nov 2016, 06:26
Thanks guys. My API can already deal with multiple lines (as in ListBoxes) and I'd like to use this functionality.

When a control is being created (any type of control), the creation procedure receives a ListCount argument and an address where item captions are originally located. Then it allocates ControlStrucSize + (ControlWidth +1) * 2 * ListCount bytes of memory, fills the beginning with the actual control structure and copies the array of strings after the .Data field at the same time padding each item with spaces to the ControlWidth length or cutting the tail off if the line is longer than width. So basically I have an array of N strings, no gaps between them, where each character in a string is word-sized and there are two extra bytes in front of each line that may contain anything. Additionally, the control data itself contains ListIndex value (currently selected item), FirstVisible item index, etc.

This is how my Controls are defined in code:
Code:
struc Control
{
        align 4
        .ID             dw 0
        .Type           dw 0
        .Left           dd 0
        .Top            dd 0
        .Width          dd 0
        .Height         dd 0
        .State          dw 0    ; State
        .ListCount      dw 0    ; Total items
        .ListIndex      dw 0    ; Current item...
        .FirstVisible   dw 0    ; First visible item (top of list on the screen)...
        .Next           UINTN   ; Address of next control within current window
        .Prev           UINTN   ; Address of prev control 
        .Data:                  ; Area to store control's caption, items, etc.
        ControlStrucSize=.Data-.ID
}
    


This system works pretty well for fixed-content controls, but I definitely need a mechanism for adding/inserting/removing items. And yes, I want to use this system to manage strings in multiline edition fields. I guess I have to insert some 'shadow' space portions in between items and use it to store new items or something.

The alternative is to reallocate a new piece of memory each time a new line is created and copy the whole data with the new line inserted... I don't think it's a good idea.

The other alternative is to initially allocate +N (K)bytes for possible changes in line structure isn't good either because on each new line insertion I'll have to move the tail right and in case of large files this tail may be kinda huge. Although this one looks like the simplest to implement, I introduce MaxItemCount, reserve memory using it (instead of ListCount) and that's all. Navigation proc stays the same, the overhead MaxItemCount - ListCount is just a surplus amount of memory after the tail...

Any ideas on how to improve the system so that it could be easily used for text edition?
Post 16 Nov 2016, 06:26
View user's profile Send private message Reply with quote
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 26 Dec 2016, 13:26


Last edited by zhak on 26 Dec 2016, 20:00; edited 1 time in total
Post 26 Dec 2016, 13:26
View user's profile Send private message Reply with quote
Trinitek



Joined: 06 Nov 2011
Posts: 257
Trinitek 26 Dec 2016, 19:49
zhak wrote:
You also could be interested in http://www.cs.unm.edu/~crowley/papers/sds/sds.html.
That ending period snuck into the URL.
Post 26 Dec 2016, 19:49
View user's profile Send private message Reply with quote
MrFox



Joined: 17 Aug 2016
Posts: 52
Location: Russia
MrFox 05 Jan 2017, 15:57
Thanks guys. That was a Great read! I wish there were something like that about memory management (defragmentation) algorythms when storing, modifying and deleting random pieces of data.
Post 05 Jan 2017, 15:57
View user's profile Send private message Reply with quote
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 06 Jan 2017, 12:05
BTW how do you output text? Here's graphic console driver source which has helped me a lot with the idea of multiline strings output. https://www.virtualbox.org/svn/vbox/trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c

The idea is to use HII Font functions to convert string to bitmap, and then display it with GOP functions

I have a strong feeling that we're working on similar things in parallel Smile
Post 06 Jan 2017, 12:05
View user's profile Send private message Reply with quote
MrFox



Joined: 17 Aug 2016
Posts: 52
Location: Russia
MrFox 08 Jan 2017, 08:45
>BTW how do you output text?

(I use only console output, not the GOP. It turned out a little bit complex but it works perfectly: I sort of emulated a text-video-buffer array for characters and colors)

1. I got hScreen and vScreen dimensions
2. Reserved hScreen*vScreen*3 bytes: (hScreen*vScreen*2 for each character) and hScreen*vScreen for their respective colors.
3. ShowScreen procedure:
3.1. Save caret position and state; hide caret (to avoid blinking while multiple OutputString-s are working)
3.2. Get first modified screen row and column; if none then Goto End.
3.3. Calculate the address of the current char in colors array (ColorStartAddress+y*hScreen+x).
3.4. Get Current Color from array
3.5. Set Text Output Color (UEFI function)
3.6. Set Text Output Position (UEFI function)
3.7. Scan the array of colors while color=SavedColor and x<hScreen
3.8 Calculate length of text of the same color as the first char's color.
3.9. Output Text to the screen (UEFI function)
3.10. Modify x and y coordinates.
3.11. If y<vScreen then Goto 3.3.
3.12. Restore caret position and state (visible/invisible) - UEFI functions

So to show something you modify either text array or colors array or both and then call "DrawScreen".

To avoid multiple printing of the same screen portions I introduced "RowModified" array with {Start and Length} bytes for each row that makes all of the above algorythm skip output for non-modified screen parts.

So if you call 'DrawTextAt' with 10,10,TextAddr,ColorRef it calculates text length, MovStringWord-s the string characters to appropriate positions in ScreenChars array, StoSB's the appropriate colors in ScreenColors array and marks row 10 as modified from 10 to 10+textLength (if row 10 was already modified then max-s and min-s are calculated). So the above DrawScreen proc processes only screen coordinates from 10,10 to 10,10+Len and other modified rows (if any).
Post 08 Jan 2017, 08:45
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4354
Location: Now
edfed 08 Jan 2017, 14:53
text edition is a good example of the MVC pattern.

first focus on the problem of what to edit (M)
then, maybe implement a little code to see what you do (V)
and finally, code the essential thing of the editor (C)

and now, maybe i should do it myself instead of telling others how to do Wink
Post 08 Jan 2017, 14:53
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.