From 78a4fa99ff81493e05210c808249014d30ec20b4 Mon Sep 17 00:00:00 2001 From: jmsgrogan Date: Tue, 17 Jan 2023 08:34:48 +0000 Subject: [PATCH] Add win32 mouse button events. --- apps/notes_tk/canvas/CanvasDrawingArea.cpp | 10 +++--- src/core/Color.cpp | 5 +++ src/core/Color.h | 3 ++ src/database/CMakeLists.txt | 20 +++++++---- src/graphics/directx/DirectX2dPainter.cpp | 2 +- src/network/server/win32/Win32WebRequest.cpp | 2 +- src/network/server/win32/Win32WebResponse.cpp | 13 +++----- src/network/server/win32/Win32WebResponse.h | 1 + src/network/server/win32/Win32WebServer.cpp | 4 ++- src/ui_elements/ui_events/MouseEvent.cpp | 12 +++---- src/ui_elements/ui_events/MouseEvent.h | 22 ++++++------- src/ui_elements/widgets/Button.cpp | 8 ++--- src/ui_elements/widgets/Widget.cpp | 9 +++-- src/ui_elements/widgets/Widget.h | 2 -- src/visual_elements/nodes/GeometryNode.cpp | 2 +- src/web/svg/SvgShapeElement.cpp | 4 +-- .../ui_interfaces/win32/Win32Window.cpp | 33 +++++++++++++++++++ src/windows/ui_interfaces/win32/Win32Window.h | 4 +++ test/graphics/TestD2dRendering.cpp | 31 +++++++++++++++++ test/test_utils/TestRenderUtils.h | 7 +++- 20 files changed, 141 insertions(+), 53 deletions(-) diff --git a/apps/notes_tk/canvas/CanvasDrawingArea.cpp b/apps/notes_tk/canvas/CanvasDrawingArea.cpp index 6b1c18f..779ae70 100644 --- a/apps/notes_tk/canvas/CanvasDrawingArea.cpp +++ b/apps/notes_tk/canvas/CanvasDrawingArea.cpp @@ -6,8 +6,6 @@ #include "TransformNode.h" #include "CircleNode.h" -#include - CanvasDrawingArea::~CanvasDrawingArea() { @@ -40,14 +38,14 @@ void CanvasDrawingArea::doPaint(const PaintEvent* event) void CanvasDrawingArea::onMyMouseEvent(const MouseEvent* event) { - if(event->GetAction() == MouseEvent::Action::Pressed) + if(event->getAction() == MouseEvent::Action::Pressed) { } - else if(event->GetAction() == MouseEvent::Action::Released) + else if(event->getAction() == MouseEvent::Action::Released) { - auto client_loc = event->GetClientLocation(); - auto screen_loc = event->GetScreenLocation(); + auto client_loc = event->getClientLocation(); + auto screen_loc = event->getScreenLocation(); addShapeAt(client_loc.getX(), client_loc.getY()); } diff --git a/src/core/Color.cpp b/src/core/Color.cpp index 9d860ba..244aafc 100644 --- a/src/core/Color.cpp +++ b/src/core/Color.cpp @@ -47,4 +47,9 @@ std::vector Color::getAsVectorDouble() const uint32_t Color::getAsUInt32() const { return static_cast(mB + (mG << 8) + (mR << 16)); +} + +std::string Color::toString() const +{ + return std::to_string(static_cast(mR)) + "," + std::to_string(static_cast(mG)) + "," + std::to_string(static_cast(mB)); } \ No newline at end of file diff --git a/src/core/Color.h b/src/core/Color.h index f091b68..411c048 100644 --- a/src/core/Color.h +++ b/src/core/Color.h @@ -2,6 +2,7 @@ #include #include +#include class Color { @@ -20,6 +21,8 @@ public: uint32_t getAsUInt32() const; + std::string toString() const; + bool operator==(const Color& rhs) const { return (mR == rhs.mR) diff --git a/src/database/CMakeLists.txt b/src/database/CMakeLists.txt index a79f13c..3aad33d 100644 --- a/src/database/CMakeLists.txt +++ b/src/database/CMakeLists.txt @@ -1,20 +1,28 @@ +set(MODULE_NAME database) + set(SQLite3_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/third_party/sqlite3") set(SQLite3_SOURCE_FILE "${CMAKE_SOURCE_DIR}/src/third_party/sqlite3/sqlite3.c") -list(APPEND database_LIB_INCLUDES +list(APPEND HEADERS + Database.h + DatabaseManager.h + database_interfaces/SqliteInterface.h + ${SQLite3_SOURCE_FILE}) + +list(APPEND LIB_INCLUDES Database.cpp DatabaseManager.cpp database_interfaces/SqliteInterface.cpp ${SQLite3_SOURCE_FILE}) -add_library(database SHARED ${database_LIB_INCLUDES}) +add_library(${MODULE_NAME} SHARED ${LIB_INCLUDES} ${HEADERS}) -target_include_directories(database PUBLIC +target_include_directories(${MODULE_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/database_interfaces ${SQLite3_INCLUDE_DIR} ) -target_link_libraries(database core) -set_property(TARGET database PROPERTY FOLDER src) -set_target_properties( database PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON ) +target_link_libraries(${MODULE_NAME} core) +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER src) +set_target_properties( ${MODULE_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON ) diff --git a/src/graphics/directx/DirectX2dPainter.cpp b/src/graphics/directx/DirectX2dPainter.cpp index 7a170dc..7150ce0 100644 --- a/src/graphics/directx/DirectX2dPainter.cpp +++ b/src/graphics/directx/DirectX2dPainter.cpp @@ -35,7 +35,7 @@ void DirectX2dPainter::paint(SceneModel* model) const auto loc = model->getTransform().getLocation(); const auto scale_x = model->getTransform().getScaleX(); const auto scale_y = model->getTransform().getScaleY(); - D2D1_RECT_F d2d_rect{ static_cast(loc.getX()), static_cast(loc.getY() + scale_x), static_cast(loc.getX() + scale_y), static_cast(loc.getY()) }; + D2D1_RECT_F d2d_rect{ static_cast(loc.getX()), static_cast(loc.getY() + scale_y), static_cast(loc.getX() + scale_x), static_cast(loc.getY()) }; if (model->hasFillColor()) { diff --git a/src/network/server/win32/Win32WebRequest.cpp b/src/network/server/win32/Win32WebRequest.cpp index f3a6c3b..4ea1adb 100644 --- a/src/network/server/win32/Win32WebRequest.cpp +++ b/src/network/server/win32/Win32WebRequest.cpp @@ -48,7 +48,7 @@ void Win32WebRequest::resizeBuffer(unsigned size) std::string Win32WebRequest::getUrlFromRequest() const { - return UnicodeUtils::utf16ToUtf8String(mHandle->CookedUrl.pFullUrl); + return UnicodeUtils::utf16ToUtf8String(mHandle->CookedUrl.pAbsPath); } HttpRequest Win32WebRequest::getRequest() const diff --git a/src/network/server/win32/Win32WebResponse.cpp b/src/network/server/win32/Win32WebResponse.cpp index d9a2162..a448e19 100644 --- a/src/network/server/win32/Win32WebResponse.cpp +++ b/src/network/server/win32/Win32WebResponse.cpp @@ -9,7 +9,6 @@ Win32WebResponse::Win32WebResponse(const HttpResponse& response) { RtlZeroMemory((&mResponse), sizeof(*(&mResponse))); - mResponse.StatusCode = response.getStatusCode(); mResponseReason = response.getResponseReason(); @@ -32,16 +31,14 @@ void Win32WebResponse::populateBody(const HttpResponse& response) if (!mBody.empty()) { mContentLength = std::to_string(mBody.size()); - mResponse.Headers.KnownHeaders[HttpHeaderContentLength].pRawValue = mContentLength.c_str(); - mResponse.Headers.KnownHeaders[HttpHeaderContentLength].RawValueLength = (USHORT)strlen(mContentLength.c_str()); - HTTP_DATA_CHUNK dataChunk; - dataChunk.DataChunkType = HttpDataChunkFromMemory; - dataChunk.FromMemory.pBuffer = mBody.data(); - dataChunk.FromMemory.BufferLength = (ULONG)strlen(mBody.data()); + mDataChunk.DataChunkType = HttpDataChunkFromMemory; + char test[] = "test"; + mDataChunk.FromMemory.pBuffer = mBody.data(); + mDataChunk.FromMemory.BufferLength = (ULONG)strlen(mBody.data()); mResponse.EntityChunkCount = 1; - mResponse.pEntityChunks = &dataChunk; + mResponse.pEntityChunks = &mDataChunk; } } diff --git a/src/network/server/win32/Win32WebResponse.h b/src/network/server/win32/Win32WebResponse.h index feaf64a..0ccf777 100644 --- a/src/network/server/win32/Win32WebResponse.h +++ b/src/network/server/win32/Win32WebResponse.h @@ -38,4 +38,5 @@ private: std::string mContentLength; HTTP_RESPONSE mResponse; + HTTP_DATA_CHUNK mDataChunk; }; \ No newline at end of file diff --git a/src/network/server/win32/Win32WebServer.cpp b/src/network/server/win32/Win32WebServer.cpp index f69cc56..6e7ded6 100644 --- a/src/network/server/win32/Win32WebServer.cpp +++ b/src/network/server/win32/Win32WebServer.cpp @@ -149,7 +149,7 @@ bool Win32WebServer::sendHttpResponse(const Win32WebRequest& request, const Http Win32WebResponse response(appResponse); DWORD bytesSent; - const auto result = ::HttpSendHttpResponse(mWorkingQueue, request.getHandle()->RequestId, 0, &(response.getResponse()), NULL, &bytesSent, NULL, 0, NULL, NULL); + const auto result = ::HttpSendHttpResponse(mWorkingQueue, request.getHandle()->RequestId, 0, &response.getResponse(), nullptr, &bytesSent, nullptr, 0, nullptr, nullptr); if (result != NO_ERROR) { MLOG_ERROR("Http response failed with error: " << result); @@ -196,6 +196,8 @@ bool Win32WebServer::sendHttpPostResponse(const Win32WebRequest& request, const void Win32WebServer::run() { + MLOG_INFO("Running web server on: " << mListenUrl); + Win32WebRequest request; if (!request.isValid()) { diff --git a/src/ui_elements/ui_events/MouseEvent.cpp b/src/ui_elements/ui_events/MouseEvent.cpp index 6d018ec..7645a0d 100644 --- a/src/ui_elements/ui_events/MouseEvent.cpp +++ b/src/ui_elements/ui_events/MouseEvent.cpp @@ -19,32 +19,32 @@ std::unique_ptr MouseEvent::Create() return std::make_unique(); } -void MouseEvent::SetClientLocation(Pixel location) +void MouseEvent::setClientLocation(Pixel location) { mClientLocation = location; } -void MouseEvent::SetScreenLocation(Pixel location) +void MouseEvent::setScreenLocation(Pixel location) { mScreenLocation = location; } -void MouseEvent::SetAction(MouseEvent::Action action) +void MouseEvent::setAction(MouseEvent::Action action) { mAction = action; } -Pixel MouseEvent::GetClientLocation() const +Pixel MouseEvent::getClientLocation() const { return mClientLocation; } -Pixel MouseEvent::GetScreenLocation() const +Pixel MouseEvent::getScreenLocation() const { return mScreenLocation; } -MouseEvent::Action MouseEvent::GetAction() const +MouseEvent::Action MouseEvent::getAction() const { return mAction; } diff --git a/src/ui_elements/ui_events/MouseEvent.h b/src/ui_elements/ui_events/MouseEvent.h index 3c17dfe..dfa5e61 100644 --- a/src/ui_elements/ui_events/MouseEvent.h +++ b/src/ui_elements/ui_events/MouseEvent.h @@ -14,11 +14,6 @@ public: Released }; -private: - Pixel mClientLocation; - Pixel mScreenLocation; - Action mAction; - public: MouseEvent(); @@ -27,16 +22,21 @@ public: static std::unique_ptr Create(); - void SetClientLocation(Pixel location); + Pixel getClientLocation() const; - void SetScreenLocation(Pixel location); + Pixel getScreenLocation() const; - void SetAction(Action action); + Action getAction() const; - Pixel GetClientLocation() const; + void setClientLocation(Pixel location); - Pixel GetScreenLocation() const; + void setScreenLocation(Pixel location); - Action GetAction() const; + void setAction(Action action); + +private: + Pixel mClientLocation; + Pixel mScreenLocation; + Action mAction; }; using MouseEventUPtr = std::unique_ptr; diff --git a/src/ui_elements/widgets/Button.cpp b/src/ui_elements/widgets/Button.cpp index d09c5e7..12923fd 100644 --- a/src/ui_elements/widgets/Button.cpp +++ b/src/ui_elements/widgets/Button.cpp @@ -5,8 +5,7 @@ #include "TransformNode.h" #include "MouseEvent.h" - -#include +#include "FileLogger.h" Button::Button() : Widget(), @@ -44,7 +43,8 @@ void Button::setLabel(const std::string& text) void Button::onMyMouseEvent(const MouseEvent* event) { - if(event->GetAction() == MouseEvent::Action::Pressed) + MLOG_INFO("Widget mouse event"); + if(event->getAction() == MouseEvent::Action::Pressed) { mCachedColor = mBackgroundColor; setBackgroundColor(mClickedColor); @@ -53,7 +53,7 @@ void Button::onMyMouseEvent(const MouseEvent* event) mClickFunc(this); } } - else if(event->GetAction() == MouseEvent::Action::Released) + else if(event->getAction() == MouseEvent::Action::Released) { setBackgroundColor(mCachedColor); } diff --git a/src/ui_elements/widgets/Widget.cpp b/src/ui_elements/widgets/Widget.cpp index 8df9f0a..4b8d161 100644 --- a/src/ui_elements/widgets/Widget.cpp +++ b/src/ui_elements/widgets/Widget.cpp @@ -11,6 +11,7 @@ #include "RootNode.h" #include "Window.h" +#include "FileLogger.h" #include #include @@ -293,7 +294,7 @@ bool Widget::onMouseEvent(const MouseEvent* event) } if(!inChild) { - if(mVisible && contains(event->GetClientLocation())) + if(mVisible && contains(event->getClientLocation())) { onMyMouseEvent(event); return true; @@ -308,13 +309,13 @@ bool Widget::onMouseEvent(const MouseEvent* event) void Widget::onMyMouseEvent(const MouseEvent* event) { - + MLOG_INFO("Widget mouse event"); } void Widget::updateBackground(const PaintEvent* event) { unsigned locX = mLocation.getX() + mMargin.mLeft; - unsigned locY = mLocation.getX() + mMargin.mTop; + unsigned locY = mLocation.getY() + mMargin.mTop; unsigned deltaX = mSize.mWidth - mMargin.mLeft - mMargin.mRight; unsigned deltaY = mSize.mHeight - mMargin.mTop - mMargin.mBottom; @@ -335,6 +336,8 @@ void Widget::updateBackground(const PaintEvent* event) if (mMaterialDirty) { mBackgroundNode->setFillColor(mBackgroundColor); + mBackgroundNode->setStrokeColor(mBorderColor); + mBackgroundNode->setStrokeThickness(mBorderThickness); } if (mVisibilityDirty) diff --git a/src/ui_elements/widgets/Widget.h b/src/ui_elements/widgets/Widget.h index e4287e5..b82a76b 100644 --- a/src/ui_elements/widgets/Widget.h +++ b/src/ui_elements/widgets/Widget.h @@ -141,8 +141,6 @@ protected: virtual bool isDirty() const; - - void setParent(Widget* parent); Widget* getParent() const; diff --git a/src/visual_elements/nodes/GeometryNode.cpp b/src/visual_elements/nodes/GeometryNode.cpp index cb0fb09..2ac897a 100644 --- a/src/visual_elements/nodes/GeometryNode.cpp +++ b/src/visual_elements/nodes/GeometryNode.cpp @@ -60,7 +60,7 @@ void GeometryNode::updateMaterial() mBackgroundItem->setFillColor(mFillColor); } - if (mHasStrokeColor) + if (mHasStrokeColor && mStrokeThickness > 0) { mBackgroundItem->setOutlineColor(mStrokeColor); mBackgroundItem->setOutlineThickness(mStrokeThickness); diff --git a/src/web/svg/SvgShapeElement.cpp b/src/web/svg/SvgShapeElement.cpp index 497bcc6..ab23a00 100644 --- a/src/web/svg/SvgShapeElement.cpp +++ b/src/web/svg/SvgShapeElement.cpp @@ -29,7 +29,7 @@ void SvgShapeElement::setFill(const Color& fill) auto attr = std::make_unique("fill"); std::stringstream sstr; - sstr << "rgb(" << fill.getR() << "," << fill.getG() << "," << fill.getB() << ")"; + sstr << "rgb(" << fill.toString() << ")"; attr->setValue(sstr.str()); addAttribute(std::move(attr)); @@ -48,7 +48,7 @@ void SvgShapeElement::setStrokeColor(const Color& stroke) auto attr = std::make_unique("stroke"); std::stringstream sstr; - sstr << "rgb(" << stroke.getR() << "," << stroke.getG() << "," << stroke.getB() << ")"; + sstr << "rgb(" << stroke.toString() << ")"; attr->setValue(sstr.str()); addAttribute(std::move(attr)); diff --git a/src/windows/ui_interfaces/win32/Win32Window.cpp b/src/windows/ui_interfaces/win32/Win32Window.cpp index 25dc87a..029624c 100644 --- a/src/windows/ui_interfaces/win32/Win32Window.cpp +++ b/src/windows/ui_interfaces/win32/Win32Window.cpp @@ -14,6 +14,7 @@ #include "DesktopManager.h" #include +#include LRESULT CALLBACK FreeWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); @@ -90,6 +91,24 @@ void Win32Window::onPaintMessage() mWindow->doPaint(nullptr); } +void Win32Window::onMouseDownMessage(int x, int y) +{ + auto event = MouseEvent::Create(); + event->setClientLocation({ static_cast(x), static_cast(y) }); + event->setAction(MouseEvent::Action::Pressed); + mDesktopManager->onUiEvent(std::move(event)); + MLOG_INFO("Mouse down at: " << x << " , " << y); +} + +void Win32Window::onMouseUpMessage(int x, int y) +{ + auto event = MouseEvent::Create(); + event->setClientLocation({ static_cast(x), static_cast(y) }); + event->setAction(MouseEvent::Action::Released); + mDesktopManager->onUiEvent(std::move(event)); + MLOG_INFO("Mouse up at: " << x << " , " << y); +} + LRESULT CALLBACK Win32Window::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) @@ -114,6 +133,20 @@ LRESULT CALLBACK Win32Window::WindowProc(UINT message, WPARAM wParam, LPARAM lPa onPaintMessage(); return 0; } + case WM_LBUTTONDOWN : + { + const auto x = GET_X_LPARAM(lParam); + const auto y = GET_Y_LPARAM(lParam); + onMouseDownMessage(x, y); + return 0; + } + case WM_LBUTTONUP: + { + const auto x = GET_X_LPARAM(lParam); + const auto y = GET_Y_LPARAM(lParam); + onMouseUpMessage(x, y); + return 0; + } case WM_SIZE: { auto width = LOWORD(lParam); diff --git a/src/windows/ui_interfaces/win32/Win32Window.h b/src/windows/ui_interfaces/win32/Win32Window.h index c5792be..5e684dd 100644 --- a/src/windows/ui_interfaces/win32/Win32Window.h +++ b/src/windows/ui_interfaces/win32/Win32Window.h @@ -50,6 +50,10 @@ public: void afterPaint(mt::Screen* screen); private: + void onMouseDownMessage(int x, int y); + + void onMouseUpMessage(int x, int y); + void onPaintMessage(); HWND mHandle{ 0 }; diff --git a/test/graphics/TestD2dRendering.cpp b/test/graphics/TestD2dRendering.cpp index 2407d04..3a455ac 100644 --- a/test/graphics/TestD2dRendering.cpp +++ b/test/graphics/TestD2dRendering.cpp @@ -1,9 +1,14 @@ #include "TestUiApplication.h" #include "TestFramework.h" +#include "TestRenderUtils.h" +#include "TestUtils.h" #include "RectangleNode.h" #include "TextNode.h" +#include "Button.h" +#include "TransformNode.h" + #include #include #include @@ -20,5 +25,31 @@ TEST_CASE(TestD2dRendering, "graphics") scene->addNode(text_node.get()); scene->update(); + gui_app->run(); +}; + +TEST_CASE(TestD2dWidgetRendering, "graphics") +{ + auto gui_app = TestCaseRunner::getInstance().getTestApplication(); + auto scene = gui_app->getMainWindowScene(); + + Widget widget; + widget.setBackgroundColor({ 0, 200, 0 }); + widget.setBounds(300, 300); + + auto button = Button::Create(); + button->setBackgroundColor({ 200, 0, 0 }); + button->setLabel("Test Button"); + button->setMaxWidth(100); + + widget.addWidget(std::move(button)); + widget.onPaintEvent(nullptr); + + scene->addNode(widget.getRootNode()); + + scene->update(); + + TestRenderer::writeSvg(TestUtils::getTestOutputDir(__FILE__) / "TestD2dWidgetRendering.svg", scene); + gui_app->run(); }; \ No newline at end of file diff --git a/test/test_utils/TestRenderUtils.h b/test/test_utils/TestRenderUtils.h index 977fc00..e750e25 100644 --- a/test/test_utils/TestRenderUtils.h +++ b/test/test_utils/TestRenderUtils.h @@ -41,9 +41,14 @@ public: } void writeSvg(const Path& path) + { + writeSvg(path, mSurface->getScene()); + } + + static void writeSvg(const Path& path, Scene* scene) { SvgConverter converter; - auto svg_document = converter.convert(mSurface->getScene()); + auto svg_document = converter.convert(scene); SvgWriter writer; auto svg_content = writer.toString(svg_document.get());