//=========================================================================== // COORDINATED ARRAYS OF LABELS, SHAPES and IMAGES // (with drag-and-drop) // 28 May 2007 // // You can create arrays of labels, shapes and images // to help visualize the state of each agent in a simulation. // // In this sampler, six faces are imported as six Borland Image Components // representing a range of emotion from happy to sad. They are transparent // bitmap (.bmp) images (they could have been colored but these are not). // // We then create an array of 18 images and copy the ->Picture property // from these 6 Borland Image Components into the ->Picture property of // our array of images showing that we can change the ->Picture property // dynamically. // // We create OnMouseDown, OnMouseMove and OnMouseUp events for the images // in the array so that we can drag-and-drop them on the screen. These // events don't discriminate between the Left and Right Mouse Buttons. // // We create an OnMouseDown event for the Right Mouse Button which changes // the ->Picture property in the image clicked. //=========================================================================== #include #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { DoubleBuffered = true; // helps to eliminate flicker } //--------------------------------------------------------------------------- //=========================================================================== // VARIABLES //=========================================================================== class anAgent { public: int x; int y; } agent[18]; // sets up arrays of labels, shapes and images TStaticText *text[18] = {0}; TShape *shape[18] = {0}; TImage *image[18] = {0}; // these variables coordinate drag-and-drop events int chosenImage; int imageDownX, imageDownY; bool imageWasChosen = false; //=========================================================================== // FUNCTIONS //=========================================================================== //---------------------------------------------------------------- Color Ramp int colorRamp(int value, int maximum) { if (value == 0) value = 1; int pixelDistanceAlongPath = (value * 1792) / maximum; int red, green, blue; // Which edge of the color cube are we on? if (pixelDistanceAlongPath < 256) { // Edge 1 from BLACK to BLUE red=0; green=0; blue=pixelDistanceAlongPath; } else if (pixelDistanceAlongPath < 512) { // Edge 2 from BLUE to CYAN red =0; green=pixelDistanceAlongPath-256; blue=255; } else if (pixelDistanceAlongPath < 768) { // Edge 3 from CYAN to GREEN red =0; green =255; blue= 255-(pixelDistanceAlongPath-512); } else if (pixelDistanceAlongPath < 1024) { // Edge 4 from GREEN to YELLOW red= (pixelDistanceAlongPath-768); green =255; blue =0; } else if (pixelDistanceAlongPath <1280) { // Edge 5 from YELLOW to RED red =255; green=255-(pixelDistanceAlongPath-1024); blue =0; } else if (pixelDistanceAlongPath < 1536) { // Edge 6 from RED to MAGENTA red =255; green=0; blue=pixelDistanceAlongPath -1280; } else { // Edge 7 from MAGENTA to WHITE red =255; green=pixelDistanceAlongPath-1536; blue =255; } return (RGB(red, green, blue)); } //--------------------------------------------------------------------- Reset void reset (void) { for (int i = 0; i < 18; i++) { agent[i].x = random(400); agent[i].y = random(400); text[i]->Top = agent[i].y - 5; text[i]->Left = agent[i].x - 5; shape[i]->Top = agent[i].y; shape[i]->Left = agent[i].x; shape[i]->Height = 65; shape[i]->Width = 65; shape[i]->Pen->Color = clYellow; shape[i]->Brush->Color = clYellow; image[i]->Top = agent[i].y; image[i]->Left = agent[i].x; image[i]->Height = 65; image[i]->Width = 65; } } //-------------------------------------------------------------------- Shrink void shrink (void) { for (int i = 0; i < 18; i++) { shape[i]->Height -= 5; shape[i]->Width -= 5; image[i]->Height -= 5; image[i]->Width -= 5; } } //---------------------------------------------------------------------- Grow void grow (void) { for (int i = 0; i < 18; i++) { shape[i]->Height += 5; shape[i]->Width += 5; image[i]->Height += 5; image[i]->Width += 5; } } //--------------------------------------------------------------------- Color void color (void) { for (int i = 0; i < 18; i++) { shape[i]->Brush->Color = static_cast(colorRamp(i + 5, 25)); shape[i]->Pen->Color = static_cast(colorRamp(i + 5, 25)); } } //=========================================================================== // EVENT HANDLERS //=========================================================================== //-------------------------------------------------------------- OnFormCreate void __fastcall TForm1::FormCreate(TObject *Sender) { randomize(); // randomizes the pseudo-random-number generator // defines the properties for the array of StaticText objects for (int i = 0; i < 18; i++) { text[i] = new TStaticText(this); text[i]->Parent = Form1; text[i]->Visible = true; text[i]->Caption = i; text[i]->Tag = i; text[i]->BorderStyle = sbsSunken; text[i]->Brush->Color = clAqua; } // defines the properties for the array of shape objects for (int i = 0; i < 18; i++) { shape[i] = new TShape(this); shape[i]->Parent = Form1; shape[i]->Visible = true; shape[i]->Height = 65; shape[i]->Width = 65; shape[i]->Shape = stCircle; shape[i]->Tag = i; shape[i]->Pen->Width = 2; shape[i]->Pen->Color = clYellow; shape[i]->Brush->Color = clYellow; } // defines the properties and events for the array of image objects for (int i = 0; i < 18; i++) { image[i] = new TImage(this); image[i]->Parent = Form1; image[i]->Visible = true; image[i]->Transparent = true; image[i]->Stretch = true; image[i]->AutoSize = false; image[i]->Height = 65; image[i]->Width = 65; image[i]->Proportional = true; image[i]->Tag = i; // here we copy the pictures from the original 6 invisible images if (i < 3) { image[i]->Picture = Form1->Image1->Picture; } if (i > 2 && i < 6) { image[i]->Picture = Form1->Image2->Picture; } if (i > 5 && i < 9) { image[i]->Picture = Form1->Image3->Picture; } if (i > 8 && i < 12) { image[i]->Picture = Form1->Image4->Picture; } if (i > 11 && i < 15) { image[i]->Picture = Form1->Image5->Picture; } if (i > 14) { image[i]->Picture = Form1->Image6->Picture; } // and here we associate the images with event handlers image[i]->OnMouseDown = ImageMouseDown; image[i]->OnMouseMove = ImageMouseMove; image[i]->OnMouseUp = ImageMouseUp; } reset(); } //--------------------------------------------------------------------------- // We must write the following event handlers ourselves here in Unit1.cpp // We must also write references to them in Unit1.h //--------------------------------------------------------------------------- //------------------------------------------------------- On Image Mouse Down void __fastcall TForm1::ImageMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { TImage *image = dynamic_cast(Sender); if (Button == 0) { // if left click chosenImage = image->Tag; imageWasChosen = true; imageDownX = X; imageDownY = Y; } else { // if right click if (random(2)) { // happy to sad image->Picture = Image1->Picture; Application->ProcessMessages(); Sleep(500); image->Picture = Image2->Picture; Application->ProcessMessages(); Sleep(100); image->Picture = Image3->Picture; Application->ProcessMessages(); Sleep(100); image->Picture = Image4->Picture; Application->ProcessMessages(); Sleep(100); image->Picture = Image5->Picture; Application->ProcessMessages(); Sleep(100); image->Picture = Image6->Picture; Application->ProcessMessages(); Sleep(100); } else { // sad to happy image->Picture = Image6->Picture; Application->ProcessMessages(); Sleep(500); image->Picture = Image5->Picture; Application->ProcessMessages(); Sleep(100); image->Picture = Image4->Picture; Application->ProcessMessages(); Sleep(100); image->Picture = Image3->Picture; Application->ProcessMessages(); Sleep(100); image->Picture = Image2->Picture; Application->ProcessMessages(); Sleep(100); image->Picture = Image1->Picture; Application->ProcessMessages(); Sleep(100); } } } //------------------------------------------------------- On Image Mouse Move void __fastcall TForm1::ImageMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { TImage *image = dynamic_cast(Sender); if (imageWasChosen) { image->Left = image->Left + X - imageDownX; image->Top = image->Top + Y - imageDownY; shape[chosenImage]->Left = shape[chosenImage]->Left + X - imageDownX; shape[chosenImage]->Top = shape[chosenImage]->Top + Y - imageDownY; text[chosenImage]->Left = text[chosenImage]->Left + X - imageDownX; text[chosenImage]->Top = text[chosenImage]->Top + Y - imageDownY; } } //--------------------------------------------------------- On Image Mouse Up void __fastcall TForm1::ImageMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { //TImage *image = dynamic_cast(Sender); imageWasChosen = false; } //------------------------------------------------------------- Shrink Button void __fastcall TForm1::ButtonShrinkClick(TObject *Sender) { shrink(); } //--------------------------------------------------------------- Grow Button void __fastcall TForm1::ButtonGrowClick(TObject *Sender) { grow(); } //-------------------------------------------------------------- Color Button void __fastcall TForm1::ButtonColorClick(TObject *Sender) { color(); } //-------------------------------------------------------------- Reset Button void __fastcall TForm1::ButtonResetClick(TObject *Sender) { reset(); } //---------------------------------------------------------- That's All Folks