WsParser_VS/StoryPresent/storypresent.cpp

181 lines
5.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "storypresent.h"
#include <QFileInfo>
#include <QMessageBox>
#include <QMenu>
#include <QMenuBar>
using namespace dags;
using namespace xast_parse;
StoryPresent::StoryPresent(QWidget* parent)
: QMainWindow(parent), _story_present(new DAGActiveView(this))
{
setCentralWidget(_story_present);
auto mbar = menuBar();
auto view = mbar->addMenu(u8"视图");
view->addAction(u8"缩小", this, &StoryPresent::lesser, Qt::CTRL + Qt::Key_N);
view->addAction(u8"放大", this, &StoryPresent::bigger, Qt::CTRL + Qt::Key_P);
auto layout = mbar->addMenu(u8"布局调整");
layout->addAction(u8"正向布局", this, &StoryPresent::forwardLayout, Qt::CTRL + Qt::Key_F);
layout->addAction(u8"逆向布局", this, &StoryPresent::backwardLayout, Qt::CTRL + Qt::Key_B);
//layout->addAction(u8"调整布局", this, &StoryPresent::adjustLayout, Qt::CTRL+Qt::Key_A);
connect(_story_present, &DAGActiveView::nodeClicked, this, &StoryPresent::nodeClickAccept);
}
StoryPresent::~StoryPresent()
{}
#include "xast_parse.h"
void StoryPresent::loadXAST(const QString& ast_path)
{
QFileInfo finfo(ast_path);
if (!finfo.exists() || !finfo.isFile()) {
QMessageBox::critical(this, u8"文件错误", QString(u8"指定文件(%1非法").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()) {
case SliceType::FragmentDefines:
{
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;
case SliceType::FragmentRefers:
{
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);
}
#include <QTransform>
void StoryPresent::nodeClickAccept(const QPointF& pos, const QString& node_name)
{
// 起始节点
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;
}
QList<std::shared_ptr<IElementSlice>> parent_slices;
std::transform(refers.begin(), refers.end(), std::back_inserter(parent_slices),
[](std::shared_ptr<IElementSlice> ins) { return ins->parentSlice().lock(); });
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()));
}
}
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);
}
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();
}