1 #include "tool_resize_symbol.hpp"
2 #include "document/idocument_symbol.hpp"
3 #include "pool/symbol.hpp"
4 #include "util/util.hpp"
5 #include "util/util.hpp"
6 #include "util/geom_util.hpp"
7 #include "imp/imp_interface.hpp"
8 
9 namespace horizon {
10 
can_begin()11 bool ToolResizeSymbol::can_begin()
12 {
13     return doc.y;
14 }
15 
begin(const ToolArgs & args)16 ToolResponse ToolResizeSymbol::begin(const ToolArgs &args)
17 {
18 
19     pos_orig = args.coords;
20     const auto &sym = doc.y->get_symbol();
21     for (const auto &it : sym.pins) {
22         positions.emplace(std::piecewise_construct, std::forward_as_tuple(ObjectType::SYMBOL_PIN, it.first),
23                           std::forward_as_tuple(it.second.position));
24     }
25     for (const auto &it : sym.junctions) {
26         positions.emplace(std::piecewise_construct, std::forward_as_tuple(ObjectType::JUNCTION, it.first),
27                           std::forward_as_tuple(it.second.position));
28     }
29     for (const auto &it : sym.texts) {
30         positions.emplace(std::piecewise_construct, std::forward_as_tuple(ObjectType::TEXT, it.first),
31                           std::forward_as_tuple(it.second.placement.shift));
32     }
33     update_positions(args.coords);
34 
35     imp->tool_bar_set_actions({
36             {InToolActionID::LMB, "finish"},
37             {InToolActionID::RMB},
38     });
39 
40     return ToolResponse();
41 }
42 
update_positions(const Coordi & ac)43 void ToolResizeSymbol::update_positions(const Coordi &ac)
44 {
45     auto d = ac - pos_orig;
46     if (pos_orig.y < 0)
47         d.y *= -1;
48     if (pos_orig.x < 0)
49         d.x *= -1;
50     auto c = d + delta_key;
51     imp->tool_bar_set_tip(coord_to_string(c, true));
52     auto &sym = doc.y->get_symbol();
53     for (auto &it : sym.pins) {
54         const auto k = std::make_pair(ObjectType::SYMBOL_PIN, it.first);
55         const auto &p = positions.at(k);
56         switch (it.second.orientation) {
57         case Orientation::RIGHT:
58             it.second.position = p + Coordi(c.x, 0);
59             break;
60         case Orientation::LEFT:
61             it.second.position = p + Coordi(-c.x, 0);
62             break;
63         case Orientation::UP:
64             it.second.position = p + Coordi(0, c.y);
65             break;
66         case Orientation::DOWN:
67             it.second.position = p + Coordi(0, -c.y);
68             break;
69         }
70     }
71     for (auto &it : sym.junctions) {
72         const auto k = std::make_pair(ObjectType::JUNCTION, it.first);
73         const auto &p = positions.at(k);
74         if (p.x > 0 && p.y > 0) {
75             it.second.position = p + Coordi(c.x, c.y);
76         }
77         else if (p.x > 0 && p.y < 0) {
78             it.second.position = p + Coordi(c.x, -c.y);
79         }
80         else if (p.x < 0 && p.y < 0) {
81             it.second.position = p + Coordi(-c.x, -c.y);
82         }
83         else if (p.x < 0 && p.y > 0) {
84             it.second.position = p + Coordi(-c.x, c.y);
85         }
86     }
87     for (auto &it : sym.texts) {
88         const auto k = std::make_pair(ObjectType::TEXT, it.first);
89         const auto &p = positions.at(k);
90         if (p.y > 0) {
91             it.second.placement.shift = p + Coordi(0, c.y);
92         }
93         else {
94             it.second.placement.shift = p + Coordi(0, -c.y);
95         }
96     }
97 }
98 
update(const ToolArgs & args)99 ToolResponse ToolResizeSymbol::update(const ToolArgs &args)
100 {
101     if (args.type == ToolEventType::MOVE) {
102         update_positions(args.coords);
103     }
104     else if (args.type == ToolEventType::ACTION) {
105         switch (args.action) {
106         case InToolActionID::LMB:
107             return ToolResponse::commit();
108 
109         case InToolActionID::RMB:
110         case InToolActionID::CANCEL:
111             return ToolResponse::revert();
112 
113         default: {
114             const auto [dir, fine] = dir_from_action(args.action);
115             if (dir.x || dir.y) {
116                 delta_key += dir * 1.25_mm;
117                 update_positions(args.coords);
118             }
119         };
120         }
121     }
122     return ToolResponse();
123 }
124 } // namespace horizon
125