metaforce/Editor/ResourceBrowser.hpp

265 lines
7.2 KiB
C++
Raw Normal View History

2016-01-06 16:40:27 -08:00
#ifndef URDE_RESOURCE_OUTLINER_HPP
#define URDE_RESOURCE_OUTLINER_HPP
#include "Space.hpp"
#include "ViewManager.hpp"
2016-03-04 15:04:53 -08:00
#include "specter/PathButtons.hpp"
2017-12-29 00:08:12 -08:00
#include "specter/Table.hpp"
2016-01-06 16:40:27 -08:00
2016-03-04 16:03:41 -08:00
namespace urde
2016-01-06 16:40:27 -08:00
{
2016-03-04 15:04:53 -08:00
class ResourceBrowser : public Space, public specter::IPathButtonsBinding
2016-01-06 16:40:27 -08:00
{
struct State : Space::State
{
2018-02-21 23:24:51 -08:00
AT_DECL_DNA_YAML
AT_DECL_DNAV
2016-01-06 16:40:27 -08:00
String<-1> path;
Value<float> columnSplits[3] = {0.0f, 0.7f, 0.9f};
enum class SortColumn
{
Name,
Type,
Size
};
Value<SortColumn> sortColumn = SortColumn::Name;
2016-03-04 15:04:53 -08:00
Value<specter::SortDirection> sortDir = specter::SortDirection::Ascending;
2016-01-06 16:40:27 -08:00
} m_state;
const Space::State& spaceState() const {return m_state;}
2016-03-04 15:04:53 -08:00
hecl::ProjectPath m_path;
std::vector<hecl::SystemString> m_comps;
2016-01-06 16:40:27 -08:00
void pathButtonActivated(size_t idx);
2016-03-04 15:04:53 -08:00
struct ResListingDataBind : specter::ITableDataBinding, specter::ITableStateBinding
2016-01-06 16:40:27 -08:00
{
ResourceBrowser& m_rb;
struct Entry
{
2016-03-04 15:04:53 -08:00
hecl::SystemString m_path;
2016-01-06 16:40:27 -08:00
std::string m_name;
std::string m_type;
std::string m_size;
};
std::vector<Entry> m_entries;
std::string m_nameCol;
std::string m_typeCol;
std::string m_sizeCol;
std::string m_dirStr;
std::string m_projStr;
std::string m_fileStr;
size_t columnCount() const {return 3;}
size_t rowCount() const {return m_entries.size();}
2017-11-12 22:19:18 -08:00
std::string_view header(size_t cIdx) const
2016-01-06 16:40:27 -08:00
{
switch (cIdx)
{
case 0:
2017-11-12 22:19:18 -08:00
return m_nameCol;
2016-01-06 16:40:27 -08:00
case 1:
2017-11-12 22:19:18 -08:00
return m_typeCol;
2016-01-06 16:40:27 -08:00
case 2:
2017-11-12 22:19:18 -08:00
return m_sizeCol;
2016-01-06 16:40:27 -08:00
default: break;
}
2017-11-12 22:19:18 -08:00
return {};
2016-01-06 16:40:27 -08:00
}
2017-11-12 22:19:18 -08:00
std::string_view cell(size_t cIdx, size_t rIdx) const
2016-01-06 16:40:27 -08:00
{
switch (cIdx)
{
case 0:
2017-11-12 22:19:18 -08:00
return m_entries.at(rIdx).m_name;
2016-01-06 16:40:27 -08:00
case 1:
2017-11-12 22:19:18 -08:00
return m_entries.at(rIdx).m_type;
2016-01-06 16:40:27 -08:00
case 2:
2017-11-12 22:19:18 -08:00
return m_entries.at(rIdx).m_size;
2016-01-06 16:40:27 -08:00
default: break;
}
2017-11-12 22:19:18 -08:00
return {};
2016-01-06 16:40:27 -08:00
}
bool columnSplitResizeAllowed() const {return true;}
float getColumnSplit(size_t cIdx) const
{
return m_rb.m_state.columnSplits[cIdx];
}
void setColumnSplit(size_t cIdx, float split)
{
m_rb.m_state.columnSplits[cIdx] = split;
}
2016-03-04 15:04:53 -08:00
void updateListing(const hecl::DirectoryEnumerator& dEnum)
2016-01-06 16:40:27 -08:00
{
m_entries.clear();
m_entries.reserve(dEnum.size());
2016-03-04 15:04:53 -08:00
for (const hecl::DirectoryEnumerator::Entry& d : dEnum)
2016-01-06 16:40:27 -08:00
{
m_entries.emplace_back();
Entry& ent = m_entries.back();
ent.m_path = d.m_path;
2017-11-12 22:19:18 -08:00
hecl::SystemUTF8Conv nameUtf8(d.m_name);
2016-01-06 16:40:27 -08:00
ent.m_name = nameUtf8.str();
if (d.m_isDir)
{
2016-03-04 15:04:53 -08:00
if (hecl::SearchForProject(d.m_path))
2016-01-06 16:40:27 -08:00
ent.m_type = m_projStr;
else
ent.m_type = m_dirStr;
}
else
{
ent.m_type = m_fileStr;
2016-03-04 15:04:53 -08:00
ent.m_size = hecl::HumanizeNumber(d.m_fileSz, 7, nullptr, int(hecl::HNScale::AutoScale),
hecl::HNFlags::B | hecl::HNFlags::Decimal);
2016-01-06 16:40:27 -08:00
}
}
m_needsUpdate = false;
}
bool m_needsUpdate = false;
2016-03-04 15:04:53 -08:00
specter::SortDirection getSort(size_t& cIdx) const
2016-01-06 16:40:27 -08:00
{
cIdx = size_t(m_rb.m_state.sortColumn);
if (cIdx > 2)
cIdx = 0;
return m_rb.m_state.sortDir;
}
2016-03-04 15:04:53 -08:00
void setSort(size_t cIdx, specter::SortDirection dir)
2016-01-06 16:40:27 -08:00
{
m_rb.m_state.sortDir = dir;
m_rb.m_state.sortColumn = State::SortColumn(cIdx);
2016-01-06 16:40:27 -08:00
m_needsUpdate = true;
}
void setSelectedRow(size_t rIdx)
{
}
void rowActivated(size_t rIdx)
{
}
2016-03-04 15:04:53 -08:00
ResListingDataBind(ResourceBrowser& rb, const specter::IViewManager& vm)
2016-01-06 16:40:27 -08:00
: m_rb(rb)
{
m_nameCol = vm.translateOr("name", "Name");
m_typeCol = vm.translateOr("type", "Type");
m_sizeCol = vm.translateOr("size", "Size");
m_dirStr = vm.translateOr("directory", "Directory");
m_projStr = vm.translateOr("hecl_project", "HECL Project");
m_fileStr = vm.translateOr("file", "File");
}
} m_resListingBind;
2016-01-06 16:40:27 -08:00
2016-03-04 15:04:53 -08:00
struct View : specter::View
2016-01-06 16:40:27 -08:00
{
ResourceBrowser& m_ro;
2016-03-04 16:03:41 -08:00
specter::ViewChild<std::unique_ptr<specter::Table>> m_resListing;
2016-01-06 16:40:27 -08:00
2016-03-04 15:04:53 -08:00
View(ResourceBrowser& ro, specter::ViewResources& res)
: specter::View(res, ro.m_vm.rootView()), m_ro(ro)
2016-01-06 16:40:27 -08:00
{
2016-03-04 16:03:41 -08:00
m_resListing.m_view.reset(new specter::Table(res, *this, &ro.m_resListingBind, &ro.m_resListingBind, 3));
2016-01-06 16:40:27 -08:00
}
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
void mouseMove(const boo::SWindowCoord&);
void mouseLeave(const boo::SWindowCoord&);
2016-01-06 16:40:27 -08:00
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
void draw(boo::IGraphicsCommandQueue* gfxQ);
};
std::unique_ptr<View> m_view;
2016-03-04 15:04:53 -08:00
std::unique_ptr<specter::PathButtons> m_pathButtons;
2016-01-06 16:40:27 -08:00
public:
ResourceBrowser(ViewManager& vm, Space* parent)
: Space(vm, Class::ResourceBrowser, parent),
m_resListingBind(*this, vm)
2016-01-06 16:40:27 -08:00
{
reloadState();
}
ResourceBrowser(ViewManager& vm, Space* parent, const ResourceBrowser& other)
: ResourceBrowser(vm, parent)
{
m_state = other.m_state;
reloadState();
}
ResourceBrowser(ViewManager& vm, Space* parent, ConfigReader& r)
: ResourceBrowser(vm, parent)
2016-01-06 16:40:27 -08:00
{
m_state.read(r);
reloadState();
}
void reloadState()
{
2016-03-04 15:04:53 -08:00
hecl::ProjectPath pp(*m_vm.project(), m_state.path);
2016-09-18 16:47:48 -07:00
if (m_state.path.empty() || pp.isNone())
{
m_state.path = m_vm.project()->getProjectWorkingPath().getRelativePathUTF8();
2016-03-04 15:04:53 -08:00
navigateToPath(hecl::ProjectPath(*m_vm.project(), m_state.path));
}
else
navigateToPath(pp);
2016-01-06 16:40:27 -08:00
}
void think()
{
if (m_resListingBind.m_needsUpdate)
reloadState();
}
2016-03-04 15:04:53 -08:00
bool navigateToPath(const hecl::ProjectPath& path);
2016-01-06 16:40:27 -08:00
Space* copy(Space* parent) const
{
return new ResourceBrowser(m_vm, parent, *this);
}
2016-03-04 15:04:53 -08:00
void buildToolbarView(specter::ViewResources &res, specter::Toolbar &tb)
{
2016-03-04 15:04:53 -08:00
m_pathButtons.reset(new specter::PathButtons(res, tb, *this, true));
tb.push_back(m_pathButtons.get(), 1);
reloadState();
}
2016-03-04 15:04:53 -08:00
specter::View* buildContentView(specter::ViewResources& res)
2016-01-06 16:40:27 -08:00
{
m_view.reset(new View(*this, res));
return m_view.get();
}
bool usesToolbar() const
{
return true;
}
unsigned toolbarUnits() const
{
return 2;
}
2016-01-06 16:40:27 -08:00
};
}
#endif // URDE_RESOURCE_OUTLINER_HPP