Minsky
item.h
Go to the documentation of this file.
1 /*
2  @copyright Steve Keen 2015
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 ITEM_H
21 #define ITEM_H
22 
23 #include "noteBase.h"
24 #include "port.h"
25 #include "intrusiveMap.h"
26 #include "geometry.h"
27 #include "str.h"
28 #include "polyRESTProcessBase.h"
29 
30 #include <accessor.h>
31 #include <TCL_obj_base.h>
32 #include <json_pack_base.h>
33 
34 #include <cairo.h>
35 #include <vector>
36 #include <cairo_base.h>
37 
38 #include <iostream>
39 #include <assert.h>
40 
41 #include <RESTProcess_base.h>
42 
43 namespace minsky
44 {
45  struct LassoBox;
46  struct Selection;
47  class GroupItems;
48  class Group;
49  class VariablePtr;
50  class VariableBase;
51  class OperationBase;
52  class SwitchIcon;
53  class PlotWidget;
54  class GodleyIcon;
55  class Ravel;
56 
57  class Item;
58  typedef std::shared_ptr<Item> ItemPtr;
59 
63  struct ClickType
64  {
66  };
67 
69  constexpr float portRadius=6;
70  constexpr float portRadiusMult=2.0f*portRadius;
71 
72  // ports are owned by their items, so it is not appropriate to
73  // default copy the port references
74  struct ItemPortVector: public std::vector<std::shared_ptr<Port> >
75  {
79  ItemPortVector& operator=(const ItemPortVector&) {return *this;}
81  };
82 
85  {
86  float m_left=0, m_right=0, m_top, m_bottom;
87  public:
88  void update(const Item& x);
89  bool contains(float x, float y) const {
90  // extend each item by a portradius to solve ticket #903
91  return m_left-portRadius<=x && m_right+portRadius>=x && m_top-portRadius<=y && m_bottom+portRadius>=y;
92  }
93  bool valid() const {return m_left!=m_right;}
94  float width() const {return m_right-m_left;}
95  float height() const {return m_bottom-m_top;}
96  float left() const {return m_left;}
97  float right() const {return m_right;}
98  float top() const {return m_top;}
99  float bottom() const {return m_bottom;}
100  };
101 
103  struct ItemExclude
104  {
106  classdesc::Exclude<std::weak_ptr<Group>> group;
107 
108  virtual ~ItemExclude() {}
109 
111  virtual const VariableBase* variableCast() const {return nullptr;}
112  virtual VariableBase* variableCast() {return nullptr;}
115  virtual const OperationBase* operationCast() const {return nullptr;}
116  virtual OperationBase* operationCast() {return nullptr;}
119  virtual const SwitchIcon* switchIconCast() const {return nullptr;}
120  virtual SwitchIcon* switchIconCast() {return nullptr;}
123  virtual const PlotWidget* plotWidgetCast() const {return nullptr;}
124  virtual PlotWidget* plotWidgetCast() {return nullptr;}
127  virtual const GodleyIcon* godleyIconCast() const {return nullptr;}
128  virtual GodleyIcon* godleyIconCast() {return nullptr;}
131  virtual const Ravel* ravelCast() const {return nullptr;}
132  virtual Ravel* ravelCast() {return nullptr;}
134 
137  virtual void insertControlled(Selection& selection) {}
141  void removeControlledItems();
142 
143  double m_rotation=0;
144  void rotate(const Point& mouse, const Point& orig);
146  };
147 
148  class Item: public NoteBase, public ecolab::TCLAccessor<Item,double>,
149  public classdesc::PolyRESTProcessBase,
150  public classdesc::Exclude<ItemExclude>
151  {
152 
153  protected:
154  // these need to be protected, not private to allow the setting of these in constructors.
155  double m_width=10, m_height=10;
157 
158  mutable struct MemoisedRotator: public Rotate
159  {
160  MemoisedRotator(): Rotate(0,0,0) {}
161  void update(float a,float x, float y) {
162  if (!initialisedFrom(a,x,y))
163  Rotate::operator=(Rotate(a,x,y));
164  }
165  } memoisedRotator;
166 
167  static void drawResizeHandle(cairo_t* cairo, double x, double y, double sf, double angle);
168 
169 
170  public:
171 
172  Item(): TCLAccessor<Item,double>("rotation",(Getter)&Item::rotation,(Setter)&Item::rotation) {}
173  float m_x=0, m_y=0;
174  float m_sf=1;
175  mutable bool onResizeHandles=false;
176  bool onBorder=false;
177  std::string deleteCallback;
178 
180  virtual std::weak_ptr<Port> ports(std::size_t i) const {
181  return i<m_ports.size()? m_ports[i]: nullptr;
182  }
184  std::size_t portsSize() const {return m_ports.size();}
185  float portX(std::size_t i) {
186  if (auto p=ports(i).lock()) return p->x();
187  return 0;
188  }
189 
190  float portY(std::size_t i) {
191  if (auto p=ports(i).lock()) return p->y();
192  return 0;
193  }
195  mutable BoundingBox bb;
196  virtual bool contains(float xx, float yy) const {
197  auto hz=resizeHandleSize(); // extend by resize handle size (which is also portRadius)
198  return left()-hz<=xx && right()+hz>=xx && top()-hz<=yy && bottom()+hz>=yy;
199  }
200  bool contains(const Point& p) const {return contains(p.x(),p.y());}
201  void updateBoundingBox() override {bb.update(*this);}
202 
204  [[noreturn]] void throw_error(const std::string&) const;
205 
207  virtual bool ioVar() const {return false;}
209  virtual double value() const {return 0;}
210 
211  double rotation() const {return m_rotation;}
212  double rotation(const double& r) {return m_rotation=r;}
213 
215  std::pair<double,bool> rotationAsRadians() const;
216 
217  float iWidth() const {return m_width;}
218  float iWidth(const float& w) {
219  m_width=w;
220  bb.update(*this);
221  return m_width;
222  }
223 
224  float iHeight() const {return m_height;}
225  float iHeight(const float& h) {
226  m_height=h;
227  bb.update(*this);
228  return m_height;
229  }
230 
232  virtual void flip() {rotation(rotation()+180);}
233 
234  virtual std::string classType() const {return "Item";}
236  std::string id() const {return str(size_t(this));}
237 
238  virtual float x() const;
239  virtual float y() const;
240  virtual float zoomFactor() const;
241  void ensureBBValid() const {if (!bb.valid()) bb.update(*this);}
242  float width() const {return right()-left();}
243  float height() const {return bottom()-top();}
244  virtual std::vector<Point> corners() const; // 4 corners of item
245  float left() const;
246  float right() const;
247  float top() const;
248  float bottom() const;
249 
251  std::string bookmarkId() const {return tooltip().empty()? std::to_string(size_t(this)): tooltip();}
252  void adjustBookmark() const override;
253 
255  float resizeHandleSize() const {return std::max(portRadius*zoomFactor(), std::max(0.02f*width(), 0.02f*height()));}
257  virtual bool onResizeHandle(float x, float y) const;
259  virtual bool inItem(float x, float y) const {return false;}
261  virtual bool onItem(float x, float y) const;
263  virtual void onMouseDown(float x, float y) {}
265  virtual void onMouseUp(float x, float y) {}
268  virtual bool onMouseMotion(float x, float y) {return false;}
271  virtual bool onMouseOver(float x, float y) {return false;}
273  virtual void onMouseLeave() {}
276  virtual bool onKeyPress(int keySym, const std::string& utf8, int state)
277  {return false;}
278 
280  virtual void deleteAttachedWires();
281 
282  virtual Item* clone() const {
283  auto r=new Item(*this);
284  r->group.reset();
285  return r;
286  }
287 
289  virtual bool visible() const;
290 
291  void moveTo(float x, float y);
292 
294  virtual void draw(cairo_t* cairo) const;
296  virtual void resize(const LassoBox& b);
298  virtual float scaleFactor() const;
299  virtual float scaleFactor(const float& sf);
300 
303  void dummyDraw() const;
304 
306  virtual void displayTooltip(cairo_t*, const std::string&) const;
307 
309  virtual void updateIcon(double t) {}
310 
311  Item(const Item&)=default;
312  Item& operator=(const Item&)=default;
313  virtual ~Item() {}
314 
315  void drawPorts(cairo_t* cairo) const;
316  static void drawSelected(cairo_t* cairo);
317  virtual void drawResizeHandles(cairo_t* cairo) const;
318 
320  virtual ClickType::Type clickType(float x, float y) const;
321 
323  virtual std::shared_ptr<Port> closestOutPort(float x, float y) const;
324  virtual std::shared_ptr<Port> closestInPort(float x, float y) const;
325 
328  virtual std::shared_ptr<Item> select(float x, float y) const {return {};}
330  virtual void TCL_obj(classdesc::TCL_obj_t& t, const std::string& d)
331  {::TCL_obj(t,d,*this);}
333  void RESTProcess(classdesc::RESTProcess_t& rp,const std::string& d) override
334  {::RESTProcess(rp,d,*this);}
335  void RESTProcess(classdesc::RESTProcess_t& rp,const std::string& d) const override
336  {::RESTProcess(rp,d,*this);}
337  virtual void json_pack(classdesc::json_pack_t& j) const
338  {::json_pack(j,"",*this);}
339 
341  virtual void displayDelayedTooltip(float x, float y) {}
342  virtual void disableDelayedTooltip() {}
343 
345  virtual bool editorMode() const {return false;}
346  virtual void toggleEditorMode() {}
347 
351  // all items feeding into other items must implement this
352  virtual Units units(bool check=false) const {
353  if (check) throw_error("units not implemented");
354  return {};
355  }
357  Units checkUnits() const {return units(true);}
358 
360  ItemPtr itemPtrFromThis() const;
361 
363  virtual void destroyFrame() {}
364  };
365 
366  typedef std::vector<ItemPtr> Items;
367 
369  {
370  bool onResizeHandle(float x, float y) const override;
371  void drawResizeHandles(cairo_t* cairo) const override;
373  virtual Point resizeHandleCoords() const;
374  };
375 
376 }
377 
378 #ifdef CLASSDESC
379 // omit these, because weak/shared pointers cause problems, and its
380 // not needed anyway
381 #pragma omit pack minsky::Item
382 #pragma omit unpack minsky::Item
383 
384 // omit ItemExclude to reduce the amount of boilerplate code needing to be compiled
385 #pragma omit pack minsky::ItemExclude
386 #pragma omit unpack minsky::ItemExclude
387 #pragma omit json_pack minsky::ItemExclude
388 #pragma omit json_unpack minsky::ItemExclude
389 #pragma omit xml_pack minsky::ItemExclude
390 #pragma omit xml_unpack minsky::ItemExclude
391 #pragma omit TCL_obj minsky::ItemExclude
392 #pragma omit RESTProcess minsky::ItemExclude
393 
394 #endif
395 namespace classdesc_access
396 {
397  template <> struct access_pack<minsky::Item>:
398  public classdesc::NullDescriptor<classdesc::pack_t> {};
399  template <> struct access_unpack<minsky::Item>:
400  public classdesc::NullDescriptor<classdesc::unpack_t> {};
401 
402  // this implements polymorphic TCL_obj drilldown
403  template <>
404  struct access_TCL_obj<minsky::ItemPtr>
405  {
406  template <class U>
407  void operator()(cd::TCL_obj_t& t, const cd::string& d, U& a)
408  {
409  if (a) a->TCL_obj(t,d);
410  }
411  };
412 }
413 #include "item.cd"
414 #include "item.xcd"
415 #endif
416 
virtual bool ioVar() const
indicates this is a group I/O variable
Definition: item.h:207
virtual Units units(bool check=false) const
compute the dimensional units
Definition: item.h:352
represents items that have been selected
Definition: selection.h:32
function f
Definition: canvas.m:1
float portY(std::size_t i)
Definition: item.h:190
virtual std::shared_ptr< Port > closestOutPort(float x, float y) const
returns closest output port to x,y
Definition: item.cc:421
virtual bool onMouseOver(float x, float y)
respond to mouse motion events (hover) without button pressed
Definition: item.h:271
void drawPorts(cairo_t *cairo) const
Definition: item.cc:294
void adjustBookmark() const override
adjust bookmark list to reflect current configuration
Definition: item.cc:192
float bottom() const
Definition: item.h:99
virtual void updateIcon(double t)
update display after a step()
Definition: item.h:309
represents whether a mouse click is on the item, on an output port (for wiring, or is actually outsid...
Definition: item.h:63
std::size_t portsSize() const
number of ports
Definition: item.h:184
virtual Point resizeHandleCoords() const
returns coordinates of the resizer handle
Definition: item.cc:205
bool initialisedFrom(float rot, float x, float y) const
Definition: geometry.h:53
float right() const
Definition: item.cc:170
virtual void displayTooltip(cairo_t *, const std::string &) const
display tooltip text, eg on mouseover
Definition: item.cc:398
virtual double value() const
current value of output port
Definition: item.h:209
bool contains(const Point &p) const
Definition: item.h:200
virtual float x() const
Definition: item.cc:107
virtual void removeControlledItems(GroupItems &)
remove all controlled items from a group
Definition: item.h:139
virtual void onMouseLeave()
respond to mouse leave events (when mouse leaves item)
Definition: item.h:273
virtual bool visible() const
whether this item is visible on the canvas.
Definition: item.cc:250
virtual float y() const
Definition: item.cc:114
virtual const PlotWidget * plotWidgetCast() const
a more efficient replacement for dynamic_cast<PlotWidget*>(this)
Definition: item.h:123
float top() const
Definition: item.cc:177
void dummyDraw() const
draw into a dummy cairo context, for purposes of calculating port positions
Definition: item.cc:392
float iHeight() const
Definition: item.h:224
bool onResizeHandles
set to true to indicate mouse is ovcaler resize handles
Definition: item.h:175
bool onResizeHandle(float x, float y) const override
Definition: item.cc:236
represents rectangular region of a lasso operation
Definition: lasso.h:28
float m_sf
scale factor of item on canvas, or within group
Definition: item.h:174
virtual const SwitchIcon * switchIconCast() const
a more efficient replacement for dynamic_cast<SwitchIcon*>(this)
Definition: item.h:119
float y(float x, float y) const
Definition: geometry.h:60
virtual bool editorMode() const
some items have an editor mode attribute
Definition: item.h:345
std::shared_ptr< Item > ItemPtr
Definition: item.h:57
float width() const
Definition: item.h:94
Item members excluded from reflection.
Definition: item.h:103
virtual PlotWidget * plotWidgetCast()
a more efficient replacement for dynamic_cast<PlotWidget*>(this)
Definition: item.h:124
std::pair< double, bool > rotationAsRadians() const
return the rotation as radians, and whether rotation should have additional straight angle added for ...
Definition: item.cc:92
void RESTProcess(classdesc::RESTProcess_t &rp, const std::string &d) override
runs the RESTProcess descriptor suitable for this type
Definition: item.h:333
Rotate(float rot, float x0, float y0)
Definition: geometry.h:51
rotate (x,y) by rot (in degrees) around the origin (x0, y0) can be used for rotating multiple points ...
Definition: geometry.h:44
float m_left
Definition: item.h:86
float m_right
Definition: item.h:86
BoundingBox bb
canvas bounding box.
Definition: item.h:195
double m_height
Definition: item.h:155
virtual std::string const & tooltip() const
Definition: noteBase.h:36
virtual Ravel * ravelCast()
a more efficient replacement for dynamic_cast<Ravel*>(this)
Definition: item.h:132
bool valid() const
Definition: item.h:93
virtual float zoomFactor() const
Definition: item.cc:121
static void drawResizeHandle(cairo_t *cairo, double x, double y, double sf, double angle)
Definition: item.cc:316
minsky::Item::MemoisedRotator memoisedRotator
virtual const GodleyIcon * godleyIconCast() const
a more efficient replacement for dynamic_cast<GodleyIcon*>(this)
Definition: item.h:127
void update(const Item &x)
Definition: item.cc:46
void operator()(cd::TCL_obj_t &t, const cd::string &d, U &a)
Definition: item.h:407
void ensureBBValid() const
Definition: item.h:241
virtual SwitchIcon * switchIconCast()
a more efficient replacement for dynamic_cast<SwitchIcon*>(this)
Definition: item.h:120
virtual bool onResizeHandle(float x, float y) const
Definition: item.cc:228
Units checkUnits() const
perform units consistency checks
Definition: item.h:357
virtual void draw(cairo_t *cairo) const
draw this item into a cairo context
Definition: item.cc:363
float iHeight(const float &h)
Definition: item.h:225
virtual VariableBase * variableCast()
a more efficient replacement for dynamic_cast<VariableBase*>(this)
Definition: item.h:112
virtual ClickType::Type clickType(float x, float y) const
returns the clicktype given a mouse click at x, y.
Definition: item.cc:275
virtual bool onMouseMotion(float x, float y)
respond to mouse motion events with button pressed
Definition: item.h:268
virtual void insertControlled(Selection &selection)
insert this items controlled or controller items are inserted correctly into selection.
Definition: item.h:137
float left() const
Definition: item.cc:163
static void drawSelected(cairo_t *cairo)
Definition: item.cc:308
float iWidth(const float &w)
Definition: item.h:218
Creation and access to the minskyTCL_obj object, which has code to record whenever Minsky&#39;s state cha...
Definition: constMap.h:22
float width() const
Definition: item.h:242
float right() const
Definition: item.h:97
float iWidth() const
Definition: item.h:217
std::vector< ItemPtr > Items
Definition: item.h:366
float height() const
Definition: item.h:95
double rotation(const double &r)
Definition: item.h:212
float left() const
Definition: item.h:96
virtual const OperationBase * operationCast() const
a more efficient replacement for dynamic_cast<OperationBase*>(this)
Definition: item.h:115
virtual void onMouseUp(float x, float y)
respond to mouse up events
Definition: item.h:265
represents the units (in sense of dimensional analysis) of a variable.
Definition: units.h:34
double m_width
Definition: item.h:155
ItemPtr itemPtrFromThis() const
return a shared_ptr to this
Definition: item.cc:447
bool onBorder
true to indicate mouse hovering over border
Definition: item.h:176
void rotate(const Point &mouse, const Point &orig)
Definition: item.cc:100
boost::geometry::model::d2::point_xy< float > Point
Definition: geometry.h:34
std::string str(T x)
utility function to create a string representation of a numeric type
Definition: str.h:33
virtual void drawResizeHandles(cairo_t *cairo) const
Definition: item.cc:343
virtual bool contains(float xx, float yy) const
Definition: item.h:196
virtual void toggleEditorMode()
Definition: item.h:346
void throw_error(const std::string &) const
mark item on canvas, then throw
Definition: item.cc:86
virtual GodleyIcon * godleyIconCast()
a more efficient replacement for dynamic_cast<GodleyIcon*>(this)
Definition: item.h:128
ItemPortVector m_ports
Definition: item.h:156
float resizeHandleSize() const
resize handles should be at least a percentage if the icon size (#1025)
Definition: item.h:255
virtual float scaleFactor() const
factor by which item has been resized
Definition: item.cc:128
float m_bottom
Definition: item.h:86
virtual void resize(const LassoBox &b)
resize this item on the canvas
Definition: item.cc:333
ItemPortVector(const ItemPortVector &)
Definition: item.h:77
float bottom() const
Definition: item.cc:184
classdesc::Exclude< std::weak_ptr< Group > > group
owning group of this item.
Definition: item.h:106
virtual std::vector< Point > corners() const
Definition: item.cc:153
float height() const
Definition: item.h:243
virtual ~ItemExclude()
Definition: item.h:108
virtual void disableDelayedTooltip()
Definition: item.h:342
float portX(std::size_t i)
Definition: item.h:185
virtual std::string classType() const
Definition: item.h:234
void removeControlledItems()
remove all controlled items from their owning group
Definition: item.cc:441
virtual Item * clone() const
Definition: item.h:282
bounding box information (at zoom=1 scale)
Definition: item.h:84
std::string bookmarkId() const
Id of bookmark associated with this.
Definition: item.h:251
double m_rotation
rotation of icon, in degrees rotate item based on vector from orig to mouse
Definition: item.h:143
virtual bool inItem(float x, float y) const
Definition: item.h:259
virtual OperationBase * operationCast()
a more efficient replacement for dynamic_cast<OperationBase*>(this)
Definition: item.h:116
constexpr float portRadiusMult
Definition: item.h:70
virtual const Ravel * ravelCast() const
a more efficient replacement for dynamic_cast<Ravel*>(this)
Definition: item.h:131
virtual void deleteAttachedWires()
delete all attached wires
Definition: item.cc:139
Item & operator=(const Item &)=default
void moveTo(float x, float y)
Definition: item.cc:256
void updateBoundingBox() override
Definition: item.h:201
ItemPortVector & operator=(const ItemPortVector &)
Definition: item.h:79
bool contains(float x, float y) const
Definition: item.h:89
virtual void TCL_obj(classdesc::TCL_obj_t &t, const std::string &d)
runs the TCL_obj descriptor suitable for this type
Definition: item.h:330
virtual std::weak_ptr< Port > ports(std::size_t i) const
callback to be run when item deleted from group
Definition: item.h:180
virtual void json_pack(classdesc::json_pack_t &j) const
Definition: item.h:337
string to_string(CONST84 char *x)
Definition: minskyTCLObj.h:33
virtual bool onKeyPress(int keySym, const std::string &utf8, int state)
respond to key press events
Definition: item.h:276
void RESTProcess(classdesc::RESTProcess_t &rp, const std::string &d) const override
Definition: item.h:335
float m_y
position in canvas, or within group
Definition: item.h:173
virtual void destroyFrame()
destroy any popup windows associated with this
Definition: item.h:363
a container item for a plot widget
Definition: plotWidget.h:46
float m_x
Definition: item.h:173
constexpr float portRadius
radius of circle marking ports at zoom=1
Definition: item.h:69
virtual void displayDelayedTooltip(float x, float y)
enable extended tooltip help message appropriate for mouse at (x,y)
Definition: item.h:341
float x(float x, float y) const
Definition: geometry.h:59
void update(float a, float x, float y)
Definition: item.h:161
virtual void onMouseDown(float x, float y)
respond to mouse down events
Definition: item.h:263
virtual bool onItem(float x, float y) const
returns true if (x,y) is on the icon
Definition: item.cc:242
std::string id() const
return an id uniquely identifying this item
Definition: item.h:236
void drawResizeHandles(cairo_t *cairo) const override
Definition: item.cc:355
float top() const
Definition: item.h:98
ItemPortVector(ItemPortVector &&)
Definition: item.h:78
virtual std::shared_ptr< Port > closestInPort(float x, float y) const
Definition: item.cc:428
virtual void flip()
rotate icon though 180∘
Definition: item.h:232
double rotation() const
Definition: item.h:211
virtual ~Item()
Definition: item.h:313
std::string deleteCallback
Definition: item.h:177
virtual const VariableBase * variableCast() const
a more efficient replacement for dynamic_cast<VariableBase*>(this)
Definition: item.h:111
virtual std::shared_ptr< Item > select(float x, float y) const
returns the variable if point (x,y) is within a visible variable icon, null otherwise.
Definition: item.h:328
ItemPortVector & operator=(ItemPortVector &&)
Definition: item.h:80