Cleanup widgets
This commit is contained in:
parent
9e7704a446
commit
bce1dbacc2
30 changed files with 705 additions and 654 deletions
|
|
@ -30,15 +30,15 @@ namespace tp {
|
||||||
Canvas::ImageHandle mImage;
|
Canvas::ImageHandle mImage;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EditorWidget : public Widget {
|
class EditorWidget : public WorkspaceWidget {
|
||||||
public:
|
public:
|
||||||
EditorWidget(Canvas* canvas, Editor* editor) :
|
EditorWidget(Canvas* canvas, Editor* editor) :
|
||||||
mViewport(canvas, editor) {
|
mViewport(canvas, editor) {
|
||||||
mEditor = editor;
|
mEditor = editor;
|
||||||
|
|
||||||
this->mChildWidgets.pushBack(&mViewport);
|
mDockSpace.addSideWidget(&mNavigationMenu, GridLayoutWidget::RIGHT);
|
||||||
this->mChildWidgets.pushBack(&mSplitView);
|
mDockSpace.addSideWidget(&mRenderMenu, GridLayoutWidget::LEFT);
|
||||||
this->mChildWidgets.pushBack(&mSettingsWidget);
|
mDockSpace.setCenterWidget(&mViewport);
|
||||||
|
|
||||||
// Render
|
// Render
|
||||||
{
|
{
|
||||||
|
|
@ -68,55 +68,24 @@ namespace tp {
|
||||||
mNavigationMenu.setLabel("Navigation");
|
mNavigationMenu.setLabel("Navigation");
|
||||||
}
|
}
|
||||||
|
|
||||||
mSettingsWidget.addWidget(&mRenderMenu);
|
mRenderPathTracer.mCallback = [this]() {
|
||||||
mSettingsWidget.addWidget(&mNavigationMenu);
|
mEditor->renderPathFrame();
|
||||||
|
mEditor->setRenderType(Editor::RenderType::PATH_TRACER);
|
||||||
|
};
|
||||||
|
|
||||||
|
mRenderRaster.mCallback = [this]() { mEditor->setRenderType(Editor::RenderType::RASTER); };
|
||||||
|
mRenderDeNoise.mCallback = [this]() { mEditor->denoisePathRenderBuffers(); };
|
||||||
|
mNavigationOrbit.mCallback = [this]() { mNavigationType = ORBIT; };
|
||||||
|
mNavigationPan.mCallback = [this]() { mNavigationType = PAN; };
|
||||||
|
mNavigationZoom.mCallback = [this](){ mNavigationType = ZOOM; };
|
||||||
|
mNavigationReset.mCallback = [this]() { mEditor->navigationReset(); };
|
||||||
}
|
}
|
||||||
|
|
||||||
void eventProcess(const Events& events) override {
|
void eventProcess(const Events& events) override {
|
||||||
mSplitView.setArea(this->mArea);
|
|
||||||
|
|
||||||
mViewport.setArea(mSplitView.getFirst());
|
|
||||||
mViewport.mEnable = mSplitView.getFirstEnabled();
|
|
||||||
|
|
||||||
mSettingsWidget.setArea(mSplitView.getSecond());
|
|
||||||
mSettingsWidget.mEnable = mSplitView.getSecondEnabled();
|
|
||||||
|
|
||||||
// render settings
|
|
||||||
{
|
|
||||||
if (mRenderPathTracer.isFired()) {
|
|
||||||
mEditor->renderPathFrame();
|
|
||||||
mEditor->setRenderType(Editor::RenderType::PATH_TRACER);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mRenderRaster.isFired()) {
|
|
||||||
mEditor->setRenderType(Editor::RenderType::RASTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mRenderDeNoise.isFired()) {
|
|
||||||
mEditor->denoisePathRenderBuffers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// navigation
|
// navigation
|
||||||
{
|
{
|
||||||
if (mNavigationOrbit.isFired()) {
|
|
||||||
mNavigationType = ORBIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mNavigationPan.isFired()) {
|
|
||||||
mNavigationType = PAN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mNavigationZoom.isFired()) {
|
|
||||||
mNavigationType = ZOOM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mNavigationReset.isFired()) {
|
|
||||||
mEditor->navigationReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& activeArea = mViewport.mArea;
|
const auto& activeArea = mViewport.mArea;
|
||||||
if (this->isHolding() && activeArea.isInside(events.getPointer())) {
|
if (mViewport.isHolding()) {
|
||||||
switch (mNavigationType) {
|
switch (mNavigationType) {
|
||||||
case ORBIT: mEditor->navigationOrbit(events.getPointerDelta() / activeArea.size * 3); break;
|
case ORBIT: mEditor->navigationOrbit(events.getPointerDelta() / activeArea.size * 3); break;
|
||||||
|
|
||||||
|
|
@ -132,6 +101,8 @@ namespace tp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WorkspaceWidget::eventProcess(events);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eventDraw(Canvas& canvas) override { canvas.rect(this->mArea, mBaseColor); }
|
void eventDraw(Canvas& canvas) override { canvas.rect(this->mArea, mBaseColor); }
|
||||||
|
|
@ -144,13 +115,13 @@ namespace tp {
|
||||||
public:
|
public:
|
||||||
Editor* mEditor = nullptr;
|
Editor* mEditor = nullptr;
|
||||||
|
|
||||||
SplitView mSplitView;
|
// SplitView mSplitView;
|
||||||
|
|
||||||
ViewportWidget mViewport;
|
ViewportWidget mViewport;
|
||||||
ScrollableWindow mSettingsWidget;
|
// ScrollableWindow mSettingsWidget;
|
||||||
|
|
||||||
// Controls
|
// Controls
|
||||||
CollapsableMenu mRenderMenu;
|
FloatingWidget mRenderMenu;
|
||||||
ButtonWidget mRenderPathTracer;
|
ButtonWidget mRenderPathTracer;
|
||||||
ButtonWidget mRenderRaster;
|
ButtonWidget mRenderRaster;
|
||||||
ButtonWidget mRenderDeNoise;
|
ButtonWidget mRenderDeNoise;
|
||||||
|
|
@ -158,7 +129,7 @@ namespace tp {
|
||||||
// Navigation
|
// Navigation
|
||||||
enum NavigationType { ORBIT, PAN, ZOOM } mNavigationType = ORBIT;
|
enum NavigationType { ORBIT, PAN, ZOOM } mNavigationType = ORBIT;
|
||||||
|
|
||||||
CollapsableMenu mNavigationMenu;
|
FloatingWidget mNavigationMenu;
|
||||||
ButtonWidget mNavigationPan;
|
ButtonWidget mNavigationPan;
|
||||||
ButtonWidget mNavigationOrbit;
|
ButtonWidget mNavigationOrbit;
|
||||||
ButtonWidget mNavigationZoom;
|
ButtonWidget mNavigationZoom;
|
||||||
|
|
|
||||||
|
|
@ -159,16 +159,11 @@ namespace tp {
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] Node* find(const TypeArg data) const {
|
[[nodiscard]] Node* find(const TypeArg data) const {
|
||||||
Node* found = mFirst;
|
for (Node* found = mFirst; found; found = found->next) {
|
||||||
for (alni i = 0; data != found->data; i++) {
|
if (data == found->data) return found;
|
||||||
if (i == length()) return nullptr;
|
}
|
||||||
if (!found->next) {
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
found = found->next;
|
|
||||||
}
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] inline const Type& operator[](Index idx) const {
|
[[nodiscard]] inline const Type& operator[](Index idx) const {
|
||||||
DEBUG_ASSERT(idx < mLength)
|
DEBUG_ASSERT(idx < mLength)
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,8 @@ static void scrollCallback(GLFWwindow* window, double xOffset, double yOffset);
|
||||||
Window::Window(Vec2F size, const char* title) {
|
Window::Window(Vec2F size, const char* title) {
|
||||||
mContext = new Context();
|
mContext = new Context();
|
||||||
|
|
||||||
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, 1);
|
// glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, 1);
|
||||||
|
// glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);
|
||||||
|
|
||||||
// Create a window and OpenGL context
|
// Create a window and OpenGL context
|
||||||
mContext->window = glfwCreateWindow((int) size.x, (int) size.y, title, nullptr, nullptr);
|
mContext->window = glfwCreateWindow((int) size.x, (int) size.y, title, nullptr, nullptr);
|
||||||
|
|
@ -63,7 +64,8 @@ Window* Window::createWindow(Vec2F size, const char* title) {
|
||||||
}
|
}
|
||||||
count--;
|
count--;
|
||||||
|
|
||||||
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_X11);
|
// glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_X11);
|
||||||
|
// glfwInitHint(GLFW_WAYLAND_LIBDECOR, GLFW_WAYLAND_DISABLE_LIBDECOR);
|
||||||
|
|
||||||
// Initialize GLFW
|
// Initialize GLFW
|
||||||
if (!glfwInit()) {
|
if (!glfwInit()) {
|
||||||
|
|
@ -89,8 +91,8 @@ void Window::destroyWindow(Window* window) {
|
||||||
bool Window::shouldClose() const { return glfwWindowShouldClose(mContext->window); }
|
bool Window::shouldClose() const { return glfwWindowShouldClose(mContext->window); }
|
||||||
|
|
||||||
void Window::processEvents() {
|
void Window::processEvents() {
|
||||||
glfwPollEvents();
|
// glfwPollEvents();
|
||||||
// glfwWaitEvents();
|
glfwWaitEvents();
|
||||||
checkAxisUpdates();
|
checkAxisUpdates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ namespace tp {
|
||||||
int filterExisting = 0; // all existing no-existing
|
int filterExisting = 0; // all existing no-existing
|
||||||
};
|
};
|
||||||
|
|
||||||
class LibraryWidget : public Widget {
|
class LibraryWidget : public WorkspaceWidget {
|
||||||
public:
|
public:
|
||||||
LibraryWidget(Library* lib, Player* player) {
|
LibraryWidget(Library* lib, Player* player) {
|
||||||
mLibrary = (lib);
|
mLibrary = (lib);
|
||||||
|
|
@ -194,10 +194,11 @@ namespace tp {
|
||||||
|
|
||||||
mCurrentTrackInfo.mPlayer = mPlayer;
|
mCurrentTrackInfo.mPlayer = mPlayer;
|
||||||
|
|
||||||
this->mChildWidgets.pushBack(&mSplitView);
|
mDockSpace.setCenterWidget(&mSongList);
|
||||||
this->mChildWidgets.pushBack(&mSongList);
|
mDockSpace.addSideWidget(&mCurrentTrackInfo, GridLayoutWidget::RIGHT);
|
||||||
this->mChildWidgets.pushBack(&mCurrentTrackInfo);
|
|
||||||
this->mChildWidgets.pushBack(&mCurrentTrack);
|
// this->mChildWidgets.pushBack(&mCurrentTrackInfo);
|
||||||
|
// this->mChildWidgets.pushBack(&mCurrentTrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateTracks() {
|
void updateTracks() {
|
||||||
|
|
@ -210,9 +211,6 @@ namespace tp {
|
||||||
void eventProcess(const Events& events) override {
|
void eventProcess(const Events& events) override {
|
||||||
filter();
|
filter();
|
||||||
|
|
||||||
mSplitView.setArea(this->mArea);
|
|
||||||
mSongList.setArea(mSplitView.getFirst());
|
|
||||||
|
|
||||||
for (auto track : mSongList.getContent()) {
|
for (auto track : mSongList.getContent()) {
|
||||||
auto trackWidget = (TrackWidget*) track.data();
|
auto trackWidget = (TrackWidget*) track.data();
|
||||||
if (trackWidget->mSelected) {
|
if (trackWidget->mSelected) {
|
||||||
|
|
@ -220,12 +218,14 @@ namespace tp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentTrackInfo.setArea(mSplitView.getSecond());
|
|
||||||
|
|
||||||
// mCurrentTrack.proc(events, this->mArea, mSplitView.getFirst());
|
// mCurrentTrack.proc(events, this->mArea, mSplitView.getFirst());
|
||||||
|
|
||||||
|
WorkspaceWidget::eventProcess(events);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eventDraw(Canvas& canvas) override { canvas.rect(this->mArea, { 0.1f, 0.1f, 0.1f, 1.f }); }
|
// void eventDraw(Canvas& canvas) override {
|
||||||
|
// canvas.rect(this->mArea, { 0.1f, 0.1f, 0.1f, 1.f });
|
||||||
|
// }
|
||||||
|
|
||||||
void filter() {
|
void filter() {
|
||||||
if (!mCurrentTrackInfo.isSongFilterChanged) return;
|
if (!mCurrentTrackInfo.isSongFilterChanged) return;
|
||||||
|
|
@ -264,7 +264,6 @@ namespace tp {
|
||||||
|
|
||||||
Buffer<TrackWidget> mTracks;
|
Buffer<TrackWidget> mTracks;
|
||||||
|
|
||||||
SplitView mSplitView;
|
|
||||||
ScrollableWindow mSongList;
|
ScrollableWindow mSongList;
|
||||||
TrackInfoWidget mCurrentTrackInfo;
|
TrackInfoWidget mCurrentTrackInfo;
|
||||||
TrackWidget mCurrentTrack;
|
TrackWidget mCurrentTrack;
|
||||||
|
|
|
||||||
|
|
@ -245,6 +245,12 @@ namespace tp {
|
||||||
return { x, y + abs, size.x, size.y - abs };
|
return { x, y + abs, size.x, size.y - abs };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rect<Type> getSizedFromCenter(Vec2<Type> size) {
|
||||||
|
const auto pivot = center();
|
||||||
|
const auto sizeHalf = size / 2;
|
||||||
|
return { pivot - sizeHalf, size };
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
union {
|
union {
|
||||||
Vec2<Type> v1;
|
Vec2<Type> v1;
|
||||||
|
|
|
||||||
|
|
@ -91,56 +91,36 @@ namespace tp {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Sketch3DGUI : public Widget {
|
class Sketch3DGUI : public WorkspaceWidget {
|
||||||
public:
|
public:
|
||||||
Sketch3DGUI(Canvas& canvas, Vec2F renderResolution) :
|
Sketch3DGUI(Canvas& canvas, Vec2F renderResolution) :
|
||||||
mViewport(canvas, renderResolution) {
|
mViewport(canvas, renderResolution)
|
||||||
mDrawButton = new ButtonWidget("Draw", { 0, 0, 100, 30 });
|
{
|
||||||
mMoveButton = new ButtonWidget("Pan View", { 0, 0, 100, 30 });
|
|
||||||
mRotateButton = new ButtonWidget("Rotate view", { 0, 0, 100, 30 });
|
|
||||||
mZoomButton = new ButtonWidget("Zoom view", { 0, 0, 100, 30 });
|
|
||||||
|
|
||||||
mOptions.addWidget(mDrawButton);
|
mControls.addWidgetToMenu(&mDrawButton);
|
||||||
mOptions.addWidget(mMoveButton);
|
mControls.addWidgetToMenu(&mMoveButton);
|
||||||
mOptions.addWidget(mRotateButton);
|
mControls.addWidgetToMenu(&mRotateButton);
|
||||||
mOptions.addWidget(mZoomButton);
|
mControls.addWidgetToMenu(&mZoomButton);
|
||||||
|
|
||||||
// add color sliders
|
mColorPicker.addWidgetToMenu(&mRed);
|
||||||
mRed = new NamedSliderWidget("Red");
|
mColorPicker.addWidgetToMenu(&mGreen);
|
||||||
mGreen = new NamedSliderWidget("Green");
|
mColorPicker.addWidgetToMenu(&mBlue);
|
||||||
mBlue = new NamedSliderWidget("Blue");
|
|
||||||
|
|
||||||
mOptions.addWidget(mRed);
|
mDockSpace.setCenterWidget(&mViewport);
|
||||||
mOptions.addWidget(mGreen);
|
|
||||||
mOptions.addWidget(mBlue);
|
|
||||||
|
|
||||||
this->mChildWidgets.pushBack(&mViewport);
|
mFloatingLayer.mChildWidgets.pushBack(&mControls);
|
||||||
this->mChildWidgets.pushBack(&mSplitView);
|
mFloatingLayer.mChildWidgets.pushBack(&mColorPicker);
|
||||||
this->mChildWidgets.pushBack(&mOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Sketch3DGUI() {
|
mDrawButton.mCallback = [this]() { mViewport.mMode = Sketch3DWidget::Mode::DRAW; };
|
||||||
for (auto item : mOptions.getContent()) {
|
mMoveButton.mCallback = [this]() { mViewport.mMode = Sketch3DWidget::Mode::MOVE; };
|
||||||
delete item.data();
|
mRotateButton.mCallback = [this]() { mViewport.mMode = Sketch3DWidget::Mode::ROTATE; };
|
||||||
}
|
mZoomButton.mCallback = [this]() { mViewport.mMode = Sketch3DWidget::Mode::ZOOM; };
|
||||||
}
|
}
|
||||||
|
|
||||||
void eventProcess(const Events& events) override {
|
void eventProcess(const Events& events) override {
|
||||||
mSplitView.setArea(this->mArea);
|
WorkspaceWidget::eventProcess(events);
|
||||||
mViewport.setArea(mSplitView.getFirst());
|
|
||||||
mOptions.setArea(mSplitView.getSecond());
|
|
||||||
|
|
||||||
if (mDrawButton->isFired()) {
|
mViewport.setColor(RGBA(mRed.mSlider.mFactor, mGreen.mSlider.mFactor, mBlue.mSlider.mFactor, 1.f));
|
||||||
mViewport.mMode = Sketch3DWidget::Mode::DRAW;
|
|
||||||
} else if (mMoveButton->isFired()) {
|
|
||||||
mViewport.mMode = Sketch3DWidget::Mode::MOVE;
|
|
||||||
} else if (mRotateButton->isFired()) {
|
|
||||||
mViewport.mMode = Sketch3DWidget::Mode::ROTATE;
|
|
||||||
} else if (mZoomButton->isFired()) {
|
|
||||||
mViewport.mMode = Sketch3DWidget::Mode::ZOOM;
|
|
||||||
}
|
|
||||||
|
|
||||||
mViewport.setColor(RGBA(mRed->mSlider.mFactor, mGreen->mSlider.mFactor, mBlue->mSlider.mFactor, 1.f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void eventDraw(Canvas& canvas) override { canvas.rect(this->mArea, mBackgroundColor, mRounding); }
|
void eventDraw(Canvas& canvas) override { canvas.rect(this->mArea, mBackgroundColor, mRounding); }
|
||||||
|
|
@ -154,17 +134,18 @@ namespace tp {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Sketch3DWidget mViewport;
|
Sketch3DWidget mViewport;
|
||||||
SplitView mSplitView;
|
|
||||||
ScrollableWindow mOptions;
|
ScrollableWindow mOptions;
|
||||||
|
|
||||||
ButtonWidget* mDrawButton = nullptr;
|
FloatingWidget mControls;
|
||||||
ButtonWidget* mMoveButton = nullptr;
|
ButtonWidget mDrawButton = ButtonWidget("Draw", { 0, 0, 100, 30 });
|
||||||
ButtonWidget* mRotateButton = nullptr;
|
ButtonWidget mMoveButton = ButtonWidget("Pan", { 0, 0, 100, 30 });
|
||||||
ButtonWidget* mZoomButton = nullptr;
|
ButtonWidget mRotateButton = ButtonWidget("Orbit", { 0, 0, 100, 30 });
|
||||||
|
ButtonWidget mZoomButton = ButtonWidget("Zoom", { 0, 0, 100, 30 });
|
||||||
|
|
||||||
NamedSliderWidget* mRed = nullptr;
|
FloatingWidget mColorPicker;
|
||||||
NamedSliderWidget* mGreen = nullptr;
|
NamedSliderWidget mRed = NamedSliderWidget("Red");
|
||||||
NamedSliderWidget* mBlue = nullptr;
|
NamedSliderWidget mGreen = NamedSliderWidget("Green");
|
||||||
|
NamedSliderWidget mBlue = NamedSliderWidget("Blue");
|
||||||
|
|
||||||
RGBA mBackgroundColor;
|
RGBA mBackgroundColor;
|
||||||
halnf mRounding = 0;
|
halnf mRounding = 0;
|
||||||
|
|
|
||||||
3
TODO
3
TODO
|
|
@ -67,9 +67,10 @@ Language:
|
||||||
Make automations itself a universal tool - NFA DFA conversions
|
Make automations itself a universal tool - NFA DFA conversions
|
||||||
|
|
||||||
Widgets:
|
Widgets:
|
||||||
Add tree structure interface to simplify code
|
|
||||||
Add shortcuts
|
Add shortcuts
|
||||||
Config cache may be static
|
Config cache may be static
|
||||||
|
Cleanup
|
||||||
|
Add animations
|
||||||
|
|
||||||
LibraryViewer:
|
LibraryViewer:
|
||||||
artworks
|
artworks
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ namespace tp {
|
||||||
halnf mPadding = 0;
|
halnf mPadding = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ChattingWidget : public Widget {
|
class ChattingWidget : public GridLayoutWidget {
|
||||||
public:
|
public:
|
||||||
ChattingWidget() {
|
ChattingWidget() {
|
||||||
// todo : fetch code
|
// todo : fetch code
|
||||||
|
|
@ -205,19 +205,10 @@ namespace tp {
|
||||||
mActive.mHistoryView.addWidget(&message.data());
|
mActive.mHistoryView.addWidget(&message.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
this->mChildWidgets.pushBack(&mSideView);
|
addSideWidget(&mSideView, GridLayoutWidget::RIGHT);
|
||||||
this->mChildWidgets.pushBack(&mActive);
|
setCenterWidget(&mActive);
|
||||||
this->mChildWidgets.pushBack(&mSplitView);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void eventProcess(const Events& events) override {
|
|
||||||
mSplitView.setArea(this->mArea);
|
|
||||||
mSideView.setArea(mSplitView.getSecond());
|
|
||||||
mActive.setArea(mSplitView.getFirst());
|
|
||||||
}
|
|
||||||
|
|
||||||
void eventDraw(Canvas& canvas) override { canvas.rect(this->mArea, mBGColor); }
|
|
||||||
|
|
||||||
void eventUpdateConfiguration(WidgetManager& wm) override {
|
void eventUpdateConfiguration(WidgetManager& wm) override {
|
||||||
wm.setActiveId("ChattingWidget");
|
wm.setActiveId("ChattingWidget");
|
||||||
mBGColor = wm.getColor("Back", "Background");
|
mBGColor = wm.getColor("Back", "Background");
|
||||||
|
|
@ -227,7 +218,6 @@ namespace tp {
|
||||||
Buffer<UserWidget> mUsers;
|
Buffer<UserWidget> mUsers;
|
||||||
ScrollableWindow mSideView;
|
ScrollableWindow mSideView;
|
||||||
ActiveChatWidget mActive;
|
ActiveChatWidget mActive;
|
||||||
SplitView mSplitView;
|
|
||||||
|
|
||||||
RGBA mBGColor;
|
RGBA mBGColor;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -9,28 +9,7 @@ using namespace tp;
|
||||||
class SimpleGUI : public Application {
|
class SimpleGUI : public Application {
|
||||||
public:
|
public:
|
||||||
SimpleGUI() {
|
SimpleGUI() {
|
||||||
|
// mGui.mPreview = true;
|
||||||
// debug
|
|
||||||
|
|
||||||
mGui.addSideWidget(&mButtons[0], DockSpaceWidget::BOTTOM);
|
|
||||||
mGui.addSideWidget(&mButtons[1], DockSpaceWidget::RIGHT);
|
|
||||||
|
|
||||||
mGui.removeSideWidget(DockSpaceWidget::BOTTOM);
|
|
||||||
|
|
||||||
mGui.addSideWidget(&mButtons[0], DockSpaceWidget::TOP);
|
|
||||||
mGui.addSideWidget(&mButtons[2], DockSpaceWidget::LEFT);
|
|
||||||
|
|
||||||
mGui.removeSideWidget(DockSpaceWidget::TOP);
|
|
||||||
|
|
||||||
mGui.addSideWidget(&mButtons[0], DockSpaceWidget::BOTTOM);
|
|
||||||
|
|
||||||
mGui.addSideWidget(&mButtons[3], DockSpaceWidget::TOP);
|
|
||||||
mGui.setCenterWidget(&mButtons[4]);
|
|
||||||
|
|
||||||
mButtons[4].mCallback = [&]() { mGui.toggleHiddenState(DockSpaceWidget::BOTTOM); };
|
|
||||||
mButtons[0].mCallback = [&]() { mGui.toggleHiddenState(DockSpaceWidget::TOP); };
|
|
||||||
mButtons[2].mCallback = [&]() { mGui.toggleHiddenState(DockSpaceWidget::RIGHT); };
|
|
||||||
mButtons[3].mCallback = [&]() { mGui.toggleHiddenState(DockSpaceWidget::LEFT); };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void processFrame(EventHandler* eventHandler) override {
|
void processFrame(EventHandler* eventHandler) override {
|
||||||
|
|
@ -49,9 +28,8 @@ public:
|
||||||
private:
|
private:
|
||||||
WidgetManager mWidgetManager;
|
WidgetManager mWidgetManager;
|
||||||
|
|
||||||
DockSpaceWidget mGui;
|
// DockSpaceWidget mGui;
|
||||||
|
SimpleWidget3 mGui;
|
||||||
ButtonWidget mButtons[5];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,19 @@ namespace tp {
|
||||||
class SimpleWidget : public CollapsableMenu {
|
class SimpleWidget : public CollapsableMenu {
|
||||||
public:
|
public:
|
||||||
SimpleWidget() {
|
SimpleWidget() {
|
||||||
|
this->addWidgetToMenu(&mSlider);
|
||||||
|
|
||||||
this->addWidgetToMenu(&mInMenuButton1);
|
this->addWidgetToMenu(&mInMenuButton1);
|
||||||
this->addWidgetToMenu(&mInMenuButton2);
|
this->addWidgetToMenu(&mInMenuButton2);
|
||||||
|
|
||||||
this->addWidgetToMenu(&mLabel);
|
this->addWidgetToMenu(&mLabel);
|
||||||
this->addWidgetToMenu(&mSlider);
|
|
||||||
|
|
||||||
mInMenuButton1.mLabel.mLabel = "Button1";
|
mInMenuButton1.mLabel.mLabel = "Button1";
|
||||||
|
|
||||||
|
mInMenuButton1.mCallback = []() {
|
||||||
|
printf("asd\n");
|
||||||
|
};
|
||||||
|
|
||||||
mInMenuButton2.mLabel.mLabel = "Button2";
|
mInMenuButton2.mLabel.mLabel = "Button2";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -23,31 +29,41 @@ namespace tp {
|
||||||
NamedSliderWidget mSlider;
|
NamedSliderWidget mSlider;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SimpleWidget2 : public DockSpaceWidget {
|
class SimpleWidget3 : public WorkspaceWidget {
|
||||||
public:
|
public:
|
||||||
SimpleWidget2() {
|
SimpleWidget3() {
|
||||||
this->mChildWidgets.pushBack(&mFloating);
|
|
||||||
mFloating.addWidgetToMenu(&mWidget);
|
|
||||||
|
|
||||||
this->mChildWidgets.pushBack(&mFloating2);
|
mDockSpace.addSideWidget(&mButtons[0], GridLayoutWidget::BOTTOM);
|
||||||
mFloating2.addWidgetToMenu(&mWidget2);
|
mDockSpace.addSideWidget(&mButtons[1], GridLayoutWidget::RIGHT);
|
||||||
|
|
||||||
mFloating2.mArea = { 200, 100, 100, 100 };
|
mDockSpace.removeSideWidget(GridLayoutWidget::BOTTOM);
|
||||||
|
|
||||||
this->mChildWidgets.pushBack(&mFloating3);
|
mDockSpace.addSideWidget(&mButtons[0], GridLayoutWidget::TOP);
|
||||||
mFloating3.addWidgetToMenu(&mWidget3);
|
mDockSpace.addSideWidget(&mButtons[2], GridLayoutWidget::LEFT);
|
||||||
|
|
||||||
mFloating3.mArea = { 400, 100, 100, 100 };
|
mDockSpace.removeSideWidget(GridLayoutWidget::TOP);
|
||||||
|
|
||||||
|
mDockSpace.addSideWidget(&mButtons[0], GridLayoutWidget::BOTTOM);
|
||||||
|
|
||||||
|
mDockSpace.addSideWidget(&mButtons[3], GridLayoutWidget::TOP);
|
||||||
|
mDockSpace.setCenterWidget(&mButtons[4]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
mButtons[4].mCallback = [&]() { mDockSpace.toggleHiddenState(DockSpaceWidget::BOTTOM); };
|
||||||
|
mButtons[0].mCallback = [&]() { mDockSpace.toggleHiddenState(DockSpaceWidget::TOP); };
|
||||||
|
mButtons[2].mCallback = [&]() { mDockSpace.toggleHiddenState(DockSpaceWidget::RIGHT); };
|
||||||
|
mButtons[3].mCallback = [&]() { mDockSpace.toggleHiddenState(DockSpaceWidget::LEFT); };
|
||||||
|
*/
|
||||||
|
|
||||||
|
mButtons[0].addWidgetToMenu(&mWidget);
|
||||||
|
mButtons[1].addWidgetToMenu(&mWidget2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FloatingWidget mFloating;
|
FloatingWidget mButtons[5];
|
||||||
|
|
||||||
SimpleWidget mWidget;
|
SimpleWidget mWidget;
|
||||||
|
|
||||||
FloatingWidget mFloating2;
|
|
||||||
SimpleWidget mWidget2;
|
SimpleWidget mWidget2;
|
||||||
|
|
||||||
FloatingWidget mFloating3;
|
|
||||||
SimpleWidget mWidget3;
|
SimpleWidget mWidget3;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -17,8 +17,12 @@ void CollapsableMenu::eventProcess(const Events&) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollapsableMenu::eventDraw(Canvas& canvas) {
|
void CollapsableMenu::eventDraw(Canvas& canvas) {
|
||||||
|
if (mBorders) {
|
||||||
canvas.rect(this->mArea, mBorderColor, rounding);
|
canvas.rect(this->mArea, mBorderColor, rounding);
|
||||||
canvas.rect(this->mArea.shrink(mBorderSize), mMenuColor, rounding);
|
canvas.rect(this->mArea.shrink(mBorderSize), mMenuColor, rounding);
|
||||||
|
} else {
|
||||||
|
canvas.rect(this->mArea, mMenuColor, rounding);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollapsableMenu::addWidgetToMenu(Widget* widget) {
|
void CollapsableMenu::addWidgetToMenu(Widget* widget) {
|
||||||
|
|
@ -60,7 +64,8 @@ void CollapsableMenu::updateGeometry() {
|
||||||
|
|
||||||
RectF CollapsableMenu::getHeaderRect() {
|
RectF CollapsableMenu::getHeaderRect() {
|
||||||
RectF out = { this->mArea.pos, { this->mArea.size.x, headerHeight } };
|
RectF out = { this->mArea.pos, { this->mArea.size.x, headerHeight } };
|
||||||
return out.shrink(mPadding);
|
if (mBorders) out = out.shrink(mPadding);
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
RectF CollapsableMenu::getBodyRect() {
|
RectF CollapsableMenu::getBodyRect() {
|
||||||
|
|
@ -71,7 +76,7 @@ RectF CollapsableMenu::getBodyRect() {
|
||||||
|
|
||||||
if (mAdjustHeight) out.size.y = mBody.getContentSize();
|
if (mAdjustHeight) out.size.y = mBody.getContentSize();
|
||||||
|
|
||||||
if (mBody.getContentSize()) {
|
if (mBody.getContentSize() && mBorders) {
|
||||||
out = out.shrink(mPadding);
|
out = out.shrink(mPadding);
|
||||||
out.size.y += mPadding * 2 + 1;
|
out.size.y += mPadding * 2 + 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,249 +0,0 @@
|
||||||
#include "DockspaceWidget.hpp"
|
|
||||||
|
|
||||||
using namespace tp;
|
|
||||||
|
|
||||||
DockSpaceWidget::DockSpaceWidget() = default;
|
|
||||||
|
|
||||||
void DockSpaceWidget::addSideWidget(Widget* widget, Side side) {
|
|
||||||
if (mSideWidgets[side]) return;
|
|
||||||
mSideWidgets[side] = widget;
|
|
||||||
for (auto& order : mSideSplitOrder) {
|
|
||||||
if (order == -1) {
|
|
||||||
order = side;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mChildWidgets.pushBack(widget);
|
|
||||||
widget->mIsDocked = true;
|
|
||||||
mSideHidden[side] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockSpaceWidget::removeSideWidget(Side side) {
|
|
||||||
if (!mSideWidgets[side]) return;
|
|
||||||
|
|
||||||
bool removed = false;
|
|
||||||
for (ualni i = 0; i < 3; i++) {
|
|
||||||
if (mSideSplitOrder[i] == side) {
|
|
||||||
removed = true;
|
|
||||||
}
|
|
||||||
if (removed) {
|
|
||||||
mSideSplitOrder[i] = mSideSplitOrder[i + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mSideSplitOrder[3] = -1;
|
|
||||||
|
|
||||||
auto widget = mSideWidgets[side];
|
|
||||||
mSideWidgets[side] = nullptr;
|
|
||||||
widget->mIsDocked = false;
|
|
||||||
|
|
||||||
mChildWidgets.removeNode(mChildWidgets.find(widget));
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockSpaceWidget::setCenterWidget(Widget* widget) {
|
|
||||||
mChildWidgets.removeNode(mChildWidgets.find(mCenterWidget));
|
|
||||||
mCenterWidget = widget;
|
|
||||||
mChildWidgets.pushBack(mCenterWidget);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockSpaceWidget::toggleHiddenState(DockSpaceWidget::Side side) {
|
|
||||||
if (!isSideExists(side)) return;
|
|
||||||
mSideHidden[side] = !mSideHidden[side];
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockSpaceWidget::eventProcess(const tp::Events& events) {
|
|
||||||
updateActiveWindow(events);
|
|
||||||
|
|
||||||
calculateSideAreas();
|
|
||||||
calculateResizeHandles();
|
|
||||||
// calculateHeaderAreas();
|
|
||||||
handleResizeEvents(events);
|
|
||||||
|
|
||||||
updateChildSideWidgets();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockSpaceWidget::eventDraw(Canvas& canvas) {
|
|
||||||
canvas.rect(this->mArea, mBackgroundColor, 0);
|
|
||||||
|
|
||||||
for (auto sizeHandle : mResizeHandles) {
|
|
||||||
if (sizeHandle->active) {
|
|
||||||
canvas.rect(sizeHandle->area.shrink(mPadding / 1.5f), mResizeHandleColorActive, 0);
|
|
||||||
} else if (sizeHandle->hover) {
|
|
||||||
canvas.rect(sizeHandle->area.shrink(mPadding / 1.5f), mResizeHandleColorHovered, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& header : mSideHeaderAreas) {
|
|
||||||
canvas.rect(header, mResizeHandleColorActive, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockSpaceWidget::updateActiveWindow(const tp::Events& events) {
|
|
||||||
if (this->mChildWidgets.size() > 1 && events.isPressed(InputID::MOUSE1)) {
|
|
||||||
|
|
||||||
Widget* activeChild = nullptr;
|
|
||||||
|
|
||||||
for (auto childNode = this->mChildWidgets.firstNode(); childNode; childNode = childNode->next) {
|
|
||||||
auto child = childNode->data;
|
|
||||||
|
|
||||||
if (child->mIsDocked) continue;
|
|
||||||
if (child->mArea.isInside(events.getPointer())) {
|
|
||||||
|
|
||||||
mChildWidgets.detach(childNode);
|
|
||||||
mChildWidgets.pushFront(childNode);
|
|
||||||
|
|
||||||
child->mHandlesEvents = true;
|
|
||||||
activeChild = child;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activeChild) {
|
|
||||||
for (auto child : this->mChildWidgets) {
|
|
||||||
if (activeChild != child.data() && !child->mIsDocked) child->mHandlesEvents = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockSpaceWidget::calculateSideAreas() {
|
|
||||||
auto startArea = this->mArea;
|
|
||||||
for (ualni i = 0; i < 4; i++) {
|
|
||||||
const auto side = mSideSplitOrder[i];
|
|
||||||
|
|
||||||
if (side == -1) break;
|
|
||||||
if (mSideHidden[side]) continue;
|
|
||||||
|
|
||||||
bool vertical = side == TOP || side == BOTTOM;
|
|
||||||
bool opposite = side == BOTTOM || side == RIGHT;
|
|
||||||
|
|
||||||
const auto maxAbsoluteSize = startArea.size[vertical];
|
|
||||||
const auto paddingFactor = mSideSizePadding / maxAbsoluteSize;
|
|
||||||
|
|
||||||
mSideAbsoluteSize[side] =
|
|
||||||
clamp(mSideAbsoluteSize[side], maxAbsoluteSize * paddingFactor, maxAbsoluteSize * (1.f - paddingFactor));
|
|
||||||
|
|
||||||
auto factor = mSideAbsoluteSize[side] / startArea.size[vertical];
|
|
||||||
if (opposite) factor = factor * -1 + 1;
|
|
||||||
|
|
||||||
if (!vertical) {
|
|
||||||
const auto first = startArea.splitByFactorHL(factor);
|
|
||||||
const auto second = startArea.splitByFactorHR(factor);
|
|
||||||
mSideAreas[side] = side == LEFT ? first : second;
|
|
||||||
startArea = side == LEFT ? second : first;
|
|
||||||
} else {
|
|
||||||
const auto first = startArea.splitByFactorVT(factor);
|
|
||||||
const auto second = startArea.splitByFactorVB(factor);
|
|
||||||
mSideAreas[side] = side == TOP ? first : second;
|
|
||||||
startArea = side == TOP ? second : first;
|
|
||||||
}
|
|
||||||
|
|
||||||
mSideAreas[side] = mSideAreas[side].shrink(mPadding);
|
|
||||||
}
|
|
||||||
|
|
||||||
mCenterArea = startArea.shrink(mPadding);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockSpaceWidget::calculateResizeHandles() {
|
|
||||||
mResizeHandles.clear();
|
|
||||||
RectF rec;
|
|
||||||
|
|
||||||
if (isSideVisible(LEFT)) {
|
|
||||||
rec = { mSideAreas[LEFT].p4(), { mPadding * 2, mSideAreas[LEFT].size.y } };
|
|
||||||
mResizeHandles.append({ rec, LEFT, 0, mCenterArea.p3().x });
|
|
||||||
}
|
|
||||||
if (isSideVisible(RIGHT)) {
|
|
||||||
rec = { mSideAreas[RIGHT].p1(), { mPadding * 2, mSideAreas[RIGHT].size.y } };
|
|
||||||
rec.x -= mPadding * 2;
|
|
||||||
mResizeHandles.append({ rec, RIGHT, mCenterArea.p1().x, rec.p3().x });
|
|
||||||
}
|
|
||||||
if (isSideVisible(TOP)) {
|
|
||||||
rec = { mSideAreas[TOP].p2(), { mSideAreas[TOP].size.x, mPadding * 2 } };
|
|
||||||
mResizeHandles.append({ rec, TOP, 0, mCenterArea.p2().y });
|
|
||||||
}
|
|
||||||
if (isSideVisible(BOTTOM)) {
|
|
||||||
rec = { mSideAreas[BOTTOM].p1(), { mSideAreas[BOTTOM].size.x, mPadding * 2 } };
|
|
||||||
rec.y -= mPadding * 2;
|
|
||||||
mResizeHandles.append({ rec, BOTTOM, mCenterArea.p1().y, rec.p2().y });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockSpaceWidget::handleResizeEvents(const Events& events) {
|
|
||||||
for (auto resizeHandle : mResizeHandles) {
|
|
||||||
resizeHandle->hover = false;
|
|
||||||
if (resizeHandle->area.isInside(events.getPointerPrev())) {
|
|
||||||
resizeHandle->hover = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (events.isDown(InputID::MOUSE1)) {
|
|
||||||
for (auto resizeHandle : mResizeHandles) {
|
|
||||||
resizeHandle->active = false;
|
|
||||||
if (resizeHandle->area.isInside(events.getPointerPrev())) {
|
|
||||||
auto factorDeltaVec = events.getPointerDelta();
|
|
||||||
halnf factorDelta = factorDeltaVec[(resizeHandle->side == TOP || resizeHandle->side == BOTTOM)];
|
|
||||||
if (resizeHandle->side == BOTTOM || resizeHandle->side == RIGHT) factorDelta *= -1;
|
|
||||||
mSideAbsoluteSize[resizeHandle->side] += factorDelta;
|
|
||||||
resizeHandle->active = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockSpaceWidget::updateChildSideWidgets() {
|
|
||||||
// Update Child Widgets
|
|
||||||
{
|
|
||||||
for (ualni i = 0; i < 4; i++) {
|
|
||||||
if (!isSideExists(Side(i))) continue;
|
|
||||||
|
|
||||||
if (!isSideVisible(Side(i))) {
|
|
||||||
mSideWidgets[i]->mEnable = false;
|
|
||||||
} else {
|
|
||||||
mSideWidgets[i]->setArea(mSideAreas[i]);
|
|
||||||
mSideWidgets[i]->mEnable = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCenterWidget) mCenterWidget->setArea(mCenterArea);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update depth order
|
|
||||||
/*
|
|
||||||
if (mChildWidgets.size() > 1) {
|
|
||||||
for (auto sideChild : mSideWidgets) {
|
|
||||||
if (!sideChild) continue;
|
|
||||||
|
|
||||||
for (auto childNode = mChildWidgets.firstNode(); childNode; childNode = childNode->next) {
|
|
||||||
if (childNode->data == sideChild) {
|
|
||||||
mChildWidgets.detach(childNode);
|
|
||||||
mChildWidgets.pushBack(childNode);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void DockSpaceWidget::calculateHeaderAreas() {
|
|
||||||
for (ualni i = 0; i < 4; i++) {
|
|
||||||
if (!isSideVisible(Side(i))) continue;
|
|
||||||
const auto factor = mHeaderSize / mSideAreas[i].size.y;
|
|
||||||
mSideHeaderAreas[i] = mSideAreas[i].splitByFactorVT(factor);
|
|
||||||
mSideAreas[i] = mSideAreas[i].splitByFactorVB(factor);
|
|
||||||
|
|
||||||
mSideHeaderAreas[i].size.y -= mPadding;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DockSpaceWidget::isSideVisible(DockSpaceWidget::Side side) { return mSideWidgets[side] && !mSideHidden[side]; }
|
|
||||||
|
|
||||||
bool DockSpaceWidget::isSideExists(DockSpaceWidget::Side side) { return mSideWidgets[side]; }
|
|
||||||
|
|
||||||
|
|
||||||
ualni DockSpaceWidget::getVisibleSidesSize() {
|
|
||||||
ualni out = 0;
|
|
||||||
for (ualni i = 0; i < 4; i++) {
|
|
||||||
if (isSideVisible(Side(i))) out++;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
47
Widgets/private/FloatSpaceWidget.cpp
Normal file
47
Widgets/private/FloatSpaceWidget.cpp
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
#include "FloatingLayoutWidget.hpp"
|
||||||
|
|
||||||
|
using namespace tp;
|
||||||
|
|
||||||
|
FloatingLayoutWidget::FloatingLayoutWidget() = default;
|
||||||
|
|
||||||
|
void FloatingLayoutWidget::eventProcess(const tp::Events& events) {
|
||||||
|
updateActiveWindow(events);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FloatingLayoutWidget::updateActiveWindow(const tp::Events& events) {
|
||||||
|
mIsPassThrough = true;
|
||||||
|
for (auto childNode = this->mChildWidgets.firstNode(); childNode; childNode = childNode->next) {
|
||||||
|
auto child = childNode->data;
|
||||||
|
if (child->mArea.isInside(events.getPointer())) {
|
||||||
|
mIsPassThrough = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (events.isPressed(InputID::MOUSE1)) {
|
||||||
|
|
||||||
|
Widget* activeChild = nullptr;
|
||||||
|
|
||||||
|
for (auto childNode = this->mChildWidgets.firstNode(); childNode; childNode = childNode->next) {
|
||||||
|
auto child = childNode->data;
|
||||||
|
|
||||||
|
if (child->mArea.isInside(events.getPointer())) {
|
||||||
|
|
||||||
|
mChildWidgets.detach(childNode);
|
||||||
|
mChildWidgets.pushFront(childNode);
|
||||||
|
|
||||||
|
child->mHandlesEvents = true;
|
||||||
|
activeChild = child;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeChild) {
|
||||||
|
for (auto child : this->mChildWidgets) {
|
||||||
|
if (activeChild != child.data() && !child->mIsDocked) child->mHandlesEvents = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FloatingLayoutWidget::handlesEvent() const { return !mIsPassThrough; }
|
||||||
|
|
@ -12,7 +12,7 @@ void FloatingWidget::eventProcess(const Events& events) {
|
||||||
mActionStartRelativePos = events.getPointerPrev() - this->mArea.pos;
|
mActionStartRelativePos = events.getPointerPrev() - this->mArea.pos;
|
||||||
|
|
||||||
checkFloating(events);
|
checkFloating(events);
|
||||||
checkResizing(events);
|
if (mResizable) checkResizing(events);
|
||||||
|
|
||||||
CollapsableMenu::eventProcess(events);
|
CollapsableMenu::eventProcess(events);
|
||||||
}
|
}
|
||||||
|
|
@ -20,7 +20,7 @@ void FloatingWidget::eventProcess(const Events& events) {
|
||||||
void FloatingWidget::eventDraw(Canvas& canvas) {
|
void FloatingWidget::eventDraw(Canvas& canvas) {
|
||||||
CollapsableMenu::eventDraw(canvas);
|
CollapsableMenu::eventDraw(canvas);
|
||||||
|
|
||||||
if (!this->getCollapsed()) {
|
if (!this->getCollapsed() && mResizable) {
|
||||||
auto rect = getResizeHandle();
|
auto rect = getResizeHandle();
|
||||||
canvas.rect(rect, mResizeHandleColor, 0);
|
canvas.rect(rect, mResizeHandleColor, 0);
|
||||||
canvas.circle(rect.pos - this->mBorderSize, rect.w, this->mMenuColor);
|
canvas.circle(rect.pos - this->mBorderSize, rect.w, this->mMenuColor);
|
||||||
|
|
@ -78,3 +78,9 @@ RectF FloatingWidget::getResizeHandle() {
|
||||||
auto pos = this->mArea.pos + this->mArea.size - size;
|
auto pos = this->mArea.pos + this->mArea.size - size;
|
||||||
return { pos, size };
|
return { pos, size };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FloatingWidget::isFloating() const { return mFloating; }
|
||||||
|
|
||||||
|
void FloatingWidget::stopFloating() {
|
||||||
|
mFloating = false;
|
||||||
|
}
|
||||||
|
|
|
||||||
328
Widgets/private/GridLayoutWidget.cpp
Normal file
328
Widgets/private/GridLayoutWidget.cpp
Normal file
|
|
@ -0,0 +1,328 @@
|
||||||
|
#include "GridLayoutWidget.hpp"
|
||||||
|
|
||||||
|
using namespace tp;
|
||||||
|
|
||||||
|
GridLayoutWidget::GridLayoutWidget() {
|
||||||
|
mSideWidgets[0].side = LEFT;
|
||||||
|
mSideWidgets[1].side = TOP;
|
||||||
|
mSideWidgets[2].side = RIGHT;
|
||||||
|
mSideWidgets[3].side = BOTTOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridLayoutWidget::addSideWidget(Widget* widget, Side side) {
|
||||||
|
if (isSideExists(side)) return;
|
||||||
|
|
||||||
|
auto& sideWidget = mSideWidgets[side];
|
||||||
|
sideWidget.widget = widget;
|
||||||
|
for (auto& order : mSideWidgets) {
|
||||||
|
if (order.order == -1) {
|
||||||
|
order.order = side;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sideWidget.hidden = false;
|
||||||
|
|
||||||
|
mChildWidgets.pushBack(widget);
|
||||||
|
widget->mIsDocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridLayoutWidget::removeSideWidget(Side side) {
|
||||||
|
if (!isSideExists(side)) return;
|
||||||
|
|
||||||
|
bool removed = false;
|
||||||
|
for (ualni i = 0; i < 3; i++) {
|
||||||
|
if (mSideWidgets[i].order == side) {
|
||||||
|
removed = true;
|
||||||
|
}
|
||||||
|
if (removed) {
|
||||||
|
swap(mSideWidgets[i].order, mSideWidgets[i + 1].order);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mSideWidgets[3].order = -1;
|
||||||
|
|
||||||
|
auto widget = mSideWidgets[side].widget;
|
||||||
|
widget->mIsDocked = false;
|
||||||
|
mChildWidgets.removeNode(mChildWidgets.find(widget));
|
||||||
|
|
||||||
|
mSideWidgets[side].widget = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridLayoutWidget::setCenterWidget(Widget* widget) {
|
||||||
|
mChildWidgets.removeNode(mChildWidgets.find(mCenterWidget));
|
||||||
|
mCenterWidget = widget;
|
||||||
|
mChildWidgets.pushBack(mCenterWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridLayoutWidget::toggleHiddenState(GridLayoutWidget::Side side) {
|
||||||
|
if (!isSideExists(side)) return;
|
||||||
|
mSideWidgets[side].hidden = !mSideWidgets[side].hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridLayoutWidget::eventProcess(const tp::Events& events) {
|
||||||
|
calculateSideAreas();
|
||||||
|
calculateResizeHandles();
|
||||||
|
// calculateHeaderAreas();
|
||||||
|
|
||||||
|
handlePreview(events);
|
||||||
|
handleResizeEvents(events);
|
||||||
|
|
||||||
|
updateChildSideWidgets();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridLayoutWidget::eventDraw(Canvas& canvas) {
|
||||||
|
canvas.rect(this->mArea, mBackgroundColor, 0);
|
||||||
|
|
||||||
|
for (auto& sideWidget : mSideWidgets) {
|
||||||
|
if (!isSideVisible(sideWidget.side)) continue;
|
||||||
|
auto& handle = sideWidget.resizeHandle;
|
||||||
|
if (handle.active) {
|
||||||
|
canvas.rect(handle.area.shrink(mPadding / 1.5f), mResizeHandleColorActive, 0);
|
||||||
|
} else if (handle.hover) {
|
||||||
|
canvas.rect(handle.area.shrink(mPadding / 1.5f), mResizeHandleColorHovered, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& sideWidget : mSideWidgets) {
|
||||||
|
if (!isSideVisible(sideWidget.side)) continue;
|
||||||
|
canvas.rect(sideWidget.headerArea, mResizeHandleColorActive, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridLayoutWidget::eventDrawOver(Canvas& canvas) {
|
||||||
|
if (!mPreview) return;
|
||||||
|
|
||||||
|
if (mPreviewSide != NONE) canvas.rect(mPreviewArea.shrink(mPadding * 2), mPreviewColor, mRounding);
|
||||||
|
|
||||||
|
for (auto& sideWidget : mSideWidgets) {
|
||||||
|
if (sideWidget.widget) continue;
|
||||||
|
canvas.rect(sideWidget.previewHandleArea, mPreviewColor, mRounding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridLayoutWidget::calculateSideAreas() {
|
||||||
|
auto startArea = this->mArea;
|
||||||
|
for (auto& sideWidget : mSideWidgets) {
|
||||||
|
const auto side = sideWidget.order;
|
||||||
|
|
||||||
|
if (side == -1) break;
|
||||||
|
if (!isSideVisible(Side(side))) continue;
|
||||||
|
|
||||||
|
bool vertical = side == TOP || side == BOTTOM;
|
||||||
|
bool opposite = side == BOTTOM || side == RIGHT;
|
||||||
|
|
||||||
|
auto& sideSize = mSideWidgets[side].absoluteSize;
|
||||||
|
|
||||||
|
auto factor = sideSize / startArea.size[vertical];
|
||||||
|
if (opposite) factor = factor * -1 + 1;
|
||||||
|
auto& area = mSideWidgets[side].area;
|
||||||
|
|
||||||
|
if (!vertical) {
|
||||||
|
const auto first = startArea.splitByFactorHL(factor);
|
||||||
|
const auto second = startArea.splitByFactorHR(factor);
|
||||||
|
area = side == LEFT ? first : second;
|
||||||
|
startArea = side == LEFT ? second : first;
|
||||||
|
} else {
|
||||||
|
const auto first = startArea.splitByFactorVT(factor);
|
||||||
|
const auto second = startArea.splitByFactorVB(factor);
|
||||||
|
area = side == TOP ? first : second;
|
||||||
|
startArea = side == TOP ? second : first;
|
||||||
|
}
|
||||||
|
|
||||||
|
area = area.shrink(mPadding);
|
||||||
|
}
|
||||||
|
|
||||||
|
mCenterArea = startArea.shrink(mPadding);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridLayoutWidget::calculateResizeHandles() {
|
||||||
|
RectF rec;
|
||||||
|
|
||||||
|
if (isSideVisible(LEFT)) {
|
||||||
|
auto& side = mSideWidgets[LEFT];
|
||||||
|
rec = { side.area.p4(), { mPadding * 2, side.area.size.y } };
|
||||||
|
side.resizeHandle = { rec, 0, mCenterArea.p3().x };
|
||||||
|
}
|
||||||
|
if (isSideVisible(RIGHT)) {
|
||||||
|
auto& side = mSideWidgets[RIGHT];
|
||||||
|
rec = { side.area.p1(), { mPadding * 2, side.area.size.y } };
|
||||||
|
rec.x -= mPadding * 2;
|
||||||
|
side.resizeHandle = { rec, 0, (this->mArea.p3() - mCenterArea.p1()).x };
|
||||||
|
}
|
||||||
|
if (isSideVisible(TOP)) {
|
||||||
|
auto& side = mSideWidgets[TOP];
|
||||||
|
rec = { side.area.p2(), { side.area.size.x, mPadding * 2 } };
|
||||||
|
side.resizeHandle = { rec, 0, mCenterArea.p2().y };
|
||||||
|
}
|
||||||
|
if (isSideVisible(BOTTOM)) {
|
||||||
|
auto& side = mSideWidgets[BOTTOM];
|
||||||
|
rec = { side.area.p1(), { side.area.size.x, mPadding * 2 } };
|
||||||
|
rec.y -= mPadding * 2;
|
||||||
|
side.resizeHandle = { rec, 0, (this->mArea.p3() - mCenterArea.p1()).y };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridLayoutWidget::handleResizeEvents(const Events& events) {
|
||||||
|
for (auto& sideWidget : mSideWidgets) {
|
||||||
|
auto& sideSize = sideWidget.absoluteSize;
|
||||||
|
auto& resizeHandle = sideWidget.resizeHandle;
|
||||||
|
if (resizeHandle.end < mSideSizePadding * 2) {
|
||||||
|
sideSize = resizeHandle.end / 2.f;
|
||||||
|
} else {
|
||||||
|
sideSize = clamp(sideSize, resizeHandle.start + mSideSizePadding, resizeHandle.end - mSideSizePadding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& sideWidget : mSideWidgets) {
|
||||||
|
sideWidget.resizeHandle.hover = false;
|
||||||
|
if (sideWidget.resizeHandle.area.isInside(events.getPointerPrev())) {
|
||||||
|
sideWidget.resizeHandle.hover = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& sideWidget : mSideWidgets) {
|
||||||
|
sideWidget.resizeHandle.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPreview) return;
|
||||||
|
|
||||||
|
auto resizeSideWidget = [&events](SideWidgetData& sideWidget, Vec2F deltaVec) {
|
||||||
|
halnf delta = deltaVec[(sideWidget.side == TOP || sideWidget.side == BOTTOM)];
|
||||||
|
if (sideWidget.side == BOTTOM || sideWidget.side == RIGHT) delta *= -1;
|
||||||
|
sideWidget.absoluteSize += delta;
|
||||||
|
sideWidget.resizeHandle.active = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (events.isDown(InputID::MOUSE1)) {
|
||||||
|
for (auto& sideWidget : mSideWidgets) {
|
||||||
|
if (sideWidget.resizeHandle.area.isInside(events.getPointerPrev())) {
|
||||||
|
resizeSideWidget(sideWidget, events.getPointerDelta());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (events.isDown(InputID::LEFT_ALT)) {
|
||||||
|
const auto pointer = events.getPointerPrev();
|
||||||
|
if (!mCenterArea.isInside(pointer)) return;
|
||||||
|
|
||||||
|
if (events.isPressed(InputID::MOUSE1)) {
|
||||||
|
for (auto i : { 0, 1 }) {
|
||||||
|
const auto step = mCenterArea.size[i] / 3.f;
|
||||||
|
const auto rec1 = mCenterArea.pos[i];
|
||||||
|
const auto pos = pointer[i];
|
||||||
|
if (pos > rec1 && pos < rec1 + step) resizeType[i] = 0;
|
||||||
|
if (pos > rec1 + step && pos < rec1 + step * 2) resizeType[i] = 1;
|
||||||
|
if (pos > rec1 + step * 2) resizeType[i] = 2;
|
||||||
|
}
|
||||||
|
} else if (events.isDown(InputID::MOUSE1)) {
|
||||||
|
const auto deltaVec = events.getPointerDelta();
|
||||||
|
|
||||||
|
if (resizeType[0] == 0) resizeSideWidget(mSideWidgets[LEFT], deltaVec);
|
||||||
|
if (resizeType[1] == 0) resizeSideWidget(mSideWidgets[TOP], deltaVec);
|
||||||
|
if (resizeType[0] == 2) resizeSideWidget(mSideWidgets[RIGHT], deltaVec);
|
||||||
|
if (resizeType[1] == 2) resizeSideWidget(mSideWidgets[BOTTOM], deltaVec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridLayoutWidget::updateChildSideWidgets() {
|
||||||
|
// Update Child Widgets
|
||||||
|
{
|
||||||
|
for (ualni i = 0; i < 4; i++) {
|
||||||
|
if (!isSideExists(Side(i))) continue;
|
||||||
|
auto widget = mSideWidgets[i].widget;
|
||||||
|
|
||||||
|
if (!isSideVisible(Side(i))) {
|
||||||
|
widget->mEnable = false;
|
||||||
|
} else {
|
||||||
|
widget->setArea(mSideWidgets[i].area);
|
||||||
|
widget->mEnable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCenterWidget) mCenterWidget->setArea(mCenterArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update depth order
|
||||||
|
/*
|
||||||
|
if (mChildWidgets.size() > 1) {
|
||||||
|
for (auto sideChild : mSideWidgets) {
|
||||||
|
if (!sideChild) continue;
|
||||||
|
|
||||||
|
for (auto childNode = mChildWidgets.firstNode(); childNode; childNode = childNode->next) {
|
||||||
|
if (childNode->data == sideChild) {
|
||||||
|
mChildWidgets.detach(childNode);
|
||||||
|
mChildWidgets.pushBack(childNode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridLayoutWidget::calculateHeaderAreas() {
|
||||||
|
for (ualni i = 0; i < 4; i++) {
|
||||||
|
if (!isSideVisible(Side(i))) continue;
|
||||||
|
auto& area = mSideWidgets[i].area;
|
||||||
|
const auto factor = mHeaderSize / area.size.y;
|
||||||
|
mSideWidgets[i].headerArea = area.splitByFactorVT(factor);
|
||||||
|
area = area.splitByFactorVB(factor);
|
||||||
|
|
||||||
|
mSideWidgets[i].headerArea.size.y -= mPadding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GridLayoutWidget::isSideVisible(GridLayoutWidget::Side side) {
|
||||||
|
return isSideExists(side) && !mSideWidgets[side].hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GridLayoutWidget::isSideExists(GridLayoutWidget::Side side) { return mSideWidgets[side].widget; }
|
||||||
|
|
||||||
|
ualni GridLayoutWidget::getVisibleSidesSize() {
|
||||||
|
ualni out = 0;
|
||||||
|
for (ualni i = 0; i < 4; i++) {
|
||||||
|
if (isSideVisible(Side(i))) out++;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayoutWidget::Side GridLayoutWidget::getPreviewSide() { return mPreviewSide; }
|
||||||
|
|
||||||
|
void GridLayoutWidget::handlePreview(const Events& events) {
|
||||||
|
if (!mPreview) {
|
||||||
|
mPreviewSide = NONE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const halnf factor = 0.3;
|
||||||
|
const halnf handleFactor = 0.1;
|
||||||
|
|
||||||
|
const auto handleSize = min(mCenterArea.size.x, mCenterArea.size.y) * handleFactor;
|
||||||
|
|
||||||
|
for (auto& sideWidget : mSideWidgets) {
|
||||||
|
if (sideWidget.widget) continue;
|
||||||
|
|
||||||
|
switch (sideWidget.side) {
|
||||||
|
case TOP: sideWidget.area = mCenterArea.splitByFactorVT(factor); break;
|
||||||
|
case BOTTOM: sideWidget.area = mCenterArea.splitByFactorVB(1 - factor); break;
|
||||||
|
case LEFT: sideWidget.area = mCenterArea.splitByFactorHL(factor); break;
|
||||||
|
case RIGHT: sideWidget.area = mCenterArea.splitByFactorHR(1 - factor); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sideWidget.area = sideWidget.area.shrink(mPadding * 2);
|
||||||
|
sideWidget.previewHandleArea = sideWidget.area.getSizedFromCenter({ handleSize, handleSize });
|
||||||
|
}
|
||||||
|
|
||||||
|
mPreviewArea = {};
|
||||||
|
mPreviewSide = NONE;
|
||||||
|
for (auto& sideWidget : mSideWidgets) {
|
||||||
|
if (sideWidget.widget) continue;
|
||||||
|
|
||||||
|
if (sideWidget.previewHandleArea.isInside(events.getPointer())) {
|
||||||
|
mPreviewArea = sideWidget.area;
|
||||||
|
mPreviewSide = sideWidget.side;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,7 +13,7 @@ void ScrollBarWidget::eventProcess(const Events& events) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (events.getScrollY() != 0) {
|
if (events.getScrollY() != 0 && mArea.isInside(events.getPointer())) {
|
||||||
auto offset = events.getScrollY() < 0 ? 1.0f : -1.0f;
|
auto offset = events.getScrollY() < 0 ? 1.0f : -1.0f;
|
||||||
mPositionFraction += mSizeFraction * offset * 0.3f;
|
mPositionFraction += mSizeFraction * offset * 0.3f;
|
||||||
mPositionFraction = tp::clamp(mPositionFraction, 0.f, 1.f - mSizeFraction);
|
mPositionFraction = tp::clamp(mPositionFraction, 0.f, 1.f - mSizeFraction);
|
||||||
|
|
@ -98,7 +98,7 @@ void ScrollableWindow::eventProcess(const Events& events) {
|
||||||
|
|
||||||
// to account all changed geometry of child widgets
|
// to account all changed geometry of child widgets
|
||||||
for (auto widget : content) {
|
for (auto widget : content) {
|
||||||
widget->procWrapper(events, this->mArea);
|
widget->procWrapper(events, mContentWidget.mVisibleArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateContents(content);
|
updateContents(content);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,8 @@ void SliderWidget::eventProcess(const Events& events) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SliderWidget::eventDraw(Canvas& canvas) {
|
void SliderWidget::eventDraw(Canvas& canvas) {
|
||||||
canvas.rect(this->mArea, defaultColor, rounding);
|
canvas.rect(this->mArea, handleColor, rounding);
|
||||||
|
canvas.rect(this->mArea.shrink(borderSize), defaultColor, rounding);
|
||||||
canvas.rect(getHandle(), handleColor, rounding);
|
canvas.rect(getHandle(), handleColor, rounding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,8 +32,9 @@ RectF SliderWidget::getHandle() const {
|
||||||
void SliderWidget::eventUpdateConfiguration(WidgetManager& wm) {
|
void SliderWidget::eventUpdateConfiguration(WidgetManager& wm) {
|
||||||
wm.setActiveId("Slider");
|
wm.setActiveId("Slider");
|
||||||
defaultColor = wm.getColor("Default", "Base");
|
defaultColor = wm.getColor("Default", "Base");
|
||||||
handleColor = wm.getColor("Handle", "Accent");
|
handleColor = wm.getColor("Handle", RGBA(0.3f, 0.3f, 0.3f, 1.f));
|
||||||
handleSize = wm.getNumber("HandleSize", 20.f);
|
borderSize = wm.getNumber("BorderSize", 2);
|
||||||
|
handleSize = wm.getNumber("HandleSize", 15.f);
|
||||||
rounding = wm.getNumber("Rounding", "Rounding");
|
rounding = wm.getNumber("Rounding", "Rounding");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,135 +0,0 @@
|
||||||
#include "SplitViewWidget.hpp"
|
|
||||||
|
|
||||||
using namespace tp;
|
|
||||||
|
|
||||||
SplitView::SplitView() {
|
|
||||||
mLeftLabel.mLabel = "Left";
|
|
||||||
mRightLabel.mLabel = "Right";
|
|
||||||
|
|
||||||
this->mChildWidgets.pushBack(&mLeftLabel);
|
|
||||||
this->mChildWidgets.pushBack(&mRightLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SplitView::eventProcess(const Events& events) {
|
|
||||||
mIsHover = getHandle().isInside(events.getPointer());
|
|
||||||
|
|
||||||
if (events.isPressed(InputID::MOUSE1) && mIsHover) {
|
|
||||||
mResizeInProcess = true;
|
|
||||||
} else if (events.isReleased(InputID::MOUSE1)) {
|
|
||||||
mResizeInProcess = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mResizeInProcess) {
|
|
||||||
halnf pos = events.getPointer().x;
|
|
||||||
auto diff = pos - (this->mArea.x + mFactor * this->mArea.z);
|
|
||||||
mFactor += diff / this->mArea.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
mFactor = tp::clamp(mFactor, mMinSize / this->mArea.z, 1 - mMinSize / this->mArea.z);
|
|
||||||
|
|
||||||
if (mMinSize * 2.f > this->mArea.z) {
|
|
||||||
mFactor = 0.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
mLeftLabel.mEnable = mHeaders && mCollapsedSide != LEFT;
|
|
||||||
mRightLabel.mEnable = mHeaders && mCollapsedSide != RIGHT;
|
|
||||||
|
|
||||||
if (mHeaders) {
|
|
||||||
mLeftLabel.setArea(getFirstHeader());
|
|
||||||
mRightLabel.setArea(getSecondHeader());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mLeftLabel.isReleased()) {
|
|
||||||
mCollapsedSide = (mCollapsedSide == NONE) ? RIGHT : NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mRightLabel.isReleased()) {
|
|
||||||
mCollapsedSide = (mCollapsedSide == NONE) ? LEFT : NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SplitView::eventDraw(Canvas& canvas) {
|
|
||||||
if (mResizeInProcess) canvas.rect(getHandle(), mResizingColor);
|
|
||||||
else if (mIsHover) canvas.rect(getHandle(), mHoveredColor);
|
|
||||||
else canvas.rect(getHandle(), mHandleColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SplitView::getFirstEnabled() const { return mCollapsedSide != CollapsedSize::LEFT; }
|
|
||||||
|
|
||||||
bool SplitView::getSecondEnabled() const { return mCollapsedSide != CollapsedSize::RIGHT; }
|
|
||||||
|
|
||||||
RectF SplitView::getFirst() const {
|
|
||||||
Rect out = { this->mArea.x, this->mArea.y, mFactor * this->mArea.z - mHandleSize / 2.f, this->mArea.w };
|
|
||||||
|
|
||||||
if (mCollapsedSide == RIGHT) {
|
|
||||||
out.pos.x = this->mArea.pos.x;
|
|
||||||
out.size.x = this->mArea.size.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mHeaders) {
|
|
||||||
out.pos.y += mHeaderSize;
|
|
||||||
out.size.y -= mHeaderSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
RectF SplitView::getFirstHeader() const {
|
|
||||||
Rect out = { this->mArea.x, this->mArea.y, mFactor * this->mArea.z - mHandleSize / 2.f, mHeaderSize };
|
|
||||||
|
|
||||||
if (mCollapsedSide == RIGHT) {
|
|
||||||
out.pos.x = this->mArea.pos.x;
|
|
||||||
out.size.x = this->mArea.size.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
RectF SplitView::getSecondHeader() const {
|
|
||||||
RectF out = { this->mArea.x + mFactor * this->mArea.z + mHandleSize / 2.f,
|
|
||||||
this->mArea.y,
|
|
||||||
(1.f - mFactor) * this->mArea.z - mHandleSize / 2.f,
|
|
||||||
mHeaderSize };
|
|
||||||
|
|
||||||
if (mCollapsedSide == LEFT) {
|
|
||||||
out.pos.x = this->mArea.pos.x;
|
|
||||||
out.size.x = this->mArea.size.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
RectF SplitView::getSecond() const {
|
|
||||||
RectF out = { this->mArea.x + mFactor * this->mArea.z + mHandleSize / 2.f,
|
|
||||||
this->mArea.y,
|
|
||||||
(1.f - mFactor) * this->mArea.z - mHandleSize / 2.f,
|
|
||||||
this->mArea.w };
|
|
||||||
|
|
||||||
if (mCollapsedSide == LEFT) {
|
|
||||||
out.pos.x = this->mArea.pos.x;
|
|
||||||
out.size.x = this->mArea.size.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mHeaders) {
|
|
||||||
out.pos.y += mHeaderSize;
|
|
||||||
out.size.y -= mHeaderSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
RectF SplitView::getHandle() const {
|
|
||||||
if (mCollapsedSide != NONE) return {};
|
|
||||||
return { this->mArea.x + mFactor * this->mArea.z - mHandleSize / 2.f, this->mArea.y, mHandleSize, this->mArea.w };
|
|
||||||
}
|
|
||||||
|
|
||||||
void SplitView::eventUpdateConfiguration(WidgetManager& wm) {
|
|
||||||
wm.setActiveId("SplitView");
|
|
||||||
|
|
||||||
mHandleColor = wm.getColor("Handle", "Accent");
|
|
||||||
mHoveredColor = wm.getColor("Hovered", "Interaction");
|
|
||||||
mResizingColor = wm.getColor("Resizing", "Action");
|
|
||||||
mMinSize = wm.getNumber("Min", 200.f);
|
|
||||||
mHandleSize = wm.getNumber("HandleSize", 7.f);
|
|
||||||
mHeaderSize = wm.getNumber("HeaderSize", 30.f);
|
|
||||||
}
|
|
||||||
|
|
@ -22,7 +22,7 @@ void Widget::procWrapper(const Events& events, const RectF& parentArea) {
|
||||||
eventProcess(events);
|
eventProcess(events);
|
||||||
|
|
||||||
for (auto child : mChildWidgets) {
|
for (auto child : mChildWidgets) {
|
||||||
child->procWrapper(events, getArea());
|
child->procWrapper(events, mVisibleArea);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -38,6 +38,8 @@ void Widget::drawWrapper(Canvas& canvas) {
|
||||||
child->data->drawWrapper(canvas);
|
child->data->drawWrapper(canvas);
|
||||||
}
|
}
|
||||||
canvas.popClamp();
|
canvas.popClamp();
|
||||||
|
|
||||||
|
eventDrawOver(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::updateConfigWrapper(WidgetManager& wm) {
|
void Widget::updateConfigWrapper(WidgetManager& wm) {
|
||||||
|
|
@ -52,6 +54,7 @@ void Widget::updateConfigWrapper(WidgetManager& wm) {
|
||||||
|
|
||||||
void Widget::eventProcess(const Events& events) {}
|
void Widget::eventProcess(const Events& events) {}
|
||||||
void Widget::eventDraw(Canvas& canvas) {}
|
void Widget::eventDraw(Canvas& canvas) {}
|
||||||
|
void Widget::eventDrawOver(Canvas& canvas) {}
|
||||||
void Widget::eventUpdateConfiguration(WidgetManager& wm) {}
|
void Widget::eventUpdateConfiguration(WidgetManager& wm) {}
|
||||||
|
|
||||||
void Widget::eventVisible(const Events& events) {}
|
void Widget::eventVisible(const Events& events) {}
|
||||||
|
|
@ -66,6 +69,8 @@ void Widget::eventReleased(const Events& events) {}
|
||||||
void Widget::checkVisibility(const Events& events, const RectF& parentArea) {
|
void Widget::checkVisibility(const Events& events, const RectF& parentArea) {
|
||||||
const bool currentVisibility = parentArea.isOverlap(getArea());
|
const bool currentVisibility = parentArea.isOverlap(getArea());
|
||||||
|
|
||||||
|
parentArea.calcIntersection(mArea, mVisibleArea);
|
||||||
|
|
||||||
if (currentVisibility != mVisible) {
|
if (currentVisibility != mVisible) {
|
||||||
if (currentVisibility) eventVisible(events);
|
if (currentVisibility) eventVisible(events);
|
||||||
else eventNotVisible(events);
|
else eventNotVisible(events);
|
||||||
|
|
@ -81,7 +86,7 @@ void Widget::checkVisibility(const Events& events, const RectF& parentArea) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::checkFocus(const Events& events) {
|
void Widget::checkFocus(const Events& events) {
|
||||||
const bool currentFocus = getArea().isInside(events.getPointer());
|
const bool currentFocus = mVisibleArea.isInside(events.getPointer());
|
||||||
|
|
||||||
if (currentFocus != mInFocus) {
|
if (currentFocus != mInFocus) {
|
||||||
if (currentFocus) eventFocusEnter(events);
|
if (currentFocus) eventFocusEnter(events);
|
||||||
|
|
@ -110,7 +115,7 @@ void Widget::checkClicked(const Events& events) {
|
||||||
mHolding = false;
|
mHolding = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (events.isPressed(InputID::MOUSE1)) {
|
if (events.isPressed(InputID::MOUSE1) && mVisibleArea.isInside(events.getPointer())) {
|
||||||
eventPressed(events);
|
eventPressed(events);
|
||||||
mHolding = true;
|
mHolding = true;
|
||||||
mPressed = true;
|
mPressed = true;
|
||||||
|
|
|
||||||
72
Widgets/private/WorkspaceWidget.cpp
Normal file
72
Widgets/private/WorkspaceWidget.cpp
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
#include "WorkspaceWidget.hpp"
|
||||||
|
|
||||||
|
using namespace tp;
|
||||||
|
|
||||||
|
WorkspaceWidget::WorkspaceWidget() {
|
||||||
|
this->mChildWidgets.pushBack(&mFloatingLayer);
|
||||||
|
this->mChildWidgets.pushBack(&mDockSpace);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorkspaceWidget::eventProcess(const Events& events) {
|
||||||
|
mDockSpace.setArea(this->mArea);
|
||||||
|
mFloatingLayer.setArea(this->mArea);
|
||||||
|
|
||||||
|
mDockSpace.mPreview = false;
|
||||||
|
mDockSpace.mHandlesEvents = !mFloatingLayer.handlesEvent();
|
||||||
|
|
||||||
|
for (auto floatingChild : mFloatingLayer.mChildWidgets) {
|
||||||
|
auto widget = dynamic_cast<FloatingWidget*>(floatingChild.data());
|
||||||
|
if (!widget) continue;
|
||||||
|
if (widget->isFloating()) {
|
||||||
|
if (widget->isReleased()) {
|
||||||
|
auto side = mDockSpace.getPreviewSide();
|
||||||
|
if (side != GridLayoutWidget::NONE) {
|
||||||
|
mFloatingLayer.mChildWidgets.removeNode(mFloatingLayer.mChildWidgets.find(widget));
|
||||||
|
widget->setCollapsed(true);
|
||||||
|
widget->stopFloating();
|
||||||
|
mDockSpace.addSideWidget(widget, side);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mDockSpace.mHandlesEvents = true;
|
||||||
|
mDockSpace.mPreview = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& dockedChild : mDockSpace.mSideWidgets) {
|
||||||
|
auto widget = dynamic_cast<FloatingWidget*>(dockedChild.widget);
|
||||||
|
if (!widget) continue;
|
||||||
|
|
||||||
|
if (widget->isFloating()) {
|
||||||
|
mDockSpace.removeSideWidget(dockedChild.side);
|
||||||
|
mFloatingLayer.mChildWidgets.pushBack(widget);
|
||||||
|
widget->mArea.pos = events.getPointer() - 20;
|
||||||
|
widget->mArea.size = mDefaultFloatSize;
|
||||||
|
|
||||||
|
widget->mResizable = true;
|
||||||
|
// widget->mBorders = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// toggle hide state
|
||||||
|
if (events.isDown(InputID::LEFT_ALT)) {
|
||||||
|
if (events.isPressed(InputID::N1)) {
|
||||||
|
mDockSpace.toggleHiddenState(GridLayoutWidget::LEFT);
|
||||||
|
} else if (events.isPressed(InputID::N2)) {
|
||||||
|
mDockSpace.toggleHiddenState(GridLayoutWidget::TOP);
|
||||||
|
} else if (events.isPressed(InputID::N3)) {
|
||||||
|
mDockSpace.toggleHiddenState(GridLayoutWidget::RIGHT);
|
||||||
|
} else if (events.isPressed(InputID::N4)) {
|
||||||
|
mDockSpace.toggleHiddenState(GridLayoutWidget::BOTTOM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& dockedChild : mDockSpace.mSideWidgets) {
|
||||||
|
auto widget = dynamic_cast<FloatingWidget*>(dockedChild.widget);
|
||||||
|
if (!widget) continue;
|
||||||
|
|
||||||
|
widget->setCollapsed(false);
|
||||||
|
widget->mResizable = false;
|
||||||
|
// widget->mBorders = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,9 @@
|
||||||
namespace tp {
|
namespace tp {
|
||||||
|
|
||||||
class ButtonWidget : public Widget {
|
class ButtonWidget : public Widget {
|
||||||
|
public:
|
||||||
|
// enum State { NONE, ANTICIPATION, ACTIVATED, CONFIRMED };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ButtonWidget();
|
ButtonWidget();
|
||||||
ButtonWidget(const std::string& label, const tp::RectF& aArea);
|
ButtonWidget(const std::string& label, const tp::RectF& aArea);
|
||||||
|
|
@ -20,6 +23,7 @@ namespace tp {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LabelWidget mLabel;
|
LabelWidget mLabel;
|
||||||
|
// State mStat = NONE;
|
||||||
|
|
||||||
RGBA pressedColor;
|
RGBA pressedColor;
|
||||||
RGBA hoveredColor;
|
RGBA hoveredColor;
|
||||||
|
|
|
||||||
|
|
@ -44,5 +44,8 @@ namespace tp {
|
||||||
bool mCollapsed = true;
|
bool mCollapsed = true;
|
||||||
bool mLocked = false;
|
bool mLocked = false;
|
||||||
bool mAdjustHeight = true;
|
bool mAdjustHeight = true;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool mBorders = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
18
Widgets/public/FloatingLayoutWidget.hpp
Normal file
18
Widgets/public/FloatingLayoutWidget.hpp
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
#include "FloatingWidget.hpp"
|
||||||
|
|
||||||
|
namespace tp {
|
||||||
|
class FloatingLayoutWidget : public Widget {
|
||||||
|
public:
|
||||||
|
FloatingLayoutWidget();
|
||||||
|
|
||||||
|
void eventProcess(const Events& events) override;
|
||||||
|
|
||||||
|
[[nodiscard]] bool handlesEvent() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateActiveWindow(const tp::Events& events);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mIsPassThrough = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -11,6 +11,9 @@ namespace tp {
|
||||||
void eventDraw(Canvas& canvas) override;
|
void eventDraw(Canvas& canvas) override;
|
||||||
void eventUpdateConfiguration(WidgetManager& wm) override;
|
void eventUpdateConfiguration(WidgetManager& wm) override;
|
||||||
|
|
||||||
|
[[nodiscard]] bool isFloating() const;
|
||||||
|
void stopFloating();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void checkFloating(const Events& events);
|
void checkFloating(const Events& events);
|
||||||
void checkResizing(const Events& events);
|
void checkResizing(const Events& events);
|
||||||
|
|
@ -26,5 +29,8 @@ namespace tp {
|
||||||
bool mResizing = false;
|
bool mResizing = false;
|
||||||
|
|
||||||
Vec2F mActionStartRelativePos = {};
|
Vec2F mActionStartRelativePos = {};
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool mResizable = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -1,25 +1,51 @@
|
||||||
#include "FloatingWidget.hpp"
|
#include "WidgetBase.hpp"
|
||||||
|
|
||||||
namespace tp {
|
namespace tp {
|
||||||
class DockSpaceWidget : public Widget {
|
class GridLayoutWidget : public Widget {
|
||||||
public:
|
public:
|
||||||
enum Side { LEFT, TOP, RIGHT, BOTTOM };
|
enum Side { LEFT, TOP, RIGHT, BOTTOM, NONE };
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct ResizeHandle {
|
||||||
|
RectF area{ 0, 0, 0, 0 };
|
||||||
|
halnf start{ 0 };
|
||||||
|
halnf end{ 0 };
|
||||||
|
bool active = false;
|
||||||
|
bool hover = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SideWidgetData {
|
||||||
|
Widget* widget = nullptr;
|
||||||
|
bool hidden = false;
|
||||||
|
halnf absoluteSize = 200;
|
||||||
|
alni order = -1;
|
||||||
|
|
||||||
|
Side side = { TOP };
|
||||||
|
|
||||||
|
RectF area = {};
|
||||||
|
RectF headerArea = {};
|
||||||
|
RectF previewHandleArea = {};
|
||||||
|
|
||||||
|
ResizeHandle resizeHandle;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DockSpaceWidget();
|
GridLayoutWidget();
|
||||||
|
|
||||||
void eventProcess(const Events& events) override;
|
void eventProcess(const Events& events) override;
|
||||||
void eventDraw(Canvas& canvas) override;
|
void eventDraw(Canvas& canvas) override;
|
||||||
|
void eventDrawOver(Canvas& canvas) override;
|
||||||
|
|
||||||
void addSideWidget(Widget* widget, Side side);
|
void addSideWidget(Widget* widget, Side side);
|
||||||
void removeSideWidget(Side side);
|
void removeSideWidget(Side side);
|
||||||
|
|
||||||
void toggleHiddenState(DockSpaceWidget::Side side);
|
void toggleHiddenState(Side side);
|
||||||
|
|
||||||
void setCenterWidget(Widget* widget);
|
void setCenterWidget(Widget* widget);
|
||||||
|
|
||||||
|
Side getPreviewSide();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateActiveWindow(const tp::Events& events);
|
|
||||||
void calculateSideAreas();
|
void calculateSideAreas();
|
||||||
void calculateResizeHandles();
|
void calculateResizeHandles();
|
||||||
void handleResizeEvents(const Events& events);
|
void handleResizeEvents(const Events& events);
|
||||||
|
|
@ -27,43 +53,36 @@ namespace tp {
|
||||||
|
|
||||||
void calculateHeaderAreas();
|
void calculateHeaderAreas();
|
||||||
|
|
||||||
|
|
||||||
bool isSideVisible(Side side);
|
bool isSideVisible(Side side);
|
||||||
bool isSideExists(Side side);
|
bool isSideExists(Side side);
|
||||||
ualni getVisibleSidesSize();
|
ualni getVisibleSidesSize();
|
||||||
|
void handlePreview(const Events& events);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// todo : make better grouping into structs
|
RectF mPreviewArea = {};
|
||||||
|
Side mPreviewSide = NONE;
|
||||||
|
int resizeType[2] = { 0, 0 };
|
||||||
|
|
||||||
Widget* mSideWidgets[4] { nullptr, nullptr, nullptr, nullptr };
|
public:
|
||||||
|
SideWidgetData mSideWidgets[4];
|
||||||
|
|
||||||
|
private:
|
||||||
Widget* mCenterWidget = nullptr;
|
Widget* mCenterWidget = nullptr;
|
||||||
|
|
||||||
alni mSideSplitOrder[4] = { -1, -1, -1, -1 };
|
|
||||||
halnf mSideAbsoluteSize[4] { 200, 100, 200, 100 };
|
|
||||||
bool mSideHidden[4] { true, false, false, false };
|
|
||||||
halnf mSideSizePadding = 50.f;
|
|
||||||
|
|
||||||
// Geometry cache
|
|
||||||
struct ResizeHandle {
|
|
||||||
RectF area{ 0, 0, 0, 0 };
|
|
||||||
Side side{ TOP };
|
|
||||||
halnf start{ 0 };
|
|
||||||
halnf end{ 0 };
|
|
||||||
bool active = false;
|
|
||||||
bool hover = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
Buffer<ResizeHandle> mResizeHandles;
|
|
||||||
RectF mSideAreas[4];
|
|
||||||
RectF mSideHeaderAreas[4];
|
|
||||||
RectF mCenterArea {};
|
RectF mCenterArea {};
|
||||||
|
|
||||||
// View Parameters
|
// Parameters
|
||||||
|
halnf mSideSizePadding = 150.f;
|
||||||
halnf mPadding = 4;
|
halnf mPadding = 4;
|
||||||
halnf mHeaderSize = 27;
|
halnf mHeaderSize = 27;
|
||||||
|
halnf mRounding = 10;
|
||||||
|
Vec2F mPreviewHandleSize = { 50, 50 };
|
||||||
|
|
||||||
RGBA mResizeHandleColorHovered = RGBA(0.3, 0.3, 0.3, 1);
|
RGBA mResizeHandleColorHovered = RGBA(0.3, 0.3, 0.3, 1);
|
||||||
RGBA mResizeHandleColorActive = RGBA(0.6, 0.6, 0.6, 1);
|
RGBA mResizeHandleColorActive = RGBA(0.6, 0.6, 0.6, 1);
|
||||||
RGBA mBackgroundColor = RGBA(0, 0, 0, 1);
|
RGBA mBackgroundColor = RGBA(0, 0, 0, 1);
|
||||||
|
RGBA mPreviewColor = RGBA(0.6, 0.6, 0.6, 1);
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool mPreview = false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -24,6 +24,7 @@ namespace tp {
|
||||||
RGBA handleColor;
|
RGBA handleColor;
|
||||||
halnf handleSize = 0;
|
halnf handleSize = 0;
|
||||||
halnf rounding = 0;
|
halnf rounding = 0;
|
||||||
|
halnf borderSize = 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NamedSliderWidget : public Widget {
|
class NamedSliderWidget : public Widget {
|
||||||
|
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "LabelWidget.hpp"
|
|
||||||
|
|
||||||
namespace tp {
|
|
||||||
|
|
||||||
//TODO : clean up this mess
|
|
||||||
// takes the whole parent area
|
|
||||||
class SplitView : public Widget {
|
|
||||||
public:
|
|
||||||
SplitView();
|
|
||||||
|
|
||||||
void eventProcess(const Events& events) override;
|
|
||||||
void eventDraw(Canvas& canvas) override;
|
|
||||||
|
|
||||||
[[nodiscard]] bool getFirstEnabled() const;
|
|
||||||
[[nodiscard]] bool getSecondEnabled() const;
|
|
||||||
|
|
||||||
RectF getFirst() const;
|
|
||||||
RectF getFirstHeader() const;
|
|
||||||
RectF getSecondHeader() const;
|
|
||||||
RectF getSecond() const ;
|
|
||||||
RectF getHandle() const;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void eventUpdateConfiguration(WidgetManager& wm) override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
halnf mFactor = 0.7f;
|
|
||||||
bool mResizeInProcess = false;
|
|
||||||
bool mIsHover = false;
|
|
||||||
|
|
||||||
RGBA mHandleColor;
|
|
||||||
RGBA mHoveredColor;
|
|
||||||
RGBA mResizingColor;
|
|
||||||
halnf mMinSize = 0;
|
|
||||||
halnf mHandleSize = 0;
|
|
||||||
|
|
||||||
// Headers
|
|
||||||
halnf mHeaderSize = 0;
|
|
||||||
bool mHeaders = false;
|
|
||||||
enum CollapsedSize { NONE, LEFT, RIGHT } mCollapsedSide = NONE;
|
|
||||||
|
|
||||||
LabelWidget mLeftLabel;
|
|
||||||
LabelWidget mRightLabel;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -20,7 +20,13 @@ namespace tp {
|
||||||
void updateConfigWrapper(WidgetManager& wm);
|
void updateConfigWrapper(WidgetManager& wm);
|
||||||
|
|
||||||
virtual void eventProcess(const Events& events);
|
virtual void eventProcess(const Events& events);
|
||||||
|
|
||||||
|
// draws before child widgets
|
||||||
virtual void eventDraw(Canvas& canvas);
|
virtual void eventDraw(Canvas& canvas);
|
||||||
|
|
||||||
|
// draws overlay after child widgets
|
||||||
|
virtual void eventDrawOver(Canvas& canvas);
|
||||||
|
|
||||||
virtual void eventUpdateConfiguration(WidgetManager& wm);
|
virtual void eventUpdateConfiguration(WidgetManager& wm);
|
||||||
|
|
||||||
virtual void eventVisible(const Events& events);
|
virtual void eventVisible(const Events& events);
|
||||||
|
|
@ -52,6 +58,7 @@ namespace tp {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RectF mArea;
|
RectF mArea;
|
||||||
|
RectF mVisibleArea;
|
||||||
|
|
||||||
List<Widget*> mChildWidgets;
|
List<Widget*> mChildWidgets;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Animations.hpp"
|
||||||
#include "ButtonWidget.hpp"
|
#include "ButtonWidget.hpp"
|
||||||
#include "LabelWidget.hpp"
|
#include "LabelWidget.hpp"
|
||||||
#include "ScrollableWidget.hpp"
|
#include "ScrollableWidget.hpp"
|
||||||
#include "SplitViewWidget.hpp"
|
|
||||||
#include "TextInputWidget.hpp"
|
#include "TextInputWidget.hpp"
|
||||||
#include "SliderWidget.hpp"
|
#include "SliderWidget.hpp"
|
||||||
#include "CollapsableMenu.hpp"
|
#include "CollapsableMenu.hpp"
|
||||||
#include "FloatingWidget.hpp"
|
#include "FloatingWidget.hpp"
|
||||||
#include "Animations.hpp"
|
#include "FloatingLayoutWidget.hpp"
|
||||||
#include "DockspaceWidget.hpp"
|
#include "GridLayoutWidget.hpp"
|
||||||
|
#include "WorkspaceWidget.hpp"
|
||||||
|
|
|
||||||
19
Widgets/public/WorkspaceWidget.hpp
Normal file
19
Widgets/public/WorkspaceWidget.hpp
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Widgets.hpp"
|
||||||
|
|
||||||
|
namespace tp {
|
||||||
|
class WorkspaceWidget : public Widget {
|
||||||
|
public:
|
||||||
|
WorkspaceWidget();
|
||||||
|
|
||||||
|
void eventProcess(const Events& events) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GridLayoutWidget mDockSpace;
|
||||||
|
FloatingLayoutWidget mFloatingLayer;
|
||||||
|
|
||||||
|
// Parameters
|
||||||
|
Vec2F mDefaultFloatSize = { 200, 200 };
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue