00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "layoutCanvas.hpp"
00022 #include <wx/dcbuffer.h>
00023
00024 #define NUMTRANSITIONS 25
00025 #define TIMERINTERVAL 15
00026 #define CELL_SIZE 18
00027
00028 enum
00029 {
00030 TIMER_ID
00031 };
00032
00033
00034 DEFINE_EVENT_TYPE( LAYOUT_CANVAS_ACTION )
00035
00036
00037
00038
00042 LayoutCanvasEvent::LayoutCanvasEvent(wxEventType commandType, int id)
00043 : wxNotifyEvent( commandType, id )
00044 {
00045 x = 0;
00046 y = 0;
00047 }
00048
00049
00051
00054 int LayoutCanvasEvent::getX()
00055 {
00056 return x;
00057 }
00058
00059
00061
00064 int LayoutCanvasEvent::getY()
00065 {
00066 return y;
00067 }
00068
00069
00071
00074 void LayoutCanvasEvent::setX(int x)
00075 {
00076 this->x = x;
00077 }
00078
00079
00081
00084 void LayoutCanvasEvent::setY(int y)
00085 {
00086 this->y = y;
00087 }
00088
00089
00090 BEGIN_EVENT_TABLE(LayoutCanvas, wxWindow)
00091 EVT_PAINT(LayoutCanvas::OnPaint)
00092 EVT_LEFT_DOWN(LayoutCanvas::OnLeftDown)
00093 EVT_SCROLLWIN(LayoutCanvas::OnScroll)
00094 EVT_SIZE(LayoutCanvas::OnResize)
00095 EVT_TIMER(TIMER_ID, LayoutCanvas::OnTimer)
00096 END_EVENT_TABLE()
00097
00098
00100
00105 LayoutCanvas::LayoutCanvas(wxWindow *parent, wxWindowID id, Grid initialLayout)
00106 : wxWindow( parent, id, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE | wxSUNKEN_BORDER), layout(initialLayout), previous(initialLayout), chrono(this, TIMER_ID)
00107 {
00108 width = initialLayout.getWidth();
00109 height = initialLayout.getHeight();
00110 cellSize = CELL_SIZE;
00111 scrollX = 0;
00112 scrollY = 0;
00113 centerX = 0;
00114 centerY = 0;
00115 adjustScrollbars();
00116 adjustCenter();
00117 SetMinSize(wxSize(100, 100));
00118 enableds = true;
00119 disableds = true;
00120 inputs = true;
00121 outputs = true;
00122 spaces = true;
00123 initTransitions();
00124 resetTransitions(NUMTRANSITIONS -1);
00125 drawScene();
00126 transition = false;
00127 chrono.Start(TIMERINTERVAL, false);
00128 }
00129
00130
00132 LayoutCanvas::~LayoutCanvas()
00133 {
00134 }
00135
00136
00138
00142 void LayoutCanvas::OnPaint(wxPaintEvent& WXUNUSED (event))
00143 {
00144 wxBufferedPaintDC dc(this);
00145 clear(dc);
00146 drawGrid(dc);
00147 drawCells(dc);
00148 drawIO(dc);
00149 drawMargins(dc);
00150 }
00151
00152
00154
00159 void LayoutCanvas::OnLeftDown(wxMouseEvent& event)
00160 {
00161 if (!transition)
00162 {
00163
00164 int widgetWidth;
00165 int widgetHeight;
00166 GetClientSize(&widgetWidth, &widgetHeight);
00167 coordinate view;
00168 view.x = event.GetX();
00169 view.y = event.GetY();
00170 coordinate real = viewToReal(view);
00171
00172
00173 if ((real.x >= 0) && (real.x < width) && (real.y >= 0) && (real.y < height))
00174 {
00175 LayoutCanvasEvent event( LAYOUT_CANVAS_ACTION, GetId() );
00176 event.SetEventObject( this );
00177 event.setX(real.x);
00178 event.setY(real.y);
00179 GetEventHandler()->ProcessEvent( event );
00180 }
00181 }
00182 }
00183
00184
00186
00191 void LayoutCanvas::adjustScrollbars()
00192 {
00193 int widgetWidth;
00194 int widgetHeight;
00195 GetClientSize(&widgetWidth, &widgetHeight);
00196
00197
00198
00199
00200
00201
00202 SetScrollbar(wxHORIZONTAL, 0, widgetWidth, width*cellSize + (cellSize/2) * height);
00203 SetScrollbar(wxVERTICAL, 0, widgetHeight, height*cellSize);
00204 adjustCenter();
00205 drawScene();
00206 }
00207
00208
00210
00216 void LayoutCanvas::OnScroll(wxScrollWinEvent& event)
00217 {
00218 WXTYPE type = (WXTYPE)event.GetEventType();
00219 int pos = event.GetPosition();
00220 int orient = event.GetOrientation();
00221
00222 if (type == wxEVT_SCROLLWIN_THUMBTRACK)
00223 {
00224 if (orient == wxHORIZONTAL)
00225 {
00226
00227 scrollX = -pos;
00228 }
00229 else
00230 {
00231
00232 scrollY = -pos;
00233 }
00234 }
00235 drawScene();
00236 }
00237
00238
00240
00246 void LayoutCanvas::drawScene()
00247 {
00248 wxClientDC dc(this);
00249 wxBufferedDC bdc(&dc);
00250 clear(bdc);
00251 drawGrid(bdc);
00252 drawMargins(bdc);
00253 drawCells(bdc);
00254 drawIO(bdc);
00255 }
00256
00257
00259
00264 void LayoutCanvas::OnResize(wxSizeEvent& event)
00265 {
00266 adjustCenter();
00267 adjustScrollbars();
00268 drawScene();
00269 }
00270
00271
00273
00278 void LayoutCanvas::adjustCenter()
00279 {
00280 int widgetWidth;
00281 int widgetHeight;
00282 GetClientSize(&widgetWidth, &widgetHeight);
00283
00284 if (widgetWidth > (width * cellSize + (cellSize/2) * height))
00285 {
00286 centerX = (widgetWidth / 2) - ((width * cellSize + (cellSize / 2) * height)) / 2;
00287 }
00288 else
00289 {
00290 centerX = 0;
00291 }
00292 if (widgetHeight > (height * cellSize))
00293 {
00294 centerY = (widgetHeight / 2) - ((height * cellSize)) / 2;
00295 }
00296 else
00297 {
00298 centerY = 0;
00299 }
00300 }
00301
00302
00304
00310 coordinate LayoutCanvas::viewToReal(coordinate view)
00311 {
00312 int row = (view.y - centerY - scrollY) / cellSize;
00313 coordinate result;
00314 if ((view.x < centerX + scrollX + row * cellSize/2) || (view.y < centerY + scrollY) || (view.x > width * cellSize + centerX + scrollX + row * cellSize/2) || (view.y > height * cellSize + centerY + scrollY))
00315 {
00316 result.x = -1;
00317 result.y = -1;
00318 }
00319 else
00320 {
00321 result.y = (view.y - centerY - scrollY) / cellSize;
00322 result.x = (view.x - centerX - scrollX - result.y * cellSize / 2) / cellSize;
00323 }
00324
00325 return result;
00326 }
00327
00328
00330
00336 coordinate LayoutCanvas::realToView(coordinate real)
00337 {
00338 coordinate result;
00339 result.x = (real.x * cellSize) + centerX + scrollX + cellSize / 2 + real.y * cellSize / 2;
00340 result.y = (real.y * cellSize) + centerY + scrollY + cellSize / 2;
00341
00342 return result;
00343 }
00344
00345
00347
00353 void LayoutCanvas::drawCell(int i, int j, wxColour color, wxDC &dc)
00354 {
00355
00356 coordinate real;
00357 real.x = i;
00358 real.y = j;
00359 coordinate view;
00360 view = realToView(real);
00361
00362 dc.SetPen(wxPen(color));
00363 dc.SetBrush(wxBrush(color));
00364 dc.DrawCircle(view.x, view.y, cellSize / 2 - 1);
00365 }
00366
00367
00369
00373 void LayoutCanvas::setCellSize(int newCellSize)
00374 {
00375 if (newCellSize >= 4)
00376 {
00377 cellSize = newCellSize;
00378 adjustScrollbars();
00379 adjustCenter();
00380 }
00381 }
00382
00383
00385
00390 void LayoutCanvas::drawGrid(wxDC &dc)
00391 {
00392 dc.SetBackground(*wxWHITE_BRUSH);
00393 dc.SetPen(*wxWHITE_PEN);
00394 dc.SetBrush(*wxBLACK_BRUSH);
00395
00396 for (int i = 0; i < width; i++)
00397 {
00398 for (int j = 0; j < height; j ++)
00399 {
00400 dc.DrawCircle(scrollX + centerX + i * cellSize + cellSize / 2 + j * cellSize / 2, scrollY + centerY + j * cellSize + cellSize / 2, 3);
00401 }
00402 }
00403 }
00404
00405
00407
00410 void LayoutCanvas::drawCells(wxDC &dc)
00411 {
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 wxColour initial;
00424 wxColour final;
00425 for (int i = 0; i < layout.getWidth(); i++)
00426 {
00427 for (int j = 0; j < layout.getHeight(); j++)
00428 {
00429
00430 switch (previous(i, j))
00431 {
00432 case nENABLED:
00433 {
00434 initial = wxColour(*wxRED);
00435 break;
00436 }
00437 case nDISABLED:
00438 {
00439 initial = wxColour(*wxBLACK);
00440 break;
00441 }
00442 case nINPUT:
00443 {
00444 initial = wxColour(*wxGREEN);
00445 break;
00446 }
00447 case nOUTPUT:
00448 {
00449 initial = wxColour(*wxCYAN);
00450 break;
00451 }
00452 case nNOSPACE:
00453 {
00454 initial = wxColour(*wxLIGHT_GREY);
00455 break;
00456 }
00457 case nDONTCARE:
00458 {
00459 initial = wxColour(*wxWHITE);
00460 break;
00461 }
00462 }
00463
00464 switch (layout(i, j))
00465 {
00466 case nENABLED:
00467 {
00468 final = wxColour(*wxRED);
00469 if (enableds)
00470 {
00471 drawCell(i, j, calculateColour(initial, final, transitions[i][j]), dc);
00472 }
00473 break;
00474 }
00475 case nDISABLED:
00476 {
00477 final = wxColour(*wxBLACK);
00478 if (disableds)
00479 {
00480 drawCell(i, j, calculateColour(initial, final, transitions[i][j]), dc);
00481 }
00482 break;
00483 }
00484 case nINPUT:
00485 {
00486 final = wxColour(*wxGREEN);
00487 if (inputs)
00488 {
00489 drawCell(i, j, calculateColour(initial, final, transitions[i][j]), dc);
00490 }
00491 break;
00492 }
00493 case nOUTPUT:
00494 {
00495 final = wxColour(*wxCYAN);
00496 if (outputs)
00497 {
00498 drawCell(i, j, calculateColour(initial, final, transitions[i][j]), dc);
00499 }
00500 break;
00501 }
00502 case nNOSPACE:
00503 {
00504 final = wxColour(*wxLIGHT_GREY);
00505 if (spaces)
00506 {
00507 drawCell(i, j, calculateColour(initial, final, transitions[i][j]), dc);
00508 }
00509 break;
00510 }
00511 case nDONTCARE:
00512 {
00513 final = wxColour(*wxWHITE);
00514 break;
00515 }
00516 }
00517 }
00518 }
00519 }
00520
00521
00523
00528 void LayoutCanvas::setFittingCellSize()
00529 {
00530 int widgetWidth;
00531 int widgetHeight;
00532 GetClientSize(&widgetWidth, &widgetHeight);
00533
00534 if (widgetWidth > widgetHeight)
00535 {
00536 setCellSize(widgetHeight / height);
00537 }
00538 else
00539 {
00540 setCellSize(widgetWidth / width + 1);
00541 }
00542 }
00543
00544
00546
00551 void LayoutCanvas::setGrid(Grid newGrid, bool changed)
00552 {
00553
00554 previous.init(layout);
00555
00556 layout.init(newGrid);
00557
00558 initTransitions();
00559 resetTransitions(0);
00560 if (changed || (previous.getHeight() != newGrid.getHeight()) || (previous.getWidth() != newGrid.getWidth()))
00561 {
00562
00563 previous.init(newGrid);
00564 width = newGrid.getWidth();
00565 height = newGrid.getHeight();
00566 adjustCenter();
00567 adjustScrollbars();
00568 }
00569
00570 if (!chrono.IsRunning())
00571 {
00572 chrono.Start(TIMERINTERVAL, false);
00573 }
00574
00575 drawScene();
00576 }
00577
00578
00580
00585 void LayoutCanvas::drawMargins(wxDC &dc)
00586 {
00587 int widgetWidth;
00588 int widgetHeight;
00589 GetClientSize(&widgetWidth, &widgetHeight);
00590 dc.SetPen(*wxTRANSPARENT_PEN);
00591 dc.SetBrush(*wxLIGHT_GREY_BRUSH);
00592
00593 if ((width > 0) && (height > 0))
00594 {
00595 dc.DrawRectangle(0, 0, widgetWidth, scrollY + centerY - cellSize);
00596 dc.DrawRectangle(0, 0, scrollX + centerX - cellSize, widgetHeight);
00597 dc.DrawRectangle(0, scrollY + centerY + height * cellSize + cellSize, widgetWidth, widgetHeight - (scrollY + centerY + height * cellSize + cellSize));
00598 dc.DrawRectangle(scrollX + centerX + width * cellSize + height * (cellSize/2) + cellSize, 0, widgetWidth - scrollX + centerX + width * cellSize + height * (cellSize/2), widgetHeight);
00599 dc.SetPen(*wxBLACK_PEN);
00600 dc.SetBrush(*wxTRANSPARENT_BRUSH);
00601 dc.DrawRectangle(scrollX + centerX - cellSize, scrollY + centerY - cellSize, width * cellSize + height * (cellSize/2) + cellSize*2, height * cellSize + cellSize*2);
00602 }
00603 else
00604 {
00605 dc.DrawRectangle(0, 0, widgetWidth, widgetHeight);
00606 }
00607 }
00608
00609
00611
00620 void LayoutCanvas::setVisible(bool enableds, bool disableds, bool inputs, bool outputs, bool spaces)
00621 {
00622 this->enableds = enableds;
00623 this->disableds = disableds;
00624 this->inputs = inputs;
00625 this->outputs = outputs;
00626 this->spaces = spaces;
00627 drawScene();
00628 }
00629
00630
00632
00640 void LayoutCanvas::setAssignedInputs(vector<coordinate> newInputs)
00641 {
00642 assignedInputs = newInputs;
00643 }
00644
00645
00647
00655 void LayoutCanvas::setAssignedOutputs(vector<coordinate> newOutputs)
00656 {
00657 assignedOutputs = newOutputs;
00658 }
00659
00660
00662
00665 void LayoutCanvas::drawIO(wxDC &dc)
00666 {
00667
00668
00669
00670 int number;
00671
00672 if (inputs)
00673 {
00674 number = 1;
00675
00676 for (unsigned int i = 0; i < assignedInputs.size(); i++)
00677 {
00678 if (assignedInputs[i].x >= 0)
00679 {
00680 drawNumber(assignedInputs[i].x, assignedInputs[i].y, number, dc);
00681 }
00682 number++;
00683 }
00684 }
00685
00686 if (outputs)
00687 {
00688 number = 1;
00689 for (unsigned int i = 0; i < assignedOutputs.size(); i++)
00690 {
00691 if (assignedOutputs[i].x >= 0)
00692 {
00693 drawNumber(assignedOutputs[i].x, assignedOutputs[i].y, number, dc);
00694 }
00695 number++;
00696 }
00697 }
00698 }
00699
00700
00702
00708 void LayoutCanvas::drawNumber(int i, int j, int number, wxDC &dc)
00709 {
00710 coordinate real;
00711 real.x = i;
00712 real.y = j;
00713 coordinate view;
00714 view = realToView(real);
00715 int w, h;
00716 dc.GetTextExtent(wxString::Format(_("%d"), number), &w, &h);
00717 dc.SetBackgroundMode(wxTRANSPARENT);
00718 dc.SetTextForeground(*wxBLACK);
00719 dc.DrawText(wxString::Format(_("%d"), number), view.x - w / 2, view.y - h / 2);
00720 }
00721
00722
00724
00727 void LayoutCanvas::clear(wxDC &dc)
00728 {
00729 dc.Clear();
00730 }
00731
00732
00734 void LayoutCanvas::initTransitions()
00735 {
00736 transitions.resize(layout.getWidth());
00737 for (unsigned int i = 0; i < transitions.size(); i++)
00738 {
00739 transitions[i].resize(layout.getHeight());
00740 for (unsigned int j = 0; j < transitions[i].size(); j++)
00741 {
00742 transitions[i][j] = NUMTRANSITIONS -1;
00743 }
00744 }
00745 }
00746
00747
00749
00754 void LayoutCanvas::OnTimer(wxTimerEvent& event)
00755 {
00756 bool stop = true;
00757
00758 for (unsigned int i = 0; i < transitions.size(); i++)
00759 {
00760 for (unsigned int j = 0; j < transitions[i].size(); j++)
00761 {
00762 if (transitions[i][j] < NUMTRANSITIONS - 1)
00763 {
00764 transitions[i][j] = transitions[i][j] + 1;
00765 stop = false;
00766 }
00767 }
00768 }
00769
00770
00771 if (stop)
00772 {
00773 chrono.Stop();
00774 }
00775
00776 drawScene();
00777 }
00778
00779
00781
00784 void LayoutCanvas::resetTransitions(int value)
00785 {
00786 for (unsigned int i = 0; i < transitions.size(); i++)
00787 {
00788 transitions[i].resize(layout.getHeight());
00789 for (unsigned int j = 0; j < transitions[i].size(); j++)
00790 {
00791 transitions[i][j] = value;
00792 }
00793 }
00794 }
00795
00796
00798
00805 wxColour LayoutCanvas::calculateColour(wxColour initial, wxColour final, int percent)
00806 {
00807 float rIncrease;
00808 float gIncrease;
00809 float bIncrease;
00810 int r = (int)final.Red() - (int)initial.Red();
00811 rIncrease = ((float)r/NUMTRANSITIONS);
00812 r = (int)initial.Red();
00813
00814 int g = (int)final.Green() - (int)initial.Green();
00815 gIncrease = ((float)g/NUMTRANSITIONS);
00816 g = (int)initial.Green();
00817
00818 int b = (int)final.Blue() - (int)initial.Blue();
00819 bIncrease = ((float)b/NUMTRANSITIONS);
00820 b = (int)initial.Blue();
00821 return wxColour((unsigned char)((float)r + (float)percent*rIncrease), (unsigned char)((float)g + (float)percent*gIncrease), (unsigned char)((float)b + (float)percent*bIncrease));
00822 }