Minsky: 3.17.0
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(ravelCAPI::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  icon->render(cairo,w,h);
91  }
92 
93  if (mouseFocus)
94  {
95  drawPorts(cairo);
96  displayTooltip(cairo,tooltip());
97  if (onResizeHandles) drawResizeHandles(cairo);
98  }
99 
100  // add 8 pt margin to allow for ports
101  cairo_rectangle(cairo,-0.5*w-8,-0.5*h-8,w+16,h+8);
102  cairo_clip(cairo);
103  if (selected) drawSelected(cairo);
104  }
105 
106  Units Lock::units(bool check) const
107  {
108  if (locked())
109  {
110  if (auto* r=ravelInput())
111  if (auto p=r->ports(1).lock())
112  {
113  Units inputUnits=p->units(check);
114  if (inputUnits.empty()) return inputUnits;
115  size_t multiplier=1;
116  // at this stage, gross up exponents by the handle size of each
117  // reduced by product handles
118  for (const auto& h: lockedState.handleStates)
119  if (h.collapsed && h.reductionOp==ravel::Op::prod)
120  {
121  // find which handle number this is
122  // TODO - is there a way of avoiding this second loop?
123  size_t i=0;
124  for (; i<r->maxRank(); ++i)
125  if (r->handleDescription(i)==h.description)
126  {
127  multiplier*=r->numSliceLabels(i);
128  break;
129  }
130  }
131  if (multiplier>1)
132  for (auto& u: inputUnits)
133  u.second*=multiplier;
134  return inputUnits;
135  }
136  return {};
137  }
138  return m_ports[1]->units(check);
139  }
140 
141  void Lock::applyLockedStateToRavel() const
142  {
143  if (auto ravel=ravelInput())
144  ravel->applyState(lockedState);
145  }
146 
147 
148 }
149 
STL namespace.
void reset()
resets the variables back to their initial values
Definition: minsky.cc:865
represents the units (in sense of dimensional analysis) of a variable.
Definition: units.h:34
CLASSDESC_ACCESS_EXPLICIT_INSTANTIATION(minsky::Lock)
Minsky & minsky()
global minsky object
Definition: addon.cc:545
void render(cairo_t *, double width, double height) const
render SVG into region of size width height
Definition: SVGItem.cc:84