Merge branch 'main' into ly-as-sdk/LYN-2948

This commit is contained in:
phistere
2021-05-13 11:25:03 -05:00
1224 changed files with 18773 additions and 126359 deletions
-5
View File
@@ -1,5 +0,0 @@
#Ignore these directories
SDKs
#ignore these files
*.user
@@ -1,629 +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 "EditorDefs.h"
#include "BackgroundScheduleManager.h"
namespace BackgroundScheduleManager
{
//-----------------------------------------------------------------------------
CScheduleItem::CScheduleItem(const char* szName)
: m_name(szName)
, m_refCount(1)
, m_state(eScheduleItemState_Pending)
{
}
CScheduleItem::~CScheduleItem()
{
CRY_ASSERT(m_refCount == 0);
for (TWorkItems::const_iterator it = m_workItems.begin();
it != m_workItems.end(); ++it)
{
(*it)->Release();
}
}
const char* CScheduleItem::GetDescription() const
{
return m_name.c_str();
}
EScheduleItemState CScheduleItem::GetState() const
{
return m_state;
}
const float CScheduleItem::GetProgress() const
{
if (m_workItems.empty())
{
return 1.0f;
}
else
{
float totalProgress = 0.0f;
for (TWorkItems::const_iterator it = m_workItems.begin();
it != m_workItems.end(); ++it)
{
totalProgress += (*it)->GetProgress();
}
return totalProgress / (float)m_workItems.size();
}
}
const uint32 CScheduleItem::GetNumWorkItems() const
{
return m_workItems.size();
}
IBackgroundScheduleItemWork* CScheduleItem::GetWorkItem(const uint32 index) const
{
return m_workItems[index];
}
void CScheduleItem::AddWorkItem(IBackgroundScheduleItemWork* pWork)
{
// cannot add new work items when item has finished or failed
if (m_state == eScheduleItemState_Failed || m_state == eScheduleItemState_Completed)
{
CryFatalError("Cannot add new work items when item has finished or failed");
return;
}
// add to the work list
if (m_state == eScheduleItemState_Processing)
{
m_addedWorkItems.push_back(pWork);
}
else
{
m_workItems.push_back(pWork);
}
}
void CScheduleItem::AddRef()
{
CryInterlockedIncrement(&m_refCount);
}
void CScheduleItem::Release()
{
const int nCount = CryInterlockedDecrement(&m_refCount);
assert(nCount >= 0);
if (nCount == 0)
{
delete this;
}
else if (nCount < 0)
{
assert(0);
CryFatalError("Deleting Reference Counted Object Twice");
}
}
void CScheduleItem::RequestStop()
{
if (m_state == eScheduleItemState_Pending)
{
// we can stop right away :)
m_state = eScheduleItemState_Failed;
}
else if (m_state == eScheduleItemState_Processing)
{
m_state = eScheduleItemState_Stopping;
// signal all pending work to stop
uint32 curIndex = 0;
while (curIndex < m_processedWorkItems.size())
{
IBackgroundScheduleItemWork* pWork = m_processedWorkItems[curIndex];
if (pWork->OnStop())
{
// if the work was stopped remove it from list
m_processedWorkItems.erase(m_processedWorkItems.begin() + curIndex);
continue;
}
else
{
// this work item cannot be stopped this frame
curIndex += 1;
}
}
// if all pending work has been stopped we can assume the failed state
if (m_processedWorkItems.empty())
{
m_state = eScheduleItemState_Failed;
}
}
}
EScheduleWorkItemStatus CScheduleItem::Update()
{
EScheduleWorkItemStatus retStatus = eScheduleWorkItemStatus_NotFinished;
switch (m_state)
{
// finial state - work failed
case eScheduleItemState_Failed:
{
retStatus = eScheduleWorkItemStatus_Failed;
break;
}
// final state - work completed
case eScheduleItemState_Completed:
{
retStatus = eScheduleWorkItemStatus_Finished;
break;
}
// first update, start all the work items
case eScheduleItemState_Pending:
{
// start all of the tasks
bool bHasFailedStarts = false;
for (TWorkItems::const_iterator it = m_workItems.begin();
it != m_workItems.end(); ++it)
{
IBackgroundScheduleItemWork* pWork = (*it);
if (pWork->OnStart())
{
m_processedWorkItems.push_back(pWork);
}
else
{
bHasFailedStarts = true;
break;
}
}
if (bHasFailedStarts)
{
m_state = eScheduleItemState_Stopping;
break;
}
else
{
m_state = eScheduleItemState_Processing;
/* FALLS THROUGHT TO PROCESSING STATE */
}
}
// work processing state
case eScheduleItemState_Processing:
{
// process new work items that were added while the schedule was created
if (!m_addedWorkItems.empty())
{
for (TWorkItems::const_iterator it = m_addedWorkItems.begin();
it != m_addedWorkItems.end(); ++it)
{
IBackgroundScheduleItemWork* pWork = (*it);
pWork->OnStart();
m_processedWorkItems.push_back(pWork);
m_workItems.push_back(pWork);
}
m_addedWorkItems.clear();
}
// update work items
bool bHasFailedItems = false;
TWorkItems completedItems;
for (TWorkItems::const_iterator it = m_processedWorkItems.begin();
it != m_processedWorkItems.end(); ++it)
{
IBackgroundScheduleItemWork* pWork = (*it);
// update given work item
const EScheduleWorkItemStatus status = pWork->OnUpdate();
if (status == eScheduleWorkItemStatus_Finished)
{
completedItems.push_back(pWork);
continue;
}
// item failed - we need to stop other tasks
if (status == eScheduleWorkItemStatus_Failed)
{
bHasFailedItems = true;
break;
}
}
// cleanup completed items
for (TWorkItems::iterator it = completedItems.begin();
it != completedItems.end(); ++it)
{
IBackgroundScheduleItemWork* pWork = (*it);
TWorkItems::iterator jt = std::find(m_processedWorkItems.begin(), m_processedWorkItems.end(), pWork);
m_processedWorkItems.erase(jt);
}
if (!bHasFailedItems)
{
// all work has finished
if (m_processedWorkItems.empty())
{
retStatus = eScheduleWorkItemStatus_Finished;
m_state = eScheduleItemState_Completed;
}
break;
}
else
{
// some of the items failed
m_state = eScheduleItemState_Stopping;
/* FALL THROUGH TO STOPPING STATE */
}
}
// We are stopping failed work
case eScheduleItemState_Stopping:
{
uint32 curIndex = 0;
while (curIndex < m_processedWorkItems.size())
{
IBackgroundScheduleItemWork* pWork = m_processedWorkItems[curIndex];
if (pWork->OnStop())
{
// if the work was stopped remove it from list
m_processedWorkItems.erase(m_processedWorkItems.begin() + curIndex);
continue;
}
else
{
// this work item cannot be stopped this frame
curIndex += 1;
}
}
// if all pending work has been stopped we can assume the failed state
if (m_processedWorkItems.empty())
{
m_state = eScheduleItemState_Failed;
return eScheduleWorkItemStatus_Failed;
}
}
}
return retStatus;
}
//-----------------------------------------------------------------------------
CSchedule::CSchedule(const char* szName)
: m_name(szName)
, m_refCount(1)
, m_bCanceled(false)
, m_currentItem(0)
, m_state(eScheduleState_Pending)
{
}
CSchedule::~CSchedule()
{
CRY_ASSERT(m_refCount == 0);
for (TItems::const_iterator it = m_items.begin();
it != m_items.end(); ++it)
{
CScheduleItem* pItem = *it;
SAFE_RELEASE(pItem);
}
m_items.clear();
}
const char* CSchedule::GetDescription() const
{
return m_name.c_str();
}
float CSchedule::GetProgress() const
{
if (m_currentItem >= m_items.size())
{
return 1.0f;
}
else
{
const float itemProgress = 1.0f / (float)(m_items.size());
const IBackgroundScheduleItem* pItem = m_items[m_currentItem];
return (m_currentItem + pItem->GetProgress()) * itemProgress;
}
}
IBackgroundScheduleItem* CSchedule::GetProcessedItem() const
{
if (m_currentItem >= m_items.size())
{
return NULL;
}
else
{
IBackgroundScheduleItem* pItem = m_items[m_currentItem];
return pItem;
}
}
const uint32 CSchedule::GetNumItems() const
{
return m_items.size();
}
IBackgroundScheduleItem* CSchedule::GetItem(const uint32 index) const
{
return m_items[index];
}
EScheduleState CSchedule::GetState() const
{
return m_state;
}
void CSchedule::Cancel()
{
m_bCanceled = true;
}
bool CSchedule::IsCanceled() const
{
return m_bCanceled;
}
void CSchedule::AddItem(IBackgroundScheduleItem* pItem)
{
if (NULL == pItem)
{
return;
}
// we can add items only in the "pending" state
if (pItem->GetState() != eScheduleItemState_Pending)
{
CryFatalError("Schedule items can be added to schedule only before their work starts");
return;
}
// item has no jobs, do not add
if (pItem->GetNumWorkItems() == 0)
{
return;
}
m_items.push_back(static_cast<CScheduleItem*>(pItem));
pItem->AddRef();
}
void CSchedule::AddRef()
{
CryInterlockedIncrement(&m_refCount);
}
void CSchedule::Release()
{
const int nCount = CryInterlockedDecrement(&m_refCount);
assert(nCount >= 0);
if (nCount == 0)
{
delete this;
}
else if (nCount < 0)
{
assert(0);
CryFatalError("Deleting Reference Counted Object Twice");
}
}
EScheduleWorkItemStatus CSchedule::Update()
{
EScheduleWorkItemStatus retStatus = eScheduleWorkItemStatus_NotFinished;
// we have a cancel request
if (m_bCanceled)
{
CryLog("Schedule '%s' was canceled", GetDescription());
if (m_state == eScheduleState_Processing && m_currentItem < m_items.size())
{
// stop the current item
CScheduleItem* pItem = m_items[m_currentItem];
pItem->RequestStop();
m_state = eSccheduleState_Stopping;
}
else if (m_state != eScheduleState_Completed)
{
m_state = eScheduleState_Failed;
return eScheduleWorkItemStatus_Failed;
}
}
// process internal state machine
switch (m_state)
{
// final state - work failed
case eScheduleState_Failed:
{
retStatus = eScheduleWorkItemStatus_Failed;
break;
}
// final state - work completed
case eScheduleState_Completed:
{
retStatus = eScheduleWorkItemStatus_Finished;
break;
}
// stopping current task
case eSccheduleState_Stopping:
{
if (m_currentItem < m_items.size())
{
CScheduleItem* pItem = m_items[m_currentItem];
if (pItem->Update() != eScheduleWorkItemStatus_NotFinished)
{
// task was finally stopped
m_state = eScheduleState_Failed;
retStatus = eScheduleWorkItemStatus_Failed;
}
}
break;
}
// first update, switch to processing
case eScheduleState_Pending:
{
m_state = eScheduleState_Processing;
m_currentItem = 0;
/* FALLS THROUGHT */
}
// if we were in the processing phase inform the current schedule item to stop all it's work
case eScheduleState_Processing:
{
// update schedule items
while (m_currentItem < m_items.size())
{
CScheduleItem* pItem = m_items[m_currentItem];
const EScheduleWorkItemStatus itemStatus = pItem->Update();
if (itemStatus == eScheduleWorkItemStatus_Finished)
{
m_currentItem += 1;
continue;
}
else if (itemStatus == eScheduleWorkItemStatus_Failed)
{
m_state = eScheduleState_Failed;
retStatus = eScheduleWorkItemStatus_Failed;
gEnv->pLog->LogWarning("Schedule '%s' failed on item '%s'.", GetDescription(), pItem->GetDescription());
}
break;
}
// all items updated
if (m_currentItem >= m_items.size())
{
// empty schedule, complete in one tick
m_state = eScheduleState_Completed;
retStatus = eScheduleWorkItemStatus_Finished;
CryLog("Schedule '%s' completed", GetDescription());
}
break;
}
}
return retStatus;
}
//-----------------------------------------------------------------------------
CScheduleManager::CScheduleManager()
{
GetIEditor()->RegisterNotifyListener(this);
}
CScheduleManager::~CScheduleManager()
{
GetIEditor()->UnregisterNotifyListener(this);
for (TSchedules::const_iterator it = m_schedules.begin();
it != m_schedules.end(); ++it)
{
CSchedule* pSchedule = *it;
SAFE_RELEASE(pSchedule);
}
m_schedules.clear();
}
IBackgroundSchedule* CScheduleManager::CreateSchedule(const char* szName)
{
return new CSchedule(szName);
}
IBackgroundScheduleItem* CScheduleManager::CreateScheduleItem(const char* szName)
{
return new CScheduleItem(szName);
}
void CScheduleManager::SubmitSchedule(IBackgroundSchedule* pSchedule)
{
if (NULL != pSchedule)
{
if (pSchedule->GetState() != eScheduleState_Pending)
{
CryFatalError("Only schedules with pending state can be submitted");
return;
}
pSchedule->AddRef();
m_schedules.push_back(static_cast<CSchedule*>(pSchedule));
}
}
const uint32 CScheduleManager::GetNumSchedules() const
{
return m_schedules.size();
}
IBackgroundSchedule* CScheduleManager::GetSchedule(const uint32 index) const
{
return m_schedules[index];
}
void CScheduleManager::Update()
{
while (!m_schedules.empty())
{
CSchedule* pSchedule = m_schedules[0];
const EScheduleWorkItemStatus status = pSchedule->Update();
if (status == eScheduleWorkItemStatus_NotFinished)
{
// we need more work next frame
break;
}
// schedule has finished, remove current reference
m_schedules.erase(m_schedules.begin());
SAFE_RELEASE(pSchedule);
}
}
void CScheduleManager::OnEditorNotifyEvent(EEditorNotifyEvent ev)
{
switch (ev)
{
case eNotify_OnQuit:
GetIEditor()->UnregisterNotifyListener(this);
break;
}
}
//-----------------------------------------------------------------------------
} // BackgroundScheduleManager
@@ -1,117 +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_EDITOR_BACKGROUNDSCHEDULEMANAGER_H
#define CRYINCLUDE_EDITOR_BACKGROUNDSCHEDULEMANAGER_H
#pragma once
#include "Include/IBackgroundScheduleManager.h"
namespace BackgroundScheduleManager
{
class CScheduleItem
: public IBackgroundScheduleItem
{
private:
std::string m_name;
volatile int m_refCount;
EScheduleItemState m_state;
typedef std::vector<IBackgroundScheduleItemWork*> TWorkItems;
TWorkItems m_workItems;
TWorkItems m_addedWorkItems;
TWorkItems m_processedWorkItems;
public:
CScheduleItem(const char* szName);
virtual ~CScheduleItem();
// IBackgroundScheduleItem interface
virtual const char* GetDescription() const;
virtual EScheduleItemState GetState() const;
virtual const float GetProgress() const;
virtual const uint32 GetNumWorkItems() const;
virtual IBackgroundScheduleItemWork* GetWorkItem(const uint32 index) const;
virtual void AddWorkItem(IBackgroundScheduleItemWork* pWork);
virtual void AddRef();
virtual void Release();
// Update schedule item
EScheduleWorkItemStatus Update();
// Request to stop work in this item
void RequestStop();
};
class CSchedule
: public IBackgroundSchedule
{
private:
std::string m_name;
volatile int m_refCount;
bool m_bCanceled;
EScheduleState m_state;
typedef std::vector<CScheduleItem*> TItems;
TItems m_items;
uint32 m_currentItem;
public:
CSchedule(const char* szName);
virtual ~CSchedule();
// IBackgroundSchedule interface
virtual const char* GetDescription() const;
virtual float GetProgress() const;
virtual IBackgroundScheduleItem* GetProcessedItem() const;
virtual const uint32 GetNumItems() const;
virtual IBackgroundScheduleItem* GetItem(const uint32 index) const;
virtual EScheduleState GetState() const;
virtual void Cancel();
virtual bool IsCanceled() const;
virtual void AddItem(IBackgroundScheduleItem* pItem);
virtual void AddRef();
virtual void Release();
// Update schedule item
EScheduleWorkItemStatus Update();
};
class CScheduleManager
: public IBackgroundScheduleManager
, public IEditorNotifyListener
{
private:
typedef std::vector<CSchedule*> TSchedules;
TSchedules m_schedules;
public:
CScheduleManager();
virtual ~CScheduleManager();
// IBackgroundScheduleManager interface
virtual IBackgroundSchedule* CreateSchedule(const char* szName);
virtual IBackgroundScheduleItem* CreateScheduleItem(const char* szName);
virtual void SubmitSchedule(IBackgroundSchedule* pSchedule);
virtual const uint32 GetNumSchedules() const;
virtual IBackgroundSchedule* GetSchedule(const uint32 index) const;
virtual void Update();
// IEditorNotifyListener interface implementation
virtual void OnEditorNotifyEvent(EEditorNotifyEvent ev) override;
};
}
#endif // CRYINCLUDE_EDITOR_BACKGROUNDSCHEDULEMANAGER_H
@@ -1,410 +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 "EditorDefs.h"
#include "BackgroundTaskManager.h"
namespace BackgroundTaskManager
{
//-----------------------------------------------------------------------------
CTaskManager::CThread::CThread(class CTaskManager* pManager, CQueue* pQueue)
: m_pManager(pManager)
, m_pQueue(pQueue)
{
start();
}
CTaskManager::CThread::~CThread()
{
}
void CTaskManager::CThread::WaitForThread()
{
wait();
}
void CTaskManager::CThread::run()
{
CryThreadSetName(-1, "BackgroundTaskThread");
while (!m_pManager->IsStopped())
{
STaskHandle taskHandle;
// This blocks on Semaphore waiting for task from queue
m_pQueue->PopTask(taskHandle);
// Should not happen but it's a stupid way to crash :)
if (NULL == taskHandle.pTask)
{
continue;
}
if (taskHandle.pTask->IsCanceled())
{
// Task was canceled before we got here
m_pManager->AddCompletedTask(taskHandle, eTaskResult_Canceled);
}
else
{
const ETaskResult state = taskHandle.pTask->Work();
if (state == eTaskResult_Resume)
{
// Put it back into queue, so more important task can take over.
m_pManager->AddTask(taskHandle);
}
else
{
// Finish task
m_pManager->AddCompletedTask(taskHandle, state);
}
}
}
}
//-----------------------------------------------------------------------------
CTaskManager::CQueue::CQueue()
: m_semaphore(INT_MAX, 0) // no good maximum value, assume worst case
{
}
void CTaskManager::CQueue::AddTask(const STaskHandle& taskHandle)
{
{
CryAutoLock<CryMutex> lock(m_lock);
// TODO: use heap?
m_pendingTasks.insert(m_pendingTasks.begin(), taskHandle);
std::stable_sort(m_pendingTasks.begin(), m_pendingTasks.end());
}
taskHandle.pTask->SetState(eTaskState_Pending);
// release internal semaphore so threads can pick up the work
m_semaphore.Release();
}
void CTaskManager::CQueue::PopTask(STaskHandle& outTaskHandle)
{
// wait for job
m_semaphore.Acquire();
{
CryAutoLock<CryMutex> lock(m_lock);
if (m_pendingTasks.empty())
{
outTaskHandle.pTask = NULL;
}
else
{
outTaskHandle = m_pendingTasks.back();
outTaskHandle.pTask->SetState(eTaskState_Working);
m_pendingTasks.pop_back();
}
}
}
void CTaskManager::CQueue::ReleaseSemaphore()
{
m_semaphore.Release();
}
void CTaskManager::CQueue::Clear()
{
CryAutoLock<CryMutex> lock(m_lock);
for (uint i = 0; i < m_pendingTasks.size(); ++i)
{
m_pendingTasks[i].pTask->Release();
}
m_pendingTasks.clear();
}
//-----------------------------------------------------------------------------
CTaskManager::CTaskManager()
: m_bStop(false)
, m_nextTaskID(1)
, m_listeners(1)
{
GetIEditor()->RegisterNotifyListener(this);
}
CTaskManager::~CTaskManager()
{
if (!m_bStop)
{
Stop();
}
}
void CTaskManager::Start(const uint32 threadCount /*=kDefaultThreadCount*/)
{
m_bStop = false;
if (m_pThreads.empty())
{
// Always create one IO thread
{
CThread* pThread = new CThread(this, &m_pendingTasks[ eTaskThreadMask_IO ]);
m_pThreads.push_back(pThread);
}
// We also need at least one generic thread
const uint32 numGenericThreads = max<uint32>(threadCount, 1);
for (uint32 i = 0; i < numGenericThreads; ++i)
{
CThread* pThread = new CThread(this, &m_pendingTasks[ eTaskThreadMask_Any ]);
m_pThreads.push_back(pThread);
}
}
}
void CTaskManager::StartScheduledTasks()
{
CryAutoLock<CryMutex> lock(m_tasksLock);
if (!m_scheduledTasks.empty())
{
const unsigned int time = GetTickCount();
while (!m_scheduledTasks.empty())
{
const int delta = (int)(time - m_scheduledTasks[0].time);
if (delta > 0)
{
// the soonest task on the list is still in the future, no point in looking at the next entries in the list
break;
}
// promote the scheduled task to be a full task
AddTask(m_scheduledTasks[0].handle);
// We held a reference to the task on list, release it
m_scheduledTasks[0].handle.pTask->Release();
m_scheduledTasks.erase(m_scheduledTasks.begin());
}
}
}
void CTaskManager::Stop()
{
if (!m_bStop)
{
m_bStop = true;
GetIEditor()->UnregisterNotifyListener(this);
// clear queues - no new tasks will be processed
for (uint32 i = 0; i < eTaskThreadMask_COUNT; ++i)
{
m_pendingTasks[i].Clear();
}
// kick all the threads to allow them to quit
for (uint32 j = 0; j < m_pThreads.size(); ++j)
{
for (uint32 i = 0; i < eTaskThreadMask_COUNT; ++i)
{
m_pendingTasks[i].ReleaseSemaphore();
}
}
// Stop threads
for (TWorkerThreads::iterator it = m_pThreads.begin();
it != m_pThreads.end(); ++it)
{
(*it)->WaitForThread();
delete *it;
}
m_pThreads.clear();
}
}
void CTaskManager::AddListener(IBackgroundTaskManagerListener* pListener, const char* name)
{
m_listeners.Add(pListener, name);
}
void CTaskManager::RemoveListener(IBackgroundTaskManagerListener* pListener)
{
m_listeners.Remove(pListener);
}
void CTaskManager::AddTask(IBackgroundTask* pTask, ETaskPriority priority, ETaskThreadMask threadMask)
{
MAKE_SURE(pTask != 0, return );
// keep an extra reference to the task in the manager
pTask->AddRef();
STaskHandle handle;
handle.id = CryInterlockedIncrement(&m_nextTaskID);
handle.priority = priority;
handle.threadMask = threadMask;
handle.pTask = pTask;
AddTask(handle);
for (TListeners::Notifier notifier(m_listeners); notifier.IsValid(); notifier.Next())
{
notifier->OnBackgroundTaskAdded(pTask->Description());
}
}
void CTaskManager::ScheduleTask(IBackgroundTask* pTask, ETaskPriority priority, int delayMilliseconds, ETaskThreadMask threadMask)
{
MAKE_SURE(delayMilliseconds >= 0, return );
MAKE_SURE(pTask != 0, return );
// keep an extra reference to the task in the manager
pTask->AddRef();
SScheduledTask task;
task.time = GetTickCount() + delayMilliseconds;
task.handle.pTask = pTask;
task.handle.id = CryInterlockedIncrement(&m_nextTaskID);
task.handle.threadMask = threadMask;
task.handle.priority = priority;
{
CryAutoLock<CryMutex> lock(m_tasksLock);
m_scheduledTasks.push_back(task);
}
for (TListeners::Notifier notifier(m_listeners); notifier.IsValid(); notifier.Next())
{
notifier->OnBackgroundTaskAdded(pTask->Description());
}
}
void CTaskManager::AddTask(const STaskHandle& handle)
{
MAKE_SURE(handle.pTask != 0, return );
MAKE_SURE(handle.id != 0, return );
// add task to appropriate queue (every thread mask has it's own queue)
m_pendingTasks[handle.threadMask].AddTask(handle);
}
void CTaskManager::AddCompletedTask(const STaskHandle& handle, ETaskResult resultState)
{
CryAutoLock<CryMutex> lock(m_tasksLock);
CRY_ASSERT(handle.pTask->GetState() == eTaskState_Working);
CRY_ASSERT(resultState != eTaskResult_Resume);
// Update task state
switch (resultState)
{
case eTaskResult_Canceled:
{
handle.pTask->SetState(eTaskState_Canceled);
break;
}
case eTaskResult_Completed:
{
handle.pTask->SetState(eTaskState_Completed);
break;
}
case eTaskResult_Failed:
{
handle.pTask->SetState(eTaskState_Failed);
break;
}
}
// add to the list of completed tasks (for calling the Finalize)
// TODO: some of the tasks do not require Finalize() and they could be released here instead of the main thread
SCompletedTask info;
info.pTask = handle.pTask;
info.id = handle.id;
info.state = resultState;
m_completedTasks.push_back(info);
}
void CTaskManager::Update()
{
std::vector<SCompletedTask> completedTasks;
{
CryAutoLock<CryMutex> lock(m_tasksLock);
m_completedTasks.swap(completedTasks);
}
// call finalize for the completed tasks
for (size_t i = 0; i < completedTasks.size(); ++i)
{
SCompletedTask& handle = completedTasks[i];
if (NULL != handle.pTask)
{
string description = handle.pTask->Description(); // copy string as the description is used after pTask is destroyed
if (handle.state == eTaskResult_Completed)
{
if (description && description[0] != '\0')
{
gEnv->pLog->Log("Task Completed: %s", description.c_str());
}
}
else if (handle.state == eTaskResult_Failed)
{
if (description && description[0] != '\0' && !handle.pTask->FailReported())
{
gEnv->pLog->LogError("Task Failed: %s ", description.c_str());
const char* errorMessage = handle.pTask->ErrorMessage();
if (errorMessage && errorMessage[0] != '\0')
{
gEnv->pLog->LogError("\tReason: [%s]", errorMessage);
}
}
}
handle.pTask->Finalize();
// release the internal (task manager) reference.
// Tthis is usually the last reference to the task so it gets deleted here.
handle.pTask->Release();
for (TListeners::Notifier notifier(m_listeners); notifier.IsValid(); notifier.Next())
{
notifier->OnBackgroundTaskCompleted(handle.state, description.c_str());
}
}
}
}
void CTaskManager::OnEditorNotifyEvent(EEditorNotifyEvent ev)
{
switch (ev)
{
case eNotify_OnInit:
Start();
break;
case eNotify_OnIdleUpdate:
Update();
break;
case eNotify_OnQuit:
Stop();
break;
}
}
}
-161
View File
@@ -1,161 +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_EDITOR_BACKGROUNDTASKMANAGER_H
#define CRYINCLUDE_EDITOR_BACKGROUNDTASKMANAGER_H
#pragma once
#include "Include/IBackgroundTaskManager.h"
#include "CryListenerSet.h"
#include <QThread>
namespace BackgroundTaskManager
{
typedef int TTaskID;
struct STaskHandle
{
ETaskPriority priority;
ETaskThreadMask threadMask;
TTaskID id;
IBackgroundTask* pTask;
bool operator<(const STaskHandle& rhs) const
{
if (priority < rhs.priority)
{
return true;
}
if (priority > rhs.priority)
{
return false;
}
return id < rhs.id;
}
};
struct SCompletedTask
{
ETaskResult state;
TTaskID id;
ETaskThreadMask threadMask;
IBackgroundTask* pTask;
};
struct SScheduledTask
{
unsigned int time;
STaskHandle handle;
};
class CTaskManager
: public IBackgroundTaskManager
, public IEditorNotifyListener
{
public:
CTaskManager();
~CTaskManager();
// IBackgroundTaskManager interface implementation
virtual void AddTask(IBackgroundTask* pTask, ETaskPriority priority, ETaskThreadMask threadMask) override;
virtual void ScheduleTask(IBackgroundTask* pTask, ETaskPriority priority, int delayMilliseconds, ETaskThreadMask threadMask) override;
void AddListener(IBackgroundTaskManagerListener* pListener, const char* name) override;
void RemoveListener(IBackgroundTaskManagerListener* pListener) override;
private:
// IEditorNotifyListener interface implementation
virtual void OnEditorNotifyEvent(EEditorNotifyEvent ev) override;
void Start(const uint32 threadCount = kDefaultThreadCount);
void Stop();
void StartScheduledTasks();
void AddTask(const STaskHandle& outTask);
void AddCompletedTask(const STaskHandle& outTask, ETaskResult resultState);
void Update();
inline bool IsStopped() const
{
return m_bStop;
}
private:
// Internal queue (per thread mask)
class CQueue
{
public:
CQueue();
// Add task to list
void AddTask(const STaskHandle& taskHandle);
// Pop task from list
void PopTask(STaskHandle& outTaskHandle);
// Release thread semaphore without adding a task
void ReleaseSemaphore();
// Remove all pending tasks
void Clear();
private:
CrySemaphore m_semaphore;
std::vector<STaskHandle> m_pendingTasks;
CryMutex m_lock;
};
// Worker thread class implementation
class CThread : public QThread
{
public:
CThread(CTaskManager* pManager, CQueue* pQueue);
~CThread();
void WaitForThread();
private:
void run() override;
private:
CTaskManager* m_pManager;
CQueue* m_pQueue;
};
private:
static const uint32 kMaxThreadCloseWaitTime = 10000; // ms
static const uint32 kDefaultThreadCount = 4; // good enough for LiveCreate (main user right now), do not set to less than 2
CQueue m_pendingTasks[ eTaskThreadMask_COUNT ];
// Task scheduled for execution in the future
std::vector<SScheduledTask> m_scheduledTasks;
// Completed tasks (waiting for the "finalize" call)
std::vector<SCompletedTask> m_completedTasks;
volatile TTaskID m_nextTaskID;
typedef std::vector<CThread*> TWorkerThreads;
TWorkerThreads m_pThreads;
CryMutex m_tasksLock;
bool m_bStop;
typedef CListenerSet<IBackgroundTaskManagerListener*> TListeners;
TListeners m_listeners;
};
}
//-----------------------------------------------------------------------------
#endif // CRYINCLUDE_EDITOR_BACKGROUNDTASKMANAGER_H
-1
View File
@@ -112,7 +112,6 @@ ly_add_target(
3rdParty::zlib
3rdParty::AWSNativeSDK::STS
Legacy::CryCommon
Legacy::CryCommon.EngineSettings.Static
Legacy::EditorCommon
AZ::AzCore
AZ::AzToolsFramework
@@ -1,821 +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 "EditorDefs.h"
#include "CurveEditorCtrl.h"
// Qt
#include <QPainter>
#include <QPainterPath>
namespace CurveEditor
{
const int kHandleSize = 6;
const int kHandleSizeHalf = kHandleSize / 2;
const int kDefaultPadding = 10;
const int kInfoFontSize = 7;
const int kGrid = 4;
const QColor kColor_SelectCross(132, 132, 132);
const QColor kColor_DisabledCross(90, 90, 90);
const QColor kColor_MiddleLines(80, 80, 80);
const QColor kColor_Background(41, 41, 41);
const QColor kColor_Disabled(60, 60, 60);
const QColor kColor_PaddingBorder(128, 128, 128);
const QColor kColor_Text(128, 128, 128);
const QColor kColor_TextCrtPos(187, 187, 187);
const QColor kColor_Curve(255, 0, 0);
const QColor kColor_SelHandle(200, 200, 200);
const QColor kColor_NormalHandle(30, 30, 30);
const QColor kColor_HandleLight(60, 60, 60);
const QColor kColor_HandleShadow(0, 0, 0);
const QColor kColor_MarkLines(0, 255, 0);
}
CCurveEditorCtrl::CCurveEditorCtrl(QWidget* parent)
: QWidget(parent)
{
m_domainMinX = 0.0f;
m_domainMinY = 0.0f;
m_domainMaxX = 1.0f;
m_domainMaxY = 1.0f;
m_bMouseDown = m_bDragging = false;
m_bAllowMouse = true;
m_padding = CurveEditor::kDefaultPadding;
m_flags = eFlag_ShowVerticalRuler
| eFlag_ShowHorizontalRuler
| eFlag_ShowVerticalRulerText
| eFlag_ShowHorizontalRulerText
| eFlag_ShowPaddingBorder
| eFlag_ShowMovingPointAxis
| eFlag_ShowPointHandles;
m_gridSplits.set(CurveEditor::kGrid, CurveEditor::kGrid);
m_fntInfo.setFamily("Arial");
m_fntInfo.setPointSize(CurveEditor::kInfoFontSize);
m_bHovered = false;
m_selCrossPen = QPen(CurveEditor::kColor_SelectCross);
GenerateDefaultCurve();
}
CCurveEditorCtrl::~CCurveEditorCtrl()
{
}
void CCurveEditorCtrl::SetFlags(UINT aFlags)
{
m_flags = aFlags;
}
UINT CCurveEditorCtrl::GetFlags() const
{
return m_flags;
}
bool CCurveEditorCtrl::SetDomainBounds(float aMinX, float aMinY, float aMaxX, float aMaxY)
{
assert(aMinX < aMaxX);
assert(aMinY < aMaxY);
if (aMinX >= aMaxX)
{
return false;
}
if (aMinY >= aMaxY)
{
return false;
}
m_domainMinX = aMinX;
m_domainMinY = aMinY;
m_domainMaxX = aMaxX;
m_domainMaxY = aMaxY;
return true;
}
void CCurveEditorCtrl::GetDomainBounds(float& rMinX, float& rMinY, float& rMaxX, float& rMaxY) const
{
rMinX = m_domainMinX;
rMinY = m_domainMinY;
rMaxX = m_domainMaxX;
rMaxY = m_domainMaxY;
}
void CCurveEditorCtrl::SetGrid(UINT aHorizontalSplits, UINT aVerticalSplits, const QStringList& labelsX, const QStringList& labelsY)
{
assert(aHorizontalSplits);
assert(aVerticalSplits);
if (!aHorizontalSplits)
{
// defaults
aHorizontalSplits = 2;
}
if (!aVerticalSplits)
{
// defaults
aVerticalSplits = 2;
}
m_gridSplits.x = aHorizontalSplits;
m_gridSplits.y = aVerticalSplits;
if (!labelsX.isEmpty())
{
m_labelsX = labelsX;
}
if (!labelsY.isEmpty())
{
m_labelsY = labelsY;
}
}
QPoint CCurveEditorCtrl::ProjectPoint(float x, float y)
{
QPoint pt;
pt.setX(m_padding + (width() - m_padding * 2) * (x - m_domainMinX) / (m_domainMaxX - m_domainMinX));
pt.setY(m_padding + (height() - m_padding * 2) * (1.0f - (y - m_domainMinY) / (m_domainMaxY - m_domainMinY)));
return pt;
}
Vec2 CCurveEditorCtrl::UnprojectPoint(const QPoint& pt)
{
Vec2 vec;
int y = height() - pt.y();
float dx = (width() - m_padding * 2);
float dy = (height() - m_padding * 2);
const float kEpsilon = 0.00000001f;
if (fabs(dx) <= kEpsilon)
{
dx = 1.0f;
}
if (fabs(dy) <= kEpsilon)
{
dy = 1.0f;
}
vec.x = m_domainMinX + (float)(pt.x() - m_padding) / dx * (m_domainMaxX - m_domainMinX);
vec.y = m_domainMinY + (float)(y - m_padding) / dy * (m_domainMaxY - m_domainMinY);
return vec;
}
void CCurveEditorCtrl::SetControlPointCount(UINT aCount)
{
m_points.resize(aCount);
m_projectedPoints.clear();
}
UINT CCurveEditorCtrl::GetControlPointCount() const
{
return m_points.size();
}
void CCurveEditorCtrl::AddControlPoint(const Vec2& rPosition)
{
m_points.push_back(CurvePoint(rPosition.x, rPosition.y));
}
void CCurveEditorCtrl::ClearControlPoints()
{
m_points.clear();
}
void CCurveEditorCtrl::SetControlPoint(UINT aIndex, const Vec2& rPosition)
{
assert(aIndex < m_points.size());
if (aIndex >= m_points.size())
{
return;
}
m_points[aIndex].pos = rPosition;
}
void CCurveEditorCtrl::SetControlPointTangents(UINT aIndex, const Vec2& rLeft, const Vec2& rRight)
{
assert(aIndex < m_points.size());
if (aIndex >= m_points.size())
{
return;
}
m_points[aIndex].tanA = rLeft;
m_points[aIndex].tanB = rRight;
}
void CCurveEditorCtrl::GetControlPoint(UINT aIndex, Vec2& rOutPosition) const
{
assert(aIndex < m_points.size());
if (aIndex >= m_points.size())
{
return;
}
rOutPosition = m_points[aIndex].pos;
}
void CCurveEditorCtrl::GetControlPointTangents(UINT aIndex, Vec2& rOutLeft, Vec2& rOutRight) const
{
assert(aIndex < m_points.size());
if (aIndex >= m_points.size())
{
return;
}
rOutLeft = m_points[aIndex].tanA;
rOutRight = m_points[aIndex].tanB;
}
void CCurveEditorCtrl::paintEvent(QPaintEvent* event)
{
QWidget::paintEvent(event);
QPainter dc(this);
QRect rc = geometry();
QString str;
QRect textSize;
dc.setFont(m_fntInfo);
QFontMetrics fntMetrics(m_fntInfo);
if (m_flags & eFlag_Disabled)
{
// If disabled, just draw a blank square.
dc.fillRect(rc, CurveEditor::kColor_Disabled);
dc.setPen(CurveEditor::kColor_DisabledCross);
dc.drawLine(0, 0, rc.width(), rc.height());
dc.drawLine(rc.width(), 0, 0, rc.height());
return;
}
dc.fillRect(rc, CurveEditor::kColor_Background);
dc.setPen(CurveEditor::kColor_MiddleLines);
if (m_flags & eFlag_ShowVerticalRuler)
{
float y = m_domainMinY;
float grid = (m_domainMaxY - m_domainMinY) / m_gridSplits.y;
QPoint p;
for (int i = 0; i <= m_gridSplits.y; ++i)
{
p = ProjectPoint(0, y);
dc.drawLine(m_padding, p.y(), rc.width() - m_padding, p.y());
if (m_flags & eFlag_ShowVerticalRulerText)
{
if (m_labelsY.empty())
{
str.asprintf("%0.2f", y);
}
else
{
str = m_labelsY[i];
}
textSize = fntMetrics.tightBoundingRect(str);
dc.drawText(2, p.y(), str);
}
y += grid;
}
}
if (m_flags & eFlag_ShowHorizontalRuler)
{
float x = m_domainMinX;
float grid = (m_domainMaxX - m_domainMinX) / m_gridSplits.x;
QPoint p;
for (int i = 0; i <= m_gridSplits.x; ++i)
{
p = ProjectPoint(x, 0);
dc.drawLine(p.x(), m_padding, p.x(), rc.height() - m_padding);
if (m_flags & eFlag_ShowHorizontalRulerText)
{
if (m_labelsX.empty())
{
str.asprintf("%0.2f", x);
}
else
{
str = m_labelsX[i];
}
textSize = fntMetrics.tightBoundingRect(str);
p.setX(p.x() + 2);
if (p.x() + textSize.width() > width())
{
p.setX(width() - textSize.width());
}
dc.drawText(p.x(), height() - m_padding + textSize.height() + 2, str);
}
x += grid;
}
}
dc.setPen(CurveEditor::kColor_MarkLines);
if (m_flags & eFlag_ShowVerticalRuler)
{
QPoint p;
for (size_t i = 0; i < m_marksY.size(); ++i)
{
float v = m_marksY[i];
if (v < m_domainMinY || v > m_domainMaxY)
{
continue;
}
p = ProjectPoint(0, v);
dc.drawLine(m_padding, p.y(), width() - m_padding, p.y());
}
}
if (m_flags & eFlag_ShowHorizontalRuler)
{
QPoint p;
for (size_t i = 0; i < m_marksX.size(); ++i)
{
float v = m_marksX[i];
if (v < m_domainMinX || v > m_domainMaxX)
{
continue;
}
p = ProjectPoint(v, 0);
dc.drawLine(p.x(), m_padding, p.x(), height() - m_padding);
}
}
if (m_flags & eFlag_ShowPaddingBorder)
{
dc.setPen(CurveEditor::kColor_PaddingBorder);
dc.drawRect(m_padding, m_padding, width() - m_padding * 2, height() - m_padding * 2);
}
if (m_bDragging
&& !m_selectedIndices.empty()
&& (m_flags & eFlag_ShowMovingPointAxis))
{
const Vec2& crtPos = m_points[m_selectedIndices[0]].pos;
dc.setBrush(CurveEditor::kColor_TextCrtPos);
str.asprintf("(%0.2f,%0.2f)", crtPos.x, crtPos.y);
textSize = fntMetrics.tightBoundingRect(str);
const int kOffsetFromPointer = 5;
QPoint txtPos(m_lastMousePoint.x() + kOffsetFromPointer, m_lastMousePoint.y() + kOffsetFromPointer);
if (txtPos.x() + textSize.width() > width())
{
txtPos.setX(width() - textSize.width());
}
if (txtPos.y() + textSize.height() > height())
{
txtPos.setY(height() - textSize.height());
}
dc.drawText(txtPos, str);
}
ComputeTangents();
UpdateProjectedPoints();
// for curve debug, tangents poly, don't delete
// dc.setPen(Qt::black);
// dc.drawPolyline(m_projectedPoints.data(), m_projectedPoints.size());
dc.setPen(CurveEditor::kColor_Curve);
// curve
QPainterPath bezierPath;
bezierPath.moveTo(m_projectedPoints[0]);
for (int i = 1; i < m_projectedPoints.size(); i += 3)
{
bezierPath.cubicTo(m_projectedPoints[i], m_projectedPoints[i + 1], m_projectedPoints[i + 2]);
}
dc.drawPath(bezierPath);
// curve control point handles
if (m_flags & eFlag_ShowPointHandles)
{
for (size_t i = 0; i < m_points.size(); ++i)
{
QPoint ptProj = ProjectPoint(m_points[i].pos.x, m_points[i].pos.y);
QRect rcHandle(0, 0, CurveEditor::kHandleSize, CurveEditor::kHandleSize);
rcHandle.moveCenter(ptProj);
std::vector<int>::iterator iter =
std::find(m_selectedIndices.begin(), m_selectedIndices.end(), i);
bool bSelected = (iter != m_selectedIndices.end());
if (bSelected && m_bDragging)
{
dc.setPen(m_selCrossPen);
dc.drawLine(0, ptProj.y(), width(), ptProj.y());
dc.drawLine(ptProj.x(), 0, ptProj.x(), height());
}
dc.fillRect(rcHandle, bSelected
? CurveEditor::kColor_SelHandle
: CurveEditor::kColor_NormalHandle);
dc.setPen(CurveEditor::kColor_HandleLight);
dc.drawLine(ptProj.x() - CurveEditor::kHandleSizeHalf, ptProj.y() - CurveEditor::kHandleSizeHalf,
ptProj.x() - CurveEditor::kHandleSizeHalf, ptProj.y() + CurveEditor::kHandleSizeHalf);
dc.drawLine(ptProj.x() - CurveEditor::kHandleSizeHalf, ptProj.y() + CurveEditor::kHandleSizeHalf,
ptProj.x() + CurveEditor::kHandleSizeHalf, ptProj.y() + CurveEditor::kHandleSizeHalf);
dc.setPen(CurveEditor::kColor_HandleShadow);
dc.drawLine(ptProj.x() + CurveEditor::kHandleSizeHalf, ptProj.y() + CurveEditor::kHandleSizeHalf,
ptProj.x() + CurveEditor::kHandleSizeHalf, ptProj.y() - CurveEditor::kHandleSizeHalf);
dc.drawLine(ptProj.x() + CurveEditor::kHandleSizeHalf, ptProj.y() - CurveEditor::kHandleSizeHalf,
ptProj.x() - CurveEditor::kHandleSizeHalf, ptProj.y() - CurveEditor::kHandleSizeHalf);
}
}
}
void CCurveEditorCtrl::ComputeTangents()
{
for (size_t i = 0; i < m_points.size(); ++i)
{
m_points[i].tanA = m_points[i].pos;
m_points[i].tanB = m_points[i].pos;
}
int maxIndex = m_points.size() - 1;
for (size_t i = 0; i < m_points.size(); ++i)
{
if (i > maxIndex)
{
break;
}
Vec2& p2 = m_points[i].pos;
Vec2& back = m_points[i].tanA;
Vec2& forw = m_points[i].tanB;
const float kEpsilon = 0.000001f;
// first point
if (i == 0)
{
back = p2;
if (maxIndex == 1)
{
Vec2& p3 = m_points[i + 1].pos;
forw = p2 + (p3 - p2) / 3.0f;
}
else if (maxIndex > 0)
{
Vec2& p3 = m_points[i + 1].pos;
Vec2& pb3 = m_points[i + 1].tanA;
float lenOsn = (pb3 - p2).GetLength();
float lenb = (p3 - p2).GetLength();
if (lenOsn > kEpsilon && lenb > kEpsilon)
{
forw = p2 + (pb3 - p2) / (lenOsn / lenb * 3.0f);
}
else
{
forw = p2;
}
}
}
if (i == maxIndex)
{
forw = p2;
if (i > 0)
{
Vec2& p1 = m_points[i - 1].pos;
Vec2& pf1 = m_points[i - 1].tanB;
float lenOsn = (pf1 - p2).GetLength();
float lenf = (p1 - p2).GetLength();
if (lenOsn > kEpsilon && lenf > kEpsilon)
{
back = p2 + (pf1 - p2) / (lenOsn / lenf * 3.0f);
}
else
{
back = p2;
}
}
}
else if (i >= 1 && i <= maxIndex - 1)
{
Vec2& p1 = m_points[i - 1].pos;
Vec2& p3 = m_points[i + 1].pos;
float lenOsn = (p3 - p1).GetLength();
float lenb = (p1 - p2).GetLength();
float lenf = (p3 - p2).GetLength();
if (lenOsn > kEpsilon
&& lenf > kEpsilon
&& lenb > kEpsilon)
{
back = p2 + (p1 - p3) * (lenb / lenOsn / 3.0f);
forw = p2 + (p3 - p1) * (lenf / lenOsn / 3.0f);
}
}
ClampToDomain(back);
ClampToDomain(forw);
}
// fix tangents in relation of one to another
for (size_t i = 0; i < m_points.size(); ++i)
{
Vec2& p = m_points[i].pos;
Vec2& tanA = m_points[i].tanA;
Vec2& tanB = m_points[i].tanB;
if (i < m_points.size() - 1)
{
if (tanB.x > m_points[i + 1].tanA.x)
{
tanB.x = (m_points[i + 1].pos.x + p.x) * 0.5f;
}
}
if (i > 0)
{
if (tanA.x < m_points[i - 1].tanB.x)
{
tanA.x = (m_points[i - 1].pos.x + p.x) * 0.5f;
}
}
}
}
void CCurveEditorCtrl::UpdateProjectedPoints()
{
m_projectedPoints.resize(m_points.size() * 3 - 2);
int numPts = 0;
for (size_t i = 0; i < m_points.size(); ++i)
{
if (i == 0)
{
m_projectedPoints[numPts++] = ProjectPoint(m_points[i].pos.x, m_points[i].pos.y);
m_projectedPoints[numPts++] = ProjectPoint(m_points[i].tanB.x, m_points[i].tanB.y);
}
else if (i == m_points.size() - 1)
{
m_projectedPoints[numPts++] = ProjectPoint(m_points[i].tanA.x, m_points[i].tanA.y);
m_projectedPoints[numPts++] = ProjectPoint(m_points[i].pos.x, m_points[i].pos.y);
}
else
{
m_projectedPoints[numPts++] = ProjectPoint(m_points[i].tanA.x, m_points[i].tanA.y);
m_projectedPoints[numPts++] = ProjectPoint(m_points[i].pos.x, m_points[i].pos.y);
m_projectedPoints[numPts++] = ProjectPoint(m_points[i].tanB.x, m_points[i].tanB.y);
}
}
}
void CCurveEditorCtrl::ClampToDomain(Vec2& rVec)
{
if (rVec.x < m_domainMinX)
{
rVec.x = m_domainMinX;
}
else if (rVec.x > m_domainMaxX)
{
rVec.x = m_domainMaxX;
}
if (rVec.y < m_domainMinY)
{
rVec.y = m_domainMinY;
}
else if (rVec.y > m_domainMaxY)
{
rVec.y = m_domainMaxY;
}
}
void CCurveEditorCtrl::GenerateDefaultCurve()
{
m_points.clear();
m_domainMinX = 0.0f;
m_domainMinY = 0.0f;
m_domainMaxX = 1.0f;
m_domainMaxY = 1.0f;
m_points.push_back(CurvePoint(0.00f, 0.00f));
m_points.push_back(CurvePoint(0.25f, 0.25f));
m_points.push_back(CurvePoint(0.50f, 0.50f));
m_points.push_back(CurvePoint(0.75f, 0.75f));
m_points.push_back(CurvePoint(1.00f, 1.00f));
}
void CCurveEditorCtrl::mousePressEvent(QMouseEvent* event)
{
QWidget::mousePressEvent(event);
if (event->button() != Qt::LeftButton)
{
return;
}
const QPoint point = event->pos();
if (m_bAllowMouse)
{
bool bSimpleSelect = !(event->modifiers() & Qt::ShiftModifier) && !(event->modifiers() & Qt::ControlModifier);
if (bSimpleSelect)
{
m_selectedIndices.clear();
}
for (size_t i = 0; i < m_points.size(); ++i)
{
QPoint ptProj = ProjectPoint(m_points[i].pos.x, m_points[i].pos.y);
QRect rcHandle(0, 0, CurveEditor::kHandleSize, CurveEditor::kHandleSize);
rcHandle.moveCenter(ptProj);
if (rcHandle.contains(point))
{
if (bSimpleSelect)
{
m_selectedIndices.push_back(i);
break;
}
if (event->modifiers() & Qt::ShiftModifier)
{
m_selectedIndices.push_back(i);
}
else if (event->modifiers() & Qt::ControlModifier)
{
std::vector<int>::iterator iter =
std::find(m_selectedIndices.begin(), m_selectedIndices.end(), i);
if (iter == m_selectedIndices.end())
{
m_selectedIndices.push_back(i);
}
else
{
m_selectedIndices.erase(iter);
}
}
}
}
m_bMouseDown = true;
m_lastMousePoint = point;
}
grabMouse();
update();
}
void CCurveEditorCtrl::mouseReleaseEvent(QMouseEvent* event)
{
QWidget::mouseReleaseEvent(event);
if (event->button() != Qt::LeftButton)
{
return;
}
m_bMouseDown = false;
m_bDragging = false;
m_selectedIndices.clear();
releaseMouse();
update();
}
void CCurveEditorCtrl::mouseMoveEvent(QMouseEvent* event)
{
if (m_bMouseDown && !m_bDragging)
{
m_bDragging = true;
}
m_bHovered = true;
if (m_flags & eFlag_ShowCursorAlways)
{
m_bHovered = true;
}
else
{
m_bHovered = false;
for (size_t i = 0; i < m_points.size(); ++i)
{
QPoint ptProj = ProjectPoint(m_points[i].pos.x, m_points[i].pos.y);
QRect rcHandle(0, 0, CurveEditor::kHandleSize, CurveEditor::kHandleSize);
rcHandle.moveCenter(ptProj);
if (rcHandle.contains(event->pos()))
{
m_bHovered = true;
break;
}
}
}
if (m_bDragging)
{
Vec2 v1 = UnprojectPoint(m_lastMousePoint);
Vec2 v2 = UnprojectPoint(event->pos());
Vec2 v = v1 - v2;
for (size_t i = 0; i < m_selectedIndices.size(); ++i)
{
int index = m_selectedIndices[i];
CurvePoint& cpt = m_points[index];
// do not move first and last points on X
if (index > 0 && index < m_points.size() - 1)
{
cpt.pos.x -= v.x;
}
cpt.pos.y -= v.y;
// lets check if the point is overlapping its neighbours
if (index > 0 && (index - 1) > 0)
{
if (cpt.pos.x < m_points[index - 1].pos.x)
{
CurvePoint p = m_points[index];
// swap!
m_points[index] = m_points[index - 1];
m_points[index - 1] = p;
m_selectedIndices[i] = index - 1;
}
}
if (index < m_points.size() - 1 && (index + 1) < m_points.size() - 1)
{
if (cpt.pos.x > m_points[index + 1].pos.x)
{
CurvePoint p = m_points[index];
// swap!
m_points[index] = m_points[index + 1];
m_points[index + 1] = p;
m_selectedIndices[i] = index + 1;
}
}
ClampToDomain(cpt.pos);
}
update();
m_lastMousePoint = event->pos();
}
QWidget::mouseMoveEvent(event);
}
void CCurveEditorCtrl::MarkX(float value)
{
m_marksX.push_back(value);
}
void CCurveEditorCtrl::MarkY(float value)
{
m_marksY.push_back(value);
}
@@ -1,112 +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_EDITOR_CONTROLS_CURVEEDITORCTRL_H
#define CRYINCLUDE_EDITOR_CONTROLS_CURVEEDITORCTRL_H
#pragma once
#include "Util/GdiUtil.h"
#include <QWidget>
#include <QPen>
class CCurveEditorCtrl
: public QWidget
{
public:
enum EFlags
{
eFlag_ShowVerticalRuler = (1 << 0),
eFlag_ShowHorizontalRuler = (1 << 1),
eFlag_ShowVerticalRulerText = (1 << 2),
eFlag_ShowHorizontalRulerText = (1 << 3),
eFlag_ShowPaddingBorder = (1 << 4),
eFlag_ShowMovingPointAxis = (1 << 5),
eFlag_ShowPointHandles = (1 << 6),
eFlag_ShowCursorAlways = (1 << 7),
eFlag_Disabled = (1 << 8) // special case, when disabling preview window.
};
CCurveEditorCtrl(QWidget* parent);
virtual ~CCurveEditorCtrl();
void SetFlags(UINT aFlags);
UINT GetFlags() const;
void SetMouseEnable(bool bEnable = true) { m_bAllowMouse = bEnable; }
bool GetMouseEnable() const {return m_bAllowMouse; }
bool SetDomainBounds(float aMinX, float aMinY, float aMaxX, float aMaxY);
void GetDomainBounds(float& rMinX, float& rMinY, float& rMaxX, float& rMaxY) const;
// labelsX/labelsY must be null (to use default labels)
// or contain aHorizontalSplits+1/aVerticalSplits+1 items.
void SetGrid(UINT aHorizontalSplits, UINT aVerticalSplits, const QStringList& labelsX = QStringList(), const QStringList& labelsY = QStringList());
void SetPadding(float padding) { m_padding = padding; }
void MarkX(float value);
void MarkY(float value);
void AddControlPoint(const Vec2& rPosition);
void ClearControlPoints();
void SetControlPointCount(UINT aCount);
UINT GetControlPointCount() const;
void SetControlPoint(UINT aIndex, const Vec2& rPosition);
void SetControlPointTangents(UINT aIndex, const Vec2& rLeft, const Vec2& rRight);
void GetControlPoint(UINT aIndex, Vec2& rOutPosition) const;
void GetControlPointTangents(UINT aIndex, Vec2& rOutLeft, Vec2& rOutRight) const;
QPoint ProjectPoint(float x, float y);
Vec2 UnprojectPoint(const QPoint& pt);
void UpdateProjectedPoints();
protected:
struct CurvePoint
{
CurvePoint(float aX = 0.0f, float aY = 0.0f)
{
pos.x = aX;
pos.y = aY;
}
Vec2 pos;
Vec2 tanA, tanB;
};
void ComputeTangents();
void ClampToDomain(Vec2& rVec);
void GenerateDefaultCurve();
void paintEvent(QPaintEvent* event) override;
std::vector<CurvePoint> m_points;
std::vector<QPoint> m_projectedPoints;
float m_domainMinX;
float m_domainMinY;
float m_domainMaxX;
float m_domainMaxY;
Vec2 m_gridSplits;
int m_padding;
bool m_bMouseDown, m_bDragging, m_bAllowMouse;
bool m_bHovered;
QPoint m_lastMousePoint;
std::vector<int> m_selectedIndices;
QFont m_fntInfo;
QPen m_pen, m_selCrossPen;
UINT m_flags;
QStringList m_labelsX;
QStringList m_labelsY;
std::vector<float> m_marksX;
std::vector<float> m_marksY;
void mousePressEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override;
};
#endif // CRYINCLUDE_EDITOR_CONTROLS_CURVEEDITORCTRL_H
-10
View File
@@ -85,7 +85,6 @@ AZ_POP_DISABLE_WARNING
// Editor
#include "Settings.h"
#include "Include/IBackgroundScheduleManager.h"
#include "GameExporter.h"
#include "GameResourcesExporter.h"
@@ -2314,15 +2313,6 @@ int CCryEditApp::IdleProcessing(bool bBackgroundUpdate)
#endif
}
// process the work schedule - regardless if the app is active or not
GetIEditor()->GetBackgroundScheduleManager()->Update();
// if there are active schedules keep updating the application
if (GetIEditor()->GetBackgroundScheduleManager()->GetNumSchedules() > 0)
{
bActive = true;
}
m_bPrevActive = bActive;
AZStd::chrono::system_clock::time_point now = AZStd::chrono::system_clock::now();
-21
View File
@@ -420,7 +420,6 @@ AZ::Outcome<void, AZStd::string> CGameEngine::Init(
#else
sip.hWnd = hwndForInputSystem;
#endif
sip.hWndForInputSystem = hwndForInputSystem;
sip.pLogCallback = &m_logFile;
sip.sLogFileName = "@log@/Editor.log";
@@ -503,7 +502,6 @@ AZ::Outcome<void, AZStd::string> CGameEngine::Init(
bool CGameEngine::InitGame(const char*)
{
// in editor we do it later, bExecuteCommandLine was set to false
m_pISystem->ExecuteCommandLine();
return true;
@@ -608,8 +606,6 @@ void CGameEngine::SwitchToInGame()
GetIEditor()->Notify(eNotify_OnBeginGameMode);
m_pISystem->SetThreadState(ESubsys_Physics, false);
m_pISystem->GetIMovieSystem()->EnablePhysicsEvents(true);
m_bInGameMode = true;
@@ -646,8 +642,6 @@ void CGameEngine::SwitchToInEditor()
}
m_pISystem->GetIMovieSystem()->Reset(false, false);
m_pISystem->SetThreadState(ESubsys_Physics, false);
CViewport* pGameViewport = GetIEditor()->GetViewManager()->GetGameViewport();
m_pISystem->GetIMovieSystem()->EnablePhysicsEvents(m_bSimulationMode);
@@ -791,8 +785,6 @@ void CGameEngine::SetSimulationMode(bool enabled, bool bOnlyPhysics)
// Enables engine to know about simulation mode.
gEnv->SetIsEditorSimulationMode(enabled);
m_pISystem->SetThreadState(ESubsys_Physics, false);
if (m_bSimulationMode)
{
// [Anton] the order of the next 3 calls changed, since, EVENT_INGAME loads physics state (if any),
@@ -903,19 +895,6 @@ void CGameEngine::Update()
// [marco] check current sound and vis areas for music etc.
// but if in game mode, 'cos is already done in the above call to game->update()
unsigned int updateFlags = ESYSUPDATE_EDITOR;
if (!m_bSimulationMode)
{
updateFlags |= ESYSUPDATE_IGNORE_PHYSICS;
}
bool bUpdateAIPhysics = GetSimulationMode();
if (bUpdateAIPhysics)
{
updateFlags |= ESYSUPDATE_EDITOR_AI_PHYSICS;
}
GetIEditor()->GetAnimation()->Update();
GetIEditor()->GetSystem()->UpdatePreTickBus(updateFlags);
componentApplication->Tick(gEnv->pTimer->GetFrameTime(ITimer::ETIMER_GAME));
-2
View File
@@ -550,7 +550,6 @@ struct IEditor
virtual class CViewManager* GetViewManager() = 0;
virtual class CViewport* GetActiveView() = 0;
virtual void SetActiveView(CViewport* viewport) = 0;
virtual struct IBackgroundTaskManager* GetBackgroundTaskManager() = 0;
virtual struct IEditorFileMonitor* GetFileMonitor() = 0;
// These are needed for Qt integration:
@@ -720,7 +719,6 @@ struct IEditor
virtual ESystemConfigPlatform GetEditorConfigPlatform() const = 0;
virtual void ReloadTemplates() = 0;
virtual IResourceSelectorHost* GetResourceSelectorHost() = 0;
virtual struct IBackgroundScheduleManager* GetBackgroundScheduleManager() = 0;
virtual void ShowStatusText(bool bEnable) = 0;
// Provides a way to extend the context menu of an object. The function gets called every time the menu is opened.
-17
View File
@@ -66,12 +66,9 @@ AZ_POP_DISABLE_WARNING
#include "Objects/SelectionGroup.h"
#include "Objects/ObjectManager.h"
#include "BackgroundTaskManager.h"
#include "BackgroundScheduleManager.h"
#include "EditorFileMonitor.h"
#include "MainStatusBar.h"
#include "SettingsBlock.h"
#include "ResourceSelectorHost.h"
#include "Util/FileUtil_impl.h"
#include "Util/ImageUtil_impl.h"
@@ -177,8 +174,6 @@ CEditorImpl::CEditorImpl()
regCtx.pCommandManager = m_pCommandManager;
regCtx.pClassFactory = m_pClassFactory;
m_pEditorFileMonitor.reset(new CEditorFileMonitor());
m_pBackgroundTaskManager.reset(new BackgroundTaskManager::CTaskManager);
m_pBackgroundScheduleManager.reset(new BackgroundScheduleManager::CScheduleManager);
m_pUIEnumsDatabase = new CUIEnumsDatabase;
m_pDisplaySettings = new CDisplaySettings;
m_pDisplaySettings->LoadRegistry();
@@ -844,16 +839,6 @@ IIconManager* CEditorImpl::GetIconManager()
return m_pIconManager;
}
IBackgroundTaskManager* CEditorImpl::GetBackgroundTaskManager()
{
return m_pBackgroundTaskManager.get();
}
IBackgroundScheduleManager* CEditorImpl::GetBackgroundScheduleManager()
{
return m_pBackgroundScheduleManager.get();
}
IEditorFileMonitor* CEditorImpl::GetFileMonitor()
{
return m_pEditorFileMonitor.get();
@@ -1624,8 +1609,6 @@ ESystemConfigPlatform CEditorImpl::GetEditorConfigPlatform() const
void CEditorImpl::InitFinished()
{
SProjectSettingsBlock::Load();
if (!m_bInitialized)
{
m_bInitialized = true;
-17
View File
@@ -43,15 +43,12 @@ class CGameEngine;
class CExportManager;
class CErrorsDlg;
class CIconManager;
class CBackgroundTaskManager;
class CTrackViewSequenceManager;
class CEditorFileMonitor;
class AzAssetWindow;
class AzAssetBrowserRequestHandler;
class AssetEditorRequestsHandler;
class CAlembicCompiler;
struct IBackgroundTaskManager;
struct IBackgroundScheduleManager;
struct IEditorFileMonitor;
class CVegetationMap;
@@ -61,16 +58,6 @@ namespace Editor
class EditorQtApplication;
}
namespace BackgroundScheduleManager
{
class CScheduleManager;
}
namespace BackgroundTaskManager
{
class CTaskManager;
}
namespace WinWidget
{
class WinWidgetManager;
@@ -179,8 +166,6 @@ public:
IDataBaseManager* GetDBItemManager(EDataBaseItemType itemType);
CMusicManager* GetMusicManager() { return m_pMusicManager; };
IBackgroundTaskManager* GetBackgroundTaskManager() override;
IBackgroundScheduleManager* GetBackgroundScheduleManager() override;
IEditorFileMonitor* GetFileMonitor() override;
void RegisterEventLoopHook(IEventLoopHook* pHook) override;
void UnregisterEventLoopHook(IEventLoopHook* pHook) override;
@@ -394,8 +379,6 @@ protected:
//! Export manager for exporting objects and a terrain from the game to DCC tools
CExportManager* m_pExportManager;
std::unique_ptr<BackgroundTaskManager::CTaskManager> m_pBackgroundTaskManager;
std::unique_ptr<BackgroundScheduleManager::CScheduleManager> m_pBackgroundScheduleManager;
std::unique_ptr<CEditorFileMonitor> m_pEditorFileMonitor;
std::unique_ptr<IResourceSelectorHost> m_pResourceSelectorHost;
QString m_selectFileBuffer;
@@ -1,207 +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.
//
// IBackgroundScheduleManager manages schedule of group of larger operations that should be run in sequence
//
// Schedules are derived from IBackgroundSchedule and consist of a list of IBackgroundScheduleItems.
// Each schedule item is executed IN ORDER for the previous item to complete first.
// Each IBackgroundScheduleItems consists of list of user defined work via IBackgroundScheduleItemsWork classes.
// Each schedule item work is executed IN PARALEL (they are all started when the item starts).
//
// Whenever a work item fails to complete the other work items are stopped, the schedule item is marked as "failed"
// and so is the whole schedule.
//
// All logic is performed on the main thread although schedule items are free to use threads.
// It is recommended to use IBackgroundTaskManager for dispatching a task list for every schedule work item.
//
// All objects in the schedule system are reference counted.
//
// State of the whole schedule
#ifndef CRYINCLUDE_EDITOR_INCLUDE_IBACKGROUNDSCHEDULEMANAGER_H
#define CRYINCLUDE_EDITOR_INCLUDE_IBACKGROUNDSCHEDULEMANAGER_H
#pragma once
enum EScheduleState
{
// Item has not started yet but is on the list
eScheduleState_Pending,
// We are processing this item
eScheduleState_Processing,
// We are stopping the schedule
eSccheduleState_Stopping,
// Schedule item has failed
eScheduleState_Failed,
// Schedule item was canceled
eScheduleState_Canceled,
// Schedule item has completed it's work
eScheduleState_Completed,
};
// State of the single schedule item
enum EScheduleItemState
{
// Item has not started yet but is on the list
eScheduleItemState_Pending,
// We are processing this item
eScheduleItemState_Processing,
// We are stopping this item
eScheduleItemState_Stopping,
// Schedule item has failed
eScheduleItemState_Failed,
// Schedule item has completed it's work
eScheduleItemState_Completed,
};
// Work item status
enum EScheduleWorkItemStatus
{
// Work is still not finished
eScheduleWorkItemStatus_NotFinished,
// Work has failed
eScheduleWorkItemStatus_Failed,
// Work has finished
eScheduleWorkItemStatus_Finished,
};
struct IBackgroundScheduleItemWork
{
// Get human readable description
virtual const char* GetDescription() const = 0;
// Get work item progress
virtual float GetProgress() const = 0;
// Called when the schedule item containing this work piece has started
// If the work cannot be started for any reason return false.
virtual bool OnStart() = 0;
// Called when the schedule item containing this work piece has been canceled or failed externally
// Not called when schedule item completed without errors.
// If the work cannot be stopped this frame return false.
virtual bool OnStop() = 0;
// Called every frame to advance and check the work state
// Should return one of the EBackgroundScheduleWorkItemStatus value
virtual EScheduleWorkItemStatus OnUpdate() = 0;
// Reference counting
virtual void AddRef() = 0;
virtual void Release() = 0;
protected:
virtual ~IBackgroundScheduleItemWork() {};
};
struct IBackgroundScheduleItem
{
// Get name of the schedule (debug & display)
virtual const char* GetDescription() const = 0;
// Get interal state
virtual EScheduleItemState GetState() const = 0;
// Get overall progress of this schedule item
virtual const float GetProgress() const = 0;
// Get number of work items in this schedule item
virtual const uint32 GetNumWorkItems() const = 0;
// Get n-th work item from the schedule item
virtual IBackgroundScheduleItemWork* GetWorkItem(const uint32 index) const = 0;
// Add work item to the schedule item
virtual void AddWorkItem(IBackgroundScheduleItemWork* pWork) = 0;
// Reference counting
virtual void AddRef() = 0;
virtual void Release() = 0;
protected:
virtual ~IBackgroundScheduleItem() {};
};
struct IBackgroundSchedule
{
// Get name of the schedule (debug & display)
virtual const char* GetDescription() const = 0;
// Get overall progress of the whole schedule
virtual float GetProgress() const = 0;
// Get item being currently processed
virtual IBackgroundScheduleItem* GetProcessedItem() const = 0;
// Get number of items in the schedule
virtual const uint32 GetNumItems() const = 0;
// Get single schedule item
virtual IBackgroundScheduleItem* GetItem(const uint32 index) const = 0;
// Get schedule item
virtual EScheduleState GetState() const = 0;
// Cancel the whole schedule
virtual void Cancel() = 0;
// Is the schedule canceled ?
virtual bool IsCanceled() const = 0;
// Add schedule item at the end of the list
virtual void AddItem(IBackgroundScheduleItem* pItem) = 0;
// Reference counting
virtual void AddRef() = 0;
virtual void Release() = 0;
protected:
virtual ~IBackgroundSchedule() {};
};
struct IBackgroundScheduleManager
{
virtual ~IBackgroundScheduleManager() {};
// Create empty schedule
virtual IBackgroundSchedule* CreateSchedule(const char* szName) = 0;
// Create empty schedule item
virtual IBackgroundScheduleItem* CreateScheduleItem(const char* szName) = 0;
// Issue a schedule to the list (will start processing it)
virtual void SubmitSchedule(IBackgroundSchedule* pSchedule) = 0;
// Get number of schedules on the list
virtual const uint32 GetNumSchedules() const = 0;
// Get n-th schedule
virtual IBackgroundSchedule* GetSchedule(const uint32 index) const = 0;
// Advance work on the schedules
virtual void Update() = 0;
};
#endif // CRYINCLUDE_EDITOR_INCLUDE_IBACKGROUNDSCHEDULEMANAGER_H
@@ -1,230 +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.
//
// IBackgroundTaskManager runs background tasks in worker thread.
//
// Tasks are derived from IBackgroundTask. Each task is split in two parts for:
// Work - done in background thread.
// Finalize - called afterward in main thread to apply results.
//
// Task objects are reference counted. Task manager will hold its own reference to the task object
// for as long as the task is pending or being executed. If you want to keep the task object around
// in your code you will have to call AddRef() and Release() on the task object by yourself so there
// will be an extra reference to the task object held by your code.
//
// Work returns the state of the task. Task can be resumed, then the Work
// method will be called again. Other tasks can work between calls to Work.
// It is possible to Cancel task. Work method is not invoked any more for
// Canceled tasks.
//
#ifndef CRYINCLUDE_EDITOR_INCLUDE_IBACKGROUNDTASKMANAGER_H
#define CRYINCLUDE_EDITOR_INCLUDE_IBACKGROUNDTASKMANAGER_H
#pragma once
enum ETaskPriority
{
eTaskPriority_FileUpdateFinal,
eTaskPriority_BackgroundScan,
eTaskPriority_FileUpdate,
eTaskPriority_RealtimePreview
};
// Result code returned by task Work() function
enum ETaskResult
{
// Task has not yet completed, add it back to the task queue with the same parameters (priority and thread mask)
eTaskResult_Resume,
// Task has completed without errors (it's assumed that the result the task was supposed to achieve was achieved)
eTaskResult_Completed,
// Task was canceled
eTaskResult_Canceled,
// Task has failed to complete it's work
eTaskResult_Failed,
};
// Internal task tracking state
enum ETaskState
{
// Task was just created.
eTaskState_Created,
// Task was scheduled to be executed in the future.
eTaskState_Scheduled,
// Task was added to the task queue and is waiting for it's time to be executed.
eTaskState_Pending,
// Task is being processed right now.
eTaskState_Working,
// Task was canceled before it has finished (indication that TaskManager has seen the Cancel() call).
eTaskState_Canceled,
// Task Work() function was called but it ended with an error code.
eTaskState_Failed,
// Task has completed it's Work() function without errors.
eTaskState_Completed,
};
// Thread mask controls which on which threads given task can be executed.
enum ETaskThreadMask
{
// Task can run only on the IO thread (default)
// There is only one IO thread so all task with this flag are run in a sequence.
eTaskThreadMask_IO,
// Task can run on any thread (concurrent tasks allowed)
// There can be many threads with this mask so there's no limit on the concurrent task count.
eTaskThreadMask_Any,
eTaskThreadMask_COUNT,
};
struct IBackgroundTask
{
public:
IBackgroundTask()
: m_bCanceled(false)
, m_state(eTaskState_Created)
, m_progress(-1.0f)
, m_refCount(0)
, m_bFailReported(false)
{}
void Cancel()
{
m_bCanceled = true;
}
bool IsCanceled() const
{
return m_bCanceled;
}
bool HasFinished() const
{
return (m_state == eTaskState_Canceled) ||
(m_state == eTaskState_Completed) ||
(m_state == eTaskState_Failed);
}
bool HasFinishedWithoutError() const
{
return (m_state == eTaskState_Completed);
}
ETaskState GetState() const
{
return m_state;
}
void SetState(ETaskState state)
{
m_state = state;
}
float GetProgress() const
{
return m_progress;
}
int AddRef()
{
return CryInterlockedIncrement(&m_refCount);
}
int Release()
{
const int nCount = CryInterlockedDecrement(&m_refCount);
assert(nCount >= 0);
if (nCount == 0)
{
Delete();
}
else if (nCount < 0)
{
assert(0);
CryFatalError("Deleting Reference Counted Object Twice");
}
return nCount;
}
bool FailReported() const{ return m_bFailReported; }
// Get the user readable description (name) of this task, used for logging
virtual const char* Description() const { return ""; }
// Get the user readable error message (in case when the task fails), used for logging the errors
virtual const char* ErrorMessage() const { return ""; }
// Called from main thread after task is completed just before the task gets destroyed
virtual void Finalize() {}
// Since there's a possibility that task object were created using different allocator
// we need a way to delete the task object once we are done with it
virtual void Delete() = 0;
// Invoked from worker thread, actual work is done here
virtual ETaskResult Work() = 0;
protected:
void SetProgress(float progress) { m_progress = progress; }
void SetFailReported() { m_bFailReported = true; }
// destructor is hidden to indicate that we should use Release() method
virtual ~IBackgroundTask() {}
private:
volatile int m_refCount;
ETaskState m_state;
float m_progress;
bool m_bCanceled;
bool m_bFailReported;
};
struct IBackgroundTaskManagerListener
{
virtual ~IBackgroundTaskManagerListener() {}
virtual void OnBackgroundTaskAdded(const char* description) = 0;
virtual void OnBackgroundTaskCompleted(ETaskResult taskResult, const char* description) = 0;
};
struct IBackgroundTaskManager
{
enum
{
BACKGROUND_TASK_ID_INVALID = 0
};
virtual ~IBackgroundTaskManager() {}
// Add task to the queue with given priority and thread mask
virtual void AddTask(IBackgroundTask* pTask, ETaskPriority priority, ETaskThreadMask threadMask) = 0;
// Schedule task to be executed in the future
virtual void ScheduleTask(IBackgroundTask* pTask, ETaskPriority priority, int delayMilliseconds, ETaskThreadMask threadMask) = 0;
virtual void AddListener(IBackgroundTaskManagerListener* pListener, const char* name) = 0;
virtual void RemoveListener(IBackgroundTaskManagerListener* pListener) = 0;
};
#endif // CRYINCLUDE_EDITOR_INCLUDE_IBACKGROUNDTASKMANAGER_H
@@ -28,16 +28,6 @@
// }
// REGISTER_RESOURCE_SELECTOR("Sound", SoundFileSelector, "Icons/sound_16x16.png")
//
// To expose it to serialization:
//
// #include "Serialization/Decorators/Resources.h"
// template<class TString>
// ResourceSelector<TString> SoundName(TString& s) { return ResourceSelector<TString>(s, "Sound"); }
//
// To use in serialization:
//
// ar(Serialization::SoundName(soundString), "soundString", "Sound String");
//
// Here is how it can be invoked directly:
//
// SResourceSelectorContext x;
@@ -56,19 +46,7 @@
//
// QString SoundFileSelector(const SResourceSelectorContext& x, const QString& previousValue,
// SoundFileList* list) // your context argument
//
// And provide this value through serialization context:
//
// struct SourceFileList
// {
// void Serialize(IArchive& ar)
// {
// Serialization::SContext<SourceFileList> context(ar, this);
// ...
// }
// }
#include <Serialization/TypeID.h>
#include <QString>
class QWidget;
@@ -82,7 +60,6 @@ struct SResourceSelectorContext
unsigned int entityId;
void* contextObject;
Serialization::TypeID contextObjectType;
SResourceSelectorContext()
: parentWidget(0)
@@ -107,7 +84,6 @@ struct IResourceSelectorHost
virtual ~IResourceSelectorHost() = default;
virtual QString SelectResource(const SResourceSelectorContext& context, const QString& previousValue) = 0;
virtual const char* ResourceIconPath(const char* typeName) const = 0;
virtual Serialization::TypeID ResourceContextType(const char* typeName) const = 0;
virtual void RegisterResourceSelector(const SStaticResourceSelectorEntry* entry) = 0;
@@ -128,7 +104,6 @@ struct SStaticResourceSelectorEntry
TResourceSelectionFunction function;
TResourceSelectionFunctionWithContext functionWithContext;
const char* iconPath;
Serialization::TypeID contextType;
static SStaticResourceSelectorEntry*& GetFirst() { static SStaticResourceSelectorEntry* first; return first; }
SStaticResourceSelectorEntry* next;
@@ -150,7 +125,6 @@ struct SStaticResourceSelectorEntry
, functionWithContext(TResourceSelectionFunctionWithContext(function))
, iconPath(icon)
{
contextType = Serialization::TypeID::get<T>();
next = GetFirst();
GetFirst() = this;
}
-4
View File
@@ -97,10 +97,6 @@ void CLevelInfo::ValidateObjects()
pObject->Validate(m_pReport);
CUsedResources rs;
pObject->GatherUsedResources(rs);
rs.Validate(m_pReport);
m_pReport->SetCurrentValidatorObject(NULL);
}
@@ -102,7 +102,6 @@ public:
MOCK_METHOD0(GetViewManager, class CViewManager* ());
MOCK_METHOD0(GetActiveView, class CViewport* ());
MOCK_METHOD1(SetActiveView, void(CViewport*));
MOCK_METHOD0(GetBackgroundTaskManager, struct IBackgroundTaskManager* ());
MOCK_METHOD0(GetFileMonitor, struct IEditorFileMonitor* ());
MOCK_METHOD1(RegisterEventLoopHook, void(IEventLoopHook* ));
MOCK_METHOD1(UnregisterEventLoopHook, void(IEventLoopHook* ));
@@ -184,7 +183,6 @@ public:
MOCK_CONST_METHOD0(GetEditorConfigPlatform, ESystemConfigPlatform());
MOCK_METHOD0(ReloadTemplates, void());
MOCK_METHOD0(GetResourceSelectorHost, IResourceSelectorHost* ());
MOCK_METHOD0(GetBackgroundScheduleManager, struct IBackgroundScheduleManager* ());
MOCK_METHOD1(ShowStatusText, void(bool ));
MOCK_METHOD1(RegisterObjectContextMenuExtension, void(TContextMenuExtensionFunc ));
MOCK_METHOD0(GetEnv, SSystemGlobalEnvironment* ());
-1
View File
@@ -13,7 +13,6 @@
#pragma once
#include <MainStatusBar.h>
#include <IBackgroundTaskManager.h>
#include <IRenderer.h>
#include <QMutex>
#include <QString>
-140
View File
@@ -92,7 +92,6 @@ AZ_POP_DISABLE_WARNING
#include "ErrorReportDialog.h"
#include "Dialogs/PythonScriptsDialog.h"
#include "EngineSettingsManager.h"
#include "AzAssetBrowser/AzAssetBrowserWindow.h"
#include "AssetEditor/AssetEditorWindow.h"
@@ -695,8 +694,6 @@ void MainWindow::InitActions()
am->AddAction(ID_TOOLBAR_WIDGET_REDO, QString());
am->AddAction(ID_TOOLBAR_WIDGET_SNAP_ANGLE, QString());
am->AddAction(ID_TOOLBAR_WIDGET_SNAP_GRID, QString());
am->AddAction(ID_TOOLBAR_WIDGET_ENVIRONMENT_MODE, QString());
am->AddAction(ID_TOOLBAR_WIDGET_DEBUG_MODE, QString());
am->AddAction(ID_TOOLBAR_WIDGET_SPACER_RIGHT, QString());
// File actions
@@ -1253,44 +1250,6 @@ QToolButton* MainWindow::CreateUndoRedoButton(int command)
return button;
}
QToolButton* MainWindow::CreateEnvironmentModeButton()
{
QToolButton* environmentModeButton = new QToolButton(this);
environmentModeButton->setAutoRaise(true);
environmentModeButton->setPopupMode(QToolButton::InstantPopup);
environmentModeButton->setIcon(Style::icon("Environment"));
environmentModeButton->setStatusTip(tr("Select from a variety of environment mode options"));
environmentModeButton->setToolTip(tr("Environment modes"));
CVarMenu* environmentModeMenu = new CVarMenu(this);
connect(environmentModeMenu, &QMenu::aboutToShow, [this, environmentModeMenu]()
{
InitEnvironmentModeMenu(environmentModeMenu);
});
environmentModeButton->setMenu(environmentModeMenu);
return environmentModeButton;
}
QToolButton* MainWindow::CreateDebugModeButton()
{
QToolButton* debugModeButton = new QToolButton(this);
debugModeButton->setAutoRaise(true);
debugModeButton->setPopupMode(QToolButton::InstantPopup);
debugModeButton->setIcon(Style::icon("Debugging"));
debugModeButton->setStatusTip(tr("Select from a variety of debug/view mode options"));
debugModeButton->setToolTip(tr("Debug modes"));
CVarMenu* debugModeMenu = new CVarMenu(this);
connect(debugModeMenu, &QMenu::aboutToShow, [this, debugModeMenu]()
{
InitDebugModeMenu(debugModeMenu);
});
debugModeButton->setMenu(debugModeMenu);
return debugModeButton;
}
QWidget* MainWindow::CreateSpacerRightWidget()
{
QWidget* spacer = new QWidget(this);
@@ -1299,93 +1258,6 @@ QWidget* MainWindow::CreateSpacerRightWidget()
return spacer;
}
void MainWindow::InitEnvironmentModeMenu(CVarMenu* environmentModeMenu)
{
environmentModeMenu->clear();
environmentModeMenu->AddCVarToggleItem({ "e_Fog", tr("Hide Global Fog"), 0, 1 });
environmentModeMenu->AddCVarToggleItem({ "r_FogVolumes", tr("Hide Fog Volumes"), 0, 1 });
environmentModeMenu->AddCVarToggleItem({ "e_Clouds", tr("Hide Clouds"), 0, 1 });
environmentModeMenu->AddCVarToggleItem({ "e_Wind", tr("Hide Wind"), 0, 1 });
environmentModeMenu->AddSeparator();
environmentModeMenu->AddCVarToggleItem({ "e_Sun", tr("Hide Sun"), 0, 1 });
environmentModeMenu->AddCVarToggleItem({ "e_Skybox", tr("Hide Skybox"), 0, 1 });
environmentModeMenu->AddCVarToggleItem({ "r_SSReflections", tr("Hide Screen Space Reflection"), 0, 1 });
environmentModeMenu->AddCVarToggleItem({ "e_Shadows", tr("Hide Shadows"), 0, 1 });
environmentModeMenu->AddCVarToggleItem({ "r_TransparentPasses", tr("Hide Transparent Objects"), 0, 1 });
environmentModeMenu->AddCVarToggleItem({ "r_ssdo", tr("Hide Screen Space Directional Occlusion"), 0, 1 });
environmentModeMenu->AddCVarToggleItem({ "e_DynamicLights", tr("Hide All Dynamic Lights"), 0, 1 });
environmentModeMenu->AddSeparator();
environmentModeMenu->AddCVarToggleItem({ "e_Entities", tr("Hide Entities"), 0, 1 });
environmentModeMenu->AddSeparator();
environmentModeMenu->AddCVarToggleItem({ "e_Vegetation", tr("Hide Vegetation"), 0, 1 });
environmentModeMenu->AddCVarToggleItem({ "e_Terrain", tr("Hide Terrain"), 0, 1 });
environmentModeMenu->AddSeparator();
environmentModeMenu->AddCVarToggleItem({ "e_Particles", tr("Hide Particles"), 0, 1 });
environmentModeMenu->AddCVarToggleItem({ "e_Flares", tr("Hide Flares"), 0, 1 });
environmentModeMenu->AddCVarToggleItem({ "e_Decals", tr("Hide Decals"), 0, 1 });
environmentModeMenu->AddSeparator();
environmentModeMenu->AddCVarToggleItem({ "e_WaterOcean", tr("Hide Ocean Water (for legacy)"), 0, 1 });
environmentModeMenu->AddCVarToggleItem({ "e_WaterVolumes", tr("Hide Water Volumes"), 0, 1 });
environmentModeMenu->AddSeparator();
environmentModeMenu->AddCVarToggleItem({ "e_BBoxes", tr("Hide BBoxes"), 0, 1 });
environmentModeMenu->AddSeparator();
environmentModeMenu->AddResetCVarsItem();
}
void MainWindow::InitDebugModeMenu(CVarMenu* debugModeMenu)
{
debugModeMenu->clear();
debugModeMenu->AddCVarValuesItem("r_DebugGBuffer", tr("GBuffers"),
{
{tr("Full Shading Mode (Default)"), 0},
{tr("Normal Visualization"), 1},
{tr("Smoothness"), 2},
{tr("Reflectance"), 3},
{tr("Albedo"), 4},
{tr("Lighting Model"), 5},
{tr("Translucency"), 6},
{tr("Sun Self Shadowing"), 7},
{tr("Subsurface Scattering"), 8},
{tr("Specular Validation Overlay"), 9}
}, 0);
debugModeMenu->AddSeparator();
debugModeMenu->AddCVarValuesItem("r_Stats", tr("Profiling"),
{
{tr("Frame Timing"), 1},
{tr("Object Timing"), 3},
{tr("Instance Draw Calls"), 6},
}, 0);
debugModeMenu->AddSeparator();
debugModeMenu->AddUniqueCVarsItem(tr("Wireframe"),
{
{"r_wireframe", tr("Wireframe Rendering Mode"), 1, 0},
{"r_showlines", tr("Wireframe Overlay"), 1, 0}
}),
debugModeMenu->AddCVarValuesItem("e_debugdraw", tr("Art Info"),
{
{tr("Texture Memory Usage"), 4},
{tr("Renderable Material Count"), 5},
{tr("LOD Vertex Count"), 22}
}, 0);
debugModeMenu->AddSeparator();
debugModeMenu->AddCVarValuesItem("e_defaultmaterial", tr("Default Material on all Objects"),
{
{tr("Gray Material with Normal Maps"), 1},
}, 0);
debugModeMenu->AddCVarValuesItem("r_DeferredShadingTiledDebugAlbedo", tr("Debug Visualization of Deferred Lighting"),
{
{tr("White Albedo"), 1},
}, 0);
debugModeMenu->AddCVarToggleItem({ "r_ShowTangents", tr("Show Tangents"), 1, 0 });
debugModeMenu->AddCVarToggleItem({ "p_draw_helpers", tr("Show Collision Shapes (Proxy)"), 1, 0 });
debugModeMenu->AddSeparator();
debugModeMenu->AddResetCVarsItem();
}
UndoRedoToolButton::UndoRedoToolButton(QWidget* parent)
: QToolButton(parent)
{
@@ -2068,12 +1940,6 @@ void MainWindow::ConnectivityStateChanged(const AzToolsFramework::SourceControlS
}
}
#if defined(CRY_ENABLE_RC_HELPER)
CEngineSettingsManager settingsManager;
settingsManager.SetModuleSpecificBoolEntry("RC_EnableSourceControl", connected);
settingsManager.StoreData();
#endif
gSettings.enableSourceControl = connected;
gSettings.SaveEnableSourceControlFlag(false);
}
@@ -2150,12 +2016,6 @@ QWidget* MainWindow::CreateToolbarWidget(int actionId)
case ID_TOOLBAR_WIDGET_SNAP_ANGLE:
w = CreateSnapToAngleWidget();
break;
case ID_TOOLBAR_WIDGET_ENVIRONMENT_MODE:
w = CreateEnvironmentModeButton();
break;
case ID_TOOLBAR_WIDGET_DEBUG_MODE:
w = CreateDebugModeButton();
break;
case ID_TOOLBAR_WIDGET_SPACER_RIGHT:
w = CreateSpacerRightWidget();
break;
-5
View File
@@ -208,11 +208,6 @@ private:
QToolButton* CreateUndoRedoButton(int command);
QToolButton* CreateEnvironmentModeButton();
QToolButton* CreateDebugModeButton();
void InitEnvironmentModeMenu(CVarMenu* environmentModeMenu);
void InitDebugModeMenu(CVarMenu* debugModeMenu);
private Q_SLOTS:
void ShowKeyboardCustomization();
void ExportKeyboardShortcuts();
@@ -35,7 +35,6 @@
class CEntityObject;
class QMenu;
class IOpticsElementBase;
/*!
* CEntityEventTarget is an Entity event target and type.
@@ -72,16 +72,6 @@ public:
return "";
}
Serialization::TypeID ResourceContextType(const char* typeName) const override
{
TTypeMap::const_iterator it = m_typeMap.find(typeName);
if (it != m_typeMap.end())
{
return it->second->contextType;
}
return Serialization::TypeID();
}
void RegisterResourceSelector(const SStaticResourceSelectorEntry* entry) override
{
m_typeMap[entry->typeName] = entry;
-26
View File
@@ -1,26 +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_EDITOR_SERIALIZATION_H
#define CRYINCLUDE_EDITOR_SERIALIZATION_H
#include <Serialization/STL.h>
#include <Serialization/SmartPtr.h>
#include <Serialization/ClassFactory.h>
#include <Serialization/IArchive.h>
#include <Serialization/Enum.h>
using Serialization::IArchive;
#endif // CRYINCLUDE_EDITOR_SERIALIZATION_H
@@ -1,283 +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 "EditorDefs.h"
#include "VariableIArchive.h"
// Editor
#include "Serialization/Decorators/Resources.h"
#include "Serialization/Decorators/Range.h"
using Serialization::CVariableIArchive;
namespace VarUtil
{
_smart_ptr< IVariable > FindChildVariable(const _smart_ptr< IVariable >& pParent, const int childIndexOverride, const char* const name)
{
if (0 <= childIndexOverride)
{
return pParent->GetVariable(childIndexOverride);
}
else
{
const bool shouldSearchRecursively = false;
return pParent->FindVariable(name, shouldSearchRecursively);
}
}
template< typename T, typename TOut >
bool ReadChildVariableAs(const _smart_ptr< IVariable >& pParent, const int childIndexOverride, const char* const name, TOut& valueOut)
{
_smart_ptr< IVariable > pVariable = FindChildVariable(pParent, childIndexOverride, name);
if (pVariable)
{
T tmp;
pVariable->Get(tmp);
valueOut = static_cast< TOut >(tmp);
return true;
}
return false;
}
template< typename T >
bool ReadChildVariable(const _smart_ptr< IVariable >& pParent, const int childIndexOverride, const char* const name, T& valueOut)
{
return ReadChildVariableAs< T >(pParent, childIndexOverride, name, valueOut);
}
}
CVariableIArchive::CVariableIArchive(const _smart_ptr< IVariable >& pVariable)
: IArchive(IArchive::INPUT | IArchive::EDIT | IArchive::NO_EMPTY_NAMES)
, m_pVariable(pVariable)
, m_childIndexOverride(-1)
{
CRY_ASSERT(m_pVariable);
m_structHandlers[ TypeID::get < Serialization::IResourceSelector > ().name() ] = &CVariableIArchive::SerializeResourceSelector;
m_structHandlers[ TypeID::get < Serialization::RangeDecorator < float >> ().name() ] = &CVariableIArchive::SerializeRangeFloat;
m_structHandlers[ TypeID::get < Serialization::RangeDecorator < int >> ().name() ] = &CVariableIArchive::SerializeRangeInt;
m_structHandlers[ TypeID::get < Serialization::RangeDecorator < unsigned int >> ().name() ] = &CVariableIArchive::SerializeRangeUInt;
m_structHandlers[ TypeID::get < StringListStaticValue > ().name() ] = &CVariableIArchive::SerializeStringListStaticValue;
}
CVariableIArchive::~CVariableIArchive()
{
}
bool CVariableIArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label)
{
return VarUtil::ReadChildVariableAs< bool >(m_pVariable, m_childIndexOverride, name, value);
}
bool CVariableIArchive::operator()(Serialization::IString& value, const char* name, [[maybe_unused]] const char* label)
{
QString stringValue;
const bool readSuccess = VarUtil::ReadChildVariableAs< QString >(m_pVariable, m_childIndexOverride, name, stringValue);
if (readSuccess)
{
value.set(stringValue.toUtf8().data());
return true;
}
return false;
}
bool CVariableIArchive::operator()([[maybe_unused]] Serialization::IWString& value, [[maybe_unused]] const char* name, [[maybe_unused]] const char* label)
{
CryFatalError("CVariableIArchive::operator() with IWString is not implemented");
return false;
}
bool CVariableIArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label)
{
return VarUtil::ReadChildVariableAs< float >(m_pVariable, m_childIndexOverride, name, value);
}
bool CVariableIArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label)
{
return VarUtil::ReadChildVariableAs< float >(m_pVariable, m_childIndexOverride, name, value);
}
bool CVariableIArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label)
{
return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value);
}
bool CVariableIArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label)
{
return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value);
}
bool CVariableIArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label)
{
return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value);
}
bool CVariableIArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label)
{
return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value);
}
bool CVariableIArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label)
{
return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value);
}
bool CVariableIArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label)
{
return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value);
}
bool CVariableIArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label)
{
return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value);
}
bool CVariableIArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label)
{
return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value);
}
bool CVariableIArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label)
{
return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, value);
}
bool CVariableIArchive::operator()(const Serialization::SStruct& ser, const char* name, const char* label)
{
const char* const typeName = ser.type().name();
HandlersMap::const_iterator it = m_structHandlers.find(typeName);
const bool handlerFound = (it != m_structHandlers.end());
if (handlerFound)
{
StructHandlerFunctionPtr pHandler = it->second;
return (this->*pHandler)(ser, name, label);
}
return SerializeStruct(ser, name, label);
}
bool CVariableIArchive::operator()(Serialization::IContainer& ser, const char* name, [[maybe_unused]] const char* label)
{
_smart_ptr< IVariable > pChild = VarUtil::FindChildVariable(m_pVariable, m_childIndexOverride, name);
if (pChild)
{
const int elementCount = pChild->GetNumVariables();
ser.resize(elementCount);
if (0 < elementCount)
{
CVariableIArchive childArchive(pChild);
childArchive.SetFilter(GetFilter());
childArchive.SetInnerContext(GetInnerContext());
for (int i = 0; i < elementCount; ++i)
{
childArchive.m_childIndexOverride = i;
ser(childArchive, "", "");
ser.next();
}
}
return true;
}
return false;
}
bool CVariableIArchive::SerializeStruct(const Serialization::SStruct& ser, const char* name, [[maybe_unused]] const char* label)
{
_smart_ptr< IVariable > pChild = VarUtil::FindChildVariable(m_pVariable, m_childIndexOverride, name);
if (pChild)
{
CVariableIArchive childArchive(pChild);
childArchive.SetFilter(GetFilter());
childArchive.SetInnerContext(GetInnerContext());
ser(childArchive);
return true;
}
return false;
}
bool CVariableIArchive::SerializeResourceSelector(const Serialization::SStruct& ser, const char* name, [[maybe_unused]] const char* label)
{
Serialization::IResourceSelector* pSelector = reinterpret_cast< Serialization::IResourceSelector* >(ser.pointer());
QString stringValue;
const bool readSuccess = VarUtil::ReadChildVariableAs< QString >(m_pVariable, m_childIndexOverride, name, stringValue);
if (readSuccess)
{
pSelector->SetValue(stringValue.toUtf8().data());
return true;
}
return false;
}
bool CVariableIArchive::SerializeStringListStaticValue(const Serialization::SStruct& ser, const char* name, [[maybe_unused]] const char* label)
{
StringListStaticValue* const pStringListStaticValue = reinterpret_cast< StringListStaticValue* >(ser.pointer());
_smart_ptr< IVariable > pChild = VarUtil::FindChildVariable(m_pVariable, m_childIndexOverride, name);
if (pChild)
{
int index = -1;
pChild->Get(index);
*pStringListStaticValue = index;
return true;
}
return false;
}
bool CVariableIArchive::SerializeRangeFloat(const Serialization::SStruct& ser, const char* name, [[maybe_unused]] const char* label)
{
const Serialization::RangeDecorator< float >* const pRange = reinterpret_cast< Serialization::RangeDecorator< float >* >(ser.pointer());
return VarUtil::ReadChildVariableAs< float >(m_pVariable, m_childIndexOverride, name, *pRange->value);
}
bool CVariableIArchive::SerializeRangeInt(const Serialization::SStruct& ser, const char* name, [[maybe_unused]] const char* label)
{
const Serialization::RangeDecorator< int >* const pRange = reinterpret_cast< Serialization::RangeDecorator< int >* >(ser.pointer());
return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, *pRange->value);
}
bool CVariableIArchive::SerializeRangeUInt(const Serialization::SStruct& ser, const char* name, [[maybe_unused]] const char* label)
{
const Serialization::RangeDecorator< unsigned int >* const pRange = reinterpret_cast< Serialization::RangeDecorator< unsigned int >* >(ser.pointer());
return VarUtil::ReadChildVariableAs< int >(m_pVariable, m_childIndexOverride, name, *pRange->value);
}
@@ -1,71 +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 "Util/Variable.h"
#include "Serialization.h"
namespace Serialization
{
class CVariableIArchive
: public IArchive
{
public:
CVariableIArchive(const _smart_ptr< IVariable >& pVariable);
virtual ~CVariableIArchive();
// IArchive
virtual bool operator()(bool& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(IString& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(IWString& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(float& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(double& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(int16& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(uint16& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(int32& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(uint32& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(int64& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(uint64& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(int8& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(uint8& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(char& value, const char* name = "", const char* label = 0);
virtual bool operator()(const SStruct& ser, const char* name = "", const char* label = 0) override;
virtual bool operator()(IContainer& ser, const char* name = "", const char* label = 0) override;
//virtual bool operator()( IPointer& ptr, const char* name = "", const char* label = 0 ) override;
// ~IArchive
using IArchive::operator();
private:
bool SerializeResourceSelector(const SStruct& ser, const char* name, const char* label);
bool SerializeStruct(const SStruct& ser, const char* name, const char* label);
bool SerializeStringListStaticValue(const SStruct& ser, const char* name, const char* label);
bool SerializeRangeFloat(const SStruct& ser, const char* name, const char* label);
bool SerializeRangeInt(const SStruct& ser, const char* name, const char* label);
bool SerializeRangeUInt(const SStruct& ser, const char* name, const char* label);
private:
_smart_ptr< IVariable > m_pVariable;
int m_childIndexOverride;
typedef bool ( CVariableIArchive::* StructHandlerFunctionPtr )(const SStruct&, const char*, const char*);
typedef std::map< string, StructHandlerFunctionPtr > HandlersMap;
HandlersMap m_structHandlers; // TODO: have only one of these.
};
}
@@ -1,416 +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 "EditorDefs.h"
#include "VariableOArchive.h"
// Editor
#include "Serialization/Decorators/Resources.h"
#include "Serialization/Decorators/Range.h"
using Serialization::CVariableOArchive;
namespace VarUtil
{
template< typename T >
_smart_ptr< IVariable > AddChildVariable(const _smart_ptr< IVariable >& pVariableArray, const T& value, const char* const name, const char* label)
{
CRY_ASSERT(pVariableArray);
_smart_ptr< IVariable > pVariable = new CVariable< T >();
pVariable->SetName(name);
pVariable->SetHumanName(label);
pVariable->Set(value);
pVariableArray->AddVariable(pVariable);
return pVariable;
}
template< typename TMin, typename TMax >
void SetLimits(const _smart_ptr< IVariable >& pVariable, const TMin minValue, const TMax maxValue)
{
pVariable->SetLimits(static_cast< float >(minValue), static_cast< float >(maxValue));
}
}
CVariableOArchive::CVariableOArchive()
: IArchive(IArchive::OUTPUT | IArchive::EDIT | IArchive::NO_EMPTY_NAMES)
, m_pVariable(new CVariableArray())
{
m_resourceHandlers[ "Animation" ] = &CVariableOArchive::SerializeAnimationName;
m_resourceHandlers[ "Sound" ] = &CVariableOArchive::SerializeSoundName;
m_resourceHandlers[ "Model" ] = &CVariableOArchive::SerializeObjectFilename;
m_structHandlers[ TypeID::get < Serialization::IResourceSelector > ().name() ] = &CVariableOArchive::SerializeIResourceSelector;
m_structHandlers[ TypeID::get < Serialization::RangeDecorator < float >> ().name() ] = &CVariableOArchive::SerializeRangeFloat;
m_structHandlers[ TypeID::get < Serialization::RangeDecorator < int >> ().name() ] = &CVariableOArchive::SerializeRangeInt;
m_structHandlers[ TypeID::get < Serialization::RangeDecorator < unsigned int >> ().name() ] = &CVariableOArchive::SerializeRangeUInt;
m_structHandlers[ TypeID::get < StringListStaticValue > ().name() ] = &CVariableOArchive::SerializeStringListStaticValue;
}
CVariableOArchive::~CVariableOArchive()
{
}
_smart_ptr< IVariable > CVariableOArchive::GetIVariable() const
{
return m_pVariable;
}
CVarBlockPtr CVariableOArchive::GetVarBlock() const
{
CVarBlockPtr pVarBlock = new CVarBlock();
pVarBlock->AddVariable(m_pVariable);
return pVarBlock;
}
bool CVariableOArchive::operator()(bool& value, const char* name, const char* label)
{
VarUtil::AddChildVariable< bool >(m_pVariable, value, name, label);
return true;
}
bool CVariableOArchive::operator()(Serialization::IString& value, const char* name, const char* label)
{
const QString valueString = value.get();
VarUtil::AddChildVariable< QString >(m_pVariable, valueString, name, label);
return true;
}
bool CVariableOArchive::operator()([[maybe_unused]] Serialization::IWString& value, [[maybe_unused]] const char* name, [[maybe_unused]] const char* label)
{
CryFatalError("CVarBlockOArchive::operator() with IWString is not implemented");
return false;
}
bool CVariableOArchive::operator()(float& value, const char* name, const char* label)
{
VarUtil::AddChildVariable< float >(m_pVariable, value, name, label);
return true;
}
bool CVariableOArchive::operator()(double& value, const char* name, const char* label)
{
VarUtil::AddChildVariable< float >(m_pVariable, value, name, label);
return true;
}
bool CVariableOArchive::operator()(int16& value, const char* name, const char* label)
{
_smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label);
VarUtil::SetLimits(pVariable, SHRT_MIN, SHRT_MAX);
return true;
}
bool CVariableOArchive::operator()(uint16& value, const char* name, const char* label)
{
_smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label);
VarUtil::SetLimits(pVariable, 0, USHRT_MAX);
return true;
}
bool CVariableOArchive::operator()(int32& value, const char* name, const char* label)
{
_smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label);
VarUtil::SetLimits(pVariable, INT_MIN, INT_MAX);
return true;
}
bool CVariableOArchive::operator()(uint32& value, const char* name, const char* label)
{
_smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label);
VarUtil::SetLimits(pVariable, 0, INT_MAX);
return true;
}
bool CVariableOArchive::operator()(int64& value, const char* name, const char* label)
{
_smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label);
VarUtil::SetLimits(pVariable, INT_MIN, INT_MAX);
return true;
}
bool CVariableOArchive::operator()(uint64& value, const char* name, const char* label)
{
_smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label);
VarUtil::SetLimits(pVariable, 0, INT_MAX);
return true;
}
bool CVariableOArchive::operator()(int8& value, const char* name, const char* label)
{
_smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label);
VarUtil::SetLimits(pVariable, SCHAR_MIN, SCHAR_MAX);
return true;
}
bool CVariableOArchive::operator()(uint8& value, const char* name, const char* label)
{
_smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label);
VarUtil::SetLimits(pVariable, 0, UCHAR_MAX);
return true;
}
bool CVariableOArchive::operator()(char& value, const char* name, const char* label)
{
_smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, value, name, label);
VarUtil::SetLimits(pVariable, CHAR_MIN, CHAR_MAX);
return true;
}
bool CVariableOArchive::operator()(const Serialization::SStruct& ser, const char* name, const char* label)
{
const char* const typeName = ser.type().name();
HandlersMap::const_iterator it = m_structHandlers.find(typeName);
const bool handlerFound = (it != m_structHandlers.end());
if (handlerFound)
{
StructHandlerFunctionPtr pHandler = it->second;
return (this->*pHandler)(ser, name, label);
}
return SerializeStruct(ser, name, label);
}
static const char* gVec4Names[] = { "X", "Y", "Z", "W" };
static const char* gEmptyNames[] = { "" };
bool CVariableOArchive::operator()(Serialization::IContainer& ser, const char* name, const char* label)
{
CVariableOArchive childArchive;
childArchive.SetFilter(GetFilter());
childArchive.SetInnerContext(GetInnerContext());
_smart_ptr< IVariable > pChildVariable = childArchive.GetIVariable();
pChildVariable->SetName(name);
pChildVariable->SetHumanName(label);
m_pVariable->AddVariable(pChildVariable);
const size_t containerSize = ser.size();
const char** nameArray = gEmptyNames;
size_t nameArraySize = 1;
if (containerSize >= 2 && containerSize <= 4)
{
nameArray = gVec4Names;
nameArraySize = containerSize;
}
size_t index = 0;
if (0 < containerSize)
{
do
{
ser(childArchive, nameArray[index % nameArraySize], nameArray[index % nameArraySize]);
++index;
} while (ser.next());
}
return true;
}
bool CVariableOArchive::SerializeStruct(const Serialization::SStruct& ser, const char* name, const char* label)
{
CVariableOArchive childArchive;
childArchive.SetFilter(GetFilter());
childArchive.SetInnerContext(GetInnerContext());
_smart_ptr< IVariable > pChildVariable = childArchive.GetIVariable();
pChildVariable->SetName(name);
pChildVariable->SetHumanName(label);
m_pVariable->AddVariable(pChildVariable);
const bool serializeSuccess = ser(childArchive);
return serializeSuccess;
}
bool CVariableOArchive::SerializeAnimationName(const Serialization::IResourceSelector* pSelector, const char* name, const char* label)
{
const QString valueString = pSelector->GetValue();
_smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< QString >(m_pVariable, valueString, name, label);
pVariable->SetDataType(IVariable::DT_ANIMATION);
return true;
}
bool CVariableOArchive::SerializeSoundName(const Serialization::IResourceSelector* pSelector, const char* name, const char* label)
{
const QString valueString = pSelector->GetValue();
_smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< QString >(m_pVariable, valueString, name, label);
pVariable->SetDataType(IVariable::DT_AUDIO_TRIGGER);
return true;
}
void CVariableOArchive::CreateChildEnumVariable(const QStringList& enumValues, const QString& value, const char* name, const char* label)
{
if (enumValues.empty())
{
VarUtil::AddChildVariable< QString >(m_pVariable, value, name, label);
}
else
{
_smart_ptr< CVariableEnum< QString > > pVariable = new CVariableEnum< QString >();
pVariable->SetName(name);
pVariable->SetHumanName(label);
pVariable->AddEnumItem("", "");
const size_t enumValuesCount = enumValues.size();
for (size_t i = 0; i < enumValuesCount; ++i)
{
pVariable->AddEnumItem(enumValues[ i ], enumValues[ i ]);
}
pVariable->Set(value);
m_pVariable->AddVariable(pVariable);
}
}
bool CVariableOArchive::SerializeObjectFilename(const Serialization::IResourceSelector* pSelector, const char* name, const char* label)
{
const QString valueString = pSelector->GetValue();
_smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< QString >(m_pVariable, valueString, name, label);
pVariable->SetDataType(IVariable::DT_OBJECT);
return true;
}
bool CVariableOArchive::SerializeStringListStaticValue(const Serialization::SStruct& ser, const char* name, const char* label)
{
const StringListStaticValue* const pStringListStaticValue = reinterpret_cast< StringListStaticValue* >(ser.pointer());
const StringListStatic& stringListStatic = pStringListStaticValue->stringList();
const int index = pStringListStaticValue->index();
_smart_ptr< CVariableEnum< int > > pVariable = new CVariableEnum< int >();
pVariable->SetName(name);
pVariable->SetHumanName(label);
const size_t stringListStaticSize = stringListStatic.size();
for (size_t i = 0; i < stringListStaticSize; ++i)
{
pVariable->AddEnumItem(stringListStatic[ i ], static_cast< int >(i));
}
if (0 <= index)
{
CRY_ASSERT(index < stringListStaticSize);
pVariable->Set(static_cast< int >(index));
}
m_pVariable->AddVariable(pVariable);
return true;
}
bool CVariableOArchive::SerializeIResourceSelector(const Serialization::SStruct& ser, const char* name, const char* label)
{
const Serialization::IResourceSelector* pSelector = reinterpret_cast< Serialization::IResourceSelector* >(ser.pointer());
ResourceHandlersMap::iterator it = m_resourceHandlers.find(pSelector->resourceType);
if (it != m_resourceHandlers.end())
{
return (this->*(it->second))(pSelector, name, label);
}
return false;
}
template<class T>
static void SetLimits(IVariable* pVariable, const Serialization::RangeDecorator<T>* pRange, float stepValue)
{
if (pRange->softMin != std::numeric_limits<T>::lowest() || pRange->softMax != std::numeric_limits<T>::max())
{
float minimal = (float)pRange->softMin;
float maximal = (float)pRange->softMax;
bool hardMin = false;
bool hardMax = false;
if (pRange->hardMin != std::numeric_limits<T>::lowest())
{
minimal = pRange->hardMin;
hardMin = true;
}
if (pRange->hardMax != std::numeric_limits<T>::max())
{
maximal = pRange->hardMax;
hardMax = true;
}
pVariable->SetLimits(minimal, maximal, stepValue, hardMin, hardMax);
}
else
{
float minimal = 0.0f;
float maximal = 0.0f;
float oldStep = 0.0f;
bool hardMin = false;
bool hardMax = false;
pVariable->GetLimits(minimal, maximal, oldStep, hardMin, hardMax);
pVariable->SetLimits(minimal, maximal, stepValue, hardMin, hardMax);
}
}
bool CVariableOArchive::SerializeRangeFloat(const Serialization::SStruct& ser, const char* name, const char* label)
{
const Serialization::RangeDecorator< float >* const pRange = reinterpret_cast< Serialization::RangeDecorator< float >* >(ser.pointer());
_smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< float >(m_pVariable, *pRange->value, name, label);
SetLimits(pVariable.get(), pRange, 0.01f);
return true;
}
bool CVariableOArchive::SerializeRangeInt(const Serialization::SStruct& ser, const char* name, const char* label)
{
const Serialization::RangeDecorator< int >* const pRange = reinterpret_cast< Serialization::RangeDecorator< int >* >(ser.pointer());
_smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, *pRange->value, name, label);
SetLimits(pVariable.get(), pRange, 1.0f);
return true;
}
bool CVariableOArchive::SerializeRangeUInt(const Serialization::SStruct& ser, const char* name, const char* label)
{
const Serialization::RangeDecorator< unsigned int >* const pRange = reinterpret_cast< Serialization::RangeDecorator< unsigned int >* >(ser.pointer());
_smart_ptr< IVariable > pVariable = VarUtil::AddChildVariable< int >(m_pVariable, *pRange->value, name, label);
SetLimits(pVariable, pRange, 1.0f);
return true;
}
@@ -1,83 +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 "Util/Variable.h"
#include "Serialization.h"
namespace Serialization
{
struct IResourceSelector;
class CVariableOArchive
: public IArchive
{
public:
CVariableOArchive();
virtual ~CVariableOArchive();
_smart_ptr< IVariable > GetIVariable() const;
CVarBlockPtr GetVarBlock() const;
// IArchive
virtual bool operator()(bool& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(IString& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(IWString& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(float& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(double& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(int16& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(uint16& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(int32& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(uint32& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(int64& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(uint64& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(int8& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(uint8& value, const char* name = "", const char* label = 0) override;
virtual bool operator()(char& value, const char* name = "", const char* label = 0);
virtual bool operator()(const SStruct& ser, const char* name = "", const char* label = 0) override;
virtual bool operator()(IContainer& ser, const char* name = "", const char* label = 0) override;
//virtual bool operator()( IPointer& ptr, const char* name = "", const char* label = 0 ) override;
// ~IArchive
using IArchive::operator();
private:
bool SerializeStruct(const SStruct& ser, const char* name, const char* label);
bool SerializeStringListStaticValue(const SStruct& ser, const char* name, const char* label);
bool SerializeRangeFloat(const SStruct& ser, const char* name, const char* label);
bool SerializeRangeInt(const SStruct& ser, const char* name, const char* label);
bool SerializeRangeUInt(const SStruct& ser, const char* name, const char* label);
bool SerializeIResourceSelector(const SStruct& ser, const char* name, const char* label);
bool SerializeAnimationName(const IResourceSelector* pSelector, const char* name, const char* label);
bool SerializeSoundName(const IResourceSelector* pSelector, const char* name, const char* label);
bool SerializeObjectFilename(const IResourceSelector* pSelector, const char* name, const char* label);
void CreateChildEnumVariable(const QStringList& enumValues, const QString& value, const char* name, const char* label);
private:
_smart_ptr< IVariable > m_pVariable;
typedef bool ( CVariableOArchive::* StructHandlerFunctionPtr )(const SStruct&, const char*, const char*);
typedef std::map< string, StructHandlerFunctionPtr > HandlersMap;
HandlersMap m_structHandlers; // TODO: have only one of these.
typedef bool ( CVariableOArchive::* ResourceHandlerFunctionPtr )(const IResourceSelector*, const char*, const char*);
typedef std::map< string, ResourceHandlerFunctionPtr > ResourceHandlersMap;
ResourceHandlersMap m_resourceHandlers;
};
}
-177
View File
@@ -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 "EditorDefs.h"
#include "SettingsBlock.h"
// CryCommon
#include <CryCommon/Serialization/ITextInputArchive.h>
#include <CryCommon/Serialization/ITextOutputArchive.h>
// Editor
#include "Serialization.h"
using std::vector;
SProjectSettingsBlock* SProjectSettingsBlock::s_pLastBlock;
SProjectSettingsBlock::SProjectSettingsBlock(const char* name, const char* label)
: m_name(name)
, m_label(label)
{
m_pPrevious = s_pLastBlock;
s_pLastBlock = this;
}
struct SAllSettingsSerializer
{
void Serialize(Serialization::IArchive& ar)
{
SProjectSettingsBlock* pCurrent = SProjectSettingsBlock::s_pLastBlock;
while (pCurrent != 0)
{
ar(*pCurrent, pCurrent->GetName(), pCurrent->GetLabel());
pCurrent = pCurrent->m_pPrevious;
}
}
} static gAllSettingsSerializer;
void SProjectSettingsBlock::GetAllSettingsSerializer(Serialization::SStruct* pSerializer)
{
*pSerializer = Serialization::SStruct(gAllSettingsSerializer);
}
SProjectSettingsBlock* SProjectSettingsBlock::Find(const char* blockName)
{
SProjectSettingsBlock* pCurrent = SProjectSettingsBlock::s_pLastBlock;
while (pCurrent != 0)
{
if (_stricmp(pCurrent->GetName(), blockName) == 0)
{
return pCurrent;
}
}
return 0;
}
static bool ReadFileContent(vector<char>* pBuffer, const char* filename)
{
AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen(filename, "rb");
if (fileHandle == AZ::IO::InvalidHandle)
{
return false;
}
size_t size = gEnv->pCryPak->FGetSize(fileHandle);
pBuffer->resize(size);
bool result = true;
if (gEnv->pCryPak->FRead(&(*pBuffer)[0], size, fileHandle) != size)
{
result = false;
}
gEnv->pCryPak->FClose(fileHandle);
return result;
}
static bool SaveFileContent(const char* filename, const char* pBuffer, size_t length)
{
string fullpath = Path::GamePathToFullPath(filename).toUtf8().data();
AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle;
if (!gEnv->pFileIO->Open(fullpath.c_str(), AZ::IO::GetOpenModeFromStringMode("wb"), fileHandle))
{
return false;
}
bool result = true;
if (!gEnv->pFileIO->Write(fileHandle, pBuffer, length))
{
result = false;
}
gEnv->pFileIO->Close(fileHandle);
return result;
}
static bool SaveFileContentIfDiffers(const char* filename, const char* pBuffer, size_t length)
{
vector<char> content;
ReadFileContent(&content, filename);
bool needToWrite = true;
if (!content.empty() && content.size() == length)
{
needToWrite = memcmp(&content[0], pBuffer, length) != 0;
}
if (needToWrite)
{
return SaveFileContent(filename, pBuffer, length);
}
else
{
return true;
}
}
bool SProjectSettingsBlock::Load()
{
const char* filename = GetFilename();
vector<char> content;
if (!ReadFileContent(&content, filename))
{
return false;
}
auto pArchive(Serialization::CreateTextInputArchive());
if (!pArchive)
{
return false;
}
if (!pArchive->AttachMemory(&content[0], content.size()))
{
return false;
}
Serialization::SStruct serializer;
GetAllSettingsSerializer(&serializer);
serializer(*pArchive);
return true;
}
bool SProjectSettingsBlock::Save()
{
const char* filename = GetFilename();
auto pArchive(Serialization::CreateTextOutputArchive());
if (!pArchive)
{
return false;
}
Serialization::SStruct serializer;
GetAllSettingsSerializer(&serializer);
serializer(*pArchive);
return SaveFileContentIfDiffers(filename, pArchive->GetBuffer(), pArchive->GetBufferLength());
}
const char* SProjectSettingsBlock::GetFilename()
{
return "SandboxSettings.json";
}
-76
View File
@@ -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.
#pragma once
// ---------------------------------------------------------------------------
// Following utility can be used to add blocks of per-project settings.
// Example:
//
// MyComponent.cpp:
//
// struct SProjectSettingsMy : SProjectSettingsBlock
// {
// bool bMyOption;
//
// SProjectSettingsMy()
// : SProjectSettingsBlock("my", "My")
// , bMyOption(false)
// {}
//
// void Serialize(Serialization::IArchive& ar)
// {
// ar(bMyOption, "myOption", "My Option");
// }
//
// } static gMySettings;
//
//
// Now gMySettings will be loaded and saved automatically and available for
// editing through:
//
// GetIEditor()->OpenProjectSettings("my");
//
// ---------------------------------------------------------------------------
#ifndef CRYINCLUDE_EDITOR_SETTINGSBLOCK_H
#define CRYINCLUDE_EDITOR_SETTINGSBLOCK_H
namespace Serialization
{
class IArchive;
struct SStruct;
};
struct SProjectSettingsBlock
{
SProjectSettingsBlock(const char* name, const char* label);
virtual void Serialize(Serialization::IArchive& ar) = 0;
const char* GetName() const{ return m_name; }
const char* GetLabel() const{ return m_label; }
static void GetAllSettingsSerializer(Serialization::SStruct* serializer);
static SProjectSettingsBlock* Find(const char* name);
static bool Load();
static bool Save();
static const char* GetFilename();
private:
const char* m_name;
const char* m_label;
SProjectSettingsBlock* m_pPrevious;
static SProjectSettingsBlock* s_pLastBlock;
friend struct SAllSettingsSerializer;
};
#endif // CRYINCLUDE_EDITOR_SETTINGSBLOCK_H
-4
View File
@@ -595,10 +595,6 @@ AmazonToolbar ToolbarManager::GetEditModeToolbar() const
t.AddAction(ID_TOOLBAR_WIDGET_SNAP_GRID, ORIGINAL_TOOLBAR_VERSION);
t.AddAction(ID_TOOLBAR_WIDGET_SNAP_ANGLE, ORIGINAL_TOOLBAR_VERSION);
t.AddAction(ID_TOOLBAR_SEPARATOR, ORIGINAL_TOOLBAR_VERSION);
t.AddAction(ID_TOOLBAR_WIDGET_ENVIRONMENT_MODE, ORIGINAL_TOOLBAR_VERSION);
t.AddAction(ID_TOOLBAR_WIDGET_DEBUG_MODE, ORIGINAL_TOOLBAR_VERSION);
return t;
}
-35
View File
@@ -27,38 +27,3 @@ void CUsedResources::Add(const char* pResourceFileName)
files.insert(pResourceFileName);
}
}
void CUsedResources::Validate(IErrorReport* pReport)
{
auto pPak = gEnv->pCryPak;
for (TResourceFiles::iterator it = files.begin(); it != files.end(); ++it)
{
const QString& filename = *it;
bool fileExists = pPak->IsFileExist(filename.toUtf8().data());
if (!fileExists)
{
for (int i = 0; !fileExists && i < IResourceCompilerHelper::GetNumEngineImageFormats(); ++i)
{
fileExists = gEnv->pCryPak->IsFileExist(PathUtil::ReplaceExtension(filename.toUtf8().data(), IResourceCompilerHelper::GetEngineImageFormat(i, true)).c_str());
}
for (int i = 0; !fileExists && i < IResourceCompilerHelper::GetNumSourceImageFormats(); ++i)
{
fileExists = gEnv->pCryPak->IsFileExist(PathUtil::ReplaceExtension(filename.toUtf8().data(), IResourceCompilerHelper::GetSourceImageFormat(i, true)).c_str());
}
}
if (!fileExists)
{
CErrorRecord err;
err.error = QObject::tr("Resource File %1 not found,").arg(filename);
err.severity = CErrorRecord::ESEVERITY_ERROR;
err.flags |= CErrorRecord::FLAG_NOFILE;
pReport->ReportError(err);
}
}
}
-2
View File
@@ -36,8 +36,6 @@ public:
CUsedResources();
void Add(const char* pResourceFileName);
//! validate gathered resources, reports warning if resource is not found
void Validate(struct IErrorReport* pReport);
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
TResourceFiles files;
@@ -21,206 +21,228 @@
#include <QApplication>
static const auto ManipulatorPriority = AzFramework::ViewportControllerPriority::High;
static const auto InteractionPriority = AzFramework::ViewportControllerPriority::Low;
static const auto ManipulatorPriority = AzFramework::ViewportControllerPriority::Highest;
static const auto InteractionPriority = AzFramework::ViewportControllerPriority::High;
namespace SandboxEditor
{
ViewportManipulatorControllerInstance::ViewportManipulatorControllerInstance(AzFramework::ViewportId viewport, ViewportManipulatorController* controller)
: AzFramework::MultiViewportControllerInstanceInterface<ViewportManipulatorController>(viewport, controller)
{
}
AzToolsFramework::ViewportInteraction::MouseButton ViewportManipulatorControllerInstance::GetMouseButton(
const AzFramework::InputChannel& inputChannel)
{
using AzToolsFramework::ViewportInteraction::MouseButton;
using InputButton = AzFramework::InputDeviceMouse::Button;
const auto& id = inputChannel.GetInputChannelId();
if (id == InputButton::Left)
ViewportManipulatorControllerInstance::ViewportManipulatorControllerInstance(
AzFramework::ViewportId viewport, ViewportManipulatorController* controller)
: AzFramework::MultiViewportControllerInstanceInterface<ViewportManipulatorController>(viewport, controller)
{
return MouseButton::Left;
}
if (id == InputButton::Middle)
{
return MouseButton::Middle;
}
if (id == InputButton::Right)
{
return MouseButton::Right;
}
return MouseButton::None;
}
bool ViewportManipulatorControllerInstance::IsMouseMove(const AzFramework::InputChannel& inputChannel)
{
return inputChannel.GetInputChannelId() == AzFramework::InputDeviceMouse::SystemCursorPosition;
}
AzToolsFramework::ViewportInteraction::KeyboardModifier ViewportManipulatorControllerInstance::GetKeyboardModifier(
const AzFramework::InputChannel& inputChannel)
{
using AzToolsFramework::ViewportInteraction::KeyboardModifier;
using Key = AzFramework::InputDeviceKeyboard::Key;
const auto& id = inputChannel.GetInputChannelId();
if (id == Key::ModifierAltL || id == Key::ModifierAltR)
{
return KeyboardModifier::Alt;
}
if (id == Key::ModifierCtrlL || id == Key::ModifierCtrlR)
{
return KeyboardModifier::Ctrl;
}
if (id == Key::ModifierShiftL || id == Key::ModifierShiftR)
{
return KeyboardModifier::Shift;
}
return KeyboardModifier::None;
}
bool ViewportManipulatorControllerInstance::HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event)
{
// We only care about manipulator and viewport interaction events
if (event.m_priority != ManipulatorPriority && event.m_priority != InteractionPriority)
{
return false;
}
using InteractionBus = AzToolsFramework::EditorInteractionSystemViewportSelectionRequestBus;
using namespace AzToolsFramework::ViewportInteraction;
using AzFramework::InputChannel;
bool interactionHandled = false;
AZStd::optional<MouseButton> overrideButton;
AZStd::optional<MouseEvent> eventType;
// Because we receive events multiple times at separate priorities for manipulator events and
// viewport interaction events, we want to avoid updating our "last tick state" until we're on our last event,
// which currently is the low priority Interaction processor.
const bool finishedProcessingEvents = event.m_priority == InteractionPriority;
if (IsMouseMove(event.m_inputChannel))
AzToolsFramework::ViewportInteraction::MouseButton ViewportManipulatorControllerInstance::GetMouseButton(
const AzFramework::InputChannel& inputChannel)
{
// Cache the ray trace results when doing manipulator interaction checks, no need to recalculate after
if (event.m_priority == ManipulatorPriority)
using AzToolsFramework::ViewportInteraction::MouseButton;
using InputButton = AzFramework::InputDeviceMouse::Button;
const auto& id = inputChannel.GetInputChannelId();
if (id == InputButton::Left)
{
AzFramework::ScreenPoint screenPosition = AzFramework::ScreenPoint(0, 0);
ViewportMouseCursorRequestBus::EventResult(
screenPosition, GetViewportId(), &ViewportMouseCursorRequestBus::Events::ViewportCursorScreenPosition);
m_state.m_mousePick.m_screenCoordinates = screenPosition;
AZStd::optional<ProjectedViewportRay> ray;
ViewportInteractionRequestBus::EventResult(
ray, GetViewportId(), &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, screenPosition);
if (ray.has_value())
{
m_state.m_mousePick.m_rayOrigin = ray.value().origin;
m_state.m_mousePick.m_rayDirection = ray.value().direction;
}
return MouseButton::Left;
}
eventType = MouseEvent::Move;
}
else if (auto mouseButton = GetMouseButton(event.m_inputChannel); mouseButton != MouseButton::None)
{
const AZ::u32 mouseButtonValue = static_cast<AZ::u32>(mouseButton);
overrideButton = mouseButton;
if (event.m_inputChannel.GetState() == InputChannel::State::Began)
if (id == InputButton::Middle)
{
m_state.m_mouseButtons.m_mouseButtons |= mouseButtonValue;
if (IsDoubleClick(mouseButton))
return MouseButton::Middle;
}
if (id == InputButton::Right)
{
return MouseButton::Right;
}
return MouseButton::None;
}
bool ViewportManipulatorControllerInstance::IsMouseMove(const AzFramework::InputChannel& inputChannel)
{
return inputChannel.GetInputChannelId() == AzFramework::InputDeviceMouse::SystemCursorPosition;
}
AzToolsFramework::ViewportInteraction::KeyboardModifier ViewportManipulatorControllerInstance::GetKeyboardModifier(
const AzFramework::InputChannel& inputChannel)
{
using AzToolsFramework::ViewportInteraction::KeyboardModifier;
using Key = AzFramework::InputDeviceKeyboard::Key;
const auto& id = inputChannel.GetInputChannelId();
if (id == Key::ModifierAltL || id == Key::ModifierAltR)
{
return KeyboardModifier::Alt;
}
if (id == Key::ModifierCtrlL || id == Key::ModifierCtrlR)
{
return KeyboardModifier::Ctrl;
}
if (id == Key::ModifierShiftL || id == Key::ModifierShiftR)
{
return KeyboardModifier::Shift;
}
return KeyboardModifier::None;
}
bool ViewportManipulatorControllerInstance::HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event)
{
// We only care about manipulator and viewport interaction events
if (event.m_priority != ManipulatorPriority && event.m_priority != InteractionPriority)
{
return false;
}
using InteractionBus = AzToolsFramework::EditorInteractionSystemViewportSelectionRequestBus;
using namespace AzToolsFramework::ViewportInteraction;
using AzFramework::InputChannel;
bool interactionHandled = false;
float wheelDelta = 0.0f;
AZStd::optional<MouseButton> overrideButton;
AZStd::optional<MouseEvent> eventType;
// Because we receive events multiple times at separate priorities for manipulator events and
// viewport interaction events, we want to avoid updating our "last tick state" until we're on our last event,
// which currently is the low priority Interaction processor.
const bool finishedProcessingEvents = event.m_priority == InteractionPriority;
const auto state = event.m_inputChannel.GetState();
if (IsMouseMove(event.m_inputChannel))
{
// Cache the ray trace results when doing manipulator interaction checks, no need to recalculate after
if (event.m_priority == ManipulatorPriority)
{
// Only remove the double click flag once we're done processing both Manipulator and Interaction events
if (event.m_priority == InteractionPriority)
AzFramework::ScreenPoint screenPosition = AzFramework::ScreenPoint(0, 0);
ViewportMouseCursorRequestBus::EventResult(
screenPosition, GetViewportId(), &ViewportMouseCursorRequestBus::Events::ViewportCursorScreenPosition);
m_mouseInteraction.m_mousePick.m_screenCoordinates = screenPosition;
AZStd::optional<ProjectedViewportRay> ray;
ViewportInteractionRequestBus::EventResult(
ray, GetViewportId(), &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, screenPosition);
if (ray.has_value())
{
m_pendingDoubleClicks.erase(mouseButton);
m_mouseInteraction.m_mousePick.m_rayOrigin = ray.value().origin;
m_mouseInteraction.m_mousePick.m_rayDirection = ray.value().direction;
}
eventType = MouseEvent::DoubleClick;
}
else
eventType = MouseEvent::Move;
}
else if (auto mouseButton = GetMouseButton(event.m_inputChannel); mouseButton != MouseButton::None)
{
const AZ::u32 mouseButtonValue = static_cast<AZ::u32>(mouseButton);
overrideButton = mouseButton;
if (state == InputChannel::State::Began)
{
// Only insert the double click timing once we're done processing events, to avoid a false IsDoubleClick positive
if (finishedProcessingEvents)
m_mouseInteraction.m_mouseButtons.m_mouseButtons |= mouseButtonValue;
if (IsDoubleClick(mouseButton))
{
m_pendingDoubleClicks[mouseButton] = m_curTime;
// Only remove the double click flag once we're done processing both Manipulator and Interaction events
if (event.m_priority == InteractionPriority)
{
m_pendingDoubleClicks.erase(mouseButton);
}
eventType = MouseEvent::DoubleClick;
}
else
{
// Only insert the double click timing once we're done processing events, to avoid a false IsDoubleClick positive
if (finishedProcessingEvents)
{
m_pendingDoubleClicks[mouseButton] = m_curTime;
}
eventType = MouseEvent::Down;
}
eventType = MouseEvent::Down;
}
}
else if (event.m_inputChannel.GetState() == InputChannel::State::Ended)
{
// If we've actually logged a mouse down event, forward a mouse up event.
// This prevents corner cases like the context menu thinking it should be opened even though no one clicked in this viewport,
// due to RenderViewportWidget ensuring all controllers get InputChannel::State::Ended events.
if (m_state.m_mouseButtons.m_mouseButtons & mouseButtonValue)
else if (state == InputChannel::State::Ended)
{
// Erase the button from our state if we're done processing events.
if (event.m_priority == InteractionPriority)
// If we've actually logged a mouse down event, forward a mouse up event.
// This prevents corner cases like the context menu thinking it should be opened even though no one clicked in this viewport,
// due to RenderViewportWidget ensuring all controllers get InputChannel::State::Ended events.
if (m_mouseInteraction.m_mouseButtons.m_mouseButtons & mouseButtonValue)
{
m_state.m_mouseButtons.m_mouseButtons &= ~mouseButtonValue;
// Erase the button from our state if we're done processing events.
if (event.m_priority == InteractionPriority)
{
m_mouseInteraction.m_mouseButtons.m_mouseButtons &= ~mouseButtonValue;
}
eventType = MouseEvent::Up;
}
eventType = MouseEvent::Up;
}
}
}
else if (auto keyboardModifier = GetKeyboardModifier(event.m_inputChannel); keyboardModifier != KeyboardModifier::None)
{
if (event.m_inputChannel.GetState() == InputChannel::State::Began || event.m_inputChannel.GetState() == InputChannel::State::Updated)
else if (auto keyboardModifier = GetKeyboardModifier(event.m_inputChannel); keyboardModifier != KeyboardModifier::None)
{
m_state.m_keyboardModifiers.m_keyModifiers |= static_cast<AZ::u32>(keyboardModifier);
if (state == InputChannel::State::Began || state == InputChannel::State::Updated)
{
m_mouseInteraction.m_keyboardModifiers.m_keyModifiers |= static_cast<AZ::u32>(keyboardModifier);
}
else if (state == InputChannel::State::Ended)
{
m_mouseInteraction.m_keyboardModifiers.m_keyModifiers &= ~static_cast<AZ::u32>(keyboardModifier);
}
}
else if (event.m_inputChannel.GetState() == InputChannel::State::Ended)
else if (event.m_inputChannel.GetInputChannelId() == AzFramework::InputDeviceMouse::Movement::Z)
{
m_state.m_keyboardModifiers.m_keyModifiers &= ~static_cast<AZ::u32>(keyboardModifier);
if (state == InputChannel::State::Began || state == InputChannel::State::Updated)
{
eventType = MouseEvent::Wheel;
wheelDelta = event.m_inputChannel.GetValue();
}
}
}
if (eventType)
{
MouseInteraction mouseInteraction = m_state;
if (overrideButton)
if (eventType)
{
mouseInteraction.m_mouseButtons.m_mouseButtons = static_cast<AZ::u32>(overrideButton.value());
MouseInteraction mouseInteraction = m_mouseInteraction;
if (overrideButton)
{
mouseInteraction.m_mouseButtons.m_mouseButtons = static_cast<AZ::u32>(overrideButton.value());
}
mouseInteraction.m_interactionId.m_viewportId = GetViewportId();
// Depending on priority, we dispatch to either the manipulator or viewport interaction event
const auto& targetInteractionEvent = event.m_priority == ManipulatorPriority
? &InteractionBus::Events::InternalHandleMouseManipulatorInteraction
: &InteractionBus::Events::InternalHandleMouseViewportInteraction;
const auto mouseInteractionEvent = [mouseInteraction, event = eventType.value(), wheelDelta] {
switch (event)
{
case MouseEvent::Up:
case MouseEvent::Down:
case MouseEvent::Move:
case MouseEvent::DoubleClick:
return MouseInteractionEvent(AZStd::move(mouseInteraction), event);
case MouseEvent::Wheel:
return MouseInteractionEvent(AZStd::move(mouseInteraction), wheelDelta);
}
AZ_Assert(false, "Unhandled MouseEvent");
return MouseInteractionEvent(MouseInteraction{}, MouseEvent::Up);
}();
InteractionBus::EventResult(
interactionHandled, AzToolsFramework::GetEntityContextId(), targetInteractionEvent, mouseInteractionEvent);
}
mouseInteraction.m_interactionId.m_viewportId = GetViewportId();
// Depending on priority, we dispatch to either the manipulator or viewport interaction event
const auto& targetInteractionEvent =
event.m_priority == ManipulatorPriority
? &InteractionBus::Events::InternalHandleMouseManipulatorInteraction
: &InteractionBus::Events::InternalHandleMouseViewportInteraction;
InteractionBus::EventResult(
interactionHandled,
AzToolsFramework::GetEntityContextId(),
targetInteractionEvent,
MouseInteractionEvent(AZStd::move(mouseInteraction), eventType.value()));
return interactionHandled;
}
return interactionHandled;
}
void ViewportManipulatorControllerInstance::ResetInputChannels()
{
m_pendingDoubleClicks.clear();
m_state = AzToolsFramework::ViewportInteraction::MouseInteraction();
}
void ViewportManipulatorControllerInstance::UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event)
{
m_curTime = event.m_time;
}
bool ViewportManipulatorControllerInstance::IsDoubleClick(AzToolsFramework::ViewportInteraction::MouseButton button) const
{
auto clickIt = m_pendingDoubleClicks.find(button);
if (clickIt == m_pendingDoubleClicks.end())
void ViewportManipulatorControllerInstance::ResetInputChannels()
{
return false;
m_pendingDoubleClicks.clear();
m_mouseInteraction = AzToolsFramework::ViewportInteraction::MouseInteraction();
}
const double doubleClickThresholdMilliseconds = qApp->doubleClickInterval();
return (m_curTime.GetMilliseconds() - clickIt->second.GetMilliseconds()) < doubleClickThresholdMilliseconds;
}
void ViewportManipulatorControllerInstance::UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event)
{
m_curTime = event.m_time;
}
bool ViewportManipulatorControllerInstance::IsDoubleClick(AzToolsFramework::ViewportInteraction::MouseButton button) const
{
auto clickIt = m_pendingDoubleClicks.find(button);
if (clickIt == m_pendingDoubleClicks.end())
{
return false;
}
const double doubleClickThresholdMilliseconds = qApp->doubleClickInterval();
return (m_curTime.GetMilliseconds() - clickIt->second.GetMilliseconds()) < doubleClickThresholdMilliseconds;
}
} //namespace SandboxEditor
@@ -39,7 +39,7 @@ namespace SandboxEditor
static bool IsMouseMove(const AzFramework::InputChannel& inputChannel);
static AzToolsFramework::ViewportInteraction::KeyboardModifier GetKeyboardModifier(const AzFramework::InputChannel& inputChannel);
AzToolsFramework::ViewportInteraction::MouseInteraction m_state;
AzToolsFramework::ViewportInteraction::MouseInteraction m_mouseInteraction;
AZStd::unordered_map<AzToolsFramework::ViewportInteraction::MouseButton, AZ::ScriptTimePoint> m_pendingDoubleClicks;
AZ::ScriptTimePoint m_curTime;
};
@@ -280,8 +280,6 @@ set(FILES
Include/IAnimationCompressionManager.h
Include/IAssetItem.h
Include/IAssetItemDatabase.h
Include/IBackgroundScheduleManager.h
Include/IBackgroundTaskManager.h
Include/ICommandManager.h
Include/IConsoleConnectivity.h
Include/IDataBaseItem.h
@@ -343,10 +341,6 @@ set(FILES
AssetEditor/AssetEditorWindow.cpp
AssetEditor/AssetEditorWindow.h
AssetEditor/AssetEditorWindow.ui
BackgroundTaskManager.cpp
BackgroundScheduleManager.cpp
BackgroundTaskManager.h
BackgroundScheduleManager.h
Commands/CommandManager.cpp
Commands/CommandManager.h
Controls/BitmapToolTip.cpp
@@ -357,8 +351,6 @@ set(FILES
Controls/ConsoleSCB.h
Controls/ConsoleSCB.ui
Controls/ConsoleSCB.qrc
Controls/CurveEditorCtrl.cpp
Controls/CurveEditorCtrl.h
Controls/FolderTreeCtrl.cpp
Controls/FolderTreeCtrl.h
Controls/HotTrackingTreeCtrl.cpp
@@ -575,11 +567,6 @@ set(FILES
QtUI/WaitCursor.cpp
RenderHelpers/AxisHelper.cpp
RenderHelpers/AxisHelper.h
Serialization.h
Serialization/VariableOArchive.cpp
Serialization/VariableOArchive.h
Serialization/VariableIArchive.cpp
Serialization/VariableIArchive.h
CustomizeKeyboardDialog.h
CustomizeKeyboardDialog.cpp
CustomizeKeyboardDialog.ui
@@ -738,8 +725,6 @@ set(FILES
TrackView/TrackViewEventNode.h
ConfigGroup.cpp
ConfigGroup.h
SettingsBlock.cpp
SettingsBlock.h
Util/AffineParts.h
Util/AutoLogTime.cpp
Util/AutoLogTime.h
@@ -15,7 +15,6 @@
#include <LyViewPaneNames.h>
#include "IResourceSelectorHost.h"
#include "CryExtension/ICryFactoryRegistry.h"
#include "UI/QComponentEntityEditorMainWindow.h"
#include "UI/QComponentEntityEditorOutlinerWindow.h"
@@ -160,7 +160,6 @@ void SandboxIntegrationManager::Setup()
AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler::BusConnect();
AzFramework::DisplayContextRequestBus::Handler::BusConnect();
SetupFileExtensionMap();
MainWindow::instance()->GetActionManager()->RegisterActionHandler(ID_FILE_SAVE_SLICE_TO_ROOT, [this]() {
SaveSlice(false);
@@ -1926,30 +1925,6 @@ void SandboxIntegrationManager::MakeSliceFromEntities(const AzToolsFramework::En
AzToolsFramework::SliceUtilities::MakeNewSlice(entitiesAndDescendants, path, inheritSlices, setAsDynamic);
}
void SandboxIntegrationManager::SetupFileExtensionMap()
{
// There's no central registry for geometry file types.
const char* geometryFileExtensions[] =
{
CRY_GEOMETRY_FILE_EXT, // .cgf
CRY_SKEL_FILE_EXT, // .chr
CRY_CHARACTER_DEFINITION_FILE_EXT, // .cdf
};
// Cry geometry file extensions.
for (const char* extension : geometryFileExtensions)
{
m_extensionToFileType[AZ::Crc32(extension)] = IFileUtil::EFILE_TYPE_GEOMETRY;
}
// Cry image file extensions.
for (size_t i = 0; i < IResourceCompilerHelper::GetNumSourceImageFormats(); ++i)
{
const char* extension = IResourceCompilerHelper::GetSourceImageFormat(i, false);
m_extensionToFileType[AZ::Crc32(extension)] = IFileUtil::EFILE_TYPE_TEXTURE;
}
}
void SandboxIntegrationManager::RegisterViewPane(const char* name, const char* category, const AzToolsFramework::ViewPaneOptions& viewOptions, const WidgetCreationFunc& widgetCreationFunc)
{
QtViewPaneManager::instance()->RegisterPane(name, category, widgetCreationFunc, viewOptions);
@@ -319,12 +319,10 @@ private:
void OnLayerComponentDeactivated(AZ::EntityId entityId) override;
private:
void SetupFileExtensionMap();
// Right click context menu when a layer is included in the selection.
void SetupLayerContextMenu(QMenu* menu);
void SetupSliceContextMenu(QMenu* menu);
void SetupSliceContextMenu_Modify(QMenu* menu, const AzToolsFramework::EntityIdList& selectedEntities, const AZ::u32 numEntitiesInSlices);
void SetupScriptCanvasContextMenu(QMenu* menu);
void SaveSlice(const bool& QuickPushToFirstLevel);
void GetEntitiesInSlices(const AzToolsFramework::EntityIdList& selectedEntities, AZ::u32& entitiesInSlices, AZStd::vector<AZ::SliceComponent::SliceInstanceAddress>& sliceInstances);
@@ -348,9 +346,6 @@ private:
};
private:
typedef AZStd::unordered_map<AZ::u32, IFileUtil::ECustomFileType> ExtensionMap;
ExtensionMap m_extensionToFileType;
AZ::Vector2 m_contextMenuViewPoint;
AZ::Vector3 m_sliceWorldPos;
@@ -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

Some files were not shown because too many files have changed in this diff Show More