Refactor Layout Manager
This commit is contained in:
parent
7cf3328a40
commit
54dcbcb46b
28 changed files with 408 additions and 123 deletions
|
|
@ -418,7 +418,7 @@ namespace tp {
|
||||||
|
|
||||||
void reverse() {
|
void reverse() {
|
||||||
for (ualni idx = 0; idx < mLoad / 2; idx++) {
|
for (ualni idx = 0; idx < mLoad / 2; idx++) {
|
||||||
swap(mBuff[idx], mBuff[mLoad - idx - 1]);
|
swapV(mBuff[idx], mBuff[mLoad - idx - 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ namespace tp {
|
||||||
for (Index i = 0; i < mSize.x; i++) {
|
for (Index i = 0; i < mSize.x; i++) {
|
||||||
const auto lenIdx = mSize.y - 1;
|
const auto lenIdx = mSize.y - 1;
|
||||||
for (Index j = 0; j < mSize.y / 2; j++) {
|
for (Index j = 0; j < mSize.y / 2; j++) {
|
||||||
swap(get({i, j}), get({i, lenIdx - j}));
|
swapV(get({ i, j }), get({ i, lenIdx - j }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -72,7 +72,7 @@ namespace tp {
|
||||||
for (Index i = 0; i < mSize.y; i++) {
|
for (Index i = 0; i < mSize.y; i++) {
|
||||||
const auto lenIdx = mSize.x - 1;
|
const auto lenIdx = mSize.x - 1;
|
||||||
for (Index j = 0; j < mSize.x / 2; j++) {
|
for (Index j = 0; j < mSize.x / 2; j++) {
|
||||||
swap(get({i, j}), get({i, lenIdx - j}));
|
swapV(get({ i, j }), get({ i, lenIdx - j }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -288,9 +288,9 @@ namespace tp {
|
||||||
while (iter) {
|
while (iter) {
|
||||||
tmp = iter;
|
tmp = iter;
|
||||||
iter = iter->next;
|
iter = iter->next;
|
||||||
swap(tmp->next, tmp->prev);
|
swapV(tmp->next, tmp->prev);
|
||||||
}
|
}
|
||||||
swap(mFirst, mLast);
|
swapV(mFirst, mLast);
|
||||||
}
|
}
|
||||||
|
|
||||||
void detachAll() {
|
void detachAll() {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ struct Interval {
|
||||||
start = ((halnf) randomFloat()) * (span) - offset;
|
start = ((halnf) randomFloat()) * (span) - offset;
|
||||||
end = ((halnf) randomFloat()) * (span) - offset;
|
end = ((halnf) randomFloat()) * (span) - offset;
|
||||||
|
|
||||||
if (start > end) swap(start, end);
|
if (start > end) swapV(start, end);
|
||||||
|
|
||||||
auto len = (end - start) * scale * 0.5f;
|
auto len = (end - start) * scale * 0.5f;
|
||||||
auto mid = (start + end) / 2.f;
|
auto mid = (start + end) / 2.f;
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,8 @@ namespace tp {
|
||||||
protected:
|
protected:
|
||||||
bool mInitialized = false;
|
bool mInitialized = false;
|
||||||
|
|
||||||
ualni mDrawPerSecond = 60;
|
ualni mDrawPerSecond = 1160;
|
||||||
ualni mProcPerSecond = 100;
|
ualni mProcPerSecond = 1300;
|
||||||
|
|
||||||
Timer mDrawTimer;
|
Timer mDrawTimer;
|
||||||
Timer mProcTimer;
|
Timer mProcTimer;
|
||||||
|
|
|
||||||
|
|
@ -221,7 +221,7 @@ namespace tp {
|
||||||
static_assert(tNRows == tNColoumns);
|
static_assert(tNRows == tNColoumns);
|
||||||
for (halni i = 0; i < tNColoumns; i++) {
|
for (halni i = 0; i < tNColoumns; i++) {
|
||||||
for (halni j = i + 1; j < tNColoumns; j++) {
|
for (halni j = i + 1; j < tNColoumns; j++) {
|
||||||
swap((*this)[i][j], (*this)[j][i]);
|
swapV((*this)[i][j], (*this)[j][i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -479,7 +479,7 @@ namespace tp {
|
||||||
Mat operator*(const Mat& in) { return transform(in); }
|
Mat operator*(const Mat& in) { return transform(in); }
|
||||||
|
|
||||||
Mat& transpose() {
|
Mat& transpose() {
|
||||||
swap(j.x, i.y);
|
swapV(j.x, i.y);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -635,9 +635,9 @@ namespace tp {
|
||||||
}
|
}
|
||||||
|
|
||||||
Mat& transpose() {
|
Mat& transpose() {
|
||||||
swap(I.y, J.x);
|
swapV(I.y, J.x);
|
||||||
swap(I.z, K.x);
|
swapV(I.z, K.x);
|
||||||
swap(J.z, K.y);
|
swapV(J.z, K.y);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,12 @@ namespace tp {
|
||||||
__builtin_debugtrap(); \
|
__builtin_debugtrap(); \
|
||||||
}
|
}
|
||||||
#elif defined(ENV_OS_LINUX)
|
#elif defined(ENV_OS_LINUX)
|
||||||
|
|
||||||
|
#include <csignal>
|
||||||
|
|
||||||
#define DEBUG_BREAK(expr) \
|
#define DEBUG_BREAK(expr) \
|
||||||
if (expr) { \
|
if (expr) { \
|
||||||
__builtin_trap(); \
|
raise(SIGTRAP); \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define DEBUG_BREAK(expr) ()
|
#define DEBUG_BREAK(expr) ()
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ namespace tp {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void swap(T& t1, T& t2) {
|
inline void swapV(T& t1, T& t2) {
|
||||||
const T tmp = t1;
|
const T tmp = t1;
|
||||||
t1 = t2;
|
t1 = t2;
|
||||||
t2 = tmp;
|
t2 = tmp;
|
||||||
|
|
|
||||||
|
|
@ -697,13 +697,13 @@ obj::ObjectsGUI::ViewStackNode obj::ObjectsGUI::listView(obj::ListObject* obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (childo.node()->prev && ImGui::Selectable("Move Up")) {
|
if (childo.node()->prev && ImGui::Selectable("Move Up")) {
|
||||||
tp::swap(childo.node()->prev->data, childo.data());
|
tp::swapV(childo.node()->prev->data, childo.data());
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (childo.node()->next && ImGui::Selectable("Move Down")) {
|
if (childo.node()->next && ImGui::Selectable("Move Down")) {
|
||||||
tp::swap(childo.node()->next->data, childo.data());
|
tp::swapV(childo.node()->next->data, childo.data());
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
28
TODO
28
TODO
|
|
@ -1,14 +1,31 @@
|
||||||
|
Widgets-New:
|
||||||
|
Lock-focus feature
|
||||||
|
Collapsing menu
|
||||||
|
Scrolling in basic layout
|
||||||
|
|
||||||
|
Add Widgets:
|
||||||
|
popups, drop-downs, tool-tips
|
||||||
|
list menu
|
||||||
|
|
||||||
|
Add UI scaling
|
||||||
|
Add Theming
|
||||||
|
|
||||||
|
|
||||||
|
Sketch3D:
|
||||||
|
Use new widgets
|
||||||
|
add gizmos
|
||||||
|
add save and loads
|
||||||
|
add better bui
|
||||||
|
selection
|
||||||
|
|
||||||
ALL:
|
ALL:
|
||||||
Gradually introduce STL into the project (replace own classes or add seamless interface and conversions into STL)
|
|
||||||
|
|
||||||
Remove BaseModule and Connection modules
|
Remove BaseModule and Connection modules
|
||||||
remove archiver and add boost serialization
|
remove archiver and add boost serialization ??
|
||||||
Bring windows old window to graphics
|
Bring ms-windows old window to graphics
|
||||||
|
|
||||||
Check Warnings
|
Check Warnings
|
||||||
Make all modules stable with tests
|
Make all modules stable with tests
|
||||||
|
|
||||||
|
|
||||||
Modules:
|
Modules:
|
||||||
Remove all static variable into module's data
|
Remove all static variable into module's data
|
||||||
|
|
||||||
|
|
@ -92,7 +109,6 @@ Math:
|
||||||
|
|
||||||
RayTracer:
|
RayTracer:
|
||||||
Features:
|
Features:
|
||||||
iodn
|
|
||||||
Normals flag
|
Normals flag
|
||||||
Material, Normals, per trig info
|
Material, Normals, per trig info
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ void DockWidget::removeSideWidget(Side side) {
|
||||||
removed = true;
|
removed = true;
|
||||||
}
|
}
|
||||||
if (removed) {
|
if (removed) {
|
||||||
swap(mSideWidgets[i].order, mSideWidgets[i + 1].order);
|
swapV(mSideWidgets[i].order, mSideWidgets[i + 1].order);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mSideWidgets[3].order = -1;
|
mSideWidgets[3].order = -1;
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,34 @@ public:
|
||||||
setup1();
|
setup1();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setupLay() {
|
||||||
|
mRootWidget.setRootWidget(&mWidget);
|
||||||
|
|
||||||
|
mWidget.addChild(&mWidgets[1]);
|
||||||
|
|
||||||
|
mWidgets[1].addChild(&mButtons[1]);
|
||||||
|
mWidgets[1].addChild(&mButtons[2]);
|
||||||
|
mWidgets[1].addChild(&mWidgets[2]);
|
||||||
|
|
||||||
|
RootWidget::setWidgetArea(mWidgets[1], { 300, 100, 350, 800 });
|
||||||
|
RootWidget::setWidgetArea(mButtons[2], { 100, 100, 150, 300 });
|
||||||
|
|
||||||
|
mWidgets[2].addChild(&mButtons[3]);
|
||||||
|
mWidgets[2].addChild(&mButtons[4]);
|
||||||
|
mWidgets[2].addChild(&mButtons[5]);
|
||||||
|
mWidgets[2].addChild(&mButtons[6]);
|
||||||
|
|
||||||
|
mButtons[1].setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding);
|
||||||
|
mButtons[2].setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding);
|
||||||
|
mButtons[3].setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding);
|
||||||
|
mButtons[4].setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding);
|
||||||
|
mButtons[5].setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding);
|
||||||
|
mButtons[6].setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding);
|
||||||
|
|
||||||
|
mWidgets[2].setSizePolicy(SizePolicy::Expanding, SizePolicy::Expanding);
|
||||||
|
((BasicLayout*)mWidgets[1].getLayout())->setLayoutPolicy(LayoutPolicy::Horizontal);
|
||||||
|
}
|
||||||
|
|
||||||
void setup1() {
|
void setup1() {
|
||||||
mRootWidget.setRootWidget(&mDockLayout);
|
mRootWidget.setRootWidget(&mDockLayout);
|
||||||
|
|
||||||
|
|
@ -122,6 +150,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Widget mWidgets[15];
|
||||||
|
ButtonWidget mButtons[15];
|
||||||
|
|
||||||
Widget mWidget;
|
Widget mWidget;
|
||||||
|
|
||||||
ButtonWidget mButton;
|
ButtonWidget mButton;
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ void RootWidget::setRootWidget(Widget* widget) {
|
||||||
void RootWidget::processFrame(EventHandler* events, const RectF& screenArea) {
|
void RootWidget::processFrame(EventHandler* events, const RectF& screenArea) {
|
||||||
mRoot->setArea(screenArea);
|
mRoot->setArea(screenArea);
|
||||||
|
|
||||||
if (!mDebugManager.update(this, *events)) return;
|
if (!gDebugWidget.update(this, *events)) return;
|
||||||
|
|
||||||
// construct hierarchy tree of widgets to process
|
// construct hierarchy tree of widgets to process
|
||||||
mUpdateManager.updateTreeToProcess(mRoot);
|
mUpdateManager.updateTreeToProcess(mRoot);
|
||||||
|
|
@ -49,7 +49,7 @@ void RootWidget::processFrame(EventHandler* events, const RectF& screenArea) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RootWidget::needsUpdate() const {
|
bool RootWidget::needsUpdate() const {
|
||||||
if (mDebugManager.isRedrawAlways()) return true;
|
if (gDebugWidget.isRedrawAlways()) return true;
|
||||||
return mUpdateManager.isPendingUpdates();
|
return mUpdateManager.isPendingUpdates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,7 +58,7 @@ void RootWidget::drawFrame(Canvas& canvas) {
|
||||||
|
|
||||||
drawRecursion(canvas, mRoot, { 0, 0 });
|
drawRecursion(canvas, mRoot, { 0, 0 });
|
||||||
|
|
||||||
mDebugManager.drawDebug(this, canvas);
|
gDebugWidget.drawDebug(this, canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,20 +7,26 @@
|
||||||
using namespace tp;
|
using namespace tp;
|
||||||
|
|
||||||
|
|
||||||
void BasicLayout::pickRect() {
|
void BasicLayout::pickRect(bool vertical) {
|
||||||
auto current = getArea();
|
auto current = getArea();
|
||||||
auto children = getChildrenEnclosure();
|
auto children = getChildrenEnclosure();
|
||||||
auto parent = getParentEnclosure();
|
auto parent = getParentEnclosure();
|
||||||
|
RectF newArea = current;
|
||||||
|
|
||||||
auto rangeX = pickRange(current.getRangeX(), children.getRangeX(), parent.getRangeX(), false);
|
if (vertical) {
|
||||||
auto rangeY = pickRange(current.getRangeY(), children.getRangeY(), parent.getRangeY(), true);
|
auto rangeY = pickRange(current.getRangeY(), children.getRangeY(), parent.getRangeY(), true);
|
||||||
|
newArea = RectF(current.getRangeX(), rangeY);
|
||||||
auto newArea = RectF(rangeX, rangeY);
|
} else {
|
||||||
|
auto rangeX = pickRange(current.getRangeX(), children.getRangeX(), parent.getRangeX(), false);
|
||||||
|
newArea = RectF(rangeX, current.getRangeY());
|
||||||
|
}
|
||||||
|
|
||||||
setArea(newArea);
|
setArea(newArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicLayout::clampRect() {
|
void BasicLayout::clampRect() {
|
||||||
|
DEBUG_ASSERT(0)
|
||||||
|
|
||||||
auto current = getArea();
|
auto current = getArea();
|
||||||
auto children = getChildrenEnclosure();
|
auto children = getChildrenEnclosure();
|
||||||
auto parent = getParentEnclosure();
|
auto parent = getParentEnclosure();
|
||||||
|
|
@ -31,13 +37,21 @@ void BasicLayout::clampRect() {
|
||||||
setArea(RectF(rangeX, rangeY));
|
setArea(RectF(rangeX, rangeY));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicLayout::adjustChildrenRect() {
|
void BasicLayout::updateLayout(bool vertical) {
|
||||||
if (children().empty()) return;
|
if (children().empty()) return;
|
||||||
|
|
||||||
|
if (vertical) {
|
||||||
switch (mLayoutPolicy) {
|
switch (mLayoutPolicy) {
|
||||||
case LayoutPolicy::Passive: break;
|
|
||||||
case LayoutPolicy::Vertical: adjustLayout(true); break;
|
case LayoutPolicy::Vertical: adjustLayout(true); break;
|
||||||
|
case LayoutPolicy::Passive:
|
||||||
|
case LayoutPolicy::Horizontal: break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (mLayoutPolicy) {
|
||||||
case LayoutPolicy::Horizontal: adjustLayout(false); break;
|
case LayoutPolicy::Horizontal: adjustLayout(false); break;
|
||||||
|
case LayoutPolicy::Passive:
|
||||||
|
case LayoutPolicy::Vertical: break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,9 +75,7 @@ void BasicLayout::adjustLayout(bool vertical) {
|
||||||
Vec2F availableSize = getArea().size;
|
Vec2F availableSize = getArea().size;
|
||||||
|
|
||||||
for (auto child : children()) {
|
for (auto child : children()) {
|
||||||
if (child->getLayout()->getSizePolicy()[!vertical] != SizePolicy::Minimal) {
|
child->getLayout()->pickRect(vertical);
|
||||||
child->getLayout()->pickRect();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (child->getLayout()->getSizePolicy()[vertical] == SizePolicy::Expanding) {
|
if (child->getLayout()->getSizePolicy()[vertical] == SizePolicy::Expanding) {
|
||||||
contributors.emplace_back( child, true );
|
contributors.emplace_back( child, true );
|
||||||
|
|
@ -71,7 +83,7 @@ void BasicLayout::adjustLayout(bool vertical) {
|
||||||
auto area = child->getLayout()->getArea();
|
auto area = child->getLayout()->getArea();
|
||||||
area.size[vertical] = 0;
|
area.size[vertical] = 0;
|
||||||
child->setAreaCache(area);
|
child->setAreaCache(area);
|
||||||
child->getLayout()->clampRect();
|
child->getLayout()->clampMinMaxSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
contentSize += child->getLayout()->getArea().size;
|
contentSize += child->getLayout()->getArea().size;
|
||||||
|
|
@ -104,15 +116,26 @@ void BasicLayout::adjustLayout(bool vertical) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// arrange
|
// set opposite direction size
|
||||||
|
for (auto child : children()) {
|
||||||
|
// if (child->getLayout()->getSizePolicy()[!vertical] != SizePolicy::Minimal) {
|
||||||
|
auto area = child->getLayout()->getArea();
|
||||||
|
area.size[!vertical] = getArea().size[!vertical] - mLayoutMargin * 2;
|
||||||
|
child->setAreaCache(area);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// set pos
|
||||||
halnf iterPos = mLayoutMargin;
|
halnf iterPos = mLayoutMargin;
|
||||||
for (auto child : children()) {
|
for (auto child : children()) {
|
||||||
auto area = child->getLayout()->getArea();
|
auto area = child->getLayout()->getArea();
|
||||||
|
|
||||||
area.pos[vertical] = iterPos;
|
area.pos[vertical] = iterPos;
|
||||||
|
area.pos[!vertical] = mLayoutMargin;
|
||||||
|
|
||||||
iterPos += area.size[vertical] + mLayoutGap;
|
iterPos += area.size[vertical] + mLayoutGap;
|
||||||
child->setAreaCache(area);
|
child->setAreaCache(area);
|
||||||
|
|
||||||
|
|
||||||
// child->updateAnimations();
|
// child->updateAnimations();
|
||||||
// child->triggerWidgetUpdate("layout changed");
|
// child->triggerWidgetUpdate("layout changed");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ bool DockLayout::undockWidget(Side side) {
|
||||||
removed = true;
|
removed = true;
|
||||||
}
|
}
|
||||||
if (removed) {
|
if (removed) {
|
||||||
swap(mSideWidgets[i].order, mSideWidgets[i + 1].order);
|
swapV(mSideWidgets[i].order, mSideWidgets[i + 1].order);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mSideWidgets[3].order = -1;
|
mSideWidgets[3].order = -1;
|
||||||
|
|
@ -184,6 +184,15 @@ auto DockLayout::getSideFromWidget(Widget* widget) -> Side {
|
||||||
return DockLayout::NONE;
|
return DockLayout::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DockLayout::updateLayout(bool vertical) {
|
||||||
|
for (auto child : children()) {
|
||||||
|
child->getLayout()->pickRect(vertical);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vertical) return;
|
||||||
|
adjustChildrenRect();
|
||||||
|
}
|
||||||
|
|
||||||
void DockLayout::adjustChildrenRect() {
|
void DockLayout::adjustChildrenRect() {
|
||||||
calculateSideAreas();
|
calculateSideAreas();
|
||||||
calculateResizeHandles();
|
calculateResizeHandles();
|
||||||
|
|
|
||||||
|
|
@ -3,21 +3,21 @@
|
||||||
|
|
||||||
using namespace tp;
|
using namespace tp;
|
||||||
|
|
||||||
void FloatingLayout::pickRect() {
|
void FloatingLayout::pickRect(bool vertical) {
|
||||||
if (mIsFloating) {
|
if (mIsFloating) {
|
||||||
auto area = getArea();
|
auto area = getArea();
|
||||||
|
|
||||||
if (mIsResizing) {
|
if (mIsResizing) {
|
||||||
mPointerCurrent.clamp(mMinSize, mMaxSize);
|
mPointerCurrent.clamp(mMinSize, mMaxSize);
|
||||||
|
|
||||||
area.size = mPointerCurrent + mHandleSize / 2.f;
|
area.size[vertical] = (mPointerCurrent + mHandleSize / 2.f)[vertical];
|
||||||
|
|
||||||
for (auto child : children()) {
|
for (auto child : children()) {
|
||||||
child->triggerWidgetUpdate("floating menu resized");
|
child->triggerWidgetUpdate("floating menu resized");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (mIsFloating) {
|
} else if (mIsFloating) {
|
||||||
area.pos += mPointerCurrent - mPointerStart;
|
area.pos[vertical] += (mPointerCurrent - mPointerStart)[vertical];
|
||||||
}
|
}
|
||||||
|
|
||||||
setArea(area);
|
setArea(area);
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,19 @@
|
||||||
#include "DebugManager.hpp"
|
#include "DebugManager.hpp"
|
||||||
#include "RootWidget.hpp"
|
#include "RootWidget.hpp"
|
||||||
|
#include "BasicLayout.hpp"
|
||||||
|
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
using namespace tp;
|
using namespace tp;
|
||||||
|
|
||||||
|
DebugManager tp::gDebugWidget;
|
||||||
|
|
||||||
|
#define LIST_SIZE { -FLT_MIN, 150 }
|
||||||
|
|
||||||
bool DebugManager::update(RootWidget* rootWidget, EventHandler& events) {
|
bool DebugManager::update(RootWidget* rootWidget, EventHandler& events) {
|
||||||
|
mRootWidget = rootWidget;
|
||||||
|
|
||||||
if (mDebug) {
|
if (mDebug) {
|
||||||
auto area = rootWidget->mRoot->getAreaT();
|
auto area = rootWidget->mRoot->getAreaT();
|
||||||
area.size -= { 400, 0 };
|
area.size -= { 400, 0 };
|
||||||
|
|
@ -14,38 +22,60 @@ bool DebugManager::update(RootWidget* rootWidget, EventHandler& events) {
|
||||||
events.setEnableKeyEvents(true);
|
events.setEnableKeyEvents(true);
|
||||||
if (events.isPressed(InputID::K)) mDebugStopProcessing = !mDebugStopProcessing;
|
if (events.isPressed(InputID::K)) mDebugStopProcessing = !mDebugStopProcessing;
|
||||||
if (mDebugStopProcessing) return false;
|
if (mDebugStopProcessing) return false;
|
||||||
|
|
||||||
|
if (auto widget = rootWidget->mUpdateManager.mInFocusWidget) {
|
||||||
|
if (auto lay = dynamic_cast<BasicLayout*>(widget->getLayout())) {
|
||||||
|
if (events.isPressed(InputID::V)) lay->setLayoutPolicy(LayoutPolicy::Vertical);
|
||||||
|
if (events.isPressed(InputID::H)) lay->setLayoutPolicy(LayoutPolicy::Horizontal);
|
||||||
|
|
||||||
|
auto sizing = lay->getSizePolicy();
|
||||||
|
|
||||||
|
if (events.isDown(InputID::X)) {
|
||||||
|
if (events.isPressed(InputID::S)) lay->setSizePolicy(SizePolicy::Minimal, sizing.y);
|
||||||
|
if (events.isPressed(InputID::E)) lay->setSizePolicy(SizePolicy::Expanding, sizing.y);
|
||||||
|
}
|
||||||
|
if (events.isDown(InputID::Y)) {
|
||||||
|
if (events.isPressed(InputID::S)) lay->setSizePolicy(sizing.x, SizePolicy::Minimal);
|
||||||
|
if (events.isPressed(InputID::E)) lay->setSizePolicy(sizing.x, SizePolicy::Expanding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto breakWidget = rootWidget->mUpdateManager.mInFocusWidget) {
|
||||||
|
if (events.isPressed(InputID::P)) mProcBreakpoints.insert(breakWidget);
|
||||||
|
if (events.isPressed(InputID::L)) mLayBreakpoints.insert(breakWidget);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugManager::drawDebug(RootWidget* rootWidget, Canvas& canvas) {
|
void DebugManager::drawDebug(RootWidget* rootWidget, Canvas& canvas) {
|
||||||
|
mRootWidget = rootWidget;
|
||||||
|
|
||||||
ImGui::Checkbox("Draw debug", &mDebug);
|
ImGui::Checkbox("Draw debug", &mDebug);
|
||||||
|
|
||||||
|
if (!mDebug) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine(); ImGui::Text("To Toggle processing press k");
|
||||||
|
|
||||||
auto& upd = rootWidget->mUpdateManager;
|
auto& upd = rootWidget->mUpdateManager;
|
||||||
|
|
||||||
if (mDebug) {
|
|
||||||
recursiveDraw(canvas, rootWidget->mRoot, { 0, 0 }, 0);
|
recursiveDraw(canvas, rootWidget->mRoot, { 0, 0 }, 0);
|
||||||
|
|
||||||
ImGui::Text("Triggered Widgets: %i", (int) upd.mTriggeredWidgets.size());
|
ImGui::Text("Triggered: %i", (int) upd.mTriggeredWidgets.size());
|
||||||
ImGui::Text("Widgets To Process: %i", upd.mDebugWidgetsToProcess);
|
ImGui::SameLine(); ImGui::Text("Processing: %i", upd.mDebugWidgetsToProcess);
|
||||||
|
|
||||||
ImGui::Text("To Toggle processing press k");
|
|
||||||
ImGui::Checkbox("Stop processing", &mDebugStopProcessing);
|
ImGui::Checkbox("Stop processing", &mDebugStopProcessing);
|
||||||
ImGui::Checkbox("Force new frames", &mDebugRedrawAlways);
|
ImGui::SameLine(); ImGui::Checkbox("Force new frames", &mDebugRedrawAlways);
|
||||||
|
ImGui::SameLine(); ImGui::Checkbox("Slow-mo", &mSlowMotion);
|
||||||
if (ImGui::CollapsingHeader("Triggered")) {
|
|
||||||
if (ImGui::BeginListBox("##triggered", { -FLT_MIN, 300 })) {
|
|
||||||
for (auto widget : upd.mTriggeredWidgets) {
|
|
||||||
widgetMenu(widget.first);
|
|
||||||
}
|
|
||||||
ImGui::EndListBox();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (upd.mInFocusWidget) {
|
if (upd.mInFocusWidget) {
|
||||||
if (ImGui::CollapsingHeader("Under cursor")) {
|
ImGui::Text("Under cursor");
|
||||||
if (ImGui::BeginListBox("##under_cursor", { -FLT_MIN, 300 })) {
|
{
|
||||||
|
if (ImGui::BeginListBox("##under_cursor", LIST_SIZE)) {
|
||||||
for (auto widget = upd.mInFocusWidget; widget && widget->mParent; widget = widget->mParent) {
|
for (auto widget = upd.mInFocusWidget; widget && widget->mParent; widget = widget->mParent) {
|
||||||
widgetMenu(widget);
|
widgetMenu(widget);
|
||||||
}
|
}
|
||||||
|
|
@ -53,14 +83,25 @@ void DebugManager::drawDebug(RootWidget* rootWidget, Canvas& canvas) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::Text("Triggered");
|
||||||
|
{
|
||||||
|
if (ImGui::BeginListBox("##triggered", LIST_SIZE)) {
|
||||||
|
for (auto widget : upd.mTriggeredWidgets) {
|
||||||
|
widgetMenu(widget.first);
|
||||||
}
|
}
|
||||||
|
ImGui::EndListBox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drawLayoutOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugManager::recursiveDraw(Canvas& canvas, Widget* active, const Vec2F& pos, int depthOrder) {
|
void DebugManager::recursiveDraw(Canvas& canvas, Widget* active, const Vec2F& pos, int depthOrder) {
|
||||||
auto area = RectF{ pos, active->getAreaT().size };
|
auto area = RectF{ pos, active->getAreaT().size };
|
||||||
|
|
||||||
if (active->isUpdate()) {
|
if (active->isUpdate()) {
|
||||||
RGBA color = { 1, 0, 0, 1};
|
RGBA color = { 1, 0, 0, 1 };
|
||||||
canvas.frame(area, color);
|
canvas.frame(area, color);
|
||||||
canvas.text((active->mDebug.id + ":" + std::to_string(depthOrder)).c_str(), area, 22, Canvas::Align::LC, 2, color);
|
canvas.text((active->mDebug.id + ":" + std::to_string(depthOrder)).c_str(), area, 22, Canvas::Align::LC, 2, color);
|
||||||
}
|
}
|
||||||
|
|
@ -71,7 +112,7 @@ void DebugManager::recursiveDraw(Canvas& canvas, Widget* active, const Vec2F& po
|
||||||
canvas.circle(active->mDebug.pGlobal, 15, active->mDebug.col);
|
canvas.circle(active->mDebug.pGlobal, 15, active->mDebug.col);
|
||||||
}
|
}
|
||||||
|
|
||||||
RGBA color = { 1, 0, 0, 0.3f};
|
RGBA color = { 1, 0, 0, 0.3f };
|
||||||
canvas.debugCross(area, color);
|
canvas.debugCross(area, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -84,7 +125,8 @@ void DebugManager::recursiveDraw(Canvas& canvas, Widget* active, const Vec2F& po
|
||||||
void DebugManager::widgetMenu(Widget* widget) {
|
void DebugManager::widgetMenu(Widget* widget) {
|
||||||
|
|
||||||
ImGui::PushID(widget);
|
ImGui::PushID(widget);
|
||||||
if (ImGui::CollapsingHeader(widget->mDebug.id.c_str())) {
|
|
||||||
|
if (ImGui::CollapsingHeader((widget->mDebug.id + std::to_string((long) widget)).c_str())) {
|
||||||
|
|
||||||
ImGui::Text("trigger reason: %s", widget->mDebug.triggerReason.c_str());
|
ImGui::Text("trigger reason: %s", widget->mDebug.triggerReason.c_str());
|
||||||
|
|
||||||
|
|
@ -93,24 +135,38 @@ void DebugManager::widgetMenu(Widget* widget) {
|
||||||
widget->setArea(area);
|
widget->setArea(area);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImGui::InputFloat2("min size", &widget->mMinSize.x);
|
auto layout = widget->getLayout();
|
||||||
// ImGui::InputFloat2("max size", &widget->mMaxSize.x);
|
|
||||||
|
|
||||||
// int sizePolicyX = int(widget->mSizePolicy.x);
|
ImGui::InputFloat2("min size", &layout->mMinSize.x);
|
||||||
// int sizePolicyY = int(widget->mSizePolicy.y);
|
ImGui::InputFloat2("max size", &layout->mMaxSize.x);
|
||||||
// int layout = int(widget->mLayoutPolicy);
|
|
||||||
|
|
||||||
// if (ImGui::Combo("Size Policy X", &sizePolicyX, "Fixed\0Expanding\0Minimal\0")) {
|
if (auto pBasicLayout = dynamic_cast<BasicLayout*>(widget->getLayout())) {
|
||||||
// widget->setSizePolicy(SizePolicy(sizePolicyX), SizePolicy(sizePolicyY));
|
int sizePolicyX = int(pBasicLayout->mSizePolicy.x);
|
||||||
// }
|
int sizePolicyY = int(pBasicLayout->mSizePolicy.y);
|
||||||
|
int policy = int(pBasicLayout->mLayoutPolicy);
|
||||||
|
|
||||||
// if (ImGui::Combo("Size Policy Y", &sizePolicyY, "Fixed\0Expanding\0Minimal\0")) {
|
if (ImGui::Combo("Size Policy X", &sizePolicyX, "Fixed\0Expanding\0Minimal\0")) {
|
||||||
// widget->setSizePolicy(SizePolicy(sizePolicyX), SizePolicy(sizePolicyY));
|
widget->setSizePolicy(SizePolicy(sizePolicyX), SizePolicy(sizePolicyY));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if (ImGui::Combo("Layout", &layout, "Passive\0Vertical\0Horizontal\0")) {
|
if (ImGui::Combo("Size Policy Y", &sizePolicyY, "Fixed\0Expanding\0Minimal\0")) {
|
||||||
// widget->setLayoutPolicy(LayoutPolicy(layout));
|
widget->setSizePolicy(SizePolicy(sizePolicyX), SizePolicy(sizePolicyY));
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
if (ImGui::Combo("Layout", &policy, "Passive\0Vertical\0Horizontal\0")) {
|
||||||
|
pBasicLayout->mLayoutPolicy = LayoutPolicy(policy);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebugManager::drawLayoutOrder() {
|
||||||
|
ImGui::Text("Layout Processing Order");
|
||||||
|
if (ImGui::BeginListBox("##layout_order", LIST_SIZE)) {
|
||||||
|
for (auto iter : mRootWidget->mLayoutManager.mLayOrder) {
|
||||||
|
ImGui::Text("%i %s (%s)", iter.second, iter.first->mDebug.id.c_str(), std::to_string((long) iter.first).c_str());
|
||||||
|
}
|
||||||
|
ImGui::EndListBox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,17 +1,96 @@
|
||||||
#include "LayoutManager.hpp"
|
#include "LayoutManager.hpp"
|
||||||
|
#include "DebugManager.hpp"
|
||||||
|
|
||||||
#include "Widget.hpp"
|
#include "DockLayout.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace tp;
|
using namespace tp;
|
||||||
|
|
||||||
void LayoutManager::adjust(Widget* root) {
|
void LayoutManager::adjust(Widget* root) {
|
||||||
Widget::dfs(
|
for (auto i : IterRange(2)) {
|
||||||
root,
|
mVertical = bool(i);
|
||||||
[](Widget* widget) {
|
|
||||||
widget->getLayout()->pickRect();
|
mDepGraph.clear();
|
||||||
},
|
mLayOrder.clear();
|
||||||
[](Widget* widget) {
|
mRoots.clear();
|
||||||
widget->getLayout()->adjustChildrenRect();
|
|
||||||
|
findDependencies(root);
|
||||||
|
|
||||||
|
// TODO : implement better topological-sort
|
||||||
|
for (auto iterRoot : mRoots) {
|
||||||
|
topologicalSort(iterRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
adjustLayouts();
|
||||||
}
|
}
|
||||||
);
|
}
|
||||||
|
|
||||||
|
void LayoutManager::findDependencies(Widget* root) {
|
||||||
|
mDepGraph.insert({ root, {} });
|
||||||
|
|
||||||
|
Widget::dfs(root, [this](Widget* widget) { mDepGraph.insert({ widget, {} }); });
|
||||||
|
|
||||||
|
for (auto& [widget, deps] : mDepGraph) {
|
||||||
|
for (auto child : widget->mChildren) {
|
||||||
|
mDepGraph.insert({ child, {} });
|
||||||
|
|
||||||
|
if (auto depOrder = getLayoutOrder(widget->getLayout(), child->getLayout())) {
|
||||||
|
if (depOrder > 0) {
|
||||||
|
deps.depends.push_back(child);
|
||||||
|
mDepGraph[child].references++;
|
||||||
|
} else {
|
||||||
|
mDepGraph[child].depends.push_back(widget);
|
||||||
|
mDepGraph[widget].references++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find root
|
||||||
|
for (auto& node : mDepGraph) {
|
||||||
|
if (node.second.references == 0) {
|
||||||
|
mRoots.push_back(node.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayoutManager::topologicalSort(Widget* root, int depth) {
|
||||||
|
mDepGraph.at(root).depth = max(mDepGraph.at(root).depth, depth);
|
||||||
|
|
||||||
|
for (auto& dep : mDepGraph.at(root).depends) {
|
||||||
|
topologicalSort(dep, depth + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayoutManager::adjustLayouts() {
|
||||||
|
for (auto& iter : mDepGraph) {
|
||||||
|
mLayOrder.emplace_back(iter.first, iter.second.depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(mLayOrder.begin(), mLayOrder.end(), [](auto first, auto second){
|
||||||
|
return first.second > second.second;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (auto& [iter, _] : mLayOrder) {
|
||||||
|
iter->getLayout()->updateLayout(mVertical);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sizePolicyDep[3][3] = {
|
||||||
|
// f s e child
|
||||||
|
{ 1, 1, 1 }, // parent fixed
|
||||||
|
{ 1, 1, 1 }, // parent shrink
|
||||||
|
{ 1, 1, 1 }, // parent expand
|
||||||
|
};
|
||||||
|
|
||||||
|
int LayoutManager::getLayoutOrder(WidgetLayout* parent, WidgetLayout* child) const {
|
||||||
|
if (!parent || !child) return 0;
|
||||||
|
|
||||||
|
auto policyParent = parent->getSizePolicy()[mVertical];
|
||||||
|
auto policyChild = parent->getSizePolicy()[mVertical];
|
||||||
|
|
||||||
|
if (dynamic_cast<DockLayout*>(parent)) return -1;
|
||||||
|
|
||||||
|
return sizePolicyDep[int(policyParent)][int(policyChild)];
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include "UpdateManager.hpp"
|
#include "UpdateManager.hpp"
|
||||||
|
#include "DebugManager.hpp"
|
||||||
|
|
||||||
using namespace tp;
|
using namespace tp;
|
||||||
|
|
||||||
|
|
@ -64,7 +65,7 @@ void UpdateManager::getWidgetPath(Widget* widget, std::vector<Widget*>& out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto i = 0; i < out.size() / 2; i++) {
|
for (auto i = 0; i < out.size() / 2; i++) {
|
||||||
swap(out[i], out[out.size() - i - 1]);
|
swapV(out[i], out[out.size() - i - 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,7 +137,7 @@ void UpdateManager::processActiveTree(Widget* iter, EventHandler& events, Vec2F
|
||||||
iter->mDebug.pGlobal = current;
|
iter->mDebug.pGlobal = current;
|
||||||
|
|
||||||
events.setCursorOrigin(current);
|
events.setCursorOrigin(current);
|
||||||
iter->process(events);
|
procWidget(iter, events, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto child : iter->mDepthOrder) {
|
for (auto child : iter->mDepthOrder) {
|
||||||
|
|
@ -178,14 +179,16 @@ void UpdateManager::processFocusItems(EventHandler& events) {
|
||||||
widget->mDebug.pGlobal = widgetGlobalPos[iter];
|
widget->mDebug.pGlobal = widgetGlobalPos[iter];
|
||||||
|
|
||||||
if (!eventsProcessed && widget->processesEvents()) {
|
if (!eventsProcessed && widget->processesEvents()) {
|
||||||
events.setEnableKeyEvents(true);
|
procWidget(widget, events, true);
|
||||||
widget->process(events);
|
|
||||||
|
|
||||||
events.setEnableKeyEvents(false);
|
|
||||||
eventsProcessed = true;
|
eventsProcessed = true;
|
||||||
} else {
|
} else {
|
||||||
widget->process(events);
|
procWidget(widget, events, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateManager::procWidget(Widget* widget, EventHandler& events, bool withEvents) {
|
||||||
|
events.setEnableKeyEvents(withEvents);
|
||||||
|
gDebugWidget.checkProcBreakPoints(widget);
|
||||||
|
widget->process(events);
|
||||||
|
}
|
||||||
|
|
@ -19,13 +19,16 @@ namespace tp {
|
||||||
};
|
};
|
||||||
|
|
||||||
class WidgetLayout {
|
class WidgetLayout {
|
||||||
|
friend class DebugManager;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit WidgetLayout(Widget* widget) { mWidget = widget; }
|
explicit WidgetLayout(Widget* widget) { mWidget = widget; }
|
||||||
virtual ~WidgetLayout() = default;
|
virtual ~WidgetLayout() = default;
|
||||||
|
|
||||||
virtual void pickRect() = 0;
|
virtual void updateLayout(bool vertical) {}
|
||||||
|
|
||||||
|
virtual void pickRect(bool vertical) = 0;
|
||||||
virtual void clampRect() = 0;
|
virtual void clampRect() = 0;
|
||||||
virtual void adjustChildrenRect() = 0;
|
|
||||||
[[nodiscard]] virtual RectF getAvailableChildArea() const;
|
[[nodiscard]] virtual RectF getAvailableChildArea() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,5 @@ namespace tp {
|
||||||
|
|
||||||
LayoutManager mLayoutManager;
|
LayoutManager mLayoutManager;
|
||||||
UpdateManager mUpdateManager;
|
UpdateManager mUpdateManager;
|
||||||
DebugManager mDebugManager;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -5,14 +5,19 @@
|
||||||
namespace tp {
|
namespace tp {
|
||||||
|
|
||||||
class BasicLayout : public WidgetLayout {
|
class BasicLayout : public WidgetLayout {
|
||||||
|
friend class DebugManager;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BasicLayout(Widget* widget) : WidgetLayout(widget) {}
|
explicit BasicLayout(Widget* widget) : WidgetLayout(widget) {}
|
||||||
|
|
||||||
void pickRect() override;
|
void updateLayout(bool vertical) override;
|
||||||
|
|
||||||
|
void pickRect(bool vertical) override;
|
||||||
void clampRect() override;
|
void clampRect() override;
|
||||||
void adjustChildrenRect() override;
|
|
||||||
[[nodiscard]] RectF getAvailableChildArea() const override;
|
[[nodiscard]] RectF getAvailableChildArea() const override;
|
||||||
|
|
||||||
|
void setLayoutPolicy(LayoutPolicy layout) { mLayoutPolicy = layout; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void adjustLayout(bool vertical);
|
void adjustLayout(bool vertical);
|
||||||
static halnf changeChildSize(Widget*, halnf diff, bool vertical);
|
static halnf changeChildSize(Widget*, halnf diff, bool vertical);
|
||||||
|
|
@ -20,6 +25,6 @@ namespace tp {
|
||||||
private:
|
private:
|
||||||
LayoutPolicy mLayoutPolicy = LayoutPolicy::Vertical;
|
LayoutPolicy mLayoutPolicy = LayoutPolicy::Vertical;
|
||||||
halnf mLayoutGap = 5;
|
halnf mLayoutGap = 5;
|
||||||
halnf mLayoutMargin = 10;
|
halnf mLayoutMargin = 9;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -42,9 +42,10 @@ namespace tp {
|
||||||
void updatePreviewSide(const Vec2F& pointer);
|
void updatePreviewSide(const Vec2F& pointer);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void pickRect() override {}
|
void pickRect(bool vertical) override {}
|
||||||
void adjustChildrenRect() override;
|
|
||||||
void clampRect() override {};
|
void clampRect() override {};
|
||||||
|
void updateLayout(bool vertical) override;
|
||||||
|
void adjustChildrenRect();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool setCenterWidget(Widget* widget);
|
bool setCenterWidget(Widget* widget);
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ namespace tp {
|
||||||
RectF resizeHandleRect();
|
RectF resizeHandleRect();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void pickRect() override;
|
void pickRect(bool vertical) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mIsFloating = false;
|
bool mIsFloating = false;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "Widget.hpp"
|
#include "Widget.hpp"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
namespace tp {
|
namespace tp {
|
||||||
class DebugManager {
|
class DebugManager {
|
||||||
public:
|
public:
|
||||||
|
|
@ -11,15 +13,38 @@ namespace tp {
|
||||||
bool update(RootWidget* rootWidget, EventHandler& events);
|
bool update(RootWidget* rootWidget, EventHandler& events);
|
||||||
void drawDebug(RootWidget* rootWidget, Canvas& canvas);
|
void drawDebug(RootWidget* rootWidget, Canvas& canvas);
|
||||||
|
|
||||||
|
void checkProcBreakPoints(Widget* widget) {
|
||||||
|
if (mProcBreakpoints.find(widget) != mProcBreakpoints.end()) {
|
||||||
|
mProcBreakpoints.erase(widget);
|
||||||
|
DEBUG_BREAK(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkLayoutBreakpoints(Widget* widget) {
|
||||||
|
if (mLayBreakpoints.find(widget) != mLayBreakpoints.end()) {
|
||||||
|
mLayBreakpoints.erase(widget);
|
||||||
|
DEBUG_BREAK(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void recursiveDraw(Canvas& canvas, Widget* active, const Vec2F& pos, int depthOrder);
|
void recursiveDraw(Canvas& canvas, Widget* active, const Vec2F& pos, int depthOrder);
|
||||||
|
|
||||||
static void widgetMenu(Widget*);
|
static void widgetMenu(Widget*);
|
||||||
|
void drawLayoutOrder();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
RootWidget* mRootWidget = nullptr;
|
||||||
|
|
||||||
// debug
|
// debug
|
||||||
bool mDebug = true;
|
bool mDebug = true;
|
||||||
bool mDebugStopProcessing = false;
|
bool mDebugStopProcessing = false;
|
||||||
bool mDebugRedrawAlways = false;
|
bool mDebugRedrawAlways = false;
|
||||||
|
bool mSlowMotion = false;
|
||||||
|
|
||||||
|
std::set<Widget*> mProcBreakpoints;
|
||||||
|
std::set<Widget*> mLayBreakpoints;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern DebugManager gDebugWidget;
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +1,39 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Layout.hpp"
|
#include "Layout.hpp"
|
||||||
|
#include "DebugManager.hpp"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace tp {
|
namespace tp {
|
||||||
class LayoutManager {
|
class LayoutManager {
|
||||||
|
friend DebugManager;
|
||||||
|
|
||||||
|
struct DepNode {
|
||||||
|
std::vector<Widget*> depends;
|
||||||
|
int references = 0;
|
||||||
|
int depth = 0;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LayoutManager() = default;
|
LayoutManager() = default;
|
||||||
|
|
||||||
void adjust(Widget* root);
|
void adjust(Widget* root);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void findDependencies(Widget* root);
|
||||||
|
void topologicalSort(Widget* root, int depth = 0);
|
||||||
|
void adjustLayouts();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int getLayoutOrder(WidgetLayout* parent, WidgetLayout* child) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<Widget*, DepNode> mDepGraph;
|
||||||
|
std::vector<Widget*> mRoots;
|
||||||
|
|
||||||
|
std::vector<std::pair<Widget*, int>> mLayOrder;
|
||||||
|
bool mVertical = false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -28,6 +28,9 @@ namespace tp {
|
||||||
void processActiveTree(Widget* iter, EventHandler& events, Vec2F pos);
|
void processActiveTree(Widget* iter, EventHandler& events, Vec2F pos);
|
||||||
void processFocusItems(EventHandler& events);
|
void processFocusItems(EventHandler& events);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void procWidget(Widget* widget, EventHandler& events, bool withEvents = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<Widget*, bool> mTriggeredWidgets;
|
std::map<Widget*, bool> mTriggeredWidgets;
|
||||||
Widget* mInFocusWidget = nullptr;
|
Widget* mInFocusWidget = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ namespace tp {
|
||||||
|
|
||||||
[[nodiscard]] bool propagateEventsToChildren() const override;
|
[[nodiscard]] bool propagateEventsToChildren() const override;
|
||||||
[[nodiscard]] bool needsNextFrame() const override;
|
[[nodiscard]] bool needsNextFrame() const override;
|
||||||
|
[[nodiscard]]bool processesEvents() const override { return true; }
|
||||||
|
|
||||||
void drawSide(DockLayout::Side side, Canvas& canvas);
|
void drawSide(DockLayout::Side side, Canvas& canvas);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue