Split up Window Layout loading into a loading and application stage (#1964)

* Split up Window Layout loading into a loading and application stage

Previously, we were creating UI elements at while we were reading the window-layout.json file.
We now read the window-layout.json file fully first, which results in a
WindowLayout struct which is built up of a list of windows with a list
of tabs with a root node which contains containers and splits.
This WindowLayout can then be applied.

This will enable PRs like #1940 to start Chatterino with Window Layouts
that aren't defined in a json file.

This commit has deprecated loading of v1 window layouts (we're now on v2). If a v1 window layout is there, it will just be ignored and Chatterino will boot up as if it did not have a window layout at all, and on save that old window layout will be gone.

* Fix compile error for mac
This commit is contained in:
pajlada
2020-09-19 11:14:10 -04:00
committed by GitHub
parent 7eabba959b
commit 913193f8b5
8 changed files with 484 additions and 191 deletions
+35 -35
View File
@@ -695,55 +695,67 @@ SplitContainer::Node *SplitContainer::getBaseNode()
return &this->baseNode_;
}
void SplitContainer::decodeFromJson(QJsonObject &obj)
void SplitContainer::applyFromDescriptor(const NodeDescriptor &rootNode)
{
assert(this->baseNode_.type_ == Node::EmptyRoot);
this->decodeNodeRecusively(obj, &this->baseNode_);
this->applyFromDescriptorRecursively(rootNode, &this->baseNode_);
}
void SplitContainer::decodeNodeRecusively(QJsonObject &obj, Node *node)
void SplitContainer::applyFromDescriptorRecursively(
const NodeDescriptor &rootNode, Node *node)
{
QString type = obj.value("type").toString();
if (type == "split")
if (std::holds_alternative<SplitNodeDescriptor>(rootNode))
{
auto *n = std::get_if<SplitNodeDescriptor>(&rootNode);
if (!n)
{
return;
}
const auto &splitNode = *n;
auto *split = new Split(this);
split->setChannel(
WindowManager::decodeChannel(obj.value("data").toObject()));
split->setModerationMode(obj.value("moderationMode").toBool(false));
split->setChannel(WindowManager::decodeChannel(splitNode));
split->setModerationMode(splitNode.moderationMode_);
this->appendSplit(split);
}
else if (type == "horizontal" || type == "vertical")
else if (std::holds_alternative<ContainerNodeDescriptor>(rootNode))
{
bool vertical = type == "vertical";
auto *n = std::get_if<ContainerNodeDescriptor>(&rootNode);
if (!n)
{
return;
}
const auto &containerNode = *n;
bool vertical = containerNode.vertical_;
Direction direction = vertical ? Direction::Below : Direction::Right;
node->type_ =
vertical ? Node::VerticalContainer : Node::HorizontalContainer;
for (QJsonValue _val : obj.value("items").toArray())
for (const auto &item : containerNode.items_)
{
auto _obj = _val.toObject();
auto _type = _obj.value("type");
if (_type == "split")
if (std::holds_alternative<SplitNodeDescriptor>(item))
{
auto *n = std::get_if<SplitNodeDescriptor>(&item);
if (!n)
{
return;
}
const auto &splitNode = *n;
auto *split = new Split(this);
split->setChannel(WindowManager::decodeChannel(
_obj.value("data").toObject()));
split->setModerationMode(
_obj.value("moderationMode").toBool(false));
split->setChannel(WindowManager::decodeChannel(splitNode));
split->setModerationMode(splitNode.moderationMode_);
Node *_node = new Node();
_node->parent_ = node;
_node->split_ = split;
_node->type_ = Node::_Split;
_node->flexH_ = _obj.value("flexh").toDouble(1.0);
_node->flexV_ = _obj.value("flexv").toDouble(1.0);
_node->flexH_ = splitNode.flexH_;
_node->flexV_ = splitNode.flexV_;
node->children_.emplace_back(_node);
this->addSplit(split);
@@ -753,19 +765,7 @@ void SplitContainer::decodeNodeRecusively(QJsonObject &obj, Node *node)
Node *_node = new Node();
_node->parent_ = node;
node->children_.emplace_back(_node);
this->decodeNodeRecusively(_obj, _node);
}
}
for (int i = 0; i < 2; i++)
{
if (node->getChildren().size() < 2)
{
auto *split = new Split(this);
split->setChannel(
WindowManager::decodeChannel(obj.value("data").toObject()));
this->insertSplit(split, direction, node);
this->applyFromDescriptorRecursively(item, _node);
}
}
}