Welcome to the new Friends-of-FPC!

Here you can find all kinds of information about the FreePascal Compiler. We have many tutorials and howtos as well as a selection of tools to help you with your programming. We also have some example codes for you. And if you want to contribute some information/ sources/ tools yourself you can do so.
Also we have finally relaunched the FoFPC forum. It's your chance for some Q&A about everything FreePascal.

Friends-of-FPC

Tutorials: Learn how to code with FreePascal.

Source Codes: A collection of examples, miscellaneous source codes and open source stuff.

Tools and Help Files: Intro- duction of some tools that might help you with FPC.

Community

Forum: Ask or answer questions about the FreePascal Compiler, programming or just babble about coding.

Contribute! Contribute your own Tutorial, Source Codes or Tools and send them to us!

Website

About: Information about Friends-of-FPC.org.

How to write an editor - Chapter 2 - by Aiwendil

Users, no matter how annoying, are always to take into consideration

The screen, here we have a thing that actually are tricky in linux since a screen can be just about anywhere from 1*2 to 255*255 chars, I will assume that you will solve that problem for youself and also another nice problem, that linux usually tend to expand tabs and such itself.

screen.pas are what we are working with in this part unless otherwise specified. also, it is assumed that you use the unit buffers specified in part1 and the unit CRT or equialant, what we need are the routines gotoxy and clrscr.

First we need to define a type for windowed controls, in dos this step is skipped by most programmers and inserted later with a great effort, in linux you almost must implement this right away since the size of the screen can vary a lot, using this approach will also make it lots easier to implement multiple document interface.

TYPE tWindow = RECORD
                  XPos : Byte;
                  YPos : Byte;
                  XLength : Byte;
                  YLength : Byte;
                  BufferList : tBufferList;
               END;

There, it is pretty straightforward, I know that YLength would be more correct to call YHeight instead but I prefer to keep the code uniform instead of correct according to some rules one don't really have to pay attention to while coding.

First we need a procedure to init the tWindow to nice defaults;

PROCEDURE InitWindow(VAR Window:tWindow);
BEGIN
   WITH Window DO BEGIN
      XPos := 1;
      YPos := 1;
      XLength := 80;
      YLength:=25;
      InitBufferList(BufferList);
   END;
END;

Ok, that wasn't so hard, and I doubt you need to have that one explained.

Now, time to make the partial update-routine, this one will be called upon frequently so here it is to favour speed over memory.

PROCEDURE WindowUpdate(CurX,CurY,X,XLen,Depth:Byte;Dir:Boolean;
                       VAR Buffer:pBuffer);
{CurX/CurY is the row/column to start writing on.
 X is on which position in Data to start with.
 XLen is the number of chars to write for each line.
 Depth is the number of levels to go.
 Dir is which direction to go. True = Next, False = Prev.
 Buffer is the the first Buffer to work with}

VAR TmpBuffer : pBuffer;
    B         : Byte;
    S         : STRING;

BEGIN
   IF (Depth=0) OR (X=0) OR (XLen=0) THEN Exit;
   TmpBuffer:=Buffer;
   FOR B:=1 TO Depth DO BEGIN
      GotoXY(CurX,CurY+B-1);
      FillChar(S[1],XLen,' ');
      IF TmpBuffer<>NIL THEN S:=Copy(GetBufferData(TmpBuffer),X,XLen);
      S[0]:=Chr(XLen);
      Write(S);
      IF TmpBuffer<>NIL THEN 
         IF Dir THEN TmpBuffer:=BufferNext(TmpBuffer)
            ELSE TmpBuffer:=BufferPrev(TmpBuffer);
   END;
END;

The above procedure will have a rather fun bug on many but not all systems, let's see if you can figure it out and catch it :)

And now an updater for the entire window

PROCEDURE UpdateEntireWindow(X:Byte;Dir:Boolean;VAR Buffer:pBuffer;
                             Window:tWindow);

{for explanation of parameters see WindowUpdate.
 Window is the tWindow we have to work with}

BEGIN
   WITH Window DO WindowUpdate(XPos, YPos, X, XLength, YLength, True, 
                               Buffer);
END;

Hmm, that seems to be about what we need to have in screens.pas, oh well, most likely I will write an addendum to this one.

End of part2.

Back to previous page

Useful Links









Link to us