#include <vector>
#include <stdexcept>
#include <algorithm>
#include <iostream>
#include <nana/deploy.hpp>
#include <nana/gui.hpp>
#include <nana/gui/widgets/panel.hpp>
#include <nana/gui/place.hpp>
#include <nana/gui/widgets/treebox.hpp>
#include <nana/gui/widgets/listbox.hpp>
#include <nana/gui/widgets/categorize.hpp>
#include <nana/gui/widgets/menubar.hpp>
#include <nana/gui/widgets/toolbar.hpp>
#include <nana/filesystem/filesystem_ext.hpp>
namespace fs = std::filesystem;
namespace fs_ext = nana::filesystem_ext;
using d_node = fs::directory_entry ;
using d_item = fs::directory_entry ;
using ct_l_items = fs::directory_iterator ;
auto children = [](const d_node& f)->ct_n_children
{
try {
return ct_n_children{ f.path() };
} catch (...) {
return ct_n_children();
}
};
auto l_items = [](const d_node& f)->ct_l_items
{
try {
return ct_l_items { f.path() };
} catch (...) {
return ct_l_items();
}
};
auto f_name = [](const d_node& f)
{
return f.path().filename().generic_string();
};
using f_node_children = decltype (children);
using f_list_items = decltype (l_items);
using f_node_title = decltype (f_name);
{
ores << f_name(item);
if (fs::is_directory(item))
ores << ("Directory") << "";
else
{
if (item.path().has_extension())
ores << item.path().extension().generic_string();
else
ores << ("File");
}
return ores;
}
{
return ires;
}
{
status_{*this};
nav_ {*this};
f_node_title &node_to_title;
f_node_children &node_children;
f_list_items &list_items;
R"(
vertical <weight=23 menu>
<weight=23 path>
<weight=23 tools>
<<tree> |70% < vertical <list> |50% <vertical <weight=23 nav>
<view>
>
>
>
<weight=23 status>
)";
public:
bool force_refresh{false};
explorer (
f_node_title fnt,
f_node_children ctnc,
f_list_items ctni,
:form{r}, node_to_title{fnt}, node_children{ ctnc }, list_items{ ctni }, fake_item("Sorray, this is a fake item")
{
place_.div(div_.c_str());
place_["menu"] << menu_ ;
place_["tools"] << tools_ ;
place_["path"] << path_ ;
place_["tree"] << tree_ ;
place_["list"] << list_ ;
place_["nav"] << nav_ ;
place_["view"] << view_ ;
place_["status"]<< status_ ;
place_.collocate();
{
tree_.auto_draw(false);
list_.auto_draw(false);
refresh_tnode(tb_msg.
item, force_refresh);
refresh_list(tb_msg.
item);
refresh_path(tb_msg.
item);
tree_.auto_draw(true);
list_.auto_draw(true);
});
{
tree_.auto_draw(false);
refresh_tnode(tb_msg.
item, force_refresh);
tree_.auto_draw(true);
});
menu_.push_back("File");
menu_.push_back("Help");
for (auto & col : columns)
list_.append_header(col.first, col.second);
}
#if 0 //deprecated
t_node add_root(d_node & root)
{
auto r= tree_.insert(node_to_title(root), node_to_title(root));
r.value(root);
signal_child(r);
return r;
}
{
auto r = tree_.insert(root, root);
r.value(d_node(root));
signal_child(r);
return r;
}
#endif
{
auto r = tree_.insert("root_" + k, t);
r.value(root);
signal_child(r);
return r;
}
void signal_child(t_node& node)
{
if (!force_refresh && !node.child().empty()) return;
clear_children(node);
auto&
data = node.value<d_node>();
const ct_n_children& d_c = node_children(data);
const auto& child_1 =
begin(d_c);
tree_.insert(node, fake_item, "");
}
void clear_children(t_node& sel_node)
{
while (!sel_node.child().empty())
tree_.erase(sel_node.child());
}
void refresh_list(t_node& sel_node)
{
list_.clear();
const ct_l_items& items = list_items(sel_node.value<d_node>());
for (auto &i : items)
list_.at(0).append(i, true);
}
void refresh_path(t_node& sel_node) {};
void refresh_tnode(t_node& sel_node, bool force)
{
if (!force && !sel_node.child().empty() && sel_node.child().key()!=fake_item ) return;
clear_children(sel_node);
const ct_n_children& d_c = node_children(sel_node.value<d_node>());
for (auto &n : d_c)
{
auto name = node_to_title(n);
auto tn = tree_.insert(sel_node, name, name);
if (tn.empty()) continue;
tn.value(n);
signal_child(tn);
}
};
};
template <class V,
class C_I,
class C_N
>
struct data_node
{
using value_type = V;
using cont_it_t = C_I;
using cont_nd_t = C_I;
value_type value;
C_I items;
C_N nodes;
: value{ path },
separator(separator)
{}
};
struct dir_node
{
using value_type = fs::directory_entry;
using cont_it_t = fs::directory_iterator;
value_type value;
cont_it_t items;
cont_nd_t nodes;
dir_node(fs::path path)
: value{ path }, items{ path }, nodes { path }
{}
};
std::string key(
const dir_node& dn) {
return dn.value.path().filename().generic_string(); };
std::string title(
const dir_node& dn) {
return key(dn); };
std::string key(
const dir_it& d) {
return d->path().filename().generic_string(); };
int main()
{
explorer fb( f_name,
children,
l_items,
{ { ("Name"), 190 }, { ("Modified"), 145 }, { ("Type"), 80 }, { ("Size"), 70 } });
fb.add_root(fs_ext::def_root, fs_ext::def_rootname, d_node{ fs_ext::def_rootstr }).
select(
true);
fb.show();
}