Solved

Dynamically create color chart

Posted on 2000-02-17
6
268 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

726 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