A Delphi color dialog form with history

On many occasions in programs a color has to be selected to fill a shape or draw a line.
A convenient way for selection is a specialized pop-up form, a so called dialog form.
After the selection the form closes.

This article describes the programming of such a dialog form.
Below is a real size picture:
Colorselection takes place by mixing the colors red, green and blue.
The colormixer detailes are found HERE.
New however is that the last ten selections are saved.
A quick selection of previously used colors is possible by simply clicking on the color.

Components

    - Colormixer...........3 slides for color mixing, my own component
    - Showbox..............paintbox to show the mixer color
    - Historybox............paintbox with the last 10 stored selections

Constants and Variables

    const maxhistory = 10;
    
    var colorhistory : array[1..maxhistory+1] of dword;
        hcount : byte;
     
Colors have the pf32bit format.
Old selections are stored in array colorhistory.
hcount is the number of stored colors.

Procedures

A new color is stored in colorhistory[ 1 ].
Old colors in the colorhistory are shifted one place down.

Several cases have to be considered:
1.
A first color is added to the history.
hcount was 0 and is increased to 1.

2.
Allready some colors are in the history.
All colors are shifted one place down, new color in colorhistory[ 1 ].
hcount is increased by 1.
3.
The new color allready is in the history.
All colors up to this color are shifted one pace down, new color in [ 1 ],
hcount is not increased.
4.
Ten colors present in the history.
All colors shift one place down. Color at [10] is lost. New color in [ 1]
hcount is not increased.

Procedure below adds the new color C to the history.
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;
First, the while loop checks for occurrance of c in the history.
If so, variable i will have a value <= hcount.
in case of a new color variable i = hcount + 1
The trick is to give the history 1 extra (dummy) position.
In this way, the procedure does it's job in all cases.

The call in the 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;
The mixer is set to the color in the call.
showmodal halts program execution until modalresult has the value mrOK or mrcancel.
In case of mrOK the mixer is adjusted to the new color, which is added to the history.
De dialogform closes with result true.

The OK button has property mrOK, defined at design time.
The Cancel button has property mrCancel.
Typing ESCAPE also sets modalresult to mrCancel.

Opening the dialogform

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 the last selected color.
If true exit, paintbox1 is repainted with the new color.

For more details please refer to the source code listing of this Delphi-7 project.

Download the complete Delphi-7 project
Download the demo program