Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions editor/views/editor/editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,7 @@ void EditorWindow::activateWorkspace(int index) {
if (auto *button = workspaceModeGroup->button(index))
button->setChecked(true);
}
scheduleLayoutSave();
}

void EditorWindow::createScene() {
Expand Down Expand Up @@ -1718,6 +1719,8 @@ void EditorWindow::saveLayout() {

settings.setValue("window/geometry", saveGeometry());
settings.setValue(DockStateKey, coreManager->saveState(DockStateVersion));
if (workspaceStack != nullptr)
settings.setValue("workspace/mode", workspaceStack->currentIndex());
settings.sync();
}

Expand All @@ -1735,6 +1738,10 @@ void EditorWindow::restoreLayout() {
coreManager->restoreState(dockState, DockStateVersion);
if (!restored && !defaultDockState.isEmpty())
coreManager->restoreState(defaultDockState, DockStateVersion);
if (workspaceStack != nullptr)
activateWorkspace(
std::clamp(settings.value("workspace/mode", 0).toInt(), 0,
workspaceStack->count() - 1));
restoringLayout = false;
configureDockSplitters();
}
Expand Down
45 changes: 45 additions & 0 deletions editor/views/editor/inspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <QFrame>
#include <QHBoxLayout>
#include <QIcon>
#include <QImageReader>
#include <QJsonArray>
#include <QJsonDocument>
#include <QLabel>
Expand Down Expand Up @@ -192,6 +193,12 @@ QIcon inspectorIcon(QWidget *, const QString &type) {
return styling::icon(styling::Icon::MusicNote, "#849589");
if (normalized.contains("material"))
return styling::icon(styling::Icon::Material, "#9E897D");
if (normalized == "png" || normalized == "jpg" ||
normalized == "jpeg" || normalized == "bmp" ||
normalized == "gif" || normalized == "webp" ||
normalized == "tif" || normalized == "tiff" ||
normalized == "tga" || normalized == "hdr" || normalized == "exr")
return styling::icon(styling::Icon::Image, "#A1957D");
if (normalized.contains("script") || normalized == "ts" ||
normalized == "js")
return styling::icon(styling::Icon::FileCode, "#7E929C");
Expand Down Expand Up @@ -1883,6 +1890,44 @@ void InspectorPanel::showFile() {
connect(nameField, &QLineEdit::editingFinished, this,
&InspectorPanel::commitHeaderName);

if (info.isFile()) {
QImageReader reader(info.absoluteFilePath());
reader.setAutoTransform(true);
if (reader.canRead()) {
const QSize sourceSize = reader.size();
if (sourceSize.isValid() &&
(sourceSize.width() > 720 || sourceSize.height() > 480)) {
reader.setScaledSize(
sourceSize.scaled(720, 480, Qt::KeepAspectRatio));
}
const QImage image = reader.read();
if (!image.isNull()) {
auto *previewCard = new QFrame(content);
previewCard->setObjectName("inspectorComponent");
auto *previewLayout = new QVBoxLayout(previewCard);
previewLayout->setContentsMargins(0, 0, 0, 7);
previewLayout->setSpacing(2);
auto *previewTitle = new QLabel("Preview", previewCard);
previewTitle->setObjectName("inspectorComponentHeader");
auto *previewBody = new QWidget(previewCard);
previewBody->setObjectName("inspectorComponentBody");
auto *previewBodyLayout = new QVBoxLayout(previewBody);
previewBodyLayout->setContentsMargins(5, 5, 5, 5);
auto *imageLabel = new QLabel(previewBody);
imageLabel->setAlignment(Qt::AlignCenter);
imageLabel->setSizePolicy(QSizePolicy::Expanding,
QSizePolicy::Preferred);
imageLabel->setPixmap(QPixmap::fromImage(image).scaled(
360, 240, Qt::KeepAspectRatio,
Qt::SmoothTransformation));
previewBodyLayout->addWidget(imageLabel);
previewLayout->addWidget(previewTitle);
previewLayout->addWidget(previewBody);
contentLayout->addWidget(previewCard);
}
}
}

QJsonObject metadata{
{"path", info.absoluteFilePath()},
{"size", static_cast<double>(info.size())},
Expand Down
47 changes: 36 additions & 11 deletions editor/views/editor/materialEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <QPair>
#include <QSaveFile>
#include <QScrollArea>
#include <QSettings>
#include <QSizePolicy>
#include <QStyle>
#include <QSignalBlocker>
Expand Down Expand Up @@ -482,6 +483,7 @@ void MaterialEditorPanel::rebuildBody() {
delete item;
}
preview = nullptr;
materialSplitter = nullptr;
textureFields.clear();
texturePreviews.clear();
}
Expand All @@ -504,10 +506,10 @@ void MaterialEditorPanel::showMaterial() {
titleLabel->setText(QFileInfo(materialPath).completeBaseName());
statusLabel->setText("Ready");

auto *splitter = new QSplitter(Qt::Horizontal, body);
splitter->setChildrenCollapsible(false);
auto *previewPane = new QWidget(splitter);
previewPane->setMinimumWidth(1);
materialSplitter = new QSplitter(Qt::Horizontal, body);
materialSplitter->setChildrenCollapsible(false);
auto *previewPane = new QWidget(materialSplitter);
previewPane->setMinimumWidth(180);
previewPane->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
auto *previewLayout = new QVBoxLayout(previewPane);
previewLayout->setContentsMargins(0, 0, 5, 0);
Expand All @@ -528,22 +530,45 @@ void MaterialEditorPanel::showMaterial() {
connect(environment, &QComboBox::currentIndexChanged, preview,
&MaterialPreviewWidget::setEnvironmentMode);

auto *propertiesScroll = new QScrollArea(splitter);
auto *propertiesScroll = new QScrollArea(materialSplitter);
propertiesScroll->setObjectName("materialPropertiesScroll");
propertiesScroll->setWidgetResizable(true);
propertiesScroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
auto *properties = new QWidget(propertiesScroll);
properties->setMinimumWidth(1);
propertiesScroll->setMinimumWidth(280);
properties->setMinimumWidth(260);
properties->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
auto *propertiesLayout = new QVBoxLayout(properties);
propertiesLayout->setContentsMargins(5, 0, 0, 0);
propertiesLayout->setSpacing(9);
propertiesScroll->setWidget(properties);
splitter->addWidget(previewPane);
splitter->addWidget(propertiesScroll);
splitter->setStretchFactor(0, 3);
splitter->setStretchFactor(1, 2);
bodyLayout->addWidget(splitter, 1);
materialSplitter->addWidget(previewPane);
materialSplitter->addWidget(propertiesScroll);
materialSplitter->setStretchFactor(0, 2);
materialSplitter->setStretchFactor(1, 3);
bodyLayout->addWidget(materialSplitter, 1);

QSettings settings("Neutral Software", "Atlas Engine");
const QByteArray splitterState =
settings.value("materialEditor/splitterState").toByteArray();
if (splitterState.isEmpty() ||
!materialSplitter->restoreState(splitterState)) {
QTimer::singleShot(0, materialSplitter, [this] {
if (materialSplitter == nullptr)
return;
const int available = std::max(materialSplitter->width(), 500);
materialSplitter->setSizes(
{available * 2 / 5, available * 3 / 5});
});
}
connect(materialSplitter, &QSplitter::splitterMoved, this,
[this](int, int) {
if (materialSplitter == nullptr)
return;
QSettings settings("Neutral Software", "Atlas Engine");
settings.setValue("materialEditor/splitterState",
materialSplitter->saveState());
});

auto *surface = new QGroupBox("Surface", properties);
auto *surfaceForm = new QFormLayout(surface);
Expand Down
71 changes: 55 additions & 16 deletions editor/views/general/contentBrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <QSaveFile>
#include <QSignalBlocker>
#include <QSize>
#include <QSortFilterProxyModel>
#include <QStyle>
#include <QToolButton>
#include <QUrl>
Expand Down Expand Up @@ -139,7 +140,9 @@ class AtlasFileIconProvider : public QFileIconProvider {
suffix == "h" || suffix == "json")
return styling::icon(styling::Icon::FileCode, "#7E929C");
if (suffix == "png" || suffix == "jpg" || suffix == "jpeg" ||
suffix == "hdr")
suffix == "bmp" || suffix == "gif" || suffix == "webp" ||
suffix == "tif" || suffix == "tiff" || suffix == "tga" ||
suffix == "hdr" || suffix == "exr")
return styling::icon(styling::Icon::Image, "#A1957D");
if (suffix == "wav" || suffix == "mp3" || suffix == "ogg" ||
suffix == "flac")
Expand All @@ -155,6 +158,29 @@ class AtlasFileIconProvider : public QFileIconProvider {
};

AtlasFileIconProvider atlasFileIconProvider;

class ContentBrowserFilterModel : public QSortFilterProxyModel {
protected:
bool filterAcceptsRow(int sourceRow,
const QModelIndex &sourceParent) const override {
const QModelIndex index =
sourceModel()->index(sourceRow, 0, sourceParent);
const QFileInfo info =
qobject_cast<QFileSystemModel *>(sourceModel())->fileInfo(index);
const QString name = info.fileName().toLower();
if (info.isDir()) {
if (name == "lib" || name == "dist" || name == "node_modules")
return false;
return true;
}
if (name == "package.json" || name == "package-lock.json" ||
name == "tsconfig.json" || name == "yarn.lock" ||
name == "bun.lock" || name == "bun.lockb")
return false;
return QSortFilterProxyModel::filterAcceptsRow(sourceRow,
sourceParent);
}
};
} // namespace

ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile,
Expand Down Expand Up @@ -239,9 +265,16 @@ ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile,
model->setRootPath(projectRoot);
model->sort(0, Qt::AscendingOrder);

filterModel = new ContentBrowserFilterModel();
filterModel->setParent(this);
filterModel->setSourceModel(model);
filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
filterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
filterModel->sort(0, Qt::AscendingOrder);

gridView = new QListView(this);
gridView->setObjectName("contentGrid");
gridView->setModel(model);
gridView->setModel(filterModel);
gridView->setViewMode(QListView::IconMode);
gridView->setFlow(QListView::LeftToRight);
gridView->setWrapping(true);
Expand Down Expand Up @@ -319,10 +352,9 @@ ContentBrowserPanel::ContentBrowserPanel(const QString &projectFile,
});
connect(searchField, &QLineEdit::textChanged, this,
[this](const QString &search) {
model->setNameFilters(search.isEmpty()
? QStringList()
: QStringList{"*" + search + "*"});
model->setNameFilterDisables(false);
filterModel->setFilterWildcard(search.isEmpty()
? QString()
: "*" + search + "*");
});
connect(gridView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, [this] {
Expand Down Expand Up @@ -403,7 +435,8 @@ void ContentBrowserPanel::navigateTo(const QString &path, bool recordHistory) {
}

currentPath = target;
gridView->setRootIndex(model->index(currentPath));
gridView->setRootIndex(
filterModel->mapFromSource(model->index(currentPath)));
gridView->clearSelection();
searchField->clear();

Expand All @@ -421,7 +454,7 @@ void ContentBrowserPanel::navigateTo(const QString &path, bool recordHistory) {
}

void ContentBrowserPanel::openIndex(const QModelIndex &index) {
const QFileInfo info = model->fileInfo(index);
const QFileInfo info = model->fileInfo(filterModel->mapToSource(index));
if (info.isDir()) {
navigateTo(info.absoluteFilePath());
return;
Expand Down Expand Up @@ -507,7 +540,8 @@ void ContentBrowserPanel::createScene() {
if (path.isEmpty())
return;
if (writeNewFile(path, EmptyScene)) {
gridView->setCurrentIndex(model->index(path));
gridView->setCurrentIndex(
filterModel->mapFromSource(model->index(path)));
}
}

Expand All @@ -532,7 +566,7 @@ void ContentBrowserPanel::createScript() {
error.isEmpty() ? "Atlas could not create the script." : error);
return;
}
gridView->setCurrentIndex(model->index(path));
gridView->setCurrentIndex(filterModel->mapFromSource(model->index(path)));
}

void ContentBrowserPanel::createMaterial() {
Expand All @@ -558,7 +592,8 @@ void ContentBrowserPanel::createMaterial() {
" }\n"
"}\n";
if (writeNewFile(path, material)) {
const QModelIndex index = model->index(path);
const QModelIndex index =
filterModel->mapFromSource(model->index(path));
gridView->setCurrentIndex(index);
emit assetActivated(path);
}
Expand Down Expand Up @@ -586,7 +621,8 @@ void ContentBrowserPanel::renameSelection() {
return;
}
gridView->setCurrentIndex(
model->index(QDir(info.absolutePath()).filePath(entryName)));
filterModel->mapFromSource(
model->index(QDir(info.absolutePath()).filePath(entryName))));
}

void ContentBrowserPanel::deleteSelection() {
Expand All @@ -596,7 +632,8 @@ void ContentBrowserPanel::deleteSelection() {
return;
}
for (const QModelIndex &index : selected) {
const QFileInfo info = model->fileInfo(index);
const QFileInfo info =
model->fileInfo(filterModel->mapToSource(index));
if (info.isSymLink()) {
QFile::remove(info.absoluteFilePath());
} else if (info.isDir()) {
Expand All @@ -616,7 +653,8 @@ void ContentBrowserPanel::copySelection() {
clipboardPaths.clear();
for (const QModelIndex &index :
gridView->selectionModel()->selectedIndexes()) {
clipboardPaths.append(model->filePath(index));
clipboardPaths.append(
model->filePath(filterModel->mapToSource(index)));
}
cutClipboard = false;
}
Expand Down Expand Up @@ -654,7 +692,8 @@ void ContentBrowserPanel::duplicateSelection() {
void ContentBrowserPanel::refreshAssets() {
model->setRootPath(QString());
model->setRootPath(projectRoot);
gridView->setRootIndex(model->index(currentPath));
gridView->setRootIndex(
filterModel->mapFromSource(model->index(currentPath)));
}

void ContentBrowserPanel::selectAllAssets() { gridView->selectAll(); }
Expand Down Expand Up @@ -683,7 +722,7 @@ void ContentBrowserPanel::copySelectionPath() const {
QString ContentBrowserPanel::selectedPath() const {
const QModelIndex index = gridView->currentIndex();
return index.isValid() && gridView->selectionModel()->isSelected(index)
? model->filePath(index)
? model->filePath(filterModel->mapToSource(index))
: QString();
}

Expand Down
11 changes: 10 additions & 1 deletion editor/views/general/projectBrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <QPushButton>
#include <QRadioButton>
#include <QScrollBar>
#include <QSettings>
#include <QStandardPaths>
#include <QStackedWidget>
#include <QStyle>
Expand Down Expand Up @@ -160,8 +161,13 @@ class CreateProjectDialog : public QDialog {
fields->addWidget(locationLabel);
auto *locationLayout = new QHBoxLayout();
locationField = new QLineEdit(this);
QSettings settings("Neutral Software", "Atlas Engine");
QString defaultLocation =
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
settings.value("projects/lastCreatedLocation").toString();
if (defaultLocation.isEmpty() || !QDir(defaultLocation).exists()) {
defaultLocation = QStandardPaths::writableLocation(
QStandardPaths::DocumentsLocation);
}
if (defaultLocation.isEmpty()) {
defaultLocation = QDir::homePath();
}
Expand Down Expand Up @@ -222,6 +228,9 @@ class CreateProjectDialog : public QDialog {
errorLabel->show();
return;
}
QSettings settings("Neutral Software", "Atlas Engine");
settings.setValue("projects/lastCreatedLocation",
QDir(locationField->text()).absolutePath());
accept();
});
nameField->setFocus();
Expand Down
Loading
Loading