Solved

Dynamically create color chart

Posted on 2000-02-17
6
264 Views
Last Modified: 2010-04-04
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
Comment
Question by:Asw
  • 3
  • 3
6 Comments
 
LVL 5

Expert Comment

by:TheNeil
ID: 2531609
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
 
LVL 5

Expert Comment

by:TheNeil
ID: 2531660
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
 
LVL 1

Author Comment

by:Asw
ID: 2532202
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
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 1

Author Comment

by:Asw
ID: 2532205
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
 
LVL 5

Accepted Solution

by:
TheNeil earned 200 total points
ID: 2534134
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
 
LVL 1

Author Comment

by:Asw
ID: 2536343
Hi The Neil,

Thanks very much for your help the code
is superb.

Thanks

Andy
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This video discusses moving either the default database or any database to a new volume.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now