OpenASIP 2.2
Loading...
Searching...
No Matches
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"
44#include "OptionValue.hh"
45
46using std::vector;
47using std::map;
48
49const wxColour UnitFigure::DEFAULT_COLOUR = wxColour(0, 0, 0);
50const wxColour UnitFigure::DEFAULT_INFO_TEXT_COLOUR = wxColour(150, 150, 150);
51const wxColour UnitFigure::DEFAULT_BG_COLOUR = wxColour(255, 255, 255);
52
53const int UnitFigure::MARGIN = 5;
54const int UnitFigure::SPACING = 5;
55
56
57/**
58 * The Constructor.
59 */
66
67/**
68 * The Destructor.
69 */
72
73
74/**
75 * Draws the function unit's Figure on the given device context.
76 *
77 * @param dc The device context.
78 */
79void
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 */
195void
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 */
303void
304UnitFigure::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 */
322void
323UnitFigure::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 */
335void
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 */
349void
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}
#define assert(condition)
wxSize minSize_
Figure's minimum size.
Definition Figure.hh:88
MachineCanvasOptions * options()
Definition Figure.cc:199
wxColour highlight_
Highlight colour.
Definition Figure.hh:99
int childCount() const
Figure * child(int index) const
std::vector< Figure * > children_
Figure's children.
Definition Figure.hh:90
virtual wxRect bounds() const
bool laidOut_
Tells whether the Figure and its children have been laid out or not.
Definition Figure.hh:95
wxSize size_
wxSize of the Figure's bounding rectangle.
Definition Figure.hh:86
bool highlighted_
Tells if the figure is highlighted.
Definition Figure.hh:101
wxPoint location_
Top-left location of the Figure's bounding rectangle.
Definition Figure.hh:84
static const int UNIT_HEIGHT
Minimum unit height.
static const int UNIT_WIDTH
Minimum unit width.
static const int PORT_WIDTH
Default Width of a port.
static const int PORT_SPACE
Space between ports.
static const int MAX_UNIT_NAME_WIDTH
Maximun unit name width in pixels.
static const std::string SHOW_UNIT_INFO_STRING
Option name for the unit info string visibility flag.
virtual bool isFlagOn() const
OptionValue & optionValue(const string &name, int index=0)
Definition Options.cc:115
void setName(const wxString &name)
virtual void layout(wxDC *)
static const wxColour DEFAULT_BG_COLOUR
Default background colour for the figure.
Definition UnitFigure.hh:76
static const wxColour DEFAULT_COLOUR
Default colour for the figure.
Definition UnitFigure.hh:74
static const wxColour DEFAULT_INFO_TEXT_COLOUR
Default info string colour for the figure.
Definition UnitFigure.hh:78
wxString type_
Type identifier of the unit.
Definition UnitFigure.hh:67
static const int SPACING
Space between text rows in pixels.
Definition UnitFigure.hh:82
static const int MARGIN
Top and bottom margin in pixels.
Definition UnitFigure.hh:80
virtual void layoutChildren(wxDC *)
void setInfo(const wxString &info)
virtual void drawSelf(wxDC *)
Definition UnitFigure.cc:80
wxString name_
Name of the unit.
Definition UnitFigure.hh:69
virtual ~UnitFigure()
Definition UnitFigure.cc:70
wxString info_
Extra information string describing the unit.
Definition UnitFigure.hh:71
virtual void layoutSelf(wxDC *)
std::string name() const