Skip to content

Instantly share code, notes, and snippets.

@ChemistAion
Created February 1, 2018 12:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ChemistAion/60d6ff71afc5f0367ccdea64b45acb34 to your computer and use it in GitHub Desktop.
Save ChemistAion/60d6ff71afc5f0367ccdea64b45acb34 to your computer and use it in GitHub Desktop.
Customized ImWindow (https://github.com/thennequin/ImWindow) with latest ImGui support
#pragma once
#include <stdlib.h>
#ifndef ImwList
#include <list>
#define ImwList std::list
#endif // ImwList
#ifndef ImwMap
#include <map>
#define ImwMap std::map
#endif // ImwMap
#ifndef ImwString
#include <string>
#define ImwString std::string
#endif // ImwString
#ifndef ImwChar
#define ImwChar char
#endif // ImwChar
#define ImwSafeDelete(pObj) { if (NULL != pObj) { delete pObj; pObj = NULL; } }
#define ImwSafeRelease(pObj) { if (NULL != pObj) { pObj->Release(); pObj = NULL; } }
#define ImwIsSafe(pObj) if (NULL != pObj) pObj
#define ImwMalloc(iSize) malloc(iSize)
#define ImwFree(pObj) free(pObj)
#define ImwSafeFree(pObj) { if (pObj != NULL) { free(pObj); pObj = NULL; } }
// Define IMW_INHERITED_BY_IMWWINDOW when you want ImwWindow inherit from one of your class
//#define IMW_INHERITED_BY_IMWWINDOW MyInheritedClass
// Define IMW_CUSTOM_DECLARE_IMWWINDOW and/or IMW_CUSTOM_IMPLEMENT_IMWWINDOW for custom declaration and implementation for ImwWindow
//#define IMW_CUSTOM_BEFORE_DECLARE_IMWWINDOW
//#define IMW_CUSTOM_DECLARE_IMWWINDOW
//#define IMW_CUSTOM_IMPLEMENT_IMWWINDOW
// Define IMW_BEFORE_WINDOW_PAINT for calling function of instancing object before painting window
//#define IMW_BEFORE_WINDOW_PAINT(pName) printf("Painting %s\n", pName);
//////////////////////////////////////////////////////////////////////////
// Include here imgui.h
//////////////////////////////////////////////////////////////////////////
#include "imgui.h"
#include "imgui_internal.h"
#include "..\..\pch.h"
namespace ImWindow
{
//SFF_BEGIN
const float ImwContainer::c_fTabHeight = 25.f;
ImwContainer::ImwContainer(ImwContainer* pParent)
{
IM_ASSERT(NULL != pParent);
m_pSplits[0] = NULL;
m_pSplits[1] = NULL;
m_bVerticalSplit = false;
m_iActiveWindow = 0;
m_fSplitRatio = 0.5f;
m_bIsDrag = false;
m_pParent = pParent;
m_pParentWindow = (NULL != pParent) ? pParent->m_pParentWindow : NULL;
}
ImwContainer::ImwContainer(ImwPlatformWindow* pParent)
{
IM_ASSERT(NULL != pParent);
m_pSplits[0] = NULL;
m_pSplits[1] = NULL;
m_bVerticalSplit = false;
m_iActiveWindow = 0;
m_fSplitRatio = 0.5f;
m_bIsDrag = false;
m_pParent = NULL;
m_pParentWindow = pParent;
}
ImwContainer::~ImwContainer()
{
while ( m_lWindows.begin() != m_lWindows.end() )
{
ImwWindowManager::GetInstance()->RemoveWindow(*m_lWindows.begin());
delete *m_lWindows.begin();
m_lWindows.erase(m_lWindows.begin());
}
ImwSafeDelete(m_pSplits[0]);
ImwSafeDelete(m_pSplits[1]);
}
void ImwContainer::CreateSplits()
{
m_pSplits[0] = new ImwContainer(this);
m_pSplits[1] = new ImwContainer(this);
}
void ImwContainer::Dock(ImwWindow* pWindow, EDockOrientation eOrientation, float fRatio, int iPosition)
{
IM_ASSERT(NULL != pWindow);
IM_ASSERT(fRatio > 0.f && fRatio < 1.f);
if ( NULL != pWindow )
{
IM_ASSERT(eOrientation != E_DOCK_ORIENTATION_CENTER || !IsSplit());
if ( !IsSplit() )
{
if (m_lWindows.begin() == m_lWindows.end())
{
eOrientation = E_DOCK_ORIENTATION_CENTER;
}
switch (eOrientation)
{
case E_DOCK_ORIENTATION_CENTER:
{
if (iPosition < 0 || iPosition >= (int)m_lWindows.size())
{
m_lWindows.push_back(pWindow);
m_iActiveWindow = (int)m_lWindows.size() - 1;
}
else
{
ImwWindowList::iterator itWindow = m_lWindows.begin();
std::advance(itWindow, iPosition);
m_lWindows.insert(itWindow, pWindow);
}
}
break;
case E_DOCK_ORIENTATION_TOP:
{
m_bVerticalSplit = true;
CreateSplits();
m_pSplits[0]->Dock(pWindow);
m_pSplits[1]->m_lWindows.insert(m_pSplits[1]->m_lWindows.begin(), m_lWindows.begin(), m_lWindows.end());
m_fSplitRatio = fRatio;
m_lWindows.clear();
m_iActiveWindow = 0;
}
break;
case E_DOCK_ORIENTATION_LEFT:
{
m_bVerticalSplit = false;
CreateSplits();
m_pSplits[0]->Dock(pWindow);
m_pSplits[1]->m_lWindows.insert(m_pSplits[1]->m_lWindows.begin(), m_lWindows.begin(), m_lWindows.end());
m_fSplitRatio = fRatio;
m_lWindows.clear();
m_iActiveWindow = 0;
}
break;
case E_DOCK_ORIENTATION_RIGHT:
{
m_bVerticalSplit = false;
CreateSplits();
m_pSplits[0]->m_lWindows.insert(m_pSplits[0]->m_lWindows.begin(), m_lWindows.begin(), m_lWindows.end());
m_pSplits[1]->Dock(pWindow);
m_fSplitRatio = 1.f - fRatio;
m_lWindows.clear();
m_iActiveWindow = 0;
}
break;
case E_DOCK_ORIENTATION_BOTTOM:
{
m_bVerticalSplit = true;
CreateSplits();
m_pSplits[0]->m_lWindows.insert(m_pSplits[0]->m_lWindows.begin(), m_lWindows.begin(), m_lWindows.end());
m_pSplits[1]->Dock(pWindow);
m_fSplitRatio = 1.f - fRatio;
m_lWindows.clear();
m_iActiveWindow = 0;
}
break;
}
}
else
{
switch (eOrientation)
{
case E_DOCK_ORIENTATION_CENTER:
IM_ASSERT(false);
break;
case E_DOCK_ORIENTATION_TOP:
{
ImwContainer* pSplit0 = m_pSplits[0];
ImwContainer* pSplit1 = m_pSplits[1];
CreateSplits();
m_pSplits[0]->m_lWindows.push_back(pWindow);
m_pSplits[1]->m_bVerticalSplit = m_bVerticalSplit;
m_pSplits[1]->m_fSplitRatio = m_fSplitRatio;
m_pSplits[1]->m_pSplits[0] = pSplit0;
m_pSplits[1]->m_pSplits[1] = pSplit1;
m_pSplits[1]->m_pSplits[0]->m_pParent = m_pSplits[1];
m_pSplits[1]->m_pSplits[1]->m_pParent = m_pSplits[1];
m_fSplitRatio = fRatio;
m_bVerticalSplit = true;
}
break;
case E_DOCK_ORIENTATION_LEFT:
{
ImwContainer* pSplit0 = m_pSplits[0];
ImwContainer* pSplit1 = m_pSplits[1];
CreateSplits();
m_pSplits[0]->m_lWindows.push_back(pWindow);
m_pSplits[1]->m_bVerticalSplit = m_bVerticalSplit;
m_pSplits[1]->m_fSplitRatio = m_fSplitRatio;
m_pSplits[1]->m_pSplits[0] = pSplit0;
m_pSplits[1]->m_pSplits[1] = pSplit1;
m_pSplits[1]->m_pSplits[0]->m_pParent = m_pSplits[1];
m_pSplits[1]->m_pSplits[1]->m_pParent = m_pSplits[1];
m_fSplitRatio = fRatio;
m_bVerticalSplit = false;
}
break;
case E_DOCK_ORIENTATION_RIGHT:
{
ImwContainer* pSplit0 = m_pSplits[0];
ImwContainer* pSplit1 = m_pSplits[1];
CreateSplits();
m_pSplits[1]->m_lWindows.push_back(pWindow);
m_pSplits[0]->m_bVerticalSplit = m_bVerticalSplit;
m_pSplits[0]->m_fSplitRatio = m_fSplitRatio;
m_pSplits[0]->m_pSplits[0] = pSplit0;
m_pSplits[0]->m_pSplits[1] = pSplit1;
m_pSplits[0]->m_pSplits[0]->m_pParent = m_pSplits[0];
m_pSplits[0]->m_pSplits[1]->m_pParent = m_pSplits[0];
m_fSplitRatio = 1.f - fRatio;
m_bVerticalSplit = false;
}
break;
case E_DOCK_ORIENTATION_BOTTOM:
{
ImwContainer* pSplit0 = m_pSplits[0];
ImwContainer* pSplit1 = m_pSplits[1];
CreateSplits();
m_pSplits[1]->m_lWindows.push_back(pWindow);
m_pSplits[0]->m_bVerticalSplit = m_bVerticalSplit;
m_pSplits[0]->m_fSplitRatio = m_fSplitRatio;
m_pSplits[0]->m_pSplits[0] = pSplit0;
m_pSplits[0]->m_pSplits[1] = pSplit1;
m_pSplits[0]->m_pSplits[0]->m_pParent = m_pSplits[0];
m_pSplits[0]->m_pSplits[1]->m_pParent = m_pSplits[0];
m_fSplitRatio = 1.f - fRatio;
m_bVerticalSplit = true;
}
break;
}
}
}
}
bool ImwContainer::UnDock(ImwWindow* pWindow)
{
if (std::find(m_lWindows.begin(), m_lWindows.end(), pWindow) != m_lWindows.end())
{
m_lWindows.remove(pWindow);
if (m_iActiveWindow >= (int)m_lWindows.size())
{
m_iActiveWindow = (int)m_lWindows.size() - 1;
}
return true;
}
if (NULL != m_pSplits[0] && NULL != m_pSplits[1])
{
if ( m_pSplits[0]->UnDock(pWindow) )
{
if (m_pSplits[0]->IsEmpty())
{
if (m_pSplits[1]->IsSplit())
{
ImwContainer* pSplit = m_pSplits[1];
m_bVerticalSplit = pSplit->m_bVerticalSplit;
ImwSafeDelete(m_pSplits[0]);
m_pSplits[0] = pSplit->m_pSplits[0];
m_pSplits[1] = pSplit->m_pSplits[1];
m_fSplitRatio = pSplit->m_fSplitRatio;
pSplit->m_pSplits[0] = NULL;
pSplit->m_pSplits[1] = NULL;
m_pSplits[0]->m_pParent = this;
m_pSplits[1]->m_pParent = this;
ImwSafeDelete(pSplit);
}
else
{
m_lWindows.insert(m_lWindows.end(), m_pSplits[1]->m_lWindows.begin(), m_pSplits[1]->m_lWindows.end());
m_pSplits[1]->m_lWindows.clear();
m_pSplits[1]->m_iActiveWindow = 0;
ImwSafeDelete(m_pSplits[0]);
ImwSafeDelete(m_pSplits[1]);
}
}
return true;
}
if (m_pSplits[1]->UnDock(pWindow))
{
if (m_pSplits[1]->IsEmpty())
{
if (m_pSplits[0]->IsSplit())
{
ImwContainer* pSplit = m_pSplits[0];
m_bVerticalSplit = pSplit->m_bVerticalSplit;
ImwSafeDelete(m_pSplits[1]);
m_pSplits[0] = pSplit->m_pSplits[0];
m_pSplits[1] = pSplit->m_pSplits[1];
m_fSplitRatio = pSplit->m_fSplitRatio;
pSplit->m_pSplits[0] = NULL;
pSplit->m_pSplits[1] = NULL;
m_pSplits[0]->m_pParent = this;
m_pSplits[1]->m_pParent = this;
ImwSafeDelete(pSplit);
}
else
{
m_lWindows.insert(m_lWindows.end(), m_pSplits[0]->m_lWindows.begin(), m_pSplits[0]->m_lWindows.end());
m_pSplits[0]->m_lWindows.clear();
m_pSplits[0]->m_iActiveWindow = 0;
ImwSafeDelete(m_pSplits[0]);
ImwSafeDelete(m_pSplits[1]);
}
}
return true;
}
}
return false;
}
void ImwContainer::DockToBest(ImwWindow* pWindow)
{
if (IsSplit())
{
if (m_fSplitRatio < 0.5f)
{
m_pSplits[0]->DockToBest(pWindow);
}
else
{
m_pSplits[1]->DockToBest(pWindow);
}
}
else
{
Dock(pWindow);
}
}
bool ImwContainer::IsEmpty() const
{
//IM_ASSERT(IsSplit() != HasWindowTabbed());
return !(IsSplit() || HasWindowTabbed());
}
bool ImwContainer::IsSplit() const
{
IM_ASSERT((NULL == m_pSplits[0]) == (NULL == m_pSplits[1]));
return (NULL != m_pSplits[0] && NULL != m_pSplits[1]);
}
bool ImwContainer::HasWindowTabbed() const
{
return m_lWindows.size() > 0;
}
ImwContainer* ImwContainer::HasWindow( const ImwWindow* pWindow)
{
if (std::find(m_lWindows.begin(), m_lWindows.end(), pWindow) != m_lWindows.end())
{
return this;
}
else
{
if (NULL != m_pSplits[0])
{
ImwContainer* pContainer = m_pSplits[0]->HasWindow(pWindow);
if (NULL != pContainer)
{
return pContainer;
}
}
if (NULL != m_pSplits[1])
{
ImwContainer* pContainer = m_pSplits[1]->HasWindow(pWindow);
if (NULL != pContainer)
{
return pContainer;
}
}
}
return NULL;
}
bool ImwContainer::FocusWindow(ImwWindow* pWindow)
{
ImwWindowList::iterator itFind = std::find(m_lWindows.begin(), m_lWindows.end(), pWindow);
if ( itFind != m_lWindows.end())
{
m_iActiveWindow = (int)std::distance(m_lWindows.begin(), itFind);
return true;
}
else
{
return (NULL != m_pSplits[0] && m_pSplits[0]->FocusWindow(pWindow)) || (NULL != m_pSplits[1] && m_pSplits[1]->FocusWindow(pWindow));
}
}
ImwPlatformWindow* ImwContainer::GetPlatformWindowParent() const
{
return m_pParentWindow;
}
bool ImwContainer::BeginChildAlpha(const char* pStrId, const ImVec2& oSizeArg, float fAlpha, ImGuiWindowFlags eExtraFlags)
{
ImGuiWindow* pWindow = ImGui::GetCurrentWindow();
ImGuiWindowFlags eFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_ChildWindow;
const ImVec2 oContentAvailable = ImGui::GetContentRegionAvail();
ImVec2 oSize = ImFloor(oSizeArg);
const int auto_fit_axises = ((oSize.x == 0.0f) ? 0x01 : 0x00) | ((oSize.y == 0.0f) ? 0x02 : 0x00);
if (oSize.x <= 0.0f)
oSize.x = ImMax(oContentAvailable.x, 4.0f) - fabsf(oSize.x);
if (oSize.y <= 0.0f)
oSize.y = ImMax(oContentAvailable.y, 4.0f) - fabsf(oSize.y);
eFlags |= eExtraFlags;
char pTitle[256];
ImFormatString(pTitle, IM_ARRAYSIZE(pTitle), "%s.%s", pWindow->Name, pStrId);
ImGui::SetNextWindowSize(oSize);
ImGuiContext& g = *GImGui;
const ImVec4 bg_color_backup = g.Style.Colors[ImGuiCol_ChildBg];
if (fAlpha >= 0.0f)
g.Style.Colors[ImGuiCol_ChildBg].w = fAlpha;
bool ret = ImGui::Begin(pTitle, NULL, eFlags);
if (fAlpha >= 0.0f)
g.Style.Colors[ImGuiCol_ChildBg] = bg_color_backup;
// ImGuiWindow* child_window = ImGui::GetCurrentWindow();
// child_window->AutoFitChildAxises = auto_fit_axises;
pWindow->AutoFitChildAxises = auto_fit_axises;
g.Style.WindowBorderSize = 0.0f;
g.Style.ChildBorderSize = 0.0f;
g.Style.FrameBorderSize = 0.0f;
return ret;
}
void ImwContainer::Paint(/* int iX, int iY, int iWidth, int iHeight */)
{
ImwWindowManager* pWindowManager = ImwWindowManager::GetInstance();
ImGuiWindow* pWindow = ImGui::GetCurrentWindow();
ImGuiStyle& oStyle = ImGui::GetStyle();
ImDrawList* pDrawList = ImGui::GetWindowDrawList();
const ImVec2 oPos = ImGui::GetWindowPos();
const ImVec2 oSize = ImGui::GetWindowSize();
const ImVec2 oMin = ImVec2(oPos.x, oPos.y);
const ImVec2 oMax = ImVec2(oPos.x + oSize.x, oPos.y + oSize.y);
const ImVec2 oCursorPos = ImGui::GetIO().MousePos;
m_oLastPosition = oPos;
m_oLastSize = oSize;
const int iSeparatorHalfSize = 4;
const int iSeparatorSize = iSeparatorHalfSize * 2;
if (IsSplit())
{
if (m_bVerticalSplit)
{
float iFirstHeight = oSize.y * m_fSplitRatio - iSeparatorHalfSize - pWindow->WindowPadding.x;
BeginChildAlpha("Split1", ImVec2(0, iFirstHeight), 0.f, ImGuiWindowFlags_NoScrollbar);
m_pSplits[0]->Paint(/*iX, iY, iWidth, iFirstHeight*/);
ImGui::EndChild();
ImRect oSeparatorRect( 0, iFirstHeight, oSize.x, iFirstHeight + iSeparatorSize);
if (pWindowManager->GetConfig().m_bVisibleDragger)
ImGui::Button("##Dragger", oSeparatorRect.GetSize());
else
ImGui::InvisibleButton("##Dragger", oSeparatorRect.GetSize());
if (ImGui::IsItemHovered() || m_bIsDrag)
{
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS);
}
if (ImGui::IsItemActive())
{
if (!m_bIsDrag)
{
m_bIsDrag = true;
}
m_fSplitRatio += ImGui::GetIO().MouseDelta.y / oSize.y;
m_fSplitRatio = ImClamp( m_fSplitRatio, 0.05f, 0.95f );
}
else
{
m_bIsDrag = false;
}
BeginChildAlpha("Split2", ImVec2(0, 0), 0.f, ImGuiWindowFlags_NoScrollbar);
m_pSplits[1]->Paint(/*iX, iY + iFirstHeight, iWidth, iSecondHeight*/);
ImGui::EndChild();
}
else
{
float iFirstWidth = oSize.x * m_fSplitRatio - iSeparatorHalfSize - pWindow->WindowPadding.y;
BeginChildAlpha("Split1", ImVec2(iFirstWidth, 0), 0.f, ImGuiWindowFlags_NoScrollbar);
m_pSplits[0]->Paint();
ImGui::EndChild();
ImGui::SameLine();
ImRect oSeparatorRect( iFirstWidth, 0, iFirstWidth + iSeparatorSize, oSize.y);
if (pWindowManager->GetConfig().m_bVisibleDragger)
ImGui::Button("##Dragger", oSeparatorRect.GetSize());
else
ImGui::InvisibleButton("##Dragger", oSeparatorRect.GetSize());
if (ImGui::IsItemHovered() || m_bIsDrag)
{
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
}
if (ImGui::IsItemActive())
{
if (!m_bIsDrag)
{
m_bIsDrag = true;
}
m_fSplitRatio += ImGui::GetIO().MouseDelta.x / oSize.x;
m_fSplitRatio = ImClamp( m_fSplitRatio, 0.05f, 0.95f );
}
else
{
m_bIsDrag = false;
}
ImGui::SameLine();
BeginChildAlpha("Split2", ImVec2(0, 0), 0.f, ImGuiWindowFlags_NoScrollbar);
m_pSplits[1]->Paint();
ImGui::EndChild();
}
}
else if (HasWindowTabbed())
{
pWindowManager->PopStyle();
bool bAlone = m_lWindows.front()->IsAlone();
ImwWindow* pActiveWindow = NULL;
if (!bAlone)
{
ImVec2 oItemSpacing = ImGui::GetStyle().ItemSpacing;
ImGui::GetStyle().ItemSpacing = ImVec2(oItemSpacing.x, 0.f);
ImGui::InvisibleButton("TabListButton", ImVec2(16, 16));
ImGui::SameLine();
if (ImGui::BeginPopupContextItem("TabListMenu", 0))
{
int iIndex = 0;
for (ImwWindowList::const_iterator itWindow = m_lWindows.begin(); itWindow != m_lWindows.end(); ++itWindow, ++iIndex)
{
if (ImGui::Selectable((*itWindow)->GetTitle()))
{
m_iActiveWindow = iIndex;
}
}
ImGui::EndPopup();
}
ImColor oLinesColor = ImColor(160, 160, 160, 255);
if (ImGui::IsItemHovered())
{
oLinesColor = ImColor(255, 255, 255, 255);
}
ImVec2 oButtonMin = ImGui::GetItemRectMin();
ImVec2 oButtonMax = ImGui::GetItemRectMax();
ImVec2 oButtonSize = ImVec2(oButtonMax.x - oButtonMin.x, oButtonMax.y - oButtonMin.y);
pDrawList->AddLine(
ImVec2(oButtonMin.x + 1, oButtonMin.y + oButtonSize.y / 2),
ImVec2(oButtonMax.x - 1, oButtonMin.y + oButtonSize.y / 2),
oLinesColor);
pDrawList->AddLine(
ImVec2(oButtonMin.x + 1, oButtonMin.y + oButtonSize.y / 2 - 4),
ImVec2(oButtonMax.x - 1, oButtonMin.y + oButtonSize.y / 2 - 4),
oLinesColor);
pDrawList->AddLine(
ImVec2(oButtonMin.x + 1, oButtonMin.y + oButtonSize.y / 2 + 4),
ImVec2(oButtonMax.x - 1, oButtonMin.y + oButtonSize.y / 2 + 4),
oLinesColor);
pDrawList->ChannelsSplit(2);
//Tabs
int iSize = (int)m_lWindows.size();
float fMaxTabSize = GetTabAreaWidth() / iSize;
ImwWindow* pDraggedWindow = ImwWindowManager::GetInstance()->GetDraggedWindow();
float fDraggedTabWidth = 0.f;
int iDraggedTabPosition = 0;
if (pDraggedWindow != NULL)
{
if (ImwWindowManager::GetInstance()->GetDragBestContainer() == this &&
ImwWindowManager::GetInstance()->GetDragOnTabArea())
{
iDraggedTabPosition = ImwWindowManager::GetInstance()->GetDragTabPosition();
fMaxTabSize = GetTabAreaWidth() / (iSize + 1);
//Tab(pDraggedWindow, true, oMin.x, oMax.x, fMaxTabSize);
ImGuiWindow* window = ImGui::GetCurrentWindow();
ImVec2 oTabSize;
float fMin = window->DC.CursorPos.x;
float fMax = fMin + m_oLastSize.x - fMaxTabSize;
float fTabPosX = oCursorPos.x + ImwWindowManager::GetInstance()->GetDragOffset().x;
if (fTabPosX < fMin) fTabPosX = fMin;
if (fTabPosX > fMax) fTabPosX = fMax;
ImVec2 oDraggedTabPos = ImVec2(fTabPosX, window->DC.CursorPos.y);
DrawTab(pDraggedWindow->GetTitle(), true, oDraggedTabPos, oMin.x, oMax.x, fMaxTabSize, &oTabSize);
fDraggedTabWidth = oTabSize.x;
}
else
{
pDraggedWindow = NULL;
}
}
int iIndex = 0;
int iNewActive = -1;
bool bFirstTab = true;
ImVec2 oFirstTabPos;
for (ImwWindowList::iterator it = m_lWindows.begin(); it != m_lWindows.end(); ++it)
{
if (pDraggedWindow != NULL && iDraggedTabPosition == iIndex)
{
ImGui::Dummy(ImVec2(fDraggedTabWidth, 1.f));
ImGui::SameLine();
}
ImGui::PushID(iIndex);
bool bSelected = iIndex == m_iActiveWindow && pDraggedWindow == NULL;
if (Tab(*it, bSelected, oMin.x, oMax.x, fMaxTabSize))
{
iNewActive = iIndex;
}
if (bFirstTab)
{
bFirstTab = false;
oFirstTabPos = ImGui::GetItemRectMin();
}
if (iIndex < (iSize - 1))
{
ImGui::SameLine();
}
if (ImGui::IsItemActive())
{
if (ImGui::IsMouseDragging())
{
//ImGui::GetIO().MouseClickedPos[0];
float fOffsetX = (oCursorPos.x - ImGui::GetItemRectMin().x) + (oFirstTabPos.x - oPos.x);
float fOffsetY = (oCursorPos.y - ImGui::GetItemRectMin().y);
ImVec2 oOffset = ImVec2(-fOffsetX, -fOffsetY);
pWindowManager->StartDragWindow(*it, oOffset);
}
}
else if (ImGui::IsItemHovered() && (*it)->IsClosable() && ImGui::GetIO().MouseClicked[2])
{
(*it)->Destroy();
}
if (ImGui::BeginPopupContextItem("TabMenu"))
{
if ((*it)->IsClosable() && ImGui::Selectable("Close"))
{
(*it)->Destroy();
}
if (ImGui::BeginMenu("Dock to"))
{
int iDockIndex = 0;
if (pWindowManager->GetMainPlatformWindow()->GetContainer()->IsEmpty())
{
ImGui::PushID(0);
if (ImGui::Selectable("Main")) pWindowManager->Dock((*it));
ImGui::PopID();
++iDockIndex;
}
const ImwWindowList& lWindows = pWindowManager->GetWindowList();
for (ImwWindowList::const_iterator itWindow = lWindows.begin(); itWindow != lWindows.end(); ++itWindow)
{
if ((*it) != (*itWindow))
{
ImGui::PushID(iDockIndex);
if (ImGui::BeginMenu((*itWindow)->GetTitle()))
{
bool bHovered = false;
ImwPlatformWindow* pPlatformWindow = pWindowManager->GetWindowParent((*itWindow));
ImVec2 oLastWinPos = (*itWindow)->GetLastPosition();
ImVec2 oLastWinSize = (*itWindow)->GetLastSize();
if (!(*itWindow)->IsAlone())
{
ImGui::PushID(0);
if (ImGui::Selectable("Tab")) pWindowManager->DockWith((*it), (*itWindow), E_DOCK_ORIENTATION_CENTER);
if (ImGui::IsItemHovered() && NULL != pPlatformWindow)
{
bHovered = true;
pWindowManager->DrawWindowArea(pPlatformWindow, oLastWinPos, oLastWinSize, ImColor(0.f, 0.5f, 1.f, 0.5f));
}
ImGui::PopID();
}
ImGui::PushID(1);
if (ImGui::Selectable("Top")) pWindowManager->DockWith((*it), (*itWindow), E_DOCK_ORIENTATION_TOP);
if (ImGui::IsItemHovered() && NULL != pPlatformWindow)
{
bHovered = true;
pWindowManager->DrawWindowArea(pPlatformWindow, oLastWinPos, ImVec2(oLastWinSize.x, oLastWinSize.y / 2.f), ImColor(0.f, 0.5f, 1.f, 0.5f));
}
ImGui::PopID();
ImGui::PushID(2);
if (ImGui::Selectable("Left")) pWindowManager->DockWith((*it), (*itWindow), E_DOCK_ORIENTATION_LEFT);
if (ImGui::IsItemHovered() && NULL != pPlatformWindow)
{
bHovered = true;
pWindowManager->DrawWindowArea(pPlatformWindow, oLastWinPos, ImVec2(oLastWinSize.x / 2.f, oLastWinSize.y), ImColor(0.f, 0.5f, 1.f, 0.5f));
}
ImGui::PopID();
ImGui::PushID(3);
if (ImGui::Selectable("Right")) pWindowManager->DockWith((*it), (*itWindow), E_DOCK_ORIENTATION_RIGHT);
if (ImGui::IsItemHovered() && NULL != pPlatformWindow)
{
bHovered = true;
pWindowManager->DrawWindowArea(pPlatformWindow, ImVec2(oLastWinPos.x + oLastWinSize.x / 2.f, oLastWinPos.y), ImVec2(oLastWinSize.x / 2.f, oLastWinSize.y), ImColor(0.f, 0.5f, 1.f, 0.5f));
}
ImGui::PopID();
ImGui::PushID(4);
if (ImGui::Selectable("Bottom")) pWindowManager->DockWith((*it), (*itWindow), E_DOCK_ORIENTATION_BOTTOM);
if (ImGui::IsItemHovered() && NULL != pPlatformWindow)
{
bHovered = true;
pWindowManager->DrawWindowArea(pPlatformWindow, ImVec2(oLastWinPos.x, oLastWinPos.y + oLastWinSize.y / 2.f), ImVec2(oLastWinSize.x, oLastWinSize.y / 2.f), ImColor(0.f, 0.5f, 1.f, 0.5f));
}
ImGui::PopID();
if (!bHovered)
{
if (NULL != pPlatformWindow)
{
pWindowManager->DrawWindowArea(pPlatformWindow, oLastWinPos, oLastWinSize, ImColor(0.f, 0.5f, 1.f, 0.5f));
}
}
ImGui::EndMenu();
}
ImGui::PopID();
}
++iDockIndex;
}
ImGui::EndMenu();
}
if (ImGui::Selectable("Float"))
{
pWindowManager->Float((*it), ImVec2(-1.f, -1.f), (*it)->m_oLastSize);
}
(*it)->OnContextMenu();
ImGui::EndPopup();
}
ImGui::PopID();
++iIndex;
}
if (iNewActive >= 0)
m_iActiveWindow = iNewActive;
pDrawList->ChannelsMerge();
ImGui::GetStyle().ItemSpacing = oItemSpacing;
pActiveWindow = pDraggedWindow;
}
if (pActiveWindow == NULL)
{
ImwWindowList::iterator itActiveWindow = m_lWindows.begin();
std::advance(itActiveWindow, m_iActiveWindow);
IM_ASSERT(itActiveWindow != m_lWindows.end());
pActiveWindow = *itActiveWindow;
}
//Draw active
if (pActiveWindow != NULL)
{
ImVec4 oBorderColor = oStyle.Colors[ImGuiCol_Border];
ImVec4 oBorderShadowColor = oStyle.Colors[ImGuiCol_BorderShadow];
oStyle.Colors[ImGuiCol_Border] = ImVec4(0.f, 0.f, 0.f, 0.f);
oStyle.Colors[ImGuiCol_BorderShadow] = ImVec4(0.f, 0.f, 0.f, 0.f);
ImGui::BeginChild(pActiveWindow->GetId(), ImVec2(0.f, 0.f), !pActiveWindow->IsFillingSpace(), ImGuiWindowFlags_NoScrollbar);
oStyle.Colors[ImGuiCol_Border] = oBorderColor;
oStyle.Colors[ImGuiCol_BorderShadow] = oBorderShadowColor;
ImVec2 oWinPos = ImGui::GetWindowPos();
ImVec2 oWinSize = ImGui::GetWindowSize();
for (ImwWindowList::iterator it = m_lWindows.begin(); it != m_lWindows.end(); ++it)
{
(*it)->m_oLastPosition = oWinPos;
(*it)->m_oLastSize = oWinSize;
}
{
#ifdef IMW_BEFORE_WINDOW_PAINT
IMW_BEFORE_WINDOW_PAINT(pActiveWindow->GetTitle())
#endif //IMW_BEFORE_WINDOW_PAINT
pActiveWindow->OnGui();
}
ImGui::EndChild();
}
pWindowManager->PushStyle();
}
else
{
// This case can happened only where it's main container
IM_ASSERT(m_pParent == NULL);
}
}
bool ImwContainer::Tab(const ImwWindow* pWindow, bool bFocused, float fStartLinePos, float fEndLinePos, float fMaxSize)
{
ImGuiWindow* window = ImGui::GetCurrentWindow();
if (window->SkipItems)
return false;
ImVec2 oTabSize;
DrawTab(pWindow->GetTitle(), bFocused, window->DC.CursorPos, fStartLinePos, fEndLinePos, fMaxSize, &oTabSize);
return ImGui::InvisibleButton(pWindow->GetIdStr(), oTabSize);
}
void ImwContainer::DrawTab(const ImwChar* pText, bool bFocused, ImVec2 oPos, float fStartLinePos, float fEndLinePos, float fMaxSize, ImVec2* pSizeOut)
{
const ImwWindowManager::Config& oConfig = ImwWindowManager::GetInstance()->GetConfig();
ImDrawList* pDrawList = ImGui::GetWindowDrawList();
const ImGuiStyle& oStyle = ImGui::GetStyle();
//Calculate text size
ImVec2 oTextSize;
float fTabWidth = GetTabWidth(pText, fMaxSize, &oTextSize);
//Calculate tab size
ImVec2 oTabSize(fTabWidth, c_fTabHeight);
if (pSizeOut != NULL)
{
*pSizeOut = oTabSize;
}
ImColor oNormalTab(0), oSelectedTab(0), oBorderColor(0);
switch (oConfig.m_eTabColorMode)
{
case ImwWindowManager::E_TABCOLORMODE_TITLE:
oNormalTab = ImGui::GetStyle().Colors[ImGuiCol_TitleBg];
oNormalTab.Value.w = 1.f;
oSelectedTab = ImGui::GetStyle().Colors[ImGuiCol_TitleBgActive];
oSelectedTab.Value.w = 1.f;
oBorderColor = ImGui::GetStyle().Colors[ImGuiCol_Border];
oBorderColor.Value.w = 1.f;
break;
case ImwWindowManager::E_TABCOLORMODE_BACKGROUND:
oNormalTab = ImColor(
oStyle.Colors[ImGuiCol_WindowBg].x + (oStyle.Colors[ImGuiCol_ChildBg].x - oStyle.Colors[ImGuiCol_WindowBg].x) * 0.5f,
oStyle.Colors[ImGuiCol_WindowBg].y + (oStyle.Colors[ImGuiCol_ChildBg].y - oStyle.Colors[ImGuiCol_WindowBg].y) * 0.5f,
oStyle.Colors[ImGuiCol_WindowBg].z + (oStyle.Colors[ImGuiCol_ChildBg].z - oStyle.Colors[ImGuiCol_WindowBg].z) * 0.5f,
oStyle.Colors[ImGuiCol_WindowBg].w + (oStyle.Colors[ImGuiCol_ChildBg].w - oStyle.Colors[ImGuiCol_WindowBg].w) * 0.5f
);
oSelectedTab = oStyle.Colors[ImGuiCol_ChildBg];
oBorderColor = oStyle.Colors[ImGuiCol_Border];
break;
case ImwWindowManager::E_TABCOLORMODE_CUSTOM:
oNormalTab = oConfig.m_oTabColorNormal;
oSelectedTab = oConfig.m_oTabColorActive;
oBorderColor = oConfig.m_oTabColorBorder;
break;
}
ImVec2 oRectMin = oPos;
ImVec2 oRectMax = ImVec2(oPos.x + oTabSize.x, oPos.y + oTabSize.y);
pDrawList->PathClear();
if (bFocused)
{
pDrawList->ChannelsSetCurrent(1);
}
else
{
pDrawList->ChannelsSetCurrent(0);
}
// //Drop shadows
// if (oConfig.m_bShowTabShadows)
// {
// const ImVec2 uv = GImGui->FontTexUvWhitePixel;
// pDrawList->PrimReserve(3, 3);
// pDrawList->PrimWriteIdx((ImDrawIdx)(pDrawList->_VtxCurrentIdx)); pDrawList->PrimWriteIdx((ImDrawIdx)(pDrawList->_VtxCurrentIdx + 1)); pDrawList->PrimWriteIdx((ImDrawIdx)(pDrawList->_VtxCurrentIdx + 2));
// pDrawList->PrimWriteVtx(ImVec2(oRectMin.x - oConfig.m_fTabOverlap - oConfig.m_fTabShadowDropSize, oRectMax.y), uv, ImColor(0.f, 0.f, 0.f, 0.f));
// pDrawList->PrimWriteVtx(ImVec2(oRectMin.x - oConfig.m_fTabOverlap + oConfig.m_fTabSlopWidth * oConfig.m_fTabShadowSlopRatio, oRectMin.y), uv, ImColor(0.f, 0.f, 0.f, 0.f));
// pDrawList->PrimWriteVtx(ImVec2(oRectMin.x - oConfig.m_fTabOverlap + oConfig.m_fTabSlopWidth * oConfig.m_fTabShadowSlopRatio, oRectMax.y), uv, ImColor(0.f, 0.f, 0.f, oConfig.m_fTabShadowAlpha));
// if (bFocused)
// {
// pDrawList->PrimReserve(3, 3);
// pDrawList->PrimWriteIdx((ImDrawIdx)(pDrawList->_VtxCurrentIdx)); pDrawList->PrimWriteIdx((ImDrawIdx)(pDrawList->_VtxCurrentIdx + 1)); pDrawList->PrimWriteIdx((ImDrawIdx)(pDrawList->_VtxCurrentIdx + 2));
// pDrawList->PrimWriteVtx(ImVec2(oRectMax.x + oConfig.m_fTabOverlap + oConfig.m_fTabShadowDropSize, oRectMax.y), uv, ImColor(0.f, 0.f, 0.f, 0.f));
// pDrawList->PrimWriteVtx(ImVec2(oRectMax.x + oConfig.m_fTabOverlap - oConfig.m_fTabSlopWidth * oConfig.m_fTabShadowSlopRatio, oRectMin.y), uv, ImColor(0.f, 0.f, 0.f, 0.f));
// pDrawList->PrimWriteVtx(ImVec2(oRectMax.x + oConfig.m_fTabOverlap - oConfig.m_fTabSlopWidth * oConfig.m_fTabShadowSlopRatio, oRectMax.y), uv, ImColor(0.f, 0.f, 0.f, oConfig.m_fTabShadowAlpha));
// }
// }
// Draw tab and border
if (bFocused && fStartLinePos < oPos.x)
{
pDrawList->PathLineTo(ImVec2(fStartLinePos, oRectMax.y));
}
pDrawList->PathLineTo(ImVec2(oRectMin.x - oConfig.m_fTabOverlap, oRectMax.y));
pDrawList->PathBezierCurveTo(
ImVec2(oRectMin.x + oConfig.m_fTabSlopWidth * oConfig.m_fTabSlopP1Ratio - oConfig.m_fTabOverlap, oRectMin.y + (oRectMax.y - oRectMin.y) * oConfig.m_fTabSlopHRatio),
ImVec2(oRectMin.x + oConfig.m_fTabSlopWidth * oConfig.m_fTabSlopP2Ratio - oConfig.m_fTabOverlap, oRectMin.y),
ImVec2(oRectMin.x + oConfig.m_fTabSlopWidth - oConfig.m_fTabOverlap, oRectMin.y)
);
pDrawList->PathLineTo(ImVec2(oRectMax.x - oConfig.m_fTabSlopWidth + oConfig.m_fTabOverlap, oRectMin.y));
pDrawList->PathBezierCurveTo(
ImVec2(oRectMax.x - oConfig.m_fTabSlopWidth * oConfig.m_fTabSlopP2Ratio + oConfig.m_fTabOverlap, oRectMin.y),
ImVec2(oRectMax.x - oConfig.m_fTabSlopWidth * oConfig.m_fTabSlopP1Ratio + oConfig.m_fTabOverlap, oRectMin.y + (oRectMax.y - oRectMin.y) * oConfig.m_fTabSlopHRatio),
ImVec2(oRectMax.x + oConfig.m_fTabOverlap, oRectMax.y)
);
if (bFocused)
{
pDrawList->AddConvexPolyFilled(pDrawList->_Path.Data + 1, pDrawList->_Path.Size - 1, bFocused ? oSelectedTab : oNormalTab);
if (fEndLinePos > oRectMax.x)
{
pDrawList->PathLineTo(ImVec2(fEndLinePos, oRectMax.y));
}
if (oConfig.m_bShowTabBorder)
pDrawList->AddPolyline(pDrawList->_Path.Data, pDrawList->_Path.Size, oBorderColor, false, 1.5f);
}
else
{
pDrawList->AddConvexPolyFilled(pDrawList->_Path.Data, pDrawList->_Path.Size, bFocused ? oSelectedTab : oNormalTab);
}
pDrawList->PathClear();
ImVec2 oTextRectMin(oRectMin.x + 5, oRectMin.y);
ImVec2 oTextRectMax(oRectMax.x - 5, oRectMax.y);
ImGui::RenderTextClipped(oTextRectMin, oTextRectMax, pText, NULL, &oTextSize, ImVec2(0.5f, 0.5f));
}
float ImwContainer::GetTabWidth(const ImwChar* pText, float fMaxSize, ImVec2* pOutTextSize)
{
const ImVec2 oTextSize = ImGui::CalcTextSize(pText);
if (NULL != pOutTextSize)
{
*pOutTextSize = oTextSize;
}
//Clamp fMaxSize to a minimum for avoid glitch
if (fMaxSize < 30.f)
{
fMaxSize = 30.f;
}
//Calculate tab size
float fWidth = oTextSize.x + 15;
if (fMaxSize != 1.f && fWidth > fMaxSize)
{
fWidth = fMaxSize;
}
return fWidth;
}
float ImwContainer::GetTabAreaWidth() const
{
return m_oLastSize.x - 50.f;
}
ImwContainer* ImwContainer::GetBestDocking(const ImVec2 oCursorPos, EDockOrientation& oOutOrientation, ImVec2& oOutAreaPos, ImVec2& oOutAreaSize, bool& bOutOnTabArea, int& iOutPosition, bool bLargeCheck)
{
if (m_pParent == NULL ||
(oCursorPos.x >= m_oLastPosition.x && oCursorPos.x <= (m_oLastPosition.x + m_oLastSize.x) &&
oCursorPos.y >= m_oLastPosition.y && oCursorPos.y <= (m_oLastPosition.y + m_oLastSize.y)))
{
if (IsSplit())
{
ImwContainer* pBestContainer = NULL;
pBestContainer = m_pSplits[0]->GetBestDocking(oCursorPos, oOutOrientation, oOutAreaPos, oOutAreaSize, bOutOnTabArea, iOutPosition, bLargeCheck);
if (NULL != pBestContainer)
{
return pBestContainer;
}
pBestContainer = m_pSplits[1]->GetBestDocking(oCursorPos, oOutOrientation, oOutAreaPos, oOutAreaSize, bOutOnTabArea, iOutPosition, bLargeCheck);
if (NULL != pBestContainer)
{
return pBestContainer;
}
}
else
{
if (oCursorPos.y < m_oLastPosition.y + c_fTabHeight)
{
oOutOrientation = E_DOCK_ORIENTATION_CENTER;
oOutAreaPos = m_oLastPosition;
oOutAreaSize = ImVec2(0,0);
bOutOnTabArea = true;
//Search tab position
float fMaxTabSize = GetTabAreaWidth() / (m_lWindows.size() + 1);
float fCurrentTabPosX = m_oLastPosition.x;
int iCurrentTab = 0;
float fCursorX = oCursorPos.x + ImwWindowManager::GetInstance()->GetDragOffset().x;
for (ImwWindowList::const_iterator itWindow = m_lWindows.begin(); itWindow != m_lWindows.end(); ++itWindow)
{
float fTabWidth = GetTabWidth((*itWindow)->m_pTitle, fMaxTabSize);
if (fCursorX < (fCurrentTabPosX + fTabWidth / 2.f))
{
break;
}
fCurrentTabPosX += fTabWidth;
++iCurrentTab;
}
iOutPosition = iCurrentTab;
return this;
}
else
{
const float c_fBoxHalfSize = 20.f;
const float c_fBoxSize = c_fBoxHalfSize * 2.f;
const float c_fMinSize = c_fBoxSize * 4.f;
const float c_fSplitRatio = 0.5f;
//const float c_fSplitRatio = oConfig.m_fDragMarginSizeRatio;
const ImColor oBoxColor(200, 200, 255, 255);
const ImColor oBoxHightlightColor(100, 100, 255, 255);
if (m_oLastSize.x < c_fMinSize && m_oLastSize.y < c_fMinSize)
{
oOutOrientation = E_DOCK_ORIENTATION_CENTER;
oOutAreaPos = m_oLastPosition;
oOutAreaSize = m_oLastSize;
return this;
}
else
{
const ImVec2 oCenter = ImVec2(m_oLastPosition.x + m_oLastSize.x / 2.f, m_oLastPosition.y + m_oLastSize.y / 2.f);
bool bIsInCenter = false;
bool bIsInTop = false;
bool bIsInLeft = false;
bool bIsInRight = false;
bool bIsInBottom = false;
if (bLargeCheck)
{
ImRect oRectCenter(ImVec2(oCenter.x - c_fBoxHalfSize * 2.f, oCenter.y - c_fBoxHalfSize * 2.f), ImVec2(oCenter.x + c_fBoxHalfSize * 2.f, oCenter.y + c_fBoxHalfSize * 2.f));
ImRect oRectTop = ImRect(ImVec2(m_oLastPosition.x, m_oLastPosition.y), ImVec2(m_oLastPosition.x + m_oLastSize.x, oCenter.y - c_fBoxHalfSize * 2.f));
ImRect oRectBottom = ImRect(ImVec2(m_oLastPosition.x, oCenter.y + c_fBoxHalfSize * 2.f), ImVec2(m_oLastPosition.x + m_oLastSize.x, m_oLastPosition.y + m_oLastSize.y));
ImRect oRectLeft = ImRect(ImVec2(m_oLastPosition.x, m_oLastPosition.y), ImVec2(oCenter.x - c_fBoxHalfSize * 2.f, m_oLastPosition.y + m_oLastSize.y));
ImRect oRectRight = ImRect(ImVec2(oCenter.x + c_fBoxHalfSize * 2.f, m_oLastPosition.y), ImVec2(m_oLastPosition.x + m_oLastSize.x, m_oLastPosition.y + m_oLastSize.y));
bIsInCenter = oRectCenter.Contains(oCursorPos);
if (m_oLastSize.y >= c_fMinSize)
{
bIsInTop = oRectTop.Contains(oCursorPos);
bIsInBottom = oRectBottom.Contains(oCursorPos);
}
if (m_oLastSize.x >= c_fMinSize)
{
bIsInLeft = oRectLeft.Contains(oCursorPos);
bIsInRight = oRectRight.Contains(oCursorPos);
}
}
else
{
if (m_lWindows.empty() || !m_lWindows.front()->IsAlone())
{
//Center
ImRect oRectCenter(ImVec2(oCenter.x - c_fBoxHalfSize, oCenter.y - c_fBoxHalfSize), ImVec2(oCenter.x + c_fBoxHalfSize, oCenter.y + c_fBoxHalfSize));
bIsInCenter = oRectCenter.Contains(oCursorPos);
ImwWindowManager::GetInstance()->DrawWindowArea(m_pParentWindow, oRectCenter.Min, oRectCenter.GetSize(), bIsInCenter ? oBoxHightlightColor : oBoxColor);
}
if (!m_lWindows.empty())
{
if (m_oLastSize.y >= c_fMinSize)
{
//Top
ImRect oRectTop(ImVec2(oCenter.x - c_fBoxHalfSize, oCenter.y - c_fBoxHalfSize * 4.f), ImVec2(oCenter.x + c_fBoxHalfSize, oCenter.y - c_fBoxHalfSize * 2.f));
bIsInTop = oRectTop.Contains(oCursorPos);
ImwWindowManager::GetInstance()->DrawWindowArea(m_pParentWindow, oRectTop.Min, oRectTop.GetSize(), bIsInTop ? oBoxHightlightColor : oBoxColor);
//Bottom
ImRect oRectBottom(ImVec2(oCenter.x - c_fBoxHalfSize, oCenter.y + c_fBoxHalfSize * 2.f), ImVec2(oCenter.x + c_fBoxHalfSize, oCenter.y + c_fBoxHalfSize * 4.f));
bIsInBottom = oRectBottom.Contains(oCursorPos);
ImwWindowManager::GetInstance()->DrawWindowArea(m_pParentWindow, oRectBottom.Min, oRectBottom.GetSize(), bIsInBottom ? oBoxHightlightColor : oBoxColor);
}
if (m_oLastSize.x >= c_fMinSize)
{
//Left
ImRect oRectLeft(ImVec2(oCenter.x - c_fBoxHalfSize * 4.f, oCenter.y - c_fBoxHalfSize), ImVec2(oCenter.x - c_fBoxHalfSize * 2.f, oCenter.y + c_fBoxHalfSize));
bIsInLeft = oRectLeft.Contains(oCursorPos);
ImwWindowManager::GetInstance()->DrawWindowArea(m_pParentWindow, oRectLeft.Min, oRectLeft.GetSize(), bIsInLeft ? oBoxHightlightColor : oBoxColor);
//Right
ImRect oRectRight(ImVec2(oCenter.x + c_fBoxHalfSize * 2.f, oCenter.y - c_fBoxHalfSize), ImVec2(oCenter.x + c_fBoxHalfSize * 4.f, oCenter.y + c_fBoxHalfSize));
bIsInRight = oRectRight.Contains(oCursorPos);
ImwWindowManager::GetInstance()->DrawWindowArea(m_pParentWindow, oRectRight.Min, oRectRight.GetSize(), bIsInRight ? oBoxHightlightColor : oBoxColor);
}
}
}
if (bIsInCenter)
{
oOutOrientation = E_DOCK_ORIENTATION_CENTER;
oOutAreaPos = m_oLastPosition;
oOutAreaSize = m_oLastSize;
bOutOnTabArea = false;
return this;
}
else if (bIsInTop)
{
oOutOrientation = E_DOCK_ORIENTATION_TOP;
oOutAreaPos = m_oLastPosition;
oOutAreaSize = ImVec2(m_oLastSize.x, m_oLastSize.y * c_fSplitRatio);
bOutOnTabArea = false;
return this;
}
else if (bIsInLeft)
{
oOutOrientation = E_DOCK_ORIENTATION_LEFT;
oOutAreaPos = m_oLastPosition;
oOutAreaSize = ImVec2(m_oLastSize.x * c_fSplitRatio, m_oLastSize.y);
bOutOnTabArea = false;
return this;
}
else if (bIsInRight)
{
oOutOrientation = E_DOCK_ORIENTATION_RIGHT;
oOutAreaPos = ImVec2(m_oLastPosition.x + m_oLastSize.x * (1.f - c_fSplitRatio), m_oLastPosition.y);
oOutAreaSize = ImVec2(m_oLastSize.x * c_fSplitRatio, m_oLastSize.y);
bOutOnTabArea = false;
return this;
}
else if (bIsInBottom)
{
oOutOrientation = E_DOCK_ORIENTATION_BOTTOM;
oOutAreaPos = ImVec2(m_oLastPosition.x, m_oLastPosition.y + m_oLastSize.y * (1.f - c_fSplitRatio));
oOutAreaSize = ImVec2(m_oLastSize.x, m_oLastSize.y * c_fSplitRatio);
bOutOnTabArea = false;
return this;
}
}
}
}
}
return NULL;
}
bool ImwContainer::HasUnclosableWindow() const
{
for (ImwWindowList::const_iterator itWindow = m_lWindows.begin(); itWindow != m_lWindows.end(); ++itWindow)
{
if ( !(*itWindow)->IsClosable() )
{
return true;
}
}
if (IsSplit())
{
return m_pSplits[0]->HasUnclosableWindow() || m_pSplits[1]->HasUnclosableWindow();
}
return false;
}
// bool ImwContainer::Save(JsonValue& oJson)
// {
// oJson["Vertical"] = m_bVerticalSplit;
// oJson["SplitRatio"] = m_fSplitRatio;
//
// if (m_lWindows.size() > 0)
// {
// ImwWindowManager* pWindowManager = ImwWindowManager::GetInstance();
// oJson["CurrentWindow"] = (long)m_iActiveWindow;
// JsonValue& oJsonWindows = oJson["Windows"];
// int iCurrentWindow = 0;
// for (ImwWindowList::const_iterator itWindow = m_lWindows.begin(); itWindow != m_lWindows.end(); ++itWindow)
// {
// JsonValue& oJsonWindow = oJsonWindows[iCurrentWindow++];
// const ImwChar* pClassName = pWindowManager->GetWindowClassName(*itWindow);
// if (pClassName == NULL)
// return false;
// oJsonWindow["Class"] = pClassName;
// (*itWindow)->GetParameters(oJsonWindow["Parameters"]);
// }
// return true;
// }
// else
// {
// JsonValue& oJsonSplits = oJson["Splits"];
// return m_pSplits[0]->Save(oJsonSplits[0]) && m_pSplits[1]->Save(oJsonSplits[1]);
// }
// }
//
// bool ImwContainer::Load(const JsonValue& oJson, bool bJustCheck)
// {
// if (!oJson["Vertical"].IsBoolean() || !oJson["SplitRatio"].IsFloat())
// return false;
//
// if (!(oJson["Windows"].IsArray() || (oJson["Splits"].IsArray() && oJson["Splits"].GetMemberCount() == 2)))
// return false;
//
// if (!bJustCheck)
// {
// m_bVerticalSplit = oJson["Vertical"];
// m_fSplitRatio = (float)(double)oJson["SplitRatio"];
//
// //Clear
// while (m_lWindows.begin() != m_lWindows.end())
// {
// ImwWindowManager::GetInstance()->RemoveWindow(*m_lWindows.begin());
// delete *m_lWindows.begin();
// m_lWindows.erase(m_lWindows.begin());
// }
//
// ImwSafeDelete(m_pSplits[0]);
// ImwSafeDelete(m_pSplits[1]);
// }
//
// if (oJson["Splits"].IsArray())
// {
// if (!bJustCheck)
// {
// CreateSplits();
// if (!m_pSplits[0]->Load(oJson["Splits"][0], bJustCheck) || !m_pSplits[1]->Load(oJson["Splits"][1], bJustCheck))
// return false;
// }
// else
// {
// if (!Load(oJson["Splits"][0], bJustCheck) || !Load(oJson["Splits"][1], bJustCheck))
// return false;
// }
// }
// else
// {
// ImwWindowManager* pWindowManager = ImwWindowManager::GetInstance();
//
// const JsonValue& oJsonCurrentWindow = oJson["CurrentWindow"];
// const JsonValue& oJsonWindows = oJson["Windows"];
// int iWindowCount = oJsonWindows.GetMemberCount();
// //Check
// if (!(oJsonCurrentWindow.IsNull() || oJsonCurrentWindow.IsInteger()))
// return false;
//
// for (int iCurrent = 0; iCurrent < iWindowCount; ++iCurrent)
// {
// const JsonValue& oJsonWindow = oJsonWindows[iCurrent];
// if (!oJsonWindow.IsObject() || !oJsonWindow["Class"].IsString())
// return false;
// if (!pWindowManager->CanCreateWindowByClassName(oJsonWindow["Class"]))
// return false;
// }
//
// if (!bJustCheck)
// {
// for (int iCurrent = 0; iCurrent < iWindowCount; ++iCurrent)
// {
// const JsonValue& oJsonWindow = oJsonWindows[iCurrent];
// ImwWindow* pWindow = pWindowManager->CreateWindowByClassName(oJsonWindow["Class"]);
// pWindow->SetParameters(oJsonWindow["Parameters"]);
// m_lWindows.push_back(pWindow);
// }
//
// if (oJsonCurrentWindow.IsInteger())
// {
// m_iActiveWindow = (int)(long)oJsonCurrentWindow;
// if (m_iActiveWindow < 0 || m_iActiveWindow >= iWindowCount)
// m_iActiveWindow = 0;
// }
// else
// {
// m_iActiveWindow = 0;
// }
// }
// }
//
// return true;
// }
//SFF_END
}
#pragma once
#include "ImwConfig.h"
#include "ImwWindow.h"
//#include "JsonValue.h"
namespace ImWindow
{
class ImwPlatformWindow;
class ImwWindowManager;
class IMGUI_API ImwContainer
{
friend class ImwPlatformWindow;
friend class ImwWindowManager;
public:
void Dock(ImwWindow* pWindow, EDockOrientation eOrientation = E_DOCK_ORIENTATION_CENTER, float fRatio = 0.5f, int iPosition = -1);
bool UnDock(ImwWindow* pWindow);
void DockToBest(ImwWindow* pWindow);
bool IsEmpty() const;
bool IsSplit() const;
bool HasWindowTabbed() const;
ImwContainer* HasWindow(const ImwWindow* pWindow);
bool FocusWindow(ImwWindow* pWindow);
ImwPlatformWindow* GetPlatformWindowParent() const;
ImwContainer* GetBestDocking(const ImVec2 oCursorPosInContainer, EDockOrientation& oOutOrientation, ImVec2& oOutAreaPos, ImVec2& oOutAreaSize, bool& bOutOnTabArea, int& iOutPosition, bool bLargeCheck);
bool HasUnclosableWindow() const;
protected:
ImwContainer(ImwContainer* pParent);
ImwContainer(ImwPlatformWindow* pParent);
~ImwContainer();
void CreateSplits();
void Paint();
//Copy of ImGui::BeginChild but with alpha support
bool BeginChildAlpha(const char* pStrId, const ImVec2& oSizeArg, float fAlpha, ImGuiWindowFlags eExtraFlags);
bool Tab(const ImwWindow* pWindow, bool bFocused, float fStartLinePos, float fEndLinePos, float fMaxSize = -1.f);
void DrawTab(const ImwChar* pText, bool bFocused, ImVec2 oPos, float fStartLinePos, float fEndLinePos, float fMaxSize = -1.f, ImVec2* pSizeOut = NULL);
float GetTabWidth(const ImwChar* pText, float fMaxSize, ImVec2* pOutTextSize = NULL);
float GetTabAreaWidth() const;
// bool Save(JsonValue& oJson);
// bool Load(const JsonValue& oJson, bool bJustCheck);
ImwContainer* m_pParent;
ImwPlatformWindow* m_pParentWindow;
ImwWindowList m_lWindows;
ImwContainer* m_pSplits[2];
float m_fSplitRatio;
bool m_bVerticalSplit;
int m_iActiveWindow;
bool m_bIsDrag;
ImVec2 m_oLastPosition;
ImVec2 m_oLastSize;
static const float c_fTabHeight;
};
}
#include "..\..\pch.h"
namespace ImWindow
{
//SFF_BEGIN
ImwMenu::ImwMenu(int iHorizontalPriority, bool bAutoDeleted)
{
m_iHorizontalPriority = iHorizontalPriority;
m_bAutoDeleted = bAutoDeleted;
ImwWindowManager::GetInstance()->AddMenu(this);
}
ImwMenu::ImwMenu(const ImwMenu& oStatusBar)
{
m_iHorizontalPriority = oStatusBar.m_iHorizontalPriority;
}
ImwMenu::~ImwMenu()
{
ImwWindowManager::GetInstance()->RemoveMenu(this);
}
int ImwMenu::GetHorizontalPriority() const
{
return m_iHorizontalPriority;
}
bool ImwMenu::IsAutoDeleted()
{
return m_bAutoDeleted;
}
//SFF_END
}
#pragma once
#include "ImwConfig.h"
namespace ImWindow
{
class IMGUI_API ImwMenu
{
public:
ImwMenu(int iHorizontalPriority = 0, bool bAutoDeleted = true);
ImwMenu(const ImwMenu& oStatusBar);
virtual ~ImwMenu();
virtual void OnMenu() = 0;
int GetHorizontalPriority() const;
bool IsAutoDeleted();
private:
int m_iHorizontalPriority;
bool m_bAutoDeleted;
};
typedef ImwList<ImwMenu*> ImwMenuList;
}
#include "..\..\pch.h"
namespace ImWindow
{
//SFF_BEGIN
ImwPlatformWindow::ImwPlatformWindow(EPlatformWindowType eType, bool bCreateContext)
{
m_eType = eType;
m_pContainer = new ImwContainer(this);
m_pContext = NULL;
m_pPreviousContext = NULL;
m_bNeedRender = false;
m_bShowContent = true;
if (bCreateContext)
{
ImGuiContext* pGlobalContext = ImGui::GetCurrentContext();
IM_ASSERT(pGlobalContext != NULL);
m_pContext = ImGui::CreateContext(pGlobalContext->IO.MemAllocFn, pGlobalContext->IO.MemFreeFn);
ImGuiIO& oGlobalIO = pGlobalContext->IO;
ImGuiIO& oNewIO = m_pContext->IO;
memcpy(&(oNewIO.KeyMap), &(oGlobalIO.KeyMap), sizeof(pGlobalContext->IO.KeyMap));
oNewIO.RenderDrawListsFn = oGlobalIO.RenderDrawListsFn;
oNewIO.GetClipboardTextFn = oGlobalIO.GetClipboardTextFn;
oNewIO.SetClipboardTextFn = oGlobalIO.SetClipboardTextFn;
oNewIO.ImeSetInputScreenPosFn = oGlobalIO.ImeSetInputScreenPosFn;
oNewIO.IniFilename = NULL;
}
}
ImwPlatformWindow::~ImwPlatformWindow()
{
ImwSafeDelete(m_pContainer);
if (m_pContext != NULL)
{
m_pContext->IO.Fonts = NULL;
SetContext(false);
ImGui::Shutdown();
RestoreContext(false);
ImGui::DestroyContext(m_pContext);
m_pContext = NULL;
}
}
bool ImwPlatformWindow::Init(MOCKUP::RENDERER::Manager& manager, ImwPlatformWindow* pParent)
{
DWORD window_style = WS_OVERLAPPEDWINDOW;
if (m_eType == E_PLATFORM_WINDOW_TYPE_DRAG_PREVIEW)
{
window_style = WS_POPUP;
}
m_pWindow = std::make_unique<MOCKUP::Window>(L"Mockup AION demotool", window_style, pParent != NULL ? pParent->m_pWindow.get() : nullptr);
m_pWindow->OnClose = std::bind(&ImwPlatformWindow::OnClose, this);
m_pWindow->OnFocus = std::bind(&ImwPlatformWindow::OnFocus, this, std::placeholders::_1);
m_pWindow->OnSize = std::bind(&ImwPlatformWindow::OnSize, this, std::placeholders::_1, std::placeholders::_2);
m_pWindow->OnMouseButton = std::bind(&ImwPlatformWindow::OnMouseButton, this, std::placeholders::_1, std::placeholders::_2);
m_pWindow->OnMouseMove = std::bind(&ImwPlatformWindow::OnMouseMove, this, std::placeholders::_1, std::placeholders::_2);
m_pWindow->OnMouseWheel = std::bind(&ImwPlatformWindow::OnMouseWheel, this, std::placeholders::_1);
m_pWindow->OnKey = std::bind(&ImwPlatformWindow::OnKey, this, std::placeholders::_1, std::placeholders::_2);
m_pWindow->OnChar = std::bind(&ImwPlatformWindow::OnChar, this, std::placeholders::_1);
if (m_eType == E_PLATFORM_WINDOW_TYPE_DRAG_PREVIEW)
{
m_pWindow->SetAlpha(128);
}
////////////////////////////////////////////////////////////////////////////////
m_pRenderer = std::make_unique<MOCKUP::RENDERER::Renderer>(manager.GetDevice(), manager.GetImmediateContext(), *m_pWindow);
m_pCommand = std::make_unique<MOCKUP::RENDERER::Command>();
m_pConstant = std::make_unique<MOCKUP::RENDERER::ConstantsLayout>(manager.GetDevice());
////////////////////////////////////////////////////////////////////////////////
m_iVertexBufferSize = IMGUI_VB_BATCH;
m_iIndexBufferSize = IMGUI_IDX_BATCH;
std::vector<D3D11_INPUT_ELEMENT_DESC> layout;
layout.push_back({ "POSITION", 0, MOCKUP::RENDERER::GetFormatFromString("DXGI_FORMAT_R32G32_FLOAT"), 0, (size_t)(&((ImDrawVert*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 });
layout.push_back({ "TEXCOORD", 0, MOCKUP::RENDERER::GetFormatFromString("DXGI_FORMAT_R32G32_FLOAT"), 0, (size_t)(&((ImDrawVert*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 });
layout.push_back({ "COLOR", 0, MOCKUP::RENDERER::GetFormatFromString("DXGI_FORMAT_R8G8B8A8_UNORM"), 0, (size_t)(&((ImDrawVert*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 });
////////////////////////////////////////////////////////////////////////////////
m_pCommand->AddCommands(manager.YieldVertexShaderCommand("editor_vsDBG", layout));
m_pCommand->AddCommands(manager.YieldPixelShaderCommand("editor_psDBG"));
m_pCommand->SetInputTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_pConstant->AddParameters(manager.YieldParametersLayout("editor_vsDBG"));
m_pConstant->AddParameters(manager.YieldParametersLayout("editor_psDBG"));
m_pCommand->SetConstantBuffers(*m_pConstant);
{
D3D11_BLEND_DESC desc = {};
desc.AlphaToCoverageEnable = false;
desc.RenderTarget[0].BlendEnable = true;
desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
m_pSavedBS = manager.GetState(desc);
m_pCommand->SetBlendState(m_pSavedBS);
}
{
D3D11_RASTERIZER_DESC desc = {};
desc.FillMode = D3D11_FILL_SOLID;
desc.CullMode = D3D11_CULL_NONE;
desc.ScissorEnable = true;
desc.DepthClipEnable = true;
auto state = manager.GetState(desc);
m_pCommand->SetRasterizerState(state);
}
{
D3D11_DEPTH_STENCIL_DESC desc = {};
desc.DepthEnable = false;
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
desc.StencilEnable = false;
desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
desc.BackFace = desc.FrontFace;
auto state = manager.GetState(desc);
m_pCommand->SetDepthStencilState(state);
}
{
D3D11_SAMPLER_DESC desc = {};
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
desc.MipLODBias = 0.f;
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
desc.MinLOD = 0.f;
desc.MaxLOD = 0.f;
auto state = manager.GetState(desc);
m_pCommand->SetSamplerState(state);
}
////////////////////////////////////////////////////////////////////////////////
SetContext(false);
ImGuiIO& io = ImGui::GetIO();
if (pParent == nullptr)
{
ImFontConfig config;
config.OversampleH = 4;
config.OversampleV = 1;
config.PixelSnapH = false;
config.SizePixels = 48.0f;
io.Fonts->AddFontDefault(&config);
DXGI_SURFACE_DESC desc;
D3D11_SUBRESOURCE_DATA data;
unsigned char* out_pixels;
int out_width;
int out_height;
io.Fonts->GetTexDataAsRGBA32(&out_pixels, &out_width, &out_height);
desc.Width = out_width;
desc.Height = out_height;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
data.pSysMem = out_pixels;
data.SysMemPitch = out_width * 4;
data.SysMemSlicePitch = 0;
m_pFonts = std::make_unique<MOCKUP::RENDERER::Texture2D>
(
manager.GetDevice(),
desc,
&data,
0,
desc.Format
);
io.Fonts->TexID = (void *)m_pFonts->GetTextureSRV();
}
////////////////////////////////////////////////////////////////////////////////
io.KeyMap[ImGuiKey_Tab] = VK_TAB;
io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN;
io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR;
io.KeyMap[ImGuiKey_PageDown] = VK_NEXT;
io.KeyMap[ImGuiKey_Home] = VK_HOME;
io.KeyMap[ImGuiKey_End] = VK_END;
io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
io.KeyMap[ImGuiKey_A] = 'A';
io.KeyMap[ImGuiKey_C] = 'C';
io.KeyMap[ImGuiKey_V] = 'V';
io.KeyMap[ImGuiKey_X] = 'X';
io.KeyMap[ImGuiKey_Y] = 'Y';
io.KeyMap[ImGuiKey_Z] = 'Z';
io.RenderDrawListsFn = NULL;
io.ImeWindowHandle = NULL;// m_pWindow->GetHandle();
io.FontGlobalScale = 0.25f;
io.MouseDrawCursor = false;
io.IniFilename = NULL;
io.LogFilename = NULL;
////////////////////////////////////////////////////////////////////////////////
ImGuiStyle& style = ImGui::GetStyle();
style.Colors[ImGuiCol_WindowBg] = ImVec4(0.1f, 0.1f, 0.1f, 1.0f);
style.Colors[ImGuiCol_ChildBg] = ImVec4(0.2f, 0.2f, 0.2f, 1.0f);
RestoreContext(false);
return true;
}
EPlatformWindowType ImwPlatformWindow::GetType() const
{
return m_eType;
}
ImVec2 ImwPlatformWindow::GetPosition() const
{
auto rect = m_pWindow->GetClientRectangle();
ClientToScreen(m_pWindow->GetHandle(), reinterpret_cast<POINT*>(&rect.left));
return ImVec2(float(rect.left), float(rect.top));
}
ImVec2 ImwPlatformWindow::GetSize() const
{
return ImVec2(float(m_pWindow->GetClientWidth()), float(m_pWindow->GetClientHeight()));
}
bool ImwPlatformWindow::IsWindowMaximized() const
{
return m_pWindow->IsWindowMaximized();
}
bool ImwPlatformWindow::IsWindowMinimized() const
{
return m_pWindow->IsWindowMinimized();
}
void ImwPlatformWindow::Show(bool bShow)
{
if (bShow)
{
m_pWindow->SetShow();
}
else
{
m_pWindow->SetHide();
}
}
void ImwPlatformWindow::SetSize(int iWidth, int iHeight)
{
m_pWindow->SetClientSize(iWidth, iHeight);
}
void ImwPlatformWindow::SetPosition(int iX, int iY)
{
m_pWindow->SetClientPosition(iX, iY);
}
void ImwPlatformWindow::SetWindowMaximized(bool bMaximized)
{
if (bMaximized)
m_pWindow->SetMaximize();
else
m_pWindow->SetRestore();
}
void ImwPlatformWindow::SetWindowMinimized()
{
m_pWindow->SetMinimize();
}
void ImwPlatformWindow::SetTitle(const char* pTtile)
{
std::string title(pTtile);
m_pWindow->SetTitle(std::wstring(title.cbegin(), title.cend()));
}
bool ImwPlatformWindow::IsShowContent() const
{
return m_bShowContent;
}
void ImwPlatformWindow::SetShowContent(bool bShow)
{
m_bShowContent = bShow;
}
void ImwPlatformWindow::SetClipCursor(int iMinX, int iMinY, int iMaxX, int iMaxY)
{
m_pWindow->SetClipCursor(iMinX, iMinY, iMaxX, iMaxY);
}
void ImwPlatformWindow::RemoveClipCursor()
{
m_pWindow->SetClipCursor();
}
void ImwPlatformWindow::OnClose()
{
ImwWindowManager::GetInstance()->OnClosePlatformWindow(this);
}
void ImwPlatformWindow::OnFocus(bool bHasFocus)
{
if (!bHasFocus)
{
OnLoseFocus();
}
}
void ImwPlatformWindow::OnSize(int iWidth, int iHeight)
{
UNREFERENCED_PARAMETER(iWidth);
UNREFERENCED_PARAMETER(iHeight);
m_pRenderer->Resize();
}
void ImwPlatformWindow::OnMouseButton(int iButton, bool bDown)
{
m_pContext->IO.MouseDown[iButton] = bDown;
}
void ImwPlatformWindow::OnMouseMove(int iX, int iY)
{
if (m_pWindow->IsCursorClip())
{
POINT mouse;
mouse.x = iX;
mouse.y = iY;
POINT teleport;
teleport.x = iX;
teleport.y = iY;
auto clip = m_pWindow->GetClientCursorClip();
const int posMargin = 3;
if (mouse.x < clip.left + posMargin)
{
teleport.x = clip.right - (2 * posMargin);
}
if (mouse.y < clip.top + posMargin)
{
teleport.y = clip.bottom - (2 * posMargin);
}
if (mouse.x > clip.right - posMargin)
{
teleport.x = clip.left + (2 * posMargin);
}
if (mouse.y > clip.bottom - posMargin)
{
teleport.y = clip.top + (2 * posMargin);
}
if (mouse.x != teleport.x || mouse.y != teleport.y)
{
m_pWindow->SetMousePos(teleport.x, teleport.y);
m_pContext->IO.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
}
else
{
m_pContext->IO.MousePos = ImVec2((float)iX, (float)iY);
}
}
else
{
m_pContext->IO.MousePos = ImVec2((float)iX, (float)iY);
}
}
void ImwPlatformWindow::OnMouseWheel(int iStep)
{
m_pContext->IO.MouseWheel += iStep;
}
void ImwPlatformWindow::OnKey(int eKey, bool bDown)
{
m_pContext->IO.KeysDown[eKey] = bDown;
}
void ImwPlatformWindow::OnChar(int iChar)
{
m_pContext->IO.AddInputCharacter((ImwChar)iChar);
}
// bool ImwPlatformWindow::Save(JsonValue& oJson)
// {
// oJson["Width"] = (long)GetSize().x;
// oJson["Height"] = (long)GetSize().y;
// oJson["Left"] = (long)GetPosition().x;
// oJson["Top"] = (long)GetPosition().y;
// oJson["Maximized"] = IsWindowMaximized();
//
// return m_pContainer->Save(oJson["Container"]);
// bool ImwPlatformWindow::Load(const JsonValue& oJson, bool bJustCheck)
// {
// if (!oJson["Width"].IsNumeric() || !oJson["Height"].IsNumeric() || !oJson["Left"].IsNumeric() || !oJson["Top"].IsNumeric() || !oJson["Maximized"].IsBoolean())
// return false;
//
// if (!bJustCheck)
// {
// SetSize((long)oJson["Width"], (long)oJson["Height"]);
// SetPosition((long)oJson["Left"], (long)oJson["Top"]);
// SetWindowMaximized(oJson["Maximized"]);
// }
//
// return m_pContainer->Load(oJson["Container"], bJustCheck);
// }
static bool s_bContextPushed = false;
bool ImwPlatformWindow::IsContextSet()
{
return s_bContextPushed;
}
bool ImwPlatformWindow::HasContext() const
{
return m_pContext != NULL;
}
void ImwPlatformWindow::SetContext(bool bCopyStyle)
{
IM_ASSERT(s_bContextPushed == false);
s_bContextPushed = true;
if (m_pContext != NULL)
{
IM_ASSERT(m_pPreviousContext == NULL);
m_pPreviousContext = ImGui::GetCurrentContext();
ImGui::SetCurrentContext(m_pContext);
if (bCopyStyle)
{
//Copy style from Global context
memcpy(&(m_pContext->Style), &(m_pPreviousContext->Style), sizeof(ImGuiStyle));
}
}
}
void ImwPlatformWindow::RestoreContext(bool bCopyStyle)
{
IM_ASSERT(s_bContextPushed == true);
s_bContextPushed = false;
if (m_pContext != NULL)
{
IM_ASSERT(m_pPreviousContext != NULL);
if (bCopyStyle)
{
//Copy style to Global context
memcpy(&(m_pPreviousContext->Style), &(m_pContext->Style), sizeof(ImGuiStyle));
}
ImGui::SetCurrentContext(m_pPreviousContext);
m_pPreviousContext = NULL;
}
}
void ImwPlatformWindow::RenderDrawList(MOCKUP::RENDERER::Manager& manager, ImDrawData* pDrawData)
{
if (!m_pVertexBuffer || m_iVertexBufferSize < static_cast<decltype(m_iVertexBufferSize)>(pDrawData->TotalVtxCount))
{
m_iVertexBufferSize = pDrawData->TotalVtxCount + (IMGUI_VB_BATCH >> 1);
m_pVertexBuffer = std::make_unique<MOCKUP::RENDERER::VertexBuffer<ImDrawVert>>(manager.GetDevice(), nullptr, m_iVertexBufferSize);
}
////////////////////////////////////////////////////////////////////////////////
if (!m_pIndexBuffer || m_iIndexBufferSize < static_cast<decltype(m_iIndexBufferSize)>(pDrawData->TotalIdxCount))
{
m_iIndexBufferSize = pDrawData->TotalIdxCount + (IMGUI_IDX_BATCH >> 1);
m_pIndexBuffer = std::make_unique<MOCKUP::RENDERER::IndexBuffer<ImDrawIdx>>(manager.GetDevice(), nullptr, m_iIndexBufferSize);
}
auto context = manager.GetImmediateContext();
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
if (context->Map(m_pVertexBuffer->GetVertexBuffer(), 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
{
return;
}
if (context->Map(m_pIndexBuffer->GetIndexBuffer(), 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
{
return;
}
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
for (int n = 0; n < pDrawData->CmdListsCount; n++)
{
const ImDrawList* cmd_list = pDrawData->CmdLists[n];
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vtx_dst += cmd_list->VtxBuffer.Size;
idx_dst += cmd_list->IdxBuffer.Size;
}
context->Unmap(m_pVertexBuffer->GetVertexBuffer(), 0);
context->Unmap(m_pIndexBuffer->GetIndexBuffer(), 0);
////////////////////////////////////////////////////////////////////////////////
float L = 0.0f;
float R = ImGui::GetIO().DisplaySize.x;
float B = ImGui::GetIO().DisplaySize.y;
float T = 0.0f;
float mvp[16] =
{
2.0f / (R - L), 0.0f, 0.0f, 0.0f,
0.0f, 2.0f / (T - B), 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
(R + L) / (L - R), (T + B) / (B - T), 0.5f, 1.0f
};
DirectX::XMMATRIX temp(mvp);
m_pConstant->SetParamaterValue("Projection", &temp);
m_pConstant->Update(context);
////////////////////////////////////////////////////////////////////////////////
D3D11_VIEWPORT vp;
vp.TopLeftX = 0.0f;
vp.TopLeftY = 0.0f;
vp.Width = ImGui::GetIO().DisplaySize.x;
vp.Height = ImGui::GetIO().DisplaySize.y;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
context->RSSetViewports(1, &vp);
m_pCommand->ExecuteCommandsList(context);
{
MOCKUP::RENDERER::Command command;
command.SetVertexBuffer(*m_pVertexBuffer, 0, 0);
command.SetIndexBuffer(*m_pIndexBuffer, 0);
command.ExecuteCommandsList(context);
}
// Render command lists
int vtx_offset = 0;
int idx_offset = 0;
bool bring_back = false;
for (int n = 0; n < pDrawData->CmdListsCount; n++)
{
const ImDrawList* cmd_list = pDrawData->CmdLists[n];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
if (bring_back)
{
context->OMSetBlendState(m_pSavedBS, nullptr, 0xFFFFFFFF);
bring_back = false;
}
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback)
{
pcmd->UserCallback(cmd_list, pcmd);
}
else
{
if (pcmd->TextureId && (ImGui::GetIO().Fonts->TexID != pcmd->TextureId))
{
context->OMSetBlendState(nullptr, nullptr, 0xFFFFFFFF);
bring_back = true;
}
const D3D11_RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w };
context->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&pcmd->TextureId);
context->RSSetScissorRects(1, &r);
context->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset);
}
idx_offset += pcmd->ElemCount;
}
vtx_offset += cmd_list->VtxBuffer.Size;
}
}
void ImwPlatformWindow::OnLoseFocus()
{
if (NULL != m_pContext)
{
m_pContext->NextWindowData.Clear();
m_pContext->ActiveId = 0;
for (int i = 0; i < 512; ++i)
m_pContext->IO.KeysDown[i] = false;
for (int i = 0; i < 5; ++i)
m_pContext->IO.MouseDown[i] = false;
m_pContext->IO.KeyAlt = false;
m_pContext->IO.KeyCtrl = false;
m_pContext->IO.KeyShift = false;
}
}
void ImwPlatformWindow::PreUpdate()
{
m_pWindow->Update();
ImGuiIO& oIO = m_pContext->IO;
oIO.KeyCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
oIO.KeyShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0;
oIO.KeyAlt = (GetKeyState(VK_MENU) & 0x8000) != 0;
oIO.KeySuper = false;
if (oIO.MouseDrawCursor)
{
m_pWindow->SetMouseCursor(NULL);
}
else if (oIO.MousePos.x != -FLT_MAX && oIO.MousePos.y != -FLT_MAX)
{
switch (m_pContext->MouseCursor)
{
case ImGuiMouseCursor_Arrow:
m_pWindow->SetMouseCursor(LoadCursor(NULL, IDC_ARROW));
break;
case ImGuiMouseCursor_TextInput: // When hovering over InputText, etc.
m_pWindow->SetMouseCursor(LoadCursor(NULL, IDC_IBEAM));
break;
case ImGuiMouseCursor_Move: // Unused
m_pWindow->SetMouseCursor(LoadCursor(NULL, IDC_HAND));
break;
case ImGuiMouseCursor_ResizeNS: // Unused
m_pWindow->SetMouseCursor(LoadCursor(NULL, IDC_SIZENS));
break;
case ImGuiMouseCursor_ResizeEW: // When hovering over a column
m_pWindow->SetMouseCursor(LoadCursor(NULL, IDC_SIZEWE));
break;
case ImGuiMouseCursor_ResizeNESW: // Unused
m_pWindow->SetMouseCursor(LoadCursor(NULL, IDC_SIZENESW));
break;
case ImGuiMouseCursor_ResizeNWSE: // When hovering over the bottom-right corner of a window
m_pWindow->SetMouseCursor(LoadCursor(NULL, IDC_SIZENWSE));
break;
}
}
}
void ImwPlatformWindow::Render(MOCKUP::RENDERER::Manager& manager)
{
if (m_bNeedRender)
{
m_bNeedRender = false;
SetContext(false);
m_pRenderer->Prepare();
ImVec2 oSize = ImVec2(float(m_pWindow->GetClientWidth()), float(m_pWindow->GetClientHeight()));
ImGui::GetIO().DisplaySize = oSize;
ImGui::Render();
RenderDrawList(manager, ImGui::GetDrawData());
m_pRenderer->Present();
RestoreContext(false);
}
}
void ImwPlatformWindow::Dock(ImwWindow* pWindow)
{
m_pContainer->Dock(pWindow);
}
bool ImwPlatformWindow::UnDock(ImwWindow* pWindow)
{
return m_pContainer->UnDock(pWindow);
}
ImwContainer* ImwPlatformWindow::GetContainer()
{
return m_pContainer;
}
ImwContainer* ImwPlatformWindow::HasWindow(ImwWindow* pWindow)
{
return m_pContainer->HasWindow(pWindow);
}
bool ImwPlatformWindow::FocusWindow(ImwWindow* pWindow)
{
return m_pContainer->FocusWindow(pWindow);
}
void ImwPlatformWindow::PaintContainer()
{
m_pContainer->Paint();
}
//SFF_END
}
#pragma once
#include "ImwConfig.h"
#include "ImwContainer.h"
//#include "JsonValue.h"
#include <functional>
namespace ImWindow
{
enum EPlatformWindowType
{
E_PLATFORM_WINDOW_TYPE_MAIN,
E_PLATFORM_WINDOW_TYPE_SECONDARY,
E_PLATFORM_WINDOW_TYPE_DRAG_PREVIEW,
E_PLATFORM_WINDOW_TYPE_DIALOG_BOX
};
class IMGUI_API ImwPlatformWindow
{
friend class ImwWindowManager;
public:
ImwPlatformWindow(EPlatformWindowType eType, bool bCreateContext);
virtual ~ImwPlatformWindow();
bool Init(MOCKUP::RENDERER::Manager& manager, ImwPlatformWindow* pParent);
EPlatformWindowType GetType() const;
ImVec2 GetPosition() const;
ImVec2 GetSize() const;
bool IsWindowMaximized() const;
bool IsWindowMinimized() const;
void Show(bool bShow);
void SetSize(int iWidth, int iHeight);
void SetPosition(int iX, int iY);
void SetWindowMaximized(bool bMaximized);
void SetWindowMinimized();
void SetTitle(const char* pTtile);
bool IsShowContent() const;
void SetShowContent(bool bShow);
void SetClipCursor(int iMinX, int iMinY, int iMaxX, int iMaxY);
void RemoveClipCursor();
void Dock(ImwWindow* pWindow);
bool UnDock(ImwWindow* pWindow);
ImwContainer* GetContainer();
ImwContainer* HasWindow(ImwWindow* pWindow);
bool FocusWindow(ImwWindow* pWindow);
bool HasContext() const;
void SetContext(bool bCopyStyle);
void RestoreContext(bool bCopyStyle);
static bool IsContextSet();
////////////////////////////////////////////////////////////////////////////////
void OnClose();
void OnFocus(bool bHasFocus);
void OnSize(int iWidth, int iHeight);
void OnMouseButton(int iButton, bool bDown);
void OnMouseMove(int iX, int iY);
void OnMouseWheel(int iStep);
void OnKey(int eKey, bool bDown);
void OnChar(int iChar);
private:
void RenderDrawList(MOCKUP::RENDERER::Manager& manager, ImDrawData* pDrawData);
void OnLoseFocus();
void PreUpdate();
void Render(MOCKUP::RENDERER::Manager& manager);
void PaintContainer();
// bool Save(JsonValue& oJson);
// bool Load(const JsonValue& oJson, bool bJustCheck);
EPlatformWindowType m_eType;
ImwContainer* m_pContainer;
ImGuiContext* m_pContext;
ImGuiContext* m_pPreviousContext;
bool m_bNeedRender;
bool m_bShowContent;
////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<MOCKUP::Window> m_pWindow;
std::unique_ptr<MOCKUP::RENDERER::Renderer> m_pRenderer;
////////////////////////////////////////////////////////////////////////////////
uint32_t m_iVertexBufferSize;
uint32_t m_iIndexBufferSize;
std::unique_ptr<MOCKUP::RENDERER::VertexBuffer<ImDrawVert>> m_pVertexBuffer;
std::unique_ptr<MOCKUP::RENDERER::IndexBuffer<ImDrawIdx>> m_pIndexBuffer;
std::unique_ptr<MOCKUP::RENDERER::Texture2D> m_pFonts;
std::unique_ptr<MOCKUP::RENDERER::Command> m_pCommand;
std::unique_ptr<MOCKUP::RENDERER::ConstantsLayout> m_pConstant;
ID3D11BlendState* m_pSavedBS;
////////////////////////////////////////////////////////////////////////////////
};
typedef ImwList<ImwPlatformWindow*> ImwPlatformWindowList;
}
#include "..\..\pch.h"
namespace ImWindow
{
//SFF_BEGIN
ImwStatusBar::ImwStatusBar(int iHorizontalPriority, bool bAutoDeleted)
{
m_iHorizontalPriority = iHorizontalPriority;
m_bAutoDeleted = bAutoDeleted;
ImwWindowManager::GetInstance()->AddStatusBar(this);
}
ImwStatusBar::ImwStatusBar(const ImwStatusBar& oStatusBar)
{
m_iHorizontalPriority = oStatusBar.m_iHorizontalPriority;
}
ImwStatusBar::~ImwStatusBar()
{
ImwWindowManager::GetInstance()->RemoveStatusBar(this);
}
void ImwStatusBar::OnStatusBar()
{
}
int ImwStatusBar::GetHorizontalPriority() const
{
return m_iHorizontalPriority;
}
bool ImwStatusBar::IsAutoDeleted()
{
return m_bAutoDeleted;
}
//SFF_END
}
#pragma once
#include "ImwConfig.h"
namespace ImWindow
{
class IMGUI_API ImwStatusBar
{
public:
ImwStatusBar(int iHorizontalPriority = 0, bool bAutoDeleted = true);
ImwStatusBar(const ImwStatusBar& oStatusBar);
virtual ~ImwStatusBar();
virtual void OnStatusBar();
int GetHorizontalPriority() const;
bool IsAutoDeleted();
private:
int m_iHorizontalPriority;
bool m_bAutoDeleted;
};
typedef ImwList<ImwStatusBar*> ImwStatusBarList;
}
#include "..\..\pch.h"
namespace ImWindow
{
//SFF_BEGIN
ImwToolBar::ImwToolBar(int iHorizontalPriority, bool bAutoDeleted)
{
m_iHorizontalPriority = iHorizontalPriority;
m_bAutoDeleted = bAutoDeleted;
ImwWindowManager::GetInstance()->AddToolBar(this);
}
ImwToolBar::ImwToolBar(const ImwToolBar& oToolBar)
{
m_iHorizontalPriority = oToolBar.m_iHorizontalPriority;
}
ImwToolBar::~ImwToolBar()
{
ImwWindowManager::GetInstance()->RemoveToolBar(this);
}
void ImwToolBar::Destroy()
{
ImwWindowManager::GetInstance()->DestroyToolBar(this);
}
int ImwToolBar::GetHorizontalPriority() const
{
return m_iHorizontalPriority;
}
bool ImwToolBar::IsAutoDeleted()
{
return m_bAutoDeleted;
}
//SFF_END
}
#pragma once
#include "ImwConfig.h"
namespace ImWindow
{
class IMGUI_API ImwToolBar
{
public:
ImwToolBar(int iHorizontalPriority = 0, bool bAutoDeleted = true);
ImwToolBar(const ImwToolBar& oToolBar);
virtual ~ImwToolBar();
void Destroy();
virtual void OnToolBar() = 0;
int GetHorizontalPriority() const;
bool IsAutoDeleted();
private:
int m_iHorizontalPriority;
bool m_bAutoDeleted;
};
typedef ImwList<ImwToolBar*> ImwToolBarList;
}
#include "..\..\pch.h"
namespace ImWindow
{
//SFF_BEGIN
int ImwWindow::s_iNextId = 0;
#ifdef IMW_CUSTOM_IMPLEMENT_IMWWINDOW
IMW_CUSTOM_IMPLEMENT_IMWWINDOW
#endif //IMW_CUSTOM_IMPLEMENT_IMWWINDOW
ImwWindow::ImwWindow()
{
m_pTitle = NULL;
m_bClosable = true;
m_bAlone = false;
m_bFillingSpace = false;
m_iId = s_iNextId++;
//Write Id to string
int iIndex = 0;
int iNumber = m_iId;
do
{
m_pId[iIndex++] = iNumber % 10 + '0';
}
while ((iNumber /= 10) > 0 && iIndex <= 10);
m_pId[iIndex] = '\0';
ImwWindowManager::GetInstance()->AddWindow(this);
}
ImwWindow::~ImwWindow()
{
ImwWindowManager::GetInstance()->RemoveWindow(this);
ImwSafeFree(m_pTitle);
}
void ImwWindow::OnContextMenu()
{
}
bool ImwWindow::IsFillingSpace() const
{
return m_bFillingSpace;
}
void ImwWindow::SetFillingSpace(bool bFilling)
{
m_bFillingSpace = bFilling;
}
// void ImwWindow::GetParameters(JsonValue& /*oOutParameters*/)
// {
// }
//
// void ImwWindow::SetParameters(const JsonValue& /*oParameters*/)
// {
// }
ImU32 ImwWindow::GetId() const
{
return m_iId;
}
const ImwChar* ImwWindow::GetIdStr() const
{
return m_pId;
}
void ImwWindow::Destroy()
{
ImwWindowManager::GetInstance()->DestroyWindow(this);
}
void ImwWindow::SetTitle(const ImwChar* pTitle)
{
ImwSafeFree(m_pTitle);
if (NULL != pTitle)
{
size_t iLen = strlen(pTitle) + 1;
m_pTitle = (ImwChar*)ImwMalloc(sizeof(ImwChar) * iLen);
strcpy_s(m_pTitle, iLen, pTitle);
}
}
const ImwChar* ImwWindow::GetTitle() const
{
return m_pTitle;
}
void ImwWindow::SetClosable( bool bClosable )
{
m_bClosable = bClosable;
}
bool ImwWindow::IsClosable() const
{
return m_bClosable;
}
void ImwWindow::SetAlone(bool bAlone)
{
m_bAlone = bAlone;
}
bool ImwWindow::IsAlone() const
{
return m_bAlone;
}
const ImVec2& ImwWindow::GetLastPosition() const
{
return m_oLastPosition;
}
const ImVec2& ImwWindow::GetLastSize() const
{
return m_oLastSize;
}
//SFF_END
}
#pragma once
#include "ImwConfig.h"
namespace ImWindow
{
enum EDockOrientation
{
E_DOCK_ORIENTATION_CENTER,
//E_DOCK_ORIENTATION_TABBED = E_DOCK_ORIENTATION_CENTER,
E_DOCK_ORIENTATION_TOP,
E_DOCK_ORIENTATION_LEFT,
E_DOCK_ORIENTATION_RIGHT,
E_DOCK_ORIENTATION_BOTTOM,
};
class IMGUI_API ImwWindow
{
friend class ImwWindowManager;
friend class ImwContainer;
protected:
ImwWindow();
virtual ~ImwWindow();
public:
virtual void OnGui() = 0;
virtual void OnContextMenu();
bool IsFillingSpace() const;
void SetFillingSpace(bool bFilling);
// virtual void GetParameters(JsonValue& oOutParameters);
// virtual void SetParameters(const JsonValue& oParameters);
ImU32 GetId() const;
const ImwChar* GetIdStr() const;
void Destroy();
void SetTitle(const ImwChar* pTitle);
const ImwChar* GetTitle() const;
void SetClosable( bool bClosable );
bool IsClosable() const;
void SetAlone( bool bAlone );
bool IsAlone() const;
const ImVec2& GetLastPosition() const;
const ImVec2& GetLastSize() const;
protected:
ImwChar* m_pTitle;
ImU32 m_iId;
ImwChar m_pId[11];
bool m_bClosable;
bool m_bAlone;
bool m_bFillingSpace;
ImVec2 m_oLastPosition;
ImVec2 m_oLastSize;
static int s_iNextId;
};
typedef ImwList<ImwWindow*> ImwWindowList;
}
#include "..\..\pch.h"
namespace ImWindow
{
//SFF_BEGIN
ImwWindowManager::PlatformWindowAction::PlatformWindowAction(ImwPlatformWindow* pPlatformWindow, EPlatformWindowAction eAction, ImVec2 oValue)
{
m_pPlatformWindow = pPlatformWindow;
m_eAction = eAction;
m_oValue = oValue;
}
//////////////////////////////////////////////////////////////////////////
ImwWindowManager::DrawWindowAreaAction::DrawWindowAreaAction( ImwPlatformWindow* pWindow, const ImVec2& oRectPos, const ImVec2& oRectSize, const ImColor& oColor )
: m_oColor( oColor )
{
m_pWindow = pWindow;
m_oRectPos = oRectPos;
m_oRectSize = oRectSize;
}
ImwWindowManager* ImwWindowManager::s_pInstance = 0;
//////////////////////////////////////////////////////////////////////////
ImwWindowManager::Config::Config()
: m_fDragMarginRatio( 0.1f )
, m_fDragMarginSizeRatio( 0.25f )
, m_oHightlightAreaColor( 0.f, 0.5f, 1.f, 0.5f )
, m_eTabColorMode( E_TABCOLORMODE_BACKGROUND )
, m_bVisibleDragger( false )
, m_bShowTabBorder( false )
, m_bShowTabShadows( false )
, m_oTabColorNormal( 50, 50, 50, 255 )
, m_oTabColorActive( 37, 37, 37, 255 )
, m_oTabColorBorder( 72, 72, 72, 255 )
, m_fTabOverlap( 15.f )
, m_fTabSlopWidth( 30.f )
, m_fTabSlopP1Ratio( 0.6f )
, m_fTabSlopP2Ratio( 0.4f )
, m_fTabSlopHRatio( 0.f )
, m_fTabShadowDropSize( 15.f )
, m_fTabShadowSlopRatio( 0.6f )
, m_fTabShadowAlpha( 0.75f )
, m_oStatusBarWindowPadding( 4.f, 4.f )
, m_oStatusBarFramePadding( 4.f, 2.f )
{
}
//////////////////////////////////////////////////////////////////////////
ImwWindowManager::ImwWindowManager()
{
s_pInstance = this;
m_pMainPlatformWindow = NULL;
m_pDragPlatformWindow = NULL;
m_pCurrentPlatformWindow = NULL;
m_pDraggedWindow = NULL;
m_pDragBestContainer = NULL;
m_bDragOnTab = false;
m_iDragBestContainerPosition = -1;
m_oDragPreviewOffset = ImVec2(-20, -10);
m_bHasWantCaptureKeyboard = false;
m_bHasWantCaptureMouse = false;
}
ImwWindowManager::~ImwWindowManager()
{
Destroy();
s_pInstance = 0;
}
bool ImwWindowManager::Init(MOCKUP::RENDERER::Manager& manager)
{
IM_ASSERT(m_pCurrentPlatformWindow == NULL);
m_pMainPlatformWindow = new ImwPlatformWindow(E_PLATFORM_WINDOW_TYPE_MAIN, true);
if (m_pMainPlatformWindow && m_pMainPlatformWindow->Init(manager, nullptr))
{
m_pMainPlatformWindow->Show(true);
m_pDragPlatformWindow = new ImwPlatformWindow(E_PLATFORM_WINDOW_TYPE_DRAG_PREVIEW, true);
if (!m_pDragPlatformWindow || !m_pDragPlatformWindow->Init(manager, m_pMainPlatformWindow))
{
delete m_pDragPlatformWindow;
m_pDragPlatformWindow = nullptr;
delete m_pMainPlatformWindow;
m_pMainPlatformWindow = nullptr;
}
else
{
return true;
}
}
else
{
delete m_pMainPlatformWindow;
m_pMainPlatformWindow = nullptr;
}
return false;
}
void ImwWindowManager::Destroy()
{
if (m_pCurrentPlatformWindow != NULL)
{
if(m_pMainPlatformWindow != NULL)
m_lPlatformWindowActions.push_back(new PlatformWindowAction(m_pMainPlatformWindow, E_PLATFORM_WINDOW_ACTION_DESTROY));
}
else
{
while (m_lMenus.begin() != m_lMenus.end())
{
ImwMenu* pMenu = m_lMenus.back();
if (pMenu->IsAutoDeleted())
delete pMenu;
else
m_lMenus.pop_back();
}
while (m_lStatusBars.begin() != m_lStatusBars.end())
{
ImwStatusBar* pStatusBar = m_lStatusBars.back();
if (pStatusBar->IsAutoDeleted())
delete pStatusBar;
else
m_lStatusBars.pop_back();
}
while (m_lToolBars.begin() != m_lToolBars.end())
{
ImwToolBar* pToolBar = m_lToolBars.back();
if (pToolBar->IsAutoDeleted())
delete pToolBar;
else
m_lToolBars.pop_back();
}
ImwSafeDelete(m_pDragPlatformWindow);
while (m_lPlatformWindows.begin() != m_lPlatformWindows.end())
{
delete *m_lPlatformWindows.begin();
m_lPlatformWindows.erase(m_lPlatformWindows.begin());
}
ImwSafeDelete(m_pMainPlatformWindow);
}
}
ImwPlatformWindow* ImwWindowManager::GetMainPlatformWindow() const
{
return m_pMainPlatformWindow;
}
const ImwPlatformWindowList& ImwWindowManager::GetSecondariesPlatformWindows() const
{
return m_lPlatformWindows;
}
ImwWindowManager::Config& ImwWindowManager::GetConfig()
{
return m_oConfig;
}
void ImwWindowManager::SetMainTitle(const ImwChar* pTitle)
{
ImwIsSafe(m_pMainPlatformWindow)->SetTitle(pTitle);
}
void ImwWindowManager::UnDock(ImwWindow* pWindow)
{
DockAction* pAction = new DockAction();
pAction->m_bFloat = false;
pAction->m_pWindow = pWindow;
pAction->m_pWith = NULL;
pAction->m_eOrientation = E_DOCK_ORIENTATION_CENTER;
pAction->m_pToPlatformWindow = NULL;
pAction->m_pToContainer = NULL;
pAction->m_iPosition = -1;
m_lDockActions.push_back(pAction);
}
void ImwWindowManager::Dock(ImwWindow* pWindow, EDockOrientation eOrientation, float fRatio, ImwPlatformWindow* pToPlatformWindow)
{
DockAction* pAction = new DockAction();
pAction->m_bFloat = false;
pAction->m_pWindow = pWindow;
pAction->m_pWith = NULL;
pAction->m_eOrientation = eOrientation;
pAction->m_pToPlatformWindow = (pToPlatformWindow != NULL) ? pToPlatformWindow : m_pMainPlatformWindow;
pAction->m_pToContainer = NULL;
pAction->m_iPosition = -1;
pAction->m_fRatio = fRatio;
m_lDockActions.push_back(pAction);
}
void ImwWindowManager::DockTo(ImwWindow* pWindow, EDockOrientation eOrientation, float fRatio, ImwContainer* pContainer, int iPosition)
{
IM_ASSERT(NULL != pContainer);
if (NULL != pContainer)
{
DockAction* pAction = new DockAction();
pAction->m_bFloat = false;
pAction->m_pWindow = pWindow;
pAction->m_pWith = NULL;
pAction->m_eOrientation = eOrientation;
pAction->m_pToPlatformWindow = NULL;
pAction->m_pToContainer = pContainer;
pAction->m_iPosition = iPosition;
pAction->m_fRatio = fRatio;
m_lDockActions.push_back(pAction);
}
}
void ImwWindowManager::DockWith(ImwWindow* pWindow, ImwWindow* pWithWindow, EDockOrientation eOrientation, float fRatio)
{
DockAction* pAction = new DockAction();
pAction->m_bFloat = false;
pAction->m_pWindow = pWindow;
pAction->m_pWith = pWithWindow;
pAction->m_eOrientation = eOrientation;
pAction->m_fRatio = fRatio;
m_lDockActions.push_back(pAction);
}
void ImwWindowManager::Float(ImwWindow* pWindow, const ImVec2& oPosition, const ImVec2& oSize)
{
DockAction* pAction = new DockAction();
pAction->m_bFloat = true;
pAction->m_pWindow = pWindow;
pAction->m_oPosition = oPosition;
pAction->m_oSize = oSize;
m_lDockActions.push_back(pAction);
}
void ImwWindowManager::FocusWindow(ImwWindow* pWindow)
{
if (!m_pMainPlatformWindow->FocusWindow(pWindow))
{
for (ImwList<ImwPlatformWindow*>::iterator it = m_lPlatformWindows.begin(); it != m_lPlatformWindows.end(); ++it)
{
if ((*it)->FocusWindow(pWindow))
break;
}
}
}
const ImwWindowList& ImwWindowManager::GetWindowList() const
{
return m_lWindows;
}
ImwPlatformWindow* ImwWindowManager::GetCurrentPlatformWindow()
{
return m_pCurrentPlatformWindow;
}
ImwPlatformWindow* ImwWindowManager::GetWindowParent(ImwWindow* pWindow)
{
ImwContainer* pContainer = m_pMainPlatformWindow->HasWindow(pWindow);
if (NULL != pContainer)
{
return m_pMainPlatformWindow;
}
for ( ImwList<ImwPlatformWindow*>::iterator it = m_lPlatformWindows.begin(); it != m_lPlatformWindows.end(); ++it )
{
pContainer = (*it)->HasWindow(pWindow);
if (NULL != pContainer)
{
return *it;
}
}
IM_ASSERT(false);
return NULL;
}
void ImwWindowManager::MaximizeCurrentPlatformWindow()
{
if (m_pCurrentPlatformWindow != NULL)
m_lPlatformWindowActions.push_back(new PlatformWindowAction(m_pCurrentPlatformWindow, E_PLATFORM_WINDOW_ACTION_MAXIMIZE));
}
void ImwWindowManager::MinimizeCurrentPlatformWindow()
{
if (m_pCurrentPlatformWindow != NULL)
m_lPlatformWindowActions.push_back(new PlatformWindowAction(m_pCurrentPlatformWindow, E_PLATFORM_WINDOW_ACTION_MINIMIZE));
}
void ImwWindowManager::RestoreCurrentPlatformWindow()
{
if (m_pCurrentPlatformWindow != NULL)
m_lPlatformWindowActions.push_back(new PlatformWindowAction(m_pCurrentPlatformWindow, E_PLATFORM_WINDOW_ACTION_RESTORE));
}
// bool ImwWindowManager::SaveLayoutToString(ImwString& sLayout, bool bCompact)
// {
// JsonValue oJson;
// oJson.InitType(JsonValue::E_TYPE_OBJECT);
//
// if ( m_pMainPlatformWindow->Save(oJson["MainPlatformWindow"]) )
// {
// JsonValue& oJsonPlatformWindows = oJson["PlatformWindows"];
// int iCurrent = 0;
// for (ImwList<ImwPlatformWindow*>::iterator it = m_lPlatformWindows.begin(); it != m_lPlatformWindows.end(); ++it)
// {
// if ( !(*it)->Save(oJsonPlatformWindows[iCurrent++]) )
// return false;
// }
//
// sLayout.clear();
// oJson.WriteString(sLayout, bCompact);
// return true;
// }
// return false;
// }
// bool ImwWindowManager::SaveLayoutToFile(const ImwChar* pFilePath, bool bCompact)
// {
// FILE* pFile = fopen(pFilePath, "w");
// if (pFile != NULL)
// {
// ImwString sLayout;
// bool bSaved = SaveLayoutToString(sLayout, bCompact);
// if ( bSaved )
// {
// fwrite(sLayout.c_str(), 1, sLayout.size(), pFile);
// }
// fclose(pFile);
// return bSaved;
// }
// return false;
// }
// bool ImwWindowManager::LoadLayoutFromString(const ImwChar* pLayout)
// {
// JsonValue oJson;
// if (oJson.ReadString(pLayout) == 0 && oJson.IsObject())
// {
// JsonValue& oJsonMainPlatformWindow = oJson["MainPlatformWindow"];
// JsonValue& oJsonPlatformWindows = oJson["PlatformWindows"];
//
// //Check layout integrity
// if (!oJsonMainPlatformWindow.IsObject() || !m_pMainPlatformWindow->Load(oJsonMainPlatformWindow, true))
// return false;
//
// if (!oJsonPlatformWindows.IsArray() && !oJsonPlatformWindows.IsNull())
// return false;
//
// int iPlatformWindowCount = oJsonPlatformWindows.GetMemberCount();
// for (int iCurrent = 0; iCurrent < iPlatformWindowCount; ++iCurrent)
// {
// JsonValue& oJsonPlatformWindow = oJsonPlatformWindows[iCurrent];
// if (!oJsonPlatformWindow.IsObject() || !m_pMainPlatformWindow->Load(oJsonPlatformWindow, true))
// return false;
// }
//
// //Load layout
// if (!m_pMainPlatformWindow->Load(oJsonMainPlatformWindow, false))
// return false; //Something wrong
//
// while (m_lPlatformWindows.begin() != m_lPlatformWindows.end())
// {
// ImwPlatformWindow* pPlatformWindow = *m_lPlatformWindows.begin();
// m_lPlatformWindows.remove(pPlatformWindow);
// delete pPlatformWindow;
// }
//
// for (int iCurrent = 0; iCurrent < iPlatformWindowCount; ++iCurrent)
// {
// JsonValue& oJsonPlatformWindow = oJsonPlatformWindows[iCurrent];
// ImwPlatformWindow* pNewPlatformWindow = CreatePlatformWindow(E_PLATFORM_WINDOW_TYPE_SECONDARY, m_pMainPlatformWindow);
// m_lPlatformWindows.push_back(pNewPlatformWindow);
// pNewPlatformWindow->Show(true);
// if (!pNewPlatformWindow->Load(oJsonPlatformWindow, false))
// return false; //Something wrong
// }
//
// m_lOrphanWindows.clear();
//
// return true;
// }
// return false;
// }
// bool ImwWindowManager::LoadLayoutFromFile(const ImwChar* pFilePath)
// {
// FILE* pFile = fopen(pFilePath, "r");
// if (NULL != pFile)
// {
// fseek(pFile, 0, SEEK_END);
// long iSize = ftell(pFile);
// fseek(pFile, 0, SEEK_SET);
//
// ImwChar* pString = new ImwChar[iSize / sizeof(ImwChar)];
// fread(pString, 1, iSize, pFile);
// fclose(pFile);
//
// bool bReturn = LoadLayoutFromString(pString);
//
// delete[] pString;
// return bReturn;
// }
// return false;
// }
// const ImwChar* ImwWindowManager::GetWindowClassName(ImwWindow* /*pWindow*/)
// {
// return NULL;
// }
//
// bool ImwWindowManager::CanCreateWindowByClassName(const ImwChar* /*pName*/)
// {
// return false;
// }
//
// ImwWindow* ImwWindowManager::CreateWindowByClassName(const ImwChar* /*pName*/)
// {
// return NULL;
// }
void ImwWindowManager::PreUpdate()
{
ImwIsSafe(m_pMainPlatformWindow)->PreUpdate();
for (ImwList<ImwPlatformWindow*>::iterator it = m_lPlatformWindows.begin(); it != m_lPlatformWindows.end(); ++it)
{
(*it)->PreUpdate();
}
}
void ImwWindowManager::Update(MOCKUP::RENDERER::Manager& manager)
{
// if (m_pMainPlatformWindow == NULL)
// {
// return;
// }
UpdatePlatformwWindowActions(manager);
UpdateDockActions(manager);
UpdateOrphans(manager);
while (m_lToDestroyWindows.begin() != m_lToDestroyWindows.end())
{
ImwWindow* pWindow = *m_lToDestroyWindows.begin();
m_lToDestroyWindows.remove(pWindow);
m_lOrphanWindows.remove(pWindow);
m_lWindows.remove(pWindow);
InternalUnDock(pWindow);
delete pWindow;
}
while (m_lToDestroyStatusBars.begin() != m_lToDestroyStatusBars.end())
{
ImwStatusBar* pStatusBar = *m_lToDestroyStatusBars.begin();
m_lToDestroyStatusBars.remove(pStatusBar);
delete pStatusBar;
}
while (m_lToDestroyMenus.begin() != m_lToDestroyMenus.end())
{
ImwMenu* pMenu = *m_lToDestroyMenus.begin();
m_lToDestroyMenus.remove(pMenu);
delete pMenu;
}
while (m_lToDestroyToolBars.begin() != m_lToDestroyToolBars.end())
{
ImwToolBar* pToolBar = *m_lToDestroyToolBars.begin();
m_lToDestroyToolBars.remove(pToolBar);
delete pToolBar;
}
while (m_lToDestroyPlatformWindows.begin() != m_lToDestroyPlatformWindows.end())
{
ImwPlatformWindow* pPlatformWindow = *m_lToDestroyPlatformWindows.begin();
m_lToDestroyPlatformWindows.remove(pPlatformWindow);
m_lPlatformWindows.remove(pPlatformWindow);
delete pPlatformWindow;
}
if (NULL != m_pMainPlatformWindow)
{
m_bHasWantCaptureKeyboard = false;
m_bHasWantCaptureMouse = false;
UpdateDragWindow(manager);
Paint(m_pMainPlatformWindow);
Paint(m_pDragPlatformWindow);
for ( ImwList<ImwPlatformWindow*>::iterator it = m_lPlatformWindows.begin(); it != m_lPlatformWindows.end(); ++it )
{
Paint(*it);
}
PostPaint(m_pMainPlatformWindow);
//if (NULL != m_pDragPlatformWindow && m_pDragPlatformWindow->m_bNeedRender)
//PostPaint(m_pDragPlatformWindow);
for ( ImwList<ImwPlatformWindow*>::iterator it = m_lPlatformWindows.begin(); it != m_lPlatformWindows.end(); ++it )
{
PostPaint(*it);
}
m_pCurrentPlatformWindow = NULL;
}
}
void ImwWindowManager::UpdatePlatformwWindowActions(MOCKUP::RENDERER::Manager& manager)
{
UNREFERENCED_PARAMETER(manager);
while (m_lPlatformWindowActions.begin() != m_lPlatformWindowActions.end())
{
PlatformWindowAction* pAction = *m_lPlatformWindowActions.begin();
if (pAction->m_eAction == E_PLATFORM_WINDOW_ACTION_DESTROY)
{
bool bFound = false;
if (m_pMainPlatformWindow == pAction->m_pPlatformWindow)
{
Destroy();
bFound = true;
}
else
{
for (ImwList<ImwPlatformWindow*>::iterator it = m_lPlatformWindows.begin(); it != m_lPlatformWindows.end(); ++it)
{
if (*it == pAction->m_pPlatformWindow)
{
delete *it;
m_lPlatformWindows.erase(it);
bFound = true;
break;
}
}
}
if (!bFound)
{
IM_ASSERT(false); // ImwPlatformWindow not found, maybe already closed
}
}
else if (pAction->m_eAction == E_PLATFORM_WINDOW_ACTION_SHOW)
{
pAction->m_pPlatformWindow->Show(true);
}
else if (pAction->m_eAction == E_PLATFORM_WINDOW_ACTION_HIDE)
{
pAction->m_pPlatformWindow->Show(false);
}
else if (pAction->m_eAction == E_PLATFORM_WINDOW_ACTION_SET_POSITION)
{
pAction->m_pPlatformWindow->SetPosition((int)pAction->m_oValue.x, (int)pAction->m_oValue.y);
}
else if (pAction->m_eAction == E_PLATFORM_WINDOW_ACTION_SET_SIZE)
{
pAction->m_pPlatformWindow->SetSize((int)pAction->m_oValue.x, (int)pAction->m_oValue.y);
}
else if (pAction->m_eAction == E_PLATFORM_WINDOW_ACTION_MAXIMIZE)
{
pAction->m_pPlatformWindow->SetWindowMaximized(true);
}
else if (pAction->m_eAction == E_PLATFORM_WINDOW_ACTION_MINIMIZE)
{
pAction->m_pPlatformWindow->SetWindowMinimized();
}
else if (pAction->m_eAction == E_PLATFORM_WINDOW_ACTION_RESTORE)
{
pAction->m_pPlatformWindow->SetWindowMaximized(false);
}
delete *m_lPlatformWindowActions.begin();
m_lPlatformWindowActions.erase(m_lPlatformWindowActions.begin());
}
}
void ImwWindowManager::UpdateDockActions(MOCKUP::RENDERER::Manager& manager)
{
while (m_lDockActions.begin() != m_lDockActions.end())
{
DockAction* pAction = *m_lDockActions.begin();
InternalUnDock(pAction->m_pWindow);
if (pAction->m_bFloat)
{
InternalFloat(manager, pAction->m_pWindow, pAction->m_oPosition, pAction->m_oSize);
}
else
{
if (NULL != pAction->m_pWith)
{
InternalDockWith(pAction->m_pWindow, pAction->m_pWith, pAction->m_eOrientation, pAction->m_fRatio);
}
else if (NULL != pAction->m_pToContainer)
{
InternalDockTo(pAction->m_pWindow, pAction->m_eOrientation, pAction->m_fRatio, pAction->m_pToContainer, pAction->m_iPosition);
}
else if (NULL != pAction->m_pToPlatformWindow)
{
InternalDock(pAction->m_pWindow, pAction->m_eOrientation, pAction->m_fRatio, pAction->m_pToPlatformWindow);
}
}
m_lOrphanWindows.remove(pAction->m_pWindow);
delete pAction;
m_lDockActions.erase(m_lDockActions.begin());
}
}
void ImwWindowManager::UpdateOrphans(MOCKUP::RENDERER::Manager& manager)
{
while (m_lOrphanWindows.begin() != m_lOrphanWindows.end())
{
if (m_pMainPlatformWindow->m_pContainer->IsEmpty())
{
InternalDock(*m_lOrphanWindows.begin(), E_DOCK_ORIENTATION_CENTER, 0.5f, m_pMainPlatformWindow);
}
else
{
ImVec2 oSize = ImVec2(300, 300);
ImVec2 oPos = m_pMainPlatformWindow->GetPosition();
ImVec2 oMainSize = m_pMainPlatformWindow->GetSize();
oPos.x += (oMainSize.x - oSize.x) / 2;
oPos.y += (oMainSize.y - oSize.y) / 2;
InternalFloat(manager, *m_lOrphanWindows.begin(), oPos, oSize);
}
m_lOrphanWindows.erase(m_lOrphanWindows.begin());
}
}
void ImwWindowManager::Render(MOCKUP::RENDERER::Manager& manager)
{
if (m_pMainPlatformWindow == NULL)
{
return;
}
if (NULL != m_pMainPlatformWindow && m_pMainPlatformWindow->m_bNeedRender)
{
m_pMainPlatformWindow->Render(manager);
}
if (NULL != m_pDragPlatformWindow && m_pDragPlatformWindow->m_bNeedRender)
{
m_pDragPlatformWindow->Render(manager);
}
for (ImwList<ImwPlatformWindow*>::iterator it = m_lPlatformWindows.begin(); it != m_lPlatformWindows.end(); ++it)
{
if ((*it)->m_bNeedRender)
(*it)->Render(manager);
}
}
void ImwWindowManager::Paint(ImwPlatformWindow* pWindow)
{
IM_ASSERT(NULL != pWindow);
if (NULL == pWindow)
return;
pWindow->m_bNeedRender = false;
if (pWindow->m_eType == E_PLATFORM_WINDOW_TYPE_DRAG_PREVIEW && (NULL == m_pDraggedWindow || m_bDragOnTab || m_pDragBestContainer != NULL))
return;
pWindow->m_bNeedRender = true;
m_pCurrentPlatformWindow = pWindow;
pWindow->SetContext(true);
ImGui::GetIO().DisplaySize = pWindow->GetSize();
ImGuiContext* pContext = ImGui::GetCurrentContext();
if (pContext->FrameCountEnded >= pContext->FrameCount || !pContext->Initialized)
ImGui::NewFrame();
float fTop = 0.f;
float fBottom = 0.f;
if (pWindow->GetType() == E_PLATFORM_WINDOW_TYPE_MAIN)
{
ImGuiIO& oIO = ImGui::GetIO();
if (pWindow->IsShowContent() || oIO.MousePos.y <= 50.f || oIO.MetricsActiveWindows > 2) // Autohide menu bar
{
ImGui::BeginMainMenuBar();
for (ImwMenuList::iterator it = m_lMenus.begin(), itEnd = m_lMenus.end(); it != itEnd; ++it)
{
(*it)->OnMenu();
}
fTop = ImGui::GetWindowHeight();
ImGui::EndMainMenuBar();
if (m_lStatusBars.size() > 0)
{
fBottom = m_oConfig.m_oStatusBarFramePadding.y * 2.f + m_oConfig.m_oStatusBarWindowPadding.y * 2.f + ImGui::GetTextLineHeight();
}
}
}
if (pWindow->IsShowContent())
{
ImGui::SetNextWindowPos(ImVec2(0, fTop), ImGuiCond_Always);
ImGui::SetNextWindowSize(ImVec2(pWindow->GetSize().x, pWindow->GetSize().y - fTop - fBottom), ImGuiCond_Always);
int iFlags = ImGuiWindowFlags_NoTitleBar
| ImGuiWindowFlags_NoResize
| ImGuiWindowFlags_NoMove
| ImGuiWindowFlags_NoCollapse
| ImGuiWindowFlags_NoSavedSettings
| ImGuiWindowFlags_NoScrollbar
| ImGuiWindowFlags_NoScrollWithMouse
| ImGuiWindowFlags_NoBringToFrontOnFocus;
if (NULL != m_pDraggedWindow)
{
iFlags += ImGuiWindowFlags_NoInputs;
}
PushStyle();
ImGui::Begin("Main", NULL, iFlags);
if (NULL != m_pDraggedWindow)
{
ImGuiID oId = ImGui::GetID("##DraggedWindow");
ImGui::PushID(oId);
ImGui::PopID();
ImGui::SetActiveID(oId, ImGui::GetCurrentWindow());
}
if (pWindow->GetType() == E_PLATFORM_WINDOW_TYPE_MAIN)
{
if (!m_lToolBars.empty())
{
PopStyle();
for (ImwToolBarList::iterator it = m_lToolBars.begin(), itEnd = m_lToolBars.end(); it != itEnd; ++it)
{
(*it)->OnToolBar();
}
ImGui::Separator();
PushStyle();
}
}
pWindow->PaintContainer();
ImGui::End();
PopStyle();
if (pWindow->GetType() == E_PLATFORM_WINDOW_TYPE_MAIN && m_lStatusBars.size() > 0)
{
ImGui::SetNextWindowPos(ImVec2(0, pWindow->GetSize().y - fBottom), ImGuiCond_Always);
ImGui::SetNextWindowSize(ImVec2(pWindow->GetSize().x, fBottom), ImGuiCond_Always);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, m_oConfig.m_oStatusBarWindowPadding);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, m_oConfig.m_oStatusBarFramePadding);
ImGui::Begin("##StatusBar", NULL, iFlags);
ImGui::Columns((int)m_lStatusBars.size());
for (ImwStatusBarList::iterator it = m_lStatusBars.begin(); it != m_lStatusBars.end(); ++it)
{
(*it)->OnStatusBar();
ImGui::NextColumn();
}
ImGui::Columns(1);
ImGui::End();
ImGui::PopStyleVar(3);
}
}
m_bHasWantCaptureKeyboard |= ImGui::GetIO().WantCaptureKeyboard;
m_bHasWantCaptureMouse |= ImGui::GetIO().WantCaptureMouse;
pWindow->RestoreContext(true);
}
void ImwWindowManager::PostPaint(ImwPlatformWindow* pWindow)
{
IM_ASSERT(NULL != pWindow);
if (NULL == pWindow)
return;
m_pCurrentPlatformWindow = pWindow;
pWindow->SetContext(true);
ImDrawList* pDrawList = &(ImGui::GetCurrentContext()->OverlayDrawList);
for (ImwList<DrawWindowAreaAction>::iterator it = m_lDrawWindowAreas.begin(); it != m_lDrawWindowAreas.end(); )
{
DrawWindowAreaAction& oAction = *it;
if (pWindow == oAction.m_pWindow)
{
ImVec2 oPosA = oAction.m_oRectPos;
ImVec2 oPosB = oAction.m_oRectSize;
oPosB.x += oPosA.x;
oPosB.y += oPosA.y;
pDrawList->AddRectFilled(oPosA, oPosB, oAction.m_oColor);
ImwList<DrawWindowAreaAction>::iterator toRemove = it;
++it;
m_lDrawWindowAreas.erase(toRemove);
}
else
{
++it;
}
}
pWindow->RestoreContext(true);
}
void ImwWindowManager::PushStyle(bool bRounding, bool bPadding)
{
ImGuiStyle& oStyle = ImGui::GetStyle();
m_fStyleBackupWindowRounding = oStyle.WindowRounding;
m_oStyleBackupWindowPadding = oStyle.WindowPadding;
m_oStyleBackupItemInnerSpacing = oStyle.ItemInnerSpacing;
m_oStyleBackupItemSpacing = oStyle.ItemSpacing;
if (bRounding)
{
oStyle.WindowRounding = 0.f;
}
if (bPadding)
{
oStyle.WindowPadding = ImVec2(0.f, 0.f);
oStyle.ItemInnerSpacing = ImVec2(0.f, 0.f);
oStyle.ItemSpacing = ImVec2(0.f, 0.f);
}
}
void ImwWindowManager::PopStyle()
{
ImGuiStyle& oStyle = ImGui::GetStyle();
oStyle.WindowRounding = m_fStyleBackupWindowRounding;
oStyle.WindowPadding = m_oStyleBackupWindowPadding;
oStyle.ItemInnerSpacing = m_oStyleBackupItemInnerSpacing;
oStyle.ItemSpacing = m_oStyleBackupItemSpacing;
}
void ImwWindowManager::StartDragWindow(ImwWindow* pWindow, ImVec2 oOffset)
{
if (NULL == m_pDraggedWindow)
{
m_pDraggedWindow = pWindow;
m_oDragPreviewOffset = oOffset;
if (NULL != m_pDragPlatformWindow)
{
POINT oPoint;
GetCursorPos(&oPoint);
ImVec2 oCursorPos = ImVec2((float)oPoint.x, (float)oPoint.y);
ImVec2 oPosition = ImVec2(oCursorPos.x + m_oDragPreviewOffset.x, oCursorPos.y + m_oDragPreviewOffset.y);
ImVec2 oSize = ImVec2(pWindow->GetLastSize().x, pWindow->GetLastSize().y + ImwContainer::c_fTabHeight);
m_lPlatformWindowActions.push_back(new PlatformWindowAction(m_pDragPlatformWindow, E_PLATFORM_WINDOW_ACTION_SHOW));
m_lPlatformWindowActions.push_back(new PlatformWindowAction(m_pDragPlatformWindow, E_PLATFORM_WINDOW_ACTION_SET_POSITION, oPosition));
m_lPlatformWindowActions.push_back(new PlatformWindowAction(m_pDragPlatformWindow, E_PLATFORM_WINDOW_ACTION_SET_SIZE, oSize));
Dock(pWindow, E_DOCK_ORIENTATION_CENTER, 0.5f, m_pDragPlatformWindow);
m_pDragPlatformWindow->m_pContext->IO.MouseDown[0] = true;
}
else
{
UnDock(pWindow);
}
}
}
void ImwWindowManager::StopDragWindow()
{
if ( NULL != m_pDragPlatformWindow )
{
m_pDragPlatformWindow->Show(false);
m_pDragPlatformWindow->m_bNeedRender = false;
m_lPlatformWindowActions.push_back(new PlatformWindowAction(m_pDragPlatformWindow, E_PLATFORM_WINDOW_ACTION_HIDE));
}
m_pDraggedWindow = NULL;
}
void ImwWindowManager::UpdateDragWindow(MOCKUP::RENDERER::Manager& manager)
{
if (NULL != m_pDraggedWindow)
{
POINT oPoint;
GetCursorPos(&oPoint);
ImVec2 oCursorPos = ImVec2((float)oPoint.x, (float)oPoint.y);
//Search best dock area
EDockOrientation eBestDockOrientation;
ImVec2 oHightlightPos;
ImVec2 oHightlightSize;
float fSizeRatio;
m_pDragBestContainer = GetBestDocking(m_pMainPlatformWindow, oCursorPos, eBestDockOrientation, oHightlightPos, oHightlightSize, fSizeRatio, m_bDragOnTab, m_iDragBestContainerPosition, false);
if (NULL == m_pDragBestContainer)
{
for (ImwList<ImwPlatformWindow*>::iterator it = m_lPlatformWindows.begin(); it != m_lPlatformWindows.end() && NULL == m_pDragBestContainer; ++it)
{
m_pDragBestContainer = GetBestDocking(*it, oCursorPos, eBestDockOrientation, oHightlightPos, oHightlightSize, fSizeRatio, m_bDragOnTab, m_iDragBestContainerPosition, false);
}
}
if (m_pDragBestContainer)
{
DrawWindowArea(m_pDragBestContainer->GetPlatformWindowParent(), oHightlightPos, oHightlightSize, m_oConfig.m_oHightlightAreaColor);
}
if (NULL != m_pDragPlatformWindow)
{
if (m_bDragOnTab || m_pDragBestContainer != NULL)
{
m_pDragPlatformWindow->Show(false);
}
else
{
m_pDragPlatformWindow->Show(true);
m_pDragPlatformWindow->SetPosition((int)(oCursorPos.x + m_oDragPreviewOffset.x), (int)(oCursorPos.y + m_oDragPreviewOffset.y));
}
}
if (GetAsyncKeyState(VK_LBUTTON) == 0)
{
InternalUnDock(m_pDraggedWindow);
if (NULL != m_pDragBestContainer)
{
InternalDockTo(m_pDraggedWindow, eBestDockOrientation, fSizeRatio, m_pDragBestContainer, m_iDragBestContainerPosition);
}
else if (NULL != m_pDragPlatformWindow)
{
InternalFloat(manager, m_pDraggedWindow, m_pDragPlatformWindow->GetPosition(), m_pDragPlatformWindow->GetSize());
}
else
{
InternalDock(m_pDraggedWindow, E_DOCK_ORIENTATION_CENTER, fSizeRatio, m_pMainPlatformWindow);
}
StopDragWindow();
}
}
}
ImwWindow* ImwWindowManager::GetDraggedWindow() const
{
return m_pDraggedWindow;
}
ImVec2 ImwWindowManager::GetDragOffset() const
{
return m_oDragPreviewOffset;
}
ImwContainer* ImwWindowManager::GetDragBestContainer() const
{
return m_pDragBestContainer;
}
bool ImwWindowManager::GetDragOnTabArea() const
{
return m_bDragOnTab;
}
int ImwWindowManager::GetDragTabPosition() const
{
return m_iDragBestContainerPosition;
}
ImwContainer* ImwWindowManager::GetBestDocking(ImwPlatformWindow* pPlatformWindow, const ImVec2 oCursorPos, EDockOrientation& oOutOrientation, ImVec2& oOutAreaPos, ImVec2& oOutAreaSize, float& fOutRatio, bool& bOutOnTabArea, int& iOutPosition, bool bLargeCheck)
{
ImVec2 oPos = pPlatformWindow->GetPosition();
ImVec2 oSize = pPlatformWindow->GetSize();
if (bLargeCheck || (oCursorPos.x >= oPos.x && oCursorPos.x <= (oPos.x + oSize.x) &&
oCursorPos.y >= oPos.y && oCursorPos.y <= (oPos.y + oSize.y)))
{
ImVec2 oRectPos(oCursorPos.x - oPos.x, oCursorPos.y - oPos.y);
pPlatformWindow->SetContext(false);
ImwContainer* pBestContainer = pPlatformWindow->GetContainer()->GetBestDocking(oRectPos, oOutOrientation, oOutAreaPos, oOutAreaSize, bOutOnTabArea, iOutPosition, bLargeCheck);
pPlatformWindow->RestoreContext(false);
if (NULL != pBestContainer)
{
fOutRatio = 0.5f; //Default value
return pBestContainer;
}
//Left
if (oRectPos.x <= oSize.x * m_oConfig.m_fDragMarginRatio)
{
oOutOrientation = E_DOCK_ORIENTATION_LEFT;
oOutAreaPos = ImVec2(0, 0);
oOutAreaSize = ImVec2(oSize.x * m_oConfig.m_fDragMarginSizeRatio, oSize.y);
bOutOnTabArea = false;
}
//Right
else if (oRectPos.x >= oSize.x * (1.f - m_oConfig.m_fDragMarginRatio))
{
oOutOrientation = E_DOCK_ORIENTATION_RIGHT;
oOutAreaPos = ImVec2(oSize.x * (1.f - m_oConfig.m_fDragMarginSizeRatio), 0.f);
oOutAreaSize = ImVec2(oSize.x * m_oConfig.m_fDragMarginSizeRatio, oSize.y);
bOutOnTabArea = false;
}
//Top
else if (oRectPos.y <= oSize.y * m_oConfig.m_fDragMarginRatio)
{
oOutOrientation = E_DOCK_ORIENTATION_TOP;
oOutAreaPos = ImVec2(0, 0);
oOutAreaSize = ImVec2(oSize.x, oSize.y * m_oConfig.m_fDragMarginSizeRatio);
bOutOnTabArea = false;
}
//Bottom
else if (oRectPos.y >= oSize.y * (1.f - m_oConfig.m_fDragMarginRatio))
{
oOutOrientation = E_DOCK_ORIENTATION_BOTTOM;
oOutAreaPos = ImVec2(0.f, oSize.y * (1.f - m_oConfig.m_fDragMarginSizeRatio));
oOutAreaSize = ImVec2(oSize.x, oSize.y * m_oConfig.m_fDragMarginSizeRatio);
bOutOnTabArea = false;
}
else
{
oOutOrientation = E_DOCK_ORIENTATION_CENTER;
oOutAreaPos = ImVec2(0, 0);
oOutAreaSize = ImVec2(oSize.x, oSize.y);
bOutOnTabArea = false;
//IM_ASSERT(false); //Best dock orientation not found
return NULL;
}
fOutRatio = GetConfig().m_fDragMarginSizeRatio;
return pPlatformWindow->GetContainer();
}
oOutOrientation = E_DOCK_ORIENTATION_CENTER;
oOutAreaPos = ImVec2(0, 0);
oOutAreaSize = ImVec2(oSize.x, oSize.y);
bOutOnTabArea = false;
return NULL;
}
void ImwWindowManager::AddWindow(ImwWindow* pWindow)
{
m_lWindows.push_back(pWindow);
m_lOrphanWindows.push_back(pWindow);
}
void ImwWindowManager::RemoveWindow(ImwWindow* pWindow)
{
m_lWindows.remove(pWindow);
m_lOrphanWindows.remove(pWindow);
}
void ImwWindowManager::DestroyWindow(ImwWindow* pWindow)
{
if (NULL != pWindow && std::find(m_lToDestroyWindows.begin(), m_lToDestroyWindows.end(), pWindow) == m_lToDestroyWindows.end())
{
m_lToDestroyWindows.push_back(pWindow);
}
}
void ImwWindowManager::AddStatusBar(ImwStatusBar* pStatusBar)
{
ImwStatusBarList::iterator it = m_lStatusBars.begin(), itEnd = m_lStatusBars.end();
for (; it != itEnd; ++it)
{
if (pStatusBar->GetHorizontalPriority() <= (*it)->GetHorizontalPriority())
break;
}
m_lStatusBars.insert(it, pStatusBar);
}
void ImwWindowManager::RemoveStatusBar(ImwStatusBar* pStatusBar)
{
m_lStatusBars.remove(pStatusBar);
}
void ImwWindowManager::DestroyStatusBar(ImwStatusBar* pStatusBar)
{
if (NULL != pStatusBar && std::find(m_lToDestroyStatusBars.begin(), m_lToDestroyStatusBars.end(), pStatusBar) == m_lToDestroyStatusBars.end())
{
m_lToDestroyStatusBars.push_back(pStatusBar);
}
}
void ImwWindowManager::AddMenu(ImwMenu* pMenu)
{
ImwMenuList::iterator it = m_lMenus.begin(), itEnd = m_lMenus.end();
for (; it != itEnd; ++it)
{
if (pMenu->GetHorizontalPriority() <= (*it)->GetHorizontalPriority())
break;
}
m_lMenus.insert(it, pMenu);
}
void ImwWindowManager::RemoveMenu(ImwMenu* pMenu)
{
m_lMenus.remove(pMenu);
}
void ImwWindowManager::DestroyMenu(ImwMenu* pMenu)
{
if (NULL != pMenu && std::find(m_lToDestroyMenus.begin(), m_lToDestroyMenus.end(), pMenu) == m_lToDestroyMenus.end())
{
m_lToDestroyMenus.push_back(pMenu);
}
}
void ImwWindowManager::AddToolBar(ImwToolBar* pToolBar)
{
ImwToolBarList::iterator it = m_lToolBars.begin(), itEnd = m_lToolBars.end();
for (; it != itEnd; ++it)
{
if (pToolBar->GetHorizontalPriority() <= (*it)->GetHorizontalPriority())
break;
}
m_lToolBars.insert(it, pToolBar);
}
void ImwWindowManager::RemoveToolBar(ImwToolBar* pToolBar)
{
m_lToolBars.remove(pToolBar);
}
void ImwWindowManager::DestroyToolBar(ImwToolBar* pToolBar)
{
if (NULL != pToolBar && std::find(m_lToDestroyToolBars.begin(), m_lToDestroyToolBars.end(), pToolBar) == m_lToDestroyToolBars.end())
{
m_lToDestroyToolBars.push_back(pToolBar);
}
}
void ImwWindowManager::InternalDock(ImwWindow* pWindow, EDockOrientation eOrientation, float fRatio, ImwPlatformWindow* pToPlatformWindow)
{
pToPlatformWindow->m_pContainer->Dock(pWindow, eOrientation, fRatio);
}
void ImwWindowManager::InternalDockTo(ImwWindow* pWindow, EDockOrientation eOrientation, float fRatio, ImwContainer* pToContainer, int iPosition)
{
pToContainer->Dock(pWindow, eOrientation, fRatio, iPosition);
}
void ImwWindowManager::InternalDockWith(ImwWindow* pWindow, ImwWindow* pWithWindow, EDockOrientation eOrientation, float fRatio)
{
ImwContainer* pContainer = m_pMainPlatformWindow->HasWindow(pWithWindow);
if (NULL != pContainer)
{
pContainer->Dock(pWindow, eOrientation, fRatio);
}
for ( ImwList<ImwPlatformWindow*>::iterator it = m_lPlatformWindows.begin(); it != m_lPlatformWindows.end(); ++it )
{
pContainer = (*it)->HasWindow(pWithWindow);
if (NULL != pContainer)
{
pContainer->Dock(pWindow, eOrientation, fRatio);
break;
}
}
}
void ImwWindowManager::InternalFloat(MOCKUP::RENDERER::Manager& manager, ImwWindow* pWindow, ImVec2 oPosition, ImVec2 oSize)
{
IM_ASSERT(m_pCurrentPlatformWindow == NULL);
ImwPlatformWindow* pPlatformWindow = new ImwPlatformWindow(E_PLATFORM_WINDOW_TYPE_SECONDARY, true);
if (pPlatformWindow && pPlatformWindow->Init(manager, m_pMainPlatformWindow))
{
// pPlatformWindow->Show(true);
}
else
{
delete pPlatformWindow;
pPlatformWindow = nullptr;
return;
}
if (NULL != pPlatformWindow)
{
m_lPlatformWindows.push_back(pPlatformWindow);
const ImVec2 oVec2_1 = ImVec2(1, 1);
const ImVec2 oVec2_N1 = ImVec2(-1, -1);
if (oSize.x == oVec2_1.x && oSize.y == oVec2_1.y)
{
oSize = pWindow->GetLastSize();
}
if (oPosition.x == oVec2_N1.x && oPosition.y == oVec2_N1.y)
{
POINT oPoint;
GetCursorPos(&oPoint);
oPosition = ImVec2((float)oPoint.x, (float)oPoint.y);
oPosition.x -= 20;
oPosition.x -= 10;
}
pPlatformWindow->Dock(pWindow);
pPlatformWindow->SetSize((int)oSize.x, (int)oSize.y);
pPlatformWindow->SetPosition((int)oPosition.x, (int)oPosition.y);
pPlatformWindow->Show(true);
}
}
void ImwWindowManager::InternalUnDock(ImwWindow* pWindow)
{
if (m_pMainPlatformWindow->UnDock(pWindow))
{
return;
}
for ( ImwList<ImwPlatformWindow*>::iterator it = m_lPlatformWindows.begin(); it != m_lPlatformWindows.end(); ++it )
{
if ( (*it)->UnDock(pWindow) )
{
//Destroy empty platform window if not main window
if ( (*it)->GetType() != E_PLATFORM_WINDOW_TYPE_MAIN && (*it)->GetContainer()->IsEmpty() )
{
m_lToDestroyPlatformWindows.push_back(*it);
}
return;
}
}
if ( NULL != m_pDragPlatformWindow )
{
m_pDragPlatformWindow->UnDock(pWindow);
}
}
void ImwWindowManager::OnClosePlatformWindow(ImwPlatformWindow* pWindow)
{
if (NULL != pWindow && !pWindow->m_pContainer->HasUnclosableWindow())
{
if (pWindow->GetType() == E_PLATFORM_WINDOW_TYPE_MAIN)
{
for (ImwList<ImwPlatformWindow*>::iterator it = m_lPlatformWindows.begin(); it != m_lPlatformWindows.end(); ++it)
{
if ((*it)->m_pContainer->HasUnclosableWindow())
return;
}
}
m_lPlatformWindowActions.push_back(new PlatformWindowAction(pWindow, E_PLATFORM_WINDOW_ACTION_DESTROY));
}
}
void ImwWindowManager::DrawWindowArea( ImwPlatformWindow* pWindow, const ImVec2& oPos, const ImVec2& oSize, const ImColor& oColor )
{
m_lDrawWindowAreas.push_back(DrawWindowAreaAction(pWindow, oPos, oSize, oColor));
}
// Static
ImwWindowManager* ImwWindowManager::GetInstance()
{
return s_pInstance;
}
//SFF_END
}
#pragma once
#include "ImwConfig.h"
#include "ImwWindow.h"
#include "ImwMenu.h"
#include "ImwPlatformWindow.h"
#include "ImwStatusBar.h"
#include "ImwToolBar.h"
//#include "JsonValue.h"
#include "..\..\pch.h"
namespace MOCKUP
{
class Editor;
}
namespace ImWindow
{
class IMGUI_API ImwWindowManager
{
friend class ImwWindow;
friend class ImwMenu;
friend class ImwStatusBar;
friend class ImwToolBar;
friend class ImwPlatformWindow;
friend class ImwContainer;
enum EPlatformWindowAction
{
E_PLATFORM_WINDOW_ACTION_DESTROY,
E_PLATFORM_WINDOW_ACTION_SHOW,
E_PLATFORM_WINDOW_ACTION_HIDE,
E_PLATFORM_WINDOW_ACTION_SET_POSITION,
E_PLATFORM_WINDOW_ACTION_SET_SIZE,
E_PLATFORM_WINDOW_ACTION_MAXIMIZE,
E_PLATFORM_WINDOW_ACTION_MINIMIZE,
E_PLATFORM_WINDOW_ACTION_RESTORE,
};
struct PlatformWindowAction
{
PlatformWindowAction(ImwPlatformWindow* pPlatformWindow, EPlatformWindowAction eAction, ImVec2 oValue = ImVec2(0.f, 0.f));
ImwPlatformWindow* m_pPlatformWindow;
EPlatformWindowAction m_eAction;
ImVec2 m_oValue;
};
struct DockAction
{
ImwWindow* m_pWindow;
// Is Dock or Float
bool m_bFloat;
//For Docking
ImwWindow* m_pWith;
EDockOrientation m_eOrientation;
ImwPlatformWindow* m_pToPlatformWindow;
ImwContainer* m_pToContainer;
int m_iPosition;
float m_fRatio;
//For Floating
ImVec2 m_oPosition;
ImVec2 m_oSize;
};
struct DrawWindowAreaAction
{
DrawWindowAreaAction( ImwPlatformWindow* pWindow, const ImVec2& oRectPos, const ImVec2& oRectSize, const ImColor& oColor );
ImwPlatformWindow* m_pWindow;
ImVec2 m_oRectPos;
ImVec2 m_oRectSize;
ImColor m_oColor;
};
public:
enum ETabColorMode
{
E_TABCOLORMODE_TITLE,
E_TABCOLORMODE_BACKGROUND,
E_TABCOLORMODE_CUSTOM
};
struct Config
{
Config();
float m_fDragMarginRatio;
float m_fDragMarginSizeRatio;
ImColor m_oHightlightAreaColor;
ETabColorMode m_eTabColorMode;
bool m_bVisibleDragger;
bool m_bShowTabBorder;
bool m_bShowTabShadows;
ImColor m_oTabColorNormal;
ImColor m_oTabColorActive;
ImColor m_oTabColorBorder;
float m_fTabOverlap;
float m_fTabSlopWidth;
float m_fTabSlopP1Ratio;
float m_fTabSlopP2Ratio;
float m_fTabSlopHRatio;
float m_fTabShadowDropSize;
float m_fTabShadowSlopRatio;
float m_fTabShadowAlpha;
ImVec2 m_oStatusBarWindowPadding;
ImVec2 m_oStatusBarFramePadding;
};
public:
ImwWindowManager();
~ImwWindowManager();
bool Init(MOCKUP::RENDERER::Manager& manager);
void Destroy();
////////////////////////////////////////////////////////////////////////////////
void PreUpdate();
void Update(MOCKUP::RENDERER::Manager& manager);
void Render(MOCKUP::RENDERER::Manager& manager);
////////////////////////////////////////////////////////////////////////////////
ImwPlatformWindow* GetMainPlatformWindow() const;
const ImwPlatformWindowList& GetSecondariesPlatformWindows() const;
Config& GetConfig();
void SetMainTitle(const ImwChar* pTitle);
void Dock(ImwWindow* pWindow, EDockOrientation eOrientation = E_DOCK_ORIENTATION_CENTER, float fRatio = 0.5f, ImwPlatformWindow* pToPlatformWindow = NULL);
void DockTo(ImwWindow* pWindow, EDockOrientation eOrientation = E_DOCK_ORIENTATION_CENTER, float fRatio = 0.5f, ImwContainer* pContainer = NULL, int iPosition = -1);
void DockWith(ImwWindow* pWindow, ImwWindow* pWithWindow, EDockOrientation eOrientation = E_DOCK_ORIENTATION_CENTER, float fRatio = 0.5f);
void Float(ImwWindow* pWindow, const ImVec2& oPosition = ImVec2(-1, -1), const ImVec2& oSize = ImVec2(-1, -1));
void FocusWindow(ImwWindow* pWindow);
const ImwWindowList& GetWindowList() const;
ImwPlatformWindow* GetCurrentPlatformWindow();
ImwPlatformWindow* GetWindowParent(ImwWindow* pWindow);
void MaximizeCurrentPlatformWindow();
void MinimizeCurrentPlatformWindow();
void RestoreCurrentPlatformWindow();
bool HasWantCaptureKeyboard() const { return m_bHasWantCaptureKeyboard; }
bool HasWantCaptureMouse() const { return m_bHasWantCaptureMouse; }
// bool SaveLayoutToString(ImwString& sLayout, bool bCompact = false);
// bool SaveLayoutToFile(const ImwChar* pFilePath, bool bCompact = false);
// bool LoadLayoutFromString(const ImwChar* pLayout);
// bool LoadLayoutFromFile(const ImwChar* pFilePath);
// virtual const ImwChar* GetWindowClassName(ImwWindow* pWindow);
// virtual bool CanCreateWindowByClassName(const ImwChar* pName);
// virtual ImwWindow* CreateWindowByClassName(const ImwChar* pName);
// protected:
// virtual bool CanCreateMultipleWindow();
// virtual bool InternalInit();
// virtual ImwPlatformWindow* CreatePlatformWindow(EPlatformWindowType eType, ImwPlatformWindow* pParent);
// virtual ImVec2 GetCursorPos();
// virtual bool IsLeftClickDown();
// bool InternalInit();
// ImVec2 GetCursorPos();
// bool IsLeftClickDown();
private:
void AddWindow(ImwWindow* pWindow);
void RemoveWindow(ImwWindow* pWindow);
void DestroyWindow(ImwWindow* pWindow);
void AddStatusBar(ImwStatusBar* pStatusBar);
void RemoveStatusBar(ImwStatusBar* pStatusBar);
void DestroyStatusBar(ImwStatusBar* pStatusBar);
void AddMenu(ImwMenu* pMenu);
void RemoveMenu(ImwMenu* pMenu);
void DestroyMenu(ImwMenu* pWindow);
void AddToolBar(ImwToolBar* pToolBar);
void RemoveToolBar(ImwToolBar* pToolBar);
void DestroyToolBar(ImwToolBar* pToolBar);
void UnDock(ImwWindow* pWindow);
void InternalDock(ImwWindow* pWindow, EDockOrientation eOrientation, float fRatio, ImwPlatformWindow* pToPlatformWindow);
void InternalDockTo(ImwWindow* pWindow, EDockOrientation eOrientation, float fRatio, ImwContainer* pToContainer, int iPosition);
void InternalDockWith(ImwWindow* pWindow, ImwWindow* pWithWindow, EDockOrientation eOrientation, float fRatio);
void InternalFloat(MOCKUP::RENDERER::Manager& manager, ImwWindow* pWindow, ImVec2 oPosition, ImVec2 oSize);
void InternalUnDock(ImwWindow* pWindow);
void OnClosePlatformWindow(ImwPlatformWindow* pWindow);
void DrawWindowArea(ImwPlatformWindow* pWindow, const ImVec2& oPos, const ImVec2& oSize, const ImColor& oColor );
void UpdatePlatformwWindowActions(MOCKUP::RENDERER::Manager& manager);
void UpdateDockActions(MOCKUP::RENDERER::Manager& manager);
void UpdateOrphans(MOCKUP::RENDERER::Manager& manager);
void Paint(ImwPlatformWindow* pWindow);
void PostPaint(ImwPlatformWindow* pWindow);
void PushStyle(bool bRounding = true, bool bPadding = true);
void PopStyle();
void StartDragWindow(ImwWindow* pWindow, ImVec2 oOffset);
void StopDragWindow();
void UpdateDragWindow(MOCKUP::RENDERER::Manager& manager);
ImwWindow* GetDraggedWindow() const;
ImVec2 GetDragOffset() const;
ImwContainer* GetDragBestContainer() const;
bool GetDragOnTabArea() const;
int GetDragTabPosition() const;
ImwContainer* GetBestDocking(ImwPlatformWindow* pPlatformWindow, const ImVec2 oCursorPos, EDockOrientation& oOutOrientation, ImVec2& oOutAreaPos, ImVec2& oOutAreaSize, float& fOutRatio, bool& bOutOnTabArea, int& iOutPosition, bool bLargeCheck);
Config m_oConfig;
ImwPlatformWindow* m_pMainPlatformWindow;
ImwPlatformWindowList m_lPlatformWindows;
ImwPlatformWindow* m_pDragPlatformWindow;
ImwWindowList m_lWindows;
ImwWindowList m_lOrphanWindows;
ImwWindowList m_lToDestroyWindows;
ImwStatusBarList m_lStatusBars;
ImwStatusBarList m_lToDestroyStatusBars;
ImwToolBarList m_lToolBars;
ImwToolBarList m_lToDestroyToolBars;
ImwMenuList m_lMenus;
ImwMenuList m_lToDestroyMenus;
ImwPlatformWindowList m_lToDestroyPlatformWindows;
ImwList<PlatformWindowAction*> m_lPlatformWindowActions;
ImwList<DockAction*> m_lDockActions;
ImwList<DrawWindowAreaAction> m_lDrawWindowAreas;
ImwPlatformWindow* m_pCurrentPlatformWindow;
ImwWindow* m_pDraggedWindow;
bool m_bDragOnTab;
ImwContainer* m_pDragBestContainer;
int m_iDragBestContainerPosition;
ImVec2 m_oDragPreviewOffset;
float m_fStyleBackupWindowRounding;
ImVec2 m_oStyleBackupWindowPadding;
ImVec2 m_oStyleBackupItemInnerSpacing;
ImVec2 m_oStyleBackupItemSpacing;
bool m_bHasWantCaptureKeyboard;
bool m_bHasWantCaptureMouse;
// Static
public:
static ImwWindowManager* GetInstance();
private:
static ImwWindowManager* s_pInstance;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment