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:
bosnichd
2021-05-11 09:31:02 -06:00
committed by GitHub
parent a009e38064
commit 3defbce31b
338 changed files with 16 additions and 63358 deletions
@@ -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
@@ -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