Minsky
switchIcon.cc
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 #include "minsky.h"
20 #include "cairoItems.h"
21 #include "itemT.rcd"
22 #include "switchIcon.h"
23 #include "switchIcon.rcd"
24 #include "minsky_epilogue.h"
25 using namespace ecolab::cairo;
26 using namespace ecolab;
27 using namespace std;
28 
29 namespace minsky
30 {
31  void SwitchIcon::setNumCases(unsigned n)
32  {
33  if (n<2) throw error("switches need at least two cases");
34 
35  m_ports.clear();
36  m_ports.emplace_back(make_shared<Port>(*this));
37  // output port, selector port and n case ports
38  for (unsigned i=m_ports.size(); i<n+2; ++i)
39  m_ports.emplace_back(make_shared<InputPort>(*this));
40  const float width=8*numCases();
41  if (width>iWidth()) iWidth(width);
42  if (width>iHeight()) iHeight(width);
43  }
44 
45  unsigned SwitchIcon::switchValue() const
46  {
47  const double x=m_ports[1]->value();
48  if (x<1)
49  return 0;
50  if (x>=numCases()-1)
51  return numCases()-1;
52  return unsigned(x);
53  }
54 
55  Units SwitchIcon::units(bool check) const
56  {
57  bool inputFound=false;
58  Units r;
59  for (size_t i=2; i<m_ports.size(); ++i)
60  for (auto w: m_ports[i]->wires())
61  if (check && inputFound)
62  {
63  auto tmp=w->units(check);
64  if (tmp!=r)
65  throw_error("incompatible units: "+tmp.str()+"≠"+r.str());
66  }
67  else
68  {
69  inputFound=true;
70  r=w->units(check);
71  }
72  return r;
73  }
74 
75  void SwitchIcon::draw(cairo_t* cairo) const
76  {
77  auto z=zoomFactor();
78  // following the draw method in the Sheet class, iWidth() and iHeight() have been changed to m_width and m_height,
79  // since the former largely play a role in the VariableBase and OperationBase classes. for ticket 1250
80  const float width=m_width*z, height=m_height*z;
81  cairo_set_line_width(cairo,1);
82  cairo_rectangle(cairo,-0.5*width,-0.5*height,width,height);
83  cairo_stroke(cairo);
84 
85  const float w=flipped? -width: width;
86  const float o=flipped? -8: 8;
87  // output port
88  drawTriangle(cairo, 0.5*w, 0, palette[0], flipped? M_PI: 0);
89  m_ports[0]->moveTo(x()+0.5*w, y());
90  // control port
91  drawTriangle(cairo, 0, -0.5*height-8, palette[0], M_PI/2);
92  m_ports[1]->moveTo(x(), y()-0.5*height-8);
93  const float dy=height/numCases();
94  float y1=-0.5*height+0.5*dy;
95  // case ports
96  for (size_t i=2; i<m_ports.size(); ++i, y1+=dy)
97  {
98  drawTriangle(cairo, -0.5*w-o, y1, palette[(i-2)%paletteSz], flipped? M_PI: 0);
99  m_ports[i]->moveTo(x()+-0.5*w-o, y()+y1);
100  }
101  // draw indicating arrow
102  cairo_move_to(cairo,0.5*w, 0);
103  try
104  {
105  y1=-0.5*width+0.5*dy+switchValue()*dy;
106  }
107  catch (const std::exception&)
108  {
109  y1=-0.5*width+0.5*dy;
110  }
111  cairo_line_to(cairo,-0.45*w,0.9*y1);
112  cairo_stroke(cairo);
113 
114  if (mouseFocus)
115  {
116  drawPorts(cairo);
117  displayTooltip(cairo,tooltip());
118  if (onResizeHandles) drawResizeHandles(cairo);
119  }
120 
121  // add 8 pt margin to allow for ports
122  cairo_rectangle(cairo,-0.5*width-8,-0.5*height-8,width+16,height+8);
123  cairo_clip(cairo);
124  if (selected) drawSelected(cairo);
125  }
126 
127 }
#define M_PI
some useful geometry types, defined from boost::geometry
Definition: geometry.h:29
std::string str() const
Definition: variableType.cc:33
STL namespace.
bool flipped(double rotation)
returns if the angle (in degrees) is in the second or third quadrant
Definition: geometry.h:102
Creation and access to the minskyTCL_obj object, which has code to record whenever Minsky&#39;s state cha...
Definition: constMap.h:22
represents the units (in sense of dimensional analysis) of a variable.
Definition: units.h:34
void drawTriangle(cairo_t *cairo, double x, double y, const ecolab::cairo::Colour &col, double angle=0)
CLASSDESC_ACCESS_EXPLICIT_INSTANTIATION(minsky::SwitchIcon)