stable
This commit is contained in:
parent
6d02137dca
commit
a46a2167ba
13 changed files with 182 additions and 90 deletions
|
|
@ -37,6 +37,8 @@ DebugGUI::DebugGUI(Window* window) {
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.Fonts->AddFontFromFileTTF("Font.ttf", 20.f);
|
io.Fonts->AddFontFromFileTTF("Font.ttf", 20.f);
|
||||||
|
|
||||||
|
io.ConfigInputTrickleEventQueue = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugGUI::~DebugGUI() {
|
DebugGUI::~DebugGUI() {
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,87 @@
|
||||||
using namespace tp;
|
using namespace tp;
|
||||||
|
|
||||||
EventHandler::EventHandler() = default;
|
EventHandler::EventHandler() = default;
|
||||||
EventHandler::~EventHandler() = default;
|
EventHandler::~EventHandler() = default;
|
||||||
|
|
||||||
|
void EventHandler::postEvent(InputID inputID, InputEvent inputEvent) {
|
||||||
|
mMutex.lock();
|
||||||
|
mEventQueue.pushBack({ inputID, inputEvent });
|
||||||
|
mMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EventHandler::isEvents() {
|
||||||
|
mMutex.lock();
|
||||||
|
auto res = mEventQueue.length();
|
||||||
|
mMutex.unlock();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputState::State transitions[4][4] = {
|
||||||
|
{ InputState::State::NONE, InputState::State::PRESSED, InputState::State::PRESSED, InputState::State::NONE },
|
||||||
|
{ InputState::State::PRESSED, InputState::State::PRESSED, InputState::State::HOLD, InputState::State::PRESSED },
|
||||||
|
{ InputState::State::HOLD, InputState::State::RELEASED, InputState::State::RELEASED, InputState::State::HOLD },
|
||||||
|
{ InputState::State::RELEASED, InputState::State::NONE, InputState::State::RELEASED, InputState::State::RELEASED },
|
||||||
|
};
|
||||||
|
|
||||||
|
bool transitionsReduce[4][4] = {
|
||||||
|
{ true, true, false, true },
|
||||||
|
{ true, true, false, true },
|
||||||
|
{ true, false, true, true },
|
||||||
|
{ true, false, true, true },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void EventHandler::processEvent() {
|
||||||
|
mMutex.lock();
|
||||||
|
auto lastEvent = mEventQueue.last();
|
||||||
|
|
||||||
|
const auto& eventData = lastEvent->data.second;
|
||||||
|
const auto& inputId = lastEvent->data.first;
|
||||||
|
|
||||||
|
switch (eventData.type) {
|
||||||
|
case InputEvent::Type::MOUSE_POS:
|
||||||
|
{
|
||||||
|
mPointer = eventData.mouseEvent;
|
||||||
|
mEventQueue.popFront();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case InputEvent::Type::BUTTON_ACTION:
|
||||||
|
{
|
||||||
|
auto currentState = (int) mInputStates[(int) inputId].mCurrentState;
|
||||||
|
auto reportedEvent = (int) eventData.buttonAction;
|
||||||
|
|
||||||
|
mInputStates[(int) inputId].mCurrentState = transitions[currentState][reportedEvent];
|
||||||
|
|
||||||
|
if (transitionsReduce[currentState][reportedEvent]) {
|
||||||
|
mEventQueue.popFront();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
mEventQueue.popFront();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vec2F& EventHandler::getPointer() const { return mPointer; }
|
||||||
|
|
||||||
|
bool EventHandler::isPressed(InputID id) const {
|
||||||
|
return mInputStates[(int) id].mCurrentState == InputState::State::PRESSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EventHandler::isReleased(InputID id) const {
|
||||||
|
return mInputStates[(int) id].mCurrentState == InputState::State::RELEASED;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EventHandler::isDown(InputID id) const {
|
||||||
|
return mInputStates[(int) id].mCurrentState == InputState::State::PRESSED ||
|
||||||
|
mInputStates[(int) id].mCurrentState == InputState::State::HOLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
halnf EventHandler::getScrollY() const { return 0; }
|
||||||
|
|
@ -96,6 +96,8 @@ bool Window::shouldClose() const { return glfwWindowShouldClose(mContext->window
|
||||||
void Window::processEvents() {
|
void Window::processEvents() {
|
||||||
glfwWaitEvents();
|
glfwWaitEvents();
|
||||||
checkAxisUpdates();
|
checkAxisUpdates();
|
||||||
|
|
||||||
|
glViewport(0, 0, mSize.x, mSize.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::draw() {
|
void Window::draw() {
|
||||||
|
|
@ -134,7 +136,7 @@ void Window::checkAxisUpdates() {
|
||||||
RectF windowRec = { { 0, 0 }, mSize };
|
RectF windowRec = { { 0, 0 }, mSize };
|
||||||
|
|
||||||
if (windowRec.isInside(mPointerPos)) {
|
if (windowRec.isInside(mPointerPos)) {
|
||||||
mEventHandler->postEvent(InputID::MOUSE1, { {}, {}, mPointerPos });
|
mEventHandler->postEvent(InputID::MOUSE1, { InputEvent::Type::MOUSE_POS, {}, mPointerPos });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -149,15 +151,11 @@ static void keyCallback(GLFWwindow* window, int key, int scancode, int action, i
|
||||||
|
|
||||||
self->checkAxisUpdates();
|
self->checkAxisUpdates();
|
||||||
|
|
||||||
// post key event
|
|
||||||
/*
|
|
||||||
if (action == GLFW_PRESS) {
|
if (action == GLFW_PRESS) {
|
||||||
inputManager->keyStates[key] = GLFW_PRESS;
|
eventHandler->postEvent((InputID) key, { InputEvent::Type::BUTTON_ACTION, InputEvent::ButtonAction::PRESS, {} });
|
||||||
} else if (action == GLFW_RELEASE) {
|
} else if (action == GLFW_RELEASE) {
|
||||||
inputManager->keyStates[key] = GLFW_RELEASE;
|
eventHandler->postEvent((InputID) key, { InputEvent::Type::BUTTON_ACTION, InputEvent::ButtonAction::RELEASE, {} });
|
||||||
}
|
}
|
||||||
inputManager->isEvent = true;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods) {
|
static void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods) {
|
||||||
|
|
@ -169,9 +167,14 @@ static void mouseButtonCallback(GLFWwindow* window, int button, int action, int
|
||||||
|
|
||||||
self->checkAxisUpdates();
|
self->checkAxisUpdates();
|
||||||
|
|
||||||
// post mouse button event
|
auto id = (InputID) ((int) InputID::MOUSE1 + button);
|
||||||
// inputManager->mouseButtonStates[button] = action;
|
|
||||||
// inputManager->isEvent = true;
|
if (action == GLFW_PRESS) {
|
||||||
|
eventHandler->postEvent(id, { InputEvent::Type::BUTTON_ACTION, InputEvent::ButtonAction::PRESS, {} }
|
||||||
|
);
|
||||||
|
} else if (action == GLFW_RELEASE) {
|
||||||
|
eventHandler->postEvent(id, { InputEvent::Type::BUTTON_ACTION, InputEvent::ButtonAction::RELEASE, {} });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scrollCallback(GLFWwindow* window, double xOffset, double yOffset) {
|
static void scrollCallback(GLFWwindow* window, double xOffset, double yOffset) {
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,14 @@ namespace tp {
|
||||||
|
|
||||||
struct InputEvent {
|
struct InputEvent {
|
||||||
enum class Type {
|
enum class Type {
|
||||||
NONE,
|
NONE = 0,
|
||||||
BUTTON_ACTION,
|
BUTTON_ACTION,
|
||||||
MOUSE_DELTA,
|
MOUSE_DELTA,
|
||||||
MOUSE_POS,
|
MOUSE_POS,
|
||||||
} type = Type::NONE;
|
} type = Type::NONE;
|
||||||
|
|
||||||
enum class ButtonAction {
|
enum class ButtonAction {
|
||||||
NONE,
|
NONE = 0,
|
||||||
PRESS,
|
PRESS,
|
||||||
RELEASE,
|
RELEASE,
|
||||||
REPEAT,
|
REPEAT,
|
||||||
|
|
@ -28,18 +28,6 @@ namespace tp {
|
||||||
};
|
};
|
||||||
|
|
||||||
class InputState {
|
class InputState {
|
||||||
// Transitions from state to state is strict and defined by state order in the enum
|
|
||||||
// If posted event conflicts with that automata, we need to emulate intermediate states
|
|
||||||
enum State {
|
|
||||||
NONE, // Button is inactive
|
|
||||||
PRESSED, // Button is pressed
|
|
||||||
HOLD, // Button is still pressed
|
|
||||||
RELEASED, // Button is released
|
|
||||||
};
|
|
||||||
|
|
||||||
State mCurrentState;
|
|
||||||
State mPreviousState;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InputState() = default;
|
InputState() = default;
|
||||||
|
|
||||||
|
|
@ -49,6 +37,19 @@ namespace tp {
|
||||||
|
|
||||||
// true if event is no longer needed and false if we need to emulate some transitions further
|
// true if event is no longer needed and false if we need to emulate some transitions further
|
||||||
bool isHandled();
|
bool isHandled();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Transitions from state to state is strict and defined by state order in the enum
|
||||||
|
// If posted event conflicts with that automata, we need to emulate intermediate states
|
||||||
|
enum State {
|
||||||
|
NONE = 0, // Button is inactive
|
||||||
|
PRESSED, // Button is pressed
|
||||||
|
HOLD, // Button is still pressed
|
||||||
|
RELEASED, // Button is released
|
||||||
|
};
|
||||||
|
|
||||||
|
State mCurrentState;
|
||||||
|
State mPreviousState;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Assumes that user and event poster use different threads
|
// Assumes that user and event poster use different threads
|
||||||
|
|
@ -62,32 +63,16 @@ namespace tp {
|
||||||
public: // Event Poster Interface
|
public: // Event Poster Interface
|
||||||
|
|
||||||
// Record event
|
// Record event
|
||||||
void postEvent(InputID inputID, InputEvent inputEvent) {
|
void postEvent(InputID inputID, InputEvent inputEvent);
|
||||||
mMutex.lock();
|
|
||||||
mEventQueue.pushBack({ inputID, inputEvent });
|
|
||||||
mMutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
public: // User interface
|
public: // User interface
|
||||||
bool isEvents() {
|
bool isEvents();
|
||||||
mMutex.lock();
|
void processEvent();
|
||||||
auto res = mEventQueue.length();
|
|
||||||
mMutex.unlock();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void processEvent() {
|
|
||||||
mMutex.lock();
|
|
||||||
mEventQueue.popFront();
|
|
||||||
mMutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
const Vec2F& getPointer() const;
|
const Vec2F& getPointer() const;
|
||||||
|
|
||||||
bool isPressed(InputID id) const;
|
bool isPressed(InputID id) const;
|
||||||
bool isReleased(InputID id) const;
|
bool isReleased(InputID id) const;
|
||||||
bool isDown(InputID id) const;
|
bool isDown(InputID id) const;
|
||||||
|
|
||||||
halnf getScrollY() const;
|
halnf getScrollY() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -100,7 +85,7 @@ namespace tp {
|
||||||
Vec2F mPointer;
|
Vec2F mPointer;
|
||||||
halnf pressure = 0;
|
halnf pressure = 0;
|
||||||
|
|
||||||
InputState mInputStates[(int) InputID::LAST_KEY_CODE];
|
InputState mInputStates[(int) InputID::LAST_KEY_CODE]{};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -142,8 +142,6 @@ namespace tp {
|
||||||
MOUSE3 = 503,
|
MOUSE3 = 503,
|
||||||
MOUSE4 = 504,
|
MOUSE4 = 504,
|
||||||
MOUSE5 = 505,
|
MOUSE5 = 505,
|
||||||
MOUSE_UP = 506,
|
|
||||||
MOUSE_DOWN = 507,
|
|
||||||
|
|
||||||
LAST_KEY_CODE = 508,
|
LAST_KEY_CODE = 508,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ file(GLOB HEADERS "./public/*.hpp")
|
||||||
|
|
||||||
add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS})
|
add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS})
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC ./public/)
|
target_include_directories(${PROJECT_NAME} PUBLIC ./public/)
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC Math Graphics Strings)
|
target_link_libraries(${PROJECT_NAME} PUBLIC Math Graphics Imgui Strings)
|
||||||
|
|
||||||
### -------------------------- Tests -------------------------- ###
|
### -------------------------- Tests -------------------------- ###
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
@ -18,6 +18,6 @@ add_test(NAME Test${PROJECT_NAME} COMMAND Test${PROJECT_NAME})
|
||||||
### -------------------------- Applications -------------------------- ###
|
### -------------------------- Applications -------------------------- ###
|
||||||
|
|
||||||
add_executable(ExampleGui examples/Entry.cpp)
|
add_executable(ExampleGui examples/Entry.cpp)
|
||||||
target_link_libraries(ExampleGui ${PROJECT_NAME} Graphics Imgui Nanovg glfw ${GLEW_LIB})
|
target_link_libraries(ExampleGui ${PROJECT_NAME} ${GLEW_LIB})
|
||||||
target_include_directories(ExampleGui PUBLIC ../Externals/glfw/include ${GLEW_INCLUDE_DIR})
|
target_include_directories(ExampleGui PUBLIC ../Externals/glfw/include ${GLEW_INCLUDE_DIR})
|
||||||
file(COPY "examples/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")
|
file(COPY "examples/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")
|
||||||
|
|
@ -7,9 +7,7 @@ using namespace tp;
|
||||||
|
|
||||||
class ExampleGUI : public Application {
|
class ExampleGUI : public Application {
|
||||||
public:
|
public:
|
||||||
ExampleGUI() {
|
ExampleGUI() = default;
|
||||||
gGlobalGUIConfig = &mConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
void processFrame(EventHandler* eventHandler) override {
|
void processFrame(EventHandler* eventHandler) override {
|
||||||
auto rec = RectF( { 0, 0 }, mWindow->getSize() );
|
auto rec = RectF( { 0, 0 }, mWindow->getSize() );
|
||||||
|
|
@ -21,7 +19,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GlobalGUIConfig mConfig;
|
|
||||||
ComplexWidget<EventHandler, Canvas> mGui;
|
ComplexWidget<EventHandler, Canvas> mGui;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -35,8 +32,13 @@ int main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ExampleGUI gui;
|
GlobalGUIConfig mConfig;
|
||||||
gui.run();
|
gGlobalGUIConfig = &mConfig;
|
||||||
|
|
||||||
|
{
|
||||||
|
ExampleGUI gui;
|
||||||
|
gui.run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
binModule.deinitialize();
|
binModule.deinitialize();
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ namespace tp {
|
||||||
this->mArea.w = 30;
|
this->mArea.w = 30;
|
||||||
this->mVisible = areaParent.isOverlap(aArea);
|
this->mVisible = areaParent.isOverlap(aArea);
|
||||||
if (!this->mVisible) return;
|
if (!this->mVisible) return;
|
||||||
mIsHover = aArea.isInside(events.getPos());
|
mIsHover = aArea.isInside(events.getPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Canvas& canvas) override {
|
void draw(Canvas& canvas) override {
|
||||||
|
|
@ -62,7 +62,7 @@ namespace tp {
|
||||||
this->mArea.w = 50;
|
this->mArea.w = 50;
|
||||||
this->mVisible = areaParent.isOverlap(aArea);
|
this->mVisible = areaParent.isOverlap(aArea);
|
||||||
if (!this->mVisible) return;
|
if (!this->mVisible) return;
|
||||||
mIsHover = aArea.isInside(events.getPos());
|
mIsHover = aArea.isInside(events.getPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Canvas& canvas) override {
|
void draw(Canvas& canvas) override {
|
||||||
|
|
@ -181,7 +181,7 @@ namespace tp {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Buffer<MessageWidget<Events, Canvas>> mMessages;
|
Buffer<MessageWidget<Events, Canvas>*> mMessages;
|
||||||
ScrollableWindow<Events, Canvas> mHistoryView;
|
ScrollableWindow<Events, Canvas> mHistoryView;
|
||||||
TextInputWidget<Events, Canvas> mMessage;
|
TextInputWidget<Events, Canvas> mMessage;
|
||||||
ButtonWidget<Events, Canvas> mSend;
|
ButtonWidget<Events, Canvas> mSend;
|
||||||
|
|
@ -190,34 +190,34 @@ namespace tp {
|
||||||
template <typename Events, typename Canvas>
|
template <typename Events, typename Canvas>
|
||||||
class ChattingWidget : public Widget<Events, Canvas> {
|
class ChattingWidget : public Widget<Events, Canvas> {
|
||||||
public:
|
public:
|
||||||
explicit ChattingWidget() {
|
ChattingWidget() {
|
||||||
this->createConfig("Chatting");
|
this->createConfig("Chatting");
|
||||||
this->addColor("Back", "Background");
|
this->addColor("Back", "Background");
|
||||||
this->addValue("Padding", "Padding");
|
this->addValue("Padding", "Padding");
|
||||||
|
|
||||||
// todo : fetch code
|
// todo : fetch code
|
||||||
mUsers.append(UserWidget<Events, Canvas>());
|
mUsers.append(new UserWidget<Events, Canvas>());
|
||||||
mUsers.append(UserWidget<Events, Canvas>());
|
mUsers.append(new UserWidget<Events, Canvas>());
|
||||||
mUsers.append(UserWidget<Events, Canvas>());
|
mUsers.append(new UserWidget<Events, Canvas>());
|
||||||
|
|
||||||
mUsers[0].mArea = { 0, 0, 100, 100 };
|
mUsers[0]->mArea = { 0, 0, 100, 100 };
|
||||||
mUsers[1].mArea = { 0, 0, 100, 100 };
|
mUsers[1]->mArea = { 0, 0, 100, 100 };
|
||||||
mUsers[2].mArea = { 0, 0, 100, 100 };
|
mUsers[2]->mArea = { 0, 0, 100, 100 };
|
||||||
|
|
||||||
for (auto message : mUsers) {
|
for (auto message : mUsers) {
|
||||||
mSideView.mContents.append(&message.data());
|
mSideView.mContents.append(message.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
mActive.mMessages.append(MessageWidget<Events, Canvas>());
|
mActive.mMessages.append(new MessageWidget<Events, Canvas>());
|
||||||
mActive.mMessages.append(MessageWidget<Events, Canvas>());
|
mActive.mMessages.append(new MessageWidget<Events, Canvas>());
|
||||||
mActive.mMessages.append(MessageWidget<Events, Canvas>());
|
mActive.mMessages.append(new MessageWidget<Events, Canvas>());
|
||||||
|
|
||||||
mActive.mMessages[0].mArea = { 0, 0, 100, 100 };
|
mActive.mMessages[0]->mArea = { 0, 0, 100, 100 };
|
||||||
mActive.mMessages[1].mArea = { 0, 0, 100, 100 };
|
mActive.mMessages[1]->mArea = { 0, 0, 100, 100 };
|
||||||
mActive.mMessages[2].mArea = { 0, 0, 100, 100 };
|
mActive.mMessages[2]->mArea = { 0, 0, 100, 100 };
|
||||||
|
|
||||||
for (auto message : mActive.mMessages) {
|
for (auto message : mActive.mMessages) {
|
||||||
mActive.mHistoryView.mContents.append(&message.data());
|
mActive.mHistoryView.mContents.append(message.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,7 +240,7 @@ namespace tp {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Buffer<UserWidget<Events, Canvas>> mUsers;
|
Buffer<UserWidget<Events, Canvas>*> mUsers;
|
||||||
ScrollableWindow<Events, Canvas> mSideView;
|
ScrollableWindow<Events, Canvas> mSideView;
|
||||||
ActiveChatWidget<Events, Canvas> mActive;
|
ActiveChatWidget<Events, Canvas> mActive;
|
||||||
SplitView<Events, Canvas> mSplitView;
|
SplitView<Events, Canvas> mSplitView;
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@ namespace tp {
|
||||||
|
|
||||||
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
|
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
|
||||||
this->mArea = aArea;
|
this->mArea = aArea;
|
||||||
|
this->mVisible = areaParent.isOverlap(aArea);
|
||||||
|
if (!this->mVisible) return;
|
||||||
|
|
||||||
mIsHover = false;
|
mIsHover = false;
|
||||||
|
|
||||||
if (!areaParent.isOverlap(aArea)) {
|
if (!areaParent.isOverlap(aArea)) {
|
||||||
|
|
@ -37,13 +40,13 @@ namespace tp {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mIsHover = aArea.isInside(events.getPos());
|
mIsHover = aArea.isInside(events.getPointer());
|
||||||
|
|
||||||
if (events.isPressed() && mIsHover) {
|
if (events.isPressed(InputID::MOUSE1) && mIsHover) {
|
||||||
mIsPressed = true;
|
mIsPressed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mIsPressed && mIsHover && events.isReleased()) {
|
if (mIsPressed && mIsHover && events.isReleased(InputID::MOUSE1)) {
|
||||||
mIsReleased = true;
|
mIsReleased = true;
|
||||||
mIsPressed = false;
|
mIsPressed = false;
|
||||||
}
|
}
|
||||||
|
|
@ -54,6 +57,8 @@ namespace tp {
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Canvas& canvas) override {
|
void draw(Canvas& canvas) override {
|
||||||
|
if (!this->mVisible) return;
|
||||||
|
|
||||||
if (mIsPressed) {
|
if (mIsPressed) {
|
||||||
canvas.rect(this->mArea, this->getColor("Pressed"), this->getValue("Rounding"));
|
canvas.rect(this->mArea, this->getColor("Pressed"), this->getValue("Rounding"));
|
||||||
} else if (mIsHover) {
|
} else if (mIsHover) {
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,13 @@ namespace tp {
|
||||||
|
|
||||||
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
|
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
|
||||||
this->mArea = aArea;
|
this->mArea = aArea;
|
||||||
|
this->mVisible = areaParent.isOverlap(aArea);
|
||||||
|
if (!this->mVisible) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Canvas& canvas) override {
|
void draw(Canvas& canvas) override {
|
||||||
|
if (!this->mVisible) return;
|
||||||
|
|
||||||
canvas.text(
|
canvas.text(
|
||||||
mLabel.read(),
|
mLabel.read(),
|
||||||
this->mArea,
|
this->mArea,
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,11 @@ namespace tp {
|
||||||
// takes whole area
|
// takes whole area
|
||||||
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
|
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
|
||||||
this->mArea = aArea;
|
this->mArea = aArea;
|
||||||
|
this->mVisible = areaParent.isOverlap(aArea);
|
||||||
|
if (!this->mVisible) return;
|
||||||
|
|
||||||
auto area = getHandle();
|
auto area = getHandle();
|
||||||
mHovered = getHandleHandle().isInside(events.getPos());
|
mHovered = getHandleHandle().isInside(events.getPointer());
|
||||||
|
|
||||||
if (mSizeFraction > 1.f) {
|
if (mSizeFraction > 1.f) {
|
||||||
mPositionFraction = 0;
|
mPositionFraction = 0;
|
||||||
|
|
@ -36,7 +38,7 @@ namespace tp {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (events.getScrollY() != 0 && areaParent.isInside(events.getPos())) {
|
if (events.getScrollY() != 0 && areaParent.isInside(events.getPointer())) {
|
||||||
auto offset = events.getScrollY() < 0 ? 1.0f : -1.0f;
|
auto offset = events.getScrollY() < 0 ? 1.0f : -1.0f;
|
||||||
if (scrollInertia * offset > 0) {
|
if (scrollInertia * offset > 0) {
|
||||||
scrollInertia += offset;
|
scrollInertia += offset;
|
||||||
|
|
@ -53,14 +55,14 @@ namespace tp {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (events.isPressed() && area.isInside(events.getPos())) {
|
if (events.isPressed(InputID::MOUSE1) && area.isInside(events.getPointer())) {
|
||||||
mIsScrolling = true;
|
mIsScrolling = true;
|
||||||
} else if (!events.isDown()) {
|
} else if (events.isReleased(InputID::MOUSE1)) {
|
||||||
mIsScrolling = false;
|
mIsScrolling = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mIsScrolling) {
|
if (mIsScrolling) {
|
||||||
tp::halnf pos = events.getPos().y;
|
tp::halnf pos = events.getPointer().y;
|
||||||
pos = (pos - area.y - mSizeFraction * area.w / 2.f) / area.w;
|
pos = (pos - area.y - mSizeFraction * area.w / 2.f) / area.w;
|
||||||
mPositionFraction = tp::clamp(pos, 0.f, 1.f - mSizeFraction);
|
mPositionFraction = tp::clamp(pos, 0.f, 1.f - mSizeFraction);
|
||||||
}
|
}
|
||||||
|
|
@ -69,6 +71,8 @@ namespace tp {
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Canvas& canvas) override {
|
void draw(Canvas& canvas) override {
|
||||||
|
if (!this->mVisible) return;
|
||||||
|
|
||||||
auto area = getHandle();
|
auto area = getHandle();
|
||||||
|
|
||||||
if (mSizeFraction > 1.f) return;
|
if (mSizeFraction > 1.f) return;
|
||||||
|
|
@ -142,7 +146,6 @@ namespace tp {
|
||||||
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
|
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
|
||||||
this->mArea = aArea;
|
this->mArea = aArea;
|
||||||
this->mVisible = areaParent.isOverlap(aArea);
|
this->mVisible = areaParent.isOverlap(aArea);
|
||||||
|
|
||||||
if (!this->mVisible) return;
|
if (!this->mVisible) return;
|
||||||
|
|
||||||
updateContents();
|
updateContents();
|
||||||
|
|
@ -170,6 +173,7 @@ namespace tp {
|
||||||
|
|
||||||
void draw(Canvas& canvas) override {
|
void draw(Canvas& canvas) override {
|
||||||
if (!this->mVisible) return;
|
if (!this->mVisible) return;
|
||||||
|
|
||||||
mScroller.draw(canvas);
|
mScroller.draw(canvas);
|
||||||
|
|
||||||
canvas.pushClamp(this->mArea);
|
canvas.pushClamp(this->mArea);
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,9 @@ namespace tp {
|
||||||
|
|
||||||
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
|
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
|
||||||
this->mArea = aArea;
|
this->mArea = aArea;
|
||||||
|
this->mVisible = areaParent.isOverlap(aArea);
|
||||||
|
|
||||||
if (!areaParent.isOverlap(aArea)) {
|
if (!this->mVisible) {
|
||||||
mResizeInProcess = false;
|
mResizeInProcess = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -27,12 +28,12 @@ namespace tp {
|
||||||
|
|
||||||
if (events.isPressed(InputID::MOUSE1) && mIsHover) {
|
if (events.isPressed(InputID::MOUSE1) && mIsHover) {
|
||||||
mResizeInProcess = true;
|
mResizeInProcess = true;
|
||||||
} else if (!events.isDown()) {
|
} else if (events.isReleased(InputID::MOUSE1)) {
|
||||||
mResizeInProcess = false;
|
mResizeInProcess = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mResizeInProcess) {
|
if (mResizeInProcess) {
|
||||||
halnf pos = events.getPos().x;
|
halnf pos = events.getPointer().x;
|
||||||
auto diff = pos - (this->mArea.x + mFactor * this->mArea.z);
|
auto diff = pos - (this->mArea.x + mFactor * this->mArea.z);
|
||||||
mFactor += diff / this->mArea.z;
|
mFactor += diff / this->mArea.z;
|
||||||
}
|
}
|
||||||
|
|
@ -46,6 +47,8 @@ namespace tp {
|
||||||
|
|
||||||
// takes whole area
|
// takes whole area
|
||||||
void draw(Canvas& canvas) override {
|
void draw(Canvas& canvas) override {
|
||||||
|
if (!this->mVisible) return;
|
||||||
|
|
||||||
if (mResizeInProcess) canvas.rect(getHandle(), this->getColor("Resizing"));
|
if (mResizeInProcess) canvas.rect(getHandle(), this->getColor("Resizing"));
|
||||||
else if (mIsHover) canvas.rect(getHandle(), this->getColor("Hovered"));
|
else if (mIsHover) canvas.rect(getHandle(), this->getColor("Hovered"));
|
||||||
else canvas.rect(getHandle(), this->getColor("Handle"));
|
else canvas.rect(getHandle(), this->getColor("Handle"));
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,13 @@ namespace tp {
|
||||||
|
|
||||||
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
|
void proc(const Events& events, const tp::RectF& areaParent, const tp::RectF& aArea) override {
|
||||||
this->mArea = aArea;
|
this->mArea = aArea;
|
||||||
|
this->mVisible = areaParent.isOverlap(aArea);
|
||||||
|
if (!this->mVisible) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw(Canvas& canvas) override {
|
||||||
|
if (!this->mVisible) return;
|
||||||
|
|
||||||
nChanged = false;
|
nChanged = false;
|
||||||
|
|
||||||
const auto col = this->getColor("Accent");
|
const auto col = this->getColor("Accent");
|
||||||
|
|
@ -58,10 +65,6 @@ namespace tp {
|
||||||
ImGui::PopStyleVar(3);
|
ImGui::PopStyleVar(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Canvas& canvas) override {
|
|
||||||
// canvas.rect(this->mArea, this->getColor("Base"));
|
|
||||||
}
|
|
||||||
|
|
||||||
enum { mMaxBufferSize = 512 };
|
enum { mMaxBufferSize = 512 };
|
||||||
char mBuff[mMaxBufferSize] = "";
|
char mBuff[mMaxBufferSize] = "";
|
||||||
bool nChanged = false;
|
bool nChanged = false;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue