OpenASIP 2.2
Loading...
Searching...
No Matches
MachineCanvas.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 MachineCanvas.cc
26 *
27 * Definition of MachineCanvas class.
28 *
29 * @author Veli-Pekka Jääskeläinen 2005 (vjaaskel-no.spam-cs.tut.fi)
30 * @note rating: red
31 */
32
33#include <fstream>
34#include <wx/dc.h>
35#include <wx/dcclient.h>
36#include <wx/event.h>
37#include "Segment.hh"
38#include "MachineCanvas.hh"
39#include "MachineCanvasTool.hh"
41#include "RootEditPart.hh"
42#include "Figure.hh"
43#include "SelectionFigure.hh"
44#include "SequenceTools.hh"
45#include "Bus.hh"
46#include "Port.hh"
47#include "MoveFigure.hh"
48#include "EPSDC.hh"
49#include "WxConversion.hh"
50#include "BEMGenerator.hh"
51#include "BinaryEncoding.hh"
52#include "CanvasConstants.hh"
53
54#if wxCHECK_VERSION(3, 0, 0)
55#include <wx/dcsvg.h> // wxSVGFileDC only available in wxwidgets 3.*
56#endif
57
58BEGIN_EVENT_TABLE(MachineCanvas, wxScrolledWindow)
59EVT_MOUSE_EVENTS(MachineCanvas::onMouseEvent)
61
62using namespace TTAMachine;
63
64/**
65 * The Constructor, with a parameter for parent frame.
66 *
67 * @param parent Parent frame of the canvas.
68 * @param policyFactory EditPolicyFactory for creating edit policies.
69 */
70MachineCanvas::MachineCanvas(wxWindow* parent,
71 EditPolicyFactory* policyFactory, ChildFrame* parentFrame) :
72 wxScrolledWindow(parent), tool_(NULL), machine_(NULL),
73 editPolicyFactory_(policyFactory), parent_(parentFrame),
74 zoomFactor_(1.0), dirty_(true), root_(NULL),
75 selection_(NULL), toolBounds_(0, 0, 0, 0) {
76
77 root_ = new RootEditPart();
78
79 SetScrollRate(20, 20);
80 SetVirtualSize(1000, 800);
81}
82
83
84
85/**
86 * The Destructor.
87 */
89 if (root_ != NULL) {
90 delete root_;
91 }
92 clearMoves();
93}
94
95/**
96 * Called when the window needs to be drawn again.
97 *
98 * @param dc The device context where to do the actual drawing.
99 */
100void
102
103 wxBrush backgroundBrush(*wxLIGHT_GREY, wxSOLID);
104 dc.SetBackground(backgroundBrush);
105
106#if wxCHECK_VERSION(3, 0, 0)
107 // Do not call Clear() for wxSVGFileDC object cause its not implemented
108 try {
109 (void)dynamic_cast<wxSVGFileDC&> (dc);
110 } catch (const std::bad_cast& e) {
111 dc.Clear();
112 }
113#else
114 dc.Clear();
115#endif
116
117 // Set the canvas font.
118 dc.SetFont(wxFont(10, wxDEFAULT, wxNORMAL, wxNORMAL));
119
120 // Set scaling factor.
121 dc.SetUserScale(zoomFactor_, zoomFactor_);
122 // draw machine
123 if (root_->contents() != NULL) {
124 if (dirty_) {
125 root_->contents()->figure()->layout(&dc);
126 // Set Canvas virtual size according to the size needed by the
127 // figures.
128 wxRect bounds = root_->contents()->figure()->bounds();
129 SetVirtualSize(int(bounds.GetWidth() * zoomFactor()),
130 int(bounds.GetHeight() * zoomFactor()));
131
132 dirty_ = false;
133 }
134 root_->contents()->figure()->draw(&dc);
135
136 }
137
138 // draw tool figure
139 if (tool() != NULL) {
140 Figure* toolFigure = tool()->figure();
141 if (toolFigure != NULL) {
142 toolFigure->layout(&dc);
143 toolFigure->draw(&dc);
144 }
145 }
146
147 // Draw moves.
148 for (unsigned i = 0; i < moveFigures_.size(); i++) {
149 moveFigures_[i]->draw(&dc);
150 }
151
152 // Draw selection rectangle.
153 if (selection() != NULL) {
154 SelectionFigure figure(selection()->figure());
155 figure.layout(&dc);
156 figure.draw(&dc);
157 }
158}
159
160/**
161 * Refreshes the tool figures on the canvas.
162 */
163void
165
166 if (toolBounds_.GetWidth() > 0 && toolBounds_.GetHeight() > 0) {
167 // Clear previous tool figure.
169 }
170
171 Figure* toolFigure = tool()->figure();
172 if (toolFigure != NULL) {
173 // Draw new tool figure.
174 toolFigure->layout(NULL);
175 toolBounds_ = toolFigure->bounds();
177 } else {
178 toolBounds_ = wxRect(0, 0, 0, 0);
179 }
180}
181
182/**
183 * Sets the zoom factor of the canvas.
184 *
185 * @param factor New zoom factor of the canvas.
186 */
187void
189
190 // Limit the min/max size of the zoom factor
193 } else if (factor < CanvasConstants::MIN_ZOOM_FACTOR) {
195 }
196
197 // when scrolling, try to:
198 // * On X direction, keep the middle pointing to same position in machine
199 // * On Y direction, keep the upper edge of the windows pointer to
200 // same position in the machine.
201 // This code calculates this and does the scrolling.
202 int x, y;
203 int xSize, ySize;
204 int scrollUnitX, scrollUnitY;
205 GetScrollPixelsPerUnit(&scrollUnitX, &scrollUnitY);
206 GetViewStart(&x, &y);
207 x *= scrollUnitX;
208 y *= scrollUnitY;
209 GetSize(&xSize, &ySize);
210 double xPos = (x + (xSize >> 1)) / zoomFactor_;
211 double yPos = y / zoomFactor_;
212 x = std::max(static_cast<int>(xPos * factor) - (xSize >> 1), 0);
213 y = static_cast<int>(yPos * factor);
214 Scroll((x + (scrollUnitX >> 1)) / scrollUnitX,
215 (y + (scrollUnitY >> 1)) / scrollUnitY);
216
217 // then do the zooming
218 zoomFactor_ = factor;
219 dirty_ = true;
220 Refresh();
221}
222
223
224/**
225 * Returns the zoom factor of the canvas.
226 *
227 * @return Zoom factor of the canvas.
228 */
229double
233
234
235/**
236 * Zooms in the canvas by a predefined factor
237 *
238 */
239void
241 double factor = zoomFactor() + CanvasConstants::ZOOM_STEP;
242 setZoomFactor(factor);
243}
244
245
246/**
247 * Zooms out the canvas by a predefined factor
248 *
249 */
250void
252 double factor = zoomFactor() - CanvasConstants::ZOOM_STEP;
253 setZoomFactor(factor);
254}
255
256
257/**
258 * Handles mouse events on the canvas.
259 *
260 * Passes the mouse event to the active tool.
261 *
262 * @param event Mouse event to pass to the active tool.
263 */
264void
265MachineCanvas::onMouseEvent(wxMouseEvent& event) {
266
267 wxClientDC dc(this);
268 PrepareDC(dc);
269 dc.SetUserScale(zoomFactor_, zoomFactor_);
270
271 // Zoomin/out with mousewheel
272 if (event.GetEventType() == wxEVT_MOUSEWHEEL) {
273 double factor;
274
275 if (event.GetWheelRotation() > 0) {
277 } else {
279 }
280 setZoomFactor(factor);
281 }
282
283 if (tool_ != NULL) {
284 tool_->onMouseEvent(event, dc);
285 }
286}
287
288
289/**
290 * Return the original size of the currently loaded Machine Figure
291 *
292 */
293wxSize
295 return root_->contents()->figure()->bounds().GetSize();
296}
297
298
299/**
300 * Sets the active tool.
301 *
302 * @param tool MachineCanvasTool to activate.
303 */
304void
306 if (tool_ != NULL) {
307 tool_->deactivate();
308 delete (tool_);
309 }
310 tool_ = tool;
311 tool_->activate();
312}
313
314/**
315 * Returns pointer to the current tool of the canvas.
316 */
319 return tool_;
320}
321
322/**
323 * Refreshes area of the MachineCanvas bound by a logical coordinate
324 * rectangle.
325 *
326 * @param rectangle Area to refresh.
327 */
328void
329MachineCanvas::refreshLogicalRect(const wxRect& rectangle) {
330
331 int x = 0;
332 int y = 0;
333 CalcScrolledPosition(int(rectangle.x * zoomFactor_),
334 int(rectangle.y * zoomFactor_), &x, &y);
335 wxRect zoomed(x, y, int(rectangle.width * zoomFactor_),
336 int(rectangle.height * zoomFactor_));
337
338 RefreshRect(zoomed);
339}
340
341/**
342 * Updates the machine from the machine object model.
343 */
344void
346
348 clearMoves();
349 dirty_ = true;
350
351 if (machine_ == NULL) {
352 root_->setContents(NULL);
353 return;
354 }
355
357 EditPart* contents = factory.createEditPart(machine_);
358 assert(root_ != NULL);
359 root_->setContents(contents);
360 contents->figure()->setOptions(&options_);
361
362 if (parent_ != nullptr) {
363
364 wxString text(_T(""));
365 BinaryEncoding* bem(nullptr);
366 try {
367 bem = BEMGenerator(*machine_).generate();
368 int width = bem->width();
369 text = wxString::Format(_T("Instruction width: %u"), width);
370 } catch (...) {
371 text = _T("BEM could not be generated");
372 }
373 delete bem;
374 parent_->setStatus(text, 1);
375 }
376
377 Refresh();
378}
379
380/**
381 * Sets the machine which is dispalyed on the canvas.
382 *
383 * @param machine Machine to display on the canvas.
384 */
385void
390
391/**
392 * Clears component selection.
393 */
394void
396 if (selection_ != NULL) {
397 selection_->setSelected(false);
398 }
399 selection_ = NULL;
400 Refresh();
401}
402
403/**
404 * Returns pointer to the EditPart of the selected component.
405 *
406 * @return Pointer to the selected EditPart, or null if selection is empty.
407 */
412
413/**
414 * Finds an edit part at the given coordinates on the canvas.
415 *
416 * @param x X-coordinate of the position to search.
417 * @param y Y-coordinate of the position to search.
418 * @return Pointer to the found edit part, or NULL if no edit part was found.
419 */
422 EditPart* part = NULL;
423 if (root_ != NULL && root_->contents() != NULL) {
424 part = root_->contents()->find(wxPoint(x, y));
425 }
426 return part;
427}
428
429/**
430 * Finds an edit part corresponding the given machine part.
431 *
432 * @param model MachinePart to find
433 * @return Pointer to the found edit part, or NULL if no edit part was found.
434 */
437 EditPart* part = NULL;
438 if (root_ != NULL && root_->contents() != NULL) {
439 part = root_->contents()->find(model);
440 }
441 return part;
442}
443
444/**
445 * Finds EditParts around coordinates that are in given range.
446 *
447 * @param x X-coordinate of the position to search.
448 * @param y Y-coordinate of the position to search.
449 * @param range Search range from position (x, y).
450 * @param found Found EditParts after call.
451 * @return Number of found EditParts. Zero if found nothing.
452 */
453int
455 std::vector<EditPart*>& found) {
456 if (root_ != NULL && root_->contents() != NULL) {
457 return root_->contents()->findInRange(wxPoint(x, y),
458 static_cast<float>(range), found);
459 }
460 return 0;
461}
462
463/**
464 * Looks for given EditPart recursively.
465 *
466 * @param part Part to look up.
467 * @return True if canvas has given EditPart.
468 */
469bool
471 if (root_ != NULL && root_->contents() != NULL) {
472 return root_->contents()->hasEditPartRecursive(part);
473 }
474 return false;
475}
476
477/**
478 * Marks an edit part selected.
479 *
480 * Previous selection is cleared.
481 *
482 * @param part Edit part to select.
483 */
484void
486 if (selection_ != NULL) {
487 selection_->setSelected(false);
488 }
489
490 // segments are not supported so we should select the parent
491 // bus instead the segment (a very long standing irritating bug)
492 TTAMachine::Segment* segment =
493 dynamic_cast<TTAMachine::Segment*>(part->model());
494 if (segment != NULL) {
495 // clicked segment, selecting parent bus instead
496 part = part->parent();
497 }
498
499 selection_ = part;
500 if (selection_ != NULL) {
501 selection_->setSelected(true);
502 }
503 Refresh();
504}
505
506/**
507 * Highlights figure of a machine component.
508 */
509void
511 const wxColour& colour) {
512
513 if (root_->contents() == NULL) {
514 return;
515 }
516
517 EditPart* editPart = root_->contents()->find(component);
518 if (editPart != NULL && editPart->figure() != NULL) {
519 editPart->figure()->highlight(colour);
520 }
521}
522
523/**
524 * Clears highlighting of all machine components.
525 */
526void
528 if (root_ != NULL && root_->contents() != NULL) {
530 }
531}
532
533/**
534 * Adds a move to be drawn on the canvas.
535 *
536 * @param bus Transport bus of the move.
537 * @param source Source port of the move.
538 * @param target Target port of the move.
539 */
540void
541MachineCanvas::addMove(const Bus* bus, const Port* source, const Port* target) {
542 std::string procName = "MachineCanvas::addMove";
543 EditPart* busEditPart = findEditPart(bus);
544
545 if (busEditPart == NULL) {
546 throw InstanceNotFound(__FILE__, __LINE__, procName);
547 }
548
549 Figure* busFigure = busEditPart->figure();
550 Figure* sourceFigure = NULL;
551 Figure* targetFigure = NULL;
552
553 if (source != NULL) {
554 EditPart* sourceEditPart = findEditPart(source);
555 if (sourceEditPart == NULL) {
556 throw InstanceNotFound(__FILE__, __LINE__, procName);
557 }
558 sourceFigure = sourceEditPart->figure();
559 }
560
561 if (target != NULL) {
562 EditPart* targetEditPart = findEditPart(target);
563 if (targetEditPart == NULL) {
564 throw InstanceNotFound(__FILE__, __LINE__, procName);
565 }
566 targetFigure = targetEditPart->figure();
567 }
568
569 moveFigures_.push_back(
570 new MoveFigure(busFigure, sourceFigure, targetFigure));
571}
572
573/**
574 * Clears list of moves to be drawn on the canvas.
575 */
576void
580
581#if wxCHECK_VERSION(3, 0, 0)
582/**
583 * Saves the machine figure to a .svg file.
584 *
585 * @param filename Name of the .svg file.
586 * @return True, if the svg was succesfully saved.
587 */
588bool
589MachineCanvas::saveSVG(const std::string& filename) {
590 // Refresh machine figure to get the canvas size.
591 wxClientDC clientDC(this);
592 OnDraw(clientDC);
593
594 // Add minimum coordinates to maximum coordinates to create margins
595 // of equal width.
596 int width = clientDC.MaxX() + clientDC.MinX();
597 int height = clientDC.MaxY() + clientDC.MinY();
598
599 wxSVGFileDC svg(filename, width, height);
600 svg.StartPage();
601 OnDraw(svg);
602 svg.EndPage();
603
604 return true;
605}
606
607#else
608/**
609 * Saves the machine figure to an eps file.
610 *
611 * @param filename Name of the eps file.
612 * @param title Title of the eps document.
613 * @param creator Creator of the eps document.
614 * @return True, if the eps was succesfully saved.
615 */
616bool
617MachineCanvas::saveEPS(const std::string& filename, const std::string& title,
618 const std::string& creator) {
619
620 EPSDC dc;
621 dc.setCreator(creator);
622
623 dc.setTitle(title);
624 dc.StartPage();
625 OnDraw(dc);
626 dc.EndPage();
627
628 std::ofstream file(filename.c_str());
629
630 if (file.bad()) {
631 return false;
632 }
633
634 dc.writeToStream(file);
635 file.close();
636
637 return true;
638}
639#endif
640
641/**
642 * Saves the machine figure to a .png file.
643 *
644 * @param filename Name of the .png file.
645 * @return True, if the png was succesfully saved.
646 */
647bool
648MachineCanvas::savePNG(const std::string& filename) {
649
650 // Refresh machine figure to get the canvas size.
651 wxClientDC clientDC(this);
652 OnDraw(clientDC);
653
654 // Add minimum coordinates to maximum coordinates to create margins
655 // of equal width.
656 int width = clientDC.MaxX() + clientDC.MinX();
657 int height = clientDC.MaxY() + clientDC.MinY();
658
659 // Create bitmap and a MemoryDC which writes the bitmap.
660 wxMemoryDC bitmapDC;
661 wxBitmap bitmap(width, height);
662 bitmapDC.SelectObject(bitmap);
663 OnDraw(bitmapDC);
664
665 wxString file = WxConversion::toWxString(filename);
666
667 // Save bitmap.
668 if (bitmap.SaveFile(file, wxBITMAP_TYPE_PNG)) {
669 return true;
670 }
671
672 return false;
673}
674
675/**
676 * Returns the current options used by machine canvas figures.
677 *
678 * @return Current machine canvas options.
679 */
682 return options_;
683}
#define assert(condition)
END_EVENT_TABLE() using namespace IDF
TTAMachine::Machine * machine
the architecture definition of the estimated processor
BinaryEncoding * generate()
virtual int width(const TCEString &templateName) const
static const double MAX_ZOOM_FACTOR
Maximum zoom factor.
static const double ZOOM_STEP
Step between zoom levels.
static const double MIN_ZOOM_FACTOR
Minimum zoom factor.
void setStatus(const wxString text, int field=0)
Definition ChildFrame.cc:76
Definition EPSDC.hh:48
void writeToStream(std::ostream &stream)
Definition EPSDC.cc:209
virtual void EndPage()
Definition EPSDC.cc:568
virtual void StartPage()
Definition EPSDC.cc:560
void setCreator(const std::string &creator)
Definition EPSDC.cc:199
void setTitle(const std::string &title)
Definition EPSDC.cc:189
int findInRange(wxPoint point, float radius, std::vector< EditPart * > &found)
Definition EditPart.cc:219
bool hasEditPartRecursive(const EditPart *part) const
Definition EditPart.cc:274
Figure * figure() const
void setSelected(bool select)
EditPart * parent() const
EditPart * find(wxPoint point)
Definition EditPart.cc:102
TTAMachine::MachinePart * model() const
void setOptions(MachineCanvasOptions *options)
Definition Figure.cc:212
void highlight(const wxColour &colour)
Definition Figure.cc:182
virtual wxRect bounds() const
virtual void layout(wxDC *dc)
Definition Figure.cc:109
void clearHighlight()
Definition Figure.cc:165
virtual void draw(wxDC *dc)
Definition Figure.cc:138
virtual Figure * figure()
virtual void onMouseEvent(wxMouseEvent &event, wxDC &dc)=0
virtual void activate()=0
virtual void deactivate()=0
bool savePNG(const std::string &filename)
EditPolicyFactory * editPolicyFactory_
EditPolicyFactory which creates edit policies for machine components.
void onMouseEvent(wxMouseEvent &event)
virtual ~MachineCanvas()
RootEditPart * root_
Root of the machine EditPart hierarchy.
void highlight(TTAMachine::MachinePart *model, const wxColour &colour)
EditPart * selection()
wxSize getFigureSize() const
int findEditPartsInRange(int x, int y, int range, std::vector< EditPart * > &found)
TTAMachine::Machine * machine_
Machine to draw on the canvas.
std::vector< Figure * > moveFigures_
Move figures to be drawn on the canvas.
double zoomFactor_
Zoom factor of the canvas.
void setTool(MachineCanvasTool *tool)
MachineCanvasTool * tool()
void select(EditPart *part)
MachineCanvasTool * tool_
Tool which handles mouse events on the MachineCanvas.
void addMove(const TTAMachine::Bus *bus, const TTAMachine::Port *source, const TTAMachine::Port *target)
bool hasEditPart(const EditPart *part) const
bool saveEPS(const std::string &filename, const std::string &title, const std::string &creator="")
wxRect toolBounds_
Bounding box of the last tool figure drawn.
EditPart * findEditPart(int x, int y)
virtual void OnDraw(wxDC &dc)
void refreshToolFigure()
void refreshLogicalRect(const wxRect &rectangle)
EditPart * selection_
Pointer to the the selected component.
ChildFrame * parent_
Parent frame which holds the MachineCanvas.
bool dirty_
Tells if the figures need to be laid out before next draw.
double zoomFactor()
MachineCanvasOptions options_
MachineCanvasOptions & options()
void setMachine(TTAMachine::Machine *machine)
void setZoomFactor(double factor)
virtual EditPart * createEditPart(TTAMachine::MachinePart *component)
void setContents(EditPart *contents)
EditPart * contents() const
static void deleteAllItems(SequenceType &aSequence)
static wxString toWxString(const std::string &source)