Delphi kleuren dialog met historie

In programma's moet vaak een kleur gekozen worden om een vlak in te kleuren of een lijn te tekenen.
Daarvoor wordt dan een apart form getoond waarop dat mogelijk is, een zg. dialog form.
Na de selectie sluit het form weer.

In dit artikel wordt het programmeren van dialogform voor kleurenselectie beschreven .
Hieronder een plaatje van het dialogform op ware grootte
De kleurselectie vindt plaats door de drie primaire kleuren (rood, groen, blauw) te mengen.
Het kleuren mixertje beschreef ik [ HIER ] al eerder.
Nieuw echter is dat de laatste tien gekozen kleuren worden onthouden.
Er is snel een keuze uit een vorige kleur te maken door er simpelweg op te klikken.

Componenten

    - Colormixer...........3 schuifjes om de kleur in te stellen, eigen component
    - Showbox..............paintbox om de ingestelde kleur te laten zien
    - Historybox............paintbox om de laatstgekozen kleuren te laten zien

Constanten en Variabelen

    const maxhistory = 10;
    
    var colorhistory : array[1..maxhistory+1] of dword;
        hcount : byte;
     
De kleuren zijn van het format pf32bit.
Eerdere kleurselecties staan in array colorhistory.
hcount is het aantal opgeslagen kleuren.

Procedures

Bij keuze van een kleur wordt deze bovenaan in colorhistory[ 1 ] geplaatst.
Reeds aanwezige kleuren zakken één plaats omlaag.

Nu zijn er een aantal gevallen:
1.
De eerste kleur wordt toegevoegd.
hcount was 0, wordt 1.

2.
Er waren al enkele andere kleuren opgeslagen.
Die kleuren schuiven één plaats op en de nieuwe kleur komt in colorhistory[ 1 ].
hcount wordt met éénverhoogd.
3.
Er waren al kleuren opgeslagen, waaronder de "nieuwe" kleur.
De kleuren tot aan deze kleur worden opgeschoven, de nieuwe kleur komt in [ 1 ],
hcount wordt niet verhoogd.
4.
Er zijn al tien kleuren opgeslagen.
Alle kleuren schuiven op, kleur 10 gaat verloren, nieuwe kleur in [ 1],
hcount wordt niet verhoogd.

In de onderstaande procedure wordt een "nieuwe" kleur C aan de historie toegevoegd.
procedure add2history(c : dword);
//add color c to history
var i,j : byte;
    hit : boolean;
begin
 i := 1;
 hit := false;
 while (i <= hcount) and (hit = false) do
  if colorhistory[i] = c then hit := true
   else inc(i);
 for j := i downto 2 do colorhistory[j] := colorhistory[j-1];//shift up
 if (i > hcount) and (i <= maxhistory) then hcount := i; 
 colorhistory[1] := c;
end;
In een while loop wordt eerst gekeken of de kleur al in array colorhistory voorkomt.
Als dit zo is, dan zal i een waarde <= hcount hebben.
Bij een nieuwe kleur geldt i = hcount + 1
Vandaar de truuk om array colorhistory 1 positie langer dan maxhistory te maken.
Dat zorgt er voor, dat de procedure voor alle gevallen goed werkt.

Aanroep in het dialogform

function colordialog(var col : dword) : boolean;
begin
 with colordialogform do
  begin
   colormixer.color := col;
   showmodal;
   if colordialogform.ModalResult = mrOK then
    begin
     col := colormixer.color;
     result := true;
     add2history(col);
    end
    else result := false; 
  end; 
end;
Bij de aanroep wordt een kleur meegegeven, de mixer wordt daarop ingesteld.
showmodal stopt het programma en wacht tot modalresult de waarde mrOK of mrcancel krijgt.
In geval van mrOK wordt de mixer op de nieuwe kleur ingesteld en de kleur aan de historie toegevoegd.
Het dialogform sluit met functieresultaat true.

De OK button heeft als property mrOK, ingesteld op design time.
De Cancel button heeft property mrCancel.
Tikken van de ESCAPE toets stelt ook de waarde mrCancel in.

Aanroep van het dialogform vanuit het hoofdprogramma

procedure TForm1.Button1Click(Sender: TObject);
//select button
var col : dword;
begin
 col := selcolor;
 if colordialog(col) then
  begin
   selcolor := col;
   paintbox1.invalidate;
  end;
end;
selcolor is de laatst geselecteerde kleur.
Bij true exit van de colordialog wordt paintbox1 opnieuw geschreven,
nu met de nieuwe kleur.

Voor details verwijs ik naar het complete Delphi-7 project.

Download het complete Delphi-7 project
Download het demonstratieprogramma