Einzelnen Beitrag anzeigen

Nils_13

Registriert seit: 15. Nov 2004
2.647 Beiträge
 
#1

Terminal: Inhalt bei Fensterskalierung anpassen

  Alt 22. Mär 2008, 18:01
Hi,

ich möchte aus Spaß einen kleinen Terminal programmieren der auf Canvas basiert. Damit man am Ende auch noch alle Befehle im Griff hat und sich da nichts dumm zusammensuchen muss, ergab sich folgendes System:
Delphi-Quellcode:
type
  TDynIntArray = Array of Integer;
  TDynChrArray = Array of Char;

  TScreen = record
    X, Y : TDynIntArray;
    Text : TDynChrArray;
  end;

  TfrmMain = class(TForm)
    ...
  private
    { Private-Deklarationen }
    Befehle : Array of TScreen;
    pX : Integer;
  public
    { Public-Deklarationen }
  end;
Jeder Befehl enthält einen record namens Screen. In Screen wird jedes zum Befehl gehörige Zeichen inklusive X- und Y-Position gespeichert. Dieses System muss genauso sein, damit der Terminal automatische Zeilenumbrüche (Vermeiden von Schreiben über den Rand hinaus) beherrscht. Im folgenden Codeabschnitt werden X, Y und aktuelles Zeichen des Screens des aktuellen Befehls befüllt:
Delphi-Quellcode:
procedure TfrmMain.FormKeyPress(Sender: TObject; var Key: Char);
begin
  with Befehle[High(Befehle)] do
  begin
    SetLength(X, Length(X)+1);
    X[High(X)] := pX; // eintragen des aktuellen X-Wertes
    inc(pX); // erhöhen des X-Wertes für das nächste Mal

    SetLength(Y, Length(Y)+1);
    if X[High(X)]*7 >= ClientWidth-4 then // Alle Textzeichen sind 7 Pixel breit. Wenn der aktuelle X-Wert >= der Zeichenflächenbreite ist, muss umgebrochen werden
    begin
      Y[High(Y)] := Y[High(Y)-1]+1; // der letzte Y-Wert wird aufgegriffen und um 1 erhöht
      X[High(X)] := 0; // da der aktuelle X-Wert außerhalb des Fensters liegt, muss er noch auf 0 verschoben werden, damit er in der nächsten Zeile am Zeilenanfang steht

      SetLength(Text, Length(Text)+1);
      Text[High(Text)] := Key; // das aktuelle Zeichen hinzufügen

      pX := 1; // da das Zeichen bei X=0 schon belegt ist, geht es bei X=1 weiter
    end else
    begin
      Y[High(Y)] := Y[High(Y)-1]; // wenn es nicht nötig ist, umzubrechen, wird der letzte Y-Wert genommen

      SetLength(Text, Length(Text)+1);
      Text[High(Text)] := Key; // das aktuelle Zeichen hinzufügen
    end;
  end;
  Repaint; // neu zeichnen um den Text auf die Zeichenfläche zu bringen
end;
Der Code funktioniert. Aber was passiert, wenn man das Fenster vergrößert ? Neben dem Text entsteht ein Freiraum. Was passiert, wenn man das Fenster verkleinert ? Ein Teil des Textes ist nicht mehr sichtbar. Ich muss nun die X- und Y-Werte anpassen. Man könnte die X-Werte in ein temporäres 1D-Array packen und dort weiterverarbeiten. Aber wie verarbeitet man es weiter ? Abgesehen davon muss das zugehörige Y-Array auch noch angepasst werden. Habt ihr eine Idee, wie man die Fensterskalierung gut lösen könnte ?
Delphi-Quellcode:
procedure TfrmMain.FormResize(Sender: TObject);
var Alt, DifW, i : Integer; // Alt=Alte Fensterbreite; DifW=Differenz zwischen neuer und alter Breite
    tmp : TDynIntArray;
begin
  Alt := Width;
  Width := Round((Alt div 7)*7)+1;
  DifW := (Alt - Width) div 7;
  
  for i := 0 to High(Befehle) do
  begin
    tmp := Befehle[i].X;
  end;

  SetLength(tmp, 0);
  Repaint;
end;
  Mit Zitat antworten Zitat