Remove legacy serialization and QPropertyTree (#684)
Remove: - CryCommon/CryExtension/* - CryCommon/Serialization/* - Sandbox/Plugins/EditorCommon/QPropertyTree/* - All related CryCommon interfaces - All CrySystem implementations - Various related Editor classes
This commit is contained in:
@@ -1,357 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "BatchFileDialog.h"
|
||||
#include "QPropertyTree/QPropertyDialog.h"
|
||||
#include "Serialization/StringList.h"
|
||||
#include "Serialization/STL.h"
|
||||
#include "Serialization/IArchive.h"
|
||||
#include "Serialization/STLImpl.h"
|
||||
#include "IEditor.h"
|
||||
#include "Pak/CryPakUtils.h"
|
||||
#include <vector>
|
||||
#include <AzFramework/Archive/IArchive.h>
|
||||
#include <StringUtils.h>
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
#include <QBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QFileDialog>
|
||||
#include <Util/PathUtil.h>
|
||||
#include <QDirIterator>
|
||||
|
||||
struct SBatchFileItem
|
||||
{
|
||||
bool selected;
|
||||
string path;
|
||||
bool checkable = false;
|
||||
|
||||
bool operator<(const SBatchFileItem& rhs) const { return path < rhs.path; }
|
||||
|
||||
void Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
// -------------------------------------------------------------------
|
||||
// Note: The property tree label modifiers used below indicate...
|
||||
// ! - Readonly, you can't modify the path
|
||||
// ^ - Raise location to the parent (the index indicator)
|
||||
// < - Take up the rest of the space
|
||||
// -------------------------------------------------------------------
|
||||
if (!checkable)
|
||||
{
|
||||
ar(selected, "selected", "^");
|
||||
}
|
||||
|
||||
auto gamePath = PathUtil::MakeGamePath(path);
|
||||
ar(gamePath, "path", "!^<");
|
||||
}
|
||||
};
|
||||
typedef std::vector<SBatchFileItem> SBatchFileItems;
|
||||
|
||||
struct CBatchFileDialog::SContent
|
||||
{
|
||||
SBatchFileItems items;
|
||||
string listLabel;
|
||||
|
||||
SContent(const char* itemsLabelText, bool readonlyList)
|
||||
{
|
||||
// Respect the readonly settings
|
||||
if (readonlyList)
|
||||
{
|
||||
listLabel += "!";
|
||||
}
|
||||
|
||||
// Label Size (5px per character)
|
||||
auto labelSize = static_cast<int>(strlen(itemsLabelText)) * 5;
|
||||
{
|
||||
// Format is: >#>+ where the >#> indicates the label size, and the + indicates end of all row formatting
|
||||
char buffer[16];
|
||||
sprintf_s(buffer, sizeof(buffer), ">%i>+", labelSize);
|
||||
listLabel += buffer;
|
||||
}
|
||||
|
||||
// Add the actual label text (the text that is seen)
|
||||
listLabel += itemsLabelText;
|
||||
}
|
||||
|
||||
void Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(items, "items", listLabel.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
static bool ReadFile(std::vector<char>* buffer, const char* path)
|
||||
{
|
||||
FILE* f = nullptr;
|
||||
azfopen(&f, path, "rb");
|
||||
if (!f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
fseek(f, 0, SEEK_END);
|
||||
size_t len = (size_t)ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
buffer->resize(len);
|
||||
bool result = true;
|
||||
if (len)
|
||||
{
|
||||
result = fread(&(*buffer)[0], 1, len, f) == len;
|
||||
}
|
||||
fclose(f);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void SplitLines(std::vector<string>* lines, const char* start, const char* end)
|
||||
{
|
||||
const char* p = start;
|
||||
const char* lineStart = start;
|
||||
while (true)
|
||||
{
|
||||
if (p == end || *p == '\r' || *p == '\n')
|
||||
{
|
||||
if (p != lineStart)
|
||||
{
|
||||
string line(lineStart, p);
|
||||
bool hasPrintableChars = false;
|
||||
for (size_t i = 0; i < line.size(); ++i)
|
||||
{
|
||||
if (!isspace(line[i]))
|
||||
{
|
||||
hasPrintableChars = true;
|
||||
}
|
||||
}
|
||||
if (hasPrintableChars)
|
||||
{
|
||||
lines->push_back(line);
|
||||
}
|
||||
}
|
||||
lineStart = p + 1;
|
||||
if (p == end)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
static string NormalizePath(const char* path)
|
||||
{
|
||||
string result = path;
|
||||
result.replace('\\', '/');
|
||||
result.MakeLower();
|
||||
|
||||
// strip .phys extensions in case list of .cdf is provided
|
||||
string::size_type dotPos = result.rfind('.');
|
||||
if (dotPos != string::npos)
|
||||
{
|
||||
if (_stricmp(result.c_str() + dotPos, ".phys"))
|
||||
{
|
||||
result.erase(dotPos, 5);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool IsEquivalentPath(const char* pathA, const char* pathB)
|
||||
{
|
||||
string normalizedA = NormalizePath(pathA);
|
||||
string normalizedB = NormalizePath(pathB);
|
||||
return normalizedA == normalizedB;
|
||||
}
|
||||
|
||||
void CBatchFileDialog::OnLoadList()
|
||||
{
|
||||
QString existingFile = QFileDialog::getOpenFileName(m_dialog, "Load file list...", QString(), QString("Text Files (*.txt)"));
|
||||
if (existingFile.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string path = existingFile.toLocal8Bit().data();
|
||||
std::vector<char> content;
|
||||
ReadFile(&content, path.c_str());
|
||||
|
||||
std::vector<string> lines;
|
||||
SplitLines(&lines, &content[0], &content[0] + content.size());
|
||||
|
||||
for (size_t i = 0; i < m_content->items.size(); ++i)
|
||||
{
|
||||
m_content->items[i].selected = false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < lines.size(); ++i)
|
||||
{
|
||||
const char* line = lines[i].c_str();
|
||||
for (size_t j = 0; j < m_content->items.size(); ++j)
|
||||
{
|
||||
const char* itemPath = m_content->items[j].path.c_str();
|
||||
if (IsEquivalentPath(line, itemPath))
|
||||
{
|
||||
m_content->items[j].selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_dialog->revert();
|
||||
}
|
||||
|
||||
void CBatchFileDialog::OnSelectAll()
|
||||
{
|
||||
for (size_t i = 0; i < m_content->items.size(); ++i)
|
||||
{
|
||||
m_content->items[i].selected = true;
|
||||
}
|
||||
|
||||
m_dialog->revert();
|
||||
}
|
||||
|
||||
void CBatchFileDialog::OnSelectNone()
|
||||
{
|
||||
for (size_t i = 0; i < m_content->items.size(); ++i)
|
||||
{
|
||||
m_content->items[i].selected = false;
|
||||
}
|
||||
|
||||
m_dialog->revert();
|
||||
}
|
||||
|
||||
bool EDITOR_COMMON_API ShowBatchFileDialog(Serialization::StringList* result, const SBatchFileSettings& settings, QWidget* parent)
|
||||
{
|
||||
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
||||
|
||||
CBatchFileDialog::SContent content(settings.listLabel, settings.readonlyList);
|
||||
if (settings.scanExtension[0] != '\0')
|
||||
{
|
||||
if (settings.useCryPak)
|
||||
{
|
||||
AZStd::vector<AZStd::string> files;
|
||||
|
||||
string mask = "*.";
|
||||
mask += settings.scanExtension;
|
||||
SDirectoryEnumeratorHelper helper;
|
||||
helper.ScanDirectoryRecursive(gEnv->pCryPak, Path::GetEditingGameDataFolder().c_str(), "", mask.c_str(), files);
|
||||
|
||||
for (int k = 0; k < files.size(); ++k)
|
||||
{
|
||||
SBatchFileItem item;
|
||||
item.checkable = settings.filesAreCheckable;
|
||||
item.selected = true;
|
||||
item.path = { files[k].data(), files[k].size() };
|
||||
content.items.push_back(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string gameFolder = Path::GetEditingGameDataFolder().c_str();
|
||||
string gamePrefix = GetIEditor()->GetPrimaryCDFolder().toUtf8().data();
|
||||
if (!gamePrefix.empty() && gamePrefix[gamePrefix.size() - 1] != '\\')
|
||||
{
|
||||
gamePrefix += "\\";
|
||||
}
|
||||
gamePrefix += gameFolder;
|
||||
if (!gamePrefix.empty() && gamePrefix[gamePrefix.size() - 1] != '\\')
|
||||
{
|
||||
gamePrefix += "\\";
|
||||
}
|
||||
gamePrefix.replace('/', '\\');
|
||||
|
||||
QString mask = "*." + QString(settings.scanExtension);
|
||||
QDirIterator dirIterator(QString(gamePrefix), QStringList() << mask, QDir::Files, QDirIterator::Subdirectories);
|
||||
while (dirIterator.hasNext())
|
||||
{
|
||||
SBatchFileItem item;
|
||||
item.selected = true;
|
||||
QByteArray array = dirIterator.next().toUtf8();
|
||||
item.path = string(array);
|
||||
item.path.replace('/', '\\');
|
||||
content.items.push_back(item);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
content.items.reserve(content.items.size() + settings.explicitFileList.size());
|
||||
for (size_t i = 0; i < settings.explicitFileList.size(); ++i)
|
||||
{
|
||||
SBatchFileItem item;
|
||||
item.path = settings.explicitFileList[i].c_str();
|
||||
item.selected = true;
|
||||
content.items.push_back(item);
|
||||
}
|
||||
|
||||
|
||||
std::sort(content.items.begin(), content.items.end());
|
||||
QApplication::restoreOverrideCursor();
|
||||
|
||||
QPropertyDialog dialog(parent);
|
||||
dialog.setSerializer(Serialization::SStruct(content));
|
||||
dialog.setWindowTitle(settings.title);
|
||||
dialog.setWindowStateFilename(settings.stateFilename);
|
||||
dialog.setSizeHint(QSize(settings.defaultWidth, settings.defaultHeight));
|
||||
dialog.setMinimumSize(QSize(540, 250));
|
||||
|
||||
CBatchFileDialog handler;
|
||||
handler.m_dialog = &dialog;
|
||||
handler.m_content = &content;
|
||||
|
||||
QBoxLayout* topRow = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
QLabel* label = new QLabel(settings.descriptionText);
|
||||
QFont font;
|
||||
font.setBold(true);
|
||||
label->setFont(font);
|
||||
topRow->addWidget(label, 1);
|
||||
{
|
||||
if (settings.allowListLoading && !settings.readonlyList)
|
||||
{
|
||||
QPushButton* loadListButton = new QPushButton("Load List...");
|
||||
QObject::connect(loadListButton, SIGNAL(pressed()), &handler, SLOT(OnLoadList()));
|
||||
topRow->addWidget(loadListButton);
|
||||
}
|
||||
QPushButton* selectAllButton = new QPushButton("Select All");
|
||||
QObject::connect(selectAllButton, SIGNAL(pressed()), &handler, SLOT(OnSelectAll()));
|
||||
topRow->addWidget(selectAllButton);
|
||||
QPushButton* selectNoneButton = new QPushButton("Select None");
|
||||
QObject::connect(selectNoneButton, SIGNAL(pressed()), &handler, SLOT(OnSelectNone()));
|
||||
topRow->addWidget(selectNoneButton);
|
||||
}
|
||||
dialog.layout()->insertLayout(0, topRow);
|
||||
|
||||
if (parent)
|
||||
{
|
||||
QPoint center = parent->rect().center();
|
||||
dialog.window()->move(max(0, center.x() - dialog.width() / 2),
|
||||
max(0, center.y() - dialog.height() / 2));
|
||||
}
|
||||
|
||||
std::vector<string> failedFiles;
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
result->clear();
|
||||
for (size_t i = 0; i < content.items.size(); ++i)
|
||||
{
|
||||
if (content.items[i].selected)
|
||||
{
|
||||
const char* path = content.items[i].path.c_str();
|
||||
result->push_back(path);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#include <moc_BatchFileDialog.cpp>
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_BATCHFILEDIALOG_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_BATCHFILEDIALOG_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "EditorCommonAPI.h"
|
||||
#include <QObject>
|
||||
#include <Serialization/StringList.h>
|
||||
#endif
|
||||
|
||||
// Private class, should not be used directly
|
||||
class QWidget;
|
||||
class QPropertyDialog;
|
||||
class CBatchFileDialog
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public slots:
|
||||
void OnSelectAll();
|
||||
void OnSelectNone();
|
||||
void OnLoadList();
|
||||
|
||||
public:
|
||||
QPropertyDialog* m_dialog;
|
||||
struct SContent;
|
||||
SContent* m_content;
|
||||
};
|
||||
// ^^^
|
||||
|
||||
struct SBatchFileSettings
|
||||
{
|
||||
const char* scanExtension;
|
||||
const char* scanFolder;
|
||||
const char* title;
|
||||
const char* descriptionText;
|
||||
const char* listLabel;
|
||||
const char* stateFilename;
|
||||
bool useCryPak;
|
||||
bool allowListLoading;
|
||||
bool readonlyList;
|
||||
bool filesAreCheckable;
|
||||
Serialization::StringList explicitFileList;
|
||||
int defaultWidth;
|
||||
int defaultHeight;
|
||||
|
||||
SBatchFileSettings()
|
||||
: useCryPak(true)
|
||||
, readonlyList(true)
|
||||
, filesAreCheckable(false)
|
||||
, allowListLoading(true)
|
||||
, descriptionText("Batch Selected Files")
|
||||
, listLabel("Files")
|
||||
, stateFilename("batchFileDialog.state")
|
||||
, title("Batch Files")
|
||||
, scanFolder("")
|
||||
, scanExtension("*")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
bool EDITOR_COMMON_API ShowBatchFileDialog(Serialization::StringList* filenames, const SBatchFileSettings& settings, QWidget* parent);
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_BATCHFILEDIALOG_H
|
||||
@@ -13,8 +13,6 @@ if(NOT PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
|
||||
|
||||
# Header only target to prevent linkage against editor libraries when it is not needed. Eventually the targets that depend
|
||||
# on editor headers should cleanup dependencies and interact with the editor through buses or other mechanisms
|
||||
ly_add_target(
|
||||
@@ -34,7 +32,6 @@ ly_add_target(
|
||||
AUTORCC
|
||||
FILES_CMAKE
|
||||
editorcommon_files.cmake
|
||||
${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
PUBLIC
|
||||
.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,233 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CurveEditorContent.h"
|
||||
#include <QWidget>
|
||||
#include <Range.h>
|
||||
|
||||
class QMenu;
|
||||
class CCurveEditorControl;
|
||||
class CCurveEditorTangentControl;
|
||||
struct ISplineInterpolator;
|
||||
|
||||
enum ETangent
|
||||
{
|
||||
ETangent_In,
|
||||
ETangent_Out
|
||||
};
|
||||
|
||||
enum ECurveEditorCurveType
|
||||
{
|
||||
eCECT_Bezier,
|
||||
// 2D Bezier curves are used for better curve control, the editor
|
||||
// will enforce that the resulting curve is always 1D.
|
||||
eCECT_2DBezier,
|
||||
};
|
||||
|
||||
namespace CurveEditorHelpers
|
||||
{
|
||||
// Picks a nice color value for a curve. Wraps around after 4.
|
||||
EDITOR_COMMON_API ColorB GetCurveColor(const uint n);
|
||||
EDITOR_COMMON_API QColor LerpColor(const QColor& a, const QColor& b, float k);
|
||||
}
|
||||
|
||||
class EDITOR_COMMON_API CCurveEditor
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum EOptOutFlags
|
||||
{
|
||||
EOptOutFree = 1 << 0,
|
||||
EOptOutFlat = 1 << 1,
|
||||
EOptOutLinear = 1 << 2,
|
||||
EOptOutStep = 1 << 3,
|
||||
EOptOutBezier = 1 << 4,
|
||||
EOptOutSelectionKey = 1 << 5,
|
||||
EOptOutSelectionInOutTangent = 1 << 6,
|
||||
//steven@conffx added some optout options to allow easier graphical customization
|
||||
EOptOutKeyIcon = 1 << 7,
|
||||
EOptOutRuler = 1 << 8,
|
||||
EOptOutTimeSlider = 1 << 9,
|
||||
EOptOutBackground = 1 << 10,
|
||||
EOptOutCustomPenColor = 1 << 11,
|
||||
EOptOutControls = 1 << 12,
|
||||
eOptOutDashedPath = 1 << 13,
|
||||
EOptOutDefaultTooltip = 1 << 14,
|
||||
EOptOutFitCurvesContextMenuOptions = 1 << 15,
|
||||
EOptOutZoomingAndPanning = 1 << 16
|
||||
};
|
||||
|
||||
CCurveEditor(QWidget* parent);
|
||||
~CCurveEditor();
|
||||
|
||||
void SetContent(SCurveEditorContent* pContent);
|
||||
SCurveEditorContent* Content() const { return m_pContent; }
|
||||
|
||||
void SetTime(const float time);
|
||||
|
||||
// The background in the time and value range will be drawn a bit brighter to indicate where keys
|
||||
// should be placed. The curve editor does not enforce that the curves actually stay in those ranges.
|
||||
void SetTimeRange(const float start, const float end);
|
||||
void SetValueRange(const float min, const float max);
|
||||
|
||||
// Points cannot be added outside of the time range and the view will not move horizontally...zooming will only be done on the vertical axis
|
||||
void EnforceTimeRange(const float start, const float end);
|
||||
bool IsTimeRangeEnforced() const;
|
||||
|
||||
void ZoomToTimeRange(const float start, const float end);
|
||||
void ZoomToValueRange(const float min, const float max);
|
||||
|
||||
void SetCurveType(ECurveEditorCurveType curveType);
|
||||
void SetWeighted(bool bWeighted);
|
||||
void SetHandlesVisible(bool bVisible);
|
||||
void SetRulerVisible(bool bVisible);
|
||||
void SetTimeSliderVisible(bool bVisible);
|
||||
|
||||
Vec2 TransformToScreenCoordinates(Vec2 graphPoint);
|
||||
Vec2 TransformFromScreenCoordinates(Vec2 screenPoint);
|
||||
|
||||
// Removes parts of the popup-menu, use CCurveEditor::EMenuOptOutFlags
|
||||
void SetOptOutFlags(int flags);
|
||||
|
||||
// Tools added to tool bar depend on options above
|
||||
void PopulateControlContextMenu(QMenu* pToolBar);
|
||||
|
||||
virtual void paintEvent(QPaintEvent* pEvent) override;
|
||||
void mousePressEvent(QMouseEvent* pEvent) override;
|
||||
void mouseDoubleClickEvent(QMouseEvent* pEvent) override;
|
||||
void mouseMoveEvent(QMouseEvent* pEvent) override;
|
||||
void mouseReleaseEvent(QMouseEvent* pEvent) override;
|
||||
void focusOutEvent(QFocusEvent* pEvent) override;
|
||||
void wheelEvent(QWheelEvent* pEvent) override;
|
||||
void keyPressEvent(QKeyEvent* pEvent) override;
|
||||
|
||||
QString static TangentTypeToString(SCurveEditorKey::ETangentType type);
|
||||
|
||||
void updateCurveKeyShapeColor(); // loop through curve keys and set shape color for them
|
||||
void SetIconShapeColor(unsigned int key, QColor color);
|
||||
void SetIconFillColor(unsigned int key, QColor color);
|
||||
void SetIconImage(QString str);
|
||||
void SetIconShapeMask(QColor color);
|
||||
void SetIconFillMask(QColor color);
|
||||
void SetIconToolTip(unsigned int key, QString str);
|
||||
void SetIconSize(unsigned int key, unsigned int size);
|
||||
|
||||
void setPenColor(QColor color);
|
||||
void ContentChanged();
|
||||
void SortKeys(SCurveEditorCurve& curve);
|
||||
|
||||
std::pair<SCurveEditorCurve*, Vec2> HitDetectCurve(const QPoint point);
|
||||
CCurveEditorControl* HitDetectKey(const QPoint point);
|
||||
CCurveEditorTangentControl* HitDetectTangent(const QPoint point);
|
||||
|
||||
CCurveEditorControl* GetSelectedCurveKey();
|
||||
QRectF GetBackgroundRect();
|
||||
|
||||
void SelectKey(CCurveEditorControl* pKeyToSelect, bool addToExistingSelection);
|
||||
void SelectTangent(CCurveEditorTangentControl* pTangentToSelect);
|
||||
void SelectInRect(const QRect& rect);
|
||||
|
||||
signals:
|
||||
void SignalContentChanged();
|
||||
void SignalScrub();
|
||||
void SignalKeyMoved();
|
||||
void SignalKeyMoveStarted();
|
||||
void SignalKeySelected(CCurveEditorControl* selectedKey);
|
||||
|
||||
public slots:
|
||||
void OnDeleteSelectedKeys();
|
||||
void OnSetSelectedKeysTangentStandard();
|
||||
void OnSetSelectedKeysTangentSmooth();
|
||||
void OnSetSelectedKeysTangentFree();
|
||||
void OnSetSelectedKeysTangentBezier();
|
||||
void OnSetSelectedKeysTangentFlat();
|
||||
void OnSetSelectedKeysTangentLinear();
|
||||
|
||||
void OnSetSelectedKeysInTangentFree();
|
||||
void OnSetSelectedKeysInTangentFlat();
|
||||
void OnSetSelectedKeysInTangentLinear();
|
||||
void OnSetSelectedKeysInTangentStep();
|
||||
void OnSetSelectedKeysInTangentBezier();
|
||||
|
||||
void OnSetSelectedKeysOutTangentFree();
|
||||
void OnSetSelectedKeysOutTangentFlat();
|
||||
void OnSetSelectedKeysOutTangentLinear();
|
||||
void OnSetSelectedKeysOutTangentStep();
|
||||
void OnSetSelectedKeysOutTangentBezier();
|
||||
|
||||
void OnFitCurvesHorizontally();
|
||||
void OnFitCurvesVertically();
|
||||
|
||||
protected:
|
||||
struct SMouseHandler
|
||||
{
|
||||
virtual ~SMouseHandler() = default;
|
||||
virtual void mousePressEvent([[maybe_unused]] QMouseEvent* pEvent) {}
|
||||
virtual void mouseDoubleClickEvent([[maybe_unused]] QMouseEvent* pEvent) {}
|
||||
virtual void mouseMoveEvent([[maybe_unused]] QMouseEvent* pEvent) {}
|
||||
virtual void mouseReleaseEvent([[maybe_unused]] QMouseEvent* pEvent) {}
|
||||
virtual void focusOutEvent([[maybe_unused]] QFocusEvent* pEvent) {}
|
||||
virtual void paintOver([[maybe_unused]] QPainter& painter) {}
|
||||
};
|
||||
struct SSelectionHandler;
|
||||
struct SPanHandler;
|
||||
struct SZoomHandler;
|
||||
struct SMoveKeyHandler;
|
||||
struct SRotateTangentHandler;
|
||||
struct SScrubHandler;
|
||||
QColor m_penColor;
|
||||
|
||||
void LeftButtonMousePressEvent(QMouseEvent* pEvent);
|
||||
void MiddleButtonMousePressEvent(QMouseEvent* pEvent);
|
||||
void RightButtonMousePressEvent(QMouseEvent* pEvent);
|
||||
|
||||
void DeleteMarkedKeys();
|
||||
|
||||
void SetTimeRange(const float start, const float end, bool enforce);
|
||||
|
||||
Vec2 ClosestPointOnCurve(const Vec2 point, const SCurveEditorCurve& curve, const ECurveEditorCurveType curveType);
|
||||
|
||||
bool AddPointToCurve(Vec2 point, SCurveEditorCurve* pCurve);
|
||||
|
||||
QRect GetCurveArea();
|
||||
|
||||
void SetSelectedKeysTangentType(const ETangent tangent, const SCurveEditorKey::ETangentType type);
|
||||
void SmoothSelectedKeys();
|
||||
|
||||
void UpdateTangents();
|
||||
SCurveEditorContent* m_pContent;
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
std::unique_ptr<SMouseHandler> m_pMouseHandler;
|
||||
|
||||
ECurveEditorCurveType m_curveType;
|
||||
bool m_bWeighted;
|
||||
bool m_bHandlesVisible;
|
||||
bool m_bRulerVisible;
|
||||
bool m_bTimeSliderVisible;
|
||||
|
||||
float m_time;
|
||||
Vec2 m_zoom;
|
||||
Vec2 m_translation;
|
||||
Range m_timeRange;
|
||||
bool m_timeRangeEnforced;
|
||||
Range m_valueRange;
|
||||
|
||||
int m_optOutFlags;
|
||||
public:
|
||||
QList<CCurveEditorControl*> m_pControlKeys;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
};
|
||||
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Cry_Math.h>
|
||||
#include <Cry_Color.h>
|
||||
|
||||
#include "Serialization/Strings.h"
|
||||
#include "Serialization/SmartPtr.h"
|
||||
#include "Serialization/Color.h"
|
||||
#include "Serialization.h"
|
||||
|
||||
struct ISplineInterpolator;
|
||||
|
||||
struct SCurveEditorKey
|
||||
{
|
||||
SCurveEditorKey()
|
||||
: m_bSelected(false)
|
||||
, m_bModified(false)
|
||||
, m_bAdded(false)
|
||||
, m_bDeleted(false)
|
||||
, m_time(0.0f)
|
||||
, m_value(0.0f)
|
||||
, m_inTangentType(eTangentType_Standard)
|
||||
, m_outTangentType(eTangentType_Standard)
|
||||
, m_inTangent(ZERO)
|
||||
, m_outTangent(ZERO)
|
||||
{
|
||||
}
|
||||
|
||||
enum ETangentType
|
||||
{
|
||||
eTangentType_Standard, // Tangent freely rotates but will stay in sync with its pair if its pair is also standard
|
||||
eTangentType_Free, // Tangent is completely free moving (does not sync with its pair)
|
||||
eTangentType_Step, // Step immediately to value of next control point in tangent direction
|
||||
eTangentType_Linear, // Tangent always points to next control point
|
||||
eTangentType_Bezier, // Tangent is free moving and can be justified by user
|
||||
eTangentType_Smooth, // Tangent is smoothed automatically based on direction/distance to neighboring controls
|
||||
eTangentType_Flat, // Tangent is flattened (y = 0) - will still sync with its pair if both are flat
|
||||
};
|
||||
|
||||
void Serialize(IArchive& ar)
|
||||
{
|
||||
ar(m_inTangentType, "inTangentType");
|
||||
ar(m_outTangentType, "outTangentType");
|
||||
ar(m_time, "time");
|
||||
ar(m_value, "value");
|
||||
ar(m_inTangent, "inTangent");
|
||||
ar(m_outTangent, "outTangent");
|
||||
}
|
||||
|
||||
bool m_bSelected : 1;
|
||||
bool m_bModified : 1;
|
||||
bool m_bAdded : 1;
|
||||
bool m_bDeleted : 1;
|
||||
|
||||
ETangentType m_inTangentType : 4;
|
||||
ETangentType m_outTangentType : 4;
|
||||
|
||||
float m_time;
|
||||
float m_value;
|
||||
|
||||
// For 1D Bezier only the Y component is used
|
||||
Vec2 m_inTangent;
|
||||
Vec2 m_outTangent;
|
||||
|
||||
|
||||
bool operator==(const SCurveEditorKey& rhs) const
|
||||
{
|
||||
return (m_inTangentType == rhs.m_inTangentType
|
||||
&& m_outTangentType == rhs.m_outTangentType
|
||||
&& m_time == rhs.m_time
|
||||
&& m_value == rhs.m_value
|
||||
&& m_inTangent == rhs.m_inTangent
|
||||
&& m_outTangent == rhs.m_outTangent);
|
||||
}
|
||||
|
||||
bool operator!=(const SCurveEditorKey& rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
struct SCurveEditorCurve
|
||||
{
|
||||
SCurveEditorCurve()
|
||||
: m_bModified(false)
|
||||
, m_defaultValue(0.0f)
|
||||
, m_color(255, 255, 255)
|
||||
, m_customInterpolator(nullptr)
|
||||
{}
|
||||
|
||||
void Serialize(IArchive& ar)
|
||||
{
|
||||
ar(m_keys, "keys");
|
||||
ar(m_defaultValue, "defaultValue");
|
||||
ar(m_color, "color");
|
||||
}
|
||||
|
||||
bool m_bModified : 1;
|
||||
float m_defaultValue;
|
||||
ColorB m_color;
|
||||
|
||||
// Setting m_customInterpolator will override spline-draw code.
|
||||
// When used, its up to developer to fill and update all necessary keys.
|
||||
ISplineInterpolator* m_customInterpolator;
|
||||
|
||||
std::vector<SCurveEditorKey> m_keys;
|
||||
|
||||
bool operator==(const SCurveEditorCurve& rhs) const
|
||||
{
|
||||
if (m_defaultValue != rhs.m_defaultValue
|
||||
|| m_color != rhs.m_color
|
||||
|| m_keys.size() != rhs.m_keys.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_keys.size(); i++)
|
||||
{
|
||||
if (m_keys[i] != rhs.m_keys[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const SCurveEditorCurve& rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<SCurveEditorCurve> TCurveEditorCurves;
|
||||
|
||||
struct SCurveEditorContent
|
||||
{
|
||||
void Serialize(IArchive& ar)
|
||||
{
|
||||
ar(m_curves, "curves");
|
||||
}
|
||||
|
||||
TCurveEditorCurves m_curves;
|
||||
};
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Cry_Math.h>
|
||||
#include <Cry_Color.h>
|
||||
#include <Bezier.h>
|
||||
#include <AnimTime.h>
|
||||
|
||||
#include "Serialization/Strings.h"
|
||||
#include "Serialization/SmartPtr.h"
|
||||
#include "Serialization/Color.h"
|
||||
#include "Serialization.h"
|
||||
|
||||
struct SCurveEditorKey
|
||||
{
|
||||
SCurveEditorKey()
|
||||
: m_time(0)
|
||||
, m_bSelected(false)
|
||||
, m_bModified(false)
|
||||
, m_bAdded(false)
|
||||
, m_bDeleted(false)
|
||||
{
|
||||
}
|
||||
|
||||
void Serialize(IArchive& ar)
|
||||
{
|
||||
ar(m_time);
|
||||
ar(m_controlPoint);
|
||||
}
|
||||
|
||||
SAnimTime m_time;
|
||||
SBezierControlPoint m_controlPoint;
|
||||
|
||||
bool m_bSelected : 1;
|
||||
bool m_bModified : 1;
|
||||
bool m_bAdded : 1;
|
||||
bool m_bDeleted : 1;
|
||||
};
|
||||
|
||||
struct SCurveEditorCurve
|
||||
{
|
||||
SCurveEditorCurve()
|
||||
: m_bModified(false)
|
||||
, m_defaultValue(0.0f)
|
||||
, m_color(255, 255, 255)
|
||||
{}
|
||||
|
||||
void Serialize(IArchive& ar)
|
||||
{
|
||||
ar(m_keys, "keys");
|
||||
ar(m_defaultValue, "defaultValue");
|
||||
ar(m_color, "color");
|
||||
}
|
||||
|
||||
bool m_bModified : 1;
|
||||
float m_defaultValue;
|
||||
ColorB m_color;
|
||||
|
||||
DynArray<char> userSideLoad;
|
||||
|
||||
std::vector<SCurveEditorKey> m_keys;
|
||||
};
|
||||
|
||||
typedef std::vector<SCurveEditorCurve> TCurveEditorCurves;
|
||||
|
||||
struct SCurveEditorContent
|
||||
{
|
||||
void Serialize(IArchive& ar)
|
||||
{
|
||||
ar(m_curves, "curves");
|
||||
}
|
||||
|
||||
TCurveEditorCurves m_curves;
|
||||
};
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#include "CurveEditorContent.h"
|
||||
|
||||
SERIALIZATION_ENUM_BEGIN_NESTED(SCurveEditorKey, ETangentType, "TangentType")
|
||||
SERIALIZATION_ENUM_VALUE_NESTED(SCurveEditorKey, eTangentType_Custom, "Custom")
|
||||
SERIALIZATION_ENUM_VALUE_NESTED(SCurveEditorKey, eTangentType_Auto, "Smooth")
|
||||
SERIALIZATION_ENUM_VALUE_NESTED(SCurveEditorKey, eTangentType_Zero, "Zero")
|
||||
SERIALIZATION_ENUM_VALUE_NESTED(SCurveEditorKey, eTangentType_Step, "Step")
|
||||
SERIALIZATION_ENUM_VALUE_NESTED(SCurveEditorKey, eTangentType_Linear, "Linear")
|
||||
SERIALIZATION_ENUM_END()
|
||||
@@ -1,352 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "CurveEditorControl.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QBitmap>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "CurveEditor.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
const int kDefaultControlVisualSize = 8;
|
||||
const int kDefaultControlClickableSize = 10;
|
||||
const int kDefaultTangentControlVisualSize = 6;
|
||||
const int kDefaultTangentControlClickableSize = 8;
|
||||
const int kDefaultTangentControlDistanceFromControl = 30;
|
||||
|
||||
void DrawPointRect(QPainter& painter, QPointF point, const QColor& color, int size)
|
||||
{
|
||||
painter.setBrush(QBrush(color));
|
||||
painter.setPen(QColor(0, 0, 0));
|
||||
float halfSize = size / 2.0f;
|
||||
QPointF extents = QPointF(halfSize, halfSize);
|
||||
painter.drawRect(QRectF(point - extents, point + extents));
|
||||
}
|
||||
}
|
||||
|
||||
CCurveEditorControl::CCurveEditorControl(CCurveEditor& curveEditor, SCurveEditorCurve& curve, SCurveEditorKey& key)
|
||||
: m_CurveEditor(curveEditor)
|
||||
, m_Curve(curve)
|
||||
, m_Key(key)
|
||||
, m_VisualSize(kDefaultControlVisualSize)
|
||||
, m_ClickableSize(kDefaultControlClickableSize)
|
||||
, m_pInTangent(new CCurveEditorTangentControl(*this, ETangent_In))
|
||||
, m_pOutTangent(new CCurveEditorTangentControl(*this, ETangent_Out))
|
||||
, m_filledPxr(kDefaultControlVisualSize, kDefaultControlVisualSize)
|
||||
, m_shapePxr(kDefaultControlVisualSize, kDefaultControlVisualSize)
|
||||
, m_icon(kDefaultControlVisualSize, kDefaultControlVisualSize)
|
||||
, m_originalPxr(kDefaultControlVisualSize, kDefaultControlVisualSize)
|
||||
, m_tip("")
|
||||
, m_iconsize(16)
|
||||
{
|
||||
}
|
||||
|
||||
CCurveEditorControl::~CCurveEditorControl()
|
||||
{
|
||||
delete m_pInTangent;
|
||||
delete m_pOutTangent;
|
||||
}
|
||||
|
||||
CCurveEditor& CCurveEditorControl::GetCurveEditor() const
|
||||
{
|
||||
return m_CurveEditor;
|
||||
}
|
||||
|
||||
SCurveEditorCurve& CCurveEditorControl::GetCurve() const
|
||||
{
|
||||
return m_Curve;
|
||||
}
|
||||
|
||||
SCurveEditorKey& CCurveEditorControl::GetKey() const
|
||||
{
|
||||
return m_Key;
|
||||
}
|
||||
|
||||
CCurveEditorTangentControl& CCurveEditorControl::GetInTangent()
|
||||
{
|
||||
return *m_pInTangent;
|
||||
}
|
||||
|
||||
CCurveEditorTangentControl& CCurveEditorControl::GetOutTangent()
|
||||
{
|
||||
return *m_pOutTangent;
|
||||
}
|
||||
|
||||
bool CCurveEditorControl::IsSelected() const
|
||||
{
|
||||
return m_Key.m_bSelected;
|
||||
}
|
||||
|
||||
void CCurveEditorControl::SetSelected(bool selected)
|
||||
{
|
||||
m_Key.m_bSelected = selected;
|
||||
m_pInTangent->SetVisible(selected);
|
||||
m_pOutTangent->SetVisible(selected);
|
||||
}
|
||||
|
||||
bool CCurveEditorControl::IsKeyMarkedForRemoval() const
|
||||
{
|
||||
return m_Key.m_bDeleted;
|
||||
}
|
||||
|
||||
void CCurveEditorControl::MarkKeyForRemoval()
|
||||
{
|
||||
m_Key.m_bDeleted = true;
|
||||
}
|
||||
|
||||
void CCurveEditorControl::Paint(QPainter& painter, const QPalette& palette, const bool& paintInOutTangents)
|
||||
{
|
||||
const QColor pointColor = m_Key.m_bSelected ? palette.color(QPalette::Highlight) : QColor(255, 255, 255, 255);
|
||||
|
||||
if (paintInOutTangents)
|
||||
{
|
||||
m_pInTangent->Paint(painter, palette);
|
||||
m_pOutTangent->Paint(painter, palette);
|
||||
}
|
||||
|
||||
DrawPointRect(painter, GetScreenPosition(), pointColor, m_VisualSize);
|
||||
}
|
||||
void CCurveEditorControl::PaintIcon(QPainter& painter, const QPalette& palette, const bool& paintInOutTangents)
|
||||
{
|
||||
if (paintInOutTangents)
|
||||
{
|
||||
m_pInTangent->Paint(painter, palette);
|
||||
m_pOutTangent->Paint(painter, palette);
|
||||
}
|
||||
|
||||
QPointF pos = GetScreenPosition();
|
||||
float halfSize = m_iconsize / 2.0f;
|
||||
QPointF extents = QPointF(halfSize, halfSize);
|
||||
painter.drawPixmap(QRectF(GetScreenPosition() - extents, GetScreenPosition() + extents), m_icon, QRectF(0, 0, m_iconsize, m_iconsize));
|
||||
}
|
||||
|
||||
bool CCurveEditorControl::IsMouseWithinControl(QPointF screenPos) const
|
||||
{
|
||||
QPointF keyPosition = GetScreenPosition();
|
||||
QPointF deltaPos = screenPos - keyPosition;
|
||||
|
||||
float halfClickSize = m_ClickableSize / 2.0f;
|
||||
|
||||
return abs(deltaPos.x()) <= halfClickSize && abs(deltaPos.y()) <= halfClickSize;
|
||||
}
|
||||
|
||||
QPointF CCurveEditorControl::GetScreenPosition() const
|
||||
{
|
||||
Vec2 screenPosition = m_CurveEditor.TransformToScreenCoordinates(Vec2(m_Key.m_time, m_Key.m_value));
|
||||
return QPointF(screenPosition.x, screenPosition.y);
|
||||
}
|
||||
|
||||
void CCurveEditorControl::BuildIcon()
|
||||
{
|
||||
m_filledPxr = QPixmap(m_originalPxr.size());
|
||||
m_shapePxr = QPixmap(m_originalPxr.size());
|
||||
m_shapePxr.fill(m_shapeColor);
|
||||
m_filledPxr.fill(m_fillColor);
|
||||
m_shapePxr.setMask(m_originalPxr.createMaskFromColor(m_shapeMask).createMaskFromColor(m_fillMask));
|
||||
m_filledPxr.setMask(m_originalPxr.createMaskFromColor(m_fillMask, Qt::MaskOutColor));
|
||||
QPainter painter(&m_shapePxr);
|
||||
painter.drawPixmap(0, 0, m_filledPxr);
|
||||
m_icon = m_shapePxr.scaled(m_iconsize, m_iconsize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
|
||||
void CCurveEditorControl::SetIconFillMask(QColor color)
|
||||
{
|
||||
m_fillMask = color;
|
||||
BuildIcon();
|
||||
}
|
||||
|
||||
void CCurveEditorControl::SetIconShapeMask(QColor color)
|
||||
{
|
||||
m_shapeMask = color;
|
||||
BuildIcon();
|
||||
}
|
||||
|
||||
void CCurveEditorControl::SetIconImage(QString str)
|
||||
{
|
||||
m_originalPxr.load(str);
|
||||
BuildIcon();
|
||||
}
|
||||
|
||||
void CCurveEditorControl::SetIconFillColor(QColor color)
|
||||
{
|
||||
m_fillColor = color;
|
||||
BuildIcon();
|
||||
}
|
||||
|
||||
void CCurveEditorControl::SetIconShapeColor(QColor color)
|
||||
{
|
||||
m_shapeColor = color;
|
||||
BuildIcon();
|
||||
}
|
||||
|
||||
|
||||
CCurveEditorTangentControl::CCurveEditorTangentControl(CCurveEditorControl& control, ETangent tangentDirection)
|
||||
: m_Control(control)
|
||||
, m_TangentDirection(tangentDirection)
|
||||
, m_Visible(false)
|
||||
, m_Selected(false)
|
||||
, m_VisualSize(kDefaultTangentControlVisualSize)
|
||||
, m_ClickableSize(kDefaultTangentControlClickableSize)
|
||||
, m_DistanceFromControl(kDefaultTangentControlDistanceFromControl)
|
||||
{
|
||||
}
|
||||
|
||||
CCurveEditorTangentControl::~CCurveEditorTangentControl()
|
||||
{
|
||||
}
|
||||
|
||||
CCurveEditorControl& CCurveEditorTangentControl::GetControl()
|
||||
{
|
||||
return m_Control;
|
||||
}
|
||||
|
||||
ETangent CCurveEditorTangentControl::GetTangentDirection() const
|
||||
{
|
||||
return m_TangentDirection;
|
||||
}
|
||||
|
||||
bool CCurveEditorTangentControl::IsVisible() const
|
||||
{
|
||||
if (!m_Visible)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
SCurveEditorKey::ETangentType tangentType;
|
||||
|
||||
if (m_TangentDirection == ETangent_In)
|
||||
{
|
||||
tangentType = m_Control.GetKey().m_inTangentType;
|
||||
}
|
||||
else
|
||||
{
|
||||
tangentType = m_Control.GetKey().m_outTangentType;
|
||||
}
|
||||
|
||||
if (tangentType == SCurveEditorKey::eTangentType_Step)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// first in
|
||||
if ((*m_Control.GetCurve().m_keys.begin()).m_time == m_Control.GetKey().m_time && m_TangentDirection == ETangent_In)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// last out
|
||||
if ((*(m_Control.GetCurve().m_keys.end() - 1)).m_time == m_Control.GetKey().m_time && m_TangentDirection == ETangent_Out)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CCurveEditorTangentControl::SetVisible(bool visible)
|
||||
{
|
||||
m_Visible = visible;
|
||||
}
|
||||
|
||||
bool CCurveEditorTangentControl::IsSelected() const
|
||||
{
|
||||
return m_Selected;
|
||||
}
|
||||
|
||||
void CCurveEditorTangentControl::SetSelected(bool selected)
|
||||
{
|
||||
m_Selected = selected;
|
||||
}
|
||||
|
||||
void CCurveEditorTangentControl::SetVisualSize(int visualSize)
|
||||
{
|
||||
m_VisualSize = visualSize;
|
||||
}
|
||||
|
||||
void CCurveEditorTangentControl::SetClickableSize(int clickableSize)
|
||||
{
|
||||
m_ClickableSize = clickableSize;
|
||||
}
|
||||
|
||||
void CCurveEditorTangentControl::SetDistanceFromControl(int distanceFromControl)
|
||||
{
|
||||
m_DistanceFromControl = distanceFromControl;
|
||||
}
|
||||
|
||||
void CCurveEditorTangentControl::Paint(QPainter& painter, const QPalette& palette)
|
||||
{
|
||||
if (!IsVisible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QPointF controlPosition = m_Control.GetScreenPosition();
|
||||
QPointF tangentPosition = GetScreenPosition();
|
||||
|
||||
float highlightPercent;
|
||||
if (m_Selected)
|
||||
{
|
||||
highlightPercent = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
highlightPercent = 0.5f;
|
||||
}
|
||||
const QColor tangentColor = CurveEditorHelpers::LerpColor(palette.color(QPalette::Highlight), palette.color(QPalette::Window), highlightPercent);
|
||||
const QPen tangentPen = QPen(tangentColor);
|
||||
|
||||
painter.setPen(tangentPen);
|
||||
painter.drawLine(controlPosition, tangentPosition);
|
||||
|
||||
const QColor tangentControlColor = m_Selected ? palette.color(QPalette::Highlight) : palette.color(QPalette::Dark);
|
||||
DrawPointRect(painter, tangentPosition, tangentControlColor, m_VisualSize);
|
||||
}
|
||||
|
||||
bool CCurveEditorTangentControl::IsMouseWithinControl(QPointF screenPos) const
|
||||
{
|
||||
if (!IsVisible())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QPointF keyPosition = GetScreenPosition();
|
||||
QPointF deltaPos = screenPos - keyPosition;
|
||||
|
||||
float halfClickSize = m_ClickableSize / 2.0f;
|
||||
|
||||
return abs(deltaPos.x()) <= halfClickSize && abs(deltaPos.y()) <= halfClickSize;
|
||||
}
|
||||
|
||||
QPointF CCurveEditorTangentControl::GetScreenPosition() const
|
||||
{
|
||||
QPointF controlPosition = m_Control.GetScreenPosition();
|
||||
|
||||
Vec2 tangent;
|
||||
if (m_TangentDirection == ETangent_In)
|
||||
{
|
||||
tangent = m_Control.GetKey().m_inTangent;
|
||||
}
|
||||
else
|
||||
{
|
||||
tangent = m_Control.GetKey().m_outTangent;
|
||||
}
|
||||
|
||||
Vec2 tangentScreenPosition = m_Control.GetCurveEditor().TransformToScreenCoordinates(Vec2(m_Control.GetKey().m_time + tangent.x, m_Control.GetKey().m_value + tangent.y));
|
||||
Vec2 transformedTangentDelta = (tangentScreenPosition - Vec2(aznumeric_cast<float>(controlPosition.x()), aznumeric_cast<float>(controlPosition.y()))).Normalize() * aznumeric_cast<float>(m_DistanceFromControl);
|
||||
|
||||
return controlPosition + QPointF(transformedTangentDelta.x, transformedTangentDelta.y);
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CurveEditor.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class CCurveEditor;
|
||||
class CCurveEditorTangentControl;
|
||||
class QMouseEvent;
|
||||
|
||||
class QPainter;
|
||||
|
||||
class EDITOR_COMMON_API CCurveEditorControl
|
||||
{
|
||||
public:
|
||||
CCurveEditorControl(CCurveEditor& curveEditor, SCurveEditorCurve& curve, SCurveEditorKey& key);
|
||||
~CCurveEditorControl();
|
||||
|
||||
CCurveEditor& GetCurveEditor() const;
|
||||
SCurveEditorCurve& GetCurve() const;
|
||||
SCurveEditorKey& GetKey() const;
|
||||
|
||||
CCurveEditorTangentControl& GetInTangent();
|
||||
CCurveEditorTangentControl& GetOutTangent();
|
||||
|
||||
void SetVisualSize(int visualSize)
|
||||
{
|
||||
m_VisualSize = visualSize;
|
||||
}
|
||||
void SetClickableSize(int clickableSize)
|
||||
{
|
||||
m_ClickableSize = clickableSize;
|
||||
}
|
||||
|
||||
bool IsSelected() const;
|
||||
void SetSelected(bool selected);
|
||||
|
||||
bool IsKeyMarkedForRemoval() const;
|
||||
void MarkKeyForRemoval();
|
||||
|
||||
void Paint(QPainter& painter, const QPalette& palette, const bool& paintInOutTangents);
|
||||
void PaintIcon(QPainter& painter, const QPalette& palette, const bool& paintInOutTangents);
|
||||
|
||||
bool IsMouseWithinControl(QPointF screenPos) const;
|
||||
|
||||
QPointF GetScreenPosition() const;
|
||||
|
||||
QRect GetRect() const
|
||||
{
|
||||
return QRect(aznumeric_cast<int>(GetScreenPosition().x() - (m_VisualSize / 2)), aznumeric_cast<int>(GetScreenPosition().y() - (m_VisualSize / 2)), m_VisualSize, m_VisualSize);
|
||||
}
|
||||
|
||||
void SetIconShapeColor(QColor color);
|
||||
|
||||
void SetIconFillColor(QColor color);
|
||||
|
||||
void SetIconImage(QString str);
|
||||
|
||||
void SetIconShapeMask(QColor color);
|
||||
|
||||
void SetIconFillMask(QColor color);
|
||||
|
||||
void SetIconToolTip(QString str)
|
||||
{
|
||||
m_tip = str;
|
||||
}
|
||||
|
||||
void SetIconSize(int size)
|
||||
{
|
||||
m_iconsize = size;
|
||||
BuildIcon();
|
||||
}
|
||||
|
||||
QString GetToolTip() const { return m_tip; }
|
||||
|
||||
protected:
|
||||
void BuildIcon();
|
||||
|
||||
private:
|
||||
QPixmap m_icon;
|
||||
QPixmap m_filledPxr;
|
||||
QPixmap m_shapePxr;
|
||||
QPixmap m_originalPxr;
|
||||
QColor m_fillColor;
|
||||
QColor m_shapeColor;
|
||||
QColor m_fillMask;
|
||||
QColor m_shapeMask;
|
||||
QString m_tip;
|
||||
int m_iconsize;
|
||||
|
||||
CCurveEditor& m_CurveEditor;
|
||||
SCurveEditorCurve& m_Curve;
|
||||
SCurveEditorKey& m_Key;
|
||||
|
||||
int m_VisualSize;
|
||||
int m_ClickableSize;
|
||||
|
||||
CCurveEditorTangentControl* m_pInTangent;
|
||||
CCurveEditorTangentControl* m_pOutTangent;
|
||||
};
|
||||
|
||||
class EDITOR_COMMON_API CCurveEditorTangentControl
|
||||
{
|
||||
public:
|
||||
CCurveEditorTangentControl(CCurveEditorControl& curveControl, ETangent tangentDirection);
|
||||
~CCurveEditorTangentControl();
|
||||
|
||||
CCurveEditorControl& GetControl();
|
||||
ETangent GetTangentDirection() const;
|
||||
|
||||
bool IsVisible() const;
|
||||
void SetVisible(bool visible);
|
||||
|
||||
bool IsSelected() const;
|
||||
void SetSelected(bool selected);
|
||||
|
||||
void SetVisualSize(int visualSize);
|
||||
void SetClickableSize(int clickableSize);
|
||||
void SetDistanceFromControl(int distanceFromControl);
|
||||
|
||||
void Paint(QPainter& painter, const QPalette& palette);
|
||||
|
||||
bool IsMouseWithinControl(QPointF screenPos) const;
|
||||
|
||||
private:
|
||||
|
||||
QPointF GetScreenPosition() const;
|
||||
|
||||
CCurveEditorControl& m_Control;
|
||||
ETangent m_TangentDirection;
|
||||
|
||||
bool m_Selected;
|
||||
|
||||
int m_VisualSize;
|
||||
int m_ClickableSize;
|
||||
int m_DistanceFromControl;
|
||||
|
||||
bool m_Visible;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CurveEditorContent.h"
|
||||
#include <QWidget>
|
||||
#include <Range.h>
|
||||
#include <AnimTime.h>
|
||||
|
||||
class QToolBar;
|
||||
|
||||
enum ECurveEditorCurveType
|
||||
{
|
||||
eCECT_Bezier,
|
||||
// 2D Bezier curves are used for better curve control, the editor
|
||||
// will enforce that the resulting curve is always 1D.
|
||||
eCECT_2DBezier,
|
||||
};
|
||||
|
||||
namespace CurveEditorHelpers
|
||||
{
|
||||
// Picks a nice color value for a curve. Wraps around after 4.
|
||||
EDITOR_COMMON_API ColorB GetCurveColor(const uint n);
|
||||
}
|
||||
|
||||
class EDITOR_COMMON_API CCurveEditor
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CCurveEditor(QWidget* parent);
|
||||
~CCurveEditor();
|
||||
|
||||
void SetContent(SCurveEditorContent* pContent);
|
||||
SCurveEditorContent* Content() const { return m_pContent; }
|
||||
|
||||
SAnimTime Time() const { return m_time; }
|
||||
void SetTime(const SAnimTime time);
|
||||
|
||||
// The background in the time and value range will be drawn a bit brighter to indicate where keys
|
||||
// should be placed. The curve editor does not enforce that the curves actually stay in those ranges.
|
||||
void SetTimeRange(const SAnimTime start, const SAnimTime end);
|
||||
void SetValueRange(const float min, const float max);
|
||||
|
||||
void ZoomToTimeRange(const float start, const float end);
|
||||
void ZoomToValueRange(const float min, const float max);
|
||||
|
||||
void SetCurveType(ECurveEditorCurveType curveType);
|
||||
void SetWeighted(bool bWeighted);
|
||||
void SetHandlesVisible(bool bVisible);
|
||||
void SetRulerVisible(bool bVisible);
|
||||
void SetTimeSliderVisible(bool bVisible);
|
||||
void SetGridVisible(bool bVisible);
|
||||
void SetFrameRate(SAnimTime::EFrameRate frameRate) { m_frameRate = frameRate; }
|
||||
void SetTimeSnapping(bool snapTime) { m_bSnapTime = snapTime; }
|
||||
void SetKeySnapping(bool snapKeys) { m_bSnapKeys = snapKeys; }
|
||||
|
||||
// Tools added to tool bar depend on options above
|
||||
void FillWithCurveToolsAndConnect(QToolBar* pToolBar);
|
||||
|
||||
void paintEvent(QPaintEvent* pEvent) override;
|
||||
void mousePressEvent(QMouseEvent* pEvent) override;
|
||||
void mouseDoubleClickEvent(QMouseEvent* pEvent) override;
|
||||
void mouseMoveEvent(QMouseEvent* pEvent) override;
|
||||
void mouseReleaseEvent(QMouseEvent* pEvent) override;
|
||||
void focusOutEvent(QFocusEvent* pEvent) override;
|
||||
void wheelEvent(QWheelEvent* pEvent) override;
|
||||
void keyPressEvent(QKeyEvent* pEvent) override;
|
||||
|
||||
signals:
|
||||
void SignalContentChanged();
|
||||
void SignalScrub();
|
||||
|
||||
public slots:
|
||||
void OnDeleteSelectedKeys();
|
||||
void OnSetSelectedKeysTangentAuto();
|
||||
void OnSetSelectedKeysInTangentZero();
|
||||
void OnSetSelectedKeysInTangentStep();
|
||||
void OnSetSelectedKeysInTangentLinear();
|
||||
void OnSetSelectedKeysOutTangentZero();
|
||||
void OnSetSelectedKeysOutTangentStep();
|
||||
void OnSetSelectedKeysOutTangentLinear();
|
||||
void OnFitCurvesHorizontally();
|
||||
void OnFitCurvesVertically();
|
||||
void OnBreakTangents();
|
||||
void OnUnifyTangents();
|
||||
|
||||
private:
|
||||
struct SMouseHandler;
|
||||
struct SSelectionHandler;
|
||||
struct SPanHandler;
|
||||
struct SZoomHandler;
|
||||
struct SMoveHandler;
|
||||
struct SHandleMoveHandler;
|
||||
struct SScrubHandler;
|
||||
enum ETangent;
|
||||
|
||||
void DrawGrid(QPainter& painter, const QPalette& palette);
|
||||
|
||||
void LeftButtonMousePressEvent(QMouseEvent* pEvent);
|
||||
void MiddleButtonMousePressEvent(QMouseEvent* pEvent);
|
||||
void RightButtonMousePressEvent(QMouseEvent* pEvent);
|
||||
|
||||
void SelectInRect(const QRect& rect);
|
||||
|
||||
void ContentChanged();
|
||||
void DeleteMarkedKeys();
|
||||
|
||||
std::pair<SCurveEditorCurve*, Vec2> HitDetectCurve(const QPoint point);
|
||||
std::pair<SCurveEditorCurve*, SCurveEditorKey*> HitDetectKey(const QPoint point);
|
||||
std::tuple<SCurveEditorCurve*, SCurveEditorKey, SCurveEditorKey*, ETangent> HitDetectHandle(const QPoint point);
|
||||
Vec2 ClosestPointOnCurve(const Vec2 point, const SCurveEditorCurve& curve, const ECurveEditorCurveType curveType);
|
||||
|
||||
void AddPointToCurve(Vec2 point, SCurveEditorCurve* pCurve);
|
||||
void SortKeys(SCurveEditorCurve& curve);
|
||||
|
||||
QRect GetCurveArea();
|
||||
|
||||
enum ETangent
|
||||
{
|
||||
ETangent_In,
|
||||
ETangent_Out
|
||||
};
|
||||
|
||||
void SetSelectedKeysTangentType(const ETangent tangent, const SBezierControlPoint::ETangentType type);
|
||||
|
||||
SCurveEditorContent* m_pContent;
|
||||
std::unique_ptr<SMouseHandler> m_pMouseHandler;
|
||||
|
||||
ECurveEditorCurveType m_curveType;
|
||||
SAnimTime::EFrameRate m_frameRate;
|
||||
bool m_bWeighted : 1;
|
||||
bool m_bHandlesVisible : 1;
|
||||
bool m_bRulerVisible : 1;
|
||||
bool m_bTimeSliderVisible : 1;
|
||||
bool m_bGridVisible : 1;
|
||||
bool m_bSnapTime : 1;
|
||||
bool m_bSnapKeys : 1;
|
||||
|
||||
SAnimTime m_time;
|
||||
Vec2 m_zoom;
|
||||
Vec2 m_translation;
|
||||
TRange<SAnimTime> m_timeRange;
|
||||
Range m_valueRange;
|
||||
};
|
||||
@@ -1,194 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
//Cry
|
||||
#include <Cry_Camera.h>
|
||||
|
||||
//Editor
|
||||
#include <Util/EditorUtils.h>
|
||||
#include <Util/Math.h>
|
||||
|
||||
//Local
|
||||
#include "QViewport.h"
|
||||
#include "DisplayViewportAdapter.h"
|
||||
|
||||
CDisplayViewportAdapter::CDisplayViewportAdapter(QViewport* viewport)
|
||||
: m_viewport(viewport)
|
||||
{
|
||||
m_screenMatrix.SetIdentity();
|
||||
}
|
||||
|
||||
void CDisplayViewportAdapter::Update()
|
||||
{
|
||||
}
|
||||
|
||||
const Matrix34& CDisplayViewportAdapter::GetScreenTM() const
|
||||
{
|
||||
return m_screenMatrix;
|
||||
}
|
||||
|
||||
float CDisplayViewportAdapter::GetScreenScaleFactor(const Vec3& position) const
|
||||
{
|
||||
float dist = m_viewport->Camera()->GetPosition().GetDistance(position);
|
||||
if (dist < m_viewport->Camera()->GetNearPlane())
|
||||
{
|
||||
dist = m_viewport->Camera()->GetNearPlane();
|
||||
}
|
||||
return dist;
|
||||
}
|
||||
|
||||
float CDisplayViewportAdapter::GetScreenScaleFactor([[maybe_unused]] const CCamera& camera, [[maybe_unused]] const Vec3& object_position)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool CDisplayViewportAdapter::HitTestLine(const Vec3& lineP1, const Vec3& lineP2, const QPoint& hitpoint, int pixelRadius, float* pToCameraDistance) const
|
||||
{
|
||||
float dist = GetDistanceToLine(lineP1, lineP2, hitpoint);
|
||||
if (dist <= pixelRadius)
|
||||
{
|
||||
if (pToCameraDistance)
|
||||
{
|
||||
Vec3 raySrc, rayDir;
|
||||
ViewToWorldRay(hitpoint, raySrc, rayDir);
|
||||
Vec3 rayTrg = raySrc + rayDir * 10000.0f;
|
||||
|
||||
Vec3 pa, pb;
|
||||
float mua, mub;
|
||||
LineLineIntersect(lineP1, lineP2, raySrc, rayTrg, pa, pb, mua, mub);
|
||||
*pToCameraDistance = mub;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
float CDisplayViewportAdapter::GetDistanceToLine(const Vec3& lineP1, const Vec3& lineP2, const QPoint& point) const
|
||||
{
|
||||
QPoint p1 = WorldToView(lineP1);
|
||||
QPoint p2 = WorldToView(lineP2);
|
||||
|
||||
return PointToLineDistance2D(
|
||||
Vec3(float(p1.x()), float(p1.y()), 0),
|
||||
Vec3(float(p2.x()), float(p2.y()), 0),
|
||||
Vec3(float(point.x()), float(point.y()), 0));
|
||||
}
|
||||
|
||||
CBaseObjectsCache* CDisplayViewportAdapter::GetVisibleObjectsCache()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CDisplayViewportAdapter::IsBoundsVisible([[maybe_unused]] const AABB& box) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void CDisplayViewportAdapter::GetPerpendicularAxis(EAxis* axis, bool* is2D) const
|
||||
{
|
||||
*axis = AXIS_NONE;
|
||||
*is2D = false;
|
||||
}
|
||||
|
||||
const Matrix34& CDisplayViewportAdapter::GetViewTM() const
|
||||
{
|
||||
m_viewMatrix = m_viewport->Camera()->GetViewMatrix();
|
||||
return m_viewMatrix;
|
||||
}
|
||||
|
||||
QPoint CDisplayViewportAdapter::WorldToView(const Vec3& worldPoint) const
|
||||
{
|
||||
return m_viewport->ProjectToScreen(worldPoint);
|
||||
}
|
||||
|
||||
QPoint CDisplayViewportAdapter::WorldToViewParticleEditor(const Vec3& worldPoint, [[maybe_unused]] int width, [[maybe_unused]] int height) const
|
||||
{
|
||||
return m_viewport->ProjectToScreen(worldPoint);
|
||||
}
|
||||
|
||||
Vec3 CDisplayViewportAdapter::WorldToView3D([[maybe_unused]] const Vec3& worldPoint, [[maybe_unused]] int flags) const
|
||||
{
|
||||
return Vec3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
Vec3 CDisplayViewportAdapter::ViewToWorld([[maybe_unused]] const QPoint& vp, [[maybe_unused]] bool* collideWithTerrain, [[maybe_unused]] bool onlyTerrain, [[maybe_unused]] bool bSkipVegetation, [[maybe_unused]] bool bTestRenderMesh, [[maybe_unused]] bool* collideWithObject) const
|
||||
{
|
||||
return Vec3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void CDisplayViewportAdapter::ViewToWorldRay(const QPoint& vp, Vec3& raySrc, Vec3& rayDir) const
|
||||
{
|
||||
Ray ray;
|
||||
// this can fail for number of reasons
|
||||
if (!m_viewport->ScreenToWorldRay(&ray, vp.x(), vp.y()))
|
||||
{
|
||||
// return some "safe" default that will not cause FPE
|
||||
raySrc = m_viewport->Camera()->GetPosition();
|
||||
rayDir = m_viewport->Camera()->GetViewdir();
|
||||
|
||||
// the interface should be changed to accommodate for error
|
||||
return;
|
||||
}
|
||||
raySrc = ray.origin;
|
||||
rayDir = ray.direction;
|
||||
}
|
||||
|
||||
float CDisplayViewportAdapter::GetGridStep() const
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
float CDisplayViewportAdapter::GetAspectRatio() const
|
||||
{
|
||||
int w, h;
|
||||
GetDimensions(&w, &h);
|
||||
if (h != 0)
|
||||
{
|
||||
return float(w) / h;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
const Plane* CDisplayViewportAdapter::GetConstructionPlane() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CDisplayViewportAdapter::ScreenToClient([[maybe_unused]] QPoint& pt) const
|
||||
{
|
||||
}
|
||||
|
||||
void CDisplayViewportAdapter::GetDimensions(int* width, int* height) const
|
||||
{
|
||||
if (width)
|
||||
{
|
||||
*width = m_viewport->Width();
|
||||
}
|
||||
if (height)
|
||||
{
|
||||
*height = m_viewport->Height();
|
||||
}
|
||||
}
|
||||
|
||||
void CDisplayViewportAdapter::setRay([[maybe_unused]] QPoint& vp, [[maybe_unused]] Vec3& raySrc, [[maybe_unused]] Vec3& rayDir)
|
||||
{
|
||||
}
|
||||
|
||||
void CDisplayViewportAdapter::setHitcontext([[maybe_unused]] QPoint& vp, [[maybe_unused]] Vec3& raySrc, [[maybe_unused]] Vec3& rayDir)
|
||||
{
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
//Cry
|
||||
#include <Cry_Math.h>
|
||||
#include "Cry_Matrix34.h"
|
||||
#include "Cry_Vector3.h"
|
||||
|
||||
//Editor
|
||||
#include "Include/IDisplayViewport.h"
|
||||
|
||||
//Local
|
||||
#include "EditorCommonAPI.h"
|
||||
|
||||
class EDITOR_COMMON_API QViewport;
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
|
||||
class EDITOR_COMMON_API CDisplayViewportAdapter
|
||||
: public ::IDisplayViewport
|
||||
{
|
||||
public:
|
||||
AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
|
||||
CDisplayViewportAdapter(QViewport* viewport);
|
||||
|
||||
void Update() override;
|
||||
const Matrix34& GetScreenTM() const override;
|
||||
float GetScreenScaleFactor(const Vec3& position) const override;
|
||||
float GetScreenScaleFactor(const CCamera& camera, const Vec3& object_position) override;
|
||||
bool HitTestLine(const Vec3& lineP1, const Vec3& lineP2, const QPoint& hitpoint, int pixelRadius, float* pToCameraDistance = 0) const override;
|
||||
float GetDistanceToLine(const Vec3& lineP1, const Vec3& lineP2, const QPoint& point) const override;
|
||||
CBaseObjectsCache* GetVisibleObjectsCache() override;
|
||||
bool IsBoundsVisible(const AABB& box) const override;
|
||||
void GetPerpendicularAxis(EAxis* axis, bool* is2D) const override;
|
||||
const Matrix34& GetViewTM() const override;
|
||||
QPoint WorldToView(const Vec3& worldPoint) const override;
|
||||
QPoint WorldToViewParticleEditor(const Vec3& worldPoint, int width, int height) const override;
|
||||
Vec3 WorldToView3D(const Vec3& worldPoint, int flags = 0) const override;
|
||||
Vec3 ViewToWorld(const QPoint& vp, bool* collideWithTerrain = nullptr, bool onlyTerrain = false, bool bSkipVegetation = false, bool bTestRenderMesh = false, bool* collideWithObject = nullptr) const override;
|
||||
void ViewToWorldRay(const QPoint& vp, Vec3& raySrc, Vec3& rayDir) const override;
|
||||
float GetGridStep() const override;
|
||||
float GetAspectRatio() const override;
|
||||
const Plane* GetConstructionPlane() const override;
|
||||
void ScreenToClient(QPoint& pt) const override;
|
||||
void GetDimensions(int* width, int* height) const override;
|
||||
void setRay(QPoint& vp, Vec3& raySrc, Vec3& rayDir) override;
|
||||
void setHitcontext(QPoint& vp, Vec3& raySrc, Vec3& rayDir) override;
|
||||
|
||||
private:
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
mutable Matrix34 m_viewMatrix;
|
||||
Matrix34 m_screenMatrix;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
QViewport* m_viewport;
|
||||
};
|
||||
@@ -16,13 +16,16 @@
|
||||
#include <QStyleOptionToolButton>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
|
||||
static QColor Interpolate(const QColor& a, const QColor& b, float k)
|
||||
namespace DockTitleBarInterpolate
|
||||
{
|
||||
float mk = 1.0f - k;
|
||||
return QColor(aznumeric_cast<int>(a.red() * mk + b.red() * k),
|
||||
aznumeric_cast<int>(a.green() * mk + b.green() * k),
|
||||
aznumeric_cast<int>(a.blue() * mk + b.blue() * k),
|
||||
aznumeric_cast<int>(a.alpha() * mk + b.alpha() * k));
|
||||
static QColor Interpolate(const QColor& a, const QColor& b, float k)
|
||||
{
|
||||
float mk = 1.0f - k;
|
||||
return QColor(aznumeric_cast<int>(a.red() * mk + b.red() * k),
|
||||
aznumeric_cast<int>(a.green() * mk + b.green() * k),
|
||||
aznumeric_cast<int>(a.blue() * mk + b.blue() * k),
|
||||
aznumeric_cast<int>(a.alpha() * mk + b.alpha() * k));
|
||||
}
|
||||
}
|
||||
|
||||
class CDockWidgetTitleButton
|
||||
@@ -60,7 +63,7 @@ public:
|
||||
p.setRenderHint(QPainter::Antialiasing, true);
|
||||
QRect r = rect().adjusted(2, 2, -3, -3);
|
||||
p.translate(0.5f, 0.5f);
|
||||
QColor color = Interpolate(palette().color(QPalette::Window), palette().color(QPalette::Shadow), 0.2f);
|
||||
QColor color = DockTitleBarInterpolate::Interpolate(palette().color(QPalette::Window), palette().color(QPalette::Shadow), 0.2f);
|
||||
p.setBrush(QBrush(color));
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawRoundedRect(r, 4, 4, Qt::AbsoluteSize);
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace DrawingPrimitives
|
||||
|
||||
void DrawTicks(const std::vector<STick>& ticks, QPainter& painter, const QPalette& palette, const STickOptions& options)
|
||||
{
|
||||
QColor midDark = Interpolate(palette.color(QPalette::Dark), palette.color(QPalette::Button), 0.5f);
|
||||
QColor midDark = DrawingPrimitives::Interpolate(palette.color(QPalette::Dark), palette.color(QPalette::Button), 0.5f);
|
||||
painter.setPen(QPen(midDark));
|
||||
|
||||
const int height = options.m_rect.height();
|
||||
@@ -149,13 +149,13 @@ namespace DrawingPrimitives
|
||||
painter.fillRect(shadowRect, upperBrush);
|
||||
}
|
||||
|
||||
painter.fillRect(options.m_rect, Interpolate(palette.color(QPalette::Button), palette.color(QPalette::Midlight), 0.25f));
|
||||
painter.fillRect(options.m_rect, DrawingPrimitives::Interpolate(palette.color(QPalette::Button), palette.color(QPalette::Midlight), 0.25f));
|
||||
if (options.m_drawBackgroundCallback)
|
||||
{
|
||||
options.m_drawBackgroundCallback();
|
||||
}
|
||||
|
||||
QColor midDark = Interpolate(palette.color(QPalette::Dark), palette.color(QPalette::Button), 0.5f);
|
||||
QColor midDark = DrawingPrimitives::Interpolate(palette.color(QPalette::Dark), palette.color(QPalette::Button), 0.5f);
|
||||
painter.setPen(QPen(midDark));
|
||||
|
||||
QFont font;
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
<RCC>
|
||||
<qresource>
|
||||
<file>Icons/CurveEditor/auto.png</file>
|
||||
<file>Icons/CurveEditor/fit_horizontal.png</file>
|
||||
<file>Icons/CurveEditor/fit_vertical.png</file>
|
||||
<file>Icons/CurveEditor/linear_in.png</file>
|
||||
<file>Icons/CurveEditor/linear_out.png</file>
|
||||
<file>Icons/CurveEditor/step_in.png</file>
|
||||
<file>Icons/CurveEditor/step_out.png</file>
|
||||
<file>Icons/CurveEditor/zero_in.png</file>
|
||||
<file>Icons/CurveEditor/zero_out.png</file>
|
||||
<file>Icons/CurveEditor/break.png</file>
|
||||
<file>Icons/CurveEditor/unify.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "EventManager.h"
|
||||
#include "Serialization/JSONIArchive.h"
|
||||
#include "Serialization/JSONOArchive.h"
|
||||
|
||||
CEventManager* CEventManager::ms_pEventManager;
|
||||
|
||||
CEventManager::CEventManager()
|
||||
: m_nextAddress(0)
|
||||
, m_nextHandlerId(0)
|
||||
{
|
||||
if (ms_pEventManager)
|
||||
{
|
||||
CryFatalError("There should be only one event manager instance");
|
||||
}
|
||||
|
||||
ms_pEventManager = this;
|
||||
}
|
||||
|
||||
void CEventManager::Init([[maybe_unused]] SSystemGlobalEnvironment* env)
|
||||
{
|
||||
}
|
||||
|
||||
CEventManager* CEventManager::GetInstance()
|
||||
{
|
||||
return ms_pEventManager;
|
||||
}
|
||||
|
||||
uint CEventManager::GetAddressId(const char* name)
|
||||
{
|
||||
auto findIter = m_nameToAddressMap.find(name);
|
||||
if (findIter != m_nameToAddressMap.end())
|
||||
{
|
||||
return findIter->second;
|
||||
}
|
||||
|
||||
uint newId = m_nextAddress++;
|
||||
m_nameToAddressMap[name] = newId;
|
||||
return newId;
|
||||
}
|
||||
|
||||
uint CEventManager::GetUniqueAddressId()
|
||||
{
|
||||
return m_nextAddress++;
|
||||
}
|
||||
|
||||
void CEventManager::SendEventRaw(const uint address, const char* eventName, const char* message) const
|
||||
{
|
||||
SendEventImplementation(address, eventName, message, DynArray<uint>());
|
||||
}
|
||||
|
||||
void CEventManager::SendEventRaw(const uint address, const char* eventName, const char* message, const DynArray<uint>& excludedHandlers) const
|
||||
{
|
||||
SendEventImplementation(address, eventName, message, excludedHandlers);
|
||||
}
|
||||
|
||||
void CEventManager::SendEventImplementation(const uint address, const string& eventName, const string& message, const DynArray<uint>& excludedHandlers) const
|
||||
{
|
||||
auto handlerFindIter = m_messageRoutingMap.find(std::make_pair(address, eventName));
|
||||
if (handlerFindIter != m_messageRoutingMap.end())
|
||||
{
|
||||
const std::vector<std::pair<uint, TEventHandlerFunc> >& handlers = handlerFindIter->second;
|
||||
|
||||
for (uint i = 0; i < handlers.size(); ++i)
|
||||
{
|
||||
if (!stl::find(excludedHandlers, handlers[i].first))
|
||||
{
|
||||
handlers[i].second(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CEventManager::CanDeliverRaw(const uint address, const char* eventName) const
|
||||
{
|
||||
auto handlerFindIter = m_messageRoutingMap.find(std::make_pair(address, eventName));
|
||||
if (handlerFindIter != m_messageRoutingMap.end())
|
||||
{
|
||||
const std::vector<std::pair<uint, TEventHandlerFunc> >& handlers = handlerFindIter->second;
|
||||
return !handlers.empty();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CEventConnection CEventManager::AddEventCallbackRaw(const uint address, const char* eventName, TEventHandlerFunc callback)
|
||||
{
|
||||
const uint handlerId = m_nextHandlerId++;
|
||||
m_messageRoutingMap[std::make_pair(address, eventName)].push_back(std::make_pair(handlerId, callback));
|
||||
return CEventConnection(address, eventName, handlerId);
|
||||
}
|
||||
|
||||
string CEventManager::SerializeMessageToJSON(const Serialization::SStruct& ref) const
|
||||
{
|
||||
Serialization::JSONOArchive oArchive;
|
||||
oArchive(ref);
|
||||
return oArchive.buffer();
|
||||
}
|
||||
|
||||
void CEventManager::DeserializeFromJSON(const Serialization::SStruct& ref, const string& json)
|
||||
{
|
||||
Serialization::JSONIArchive iArchive;
|
||||
if (iArchive.open(json.data(), json.size()))
|
||||
{
|
||||
iArchive(ref);
|
||||
}
|
||||
}
|
||||
|
||||
void CEventConnection::Disconnect()
|
||||
{
|
||||
if (m_bConnected)
|
||||
{
|
||||
auto& messageMap = CEventManager::GetInstance()->m_messageRoutingMap;
|
||||
auto findIter = messageMap.find(std::make_pair(m_address, m_eventName));
|
||||
|
||||
if (findIter != messageMap.end())
|
||||
{
|
||||
stl::find_and_erase_if(findIter->second, [=](const std::pair<uint, CEventManager::TEventHandlerFunc>& h)
|
||||
{
|
||||
return h.first == m_handlerId;
|
||||
});
|
||||
}
|
||||
|
||||
if (findIter->second.empty())
|
||||
{
|
||||
messageMap.erase(findIter);
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_EVENTS_EVENTMANAGER_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_EVENTS_EVENTMANAGER_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "EditorCommonAPI.h"
|
||||
#include "IEditor.h"
|
||||
|
||||
#include "Serialization/IArchive.h"
|
||||
|
||||
struct SSystemGlobalEnvironment;
|
||||
|
||||
class CEventConnection
|
||||
{
|
||||
friend class CEventManager;
|
||||
friend class CScopedEventConnection;
|
||||
|
||||
public:
|
||||
CEventConnection()
|
||||
: m_bConnected(false) {}
|
||||
|
||||
EDITOR_COMMON_API void Disconnect();
|
||||
|
||||
uint GetHandlerId() const { return m_handlerId; }
|
||||
|
||||
private:
|
||||
CEventConnection(const uint address, const string& eventName, const uint handlerId)
|
||||
: m_address(address)
|
||||
, m_eventName(eventName)
|
||||
, m_handlerId(handlerId)
|
||||
, m_bConnected(true) {}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_bConnected = false;
|
||||
m_address = 0;
|
||||
m_handlerId = 0;
|
||||
m_eventName.clear();
|
||||
}
|
||||
|
||||
void Move(CEventConnection& other)
|
||||
{
|
||||
m_bConnected = other.m_bConnected;
|
||||
m_address = other.m_address;
|
||||
m_handlerId = other.m_handlerId;
|
||||
m_eventName.swap(other.m_eventName);
|
||||
other.Reset();
|
||||
}
|
||||
|
||||
bool m_bConnected;
|
||||
uint m_address;
|
||||
uint m_handlerId;
|
||||
string m_eventName;
|
||||
};
|
||||
|
||||
class CScopedEventConnection
|
||||
: public CEventConnection
|
||||
{
|
||||
public:
|
||||
CScopedEventConnection()
|
||||
: CEventConnection() {}
|
||||
|
||||
CScopedEventConnection(CScopedEventConnection&& connection)
|
||||
{
|
||||
Move(connection);
|
||||
}
|
||||
|
||||
CScopedEventConnection(CEventConnection&& connection)
|
||||
{
|
||||
Move(connection);
|
||||
}
|
||||
|
||||
CScopedEventConnection& operator =(CEventConnection&& connection)
|
||||
{
|
||||
if (&connection != this)
|
||||
{
|
||||
Disconnect();
|
||||
Move(connection);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~CScopedEventConnection() { Disconnect(); }
|
||||
|
||||
private:
|
||||
CScopedEventConnection(const CScopedEventConnection&); // no implementation
|
||||
CScopedEventConnection& operator =(const CScopedEventConnection&); // no implementation
|
||||
};
|
||||
|
||||
class EDITOR_COMMON_API CEventManager
|
||||
{
|
||||
friend class CEventConnection;
|
||||
|
||||
public:
|
||||
CEventManager();
|
||||
|
||||
static CEventManager* GetInstance();
|
||||
|
||||
void Init(SSystemGlobalEnvironment* pEnv);
|
||||
|
||||
// Registers an address and returns its ID. Multiple event handlers can listen to the same address, allowing broadcasts.
|
||||
uint GetAddressId(const char* name);
|
||||
|
||||
// Registers a new unique address
|
||||
uint GetUniqueAddressId();
|
||||
|
||||
public:
|
||||
|
||||
// Sends an event to an address
|
||||
//
|
||||
// TMessageType must be a serializable struct
|
||||
//
|
||||
template <class TMessageType>
|
||||
void SendEvent(const uint address, const TMessageType& message)
|
||||
{
|
||||
const string json = SerializeMessageToJSON(Serialization::SStruct(message));
|
||||
SendEventRaw(address, TMessageType::GetName(), json);
|
||||
}
|
||||
|
||||
template <class TMessageType>
|
||||
void SendEvent(const uint address, const TMessageType& message, const DynArray<uint>& excludedHandlers) const
|
||||
{
|
||||
const string json = SerializeMessageToJSON(Serialization::SStruct(message));
|
||||
SendEventRaw(address, TMessageType::GetName(), json, excludedHandlers);
|
||||
}
|
||||
|
||||
// For sending a raw JSON message.
|
||||
void SendEventRaw(const uint address, const char* eventName, const char* message) const;
|
||||
void SendEventRaw(const uint address, const char* eventName, const char* message, const DynArray<uint>& excludedHandlers) const;
|
||||
|
||||
// Tests if a call to SendEvent would actually send a message (there is someone listening to this message)
|
||||
bool CanDeliverRaw(const uint address, const char* eventName) const;
|
||||
template<class TMessageType>
|
||||
bool CanDeliver(const uint address) const
|
||||
{
|
||||
const char* pEventName = TMessageType::GetName();
|
||||
return CanDeliverRaw(address, pEventName);
|
||||
}
|
||||
|
||||
// This should be the most common way to add an event callback
|
||||
//
|
||||
// This example will install an event handler for OnEvent(const SMessageType &message) that is sent to a specific address:
|
||||
// CEventManager::GetInstance()->AddEventCallback(componentId, this, &CEventHandler::OnEvent);
|
||||
//
|
||||
// TMessageType must be a serializable struct
|
||||
//
|
||||
// Returns a CEventConnection. The callback is removed when this object is destroyed.
|
||||
//
|
||||
template <class TClassType, class TMessageType>
|
||||
CEventConnection AddEventCallback(const uint address, TClassType* pThis, void (TClassType::* pMethod)(const TMessageType&))
|
||||
{
|
||||
return AddEventCallback<TMessageType>(address, std::bind(pMethod, pThis, std::placeholders::_1));
|
||||
}
|
||||
|
||||
// Same as above, but you can pass in any function object that takes TMessageType& as an argument directly.
|
||||
//
|
||||
template <class TMessageType>
|
||||
CEventConnection AddEventCallback(const uint address, std::function<void (const TMessageType&)> callback)
|
||||
{
|
||||
return AddEventCallbackRaw(address, TMessageType::GetName(), [=](const string& json)
|
||||
{
|
||||
TMessageType message;
|
||||
DeserializeFromJSON(Serialization::SStruct(message), json);
|
||||
callback(message);
|
||||
});
|
||||
}
|
||||
|
||||
// This can be used if raw parsing of JSON is preferred.
|
||||
typedef std::function<void (const char*)> TEventHandlerFunc;
|
||||
CEventConnection AddEventCallbackRaw(const uint componentId, const char* eventName, TEventHandlerFunc callback);
|
||||
|
||||
private:
|
||||
void SendEventImplementation(const uint address, const string& eventName, const string& message, const DynArray<uint>& excludedHandlers) const;
|
||||
|
||||
string SerializeMessageToJSON(const Serialization::SStruct& ref) const;
|
||||
void DeserializeFromJSON(const Serialization::SStruct& ref, const string& json);
|
||||
|
||||
uint m_nextAddress;
|
||||
uint m_nextHandlerId;
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
std::map<string, uint, stl::less_stricmp<string> > m_nameToAddressMap;
|
||||
std::map<std::pair<uint, string>, std::vector<std::pair<uint, TEventHandlerFunc> > > m_messageRoutingMap;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
static CEventManager* ms_pEventManager;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_EVENTS_EVENTMANAGER_H
|
||||
@@ -1,224 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "Serialization/ClassFactory.h"
|
||||
#include "Serialization/Pointers.h"
|
||||
#include "Serialization/IArchive.h"
|
||||
#include "ListSelectionDialog.h"
|
||||
#include <IEditor.h>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QBoxLayout>
|
||||
#include <QTreeView>
|
||||
#include <QStandardItemModel>
|
||||
#include <QHeaderView>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QIcon>
|
||||
#include <QMenu>
|
||||
#include <QEvent>
|
||||
#include <QKeyEvent>
|
||||
#include <QCoreApplication>
|
||||
#include <QByteArray>
|
||||
#include "IResourceSelectorHost.h"
|
||||
|
||||
#include "DeepFilterProxyModel.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
ListSelectionDialog::ListSelectionDialog(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, m_currentColumn(0)
|
||||
{
|
||||
setWindowTitle("Choose...");
|
||||
setWindowModality(Qt::ApplicationModal);
|
||||
|
||||
QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
setLayout(layout);
|
||||
|
||||
QBoxLayout* filterBox = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
layout->addLayout(filterBox);
|
||||
{
|
||||
filterBox->addWidget(new QLabel("Filter:", this), 0);
|
||||
filterBox->addWidget(m_filterEdit = new QLineEdit(this), 1);
|
||||
connect(m_filterEdit, SIGNAL(textChanged(const QString&)), this, SLOT(onFilterChanged(const QString&)));
|
||||
m_filterEdit->installEventFilter(this);
|
||||
}
|
||||
|
||||
QBoxLayout* infoBox = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
layout->addLayout(infoBox);
|
||||
|
||||
m_model = new QStandardItemModel();
|
||||
m_model->setColumnCount(1);
|
||||
m_model->setHeaderData(0, Qt::Horizontal, "Name", Qt::DisplayRole);
|
||||
|
||||
m_filterModel = new DeepFilterProxyModel(this);
|
||||
m_filterModel->setSourceModel(m_model);
|
||||
m_filterModel->setDynamicSortFilter(true);
|
||||
|
||||
m_tree = new QTreeView(this);
|
||||
//m_tree->setColumnCount(3);
|
||||
m_tree->setModel(m_filterModel);
|
||||
|
||||
m_tree->header()->setStretchLastSection(false);
|
||||
#if QT_VERSION >= 0x50000
|
||||
m_tree->header()->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
#else
|
||||
m_tree->header()->setResizeMode(0, QHeaderView::Stretch);
|
||||
#endif
|
||||
//m_tree->header()->resizeSection(0, 80);
|
||||
connect(m_tree, SIGNAL(activated(const QModelIndex&)), this, SLOT(onActivated(const QModelIndex&)));
|
||||
|
||||
layout->addWidget(m_tree, 1);
|
||||
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(this);
|
||||
buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
layout->addWidget(buttons, 0);
|
||||
}
|
||||
|
||||
bool ListSelectionDialog::eventFilter(QObject* obj, QEvent* event)
|
||||
{
|
||||
if (obj == m_filterEdit && event->type() == QEvent::KeyPress)
|
||||
{
|
||||
QKeyEvent* keyEvent = (QKeyEvent*)event;
|
||||
if (keyEvent->key() == Qt::Key_Down ||
|
||||
keyEvent->key() == Qt::Key_Up ||
|
||||
keyEvent->key() == Qt::Key_PageDown ||
|
||||
keyEvent->key() == Qt::Key_PageUp)
|
||||
{
|
||||
QCoreApplication::sendEvent(m_tree, event);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QDialog::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void ListSelectionDialog::onFilterChanged(const QString& str)
|
||||
{
|
||||
m_filterModel->setFilterString(str);
|
||||
m_filterModel->invalidate();
|
||||
m_tree->expandAll();
|
||||
|
||||
QModelIndex currentSource = m_filterModel->mapToSource(m_tree->selectionModel()->currentIndex());
|
||||
if (!currentSource.isValid() || !m_filterModel->matchFilter(currentSource.row(), currentSource.parent()))
|
||||
{
|
||||
QModelIndex firstMatchingIndex = m_filterModel->findFirstMatchingIndex(QModelIndex());
|
||||
if (firstMatchingIndex.isValid())
|
||||
{
|
||||
m_tree->selectionModel()->setCurrentIndex(firstMatchingIndex, QItemSelectionModel::SelectCurrent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ListSelectionDialog::onActivated(const QModelIndex& index)
|
||||
{
|
||||
m_tree->setCurrentIndex(index);
|
||||
accept();
|
||||
}
|
||||
|
||||
QSize ListSelectionDialog::sizeHint() const
|
||||
{
|
||||
return QSize(600, 900);
|
||||
}
|
||||
|
||||
void ListSelectionDialog::SetColumnText(int column, const char* text)
|
||||
{
|
||||
if (column >= m_model->columnCount())
|
||||
{
|
||||
int oldColumnCount = m_model->columnCount();
|
||||
m_model->setColumnCount(column + 1);
|
||||
for (int i = oldColumnCount; i <= column; ++i)
|
||||
{
|
||||
#if QT_VERSION >= 0x50000
|
||||
m_tree->header()->setSectionResizeMode(i, QHeaderView::Interactive);
|
||||
#else
|
||||
m_tree->header()->setResizeMode(i, QHeaderView::Interactive);
|
||||
#endif
|
||||
m_tree->header()->resizeSection(i, 40);
|
||||
}
|
||||
}
|
||||
m_model->setHeaderData(column, Qt::Horizontal, text, Qt::DisplayRole);
|
||||
}
|
||||
|
||||
void ListSelectionDialog::SetColumnWidth(int column, int width)
|
||||
{
|
||||
if (column >= m_model->columnCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_tree->header()->resizeSection(column, width);
|
||||
}
|
||||
|
||||
|
||||
void ListSelectionDialog::AddRow(const char* name)
|
||||
{
|
||||
AddRow(name, QIcon());
|
||||
}
|
||||
|
||||
void ListSelectionDialog::AddRow(const char* name, const QIcon& icon)
|
||||
{
|
||||
QStandardItem* item = new QStandardItem(name);
|
||||
item->setEditable(false);
|
||||
item->setData(name);
|
||||
item->setIcon(icon);
|
||||
|
||||
QList<QStandardItem*> items;
|
||||
items.append(item);
|
||||
|
||||
m_model->appendRow(items);
|
||||
m_currentColumn = 1;
|
||||
m_firstColumnToItem[name] = item;
|
||||
}
|
||||
|
||||
void ListSelectionDialog::AddRowColumn(const char* text)
|
||||
{
|
||||
int itemCount = m_model->rowCount(QModelIndex());
|
||||
if (itemCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QStandardItem* item = new QStandardItem();
|
||||
item->setText(QString::fromLocal8Bit(text));
|
||||
if (QStandardItem* lastItem = m_model->item(itemCount - 1, 0))
|
||||
{
|
||||
item->setData(lastItem->data());
|
||||
}
|
||||
item->setEditable(false);
|
||||
m_model->setItem(itemCount - 1, m_currentColumn, item);
|
||||
++m_currentColumn;
|
||||
}
|
||||
|
||||
QString ListSelectionDialog::ChooseItem(const QString& currentValue)
|
||||
{
|
||||
m_tree->expandAll();
|
||||
|
||||
if (exec() == QDialog::Accepted && m_tree->selectionModel()->currentIndex().isValid())
|
||||
{
|
||||
QModelIndex currentIndex = m_tree->selectionModel()->currentIndex();
|
||||
QModelIndex sourceCurrentIndex = m_filterModel->mapToSource(currentIndex);
|
||||
QStandardItem* item = m_model->itemFromIndex(sourceCurrentIndex);
|
||||
if (item)
|
||||
{
|
||||
m_chosenItem = item->data().toString().toUtf8();
|
||||
return m_chosenItem.constData();
|
||||
}
|
||||
}
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#include <moc_ListSelectionDialog.cpp>
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_LISTSELECTIONDIALOG_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_LISTSELECTIONDIALOG_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "EditorCommonAPI.h"
|
||||
#include <QDialog>
|
||||
#include <QMap>
|
||||
#endif
|
||||
|
||||
class DeepFilterProxyModel;
|
||||
class QLineEdit;
|
||||
class QModelIndex;
|
||||
class QStandardItemModel;
|
||||
class QStandardItem;
|
||||
class QString;
|
||||
class QTreeView;
|
||||
class QWidget;
|
||||
class QByteArray;
|
||||
|
||||
class EDITOR_COMMON_API ListSelectionDialog
|
||||
: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ListSelectionDialog(QWidget* parent);
|
||||
void SetColumnText(int column, const char* text);
|
||||
void SetColumnWidth(int column, int width);
|
||||
|
||||
void AddRow(const char* firstColumnValue);
|
||||
void AddRow(const char* firstColumnValue, const QIcon& icon);
|
||||
void AddRowColumn(const char* value);
|
||||
|
||||
QString ChooseItem(const QString& currentValue);
|
||||
|
||||
QSize sizeHint() const override;
|
||||
|
||||
protected slots:
|
||||
void onActivated(const QModelIndex& index);
|
||||
void onFilterChanged(const QString&);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject* obj, QEvent* event);
|
||||
|
||||
private:
|
||||
QTreeView* m_tree;
|
||||
QStandardItemModel* m_model;
|
||||
DeepFilterProxyModel* m_filterModel;
|
||||
typedef QMap<QString, QStandardItem*> StringToItem;
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
StringToItem m_firstColumnToItem;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
QLineEdit* m_filterEdit;
|
||||
QByteArray m_chosenItem;
|
||||
int m_currentColumn;
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_LISTSELECTIONDIALOG_H
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates
|
||||
|
||||
#include <QPropertyTree/Unicode.h>
|
||||
|
||||
#include <vector>
|
||||
#include <QtCore/QString>
|
||||
|
||||
string fromWideChar(const wchar_t* wstr)
|
||||
{
|
||||
return QString::fromWCharArray(wstr).toUtf8().data();
|
||||
}
|
||||
|
||||
wstring toWideChar(const char* str)
|
||||
{
|
||||
QString s = QString::fromUtf8(str);
|
||||
|
||||
std::vector<wchar_t> result(s.size()+1);
|
||||
s.toWCharArray(&result[0]);
|
||||
return &result[0];
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
set(FILES
|
||||
../Common/UnixLike/QPropertyTree/Unicode_UnixLike.cpp
|
||||
)
|
||||
@@ -1,14 +0,0 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
set(FILES
|
||||
../Common/UnixLike/QPropertyTree/Unicode_UnixLike.cpp
|
||||
)
|
||||
@@ -1,41 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates
|
||||
|
||||
#include <QPropertyTree/Unicode.h>
|
||||
|
||||
#include <AzCore/PlatformIncl.h>
|
||||
|
||||
string fromWideChar(const wchar_t* wstr)
|
||||
{
|
||||
// We have different implementation for windows as Qt for windows
|
||||
// is built with wchar_t of diferent size (4 bytes, as on linux).
|
||||
// Therefore we avoid calling any wchar_t functions in Qt.
|
||||
const unsigned int codepage = CP_UTF8;
|
||||
int len = WideCharToMultiByte(codepage, 0, wstr, -1, NULL, 0, 0, 0);
|
||||
char* buf = (char*)alloca(len);
|
||||
if (len > 1) {
|
||||
WideCharToMultiByte(codepage, 0, wstr, -1, buf, len, 0, 0);
|
||||
return string(buf, len - 1);
|
||||
}
|
||||
return string();
|
||||
}
|
||||
|
||||
wstring toWideChar(const char* str)
|
||||
{
|
||||
const unsigned int codepage = CP_UTF8;
|
||||
int len = MultiByteToWideChar(codepage, 0, str, -1, NULL, 0);
|
||||
wchar_t* buf = (wchar_t*)alloca(len * sizeof(wchar_t));
|
||||
if (len > 1) {
|
||||
MultiByteToWideChar(codepage, 0, str, -1, buf, len);
|
||||
return wstring(buf, len - 1);
|
||||
}
|
||||
return wstring();
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
set(FILES
|
||||
QPropertyTree/Unicode_Windows.cpp
|
||||
)
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#include <QAbstractQVariantTreeDataModel.h>
|
||||
|
||||
|
||||
QAbstractQVariantTreeDataModel::Item* QAbstractQVariantTreeDataModel::itemFromIndex(const QModelIndex& index) const
|
||||
{
|
||||
if (index.isValid())
|
||||
{
|
||||
return (Item*)index.internalPointer();
|
||||
}
|
||||
return m_root.get();
|
||||
}
|
||||
|
||||
QModelIndex QAbstractQVariantTreeDataModel::indexFromItem(QAbstractQVariantTreeDataModel::Item* item, int col /*= 0*/) const
|
||||
{
|
||||
if (0 == item)
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
if (!item->m_parent || !item->m_parent->asFolder())
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
int row = item->m_parent->asFolder()->row(item);
|
||||
return createIndex(row, col, item);
|
||||
}
|
||||
|
||||
QModelIndex QAbstractQVariantTreeDataModel::index(int row, int column, const QModelIndex& parent /*= QModelIndex()*/) const
|
||||
{
|
||||
Item* parentItem = itemFromIndex(parent);
|
||||
if (parentItem && parentItem->asFolder() && row < parentItem->asFolder()->m_children.size())
|
||||
{
|
||||
Item* item = parentItem->asFolder()->m_children[row].get();
|
||||
return createIndex(row, column, item);
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex QAbstractQVariantTreeDataModel::parent(const QModelIndex& child) const
|
||||
{
|
||||
Item* item = itemFromIndex(child);
|
||||
return item && item->m_parent && item->m_parent->asFolder() ? indexFromItem(item->m_parent) : QModelIndex();
|
||||
}
|
||||
|
||||
bool QAbstractQVariantTreeDataModel::hasChildren(const QModelIndex& parent /* = QModelIndex() */) const
|
||||
{
|
||||
Item* item = itemFromIndex(parent);
|
||||
return item && item->asFolder() && item->asFolder()->m_children.size();
|
||||
}
|
||||
|
||||
int QAbstractQVariantTreeDataModel::rowCount(const QModelIndex& parent /*= QModelIndex()*/) const
|
||||
{
|
||||
Item* item = itemFromIndex(parent);
|
||||
int res = 0;
|
||||
if (item && item->asFolder())
|
||||
{
|
||||
res = (int) item->asFolder()->m_children.size();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int QAbstractQVariantTreeDataModel::columnCount([[maybe_unused]] const QModelIndex& parent /*= QModelIndex()*/) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#ifndef QABSTRACTQVARIANTTREEDATAMODEL_H
|
||||
#define QABSTRACTQVARIANTTREEDATAMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "EditorCommonAPI.h"
|
||||
|
||||
|
||||
class EDITOR_COMMON_API QAbstractQVariantTreeDataModel
|
||||
: public QAbstractItemModel
|
||||
{
|
||||
public:
|
||||
QAbstractQVariantTreeDataModel(QObject* parent)
|
||||
: QAbstractItemModel(parent) { }
|
||||
|
||||
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex& child) const override;
|
||||
bool hasChildren(const QModelIndex& parent = QModelIndex()) const override;
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
|
||||
protected:
|
||||
struct Folder;
|
||||
|
||||
struct Item
|
||||
{
|
||||
Item()
|
||||
: m_parent(0) { }
|
||||
|
||||
QMap<int, QVariant> m_data;
|
||||
Folder* m_parent;
|
||||
|
||||
virtual ~Item() = default;
|
||||
virtual const Folder* asFolder() const { return 0; } // need this as we don't have RTTI
|
||||
};
|
||||
|
||||
struct Folder
|
||||
: public Item
|
||||
{
|
||||
Folder(const QString& name)
|
||||
{
|
||||
m_data.insert(Qt::DisplayRole, name);
|
||||
}
|
||||
std::vector < std::shared_ptr<Item> > m_children;
|
||||
const Folder* asFolder() const override { return this; } // need this as we don't have RTTI
|
||||
|
||||
int row(Item* item) const
|
||||
{
|
||||
for (int i = 0; i < m_children.size(); ++i)
|
||||
{
|
||||
if (m_children[i].get() == item)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
void addChild(std::shared_ptr<Item> item)
|
||||
{
|
||||
item->m_parent = this;
|
||||
m_children.push_back(item);
|
||||
}
|
||||
};
|
||||
|
||||
Item* itemFromIndex(const QModelIndex& index) const;
|
||||
QModelIndex indexFromItem(Item* item, int col = 0) const;
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
std::shared_ptr<Folder> m_root;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
};
|
||||
|
||||
#endif // QABSTRACTQVARIANTTREEDATAMODEL_H
|
||||
@@ -1,309 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "QParentWndWidget.h"
|
||||
#include <QEvent>
|
||||
#include <QGuiApplication>
|
||||
#include <QApplication>
|
||||
#include <QFocusEvent>
|
||||
|
||||
#include "QParentWndWidget.h"
|
||||
|
||||
#include <qt_windows.h>
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
#include <QWindow>
|
||||
#endif
|
||||
static HWND FindTopmostWindow(HWND child, bool considerWsChild)
|
||||
{
|
||||
if (child == GetDesktopWindow())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
HWND current = child;
|
||||
while (GetParent(current) != 0)
|
||||
{
|
||||
if (considerWsChild && (GetWindowLongW(current, GWL_STYLE) & WS_CHILD) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
current = GetParent(current);
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
QParentWndWidget::QParentWndWidget(HWND parent)
|
||||
: m_parent(parent)
|
||||
, m_previousFocus(0)
|
||||
, m_modalityRoot(0)
|
||||
, m_parentToCenterOn(0)
|
||||
{
|
||||
if (m_parent)
|
||||
{
|
||||
SetWindowLongA((HWND)winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_TABSTOP);
|
||||
|
||||
#if QT_VERSION >= 0x50000
|
||||
QWindow* window = windowHandle();
|
||||
window->setProperty("_q_embedded_native_parent_handle", (WId)m_parent);
|
||||
SetParent((HWND)winId(), m_parent);
|
||||
window->setFlags(Qt::FramelessWindowHint);
|
||||
#else
|
||||
SetParent((HWND)winId(), m_parent);
|
||||
#endif
|
||||
QEvent e(QEvent::EmbeddingControl);
|
||||
QApplication::sendEvent(this, &e);
|
||||
}
|
||||
|
||||
m_parentToCenterOn = FindTopmostWindow(m_parent, true);
|
||||
m_modalityRoot = FindTopmostWindow(m_parent, false);
|
||||
}
|
||||
|
||||
void QParentWndWidget::childEvent(QChildEvent* ev)
|
||||
{
|
||||
QObject* child = ev->child();
|
||||
if (child->isWidgetType())
|
||||
{
|
||||
if (ev->added())
|
||||
{
|
||||
if (child->isWidgetType())
|
||||
{
|
||||
child->installEventFilter(this);
|
||||
}
|
||||
}
|
||||
else if (ev->removed() && m_parentWasDisabled)
|
||||
{
|
||||
m_parentWasDisabled = false;
|
||||
EnableWindow(m_modalityRoot, true);
|
||||
child->removeEventFilter(this);
|
||||
}
|
||||
}
|
||||
QWidget::childEvent(ev);
|
||||
}
|
||||
|
||||
void QParentWndWidget::show()
|
||||
{
|
||||
if (!m_previousFocus)
|
||||
{
|
||||
m_previousFocus = ::GetFocus();
|
||||
}
|
||||
if (!m_previousFocus)
|
||||
{
|
||||
m_previousFocus = parentWindow();
|
||||
}
|
||||
|
||||
QWidget::show();
|
||||
}
|
||||
void QParentWndWidget::hide()
|
||||
{
|
||||
QWidget::hide();
|
||||
}
|
||||
|
||||
void QParentWndWidget::center()
|
||||
{
|
||||
const QWidget* child = findChild<QWidget*>();
|
||||
|
||||
RECT rect;
|
||||
GetWindowRect(m_parentToCenterOn, &rect);
|
||||
setGeometry((rect.right - rect.left) / 2 + rect.left,
|
||||
(rect.bottom - rect.top) / 2 + rect.top, 0, 0);
|
||||
}
|
||||
|
||||
#if QT_VERSION >= 0x50000
|
||||
bool QParentWndWidget::nativeEvent(const QByteArray&, void* message, long* result)
|
||||
#else
|
||||
bool QParentWndWidget::winEvent(MSG* msg, long* result)
|
||||
#endif
|
||||
{
|
||||
#if QT_VERSION >= 0x50000
|
||||
MSG* msg = (MSG*)message;
|
||||
#endif
|
||||
if (msg->message == WM_SETFOCUS)
|
||||
{
|
||||
Qt::FocusReason reason;
|
||||
if (::GetKeyState(VK_LBUTTON) < 0 ||
|
||||
::GetKeyState(VK_RBUTTON) < 0)
|
||||
{
|
||||
reason = Qt::MouseFocusReason;
|
||||
}
|
||||
else if (::GetKeyState(VK_SHIFT) < 0)
|
||||
{
|
||||
reason = Qt::BacktabFocusReason;
|
||||
}
|
||||
else
|
||||
{
|
||||
reason = Qt::TabFocusReason;
|
||||
}
|
||||
QFocusEvent ev(QEvent::FocusIn, reason);
|
||||
QApplication::sendEvent(this, &ev);
|
||||
}
|
||||
if (msg->message == WM_GETDLGCODE)
|
||||
{
|
||||
*result = DLGC_WANTARROWS | DLGC_WANTTAB;
|
||||
return(true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QParentWndWidget::eventFilter(QObject* obj, QEvent* ev)
|
||||
{
|
||||
QWidget* widget = (QWidget*)obj;
|
||||
switch (ev->type())
|
||||
{
|
||||
case QEvent::WindowDeactivate:
|
||||
{
|
||||
if (widget->isModal() && isHidden())
|
||||
{
|
||||
BringWindowToTop(m_parent);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QEvent::Show:
|
||||
{
|
||||
if (widget->isWindow())
|
||||
{
|
||||
if (!m_previousFocus)
|
||||
{
|
||||
m_previousFocus = ::GetFocus();
|
||||
}
|
||||
if (!m_previousFocus)
|
||||
{
|
||||
m_previousFocus = parentWindow();
|
||||
}
|
||||
hide();
|
||||
if (widget->isModal() && !m_parentWasDisabled)
|
||||
{
|
||||
EnableWindow(m_modalityRoot, false);
|
||||
m_parentWasDisabled = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QEvent::Hide:
|
||||
{
|
||||
if (m_parentWasDisabled)
|
||||
{
|
||||
EnableWindow(m_modalityRoot, true);
|
||||
m_parentWasDisabled = false;
|
||||
}
|
||||
if (m_previousFocus)
|
||||
{
|
||||
::SetFocus(m_previousFocus);
|
||||
}
|
||||
else
|
||||
{
|
||||
::SetFocus(parentWindow());
|
||||
}
|
||||
if (widget->testAttribute(Qt::WA_DeleteOnClose) && widget->isWindow())
|
||||
{
|
||||
deleteLater();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QEvent::Close:
|
||||
{
|
||||
::SetActiveWindow(m_parent);
|
||||
if (widget->testAttribute(Qt::WA_DeleteOnClose))
|
||||
{
|
||||
deleteLater();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
;
|
||||
|
||||
return QWidget::eventFilter(obj, ev);
|
||||
}
|
||||
|
||||
void QParentWndWidget::focusInEvent(QFocusEvent* ev)
|
||||
{
|
||||
QWidget* candidate = this;
|
||||
|
||||
if (ev->reason() == Qt::TabFocusReason || ev->reason() == Qt::BacktabFocusReason)
|
||||
{
|
||||
while (candidate && (candidate->focusPolicy() & Qt::TabFocus) == 0)
|
||||
{
|
||||
candidate = candidate->nextInFocusChain();
|
||||
if (candidate == this)
|
||||
{
|
||||
candidate = 0;
|
||||
}
|
||||
}
|
||||
if (candidate)
|
||||
{
|
||||
candidate->setFocus(ev->reason());
|
||||
candidate->setAttribute(Qt::WA_KeyboardFocusChange);
|
||||
candidate->window()->setAttribute(Qt::WA_KeyboardFocusChange);
|
||||
if (ev->reason() == Qt::BacktabFocusReason)
|
||||
{
|
||||
QWidget::focusNextPrevChild(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool QParentWndWidget::focusNextPrevChild(bool next)
|
||||
{
|
||||
QWidget* current = focusWidget();
|
||||
if (next)
|
||||
{
|
||||
QWidget* nextFocus = current;
|
||||
while (true)
|
||||
{
|
||||
nextFocus = nextFocus->nextInFocusChain();
|
||||
if (nextFocus->isWindow())
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (nextFocus->focusPolicy() & Qt::TabFocus)
|
||||
{
|
||||
return QWidget::focusNextPrevChild(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!current->isWindow())
|
||||
{
|
||||
QWidget* nextFocus = current->nextInFocusChain();
|
||||
QWidget* prevFocus = 0;
|
||||
QWidget* topLevel = 0;
|
||||
while (nextFocus != current)
|
||||
{
|
||||
if ((nextFocus->focusPolicy() & Qt::TabFocus) != 0)
|
||||
{
|
||||
prevFocus = nextFocus;
|
||||
topLevel = 0;
|
||||
}
|
||||
else if (nextFocus->isWindow())
|
||||
{
|
||||
topLevel = nextFocus;
|
||||
}
|
||||
nextFocus = nextFocus->nextInFocusChain();
|
||||
}
|
||||
|
||||
if (!topLevel)
|
||||
{
|
||||
return QWidget::focusNextPrevChild(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::SetFocus(m_parent);
|
||||
return true;
|
||||
}
|
||||
|
||||
#include <moc_QParentWndWidget.cpp>
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#pragma once
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPARENTWNDWIDGET_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPARENTWNDWIDGET_H
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QWidget>
|
||||
|
||||
#include "EditorCommonAPI.h"
|
||||
#endif
|
||||
|
||||
// QParentWndWidget can be used to show Qt popup windows/dialogs on top on
|
||||
// Win32/MFC windows.
|
||||
//
|
||||
// Example of usage:
|
||||
// QParentWndWidget parent(parentHwnd);
|
||||
//
|
||||
// QDialog dialog(parent);
|
||||
// dialog.exec(...);
|
||||
class EDITOR_COMMON_API QParentWndWidget
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QParentWndWidget(HWND parent);
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
void center();
|
||||
|
||||
HWND parentWindow() const { return m_parent; }
|
||||
|
||||
protected:
|
||||
void childEvent(QChildEvent* e) override;
|
||||
void focusInEvent(QFocusEvent* ev) override;
|
||||
bool focusNextPrevChild(bool next) override;
|
||||
|
||||
bool eventFilter(QObject* o, QEvent* e) override;
|
||||
#if QT_VERSION >= 0x50000
|
||||
bool nativeEvent(const QByteArray&, void* message, long*);
|
||||
#else
|
||||
bool winEvent(MSG* msg, long*);
|
||||
#endif
|
||||
|
||||
private:
|
||||
HWND m_parent;
|
||||
HWND m_parentToCenterOn;
|
||||
HWND m_modalityRoot;
|
||||
|
||||
HWND m_previousFocus;
|
||||
|
||||
bool m_parentWasDisabled;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPARENTWNDWIDGET_H
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "EditorCommonAPI.h"
|
||||
#include "Controls/PropertyCtrl.h"
|
||||
#include <QtWinMigrate/qwinhost.h>
|
||||
|
||||
template<class T>
|
||||
class TemplatePropertyCtrl
|
||||
: public QWinHost
|
||||
{
|
||||
public:
|
||||
TemplatePropertyCtrl(QWidget* parent)
|
||||
: QWinHost(parent) { }
|
||||
|
||||
T m_props;
|
||||
protected:
|
||||
virtual HWND createWindow(HWND parent, HINSTANCE instance)
|
||||
{
|
||||
CWnd* parentWindow = CWnd::FromHandle(parent);
|
||||
m_props.Create(WS_CHILD | WS_VISIBLE, CRect(0, 0, 100, 100), parentWindow /*, IDC_GRAPH_PROPERTIES*/);
|
||||
m_props.ModifyStyleEx(0, WS_EX_CLIENTEDGE);
|
||||
m_props.SetParent(parentWindow);
|
||||
return m_props.m_hWnd;
|
||||
}
|
||||
};
|
||||
|
||||
class QPropertyCtrl
|
||||
: public TemplatePropertyCtrl <CPropertyCtrl>
|
||||
{
|
||||
public:
|
||||
QPropertyCtrl(QWidget* parent)
|
||||
: TemplatePropertyCtrl<CPropertyCtrl>(parent)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "Color.h"
|
||||
#include "Serialization/IArchive.h"
|
||||
#include <math.h>
|
||||
#include "MathUtils.h"
|
||||
|
||||
|
||||
// HSV
|
||||
// h=0..360, s=0..1, v=0..1
|
||||
inline void HSVtoRGB(float h,float s,float v,
|
||||
float& r,float& g,float& b)
|
||||
{
|
||||
const float min=1e-5f;
|
||||
int i;
|
||||
float f,m,n,k;
|
||||
|
||||
if(s<min){
|
||||
r=g=b=v;
|
||||
}
|
||||
else {
|
||||
if(h>=360.0f)
|
||||
h=0;
|
||||
else
|
||||
h=h/60.0f;
|
||||
|
||||
i=xround(floor(h));
|
||||
f=h-i;
|
||||
m=v*(1-s);
|
||||
n=v*(1-s*f);
|
||||
k=v*(1-s*(1-f));
|
||||
|
||||
switch(i){
|
||||
case 0:
|
||||
r=v; g=k; b=m;
|
||||
break;
|
||||
case 1:
|
||||
r=n; g=v; b=m;
|
||||
break;
|
||||
case 2:
|
||||
r=m; g=v; b=k;
|
||||
break;
|
||||
case 3:
|
||||
r=m; g=n; b=v;
|
||||
break;
|
||||
case 4:
|
||||
r=k; g=m; b=v;
|
||||
break;
|
||||
case 5:
|
||||
r=v; g=m; b=n;
|
||||
break;
|
||||
default:
|
||||
YASLI_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
YASLI_ASSERT(r>=0 && r<=1);
|
||||
YASLI_ASSERT(g>=0 && g<=1);
|
||||
YASLI_ASSERT(b>=0 && b<=1);
|
||||
}
|
||||
|
||||
void Color::setHSV(float h,float s,float v, unsigned char alpha)
|
||||
{
|
||||
float rf,gf,bf;
|
||||
HSVtoRGB(h,s,v, rf,gf,bf);
|
||||
r = xround(rf*255);
|
||||
g = xround(gf*255);
|
||||
b = xround(bf*255);
|
||||
a = alpha;
|
||||
}
|
||||
|
||||
|
||||
void Color::toHSV(float& h,float& s,float& v)
|
||||
{
|
||||
float rf = r/255.f;
|
||||
float gf = g/255.f;
|
||||
float bf = b/255.f;
|
||||
v = max(max(rf,gf),bf);
|
||||
float temp=min(min(rf,gf),bf);
|
||||
if(v==0)
|
||||
s=0;
|
||||
else
|
||||
s=(v-temp)/v;
|
||||
|
||||
if(s==0)
|
||||
h=0;
|
||||
else {
|
||||
float Cr=(v-rf)/(v-temp);
|
||||
float Cg=(v-gf)/(v-temp);
|
||||
float Cb=(v-bf)/(v-temp);
|
||||
|
||||
if(rf==v) {
|
||||
h=Cb-Cg;
|
||||
}
|
||||
else if(gf==v) {
|
||||
h=2+Cr-Cb;
|
||||
}
|
||||
else if(bf==v) {
|
||||
h=4+Cg-Cr;
|
||||
}
|
||||
|
||||
h=60*h;
|
||||
if(h<0)h+=360;
|
||||
}
|
||||
}
|
||||
|
||||
void Color::Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(r, "", "^R");
|
||||
ar(g, "", "^G");
|
||||
ar(b, "", "^B");
|
||||
ar(a, "", "^A");
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_COLOR_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_COLOR_H
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace Serialization {
|
||||
class IArchive;
|
||||
}
|
||||
|
||||
struct Color
|
||||
{
|
||||
unsigned char b, g, r, a;
|
||||
|
||||
Color() : r(255), g(255), b(255), a(255) { }
|
||||
Color(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a = 255) { r=_r; g=_g; b=_b; a=_a; }
|
||||
explicit Color(unsigned long _argb) { argb() = _argb; }
|
||||
void set(int rc,int gc,int bc,int ac = 255) { r=rc; g=gc; b=bc; a=ac; }
|
||||
|
||||
Color& setGDI(unsigned long color) {
|
||||
b = (unsigned char)(color >> 16);
|
||||
g = (unsigned char)(color >> 8);
|
||||
r = (unsigned char)(color);
|
||||
a = 255;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void setHSV(float h,float s,float v, unsigned char alpha = 255);
|
||||
void toHSV(float& h,float& s, float& v);
|
||||
|
||||
Color& operator*= (float f) { r=int(r*f); g=int(g*f); b=int(b*f); a=int(a*f); return *this; }
|
||||
Color& operator+= (Color &p) { r+=p.r; g+=p.g; b+=p.b; a+=p.a; return *this; }
|
||||
Color& operator-= (Color &p) { r-=p.r; g-=p.g; b-=p.b; a-=p.a; return *this; }
|
||||
Color operator+ (Color &p) { return Color(r+p.r,g+p.g,b+p.b,a+p.a); }
|
||||
Color operator- (Color &p) { return Color(r-p.r,g-p.g,b-p.b,a-p.a); }
|
||||
Color operator* (float f) const { return Color(int(r*f), int(g*f), int(b*f), int(a*f)); }
|
||||
Color operator* (int f) const { return Color(r*f,g*f,b*f,a*f); }
|
||||
Color operator/ (int f) const { if(f!=0) f=(1<<16)/f; else f=1<<16; return Color((r*f)>>16,(g*f)>>16,(b*f)>>16,(a*f)>>16); }
|
||||
|
||||
bool operator==(const Color& rhs) const { return argb() == rhs.argb(); }
|
||||
bool operator!=(const Color& rhs) const { return argb() != rhs.argb(); }
|
||||
|
||||
unsigned long argb() const { return *reinterpret_cast<const unsigned long*>(this); }
|
||||
unsigned long& argb() { return *reinterpret_cast<unsigned long*>(this); }
|
||||
unsigned long rgb() const { return r | g << 8 | b << 16; }
|
||||
unsigned long rgba() const { return r | g << 8 | b << 16 | a << 24; }
|
||||
unsigned char& operator[](int i) { return ((unsigned char*)this)[i];}
|
||||
Color interpolate(const Color &v, float f) const
|
||||
{
|
||||
return Color(int(r+int(v.r-r)*f),
|
||||
int(g+int(v.g-g)*f),
|
||||
int(b+int(v.b-b)*f),
|
||||
int(a+(v.a-a)*f));
|
||||
}
|
||||
void Serialize(Serialization::IArchive& ar);
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_COLOR_H
|
||||
@@ -1,58 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "ConstStringList.h"
|
||||
#include <algorithm>
|
||||
#include "Serialization/STL.h"
|
||||
#include "Serialization/IArchive.h"
|
||||
#include "Serialization/STLImpl.h"
|
||||
|
||||
ConstStringList globalConstStringList;
|
||||
|
||||
const char* ConstStringList::findOrAdd(const char* string)
|
||||
{
|
||||
// TODO: try sorted vector of const char*
|
||||
Strings::iterator it = std::find(strings_.begin(), strings_.end(), string);
|
||||
if (it == strings_.end()) {
|
||||
strings_.push_back(string);
|
||||
return strings_.back().c_str();
|
||||
}
|
||||
else {
|
||||
return it->c_str();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ConstStringWrapper::ConstStringWrapper(ConstStringList* list, const char*& string)
|
||||
: list_(list ? list : &globalConstStringList)
|
||||
, string_(string)
|
||||
{
|
||||
YASLI_ASSERT(string_);
|
||||
}
|
||||
|
||||
using Serialization::string;
|
||||
|
||||
bool Serialize(Serialization::IArchive& ar, ConstStringWrapper& val, const char* name, const char* label)
|
||||
{
|
||||
if (ar.IsOutput()) {
|
||||
YASLI_ASSERT(val.string_);
|
||||
string out = val.string_;
|
||||
return ar(out, name, label);
|
||||
}
|
||||
else {
|
||||
string in;
|
||||
bool result = ar(in, name, label);
|
||||
|
||||
val.string_ = val.list_->findOrAdd(in.c_str());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_CONSTSTRINGLIST_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_CONSTSTRINGLIST_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include "EditorCommonAPI.h"
|
||||
|
||||
class ConstStringWrapper;
|
||||
|
||||
namespace Serialization { class IArchive; }
|
||||
|
||||
bool Serialize(Serialization::IArchive& ar, ConstStringWrapper &wrapper, const char* name, const char* label);
|
||||
|
||||
class ConstStringList{
|
||||
public:
|
||||
const char* findOrAdd(const char* string);
|
||||
protected:
|
||||
typedef std::list<std::string> Strings;
|
||||
Strings strings_;
|
||||
};
|
||||
|
||||
class ConstStringWrapper {
|
||||
public:
|
||||
ConstStringWrapper(ConstStringList* list, const char*& string);
|
||||
protected:
|
||||
ConstStringList* list_;
|
||||
const char*& string_;
|
||||
friend bool ::Serialize(Serialization::IArchive& ar, ConstStringWrapper &wrapper, const char* name, const char* label);
|
||||
};
|
||||
|
||||
extern ConstStringList globalConstStringList;
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_CONSTSTRINGLIST_H
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_CONTEXTLIST_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_CONTEXTLIST_H
|
||||
#pragma once
|
||||
|
||||
#include <Serialization/IArchive.h>
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
class CContextList
|
||||
{
|
||||
public:
|
||||
template<class T>
|
||||
void Update(T* contextObject)
|
||||
{
|
||||
for (size_t i = 0; i < links_.size(); ++i)
|
||||
{
|
||||
if (links_[i]->type == TypeID::get<T>())
|
||||
{
|
||||
links_[i]->contextObject = (void*)contextObject;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SContextLink* newLink = new SContextLink;
|
||||
newLink->type = TypeID::get<T>();
|
||||
newLink->outer = links_.empty() ? connectedList_ : links_.back();
|
||||
newLink->contextObject = (void*)contextObject;
|
||||
tail_.outer = newLink;
|
||||
links_.push_back(newLink);
|
||||
}
|
||||
|
||||
CContextList()
|
||||
{
|
||||
tail_.outer = 0;
|
||||
tail_.contextObject = 0;
|
||||
connectedList_ = 0;
|
||||
}
|
||||
|
||||
explicit CContextList(SContextLink* connectedList)
|
||||
{
|
||||
tail_.outer = 0;
|
||||
tail_.contextObject = 0;
|
||||
connectedList_ = connectedList;
|
||||
}
|
||||
|
||||
~CContextList()
|
||||
{
|
||||
for (size_t i = 0; i < links_.size(); ++i)
|
||||
{
|
||||
delete links_[i];
|
||||
}
|
||||
links_.clear();
|
||||
}
|
||||
|
||||
SContextLink* Tail() { return &tail_; }
|
||||
private:
|
||||
SContextLink tail_;
|
||||
std::vector<SContextLink*> links_;
|
||||
SContextLink* connectedList_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_CONTEXTLIST_H
|
||||
@@ -1,156 +0,0 @@
|
||||
/**
|
||||
* yasli - Serialization Library.
|
||||
* Copyright (C) 2007-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_FACTORY_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_FACTORY_H
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/containers/map.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
#include "Serialization/Assert.h"
|
||||
|
||||
template<class _Key, class _Product, class _KeyPred = std::less<_Key>>
|
||||
class Factory {
|
||||
public:
|
||||
typedef AZStd::map<_Key, AZStd::function<_Product *()>, _KeyPred, AZ::StdLegacyAllocator> Creators;
|
||||
typedef _Product* (*ProductConstructionFunction)(void);
|
||||
|
||||
Factory() {}
|
||||
|
||||
struct Creator
|
||||
{
|
||||
Creator()
|
||||
{
|
||||
if (s_creatorsHead)
|
||||
{
|
||||
m_next = s_creatorsHead;
|
||||
}
|
||||
s_creatorsHead = this;
|
||||
}
|
||||
|
||||
Creator(Factory& factory, _Key key, ProductConstructionFunction construction_function_)
|
||||
: Creator()
|
||||
{
|
||||
// capture key and construction_function_ by value so the lazy load won't try to access possibly deleted data
|
||||
Register = [&, key, construction_function_]()
|
||||
{
|
||||
factory.add(key, construction_function_);
|
||||
};
|
||||
}
|
||||
|
||||
Creator(_Key key, ProductConstructionFunction construction_function_)
|
||||
: Creator()
|
||||
{
|
||||
// capture key and construction_function_ by value so the lazy load won't try to access possibly deleted data
|
||||
Register = [&, key, construction_function_]()
|
||||
{
|
||||
Factory::the().add(key, construction_function_);
|
||||
};
|
||||
}
|
||||
|
||||
AZStd::function<void()> Register;
|
||||
Creator* m_next = nullptr;
|
||||
};
|
||||
|
||||
void add(const _Key& key, AZStd::function<_Product *()> creator) {
|
||||
YASLI_ASSERT(creators_.find(key) == creators_.end());
|
||||
YASLI_ASSERT(creator);
|
||||
creators_[key] = creator;
|
||||
}
|
||||
|
||||
void remove(const _Key& key) {
|
||||
auto& entry = creators_.find(key);
|
||||
if (entry != creators_.end()) {
|
||||
creators_.erase(entry);
|
||||
}
|
||||
}
|
||||
|
||||
_Product* create(const _Key& key) const
|
||||
{
|
||||
lazyRegisterCreators();
|
||||
typename Creators::const_iterator it = creators_.find(key);
|
||||
if (it != creators_.end()) {
|
||||
return it->second();
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
{
|
||||
lazyRegisterCreators();
|
||||
return creators_.size();
|
||||
}
|
||||
|
||||
_Product* createByIndex(int index) const
|
||||
{
|
||||
lazyRegisterCreators();
|
||||
YASLI_ASSERT(index >= 0 && index < creators_.size());
|
||||
typename Creators::const_iterator it = creators_.begin();
|
||||
std::advance(it, index);
|
||||
return it->second();
|
||||
}
|
||||
|
||||
|
||||
const Creators& creators() const
|
||||
{
|
||||
lazyRegisterCreators();
|
||||
return creators_;
|
||||
}
|
||||
|
||||
static Factory& the()
|
||||
{
|
||||
static Factory* genericFactory = nullptr;
|
||||
static AZStd::aligned_storage_for_t<Factory> s_storage;
|
||||
if (!genericFactory)
|
||||
{
|
||||
genericFactory = new(&s_storage) Factory();
|
||||
}
|
||||
return *genericFactory;
|
||||
}
|
||||
|
||||
private:
|
||||
void lazyRegisterCreators() const
|
||||
{
|
||||
if (s_creatorsHead)
|
||||
{
|
||||
Creator* creator = s_creatorsHead;
|
||||
while (creator)
|
||||
{
|
||||
creator->Register();
|
||||
creator = creator->m_next;
|
||||
}
|
||||
s_creatorsHead = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
Creators creators_;
|
||||
|
||||
static Creator* s_creatorsHead;
|
||||
};
|
||||
|
||||
template <class _Key, class _Product, class _KeyPred>
|
||||
typename Factory<_Key, _Product, _KeyPred>::Creator* Factory<_Key, _Product, _KeyPred>::s_creatorsHead = nullptr;
|
||||
|
||||
#define REGISTER_IN_FACTORY(factory, key, product, construction_function) \
|
||||
static factory::Creator factory##product##Creator(key, construction_function);
|
||||
|
||||
#define REGISTER_IN_FACTORY_INSTANCE(factory, factoryType, key, product) \
|
||||
static factoryType::Creator<product> factoryType##product##Creator(factory, key);
|
||||
|
||||
#define DECLARE_SEGMENT(fileName) int dataSegment##fileName;
|
||||
|
||||
#define FORCE_SEGMENT(fileName) \
|
||||
extern int dataSegment##fileName; \
|
||||
int* dataSegmentPtr##fileName = &dataSegment##fileName;
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_FACTORY_H
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_MATHUTILS_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_MATHUTILS_H
|
||||
#pragma once
|
||||
|
||||
inline int xround(float v)
|
||||
{
|
||||
return int(v + 0.5f);
|
||||
}
|
||||
|
||||
inline int min(int a, int b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
inline int max(int a, int b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
inline float min(float a, float b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
inline float max(float a, float b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
inline float clamp(float value, float min, float max)
|
||||
{
|
||||
return ::min(::max(min, value), max);
|
||||
}
|
||||
|
||||
inline int clamp(int value, int min, int max)
|
||||
{
|
||||
return ::min(::max(min, value), max);
|
||||
}
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_MATHUTILS_H
|
||||
@@ -1,466 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "PropertyDrawContext.h"
|
||||
#include <memory>
|
||||
#include "QPropertyTree.h"
|
||||
#include "Serialization/Decorators/IconXPM.h"
|
||||
#include "Unicode.h"
|
||||
#include <QApplication>
|
||||
#include <QStyleOption>
|
||||
#include <QPainter>
|
||||
#include <QBitmap>
|
||||
|
||||
// required to create context for the draw calls
|
||||
#include <QPushButton>
|
||||
#include <QCheckBox>
|
||||
#include <QLineEdit>
|
||||
|
||||
#include <AzQtComponents/Components/StyleManager.h>
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# define _stricmp strcasecmp
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
QColor interpolateColor(const QColor& a, const QColor& b, float k);
|
||||
|
||||
IconXPMCache::~IconXPMCache()
|
||||
{
|
||||
flush();
|
||||
}
|
||||
|
||||
|
||||
void IconXPMCache::flush()
|
||||
{
|
||||
IconToBitmap::iterator it;
|
||||
for (it = iconToImageMap_.begin(); it != iconToImageMap_.end(); ++it)
|
||||
delete it->second.bitmap;
|
||||
iconToImageMap_.clear();
|
||||
}
|
||||
|
||||
struct RGBAImage
|
||||
{
|
||||
int width_;
|
||||
int height_;
|
||||
std::vector<Color> pixels_;
|
||||
|
||||
RGBAImage() : width_(0), height_(0) {}
|
||||
};
|
||||
|
||||
bool IconXPMCache::parseXPM(RGBAImage* out, const Serialization::IconXPM& icon)
|
||||
{
|
||||
if (icon.lineCount < 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse values
|
||||
std::vector<Color> pixels;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
int charsPerPixel = 0;
|
||||
int colorCount = 0;
|
||||
int hotSpotX = -1;
|
||||
int hotSpotY = -1;
|
||||
|
||||
int scanResult = azsscanf(icon.source[0], "%d %d %d %d %d %d", &width, &height, &colorCount, &charsPerPixel, &hotSpotX, &hotSpotY);
|
||||
if (scanResult != 4 && scanResult != 6)
|
||||
return false;
|
||||
|
||||
if (charsPerPixel > 4)
|
||||
return false;
|
||||
|
||||
if (icon.lineCount != 1 + colorCount + height) {
|
||||
YASLI_ASSERT(0 && "Wrong line count");
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse colors
|
||||
std::vector<std::pair<int, Color> > colors;
|
||||
colors.resize(colorCount);
|
||||
|
||||
for (int colorIndex = 0; colorIndex < colorCount; ++colorIndex) {
|
||||
const char* p = icon.source[colorIndex + 1];
|
||||
int code = 0;
|
||||
for (int charIndex = 0; charIndex < charsPerPixel; ++charIndex) {
|
||||
if (*p == '\0')
|
||||
return false;
|
||||
code = (code << 8) | *p;
|
||||
++p;
|
||||
}
|
||||
colors[colorIndex].first = code;
|
||||
|
||||
while (*p == '\t' || *p == ' ')
|
||||
++p;
|
||||
|
||||
if (*p == '\0')
|
||||
return false;
|
||||
|
||||
if (*p != 'c' && *p != 'g')
|
||||
return false;
|
||||
++p;
|
||||
|
||||
while (*p == '\t' || *p == ' ')
|
||||
++p;
|
||||
|
||||
if (*p == '\0')
|
||||
return false;
|
||||
|
||||
if (*p == '#') {
|
||||
++p;
|
||||
if (strlen(p) == 6) {
|
||||
int colorCode;
|
||||
if (azsscanf(p, "%x", &colorCode) != 1)
|
||||
return false;
|
||||
Color color((colorCode & 0xff0000) >> 16,
|
||||
(colorCode & 0xff00) >> 8,
|
||||
(colorCode & 0xff),
|
||||
255);
|
||||
colors[colorIndex].second = color;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (_stricmp(p, "None") == 0)
|
||||
colors[colorIndex].second = Color(0, 0, 0, 0);
|
||||
else if (_stricmp(p, "Black") == 0)
|
||||
colors[colorIndex].second = Color(0, 0, 0, 255);
|
||||
else {
|
||||
// unknown color
|
||||
colors[colorIndex].second = Color(255, 0, 0, 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parse pixels
|
||||
pixels.resize(width * height);
|
||||
int pi = 0;
|
||||
for (int y = 0; y < height; ++y) {
|
||||
const char* p = icon.source[1 + colorCount + y];
|
||||
if (strlen(p) != width * charsPerPixel)
|
||||
return false;
|
||||
|
||||
for (int x = 0; x < width; ++x) {
|
||||
int code = 0;
|
||||
for (int i = 0; i < charsPerPixel; ++i) {
|
||||
code = (code << 8) | *p;
|
||||
++p;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < size_t(colorCount); ++i)
|
||||
if (colors[i].first == code)
|
||||
pixels[pi] = colors[i].second;
|
||||
++pi;
|
||||
}
|
||||
}
|
||||
|
||||
out->pixels_.swap(pixels);
|
||||
out->width_ = width;
|
||||
out->height_ = height;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QImage* IconXPMCache::getImageForIcon(const Serialization::IconXPM& icon)
|
||||
{
|
||||
IconToBitmap::iterator it = iconToImageMap_.find(icon.source);
|
||||
if (it != iconToImageMap_.end())
|
||||
return it->second.bitmap;
|
||||
|
||||
RGBAImage image;
|
||||
if (!parseXPM(&image, icon))
|
||||
return 0;
|
||||
|
||||
BitmapCache& cache = iconToImageMap_[icon.source];
|
||||
cache.pixels.swap(image.pixels_);
|
||||
cache.bitmap = new QImage((unsigned char*)&cache.pixels[0], image.width_, image.height_, QImage::Format_ARGB32);
|
||||
return cache.bitmap;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void drawRoundRectangle(QPainter& p, const QRect &_r, unsigned int color, int radius, [[maybe_unused]] int width)
|
||||
{
|
||||
QRect r = _r;
|
||||
int dia = 2 * radius;
|
||||
|
||||
p.setPen(QColor(color));
|
||||
p.drawRoundedRect(r, dia, dia);
|
||||
}
|
||||
|
||||
void fillRoundRectangle(QPainter& p, const QBrush& brush, const QRect& _r, const QColor& border, int radius)
|
||||
{
|
||||
bool wasAntialisingSet = p.renderHints().testFlag(QPainter::Antialiasing);
|
||||
p.setRenderHints(QPainter::Antialiasing, true);
|
||||
|
||||
p.setBrush(brush);
|
||||
QPen pen(QBrush(border), 1.0, Qt::SolidLine);
|
||||
p.setPen(pen);
|
||||
QRectF adjustedRect = _r;
|
||||
adjustedRect.adjust(0.5f, 0.5f, -0.5f, -0.5f);
|
||||
p.drawRoundedRect(adjustedRect, radius, radius);
|
||||
|
||||
p.setRenderHints(QPainter::Antialiasing, wasAntialisingSet);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void PropertyDrawContext::drawIcon(const QRect& rect, const Serialization::IconXPM& icon) const
|
||||
{
|
||||
QImage* image = tree->_iconCache()->getImageForIcon(icon);
|
||||
if (!image)
|
||||
return;
|
||||
int x = rect.left() + (rect.width() - image->width()) / 2;
|
||||
int y = rect.top() + (rect.height() - image->height()) / 2;
|
||||
painter->drawImage(x, y, *image);
|
||||
}
|
||||
|
||||
void PropertyDrawContext::drawCheck(const QRect& rect, bool disabled, CheckState checked) const
|
||||
{
|
||||
QStyleOptionButton option;
|
||||
if (!disabled)
|
||||
option.state |= QStyle::State_Enabled;
|
||||
else {
|
||||
option.state |= QStyle::State_ReadOnly;
|
||||
option.palette.setCurrentColorGroup(QPalette::Disabled);
|
||||
}
|
||||
if (checked == CHECK_SET)
|
||||
option.state |= QStyle::State_On;
|
||||
else if (checked == CHECK_IN_BETWEEN)
|
||||
option.state |= QStyle::State_NoChange;
|
||||
else
|
||||
option.state |= QStyle::State_Off;
|
||||
|
||||
// create a widget so that the style sheet has context for its draw calls
|
||||
QCheckBox forContext;
|
||||
QSize checkboxSize = tree->style()->subElementRect(QStyle::SE_CheckBoxIndicator, &option, &forContext).size();
|
||||
option.rect = QRect(rect.left(), rect.center().y() - checkboxSize.height() / 2, checkboxSize.width(), checkboxSize.height());
|
||||
tree->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter, &forContext);
|
||||
if (disabled) {
|
||||
// With Fusion theme difference between disabled and enabled checkbox is very subtle, let's amplify it
|
||||
QColor readOnlyOverlay = tree->backgroundColor();
|
||||
readOnlyOverlay.setAlpha(128);
|
||||
painter->fillRect(option.rect, QBrush(readOnlyOverlay));
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyDrawContext::drawButton(const QRect& rect, const wchar_t* text, int buttonFlags, const QFont* font, const Color* colorOverride) const
|
||||
{
|
||||
QPushButton button;
|
||||
button.ensurePolished();
|
||||
QStyleOptionButton option;
|
||||
option.initFrom(&button);
|
||||
if (buttonFlags & BUTTON_DISABLED) {
|
||||
option.state |= QStyle::State_ReadOnly;
|
||||
option.palette.setCurrentColorGroup(QPalette::Disabled);
|
||||
}
|
||||
else
|
||||
option.state |= QStyle::State_Enabled;
|
||||
if (buttonFlags & BUTTON_PRESSED) {
|
||||
option.state |= QStyle::State_On;
|
||||
option.state |= QStyle::State_Sunken;
|
||||
}
|
||||
else
|
||||
option.state |= QStyle::State_Raised;
|
||||
|
||||
if (buttonFlags & BUTTON_FOCUSED)
|
||||
option.state |= QStyle::State_HasFocus;
|
||||
option.rect = rect.adjusted(0, 0, -1, -1);
|
||||
|
||||
QWidget* pseudoDrawWidget = &button;
|
||||
|
||||
if (colorOverride) {
|
||||
QPalette& palette = option.palette;
|
||||
palette.setCurrentColorGroup(QPalette::Normal);
|
||||
QColor tintTarget(colorOverride->r, colorOverride->g, colorOverride->b, colorOverride->a);
|
||||
|
||||
QPalette::ColorRole groups[] = { QPalette::Button, QPalette::Light, QPalette::Dark, QPalette::Midlight, QPalette::Mid, QPalette::Shadow };
|
||||
for (int i = 0; i < sizeof(groups) / sizeof(groups[0]); ++i)
|
||||
palette.setColor(groups[i], interpolateColor(palette.color(groups[i]), tintTarget, 0.11f));
|
||||
|
||||
tree->style()->drawControl(QStyle::CE_PushButtonBevel, &option, painter, pseudoDrawWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Previously, a temporary QPushButton widget was used as the drawing aid
|
||||
// for this control. However, our stylesheets didn't seem to affect the
|
||||
// QPushButton as intended, which left some of them with incorrect background
|
||||
// colors. It seemed to work to let the tree be the drawing aid, but we should
|
||||
// probably revisit this in the future.
|
||||
tree->style()->drawControl(QStyle::CE_PushButtonBevel, &option, painter, pseudoDrawWidget);
|
||||
}
|
||||
|
||||
QRect textRect;
|
||||
if ((buttonFlags & BUTTON_DISABLED) == 0 && buttonFlags & BUTTON_POPUP_ARROW)
|
||||
{
|
||||
QStyleOption arrowOption;
|
||||
arrowOption.rect = QRect(rect.right() - 11, rect.top(), 8, rect.height());
|
||||
arrowOption.state |= QStyle::State_Enabled;
|
||||
|
||||
// part of the above context change
|
||||
tree->style()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &arrowOption, painter, tree);
|
||||
|
||||
textRect = rect.adjusted(0, 0, -8, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
textRect = rect;
|
||||
}
|
||||
|
||||
if (buttonFlags & BUTTON_PRESSED)
|
||||
{
|
||||
textRect = textRect.adjusted(1, 0, 1, 0);
|
||||
}
|
||||
if ((buttonFlags & BUTTON_CENTER) == 0)
|
||||
{
|
||||
textRect.adjust(4, 0, -5, 0);
|
||||
}
|
||||
|
||||
QColor textColor;
|
||||
if (colorOverride && !(buttonFlags & BUTTON_DISABLED))
|
||||
{
|
||||
textColor = interpolateColor(tree->palette().color(QPalette::Normal, QPalette::ButtonText),
|
||||
QColor(colorOverride->r, colorOverride->g, colorOverride->b, colorOverride->a), 0.4f);
|
||||
}
|
||||
else
|
||||
{
|
||||
textColor = tree->palette().color((buttonFlags & BUTTON_DISABLED) ? QPalette::Disabled : QPalette::Normal, QPalette::ButtonText);
|
||||
}
|
||||
tree->_drawRowValue(*painter, text, font, textRect, textColor, false, (buttonFlags & BUTTON_CENTER) != 0);
|
||||
}
|
||||
|
||||
void PropertyDrawContext::drawButtonWithIcon(const QIcon& icon, const QRect& rect, const wchar_t* text, bool selected, bool pressed, bool focused, bool enabled, bool showButtonFrame, const QFont* font) const
|
||||
{
|
||||
QStyleOptionButton option;
|
||||
if (enabled)
|
||||
option.state |= QStyle::State_Enabled;
|
||||
else
|
||||
option.state |= QStyle::State_ReadOnly;
|
||||
if (pressed) {
|
||||
option.state |= QStyle::State_On;
|
||||
option.state |= QStyle::State_Sunken;
|
||||
}
|
||||
else
|
||||
option.state |= QStyle::State_Raised;
|
||||
|
||||
if (focused)
|
||||
option.state |= QStyle::State_HasFocus;
|
||||
option.rect = rect.adjusted(0, 0, -1, -1);
|
||||
|
||||
// See the comment in the drawButton method above for why we don't use the
|
||||
// QPushButton as the drawing aid for this control
|
||||
if (showButtonFrame)
|
||||
tree->style()->drawControl(QStyle::CE_PushButton, &option, painter, tree);
|
||||
|
||||
int iconSize = 16;
|
||||
QRect iconRect(rect.topLeft(), QPoint(rect.left() + iconSize, rect.bottom()));
|
||||
QRect textRect;
|
||||
if (enabled)
|
||||
textRect = rect.adjusted(iconSize, 0, -8, 0);
|
||||
else
|
||||
textRect = rect.adjusted(iconSize, 0, 0, 0);
|
||||
|
||||
if (pressed)
|
||||
{
|
||||
textRect.adjust(5, 0, 1, 0);
|
||||
iconRect.adjust(4, 0, 4, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
textRect.adjust(4, 0, 0, 0);
|
||||
iconRect.adjust(3, 0, 3, 0);
|
||||
}
|
||||
icon.paint(painter, iconRect);
|
||||
|
||||
QColor textColor = tree->palette().color(enabled ? QPalette::Active : QPalette::Disabled, selected && !showButtonFrame ? QPalette::HighlightedText : QPalette::ButtonText);
|
||||
tree->_drawRowValue(*painter, text, font, textRect, textColor, false, false);
|
||||
}
|
||||
|
||||
void PropertyDrawContext::drawValueText(bool highlighted, const wchar_t* text) const
|
||||
{
|
||||
QColor textColor = highlighted ? tree->palette().highlight().color() : tree->palette().buttonText().color();
|
||||
QRect textRect(widgetRect.left() + 3, widgetRect.top() + 2, widgetRect.width() - 6, widgetRect.height() - 4);
|
||||
tree->_drawRowValue(*painter, text, &tree->font(), textRect, textColor, false, false);
|
||||
}
|
||||
|
||||
void PropertyDrawContext::drawEntry(const wchar_t* text, bool pathEllipsis, bool grayBackground, int trailingOffset) const
|
||||
{
|
||||
QRect rt = widgetRect;
|
||||
rt.adjust(0, 0, -trailingOffset, 0);
|
||||
|
||||
// the drawing context requires context so that the style sheet can be used:
|
||||
QFrame frameForContext;
|
||||
QLineEdit forContext;
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 11, 0))
|
||||
QStyleOptionFrameV2 option;
|
||||
option.features = QStyleOptionFrameV2::None;
|
||||
#else
|
||||
QStyleOptionFrame option;
|
||||
option.features = QStyleOptionFrame::None;
|
||||
#endif
|
||||
option.state = QStyle::State_Sunken;
|
||||
option.lineWidth = tree->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &option, &frameForContext);
|
||||
option.midLineWidth = 0;
|
||||
if (!grayBackground)
|
||||
option.state |= QStyle::State_Enabled;
|
||||
else {
|
||||
option.palette.setCurrentColorGroup(QPalette::Disabled);
|
||||
}
|
||||
if (captured)
|
||||
option.state |= QStyle::State_HasFocus;
|
||||
option.rect = rt; // option.rect is the rectangle to be drawn on.
|
||||
QRect textRect = tree->style()->subElementRect(QStyle::SE_LineEditContents, &option, &forContext);
|
||||
if (!textRect.isValid())
|
||||
{
|
||||
textRect = rt;
|
||||
textRect.adjust(3, 1, -3, -2);
|
||||
}
|
||||
else {
|
||||
textRect.adjust(2, 1, -2, -1);
|
||||
}
|
||||
|
||||
// make sure the context control is polished (ie, ready for rendering) since we need to use its color palette:
|
||||
forContext.ensurePolished();
|
||||
|
||||
// some styles rely on default pens
|
||||
painter->setPen(QPen(forContext.palette().color(QPalette::Text)));
|
||||
painter->setBrush(QBrush(forContext.palette().color(QPalette::Base)));
|
||||
|
||||
tree->style()->drawPrimitive(QStyle::PE_PanelLineEdit, &option, painter, &forContext);
|
||||
tree->_drawRowValue(*painter, text, &tree->font(), textRect, forContext.palette().color(QPalette::Text), pathEllipsis, false);
|
||||
// end amazno changes
|
||||
}
|
||||
|
||||
|
||||
QFont* propertyTreeDefaultFont()
|
||||
{
|
||||
static QFont font;
|
||||
return &font;
|
||||
}
|
||||
|
||||
QFont* propertyTreeDefaultBoldFont()
|
||||
{
|
||||
static QFont font;
|
||||
font.setBold(true);
|
||||
return &font;
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYDRAWCONTEXT_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYDRAWCONTEXT_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <QRect>
|
||||
#include "Color.h"
|
||||
#include "EditorCommonAPI.h"
|
||||
|
||||
class QPainter;
|
||||
class QImage;
|
||||
class QBrush;
|
||||
class QRect;
|
||||
class QIcon;
|
||||
class QColor;
|
||||
class QFont;
|
||||
struct RGBAImage;
|
||||
namespace Serialization { struct IconXPM; }
|
||||
struct Color;
|
||||
|
||||
struct IconXPMCache
|
||||
{
|
||||
void initialize();
|
||||
void finalize();
|
||||
void flush();
|
||||
|
||||
~IconXPMCache();
|
||||
|
||||
QImage* getImageForIcon(const Serialization::IconXPM& icon);
|
||||
private:
|
||||
struct BitmapCache {
|
||||
std::vector<Color> pixels;
|
||||
QImage* bitmap;
|
||||
};
|
||||
|
||||
static bool parseXPM(RGBAImage* out, const Serialization::IconXPM& xpm);
|
||||
typedef std::map<const char* const*, BitmapCache> IconToBitmap;
|
||||
IconToBitmap iconToImageMap_;
|
||||
};
|
||||
|
||||
|
||||
void fillRoundRectangle(QPainter& p, const QBrush& brush, const QRect& r, const QColor& borderColor, int radius);
|
||||
void drawRoundRectangle(QPainter& p, const QRect &_r, unsigned int color, int radius, int width);
|
||||
|
||||
|
||||
enum CheckState {
|
||||
CHECK_SET,
|
||||
CHECK_NOT_SET,
|
||||
CHECK_IN_BETWEEN
|
||||
};
|
||||
|
||||
enum {
|
||||
BUTTON_POPUP_ARROW = 1 << 0,
|
||||
BUTTON_DISABLED = 1 << 1,
|
||||
BUTTON_FOCUSED = 1 << 2,
|
||||
BUTTON_PRESSED = 1 << 3,
|
||||
BUTTON_CENTER = 1 << 4
|
||||
};
|
||||
|
||||
class QPropertyTree;
|
||||
struct EDITOR_COMMON_API PropertyDrawContext {
|
||||
const QPropertyTree* tree;
|
||||
QPainter* painter;
|
||||
QRect widgetRect;
|
||||
QRect lineRect;
|
||||
bool captured;
|
||||
bool m_pressed;
|
||||
|
||||
void drawIcon(const QRect& rect, const Serialization::IconXPM& icon) const;
|
||||
void drawCheck(const QRect& rect, bool disabled, CheckState checked) const;
|
||||
void drawButton(const QRect& rect, const wchar_t* text, int buttonFlags, const QFont* font, const Color* optionalColorOverride = 0) const;
|
||||
void drawButtonWithIcon(const QIcon& icon, const QRect& rect, const wchar_t* text, bool selected, bool pressed, bool focused, bool enabled, bool showButtonFrame, const QFont* font) const;
|
||||
void drawValueText(bool highlighted, const wchar_t* text) const;
|
||||
void drawEntry(const wchar_t* text, bool pathEllipsis, bool grayBackground, int trailingOffset) const;
|
||||
|
||||
PropertyDrawContext()
|
||||
: tree(0)
|
||||
, painter(0)
|
||||
, captured(false)
|
||||
, m_pressed(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYDRAWCONTEXT_H
|
||||
@@ -1,377 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "Serialization.h"
|
||||
#include "Serialization/Enum.h"
|
||||
#include "Serialization/Callback.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "PropertyIArchive.h"
|
||||
#include "PropertyRowBool.h"
|
||||
#include "PropertyRowString.h"
|
||||
#include "PropertyRowNumber.h"
|
||||
#include "PropertyRowPointer.h"
|
||||
#include "PropertyRowObject.h"
|
||||
#include "Unicode.h"
|
||||
|
||||
using Serialization::TypeID;
|
||||
|
||||
PropertyIArchive::PropertyIArchive(PropertyTreeModel* model, PropertyRow* root)
|
||||
: IArchive(INPUT | EDIT)
|
||||
, model_(model)
|
||||
, currentNode_(0)
|
||||
, lastNode_(0)
|
||||
, root_(root)
|
||||
{
|
||||
stack_.push_back(Level());
|
||||
|
||||
if (!root_)
|
||||
root_ = model_->root();
|
||||
else
|
||||
currentNode_ = root;
|
||||
}
|
||||
|
||||
bool PropertyIArchive::operator()(Serialization::IString& value, const char* name, const char* label)
|
||||
{
|
||||
if(openRow(name, label, "string")){
|
||||
if(PropertyRowString* row = static_cast<PropertyRowString*>(currentNode_))
|
||||
value.set(fromWideChar(row->value().c_str()).c_str());
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyIArchive::operator()(Serialization::IWString& value, const char* name, const char* label)
|
||||
{
|
||||
if(openRow(name, label, "string")){
|
||||
if(PropertyRowString* row = static_cast<PropertyRowString*>(currentNode_)) {
|
||||
value.set(row->value().c_str());
|
||||
}
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyIArchive::operator()(bool& value, const char* name, const char* label)
|
||||
{
|
||||
if(openRow(name, label, "bool")){
|
||||
currentNode_->assignToPrimitive(&value, sizeof(value));
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyIArchive::operator()(char& value, const char* name, const char* label)
|
||||
{
|
||||
if(openRow(name, label, "char")){
|
||||
currentNode_->assignToPrimitive(&value, sizeof(value));
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// Signed types
|
||||
bool PropertyIArchive::operator()(int8& value, const char* name, const char* label)
|
||||
{
|
||||
if(openRow(name, label, "int8")){
|
||||
currentNode_->assignToPrimitive(&value, sizeof(value));
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyIArchive::operator()(int16& value, const char* name, const char* label)
|
||||
{
|
||||
if(openRow(name, label, "int16")){
|
||||
currentNode_->assignToPrimitive(&value, sizeof(value));
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyIArchive::operator()(int32& value, const char* name, const char* label)
|
||||
{
|
||||
if(openRow(name, label, "int32")){
|
||||
currentNode_->assignToPrimitive(&value, sizeof(value));
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyIArchive::operator()(int64& value, const char* name, const char* label)
|
||||
{
|
||||
if(openRow(name, label, "int64")){
|
||||
currentNode_->assignToPrimitive(&value, sizeof(value));
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// Unsigned types
|
||||
bool PropertyIArchive::operator()(uint8& value, const char* name, const char* label)
|
||||
{
|
||||
if(openRow(name, label, "uint8")){
|
||||
currentNode_->assignToPrimitive(&value, sizeof(value));
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyIArchive::operator()(uint16& value, const char* name, const char* label)
|
||||
{
|
||||
if(openRow(name, label, "uint16")){
|
||||
currentNode_->assignToPrimitive(&value, sizeof(value));
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyIArchive::operator()(uint32& value, const char* name, const char* label)
|
||||
{
|
||||
if(openRow(name, label, "uint32")){
|
||||
currentNode_->assignToPrimitive(&value, sizeof(value));
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyIArchive::operator()(uint64& value, const char* name, const char* label)
|
||||
{
|
||||
if(openRow(name, label, "uint64")){
|
||||
currentNode_->assignToPrimitive(&value, sizeof(value));
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyIArchive::operator()(float& value, const char* name, const char* label)
|
||||
{
|
||||
if(openRow(name, label, "float")){
|
||||
currentNode_->assignToPrimitive(&value, sizeof(value));
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyIArchive::operator()(double& value, const char* name, const char* label)
|
||||
{
|
||||
if(openRow(name, label, "double")){
|
||||
currentNode_->assignToPrimitive(&value, sizeof(value));
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyIArchive::operator()(Serialization::IContainer& ser, const char* name, const char* label)
|
||||
{
|
||||
const char* typeName = ser.containerType().name();
|
||||
if(!openRow(name, label, typeName))
|
||||
return false;
|
||||
|
||||
size_t size = 0;
|
||||
if(currentNode_->multiValue())
|
||||
size = ser.size();
|
||||
else{
|
||||
size = currentNode_->count();
|
||||
size = ser.resize(size);
|
||||
}
|
||||
|
||||
stack_.push_back(Level());
|
||||
|
||||
size_t index = 0;
|
||||
if(ser.size() > 0)
|
||||
while(index < size)
|
||||
{
|
||||
ser(*this, "", "<");
|
||||
ser.next();
|
||||
++index;
|
||||
}
|
||||
|
||||
stack_.pop_back();
|
||||
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyIArchive::operator()(const Serialization::SStruct& ser, const char* name, const char* label)
|
||||
{
|
||||
PropertyRow* nonLeafNode = 0;
|
||||
if(openRow(name, label, ser.type().name())){
|
||||
if (currentNode_->isLeaf()) {
|
||||
if(!currentNode_->isRoot()){
|
||||
currentNode_->assignTo(ser);
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
nonLeafNode = currentNode_;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
stack_.push_back(Level());
|
||||
|
||||
ser(*this);
|
||||
|
||||
stack_.pop_back();
|
||||
|
||||
if (nonLeafNode)
|
||||
nonLeafNode->closeNonLeaf(ser, *this);
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PropertyIArchive::operator()(Serialization::IPointer& ser, const char* name, const char* label)
|
||||
{
|
||||
const char* baseName = ser.baseType().name();
|
||||
|
||||
if(openRow(name, label, baseName)){
|
||||
if (!currentNode_->isPointer()) {
|
||||
closeRow(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
YASLI_ASSERT(currentNode_);
|
||||
PropertyRowPointer* row = static_cast<PropertyRowPointer*>(currentNode_);
|
||||
if(!row){
|
||||
closeRow(name);
|
||||
return false;
|
||||
}
|
||||
row->assignTo(ser);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
stack_.push_back(Level());
|
||||
|
||||
if(ser.get() != 0)
|
||||
ser.serializer()( *this );
|
||||
|
||||
stack_.pop_back();
|
||||
|
||||
closeRow(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyIArchive::operator()(Serialization::ICallback& callback, const char* name, const char* label)
|
||||
{
|
||||
return callback.SerializeValue(*this, name, label);
|
||||
}
|
||||
|
||||
bool PropertyIArchive::operator()(Serialization::Object& obj, const char* name, const char* label)
|
||||
{
|
||||
if(openRow(name, label, obj.type().name())){
|
||||
bool result = false;
|
||||
if (currentNode_->isObject()) {
|
||||
PropertyRowObject* rowObj = static_cast<PropertyRowObject*>(currentNode_);
|
||||
result = rowObj->assignTo(&obj);
|
||||
}
|
||||
closeRow(name);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyIArchive::OpenBlock(const char* name, const char* label)
|
||||
{
|
||||
if(openRow(name, label, "block")){
|
||||
stack_.push_back(Level());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void PropertyIArchive::CloseBlock()
|
||||
{
|
||||
closeRow("block");
|
||||
stack_.pop_back();
|
||||
}
|
||||
|
||||
bool PropertyIArchive::openRow(const char* name, [[maybe_unused]] const char* label, const char* typeName)
|
||||
{
|
||||
if(!name)
|
||||
return false;
|
||||
|
||||
if(!currentNode_){
|
||||
lastNode_ = currentNode_ = model_->root();
|
||||
YASLI_ASSERT(currentNode_);
|
||||
if (currentNode_ && strcmp(currentNode_->typeName(), typeName) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
YASLI_ESCAPE(currentNode_, return false);
|
||||
|
||||
if(currentNode_->empty())
|
||||
return false;
|
||||
|
||||
Level& level = stack_.back();
|
||||
|
||||
PropertyRow* node = 0;
|
||||
if(currentNode_->isContainer()){
|
||||
if (level.rowIndex < int(currentNode_->children_.size()))
|
||||
node = currentNode_->children_[level.rowIndex];
|
||||
++level.rowIndex;
|
||||
}
|
||||
else {
|
||||
node = currentNode_->findFromIndex(&level.rowIndex, name, typeName, level.rowIndex);
|
||||
++level.rowIndex;
|
||||
}
|
||||
|
||||
if(node){
|
||||
lastNode_ = node;
|
||||
if(node->isContainer() || !node->multiValue()){
|
||||
currentNode_ = node;
|
||||
if (currentNode_ && strcmp(currentNode_->typeName(), typeName) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PropertyIArchive::closeRow([[maybe_unused]] const char* name)
|
||||
{
|
||||
YASLI_ESCAPE(currentNode_, return);
|
||||
currentNode_ = currentNode_->parent();
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYIARCHIVE_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYIARCHIVE_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "Serialization/IArchive.h"
|
||||
|
||||
namespace Serialization{
|
||||
class CEnumDescription;
|
||||
class Object;
|
||||
}
|
||||
|
||||
class PropertyRow;
|
||||
class PropertyTreeModel;
|
||||
|
||||
class PropertyIArchive : public Serialization::IArchive{
|
||||
public:
|
||||
PropertyIArchive(PropertyTreeModel* model, PropertyRow* root);
|
||||
|
||||
protected:
|
||||
bool operator()(Serialization::IString& value, const char* name, const char* label);
|
||||
bool operator()(Serialization::IWString& value, const char* name, const char* label);
|
||||
bool operator()(bool& value, const char* name, const char* label);
|
||||
bool operator()(char& value, const char* name, const char* label);
|
||||
|
||||
// Signed types
|
||||
bool operator()(int8& value, const char* name, const char* label);
|
||||
bool operator()(int16& value, const char* name, const char* label);
|
||||
bool operator()(int32& value, const char* name, const char* label);
|
||||
bool operator()(int64& value, const char* name, const char* label);
|
||||
// Unsigned types
|
||||
bool operator()(uint8& value, const char* name, const char* label);
|
||||
bool operator()(uint16& value, const char* name, const char* label);
|
||||
bool operator()(uint32& value, const char* name, const char* label);
|
||||
bool operator()(uint64& value, const char* name, const char* label);
|
||||
|
||||
bool operator()(float& value, const char* name, const char* label);
|
||||
bool operator()(double& value, const char* name, const char* label);
|
||||
|
||||
bool operator()(const Serialization::SStruct& ser, const char* name, const char* label);
|
||||
bool operator()(Serialization::IPointer& ser, const char* name, const char* label);
|
||||
bool operator()(Serialization::IContainer& ser, const char* name, const char* label);
|
||||
bool operator()(Serialization::Object& obj, const char* name, const char* label);
|
||||
bool operator()(Serialization::ICallback& callback, const char* name, const char* label);
|
||||
using Serialization::IArchive::operator();
|
||||
|
||||
bool OpenBlock(const char* name, const char* label);
|
||||
void CloseBlock();
|
||||
|
||||
protected:
|
||||
bool needDefaultArchive([[maybe_unused]] const char* baseName) const { return false; }
|
||||
private:
|
||||
bool openRow(const char* name, const char* label, const char* typeName);
|
||||
void closeRow(const char* name);
|
||||
|
||||
struct Level {
|
||||
int rowIndex;
|
||||
Level() : rowIndex(0) {}
|
||||
};
|
||||
|
||||
vector<Level> stack_;
|
||||
|
||||
PropertyTreeModel* model_;
|
||||
PropertyRow* currentNode_;
|
||||
PropertyRow* lastNode_;
|
||||
PropertyRow* root_;
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYIARCHIVE_H
|
||||
@@ -1,487 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include <math.h>
|
||||
#include <memory>
|
||||
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "QPropertyTree.h"
|
||||
|
||||
#include "PropertyRowContainer.h"
|
||||
#include "PropertyRowBool.h"
|
||||
#include "PropertyRowString.h"
|
||||
#include "PropertyRowNumber.h"
|
||||
#include "PropertyRowPointer.h"
|
||||
#include "PropertyRowObject.h"
|
||||
#include "ConstStringList.h"
|
||||
#include "Unicode.h"
|
||||
|
||||
#include "Serialization.h"
|
||||
#include "PropertyOArchive.h"
|
||||
#include "Serialization/Callback.h"
|
||||
using Serialization::TypeID;
|
||||
|
||||
|
||||
PropertyOArchive::PropertyOArchive(PropertyTreeModel* model, PropertyRow* root, ValidatorBlock* validator)
|
||||
: IArchive(OUTPUT | EDIT | VALIDATION | DOCUMENTATION)
|
||||
, model_(model)
|
||||
, currentNode_(root)
|
||||
, lastNode_(0)
|
||||
, updateMode_(false)
|
||||
, defaultValueCreationMode_(false)
|
||||
, rootNode_(root)
|
||||
, outlineMode_(false)
|
||||
, validator_(validator)
|
||||
{
|
||||
stack_.push_back(Level());
|
||||
YASLI_ASSERT(model != 0);
|
||||
if(!rootNode_->empty()){
|
||||
updateMode_ = true;
|
||||
stack_.back().oldRows.swap(rootNode_->children_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PropertyOArchive::PropertyOArchive(PropertyTreeModel* model, bool forDefaultType)
|
||||
: IArchive(OUTPUT | EDIT | VALIDATION | DOCUMENTATION)
|
||||
, model_(model)
|
||||
, currentNode_(0)
|
||||
, lastNode_(0)
|
||||
, updateMode_(false)
|
||||
, defaultValueCreationMode_(forDefaultType)
|
||||
, rootNode_(0)
|
||||
, outlineMode_(false)
|
||||
, validator_(0)
|
||||
{
|
||||
rootNode_ = new PropertyRow();
|
||||
rootNode_->setName("root");
|
||||
currentNode_ = rootNode_.get();
|
||||
stack_.push_back(Level());
|
||||
}
|
||||
|
||||
PropertyOArchive::~PropertyOArchive()
|
||||
{
|
||||
}
|
||||
|
||||
PropertyRow* PropertyOArchive::defaultValueRootNode()
|
||||
{
|
||||
if (!rootNode_)
|
||||
return 0;
|
||||
return rootNode_->childByIndex(0);
|
||||
}
|
||||
|
||||
void PropertyOArchive::enterNode(PropertyRow* row)
|
||||
{
|
||||
currentNode_ = row;
|
||||
|
||||
stack_.push_back(Level());
|
||||
Level& level = stack_.back();
|
||||
level.oldRows.swap(row->children_);
|
||||
row->children_.reserve(level.oldRows.size());
|
||||
}
|
||||
|
||||
void PropertyOArchive::closeStruct([[maybe_unused]] const char* name)
|
||||
{
|
||||
stack_.pop_back();
|
||||
|
||||
if(currentNode_){
|
||||
lastNode_ = currentNode_;
|
||||
currentNode_ = currentNode_->parent();
|
||||
}
|
||||
}
|
||||
|
||||
static PropertyRow* findRow(int* index, PropertyRows& rows, const char* name, const char* typeName, int startIndex)
|
||||
{
|
||||
int count = int(rows.size());
|
||||
for(int i = startIndex; i < count; ++i){
|
||||
PropertyRow* row = rows[i];
|
||||
if (!row)
|
||||
continue;
|
||||
if(((row->name() == name) || strcmp(row->name(), name) == 0) &&
|
||||
(row->typeName() == typeName || strcmp(row->typeName(), typeName) == 0)) {
|
||||
*index = (int)i;
|
||||
return row;
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < startIndex; ++i){
|
||||
PropertyRow* row = rows[i];
|
||||
if (!row)
|
||||
continue;
|
||||
if(((row->name() == name) || strcmp(row->name(), name) == 0) &&
|
||||
(row->typeName() == typeName || strcmp(row->typeName(), typeName) == 0)) {
|
||||
*index = (int)i;
|
||||
return row;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class RowType, class ValueType>
|
||||
RowType* PropertyOArchive::updateRow(const char* name, const char* label, const char* typeName, const ValueType& value)
|
||||
{
|
||||
SharedPtr<RowType> newRow;
|
||||
if(currentNode_ == 0){
|
||||
if (rootNode_)
|
||||
newRow = static_cast<RowType*>(rootNode_.get());
|
||||
else
|
||||
newRow.reset(new RowType());
|
||||
newRow->setNames(name, label, typeName);
|
||||
if(updateMode_){
|
||||
model_->setRoot(newRow);
|
||||
return newRow;
|
||||
}
|
||||
else{
|
||||
if(defaultValueCreationMode_)
|
||||
rootNode_ = newRow;
|
||||
else
|
||||
model_->setRoot(newRow);
|
||||
newRow->setValueAndContext(value, *this);
|
||||
return newRow;
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
Level& level = stack_.back();
|
||||
int rowIndex;
|
||||
PropertyRow* oldRow = findRow(&rowIndex, level.oldRows, name, typeName, level.rowIndex);
|
||||
|
||||
const char* oldLabel = 0;
|
||||
if(oldRow){
|
||||
oldRow->setMultiValue(false);
|
||||
newRow = static_cast<RowType*>(oldRow);
|
||||
level.oldRows[rowIndex] = 0;
|
||||
level.rowIndex = rowIndex + 1;
|
||||
oldLabel = oldRow->label();
|
||||
newRow->setNames(name, label, typeName);
|
||||
}
|
||||
else{
|
||||
PropertyRowFactory& factory = PropertyRowFactory::the();
|
||||
newRow = static_cast<RowType*>(factory.create(typeName));
|
||||
if(!newRow)
|
||||
newRow.reset(new RowType());
|
||||
newRow->setNames(name, label, typeName);
|
||||
if(model_->expandLevels() != 0 && (model_->expandLevels() == -1 || model_->expandLevels() >= currentNode_->level()))
|
||||
newRow->_setExpanded(true);
|
||||
}
|
||||
currentNode_->add(newRow);
|
||||
if (!oldRow || oldLabel != label) {
|
||||
// for new rows we should mark all parents with labelChanged_
|
||||
newRow->setLabelChanged();
|
||||
newRow->setLabelChangedToChildren();
|
||||
}
|
||||
newRow->setValueAndContext(value, *this);
|
||||
return newRow;
|
||||
}
|
||||
}
|
||||
|
||||
template<class RowType, class ValueType>
|
||||
PropertyRow* PropertyOArchive::updateRowPrimitive(const char* name, const char* label, const char* typeName, const ValueType& value, const void* handle, const Serialization::TypeID& typeId)
|
||||
{
|
||||
SharedPtr<RowType> newRow;
|
||||
|
||||
if(currentNode_ == 0)
|
||||
return 0;
|
||||
|
||||
int rowIndex;
|
||||
Level& level = stack_.back();
|
||||
PropertyRow* oldRow = findRow(&rowIndex, level.oldRows, name, typeName, level.rowIndex);
|
||||
|
||||
const char* oldLabel = 0;
|
||||
if(oldRow){
|
||||
oldRow->setMultiValue(false);
|
||||
newRow.reset(static_cast<RowType*>(oldRow));
|
||||
level.oldRows[rowIndex] = 0;
|
||||
level.rowIndex = rowIndex + 1;
|
||||
oldLabel = oldRow->label();
|
||||
oldRow->setNames(name, label, typeName);
|
||||
}
|
||||
else{
|
||||
newRow = new RowType();
|
||||
newRow->setNames(name, label, typeName);
|
||||
if(model_->expandLevels() != 0){
|
||||
if(model_->expandLevels() == -1 || model_->expandLevels() >= currentNode_->level())
|
||||
newRow->_setExpanded(true);
|
||||
}
|
||||
}
|
||||
currentNode_->add(newRow);
|
||||
if (!oldRow || oldLabel != label)
|
||||
{
|
||||
// for new rows we should mark all parents with labelChanged_
|
||||
newRow->setLabelChanged();
|
||||
}
|
||||
|
||||
newRow->setValue(value, handle, typeId);
|
||||
return newRow;
|
||||
}
|
||||
|
||||
bool PropertyOArchive::operator()(const Serialization::SStruct& ser, const char* name, const char* label)
|
||||
{
|
||||
const char* typeName = ser.type().name();
|
||||
|
||||
lastNode_ = currentNode_;
|
||||
bool hideChildren = outlineMode_ && currentNode_ && currentNode_->isContainer();
|
||||
PropertyRow* row = updateRow<PropertyRow>(name, label, typeName, ser);
|
||||
row->setHideChildren(hideChildren);
|
||||
|
||||
PropertyRow* nonLeaf = 0;
|
||||
if(!row->isLeaf() || currentNode_ == 0){
|
||||
enterNode(row);
|
||||
|
||||
if(currentNode_->isLeaf())
|
||||
return false;
|
||||
else
|
||||
nonLeaf = currentNode_;
|
||||
}
|
||||
else{
|
||||
lastNode_ = row;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ser)
|
||||
ser(*this);
|
||||
|
||||
if (nonLeaf)
|
||||
nonLeaf->closeNonLeaf(ser, *this);
|
||||
|
||||
closeStruct(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyOArchive::operator()(Serialization::IString& value, const char* name, const char* label)
|
||||
{
|
||||
lastNode_ = updateRowPrimitive<PropertyRowString>(name, label, "string", value.get(), value.handle(), value.type());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyOArchive::operator()(Serialization::IWString& value, const char* name, const char* label)
|
||||
{
|
||||
lastNode_ = updateRowPrimitive<PropertyRowString>(name, label, "string", value.get(), value.handle(), value.type());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyOArchive::operator()(bool& value, const char* name, const char* label)
|
||||
{
|
||||
lastNode_ = updateRowPrimitive<PropertyRowBool>(name, label, "bool", value, &value, Serialization::TypeID::get<bool>());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyOArchive::operator()(char& value, const char* name, const char* label)
|
||||
{
|
||||
lastNode_ = updateRowPrimitive<PropertyRowNumber<char> >(name, label, "char", value, &value, Serialization::TypeID::get<char>());
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
bool PropertyOArchive::operator()(int8& value, const char* name, const char* label)
|
||||
{
|
||||
lastNode_ = updateRowPrimitive<PropertyRowNumber<int8> >(name, label, "int8", value, &value, Serialization::TypeID::get<int8>());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyOArchive::operator()(int16& value, const char* name, const char* label)
|
||||
{
|
||||
lastNode_ = updateRowPrimitive<PropertyRowNumber<int16> >(name, label, "int16", value, &value, Serialization::TypeID::get<int16>());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyOArchive::operator()(int32& value, const char* name, const char* label)
|
||||
{
|
||||
lastNode_ = updateRowPrimitive<PropertyRowNumber<int32> >(name, label, "int32", value, &value, Serialization::TypeID::get<int32>());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyOArchive::operator()(int64& value, const char* name, const char* label)
|
||||
{
|
||||
lastNode_ = updateRowPrimitive<PropertyRowNumber<int64> >(name, label, "int64", value, &value, Serialization::TypeID::get<int64>());
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
bool PropertyOArchive::operator()(uint8& value, const char* name, const char* label)
|
||||
{
|
||||
lastNode_ = updateRowPrimitive<PropertyRowNumber<uint8> >(name, label, "uint8", value, &value, Serialization::TypeID::get<uint8>());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyOArchive::operator()(uint16& value, const char* name, const char* label)
|
||||
{
|
||||
lastNode_ = updateRowPrimitive<PropertyRowNumber<uint16> >(name, label, "uint16", value, &value, Serialization::TypeID::get<uint16>());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyOArchive::operator()(uint32& value, const char* name, const char* label)
|
||||
{
|
||||
lastNode_ = updateRowPrimitive<PropertyRowNumber<uint32> >(name, label, "uint32", value, &value, Serialization::TypeID::get<uint32>());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyOArchive::operator()(uint64& value, const char* name, const char* label)
|
||||
{
|
||||
lastNode_ = updateRowPrimitive<PropertyRowNumber<uint64> >(name, label, "uint64", value, &value, Serialization::TypeID::get<uint64>());
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
bool PropertyOArchive::operator()(float& value, const char* name, const char* label)
|
||||
{
|
||||
lastNode_ = updateRowPrimitive<PropertyRowNumber<float> >(name, label, "float", value, &value, Serialization::TypeID::get<float>());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyOArchive::operator()(double& value, const char* name, const char* label)
|
||||
{
|
||||
lastNode_ = updateRowPrimitive<PropertyRowNumber<double> >(name, label, "double", value, &value, Serialization::TypeID::get<double>());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PropertyOArchive::operator()(Serialization::IContainer& ser, const char *name, const char *label)
|
||||
{
|
||||
const char* elementTypeName = ser.elementType().name();
|
||||
enterNode(updateRow<PropertyRowContainer>(name, label, ser.containerType().name(), ser));
|
||||
|
||||
if (!model_->defaultTypeRegistered(elementTypeName)) {
|
||||
PropertyOArchive ar(model_, true);
|
||||
ar.SetOutlineMode(outlineMode_);
|
||||
ar.SetFilter(GetFilter());
|
||||
ar.SetInnerContext(GetInnerContext());
|
||||
model_->addDefaultType(0, elementTypeName); // add empty default to prevent recursion
|
||||
ser.serializeNewElement(ar, "", (label&&*label=='!')?"!<":"<");
|
||||
if (ar.defaultValueRootNode() != 0)
|
||||
model_->addDefaultType(ar.defaultValueRootNode(), elementTypeName);
|
||||
}
|
||||
if ( ser.size() > 0 )
|
||||
while( true ) {
|
||||
ser(*this, "", (label&&*label=='!')?"!<":"<");
|
||||
if ( !ser.next() )
|
||||
break;
|
||||
}
|
||||
currentNode_->labelChanged();
|
||||
closeStruct(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyOArchive::operator()(Serialization::IPointer& ptr, const char *name, const char *label)
|
||||
{
|
||||
lastNode_ = currentNode_;
|
||||
|
||||
bool hideChildren = outlineMode_ && currentNode_ && currentNode_->isContainer();
|
||||
PropertyRow* row = updateRow<PropertyRowPointer>(name, label, ptr.baseType().name(), ptr);
|
||||
row->setHideChildren(hideChildren);
|
||||
enterNode(row);
|
||||
{
|
||||
TypeID baseType = ptr.baseType();
|
||||
Serialization::IClassFactory* factory = ptr.factory();
|
||||
size_t count = factory->size();
|
||||
|
||||
const char* nullLabel = factory->nullLabel();
|
||||
if (!(nullLabel && nullLabel[0] == '\0'))
|
||||
{
|
||||
PropertyDefaultDerivedTypeValue nullValue;
|
||||
nullValue.factory = factory;
|
||||
nullValue.factoryIndex = -1;
|
||||
nullValue.label = nullLabel ? nullLabel : "[ null ]";
|
||||
model_->addDefaultType(baseType, nullValue);
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < count; ++i) {
|
||||
const Serialization::TypeDescription *desc = factory->descriptionByIndex((int)i);
|
||||
if (!model_->defaultTypeRegistered(baseType, desc->name())){
|
||||
PropertyOArchive ar(model_, true);
|
||||
ar.SetOutlineMode(outlineMode_);
|
||||
ar.SetInnerContext(GetInnerContext());
|
||||
ar.SetFilter(GetFilter());
|
||||
|
||||
PropertyDefaultDerivedTypeValue defaultValue;
|
||||
defaultValue.registeredName = desc->name();
|
||||
defaultValue.factory = factory;
|
||||
defaultValue.factoryIndex = int(i);
|
||||
defaultValue.label = desc->label();
|
||||
|
||||
model_->addDefaultType(baseType, defaultValue);
|
||||
factory->serializeNewByIndex(ar, (int)i, "name", "label");
|
||||
if (ar.defaultValueRootNode() != 0) {
|
||||
ar.defaultValueRootNode()->setTypeName(desc->name());
|
||||
defaultValue.root = ar.defaultValueRootNode();
|
||||
model_->addDefaultType(baseType, defaultValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(Serialization::SStruct ser = ptr.serializer())
|
||||
ser(*this);
|
||||
closeStruct(name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyOArchive::operator()(Serialization::ICallback& callback, const char* name, const char* label)
|
||||
{
|
||||
if (!callback.SerializeValue(*this, name, label))
|
||||
return false;
|
||||
|
||||
lastNode_->setCallback(callback.Clone());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyOArchive::operator()(Serialization::Object& obj, const char *name, const char *label)
|
||||
{
|
||||
PropertyRowObject* row = 0;
|
||||
row = updateRow<PropertyRowObject>(name, label, obj.type().name(), obj);
|
||||
|
||||
lastNode_ = row;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyOArchive::OpenBlock(const char* name, const char* label)
|
||||
{
|
||||
PropertyRow* row = updateRow<PropertyRow>(name, label, "block", Serialization::SStruct());
|
||||
lastNode_ = currentNode_;
|
||||
enterNode(row);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PropertyOArchive::ValidatorMessage(bool error, const void* handle, const Serialization::TypeID& type, const char* message)
|
||||
{
|
||||
if (validator_)
|
||||
{
|
||||
ValidatorEntry entry(error ? VALIDATOR_ENTRY_ERROR : VALIDATOR_ENTRY_WARNING,
|
||||
handle,
|
||||
type,
|
||||
message);
|
||||
validator_->AddEntry(entry);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyOArchive::DocumentLastField(const char* message)
|
||||
{
|
||||
if (lastNode_ && (!currentNode_ || lastNode_->parent() == currentNode_))
|
||||
lastNode_->setTooltip(message ? message : "");
|
||||
else if (currentNode_)
|
||||
currentNode_->setTooltip(message ? message : "");
|
||||
}
|
||||
|
||||
void PropertyOArchive::CloseBlock()
|
||||
{
|
||||
closeStruct("block");
|
||||
}
|
||||
|
||||
void PropertyOArchive::SetOutlineMode(bool outlineMode)
|
||||
{
|
||||
outlineMode_ = outlineMode;
|
||||
}
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
@@ -1,112 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYOARCHIVE_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYOARCHIVE_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "Serialization/IArchive.h"
|
||||
#include "Serialization/Pointers.h"
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
class CEnumDescription;
|
||||
class Object;
|
||||
struct ICallback;
|
||||
}
|
||||
|
||||
class PropertyRow;
|
||||
class PropertyTreeModel;
|
||||
class ValidatorBlock;
|
||||
|
||||
using Serialization::SharedPtr;
|
||||
|
||||
class PropertyOArchive : public Serialization::IArchive{
|
||||
public:
|
||||
PropertyOArchive(PropertyTreeModel* model, PropertyRow* root, ValidatorBlock* validator);
|
||||
~PropertyOArchive();
|
||||
|
||||
void SetOutlineMode(bool outlineMode);
|
||||
|
||||
inline const SharedPtr<PropertyRow>& currentNode() const {
|
||||
return currentNode_;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool operator()(Serialization::IString& value, const char* name, const char* label);
|
||||
bool operator()(Serialization::IWString& value, const char* name, const char* label);
|
||||
bool operator()(bool& value, const char* name, const char* label);
|
||||
bool operator()(char& value, const char* name, const char* label);
|
||||
|
||||
bool operator()(int8& value, const char* name, const char* label);
|
||||
bool operator()(int16& value, const char* name, const char* label);
|
||||
bool operator()(int32& value, const char* name, const char* label);
|
||||
bool operator()(int64& value, const char* name, const char* label);
|
||||
|
||||
bool operator()(uint8& value, const char* name, const char* label);
|
||||
bool operator()(uint16& value, const char* name, const char* label);
|
||||
bool operator()(uint32& value, const char* name, const char* label);
|
||||
bool operator()(uint64& value, const char* name, const char* label);
|
||||
|
||||
bool operator()(float& value, const char* name, const char* label);
|
||||
bool operator()(double& value, const char* name, const char* label);
|
||||
|
||||
bool operator()(const Serialization::SStruct& ser, const char* name, const char* label);
|
||||
bool operator()(Serialization::IPointer& ptr, const char *name, const char *label);
|
||||
bool operator()(Serialization::IContainer& ser, const char *name, const char *label);
|
||||
bool operator()(Serialization::Object& obj, const char *name, const char *label);
|
||||
bool operator()(Serialization::ICallback& ser, const char *name, const char *label);
|
||||
using Serialization::IArchive::operator();
|
||||
|
||||
bool OpenBlock(const char* name, const char* label);
|
||||
void CloseBlock();
|
||||
void ValidatorMessage(bool error, const void* handle, const Serialization::TypeID& type, const char* message);
|
||||
void DocumentLastField(const char* docString);
|
||||
|
||||
protected:
|
||||
PropertyOArchive(PropertyTreeModel* model, bool forDefaultType);
|
||||
|
||||
private:
|
||||
struct Level {
|
||||
std::vector<SharedPtr<PropertyRow> > oldRows;
|
||||
int rowIndex;
|
||||
Level() : rowIndex(0) {}
|
||||
};
|
||||
std::vector<Level> stack_;
|
||||
|
||||
template<class RowType, class ValueType>
|
||||
PropertyRow* updateRowPrimitive(const char* name, const char* label, const char* typeName, const ValueType& value, const void* handle, const Serialization::TypeID& typeId);
|
||||
|
||||
template<class RowType, class ValueType>
|
||||
RowType* updateRow(const char* name, const char* label, const char* typeName, const ValueType& value);
|
||||
|
||||
void enterNode(PropertyRow* row); // sets currentNode
|
||||
void closeStruct(const char* name);
|
||||
PropertyRow* defaultValueRootNode();
|
||||
|
||||
bool updateMode_;
|
||||
bool defaultValueCreationMode_;
|
||||
PropertyTreeModel* model_;
|
||||
ValidatorBlock* validator_;
|
||||
SharedPtr<PropertyRow> currentNode_;
|
||||
SharedPtr<PropertyRow> lastNode_;
|
||||
|
||||
// for defaultArchive
|
||||
SharedPtr<PropertyRow> rootNode_;
|
||||
std::string typeName_;
|
||||
const char* derivedTypeName_;
|
||||
std::string derivedTypeNameAlt_;
|
||||
bool outlineMode_;
|
||||
};
|
||||
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYOARCHIVE_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,575 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <typeinfo>
|
||||
#include <algorithm>
|
||||
#include "Serialization/Serializer.h"
|
||||
#include "Serialization/StringList.h"
|
||||
#include <Serialization/Pointers.h>
|
||||
#include "Factory.h"
|
||||
#include "ConstStringList.h"
|
||||
#include "Strings.h"
|
||||
#include "../EditorCommonAPI.h"
|
||||
#include "Serialization/ClassFactory.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QPoint>
|
||||
#include <QRect>
|
||||
#include <QCursor>
|
||||
#endif
|
||||
|
||||
namespace Serialization { struct ICallback; }
|
||||
|
||||
class QWidget;
|
||||
class QFont;
|
||||
class QPainter;
|
||||
class QMenu;
|
||||
class QKeyEvent;
|
||||
|
||||
using std::vector;
|
||||
class QPropertyTree;
|
||||
class PropertyRow;
|
||||
class PropertyTreeModel;
|
||||
class PopupMenuItem;
|
||||
struct PropertyDrawContext;
|
||||
struct EDITOR_COMMON_API ContainerMenuHandler;
|
||||
class PropertyRowContainer;
|
||||
|
||||
enum ScanResult {
|
||||
SCAN_FINISHED,
|
||||
SCAN_CHILDREN,
|
||||
SCAN_SIBLINGS,
|
||||
SCAN_CHILDREN_SIBLINGS,
|
||||
};
|
||||
|
||||
struct EDITOR_COMMON_API PropertyRowMenuHandler : QObject
|
||||
{
|
||||
public:
|
||||
virtual ~PropertyRowMenuHandler() {}
|
||||
|
||||
};
|
||||
|
||||
struct PropertyActivationEvent
|
||||
{
|
||||
enum Reason
|
||||
{
|
||||
REASON_PRESS,
|
||||
REASON_RELEASE,
|
||||
REASON_DOUBLECLICK,
|
||||
REASON_KEYBOARD,
|
||||
REASON_NEW_ELEMENT
|
||||
};
|
||||
|
||||
QPropertyTree* tree;
|
||||
Reason reason;
|
||||
bool force;
|
||||
QPoint clickPoint;
|
||||
|
||||
PropertyActivationEvent()
|
||||
: force(false)
|
||||
, clickPoint(0, 0)
|
||||
, tree(0)
|
||||
, reason(REASON_PRESS)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct PropertyDragEvent
|
||||
{
|
||||
QPropertyTree* tree;
|
||||
QPoint pos;
|
||||
QPoint start;
|
||||
QPoint lastDelta;
|
||||
QPoint totalDelta;
|
||||
};
|
||||
|
||||
struct PropertyHoverInfo
|
||||
{
|
||||
QCursor cursor;
|
||||
QString toolTip;
|
||||
|
||||
PropertyHoverInfo()
|
||||
: cursor()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
enum DragCheckBegin {
|
||||
DRAG_CHECK_IGNORE,
|
||||
DRAG_CHECK_SET,
|
||||
DRAG_CHECK_UNSET
|
||||
};
|
||||
|
||||
class PropertyRowWidget : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PropertyRowWidget(PropertyRow* row, QPropertyTree* tree);
|
||||
virtual ~PropertyRowWidget();
|
||||
virtual QWidget* actualWidget() { return 0; }
|
||||
virtual void showPopup() {}
|
||||
virtual void commit() = 0;
|
||||
PropertyRow* row() { return row_; }
|
||||
PropertyTreeModel* model() { return model_; }
|
||||
protected:
|
||||
PropertyRow* row_;
|
||||
QPropertyTree* tree_;
|
||||
PropertyTreeModel* model_;
|
||||
};
|
||||
|
||||
class PropertyTreeTransaction;
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
|
||||
class EDITOR_COMMON_API PropertyRow : public Serialization::RefCounter
|
||||
{
|
||||
AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
|
||||
public:
|
||||
enum WidgetPlacement {
|
||||
WIDGET_NONE,
|
||||
WIDGET_ICON,
|
||||
WIDGET_AFTER_NAME,
|
||||
WIDGET_VALUE,
|
||||
WIDGET_AFTER_PULLED,
|
||||
WIDGET_INSTEAD_OF_TEXT
|
||||
};
|
||||
|
||||
typedef std::vector< Serialization::SharedPtr<PropertyRow> > Rows;
|
||||
typedef Rows::iterator iterator;
|
||||
typedef Rows::const_iterator const_iterator;
|
||||
|
||||
PropertyRow();
|
||||
virtual ~PropertyRow();
|
||||
|
||||
void setNames(const char* name, const char* label, const char* typeName);
|
||||
|
||||
bool selected() const{ return selected_; }
|
||||
void setSelected(bool selected) { selected_ = selected; }
|
||||
bool expanded() const{ return expanded_; }
|
||||
void _setExpanded(bool expanded); // use QPropertyTree::expandRow
|
||||
void setExpandedRecursive(QPropertyTree* tree, bool expanded);
|
||||
|
||||
void setMatchFilter(bool matchFilter) { matchFilter_ = matchFilter; }
|
||||
bool matchFilter() const { return matchFilter_; }
|
||||
|
||||
void setBelongsToFilteredRow(bool belongs) { belongsToFilteredRow_ = belongs; }
|
||||
bool belongsToFilteredRow() const { return belongsToFilteredRow_; }
|
||||
|
||||
bool visible(const QPropertyTree* tree) const;
|
||||
bool hasVisibleChildren(const QPropertyTree* tree, bool internalCall = false) const;
|
||||
|
||||
const PropertyRow* hit(const QPropertyTree* tree, QPoint point) const;
|
||||
PropertyRow* hit(const QPropertyTree* tree, QPoint point);
|
||||
PropertyRow* parent() { return parent_; }
|
||||
const PropertyRow* parent() const{ return parent_; }
|
||||
void setParent(PropertyRow* row) { parent_ = row; }
|
||||
bool isRoot() const { return !parent_; }
|
||||
int level() const;
|
||||
|
||||
void add(PropertyRow* row);
|
||||
void addAfter(PropertyRow* row, PropertyRow* after);
|
||||
void addBefore(PropertyRow* row, PropertyRow* before);
|
||||
|
||||
template<class Op> bool scanChildren(Op& op);
|
||||
template<class Op> bool scanChildren(Op& op, QPropertyTree* tree);
|
||||
template<class Op> bool scanChildrenReverse(Op& op, QPropertyTree* tree);
|
||||
template<class Op> bool scanChildrenBottomUp(Op& op, QPropertyTree* tree);
|
||||
|
||||
PropertyRow* childByIndex(int index);
|
||||
const PropertyRow* childByIndex(int index) const;
|
||||
int childIndex(const PropertyRow* row) const;
|
||||
bool isChildOf(const PropertyRow* row) const;
|
||||
|
||||
bool empty() const{ return children_.empty(); }
|
||||
iterator find(PropertyRow* row) { return std::find(children_.begin(), children_.end(), row); }
|
||||
PropertyRow* findFromIndex(int* outIndex, const char* name, const char* typeName, int startIndex) const;
|
||||
PropertyRow* findByAddress(const void* handle);
|
||||
virtual const void* searchHandle() const;
|
||||
iterator begin() { return children_.begin(); }
|
||||
iterator end() { return children_.end(); }
|
||||
const_iterator begin() const{ return children_.begin(); }
|
||||
const_iterator end() const{ return children_.end(); }
|
||||
std::size_t count() const{ return children_.size(); }
|
||||
iterator erase(iterator it){ return children_.erase(it); }
|
||||
void clear(){ children_.clear(); }
|
||||
void erase(PropertyRow* row);
|
||||
void swapChildren(PropertyRow* row, PropertyTreeModel* model);
|
||||
|
||||
void assignRowState(const PropertyRow& row, bool recurse);
|
||||
void assignRowProperties(PropertyRow* row);
|
||||
void replaceAndPreserveState(PropertyRow* oldRow, PropertyRow* newRow, PropertyTreeModel* model);
|
||||
|
||||
const char* name() const{ return name_; }
|
||||
void setName(const char* name) { name_ = name; }
|
||||
const char* label() const { return label_; }
|
||||
const char* labelUndecorated() const { return labelUndecorated_; }
|
||||
void setLabel(const char* label);
|
||||
void setLabelChanged();
|
||||
void setTooltip(const char* tooltip);
|
||||
bool setValidatorEntry(int index, int count);
|
||||
int validatorCount() const{ return validatorCount_; }
|
||||
int validatorIndex() const{ return validatorIndex_; }
|
||||
void resetValidatorIcons();
|
||||
void addValidatorIcons(bool hasWarnings, bool hasErrors);
|
||||
const char* tooltip() const { return tooltip_; }
|
||||
void setLayoutChanged();
|
||||
void setLabelChangedToChildren();
|
||||
void setLayoutChangedToChildren();
|
||||
void setHideChildren(bool hideChildren) { hideChildren_ = hideChildren; }
|
||||
bool hideChildren() const { return hideChildren_; }
|
||||
void updateLabel(const QPropertyTree* tree, int index, bool parentHidesNonInlineChildren);
|
||||
void updateTextSizeInitial(const QPropertyTree* tree, int index, bool force);
|
||||
virtual void labelChanged() {}
|
||||
void parseControlCodes(const QPropertyTree* tree, const char* label, bool changeLabel);
|
||||
const char* typeName() const{ return typeName_; }
|
||||
virtual const char* typeNameForFilter(QPropertyTree* tree) const;
|
||||
void setTypeName(const char* typeName) { typeName_ = typeName; }
|
||||
const char* rowText(char* containerLabelBuffer, size_t bufsiz, const QPropertyTree* tree, int rowIndex) const;
|
||||
|
||||
PropertyRow* findSelected();
|
||||
PropertyRow* find(const char* name, const char* nameAlt, const char* typeName);
|
||||
const PropertyRow* find(const char* name, const char* nameAlt, const char* typeName) const;
|
||||
void intersect(const PropertyRow* row);
|
||||
|
||||
int verticalIndex(QPropertyTree* tree, PropertyRow* row);
|
||||
PropertyRow* rowByVerticalIndex(QPropertyTree* tree, int index);
|
||||
int horizontalIndex(QPropertyTree* tree, PropertyRow* row);
|
||||
PropertyRow* rowByHorizontalIndex(QPropertyTree* tree, int index);
|
||||
|
||||
virtual bool assignToPrimitive([[maybe_unused]] void* object, [[maybe_unused]] size_t size) const{ return false; }
|
||||
virtual bool assignTo([[maybe_unused]] const Serialization::SStruct& ser) const{ return false; }
|
||||
virtual bool assignToByPointer(void* instance, const Serialization::TypeID& type) const{ return assignTo(Serialization::SStruct(type, instance, type.sizeOf(), 0)); }
|
||||
virtual void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) { serializer_ = ser; }
|
||||
virtual void handleChildrenChange() {}
|
||||
virtual string valueAsString() const;
|
||||
virtual wstring valueAsWString() const;
|
||||
|
||||
int height() const{ return size_.y(); }
|
||||
|
||||
virtual int widgetSizeMin(const QPropertyTree*) const { return userWidgetSize() >= 0 ? userWidgetSize() : 0; }
|
||||
virtual int floorHeight() const{ return 0; }
|
||||
|
||||
void calcPulledRows(int* minTextSize, int* freePulledChildren, int* minimalWidth, const QPropertyTree* tree, int index);
|
||||
void calculateMinimalSize(const QPropertyTree* tree, int posX, int availableWidth, bool force, int* extraSizeRemainder, int* _extraSize, int index);
|
||||
void setTextSize(const QPropertyTree* tree, int rowIndex, float multiplier);
|
||||
void calculateTotalSizes(int* minTextSize);
|
||||
void adjustVerticalPosition(const QPropertyTree* tree, int& totalHeight);
|
||||
|
||||
virtual bool isWidgetFixed() const{ return userFixedWidget_ || (widgetPlacement() != WIDGET_VALUE && widgetPlacement() != WIDGET_INSTEAD_OF_TEXT); }
|
||||
|
||||
virtual WidgetPlacement widgetPlacement() const{ return WIDGET_NONE; }
|
||||
|
||||
QRect rect() const{ return QRect(pos_.x(), pos_.y(), size_.x(), size_.y()); }
|
||||
QRect rectIncludingChildren(const QPropertyTree* tree) const;
|
||||
QRect textRect(const QPropertyTree* tree) const;
|
||||
QRect widgetRect(const QPropertyTree* tree) const;
|
||||
QRect plusRect(const QPropertyTree* tree) const;
|
||||
QRect floorRect(const QPropertyTree* tree) const;
|
||||
QRect validatorRect(const QPropertyTree* tree) const;
|
||||
QRect validatorWarningIconRect(const QPropertyTree* tree) const;
|
||||
QRect validatorErrorIconRect(const QPropertyTree* tree) const;
|
||||
void adjustHoveredRect(QRect& hoveredRect);
|
||||
int heightIncludingChildren() const{ return heightIncludingChildren_; }
|
||||
const QFont* rowFont(const QPropertyTree* tree) const;
|
||||
|
||||
void drawRow(QPainter& painter, const QPropertyTree* tree, int rowIndex, bool selectionPass);
|
||||
void drawPlus(QPainter& p, const QPropertyTree* tree, const QRect& rect, bool expanded, bool selected, bool grayed) const;
|
||||
void drawStaticText(QPainter& p, const QRect& widgetRect);
|
||||
|
||||
virtual void redraw(const PropertyDrawContext& context);
|
||||
virtual PropertyRowWidget* createWidget([[maybe_unused]] QPropertyTree* tree) { return 0; }
|
||||
|
||||
virtual bool isContainer() const{ return false; }
|
||||
virtual bool isPointer() const{ return false; }
|
||||
virtual bool isObject() const{ return false; }
|
||||
|
||||
virtual bool isLeaf() const{ return false; }
|
||||
virtual void closeNonLeaf([[maybe_unused]] const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) {}
|
||||
virtual bool isStatic() const{ return pulledContainer_ == 0; }
|
||||
virtual bool isSelectable() const{ return (!userReadOnly() && !userReadOnlyRecurse()) || (!pulledUp() && !pulledBefore()); }
|
||||
virtual bool activateOnAdd() const{ return false; }
|
||||
virtual bool inlineInShortArrays() const{ return false; }
|
||||
|
||||
bool canBeToggled(const QPropertyTree* tree) const;
|
||||
bool canBeDragged() const;
|
||||
bool canBeDroppedOn(const PropertyRow* parentRow, const PropertyRow* beforeChild, const QPropertyTree* tree) const;
|
||||
void dropInto(PropertyRow* parentRow, PropertyRow* cursorRow, QPropertyTree* tree, bool before);
|
||||
virtual bool getHoverInfo(PropertyHoverInfo* hit, [[maybe_unused]] const QPoint& cursorPos, [[maybe_unused]] const QPropertyTree* tree) const {
|
||||
hit->toolTip = QString::fromUtf8(tooltip_);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool onActivate(const PropertyActivationEvent& e);
|
||||
virtual bool processesKey(QPropertyTree* tree, const QKeyEvent* ev); // returns true if it wants to process key events; otherwise, they will get processed by shortcuts in some cases, like delete
|
||||
virtual bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev);
|
||||
virtual bool onMouseDown([[maybe_unused]] QPropertyTree* tree, [[maybe_unused]] QPoint point, [[maybe_unused]] bool& changed) { return false; }
|
||||
virtual void onMouseDrag([[maybe_unused]] const PropertyDragEvent& e) {}
|
||||
virtual void onMouseStill([[maybe_unused]] const PropertyDragEvent& e) {}
|
||||
virtual void onMouseUp([[maybe_unused]] QPropertyTree* tree, [[maybe_unused]] QPoint point) {}
|
||||
// "drag check" allows you to "paint" with the mouse through checkboxes to set all values at once
|
||||
virtual DragCheckBegin onMouseDragCheckBegin() { return DRAG_CHECK_IGNORE; }
|
||||
virtual bool onMouseDragCheck([[maybe_unused]] QPropertyTree* tree, [[maybe_unused]] bool value) { return false; }
|
||||
virtual bool onContextMenu(QMenu &menu, QPropertyTree* tree);
|
||||
virtual ContainerMenuHandler* createMenuHandler(QPropertyTree* tree, PropertyRowContainer* container);
|
||||
|
||||
virtual bool isFullRow(const QPropertyTree* tree) const;
|
||||
|
||||
// User states.
|
||||
// Assigned using control codes (characters in the beginning of label)
|
||||
// fixed widget doesn't expand automatically to occupy all available place
|
||||
bool userFixedWidget() const{ return userFixedWidget_; }
|
||||
bool userFullRow() const { return userFullRow_; }
|
||||
void setUserReadOnly(bool userReadOnly) { userReadOnly_ = userReadOnly; }
|
||||
virtual bool userReadOnly() const { return userReadOnly_; }
|
||||
void propagateFlagsTopToBottom();
|
||||
virtual bool userReadOnlyRecurse() const { return userReadOnlyRecurse_; }
|
||||
bool userWidgetToContent() const { return userWidgetToContent_; }
|
||||
int userWidgetSize() const{ return userWidgetSize_; }
|
||||
bool userNonCopyable() const { return userNonCopyable_; }
|
||||
|
||||
// multiValue is used to edit properties of multiple objects simulateneously
|
||||
bool multiValue() const { return multiValue_; }
|
||||
void setMultiValue(bool multiValue) { multiValue_ = multiValue; }
|
||||
|
||||
// pulledRow - is the one that is pulled up to the parents row
|
||||
// (created with ^ in the beginning of label)
|
||||
bool pulledUp() const { return pulledUp_; }
|
||||
bool pulledBefore() const { return pulledBefore_; }
|
||||
bool hasPulled() const { return hasPulled_; }
|
||||
bool packedAfterPreviousRow() const { return packedAfterPreviousRow_; }
|
||||
bool pulledSelected() const;
|
||||
PropertyRow* nonPulledParent();
|
||||
void setPulledContainer(PropertyRow* container){ pulledContainer_ = container; }
|
||||
PropertyRow* pulledContainer() { return pulledContainer_; }
|
||||
const PropertyRow* pulledContainer() const{ return pulledContainer_; }
|
||||
|
||||
Serialization::SharedPtr<PropertyRow> clone(ConstStringList* constStrings) const;
|
||||
|
||||
Serialization::SStruct serializer() const{ return serializer_; }
|
||||
virtual Serialization::TypeID typeId() const{ return serializer_.type(); }
|
||||
void setSerializer(const Serialization::SStruct& ser) { serializer_ = ser; }
|
||||
virtual void serializeValue([[maybe_unused]] Serialization::IArchive& ar) {}
|
||||
void setCallback(Serialization::ICallback* callback);
|
||||
Serialization::ICallback* callback() { return callback_; }
|
||||
virtual void Serialize(Serialization::IArchive& ar);
|
||||
|
||||
static void setConstStrings(ConstStringList* constStrings){ constStrings_ = constStrings; }
|
||||
|
||||
protected:
|
||||
void init(const char* name, const char* nameAlt, const char* typeName);
|
||||
PropertyRow* findChildFromDescendant(PropertyRow* row) const;
|
||||
|
||||
virtual void overrideTextColor([[maybe_unused]] QColor& textColor) {}
|
||||
|
||||
const char* name_;
|
||||
const char* label_;
|
||||
const char* labelUndecorated_;
|
||||
const char* typeName_;
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
Serialization::SStruct serializer_;
|
||||
PropertyRow* parent_;
|
||||
Serialization::ICallback* callback_;
|
||||
const char* tooltip_;
|
||||
Rows children_;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
unsigned int textHash_;
|
||||
|
||||
// do we really need QPoint here?
|
||||
QPoint pos_;
|
||||
QPoint size_;
|
||||
short int textPos_;
|
||||
short int textSizeInitial_;
|
||||
short int textSize_;
|
||||
short int widgetPos_; // widget == icon!
|
||||
short int widgetSize_;
|
||||
short int userWidgetSize_;
|
||||
unsigned short heightIncludingChildren_;
|
||||
unsigned short validatorIndex_;
|
||||
unsigned short validatorsHeight_;
|
||||
unsigned char validatorCount_;
|
||||
unsigned char plusSize_;
|
||||
bool visible_ : 1;
|
||||
bool matchFilter_ : 1;
|
||||
bool belongsToFilteredRow_ : 1;
|
||||
bool expanded_ : 1;
|
||||
bool selected_ : 1;
|
||||
bool labelChanged_ : 1;
|
||||
bool layoutChanged_ : 1;
|
||||
bool userReadOnly_ : 1;
|
||||
bool userReadOnlyRecurse_ : 1;
|
||||
bool userFixedWidget_ : 1;
|
||||
bool userFullRow_ : 1;
|
||||
bool userPackCheckboxes_ : 1;
|
||||
bool userWidgetToContent_ : 1;
|
||||
bool pulledUp_ : 1;
|
||||
bool pulledBefore_ : 1;
|
||||
bool packedAfterPreviousRow_ : 1;
|
||||
bool hasPulled_ : 1;
|
||||
bool multiValue_ : 1;
|
||||
bool hideChildren_ : 1;
|
||||
bool validatorHasErrors_ : 1;
|
||||
bool validatorHasWarnings_ : 1;
|
||||
bool userNonCopyable_ : 1;
|
||||
enum class FontWeight
|
||||
{
|
||||
Undefined,
|
||||
Bold,
|
||||
Regular
|
||||
};
|
||||
FontWeight fontWeight_;
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
Serialization::SharedPtr<PropertyRow> pulledContainer_;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
static ConstStringList* constStrings_;
|
||||
friend class PropertyOArchive;
|
||||
friend class PropertyIArchive;
|
||||
};
|
||||
|
||||
inline unsigned int calculateHash(const char* str, unsigned hash = 5381)
|
||||
{
|
||||
while(*str)
|
||||
hash = hash * 33 + (unsigned char)*str++;
|
||||
return hash;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline unsigned int calculateHash(const T& t, unsigned hash = 5381)
|
||||
{
|
||||
for (int i = 0; i < sizeof(T); i++)
|
||||
hash = hash * 33 + ((unsigned char*)&t)[i];
|
||||
return hash;
|
||||
}
|
||||
|
||||
struct RowWidthCache
|
||||
{
|
||||
unsigned int valueHash;
|
||||
int width;
|
||||
|
||||
RowWidthCache() : valueHash(0), width(-1) {}
|
||||
int getOrUpdate(const QPropertyTree* tree, const PropertyRow* rowForValue, int extraSpace);
|
||||
};
|
||||
|
||||
typedef vector<Serialization::SharedPtr<PropertyRow> > PropertyRows;
|
||||
|
||||
template<bool value>
|
||||
struct StaticBool{
|
||||
enum { Value = value };
|
||||
};
|
||||
|
||||
struct LessStrCmp
|
||||
{
|
||||
bool operator()(const char* a, const char* b) const {
|
||||
return strcmp(a, b) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef Factory<const char*, PropertyRow, LessStrCmp> PropertyRowFactory;
|
||||
|
||||
template<class Op>
|
||||
bool PropertyRow::scanChildren(Op& op)
|
||||
{
|
||||
Rows::iterator it;
|
||||
|
||||
for(it = children_.begin(); it != children_.end(); ++it){
|
||||
ScanResult result = op(*it);
|
||||
if(result == SCAN_FINISHED)
|
||||
return false;
|
||||
if(result == SCAN_CHILDREN || result == SCAN_CHILDREN_SIBLINGS){
|
||||
if(!(*it)->scanChildren(op))
|
||||
return false;
|
||||
if(result == SCAN_CHILDREN)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class Op>
|
||||
bool PropertyRow::scanChildren(Op& op, QPropertyTree* tree)
|
||||
{
|
||||
int numChildren = int(children_.size());
|
||||
for(int index = 0; index < numChildren; ++index){
|
||||
PropertyRow* child = children_[index];
|
||||
ScanResult result = op(child, tree, index);
|
||||
if(result == SCAN_FINISHED)
|
||||
return false;
|
||||
if(result == SCAN_CHILDREN || result == SCAN_CHILDREN_SIBLINGS){
|
||||
if(!child->scanChildren(op, tree))
|
||||
return false;
|
||||
if(result == SCAN_CHILDREN)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class Op>
|
||||
bool PropertyRow::scanChildrenReverse(Op& op, QPropertyTree* tree)
|
||||
{
|
||||
int numChildren = (int)children_.size();
|
||||
for(int index = numChildren - 1; index >= 0; --index){
|
||||
PropertyRow* child = children_[index];
|
||||
ScanResult result = op(child, tree, index);
|
||||
if(result == SCAN_FINISHED)
|
||||
return false;
|
||||
if(result == SCAN_CHILDREN || result == SCAN_CHILDREN_SIBLINGS){
|
||||
if(!child->scanChildrenReverse(op, tree))
|
||||
return false;
|
||||
if(result == SCAN_CHILDREN)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class Op>
|
||||
bool PropertyRow::scanChildrenBottomUp(Op& op, QPropertyTree* tree)
|
||||
{
|
||||
size_t numChildren = children_.size();
|
||||
for(size_t i = 0; i < numChildren; ++i)
|
||||
{
|
||||
PropertyRow* child = children_[i];
|
||||
if(!child->scanChildrenBottomUp(op, tree))
|
||||
return false;
|
||||
ScanResult result = op(child, tree);
|
||||
if(result == SCAN_FINISHED)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
EDITOR_COMMON_API PropertyRowFactory& GlobalPropertyRowFactory();
|
||||
EDITOR_COMMON_API Serialization::ClassFactory<PropertyRow>& GlobalPropertyRowClassFactory();
|
||||
|
||||
struct PropertyRowPtrSerializer : Serialization::SharedPtrSerializer<PropertyRow>
|
||||
{
|
||||
PropertyRowPtrSerializer(Serialization::SharedPtr<PropertyRow>& ptr) : SharedPtrSerializer(ptr) {}
|
||||
Serialization::ClassFactory<PropertyRow>* factory() const override { return &GlobalPropertyRowClassFactory(); }
|
||||
};
|
||||
|
||||
inline bool Serialize(Serialization::IArchive& ar, Serialization::SharedPtr<PropertyRow>& ptr, const char* name, const char* label)
|
||||
{
|
||||
PropertyRowPtrSerializer serializer(ptr);
|
||||
return ar(static_cast<Serialization::IPointer&>(serializer), name, label);
|
||||
}
|
||||
|
||||
#define REGISTER_PROPERTY_ROW(DataType, RowType) \
|
||||
PropertyRow* _Factory_For_##RowType() {return new RowType; }; \
|
||||
REGISTER_IN_FACTORY(PropertyRowFactory, Serialization::TypeID::get<DataType>().name(), RowType, _Factory_For_##RowType); \
|
||||
SERIALIZATION_CLASS_NAME_FOR_FACTORY(GlobalPropertyRowClassFactory(), PropertyRow, RowType, #DataType, #DataType);
|
||||
|
||||
// Exposes the necessary class factories to extend the property tree
|
||||
// Exposes the necessary class factories to extend the property tree
|
||||
EDITOR_COMMON_API Serialization::ClassFactory<PropertyRow>& GetPropertyRowClassFactory();
|
||||
EDITOR_COMMON_API PropertyRowFactory& GetPropertyRowFactory();
|
||||
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include <QIcon>
|
||||
|
||||
#include "Serialization/ClassFactory.h"
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "PropertyRowImpl.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "Serialization.h"
|
||||
#include "Color.h"
|
||||
#include "Unicode.h"
|
||||
#include "Serialization/Decorators/ActionButton.h"
|
||||
|
||||
using Serialization::IActionButton;
|
||||
using Serialization::IActionButtonPtr;
|
||||
|
||||
class PropertyRowActionButton
|
||||
: public PropertyRow
|
||||
{
|
||||
public:
|
||||
PropertyRowActionButton()
|
||||
: underMouse_()
|
||||
, pressed_()
|
||||
, minimalWidth_() {}
|
||||
bool isLeaf() const override { return true; }
|
||||
bool isStatic() const override { return false; }
|
||||
bool isSelectable() const override { return true; }
|
||||
|
||||
bool onActivate(const PropertyActivationEvent& e) override
|
||||
{
|
||||
if (e.reason == PropertyActivationEvent::REASON_KEYBOARD)
|
||||
{
|
||||
if (value_)
|
||||
{
|
||||
value_->Callback();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool onMouseDown(QPropertyTree* tree, QPoint point, [[maybe_unused]] bool& changed) override
|
||||
{
|
||||
if (userReadOnly())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (widgetRect(tree).contains(point))
|
||||
{
|
||||
underMouse_ = true;
|
||||
pressed_ = true;
|
||||
tree->update();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void onMouseDrag(const PropertyDragEvent& e) override
|
||||
{
|
||||
if (userReadOnly())
|
||||
{
|
||||
return;
|
||||
}
|
||||
bool underMouse = widgetRect(e.tree).contains(e.pos);
|
||||
if (underMouse != underMouse_)
|
||||
{
|
||||
underMouse_ = underMouse;
|
||||
e.tree->update();
|
||||
}
|
||||
}
|
||||
|
||||
void onMouseUp(QPropertyTree* tree, QPoint point) override
|
||||
{
|
||||
if (userReadOnly())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (widgetRect(tree).contains(point))
|
||||
{
|
||||
pressed_ = false;
|
||||
if (value_)
|
||||
{
|
||||
value_->Callback();
|
||||
}
|
||||
tree->update();
|
||||
}
|
||||
}
|
||||
void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override
|
||||
{
|
||||
value_ = static_cast<IActionButton*>(ser.pointer())->Clone();
|
||||
const char* icon = value_->Icon();
|
||||
icon_ = icon && icon[0] ? QIcon() : QIcon(QString::fromLocal8Bit(icon));
|
||||
}
|
||||
bool assignTo([[maybe_unused]] const Serialization::SStruct& ser) const override { return true; }
|
||||
wstring valueAsWString() const override { return L""; }
|
||||
WidgetPlacement widgetPlacement() const override { return WIDGET_INSTEAD_OF_TEXT; }
|
||||
void serializeValue([[maybe_unused]] Serialization::IArchive& ar) override { }
|
||||
|
||||
int widgetSizeMin(const QPropertyTree* tree) const override
|
||||
{
|
||||
if (minimalWidth_ == 0)
|
||||
{
|
||||
QFontMetrics fm(tree->font());
|
||||
minimalWidth_ = (int)fm.horizontalAdvance(QString::fromLocal8Bit(labelUndecorated())) + 6 + (icon_.isNull() ? 0 : 18);
|
||||
}
|
||||
return minimalWidth_;
|
||||
}
|
||||
|
||||
void redraw(const PropertyDrawContext& context)
|
||||
{
|
||||
QRect rect = context.widgetRect.adjusted(-1, -1, 1, 1);
|
||||
bool pressed = pressed_ && underMouse_;
|
||||
|
||||
wstring text = toWideChar(labelUndecorated());
|
||||
if (icon_.isNull())
|
||||
{
|
||||
int buttonFlags = BUTTON_CENTER;
|
||||
if (pressed)
|
||||
{
|
||||
buttonFlags |= BUTTON_PRESSED;
|
||||
}
|
||||
if (selected())
|
||||
{
|
||||
buttonFlags |= BUTTON_FOCUSED;
|
||||
}
|
||||
if (userReadOnly())
|
||||
{
|
||||
buttonFlags |= BUTTON_DISABLED;
|
||||
}
|
||||
context.drawButton(rect, text.c_str(), buttonFlags, &context.tree->font());
|
||||
}
|
||||
else
|
||||
{
|
||||
context.drawButtonWithIcon(icon_, rect, text.c_str(), selected(), pressed, selected(), !userReadOnly(), true, &context.tree->font());
|
||||
}
|
||||
}
|
||||
bool isFullRow(const QPropertyTree* tree) const override
|
||||
{
|
||||
if (PropertyRow::isFullRow(tree))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return !userFixedWidget();
|
||||
}
|
||||
protected:
|
||||
mutable int minimalWidth_;
|
||||
bool underMouse_;
|
||||
bool pressed_;
|
||||
QIcon icon_;
|
||||
IActionButtonPtr value_;
|
||||
};
|
||||
|
||||
REGISTER_PROPERTY_ROW(IActionButton, PropertyRowActionButton);
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "PropertyRowBool.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "Serialization/ClassFactory.h"
|
||||
#include "Serialization.h"
|
||||
#include <QKeyEvent>
|
||||
|
||||
SERIALIZATION_CLASS_NAME(PropertyRow, PropertyRowBool, "PropertyRowBool", "bool");
|
||||
|
||||
PropertyRowBool::PropertyRowBool()
|
||||
: value_(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool PropertyRowBool::assignToPrimitive(void* object, [[maybe_unused]] size_t size) const
|
||||
{
|
||||
YASLI_ASSERT(size == sizeof(bool));
|
||||
*reinterpret_cast<bool*>(object) = value_;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyRowBool::assignToByPointer(void* instance, const Serialization::TypeID& type) const
|
||||
{
|
||||
return assignToPrimitive(instance, type.sizeOf());
|
||||
}
|
||||
|
||||
void PropertyRowBool::redraw(const PropertyDrawContext& context)
|
||||
{
|
||||
context.drawCheck(widgetRect(context.tree), userReadOnly(), multiValue() ? CHECK_IN_BETWEEN : (value_ ? CHECK_SET : CHECK_NOT_SET));
|
||||
}
|
||||
|
||||
bool PropertyRowBool::processesKey(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (QKeySequence(ev->key()) == QKeySequence(Qt::Key_Space))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return PropertyRow::processesKey(tree, ev);
|
||||
}
|
||||
|
||||
bool PropertyRowBool::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (QKeySequence(ev->key()) == QKeySequence(Qt::Key_Space))
|
||||
{
|
||||
PropertyActivationEvent e;
|
||||
e.tree = tree;
|
||||
e.reason = e.REASON_KEYBOARD;
|
||||
onActivate(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
return PropertyRow::onKeyDown(tree, ev);
|
||||
}
|
||||
|
||||
bool PropertyRowBool::onActivate(const PropertyActivationEvent& e)
|
||||
{
|
||||
if (e.reason != e.REASON_RELEASE)
|
||||
{
|
||||
if (!this->userReadOnly())
|
||||
{
|
||||
e.tree->model()->rowAboutToBeChanged(this);
|
||||
value_ = !value_;
|
||||
e.tree->model()->rowChanged(this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DragCheckBegin PropertyRowBool::onMouseDragCheckBegin()
|
||||
{
|
||||
if (userReadOnly())
|
||||
{
|
||||
return DRAG_CHECK_IGNORE;
|
||||
}
|
||||
return value_ ? DRAG_CHECK_UNSET : DRAG_CHECK_SET;
|
||||
}
|
||||
|
||||
bool PropertyRowBool::onMouseDragCheck(QPropertyTree* tree, bool value)
|
||||
{
|
||||
if (value_ != value)
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
value_ = value;
|
||||
tree->model()->rowChanged(this);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PropertyRowBool::serializeValue(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(value_, "value", "Value");
|
||||
}
|
||||
|
||||
int PropertyRowBool::widgetSizeMin(const QPropertyTree* tree) const
|
||||
{
|
||||
return aznumeric_cast<int>(tree->_defaultRowHeight() * 0.9f);
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWBOOL_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWBOOL_H
|
||||
#pragma once
|
||||
|
||||
#include "PropertyRow.h"
|
||||
#include "Unicode.h"
|
||||
|
||||
class PropertyRowBool
|
||||
: public PropertyRow
|
||||
{
|
||||
public:
|
||||
PropertyRowBool();
|
||||
bool assignToPrimitive(void* val, size_t size) const override;
|
||||
bool assignToByPointer(void* instance, const Serialization::TypeID& type) const;
|
||||
void setValue(bool value, const void* handle, [[maybe_unused]] const Serialization::TypeID& typeId) { value_ = value; serializer_.setPointer((void*)handle); serializer_.setType(Serialization::TypeID::get<bool>()); }
|
||||
|
||||
void redraw(const PropertyDrawContext& context);
|
||||
bool isLeaf() const{ return true; }
|
||||
bool isStatic() const{ return false; }
|
||||
|
||||
bool onActivate(const PropertyActivationEvent& e);
|
||||
DragCheckBegin onMouseDragCheckBegin() override;
|
||||
bool onMouseDragCheck(QPropertyTree* tree, bool value) override;
|
||||
wstring valueAsWString() const{ return value_ ? L"true" : L"false"; }
|
||||
string valueAsString() const{ return value_ ? "true" : "false"; }
|
||||
WidgetPlacement widgetPlacement() const{ return WIDGET_ICON; }
|
||||
void serializeValue(Serialization::IArchive& ar);
|
||||
int widgetSizeMin(const QPropertyTree* tree) const override;
|
||||
bool processesKey(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
protected:
|
||||
bool value_;
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWBOOL_H
|
||||
@@ -1,241 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "PropertyRowColor.h"
|
||||
#include "Serialization/ClassFactory.h"
|
||||
#include <Cry_Color.h>
|
||||
#include <QMenu>
|
||||
#include <QFileDialog>
|
||||
#include <QPainter>
|
||||
|
||||
#include <AzQtComponents/Components/Widgets/ColorPicker.h>
|
||||
#include <AzQtComponents/Utilities/Conversions.h>
|
||||
|
||||
using Serialization::Vec3AsColor;
|
||||
typedef SerializableColor_tpl<unsigned char> SerializableColorB;
|
||||
typedef SerializableColor_tpl<float> SerializableColorF;
|
||||
|
||||
QColor ToQColor(const ColorB& v)
|
||||
{
|
||||
return QColor(v.r, v.g, v.b, v.a);
|
||||
}
|
||||
|
||||
void FromQColor(SerializableColorB& vColor, QColor color)
|
||||
{
|
||||
vColor.r = color.red();
|
||||
vColor.g = color.green();
|
||||
vColor.b = color.blue();
|
||||
vColor.a = color.alpha();
|
||||
}
|
||||
|
||||
|
||||
QColor ToQColor(const Vec3AsColor& v)
|
||||
{
|
||||
return QColor(int(v.v.x * 255.0f), int(v.v.y * 255.0f), int(v.v.z * 255.0f));
|
||||
}
|
||||
|
||||
void FromQColor(Vec3AsColor& vColor, QColor color)
|
||||
{
|
||||
vColor.v.x = color.red() / 255.0f;
|
||||
vColor.v.y = color.green() / 255.0f;
|
||||
vColor.v.z = color.blue() / 255.0f;
|
||||
}
|
||||
|
||||
QColor ToQColor(const SerializableColorF& v)
|
||||
{
|
||||
return QColor::fromRgbF(v.r, v.g, v.b, v.a);
|
||||
}
|
||||
|
||||
void FromQColor(SerializableColorF& vColor, QColor color)
|
||||
{
|
||||
vColor.r = aznumeric_cast<float>(color.redF());
|
||||
vColor.g = aznumeric_cast<float>(color.greenF());
|
||||
vColor.b = aznumeric_cast<float>(color.blueF());
|
||||
vColor.a = aznumeric_cast<float>(color.alphaF());
|
||||
}
|
||||
|
||||
|
||||
template <class ColorClass>
|
||||
bool PropertyRowColor<ColorClass>::pickColor(QPropertyTree* tree)
|
||||
{
|
||||
const AZ::Color initialColor = AzQtComponents::fromQColor(color_);
|
||||
const AZ::Color color = AzQtComponents::ColorPicker::getColor(AzQtComponents::ColorPicker::Configuration::RGB, initialColor, QObject::tr("Select Color"));
|
||||
|
||||
if (color != initialColor)
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
color_.setRed(color.GetR8());
|
||||
color_.setGreen(color.GetG8());
|
||||
color_.setBlue(color.GetB8());
|
||||
colorChanged_ = true;
|
||||
tree->model()->rowChanged(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class ColorClass>
|
||||
bool PropertyRowColor<ColorClass>::onActivate(const PropertyActivationEvent& e)
|
||||
{
|
||||
return pickColor(e.tree);
|
||||
}
|
||||
|
||||
template <class ColorClass>
|
||||
void PropertyRowColor<ColorClass>::setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] IArchive& ar)
|
||||
{
|
||||
color_ = ToQColor(*(ColorClass*)ser.pointer());
|
||||
colorChanged_ = false;
|
||||
}
|
||||
|
||||
template <class ColorClass>
|
||||
bool PropertyRowColor<ColorClass>::assignTo(const Serialization::SStruct& ser) const
|
||||
{
|
||||
FromQColor(*((ColorClass*)ser.pointer()), color_);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class ColorClass>
|
||||
string PropertyRowColor<ColorClass>::valueAsString() const
|
||||
{
|
||||
char buf[64];
|
||||
sprintf_s(buf, "%d %d %d", (int)color_.red(), (int)color_.green(), (int)color_.blue());
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
template <class ColorClass>
|
||||
bool PropertyRowColor<ColorClass>::onContextMenu(QMenu& menu, QPropertyTree* tree)
|
||||
{
|
||||
Serialization::SharedPtr<PropertyRowColor> selfPointer(this);
|
||||
ColorMenuHandler* handler = new ColorMenuHandler(tree, this);
|
||||
menu.addAction("Pick Color", handler, SLOT(onMenuPickColor()));
|
||||
tree->addMenuHandler(handler);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class ColorClass>
|
||||
void PropertyRowColor<ColorClass>::redraw(const PropertyDrawContext& context)
|
||||
{
|
||||
static QImage checkboardPattern;
|
||||
if (checkboardPattern.isNull())
|
||||
{
|
||||
int size = 12;
|
||||
static vector<int> pixels(size * size);
|
||||
for (int i = 0; i < pixels.size(); ++i)
|
||||
{
|
||||
pixels[i] = ((i / size) / (size / 2) + (i % size) / (size / 2)) % 2 ? 0xffffffff : 0x000000ff;
|
||||
}
|
||||
checkboardPattern = QImage((unsigned char*)pixels.data(), size, size, size * 4, QImage::Format_RGBA8888);
|
||||
}
|
||||
|
||||
QRect r = context.widgetRect.adjusted(0, 0, 0, -1);
|
||||
|
||||
context.painter->save();
|
||||
context.painter->setPen(QPen(Qt::NoPen));
|
||||
context.painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
context.painter->setBrush(context.tree->palette().color(QPalette::Dark));
|
||||
context.painter->setPen(Qt::NoPen);
|
||||
context.painter->drawRoundedRect(r, 2, 2);
|
||||
r = r.adjusted(1, 1, -1, -1);
|
||||
QRect cr = r.adjusted(0, 0, -r.width() / 2, 0);
|
||||
context.painter->setBrushOrigin(cr.topRight() + QPoint(1, 0));
|
||||
context.painter->setBrush(QBrush(checkboardPattern));
|
||||
|
||||
context.painter->setRenderHint(QPainter::Antialiasing, false);
|
||||
context.painter->drawRoundedRect(r, 2, 2);
|
||||
|
||||
context.painter->setPen(QPen(Qt::NoPen));
|
||||
context.painter->setClipRect(cr);
|
||||
context.painter->setBrush(QBrush(color_));
|
||||
context.painter->drawRoundedRect(r, 2, 2);
|
||||
|
||||
cr = r.adjusted(r.width() / 2, 0, 0, 0);
|
||||
context.painter->setClipRect(cr);
|
||||
context.painter->setBrush(QBrush(QColor(color_.red(), color_.green(), color_.blue(), 255)));
|
||||
context.painter->drawRoundedRect(r, 2, 2);
|
||||
context.painter->restore();
|
||||
}
|
||||
|
||||
template <class ColorClass>
|
||||
void PropertyRowColor<ColorClass>::closeNonLeaf(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar)
|
||||
{
|
||||
color_ = ToQColor(*(ColorClass*)ser.pointer());
|
||||
}
|
||||
|
||||
static int componentFromRowValue(const char* str, ColorB*)
|
||||
{
|
||||
return clamp_tpl(atoi(str), 0, 255);
|
||||
}
|
||||
|
||||
static int componentFromRowValue(const char* str, ColorF*)
|
||||
{
|
||||
return clamp_tpl(int(atof(str) * 255.0f + 0.5f), 0, 255);
|
||||
}
|
||||
|
||||
static int componentFromRowValue(const char* str, Vec3AsColor*)
|
||||
{
|
||||
return clamp_tpl(int(atof(str) * 255.0f + 0.5f), 0, 255);
|
||||
}
|
||||
|
||||
template<class ColorClass>
|
||||
void PropertyRowColor<ColorClass>::handleChildrenChange()
|
||||
{
|
||||
// generally is not needed unless we are using callbacks
|
||||
PropertyRow* rows[4] = {
|
||||
childByIndex(0),
|
||||
childByIndex(1),
|
||||
childByIndex(2),
|
||||
childByIndex(3)
|
||||
};
|
||||
|
||||
if (rows[0])
|
||||
{
|
||||
color_.setRed(componentFromRowValue(rows[0]->valueAsString().c_str(), (ColorClass*)0));
|
||||
}
|
||||
if (rows[1])
|
||||
{
|
||||
color_.setGreen(componentFromRowValue(rows[1]->valueAsString().c_str(), (ColorClass*)0));
|
||||
}
|
||||
if (rows[2])
|
||||
{
|
||||
color_.setBlue(componentFromRowValue(rows[2]->valueAsString().c_str(), (ColorClass*)0));
|
||||
}
|
||||
if (rows[3])
|
||||
{
|
||||
color_.setAlpha(componentFromRowValue(rows[3]->valueAsString().c_str(), (ColorClass*)0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ColorMenuHandler::ColorMenuHandler(QPropertyTree* tree, IPropertyRowColor* propertyRowColor)
|
||||
: propertyRowColor(propertyRowColor)
|
||||
, tree(tree)
|
||||
{
|
||||
}
|
||||
|
||||
void ColorMenuHandler::onMenuPickColor()
|
||||
{
|
||||
propertyRowColor->pickColor(tree);
|
||||
}
|
||||
|
||||
typedef PropertyRowColor<SerializableColorB> PropertyRowColorB;
|
||||
typedef PropertyRowColor<Vec3AsColor> PropertyRowVec3AsColor;
|
||||
typedef PropertyRowColor<SerializableColorF> PropertyRowColorF;
|
||||
|
||||
REGISTER_PROPERTY_ROW(SerializableColorB, PropertyRowColorB);
|
||||
REGISTER_PROPERTY_ROW(Vec3AsColor, PropertyRowVec3AsColor);
|
||||
REGISTER_PROPERTY_ROW(SerializableColorF, PropertyRowColorF);
|
||||
|
||||
#include <QPropertyTree/moc_PropertyRowColor.cpp>
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include <Serialization.h>
|
||||
#endif
|
||||
|
||||
struct IPropertyRowColor
|
||||
{
|
||||
virtual bool pickColor(QPropertyTree* tree) = 0;
|
||||
};
|
||||
|
||||
template <class ColorClass>
|
||||
class PropertyRowColor
|
||||
: public PropertyRow
|
||||
, public IPropertyRowColor
|
||||
{
|
||||
public:
|
||||
PropertyRowColor()
|
||||
: colorChanged_(false) {}
|
||||
|
||||
bool isLeaf() const override { return colorChanged_; }
|
||||
bool isStatic() const override { return false; }
|
||||
WidgetPlacement widgetPlacement() const{ return WIDGET_AFTER_PULLED; }
|
||||
int widgetSizeMin(const QPropertyTree* tree) const { return userWidgetSize() >= 0 ? userWidgetSize() : tree->_defaultRowHeight()* 2 - 4; }
|
||||
void handleChildrenChange() override;
|
||||
|
||||
void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override;
|
||||
bool assignTo(const Serialization::SStruct& ser) const override;
|
||||
void closeNonLeaf(const Serialization::SStruct& ser, Serialization::IArchive& ar);
|
||||
|
||||
bool onActivate(const PropertyActivationEvent& ev) override;
|
||||
|
||||
string valueAsString() const;
|
||||
void redraw(const PropertyDrawContext& context);
|
||||
|
||||
bool onContextMenu(QMenu& menu, QPropertyTree* tree);
|
||||
|
||||
bool pickColor(QPropertyTree* tree) override;
|
||||
|
||||
private:
|
||||
QColor color_;
|
||||
bool colorChanged_;
|
||||
};
|
||||
|
||||
struct ColorMenuHandler
|
||||
: PropertyRowMenuHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QPropertyTree * tree;
|
||||
IPropertyRowColor* propertyRowColor;
|
||||
|
||||
ColorMenuHandler(QPropertyTree* tree, IPropertyRowColor* propertyRowColor);
|
||||
~ColorMenuHandler(){};
|
||||
|
||||
public slots:
|
||||
void onMenuPickColor();
|
||||
};
|
||||
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "PropertyRowColorPicker.h"
|
||||
#include "Serialization/ClassFactory.h"
|
||||
#include <IEditor.h>
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
#include <QIcon>
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include <AzQtComponents/Components/Widgets/ColorPicker.h>
|
||||
#include <AzQtComponents/Utilities/Conversions.h>
|
||||
|
||||
bool PropertyRowColorPicker::onActivate(const PropertyActivationEvent& e)
|
||||
{
|
||||
if (e.reason == e.REASON_RELEASE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ColorF -> QColor.
|
||||
AZ::Color initialColor;
|
||||
initialColor.SetR(color_.r);
|
||||
initialColor.SetG(color_.g);
|
||||
initialColor.SetB(color_.b);
|
||||
initialColor.SetA(color_.a);
|
||||
|
||||
const AZ::Color colorFromDialog = AzQtComponents::ColorPicker::getColor(AzQtComponents::ColorPicker::Configuration::RGBA,
|
||||
initialColor,
|
||||
QObject::tr("Select Color"));
|
||||
|
||||
if (initialColor == colorFromDialog)
|
||||
{
|
||||
// The user cancelled the dialog box.
|
||||
// Nothing more to do.
|
||||
return false;
|
||||
}
|
||||
|
||||
// QColor -> ColorF.
|
||||
ColorF color(colorFromDialog.GetR(),
|
||||
colorFromDialog.GetG(),
|
||||
colorFromDialog.GetB(),
|
||||
colorFromDialog.GetA());
|
||||
|
||||
e.tree->model()->rowAboutToBeChanged(this);
|
||||
color_ = color;
|
||||
e.tree->model()->rowChanged(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
void PropertyRowColorPicker::setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar)
|
||||
{
|
||||
ColorPicker* value = (ColorPicker*)ser.pointer();
|
||||
color_ = *value->color;
|
||||
}
|
||||
|
||||
bool PropertyRowColorPicker::assignTo(const Serialization::SStruct& ser) const
|
||||
{
|
||||
((ColorPicker*)ser.pointer())->SetColor(&color_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PropertyRowColorPicker::serializeValue(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(color_, "color");
|
||||
}
|
||||
|
||||
const QIcon& PropertyRowColorPicker::buttonIcon([[maybe_unused]] const QPropertyTree* tree, [[maybe_unused]] int index) const
|
||||
{
|
||||
// Color-chip.
|
||||
|
||||
QColor color((int)(color_.r * 255.0f),
|
||||
(int)(color_.g * 255.0f),
|
||||
(int)(color_.b * 255.0f));
|
||||
QPen pen(color);
|
||||
QBrush brush(color);
|
||||
|
||||
QPixmap pixmap(16, 16);
|
||||
pixmap.fill(Qt::transparent);
|
||||
|
||||
QPainter painter(&pixmap);
|
||||
painter.setBrush(brush);
|
||||
painter.setPen(pen);
|
||||
painter.drawEllipse(0, 0, 15, 15);
|
||||
|
||||
static QIcon icon;
|
||||
icon.addPixmap(pixmap);
|
||||
return icon;
|
||||
}
|
||||
|
||||
string PropertyRowColorPicker::valueAsString() const
|
||||
{
|
||||
int r = (int)(255.0f * color_.r);
|
||||
int g = (int)(255.0f * color_.g);
|
||||
int b = (int)(255.0f * color_.b);
|
||||
int a = (int)(255.0f * color_.a);
|
||||
string value;
|
||||
value.Format("#%02x%02x%02x%02x", r, g, b, a);
|
||||
return value;
|
||||
}
|
||||
|
||||
void PropertyRowColorPicker::clear()
|
||||
{
|
||||
color_ = Col_White;
|
||||
}
|
||||
|
||||
bool PropertyRowColorPicker::onContextMenu(QMenu& menu, QPropertyTree* tree)
|
||||
{
|
||||
QAction* action = menu.addAction("Clear");
|
||||
QObject::connect(action,
|
||||
&QAction::triggered,
|
||||
tree,
|
||||
[ this, tree ]
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
clear();
|
||||
tree->model()->rowChanged(this);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyRowColorPicker::processesKey(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (QKeySequence(ev->key()) == QKeySequence(Qt::Key_Delete))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return PropertyRowField::processesKey(tree, ev);
|
||||
}
|
||||
|
||||
bool PropertyRowColorPicker::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (ev->key() == Qt::Key_Delete)
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
clear();
|
||||
tree->model()->rowChanged(this);
|
||||
return true;
|
||||
}
|
||||
return PropertyRowField::onKeyDown(tree, ev);
|
||||
}
|
||||
|
||||
REGISTER_PROPERTY_ROW(ColorPicker, PropertyRowColorPicker);
|
||||
DECLARE_SEGMENT(PropertyRowColorPicker)
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWCOLORPICKER_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWCOLORPICKER_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "PropertyRowField.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "Serialization.h"
|
||||
#include <Serialization/Decorators/ColorPicker.h>
|
||||
#include <Serialization/Decorators/ColorPickerImpl.h>
|
||||
#include <Serialization/Decorators/IconXPM.h>
|
||||
#endif
|
||||
|
||||
using Serialization::ColorPicker;
|
||||
|
||||
class PropertyRowColorPicker
|
||||
: public PropertyRowField
|
||||
{
|
||||
public:
|
||||
void clear();
|
||||
|
||||
bool isLeaf() const override { return true; }
|
||||
bool isStatic() const override { return false; }
|
||||
|
||||
void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override;
|
||||
bool assignTo(const Serialization::SStruct& ser) const override;
|
||||
bool onActivate(const PropertyActivationEvent& e) override;
|
||||
|
||||
int buttonCount() const override { return 1; }
|
||||
virtual const QIcon& buttonIcon(const QPropertyTree* tree, int index) const override;
|
||||
string valueAsString() const override;
|
||||
void serializeValue(Serialization::IArchive& ar);
|
||||
|
||||
bool onContextMenu(QMenu& menu, QPropertyTree* tree);
|
||||
|
||||
bool processesKey(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
|
||||
private:
|
||||
ColorF color_;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWCOLORPICKER_H
|
||||
@@ -1,439 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "PropertyRowContainer.h"
|
||||
#include "PropertyRowPointer.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "Serialization.h"
|
||||
#include "PropertyRowPointer.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QKeyEvent>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
ContainerMenuHandler::ContainerMenuHandler(QPropertyTree* tree, PropertyRowContainer* container)
|
||||
: element()
|
||||
, container(container)
|
||||
, tree(tree)
|
||||
, pointerIndex(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
SERIALIZATION_CLASS_NAME(PropertyRow, PropertyRowContainer, "PropertyRowContainer", "Container");
|
||||
|
||||
PropertyRowContainer::PropertyRowContainer()
|
||||
: fixedSize_(false)
|
||||
, elementTypeName_("")
|
||||
, inlined_(false)
|
||||
{
|
||||
buttonLabel_[0] = '\0';
|
||||
}
|
||||
|
||||
struct ClassMenuItemAdderRowContainer
|
||||
: ClassMenuItemAdder
|
||||
{
|
||||
ClassMenuItemAdderRowContainer(PropertyRowContainer* row, QPropertyTree* tree, bool insert = false)
|
||||
: row_(row)
|
||||
, tree_(tree)
|
||||
, insert_(insert) {}
|
||||
|
||||
void addAction(QMenu& menu, const char* text, int index) override
|
||||
{
|
||||
ContainerMenuHandler* handler = row_->createMenuHandler(tree_, row_);
|
||||
tree_->addMenuHandler(handler);
|
||||
handler->pointerIndex = index;
|
||||
|
||||
QAction* action = menu.addAction(text);
|
||||
QObject::connect(action, SIGNAL(triggered()), handler, SLOT(onMenuAppendPointerByIndex()));
|
||||
}
|
||||
protected:
|
||||
PropertyRowContainer* row_;
|
||||
QPropertyTree* tree_;
|
||||
bool insert_;
|
||||
};
|
||||
|
||||
void PropertyRowContainer::redraw(const PropertyDrawContext& context)
|
||||
{
|
||||
QRect widgetRect = context.widgetRect;
|
||||
if (widgetRect.width() == 0 || inlined_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
QRect rt = widgetRect;
|
||||
rt.adjust(0, 1, -1, -1);
|
||||
QColor brushColor = context.tree->palette().button().color();
|
||||
QLinearGradient gradient(rt.left(), rt.top(), rt.left(), rt.bottom());
|
||||
gradient.setColorAt(0.0f, brushColor);
|
||||
gradient.setColorAt(0.6f, brushColor);
|
||||
gradient.setColorAt(1.0f, context.tree->palette().color(QPalette::Shadow));
|
||||
QBrush brush(gradient);
|
||||
|
||||
const wchar_t* text = multiValue() ? L"..." : buttonLabel_;
|
||||
int buttonFlags = BUTTON_CENTER | BUTTON_POPUP_ARROW;
|
||||
if (userReadOnly())
|
||||
{
|
||||
buttonFlags |= BUTTON_DISABLED;
|
||||
}
|
||||
if (context.m_pressed)
|
||||
{
|
||||
buttonFlags |= BUTTON_PRESSED;
|
||||
}
|
||||
context.drawButton(rt, text, buttonFlags, &context.tree->font());
|
||||
}
|
||||
|
||||
|
||||
bool PropertyRowContainer::onActivate(const PropertyActivationEvent& e)
|
||||
{
|
||||
if (e.reason == e.REASON_RELEASE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (userReadOnly())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (inlined_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
QMenu menu;
|
||||
generateMenu(menu, e.tree, true);
|
||||
e.tree->_setPressedRow(this);
|
||||
menu.exec(e.tree->_toScreen(QPoint(widgetPos_, pos_.y() + e.tree->_defaultRowHeight())));
|
||||
e.tree->_setPressedRow(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
ContainerMenuHandler* PropertyRowContainer::createMenuHandler(QPropertyTree* tree, PropertyRowContainer* container)
|
||||
{
|
||||
return new ContainerMenuHandler(tree, container);
|
||||
}
|
||||
|
||||
void PropertyRowContainer::generateMenu(QMenu& menu, QPropertyTree* tree, bool addActions)
|
||||
{
|
||||
ContainerMenuHandler* handler = createMenuHandler(tree, this);
|
||||
tree->addMenuHandler(handler);
|
||||
|
||||
if (fixedSize_)
|
||||
{
|
||||
if (!inlined_)
|
||||
{
|
||||
menu.addAction("[ Fixed Size Container ]")->setEnabled(false);
|
||||
}
|
||||
}
|
||||
else if (userReadOnly())
|
||||
{
|
||||
menu.addAction("[ Read Only Container ]")->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addActions)
|
||||
{
|
||||
PropertyRow* row = defaultRow(tree->model());
|
||||
if (row && row->isPointer())
|
||||
{
|
||||
QMenu* createItem = menu.addMenu("Add");
|
||||
menu.addSeparator();
|
||||
|
||||
PropertyRowPointer* pointerRow = static_cast<PropertyRowPointer*>(row);
|
||||
ClassMenuItemAdderRowContainer(this, tree).generateMenu(*createItem, tree->model()->typeStringList(pointerRow->baseType()));
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.addAction("Insert", handler, SLOT(onMenuAddElement()));
|
||||
menu.addAction("Add", handler, SLOT(onMenuAppendElement()), Qt::Key_Insert);
|
||||
}
|
||||
}
|
||||
|
||||
if (!menu.isEmpty())
|
||||
{
|
||||
menu.addSeparator();
|
||||
}
|
||||
|
||||
QAction* removeAll = menu.addAction(pulledUp() ? "Remove Children" : "Remove All");
|
||||
removeAll->setShortcut(QKeySequence("Shift+Delete"));
|
||||
removeAll->setEnabled(!userReadOnly());
|
||||
QObject::connect(removeAll, SIGNAL(triggered()), handler, SLOT(onMenuRemoveAll()));
|
||||
}
|
||||
}
|
||||
|
||||
bool PropertyRowContainer::onContextMenu(QMenu& menu, QPropertyTree* tree)
|
||||
{
|
||||
if (!menu.isEmpty())
|
||||
{
|
||||
menu.addSeparator();
|
||||
}
|
||||
|
||||
generateMenu(menu, tree, true);
|
||||
|
||||
if (pulledUp())
|
||||
{
|
||||
return !menu.isEmpty();
|
||||
}
|
||||
|
||||
return PropertyRow::onContextMenu(menu, tree);
|
||||
}
|
||||
|
||||
|
||||
void ContainerMenuHandler::onMenuRemoveAll()
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(container);
|
||||
container->clear();
|
||||
tree->model()->rowChanged(container);
|
||||
}
|
||||
|
||||
PropertyRow* PropertyRowContainer::defaultRow(PropertyTreeModel* model)
|
||||
{
|
||||
PropertyRow* defaultType = model->defaultType(elementTypeName_);
|
||||
//YASLI_ASSERT(defaultType);
|
||||
//YASLI_ASSERT(defaultType->numRef() == 1);
|
||||
return defaultType;
|
||||
}
|
||||
|
||||
const PropertyRow* PropertyRowContainer::defaultRow(const PropertyTreeModel* model) const
|
||||
{
|
||||
const PropertyRow* defaultType = model->defaultType(elementTypeName_);
|
||||
return defaultType;
|
||||
}
|
||||
|
||||
void ContainerMenuHandler::onMenuAddElement()
|
||||
{
|
||||
container->addElement(tree, false);
|
||||
}
|
||||
|
||||
void ContainerMenuHandler::onMenuAppendElement()
|
||||
{
|
||||
container->addElement(tree, true);
|
||||
}
|
||||
|
||||
PropertyRow* PropertyRowContainer::addElement(QPropertyTree* tree, bool append)
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
PropertyRow* defaultType = defaultRow(tree->model());
|
||||
YASLI_ESCAPE(defaultType != 0, return 0);
|
||||
SharedPtr<PropertyRow> clonedRow = defaultType->clone(tree->model()->constStrings());
|
||||
if (count() == 0)
|
||||
{
|
||||
tree->expandRow(this);
|
||||
}
|
||||
if (append)
|
||||
{
|
||||
add(clonedRow);
|
||||
}
|
||||
else
|
||||
{
|
||||
addBefore(clonedRow, 0);
|
||||
}
|
||||
clonedRow->setHideChildren(tree->outlineMode());
|
||||
clonedRow->setLabelChanged();
|
||||
clonedRow->setLabelChangedToChildren();
|
||||
setMultiValue(false);
|
||||
if (expanded())
|
||||
{
|
||||
tree->model()->selectRow(clonedRow, true);
|
||||
}
|
||||
tree->expandRow(clonedRow);
|
||||
TreePath path = tree->model()->pathFromRow(clonedRow);
|
||||
tree->model()->rowChanged(clonedRow);
|
||||
clonedRow = tree->model()->rowFromPath(path);
|
||||
tree->update();
|
||||
clonedRow = tree->model()->rowFromPath(path);
|
||||
if (clonedRow)
|
||||
{
|
||||
PropertyTreeModel::Selection sel;
|
||||
sel.push_back(path);
|
||||
tree->model()->setSelection(sel);
|
||||
if (clonedRow->activateOnAdd())
|
||||
{
|
||||
PropertyActivationEvent e;
|
||||
e.tree = tree;
|
||||
e.reason = e.REASON_NEW_ELEMENT;
|
||||
clonedRow->onActivate(e);
|
||||
}
|
||||
}
|
||||
return clonedRow;
|
||||
}
|
||||
|
||||
|
||||
void ContainerMenuHandler::onMenuAppendPointerByIndex()
|
||||
{
|
||||
PropertyRow* defaultType = container->defaultRow(tree->model());
|
||||
PropertyRowPointer* defaultTypePointer = static_cast<PropertyRowPointer*>(defaultType);
|
||||
SharedPtr<PropertyRow> clonedRow = defaultType->clone(tree->model()->constStrings());
|
||||
if (container->count() == 0)
|
||||
{
|
||||
tree->expandRow(container);
|
||||
}
|
||||
container->add(clonedRow);
|
||||
clonedRow->setLabelChanged();
|
||||
clonedRow->setLabelChangedToChildren();
|
||||
clonedRow->setHideChildren(tree->outlineMode());
|
||||
container->setMultiValue(false);
|
||||
PropertyRowPointer* clonedRowPointer = static_cast<PropertyRowPointer*>(clonedRow.get());
|
||||
clonedRowPointer->setDerivedType(defaultTypePointer->derivedTypeName(), defaultTypePointer->factory());
|
||||
clonedRowPointer->setBaseType(defaultTypePointer->baseType());
|
||||
clonedRowPointer->setFactory(defaultTypePointer->factory());
|
||||
if (container->expanded())
|
||||
{
|
||||
tree->model()->selectRow(clonedRow, true);
|
||||
}
|
||||
tree->expandRow(clonedRowPointer);
|
||||
PropertyTreeModel::Selection sel = tree->model()->selection();
|
||||
|
||||
CreatePointerMenuHandler handler;
|
||||
handler.tree = tree;
|
||||
handler.row = clonedRowPointer;
|
||||
handler.index = pointerIndex;
|
||||
handler.onMenuCreateByIndex();
|
||||
tree->model()->setSelection(sel);
|
||||
tree->update();
|
||||
}
|
||||
|
||||
void ContainerMenuHandler::onMenuChildInsertBefore()
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(container);
|
||||
PropertyRow* defaultType = tree->model()->defaultType(container->elementTypeName());
|
||||
if (!defaultType)
|
||||
{
|
||||
return;
|
||||
}
|
||||
SharedPtr<PropertyRow> clonedRow = defaultType->clone(tree->model()->constStrings());
|
||||
clonedRow->setHideChildren(tree->outlineMode());
|
||||
element->setSelected(false);
|
||||
container->addBefore(clonedRow, element);
|
||||
container->setMultiValue(false);
|
||||
tree->model()->selectRow(clonedRow, true);
|
||||
PropertyTreeModel::Selection sel = tree->model()->selection();
|
||||
tree->model()->rowChanged(clonedRow);
|
||||
tree->model()->setSelection(sel);
|
||||
tree->update();
|
||||
clonedRow = tree->selectedRow();
|
||||
if (clonedRow->activateOnAdd())
|
||||
{
|
||||
PropertyActivationEvent e;
|
||||
e.tree = tree;
|
||||
e.reason = PropertyActivationEvent::REASON_NEW_ELEMENT;
|
||||
clonedRow->onActivate(e);
|
||||
}
|
||||
}
|
||||
|
||||
void ContainerMenuHandler::onMenuChildRemove()
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(container);
|
||||
container->erase(element);
|
||||
container->setMultiValue(false);
|
||||
tree->model()->rowChanged(container);
|
||||
}
|
||||
|
||||
|
||||
void PropertyRowContainer::labelChanged()
|
||||
{
|
||||
swprintf(buttonLabel_, sizeof(buttonLabel_) / sizeof(buttonLabel_[0]), L"%zi", count());
|
||||
}
|
||||
|
||||
void PropertyRowContainer::serializeValue(IArchive& ar)
|
||||
{
|
||||
ar(ConstStringWrapper(constStrings_, elementTypeName_), "elementTypeName", "ElementTypeName");
|
||||
ar(fixedSize_, "fixedSize", "fixedSize");
|
||||
}
|
||||
|
||||
string PropertyRowContainer::valueAsString() const
|
||||
{
|
||||
char buf[32] = { 0 };
|
||||
sprintf_s(buf, "%d", (int)children_.size());
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
const char* PropertyRowContainer::typeNameForFilter(QPropertyTree* tree) const
|
||||
{
|
||||
const PropertyRow* defaultType = defaultRow(tree->model());
|
||||
if (defaultType)
|
||||
{
|
||||
return defaultType->typeNameForFilter(tree);
|
||||
}
|
||||
else
|
||||
{
|
||||
return elementTypeName_;
|
||||
}
|
||||
}
|
||||
|
||||
bool PropertyRowContainer::processesKeyContainer([[maybe_unused]] QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (ev->key() == Qt::Key_Delete && ev->modifiers() == Qt::SHIFT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ev->key() == Qt::Key_Insert && ev->modifiers() == Qt::NoModifier)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyRowContainer::processesKey(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (processesKeyContainer(tree, ev))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return PropertyRow::processesKey(tree, ev);
|
||||
}
|
||||
|
||||
bool PropertyRowContainer::onKeyDownContainer(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (userReadOnly())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<ContainerMenuHandler> handler(createMenuHandler(tree, this));
|
||||
if (ev->key() == Qt::Key_Delete && ev->modifiers() == Qt::SHIFT)
|
||||
{
|
||||
handler->onMenuRemoveAll();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ev->key() == Qt::Key_Insert && ev->modifiers() == Qt::NoModifier)
|
||||
{
|
||||
handler->onMenuAppendElement();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyRowContainer::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (onKeyDownContainer(tree, ev))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return PropertyRow::onKeyDown(tree, ev);
|
||||
}
|
||||
|
||||
int PropertyRowContainer::widgetSizeMin(const QPropertyTree* tree) const
|
||||
{
|
||||
return inlined_ ? 0 : (userWidgetSize() >= 0 ? userWidgetSize() : aznumeric_cast<int>(tree->_defaultRowHeight() * 1.7f));
|
||||
}
|
||||
|
||||
#include <QPropertyTree/moc_PropertyRowContainer.cpp>
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWCONTAINER_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWCONTAINER_H
|
||||
#pragma once
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "PropertyRow.h"
|
||||
#endif
|
||||
|
||||
|
||||
class EDITOR_COMMON_API PropertyRowContainer;
|
||||
struct EDITOR_COMMON_API ContainerMenuHandler
|
||||
: PropertyRowMenuHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
QPropertyTree * tree;
|
||||
PropertyRowContainer* container;
|
||||
PropertyRow* element;
|
||||
int pointerIndex;
|
||||
|
||||
ContainerMenuHandler(QPropertyTree* tree, PropertyRowContainer* container);
|
||||
|
||||
public slots:
|
||||
virtual void onMenuAddElement();
|
||||
virtual void onMenuAppendElement();
|
||||
virtual void onMenuAppendPointerByIndex();
|
||||
virtual void onMenuRemoveAll();
|
||||
virtual void onMenuChildInsertBefore();
|
||||
virtual void onMenuChildRemove();
|
||||
};
|
||||
|
||||
class EDITOR_COMMON_API PropertyRowContainer
|
||||
: public PropertyRow
|
||||
{
|
||||
public:
|
||||
PropertyRowContainer();
|
||||
bool isContainer() const{ return true; }
|
||||
bool onActivate(const PropertyActivationEvent& e);
|
||||
bool onContextMenu(QMenu& item, QPropertyTree* tree);
|
||||
virtual ContainerMenuHandler* createMenuHandler(QPropertyTree* tree, PropertyRowContainer* container) override;
|
||||
void redraw(const PropertyDrawContext& context);
|
||||
bool processesKeyContainer(QPropertyTree* tree, const QKeyEvent* ev);
|
||||
bool processesKey(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
bool onKeyDownContainer(QPropertyTree* tree, const QKeyEvent* key);
|
||||
bool onKeyDown(QPropertyTree* tree, const QKeyEvent* key) override;
|
||||
|
||||
void labelChanged() override;
|
||||
bool isStatic() const{ return false; }
|
||||
bool isSelectable() const{ return userWidgetSize() == 0 ? false : true; }
|
||||
PropertyRow* addElement(QPropertyTree* tree, bool append);
|
||||
void setInlined(bool inlined) { inlined_ = inlined; }
|
||||
bool isInlined() const{ return inlined_; }
|
||||
|
||||
PropertyRow* defaultRow(PropertyTreeModel* model);
|
||||
const PropertyRow* defaultRow(const PropertyTreeModel* model) const;
|
||||
void serializeValue(Serialization::IArchive& ar);
|
||||
|
||||
const char* elementTypeName() const{ return elementTypeName_; }
|
||||
using PropertyRow::setValueAndContext;
|
||||
virtual void setValueAndContext(const Serialization::IContainer& value, [[maybe_unused]] Serialization::IArchive& ar)
|
||||
{
|
||||
fixedSize_ = value.isFixedSize();
|
||||
elementTypeName_ = value.elementType().name();
|
||||
serializer_.setPointer(value.pointer());
|
||||
serializer_.setType(value.containerType());
|
||||
}
|
||||
const char* typeNameForFilter(QPropertyTree* tree) const override;
|
||||
string valueAsString() const;
|
||||
// C-array is an example of fixed size container
|
||||
bool isFixedSize() const{ return fixedSize_; }
|
||||
WidgetPlacement widgetPlacement() const override { return inlined_ ? WIDGET_NONE : WIDGET_AFTER_NAME; }
|
||||
int widgetSizeMin(const QPropertyTree* tree) const override;
|
||||
|
||||
protected:
|
||||
virtual void generateMenu(QMenu& menu, QPropertyTree* tree, bool addActions);
|
||||
|
||||
const char* elementTypeName_;
|
||||
wchar_t buttonLabel_[8];
|
||||
bool fixedSize_;
|
||||
bool inlined_;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWCONTAINER_H
|
||||
@@ -1,84 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "PropertyRowField.h"
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "QPropertyTreeStyle.h"
|
||||
#include <QtGui/QIcon>
|
||||
|
||||
enum { BUTTON_SIZE = 16 };
|
||||
|
||||
QRect PropertyRowField::fieldRect(const QPropertyTree* tree) const
|
||||
{
|
||||
QRect fieldRect = widgetRect(tree);
|
||||
fieldRect.setRight(fieldRect.right() - buttonCount() * BUTTON_SIZE);
|
||||
return fieldRect;
|
||||
}
|
||||
|
||||
bool PropertyRowField::onActivate(const PropertyActivationEvent& e)
|
||||
{
|
||||
if (e.reason == e.REASON_PRESS) {
|
||||
int buttonCount = this->buttonCount();
|
||||
QRect buttonsRect = widgetRect(e.tree);
|
||||
buttonsRect.setLeft(buttonsRect.right() - buttonCount * BUTTON_SIZE);
|
||||
|
||||
if (buttonsRect.contains(e.clickPoint)) {
|
||||
int buttonIndex = buttonCount - (e.clickPoint.x() - buttonsRect.x()) / BUTTON_SIZE - 1;
|
||||
if (buttonIndex >= 0 && buttonIndex < buttonCount)
|
||||
{
|
||||
if (onActivateButton(buttonIndex, e))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PropertyRow::onActivate(e);
|
||||
}
|
||||
|
||||
void PropertyRowField::redraw(const PropertyDrawContext& context)
|
||||
{
|
||||
int buttonCount = this->buttonCount();
|
||||
int offset = 0;
|
||||
for (int i = 0; i < buttonCount; ++i) {
|
||||
const QIcon& icon = buttonIcon(context.tree, i);
|
||||
QRect iconRect(context.widgetRect.right() - offset - BUTTON_SIZE, context.widgetRect.top(), BUTTON_SIZE, context.widgetRect.height());
|
||||
icon.paint(context.painter, iconRect, Qt::AlignCenter, userReadOnly() ? QIcon::Disabled : QIcon::Normal);
|
||||
offset += BUTTON_SIZE;
|
||||
}
|
||||
|
||||
int iconSpace = offset ? offset + 2 : 0;
|
||||
if(multiValue())
|
||||
context.drawEntry(L" ... ", false, true, iconSpace);
|
||||
else if(userReadOnly())
|
||||
context.drawValueText(pulledSelected(), valueAsWString().c_str());
|
||||
else
|
||||
context.drawEntry(valueAsWString().c_str(), usePathEllipsis(), false, iconSpace);
|
||||
|
||||
}
|
||||
|
||||
const QIcon& PropertyRowField::buttonIcon([[maybe_unused]] const QPropertyTree* tree, [[maybe_unused]] int index) const
|
||||
{
|
||||
static QIcon defaultIcon;
|
||||
return defaultIcon;
|
||||
}
|
||||
|
||||
int PropertyRowField::widgetSizeMin(const QPropertyTree* tree) const
|
||||
{
|
||||
if (userWidgetSize() >= 0)
|
||||
return userWidgetSize();
|
||||
|
||||
if (userWidgetToContent_)
|
||||
return widthCache_.getOrUpdate(tree, this, 0);
|
||||
else
|
||||
return 40;
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWFIELD_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWFIELD_H
|
||||
#pragma once
|
||||
|
||||
#include "PropertyRow.h"
|
||||
class QIcon;
|
||||
|
||||
class PropertyRowField : public PropertyRow
|
||||
{
|
||||
public:
|
||||
WidgetPlacement widgetPlacement() const override{ return WIDGET_VALUE; }
|
||||
int widgetSizeMin(const QPropertyTree* tree) const override;
|
||||
|
||||
virtual int buttonCount() const{ return 0; }
|
||||
virtual const QIcon& buttonIcon(const QPropertyTree* tree, int index) const;
|
||||
virtual bool usePathEllipsis() const { return false; }
|
||||
virtual bool onActivateButton([[maybe_unused]] int buttonIndex, [[maybe_unused]] const PropertyActivationEvent& e) { return false; }
|
||||
|
||||
void redraw(const PropertyDrawContext& context) override;
|
||||
bool onActivate(const PropertyActivationEvent& e) override;
|
||||
protected:
|
||||
QRect fieldRect(const QPropertyTree* tree) const;
|
||||
void drawButtons(int* offset);
|
||||
|
||||
mutable RowWidthCache widthCache_;
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWFIELD_H
|
||||
@@ -1,119 +0,0 @@
|
||||
/**
|
||||
* yasli - Serialization Library.
|
||||
* Copyright (C) 2007-2013 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "Serialization/ClassFactory.h"
|
||||
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "PropertyRowImpl.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "Serialization.h"
|
||||
#include "Color.h"
|
||||
#include "Serialization/Decorators/IconXPM.h"
|
||||
using Serialization::IconXPM;
|
||||
using Serialization::IconXPMToggle;
|
||||
|
||||
class PropertyRowIconXPM : public PropertyRow{
|
||||
public:
|
||||
void redraw(const PropertyDrawContext& context)
|
||||
{
|
||||
QRect rect = context.widgetRect;
|
||||
context.drawIcon(rect, icon_);
|
||||
}
|
||||
|
||||
bool isLeaf() const{ return true; }
|
||||
bool isStatic() const{ return false; }
|
||||
bool isSelectable() const{ return false; }
|
||||
|
||||
bool onActivate([[maybe_unused]] const PropertyActivationEvent& e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override {
|
||||
YASLI_ESCAPE(ser.size() == sizeof(IconXPM), return);
|
||||
icon_ = *(IconXPM*)(ser.pointer());
|
||||
}
|
||||
wstring valueAsWString() const{ return L""; }
|
||||
WidgetPlacement widgetPlacement() const{ return WIDGET_ICON; }
|
||||
void serializeValue([[maybe_unused]] Serialization::IArchive& ar) {}
|
||||
int widgetSizeMin(const QPropertyTree* tree) const override{ return tree->_defaultRowHeight(); }
|
||||
int height() const{ return 16; }
|
||||
protected:
|
||||
IconXPM icon_;
|
||||
};
|
||||
|
||||
class PropertyRowIconToggle : public PropertyRow{
|
||||
public:
|
||||
void redraw(const PropertyDrawContext& context) override
|
||||
{
|
||||
IconXPM& icon = value_ ? iconTrue_ : iconFalse_;
|
||||
context.drawIcon(context.widgetRect, icon);
|
||||
}
|
||||
|
||||
void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override {
|
||||
YASLI_ESCAPE(ser.size() == sizeof(IconXPMToggle), return);
|
||||
const IconXPMToggle* icon = (IconXPMToggle*)(ser.pointer());
|
||||
iconTrue_ = icon->iconTrue_;
|
||||
iconFalse_ = icon->iconFalse_;
|
||||
value_ = icon->value_;
|
||||
}
|
||||
|
||||
bool assignTo(const Serialization::SStruct& ser) const override
|
||||
{
|
||||
IconXPMToggle* toggle = (IconXPMToggle*)ser.pointer();
|
||||
toggle->value_ = value_;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isLeaf() const override{ return true; }
|
||||
bool isStatic() const override{ return false; }
|
||||
bool isSelectable() const override{ return true; }
|
||||
bool onActivate(const PropertyActivationEvent& e)
|
||||
{
|
||||
if (e.reason != e.REASON_RELEASE)
|
||||
{
|
||||
e.tree->model()->rowAboutToBeChanged(this);
|
||||
value_ = !value_;
|
||||
e.tree->model()->rowChanged(this);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
DragCheckBegin onMouseDragCheckBegin() override
|
||||
{
|
||||
if (userReadOnly())
|
||||
return DRAG_CHECK_IGNORE;
|
||||
return value_ ? DRAG_CHECK_UNSET : DRAG_CHECK_SET;
|
||||
}
|
||||
bool onMouseDragCheck(QPropertyTree* tree, bool value) override
|
||||
{
|
||||
if (value_ != value) {
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
value_ = value;
|
||||
tree->model()->rowChanged(this);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
wstring valueAsWString() const{ return value_ ? L"true" : L"false"; }
|
||||
WidgetPlacement widgetPlacement() const{ return WIDGET_ICON; }
|
||||
|
||||
int widgetSizeMin(const QPropertyTree* tree) const{ return tree->_defaultRowHeight(); }
|
||||
int height() const{ return 16; }
|
||||
|
||||
IconXPM iconTrue_;
|
||||
IconXPM iconFalse_;
|
||||
bool value_;
|
||||
};
|
||||
|
||||
REGISTER_PROPERTY_ROW(IconXPM, PropertyRowIconXPM);
|
||||
REGISTER_PROPERTY_ROW(IconXPMToggle, PropertyRowIconToggle);
|
||||
DECLARE_SEGMENT(PropertyRowIconXPM)
|
||||
@@ -1,48 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWIMPL_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWIMPL_H
|
||||
#pragma once
|
||||
|
||||
#include "Serialization/STL.h"
|
||||
#include "PropertyRowField.h"
|
||||
#include "Serialization.h"
|
||||
|
||||
template<class Type>
|
||||
class PropertyRowImpl;
|
||||
|
||||
template<class Type>
|
||||
class PropertyRowImpl : public PropertyRowField{
|
||||
public:
|
||||
bool assignTo(const Serialization::SStruct& ser) const override {
|
||||
*reinterpret_cast<Type*>(ser.pointer()) = value();
|
||||
return true;
|
||||
}
|
||||
bool isLeaf() const override{ return true; }
|
||||
bool isStatic() const override{ return false; }
|
||||
void setValue(const Type& value) { value_ = value; }
|
||||
Type& value() { return value_; }
|
||||
const Type& value() const{ return value_; }
|
||||
|
||||
void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override {
|
||||
YASLI_ESCAPE(ser.size() == sizeof(Type), return);
|
||||
value_ = *(Type*)(ser.pointer());
|
||||
}
|
||||
|
||||
void serializeValue(Serialization::IArchive& ar) override{
|
||||
ar(value_, "value", "Value");
|
||||
}
|
||||
protected:
|
||||
Type value_;
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWIMPL_H
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "PropertyRowLocalFrame.h"
|
||||
#include <QIcon>
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include <Serialization/Decorators/IGizmoSink.h>
|
||||
#include <Serialization/Decorators/LocalFrame.h>
|
||||
#include "Serialization/ClassFactory.h"
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "Serialization.h"
|
||||
#include <Serialization/Decorators/LocalFrameImpl.h>
|
||||
|
||||
using Serialization::LocalPosition;
|
||||
|
||||
void LocalFrameMenuHandler::onMenuReset()
|
||||
{
|
||||
self->reset(tree);
|
||||
}
|
||||
|
||||
PropertyRowLocalFrameBase::PropertyRowLocalFrameBase()
|
||||
: m_sink(0)
|
||||
, m_gizmoIndex(-1)
|
||||
, m_handle(0)
|
||||
, m_reset(false)
|
||||
{
|
||||
}
|
||||
|
||||
PropertyRowLocalFrameBase::~PropertyRowLocalFrameBase()
|
||||
{
|
||||
m_sink = 0;
|
||||
}
|
||||
|
||||
bool PropertyRowLocalFrameBase::onActivate(const PropertyActivationEvent& e)
|
||||
{
|
||||
if (e.reason == e.REASON_RELEASE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
string PropertyRowLocalFrameBase::valueAsString() const
|
||||
{
|
||||
return string();
|
||||
}
|
||||
|
||||
bool PropertyRowLocalFrameBase::onContextMenu(QMenu& menu, QPropertyTree* tree)
|
||||
{
|
||||
Serialization::SharedPtr<PropertyRow> selfPointer(this);
|
||||
|
||||
LocalFrameMenuHandler* handler = new LocalFrameMenuHandler(tree, this);
|
||||
|
||||
menu.addAction("Reset", handler, SLOT(onMenuReset()));
|
||||
|
||||
tree->addMenuHandler(handler);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PropertyRowLocalFrameBase::reset(QPropertyTree* tree)
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
m_reset = true;
|
||||
tree->model()->rowChanged(this);
|
||||
}
|
||||
|
||||
void PropertyRowLocalFrameBase::redraw(const PropertyDrawContext& context)
|
||||
{
|
||||
static QIcon gizmo("Icons/animation/gizmo_location.png");
|
||||
gizmo.paint(context.painter, context.widgetRect.adjusted(1, 1, 1, 1), Qt::AlignRight);
|
||||
}
|
||||
|
||||
static void ResetTransform(Serialization::LocalPosition* l) { *l->value = ZERO; }
|
||||
static void ResetTransform(Serialization::LocalOrientation* l) { *l->value = IDENTITY; }
|
||||
static void ResetTransform(Serialization::LocalFrame* l) { *l->position = ZERO; *l->rotation = IDENTITY; }
|
||||
|
||||
template<class TLocal>
|
||||
class PropertyRowLocalFrameImpl
|
||||
: public PropertyRowLocalFrameBase
|
||||
{
|
||||
public:
|
||||
void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override
|
||||
{
|
||||
serializer_ = ser;
|
||||
|
||||
TLocal* value = (TLocal*)ser.pointer();
|
||||
m_handle = value->handle;
|
||||
m_reset = false;
|
||||
|
||||
if (label() && label()[0])
|
||||
{
|
||||
m_sink = ar.FindContext<Serialization::IGizmoSink>();
|
||||
if (m_sink)
|
||||
{
|
||||
m_gizmoIndex = m_sink->Write(*value, m_gizmoFlags, m_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void closeNonLeaf(const Serialization::SStruct& ser, Serialization::IArchive& ar) override
|
||||
{
|
||||
if (label() && label()[0] && ar.IsInput())
|
||||
{
|
||||
TLocal& value = *((TLocal*)ser.pointer());
|
||||
if (m_sink)
|
||||
{
|
||||
if (m_sink->CurrentGizmoIndex() == m_gizmoIndex)
|
||||
{
|
||||
m_sink->Read(&value, &m_gizmoFlags, m_handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sink->SkipRead();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool assignTo(const Serialization::SStruct& ser) const
|
||||
{
|
||||
if (m_reset)
|
||||
{
|
||||
TLocal& value = *((TLocal*)ser.pointer());
|
||||
ResetTransform(&value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
typedef PropertyRowLocalFrameImpl<Serialization::LocalPosition> PropertyRowLocalPosition;
|
||||
typedef PropertyRowLocalFrameImpl<Serialization::LocalOrientation> PropertyRowLocalOrientation;
|
||||
typedef PropertyRowLocalFrameImpl<Serialization::LocalFrame> PropertyRowLocalFrame;
|
||||
|
||||
REGISTER_PROPERTY_ROW(Serialization::LocalPosition, PropertyRowLocalPosition);
|
||||
REGISTER_PROPERTY_ROW(Serialization::LocalOrientation, PropertyRowLocalOrientation);
|
||||
REGISTER_PROPERTY_ROW(Serialization::LocalFrame, PropertyRowLocalFrame);
|
||||
|
||||
#include <QPropertyTree/moc_PropertyRowLocalFrame.cpp>
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWLOCALFRAME_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWLOCALFRAME_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "Serialization/Decorators/IGizmoSink.h"
|
||||
#include "PropertyRowField.h"
|
||||
#include "QPropertyTree.h"
|
||||
#endif
|
||||
|
||||
struct IGizmoSink;
|
||||
|
||||
class PropertyRowLocalFrameBase
|
||||
: public PropertyRow
|
||||
{
|
||||
public:
|
||||
PropertyRowLocalFrameBase();
|
||||
~PropertyRowLocalFrameBase();
|
||||
|
||||
bool isLeaf() const override { return m_reset; }
|
||||
bool isStatic() const override { return false; }
|
||||
|
||||
bool onActivate(const PropertyActivationEvent& e) override;
|
||||
|
||||
WidgetPlacement widgetPlacement() const override { return WIDGET_AFTER_PULLED; }
|
||||
int widgetSizeMin(const QPropertyTree* tree) const override { return tree->_defaultRowHeight(); }
|
||||
|
||||
string valueAsString() const override;
|
||||
bool onContextMenu(QMenu& menu, QPropertyTree* tree) override;
|
||||
const void* searchHandle() const override { return m_handle; }
|
||||
void redraw(const PropertyDrawContext& context) override;
|
||||
|
||||
void reset(QPropertyTree* tree);
|
||||
protected:
|
||||
Serialization::IGizmoSink* m_sink;
|
||||
const void* m_handle;
|
||||
int m_gizmoIndex;
|
||||
mutable Serialization::GizmoFlags m_gizmoFlags;
|
||||
bool m_reset;
|
||||
};
|
||||
|
||||
struct LocalFrameMenuHandler
|
||||
: PropertyRowMenuHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QPropertyTree * tree;
|
||||
PropertyRowLocalFrameBase* self;
|
||||
|
||||
LocalFrameMenuHandler(QPropertyTree* tree, PropertyRowLocalFrameBase* self)
|
||||
: tree(tree)
|
||||
, self(self) {}
|
||||
public slots:
|
||||
void onMenuReset();
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWLOCALFRAME_H
|
||||
@@ -1,43 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "Serialization.h"
|
||||
#include "PropertyRowNumber.h"
|
||||
|
||||
#define REGISTER_NUMBER_ROW(TypeName, postfix) \
|
||||
typedef PropertyRowNumber<TypeName> PropertyRow##postfix; \
|
||||
typedef Serialization::RangeDecorator<TypeName> RangeDecorator##postfix; \
|
||||
PropertyRow* TypeName##postfixFactory() { return new PropertyRow##postfix; }; \
|
||||
REGISTER_IN_FACTORY(PropertyRowFactory, Serialization::TypeID::get<RangeDecorator##postfix>().name(), PropertyRow##postfix, TypeName##postfixFactory); \
|
||||
SERIALIZATION_CLASS_NAME(PropertyRow, PropertyRow##postfix, "PropertyRow" #postfix, #TypeName);
|
||||
|
||||
REGISTER_NUMBER_ROW(float, Float)
|
||||
REGISTER_NUMBER_ROW(double , Double)
|
||||
|
||||
REGISTER_NUMBER_ROW(char, Char)
|
||||
REGISTER_NUMBER_ROW(int8, Int8)
|
||||
REGISTER_NUMBER_ROW(uint8, Uint8)
|
||||
|
||||
REGISTER_NUMBER_ROW(int16, Int16)
|
||||
REGISTER_NUMBER_ROW(int32, Int32)
|
||||
REGISTER_NUMBER_ROW(int64, Int64)
|
||||
REGISTER_NUMBER_ROW(uint16, Uint16)
|
||||
REGISTER_NUMBER_ROW(uint32, Uint32)
|
||||
REGISTER_NUMBER_ROW(uint64, Uint64)
|
||||
|
||||
#undef REGISTER_NUMBER_ROW
|
||||
|
||||
DECLARE_SEGMENT(PropertyRowNumber)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -1,237 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWNUMBER_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWNUMBER_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "QPropertyTree.h"
|
||||
#include "Serialization/MemoryWriter.h"
|
||||
#include "Serialization/Decorators/Range.h"
|
||||
#include "PropertyRowNumberField.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
template<class T>
|
||||
string numberAsString(T value)
|
||||
{
|
||||
Serialization::MemoryWriter buf;
|
||||
buf << value;
|
||||
return buf.c_str();
|
||||
}
|
||||
|
||||
inline long long stringToSignedInteger(const char* str)
|
||||
{
|
||||
long long value;
|
||||
#ifdef _MSC_VER
|
||||
value = _atoi64(str);
|
||||
#else
|
||||
char* endptr = (char*)str;
|
||||
value = strtoll(str, &endptr, 10);
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
inline unsigned long long stringToUnsignedInteger(const char* str)
|
||||
{
|
||||
unsigned long long value;
|
||||
if (*str == '-') {
|
||||
value = 0;
|
||||
}
|
||||
else {
|
||||
#ifdef _MSC_VER
|
||||
char* endptr = (char*)str;
|
||||
value = _strtoui64(str, &endptr, 10);
|
||||
#else
|
||||
char* endptr = (char*)str;
|
||||
value = strtoull(str, &endptr, 10);
|
||||
#endif
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
template<class Output, class Input>
|
||||
Output clamp(Input value, Output min, Output max)
|
||||
{
|
||||
if (value < Input(min))
|
||||
return min;
|
||||
if (value > Input(max))
|
||||
return max;
|
||||
return Output(value);
|
||||
}
|
||||
|
||||
template<class Out, class In> void clampToType(Out* out, In value) { *out = clamp(value, std::numeric_limits<Out>::lowest(), std::numeric_limits<Out>::max()); }
|
||||
|
||||
inline void clampedNumberFromString(char* value, const char* str) { clampToType(value, stringToSignedInteger(str)); }
|
||||
inline void clampedNumberFromString(signed char* value, const char* str) { clampToType(value, stringToSignedInteger(str)); }
|
||||
inline void clampedNumberFromString(short* value, const char* str) { clampToType(value, stringToSignedInteger(str)); }
|
||||
inline void clampedNumberFromString(int* value, const char* str) { clampToType(value, stringToSignedInteger(str)); }
|
||||
inline void clampedNumberFromString(long* value, const char* str) { clampToType(value, stringToSignedInteger(str)); }
|
||||
inline void clampedNumberFromString(long long* value, const char* str) { clampToType(value, stringToSignedInteger(str)); }
|
||||
inline void clampedNumberFromString(unsigned char* value, const char* str) { clampToType(value, stringToUnsignedInteger(str)); }
|
||||
inline void clampedNumberFromString(unsigned short* value, const char* str) { clampToType(value, stringToUnsignedInteger(str)); }
|
||||
inline void clampedNumberFromString(unsigned int* value, const char* str) { clampToType(value, stringToUnsignedInteger(str)); }
|
||||
inline void clampedNumberFromString(unsigned long* value, const char* str) { clampToType(value, stringToUnsignedInteger(str)); }
|
||||
inline void clampedNumberFromString(unsigned long long* value, const char* str) { clampToType(value, stringToUnsignedInteger(str)); }
|
||||
inline void clampedNumberFromString(float* value, const char* str)
|
||||
{
|
||||
double v = atof(str);
|
||||
if (v > FLT_MAX)
|
||||
v = FLT_MAX;
|
||||
if (v < -FLT_MAX)
|
||||
v = -FLT_MAX;
|
||||
*value = float(v);
|
||||
}
|
||||
|
||||
inline void clampedNumberFromString(double* value, const char* str)
|
||||
{
|
||||
*value = atof(str);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
class PropertyRowNumber : public PropertyRowNumberField{
|
||||
public:
|
||||
PropertyRowNumber()
|
||||
{
|
||||
softMin_ = std::numeric_limits<Type>::lowest();
|
||||
softMax_ = std::numeric_limits<Type>::max();
|
||||
hardMin_ = std::numeric_limits<Type>::lowest();
|
||||
hardMax_ = std::numeric_limits<Type>::max();
|
||||
}
|
||||
|
||||
void setValue(Type value, const void* handle, const Serialization::TypeID& type)
|
||||
{
|
||||
value_ = value;
|
||||
serializer_.setPointer((void*)handle);
|
||||
serializer_.setType(type);
|
||||
}
|
||||
bool setValueFromString(const char* str) override{
|
||||
Type value = value_;
|
||||
clampedNumberFromString(&value_, str);
|
||||
return value_ != value;
|
||||
}
|
||||
string valueAsString() const override
|
||||
{
|
||||
return numberAsString(Type(value_));
|
||||
}
|
||||
|
||||
bool assignToPrimitive(void* object, [[maybe_unused]] size_t size) const override
|
||||
{
|
||||
*reinterpret_cast<Type*>(object) = value_;
|
||||
return true;
|
||||
}
|
||||
|
||||
void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override
|
||||
{
|
||||
Serialization::RangeDecorator<Type>* range = (Serialization::RangeDecorator<Type>*)ser.pointer();
|
||||
serializer_.setPointer((void*)range->value);
|
||||
serializer_.setType(Serialization::TypeID::get<Type>());
|
||||
value_ = *range->value;
|
||||
softMin_ = range->softMin;
|
||||
softMax_ = range->softMax;
|
||||
hardMin_ = range->hardMin;
|
||||
hardMax_ = range->hardMax;
|
||||
}
|
||||
|
||||
bool assignTo(const Serialization::SStruct& ser) const override
|
||||
{
|
||||
if (ser.type() == Serialization::TypeID::get<Serialization::RangeDecorator<Type>>()) {
|
||||
Serialization::RangeDecorator<Type>* range = (Serialization::RangeDecorator<Type>*)ser.pointer();
|
||||
*range->value = value_;
|
||||
}
|
||||
else if (ser.type() == Serialization::TypeID::get<Type>()) {
|
||||
*(Type*)ser.pointer() = value_;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void serializeValue(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(value_, "value", "Value");
|
||||
ar(softMin_, "softMin", "SoftMin");
|
||||
ar(softMax_, "softMax", "SoftMax");
|
||||
ar(hardMin_, "hardMin", "HardMin");
|
||||
ar(hardMax_, "hardMax", "HardMax");
|
||||
}
|
||||
|
||||
void startIncrement() override
|
||||
{
|
||||
incrementStartValue_ = value_;
|
||||
}
|
||||
|
||||
void endIncrement(QPropertyTree* tree) override
|
||||
{
|
||||
if (value_ != incrementStartValue_) {
|
||||
Type value = value_;
|
||||
value_ = incrementStartValue_;
|
||||
value_ = value;
|
||||
tree->model()->rowChanged(this, true);
|
||||
}
|
||||
}
|
||||
|
||||
void incrementLog(float screenFraction, float valueFieldFraction)
|
||||
{
|
||||
bool bothSoftLimitsSet = (std::numeric_limits<Type>::lowest() == 0 || softMin_ != std::numeric_limits<Type>::lowest()) && softMax_ != std::numeric_limits<Type>::max();
|
||||
|
||||
if (bothSoftLimitsSet)
|
||||
{
|
||||
Type softRange = softMax_ - softMin_;
|
||||
double newValue = incrementStartValue_ + softRange * valueFieldFraction;
|
||||
value_ = clamp(newValue, hardMin_, hardMax_);
|
||||
}
|
||||
else
|
||||
{
|
||||
double screenFractionMultiplier = 1000.0;
|
||||
if (Serialization::TypeID::get<Type>() == Serialization::TypeID::get<float>() ||
|
||||
Serialization::TypeID::get<Type>() == Serialization::TypeID::get<double>())
|
||||
screenFractionMultiplier = 10.0;
|
||||
|
||||
double startPower = log10(fabs(double(incrementStartValue_)) + 1.0) - 3.0;
|
||||
double power = startPower + fabs(screenFraction) * 10.0f;
|
||||
double delta = pow(10.0, power) - pow(10.0, startPower) + screenFractionMultiplier * fabs(screenFraction);
|
||||
double newValue;
|
||||
if (screenFraction > 0.0f)
|
||||
newValue = double(incrementStartValue_) + delta;
|
||||
else
|
||||
newValue = double(incrementStartValue_) - delta;
|
||||
#ifdef _MSC_VER
|
||||
if (_isnan(newValue)) {
|
||||
#else
|
||||
if (isnan(newValue)) {
|
||||
#endif
|
||||
if (screenFraction > 0.0f)
|
||||
newValue = DBL_MAX;
|
||||
else
|
||||
newValue = -DBL_MAX;
|
||||
}
|
||||
value_ = clamp(newValue, hardMin_, hardMax_);
|
||||
}
|
||||
}
|
||||
|
||||
double sliderPosition() const override
|
||||
{
|
||||
if ((softMin_ == std::numeric_limits<Type>::lowest() && softMax_ == std::numeric_limits<Type>::max() && softMax_ != Type(255)) || (softMin_ >= softMax_))
|
||||
return 0.0;
|
||||
return clamp(double(value_ - softMin_) / (softMax_ - softMin_), 0.0, 1.0);
|
||||
}
|
||||
protected:
|
||||
Type incrementStartValue_;
|
||||
Type value_;
|
||||
Type softMin_;
|
||||
Type softMax_;
|
||||
Type hardMin_;
|
||||
Type hardMax_;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWNUMBER_H
|
||||
@@ -1,287 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "QPropertyTreeStyle.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "PropertyRowNumberField.h"
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "MathUtils.h"
|
||||
#include <QStyleOption>
|
||||
#include <QDesktopWidget>
|
||||
#include <QApplication>
|
||||
#include <QPainter>
|
||||
#include <QBitmap>
|
||||
|
||||
PropertyRowNumberField::PropertyRowNumberField()
|
||||
: pressed_(false)
|
||||
, dragStarted_(false)
|
||||
{
|
||||
}
|
||||
|
||||
PropertyRowWidget* PropertyRowNumberField::createWidget(QPropertyTree* tree)
|
||||
{
|
||||
return new PropertyRowWidgetNumber(tree->model(), this, tree);
|
||||
}
|
||||
|
||||
QColor interpolateColor(const QColor& a, const QColor& b, float k);
|
||||
|
||||
void PropertyRowNumberField::redraw(const PropertyDrawContext& context)
|
||||
{
|
||||
if (multiValue())
|
||||
context.drawEntry(L" ... ", false, true, 0);
|
||||
else if (userReadOnly())
|
||||
context.drawValueText(pulledSelected(), valueAsWString().c_str());
|
||||
else
|
||||
{
|
||||
QPainter* painter = context.painter;
|
||||
const QPropertyTree* tree = context.tree;
|
||||
|
||||
QRect rt = context.widgetRect;
|
||||
rt.adjust(0, 0, 0, -1);
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 11, 0))
|
||||
QStyleOptionFrameV2 option;
|
||||
option.features = QStyleOptionFrameV2::None;
|
||||
#else
|
||||
QStyleOptionFrame option;
|
||||
option.features = QStyleOptionFrame::None;
|
||||
#endif
|
||||
|
||||
option.state = QStyle::State_Sunken;
|
||||
|
||||
// We require a widget to use as context, so that the style sheet can work.
|
||||
QLineEdit widgetForContext;
|
||||
option.lineWidth = tree->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &option, &widgetForContext);
|
||||
|
||||
option.midLineWidth = 0;
|
||||
|
||||
if (context.captured) {
|
||||
option.state |= QStyle::State_HasFocus;
|
||||
option.state |= QStyle::State_Active;
|
||||
option.state |= QStyle::State_MouseOver;
|
||||
}
|
||||
else if (!userReadOnly()) {
|
||||
option.state |= QStyle::State_Enabled;
|
||||
}
|
||||
option.rect = rt; // option.rect is the rectangle to be drawn on.
|
||||
option.palette = tree->palette();
|
||||
option.fontMetrics = tree->fontMetrics();
|
||||
QRect textRect = tree->style()->subElementRect(QStyle::SE_LineEditContents, &option, &widgetForContext);
|
||||
if (!textRect.isValid()) {
|
||||
textRect = rt;
|
||||
textRect.adjust(3, 1, -3, -2);
|
||||
}
|
||||
else {
|
||||
textRect.adjust(2, 1, -2, -1);
|
||||
}
|
||||
|
||||
|
||||
widgetForContext.ensurePolished();
|
||||
option.palette = widgetForContext.palette();
|
||||
|
||||
painter->setPen(QPen(widgetForContext.palette().color(QPalette::WindowText)));
|
||||
painter->setBrush(QBrush(widgetForContext.palette().color(QPalette::Base)));
|
||||
tree->style()->drawPrimitive(QStyle::PE_PanelLineEdit, &option, painter, &widgetForContext);
|
||||
|
||||
double sliderPos = sliderPosition();
|
||||
if (sliderPos != 0.0)
|
||||
{
|
||||
QRect r = textRect.adjusted(-2, -1, 2, 1);
|
||||
QRect sliderOverlayRect(r.left(), r.top(), int(r.width() * sliderPos), r.height());
|
||||
QColor sliderOverlayColor = interpolateColor(tree->palette().color(QPalette::Window), tree->palette().color(QPalette::Highlight), tree->treeStyle().sliderSaturation);
|
||||
sliderOverlayColor.setAlpha(192);
|
||||
painter->setBrush(QBrush(sliderOverlayColor));
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->drawRoundedRect(sliderOverlayRect, 1, 1);
|
||||
|
||||
if (pressed_) {
|
||||
painter->setPen(QColor(255, 255, 255));
|
||||
painter->setBrush(QBrush(QColor(255, 255, 255)));
|
||||
painter->drawLine(sliderOverlayRect.right(), sliderOverlayRect.top(), sliderOverlayRect.right(), sliderOverlayRect.bottom());
|
||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
painter->translate(0.5f, 0.5f);
|
||||
int r2 = sliderOverlayRect.right();
|
||||
int t = sliderOverlayRect.top();
|
||||
int h = sliderOverlayRect.height();
|
||||
QPoint points[3] = {
|
||||
QPoint(r2 - 1 - h / 8 - h / 3, t + h / 2),
|
||||
QPoint(r2 - 1 - h / 8, t + h * 1 / 4),
|
||||
QPoint(r2 - 1 - h / 8, t + h * 3 / 4)
|
||||
};
|
||||
QPoint pointsR[3] = {
|
||||
QPoint(r2 + 1 + h / 8 + h / 3, t + h / 2),
|
||||
QPoint(r2 + 1 + h / 8, t + h * 1 / 4),
|
||||
QPoint(r2 + 1 + h / 8, t + h * 3 / 4)
|
||||
};
|
||||
painter->drawPolygon(points, 3);
|
||||
painter->drawPolygon(pointsR, 3);
|
||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||
painter->translate(-0.5f, -0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
painter->setPen(QPen(widgetForContext.palette().color(QPalette::WindowText)));
|
||||
painter->setBrush(QBrush(widgetForContext.palette().color(QPalette::Base)));
|
||||
painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, QString(valueAsString().c_str()));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
QCursor createSliderHoverCursor()
|
||||
{
|
||||
QCursor arrow(Qt::ArrowCursor);
|
||||
QPoint hotSpot = arrow.hotSpot();
|
||||
static QImage image = arrow.pixmap().toImage();
|
||||
if (image.isNull())
|
||||
return QCursor(Qt::SizeHorCursor);
|
||||
|
||||
int w = image.width();
|
||||
int h = image.height();
|
||||
QImage empty(w * 2, h, QImage::Format_ARGB32);
|
||||
empty.fill(Qt::transparent);
|
||||
QPixmap pixmap = QPixmap::fromImage(empty);
|
||||
if (pixmap.isNull())
|
||||
return QCursor(Qt::SizeHorCursor);
|
||||
QPainter p(&pixmap);
|
||||
p.drawImage(image.width() / 2, 0, image);
|
||||
p.setRenderHint(QPainter::Antialiasing, true);
|
||||
|
||||
QPoint points[3] = {
|
||||
QPoint(w / 2 - w * 2 / 8, h / 2),
|
||||
QPoint(w / 2 - w / 8, h * 3 / 8),
|
||||
QPoint(w / 2 - w / 8, h * 5 / 8)
|
||||
};
|
||||
QPoint pointsR[3] = {
|
||||
QPoint(w, h * 3 / 8),
|
||||
QPoint(w, h * 5 / 8),
|
||||
QPoint(w + w / 8, h / 2),
|
||||
};
|
||||
p.setBrush(QBrush(QColor(255, 255, 255)));
|
||||
p.setPen(QPen(QColor(0, 0, 0)));
|
||||
p.drawPolygon(points, 3);
|
||||
p.drawPolygon(pointsR, 3);
|
||||
return QCursor(pixmap, image.width() / 2 + hotSpot.x(), hotSpot.y());
|
||||
}
|
||||
|
||||
|
||||
void PropertyRowNumberField::onMouseDrag(const PropertyDragEvent& e)
|
||||
{
|
||||
if (!dragStarted_) {
|
||||
e.tree->model()->rowAboutToBeChanged(this);
|
||||
dragStarted_ = true;
|
||||
}
|
||||
QSize screenSize = QApplication::desktop()->screenGeometry(e.tree).size();
|
||||
float relativeDelta = float(e.totalDelta.x()) / screenSize.width();
|
||||
int fieldRectWidth = widgetRect(e.tree).width();
|
||||
if (fieldRectWidth < 16)
|
||||
fieldRectWidth = aznumeric_cast<int>(e.tree->treeSize().x() * e.tree->valueColumnWidth());
|
||||
float valueFieldFraction = fieldRectWidth < FLT_EPSILON ? 0 : float(e.totalDelta.x()) / fieldRectWidth;
|
||||
incrementLog(relativeDelta, valueFieldFraction);
|
||||
setMultiValue(false);
|
||||
}
|
||||
|
||||
bool PropertyRowNumberField::getHoverInfo(PropertyHoverInfo* hit, const QPoint& cursorPos, const QPropertyTree* tree) const
|
||||
{
|
||||
if (pressed_ && !userReadOnly())
|
||||
hit->cursor = QCursor(Qt::BlankCursor);
|
||||
else if (widgetRect(tree).contains(cursorPos) && !userReadOnly())
|
||||
hit->cursor = QCursor(createSliderHoverCursor());
|
||||
hit->toolTip = tooltip_;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PropertyRowNumberField::onMouseStill(const PropertyDragEvent& e)
|
||||
{
|
||||
e.tree->model()->callRowCallback(this);
|
||||
e.tree->apply(true);
|
||||
}
|
||||
|
||||
bool PropertyRowNumberField::onMouseDown(QPropertyTree* tree, QPoint point, bool& changed)
|
||||
{
|
||||
changed = false;
|
||||
if (widgetRect(tree).contains(point) && !userReadOnly()) {
|
||||
startIncrement();
|
||||
pressed_ = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PropertyRowNumberField::onMouseUp(QPropertyTree* tree, [[maybe_unused]] QPoint point)
|
||||
{
|
||||
tree->unsetCursor();
|
||||
pressed_ = false;
|
||||
dragStarted_ = false;
|
||||
|
||||
// endIncrement() can cause PropertyRow to be destroy,
|
||||
// so no "this" members should be accessed after the call.
|
||||
endIncrement(tree);
|
||||
}
|
||||
|
||||
bool PropertyRowNumberField::onActivate(const PropertyActivationEvent& e)
|
||||
{
|
||||
if (e.reason == e.REASON_RELEASE || e.reason == e.REASON_DOUBLECLICK)
|
||||
return e.tree->spawnWidget(this, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
int PropertyRowNumberField::widgetSizeMin(const QPropertyTree* tree) const
|
||||
{
|
||||
if (userWidgetSize() >= 0)
|
||||
return userWidgetSize();
|
||||
|
||||
if (userWidgetToContent())
|
||||
return widthCache_.getOrUpdate(tree, this, 0);
|
||||
else
|
||||
return 40;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
PropertyRowWidgetNumber::PropertyRowWidgetNumber([[maybe_unused]] PropertyTreeModel* model, PropertyRowNumberField* row, QPropertyTree* tree)
|
||||
: PropertyRowWidget(row, tree)
|
||||
, row_(row)
|
||||
, entry_(new QLineEdit())
|
||||
, tree_(tree)
|
||||
{
|
||||
entry_->setText(row_->valueAsString().c_str());
|
||||
connect(entry_, SIGNAL(editingFinished()), this, SLOT(onEditingFinished()));
|
||||
connect(entry_, &QLineEdit::textChanged, this, [this, tree] {
|
||||
QFontMetrics fm(entry_->font());
|
||||
int contentWidth = min((int)fm.horizontalAdvance(entry_->text()) + 8, tree->width() - entry_->x());
|
||||
if (contentWidth > entry_->width())
|
||||
entry_->resize(contentWidth, entry_->height());
|
||||
});
|
||||
|
||||
entry_->selectAll();
|
||||
}
|
||||
|
||||
|
||||
void PropertyRowWidgetNumber::onEditingFinished()
|
||||
{
|
||||
tree_->model()->rowAboutToBeChanged(row());
|
||||
string str = entry_->text().toLocal8Bit().data();
|
||||
if (row_->setValueFromString(str.c_str()) || row_->multiValue())
|
||||
tree_->model()->rowChanged(row());
|
||||
else
|
||||
tree_->_cancelWidget();
|
||||
}
|
||||
|
||||
void PropertyRowWidgetNumber::commit()
|
||||
{
|
||||
if (entry_)
|
||||
onEditingFinished();
|
||||
}
|
||||
|
||||
#include <QPropertyTree/moc_PropertyRowNumberField.cpp>
|
||||
@@ -1,75 +0,0 @@
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWNUMBERFIELD_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWNUMBERFIELD_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "PropertyRow.h"
|
||||
#include <QLineEdit>
|
||||
#endif
|
||||
|
||||
class PropertyRowNumberField;
|
||||
class PropertyRowWidgetNumber : public PropertyRowWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PropertyRowWidgetNumber(PropertyTreeModel* mode, PropertyRowNumberField* numberField, QPropertyTree* tree);
|
||||
~PropertyRowWidgetNumber(){
|
||||
if (entry_)
|
||||
entry_->setParent(0);
|
||||
entry_->deleteLater();
|
||||
entry_ = 0;
|
||||
}
|
||||
|
||||
void commit();
|
||||
QWidget* actualWidget() { return entry_; }
|
||||
public slots:
|
||||
void onEditingFinished();
|
||||
protected:
|
||||
QLineEdit* entry_;
|
||||
PropertyRowNumberField* row_;
|
||||
QPropertyTree* tree_;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class PropertyRowNumberField : public PropertyRow
|
||||
{
|
||||
public:
|
||||
PropertyRowNumberField();
|
||||
WidgetPlacement widgetPlacement() const override{ return WIDGET_VALUE; }
|
||||
int widgetSizeMin(const QPropertyTree* tree) const override;
|
||||
|
||||
PropertyRowWidget* createWidget(QPropertyTree* tree) override;
|
||||
bool isLeaf() const override{ return true; }
|
||||
bool isStatic() const override{ return false; }
|
||||
bool inlineInShortArrays() const override{ return true; }
|
||||
void redraw(const PropertyDrawContext& context) override;
|
||||
bool onActivate(const PropertyActivationEvent& e) override;
|
||||
bool onMouseDown(QPropertyTree* tree, QPoint point, bool& changed) override;
|
||||
void onMouseUp(QPropertyTree* tree, QPoint point) override;
|
||||
void onMouseDrag(const PropertyDragEvent& e) override;
|
||||
void onMouseStill(const PropertyDragEvent& e) override;
|
||||
bool getHoverInfo(PropertyHoverInfo* hit, const QPoint& cursorPos, const QPropertyTree* tree) const;
|
||||
|
||||
virtual void startIncrement() = 0;
|
||||
virtual void endIncrement(QPropertyTree* tree) = 0;
|
||||
virtual void incrementLog(float screenFraction, float valueFieldFraction) = 0;
|
||||
virtual bool setValueFromString(const char* str) = 0;
|
||||
virtual double sliderPosition() const = 0;
|
||||
|
||||
mutable RowWidthCache widthCache_;
|
||||
bool pressed_ : 1;
|
||||
bool dragStarted_ : 1;
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWNUMBERFIELD_H
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "PropertyRowObject.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
|
||||
PropertyRowObject::PropertyRowObject()
|
||||
: model_(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool PropertyRowObject::assignTo(Serialization::Object* obj)
|
||||
{
|
||||
if (object_.type() == obj->type())
|
||||
{
|
||||
*obj = object_;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PropertyRowObject::~PropertyRowObject()
|
||||
{
|
||||
object_ = Serialization::Object();
|
||||
}
|
||||
|
||||
void PropertyRowObject::Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
PropertyRow::Serialize(ar);
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWOBJECT_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWOBJECT_H
|
||||
#pragma once
|
||||
#include "PropertyRow.h"
|
||||
#include "Serialization/MemoryWriter.h"
|
||||
#include "Serialization/Pointers.h"
|
||||
#include "Serialization/Object.h"
|
||||
|
||||
namespace Serialization {
|
||||
class IArchive;
|
||||
struct SStruct;
|
||||
class MemoryWriter;
|
||||
};
|
||||
|
||||
class PropertyRowObject
|
||||
: public PropertyRow
|
||||
{
|
||||
public:
|
||||
PropertyRowObject();
|
||||
~PropertyRowObject();
|
||||
|
||||
using PropertyRow::setValueAndContext;
|
||||
using PropertyRow::assignTo;
|
||||
|
||||
void setValueAndContext(const Serialization::Object& obj, [[maybe_unused]] Serialization::IArchive& ar) { object_ = obj; }
|
||||
void setModel(PropertyTreeModel* model) { model_ = model; }
|
||||
bool isObject() const override { return true; }
|
||||
bool assignTo(Serialization::Object* obj);
|
||||
void Serialize(Serialization::IArchive& ar);
|
||||
const Serialization::Object& object() const{ return object_; }
|
||||
protected:
|
||||
|
||||
Serialization::Object object_;
|
||||
PropertyTreeModel* model_;
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWOBJECT_H
|
||||
@@ -1,205 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "PropertyRowOutputFilePath.h"
|
||||
#include "Serialization/ClassFactory.h"
|
||||
#include <Serialization/Decorators/IconXPM.h>
|
||||
#ifndef SERIALIZATION_STANDALONE
|
||||
#include <Include/EditorCoreAPI.h>
|
||||
#include <Util/PathUtil.h> // for Getting game folder
|
||||
#endif
|
||||
#include <QFileDialog>
|
||||
#include <QIcon>
|
||||
#include <QMenu>
|
||||
#include <QKeyEvent>
|
||||
|
||||
OutputFilePathMenuHandler::OutputFilePathMenuHandler(QPropertyTree* tree, PropertyRowOutputFilePath* self)
|
||||
: self(self)
|
||||
, tree(tree)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void OutputFilePathMenuHandler::onMenuClear()
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(self);
|
||||
self->clear();
|
||||
tree->model()->rowChanged(self);
|
||||
}
|
||||
|
||||
QString convertMFCToQtFileFilter(QString* defaultSuffix, const char* mfcFilter)
|
||||
{
|
||||
// convert filter from "All Files|*.*|Text files|*.txt||"
|
||||
// format into "All files (*.*);;Text Files (*.txt)"
|
||||
QString filterMFC = QString::fromLocal8Bit(mfcFilter);
|
||||
QStringList filterItems = filterMFC.split("|");
|
||||
|
||||
if (defaultSuffix && filterItems.size() > 1)
|
||||
{
|
||||
QString extensions = filterItems[1];
|
||||
QRegExp re("\\*\\.(\\w*)");
|
||||
if (extensions.indexOf(re) >= 0)
|
||||
{
|
||||
*defaultSuffix = re.cap(1);
|
||||
}
|
||||
}
|
||||
|
||||
QString filter;
|
||||
for (int i = 0; i < int(filterItems.size()) / 2; ++i)
|
||||
{
|
||||
int bracketPos = filterItems[i].indexOf('(');
|
||||
QString desc = bracketPos >= 0 ? filterItems[i].left(bracketPos) : filterItems[i];
|
||||
int extIndex = i * 2 + 1;
|
||||
if (extIndex >= filterItems.size())
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (!filter.isEmpty())
|
||||
{
|
||||
filter += ";;";
|
||||
}
|
||||
filter += desc;
|
||||
filter += " (";
|
||||
filter += filterItems[extIndex];
|
||||
filter += ")";
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
bool PropertyRowOutputFilePath::onActivate(const PropertyActivationEvent& e)
|
||||
{
|
||||
if (e.reason == e.REASON_RELEASE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#ifndef SERIALIZATION_STANDALONE
|
||||
if (!GetIEditor())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
QString title;
|
||||
if (labelUndecorated())
|
||||
{
|
||||
title = QString("Choose file for '") + labelUndecorated() + "'";
|
||||
}
|
||||
else
|
||||
{
|
||||
title = "Choose file";
|
||||
}
|
||||
|
||||
#ifdef SERIALIZATION_STANDALONE
|
||||
QString gameFolder;
|
||||
#else
|
||||
QString gameFolder = QString::fromLocal8Bit(Path::GetEditingGameDataFolder().c_str());
|
||||
#endif
|
||||
QDir gameFolderDir(QDir::fromNativeSeparators(gameFolder));
|
||||
QString defaultSuffix;
|
||||
QString filter = convertMFCToQtFileFilter(&defaultSuffix, filter_.c_str());
|
||||
QString existingFile = QString::fromLocal8Bit(path_.c_str());
|
||||
|
||||
QString existingFilePath = (existingFile.isEmpty() || QDir::isAbsolutePath(existingFile)) ? existingFile : gameFolderDir.absoluteFilePath(existingFile);
|
||||
QString startFolder = QString::fromLocal8Bit(startFolder_.c_str());
|
||||
|
||||
// Not using QFileDialog().exec() as it implements custom file dialog that
|
||||
// freezes for couple of seconds when being open. Scannign network drives?
|
||||
QString result = QFileDialog::getSaveFileName(e.tree, title, existingFilePath.isEmpty() ? (gameFolder + "/" + startFolder) : existingFilePath, filter);
|
||||
if (!result.isEmpty())
|
||||
{
|
||||
e.tree->model()->rowAboutToBeChanged(this);
|
||||
QString relativeFilename = gameFolderDir.relativeFilePath(result);
|
||||
path_ = relativeFilename.toLocal8Bit().data();
|
||||
e.tree->model()->rowChanged(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void PropertyRowOutputFilePath::setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar)
|
||||
{
|
||||
OutputFilePath* value = (OutputFilePath*)ser.pointer();
|
||||
path_ = value->m_path->c_str();
|
||||
filter_ = value->filter.c_str();
|
||||
startFolder_ = value->startFolder.c_str();
|
||||
handle_ = value->m_path;
|
||||
}
|
||||
|
||||
bool PropertyRowOutputFilePath::assignTo(const Serialization::SStruct& ser) const
|
||||
{
|
||||
((OutputFilePath*)ser.pointer())->SetPath(path_.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
const QIcon& PropertyRowOutputFilePath::buttonIcon(const QPropertyTree* tree, [[maybe_unused]] int index) const
|
||||
{
|
||||
#include "file_save.xpm"
|
||||
static QIcon fileOpenIcon = QIcon(QPixmap::fromImage(*tree->_iconCache()->getImageForIcon(Serialization::IconXPM(file_save_xpm))));
|
||||
return fileOpenIcon;
|
||||
}
|
||||
|
||||
string PropertyRowOutputFilePath::valueAsString() const
|
||||
{
|
||||
return path_;
|
||||
}
|
||||
|
||||
|
||||
void PropertyRowOutputFilePath::clear()
|
||||
{
|
||||
path_.clear();
|
||||
}
|
||||
|
||||
bool PropertyRowOutputFilePath::onContextMenu(QMenu& menu, QPropertyTree* tree)
|
||||
{
|
||||
QAction* action = menu.addAction("Clear");
|
||||
Serialization::SharedPtr<PropertyRow> selfPointer(this);
|
||||
|
||||
OutputFilePathMenuHandler* handler = new OutputFilePathMenuHandler(tree, this);
|
||||
QObject::connect(action, SIGNAL(triggered()), handler, SLOT(onMenuClear()));
|
||||
tree->addMenuHandler(handler);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PropertyRowOutputFilePath::serializeValue(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(path_, "path");
|
||||
ar(filter_, "filter");
|
||||
ar(startFolder_, "startFolder");
|
||||
}
|
||||
|
||||
bool PropertyRowOutputFilePath::processesKey(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (ev->key() == Qt::Key_Delete)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return PropertyRowField::processesKey(tree, ev);
|
||||
}
|
||||
|
||||
bool PropertyRowOutputFilePath::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (ev->key() == Qt::Key_Delete)
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
clear();
|
||||
tree->model()->rowChanged(this);
|
||||
return true;
|
||||
}
|
||||
return PropertyRowField::onKeyDown(tree, ev);
|
||||
}
|
||||
|
||||
REGISTER_PROPERTY_ROW(OutputFilePath, PropertyRowOutputFilePath);
|
||||
DECLARE_SEGMENT(PropertyRowOutputFilePath)
|
||||
|
||||
#include <QPropertyTree/moc_PropertyRowOutputFilePath.cpp>
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWOUTPUTFILEPATH_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWOUTPUTFILEPATH_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "PropertyRowField.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "Serialization.h"
|
||||
#include <Serialization/Decorators/OutputFilePath.h>
|
||||
#include <Serialization/Decorators/OutputFilePathImpl.h>
|
||||
#endif
|
||||
|
||||
using Serialization::OutputFilePath;
|
||||
|
||||
class PropertyRowOutputFilePath
|
||||
: public PropertyRowField
|
||||
{
|
||||
public:
|
||||
void clear();
|
||||
|
||||
bool isLeaf() const override { return true; }
|
||||
bool isStatic() const override { return false; }
|
||||
|
||||
bool onActivate(const PropertyActivationEvent& e) override;
|
||||
void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override;
|
||||
bool assignTo(const Serialization::SStruct& ser) const override;
|
||||
string valueAsString() const;
|
||||
void serializeValue(Serialization::IArchive& ar);
|
||||
bool onContextMenu(QMenu& menu, QPropertyTree* tree);
|
||||
const void* searchHandle() const { return handle_; }
|
||||
|
||||
int buttonCount() const override { return 1; }
|
||||
virtual const QIcon& buttonIcon(const QPropertyTree* tree, int index) const override;
|
||||
virtual bool usePathEllipsis() const override { return true; }
|
||||
|
||||
bool processesKey(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
|
||||
private:
|
||||
string path_;
|
||||
string filter_;
|
||||
string startFolder_;
|
||||
const void* handle_;
|
||||
};
|
||||
|
||||
struct OutputFilePathMenuHandler
|
||||
: PropertyRowMenuHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QPropertyTree * tree;
|
||||
PropertyRowOutputFilePath* self;
|
||||
|
||||
OutputFilePathMenuHandler(QPropertyTree* tree, PropertyRowOutputFilePath* container);
|
||||
public slots:
|
||||
void onMenuClear();
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWOUTPUTFILEPATH_H
|
||||
@@ -1,346 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "PropertyRowPointer.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "Serialization.h"
|
||||
#include "Unicode.h"
|
||||
#include <QMenu>
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void ClassMenuItemAdder::generateMenu(QMenu& createItem, const StringList& comboStrings)
|
||||
{
|
||||
StringList::const_iterator it;
|
||||
int index = 0;
|
||||
for (it = comboStrings.begin(); it != comboStrings.end(); ++it)
|
||||
{
|
||||
StringList path;
|
||||
splitStringList(&path, it->c_str(), '\\');
|
||||
QMenu* item = &createItem;
|
||||
//createItem.addMenu(
|
||||
for (int level2 = 0; level2 < int(path.size()); ++level2)
|
||||
{
|
||||
const char* leaf = path[level2].c_str();
|
||||
if (level2 == path.size() - 1)
|
||||
{
|
||||
addAction(*item, leaf, index++);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (QMenu* menu = item->findChild<QMenu*>(leaf))
|
||||
{
|
||||
item = menu;
|
||||
}
|
||||
else
|
||||
{
|
||||
item = addMenu(*item, leaf); //&item->add(leaf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClassMenuItemAdder::addAction(QMenu& menu, const char* text, [[maybe_unused]] int index)
|
||||
{
|
||||
menu.addAction(text)->setEnabled(false);
|
||||
}
|
||||
|
||||
QMenu* ClassMenuItemAdder::addMenu(QMenu& menu, const char* text)
|
||||
{
|
||||
QMenu* result = menu.addMenu(text);
|
||||
result->setObjectName(text);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
SERIALIZATION_CLASS_NAME(PropertyRow, PropertyRowPointer, "PropertyRowPointer", "SharedPtr");
|
||||
|
||||
PropertyRowPointer::PropertyRowPointer()
|
||||
: factory_(0)
|
||||
, searchHandle_(0)
|
||||
, colorOverride_(0, 0, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
void PropertyRowPointer::setDerivedType(const char* typeName, Serialization::IClassFactory* factory)
|
||||
{
|
||||
if (!factory)
|
||||
{
|
||||
derivedTypeName_.clear();
|
||||
return;
|
||||
}
|
||||
derivedTypeName_ = typeName;
|
||||
}
|
||||
|
||||
bool PropertyRowPointer::assignTo(Serialization::IPointer& ptr)
|
||||
{
|
||||
if (derivedTypeName_ != ptr.registeredTypeName())
|
||||
{
|
||||
ptr.create(derivedTypeName_.c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CreatePointerMenuHandler::onMenuCreateByIndex()
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(row);
|
||||
if (index < 0) // NULL value
|
||||
{
|
||||
row->setDerivedType("", 0);
|
||||
row->clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
const PropertyDefaultDerivedTypeValue* defaultValue = tree->model()->defaultType(row->baseType(), index);
|
||||
SharedPtr<PropertyRow> clonedDefault = defaultValue->root->clone(tree->model()->constStrings());
|
||||
if (defaultValue && defaultValue->root)
|
||||
{
|
||||
YASLI_ASSERT(defaultValue->root->refCount() == 1);
|
||||
if (useDefaultValue)
|
||||
{
|
||||
row->clear();
|
||||
row->swapChildren(clonedDefault, 0);
|
||||
}
|
||||
row->setDerivedType(defaultValue->registeredName.c_str(), row->factory());
|
||||
row->setLabelChanged();
|
||||
row->setLabelChangedToChildren();
|
||||
tree->expandRow(row);
|
||||
}
|
||||
else
|
||||
{
|
||||
row->setDerivedType("", 0);
|
||||
row->clear();
|
||||
}
|
||||
}
|
||||
tree->model()->rowChanged(row);
|
||||
}
|
||||
|
||||
|
||||
string PropertyRowPointer::valueAsString() const
|
||||
{
|
||||
string result;
|
||||
const Serialization::TypeDescription* desc = 0;
|
||||
if (factory_)
|
||||
{
|
||||
desc = factory_->descriptionByRegisteredName(derivedTypeName_.c_str());
|
||||
}
|
||||
if (desc)
|
||||
{
|
||||
result = desc->label();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = derivedTypeName_;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
wstring PropertyRowPointer::generateLabel() const
|
||||
{
|
||||
if (multiValue())
|
||||
{
|
||||
return L"...";
|
||||
}
|
||||
|
||||
wstring str;
|
||||
if (!derivedTypeName_.empty())
|
||||
{
|
||||
const char* textStart = derivedTypeName_.c_str();
|
||||
if (factory_)
|
||||
{
|
||||
const Serialization::TypeDescription* desc = factory_->descriptionByRegisteredName(derivedTypeName_.c_str());
|
||||
|
||||
if (desc)
|
||||
{
|
||||
textStart = desc->label();
|
||||
}
|
||||
}
|
||||
const char* p = textStart + strlen(textStart);
|
||||
while (p > textStart)
|
||||
{
|
||||
if (*(p - 1) == '\\')
|
||||
{
|
||||
break;
|
||||
}
|
||||
--p;
|
||||
}
|
||||
str = toWideChar(p);
|
||||
if (p != textStart)
|
||||
{
|
||||
str += L" (";
|
||||
str += toWideChar(string(textStart, p - 1).c_str());
|
||||
str += L")";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (factory_)
|
||||
{
|
||||
str = toWideChar(factory_->nullLabel() ? factory_->nullLabel() : "[ null ]");
|
||||
}
|
||||
else
|
||||
{
|
||||
str = L"[ null ]";
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
void PropertyRowPointer::redraw(const PropertyDrawContext& context)
|
||||
{
|
||||
QRect widgetRect = context.widgetRect;
|
||||
QRect rt = widgetRect;
|
||||
rt.adjust(-1, 0, 0, 1);
|
||||
wstring str = generateLabel();
|
||||
const QFont* font = derivedTypeName_.empty() ? &context.tree->font() : &context.tree->_boldFont();
|
||||
int buttonFlags = BUTTON_POPUP_ARROW;
|
||||
if (userReadOnly())
|
||||
{
|
||||
buttonFlags |= BUTTON_DISABLED;
|
||||
}
|
||||
if (context.m_pressed)
|
||||
{
|
||||
buttonFlags |= BUTTON_PRESSED;
|
||||
}
|
||||
context.drawButton(rt, str.c_str(), buttonFlags, font, colorOverride_.a != 0 ? &colorOverride_ : 0);
|
||||
}
|
||||
|
||||
struct ClassMenuItemAdderRowPointer
|
||||
: ClassMenuItemAdder
|
||||
{
|
||||
ClassMenuItemAdderRowPointer(PropertyRowPointer* row, QPropertyTree* tree)
|
||||
: row_(row)
|
||||
, tree_(tree) {}
|
||||
void addAction(QMenu& menu, const char* text, int index)
|
||||
{
|
||||
CreatePointerMenuHandler* handler = new CreatePointerMenuHandler;
|
||||
tree_->addMenuHandler(handler);
|
||||
handler->row = row_;
|
||||
handler->tree = tree_;
|
||||
handler->index = index;
|
||||
handler->useDefaultValue = !tree_->immediateUpdate();
|
||||
|
||||
QAction* action = menu.addAction(text);
|
||||
|
||||
QObject::connect(action, SIGNAL(triggered()), handler, SLOT(onMenuCreateByIndex()));
|
||||
}
|
||||
protected:
|
||||
PropertyRowPointer* row_;
|
||||
QPropertyTree* tree_;
|
||||
};
|
||||
|
||||
|
||||
bool PropertyRowPointer::onActivate(QPropertyTree* tree, [[maybe_unused]] bool force)
|
||||
{
|
||||
if (userReadOnly())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
QMenu menu;
|
||||
ClassMenuItemAdderRowPointer(this, tree).generateMenu(menu, tree->model()->typeStringList(baseType()));
|
||||
tree->_setPressedRow(this);
|
||||
menu.exec(tree->_toScreen(QPoint(widgetPos_, pos_.y() + tree->_defaultRowHeight())));
|
||||
tree->_setPressedRow(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyRowPointer::onMouseDown(QPropertyTree* tree, QPoint point, bool& changed)
|
||||
{
|
||||
if (widgetRect(tree).contains(point))
|
||||
{
|
||||
if (onActivate(tree, false))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyRowPointer::onContextMenu(QMenu& menu, QPropertyTree* tree)
|
||||
{
|
||||
if (!menu.isEmpty())
|
||||
{
|
||||
menu.addSeparator();
|
||||
}
|
||||
if (!userReadOnly())
|
||||
{
|
||||
QMenu* createItem = menu.addMenu("Set");
|
||||
ClassMenuItemAdderRowPointer(this, tree).generateMenu(*createItem, tree->model()->typeStringList(baseType()));
|
||||
}
|
||||
return PropertyRow::onContextMenu(menu, tree);
|
||||
}
|
||||
|
||||
void PropertyRowPointer::serializeValue(IArchive& ar)
|
||||
{
|
||||
ar(derivedTypeName_, "derivedTypeName", "Derived Type Name");
|
||||
}
|
||||
|
||||
int PropertyRowPointer::widgetSizeMin(const QPropertyTree* tree) const
|
||||
{
|
||||
QFontMetrics fm(tree->_boldFont());
|
||||
QString str(fromWideChar(generateLabel().c_str()).c_str());
|
||||
return fm.horizontalAdvance(str) + 24;
|
||||
}
|
||||
|
||||
static Color parseColorString(const char* str)
|
||||
{
|
||||
unsigned int color = 0;
|
||||
if (azsscanf(str, "%x", &color) != 1)
|
||||
{
|
||||
return Color(0, 0, 0, 0);
|
||||
}
|
||||
Color result((color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, 255);
|
||||
return result;
|
||||
}
|
||||
|
||||
void PropertyRowPointer::setValueAndContext(const Serialization::IPointer& ptr, [[maybe_unused]] Serialization::IArchive& ar)
|
||||
{
|
||||
baseType_ = ptr.baseType();
|
||||
factory_ = ptr.factory();
|
||||
serializer_ = ptr.serializer();
|
||||
pointerType_ = ptr.pointerType();
|
||||
searchHandle_ = ptr.handle();
|
||||
|
||||
const char* colorString = factory_->findAnnotation(ptr.registeredTypeName(), "color");
|
||||
if (colorString[0] != '\0')
|
||||
{
|
||||
colorOverride_ = parseColorString(colorString);
|
||||
}
|
||||
else
|
||||
{
|
||||
colorOverride_ = Color(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
const Serialization::TypeDescription* desc = factory_->descriptionByRegisteredName(ptr.registeredTypeName());
|
||||
if (desc)
|
||||
{
|
||||
derivedTypeName_ = desc->name();
|
||||
}
|
||||
else
|
||||
{
|
||||
derivedTypeName_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
#include <QPropertyTree/moc_PropertyRowPointer.cpp>
|
||||
// vim:ts=4 sw=4:
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWPOINTER_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWPOINTER_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "Color.h"
|
||||
#include "Serialization/StringList.h"
|
||||
using Serialization::StringList;
|
||||
|
||||
#include "PropertyRow.h"
|
||||
#endif
|
||||
|
||||
class QPropertyTree;
|
||||
class PropertyRowPointer;
|
||||
struct CreatePointerMenuHandler
|
||||
: PropertyRowMenuHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QPropertyTree * tree;
|
||||
PropertyRowPointer* row;
|
||||
int index;
|
||||
bool useDefaultValue;
|
||||
public slots:
|
||||
void onMenuCreateByIndex();
|
||||
};
|
||||
|
||||
class QMenu;
|
||||
struct ClassMenuItemAdder
|
||||
{
|
||||
virtual void addAction(QMenu& menu, const char* text, int index);
|
||||
virtual QMenu* addMenu(QMenu& menu, const char* text);
|
||||
void generateMenu(QMenu& createItem, const StringList& comboStrings);
|
||||
};
|
||||
|
||||
class PropertyRowPointer
|
||||
: public PropertyRow
|
||||
{
|
||||
public:
|
||||
PropertyRowPointer();
|
||||
|
||||
bool assignTo(Serialization::IPointer& ptr);
|
||||
void setValueAndContext(const Serialization::IPointer& ptr, Serialization::IArchive& ar);
|
||||
using PropertyRow::assignTo;
|
||||
using PropertyRow::setValueAndContext;
|
||||
using PropertyRow::onActivate;
|
||||
|
||||
Serialization::TypeID baseType() const{ return baseType_; }
|
||||
void setBaseType(const Serialization::TypeID& baseType) { baseType_ = baseType; }
|
||||
const char* derivedTypeName() const{ return derivedTypeName_.c_str(); }
|
||||
void setDerivedType(const char* typeName, Serialization::IClassFactory* factory);
|
||||
void setFactory(Serialization::IClassFactory* factory) { factory_ = factory; }
|
||||
Serialization::IClassFactory* factory() const{ return factory_; }
|
||||
bool onActivate(QPropertyTree* tree, bool force);
|
||||
bool onMouseDown(QPropertyTree* tree, QPoint point, bool& changed);
|
||||
bool onContextMenu(QMenu& root, QPropertyTree* tree);
|
||||
bool isStatic() const{ return false; }
|
||||
bool isPointer() const{ return true; }
|
||||
int widgetSizeMin(const QPropertyTree* tree) const override;
|
||||
wstring generateLabel() const;
|
||||
string valueAsString() const;
|
||||
const char* typeNameForFilter([[maybe_unused]] QPropertyTree* tree) const override { return baseType_.name(); }
|
||||
void redraw(const PropertyDrawContext& context);
|
||||
WidgetPlacement widgetPlacement() const{ return WIDGET_VALUE; }
|
||||
void serializeValue(Serialization::IArchive& ar);
|
||||
const void* searchHandle() const override { return searchHandle_; }
|
||||
Serialization::TypeID typeId() const override { return pointerType_; }
|
||||
protected:
|
||||
|
||||
Serialization::TypeID baseType_;
|
||||
string derivedTypeName_;
|
||||
string derivedLabel_;
|
||||
|
||||
// this member is available for instances deserialized from clipboard:
|
||||
Serialization::IClassFactory* factory_;
|
||||
const void* searchHandle_;
|
||||
Serialization::TypeID pointerType_;
|
||||
Color colorOverride_;
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWPOINTER_H
|
||||
@@ -1,177 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
|
||||
#include "PropertyRowResourceFilePath.h"
|
||||
#include "Serialization/ClassFactory.h"
|
||||
#include <Include/EditorCoreAPI.h>
|
||||
#include <QMenu>
|
||||
#include <QFileDialog>
|
||||
#include <QIcon>
|
||||
#include <QKeyEvent>
|
||||
#include <Util/PathUtil.h> // for getting game folder.
|
||||
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetSelectionModel.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
|
||||
|
||||
ResourceFilePathMenuHandler::ResourceFilePathMenuHandler(QPropertyTree* tree, PropertyRowResourceFilePath* self)
|
||||
: self(self)
|
||||
, tree(tree)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ResourceFilePathMenuHandler::onMenuClear()
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(self);
|
||||
self->clear();
|
||||
tree->model()->rowChanged(self);
|
||||
}
|
||||
|
||||
// Get filename relative to the asset folder,
|
||||
// whether it came from the project or from a gem
|
||||
QString AssetRelativePathFromAbsolutePath(const QString& absPath)
|
||||
{
|
||||
return Path::FullPathToGamePath(absPath);
|
||||
}
|
||||
|
||||
bool PropertyRowResourceFilePath::onActivate(const PropertyActivationEvent& e)
|
||||
{
|
||||
using namespace AzToolsFramework::AssetBrowser;
|
||||
|
||||
if (e.reason == e.REASON_RELEASE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AssetSelectionModel selection;
|
||||
if (m_group)
|
||||
{
|
||||
selection = AssetSelectionModel::AssetGroupSelection(filter_);
|
||||
}
|
||||
else
|
||||
{
|
||||
selection = AssetSelectionModel::AssetTypeSelection(filter_);
|
||||
}
|
||||
|
||||
AzToolsFramework::EditorRequests::Bus::Broadcast(&AzToolsFramework::EditorRequests::BrowseForAssets, selection);
|
||||
if (!selection.IsValid())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
auto product = azrtti_cast<const ProductAssetBrowserEntry*>(selection.GetResult());
|
||||
if (!product)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
AZStd::string relativeFilename = product->GetRelativePath();
|
||||
|
||||
if (flags_ & ResourceFilePath::STRIP_EXTENSION)
|
||||
{
|
||||
size_t ext = relativeFilename.rfind('.');
|
||||
if (ext != relativeFilename.npos)
|
||||
{
|
||||
relativeFilename.erase(ext, relativeFilename.length() - ext);
|
||||
}
|
||||
}
|
||||
|
||||
e.tree->model()->rowAboutToBeChanged(this);
|
||||
path_ = relativeFilename.c_str();
|
||||
e.tree->model()->rowChanged(this);
|
||||
return true;
|
||||
}
|
||||
void PropertyRowResourceFilePath::setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar)
|
||||
{
|
||||
ResourceFilePath* value = (ResourceFilePath*)ser.pointer();
|
||||
filter_ = value->filter.c_str();
|
||||
path_ = value->m_path->c_str();
|
||||
flags_ = value->flags;
|
||||
handle_ = value->m_path;
|
||||
m_group = value->group;
|
||||
}
|
||||
|
||||
bool PropertyRowResourceFilePath::assignTo(const Serialization::SStruct& ser) const
|
||||
{
|
||||
((ResourceFilePath*)ser.pointer())->SetPath(path_.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void PropertyRowResourceFilePath::serializeValue(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(filter_, "filter");
|
||||
ar(path_, "path");
|
||||
ar(startFolder_, "startFolder");
|
||||
ar(m_group, "group");
|
||||
}
|
||||
|
||||
const QIcon& PropertyRowResourceFilePath::buttonIcon(const QPropertyTree* tree, [[maybe_unused]] int index) const
|
||||
{
|
||||
#include "file_open.xpm"
|
||||
static QIcon fileOpenIcon = QIcon(QPixmap::fromImage(*tree->_iconCache()->getImageForIcon(Serialization::IconXPM(file_open_xpm))));
|
||||
return fileOpenIcon;
|
||||
}
|
||||
|
||||
string PropertyRowResourceFilePath::valueAsString() const
|
||||
{
|
||||
return path_;
|
||||
}
|
||||
|
||||
|
||||
void PropertyRowResourceFilePath::clear()
|
||||
{
|
||||
path_.clear();
|
||||
}
|
||||
|
||||
bool PropertyRowResourceFilePath::onContextMenu(QMenu& menu, QPropertyTree* tree)
|
||||
{
|
||||
QAction* action = menu.addAction("Clear");
|
||||
Serialization::SharedPtr<PropertyRow> selfPointer(this);
|
||||
|
||||
ResourceFilePathMenuHandler* handler = new ResourceFilePathMenuHandler(tree, this);
|
||||
QObject::connect(action, SIGNAL(triggered()), handler, SLOT(onMenuClear()));
|
||||
tree->addMenuHandler(handler);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyRowResourceFilePath::processesKey(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (ev->key() == Qt::Key_Delete)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return PropertyRowField::processesKey(tree, ev);
|
||||
}
|
||||
|
||||
bool PropertyRowResourceFilePath::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (ev->key() == Qt::Key_Delete)
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
clear();
|
||||
tree->model()->rowChanged(this);
|
||||
return true;
|
||||
}
|
||||
return PropertyRowField::onKeyDown(tree, ev);
|
||||
}
|
||||
|
||||
REGISTER_PROPERTY_ROW(ResourceFilePath, PropertyRowResourceFilePath);
|
||||
DECLARE_SEGMENT(PropertyRowResourceFilePath)
|
||||
|
||||
#include <QPropertyTree/moc_PropertyRowResourceFilePath.cpp>
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCEFILEPATH_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCEFILEPATH_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "PropertyRowField.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "Serialization.h"
|
||||
#include <Serialization/Decorators/ResourceFilePath.h>
|
||||
#include <Serialization/Decorators/ResourceFilePathImpl.h>
|
||||
#include <Serialization/Decorators/IconXPM.h>
|
||||
#endif
|
||||
|
||||
using Serialization::ResourceFilePath;
|
||||
|
||||
class PropertyRowResourceFilePath
|
||||
: public PropertyRowField
|
||||
{
|
||||
public:
|
||||
void clear();
|
||||
|
||||
bool isLeaf() const override { return true; }
|
||||
bool isStatic() const override { return false; }
|
||||
|
||||
void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override;
|
||||
bool assignTo(const Serialization::SStruct& ser) const override;
|
||||
bool onActivate(const PropertyActivationEvent& e) override;
|
||||
|
||||
int buttonCount() const override { return 1; }
|
||||
virtual const QIcon& buttonIcon(const QPropertyTree* tree, int index) const override;
|
||||
virtual bool usePathEllipsis() const override { return true; }
|
||||
string valueAsString() const;
|
||||
void serializeValue(Serialization::IArchive& ar);
|
||||
const void* searchHandle() const override { return handle_; }
|
||||
Serialization::TypeID typeId() const override { return Serialization::TypeID::get<string>(); }
|
||||
|
||||
bool onContextMenu(QMenu& menu, QPropertyTree* tree);
|
||||
|
||||
bool processesKey(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
|
||||
private:
|
||||
string filter_;
|
||||
string path_;
|
||||
string startFolder_;
|
||||
bool m_group;
|
||||
int flags_;
|
||||
const void* handle_;
|
||||
};
|
||||
|
||||
struct ResourceFilePathMenuHandler
|
||||
: PropertyRowMenuHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QPropertyTree * tree;
|
||||
PropertyRowResourceFilePath* self;
|
||||
|
||||
ResourceFilePathMenuHandler(QPropertyTree* tree, PropertyRowResourceFilePath* container);
|
||||
public slots:
|
||||
void onMenuClear();
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCEFILEPATH_H
|
||||
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include <Serialization/Decorators/IconXPM.h>
|
||||
#include "PropertyRowResourceFolderPath.h"
|
||||
#include "Serialization/ClassFactory.h"
|
||||
#include <Include/EditorCoreAPI.h>
|
||||
#include <QMenu>
|
||||
#include <QKeyEvent>
|
||||
#include <Util/PathUtil.h>
|
||||
|
||||
ResourceFolderPathMenuHandler::ResourceFolderPathMenuHandler(QPropertyTree* tree, PropertyRowResourceFolderPath* self)
|
||||
: self(self)
|
||||
, tree(tree)
|
||||
{
|
||||
}
|
||||
|
||||
void ResourceFolderPathMenuHandler::onMenuClear()
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(self);
|
||||
self->clear();
|
||||
tree->model()->rowChanged(self);
|
||||
}
|
||||
|
||||
bool PropertyRowResourceFolderPath::onActivate(const PropertyActivationEvent& e)
|
||||
{
|
||||
if (e.reason == e.REASON_RELEASE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!GetIEditor())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (userReadOnly())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QString title;
|
||||
if (labelUndecorated() && labelUndecorated()[0] != '\0')
|
||||
{
|
||||
title = QString("Choose folder for '") + QString::fromLocal8Bit(labelUndecorated()) + "'";
|
||||
}
|
||||
else
|
||||
{
|
||||
title = "Choose folder";
|
||||
}
|
||||
|
||||
QString gameFolder = QString::fromLocal8Bit(Path::GetEditingGameDataFolder().c_str());
|
||||
QString startFolder = gameFolder + QDir::separator();
|
||||
|
||||
if (path_.empty() || !QDir().exists(startFolder))
|
||||
{
|
||||
startFolder += QString::fromLocal8Bit(startFolder_.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
startFolder += QString::fromLocal8Bit(path_.c_str());
|
||||
}
|
||||
|
||||
QString filename = QFileDialog::getExistingDirectory(e.tree, title, startFolder, QFileDialog::ShowDirsOnly);
|
||||
if (filename.isEmpty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
e.tree->model()->rowAboutToBeChanged(this);
|
||||
QString result = QDir(gameFolder).relativeFilePath(filename);
|
||||
path_ = result.toLocal8Bit().data();
|
||||
e.tree->model()->rowChanged(this);
|
||||
return true;
|
||||
}
|
||||
void PropertyRowResourceFolderPath::setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar)
|
||||
{
|
||||
ResourceFolderPath* value = (ResourceFolderPath*)(ser.pointer());
|
||||
path_ = value->m_path->c_str();
|
||||
startFolder_ = value->startFolder.c_str();
|
||||
handle_ = value->m_path;
|
||||
}
|
||||
|
||||
bool PropertyRowResourceFolderPath::assignTo(const Serialization::SStruct& ser) const
|
||||
{
|
||||
((ResourceFolderPath*)ser.pointer())->SetPath(path_.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
const QIcon& PropertyRowResourceFolderPath::buttonIcon(const QPropertyTree* tree, [[maybe_unused]] int index) const
|
||||
{
|
||||
#include "file_open.xpm"
|
||||
static QIcon fileOpenIcon = QIcon(QPixmap::fromImage(*tree->_iconCache()->getImageForIcon(Serialization::IconXPM(file_open_xpm))));
|
||||
return fileOpenIcon;
|
||||
}
|
||||
|
||||
string PropertyRowResourceFolderPath::valueAsString() const
|
||||
{
|
||||
return path_;
|
||||
}
|
||||
|
||||
void PropertyRowResourceFolderPath::clear()
|
||||
{
|
||||
path_.clear();
|
||||
}
|
||||
|
||||
void PropertyRowResourceFolderPath::serializeValue(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(path_, "path");
|
||||
ar(startFolder_, "startFolder");
|
||||
}
|
||||
|
||||
bool PropertyRowResourceFolderPath::onContextMenu(QMenu& menu, QPropertyTree* tree)
|
||||
{
|
||||
ResourceFolderPathMenuHandler* handler = new ResourceFolderPathMenuHandler(tree, this);
|
||||
QAction* action = menu.addAction("Clear", handler, SLOT(onMenuClear()));
|
||||
action->setEnabled(!userReadOnly());
|
||||
SharedPtr<PropertyRow> selfPointer(this);
|
||||
|
||||
tree->addMenuHandler(handler);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyRowResourceFolderPath::processesKey(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (ev->key() == Qt::Key_Delete)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return PropertyRowField::processesKey(tree, ev);
|
||||
}
|
||||
|
||||
bool PropertyRowResourceFolderPath::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (ev->key() == Qt::Key_Delete)
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
clear();
|
||||
tree->model()->rowChanged(this);
|
||||
return true;
|
||||
}
|
||||
return PropertyRowField::onKeyDown(tree, ev);
|
||||
}
|
||||
|
||||
REGISTER_PROPERTY_ROW(ResourceFolderPath, PropertyRowResourceFolderPath);
|
||||
DECLARE_SEGMENT(PropertyRowResourceFolderPath)
|
||||
|
||||
#include <QPropertyTree/moc_PropertyRowResourceFolderPath.cpp>
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCEFOLDERPATH_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCEFOLDERPATH_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "PropertyRowImpl.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "Serialization.h"
|
||||
#include <Serialization/Decorators/ResourceFolderPath.h>
|
||||
#include <Serialization/Decorators/ResourceFolderPathImpl.h>
|
||||
#include <QFileDialog>
|
||||
#include <QtGui/QIcon>
|
||||
#endif
|
||||
|
||||
using Serialization::ResourceFolderPath;
|
||||
|
||||
class PropertyRowResourceFolderPath
|
||||
: public PropertyRowField
|
||||
{
|
||||
public:
|
||||
PropertyRowResourceFolderPath()
|
||||
: handle_() {}
|
||||
bool isLeaf() const override { return true; }
|
||||
bool isStatic() const override { return false; }
|
||||
bool onActivate(const PropertyActivationEvent& e) override;
|
||||
void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override;
|
||||
bool assignTo(const Serialization::SStruct& ser) const override;
|
||||
string valueAsString() const;
|
||||
bool onContextMenu(QMenu& menu, QPropertyTree* tree);
|
||||
|
||||
int buttonCount() const override { return 1; }
|
||||
virtual const QIcon& buttonIcon(const QPropertyTree* tree, int index) const override;
|
||||
virtual bool usePathEllipsis() const override { return true; }
|
||||
void serializeValue(Serialization::IArchive& ar) override;
|
||||
const void* searchHandle() const override { return handle_; }
|
||||
Serialization::TypeID typeId() const override { return Serialization::TypeID::get<string>(); }
|
||||
void clear();
|
||||
|
||||
bool processesKey(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
|
||||
private:
|
||||
string path_;
|
||||
string startFolder_;
|
||||
const void* handle_;
|
||||
};
|
||||
|
||||
struct ResourceFolderPathMenuHandler
|
||||
: PropertyRowMenuHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QPropertyTree * tree;
|
||||
PropertyRowResourceFolderPath* self;
|
||||
|
||||
ResourceFolderPathMenuHandler(QPropertyTree* tree, PropertyRowResourceFolderPath* container);
|
||||
public slots:
|
||||
void onMenuClear();
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCEFOLDERPATH_H
|
||||
@@ -1,425 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "PropertyRowResourceSelector.h"
|
||||
#include "Serialization/ClassFactory.h"
|
||||
#include "Serialization/Decorators/Resources.h"
|
||||
#include "Serialization/Decorators/INavigationProvider.h"
|
||||
#include "Serialization/Decorators/IconXPM.h"
|
||||
#include <Include/EditorCoreAPI.h>
|
||||
#include "IEditor.h"
|
||||
#include <QMenu>
|
||||
#include <QFileDialog>
|
||||
#include <QIcon>
|
||||
#include <QKeyEvent>
|
||||
#include <Util/PathUtil.h>
|
||||
|
||||
enum Button
|
||||
{
|
||||
BUTTON_PICK,
|
||||
BUTTON_CREATE
|
||||
};
|
||||
|
||||
ResourceSelectorMenuHandler::ResourceSelectorMenuHandler(QPropertyTree* tree, PropertyRowResourceSelector* self)
|
||||
: self(self)
|
||||
, tree(tree)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ResourceSelectorMenuHandler::onMenuClear()
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(self);
|
||||
self->clear();
|
||||
tree->model()->rowChanged(self);
|
||||
}
|
||||
|
||||
void ResourceSelectorMenuHandler::onMenuPickResource()
|
||||
{
|
||||
self->pickResource(tree);
|
||||
}
|
||||
|
||||
void ResourceSelectorMenuHandler::onMenuCreateFile()
|
||||
{
|
||||
self->createFile(tree);
|
||||
}
|
||||
|
||||
void ResourceSelectorMenuHandler::onMenuJumpTo()
|
||||
{
|
||||
self->jumpTo(tree);
|
||||
}
|
||||
|
||||
bool PropertyRowResourceSelector::onActivate(const PropertyActivationEvent& e)
|
||||
{
|
||||
if (PropertyRowField::onActivate(e))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool canSelect = !userReadOnly() && !multiValue() && provider_ && provider_->CanSelect(type_.c_str(), value_.c_str(), id_);
|
||||
|
||||
if (!userReadOnly() && e.reason == e.REASON_DOUBLECLICK && provider_ && provider_->CanPickFile(type_.c_str(), id_))
|
||||
{
|
||||
return pickResource(e.tree);
|
||||
}
|
||||
|
||||
if (canSelect)
|
||||
{
|
||||
jumpTo(e.tree);
|
||||
return true;
|
||||
}
|
||||
else if (!userReadOnly())
|
||||
{
|
||||
if (!provider_ && !userReadOnly())
|
||||
{
|
||||
pickResource(e.tree);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int PropertyRowResourceSelector::buttonCount() const
|
||||
{
|
||||
if (!provider_)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
if (provider_->CanPickFile(type_.c_str(), id_))
|
||||
{
|
||||
result = 1;
|
||||
if (!multiValue() && value_.empty() && provider_->CanCreate(type_.c_str(), id_))
|
||||
{
|
||||
result = 2;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PropertyRowResourceSelector::onActivateButton(int button, const PropertyActivationEvent& e)
|
||||
{
|
||||
if (userReadOnly())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (button == BUTTON_PICK)
|
||||
{
|
||||
return pickResource(e.tree);
|
||||
}
|
||||
else if (button == BUTTON_CREATE)
|
||||
{
|
||||
return createFile(e.tree);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyRowResourceSelector::getHoverInfo(PropertyHoverInfo* hover, const QPoint& cursorPos, const QPropertyTree* tree) const
|
||||
{
|
||||
if (fieldRect(tree).contains(cursorPos) && provider_ && provider_->CanSelect(type_.c_str(), value_.c_str(), id_) && !provider_->IsSelected(type_.c_str(), value_.c_str(), id_))
|
||||
{
|
||||
hover->cursor = QCursor(Qt::PointingHandCursor);
|
||||
}
|
||||
else
|
||||
{
|
||||
hover->cursor = QCursor();
|
||||
}
|
||||
hover->toolTip = QString::fromLocal8Bit(value_.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void PropertyRowResourceSelector::jumpTo([[maybe_unused]] QPropertyTree* tree)
|
||||
{
|
||||
if (multiValue())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (provider_)
|
||||
{
|
||||
provider_->Select(type_.c_str(), value_.c_str(), id_);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool PropertyRowResourceSelector::pickResource(QPropertyTree* tree)
|
||||
{
|
||||
if (!GetIEditor())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
context_.typeName = type_.c_str();
|
||||
context_.parentWidget = tree;
|
||||
QString filename = GetIEditor()->GetResourceSelectorHost()->SelectResource(context_, value_.c_str());
|
||||
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
value_ = filename.toUtf8().constData();
|
||||
tree->model()->rowChanged(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QString convertMFCToQtFileFilter(QString* defaultSuffix, const char* mfcFilter);
|
||||
|
||||
bool PropertyRowResourceSelector::createFile(QPropertyTree* tree)
|
||||
{
|
||||
if (!provider_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QString title;
|
||||
if (labelUndecorated())
|
||||
{
|
||||
title = QString("Create file for '") + labelUndecorated() + "'";
|
||||
}
|
||||
else
|
||||
{
|
||||
title = "Choose file";
|
||||
}
|
||||
|
||||
string originalFilter;
|
||||
originalFilter = provider_->GetFileSelectorMaskForType(type_.c_str());
|
||||
|
||||
QString gameFolder = QString::fromLocal8Bit(Path::GetEditingGameDataFolder().c_str());
|
||||
QDir gameFolderDir(QDir::fromNativeSeparators(gameFolder));
|
||||
QString defaultSuffix;
|
||||
QString filter = convertMFCToQtFileFilter(&defaultSuffix, originalFilter.c_str());
|
||||
QString existingFile = QString::fromLocal8Bit(PathUtil::ReplaceExtension(defaultPath_.empty() ? value_.c_str() : defaultPath_.c_str(), defaultSuffix.toLocal8Bit().data()));
|
||||
|
||||
QString existingFilePath = (existingFile.isEmpty() || QDir::isAbsolutePath(existingFile)) ? existingFile : gameFolderDir.absoluteFilePath(existingFile);
|
||||
|
||||
// Not using QFileDialog().exec() as it implements custom file dialog that
|
||||
// freezes for couple of seconds when being open. Scannign network drives?
|
||||
QString result = QFileDialog::getSaveFileName(tree, title, existingFilePath.isEmpty() ? (gameFolder + "/") : existingFilePath, filter);
|
||||
if (!result.isEmpty())
|
||||
{
|
||||
QString relativeFilename = gameFolderDir.relativeFilePath(result);
|
||||
|
||||
if (provider_->Create(type_.c_str(), relativeFilename.toLocal8Bit().data(), id_))
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
value_ = relativeFilename.toLocal8Bit().data();
|
||||
tree->model()->rowChanged(this);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PropertyRowResourceSelector::setValueAndContext(const Serialization::SStruct& ser, IArchive& ar)
|
||||
{
|
||||
IResourceSelector* value = (IResourceSelector*)ser.pointer();
|
||||
if (type_ != value->resourceType)
|
||||
{
|
||||
type_ = value->resourceType;
|
||||
const char* resourceIconPath = GetIEditor()->GetResourceSelectorHost()->ResourceIconPath(type_.c_str());
|
||||
icon_ = resourceIconPath[0] ? QIcon(QString::fromLocal8Bit(resourceIconPath)) : QIcon();
|
||||
}
|
||||
value_ = value->GetValue();
|
||||
id_ = value->GetId();
|
||||
searchHandle_ = value->GetHandle();
|
||||
wrappedType_ = value->GetType();
|
||||
|
||||
provider_ = ar.FindContext<Serialization::INavigationProvider>();
|
||||
if (!provider_ || !provider_->IsRegistered(type_))
|
||||
{
|
||||
provider_ = 0;
|
||||
}
|
||||
|
||||
Serialization::TypeID contextObjectType = GetIEditor()->GetResourceSelectorHost()->ResourceContextType(type_.c_str());
|
||||
if (contextObjectType != Serialization::TypeID())
|
||||
{
|
||||
context_.contextObject = ar.FindContextByType(contextObjectType);
|
||||
context_.contextObjectType = contextObjectType;
|
||||
}
|
||||
|
||||
if (Serialization::SNavigationContext* navigationContext = ar.FindContext<Serialization::SNavigationContext>())
|
||||
{
|
||||
defaultPath_ = navigationContext->path.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultPath_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool PropertyRowResourceSelector::assignTo(const Serialization::SStruct& ser) const
|
||||
{
|
||||
((IResourceSelector*)ser.pointer())->SetValue(value_.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void PropertyRowResourceSelector::serializeValue(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(type_, "type");
|
||||
ar(value_, "value");
|
||||
ar(id_, "index");
|
||||
|
||||
if (ar.IsInput())
|
||||
{
|
||||
const char* resourceIconPath = GetIEditor()->GetResourceSelectorHost()->ResourceIconPath(type_.c_str());
|
||||
icon_ = resourceIconPath[0] ? QIcon(QString::fromLocal8Bit(resourceIconPath)) : QIcon();
|
||||
}
|
||||
}
|
||||
|
||||
const QIcon& PropertyRowResourceSelector::buttonIcon(const QPropertyTree* tree, int index) const
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case BUTTON_PICK:
|
||||
{
|
||||
if (provider_ != 0 || icon_.isNull())
|
||||
{
|
||||
#include "file_open.xpm"
|
||||
static QIcon defaultIcon(QPixmap::fromImage(*tree->_iconCache()->getImageForIcon(Serialization::IconXPM(file_open_xpm))));
|
||||
return defaultIcon;
|
||||
}
|
||||
else
|
||||
{
|
||||
return icon_;
|
||||
}
|
||||
}
|
||||
case BUTTON_CREATE:
|
||||
{
|
||||
static QIcon addIcon("Icons/animation/add.png");
|
||||
;
|
||||
return addIcon;
|
||||
}
|
||||
default:
|
||||
{
|
||||
static QIcon defaultIcon;
|
||||
return defaultIcon;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string PropertyRowResourceSelector::valueAsString() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
void PropertyRowResourceSelector::clear()
|
||||
{
|
||||
value_.clear();
|
||||
}
|
||||
|
||||
bool PropertyRowResourceSelector::onContextMenu(QMenu& menu, QPropertyTree* tree)
|
||||
{
|
||||
Serialization::SharedPtr<PropertyRow> selfPointer(this);
|
||||
|
||||
ResourceSelectorMenuHandler* handler = new ResourceSelectorMenuHandler(tree, this);
|
||||
if (!multiValue() && provider_ && provider_->CanSelect(type_.c_str(), value_.c_str(), id_))
|
||||
{
|
||||
QAction* jumpToAction = menu.addAction("Jump to", handler, SLOT(onMenuJumpTo()));
|
||||
menu.setDefaultAction(jumpToAction);
|
||||
}
|
||||
if (!userReadOnly())
|
||||
{
|
||||
if (!provider_ || provider_->CanPickFile(type_.c_str(), id_))
|
||||
{
|
||||
menu.addAction(buttonIcon(tree, 0), "Pick Resource...", handler, SLOT(onMenuPickResource()))->setEnabled(!userReadOnly());
|
||||
}
|
||||
if (provider_ && provider_->CanCreate(type_.c_str(), id_))
|
||||
{
|
||||
menu.addAction(buttonIcon(tree, 1), "Create...", handler, SLOT(onMenuCreateFile()));
|
||||
}
|
||||
menu.addAction("Clear", handler, SLOT(onMenuClear()))->setEnabled(!userReadOnly());
|
||||
}
|
||||
tree->addMenuHandler(handler);
|
||||
|
||||
PropertyRow::onContextMenu(menu, tree);
|
||||
return true;
|
||||
}
|
||||
|
||||
static const wchar_t* getFilenameFromPath(const wchar_t* path)
|
||||
{
|
||||
const wchar_t* lastSep = wcsrchr(path, L'/');
|
||||
if (!lastSep)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
return lastSep + 1;
|
||||
}
|
||||
|
||||
void PropertyRowResourceSelector::redraw(const PropertyDrawContext& context)
|
||||
{
|
||||
////! TOFIX: THIS CODE IS DUPLICATED IN PropertyRowField.cpp: PropertyRowField::redraw()!!!
|
||||
//
|
||||
int buttonCount = this->buttonCount();
|
||||
int offset = 0;
|
||||
for (int i = 0; i < buttonCount; ++i)
|
||||
{
|
||||
const QIcon& icon = buttonIcon(context.tree, i);
|
||||
int width = 16;
|
||||
QRect iconRect(context.widgetRect.right() - offset - width, context.widgetRect.top(), width, context.widgetRect.height());
|
||||
icon.paint(context.painter, iconRect, Qt::AlignCenter, userReadOnly() ? QIcon::Disabled : QIcon::Normal);
|
||||
offset += width;
|
||||
}
|
||||
|
||||
int iconSpace = offset ? offset + 2 : 0;
|
||||
//
|
||||
////
|
||||
|
||||
QRect rect = context.widgetRect;
|
||||
rect.setRight(rect.right() - iconSpace);
|
||||
bool pressed = context.m_pressed || (provider_ ? provider_->IsSelected(type_.c_str(), value_.c_str(), id_) : false);
|
||||
bool active = !provider_ || provider_->IsActive(type_.c_str(), value_.c_str(), id_);
|
||||
bool modified = provider_ && provider_->IsModified(type_.c_str(), value_.c_str(), id_);
|
||||
QIcon icon = icon_;
|
||||
if (provider_)
|
||||
{
|
||||
icon = QIcon(provider_->GetIcon(type_.c_str(), value_.c_str()));
|
||||
}
|
||||
bool canSelect = !multiValue() && provider_ && provider_->CanSelect(type_.c_str(), value_.c_str(), id_);
|
||||
|
||||
wstring text = multiValue() ? L"..." : wstring(modified ? L"*" : L"") + getFilenameFromPath(valueAsWString());
|
||||
if (provider_)
|
||||
{
|
||||
if (canSelect || !text.empty())
|
||||
{
|
||||
context.drawButtonWithIcon(icon, rect, text.c_str(), selected(), pressed, selected(), !userReadOnly(), canSelect, active ? &context.tree->_boldFont() : &context.tree->font());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
context.drawEntry(text.c_str(), true, false, iconSpace);
|
||||
}
|
||||
}
|
||||
|
||||
bool PropertyRowResourceSelector::processesKey(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (ev->key() == Qt::Key_Delete)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return PropertyRowField::processesKey(tree, ev);
|
||||
}
|
||||
|
||||
bool PropertyRowResourceSelector::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (ev->key() == Qt::Key_Delete)
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
clear();
|
||||
tree->model()->rowChanged(this);
|
||||
return true;
|
||||
}
|
||||
return PropertyRowField::onKeyDown(tree, ev);
|
||||
}
|
||||
|
||||
REGISTER_PROPERTY_ROW(IResourceSelector, PropertyRowResourceSelector);
|
||||
DECLARE_SEGMENT(PropertyRowResourceSelector)
|
||||
|
||||
#include <QPropertyTree/moc_PropertyRowResourceSelector.cpp>
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCESELECTOR_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCESELECTOR_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "PropertyRowField.h"
|
||||
#include <Serialization.h>
|
||||
#include "Serialization/Decorators/Resources.h"
|
||||
#include "IResourceSelectorHost.h"
|
||||
#include <QIcon>
|
||||
#endif
|
||||
|
||||
using Serialization::IResourceSelector;
|
||||
namespace Serialization {
|
||||
struct INavigationProvider;
|
||||
}
|
||||
|
||||
class PropertyRowResourceSelector
|
||||
: public PropertyRowField
|
||||
{
|
||||
public:
|
||||
PropertyRowResourceSelector()
|
||||
: provider_(0)
|
||||
, id_(0)
|
||||
, searchHandle_(0) {}
|
||||
void clear();
|
||||
|
||||
bool isLeaf() const override { return true; }
|
||||
bool isStatic() const override { return false; }
|
||||
|
||||
void jumpTo(QPropertyTree* tree);
|
||||
bool createFile(QPropertyTree* tree);
|
||||
void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override;
|
||||
bool assignTo(const Serialization::SStruct& ser) const override;
|
||||
bool onActivate(const PropertyActivationEvent& ev) override;
|
||||
bool onActivateButton(int button, const PropertyActivationEvent& e) override;
|
||||
bool getHoverInfo(PropertyHoverInfo* hover, const QPoint& cursorPos, const QPropertyTree* tree) const override;
|
||||
const void* searchHandle() const override { return searchHandle_; }
|
||||
Serialization::TypeID typeId() const override { return wrappedType_; }
|
||||
|
||||
int buttonCount() const override;
|
||||
virtual const QIcon& buttonIcon(const QPropertyTree* tree, int index) const override;
|
||||
virtual bool usePathEllipsis() const override { return true; }
|
||||
string valueAsString() const;
|
||||
void serializeValue(Serialization::IArchive& ar);
|
||||
void redraw(const PropertyDrawContext& context);
|
||||
|
||||
bool onContextMenu(QMenu& menu, QPropertyTree* tree);
|
||||
bool pickResource(QPropertyTree* tree);
|
||||
const char* typeNameForFilter([[maybe_unused]] QPropertyTree* tree) const override { return !type_.empty() ? type_.c_str() : "ResourceSelector"; }
|
||||
|
||||
bool processesKey(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
|
||||
private:
|
||||
SResourceSelectorContext context_;
|
||||
Serialization::INavigationProvider* provider_;
|
||||
const void* searchHandle_;
|
||||
Serialization::TypeID wrappedType_;
|
||||
QIcon icon_;
|
||||
|
||||
string type_;
|
||||
string value_;
|
||||
string defaultPath_;
|
||||
int id_;
|
||||
};
|
||||
|
||||
struct ResourceSelectorMenuHandler
|
||||
: PropertyRowMenuHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QPropertyTree * tree;
|
||||
PropertyRowResourceSelector* self;
|
||||
|
||||
ResourceSelectorMenuHandler(QPropertyTree* tree, PropertyRowResourceSelector* container);
|
||||
public slots:
|
||||
void onMenuCreateFile();
|
||||
void onMenuJumpTo();
|
||||
void onMenuClear();
|
||||
void onMenuPickResource();
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWRESOURCESELECTOR_H
|
||||
@@ -1,521 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "Serialization/ClassFactory.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "PropertyRowNumber.h"
|
||||
#include "MathUtils.h"
|
||||
|
||||
#include <QKeyEvent>
|
||||
#include <QStyleOption>
|
||||
#include <QStyleOptionSlider>
|
||||
#include <QPainter>
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyRow.h"
|
||||
#include "PropertyDrawContext.h"
|
||||
|
||||
#include "Serialization.h"
|
||||
#include "Serialization/Decorators/Slider.h"
|
||||
#include "Serialization/Decorators/SliderImpl.h"
|
||||
#include <math.h>
|
||||
|
||||
using Serialization::SSliderF;
|
||||
using Serialization::SSliderI;
|
||||
|
||||
class PropertyRowSliderF
|
||||
: public PropertyRowNumberField
|
||||
{
|
||||
public:
|
||||
static const bool Custom = true;
|
||||
PropertyRowSliderF();
|
||||
void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override;
|
||||
int floorHeight() const override { return 18; }
|
||||
void redraw(const PropertyDrawContext& context) override;
|
||||
|
||||
bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
bool onMouseDown(QPropertyTree* tree, QPoint point, bool& changed) override;
|
||||
void onMouseDrag(const PropertyDragEvent& e) override;
|
||||
void onMouseUp(QPropertyTree* tree, QPoint point) override;
|
||||
bool assignTo(const Serialization::SStruct& ser) const override
|
||||
{
|
||||
if (ser.size() != sizeof(SSliderF))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
SSliderF* slider = (SSliderF*)(ser.pointer());
|
||||
*slider->valuePointer = clamp(localValue_, slider->minLimit, slider->maxLimit);
|
||||
return true;
|
||||
}
|
||||
bool handleMouse(QPropertyTree* tree, QPoint point);
|
||||
|
||||
bool setValueFromString(const char* str) override
|
||||
{
|
||||
float newValue = aznumeric_cast<float>(atof(str));
|
||||
if (localValue_ != newValue)
|
||||
{
|
||||
localValue_ = newValue;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
string valueAsString() const override
|
||||
{
|
||||
return numberAsString(localValue_);
|
||||
}
|
||||
|
||||
void startIncrement() override
|
||||
{
|
||||
incrementStartValue_ = localValue_;
|
||||
}
|
||||
|
||||
void endIncrement(QPropertyTree* tree) override
|
||||
{
|
||||
if (localValue_ != incrementStartValue_)
|
||||
{
|
||||
float localValue = localValue_;
|
||||
localValue_ = incrementStartValue_;
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
localValue_ = localValue;
|
||||
tree->model()->rowChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
void incrementLog(float screenFraction, [[maybe_unused]] float valueFieldFraction)
|
||||
{
|
||||
double startPower = log10(fabs(double(incrementStartValue_) + 1.0)) - 3.0;
|
||||
double power = startPower + fabs(screenFraction) * 10.0f;
|
||||
double delta = powf(10.0f, aznumeric_cast<float>(power)) - powf(10.0f, aznumeric_cast<float>(startPower)) + 10.0f * fabsf(screenFraction);
|
||||
double newValue;
|
||||
if (screenFraction > 0.0f)
|
||||
{
|
||||
newValue = double(incrementStartValue_) + delta;
|
||||
}
|
||||
else
|
||||
{
|
||||
newValue = double(incrementStartValue_) - delta;
|
||||
}
|
||||
if (_isnan(newValue))
|
||||
{
|
||||
if (screenFraction > 0.0f)
|
||||
{
|
||||
newValue = DBL_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
newValue = -DBL_MAX;
|
||||
}
|
||||
}
|
||||
clampToType(&localValue_, newValue);
|
||||
}
|
||||
|
||||
void serializeValue(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(value_.minLimit, "min");
|
||||
ar(value_.maxLimit, "max");
|
||||
ar(localValue_, "value");
|
||||
}
|
||||
|
||||
double sliderPosition() const override { return 0.0; }
|
||||
|
||||
SSliderF value_;
|
||||
float localValue_;
|
||||
float incrementStartValue_;
|
||||
bool captured_;
|
||||
};
|
||||
|
||||
bool PropertyRowSliderF::handleMouse(QPropertyTree* tree, QPoint point)
|
||||
{
|
||||
QStyleOptionSlider slider;
|
||||
slider.rect = floorRect(tree);
|
||||
QSlider widgetForContext;
|
||||
QRect sliderGroove = tree->style()->subControlRect(QStyle::CC_Slider, &slider, QStyle::SC_SliderGroove, &widgetForContext);
|
||||
QRect sliderHandle = tree->style()->subControlRect(QStyle::CC_Slider, &slider, QStyle::SC_SliderHandle, &widgetForContext);
|
||||
|
||||
int sliderLength = sliderGroove.width() - sliderHandle.width();
|
||||
|
||||
float valRelative = float(point.x() - (sliderGroove.left() + sliderHandle.width() / 2)) / sliderLength;
|
||||
if (valRelative < 0.0f)
|
||||
{
|
||||
valRelative = 0.0f;
|
||||
}
|
||||
if (valRelative > 1.0f)
|
||||
{
|
||||
valRelative = 1.0f;
|
||||
}
|
||||
float newValue = float(valRelative * (value_.maxLimit - value_.minLimit) + value_.minLimit);
|
||||
if (newValue != localValue_)
|
||||
{
|
||||
localValue_ = newValue;
|
||||
setMultiValue(false);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool PropertyRowSliderF::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
float step = (value_.maxLimit - value_.minLimit) * 0.01f;
|
||||
if (ev->key() == Qt::Key_Left)
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
localValue_ = clamp(localValue_ - step, value_.minLimit, value_.maxLimit);
|
||||
tree->model()->rowChanged(this);
|
||||
return true;
|
||||
}
|
||||
if (ev->key() == Qt::Key_Right)
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
localValue_ = clamp(localValue_ + step, value_.minLimit, value_.maxLimit);
|
||||
tree->model()->rowChanged(this);
|
||||
return true;
|
||||
}
|
||||
return PropertyRowNumberField::onKeyDown(tree, ev);
|
||||
}
|
||||
|
||||
bool PropertyRowSliderF::onMouseDown(QPropertyTree* tree, QPoint point, [[maybe_unused]] bool& changed)
|
||||
{
|
||||
if (floorRect(tree).contains(point) && !userReadOnly())
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
if (handleMouse(tree, point))
|
||||
{
|
||||
tree->update();
|
||||
}
|
||||
captured_ = true;
|
||||
return true;
|
||||
}
|
||||
captured_ = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PropertyRowSliderF::onMouseDrag(const PropertyDragEvent& e)
|
||||
{
|
||||
if (!captured_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (userReadOnly())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (handleMouse(e.tree, e.pos))
|
||||
{
|
||||
e.tree->update();
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyRowSliderF::onMouseUp(QPropertyTree* tree, QPoint point)
|
||||
{
|
||||
if (!captured_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
handleMouse(tree, point);
|
||||
tree->model()->rowChanged(this);
|
||||
}
|
||||
|
||||
void PropertyRowSliderF::setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar)
|
||||
{
|
||||
value_ = *(SSliderF*)ser.pointer();
|
||||
localValue_ = *value_.valuePointer;
|
||||
value_.valuePointer = 0;
|
||||
}
|
||||
|
||||
static void drawSlider(const PropertyDrawContext& context, float relativeVal, bool userReadOnly, bool selected)
|
||||
{
|
||||
// Eliminate x-shift offset in the control rect as it triggers a bug in
|
||||
// Fusion theme, that causes blue area in the slider groove to stand out to
|
||||
// the right from slider.
|
||||
int xOffset = context.lineRect.left();
|
||||
context.painter->translate(xOffset, 0);
|
||||
|
||||
QStyleOptionSlider sliderOptions;
|
||||
sliderOptions.rect = context.lineRect.translated(-xOffset, 0);
|
||||
sliderOptions.minimum = 0;
|
||||
QSlider widgetForContext;
|
||||
QRect sliderGroove = context.tree->style()->subControlRect(QStyle::CC_Slider, &sliderOptions, QStyle::SC_SliderGroove, &widgetForContext);
|
||||
QRect sliderHandle = context.tree->style()->subControlRect(QStyle::CC_Slider, &sliderOptions, QStyle::SC_SliderHandle, &widgetForContext);
|
||||
int width = sliderGroove.width() - sliderHandle.width() + 1;
|
||||
sliderOptions.maximum = width;
|
||||
sliderOptions.pageStep = width / 100;
|
||||
sliderOptions.sliderPosition = aznumeric_cast<int>(width * relativeVal);
|
||||
sliderOptions.state = !userReadOnly ? (QStyle::State_Enabled | (selected ? QStyle::State_HasFocus : QStyle::State())) : QStyle::State();
|
||||
|
||||
context.tree->style()->drawComplexControl(QStyle::CC_Slider, &sliderOptions, context.painter, &widgetForContext);
|
||||
|
||||
context.painter->translate(-xOffset, 0);
|
||||
}
|
||||
|
||||
void PropertyRowSliderF::redraw(const PropertyDrawContext& context)
|
||||
{
|
||||
PropertyRowNumberField::redraw(context);
|
||||
float val = localValue_;
|
||||
float valRange = value_.maxLimit - value_.minLimit;
|
||||
if (valRange == 0.0f)
|
||||
{
|
||||
valRange = 0.00001f;
|
||||
}
|
||||
float relativeVal = clamp((val - value_.minLimit) / valRange, 0.0f, 1.0f);
|
||||
|
||||
drawSlider(context, relativeVal, userReadOnly(), selected());
|
||||
}
|
||||
|
||||
PropertyRowSliderF::PropertyRowSliderF()
|
||||
: captured_(false)
|
||||
, localValue_()
|
||||
, incrementStartValue_()
|
||||
{
|
||||
}
|
||||
|
||||
DECLARE_SEGMENT(PropertyRowSliderF)
|
||||
REGISTER_PROPERTY_ROW(SSliderF, PropertyRowSliderF)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class PropertyRowSliderI
|
||||
: public PropertyRowNumberField
|
||||
{
|
||||
public:
|
||||
static const bool Custom = true;
|
||||
PropertyRowSliderI();
|
||||
void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override;
|
||||
int floorHeight() const override { return 18; }
|
||||
void redraw(const PropertyDrawContext& context) override;
|
||||
|
||||
bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
bool onMouseDown(QPropertyTree* tree, QPoint point, bool& changed) override;
|
||||
void onMouseDrag(const PropertyDragEvent& e) override;
|
||||
void onMouseUp(QPropertyTree* tree, QPoint point) override;
|
||||
bool assignTo(const Serialization::SStruct& ser) const override
|
||||
{
|
||||
if (ser.size() != sizeof(SSliderI))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
SSliderI* slider = (SSliderI*)(ser.pointer());
|
||||
*slider->valuePointer = clamp(localValue_, slider->minLimit, slider->maxLimit);
|
||||
return true;
|
||||
}
|
||||
bool handleMouse(QPropertyTree* tree, QPoint point);
|
||||
|
||||
bool setValueFromString(const char* str) override
|
||||
{
|
||||
int newValue = atoi(str);
|
||||
if (localValue_ != newValue)
|
||||
{
|
||||
localValue_ = newValue;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Serialization::string valueAsString() const override
|
||||
{
|
||||
return numberAsString(localValue_);
|
||||
}
|
||||
|
||||
void startIncrement() override
|
||||
{
|
||||
incrementStartValue_ = localValue_;
|
||||
}
|
||||
|
||||
void endIncrement(QPropertyTree* tree) override
|
||||
{
|
||||
if (localValue_ != incrementStartValue_)
|
||||
{
|
||||
int localValue = localValue_;
|
||||
localValue_ = incrementStartValue_;
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
localValue_ = localValue;
|
||||
tree->model()->rowChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
void incrementLog(float screenFraction, [[maybe_unused]] float valueFieldFraction)
|
||||
{
|
||||
double startPower = log10(fabs(double(incrementStartValue_) + 1.0)) - 3.0;
|
||||
double power = startPower + fabs(screenFraction) * 10.0f;
|
||||
double delta = powf(10.0f, aznumeric_cast<float>(power)) - powf(10.0f, aznumeric_cast<float>(startPower)) + 1000.0f * fabsf(screenFraction);
|
||||
double newValue;
|
||||
if (screenFraction > 0.0f)
|
||||
{
|
||||
newValue = double(incrementStartValue_) + delta;
|
||||
}
|
||||
else
|
||||
{
|
||||
newValue = double(incrementStartValue_) - delta;
|
||||
}
|
||||
if (_isnan(newValue))
|
||||
{
|
||||
if (screenFraction > 0.0f)
|
||||
{
|
||||
newValue = DBL_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
newValue = -DBL_MAX;
|
||||
}
|
||||
}
|
||||
clampToType(&localValue_, newValue);
|
||||
}
|
||||
|
||||
void serializeValue(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(value_.minLimit, "min");
|
||||
ar(value_.maxLimit, "max");
|
||||
ar(localValue_, "value");
|
||||
}
|
||||
|
||||
double sliderPosition() const override { return 0.0; }
|
||||
|
||||
SSliderI value_;
|
||||
int localValue_;
|
||||
int incrementStartValue_;
|
||||
bool captured_;
|
||||
};
|
||||
|
||||
bool PropertyRowSliderI::handleMouse(QPropertyTree* tree, QPoint point)
|
||||
{
|
||||
QStyleOptionSlider slider;
|
||||
slider.rect = floorRect(tree);
|
||||
|
||||
QSlider widgetForContext;
|
||||
QRect sliderGroove = tree->style()->subControlRect(QStyle::CC_Slider, &slider, QStyle::SC_SliderGroove, &widgetForContext);
|
||||
QRect sliderHandle = tree->style()->subControlRect(QStyle::CC_Slider, &slider, QStyle::SC_SliderHandle, &widgetForContext);
|
||||
|
||||
int sliderLength = sliderGroove.width() - sliderHandle.width();
|
||||
|
||||
float valRelative = float(point.x() - (sliderGroove.left() + sliderHandle.width() / 2)) / sliderLength;
|
||||
if (valRelative < 0.0f)
|
||||
{
|
||||
valRelative = 0.0f;
|
||||
}
|
||||
if (valRelative > 1.0f)
|
||||
{
|
||||
valRelative = 1.0f;
|
||||
}
|
||||
int newValue = int(valRelative * (value_.maxLimit - value_.minLimit) + value_.minLimit);
|
||||
if (newValue != localValue_)
|
||||
{
|
||||
localValue_ = newValue;
|
||||
setMultiValue(false);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool PropertyRowSliderI::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
int step = aznumeric_cast<int>((value_.maxLimit - value_.minLimit) * 0.01f);
|
||||
if (ev->key() == Qt::Key_Left)
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
localValue_ = clamp(localValue_ - step, value_.minLimit, value_.maxLimit);
|
||||
tree->model()->rowChanged(this);
|
||||
return true;
|
||||
}
|
||||
if (ev->key() == Qt::Key_Right)
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
localValue_ = clamp(localValue_ + step, value_.minLimit, value_.maxLimit);
|
||||
tree->model()->rowChanged(this);
|
||||
return true;
|
||||
}
|
||||
return PropertyRowNumberField::onKeyDown(tree, ev);
|
||||
}
|
||||
|
||||
bool PropertyRowSliderI::onMouseDown(QPropertyTree* tree, QPoint point, [[maybe_unused]] bool& changed)
|
||||
{
|
||||
if (floorRect(tree).contains(point) && !userReadOnly())
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
if (handleMouse(tree, point))
|
||||
{
|
||||
tree->update();
|
||||
}
|
||||
captured_ = true;
|
||||
return true;
|
||||
}
|
||||
captured_ = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PropertyRowSliderI::onMouseDrag(const PropertyDragEvent& e)
|
||||
{
|
||||
if (!captured_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (userReadOnly())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (handleMouse(e.tree, e.pos))
|
||||
{
|
||||
e.tree->update();
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyRowSliderI::onMouseUp(QPropertyTree* tree, QPoint point)
|
||||
{
|
||||
if (!captured_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
handleMouse(tree, point);
|
||||
tree->model()->rowChanged(this);
|
||||
}
|
||||
|
||||
void PropertyRowSliderI::setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar)
|
||||
{
|
||||
value_ = *(SSliderI*)ser.pointer();
|
||||
localValue_ = *value_.valuePointer;
|
||||
value_.valuePointer = 0;
|
||||
}
|
||||
|
||||
void PropertyRowSliderI::redraw(const PropertyDrawContext& context)
|
||||
{
|
||||
PropertyRowNumberField::redraw(context);
|
||||
int val = localValue_;
|
||||
int valRange = value_.maxLimit - value_.minLimit;
|
||||
if (valRange == 0)
|
||||
{
|
||||
valRange = 1;
|
||||
}
|
||||
float relativeVal = clamp(float(val - value_.minLimit) / valRange, 0.0f, 1.0f);
|
||||
|
||||
drawSlider(context, relativeVal, userReadOnly(), selected());
|
||||
}
|
||||
|
||||
PropertyRowSliderI::PropertyRowSliderI()
|
||||
: captured_(false)
|
||||
, localValue_()
|
||||
, incrementStartValue_()
|
||||
{
|
||||
}
|
||||
|
||||
DECLARE_SEGMENT(PropertyRowSliderI)
|
||||
REGISTER_PROPERTY_ROW(SSliderI, PropertyRowSliderI)
|
||||
@@ -1,299 +0,0 @@
|
||||
//-------------------------------------------------------------------------------
|
||||
// Copyright (C) Amazon.com, Inc. or its affiliates.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Licensed under the terms set out in the LICENSE.HTML file included at the
|
||||
// root of the distribution; you may not use this file except in compliance
|
||||
// with the License.
|
||||
//
|
||||
// Do not remove or modify this notice or the LICENSE.HTML file. This file
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language
|
||||
// governing permissions and limitations under the License.
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "SpriteBorderEditorCommon.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyRowField.h"
|
||||
#include "PropertyRowSprite.h"
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include <Serialization/Decorators/Sprite.h>
|
||||
#include <Serialization/Decorators/SpriteImpl.h>
|
||||
#include <Serialization/Decorators/IconXPM.h>
|
||||
#include <QFileDialog>
|
||||
|
||||
extern QString AssetRelativePathFromAbsolutePath(const QString& absPath);
|
||||
|
||||
bool PropertyRowSprite::onActivateButton(int buttonIndex, const PropertyActivationEvent& ev)
|
||||
{
|
||||
Show show = FromButtonIndexToShow( buttonIndex );
|
||||
|
||||
if( show == Show::kFilePicker )
|
||||
{
|
||||
return showFilePicker( ev );
|
||||
}
|
||||
|
||||
if( show == Show::kSpriteBorderEditor )
|
||||
{
|
||||
return showSpriteBorderEditor( ev );
|
||||
}
|
||||
|
||||
// This is to avoid a compiler warning.
|
||||
// We should NEVER get here.
|
||||
CRY_ASSERT( 0 );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyRowSprite::onActivate(const PropertyActivationEvent& ev)
|
||||
{
|
||||
if( PropertyRowField::onActivate( ev ) )
|
||||
{
|
||||
// PropertyRowSprite::onActivateButton() has handled this event.
|
||||
// Nothing else to do.
|
||||
return true;
|
||||
}
|
||||
|
||||
return showFilePicker( ev );
|
||||
}
|
||||
|
||||
void PropertyRowSprite::setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar)
|
||||
{
|
||||
Serialization::Sprite* value = (Serialization::Sprite *)ser.pointer();
|
||||
|
||||
m_path = value->m_path->c_str();
|
||||
}
|
||||
|
||||
bool PropertyRowSprite::assignTo(const Serialization::SStruct& ser) const
|
||||
{
|
||||
if( ser.size() != sizeof(Serialization::Sprite) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Serialization::Sprite* s = (Serialization::Sprite *)ser.pointer();
|
||||
|
||||
*s->m_path = m_path.c_str();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PropertyRowSprite::serializeValue(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(m_path, "path");
|
||||
ar(m_filter, "filter");
|
||||
ar(m_startFolder, "startFolder");
|
||||
}
|
||||
|
||||
int PropertyRowSprite::buttonCount() const
|
||||
{
|
||||
return ( CanBeEdited() ? 2 : 1 );
|
||||
}
|
||||
|
||||
const QIcon& PropertyRowSprite::buttonIcon(const QPropertyTree* tree, int index) const
|
||||
{
|
||||
Show show = FromButtonIndexToShow( index );
|
||||
|
||||
if( show == Show::kFilePicker )
|
||||
{
|
||||
#include "file_open.xpm"
|
||||
static QIcon icon = QIcon(QPixmap::fromImage(*tree->_iconCache()->getImageForIcon(Serialization::IconXPM(file_open_xpm))));
|
||||
return icon;
|
||||
}
|
||||
|
||||
if( show == Show::kSpriteBorderEditor )
|
||||
{
|
||||
#include "gear.xpm"
|
||||
static QIcon icon = QIcon(QPixmap::fromImage(*tree->_iconCache()->getImageForIcon(Serialization::IconXPM(gear_xpm))));
|
||||
return icon;
|
||||
}
|
||||
|
||||
// This is to avoid a compiler warning.
|
||||
// We should NEVER get here.
|
||||
CRY_ASSERT( 0 );
|
||||
|
||||
#include "gear.xpm"
|
||||
static QIcon icon;
|
||||
return icon;
|
||||
}
|
||||
|
||||
string PropertyRowSprite::valueAsString() const
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
|
||||
void PropertyRowSprite::clear()
|
||||
{
|
||||
m_path.clear();
|
||||
}
|
||||
|
||||
bool PropertyRowSprite::onContextMenu(QMenu &menu, QPropertyTree* tree)
|
||||
{
|
||||
QAction* action = nullptr;
|
||||
|
||||
action = menu.addAction("Clear");
|
||||
QObject::connect( action,
|
||||
&QAction::triggered,
|
||||
tree,
|
||||
[ this, tree ]
|
||||
{
|
||||
Clear( tree );
|
||||
} );
|
||||
|
||||
int buttonIndex = ( buttonCount() - 1 );
|
||||
|
||||
action = menu.addAction(buttonIcon(tree, buttonIndex--), "Pick Resource...");
|
||||
QObject::connect( action,
|
||||
&QAction::triggered,
|
||||
tree,
|
||||
[ this, tree ]
|
||||
{
|
||||
PropertyActivationEvent ev;
|
||||
ev.tree = tree;
|
||||
showFilePicker( ev );
|
||||
} );
|
||||
|
||||
if( buttonIndex >= 0 )
|
||||
{
|
||||
action = menu.addAction(buttonIcon(tree, buttonIndex), "Edit");
|
||||
QObject::connect( action,
|
||||
&QAction::triggered,
|
||||
tree,
|
||||
[ this, tree ]
|
||||
{
|
||||
PropertyActivationEvent ev;
|
||||
ev.tree = tree;
|
||||
showSpriteBorderEditor( ev );
|
||||
} );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyRowSprite::processesKey(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if (ev->key() == Qt::Key_Delete)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return PropertyRowField::processesKey(tree, ev);
|
||||
}
|
||||
|
||||
bool PropertyRowSprite::onKeyDown(QPropertyTree* tree, const QKeyEvent* ev)
|
||||
{
|
||||
if( ev->key() == Qt::Key_Delete )
|
||||
{
|
||||
Clear( tree );
|
||||
return true;
|
||||
}
|
||||
return PropertyRowField::onKeyDown(tree, ev);
|
||||
}
|
||||
|
||||
void PropertyRowSprite::Clear(QPropertyTree* tree)
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
clear();
|
||||
tree->model()->rowChanged(this);
|
||||
}
|
||||
|
||||
bool PropertyRowSprite::showFilePicker(const PropertyActivationEvent& ev)
|
||||
{
|
||||
if (ev.reason == ev.REASON_RELEASE)
|
||||
return false;
|
||||
|
||||
// Open the file picker and get the filename the user selects
|
||||
// (QFileDialog can traverse symlinks and shortcuts)
|
||||
QString filename = QFileDialog::getOpenFileName(ev.tree,
|
||||
"Choose file",
|
||||
QString(),
|
||||
"*.tif;;*.sprite" );
|
||||
|
||||
// Early out.
|
||||
{
|
||||
if (filename.isEmpty())
|
||||
{
|
||||
// Nothing selected.
|
||||
return true;
|
||||
}
|
||||
|
||||
QFileInfo fileInfo( filename );
|
||||
if( ! ( ( fileInfo.suffix() == "tif" ) ||
|
||||
( fileInfo.suffix() == "sprite" ) ) )
|
||||
{
|
||||
// Incompatible files selected.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
ev.tree->model()->rowAboutToBeChanged(this);
|
||||
m_path = AssetRelativePathFromAbsolutePath(filename).toStdString().c_str();;
|
||||
ev.tree->model()->rowChanged(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyRowSprite::showSpriteBorderEditor(const PropertyActivationEvent& ev)
|
||||
{
|
||||
SpriteBorderEditor sbe( m_path.c_str(), ev.tree );
|
||||
if (sbe.GetHasBeenInitializedProperly())
|
||||
{
|
||||
sbe.exec();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyRowSprite::CanBeEdited() const
|
||||
{
|
||||
return ( ! m_path.empty() );
|
||||
}
|
||||
|
||||
PropertyRowSprite::Show PropertyRowSprite::FromButtonIndexToShow(int index) const
|
||||
{
|
||||
bool showFile = false;
|
||||
bool showGear = false;
|
||||
|
||||
if( index )
|
||||
{
|
||||
// Second icon from the right.
|
||||
|
||||
showFile = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// First icon from the right (right-most icon).
|
||||
|
||||
if( CanBeEdited() )
|
||||
{
|
||||
showGear = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
showFile = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( showFile )
|
||||
{
|
||||
return Show::kFilePicker;
|
||||
}
|
||||
|
||||
if( showGear )
|
||||
{
|
||||
return Show::kSpriteBorderEditor;
|
||||
}
|
||||
|
||||
// This is to avoid a compiler warning.
|
||||
// We should NEVER get here.
|
||||
CRY_ASSERT( 0 );
|
||||
return (Show)0;
|
||||
}
|
||||
|
||||
DECLARE_SEGMENT(PropertyRowSprite)
|
||||
REGISTER_PROPERTY_ROW(Serialization::Sprite, PropertyRowSprite);
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
//-------------------------------------------------------------------------------
|
||||
// Copyright (C) Amazon.com, Inc. or its affiliates.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Licensed under the terms set out in the LICENSE.HTML file included at the
|
||||
// root of the distribution; you may not use this file except in compliance
|
||||
// with the License.
|
||||
//
|
||||
// Do not remove or modify this notice or the LICENSE.HTML file. This file
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language
|
||||
// governing permissions and limitations under the License.
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSPRITE_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSPRITE_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "PropertyRowField.h"
|
||||
#endif
|
||||
|
||||
class PropertyRowSprite
|
||||
: public PropertyRowField
|
||||
{
|
||||
public:
|
||||
void clear();
|
||||
|
||||
bool isLeaf() const override{ return true; }
|
||||
bool isStatic() const override{ return false; }
|
||||
|
||||
void setValueAndContext(const Serialization::SStruct& ser, Serialization::IArchive& ar) override;
|
||||
bool assignTo(const Serialization::SStruct& ser) const override;
|
||||
bool onActivateButton(int buttonIndex, const PropertyActivationEvent& ev) override;
|
||||
bool onActivate(const PropertyActivationEvent& ev) override;
|
||||
|
||||
int buttonCount() const override;
|
||||
virtual const QIcon& buttonIcon(const QPropertyTree* tree, int index) const override;
|
||||
virtual bool usePathEllipsis() const override { return true; }
|
||||
string valueAsString() const override;
|
||||
void serializeValue(Serialization::IArchive& ar);
|
||||
|
||||
bool onContextMenu(QMenu& menu, QPropertyTree* tree);
|
||||
|
||||
bool processesKey(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
bool onKeyDown(QPropertyTree* tree, const QKeyEvent* ev) override;
|
||||
|
||||
private:
|
||||
|
||||
enum class Show
|
||||
{
|
||||
kFilePicker,
|
||||
kSpriteBorderEditor
|
||||
};
|
||||
|
||||
void Clear(QPropertyTree* tree);
|
||||
bool showFilePicker(const PropertyActivationEvent& ev);
|
||||
bool showSpriteBorderEditor(const PropertyActivationEvent& ev);
|
||||
bool CanBeEdited() const;
|
||||
Show FromButtonIndexToShow(int index) const;
|
||||
|
||||
string m_path;
|
||||
string m_filter;
|
||||
string m_startFolder;
|
||||
int m_flags;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSPRITE_H
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "PropertyRowString.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "QPropertyTree.h"
|
||||
|
||||
#include "Serialization/IArchive.h"
|
||||
#include "Serialization/ClassFactory.h"
|
||||
#include <QMenu>
|
||||
#include "Unicode.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
SERIALIZATION_CLASS_NAME(PropertyRow, PropertyRowString, "PropertyRowString", "string");
|
||||
|
||||
bool PropertyRowString::assignTo(string& str) const
|
||||
{
|
||||
str = fromWideChar(value_.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyRowString::assignTo(wstring& str) const
|
||||
{
|
||||
str = value_;
|
||||
return true;
|
||||
}
|
||||
|
||||
PropertyRowWidget* PropertyRowString::createWidget(QPropertyTree* tree)
|
||||
{
|
||||
return new PropertyRowWidgetString(this, tree);
|
||||
}
|
||||
|
||||
bool PropertyRowString::assignToByPointer(void* instance, const Serialization::TypeID& type) const
|
||||
{
|
||||
if (type == Serialization::TypeID::get<string>())
|
||||
{
|
||||
assignTo(*(string*)instance);
|
||||
return true;
|
||||
}
|
||||
else if (type == Serialization::TypeID::get<wstring>())
|
||||
{
|
||||
assignTo(*(wstring*)instance);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
string PropertyRowString::valueAsString() const
|
||||
{
|
||||
return fromWideChar(value_.c_str());
|
||||
}
|
||||
|
||||
void PropertyRowString::setValue(const wchar_t* str, const void* handle, const Serialization::TypeID& type)
|
||||
{
|
||||
value_ = str;
|
||||
serializer_.setPointer((void*)handle);
|
||||
serializer_.setType(type);
|
||||
}
|
||||
|
||||
void PropertyRowString::setValue(const char* str, const void* handle, const Serialization::TypeID& type)
|
||||
{
|
||||
value_ = toWideChar(str);
|
||||
serializer_.setPointer((void*)handle);
|
||||
serializer_.setType(type);
|
||||
}
|
||||
|
||||
void PropertyRowString::serializeValue(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(value_, "value", "Value");
|
||||
}
|
||||
|
||||
#include <QPropertyTree/moc_PropertyRowString.cpp>
|
||||
// vim:ts=4 sw=4:
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSTRING_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSTRING_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "PropertyRowField.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "Unicode.h"
|
||||
#include "MathUtils.h"
|
||||
|
||||
#include <QLineEdit>
|
||||
#endif
|
||||
|
||||
class PropertyRowString
|
||||
: public PropertyRowField
|
||||
{
|
||||
public:
|
||||
bool isLeaf() const override { return true; }
|
||||
bool isStatic() const override { return false; }
|
||||
using PropertyRowField::assignTo;
|
||||
bool assignTo(string& str) const;
|
||||
bool assignTo(wstring& str) const;
|
||||
void setValue(const char* str, const void* handle, const Serialization::TypeID& typeId);
|
||||
void setValue(const wchar_t* str, const void* handle, const Serialization::TypeID& typeId);
|
||||
PropertyRowWidget* createWidget(QPropertyTree* tree);
|
||||
string valueAsString() const;
|
||||
wstring valueAsWString() const { return value_; }
|
||||
WidgetPlacement widgetPlacement() const override { return WIDGET_VALUE; }
|
||||
void serializeValue(Serialization::IArchive& ar) override;
|
||||
const wstring& value() const{ return value_; }
|
||||
bool assignToByPointer(void* instance, const Serialization::TypeID& type) const;
|
||||
protected:
|
||||
wstring value_;
|
||||
};
|
||||
|
||||
class PropertyRowWidgetString
|
||||
: public PropertyRowWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PropertyRowWidgetString(PropertyRowString* row, QPropertyTree* tree)
|
||||
: PropertyRowWidget(row, tree)
|
||||
, entry_(new QLineEdit())
|
||||
, tree_(tree)
|
||||
{
|
||||
initialValue_ = QString(fromWideChar(row->value().c_str()).c_str());
|
||||
entry_->setText(initialValue_);
|
||||
entry_->selectAll();
|
||||
connect(entry_.data(), SIGNAL(editingFinished()), this, SLOT(onEditingFinished()));
|
||||
connect(entry_.data(), &QLineEdit::textChanged, this, [this, tree] {
|
||||
QFontMetrics fm(entry_->font());
|
||||
int contentWidth = min((int)fm.horizontalAdvance(entry_->text()) + 8, tree->width() - entry_->x());
|
||||
if (contentWidth > entry_->width())
|
||||
{
|
||||
entry_->resize(contentWidth, entry_->height());
|
||||
}
|
||||
});
|
||||
}
|
||||
~PropertyRowWidgetString()
|
||||
{
|
||||
entry_->hide();
|
||||
entry_->setParent(0);
|
||||
entry_.take()->deleteLater();
|
||||
}
|
||||
|
||||
void commit()
|
||||
{
|
||||
onEditingFinished();
|
||||
}
|
||||
QWidget* actualWidget() { return entry_.data(); }
|
||||
|
||||
public slots:
|
||||
void onEditingFinished()
|
||||
{
|
||||
PropertyRowString* row = static_cast<PropertyRowString*>(this->row());
|
||||
if (initialValue_ != entry_->text() || row_->multiValue())
|
||||
{
|
||||
model()->rowAboutToBeChanged(row);
|
||||
vector<wchar_t> str;
|
||||
QString text = entry_->text();
|
||||
str.resize(text.size() + 1, L'\0');
|
||||
if (!text.isEmpty())
|
||||
{
|
||||
text.toWCharArray(&str[0]);
|
||||
}
|
||||
row->setValue(&str[0], row->searchHandle(), row->typeId());
|
||||
model()->rowChanged(row);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree_->_cancelWidget();
|
||||
}
|
||||
}
|
||||
protected:
|
||||
QPropertyTree* tree_;
|
||||
QScopedPointer<QLineEdit> entry_;
|
||||
QString initialValue_;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSTRING_H
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "Factory.h"
|
||||
#include "PropertyRowStringListValue.h"
|
||||
|
||||
#include "Serialization/IArchive.h"
|
||||
#include "Serialization/ClassFactory.h"
|
||||
|
||||
using Serialization::StringList;
|
||||
using Serialization::StringListValue;
|
||||
|
||||
REGISTER_PROPERTY_ROW(StringListValue, PropertyRowStringListValue)
|
||||
|
||||
PropertyRowWidget * PropertyRowStringListValue::createWidget(QPropertyTree * tree)
|
||||
{
|
||||
return new PropertyRowWidgetStringListValue(this, tree);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
REGISTER_PROPERTY_ROW(StringListStaticValue, PropertyRowStringListStaticValue)
|
||||
|
||||
PropertyRowWidget * PropertyRowStringListStaticValue::createWidget(QPropertyTree * tree)
|
||||
{
|
||||
return new PropertyRowWidgetStringListValue(this, tree);
|
||||
}
|
||||
|
||||
DECLARE_SEGMENT(PropertyRowStringList)
|
||||
|
||||
#include <QPropertyTree/moc_PropertyRowStringListValue.cpp>
|
||||
// vim:ts=4 sw=4:
|
||||
@@ -1,303 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSTRINGLISTVALUE_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSTRINGLISTVALUE_H
|
||||
#pragma once
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "PropertyRowImpl.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include <QComboBox>
|
||||
#include <QMouseEvent>
|
||||
#include <QApplication>
|
||||
#include <QStyle>
|
||||
#include <QtGui/QPainter>
|
||||
#endif
|
||||
|
||||
using Serialization::StringListValue;
|
||||
class PropertyRowStringListValue
|
||||
: public PropertyRow
|
||||
{
|
||||
public:
|
||||
PropertyRowStringListValue()
|
||||
: handle_() {}
|
||||
PropertyRowWidget* createWidget(QPropertyTree* tree) override;
|
||||
string valueAsString() const override { return value_.c_str(); }
|
||||
bool assignTo(const Serialization::SStruct& ser) const override
|
||||
{
|
||||
*((StringListValue*)ser.pointer()) = value_.c_str();
|
||||
return true;
|
||||
}
|
||||
void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override
|
||||
{
|
||||
YASLI_ESCAPE(ser.size() == sizeof(StringListValue), return );
|
||||
const StringListValue& stringListValue = *((StringListValue*)(ser.pointer()));
|
||||
stringList_ = stringListValue.stringList();
|
||||
value_ = stringListValue.c_str();
|
||||
handle_ = stringListValue.handle();
|
||||
type_ = stringListValue.type();
|
||||
}
|
||||
|
||||
bool isLeaf() const override { return true; }
|
||||
bool isStatic() const override { return false; }
|
||||
int widgetSizeMin(const QPropertyTree* tree) const override
|
||||
{
|
||||
if (userWidgetToContent())
|
||||
{
|
||||
return widthCache_.getOrUpdate(tree, this, tree->_defaultRowHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
return 80;
|
||||
}
|
||||
}
|
||||
WidgetPlacement widgetPlacement() const override { return WIDGET_VALUE; }
|
||||
const void* searchHandle() const override { return handle_; }
|
||||
Serialization::TypeID typeId() const override { return type_; }
|
||||
|
||||
void redraw(const PropertyDrawContext& context) override
|
||||
{
|
||||
if (multiValue())
|
||||
{
|
||||
context.drawEntry(L" ... ", false, true, 0);
|
||||
}
|
||||
else if (userReadOnly())
|
||||
{
|
||||
context.drawValueText(pulledSelected(), valueAsWString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
QStyleOptionComboBox option;
|
||||
option.editable = false;
|
||||
option.frame = true;
|
||||
option.currentText = QString(valueAsString().c_str());
|
||||
option.state |= QStyle::State_Enabled;
|
||||
option.rect = QRect(0, 0, context.widgetRect.width(), context.widgetRect.height());
|
||||
// we have to translate painter here to work around bug in some themes
|
||||
context.painter->translate(context.widgetRect.left(), context.widgetRect.top());
|
||||
|
||||
// create a real instance of a combo so that it has the style sheet applied.
|
||||
QComboBox widgetForContext;
|
||||
context.tree->style()->drawComplexControl(QStyle::CC_ComboBox, &option, context.painter, &widgetForContext);
|
||||
context.painter->setPen(QPen(context.tree->palette().color(QPalette::WindowText)));
|
||||
QRect textRect = context.tree->style()->subControlRect(QStyle::CC_ComboBox, &option, QStyle::SC_ComboBoxEditField, &widgetForContext);
|
||||
|
||||
textRect.adjust(1, 0, -1, 0);
|
||||
context.tree->_drawRowValue(*context.painter, valueAsWString().c_str(), &context.tree->font(), textRect, context.tree->palette().color(QPalette::WindowText), false, false);
|
||||
context.painter->translate(-context.widgetRect.left(), -context.widgetRect.top());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void serializeValue(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(value_, "value", "Value");
|
||||
ar(stringList_, "stringList", "String List");
|
||||
}
|
||||
private:
|
||||
Serialization::StringList stringList_;
|
||||
string value_;
|
||||
const void* handle_;
|
||||
Serialization::TypeID type_;
|
||||
friend class PropertyRowWidgetStringListValue;
|
||||
mutable RowWidthCache widthCache_;
|
||||
};
|
||||
|
||||
using Serialization::StringListStaticValue;
|
||||
class PropertyRowStringListStaticValue
|
||||
: public PropertyRowImpl<StringListStaticValue>
|
||||
{
|
||||
public:
|
||||
PropertyRowStringListStaticValue()
|
||||
: handle_() {}
|
||||
PropertyRowWidget* createWidget(QPropertyTree* tree) override;
|
||||
string valueAsString() const override { return value_.c_str(); }
|
||||
bool assignTo(const Serialization::SStruct& ser) const override
|
||||
{
|
||||
*((StringListStaticValue*)ser.pointer()) = value_.c_str();
|
||||
return true;
|
||||
}
|
||||
void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override
|
||||
{
|
||||
YASLI_ESCAPE(ser.size() == sizeof(StringListStaticValue), return );
|
||||
const StringListStaticValue& stringListValue = *((StringListStaticValue*)(ser.pointer()));
|
||||
stringList_.resize(stringListValue.stringList().size());
|
||||
for (size_t i = 0; i < stringList_.size(); ++i)
|
||||
{
|
||||
stringList_[i] = stringListValue.stringList()[i];
|
||||
}
|
||||
value_ = stringListValue.c_str();
|
||||
handle_ = stringListValue.handle();
|
||||
type_ = stringListValue.type();
|
||||
}
|
||||
|
||||
bool isLeaf() const override { return true; }
|
||||
bool isStatic() const override { return false; }
|
||||
int widgetSizeMin(const QPropertyTree* tree) const override
|
||||
{
|
||||
if (userWidgetToContent())
|
||||
{
|
||||
return widthCache_.getOrUpdate(tree, this, tree->_defaultRowHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
return 80;
|
||||
}
|
||||
}
|
||||
WidgetPlacement widgetPlacement() const override { return WIDGET_VALUE; }
|
||||
const void* searchHandle() const override { return handle_; }
|
||||
Serialization::TypeID typeId() const override { return type_; }
|
||||
void redraw(const PropertyDrawContext& context) override
|
||||
{
|
||||
if (multiValue())
|
||||
{
|
||||
context.drawEntry(L" ... ", false, true, 0);
|
||||
}
|
||||
else if (userReadOnly())
|
||||
{
|
||||
context.drawValueText(pulledSelected(), valueAsWString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
QStyleOptionComboBox option;
|
||||
option.currentText = QString(valueAsString().c_str());
|
||||
option.state |= QStyle::State_Enabled;
|
||||
option.rect = context.widgetRect;
|
||||
|
||||
// create a real instance of a combo so that it has the style sheet applied.
|
||||
QComboBox widgetForContext;
|
||||
context.tree->style()->drawComplexControl(QStyle::CC_ComboBox, &option, context.painter, &widgetForContext);
|
||||
context.painter->setPen(QPen(context.tree->palette().color(QPalette::WindowText)));
|
||||
QRect textRect = context.tree->style()->subControlRect(QStyle::CC_ComboBox, &option, QStyle::SC_ComboBoxEditField, &widgetForContext);
|
||||
|
||||
textRect.adjust(1, 0, -1, 0);
|
||||
context.tree->_drawRowValue(*context.painter, valueAsWString().c_str(), &context.tree->font(), textRect, context.tree->palette().color(QPalette::WindowText), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void serializeValue(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(value_, "value", "Value");
|
||||
ar(stringList_, "stringList", "String List");
|
||||
}
|
||||
private:
|
||||
Serialization::StringList stringList_;
|
||||
string value_;
|
||||
const void* handle_;
|
||||
Serialization::TypeID type_;
|
||||
friend class PropertyRowWidgetStringListValue;
|
||||
mutable RowWidthCache widthCache_;
|
||||
};
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class PropertyRowWidgetStringListValue
|
||||
: public PropertyRowWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PropertyRowWidgetStringListValue(PropertyRowStringListValue* row, QPropertyTree* tree)
|
||||
: PropertyRowWidget(row, tree)
|
||||
, comboBox_(new QComboBox())
|
||||
{
|
||||
const Serialization::StringList& stringList = row->stringList_;
|
||||
for (size_t i = 0; i < stringList.size(); ++i)
|
||||
{
|
||||
comboBox_->addItem(stringList[i].c_str());
|
||||
}
|
||||
comboBox_->setCurrentIndex(stringList.find(row->value_.c_str()));
|
||||
connect(comboBox_, SIGNAL(activated(int)), this, SLOT(onChange(int)));
|
||||
}
|
||||
|
||||
PropertyRowWidgetStringListValue(PropertyRowStringListStaticValue* row, QPropertyTree* tree)
|
||||
: PropertyRowWidget(row, tree)
|
||||
, comboBox_(new QComboBox())
|
||||
{
|
||||
const Serialization::StringList& stringList = row->stringList_;
|
||||
for (size_t i = 0; i < stringList.size(); ++i)
|
||||
{
|
||||
comboBox_->addItem(stringList[i].c_str());
|
||||
}
|
||||
comboBox_->setCurrentIndex(stringList.find(row->value_.c_str()));
|
||||
connect(comboBox_, SIGNAL(currentIndexChanged(int)), this, SLOT(onChange(int)));
|
||||
}
|
||||
|
||||
void showPopup() override
|
||||
{
|
||||
// Here comboBox_->showPopup() should be sufficient, but sadly with Fusion
|
||||
// theme ComboBox, when clicked, it fires a mouseReleseTimer, which doesn't
|
||||
// happen with showPopup. It is used to distinguish click-and-hold from
|
||||
// simple click. If timer is not fired following mouse release hides combo
|
||||
// box. That's why the user click is emulated here.
|
||||
QSize size = comboBox_->size();
|
||||
QPoint localPoint = QPoint(aznumeric_cast<int>(size.width() * 0.5f), aznumeric_cast<int>(size.height() * 0.5f));
|
||||
QMouseEvent ev(QMouseEvent::MouseButtonPress, localPoint, comboBox_->mapToGlobal(localPoint), Qt::LeftButton, Qt::LeftButton, Qt::KeyboardModifiers());
|
||||
QApplication::sendEvent(comboBox_, &ev);
|
||||
}
|
||||
|
||||
~PropertyRowWidgetStringListValue()
|
||||
{
|
||||
comboBox_->hide();
|
||||
comboBox_->setParent(0);
|
||||
comboBox_->deleteLater();
|
||||
comboBox_ = 0;
|
||||
}
|
||||
|
||||
|
||||
void commit(){}
|
||||
QWidget* actualWidget() { return comboBox_; }
|
||||
public slots:
|
||||
void onChange(int)
|
||||
{
|
||||
if (strcmp(this->row()->typeName(), Serialization::TypeID::get<StringListValue>().name()) == 0)
|
||||
{
|
||||
PropertyRowStringListValue* r = static_cast<PropertyRowStringListValue*>(this->row());
|
||||
QByteArray newValue = comboBox_->currentText().toUtf8();
|
||||
if (r->value_ != newValue.data())
|
||||
{
|
||||
model()->rowAboutToBeChanged(r);
|
||||
r->value_ = newValue.data();
|
||||
model()->rowChanged(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree_->_cancelWidget();
|
||||
}
|
||||
}
|
||||
else if (strcmp(this->row()->typeName(), Serialization::TypeID::get<StringListStaticValue>().name()) == 0)
|
||||
{
|
||||
PropertyRowStringListStaticValue* r = static_cast<PropertyRowStringListStaticValue*>(this->row());
|
||||
QByteArray newValue = comboBox_->currentText().toUtf8();
|
||||
if (r->value_ != newValue.data())
|
||||
{
|
||||
model()->rowAboutToBeChanged(r);
|
||||
r->value_ = newValue.data();
|
||||
model()->rowChanged(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree_->_cancelWidget();
|
||||
}
|
||||
}
|
||||
}
|
||||
protected:
|
||||
QComboBox* comboBox_;
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWSTRINGLISTVALUE_H
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "PropertyRowTagList.h"
|
||||
#include "PropertyRowString.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "Serialization/Decorators/TagList.h"
|
||||
#include "Serialization/ClassFactory.h"
|
||||
#include "Serialization/IArchive.h"
|
||||
#include "Serialization/Decorators/TagListImpl.h"
|
||||
#include <QMenu>
|
||||
|
||||
PropertyRowTagList::PropertyRowTagList()
|
||||
: source_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PropertyRowTagList::~PropertyRowTagList()
|
||||
{
|
||||
if (source_)
|
||||
{
|
||||
source_->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyRowTagList::generateMenu(QMenu& item, QPropertyTree* tree, [[maybe_unused]] bool addActions)
|
||||
{
|
||||
if (userReadOnly() || isFixedSize())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!source_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TagListMenuHandler* handler = new TagListMenuHandler();
|
||||
handler->tree = tree;
|
||||
handler->row = this;
|
||||
tree->addMenuHandler(handler);
|
||||
|
||||
unsigned int numGroups = source_->GroupCount();
|
||||
for (unsigned int group = 0; group < numGroups; ++group)
|
||||
{
|
||||
unsigned int tagCount = source_->TagCount(group);
|
||||
if (tagCount == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const char* groupName = source_->GroupName(group);
|
||||
QString title = QString("From ") + groupName;
|
||||
QMenu* menu = item.addMenu(title);
|
||||
for (unsigned int tagIndex = 0; tagIndex < tagCount; ++tagIndex)
|
||||
{
|
||||
QString str;
|
||||
str = source_->TagValue(group, tagIndex);
|
||||
const char* desc = source_->TagDescription(group, tagIndex);
|
||||
if (desc && desc[0] != '\0')
|
||||
{
|
||||
str += "\t";
|
||||
str += desc;
|
||||
}
|
||||
QAction* action = menu->addAction(str);
|
||||
QString tag = QString::fromLocal8Bit(source_->TagValue(group, tagIndex));
|
||||
action->setData(QVariant(tag));
|
||||
QObject::connect(action, SIGNAL(triggered()), handler, SLOT(onMenuAddTag()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QAction* action = item.addAction("Add");
|
||||
action->setData(QVariant(QString()));
|
||||
QObject::connect(action, SIGNAL(triggered()), handler, SLOT(onMenuAddTag()));
|
||||
|
||||
PropertyRowContainer::generateMenu(item, tree, false);
|
||||
}
|
||||
|
||||
void PropertyRowTagList::addTag(const char* tag, QPropertyTree* tree)
|
||||
{
|
||||
Serialization::SharedPtr<PropertyRowTagList> ref(this);
|
||||
|
||||
PropertyRow* child = addElement(tree, false);
|
||||
if (child && strcmp(child->typeName(), "string") == 0)
|
||||
{
|
||||
PropertyRowString* stringRow = static_cast<PropertyRowString*>(child);
|
||||
tree->model()->rowAboutToBeChanged(stringRow);
|
||||
stringRow->setValue(tag, stringRow->searchHandle(), stringRow->typeId());
|
||||
tree->model()->rowChanged(stringRow);
|
||||
}
|
||||
}
|
||||
|
||||
void TagListMenuHandler::onMenuAddTag()
|
||||
{
|
||||
if (QAction* action = qobject_cast<QAction*>(sender()))
|
||||
{
|
||||
QString str = action->data().toString();
|
||||
row->addTag(str.toLocal8Bit().data(), tree);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyRowTagList::setValueAndContext(const Serialization::IContainer& value, Serialization::IArchive& ar)
|
||||
{
|
||||
if (source_)
|
||||
{
|
||||
source_->Release();
|
||||
}
|
||||
source_ = ar.FindContext<ITagSource>();
|
||||
if (source_)
|
||||
{
|
||||
source_->AddRef();
|
||||
}
|
||||
|
||||
PropertyRowContainer::setValueAndContext(value, ar);
|
||||
}
|
||||
|
||||
|
||||
REGISTER_PROPERTY_ROW(TagList, PropertyRowTagList)
|
||||
DECLARE_SEGMENT(PropertyRowTagList)
|
||||
|
||||
#include <QPropertyTree/moc_PropertyRowTagList.cpp>
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWTAGLIST_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWTAGLIST_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "PropertyRowContainer.h"
|
||||
#endif
|
||||
|
||||
struct ITagSource;
|
||||
|
||||
class PropertyRowTagList
|
||||
: public PropertyRowContainer
|
||||
{
|
||||
public:
|
||||
PropertyRowTagList();
|
||||
~PropertyRowTagList();
|
||||
void setValueAndContext(const Serialization::IContainer& value, Serialization::IArchive& ar) override;
|
||||
void generateMenu(QMenu& item, QPropertyTree* tree, bool addActions) override;
|
||||
void addTag(const char* tag, QPropertyTree* tree);
|
||||
|
||||
private:
|
||||
using PropertyRow::setValueAndContext;
|
||||
ITagSource* source_;
|
||||
};
|
||||
|
||||
struct TagListMenuHandler
|
||||
: public PropertyRowMenuHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
PropertyRowTagList * row;
|
||||
QPropertyTree* tree;
|
||||
public slots:
|
||||
void onMenuAddTag();
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYROWTAGLIST_H
|
||||
@@ -1,205 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include <QIcon>
|
||||
|
||||
#include "Serialization/ClassFactory.h"
|
||||
#include "PropertyDrawContext.h"
|
||||
#include "PropertyRowImpl.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "Serialization.h"
|
||||
#include "Color.h"
|
||||
#include "Unicode.h"
|
||||
#include "Serialization/Decorators/ToggleButton.h"
|
||||
using Serialization::ToggleButton;
|
||||
using Serialization::RadioButton;
|
||||
|
||||
class PropertyRowToggleButton
|
||||
: public PropertyRow
|
||||
{
|
||||
public:
|
||||
PropertyRowToggleButton()
|
||||
: underMouse_(false)
|
||||
, value_(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool isLeaf() const{ return true; }
|
||||
bool isStatic() const{ return false; }
|
||||
bool isSelectable() const{ return true; }
|
||||
|
||||
void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override
|
||||
{
|
||||
ToggleButton* value = (ToggleButton*)(ser.pointer());
|
||||
value_ = *value->value;
|
||||
}
|
||||
|
||||
bool assignTo(const Serialization::SStruct& ser) const override
|
||||
{
|
||||
ToggleButton* value = (ToggleButton*)(ser.pointer());
|
||||
*value->value = value_;
|
||||
return true;
|
||||
}
|
||||
wstring valueAsWString() const override { return L""; }
|
||||
WidgetPlacement widgetPlacement() const override { return WIDGET_INSTEAD_OF_TEXT; }
|
||||
void serializeValue([[maybe_unused]] Serialization::IArchive& ar) {}
|
||||
int widgetSizeMin([[maybe_unused]] const QPropertyTree* tree) const override { return 36; }
|
||||
|
||||
bool onActivate(const PropertyActivationEvent& e) override
|
||||
{
|
||||
if (e.reason == PropertyActivationEvent::REASON_KEYBOARD)
|
||||
{
|
||||
value_;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool onMouseDown(QPropertyTree* tree, QPoint point, [[maybe_unused]] bool& changed) override
|
||||
{
|
||||
if (widgetRect(tree).contains(point))
|
||||
{
|
||||
underMouse_ = true;
|
||||
pressed_ = true;
|
||||
tree->update();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void onMouseDrag(const PropertyDragEvent& e) override
|
||||
{
|
||||
bool underMouse = widgetRect(e.tree).contains(e.pos);
|
||||
if (underMouse != underMouse_)
|
||||
{
|
||||
underMouse_ = underMouse;
|
||||
e.tree->update();
|
||||
}
|
||||
}
|
||||
|
||||
void onMouseUp(QPropertyTree* tree, QPoint point) override
|
||||
{
|
||||
if (widgetRect(tree).contains(point))
|
||||
{
|
||||
tree->model()->rowAboutToBeChanged(this);
|
||||
pressed_ = false;
|
||||
value_ = !value_;
|
||||
tree->model()->rowChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
void redraw(const PropertyDrawContext& context) override
|
||||
{
|
||||
QRect rect = context.widgetRect;
|
||||
|
||||
wstring text = toWideChar(labelUndecorated());
|
||||
int buttonFlags = BUTTON_CENTER;
|
||||
if ((value_ || pressed_) && underMouse_)
|
||||
{
|
||||
buttonFlags |= BUTTON_PRESSED;
|
||||
}
|
||||
if (selected() || pressed_)
|
||||
{
|
||||
buttonFlags |= BUTTON_FOCUSED;
|
||||
}
|
||||
if (userReadOnly())
|
||||
{
|
||||
buttonFlags |= BUTTON_DISABLED;
|
||||
}
|
||||
context.drawButton(rect, text.c_str(), buttonFlags, &context.tree->font());
|
||||
}
|
||||
protected:
|
||||
bool pressed_ : 1;
|
||||
bool underMouse_ : 1;
|
||||
bool value_ : 1;
|
||||
};
|
||||
|
||||
class PropertyRowRadioButton
|
||||
: public PropertyRow
|
||||
{
|
||||
public:
|
||||
|
||||
bool isLeaf() const override { return true; }
|
||||
bool isStatic() const override { return false; }
|
||||
bool isSelectable() const override { return false; }
|
||||
|
||||
bool onActivate(const PropertyActivationEvent& e) override
|
||||
{
|
||||
if (!m_justSet)
|
||||
{
|
||||
e.tree->model()->rowAboutToBeChanged(this);
|
||||
m_justSet = true;
|
||||
e.tree->model()->rowChanged(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void setValueAndContext(const Serialization::SStruct& ser, [[maybe_unused]] Serialization::IArchive& ar) override
|
||||
{
|
||||
RadioButton* value = (RadioButton*)(ser.pointer());
|
||||
m_value = value->buttonValue;
|
||||
m_toggled = m_value == *value->value;
|
||||
m_justSet = false;
|
||||
}
|
||||
bool assignTo(const Serialization::SStruct& ser) const override
|
||||
{
|
||||
if (m_justSet)
|
||||
{
|
||||
*((RadioButton*)ser.pointer())->value = m_value;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
wstring valueAsWString() const override { return L""; }
|
||||
WidgetPlacement widgetPlacement() const override { return WIDGET_INSTEAD_OF_TEXT; }
|
||||
void serializeValue(Serialization::IArchive& ar) override
|
||||
{
|
||||
bool oldToggled = m_toggled;
|
||||
ar(m_toggled, "toggled");
|
||||
if (m_toggled && !oldToggled)
|
||||
{
|
||||
m_justSet = true;
|
||||
}
|
||||
ar(m_value, "value");
|
||||
}
|
||||
int widgetSizeMin([[maybe_unused]] const QPropertyTree* tree) const override { return 40; }
|
||||
|
||||
void redraw(const PropertyDrawContext& context)
|
||||
{
|
||||
QRect rect = context.widgetRect;
|
||||
bool pressed = context.m_pressed || m_toggled || m_justSet;
|
||||
|
||||
wstring text = toWideChar(labelUndecorated());
|
||||
int buttonFlags = BUTTON_CENTER;
|
||||
if (pressed)
|
||||
{
|
||||
buttonFlags |= BUTTON_PRESSED;
|
||||
}
|
||||
if (selected())
|
||||
{
|
||||
buttonFlags |= BUTTON_FOCUSED;
|
||||
}
|
||||
if (userReadOnly())
|
||||
{
|
||||
buttonFlags |= BUTTON_DISABLED;
|
||||
}
|
||||
context.drawButton(rect, text.c_str(), buttonFlags, &context.tree->font());
|
||||
}
|
||||
protected:
|
||||
bool m_toggled;
|
||||
bool m_justSet;
|
||||
int m_value;
|
||||
};
|
||||
|
||||
REGISTER_PROPERTY_ROW(ToggleButton, PropertyRowToggleButton);
|
||||
REGISTER_PROPERTY_ROW(RadioButton, PropertyRowRadioButton);
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEMENUHANDLER_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEMENUHANDLER_H
|
||||
#pragma once
|
||||
|
||||
#include "PropertyRow.h"
|
||||
|
||||
struct PropertyTreeMenuHandler
|
||||
: PropertyRowMenuHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PropertyRow * row;
|
||||
QPropertyTree* tree;
|
||||
|
||||
string filterName;
|
||||
string filterValue;
|
||||
string filterType;
|
||||
|
||||
public slots:
|
||||
void onMenuFilter();
|
||||
void onMenuFilterByName();
|
||||
void onMenuFilterByValue();
|
||||
void onMenuFilterByType();
|
||||
|
||||
void onMenuUndo();
|
||||
void onMenuRedo();
|
||||
|
||||
void onMenuCopy();
|
||||
void onMenuPaste();
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEMENUHANDLER_H
|
||||
@@ -1,445 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "PropertyTreeModel.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "Serialization.h"
|
||||
#include "Serialization/ClassFactory.h"
|
||||
#include "Serialization/Callback.h"
|
||||
|
||||
PropertyTreeModel::PropertyTreeModel()
|
||||
: expandLevels_(0)
|
||||
, undoEnabled_(true)
|
||||
, fullUndo_(false)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
PropertyTreeModel::~PropertyTreeModel()
|
||||
{
|
||||
root_ = 0;
|
||||
defaultTypes_.clear();
|
||||
defaultTypesPoly_.clear();
|
||||
}
|
||||
|
||||
TreePath PropertyTreeModel::pathFromRow(PropertyRow* row)
|
||||
{
|
||||
TreePath result;
|
||||
if(row)
|
||||
{
|
||||
while(row->parent()){
|
||||
int childIndex = row->parent()->childIndex(row);
|
||||
YASLI_ESCAPE(childIndex >= 0, return TreePath());
|
||||
result.insert(result.begin(), childIndex);
|
||||
row = row->parent();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void PropertyTreeModel::selectRow(PropertyRow* row, bool select, bool exclusive)
|
||||
{
|
||||
if(exclusive)
|
||||
deselectAll();
|
||||
|
||||
row->setSelected(select);
|
||||
|
||||
Selection::iterator it = std::find(selection_.begin(), selection_.end(), pathFromRow(row));
|
||||
if(select){
|
||||
if(it == selection_.end())
|
||||
selection_.push_back(pathFromRow(row));
|
||||
setFocusedRow(row);
|
||||
}
|
||||
else if(it != selection_.end()){
|
||||
#if !defined(NDEBUG)
|
||||
PropertyRow* it_row = rowFromPath(*it);
|
||||
#endif
|
||||
YASLI_ASSERT(it_row->refCount() > 0 && it_row->refCount() < 0xFFFF);
|
||||
selection_.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyTreeModel::deselectAll()
|
||||
{
|
||||
Selection::iterator it;
|
||||
for(it = selection_.begin(); it != selection_.end(); ++it){
|
||||
PropertyRow* row = rowFromPath(*it);
|
||||
row->setSelected(false);
|
||||
}
|
||||
selection_.clear();
|
||||
}
|
||||
|
||||
PropertyRow* PropertyTreeModel::rowFromPath(const TreePath& path)
|
||||
{
|
||||
PropertyRow* row = root();
|
||||
if (!root())
|
||||
return 0;
|
||||
TreePath::const_iterator it;
|
||||
for(it = path.begin(); it != path.end(); ++it){
|
||||
int index = it->index;
|
||||
if(index < int(row->count()) && index >= 0){
|
||||
PropertyRow* nextRow = row->childByIndex(index);
|
||||
if(!nextRow)
|
||||
return row;
|
||||
else
|
||||
row = nextRow;
|
||||
}
|
||||
else
|
||||
return row;
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
void PropertyTreeModel::setSelection(const Selection& selection)
|
||||
{
|
||||
deselectAll();
|
||||
Selection::const_iterator it;
|
||||
for(it = selection.begin(); it != selection.end(); ++it){
|
||||
const TreePath& path = *it;
|
||||
PropertyRow* row = rowFromPath(path);
|
||||
if(row)
|
||||
selectRow(row, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyTreeModel::clear()
|
||||
{
|
||||
if(root_)
|
||||
root_->clear();
|
||||
root_ = 0;
|
||||
setRoot(new PropertyRow());
|
||||
root_->setNames("", "root", "");
|
||||
selection_.clear();
|
||||
}
|
||||
|
||||
void PropertyTreeModel::onUpdated(const PropertyRows& rows, bool needApply)
|
||||
{
|
||||
signalUpdated(rows, needApply);
|
||||
}
|
||||
|
||||
void PropertyTreeModel::applyOperator(PropertyTreeOperator* op)
|
||||
{
|
||||
YASLI_ESCAPE(op, return);
|
||||
PropertyRow *dest = rowFromPath(op->path_);
|
||||
YASLI_ESCAPE(dest && "Unable to apply operator!", return);
|
||||
if(op->type_ == PropertyTreeOperator::NONE)
|
||||
return;
|
||||
YASLI_ESCAPE(op->row_, return);
|
||||
if(dest->parent())
|
||||
dest->parent()->replaceAndPreserveState(dest, op->row_, 0);
|
||||
else{
|
||||
op->row_->assignRowProperties(root_);
|
||||
root_ = op->row_;
|
||||
}
|
||||
PropertyRow* newRow = op->row_;
|
||||
op->row_ = 0;
|
||||
rowChanged(newRow);
|
||||
}
|
||||
|
||||
void PropertyTreeModel::undo()
|
||||
{
|
||||
YASLI_ESCAPE(!undoOperators_.empty(), return);
|
||||
|
||||
auto op = &undoOperators_.back();
|
||||
PropertyRow *dest = rowFromPath(op->path_);
|
||||
PropertyTreeOperator redoOp = getCurrentStateTreeOperator(dest);
|
||||
|
||||
applyOperator(op);
|
||||
undoOperators_.pop_back();
|
||||
|
||||
pushRedo(redoOp);
|
||||
}
|
||||
|
||||
void PropertyTreeModel::redo()
|
||||
{
|
||||
YASLI_ESCAPE(!redoOperators_.empty(), return);
|
||||
|
||||
auto op = &redoOperators_.back();
|
||||
PropertyRow *dest = rowFromPath(op->path_);
|
||||
PropertyTreeOperator undoOp = getCurrentStateTreeOperator(dest);
|
||||
|
||||
applyOperator(op);
|
||||
redoOperators_.pop_back();
|
||||
|
||||
pushUndo(undoOp);
|
||||
}
|
||||
|
||||
void PropertyTreeModel::clearUndo()
|
||||
{
|
||||
undoOperators_.clear();
|
||||
redoOperators_.clear();
|
||||
|
||||
Q_EMIT signalUndoRedoStackChanged(false, false);
|
||||
}
|
||||
|
||||
PropertyTreeModel::UpdateLock PropertyTreeModel::lockUpdate()
|
||||
{
|
||||
if(updateLock_)
|
||||
return updateLock_;
|
||||
else {
|
||||
UpdateLock lock = new PropertyTreeModel::LockedUpdate(this);;
|
||||
updateLock_ = lock;
|
||||
lock->release();
|
||||
return lock;
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyTreeModel::dismissUpdate()
|
||||
{
|
||||
if(updateLock_)
|
||||
updateLock_->dismissUpdate();
|
||||
}
|
||||
|
||||
void PropertyTreeModel::requestUpdate(const PropertyRows& rows, bool apply)
|
||||
{
|
||||
if(updateLock_)
|
||||
updateLock_->requestUpdate(rows, apply);
|
||||
else
|
||||
onUpdated(rows, apply);
|
||||
}
|
||||
|
||||
struct RowObtainer {
|
||||
RowObtainer(std::vector<char>& states) : states_(states) {}
|
||||
ScanResult operator()(PropertyRow* row)
|
||||
{
|
||||
states_.push_back(row->expanded() ? 1 : 0);
|
||||
return row->expanded() ? SCAN_CHILDREN_SIBLINGS : SCAN_SIBLINGS;
|
||||
}
|
||||
protected:
|
||||
std::vector<char>& states_;
|
||||
};
|
||||
|
||||
struct RowExpander {
|
||||
RowExpander(const std::vector<char>& states) : states_(states), index_(0) {}
|
||||
ScanResult operator()(PropertyRow* row, QPropertyTree* tree, [[maybe_unused]] int index)
|
||||
{
|
||||
if(size_t(index_) >= states_.size())
|
||||
return SCAN_FINISHED;
|
||||
|
||||
if(states_[index_++]){
|
||||
if(row->canBeToggled(tree))
|
||||
row->_setExpanded(true);
|
||||
return SCAN_CHILDREN_SIBLINGS;
|
||||
}
|
||||
else{
|
||||
row->_setExpanded(false);
|
||||
return SCAN_SIBLINGS;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
int index_;
|
||||
const std::vector<char>& states_;
|
||||
};
|
||||
|
||||
void PropertyTreeModel::Serialize(Serialization::IArchive& ar, QPropertyTree* tree)
|
||||
{
|
||||
ar(focusedRow_, "focusedRow", 0);
|
||||
ar(selection_, "selection", 0);
|
||||
|
||||
if (root()) {
|
||||
std::vector<char> expanded;
|
||||
if(ar.IsOutput()) {
|
||||
RowObtainer op(expanded);
|
||||
root()->scanChildren(op);
|
||||
}
|
||||
ar(expanded, "expanded", 0);
|
||||
if(ar.IsInput()){
|
||||
Selection sel = selection_;
|
||||
setSelection(sel);
|
||||
RowExpander op(expanded);
|
||||
root()->scanChildren(op, tree);
|
||||
root()->setLayoutChanged();
|
||||
root()->setLayoutChangedToChildren();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyTreeModel::pushUndo(const PropertyTreeOperator& op)
|
||||
{
|
||||
PropertyTreeOperator oper = op;
|
||||
bool handled = false;
|
||||
signalPushUndo(&oper, &handled);
|
||||
if(!handled && oper.row_ != 0)
|
||||
undoOperators_.push_back(oper);
|
||||
|
||||
Q_EMIT signalUndoRedoStackChanged(!undoOperators_.empty(), !redoOperators_.empty());
|
||||
}
|
||||
|
||||
void PropertyTreeModel::pushRedo(const PropertyTreeOperator& op)
|
||||
{
|
||||
PropertyTreeOperator oper = op;
|
||||
bool handled = false;
|
||||
signalPushRedo(&oper, &handled);
|
||||
if (!handled && oper.row_ != 0)
|
||||
redoOperators_.push_back(oper);
|
||||
|
||||
Q_EMIT signalUndoRedoStackChanged(!undoOperators_.empty(), !redoOperators_.empty());
|
||||
}
|
||||
|
||||
PropertyTreeOperator PropertyTreeModel::getCurrentStateTreeOperator(PropertyRow* row)
|
||||
{
|
||||
if (fullUndo_){
|
||||
if (undoEnabled_){
|
||||
SharedPtr<PropertyRow> clonedRow = root()->clone(constStrings());
|
||||
clonedRow->assignRowState(*root(), true);
|
||||
return PropertyTreeOperator(TreePath(), clonedRow);
|
||||
}
|
||||
else{
|
||||
return PropertyTreeOperator(TreePath(), 0);
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (undoEnabled_){
|
||||
SharedPtr<PropertyRow> clonedRow = row->clone(constStrings());
|
||||
clonedRow->assignRowState(*row, true);
|
||||
return PropertyTreeOperator(pathFromRow(row), clonedRow);
|
||||
}
|
||||
else{
|
||||
return PropertyTreeOperator(pathFromRow(row), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyTreeModel::rowAboutToBeChanged(PropertyRow* row)
|
||||
{
|
||||
YASLI_ESCAPE(row, return);
|
||||
pushUndo(getCurrentStateTreeOperator(row));
|
||||
|
||||
// clear the redo stack now
|
||||
redoOperators_.clear();
|
||||
Q_EMIT signalUndoRedoStackChanged(true, false);
|
||||
}
|
||||
|
||||
void PropertyTreeModel::callRowCallback(PropertyRow* row)
|
||||
{
|
||||
PropertyRow* current = row;
|
||||
while (true) {
|
||||
Serialization::ICallback* callback = current->callback();
|
||||
if (callback) {
|
||||
auto applyFunc = [=](void* arg, [[maybe_unused]] const TypeID& type) {
|
||||
current->assignToByPointer(arg, callback->Type());
|
||||
};
|
||||
callback->Call(applyFunc);
|
||||
return;
|
||||
}
|
||||
current = current->parent();
|
||||
if (current)
|
||||
current->handleChildrenChange();
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyTreeModel::rowChanged(PropertyRow* row, bool apply)
|
||||
{
|
||||
callRowCallback(row);
|
||||
|
||||
YASLI_ESCAPE(row, return);
|
||||
row->setLabelChanged();
|
||||
row->setLayoutChanged();
|
||||
|
||||
PropertyRow* parentObj = row;
|
||||
while (parentObj->parent() && !parentObj->isObject())
|
||||
parentObj = parentObj->parent();
|
||||
|
||||
row->setMultiValue(false);
|
||||
|
||||
PropertyRows rows;
|
||||
rows.push_back(parentObj);
|
||||
requestUpdate(rows, apply);
|
||||
}
|
||||
|
||||
bool PropertyTreeModel::defaultTypeRegistered(const char* typeName) const
|
||||
{
|
||||
return defaultTypes_.find(typeName) != defaultTypes_.end();
|
||||
}
|
||||
|
||||
void PropertyTreeModel::addDefaultType(PropertyRow* row, const char* typeName)
|
||||
{
|
||||
YASLI_ESCAPE(typeName != 0, return);
|
||||
defaultTypes_[typeName] = row;
|
||||
}
|
||||
|
||||
PropertyRow* PropertyTreeModel::defaultType(const char* typeName) const
|
||||
{
|
||||
DefaultTypes::const_iterator it = defaultTypes_.find(typeName);
|
||||
YASLI_ESCAPE(it != defaultTypes_.end(), return 0);
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void PropertyTreeModel::addDefaultType(const TypeID& type, const PropertyDefaultDerivedTypeValue& value)
|
||||
{
|
||||
YASLI_ASSERT(type != TypeID());
|
||||
|
||||
BaseClass& base = defaultTypesPoly_[type];
|
||||
for (DerivedTypes::iterator it = base.types.begin(); it != base.types.end(); ++it){
|
||||
if (it->registeredName == value.registeredName) {
|
||||
YASLI_ASSERT(it->root == 0);
|
||||
*it = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
base.types.push_back(value);
|
||||
base.strings.push_back(value.label.c_str());
|
||||
}
|
||||
|
||||
const PropertyDefaultDerivedTypeValue* PropertyTreeModel::defaultType(const TypeID& baseType, int derivedIndex) const
|
||||
{
|
||||
DefaultTypesPoly::const_iterator it = defaultTypesPoly_.find(baseType);
|
||||
YASLI_ESCAPE(it != defaultTypesPoly_.end(), return 0);
|
||||
const BaseClass& base = it->second;
|
||||
YASLI_ESCAPE(size_t(derivedIndex) < base.types.size(), return 0);
|
||||
return &base.types[derivedIndex];
|
||||
}
|
||||
|
||||
bool PropertyTreeModel::defaultTypeRegistered(const TypeID& baseType, const char* derivedRegisteredName) const
|
||||
{
|
||||
if (!derivedRegisteredName)
|
||||
derivedRegisteredName = "";
|
||||
DefaultTypesPoly::const_iterator it = defaultTypesPoly_.find(baseType);
|
||||
|
||||
if (it == defaultTypesPoly_.end())
|
||||
return false;
|
||||
|
||||
const BaseClass& base = it->second;
|
||||
DerivedTypes::const_iterator dit;
|
||||
for (dit = base.types.begin(); dit != base.types.end(); ++dit){
|
||||
if (dit->registeredName == derivedRegisteredName)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const Serialization::StringList& PropertyTreeModel::typeStringList(const TypeID& baseType) const
|
||||
{
|
||||
DefaultTypesPoly::const_iterator it = defaultTypesPoly_.find(baseType);
|
||||
|
||||
static Serialization::StringList empty;
|
||||
YASLI_ESCAPE(it != defaultTypesPoly_.end(), return empty);
|
||||
const BaseClass& base = it->second;
|
||||
return base.strings;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
bool Serialize(Serialization::IArchive& ar, TreePathLeaf& value, const char* name, const char* label)
|
||||
{
|
||||
return ar(value.index, name, label);
|
||||
}
|
||||
|
||||
bool Serialize(Serialization::IArchive& ar, TreeSelection& value, const char* name, const char* label)
|
||||
{
|
||||
return ar(static_cast<std::vector<TreePath>&>(value), name, label);
|
||||
}
|
||||
|
||||
#include <QPropertyTree/moc_PropertyTreeModel.cpp>
|
||||
@@ -1,208 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEMODEL_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEMODEL_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <map>
|
||||
#include "PropertyRow.h"
|
||||
#include "PropertyTreeOperator.h"
|
||||
#include "Serialization/Pointers.h"
|
||||
#endif
|
||||
|
||||
using std::vector;
|
||||
using std::map;
|
||||
|
||||
struct TreeSelection : vector<TreePath>
|
||||
{
|
||||
bool operator==(const TreeSelection& rhs){
|
||||
if(size() != rhs.size())
|
||||
return false;
|
||||
for(int i = 0; i < int(size()); ++i)
|
||||
if((*this)[i] != rhs[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct PropertyDefaultDerivedTypeValue
|
||||
{
|
||||
string registeredName;
|
||||
Serialization::SharedPtr<PropertyRow> root;
|
||||
Serialization::IClassFactory* factory;
|
||||
int factoryIndex;
|
||||
std::string label;
|
||||
|
||||
PropertyDefaultDerivedTypeValue()
|
||||
: factoryIndex(-1)
|
||||
, factory(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct PropertyDefaultTypeValue
|
||||
{
|
||||
Serialization::TypeID type;
|
||||
string registedName;
|
||||
Serialization::SharedPtr<PropertyRow> root;
|
||||
Serialization::IClassFactory* factory;
|
||||
int factoryIndex;
|
||||
std::string label;
|
||||
|
||||
PropertyDefaultTypeValue()
|
||||
: factoryIndex(-1)
|
||||
, factory(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class PropertyTreeModel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
class LockedUpdate : public Serialization::RefCounter{
|
||||
public:
|
||||
LockedUpdate(PropertyTreeModel* model)
|
||||
: model_(model)
|
||||
, apply_(false)
|
||||
{}
|
||||
void requestUpdate(const PropertyRows& rows, bool apply) {
|
||||
for (size_t i = 0; i < rows.size(); ++i) {
|
||||
PropertyRow* row = rows[i];
|
||||
if (std::find(rows_.begin(), rows_.end(), row) == rows_.end())
|
||||
rows_.push_back(row);
|
||||
}
|
||||
if (apply)
|
||||
apply_ = true;
|
||||
}
|
||||
void dismissUpdate(){ rows_.clear(); }
|
||||
~LockedUpdate(){
|
||||
model_->updateLock_ = 0;
|
||||
if(!rows_.empty())
|
||||
model_->signalUpdated(rows_, apply_);
|
||||
}
|
||||
protected:
|
||||
PropertyTreeModel* model_;
|
||||
PropertyRows rows_;
|
||||
bool apply_;
|
||||
};
|
||||
typedef Serialization::SharedPtr<LockedUpdate> UpdateLock;
|
||||
|
||||
typedef TreeSelection Selection;
|
||||
|
||||
PropertyTreeModel();
|
||||
~PropertyTreeModel();
|
||||
|
||||
void clear();
|
||||
bool canUndo() const{ return !undoOperators_.empty(); }
|
||||
void undo();
|
||||
bool canRedo() const{ return !redoOperators_.empty(); }
|
||||
void redo();
|
||||
void clearUndo();
|
||||
|
||||
TreePath pathFromRow(PropertyRow* node);
|
||||
PropertyRow* rowFromPath(const TreePath& path);
|
||||
void setFocusedRow(PropertyRow* row) { focusedRow_ = pathFromRow(row); }
|
||||
PropertyRow* focusedRow() { return rowFromPath(focusedRow_); }
|
||||
|
||||
const Selection& selection() const{ return selection_; }
|
||||
void setSelection(const Selection& selection);
|
||||
|
||||
void setRoot(PropertyRow* root) { root_ = root; }
|
||||
PropertyRow* root() { return root_; }
|
||||
const PropertyRow* root() const { return root_; }
|
||||
|
||||
void Serialize(Serialization::IArchive& ar, QPropertyTree* tree);
|
||||
|
||||
UpdateLock lockUpdate();
|
||||
void requestUpdate(const PropertyRows& rows, bool needApply);
|
||||
void dismissUpdate();
|
||||
|
||||
void selectRow(PropertyRow* row, bool selected, bool exclusive = true);
|
||||
void deselectAll();
|
||||
|
||||
void rowAboutToBeChanged(PropertyRow* row);
|
||||
void callRowCallback(PropertyRow* row);
|
||||
void rowChanged(PropertyRow* row, bool apply = true); // be careful: it can destroy 'row'
|
||||
|
||||
void setUndoEnabled(bool enabled) { undoEnabled_ = enabled; }
|
||||
void setFullUndo(bool fullUndo) { fullUndo_ = fullUndo; }
|
||||
void setExpandLevels(int levels) { expandLevels_ = levels; }
|
||||
int expandLevels() const{ return expandLevels_; }
|
||||
|
||||
void onUpdated(const PropertyRows& rows, bool needApply);
|
||||
|
||||
// for defaultArchive
|
||||
const Serialization::StringList& typeStringList(const Serialization::TypeID& baseType) const;
|
||||
|
||||
bool defaultTypeRegistered(const char* typeName) const;
|
||||
void addDefaultType(PropertyRow* propertyRow, const char* typeName);
|
||||
PropertyRow* defaultType(const char* typeName) const;
|
||||
|
||||
bool defaultTypeRegistered(const Serialization::TypeID& baseType, const char* derivedRegisteredName) const;
|
||||
void addDefaultType(const Serialization::TypeID& baseType, const PropertyDefaultDerivedTypeValue& value);
|
||||
const PropertyDefaultDerivedTypeValue* defaultType(const Serialization::TypeID& baseType, int index) const;
|
||||
ConstStringList* constStrings() { return &constStrings_; }
|
||||
|
||||
signals:
|
||||
void signalUpdated(const PropertyRows& rows, bool needApply);
|
||||
void signalPushUndo(PropertyTreeOperator* op, bool* result);
|
||||
void signalPushRedo(PropertyTreeOperator* op, bool* result);
|
||||
|
||||
void signalUndoRedoStackChanged(bool undosAvailable, bool redosAvailable);
|
||||
private:
|
||||
void applyOperator(PropertyTreeOperator* op);
|
||||
void pushUndo(const PropertyTreeOperator& op);
|
||||
void pushRedo(const PropertyTreeOperator& op);
|
||||
|
||||
void clearObjectReferences();
|
||||
PropertyTreeOperator getCurrentStateTreeOperator(PropertyRow* row);
|
||||
|
||||
TreePath focusedRow_;
|
||||
Selection selection_;
|
||||
|
||||
Serialization::SharedPtr<PropertyRow> root_;
|
||||
UpdateLock updateLock_;
|
||||
|
||||
typedef std::map<string, Serialization::SharedPtr<PropertyRow> > DefaultTypes;
|
||||
DefaultTypes defaultTypes_;
|
||||
|
||||
|
||||
typedef vector<PropertyDefaultDerivedTypeValue> DerivedTypes;
|
||||
struct BaseClass{
|
||||
Serialization::TypeID type;
|
||||
std::string name;
|
||||
Serialization::StringList strings;
|
||||
DerivedTypes types;
|
||||
};
|
||||
typedef map<Serialization::TypeID, BaseClass> DefaultTypesPoly;
|
||||
DefaultTypesPoly defaultTypesPoly_;
|
||||
|
||||
int expandLevels_;
|
||||
bool undoEnabled_;
|
||||
bool fullUndo_;
|
||||
|
||||
std::vector<PropertyTreeOperator> undoOperators_;
|
||||
std::vector<PropertyTreeOperator> redoOperators_;
|
||||
|
||||
ConstStringList constStrings_;
|
||||
|
||||
friend class TreeImpl;
|
||||
};
|
||||
|
||||
bool Serialize(Serialization::IArchive& ar, TreeSelection &selection, const char* name, const char* label);
|
||||
// vim:ts=4 sw=4:
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEMODEL_H
|
||||
@@ -1,53 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "PropertyTreeOperator.h"
|
||||
#include "PropertyRow.h"
|
||||
#include "Serialization/Enum.h"
|
||||
#include "Serialization/STL.h"
|
||||
#include "Serialization/Pointers.h"
|
||||
#include "Serialization/IArchive.h"
|
||||
#include "Serialization/STLImpl.h"
|
||||
#include "Serialization/PointersImpl.h"
|
||||
|
||||
SERIALIZATION_ENUM_BEGIN_NESTED(PropertyTreeOperator, Type, "PropertyTreeOp")
|
||||
SERIALIZATION_ENUM_VALUE_NESTED(PropertyTreeOperator, REPLACE, "Replace")
|
||||
SERIALIZATION_ENUM_VALUE_NESTED(PropertyTreeOperator, ADD, "Add")
|
||||
SERIALIZATION_ENUM_VALUE_NESTED(PropertyTreeOperator, REMOVE, "Remove")
|
||||
SERIALIZATION_ENUM_END()
|
||||
|
||||
PropertyTreeOperator::PropertyTreeOperator(const TreePath& path, PropertyRow* row)
|
||||
: type_(REPLACE)
|
||||
, path_(path)
|
||||
, index_(-1)
|
||||
, row_(row)
|
||||
{
|
||||
}
|
||||
|
||||
PropertyTreeOperator::PropertyTreeOperator()
|
||||
: type_(NONE)
|
||||
, index_(-1)
|
||||
{
|
||||
}
|
||||
|
||||
PropertyTreeOperator::~PropertyTreeOperator()
|
||||
{
|
||||
}
|
||||
|
||||
void PropertyTreeOperator::Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(type_, "type", "Type");
|
||||
ar(path_, "path", "Path");
|
||||
ar(row_, "row", "Row");
|
||||
ar(index_, "index", "Index");
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEOPERATOR_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEOPERATOR_H
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "Serialization/Pointers.h"
|
||||
|
||||
namespace Serialization{ class IArchive; }
|
||||
|
||||
class PropertyRow;
|
||||
|
||||
struct TreePathLeaf
|
||||
{
|
||||
int index;
|
||||
|
||||
TreePathLeaf(int _index = -1)
|
||||
: index(_index)
|
||||
{
|
||||
}
|
||||
bool operator==(const TreePathLeaf& rhs) const{
|
||||
return index == rhs.index;
|
||||
}
|
||||
bool operator!=(const TreePathLeaf& rhs) const{
|
||||
return index != rhs.index;
|
||||
}
|
||||
};
|
||||
bool Serialize(Serialization::IArchive& ar, TreePathLeaf& value, const char* name, const char* label);
|
||||
|
||||
typedef std::vector<TreePathLeaf> TreePath;
|
||||
typedef std::vector<TreePath> TreePathes;
|
||||
|
||||
class PropertyTreeOperator
|
||||
{
|
||||
public:
|
||||
enum Type{
|
||||
NONE,
|
||||
REPLACE,
|
||||
ADD,
|
||||
REMOVE
|
||||
};
|
||||
|
||||
PropertyTreeOperator();
|
||||
~PropertyTreeOperator();
|
||||
PropertyTreeOperator(const TreePath& path, PropertyRow* row);
|
||||
void Serialize(Serialization::IArchive& ar);
|
||||
private:
|
||||
Type type_;
|
||||
TreePath path_;
|
||||
Serialization::SharedPtr<PropertyRow> row_;
|
||||
int index_;
|
||||
friend class PropertyTreeModel;
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_PROPERTYTREEOPERATOR_H
|
||||
@@ -1,227 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "QPropertyDialog.h"
|
||||
#include "QPropertyTree.h"
|
||||
#include "Serialization/IArchive.h"
|
||||
#include "Serialization/BinArchive.h"
|
||||
#include "Serialization/JSONIArchive.h"
|
||||
#include "Serialization/JSONOArchive.h"
|
||||
#include <QBoxLayout>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDir>
|
||||
|
||||
#include <CryPath.h>
|
||||
|
||||
#ifndef SERIALIZATION_STANDALONE
|
||||
#include <CryFile.h>
|
||||
#include <Include/EditorCoreAPI.h>
|
||||
#else
|
||||
namespace PathUtil
|
||||
{
|
||||
string GetParentDirectory(const char* path)
|
||||
{
|
||||
const char* end = strrchr(path, '/');
|
||||
if (!end)
|
||||
{
|
||||
end = strrchr(path, '\\');
|
||||
}
|
||||
if (end)
|
||||
{
|
||||
return string(path, end);
|
||||
}
|
||||
else
|
||||
{
|
||||
return string();
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef SERIALIZATION_STANDALONE
|
||||
#include <IEditor.h>
|
||||
#endif
|
||||
|
||||
static string getFullStateFilename(const char* filename)
|
||||
{
|
||||
#ifdef SERIALIZATION_STANDALONE
|
||||
// use current folder
|
||||
return filename;
|
||||
#else
|
||||
string path = GetIEditor()->GetResolvedUserFolder().toUtf8().data();
|
||||
if (!path.empty() && path[path.size() - 1] != '\\' && path[path.size() - 1] != '/')
|
||||
{
|
||||
path.push_back('\\');
|
||||
}
|
||||
path += filename;
|
||||
return path;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool QPropertyDialog::edit(Serialization::SStruct& ser, const char* title, const char* windowStateFilename, QWidget* parent)
|
||||
{
|
||||
QPropertyDialog dialog(parent);
|
||||
dialog.setSerializer(ser);
|
||||
dialog.setWindowTitle(QString::fromLocal8Bit(title));
|
||||
dialog.setWindowStateFilename(windowStateFilename);
|
||||
|
||||
return dialog.exec() == QDialog::Accepted;
|
||||
}
|
||||
|
||||
QPropertyDialog::QPropertyDialog(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, m_sizeHint(440, 500)
|
||||
, m_layout(0)
|
||||
, m_storeContent(false)
|
||||
{
|
||||
connect(this, SIGNAL(accepted()), this, SLOT(onAccepted()));
|
||||
connect(this, SIGNAL(rejected()), this, SLOT(onRejected()));
|
||||
setModal(true);
|
||||
setWindowModality(Qt::ApplicationModal);
|
||||
|
||||
m_propertyTree = new QPropertyTree(this);
|
||||
m_propertyTree->setExpandLevels(1);
|
||||
|
||||
m_layout = new QBoxLayout(QBoxLayout::TopToBottom, this);
|
||||
|
||||
m_layout->addWidget(m_propertyTree, 1);
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(this);
|
||||
buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
m_layout->addWidget(buttons, 0);
|
||||
}
|
||||
|
||||
QPropertyDialog::~QPropertyDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void QPropertyDialog::revert()
|
||||
{
|
||||
if (m_propertyTree)
|
||||
{
|
||||
m_propertyTree->revert();
|
||||
}
|
||||
}
|
||||
|
||||
void QPropertyDialog::setSerializer(const Serialization::SStruct& ser)
|
||||
{
|
||||
if (!m_serializer)
|
||||
{
|
||||
m_serializer.reset(new Serialization::SStruct());
|
||||
}
|
||||
*m_serializer = ser;
|
||||
}
|
||||
|
||||
void QPropertyDialog::setWindowStateFilename(const char* windowStateFilename)
|
||||
{
|
||||
m_windowStateFilename = windowStateFilename;
|
||||
}
|
||||
|
||||
void QPropertyDialog::setSizeHint(const QSize& size)
|
||||
{
|
||||
m_sizeHint = size;
|
||||
}
|
||||
|
||||
void QPropertyDialog::setStoreContent(bool storeContent)
|
||||
{
|
||||
m_storeContent = storeContent;
|
||||
}
|
||||
|
||||
QSize QPropertyDialog::sizeHint() const
|
||||
{
|
||||
return m_sizeHint;
|
||||
}
|
||||
|
||||
void QPropertyDialog::setVisible(bool visible)
|
||||
{
|
||||
QDialog::setVisible(visible);
|
||||
|
||||
if (visible)
|
||||
{
|
||||
string fullStateFilename = getFullStateFilename(m_windowStateFilename.c_str());
|
||||
if (!fullStateFilename.empty())
|
||||
{
|
||||
Serialization::JSONIArchive ia;
|
||||
if (ia.load(fullStateFilename.c_str()))
|
||||
{
|
||||
ia(*this);
|
||||
}
|
||||
}
|
||||
|
||||
m_backup.reset(new Serialization::BinOArchive());
|
||||
if (m_serializer && *m_serializer)
|
||||
{
|
||||
const Serialization::SStruct& ser = *m_serializer;
|
||||
(*m_backup)(ser, "backup");
|
||||
m_propertyTree->attach(*m_serializer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QPropertyDialog::onAccepted()
|
||||
{
|
||||
string fullStateFilename = getFullStateFilename(m_windowStateFilename.c_str());
|
||||
if (!fullStateFilename.empty())
|
||||
{
|
||||
Serialization::JSONOArchive oa;
|
||||
oa(*this);
|
||||
|
||||
QDir().mkdir(QString::fromLocal8Bit(PathUtil::GetParentDirectory(fullStateFilename.c_str()).c_str()));
|
||||
oa.save(fullStateFilename.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void QPropertyDialog::onRejected()
|
||||
{
|
||||
if (m_backup.get() && m_serializer.get() && *m_serializer)
|
||||
{
|
||||
// restore previous object state
|
||||
Serialization::BinIArchive ia;
|
||||
if (ia.open(m_backup->buffer(), m_backup->length()))
|
||||
{
|
||||
const Serialization::SStruct& ser = *m_serializer;
|
||||
ia(ser, "backup");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QPropertyDialog::setArchiveContext(Serialization::SContextLink* context)
|
||||
{
|
||||
m_propertyTree->setArchiveContext(context);
|
||||
}
|
||||
|
||||
void QPropertyDialog::Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
if (m_storeContent && m_serializer.get())
|
||||
{
|
||||
ar(*m_serializer, "content");
|
||||
}
|
||||
|
||||
QByteArray geometry;
|
||||
if (ar.IsOutput())
|
||||
{
|
||||
geometry = saveGeometry();
|
||||
}
|
||||
std::vector<char> geometryVec(geometry.begin(), geometry.end());
|
||||
ar(geometryVec, "geometry");
|
||||
if (ar.IsInput() && !geometryVec.empty())
|
||||
{
|
||||
restoreGeometry(QByteArray(geometryVec.data(), (int)geometryVec.size()));
|
||||
}
|
||||
|
||||
ar(*m_propertyTree, "propertyTree");
|
||||
}
|
||||
|
||||
#include <QPropertyTree/moc_QPropertyDialog.cpp>
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_QPROPERTYDIALOG_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_QPROPERTYDIALOG_H
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "../EditorCommonAPI.h"
|
||||
#include "Strings.h"
|
||||
#include <memory>
|
||||
|
||||
#include <QDialog>
|
||||
#endif
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
struct SStruct;
|
||||
struct SContextLink;
|
||||
class BinOArchive;
|
||||
class IArchive;
|
||||
}
|
||||
|
||||
class QPropertyTree;
|
||||
class QBoxLayout;
|
||||
|
||||
class EDITOR_COMMON_API QPropertyDialog
|
||||
: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static bool edit(Serialization::SStruct& ser, const char* title, const char* windowStateFilename, QWidget* parent);
|
||||
|
||||
QPropertyDialog(QWidget* parent);
|
||||
~QPropertyDialog();
|
||||
|
||||
void setSerializer(const Serialization::SStruct& ser);
|
||||
void setArchiveContext(Serialization::SContextLink* context);
|
||||
void setWindowStateFilename(const char* windowStateFilename);
|
||||
void setSizeHint(const QSize& sizeHint);
|
||||
void setStoreContent(bool storeContent);
|
||||
|
||||
void revert();
|
||||
QBoxLayout* layout() { return m_layout; }
|
||||
|
||||
void Serialize(Serialization::IArchive& ar);
|
||||
protected slots:
|
||||
void onAccepted();
|
||||
void onRejected();
|
||||
|
||||
protected:
|
||||
QSize sizeHint() const override;
|
||||
void setVisible(bool visible) override;
|
||||
private:
|
||||
QPropertyTree* m_propertyTree;
|
||||
QBoxLayout* m_layout;
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
std::unique_ptr<Serialization::SStruct> m_serializer;
|
||||
std::unique_ptr<Serialization::BinOArchive> m_backup;
|
||||
string m_windowStateFilename;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
QSize m_sizeHint;
|
||||
bool m_storeContent;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_QPROPERTYDIALOG_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,528 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_QPROPERTYTREE_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_QPROPERTYTREE_H
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include "../EditorCommonAPI.h"
|
||||
#include "ConstStringList.h"
|
||||
#include "ValidatorBlock.h"
|
||||
#include <string>
|
||||
#include "Serialization/Serializer.h"
|
||||
#include "Serialization/IArchive.h"
|
||||
#include "Serialization/Pointers.h"
|
||||
#include "Serialization/Object.h"
|
||||
#include "PropertyRow.h"
|
||||
#include <QWidget>
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
struct SContextLink;
|
||||
class IClassFactory;
|
||||
}
|
||||
|
||||
class QMenu;
|
||||
class QLineEdit;
|
||||
class QScrollBar;
|
||||
|
||||
struct Color;
|
||||
class TreeImpl;
|
||||
class PropertyTreeModel;
|
||||
class PopupMenuItem;
|
||||
class PropertyTreeModel;
|
||||
class PropertyRow;
|
||||
class PropertyRowWidget;
|
||||
class PropertyTreeOperator;
|
||||
class Entry;
|
||||
struct IconXPMCache;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
struct QPropertyTreeStyle;
|
||||
struct PropertyTreeConfig
|
||||
{
|
||||
bool immediateUpdate;
|
||||
bool hideUntranslated;
|
||||
bool showContainerIndices;
|
||||
bool showContainerIndexLabels;
|
||||
bool containerIndicesZeroBased;
|
||||
bool filterWhenType;
|
||||
int filter;
|
||||
int sliderUpdateDelay;
|
||||
int expandLevels;
|
||||
bool undoEnabled;
|
||||
bool fullUndo;
|
||||
bool multiSelection;
|
||||
bool copyPasteEnabled;
|
||||
|
||||
PropertyTreeConfig()
|
||||
: immediateUpdate(true)
|
||||
, hideUntranslated(true)
|
||||
, showContainerIndices(true)
|
||||
, showContainerIndexLabels(false)
|
||||
, containerIndicesZeroBased(true)
|
||||
, filterWhenType(true)
|
||||
, filter(0)
|
||||
, sliderUpdateDelay(25)
|
||||
, undoEnabled(true)
|
||||
, fullUndo(true)
|
||||
, multiSelection(true)
|
||||
, copyPasteEnabled(true)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
struct PropertyRowMenuHandler;
|
||||
|
||||
class DragWindow : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DragWindow(QPropertyTree* tree);
|
||||
|
||||
void set(QPropertyTree* tree, PropertyRow* row, const QRect& rowRect);
|
||||
void setWindowPos(bool visible);
|
||||
void show();
|
||||
void move(int deltaX, int deltaY);
|
||||
void hide();
|
||||
|
||||
void drawRow(QPainter& p);
|
||||
void paintEvent(QPaintEvent* ev);
|
||||
|
||||
protected:
|
||||
bool useLayeredWindows_;
|
||||
PropertyRow* row_;
|
||||
QRect rect_;
|
||||
QPropertyTree* tree_;
|
||||
QPoint offset_;
|
||||
};
|
||||
|
||||
class EDITOR_COMMON_API QPropertyTree : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QPropertyTree(QWidget* parent = nullptr);
|
||||
~QPropertyTree();
|
||||
|
||||
// Used to attach an object to a PropertyTree widget. Attached object should implement
|
||||
// Serialize method. Example of usage:
|
||||
//
|
||||
// struct MyType
|
||||
// {
|
||||
// void Serialize(Serialization::IArchive& ar);
|
||||
// };
|
||||
// MyType object;
|
||||
//
|
||||
// propertyTree->attach(Serialization::SStruct(object));
|
||||
//
|
||||
// Attached object will be serialized through PropertyOArchive to populate the tree. On
|
||||
// every input made to the tree attached object will be deserialized through
|
||||
// PropertyIArchive and serialized back again through PropertyOArchive to make sure that
|
||||
// tree content is up-to-date.
|
||||
// Property archives can be identified by calling ar.IsEdit().
|
||||
// SStruct stores a pointer to an actual object that should either outlive property tree
|
||||
// or be detached on destruction.
|
||||
void attach(const Serialization::SStruct& serializer);
|
||||
// This form attaches an array of SStruct-s. This is used to edit multiple objects
|
||||
// simultaneously. Only shared properties will be shown (i.e. intersection of all
|
||||
// properties). Properties with different values will be shown as "..." or a gray
|
||||
// checkbox.
|
||||
bool attach(const Serialization::SStructs& serializers);
|
||||
// Used for two-trees setup. In this case leader tree acts as an outliner, that shows
|
||||
// top level of the data (either by using setOutlineMode or setting different filter).
|
||||
// Attached, follower tree then shows properties ot the item selected in the main tree.
|
||||
// Temporary structures (e.g. created on the stack) should not be used in this mode
|
||||
// (except for decorators), as this may cause access to deallocated object when
|
||||
// selecting it in the tree.
|
||||
void attachPropertyTree(QPropertyTree* propertyTree);
|
||||
void detachPropertyTree();
|
||||
void setAutoHideAttachedPropertyTree(bool autoHide);
|
||||
// Effectively clears the tree.
|
||||
void detach();
|
||||
bool attached() const { return !attached_.empty(); }
|
||||
|
||||
// Forces serialization of attached object to update properties. Can be used to update
|
||||
// property tree when attached object was changed for some reason.
|
||||
void revert();
|
||||
// Same as revert(), except that it will but interrupt editing or mouse action in
|
||||
// progress.
|
||||
void revertNoninterrupting();
|
||||
// Forces deserialization of attached objects from property items.
|
||||
void apply(bool continuousUpdate);
|
||||
// Useful to apply edit boxes that are being edited at the moment.
|
||||
// May be needed when click on toolbar button doesn't steal the focus, leaving input
|
||||
// data effectively not saved.
|
||||
void applyInplaceEditor();
|
||||
|
||||
// Reduces width of the tree by removing expansion arrow/plus on the first level of the
|
||||
// tree (first level is always expanded).
|
||||
void setCompact(bool compact);
|
||||
bool compact() const;
|
||||
// Puts checkboxes into two columns when possible.
|
||||
void setPackCheckboxes(bool pack);
|
||||
bool packCheckboxes() const;
|
||||
// Changes distance between rows, multiplier of row height.
|
||||
void setRowSpacing(float rowSpacing);
|
||||
float rowSpacing() const;
|
||||
// Sets default width of the value column, 0..1 (relative to widget width)
|
||||
void setValueColumnWidth(float valueColumnWidth);
|
||||
float valueColumnWidth() const;
|
||||
// Allows to override background color, useful when placing on tabs or panels that have
|
||||
// have different background.
|
||||
void setBackgroundColor(const QColor& color);
|
||||
const QColor& backgroundColor() const { return backgroundColor_; }
|
||||
// Set number of levels to be expanded by default. Note that this function should be
|
||||
// invoked before first call to attach attach() to have an effect.
|
||||
void setExpandLevels(int levels);
|
||||
// Can be used to control if container(array) elements have numbered labels.
|
||||
void setShowContainerIndices(bool showContainerIndices) { config_.showContainerIndices = showContainerIndices; }
|
||||
bool showContainerIndices() const{ return config_.showContainerIndices; }
|
||||
// Can be used to control if container(array) elements should prepend the number to the existing label
|
||||
void setShowContainerIndexLabels(bool showContainerIndexLabels) { config_.showContainerIndexLabels = showContainerIndexLabels; }
|
||||
bool showContainerIndexLabels() const{ return config_.showContainerIndexLabels; }
|
||||
// Can be used to control if container(array) elements should be zero- (default) or one-based
|
||||
void setContainerIndicesZeroBased(bool containerIndicesZeroBased) { config_.containerIndicesZeroBased = containerIndicesZeroBased; }
|
||||
bool containerIndicesZeroBased() const{ return config_.containerIndicesZeroBased; }
|
||||
// Allows control of copy/paste functionality
|
||||
void setCopyPasteEnabled(bool copyPasteEnabled) { config_.copyPasteEnabled = copyPasteEnabled; }
|
||||
bool copyPasteEnabled() const{ return config_.copyPasteEnabled; }
|
||||
|
||||
// Limits the rate at which sliders emit change signal.
|
||||
void setSliderUpdateDelay(int delayMS) { config_.sliderUpdateDelay = delayMS; }
|
||||
|
||||
// Limit number of mouse-movement updates per-frame. Used to prevent large tree updates
|
||||
// from draining all the idle time.
|
||||
void setAggregateMouseEvents(bool aggregate) { aggregateMouseEvents_ = aggregate; }
|
||||
void flushAggregatedMouseEvents();
|
||||
|
||||
// Can be used to disable internal undo.
|
||||
void setUndoEnabled(bool enabled, bool full = false);
|
||||
// This can be used to disable automatic serialization after each deserialization call.
|
||||
// May be useful to prevent double-revert when signalChange is connected to some
|
||||
// external data model, which fires an event that reverts tree automatically.
|
||||
void setAutoRevert(bool autoRevert) { autoRevert_ = autoRevert; }
|
||||
// Default size.
|
||||
void setSizeHint(const QSize& size) { sizeHint_ = size; }
|
||||
// Sets minimal size of the widget to the size of the visible content of the tree.
|
||||
void setSizeToContent(bool sizeToContent);
|
||||
bool sizeToContent() const{ return sizeToContent_; }
|
||||
// Retrieves size of the content, doesn't require sizeToContent to be set.
|
||||
QSize contentSize() const{ return contentSize_; }
|
||||
// When set filtering is started just by typing in the property tree
|
||||
void setFilterWhenType(bool filterWhenType) { config_.filterWhenType = filterWhenType; }
|
||||
|
||||
// Outline mode hides content of the elements of the container (excepted for
|
||||
// inlined/pulled-up properties). Can be used together with second property
|
||||
// tree through attachPropertyTree.
|
||||
void setOutlineMode(bool outlineMode) { outlineMode_ = outlineMode; }
|
||||
bool outlineMode() const{ return outlineMode_; }
|
||||
// Hide selection when widget is out of focus. Disables selection for parent of inline items.
|
||||
void setHideSelection(bool hideSelection) { hideSelection_ = hideSelection; }
|
||||
bool hideSelection() const{ return hideSelection_; }
|
||||
// Can be used to disable selection of multiple properties at the same time.
|
||||
void setMultiSelection(bool multiSelection) { config_.multiSelection = multiSelection; }
|
||||
bool multiSelection() const{ return config_.multiSelection; }
|
||||
|
||||
// Sets head of the context-list. Can be used to pass additional data to nested decorators.
|
||||
void setArchiveContext(Serialization::SContextLink* context) { archiveContext_ = context; }
|
||||
// Sets archive filter. Filter is a bit mask stored within archive that can be used to
|
||||
// affect behavior of serialization. For example one can have two trees that shows
|
||||
// different portions of the same object.
|
||||
void setFilter(int filter) { config_.filter = filter; }
|
||||
|
||||
// This methods returns array of SStruct-s for all selected properties.
|
||||
// This is useful for manual implementation of attachPropertyTree behavior
|
||||
// with type filtering or special logic.
|
||||
void getSelectionSerializers(Serialization::SStructs* serializers);
|
||||
// Can be used to select once serialized object(s) in the tree.
|
||||
bool selectByAddress(const void*, bool keepSelectionIfChildSelected = false);
|
||||
bool selectByAddresses(const void* const* addresses, size_t addressCount, bool keepSelectionIfChildSelected);
|
||||
// Can be used to query information about selection in the tree.
|
||||
bool setSelectedRow(PropertyRow* row);
|
||||
PropertyRow* selectedRow();
|
||||
int selectedRowCount() const;
|
||||
PropertyRow* selectedRowByIndex(int index);
|
||||
|
||||
// Reports if serialized data contains errors. Errors are reported
|
||||
// through IArchive::Error() method.
|
||||
bool containsErrors() const;
|
||||
void focusFirstError();
|
||||
|
||||
void ensureVisible(PropertyRow* row, bool update = true, bool considerChildren = true);
|
||||
void expandRow(PropertyRow* row, bool expanded = true, bool updateHeights = true);
|
||||
|
||||
// PropertyTreeStyle used to customize visual appearance of the property tree
|
||||
const QPropertyTreeStyle& treeStyle() const{ return *style_; }
|
||||
void setTreeStyle(const QPropertyTreeStyle& style);
|
||||
|
||||
// Config used to store behavioral settings
|
||||
const PropertyTreeConfig& config() const{ return config_; }
|
||||
|
||||
// Instance of PropertyTree can be serialized. In this case the expansion state
|
||||
// of the rows and list of selected rows will be saved (not the property values).
|
||||
void Serialize(Serialization::IArchive& ar);
|
||||
|
||||
// OBSOLETE: Serialization::Object will be gone
|
||||
void attach(const Serialization::Object& object);
|
||||
int revertObjects(vector<void*> objectAddresses);
|
||||
bool revertObject(void* objectAddress);
|
||||
signals:
|
||||
// Emited for every finished changed of the value. E.g. when you drag a slider,
|
||||
// signalChanged will be invoked when you release a mouse button.
|
||||
void signalChanged();
|
||||
// Used fast-pace changes, like movement of the slider before mouse gets released.
|
||||
void signalContinuousChange();
|
||||
// Invoked whenever selection changed.
|
||||
void signalSelected();
|
||||
// Invoked after each revert() call (can be caused by user intput).
|
||||
void signalReverted();
|
||||
// Invoked before any change is going to occur and can be used to store current version
|
||||
// of data for own undo stack.
|
||||
void signalPushUndo();
|
||||
void signalPushRedo();
|
||||
|
||||
// Called before and after serialization is invoked. Can be used to update context list
|
||||
// in archive.
|
||||
void signalAboutToSerialize(Serialization::IArchive& ar);
|
||||
void signalSerialized(Serialization::IArchive& ar);
|
||||
|
||||
// OBSOLETE: do not use
|
||||
void signalObjectChanged(const Serialization::Object& obj);
|
||||
|
||||
// Called when visual size of the tree changes, i.e. when things are deserialized and
|
||||
// and when rows are expanded/collapsed.
|
||||
void signalSizeChanged();
|
||||
|
||||
// Called when undo/redo are triggered via keyboard shortcut
|
||||
void signalUndo();
|
||||
void signalRedo();
|
||||
public slots:
|
||||
void expandAll(PropertyRow* root = 0);
|
||||
void collapseAll(PropertyRow* root = 0);
|
||||
void onAttachedTreeChanged();
|
||||
public:
|
||||
// internal methods:
|
||||
void setFullRowMode(bool fullRowMode);
|
||||
bool fullRowMode() const;
|
||||
void setHideUntranslated(bool hideUntranslated) { config_.hideUntranslated = hideUntranslated; }
|
||||
bool hideUntranslated() const{ return config_.hideUntranslated; }
|
||||
void setImmediateUpdate(bool immediateUpdate) { config_.immediateUpdate = immediateUpdate; }
|
||||
bool immediateUpdate() const{ return config_.immediateUpdate; }
|
||||
int _defaultRowHeight() const { return defaultRowHeight_; }
|
||||
PropertyTreeModel* model() { return model_.data(); }
|
||||
const PropertyTreeModel* model() const { return model_.data(); }
|
||||
|
||||
QPoint treeSize() const;
|
||||
int leftBorder() const { return leftBorder_; }
|
||||
int rightBorder() const { return rightBorder_; }
|
||||
bool multiSelectable() const { return attachedPropertyTree_ != 0 || config_.multiSelection; }
|
||||
void expandParents(PropertyRow* row);
|
||||
bool spawnWidget(PropertyRow* row, bool ignoreReadOnly);
|
||||
bool getSelectedObject(Serialization::Object* object);
|
||||
void onSignalChanged() { signalChanged(); }
|
||||
|
||||
void onRowSelected(const std::vector<PropertyRow*>& row, bool addSelection, bool adjustCursorPos);
|
||||
const ValidatorBlock* _validatorBlock() const { return validatorBlock_.data(); }
|
||||
QPoint _toScreen(QPoint point) const;
|
||||
void _cancelWidget(){ widget_.reset(); }
|
||||
void _drawRowLabel(QPainter& p, const wchar_t* text, const QFont* font, const QRect& rect, const QColor& color) const;
|
||||
void _drawRowValue(QPainter& p, const wchar_t* text, const QFont* font, const QRect& rect, const QColor& color, bool pathEllipsis, bool center) const;
|
||||
QRect _visibleRect() const;
|
||||
bool _isDragged(const PropertyRow* row) const;
|
||||
bool _isCapturedRow(const PropertyRow* row) const;
|
||||
PropertyRow* _pressedRow() const { return pressedRow_; }
|
||||
void _setPressedRow(PropertyRow* row) { pressedRow_ = row; }
|
||||
int _applyTime() const{ return applyTime_; }
|
||||
int _revertTime() const{ return revertTime_; }
|
||||
int _updateHeightsTime() const{ return updateHeightsTime_; }
|
||||
int _paintTime() const{ return paintTime_; }
|
||||
const QFont& _boldFont() const{ return boldFont_; }
|
||||
bool hasFocusOrInplaceHasFocus() const;
|
||||
void addMenuHandler(PropertyRowMenuHandler* handler);
|
||||
IconXPMCache* _iconCache() const{ return iconCache_.data(); }
|
||||
public slots:
|
||||
void onFilterChanged(const QString& str);
|
||||
protected slots:
|
||||
void onScroll(int pos);
|
||||
void onModelUpdated(const PropertyRows& rows, bool apply);
|
||||
void onModelPushUndo(PropertyTreeOperator* op, bool* handled);
|
||||
void onModelPushRedo(PropertyTreeOperator* op, bool* handled);
|
||||
void onMouseStillTimeout();
|
||||
|
||||
private:
|
||||
QPropertyTree(const QPropertyTree&);
|
||||
QPropertyTree& operator=(const QPropertyTree&);
|
||||
protected:
|
||||
class DragController;
|
||||
enum HitTest{
|
||||
TREE_HIT_PLUS,
|
||||
TREE_HIT_TEXT,
|
||||
TREE_HIT_ROW,
|
||||
TREE_HIT_NONE
|
||||
};
|
||||
PropertyRow* rowByPoint(const QPoint& point);
|
||||
HitTest hitTest(PropertyRow* row, const QPoint& pointInWindowSpace, const QRect& rowRect);
|
||||
void onRowMenuDecompose(PropertyRow* row);
|
||||
void onMouseStill(QPoint point);
|
||||
|
||||
QSize sizeHint() const override;
|
||||
bool event(QEvent* ev) override;
|
||||
void paintEvent(QPaintEvent* ev) override;
|
||||
void moveEvent(QMoveEvent* ev) override;
|
||||
void resizeEvent(QResizeEvent* ev) override;
|
||||
void mousePressEvent(QMouseEvent* ev) override;
|
||||
void mouseReleaseEvent(QMouseEvent* ev) override;
|
||||
void mouseDoubleClickEvent(QMouseEvent* ev) override;
|
||||
void mouseMoveEvent(QMouseEvent* ev) override;
|
||||
void wheelEvent(QWheelEvent* ev) override;
|
||||
void keyPressEvent(QKeyEvent* ev) override;
|
||||
void focusInEvent(QFocusEvent* ev) override;
|
||||
|
||||
void updateArea();
|
||||
bool toggleRow(PropertyRow* row);
|
||||
|
||||
struct RowFilter {
|
||||
enum Type {
|
||||
NAME_VALUE,
|
||||
NAME,
|
||||
VALUE,
|
||||
TYPE,
|
||||
NUM_TYPES
|
||||
};
|
||||
|
||||
string start[NUM_TYPES];
|
||||
bool tillEnd[NUM_TYPES];
|
||||
std::vector<string> substrings[NUM_TYPES];
|
||||
|
||||
void parse(const char* filter);
|
||||
bool match(const char* text, Type type, size_t* matchStart, size_t* matchEnd) const;
|
||||
bool typeRelevant(Type type) const{
|
||||
return !start[type].empty() || !substrings[type].empty();
|
||||
}
|
||||
|
||||
RowFilter()
|
||||
{
|
||||
for (int i = 0; i < NUM_TYPES; ++i)
|
||||
tillEnd[i] = false;
|
||||
}
|
||||
};
|
||||
|
||||
QPoint pointToRootSpace(const QPoint& pointInWindowSpace) const;
|
||||
QPoint pointFromRootSpace(const QPoint& point) const;
|
||||
|
||||
void interruptDrag();
|
||||
void updateHeights(bool recalculateTextSize=false);
|
||||
void updateValidatorIcons();
|
||||
bool updateScrollBar();
|
||||
void applyValidation();
|
||||
void jumpToNextHiddenValidatorIssue(bool isError, PropertyRow* start);
|
||||
|
||||
bool onContextMenu(PropertyRow* row, QMenu& menu);
|
||||
void clearMenuHandlers();
|
||||
bool onRowKeyDown(PropertyRow* row, const QKeyEvent* ev);
|
||||
bool rowProcessesKey(PropertyRow* row, const QKeyEvent* ev);
|
||||
// points here are specified in root-row space
|
||||
bool onRowLMBDown(PropertyRow* row, const QRect& rowRect, QPoint point, bool controlPressed, bool shiftPressed);
|
||||
void onRowLMBUp(PropertyRow* row, const QRect& rowRect, QPoint point);
|
||||
void onRowRMBDown(PropertyRow* row, const QRect& rowRect, QPoint point);
|
||||
void onRowMouseMove(PropertyRow* row, const QRect& rowRect, QPoint point);
|
||||
|
||||
bool canBePasted(PropertyRow* destination);
|
||||
bool canBePasted(const char* destinationType);
|
||||
|
||||
void setFilterMode(bool inFilterMode);
|
||||
void startFilter(const char* filter);
|
||||
void setWidget(PropertyRowWidget* widget);
|
||||
void _arrangeChildren();
|
||||
|
||||
void updateAttachedPropertyTree(bool revert);
|
||||
void drawFilteredString(QPainter& p, const wchar_t* text, RowFilter::Type type, const QFont* font, const QRect& rect, const QColor& color, bool pathEllipsis, bool center) const;
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
QScopedPointer<PropertyTreeModel> model_;
|
||||
int cursorX_;
|
||||
|
||||
QScopedPointer<PropertyRowWidget> widget_; // in-place widget
|
||||
vector<PropertyRowMenuHandler*> menuHandlers_;
|
||||
|
||||
typedef vector<Serialization::Object> Objects;
|
||||
Objects attached_;
|
||||
QPropertyTree* attachedPropertyTree_;
|
||||
bool autoHideAttachedPropertyTree_;
|
||||
|
||||
bool filterMode_;
|
||||
RowFilter rowFilter_;
|
||||
QScopedPointer<QLineEdit> filterEntry_;
|
||||
QScopedPointer<IconXPMCache> iconCache_;
|
||||
Serialization::SContextLink* archiveContext_;
|
||||
QScopedPointer<ValidatorBlock> validatorBlock_;
|
||||
bool outlineMode_;
|
||||
bool sizeToContent_;
|
||||
bool hideSelection_;
|
||||
|
||||
bool autoRevert_;
|
||||
bool needUpdate_;
|
||||
|
||||
QScrollBar* scrollBar_;
|
||||
QFont boldFont_;
|
||||
QColor backgroundColor_;
|
||||
QRect area_;
|
||||
int leftBorder_;
|
||||
int rightBorder_;
|
||||
QPoint size_;
|
||||
QPoint offset_;
|
||||
QSize sizeHint_;
|
||||
QSize contentSize_;
|
||||
DragController* dragController_;
|
||||
Serialization::SharedPtr<PropertyRow> lastSelectedRow_;
|
||||
QPoint pressPoint_;
|
||||
QPoint pressDelta_;
|
||||
bool pointerMovedSincePress_;
|
||||
QPoint lastStillPosition_;
|
||||
PropertyRow* capturedRow_;
|
||||
PropertyRow* pressedRow_;
|
||||
QTimer* mouseStillTimer_;
|
||||
|
||||
bool aggregateMouseEvents_;
|
||||
int aggregatedMouseEventCount_;
|
||||
QScopedPointer<QMouseEvent> lastMouseMoveEvent_;
|
||||
|
||||
PropertyTreeConfig config_;
|
||||
QScopedPointer<QPropertyTreeStyle> style_;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
int defaultRowHeight_;
|
||||
|
||||
int applyTime_;
|
||||
int revertTime_;
|
||||
int updateHeightsTime_;
|
||||
int paintTime_;
|
||||
int zoomLevel_;
|
||||
bool dragCheckMode_;
|
||||
bool dragCheckValue_;
|
||||
|
||||
friend class TreeImpl;
|
||||
friend class FilterEntry;
|
||||
friend class DragWindow;
|
||||
friend struct FilterVisitor;
|
||||
friend struct PropertyTreeMenuHandler;
|
||||
};
|
||||
|
||||
wstring generateDigest(Serialization::SStruct& ser);
|
||||
// vim: tw=90:
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_QPROPERTYTREE_H
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Serialization.h"
|
||||
#include "Serialization/Decorators/Range.h"
|
||||
|
||||
struct QPropertyTreeStyle
|
||||
{
|
||||
bool compact;
|
||||
bool packCheckboxes;
|
||||
bool fullRowMode;
|
||||
bool showHorizontalLines;
|
||||
bool doNotIndentSecondLevel;
|
||||
bool groupShadows;
|
||||
bool groupRectangle;
|
||||
bool alignLabelsToRight;
|
||||
float valueColumnWidth;
|
||||
float rowSpacing;
|
||||
unsigned char levelShadowOpacity;
|
||||
float levelIndent;
|
||||
float firstLevelIndent;
|
||||
float groupShade;
|
||||
float sliderSaturation;
|
||||
|
||||
QPropertyTreeStyle()
|
||||
: compact(false)
|
||||
, packCheckboxes(true)
|
||||
, fullRowMode(false)
|
||||
, valueColumnWidth(.59f)
|
||||
, rowSpacing(1.1f)
|
||||
, showHorizontalLines(false)
|
||||
, firstLevelIndent(0.75f)
|
||||
, levelIndent(0.75f)
|
||||
, levelShadowOpacity(36)
|
||||
, doNotIndentSecondLevel(false)
|
||||
, groupShadows(false)
|
||||
, sliderSaturation(0.0f)
|
||||
, groupShade(0.15f)
|
||||
, groupRectangle(false)
|
||||
, alignLabelsToRight(false)
|
||||
{
|
||||
}
|
||||
|
||||
void Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
ar.Doc("Here you can define appearance of QPropertyTree control.");
|
||||
|
||||
ar(valueColumnWidth, "valueColumnWidth", "Value Column Width");
|
||||
ar.Doc("Defines a ratio of the value / name columns. Normalized.");
|
||||
ar(Serialization::Range(rowSpacing, 0.5f, 3.0f), "rowSpacing", "Row Spacing");
|
||||
ar.Doc("Height of one row (line) in text-height units.");
|
||||
ar(alignLabelsToRight, "alignLabelsToRight", "Right Alignment");
|
||||
ar(Serialization::Range(levelIndent, 0.0f, 3.0f), "levelIndent", "Level Indent");
|
||||
ar.Doc("Indentation of a every next level in text-height units.");
|
||||
|
||||
ar(Serialization::Range(firstLevelIndent, 0.0f, 3.0f), "firstLevelIndent", "First Level Indent");
|
||||
ar.Doc("Indentation of a very first level in text-height units.");
|
||||
ar(Serialization::Range(sliderSaturation, 0.0f, 1.0f), "sliderSaturation", "Slider Saturation");
|
||||
ar(levelShadowOpacity, "levelShadowOpacity", "Level Shadow Opacity");
|
||||
ar.Doc("Amount of background darkening that gets added to each next nested level.");
|
||||
|
||||
ar(compact, "compact", "Compact");
|
||||
ar.Doc("Compact mode removes expansion pluses from the level and reduces inner padding. Useful for narrowing the widget.");
|
||||
ar(packCheckboxes, "packCheckboxes", "Pack Checkboxes");
|
||||
ar.Doc("Arranges checkboxes in two columns, when possible.");
|
||||
|
||||
ar(showHorizontalLines, "showHorizontalLines", "Horizontal Lines");
|
||||
ar.Doc("Show thin line that connects row name with its value.");
|
||||
|
||||
ar(doNotIndentSecondLevel, "doNotIndentSecondLevel", "Do not indent second level");
|
||||
ar(groupShadows, "groupShadows", "Group Shadows");
|
||||
ar(groupRectangle, "groupRectangle", "Group Rectangle");
|
||||
|
||||
ar(Serialization::Range(groupShade, -1.0f, 1.0f), "groupShade", "Group Shade");
|
||||
ar.Doc("Shade of the group.");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/**
|
||||
* wWidgets - Lightweight UI Toolkit.
|
||||
* Copyright (C) 2009-2011 Evgeny Andreeshchev <eugene.andreeshchev@gmail.com>
|
||||
* Alexander Kotliar <alexander.kotliar@gmail.com>
|
||||
*
|
||||
* This code is distributed under the MIT License:
|
||||
* http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates
|
||||
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_SERIALIZATION_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_SERIALIZATION_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "Serialization/STL.h"
|
||||
#include "Serialization/Pointers.h"
|
||||
#include "Serialization/ClassFactory.h"
|
||||
#include "Serialization/StringList.h"
|
||||
|
||||
#include "Serialization/IArchive.h"
|
||||
#include "Serialization/BinArchive.h"
|
||||
|
||||
using Serialization::IArchive;
|
||||
using Serialization::SStruct;
|
||||
using Serialization::TypeID;
|
||||
using Serialization::SharedPtr;
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_QPROPERTYTREE_SERIALIZATION_H
|
||||
@@ -1,56 +0,0 @@
|
||||
//-------------------------------------------------------------------------------
|
||||
// Copyright (C) Amazon.com, Inc. or its affiliates.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Licensed under the terms set out in the LICENSE.HTML file included at the
|
||||
// root of the distribution; you may not use this file except in compliance
|
||||
// with the License.
|
||||
//
|
||||
// Do not remove or modify this notice or the LICENSE.HTML file. This file
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language
|
||||
// governing permissions and limitations under the License.
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "EditorCommon_precompiled.h"
|
||||
#include "SpriteBorderEditorCommon.h"
|
||||
|
||||
SlicerEdit::SlicerEdit( SpriteBorder border,
|
||||
QSize& unscaledPixmapSize,
|
||||
ISprite* sprite )
|
||||
: QLineEdit()
|
||||
, m_manipulator( nullptr )
|
||||
{
|
||||
bool isVertical = IsBorderVertical( border );
|
||||
|
||||
float totalUnscaledSizeInPixels = aznumeric_cast<float>( isVertical ? unscaledPixmapSize.width() : unscaledPixmapSize.height() );
|
||||
|
||||
setPixelPosition( GetBorderValueInPixels( sprite, border, totalUnscaledSizeInPixels ) );
|
||||
|
||||
setValidator( new QDoubleValidator( 0.0f, totalUnscaledSizeInPixels, 1 ) );
|
||||
|
||||
QObject::connect( this,
|
||||
&SlicerEdit::editingFinished, this,
|
||||
[ this, border, sprite, totalUnscaledSizeInPixels ]()
|
||||
{
|
||||
float p = text().toFloat();
|
||||
|
||||
m_manipulator->setPixelPosition( p );
|
||||
|
||||
SetBorderValue( sprite, border, p, totalUnscaledSizeInPixels );
|
||||
} );
|
||||
}
|
||||
|
||||
void SlicerEdit::SetManipulator(SlicerManipulator* manipulator)
|
||||
{
|
||||
m_manipulator = manipulator;
|
||||
}
|
||||
|
||||
void SlicerEdit::setPixelPosition(float p)
|
||||
{
|
||||
setText( QString::number( p ) );
|
||||
}
|
||||
|
||||
#include <QPropertyTree/moc_SlicerEdit.cpp>
|
||||
@@ -1,46 +0,0 @@
|
||||
//-------------------------------------------------------------------------------
|
||||
// Copyright (C) Amazon.com, Inc. or its affiliates.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Licensed under the terms set out in the LICENSE.HTML file included at the
|
||||
// root of the distribution; you may not use this file except in compliance
|
||||
// with the License.
|
||||
//
|
||||
// Do not remove or modify this notice or the LICENSE.HTML file. This file
|
||||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language
|
||||
// governing permissions and limitations under the License.
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
#pragma once
|
||||
#ifndef CRYINCLUDE_EDITORCOMMON_SLICEREDIT_H
|
||||
#define CRYINCLUDE_EDITORCOMMON_SLICEREDIT_H
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QLineEdit>
|
||||
|
||||
#include "SpriteBorderEditorCommon.h"
|
||||
#endif
|
||||
|
||||
class SlicerEdit
|
||||
: public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
SlicerEdit( SpriteBorder border,
|
||||
QSize& unscaledPixmapSize,
|
||||
ISprite* sprite );
|
||||
|
||||
void SetManipulator(SlicerManipulator* manipulator);
|
||||
|
||||
void setPixelPosition(float p);
|
||||
|
||||
private:
|
||||
|
||||
SlicerManipulator* m_manipulator;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITORCOMMON_SLICEREDIT_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user