-/* $Id$
-
-This file is part of R²C²
-Copyright © 2010-2011 Mikkosoft Productions, Mikko Rasa
-Distributed under the GPL
-*/
-
-#include <msp/strings/formatter.h>
+#include <msp/strings/format.h>
#include "libr2c2/zone.h"
#include "designer.h"
#include "zonebar.h"
using namespace Msp;
using namespace R2C2;
+string zone_detail(Zone *const &zone)
+{
+ return zone ? format("%s %d", zone->get_qualifier(), zone->get_number()) : "(new)";
+}
+
Zonebar::Zonebar(Designer &d):
- Toolbar("Zone", 420),
- designer(d)
+ Toolbar("Zone"),
+ designer(d),
+ zones(&zone_detail)
{
- pnl_content->add(*(drp_groups = new GLtk::Dropdown));
- drp_groups->set_geometry(GLtk::Geometry(0, 10, 195, 20));
+ pnl_content->add(*(drp_groups = new GLtk::Dropdown(groups)));
drp_groups->set_tooltip("Select zone group to edit");
drp_groups->signal_item_selected.connect(sigc::mem_fun(this, &Zonebar::group_selected));
- pnl_content->add(*(drp_numbers = new GLtk::Dropdown));
- drp_numbers->set_geometry(GLtk::Geometry(200, 10, 100, 20));
+ pnl_content->add(*(drp_numbers = new GLtk::Dropdown(zones)));
drp_groups->set_tooltip("Select zone to edit");
drp_numbers->signal_item_selected.connect(sigc::mem_fun(this, &Zonebar::number_selected));
GLtk::Button *btn;
pnl_content->add(*(btn = new GLtk::Button("Del")));
- btn->set_geometry(GLtk::Geometry(300, 10, 40, 24));
btn->set_style("red");
btn->set_tooltip("Delete selected zone");
btn->signal_clicked.connect(sigc::mem_fun(this, &Zonebar::delete_zone_clicked));
pnl_content->add(*(btn = new GLtk::Button("Prop")));
- btn->set_geometry(GLtk::Geometry(340, 10, 40, 24));
btn->set_tooltip("Change properties of the selected zone");
btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::zone_properties));
pnl_content->add(*(btn = new GLtk::Button("AddT")));
- btn->set_geometry(GLtk::Geometry(380, 10, 40, 24));
btn->set_tooltip("Add selected tracks to zone");
btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::add_selection_to_zone));
Layout &rlayout = designer.get_layout();
- rlayout.signal_zone_added.connect(sigc::mem_fun(this, &Zonebar::zone_added));
- rlayout.signal_zone_removed.connect(sigc::hide(sigc::mem_fun(this, &Zonebar::update_groups)));
+ rlayout.signal_track_chain_added.connect(sigc::mem_fun(this, &Zonebar::track_chain_added));
+ rlayout.signal_track_chain_removed.connect(sigc::mem_fun(this, &Zonebar::track_chain_removed));
- const Layout::ZoneSet &zones = rlayout.get_zones();
- for(Layout::ZoneSet::const_iterator i=zones.begin(); i!=zones.end(); ++i)
- (*i)->signal_name_changed.connect(sigc::mem_fun(this, &Zonebar::zone_renamed));
+ const set<Zone *> &lzones = rlayout.get_all<Zone>();
+ set<string> group_names;
+ for(set<Zone *>::const_iterator i=lzones.begin(); i!=lzones.end(); ++i)
+ {
+ (*i)->signal_name_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Zonebar::zone_renamed), sigc::ref(**i)));
+ if(!group_names.count((*i)->get_group()))
+ {
+ groups.append((*i)->get_group());
+ group_names.insert((*i)->get_group());
+ }
+ }
+ groups.append("(new)");
+}
- update_groups();
+void Zonebar::track_chain_added(TrackChain &chain)
+{
+ if(Zone *zone = dynamic_cast<Zone *>(&chain))
+ zone->signal_name_changed.connect(sigc::bind<0>(sigc::mem_fun(this, &Zonebar::zone_renamed), sigc::ref(*zone)));
}
-void Zonebar::zone_added(Zone &zone)
+void Zonebar::track_chain_removed(TrackChain &chain)
{
- zone.signal_name_changed.connect(sigc::mem_fun(this, &Zonebar::zone_renamed));
- update_groups();
+ if(Zone *zone = dynamic_cast<Zone *>(&chain))
+ {
+ bool keep_group = false;
+ const set<Zone *> &lzones = designer.get_layout().get_all<Zone>();
+ for(set<Zone *>::const_iterator j=lzones.begin(); (!keep_group && j!=lzones.end()); ++j)
+ keep_group = (*j)->get_group()==zone->get_group();
+
+ if(!keep_group)
+ {
+ for(unsigned i=0; i<groups.size(); ++i)
+ if(groups.get(i)==zone->get_group())
+ {
+ groups.remove(i);
+ break;
+ }
+ }
+
+ for(unsigned i=0; i<zones.size(); ++i)
+ if(zones.get(i)==zone)
+ {
+ zones.remove(i);
+ break;
+ }
+ }
}
-void Zonebar::zone_renamed(const string &, const string &, unsigned)
+void Zonebar::zone_renamed(Zone &zone, const string &)
{
- update_groups();
+ const string &group = zone.get_group();
+ const set<Zone *> &lzones = designer.get_layout().get_all<Zone>();
+ set<string> group_names;
+ for(set<Zone *>::const_iterator i=lzones.begin(); i!=lzones.end(); ++i)
+ group_names.insert((*i)->get_group());
+
+ bool new_group = true;
+ for(unsigned i=0; i+1<groups.size(); )
+ {
+ if(group_names.count(groups.get(i)))
+ {
+ if(groups.get(i)==group)
+ new_group = false;
+ ++i;
+ }
+ else
+ groups.remove(i);
+ }
+
+ if(new_group)
+ groups.insert(groups.size()-1, group);
+
+ int sel = drp_groups->get_selected_index();
+ if(sel>=0 && groups.get(sel)==group)
+ {
+ int i = zones.find(&zone);
+ if(i<0)
+ zones.insert(zones.size()-1, &zone);
+ else
+ zones.refresh(i);
+ }
}
-void Zonebar::group_selected(unsigned index, const string &group)
+void Zonebar::group_selected(unsigned index)
{
- if(index==drp_groups->get_n_items()-1)
+ if(index==groups.size()-1)
{
Zone *zone = new Zone(designer.get_layout());
zone->set_name("New zone", "track", 1);
+
+ for(unsigned i=0; i<groups.size(); ++i)
+ if(groups.get(i)=="New zone")
+ {
+ drp_groups->set_selected_index(i);
+ break;
+ }
+
+ for(unsigned i=0; i<zones.size(); ++i)
+ if(zones.get(i)==zone)
+ {
+ drp_numbers->set_selected_index(i);
+ break;
+ }
+
designer.edit_zone(zone);
- update_groups();
}
else
{
Zone *cur = designer.get_current_zone();
- if(cur && group==cur->get_group())
+ if(cur && groups.get(index)==cur->get_group())
return;
designer.edit_zone(0);
- update_numbers(group);
+
+ zones.clear();
+ Layout::ZoneArray lzones = designer.get_layout().get_zones(groups.get(index));
+ for(Layout::ZoneArray::iterator i=lzones.begin(); i!=lzones.end(); ++i)
+ zones.append(*i);
+ zones.append(0);
}
}
-void Zonebar::number_selected(unsigned index, const string &)
+void Zonebar::number_selected(unsigned index)
{
if(drp_groups->get_selected_index()<0)
return;
- string group = drp_groups->get_selected();
- Layout::ZoneArray zones = designer.get_layout().get_zones(group);
- if(index==drp_numbers->get_n_items()-1)
+ string group = groups.get(drp_groups->get_selected_index());
+ if(index==zones.size()-1)
{
Zone *cur = designer.get_current_zone();
string qualifier = (cur ? cur->get_qualifier() : "track");
Zone *zone = new Zone(designer.get_layout());
- zone->set_name(group, qualifier, zones.size()+1);
+ zone->set_name(group, qualifier, index+1);
designer.edit_zone(zone);
- if(cur)
- update_numbers(group);
- else
- update_groups();
+
+ for(unsigned i=0; i<zones.size(); ++i)
+ if(zones.get(i)==zone)
+ {
+ drp_numbers->set_selected_index(i);
+ break;
+ }
}
- else if(index<zones.size())
- designer.edit_zone(zones[index]);
+ else
+ designer.edit_zone(zones.get(index));
}
void Zonebar::delete_zone_clicked()
designer.edit_zone(0);
delete cur;
}
-
-void Zonebar::update_groups()
-{
- const Layout::ZoneSet &zones = designer.get_layout().get_zones();
- set<string> groups;
- for(Layout::ZoneSet::const_iterator i=zones.begin(); i!=zones.end(); ++i)
- groups.insert((*i)->get_group());
-
- Zone *cur = designer.get_current_zone();
-
- drp_groups->clear();
- int selected = -1;
- unsigned n = 0;
- for(set<string>::iterator i=groups.begin(); i!=groups.end(); ++i, ++n)
- {
- drp_groups->append(*i);
- if(cur && *i==cur->get_group())
- selected = n;
- }
- drp_groups->append("(new)");
- drp_groups->set_selected_index(selected);
-
- if(cur)
- update_numbers(cur->get_group());
- else
- drp_numbers->clear();
-}
-
-void Zonebar::update_numbers(const string &group)
-{
- Layout::ZoneArray zones = designer.get_layout().get_zones(group);
- Zone *cur = designer.get_current_zone();
-
- drp_numbers->clear();
- int selected = -1;
- unsigned n = 0;
- for(Layout::ZoneArray::iterator i=zones.begin(); i!=zones.end(); ++i, ++n)
- {
- drp_numbers->append(format("%s %d", (*i)->get_qualifier(), (*i)->get_number()));
- if(cur && *i==cur)
- selected = n;
- }
- drp_numbers->append("(new)");
- drp_numbers->set_selected_index(selected);
-}