OpenASIP  2.0
UnitFigure.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2009 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file UnitFigure.cc
26  *
27  * Definition of UnitFigure class.
28  *
29  * @author Ari Metsähalme 2003 (ari.metsahalme-no.spam-tut.fi)
30  * @note rating: yellow
31  * @note reviewed Jul 22 2004 by tr, ml, jm, am
32  */
33 
34 #include <vector>
35 #include <map>
36 
37 #include "Application.hh"
38 #include "UnitFigure.hh"
40 #include "InputSocketFigure.hh"
41 #include "OutputSocketFigure.hh"
42 #include "TriggeringPortFigure.hh"
43 #include "MachineCanvasOptions.hh"
44 #include "OptionValue.hh"
45 
46 using std::vector;
47 using std::map;
48 
49 const wxColour UnitFigure::DEFAULT_COLOUR = wxColour(0, 0, 0);
50 const wxColour UnitFigure::DEFAULT_INFO_TEXT_COLOUR = wxColour(150, 150, 150);
51 const wxColour UnitFigure::DEFAULT_BG_COLOUR = wxColour(255, 255, 255);
52 
53 const int UnitFigure::MARGIN = 5;
54 const int UnitFigure::SPACING = 5;
55 
56 
57 /**
58  * The Constructor.
59  */
61  minSize_ = wxSize(
64  size_ = minSize_;
65 }
66 
67 /**
68  * The Destructor.
69  */
71 }
72 
73 
74 /**
75  * Draws the function unit's Figure on the given device context.
76  *
77  * @param dc The device context.
78  */
79 void
81 
82  wxPen pen = wxPen(DEFAULT_COLOUR, 1, wxSOLID);
83  dc->SetPen(pen);
84  wxBrush brush = wxBrush(DEFAULT_BG_COLOUR, wxSOLID);
85  if (highlighted_) {
86  brush = wxBrush(highlight_, wxSOLID);
87  }
88  dc->SetBrush(brush);
89 
90  const bool drawInfoRow =
91  (options() != NULL &&
94 
95  if (type_ == _T("FU:")) {
96  if (!highlighted_) {
97  if (info_.StartsWith(_T("{ AS:"))) {
98  dc->SetBrush(wxBrush(wxColour(170,255,170),wxSOLID));
99  } else {
100  dc->SetBrush(wxBrush(wxColour(205,205,255),wxSOLID));
101  }
102  } else {
103  if (info_.StartsWith(_T("{ AS:"))) {
104  dc->SetBrush(wxBrush(wxColour((53+highlight_.Red()*2)/3,
105  (82+highlight_.Green()*2)/3,
106  (53+highlight_.Blue()*2)/3),
107  wxSOLID));
108  } else {
109  dc->SetBrush(wxBrush(wxColour((68+highlight_.Red()*2)/3,
110  (68+highlight_.Green()*2)/3,
111  (82+highlight_.Blue()*2)/3),
112  wxSOLID));
113  }
114  }
115  dc->DrawRoundedRectangle(
116  location_.x, location_.y, size_.GetWidth(),
117  size_.GetHeight(), size_.GetHeight()*0.25);
118  } else if (type_ == _T("GCU:")) {
119  dc->SetBrush(wxBrush(wxColour(250,145,255), wxSOLID));
120  dc->DrawRoundedRectangle(
121  location_.x, location_.y, size_.GetWidth(),
122  size_.GetHeight(), size_.GetHeight()*0.4);
123  } else if (type_ == _T("IMM:")) {
124  dc->SetBrush(wxBrush(wxColour(255,168,140),wxSOLID));
125  wxPoint points[4];
126  points[0] = wxPoint(size_.GetWidth()/2-10, size_.GetHeight());
127  points[1] = wxPoint(size_.GetWidth()/2+10, size_.GetHeight());
128  points[2] = wxPoint(size_.GetWidth(),0);
129  points[3] = wxPoint(0,0);
130  dc->DrawPolygon(
131  4, points,
132  location_.x, location_.y,
133  wxODDEVEN_RULE);
134  } else { // register file
135  dc->SetBrush(wxBrush(wxColour(240,230,150),wxSOLID));
136  dc->DrawRectangle(
137  location_.x, location_.y, size_.GetWidth(),
138  size_.GetHeight());
139  }
140 
141  dc->SetBackgroundMode(wxTRANSPARENT);
142  dc->SetTextForeground(DEFAULT_COLOUR);
143 
144  int typeWidth = 0;
145  int typeHeight = 0;
146  if (drawInfoRow) {
147  dc->GetTextExtent(type_, &typeWidth, &typeHeight);
148 
149  int typeX = location_.x + size_.GetWidth() / 2 - typeWidth / 2;
150  int typeY = location_.y + MARGIN;
151 
152  dc->DrawText(type_, typeX, typeY);
153  }
154 
155  int nameWidth;
156  int nameHeight;
157 
158  wxFont oldFont = dc->GetFont();
159  if (!drawInfoRow) {
160  // In case we do not write the details (operation set) to the unit,
161  // print the name of the unit larger.
162  dc->SetFont(wxFont(16, wxDEFAULT, wxNORMAL, wxNORMAL));
163  }
164  dc->GetTextExtent(name_, &nameWidth, &nameHeight);
165 
166  int nameX = location_.x + size_.GetWidth() / 2 - nameWidth / 2;
167  int nameY = location_.y + MARGIN + typeHeight + SPACING;
168  dc->DrawText(name_, nameX, nameY);
169 
170  if (!drawInfoRow) {
171  dc->SetFont(oldFont);
172  }
173 
174  if (drawInfoRow) {
175 
176  int infoWidth;
177  int infoHeight;
178 
179  dc->GetTextExtent(info_, &infoWidth, &infoHeight);
180 
181  int infoX = location_.x + size_.GetWidth() / 2 - infoWidth / 2;
182  int infoY =
183  location_.y + MARGIN + typeHeight + SPACING + nameHeight + SPACING;
184 
185  dc->SetTextForeground(DEFAULT_INFO_TEXT_COLOUR);
186  dc->DrawText(info_, infoX, infoY);
187  }
188 }
189 
190 /**
191  * Lays out the ports to the bottom of the fu's Figure, spaced evenly.
192  *
193  * @param dc Device context.
194  */
195 void
197 
198  // Sort port child figures to containers based on port directions.
199  // Map with portname, figure pairs is used so that the ports
200  // are automatically ordered by the port name.
201  map<std::string, Figure*> inputPorts;
202  map<std::string, Figure*> outputPorts;
203  map<std::string, Figure*> bidirPorts;
204  map<std::string, Figure*> trigPorts;
205  map<std::string, Figure*> nodirPorts;
206 
207  vector<Figure*>::iterator i = children_.begin();
208  for(; i != children_.end(); i++) {
209  UnitPortFigure* fig = dynamic_cast<UnitPortFigure*>(*i);
210  assert(fig != NULL);
211  bool input = false;
212  bool output = false;
213  for (int j = 0; j < (fig->childCount()); j++) {
214  Figure* socketFig = fig->child(j);
215  if (dynamic_cast<InputSocketFigure*>(socketFig) != NULL) {
216  input = true;
217  } else if (dynamic_cast<OutputSocketFigure*>(socketFig) != NULL) {
218  output = true;
219  }
220  }
221  if (input && dynamic_cast<TriggeringPortFigure*>(fig) != NULL) {
222  trigPorts[fig->name()] = fig;
223  } else if (input && output) {
224  bidirPorts[fig->name()] = fig;
225  } else if (input) {
226  inputPorts[fig->name()] = fig;
227  } else if (output) {
228  outputPorts[fig->name()] = fig;
229  } else {
230  nodirPorts[fig->name()] = fig;
231  }
232  }
233 
235  int portY = location_.y + size_.GetHeight();
236 
237  // if only single port, put it to middle.
238  if (children_.size() == 1) {
239  portX = location_.x + (size_.GetWidth()- children_[0]->bounds().GetWidth()) / 2;
240  }
241 
242  // Layout input ports.
243  map<std::string, Figure*>::iterator inIter = inputPorts.begin();
244  for (; inIter != inputPorts.end(); inIter++) {
245  portY -= (*inIter).second->bounds().GetHeight()/2;
246  (*inIter).second->setLocation(wxPoint(portX, portY));
247  (*inIter).second->layout(dc);
248  portY = location_.y + size_.GetHeight();
249  portX += (*inIter).second->bounds().GetWidth() +
251  }
252 
253  // Layout triggering ports.
254  map<std::string, Figure*>::iterator trigIter = trigPorts.begin();
255  for (; trigIter != trigPorts.end(); trigIter++) {
256  portY -= (*trigIter).second->bounds().GetHeight()/2;
257  (*trigIter).second->setLocation(wxPoint(portX, portY));
258  (*trigIter).second->layout(dc);
259  portY = location_.y + size_.GetHeight();
260  portX += (*trigIter).second->bounds().GetWidth() +
262  }
263 
264  // Layout bidirectional ports.
265  map<std::string, Figure*>::iterator bdIter = bidirPorts.begin();
266  for (; bdIter != bidirPorts.end(); bdIter++) {
267  portY -= (*bdIter).second->bounds().GetHeight()/2;
268  (*bdIter).second->setLocation(wxPoint(portX, portY));
269  (*bdIter).second->layout(dc);
270  portY = location_.y + size_.GetHeight();
271  portX += (*bdIter).second->bounds().GetWidth() +
273  }
274 
275  // Layout output ports.
276  map<std::string, Figure*>::iterator outIter = outputPorts.begin();
277  for (; outIter != outputPorts.end(); outIter++) {
278  portY -= (*outIter).second->bounds().GetHeight()/2;
279  (*outIter).second->setLocation(wxPoint(portX, portY));
280  (*outIter).second->layout(dc);
281  portY = location_.y + size_.GetHeight();
282  portX += (*outIter).second->bounds().GetWidth() +
284  }
285 
286  // Layout ports w/ no direction.
287  map<std::string, Figure*>::iterator ndIter = nodirPorts.begin();
288  for (; ndIter != nodirPorts.end(); ndIter++) {
289  portY -= (*ndIter).second->bounds().GetHeight()/2;
290  (*ndIter).second->setLocation(wxPoint(portX, portY));
291  (*ndIter).second->layout(dc);
292  portY = location_.y + size_.GetHeight();
293  portX += (*ndIter).second->bounds().GetWidth() +
295  }
296 }
297 
298 /**
299  * Sets the name of the unit.
300  *
301  * @param name New name.
302  */
303 void
304 UnitFigure::setName(const wxString& name) {
305  int index = name.Find(':');
306  if (index == -1) {
307  type_ = _T("Unit:");
308  name_ = name;
309  } else {
310  type_ = name.Mid(0, index + 1);
311  type_.Trim();
312  name_ = name.Mid(index + 2);
313  name_.Trim();
314  }
315 }
316 
317 /**
318  * Sets the information string of the unit.
319  *
320  * @param info New info string..
321  */
322 void
323 UnitFigure::setInfo(const wxString& info) {
324  info_ = info;
325 }
326 
327 /**
328  * Lays the figure out.
329  *
330  * Figure of the unit is laid out before it's children, so that the port
331  * Y-coordinate can be set correctly when laying out the ports.
332  *
333  * @param dc Device cotnext to lay the figure out on.
334  */
335 void
337  layoutSelf(dc);
338  layoutChildren(dc);
339  laidOut_ = true;
340 }
341 
342 /**
343  * Calculates and sets the size of the unit.
344  *
345  * Depends on its name and the amount of ports.
346  *
347  * @param dc Device context.
348  */
349 void
351 
352  bool showInfo = (options() != NULL) && options()->optionValue(
354 
355  int portsWidth = 0;
356 
357  vector<Figure*>::const_iterator i = children_.begin();
358  for (; i != children_.end(); i++) {
359  portsWidth += (*i)->bounds().GetWidth();
360  }
361 
362  portsWidth +=
364 
365  int nameWidth = 0;
366  int nameHeight = 0;
367  int infoWidth = 0;
368  int infoHeight = 0;
369  int typeWidth = 0;
370  int typeHeight = 0;
371 
372  dc->GetTextExtent(name_, &nameWidth, &nameHeight);
373  dc->GetTextExtent(type_, &typeWidth, &typeHeight);
374  if (showInfo) {
375  dc->GetTextExtent(info_, &infoWidth, &infoHeight);
376  }
377  nameWidth += MARGIN * 4;
378  typeWidth += MARGIN * 4;
379  infoWidth += MARGIN * 4;
380 
382 
383  if (portsWidth > maxWidth) {
384  maxWidth = portsWidth;
385  }
386 
387  if ((nameWidth + 2 * MARGIN) > maxWidth) {
388 
389  unsigned int chars = 0;
390  int charsExtent = 0;
391 
392  while ((charsExtent + 2 * MARGIN) < maxWidth) {
393  int charWidth = 0;
394  int charHeight = 0;
395  dc->GetTextExtent(name_.GetChar(chars), &charWidth, &charHeight);
396  charsExtent += charWidth;
397  chars++;
398  if (chars > name_.Len()) {
399  break;
400  }
401  }
402 
403  name_.Truncate(chars - 5);
404  name_.Append(_T("..."));
405  dc->GetTextExtent(name_, &nameWidth, &nameHeight);
406  nameWidth += 4 * MARGIN;
407  }
408 
409  if (showInfo && (infoWidth + 2 * MARGIN) > maxWidth) {
410 
411  unsigned int chars = 0;
412  int charsExtent = 0;
413 
414  while ((charsExtent + 2 * MARGIN) < maxWidth) {
415  int charWidth = 0;
416  int charHeight = 0;
417  dc->GetTextExtent(info_.GetChar(chars), &charWidth, &charHeight);
418  charsExtent += charWidth;
419  chars++;
420  if (chars > info_.Len()) {
421  break;
422  }
423  }
424 
425  info_.Truncate(chars - 5);
426  info_.Append(_T("..."));
427  dc->GetTextExtent(info_, &infoWidth, &infoHeight);
428  infoWidth += 4 * MARGIN;
429  }
430 
431  if (infoWidth > size_.GetWidth() &&
432  infoWidth >= nameWidth && infoWidth > portsWidth) {
433 
434  size_.SetWidth(infoWidth);
435 
436  } else if (nameWidth > size_.GetWidth() &&
437  nameWidth > infoWidth && nameWidth > portsWidth) {
438 
439  size_.SetWidth(nameWidth);
440 
441  } else if (portsWidth > size_.GetWidth()) {
442  size_.SetWidth(portsWidth);
443  }
444 
445  // Set figure height.
446  int height = 2 * MARGIN + SPACING + nameHeight +
448 
449  if (showInfo) {
450  height += typeHeight + SPACING + infoHeight;
451  }
452  if (height > minSize_.GetHeight()) {
453  size_.SetHeight(height);
454  }
455 }
UnitFigure::name_
wxString name_
Name of the unit.
Definition: UnitFigure.hh:69
InputSocketFigure.hh
MachineCanvasLayoutConstraints::UNIT_WIDTH
static const int UNIT_WIDTH
Minimum unit width.
Definition: MachineCanvasLayoutConstraints.hh:43
MachineCanvasLayoutConstraints::UNIT_HEIGHT
static const int UNIT_HEIGHT
Minimum unit height.
Definition: MachineCanvasLayoutConstraints.hh:45
UnitPortFigure::name
std::string name() const
Definition: UnitPortFigure.cc:112
UnitFigure::layoutSelf
virtual void layoutSelf(wxDC *)
Definition: UnitFigure.cc:350
Figure::laidOut_
bool laidOut_
Tells whether the Figure and its children have been laid out or not.
Definition: Figure.hh:95
Options::optionValue
OptionValue & optionValue(const string &name, int index=0)
Definition: Options.cc:115
MachineCanvasOptions.hh
UnitFigure::layoutChildren
virtual void layoutChildren(wxDC *)
Definition: UnitFigure.cc:196
UnitPortFigure
Definition: UnitPortFigure.hh:46
Figure::children_
std::vector< Figure * > children_
Figure's children.
Definition: Figure.hh:90
UnitFigure::type_
wxString type_
Type identifier of the unit.
Definition: UnitFigure.hh:67
Figure::highlight_
wxColour highlight_
Highlight colour.
Definition: Figure.hh:99
OutputSocketFigure
Definition: OutputSocketFigure.hh:46
assert
#define assert(condition)
Definition: Application.hh:86
UnitFigure::DEFAULT_COLOUR
static const wxColour DEFAULT_COLOUR
Default colour for the figure.
Definition: UnitFigure.hh:74
Figure::size_
wxSize size_
wxSize of the Figure's bounding rectangle.
Definition: Figure.hh:86
MachineCanvasOptions::SHOW_UNIT_INFO_STRING
static const std::string SHOW_UNIT_INFO_STRING
Option name for the unit info string visibility flag.
Definition: MachineCanvasOptions.hh:48
MachineCanvasLayoutConstraints::MAX_UNIT_NAME_WIDTH
static const int MAX_UNIT_NAME_WIDTH
Maximun unit name width in pixels.
Definition: MachineCanvasLayoutConstraints.hh:49
OptionValue::isFlagOn
virtual bool isFlagOn() const
Definition: OptionValue.cc:166
OutputSocketFigure.hh
Figure::child
Figure * child(int index) const
Figure
Definition: Figure.hh:50
Application.hh
Figure::location_
wxPoint location_
Top-left location of the Figure's bounding rectangle.
Definition: Figure.hh:84
UnitFigure::UnitFigure
UnitFigure()
Definition: UnitFigure.cc:60
UnitFigure::setInfo
void setInfo(const wxString &info)
Definition: UnitFigure.cc:323
UnitFigure::layout
virtual void layout(wxDC *)
Definition: UnitFigure.cc:336
UnitFigure::setName
void setName(const wxString &name)
Definition: UnitFigure.cc:304
MachineCanvasLayoutConstraints::PORT_WIDTH
static const int PORT_WIDTH
Default Width of a port.
Definition: MachineCanvasLayoutConstraints.hh:51
TriggeringPortFigure.hh
UnitFigure::MARGIN
static const int MARGIN
Top and bottom margin in pixels.
Definition: UnitFigure.hh:80
InputSocketFigure
Definition: InputSocketFigure.hh:46
UnitFigure.hh
UnitFigure::DEFAULT_BG_COLOUR
static const wxColour DEFAULT_BG_COLOUR
Default background colour for the figure.
Definition: UnitFigure.hh:76
Figure::highlighted_
bool highlighted_
Tells if the figure is highlighted.
Definition: Figure.hh:101
Figure::minSize_
wxSize minSize_
Figure's minimum size.
Definition: Figure.hh:88
Figure::childCount
int childCount() const
UnitFigure::~UnitFigure
virtual ~UnitFigure()
Definition: UnitFigure.cc:70
UnitFigure::drawSelf
virtual void drawSelf(wxDC *)
Definition: UnitFigure.cc:80
MachineCanvasLayoutConstraints.hh
TriggeringPortFigure
Definition: TriggeringPortFigure.hh:45
Figure::options
MachineCanvasOptions * options()
Definition: Figure.cc:199
UnitFigure::info_
wxString info_
Extra information string describing the unit.
Definition: UnitFigure.hh:71
UnitFigure::DEFAULT_INFO_TEXT_COLOUR
static const wxColour DEFAULT_INFO_TEXT_COLOUR
Default info string colour for the figure.
Definition: UnitFigure.hh:78
UnitFigure::SPACING
static const int SPACING
Space between text rows in pixels.
Definition: UnitFigure.hh:82
MachineCanvasLayoutConstraints::PORT_SPACE
static const int PORT_SPACE
Space between ports.
Definition: MachineCanvasLayoutConstraints.hh:57
OptionValue.hh