173 lines
No EOL
5.2 KiB
C++
173 lines
No EOL
5.2 KiB
C++
#pragma once
|
|
|
|
#include "Sketch3D.hpp"
|
|
#include "Widgets.hpp"
|
|
|
|
namespace tp {
|
|
|
|
template <typename Events, typename Canvas>
|
|
class Sketch3DWidget : public Widget<Events, Canvas> {
|
|
public:
|
|
Sketch3DWidget(Canvas& canvas, Vec2F renderResolution) :
|
|
mRenderer(renderResolution) {
|
|
mImage = canvas.createImageFromTextId(mRenderer.getBuff()->texId(), mRenderer.getBuff()->getSize());
|
|
mCanvas = &canvas;
|
|
|
|
mProject.mBackgroundColor = { 0.13f, 0.13f, 0.13f, 1.f };
|
|
}
|
|
|
|
~Sketch3DWidget() { mCanvas->deleteImageHandle(mImage); }
|
|
|
|
void eventProcess(const Events& events) override {
|
|
if (!this->mArea.isInside(events.getPointer())) {
|
|
return;
|
|
}
|
|
|
|
auto crs = (events.getPointer() - this->mArea.pos);
|
|
crs.x /= this->mArea.z;
|
|
crs.y /= this->mArea.w;
|
|
crs = (crs - 0.5) * 2;
|
|
|
|
// TODO : make better api for events
|
|
Vec2F absolutePos = events.getPointer() - this->mArea.pos;
|
|
|
|
if (events.isPressed(InputID::MOUSE1)) {
|
|
mAction = true;
|
|
} else if (events.isReleased(InputID::MOUSE1)) {
|
|
mAction = false;
|
|
}
|
|
|
|
Vec2F relativePos = ((absolutePos / this->mArea.size) - 0.5f) * 2.f;
|
|
Vec2F relativePosPrev = ((mActionPosAbsolutePrev / this->mArea.size) - 0.5f) * 2.f;
|
|
Vec2F relativeDelta = relativePos - relativePosPrev;
|
|
|
|
mProject.mCamera.setRatio(this->mArea.w / this->mArea.z);
|
|
|
|
switch (mMode) {
|
|
case Mode::MOVE:
|
|
{
|
|
if (mAction) mProject.mCamera.move(relativePos, relativePosPrev);
|
|
break;
|
|
}
|
|
case Mode::ZOOM:
|
|
{
|
|
halnf factor = absolutePos.y / mActionPosAbsolutePrev.y;
|
|
if (mAction) mProject.mCamera.zoom(factor);
|
|
break;
|
|
}
|
|
case Mode::ROTATE:
|
|
{
|
|
if (mAction) mProject.mCamera.rotate(-relativeDelta.x * halnf(PI), -relativeDelta.y * halnf(PI));
|
|
break;
|
|
}
|
|
case Mode::DRAW:
|
|
{
|
|
mProject.sample(events.getPointerPressure(), this->mArea.w / this->mArea.z, crs);
|
|
break;
|
|
}
|
|
default: break;
|
|
}
|
|
|
|
mActionPosAbsolutePrev = absolutePos;
|
|
}
|
|
|
|
void eventDraw(Canvas& canvas) override {
|
|
mRenderer.renderToTexture(&mProject, this->mArea.size);
|
|
canvas.drawImage(this->mArea, &mImage, 0, 1, 12);
|
|
}
|
|
|
|
void setColor(const RGBA& color) { ((PencilBrush*) mProject.mBrushes.get("pencil"))->mCol = color; }
|
|
|
|
public:
|
|
enum class Mode { MOVE, ROTATE, ZOOM, DRAW, NONE } mMode = Mode::NONE;
|
|
|
|
Vec2F mActionPosAbsolutePrev = { 0, 0 };
|
|
bool mAction = false;
|
|
|
|
private:
|
|
Renderer mRenderer;
|
|
Project mProject;
|
|
Canvas::ImageHandle mImage;
|
|
Canvas* mCanvas = nullptr;
|
|
};
|
|
|
|
template <typename Events, typename Canvas>
|
|
class Sketch3DGUI : public Widget<Events, Canvas> {
|
|
public:
|
|
Sketch3DGUI(Canvas& canvas, Vec2F renderResolution) :
|
|
mViewport(canvas, renderResolution) {
|
|
mDrawButton = new ButtonWidget<Events, Canvas>("Draw", { 0, 0, 100, 30 });
|
|
mMoveButton = new ButtonWidget<Events, Canvas>("Pan View", { 0, 0, 100, 30 });
|
|
mRotateButton = new ButtonWidget<Events, Canvas>("Rotate view", { 0, 0, 100, 30 });
|
|
mZoomButton = new ButtonWidget<Events, Canvas>("Zoom view", { 0, 0, 100, 30 });
|
|
|
|
mOptions.addWidget(mDrawButton);
|
|
mOptions.addWidget(mMoveButton);
|
|
mOptions.addWidget(mRotateButton);
|
|
mOptions.addWidget(mZoomButton);
|
|
|
|
// add color sliders
|
|
mRed = new NamedSliderWidget<Events, Canvas>("Red");
|
|
mGreen = new NamedSliderWidget<Events, Canvas>("Green");
|
|
mBlue = new NamedSliderWidget<Events, Canvas>("Blue");
|
|
|
|
mOptions.addWidget(mRed);
|
|
mOptions.addWidget(mGreen);
|
|
mOptions.addWidget(mBlue);
|
|
|
|
this->mChildWidgets.pushBack(&mViewport);
|
|
this->mChildWidgets.pushBack(&mSplitView);
|
|
this->mChildWidgets.pushBack(&mOptions);
|
|
}
|
|
|
|
~Sketch3DGUI() {
|
|
for (auto item : mOptions.getContent()) {
|
|
delete item.data();
|
|
}
|
|
}
|
|
|
|
void eventProcess(const Events& events) override {
|
|
mSplitView.setArea(this->mArea);
|
|
mViewport.setArea(mSplitView.getFirst());
|
|
mOptions.setArea(mSplitView.getSecond());
|
|
|
|
if (mDrawButton->isFired()) {
|
|
mViewport.mMode = Sketch3DWidget<Events, Canvas>::Mode::DRAW;
|
|
} else if (mMoveButton->isFired()) {
|
|
mViewport.mMode = Sketch3DWidget<Events, Canvas>::Mode::MOVE;
|
|
} else if (mRotateButton->isFired()) {
|
|
mViewport.mMode = Sketch3DWidget<Events, Canvas>::Mode::ROTATE;
|
|
} else if (mZoomButton->isFired()) {
|
|
mViewport.mMode = Sketch3DWidget<Events, Canvas>::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 eventUpdateConfiguration(WidgetManager& wm) override {
|
|
wm.setActiveId("Sketch3DGui");
|
|
|
|
mBackgroundColor = wm.getColor("Background", "Background");
|
|
mRounding = wm.getNumber("Rounding", "Rounding");
|
|
}
|
|
|
|
private:
|
|
Sketch3DWidget<Events, Canvas> mViewport;
|
|
SplitView<Events, Canvas> mSplitView;
|
|
ScrollableWindow<Events, Canvas> mOptions;
|
|
|
|
ButtonWidget<Events, Canvas>* mDrawButton = nullptr;
|
|
ButtonWidget<Events, Canvas>* mMoveButton = nullptr;
|
|
ButtonWidget<Events, Canvas>* mRotateButton = nullptr;
|
|
ButtonWidget<Events, Canvas>* mZoomButton = nullptr;
|
|
|
|
NamedSliderWidget<Events, Canvas>* mRed = nullptr;
|
|
NamedSliderWidget<Events, Canvas>* mGreen = nullptr;
|
|
NamedSliderWidget<Events, Canvas>* mBlue = nullptr;
|
|
|
|
RGBA mBackgroundColor;
|
|
halnf mRounding = 0;
|
|
};
|
|
} |