]> git.tdb.fi Git - r2c2.git/blob - source/designer/manipulator.cpp
Split the Manipulator class into several Tools
[r2c2.git] / source / designer / manipulator.cpp
1 #include <algorithm>
2 #include <cmath>
3 #include <msp/strings/format.h>
4 #include "libr2c2/tracktype.h"
5 #include "designer.h"
6 #include "manipulator.h"
7 #include "selection.h"
8
9 using namespace std;
10 using namespace R2C2;
11 using namespace Msp;
12
13 Manipulator::Manipulator(Designer &d, Input::Mouse &m, const set<Object *> &objs):
14         Tool(d, m),
15         accepted(false)
16 {
17         set<Object *> pending = objs;
18         while(!pending.empty())
19         {
20                 for(set<Object *>::iterator i=pending.begin(); i!=pending.end(); )
21                 {
22                         if((*i)->get_parent() && pending.count((*i)->get_parent()))
23                                 ++i;
24                         else
25                         {
26                                 objects.push_back(*i);
27                                 pending.erase(i++);
28                         }
29                 }
30         }
31
32         Geometry::BoundingBox<float, 3> bbox;
33         for(vector<MObject>::iterator i=objects.begin(); i!=objects.end(); ++i)
34                 bbox = bbox|i->object->get_bounding_box();
35
36         const Vector &minp = bbox.get_minimum_point();
37         const Vector &maxp = bbox.get_maximum_point();
38
39         center = (minp+maxp)/2.0f;
40         center.z = minp.z;
41         for(ObjectArray::iterator i=objects.begin(); i!=objects.end(); ++i)
42         {
43                 i->original_position = i->object->get_position()-center;
44                 i->original_rotation = i->object->get_rotation();
45         }
46 }
47
48 Manipulator::~Manipulator()
49 {
50         if(!accepted)
51         {
52                 for(ObjectArray::iterator i=objects.begin(); i!=objects.end(); ++i)
53                 {
54                         i->object->set_position(center+i->original_position);
55                         i->object->set_rotation(i->original_rotation);
56                 }
57         }
58 }
59
60 void Manipulator::button_press(unsigned btn)
61 {
62         if(btn==3)
63                 set_done();
64         else if(btn==1)
65         {
66                 set<Object *> object_set;
67                 for(ObjectArray::iterator i=objects.begin(); i!=objects.end(); ++i)
68                         object_set.insert(i->object);
69                 for(ObjectArray::iterator i=objects.begin(); i!=objects.end(); ++i)
70                 {
71                         unsigned nls = i->object->get_n_link_slots();
72                         for(unsigned j=0; j<nls; ++j)
73                                 if(Object *link = i->object->get_link(j))
74                                         if(!object_set.count(link))
75                                                 i->object->break_link(j);
76                 }
77
78                 const set<Track *> &ltracks = designer.get_layout().get_all<Track>();
79                 for(set<Track *>::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
80                 {
81                         bool ok = true;
82                         for(vector<MObject>::iterator j=objects.begin(); (j!=objects.end() && ok); ++j)
83                                 ok = (j->object!=*i);
84                         if(!ok) continue;
85
86                         for(vector<MObject>::iterator j=objects.begin(); j!=objects.end(); ++j)
87                                 j->object->link_to(**i);
88                 }
89
90                 accepted = true;
91                 set_done();
92         }
93 }
94
95
96 Manipulator::MObject::MObject(Object *o):
97         object(o),
98         original_position(object->get_position()),
99         original_rotation(object->get_rotation())
100 { }