Minsky: 3.17.0
canvas.h
Go to the documentation of this file.
1 /*
2  @copyright Steve Keen 2017
3  @author Russell Standish
4  This file is part of Minsky.
5 
6  Minsky is free software: you can redistribute it and/or modify it
7  under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Minsky is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Minsky. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #ifndef CANVAS_H
21 #define CANVAS_H
22 
23 #include "group.h"
24 #include "godleyIcon.h"
25 #include "operation.h"
26 #include "plotOptions.h"
27 #include "plotWidget.h"
28 #include "selection.h"
29 #include "switchIcon.h"
30 #include "wire.h"
31 #include "ravelWrap.h"
32 #include "lasso.h"
33 #include "lock.h"
34 #include "sheet.h"
35 #include "renderNativeWindow.h"
36 
37 #include <chrono>
38 
39 namespace minsky
40 {
41  using namespace classdesc;
42  template <class T>
43  struct NoAssign: public T
44  {
45  // disable assignment for objects wrapped in this class, but allow
46  // assignment otherwise
47  NoAssign& operator=(const NoAssign&) {return *this;}
48  template <class U>
49  NoAssign& operator=(const U& x) {T::operator=(x); return *this;}
50  };
51 
52  class Canvas: public RenderNativeWindow
53  {
55  void copyVars(const std::vector<VariablePtr>&);
56  void reportDrawTime(double) override;
57  void mouseDownCommon(float x, float y);
58  bool redraw(int x0, int y0, int width, int height) override;
59  void mouseMoveOnItem(float x, float y);
60 
62  bool m_redrawRequested=false;
63 
66 
67  public:
68  typedef std::chrono::time_point<std::chrono::high_resolution_clock> Timestamp;
69  struct Model: public GroupPtr
70  {
71  Exclude<Timestamp> timestamp{Timestamp::clock::now()};
72  void updateTimestamp() {timestamp=Timestamp::clock::now();}
73  GroupPtr parent; // stash a ref to this groups parent for later restore
74  float px=0,py=0,pz=1;
75  Model() {}
76  Model(const GroupPtr& g) {operator=(g);}
77  Model& operator=(const GroupPtr& model) {
78  updateTimestamp();
79  if (this->get())
80  {
81  // restore previous stuff
82  (*this)->group=parent;
83  (*this)->m_x=px;
84  (*this)->m_y=py;
85  (*this)->relZoom=pz;
86  }
87  parent=model->group.lock();
88  model->group.reset();
89  px=model->m_x;
90  py=model->m_y;
91  pz=model->relZoom;
92  model->group.reset(); // disassociate model from it's parent
93  GroupPtr::operator=(model);
94  return *this;
95  }
96  void zoom(double x, double y, double z) {
97  if (fabs(x-(*this)->x())>1e-5 || fabs(y-(*this)->y())>1e-5)
98  updateTimestamp(); // Why is this needed??
99  (*this)->zoom(x,y,z);
100  }
101  };
102 
104 
109  Exclude<shared_ptr<Port>> fromPort;
110  double termX,termY;
111  float moveOffsX, moveOffsY;
112  bool rotatingItem=false;
113  Exclude<Point> rotateOrigin;
114  void rotateItem(float x, float y) {
115  rotateOrigin=Point(x,y);
116  rotatingItem=true;
117  }
121 
123  struct LassoMode {enum type {none, lasso, itemResize};};
124  LassoMode::type lassoMode=LassoMode::none;
125  LassoBox lasso{0,0,0,0};
126 
127  bool redrawAll=true;
128 
129  void moveTo(float x, float y) override {
130  model->moveTo(x,y);
131  requestRedraw();
132  }
133 
134  std::vector<float> position() const override {
135  return {model->x(), model->y()};
136  }
137 
138  void zoom(double x, double y, double z) override {
139  model->zoom(x,y,z);
140  requestRedraw();
141  }
142 
143  double zoomFactor() const override {return model->zoomFactor();}
144 
145  Canvas() {}
146  Canvas(const GroupPtr& m): model(m) {}
147 
148  ecolab::cairo::SurfacePtr& surface() {return ecolab::CairoSurface::surface;}
149 
151  void mouseDown(float x, float y) override;
152  void controlMouseDown(float x, float y) override;
153  void mouseUp(float x, float y) override;
154  void mouseMove(float x, float y) override;
155  bool keyPress(const EventInterface::KeyPressArgs&) override;
156  void displayDelayedTooltip(float x, float y);
157 
159  std::shared_ptr<Port> closestInPort(float x, float y) const;
160 
162  void select(const LassoBox&);
163 
164  int ravelsSelected() const;
165 
167  void setItemFocus(const ItemPtr& x) {
168  itemFocus=x;
169  moveOffsX=moveOffsY=0;
170  clickType=ClickType::onItem;
171  }
172 
173 
177  ItemPtr itemAt(float x, float y);
178  bool getItemAt(float x, float y) override {return (item=itemAt(x,y)).get();}
179  bool getWireAt(float x, float y) override;
180 
181  double defaultRotation=0;
183  if (op==OperationType::numOps) return;
184  setItemFocus(model->addItem(OperationBase::create(op)));
185  itemFocus->rotation(defaultRotation);
186  }
187  void addVariable(const std::string& name, VariableType::Type type) {
188  if (type==VariableType::undefined || type==VariableType::numVarTypes) return;
189  setItemFocus(model->addItem(VariablePtr(type,name)));
190  itemFocus->rotation(defaultRotation);
191  }
192  void addNote(const std::string& text) {
193  setItemFocus(model->addItem(new Item));
194  itemFocus->detailedText(text);
195  }
196  void addPlot() {
197  setItemFocus(model->addItem(new PlotWidget));
198  defaultPlotOptions.applyPlotOptions(*itemFocus->plotWidgetCast());
199  }
200  void addGodley() {setItemFocus(model->addItem(new GodleyIcon));}
201  void addGroup() {setItemFocus(model->addItem(new Group));}
202  void addSwitch() {setItemFocus(model->addItem(new SwitchIcon));}
203  void addRavel() {setItemFocus(model->addItem(new Ravel));}
204  void addLock() {setItemFocus(model->addItem(new Lock));}
205  void addSheet() {setItemFocus(model->addItem(new Sheet));}
206 
208  void groupSelection();
212  void lockRavelsInSelection();
213  void unlockRavelsInSelection();
214 
216  void deleteItem();
218  void deleteWire();
220  void delHandle(float x, float y);
222  void removeItemFromItsGroup();
223 
225  void selectAllVariables();
227  void renameAllInstances(const std::string& newName);
229  void renameItem(const std::string& newName);
230 
232  void ungroupItem();
233 
235  void copyItem();
236 
238  void zoomToFit();
239 
241  void openGroupInCanvas(const ItemPtr& item);
242 
245  if (auto g=dynamic_cast<GodleyIcon*>(item.get()))
246  copyVars(g->flowVars());
247  }
250  if (auto g=dynamic_cast<GodleyIcon*>(item.get()))
251  copyVars(g->stockVars());
252  }
253 
255  void zoomToDisplay();
256 
259  bool selectVar(float x, float y);
260 
265  bool findVariableDefinition();
266 
268  // void indicateItem() {itemIndicator=true;}
269 
271  bool redraw();
273  LassoBox updateRegion{0,0,0,0};
275  bool redrawUpdateRegion();
276 
277  struct ZoomCrop
278  {
279  double zoom=1, left=0, top=0, width=1000, height=1000;
280  };
281 
283  void renderToPNGCropped(const std::string& filename, const ZoomCrop&);
284 
285 
287  void recentre();
288 
290  bool redrawRequested() const {return m_redrawRequested;}
292  void requestRedraw() {m_redrawRequested=true; if (surface().get()) surface()->requestRedraw();}
293  bool hasScrollBars() const override {return true;}
294 
296  if (auto p=item->plotWidgetCast())
297  defaultPlotOptions=*p;
298  }
299 
300  void applyDefaultPlotOptions();
301 
302  void setItemFromItemFocus();
303  };
304 }
305 
306 namespace classdesc
307 {
308  template <> struct is_smart_ptr<minsky::Canvas::Model>: public true_type {};
309 }
310 
311 #include "canvas.cd"
312 
313 #endif
void addGroup()
item or wire obtained by get*At() calls
Definition: canvas.h:201
represents items that have been selected
Definition: selection.h:32
void zoom(double x, double y, double z) override
Definition: canvas.h:138
void rotateItem(float x, float y)
Definition: canvas.h:114
Model & operator=(const GroupPtr &model)
Definition: canvas.h:77
PlotOptions defaultPlotOptions
options to apply to a new plot widget
Definition: canvas.h:65
std::vector< float > position() const override
current centre coordinates
Definition: canvas.h:134
WirePtr wire
item or wire obtained by get*At() calls
Definition: canvas.h:176
Canvas(const GroupPtr &m)
Definition: canvas.h:146
void addNote(const std::string &text)
item or wire obtained by get*At() calls
Definition: canvas.h:192
void addVariable(const std::string &name, VariableType::Type type)
item or wire obtained by get*At() calls
Definition: canvas.h:187
represents rectangular region of a lasso operation
Definition: lasso.h:28
int handleSelected
selected handle for handle moves, -ve = invalid
Definition: canvas.h:108
void setItemFocus(const ItemPtr &x)
sets itemFocus, and resets mouse offset for placement
Definition: canvas.h:167
std::shared_ptr< Item > ItemPtr
Definition: item.h:55
ClickType::Type clickType
Definition: canvas.h:118
std::shared_ptr< Wire > WirePtr
Definition: wire.h:98
void addPlot()
item or wire obtained by get*At() calls
Definition: canvas.h:196
Exclude< shared_ptr< Port > > fromPort
from port when creating a new wire
Definition: canvas.h:109
bool redrawRequested() const
flag indicating that a redraw is requested, but not yet redrawn
Definition: canvas.h:290
void copyAllStockVars()
copy all stockVars of a GodleyIcon in item
Definition: canvas.h:249
Model model
Definition: canvas.h:103
Model(const GroupPtr &g)
Definition: canvas.h:76
float moveOffsY
Definition: canvas.h:111
void addSheet()
item or wire obtained by get*At() calls
Definition: canvas.h:205
Exclude< Point > rotateOrigin
starting mouse position when rotating
Definition: canvas.h:113
void copyAllFlowVars()
copy all flowVars of a GodleyIcon in item
Definition: canvas.h:244
ItemPtr itemIndicator
for drawing error indicator on the canvas
Definition: canvas.h:120
void addLock()
item or wire obtained by get*At() calls
Definition: canvas.h:204
bool hasScrollBars() const override
item or wire obtained by get*At() calls
Definition: canvas.h:293
void zoom(double x, double y, double z)
Definition: canvas.h:96
ecolab::cairo::SurfacePtr & surface()
Definition: canvas.h:148
static OperationBase * create(Type type)
factory method.
Definition: operation.cc:545
#define CLASSDESC_ACCESS(type)
void applyPlotOptions(PlotWidget &plot) const
Definition: plotOptions.h:90
bool getItemAt(float x, float y) override
item or wire obtained by get*At() calls
Definition: canvas.h:178
boost::geometry::model::d2::point_xy< float > Point
Definition: geometry.h:34
void addOperation(OperationType::Type op)
item or wire obtained by get*At() calls
Definition: canvas.h:182
void addGodley()
item or wire obtained by get*At() calls
Definition: canvas.h:200
void requestRedraw()
request a redraw on the screen
Definition: canvas.h:292
void addSwitch()
item or wire obtained by get*At() calls
Definition: canvas.h:202
NoAssign & operator=(const U &x)
Definition: canvas.h:49
ItemPtr itemFocus
item selected by clicking
Definition: canvas.h:106
Selection selection
Definition: canvas.h:105
void moveTo(float x, float y) override
move this so that (x,y) is centred
Definition: canvas.h:129
std::shared_ptr< Group > GroupPtr
Definition: port.h:32
GroupPtr parent
Definition: canvas.h:73
double termY
terminal of wire when extending
Definition: canvas.h:110
std::chrono::time_point< std::chrono::high_resolution_clock > Timestamp
Definition: canvas.h:68
void zoom(float &val, float origin, float factor)
base zooming transformation
Definition: zoom.h:26
a container item for a plot widget
Definition: plotWidget.h:45
void setDefaultPlotOptions()
item or wire obtained by get*At() calls
Definition: canvas.h:295
NoAssign & operator=(const NoAssign &)
Definition: canvas.h:47
lasso mode support
Definition: canvas.h:123
WirePtr wireFocus
wire that mouse is hovering over
Definition: canvas.h:107
void addRavel()
item or wire obtained by get*At() calls
Definition: canvas.h:203
double zoomFactor() const override
Definition: canvas.h:143
void updateTimestamp()
Definition: canvas.h:72
ItemPtr item
item or wire obtained by get*At() calls
Definition: canvas.h:175