]> git.tdb.fi Git - r2c2.git/blob - source/designer/zonebar.cpp
Give tools access to the keyboard
[r2c2.git] / source / designer / zonebar.cpp
1 #include <msp/strings/format.h>
2 #include "libr2c2/zone.h"
3 #include "designer.h"
4 #include "zonebar.h"
5
6 using namespace std;
7 using namespace Msp;
8 using namespace R2C2;
9
10 string zone_detail(Zone *const &zone)
11 {
12         return zone ? format("%s %d", zone->get_qualifier(), zone->get_number()) : "(new)";
13 }
14
15 Zonebar::Zonebar(Designer &d):
16         Toolbar("Zone"),
17         designer(d),
18         zones(&zone_detail)
19 {
20         pnl_content->add(*(drp_groups = new GLtk::Dropdown(groups)));
21         drp_groups->set_tooltip("Select zone group to edit");
22         drp_groups->signal_item_selected.connect(sigc::mem_fun(this, &Zonebar::group_selected));
23
24         pnl_content->add(*(drp_numbers = new GLtk::Dropdown(zones)));
25         drp_groups->set_tooltip("Select zone to edit");
26         drp_numbers->signal_item_selected.connect(sigc::mem_fun(this, &Zonebar::number_selected));
27
28         GLtk::Button *btn;
29
30         pnl_content->add(*(btn = new GLtk::Button("Del")));
31         btn->set_style("red");
32         btn->set_tooltip("Delete selected zone");
33         btn->signal_clicked.connect(sigc::mem_fun(this, &Zonebar::delete_zone_clicked));
34
35         pnl_content->add(*(btn = new GLtk::Button("Prop")));
36         btn->set_tooltip("Change properties of the selected zone");
37         btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::zone_properties));
38
39         pnl_content->add(*(btn = new GLtk::Button("AddT")));
40         btn->set_tooltip("Add selected tracks to zone");
41         btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::add_selection_to_zone));
42
43         Layout &rlayout = designer.get_layout();
44         rlayout.signal_track_chain_added.connect(sigc::mem_fun(this, &Zonebar::track_chain_added));
45         rlayout.signal_track_chain_removed.connect(sigc::mem_fun(this, &Zonebar::track_chain_removed));
46
47         const set<Zone *> &lzones = rlayout.get_all<Zone>();
48         set<string> group_names;
49         for(set<Zone *>::const_iterator i=lzones.begin(); i!=lzones.end(); ++i)
50         {
51                 (*i)->signal_name_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Zonebar::zone_renamed), sigc::ref(**i)));
52                 if(!group_names.count((*i)->get_group()))
53                 {
54                         groups.append((*i)->get_group());
55                         group_names.insert((*i)->get_group());
56                 }
57         }
58         groups.append("(new)");
59 }
60
61 void Zonebar::track_chain_added(TrackChain &chain)
62 {
63         if(Zone *zone = dynamic_cast<Zone *>(&chain))
64                 zone->signal_name_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Zonebar::zone_renamed), sigc::ref(*zone)));
65 }
66
67 void Zonebar::track_chain_removed(TrackChain &chain)
68 {
69         if(Zone *zone = dynamic_cast<Zone *>(&chain))
70         {
71                 bool keep_group = false;
72                 const set<Zone *> &lzones = designer.get_layout().get_all<Zone>();
73                 for(set<Zone *>::const_iterator j=lzones.begin(); (!keep_group && j!=lzones.end()); ++j)
74                         keep_group = (*j)->get_group()==zone->get_group();
75
76                 if(!keep_group)
77                 {
78                         for(unsigned i=0; i<groups.size(); ++i)
79                                 if(groups.get(i)==zone->get_group())
80                                 {
81                                         groups.remove(i);
82                                         break;
83                                 }
84                 }
85
86                 for(unsigned i=0; i<zones.size(); ++i)
87                         if(zones.get(i)==zone)
88                         {
89                                 zones.remove(i);
90                                 break;
91                         }
92         }
93 }
94
95 void Zonebar::zone_renamed(Zone &zone, const string &group, const string &, unsigned)
96 {
97         const set<Zone *> &lzones = designer.get_layout().get_all<Zone>();
98         set<string> group_names;
99         for(set<Zone *>::const_iterator i=lzones.begin(); i!=lzones.end(); ++i)
100                 group_names.insert((*i)->get_group());
101
102         bool new_group = true;
103         for(unsigned i=0; i+1<groups.size(); )
104         {
105                 if(group_names.count(groups.get(i)))
106                 {
107                         if(groups.get(i)==group)
108                                 new_group = false;
109                         ++i;
110                 }
111                 else
112                         groups.remove(i);
113         }
114
115         if(new_group)
116                 groups.insert(groups.size()-1, group);
117
118         int sel = drp_groups->get_selected_index();
119         if(sel>=0 && groups.get(sel)==group)
120         {
121                 int i = zones.find(&zone);
122                 if(i<0)
123                         zones.insert(zones.size()-1, &zone);
124                 else
125                         zones.refresh(i);
126         }
127 }
128
129 void Zonebar::group_selected(unsigned index)
130 {
131         if(index==groups.size()-1)
132         {
133                 Zone *zone = new Zone(designer.get_layout());
134                 zone->set_name("New zone", "track", 1);
135
136                 for(unsigned i=0; i<groups.size(); ++i)
137                         if(groups.get(i)=="New zone")
138                         {
139                                 drp_groups->set_selected_index(i);
140                                 break;
141                         }
142
143                 for(unsigned i=0; i<zones.size(); ++i)
144                         if(zones.get(i)==zone)
145                         {
146                                 drp_numbers->set_selected_index(i);
147                                 break;
148                         }
149
150                 designer.edit_zone(zone);
151         }
152         else
153         {
154                 Zone *cur = designer.get_current_zone();
155                 if(cur && groups.get(index)==cur->get_group())
156                         return;
157
158                 designer.edit_zone(0);
159
160                 zones.clear();
161                 Layout::ZoneArray lzones = designer.get_layout().get_zones(groups.get(index));
162                 for(Layout::ZoneArray::iterator i=lzones.begin(); i!=lzones.end(); ++i)
163                         zones.append(*i);
164                 zones.append(0);
165         }
166 }
167
168 void Zonebar::number_selected(unsigned index)
169 {
170         if(drp_groups->get_selected_index()<0)
171                 return;
172
173         string group = groups.get(drp_groups->get_selected_index());
174         if(index==zones.size()-1)
175         {
176                 Zone *cur = designer.get_current_zone();
177                 string qualifier = (cur ? cur->get_qualifier() : "track");
178
179                 Zone *zone = new Zone(designer.get_layout());
180                 zone->set_name(group, qualifier, index+1);
181                 designer.edit_zone(zone);
182
183                 for(unsigned i=0; i<zones.size(); ++i)
184                         if(zones.get(i)==zone)
185                         {
186                                 drp_numbers->set_selected_index(i);
187                                 break;
188                         }
189         }
190         else
191                 designer.edit_zone(zones.get(index));
192 }
193
194 void Zonebar::delete_zone_clicked()
195 {
196         Zone *cur = designer.get_current_zone();
197         designer.edit_zone(0);
198         delete cur;
199 }