• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 275
  • Last Modified:

Dynamically create color chart

Hi Guy's,

I want to create a color chart just like the paints shops have to show the shade of color.

I have a list of 50 colors; I would like to dynamically create 50 TPanels change the color or each panel created to match Colors I have in my list.

If the color is say CLBlue the caption need to read Blue.

What is the best way to do this?

Asw
0
Asw
Asked:
Asw
  • 3
  • 3
1 Solution
 
TheNeilCommented:
Well I wouldn't use panels for starters. You're better off using a single image and just drawing onto that.

bw := Image1.Width DIV 10;
bh := Image1.Height DIV 5;
FOR n := 0 TO 49
DO
BEGIN
  x := n MOD 10;
  y := n DIV 10;

  Image1.Canvas.Brush.Color := Colour[n];
  Image1.Canvas.FillRect(RECT(x * bw, y * bh, (x + 1) * bw, (y + 1) * bh));

  CASE Image1.Canvas.Brush.Color OF
    clRed   : TextStr := 'clRed';
    clBlue  : TextStr := 'clBlue';
    ...  
    clBlack : TextStr := 'clBlack';
  ELSE
    TextStr := 'Colour ' + IntToStr(n + 1);
  END;
  cx := (bw - Image1.Canvas.TextWidth(TextStr)) DIV 2;
  cy := (bh - Image1.Canvas.TextHeight(TextStr)) DIV 2;
  Image1.Canvas.TextOut(x * bw + cx, y * bh + cy, TextStr);
END;

The above code will do exactly what you want. Naturally you can tart it up a bit (bevels etc.) and if you want code to do that then just say.

All you have to do is setup your colour array properly by doing something like the following:

AssignFile(data_in, 'c:\colours.txt');
Reset(data_in);
FOR n := 0 TO 49
DO
BEGIN
  READLN(data_in, r, g, b);
  Colours[n] := RGB(r, g, b);
END;

CloseFile(data_in);

That's the way that I'd do it. If (as I think you'll want to do) you want to allow the user to select a colour then just use the mouse x and y co-ords to work out which box you're in

index := (x DIV bw) + 10 * (y DIV bh);

index now points to the colour in your colour array

The Neil
0
 
TheNeilCommented:
BTW,

I've put 'cl' in front of the colour text in the case statement because basically I'm brain dead and don't read things properly. Just get rid of the 'cl' bit of text and put whatever you need (best put in all the other colours you want to match). Because there are not names for every colour, it will deafult to just putting 'Colour X'. You can actually get around this by adding additional case conditions defined as RGB values

e.g.
RGB(200, 0, 0) : TextStr := 'Mid Red';

Hope this gets me some points

The Neil
0
 
AswAuthor Commented:
Hi TheNeil,

Thanks for your help.

Can you give me some code to tart it up like (bevels etc).

Can you give me an idea how to lay the filename out'c:\colours.txt'.

Put your reply as an answer.

Many thanks
Andy

0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
AswAuthor Commented:
Hi TheNeil,

Thanks for your help.

Can you give me some code to tart it up like (bevels etc).

Can you give me an idea how to lay the filename out'c:\colours.txt'.

Put your reply as an answer.

Many thanks
Andy

0
 
TheNeilCommented:
Andy,

No problems. I had a quick look at the code and added things like bevels in, fixed the naming etc. so try this routine

procedure TForm1.Button1Click(Sender: TObject);
VAR
  TextStr : STRING;
  n       : INTEGER;
  bw      : INTEGER;
  bh      : INTEGER;
  x       : INTEGER;
  y       : INTEGER;
  cx      : INTEGER;
  cy      : INTEGER;
begin
  bw := Image1.Width DIV 10;
  bh := Image1.Height DIV 5;

  Image1.Width := bw * 10;
  Image1.Height := bh * 5;

  FOR n := 0 TO 49
  DO
  BEGIN
    x := n MOD 10;
    y := n DIV 10;

    Image1.Canvas.Brush.Color := Colurs[n];
    Image1.Canvas.FillRect(RECT(x * bw, y * bh, (x + 1) * bw, (y + 1) * bh));

    CASE Image1.Canvas.Brush.Color OF
      clRed   : TextStr := 'Red';
      clBlue  : TextStr := 'Blue';
      clBlack : TextStr := 'Black';
    ELSE
      TextStr := 'Colour ' + IntToStr(n + 1);
    END;

    Image1.Canvas.Font.Color := clWhite - Image1.Canvas.Brush.Color;

    cx := (bw - Image1.Canvas.TextWidth(TextStr)) DIV 2;
    cy := (bh - Image1.Canvas.TextHeight(TextStr)) DIV 2;
    Image1.Canvas.TextOut(x * bw + cx, y * bh + cy, TextStr);
   
    Image1.Canvas.Brush.Color := clGray;
    Image1.Canvas.FrameRect(RECT(x * bw, y * bh, (x + 1) * bw, (y + 1) * bh));
    Image1.Canvas.Pen.Color := clWhite;
    Image1.Canvas.MoveTo(x * bw, (y + 1) * bh);
    Image1.Canvas.LineTo(x * bw, y * bh);
    Image1.Canvas.LineTo((x + 1) * bw, y * bh);
  END;
end;

You still need to add in the extra colours to the case statement.

What this version does is add the bevels, improves the strings, and selects a better colour for the text (based on the colour of the 'panel'.

Storing your data is a very easy affair and you can just use a standard ASCII text file, which uses the following format

r-value g-value b-value

e.g.

0 0 0
128 0 0
255 0 0
....

All you have to do is create the 50 colours that you want as 50 sets of RGB values.

I don't know if you need to know how to read the file or not but I'll include the code anyway

AssignFile(data_in, 'c:\colours.txt');
Reset(data_in);
FOR n := 0 TO 49
DO
BEGIN
  READLN(data_in, r, g, b);
  Colours[n] := RGB(r, g, b);
END;
CloseFile(data_in);

And that's all there is to it. If you want to increase the number of colours then just adjust the number of blocks across and down, and update the loops. Fot the most flexible system, add a value to the start of the colours file indicating how many colours it contains and calculate the optimum number of blocks across and down. You probably don't need any of his but I may as well earn these points

Any problems - just ask

The Neil
0
 
AswAuthor Commented:
Hi The Neil,

Thanks very much for your help the code
is superb.

Thanks

Andy
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now