]> git.tdb.fi Git - r2c2.git/commitdiff
Further adjustments to changes in GLtk
authorMikko Rasa <tdb@tdb.fi>
Mon, 1 Jul 2013 10:44:06 +0000 (13:44 +0300)
committerMikko Rasa <tdb@tdb.fi>
Mon, 1 Jul 2013 10:44:06 +0000 (13:44 +0300)
Layout subclasses were transformed to Arrangements, and Lists and
Dropdowns work a bit differently.

r2c2.res
source/designer/input.cpp
source/designer/routebar.cpp
source/designer/routebar.h
source/designer/toolbar.cpp
source/designer/trackproperties.cpp
source/designer/zonebar.cpp
source/designer/zonebar.h
source/designer/zoneproperties.cpp

index d16f555e6bd452cca7a74620d62946705f39f4d6..20bae38b1c41ce7910a79e995822b8f453d29a3e 100644 (file)
--- a/r2c2.res
+++ b/r2c2.res
@@ -463,20 +463,11 @@ graphic "selection"
 
 style "list"
 {
-       font_color 0.0 0.0 0.0;
-
        part
        {
                graphic NORMAL "sunken_white_bg";
        };
 
-       part "selection"
-       {
-               graphic NORMAL "selection";
-               fill 1.0 1.0;
-               margin { vertical 2; right 13; left 2; };
-       };
-
        part "items"
        {
                margin { vertical 2; right 13; left 2; };
@@ -491,6 +482,20 @@ style "list"
        };
 };
 
+style "listitem"
+{
+       part
+       {
+               graphic ACTIVE "selection";
+               fill 1.0 1.0;
+       };
+
+       part "children"
+       {
+               margin { vertical 1; horizontal 2; };
+       };
+};
+
 style "dropdown"
 {
        font_color 0.0 0.0 0.0;
index 18b14a573bcad9754407c00525abc482b468c37e..acfa8bd00dd7e8041ba4633daee7c7b34ac85baa 100644 (file)
@@ -1,7 +1,8 @@
 #include <GL/gl.h>
 #include <msp/gl/texture.h>
 #include <msp/gltk/button.h>
-#include <msp/gltk/mixedrows.h>
+#include <msp/gltk/column.h>
+#include <msp/gltk/row.h>
 #include <msp/input/keys.h>
 #include "designer.h"
 #include "input.h"
@@ -12,27 +13,27 @@ using namespace Msp;
 InputDialog::InputDialog(Designer &d, const string &title, const string &text):
        designer(d)
 {
-       GLtk::MixedRows *rows = new GLtk::MixedRows;
-       set_layout(rows);
+       set_layout(new GLtk::Layout);
+       GLtk::Column col(*layout);
 
        GLtk::Label *lbl;
        add(*(lbl=new GLtk::Label(title)));
-       layout->set_expand(*lbl, true, false);
        lbl->set_style("title");
 
-       rows->start_row();
        add(*(entry=new GLtk::Entry(text)));
        entry->set_edit_size(60, 1);
 
        GLtk::Button *btn;
 
-       rows->start_row();
-       rows->split_columns();
-       add_button(*(btn=new GLtk::Button("Cncl")), 0);
-       btn->set_style("red");
+       {
+               GLtk::Row row(*layout);
+               row.split();
+               add_button(*(btn=new GLtk::Button("Cncl")), 0);
+               btn->set_style("red");
 
-       add_button(*(btn=new GLtk::Button("OK")), 1);
-       btn->set_style("green");
+               add_button(*(btn=new GLtk::Button("OK")), 1);
+               btn->set_style("green");
+       }
 
        entry->set_focus();
 }
index 9726b2e88f8c853a05f995483e68eafefe67cc4f..ef9eb4891bda896d861f8de9fa2f9aaad9e10ae6 100644 (file)
@@ -7,13 +7,18 @@ using namespace std;
 using namespace Msp;
 using namespace R2C2;
 
+string route_name(Route *const &route)
+{
+       return route ? route->get_name() : "(new route)";
+}
+
 Routebar::Routebar(Designer &d):
        Toolbar("Route"),
-       designer(d)
+       designer(d),
+       routes(&route_name)
 {
-       pnl_content->add(*(drp_routes = new GLtk::Dropdown));
+       pnl_content->add(*(drp_routes = new GLtk::Dropdown(routes)));
        drp_routes->set_tooltip("Select route to edit");
-       drp_routes->append("(new route)");
        drp_routes->signal_item_selected.connect(sigc::mem_fun(this, &Routebar::route_selected));
 
        GLtk::Button *btn;
@@ -32,39 +37,33 @@ Routebar::Routebar(Designer &d):
        btn->signal_clicked.connect(sigc::mem_fun(&designer, &Designer::add_selection_to_route));
 
        designer.get_layout().signal_track_chain_added.connect(sigc::mem_fun(this, &Routebar::track_chain_added));
-       designer.get_layout().signal_track_chain_removed.connect(sigc::hide(sigc::mem_fun(this, &Routebar::update_routes)));
+       designer.get_layout().signal_track_chain_removed.connect(sigc::mem_fun(this, &Routebar::track_chain_removed));
 
-       const set<Route *> &routes = designer.get_layout().get_all<Route>();
-       for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i)
-               (*i)->signal_name_changed.connect(sigc::hide(sigc::mem_fun(this, &Routebar::update_routes)));
+       const set<Route *> &lroutes = designer.get_layout().get_all<Route>();
+       for(set<Route *>::const_iterator i=lroutes.begin(); i!=lroutes.end(); ++i)
+       {
+               routes.append(*i);
+               (*i)->signal_name_changed.connect(sigc::bind(sigc::mem_fun(this, &Routebar::route_name_changed), *i));
+       }
 
-       update_routes();
+       routes.append(0);
 }
 
-void Routebar::route_selected(unsigned index, const string &)
+void Routebar::route_selected(unsigned index)
 {
-       if(index==drp_routes->get_n_items()-1)
+       if(index==routes.size()-1)
        {
                Layout &rlayout = designer.get_layout();
                Route *route = new Route(rlayout);
-               const set<Route *> &routes = rlayout.get_all<Route>();
-               route->set_name(format("Route %d", routes.size()));
+               route->set_name(format("Route %d", index+1));
                designer.edit_route(route);
 
-               int selected = -1;
-               unsigned n = 0;
-               for(set<Route *>::const_iterator i=routes.begin(); (selected<0 && i!=routes.end()); ++i, ++n)
-                       if(*i==route)
-                               selected = n;
-               drp_routes->set_selected_index(selected);
+               for(unsigned i=0; i<routes.size(); ++i)
+                       if(routes.get(i)==route)
+                               drp_routes->set_selected_index(i);
        }
        else
-       {
-               const set<Route *> &routes = designer.get_layout().get_all<Route>();
-               set<Route *>::const_iterator i = routes.begin();
-               advance(i, index);
-               designer.edit_route(*i);
-       }
+               designer.edit_route(routes.get(index));
 }
 
 void Routebar::delete_route_clicked()
@@ -78,23 +77,25 @@ void Routebar::track_chain_added(TrackChain &tc)
 {
        if(Route *r = dynamic_cast<Route *>(&tc))
        {
-               r->signal_name_changed.connect(sigc::hide(sigc::mem_fun(this, &Routebar::update_routes)));
-               update_routes();
+               r->signal_name_changed.connect(sigc::bind(sigc::mem_fun(this, &Routebar::route_name_changed), r));
+               routes.insert(routes.size()-1, r);
        }
 }
 
-void Routebar::update_routes()
+void Routebar::track_chain_removed(TrackChain &tc)
 {
-       drp_routes->clear();
-       const set<Route *> &routes = designer.get_layout().get_all<Route>();
-       int selected = -1;
-       unsigned n = 0;
-       for(set<Route *>::const_iterator i=routes.begin(); i!=routes.end(); ++i, ++n)
+       if(Route *r = dynamic_cast<Route *>(&tc))
        {
-               drp_routes->append((*i)->get_name());
-               if(*i==designer.get_current_route())
-                       selected = n;
+               for(unsigned i=0; i<routes.size(); ++i)
+                       if(routes.get(i)==r)
+                       {
+                               routes.remove(i);
+                               break;
+                       }
        }
-       drp_routes->append("(new route)");
-       drp_routes->set_selected_index(selected);
+}
+
+void Routebar::route_name_changed(const string &, Route *route)
+{
+       routes.refresh(route);
 }
index e3698ebc0d08b55ba4c72b8840ab298e5c7e1f07..b2c9c8daeacded6241de9bac05c1b62525c4cb00 100644 (file)
@@ -8,16 +8,18 @@ class Routebar: public Toolbar, public sigc::trackable
 {
 private:
        Designer &designer;
+       Msp::GLtk::FunctionListData<R2C2::Route *> routes;
        Msp::GLtk::Dropdown *drp_routes;
 
 public:
        Routebar(Designer &);
 
 private:
-       void route_selected(unsigned, const std::string &);
+       void route_selected(unsigned);
        void delete_route_clicked();
        void track_chain_added(R2C2::TrackChain &);
-       void update_routes();
+       void track_chain_removed(R2C2::TrackChain &);
+       void route_name_changed(const std::string &, R2C2::Route *);
 };
 
 #endif
index 559d8c3e9e13636c07d0dcbfcf34f266e813d8d0..f970607fc054b97879950dda94179c5db6c1e818 100644 (file)
@@ -8,7 +8,8 @@ Toolbar::Toolbar(const string &name):
        expanded(true)
 {
        set_focusable(false);
-       set_layout(new GLtk::Row);
+       set_layout(new GLtk::Layout);
+       GLtk::Row row(*layout);
        layout->set_margin(GLtk::Sides(6, 10));
        layout->set_column_spacing(10);
 
@@ -21,7 +22,9 @@ Toolbar::Toolbar(const string &name):
 
        add(*(pnl_content = new GLtk::Panel));
        pnl_content->set_style("group");
-       GLtk::Layout *content_layout = new GLtk::Row;
+       GLtk::Layout *content_layout = new GLtk::Layout;
+       // XXX This needs to get deleted somehow
+       new GLtk::Row(*content_layout);
        pnl_content->set_layout(content_layout);
        content_layout->set_margin(0);
 }
index b85a99ae76e6459247f2f2719a0c17e287c0802d..c95ad02887f24d3bd99868aa7a6a6a83afe73253 100644 (file)
@@ -1,6 +1,7 @@
 #include <msp/gltk/button.h>
+#include <msp/gltk/column.h>
 #include <msp/gltk/label.h>
-#include <msp/gltk/mixedrows.h>
+#include <msp/gltk/row.h>
 #include "libr2c2/track.h"
 #include "libr2c2/tracktype.h"
 #include "selection.h"
@@ -13,35 +14,40 @@ using namespace R2C2;
 TrackProperties::TrackProperties(const Selection &s):
        selection(s)
 {
-       GLtk::MixedRows *rows = new GLtk::MixedRows;
-       set_layout(rows);
+       set_layout(new GLtk::Layout);
+       GLtk::Column col(*layout);
 
        GLtk::Label *lbl1, *lbl2;
 
        add(*(lbl1 = new GLtk::Label("Track properties")));
-       layout->set_expand(*lbl1, true, false);
        lbl1->set_style("title");
 
-       rows->start_row();
-       add(*(lbl1 = new GLtk::Label("Turnout ID")));
-       add(*(ent_turnout_id = new GLtk::Entry));
-       ent_turnout_id->set_edit_size(5, 1);
+       {
+               GLtk::Row row(*layout);
+               add(*(lbl1 = new GLtk::Label("Turnout ID")));
+               add(*(ent_turnout_id = new GLtk::Entry));
+               ent_turnout_id->set_edit_size(5, 1);
+       }
 
-       rows->start_row();
-       add(*(lbl2 = new GLtk::Label("Sensor ID")));
-       rows->add_constraint(*lbl1, GLtk::Layout::COPY_WIDTH, *lbl2);
-       add(*(ent_sensor_id = new GLtk::Entry));
-       ent_sensor_id->set_edit_size(5, 1);
+       {
+               GLtk::Row row(*layout);
+               add(*(lbl2 = new GLtk::Label("Sensor ID")));
+               layout->add_constraint(*lbl1, GLtk::Layout::COPY_WIDTH, *lbl2);
+               add(*(ent_sensor_id = new GLtk::Entry));
+               ent_sensor_id->set_edit_size(5, 1);
+       }
 
        GLtk::Button *btn;
 
-       rows->start_row();
-       rows->split_columns();
-       add_button(*(btn = new GLtk::Button("Cncl")), 0);
-       btn->set_style("red");
+       {
+               GLtk::Row row(*layout);
+               row.split();
+               add_button(*(btn = new GLtk::Button("Cncl")), 0);
+               btn->set_style("red");
 
-       add_button(*(btn = new GLtk::Button("OK")), 1);
-       btn->set_style("green");
+               add_button(*(btn = new GLtk::Button("OK")), 1);
+               btn->set_style("green");
+       }
 
        if(selection.size()==1)
        {
index 058b2d1d580111f524a880e794f7b58d08ce6db2..f97554c8048c6937e87ded369fe5d11023acc2de 100644 (file)
@@ -7,15 +7,21 @@ using namespace std;
 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"),
-       designer(d)
+       designer(d),
+       zones(&zone_detail)
 {
-       pnl_content->add(*(drp_groups = new GLtk::Dropdown));
+       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));
+       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));
 
@@ -36,71 +42,153 @@ Zonebar::Zonebar(Designer &d):
 
        Layout &rlayout = designer.get_layout();
        rlayout.signal_track_chain_added.connect(sigc::mem_fun(this, &Zonebar::track_chain_added));
-       rlayout.signal_track_chain_removed.connect(sigc::hide(sigc::mem_fun(this, &Zonebar::update_groups)));
+       rlayout.signal_track_chain_removed.connect(sigc::mem_fun(this, &Zonebar::track_chain_removed));
 
-       const set<Zone *> &zones = rlayout.get_all<Zone>();
-       for(set<Zone *>::const_iterator i=zones.begin(); i!=zones.end(); ++i)
-               (*i)->signal_name_changed.connect(sigc::mem_fun(this, &Zonebar::zone_renamed));
-
-       update_groups();
+       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)");
 }
 
 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::track_chain_removed(TrackChain &chain)
 {
        if(Zone *zone = dynamic_cast<Zone *>(&chain))
        {
-               zone->signal_name_changed.connect(sigc::mem_fun(this, &Zonebar::zone_renamed));
-               update_groups();
+               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 &group, const string &, unsigned)
 {
-       update_groups();
+       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()
@@ -109,48 +197,3 @@ void Zonebar::delete_zone_clicked()
        designer.edit_zone(0);
        delete cur;
 }
-
-void Zonebar::update_groups()
-{
-       const set<Zone *> &zones = designer.get_layout().get_all<Zone>();
-       set<string> groups;
-       for(set<Zone *>::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);
-}
index 8a0b3098ab451c41087f124807aa28007cfc3086..13ffbe2619b109f18d5828aca266d3bb320c5630 100644 (file)
@@ -10,7 +10,9 @@ class Zonebar: public Toolbar, public sigc::trackable
 {
 private:
        Designer &designer;
+       Msp::GLtk::BasicListData<std::string> groups;
        Msp::GLtk::Dropdown *drp_groups;
+       Msp::GLtk::FunctionListData<R2C2::Zone *> zones;
        Msp::GLtk::Dropdown *drp_numbers;
 
 public:
@@ -18,12 +20,11 @@ public:
 
 private:
        void track_chain_added(R2C2::TrackChain &);
-       void zone_renamed(const std::string &, const std::string &, unsigned);
-       void group_selected(unsigned, const std::string &);
-       void number_selected(unsigned, const std::string &);
+       void track_chain_removed(R2C2::TrackChain &);
+       void zone_renamed(R2C2::Zone &, const std::string &, const std::string &, unsigned);
+       void group_selected(unsigned);
+       void number_selected(unsigned);
        void delete_zone_clicked();
-       void update_groups();
-       void update_numbers(const std::string &);
 };
 
 #endif
index 406ebee1cbdc46bfa6f306e94e7dd150b8476d1e..6ea4f2a330fc1a4b115a597933b01ede9813968d 100644 (file)
@@ -1,6 +1,7 @@
 #include <msp/gltk/button.h>
+#include <msp/gltk/column.h>
 #include <msp/gltk/label.h>
-#include <msp/gltk/mixedrows.h>
+#include <msp/gltk/row.h>
 #include "zoneproperties.h"
 
 using namespace std;
@@ -10,48 +11,56 @@ using namespace R2C2;
 ZoneProperties::ZoneProperties(Zone &z):
        zone(z)
 {
-       GLtk::MixedRows *rows = new GLtk::MixedRows;
-       set_layout(rows);
+       set_layout(new GLtk::Layout);
+       GLtk::Column col(*layout);
 
        GLtk::Label *lbl1, *lbl2;
 
        add(*(lbl1 = new GLtk::Label("Zone properties")));
-       layout->set_expand(*lbl1, true, false);
        lbl1->set_style("title");
 
-       rows->start_row();
-       add(*(lbl1 = new GLtk::Label("Group")));
-       add(*(ent_group = new GLtk::Entry(zone.get_group())));
-       ent_group->set_edit_size(30, 1);
-
-       rows->start_row();
-       add(*(lbl2 = new GLtk::Label("Qualifier")));
-       rows->add_constraint(*lbl1, GLtk::Layout::COPY_WIDTH, *lbl2);
+       {
+               GLtk::Row row(*layout);
+               add(*(lbl1 = new GLtk::Label("Group")));
+               add(*(ent_group = new GLtk::Entry(zone.get_group())));
+               ent_group->set_edit_size(30, 1);
+       }
 
-       add(*(drp_qualifier = new GLtk::Dropdown));
-       const char *qualifiers[] = { "track", "platform", "siding", 0 };
-       for(unsigned i=0; qualifiers[i]; ++i)
        {
-               drp_qualifier->append(qualifiers[i]);
-               if(zone.get_qualifier()==qualifiers[i])
-                       drp_qualifier->set_selected_index(i);
+               GLtk::Row row(*layout);
+               add(*(lbl2 = new GLtk::Label("Qualifier")));
+               layout->add_constraint(*lbl1, GLtk::Layout::COPY_WIDTH, *lbl2);
+
+               add(*(drp_qualifier = new GLtk::Dropdown));
+               GLtk::ListDataStore<string> &data = dynamic_cast<GLtk::ListDataStore<string> &>(drp_qualifier->get_data());
+               const char *qualifiers[] = { "track", "platform", "siding", 0 };
+               for(unsigned i=0; qualifiers[i]; ++i)
+               {
+                       data.append(qualifiers[i]);
+                       if(zone.get_qualifier()==qualifiers[i])
+                               drp_qualifier->set_selected_index(i);
+               }
        }
 
-       rows->start_row();
-       add(*(lbl1 = new GLtk::Label("Number")));
-       rows->add_constraint(*lbl1, GLtk::Layout::COPY_WIDTH, *lbl2);
-       add(*(ent_number = new GLtk::Entry(lexical_cast<string>(zone.get_number()))));
-       ent_number->set_edit_size(4, 1);
+       {
+               GLtk::Row row(*layout);
+               add(*(lbl1 = new GLtk::Label("Number")));
+               layout->add_constraint(*lbl1, GLtk::Layout::COPY_WIDTH, *lbl2);
+               add(*(ent_number = new GLtk::Entry(lexical_cast<string>(zone.get_number()))));
+               ent_number->set_edit_size(4, 1);
+       }
 
        GLtk::Button *btn;
 
-       rows->start_row();
-       rows->split_columns();
-       add_button(*(btn = new GLtk::Button("Cncl")), 0);
-       btn->set_style("red");
+       {
+               GLtk::Row row(*layout);
+               row.split();
+               add_button(*(btn = new GLtk::Button("Cncl")), 0);
+               btn->set_style("red");
 
-       add_button(*(btn = new GLtk::Button("OK")), 1);
-       btn->set_style("green");
+               add_button(*(btn = new GLtk::Button("OK")), 1);
+               btn->set_style("green");
+       }
 }
 
 void ZoneProperties::on_response(int code)
@@ -59,8 +68,9 @@ void ZoneProperties::on_response(int code)
        if(code==1)
        {
                string qualifier;
-               if(drp_qualifier->get_selected_index()>=0)
-                       qualifier = drp_qualifier->get_selected();
+               int sel = drp_qualifier->get_selected_index();
+               if(sel>=0)
+                       qualifier = drp_qualifier->get_data().get_string(sel);
                unsigned number = lexical_cast<unsigned>(ent_number->get_text());
                zone.set_name(ent_group->get_text(), qualifier, number);
        }