1 #include "unplaced_box.hpp"
2 #include <algorithm>
3 #include <iostream>
4 #include "util/util.hpp"
5 
6 namespace horizon {
UnplacedBox(const std::string & title)7 UnplacedBox::UnplacedBox(const std::string &title) : Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL, 0)
8 {
9     auto *la = Gtk::manage(new Gtk::Label());
10     la->set_markup("<b>Unplaced</b>");
11     la->show();
12     pack_start(*la, false, false, 0);
13 
14 
15     store = Gtk::ListStore::create(list_columns);
16     store->set_sort_column(list_columns.text, Gtk::SORT_ASCENDING);
17     store->set_sort_func(list_columns.text,
18                          [this](const Gtk::TreeModel::iterator &ia, const Gtk::TreeModel::iterator &ib) {
19                              Gtk::TreeModel::Row ra = *ia;
20                              Gtk::TreeModel::Row rb = *ib;
21                              Glib::ustring a = ra[list_columns.text];
22                              Glib::ustring b = rb[list_columns.text];
23                              return strcmp_natural(a, b);
24                          });
25     view = Gtk::manage(new Gtk::TreeView(store));
26     view->get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
27     view->set_rubber_banding(true);
28     view->append_column(title, list_columns.text);
29     view->get_column(0)->set_sort_column(list_columns.text);
30     view->get_selection()->signal_changed().connect(
31             [this] { button_place->set_sensitive(view->get_selection()->count_selected_rows()); });
32     view->show();
33 
34     auto sc = Gtk::manage(new Gtk::ScrolledWindow());
35     sc->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
36     sc->set_shadow_type(Gtk::SHADOW_IN);
37     sc->set_min_content_height(150);
38     sc->set_propagate_natural_height(true);
39     sc->add(*view);
40     sc->show_all();
41 
42     view->signal_row_activated().connect(sigc::mem_fun(*this, &UnplacedBox::row_activated));
43     pack_start(*sc, true, true, 0);
44 
45 
46     auto tb = Gtk::manage(new Gtk::Toolbar());
47     tb->get_style_context()->add_class("inline-toolbar");
48     tb->set_icon_size(Gtk::ICON_SIZE_MENU);
49     tb->set_toolbar_style(Gtk::TOOLBAR_ICONS);
50     {
51         auto tbo = Gtk::manage(new Gtk::ToolButton("Place"));
52         tbo->signal_clicked().connect([this] {
53             auto paths = view->get_selection()->get_selected_rows();
54             std::vector<UUIDPath<2>> uuids;
55             for (const auto &path : paths) {
56                 auto it = store->get_iter(path);
57                 if (it) {
58                     Gtk::TreeModel::Row row = *it;
59                     uuids.emplace_back(row[list_columns.uuid]);
60                 }
61             }
62             if (uuids.size()) {
63                 s_signal_place.emit(uuids);
64             }
65         });
66         button_place = tbo;
67         tb->insert(*tbo, -1);
68     }
69     tb->show_all();
70     button_place->set_sensitive(false);
71     pack_start(*tb, false, false, 0);
72 }
73 
row_activated(const Gtk::TreeModel::Path & path,Gtk::TreeViewColumn * column)74 void UnplacedBox::row_activated(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *column)
75 {
76     auto it = store->get_iter(path);
77     if (it) {
78         Gtk::TreeModel::Row row = *it;
79         s_signal_place.emit({row[list_columns.uuid]});
80     }
81 }
82 
update(const std::map<UUIDPath<2>,std::string> & items)83 void UnplacedBox::update(const std::map<UUIDPath<2>, std::string> &items)
84 {
85     set_visible(items.size());
86     std::set<UUIDPath<2>> items_available;
87     {
88         auto ch = store->children();
89         for (auto it = ch.begin(); it != ch.end();) {
90             Gtk::TreeModel::Row row = *it;
91             if (items.count(row[list_columns.uuid]) == 0) {
92                 store->erase(it++);
93             }
94             else {
95                 it++;
96                 row[list_columns.text] = items.at(row[list_columns.uuid]);
97                 items_available.emplace(row[list_columns.uuid]);
98             }
99         }
100     }
101     for (const auto &[uu, name] : items) {
102         if (items_available.count(uu) == 0) {
103             Gtk::TreeModel::Row row = *(store->append());
104             row[list_columns.text] = name;
105             row[list_columns.uuid] = uu;
106         }
107     }
108 }
109 } // namespace horizon
110