Board index » cppbuilder » ImageList from TColorBox

ImageList from TColorBox


2005-12-03 09:00:41 AM
cppbuilder71
I have a TColorBox where I Choose the colors to use for drawing a graph.
The graph is made up from Items in a TListView and for each one I select a
color from the TColorBox. I've tried to figure out how to display the same
Color Icon as is found in the TColorBox from the ImageList connected to The
TListView when I select one. Right now I only paste the pretty name in the
Caption Column. It doesn't look real professional and what I'm looking at is
creating an imagelist of my own with little square color Icons. Not so hard
maybe but not so cool either. Especially if I change which colors to display
with the Style property. Then I'm all out of synch all of a sudden.
I don't necessarily have to use a TListView.
Any suggestions.
--
Perre
Sorry my site is only in Swedish as of now
www.kostforum.se
 
 

Re:ImageList from TColorBox

"Per Elmsäter" < XXXX@XXXXX.COM >wrote:
Quote

[...] I only paste the pretty name in the Caption Column.
If all you want to do is present a list of items along with
each item's associated color, I think that a TStringGrid will
work nicely for you.
Along with associating a string with each cell, you can also
associate a color with the string by using the Objects property
and the grid's OnDrawCell event will let you draw a glyph
using the assoiated color for visual feedback. In addition,
TStringGrid has all of the events and methods needed for you
to make a nice GUI for the user to customize colors.
//-------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
// set these in the IDE
StringGrid1->ScrollBars = ssVertical;
StringGrid1->DefaultDrawing = false;
StringGrid1->FixedCols = 0;
StringGrid1->FixedRows = 0;
StringGrid1->GridLineWidth = 0;
StringGrid1->ColCount = 1;
StringGrid1->DefaultColWidth = 200;
// set these at runtime
for( int Row = 0; Row < StringGrid1->RowCount; ++Row )
{
StringGrid1->Cells[0][Row] = "Name of Graph Item " + IntToStr(Row + 1);
StringGrid1->Objects[0][Row] = (TObject*) StringGrid1->Color;
}
StringGrid1->Objects[0][0] = (TObject*) clRed;
StringGrid1->Objects[0][1] = (TObject*) clLime;
}
//-------------------------------------------------------------
void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol, int ARow, TRect &Rect, TGridDrawState State)
{
TRect R = Rect;
TStringGrid *pGrid = static_cast<TStringGrid*>( Sender );
TCanvas *pCanvas = pGrid->Canvas;
if( State.Contains(gdSelected) )
{
pCanvas->Brush->Color = clHighlight;
pCanvas->Font->Color = clHighlightText;
}
else
{
pCanvas->Brush->Color = pGrid->Color;
pCanvas->Font->Color = pGrid->Font->Color;
}
pCanvas->FillRect( R );
// leave room for the color box
R.left += 14;
// draw the text
::DrawText( pCanvas->Handle, pGrid->Cells[ACol][ARow].c_str(), -1, &R, DT_SINGLELINE | DT_VCENTER );
// calculate a rect for the color box - needs work to make it look pretty
R.left = Rect.left + 2;
R.right = R.left + 10;
R.top += 2;
R.bottom -= 2;
// draw the color box
pCanvas->Brush->Color = (TColor) pGrid->Objects[ACol][ARow];
pCanvas->FillRect( R );
}
//-------------------------------------------------------------
void __fastcall TForm1::StringGrid1DblClick(TObject *Sender)
{
ColorDialog1->Color = (TColor) StringGrid1->Objects[StringGrid1->Col][StringGrid1->Row];
if( ColorDialog1->Execute() )
{
StringGrid1->Objects[StringGrid1->Col][StringGrid1->Row] = (TObject*) ColorDialog1->Color;
}
}
//-------------------------------------------------------------
~ JD
 

Re:ImageList from TColorBox

JD wrote:
Quote
"Per Elmsäter" < XXXX@XXXXX.COM >wrote:
>
>[...] I only paste the pretty name in the Caption Column.

If all you want to do is present a list of items along with
each item's associated color, I think that a TStringGrid will
work nicely for you.

Along with associating a string with each cell, you can also
associate a color with the string by using the Objects property
and the grid's OnDrawCell event will let you draw a glyph
using the assoiated color for visual feedback. In addition,
TStringGrid has all of the events and methods needed for you
to make a nice GUI for the user to customize colors.

Thanks a lot JD. I'll try this out right now.
You don't happen to be the same JD{*word*154} out on alt.mountain-bike do you?
--
Perre
Sorry my site is only in Swedish as of now
www.kostforum.se
 

{smallsort}

Re:ImageList from TColorBox

JD wrote:
Quote
"Per Elmsäter" < XXXX@XXXXX.COM >wrote:
>
>[...] I only paste the pretty name in the Caption Column.

If all you want to do is present a list of items along with
each item's associated color, I think that a TStringGrid will
work nicely for you.

Along with associating a string with each cell, you can also
associate a color with the string by using the Objects property
and the grid's OnDrawCell event will let you draw a glyph
using the assoiated color for visual feedback. In addition,
TStringGrid has all of the events and methods needed for you
to make a nice GUI for the user to customize colors.

Thank you Sir!
It worked right nicely in just a few minutes. The only thing I had to change
was a pointer implementation in your static cast
You wrote this
TStringGrid pGrid = static_cast<TStringGrid>( Sender );
and the compiler complained in VCL classes having to be constructed with the
operator new. So I modified like this and worked like a charm
TStringGrid *pGrid = static_cast<TStringGrid*>( Sender );
Much simpler than having to select an item in the listview and then
selecting a color in a TColorBox;
Getting ready to look at your TPanel suggestions now ;)
--
Perre
Sorry my site is only in Swedish as of now
www.kostforum.se
 

Re:ImageList from TColorBox

Per Elmsäter wrote:
Quote
JD wrote:
>"Per Elmsäter" < XXXX@XXXXX.COM >wrote:
>>
>>[...] I only paste the pretty name in the Caption Column.
>
>If all you want to do is present a list of items along with
>each item's associated color, I think that a TStringGrid will
>work nicely for you.
>
>Along with associating a string with each cell, you can also
>associate a color with the string by using the Objects property
>and the grid's OnDrawCell event will let you draw a glyph
>using the assoiated color for visual feedback. In addition,
>TStringGrid has all of the events and methods needed for you
>to make a nice GUI for the user to customize colors.
>

Thank you Sir!

It worked right nicely in just a few minutes. The only thing I had to
change was a pointer implementation in your static cast

You wrote this
TStringGrid pGrid = static_cast<TStringGrid>( Sender );
and the compiler complained in VCL classes having to be constructed
with the operator new. So I modified like this and worked like a charm
TStringGrid *pGrid = static_cast<TStringGrid*>( Sender );

Much simpler than having to select an item in the listview and then
selecting a color in a TColorBox;
Getting ready to look at your TPanel suggestions now ;)
Hehe ;). Now I see what happened when I reread my last post after posting.
The stars were gone ;) and the text marked bold. I was wondering why you
marked this part bold. You had actually written exactly what I found out was
needed but my Newsreader with OEQuotefix changed it to bold text instead and
I didn't see your original as I just pasted it into another editor.
Well that's another ten points to you then ;)
Thanks again
--
Perre
Sorry my site is only in Swedish as of now
www.kostforum.se
 

Re:ImageList from TColorBox

JD wrote:
Quote
"Per Elmsäter" < XXXX@XXXXX.COM >wrote:
>
>[...] I only paste the pretty name in the Caption Column.

If all you want to do is present a list of items along with
each item's associated color, I think that a TStringGrid will
work nicely for you.

Along with associating a string with each cell, you can also
associate a color with the string by using the Objects property
and the grid's OnDrawCell event will let you draw a glyph
using the assoiated color for visual feedback. In addition,
TStringGrid has all of the events and methods needed for you
to make a nice GUI for the user to customize colors.


Any suggestions on how to save this StringGrid to file?
It works nicely and I can save to and load from file but of course the
objects are lost. Ie the colors.
I use a TMemoryStream like this and somehow I need to add the Color Objects
also.
TMemoryStream *tmStream = new TMemoryStream();
tmStream->WriteComponent( StringGrid1 );
for(int x = 0; x < StringGrid1->ColCount; ++x)
{
for(int y = 0; y < StringGrid1->RowCount; ++y)
{
AnsiString s = StringGrid1->Cells[x][y];
int len = s.Length();
tmStream->WriteBuffer( &len, sizeof(int) );
tmStream->WriteBuffer( s.c_str(), len );
}
}
tmStream->SaveToFile( filename );
This saves first the StringGrid component and then the strings in each cell
but not the objects.
--
Perre
Sorry my site is only in Swedish as of now
www.kostforum.se
 

Re:ImageList from TColorBox

"Per Elmsäter" < XXXX@XXXXX.COM >wrote:
Quote

Any suggestions on how to save this StringGrid to file?
It works nicely and I can save to and load from file but
of course the objects are lost. Ie the colors. [...]

TMemoryStream *tmStream = new TMemoryStream();
tmStream->WriteComponent( StringGrid1 );
Since you are not allowing the user to customize the grid's
properties, there is no need to use WriteComponent. All you
need to save is the text and the color.
Quote
for(int x = 0; x < StringGrid1->ColCount; ++x)
{
for(int y = 0; y < StringGrid1->RowCount; ++y)
{
AnsiString s = StringGrid1->Cells[x][y];
int len = s.Length();
tmStream->WriteBuffer( &len, sizeof(int) );
tmStream->WriteBuffer( s.c_str(), len );
}
}
tmStream->SaveToFile( filename );
I've posted code before on saving and loading a TStringGrid's
content in CVS format (search the archives). When generating a
CVS file, I *always* format the file as such:
"Col 0 Row 0 text","Col 1 Row 0 text","Col 2 Row 0 Text"
"Col 0 Row 1 text","Col 1 Row 1 text","Col 2 Row 1 Text"
....
"Col 0 Row n text","Col 1 Row n text","Col 2 Row n Text"
One doesn't always *have* to use double quotes around the
individual strings to make a CVS file but it is perfectly
valid to do so and other programs that work with CVS files
will like your stuff as well. More importantly, the native
string parsing functions of BCB loves strings formatted like
the above.
The one time that you *must* use double quotes is when the
string itself has that character so all things considered,
just do it that way all of the time and BCB has a native
method that will do it for you - AnsiQuotedStr.
However, your case is slightly different because of your use
of the Objects property but it's quite simple because there's
only one column per row. I just converted the Object to an int
and then to a string and added that to the line so that the
file looks like:
"Row 0 text","1234"
"Row 1 text","5678"
....
"Row n text","987632"
Once the file is loaded using a TStringList, that's also
exactly how the the TStringList's Strings will look. Then
if you use TStringList's CommaText method using another
TStringList (for example):
StringList2->CommaText = StringList1->Strings[0];
the second TStringList's Strings will look like:
Row 0 text
1234
Then all you have to do is assign StringList2->Strings[0]
to the appropriate Cell and convert StringList2->Strings[1]
from a string to an int and assign that to the appropriate
Objects.
//-------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if( SaveDialog1->Execute() )
{
TStringGrid* pGrid = StringGrid1;
char Quote = '"';
TStringList* pList = new TStringList;
for( int Row = 0; Row < pGrid->RowCount; ++Row )
{
AnsiString S = AnsiQuotedStr( pGrid->Cells[0][Row], Quote );
S += ",";
S += AnsiQuotedStr( IntToStr((int)pGrid->Objects[0][Row]), Quote );
pList->Add( S );
}
pList->SaveToFile( SaveDialog1->FileName );
delete pList;
}
}
//-------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if( OpenDialog1->Execute() )
{
TStringGrid* pGrid = StringGrid1;
TStringList* pList = new TStringList;
pList->LoadFromFile( OpenDialog1->FileName );
pGrid->RowCount = pList->Count;
TStringList* pData = new TStringList;
for( int Row = 0; Row < pGrid->RowCount; ++Row )
{
pData->CommaText = pList->Strings[ Row ];
pGrid->Cells[0][Row] = pData->Strings[ 0 ];
pGrid->Objects[0][Row] = (TObject*)StrToInt( pData->Strings[1] );
}
delete pData;
delete pList;
}
}
//-------------------------------------------------------------
One thing puzzels me though and that's the usefulness of
saving the grid's information like this. For the data to be
meaningful, there needs to be more data from which the graph
is derived. How are you dealing with that?
~ JD
 

Re:ImageList from TColorBox

"Per Elmsäter" < XXXX@XXXXX.COM >wrote:
Quote

[...] You don't happen to be the same JD{*word*154} out on
alt.mountain-bike do you?
Sorry, no.
~ JD
 

Re:ImageList from TColorBox

"Per Elmsäter" < XXXX@XXXXX.COM >wrote:
Quote

[...] Well that's another ten points to you then ;)
I claim 15 because I don't use a reader <g>.
~ JD
 

Re:ImageList from TColorBox

JD wrote:
Quote
"Per Elmsäter" < XXXX@XXXXX.COM >wrote:
I've posted code before on saving and loading a TStringGrid's
content in CVS format (search the archives). When generating a
CVS file, I *always* format the file as such:

Hmm. I've never worked with CSV files before. But it looks interesting.
Quote
However, your case is slightly different because of your use
of the Objects property but it's quite simple because there's
only one column per row. I just converted the Object to an int
and then to a string and added that to the line so that the
I did pretty much the same thing during the wee hours of the night and added
it to my current strategy
Quote
>for(int x = 0; x < StringGrid1->ColCount; ++x)
>{
>for(int y = 0; y < StringGrid1->RowCount; ++y)
>{
>AnsiString s = StringGrid1->Cells[x][y];
>int len = s.Length();
>tmStream->WriteBuffer( &len, sizeof(int) );
>tmStream->WriteBuffer( s.c_str(), len );
if ( x == 0 ){
TColor t = (TColor)grid->Objects[x][y];
AnsiString q = t;
int size = q.Length();
tmStream->WriteBuffer( &size, sizeof(int) );
tmStream->WriteBuffer( q.c_str(), size );
}
Quote
>}
>}
>tmStream->SaveToFile( filename );
It seems to work so far. Since I only have an object in the first column I
use the " if ( x == 0 )" statement just to be safe. There is a second
Column with some indexing infrormation also.
I suppose the Object in this case being a Color makes matters fairly
simple. Credits to Remy Lebeau who showed me how to write AnsiStrings to a
TMemoryStream in this manner.
--
Perre
Sorry my site is only in Swedish as of now
www.kostforum.se
 

Re:ImageList from TColorBox

JD wrote:
Quote
"Per Elmsäter" < XXXX@XXXXX.COM >wrote:
>
>[...] Well that's another ten points to you then ;)

I claim 15 because I don't use a reader <g>.

~ JD
In this NG that seems to be wise with all these weird characters (intended
pun).
--
Perre
Sorry my site is only in Swedish as of now
www.kostforum.se