// Matt Streeter
// 2/27/00
// GENWIN.CPP
// Implementation of class TGenerationWindow; window class for displaying
// networks in a population by generation.
// Copyright Matt Streeter, 2000. All rights reserved
#include "genwin.h"
#include <owl\scroller.h>
// The following four #defines determine, respectively, the left, right, top
// and bottom borders, in pixels, between the window edge and window contents.
#define WINDOW_LBORDER 7
#define WINDOW_RBORDER 10
#define WINDOW_TBORDER 10
#define WINDOW_BBORDER 45
// The amount of horizontal space, in pixels, that is allocated to display
// the generation numbers.
#define LABEL_HSPACE 23
// The following two #defines determine the face and height of the font
// used to display the generation numbers.
#define LABEL_FONT_FACE "Times New Roman"
#define LABEL_FONT_HEIGHT 15
// Vertical border, in pixels, one generation and the next.
#define GENERATION_VBORDER 10
// The maximum depth to which the links of a family tree will be displayed
// when a network is selected.
#define DEFAULT_MAX_TREE_DEPTH 6
DEFINE_RESPONSE_TABLE1(TGenerationWindow, THeredityWindow)
EV_WM_SIZE,
EV_WM_LBUTTONDOWN,
EV_WM_LBUTTONDBLCLK,
END_RESPONSE_TABLE;
TColor TGenerationWindow::mLabelColor(255,255,255);
TGenerationWindow::TGenerationWindow(TWindow *pParent,char *pTitle,
TGeneration *pGenerationList,Network *pNetwork,double dMaxWeight,
Parameter *pParam):
THeredityWindow(pParent,pTitle,pGenerationList,pNetwork,dMaxWeight,pParam)
{
Attr.Style|=WS_VISIBLE|WS_OVERLAPPEDWINDOW|WS_VSCROLL;
// tbd: account correctly for parent coords
Attr.X=50+(pParent?pParent->Attr.X+3:0);
Attr.Y=200+(pParent?pParent->Attr.Y+25:0);
Attr.W=400;
Attr.H=275;
Scroller = new TScroller(this,1,1,100,100);
miMaxTreeDepth=DEFAULT_MAX_TREE_DEPTH;
}
void TGenerationWindow::Paint(TDC& dc, bool, TRect&)
{
int n;
int iXCursor,iYCursor,iNetworkRectsDrawn;
TGeneration *pCurGeneration;
TRect DrawRect;
int iGeneration;
GetClientRect(DrawRect);
DrawRect.left+=WINDOW_LBORDER+LABEL_HSPACE;
DrawRect.top+=WINDOW_TBORDER;
DrawRect.right-=WINDOW_RBORDER;
DrawRect.bottom-=WINDOW_BBORDER;
if(DrawRect.bottom<DrawRect.top || DrawRect.right<DrawRect.left)
return;
if(mpNetworkRects)
delete(mpNetworkRects);
miNetworkRects=0;
pCurGeneration=mpGenerationList;
while(pCurGeneration)
{
miNetworkRects+=pCurGeneration->iSurvivors;
pCurGeneration=pCurGeneration->pNext;
}
// prevent allocation of > 64K chunk if running in 16-bit mode
if((sizeof(short)==sizeof(int)) &&
(long)miNetworkRects*(long)sizeof(TNetworkRect)>65000L)
{
return;
}
mpNetworkRects=new TNetworkRect[miNetworkRects];
iNetworkRectsDrawn=0;
iYCursor=DrawRect.top;
TBrush BoxBrush(mBoxColor);
TFont LabelFont(LABEL_FONT_FACE,LABEL_FONT_HEIGHT);
dc.SelectObject(LabelFont);
dc.SetBkColor(mBackgroundColor);
dc.SetTextColor(mLabelColor);
pCurGeneration=mpGenerationList;
iGeneration=0;
while(pCurGeneration)
{
byte bIsVisible=0;
if(Scroller->IsVisibleRect(DrawRect.left/Scroller->XUnit,
iYCursor/Scroller->YUnit,
(mMatrix.GetWidth()+1)/Scroller->XUnit,
(mMatrix.GetHeight()+1)/Scroller->YUnit))
{
bIsVisible=1;
}
if(bIsVisible)
{
// draw current generation's label
char pLabel[200];
itoa(iGeneration,pLabel,10);
TSize Size=dc.GetTextExtent(pLabel,strlen(pLabel));
TPoint LabelPos(DrawRect.left-LABEL_HSPACE,
iYCursor+(mMatrix.GetHeight()-Size.cy)/2);
dc.TextOut(LabelPos,pLabel,strlen(pLabel));
}
// draw current generation networks
iXCursor=DrawRect.left;
for(n=0;n<pCurGeneration->iSurvivors;n++)
{
mpNetworkRects[iNetworkRectsDrawn].x=iXCursor+1;
mpNetworkRects[iNetworkRectsDrawn].y=iYCursor+1;
mpNetworkRects[iNetworkRectsDrawn].pChromosome
=&(pCurGeneration->pSurvivors[n]);
iNetworkRectsDrawn++;
if(bIsVisible)
{
dc.FrameRect(iXCursor,iYCursor,iXCursor+mMatrix.GetWidth()+1,
iYCursor+mMatrix.GetHeight()+1,BoxBrush);
// draw weight matrices
mMatrix.Paint(dc,iXCursor,iYCursor,
&(pCurGeneration->pSurvivors[n]));
}
iXCursor+=mMatrix.GetWidth()+1;
}
pCurGeneration=pCurGeneration->pNext;
iYCursor+=mMatrix.GetHeight()+2+GENERATION_VBORDER;
iGeneration++;
}
if(miSelectedNetwork!=-1)
{
DrawHighlight(miSelectedNetwork,mSelectedHighlightColor);
DrawParentLinks(miSelectedNetwork,0);
}
// set vertical scroll bar range
long lYRange=iYCursor-DrawRect.top-(DrawRect.bottom-DrawRect.top+1);
if(lYRange<0)
lYRange=0;
Scroller->SetRange(100,lYRange);
}
void TGenerationWindow::EvLButtonDown(uint, TPoint& point)
{
int iNetwork;
iNetwork=FindNetworkRect(point);
if(iNetwork==-1)
return;
if(iNetwork==miSelectedNetwork)
{
DrawHighlight(iNetwork,mBoxColor);
DrawParentLinks(iNetwork,1);
miSelectedNetwork=-1;
return;
}
if(miSelectedNetwork!=-1)
{
DrawHighlight(miSelectedNetwork,mBoxColor);
DrawParentLinks(miSelectedNetwork,1);
}
DrawHighlight(iNetwork,mSelectedHighlightColor);
DrawParentLinks(iNetwork,0);
miSelectedNetwork=iNetwork;
}
void TGenerationWindow::EvLButtonDblClk(uint, TPoint& point)
{
int iNetwork;
iNetwork=FindNetworkRect(point);
if(iNetwork==-1)
return;
DrawHighlight(iNetwork,mSelectedHighlightColor);
DrawParentLinks(iNetwork,0);
miSelectedNetwork=iNetwork;
CmEditNetwork();
}
void TGenerationWindow::DrawParentLinks(int iNetwork,byte bErase,int iDepth)
{
if(iNetwork==-1)
return;
if(iDepth>=miMaxTreeDepth)
return;
if(mpNetworkRects[iNetwork].pChromosome->miGeneration==0)
return;
int iWeightParent1=FindNetworkRect(
mpNetworkRects[iNetwork].pChromosome->miGeneration-1,
mpNetworkRects[iNetwork].pChromosome->miWeightParent1);
int iWeightParent2=FindNetworkRect(
mpNetworkRects[iNetwork].pChromosome->miGeneration-1,
mpNetworkRects[iNetwork].pChromosome->miWeightParent2);
// tbd: draw links
TClientDC dc(*this);
TPen HighlightPen(mParentHighlightColor,1);
TPen BoxPen(mBoxColor,1);
TPen BackgroundPen(mBackgroundColor,1);
if(bErase)
dc.SelectObject(BackgroundPen);
if(iWeightParent1!=-1)
{
if(!bErase)
{
if(mpNetworkRects[iNetwork].pChromosome->miWeightParent2!=-1)
dc.SelectObject(HighlightPen);
else
dc.SelectObject(BoxPen);
}
dc.MoveTo(mpNetworkRects[iNetwork].x-X_SCROLL_OFFSET-1+mMatrix.GetWidth()/2,
mpNetworkRects[iNetwork].y-Y_SCROLL_OFFSET-2);
dc.LineTo(
mpNetworkRects[iWeightParent1].x-X_SCROLL_OFFSET-1+mMatrix.GetWidth()/2,
mpNetworkRects[iWeightParent1].y-Y_SCROLL_OFFSET+mMatrix.GetHeight()+1);
DrawHighlight(iWeightParent1,bErase?mBoxColor:mParentHighlightColor);
}
if(iWeightParent2!=-1)
{
if(!bErase)
dc.SelectObject(HighlightPen);
dc.MoveTo(mpNetworkRects[iNetwork].x-X_SCROLL_OFFSET-1
+mMatrix.GetWidth()/2,mpNetworkRects[iNetwork].y-Y_SCROLL_OFFSET-2);
dc.LineTo(
mpNetworkRects[iWeightParent2].x-X_SCROLL_OFFSET-1
+mMatrix.GetWidth()/2,
mpNetworkRects[iWeightParent2].y
-Y_SCROLL_OFFSET+mMatrix.GetHeight()+1);
DrawHighlight(iWeightParent2,bErase?mBoxColor:mParentHighlightColor);
}
DrawParentLinks(iWeightParent1,bErase,iDepth+1);
DrawParentLinks(iWeightParent2,bErase,iDepth+1);
}
void TGenerationWindow::EvSize(UINT SizeType, TSize& Size)
{
TWindow::EvSize(SizeType, Size);
if(SizeType != SIZEICONIC)
{
Invalidate(FALSE);
}
}