News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Editor Window Theory

Started by dncprogrammer, December 04, 2006, 06:37:57 PM

Previous topic - Next topic

dncprogrammer

Hi Again,
I have been working on a simple text editor, something very similar to Microsoft EDIT. It's working fairly well so far and I have come to the point where I need to rewrite my screen/string handling for a scrolling screen. I have taken care of single screen wrap-around and back but I have been lying awake at night pontificating about how to approach scrolling & keeping track screen position, cursor position, string position. Any words of wisdom here would be greatly appreciated. Im not affraid to work but I just can't decide how to start this one.
jon

Tedd

When you load a file, parse it and create a table storing the lengths of each line. This table will become your best friend :wink
Now you know the length of each line, finding the offset to the start of each line is a simple cumulative addition.
Then why not just keep a list of offsets? Well you could, but you're going to have to keep the table updated each time the contents are modified. So, you either modify one length, or every single offset thereafter. Up to you :P
So, what use is all of this? Well, it means you can get the start and length of any line, and therefore wrapping can be done on a line-by-line basis, rather than 'searching' through the whole text each time to find which bits should be on screen. When you scroll halfway down, you can keep a character offset, and converting that to a line offset (so you know which line is at the top of the window) is a simple look through the table. Horizontal scroll means the visible part of each line starts at x characters after the actual start of each line. Hilighted-selection is all characters between two offsets..
Just create a few functions to convert offset to line number, line number to offset (start of line), offset into line, etc.. And you're away!
Simple :lol
No snowflake in an avalanche feels responsible.

dncprogrammer

Thanks for taking this one on,

Theory and programming wise, could we say that in this process the manipulation of the string is primary and the manipulation of the display is secondary? Essentially every time that the string changes it must be reflected in the display window accordingly. The keyboard prompts changes in the string to be displayed OR it prompts changes in the display view which require calculation of new relative position and display within the window.
It seems that care must be taken in efficient coding in order for the display to be as stable as possible during editing and viewing considering the high frequency of refreshing.
Im also assuming that window refreshing would work on a line by line basis as well, almost considering the "window" as a page of the string. Even if a character was deleted in the middle of the screen (changing only one line of string) the entire display must be refreshed in order to reflect the changes to the entire string within the current view.
Im not getting into mouse use, and I won't be requiring horizontal scroll so Im hoping that should simplify things a bit. Im still trying to write a process map for making this work so I may have more questions. Thank you so far!




Tedd

Hmmm... let's see.

Each time the text changes, obviously this will require an update of the screen, or more correctly, the part of the text that changes (plus any re-alignment this might cause through wrapping.) You could try to be clever and only update the portion that changes - if you keep thinking of the screen as a collection of lines, then this doesn't turn out to be that complex really (only the wrapped line portions actually change, the rest of the screen remains stable; except in the case of the line overflowing onto yet another line, in which case the lower lines must be shifted down one).
The keyboard can cause both the text to change (modification of the text) and the display to change (scrolling/navigation). So I would say it's better to think of 'actions' as prompting different types of updates.
Scrolling is a little more fun. You'll either move up (or down) one line, or a full page. A full page obviously requires a full redraw, but moving only one line means you can shift the contents of the page, and then only redraw the single new line that's come into view.
To keep the screen stable, you should aim to only update when necessary, which is only when something changes (modification or navigation.) Where possible, only update the part of the screen (lines!) that has actually changed; though where this causes too much complication, it's sometimes faster (and easier) to do a full update anyway.
No snowflake in an avalanche feels responsible.

dncprogrammer

Hi Tedd,
Because Im somewhat new to assembler I will have some trouble with application. I have spent many years programming in Basic so I understand what Im trying to do I just don't have the language tools anymore. I thank you for helping me to rearrange my thought process. Anybody can write a 20 line assembly program to do some menial task but once you set your sights higher on a bigger app everything becomes much more complicated as it has to be written much differently.
Ok, I should consider my text a series of lines, I could definitely write that up in Basic.

   1. When I open the file I should parse it and make a table of lines which would include line
       length and start offset of 1st char of line. Does this mean that I will be using up at least 2 bytes
       in memory for each "line" of text in my editor?
   2. How should I define the starting offset for the table? (Since this table can expand indefinitely
       along side the memory space for the actual file string) I defined a workspace for the
       string when I first got started, something like  "buffer        db    0 times(1024)", just a small
       experimental buffer for now.




Tedd

The small programs are just as important as the large ones, possibly more so. You have to write a number of small programs in order to learn how to perform specific tasks, and it's not until you're able to do these that you can put them all together into a larger program. So rather than deciding "I am writing a text editor!" and only focusing on that, I'd try writing some smaller programs that do specific parts of what you need to achieve in the editor. Smaller programs are easier to debug too :bdg

As for tables and storage, etc.. My suggestion was to have one table to store the line lengths in, and then store the actual text separately - otherwise you run into problems of finding the elements of the table, which is the same problem for the text that the table is meant to be solving. However, simply storing the text in one mass isn't going to be helpful because the text is modifiable, so as soon as one line changes, you'll have to shift the entire contents along.
How about storing the lines in "line-buffers"? Each one is a block of memory which contains a line, and knows its length, but has a little extra space ready for the line to grow. Modifying one line only causes a change in the line-buffer, and you don't have to mess around with shifting the other lines (if a line overflows its buffer then you'll have to reallocate a larger buffer for it.) Your task then becomes one of managing line-buffers. So your top level 'table' will simply contain a list of line-buffer pointers.
The fun part is learning how to dynamically allocate memory - you'll have to look-up which INTs to use :P
For the line lengths, I'd go with using a word (2 bytes) to store the length - which gives a maximum line-length of 64k, which should be enough given your 16-bit memory constraints (1 byte gives all of 256 characters per line.)
No snowflake in an avalanche feels responsible.

dncprogrammer

Thanks again Tedd,

Don't get me wrong here. I have written a ton of small programs and Im not one of these kids who's never written anything and they are on here bugging you about designing a compiler because it sounds cool. Im really trying here and I have a great framework of my editor, I was just not so sure that I had the best plan for navigation and modification. Looks like I didn't.

You would load the file into memory then parse it and move each line into it's own buffer space. That would mean that the pointers to these buffers would be equally spaced until one of the lines had become a deviation, and even then only the pointers after that one would need to be recalculated. Handling the screen on a line by line basis is starting to make a lot more sense. Saving the file would be a matter of reading each of these buffers to EOL and pasting it into the memory position used for the file-write, one after the other until EOF. Am I close here?

jon

Tedd

You've written a lot of basic programs, but how many asm ones? (I'm not trying to be smart here, but there is a difference.)

Anyway, yes, it sounds like you've got the idea :wink

A quick note - if you have to resize a buffer, it's probably best to increase its size by another whole buffer-size (doubling its length.) Then you keep all of the following ones 'aligned.'

Depending how you load the file into memory, you might parse it as it loads. And if you want to be really clever, only load the lines of the file as you need them - so you don't eat all of the memory before you've even started.
You could also discard/recycle line-buffers when they're no longer required - as long as they're not dirty.. Now it starts to get really messy :bdg
No snowflake in an avalanche feels responsible.

dncprogrammer

Thanks again Tedd,
I have actually been writing little assembler programs for about a year now but since I own a business ,and the assembly projects are just a hobby, I have a hard time spending large amouts of free time working on my projects. I try to come up with a solid strategy for the time that I do have to pound out code and experiment. I have read so many assembly language books that my girlfriend says that I should write a book about assembly language books.  :wink My problem is that I've become book-smart but I am missing practical application. This shows in my situation with the editor that I'm writing. I need to learn how the real world approaches these things, not just a code snippet. If I have a good idea of what Im building then I don't have trouble with the code. I admire the knowledge of so many people on this forum that it is important that you know that none of your advice is wasted on me. Thanks again!