00001
00002
00003
00004 #include "stdafx.h"
00005 #include "DlgAutoLayout.h"
00006 #include "CommonSmart.h"
00007
00008 #ifdef _DEBUG
00009 #define new DEBUG_NEW
00010 #undef THIS_FILE
00011 static char THIS_FILE[] = __FILE__;
00012 #endif
00013
00015
00016
00017
00018 CDlgAutoLayout::CDlgAutoLayout(CWnd* pParent )
00019 : CDialog(CDlgAutoLayout::IDD, pParent)
00020 {
00021
00022 m_startFromScratch = TRUE;
00023
00024 m_currentSolution = NULL;
00025 m_bAbortionRequested = false;
00026 m_bCurrentResults = false;
00027 }
00028
00029 CDlgAutoLayout::~CDlgAutoLayout()
00030 {
00031 }
00032
00033 void CDlgAutoLayout::initialize( IMgaProject * project, IMgaModel* model )
00034 {
00035 m_project = project;
00036 m_model = model;
00037
00038 COMTHROW( m_model->get_Meta((IMgaMetaFCO**)PutOut(m_metaModel)) );
00039 COMTHROW( m_metaModel->get_Aspects( PutOut(m_metaAspects) ) );
00040 }
00041
00042 LayoutOptimizerListener::ContinueAbortOrCurrent CDlgAutoLayout::update( int percentage, LayoutSolution * sol, double score )
00043 {
00044 m_score = score;
00045 m_currentSolution = sol;
00046 m_progressOptimization.SetPos(percentage);
00047 m_graph.Invalidate(FALSE);
00048 m_graph.UpdateWindow();
00049
00050
00051 m_updateTime++;
00052 if( m_updateTime > 50 )
00053 {
00054 m_updateTime = 0;
00055 Invalidate(FALSE);
00056 UpdateWindow();
00057 }
00058
00059
00060
00061
00062 MSG msg;
00063 while (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
00064 {
00065 if (!AfxGetApp()->PumpMessage())
00066 {
00067 break;
00068 }
00069 }
00070
00071 return (m_bAbortionRequested ? LayoutOptimizerListener::ABORT :
00072 (m_bCurrentResults ? LayoutOptimizerListener::CURRENT : LayoutOptimizerListener::CONTINUE));
00073 }
00074
00075 void CDlgAutoLayout::DoDataExchange(CDataExchange* pDX)
00076 {
00077 CDialog::DoDataExchange(pDX);
00078
00079 DDX_Control(pDX, IDC_LIST_ASPECTS, m_listAspects);
00080 DDX_Control(pDX, IDC_PROGRESS_OPT, m_progressOptimization);
00081 DDX_Control(pDX, IDC_PROGRESS_ASPECT, m_progressAspect);
00082 DDX_Control(pDX, IDC_BUTTON_GRAPH, m_graph);
00083 DDX_Check(pDX, IDC_CHECK_STARTFROMSCRATCH, m_startFromScratch);
00084 DDX_Control(pDX, IDC_BUTTON_START, m_startButton);
00085 DDX_Control(pDX, IDC_BUTTON_ABORT, m_abortButton);
00086 DDX_Control(pDX, IDC_BUTTON_CURRENT_RESULTS, m_currentResultsButton);
00087
00088 }
00089
00090 BEGIN_MESSAGE_MAP(CDlgAutoLayout, CDialog)
00091
00092 ON_WM_DRAWITEM()
00093 ON_BN_CLICKED(IDC_BUTTON_START, OnButtonStart)
00094 ON_BN_CLICKED(IDC_BUTTON_ABORT, OnButtonAbort)
00095 ON_BN_CLICKED(IDC_BUTTON_CURRENT_RESULTS, OnButtonCurrentResults)
00096
00097 END_MESSAGE_MAP()
00098
00100
00101
00102 BOOL CDlgAutoLayout::OnInitDialog()
00103 {
00104 CDialog::OnInitDialog();
00105
00106 m_graph.GetClientRect( m_graphRect );
00107 m_backBrush.CreateSolidBrush( RGB( 192, 192, 192 ) );
00108 CDC* dc = m_graph.GetDC();
00109 m_graphDC.CreateCompatibleDC( dc );
00110 m_graphBmp.CreateCompatibleBitmap( dc, m_graphRect.Width(), m_graphRect.Height() );
00111 m_graphOldBmp = (CBitmap*)m_graphDC.SelectObject( &m_graphBmp );
00112 m_graph.ReleaseDC( dc );
00113
00114 long aspectNum;
00115 COMTHROW( m_metaAspects->get_Count( &aspectNum ) );
00116 m_listAspects.ResetContent();
00117 for( int i=0; i<aspectNum; ++i )
00118 {
00119 CComObjPtr<IMgaMetaAspect> aspect;
00120 COMTHROW( m_metaAspects->get_Item( i+1, PutOut(aspect) ) );
00121 CComBSTR aspectName;
00122 COMTHROW( aspect->get_Name(&aspectName) );
00123 m_listAspects.AddString( CString(aspectName) );
00124 }
00125 m_listAspects.SetSel(0,TRUE);
00126
00127 m_progressOptimization.ShowWindow( SW_HIDE );
00128 m_progressAspect.ShowWindow( SW_HIDE );
00129
00130 m_abortButton.EnableWindow(FALSE);
00131 m_currentResultsButton.EnableWindow(FALSE);
00132
00133 return TRUE;
00134 }
00135
00136 void CDlgAutoLayout::drawSolution( CDC * dc, LayoutSolution * sol )
00137 {
00138 unsigned int i,j;
00139
00140
00141 dc->FillRect( &m_graphRect, &m_backBrush );
00142 dc->Draw3dRect( &m_graphRect, RGB( 128, 128, 128 ), RGB( 255, 255, 255 ) );
00143
00144 if( sol == NULL )
00145 return;
00146
00147
00148 NodePosVec& nodes = sol->getNodes();
00149 LayoutOptProblem * problem = sol->getProblem();
00150 double psx = problem->getWidth();
00151 double psy = problem->getHeight();
00152 for( i=0; i<nodes.size(); ++i )
00153 {
00154 int x = (int)(m_graphRect.Width() * nodes[i].m_x / psx);
00155 int y = (int)(m_graphRect.Height() * nodes[i].m_y / psy);
00156 int sx = (int)(m_graphRect.Width() * nodes[i].m_node->m_sx / psx );
00157 int sy = (int)(m_graphRect.Height() * nodes[i].m_node->m_sy / psy );
00158 dc->Rectangle( x, y, x+sx, y+sy );
00159
00160 for( j=0; j<nodes[i].m_node->m_ports.size(); ++j )
00161 {
00162 Node * port = nodes[i].m_node->m_ports[j];
00163 int x1 = x + (int)(m_graphRect.Width() * port->m_x / psx);
00164 int y1 = y + (int)(m_graphRect.Height() * port->m_y / psy);
00165 int sx1 = (int)(m_graphRect.Width() * port->m_sx / psx);
00166 int sy1 = (int)(m_graphRect.Height() * port->m_sy / psy);
00167 dc->Rectangle( x1, y1, x1+sx1, y1+sy1 );
00168 }
00169 }
00170
00171
00172 EdgeVec& edges = problem->getEdges();
00173 for( i=0; i<edges.size(); ++i )
00174 {
00175 int x1, y1, x2, y2;
00176 sol->calcEdgeEnds( edges[i], x1, y1, x2, y2 );
00177
00178 int xp1 = (int)(m_graphRect.Width() * x1 / psx);
00179 int yp1 = (int)(m_graphRect.Height() * y1 / psy);
00180 int xp2 = (int)(m_graphRect.Width() * x2 / psx);
00181 int yp2 = (int)(m_graphRect.Height() * y2 / psy);
00182
00183 dc->MoveTo( xp1, yp1 );
00184 dc->LineTo( xp2, yp2 );
00185 }
00186
00187
00188 dc->SetBkMode( TRANSPARENT );
00189 CString scoreLabel;
00190 scoreLabel.Format(_T("Fitness = %.6f"), m_score );
00191 dc->TextOut( 10, 10, scoreLabel );
00192 }
00193
00194 void CDlgAutoLayout::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
00195 {
00196 CDC* dc = CDC::FromHandle( lpDrawItemStruct->hDC );
00197
00198 if( nIDCtl == IDC_BUTTON_GRAPH )
00199 {
00200 drawSolution( &m_graphDC, m_currentSolution );
00201
00202 dc->BitBlt( 0, 0, m_graphRect.right, m_graphRect.bottom, &m_graphDC, 0, 0, SRCCOPY );
00203
00204 }
00205 }
00206
00207 void CDlgAutoLayout::OptimizeAllAspects() {
00208 long count;
00209 COMTHROW(m_metaAspects->get_Count(&count));
00210 for (int i = 1; i <= count; i++)
00211 {
00212 CComObjPtr<IMgaMetaAspect> aspect;
00213 COMTHROW(m_metaAspects->get_Item(i, &aspect.p));
00214 Optimize(aspect);
00215 }
00216 }
00217
00218 void CDlgAutoLayout::Optimize(CComObjPtr<IMgaMetaAspect>& aspect) {
00219
00220 GMEGraph graph( m_project, m_model, aspect );
00221 LayoutOptimizer optimizer( &graph );
00222 m_updateTime = 0;
00223 optimizer.optimize( (this->GetSafeHwnd() ? this : NULL), m_startFromScratch>0 );
00224 if ( !m_bAbortionRequested )
00225 {
00226 m_currentSolution = NULL;
00227 if (m_graph.GetSafeHwnd())
00228 m_graph.Invalidate(FALSE);
00229
00230
00231 CComObjPtr<IMgaParts> parts;
00232 long n;
00233 COMTHROW( m_model->get_AspectParts(aspect, 0, PutOut(parts)) );
00234 COMTHROW( parts->get_Count(&n) );
00235
00236 for( int i=0; i<n; ++i )
00237 {
00238 CComObjPtr<IMgaPart> part;
00239 CComObjPtr<IMgaFCO> fco;
00240
00241 COMTHROW( parts->get_Item(i+1, PutOut(part)) );
00242 COMTHROW( part->get_FCO(PutOut(fco)) );
00243
00244 for( unsigned int j=0; j<graph.m_nodes.size(); ++j )
00245 {
00246 if( fco == graph.m_nodes[j]->m_fco )
00247 {
00248 COMTHROW( part->SetGmeAttrs(0, graph.m_nodes[j]->m_x, graph.m_nodes[j]->m_y) );
00249 }
00250 }
00251 }
00252 }
00253 }
00254
00255 void CDlgAutoLayout::OnButtonStart()
00256 {
00257 try
00258 {
00259 UpdateData();
00260 CWnd* checkBoxWnd = GetDlgItem(IDC_CHECK_STARTFROMSCRATCH);
00261 if (checkBoxWnd != NULL)
00262 checkBoxWnd->EnableWindow(FALSE);
00263 m_startButton.EnableWindow(FALSE);
00264 m_abortButton.EnableWindow(TRUE);
00265 m_currentResultsButton.EnableWindow(TRUE);
00266
00267 m_progressOptimization.ShowWindow( SW_SHOW );
00268 m_progressAspect.ShowWindow( SW_SHOW );
00269 m_progressAspect.SetPos(1);
00270 m_progressAspect.UpdateWindow();
00271
00272 int selNum = m_listAspects.GetSelCount();
00273 int aspectsProcessed = 0;
00274
00275 if( selNum == 0 )
00276 return;
00277
00278 for( int i=0; i<m_listAspects.GetCount() && !m_bAbortionRequested; ++i )
00279 {
00280 if( m_listAspects.GetSel(i) > 0 )
00281 {
00282 aspectsProcessed++;
00283 m_progressAspect.SetPos( (int)(100*aspectsProcessed/(double)selNum) );
00284
00285 CComObjPtr<IMgaMetaAspect> aspect;
00286 COMTHROW( m_metaAspects->get_Item( i+1, PutOut(aspect) ) );
00287
00288 Optimize(aspect);
00289 }
00290 }
00291
00292 m_progressOptimization.ShowWindow( SW_HIDE );
00293 m_progressAspect.ShowWindow( SW_HIDE );
00294 }
00295 catch(...)
00296 {
00297 AfxMessageBox(_T("An internal error occurred in AutoLayout component. Error code = 1"));
00298 CDialog::OnCancel();
00299 }
00300
00301 if (m_bAbortionRequested)
00302 CDialog::OnCancel();
00303 else
00304 CDialog::OnOK();
00305 }
00306
00307 void CDlgAutoLayout::OnButtonCurrentResults()
00308 {
00309 m_bCurrentResults = true;
00310 }
00311
00312 void CDlgAutoLayout::OnButtonAbort()
00313 {
00314 int nRet = IDYES;
00315 if (nRet == IDYES)
00316 m_bAbortionRequested = true;
00317 else
00318 ASSERT(nRet == IDNO);
00319 }