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