2024-09-24 10:43:10 +00:00
|
|
|
|
#include "storypresent.h"
|
2024-10-05 02:11:42 +00:00
|
|
|
|
#include <QFileInfo>
|
|
|
|
|
#include <QMessageBox>
|
2024-10-05 09:20:41 +00:00
|
|
|
|
#include <QMenu>
|
|
|
|
|
#include <QMenuBar>
|
2024-09-24 10:43:10 +00:00
|
|
|
|
|
2024-10-05 02:11:42 +00:00
|
|
|
|
using namespace dags;
|
|
|
|
|
using namespace xast_parse;
|
|
|
|
|
|
|
|
|
|
StoryPresent::StoryPresent(QWidget* parent)
|
|
|
|
|
: QMainWindow(parent), _story_present(new DAGActiveView(this))
|
2024-09-24 10:43:10 +00:00
|
|
|
|
{
|
2024-10-05 02:11:42 +00:00
|
|
|
|
setCentralWidget(_story_present);
|
2024-10-05 09:20:41 +00:00
|
|
|
|
|
|
|
|
|
auto mbar = menuBar();
|
|
|
|
|
auto view = mbar->addMenu(u8"<EFBFBD><EFBFBD>ͼ");
|
|
|
|
|
view->addAction(u8"<EFBFBD><EFBFBD>С", this, &StoryPresent::lesser, Qt::CTRL + Qt::Key_N);
|
|
|
|
|
view->addAction(u8"<EFBFBD>Ŵ<EFBFBD>", this, &StoryPresent::bigger, Qt::CTRL + Qt::Key_P);
|
2024-10-06 03:01:32 +00:00
|
|
|
|
|
|
|
|
|
auto layout = mbar->addMenu(u8"<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD>");
|
2024-10-06 08:03:19 +00:00
|
|
|
|
layout->addAction(u8"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", this, &StoryPresent::forwardLayout, Qt::CTRL + Qt::Key_F);
|
|
|
|
|
layout->addAction(u8"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", this, &StoryPresent::backwardLayout, Qt::CTRL + Qt::Key_B);
|
2024-10-10 13:40:39 +00:00
|
|
|
|
layout->addAction(u8"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", this, &StoryPresent::adjustLayout, Qt::CTRL+Qt::Key_A);
|
2024-10-06 15:16:29 +00:00
|
|
|
|
|
|
|
|
|
connect(_story_present, &DAGActiveView::nodeClicked, this, &StoryPresent::nodeClickAccept);
|
2024-09-24 10:43:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StoryPresent::~StoryPresent()
|
|
|
|
|
{}
|
2024-10-05 02:11:42 +00:00
|
|
|
|
|
|
|
|
|
#include "xast_parse.h"
|
|
|
|
|
void StoryPresent::loadXAST(const QString& ast_path)
|
|
|
|
|
{
|
|
|
|
|
QFileInfo finfo(ast_path);
|
|
|
|
|
if (!finfo.exists() || !finfo.isFile()) {
|
|
|
|
|
QMessageBox::critical(this, u8"<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", QString(u8"ָ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>%1<><31><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>").arg(ast_path));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xast_parse::XAST_Parser t(ast_path);
|
|
|
|
|
this->_story_graph = t.storyGraph();
|
|
|
|
|
|
|
|
|
|
QList<graph_data::Arrow> arrows;
|
|
|
|
|
for (auto& key : this->_story_graph.keys()) {
|
|
|
|
|
auto story_line = this->_story_graph[key];
|
|
|
|
|
|
|
|
|
|
auto arrow_start = story_line->name();
|
|
|
|
|
auto frag_temp = story_line->firstChild();
|
|
|
|
|
while (frag_temp) {
|
|
|
|
|
switch (frag_temp->type()) {
|
2024-10-06 15:16:29 +00:00
|
|
|
|
case SliceType::FragmentDefines:
|
|
|
|
|
{
|
2024-10-05 02:11:42 +00:00
|
|
|
|
auto arrow_tail = std::dynamic_pointer_cast<FragmentDefine>(frag_temp)->name() + u8"@" + story_line->name();
|
|
|
|
|
arrows << graph_data::Arrow(arrow_start, arrow_tail);
|
|
|
|
|
arrow_start = arrow_tail;
|
|
|
|
|
}break;
|
2024-10-06 15:16:29 +00:00
|
|
|
|
case SliceType::FragmentRefers:
|
|
|
|
|
{
|
2024-10-05 02:11:42 +00:00
|
|
|
|
auto conv_refer = std::dynamic_pointer_cast<FragmentRefer>(frag_temp);
|
|
|
|
|
auto arrow_tail = conv_refer->fragmentRefer() + u8"@" + conv_refer->storyRefer();
|
|
|
|
|
arrows << graph_data::Arrow(arrow_start, arrow_tail);
|
|
|
|
|
arrow_start = arrow_tail;
|
|
|
|
|
}break;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
frag_temp = frag_temp->nextSlice();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this->_story_present->updateWithEdges(arrows);
|
|
|
|
|
}
|
2024-10-05 09:20:41 +00:00
|
|
|
|
|
|
|
|
|
#include <QTransform>
|
2024-10-06 15:16:29 +00:00
|
|
|
|
void StoryPresent::nodeClickAccept(const QPointF& pos, const QString& node_name)
|
|
|
|
|
{
|
|
|
|
|
// <20><>ʼ<EFBFBD>ڵ<EFBFBD>
|
|
|
|
|
if (!node_name.contains(u8"@")) {
|
|
|
|
|
auto story_line = this->_story_graph[node_name];
|
|
|
|
|
|
|
|
|
|
QList<QString> node_names;
|
|
|
|
|
node_names << node_name;
|
|
|
|
|
|
|
|
|
|
auto temp_node = story_line->firstChild();
|
|
|
|
|
while (temp_node) {
|
|
|
|
|
switch (temp_node->type()) {
|
|
|
|
|
case SliceType::FragmentDefines:
|
|
|
|
|
{
|
|
|
|
|
auto fragm = std::dynamic_pointer_cast<FragmentDefine>(temp_node);
|
|
|
|
|
node_names << QString(u8"%1@%2").arg(fragm->name(), node_name);
|
|
|
|
|
}break;
|
|
|
|
|
case SliceType::FragmentRefers:
|
|
|
|
|
{
|
|
|
|
|
auto frefer = std::dynamic_pointer_cast<FragmentRefer>(temp_node);
|
|
|
|
|
node_names << QString(u8"%1@%2").arg(frefer->fragmentRefer(), frefer->storyRefer());
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
temp_node = temp_node->nextSlice();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QList<graph_data::Arrow> arrows;
|
|
|
|
|
for (auto idx = 1; idx < node_names.size(); ++idx) {
|
|
|
|
|
auto from = node_names[idx - 1];
|
|
|
|
|
auto to = node_names[idx];
|
|
|
|
|
|
|
|
|
|
arrows << graph_data::Arrow(from, to);
|
|
|
|
|
}
|
|
|
|
|
this->_story_present->highlightGraphLink(arrows);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
auto splits = node_name.split(u8"@", QString::SkipEmptyParts);
|
|
|
|
|
auto story_line = this->_story_graph[splits.last()];
|
|
|
|
|
auto fragm_slice = story_line->getFragment(splits.first());
|
|
|
|
|
auto fragm_defn = std::dynamic_pointer_cast<FragmentDefine>(fragm_slice);
|
|
|
|
|
|
|
|
|
|
auto refers = fragm_defn->referSlices();
|
|
|
|
|
|
|
|
|
|
if (!refers.size()) {
|
|
|
|
|
this->nodeClickAccept(QPointF(), story_line->name());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-09 13:03:42 +00:00
|
|
|
|
QList<std::shared_ptr<IElementSlice>> vparent_slices;
|
|
|
|
|
std::transform(refers.begin(), refers.end(), std::back_inserter(vparent_slices),
|
2024-10-06 15:16:29 +00:00
|
|
|
|
[](std::shared_ptr<IElementSlice> ins) { return ins->parentSlice().lock(); });
|
|
|
|
|
|
2024-10-09 13:03:42 +00:00
|
|
|
|
QList<std::shared_ptr<IElementSlice>> parent_slices;
|
|
|
|
|
std::copy_if(vparent_slices.begin(), vparent_slices.end(), std::back_inserter(parent_slices),
|
|
|
|
|
[](std::shared_ptr<IElementSlice> ins) -> bool { return ins != nullptr; });
|
|
|
|
|
|
2024-10-06 15:16:29 +00:00
|
|
|
|
decltype(parent_slices) fliter_slices;
|
|
|
|
|
std::copy_if(parent_slices.begin(), parent_slices.end(), std::back_inserter(fliter_slices),
|
|
|
|
|
[](std::shared_ptr<IElementSlice> ins) { return ins->type() == SliceType::StoryDefines; });
|
|
|
|
|
|
|
|
|
|
QList<std::shared_ptr<StoryDefine>> lines = { story_line };
|
|
|
|
|
std::transform(fliter_slices.begin(), fliter_slices.end(), std::back_inserter(lines),
|
|
|
|
|
[](std::shared_ptr<IElementSlice> ins) { return std::dynamic_pointer_cast<StoryDefine>(ins); });
|
|
|
|
|
|
|
|
|
|
QMenu msep;
|
|
|
|
|
for (auto ln : lines) {
|
|
|
|
|
msep.addAction(ln->name(), [=](){
|
|
|
|
|
this->nodeClickAccept(QPointF(), ln->name());
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
msep.exec(this->_story_present->mapToParent(pos.toPoint()));
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-05 09:20:41 +00:00
|
|
|
|
void StoryPresent::bigger()
|
|
|
|
|
{
|
|
|
|
|
_scale_value *= 1.1;
|
|
|
|
|
|
|
|
|
|
QTransform trans_base;
|
|
|
|
|
trans_base.scale(_scale_value, _scale_value);
|
|
|
|
|
this->_story_present->setTransform(trans_base);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StoryPresent::lesser()
|
|
|
|
|
{
|
|
|
|
|
_scale_value /= 1.1;
|
|
|
|
|
|
|
|
|
|
QTransform trans_base;
|
|
|
|
|
trans_base.scale(_scale_value, _scale_value);
|
|
|
|
|
this->_story_present->setTransform(trans_base);
|
|
|
|
|
}
|
2024-10-06 03:01:32 +00:00
|
|
|
|
|
|
|
|
|
void StoryPresent::forwardLayout()
|
|
|
|
|
{
|
|
|
|
|
this->_story_present->layoutEngine()->forwardsLayoutImpls();
|
|
|
|
|
this->_story_present->refreshGraph();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StoryPresent::backwardLayout()
|
|
|
|
|
{
|
|
|
|
|
this->_story_present->layoutEngine()->backwardsLayoutImpls();
|
|
|
|
|
this->_story_present->refreshGraph();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StoryPresent::adjustLayout()
|
|
|
|
|
{
|
|
|
|
|
this->_story_present->layoutEngine()->adjustLayoutImpls();
|
|
|
|
|
this->_story_present->refreshGraph();
|
|
|
|
|
}
|