Advertisement
Korotkodul

logic_logic_shapes.cpp

Mar 16th, 2025
309
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.47 KB | None | 0 0
  1. #include "logic_shapes.h"
  2.  
  3. #include <cassert>
  4. #include <functional>
  5.  
  6.  
  7. using Graph_lib::Point;
  8. using Graph_lib::Color;
  9.  
  10.  
  11. namespace Logic {
  12.  
  13. SchemeShape::SchemeShape (const Point& pos, int width, int height)
  14.   : Graph_lib::Rectangle{ pos, width, height }
  15. {
  16.   set_color(BACKGROUND_COLOR);
  17.   set_fill_color(BACKGROUND_COLOR);
  18. }
  19.  
  20. void SchemeShape::attach (ElementShape& elem_shape)
  21. {
  22.   elem_shapes.push_back(elem_shape);
  23.   update_connections();
  24. }
  25.  
  26. void SchemeShape::attach (OperatorShape& oper_shape)
  27. {
  28.   oper_shapes.push_back(oper_shape);
  29.   attach(static_cast<ElementShape&>(oper_shape));
  30. }
  31.  
  32. void SchemeShape::draw_lines () const
  33. {
  34.   Graph_lib::Rectangle::draw_lines();
  35.  
  36.   for (int i = 0; i < connections.size(); ++i)
  37.     connections[i].draw();
  38.   for (int i = 0; i < elem_shapes.size(); ++i)
  39.     elem_shapes[i].draw();
  40. }
  41.  
  42. void SchemeShape::update_connections ()
  43. {
  44.   connections.clear();
  45.  
  46.   // determine all connections
  47.   for (int i = 0; i < elem_shapes.size(); ++i)
  48.   {
  49.     ElementShape& from = elem_shapes[i];
  50.  
  51.     for (int j = 0; j < oper_shapes.size(); ++j)
  52.     {
  53.       OperatorShape& to = oper_shapes[j];
  54.  
  55.       // try to find connection
  56.       const auto& to_inputs = to.parent().get_inputs();
  57.       for (size_t k = 0; k < to_inputs.size(); ++k)
  58.       {
  59.         const auto& input_pair = to_inputs[k];
  60.         if (&from.parent() == input_pair.elem)
  61.           connections.push_back(new ConnectionShape{ from, to, k });
  62.       }
  63.     } // for j
  64.   } // for i
  65. }
  66.  
  67.  
  68. ElementShape::ElementShape (SchemeShape& s,
  69.                             Element& e,
  70.                             const std::string& name,
  71.                             const Point& pos,  // left top
  72.                             int width /* = DEFAULT_WIDTH */, int height /* = DEFAULT_HEIGHT */)
  73.   : Graph_lib::Shape{ pos }
  74.   , scheme { s }
  75.   , elem { e }
  76.   , w { width }
  77.   , h { height }
  78.   , label { pos + Point{0, -LABEL_MARGIN_Y}, name }
  79.   , out_circle { Point{ pos.x + w + CIRCLES_RADIUS, pos.y + h/2 + 1 }, CIRCLES_RADIUS }
  80. {
  81.   using namespace std::placeholders;
  82.   Logic_callback cb = std::bind(&ElementShape::callback_func, this, _1);
  83.   e.set_callback(cb);
  84.  
  85.   // set style
  86.   label.set_font(LABEL_FONT);
  87.   label.set_color(LABEL_COLOR);
  88.  
  89.   out_circle.set_style(CIRCLE_LINE_TYPE);
  90.   out_circle.set_color(elem ? TRUE_COLOR : FALSE_COLOR);
  91. }
  92.  
  93. void ElementShape::on_change (const Element& e)
  94. {
  95.   out_circle.set_color(e ? TRUE_COLOR : FALSE_COLOR);
  96. }
  97.  
  98. void ElementShape::callback_func (const Element& e)
  99. {
  100.   on_change(e);
  101.   scheme.update_connections();
  102. }
  103.  
  104. void ElementShape::draw_lines () const
  105. {
  106.   label.draw();
  107.  
  108.   // we should draw output circle if only output is inverted
  109.   if (elem.inverted())
  110.     out_circle.draw();
  111. }
  112.  
  113.  
  114. SourceShape::SourceShape (SchemeShape& scheme,
  115.                           Source& e,
  116.                           const std::string& name,
  117.                           const Point& pos,  // left top
  118.                           int width /* = DEFAULT_WIDTH */, int height /* = DEFAULT_HEIGHT */)
  119.     : ElementShape{ scheme, e, name, pos, width, height }
  120.     , body { pos, width, height }
  121. {
  122.   scheme.attach(*this);
  123.  
  124.   body.set_style(SHAPE_LINE_TYPE);
  125.   body.set_color(
  126.       elem.inverted() ? (elem ? FALSE_COLOR : TRUE_COLOR)
  127.                       : (elem ? TRUE_COLOR : FALSE_COLOR)
  128.       );
  129. }
  130.  
  131. void SourceShape::on_change (const Element& e)
  132. {
  133.   ElementShape::on_change(e);
  134.  
  135.   body.set_color(
  136.       e.inverted() ? (e ? FALSE_COLOR : TRUE_COLOR)
  137.                    : (e ? TRUE_COLOR : FALSE_COLOR)
  138.       );
  139. }
  140.  
  141. void SourceShape::draw_lines () const
  142. {
  143.   ElementShape::draw_lines();
  144.  
  145.   body.draw();
  146. }
  147.  
  148.  
  149. ConnectionShape::ConnectionShape (const ElementShape& elem, const OperatorShape& oper, size_t i)
  150.   : line { elem.output_pos(), oper.input_pos(elem.parent(), i) }
  151.   , dash { oper.input_pos(elem.parent(), i), oper.input_pos(elem.parent(), i) + Point{CIRCLES_RADIUS, 0} }
  152.   , circle { oper.input_pos(elem.parent(), i), CIRCLES_RADIUS }
  153. {
  154.   // determine if inverted
  155.   inverted = false;
  156.   for(const auto& inputs_pair : oper.parent().get_inputs())
  157.   {
  158.     if (inputs_pair.elem == &elem.parent())
  159.     {
  160.       inverted = inputs_pair.inv;
  161.       break;
  162.     }
  163.   }
  164.  
  165.   // set styles
  166.   line.set_style(CONNECTION_LINE_TYPE);
  167.   dash.set_style(CONNECTION_LINE_TYPE);
  168.   circle.set_style(CIRCLE_LINE_TYPE);
  169.  
  170.   line.set_color(elem.parent() ? TRUE_COLOR : FALSE_COLOR);
  171.   dash.set_color(elem.parent() ? TRUE_COLOR : FALSE_COLOR);
  172.   circle.set_color(elem.parent() ? FALSE_COLOR : TRUE_COLOR);
  173. }
  174.  
  175. void ConnectionShape::draw_lines () const
  176. {
  177.   line.draw();
  178.   if (inverted)
  179.     circle.draw();
  180.   else
  181.     dash.draw();
  182. }
  183.  
  184.  
  185. OperatorShape::OperatorShape (SchemeShape& scheme,
  186.                               Operation& e,
  187.                               const std::string& name,
  188.                               const Point& pos,  // left top
  189.                               int width /* = DEFAULT_WIDTH */, int height /* = DEFAULT_HEIGHT */)
  190.   : ElementShape{ scheme, e, name, pos, width, height }
  191. {
  192.   scheme.attach(*this);
  193. }
  194.  
  195. Point OperatorShape::input_pos (const Element& e, size_t i) const
  196. {
  197.   Point left_top = point(0);
  198.   const auto& elem_inputs = parent().get_inputs();
  199.  
  200.   if (elem_inputs.at(i).elem == &e)
  201.     return left_top + Point{ -CIRCLES_RADIUS, int((i+1) * h / (int(inputs_count()) + 1)) };
  202.  
  203.   assert(!"wrong input");
  204.   return left_top;
  205. }
  206.  
  207. void OperatorShape::draw_lines () const
  208. {
  209.   ElementShape::draw_lines();
  210. }
  211.  
  212.  
  213. AndShape::AndShape (SchemeShape& scheme,
  214.                    And& e,
  215.                    const std::string& name,
  216.                    const Point& pos,  // left top
  217.                    int width /* = DEFAULT_WIDTH */, int height /* = DEFAULT_HEIGHT */)
  218.   : OperatorShape { scheme, e, name, pos, width, height }
  219.   , right_side { Point{pos.x + width/2, pos.y + height/2 + 1}, width/2, height/2 + 1, -90, 90 }
  220.  
  221. {
  222.   left_side.add(pos + Point{width/2, 0});
  223.   left_side.add(pos);
  224.   left_side.add(pos + Point{0, height});
  225.   left_side.add(pos + Point{width/2, height});
  226.  
  227.   left_side.set_style(SHAPE_LINE_TYPE);
  228.   right_side.set_style(SHAPE_LINE_TYPE);
  229.  
  230.   Graph_lib::Color c = elem.inverted() ? (elem ? FALSE_COLOR : TRUE_COLOR)
  231.                                        : (elem ? TRUE_COLOR : FALSE_COLOR);
  232.   left_side.set_color(c);
  233.   right_side.set_color(c);
  234. }
  235.  
  236. void AndShape::on_change (const Element& e)
  237. {
  238.   OperatorShape::on_change(e);
  239.  
  240.   Graph_lib::Color c = e.inverted() ? (e ? FALSE_COLOR : TRUE_COLOR)
  241.                                     : (e ? TRUE_COLOR : FALSE_COLOR);
  242.   left_side.set_color(c);
  243.   right_side.set_color(c);
  244. }
  245.  
  246. void AndShape::draw_lines () const
  247. {
  248.   OperatorShape::draw_lines();
  249.  
  250.   left_side.draw();
  251.   right_side.draw();
  252. }
  253.  
  254.  
  255. OrShape::OrShape (SchemeShape& scheme,
  256.                   Or& e,
  257.                   const std::string& name,
  258.                   const Point& pos,  // left top
  259.                   int width /* = DEFAULT_WIDTH */, int height /* = DEFAULT_HEIGHT */)
  260.   : OperatorShape { scheme, e, name, pos, width, height }
  261.   , left_side  { Point{pos.x, pos.y + height/2 + 1}, width/4, height/2 + 1, -90, 90 }
  262.   , right_side { Point{pos.x, pos.y + height/2 + 1}, width/1, height/2 + 1, -90, 90 }
  263. {
  264.   left_side.set_style(SHAPE_LINE_TYPE);
  265.   right_side.set_style(SHAPE_LINE_TYPE);
  266.  
  267.   Graph_lib::Color c = elem.inverted() ? (elem ? FALSE_COLOR : TRUE_COLOR)
  268.                                        : (elem ? TRUE_COLOR : FALSE_COLOR);
  269.   left_side.set_color(c);
  270.   right_side.set_color(c);
  271. }
  272.  
  273. Point OrShape::input_pos (const Element& e, size_t i) const
  274. {
  275.   auto pos = point(0);
  276.   auto p =  OperatorShape::input_pos(e, i);
  277.   double rx = left_side.major();
  278.   double ry = left_side.minor();
  279.   double dy = p.y - pos.y;
  280.   double y = std::abs(ry - dy);
  281.   double x = rx * std::sqrt( 1.0 - y*y / (ry*ry) );
  282.   return p + Point{ int(x), 0 };
  283. }
  284.  
  285. void OrShape::on_change (const Element& e)
  286. {
  287.   OperatorShape::on_change(e);
  288.  
  289.   Graph_lib::Color c = e.inverted() ? (e ? FALSE_COLOR : TRUE_COLOR)
  290.                                     : (e ? TRUE_COLOR : FALSE_COLOR);
  291.   left_side.set_color(c);
  292.   right_side.set_color(c);
  293. }
  294.  
  295. void OrShape::draw_lines () const
  296. {
  297.   OperatorShape::draw_lines();
  298.  
  299.   left_side.draw();
  300.   right_side.draw();
  301. }
  302.  
  303. XorShape::XorShape (SchemeShape& scheme,
  304.                     Xor& e,
  305.                     const std::string& name,
  306.                     const Graph_lib::Point& pos,  // left top
  307.                     int width /* = DEFAULT_WIDTH */, int height /* = DEFAULT_HEIGHT */)
  308.   : OperatorShape { scheme, e, name, pos, width, height }
  309.   , right_side { Point{pos.x + width/2, pos.y + height/2 + 1}, width/2, height/2 + 1, -90, 90 }
  310. {
  311.   left_side.add(pos + Point{width/2, 0});
  312.   left_side.add(pos);
  313.   left_side.add(pos + Point{0, height});
  314.   left_side.add(pos + Point{width/2, height});
  315.  
  316.   left_side.set_style(SHAPE_LINE_TYPE);
  317.   right_side.set_style(SHAPE_LINE_TYPE);
  318.  
  319.   Graph_lib::Color c = elem.inverted() ? (elem ? FALSE_COLOR : TRUE_COLOR)
  320.                                        : (elem ? TRUE_COLOR : FALSE_COLOR);
  321.   left_side.set_color(c);
  322.   right_side.set_color(c);
  323. }
  324.  
  325. void XorShape::on_change (const Element& e)
  326. {
  327.   OperatorShape::on_change(e);
  328.  
  329.   Graph_lib::Color c = e.inverted() ? (e ? FALSE_COLOR : TRUE_COLOR)
  330.                                     : (e ? TRUE_COLOR : FALSE_COLOR);
  331.   left_side.set_color(c);
  332.   right_side.set_color(c);
  333. }
  334.  
  335. void XorShape::draw_lines () const
  336. {
  337.   OperatorShape::draw_lines();
  338.  
  339.   left_side.draw();
  340.   right_side.draw();
  341. }
  342.  
  343.  
  344. } // namespace Logic
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement