Minsky
lock.cc
Go to the documentation of this file.
1 /*
2  @copyright Steve Keen 2021
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 #include "cairoItems.h"
21 #include "lock.h"
22 #include "wire.h"
23 #include "selection.h"
24 #include "lasso.h"
25 #include <cairo_base.h>
26 #include "itemT.rcd"
27 #include "lock.rcd"
28 #include "lock.xcd"
29 #include "minsky.h"
30 #include "minsky_epilogue.h"
31 using namespace std;
32 
33 namespace minsky
34 {
35  SVGRenderer Lock::lockedIcon;
36  SVGRenderer Lock::unlockedIcon;
37 
38  Lock::Lock()
39  {
40  tooltip("Double click to lock/unlock");
41  iWidth(30);
42  iHeight(30);
43  addPorts();
44  }
45 
46  void Lock::addPorts()
47  {
48  m_ports.clear();
49  m_ports.emplace_back(make_shared<Port>(*this));
50  m_ports[0]->moveTo(x()+15,y());
51  m_ports.emplace_back(make_shared<InputPort>(*this));
52  m_ports[1]->moveTo(x()-15,y());
53  }
54 
55  Ravel* Lock::ravelInput() const
56  {
57  if (auto inputPort=ports(1).lock())
58  if (!inputPort->wires().empty())
59  if (auto fromPort=inputPort->wires()[0]->from())
60  return dynamic_cast<Ravel*>(&fromPort->item());
61  return nullptr;
62  }
63 
64 
65  void Lock::toggleLocked()
66  {
67  if (locked())
68  lockedState.clear();
69  else
70  if (auto* r=ravelInput())
71  {
72  // need to a full reset at this point, not delayed
74  lockedState=r->getState();
75  tooltip(ravel::Ravel::description(lockedState));
76  }
77  else
78  throw_error("Locks can only be applied to Ravels");
79  }
80 
81  void Lock::draw(cairo_t* cairo) const
82  {
83  const float z=zoomFactor()*scaleFactor();
84  const float w=iWidth()*z, h=iHeight()*z;
85 
86  {
87  const ecolab::cairo::CairoSave cs(cairo);
88  cairo_translate(cairo,-0.5*w,-0.5*h);
89  SVGRenderer* icon=locked()? &lockedIcon: &unlockedIcon;
90  cairo_scale(cairo, w/icon->width(), h/icon->height());
91  icon->render(cairo);
92  }
93 
94  if (mouseFocus)
95  {
96  drawPorts(cairo);
97  displayTooltip(cairo,tooltip());
98  if (onResizeHandles) drawResizeHandles(cairo);
99  }
100 
101  // add 8 pt margin to allow for ports
102  cairo_rectangle(cairo,-0.5*w-8,-0.5*h-8,w+16,h+8);
103  cairo_clip(cairo);
104  if (selected) drawSelected(cairo);
105  }
106 
107  Units Lock::units(bool check) const
108  {
109  if (locked())
110  {
111  if (auto* r=ravelInput())
112  if (auto p=r->ports(1).lock())
113  {
114  Units inputUnits=p->units(check);
115  if (inputUnits.empty()) return inputUnits;
116  size_t multiplier=1;
117  // at this stage, gross up exponents by the handle size of each
118  // reduced by product handles
119  for (const auto& h: lockedState.handleStates)
120  if (h.collapsed && h.reductionOp==ravel::Op::prod)
121  {
122  // find which handle number this is
123  // TODO - is there a way of avoiding this second loop?
124  size_t i=0;
125  for (; i<r->maxRank(); ++i)
126  if (r->handleDescription(i)==h.description)
127  {
128  multiplier*=r->numSliceLabels(i);
129  break;
130  }
131  }
132  if (multiplier>1)
133  for (auto& u: inputUnits)
134  u.second*=multiplier;
135  return inputUnits;
136  }
137  return {};
138  }
139  return m_ports[1]->units(check);
140  }
141 
142  void Lock::applyLockedStateToRavel() const
143  {
144  if (auto ravel=ravelInput())
145  ravel->applyState(lockedState);
146  }
147 
148 
149 }
150 
STL namespace.
void reset()
resets the variables back to their initial values
Definition: minsky.cc:866
double width() const
Definition: SVGItem.h:44
Creation and access to the minskyTCL_obj object, which has code to record whenever Minsky&#39;s state cha...
Definition: constMap.h:22
double height() const
Definition: SVGItem.h:45
represents the units (in sense of dimensional analysis) of a variable.
Definition: units.h:34
void render(cairo_t *) const
Definition: SVGItem.cc:82
CLASSDESC_ACCESS_EXPLICIT_INSTANTIATION(minsky::Lock)
Minsky & minsky()
global minsky object
Definition: minskyTCL.cc:51